You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2012/06/26 21:28:22 UTC

svn commit: r1354186 [18/33] - in /subversion/branches/inheritable-props: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/ notes/ notes/api-errata/1.8/ notes/directory-i...

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_svn/marshal.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_svn/marshal.c Tue Jun 26 19:26:49 2012
@@ -439,6 +439,8 @@ static svn_error_t *write_number(svn_ra_
 {
   apr_size_t written;
 
+  /* SVN_INT64_BUFFER_SIZE includes space for a terminating NUL that
+   * svn__ui64toa will always append. */
   if (conn->write_pos + SVN_INT64_BUFFER_SIZE >= sizeof(conn->write_buf))
     SVN_ERR(writebuf_flush(conn, pool));
 
@@ -460,11 +462,11 @@ svn_error_t *svn_ra_svn_write_string(svn
 {
   if (str->len < 10)
     {
-      SVN_ERR(writebuf_writechar(conn, pool, (char)str->len + '0'));
+      SVN_ERR(writebuf_writechar(conn, pool, (char)(str->len + '0')));
       SVN_ERR(writebuf_writechar(conn, pool, ':'));
     }
   else
-    write_number(conn, pool, str->len, ':');
+    SVN_ERR(write_number(conn, pool, str->len, ':'));
 
   SVN_ERR(writebuf_write(conn, pool, str->data, str->len));
   SVN_ERR(writebuf_writechar(conn, pool, ' '));
@@ -478,11 +480,11 @@ svn_error_t *svn_ra_svn_write_cstring(sv
 
   if (len < 10)
     {
-      SVN_ERR(writebuf_writechar(conn, pool, (char)len + '0'));
+      SVN_ERR(writebuf_writechar(conn, pool, (char)(len + '0')));
       SVN_ERR(writebuf_writechar(conn, pool, ':'));
     }
   else
-    write_number(conn, pool, len, ':');
+    SVN_ERR(write_number(conn, pool, len, ':'));
 
   SVN_ERR(writebuf_write(conn, pool, s, len));
   SVN_ERR(writebuf_writechar(conn, pool, ' '));
@@ -697,7 +699,7 @@ static svn_error_t *read_string(svn_ra_s
               ? len
               : SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
 
-      svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len + 1);
+      svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len);
       dest = stringbuf->data + stringbuf->len;
     }
 
@@ -1148,10 +1150,7 @@ svn_error_t *svn_ra_svn_write_cmd(svn_ra
   va_start(ap, fmt);
   err = vwrite_tuple(conn, pool, fmt, ap);
   va_end(ap);
-  if (err)
-    return err;
-  SVN_ERR(svn_ra_svn_end_list(conn, pool));
-  return SVN_NO_ERROR;
+  return err ? svn_error_trace(err) : svn_ra_svn_end_list(conn, pool);
 }
 
 svn_error_t *svn_ra_svn_write_cmd_response(svn_ra_svn_conn_t *conn,
@@ -1161,24 +1160,18 @@ svn_error_t *svn_ra_svn_write_cmd_respon
   va_list ap;
   svn_error_t *err;
 
-  SVN_ERR(svn_ra_svn_start_list(conn, pool));
-  SVN_ERR(svn_ra_svn_write_word(conn, pool, "success"));
+  SVN_ERR(writebuf_write_short_string(conn, pool, "( success ", 10));
   va_start(ap, fmt);
   err = vwrite_tuple(conn, pool, fmt, ap);
   va_end(ap);
-  if (err)
-    return err;
-  SVN_ERR(svn_ra_svn_end_list(conn, pool));
-  return SVN_NO_ERROR;
+  return err ? svn_error_trace(err) : svn_ra_svn_end_list(conn, pool);
 }
 
 svn_error_t *svn_ra_svn_write_cmd_failure(svn_ra_svn_conn_t *conn,
                                           apr_pool_t *pool, svn_error_t *err)
 {
   char buffer[128];
-  SVN_ERR(svn_ra_svn_start_list(conn, pool));
-  SVN_ERR(svn_ra_svn_write_word(conn, pool, "failure"));
-  SVN_ERR(svn_ra_svn_start_list(conn, pool));
+  SVN_ERR(writebuf_write_short_string(conn, pool, "( failure ( ", 12));
   for (; err; err = err->child)
     {
       const char *msg;
@@ -1198,7 +1191,5 @@ svn_error_t *svn_ra_svn_write_cmd_failur
                                      err->file ? err->file : "",
                                      (apr_uint64_t) err->line));
     }
-  SVN_ERR(svn_ra_svn_end_list(conn, pool));
-  SVN_ERR(svn_ra_svn_end_list(conn, pool));
-  return SVN_NO_ERROR;
+  return writebuf_write_short_string(conn, pool, ") ) ", 4);
 }

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_svn/ra_svn.h?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_svn/ra_svn.h Tue Jun 26 19:26:49 2012
@@ -57,8 +57,8 @@ typedef svn_error_t *(*ra_svn_block_hand
                                                void *baton);
 
 /* The size of our per-connection read and write buffers. */
-#define SVN_RA_SVN__READBUF_SIZE 4*4096
-#define SVN_RA_SVN__WRITEBUF_SIZE 4*4096
+#define SVN_RA_SVN__READBUF_SIZE (4*4096)
+#define SVN_RA_SVN__WRITEBUF_SIZE (4*4096)
 
 /* Create forward reference */
 typedef struct svn_ra_svn__session_baton_t svn_ra_svn__session_baton_t;

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/commit.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/commit.c Tue Jun 26 19:26:49 2012
@@ -996,6 +996,7 @@ svn_repos_get_commit_editor5(const svn_d
 }
 
 
+#if 0
 static svn_error_t *
 ev2_check_authz(const struct ev2_baton *eb,
                 const char *relpath,
@@ -1024,6 +1025,7 @@ ev2_check_authz(const struct ev2_baton *
 
   return SVN_NO_ERROR;
 }
+#endif
 
 
 /* This implements svn_editor_cb_add_directory_t */
@@ -1098,12 +1100,14 @@ static svn_error_t *
 alter_directory_cb(void *baton,
                    const char *relpath,
                    svn_revnum_t revision,
+                   const apr_array_header_t *children,
                    apr_hash_t *props,
                    apr_pool_t *scratch_pool)
 {
   struct ev2_baton *eb = baton;
 
-  SVN_ERR(svn_editor_alter_directory(eb->inner, relpath, revision, props));
+  SVN_ERR(svn_editor_alter_directory(eb->inner, relpath, revision,
+                                     children, props));
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/deprecated.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/deprecated.c Tue Jun 26 19:26:49 2012
@@ -572,8 +572,7 @@ repos_notify_handler(void *baton,
   switch (notify->action)
   {
     case svn_repos_notify_warning:
-      len = strlen(notify->warning_str);
-      svn_error_clear(svn_stream_write(feedback_stream, notify->warning_str, &len));
+      svn_error_clear(svn_stream_puts(feedback_stream, notify->warning_str));
       return;
 
     case svn_repos_notify_dump_rev_end:
@@ -776,6 +775,27 @@ fns_from_fns2(const svn_repos_parse_fns2
   return fns;
 }
 
+static svn_repos_parser_fns2_t *
+fns2_from_fns3(const svn_repos_parse_fns3_t *fns3,
+              apr_pool_t *pool)
+{
+  svn_repos_parser_fns2_t *fns2;
+
+  fns2 = apr_palloc(pool, sizeof(*fns2));
+  fns2->new_revision_record = fns3->new_revision_record;
+  fns2->uuid_record = fns3->uuid_record;
+  fns2->new_node_record = fns3->new_node_record;
+  fns2->set_revision_property = fns3->set_revision_property;
+  fns2->set_node_property = fns3->set_node_property;
+  fns2->remove_node_props = fns3->remove_node_props;
+  fns2->set_fulltext = fns3->set_fulltext;
+  fns2->close_node = fns3->close_node;
+  fns2->close_revision = fns3->close_revision;
+  fns2->delete_node_property = fns3->delete_node_property;
+  fns2->apply_textdelta = fns3->apply_textdelta;
+  return fns2;
+}
+
 static svn_repos_parse_fns2_t *
 fns2_from_fns(const svn_repos_parser_fns_t *fns,
               apr_pool_t *pool)
@@ -797,6 +817,42 @@ fns2_from_fns(const svn_repos_parser_fns
   return fns2;
 }
 
+static svn_repos_parse_fns3_t *
+fns3_from_fns2(const svn_repos_parser_fns2_t *fns2,
+               apr_pool_t *pool)
+{
+  svn_repos_parse_fns3_t *fns3;
+
+  fns3 = apr_palloc(pool, sizeof(*fns3));
+  fns3->magic_header_record = NULL;
+  fns3->uuid_record = fns2->uuid_record;
+  fns3->new_revision_record = fns2->new_revision_record;
+  fns3->new_node_record = fns2->new_node_record;
+  fns3->set_revision_property = fns2->set_revision_property;
+  fns3->set_node_property = fns2->set_node_property;
+  fns3->remove_node_props = fns2->remove_node_props;
+  fns3->set_fulltext = fns2->set_fulltext;
+  fns3->close_node = fns2->close_node;
+  fns3->close_revision = fns2->close_revision;
+  fns3->delete_node_property = fns2->delete_node_property;
+  fns3->apply_textdelta = fns2->apply_textdelta;
+  return fns3;
+}
+
+svn_error_t *
+svn_repos_parse_dumpstream2(svn_stream_t *stream,
+                            const svn_repos_parser_fns2_t *parse_fns,
+                            void *parse_baton,
+                            svn_cancel_func_t cancel_func,
+                            void *cancel_baton,
+                            apr_pool_t *pool)
+{
+  svn_repos_parse_fns3_t *fns3 = fns3_from_fns2(parse_fns, pool);
+
+  return svn_repos_parse_dumpstream3(stream, fns3, parse_baton, FALSE,
+                                     cancel_func, cancel_baton, pool);
+}
+
 svn_error_t *
 svn_repos_parse_dumpstream(svn_stream_t *stream,
                            const svn_repos_parser_fns_t *parse_fns,
@@ -838,11 +894,17 @@ svn_repos_get_fs_build_parser3(const svn
                                void *notify_baton,
                                apr_pool_t *pool)
 {
-  return svn_repos_get_fs_build_parser4(callbacks, parse_baton, repos,
-                                        SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
-                                        use_history, validate_props,
-                                        uuid_action, parent_dir,
-                                        notify_func, notify_baton, pool);
+  const svn_repos_parse_fns3_t *fns3;
+
+  SVN_ERR(svn_repos_get_fs_build_parser4(&fns3, parse_baton, repos,
+                                         SVN_INVALID_REVNUM,
+                                         SVN_INVALID_REVNUM,
+                                         use_history, validate_props,
+                                         uuid_action, parent_dir,
+                                         notify_func, notify_baton, pool));
+
+  *callbacks = fns2_from_fns3(fns3, pool);
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/dump.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/dump.c Tue Jun 26 19:26:49 2012
@@ -34,6 +34,7 @@
 #include "svn_time.h"
 #include "svn_checksum.h"
 #include "svn_props.h"
+#include "svn_sorts.h"
 
 #include "private/svn_mergeinfo_private.h"
 #include "private/svn_fs_private.h"
@@ -282,11 +283,11 @@ dump_node(struct edit_baton *eb,
                             SVN_REPOS_DUMPFILE_NODE_PATH ": %s\n",
                             path));
   if (kind == svn_node_file)
-    SVN_ERR(svn_stream_printf(eb->stream, pool,
-                              SVN_REPOS_DUMPFILE_NODE_KIND ": file\n"));
+    SVN_ERR(svn_stream_puts(eb->stream,
+                            SVN_REPOS_DUMPFILE_NODE_KIND ": file\n"));
   else if (kind == svn_node_dir)
-    SVN_ERR(svn_stream_printf(eb->stream, pool,
-                              SVN_REPOS_DUMPFILE_NODE_KIND ": dir\n"));
+    SVN_ERR(svn_stream_puts(eb->stream,
+                            SVN_REPOS_DUMPFILE_NODE_KIND ": dir\n"));
 
   /* Remove leading slashes from copyfrom paths. */
   if (cmp_path)
@@ -301,9 +302,8 @@ dump_node(struct edit_baton *eb,
 
   if (action == svn_node_action_change)
     {
-      SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                SVN_REPOS_DUMPFILE_NODE_ACTION
-                                ": change\n"));
+      SVN_ERR(svn_stream_puts(eb->stream,
+                              SVN_REPOS_DUMPFILE_NODE_ACTION ": change\n"));
 
       /* either the text or props changed, or possibly both. */
       SVN_ERR(svn_fs_revision_root(&compare_root,
@@ -323,9 +323,9 @@ dump_node(struct edit_baton *eb,
       if (! is_copy)
         {
           /* a simple delete+add, implied by a single 'replace' action. */
-          SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                    SVN_REPOS_DUMPFILE_NODE_ACTION
-                                    ": replace\n"));
+          SVN_ERR(svn_stream_puts(eb->stream,
+                                  SVN_REPOS_DUMPFILE_NODE_ACTION
+                                  ": replace\n"));
 
           /* definitely need to dump all content for a replace. */
           if (kind == svn_node_file)
@@ -338,9 +338,9 @@ dump_node(struct edit_baton *eb,
 
           /* the path & kind headers have already been printed;  just
              add a delete action, and end the current record.*/
-          SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                    SVN_REPOS_DUMPFILE_NODE_ACTION
-                                    ": delete\n\n"));
+          SVN_ERR(svn_stream_puts(eb->stream,
+                                  SVN_REPOS_DUMPFILE_NODE_ACTION
+                                  ": delete\n\n"));
 
           /* recurse:  print an additional add-with-history record. */
           SVN_ERR(dump_node(eb, path, kind, svn_node_action_add,
@@ -354,9 +354,8 @@ dump_node(struct edit_baton *eb,
     }
   else if (action == svn_node_action_delete)
     {
-      SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                SVN_REPOS_DUMPFILE_NODE_ACTION
-                                ": delete\n"));
+      SVN_ERR(svn_stream_puts(eb->stream,
+                              SVN_REPOS_DUMPFILE_NODE_ACTION ": delete\n"));
 
       /* we can leave this routine quietly now, don't need to dump
          any content. */
@@ -365,8 +364,8 @@ dump_node(struct edit_baton *eb,
     }
   else if (action == svn_node_action_add)
     {
-      SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                SVN_REPOS_DUMPFILE_NODE_ACTION ": add\n"));
+      SVN_ERR(svn_stream_puts(eb->stream,
+                              SVN_REPOS_DUMPFILE_NODE_ACTION ": add\n"));
 
       if (! is_copy)
         {
@@ -511,9 +510,8 @@ dump_node(struct edit_baton *eb,
              saying that our property contents are a delta. */
           SVN_ERR(svn_fs_node_proplist(&oldhash, compare_root, compare_path,
                                        pool));
-          SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                    SVN_REPOS_DUMPFILE_PROP_DELTA
-                                    ": true\n"));
+          SVN_ERR(svn_stream_puts(eb->stream,
+                                  SVN_REPOS_DUMPFILE_PROP_DELTA ": true\n"));
         }
       else
         oldhash = apr_hash_make(pool);
@@ -544,9 +542,8 @@ dump_node(struct edit_baton *eb,
              saying our text contents are a delta. */
           SVN_ERR(store_delta(&delta_file, &textlen, compare_root,
                               compare_path, eb->fs_root, path, pool));
-          SVN_ERR(svn_stream_printf(eb->stream, pool,
-                                    SVN_REPOS_DUMPFILE_TEXT_DELTA
-                                    ": true\n"));
+          SVN_ERR(svn_stream_puts(eb->stream,
+                                  SVN_REPOS_DUMPFILE_TEXT_DELTA ": true\n"));
 
           if (compare_root)
             {
@@ -738,17 +735,20 @@ close_directory(void *dir_baton,
 {
   struct dir_baton *db = dir_baton;
   struct edit_baton *eb = db->edit_baton;
-  apr_hash_index_t *hi;
   apr_pool_t *subpool = svn_pool_create(pool);
+  int i;
+  apr_array_header_t *sorted_entries;
 
-  for (hi = apr_hash_first(pool, db->deleted_entries);
-       hi;
-       hi = apr_hash_next(hi))
-    {
-      const void *key;
-      const char *path;
-      apr_hash_this(hi, &key, NULL, NULL);
-      path = key;
+  /* Sort entries lexically instead of as paths. Even though the entries
+   * are full paths they're all in the same directory (see comment in struct
+   * dir_baton definition). So we really want to sort by basename, in which
+   * case the lexical sort function is more efficient. */
+  sorted_entries = svn_sort__hash(db->deleted_entries,
+                                  svn_sort_compare_items_lexically, pool);
+  for (i = 0; i < sorted_entries->nelts; i++)
+    {
+      const char *path = APR_ARRAY_IDX(sorted_entries, i,
+                                       svn_sort__item_t).key;
 
       svn_pool_clear(subpool);
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/load-fs-vtable.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/load-fs-vtable.c Tue Jun 26 19:26:49 2012
@@ -589,6 +589,13 @@ maybe_add_with_history(struct node_baton
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+magic_header_record(int version,
+                    void *parse_baton,
+                    apr_pool_t *pool)
+{
+  return SVN_NO_ERROR;
+}
 
 static svn_error_t *
 uuid_record(const char *uuid,
@@ -1016,7 +1023,7 @@ close_revision(void *baton)
 
 
 svn_error_t *
-svn_repos_get_fs_build_parser4(const svn_repos_parse_fns2_t **callbacks,
+svn_repos_get_fs_build_parser4(const svn_repos_parse_fns3_t **callbacks,
                                void **parse_baton,
                                svn_repos_t *repos,
                                svn_revnum_t start_rev,
@@ -1029,7 +1036,7 @@ svn_repos_get_fs_build_parser4(const svn
                                void *notify_baton,
                                apr_pool_t *pool)
 {
-  svn_repos_parse_fns2_t *parser = apr_pcalloc(pool, sizeof(*parser));
+  svn_repos_parse_fns3_t *parser = apr_pcalloc(pool, sizeof(*parser));
   struct parse_baton *pb = apr_pcalloc(pool, sizeof(*pb));
 
   if (parent_dir)
@@ -1042,9 +1049,10 @@ svn_repos_get_fs_build_parser4(const svn
   if (SVN_IS_VALID_REVNUM(start_rev))
     SVN_ERR_ASSERT(start_rev <= end_rev);
 
+  parser->magic_header_record = magic_header_record;
+  parser->uuid_record = uuid_record;
   parser->new_revision_record = new_revision_record;
   parser->new_node_record = new_node_record;
-  parser->uuid_record = uuid_record;
   parser->set_revision_property = set_revision_property;
   parser->set_node_property = set_node_property;
   parser->remove_node_props = remove_node_props;
@@ -1093,7 +1101,7 @@ svn_repos_load_fs4(svn_repos_t *repos,
                    void *cancel_baton,
                    apr_pool_t *pool)
 {
-  const svn_repos_parse_fns2_t *parser;
+  const svn_repos_parse_fns3_t *parser;
   void *parse_baton;
   struct parse_baton *pb;
 
@@ -1116,6 +1124,6 @@ svn_repos_load_fs4(svn_repos_t *repos,
   pb->use_pre_commit_hook = use_pre_commit_hook;
   pb->use_post_commit_hook = use_post_commit_hook;
 
-  return svn_repos_parse_dumpstream2(dumpstream, parser, parse_baton,
+  return svn_repos_parse_dumpstream3(dumpstream, parser, parse_baton, FALSE,
                                      cancel_func, cancel_baton, pool);
 }

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/load.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/load.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/load.c Tue Jun 26 19:26:49 2012
@@ -181,7 +181,7 @@ read_key_or_val(char **pbuf,
 static svn_error_t *
 parse_property_block(svn_stream_t *stream,
                      svn_filesize_t content_length,
-                     const svn_repos_parse_fns2_t *parse_fns,
+                     const svn_repos_parse_fns3_t *parse_fns,
                      void *record_baton,
                      void *parse_baton,
                      svn_boolean_t is_node,
@@ -299,7 +299,7 @@ static svn_error_t *
 parse_text_block(svn_stream_t *stream,
                  svn_filesize_t content_length,
                  svn_boolean_t is_delta,
-                 const svn_repos_parse_fns2_t *parse_fns,
+                 const svn_repos_parse_fns3_t *parse_fns,
                  void *record_baton,
                  char *buffer,
                  apr_size_t buflen,
@@ -373,7 +373,8 @@ parse_text_block(svn_stream_t *stream,
 /* Parse VERSIONSTRING and verify that we support the dumpfile format
    version number, setting *VERSION appropriately. */
 static svn_error_t *
-parse_format_version(const char *versionstring, int *version)
+parse_format_version(int *version,
+                     const char *versionstring)
 {
   static const int magic_len = sizeof(SVN_REPOS_DUMPFILE_MAGIC_HEADER) - 1;
   const char *p = strchr(versionstring, ':');
@@ -406,9 +407,10 @@ parse_format_version(const char *version
 /** The public routines **/
 
 svn_error_t *
-svn_repos_parse_dumpstream2(svn_stream_t *stream,
-                            const svn_repos_parse_fns2_t *parse_fns,
+svn_repos_parse_dumpstream3(svn_stream_t *stream,
+                            const svn_repos_parse_fns3_t *parse_fns,
                             void *parse_baton,
+                            svn_boolean_t deltas_are_text,
                             svn_cancel_func_t cancel_func,
                             void *cancel_baton,
                             apr_pool_t *pool)
@@ -428,16 +430,11 @@ svn_repos_parse_dumpstream2(svn_stream_t
     return stream_ran_dry();
 
   /* The first two lines of the stream are the dumpfile-format version
-     number, and a blank line. */
-  SVN_ERR(parse_format_version(linebuf->data, &version));
-
-  /* If we were called from svn_repos_parse_dumpstream(), the
-     callbacks to handle delta contents will be NULL, so we have to
-     reject dumpfiles with the current version. */
-  if (version == SVN_REPOS_DUMPFILE_FORMAT_VERSION
-      && (!parse_fns->delete_node_property || !parse_fns->apply_textdelta))
-    return svn_error_createf(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
-                             _("Unsupported dumpfile version: %d"), version);
+     number, and a blank line.  To preserve backward compatibility,
+     don't assume the existence of newer parser-vtable functions. */
+  SVN_ERR(parse_format_version(&version, linebuf->data));
+  if (parse_fns->magic_header_record != NULL)
+    SVN_ERR(parse_fns->magic_header_record(version, parse_baton, pool));
 
   /* A dumpfile "record" is defined to be a header-block of
      rfc822-style headers, possibly followed by a content-block.
@@ -528,6 +525,7 @@ svn_repos_parse_dumpstream2(svn_stream_t
           SVN_ERR(parse_fns->uuid_record(value, parse_baton, pool));
         }
       /* Or perhaps a dumpfile format? */
+      /* ### TODO: use parse_format_version */
       else if ((value = apr_hash_get(headers,
                                      SVN_REPOS_DUMPFILE_MAGIC_HEADER,
                                      APR_HASH_KEY_STRING)))
@@ -591,7 +589,9 @@ svn_repos_parse_dumpstream2(svn_stream_t
           const char *delta = apr_hash_get(headers,
                                            SVN_REPOS_DUMPFILE_TEXT_DELTA,
                                            APR_HASH_KEY_STRING);
-          svn_boolean_t is_delta = (delta && strcmp(delta, "true") == 0);
+          svn_boolean_t is_delta = FALSE;
+          if (! deltas_are_text)
+            is_delta = (delta && strcmp(delta, "true") == 0);
 
           SVN_ERR(parse_text_block(stream,
                                    svn__atoui64(text_cl),

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/replay.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/replay.c Tue Jun 26 19:26:49 2012
@@ -27,14 +27,18 @@
 
 #include "svn_types.h"
 #include "svn_delta.h"
+#include "svn_hash.h"
 #include "svn_fs.h"
 #include "svn_checksum.h"
 #include "svn_repos.h"
+#include "svn_sorts.h"
 #include "svn_props.h"
 #include "svn_pools.h"
 #include "svn_path.h"
 #include "svn_private_config.h"
 #include "private/svn_fspath.h"
+#include "private/svn_repos_private.h"
+#include "private/svn_delta_private.h"
 
 
 /*** Backstory ***/
@@ -99,6 +103,7 @@
    (though not necessarily in the same order in which they
    occurred). */
 
+/* #define USE_EV2_IMPL */
 
 
 /*** Helper functions. ***/
@@ -136,7 +141,6 @@ struct path_driver_cb_baton
   void *authz_read_baton;
 
   const char *base_path; /* relpath */
-  size_t base_path_len;
 
   svn_revnum_t low_water_mark;
   /* Stack of active copy operations. */
@@ -146,6 +150,7 @@ struct path_driver_cb_baton
   apr_pool_t *pool;
 };
 
+#ifndef USE_EV2_IMPL
 /* Recursively traverse EDIT_PATH (as it exists under SOURCE_ROOT) emitting
    the appropriate editor calls to add it and its children without any
    history.  This is meant to be used when either a subset of the tree
@@ -337,20 +342,7 @@ add_subdir(svn_fs_root_t *source_root,
 
   return SVN_NO_ERROR;
 }
-
-static svn_boolean_t
-is_within_base_path(const char *path, const char *base_path,
-                    apr_ssize_t base_len)
-{
-  if (base_path[0] == '\0')
-    return TRUE;
-
-  if (strncmp(base_path, path, base_len) == 0
-      && (path[base_len] == '/' || path[base_len] == '\0'))
-    return TRUE;
-
-  return FALSE;
-}
+#endif
 
 /* Given PATH deleted under ROOT, return in READABLE whether the path was
    readable prior to the deletion.  Consult COPIES (a stack of 'struct
@@ -415,7 +407,12 @@ was_readable(svn_boolean_t *readable,
    revision root, fspath, and revnum of the copyfrom of CHANGE, which
    corresponds to PATH under ROOT.  If the copyfrom info is valid
    (i.e., is not (NULL, SVN_INVALID_REVNUM)), then initialize SRC_READABLE
-   too, consulting AUTHZ_READ_FUNC and AUTHZ_READ_BATON if provided. */
+   too, consulting AUTHZ_READ_FUNC and AUTHZ_READ_BATON if provided.
+
+   NOTE: If the copyfrom information in CHANGE is marked as unknown
+   (meaning, its ->copyfrom_rev and ->copyfrom_path cannot be
+   trusted), this function will also update those members of the
+   CHANGE structure to carry accurate copyfrom information.  */
 static svn_error_t *
 fill_copyfrom(svn_fs_root_t **copyfrom_root,
               const char **copyfrom_path,
@@ -462,6 +459,7 @@ fill_copyfrom(svn_fs_root_t **copyfrom_r
   return SVN_NO_ERROR;
 }
 
+#ifndef USE_EV2_IMPL
 static svn_error_t *
 path_driver_cb_func(void **dir_baton,
                     void *parent_baton,
@@ -481,7 +479,6 @@ path_driver_cb_func(void **dir_baton,
   svn_fs_root_t *source_root = cb->compare_root;
   const char *source_fspath = NULL;
   const char *base_path = cb->base_path;
-  size_t base_path_len = cb->base_path_len;
 
   *dir_baton = NULL;
 
@@ -571,8 +568,7 @@ path_driver_cb_func(void **dir_baton,
          all. */
       if (copyfrom_path
           && ((! src_readable)
-              || (! is_within_base_path(copyfrom_path + 1, base_path,
-                                        base_path_len))
+              || (svn_relpath_skip_ancestor(base_path, copyfrom_path + 1) == NULL)
               || (cb->low_water_mark > copyfrom_rev)))
         {
           copyfrom_path = NULL;
@@ -698,10 +694,18 @@ path_driver_cb_func(void **dir_baton,
         }
     }
 
-  /* Handle property modifications. */
   if (! do_delete || do_add)
     {
-      if (change->prop_mod)
+      /* Is this a copy that was downgraded to a raw add?  (If so,
+         we'll need to transmit properties and file contents and such
+         for it regardless of what the CHANGE structure's text_mod
+         and prop_mod flags say.)  */
+      svn_boolean_t downgraded_copy = (change->copyfrom_known
+                                       && change->copyfrom_path
+                                       && (! copyfrom_path));
+
+      /* Handle property modifications. */
+      if (change->prop_mod || downgraded_copy)
         {
           apr_array_header_t *prop_diffs;
           apr_hash_t *old_props;
@@ -731,14 +735,9 @@ path_driver_cb_func(void **dir_baton,
             }
         }
 
-      /* Handle textual modifications.
-
-         Note that this needs to happen in the "copy from a file we
-         aren't allowed to see" case since otherwise the caller will
-         have no way to actually get the new file's contents, which
-         they are apparently allowed to see. */
+      /* Handle textual modifications. */
       if (change->node_kind == svn_node_file
-          && (change->text_mod || (change->copyfrom_path && ! copyfrom_path)))
+          && (change->text_mod || downgraded_copy))
         {
           svn_txdelta_window_handler_t delta_handler;
           void *delta_handler_baton;
@@ -785,6 +784,47 @@ path_driver_cb_func(void **dir_baton,
   return SVN_NO_ERROR;
 }
 
+#else
+
+static svn_error_t *
+fetch_kind_func(svn_kind_t *kind,
+                void *baton,
+                const char *path,
+                svn_revnum_t base_revision,
+                apr_pool_t *scratch_pool)
+{
+  svn_fs_root_t *root = baton;
+  svn_node_kind_t node_kind;
+
+  SVN_ERR(svn_fs_check_path(&node_kind, root, path, scratch_pool));
+
+  *kind = svn__kind_from_node_kind(node_kind, FALSE);
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+fetch_props_func(apr_hash_t **props,
+                 void *baton,
+                 const char *path,
+                 svn_revnum_t base_revision,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  svn_fs_root_t *root = baton;
+  svn_fs_root_t *prev_root;
+  svn_fs_t *fs = svn_fs_root_fs(root);
+
+  SVN_ERR(svn_fs_revision_root(&prev_root, fs,
+                               svn_fs_revision_root_revision(root) - 1,
+                               scratch_pool));
+
+  SVN_ERR(svn_fs_node_proplist(props, prev_root, path, result_pool));
+
+  return SVN_NO_ERROR;
+}
+
+#endif
+
 
 
 
@@ -799,12 +839,12 @@ svn_repos_replay2(svn_fs_root_t *root,
                   void *authz_read_baton,
                   apr_pool_t *pool)
 {
+#ifndef USE_EV2_IMPL
   apr_hash_t *fs_changes;
   apr_hash_t *changed_paths;
   apr_hash_index_t *hi;
   apr_array_header_t *paths;
   struct path_driver_cb_baton cb_baton;
-  size_t base_path_len;
 
   /* Special-case r0, which we know is an empty revision; if we don't
      special-case it we might end up trying to compare it to "r-1". */
@@ -822,8 +862,6 @@ svn_repos_replay2(svn_fs_root_t *root,
   else if (base_path[0] == '/')
     ++base_path;
 
-  base_path_len = strlen(base_path);
-
   /* Make an array from the keys of our CHANGED_PATHS hash, and copy
      the values into a new hash whose keys have no leading slashes. */
   paths = apr_array_make(pool, apr_hash_count(fs_changes),
@@ -856,14 +894,14 @@ svn_repos_replay2(svn_fs_root_t *root,
 
           /* If the base_path doesn't match the top directory of this path
              we don't want anything to do with it... */
-          if (is_within_base_path(path, base_path, base_path_len))
+          if (svn_relpath_skip_ancestor(base_path, path) != NULL)
             {
               APR_ARRAY_PUSH(paths, const char *) = path;
               apr_hash_set(changed_paths, path, keylen, change);
             }
           /* ...unless this was a change to one of the parent directories of
              base_path. */
-          else if (is_within_base_path(base_path, path, keylen))
+          else if (svn_relpath_skip_ancestor(path, base_path) != NULL)
             {
               APR_ARRAY_PUSH(paths, const char *) = path;
               apr_hash_set(changed_paths, path, keylen, change);
@@ -884,7 +922,6 @@ svn_repos_replay2(svn_fs_root_t *root,
   cb_baton.authz_read_func = authz_read_func;
   cb_baton.authz_read_baton = authz_read_baton;
   cb_baton.base_path = base_path;
-  cb_baton.base_path_len = base_path_len;
   cb_baton.low_water_mark = low_water_mark;
   cb_baton.compare_root = NULL;
 
@@ -913,4 +950,634 @@ svn_repos_replay2(svn_fs_root_t *root,
   return svn_delta_path_driver(editor, edit_baton,
                                SVN_INVALID_REVNUM, paths,
                                path_driver_cb_func, &cb_baton, pool);
+#else
+  svn_editor_t *editorv2;
+  struct svn_delta__extra_baton *exb;
+  svn_delta__unlock_func_t unlock_func;
+  svn_boolean_t send_abs_paths;
+  const char *repos_root = "";
+  void *unlock_baton;
+
+  /* Special-case r0, which we know is an empty revision; if we don't
+     special-case it we might end up trying to compare it to "r-1". */
+  if (svn_fs_is_revision_root(root)
+        && svn_fs_revision_root_revision(root) == 0)
+    {
+      SVN_ERR(editor->set_target_revision(edit_baton, 0, pool));
+      return SVN_NO_ERROR;
+    }
+
+  /* Determine the revision to use throughout the edit, and call
+     EDITOR's set_target_revision() function.  */
+  if (svn_fs_is_revision_root(root))
+    {
+      svn_revnum_t revision = svn_fs_revision_root_revision(root);
+      SVN_ERR(editor->set_target_revision(edit_baton, revision, pool));
+    }
+
+  if (! base_path)
+    base_path = "";
+  else if (base_path[0] == '/')
+    ++base_path;
+
+  /* Use the shim to convert our editor to an Ev2 editor, and pass it down
+     the stack. */
+  SVN_ERR(svn_delta__editor_from_delta(&editorv2, &exb,
+                                       &unlock_func, &unlock_baton,
+                                       editor, edit_baton,
+                                       &send_abs_paths,
+                                       repos_root, "",
+                                       NULL, NULL,
+                                       fetch_kind_func, root,
+                                       fetch_props_func, root,
+                                       pool, pool));
+
+  /* Tell the shim that we're starting the process. */
+  SVN_ERR(exb->start_edit(exb->baton, svn_fs_revision_root_revision(root)));
+
+  /* ### We're ignoring SEND_DELTAS here. */
+  SVN_ERR(svn_repos__replay_ev2(root, base_path, low_water_mark,
+                                editorv2, authz_read_func, authz_read_baton,
+                                pool));
+
+  return SVN_NO_ERROR;
+#endif
+}
+
+
+/*****************************************************************
+ *                      Ev2 Implementation                       *
+ *****************************************************************/
+
+#ifdef USE_EV2_IMPL
+/* Recursively traverse EDIT_PATH (as it exists under SOURCE_ROOT) emitting
+   the appropriate editor calls to add it and its children without any
+   history.  This is meant to be used when either a subset of the tree
+   has been ignored and we need to copy something from that subset to
+   the part of the tree we do care about, or if a subset of the tree is
+   unavailable because of authz and we need to use it as the source of
+   a copy. */
+static svn_error_t *
+add_subdir(svn_fs_root_t *source_root,
+           svn_fs_root_t *target_root,
+           svn_editor_t *editor,
+           const char *repos_relpath,
+           const char *source_fspath,
+           svn_repos_authz_func_t authz_read_func,
+           void *authz_read_baton,
+           apr_hash_t *changed_paths,
+           apr_pool_t *result_pool,
+           apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_hash_index_t *hi;
+  apr_hash_t *dirents;
+  apr_hash_t *props = NULL;
+  apr_array_header_t *children = NULL;
+
+  SVN_ERR(svn_fs_node_proplist(&props, target_root, repos_relpath,
+                               scratch_pool));
+
+  SVN_ERR(svn_editor_add_directory(editor, repos_relpath, children,
+                                   props, SVN_INVALID_REVNUM));
+
+  /* We have to get the dirents from the source path, not the target,
+     because we want nested copies from *readable* paths to be handled by
+     path_driver_cb_func, not add_subdir (in order to preserve history). */
+  SVN_ERR(svn_fs_dir_entries(&dirents, source_root, source_fspath,
+                             scratch_pool));
+
+  for (hi = apr_hash_first(scratch_pool, dirents); hi; hi = apr_hash_next(hi))
+    {
+      svn_fs_path_change2_t *change;
+      svn_boolean_t readable = TRUE;
+      svn_fs_dirent_t *dent = svn__apr_hash_index_val(hi);
+      const char *copyfrom_path = NULL;
+      svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
+      const char *child_relpath;
+
+      svn_pool_clear(iterpool);
+
+      child_relpath = svn_relpath_join(repos_relpath, dent->name, iterpool);
+
+      /* If a file or subdirectory of the copied directory is listed as a
+         changed path (because it was modified after the copy but before the
+         commit), we remove it from the changed_paths hash so that future
+         calls to path_driver_cb_func will ignore it. */
+      change = apr_hash_get(changed_paths, child_relpath, APR_HASH_KEY_STRING);
+      if (change)
+        {
+          apr_hash_set(changed_paths, child_relpath, APR_HASH_KEY_STRING,
+                       NULL);
+
+          /* If it's a delete, skip this entry. */
+          if (change->change_kind == svn_fs_path_change_delete)
+            continue;
+
+          /* If it's a replacement, check for copyfrom info (if we
+             don't have it already. */
+          if (change->change_kind == svn_fs_path_change_replace)
+            {
+              if (! change->copyfrom_known)
+                {
+                  SVN_ERR(svn_fs_copied_from(&change->copyfrom_rev,
+                                             &change->copyfrom_path,
+                                             target_root, child_relpath,
+                                             result_pool));
+                  change->copyfrom_known = TRUE;
+                }
+              copyfrom_path = change->copyfrom_path;
+              copyfrom_rev = change->copyfrom_rev;
+            }
+        }
+
+      if (authz_read_func)
+        SVN_ERR(authz_read_func(&readable, target_root, child_relpath,
+                                authz_read_baton, iterpool));
+
+      if (! readable)
+        continue;
+
+      if (dent->kind == svn_node_dir)
+        {
+          svn_fs_root_t *new_source_root;
+          const char *new_source_fspath;
+
+          if (copyfrom_path)
+            {
+              svn_fs_t *fs = svn_fs_root_fs(source_root);
+              SVN_ERR(svn_fs_revision_root(&new_source_root, fs,
+                                           copyfrom_rev, result_pool));
+              new_source_fspath = copyfrom_path;
+            }
+          else
+            {
+              new_source_root = source_root;
+              new_source_fspath = svn_fspath__join(source_fspath, dent->name,
+                                                   iterpool);
+            }
+
+          /* ### authz considerations?
+           *
+           * I think not; when path_driver_cb_func() calls add_subdir(), it
+           * passes SOURCE_ROOT and SOURCE_FSPATH that are unreadable.
+           */
+          if (change && change->change_kind == svn_fs_path_change_replace
+              && copyfrom_path == NULL)
+            {
+              SVN_ERR(svn_editor_add_directory(editor, child_relpath,
+                                               children, props,
+                                               SVN_INVALID_REVNUM));
+            }
+          else
+            {
+              SVN_ERR(add_subdir(new_source_root, target_root,
+                                 editor, child_relpath,
+                                 new_source_fspath,
+                                 authz_read_func, authz_read_baton,
+                                 changed_paths, result_pool, iterpool));
+            }
+        }
+      else if (dent->kind == svn_node_file)
+        {
+          svn_checksum_t *checksum;
+          svn_stream_t *contents;
+
+          SVN_ERR(svn_fs_node_proplist(&props, target_root,
+                                       child_relpath, iterpool));
+
+          SVN_ERR(svn_fs_file_contents(&contents, target_root,
+                                       child_relpath, iterpool));
+
+          SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1,
+                                       target_root,
+                                       child_relpath, TRUE, iterpool));
+
+          SVN_ERR(svn_editor_add_file(editor, child_relpath, checksum,
+                                      contents, props, SVN_INVALID_REVNUM));
+        }
+      else
+        SVN_ERR_MALFUNCTION();
+    }
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+#endif
+
+static svn_error_t *
+replay_node(svn_fs_root_t *root,
+            const char *repos_relpath,
+            svn_editor_t *editor,
+            svn_revnum_t low_water_mark,
+            const char *base_repos_relpath,
+            apr_array_header_t *copies,
+            apr_hash_t *changed_paths,
+            svn_repos_authz_func_t authz_read_func,
+            void *authz_read_baton,
+            apr_pool_t *result_pool,
+            apr_pool_t *scratch_pool)
+#ifndef USE_EV2_IMPL
+{
+  SVN__NOT_IMPLEMENTED();
+}
+#else
+{
+  svn_fs_path_change2_t *change;
+  svn_boolean_t do_add = FALSE;
+  svn_boolean_t do_delete = FALSE;
+  svn_revnum_t copyfrom_rev;
+  const char *copyfrom_path;
+  svn_revnum_t replaces_rev;
+
+  /* First, flush the copies stack so it only contains ancestors of path. */
+  while (copies->nelts > 0
+         && (svn_relpath_skip_ancestor(APR_ARRAY_IDX(copies,
+                                                    copies->nelts - 1,
+                                                     struct copy_info *)->path,
+                                       repos_relpath) == NULL) )
+    apr_array_pop(copies);
+
+  change = apr_hash_get(changed_paths, repos_relpath, APR_HASH_KEY_STRING);
+  if (! change)
+    {
+      /* This can only happen if the path was removed from changed_paths
+         by an earlier call to add_subdir, which means the path was already
+         handled and we should simply ignore it. */
+      return SVN_NO_ERROR;
+    }
+  switch (change->change_kind)
+    {
+    case svn_fs_path_change_add:
+      do_add = TRUE;
+      break;
+
+    case svn_fs_path_change_delete:
+      do_delete = TRUE;
+      break;
+
+    case svn_fs_path_change_replace:
+      do_add = TRUE;
+      do_delete = TRUE;
+      break;
+
+    case svn_fs_path_change_modify:
+    default:
+      /* do nothing */
+      break;
+    }
+
+  /* Handle any deletions. */
+  if (do_delete && ! do_add)
+    {
+      svn_boolean_t readable;
+
+      /* Issue #4121: delete under under a copy, of a path that was unreadable
+         at its pre-copy location. */
+      SVN_ERR(was_readable(&readable, root, repos_relpath, copies,
+                            authz_read_func, authz_read_baton,
+                            scratch_pool, scratch_pool));
+      if (readable)
+        SVN_ERR(svn_editor_delete(editor, repos_relpath, SVN_INVALID_REVNUM));
+
+      return SVN_NO_ERROR;
+    }
+
+  /* Handle replacements. */
+  if (do_delete && do_add)
+    replaces_rev = svn_fs_revision_root_revision(root);
+  else
+    replaces_rev = SVN_INVALID_REVNUM;
+
+  /* Fetch the node kind if it makes sense to do so. */
+  if (! do_delete || do_add)
+    {
+      if (change->node_kind == svn_node_unknown)
+        SVN_ERR(svn_fs_check_path(&(change->node_kind), root, repos_relpath,
+                                  scratch_pool));
+      if ((change->node_kind != svn_node_dir) &&
+          (change->node_kind != svn_node_file))
+        return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
+                                 _("Filesystem path '%s' is neither a file "
+                                   "nor a directory"), repos_relpath);
+    }
+
+  /* Handle any adds/opens. */
+  if (do_add)
+    {
+      svn_boolean_t src_readable;
+      svn_fs_root_t *copyfrom_root;
+
+      /* Was this node copied? */
+      SVN_ERR(fill_copyfrom(&copyfrom_root, &copyfrom_path, &copyfrom_rev,
+                            &src_readable, root, change,
+                            authz_read_func, authz_read_baton,
+                            repos_relpath, scratch_pool, scratch_pool));
+
+      /* If we have a copyfrom path, and we can't read it or we're just
+         ignoring it, or the copyfrom rev is prior to the low water mark
+         then we just null them out and do a raw add with no history at
+         all. */
+      if (copyfrom_path
+          && ((! src_readable)
+              || (svn_relpath_skip_ancestor(base_repos_relpath,
+                                            copyfrom_path + 1) == NULL)
+              || (low_water_mark > copyfrom_rev)))
+        {
+          copyfrom_path = NULL;
+          copyfrom_rev = SVN_INVALID_REVNUM;
+        }
+
+      /* Do the right thing based on the path KIND. */
+      if (change->node_kind == svn_node_dir)
+        {
+          /* If this is a copy, but we can't represent it as such,
+             then we just do a recursive add of the source path
+             contents. */
+          if (change->copyfrom_path && ! copyfrom_path)
+            {
+              SVN_ERR(add_subdir(copyfrom_root, root, editor,
+                                 repos_relpath, change->copyfrom_path,
+                                 authz_read_func, authz_read_baton,
+                                 changed_paths, result_pool, scratch_pool));
+            }
+          else
+            {
+              if (copyfrom_path)
+                {
+                  if (copyfrom_path[0] == '/')
+                    ++copyfrom_path;
+                  SVN_ERR(svn_editor_copy(editor, copyfrom_path, copyfrom_rev,
+                                          repos_relpath, replaces_rev));
+                }
+              else
+                {
+                  apr_array_header_t *children;
+                  apr_hash_t *props;
+                  apr_hash_t *dirents;
+
+                  SVN_ERR(svn_fs_dir_entries(&dirents, root, repos_relpath,
+                                             scratch_pool));
+                  SVN_ERR(svn_hash_keys(&children, dirents, scratch_pool));
+
+                  SVN_ERR(svn_fs_node_proplist(&props, root, repos_relpath,
+                                               scratch_pool));
+
+                  SVN_ERR(svn_editor_add_directory(editor, repos_relpath,
+                                                   children, props,
+                                                   replaces_rev));
+                }
+            }
+        }
+      else
+        {
+          if (copyfrom_path)
+            {
+              if (copyfrom_path[0] == '/')
+                ++copyfrom_path;
+              SVN_ERR(svn_editor_copy(editor, copyfrom_path, copyfrom_rev,
+                                      repos_relpath, replaces_rev));
+            }
+          else
+            {
+              apr_hash_t *props;
+              svn_checksum_t *checksum;
+              svn_stream_t *contents;
+
+              SVN_ERR(svn_fs_node_proplist(&props, root, repos_relpath,
+                                           scratch_pool));
+
+              SVN_ERR(svn_fs_file_contents(&contents, root, repos_relpath,
+                                           scratch_pool));
+
+              SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1, root,
+                                           repos_relpath, TRUE, scratch_pool));
+
+              SVN_ERR(svn_editor_add_file(editor, repos_relpath, checksum,
+                                          contents, props, replaces_rev));
+            }
+        }
+
+      /* If we represent this as a copy... */
+      if (copyfrom_path)
+        {
+          /* If it is a directory, make sure descendants get the correct
+             delta source by remembering that we are operating inside a
+             (possibly nested) copy operation. */
+          if (change->node_kind == svn_node_dir)
+            {
+              struct copy_info *info = apr_pcalloc(result_pool, sizeof(*info));
+
+              info->path = apr_pstrdup(result_pool, repos_relpath);
+              info->copyfrom_path = apr_pstrdup(result_pool, copyfrom_path);
+              info->copyfrom_rev = copyfrom_rev;
+
+              APR_ARRAY_PUSH(copies, struct copy_info *) = info;
+            }
+        }
+      else
+        /* Else, we are an add without history... */
+        {
+          /* If an ancestor is added with history, we need to forget about
+             that here, go on with life and repeat all the mistakes of our
+             past... */
+          if (change->node_kind == svn_node_dir && copies->nelts > 0)
+            {
+              struct copy_info *info = apr_pcalloc(result_pool, sizeof(*info));
+
+              info->path = apr_pstrdup(result_pool, repos_relpath);
+              info->copyfrom_path = NULL;
+              info->copyfrom_rev = SVN_INVALID_REVNUM;
+
+              APR_ARRAY_PUSH(copies, struct copy_info *) = info;
+            }
+        }
+    }
+  else if (! do_delete)
+    {
+      /* If we are inside an add with history, we need to adjust the
+         delta source. */
+      if (copies->nelts > 0)
+        {
+          struct copy_info *info = APR_ARRAY_IDX(copies,
+                                                 copies->nelts - 1,
+                                                 struct copy_info *);
+          if (info->copyfrom_path)
+            {
+              const char *relpath = svn_relpath_skip_ancestor(info->path,
+                                                              repos_relpath);
+              SVN_ERR_ASSERT(relpath && *relpath);
+              repos_relpath = svn_relpath_join(info->copyfrom_path,
+                                               relpath, scratch_pool);
+            }
+        }
+    }
+
+  if (! do_delete && !do_add)
+    {
+      apr_hash_t *props = NULL;
+
+      /* Is this a copy that was downgraded to a raw add?  (If so,
+         we'll need to transmit properties and file contents and such
+         for it regardless of what the CHANGE structure's text_mod
+         and prop_mod flags say.)  */
+      svn_boolean_t downgraded_copy = (change->copyfrom_known
+                                       && change->copyfrom_path
+                                       && (! copyfrom_path));
+
+      /* Handle property modifications. */
+      if (change->prop_mod || downgraded_copy)
+        {
+          SVN_ERR(svn_fs_node_proplist(&props, root, repos_relpath,
+                                       scratch_pool));
+        }
+
+      /* Handle textual modifications. */
+      if (change->node_kind == svn_node_file
+          && (change->text_mod || change->prop_mod || downgraded_copy))
+        {
+          svn_checksum_t *checksum;
+          svn_stream_t *contents;
+
+          SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1,
+                                       root, repos_relpath, TRUE,
+                                       scratch_pool));
+
+          SVN_ERR(svn_fs_file_contents(&contents, root, repos_relpath,
+                                       scratch_pool));
+
+          SVN_ERR(svn_editor_alter_file(editor, repos_relpath,
+                                        SVN_INVALID_REVNUM, props, checksum,
+                                        contents));
+        }
+
+      if (change->node_kind == svn_node_dir
+          && (change->prop_mod || downgraded_copy))
+        {
+          apr_array_header_t *children = NULL;
+
+          SVN_ERR(svn_editor_alter_directory(editor, repos_relpath,
+                                             SVN_INVALID_REVNUM, children,
+                                             props));
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+#endif
+
+svn_error_t *
+svn_repos__replay_ev2(svn_fs_root_t *root,
+                      const char *base_repos_relpath,
+                      svn_revnum_t low_water_mark,
+                      svn_editor_t *editor,
+                      svn_repos_authz_func_t authz_read_func,
+                      void *authz_read_baton,
+                      apr_pool_t *scratch_pool)
+{
+  apr_hash_t *fs_changes;
+  apr_hash_t *changed_paths;
+  apr_hash_index_t *hi;
+  apr_array_header_t *paths;
+  apr_array_header_t *copies;
+  apr_pool_t *iterpool;
+  svn_error_t *err = SVN_NO_ERROR;
+  int i;
+
+  SVN_ERR_ASSERT(!svn_dirent_is_absolute(base_repos_relpath));
+
+  /* Special-case r0, which we know is an empty revision; if we don't
+     special-case it we might end up trying to compare it to "r-1". */
+  if (svn_fs_is_revision_root(root)
+        && svn_fs_revision_root_revision(root) == 0)
+    {
+      return SVN_NO_ERROR;
+    }
+
+  /* Fetch the paths changed under ROOT. */
+  SVN_ERR(svn_fs_paths_changed2(&fs_changes, root, scratch_pool));
+
+  /* Make an array from the keys of our CHANGED_PATHS hash, and copy
+     the values into a new hash whose keys have no leading slashes. */
+  paths = apr_array_make(scratch_pool, apr_hash_count(fs_changes),
+                         sizeof(const char *));
+  changed_paths = apr_hash_make(scratch_pool);
+  for (hi = apr_hash_first(scratch_pool, fs_changes); hi;
+        hi = apr_hash_next(hi))
+    {
+      const void *key;
+      void *val;
+      apr_ssize_t keylen;
+      const char *path;
+      svn_fs_path_change2_t *change;
+      svn_boolean_t allowed = TRUE;
+
+      apr_hash_this(hi, &key, &keylen, &val);
+      path = key;
+      change = val;
+
+      if (authz_read_func)
+        SVN_ERR(authz_read_func(&allowed, root, path, authz_read_baton,
+                                scratch_pool));
+
+      if (allowed)
+        {
+          if (path[0] == '/')
+            {
+              path++;
+              keylen--;
+            }
+
+          /* If the base_path doesn't match the top directory of this path
+             we don't want anything to do with it... */
+          if (svn_relpath_skip_ancestor(base_repos_relpath, path) != NULL)
+            {
+              APR_ARRAY_PUSH(paths, const char *) = path;
+              apr_hash_set(changed_paths, path, keylen, change);
+            }
+          /* ...unless this was a change to one of the parent directories of
+             base_path. */
+          else if (svn_relpath_skip_ancestor(path, base_repos_relpath) != NULL)
+            {
+              APR_ARRAY_PUSH(paths, const char *) = path;
+              apr_hash_set(changed_paths, path, keylen, change);
+            }
+        }
+    }
+
+  /* If we were not given a low water mark, assume that everything is there,
+     all the way back to revision 0. */
+  if (! SVN_IS_VALID_REVNUM(low_water_mark))
+    low_water_mark = 0;
+
+  copies = apr_array_make(scratch_pool, 4, sizeof(struct copy_info *));
+
+  /* Sort the paths.  Although not strictly required by the API, this has
+     the pleasant side effect of maintaining a consistent ordering of
+     dumpfile contents. */
+  qsort(paths->elts, paths->nelts, paths->elt_size, svn_sort_compare_paths);
+
+  /* Now actually handle the various paths. */
+  iterpool = svn_pool_create(scratch_pool);
+  for (i = 0; i < paths->nelts; i++)
+    {
+      const char *repos_relpath = APR_ARRAY_IDX(paths, i, const char *);
+
+      svn_pool_clear(iterpool);
+      err = replay_node(root, repos_relpath, editor, low_water_mark,
+                        base_repos_relpath, copies, changed_paths,
+                        authz_read_func, authz_read_baton,
+                        scratch_pool, iterpool);
+      if (err)
+        break;
+    }
+
+  if (err)
+    return svn_error_compose_create(err, svn_editor_abort(editor));
+  else
+    SVN_ERR(svn_editor_complete(editor));
+
+  svn_pool_destroy(iterpool);
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c Tue Jun 26 19:26:49 2012
@@ -36,6 +36,7 @@
 #include "svn_version.h"
 
 #include "private/svn_repos_private.h"
+#include "private/svn_subr_private.h"
 #include "svn_private_config.h" /* for SVN_TEMPLATE_ROOT_DIR */
 
 #include "repos.h"
@@ -1184,9 +1185,9 @@ create_repos_structure(svn_repos_t *repo
   /* Write the top-level README file. */
   {
     const char * const readme_header =
-      "This is a Subversion repository; use the 'svnadmin' tool to examine"  NL
-      "it.  Do not add, delete, or modify files here unless you know how"    NL
-      "to avoid corrupting the repository."                                  NL
+      "This is a Subversion repository; use the 'svnadmin' and 'svnlook' "   NL
+      "tools to examine it.  Do not add, delete, or modify files here "      NL
+      "unless you know how to avoid corrupting the repository."              NL
       ""                                                                     NL;
     const char * const readme_bdb_insert =
       "The directory \"" SVN_REPOS__DB_DIR "\" contains a Berkeley DB environment."  NL

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/adler32.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/adler32.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/adler32.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/adler32.c Tue Jun 26 19:26:49 2012
@@ -61,7 +61,9 @@ svn__adler32(apr_uint32_t checksum, cons
        * optimized code. Also, new zlib versions will come with
        * SIMD code for x86 and x64.
        */
-      return adler32(checksum, (const Bytef *)data, len);
+      return (apr_uint32_t)adler32(checksum,
+                                   (const Bytef *)data,
+                                   (uInt)len);
     }
   else
     {

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/auth.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/auth.c Tue Jun 26 19:26:49 2012
@@ -441,11 +441,12 @@ svn_auth_get_platform_specific_provider(
             {
               svn_version_func_t version_function
                 = version_function_symbol;
-              const svn_version_checklist_t check_list[] =
-                {
-                  { library_label, version_function },
-                  { NULL, NULL }
-                };
+              svn_version_checklist_t check_list[2];
+
+              check_list[0].label = library_label;
+              check_list[0].version_query = version_function;
+              check_list[1].label = NULL;
+              check_list[1].version_query = NULL;
               SVN_ERR(svn_ver_check_list(svn_subr_version(), check_list));
             }
           if (apr_dso_sym(&provider_function_symbol,

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/base64.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/base64.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/base64.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/base64.c Tue Jun 26 19:26:49 2012
@@ -306,9 +306,9 @@ struct decode_baton {
 static APR_INLINE void
 decode_group(const unsigned char *in, char *out)
 {
-  out[0] = (in[0] << 2) | (in[1] >> 4);
-  out[1] = ((in[1] & 0xf) << 4) | (in[2] >> 2);
-  out[2] = ((in[2] & 0x3) << 6) | in[3];
+  out[0] = (char)((in[0] << 2) | (in[1] >> 4));
+  out[1] = (char)(((in[1] & 0xf) << 4) | (in[2] >> 2));
+  out[2] = (char)(((in[2] & 0x3) << 6) | in[3]);
 }
 
 /* Lookup table for base64 characters; reverse_base64[ch] gives a
@@ -415,9 +415,9 @@ decode_bytes(svn_stringbuf_t *str, const
      (*inbuflen+len) is encoded data length
      (*inbuflen+len)/4 is the number of complete 4-bytes sets
      (*inbuflen+len)/4*3 is the number of decoded bytes
-     (*inbuflen+len)/4*3+1 is the number of decoded bytes plus a null
+     svn_stringbuf_ensure will add an additional byte for the terminating 0.
   */
-  svn_stringbuf_ensure(str, str->len + ((*inbuflen + len) / 4) * 3 + 1);
+  svn_stringbuf_ensure(str, str->len + ((*inbuflen + len) / 4) * 3);
 
   while ( !*done && p < end )
     {

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/cache-membuffer.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/cache-membuffer.c Tue Jun 26 19:26:49 2012
@@ -23,6 +23,8 @@
 
 #include <assert.h>
 #include <apr_md5.h>
+#include <apr_thread_rwlock.h>
+
 #include "svn_pools.h"
 #include "svn_checksum.h"
 #include "md5.h"
@@ -436,11 +438,13 @@ struct svn_membuffer_t
    */
   apr_uint64_t total_hits;
 
+#if APR_HAS_THREADS
   /* A lock for intra-process synchronization to the cache, or NULL if
    * the cache's creator doesn't feel the cache needs to be
    * thread-safe.
    */
-  svn_mutex__t *mutex;
+  apr_thread_rwlock_t *lock;
+#endif
 };
 
 /* Align integer VALUE to the next ITEM_ALIGNMENT boundary.
@@ -451,6 +455,76 @@ struct svn_membuffer_t
  */
 #define ALIGN_POINTER(pointer) ((void*)ALIGN_VALUE((apr_size_t)(char*)(pointer)))
 
+/* If locking is supported for CACHE, aquire a read lock for it.
+ */
+static svn_error_t *
+read_lock_cache(svn_membuffer_t *cache)
+{
+#if APR_HAS_THREADS
+  if (cache->lock)
+  {
+    apr_status_t status = apr_thread_rwlock_rdlock(cache->lock);
+    if (status)
+      return svn_error_wrap_apr(status, _("Can't lock cache mutex"));
+  }
+#endif
+  return SVN_NO_ERROR;
+}
+
+/* If locking is supported for CACHE, aquire a write lock for it.
+ */
+static svn_error_t *
+write_lock_cache(svn_membuffer_t *cache)
+{
+#if APR_HAS_THREADS
+  if (cache->lock)
+  {
+    apr_status_t status = apr_thread_rwlock_wrlock(cache->lock);
+    if (status)
+      return svn_error_wrap_apr(status, _("Can't write-lock cache mutex"));
+  }
+#endif
+  return SVN_NO_ERROR;
+}
+
+/* If locking is supported for CACHE, release the current lock
+ * (read or write).
+ */
+static svn_error_t *
+unlock_cache(svn_membuffer_t *cache, svn_error_t *err)
+{
+#if APR_HAS_THREADS
+  if (cache->lock)
+  {
+    apr_status_t status = apr_thread_rwlock_unlock(cache->lock);
+    if (err)
+      return err;
+
+    if (status)
+      return svn_error_wrap_apr(status, _("Can't unlock cache mutex"));
+  }
+#endif
+  return err;
+}
+
+/* If supported, guard the execution of EXPR with a read lock to cache.
+ * Macro has been modelled after SVN_MUTEX__WITH_LOCK.
+ */
+#define WITH_READ_LOCK(cache, expr)         \
+do {                                        \
+  SVN_ERR(read_lock_cache(cache));          \
+  SVN_ERR(unlock_cache(cache, (expr)));     \
+} while (0)
+
+/* If supported, guard the execution of EXPR with a write lock to cache.
+ * Macro has been modelled after SVN_MUTEX__WITH_LOCK.
+ */
+#define WITH_WRITE_LOCK(cache, expr)        \
+do {                                        \
+  SVN_ERR(write_lock_cache(cache));         \
+  SVN_ERR(unlock_cache(cache, (expr)));     \
+} while (0)
+
 /* Resolve a dictionary entry reference, i.e. return the entry
  * for the given IDX.
  */
@@ -626,9 +700,11 @@ let_entry_age(svn_membuffer_t *cache, en
 static APR_INLINE unsigned char
 is_group_initialized(svn_membuffer_t *cache, apr_uint32_t group_index)
 {
-  unsigned char flags = cache->group_initialized
-                          [group_index / (8 * GROUP_INIT_GRANULARITY)];
-  unsigned char bit_mask = 1 << ((group_index / GROUP_INIT_GRANULARITY) % 8);
+  unsigned char flags
+    = cache->group_initialized[group_index / (8 * GROUP_INIT_GRANULARITY)];
+  unsigned char bit_mask
+    = (unsigned char)(1 << ((group_index / GROUP_INIT_GRANULARITY) % 8));
+
   return flags & bit_mask;
 }
 
@@ -652,7 +728,8 @@ initialize_group(svn_membuffer_t *cache,
         cache->directory[i][j].offset = NO_OFFSET;
 
   /* set the "initialized" bit for these groups */
-  bit_mask = 1 << ((group_index / GROUP_INIT_GRANULARITY) % 8);
+  bit_mask
+    = (unsigned char)(1 << ((group_index / GROUP_INIT_GRANULARITY) % 8));
   cache->group_initialized[group_index / (8 * GROUP_INIT_GRANULARITY)]
     |= bit_mask;
 }
@@ -1001,11 +1078,10 @@ svn_cache__membuffer_cache_create(svn_me
    * Note, that this limit could only be exceeded in a very
    * theoretical setup with about 1EB of cache.
    */
-  group_count = directory_size / sizeof(entry_group_t);
-  if (group_count >= (APR_UINT32_MAX / GROUP_SIZE))
-    {
-      group_count = (APR_UINT32_MAX / GROUP_SIZE) - 1;
-    }
+  group_count = directory_size / sizeof(entry_group_t)
+                    >= (APR_UINT32_MAX / GROUP_SIZE)
+              ? (APR_UINT32_MAX / GROUP_SIZE) - 1
+              : (apr_uint32_t)(directory_size / sizeof(entry_group_t));
 
   group_init_size = 1 + group_count / (8 * GROUP_INIT_GRANULARITY);
   for (seg = 0; seg < segment_count; ++seg)
@@ -1048,10 +1124,20 @@ svn_cache__membuffer_cache_create(svn_me
           return svn_error_wrap_apr(APR_ENOMEM, _("OOM"));
         }
 
+#if APR_HAS_THREADS
       /* A lock for intra-process synchronization to the cache, or NULL if
        * the cache's creator doesn't feel the cache needs to be
-       * thread-safe. */
-      SVN_ERR(svn_mutex__init(&c[seg].mutex, thread_safe, pool));
+       * thread-safe.
+       */
+      c[seg].lock = NULL;
+      if (thread_safe)
+        {
+          apr_status_t status =
+              apr_thread_rwlock_create(&(c[seg].lock), pool);
+          if (status)
+            return svn_error_wrap_apr(status, _("Can't create cache mutex"));
+        }
+#endif
     }
 
   /* done here
@@ -1156,14 +1242,14 @@ membuffer_cache_set(svn_membuffer_t *cac
 
   /* The actual cache data access needs to sync'ed
    */
-  SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       membuffer_cache_set_internal(cache,
-                                                    key,
-                                                    group_index,
-                                                    buffer,
-                                                    size,
-                                                    DEBUG_CACHE_MEMBUFFER_TAG
-                                                    scratch_pool));
+  WITH_WRITE_LOCK(cache,
+                  membuffer_cache_set_internal(cache,
+                                               key,
+                                               group_index,
+                                               buffer,
+                                               size,
+                                               DEBUG_CACHE_MEMBUFFER_TAG
+                                               scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -1252,14 +1338,14 @@ membuffer_cache_get(svn_membuffer_t *cac
   /* find the entry group that will hold the key.
    */
   group_index = get_group_index(&cache, key);
-  SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       membuffer_cache_get_internal(cache,
-                                                    group_index,
-                                                    key,
-                                                    &buffer,
-                                                    &size,
-                                                    DEBUG_CACHE_MEMBUFFER_TAG
-                                                    result_pool));
+  WITH_READ_LOCK(cache,
+                 membuffer_cache_get_internal(cache,
+                                              group_index,
+                                              key,
+                                              &buffer,
+                                              &size,
+                                              DEBUG_CACHE_MEMBUFFER_TAG
+                                              result_pool));
 
   /* re-construct the original data object from its serialized form.
    */
@@ -1355,11 +1441,11 @@ membuffer_cache_get_partial(svn_membuffe
 {
   apr_uint32_t group_index = get_group_index(&cache, key);
 
-  SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       membuffer_cache_get_partial_internal
-                           (cache, group_index, key, item, found,
-                            deserializer, baton, DEBUG_CACHE_MEMBUFFER_TAG
-                            result_pool));
+  WITH_READ_LOCK(cache,
+                 membuffer_cache_get_partial_internal
+                     (cache, group_index, key, item, found,
+                      deserializer, baton, DEBUG_CACHE_MEMBUFFER_TAG
+                      result_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1486,11 +1572,11 @@ membuffer_cache_set_partial(svn_membuffe
   /* cache item lookup
    */
   apr_uint32_t group_index = get_group_index(&cache, key);
-  SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       membuffer_cache_set_partial_internal
-                           (cache, group_index, key, func, baton,
-                            DEBUG_CACHE_MEMBUFFER_TAG_ARG
-                            scratch_pool));
+  WITH_WRITE_LOCK(cache,
+                  membuffer_cache_set_partial_internal
+                     (cache, group_index, key, func, baton,
+                      DEBUG_CACHE_MEMBUFFER_TAG_ARG
+                      scratch_pool));
 
   /* done here -> unlock the cache
    */
@@ -1825,8 +1911,8 @@ svn_membuffer_cache_get_info(void *cache
   for (i = 0; i < cache->membuffer->segment_count; ++i)
     {
       svn_membuffer_t *segment = cache->membuffer + i;
-      SVN_MUTEX__WITH_LOCK(segment->mutex,
-                           svn_membuffer_get_segment_info(segment, info));
+      WITH_READ_LOCK(segment,
+                     svn_membuffer_get_segment_info(segment, info));
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/cache-memcache.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/cache-memcache.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/cache-memcache.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/cache-memcache.c Tue Jun 26 19:26:49 2012
@@ -29,6 +29,7 @@
 
 #include "svn_private_config.h"
 #include "private/svn_cache.h"
+#include "private/svn_dep_compat.h"
 
 #include "cache.h"
 
@@ -527,7 +528,7 @@ svn_cache__make_memcache_from_config(svn
                                     svn_config_t *config,
                                     apr_pool_t *pool)
 {
-  apr_uint16_t server_count;
+  int server_count;
   apr_pool_t *subpool = svn_pool_create(pool);
 
   server_count =
@@ -542,12 +543,15 @@ svn_cache__make_memcache_from_config(svn
       return SVN_NO_ERROR;
     }
 
+  if (server_count > APR_INT16_MAX)
+    return svn_error_create(SVN_ERR_TOO_MANY_MEMCACHED_SERVERS, NULL, NULL);
+
 #ifdef SVN_HAVE_MEMCACHE
   {
     struct ams_baton b;
     svn_memcache_t *memcache = apr_pcalloc(pool, sizeof(*memcache));
     apr_status_t apr_err = apr_memcache_create(pool,
-                                               server_count,
+                                               (apr_uint16_t)server_count,
                                                0, /* flags */
                                                &(memcache->c));
     if (apr_err != APR_SUCCESS)

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/cache.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/cache.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/cache.c Tue Jun 26 19:26:49 2012
@@ -212,14 +212,14 @@ svn_cache__format_info(const svn_cache__
   enum { _1MB = 1024 * 1024 };
 
   apr_uint64_t misses = info->gets - info->hits;
-  double hit_rate = (100.0 * info->hits)
-                  / (info->gets ? info->gets : 1);
-  double write_rate = (100.0 * info->sets)
-                    / (misses ? misses : 1);
-  double data_usage_rate = (100.0 * info->used_size)
-                         / (info->data_size ? info->data_size : 1);
-  double data_entry_rate = (100.0 * info->used_entries)
-                         / (info->total_entries ? info->total_entries : 1);
+  double hit_rate = (100.0 * (double)info->hits)
+                  / (double)(info->gets ? info->gets : 1);
+  double write_rate = (100.0 * (double)info->sets)
+                    / (double)(misses ? misses : 1);
+  double data_usage_rate = (100.0 * (double)info->used_size)
+                         / (double)(info->data_size ? info->data_size : 1);
+  double data_entry_rate = (100.0 * (double)info->used_entries)
+                 / (double)(info->total_entries ? info->total_entries : 1);
 
   return svn_string_createf(result_pool,
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/checksum.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/checksum.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/checksum.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/checksum.c Tue Jun 26 19:26:49 2012
@@ -276,8 +276,8 @@ svn_checksum_parse_hex(svn_checksum_t **
       if (x1 == (char)-1 || x2 == (char)-1)
         return svn_error_create(SVN_ERR_BAD_CHECKSUM_PARSE, NULL, NULL);
 
-      digest[i] = (x1 << 4) | x2;
-      is_nonzero |= (x1 << 4) | x2;
+      digest[i] = (char)((x1 << 4) | x2);
+      is_nonzero |= (char)((x1 << 4) | x2);
     }
 
   if (!is_nonzero)