subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1182053 [15/30] - in /subversion/branches/svn_mutex: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/ contrib/hook-scripts/enforcer/ contrib/server-side/ notes/ notes/merge-t...
Date Tue, 11 Oct 2011 19:52:46 GMT
Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/mergeinfo.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/mergeinfo.c Tue Oct 11 19:52:34 2011
@@ -37,6 +37,7 @@
 #include "private/svn_string_private.h"
 #include "svn_private_config.h"
 #include "svn_hash.h"
+#include "private/svn_dep_compat.h"
 
 /* Attempt to combine two ranges, IN1 and IN2. If they are adjacent or
    overlapping, and their inheritability allows them to be combined, put
@@ -244,15 +245,13 @@ get_type_of_intersection(const svn_merge
 
    When replacing the last range in RANGELIST, either allocate a new range in
    RESULT_POOL or modify the existing range in place.  Any new ranges added
-   to RANGELIST are allocated in RESULT_POOL.  SCRATCH_POOL is used for any
-   temporary allocations.
+   to RANGELIST are allocated in RESULT_POOL.
 */
 static svn_error_t *
 combine_with_lastrange(const svn_merge_range_t *new_range,
                        apr_array_header_t *rangelist,
                        svn_boolean_t consider_inheritance,
-                       apr_pool_t *result_pool,
-                       apr_pool_t *scratch_pool)
+                       apr_pool_t *result_pool)
 {
   svn_merge_range_t *lastrange;
   svn_merge_range_t combined_range;
@@ -300,143 +299,168 @@ combine_with_lastrange(const svn_merge_r
              intersect but have differing inheritability.  Check for the
              first case as that is easy to handle. */
           intersection_type_t intersection_type;
+          svn_boolean_t sorted = FALSE;
 
           SVN_ERR(get_type_of_intersection(new_range, lastrange,
                                            &intersection_type));
 
-              switch (intersection_type)
+          switch (intersection_type)
+            {
+              case svn__no_intersection:
+                /* NEW_RANGE and *LASTRANGE *really* don't intersect so
+                   just push NEW_RANGE only RANGELIST. */
+                APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
+                  svn_merge_range_dup(new_range, result_pool);
+                sorted = (svn_sort_compare_ranges(&lastrange,
+                                                  &new_range) < 0);
+                break;
+
+              case svn__equal_intersection:
+                /* They range are equal so all we do is force the
+                   inheritability of lastrange to true. */
+                lastrange->inheritable = TRUE;
+                sorted = TRUE;
+                break;
+
+              case svn__adjoining_intersection:
+                /* They adjoin but don't overlap so just push NEW_RANGE
+                   onto RANGELIST. */
+                APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
+                  svn_merge_range_dup(new_range, result_pool);
+                sorted = (svn_sort_compare_ranges(&lastrange,
+                                                  &new_range) < 0);
+                break;
+
+              case svn__overlapping_intersection:
+                /* They ranges overlap but neither is a proper subset of
+                   the other.  We'll end up pusing two new ranges onto
+                   RANGELIST, the intersecting part and the part unique to
+                   NEW_RANGE.*/
                 {
-                  case svn__no_intersection:
-                    /* NEW_RANGE and *LASTRANGE *really* don't intersect so
-                       just push NEW_RANGE only RANGELIST. */
-                    APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
-                      svn_merge_range_dup(new_range, result_pool);
-                    break;
-
-                  case svn__equal_intersection:
-                    /* They range are equal so all we do is force the
-                       inheritability of lastrange to true. */
-                    lastrange->inheritable = TRUE;
-                    break;
-
-                  case svn__adjoining_intersection:
-                    /* They adjoin but don't overlap so just push NEW_RANGE
-                       onto RANGELIST. */
-                    APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
-                      svn_merge_range_dup(new_range, result_pool);
-                    break;
-
-                  case svn__overlapping_intersection:
-                    /* They ranges overlap but neither is a proper subset of
-                       the other.  We'll end up pusing two new ranges onto
-                       RANGELIST, the intersecting part and the part unique to
-                       NEW_RANGE.*/
+                  svn_merge_range_t *r1 = svn_merge_range_dup(lastrange,
+                                                              result_pool);
+                  svn_merge_range_t *r2 = svn_merge_range_dup(new_range,
+                                                              result_pool);
+
+                  /* Pop off *LASTRANGE to make our manipulations
+                     easier. */
+                  apr_array_pop(rangelist);
+
+                  /* Ensure R1 is the older range. */
+                  if (r2->start < r1->start)
                     {
-                      svn_merge_range_t *r1 = svn_merge_range_dup(lastrange,
-                                                                  result_pool);
-                      svn_merge_range_t *r2 = svn_merge_range_dup(new_range,
-                                                                  result_pool);
-
-                      /* Pop off *LASTRANGE to make our manipulations
-                         easier. */
-                      apr_array_pop(rangelist);
+                      /* Swap R1 and R2. */
+                      *r2 = *r1;
+                      *r1 = *new_range;
+                    }
 
-                      /* Ensure R1 is the older range. */
-                      if (r2->start < r1->start)
-                        {
-                          /* Swap R1 and R2. */
-                          *r2 = *r1;
-                          *r1 = *new_range;
-                        }
+                  /* Absorb the intersecting ranges into the
+                     inheritable range. */
+                  if (r1->inheritable)
+                    r2->start = r1->end;
+                  else
+                    r1->end = r2->start;
 
-                      /* Absorb the intersecting ranges into the
-                         inheritable range. */
-                      if (r1->inheritable)
-                        r2->start = r1->end;
-                      else
-                        r1->end = r2->start;
+                  /* Push everything back onto RANGELIST. */
+                  APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r1;
+                  sorted = (svn_sort_compare_ranges(&lastrange,
+                                                    &r1) < 0);
+                  APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r2;
+                  if (sorted)
+                    sorted = (svn_sort_compare_ranges(&r1, &r2) < 0);
+                  break;
+                }
 
-                      /* Push everything back onto RANGELIST. */
-                      APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r1;
-                      APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r2;
+              default: /* svn__proper_subset_intersection */
+                {
+                  /* One range is a proper subset of the other. */
+                  svn_merge_range_t *r1 = svn_merge_range_dup(lastrange,
+                                                              result_pool);
+                  svn_merge_range_t *r2 = svn_merge_range_dup(new_range,
+                                                              result_pool);
+                  svn_merge_range_t *r3 = NULL;
+
+                  /* Pop off *LASTRANGE to make our manipulations
+                     easier. */
+                  apr_array_pop(rangelist);
 
-                      break;
+                  /* Ensure R1 is the superset. */
+                  if (r2->start < r1->start || r2->end > r1->end)
+                    {
+                      /* Swap R1 and R2. */
+                      *r2 = *r1;
+                      *r1 = *new_range;
                     }
 
-                  default: /* svn__proper_subset_intersection */
+                  if (r1->inheritable)
                     {
-                      /* One range is a proper subset of the other. */
-                      svn_merge_range_t *r1 = svn_merge_range_dup(lastrange,
-                                                                  result_pool);
-                      svn_merge_range_t *r2 = svn_merge_range_dup(new_range,
-                                                                  result_pool);
-                      svn_merge_range_t *r3 = NULL;
-
-                      /* Pop off *LASTRANGE to make our manipulations
-                         easier. */
-                      apr_array_pop(rangelist);
-
-                      /* Ensure R1 is the superset. */
-                      if (r2->start < r1->start || r2->end > r1->end)
-                        {
-                          /* Swap R1 and R2. */
-                          *r2 = *r1;
-                          *r1 = *new_range;
-                        }
+                      /* The simple case: The superset is inheritable, so
+                         just combine r1 and r2. */
+                      r1->start = MIN(r1->start, r2->start);
+                      r1->end = MAX(r1->end, r2->end);
+                      r2 = NULL;
+                    }
+                  else if (r1->start == r2->start)
+                    {
+                      svn_revnum_t tmp_revnum;
 
-                      if (r1->inheritable)
-                        {
-                          /* The simple case: The superset is inheritable, so
-                             just combine r1 and r2. */
-                          r1->start = MIN(r1->start, r2->start);
-                          r1->end = MAX(r1->end, r2->end);
-                          r2 = NULL;
-                        }
-                      else if (r1->start == r2->start)
-                        {
-                          svn_revnum_t tmp_revnum;
+                      /* *LASTRANGE and NEW_RANGE share an end point. */
+                      tmp_revnum = r1->end;
+                      r1->end = r2->end;
+                      r2->inheritable = r1->inheritable;
+                      r1->inheritable = TRUE;
+                      r2->start = r1->end;
+                      r2->end = tmp_revnum;
+                    }
+                  else if (r1->end == r2->end)
+                    {
+                      /* *LASTRANGE and NEW_RANGE share an end point. */
+                      r1->end = r2->start;
+                      r2->inheritable = TRUE;
+                    }
+                  else
+                    {
+                      /* NEW_RANGE and *LASTRANGE share neither start
+                         nor end points. */
+                      r3 = apr_pcalloc(result_pool, sizeof(*r3));
+                      r3->start = r2->end;
+                      r3->end = r1->end;
+                      r3->inheritable = r1->inheritable;
+                      r2->inheritable = TRUE;
+                      r1->end = r2->start;
+                    }
 
-                          /* *LASTRANGE and NEW_RANGE share an end point. */
-                          tmp_revnum = r1->end;
-                          r1->end = r2->end;
-                          r2->inheritable = r1->inheritable;
-                          r1->inheritable = TRUE;
-                          r2->start = r1->end;
-                          r2->end = tmp_revnum;
-                        }
-                      else if (r1->end == r2->end)
-                        {
-                          /* *LASTRANGE and NEW_RANGE share an end point. */
-                          r1->end = r2->start;
-                          r2->inheritable = TRUE;
-                        }
-                      else
+                  /* Push everything back onto RANGELIST. */
+                  APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r1;
+                  sorted = (svn_sort_compare_ranges(&lastrange, &r1) < 0);
+                  if (r2)
+                    {
+                      APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r2;
+                      if (sorted)
+                        sorted = (svn_sort_compare_ranges(&r1, &r2) < 0);
+                    }
+                  if (r3)
+                    {
+                      APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r3;
+                      if (sorted)
                         {
-                          /* NEW_RANGE and *LASTRANGE share neither start
-                             nor end points. */
-                          r3 = apr_pcalloc(result_pool, sizeof(*r3));
-                          r3->start = r2->end;
-                          r3->end = r1->end;
-                          r3->inheritable = r1->inheritable;
-                          r2->inheritable = TRUE;
-                          r1->end = r2->start;
+                          if (r2)
+                            sorted = (svn_sort_compare_ranges(&r2,
+                                                              &r3) < 0);
+                          else
+                            sorted = (svn_sort_compare_ranges(&r1,
+                                                              &r3) < 0);
                         }
-
-                      /* Push everything back onto RANGELIST. */
-                      APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r1;
-                      if (r2)
-                        APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r2;
-                      if (r3)
-                        APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r3;
-
-                      break;
                     }
+                  break;
                 }
+            }
 
-              /* Some of the above cases might have put *RANGELIST out of
-                 order, so re-sort.*/
-              qsort(rangelist->elts, rangelist->nelts, rangelist->elt_size,
-                    svn_sort_compare_ranges);
+          /* Some of the above cases might have put *RANGELIST out of
+             order, so re-sort.*/
+          if (!sorted)
+            qsort(rangelist->elts, rangelist->nelts, rangelist->elt_size,
+                  svn_sort_compare_ranges);
         }
     }
 
