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