3 * ====================================================================
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
20 * ====================================================================
24 * @brief Contextual diffing.
26 * This is an internalized library for performing contextual diffs
27 * between sources of data.
29 * @note This is different than Subversion's binary-diffing engine.
30 * That API lives in @c svn_delta.h -- see the "text deltas" section. A
31 * "text delta" is way of representing precise binary diffs between
32 * strings of data. The Subversion client and server send text deltas
33 * to one another during updates and commits.
35 * This API, however, is (or will be) used for performing *contextual*
36 * merges between files in the working copy. During an update or
37 * merge, 3-way file merging is needed. And 'svn diff' needs to show
38 * the differences between 2 files.
40 * The nice thing about this API is that it's very general. It
41 * operates on any source of data (a "datasource") and calculates
42 * contextual differences on "tokens" within the data. In our
43 * particular usage, the datasources are files and the tokens are
44 * lines. But the possibilities are endless.
52 #include <apr_pools.h>
53 #include <apr_tables.h> /* for apr_array_header_t */
55 #include "svn_types.h"
56 #include "svn_io.h" /* for svn_stream_t */
57 #include "svn_string.h"
61 #endif /* __cplusplus */
66 * Get libsvn_diff version information.
71 svn_diff_version(void);
76 /** An opaque type that represents a difference between either two or
77 * three datasources. This object is returned by svn_diff_diff(),
78 * svn_diff_diff3() and svn_diff_diff4(), and consumed by a number of
81 typedef struct svn_diff_t svn_diff_t;
84 * There are four types of datasources. In GNU diff3 terminology,
85 * the first three types correspond to the phrases "older", "mine",
88 typedef enum svn_diff_datasource_e
90 /** The oldest form of the data. */
91 svn_diff_datasource_original,
93 /** The same data, but potentially changed by the user. */
94 svn_diff_datasource_modified,
96 /** The latest version of the data, possibly different than the
97 * user's modified version.
99 svn_diff_datasource_latest,
101 /** The common ancestor of original and modified. */
102 svn_diff_datasource_ancestor
104 } svn_diff_datasource_e;
107 /** A vtable for reading data from the three datasources.
108 * @since New in 1.7. */
109 typedef struct svn_diff_fns2_t
111 /** Open the datasources of type @a datasources. */
112 svn_error_t *(*datasources_open)(void *diff_baton,
113 apr_off_t *prefix_lines,
114 apr_off_t *suffix_lines,
115 const svn_diff_datasource_e *datasources,
116 apr_size_t datasources_len);
118 /** Close the datasource of type @a datasource. */
119 svn_error_t *(*datasource_close)(void *diff_baton,
120 svn_diff_datasource_e datasource);
122 /** Get the next "token" from the datasource of type @a datasource.
123 * Return a "token" in @a *token. Return a hash of "token" in @a *hash.
124 * Leave @a token and @a hash untouched when the datasource is exhausted.
126 svn_error_t *(*datasource_get_next_token)(apr_uint32_t *hash, void **token,
128 svn_diff_datasource_e datasource);
130 /** A function for ordering the tokens, resembling 'strcmp' in functionality.
131 * @a compare should contain the return value of the comparison:
132 * If @a ltoken and @a rtoken are "equal", return 0. If @a ltoken is
133 * "less than" @a rtoken, return a number < 0. If @a ltoken is
134 * "greater than" @a rtoken, return a number > 0.
136 svn_error_t *(*token_compare)(void *diff_baton,
141 /** Free @a token from memory, the diff algorithm is done with it. */
142 void (*token_discard)(void *diff_baton,
145 /** Free *all* tokens from memory, they're no longer needed. */
146 void (*token_discard_all)(void *diff_baton);
150 /** Like #svn_diff_fns2_t except with datasource_open() instead of
151 * datasources_open().
153 * @deprecated Provided for backward compatibility with the 1.6 API.
155 typedef struct svn_diff_fns_t
157 svn_error_t *(*datasource_open)(void *diff_baton,
158 svn_diff_datasource_e datasource);
160 svn_error_t *(*datasource_close)(void *diff_baton,
161 svn_diff_datasource_e datasource);
163 svn_error_t *(*datasource_get_next_token)(apr_uint32_t *hash, void **token,
165 svn_diff_datasource_e datasource);
167 svn_error_t *(*token_compare)(void *diff_baton,
172 void (*token_discard)(void *diff_baton,
175 void (*token_discard_all)(void *diff_baton);
179 /* The Main Events */
181 /** Given a vtable of @a diff_fns/@a diff_baton for reading datasources,
182 * return a diff object in @a *diff that represents a difference between
183 * an "original" and "modified" datasource. Do all allocation in @a pool.
188 svn_diff_diff_2(svn_diff_t **diff,
190 const svn_diff_fns2_t *diff_fns,
193 /** Like svn_diff_diff_2() but using #svn_diff_fns_t instead of
196 * @deprecated Provided for backward compatibility with the 1.6 API.
200 svn_diff_diff(svn_diff_t **diff,
202 const svn_diff_fns_t *diff_fns,
205 /** Given a vtable of @a diff_fns/@a diff_baton for reading datasources,
206 * return a diff object in @a *diff that represents a difference between
207 * three datasources: "original", "modified", and "latest". Do all
208 * allocation in @a pool.
213 svn_diff_diff3_2(svn_diff_t **diff,
215 const svn_diff_fns2_t *diff_fns,
218 /** Like svn_diff_diff3_2() but using #svn_diff_fns_t instead of
221 * @deprecated Provided for backward compatibility with the 1.6 API.
225 svn_diff_diff3(svn_diff_t **diff,
227 const svn_diff_fns_t *diff_fns,
230 /** Given a vtable of @a diff_fns/@a diff_baton for reading datasources,
231 * return a diff object in @a *diff that represents a difference between
232 * two datasources: "original" and "latest", adjusted to become a full
233 * difference between "original", "modified" and "latest" using "ancestor".
234 * Do all allocation in @a pool.
239 svn_diff_diff4_2(svn_diff_t **diff,
241 const svn_diff_fns2_t *diff_fns,
244 /** Like svn_diff_diff4_2() but using #svn_diff_fns_t instead of
247 * @deprecated Provided for backward compatibility with the 1.6 API.
251 svn_diff_diff4(svn_diff_t **diff,
253 const svn_diff_fns_t *diff_fns,
257 /* Utility functions */
259 /** Determine if a diff object contains conflicts. If it does, return
260 * @c TRUE, else return @c FALSE.
263 svn_diff_contains_conflicts(svn_diff_t *diff);
266 /** Determine if a diff object contains actual differences between the
267 * datasources. If so, return @c TRUE, else return @c FALSE.
270 svn_diff_contains_diffs(svn_diff_t *diff);
275 /* Displaying Diffs */
277 /** A vtable for displaying (or consuming) differences between datasources.
279 * Differences, similarities, and conflicts are described by lining up
282 * Any of the function pointers in this vtable may be NULL to ignore the
283 * corresponding kinds of output.
285 * @note These callbacks describe data ranges in units of "tokens".
286 * A "token" is whatever you've defined it to be in your datasource
287 * @c svn_diff_fns_t vtable.
289 typedef struct svn_diff_output_fns_t
291 /* Two-way and three-way diffs both call the first two output functions: */
294 * If doing a two-way diff, then an *identical* data range was found
295 * between the "original" and "modified" datasources. Specifically,
296 * the match starts at @a original_start and goes for @a original_length
297 * tokens in the original data, and at @a modified_start for
298 * @a modified_length tokens in the modified data.
300 * If doing a three-way diff, then all three datasources have
301 * matching data ranges. The range @a latest_start, @a latest_length in
302 * the "latest" datasource is identical to the range @a original_start,
303 * @a original_length in the original data, and is also identical to
304 * the range @a modified_start, @a modified_length in the modified data.
306 svn_error_t *(*output_common)(void *output_baton,
307 apr_off_t original_start,
308 apr_off_t original_length,
309 apr_off_t modified_start,
310 apr_off_t modified_length,
311 apr_off_t latest_start,
312 apr_off_t latest_length);
315 * If doing a two-way diff, then an *conflicting* data range was found
316 * between the "original" and "modified" datasources. Specifically,
317 * the conflict starts at @a original_start and goes for @a original_length
318 * tokens in the original data, and at @a modified_start for
319 * @a modified_length tokens in the modified data.
321 * If doing a three-way diff, then an identical data range was discovered
322 * between the "original" and "latest" datasources, but this conflicts with
323 * a range in the "modified" datasource.
325 svn_error_t *(*output_diff_modified)(void *output_baton,
326 apr_off_t original_start,
327 apr_off_t original_length,
328 apr_off_t modified_start,
329 apr_off_t modified_length,
330 apr_off_t latest_start,
331 apr_off_t latest_length);
333 /* ------ The following callbacks are used by three-way diffs only --- */
335 /** An identical data range was discovered between the "original" and
336 * "modified" datasources, but this conflicts with a range in the
337 * "latest" datasource.
339 svn_error_t *(*output_diff_latest)(void *output_baton,
340 apr_off_t original_start,
341 apr_off_t original_length,
342 apr_off_t modified_start,
343 apr_off_t modified_length,
344 apr_off_t latest_start,
345 apr_off_t latest_length);
347 /** An identical data range was discovered between the "modified" and
348 * "latest" datasources, but this conflicts with a range in the
349 * "original" datasource.
351 svn_error_t *(*output_diff_common)(void *output_baton,
352 apr_off_t original_start,
353 apr_off_t original_length,
354 apr_off_t modified_start,
355 apr_off_t modified_length,
356 apr_off_t latest_start,
357 apr_off_t latest_length);
359 /** All three datasources have conflicting data ranges. The range
360 * @a latest_start, @a latest_length in the "latest" datasource conflicts
361 * with the range @a original_start, @a original_length in the "original"
362 * datasource, and also conflicts with the range @a modified_start,
363 * @a modified_length in the "modified" datasource.
364 * If there are common ranges in the "modified" and "latest" datasources
365 * in this conflicting range, @a resolved_diff will contain a diff
366 * which can be used to retrieve the common and conflicting ranges.
368 svn_error_t *(*output_conflict)(void *output_baton,
369 apr_off_t original_start,
370 apr_off_t original_length,
371 apr_off_t modified_start,
372 apr_off_t modified_length,
373 apr_off_t latest_start,
374 apr_off_t latest_length,
375 svn_diff_t *resolved_diff);
376 } svn_diff_output_fns_t;
378 /** Style for displaying conflicts during diff3 output.
382 typedef enum svn_diff_conflict_display_style_t
384 /** Display modified and latest, with conflict markers. */
385 svn_diff_conflict_display_modified_latest,
387 /** Like svn_diff_conflict_display_modified_latest, but with an
388 extra effort to identify common sequences between modified and
390 svn_diff_conflict_display_resolved_modified_latest,
392 /** Display modified, original, and latest, with conflict
394 svn_diff_conflict_display_modified_original_latest,
396 /** Just display modified, with no markers. */
397 svn_diff_conflict_display_modified,
399 /** Just display latest, with no markers. */
400 svn_diff_conflict_display_latest,
402 /** Like svn_diff_conflict_display_modified_original_latest, but
403 *only* showing conflicts. */
404 svn_diff_conflict_display_only_conflicts
405 } svn_diff_conflict_display_style_t;
408 /** Given a vtable of @a output_fns/@a output_baton for consuming
409 * differences, output the differences in @a diff.
412 svn_diff_output(svn_diff_t *diff,
414 const svn_diff_output_fns_t *output_fns);
420 /** To what extent whitespace should be ignored when comparing lines.
424 typedef enum svn_diff_file_ignore_space_t
426 /** Ignore no whitespace. */
427 svn_diff_file_ignore_space_none,
429 /** Ignore changes in sequences of whitespace characters, treating each
430 * sequence of whitespace characters as a single space. */
431 svn_diff_file_ignore_space_change,
433 /** Ignore all whitespace characters. */
434 svn_diff_file_ignore_space_all
435 } svn_diff_file_ignore_space_t;
437 /** Options to control the behaviour of the file diff routines.
441 * @note This structure may be extended in the future, so to preserve binary
442 * compatibility, users must not allocate structs of this type themselves.
443 * @see svn_diff_file_options_create().
445 * @note Although its name suggests otherwise, this structure is used to
446 * pass options to file as well as in-memory diff functions.
448 typedef struct svn_diff_file_options_t
450 /** To what extent whitespace should be ignored when comparing lines.
451 * The default is @c svn_diff_file_ignore_space_none. */
452 svn_diff_file_ignore_space_t ignore_space;
453 /** Whether to treat all end-of-line markers the same when comparing lines.
454 * The default is @c FALSE. */
455 svn_boolean_t ignore_eol_style;
456 /** Whether the "@@" lines of the unified diff output should include a prefix
457 * of the nearest preceding line that starts with a character that might be
458 * the initial character of a C language identifier. The default is
461 svn_boolean_t show_c_function;
462 } svn_diff_file_options_t;
464 /** Allocate a @c svn_diff_file_options_t structure in @a pool, initializing
465 * it with default values.
469 svn_diff_file_options_t *
470 svn_diff_file_options_create(apr_pool_t *pool);
473 * Parse @a args, an array of <tt>const char *</tt> command line switches
474 * and adjust @a options accordingly. @a options is assumed to be initialized
475 * with default values. @a pool is used for temporary allocation.
479 * The following options are supported:
480 * - --ignore-space-change, -b
481 * - --ignore-all-space, -w
482 * - --ignore-eol-style
483 * - --show-c-function, -p @since New in 1.5.
484 * - --unified, -u (for compatibility, does nothing).
487 svn_diff_file_options_parse(svn_diff_file_options_t *options,
488 const apr_array_header_t *args,
492 /** A convenience function to produce a diff between two files.
496 * Return a diff object in @a *diff (allocated from @a pool) that represents
497 * the difference between an @a original file and @a modified file.
498 * (The file arguments must be full paths to the files.)
500 * Compare lines according to the relevant fields of @a options.
503 svn_diff_file_diff_2(svn_diff_t **diff,
504 const char *original,
505 const char *modified,
506 const svn_diff_file_options_t *options,
509 /** Similar to svn_file_diff_2(), but with @a options set to a struct with
512 * @deprecated Provided for backwards compatibility with the 1.3 API.
516 svn_diff_file_diff(svn_diff_t **diff,
517 const char *original,
518 const char *modified,
521 /** A convenience function to produce a diff between three files.
525 * Return a diff object in @a *diff (allocated from @a pool) that represents
526 * the difference between an @a original file, @a modified file, and @a latest
529 * Compare lines according to the relevant fields of @a options.
532 svn_diff_file_diff3_2(svn_diff_t **diff,
533 const char *original,
534 const char *modified,
536 const svn_diff_file_options_t *options,
539 /** Similar to svn_diff_file_diff3_2(), but with @a options set to a struct
540 * with default options.
542 * @deprecated Provided for backwards compatibility with the 1.3 API.
546 svn_diff_file_diff3(svn_diff_t **diff,
547 const char *original,
548 const char *modified,
552 /** A convenience function to produce a diff between four files.
556 * Return a diff object in @a *diff (allocated from @a pool) that represents
557 * the difference between an @a original file, @a modified file, @a latest
558 * and @a ancestor file. (The file arguments must be full paths to the files.)
560 * Compare lines according to the relevant fields of @a options.
563 svn_diff_file_diff4_2(svn_diff_t **diff,
564 const char *original,
565 const char *modified,
567 const char *ancestor,
568 const svn_diff_file_options_t *options,
571 /** Similar to svn_file_diff4_2(), but with @a options set to a struct with
574 * @deprecated Provided for backwards compatibility with the 1.3 API.
578 svn_diff_file_diff4(svn_diff_t **diff,
579 const char *original,
580 const char *modified,
582 const char *ancestor,
585 /** A convenience function to produce unified diff output from the
586 * diff generated by svn_diff_file_diff().
590 * Output a @a diff between @a original_path and @a modified_path in unified
591 * context diff format to @a output_stream. Optionally supply
592 * @a original_header and/or @a modified_header to be displayed in the header
593 * of the output. If @a original_header or @a modified_header is @c NULL, a
594 * default header will be displayed, consisting of path and last modified time.
595 * Output all headers and markers in @a header_encoding. If @a relative_to_dir
596 * is not @c NULL, the @a original_path and @a modified_path will have the
597 * @a relative_to_dir stripped from the front of the respective paths. If
598 * @a relative_to_dir is @c NULL, paths will be not be modified. If
599 * @a relative_to_dir is not @c NULL but @a relative_to_dir is not a parent
600 * path of the target, an error is returned. Finally, if @a relative_to_dir
601 * is a URL, an error will be returned.
604 svn_diff_file_output_unified3(svn_stream_t *output_stream,
606 const char *original_path,
607 const char *modified_path,
608 const char *original_header,
609 const char *modified_header,
610 const char *header_encoding,
611 const char *relative_to_dir,
612 svn_boolean_t show_c_function,
615 /** Similar to svn_diff_file_output_unified3(), but with @a relative_to_dir
616 * set to NULL and @a show_c_function to false.
618 * @deprecated Provided for backwards compatibility with the 1.4 API.
622 svn_diff_file_output_unified2(svn_stream_t *output_stream,
624 const char *original_path,
625 const char *modified_path,
626 const char *original_header,
627 const char *modified_header,
628 const char *header_encoding,
631 /** Similar to svn_diff_file_output_unified2(), but with @a header_encoding
632 * set to @c APR_LOCALE_CHARSET.
634 * @deprecated Provided for backward compatibility with the 1.2 API.
638 svn_diff_file_output_unified(svn_stream_t *output_stream,
640 const char *original_path,
641 const char *modified_path,
642 const char *original_header,
643 const char *modified_header,
647 /** A convenience function to produce diff3 output from the
648 * diff generated by svn_diff_file_diff3().
650 * Output a @a diff between @a original_path, @a modified_path and
651 * @a latest_path in merged format to @a output_stream. Optionally supply
652 * @a conflict_modified, @a conflict_original, @a conflict_separator and/or
653 * @a conflict_latest to be displayed as conflict markers in the output.
654 * If @a conflict_original, @a conflict_modified, @a conflict_latest and/or
655 * @a conflict_separator is @c NULL, a default marker will be displayed.
656 * @a conflict_style dictates how conflicts are displayed.
661 svn_diff_file_output_merge2(svn_stream_t *output_stream,
663 const char *original_path,
664 const char *modified_path,
665 const char *latest_path,
666 const char *conflict_original,
667 const char *conflict_modified,
668 const char *conflict_latest,
669 const char *conflict_separator,
670 svn_diff_conflict_display_style_t conflict_style,
674 /** Similar to svn_diff_file_output_merge2, but with @a
675 * display_original_in_conflict and @a display_resolved_conflicts
676 * booleans instead of the @a conflict_style enum.
678 * If both booleans are false, acts like
679 * svn_diff_conflict_display_modified_latest; if @a
680 * display_original_in_conflict is true, acts like
681 * svn_diff_conflict_display_modified_original_latest; if @a
682 * display_resolved_conflicts is true, acts like
683 * svn_diff_conflict_display_resolved_modified_latest. The booleans
684 * may not both be true.
686 * @deprecated Provided for backward compatibility with the 1.5 API.
690 svn_diff_file_output_merge(svn_stream_t *output_stream,
692 const char *original_path,
693 const char *modified_path,
694 const char *latest_path,
695 const char *conflict_original,
696 const char *conflict_modified,
697 const char *conflict_latest,
698 const char *conflict_separator,
699 svn_boolean_t display_original_in_conflict,
700 svn_boolean_t display_resolved_conflicts,
705 /* Diffs on in-memory structures */
707 /** Generate @a diff output from the @a original and @a modified
708 * in-memory strings. @a diff will be allocated from @a pool.
713 svn_diff_mem_string_diff(svn_diff_t **diff,
714 const svn_string_t *original,
715 const svn_string_t *modified,
716 const svn_diff_file_options_t *options,
720 /** Generate @a diff output from the @a original, @a modified and @a latest
721 * in-memory strings. @a diff will be allocated in @a pool.
726 svn_diff_mem_string_diff3(svn_diff_t **diff,
727 const svn_string_t *original,
728 const svn_string_t *modified,
729 const svn_string_t *latest,
730 const svn_diff_file_options_t *options,
734 /** Generate @a diff output from the @a original, @a modified and @a latest
735 * in-memory strings, using @a ancestor. @a diff will be allocated in @a pool.
740 svn_diff_mem_string_diff4(svn_diff_t **diff,
741 const svn_string_t *original,
742 const svn_string_t *modified,
743 const svn_string_t *latest,
744 const svn_string_t *ancestor,
745 const svn_diff_file_options_t *options,
748 /** Outputs the @a diff object generated by svn_diff_mem_string_diff()
749 * in unified diff format on @a output_stream, using @a original
750 * and @a modified for the text in the output.
752 * If @a with_diff_header is TRUE, write a diff header ("---" and "+++"
753 * lines), using @a original_header and @a modified_header to fill the field
754 * after the "---" and "+++" markers; otherwise @a original_header and
755 * @a modified_header are ignored and may be NULL.
757 * Outputs the header and hunk delimiters in @a header_encoding.
758 * A @a hunk_delimiter can optionally be specified.
759 * If @a hunk_delimiter is NULL, use the default hunk delimiter "@@".
761 * As a special case, if the hunk delimiter is "##", then for an incomplete
762 * final line use the text "\ No newline at end of property" instead of
763 * "\ No newline at end of file".
765 * @since New in 1.7. Hunk delimiter "##" has the special meaning since 1.8.
768 svn_diff_mem_string_output_unified2(svn_stream_t *output_stream,
770 svn_boolean_t with_diff_header,
771 const char *hunk_delimiter,
772 const char *original_header,
773 const char *modified_header,
774 const char *header_encoding,
775 const svn_string_t *original,
776 const svn_string_t *modified,
779 /** Similar to svn_diff_mem_string_output_unified2() but with
780 * @a with_diff_header always set to TRUE and @a hunk_delimiter always
786 svn_diff_mem_string_output_unified(svn_stream_t *output_stream,
788 const char *original_header,
789 const char *modified_header,
790 const char *header_encoding,
791 const svn_string_t *original,
792 const svn_string_t *modified,
795 /** Output the @a diff generated by svn_diff_mem_string_diff3() in diff3
796 * format on @a output_stream, using @a original, @a modified and @a latest
797 * for content changes.
799 * Use the conflict markers @a conflict_original, @a conflict_modified,
800 * @a conflict_latest and @a conflict_separator or the default one for
801 * each of these if @c NULL is passed.
803 * @a conflict_style dictates how conflicts are displayed.
808 svn_diff_mem_string_output_merge2(svn_stream_t *output_stream,
810 const svn_string_t *original,
811 const svn_string_t *modified,
812 const svn_string_t *latest,
813 const char *conflict_original,
814 const char *conflict_modified,
815 const char *conflict_latest,
816 const char *conflict_separator,
817 svn_diff_conflict_display_style_t style,
820 /** Similar to svn_diff_mem_string_output_merge2, but with @a
821 * display_original_in_conflict and @a display_resolved_conflicts
822 * booleans instead of the @a conflict_style enum.
824 * If both booleans are false, acts like
825 * svn_diff_conflict_display_modified_latest; if @a
826 * display_original_in_conflict is true, acts like
827 * svn_diff_conflict_display_modified_original_latest; if @a
828 * display_resolved_conflicts is true, acts like
829 * svn_diff_conflict_display_resolved_modified_latest. The booleans
830 * may not both be true.
832 * @deprecated Provided for backward compatibility with the 1.5 API.
836 svn_diff_mem_string_output_merge(svn_stream_t *output_stream,
838 const svn_string_t *original,
839 const svn_string_t *modified,
840 const svn_string_t *latest,
841 const char *conflict_original,
842 const char *conflict_modified,
843 const char *conflict_latest,
844 const char *conflict_separator,
845 svn_boolean_t display_original_in_conflict,
846 svn_boolean_t display_resolved_conflicts,
851 /* Diff parsing. If you want to apply a patch to a working copy
852 * rather than parse it, see svn_client_patch(). */
855 * Describes what operation has been performed on a file.
859 typedef enum svn_diff_operation_kind_e
861 svn_diff_op_unchanged,
866 /* There's no tree changes, just text modifications. */
868 } svn_diff_operation_kind_t;
871 * A single hunk inside a patch.
873 * The lines of text comprising the hunk can be interpreted in three ways:
874 * - diff text The hunk as it appears in the unidiff patch file,
875 * including the hunk header line ("@@ ... @@")
876 * - original text The text the patch was based on.
877 * - modified text The result of patching the original text.
879 * For example, consider a hunk with the following diff text:
884 int main(int argc, char *argv[]) {
885 - printf("Hello World!\n");
886 + printf("I like Subversion!\n");
889 * The original text of this hunk is:
893 int main(int argc, char *argv[]) {
894 printf("Hello World!\n");
897 * And the modified text is:
901 int main(int argc, char *argv[]) {
902 printf("I like Subversion!\n");
905 * @see svn_diff_hunk_readline_diff_text()
906 * @see svn_diff_hunk_readline_original_text()
907 * @see svn_diff_hunk_readline_modified_text()
909 * @since New in 1.7. */
910 typedef struct svn_diff_hunk_t svn_diff_hunk_t;
913 * Allocate @a *stringbuf in @a result_pool, and read into it one line
914 * of the diff text of @a hunk. The first line returned is the hunk header.
915 * Any subsequent lines are unidiff data (starting with '+', '-', or ' ').
916 * If the @a hunk is being interpreted in reverse (i.e. the reverse
917 * parameter of svn_diff_parse_next_patch() was @c TRUE), the diff
918 * text will be returned in reversed form.
919 * The line-terminator is detected automatically and stored in @a *eol
920 * if @a eol is not NULL.
921 * If EOF is reached, set @a *eof to TRUE, and set @a *eol to NULL if the
922 * hunk does not end with a newline character and @a eol is not NULL.
923 * Temporary allocations will be performed in @a scratch_pool.
928 svn_diff_hunk_readline_diff_text(svn_diff_hunk_t *hunk,
929 svn_stringbuf_t **stringbuf,
932 apr_pool_t *result_pool,
933 apr_pool_t *scratch_pool);
936 * Allocate @a *stringbuf in @a result_pool, and read into it one line
937 * of the original text of @a hunk.
938 * The line-terminator is detected automatically and stored in @a *eol
939 * if @a eol is not NULL.
940 * If EOF is reached, set @a *eof to TRUE, and set @a *eol to NULL if the
941 * hunk text does not end with a newline character and @a eol is not NULL.
942 * Temporary allocations will be performed in @a scratch_pool.
944 * @see svn_diff_hunk_t
948 svn_diff_hunk_readline_original_text(svn_diff_hunk_t *hunk,
949 svn_stringbuf_t **stringbuf,
952 apr_pool_t *result_pool,
953 apr_pool_t *scratch_pool);
956 * Like svn_diff_hunk_readline_original_text(), but it returns lines from
957 * the modified text of the hunk.
959 * @see svn_diff_hunk_t
963 svn_diff_hunk_readline_modified_text(svn_diff_hunk_t *hunk,
964 svn_stringbuf_t **stringbuf,
967 apr_pool_t *result_pool,
968 apr_pool_t *scratch_pool);
970 /** Reset the diff text of @a hunk so it can be read again from the start.
971 * @since New in 1.7. */
973 svn_diff_hunk_reset_diff_text(svn_diff_hunk_t *hunk);
975 /** Reset the original text of @a hunk so it can be read again from the start.
976 * @since New in 1.7. */
978 svn_diff_hunk_reset_original_text(svn_diff_hunk_t *hunk);
980 /** Reset the modified text of @a hunk so it can be read again from the start.
981 * @since New in 1.7. */
983 svn_diff_hunk_reset_modified_text(svn_diff_hunk_t *hunk);
985 /** Return the line offset of the original hunk text,
986 * as parsed from the hunk header.
987 * @since New in 1.7. */
989 svn_diff_hunk_get_original_start(const svn_diff_hunk_t *hunk);
991 /** Return the number of lines in the original @a hunk text,
992 * as parsed from the hunk header.
993 * @since New in 1.7. */
995 svn_diff_hunk_get_original_length(const svn_diff_hunk_t *hunk);
997 /** Return the line offset of the modified @a hunk text,
998 * as parsed from the hunk header.
999 * @since New in 1.7. */
1001 svn_diff_hunk_get_modified_start(const svn_diff_hunk_t *hunk);
1003 /** Return the number of lines in the modified @a hunk text,
1004 * as parsed from the hunk header.
1005 * @since New in 1.7. */
1007 svn_diff_hunk_get_modified_length(const svn_diff_hunk_t *hunk);
1009 /** Return the number of lines of leading context of @a hunk,
1010 * i.e. the number of lines starting with ' ' before the first line
1011 * that starts with a '+' or '-'.
1012 * @since New in 1.7. */
1014 svn_diff_hunk_get_leading_context(const svn_diff_hunk_t *hunk);
1016 /** Return the number of lines of trailing context of @a hunk,
1017 * i.e. the number of lines starting with ' ' after the last line
1018 * that starts with a '+' or '-'.
1019 * @since New in 1.7. */
1021 svn_diff_hunk_get_trailing_context(const svn_diff_hunk_t *hunk);
1024 * Data type to manage parsing of properties in patches.
1025 * API users should not allocate structures of this type directly.
1027 * @since New in 1.7. */
1028 typedef struct svn_prop_patch_t {
1031 /** Represents the operation performed on the property */
1032 svn_diff_operation_kind_t operation;
1035 * An array containing an svn_diff_hunk_t object for each hunk parsed
1036 * from the patch associated with our property name */
1037 apr_array_header_t *hunks;
1041 * Data type to manage parsing of patches.
1042 * API users should not allocate structures of this type directly.
1044 * @since New in 1.7. */
1045 typedef struct svn_patch_t {
1047 * The old and new file names as retrieved from the patch file.
1048 * These paths are UTF-8 encoded and canonicalized, but otherwise
1049 * left unchanged from how they appeared in the patch file. */
1050 const char *old_filename;
1051 const char *new_filename;
1054 * An array containing an svn_diff_hunk_t * for each hunk parsed
1055 * from the patch. */
1056 apr_array_header_t *hunks;
1059 * A hash table keyed by property names containing svn_prop_patch_t
1060 * object for each property parsed from the patch. */
1061 apr_hash_t *prop_patches;
1064 * Represents the operation performed on the file. */
1065 svn_diff_operation_kind_t operation;
1068 * Indicates whether the patch is being interpreted in reverse. */
1069 svn_boolean_t reverse;
1072 /** An opaque type representing an open patch file.
1074 * @since New in 1.7. */
1075 typedef struct svn_patch_file_t svn_patch_file_t;
1077 /** Open @a patch_file at @a local_abspath.
1078 * Allocate @a patch_file in @a result_pool.
1080 * @since New in 1.7. */
1082 svn_diff_open_patch_file(svn_patch_file_t **patch_file,
1083 const char *local_abspath,
1084 apr_pool_t *result_pool);
1087 * Return the next @a *patch in @a patch_file.
1088 * If no patch can be found, set @a *patch to NULL.
1089 * If @a reverse is TRUE, invert the patch while parsing it.
1090 * If @a ignore_whitespace is TRUE, allow patches with no leading
1091 * whitespace to be parsed.
1092 * Allocate results in @a result_pool.
1093 * Use @a scratch_pool for all other allocations.
1095 * @since New in 1.7. */
1097 svn_diff_parse_next_patch(svn_patch_t **patch,
1098 svn_patch_file_t *patch_file,
1099 svn_boolean_t reverse,
1100 svn_boolean_t ignore_whitespace,
1101 apr_pool_t *result_pool,
1102 apr_pool_t *scratch_pool);
1105 * Dispose of @a patch_file.
1106 * Use @a scratch_pool for all temporary allocations.
1108 * @since New in 1.7.
1111 svn_diff_close_patch_file(svn_patch_file_t *patch_file,
1112 apr_pool_t *scratch_pool);
1116 #endif /* __cplusplus */
1118 #endif /* SVN_DIFF_H */