@@ -588,14 +612,14 @@ parse_rangelist(const char **input, cons
 /* revisionline -> PATHNAME COLON revisionlist */
 static svn_error_t *
 parse_revision_line(const char **input, const char *end, svn_mergeinfo_t hash,
-                    apr_pool_t *pool)
+                    apr_pool_t *scratch_pool)
 {
   svn_stringbuf_t *pathname;
   apr_array_header_t *existing_rangelist;
-  apr_array_header_t *rangelist = apr_array_make(pool, 1,
+  apr_array_header_t *rangelist = apr_array_make(scratch_pool, 1,
                                                  sizeof(svn_merge_range_t *));
 
-  SVN_ERR(parse_pathname(input, end, &pathname, pool));
+  SVN_ERR(parse_pathname(input, end, &pathname, scratch_pool));
 
   if (*(*input) != ':')
     return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
@@ -603,7 +627,7 @@ parse_revision_line(const char **input, 
 
   *input = *input + 1;
 
-  SVN_ERR(parse_rangelist(input, end, rangelist, pathname->data, pool));
+  SVN_ERR(parse_rangelist(input, end, rangelist, pathname->data, scratch_pool));
 
   if (*input != end && *(*input) != '\n')
     return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
@@ -642,8 +666,10 @@ parse_revision_line(const char **input, 
                                              "revision ranges '%s' and '%s' "
                                              "with different inheritance "
                                              "types"),
-                                           range_to_string(lastrange, pool),
-                                           range_to_string(range, pool));
+                                           range_to_string(lastrange,
+                                                           scratch_pool),
+                                           range_to_string(range,
+                                                           scratch_pool));
                 }
 
               /* Combine overlapping or adjacent ranges with the
@@ -671,9 +697,12 @@ parse_revision_line(const char **input, 
      absolute path key. */
   existing_rangelist = apr_hash_get(hash, pathname->data, APR_HASH_KEY_STRING);
   if (existing_rangelist)
-    SVN_ERR(svn_rangelist_merge(&rangelist, existing_rangelist, pool));
+    SVN_ERR(svn_rangelist_merge2(rangelist, existing_rangelist,
+                                 scratch_pool, scratch_pool));
 
-  apr_hash_set(hash, pathname->data, APR_HASH_KEY_STRING, rangelist);
+  apr_hash_set(hash, apr_pstrdup(apr_hash_pool_get(hash), pathname->data),
+               APR_HASH_KEY_STRING,
+               svn_rangelist_dup(rangelist, apr_hash_pool_get(hash)));
 
   return SVN_NO_ERROR;
 }
