3 * ====================================================================
4 * Copyright (c) 2000-2008 CollabNet. All rights reserved.
6 * This software is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at http://subversion.tigris.org/license-1.html.
9 * If newer versions of this license are posted there, you may use a
10 * newer version instead, at your option.
12 * This software consists of voluntary contributions made by many
13 * individuals. For exact contribution history, see the revision
14 * history and logs, available at http://subversion.tigris.org/.
15 * ====================================================================
19 * @brief Contextual diffing.
21 * This is an internalized library for performing contextual diffs
22 * between sources of data.
24 * @note This is different than Subversion's binary-diffing engine.
25 * That API lives in @c svn_delta.h -- see the "text deltas" section. A
26 * "text delta" is way of representing precise binary diffs between
27 * strings of data. The Subversion client and server send text deltas
28 * to one another during updates and commits.
30 * This API, however, is (or will be) used for performing *contextual*
31 * merges between files in the working copy. During an update or
32 * merge, 3-way file merging is needed. And 'svn diff' needs to show
33 * the differences between 2 files.
35 * The nice thing about this API is that it's very general. It
36 * operates on any source of data (a "datasource") and calculates
37 * contextual differences on "tokens" within the data. In our
38 * particular usage, the datasources are files and the tokens are
39 * lines. But the possibilities are endless.
47 #include <apr_pools.h>
48 #include <apr_tables.h> /* for apr_array_header_t */
50 #include "svn_types.h"
51 #include "svn_io.h" /* for svn_stream_t */
52 #include "svn_version.h"
53 #include "svn_string.h"
57 #endif /* __cplusplus */
62 * Get libsvn_diff version information.
67 svn_diff_version(void);
72 /** An opaque type that represents a difference between either two or
73 * three datasources. This object is returned by svn_diff_diff(),
74 * svn_diff_diff3() and svn_diff_diff4(), and consumed by a number of
77 typedef struct svn_diff_t svn_diff_t
;
80 * There are four types of datasources. In GNU diff3 terminology,
81 * the first three types correspond to the phrases "older", "mine",
84 typedef enum svn_diff_datasource_e
86 /** The oldest form of the data. */
87 svn_diff_datasource_original
,
89 /** The same data, but potentially changed by the user. */
90 svn_diff_datasource_modified
,
92 /** The latest version of the data, possibly different than the
93 * user's modified version.
95 svn_diff_datasource_latest
,
97 /** The common ancestor of original and modified. */
98 svn_diff_datasource_ancestor
100 } svn_diff_datasource_e
;
103 /** A vtable for reading data from the three datasources. */
104 typedef struct svn_diff_fns_t
106 /** Open the datasource of type @a datasource. */
107 svn_error_t
*(*datasource_open
)(void *diff_baton
,
108 svn_diff_datasource_e datasource
);
110 /** Close the datasource of type @a datasource. */
111 svn_error_t
*(*datasource_close
)(void *diff_baton
,
112 svn_diff_datasource_e datasource
);
114 /** Get the next "token" from the datasource of type @a datasource.
115 * Return a "token" in @a *token. Return a hash of "token" in @a *hash.
116 * Leave @a token and @a hash untouched when the datasource is exhausted.
118 svn_error_t
*(*datasource_get_next_token
)(apr_uint32_t
*hash
, void **token
,
120 svn_diff_datasource_e datasource
);
122 /** A function for ordering the tokens, resembling 'strcmp' in functionality.
123 * @a compare should contain the return value of the comparison:
124 * If @a ltoken and @a rtoken are "equal", return 0. If @a ltoken is
125 * "less than" @a rtoken, return a number < 0. If @a ltoken is
126 * "greater than" @a rtoken, return a number > 0.
128 svn_error_t
*(*token_compare
)(void *diff_baton
,
133 /** Free @a token from memory, the diff algorithm is done with it. */
134 void (*token_discard
)(void *diff_baton
,
137 /** Free *all* tokens from memory, they're no longer needed. */
138 void (*token_discard_all
)(void *diff_baton
);
142 /* The Main Events */
144 /** Given a vtable of @a diff_fns/@a diff_baton for reading datasources,
145 * return a diff object in @a *diff that represents a difference between
146 * an "original" and "modified" datasource. Do all allocation in @a pool.
149 svn_diff_diff(svn_diff_t
**diff
,
151 const svn_diff_fns_t
*diff_fns
,
154 /** Given a vtable of @a diff_fns/@a diff_baton for reading datasources,
155 * return a diff object in @a *diff that represents a difference between
156 * three datasources: "original", "modified", and "latest". Do all
157 * allocation in @a pool.
160 svn_diff_diff3(svn_diff_t
**diff
,
162 const svn_diff_fns_t
*diff_fns
,
165 /** Given a vtable of @a diff_fns/@a diff_baton for reading datasources,
166 * return a diff object in @a *diff that represents a difference between
167 * two datasources: "original" and "latest", adjusted to become a full
168 * difference between "original", "modified" and "latest" using "ancestor".
169 * Do all allocation in @a pool.
172 svn_diff_diff4(svn_diff_t
**diff
,
174 const svn_diff_fns_t
*diff_fns
,
178 /* Utility functions */
180 /** Determine if a diff object contains conflicts. If it does, return
181 * @c TRUE, else return @c FALSE.
184 svn_diff_contains_conflicts(svn_diff_t
*diff
);
187 /** Determine if a diff object contains actual differences between the
188 * datasources. If so, return @c TRUE, else return @c FALSE.
191 svn_diff_contains_diffs(svn_diff_t
*diff
);
196 /* Displaying Diffs */
198 /** A vtable for displaying (or consuming) differences between datasources.
200 * Differences, similarities, and conflicts are described by lining up
203 * @note These callbacks describe data ranges in units of "tokens".
204 * A "token" is whatever you've defined it to be in your datasource
205 * @c svn_diff_fns_t vtable.
207 typedef struct svn_diff_output_fns_t
209 /* Two-way and three-way diffs both call the first two output functions: */
212 * If doing a two-way diff, then an *identical* data range was found
213 * between the "original" and "modified" datasources. Specifically,
214 * the match starts at @a original_start and goes for @a original_length
215 * tokens in the original data, and at @a modified_start for
216 * @a modified_length tokens in the modified data.
218 * If doing a three-way diff, then all three datasources have
219 * matching data ranges. The range @a latest_start, @a latest_length in
220 * the "latest" datasource is identical to the range @a original_start,
221 * @a original_length in the original data, and is also identical to
222 * the range @a modified_start, @a modified_length in the modified data.
224 svn_error_t
*(*output_common
)(void *output_baton
,
225 apr_off_t original_start
,
226 apr_off_t original_length
,
227 apr_off_t modified_start
,
228 apr_off_t modified_length
,
229 apr_off_t latest_start
,
230 apr_off_t latest_length
);
233 * If doing a two-way diff, then an *conflicting* data range was found
234 * between the "original" and "modified" datasources. Specifically,
235 * the conflict starts at @a original_start and goes for @a original_length
236 * tokens in the original data, and at @a modified_start for
237 * @a modified_length tokens in the modified data.
239 * If doing a three-way diff, then an identical data range was discovered
240 * between the "original" and "latest" datasources, but this conflicts with
241 * a range in the "modified" datasource.
243 svn_error_t
*(*output_diff_modified
)(void *output_baton
,
244 apr_off_t original_start
,
245 apr_off_t original_length
,
246 apr_off_t modified_start
,
247 apr_off_t modified_length
,
248 apr_off_t latest_start
,
249 apr_off_t latest_length
);
251 /* ------ The following callbacks are used by three-way diffs only --- */
253 /** An identical data range was discovered between the "original" and
254 * "modified" datasources, but this conflicts with a range in the
255 * "latest" datasource.
257 svn_error_t
*(*output_diff_latest
)(void *output_baton
,
258 apr_off_t original_start
,
259 apr_off_t original_length
,
260 apr_off_t modified_start
,
261 apr_off_t modified_length
,
262 apr_off_t latest_start
,
263 apr_off_t latest_length
);
265 /** An identical data range was discovered between the "modified" and
266 * "latest" datasources, but this conflicts with a range in the
267 * "original" datasource.
269 svn_error_t
*(*output_diff_common
)(void *output_baton
,
270 apr_off_t original_start
,
271 apr_off_t original_length
,
272 apr_off_t modified_start
,
273 apr_off_t modified_length
,
274 apr_off_t latest_start
,
275 apr_off_t latest_length
);
277 /** All three datasources have conflicting data ranges. The range
278 * @a latest_start, @a latest_length in the "latest" datasource conflicts
279 * with the range @a original_start, @a original_length in the "original"
280 * datasource, and also conflicts with the range @a modified_start,
281 * @a modified_length in the "modified" datasource.
282 * If there are common ranges in the "modified" and "latest" datasources
283 * in this conflicting range, @a resolved_diff will contain a diff
284 * which can be used to retrieve the common and conflicting ranges.
286 svn_error_t
*(*output_conflict
)(void *output_baton
,
287 apr_off_t original_start
,
288 apr_off_t original_length
,
289 apr_off_t modified_start
,
290 apr_off_t modified_length
,
291 apr_off_t latest_start
,
292 apr_off_t latest_length
,
293 svn_diff_t
*resolved_diff
);
294 } svn_diff_output_fns_t
;
296 /** Style for displaying conflicts during diff3 output.
300 typedef enum svn_diff_conflict_display_style_t
302 /** Display modified and latest, with conflict markers. */
303 svn_diff_conflict_display_modified_latest
,
305 /** Like svn_diff_conflict_display_modified_latest, but with an
306 extra effort to identify common sequences between modified and
308 svn_diff_conflict_display_resolved_modified_latest
,
310 /** Display modified, original, and latest, with conflict
312 svn_diff_conflict_display_modified_original_latest
,
314 /** Just display modified, with no markers. */
315 svn_diff_conflict_display_modified
,
317 /** Just display latest, with no markers. */
318 svn_diff_conflict_display_latest
,
320 /** Like svn_diff_conflict_display_modified_original_latest, but
321 *only* showing conflicts. */
322 svn_diff_conflict_display_only_conflicts
323 } svn_diff_conflict_display_style_t
;
326 /** Given a vtable of @a output_fns/@a output_baton for consuming
327 * differences, output the differences in @a diff.
330 svn_diff_output(svn_diff_t
*diff
,
332 const svn_diff_output_fns_t
*output_fns
);
338 /** To what extent whitespace should be ignored when comparing lines.
342 typedef enum svn_diff_file_ignore_space_t
344 /** Ignore no whitespace. */
345 svn_diff_file_ignore_space_none
,
347 /** Ignore changes in sequences of whitespace characters, treating each
348 * sequence of whitespace characters as a single space. */
349 svn_diff_file_ignore_space_change
,
351 /** Ignore all whitespace characters. */
352 svn_diff_file_ignore_space_all
353 } svn_diff_file_ignore_space_t
;
355 /** Options to control the behaviour of the file diff routines.
359 * @note This structure may be extended in the future, so to preserve binary
360 * compatibility, users must not allocate structs of this type themselves.
361 * @see svn_diff_file_options_create().
363 * @note Although its name suggests otherwise, this structure is used to
364 * pass options to file as well as in-memory diff functions.
366 typedef struct svn_diff_file_options_t
368 /** To what extent whitespace should be ignored when comparing lines.
369 * The default is @c svn_diff_file_ignore_space_none. */
370 svn_diff_file_ignore_space_t ignore_space
;
371 /** Whether to treat all end-of-line markers the same when comparing lines.
372 * The default is @c FALSE. */
373 svn_boolean_t ignore_eol_style
;
374 /** Whether the '@@' lines of the unified diff output should include a prefix
375 * of the nearest preceding line that starts with a character that might be
376 * the initial character of a C language identifier. The default is
379 svn_boolean_t show_c_function
;
380 } svn_diff_file_options_t
;
382 /** Allocate a @c svn_diff_file_options_t structure in @a pool, initializing
383 * it with default values.
387 svn_diff_file_options_t
*
388 svn_diff_file_options_create(apr_pool_t
*pool
);
391 * Parse @a args, an array of <tt>const char *</tt> command line switches
392 * and adjust @a options accordingly. @a options is assumed to be initialized
393 * with default values. @a pool is used for temporary allocation.
397 * The following options are supported:
398 * - --ignore-space-change, -b
399 * - --ignore-all-space, -w
400 * - --ignore-eol-style
401 * - --unified, -u (for compatibility, does nothing).
404 svn_diff_file_options_parse(svn_diff_file_options_t
*options
,
405 const apr_array_header_t
*args
,
409 /** A convenience function to produce a diff between two files.
413 * Return a diff object in @a *diff (allocated from @a pool) that represents
414 * the difference between an @a original file and @a modified file.
415 * (The file arguments must be full paths to the files.)
417 * Compare lines according to the relevant fields of @a options.
420 svn_diff_file_diff_2(svn_diff_t
**diff
,
421 const char *original
,
422 const char *modified
,
423 const svn_diff_file_options_t
*options
,
426 /** Similar to svn_file_diff_2(), but with @a options set to a struct with
429 * @deprecated Provided for backwards compatibility with the 1.3 API.
433 svn_diff_file_diff(svn_diff_t
**diff
,
434 const char *original
,
435 const char *modified
,
438 /** A convenience function to produce a diff between three files.
442 * Return a diff object in @a *diff (allocated from @a pool) that represents
443 * the difference between an @a original file, @a modified file, and @a latest
446 * Compare lines according to the relevant fields of @a options.
449 svn_diff_file_diff3_2(svn_diff_t
**diff
,
450 const char *original
,
451 const char *modified
,
453 const svn_diff_file_options_t
*options
,
456 /** Similar to svn_diff_file_diff3_2(), but with @a options set to a struct
457 * with default options.
459 * @deprecated Provided for backwards compatibility with the 1.3 API.
463 svn_diff_file_diff3(svn_diff_t
**diff
,
464 const char *original
,
465 const char *modified
,
469 /** A convenience function to produce a diff between four files.
473 * Return a diff object in @a *diff (allocated from @a pool) that represents
474 * the difference between an @a original file, @a modified file, @a latest
475 * and @a ancestor file. (The file arguments must be full paths to the files.)
477 * Compare lines according to the relevant fields of @a options.
480 svn_diff_file_diff4_2(svn_diff_t
**diff
,
481 const char *original
,
482 const char *modified
,
484 const char *ancestor
,
485 const svn_diff_file_options_t
*options
,
488 /** Simliar to svn_file_diff4_2(), but with @a options set to a struct with
491 * @deprecated Provided for backwards compatibility with the 1.3 API.
495 svn_diff_file_diff4(svn_diff_t
**diff
,
496 const char *original
,
497 const char *modified
,
499 const char *ancestor
,
502 /** A convenience function to produce unified diff output from the
503 * diff generated by svn_diff_file_diff().
507 * Output a @a diff between @a original_path and @a modified_path in unified
508 * context diff format to @a output_stream. Optionally supply
509 * @a original_header and/or @a modified_header to be displayed in the header
510 * of the output. If @a original_header or @a modified_header is @c NULL, a
511 * default header will be displayed, consisting of path and last modified time.
512 * Output all headers and markers in @a header_encoding. If @a relative_to_dir
513 * is not @c NULL, the @a original_path and @a modified_path will have the
514 * @a relative_to_dir stripped from the front of the respective paths. If
515 * @a relative_to_dir is @c NULL, paths will be not be modified. If
516 * @a relative_to_dir is not @c NULL but @a relative_to_dir is not a parent
517 * path of the target, an error is returned. Finally, if @a relative_to_dir
518 * is a URL, an error will be returned.
521 svn_diff_file_output_unified3(svn_stream_t
*output_stream
,
523 const char *original_path
,
524 const char *modified_path
,
525 const char *original_header
,
526 const char *modified_header
,
527 const char *header_encoding
,
528 const char *relative_to_dir
,
529 svn_boolean_t show_c_function
,
532 /** Similar to svn_diff_file_output_unified3(), but with @a relative_to_dir
533 * set to NULL and @a show_c_function to false.
535 * @deprecated Provided for backwards compatibility with the 1.3 API.
539 svn_diff_file_output_unified2(svn_stream_t
*output_stream
,
541 const char *original_path
,
542 const char *modified_path
,
543 const char *original_header
,
544 const char *modified_header
,
545 const char *header_encoding
,
548 /** Similar to svn_diff_file_output_unified2(), but with @a header_encoding
549 * set to @c APR_LOCALE_CHARSET.
551 * @deprecated Provided for backward compatibility with the 1.2 API.
555 svn_diff_file_output_unified(svn_stream_t
*output_stream
,
557 const char *original_path
,
558 const char *modified_path
,
559 const char *original_header
,
560 const char *modified_header
,
564 /** A convenience function to produce diff3 output from the
565 * diff generated by svn_diff_file_diff3().
567 * Output a @a diff between @a original_path, @a modified_path and
568 * @a latest_path in merged format to @a output_stream. Optionally supply
569 * @a conflict_modified, @a conflict_original, @a conflict_separator and/or
570 * @a conflict_latest to be displayed as conflict markers in the output.
571 * If @a conflict_original, @a conflict_modified, @a conflict_latest and/or
572 * @a conflict_separator is @c NULL, a default marker will be displayed.
573 * @a conflict_style dictates how conflicts are displayed.
578 svn_diff_file_output_merge2(svn_stream_t
*output_stream
,
580 const char *original_path
,
581 const char *modified_path
,
582 const char *latest_path
,
583 const char *conflict_original
,
584 const char *conflict_modified
,
585 const char *conflict_latest
,
586 const char *conflict_separator
,
587 svn_diff_conflict_display_style_t conflict_style
,
591 /** Similar to svn_diff_file_output_merge2, but with @a
592 * display_original_in_conflict and @a display_resolved_conflicts
593 * booleans instead of the @a conflict_style enum.
595 * If both booleans are false, acts like
596 * svn_diff_conflict_display_modified_latest; if @a
597 * display_original_in_conflict is true, acts like
598 * svn_diff_conflict_display_modified_original_latest; if @a
599 * display_resolved_conflicts is true, acts like
600 * svn_diff_conflict_display_resolved_modified_latest. The booleans
601 * may not both be true.
603 * @deprecated Provided for backward compatibility with the 1.5 API.
607 svn_diff_file_output_merge(svn_stream_t
*output_stream
,
609 const char *original_path
,
610 const char *modified_path
,
611 const char *latest_path
,
612 const char *conflict_original
,
613 const char *conflict_modified
,
614 const char *conflict_latest
,
615 const char *conflict_separator
,
616 svn_boolean_t display_original_in_conflict
,
617 svn_boolean_t display_resolved_conflicts
,
622 /* Diffs on in-memory structures */
624 /** Generate @a diff output from the @a original and @a modified
625 * in-memory strings. @a diff will be allocated from @a pool.
630 svn_diff_mem_string_diff(svn_diff_t
**diff
,
631 const svn_string_t
*original
,
632 const svn_string_t
*modified
,
633 const svn_diff_file_options_t
*options
,
637 /** Generate @a diff output from the @a orginal, @a modified and @a latest
638 * in-memory strings. @a diff will be allocated in @a pool.
643 svn_diff_mem_string_diff3(svn_diff_t
**diff
,
644 const svn_string_t
*original
,
645 const svn_string_t
*modified
,
646 const svn_string_t
*latest
,
647 const svn_diff_file_options_t
*options
,
651 /** Generate @a diff output from the @a original, @a modified and @a latest
652 * in-memory strings, using @a ancestor. @a diff will be allocated in @a pool.
657 svn_diff_mem_string_diff4(svn_diff_t
**diff
,
658 const svn_string_t
*original
,
659 const svn_string_t
*modified
,
660 const svn_string_t
*latest
,
661 const svn_string_t
*ancestor
,
662 const svn_diff_file_options_t
*options
,
666 /** Outputs the @a diff object generated by svn_diff_mem_string_diff()
667 * in unified diff format on @a output_stream, using @a original
668 * and @a modified for the text in the output.
669 * Outputs the header and markers in @a header_encoding.
671 * @a original_header and @a modified header are
672 * used to fill the field after the "---" and "+++" header markers.
677 svn_diff_mem_string_output_unified(svn_stream_t
*output_stream
,
679 const char *original_header
,
680 const char *modified_header
,
681 const char *header_encoding
,
682 const svn_string_t
*original
,
683 const svn_string_t
*modified
,
686 /** Output the @a diff generated by svn_diff_mem_string_diff3() in diff3
687 * format on @a output_stream, using @a original, @a modified and @a latest
688 * for content changes.
690 * Use the conflict markers @a conflict_original, @a conflict_modified,
691 * @a conflict_latest and @a conflict_separator or the default one for
692 * each of these if @c NULL is passed.
694 * @a conflict_style dictates how conflicts are displayed.
699 svn_diff_mem_string_output_merge2(svn_stream_t
*output_stream
,
701 const svn_string_t
*original
,
702 const svn_string_t
*modified
,
703 const svn_string_t
*latest
,
704 const char *conflict_original
,
705 const char *conflict_modified
,
706 const char *conflict_latest
,
707 const char *conflict_separator
,
708 svn_diff_conflict_display_style_t style
,
711 /** Similar to svn_diff_mem_string_output_merge2, but with @a
712 * display_original_in_conflict and @a display_resolved_conflicts
713 * booleans instead of the @a conflict_style enum.
715 * If both booleans are false, acts like
716 * svn_diff_conflict_display_modified_latest; if @a
717 * display_original_in_conflict is true, acts like
718 * svn_diff_conflict_display_modified_original_latest; if @a
719 * display_resolved_conflicts is true, acts like
720 * svn_diff_conflict_display_resolved_modified_latest. The booleans
721 * may not both be true.
723 * @deprecated Provided for backward compatibility with the 1.5 API.
727 svn_diff_mem_string_output_merge(svn_stream_t
*output_stream
,
729 const svn_string_t
*original
,
730 const svn_string_t
*modified
,
731 const svn_string_t
*latest
,
732 const char *conflict_original
,
733 const char *conflict_modified
,
734 const char *conflict_latest
,
735 const char *conflict_separator
,
736 svn_boolean_t display_original_in_conflict
,
737 svn_boolean_t display_resolved_conflicts
,
743 #endif /* __cplusplus */
745 #endif /* SVN_DIFF_H */