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/11/04 21:48:30 UTC

svn commit: r1031230 [5/21] - in /subversion/branches/py-tests-as-modules: ./ build/ build/ac-macros/ build/win32/ contrib/client-side/ notes/ notes/http-and-webdav/ notes/wc-ng/ subversion/bindings/ctypes-python/csvn/ subversion/bindings/javahl/native...

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_client/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_client/relocate.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_client/relocate.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_client/relocate.c Thu Nov  4 20:48:21 2010
@@ -125,26 +125,185 @@ validator_func(void *baton,
   return SVN_NO_ERROR;
 }
 
+
+/* Callback of type svn_wc_external_update_t.  Just squirrels away an
+   svn:externals property value into BATON (which is an apr_hash_t *
+   keyed on local absolute path).  */
+static svn_error_t *
+externals_update_func(void *baton,
+                      const char *local_abspath,
+                      const svn_string_t *old_val,
+                      const svn_string_t *new_val,
+                      svn_depth_t depth,
+                      apr_pool_t *scratch_pool)
+{
+  apr_hash_t *externals_hash = baton;
+  apr_pool_t *hash_pool = apr_hash_pool_get(externals_hash);
+
+  apr_hash_set(externals_hash, apr_pstrdup(hash_pool, local_abspath),
+               APR_HASH_KEY_STRING, svn_string_dup(new_val, hash_pool));
+  return SVN_NO_ERROR;
+}
+
+
+/* Callback of type svn_wc_status_func4_t.  Does nothing. */
+static svn_error_t *
+status_noop_func(void *baton,
+                 const char *local_abspath,
+                 const svn_wc_status3_t *status,
+                 apr_pool_t *scratch_pool)
+{
+  return SVN_NO_ERROR;
+}
+
+
+/* Examing the array of svn_wc_external_item2_t's EXT_DESC (parsed
+   from the svn:externals property set on LOCAL_ABSPATH) and determine
+   if the external working copies described by such should be
+   relocated as a side-effect of the relocation of their parent
+   working copy (from OLD_PARENT_REPOS_ROOT_URL to
+   NEW_PARENT_REPOS_ROOT_URL).  If so, attempt said relocation.  */
+static svn_error_t *
+relocate_externals(const char *local_abspath,
+                   apr_array_header_t *ext_desc,
+                   const char *old_parent_repos_root_url,
+                   const char *new_parent_repos_root_url,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *scratch_pool)
+{
+  const char *url;
+  apr_pool_t *iterpool;
+  int i;
+
+  SVN_ERR(svn_client_url_from_path2(&url, local_abspath, ctx,
+                                    scratch_pool, scratch_pool));
+
+  /* Parse an externals definition into an array of external items. */
+
+  iterpool = svn_pool_create(scratch_pool);
+
+  for (i = 0; i < ext_desc->nelts; i++)
+    {
+      svn_wc_external_item2_t *ext_item =
+        APR_ARRAY_IDX(ext_desc, i, svn_wc_external_item2_t *);
+      const char *target_repos_root_url;
+      const char *target_abspath;
+      
+      svn_pool_clear(iterpool);
+
+      /* If this external isn't pulled in via a relative URL, ignore
+         it.  There's no sense in relocating a working copy only to
+         have the next 'svn update' try to point it back to another
+         location. */
+      if (! ((strncmp("../", ext_item->url, 3) == 0) ||
+             (strncmp("^/", ext_item->url, 2) == 0)))
+        continue;
+
+      /* If the external working copy's not-yet-relocated repos root
+         URL matches the primary working copy's pre-relocated
+         repository root URL, try to relocate that external, too.
+         You might wonder why this check is needed, given that we're
+         already limiting ourselves to externals pulled via URLs
+         relative to their primary working copy.  Well, it's because
+         you can use "../" to "crawl up" above one repository's URL
+         space and down into another one.  */
+      SVN_ERR(svn_dirent_get_absolute(&target_abspath,
+                                      svn_dirent_join(local_abspath,
+                                                      ext_item->target_dir,
+                                                      iterpool),
+                                      iterpool));
+      SVN_ERR(svn_client_root_url_from_path(&target_repos_root_url,
+                                            target_abspath, ctx, iterpool));
+
+      if (strcmp(target_repos_root_url, old_parent_repos_root_url) == 0)
+        SVN_ERR(svn_client_relocate2(target_abspath,
+                                     old_parent_repos_root_url,
+                                     new_parent_repos_root_url,
+                                     TRUE, ctx, iterpool));
+    }
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
-svn_client_relocate(const char *path,
-                    const char *from,
-                    const char *to,
-                    svn_boolean_t recurse,
-                    svn_client_ctx_t *ctx,
-                    apr_pool_t *pool)
+svn_client_relocate2(const char *wcroot_dir,
+                     const char *from_prefix,
+                     const char *to_prefix,
+                     svn_boolean_t ignore_externals,
+                     svn_client_ctx_t *ctx,
+                     apr_pool_t *pool)
 {
   struct validator_baton_t vb;
   const char *local_abspath;
+  apr_hash_t *externals_hash = NULL;
+  apr_hash_index_t *hi;
+  apr_pool_t *iterpool = NULL;
+  const char *old_repos_root_url, *new_repos_root_url;
 
-  /* Now, populate our validator callback baton, and call the relocate code. */
+  /* Populate our validator callback baton, and call the relocate code. */
   vb.ctx = ctx;
-  vb.path = path;
+  vb.path = wcroot_dir;
   vb.url_uuids = apr_array_make(pool, 1, sizeof(struct url_uuid_t));
   vb.pool = pool;
 
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-  SVN_ERR(svn_wc_relocate4(ctx->wc_ctx, local_abspath, from, to, recurse,
+  SVN_ERR(svn_dirent_get_absolute(&local_abspath, wcroot_dir, pool));
+
+  /* If we're ignoring externals, just relocate and get outta here. */
+  if (ignore_externals)
+    {
+      return svn_error_return(svn_wc_relocate4(ctx->wc_ctx, local_abspath,
+                                               from_prefix, to_prefix,
+                                               validator_func, &vb, pool));
+    }
+
+  /* Fetch our current root URL. */
+  SVN_ERR(svn_client_root_url_from_path(&old_repos_root_url, local_abspath,
+                                        ctx, pool));
+
+  /* Perform the relocation. */
+  SVN_ERR(svn_wc_relocate4(ctx->wc_ctx, local_abspath, from_prefix, to_prefix,
                            validator_func, &vb, pool));
 
+  /* Now fetch new current root URL. */
+  SVN_ERR(svn_client_root_url_from_path(&new_repos_root_url, local_abspath,
+                                        ctx, pool));
+
+  externals_hash = apr_hash_make(pool);
+
+  /* Do a status run just to harvest externals definitions. */
+  SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, local_abspath,
+                             svn_depth_infinity, FALSE, FALSE, NULL,
+                             status_noop_func, NULL,
+                             externals_update_func, externals_hash,
+                             ctx->cancel_func, ctx->cancel_baton, pool));
+
+  /* No externals?  No problem.  We're done here. */
+  if (! apr_hash_count(externals_hash))
+    return SVN_NO_ERROR;
+
+  iterpool = svn_pool_create(pool);
+
+  for (hi = apr_hash_first(pool, externals_hash);
+       hi != NULL;
+       hi = apr_hash_next(hi))
+    {
+      const char *this_abspath = svn__apr_hash_index_key(hi);
+      const svn_string_t *pval = svn__apr_hash_index_val(hi);
+      apr_array_header_t *ext_desc;
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_wc_parse_externals_description3(&ext_desc, this_abspath,
+                                                  pval->data, FALSE,
+                                                  iterpool));
+      if (ext_desc->nelts)
+        SVN_ERR(relocate_externals(this_abspath, ext_desc, old_repos_root_url,
+                                   new_repos_root_url, ctx, iterpool));
+    }
+    
+  svn_pool_destroy(iterpool);
+
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_client/repos_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_client/repos_diff.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_client/repos_diff.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_client/repos_diff.c Thu Nov  4 20:48:21 2010
@@ -521,7 +521,7 @@ diff_deleted_dir(const char *dir,
                                 mimetype1, mimetype2,
                                 b->pristine_props,
                                 b->edit_baton->diff_cmd_baton,
-                                pool));
+                                iterpool));
         }
  
       if (dirent->kind == svn_node_dir)
@@ -1244,7 +1244,7 @@ absent_directory(const char *path,
       svn_wc_notify_t *notify
         = svn_wc_create_notify(svn_dirent_join(pb->wcpath,
                                                svn_relpath_basename(path,
-                                                                    pool),
+                                                                    NULL),
                                                pool),
                                svn_wc_notify_skip, pool);
       notify->kind = svn_node_dir;

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_client/repos_diff_summarize.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_client/repos_diff_summarize.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_client/repos_diff_summarize.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_client/repos_diff_summarize.c Thu Nov  4 20:48:21 2010
@@ -196,7 +196,7 @@ diff_deleted_dir(const char *dir,
                                 &kind,
                                 iterpool));
 
-      sum = apr_pcalloc(pool, sizeof(*sum));
+      sum = apr_pcalloc(iterpool, sizeof(*sum));
       sum->summarize_kind = svn_client_diff_summarize_kind_deleted;
       sum->path = path;
       sum->node_kind = kind;

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_client/resolved.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_client/resolved.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_client/resolved.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_client/resolved.c Thu Nov  4 20:48:21 2010
@@ -36,6 +36,7 @@
 #include "client.h"
 #include "private/svn_wc_private.h"
 