@@ -683,8 +712,14 @@ static svn_error_t *
 parse_top(const char **input, const char *end, svn_mergeinfo_t hash,
           apr_pool_t *pool)
 {
+  apr_pool_t *iterpool = svn_pool_create(pool);
+
   while (*input < end)
-    SVN_ERR(parse_revision_line(input, end, hash, pool));
+    {
+      svn_pool_clear(iterpool);
+      SVN_ERR(parse_revision_line(input, end, hash, iterpool));
+    }
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
@@ -707,73 +742,403 @@ svn_mergeinfo_parse(svn_mergeinfo_t *mer
   return err;
 }
 
+/* Cleanup after svn_rangelist_merge2 when it modifies the ending range of
+   a single rangelist element in-place.
 
-svn_error_t *
-svn_rangelist_merge(apr_array_header_t **rangelist,
-                    const apr_array_header_t *changes,
-                    apr_pool_t *pool)
+   If *RANGE_INDEX is not a valid element in RANGELIST do nothing.  Otherwise
+   ensure that RANGELIST[*RANGE_INDEX]->END does not adjoin or overlap any
+   subsequent ranges in RANGELIST.
+
+   If overlap is found, then remove, modify, and/or add elements to RANGELIST
+   as per the invariants for rangelists documented in svn_mergeinfo.h.  If
+   RANGELIST[*RANGE_INDEX]->END adjoins a subsequent element then combine the
+   elements if their inheritability permits -- The inheritance of intersecting
+   and adjoining ranges is handled as per svn_mergeinfo_merge2.  Upon return
+   set *RANGE_INDEX to the index of the youngest element modified, added, or
+   adjoined to RANGELIST[*RANGE_INDEX].
+
+   Note: Adjoining rangelist elements are those where the end rev of the older
+   element is equal to the start rev of the younger element.
+
+   Any new elements inserted into RANGELIST are allocated in  RESULT_POOL.*/
+static void
+adjust_remaining_ranges(apr_array_header_t *rangelist,
+                        int *range_index,
+                        apr_pool_t *result_pool)
 {
-  int i, j;
-  apr_array_header_t *output = apr_array_make(pool, 1,
-                                              sizeof(svn_merge_range_t *));
-  i = 0;
-  j = 0;
-  while (i < (*rangelist)->nelts && j < changes->nelts)
+  int i;
+  int starting_index;
+  int elements_to_delete = 0;
+  svn_merge_range_t *modified_range;
+
+  if (*range_index >= rangelist->nelts)
+    return;
+
+  starting_index = *range_index + 1;
+  modified_range = APR_ARRAY_IDX(rangelist, *range_index, svn_merge_range_t *);
+
+  for (i = *range_index + 1; i < rangelist->nelts; i++)
     {
-      svn_merge_range_t *elt1, *elt2;
-      int res;
+      svn_merge_range_t *next_range = APR_ARRAY_IDX(rangelist, i,
+                                                    svn_merge_range_t *);
+
+      /* If MODIFIED_RANGE doesn't adjoin or overlap the next range in
+         RANGELIST then we are finished. */
+      if (modified_range->end < next_range->start)
+        break;
+
+      /* Does MODIFIED_RANGE adjoin NEXT_RANGE? */
+      if (modified_range->end == next_range->start)
+        {
+          if (modified_range->inheritable == next_range->inheritable)
+            {
+              /* Combine adjoining ranges with the same inheritability. */
+              modified_range->end = next_range->end;
+              elements_to_delete++;
+            }
+          else
+            {
+              /* Cannot join because inheritance differs. */
+              (*range_index)++;
+            }
+          break;
+        }
+
+      /* Alright, we know MODIFIED_RANGE overlaps NEXT_RANGE, but how? */
+      if (modified_range->end > next_range->end)
+        {
+          /* NEXT_RANGE is a proper subset of MODIFIED_RANGE and the two
+             don't share the same end range. */
+          if (modified_range->inheritable
+              || (modified_range->inheritable == next_range->inheritable))
+            {
+              /* MODIFIED_RANGE absorbs NEXT_RANGE. */
+              elements_to_delete++;
+            }
+          else
+            {
+              /* NEXT_RANGE is a proper subset MODIFIED_RANGE but
+                 MODIFIED_RANGE is non-inheritable and NEXT_RANGE is
+                 inheritable.  This means MODIFIED_RANGE is truncated,
+                 NEXT_RANGE remains, and the portion of MODIFIED_RANGE
+                 younger than NEXT_RANGE is added as a separate range:
+                  ______________________________________________
+                 |                                              |
+                 M                 MODIFIED_RANGE               N
+                 |                 (!inhertiable)               |
+                 |______________________________________________|
+                                  |              |
+                                  O  NEXT_RANGE  P
+                                  | (inheritable)|
+                                  |______________|
+                                         |
+                                         V
+                  _______________________________________________
+                 |                |              |               |
+                 M MODIFIED_RANGE O  NEXT_RANGE  P   NEW_RANGE   N
+                 | (!inhertiable) | (inheritable)| (!inheritable)|
+                 |________________|______________|_______________|
+              */
+              svn_merge_range_t *new_modified_range =
+                apr_palloc(result_pool, sizeof(*new_modified_range));
+              new_modified_range->start = next_range->end;
+              new_modified_range->end = modified_range->end;
+              new_modified_range->inheritable = FALSE;
+              modified_range->end = next_range->start;
+              (*range_index)+=2;
+              svn_sort__array_insert(&new_modified_range, rangelist,
+                                     *range_index);
+              /* Recurse with the new range. */
+              adjust_remaining_ranges(rangelist, range_index, result_pool);
+              break;
+            }
+        }
+      else if (modified_range->end == next_range->end)
+        {
+          /* NEXT_RANGE is a proper subset MODIFIED_RANGE and share
+             the same end range. */
+          if (modified_range->inheritable
+              || (modified_range->inheritable == next_range->inheritable))
+            {
+              /* MODIFIED_RANGE absorbs NEXT_RANGE. */
+              elements_to_delete++;
+            }
+          else
+            {
+              /* The intersection between MODIFIED_RANGE and NEXT_RANGE is
+                 absorbed by the latter. */
+              modified_range->end = next_range->start;
+              (*range_index)++;
+            }
+          break;
+        }
+      else
+        {
+          /* NEXT_RANGE and MODIFIED_RANGE intersect but NEXT_RANGE is not
+             a proper subset of MODIFIED_RANGE, nor do the two share the
+             same end revision, i.e. they overlap. */
+          if (modified_range->inheritable == next_range->inheritable)
+            {
+              /* Combine overlapping ranges with the same inheritability. */
+              modified_range->end = next_range->end;
+              elements_to_delete++;
+            }
+          else if (modified_range->inheritable)
+            {
+              /* MODIFIED_RANGE absorbs the portion of NEXT_RANGE it overlaps
+                 and NEXT_RANGE is truncated. */
+              next_range->start = modified_range->end;
+              (*range_index)++;
+            }
+          else
+            {
+              /* NEXT_RANGE absorbs the portion of MODIFIED_RANGE it overlaps
+                 and MODIFIED_RANGE is truncated. */
+              modified_range->end = next_range->start;
+              (*range_index)++;
+            }
+          break;
+        }
+    }
+
+  if (elements_to_delete)
+    svn_sort__array_delete(rangelist, starting_index, elements_to_delete);
+}
+
+svn_error_t *
+svn_rangelist_merge2(apr_array_header_t *rangelist,
+                     const apr_array_header_t *changes,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
+{
+  int i = 0;
+  int j = 0;
 
-      elt1 = APR_ARRAY_IDX(*rangelist, i, svn_merge_range_t *);
-      elt2 = APR_ARRAY_IDX(changes, j, svn_merge_range_t *);
+  /* We may modify CHANGES, so make a copy in SCRATCH_POOL. */
+  changes = svn_rangelist_dup(changes, scratch_pool);
+
+  while (i < rangelist->nelts && j < changes->nelts)
+    {
+      svn_merge_range_t *range =
+        APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
+      svn_merge_range_t *change =
+        APR_ARRAY_IDX(changes, j, svn_merge_range_t *);
+      int res = svn_sort_compare_ranges(&range, &change);
 
-      res = svn_sort_compare_ranges(&elt1, &elt2);
       if (res == 0)
         {
           /* Only when merging two non-inheritable ranges is the result also
              non-inheritable.  In all other cases ensure an inheritiable
              result. */
-          if (elt1->inheritable || elt2->inheritable)
-            elt1->inheritable = TRUE;
-          SVN_ERR(combine_with_lastrange(elt1, output,
-                                         TRUE, pool, pool));
+          if (range->inheritable || change->inheritable)
+            range->inheritable = TRUE;
           i++;
           j++;
         }
-      else if (res < 0)
+      else if (res < 0) /* CHANGE is younger than RANGE */
         {
-          SVN_ERR(combine_with_lastrange(elt1, output,
-                                         TRUE, pool, pool));
-          i++;
+          if (range->end < change->start)
+            {
+              /* RANGE is older than CHANGE and the two do not
+                 adjoin or overlap */
+              i++;
+            }
+          else if (range->end == change->start)
+            {
+              /* RANGE and CHANGE adjoin */
+              if (range->inheritable == change->inheritable)
+                {
+                  /* RANGE and CHANGE have the same inheritability so
+                     RANGE expands to absord CHANGE. */
+                  range->end = change->end;
+                  adjust_remaining_ranges(rangelist, &i, result_pool);
+                  j++;
+                }
+              else
+                {
+                  /* RANGE and CHANGE adjoin, but have different
+                     inheritability.  Since RANGE is older, just
+                     move on to the next RANGE. */
+                  i++;
+                }
+            }
+          else
+            {
+              /* RANGE and CHANGE overlap, but how? */
+              if ((range->inheritable == change->inheritable)
+                  || range->inheritable)
+                {
+                  /* If CHANGE is a proper subset of RANGE, it absorbs RANGE
+                      with no adjustment otherwise only the intersection is
+                      absorbed and CHANGE is truncated. */
+                  if (range->end >= change->end)
+                    j++;
+                  else
+                    change->start = range->end;
+                }
+              else
+                {
+                  /* RANGE is non-inheritable and CHANGE is inheritable. */
+                  if (range->start < change->start)
+                    {
+                      /* CHANGE absorbs intersection with RANGE and RANGE
+                         is truncated. */
+                      svn_merge_range_t *range_copy =
+                        svn_merge_range_dup(range, result_pool);
+                      range_copy->end = change->start;
+                      range->start = change->start;
+                      svn_sort__array_insert(&range_copy, rangelist, i++);
+                    }
+                  else
+                    {
+                      /* CHANGE and RANGE share the same start rev, but
+                         RANGE is considered older because its end rev
+                         is older. */
+                      range->inheritable = TRUE;
+                      change->start = range->end;
+                    }
+                }
+            }
         }
-      else
+      else /* res > 0, CHANGE is older than RANGE */
         {
-          SVN_ERR(combine_with_lastrange(elt2, output,
-                                         TRUE, pool, pool));
-          j++;
+          if (change->end < range->start)
+            {
+              /* CHANGE is older than RANGE and the two do not
+                 adjoin or overlap, so insert a copy of CHANGE
+                 into RANGELIST. */
+              svn_merge_range_t *change_copy =
+                svn_merge_range_dup(change, result_pool);
+              svn_sort__array_insert(&change_copy, rangelist, i++);
+              j++;
+            }
+          else if (change->end == range->start)
+            {
+              /* RANGE and CHANGE adjoin */
+              if (range->inheritable == change->inheritable)
+                {
+                  /* RANGE and CHANGE have the same inheritability so we
+                     can simply combine the two in place. */
+                  range->start = change->start;
+                  j++;
+                }
+              else
+                {
+                  /* RANGE and CHANGE have different inheritability so insert
+                     a copy of CHANGE into RANGELIST. */
+                  svn_merge_range_t *change_copy =
+                    svn_merge_range_dup(change, result_pool);
+                  svn_sort__array_insert(&change_copy, rangelist, i);
+                  j++;
+                }
+            }
+          else
+            {
+              /* RANGE and CHANGE overlap. */
+              if (range->inheritable == change->inheritable)
+                {
+                  /* RANGE and CHANGE have the same inheritability so we
+                     can simply combine the two in place... */
+                  range->start = change->start;
+                  if (range->end < change->end)
+                    {
+                      /* ...but if RANGE is expanded ensure that we don't
+                         violate any rangelist invariants. */
+                      range->end = change->end;
+                      adjust_remaining_ranges(rangelist, &i, result_pool);
+                    }
+                  j++;
+                }
+              else if (range->inheritable)
+                {
+                  if (change->start < range->start)
+                    {
+                      /* RANGE is inheritable so absorbs any part of CHANGE
+                         it overlaps.  CHANGE is truncated and the remainder
+                         inserted into RANGELIST. */
+                      svn_merge_range_t *change_copy =
+                        svn_merge_range_dup(change, result_pool);
+                      change_copy->end = range->start;
+                      change->start = range->start;
+                      svn_sort__array_insert(&change_copy, rangelist, i++);
+                    }
+                  else
+                    {
+                      /* CHANGE and RANGE share the same start rev, but
+                         CHANGE is considered older because CHANGE->END is
+                         older than RANGE->END. */
+                      j++;
+                    }
+                }
+              else
+                {
+                  /* RANGE is non-inheritable and CHANGE is inheritable. */
+                  if (change->start < range->start)
+                    {
+                      if (change->end == range->end)
+                        {
+                          /* RANGE is a proper subset of CHANGE and share the
+                             same end revision, so set RANGE equal to CHANGE. */
+                          range->start = change->start;
+                          range->inheritable = TRUE;
+                          j++;
+                        }
+                      else if (change->end > range->end)
+                        {
+                          /* RANGE is a proper subset of CHANGE and CHANGE has
+                             a younger end revision, so set RANGE equal to its
+                             intersection with CHANGE and truncate CHANGE. */
+                          range->start = change->start;
+                          range->inheritable = TRUE;
+                          change->start = range->end;
+                        }
+                      else
+                        {
+                          /* CHANGE and RANGE overlap. Set RANGE equal to its
+                             intersection with CHANGE and take the remainder
+                             of RANGE and insert it into RANGELIST. */
+                          svn_merge_range_t *range_copy =
+                            svn_merge_range_dup(range, result_pool);
+                          range_copy->start = change->end;
+                          range->start = change->start;
+                          range->end = change->end;
+                          range->inheritable = TRUE;
+                          svn_sort__array_insert(&range_copy, rangelist, ++i);
+                          j++;
+                        }
+                    }
+                  else 
+                    {
+                      /* CHANGE and RANGE share the same start rev, but
+                         CHANGE is considered older because its end rev
+                         is older.
+                         
+                         Insert the intersection of RANGE and CHANGE into
+                         RANGELIST and then set RANGE to the non-intersecting
+                         portion of RANGE. */
+                      svn_merge_range_t *range_copy =
+                        svn_merge_range_dup(range, result_pool);
+                      range_copy->end = change->end;
+                      range_copy->inheritable = TRUE;
+                      range->start = change->end;
+                      svn_sort__array_insert(&range_copy, rangelist, i++);
+                      j++;
+                    }
+                }
+            }
         }
     }
-  /* Copy back any remaining elements.
-     Only one of these loops should end up running, if anything. */
-
-  SVN_ERR_ASSERT(!(i < (*rangelist)->nelts && j < changes->nelts));
 
-  for (; i < (*rangelist)->nelts; i++)
+  /* Copy any remaining elements in CHANGES into RANGELIST. */
+  for (; j < (changes)->nelts; j++)
     {
-      svn_merge_range_t *elt = APR_ARRAY_IDX(*rangelist, i,
-                                             svn_merge_range_t *);
-      SVN_ERR(combine_with_lastrange(elt, output,
-                                     TRUE, pool, pool));
+      svn_merge_range_t *change =
+        APR_ARRAY_IDX(changes, j, svn_merge_range_t *);
+      svn_merge_range_t *change_copy = svn_merge_range_dup(change,
+                                                           result_pool);
+      svn_sort__array_insert(&change_copy, rangelist, rangelist->nelts);
     }
 
-
-  for (; j < changes->nelts; j++)
-    {
-      svn_merge_range_t *elt = APR_ARRAY_IDX(changes, j, svn_merge_range_t *);
-      SVN_ERR(combine_with_lastrange(elt, output,
-                                     TRUE, pool, pool));
-    }
-
-  *rangelist = output;
   return SVN_NO_ERROR;
 }
 
@@ -969,7 +1334,7 @@ rangelist_intersect_or_remove(apr_array_
               tmp_range.inheritable =
                 (elt2->inheritable || elt1->inheritable);
               SVN_ERR(combine_with_lastrange(&tmp_range, *output,
-                                             consider_inheritance, pool,
+                                             consider_inheritance,
                                              pool));
             }
 
@@ -1006,7 +1371,7 @@ rangelist_intersect_or_remove(apr_array_
 
               SVN_ERR(combine_with_lastrange(&tmp_range,
                                              *output, consider_inheritance,
-                                             pool, pool));
+                                             pool));
             }
 
           /* Set up the rest of the rangelist2 range for further
@@ -1027,7 +1392,7 @@ rangelist_intersect_or_remove(apr_array_
                   SVN_ERR(combine_with_lastrange(&tmp_range,
                                                  *output,
                                                  consider_inheritance,
-                                                 pool, pool));
+                                                 pool));
                 }
 
               working_elt2.start = elt1->end;
@@ -1079,7 +1444,7 @@ rangelist_intersect_or_remove(apr_array_
       if (i2 == lasti2 && i2 < rangelist2->nelts)
         {
           SVN_ERR(combine_with_lastrange(&working_elt2, *output,
-                                         consider_inheritance, pool, pool));
+                                         consider_inheritance, pool));
           i2++;
         }
 
@@ -1090,7 +1455,7 @@ rangelist_intersect_or_remove(apr_array_
                                                  svn_merge_range_t *);
 
           SVN_ERR(combine_with_lastrange(elt, *output,
-                                         consider_inheritance, pool, pool));
+                                         consider_inheritance, pool));
         }
     }
 
@@ -1292,25 +1657,33 @@ svn_mergeinfo__equals(svn_boolean_t *is_
 }
 
 svn_error_t *
-svn_mergeinfo_merge(svn_mergeinfo_t mergeinfo, svn_mergeinfo_t changes,
-                    apr_pool_t *pool)
+svn_mergeinfo_merge2(svn_mergeinfo_t mergeinfo,
+                     svn_mergeinfo_t changes,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
 {
   apr_array_header_t *sorted1, *sorted2;
   int i, j;
+  apr_pool_t *iterpool;
 
   if (!apr_hash_count(changes))
     return SVN_NO_ERROR;
 
-  sorted1 = svn_sort__hash(mergeinfo, svn_sort_compare_items_as_paths, pool);
-  sorted2 = svn_sort__hash(changes, svn_sort_compare_items_as_paths, pool);
+  sorted1 = svn_sort__hash(mergeinfo, svn_sort_compare_items_as_paths,
+                           scratch_pool);
+  sorted2 = svn_sort__hash(changes, svn_sort_compare_items_as_paths,
+                           scratch_pool);
 
   i = 0;
   j = 0;
+  iterpool = svn_pool_create(scratch_pool);
   while (i < sorted1->nelts && j < sorted2->nelts)
     {
       svn_sort__item_t elt1, elt2;
       int res;
 
+      svn_pool_clear(iterpool);
+
       elt1 = APR_ARRAY_IDX(sorted1, i, svn_sort__item_t);
       elt2 = APR_ARRAY_IDX(sorted2, j, svn_sort__item_t);
       res = svn_sort_compare_items_as_paths(&elt1, &elt2);
@@ -1322,8 +1695,7 @@ svn_mergeinfo_merge(svn_mergeinfo_t merg
           rl1 = elt1.value;
           rl2 = elt2.value;
 
-          SVN_ERR(svn_rangelist_merge(&rl1, rl2,
-                                      pool));
+          SVN_ERR(svn_rangelist_merge2(rl1, rl2, result_pool, iterpool));
           apr_hash_set(mergeinfo, elt1.key, elt1.klen, rl1);
           i++;
           j++;
@@ -1338,6 +1710,7 @@ svn_mergeinfo_merge(svn_mergeinfo_t merg
           j++;
         }
     }
+  svn_pool_destroy(iterpool);
 
   /* Copy back any remaining elements from the second hash. */
   for (; j < sorted2->nelts; j++)
