1 /* 2 * diff.h : private header file 3 * 4 * ==================================================================== 5 * Licensed to the Apache Software Foundation (ASF) under one 6 * or more contributor license agreements. See the NOTICE file 7 * distributed with this work for additional information 8 * regarding copyright ownership. The ASF licenses this file 9 * to you under the Apache License, Version 2.0 (the 10 * "License"); you may not use this file except in compliance 11 * with the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, 16 * software distributed under the License is distributed on an 17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18 * KIND, either express or implied. See the License for the 19 * specific language governing permissions and limitations 20 * under the License. 21 * ==================================================================== 22 */ 23 24 #if !defined(DIFF_H) 25 #define DIFF_H 26 27 #include <apr.h> 28 #include <apr_pools.h> 29 #include <apr_general.h> 30 31 #include "svn_diff.h" 32 #include "svn_types.h" 33 34 #define SVN_DIFF__UNIFIED_CONTEXT_SIZE 3 35 36 typedef struct svn_diff__node_t svn_diff__node_t; 37 typedef struct svn_diff__tree_t svn_diff__tree_t; 38 typedef struct svn_diff__position_t svn_diff__position_t; 39 typedef struct svn_diff__lcs_t svn_diff__lcs_t; 40 41 typedef enum svn_diff__type_e 42 { 43 svn_diff__type_common, 44 svn_diff__type_diff_modified, 45 svn_diff__type_diff_latest, 46 svn_diff__type_diff_common, 47 svn_diff__type_conflict 48 } svn_diff__type_e; 49 50 struct svn_diff_t { 51 svn_diff_t *next; 52 svn_diff__type_e type; 53 apr_off_t original_start; 54 apr_off_t original_length; 55 apr_off_t modified_start; 56 apr_off_t modified_length; 57 apr_off_t latest_start; 58 apr_off_t latest_length; 59 svn_diff_t *resolved_diff; 60 }; 61 62 /* Type used for token indices and counts of tokens. Must be signed. */ 63 typedef long int svn_diff__token_index_t; 64 65 struct svn_diff__position_t 66 { 67 svn_diff__position_t *next; 68 svn_diff__token_index_t token_index; 69 apr_off_t offset; 70 }; 71 72 struct svn_diff__lcs_t 73 { 74 svn_diff__lcs_t *next; 75 svn_diff__position_t *position[2]; 76 apr_off_t length; 77 int refcount; 78 }; 79 80 81 /* State used when normalizing whitespace and EOL styles. */ 82 typedef enum svn_diff__normalize_state_t 83 { 84 /* Initial state; not in a sequence of whitespace. */ 85 svn_diff__normalize_state_normal, 86 /* We're in a sequence of whitespace characters. Only entered if 87 we ignore whitespace. */ 88 svn_diff__normalize_state_whitespace, 89 /* The previous character was CR. */ 90 svn_diff__normalize_state_cr 91 } svn_diff__normalize_state_t; 92 93 94 /* 95 * Calculate the Longest Common Subsequence (LCS) between two datasources 96 * POSITION_LIST1 and POSITION_LIST2, with TOKEN_COUNTS_LIST1 and 97 * TOKEN_COUNTS_LIST2 the corresponding counts of the different tokens 98 * (indexed by the 'token_index' of the positions of each position_list). 99 * 100 * From the beginning of each list, PREFIX_LINES lines will be assumed to be 101 * equal and be excluded from the comparison process. Similarly, SUFFIX_LINES 102 * at the end of both sequences will be skipped. 103 * 104 * The resulting lcs structure will be the return value of this function. 105 * Allocations will be made from POOL. 106 */ 107 svn_diff__lcs_t * 108 svn_diff__lcs(svn_diff__position_t *position_list1, /* pointer to tail (ring) */ 109 svn_diff__position_t *position_list2, /* pointer to tail (ring) */ 110 svn_diff__token_index_t *token_counts_list1, /* array of counts */ 111 svn_diff__token_index_t *token_counts_list2, /* array of counts */ 112 svn_diff__token_index_t num_tokens, /* length of count arrays */ 113 apr_off_t prefix_lines, 114 apr_off_t suffix_lines, 115 apr_pool_t *pool); 116 117 118 /* 119 * Returns number of tokens in a tree 120 */ 121 svn_diff__token_index_t 122 svn_diff__get_node_count(svn_diff__tree_t *tree); 123 124 /* 125 * Support functions to build a tree of token positions 126 */ 127 void 128 svn_diff__tree_create(svn_diff__tree_t **tree, apr_pool_t *pool); 129 130 131 /* 132 * Get all tokens from a datasource. Return the 133 * last item in the (circular) list. 134 */ 135 svn_error_t * 136 svn_diff__get_tokens(svn_diff__position_t **position_list, 137 svn_diff__tree_t *tree, 138 void *diff_baton, 139 const svn_diff_fns2_t *vtable, 140 svn_diff_datasource_e datasource, 141 apr_off_t prefix_lines, 142 apr_pool_t *pool); 143 144 /* 145 * Returns an array with the counts for the tokens in 146 * the looped linked list given in loop_start. 147 * num_tokens equals the highest possible token index +1. 148 */ 149 svn_diff__token_index_t* 150 svn_diff__get_token_counts(svn_diff__position_t *loop_start, 151 svn_diff__token_index_t num_tokens, 152 apr_pool_t *pool); 153 154 /* Morph a svn_lcs_t into a svn_diff_t. */ 155 svn_diff_t * 156 svn_diff__diff(svn_diff__lcs_t *lcs, 157 apr_off_t original_start, apr_off_t modified_start, 158 svn_boolean_t want_common, 159 apr_pool_t *pool); 160 161 void 162 svn_diff__resolve_conflict(svn_diff_t *hunk, 163 svn_diff__position_t **position_list1, 164 svn_diff__position_t **position_list2, 165 svn_diff__token_index_t num_tokens, 166 apr_pool_t *pool); 167 168 169 /* Normalize the characters pointed to by the buffer BUF (of length *LENGTHP) 170 * according to the options *OPTS, starting in the state *STATEP. 171 * 172 * Adjust *LENGTHP and *STATEP to be the length of the normalized buffer and 173 * the final state, respectively. 174 * Normalized data is written to the memory at *TGT. BUF and TGT may point 175 * to the same memory area. The memory area pointed to by *TGT should be 176 * large enough to hold *LENGTHP bytes. 177 * When on return *TGT is not equal to the value passed in, it points somewhere 178 * into the memory region designated by BUF and *LENGTHP. 179 */ 180 void 181 svn_diff__normalize_buffer(char **tgt, 182 apr_off_t *lengthp, 183 svn_diff__normalize_state_t *statep, 184 const char *buf, 185 const svn_diff_file_options_t *opts); 186 187 /* Set *OUT_STR to a newline followed by a "\ No newline at end of file" line. 188 * 189 * The text will be encoded into HEADER_ENCODING. 190 */ 191 svn_error_t * 192 svn_diff__unified_append_no_newline_msg(svn_stringbuf_t *stringbuf, 193 const char *header_encoding, 194 apr_pool_t *scratch_pool); 195 196 /* Write a unidiff hunk header to OUTPUT_STREAM. 197 * 198 * The header will use HUNK_DELIMITER (which should usually be "@@") before 199 * and after the line-number ranges which are formed from OLD_START, 200 * OLD_LENGTH, NEW_START and NEW_LENGTH. If HUNK_EXTRA_CONTEXT is not NULL, 201 * it will be written after the final delimiter, with an intervening space. 202 * 203 * The text will be encoded into HEADER_ENCODING. 204 */ 205 svn_error_t * 206 svn_diff__unified_write_hunk_header(svn_stream_t *output_stream, 207 const char *header_encoding, 208 const char *hunk_delimiter, 209 apr_off_t old_start, 210 apr_off_t old_length, 211 apr_off_t new_start, 212 apr_off_t new_length, 213 const char *hunk_extra_context, 214 apr_pool_t *scratch_pool); 215 216 217 /* Decodes a single line of base85 data in BASE85_DATA of length BASE85_LEN, 218 to OUTPUT_DATA of length OUTPUT_LEN. 219 */ 220 svn_error_t * 221 svn_diff__base85_decode_line(char *output_data, 222 apr_ssize_t output_len, 223 const char *base85_data, 224 apr_ssize_t base85_len, 225 apr_pool_t *scratch_pool); 226 227 #endif /* DIFF_H */ 228