+#include "svn_private_config.h"
 
 /*** Code. ***/
 
@@ -48,6 +49,11 @@ svn_client_resolve(const char *path,
 {
   const char *local_abspath;
 
+  if (svn_path_is_url(path))
+    return svn_error_return(svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                                              _("'%s' is not a local path"),
+                                              path));
+
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
 
   SVN_ERR(svn_wc_resolved_conflict5(ctx->wc_ctx, local_abspath,

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_client/revert.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_client/revert.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_client/revert.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_client/revert.c Thu Nov  4 20:48:21 2010
@@ -27,6 +27,7 @@
 
 /*** Includes. ***/
 
+#include "svn_path.h"
 #include "svn_wc.h"
 #include "svn_client.h"
 #include "svn_dirent_uri.h"
@@ -37,6 +38,7 @@
 #include "client.h"
 #include "private/svn_wc_private.h"
 
+#include "svn_private_config.h"
 
 
 /*** Code. ***/
@@ -121,6 +123,19 @@ svn_client_revert2(const apr_array_heade
   svn_boolean_t use_commit_times;
   struct revert_with_write_lock_baton baton;
 
+  /* Don't even attempt to modify the working copy if any of the
+   * targets look like URLs. URLs are invalid input. */
+  for (i = 0; i < paths->nelts; i++)
+    {
+      const char *path = APR_ARRAY_IDX(paths, i, const char *);
+
+      if (svn_path_is_url(path))
+        return svn_error_return(svn_error_createf(SVN_ERR_ILLEGAL_TARGET,
+                                                  NULL,
+                                                  _("'%s' is not a local path"),
+                                                  path));
+    }
+  
   cfg = ctx->config ? apr_hash_get(ctx->config, SVN_CONFIG_CATEGORY_CONFIG,
                                    APR_HASH_KEY_STRING) : NULL;
 

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_client/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_client/status.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_client/status.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_client/status.c Thu Nov  4 20:48:21 2010
@@ -32,6 +32,7 @@
 #include "svn_pools.h"
 #include "client.h"
 
+#include "svn_path.h"
 #include "svn_dirent_uri.h"
 #include "svn_delta.h"
 #include "svn_client.h"
@@ -268,6 +269,11 @@ svn_client_status5(svn_revnum_t *result_
   apr_hash_t *changelist_hash = NULL;
   struct svn_cl__externals_store externals_store = { NULL };
 
+  if (svn_path_is_url(path))
+    return svn_error_return(svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                                              _("'%s' is not a local path"),
+                                              path));
+
   if (changelists && changelists->nelts)
     SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool));
 

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_client/switch.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_client/switch.c Thu Nov  4 20:48:21 2010
@@ -190,7 +190,6 @@ switch_internal(svn_revnum_t *result_rev
                                     depth,
                                     depth_is_sticky, allow_unver_obstructions,
                                     diff3_cmd, preserved_exts,
-                                    NULL, NULL,
                                     ctx->conflict_func, ctx->conflict_baton,
                                     svn_client__external_info_gatherer, &efb,
                                     ctx->cancel_func, ctx->cancel_baton,

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_client/update.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_client/update.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_client/update.c Thu Nov  4 20:48:21 2010
@@ -45,49 +45,6 @@
 /*** Code. ***/
 
 
-/* Context baton for file_fetcher below. */
-struct ff_baton
-{
-  svn_client_ctx_t *ctx;       /* client context used to open ra session */
-  const char *repos_root;      /* repository root URL */
-  svn_ra_session_t *session;   /* the secondary ra session itself */
-  apr_pool_t *pool;            /* the pool where the ra session is allocated */
-};
-
-
-/* Implementation of svn_wc_get_file_t.  A feeble callback wrapper
-   around svn_ra_get_file(), so that the update_editor can use it to
-   fetch any file, any time. */
-static svn_error_t *
-file_fetcher(void *baton,
-             const char *path,
-             svn_revnum_t revision,
-             svn_stream_t *stream,
-             svn_revnum_t *fetched_rev,
-             apr_hash_t **props,
-             apr_pool_t *pool)
-{
-  struct ff_baton *ffb = (struct ff_baton *)baton;
-  const char *dirpath, *base_name, *session_url, *old_session_url;
-
-  svn_relpath_split(&dirpath, &base_name, path, pool);
-  session_url = svn_path_url_add_component2(ffb->repos_root, 
-                                            dirpath, pool);
-
-  if (ffb->session)
-    SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url, ffb->session,
-                                              session_url, ffb->pool));
-  else
-    SVN_ERR(svn_client__open_ra_session_internal(&(ffb->session), NULL,
-                                                 session_url, NULL, NULL,
-                                                 FALSE, TRUE,
-                                                 ffb->ctx, ffb->pool));
-
-  return svn_ra_get_file(ffb->session, base_name, revision, stream,
-                         fetched_rev, props, pool);
-}
-
-
 static svn_error_t *
 update_internal(svn_revnum_t *result_rev,
                 const char *local_abspath,
@@ -98,7 +55,6 @@ update_internal(svn_revnum_t *result_rev
                 svn_boolean_t ignore_externals,
                 svn_boolean_t allow_unver_obstructions,
                 svn_boolean_t *timestamp_sleep,
-                svn_boolean_t send_copyfrom_args,
                 svn_boolean_t innerupdate,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *pool)
@@ -120,7 +76,6 @@ update_internal(svn_revnum_t *result_rev
   svn_ra_session_t *ra_session;
   const char *preserved_exts_str;
   apr_array_header_t *preserved_exts;
-  struct ff_baton *ffb;
   svn_client__external_func_baton_t efb;
   svn_boolean_t server_supports_depth;
   svn_config_t *cfg = ctx->config ? apr_hash_get(ctx->config,
@@ -216,12 +171,6 @@ update_internal(svn_revnum_t *result_rev
      a strict sense, however.) */
   SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));
 
-  /* Build a baton for the file-fetching callback. */
-  ffb = apr_pcalloc(pool, sizeof(*ffb));
-  ffb->ctx = ctx;
-  ffb->repos_root = repos_root;
-  ffb->pool = pool;
-
   /* Build a baton for the externals-info-gatherer callback. */
   efb.externals_new = apr_hash_make(pool);
   efb.externals_old = apr_hash_make(pool);
@@ -235,7 +184,6 @@ update_internal(svn_revnum_t *result_rev
                                     target, use_commit_times, depth,
                                     depth_is_sticky, allow_unver_obstructions,
                                     diff3_cmd, preserved_exts,
-                                    file_fetcher, ffb,
                                     ctx->conflict_func, ctx->conflict_baton,
                                     svn_client__external_info_gatherer, &efb,
                                     ctx->cancel_func, ctx->cancel_baton,
@@ -244,12 +192,8 @@ update_internal(svn_revnum_t *result_rev
 
   /* Tell RA to do an update of URL+TARGET to REVISION; if we pass an
      invalid revnum, that means RA will use the latest revision.  */
-  SVN_ERR(svn_ra_do_update2(ra_session,
-                            &reporter, &report_baton,
-                            revnum,
-                            target,
-                            depth,
-                            send_copyfrom_args,
+  SVN_ERR(svn_ra_do_update2(ra_session, &reporter, &report_baton,
+                            revnum, target, depth, FALSE,
                             update_editor, update_edit_baton, pool));
 
   SVN_ERR(svn_ra_has_capability(ra_session, &server_supports_depth,
@@ -321,7 +265,6 @@ svn_client__update_internal(svn_revnum_t
                             svn_boolean_t ignore_externals,
                             svn_boolean_t allow_unver_obstructions,
                             svn_boolean_t *timestamp_sleep,
-                            svn_boolean_t send_copyfrom_args,
                             svn_boolean_t innerupdate,
                             svn_client_ctx_t *ctx,
                             apr_pool_t *pool)
@@ -343,8 +286,7 @@ svn_client__update_internal(svn_revnum_t
   err = update_internal(result_rev, local_abspath, anchor_abspath,
                          revision, depth, depth_is_sticky,
                          ignore_externals, allow_unver_obstructions,
-                         timestamp_sleep, send_copyfrom_args,
-                         innerupdate, ctx, pool);
+                         timestamp_sleep, innerupdate, ctx, pool);
 
   err = svn_error_compose_create(
             err,
@@ -398,7 +340,7 @@ svn_client_update3(apr_array_header_t **
                                             revision, depth, depth_is_sticky,
                                             ignore_externals,
                                             allow_unver_obstructions,
-                                            &sleep, TRUE, FALSE, ctx, subpool);
+                                            &sleep, FALSE, ctx, subpool);
 
           if (err && err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
             {

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_client/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_client/util.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_client/util.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_client/util.c Thu Nov  4 20:48:21 2010
@@ -218,7 +218,9 @@ svn_client__path_relative_to_root(const 
         }
       rel_url = svn_path_uri_decode(rel_url, result_pool);
       *rel_path = include_leading_slash
-                    ? apr_pstrcat(result_pool, "/", rel_url, NULL) : rel_url;
+                    ? apr_pstrcat(result_pool, "/", rel_url,
+                                  (char *)NULL)
+                    : rel_url;
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_delta/svndiff.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_delta/svndiff.c Thu Nov  4 20:48:21 2010
@@ -352,10 +352,13 @@ struct decode_baton
 };
 
 
-/* Decode an svndiff-encoded integer into VAL and return a pointer to
+/* Decode an svndiff-encoded integer into *VAL and return a pointer to
    the byte after the integer.  The bytes to be decoded live in the
-   range [P..END-1].  See the comment for encode_int earlier in this
-   file for more detail on the encoding format.  */
+   range [P..END-1].  If these bytes do not contain a whole encoded
+   integer, return NULL; in this case *VAL is undefined.
+
+   See the comment for encode_int() earlier in this file for more detail on
+   the encoding format.  */
 static const unsigned char *
 decode_file_offset(svn_filesize_t *val,
                    const unsigned char *p,
@@ -381,7 +384,6 @@ decode_file_offset(svn_filesize_t *val,
       }
     }
 
-  *val = temp;
   return NULL;
 }
 
@@ -409,7 +411,6 @@ decode_size(apr_size_t *val,
       }
     }
 
-  *val = temp;
   return NULL;
 }
 

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_diff/diff_file.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_diff/diff_file.c Thu Nov  4 20:48:21 2010
@@ -67,21 +67,26 @@ typedef struct svn_diff__file_token_t
 typedef struct svn_diff__file_baton_t
 {
   const svn_diff_file_options_t *options;
-  const char *path[4];
 
-  apr_file_t *file[4];
-  apr_off_t size[4];
+  struct file_info {
+    const char *path;  /* path to this file, absolute or relative to CWD */
 
-  int chunk[4];
-  char *buffer[4];
-  char *curp[4];
-  char *endp[4];
+    /* All the following fields are active while this datasource is open */
+    apr_file_t *file;  /* handle of this file */
+    apr_off_t size;    /* total raw size in bytes of this file */
+
+    /* The current chunk: CHUNK_SIZE bytes except for the last chunk. */
+    int chunk;     /* the current chunk number, zero-based */
+    char *buffer;  /* a buffer containing the current chunk */
+    char *curp;    /* current position in the current chunk */
+    char *endp;    /* next memory address after the current chunk */
+
+    svn_diff__normalize_state_t normalize_state;
+  } files[4];
 
   /* List of free tokens that may be reused. */
   svn_diff__file_token_t *tokens;
 
-  svn_diff__normalize_state_t normalize_state[4];
-
   apr_pool_t *pool;
 } svn_diff__file_baton_t;
 
@@ -198,26 +203,30 @@ map_or_read_file(apr_file_t **file,
 }
 
 
-/* Implements svn_diff_fns_t::datasource_open */
+/* Let FILE stand for the file_info struct element of BATON->files that is
+ * indexed by DATASOURCE.  BATON's type is (svn_diff__file_baton_t *).
+ *
+ * Open the file at FILE.path; initialize FILE.file, FILE.size, FILE.buffer,
+ * FILE.curp and FILE.endp; allocate a buffer and read the first chunk.
+ *
+ * Implements svn_diff_fns_t::datasource_open. */
 static svn_error_t *
 datasource_open(void *baton, svn_diff_datasource_e datasource)
 {
   svn_diff__file_baton_t *file_baton = baton;
-  int idx;
+  struct file_info *file = &file_baton->files[datasource_to_index(datasource)];
   apr_finfo_t finfo;
   apr_off_t length;
   char *curp;
   char *endp;
 
-  idx = datasource_to_index(datasource);
-
-  SVN_ERR(svn_io_file_open(&file_baton->file[idx], file_baton->path[idx],
+  SVN_ERR(svn_io_file_open(&file->file, file->path,
                            APR_READ, APR_OS_DEFAULT, file_baton->pool));
 
   SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_SIZE,
-                               file_baton->file[idx], file_baton->pool));
+                               file->file, file_baton->pool));
 
-  file_baton->size[idx] = finfo.size;
+  file->size = finfo.size;
   length = finfo.size > CHUNK_SIZE ? CHUNK_SIZE : finfo.size;
 
   if (length == 0)
@@ -226,10 +235,10 @@ datasource_open(void *baton, svn_diff_da
   endp = curp = apr_palloc(file_baton->pool, (apr_size_t) length);
   endp += length;
 
-  file_baton->buffer[idx] = file_baton->curp[idx] = curp;
-  file_baton->endp[idx] = endp;
+  file->buffer = file->curp = curp;
+  file->endp = endp;
 
-  return read_chunk(file_baton->file[idx], file_baton->path[idx],
+  return read_chunk(file->file, file->path,
                     curp, length, 0, file_baton->pool);
 }
 
@@ -252,7 +261,7 @@ datasource_get_next_token(apr_uint32_t *
 {
   svn_diff__file_baton_t *file_baton = baton;
   svn_diff__file_token_t *file_token;
-  int idx;
+  struct file_info *file = &file_baton->files[datasource_to_index(datasource)];
   char *endp;
   char *curp;
   char *eol;
@@ -264,15 +273,13 @@ datasource_get_next_token(apr_uint32_t *
 
   *token = NULL;
 
-  idx = datasource_to_index(datasource);
+  curp = file->curp;
+  endp = file->endp;
 
-  curp = file_baton->curp[idx];
-  endp = file_baton->endp[idx];
-
-  last_chunk = offset_to_chunk(file_baton->size[idx]);
+  last_chunk = offset_to_chunk(file->size);
 
   if (curp == endp
-      && last_chunk == file_baton->chunk[idx])
+      && last_chunk == file->chunk)
     {
       return SVN_NO_ERROR;
     }
@@ -289,8 +296,8 @@ datasource_get_next_token(apr_uint32_t *
     }
 
   file_token->datasource = datasource;
-  file_token->offset = chunk_to_offset(file_baton->chunk[idx])
-                       + (curp - file_baton->buffer[idx]);
+  file_token->offset = chunk_to_offset(file->chunk)
+                       + (curp - file->buffer);
   file_token->raw_length = 0;
   file_token->length = 0;
 
@@ -311,7 +318,7 @@ datasource_get_next_token(apr_uint32_t *
             }
         }
 
-      if (file_baton->chunk[idx] == last_chunk)
+      if (file->chunk == last_chunk)
         {
           eol = endp;
           break;
@@ -320,21 +327,21 @@ datasource_get_next_token(apr_uint32_t *
       length = endp - curp;
       file_token->raw_length += length;
       svn_diff__normalize_buffer(&curp, &length,
-                                 &file_baton->normalize_state[idx],
+                                 &file->normalize_state,
                                  curp, file_baton->options);
       file_token->length += length;
       h = svn_diff__adler32(h, curp, length);
 
-      curp = endp = file_baton->buffer[idx];
-      file_baton->chunk[idx]++;
-      length = file_baton->chunk[idx] == last_chunk ?
-        offset_in_chunk(file_baton->size[idx]) : CHUNK_SIZE;
+      curp = endp = file->buffer;
+      file->chunk++;
+      length = file->chunk == last_chunk ?
+        offset_in_chunk(file->size) : CHUNK_SIZE;
       endp += length;
-      file_baton->endp[idx] = endp;
+      file->endp = endp;
 
-      SVN_ERR(read_chunk(file_baton->file[idx], file_baton->path[idx],
+      SVN_ERR(read_chunk(file->file, file->path,
                          curp, length,
-                         chunk_to_offset(file_baton->chunk[idx]),
+                         chunk_to_offset(file->chunk),
                          file_baton->pool));
 
       /* If the last chunk ended in a CR, we're done. */
@@ -349,7 +356,7 @@ datasource_get_next_token(apr_uint32_t *
 
   length = eol - curp;
   file_token->raw_length += length;
-  file_baton->curp[idx] = eol;
+  file->curp = eol;
 
   /* If the file length is exactly a multiple of CHUNK_SIZE, we will end up
    * with a spurious empty token.  Avoid returning it.
@@ -360,7 +367,7 @@ datasource_get_next_token(apr_uint32_t *
     {
       char *c = curp;
       svn_diff__normalize_buffer(&c, &length,
-                                 &file_baton->normalize_state[idx],
+                                 &file->normalize_state,
                                  curp, file_baton->options);
 
       file_token->norm_offset = file_token->offset;
@@ -388,13 +395,12 @@ token_compare(void *baton, void *token1,
   char buffer[2][COMPARE_CHUNK_SIZE];
   char *bufp[2];
   apr_off_t offset[2];
-  int idx[2];
+  struct file_info *file[2];
   apr_off_t length[2];
   apr_off_t total_length;
   /* How much is left to read of each token from the file. */
   apr_off_t raw_length[2];
   int i;
-  int chunk[2];
   svn_diff__normalize_state_t state[2];
 
   file_token[0] = token1;
@@ -420,17 +426,18 @@ token_compare(void *baton, void *token1,
 
   for (i = 0; i < 2; ++i)
     {
-      idx[i] = datasource_to_index(file_token[i]->datasource);
+      int idx = datasource_to_index(file_token[i]->datasource);
+
+      file[i] = &file_baton->files[idx];
       offset[i] = file_token[i]->norm_offset;
-      chunk[i] = file_baton->chunk[idx[i]];
       state[i] = svn_diff__normalize_state_normal;
 
-      if (offset_to_chunk(offset[i]) == chunk[i])
+      if (offset_to_chunk(offset[i]) == file[i]->chunk)
         {
           /* If the start of the token is in memory, the entire token is
            * in memory.
            */
-          bufp[i] = file_baton->buffer[idx[i]];
+          bufp[i] = file[i]->buffer;
           bufp[i] += offset_in_chunk(offset[i]);
 
           length[i] = total_length;
@@ -458,15 +465,15 @@ token_compare(void *baton, void *token1,
                                          NULL,
                                          _("The file '%s' changed unexpectedly"
                                            " during diff"),
-                                         file_baton->path[idx[i]]);
+                                         file[i]->path);
 
               /* Read a chunk from disk into a buffer */
               bufp[i] = buffer[i];
               length[i] = raw_length[i] > COMPARE_CHUNK_SIZE ?
                 COMPARE_CHUNK_SIZE : raw_length[i];
 
-              SVN_ERR(read_chunk(file_baton->file[idx[i]],
-                                 file_baton->path[idx[i]],
+              SVN_ERR(read_chunk(file[i]->file,
+                                 file[i]->path,
                                  bufp[i], length[i], offset[i],
                                  file_baton->pool));
               offset[i] += length[i];
@@ -623,8 +630,8 @@ svn_diff_file_diff_2(svn_diff_t **diff,
 
   memset(&baton, 0, sizeof(baton));
   baton.options = options;
-  baton.path[0] = original;
-  baton.path[1] = modified;
+  baton.files[0].path = original;
+  baton.files[1].path = modified;
   baton.pool = svn_pool_create(pool);
 
   SVN_ERR(svn_diff_diff(diff, &baton, &svn_diff__file_vtable, pool));
@@ -645,9 +652,9 @@ svn_diff_file_diff3_2(svn_diff_t **diff,
 
   memset(&baton, 0, sizeof(baton));
   baton.options = options;
-  baton.path[0] = original;
-  baton.path[1] = modified;
-  baton.path[2] = latest;
+  baton.files[0].path = original;
+  baton.files[1].path = modified;
+  baton.files[2].path = latest;
   baton.pool = svn_pool_create(pool);
 
   SVN_ERR(svn_diff_diff3(diff, &baton, &svn_diff__file_vtable, pool));
@@ -669,10 +676,10 @@ svn_diff_file_diff4_2(svn_diff_t **diff,
 
   memset(&baton, 0, sizeof(baton));
   baton.options = options;
-  baton.path[0] = original;
-  baton.path[1] = modified;
-  baton.path[2] = latest;
-  baton.path[3] = ancestor;
+  baton.files[0].path = original;
+  baton.files[1].path = modified;
+  baton.files[2].path = latest;
+  baton.files[3].path = ancestor;
   baton.pool = svn_pool_create(pool);
 
   SVN_ERR(svn_diff_diff4(diff, &baton, &svn_diff__file_vtable, pool));
@@ -1130,11 +1137,11 @@ svn_diff_file_output_unified3(svn_stream
                               apr_pool_t *pool)
 {
   svn_diff__file_output_baton_t baton;
-  int i;
 
   if (svn_diff_contains_diffs(diff))
     {
       const char **c;
+      int i;
 
       memset(&baton, 0, sizeof(baton));
       baton.output_stream = output_stream;
@@ -1161,42 +1168,44 @@ svn_diff_file_output_unified3(svn_stream
       SVN_ERR(svn_utf_cstring_from_utf8_ex2(&baton.insert_str, "+",
                                             header_encoding, pool));
 
-  if (relative_to_dir)
-    {
-      /* Possibly adjust the "original" and "modified" paths shown in
-         the output (see issue #2723). */
-      const char *child_path;
-
-      if (! original_header)
-        {
-          child_path = svn_dirent_is_child(relative_to_dir,
-                                           original_path, pool);
-          if (child_path)
-            original_path = child_path;
-          else
-            return svn_error_createf(
-                               SVN_ERR_BAD_RELATIVE_PATH, NULL,
-                               _("Path '%s' must be an immediate child of "
-                                 "the directory '%s'"),
-                               svn_dirent_local_style(original_path, pool),
-                               svn_dirent_local_style(relative_to_dir, pool));
-        }
-
-      if (! modified_header)
-        {
-          child_path = svn_dirent_is_child(relative_to_dir,
-                                           modified_path, pool);
-          if (child_path)
-            modified_path = child_path;
-          else
-            return svn_error_createf(
-                               SVN_ERR_BAD_RELATIVE_PATH, NULL,
-                               _("Path '%s' must be an immediate child of "
-                                 "the directory '%s'"),
-                               svn_dirent_local_style(modified_path, pool),
-                               svn_dirent_local_style(relative_to_dir, pool));
+      if (relative_to_dir)
+        {
+          /* Possibly adjust the "original" and "modified" paths shown in
+             the output (see issue #2723). */
+          const char *child_path;
+
+          if (! original_header)
+            {
+              child_path = svn_dirent_is_child(relative_to_dir,
+                                               original_path, pool);
+              if (child_path)
+                original_path = child_path;
+              else
+                return svn_error_createf(
+                                   SVN_ERR_BAD_RELATIVE_PATH, NULL,
+                                   _("Path '%s' must be an immediate child of "
+                                     "the directory '%s'"),
+                                   svn_dirent_local_style(original_path, pool),
+                                   svn_dirent_local_style(relative_to_dir,
+                                                          pool));
+            }
+
+          if (! modified_header)
+            {
+              child_path = svn_dirent_is_child(relative_to_dir,
+                                               modified_path, pool);
+              if (child_path)
+                modified_path = child_path;
+              else
+                return svn_error_createf(
+                                   SVN_ERR_BAD_RELATIVE_PATH, NULL,
+                                   _("Path '%s' must be an immediate child of "
+                                     "the directory '%s'"),
+                                   svn_dirent_local_style(modified_path, pool),
+                                   svn_dirent_local_style(relative_to_dir,
+                                                          pool));
+            }
         }
-    }
 
       for (i = 0; i < 2; i++)
         {

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_diff/parse-diff.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_diff/parse-diff.c Thu Nov  4 20:48:21 2010
@@ -28,6 +28,7 @@
 #include "svn_error.h"
 #include "svn_io.h"
 #include "svn_pools.h"
+#include "svn_props.h"
 #include "svn_string.h"
 #include "svn_utf.h"
 #include "svn_dirent_uri.h"
@@ -150,7 +151,7 @@ parse_range(svn_linenum_t *start, svn_li
 {
   char *comma;
 
-  if (strlen(range) == 0)
+  if (*range == 0)
     return FALSE;
 
   comma = strstr(range, ",");
@@ -183,13 +184,13 @@ parse_range(svn_linenum_t *start, svn_li
 /* Try to parse a hunk header in string HEADER, putting parsed information
  * into HUNK. Return TRUE if the header parsed correctly. ATAT is the
  * character string used to delimit the hunk header.
- * If REVERSE is TRUE, invert the hunk header while parsing it.
  * Do all allocations in POOL. */
 static svn_boolean_t
 parse_hunk_header(const char *header, svn_diff_hunk_t *hunk,
                   const char *atat, apr_pool_t *pool)
 {
   const char *p;
+  const char *start;
   svn_stringbuf_t *range;
 
   p = header + strlen(atat);
@@ -202,16 +203,18 @@ parse_hunk_header(const char *header, sv
     return FALSE;
   /* OK, this may be worth allocating some memory for... */
   range = svn_stringbuf_create_ensure(31, pool);
-  p++;
+  start = ++p;
   while (*p && *p != ' ')
     {
-      svn_stringbuf_appendbyte(range, *p);
       p++;
     }
+
   if (*p != ' ')
     /* No no no... */
     return FALSE;
 
+  svn_stringbuf_appendbytes(range, start, p - start);
+
   /* Try to parse the first range. */
   if (! parse_range(&hunk->original_start, &hunk->original_length, range->data))
     return FALSE;
@@ -223,16 +226,17 @@ parse_hunk_header(const char *header, sv
     /* Eeek! */
     return FALSE;
   /* OK, this may be worth copying... */
-  p++;
+  start = ++p;
   while (*p && *p != ' ')
     {
-      svn_stringbuf_appendbyte(range, *p);
       p++;
     }
   if (*p != ' ')
     /* No no no... */
     return FALSE;
 
+  svn_stringbuf_appendbytes(range, start, p - start);
+
   /* Check for trailing @@ */
   p++;
   if (! starts_with(p, atat))
@@ -478,19 +482,24 @@ svn_diff_hunk_readline_diff_text(const s
   return SVN_NO_ERROR;
 }
 
-/* Parse PROP_NAME from HEADER as the part after the INDICATOR line. */
+/* Parse *PROP_NAME from HEADER as the part after the INDICATOR line.
+ * Allocate *PROP_NAME in RESULT_POOL.
+ * Set *PROP_NAME to NULL if no valid property name was found. */
 static svn_error_t *
 parse_prop_name(const char **prop_name, const char *header, 
                 const char *indicator, apr_pool_t *result_pool)
 {
-  /* ### This can fail if the filename cannot be represented in the current
-   * ### locale's encoding. */
   SVN_ERR(svn_utf_cstring_to_utf8(prop_name,
                                   header + strlen(indicator),
                                   result_pool));
-
-  /* ### Are we guarenteed that there are no trailing or leading
-   * ### whitespaces in the name? */
+  if (**prop_name == '\0')
+    *prop_name = NULL;
+  else if (! svn_prop_name_is_valid(*prop_name))
+    {
+      svn_stringbuf_t *buf = svn_stringbuf_create(*prop_name, result_pool);
+      svn_stringbuf_strip_whitespace(buf);
+      *prop_name = (svn_prop_name_is_valid(buf->data) ? buf->data : NULL);
+    }
 
   return SVN_NO_ERROR;
 }
@@ -675,20 +684,23 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
           else if (starts_with(line->data, "Added: "))
             {
               SVN_ERR(parse_prop_name(prop_name, line->data, "Added: ",
-                                      result_pool));
-              *prop_operation = svn_diff_op_added;
+                                      result_pool));  
+              if (*prop_name)
+                *prop_operation = svn_diff_op_added;
             }
           else if (starts_with(line->data, "Deleted: "))
             {
               SVN_ERR(parse_prop_name(prop_name, line->data, "Deleted: ",
                                       result_pool));
-              *prop_operation = svn_diff_op_deleted;
+              if (*prop_name)
+                *prop_operation = svn_diff_op_deleted;
             }
           else if (starts_with(line->data, "Modified: "))
             {
               SVN_ERR(parse_prop_name(prop_name, line->data, "Modified: ",
                                       result_pool));
-              *prop_operation = svn_diff_op_modified;
+              if (*prop_name)
+                *prop_operation = svn_diff_op_modified;
             }
           else if (starts_with(line->data, minus)
                    || starts_with(line->data, "diff --git "))
@@ -753,8 +765,8 @@ parse_next_hunk(svn_diff_hunk_t **hunk,
 static int
 compare_hunks(const void *a, const void *b)
 {
-  const svn_diff_hunk_t *ha = *((const svn_diff_hunk_t **)a);
-  const svn_diff_hunk_t *hb = *((const svn_diff_hunk_t **)b);
+  const svn_diff_hunk_t *ha = *((const svn_diff_hunk_t *const *)a);
+  const svn_diff_hunk_t *hb = *((const svn_diff_hunk_t *const *)b);
 
   if (ha->original_start < hb->original_start)
     return -1;
@@ -1263,6 +1275,8 @@ svn_diff_parse_next_patch(svn_patch_t **
       const char *prop_name;
       svn_diff_operation_kind_t prop_operation;
 
+      last_prop_name = NULL;
+
       /* Parse hunks. */
       (*patch)->hunks = apr_array_make(result_pool, 10,
                                        sizeof(svn_diff_hunk_t *));

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_fs/access.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_fs/access.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_fs/access.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_fs/access.c Thu Nov  4 20:48:21 2010
@@ -87,7 +87,7 @@ svn_fs_access_add_lock_token2(svn_fs_acc
                               const char *token)
 {
   apr_hash_set(access_ctx->lock_tokens,
-               token, APR_HASH_KEY_STRING, (void *) path);
+               token, APR_HASH_KEY_STRING, path);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/bdb/locks-table.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/bdb/locks-table.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/bdb/locks-table.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/bdb/locks-table.c Thu Nov  4 20:48:21 2010
@@ -250,7 +250,7 @@ svn_fs_bdb__locks_get(svn_fs_t *fs,
   /* As long as the prefix of the returned KEY matches LOOKUP_PATH we
      know it is either LOOKUP_PATH or a decendant thereof.  */
   if (strcmp(path, "/") != 0)
-    lookup_path = apr_pstrcat(pool, path, "/", NULL);
+    lookup_path = apr_pstrcat(pool, path, "/", (char *)NULL);
   while ((! db_err)
          && strncmp(lookup_path, key.data, strlen(lookup_path)) == 0)
     {

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/lock.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/lock.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/lock.c Thu Nov  4 20:48:21 2010
@@ -250,7 +250,7 @@ svn_fs_base__generate_lock_token(const c
      generate a URI that matches the DAV RFC.  We could change this to
      some other URI scheme someday, if we wish. */
   *token = apr_pstrcat(pool, "opaquelocktoken:",
-                       svn_uuid_generate(pool), NULL);
+                       svn_uuid_generate(pool), (char *)NULL);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/revs-txns.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/revs-txns.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/revs-txns.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/revs-txns.c Thu Nov  4 20:48:21 2010
@@ -270,7 +270,7 @@ svn_fs_base__set_rev_prop(svn_fs_t *fs,
               && !svn_string_compare(wanted_value, present_value)))
         {
           /* What we expected isn't what we found. */
-          return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+          return svn_error_createf(SVN_ERR_FS_PROP_BASEVALUE_MISMATCH, NULL,
                                    _("revprop '%s' has unexpected value in "
                                      "filesystem"),
                                    name);
@@ -1159,7 +1159,6 @@ svn_fs_base__purge_txn(svn_fs_t *fs,
 {
   struct cleanup_txn_args args;
   transaction_t *txn;
-  int i;
 
   SVN_ERR(svn_fs__check_fs(fs, TRUE));
 
@@ -1182,6 +1181,8 @@ svn_fs_base__purge_txn(svn_fs_t *fs,
   /* Kill the transaction's copies (which should gracefully...). */
   if (txn->copies)
     {
+      int i;
+
       for (i = 0; i < txn->copies->nelts; i++)
         {
           SVN_ERR(svn_fs_base__retry_txn

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/tree.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_fs_base/tree.c Thu Nov  4 20:48:21 2010
@@ -1775,7 +1775,7 @@ deltify_mutable(svn_fs_t *fs,
        For 1.6 and beyond, we just deltify the current node against its
        predecessors, using skip deltas similar to the way FSFS does.  */
 
-    int pred_count, nlevels, lev, count;
+    int pred_count;
     const svn_fs_id_t *pred_id;
     struct txn_pred_count_args tpc_args;
     apr_pool_t *subpools[2];
@@ -1861,6 +1861,8 @@ deltify_mutable(svn_fs_t *fs,
       }
     else
       {
+        int nlevels, lev, count;
+
         /**** REVERSE DELTA STORAGE ****/
 
         /* Decide how many predecessors to redeltify.  To save overhead,

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/caching.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/caching.c Thu Nov  4 20:48:21 2010
@@ -198,7 +198,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
   const char *prefix = apr_pstrcat(pool,
                                    "fsfs:", ffd->uuid,
                                    "/", fs->path, ":",
-                                   NULL);
+                                   (char *)NULL);
   svn_memcache_t *memcache;
   svn_boolean_t no_handler;
 
@@ -219,7 +219,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                                        deserialize_id,
                                        sizeof(svn_revnum_t),
                                        apr_pstrcat(pool, prefix, "RRI",
-                                                   NULL),
+                                                   (char *)NULL),
                                        fs->pool));
   else
     SVN_ERR(svn_cache__create_inprocess(&(ffd->rev_root_id_cache),
@@ -239,7 +239,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                                        svn_fs_fs__dag_deserialize,
                                        APR_HASH_KEY_STRING,
                                        apr_pstrcat(pool, prefix, "DAG",
-                                                   NULL),
+                                                   (char *)NULL),
                                        fs->pool));
   else
     SVN_ERR(svn_cache__create_inprocess(&(ffd->rev_node_cache),
@@ -259,7 +259,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                                        svn_fs_fs__dir_entries_deserialize,
                                        APR_HASH_KEY_STRING,
                                        apr_pstrcat(pool, prefix, "DIR",
-                                                   NULL),
+                                                   (char *)NULL),
                                        fs->pool));
   else
     SVN_ERR(svn_cache__create_inprocess(&(ffd->dir_cache),
@@ -279,7 +279,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                                        manifest_deserialize,
                                        sizeof(svn_revnum_t),
                                        apr_pstrcat(pool, prefix, "PACK-MANIFEST",
-                                                   NULL),
+                                                   (char *)NULL),
                                        fs->pool));
   else
     SVN_ERR(svn_cache__create_inprocess(&(ffd->packed_offset_cache),
@@ -298,7 +298,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
                                          NULL, NULL,
                                          APR_HASH_KEY_STRING,
                                          apr_pstrcat(pool, prefix, "TEXT",
-                                                     NULL),
+                                                     (char *)NULL),
                                          fs->pool));
       if (! no_handler)
         SVN_ERR(svn_cache__set_error_handler(ffd->fulltext_cache,

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/fs_fs.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/fs_fs.c Thu Nov  4 20:48:21 2010
@@ -332,7 +332,8 @@ path_txn_dir(svn_fs_t *fs, const char *t
 {
   SVN_ERR_ASSERT_NO_RETURN(txn_id != NULL);
   return svn_dirent_join_many(pool, fs->path, PATH_TXNS_DIR,
-                              apr_pstrcat(pool, txn_id, PATH_EXT_TXN, NULL),
+                              apr_pstrcat(pool, txn_id, PATH_EXT_TXN,
+                                          (char *)NULL),
                               NULL);
 }
 
@@ -373,7 +374,8 @@ path_txn_proto_rev(svn_fs_t *fs, const c
   fs_fs_data_t *ffd = fs->fsap_data;
   if (ffd->format >= SVN_FS_FS__MIN_PROTOREVS_DIR_FORMAT)
     return svn_dirent_join_many(pool, fs->path, PATH_TXN_PROTOS_DIR,
-                                apr_pstrcat(pool, txn_id, PATH_EXT_REV, NULL),
+                                apr_pstrcat(pool, txn_id, PATH_EXT_REV,
+                                            (char *)NULL),
                                 NULL);
   else
     return svn_dirent_join(path_txn_dir(fs, txn_id, pool), PATH_REV, pool);
@@ -386,7 +388,7 @@ path_txn_proto_rev_lock(svn_fs_t *fs, co
   if (ffd->format >= SVN_FS_FS__MIN_PROTOREVS_DIR_FORMAT)
     return svn_dirent_join_many(pool, fs->path, PATH_TXN_PROTOS_DIR,
                                 apr_pstrcat(pool, txn_id, PATH_EXT_REV_LOCK,
-                                            NULL),
+                                            (char *)NULL),
                                 NULL);
   else
     return svn_dirent_join(path_txn_dir(fs, txn_id, pool), PATH_REV_LOCK,
@@ -409,14 +411,14 @@ static APR_INLINE const char *
 path_txn_node_props(svn_fs_t *fs, const svn_fs_id_t *id, apr_pool_t *pool)
 {
   return apr_pstrcat(pool, path_txn_node_rev(fs, id, pool), PATH_EXT_PROPS,
-                     NULL);
+                     (char *)NULL);
 }
 
 static APR_INLINE const char *
 path_txn_node_children(svn_fs_t *fs, const svn_fs_id_t *id, apr_pool_t *pool)
 {
   return apr_pstrcat(pool, path_txn_node_rev(fs, id, pool),
-                     PATH_EXT_CHILDREN, NULL);
+                     PATH_EXT_CHILDREN, (char *)NULL);
 }
 
 static APR_INLINE const char *
@@ -606,6 +608,10 @@ with_some_lock(svn_fs_t *fs,
         SVN_ERR(update_min_unpacked_rev(fs, pool));
       if (ffd->format >= SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
         SVN_ERR(update_min_unpacked_revprop(fs, pool));
+#if 0 /* Might be a good idea? */
+      SVN_ERR(get_youngest(&ffd->youngest_rev_cache, fs->path,
+                           pool));
+#endif
       err = body(baton, subpool);
     }
 
@@ -1208,6 +1214,28 @@ update_min_unpacked_revprop(svn_fs_t *fs
                                pool);
 }
 
+/* Create a new SQLite database for storing the revprops in filesystem FS.
+ * Leave the DB open and set *SDB to its handle.  Also create the "min
+ * unpacked revprop" file. */
+static svn_error_t *
+create_packed_revprops_db(svn_sqlite__db_t **sdb,
+                          svn_fs_t *fs,
+                          apr_pool_t *result_pool,
+                          apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_io_file_create(path_min_unpacked_revprop(fs, scratch_pool),
+                             "0\n", scratch_pool));
+  SVN_ERR(svn_sqlite__open(sdb,
+                           svn_dirent_join_many(scratch_pool, fs->path,
+                                                PATH_REVPROPS_DIR,
+                                                PATH_REVPROPS_DB,
+                                                NULL),
+                           svn_sqlite__mode_rwcreate, statements,
+                           0, NULL, result_pool, scratch_pool));
+  SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_CREATE_SCHEMA));
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 get_youngest(svn_revnum_t *youngest_p, const char *fs_path, apr_pool_t *pool);
 
@@ -1345,19 +1373,7 @@ upgrade_body(void *baton, apr_pool_t *po
      and create the database. */
   if (format < SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
     {
-      SVN_ERR(svn_io_file_create(path_min_unpacked_revprop(fs, pool), "0\n",
-                                 pool));
-
-      SVN_ERR(svn_sqlite__open(&ffd->revprop_db, svn_dirent_join_many(
-                                                          pool, fs->path,
-                                                          PATH_REVPROPS_DIR,
-                                                          PATH_REVPROPS_DB,
-                                                          NULL),
-                               svn_sqlite__mode_rwcreate, statements,
-                               0, NULL,
-                               fs->pool, pool));
-      SVN_ERR(svn_sqlite__exec_statements(ffd->revprop_db,
-                                          STMT_CREATE_SCHEMA));
+      SVN_ERR(create_packed_revprops_db(&ffd->revprop_db, fs, fs->pool, pool));
     }
 
   /* Bump the format file. */
@@ -4561,7 +4577,8 @@ create_txn_dir(const char **id_p, svn_fs
   txn_dir = svn_dirent_join_many(pool,
                                  fs->path,
                                  PATH_TXNS_DIR,
-                                 apr_pstrcat(pool, *id_p, PATH_EXT_TXN, NULL),
+                                 apr_pstrcat(pool, *id_p, PATH_EXT_TXN,
+                                             (char *)NULL),
                                  NULL);
 
   return svn_io_dir_make(txn_dir, APR_OS_DEFAULT, pool);
@@ -4929,7 +4946,7 @@ get_new_txn_node_id(const char **node_id
 
   SVN_ERR(write_next_ids(fs, txn_id, node_id, cur_copy_id, pool));
 
-  *node_id_p = apr_pstrcat(pool, "_", cur_node_id, NULL);
+  *node_id_p = apr_pstrcat(pool, "_", cur_node_id, (char *)NULL);
 
   return SVN_NO_ERROR;
 }
@@ -6417,7 +6434,7 @@ svn_fs_fs__reserve_copy_id(const char **
 
   SVN_ERR(write_next_ids(fs, txn_id, cur_node_id, copy_id, pool));
 
-  *copy_id_p = apr_pstrcat(pool, "_", cur_copy_id, NULL);
+  *copy_id_p = apr_pstrcat(pool, "_", cur_copy_id, (char *)NULL);
 
   return SVN_NO_ERROR;
 }
@@ -6489,6 +6506,7 @@ svn_fs_fs__create(svn_fs_t *fs,
                                                         pool),
                                         pool));
 
+  /* Create the revprops directory. */
   if (ffd->max_files_per_dir)
     SVN_ERR(svn_io_make_dir_recursively(path_revprops_shard(fs, 0, pool),
                                         pool));
@@ -6498,21 +6516,10 @@ svn_fs_fs__create(svn_fs_t *fs,
                                                         pool),
                                         pool));
 
-  /* Create the revprops directory. */
+  /* Write the min unpacked revprop file, and create the database. */
   if (format >= SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
     {
-      SVN_ERR(svn_io_file_create(path_min_unpacked_revprop(fs, pool), "0\n",
-                                 pool));
-      SVN_ERR(svn_sqlite__open(&ffd->revprop_db, svn_dirent_join_many(
-                                                    pool, path,
-                                                    PATH_REVPROPS_DIR,
-                                                    PATH_REVPROPS_DB,
-                                                    NULL),
-                               svn_sqlite__mode_rwcreate, statements,
-                               0, NULL,
-                               fs->pool, pool));
-      SVN_ERR(svn_sqlite__exec_statements(ffd->revprop_db,
-                                          STMT_CREATE_SCHEMA));
+      SVN_ERR(create_packed_revprops_db(&ffd->revprop_db, fs, fs->pool, pool));
     }
 
   /* Create the transaction directory. */
@@ -6976,7 +6983,7 @@ svn_fs_fs__set_uuid(svn_fs_t *fs,
     uuid = svn_uuid_generate(pool);
 
   /* Make sure we have a copy in FS->POOL, and append a newline. */
-  my_uuid = apr_pstrcat(fs->pool, uuid, "\n", NULL);
+  my_uuid = apr_pstrcat(fs->pool, uuid, "\n", (char *)NULL);
   my_uuid_len = strlen(my_uuid);
 
   SVN_ERR(svn_io_write_unique(&tmp_path,
@@ -7312,7 +7319,7 @@ change_rev_prop_body(void *baton, apr_po
               && !svn_string_compare(wanted_value, present_value)))
         {
           /* What we expected isn't what we found. */
-          return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+          return svn_error_createf(SVN_ERR_FS_PROP_BASEVALUE_MISMATCH, NULL,
                                    _("revprop '%s' has unexpected value in "
                                      "filesystem"),
                                    cb->name);

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/fs_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/fs_fs.h?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/fs_fs.h Thu Nov  4 20:48:21 2010
@@ -26,7 +26,10 @@
 #include "fs.h"
 
 /* Open the fsfs filesystem pointed to by PATH and associate it with
-   filesystem object FS.  Use POOL for temporary allocations. */
+   filesystem object FS.  Use POOL for temporary allocations.
+
+   ### Some parts of *FS must have been initialized beforehand; some parts
+       (including FS->path) are initialized by this function. */
 svn_error_t *svn_fs_fs__open(svn_fs_t *fs,
                              const char *path,
                              apr_pool_t *pool);
@@ -336,7 +339,10 @@ svn_error_t *svn_fs_fs__reserve_copy_id(
                                         apr_pool_t *pool);
 
 /* Create a fs_fs fileysystem referenced by FS at path PATH.  Get any
-   temporary allocations from POOL. */
+   temporary allocations from POOL.
+
+   ### Some parts of *FS must have been initialized beforehand; some parts
+       (including FS->path) are initialized by this function. */
 svn_error_t *svn_fs_fs__create(svn_fs_t *fs,
                                const char *path,
                                apr_pool_t *pool);

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/lock.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/lock.c Thu Nov  4 20:48:21 2010
@@ -860,7 +860,7 @@ svn_fs_fs__generate_lock_token(const cha
      generate a URI that matches the DAV RFC.  We could change this to
      some other URI scheme someday, if we wish. */
   *token = apr_pstrcat(pool, "opaquelocktoken:",
-                       svn_uuid_generate(pool), NULL);
+                       svn_uuid_generate(pool), (char *)NULL);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/tree.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_fs_fs/tree.c Thu Nov  4 20:48:21 2010
@@ -2173,7 +2173,7 @@ fs_copied_from(svn_revnum_t *rev_p,
 
   if (copyfrom_str)
     {
-      if (strlen(copyfrom_str) == 0)
+      if (*copyfrom_str == 0)
         {
           /* We have a cached entry that says there is no copyfrom
              here. */

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_ra/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_ra/deprecated.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_ra/deprecated.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_ra/deprecated.c Thu Nov  4 20:48:21 2010
@@ -196,6 +196,15 @@ svn_error_t *svn_ra_open(svn_ra_session_
                       config, pool);
 }
 
+svn_error_t *svn_ra_change_rev_prop(svn_ra_session_t *session,
+                                    svn_revnum_t rev,
+                                    const char *name,
+                                    const svn_string_t *value,
+                                    apr_pool_t *pool)
+{
+  return svn_ra_change_rev_prop2(session, rev, name, NULL, value, pool);
+}
+
 svn_error_t *svn_ra_get_commit_editor2(svn_ra_session_t *session,
                                        const svn_delta_editor_t **editor,
                                        void **edit_baton,

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_ra/ra_loader.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_ra/ra_loader.c Thu Nov  4 20:48:21 2010
@@ -612,14 +612,37 @@ svn_error_t *svn_ra_get_dated_revision(s
   return session->vtable->get_dated_revision(session, revision, tm, pool);
 }
 
-svn_error_t *svn_ra_change_rev_prop(svn_ra_session_t *session,
-                                    svn_revnum_t rev,
-                                    const char *name,
-                                    const svn_string_t *value,
-                                    apr_pool_t *pool)
+svn_error_t *svn_ra_change_rev_prop2(svn_ra_session_t *session,
+                                     svn_revnum_t rev,
+                                     const char *name,
+                                     const svn_string_t *const *old_value_p,
+                                     const svn_string_t *value,
+                                     apr_pool_t *pool)
 {
   SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(rev));
-  return session->vtable->change_rev_prop(session, rev, name, value, pool);
+
+  /* If an old value was specified, make sure the server supports
+   * specifying it. */
+  if (old_value_p)
+    {
+      svn_boolean_t has_atomic_revprops;
+
+      SVN_ERR(svn_ra_has_capability(session, &has_atomic_revprops,
+                                    SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+                                    pool));
+
+      if (!has_atomic_revprops)
+        /* API violation.  (Should be an ASSERT, but gstein talked me
+         * out of it.) */
+        return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                                 _("Specifying 'old_value_p' is not allowed when "
+                                   "the '%s' capability is not advertised, and "
+                                   "could indicate a bug in your client"),
+                                   SVN_RA_CAPABILITY_ATOMIC_REVPROPS);
+    }
+
+  return session->vtable->change_rev_prop(session, rev, name,
+                                          old_value_p, value, pool);
 }
 
 svn_error_t *svn_ra_rev_proplist(svn_ra_session_t *session,

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_ra/ra_loader.h?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_ra/ra_loader.h Thu Nov  4 20:48:21 2010
@@ -77,6 +77,7 @@ typedef struct svn_ra__vtable_t {
   svn_error_t *(*change_rev_prop)(svn_ra_session_t *session,
                                   svn_revnum_t rev,
                                   const char *name,
+                                  const svn_string_t *const *old_value_p,
                                   const svn_string_t *value,
                                   apr_pool_t *pool);
 

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_ra/wrapper_template.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_ra/wrapper_template.h?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_ra/wrapper_template.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_ra/wrapper_template.h Thu Nov  4 20:48:21 2010
@@ -127,7 +127,7 @@ static svn_error_t *compat_change_rev_pr
                                            const svn_string_t *value,
                                            apr_pool_t *pool)
 {
-  return VTBL.change_rev_prop(session_baton, rev, propname, value, pool);
+  return VTBL.change_rev_prop(session_baton, rev, propname, NULL, value, pool);
 }
 
 static svn_error_t *compat_rev_proplist(void *session_baton,

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_ra_local/ra_plugin.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_ra_local/ra_plugin.c Thu Nov  4 20:48:21 2010
@@ -250,7 +250,6 @@ make_reporter(svn_ra_session_t *session,
 {
   svn_ra_local__session_baton_t *sess = session->priv;
   void *rbaton;
-  size_t repos_url_len;
   const char *other_fs_path = NULL;
   const char *repos_url_decoded;
 
@@ -262,6 +261,8 @@ make_reporter(svn_ra_session_t *session,
      regular filesystem path. */
   if (other_url)
     {
+      size_t repos_url_len;
+
       other_url = svn_path_uri_decode(other_url, pool);
       repos_url_decoded = svn_path_uri_decode(sess->repos_url, pool);
       repos_url_len = strlen(repos_url_decoded);
@@ -504,7 +505,8 @@ svn_ra_local__reparent(svn_ra_session_t 
 
   /* Update our FS_PATH sess member to point to our new
      relative-URL-turned-absolute-filesystem-path. */
-  relpath = apr_pstrcat(pool, "/", svn_path_uri_decode(relpath, pool), NULL);
+  relpath = apr_pstrcat(pool, "/", svn_path_uri_decode(relpath, pool),
+                        (char *)NULL);
   svn_stringbuf_set(sess->fs_path, relpath);
 
   return SVN_NO_ERROR;
@@ -563,14 +565,16 @@ static svn_error_t *
 svn_ra_local__change_rev_prop(svn_ra_session_t *session,
                               svn_revnum_t rev,
                               const char *name,
+                              const svn_string_t *const *old_value_p,
                               const svn_string_t *value,
                               apr_pool_t *pool)
 {
   svn_ra_local__session_baton_t *sess = session->priv;
+
   SVN_ERR(get_username(session, pool));
-  return svn_repos_fs_change_rev_prop3(sess->repos, rev, sess->username,
-                                       name, value, TRUE, TRUE, NULL, NULL,
-                                       pool);
+  return svn_repos_fs_change_rev_prop4(sess->repos, rev, sess->username,
+                                       name, old_value_p, value, TRUE, TRUE,
+                                       NULL, NULL, pool);
 }
 
 static svn_error_t *
@@ -869,13 +873,14 @@ svn_ra_local__get_log(svn_ra_session_t *
                       apr_pool_t *pool)
 {
   svn_ra_local__session_baton_t *sess = session->priv;
-  int i;
   struct log_baton lb;
   apr_array_header_t *abs_paths =
     apr_array_make(pool, 0, sizeof(const char *));
 
   if (paths)
     {
+      int i;
+
       for (i = 0; i < paths->nelts; i++)
         {
           const char *relative_path = APR_ARRAY_IDX(paths, i, const char *);
@@ -1389,7 +1394,8 @@ svn_ra_local__has_capability(svn_ra_sess
   if (strcmp(capability, SVN_RA_CAPABILITY_DEPTH) == 0
       || strcmp(capability, SVN_RA_CAPABILITY_LOG_REVPROPS) == 0
       || strcmp(capability, SVN_RA_CAPABILITY_PARTIAL_REPLAY) == 0
-      || strcmp(capability, SVN_RA_CAPABILITY_COMMIT_REVPROPS) == 0)
+      || strcmp(capability, SVN_RA_CAPABILITY_COMMIT_REVPROPS) == 0
+      || strcmp(capability, SVN_RA_CAPABILITY_ATOMIC_REVPROPS) == 0)
     {
       *has = TRUE;
     }

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/commit.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/commit.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/commit.c Thu Nov  4 20:48:21 2010
@@ -49,33 +49,27 @@
 
 
 #define APPLY_TO_VERSION "<D:apply-to-version/>"
+
 /*
-** version_rsrc_t: identify the relevant pieces of a resource on the server
-**
-** REVISION is the resource's revision, or SVN_INVALID_REVNUM if it is
-** new or is the HEAD.
-**
-** URL refers to the public/viewable/original resource.
-** VSN_URL refers to the version resource that we stored locally
-** WR_URL refers to a working resource for this resource
-**
-** Note that VSN_URL is NULL if this resource has just been added, and
-** WR_URL can be NULL if the resource has not (yet) been checked out.
-**
-** LOCAL_PATH is relative to the root of the commit. It will be used
-** for the get_func, push_func, and close_func callbacks.
-**
-** NAME is the name of the resource.
-*/
+ * version_rsrc_t: identify the relevant pieces of a resource on the server
+ *
+ * NOTE:  If you tweak this structure, please update dup_resource() to
+ * ensure that it continues to create complete deep copies!
+ */
 typedef struct
 {
-  svn_revnum_t revision;
-  const char *url;
-  const char *vsn_url;
-  const char *wr_url;
-  const char *local_path;
-  const char *name;
-  apr_pool_t *pool; /* pool in which this resource is allocated. */
+  svn_revnum_t revision;  /* resource's revision, or SVN_INVALID_REVNUM
+                             if it's new or is the HEAD */
+  const char *url;        /* public/viewable/original resource URL */
+  const char *vsn_url;    /* version resource URL that we stored
+                             locally; NULL if this is a just-added resource */
+  const char *wr_url;     /* working resource URL for this resource;
+                             NULL for resources not (yet) checked out */
+  const char *local_path; /* path relative to the root of the commit
+                             (used for get_func, push_func, and
+                             close_func callbacks). */
+  const char *name;       /* basename of the resource */
+  apr_pool_t *pool;       /* pool in which this resource is allocated */
 
 } version_rsrc_t;
 
@@ -141,11 +135,10 @@ static const ne_propname fetch_props[] =
 
 static const ne_propname log_message_prop = { SVN_DAV_PROP_NS_SVN, "log" };
 
-/* perform a deep copy of BASE into POOL, and return the result. */
+/* Return a deep copy of BASE allocated from POOL. */
 static version_rsrc_t * dup_resource(version_rsrc_t *base, apr_pool_t *pool)
 {
   version_rsrc_t *rsrc = apr_pcalloc(pool, sizeof(*rsrc));
-  rsrc->pool = pool;
   rsrc->revision = base->revision;
   rsrc->url = base->url ?
     apr_pstrdup(pool, base->url) : NULL;
@@ -155,6 +148,9 @@ static version_rsrc_t * dup_resource(ver
     apr_pstrdup(pool, base->wr_url) : NULL;
   rsrc->local_path = base->local_path ?
     apr_pstrdup(pool, base->local_path) : NULL;
+  rsrc->name = base->name ?
+    apr_pstrdup(pool, base->name) : NULL;
+  rsrc->pool = pool;
   return rsrc;
 }
 
@@ -616,7 +612,8 @@ static svn_error_t * do_proppatch(svn_ra
     }
 
   return svn_ra_neon__do_proppatch(ras, url, rb->prop_changes,
-                                   rb->prop_deletes, extra_headers, pool);
+                                   rb->prop_deletes, NULL, extra_headers,
+                                   pool);
 }
 
 
@@ -700,7 +697,7 @@ static svn_error_t * commit_delete_entry
                                          apr_pool_t *pool)
 {
   resource_baton_t *parent = parent_baton;
-  const char *name = svn_relpath_basename(path, pool);
+  const char *name = svn_relpath_basename(path, NULL);
   apr_hash_t *extra_headers = NULL;
   const char *child;
   int code;
@@ -1416,7 +1413,7 @@ static svn_error_t * apply_revprops(comm
     return err;
 
   return svn_ra_neon__do_proppatch(cc->ras, vcc_rsrc.wr_url, revprop_table,
-                                   NULL, NULL, pool);
+                                   NULL, NULL, NULL, pool);
 }
 
 svn_error_t * svn_ra_neon__get_commit_editor(svn_ra_session_t *session,

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/fetch.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/fetch.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/fetch.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/fetch.c Thu Nov  4 20:48:21 2010
@@ -56,17 +56,6 @@
 
 
 typedef struct {
-  /* the information for this subdir. if rsrc==NULL, then this is a sentinel
-     record in fetch_ctx_t.subdirs to close the directory implied by the
-     parent_baton member. */
-  svn_ra_neon__resource_t *rsrc;
-
-  /* the directory containing this subdirectory. */
-  void *parent_baton;
-
-} subdir_t;
-
-typedef struct {
   apr_pool_t *pool;
 
   /* these two are the handler that the editor gave us */
@@ -92,9 +81,6 @@ typedef struct {
   void *subctx;
 } custom_get_ctx_t;
 
-#define POP_SUBDIR(sds) (APR_ARRAY_IDX((sds), --(sds)->nelts, subdir_t *))
-#define PUSH_SUBDIR(sds,s) (APR_ARRAY_PUSH((sds), subdir_t *) = (s))
-
 typedef svn_error_t * (*prop_setter_t)(void *baton,
                                        const char *name,
                                        const svn_string_t *value,
@@ -346,7 +332,7 @@ static svn_error_t *add_props(apr_hash_t
              server, or both.  Convert the URI namespace into normal
              'svn:' prefix again before pushing it at the wc. */
           SVN_ERR((*setter)(baton, apr_pstrcat(pool, SVN_PROP_PREFIX,
-                                               key + NSLEN, NULL),
+                                               key + NSLEN, (char *)NULL),
                             val, pool));
         }
 #undef NSLEN
@@ -640,7 +626,8 @@ filter_props(apr_hash_t *props,
       if (strncmp(name, SVN_DAV_PROP_NS_SVN, NSLEN) == 0)
         {
           apr_hash_set(props,
-                       apr_pstrcat(pool, SVN_PROP_PREFIX, name + NSLEN, NULL),
+                       apr_pstrcat(pool, SVN_PROP_PREFIX, name + NSLEN,
+                                   (char *)NULL),
                        APR_HASH_KEY_STRING,
                        value);
           continue;
@@ -1122,6 +1109,7 @@ svn_error_t *svn_ra_neon__get_latest_rev
 svn_error_t *svn_ra_neon__change_rev_prop(svn_ra_session_t *session,
                                           svn_revnum_t rev,
                                           const char *name,
+                                          const svn_string_t *const *old_value_p,
                                           const svn_string_t *value,
                                           apr_pool_t *pool)
 {
@@ -1130,12 +1118,24 @@ svn_error_t *svn_ra_neon__change_rev_pro
   svn_error_t *err;
   apr_hash_t *prop_changes = NULL;
   apr_array_header_t *prop_deletes = NULL;
+  apr_hash_t *prop_old_values = NULL;
   static const ne_propname wanted_props[] =
     {
       { "DAV:", "auto-version" },
       { NULL }
     };
 
+  if (old_value_p)
+    {
+      svn_boolean_t capable;
+      SVN_ERR(svn_ra_neon__has_capability(session, &capable,
+                                          SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+                                          pool));
+
+      /* How did you get past the same check in svn_ra_change_rev_prop2()? */
+      SVN_ERR_ASSERT(capable);
+    }
+
   /* Main objective: do a PROPPATCH (allprops) on a baseline object */
 
   /* ### A Word From Our Sponsor:  see issue #916.
@@ -1165,19 +1165,33 @@ svn_error_t *svn_ra_neon__change_rev_pro
          to attempt the PROPPATCH if the deltaV server is going to do
          auto-versioning and create a new baseline! */
 
-  if (value)
+  if (old_value_p)
     {
-      prop_changes = apr_hash_make(pool);
-      apr_hash_set(prop_changes, name, APR_HASH_KEY_STRING, value);
+      svn_dav__two_props_t *both_values;
+
+      both_values = apr_palloc(pool, sizeof(*both_values));
+      both_values->old_value_p = old_value_p;
+      both_values->new_value = value;
+
+      prop_old_values = apr_hash_make(pool);
+      apr_hash_set(prop_old_values, name, APR_HASH_KEY_STRING, both_values);
     }
   else
     {
-      prop_deletes = apr_array_make(pool, 1, sizeof(const char *));
-      APR_ARRAY_PUSH(prop_deletes, const char *) = name;
+      if (value)
+        {
+          prop_changes = apr_hash_make(pool);
+          apr_hash_set(prop_changes, name, APR_HASH_KEY_STRING, value);
+        }
+      else
+        {
+          prop_deletes = apr_array_make(pool, 1, sizeof(const char *));
+          APR_ARRAY_PUSH(prop_deletes, const char *) = name;
+        }
     }
 
   err = svn_ra_neon__do_proppatch(ras, baseline->url, prop_changes,
-                                  prop_deletes, NULL, pool);
+                                  prop_deletes, prop_old_values, NULL, pool);
   if (err)
     return
       svn_error_create
@@ -2231,7 +2245,8 @@ end_element(void *userdata, int state,
           rb->file_baton ? rb->file_pool : TOP_DIR(rb).pool;
         prop_setter_t setter =
           rb->file_baton ? editor->change_file_prop : editor->change_dir_prop;
-        const char *name = apr_pstrcat(pool, elm->nspace, elm->name, NULL);
+        const char *name = apr_pstrcat(pool, elm->nspace, elm->name,
+                                       (char *)NULL);
         void *baton = rb->file_baton ? rb->file_baton : TOP_DIR(rb).baton;
         svn_string_t valstr;
 

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/get_locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/get_locks.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/get_locks.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/get_locks.c Thu Nov  4 20:48:21 2010
@@ -379,7 +379,7 @@ svn_ra_neon__get_locks(svn_ra_session_t 
                                                  url, pool));
 
   baton.lock_hash = apr_hash_make(pool);
-  baton.path = apr_pstrcat(pool, "/", rel_path, NULL);
+  baton.path = apr_pstrcat(pool, "/", rel_path, (char *)NULL);
   baton.requested_depth = depth;
   baton.pool = pool;
   baton.scratchpool = svn_pool_create(pool);

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/lock.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/lock.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/lock.c Thu Nov  4 20:48:21 2010
@@ -282,7 +282,7 @@ do_lock(svn_lock_t **lock,
                            "<D:owner>",
                            apr_xml_quote_string(pool, comment, 0),
                            "</D:owner>",
-                           NULL)
+                           (char *)NULL)
              : "");
 
   extra_headers = apr_hash_make(req->pool);

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/mergeinfo.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/mergeinfo.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/mergeinfo.c Thu Nov  4 20:48:21 2010
@@ -166,7 +166,7 @@ svn_ra_neon__get_mergeinfo(svn_ra_sessio
                            svn_boolean_t include_descendants,
                            apr_pool_t *pool)
 {
-  int i, status_code;
+  int status_code;
   svn_ra_neon__session_t *ras = session->priv;
   svn_stringbuf_t *request_body = svn_stringbuf_create("", pool);
   struct mergeinfo_baton mb;
@@ -204,6 +204,8 @@ svn_ra_neon__get_mergeinfo(svn_ra_sessio
 
   if (paths)
     {
+      int i;
+
       for (i = 0; i < paths->nelts; i++)
         {
           const char *this_path =

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/options.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/options.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_ra_neon/options.c Thu Nov  4 20:48:21 2010
@@ -152,6 +152,8 @@ parse_capabilities(ne_request *req,
                APR_HASH_KEY_STRING, capability_no);
   apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_LOG_REVPROPS,
                APR_HASH_KEY_STRING, capability_no);
+  apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+               APR_HASH_KEY_STRING, capability_no);
 
   /* Then find out which ones are supported. */
   val = ne_get_response_header(req, "dav");
@@ -199,6 +201,10 @@ parse_capabilities(ne_request *req,
         apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_LOG_REVPROPS,
                      APR_HASH_KEY_STRING, capability_yes);
 
+      if (svn_cstring_match_glob_list(SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS, vals))
+        apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+                     APR_HASH_KEY_STRING, capability_yes);
+
       if (svn_cstring_match_glob_list(SVN_DAV_NS_DAV_SVN_PARTIAL_REPLAY,
                                       vals))
         apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_PARTIAL_REPLAY,