@@ -1378,8 +1751,8 @@ svn_mergeinfo_catalog_merge(svn_mergeinf
           svn_mergeinfo_t mergeinfo = cat_elt.value;
           svn_mergeinfo_t changes_mergeinfo = change_elt.value;
 
-          SVN_ERR(svn_mergeinfo_merge(mergeinfo, changes_mergeinfo,
-                                      result_pool));
+          SVN_ERR(svn_mergeinfo_merge2(mergeinfo, changes_mergeinfo,
+                                       result_pool, scratch_pool));
           apr_hash_set(mergeinfo_cat, cat_elt.key, cat_elt.klen, mergeinfo);
           i++;
           j++;
@@ -1413,16 +1786,6 @@ svn_mergeinfo_catalog_merge(svn_mergeinf
 }
 
 svn_error_t *
-svn_mergeinfo_intersect(svn_mergeinfo_t *mergeinfo,
-                        svn_mergeinfo_t mergeinfo1,
-                        svn_mergeinfo_t mergeinfo2,
-                        apr_pool_t *pool)
-{
-  return svn_mergeinfo_intersect2(mergeinfo, mergeinfo1, mergeinfo2,
-                                  TRUE, pool, pool);
-}
-
-svn_error_t *
 svn_mergeinfo_intersect2(svn_mergeinfo_t *mergeinfo,
                          svn_mergeinfo_t mergeinfo1,
                          svn_mergeinfo_t mergeinfo2,
@@ -1431,26 +1794,29 @@ svn_mergeinfo_intersect2(svn_mergeinfo_t
                          apr_pool_t *scratch_pool)
 {
   apr_hash_index_t *hi;
+  apr_pool_t *iterpool;
 
   *mergeinfo = apr_hash_make(result_pool);
+  iterpool = svn_pool_create(scratch_pool);
 
   /* ### TODO(reint): Do we care about the case when a path in one
      ### mergeinfo hash has inheritable mergeinfo, and in the other
      ### has non-inhertiable mergeinfo?  It seems like that path
      ### itself should really be an intersection, while child paths
      ### should not be... */
-  for (hi = apr_hash_first(apr_hash_pool_get(mergeinfo1), mergeinfo1);
+  for (hi = apr_hash_first(scratch_pool, mergeinfo1);
        hi; hi = apr_hash_next(hi))
     {
       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;
 
+      svn_pool_clear(iterpool);
       rangelist2 = apr_hash_get(mergeinfo2, path, APR_HASH_KEY_STRING);
       if (rangelist2)
         {
           SVN_ERR(svn_rangelist_intersect(&rangelist2, rangelist1, rangelist2,
-                                          consider_inheritance, scratch_pool));
+                                          consider_inheritance, iterpool));
           if (rangelist2->nelts > 0)
             apr_hash_set(*mergeinfo,
                          apr_pstrdup(result_pool, path),
@@ -1458,18 +1824,11 @@ svn_mergeinfo_intersect2(svn_mergeinfo_t
                          svn_rangelist_dup(rangelist2, result_pool));
         }
     }
+  svn_pool_destroy(iterpool);
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_mergeinfo_remove(svn_mergeinfo_t *mergeinfo, svn_mergeinfo_t eraser,
-                     svn_mergeinfo_t whiteboard, apr_pool_t *pool)
-{
-  return svn_mergeinfo_remove2(mergeinfo, eraser, whiteboard, TRUE, pool,
-                               pool);
-}
-
-svn_error_t *
 svn_mergeinfo_remove2(svn_mergeinfo_t *mergeinfo,
                       svn_mergeinfo_t eraser,
                       svn_mergeinfo_t whiteboard,
@@ -2254,3 +2613,27 @@ svn_mergeinfo__mergeinfo_from_segments(s
   *mergeinfo_p = mergeinfo;
   return SVN_NO_ERROR;
 }
+
+const char *
+svn_inheritance_to_word(svn_mergeinfo_inheritance_t inherit)
+{
+  switch (inherit)
+    {
+    case svn_mergeinfo_inherited:
+      return "inherited";
+    case svn_mergeinfo_nearest_ancestor:
+      return "nearest-ancestor";
+    default:
+      return "explicit";
+    }
+}
+
+svn_mergeinfo_inheritance_t
+svn_inheritance_from_word(const char *word)
+{
+  if (strcmp(word, "inherited") == 0)
+    return svn_mergeinfo_inherited;
+  if (strcmp(word, "nearest-ancestor") == 0)
+    return svn_mergeinfo_nearest_ancestor;
+  return svn_mergeinfo_explicit;
+}

Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/properties.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/properties.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/properties.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/properties.c Tue Oct 11 19:52:34 2011
@@ -221,6 +221,85 @@ svn_prop_diffs(apr_array_header_t **prop
   return SVN_NO_ERROR;
 }
 
+/**
+ * Reallocate the members of PROP using POOL.
+ */
+static void
+svn_prop__members_dup(svn_prop_t *prop, apr_pool_t *pool)
+{
+  if (prop->name)
+    prop->name = apr_pstrdup(pool, prop->name);
+  if (prop->value)
+    prop->value = svn_string_dup(prop->value, pool);
+}
+
+svn_prop_t *
+svn_prop_dup(const svn_prop_t *prop, apr_pool_t *pool)
+{
+  svn_prop_t *new_prop = apr_palloc(pool, sizeof(*new_prop));
+
+  *new_prop = *prop;
+
+  svn_prop__members_dup(new_prop, pool);
+
+  return new_prop;
+}
+
+apr_array_header_t *
+svn_prop_array_dup(const apr_array_header_t *array, apr_pool_t *pool)
+{
+  int i;
+  apr_array_header_t *new_array = apr_array_copy(pool, array);
+  for (i = 0; i < new_array->nelts; ++i)
+    {
+      svn_prop_t *elt = &APR_ARRAY_IDX(new_array, i, svn_prop_t);
+      svn_prop__members_dup(elt, pool);
+    }
+  return new_array;
+}
+
+apr_array_header_t *
+svn_prop_hash_to_array(apr_hash_t *hash, apr_pool_t *pool)
+{
+  apr_hash_index_t *hi;
+  apr_array_header_t *array = apr_array_make(pool, apr_hash_count(hash),
+                                             sizeof(svn_prop_t));
+
+  for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
+    {
+      const void *key;
+      void *val;
+      svn_prop_t prop;
+
+      apr_hash_this(hi, &key, NULL, &val);
+      prop.name = key;
+      prop.value = val;
+      APR_ARRAY_PUSH(array, svn_prop_t) = prop;
+    }
+
+  return array;
+}
+
+apr_hash_t *
+svn_prop_hash_dup(apr_hash_t *hash,
+                  apr_pool_t *pool)
+{
+  apr_hash_index_t *hi;
+  apr_hash_t *new_hash = apr_hash_make(pool);
+
+  for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
+    {
+      const void *key;
+      apr_ssize_t klen;
+      void *prop;
+
+      apr_hash_this(hi, &key, &klen, &prop);
+      apr_hash_set(new_hash, apr_pstrdup(pool, key), klen,
+                   svn_string_dup(prop, pool));
+    }
+  return new_hash;
+}
+
 apr_hash_t *
 svn_prop_array_to_hash(const apr_array_header_t *properties,
                        apr_pool_t *pool)

Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/simple_providers.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/simple_providers.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/simple_providers.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/simple_providers.c Tue Oct 11 19:52:34 2011
@@ -358,7 +358,8 @@ svn_auth__simple_save_creds_helper(svn_b
            (strcmp(passtype, SVN_AUTH__WINCRYPT_PASSWORD_TYPE) == 0
             || strcmp(passtype, SVN_AUTH__KEYCHAIN_PASSWORD_TYPE) == 0
             || strcmp(passtype, SVN_AUTH__KWALLET_PASSWORD_TYPE) == 0
-            || strcmp(passtype, SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE) == 0) )
+            || strcmp(passtype, SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE) == 0
+            || strcmp(passtype, SVN_AUTH__GPG_AGENT_PASSWORD_TYPE) == 0))
         {
           may_save_password = TRUE;
         }

Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/sorts.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/sorts.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/sorts.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/sorts.c Tue Oct 11 19:52:34 2011
@@ -140,21 +140,38 @@ svn_sort__hash(apr_hash_t *ht,
 {
   apr_hash_index_t *hi;
   apr_array_header_t *ary;
+  svn_boolean_t sorted;
+  svn_sort__item_t *prev_item;
 
   /* allocate an array with enough elements to hold all the keys. */
   ary = apr_array_make(pool, apr_hash_count(ht), sizeof(svn_sort__item_t));
 
   /* loop over hash table and push all keys into the array */
+  sorted = TRUE;
+  prev_item = NULL;
   for (hi = apr_hash_first(pool, ht); hi; hi = apr_hash_next(hi))
     {
       svn_sort__item_t *item = apr_array_push(ary);
 
       apr_hash_this(hi, &item->key, &item->klen, &item->value);
+
+      if (prev_item == NULL)
+        {
+          prev_item = item;
+          continue;
+        }
+
+      if (sorted)
+        {
+          sorted = (comparison_func(prev_item, item) < 0);
+          prev_item = item;
+        }
     }
 
-  /* now quicksort the array.  */
-  qsort(ary->elts, ary->nelts, ary->elt_size,
-        (int (*)(const void *, const void *))comparison_func);
+  /* quicksort the array if it isn't already sorted.  */
+  if (!sorted)
+    qsort(ary->elts, ary->nelts, ary->elt_size,
+          (int (*)(const void *, const void *))comparison_func);
 
   return ary;
 }
@@ -228,3 +245,35 @@ svn_sort__array_insert(const void *new_e
   /* Copy in the new element */
   memcpy(new_position, new_element, array->elt_size);
 }
+
+void
+svn_sort__array_delete(apr_array_header_t *arr,
+                       int delete_index,
+                       int elements_to_delete)
+{
+  /* Do we have a valid index and are there enough elements? */
+  if (delete_index >= 0
+      && delete_index < arr->nelts
+      && elements_to_delete > 0
+      && (elements_to_delete + delete_index) <= arr->nelts)
+    {
+      if (delete_index == (arr->nelts - 1))
+        {
+          /* Deleting the last or only element in an array is easy. */
+          apr_array_pop(arr);
+        }
+      else if ((delete_index + elements_to_delete) == arr->nelts)
+        {
+          /* Delete the last ELEMENTS_TO_DELETE elements. */
+          arr->nelts -= elements_to_delete;
+        }
+      else
+        {
+          memmove(
+            arr->elts + arr->elt_size * delete_index,
+            arr->elts + (arr->elt_size * (delete_index + elements_to_delete)),
+            arr->elt_size * (arr->nelts - elements_to_delete - delete_index));
+          arr->nelts -= elements_to_delete;
+        }
+    }
+}

Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/sqlite.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/sqlite.c Tue Oct 11 19:52:34 2011
@@ -133,6 +133,10 @@ struct svn_sqlite__value_t
 } while (0)
 
 
+/* Time (in milliseconds) to wait for sqlite locks before giving up. */
+#define BUSY_TIMEOUT 10000
+
+
 /* Convenience wrapper around exec_sql2(). */
 #define exec_sql(db, sql) exec_sql2((db), (sql), SQLITE_OK)
 
@@ -579,108 +583,6 @@ svn_sqlite__reset(svn_sqlite__stmt_t *st
 
 
 svn_error_t *
-svn_sqlite__set_schema_version(svn_sqlite__db_t *db,
-                               int version,
-                               apr_pool_t *scratch_pool)
-{
-  const char *pragma_cmd = apr_psprintf(scratch_pool,
-                                        "PRAGMA user_version = %d;",
-                                        version);
-
-  return svn_error_trace(exec_sql(db, pragma_cmd));
-}
-
-
-/* Time (in milliseconds) to wait for sqlite locks before giving up. */
-#define BUSY_TIMEOUT 10000
-
-
-#if 0
-/*
- * EXAMPLE
- *
- * The following provide an example for a series of SQL statements to
- * create/upgrade a SQLite schema across multiple "formats". This array
- * and integer would be passed into svn_sqlite__open().
- */
-static const char *schema_create_sql[] = {
-  NULL, /* An empty database is format 0 */
-
-  /* USER_VERSION 1 */
-  "PRAGMA auto_vacuum = 1;"
-  APR_EOL_STR
-  "CREATE TABLE mergeinfo (revision INTEGER NOT NULL, mergedfrom TEXT NOT "
-  "NULL, mergedto TEXT NOT NULL, mergedrevstart INTEGER NOT NULL, "
-  "mergedrevend INTEGER NOT NULL, inheritable INTEGER NOT NULL);"
-  APR_EOL_STR
-  "CREATE INDEX mi_mergedfrom_idx ON mergeinfo (mergedfrom);"
-  APR_EOL_STR
-  "CREATE INDEX mi_mergedto_idx ON mergeinfo (mergedto);"
-  APR_EOL_STR
-  "CREATE INDEX mi_revision_idx ON mergeinfo (revision);"
-  APR_EOL_STR
-  "CREATE TABLE mergeinfo_changed (revision INTEGER NOT NULL, path TEXT "
-  "NOT NULL);"
-  APR_EOL_STR
-  "CREATE UNIQUE INDEX mi_c_revpath_idx ON mergeinfo_changed (revision, path);"
-  APR_EOL_STR
-  "CREATE INDEX mi_c_path_idx ON mergeinfo_changed (path);"
-  APR_EOL_STR
-  "CREATE INDEX mi_c_revision_idx ON mergeinfo_changed (revision);"
-  APR_EOL_STR,
-
-  /* USER_VERSION 2 */
-  "CREATE TABLE node_origins (node_id TEXT NOT NULL, node_rev_id TEXT NOT "
-  "NULL);"
-  APR_EOL_STR
-  "CREATE UNIQUE INDEX no_ni_idx ON node_origins (node_id);"
-  APR_EOL_STR
-};
-
-static const int latest_schema_format =
-  sizeof(schema_create_sql)/sizeof(schema_create_sql[0]) - 1;
-
-#endif
-
-struct upgrade_baton
-{
-  int current_schema;
-  int latest_schema;
-  const char * const *upgrade_sql;
-};
-
-
-/* This implements svn_sqlite__transaction_callback_t */
-static svn_error_t *
-upgrade_format(void *baton,
-               svn_sqlite__db_t *db,
-               apr_pool_t *scratch_pool)
-{
-  struct upgrade_baton *ub = baton;
-  int current_schema = ub->current_schema;
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
-  while (current_schema < ub->latest_schema)
-    {
-      svn_pool_clear(iterpool);
-
-      /* Go to the next schema */
-      current_schema++;
-
-      /* Run the upgrade SQL */
-      if (ub->upgrade_sql[current_schema])
-        SVN_ERR(exec_sql(db, ub->upgrade_sql[current_schema]));
-
-      /* Update the user version pragma */
-      SVN_ERR(svn_sqlite__set_schema_version(db, current_schema, iterpool));
-    }
-
-  svn_pool_destroy(iterpool);
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
 svn_sqlite__read_schema_version(int *version,
                                 svn_sqlite__db_t *db,
                                 apr_pool_t *scratch_pool)
@@ -696,41 +598,6 @@ svn_sqlite__read_schema_version(int *ver
 }
 
 
-/* Check the schema format of the database, upgrading it if necessary.
-   Return SVN_ERR_SQLITE_UNSUPPORTED_SCHEMA if the schema format is too new,
-   or SVN_ERR_SQLITE_ERROR if an sqlite error occurs during validation.
-   Return SVN_NO_ERROR if everything is okay. */
-static svn_error_t *
-check_format(svn_sqlite__db_t *db,
-             int latest_schema,
-             const char * const *upgrade_sql,
-             apr_pool_t *scratch_pool)
-{
-  int current_schema;
-
-  /* Validate that the schema exists as expected. */
-  SVN_ERR(svn_sqlite__read_schema_version(&current_schema, db, scratch_pool));
-
-  if (current_schema == latest_schema)
-    return SVN_NO_ERROR;
-
-  if (current_schema < latest_schema)
-    {
-      struct upgrade_baton ub;
-
-      ub.current_schema = current_schema;
-      ub.latest_schema = latest_schema;
-      ub.upgrade_sql = upgrade_sql;
-
-      return svn_error_trace(svn_sqlite__with_transaction(
-                               db, upgrade_format, &ub, scratch_pool));
-    }
-
-  return svn_error_createf(SVN_ERR_SQLITE_UNSUPPORTED_SCHEMA, NULL,
-                           _("Schema format %d not recognized"),
-                           current_schema);
-}
-
 static volatile svn_atomic_t sqlite_init_state = 0;
 
 /* If possible, verify that SQLite was compiled in a thread-safe
@@ -770,12 +637,6 @@ init_sqlite(void *baton, apr_pool_t *poo
 
 #endif /* APR_HAS_THRADS */
 
-  /* SQLite 3.5 allows sharing cache instances, even in a multithreaded
-     environment. This allows sharing cached data when we open a database
-     more than once (Very common in the current pre-single-database state) */
-  SQLITE_ERR_MSG(sqlite3_enable_shared_cache(TRUE),
-                 _("Could not initialize SQLite shared cache"));
-
   return SVN_NO_ERROR;
 }
 
@@ -806,6 +667,13 @@ internal_open(sqlite3 **db3, const char 
     flags |= SQLITE_OPEN_NOMUTEX;
 #endif
 
+    /* SQLite 3.5 allows sharing cache instances, even in a multithreaded
+       environment. This allows sharing cached data when we open a database
+       more than once.
+
+       OS X 10.7 doesn't support sqlite3_enable_shared_cache. */
+    flags |= SQLITE_OPEN_SHAREDCACHE;
+
     /* Open the database. Note that a handle is returned, even when an error
        occurs (except for out-of-memory); thus, we can safely use it to
        extract an error message and construct an svn_error_t. */
@@ -836,22 +704,6 @@ internal_open(sqlite3 **db3, const char 
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_sqlite__get_schema_version(int *version,
-                               const char *path,
-                               apr_pool_t *scratch_pool)
-{
-  svn_sqlite__db_t db;
-
-  SVN_ERR(svn_atomic__init_once(&sqlite_init_state,
-                                init_sqlite, NULL, scratch_pool));
-  SVN_ERR(internal_open(&db.db3, path, svn_sqlite__mode_readonly,
-                        scratch_pool));
-  SVN_ERR(svn_sqlite__read_schema_version(version, &db, scratch_pool));
-  SQLITE_ERR(sqlite3_close(db.db3), &db);
-
-  return SVN_NO_ERROR;
-}
 
 /* APR cleanup function used to close the database when its pool is destroyed.
    DATA should be the svn_sqlite__db_t handle for the database. */
@@ -897,7 +749,7 @@ close_apr(void *data)
 svn_error_t *
 svn_sqlite__open(svn_sqlite__db_t **db, const char *path,
                  svn_sqlite__mode_t mode, const char * const statements[],
-                 int latest_schema, const char * const *upgrade_sql,
+                 int unused1, const char * const *unused2,
                  apr_pool_t *result_pool, apr_pool_t *scratch_pool)
 {
   SVN_ERR(svn_atomic__init_once(&sqlite_init_state,
@@ -966,10 +818,6 @@ svn_sqlite__open(svn_sqlite__db_t **db, 
      setting SQLITE_TEMP_STORE to 0 (always to disk) */
   svn_error_clear(exec_sql(*db, "PRAGMA temp_store = MEMORY;"));
 
-  /* Validate the schema, upgrading if necessary. */
-  if (upgrade_sql != NULL)
-    SVN_ERR(check_format(*db, latest_schema, upgrade_sql, scratch_pool));
-
   /* Store the provided statements. */
   if (statements)
     {

Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/subst.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/subst.c Tue Oct 11 19:52:34 2011
@@ -1267,15 +1267,16 @@ static svn_error_t *
 translated_stream_close(void *baton)
 {
   struct translated_stream_baton *b = baton;
+  svn_error_t *err = NULL;
 
   if (b->written)
-    SVN_ERR(translate_chunk(b->stream, b->out_baton, NULL, 0, b->iterpool));
+    err = translate_chunk(b->stream, b->out_baton, NULL, 0, b->iterpool);
 
-  SVN_ERR(svn_stream_close(b->stream));
+  err = svn_error_compose_create(err, svn_stream_close(b->stream));
 
   svn_pool_destroy(b->iterpool);
 
-  return SVN_NO_ERROR;
+  return svn_error_trace(err);
 }
 
 

Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/svn_base64.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/svn_base64.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/svn_base64.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/svn_base64.c Tue Oct 11 19:52:34 2011
@@ -35,10 +35,10 @@
 #include "svn_base64.h"
 #include "private/svn_string_private.h"
 
-/* When asked to format the the base64-encoded output as multiple lines, 
+/* When asked to format the the base64-encoded output as multiple lines,
    we put this many chars in each line (plus one new line char) unless
    we run out of data.
-   It is vital for some of the optimizations below that this value is 
+   It is vital for some of the optimizations below that this value is
    a multiple of 4. */
 #define BASE64_LINELEN 76
 
@@ -73,7 +73,7 @@ encode_group(const unsigned char *in, ch
   apr_size_t part0 = in[0];
   apr_size_t part1 = in[1];
   apr_size_t part2 = in[2];
-  
+
   /* ... to prevent these arithmetic operations from being limited to
      byte size.  This saves non-zero cost conversions of the result when
      calculating the addresses within base64tab. */
@@ -88,7 +88,7 @@ encode_group(const unsigned char *in, ch
    a new line char will be appended, though.
    The code in this function will simply transform the data without
    performing any boundary checks.  Therefore, DATA must have at least
-   BYTES_PER_LINE left and space for at least another BASE64_LINELEN 
+   BYTES_PER_LINE left and space for at least another BASE64_LINELEN
    chars must have been pre-allocated in STR before calling this
    function. */
 static void
@@ -99,11 +99,11 @@ encode_line(svn_stringbuf_t *str, const 
   char *out = str->data + str->len;
   char *end = out + BASE64_LINELEN;
 
-  /* We assume that BYTES_PER_LINE is a multiple of 3 and BASE64_LINELEN 
+  /* We assume that BYTES_PER_LINE is a multiple of 3 and BASE64_LINELEN
      a multiple of 4. */
   for ( ; out != end; in += 3, out += 4)
     encode_group(in, out);
-  
+
   /* Expand and terminate the string. */
   *out = '\0';
   str->len += BASE64_LINELEN;
@@ -127,7 +127,7 @@ encode_bytes(svn_stringbuf_t *str, const
   apr_size_t buflen;
 
   /* Resize the stringbuf to make room for the (approximate) size of
-     output, to avoid repeated resizes later. 
+     output, to avoid repeated resizes later.
      Please note that our optimized code relies on the fact that STR
      never needs to be resized until we leave this function. */
   buflen = len * 4 / 3 + 4;
@@ -144,7 +144,7 @@ encode_bytes(svn_stringbuf_t *str, const
       /* May we encode BYTES_PER_LINE bytes without caring about
          line breaks, data in the temporary INBUF or running out
          of data? */
-      if (   *inbuflen == 0 
+      if (   *inbuflen == 0
           && (*linelen == 0 || !break_lines)
           && (end - p >= BYTES_PER_LINE))
         {
@@ -155,7 +155,7 @@ encode_bytes(svn_stringbuf_t *str, const
         }
       else
         {
-          /* No, this is one of a number of special cases. 
+          /* No, this is one of a number of special cases.
              Encode the data byte by byte. */
           memcpy(inbuf + *inbuflen, p, 3 - *inbuflen);
           p += (3 - *inbuflen);
@@ -361,7 +361,7 @@ decode_group_directly(const unsigned cha
    in between.
    The code in this function will simply transform the data without
    performing any boundary checks.  Therefore, DATA must have at least
-   BASE64_LINELEN left and space for at least another BYTES_PER_LINE 
+   BASE64_LINELEN left and space for at least another BYTES_PER_LINE
    chars must have been pre-allocated in STR before calling this
    function. */
 static svn_boolean_t
@@ -372,7 +372,7 @@ decode_line(svn_stringbuf_t *str, const 
   char *out = str->data + str->len;
   char *end = out + BYTES_PER_LINE;
 
-  /* We assume that BYTES_PER_LINE is a multiple of 3 and BASE64_LINELEN 
+  /* We assume that BYTES_PER_LINE is a multiple of 3 and BASE64_LINELEN
      a multiple of 4.  Stop translation as soon as we encounter a special
      char.  Leave the entire group untouched in that case. */
   for (; out < end; p += 4, out += 3)
@@ -383,7 +383,7 @@ decode_line(svn_stringbuf_t *str, const 
   str->len = out - str->data;
   *out = '\0';
   *data = (const char *)p;
-  
+
   /* Return FALSE, if the caller should continue the decoding process
      using the slow standard method. */
   return out == end;
@@ -408,7 +408,7 @@ decode_bytes(svn_stringbuf_t *str, const
   const char *end = data + len;
 
   /* Resize the stringbuf to make room for the (approximate) size of
-     output, to avoid repeated resizes later. 
+     output, to avoid repeated resizes later.
      The optimizations in decode_line rely on no resizes being necessary! */
   svn_stringbuf_ensure(str, str->len + (len / 4) * 3 + 3);
 
@@ -420,7 +420,7 @@ decode_bytes(svn_stringbuf_t *str, const
       if ((*inbuflen == 0) && (p + BASE64_LINELEN <= end))
         if (decode_line(str, &p))
           continue;
-        
+
       /* A special case or decode_line encountered a special char. */
       if (*p == '=')
         {

Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/svn_cache_config.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/svn_cache_config.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/svn_cache_config.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/svn_cache_config.c Tue Oct 11 19:52:34 2011
@@ -113,6 +113,7 @@ svn_cache__get_global_membuffer_cache(vo
       apr_pool_create_ex(&pool, NULL, NULL, allocator);
       if (pool == NULL)
         return NULL;
+      apr_allocator_owner_set(allocator, pool);
 
       err = svn_cache__membuffer_cache_create(
           &new_cache,
@@ -146,6 +147,9 @@ svn_cache__get_global_membuffer_cache(vo
       /* Handle race condition: if we are the first to create a
        * cache object, make it our global singleton. Otherwise,
        * discard the new cache and keep the existing one.
+       *
+       * Cast is necessary because of APR bug:
+       * https://issues.apache.org/bugzilla/show_bug.cgi?id=50731
        */
       old_cache = apr_atomic_casptr((volatile void **)&cache, new_cache, NULL);
       if (old_cache != NULL)

Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/svn_string.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/svn_string.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/svn_string.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/svn_string.c Tue Oct 11 19:52:34 2011
@@ -725,7 +725,7 @@ svn_cstring_join(const apr_array_header_
                  apr_pool_t *pool)
 {
   svn_stringbuf_t *new_str = svn_stringbuf_create("", pool);
-  int sep_len = strlen(separator);
+  size_t sep_len = strlen(separator);
   int i;
 
   for (i = 0; i < strings->nelts; i++)
@@ -839,3 +839,16 @@ svn_cstring_atoi(int *n, const char *str
   *n = (int)val;
   return SVN_NO_ERROR;
 }
+
+
+apr_status_t
+svn__strtoff(apr_off_t *offset, const char *buf, char **end, int base)
+{
+#if !APR_VERSION_AT_LEAST(1,0,0)
+  errno = 0;
+  *offset = strtol(buf, end, base);
+  return APR_FROM_OS_ERROR(errno);
+#else
+  return apr_strtoff(offset, buf, end, base);
+#endif
+}

Propchange: subversion/branches/svn_mutex/subversion/libsvn_subr/svn_temp_serializer.c
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Oct 11 19:52:34 2011
@@ -1 +1,2 @@
-/subversion/trunk/subversion/libsvn_subr/svn_temp_serializer.c:1067687-1072301,1141684-1142212
+/subversion/branches/revprop-packing/subversion/libsvn_subr/svn_temp_serializer.c:1143907,1143971,1144017,1144568,1146145
+/subversion/trunk/subversion/libsvn_subr/svn_temp_serializer.c:1067687-1072301,1141684-1142212,1142216-1181870

Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/target.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/target.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/target.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/target.c Tue Oct 11 19:52:34 2011
@@ -46,7 +46,7 @@ svn_path_condense_targets(const char **p
   int i, j, num_condensed = targets->nelts;
   svn_boolean_t *removed;
   apr_array_header_t *abs_targets;
-  int basedir_len;
+  size_t basedir_len;
   const char *first_target;
   svn_boolean_t first_target_is_url;
 

Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/utf.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/utf.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/utf.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/utf.c Tue Oct 11 19:52:34 2011
@@ -89,8 +89,8 @@ static apr_hash_t *xlate_handle_hash = N
  * using atomic xchange ops, i.e. without further thread synchronization.
  * If the respective item is NULL, fallback to hash lookup.
  */
-static volatile void *xlat_ntou_static_handle = NULL;
-static volatile void *xlat_uton_static_handle = NULL;
+static void * volatile xlat_ntou_static_handle = NULL;
+static void * volatile xlat_uton_static_handle = NULL;
 
 /* Clean up the xlate handle cache. */
 static apr_status_t
@@ -177,11 +177,13 @@ get_xlate_key(const char *topage,
  * the caller.
  */
 static APR_INLINE void*
-atomic_swap(volatile void **mem, void *new_value)
+atomic_swap(void * volatile * mem, void *new_value)
 {
 #if APR_HAS_THREADS
 #if APR_VERSION_AT_LEAST(1,3,0)
-   return apr_atomic_xchgptr(mem, new_value);
+  /* Cast is necessary because of APR bug:
+     https://issues.apache.org/bugzilla/show_bug.cgi?id=50731 */
+   return apr_atomic_xchgptr((volatile void **)mem, new_value);
 #else
    /* old APRs don't support atomic swaps. Simply return the
     * input to the caller for further proccessing. */

Modified: subversion/branches/svn_mutex/subversion/libsvn_subr/validate.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_subr/validate.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_subr/validate.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_subr/validate.c Tue Oct 11 19:52:34 2011
@@ -45,6 +45,7 @@ svn_mime_type_validate(const char *mime_
      specification, e.g., "text/html; charset=UTF-8", make sure we're
      only looking at the media type here. */
   const apr_size_t len = strcspn(mime_type, "; ");
+  const apr_size_t len2 = strlen(mime_type);
   const char *const slash_pos = strchr(mime_type, '/');
   apr_size_t i;
   const char *tspecials = "()<>@,;:\\\"/[]?=";
@@ -69,7 +70,19 @@ svn_mime_type_validate(const char *mime_
             || (strchr(tspecials, mime_type[i]) != NULL)))
         return svn_error_createf
           (SVN_ERR_BAD_MIME_TYPE, NULL,
-           _("MIME type '%s' contains invalid character '%c'"),
+           _("MIME type '%s' contains invalid character '%c' "
+             "in media type"),
+           mime_type, mime_type[i]);
+    }
+
+  /* Check the whole string for unsafe characters. (issue #2872) */
+  for (i = 0; i < len2; i++)
+    {
+      if (svn_ctype_iscntrl(mime_type[i]) && mime_type[i] != '\t')
+        return svn_error_createf(
+           SVN_ERR_BAD_MIME_TYPE, NULL,
+           _("MIME type '%s' contains invalid character '0x%02x' "
+             "in postfix"),
            mime_type, mime_type[i]);
     }
 

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/adm_crawler.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/adm_crawler.c Tue Oct 11 19:52:34 2011
@@ -102,7 +102,7 @@ svn_wc_restore(svn_wc_context_t *wc_ctx,
                apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   svn_node_kind_t disk_kind;
 
   SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
@@ -124,14 +124,14 @@ svn_wc_restore(svn_wc_context_t *wc_ctx,
 
   if (status == svn_wc__db_status_added)
     SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, NULL,
-                                         NULL, NULL, NULL,
-                                         wc_ctx->db, local_abspath,
-                                         scratch_pool, scratch_pool));
+                                     NULL, NULL, NULL, NULL, NULL,
+                                     wc_ctx->db, local_abspath,
+                                     scratch_pool, scratch_pool));
 
   if (status != svn_wc__db_status_normal
       && status != svn_wc__db_status_copied
       && status != svn_wc__db_status_moved_here
-      && !(kind == svn_wc__db_kind_dir
+      && !(kind == svn_kind_dir
            && (status == svn_wc__db_status_added
                || status == svn_wc__db_status_incomplete)))
     {
@@ -141,7 +141,7 @@ svn_wc_restore(svn_wc_context_t *wc_ctx,
                                                       scratch_pool));
     }
 
-  if (kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_symlink)
+  if (kind == svn_kind_file || kind == svn_kind_symlink)
     SVN_ERR(restore_file(wc_ctx->db, local_abspath, use_commit_times, FALSE,
                          scratch_pool));
   else
@@ -160,19 +160,19 @@ svn_wc_restore(svn_wc_context_t *wc_ctx,
 static svn_error_t *
 restore_node(svn_wc__db_t *db,
              const char *local_abspath,
-             svn_wc__db_kind_t kind,
+             svn_kind_t kind,
              svn_boolean_t use_commit_times,
              svn_wc_notify_func2_t notify_func,
              void *notify_baton,
              apr_pool_t *scratch_pool)
 {
-  if (kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_symlink)
+  if (kind == svn_kind_file || kind == svn_kind_symlink)
     {
       /* Recreate file from text-base */
       SVN_ERR(restore_file(db, local_abspath, use_commit_times, TRUE,
                            scratch_pool));
     }
-  else if (kind == svn_wc__db_kind_dir)
+  else if (kind == svn_kind_dir)
     {
       /* Recreating a directory is just a mkdir */
       SVN_ERR(svn_io_dir_make(local_abspath, APR_OS_DEFAULT, scratch_pool));
@@ -373,7 +373,7 @@ report_revisions_and_depths(svn_wc__db_t
           && apr_hash_get(dirents, child, APR_HASH_KEY_STRING) == NULL)
         {
           svn_wc__db_status_t wrk_status;
-          svn_wc__db_kind_t wrk_kind;
+          svn_kind_t wrk_kind;
 
           SVN_ERR(svn_wc__db_read_info(&wrk_status, &wrk_kind, NULL, NULL,
                                        NULL, NULL, NULL, NULL, NULL, NULL,
@@ -385,13 +385,13 @@ report_revisions_and_depths(svn_wc__db_t
           if (wrk_status == svn_wc__db_status_added)
             SVN_ERR(svn_wc__db_scan_addition(&wrk_status, NULL, NULL, NULL,
                                              NULL, NULL, NULL, NULL, NULL,
-                                             db, this_abspath,
+                                             NULL, NULL, db, this_abspath,
                                              iterpool, iterpool));
 
           if (wrk_status == svn_wc__db_status_normal
               || wrk_status == svn_wc__db_status_copied
               || wrk_status == svn_wc__db_status_moved_here
-              || (wrk_kind == svn_wc__db_kind_dir
+              || (wrk_kind == svn_kind_dir
                   && (wrk_status == svn_wc__db_status_added
                       || wrk_status == svn_wc__db_status_incomplete)))
             {
@@ -435,8 +435,8 @@ report_revisions_and_depths(svn_wc__db_t
         ths->depth = svn_depth_infinity;
 
       /*** Files ***/
-      if (ths->kind == svn_wc__db_kind_file ||
-               ths->kind == svn_wc__db_kind_symlink)
+      if (ths->kind == svn_kind_file ||
+               ths->kind == svn_kind_symlink)
         {
           if (report_everything)
             {
@@ -489,7 +489,7 @@ report_revisions_and_depths(svn_wc__db_t
         } /* end file case */
 
       /*** Directories (in recursive mode) ***/
-      else if (ths->kind == svn_wc__db_kind_dir
+      else if (ths->kind == svn_kind_dir
                && (depth > svn_depth_files
                    || depth == svn_depth_unknown))
         {
@@ -642,7 +642,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
   svn_revnum_t target_rev = SVN_INVALID_REVNUM;
   svn_boolean_t start_empty;
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t target_kind;
+  svn_kind_t target_kind;
   const char *repos_relpath, *repos_root_url;
   svn_depth_t target_depth;
   svn_wc__db_lock_t *target_lock;
@@ -715,7 +715,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
       && disk_kind == svn_node_none)
     {
       svn_wc__db_status_t wrk_status;
-      svn_wc__db_kind_t wrk_kind;
+      svn_kind_t wrk_kind;
       err = svn_wc__db_read_info(&wrk_status, &wrk_kind, NULL, NULL, NULL,
                                  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -729,22 +729,23 @@ svn_wc_crawl_revisions5(svn_wc_context_t
         {
           svn_error_clear(err);
           wrk_status = svn_wc__db_status_not_present;
+          wrk_kind = svn_kind_file;
         }
       else
         SVN_ERR(err);
 
       if (wrk_status == svn_wc__db_status_added)
         SVN_ERR(svn_wc__db_scan_addition(&wrk_status, NULL, NULL, NULL, NULL,
-                                         NULL, NULL, NULL, NULL,
+                                         NULL, NULL, NULL, NULL, NULL, NULL,
                                          db, local_abspath,
                                          scratch_pool, scratch_pool));
 
       if (wrk_status == svn_wc__db_status_normal
           || wrk_status == svn_wc__db_status_copied
           || wrk_status == svn_wc__db_status_moved_here
-          || (wrk_kind == svn_wc__db_kind_dir
+          || (wrk_kind == svn_kind_dir
               && (wrk_status == svn_wc__db_status_added
-                  || wrk_status == svn_wc__db_status_incomplete))) 
+                  || wrk_status == svn_wc__db_status_incomplete)))
         {
           SVN_ERR(restore_node(wc_ctx->db, local_abspath,
                                wrk_kind, use_commit_times,
@@ -767,7 +768,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
     SVN_ERR(reporter->set_path(report_baton, "", target_rev, report_depth,
                                start_empty, NULL, scratch_pool));
   }
-  if (target_kind == svn_wc__db_kind_dir)
+  if (target_kind == svn_kind_dir)
     {
       if (depth != svn_depth_empty)
         {
@@ -794,8 +795,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
         }
     }
 
-  else if (target_kind == svn_wc__db_kind_file ||
-           target_kind == svn_wc__db_kind_symlink)
+  else if (target_kind == svn_kind_file || target_kind == svn_kind_symlink)
     {
       const char *parent_abspath, *base;
       svn_wc__db_status_t parent_status;
@@ -1111,21 +1111,12 @@ svn_wc__internal_transmit_text_deltas(co
                         NULL, NULL,
                         scratch_pool, scratch_pool);
 
-  /* Close the two streams to force writing the digest,
-     if we already have an error, ignore this one. */
-  if (err)
-    {
-      svn_error_clear(svn_stream_close(base_stream));
-      svn_error_clear(svn_stream_close(local_stream));
-    }
-  else
-    {
-      SVN_ERR(svn_stream_close(base_stream));
-      SVN_ERR(svn_stream_close(local_stream));
-    }
+  /* Close the two streams to force writing the digest */
+  err = svn_error_compose_create(err, svn_stream_close(base_stream));
+  err = svn_error_compose_create(err, svn_stream_close(local_stream));
 
-  /* If we have an error, it may be caused by a corrupt text base.
-     Check the checksum and discard `err' if they don't match. */
+  /* If we have an error, it may be caused by a corrupt text base,
+     so check the checksum. */
   if (expected_md5_checksum && verify_checksum
       && !svn_checksum_match(expected_md5_checksum, verify_checksum))
     {
@@ -1141,19 +1132,20 @@ svn_wc__internal_transmit_text_deltas(co
          investigate.  Other commands could be affected,
          too, such as `svn diff'.  */
 
-      /* Deliberately ignore errors; the error about the
-         checksum mismatch is more important to return. */
-      svn_error_clear(err);
       if (tempfile)
-        svn_error_clear(svn_io_remove_file2(*tempfile, TRUE, scratch_pool));
+        err = svn_error_compose_create(
+                      err,
+                      svn_io_remove_file2(*tempfile, TRUE, scratch_pool));
 
-      return svn_error_create(SVN_ERR_WC_CORRUPT_TEXT_BASE,
-            svn_checksum_mismatch_err(expected_md5_checksum, verify_checksum,
+      err = svn_error_compose_create(
+              svn_checksum_mismatch_err(expected_md5_checksum, verify_checksum,
                             scratch_pool,
                             _("Checksum mismatch for text base of '%s'"),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool)),
-            NULL);
+              err);
+
+      return svn_error_create(SVN_ERR_WC_CORRUPT_TEXT_BASE, err, NULL);
     }
 
   /* Now, handle that delta transmission error if any, so we can stop
@@ -1214,7 +1206,7 @@ svn_wc__internal_transmit_prop_deltas(sv
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   int i;
   apr_array_header_t *propmods;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
 
   SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE, iterpool));
 
@@ -1229,7 +1221,7 @@ svn_wc__internal_transmit_prop_deltas(sv
 
       svn_pool_clear(iterpool);
 
-      if (kind == svn_wc__db_kind_file)
+      if (kind == svn_kind_file)
         SVN_ERR(editor->change_file_prop(baton, p->name, p->value,
                                          iterpool));
       else

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/adm_files.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/adm_files.c Tue Oct 11 19:52:34 2011
@@ -196,7 +196,7 @@ svn_wc__text_base_path_to_read(const cha
                                apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   const svn_checksum_t *checksum;
 
   SVN_ERR(svn_wc__db_read_pristine_info(&status, &kind, NULL, NULL, NULL, NULL,
@@ -205,7 +205,7 @@ svn_wc__text_base_path_to_read(const cha
                                         scratch_pool, scratch_pool));
 
   /* Sanity */
-  if (kind != svn_wc__db_kind_file)
+  if (kind != svn_kind_file)
     return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                              _("Can only get the pristine contents of files; "
                                "'%s' is not a file"),
@@ -249,7 +249,7 @@ svn_wc__get_pristine_contents(svn_stream
                               apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   const svn_checksum_t *sha1_checksum;
 
   if (size)
@@ -261,7 +261,7 @@ svn_wc__get_pristine_contents(svn_stream
                                         scratch_pool, scratch_pool));
 
   /* Sanity */
-  if (kind != svn_wc__db_kind_file)
+  if (kind != svn_kind_file)
     return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                              _("Can only get the pristine contents of files; "
                                "'%s' is not a file"),
@@ -484,8 +484,8 @@ svn_wc__internal_ensure_adm(svn_wc__db_t
                                              &db_repos_relpath,
                                              &db_repos_root_url,
                                              &db_repos_uuid,
-                                             NULL, NULL, NULL, NULL,
-                                             db, local_abspath,
+                                             NULL, NULL, NULL, NULL, NULL,
+                                             NULL, db, local_abspath,
                                              scratch_pool, scratch_pool));
           else
             SVN_ERR(svn_wc__db_scan_base_repos(&db_repos_relpath,



Mime
View raw message