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 [7/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_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_repos/load.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_repos/load.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_repos/load.c Thu Nov  4 20:48:21 2010
@@ -43,73 +43,6 @@
 
 /*----------------------------------------------------------------------*/
 
-/** Batons used herein **/
-
-struct parse_baton
-{
-  svn_repos_t *repos;
-  svn_fs_t *fs;
-
-  svn_boolean_t use_history;
-  svn_boolean_t use_pre_commit_hook;
-  svn_boolean_t use_post_commit_hook;
-  enum svn_repos_load_uuid uuid_action;
-  const char *parent_dir;
-  svn_repos_notify_func_t notify_func;
-  void *notify_baton;
-  svn_repos_notify_t *notify;
-  apr_pool_t *pool;
-
-  /* A hash mapping copy-from revisions and mergeinfo range revisions
-     (svn_revnum_t *) in the dump stream to their corresponding revisions
-     (svn_revnum_t *) in the loaded repository.  The hash and its
-     contents are allocated in POOL. */
-  apr_hash_t *rev_map;
-
-  /* The most recent (youngest) revision from the dump stream mapped in
-     REV_MAP.  If no revisions have been mapped yet, this is set to
-     SVN_INVALID_REVNUM. */
-  svn_revnum_t last_rev_mapped;
-
-  /* The oldest old revision loaded from the dump stream.  If no revisions
-     have been loaded yet, this is set to SVN_INVALID_REVNUM. */
-  svn_revnum_t oldest_old_rev;
-};
-
-struct revision_baton
-{
-  svn_revnum_t rev;
-
-  svn_fs_txn_t *txn;
-  svn_fs_root_t *txn_root;
-
-  const svn_string_t *datestamp;
-
-  apr_int32_t rev_offset;
-
-  struct parse_baton *pb;
-  apr_pool_t *pool;
-};
-
-struct node_baton
-{
-  const char *path;
-  svn_node_kind_t kind;
-  enum svn_node_action action;
-  svn_checksum_t *base_checksum;        /* null, if not available */
-  svn_checksum_t *result_checksum;      /* null, if not available */
-  svn_checksum_t *copy_source_checksum; /* null, if not available */
-
-  svn_revnum_t copyfrom_rev;
-  const char *copyfrom_path;
-
-  struct revision_baton *rb;
-  apr_pool_t *pool;
-};
-
-
-/*----------------------------------------------------------------------*/
-
 /** The parser and related helper funcs **/
 
 
@@ -236,170 +169,6 @@ read_key_or_val(char **pbuf,
 }
 
 
-/* Prepend the mergeinfo source paths in MERGEINFO_ORIG with PARENT_DIR, and
-   return it in *MERGEINFO_VAL. */
-static svn_error_t *
-prefix_mergeinfo_paths(svn_string_t **mergeinfo_val,
-                       const svn_string_t *mergeinfo_orig,
-                       const char *parent_dir,
-                       apr_pool_t *pool)
-{
-  apr_hash_t *prefixed_mergeinfo, *mergeinfo;
-  apr_hash_index_t *hi;
-  void *rangelist;
-
-  SVN_ERR(svn_mergeinfo_parse(&mergeinfo, mergeinfo_orig->data, pool));
-  prefixed_mergeinfo = apr_hash_make(pool);
-  for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
-    {
-      const void *key;
-      const char *path, *merge_source;
-
-      apr_hash_this(hi, &key, NULL, &rangelist);
-      merge_source = key;
-
-      /* The svn:mergeinfo property syntax demands absolute repository
-         paths, so prepend a leading slash if PARENT_DIR lacks one.  */
-      if (*parent_dir != '/')
-        path = svn_path_join_many(pool, "/", parent_dir,
-                                  merge_source + 1, NULL);
-      else
-        path = svn_path_join(parent_dir, merge_source + 1, pool);
-
-      apr_hash_set(prefixed_mergeinfo, path, APR_HASH_KEY_STRING, rangelist);
-    }
-  return svn_mergeinfo_to_string(mergeinfo_val, prefixed_mergeinfo, pool);
-}
-
-
-/* Examine the mergeinfo in INITIAL_VAL, renumber revisions in rangelists
-   as appropriate, and return the (possibly new) mergeinfo in *FINAL_VAL
-   (allocated from POOL). */
-static svn_error_t *
-renumber_mergeinfo_revs(svn_string_t **final_val,
-                        const svn_string_t *initial_val,
-                        struct revision_baton *rb,
-                        apr_pool_t *pool)
-{
-  apr_pool_t *subpool = svn_pool_create(pool);
-  svn_mergeinfo_t mergeinfo, predates_stream_mergeinfo;
-  svn_mergeinfo_t final_mergeinfo = apr_hash_make(subpool);
-  apr_hash_index_t *hi;
-
-  SVN_ERR(svn_mergeinfo_parse(&mergeinfo, initial_val->data, subpool));
-
-  /* Issue #3020
-     http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16
-     Remove mergeinfo older than the oldest revision in the dump stream
-     and adjust its revisions by the difference between the head rev of
-     the target repository and the current dump stream rev. */
-  if (rb->pb->oldest_old_rev > 1)
-    {
-      SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
-        &predates_stream_mergeinfo, mergeinfo,
-        rb->pb->oldest_old_rev - 1, 0,
-        TRUE, subpool, subpool));
-      SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
-        &mergeinfo, mergeinfo,
-        rb->pb->oldest_old_rev - 1, 0,
-        FALSE, subpool, subpool));
-      SVN_ERR(svn_mergeinfo__adjust_mergeinfo_rangelists(
-        &predates_stream_mergeinfo, predates_stream_mergeinfo,
-        -rb->rev_offset, subpool, subpool));
-    }
-  else
-    {
-      predates_stream_mergeinfo = NULL;
-    }
-
-  for (hi = apr_hash_first(subpool, mergeinfo); hi; hi = apr_hash_next(hi))
-    {
-      const char *merge_source;
-      apr_array_header_t *rangelist;
-      struct parse_baton *pb = rb->pb;
-      int i;
-      const void *key;
-      void *val;
-
-      apr_hash_this(hi, &key, NULL, &val);
-      merge_source = key;
-      rangelist = val;
-
-      /* Possibly renumber revisions in merge source's rangelist. */
-      for (i = 0; i < rangelist->nelts; i++)
-        {
-          svn_revnum_t *rev_from_map;
-          svn_merge_range_t *range = APR_ARRAY_IDX(rangelist, i,
-                                                   svn_merge_range_t *);
-          rev_from_map = apr_hash_get(pb->rev_map, &range->start,
-                                      sizeof(svn_revnum_t));
-          if (rev_from_map && SVN_IS_VALID_REVNUM(*rev_from_map))
-            {
-              range->start = *rev_from_map;
-            }
-          else if (range->start == pb->oldest_old_rev - 1)
-            {
-              /* Since the start revision of svn_merge_range_t are not
-                 inclusive there is one possible valid start revision that
-                 won't be found in the PB->REV_MAP mapping of load stream
-                 revsions to loaded revisions: The revision immediately
-                 preceeding the oldest revision from the load stream.
-                 This is a valid revision for mergeinfo, but not a valid
-                 copy from revision (which PB->REV_MAP also maps for) so it
-                 will never be in the mapping.
-
-                 If that is what we have here, then find the mapping for the
-                 oldest rev from the load stream and subtract 1 to get the
-                 renumbered, non-inclusive, start revision. */
-              rev_from_map = apr_hash_get(pb->rev_map, &pb->oldest_old_rev,
-                                          sizeof(svn_revnum_t));
-              if (rev_from_map && SVN_IS_VALID_REVNUM(*rev_from_map))
-                range->start = *rev_from_map - 1;
-            }
-          else
-            {
-              /* If we can't remap the start revision then don't even bother
-                 trying to remap the end revision.  It's possible we might
-                 actually succeed at the latter, which can result in invalid
-                 mergeinfo with a start rev > end rev.  If that gets into the
-                 repository then a world of bustage breaks loose anytime that
-                 bogus mergeinfo is parsed.  See
-                 http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16.
-                 */
-              continue;
-            }
-
-          rev_from_map = apr_hash_get(pb->rev_map, &range->end,
-                                      sizeof(svn_revnum_t));
-          if (rev_from_map && SVN_IS_VALID_REVNUM(*rev_from_map))
-            range->end = *rev_from_map;
-        }
-      apr_hash_set(final_mergeinfo, merge_source,
-                   APR_HASH_KEY_STRING, rangelist);
-    }
-
-  if (predates_stream_mergeinfo)
-      SVN_ERR(svn_mergeinfo_merge(final_mergeinfo, predates_stream_mergeinfo,
-                                  subpool));
-
-  SVN_ERR(svn_mergeinfo_sort(final_mergeinfo, subpool));
-
-  /* Mergeinfo revision sources for r0 and r1 are invalid; you can't merge r0
-     or r1.  However, svndumpfilter can be abused to produce r1 merge source
-     revs.  So if we encounter any, then strip them out, no need to put them
-     into the load target. */
-  SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(&final_mergeinfo,
-                                                    final_mergeinfo,
-                                                    1, 0, FALSE,
-                                                    subpool, subpool));
-
-  SVN_ERR(svn_mergeinfo_to_string(final_val, final_mergeinfo, pool));
-  svn_pool_destroy(subpool);
-
-  return SVN_NO_ERROR;
-}
-
-
 /* Read CONTENT_LENGTH bytes from STREAM, parsing the bytes as an
    encoded Subversion properties hash, and making multiple calls to
    PARSE_FNS->set_*_property on RECORD_BATON (depending on the value
@@ -480,38 +249,6 @@ parse_property_block(svn_stream_t *strea
               /* Now, send the property pair to the vtable! */
               if (is_node)
                 {
-                  /* svn_mergeinfo_parse() in parse_fns->set_node_property()
-                     will choke on mergeinfo with "\r\n" line endings, but we
-                     might legitimately encounter these in a dump stream.  If
-                     so normalize the line endings to '\n' and make a
-                     notification to PARSE_BATON->FEEDBACK_STREAM that we
-                     have made this correction. */
-                  if (strcmp(keybuf, SVN_PROP_MERGEINFO) == 0
-                      && strstr(propstring.data, "\r"))
-                    {
-                      const char *prop_eol_normalized;
-                      struct parse_baton *pb = parse_baton;
-
-                      SVN_ERR(svn_subst_translate_cstring2(
-                        propstring.data,
-                        &prop_eol_normalized,
-                        "\n",  /* translate to LF */
-                        FALSE, /* no repair */
-                        NULL,  /* no keywords */
-                        FALSE, /* no expansion */
-                        proppool));
-                      propstring.data = prop_eol_normalized;
-                      propstring.len = strlen(prop_eol_normalized);
-
-                      if (pb->notify_func)
-                        {
-                          pb->notify->action = 
-                            svn_repos_notify_load_normalized_mergeinfo;
-                          pb->notify_func(pb->notify_baton, pb->notify,
-                                          proppool);
-                        }
-                    }
-
                   SVN_ERR(parse_fns->set_node_property(record_baton,
                                                        keybuf,
                                                        &propstring));
@@ -663,7 +400,10 @@ parse_format_version(const char *version
 
 
 
-/* The Main Parser Logic */
+/*----------------------------------------------------------------------*/
+
+/** The public routines **/
+
 svn_error_t *
 svn_repos_parse_dumpstream2(svn_stream_t *stream,
                             const svn_repos_parse_fns2_t *parse_fns,
@@ -952,662 +692,3 @@ svn_repos_parse_dumpstream2(svn_stream_t
   svn_pool_destroy(nodepool);
   return SVN_NO_ERROR;
 }
-
-
-/*----------------------------------------------------------------------*/
-
-/** vtable for doing commits to a fs **/
-
-
-static struct node_baton *
-make_node_baton(apr_hash_t *headers,
-                struct revision_baton *rb,
-                apr_pool_t *pool)
-{
-  struct node_baton *nb = apr_pcalloc(pool, sizeof(*nb));
-  const char *val;
-
-  /* Start with sensible defaults. */
-  nb->rb = rb;
-  nb->pool = pool;
-  nb->kind = svn_node_unknown;
-
-  /* Then add info from the headers.  */
-  if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_NODE_PATH,
-                          APR_HASH_KEY_STRING)))
-  {
-    if (rb->pb->parent_dir)
-      nb->path = svn_path_join(rb->pb->parent_dir, val, pool);
-    else
-      nb->path = apr_pstrdup(pool, val);
-  }
-
-  if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_NODE_KIND,
-                          APR_HASH_KEY_STRING)))
-    {
-      if (! strcmp(val, "file"))
-        nb->kind = svn_node_file;
-      else if (! strcmp(val, "dir"))
-        nb->kind = svn_node_dir;
-    }
-
-  nb->action = (enum svn_node_action)(-1);  /* an invalid action code */
-  if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_NODE_ACTION,
-                          APR_HASH_KEY_STRING)))
-    {
-      if (! strcmp(val, "change"))
-        nb->action = svn_node_action_change;
-      else if (! strcmp(val, "add"))
-        nb->action = svn_node_action_add;
-      else if (! strcmp(val, "delete"))
-        nb->action = svn_node_action_delete;
-      else if (! strcmp(val, "replace"))
-        nb->action = svn_node_action_replace;
-    }
-
-  nb->copyfrom_rev = SVN_INVALID_REVNUM;
-  if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV,
-                          APR_HASH_KEY_STRING)))
-    {
-      nb->copyfrom_rev = SVN_STR_TO_REV(val);
-    }
-  if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH,
-                          APR_HASH_KEY_STRING)))
-    {
-      if (rb->pb->parent_dir)
-        nb->copyfrom_path = svn_path_join(rb->pb->parent_dir,
-                                          (*val == '/' ? val + 1 : val), pool);
-      else
-        nb->copyfrom_path = apr_pstrdup(pool, val);
-    }
-
-  if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_CONTENT_CHECKSUM,
-                          APR_HASH_KEY_STRING)))
-    {
-      svn_checksum_parse_hex(&nb->result_checksum, svn_checksum_md5, val, pool);
-    }
-
-  if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_DELTA_BASE_CHECKSUM,
-                          APR_HASH_KEY_STRING)))
-    {
-      svn_checksum_parse_hex(&nb->base_checksum, svn_checksum_md5, val, pool);
-    }
-
-  if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_COPY_SOURCE_CHECKSUM,
-                          APR_HASH_KEY_STRING)))
-    {
-      svn_checksum_parse_hex(&nb->copy_source_checksum, svn_checksum_md5, val,
-                             pool);
-    }
-
-  /* What's cool about this dump format is that the parser just
-     ignores any unrecognized headers.  :-)  */
-
-  return nb;
-}
-
-static struct revision_baton *
-make_revision_baton(apr_hash_t *headers,
-                    struct parse_baton *pb,
-                    apr_pool_t *pool)
-{
-  struct revision_baton *rb = apr_pcalloc(pool, sizeof(*rb));
-  const char *val;
-
-  rb->pb = pb;
-  rb->pool = pool;
-  rb->rev = SVN_INVALID_REVNUM;
-
-  if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_REVISION_NUMBER,
-                          APR_HASH_KEY_STRING)))
-    rb->rev = SVN_STR_TO_REV(val);
-
-  return rb;
-}
-
-
-static svn_error_t *
-new_revision_record(void **revision_baton,
-                    apr_hash_t *headers,
-                    void *parse_baton,
-                    apr_pool_t *pool)
-{
-  struct parse_baton *pb = parse_baton;
-  struct revision_baton *rb;
-  svn_revnum_t head_rev;
-
-  rb = make_revision_baton(headers, pb, pool);
-  SVN_ERR(svn_fs_youngest_rev(&head_rev, pb->fs, pool));
-
-  /* FIXME: This is a lame fallback loading multiple segments of dump in
-     several separate operations. It is highly susceptible to race conditions.
-     Calculate the revision 'offset' for finding copyfrom sources.
-     It might be positive or negative. */
-  rb->rev_offset = (apr_int32_t) (rb->rev) - (head_rev + 1);
-
-  if (rb->rev > 0)
-    {
-      /* Create a new fs txn. */
-      SVN_ERR(svn_fs_begin_txn2(&(rb->txn), pb->fs, head_rev, 0, pool));
-      SVN_ERR(svn_fs_txn_root(&(rb->txn_root), rb->txn, pool));
-
-      if (pb->notify_func)
-        {
-          pb->notify->action = svn_repos_notify_load_txn_start;
-          pb->notify->old_revision = rb->rev;
-          pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
-        }
-
-      /* Stash the oldest "old" revision committed from the load stream. */
-      if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev))
-        pb->oldest_old_rev = rb->rev;
-    }
-
-  /* If we're parsing revision 0, only the revision are (possibly)
-     interesting to us: when loading the stream into an empty
-     filesystem, then we want new filesystem's revision 0 to have the
-     same props.  Otherwise, we just ignore revision 0 in the stream. */
-
-  *revision_baton = rb;
-  return SVN_NO_ERROR;
-}
-
-
-
-/* Factorized helper func for new_node_record() */
-static svn_error_t *
-maybe_add_with_history(struct node_baton *nb,
-                       struct revision_baton *rb,
-                       apr_pool_t *pool)
-{
-  struct parse_baton *pb = rb->pb;
-
-  if ((nb->copyfrom_path == NULL) || (! pb->use_history))
-    {
-      /* Add empty file or dir, without history. */
-      if (nb->kind == svn_node_file)
-        SVN_ERR(svn_fs_make_file(rb->txn_root, nb->path, pool));
-
-      else if (nb->kind == svn_node_dir)
-        SVN_ERR(svn_fs_make_dir(rb->txn_root, nb->path, pool));
-    }
-  else
-    {
-      /* Hunt down the source revision in this fs. */
-      svn_fs_root_t *copy_root;
-      svn_revnum_t src_rev = nb->copyfrom_rev - rb->rev_offset;
-      svn_revnum_t *src_rev_from_map;
-      if ((src_rev_from_map = apr_hash_get(pb->rev_map, &nb->copyfrom_rev,
-                                           sizeof(nb->copyfrom_rev))))
-        src_rev = *src_rev_from_map;
-
-      if (! SVN_IS_VALID_REVNUM(src_rev))
-        return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
-                                 _("Relative source revision %ld is not"
-                                   " available in current repository"),
-                                 src_rev);
-
-      SVN_ERR(svn_fs_revision_root(&copy_root, pb->fs, src_rev, pool));
-
-      if (nb->copy_source_checksum)
-        {
-          svn_checksum_t *checksum;
-          SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5, copy_root,
-                                       nb->copyfrom_path, TRUE, pool));
-          if (!svn_checksum_match(nb->copy_source_checksum, checksum))
-            return svn_error_createf
-              (SVN_ERR_CHECKSUM_MISMATCH,
-               NULL,
-               apr_psprintf(pool, "%s:\n%s\n%s\n",
-                            _("Copy source checksum mismatch on copy from '%s'@%ld\n"
-                              "to '%s' in rev based on r%ld"),
-                            _("   expected:  %s"),
-                            _("     actual:  %s")),
-               nb->copyfrom_path, src_rev,
-               nb->path, rb->rev,
-               svn_checksum_to_cstring_display(nb->copy_source_checksum, pool),
-               svn_checksum_to_cstring_display(checksum, pool));
-        }
-
-      SVN_ERR(svn_fs_copy(copy_root, nb->copyfrom_path,
-                          rb->txn_root, nb->path, pool));
-
-      if (pb->notify_func)
-        {
-          pb->notify->action = svn_repos_notify_load_copied_node;
-          pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-uuid_record(const char *uuid,
-            void *parse_baton,
-            apr_pool_t *pool)
-{
-  struct parse_baton *pb = parse_baton;
-  svn_revnum_t youngest_rev;
-
-  if (pb->uuid_action == svn_repos_load_uuid_ignore)
-    return SVN_NO_ERROR;
-
-  if (pb->uuid_action != svn_repos_load_uuid_force)
-    {
-      SVN_ERR(svn_fs_youngest_rev(&youngest_rev, pb->fs, pool));
-      if (youngest_rev != 0)
-        return SVN_NO_ERROR;
-    }
-
-  return svn_fs_set_uuid(pb->fs, uuid, pool);
-}
-
-static svn_error_t *
-new_node_record(void **node_baton,
-                apr_hash_t *headers,
-                void *revision_baton,
-                apr_pool_t *pool)
-{
-  struct revision_baton *rb = revision_baton;
-  struct parse_baton *pb = rb->pb;
-  struct node_baton *nb;
-
-  if (rb->rev == 0)
-    return svn_error_create(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
-                            _("Malformed dumpstream: "
-                              "Revision 0 must not contain node records"));
-
-  nb = make_node_baton(headers, rb, pool);
-
-  /* Make sure we have an action we recognize. */
-  if (nb->action < svn_node_action_change
-        || nb->action > svn_node_action_replace)
-      return svn_error_createf(SVN_ERR_STREAM_UNRECOGNIZED_DATA, NULL,
-                               _("Unrecognized node-action on node '%s'"),
-                               nb->path);
-
-  if (pb->notify_func)
-    {
-      pb->notify->action = svn_repos_notify_load_node_start;
-      pb->notify->node_action = nb->action;
-      pb->notify->path = nb->path;
-      pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
-    }
-
-  switch (nb->action)
-    {
-    case svn_node_action_change:
-      break;
-
-    case svn_node_action_delete:
-      SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
-      break;
-
-    case svn_node_action_add:
-      SVN_ERR(maybe_add_with_history(nb, rb, pool));
-      break;
-
-    case svn_node_action_replace:
-      SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
-      SVN_ERR(maybe_add_with_history(nb, rb, pool));
-      break;
-    }
-
-  *node_baton = nb;
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-set_revision_property(void *baton,
-                      const char *name,
-                      const svn_string_t *value)
-{
-  struct revision_baton *rb = baton;
-
-  if (rb->rev > 0)
-    {
-      SVN_ERR(svn_fs_change_txn_prop(rb->txn, name, value, rb->pool));
-
-      /* Remember any datestamp that passes through!  (See comment in
-         close_revision() below.) */
-      if (! strcmp(name, SVN_PROP_REVISION_DATE))
-        rb->datestamp = svn_string_dup(value, rb->pool);
-    }
-  else if (rb->rev == 0)
-    {
-      /* Special case: set revision 0 properties when loading into an
-         'empty' filesystem. */
-      struct parse_baton *pb = rb->pb;
-      svn_revnum_t youngest_rev;
-
-      SVN_ERR(svn_fs_youngest_rev(&youngest_rev, pb->fs, rb->pool));
-
-      if (youngest_rev == 0)
-        SVN_ERR(svn_fs_change_rev_prop2(pb->fs, 0, name, NULL, value,
-                                        rb->pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-set_node_property(void *baton,
-                  const char *name,
-                  const svn_string_t *value)
-{
-  struct node_baton *nb = baton;
-  struct revision_baton *rb = nb->rb;
-  const char *parent_dir = rb->pb->parent_dir;
-
-  if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
-    {
-      /* Renumber mergeinfo as appropriate. */
-      svn_string_t *renumbered_mergeinfo;
-      SVN_ERR(renumber_mergeinfo_revs(&renumbered_mergeinfo, value, rb,
-                                      nb->pool));
-      value = renumbered_mergeinfo;
-      if (parent_dir)
-        {
-          /* Prefix the merge source paths with PARENT_DIR. */
-          /* ASSUMPTION: All source paths are included in the dump stream. */
-          svn_string_t *mergeinfo_val;
-          SVN_ERR(prefix_mergeinfo_paths(&mergeinfo_val, value, parent_dir,
-                                         nb->pool));
-          value = mergeinfo_val;
-        }
-    }
-
-  return svn_fs_change_node_prop(rb->txn_root, nb->path,
-                                 name, value, nb->pool);
-}
-
-
-static svn_error_t *
-delete_node_property(void *baton,
-                     const char *name)
-{
-  struct node_baton *nb = baton;
-  struct revision_baton *rb = nb->rb;
-
-  return svn_fs_change_node_prop(rb->txn_root, nb->path,
-                                 name, NULL, nb->pool);
-}
-
-
-static svn_error_t *
-remove_node_props(void *baton)
-{
-  struct node_baton *nb = baton;
-  struct revision_baton *rb = nb->rb;
-  apr_hash_t *proplist;
-  apr_hash_index_t *hi;
-
-  SVN_ERR(svn_fs_node_proplist(&proplist,
-                               rb->txn_root, nb->path, nb->pool));
-
-  for (hi = apr_hash_first(nb->pool, proplist); hi; hi = apr_hash_next(hi))
-    {
-      const void *key;
-
-      apr_hash_this(hi, &key, NULL, NULL);
-
-      SVN_ERR(svn_fs_change_node_prop(rb->txn_root, nb->path,
-                                      (const char *) key, NULL,
-                                      nb->pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-apply_textdelta(svn_txdelta_window_handler_t *handler,
-                void **handler_baton,
-                void *node_baton)
-{
-  struct node_baton *nb = node_baton;
-  struct revision_baton *rb = nb->rb;
-
-  return svn_fs_apply_textdelta(handler, handler_baton,
-                                rb->txn_root, nb->path,
-                                nb->base_checksum ?
-                                svn_checksum_to_cstring(nb->base_checksum,
-                                                        nb->pool) : NULL,
-                                nb->result_checksum ?
-                                svn_checksum_to_cstring(nb->result_checksum,
-                                                        nb->pool) : NULL,
-                                nb->pool);
-}
-
-
-static svn_error_t *
-set_fulltext(svn_stream_t **stream,
-             void *node_baton)
-{
-  struct node_baton *nb = node_baton;
-  struct revision_baton *rb = nb->rb;
-
-  return svn_fs_apply_text(stream,
-                           rb->txn_root, nb->path,
-                           nb->result_checksum ?
-                           svn_checksum_to_cstring(nb->result_checksum,
-                                                   nb->pool) : NULL,
-                           nb->pool);
-}
-
-
-static svn_error_t *
-close_node(void *baton)
-{
-  struct node_baton *nb = baton;
-  struct revision_baton *rb = nb->rb;
-  struct parse_baton *pb = rb->pb;
-
-  if (pb->notify_func)
-    {
-      pb->notify->action = svn_repos_notify_load_node_done;
-      pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-close_revision(void *baton)
-{
-  struct revision_baton *rb = baton;
-  struct parse_baton *pb = rb->pb;
-  const char *conflict_msg = NULL;
-  svn_revnum_t *old_rev, *new_rev;
-  svn_error_t *err;
-
-  if (rb->rev <= 0)
-    return SVN_NO_ERROR;
-
-  /* Prepare memory for saving dump-rev -> in-repos-rev mapping. */
-  old_rev = apr_palloc(pb->pool, sizeof(*old_rev) * 2);
-  new_rev = old_rev + 1;
-  *old_rev = rb->rev;
-
-  /* Run the pre-commit hook, if so commanded. */
-  if (pb->use_pre_commit_hook)
-    {
-      const char *txn_name;
-      err = svn_fs_txn_name(&txn_name, rb->txn, rb->pool);
-      if (! err)
-        err = svn_repos__hooks_pre_commit(pb->repos, txn_name, rb->pool);
-      if (err)
-        {
-          svn_error_clear(svn_fs_abort_txn(rb->txn, rb->pool));
-          return svn_error_return(err);
-        }
-    }
-
-  /* Commit. */
-  if ((err = svn_fs_commit_txn(&conflict_msg, new_rev, rb->txn, rb->pool)))
-    {
-      svn_error_clear(svn_fs_abort_txn(rb->txn, rb->pool));
-      if (conflict_msg)
-        return svn_error_quick_wrap(err, conflict_msg);
-      else
-        return svn_error_return(err);
-    }
-
-  /* Run post-commit hook, if so commanded.  */
-  if (pb->use_post_commit_hook)
-    {
-      if ((err = svn_repos__hooks_post_commit(pb->repos, *new_rev, rb->pool)))
-        return svn_error_create
-          (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err,
-           _("Commit succeeded, but post-commit hook failed"));
-    }
-
-  /* After a successful commit, must record the dump-rev -> in-repos-rev
-     mapping, so that copyfrom instructions in the dump file can look up the
-     correct repository revision to copy from. */
-  apr_hash_set(pb->rev_map, old_rev, sizeof(svn_revnum_t), new_rev);
-
-  /* If the incoming dump stream has non-contiguous revisions (e.g. from
-     using svndumpfilter --drop-empty-revs without --renumber-revs) then
-     we must account for the missing gaps in PB->REV_MAP.  Otherwise we
-     might not be able to map all mergeinfo source revisions to the correct
-     revisions in the target repos. */
-  if (pb->last_rev_mapped != SVN_INVALID_REVNUM
-      && *old_rev != pb->last_rev_mapped + 1)
-    {
-      svn_revnum_t i;
-
-      /* Map all dropped revisions between PB->LAST_REV_MAPPED and OLD_REV. */
-      for (i = pb->last_rev_mapped + 1; i < *old_rev; i++)
-        {
-          svn_revnum_t *gap_rev_old = apr_palloc(pb->pool,
-                                                 sizeof(*gap_rev_old));
-          svn_revnum_t *gap_rev_new = apr_palloc(pb->pool,
-                                                 sizeof(*gap_rev_new));
-          *gap_rev_old = i;
-          *gap_rev_new = pb->last_rev_mapped;
-          apr_hash_set(pb->rev_map, gap_rev_old, sizeof(svn_revnum_t),
-                       gap_rev_new);
-        }
-    }
-  pb->last_rev_mapped = *old_rev;
-
-  /* Deltify the predecessors of paths changed in this revision. */
-  SVN_ERR(svn_fs_deltify_revision(pb->fs, *new_rev, rb->pool));
-
-  /* Grrr, svn_fs_commit_txn rewrites the datestamp property to the
-     current clock-time.  We don't want that, we want to preserve
-     history exactly.  Good thing revision props aren't versioned!
-     Note that if rb->datestamp is NULL, that's fine -- if the dump
-     data doesn't carry a datestamp, we want to preserve that fact in
-     the load. */
-  SVN_ERR(svn_fs_change_rev_prop(pb->fs, *new_rev,
-                                 SVN_PROP_REVISION_DATE, rb->datestamp,
-                                 rb->pool));
-
-  if (pb->notify_func)
-    {
-      pb->notify->action = svn_repos_notify_load_txn_committed;
-      pb->notify->new_revision = *new_rev;
-      pb->notify->old_revision = ((*new_rev == rb->rev)
-                                    ? SVN_INVALID_REVNUM
-                                    : rb->rev);
-      pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
-/*----------------------------------------------------------------------*/
-
-/** The public routines **/
-
-
-svn_error_t *
-svn_repos_get_fs_build_parser3(const svn_repos_parse_fns2_t **callbacks,
-                               void **parse_baton,
-                               svn_repos_t *repos,
-                               svn_boolean_t use_history,
-                               enum svn_repos_load_uuid uuid_action,
-                               const char *parent_dir,
-                               svn_repos_notify_func_t notify_func,
-                               void *notify_baton,
-                               apr_pool_t *pool)
-{
-  svn_repos_parse_fns2_t *parser = apr_pcalloc(pool, sizeof(*parser));
-  struct parse_baton *pb = apr_pcalloc(pool, sizeof(*pb));
-
-  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;
-  parser->set_fulltext = set_fulltext;
-  parser->close_node = close_node;
-  parser->close_revision = close_revision;
-  parser->delete_node_property = delete_node_property;
-  parser->apply_textdelta = apply_textdelta;
-
-  pb->repos = repos;
-  pb->fs = svn_repos_fs(repos);
-  pb->use_history = use_history;
-  pb->notify_func = notify_func;
-  pb->notify_baton = notify_baton;
-  pb->notify = svn_repos_notify_create(svn_repos_notify_load_txn_start, pool);
-  pb->uuid_action = uuid_action;
-  pb->parent_dir = parent_dir;
-  pb->pool = pool;
-  pb->rev_map = apr_hash_make(pool);
-  pb->oldest_old_rev = SVN_INVALID_REVNUM;
-  pb->last_rev_mapped = SVN_INVALID_REVNUM;
-
-  *callbacks = parser;
-  *parse_baton = pb;
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_repos_load_fs3(svn_repos_t *repos,
-                   svn_stream_t *dumpstream,
-                   enum svn_repos_load_uuid uuid_action,
-                   const char *parent_dir,
-                   svn_boolean_t use_pre_commit_hook,
-                   svn_boolean_t use_post_commit_hook,
-                   svn_repos_notify_func_t notify_func,
-                   void *notify_baton,
-                   svn_cancel_func_t cancel_func,
-                   void *cancel_baton,
-                   apr_pool_t *pool)
-{
-  const svn_repos_parse_fns2_t *parser;
-  void *parse_baton;
-  struct parse_baton *pb;
-
-  /* This is really simple. */
-
-  SVN_ERR(svn_repos_get_fs_build_parser3(&parser, &parse_baton,
-                                         repos,
-                                         TRUE, /* look for copyfrom revs */
-                                         uuid_action,
-                                         parent_dir,
-                                         notify_func,
-                                         notify_baton,
-                                         pool));
-
-  /* Heh.  We know this is a parse_baton.  This file made it.  So
-     cast away, and set our hook booleans.  */
-  pb = parse_baton;
-  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,
-                                     cancel_func, cancel_baton, pool);
-}

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_repos/log.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_repos/log.c Thu Nov  4 20:48:21 2010
@@ -1034,7 +1034,10 @@ send_log(svn_revnum_t rev,
    memory. */
 #define MAX_OPEN_HISTORIES 32
 
-/* Get the histories for PATHS, and store them in *HISTORIES. */
+/* Get the histories for PATHS, and store them in *HISTORIES.
+
+   If IGNORE_MISSING_LOCATIONS is set, don't treat requests for bogus
+   repository locations as fatal -- just ignore them.  */
 static svn_error_t *
 get_path_histories(apr_array_header_t **histories,
                    svn_fs_t *fs,
@@ -1042,6 +1045,7 @@ get_path_histories(apr_array_header_t **
                    svn_revnum_t hist_start,
                    svn_revnum_t hist_end,
                    svn_boolean_t strict_node_history,
+                   svn_boolean_t ignore_missing_locations,
                    svn_repos_authz_func_t authz_read_func,
                    void *authz_read_baton,
                    apr_pool_t *pool)
@@ -1089,7 +1093,18 @@ get_path_histories(apr_array_header_t **
 
       if (i < MAX_OPEN_HISTORIES)
         {
-          SVN_ERR(svn_fs_node_history(&info->hist, root, this_path, pool));
+          svn_error_t *err;
+          err = svn_fs_node_history(&info->hist, root, this_path, pool);
+          if (err
+              && ignore_missing_locations
+              && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
+                  err->apr_err == SVN_ERR_FS_NOT_DIRECTORY ||
+                  err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION))
+            {
+              svn_error_clear(err);
+              continue;
+            }
+          SVN_ERR(err);
           info->newpool = svn_pool_create(pool);
           info->oldpool = svn_pool_create(pool);
         }
@@ -1336,6 +1351,7 @@ do_logs(svn_fs_t *fs,
         svn_boolean_t discover_changed_paths,
         svn_boolean_t strict_node_history,
         svn_boolean_t include_merged_revisions,
+        svn_boolean_t ignore_missing_locations,
         const apr_array_header_t *revprops,
         svn_boolean_t descending_order,
         svn_log_entry_receiver_t receiver,
@@ -1383,24 +1399,15 @@ handle_merged_revisions(svn_revnum_t rev
   iterpool = svn_pool_create(pool);
   for (i = combined_list->nelts - 1; i >= 0; i--)
     {
-      svn_error_t *err;
       struct path_list_range *pl_range
         = APR_ARRAY_IDX(combined_list, i, struct path_list_range *);
 
       svn_pool_clear(iterpool);
-      err = do_logs(fs, pl_range->paths, pl_range->range.start,
-                    pl_range->range.end, 0, discover_changed_paths,
-                    strict_node_history, TRUE, revprops, TRUE,
-                    receiver, receiver_baton, authz_read_func,
-                    authz_read_baton, iterpool);
-      if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
-                  err->apr_err == SVN_ERR_FS_NOT_DIRECTORY ||
-                  err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION))
-        {
-          svn_error_clear(err);
-          continue;
-        }
-      SVN_ERR(err);
+      SVN_ERR(do_logs(fs, pl_range->paths, pl_range->range.start,
+                      pl_range->range.end, 0, discover_changed_paths,
+                      strict_node_history, TRUE, TRUE, revprops, TRUE,
+                      receiver, receiver_baton, authz_read_func,
+                      authz_read_baton, iterpool));
     }
   svn_pool_destroy(iterpool);
 
@@ -1415,6 +1422,9 @@ handle_merged_revisions(svn_revnum_t rev
    the logs back as we find them, else buffer the logs and send them back
    in youngest->oldest order.
 
+   If IGNORE_MISSING_LOCATIONS is set, don't treat requests for bogus
+   repository locations as fatal -- just ignore them.
+
    Other parameters are the same as svn_repos_get_logs4().
  */
 static svn_error_t *
@@ -1426,6 +1436,7 @@ do_logs(svn_fs_t *fs,
         svn_boolean_t discover_changed_paths,
         svn_boolean_t strict_node_history,
         svn_boolean_t include_merged_revisions,
+        svn_boolean_t ignore_missing_locations,
         const apr_array_header_t *revprops,
         svn_boolean_t descending_order,
         svn_log_entry_receiver_t receiver,
@@ -1448,8 +1459,8 @@ do_logs(svn_fs_t *fs,
      one of our paths was changed.  So let's go figure out which
      revisions contain real changes to at least one of our paths.  */
   SVN_ERR(get_path_histories(&histories, fs, paths, hist_start, hist_end,
-                             strict_node_history, authz_read_func,
-                             authz_read_baton, pool));
+                             strict_node_history, ignore_missing_locations,
+                             authz_read_func, authz_read_baton, pool));
 
   /* Loop through all the revisions in the range and add any
      where a path was changed to the array, or if they wanted
@@ -1686,7 +1697,7 @@ svn_repos_get_logs4(svn_repos_t *repos,
 
   return do_logs(repos->fs, paths, start, end, limit,
                  discover_changed_paths, strict_node_history,
-                 include_merged_revisions, revprops, descending_order,
-                 receiver, receiver_baton,
+                 include_merged_revisions, FALSE, revprops,
+                 descending_order, receiver, receiver_baton,
                  authz_read_func, authz_read_baton, pool);
 }

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_repos/node_tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_repos/node_tree.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_repos/node_tree.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_repos/node_tree.c Thu Nov  4 20:48:21 2010
@@ -268,7 +268,7 @@ add_open_helper(const char *path,
   nb->parent_baton = pb;
 
   /* Create and populate the node. */
-  nb->node = create_child_node(pb->node, svn_relpath_basename(path, pool),
+  nb->node = create_child_node(pb->node, svn_relpath_basename(path, NULL),
                                eb->node_pool);
   nb->node->kind = kind;
   nb->node->action = action;

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_repos/replay.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_repos/replay.c Thu Nov  4 20:48:21 2010
@@ -248,7 +248,8 @@ add_subdir(svn_fs_root_t *source_root,
           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, pool));
+              SVN_ERR(svn_fs_revision_root(&new_source_root, fs, copyfrom_rev,
+                                           pool));
               new_source_path = copyfrom_path;
             }
           else

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_repos/reporter.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_repos/reporter.c Thu Nov  4 20:48:21 2010
@@ -84,6 +84,17 @@ typedef struct path_info_t
   apr_pool_t *pool;            /* Container pool */
 } path_info_t;
 
+/* Describes the standard revision properties that are relevant for
+   reports.  Since a particular revision will often show up more than
+   once in the report, we cache these properties for the time of the
+   report generation. */
+typedef struct revision_info_t
+{
+  svn_revnum_t rev;            /* revision number */
+  svn_string_t* date;          /* revision timestamp */
+  svn_string_t* author;        /* name of the revisions' author */
+} revision_info_t;
+
 /* A structure used by the routines within the `reporter' vtable,
    driven by the client as it describes its working copy revisions. */
 typedef struct report_baton_t
@@ -118,6 +129,11 @@ typedef struct report_baton_t
   path_info_t *lookahead;
   svn_fs_root_t *t_root;
   svn_fs_root_t *s_roots[NUM_CACHED_SOURCE_ROOTS];
+
+  /* Cache for revision properties. This is used to eliminate redundant 
+     revprop fetching. */
+  apr_hash_t* revision_infos;
+
   apr_pool_t *pool;
 } report_baton_t;
 
@@ -428,6 +444,53 @@ change_file_prop(report_baton_t *b, void
   return b->editor->change_file_prop(file_baton, name, value, pool);
 }
 
+/* For the report B, return the relevant revprop data of revision REV in
+   REVISION_INFO. The revision info will be allocated in b->pool.
+   Temporaries get allocated on SCRATCH_POOL. */
+static  svn_error_t *
+get_revision_info(report_baton_t *b,
+                  svn_revnum_t rev,
+                  revision_info_t** revision_info,
+                  apr_pool_t *scratch_pool)
+{
+  apr_hash_t *r_props;
+  svn_string_t *cdate, *author;
+  revision_info_t* info;
+
+  /* Try to find the info in the report's cache */
+  info = apr_hash_get(b->revision_infos, &rev, sizeof(rev));
+  if (!info)
+    {
+      /* Info is not available, yet. 
+         Get all revprops. */
+      SVN_ERR(svn_fs_revision_proplist(&r_props,
+                                       b->repos->fs,
+                                       rev,
+                                       scratch_pool));
+
+      /* Extract the committed-date. */
+      cdate = apr_hash_get(r_props, SVN_PROP_REVISION_DATE,
+                           APR_HASH_KEY_STRING);
+
+      /* Extract the last-author. */
+      author = apr_hash_get(r_props, SVN_PROP_REVISION_AUTHOR,
+                            APR_HASH_KEY_STRING);
+
+      /* Create a result object */
+      info = apr_palloc(b->pool, sizeof(*info));
+      info->rev = rev;
+      info->date = cdate ? svn_string_dup(cdate, b->pool) : NULL;
+      info->author = author ? svn_string_dup(author, b->pool) : NULL;
+
+      /* Cache it */
+      apr_hash_set(b->revision_infos, &rev, sizeof(rev), info);
+    }
+
+  *revision_info = info;
+  return SVN_NO_ERROR;
+}
+
+
 /* Generate the appropriate property editing calls to turn the
    properties of S_REV/S_PATH into those of B->t_root/T_PATH.  If
    S_PATH is NULL, this is an add, so assume the target starts with no
@@ -440,12 +503,13 @@ delta_proplists(report_baton_t *b, svn_r
                 void *object, apr_pool_t *pool)
 {
   svn_fs_root_t *s_root;
-  apr_hash_t *s_props, *t_props, *r_props;
+  apr_hash_t *s_props, *t_props;
   apr_array_header_t *prop_diffs;
   int i;
   svn_revnum_t crev;
   const char *uuid;
-  svn_string_t *cr_str, *cdate, *last_author;
+  svn_string_t *cr_str;
+  revision_info_t* revision_info;
   svn_boolean_t changed;
   const svn_prop_t *pc;
   svn_lock_t *lock;
@@ -459,21 +523,17 @@ delta_proplists(report_baton_t *b, svn_r
       SVN_ERR(change_fn(b, object,
                         SVN_PROP_ENTRY_COMMITTED_REV, cr_str, pool));
 
-      SVN_ERR(svn_fs_revision_proplist(&r_props, b->repos->fs, crev, pool));
+      SVN_ERR(get_revision_info(b, crev, &revision_info, pool));
 
       /* Transmit the committed-date. */
-      cdate = apr_hash_get(r_props, SVN_PROP_REVISION_DATE,
-                           APR_HASH_KEY_STRING);
-      if (cdate || s_path)
+      if (revision_info->date || s_path)
         SVN_ERR(change_fn(b, object, SVN_PROP_ENTRY_COMMITTED_DATE,
-                          cdate, pool));
+                          revision_info->date, pool));
 
       /* Transmit the last-author. */
-      last_author = apr_hash_get(r_props, SVN_PROP_REVISION_AUTHOR,
-                                 APR_HASH_KEY_STRING);
-      if (last_author || s_path)
+      if (revision_info->author || s_path)
         SVN_ERR(change_fn(b, object, SVN_PROP_ENTRY_LAST_AUTHOR,
-                          last_author, pool));
+                          revision_info->author, pool));
 
       /* Transmit the UUID. */
       SVN_ERR(svn_fs_get_uuid(b->repos->fs, &uuid, pool));
@@ -680,7 +740,7 @@ add_file_smartly(report_baton_t *b,
          starting with '/', so make sure o_path always starts with a '/'
          too. */
       if (*o_path != '/')
-        o_path = apr_pstrcat(pool, "/", o_path, NULL);
+        o_path = apr_pstrcat(pool, "/", o_path, (char *)NULL);
 
       SVN_ERR(svn_fs_closest_copy(&closest_copy_root, &closest_copy_path,
                                   b->t_root, o_path, pool));
@@ -760,7 +820,6 @@ update_entry(report_baton_t *b, svn_revn
   void *new_baton;
   svn_checksum_t *checksum;
   const char *hex_digest;
-  int distance;
 
   /* For non-switch operations, follow link_path in the target. */
   if (info && info->link_path && !b->is_switch)
@@ -798,7 +857,7 @@ update_entry(report_baton_t *b, svn_revn
   related = FALSE;
   if (s_entry && t_entry && s_entry->kind == t_entry->kind)
     {
-      distance = svn_fs_compare_ids(s_entry->id, t_entry->id);
+      int distance = svn_fs_compare_ids(s_entry->id, t_entry->id);
       if (distance == 0 && !any_path_info(b, e_path)
           && (!info || (!info->start_empty && !info->lock_token))
           && (requested_depth <= wc_depth || t_entry->kind == svn_node_file))
@@ -1404,6 +1463,8 @@ svn_repos_begin_report2(void **report_ba
   b->edit_baton = edit_baton;
   b->authz_read_func = authz_read_func;
   b->authz_read_baton = authz_read_baton;
+  b->revision_infos = apr_hash_make(pool);
+  b->pool = pool;
 
   SVN_ERR(svn_io_open_unique_file3(&b->tempfile, NULL, NULL,
                                    svn_io_file_del_on_pool_cleanup,

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_repos/repos.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_repos/repos.c Thu Nov  4 20:48:21 2010
@@ -1141,6 +1141,13 @@ create_conf(svn_repos_t *repos, apr_pool
 "### have the same password database, and vice versa.  The default realm"    NL
 "### is repository's uuid."                                                  NL
 "# realm = My First Repository"                                              NL
+"### The force-username-case option causes svnserve to case-normalize"       NL
+"### usernames before comparing them against the authorization rules in the" NL
+"### authz-db file configured above.  Valid values are \"upper\" (to upper-" NL
+"### case the usernames), \"lower\" (to lowercase the usernames), and"       NL
+"### \"none\" (to compare usernames as-is without case conversion, which"    NL
+"### is the default behavior)."                                              NL
+"# force-username-case = none"                                               NL
 ""                                                                           NL
 "[sasl]"                                                                     NL
 "### This option specifies whether you want to use the Cyrus SASL"           NL

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_repos/rev_hunt.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_repos/rev_hunt.c Thu Nov  4 20:48:21 2010
@@ -659,7 +659,7 @@ svn_repos_trace_node_locations(svn_fs_t 
   /* Ensure that FS_PATH is absolute, because our path-math below will
      depend on that being the case.  */
   if (*fs_path != '/')
-    fs_path = apr_pstrcat(pool, "/", fs_path, NULL);
+    fs_path = apr_pstrcat(pool, "/", fs_path, (char *)NULL);
 
   /* Another sanity check. */
   if (authz_read_func)
@@ -873,7 +873,7 @@ svn_repos_node_location_segments(svn_rep
   /* Ensure that PATH is absolute, because our path-math will depend
      on that being the case.  */
   if (*path != '/')
-    path = apr_pstrcat(pool, "/", path, NULL);
+    path = apr_pstrcat(pool, "/", path, (char *)NULL);
 
   /* Auth check. */
   if (authz_read_func)
@@ -937,7 +937,7 @@ svn_repos_node_location_segments(svn_rep
 
           /* authz_read_func requires path to have a leading slash. */
           const char *abs_path = apr_pstrcat(subpool, "/", segment->path,
-                                             NULL);
+                                             (char *)NULL);
 
           SVN_ERR(svn_fs_revision_root(&cur_rev_root, fs,
                                        segment->range_end, subpool));

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/auth.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/auth.c Thu Nov  4 20:48:21 2010
@@ -187,7 +187,7 @@ svn_auth_first_credentials(void **creden
                              cred_kind);
 
   /* First, see if we have cached creds in the auth_baton. */
-  cache_key = apr_pstrcat(pool, cred_kind, ":", realmstring, NULL);
+  cache_key = apr_pstrcat(pool, cred_kind, ":", realmstring, (char *)NULL);
   creds = apr_hash_get(auth_baton->creds_cache,
                        cache_key, APR_HASH_KEY_STRING);
   if (creds)

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/cache-memcache.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/cache-memcache.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/cache-memcache.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/cache-memcache.c Thu Nov  4 20:48:21 2010
@@ -97,7 +97,7 @@ build_key(memcache_t *cache,
     }
 
   long_key = apr_pstrcat(pool, "SVN:", cache->prefix, ":", encoded_suffix,
-                         NULL);
+                         (char *)NULL);
   long_key_len = strlen(long_key);
 
   /* We don't want to have a key that's too big.  If it was going to
@@ -117,7 +117,7 @@ build_key(memcache_t *cache,
                              apr_pstrmemdup(pool, long_key,
                                             MEMCACHED_KEY_UNHASHED_LEN),
                              svn_checksum_to_cstring_display(checksum, pool),
-                             NULL);
+                             (char *)NULL);
     }
 
   return long_key;

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/checksum.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/checksum.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/checksum.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/checksum.c Thu Nov  4 20:48:21 2010
@@ -159,7 +159,7 @@ svn_checksum_serialize(const svn_checksu
   return apr_pstrcat(result_pool,
                      ckind_str,
                      svn_checksum_to_cstring(checksum, scratch_pool),
-                     NULL);
+                     (char *)NULL);
 }
 
 

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/config_file.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/config_file.c Thu Nov  4 20:48:21 2010
@@ -38,6 +38,11 @@
 
 #include "svn_private_config.h"
 
+#ifdef __HAIKU__
+#  include <FindDirectory.h>
+#  include <StorageDefs.h>
+#endif
+
 /* Used to terminate lines in large multi-line string literals. */
 #define NL APR_EOL_STR
 
@@ -331,7 +336,19 @@ svn_config__sys_config_path(const char *
                                    SVN_CONFIG__SUBDIRECTORY, fname, NULL);
   }
 
-#else  /* ! WIN32 */
+#elif defined(__HAIKU__)
+  {
+    char folder[B_PATH_NAME_LENGTH];
+
+    status_t error = find_directory(B_COMMON_SETTINGS_DIRECTORY, -1, false,
+                                    folder, sizeof(folder));
+    if (error)
+      return SVN_NO_ERROR;
+
+    *path_p = svn_dirent_join_many(pool, folder,
+                                   SVN_CONFIG__SYS_DIRECTORY, fname, NULL);
+  }
+#else  /* ! WIN32 && !__HAIKU__ */
 
   *path_p = svn_dirent_join_many(pool, SVN_CONFIG__SYS_DIRECTORY, fname, NULL);
 
@@ -1117,7 +1134,20 @@ svn_config_get_user_config_path(const ch
                                  SVN_CONFIG__SUBDIRECTORY, fname, NULL);
   }
 
-#else  /* ! WIN32 */
+#elif defined(__HAIKU__)
+  {
+    char folder[B_PATH_NAME_LENGTH];
+
+    status_t error = find_directory(B_USER_SETTINGS_DIRECTORY, -1, false,
+                                    folder, sizeof(folder));
+    if (error)
+      return SVN_NO_ERROR;
+
+    *path = svn_dirent_join_many(pool, folder,
+                                 SVN_CONFIG__USR_DIRECTORY, fname, NULL);
+  }
+#else  /* ! WIN32 && !__HAIKU__ */
+
   {
     const char *homedir = svn_user_get_homedir(pool);
     if (! homedir)

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/config_impl.h
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/config_impl.h?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/config_impl.h (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/config_impl.h Thu Nov  4 20:48:21 2010
@@ -114,7 +114,10 @@ svn_error_t *svn_config__parse_registry(
    or svn_config_get_user_config_path() instead. */
 #ifdef WIN32
 #  define SVN_CONFIG__SUBDIRECTORY    "Subversion"
-#else  /* ! WIN32 */
+#elif defined __HAIKU__ /* HAIKU */
+#  define SVN_CONFIG__SYS_DIRECTORY   "subversion"
+#  define SVN_CONFIG__USR_DIRECTORY   "subversion"
+#else  /* ! WIN32 && ! __HAIKU__ */
 #  define SVN_CONFIG__SYS_DIRECTORY   "/etc/subversion"
 #  define SVN_CONFIG__USR_DIRECTORY   ".subversion"
 #endif /* WIN32 */

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/deprecated.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/deprecated.c Thu Nov  4 20:48:21 2010
@@ -549,17 +549,20 @@ svn_opt_print_help(apr_getopt_t *os,
                    apr_pool_t *pool)
 {
   apr_array_header_t *targets = NULL;
-  int i;
 
   if (os)
     SVN_ERR(svn_opt_parse_all_args(&targets, os, pool));
 
   if (os && targets->nelts)  /* help on subcommand(s) requested */
-    for (i = 0; i < targets->nelts; i++)
-      {
-        svn_opt_subcommand_help(APR_ARRAY_IDX(targets, i, const char *),
-                                cmd_table, option_table, pool);
-      }
+    {
+      int i;
+
+      for (i = 0; i < targets->nelts; i++)
+        {
+          svn_opt_subcommand_help(APR_ARRAY_IDX(targets, i, const char *),
+                                  cmd_table, option_table, pool);
+        }
+    }
   else if (print_version)   /* just --version */
     SVN_ERR(svn_opt__print_version_info(pgm_name, version_footer, quiet,
                                         pool));

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/dirent_uri.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/dirent_uri.c Thu Nov  4 20:48:21 2010
@@ -1936,10 +1936,9 @@ svn_dirent_condense_targets(const char *
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
 {
-  int i, j, num_condensed = targets->nelts;
+  int i, num_condensed = targets->nelts;
   svn_boolean_t *removed;
   apr_array_header_t *abs_targets;
-  size_t basedir_len;
 
   /* Early exit when there's no data to work on. */
   if (targets->nelts <= 0)
@@ -1995,6 +1994,8 @@ svn_dirent_condense_targets(const char *
 
   if (pcondensed_targets != NULL)
     {
+      size_t basedir_len;
+
       if (remove_redundancies)
         {
           /* Find the common part of each pair of targets.  If
@@ -2006,6 +2007,8 @@ svn_dirent_condense_targets(const char *
              another non-removed target, remove the child. */
           for (i = 0; i < abs_targets->nelts; ++i)
             {
+              int j;
+
               if (removed[i])
                 continue;
 
@@ -2101,10 +2104,9 @@ svn_uri_condense_targets(const char **pc
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
 {
-  int i, j, num_condensed = targets->nelts;
+  int i, num_condensed = targets->nelts;
   apr_array_header_t *uri_targets;
   svn_boolean_t *removed;
-  size_t basedir_len;
 
   /* Early exit when there's no data to work on. */
   if (targets->nelts <= 0)
@@ -2156,6 +2158,8 @@ svn_uri_condense_targets(const char **pc
 
   if (pcondensed_targets != NULL)
     {
+      size_t basedir_len;
+
       if (remove_redundancies)
         {
           /* Find the common part of each pair of targets.  If
@@ -2167,6 +2171,8 @@ svn_uri_condense_targets(const char **pc
              another non-removed target, remove the child. */
           for (i = 0; i < uri_targets->nelts; ++i)
             {
+              int j;
+
               if (removed[i])
                 continue;
 
@@ -2423,7 +2429,7 @@ svn_uri_get_file_url_from_dirent(const c
   dirent = svn_path_uri_encode(dirent, pool);
 
 #ifndef SVN_USE_DOS_PATHS
-  *url = apr_pstrcat(pool, "file://", dirent, NULL);
+  *url = apr_pstrcat(pool, "file://", dirent, (char *)NULL);
 #else
   if (dirent[0] == '/')
     {

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/error.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/error.c Thu Nov  4 20:48:21 2010
@@ -269,6 +269,18 @@ svn_error_root_cause(svn_error_t *err)
   return err;
 }
 
+svn_boolean_t
+svn_error_has_cause(svn_error_t *err, apr_status_t apr_err)
+{
+  svn_error_t *child;
+
+  for (child = err; child; child = child->child)
+    if (child->apr_err == apr_err)
+      return TRUE;
+
+  return FALSE;
+}
+
 svn_error_t *
 svn_error_dup(svn_error_t *err)
 {
@@ -473,11 +485,12 @@ svn_handle_error2(svn_error_t *err,
   tmp_err = err;
   while (tmp_err)
     {
-      int i;
       svn_boolean_t printed_already = FALSE;
 
       if (! tmp_err->message)
         {
+          int i;
+
           for (i = 0; i < empties->nelts; i++)
             {
               if (tmp_err->apr_err == APR_ARRAY_IDX(empties, i, apr_status_t) )

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/io.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/io.c Thu Nov  4 20:48:21 2010
@@ -334,6 +334,10 @@ svn_io_open_uniquely_named(apr_file_t **
   unsigned int i;
   struct temp_file_cleanup_s *baton = NULL;
 
+  /* At the beginning, we don't know whether unique_path will need 
+     UTF8 conversion */
+  svn_boolean_t needs_utf8_conversion = TRUE;
+
   SVN_ERR_ASSERT(file || unique_path);
 
   if (dirpath == NULL)
@@ -388,13 +392,27 @@ svn_io_open_uniquely_named(apr_file_t **
       if (i == 1)
         unique_name = apr_psprintf(scratch_pool, "%s%s", path, suffix);
       else
-        unique_name = apr_psprintf(scratch_pool, "%s.%u%s", path, i, suffix);
+        unique_name = apr_psprintf(scratch_pool, "%s.%u_%s", path, i, suffix);
 
       /* Hmmm.  Ideally, we would append to a native-encoding buf
          before starting iteration, then convert back to UTF-8 for
          return. But I suppose that would make the appending code
          sensitive to i18n in a way it shouldn't be... Oh well. */
-      SVN_ERR(cstring_from_utf8(&unique_name_apr, unique_name, scratch_pool));
+      if (needs_utf8_conversion)
+        {
+          SVN_ERR(cstring_from_utf8(&unique_name_apr, unique_name,
+                                    scratch_pool));
+          if (i == 1)
+            {
+              /* The variable parts of unique_name will not require UTF8
+                 conversion. Therefore, if UTF8 conversion had no effect
+                 on it in the first iteration, it won't require conversion
+                 in any future interation. */
+              needs_utf8_conversion = strcmp(unique_name_apr, unique_name);
+            }
+        }
+      else
+        unique_name_apr = unique_name;
 
       apr_err = file_open(&try_file, unique_name_apr, flag,
                           APR_OS_DEFAULT, FALSE, result_pool);
@@ -800,6 +818,29 @@ file_perms_set(const char *fname, apr_fi
   else
     return SVN_NO_ERROR;
 }
+
+/* Set permissions PERMS on the FILE. This is a cheaper variant of the 
+ * file_perms_set wrapper() function because no locale-dependent string
+ * conversion is required. 
+ */
+static svn_error_t *
+file_perms_set2(apr_file_t* file, apr_fileperms_t perms)
+{
+  const char *fname_apr;
+  apr_status_t status;
+
+  status = apr_file_name_get(&fname_apr, file);
+  if (status)
+    return svn_error_wrap_apr(status, _("Can't get file name"));
+
+  status = apr_file_perms_set(fname_apr, perms);
+  if (status)
+    return svn_error_wrap_apr(status, _("Can't set permissions on '%s'"),
+                              fname_apr);
+  else
+    return SVN_NO_ERROR;
+}
+
 #endif /* !WIN32 && !__OS2__ */
 
 svn_error_t *
@@ -1268,30 +1309,46 @@ reown_file(const char *path,
 static svn_error_t *
 get_default_file_perms(apr_fileperms_t *perms, apr_pool_t *scratch_pool)
 {
-  apr_finfo_t finfo;
-  apr_file_t *fd;
+  /* the default permissions as read from the temp folder */
+  static apr_fileperms_t default_perms = 0;
 
-  /* Get the perms for a newly created file to find out what bits
-     should be set.
+  /* Technically, this "racy": Multiple threads may use enter here and
+     try to figure out the default permisission concurrently. That's fine
+     since they will end up with the same results. Even more technical,
+     apr_fileperms_t is an atomic type on 32+ bit machines.
+   */
+  if (default_perms == 0)
+    {
+      apr_finfo_t finfo;
+      apr_file_t *fd;
 
-     NOTE: normally del_on_close can be problematic because APR might
-       delete the file if we spawned any child processes. In this case,
-       the lifetime of this file handle is about 3 lines of code, so
-       we can safely use del_on_close here.
+      /* Get the perms for a newly created file to find out what bits
+        should be set.
 
-     NOTE: not so fast, shorty. if some other thread forks off a child,
-       then the APR cleanups run, and the file will disappear. sigh.
+        Normally del_on_close can be problematic because APR might
+        delete the file if we spawned any child processes. In this
+        case, the lifetime of this file handle is about 3 lines of
+        code, so we can safely use del_on_close here.
+
+        Not so fast! If some other thread forks off a child, then the
+        APR cleanups run, and the file will disappear. So use
+        del_on_pool_cleanup instead.
 
-     Using svn_io_open_uniquely_named() here because other tempfile
-     creation functions tweak the permission bits of files they create.
-  */
-  SVN_ERR(svn_io_open_uniquely_named(&fd, NULL, NULL, "svn-tempfile", ".tmp",
-                                     svn_io_file_del_on_pool_cleanup,
-                                     scratch_pool, scratch_pool));
-  SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_PROT, fd, scratch_pool));
-  SVN_ERR(svn_io_file_close(fd, scratch_pool));
+        Using svn_io_open_uniquely_named() here because other tempfile
+        creation functions tweak the permission bits of files they create.
+      */
+      SVN_ERR(svn_io_open_uniquely_named(&fd, NULL, NULL, "svn-tempfile", ".tmp",
+                                        svn_io_file_del_on_pool_cleanup,
+                                        scratch_pool, scratch_pool));
+      SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_PROT, fd, scratch_pool));
+      SVN_ERR(svn_io_file_close(fd, scratch_pool));
+
+      *perms = finfo.protection;
+      default_perms = finfo.protection;
+    }
+  else
+    *perms = default_perms;
 
-  *perms = finfo.protection;
   return SVN_NO_ERROR;
 }
 
@@ -1664,7 +1721,7 @@ svn_io_file_lock2(const char *lock_file,
 
 /* Data consistency/coherency operations. */
 
-static svn_error_t *
+static APR_INLINE svn_error_t *
 do_io_file_wrapper_cleanup(apr_file_t *file, apr_status_t status,
                            const char *msg, const char *msg_no_name,
                            apr_pool_t *pool);
@@ -2545,7 +2602,6 @@ svn_io_parse_mimetypes_file(apr_hash_t *
     {
       apr_array_header_t *tokens;
       const char *type;
-      int i;
 
       svn_pool_clear(subpool);
 
@@ -2557,6 +2613,8 @@ svn_io_parse_mimetypes_file(apr_hash_t *
       /* Only pay attention to non-empty, non-comment lines. */
       if (buf->len)
         {
+          int i;
+
           if (buf->data[0] == '#')
             continue;
 
@@ -2724,7 +2782,7 @@ svn_io_file_open(apr_file_t **new_file, 
 }
 
 
-static svn_error_t *
+static APR_INLINE svn_error_t *
 do_io_file_wrapper_cleanup(apr_file_t *file, apr_status_t status,
                            const char *msg, const char *msg_no_name,
                            apr_pool_t *pool)
@@ -3819,7 +3877,7 @@ svn_io_open_unique_file3(apr_file_t **fi
    * ### So we tweak perms of the tempfile here, but only if the umask
    * ### allows it. */
   SVN_ERR(merge_default_file_perms(tempfile, &perms, scratch_pool));
-  SVN_ERR(file_perms_set(tempname, perms, scratch_pool));
+  SVN_ERR(file_perms_set2(tempfile, perms));
 #endif
 
   if (file)

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/log.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/log.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/log.c Thu Nov  4 20:48:21 2010
@@ -45,7 +45,7 @@ log_depth(svn_depth_t depth, apr_pool_t 
 {
   if (depth == svn_depth_unknown)
     return "";
-  return apr_pstrcat(pool, " depth=", svn_depth_to_word(depth), NULL);
+  return apr_pstrcat(pool, " depth=", svn_depth_to_word(depth), (char *)NULL);
 }
 
 static const char *

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/mergeinfo.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/mergeinfo.c Thu Nov  4 20:48:21 2010
@@ -1367,7 +1367,7 @@ svn_mergeinfo_catalog_merge(svn_mergeinf
       change_elt = APR_ARRAY_IDX(sorted_changes, j, svn_sort__item_t);
       res = svn_sort_compare_items_as_paths(&cat_elt, &change_elt);
 
-      if (res == 0) /* Both catalogs have mergeinfo for a give path. */
+      if (res == 0) /* Both catalogs have mergeinfo for a given path. */
         {
           svn_mergeinfo_t mergeinfo = cat_elt.value;
           svn_mergeinfo_t changes_mergeinfo = change_elt.value;

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/opt.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/opt.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/opt.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/opt.c Thu Nov  4 20:48:21 2010
@@ -88,18 +88,21 @@ svn_opt_get_option_from_code2(int code,
   for (i = 0; option_table[i].optch; i++)
     if (option_table[i].optch == code)
       {
-        int j;
         if (command)
-          for (j = 0; ((j < SVN_OPT_MAX_OPTIONS) &&
-                       command->desc_overrides[j].optch); j++)
-            if (command->desc_overrides[j].optch == code)
-              {
-                apr_getopt_option_t *tmpopt =
-                    apr_palloc(pool, sizeof(*tmpopt));
-                *tmpopt = option_table[i];
-                tmpopt->description = command->desc_overrides[j].desc;
-                return tmpopt;
-              }
+          {
+            int j;
+
+            for (j = 0; ((j < SVN_OPT_MAX_OPTIONS) &&
+                         command->desc_overrides[j].optch); j++)
+              if (command->desc_overrides[j].optch == code)
+                {
+                  apr_getopt_option_t *tmpopt =
+                      apr_palloc(pool, sizeof(*tmpopt));
+                  *tmpopt = option_table[i];
+                  tmpopt->description = command->desc_overrides[j].desc;
+                  return tmpopt;
+                }
+          }
         return &(option_table[i]);
       }
 
@@ -121,6 +124,84 @@ svn_opt_get_option_from_code(int code,
 }
 
 
+/* Like svn_opt_get_option_from_code2(), but also, if CODE appears a second
+ * time in OPTION_TABLE with a different name, then set *LONG_ALIAS to that
+ * second name, else set it to NULL. */
+static const apr_getopt_option_t *
+get_option_from_code(const char **long_alias,
+                     int code,
+                     const apr_getopt_option_t *option_table,
+                     const svn_opt_subcommand_desc2_t *command,
+                     apr_pool_t *pool)
+{
+  const apr_getopt_option_t *i;
+  const apr_getopt_option_t *opt
+    = svn_opt_get_option_from_code2(code, option_table, command, pool);
+
+  /* Find a long alias in the table, if there is one. */
+  *long_alias = NULL;
+  for (i = option_table; i->optch; i++)
+    {
+      if (i->optch == code && i->name != opt->name)
+        {
+          *long_alias = i->name;
+          break;
+        }
+    }
+
+  return opt;
+}
+
+
+/* Print an option OPT nicely into a STRING allocated in POOL.
+ * If OPT has a single-character short form, then print OPT->name (if not
+ * NULL) as an alias, else print LONG_ALIAS (if not NULL) as an alias.
+ * If DOC is set, include the generic documentation string of OPT,
+ * localized to the current locale if a translation is available.
+ */
+static void
+format_option(const char **string,
+              const apr_getopt_option_t *opt,
+              const char *long_alias,
+              svn_boolean_t doc,
+              apr_pool_t *pool)
+{
+  char *opts;
+
+  if (opt == NULL)
+    {
+      *string = "?";
+      return;
+    }
+
+  /* We have a valid option which may or may not have a "short
+     name" (a single-character alias for the long option). */
+  if (opt->optch <= 255)
+    opts = apr_psprintf(pool, "-%c [--%s]", opt->optch, opt->name);
+  else if (long_alias)
+    opts = apr_psprintf(pool, "--%s [--%s]", opt->name, long_alias);
+  else
+    opts = apr_psprintf(pool, "--%s", opt->name);
+
+  if (opt->has_arg)
+    opts = apr_pstrcat(pool, opts, _(" ARG"), (char *)NULL);
+
+  if (doc)
+    opts = apr_psprintf(pool, "%-24s : %s", opts, _(opt->description));
+
+  *string = opts;
+}
+
+void
+svn_opt_format_option(const char **string,
+                      const apr_getopt_option_t *opt,
+                      svn_boolean_t doc,
+                      apr_pool_t *pool)
+{
+  format_option(string, opt, NULL, doc, pool);
+}
+
+
 svn_boolean_t
 svn_opt_subcommand_takes_option3(const svn_opt_subcommand_desc2_t *command,
                                  int option_code,
@@ -204,6 +285,7 @@ print_command_info2(const svn_opt_subcom
   if (help)
     {
       const apr_getopt_option_t *option;
+      const char *long_alias;
       svn_boolean_t have_options = FALSE;
 
       SVN_ERR(svn_cmdline_fprintf(stream, pool, ": %s", _(cmd->help)));
@@ -221,16 +303,14 @@ print_command_info2(const svn_opt_subcom
                 }
 
               /* convert each option code into an option */
-              option =
-                svn_opt_get_option_from_code2(cmd->valid_options[i],
-                                              options_table,
-                                              cmd, pool);
+              option = get_option_from_code(&long_alias, cmd->valid_options[i],
+                                            options_table, cmd, pool);
 
               /* print the option's docstring */
               if (option && option->description)
                 {
                   const char *optstr;
-                  svn_opt_format_option(&optstr, option, TRUE, pool);
+                  format_option(&optstr, option, long_alias, TRUE, pool);
                   SVN_ERR(svn_cmdline_fprintf(stream, pool, "  %s\n",
                                               optstr));
                 }
@@ -247,16 +327,14 @@ print_command_info2(const svn_opt_subcom
             {
 
               /* convert each option code into an option */
-              option =
-                svn_opt_get_option_from_code2(global_options[i],
-                                              options_table,
-                                              cmd, pool);
+              option = get_option_from_code(&long_alias, global_options[i],
+                                            options_table, cmd, pool);
 
               /* print the option's docstring */
               if (option && option->description)
                 {
                   const char *optstr;
-                  svn_opt_format_option(&optstr, option, TRUE, pool);
+                  format_option(&optstr, option, long_alias, TRUE, pool);
                   SVN_ERR(svn_cmdline_fprintf(stream, pool, "  %s\n",
                                               optstr));
                 }
@@ -309,36 +387,6 @@ svn_opt_print_generic_help2(const char *
   svn_error_clear(err);
 }
 
-void
-svn_opt_format_option(const char **string,
-                      const apr_getopt_option_t *opt,
-                      svn_boolean_t doc,
-                      apr_pool_t *pool)
-{
-  char *opts;
-
-  if (opt == NULL)
-    {
-      *string = "?";
-      return;
-    }
-
-  /* We have a valid option which may or may not have a "short
-     name" (a single-character alias for the long option). */
-  if (opt->optch <= 255)
-    opts = apr_psprintf(pool, "-%c [--%s]", opt->optch, opt->name);
-  else
-    opts = apr_psprintf(pool, "--%s", opt->name);
-
-  if (opt->has_arg)
-    opts = apr_pstrcat(pool, opts, _(" ARG"), NULL);
-
-  if (doc)
-    opts = apr_psprintf(pool, "%-24s : %s", opts, _(opt->description));
-
-  *string = opts;
-}
-
 
 void
 svn_opt_subcommand_help3(const char *subcommand,
@@ -833,7 +881,7 @@ svn_opt__args_to_target_array(apr_array_
             }
         }
 
-      target = apr_pstrcat(pool, true_target, peg_rev, NULL);
+      target = apr_pstrcat(pool, true_target, peg_rev, (char *)NULL);
 
       APR_ARRAY_PUSH(output_targets, const char *) = target;
     }
@@ -1031,18 +1079,21 @@ svn_opt_print_help3(apr_getopt_t *os,
                     apr_pool_t *pool)
 {
   apr_array_header_t *targets = NULL;
-  int i;
 
   if (os)
     SVN_ERR(svn_opt_parse_all_args(&targets, os, pool));
 
   if (os && targets->nelts)  /* help on subcommand(s) requested */
-    for (i = 0; i < targets->nelts; i++)
-      {
-        svn_opt_subcommand_help3(APR_ARRAY_IDX(targets, i, const char *),
-                                 cmd_table, option_table,
-                                 global_options, pool);
-      }
+    {
+      int i;
+
+      for (i = 0; i < targets->nelts; i++)
+        {
+          svn_opt_subcommand_help3(APR_ARRAY_IDX(targets, i, const char *),
+                                   cmd_table, option_table,
+                                   global_options, pool);
+        }
+    }
   else if (print_version)   /* just --version */
     SVN_ERR(svn_opt__print_version_info(pgm_name, version_footer, quiet,
                                         pool));

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/sqlite.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/sqlite.c Thu Nov  4 20:48:21 2010
@@ -789,7 +789,7 @@ internal_open(sqlite3 **db3, const char 
              error than the close error at this point. */
           sqlite3_close(*db3);
 
-          msg = apr_pstrcat(scratch_pool, msg, ": '", path, "'", NULL);
+          msg = apr_pstrcat(scratch_pool, msg, ": '", path, "'", (char *)NULL);
           return svn_error_create(SQLITE_ERROR_CODE(err_code), NULL, msg);
         }
     }
@@ -941,6 +941,11 @@ svn_sqlite__open(svn_sqlite__db_t **db, 
   SVN_ERR(exec_sql(*db, "PRAGMA foreign_keys=ON;"));
 #endif
 
+  /* Store temporary tables in RAM instead of in temporary files, but don't
+     fail on this if this option is disabled in the sqlite compilation by
+     setting SQLITE_TEMP_STORE to 0 (always to disk) */
+  svn_error_clear(exec_sql(*db, "PRAGMA temp_store = MEMORY;"));
+
   /* Validate the schema, upgrading if necessary. */
   if (upgrade_sql != NULL)
     SVN_ERR(check_format(*db, latest_schema, upgrade_sql, scratch_pool));

Modified: subversion/branches/py-tests-as-modules/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/py-tests-as-modules/subversion/libsvn_subr/subst.c?rev=1031230&r1=1031229&r2=1031230&view=diff
==============================================================================
--- subversion/branches/py-tests-as-modules/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/py-tests-as-modules/subversion/libsvn_subr/subst.c Thu Nov  4 20:48:21 2010
@@ -371,16 +371,14 @@ svn_subst_build_keywords2(apr_hash_t **k
 
 
 /* Write out LEN bytes of BUF into STREAM. */
+/* ### TODO: 'stream_write()' would be a better name for this. */
 static svn_error_t *
 translate_write(svn_stream_t *stream,
                 const void *buf,
                 apr_size_t len)
 {
-  apr_size_t wrote = len;
-  svn_error_t *write_err = svn_stream_write(stream, buf, &wrote);
-  if ((write_err) || (len != wrote))
-    return write_err;
-
+  SVN_ERR(svn_stream_write(stream, buf, &len));
+  /* (No need to check LEN, as a short write always produces an error.) */
   return SVN_NO_ERROR;
 }
 
@@ -609,30 +607,36 @@ translate_keyword(char *buf,
 }
 
 
-/* Translate NEWLINE_BUF (length of NEWLINE_LEN) to the newline format
-   specified in EOL_STR (length of EOL_STR_LEN), and write the
-   translated thing to FILE (whose path is DST_PATH).
-
-   SRC_FORMAT (length *SRC_FORMAT_LEN) is a cache of the first newline
-   found while processing SRC_PATH.  If the current newline is not the
-   same style as that of SRC_FORMAT, look to the REPAIR parameter.  If
-   REPAIR is TRUE, ignore the inconsistency, else return an
-   SVN_ERR_IO_INCONSISTENT_EOL error.  If we are examining the first
-   newline in the file, copy it to {SRC_FORMAT, *SRC_FORMAT_LEN} to
-   use for later consistency checks. */
+/* Translate the newline string NEWLINE_BUF (of length NEWLINE_LEN) to
+   the newline string EOL_STR (of length EOL_STR_LEN), writing the
+   result (which is always EOL_STR) to the stream DST.
+
+   Also check for consistency of the source newline strings across
+   multiple calls, using SRC_FORMAT (length *SRC_FORMAT_LEN) as a cache
+   of the first newline found.  If the current newline is not the same
+   as SRC_FORMAT, look to the REPAIR parameter.  If REPAIR is TRUE,
+   ignore the inconsistency, else return an SVN_ERR_IO_INCONSISTENT_EOL
+   error.  If *SRC_FORMAT_LEN is 0, assume we are examining the first
+   newline in the file, and copy it to {SRC_FORMAT, *SRC_FORMAT_LEN} to
+   use for later consistency checks.
+
+   Note: all parameters are required even if REPAIR is TRUE.
+   ### We could require that REPAIR must not change across a sequence of
+       calls, and could then optimize by not using SRC_FORMAT at all if
+       REPAIR is TRUE.
+*/
 static svn_error_t *
 translate_newline(const char *eol_str,
                   apr_size_t eol_str_len,
                   char *src_format,
                   apr_size_t *src_format_len,
-                  char *newline_buf,
+                  const char *newline_buf,
                   apr_size_t newline_len,
                   svn_stream_t *dst,
                   svn_boolean_t repair)
 {
-  /* If this is the first newline we've seen, cache it
-     future comparisons, else compare it with our cache to
-     check for consistency. */
+  /* If we've seen a newline before, compare it with our cache to
+     check for consistency, else cache it for future comparisons. */
   if (*src_format_len)
     {
       /* Comparing with cache.  If we are inconsistent and
@@ -649,7 +653,7 @@ translate_newline(const char *eol_str,
       strncpy(src_format, newline_buf, newline_len);
       *src_format_len = newline_len;
     }
-  /* Translate the newline */
+  /* Write the desired newline */
   return translate_write(dst, eol_str, eol_str_len);
 }