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.14 written by Dimitri van Heesch,
© 1997-2002