diff options
author | svnmir <svnmir@FreeBSD.org> | 2015-08-09 04:37:48 +0000 |
---|---|---|
committer | svnmir <svnmir@FreeBSD.org> | 2015-08-09 04:37:48 +0000 |
commit | 91308aec6ca93cab82659cd43b3f6a83d366350b (patch) | |
tree | 78a13bd0acf7405df6eb6ca94a4e354d124065a6 /subversion/libsvn_subr/mergeinfo.c | |
parent | 0d1e05fe9c6027aaf742eb9b8b05f4dbefb92e2e (diff) | |
download | FreeBSD-src-91308aec6ca93cab82659cd43b3f6a83d366350b.zip FreeBSD-src-91308aec6ca93cab82659cd43b3f6a83d366350b.tar.gz |
Vendor import subversion-1.8.14
Diffstat (limited to 'subversion/libsvn_subr/mergeinfo.c')
-rw-r--r-- | subversion/libsvn_subr/mergeinfo.c | 67 |
1 files changed, 58 insertions, 9 deletions
diff --git a/subversion/libsvn_subr/mergeinfo.c b/subversion/libsvn_subr/mergeinfo.c index 63496ae..131fe59 100644 --- a/subversion/libsvn_subr/mergeinfo.c +++ b/subversion/libsvn_subr/mergeinfo.c @@ -611,6 +611,43 @@ svn_rangelist__parse(svn_rangelist_t **rangelist, return SVN_NO_ERROR; } +/* Return TRUE, if all ranges in RANGELIST are in ascending order and do + * not overlap and are not adjacent. + * + * ### Can yield false negatives: ranges of differing inheritance are + * allowed to be adjacent. + * + * If this returns FALSE, you probaly want to qsort() the + * ranges and then call svn_rangelist__combine_adjacent_ranges(). + */ +static svn_boolean_t +is_rangelist_normalized(svn_rangelist_t *rangelist) +{ + int i; + svn_merge_range_t **ranges = (svn_merge_range_t **)rangelist->elts; + + for (i = 0; i < rangelist->nelts-1; ++i) + if (ranges[i]->end >= ranges[i+1]->start) + return FALSE; + + return TRUE; +} + +svn_error_t * +svn_rangelist__canonicalize(svn_rangelist_t *rangelist, + apr_pool_t *scratch_pool) +{ + if (! is_rangelist_normalized(rangelist)) + { + qsort(rangelist->elts, rangelist->nelts, rangelist->elt_size, + svn_sort_compare_ranges); + + SVN_ERR(svn_rangelist__combine_adjacent_ranges(rangelist, scratch_pool)); + } + + return SVN_NO_ERROR; +} + svn_error_t * svn_rangelist__combine_adjacent_ranges(svn_rangelist_t *rangelist, apr_pool_t *scratch_pool) @@ -692,15 +729,11 @@ parse_revision_line(const char **input, const char *end, svn_mergeinfo_t hash, if (*input != end) *input = *input + 1; - /* Sort the rangelist, combine adjacent ranges into single ranges, - and make sure there are no overlapping ranges. */ - if (rangelist->nelts > 1) - { - qsort(rangelist->elts, rangelist->nelts, rangelist->elt_size, - svn_sort_compare_ranges); - - SVN_ERR(svn_rangelist__combine_adjacent_ranges(rangelist, scratch_pool)); - } + /* Sort the rangelist, combine adjacent ranges into single ranges, and + make sure there are no overlapping ranges. Luckily, most data in + svn:mergeinfo will already be in normalized form and this will be quick. + */ + SVN_ERR(svn_rangelist__canonicalize(rangelist, scratch_pool)); /* Handle any funky mergeinfo with relative merge source paths that might exist due to issue #3547. It's possible that this issue allowed @@ -1973,6 +2006,22 @@ svn_mergeinfo_sort(svn_mergeinfo_t input, apr_pool_t *pool) return SVN_NO_ERROR; } +svn_error_t * +svn_mergeinfo__canonicalize_ranges(svn_mergeinfo_t mergeinfo, + apr_pool_t *scratch_pool) +{ + apr_hash_index_t *hi; + + for (hi = apr_hash_first(scratch_pool, mergeinfo); hi; hi = apr_hash_next(hi)) + { + apr_array_header_t *rl = svn__apr_hash_index_val(hi); + + SVN_ERR(svn_rangelist__canonicalize(rl, scratch_pool)); + } + + return SVN_NO_ERROR; +} + svn_mergeinfo_catalog_t svn_mergeinfo_catalog_dup(svn_mergeinfo_catalog_t mergeinfo_catalog, apr_pool_t *pool) |