You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/10 20:06:33 UTC
svn commit: r984153 [20/39] - in /subversion/branches/ignore-mergeinfo: ./
build/ build/ac-macros/ build/generator/ build/generator/templates/
build/hudson/ build/hudson/jobs/subversion-1.6.x-solaris/
build/hudson/jobs/subversion-1.6.x-ubuntu/ build/hu...
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/mergeinfo.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/mergeinfo.c Tue Aug 10 18:06:17 2010
@@ -115,10 +115,20 @@ parse_pathname(const char **input,
return SVN_NO_ERROR;
}
-/* Ways in which two svn_merge_range_t can intersect, if at all. */
+/* Return TRUE iff (svn_merge_range_t *) RANGE describes a valid, forward
+ * revision range.
+ *
+ * Note: The smallest valid value of RANGE->start is 0 because it is an
+ * exclusive endpoint, being one less than the revision number of the first
+ * change described by the range, and the oldest possible change is "r1" as
+ * there cannot be a change "r0". */
+#define IS_VALID_FORWARD_RANGE(range) \
+ (SVN_IS_VALID_REVNUM((range)->start) && ((range)->start < (range)->end))
+
+/* Ways in which two svn_merge_range_t can intersect or adjoin, if at all. */
typedef enum
{
- /* Ranges don't intersect. */
+ /* Ranges don't intersect and don't adjoin. */
svn__no_intersection,
/* Ranges are equal. */
@@ -127,7 +137,7 @@ typedef enum
/* Ranges adjoin but don't overlap. */
svn__adjoining_intersection,
- /* Ranges overalp but neither is a subset of the other. */
+ /* Ranges overlap but neither is a subset of the other. */
svn__overlapping_intersection,
/* One range is a proper subset of the other. */
@@ -144,16 +154,8 @@ get_type_of_intersection(const svn_merge
{
SVN_ERR_ASSERT(r1);
SVN_ERR_ASSERT(r2);
-
- /* Why not use SVN_IS_VALID_REVNUM here? Because revision 0
- is described START = -1, END = 0. See svn_merge_range_t. */
- SVN_ERR_ASSERT(r1->start >= -1);
- SVN_ERR_ASSERT(r2->start >= -1);
-
- SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(r1->end));
- SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(r2->end));
- SVN_ERR_ASSERT(r1->start < r1->end);
- SVN_ERR_ASSERT(r2->start < r2->end);
+ SVN_ERR_ASSERT(IS_VALID_FORWARD_RANGE(r1));
+ SVN_ERR_ASSERT(IS_VALID_FORWARD_RANGE(r2));
if (!(r1->start <= r2->end && r2->start <= r1->end))
*intersection_type = svn__no_intersection;
@@ -457,6 +459,10 @@ range_to_string(const svn_merge_range_t
}
/* Helper for svn_mergeinfo_parse()
+ Append revision ranges onto the array RANGELIST to represent the range
+ descriptions found in the string *INPUT. Read only as far as a newline
+ or the position END, whichever comes first. Set *INPUT to the position
+ after the last character of INPUT that was used.
revisionlist -> (revisionelement)(COMMA revisionelement)*
revisionrange -> REVISION "-" REVISION("*")
@@ -501,6 +507,11 @@ parse_rangelist(const char **input, cons
mrange->end = firstrev;
mrange->inheritable = TRUE;
+ if (firstrev == 0)
+ return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
+ _("Invalid revision number '0' found in "
+ "range list"));
+
if (*curr == '-')
{
svn_revnum_t secondrev;
@@ -696,7 +707,7 @@ svn_mergeinfo_parse(svn_mergeinfo_t *mer
svn_error_t *
svn_rangelist_merge(apr_array_header_t **rangelist,
- apr_array_header_t *changes,
+ const apr_array_header_t *changes,
apr_pool_t *pool)
{
int i, j;
@@ -763,20 +774,31 @@ svn_rangelist_merge(apr_array_header_t *
return SVN_NO_ERROR;
}
+/* Return TRUE iff the forward revision ranges FIRST and SECOND overlap and
+ * (if CONSIDER_INHERITANCE is TRUE) have the same inheritability. */
static svn_boolean_t
range_intersect(const svn_merge_range_t *first, const svn_merge_range_t *second,
svn_boolean_t consider_inheritance)
{
+ SVN_ERR_ASSERT_NO_RETURN(IS_VALID_FORWARD_RANGE(first));
+ SVN_ERR_ASSERT_NO_RETURN(IS_VALID_FORWARD_RANGE(second));
+
return (first->start + 1 <= second->end)
&& (second->start + 1 <= first->end)
&& (!consider_inheritance
|| (!(first->inheritable) == !(second->inheritable)));
}
+/* Return TRUE iff the forward revision range FIRST wholly contains the
+ * forward revision range SECOND and (if CONSIDER_INHERITANCE is TRUE) has
+ * the same inheritability. */
static svn_boolean_t
range_contains(const svn_merge_range_t *first, const svn_merge_range_t *second,
svn_boolean_t consider_inheritance)
{
+ SVN_ERR_ASSERT_NO_RETURN(IS_VALID_FORWARD_RANGE(first));
+ SVN_ERR_ASSERT_NO_RETURN(IS_VALID_FORWARD_RANGE(second));
+
return (first->start <= second->start) && (second->end <= first->end)
&& (!consider_inheritance
|| (!(first->inheritable) == !(second->inheritable)));
@@ -848,12 +870,7 @@ svn_mergeinfo__set_inheritance(svn_merge
hi;
hi = apr_hash_next(hi))
{
- apr_array_header_t *rangelist;
- const void *path;
- void *val;
- apr_hash_this(hi, &path, NULL, &val);
-
- rangelist = apr_hash_get(mergeinfo, path, APR_HASH_KEY_STRING);
+ apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
if (rangelist)
svn_rangelist__set_inheritance(rangelist, inheritable);
@@ -862,84 +879,126 @@ svn_mergeinfo__set_inheritance(svn_merge
return;
}
-/* Either remove any overlapping ranges described by ERASER from
- WHITEBOARD (when DO_REMOVE is TRUE), or capture the overlap, and
- place the remaining or overlapping ranges in OUTPUT. */
-/* ### FIXME: Some variables names and inline comments for this method
- ### are legacy from when it was solely the remove() impl. */
+/* If DO_REMOVE is true, then remove any overlapping ranges described by
+ RANGELIST1 from RANGELIST2 and place the results in *OUTPUT. When
+ DO_REMOVE is true, RANGELIST1 is effectively the "eraser" and RANGELIST2
+ the "whiteboard".
+
+ If DO_REMOVE is false, then capture the intersection between RANGELIST1
+ and RANGELIST2 and place the results in *OUTPUT. The ordering of
+ RANGELIST1 and RANGELIST2 doesn't matter when DO_REMOVE is false.
+
+ If CONSIDER_INHERITANCE is true, then take the inheritance of the
+ ranges in RANGELIST1 and RANGELIST2 into account when comparing them
+ for intersection, see the doc string for svn_rangelist_intersection().
+
+ If CONSIDER_INHERITANCE is false, then ranges with differing inheritance
+ may intersect, but the resulting intersection is non-inheritable only
+ if both ranges were non-inheritable, e.g.:
+
+ RANGELIST1 RANGELIST2 CONSIDER DO_REMOVE *OUTPUT
+ INHERITANCE
+ ---------- ------ ----------- --------- -------
+
+ 90-420* 1-100 TRUE FALSE Empty Rangelist
+ 90-420 1-100* TRUE FALSE Empty Rangelist
+ 90-420 1-100 TRUE FALSE 90-100
+ 90-420* 1-100* TRUE FALSE 90-100*
+
+ 90-420* 1-100 FALSE FALSE 90-100
+ 90-420 1-100* FALSE FALSE 90-100
+ 90-420 1-100 FALSE FALSE 90-100
+ 90-420* 1-100* FALSE FALSE 90-100*
+
+ Allocate the contents of *OUTPUT in POOL. */
static svn_error_t *
rangelist_intersect_or_remove(apr_array_header_t **output,
- apr_array_header_t *eraser,
- apr_array_header_t *whiteboard,
+ const apr_array_header_t *rangelist1,
+ const apr_array_header_t *rangelist2,
svn_boolean_t do_remove,
svn_boolean_t consider_inheritance,
apr_pool_t *pool)
{
- int i, j, lasti;
- svn_merge_range_t wboardelt;
+ int i1, i2, lasti2;
+ svn_merge_range_t working_elt2;
*output = apr_array_make(pool, 1, sizeof(svn_merge_range_t *));
- i = 0;
- j = 0;
- lasti = -1; /* Initialized to a value that "i" will never be. */
+ i1 = 0;
+ i2 = 0;
+ lasti2 = -1; /* Initialized to a value that "i2" will never be. */
- while (i < whiteboard->nelts && j < eraser->nelts)
+ while (i1 < rangelist1->nelts && i2 < rangelist2->nelts)
{
svn_merge_range_t *elt1, *elt2;
- elt2 = APR_ARRAY_IDX(eraser, j, svn_merge_range_t *);
+ elt1 = APR_ARRAY_IDX(rangelist1, i1, svn_merge_range_t *);
- /* Instead of making a copy of the entire array of whiteboard
- elements, we just keep a copy of the current whiteboard element
+ /* Instead of making a copy of the entire array of rangelist2
+ elements, we just keep a copy of the current rangelist2 element
that needs to be used, and modify our copy if necessary. */
- if (i != lasti)
+ if (i2 != lasti2)
{
- wboardelt = *(APR_ARRAY_IDX(whiteboard, i, svn_merge_range_t *));
- lasti = i;
+ working_elt2 =
+ *(APR_ARRAY_IDX(rangelist2, i2, svn_merge_range_t *));
+ lasti2 = i2;
}
- elt1 = &wboardelt;
+ elt2 = &working_elt2;
- /* If the whiteboard range is contained completely in the
- eraser, we increment the whiteboard.
+ /* If the rangelist2 range is contained completely in the
+ rangelist1, we increment the rangelist2.
If the ranges intersect, and match exactly, we increment both
- eraser and whiteboard.
+ rangelist1 and rangelist2.
Otherwise, we have to generate a range for the left part of
- the removal of eraser from whiteboard, and possibly change
- the whiteboard to the remaining portion of the right part of
+ the removal of rangelist1 from rangelist2, and possibly change
+ the rangelist2 to the remaining portion of the right part of
the removal, to test against. */
- if (range_contains(elt2, elt1, consider_inheritance))
+ if (range_contains(elt1, elt2, consider_inheritance))
{
if (!do_remove)
- SVN_ERR(combine_with_lastrange(elt1, *output,
- consider_inheritance, pool,
- pool));
+ {
+ svn_merge_range_t tmp_range;
+ tmp_range.start = elt2->start;
+ tmp_range.end = elt2->end;
+ /* The intersection of two ranges is non-inheritable only
+ if both ranges are non-inheritable. */
+ tmp_range.inheritable =
+ (elt2->inheritable || elt1->inheritable);
+ SVN_ERR(combine_with_lastrange(&tmp_range, *output,
+ consider_inheritance, pool,
+ pool));
+ }
- i++;
+ i2++;
- if (elt1->start == elt2->start && elt1->end == elt2->end)
- j++;
+ if (elt2->start == elt1->start && elt2->end == elt1->end)
+ i1++;
}
- else if (range_intersect(elt2, elt1, consider_inheritance))
+ else if (range_intersect(elt1, elt2, consider_inheritance))
{
- if (elt1->start < elt2->start)
+ if (elt2->start < elt1->start)
{
- /* The whiteboard range starts before the eraser range. */
+ /* The rangelist2 range starts before the rangelist1 range. */
svn_merge_range_t tmp_range;
- tmp_range.inheritable = elt1->inheritable;
if (do_remove)
{
- /* Retain the range that falls before the eraser start. */
- tmp_range.start = elt1->start;
- tmp_range.end = elt2->start;
+ /* Retain the range that falls before the rangelist1
+ start. */
+ tmp_range.start = elt2->start;
+ tmp_range.end = elt1->start;
+ tmp_range.inheritable = elt2->inheritable;
}
else
{
- /* Retain the range that falls between the eraser
- start and whiteboard end. */
- tmp_range.start = elt2->start;
- tmp_range.end = MIN(elt1->end, elt2->end);
+ /* Retain the range that falls between the rangelist1
+ start and rangelist2 end. */
+ tmp_range.start = elt1->start;
+ tmp_range.end = MIN(elt2->end, elt1->end);
+ /* The intersection of two ranges is non-inheritable only
+ if both ranges are non-inheritable. */
+ tmp_range.inheritable =
+ (elt2->inheritable || elt1->inheritable);
}
SVN_ERR(combine_with_lastrange(&tmp_range,
@@ -947,40 +1006,43 @@ rangelist_intersect_or_remove(apr_array_
pool, pool));
}
- /* Set up the rest of the whiteboard range for further
+ /* Set up the rest of the rangelist2 range for further
processing. */
- if (elt1->end > elt2->end)
+ if (elt2->end > elt1->end)
{
- /* The whiteboard range ends after the eraser range. */
+ /* The rangelist2 range ends after the rangelist1 range. */
if (!do_remove)
{
/* Partial overlap. */
svn_merge_range_t tmp_range;
- tmp_range.start = MAX(elt1->start, elt2->start);
- tmp_range.end = elt2->end;
- tmp_range.inheritable = elt1->inheritable;
+ tmp_range.start = MAX(elt2->start, elt1->start);
+ tmp_range.end = elt1->end;
+ /* The intersection of two ranges is non-inheritable only
+ if both ranges are non-inheritable. */
+ tmp_range.inheritable =
+ (elt2->inheritable || elt1->inheritable);
SVN_ERR(combine_with_lastrange(&tmp_range,
*output,
consider_inheritance,
pool, pool));
}
- wboardelt.start = elt2->end;
- wboardelt.end = elt1->end;
+ working_elt2.start = elt1->end;
+ working_elt2.end = elt2->end;
}
else
- i++;
+ i2++;
}
else /* ranges don't intersect */
{
- /* See which side of the whiteboard the eraser is on. If it
- is on the left side, we need to move the eraser.
+ /* See which side of the rangelist2 the rangelist1 is on. If it
+ is on the left side, we need to move the rangelist1.
- If it is on past the whiteboard on the right side, we
- need to output the whiteboard and increment the
- whiteboard. */
- if (svn_sort_compare_ranges(&elt2, &elt1) < 0)
- j++;
+ If it is on past the rangelist2 on the right side, we
+ need to output the rangelist2 and increment the
+ rangelist2. */
+ if (svn_sort_compare_ranges(&elt1, &elt2) < 0)
+ i1++;
else
{
svn_merge_range_t *lastrange;
@@ -992,36 +1054,36 @@ rangelist_intersect_or_remove(apr_array_
lastrange = NULL;
if (do_remove && !(lastrange &&
- combine_ranges(lastrange, lastrange, elt1,
+ combine_ranges(lastrange, lastrange, elt2,
consider_inheritance)))
{
- lastrange = svn_merge_range_dup(elt1, pool);
+ lastrange = svn_merge_range_dup(elt2, pool);
APR_ARRAY_PUSH(*output, svn_merge_range_t *) = lastrange;
}
- i++;
+ i2++;
}
}
}
if (do_remove)
{
- /* Copy the current whiteboard element if we didn't hit the end
- of the whiteboard, and we still had it around. This element
- may have been touched, so we can't just walk the whiteboard
+ /* Copy the current rangelist2 element if we didn't hit the end
+ of the rangelist2, and we still had it around. This element
+ may have been touched, so we can't just walk the rangelist2
array, we have to use our copy. This case only happens when
- we ran out of eraser before whiteboard, *and* we had changed
- the whiteboard element. */
- if (i == lasti && i < whiteboard->nelts)
+ we ran out of rangelist1 before rangelist2, *and* we had changed
+ the rangelist2 element. */
+ if (i2 == lasti2 && i2 < rangelist2->nelts)
{
- SVN_ERR(combine_with_lastrange(&wboardelt, *output,
+ SVN_ERR(combine_with_lastrange(&working_elt2, *output,
consider_inheritance, pool, pool));
- i++;
+ i2++;
}
- /* Copy any other remaining untouched whiteboard elements. */
- for (; i < whiteboard->nelts; i++)
+ /* Copy any other remaining untouched rangelist2 elements. */
+ for (; i2 < rangelist2->nelts; i2++)
{
- svn_merge_range_t *elt = APR_ARRAY_IDX(whiteboard, i,
+ svn_merge_range_t *elt = APR_ARRAY_IDX(rangelist2, i2,
svn_merge_range_t *);
SVN_ERR(combine_with_lastrange(elt, *output,
@@ -1035,8 +1097,8 @@ rangelist_intersect_or_remove(apr_array_
svn_error_t *
svn_rangelist_intersect(apr_array_header_t **output,
- apr_array_header_t *rangelist1,
- apr_array_header_t *rangelist2,
+ const apr_array_header_t *rangelist1,
+ const apr_array_header_t *rangelist2,
svn_boolean_t consider_inheritance,
apr_pool_t *pool)
{
@@ -1046,8 +1108,8 @@ svn_rangelist_intersect(apr_array_header
svn_error_t *
svn_rangelist_remove(apr_array_header_t **output,
- apr_array_header_t *eraser,
- apr_array_header_t *whiteboard,
+ const apr_array_header_t *eraser,
+ const apr_array_header_t *whiteboard,
svn_boolean_t consider_inheritance,
apr_pool_t *pool)
{
@@ -1057,7 +1119,7 @@ svn_rangelist_remove(apr_array_header_t
svn_error_t *
svn_rangelist_diff(apr_array_header_t **deleted, apr_array_header_t **added,
- apr_array_header_t *from, apr_array_header_t *to,
+ const apr_array_header_t *from, const apr_array_header_t *to,
svn_boolean_t consider_inheritance,
apr_pool_t *pool)
{
@@ -1295,7 +1357,7 @@ svn_error_t *
svn_mergeinfo_intersect2(svn_mergeinfo_t *mergeinfo,
svn_mergeinfo_t mergeinfo1,
svn_mergeinfo_t mergeinfo2,
- svn_boolean_t consider_ineheritance,
+ svn_boolean_t consider_inheritance,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -1311,23 +1373,20 @@ svn_mergeinfo_intersect2(svn_mergeinfo_t
for (hi = apr_hash_first(apr_hash_pool_get(mergeinfo1), mergeinfo1);
hi; hi = apr_hash_next(hi))
{
- apr_array_header_t *rangelist;
- const void *path;
- void *val;
- apr_hash_this(hi, &path, NULL, &val);
-
- rangelist = apr_hash_get(mergeinfo2, path, APR_HASH_KEY_STRING);
- if (rangelist)
- {
- SVN_ERR(svn_rangelist_intersect(&rangelist,
- (apr_array_header_t *) val,
- rangelist, consider_ineheritance,
- scratch_pool));
- if (rangelist->nelts > 0)
+ const char *path = svn__apr_hash_index_key(hi);
+ apr_array_header_t *rangelist1 = svn__apr_hash_index_val(hi);
+ apr_array_header_t *rangelist2;
+
+ rangelist2 = apr_hash_get(mergeinfo2, path, APR_HASH_KEY_STRING);
+ if (rangelist2)
+ {
+ SVN_ERR(svn_rangelist_intersect(&rangelist2, rangelist1, rangelist2,
+ consider_inheritance, scratch_pool));
+ if (rangelist2->nelts > 0)
apr_hash_set(*mergeinfo,
apr_pstrdup(result_pool, path),
APR_HASH_KEY_STRING,
- svn_rangelist_dup(rangelist, result_pool));
+ svn_rangelist_dup(rangelist2, result_pool));
}
}
return SVN_NO_ERROR;
@@ -1345,13 +1404,13 @@ svn_error_t *
svn_mergeinfo_remove2(svn_mergeinfo_t *mergeinfo,
svn_mergeinfo_t eraser,
svn_mergeinfo_t whiteboard,
- svn_boolean_t consider_ineritance,
+ svn_boolean_t consider_inheritance,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
*mergeinfo = apr_hash_make(result_pool);
return walk_mergeinfo_hash_for_diff(whiteboard, eraser, *mergeinfo, NULL,
- consider_ineritance, result_pool,
+ consider_inheritance, result_pool,
scratch_pool);
}
@@ -1447,14 +1506,11 @@ svn_error_t *
svn_mergeinfo_sort(svn_mergeinfo_t input, apr_pool_t *pool)
{
apr_hash_index_t *hi;
- void *val;
for (hi = apr_hash_first(pool, input); hi; hi = apr_hash_next(hi))
{
- apr_array_header_t *rl;
- apr_hash_this(hi, NULL, NULL, &val);
+ apr_array_header_t *rl = svn__apr_hash_index_val(hi);
- rl = val;
qsort(rl->elts, rl->nelts, rl->elt_size, svn_sort_compare_ranges);
}
return SVN_NO_ERROR;
@@ -1471,9 +1527,9 @@ svn_mergeinfo_catalog_dup(svn_mergeinfo_
hi;
hi = apr_hash_next(hi))
{
- const void *key;
- void *val;
- apr_hash_this(hi, &key, NULL, &val);
+ const char *key = svn__apr_hash_index_key(hi);
+ svn_mergeinfo_t val = svn__apr_hash_index_val(hi);
+
apr_hash_set(new_mergeinfo_catalog,
apr_pstrdup(pool, key),
APR_HASH_KEY_STRING,
@@ -1488,15 +1544,15 @@ svn_mergeinfo_dup(svn_mergeinfo_t mergei
{
svn_mergeinfo_t new_mergeinfo = apr_hash_make(pool);
apr_hash_index_t *hi;
- const void *path;
- apr_ssize_t pathlen;
- void *rangelist;
for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
{
- apr_hash_this(hi, &path, &pathlen, &rangelist);
+ const char *path = svn__apr_hash_index_key(hi);
+ apr_ssize_t pathlen = svn__apr_hash_index_klen(hi);
+ apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
+
apr_hash_set(new_mergeinfo, apr_pstrmemdup(pool, path, pathlen), pathlen,
- svn_rangelist_dup((apr_array_header_t *) rangelist, pool));
+ svn_rangelist_dup(rangelist, pool));
}
return new_mergeinfo;
@@ -1513,25 +1569,23 @@ svn_mergeinfo_inheritable2(svn_mergeinfo
apr_pool_t *scratch_pool)
{
apr_hash_index_t *hi;
- const void *key;
- apr_ssize_t keylen;
- void *rangelist;
-
svn_mergeinfo_t inheritable_mergeinfo = apr_hash_make(result_pool);
+
for (hi = apr_hash_first(scratch_pool, mergeinfo);
hi;
hi = apr_hash_next(hi))
{
+ const char *key = svn__apr_hash_index_key(hi);
+ apr_ssize_t keylen = svn__apr_hash_index_klen(hi);
+ apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
apr_array_header_t *inheritable_rangelist;
- apr_hash_this(hi, &key, &keylen, &rangelist);
- if (!path || svn_path_compare_paths(path, (const char *)key) == 0)
- SVN_ERR(svn_rangelist_inheritable2(&inheritable_rangelist,
- (apr_array_header_t *) rangelist,
+
+ if (!path || svn_path_compare_paths(path, key) == 0)
+ SVN_ERR(svn_rangelist_inheritable2(&inheritable_rangelist, rangelist,
start, end, inheritable,
result_pool, scratch_pool));
else
- inheritable_rangelist =
- svn_rangelist_dup((apr_array_header_t *)rangelist, result_pool);
+ inheritable_rangelist = svn_rangelist_dup(rangelist, result_pool);
/* Only add this rangelist if some ranges remain. A rangelist with
a path mapped to an empty rangelist is not syntactically valid */
@@ -1544,47 +1598,10 @@ svn_mergeinfo_inheritable2(svn_mergeinfo
return SVN_NO_ERROR;
}
-svn_error_t *
-svn_mergeinfo_inheritable(svn_mergeinfo_t *output,
- svn_mergeinfo_t mergeinfo,
- const char *path,
- svn_revnum_t start,
- svn_revnum_t end,
- apr_pool_t *pool)
-{
- apr_hash_index_t *hi;
- const void *key;
- apr_ssize_t keylen;
- void *rangelist;
-
- svn_mergeinfo_t inheritable_mergeinfo = apr_hash_make(pool);
- for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
- {
- apr_array_header_t *inheritable_rangelist;
- apr_hash_this(hi, &key, &keylen, &rangelist);
- if (!path || svn_path_compare_paths(path, (const char *)key) == 0)
- SVN_ERR(svn_rangelist_inheritable(&inheritable_rangelist,
- (apr_array_header_t *) rangelist,
- start, end, pool));
- else
- inheritable_rangelist =
- svn_rangelist_dup((apr_array_header_t *)rangelist, pool);
-
- /* Only add this rangelist if some ranges remain. A rangelist with
- a path mapped to an empty rangelist is not syntactically valid */
- if (inheritable_rangelist->nelts)
- apr_hash_set(inheritable_mergeinfo,
- apr_pstrmemdup(pool, key, keylen), keylen,
- inheritable_rangelist);
- }
- *output = inheritable_mergeinfo;
- return SVN_NO_ERROR;
-}
-
svn_error_t *
svn_rangelist_inheritable2(apr_array_header_t **inheritable_rangelist,
- apr_array_header_t *rangelist,
+ const apr_array_header_t *rangelist,
svn_revnum_t start,
svn_revnum_t end,
svn_boolean_t inheritable,
@@ -1622,13 +1639,7 @@ svn_rangelist_inheritable2(apr_array_hea
/* We want only the non-inheritable ranges bound by START
and END removed. */
apr_array_header_t *ranges_inheritable =
- apr_array_make(scratch_pool, 0, sizeof(svn_merge_range_t *));
- svn_merge_range_t *range = apr_palloc(scratch_pool, sizeof(*range));
-
- range->start = start;
- range->end = end;
- range->inheritable = inheritable;
- APR_ARRAY_PUSH(ranges_inheritable, svn_merge_range_t *) = range;
+ svn_rangelist__initialize(start, end, inheritable, scratch_pool);
if (rangelist->nelts)
SVN_ERR(svn_rangelist_remove(inheritable_rangelist,
@@ -1641,17 +1652,6 @@ svn_rangelist_inheritable2(apr_array_hea
return SVN_NO_ERROR;
}
-svn_error_t *
-svn_rangelist_inheritable(apr_array_header_t **inheritable_rangelist,
- apr_array_header_t *rangelist,
- svn_revnum_t start,
- svn_revnum_t end,
- apr_pool_t *pool)
-{
- return svn_rangelist_inheritable2(inheritable_rangelist, rangelist,
- start, end, TRUE, pool, pool);
-}
-
svn_boolean_t
svn_mergeinfo__remove_empty_rangelists(svn_mergeinfo_t mergeinfo,
apr_pool_t *pool)
@@ -1663,14 +1663,8 @@ svn_mergeinfo__remove_empty_rangelists(s
{
for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
{
- const void *key;
- void *value;
- const char *path;
- apr_array_header_t *rangelist;
-
- apr_hash_this(hi, &key, NULL, &value);
- path = key;
- rangelist = value;
+ const char *path = svn__apr_hash_index_key(hi);
+ apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
if (rangelist->nelts == 0)
{
@@ -1695,15 +1689,12 @@ svn_mergeinfo__remove_prefix_from_catalo
for (hi = apr_hash_first(pool, in_catalog); hi; hi = apr_hash_next(hi))
{
- const void *key;
- const char *original_path;
- void *value;
- apr_ssize_t klen;
+ const char *original_path = svn__apr_hash_index_key(hi);
+ apr_ssize_t klen = svn__apr_hash_index_klen(hi);
+ svn_mergeinfo_t value = svn__apr_hash_index_val(hi);
- apr_hash_this(hi, &key, &klen, &value);
- original_path = key;
SVN_ERR_ASSERT(klen >= prefix_len);
- SVN_ERR_ASSERT(strncmp(key, prefix, prefix_len) == 0);
+ SVN_ERR_ASSERT(strncmp(original_path, prefix, prefix_len) == 0);
apr_hash_set(*out_catalog, original_path + prefix_len,
klen-prefix_len, value);
@@ -1734,8 +1725,8 @@ svn_mergeinfo__add_suffix_to_mergeinfo(s
hi;
hi = apr_hash_next(hi))
{
- const char *path = svn_apr_hash_index_key(hi);
- apr_array_header_t *rangelist = svn_apr_hash_index_val(hi);
+ const char *path = svn__apr_hash_index_key(hi);
+ apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
apr_hash_set(*out_mergeinfo,
svn_dirent_join(path, canonical_suffix, result_pool),
@@ -1748,7 +1739,7 @@ svn_mergeinfo__add_suffix_to_mergeinfo(s
}
apr_array_header_t *
-svn_rangelist_dup(apr_array_header_t *rangelist, apr_pool_t *pool)
+svn_rangelist_dup(const apr_array_header_t *rangelist, apr_pool_t *pool)
{
apr_array_header_t *new_rl = apr_array_make(pool, rangelist->nelts,
sizeof(svn_merge_range_t *));
@@ -1890,14 +1881,7 @@ svn_mergeinfo__get_range_endpoints(svn_r
for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
{
- const void *key;
- void *value;
- const char *path;
- apr_array_header_t *rangelist;
-
- apr_hash_this(hi, &key, NULL, &value);
- path = key;
- rangelist = value;
+ apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
if (rangelist->nelts)
{
@@ -1923,31 +1907,31 @@ svn_mergeinfo__filter_catalog_by_ranges(
svn_mergeinfo_catalog_t catalog,
svn_revnum_t youngest_rev,
svn_revnum_t oldest_rev,
- apr_pool_t *pool)
+ svn_boolean_t include_range,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
apr_hash_index_t *hi;
- *filtered_cat = apr_hash_make(pool);
- for (hi = apr_hash_first(pool, catalog);
+ *filtered_cat = apr_hash_make(result_pool);
+ for (hi = apr_hash_first(scratch_pool, catalog);
hi;
hi = apr_hash_next(hi))
{
- const void *key;
- void *val;
- const char *path;
-
- svn_mergeinfo_t mergeinfo, filtered_mergeinfo;
- apr_hash_this(hi, &key, NULL, &val);
- path = key;
- mergeinfo = val;
+ const char *path = svn__apr_hash_index_key(hi);
+ svn_mergeinfo_t mergeinfo = svn__apr_hash_index_val(hi);
+ svn_mergeinfo_t filtered_mergeinfo;
+
SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(&filtered_mergeinfo,
mergeinfo,
youngest_rev,
oldest_rev,
- pool));
+ include_range,
+ result_pool,
+ scratch_pool));
if (apr_hash_count(filtered_mergeinfo))
apr_hash_set(*filtered_cat,
- apr_pstrdup(pool, path),
+ apr_pstrdup(result_pool, path),
APR_HASH_KEY_STRING,
filtered_mergeinfo);
}
@@ -1960,42 +1944,37 @@ svn_mergeinfo__filter_mergeinfo_by_range
svn_mergeinfo_t mergeinfo,
svn_revnum_t youngest_rev,
svn_revnum_t oldest_rev,
- apr_pool_t *pool)
+ svn_boolean_t include_range,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- *filtered_mergeinfo = apr_hash_make(pool);
+ *filtered_mergeinfo = apr_hash_make(result_pool);
if (mergeinfo)
{
apr_hash_index_t *hi;
- svn_merge_range_t *range = apr_palloc(pool, sizeof(*range));
apr_array_header_t *filter_rangelist =
- apr_array_make(pool, 1, sizeof(svn_merge_range_t *));
+ svn_rangelist__initialize(oldest_rev, youngest_rev, TRUE,
+ scratch_pool);
- range->start = oldest_rev;
- range->end = youngest_rev;
- range->inheritable = TRUE;
- APR_ARRAY_PUSH(filter_rangelist, svn_merge_range_t *) = range;
-
- for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
+ for (hi = apr_hash_first(scratch_pool, mergeinfo);
+ hi;
+ hi = apr_hash_next(hi))
{
- const void *key;
- void *value;
- const char *path;
- apr_array_header_t *rangelist;
-
- apr_hash_this(hi, &key, NULL, &value);
- path = key;
- rangelist = value;
+ const char *path = svn__apr_hash_index_key(hi);
+ apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
if (rangelist->nelts)
{
apr_array_header_t *new_rangelist;
- svn_rangelist_intersect(&new_rangelist, rangelist,
- filter_rangelist, FALSE, pool);
+ SVN_ERR(rangelist_intersect_or_remove(
+ &new_rangelist, filter_rangelist, rangelist,
+ ! include_range, FALSE, result_pool));
+
if (new_rangelist->nelts)
apr_hash_set(*filtered_mergeinfo,
- apr_pstrdup(pool, path),
+ apr_pstrdup(result_pool, path),
APR_HASH_KEY_STRING,
new_rangelist);
}
@@ -2016,7 +1995,7 @@ svn_mergeinfo__is_noninheritable(svn_mer
hi;
hi = apr_hash_next(hi))
{
- apr_array_header_t *rangelist = svn_apr_hash_index_val(hi);
+ apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
int i;
for (i = 0; i < rangelist->nelts; i++)
@@ -2049,3 +2028,21 @@ svn_mergeinfo__string_has_noninheritable
return SVN_NO_ERROR;
}
+
+apr_array_header_t *
+svn_rangelist__initialize(svn_revnum_t start,
+ svn_revnum_t end,
+ svn_boolean_t inheritable,
+ apr_pool_t *result_pool)
+{
+ apr_array_header_t *rangelist =
+ apr_array_make(result_pool, 1, sizeof(svn_merge_range_t *));
+ svn_merge_range_t *range = apr_pcalloc(result_pool, sizeof(*range));
+
+ range->start = start;
+ range->end = end;
+ range->inheritable = inheritable;
+ APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = range;
+ return rangelist;
+}
+
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/opt.c Tue Aug 10 18:06:17 2010
@@ -686,6 +686,7 @@ svn_opt_parse_path(svn_opt_revision_t *r
{
ret = 0;
start_revision.kind = svn_opt_revision_unspecified;
+ start_revision.value.number = 0;
}
else /* looking at non-empty peg revision */
{
@@ -738,7 +739,7 @@ svn_opt_parse_path(svn_opt_revision_t *r
svn_error_t *
svn_opt__args_to_target_array(apr_array_header_t **targets_p,
apr_getopt_t *os,
- apr_array_header_t *known_targets,
+ const apr_array_header_t *known_targets,
apr_pool_t *pool)
{
int i;
@@ -1066,7 +1067,7 @@ svn_opt_print_help3(apr_getopt_t *os,
svn_error_t *
svn_opt_eat_peg_revisions(apr_array_header_t **true_targets_p,
- apr_array_header_t *targets,
+ const apr_array_header_t *targets,
apr_pool_t *pool)
{
int i;
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/prompt.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/prompt.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/prompt.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/prompt.c Tue Aug 10 18:06:17 2010
@@ -71,7 +71,7 @@ static apr_status_t wait_for_input(apr_f
* ourselves here.
*/
return APR_ENOTIMPL;
-#endif
+#endif
}
/* Set @a *result to the result of prompting the user with @a
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/quoprint.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/quoprint.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/quoprint.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/quoprint.c Tue Aug 10 18:06:17 2010
@@ -37,24 +37,24 @@
/* Caveats:
- (1) This code is for the encoding and decoding of binary data
- only. Thus, CRLF sequences are encoded as =0D=0A, and we
- don't have to worry about tabs and spaces coming before
- hard newlines, since there aren't any.
-
- (2) The decoder does no error reporting, and instead throws
- away invalid sequences. It also discards CRLF sequences,
- since those can only appear in the encoding of text data.
-
- (3) The decoder does not strip whitespace at the end of a
- line, so it is not actually compliant with RFC 2045.
- (Such whitespace should never occur, even in the encoding
- of text data, but RFC 2045 requires a decoder to detect
- that a transport agent has added trailing whitespace).
-
- (4) The encoder is tailored to make output embeddable in XML,
- which means it quotes <>'"& as well as the characters
- required by RFC 2045. */
+ (1) This code is for the encoding and decoding of binary data
+ only. Thus, CRLF sequences are encoded as =0D=0A, and we
+ don't have to worry about tabs and spaces coming before
+ hard newlines, since there aren't any.
+
+ (2) The decoder does no error reporting, and instead throws
+ away invalid sequences. It also discards CRLF sequences,
+ since those can only appear in the encoding of text data.
+
+ (3) The decoder does not strip whitespace at the end of a
+ line, so it is not actually compliant with RFC 2045.
+ (Such whitespace should never occur, even in the encoding
+ of text data, but RFC 2045 requires a decoder to detect
+ that a transport agent has added trailing whitespace).
+
+ (4) The encoder is tailored to make output embeddable in XML,
+ which means it quotes <>'"& as well as the characters
+ required by RFC 2045. */
#define QUOPRINT_LINELEN 76
#define VALID_LITERAL(c) ((c) == '\t' || ((c) >= ' ' && (c) <= '~' \
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/simple_providers.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/simple_providers.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/simple_providers.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/simple_providers.c Tue Aug 10 18:06:17 2010
@@ -202,7 +202,7 @@ svn_auth__simple_first_creds_helper(void
else
need_to_save = TRUE;
}
- }
+ }
/* See if we need to save this password if it is not present in
auth cache. */
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/skel.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/skel.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/skel.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/skel.c Tue Aug 10 18:06:17 2010
@@ -609,6 +609,24 @@ void svn_skel__prepend_str(const char *v
svn_skel__prepend(atom, skel);
}
+
+void svn_skel__append(svn_skel_t *list_skel, const svn_skel_t *skel)
+{
+ SVN_ERR_ASSERT_NO_RETURN(list_skel != NULL && !list_skel->is_atom);
+
+ if (list_skel->children == NULL)
+ {
+ list_skel->children = (svn_skel_t *)skel;
+ }
+ else
+ {
+ list_skel = list_skel->children;
+ while (list_skel->next != NULL)
+ list_skel = list_skel->next;
+ list_skel->next = (svn_skel_t *)skel;
+ }
+}
+
/* Examining skels. */
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sorts.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sorts.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sorts.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sorts.c Tue Aug 10 18:06:17 2010
@@ -196,7 +196,7 @@ bsearch_lower_bound(const void *key,
int
svn_sort__bsearch_lower_bound(const void *key,
- apr_array_header_t *array,
+ const apr_array_header_t *array,
int (*compare_func)(const void *, const void *))
{
return bsearch_lower_bound(key,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sqlite.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/sqlite.c Tue Aug 10 18:06:17 2010
@@ -117,6 +117,16 @@ exec_sql(svn_sqlite__db_t *db, const cha
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_sqlite__exec_statements(svn_sqlite__db_t *db, int stmt_idx)
+{
+ SVN_ERR_ASSERT(stmt_idx < db->nbr_statements);
+
+ return svn_error_return(exec_sql(db, db->statement_strings[stmt_idx]));
+}
+
+
svn_error_t *
svn_sqlite__get_statement(svn_sqlite__stmt_t **stmt, svn_sqlite__db_t *db,
int stmt_idx)
@@ -898,7 +908,8 @@ svn_sqlite__open(svn_sqlite__db_t **db,
#endif
/* Validate the schema, upgrading if necessary. */
- SVN_ERR(check_format(*db, latest_schema, upgrade_sql, scratch_pool));
+ if (upgrade_sql != NULL)
+ SVN_ERR(check_format(*db, latest_schema, upgrade_sql, scratch_pool));
/* Store the provided statements. */
if (statements)
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/stream.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/stream.c Tue Aug 10 18:06:17 2010
@@ -456,7 +456,7 @@ svn_error_t *svn_stream_copy3(svn_stream
err = svn_stream_read(from, buf, &len);
if (err)
- break;
+ break;
if (len > 0)
err = svn_stream_write(to, buf, &len);
@@ -472,22 +472,27 @@ svn_error_t *svn_stream_copy3(svn_stream
}
svn_error_t *
-svn_stream_contents_same(svn_boolean_t *same,
- svn_stream_t *stream1,
- svn_stream_t *stream2,
- apr_pool_t *pool)
+svn_stream_contents_same2(svn_boolean_t *same,
+ svn_stream_t *stream1,
+ svn_stream_t *stream2,
+ apr_pool_t *pool)
{
char *buf1 = apr_palloc(pool, SVN__STREAM_CHUNK_SIZE);
char *buf2 = apr_palloc(pool, SVN__STREAM_CHUNK_SIZE);
apr_size_t bytes_read1 = SVN__STREAM_CHUNK_SIZE;
apr_size_t bytes_read2 = SVN__STREAM_CHUNK_SIZE;
+ svn_error_t *err = NULL;
*same = TRUE; /* assume TRUE, until disproved below */
while (bytes_read1 == SVN__STREAM_CHUNK_SIZE
&& bytes_read2 == SVN__STREAM_CHUNK_SIZE)
{
- SVN_ERR(svn_stream_read(stream1, buf1, &bytes_read1));
- SVN_ERR(svn_stream_read(stream2, buf2, &bytes_read2));
+ err = svn_stream_read(stream1, buf1, &bytes_read1);
+ if (err)
+ break;
+ err = svn_stream_read(stream2, buf2, &bytes_read2);
+ if (err)
+ break;
if ((bytes_read1 != bytes_read2)
|| (memcmp(buf1, buf2, bytes_read1)))
@@ -497,7 +502,10 @@ svn_stream_contents_same(svn_boolean_t *
}
}
- return SVN_NO_ERROR;
+ return svn_error_compose_create(err,
+ svn_error_compose_create(
+ svn_stream_close(stream1),
+ svn_stream_close(stream2)));
}
@@ -676,35 +684,6 @@ read_handler_apr(void *baton, char *buff
struct baton_apr *btn = baton;
svn_error_t *err;
- /* Check for range restriction. */
- if (btn->start >= 0 && btn->end > 0)
- {
- /* Get the current file position and make sure it is in range. */
- apr_off_t pos;
-
- pos = 0;
- SVN_ERR(svn_io_file_seek(btn->file, APR_CUR, &pos, btn->pool));
- if (pos < btn->start)
- {
- /* We're before the range, so forward the file cursor to
- * the start of the range. */
- pos = btn->start;
- SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &pos, btn->pool));
- }
- else if (pos >= btn->end)
- {
- /* We're past the range, indicate that no bytes can be read. */
- *len = 0;
- return SVN_NO_ERROR;
- }
- else
- {
- /* We're in range, but don't read over the end of the range. */
- if (pos + *len > btn->end)
- *len = btn->end - pos;
- }
- }
-
err = svn_io_file_read_full(btn->file, buffer, *len, len, btn->pool);
if (err && APR_STATUS_IS_EOF(err->apr_err))
{
@@ -846,12 +825,47 @@ svn_stream_from_aprfile2(apr_file_t *fil
return stream;
}
-svn_stream_t *
-svn_stream_from_aprfile(apr_file_t *file, apr_pool_t *pool)
+/* A read handler (#svn_read_fn_t) that forwards to read_handler_apr()
+ but only allows reading between BATON->start and BATON->end. */
+static svn_error_t *
+read_range_handler_apr(void *baton, char *buffer, apr_size_t *len)
{
- return svn_stream_from_aprfile2(file, TRUE, pool);
+ struct baton_apr *btn = baton;
+
+ /* ### BH: I think this can be simplified/optimized by just keeping
+ track of the current position. */
+
+ /* Check for range restriction. */
+ if (btn->start >= 0 && btn->end > 0)
+ {
+ /* Get the current file position and make sure it is in range. */
+ apr_off_t pos;
+
+ pos = 0;
+ SVN_ERR(svn_io_file_seek(btn->file, APR_CUR, &pos, btn->pool));
+ if (pos < btn->start)
+ {
+ /* We're before the range, so forward the file cursor to
+ * the start of the range. */
+ pos = btn->start;
+ SVN_ERR(svn_io_file_seek(btn->file, APR_SET, &pos, btn->pool));
+ }
+ else if (pos >= btn->end)
+ {
+ /* We're past the range, indicate that no bytes can be read. */
+ *len = 0;
+ return SVN_NO_ERROR;
+ }
+
+ /* We're in range, but don't read over the end of the range. */
+ if (pos + *len > btn->end)
+ *len = (apr_size_t)(btn->end - pos);
+ }
+
+ return read_handler_apr(baton, buffer, len);
}
+
svn_stream_t *
svn_stream_from_aprfile_range_readonly(apr_file_t *file,
svn_boolean_t disown,
@@ -863,6 +877,7 @@ svn_stream_from_aprfile_range_readonly(a
svn_stream_t *stream;
apr_off_t pos;
+ /* ### HACK: These shortcuts don't handle disown FALSE properly */
if (file == NULL || start < 0 || end <= 0 || start >= end)
return svn_stream_empty(pool);
@@ -877,7 +892,7 @@ svn_stream_from_aprfile_range_readonly(a
baton->start = start;
baton->end = end;
stream = svn_stream_create(baton, pool);
- svn_stream_set_read(stream, read_handler_apr);
+ svn_stream_set_read(stream, read_range_handler_apr);
svn_stream_set_reset(stream, reset_handler_apr);
svn_stream_set_mark(stream, mark_handler_apr);
svn_stream_set_seek(stream, seek_handler_apr);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/subst.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/subst.c Tue Aug 10 18:06:17 2010
@@ -769,9 +769,9 @@ struct translation_baton
apr_hash_t *keywords;
svn_boolean_t expand;
- /* Characters (excluding the terminating NUL character) which
+ /* 'short boolean' array that encodes what character values
may trigger a translation action, hence are 'interesting' */
- const char *interesting;
+ char interesting[256];
/* Length of the string EOL_STR points to. */
apr_size_t eol_str_len;
@@ -821,11 +821,21 @@ create_translation_baton(const char *eol
b->repair = repair;
b->keywords = keywords;
b->expand = expand;
- b->interesting = (eol_str && keywords) ? "$\r\n" : eol_str ? "\r\n" : "$";
b->newline_off = 0;
b->keyword_off = 0;
b->src_format_len = 0;
+ /* Most characters don't start translation actions.
+ * Mark those that do depending on the parameters we got. */
+ memset(b->interesting, FALSE, sizeof(b->interesting));
+ if (keywords)
+ b->interesting['$'] = TRUE;
+ if (eol_str)
+ {
+ b->interesting['\r'] = TRUE;
+ b->interesting['\n'] = TRUE;
+ }
+
return b;
}
@@ -938,14 +948,9 @@ translate_chunk(svn_stream_t *dst,
len = 0;
/* We wanted memcspn(), but lacking that, the loop below has
- the same effect.
-
- Also, skip NUL characters explicitly, since strchr()
- considers them part of the string argument,
- but we don't consider them interesting
+ the same effect. Also, skip NUL characters.
*/
- while ((p + len) < end
- && (! p[len] || ! strchr(interesting, p[len])))
+ while ((p + len) < end && !interesting[(unsigned char)p[len]])
len++;
if (len)
@@ -1033,6 +1038,7 @@ struct translated_stream_baton
};
+/* Implements svn_read_fn_t. */
static svn_error_t *
translated_stream_read(void *baton,
char *buffer,
@@ -1044,6 +1050,25 @@ translated_stream_read(void *baton,
apr_size_t off = 0;
apr_pool_t *iterpool;
+ /* Optimization for a frequent special case. The configuration parser (and
+ a few others) reads the stream one byte at a time. All the memcpy, pool
+ clearing etc. imposes a huge overhead in that case. In most cases, we
+ can just take that single byte directly from the read buffer.
+
+ Since *len > 1 requires lots of code to be run anyways, we can afford
+ the extra overhead of checking for *len == 1.
+
+ See <http://mail-archives.apache.org/mod_mbox/subversion-dev/201003.mbox/%3C4B94011E.1070207@alice-dsl.de%3E>.
+ */
+ if (unsatisfied == 1 && b->readbuf_off < b->readbuf->len)
+ {
+ /* Just take it from the read buffer */
+ *buffer = b->readbuf->data[b->readbuf_off++];
+
+ return SVN_NO_ERROR;
+ }
+
+ /* Standard code path. */
iterpool = b->iterpool;
while (readlen == SVN__STREAM_CHUNK_SIZE && unsatisfied > 0)
{
@@ -1086,6 +1111,7 @@ translated_stream_read(void *baton,
return SVN_NO_ERROR;
}
+/* Implements svn_write_fn_t. */
static svn_error_t *
translated_stream_write(void *baton,
const char *buffer,
@@ -1098,6 +1124,7 @@ translated_stream_write(void *baton,
return translate_chunk(b->stream, b->out_baton, buffer, *len, b->iterpool);
}
+/* Implements svn_close_fn_t. */
static svn_error_t *
translated_stream_close(void *baton)
{
@@ -1112,6 +1139,7 @@ translated_stream_close(void *baton)
return SVN_NO_ERROR;
}
+/* Implements svn_io_reset_fn_t. */
static svn_error_t *
translated_stream_reset(void *baton)
{
@@ -1136,6 +1164,45 @@ translated_stream_reset(void *baton)
return svn_error_return(err);
}
+/* Implements svn_io_mark_fn_t. */
+static svn_error_t *
+translated_stream_mark(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
+{
+ struct translated_stream_baton *b = baton;
+
+ return svn_error_return(svn_stream_mark(b->stream, mark, pool));
+}
+
+/* Implements svn_io_seek_fn_t. */
+static svn_error_t *
+translated_stream_seek(void *baton, svn_stream_mark_t *mark)
+{
+ struct translated_stream_baton *b = baton;
+ svn_error_t *err;
+
+ /* Flush output buffer if necessary. */
+ if (b->written)
+ SVN_ERR(translate_chunk(b->stream, b->out_baton, NULL, 0, b->iterpool));
+
+ err = svn_stream_seek(b->stream, mark);
+ if (err == NULL)
+ {
+ /* Force into boring state. */
+ b->in_baton->newline_off = 0;
+ b->in_baton->keyword_off = 0;
+ b->out_baton->newline_off = 0;
+ b->out_baton->keyword_off = 0;
+
+ /* Output buffer has been flushed. */
+ b->written = FALSE;
+
+ /* Reset read buffer. */
+ svn_stringbuf_setempty(b->readbuf);
+ b->readbuf_off = 0;
+ }
+
+ return svn_error_return(err);
+}
svn_error_t *
svn_subst_read_specialfile(svn_stream_t **stream,
@@ -1235,6 +1302,8 @@ svn_subst_stream_translated(svn_stream_t
svn_stream_set_write(s, translated_stream_write);
svn_stream_set_close(s, translated_stream_close);
svn_stream_set_reset(s, translated_stream_reset);
+ svn_stream_set_mark(s, translated_stream_mark);
+ svn_stream_set_seek(s, translated_stream_seek);
return s;
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/svn_string.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/svn_string.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/svn_string.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/svn_string.c Tue Aug 10 18:06:17 2010
@@ -536,7 +536,7 @@ svn_cstring_split(const char *input,
svn_boolean_t svn_cstring_match_glob_list(const char *str,
- apr_array_header_t *list)
+ const apr_array_header_t *list)
{
int i;
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/win32_crashrpt.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/win32_crashrpt.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/win32_crashrpt.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/win32_crashrpt.c Tue Aug 10 18:06:17 2010
@@ -40,7 +40,7 @@
HANDLE dbghelp_dll = INVALID_HANDLE_VALUE;
/* Email address where the crash reports should be sent too. */
-#define CRASHREPORT_EMAIL "svn-breakage@subversion.tigris.org"
+#define CRASHREPORT_EMAIL "notifications@subversion.apache.org"
#define DBGHELP_DLL "dbghelp.dll"