svn_diff.h revision 262253
1/**
2 * @copyright
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
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
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
19 *    under the License.
20 * ====================================================================
21 * @endcopyright
22 *
23 * @file svn_diff.h
24 * @brief Contextual diffing.
25 *
26 * This is an internalized library for performing contextual diffs
27 * between sources of data.
28 *
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.
34 *
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.
39 *
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.
45 */
46
47
48#ifndef SVN_DIFF_H
49#define SVN_DIFF_H
50
51#include <apr.h>
52#include <apr_pools.h>
53#include <apr_tables.h>   /* for apr_array_header_t */
54
55#include "svn_types.h"
56#include "svn_io.h"       /* for svn_stream_t */
57#include "svn_string.h"
58
59#ifdef __cplusplus
60extern "C" {
61#endif /* __cplusplus */
62
63
64
65/**
66 * Get libsvn_diff version information.
67 *
68 * @since New in 1.1.
69 */
70const svn_version_t *
71svn_diff_version(void);
72
73
74/* Diffs. */
75
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
79 * other routines.
80 */
81typedef struct svn_diff_t svn_diff_t;
82
83/**
84 * There are four types of datasources.  In GNU diff3 terminology,
85 * the first three types correspond to the phrases "older", "mine",
86 * and "yours".
87 */
88typedef enum svn_diff_datasource_e
89{
90  /** The oldest form of the data. */
91  svn_diff_datasource_original,
92
93  /** The same data, but potentially changed by the user. */
94  svn_diff_datasource_modified,
95
96  /** The latest version of the data, possibly different than the
97   * user's modified version.
98   */
99  svn_diff_datasource_latest,
100
101  /** The common ancestor of original and modified. */
102  svn_diff_datasource_ancestor
103
104} svn_diff_datasource_e;
105
106
107/** A vtable for reading data from the three datasources.
108 * @since New in 1.7. */
109typedef struct svn_diff_fns2_t
110{
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);
117
118  /** Close the datasource of type @a datasource. */
119  svn_error_t *(*datasource_close)(void *diff_baton,
120                                   svn_diff_datasource_e datasource);
121
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.
125   */
126  svn_error_t *(*datasource_get_next_token)(apr_uint32_t *hash, void **token,
127                                            void *diff_baton,
128                                            svn_diff_datasource_e datasource);
129
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.
135   */
136  svn_error_t *(*token_compare)(void *diff_baton,
137                                void *ltoken,
138                                void *rtoken,
139                                int *compare);
140
141  /** Free @a token from memory, the diff algorithm is done with it. */
142  void (*token_discard)(void *diff_baton,
143                        void *token);
144
145  /** Free *all* tokens from memory, they're no longer needed. */
146  void (*token_discard_all)(void *diff_baton);
147} svn_diff_fns2_t;
148
149
150/** Like #svn_diff_fns2_t except with datasource_open() instead of
151 * datasources_open().
152 *
153 * @deprecated Provided for backward compatibility with the 1.6 API.
154 */
155typedef struct svn_diff_fns_t
156{
157  svn_error_t *(*datasource_open)(void *diff_baton,
158                                  svn_diff_datasource_e datasource);
159
160  svn_error_t *(*datasource_close)(void *diff_baton,
161                                   svn_diff_datasource_e datasource);
162
163  svn_error_t *(*datasource_get_next_token)(apr_uint32_t *hash, void **token,
164                                            void *diff_baton,
165                                            svn_diff_datasource_e datasource);
166
167  svn_error_t *(*token_compare)(void *diff_baton,
168                                void *ltoken,
169                                void *rtoken,
170                                int *compare);
171
172  void (*token_discard)(void *diff_baton,
173                        void *token);
174
175  void (*token_discard_all)(void *diff_baton);
176} svn_diff_fns_t;
177
178
179/* The Main Events */
180
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.
184 *
185 * @since New in 1.7.
186 */
187svn_error_t *
188svn_diff_diff_2(svn_diff_t **diff,
189                void *diff_baton,
190                const svn_diff_fns2_t *diff_fns,
191                apr_pool_t *pool);
192
193/** Like svn_diff_diff_2() but using #svn_diff_fns_t instead of
194 * #svn_diff_fns2_t.
195 *
196 * @deprecated Provided for backward compatibility with the 1.6 API.
197 */
198SVN_DEPRECATED
199svn_error_t *
200svn_diff_diff(svn_diff_t **diff,
201              void *diff_baton,
202              const svn_diff_fns_t *diff_fns,
203              apr_pool_t *pool);
204
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.
209 *
210 * @since New in 1.7.
211 */
212svn_error_t *
213svn_diff_diff3_2(svn_diff_t **diff,
214                 void *diff_baton,
215                 const svn_diff_fns2_t *diff_fns,
216                 apr_pool_t *pool);
217
218/** Like svn_diff_diff3_2() but using #svn_diff_fns_t instead of
219 * #svn_diff_fns2_t.
220 *
221 * @deprecated Provided for backward compatibility with the 1.6 API.
222 */
223SVN_DEPRECATED
224svn_error_t *
225svn_diff_diff3(svn_diff_t **diff,
226               void *diff_baton,
227               const svn_diff_fns_t *diff_fns,
228               apr_pool_t *pool);
229
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.
235 *
236 * @since New in 1.7.
237 */
238svn_error_t *
239svn_diff_diff4_2(svn_diff_t **diff,
240                 void *diff_baton,
241                 const svn_diff_fns2_t *diff_fns,
242                 apr_pool_t *pool);
243
244/** Like svn_diff_diff4_2() but using #svn_diff_fns_t instead of
245 * #svn_diff_fns2_t.
246 *
247 * @deprecated Provided for backward compatibility with the 1.6 API.
248 */
249SVN_DEPRECATED
250svn_error_t *
251svn_diff_diff4(svn_diff_t **diff,
252               void *diff_baton,
253               const svn_diff_fns_t *diff_fns,
254               apr_pool_t *pool);
255
256
257/* Utility functions */
258
259/** Determine if a diff object contains conflicts.  If it does, return
260 * @c TRUE, else return @c FALSE.
261 */
262svn_boolean_t
263svn_diff_contains_conflicts(svn_diff_t *diff);
264
265
266/** Determine if a diff object contains actual differences between the
267 * datasources.  If so, return @c TRUE, else return @c FALSE.
268 */
269svn_boolean_t
270svn_diff_contains_diffs(svn_diff_t *diff);
271
272
273
274
275/* Displaying Diffs */
276
277/** A vtable for displaying (or consuming) differences between datasources.
278 *
279 * Differences, similarities, and conflicts are described by lining up
280 * "ranges" of data.
281 *
282 * Any of the function pointers in this vtable may be NULL to ignore the
283 * corresponding kinds of output.
284 *
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.
288 */
289typedef struct svn_diff_output_fns_t
290{
291  /* Two-way and three-way diffs both call the first two output functions: */
292
293  /**
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.
299   *
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.
305   */
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);
313
314  /**
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.
320   *
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.
324   */
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);
332
333  /* ------ The following callbacks are used by three-way diffs only --- */
334
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.
338   */
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);
346
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.
350   */
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);
358
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.
367   */
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;
377
378/** Style for displaying conflicts during diff3 output.
379 *
380 * @since New in 1.6.
381 */
382typedef enum svn_diff_conflict_display_style_t
383{
384  /** Display modified and latest, with conflict markers. */
385  svn_diff_conflict_display_modified_latest,
386
387  /** Like svn_diff_conflict_display_modified_latest, but with an
388      extra effort to identify common sequences between modified and
389      latest. */
390  svn_diff_conflict_display_resolved_modified_latest,
391
392  /** Display modified, original, and latest, with conflict
393      markers. */
394  svn_diff_conflict_display_modified_original_latest,
395
396  /** Just display modified, with no markers. */
397  svn_diff_conflict_display_modified,
398
399  /** Just display latest, with no markers. */
400  svn_diff_conflict_display_latest,
401
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;
406
407
408/** Given a vtable of @a output_fns/@a output_baton for consuming
409 * differences, output the differences in @a diff.
410 */
411svn_error_t *
412svn_diff_output(svn_diff_t *diff,
413                void *output_baton,
414                const svn_diff_output_fns_t *output_fns);
415
416
417
418/* Diffs on files */
419
420/** To what extent whitespace should be ignored when comparing lines.
421 *
422 * @since New in 1.4.
423 */
424typedef enum svn_diff_file_ignore_space_t
425{
426  /** Ignore no whitespace. */
427  svn_diff_file_ignore_space_none,
428
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,
432
433  /** Ignore all whitespace characters. */
434  svn_diff_file_ignore_space_all
435} svn_diff_file_ignore_space_t;
436
437/** Options to control the behaviour of the file diff routines.
438 *
439 * @since New in 1.4.
440 *
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().
444 *
445 * @note Although its name suggests otherwise, this structure is used to
446 *       pass options to file as well as in-memory diff functions.
447 */
448typedef struct svn_diff_file_options_t
449{
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
459    * @c FALSE.
460    */
461  svn_boolean_t show_c_function;
462} svn_diff_file_options_t;
463
464/** Allocate a @c svn_diff_file_options_t structure in @a pool, initializing
465 * it with default values.
466 *
467 * @since New in 1.4.
468 */
469svn_diff_file_options_t *
470svn_diff_file_options_create(apr_pool_t *pool);
471
472/**
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.
476 *
477 * @since New in 1.4.
478 *
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).
485 */
486svn_error_t *
487svn_diff_file_options_parse(svn_diff_file_options_t *options,
488                            const apr_array_header_t *args,
489                            apr_pool_t *pool);
490
491
492/** A convenience function to produce a diff between two files.
493 *
494 * @since New in 1.4.
495 *
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.)
499 *
500 * Compare lines according to the relevant fields of @a options.
501 */
502svn_error_t *
503svn_diff_file_diff_2(svn_diff_t **diff,
504                     const char *original,
505                     const char *modified,
506                     const svn_diff_file_options_t *options,
507                     apr_pool_t *pool);
508
509/** Similar to svn_file_diff_2(), but with @a options set to a struct with
510 * default options.
511 *
512 * @deprecated Provided for backwards compatibility with the 1.3 API.
513 */
514SVN_DEPRECATED
515svn_error_t *
516svn_diff_file_diff(svn_diff_t **diff,
517                   const char *original,
518                   const char *modified,
519                   apr_pool_t *pool);
520
521/** A convenience function to produce a diff between three files.
522 *
523 * @since New in 1.4.
524 *
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
527 * file.
528 *
529 * Compare lines according to the relevant fields of @a options.
530 */
531svn_error_t *
532svn_diff_file_diff3_2(svn_diff_t **diff,
533                      const char *original,
534                      const char *modified,
535                      const char *latest,
536                      const svn_diff_file_options_t *options,
537                      apr_pool_t *pool);
538
539/** Similar to svn_diff_file_diff3_2(), but with @a options set to a struct
540 * with default options.
541 *
542 * @deprecated Provided for backwards compatibility with the 1.3 API.
543 */
544SVN_DEPRECATED
545svn_error_t *
546svn_diff_file_diff3(svn_diff_t **diff,
547                    const char *original,
548                    const char *modified,
549                    const char *latest,
550                    apr_pool_t *pool);
551
552/** A convenience function to produce a diff between four files.
553 *
554 * @since New in 1.4.
555 *
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.)
559 *
560 * Compare lines according to the relevant fields of @a options.
561 */
562svn_error_t *
563svn_diff_file_diff4_2(svn_diff_t **diff,
564                      const char *original,
565                      const char *modified,
566                      const char *latest,
567                      const char *ancestor,
568                      const svn_diff_file_options_t *options,
569                      apr_pool_t *pool);
570
571/** Similar to svn_file_diff4_2(), but with @a options set to a struct with
572 * default options.
573 *
574 * @deprecated Provided for backwards compatibility with the 1.3 API.
575 */
576SVN_DEPRECATED
577svn_error_t *
578svn_diff_file_diff4(svn_diff_t **diff,
579                    const char *original,
580                    const char *modified,
581                    const char *latest,
582                    const char *ancestor,
583                    apr_pool_t *pool);
584
585/** A convenience function to produce unified diff output from the
586 * diff generated by svn_diff_file_diff().
587 *
588 * @since New in 1.5.
589 *
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.
602 */
603svn_error_t *
604svn_diff_file_output_unified3(svn_stream_t *output_stream,
605                              svn_diff_t *diff,
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,
613                              apr_pool_t *pool);
614
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.
617 *
618 * @deprecated Provided for backwards compatibility with the 1.4 API.
619 */
620SVN_DEPRECATED
621svn_error_t *
622svn_diff_file_output_unified2(svn_stream_t *output_stream,
623                              svn_diff_t *diff,
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,
629                              apr_pool_t *pool);
630
631/** Similar to svn_diff_file_output_unified2(), but with @a header_encoding
632 * set to @c APR_LOCALE_CHARSET.
633 *
634 * @deprecated Provided for backward compatibility with the 1.2 API.
635 */
636SVN_DEPRECATED
637svn_error_t *
638svn_diff_file_output_unified(svn_stream_t *output_stream,
639                             svn_diff_t *diff,
640                             const char *original_path,
641                             const char *modified_path,
642                             const char *original_header,
643                             const char *modified_header,
644                             apr_pool_t *pool);
645
646
647/** A convenience function to produce diff3 output from the
648 * diff generated by svn_diff_file_diff3().
649 *
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.
657 *
658 * @since New in 1.6.
659 */
660svn_error_t *
661svn_diff_file_output_merge2(svn_stream_t *output_stream,
662                            svn_diff_t *diff,
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,
671                            apr_pool_t *pool);
672
673
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.
677 *
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.
685 *
686 * @deprecated Provided for backward compatibility with the 1.5 API.
687 */
688SVN_DEPRECATED
689svn_error_t *
690svn_diff_file_output_merge(svn_stream_t *output_stream,
691                           svn_diff_t *diff,
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,
701                           apr_pool_t *pool);
702
703
704
705/* Diffs on in-memory structures */
706
707/** Generate @a diff output from the @a original and @a modified
708 * in-memory strings.  @a diff will be allocated from @a pool.
709 *
710 * @since New in 1.5.
711 */
712svn_error_t *
713svn_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,
717                         apr_pool_t *pool);
718
719
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.
722 *
723 * @since New in 1.5.
724 */
725svn_error_t *
726svn_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,
731                          apr_pool_t *pool);
732
733
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.
736 *
737 * @since New in 1.5.
738 */
739svn_error_t *
740svn_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,
746                          apr_pool_t *pool);
747
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.
751 *
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.
756 *
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 "@@".
760 *
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".
764 *
765 * @since New in 1.7. Hunk delimiter "##" has the special meaning since 1.8.
766 */
767svn_error_t *
768svn_diff_mem_string_output_unified2(svn_stream_t *output_stream,
769                                    svn_diff_t *diff,
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,
777                                    apr_pool_t *pool);
778
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
781 * set to NULL.
782 *
783 * @since New in 1.5.
784 */
785svn_error_t *
786svn_diff_mem_string_output_unified(svn_stream_t *output_stream,
787                                   svn_diff_t *diff,
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,
793                                   apr_pool_t *pool);
794
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.
798 *
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.
802 *
803 * @a conflict_style dictates how conflicts are displayed.
804 *
805 * @since New in 1.6.
806 */
807svn_error_t *
808svn_diff_mem_string_output_merge2(svn_stream_t *output_stream,
809                                  svn_diff_t *diff,
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,
818                                  apr_pool_t *pool);
819
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.
823 *
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.
831 *
832 * @deprecated Provided for backward compatibility with the 1.5 API.
833 */
834SVN_DEPRECATED
835svn_error_t *
836svn_diff_mem_string_output_merge(svn_stream_t *output_stream,
837                                 svn_diff_t *diff,
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,
847                                 apr_pool_t *pool);
848
849
850
851/* Diff parsing. If you want to apply a patch to a working copy
852 * rather than parse it, see svn_client_patch(). */
853
854/**
855 * Describes what operation has been performed on a file.
856 *
857 * @since New in 1.7.
858 */
859typedef enum svn_diff_operation_kind_e
860{
861  svn_diff_op_unchanged,
862  svn_diff_op_added,
863  svn_diff_op_deleted,
864  svn_diff_op_copied,
865  svn_diff_op_moved,
866  /* There's no tree changes, just text modifications. */
867  svn_diff_op_modified
868} svn_diff_operation_kind_t;
869
870/**
871 * A single hunk inside a patch.
872 *
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.
878 *
879 * For example, consider a hunk with the following diff text:
880 *
881 * @verbatim
882     @@ -1,5 +1,5 @@
883      #include <stdio.h>
884      int main(int argc, char *argv[]) {
885     -        printf("Hello World!\n");
886     +        printf("I like Subversion!\n");
887      } @endverbatim
888 *
889 * The original text of this hunk is:
890 *
891 * @verbatim
892     #include <stdio.h>
893     int main(int argc, char *argv[]) {
894             printf("Hello World!\n");
895     } @endverbatim
896 *
897 * And the modified text is:
898 *
899 * @verbatim
900     #include <stdio.h>
901     int main(int argc, char *argv[]) {
902             printf("I like Subversion!\n");
903     } @endverbatim
904 *
905 * @see svn_diff_hunk_readline_diff_text()
906 * @see svn_diff_hunk_readline_original_text()
907 * @see svn_diff_hunk_readline_modified_text()
908 *
909 * @since New in 1.7. */
910typedef struct svn_diff_hunk_t svn_diff_hunk_t;
911
912/**
913 * Allocate @a *stringbuf in @a result_pool, and read into it one line
914 * of the diff text of @a hunk. The hunk header is not returned only the
915 * unidiff data lines (starting with '+', '-', or ' ') are returned.
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.
924 *
925 * @note The hunk header information can be retrievied with the following
926 * functions:
927 * @see svn_diff_hunk_get_original_start()
928 * @see svn_diff_hunk_get_original_length()
929 * @see svn_diff_hunk_get_modified_start()
930 * @see svn_diff_hunk_get_modified_length()
931 *
932 * @since New in 1.7.
933 */
934svn_error_t *
935svn_diff_hunk_readline_diff_text(svn_diff_hunk_t *hunk,
936                                 svn_stringbuf_t **stringbuf,
937                                 const char **eol,
938                                 svn_boolean_t *eof,
939                                 apr_pool_t *result_pool,
940                                 apr_pool_t *scratch_pool);
941
942/**
943 * Allocate @a *stringbuf in @a result_pool, and read into it one line
944 * of the original text of @a hunk.
945 * The line-terminator is detected automatically and stored in @a *eol
946 * if @a eol is not NULL.
947 * If EOF is reached, set @a *eof to TRUE, and set @a *eol to NULL if the
948 * hunk text does not end with a newline character and @a eol is not NULL.
949 * Temporary allocations will be performed in @a scratch_pool.
950 *
951 * @see svn_diff_hunk_t
952 * @since New in 1.7.
953 */
954svn_error_t *
955svn_diff_hunk_readline_original_text(svn_diff_hunk_t *hunk,
956                                     svn_stringbuf_t **stringbuf,
957                                     const char **eol,
958                                     svn_boolean_t *eof,
959                                     apr_pool_t *result_pool,
960                                     apr_pool_t *scratch_pool);
961
962/**
963 * Like svn_diff_hunk_readline_original_text(), but it returns lines from
964 * the modified text of the hunk.
965 *
966 * @see svn_diff_hunk_t
967 * @since New in 1.7.
968 */
969svn_error_t *
970svn_diff_hunk_readline_modified_text(svn_diff_hunk_t *hunk,
971                                     svn_stringbuf_t **stringbuf,
972                                     const char **eol,
973                                     svn_boolean_t *eof,
974                                     apr_pool_t *result_pool,
975                                     apr_pool_t *scratch_pool);
976
977/** Reset the diff text of @a hunk so it can be read again from the start.
978 * @since New in 1.7. */
979void
980svn_diff_hunk_reset_diff_text(svn_diff_hunk_t *hunk);
981
982/** Reset the original text of @a hunk so it can be read again from the start.
983 * @since New in 1.7. */
984void
985svn_diff_hunk_reset_original_text(svn_diff_hunk_t *hunk);
986
987/** Reset the modified text of @a hunk so it can be read again from the start.
988 * @since New in 1.7. */
989void
990svn_diff_hunk_reset_modified_text(svn_diff_hunk_t *hunk);
991
992/** Return the line offset of the original hunk text,
993 * as parsed from the hunk header.
994 * @since New in 1.7. */
995svn_linenum_t
996svn_diff_hunk_get_original_start(const svn_diff_hunk_t *hunk);
997
998/** Return the number of lines in the original @a hunk text,
999 * as parsed from the hunk header.
1000 * @since New in 1.7. */
1001svn_linenum_t
1002svn_diff_hunk_get_original_length(const svn_diff_hunk_t *hunk);
1003
1004/** Return the line offset of the modified @a hunk text,
1005 * as parsed from the hunk header.
1006 * @since New in 1.7. */
1007svn_linenum_t
1008svn_diff_hunk_get_modified_start(const svn_diff_hunk_t *hunk);
1009
1010/** Return the number of lines in the modified @a hunk text,
1011 * as parsed from the hunk header.
1012 * @since New in 1.7. */
1013svn_linenum_t
1014svn_diff_hunk_get_modified_length(const svn_diff_hunk_t *hunk);
1015
1016/** Return the number of lines of leading context of @a hunk,
1017 * i.e. the number of lines starting with ' ' before the first line
1018 * that starts with a '+' or '-'.
1019 * @since New in 1.7. */
1020svn_linenum_t
1021svn_diff_hunk_get_leading_context(const svn_diff_hunk_t *hunk);
1022
1023/** Return the number of lines of trailing context of @a hunk,
1024 * i.e. the number of lines starting with ' ' after the last line
1025 * that starts with a '+' or '-'.
1026 * @since New in 1.7. */
1027svn_linenum_t
1028svn_diff_hunk_get_trailing_context(const svn_diff_hunk_t *hunk);
1029
1030/**
1031 * Data type to manage parsing of properties in patches.
1032 * API users should not allocate structures of this type directly.
1033 *
1034 * @since New in 1.7. */
1035typedef struct svn_prop_patch_t {
1036  const char *name;
1037
1038  /** Represents the operation performed on the property */
1039  svn_diff_operation_kind_t operation;
1040
1041  /**
1042   * An array containing an svn_diff_hunk_t object for each hunk parsed
1043   * from the patch associated with our property name */
1044  apr_array_header_t *hunks;
1045} svn_prop_patch_t;
1046
1047/**
1048 * Data type to manage parsing of patches.
1049 * API users should not allocate structures of this type directly.
1050 *
1051 * @since New in 1.7. */
1052typedef struct svn_patch_t {
1053  /**
1054   * The old and new file names as retrieved from the patch file.
1055   * These paths are UTF-8 encoded and canonicalized, but otherwise
1056   * left unchanged from how they appeared in the patch file. */
1057  const char *old_filename;
1058  const char *new_filename;
1059
1060  /**
1061   * An array containing an svn_diff_hunk_t * for each hunk parsed
1062   * from the patch. */
1063  apr_array_header_t *hunks;
1064
1065  /**
1066   * A hash table keyed by property names containing svn_prop_patch_t
1067   * object for each property parsed from the patch. */
1068  apr_hash_t *prop_patches;
1069
1070  /**
1071   * Represents the operation performed on the file. */
1072  svn_diff_operation_kind_t operation;
1073
1074  /**
1075   * Indicates whether the patch is being interpreted in reverse. */
1076  svn_boolean_t reverse;
1077} svn_patch_t;
1078
1079/** An opaque type representing an open patch file.
1080 *
1081 * @since New in 1.7. */
1082typedef struct svn_patch_file_t svn_patch_file_t;
1083
1084/** Open @a patch_file at @a local_abspath.
1085 * Allocate @a patch_file in @a result_pool.
1086 *
1087 * @since New in 1.7. */
1088svn_error_t *
1089svn_diff_open_patch_file(svn_patch_file_t **patch_file,
1090                         const char *local_abspath,
1091                         apr_pool_t *result_pool);
1092
1093/**
1094 * Return the next @a *patch in @a patch_file.
1095 * If no patch can be found, set @a *patch to NULL.
1096 * If @a reverse is TRUE, invert the patch while parsing it.
1097 * If @a ignore_whitespace is TRUE, allow patches with no leading
1098 * whitespace to be parsed.
1099 * Allocate results in @a result_pool.
1100 * Use @a scratch_pool for all other allocations.
1101 *
1102 * @since New in 1.7. */
1103svn_error_t *
1104svn_diff_parse_next_patch(svn_patch_t **patch,
1105                          svn_patch_file_t *patch_file,
1106                          svn_boolean_t reverse,
1107                          svn_boolean_t ignore_whitespace,
1108                          apr_pool_t *result_pool,
1109                          apr_pool_t *scratch_pool);
1110
1111/**
1112 * Dispose of @a patch_file.
1113 * Use @a scratch_pool for all temporary allocations.
1114 *
1115 * @since New in 1.7.
1116 */
1117svn_error_t *
1118svn_diff_close_patch_file(svn_patch_file_t *patch_file,
1119                          apr_pool_t *scratch_pool);
1120
1121#ifdef __cplusplus
1122}
1123#endif /* __cplusplus */
1124
1125#endif /* SVN_DIFF_H */
1126