Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

svn_diff.h

Go to the documentation of this file.
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 */

Generated on Sat Apr 2 00:11:39 2005 for Subversion by doxygen 1.3.5