You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ar...@apache.org on 2011/11/21 08:08:07 UTC
svn commit: r1204374 [15/29] - in /subversion/branches/svn-bisect: ./ build/
build/ac-macros/ build/generator/ build/generator/templates/ build/win32/
contrib/client-side/ contrib/client-side/emacs/ notes/ notes/wc-ng/
subversion/bindings/javahl/native...
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/dirent_uri.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/dirent_uri.c Mon Nov 21 07:07:56 2011
@@ -884,10 +884,10 @@ svn_dirent_local_style(const char *diren
}
const char *
-svn_relpath__internal_style(const char *dirent,
- apr_pool_t *pool)
+svn_relpath__internal_style(const char *relpath,
+ apr_pool_t *pool)
{
- return svn_relpath_canonicalize(internal_style(dirent, pool), pool);
+ return svn_relpath_canonicalize(internal_style(relpath, pool), pool);
}
@@ -1403,33 +1403,6 @@ svn_dirent_is_child(const char *parent_d
}
const char *
-svn_relpath__is_child(const char *parent_relpath,
- const char *child_relpath,
- apr_pool_t *pool)
-{
- /* assert(relpath_is_canonical(parent_relpath)); */
- /* assert(relpath_is_canonical(child_relpath)); */
-
- return is_child(type_relpath, parent_relpath, child_relpath, pool);
-}
-
-const char *
-svn_uri__is_child(const char *parent_uri,
- const char *child_uri,
- apr_pool_t *pool)
-{
- const char *relpath;
-
- assert(svn_uri_is_canonical(parent_uri, NULL));
- assert(svn_uri_is_canonical(child_uri, NULL));
-
- relpath = is_child(type_uri, parent_uri, child_uri, pool);
- if (relpath)
- relpath = svn_path_uri_decode(relpath, pool);
- return relpath;
-}
-
-const char *
svn_dirent_skip_ancestor(const char *parent_dirent,
const char *child_dirent)
{
@@ -1546,12 +1519,6 @@ svn_dirent_is_ancestor(const char *paren
}
svn_boolean_t
-svn_relpath__is_ancestor(const char *parent_relpath, const char *child_relpath)
-{
- return svn_relpath_skip_ancestor(parent_relpath, child_relpath) != NULL;
-}
-
-svn_boolean_t
svn_uri__is_ancestor(const char *parent_uri, const char *child_uri)
{
return uri_skip_ancestor(parent_uri, child_uri) != NULL;
@@ -1652,7 +1619,7 @@ svn_dirent_canonicalize(const char *dire
}
svn_boolean_t
-svn_dirent_is_canonical(const char *dirent, apr_pool_t *pool)
+svn_dirent_is_canonical(const char *dirent, apr_pool_t *scratch_pool)
{
const char *ptr = dirent;
if (*ptr == '/')
@@ -1665,7 +1632,8 @@ svn_dirent_is_canonical(const char *dire
/* TODO: Scan hostname and sharename and fall back to part code */
/* ### Fall back to old implementation */
- return (strcmp(dirent, svn_dirent_canonicalize(dirent, pool)) == 0);
+ return (strcmp(dirent, svn_dirent_canonicalize(dirent, scratch_pool))
+ == 0);
}
#endif /* SVN_USE_DOS_PATHS */
}
@@ -1739,7 +1707,7 @@ svn_relpath_is_canonical(const char *rel
}
svn_boolean_t
-svn_uri_is_canonical(const char *uri, apr_pool_t *pool)
+svn_uri_is_canonical(const char *uri, apr_pool_t *scratch_pool)
{
const char *ptr = uri, *seg = uri;
const char *schema_data = NULL;
@@ -2458,21 +2426,6 @@ svn_fspath__is_root(const char *fspath,
const char *
-svn_fspath__is_child(const char *parent_fspath,
- const char *child_fspath,
- apr_pool_t *pool)
-{
- const char *result;
- assert(svn_fspath__is_canonical(parent_fspath));
- assert(svn_fspath__is_canonical(child_fspath));
-
- result = svn_relpath__is_child(parent_fspath + 1, child_fspath + 1, pool);
-
- assert(result == NULL || svn_relpath_is_canonical(result));
- return result;
-}
-
-const char *
svn_fspath__skip_ancestor(const char *parent_fspath,
const char *child_fspath)
{
@@ -2482,16 +2435,6 @@ svn_fspath__skip_ancestor(const char *pa
return svn_relpath_skip_ancestor(parent_fspath + 1, child_fspath + 1);
}
-svn_boolean_t
-svn_fspath__is_ancestor(const char *parent_fspath,
- const char *child_fspath)
-{
- assert(svn_fspath__is_canonical(parent_fspath));
- assert(svn_fspath__is_canonical(child_fspath));
-
- return svn_relpath__is_ancestor(parent_fspath + 1, child_fspath + 1);
-}
-
const char *
svn_fspath__dirname(const char *fspath,
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/dso.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/dso.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/dso.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/dso.c Mon Nov 21 07:07:56 2011
@@ -26,10 +26,10 @@
#include "svn_pools.h"
#include "svn_private_config.h"
+#include "private/svn_mutex.h"
+
/* A mutex to protect our global pool and cache. */
-#if APR_HAS_THREADS
-static apr_thread_mutex_t *dso_mutex;
-#endif
+static svn_mutex__t *dso_mutex = NULL;
/* Global pool to allocate DSOs in. */
static apr_pool_t *dso_pool;
@@ -49,40 +49,21 @@ static int not_there_sentinel;
svn_error_t *
svn_dso_initialize2(void)
{
-#if APR_HAS_THREADS
- apr_status_t status;
-#endif
if (dso_pool)
return SVN_NO_ERROR;
dso_pool = svn_pool_create(NULL);
-#if APR_HAS_THREADS
- status = apr_thread_mutex_create(&dso_mutex,
- APR_THREAD_MUTEX_DEFAULT, dso_pool);
- if (status)
- return svn_error_wrap_apr(status, _("Can't create DSO mutex"));
-#endif
+ SVN_ERR(svn_mutex__init(&dso_mutex, TRUE, dso_pool));
dso_cache = apr_hash_make(dso_pool);
return SVN_NO_ERROR;
}
#if APR_HAS_DSO
-svn_error_t *
-svn_dso_load(apr_dso_handle_t **dso, const char *fname)
+static svn_error_t *
+svn_dso_load_internal(apr_dso_handle_t **dso, const char *fname)
{
- apr_status_t status;
-
- if (! dso_pool)
- SVN_ERR(svn_dso_initialize2());
-
-#if APR_HAS_THREADS
- status = apr_thread_mutex_lock(dso_mutex);
- if (status)
- return svn_error_wrap_apr(status, _("Can't grab DSO mutex"));
-#endif
-
*dso = apr_hash_get(dso_cache, fname, APR_HASH_KEY_STRING);
/* First check to see if we've been through this before... We do this
@@ -91,18 +72,13 @@ svn_dso_load(apr_dso_handle_t **dso, con
if (*dso == NOT_THERE)
{
*dso = NULL;
-#if APR_HAS_THREADS
- status = apr_thread_mutex_unlock(dso_mutex);
- if (status)
- return svn_error_wrap_apr(status, _("Can't ungrab DSO mutex"));
-#endif
return SVN_NO_ERROR;
}
/* If we got nothing back from the cache, try and load the library. */
if (! *dso)
{
- status = apr_dso_load(dso, fname, dso_pool);
+ apr_status_t status = apr_dso_load(dso, fname, dso_pool);
if (status)
{
#ifdef SVN_DEBUG_DSO
@@ -120,11 +96,6 @@ svn_dso_load(apr_dso_handle_t **dso, con
APR_HASH_KEY_STRING,
NOT_THERE);
-#if APR_HAS_THREADS
- status = apr_thread_mutex_unlock(dso_mutex);
- if (status)
- return svn_error_wrap_apr(status, _("Can't ungrab DSO mutex"));
-#endif
return SVN_NO_ERROR;
}
@@ -135,11 +106,16 @@ svn_dso_load(apr_dso_handle_t **dso, con
*dso);
}
-#if APR_HAS_THREADS
- status = apr_thread_mutex_unlock(dso_mutex);
- if (status)
- return svn_error_wrap_apr(status, _("Can't ungrab DSO mutex"));
-#endif
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_dso_load(apr_dso_handle_t **dso, const char *fname)
+{
+ if (! dso_pool)
+ SVN_ERR(svn_dso_initialize2());
+
+ SVN_MUTEX__WITH_LOCK(dso_mutex, svn_dso_load_internal(dso, fname));
return SVN_NO_ERROR;
}
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/error.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/error.c Mon Nov 21 07:07:56 2011
@@ -64,8 +64,9 @@ static const char SVN_FILE_LINE_UNDEFINE
#undef svn_error_quick_wrap
#undef svn_error_wrap_apr
-/* Note: This function was historically in the public API, so we need
- * to define it even when !SVN_DEBUG. */
+/* Note: Although this is a "__" function, it was historically in the
+ * public ABI, so we can never change it or remove its signature, even
+ * though it is now only used in SVN_DEBUG mode. */
void
svn_error__locate(const char *file, long line)
{
@@ -663,6 +664,8 @@ svn_error_set_malfunction_handler(svn_er
return old_malfunction_handler;
}
+/* Note: Although this is a "__" function, it is in the public ABI, so
+ * we can never remove it or change its signature. */
svn_error_t *
svn_error__malfunction(svn_boolean_t can_return,
const char *file, int line,
Propchange: subversion/branches/svn-bisect/subversion/libsvn_subr/hash.c
('svn:mergeinfo' removed)
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/io.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/io.c Mon Nov 21 07:07:56 2011
@@ -2158,8 +2158,11 @@ svn_io_remove_file2(const char *path,
}
#endif
- return svn_error_wrap_apr(apr_err, _("Can't remove file '%s'"),
- svn_dirent_local_style(path, scratch_pool));
+ if (apr_err)
+ return svn_error_wrap_apr(apr_err, _("Can't remove file '%s'"),
+ svn_dirent_local_style(path, scratch_pool));
+
+ return SVN_NO_ERROR;
}
@@ -2934,9 +2937,11 @@ svn_io_detect_mimetype2(const char **mim
heuristic. */
if (mimetype_map)
{
- const char *type_from_map, *path_ext;
- svn_path_splitext(NULL, &path_ext, file, pool);
- fileext_tolower((char *)path_ext);
+ const char *type_from_map;
+ char *path_ext; /* Can point to physical const memory but only when
+ svn_path_splitext sets it to "". */
+ svn_path_splitext(NULL, (const char **)&path_ext, file, pool);
+ fileext_tolower(path_ext);
if ((type_from_map = apr_hash_get(mimetype_map, path_ext,
APR_HASH_KEY_STRING)))
{
@@ -2975,6 +2980,13 @@ svn_io_is_binary_data(const void *data,
{
const unsigned char *buf = data;
+ if (len == 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF)
+ {
+ /* This is an empty UTF-8 file which only contains the UTF-8 BOM.
+ * Treat it as plain text. */
+ return FALSE;
+ }
+
/* Right now, this function is going to be really stupid. It's
going to examine the block of data, and make sure that 15%
of the bytes are such that their value is in the ranges 0x07-0x0D
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/iter.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/iter.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/iter.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/iter.c Mon Nov 21 07:07:56 2011
@@ -176,6 +176,8 @@ svn_iter_apr_array(svn_boolean_t *comple
return err;
}
+/* Note: Although this is a "__" function, it is in the public ABI, so
+ * we can never remove it or change its signature. */
svn_error_t *
svn_iter__break(void)
{
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/log.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/log.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/log.c Mon Nov 21 07:07:56 2011
@@ -121,7 +121,7 @@ svn_log__get_mergeinfo(const apr_array_h
{
int i;
apr_pool_t *iterpool = svn_pool_create(pool);
- svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
+ svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
for (i = 0; i < paths->nelts; i++)
{
@@ -210,8 +210,8 @@ svn_log__log(const apr_array_header_t *p
{
int i;
apr_pool_t *iterpool = svn_pool_create(pool);
- svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
- svn_stringbuf_t *options = svn_stringbuf_create("", pool);
+ svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
+ svn_stringbuf_t *options = svn_stringbuf_create_empty(pool);
for (i = 0; i < paths->nelts; i++)
{
@@ -264,7 +264,7 @@ svn_log__get_locations(const char *path,
{
const svn_revnum_t *revision_ptr, *revision_ptr_start, *revision_ptr_end;
apr_pool_t *iterpool = svn_pool_create(pool);
- svn_stringbuf_t *space_separated_revnums = svn_stringbuf_create("", pool);
+ svn_stringbuf_t *space_separated_revnums = svn_stringbuf_create_empty(pool);
revision_ptr_start = (const svn_revnum_t *)location_revisions->elts;
revision_ptr = revision_ptr_start;
@@ -311,7 +311,7 @@ svn_log__lock(const apr_array_header_t *
{
int i;
apr_pool_t *iterpool = svn_pool_create(pool);
- svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
+ svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
for (i = 0; i < paths->nelts; i++)
{
@@ -334,7 +334,7 @@ svn_log__unlock(const apr_array_header_t
{
int i;
apr_pool_t *iterpool = svn_pool_create(pool);
- svn_stringbuf_t *space_separated_paths = svn_stringbuf_create("", pool);
+ svn_stringbuf_t *space_separated_paths = svn_stringbuf_create_empty(pool);
for (i = 0; i < paths->nelts; i++)
{
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/magic.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/magic.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/magic.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/magic.c Mon Nov 21 07:07:56 2011
@@ -45,8 +45,9 @@
struct svn_magic__cookie_t {
#ifdef SVN_HAVE_LIBMAGIC
magic_t magic;
-#endif
+#else
char dummy;
+#endif
};
#ifdef SVN_HAVE_LIBMAGIC
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/mergeinfo.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/mergeinfo.c Mon Nov 21 07:07:56 2011
@@ -78,7 +78,7 @@ combine_ranges(svn_merge_range_t *output
static svn_error_t *
parse_pathname(const char **input,
const char *end,
- svn_stringbuf_t **pathname,
+ const char **pathname,
apr_pool_t *pool)
{
const char *curr = *input;
@@ -101,17 +101,11 @@ parse_pathname(const char **input,
return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
_("No pathname preceding ':'"));
- /* Tolerate relative repository paths, but convert them to absolute. */
- if (**input == '/')
- {
- *pathname = svn_stringbuf_ncreate(*input, last_colon - *input, pool);
- }
- else
- {
- const char *repos_rel_path = apr_pstrndup(pool, *input,
- last_colon - *input);
- *pathname = svn_stringbuf_createf(pool, "/%s", repos_rel_path);
- }
+ /* Tolerate relative repository paths, but convert them to absolute.
+ ### Efficiency? 1 string duplication here, 2 in canonicalize. */
+ *pathname = svn_fspath__canonicalize(apr_pstrndup(pool, *input,
+ last_colon - *input),
+ pool);
*input = last_colon;
@@ -245,15 +239,13 @@ get_type_of_intersection(const svn_merge
When replacing the last range in RANGELIST, either allocate a new range in
RESULT_POOL or modify the existing range in place. Any new ranges added
- to RANGELIST are allocated in RESULT_POOL. SCRATCH_POOL is used for any
- temporary allocations.
+ to RANGELIST are allocated in RESULT_POOL.
*/
static svn_error_t *
combine_with_lastrange(const svn_merge_range_t *new_range,
apr_array_header_t *rangelist,
svn_boolean_t consider_inheritance,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+ apr_pool_t *result_pool)
{
svn_merge_range_t *lastrange;
svn_merge_range_t combined_range;
@@ -301,143 +293,168 @@ combine_with_lastrange(const svn_merge_r
intersect but have differing inheritability. Check for the
first case as that is easy to handle. */
intersection_type_t intersection_type;
+ svn_boolean_t sorted = FALSE;
SVN_ERR(get_type_of_intersection(new_range, lastrange,
&intersection_type));
- switch (intersection_type)
+ switch (intersection_type)
+ {
+ case svn__no_intersection:
+ /* NEW_RANGE and *LASTRANGE *really* don't intersect so
+ just push NEW_RANGE only RANGELIST. */
+ APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
+ svn_merge_range_dup(new_range, result_pool);
+ sorted = (svn_sort_compare_ranges(&lastrange,
+ &new_range) < 0);
+ break;
+
+ case svn__equal_intersection:
+ /* They range are equal so all we do is force the
+ inheritability of lastrange to true. */
+ lastrange->inheritable = TRUE;
+ sorted = TRUE;
+ break;
+
+ case svn__adjoining_intersection:
+ /* They adjoin but don't overlap so just push NEW_RANGE
+ onto RANGELIST. */
+ APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
+ svn_merge_range_dup(new_range, result_pool);
+ sorted = (svn_sort_compare_ranges(&lastrange,
+ &new_range) < 0);
+ break;
+
+ case svn__overlapping_intersection:
+ /* They ranges overlap but neither is a proper subset of
+ the other. We'll end up pusing two new ranges onto
+ RANGELIST, the intersecting part and the part unique to
+ NEW_RANGE.*/
{
- case svn__no_intersection:
- /* NEW_RANGE and *LASTRANGE *really* don't intersect so
- just push NEW_RANGE only RANGELIST. */
- APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
- svn_merge_range_dup(new_range, result_pool);
- break;
-
- case svn__equal_intersection:
- /* They range are equal so all we do is force the
- inheritability of lastrange to true. */
- lastrange->inheritable = TRUE;
- break;
-
- case svn__adjoining_intersection:
- /* They adjoin but don't overlap so just push NEW_RANGE
- onto RANGELIST. */
- APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
- svn_merge_range_dup(new_range, result_pool);
- break;
-
- case svn__overlapping_intersection:
- /* They ranges overlap but neither is a proper subset of
- the other. We'll end up pusing two new ranges onto
- RANGELIST, the intersecting part and the part unique to
- NEW_RANGE.*/
+ svn_merge_range_t *r1 = svn_merge_range_dup(lastrange,
+ result_pool);
+ svn_merge_range_t *r2 = svn_merge_range_dup(new_range,
+ result_pool);
+
+ /* Pop off *LASTRANGE to make our manipulations
+ easier. */
+ apr_array_pop(rangelist);
+
+ /* Ensure R1 is the older range. */
+ if (r2->start < r1->start)
{
- svn_merge_range_t *r1 = svn_merge_range_dup(lastrange,
- result_pool);
- svn_merge_range_t *r2 = svn_merge_range_dup(new_range,
- result_pool);
-
- /* Pop off *LASTRANGE to make our manipulations
- easier. */
- apr_array_pop(rangelist);
+ /* Swap R1 and R2. */
+ *r2 = *r1;
+ *r1 = *new_range;
+ }
- /* Ensure R1 is the older range. */
- if (r2->start < r1->start)
- {
- /* Swap R1 and R2. */
- *r2 = *r1;
- *r1 = *new_range;
- }
+ /* Absorb the intersecting ranges into the
+ inheritable range. */
+ if (r1->inheritable)
+ r2->start = r1->end;
+ else
+ r1->end = r2->start;
- /* Absorb the intersecting ranges into the
- inheritable range. */
- if (r1->inheritable)
- r2->start = r1->end;
- else
- r1->end = r2->start;
+ /* Push everything back onto RANGELIST. */
+ APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r1;
+ sorted = (svn_sort_compare_ranges(&lastrange,
+ &r1) < 0);
+ APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r2;
+ if (sorted)
+ sorted = (svn_sort_compare_ranges(&r1, &r2) < 0);
+ break;
+ }
- /* Push everything back onto RANGELIST. */
- APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r1;
- APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r2;
+ default: /* svn__proper_subset_intersection */
+ {
+ /* One range is a proper subset of the other. */
+ svn_merge_range_t *r1 = svn_merge_range_dup(lastrange,
+ result_pool);
+ svn_merge_range_t *r2 = svn_merge_range_dup(new_range,
+ result_pool);
+ svn_merge_range_t *r3 = NULL;
+
+ /* Pop off *LASTRANGE to make our manipulations
+ easier. */
+ apr_array_pop(rangelist);
- break;
+ /* Ensure R1 is the superset. */
+ if (r2->start < r1->start || r2->end > r1->end)
+ {
+ /* Swap R1 and R2. */
+ *r2 = *r1;
+ *r1 = *new_range;
}
- default: /* svn__proper_subset_intersection */
+ if (r1->inheritable)
{
- /* One range is a proper subset of the other. */
- svn_merge_range_t *r1 = svn_merge_range_dup(lastrange,
- result_pool);
- svn_merge_range_t *r2 = svn_merge_range_dup(new_range,
- result_pool);
- svn_merge_range_t *r3 = NULL;
-
- /* Pop off *LASTRANGE to make our manipulations
- easier. */
- apr_array_pop(rangelist);
-
- /* Ensure R1 is the superset. */
- if (r2->start < r1->start || r2->end > r1->end)
- {
- /* Swap R1 and R2. */
- *r2 = *r1;
- *r1 = *new_range;
- }
+ /* The simple case: The superset is inheritable, so
+ just combine r1 and r2. */
+ r1->start = MIN(r1->start, r2->start);
+ r1->end = MAX(r1->end, r2->end);
+ r2 = NULL;
+ }
+ else if (r1->start == r2->start)
+ {
+ svn_revnum_t tmp_revnum;
- if (r1->inheritable)
- {
- /* The simple case: The superset is inheritable, so
- just combine r1 and r2. */
- r1->start = MIN(r1->start, r2->start);
- r1->end = MAX(r1->end, r2->end);
- r2 = NULL;
- }
- else if (r1->start == r2->start)
- {
- svn_revnum_t tmp_revnum;
+ /* *LASTRANGE and NEW_RANGE share an end point. */
+ tmp_revnum = r1->end;
+ r1->end = r2->end;
+ r2->inheritable = r1->inheritable;
+ r1->inheritable = TRUE;
+ r2->start = r1->end;
+ r2->end = tmp_revnum;
+ }
+ else if (r1->end == r2->end)
+ {
+ /* *LASTRANGE and NEW_RANGE share an end point. */
+ r1->end = r2->start;
+ r2->inheritable = TRUE;
+ }
+ else
+ {
+ /* NEW_RANGE and *LASTRANGE share neither start
+ nor end points. */
+ r3 = apr_pcalloc(result_pool, sizeof(*r3));
+ r3->start = r2->end;
+ r3->end = r1->end;
+ r3->inheritable = r1->inheritable;
+ r2->inheritable = TRUE;
+ r1->end = r2->start;
+ }
- /* *LASTRANGE and NEW_RANGE share an end point. */
- tmp_revnum = r1->end;
- r1->end = r2->end;
- r2->inheritable = r1->inheritable;
- r1->inheritable = TRUE;
- r2->start = r1->end;
- r2->end = tmp_revnum;
- }
- else if (r1->end == r2->end)
- {
- /* *LASTRANGE and NEW_RANGE share an end point. */
- r1->end = r2->start;
- r2->inheritable = TRUE;
- }
- else
+ /* Push everything back onto RANGELIST. */
+ APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r1;
+ sorted = (svn_sort_compare_ranges(&lastrange, &r1) < 0);
+ if (r2)
+ {
+ APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r2;
+ if (sorted)
+ sorted = (svn_sort_compare_ranges(&r1, &r2) < 0);
+ }
+ if (r3)
+ {
+ APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r3;
+ if (sorted)
{
- /* NEW_RANGE and *LASTRANGE share neither start
- nor end points. */
- r3 = apr_pcalloc(result_pool, sizeof(*r3));
- r3->start = r2->end;
- r3->end = r1->end;
- r3->inheritable = r1->inheritable;
- r2->inheritable = TRUE;
- r1->end = r2->start;
+ if (r2)
+ sorted = (svn_sort_compare_ranges(&r2,
+ &r3) < 0);
+ else
+ sorted = (svn_sort_compare_ranges(&r1,
+ &r3) < 0);
}
-
- /* Push everything back onto RANGELIST. */
- APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r1;
- if (r2)
- APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r2;
- if (r3)
- APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r3;
-
- break;
}
+ break;
}
+ }
- /* Some of the above cases might have put *RANGELIST out of
- order, so re-sort.*/
- qsort(rangelist->elts, rangelist->nelts, rangelist->elt_size,
- svn_sort_compare_ranges);
+ /* Some of the above cases might have put *RANGELIST out of
+ order, so re-sort.*/
+ if (!sorted)
+ qsort(rangelist->elts, rangelist->nelts, rangelist->elt_size,
+ svn_sort_compare_ranges);
}
}
@@ -471,13 +488,10 @@ range_to_string(const svn_merge_range_t
revisionlist -> (revisionelement)(COMMA revisionelement)*
revisionrange -> REVISION "-" REVISION("*")
revisionelement -> revisionrange | REVISION("*")
-
- PATHNAME is the path this revisionlist is mapped to. It is
- used only for producing a more descriptive error message.
*/
static svn_error_t *
parse_rangelist(const char **input, const char *end,
- apr_array_header_t *rangelist, const char *pathname,
+ apr_array_header_t *rangelist,
apr_pool_t *pool)
{
const char *curr = *input;
@@ -490,9 +504,7 @@ parse_rangelist(const char **input, cons
{
/* Empty range list. */
*input = curr;
- return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
- _("Mergeinfo for '%s' maps to an "
- "empty revision range"), pathname);
+ return SVN_NO_ERROR;
}
while (curr < end && *curr != '\n')
@@ -586,17 +598,29 @@ parse_rangelist(const char **input, cons
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_rangelist__parse(apr_array_header_t **rangelist,
+ const char *str,
+ apr_pool_t *result_pool)
+{
+ const char *s = str;
+
+ *rangelist = apr_array_make(result_pool, 1, sizeof(svn_merge_range_t *));
+ SVN_ERR(parse_rangelist(&s, s + strlen(s), *rangelist, result_pool));
+ return SVN_NO_ERROR;
+}
+
/* revisionline -> PATHNAME COLON revisionlist */
static svn_error_t *
parse_revision_line(const char **input, const char *end, svn_mergeinfo_t hash,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
- svn_stringbuf_t *pathname;
+ const char *pathname;
apr_array_header_t *existing_rangelist;
- apr_array_header_t *rangelist = apr_array_make(pool, 1,
+ apr_array_header_t *rangelist = apr_array_make(scratch_pool, 1,
sizeof(svn_merge_range_t *));
- SVN_ERR(parse_pathname(input, end, &pathname, pool));
+ SVN_ERR(parse_pathname(input, end, &pathname, scratch_pool));
if (*(*input) != ':')
return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
@@ -604,8 +628,12 @@ parse_revision_line(const char **input,
*input = *input + 1;
- SVN_ERR(parse_rangelist(input, end, rangelist, pathname->data, pool));
+ SVN_ERR(parse_rangelist(input, end, rangelist, scratch_pool));
+ if (rangelist->nelts == 0)
+ return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
+ _("Mergeinfo for '%s' maps to an "
+ "empty revision range"), pathname);
if (*input != end && *(*input) != '\n')
return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
_("Could not find end of line in range list line "
@@ -643,8 +671,10 @@ parse_revision_line(const char **input,
"revision ranges '%s' and '%s' "
"with different inheritance "
"types"),
- range_to_string(lastrange, pool),
- range_to_string(range, pool));
+ range_to_string(lastrange,
+ scratch_pool),
+ range_to_string(range,
+ scratch_pool));
}
/* Combine overlapping or adjacent ranges with the
@@ -670,11 +700,14 @@ parse_revision_line(const char **input,
leading slash, e.g. "trunk:4033\n/trunk:4039-4995". In the event
we encounter this we merge the rangelists together under a single
absolute path key. */
- existing_rangelist = apr_hash_get(hash, pathname->data, APR_HASH_KEY_STRING);
+ existing_rangelist = apr_hash_get(hash, pathname, APR_HASH_KEY_STRING);
if (existing_rangelist)
- SVN_ERR(svn_rangelist_merge2(rangelist, existing_rangelist, pool, pool));
+ SVN_ERR(svn_rangelist_merge2(rangelist, existing_rangelist,
+ scratch_pool, scratch_pool));
- apr_hash_set(hash, pathname->data, APR_HASH_KEY_STRING, rangelist);
+ apr_hash_set(hash, apr_pstrdup(apr_hash_pool_get(hash), pathname),
+ APR_HASH_KEY_STRING,
+ svn_rangelist_dup(rangelist, apr_hash_pool_get(hash)));
return SVN_NO_ERROR;
}
@@ -684,8 +717,14 @@ static svn_error_t *
parse_top(const char **input, const char *end, svn_mergeinfo_t hash,
apr_pool_t *pool)
{
+ apr_pool_t *iterpool = svn_pool_create(pool);
+
while (*input < end)
- SVN_ERR(parse_revision_line(input, end, hash, pool));
+ {
+ svn_pool_clear(iterpool);
+ SVN_ERR(parse_revision_line(input, end, hash, iterpool));
+ }
+ svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
@@ -708,73 +747,401 @@ svn_mergeinfo_parse(svn_mergeinfo_t *mer
return err;
}
+/* Cleanup after svn_rangelist_merge2 when it modifies the ending range of
+ a single rangelist element in-place.
+
+ If *RANGE_INDEX is not a valid element in RANGELIST do nothing. Otherwise
+ ensure that RANGELIST[*RANGE_INDEX]->END does not adjoin or overlap any
+ subsequent ranges in RANGELIST.
+
+ If overlap is found, then remove, modify, and/or add elements to RANGELIST
+ as per the invariants for rangelists documented in svn_mergeinfo.h. If
+ RANGELIST[*RANGE_INDEX]->END adjoins a subsequent element then combine the
+ elements if their inheritability permits -- The inheritance of intersecting
+ and adjoining ranges is handled as per svn_mergeinfo_merge2. Upon return
+ set *RANGE_INDEX to the index of the youngest element modified, added, or
+ adjoined to RANGELIST[*RANGE_INDEX].
+
+ Note: Adjoining rangelist elements are those where the end rev of the older
+ element is equal to the start rev of the younger element.
+
+ Any new elements inserted into RANGELIST are allocated in RESULT_POOL.*/
+static void
+adjust_remaining_ranges(apr_array_header_t *rangelist,
+ int *range_index,
+ apr_pool_t *result_pool)
+{
+ int i;
+ int starting_index;
+ int elements_to_delete = 0;
+ svn_merge_range_t *modified_range;
+
+ if (*range_index >= rangelist->nelts)
+ return;
+
+ starting_index = *range_index + 1;
+ modified_range = APR_ARRAY_IDX(rangelist, *range_index, svn_merge_range_t *);
+
+ for (i = *range_index + 1; i < rangelist->nelts; i++)
+ {
+ svn_merge_range_t *next_range = APR_ARRAY_IDX(rangelist, i,
+ svn_merge_range_t *);
+
+ /* If MODIFIED_RANGE doesn't adjoin or overlap the next range in
+ RANGELIST then we are finished. */
+ if (modified_range->end < next_range->start)
+ break;
+
+ /* Does MODIFIED_RANGE adjoin NEXT_RANGE? */
+ if (modified_range->end == next_range->start)
+ {
+ if (modified_range->inheritable == next_range->inheritable)
+ {
+ /* Combine adjoining ranges with the same inheritability. */
+ modified_range->end = next_range->end;
+ elements_to_delete++;
+ }
+ else
+ {
+ /* Cannot join because inheritance differs. */
+ (*range_index)++;
+ }
+ break;
+ }
+
+ /* Alright, we know MODIFIED_RANGE overlaps NEXT_RANGE, but how? */
+ if (modified_range->end > next_range->end)
+ {
+ /* NEXT_RANGE is a proper subset of MODIFIED_RANGE and the two
+ don't share the same end range. */
+ if (modified_range->inheritable
+ || (modified_range->inheritable == next_range->inheritable))
+ {
+ /* MODIFIED_RANGE absorbs NEXT_RANGE. */
+ elements_to_delete++;
+ }
+ else
+ {
+ /* NEXT_RANGE is a proper subset MODIFIED_RANGE but
+ MODIFIED_RANGE is non-inheritable and NEXT_RANGE is
+ inheritable. This means MODIFIED_RANGE is truncated,
+ NEXT_RANGE remains, and the portion of MODIFIED_RANGE
+ younger than NEXT_RANGE is added as a separate range:
+ ______________________________________________
+ | |
+ M MODIFIED_RANGE N
+ | (!inhertiable) |
+ |______________________________________________|
+ | |
+ O NEXT_RANGE P
+ | (inheritable)|
+ |______________|
+ |
+ V
+ _______________________________________________
+ | | | |
+ M MODIFIED_RANGE O NEXT_RANGE P NEW_RANGE N
+ | (!inhertiable) | (inheritable)| (!inheritable)|
+ |________________|______________|_______________|
+ */
+ svn_merge_range_t *new_modified_range =
+ apr_palloc(result_pool, sizeof(*new_modified_range));
+ new_modified_range->start = next_range->end;
+ new_modified_range->end = modified_range->end;
+ new_modified_range->inheritable = FALSE;
+ modified_range->end = next_range->start;
+ (*range_index)+=2;
+ svn_sort__array_insert(&new_modified_range, rangelist,
+ *range_index);
+ /* Recurse with the new range. */
+ adjust_remaining_ranges(rangelist, range_index, result_pool);
+ break;
+ }
+ }
+ else if (modified_range->end == next_range->end)
+ {
+ /* NEXT_RANGE is a proper subset MODIFIED_RANGE and share
+ the same end range. */
+ if (modified_range->inheritable
+ || (modified_range->inheritable == next_range->inheritable))
+ {
+ /* MODIFIED_RANGE absorbs NEXT_RANGE. */
+ elements_to_delete++;
+ }
+ else
+ {
+ /* The intersection between MODIFIED_RANGE and NEXT_RANGE is
+ absorbed by the latter. */
+ modified_range->end = next_range->start;
+ (*range_index)++;
+ }
+ break;
+ }
+ else
+ {
+ /* NEXT_RANGE and MODIFIED_RANGE intersect but NEXT_RANGE is not
+ a proper subset of MODIFIED_RANGE, nor do the two share the
+ same end revision, i.e. they overlap. */
+ if (modified_range->inheritable == next_range->inheritable)
+ {
+ /* Combine overlapping ranges with the same inheritability. */
+ modified_range->end = next_range->end;
+ elements_to_delete++;
+ }
+ else if (modified_range->inheritable)
+ {
+ /* MODIFIED_RANGE absorbs the portion of NEXT_RANGE it overlaps
+ and NEXT_RANGE is truncated. */
+ next_range->start = modified_range->end;
+ (*range_index)++;
+ }
+ else
+ {
+ /* NEXT_RANGE absorbs the portion of MODIFIED_RANGE it overlaps
+ and MODIFIED_RANGE is truncated. */
+ modified_range->end = next_range->start;
+ (*range_index)++;
+ }
+ break;
+ }
+ }
+
+ if (elements_to_delete)
+ svn_sort__array_delete(rangelist, starting_index, elements_to_delete);
+}
+
svn_error_t *
svn_rangelist_merge2(apr_array_header_t *rangelist,
const apr_array_header_t *changes,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- int i, j;
- apr_array_header_t *original_rangelist;
-
- original_rangelist = apr_array_copy(scratch_pool, rangelist);
- apr_array_clear(rangelist);
+ int i = 0;
+ int j = 0;
- i = 0;
- j = 0;
- while (i < (original_rangelist)->nelts && j < changes->nelts)
- {
- svn_merge_range_t *elt1, *elt2;
- int res;
+ /* We may modify CHANGES, so make a copy in SCRATCH_POOL. */
+ changes = svn_rangelist_dup(changes, scratch_pool);
- elt1 = APR_ARRAY_IDX(original_rangelist, i, svn_merge_range_t *);
- elt2 = APR_ARRAY_IDX(changes, j, svn_merge_range_t *);
+ while (i < rangelist->nelts && j < changes->nelts)
+ {
+ svn_merge_range_t *range =
+ APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
+ svn_merge_range_t *change =
+ APR_ARRAY_IDX(changes, j, svn_merge_range_t *);
+ int res = svn_sort_compare_ranges(&range, &change);
- res = svn_sort_compare_ranges(&elt1, &elt2);
if (res == 0)
{
/* Only when merging two non-inheritable ranges is the result also
non-inheritable. In all other cases ensure an inheritiable
result. */
- if (elt1->inheritable || elt2->inheritable)
- elt1->inheritable = TRUE;
- SVN_ERR(combine_with_lastrange(elt1, rangelist, TRUE, result_pool,
- scratch_pool));
+ if (range->inheritable || change->inheritable)
+ range->inheritable = TRUE;
i++;
j++;
}
- else if (res < 0)
+ else if (res < 0) /* CHANGE is younger than RANGE */
{
- SVN_ERR(combine_with_lastrange(elt1, rangelist, TRUE, result_pool,
- scratch_pool));
- i++;
+ if (range->end < change->start)
+ {
+ /* RANGE is older than CHANGE and the two do not
+ adjoin or overlap */
+ i++;
+ }
+ else if (range->end == change->start)
+ {
+ /* RANGE and CHANGE adjoin */
+ if (range->inheritable == change->inheritable)
+ {
+ /* RANGE and CHANGE have the same inheritability so
+ RANGE expands to absord CHANGE. */
+ range->end = change->end;
+ adjust_remaining_ranges(rangelist, &i, result_pool);
+ j++;
+ }
+ else
+ {
+ /* RANGE and CHANGE adjoin, but have different
+ inheritability. Since RANGE is older, just
+ move on to the next RANGE. */
+ i++;
+ }
+ }
+ else
+ {
+ /* RANGE and CHANGE overlap, but how? */
+ if ((range->inheritable == change->inheritable)
+ || range->inheritable)
+ {
+ /* If CHANGE is a proper subset of RANGE, it absorbs RANGE
+ with no adjustment otherwise only the intersection is
+ absorbed and CHANGE is truncated. */
+ if (range->end >= change->end)
+ j++;
+ else
+ change->start = range->end;
+ }
+ else
+ {
+ /* RANGE is non-inheritable and CHANGE is inheritable. */
+ if (range->start < change->start)
+ {
+ /* CHANGE absorbs intersection with RANGE and RANGE
+ is truncated. */
+ svn_merge_range_t *range_copy =
+ svn_merge_range_dup(range, result_pool);
+ range_copy->end = change->start;
+ range->start = change->start;
+ svn_sort__array_insert(&range_copy, rangelist, i++);
+ }
+ else
+ {
+ /* CHANGE and RANGE share the same start rev, but
+ RANGE is considered older because its end rev
+ is older. */
+ range->inheritable = TRUE;
+ change->start = range->end;
+ }
+ }
+ }
}
- else
+ else /* res > 0, CHANGE is older than RANGE */
{
- SVN_ERR(combine_with_lastrange(elt2, rangelist, TRUE, result_pool,
- scratch_pool));
- j++;
+ if (change->end < range->start)
+ {
+ /* CHANGE is older than RANGE and the two do not
+ adjoin or overlap, so insert a copy of CHANGE
+ into RANGELIST. */
+ svn_merge_range_t *change_copy =
+ svn_merge_range_dup(change, result_pool);
+ svn_sort__array_insert(&change_copy, rangelist, i++);
+ j++;
+ }
+ else if (change->end == range->start)
+ {
+ /* RANGE and CHANGE adjoin */
+ if (range->inheritable == change->inheritable)
+ {
+ /* RANGE and CHANGE have the same inheritability so we
+ can simply combine the two in place. */
+ range->start = change->start;
+ j++;
+ }
+ else
+ {
+ /* RANGE and CHANGE have different inheritability so insert
+ a copy of CHANGE into RANGELIST. */
+ svn_merge_range_t *change_copy =
+ svn_merge_range_dup(change, result_pool);
+ svn_sort__array_insert(&change_copy, rangelist, i);
+ j++;
+ }
+ }
+ else
+ {
+ /* RANGE and CHANGE overlap. */
+ if (range->inheritable == change->inheritable)
+ {
+ /* RANGE and CHANGE have the same inheritability so we
+ can simply combine the two in place... */
+ range->start = change->start;
+ if (range->end < change->end)
+ {
+ /* ...but if RANGE is expanded ensure that we don't
+ violate any rangelist invariants. */
+ range->end = change->end;
+ adjust_remaining_ranges(rangelist, &i, result_pool);
+ }
+ j++;
+ }
+ else if (range->inheritable)
+ {
+ if (change->start < range->start)
+ {
+ /* RANGE is inheritable so absorbs any part of CHANGE
+ it overlaps. CHANGE is truncated and the remainder
+ inserted into RANGELIST. */
+ svn_merge_range_t *change_copy =
+ svn_merge_range_dup(change, result_pool);
+ change_copy->end = range->start;
+ change->start = range->start;
+ svn_sort__array_insert(&change_copy, rangelist, i++);
+ }
+ else
+ {
+ /* CHANGE and RANGE share the same start rev, but
+ CHANGE is considered older because CHANGE->END is
+ older than RANGE->END. */
+ j++;
+ }
+ }
+ else
+ {
+ /* RANGE is non-inheritable and CHANGE is inheritable. */
+ if (change->start < range->start)
+ {
+ if (change->end == range->end)
+ {
+ /* RANGE is a proper subset of CHANGE and share the
+ same end revision, so set RANGE equal to CHANGE. */
+ range->start = change->start;
+ range->inheritable = TRUE;
+ j++;
+ }
+ else if (change->end > range->end)
+ {
+ /* RANGE is a proper subset of CHANGE and CHANGE has
+ a younger end revision, so set RANGE equal to its
+ intersection with CHANGE and truncate CHANGE. */
+ range->start = change->start;
+ range->inheritable = TRUE;
+ change->start = range->end;
+ }
+ else
+ {
+ /* CHANGE and RANGE overlap. Set RANGE equal to its
+ intersection with CHANGE and take the remainder
+ of RANGE and insert it into RANGELIST. */
+ svn_merge_range_t *range_copy =
+ svn_merge_range_dup(range, result_pool);
+ range_copy->start = change->end;
+ range->start = change->start;
+ range->end = change->end;
+ range->inheritable = TRUE;
+ svn_sort__array_insert(&range_copy, rangelist, ++i);
+ j++;
+ }
+ }
+ else
+ {
+ /* CHANGE and RANGE share the same start rev, but
+ CHANGE is considered older because its end rev
+ is older.
+
+ Insert the intersection of RANGE and CHANGE into
+ RANGELIST and then set RANGE to the non-intersecting
+ portion of RANGE. */
+ svn_merge_range_t *range_copy =
+ svn_merge_range_dup(range, result_pool);
+ range_copy->end = change->end;
+ range_copy->inheritable = TRUE;
+ range->start = change->end;
+ svn_sort__array_insert(&range_copy, rangelist, i++);
+ j++;
+ }
+ }
+ }
}
}
- /* Copy back any remaining elements.
- Only one of these loops should end up running, if anything. */
-
- SVN_ERR_ASSERT(!(i < (original_rangelist)->nelts && j < changes->nelts));
-
- for (; i < (original_rangelist)->nelts; i++)
- {
- svn_merge_range_t *elt = APR_ARRAY_IDX(original_rangelist, i,
- svn_merge_range_t *);
- SVN_ERR(combine_with_lastrange(elt, rangelist, TRUE, result_pool,
- scratch_pool));
- }
-
- for (; j < changes->nelts; j++)
+ /* Copy any remaining elements in CHANGES into RANGELIST. */
+ for (; j < (changes)->nelts; j++)
{
- svn_merge_range_t *elt = APR_ARRAY_IDX(changes, j, svn_merge_range_t *);
- SVN_ERR(combine_with_lastrange(elt, rangelist,
- TRUE, result_pool, scratch_pool));
+ svn_merge_range_t *change =
+ APR_ARRAY_IDX(changes, j, svn_merge_range_t *);
+ svn_merge_range_t *change_copy = svn_merge_range_dup(change,
+ result_pool);
+ svn_sort__array_insert(&change_copy, rangelist, rangelist->nelts);
}
return SVN_NO_ERROR;
@@ -972,7 +1339,7 @@ rangelist_intersect_or_remove(apr_array_
tmp_range.inheritable =
(elt2->inheritable || elt1->inheritable);
SVN_ERR(combine_with_lastrange(&tmp_range, *output,
- consider_inheritance, pool,
+ consider_inheritance,
pool));
}
@@ -1009,7 +1376,7 @@ rangelist_intersect_or_remove(apr_array_
SVN_ERR(combine_with_lastrange(&tmp_range,
*output, consider_inheritance,
- pool, pool));
+ pool));
}
/* Set up the rest of the rangelist2 range for further
@@ -1030,7 +1397,7 @@ rangelist_intersect_or_remove(apr_array_
SVN_ERR(combine_with_lastrange(&tmp_range,
*output,
consider_inheritance,
- pool, pool));
+ pool));
}
working_elt2.start = elt1->end;
@@ -1082,7 +1449,7 @@ rangelist_intersect_or_remove(apr_array_
if (i2 == lasti2 && i2 < rangelist2->nelts)
{
SVN_ERR(combine_with_lastrange(&working_elt2, *output,
- consider_inheritance, pool, pool));
+ consider_inheritance, pool));
i2++;
}
@@ -1093,7 +1460,7 @@ rangelist_intersect_or_remove(apr_array_
svn_merge_range_t *);
SVN_ERR(combine_with_lastrange(elt, *output,
- consider_inheritance, pool, pool));
+ consider_inheritance, pool));
}
}
@@ -1242,31 +1609,32 @@ walk_mergeinfo_hash_for_diff(svn_mergein
}
svn_error_t *
-svn_mergeinfo_diff(svn_mergeinfo_t *deleted, svn_mergeinfo_t *added,
- svn_mergeinfo_t from, svn_mergeinfo_t to,
- svn_boolean_t consider_inheritance,
- apr_pool_t *pool)
+svn_mergeinfo_diff2(svn_mergeinfo_t *deleted, svn_mergeinfo_t *added,
+ svn_mergeinfo_t from, svn_mergeinfo_t to,
+ svn_boolean_t consider_inheritance,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
if (from && to == NULL)
{
- *deleted = svn_mergeinfo_dup(from, pool);
- *added = apr_hash_make(pool);
+ *deleted = svn_mergeinfo_dup(from, result_pool);
+ *added = apr_hash_make(result_pool);
}
else if (from == NULL && to)
{
- *deleted = apr_hash_make(pool);
- *added = svn_mergeinfo_dup(to, pool);
+ *deleted = apr_hash_make(result_pool);
+ *added = svn_mergeinfo_dup(to, result_pool);
}
else
{
- *deleted = apr_hash_make(pool);
- *added = apr_hash_make(pool);
+ *deleted = apr_hash_make(result_pool);
+ *added = apr_hash_make(result_pool);
if (from && to)
{
SVN_ERR(walk_mergeinfo_hash_for_diff(from, to, *deleted, *added,
- consider_inheritance, pool,
- pool));
+ consider_inheritance,
+ result_pool, scratch_pool));
}
}
@@ -1283,8 +1651,8 @@ svn_mergeinfo__equals(svn_boolean_t *is_
if (apr_hash_count(info1) == apr_hash_count(info2))
{
svn_mergeinfo_t deleted, added;
- SVN_ERR(svn_mergeinfo_diff(&deleted, &added, info1, info2,
- consider_inheritance, pool));
+ SVN_ERR(svn_mergeinfo_diff2(&deleted, &added, info1, info2,
+ consider_inheritance, pool, pool));
*is_equal = apr_hash_count(deleted) == 0 && apr_hash_count(added) == 0;
}
else
@@ -1295,8 +1663,10 @@ svn_mergeinfo__equals(svn_boolean_t *is_
}
svn_error_t *
-svn_mergeinfo_merge(svn_mergeinfo_t mergeinfo, svn_mergeinfo_t changes,
- apr_pool_t *pool)
+svn_mergeinfo_merge2(svn_mergeinfo_t mergeinfo,
+ svn_mergeinfo_t changes,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
apr_array_header_t *sorted1, *sorted2;
int i, j;
@@ -1305,12 +1675,14 @@ svn_mergeinfo_merge(svn_mergeinfo_t merg
if (!apr_hash_count(changes))
return SVN_NO_ERROR;
- sorted1 = svn_sort__hash(mergeinfo, svn_sort_compare_items_as_paths, pool);
- sorted2 = svn_sort__hash(changes, svn_sort_compare_items_as_paths, pool);
+ sorted1 = svn_sort__hash(mergeinfo, svn_sort_compare_items_as_paths,
+ scratch_pool);
+ sorted2 = svn_sort__hash(changes, svn_sort_compare_items_as_paths,
+ scratch_pool);
i = 0;
j = 0;
- iterpool = svn_pool_create(pool);
+ iterpool = svn_pool_create(scratch_pool);
while (i < sorted1->nelts && j < sorted2->nelts)
{
svn_sort__item_t elt1, elt2;
@@ -1329,7 +1701,7 @@ svn_mergeinfo_merge(svn_mergeinfo_t merg
rl1 = elt1.value;
rl2 = elt2.value;
- SVN_ERR(svn_rangelist_merge2(rl1, rl2, pool, iterpool));
+ SVN_ERR(svn_rangelist_merge2(rl1, rl2, result_pool, iterpool));
apr_hash_set(mergeinfo, elt1.key, elt1.klen, rl1);
i++;
j++;
@@ -1385,8 +1757,8 @@ svn_mergeinfo_catalog_merge(svn_mergeinf
svn_mergeinfo_t mergeinfo = cat_elt.value;
svn_mergeinfo_t changes_mergeinfo = change_elt.value;
- SVN_ERR(svn_mergeinfo_merge(mergeinfo, changes_mergeinfo,
- result_pool));
+ SVN_ERR(svn_mergeinfo_merge2(mergeinfo, changes_mergeinfo,
+ result_pool, scratch_pool));
apr_hash_set(mergeinfo_cat, cat_elt.key, cat_elt.klen, mergeinfo);
i++;
j++;
@@ -1420,16 +1792,6 @@ svn_mergeinfo_catalog_merge(svn_mergeinf
}
svn_error_t *
-svn_mergeinfo_intersect(svn_mergeinfo_t *mergeinfo,
- svn_mergeinfo_t mergeinfo1,
- svn_mergeinfo_t mergeinfo2,
- apr_pool_t *pool)
-{
- return svn_mergeinfo_intersect2(mergeinfo, mergeinfo1, mergeinfo2,
- TRUE, pool, pool);
-}
-
-svn_error_t *
svn_mergeinfo_intersect2(svn_mergeinfo_t *mergeinfo,
svn_mergeinfo_t mergeinfo1,
svn_mergeinfo_t mergeinfo2,
@@ -1438,26 +1800,29 @@ svn_mergeinfo_intersect2(svn_mergeinfo_t
apr_pool_t *scratch_pool)
{
apr_hash_index_t *hi;
+ apr_pool_t *iterpool;
*mergeinfo = apr_hash_make(result_pool);
+ iterpool = svn_pool_create(scratch_pool);
/* ### TODO(reint): Do we care about the case when a path in one
### mergeinfo hash has inheritable mergeinfo, and in the other
### has non-inhertiable mergeinfo? It seems like that path
### itself should really be an intersection, while child paths
### should not be... */
- for (hi = apr_hash_first(apr_hash_pool_get(mergeinfo1), mergeinfo1);
+ for (hi = apr_hash_first(scratch_pool, mergeinfo1);
hi; hi = apr_hash_next(hi))
{
const char *path = svn__apr_hash_index_key(hi);
apr_array_header_t *rangelist1 = svn__apr_hash_index_val(hi);
apr_array_header_t *rangelist2;
+ svn_pool_clear(iterpool);
rangelist2 = apr_hash_get(mergeinfo2, path, APR_HASH_KEY_STRING);
if (rangelist2)
{
SVN_ERR(svn_rangelist_intersect(&rangelist2, rangelist1, rangelist2,
- consider_inheritance, scratch_pool));
+ consider_inheritance, iterpool));
if (rangelist2->nelts > 0)
apr_hash_set(*mergeinfo,
apr_pstrdup(result_pool, path),
@@ -1465,18 +1830,11 @@ svn_mergeinfo_intersect2(svn_mergeinfo_t
svn_rangelist_dup(rangelist2, result_pool));
}
}
+ svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
svn_error_t *
-svn_mergeinfo_remove(svn_mergeinfo_t *mergeinfo, svn_mergeinfo_t eraser,
- svn_mergeinfo_t whiteboard, apr_pool_t *pool)
-{
- return svn_mergeinfo_remove2(mergeinfo, eraser, whiteboard, TRUE, pool,
- pool);
-}
-
-svn_error_t *
svn_mergeinfo_remove2(svn_mergeinfo_t *mergeinfo,
svn_mergeinfo_t eraser,
svn_mergeinfo_t whiteboard,
@@ -1495,7 +1853,7 @@ svn_rangelist_to_string(svn_string_t **o
const apr_array_header_t *rangelist,
apr_pool_t *pool)
{
- svn_stringbuf_t *buf = svn_stringbuf_create("", pool);
+ svn_stringbuf_t *buf = svn_stringbuf_create_empty(pool);
if (rangelist->nelts > 0)
{
@@ -1532,7 +1890,7 @@ mergeinfo_to_stringbuf(svn_stringbuf_t *
const char *prefix,
apr_pool_t *pool)
{
- *output = svn_stringbuf_create("", pool);
+ *output = svn_stringbuf_create_empty(pool);
if (apr_hash_count(input) > 0)
{
@@ -1565,16 +1923,10 @@ svn_error_t *
svn_mergeinfo_to_string(svn_string_t **output, svn_mergeinfo_t input,
apr_pool_t *pool)
{
- if (apr_hash_count(input) > 0)
- {
- svn_stringbuf_t *mergeinfo_buf;
- SVN_ERR(mergeinfo_to_stringbuf(&mergeinfo_buf, input, NULL, pool));
- *output = svn_stringbuf__morph_into_string(mergeinfo_buf);
- }
- else
- {
- *output = svn_string_create("", pool);
- }
+ svn_stringbuf_t *mergeinfo_buf;
+
+ SVN_ERR(mergeinfo_to_stringbuf(&mergeinfo_buf, input, NULL, pool));
+ *output = svn_stringbuf__morph_into_string(mergeinfo_buf);
return SVN_NO_ERROR;
}
@@ -1773,7 +2125,7 @@ svn_mergeinfo__remove_prefix_from_catalo
apr_ssize_t padding = 0;
SVN_ERR_ASSERT(klen >= prefix_len);
- SVN_ERR_ASSERT(svn_fspath__is_ancestor(prefix_path, original_path));
+ SVN_ERR_ASSERT(svn_fspath__skip_ancestor(prefix_path, original_path));
/* If the ORIGINAL_PATH doesn't match the PREFIX_PATH exactly
and we're not simply removing a single leading slash (such as
@@ -1820,6 +2172,36 @@ svn_mergeinfo__add_prefix_to_catalog(svn
}
svn_error_t *
+svn_mergeinfo__relpaths_to_urls(apr_hash_t **out_mergeinfo,
+ svn_mergeinfo_t mergeinfo,
+ const char *repos_root_url,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ *out_mergeinfo = NULL;
+ if (mergeinfo)
+ {
+ apr_hash_index_t *hi;
+ apr_hash_t *full_path_mergeinfo = apr_hash_make(result_pool);
+
+ for (hi = apr_hash_first(scratch_pool, mergeinfo);
+ hi; hi = apr_hash_next(hi))
+ {
+ const char *key = svn__apr_hash_index_key(hi);
+ void *val = svn__apr_hash_index_val(hi);
+
+ apr_hash_set(full_path_mergeinfo,
+ svn_path_url_add_component2(repos_root_url, key + 1,
+ result_pool),
+ APR_HASH_KEY_STRING, val);
+ }
+ *out_mergeinfo = full_path_mergeinfo;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_mergeinfo__add_suffix_to_mergeinfo(svn_mergeinfo_t *out_mergeinfo,
svn_mergeinfo_t mergeinfo,
const char *suffix_relpath,
@@ -1836,13 +2218,13 @@ svn_mergeinfo__add_suffix_to_mergeinfo(s
hi;
hi = apr_hash_next(hi))
{
- const char *path = svn__apr_hash_index_key(hi);
+ const char *fspath = svn__apr_hash_index_key(hi);
apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
apr_hash_set(*out_mergeinfo,
- svn_dirent_join(path, suffix_relpath, result_pool),
+ svn_fspath__join(fspath, suffix_relpath, result_pool),
APR_HASH_KEY_STRING,
- svn_rangelist_dup(rangelist, result_pool));
+ rangelist);
}
return SVN_NO_ERROR;
@@ -1901,7 +2283,7 @@ svn_mergeinfo__catalog_to_formatted_stri
apr_array_header_t *sorted_catalog =
svn_sort__hash(catalog, svn_sort_compare_items_as_paths, pool);
- output_buf = svn_stringbuf_create("", pool);
+ output_buf = svn_stringbuf_create_empty(pool);
for (i = 0; i < sorted_catalog->nelts; i++)
{
svn_sort__item_t elt =
@@ -1974,7 +2356,7 @@ svn_mergeinfo__to_formatted_string(svn_s
#endif
*output = output_buf ? svn_stringbuf__morph_into_string(output_buf)
- : svn_string_create("", pool);
+ : svn_string_create_empty(pool);
return SVN_NO_ERROR;
}
@@ -2176,25 +2558,6 @@ svn_mergeinfo__is_noninheritable(svn_mer
return FALSE;
}
-svn_error_t *
-svn_mergeinfo__string_has_noninheritable(svn_boolean_t *is_noninheritable,
- const char *mergeinfo_str,
- apr_pool_t *scratch_pool)
-{
- *is_noninheritable = FALSE;
-
- if (mergeinfo_str)
- {
- svn_mergeinfo_t mergeinfo;
-
- SVN_ERR(svn_mergeinfo_parse(&mergeinfo, mergeinfo_str, scratch_pool));
- *is_noninheritable = svn_mergeinfo__is_noninheritable(mergeinfo,
- scratch_pool);
- }
-
- return SVN_NO_ERROR;
-}
-
apr_array_header_t *
svn_rangelist__initialize(svn_revnum_t start,
svn_revnum_t end,
@@ -2261,3 +2624,54 @@ svn_mergeinfo__mergeinfo_from_segments(s
*mergeinfo_p = mergeinfo;
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_rangelist__merge_many(apr_array_header_t *merged_rangelist,
+ svn_mergeinfo_t merge_history,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ if (apr_hash_count(merge_history))
+ {
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ apr_hash_index_t *hi;
+
+ for (hi = apr_hash_first(scratch_pool, merge_history);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ apr_array_header_t *subtree_rangelist = svn__apr_hash_index_val(hi);
+
+ svn_pool_clear(iterpool);
+ SVN_ERR(svn_rangelist_merge2(merged_rangelist, subtree_rangelist,
+ result_pool, iterpool));
+ }
+ svn_pool_destroy(iterpool);
+ }
+ return SVN_NO_ERROR;
+}
+
+
+const char *
+svn_inheritance_to_word(svn_mergeinfo_inheritance_t inherit)
+{
+ switch (inherit)
+ {
+ case svn_mergeinfo_inherited:
+ return "inherited";
+ case svn_mergeinfo_nearest_ancestor:
+ return "nearest-ancestor";
+ default:
+ return "explicit";
+ }
+}
+
+svn_mergeinfo_inheritance_t
+svn_inheritance_from_word(const char *word)
+{
+ if (strcmp(word, "inherited") == 0)
+ return svn_mergeinfo_inherited;
+ if (strcmp(word, "nearest-ancestor") == 0)
+ return svn_mergeinfo_nearest_ancestor;
+ return svn_mergeinfo_explicit;
+}
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/opt.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/opt.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/opt.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/opt.c Mon Nov 21 07:07:56 2011
@@ -644,6 +644,32 @@ svn_opt__revision_to_string(const svn_op
}
}
+svn_opt_revision_range_t *
+svn_opt__revision_range_create(const svn_opt_revision_t *start_revision,
+ const svn_opt_revision_t *end_revision,
+ apr_pool_t *result_pool)
+{
+ svn_opt_revision_range_t *range = apr_palloc(result_pool, sizeof(*range));
+
+ range->start = *start_revision;
+ range->end = *end_revision;
+ return range;
+}
+
+svn_opt_revision_range_t *
+svn_opt__revision_range_from_revnums(svn_revnum_t start_revnum,
+ svn_revnum_t end_revnum,
+ apr_pool_t *result_pool)
+{
+ svn_opt_revision_range_t *range = apr_palloc(result_pool, sizeof(*range));
+
+ range->start.kind = svn_opt_revision_number;
+ range->start.value.number = start_revnum;
+ range->end.kind = svn_opt_revision_number;
+ range->end.value.number = end_revnum;
+ return range;
+}
+
/*** Parsing arguments. ***/
@@ -944,7 +970,7 @@ svn_opt_parse_revprop(apr_hash_t **revpr
else
{
SVN_ERR(svn_utf_cstring_to_utf8(&propname, revprop_spec, pool));
- propval = svn_string_create("", pool);
+ propval = svn_string_create_empty(pool);
}
if (!svn_prop_name_is_valid(propname))
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/prompt.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/prompt.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/prompt.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/prompt.c Mon Nov 21 07:07:56 2011
@@ -95,7 +95,7 @@ prompt(const char **result,
apr_file_t *fp;
char c;
- svn_stringbuf_t *strbuf = svn_stringbuf_create("", pool);
+ svn_stringbuf_t *strbuf = svn_stringbuf_create_empty(pool);
status = apr_file_open_stdin(&fp, pool);
if (status)
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/properties.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/properties.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/properties.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/properties.c Mon Nov 21 07:07:56 2011
@@ -221,6 +221,85 @@ svn_prop_diffs(apr_array_header_t **prop
return SVN_NO_ERROR;
}
+/**
+ * Reallocate the members of PROP using POOL.
+ */
+static void
+svn_prop__members_dup(svn_prop_t *prop, apr_pool_t *pool)
+{
+ if (prop->name)
+ prop->name = apr_pstrdup(pool, prop->name);
+ if (prop->value)
+ prop->value = svn_string_dup(prop->value, pool);
+}
+
+svn_prop_t *
+svn_prop_dup(const svn_prop_t *prop, apr_pool_t *pool)
+{
+ svn_prop_t *new_prop = apr_palloc(pool, sizeof(*new_prop));
+
+ *new_prop = *prop;
+
+ svn_prop__members_dup(new_prop, pool);
+
+ return new_prop;
+}
+
+apr_array_header_t *
+svn_prop_array_dup(const apr_array_header_t *array, apr_pool_t *pool)
+{
+ int i;
+ apr_array_header_t *new_array = apr_array_copy(pool, array);
+ for (i = 0; i < new_array->nelts; ++i)
+ {
+ svn_prop_t *elt = &APR_ARRAY_IDX(new_array, i, svn_prop_t);
+ svn_prop__members_dup(elt, pool);
+ }
+ return new_array;
+}
+
+apr_array_header_t *
+svn_prop_hash_to_array(apr_hash_t *hash, apr_pool_t *pool)
+{
+ apr_hash_index_t *hi;
+ apr_array_header_t *array = apr_array_make(pool, apr_hash_count(hash),
+ sizeof(svn_prop_t));
+
+ for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
+ {
+ const void *key;
+ void *val;
+ svn_prop_t prop;
+
+ apr_hash_this(hi, &key, NULL, &val);
+ prop.name = key;
+ prop.value = val;
+ APR_ARRAY_PUSH(array, svn_prop_t) = prop;
+ }
+
+ return array;
+}
+
+apr_hash_t *
+svn_prop_hash_dup(apr_hash_t *hash,
+ apr_pool_t *pool)
+{
+ apr_hash_index_t *hi;
+ apr_hash_t *new_hash = apr_hash_make(pool);
+
+ for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
+ {
+ const void *key;
+ apr_ssize_t klen;
+ void *prop;
+
+ apr_hash_this(hi, &key, &klen, &prop);
+ apr_hash_set(new_hash, apr_pstrdup(pool, key), klen,
+ svn_string_dup(prop, pool));
+ }
+ return new_hash;
+}
+
apr_hash_t *
svn_prop_array_to_hash(const apr_array_header_t *properties,
apr_pool_t *pool)
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/quoprint.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/quoprint.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/quoprint.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/quoprint.c Mon Nov 21 07:07:56 2011
@@ -120,7 +120,7 @@ encode_data(void *baton, const char *dat
{
struct encode_baton *eb = baton;
apr_pool_t *subpool = svn_pool_create(eb->pool);
- svn_stringbuf_t *encoded = svn_stringbuf_create("", subpool);
+ svn_stringbuf_t *encoded = svn_stringbuf_create_empty(subpool);
apr_size_t enclen;
svn_error_t *err = SVN_NO_ERROR;
@@ -177,7 +177,7 @@ svn_quoprint_encode(svn_stream_t *output
svn_stringbuf_t *
svn_quoprint_encode_string(const svn_stringbuf_t *str, apr_pool_t *pool)
{
- svn_stringbuf_t *encoded = svn_stringbuf_create("", pool);
+ svn_stringbuf_t *encoded = svn_stringbuf_create_empty(pool);
int linelen = 0;
encode_bytes(encoded, str->data, str->len, &linelen);
@@ -254,7 +254,7 @@ decode_data(void *baton, const char *dat
/* Decode this block of data. */
subpool = svn_pool_create(db->pool);
- decoded = svn_stringbuf_create("", subpool);
+ decoded = svn_stringbuf_create_empty(subpool);
decode_bytes(decoded, data, *len, db->buf, &db->buflen);
/* Write the output, clean up, go home. */
@@ -300,7 +300,7 @@ svn_quoprint_decode(svn_stream_t *output
svn_stringbuf_t *
svn_quoprint_decode_string(const svn_stringbuf_t *str, apr_pool_t *pool)
{
- svn_stringbuf_t *decoded = svn_stringbuf_create("", pool);
+ svn_stringbuf_t *decoded = svn_stringbuf_create_empty(pool);
char ingroup[4];
int ingrouplen = 0;
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/sorts.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/sorts.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/sorts.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/sorts.c Mon Nov 21 07:07:56 2011
@@ -140,21 +140,38 @@ svn_sort__hash(apr_hash_t *ht,
{
apr_hash_index_t *hi;
apr_array_header_t *ary;
+ svn_boolean_t sorted;
+ svn_sort__item_t *prev_item;
/* allocate an array with enough elements to hold all the keys. */
ary = apr_array_make(pool, apr_hash_count(ht), sizeof(svn_sort__item_t));
/* loop over hash table and push all keys into the array */
+ sorted = TRUE;
+ prev_item = NULL;
for (hi = apr_hash_first(pool, ht); hi; hi = apr_hash_next(hi))
{
svn_sort__item_t *item = apr_array_push(ary);
apr_hash_this(hi, &item->key, &item->klen, &item->value);
+
+ if (prev_item == NULL)
+ {
+ prev_item = item;
+ continue;
+ }
+
+ if (sorted)
+ {
+ sorted = (comparison_func(prev_item, item) < 0);
+ prev_item = item;
+ }
}
- /* now quicksort the array. */
- qsort(ary->elts, ary->nelts, ary->elt_size,
- (int (*)(const void *, const void *))comparison_func);
+ /* quicksort the array if it isn't already sorted. */
+ if (!sorted)
+ qsort(ary->elts, ary->nelts, ary->elt_size,
+ (int (*)(const void *, const void *))comparison_func);
return ary;
}
@@ -228,3 +245,28 @@ svn_sort__array_insert(const void *new_e
/* Copy in the new element */
memcpy(new_position, new_element, array->elt_size);
}
+
+void
+svn_sort__array_delete(apr_array_header_t *arr,
+ int delete_index,
+ int elements_to_delete)
+{
+ /* Do we have a valid index and are there enough elements? */
+ if (delete_index >= 0
+ && delete_index < arr->nelts
+ && elements_to_delete > 0
+ && (elements_to_delete + delete_index) <= arr->nelts)
+ {
+ /* If we are not deleting a block of elements that extends to the end
+ of the array, then we need to move the remaining elements to keep
+ the array contiguous. */
+ if ((elements_to_delete + delete_index) < arr->nelts)
+ memmove(
+ arr->elts + arr->elt_size * delete_index,
+ arr->elts + (arr->elt_size * (delete_index + elements_to_delete)),
+ arr->elt_size * (arr->nelts - elements_to_delete - delete_index));
+
+ /* Delete the last ELEMENTS_TO_DELETE elements. */
+ arr->nelts -= elements_to_delete;
+ }
+}
Modified: subversion/branches/svn-bisect/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/libsvn_subr/sqlite.c?rev=1204374&r1=1204373&r2=1204374&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/svn-bisect/subversion/libsvn_subr/sqlite.c Mon Nov 21 07:07:56 2011
@@ -133,6 +133,10 @@ struct svn_sqlite__value_t
} while (0)
+/* Time (in milliseconds) to wait for sqlite locks before giving up. */
+#define BUSY_TIMEOUT 10000
+
+
/* Convenience wrapper around exec_sql2(). */
#define exec_sql(db, sql) exec_sql2((db), (sql), SQLITE_OK)
@@ -579,108 +583,6 @@ svn_sqlite__reset(svn_sqlite__stmt_t *st
svn_error_t *
-svn_sqlite__set_schema_version(svn_sqlite__db_t *db,
- int version,
- apr_pool_t *scratch_pool)
-{
- const char *pragma_cmd = apr_psprintf(scratch_pool,
- "PRAGMA user_version = %d;",
- version);
-
- return svn_error_trace(exec_sql(db, pragma_cmd));
-}
-
-
-/* Time (in milliseconds) to wait for sqlite locks before giving up. */
-#define BUSY_TIMEOUT 10000
-
-
-#if 0
-/*
- * EXAMPLE
- *
- * The following provide an example for a series of SQL statements to
- * create/upgrade a SQLite schema across multiple "formats". This array
- * and integer would be passed into svn_sqlite__open().
- */
-static const char *schema_create_sql[] = {
- NULL, /* An empty database is format 0 */
-
- /* USER_VERSION 1 */
- "PRAGMA auto_vacuum = 1;"
- APR_EOL_STR
- "CREATE TABLE mergeinfo (revision INTEGER NOT NULL, mergedfrom TEXT NOT "
- "NULL, mergedto TEXT NOT NULL, mergedrevstart INTEGER NOT NULL, "
- "mergedrevend INTEGER NOT NULL, inheritable INTEGER NOT NULL);"
- APR_EOL_STR
- "CREATE INDEX mi_mergedfrom_idx ON mergeinfo (mergedfrom);"
- APR_EOL_STR
- "CREATE INDEX mi_mergedto_idx ON mergeinfo (mergedto);"
- APR_EOL_STR
- "CREATE INDEX mi_revision_idx ON mergeinfo (revision);"
- APR_EOL_STR
- "CREATE TABLE mergeinfo_changed (revision INTEGER NOT NULL, path TEXT "
- "NOT NULL);"
- APR_EOL_STR
- "CREATE UNIQUE INDEX mi_c_revpath_idx ON mergeinfo_changed (revision, path);"
- APR_EOL_STR
- "CREATE INDEX mi_c_path_idx ON mergeinfo_changed (path);"
- APR_EOL_STR
- "CREATE INDEX mi_c_revision_idx ON mergeinfo_changed (revision);"
- APR_EOL_STR,
-
- /* USER_VERSION 2 */
- "CREATE TABLE node_origins (node_id TEXT NOT NULL, node_rev_id TEXT NOT "
- "NULL);"
- APR_EOL_STR
- "CREATE UNIQUE INDEX no_ni_idx ON node_origins (node_id);"
- APR_EOL_STR
-};
-
-static const int latest_schema_format =
- sizeof(schema_create_sql)/sizeof(schema_create_sql[0]) - 1;
-
-#endif
-
-struct upgrade_baton
-{
- int current_schema;
- int latest_schema;
- const char * const *upgrade_sql;
-};
-
-
-/* This implements svn_sqlite__transaction_callback_t */
-static svn_error_t *
-upgrade_format(void *baton,
- svn_sqlite__db_t *db,
- apr_pool_t *scratch_pool)
-{
- struct upgrade_baton *ub = baton;
- int current_schema = ub->current_schema;
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
- while (current_schema < ub->latest_schema)
- {
- svn_pool_clear(iterpool);
-
- /* Go to the next schema */
- current_schema++;
-
- /* Run the upgrade SQL */
- if (ub->upgrade_sql[current_schema])
- SVN_ERR(exec_sql(db, ub->upgrade_sql[current_schema]));
-
- /* Update the user version pragma */
- SVN_ERR(svn_sqlite__set_schema_version(db, current_schema, iterpool));
- }
-
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
svn_sqlite__read_schema_version(int *version,
svn_sqlite__db_t *db,
apr_pool_t *scratch_pool)
@@ -696,41 +598,6 @@ svn_sqlite__read_schema_version(int *ver
}
-/* Check the schema format of the database, upgrading it if necessary.
- Return SVN_ERR_SQLITE_UNSUPPORTED_SCHEMA if the schema format is too new,
- or SVN_ERR_SQLITE_ERROR if an sqlite error occurs during validation.
- Return SVN_NO_ERROR if everything is okay. */
-static svn_error_t *
-check_format(svn_sqlite__db_t *db,
- int latest_schema,
- const char * const *upgrade_sql,
- apr_pool_t *scratch_pool)
-{
- int current_schema;
-
- /* Validate that the schema exists as expected. */
- SVN_ERR(svn_sqlite__read_schema_version(¤t_schema, db, scratch_pool));
-
- if (current_schema == latest_schema)
- return SVN_NO_ERROR;
-
- if (current_schema < latest_schema)
- {
- struct upgrade_baton ub;
-
- ub.current_schema = current_schema;
- ub.latest_schema = latest_schema;
- ub.upgrade_sql = upgrade_sql;
-
- return svn_error_trace(svn_sqlite__with_transaction(
- db, upgrade_format, &ub, scratch_pool));
- }
-
- return svn_error_createf(SVN_ERR_SQLITE_UNSUPPORTED_SCHEMA, NULL,
- _("Schema format %d not recognized"),
- current_schema);
-}
-
static volatile svn_atomic_t sqlite_init_state = 0;
/* If possible, verify that SQLite was compiled in a thread-safe
@@ -739,12 +606,12 @@ static volatile svn_atomic_t sqlite_init
static svn_error_t *
init_sqlite(void *baton, apr_pool_t *pool)
{
- if (sqlite3_libversion_number() < SQLITE_VERSION_NUMBER)
+ if (sqlite3_libversion_number() < SVN_SQLITE_MIN_VERSION_NUMBER)
{
return svn_error_createf(
SVN_ERR_SQLITE_ERROR, NULL,
_("SQLite compiled for %s, but running with %s"),
- SQLITE_VERSION, sqlite3_libversion());
+ SVN_SQLITE_MIN_VERSION, sqlite3_libversion());
}
#if APR_HAS_THREADS
@@ -770,12 +637,6 @@ init_sqlite(void *baton, apr_pool_t *poo
#endif /* APR_HAS_THRADS */
- /* SQLite 3.5 allows sharing cache instances, even in a multithreaded
- environment. This allows sharing cached data when we open a database
- more than once (Very common in the current pre-single-database state) */
- SQLITE_ERR_MSG(sqlite3_enable_shared_cache(TRUE),
- _("Could not initialize SQLite shared cache"));
-
return SVN_NO_ERROR;
}
@@ -836,22 +697,6 @@ internal_open(sqlite3 **db3, const char
return SVN_NO_ERROR;
}
-svn_error_t *
-svn_sqlite__get_schema_version(int *version,
- const char *path,
- apr_pool_t *scratch_pool)
-{
- svn_sqlite__db_t db;
-
- SVN_ERR(svn_atomic__init_once(&sqlite_init_state,
- init_sqlite, NULL, scratch_pool));
- SVN_ERR(internal_open(&db.db3, path, svn_sqlite__mode_readonly,
- scratch_pool));
- SVN_ERR(svn_sqlite__read_schema_version(version, &db, scratch_pool));
- SQLITE_ERR(sqlite3_close(db.db3), &db);
-
- return SVN_NO_ERROR;
-}
/* APR cleanup function used to close the database when its pool is destroyed.
DATA should be the svn_sqlite__db_t handle for the database. */
@@ -897,7 +742,7 @@ close_apr(void *data)
svn_error_t *
svn_sqlite__open(svn_sqlite__db_t **db, const char *path,
svn_sqlite__mode_t mode, const char * const statements[],
- int latest_schema, const char * const *upgrade_sql,
+ int unused1, const char * const *unused2,
apr_pool_t *result_pool, apr_pool_t *scratch_pool)
{
SVN_ERR(svn_atomic__init_once(&sqlite_init_state,
@@ -966,10 +811,6 @@ svn_sqlite__open(svn_sqlite__db_t **db,
setting SQLITE_TEMP_STORE to 0 (always to disk) */
svn_error_clear(exec_sql(*db, "PRAGMA temp_store = MEMORY;"));
- /* Validate the schema, upgrading if necessary. */
- if (upgrade_sql != NULL)
- SVN_ERR(check_format(*db, latest_schema, upgrade_sql, scratch_pool));
-
/* Store the provided statements. */
if (statements)
{