00001 /** 00002 * @copyright 00003 * ==================================================================== 00004 * Copyright (c) 2000-2004 CollabNet. All rights reserved. 00005 * 00006 * This software is licensed as described in the file COPYING, which 00007 * you should have received as part of this distribution. The terms 00008 * are also available at http://subversion.tigris.org/license-1.html. 00009 * If newer versions of this license are posted there, you may use a 00010 * newer version instead, at your option. 00011 * 00012 * This software consists of voluntary contributions made by many 00013 * individuals. For exact contribution history, see the revision 00014 * history and logs, available at http://subversion.tigris.org/. 00015 * ==================================================================== 00016 * @endcopyright 00017 * 00018 * @file svn_diff.h 00019 * @brief Structures related to contextual diffing. 00020 * 00021 * This is an internalized library for performing contextual diffs 00022 * between sources of data. 00023 * 00024 * NOTE: this is different than Subversion's binary-diffing engine. 00025 * That API lives in @c svn_delta.h -- see the "text deltas" section. A 00026 * "text delta" is way of representing precise binary diffs between 00027 * strings of data. The Subversion client and server send text deltas 00028 * to one another during updates and commits. 00029 * 00030 * This API, however, is (or will be) used for performing *contextual* 00031 * merges between files in the working copy. During an update or 00032 * merge, 3-way file merging is needed. And 'svn diff' needs to show 00033 * the differences between 2 files. 00034 * 00035 * The nice thing about this API is that it's very general. It 00036 * operates on any source of data (a "datasource") and calculates 00037 * contextual differences on "tokens" within the data. In our 00038 * particular usage, the datasources are files and the tokens are 00039 * lines. But the possibilities are endless. 00040 */ 00041 00042 00043 #ifndef SVN_DIFF_H 00044 #define SVN_DIFF_H 00045 00046 #include <apr.h> 00047 #include <apr_pools.h> 00048 #include <apr_file_io.h> 00049 00050 #include "svn_types.h" 00051 #include "svn_error.h" 00052 #include "svn_io.h" 00053 #include "svn_version.h" 00054 00055 #ifdef __cplusplus 00056 extern "C" { 00057 #endif /* __cplusplus */ 00058 00059 00060 00061 /** 00062 * Get libsvn_diff version information. 00063 * @since New in 1.1. 00064 */ 00065 const svn_version_t *svn_diff_version (void); 00066 00067 00068 /* Diffs. */ 00069 00070 /** An opaque type that represents a difference between either two or 00071 * three datasources. This object is returned by @c svn_diff_diff(), 00072 * @c svn_diff_diff3() and @c svn_diff_diff4 below, and consumed by a number of 00073 * other routines. 00074 */ 00075 typedef struct svn_diff_t svn_diff_t; 00076 00077 /** 00078 * There are four types of datasources. In GNU diff3 terminology, 00079 * the first three types correspond to the phrases "older", "mine", 00080 * and "yours". 00081 */ 00082 typedef enum svn_diff_datasource_e 00083 { 00084 /** The oldest form of the data. */ 00085 svn_diff_datasource_original, 00086 00087 /** The same data, but potentially changed by the user. */ 00088 svn_diff_datasource_modified, 00089 00090 /** The latest version of the data, possibly different than the 00091 * user's modified version. 00092 */ 00093 svn_diff_datasource_latest, 00094 00095 /** The common ancestor of original and modified. */ 00096 svn_diff_datasource_ancestor 00097 00098 } svn_diff_datasource_e; 00099 00100 00101 /** A vtable for reading data from the three datasources. */ 00102 typedef struct svn_diff_fns_t 00103 { 00104 /** Open the datasource of type @a datasource. */ 00105 svn_error_t *(*datasource_open)(void *diff_baton, 00106 svn_diff_datasource_e datasource); 00107 00108 /** Close the datasource of type @a datasource. */ 00109 svn_error_t *(*datasource_close)(void *diff_baton, 00110 svn_diff_datasource_e datasource); 00111 00112 /** Get the next "token" from the datasource of type @a datasource. */ 00113 svn_error_t *(*datasource_get_next_token)(apr_uint32_t *hash, void **token, 00114 void *diff_baton, 00115 svn_diff_datasource_e datasource); 00116 00117 /** A function for ordering the tokens, resembling 'strcmp' in functionality. 00118 * @a compare should contain the return value of the comparison: 00119 * If @a ltoken and @a rtoken are "equal", return 0. If @a ltoken is 00120 * "less than" @a rtoken, return a number < 0. If @a ltoken is 00121 * "greater than" @a rtoken, return a number > 0. 00122 */ 00123 svn_error_t *(*token_compare)(void *diff_baton, 00124 void *ltoken, 00125 void *rtoken, 00126 int *compare); 00127 00128 /** Free @a token from memory, the diff algorithm is done with it. */ 00129 void (*token_discard)(void *diff_baton, 00130 void *token); 00131 00132 /** Free *all* tokens from memory, they're no longer needed. */ 00133 void (*token_discard_all)(void *diff_baton); 00134 } svn_diff_fns_t; 00135 00136 00137 /* The Main Events */ 00138 00139 /** Given a vtable of @a diff_fns/@a diff_baton for reading datasources, 00140 * return a diff object in @a *diff that represents a difference between 00141 * an "original" and "modified" datasource. Do all allocation in @a pool. 00142 */ 00143 svn_error_t *svn_diff_diff(svn_diff_t **diff, 00144 void *diff_baton, 00145 const svn_diff_fns_t *diff_fns, 00146 apr_pool_t *pool); 00147 00148 /** Given a vtable of @a diff_fns/@a diff_baton for reading datasources, 00149 * return a diff object in @a *diff that represents a difference between 00150 * three datasources: "original", "modified", and "latest". Do all 00151 * allocation in @a pool. 00152 */ 00153 svn_error_t *svn_diff_diff3(svn_diff_t **diff, 00154 void *diff_baton, 00155 const svn_diff_fns_t *diff_fns, 00156 apr_pool_t *pool); 00157 00158 /** Given a vtable of @a diff_fns/@a diff_baton for reading datasources, 00159 * return a diff object in @a *diff that represents a difference between 00160 * two datasources: "original" and "latest", adjusted to become a full 00161 * difference between "original", "modified" and "latest" using "ancestor". 00162 * Do all allocation in @a pool. 00163 */ 00164 svn_error_t *svn_diff_diff4(svn_diff_t **diff, 00165 void *diff_baton, 00166 const svn_diff_fns_t *diff_fns, 00167 apr_pool_t *pool); 00168 00169 00170 /* Utility functions */ 00171 00172 /** Determine if a diff object contains conflicts. If it does, return 00173 * @c TRUE, else return @c FALSE. 00174 */ 00175 svn_boolean_t 00176 svn_diff_contains_conflicts(svn_diff_t *diff); 00177 00178 00179 /** Determine if a diff object contains actual differences between the 00180 * datasources. If so, return @c TRUE, else return @c FALSE. 00181 */ 00182 svn_boolean_t 00183 svn_diff_contains_diffs(svn_diff_t *diff); 00184 00185 00186 00187 00188 /* Displaying Diffs */ 00189 00190 /** A vtable for displaying (or consuming) differences between datasources. 00191 * 00192 * Differences, similarities, and conflicts are described by lining up 00193 * "ranges" of data. 00194 * 00195 * Note: these callbacks describe data ranges in units of "tokens". 00196 * A "token" is whatever you've defined it to be in your datasource 00197 * @c svn_diff_fns_t vtable. 00198 */ 00199 typedef struct svn_diff_output_fns_t 00200 { 00201 /* Two-way and three-way diffs both call the first two output functions: */ 00202 00203 /** 00204 * If doing a two-way diff, then an *identical* data range was found 00205 * between the "original" and "modified" datasources. Specifically, 00206 * the match starts at @a original_start and goes for @a original_length 00207 * tokens in the original data, and at @a modified_start for 00208 * @a modified_length tokens in the modified data. 00209 * 00210 * If doing a three-way diff, then all three datasources have 00211 * matching data ranges. The range @a latest_start, @a latest_length in 00212 * the "latest" datasource is identical to the range @a original_start, 00213 * @a original_length in the original data, and is also identical to 00214 * the range @a modified_start, @a modified_length in the modified data. 00215 */ 00216 svn_error_t *(*output_common)(void *output_baton, 00217 apr_off_t original_start, 00218 apr_off_t original_length, 00219 apr_off_t modified_start, 00220 apr_off_t modified_length, 00221 apr_off_t latest_start, 00222 apr_off_t latest_length); 00223 00224 /** 00225 * If doing a two-way diff, then an *conflicting* data range was found 00226 * between the "original" and "modified" datasources. Specifically, 00227 * the conflict starts at @a original_start and goes for @a original_length 00228 * tokens in the original data, and at @a modified_start for 00229 * @a modified_length tokens in the modified data. 00230 * 00231 * If doing a three-way diff, then an identical data range was discovered 00232 * between the "original" and "latest" datasources, but this conflicts with 00233 * a range in the "modified" datasource. 00234 */ 00235 svn_error_t *(*output_diff_modified)(void *output_baton, 00236 apr_off_t original_start, 00237 apr_off_t original_length, 00238 apr_off_t modified_start, 00239 apr_off_t modified_length, 00240 apr_off_t latest_start, 00241 apr_off_t latest_length); 00242 00243 /* ------ The following callbacks are used by three-way diffs only --- */ 00244 00245 /** An identical data range was discovered between the "original" and 00246 * "modified" datasources, but this conflicts with a range in the 00247 * "latest" datasource. 00248 */ 00249 svn_error_t *(*output_diff_latest)(void *output_baton, 00250 apr_off_t original_start, 00251 apr_off_t original_length, 00252 apr_off_t modified_start, 00253 apr_off_t modified_length, 00254 apr_off_t latest_start, 00255 apr_off_t latest_length); 00256 00257 /** An identical data range was discovered between the "modified" and 00258 * "latest" datasources, but this conflicts with a range in the 00259 * "original" datasource. 00260 */ 00261 svn_error_t *(*output_diff_common)(void *output_baton, 00262 apr_off_t original_start, 00263 apr_off_t original_length, 00264 apr_off_t modified_start, 00265 apr_off_t modified_length, 00266 apr_off_t latest_start, 00267 apr_off_t latest_length); 00268 00269 /** All three datasources have conflicting data ranges. The range 00270 * @a latest_start, @a latest_length in the "latest" datasource conflicts 00271 * with the range @a original_start, @a original_length in the "original" 00272 * datasource, and also conflicts with the range @a modified_start, 00273 * @a modified_length in the "modified" datasource. 00274 * If there are common ranges in the "modified" and "latest" datasources 00275 * in this conflicting range, @a resolved_diff will contain a diff 00276 * which can be used to retrieve the common and conflicting ranges. 00277 */ 00278 svn_error_t *(*output_conflict)(void *output_baton, 00279 apr_off_t original_start, 00280 apr_off_t original_length, 00281 apr_off_t modified_start, 00282 apr_off_t modified_length, 00283 apr_off_t latest_start, 00284 apr_off_t latest_length, 00285 svn_diff_t *resolved_diff); 00286 } svn_diff_output_fns_t; 00287 00288 00289 /** Given a vtable of @a output_fns/@a output_baton for consuming 00290 * differences, output the differences in @a diff. 00291 */ 00292 svn_error_t * 00293 svn_diff_output(svn_diff_t *diff, 00294 void *output_baton, 00295 const svn_diff_output_fns_t *output_fns); 00296 00297 00298 00299 /* Diffs on files */ 00300 00301 /** A convenience function to produce a diff between two files. 00302 * 00303 * Return a diff object in @a *diff (allocated from @a pool) that represents 00304 * the difference between an @a original file and @a modified file. 00305 * (The file arguments must be full paths to the files.) 00306 */ 00307 svn_error_t * 00308 svn_diff_file_diff(svn_diff_t **diff, 00309 const char *original, 00310 const char *modified, 00311 apr_pool_t *pool); 00312 00313 00314 /** A convenience function to produce a diff between three files. 00315 * 00316 * Return a diff object in @a *diff (allocated from @a pool) that represents 00317 * the difference between an @a original file, @a modified file, and @a latest 00318 * file. (The file arguments must be full paths to the files.) 00319 */ 00320 svn_error_t * 00321 svn_diff_file_diff3(svn_diff_t **diff, 00322 const char *original, 00323 const char *modified, 00324 const char *latest, 00325 apr_pool_t *pool); 00326 00327 /** A convenience function to produce a diff between four files. 00328 * 00329 * Return a diff object in @a *diff (allocated from @a pool) that represents 00330 * the difference between an @a original file, @a modified file, @a latest 00331 * and @a ancestor file. (The file arguments must be full paths to the files.) 00332 */ 00333 svn_error_t * 00334 svn_diff_file_diff4(svn_diff_t **diff, 00335 const char *original, 00336 const char *modified, 00337 const char *latest, 00338 const char *ancestor, 00339 apr_pool_t *pool); 00340 00341 /** A convenience function to produce unified diff output from the 00342 * diff generated by @c svn_diff_file. 00343 * 00344 * Output a @a diff between @a original_path and @a modified_path in unified 00345 * context diff format to @a output_file. Optionally supply @a original_header 00346 * and/or @a modified_header to be displayed in the header of the output. 00347 * If @a original_header or @a modified_header is @c NULL, a default header 00348 * will be displayed, consisting of path and last modified time. 00349 */ 00350 svn_error_t * 00351 svn_diff_file_output_unified(svn_stream_t *output_stream, 00352 svn_diff_t *diff, 00353 const char *original_path, 00354 const char *modified_path, 00355 const char *original_header, 00356 const char *modified_header, 00357 apr_pool_t *pool); 00358 00359 00360 /** A convenience function to produce diff3 output from the 00361 * diff generated by @c svn_diff3_file. 00362 * 00363 * Output a @a diff between @a original_path, @a modified_path and 00364 * @a latest_path in merged format to @a output_file. Optionally supply 00365 * @a conflict_modified, @a conflict_original, @a conflict_separator and/or 00366 * @a conflict_latest to be displayed as conflict markers in the output. 00367 * If @a conflict_original, @a conflict_modified, @a conflict_latest and/or 00368 * @a conflict_separator is @c NULL, a default marker will be displayed. 00369 * Set @a display_original_in_conflict and @a display_resolved_conflicts 00370 * as desired. Note that these options are mutually exclusive. 00371 */ 00372 svn_error_t * 00373 svn_diff_file_output_merge(svn_stream_t *output_stream, 00374 svn_diff_t *diff, 00375 const char *original_path, 00376 const char *modified_path, 00377 const char *latest_path, 00378 const char *conflict_original, 00379 const char *conflict_modified, 00380 const char *conflict_latest, 00381 const char *conflict_separator, 00382 svn_boolean_t display_original_in_conflict, 00383 svn_boolean_t display_resolved_conflicts, 00384 apr_pool_t *pool); 00385 00386 00387 #ifdef __cplusplus 00388 } 00389 #endif /* __cplusplus */ 00390 00391 #endif /* SVN_DIFF_H */
1.2.18