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(©_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);
}