aboutsummaryrefslogtreecommitdiffstats
path: root/subversion/libsvn_diff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-05-31 20:58:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-05-31 20:58:28 +0000
commitbbee6e0814d5875b85b81f26fd4ca7a28b6f9570 (patch)
tree726fcf32b39ca8976d7aa51b67c7236509f1bde4 /subversion/libsvn_diff
parent38cef28c88864beaadac7a7cffdec6da952c3eb2 (diff)
downloadsrc-vendor/subversion.tar.gz
src-vendor/subversion.zip
Notes
Notes: svn path=/vendor/subversion/dist/; revision=361669 svn path=/vendor/subversion/subversion-1.14.0/; revision=361670; tag=vendor/subversion/subversion-1.14.0
Diffstat (limited to 'subversion/libsvn_diff')
-rw-r--r--subversion/libsvn_diff/diff_file.c2
-rw-r--r--subversion/libsvn_diff/diff_tree.c75
-rw-r--r--subversion/libsvn_diff/libsvn_diff.pc.in8
-rw-r--r--subversion/libsvn_diff/parse-diff.c104
4 files changed, 91 insertions, 98 deletions
diff --git a/subversion/libsvn_diff/diff_file.c b/subversion/libsvn_diff/diff_file.c
index d0182c8b3555..6d72159cfbb0 100644
--- a/subversion/libsvn_diff/diff_file.c
+++ b/subversion/libsvn_diff/diff_file.c
@@ -1253,7 +1253,7 @@ svn_diff_file_options_parse(svn_diff_file_options_t *options,
apr_array_cat(argv, args);
APR_ARRAY_PUSH(argv, const char *) = NULL;
- apr_getopt_init(&os, pool,
+ apr_getopt_init(&os, pool,
argv->nelts - 1 /* Exclude trailing NULL */,
(const char *const *) argv->elts);
diff --git a/subversion/libsvn_diff/diff_tree.c b/subversion/libsvn_diff/diff_tree.c
index 8490179c48e7..d18b242c6343 100644
--- a/subversion/libsvn_diff/diff_tree.c
+++ b/subversion/libsvn_diff/diff_tree.c
@@ -37,14 +37,6 @@
#include "private/svn_diff_tree.h"
#include "svn_private_config.h"
-typedef struct tree_processor_t
-{
- svn_diff_tree_processor_t tp;
-
- /* void *future_extension */
-} tree_processor_t;
-
-
static svn_error_t *
default_dir_opened(void **new_dir_baton,
svn_boolean_t *skip,
@@ -215,33 +207,30 @@ svn_diff_tree_processor_t *
svn_diff__tree_processor_create(void *baton,
apr_pool_t *result_pool)
{
- tree_processor_t *wrapper;
- wrapper = apr_pcalloc(result_pool, sizeof(*wrapper));
-
- wrapper->tp.baton = baton;
+ svn_diff_tree_processor_t *tp = apr_pcalloc(result_pool, sizeof(*tp));
- wrapper->tp.dir_opened = default_dir_opened;
- wrapper->tp.dir_added = default_dir_added;
- wrapper->tp.dir_deleted = default_dir_deleted;
- wrapper->tp.dir_changed = default_dir_changed;
- wrapper->tp.dir_closed = default_dir_closed;
+ tp->baton = baton;
- wrapper->tp.file_opened = default_file_opened;
- wrapper->tp.file_added = default_file_added;
- wrapper->tp.file_deleted = default_file_deleted;
- wrapper->tp.file_changed = default_file_changed;
- wrapper->tp.file_closed = default_file_closed;
+ tp->dir_opened = default_dir_opened;
+ tp->dir_added = default_dir_added;
+ tp->dir_deleted = default_dir_deleted;
+ tp->dir_changed = default_dir_changed;
+ tp->dir_closed = default_dir_closed;
- wrapper->tp.node_absent = default_node_absent;
+ tp->file_opened = default_file_opened;
+ tp->file_added = default_file_added;
+ tp->file_deleted = default_file_deleted;
+ tp->file_changed = default_file_changed;
+ tp->file_closed = default_file_closed;
+ tp->node_absent = default_node_absent;
- return &wrapper->tp;
+ return tp;
}
struct reverse_tree_baton_t
{
const svn_diff_tree_processor_t *processor;
- const char *prefix_relpath;
};
static svn_error_t *
@@ -259,9 +248,6 @@ reverse_dir_opened(void **new_dir_baton,
{
struct reverse_tree_baton_t *rb = processor->baton;
- if (rb->prefix_relpath)
- relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
SVN_ERR(rb->processor->dir_opened(new_dir_baton, skip, skip_children,
relpath,
right_source, left_source,
@@ -284,9 +270,6 @@ reverse_dir_added(const char *relpath,
{
struct reverse_tree_baton_t *rb = processor->baton;
- if (rb->prefix_relpath)
- relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
SVN_ERR(rb->processor->dir_deleted(relpath,
right_source,
right_props,
@@ -307,9 +290,6 @@ reverse_dir_deleted(const char *relpath,
{
struct reverse_tree_baton_t *rb = processor->baton;
- if (rb->prefix_relpath)
- relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
SVN_ERR(rb->processor->dir_added(relpath,
NULL,
left_source,
@@ -335,9 +315,6 @@ reverse_dir_changed(const char *relpath,
struct reverse_tree_baton_t *rb = processor->baton;
apr_array_header_t *reversed_prop_changes = NULL;
- if (rb->prefix_relpath)
- relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
if (prop_changes)
{
SVN_ERR_ASSERT(left_props != NULL && right_props != NULL);
@@ -367,9 +344,6 @@ reverse_dir_closed(const char *relpath,
{
struct reverse_tree_baton_t *rb = processor->baton;
- if (rb->prefix_relpath)
- relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
SVN_ERR(rb->processor->dir_closed(relpath,
right_source,
left_source,
@@ -393,9 +367,6 @@ reverse_file_opened(void **new_file_baton,
{
struct reverse_tree_baton_t *rb = processor->baton;
- if (rb->prefix_relpath)
- relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
SVN_ERR(rb->processor->file_opened(new_file_baton,
skip,
relpath,
@@ -423,9 +394,6 @@ reverse_file_added(const char *relpath,
{
struct reverse_tree_baton_t *rb = processor->baton;
- if (rb->prefix_relpath)
- relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
SVN_ERR(rb->processor->file_deleted(relpath,
right_source,
right_file,
@@ -447,9 +415,6 @@ reverse_file_deleted(const char *relpath,
{
struct reverse_tree_baton_t *rb = processor->baton;
- if (rb->prefix_relpath)
- relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
SVN_ERR(rb->processor->file_added(relpath,
NULL /* copyfrom src */,
left_source,
@@ -480,9 +445,6 @@ reverse_file_changed(const char *relpath,
struct reverse_tree_baton_t *rb = processor->baton;
apr_array_header_t *reversed_prop_changes = NULL;
- if (rb->prefix_relpath)
- relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
if (prop_changes)
{
SVN_ERR_ASSERT(left_props != NULL && right_props != NULL);
@@ -515,9 +477,6 @@ reverse_file_closed(const char *relpath,
{
struct reverse_tree_baton_t *rb = processor->baton;
- if (rb->prefix_relpath)
- relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
SVN_ERR(rb->processor->file_closed(relpath,
right_source,
left_source,
@@ -536,9 +495,6 @@ reverse_node_absent(const char *relpath,
{
struct reverse_tree_baton_t *rb = processor->baton;
- if (rb->prefix_relpath)
- relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool);
-
SVN_ERR(rb->processor->node_absent(relpath,
dir_baton,
rb->processor,
@@ -549,7 +505,6 @@ reverse_node_absent(const char *relpath,
const svn_diff_tree_processor_t *
svn_diff__tree_processor_reverse_create(const svn_diff_tree_processor_t * processor,
- const char *prefix_relpath,
apr_pool_t *result_pool)
{
struct reverse_tree_baton_t *rb;
@@ -557,8 +512,6 @@ svn_diff__tree_processor_reverse_create(const svn_diff_tree_processor_t * proces
rb = apr_pcalloc(result_pool, sizeof(*rb));
rb->processor = processor;
- if (prefix_relpath)
- rb->prefix_relpath = apr_pstrdup(result_pool, prefix_relpath);
reverse = svn_diff__tree_processor_create(rb, result_pool);
diff --git a/subversion/libsvn_diff/libsvn_diff.pc.in b/subversion/libsvn_diff/libsvn_diff.pc.in
index eed9d886a9ac..34ec384f2ada 100644
--- a/subversion/libsvn_diff/libsvn_diff.pc.in
+++ b/subversion/libsvn_diff/libsvn_diff.pc.in
@@ -6,7 +6,7 @@ includedir=@includedir@
Name: libsvn_diff
Description: Subversion Diff Library
Version: @PACKAGE_VERSION@
-Requires: apr-@SVN_APR_MAJOR_VERSION@
-Requires.private: libsvn_subr
-Libs: -L${libdir} -lsvn_diff @SVN_ZLIB_LIBS@
-Cflags: -I${includedir}
+Requires: apr-@SVN_APR_MAJOR_VERSION@
+Requires.private: libsvn_subr
+Libs: -L${libdir} -lsvn_diff-1 @SVN_ZLIB_LIBS@
+Cflags: -I${includedir}/subversion-1
diff --git a/subversion/libsvn_diff/parse-diff.c b/subversion/libsvn_diff/parse-diff.c
index f2159694c4f6..4fc5bfd46d73 100644
--- a/subversion/libsvn_diff/parse-diff.c
+++ b/subversion/libsvn_diff/parse-diff.c
@@ -69,6 +69,11 @@ struct svn_diff_hunk_t {
/* APR file handle to the patch file this hunk came from. */
apr_file_t *apr_file;
+ /* Whether the hunk was interpreted as pretty-print mergeinfo. If so,
+ the hunk content is in PATCH and the rest of this hunk object is
+ mostly uninitialized. */
+ svn_boolean_t is_pretty_print_mergeinfo;
+
/* Ranges used to keep track of this hunk's texts positions within
* the patch file. */
struct svn_diff__hunk_range diff_text_range;
@@ -210,7 +215,7 @@ svn_diff_hunk__create_adds_single_line(svn_diff_hunk_t **hunk_out,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- SVN_ERR(add_or_delete_single_line(hunk_out, line, patch,
+ SVN_ERR(add_or_delete_single_line(hunk_out, line, patch,
(!patch->reverse),
result_pool, scratch_pool));
return SVN_NO_ERROR;
@@ -899,10 +904,6 @@ parse_prop_name(const char **prop_name, const char *header,
* The hunk header has the following format:
* ## -0,NUMBER_OF_REVERSE_MERGES +0,NUMBER_OF_FORWARD_MERGES ##
*
- * At this point, the number of reverse merges has already been
- * parsed into HUNK->ORIGINAL_LENGTH, and the number of forward
- * merges has been parsed into HUNK->MODIFIED_LENGTH.
- *
* The header is followed by a list of mergeinfo, one path per line.
* This function parses such lines. Lines describing reverse merges
* appear first, and then all lines describing forward merges appear.
@@ -914,18 +915,27 @@ parse_prop_name(const char **prop_name, const char *header,
* ":r", which in turn is followed by a mergeinfo revision range,
* which is terminated by whitespace or end-of-string.
*
- * If the current line meets the above criteria and we're able
- * to parse valid mergeinfo from it, the resulting mergeinfo
- * is added to patch->mergeinfo or patch->reverse_mergeinfo,
- * and we proceed to the next line.
+ * *NUMBER_OF_REVERSE_MERGES and *NUMBER_OF_FORWARD_MERGES are the
+ * numbers of reverse and forward merges remaining to be read. This
+ * function decrements *NUMBER_OF_REVERSE_MERGES for each LINE
+ * parsed until that is zero, then *NUMBER_OF_FORWARD_MERGES for
+ * each LINE parsed until that is zero. If both are zero, it parses
+ * and discards LINE.
+ *
+ * If LINE is successfully parsed, *FOUND_MERGEINFO is set to TRUE,
+ * otherwise to FALSE.
+ *
+ * If LINE is successfully parsed and counted, the resulting mergeinfo
+ * is added to PATCH->mergeinfo or PATCH->reverse_mergeinfo.
*/
static svn_error_t *
-parse_mergeinfo(svn_boolean_t *found_mergeinfo,
- svn_stringbuf_t *line,
- svn_diff_hunk_t *hunk,
- svn_patch_t *patch,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+parse_pretty_mergeinfo_line(svn_boolean_t *found_mergeinfo,
+ svn_linenum_t *number_of_reverse_merges,
+ svn_linenum_t *number_of_forward_merges,
+ svn_stringbuf_t *line,
+ svn_patch_t *patch,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
char *slash = strchr(line->data, '/');
char *colon = strrchr(line->data, ':');
@@ -972,7 +982,7 @@ parse_mergeinfo(svn_boolean_t *found_mergeinfo,
if (mergeinfo)
{
- if (hunk->original_length > 0) /* reverse merges */
+ if (*number_of_reverse_merges > 0) /* reverse merges */
{
if (patch->reverse)
{
@@ -994,9 +1004,9 @@ parse_mergeinfo(svn_boolean_t *found_mergeinfo,
result_pool,
scratch_pool));
}
- hunk->original_length--;
+ (*number_of_reverse_merges)--;
}
- else if (hunk->modified_length > 0) /* forward merges */
+ else if (number_of_forward_merges > 0) /* forward merges */
{
if (patch->reverse)
{
@@ -1018,7 +1028,7 @@ parse_mergeinfo(svn_boolean_t *found_mergeinfo,
result_pool,
scratch_pool));
}
- hunk->modified_length--;
+ (*number_of_forward_merges)--;
}
*found_mergeinfo = TRUE;
@@ -1165,18 +1175,48 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
if (in_hunk && *is_property && *prop_name &&
strcmp(*prop_name, SVN_PROP_MERGEINFO) == 0)
{
- svn_boolean_t found_mergeinfo;
+ svn_boolean_t found_pretty_mergeinfo_line;
- SVN_ERR(parse_mergeinfo(&found_mergeinfo, line, *hunk, patch,
- result_pool, iterpool));
- if (found_mergeinfo)
- continue; /* Proceed to the next line in the svn:mergeinfo hunk. */
- else
+ if (! hunk_seen)
{
- /* Perhaps we can also use original_lines/modified_lines here */
+ /* We're reading the first line of the hunk, so the start
+ * of the line just read is the hunk text's byte offset. */
+ start = last_line;
+ }
- in_hunk = FALSE; /* On to next property */
+ SVN_ERR(parse_pretty_mergeinfo_line(&found_pretty_mergeinfo_line,
+ &original_lines, &modified_lines,
+ line, patch,
+ result_pool, iterpool));
+ if (found_pretty_mergeinfo_line)
+ {
+ hunk_seen = TRUE;
+ (*hunk)->is_pretty_print_mergeinfo = TRUE;
+ continue; /* Proceed to the next line in the svn:mergeinfo hunk. */
}
+
+ if ((*hunk)->is_pretty_print_mergeinfo)
+ {
+ /* We have reached the end of the pretty-print-mergeinfo hunk.
+ (This format uses only one hunk.) */
+ if (eof)
+ {
+ /* The hunk ends at EOF. */
+ end = pos;
+ }
+ else
+ {
+ /* The start of the current line marks the first byte
+ * after the hunk text. */
+ end = last_line;
+ }
+ original_end = end;
+ modified_end = end;
+ break;
+ }
+
+ /* Otherwise, this is a property diff in the
+ regular format so fall through to normal processing. */
}
if (in_hunk)
@@ -1195,7 +1235,7 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
c = line->data[0];
if (c == ' '
|| ((original_lines > 0 && modified_lines > 0)
- && (
+ && (
/* Tolerate chopped leading spaces on empty lines. */
(! eof && line->len == 0)
/* Maybe tolerate chopped leading spaces on non-empty lines. */
@@ -1971,10 +2011,10 @@ parse_hunks(svn_patch_t *patch, apr_file_t *apr_file,
else
last_prop_name = prop_name;
- /* Skip svn:mergeinfo properties.
- * Mergeinfo data cannot be represented as a hunk and
+ /* Skip pretty-printed svn:mergeinfo property hunks.
+ * Pretty-printed mergeinfo data cannot be represented as a hunk and
* is therefore stored in PATCH itself. */
- if (strcmp(prop_name, SVN_PROP_MERGEINFO) == 0)
+ if (hunk->is_pretty_print_mergeinfo)
continue;
SVN_ERR(add_property_hunk(patch, prop_name, hunk, prop_operation,
@@ -2045,7 +2085,7 @@ parse_binary_patch(svn_patch_t *patch, apr_file_t *apr_file,
else if (in_src)
{
patch->binary_patch = bpatch; /* SUCCESS! */
- break;
+ break;
}
else
{