You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2012/11/30 19:13:02 UTC
svn commit: r1415773 [3/6] - in /subversion/branches/tree-read-api: ./
build/ac-macros/ build/generator/ notes/ subversion/bindings/cxxhl/
subversion/include/ subversion/include/private/ subversion/libsvn_client/
subversion/libsvn_delta/ subversion/lib...
Modified: subversion/branches/tree-read-api/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_ra_serf/update.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_ra_serf/update.c Fri Nov 30 18:12:52 2012
@@ -357,6 +357,10 @@ struct report_context_t {
/* completed PROPFIND requests (contains svn_ra_serf__handler_t) */
svn_ra_serf__list_t *done_propfinds;
+ svn_ra_serf__list_t *done_dir_propfinds;
+
+ /* list of outstanding prop changes (contains report_dir_t) */
+ svn_ra_serf__list_t *active_dir_propfinds;
/* list of files that only have prop changes (contains report_info_t) */
svn_ra_serf__list_t *file_propchanges_only;
@@ -1347,6 +1351,27 @@ maybe_close_dir_chain(report_dir_t *dir)
{
report_dir_t *parent = cur_dir->parent_dir;
report_context_t *report_context = cur_dir->report_context;
+ svn_boolean_t propfind_in_done_list = FALSE;
+ svn_ra_serf__list_t *done_list;
+
+ /* Make sure there are no references to this dir in the
+ active_dir_propfinds list. If there are, don't close the
+ directory -- which would delete the pool from which the
+ relevant active_dir_propfinds list item is allocated -- and
+ of course don't crawl upward to check the parents for
+ a closure opportunity, either. */
+ done_list = report_context->active_dir_propfinds;
+ while (done_list)
+ {
+ if (done_list->data == cur_dir)
+ {
+ propfind_in_done_list = TRUE;
+ break;
+ }
+ done_list = done_list->next;
+ }
+ if (propfind_in_done_list)
+ break;
SVN_ERR(close_dir(cur_dir));
if (parent)
@@ -1377,6 +1402,10 @@ handle_propchange_only(report_info_t *in
info->dir->ref_count--;
+ /* See if the parent directory of this file (and perhaps even
+ parents of that) can be closed now. */
+ SVN_ERR(maybe_close_dir_chain(info->dir));
+
return SVN_NO_ERROR;
}
@@ -1401,6 +1430,10 @@ handle_local_content(report_info_t *info
info->dir->ref_count--;
+ /* See if the parent directory of this fetched item (and
+ perhaps even parents of that) can be closed now. */
+ SVN_ERR(maybe_close_dir_chain(info->dir));
+
return SVN_NO_ERROR;
}
@@ -1565,12 +1598,7 @@ fetch_file(report_context_t *ctx, report
}
else
{
- /* No propfind or GET request. Just handle the prop changes now.
-
- Note: we'll use INFO->POOL for the scratch_pool here since it will
- be destroyed at the end of handle_propchange_only(). That pool
- would be quite fine, but it is unclear how long INFO->POOL will
- stick around since its lifetime and usage are unclear. */
+ /* No propfind or GET request. Just handle the prop changes now. */
SVN_ERR(handle_propchange_only(info, info->pool));
}
@@ -2126,13 +2154,15 @@ end_report(svn_ra_serf__xml_parser_t *pa
*/
if (info->dir->fetch_props)
{
+ svn_ra_serf__list_t *list_item;
+
SVN_ERR(svn_ra_serf__deliver_props(&info->dir->propfind_handler,
info->dir->props, ctx->sess,
get_best_connection(ctx),
info->dir->url,
ctx->target_rev, "0",
all_props,
- &ctx->done_propfinds,
+ &ctx->done_dir_propfinds,
info->dir->pool));
SVN_ERR_ASSERT(info->dir->propfind_handler);
@@ -2141,6 +2171,11 @@ end_report(svn_ra_serf__xml_parser_t *pa
ctx->num_active_propfinds++;
+ list_item = apr_pcalloc(info->dir->pool, sizeof(*list_item));
+ list_item->data = info->dir;
+ list_item->next = ctx->active_dir_propfinds;
+ ctx->active_dir_propfinds = list_item;
+
if (ctx->num_active_fetches + ctx->num_active_propfinds
> REQUEST_COUNT_TO_PAUSE)
ctx->parser_ctx->paused = TRUE;
@@ -2150,6 +2185,12 @@ end_report(svn_ra_serf__xml_parser_t *pa
info->dir->propfind_handler = NULL;
}
+ /* See if this directory (and perhaps even parents of that) can
+ be closed now. This is likely to be the case only if we
+ didn't need to contact the server for supplemental
+ information required to handle any of this directory's
+ children. */
+ SVN_ERR(maybe_close_dir_chain(info->dir));
svn_ra_serf__xml_pop_state(parser);
}
else if (state == OPEN_FILE && strcmp(name.name, "open-file") == 0)
@@ -2562,7 +2603,7 @@ finish_report(void *report_baton,
svn_stringbuf_t *buf = NULL;
apr_pool_t *iterpool = svn_pool_create(pool);
svn_error_t *err;
- apr_short_interval_time_t waittime_left = sess->timeout;
+ apr_interval_time_t waittime_left = sess->timeout;
svn_xml_make_close_tag(&buf, iterpool, "S:update-report");
SVN_ERR(svn_io_file_write_full(report->body_file, buf->data, buf->len,
@@ -2666,14 +2707,17 @@ finish_report(void *report_baton,
err = SVN_NO_ERROR;
status = 0;
- if (waittime_left > SVN_RA_SERF__CONTEXT_RUN_DURATION)
- {
- waittime_left -= SVN_RA_SERF__CONTEXT_RUN_DURATION;
- }
- else
+ if (sess->timeout)
{
- return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, NULL,
- _("Connection timed out"));
+ if (waittime_left > SVN_RA_SERF__CONTEXT_RUN_DURATION)
+ {
+ waittime_left -= SVN_RA_SERF__CONTEXT_RUN_DURATION;
+ }
+ else
+ {
+ return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, NULL,
+ _("Connection timed out"));
+ }
}
}
else
@@ -2692,10 +2736,12 @@ finish_report(void *report_baton,
SVN_ERR(open_connection_if_needed(sess, report->num_active_fetches +
report->num_active_propfinds));
- /* prune our propfind list if they are done. */
+ /* Prune completed file PROPFINDs. */
done_list = report->done_propfinds;
while (done_list)
{
+ svn_ra_serf__list_t *next_done = done_list->next;
+
svn_pool_clear(iterpool_inner);
report->num_active_propfinds--;
@@ -2730,39 +2776,46 @@ finish_report(void *report_baton,
{
report_info_t *info = cur->data;
- /* If we've got cached file content for this file,
- take care of the locally collected properties and
- file content at once. Otherwise, just deal with
- the collected properties. */
- if (info->cached_contents)
+ if (!prev)
{
- SVN_ERR(handle_local_content(info, iterpool_inner));
+ report->file_propchanges_only = cur->next;
}
else
{
- SVN_ERR(handle_propchange_only(info, iterpool_inner));
+ prev->next = cur->next;
}
- if (!prev)
+ /* If we've got cached file content for this file,
+ take care of the locally collected properties and
+ file content at once. Otherwise, just deal with
+ the collected properties.
+
+ NOTE: These functions below could delete
+ info->dir->pool (via maybe_close_dir_chain()),
+ from which is allocated the list item in
+ report->file_propchanges_only.
+ */
+ if (info->cached_contents)
{
- report->file_propchanges_only = cur->next;
+ SVN_ERR(handle_local_content(info, iterpool_inner));
}
else
{
- prev->next = cur->next;
+ SVN_ERR(handle_propchange_only(info, iterpool_inner));
}
}
}
- done_list = done_list->next;
+ done_list = next_done;
}
report->done_propfinds = NULL;
- /* Prune completely fetches from our list. */
+ /* Prune completed fetches from our list. */
done_list = report->done_fetches;
while (done_list)
{
report_fetch_t *done_fetch = done_list->data;
+ svn_ra_serf__list_t *next_done = done_list->next;
report_dir_t *cur_dir;
/* Decrease the refcount in the parent directory of the file
@@ -2773,14 +2826,77 @@ finish_report(void *report_baton,
/* Decrement our active fetch count. */
report->num_active_fetches--;
- done_list = done_list->next;
-
/* See if the parent directory of this fetched item (and
- perhaps even parents of that) can be closed now. */
+ perhaps even parents of that) can be closed now.
+
+ NOTE: This could delete cur_dir->pool, from which is
+ allocated the list item in report->done_fetches.
+ */
SVN_ERR(maybe_close_dir_chain(cur_dir));
+
+ done_list = next_done;
}
report->done_fetches = NULL;
+ /* Prune completed directory PROPFINDs. */
+ done_list = report->done_dir_propfinds;
+ while (done_list)
+ {
+ svn_ra_serf__list_t *next_done = done_list->next;
+
+ report->num_active_propfinds--;
+
+ if (report->active_dir_propfinds)
+ {
+ svn_ra_serf__list_t *cur, *prev;
+
+ prev = NULL;
+ cur = report->active_dir_propfinds;
+
+ while (cur)
+ {
+ report_dir_t *item = cur->data;
+
+ if (item->propfind_handler == done_list->data)
+ {
+ break;
+ }
+
+ prev = cur;
+ cur = cur->next;
+ }
+ SVN_ERR_ASSERT(cur); /* we expect to find a matching propfind! */
+
+ /* If we found a match, set the new props and remove this
+ * propchange from our list.
+ */
+ if (cur)
+ {
+ report_dir_t *cur_dir = cur->data;
+
+ if (!prev)
+ {
+ report->active_dir_propfinds = cur->next;
+ }
+ else
+ {
+ prev->next = cur->next;
+ }
+
+ /* See if this directory (and perhaps even parents of that)
+ can be closed now.
+
+ NOTE: This could delete cur_dir->pool, from which is
+ allocated the list item in report->active_dir_propfinds.
+ */
+ SVN_ERR(maybe_close_dir_chain(cur_dir));
+ }
+ }
+
+ done_list = next_done;
+ }
+ report->done_dir_propfinds = NULL;
+
/* If the parser is paused, and the number of active requests has
dropped far enough, then resume parsing. */
if (parser_ctx->paused
Modified: subversion/branches/tree-read-api/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_ra_serf/util.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_ra_serf/util.c Fri Nov 30 18:12:52 2012
@@ -657,6 +657,10 @@ setup_serf_req(serf_request_t *request,
SVN_ERR(svn_ra_serf__copy_into_spillbuf(&buf, body_bkt,
request_pool,
scratch_pool));
+ /* Destroy original bucket since it content is already copied
+ to spillbuf. */
+ serf_bucket_destroy(body_bkt);
+
body_bkt = svn_ra_serf__create_sb_bucket(buf, allocator,
request_pool,
scratch_pool);
@@ -718,7 +722,7 @@ svn_ra_serf__context_run_wait(svn_boolea
apr_pool_t *scratch_pool)
{
apr_pool_t *iterpool;
- apr_short_interval_time_t waittime_left = sess->timeout;
+ apr_interval_time_t waittime_left = sess->timeout;
assert(sess->pending_error == SVN_NO_ERROR);
@@ -751,14 +755,17 @@ svn_ra_serf__context_run_wait(svn_boolea
err = SVN_NO_ERROR;
status = 0;
- if (waittime_left > SVN_RA_SERF__CONTEXT_RUN_DURATION)
- {
- waittime_left -= SVN_RA_SERF__CONTEXT_RUN_DURATION;
- }
- else
+ if (sess->timeout)
{
- return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, NULL,
- _("Connection timed out"));
+ if (waittime_left > SVN_RA_SERF__CONTEXT_RUN_DURATION)
+ {
+ waittime_left -= SVN_RA_SERF__CONTEXT_RUN_DURATION;
+ }
+ else
+ {
+ return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, NULL,
+ _("Connection timed out"));
+ }
}
}
else
Modified: subversion/branches/tree-read-api/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_ra_svn/cyrus_auth.c Fri Nov 30 18:12:52 2012
@@ -871,12 +871,12 @@ svn_ra_svn__do_cyrus_auth(svn_ra_svn__se
/* The username callback. */
callbacks[0].id = SASL_CB_AUTHNAME;
- callbacks[0].proc = (void*)get_username_cb;
+ callbacks[0].proc = (int (*)(void))get_username_cb;
callbacks[0].context = &cred_baton;
/* The password callback. */
callbacks[1].id = SASL_CB_PASS;
- callbacks[1].proc = (void*)get_password_cb;
+ callbacks[1].proc = (int (*)(void))get_password_cb;
callbacks[1].context = &cred_baton;
/* Mark the end of the array. */
Modified: subversion/branches/tree-read-api/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_repos/reporter.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_repos/reporter.c Fri Nov 30 18:12:52 2012
@@ -717,11 +717,13 @@ delta_files(report_baton_t *b, void *fil
zero-copy code. */
if (b->zero_copy_limit > 0 && s_path == NULL)
{
- zero_copy_baton_t baton = { b->zero_copy_limit
- , dhandler
- , dbaton
- , FALSE};
+ zero_copy_baton_t baton;
svn_boolean_t called = FALSE;
+
+ baton.zero_copy_limit = b->zero_copy_limit;
+ baton.dhandler = dhandler;
+ baton.dbaton = dbaton;
+ baton.zero_copy_succeeded = FALSE;
SVN_ERR(svn_fs_try_process_file_contents(&called,
b->t_root, t_path,
send_zero_copy_delta,
Modified: subversion/branches/tree-read-api/subversion/libsvn_subr/named_atomic.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_subr/named_atomic.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_subr/named_atomic.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_subr/named_atomic.c Fri Nov 30 18:12:52 2012
@@ -308,7 +308,7 @@ delete_lock_file(void *arg)
const char *lock_name = NULL;
/* locks have already been cleaned up. Simply close the file */
- apr_file_close(mutex->lock_file);
+ apr_status_t status = apr_file_close(mutex->lock_file);
/* Remove the file from disk. This will fail if there ares still other
* users of this lock file, i.e. namespace. */
@@ -316,10 +316,12 @@ delete_lock_file(void *arg)
if (lock_name)
apr_file_remove(lock_name, mutex->pool);
- return 0;
+ return status;
}
-/* Validate the ATOMIC parameter, i.e it's address.
+/* Validate the ATOMIC parameter, i.e it's address. Correct code will
+ * never need this but if someone should accidentally to use a NULL or
+ * incomplete structure, let's catch that here instead of segfaulting.
*/
static svn_error_t *
validate(svn_named_atomic__t *atomic)
@@ -416,7 +418,9 @@ svn_atomic_namespace__create(svn_atomic_
APR_OS_DEFAULT,
result_pool));
- /* Make sure the last user of our lock file will actually remove it
+ /* Make sure the last user of our lock file will actually remove it.
+ * Please note that only the last file handle begin closed will actually
+ * remove the underlying file (see docstring for apr_file_remove).
*/
apr_pool_cleanup_register(result_pool, &new_ns->mutex,
delete_lock_file,
Modified: subversion/branches/tree-read-api/subversion/libsvn_subr/properties.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_subr/properties.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_subr/properties.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_subr/properties.c Fri Nov 30 18:12:52 2012
@@ -33,6 +33,90 @@
#include "svn_ctype.h"
+/* All Subversion-specific versioned node properties
+ * known to this client, that are applicable to both a file and a dir.
+ */
+#define SVN_PROP__NODE_COMMON_PROPS SVN_PROP_MERGEINFO, \
+ SVN_PROP_TEXT_TIME, \
+ SVN_PROP_OWNER, \
+ SVN_PROP_GROUP, \
+ SVN_PROP_UNIX_MODE,
+
+/* All Subversion-specific versioned node properties
+ * known to this client, that are applicable to a dir only.
+ */
+#define SVN_PROP__NODE_DIR_ONLY_PROPS SVN_PROP_IGNORE, \
+ SVN_PROP_INHERITABLE_IGNORES, \
+ SVN_PROP_INHERITABLE_AUTO_PROPS, \
+ SVN_PROP_EXTERNALS,
+
+/* All Subversion-specific versioned node properties
+ * known to this client, that are applicable to a file only.
+ */
+#define SVN_PROP__NODE_FILE_ONLY_PROPS SVN_PROP_MIME_TYPE, \
+ SVN_PROP_EOL_STYLE, \
+ SVN_PROP_KEYWORDS, \
+ SVN_PROP_EXECUTABLE, \
+ SVN_PROP_NEEDS_LOCK, \
+ SVN_PROP_SPECIAL,
+
+static const char *const known_rev_props[]
+ = { SVN_PROP_REVISION_ALL_PROPS
+ NULL };
+
+static const char *const known_node_props[]
+ = { SVN_PROP__NODE_COMMON_PROPS
+ SVN_PROP__NODE_DIR_ONLY_PROPS
+ SVN_PROP__NODE_FILE_ONLY_PROPS
+ NULL };
+
+static const char *const known_dir_props[]
+ = { SVN_PROP__NODE_COMMON_PROPS
+ SVN_PROP__NODE_DIR_ONLY_PROPS
+ NULL };
+
+static const char *const known_file_props[]
+ = { SVN_PROP__NODE_COMMON_PROPS
+ SVN_PROP__NODE_FILE_ONLY_PROPS
+ NULL };
+
+static svn_boolean_t
+is_known_prop(const char *prop_name,
+ const char *const *known_props)
+{
+ while (*known_props)
+ {
+ if (strcmp(prop_name, *known_props++) == 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+svn_boolean_t
+svn_prop_is_known_svn_rev_prop(const char *prop_name)
+{
+ return is_known_prop(prop_name, known_rev_props);
+}
+
+svn_boolean_t
+svn_prop_is_known_svn_node_prop(const char *prop_name)
+{
+ return is_known_prop(prop_name, known_node_props);
+}
+
+svn_boolean_t
+svn_prop_is_known_svn_file_prop(const char *prop_name)
+{
+ return is_known_prop(prop_name, known_file_props);
+}
+
+svn_boolean_t
+svn_prop_is_known_svn_dir_prop(const char *prop_name)
+{
+ return is_known_prop(prop_name, known_dir_props);
+}
+
+
svn_boolean_t
svn_prop_is_svn_prop(const char *prop_name)
{
Modified: subversion/branches/tree-read-api/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_subr/sqlite.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_subr/sqlite.c Fri Nov 30 18:12:52 2012
@@ -168,7 +168,7 @@ exec_sql2(svn_sqlite__db_t *db, const ch
if (sqlite_err != SQLITE_OK && sqlite_err != ignored_err)
{
svn_error_t *err = svn_error_createf(SQLITE_ERROR_CODE(sqlite_err), NULL,
- _("%s, executing statement '%s'"),
+ _("sqlite: %s, executing statement '%s'"),
err_msg, sql);
sqlite3_free(err_msg);
return err;
@@ -256,8 +256,8 @@ step_with_expectation(svn_sqlite__stmt_t
return svn_error_create(SVN_ERR_SQLITE_ERROR,
svn_sqlite__reset(stmt),
expecting_row
- ? _("Expected database row missing")
- : _("Extra database row found"));
+ ? _("sqlite: Expected database row missing")
+ : _("sqlite: Extra database row found"));
return SVN_NO_ERROR;
}
Modified: subversion/branches/tree-read-api/subversion/libsvn_subr/string.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_subr/string.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_subr/string.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_subr/string.c Fri Nov 30 18:12:52 2012
@@ -37,30 +37,108 @@
#include "svn_private_config.h"
-/* Our own realloc, since APR doesn't have one. Note: this is a
- generic realloc for memory pools, *not* for strings. */
-static void *
-my__realloc(char *data, apr_size_t oldsize, apr_size_t request,
- apr_pool_t *pool)
-{
- void *new_area;
-
- /* kff todo: it's a pity APR doesn't give us this -- sometimes it
- could realloc the block merely by extending in place, sparing us
- a memcpy(), but only the pool would know enough to be able to do
- this. We should add a realloc() to APR if someone hasn't
- already. */
-
- /* malloc new area */
- new_area = apr_palloc(pool, request);
- /* copy data to new area */
- memcpy(new_area, data, oldsize);
+/* Allocate the space for a memory buffer from POOL.
+ * Return a pointer to the new buffer in *DATA and its size in *SIZE.
+ * The buffer size will be at least MINIMUM_SIZE.
+ *
+ * N.B.: The stringbuf creation functions use this, but since stringbufs
+ * always consume at least 1 byte for the NUL terminator, the
+ * resulting data pointers will never be NULL.
+ */
+static APR_INLINE void
+membuf_create(void **data, apr_size_t *size,
+ apr_size_t minimum_size, apr_pool_t *pool)
+{
+ /* apr_palloc will allocate multiples of 8.
+ * Thus, we would waste some of that memory if we stuck to the
+ * smaller size. Note that this is safe even if apr_palloc would
+ * use some other aligment or none at all. */
+ minimum_size = APR_ALIGN_DEFAULT(minimum_size);
+ *data = (!minimum_size ? NULL : apr_palloc(pool, minimum_size));
+ *size = minimum_size;
+}
+
+/* Ensure that the size of a given memory buffer is at least MINIMUM_SIZE
+ * bytes. If *SIZE is already greater than or equal to MINIMUM_SIZE,
+ * this function does nothing.
+ *
+ * If *SIZE is 0, the allocated buffer size will be MINIMUM_SIZE
+ * rounded up to the nearest APR alignment boundary. Otherwse, *SIZE
+ * will be multiplied by a power of two such that the result is
+ * greater or equal to MINIMUM_SIZE. The pointer to the new buffer
+ * will be returned in *DATA, and its size in *SIZE.
+ */
+static APR_INLINE void
+membuf_ensure(void **data, apr_size_t *size,
+ apr_size_t minimum_size, apr_pool_t *pool)
+{
+ if (minimum_size > *size)
+ {
+ apr_size_t new_size = *size;
+
+ if (new_size == 0)
+ /* APR will increase odd allocation sizes to the next
+ * multiple for 8, for instance. Take advantage of that
+ * knowledge and allow for the extra size to be used. */
+ new_size = minimum_size;
+ else
+ while (new_size < minimum_size)
+ {
+ /* new_size is aligned; doubling it should keep it aligned */
+ const apr_size_t prev_size = new_size;
+ new_size *= 2;
+
+ /* check for apr_size_t overflow */
+ if (prev_size > new_size)
+ {
+ new_size = minimum_size;
+ break;
+ }
+ }
- /* I'm NOT freeing old area here -- cuz we're using pools, ugh. */
+ membuf_create(data, size, new_size, pool);
+ }
+}
- /* return new area */
- return new_area;
+void
+svn_membuf__create(svn_membuf_t *membuf, apr_size_t size, apr_pool_t *pool)
+{
+ membuf_create(&membuf->data, &membuf->size, size, pool);
+ membuf->pool = pool;
+}
+
+void
+svn_membuf__ensure(svn_membuf_t *membuf, apr_size_t size)
+{
+ membuf_ensure(&membuf->data, &membuf->size, size, membuf->pool);
+}
+
+void
+svn_membuf__resize(svn_membuf_t *membuf, apr_size_t size)
+{
+ const void *const old_data = membuf->data;
+ const apr_size_t old_size = membuf->size;
+
+ membuf_ensure(&membuf->data, &membuf->size, size, membuf->pool);
+ if (membuf->data && old_data && old_data != membuf->data)
+ memcpy(membuf->data, old_data, old_size);
+}
+
+/* Always provide an out-of-line implementation of svn_membuf__zero */
+#undef svn_membuf__zero
+void
+svn_membuf__zero(svn_membuf_t *membuf)
+{
+ SVN_MEMBUF__ZERO(membuf);
+}
+
+/* Always provide an out-of-line implementation of svn_membuf__nzero */
+#undef svn_membuf__nzero
+void
+svn_membuf__nzero(svn_membuf_t *membuf, apr_size_t size)
+{
+ SVN_MEMBUF__NZERO(membuf, size);
}
static APR_INLINE svn_boolean_t
@@ -283,28 +361,6 @@ svn_stringbuf__morph_into_string(svn_str
/* svn_stringbuf functions */
-/* Create a stringbuf referring to (not copying) an existing block of memory
- * at DATA, of which SIZE bytes are the user data and BLOCKSIZE bytes are
- * allocated in total. DATA[SIZE] must be a zero byte. */
-static svn_stringbuf_t *
-create_stringbuf(char *data, apr_size_t size, apr_size_t blocksize,
- apr_pool_t *pool)
-{
- svn_stringbuf_t *new_string;
-
- new_string = apr_palloc(pool, sizeof(*new_string));
-
- SVN_ERR_ASSERT_NO_RETURN(size < blocksize);
- SVN_ERR_ASSERT_NO_RETURN(data[size] == '\0');
-
- new_string->data = data;
- new_string->len = size;
- new_string->blocksize = blocksize;
- new_string->pool = pool;
-
- return new_string;
-}
-
svn_stringbuf_t *
svn_stringbuf_create_empty(apr_pool_t *pool)
{
@@ -317,24 +373,17 @@ svn_stringbuf_create_ensure(apr_size_t b
void *mem;
svn_stringbuf_t *new_string;
- /* apr_palloc will allocate multiples of 8.
- * Thus, we would waste some of that memory if we stuck to the
- * smaller size. Note that this is safe even if apr_palloc would
- * use some other aligment or none at all. */
-
++blocksize; /* + space for '\0' */
- blocksize = APR_ALIGN_DEFAULT(blocksize);
/* Allocate memory for svn_string_t and data in one chunk. */
- mem = apr_palloc(pool, sizeof(*new_string) + blocksize);
+ membuf_create(&mem, &blocksize, blocksize + sizeof(*new_string), pool);
/* Initialize header and string */
new_string = mem;
-
new_string->data = (char*)mem + sizeof(*new_string);
new_string->data[0] = '\0';
new_string->len = 0;
- new_string->blocksize = blocksize;
+ new_string->blocksize = blocksize - sizeof(*new_string);
new_string->pool = pool;
return new_string;
@@ -375,9 +424,15 @@ svn_stringbuf_createv(apr_pool_t *pool,
{
char *data = apr_pvsprintf(pool, fmt, ap);
apr_size_t size = strlen(data);
+ svn_stringbuf_t *new_string;
+
+ new_string = apr_palloc(pool, sizeof(*new_string));
+ new_string->data = data;
+ new_string->len = size;
+ new_string->blocksize = size + 1;
+ new_string->pool = pool;
- /* wrap an svn_stringbuf_t around the new data */
- return create_stringbuf(data, size, size + 1, pool);
+ return new_string;
}
@@ -444,38 +499,15 @@ svn_stringbuf_isempty(const svn_stringbu
void
svn_stringbuf_ensure(svn_stringbuf_t *str, apr_size_t minimum_size)
{
+ void *mem = NULL;
++minimum_size; /* + space for '\0' */
- /* Keep doubling capacity until have enough. */
- if (str->blocksize < minimum_size)
+ membuf_ensure(&mem, &str->blocksize, minimum_size, str->pool);
+ if (mem && mem != str->data)
{
- if (str->blocksize == 0)
- /* APR will increase odd allocation sizes to the next
- * multiple for 8, for instance. Take advantage of that
- * knowledge and allow for the extra size to be used. */
- str->blocksize = APR_ALIGN_DEFAULT(minimum_size);
- else
- while (str->blocksize < minimum_size)
- {
- /* str->blocksize is aligned;
- * doubling it should keep it aligned */
- apr_size_t prev_size = str->blocksize;
- str->blocksize *= 2;
-
- /* check for apr_size_t overflow */
- if (prev_size > str->blocksize)
- {
- str->blocksize = minimum_size;
- break;
- }
- }
-
- str->data = (char *) my__realloc(str->data,
- str->len + 1,
- /* We need to maintain (and thus copy)
- the trailing nul */
- str->blocksize,
- str->pool);
+ if (str->data)
+ memcpy(mem, str->data, str->len + 1);
+ str->data = mem;
}
}
@@ -1134,3 +1166,108 @@ svn__i64toa_sep(apr_int64_t number, char
return apr_pstrdup(pool, buffer);
}
+unsigned int
+svn_cstring__similarity(const char *stra, const char *strb,
+ svn_membuf_t *buffer, apr_size_t *rlcs)
+{
+ svn_string_t stringa, stringb;
+ stringa.data = stra;
+ stringa.len = strlen(stra);
+ stringb.data = strb;
+ stringb.len = strlen(strb);
+ return svn_string__similarity(&stringa, &stringb, buffer, rlcs);
+}
+
+unsigned int
+svn_string__similarity(const svn_string_t *stringa,
+ const svn_string_t *stringb,
+ svn_membuf_t *buffer, apr_size_t *rlcs)
+{
+ const char *stra = stringa->data;
+ const char *strb = stringb->data;
+ const apr_size_t lena = stringa->len;
+ const apr_size_t lenb = stringb->len;
+ const apr_size_t total = lena + lenb;
+ const char *enda = stra + lena;
+ const char *endb = strb + lenb;
+ apr_size_t lcs = 0;
+
+ /* Skip the common prefix ... */
+ while (stra < enda && strb < endb && *stra == *strb)
+ {
+ ++stra; ++strb;
+ ++lcs;
+ }
+
+ /* ... and the common suffix */
+ while (stra < enda && strb < endb)
+ {
+ --enda; --endb;
+ if (*enda != *endb)
+ {
+ ++enda; ++endb;
+ break;
+ }
+
+ ++lcs;
+ }
+
+ if (stra < enda && strb < endb)
+ {
+ const apr_size_t resta = enda - stra;
+ const apr_size_t restb = endb - strb;
+ const apr_size_t slots = (resta > restb ? restb : resta);
+ apr_size_t *curr, *prev;
+ const char *pstr;
+
+ /* The outer loop must iterate on the longer string. */
+ if (resta < restb)
+ {
+ pstr = stra;
+ stra = strb;
+ strb = pstr;
+
+ pstr = enda;
+ enda = endb;
+ endb = pstr;
+ }
+
+ /* Allocate two columns in the LCS matrix
+ ### Optimize this to (slots + 2) instesd of 2 * (slots + 1) */
+ svn_membuf__ensure(buffer, 2 * (slots + 1) * sizeof(apr_size_t));
+ svn_membuf__nzero(buffer, (slots + 2) * sizeof(apr_size_t));
+ prev = buffer->data;
+ curr = prev + slots + 1;
+
+ /* Calculate LCS length of the remainder */
+ for (pstr = stra; pstr < enda; ++pstr)
+ {
+ int i;
+ for (i = 1; i <= slots; ++i)
+ {
+ if (*pstr == strb[i-1])
+ curr[i] = prev[i-1] + 1;
+ else
+ curr[i] = (curr[i-1] > prev[i] ? curr[i-1] : prev[i]);
+ }
+
+ /* Swap the buffers, making the previous one current */
+ {
+ apr_size_t *const temp = prev;
+ prev = curr;
+ curr = temp;
+ }
+ }
+
+ lcs += prev[slots];
+ }
+
+ if (rlcs)
+ *rlcs = lcs;
+
+ /* Return similarity ratio rounded to 4 significant digits */
+ if (total)
+ return(unsigned int)((2000 * lcs + total/2) / total);
+ else
+ return 1000;
+}
Modified: subversion/branches/tree-read-api/subversion/libsvn_subr/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_subr/temp_serializer.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_subr/temp_serializer.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_subr/temp_serializer.c Fri Nov 30 18:12:52 2012
@@ -86,11 +86,11 @@ align_buffer_end(svn_temp_serializer__co
{
apr_size_t current_len = context->buffer->len;
apr_size_t aligned_len = APR_ALIGN_DEFAULT(current_len);
- if (aligned_len != current_len)
- {
- svn_stringbuf_ensure(context->buffer, aligned_len);
- context->buffer->len = aligned_len;
- }
+
+ if (aligned_len + 1 > context->buffer->blocksize)
+ svn_stringbuf_ensure(context->buffer, aligned_len);
+
+ context->buffer->len = aligned_len;
}
/* Begin the serialization process for the SOURCE_STRUCT and all objects
Modified: subversion/branches/tree-read-api/subversion/libsvn_subr/win32_crashrpt.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_subr/win32_crashrpt.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_subr/win32_crashrpt.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_subr/win32_crashrpt.c Fri Nov 30 18:12:52 2012
@@ -21,6 +21,9 @@
* ====================================================================
*/
+/* prevent "empty compilation unit" warning on e.g. UNIX */
+typedef int win32_crashrpt__dummy;
+
#ifdef WIN32
#ifdef SVN_USE_WIN32_CRASHHANDLER
Modified: subversion/branches/tree-read-api/subversion/libsvn_subr/win32_crypto.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_subr/win32_crypto.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_subr/win32_crypto.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_subr/win32_crypto.c Fri Nov 30 18:12:52 2012
@@ -21,6 +21,9 @@
* ====================================================================
*/
+/* prevent "empty compilation unit" warning on e.g. UNIX */
+typedef int win32_crypto__dummy;
+
/* ==================================================================== */
#if defined(WIN32) && !defined(__MINGW32__)
Modified: subversion/branches/tree-read-api/subversion/libsvn_subr/win32_xlate.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_subr/win32_xlate.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_subr/win32_xlate.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_subr/win32_xlate.c Fri Nov 30 18:12:52 2012
@@ -21,6 +21,9 @@
* ====================================================================
*/
+/* prevent "empty compilation unit" warning on e.g. UNIX */
+typedef int win32_xlate__dummy;
+
#ifdef WIN32
/* Define _WIN32_DCOM for CoInitializeEx(). */
Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/adm_ops.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_wc/adm_ops.c Fri Nov 30 18:12:52 2012
@@ -2446,9 +2446,19 @@ svn_wc_add_lock2(svn_wc_context_t *wc_ct
}
/* if svn:needs-lock is present, then make the file read-write. */
- SVN_ERR(svn_wc__internal_propget(&needs_lock, wc_ctx->db, local_abspath,
- SVN_PROP_NEEDS_LOCK, scratch_pool,
- scratch_pool));
+ err = svn_wc__internal_propget(&needs_lock, wc_ctx->db, local_abspath,
+ SVN_PROP_NEEDS_LOCK, scratch_pool,
+ scratch_pool);
+
+ if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
+ {
+ /* The node has non wc representation (e.g. deleted), so
+ we don't want to touch the in-wc file */
+ svn_error_clear(err);
+ return SVN_NO_ERROR;
+ }
+ SVN_ERR(err);
+
if (needs_lock)
SVN_ERR(svn_io_set_file_read_write(local_abspath, FALSE, scratch_pool));
Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/deprecated.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_wc/deprecated.c Fri Nov 30 18:12:52 2012
@@ -3196,6 +3196,38 @@ svn_wc_get_actual_target(const char *pat
return svn_error_trace(svn_wc_context_destroy(wc_ctx));
}
+/* This function has no internal variant as its behavior on switched
+ non-directories is not what you would expect. But this happens to
+ be the legacy behavior of this function. */
+svn_error_t *
+svn_wc_is_wc_root2(svn_boolean_t *wc_root,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *scratch_pool)
+{
+ svn_boolean_t is_root;
+ svn_boolean_t is_switched;
+ svn_kind_t kind;
+ svn_error_t *err;
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+ err = svn_wc__check_wc_root(&is_root, &kind, &is_switched,
+ wc_ctx->db, local_abspath, scratch_pool);
+
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND &&
+ err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
+ return svn_error_trace(err);
+
+ return svn_error_create(SVN_ERR_ENTRY_NOT_FOUND, err, err->message);
+ }
+
+ *wc_root = is_root || (kind == svn_kind_dir && is_switched);
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_wc_is_wc_root(svn_boolean_t *wc_root,
const char *path,
Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/diff_editor.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_wc/diff_editor.c Fri Nov 30 18:12:52 2012
@@ -610,8 +610,8 @@ file_diff(struct edit_baton *eb,
apr_hash_t *baseprops;
/* Get svn:mime-type from pristine props (in BASE or WORKING) of PATH. */
- SVN_ERR(svn_wc__get_pristine_props(&baseprops, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&baseprops, db, local_abspath,
+ scratch_pool, scratch_pool));
if (baseprops)
base_mimetype = get_prop_mimetype(baseprops);
else
@@ -731,8 +731,8 @@ file_diff(struct edit_baton *eb,
|| status == svn_wc__db_status_copied
|| status == svn_wc__db_status_moved_here);
- SVN_ERR(svn_wc__get_pristine_props(&baseprops, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&baseprops, db, local_abspath,
+ scratch_pool, scratch_pool));
/* baseprops will be NULL for added nodes */
if (!baseprops)
@@ -984,8 +984,8 @@ report_wc_file_as_added(struct edit_bato
emptyprops = apr_hash_make(scratch_pool);
if (eb->use_text_base)
- SVN_ERR(svn_wc__get_pristine_props(&wcprops, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&wcprops, db, local_abspath,
+ scratch_pool, scratch_pool));
else
SVN_ERR(svn_wc__get_actual_props(&wcprops, db, local_abspath,
scratch_pool, scratch_pool));
@@ -996,16 +996,21 @@ report_wc_file_as_added(struct edit_bato
if (eb->use_text_base)
- SVN_ERR(get_pristine_file(&source_file, db, local_abspath,
- FALSE, scratch_pool, scratch_pool));
+ {
+ SVN_ERR(get_pristine_file(&source_file, db, local_abspath,
+ FALSE, scratch_pool, scratch_pool));
+ translated_file = source_file; /* No translation needed */
+ }
else
- source_file = local_abspath;
+ {
+ source_file = local_abspath;
- SVN_ERR(svn_wc__internal_translated_file(
+ SVN_ERR(svn_wc__internal_translated_file(
&translated_file, source_file, db, local_abspath,
SVN_WC_TRANSLATE_TO_NF | SVN_WC_TRANSLATE_USE_GLOBAL_TMP,
eb->cancel_func, eb->cancel_baton,
scratch_pool, scratch_pool));
+ }
SVN_ERR(eb->callbacks->file_added(NULL, NULL, NULL,
path,
@@ -1054,8 +1059,8 @@ report_wc_directory_as_added(struct edit
eb->changelist_hash, scratch_pool))
{
if (eb->use_text_base)
- SVN_ERR(svn_wc__get_pristine_props(&wcprops, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&wcprops, db, local_abspath,
+ scratch_pool, scratch_pool));
else
SVN_ERR(svn_wc__get_actual_props(&wcprops, db, local_abspath,
scratch_pool, scratch_pool));
@@ -1227,8 +1232,9 @@ delete_entry(const char *path,
SVN_ERR(get_pristine_file(&textbase, db, local_abspath,
eb->use_text_base, pool, pool));
- SVN_ERR(svn_wc__get_pristine_props(&baseprops, eb->db, local_abspath,
- pool, pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&baseprops,
+ eb->db, local_abspath,
+ pool, pool));
base_mimetype = get_prop_mimetype(baseprops);
SVN_ERR(eb->callbacks->file_deleted(NULL, NULL, path,
@@ -1349,9 +1355,10 @@ close_directory(void *dir_baton,
{
if (db->eb->use_text_base)
{
- SVN_ERR(svn_wc__get_pristine_props(&originalprops,
- eb->db, db->local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&originalprops,
+ eb->db, db->local_abspath,
+ scratch_pool,
+ scratch_pool));
}
else
{
@@ -1362,9 +1369,9 @@ close_directory(void *dir_baton,
scratch_pool, scratch_pool));
/* Load the BASE and repository directory properties. */
- SVN_ERR(svn_wc__get_pristine_props(&base_props,
- eb->db, db->local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_base_get_props(&base_props,
+ eb->db, db->local_abspath,
+ scratch_pool, scratch_pool));
repos_props = apply_propchanges(base_props, db->propchanges);
Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/diff_local.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_wc/diff_local.c Fri Nov 30 18:12:52 2012
@@ -239,8 +239,8 @@ file_diff(struct diff_baton *eb,
/* We show a deletion of what was actually deleted */
SVN_ERR_ASSERT(status == svn_wc__db_status_deleted);
- SVN_ERR(svn_wc__get_pristine_props(&del_props, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&del_props, db, local_abspath,
+ scratch_pool, scratch_pool));
SVN_ERR(svn_wc__db_read_pristine_info(NULL, NULL, NULL, NULL, NULL,
NULL, &del_checksum, NULL,
@@ -513,9 +513,7 @@ diff_status_callback(void *baton,
/* Report the prop change. */
/* ### This case should probably be extended for git-diff, but this
is what the old diff code provided */
- if (status->node_status == svn_wc_status_deleted
- || status->node_status == svn_wc_status_replaced
- || status->prop_status == svn_wc_status_modified)
+ if (status->prop_status == svn_wc_status_modified)
{
apr_array_header_t *propchanges;
apr_hash_t *baseprops;
Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/externals.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_wc/externals.c Fri Nov 30 18:12:52 2012
@@ -164,16 +164,15 @@ svn_wc_parse_externals_description3(apr_
apr_pool_t *pool)
{
int i;
- int j;
apr_array_header_t *externals = NULL;
apr_array_header_t *lines = svn_cstring_split(desc, "\n\r", TRUE, pool);
const char *parent_directory_display = svn_path_is_url(parent_directory) ?
parent_directory : svn_dirent_local_style(parent_directory, pool);
/* If an error occurs halfway through parsing, *externals_p should stay
- * untouched. So, store the list in a local var first. Since we are checking
- * for duplicate targets, always compose the list regardless. */
- externals = apr_array_make(pool, 1, sizeof(svn_wc_external_item2_t *));
+ * untouched. So, store the list in a local var first. */
+ if (externals_p)
+ externals = apr_array_make(pool, 1, sizeof(svn_wc_external_item2_t *));
for (i = 0; i < lines->nelts; i++)
{
@@ -331,23 +330,8 @@ svn_wc_parse_externals_description3(apr_
item->url = svn_dirent_canonicalize(item->url, pool);
}
- /* Has the same WC target path already been mentioned in this prop? */
- for (j = 0; j < externals->nelts; j++)
- {
- svn_wc_external_item2_t *other_item =
- APR_ARRAY_IDX(externals, j, svn_wc_external_item2_t *);
-
- if (strcmp(item->target_dir, other_item->target_dir) == 0)
- return svn_error_createf
- (SVN_ERR_CLIENT_INVALID_EXTERNALS_DESCRIPTION, NULL,
- _("Invalid %s property on '%s': "
- "target '%s' appears more than once"),
- SVN_PROP_EXTERNALS,
- parent_directory_display,
- item->target_dir);
- }
-
- APR_ARRAY_PUSH(externals, svn_wc_external_item2_t *) = item;
+ if (externals)
+ APR_ARRAY_PUSH(externals, svn_wc_external_item2_t *) = item;
}
if (externals_p)
@@ -356,6 +340,53 @@ svn_wc_parse_externals_description3(apr_
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_wc__externals_find_target_dups(apr_array_header_t **duplicate_targets,
+ apr_array_header_t *externals,
+ apr_pool_t *pool,
+ apr_pool_t *scratch_pool)
+{
+ int i;
+ unsigned int len;
+ unsigned int len2;
+ const char *target;
+ apr_hash_t *targets = apr_hash_make(scratch_pool);
+ apr_hash_t *targets2 = NULL;
+ *duplicate_targets = NULL;
+
+ for (i = 0; i < externals->nelts; i++)
+ {
+ target = APR_ARRAY_IDX(externals, i,
+ svn_wc_external_item2_t*)->target_dir;
+ len = apr_hash_count(targets);
+ apr_hash_set(targets, target, APR_HASH_KEY_STRING, "");
+ if (len == apr_hash_count(targets))
+ {
+ /* Hashtable length is unchanged. This must be a duplicate. */
+
+ /* Collapse multiple duplicates of the same target by using a second
+ * hash layer. */
+ if (! targets2)
+ targets2 = apr_hash_make(scratch_pool);
+ len2 = apr_hash_count(targets2);
+ apr_hash_set(targets2, target, APR_HASH_KEY_STRING, "");
+ if (len2 < apr_hash_count(targets2))
+ {
+ /* The second hash list just got bigger, i.e. this target has
+ * not been counted as duplicate before. */
+ if (! *duplicate_targets)
+ {
+ *duplicate_targets = apr_array_make(
+ pool, 1, sizeof(svn_wc_external_item2_t*));
+ }
+ APR_ARRAY_PUSH((*duplicate_targets), const char *) = target;
+ }
+ /* Else, this same target has already been recorded as a duplicate,
+ * don't count it again. */
+ }
+ }
+ return SVN_NO_ERROR;
+}
struct edit_baton
{
Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/lock.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_wc/lock.c Fri Nov 30 18:12:52 2012
@@ -1066,75 +1066,21 @@ child_is_disjoint(svn_boolean_t *disjoin
const char *local_abspath,
apr_pool_t *scratch_pool)
{
- const char *node_repos_root, *node_repos_relpath, *node_repos_uuid;
- const char *parent_repos_root, *parent_repos_relpath, *parent_repos_uuid;
- svn_wc__db_status_t parent_status;
- const char *parent_abspath, *base;
+ svn_boolean_t is_switched;
/* Check if the parent directory knows about this node */
- SVN_ERR(svn_wc__db_is_wcroot(disjoint, db, local_abspath, scratch_pool));
+ SVN_ERR(svn_wc__db_is_switched(disjoint, &is_switched, NULL,
+ db, local_abspath, scratch_pool));
if (*disjoint)
return SVN_NO_ERROR;
- svn_dirent_split(&parent_abspath, &base, local_abspath, scratch_pool);
-
- SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, &node_repos_relpath,
- &node_repos_root, &node_repos_uuid, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool));
-
- /* If the node does not have its own repos_relpath, its value is inherited
- from a parent node, which implies that the node is not disjoint. */
- if (node_repos_relpath == NULL)
- {
- *disjoint = FALSE;
- return SVN_NO_ERROR;
- }
-
- SVN_ERR(svn_wc__db_read_info(&parent_status, NULL, NULL,
- &parent_repos_relpath, &parent_repos_root,
- &parent_repos_uuid, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL,
- db, parent_abspath,
- scratch_pool, scratch_pool));
-
- if (parent_repos_relpath == NULL)
- {
- if (parent_status == svn_wc__db_status_added)
- SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &parent_repos_relpath,
- &parent_repos_root,
- &parent_repos_uuid,
- NULL, NULL, NULL, NULL, NULL, NULL,
- db, parent_abspath,
- scratch_pool, scratch_pool));
- else
- SVN_ERR(svn_wc__db_scan_base_repos(&parent_repos_relpath,
- &parent_repos_root,
- &parent_repos_uuid,
- db, parent_abspath,
- scratch_pool, scratch_pool));
- }
-
- if (strcmp(parent_repos_root, node_repos_root) != 0 ||
- strcmp(parent_repos_uuid, node_repos_uuid) != 0 ||
- strcmp(svn_relpath_join(parent_repos_relpath, base, scratch_pool),
- node_repos_relpath) != 0)
- {
- *disjoint = TRUE;
- }
- else
- *disjoint = FALSE;
+ if (is_switched)
+ *disjoint = TRUE;
return SVN_NO_ERROR;
}
-
/* */
static svn_error_t *
open_anchor(svn_wc_adm_access_t **anchor_access,
@@ -1522,13 +1468,25 @@ svn_wc__acquire_write_lock(const char **
apr_pool_t *scratch_pool)
{
svn_wc__db_t *db = wc_ctx->db;
+ svn_boolean_t is_wcroot;
+ svn_boolean_t is_switched;
svn_kind_t kind;
svn_error_t *err;
- SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath,
- (lock_root_abspath != NULL) /* allow_missing*/,
- FALSE /* show_hidden */,
- scratch_pool));
+ err = svn_wc__db_is_switched(&is_wcroot, &is_switched, &kind,
+ db, local_abspath, scratch_pool);
+
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+
+ kind = svn_kind_none;
+ is_wcroot = FALSE;
+ is_switched = FALSE;
+ }
if (!lock_root_abspath && kind != svn_kind_dir)
return svn_error_createf(SVN_ERR_WC_NOT_DIRECTORY, NULL,
@@ -1538,15 +1496,6 @@ svn_wc__acquire_write_lock(const char **
if (lock_anchor && kind == svn_kind_dir)
{
- svn_boolean_t is_wcroot;
-
- SVN_ERR_ASSERT(lock_root_abspath != NULL);
-
- /* Perform a cheap check to avoid looking for a parent working copy,
- which might be very expensive in some specific scenarios */
- SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath,
- scratch_pool));
-
if (is_wcroot)
lock_anchor = FALSE;
}
@@ -1554,58 +1503,48 @@ svn_wc__acquire_write_lock(const char **
if (lock_anchor)
{
const char *parent_abspath;
- svn_kind_t parent_kind;
-
SVN_ERR_ASSERT(lock_root_abspath != NULL);
parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
- err = svn_wc__db_read_kind(&parent_kind, db, parent_abspath,
- TRUE /* allow_missing */,
- FALSE /* show_missing */,
- scratch_pool);
- if (err && SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
+
+ if (kind == svn_kind_dir)
{
- svn_error_clear(err);
- parent_kind = svn_kind_unknown;
+ if (! is_switched)
+ local_abspath = parent_abspath;
+ }
+ else if (kind != svn_kind_none && kind != svn_kind_unknown)
+ {
+ /* In the single-DB world we know parent exists */
+ local_abspath = parent_abspath;
}
else
- SVN_ERR(err);
-
- if (kind == svn_kind_dir && parent_kind == svn_kind_dir)
{
- svn_boolean_t disjoint;
- SVN_ERR(child_is_disjoint(&disjoint, wc_ctx->db, local_abspath,
- scratch_pool));
- if (!disjoint)
- local_abspath = parent_abspath;
+ /* Can't lock parents that don't exist */
+ svn_kind_t parent_kind;
+ err = svn_wc__db_read_kind(&parent_kind, db, parent_abspath,
+ TRUE /* allow_missing */,
+ FALSE /* show_hidden */,
+ scratch_pool);
+ if (err && SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
+ {
+ svn_error_clear(err);
+ parent_kind = svn_kind_unknown;
+ }
+ else
+ SVN_ERR(err);
+
+ if (parent_kind != svn_kind_dir)
+ return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
+ _("'%s' is not a working copy"),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+
+ local_abspath = parent_abspath;
}
- else if (parent_kind == svn_kind_dir)
- local_abspath = parent_abspath;
- else if (kind != svn_kind_dir)
- return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
- _("'%s' is not a working copy"),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
}
else if (kind != svn_kind_dir)
{
local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-
- /* Can't lock parents that don't exist */
- if (kind == svn_kind_unknown)
- {
- SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath,
- FALSE /* allow_missing */,
- FALSE /* show_hidden */,
- scratch_pool));
-
- if (kind != svn_kind_dir)
- return svn_error_createf(
- SVN_ERR_WC_NOT_DIRECTORY, NULL,
- _("Can't obtain lock on non-directory '%s'."),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
- }
}
if (lock_root_abspath)
Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/props.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_wc/props.c Fri Nov 30 18:12:52 2012
@@ -280,8 +280,8 @@ svn_wc__perform_props_merge(svn_wc_notif
}
if (had_props)
- SVN_ERR(svn_wc__get_pristine_props(&pristine_props, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&pristine_props, db, local_abspath,
+ scratch_pool, scratch_pool));
if (pristine_props == NULL)
pristine_props = apr_hash_make(scratch_pool);
@@ -1513,13 +1513,13 @@ svn_wc__prop_retrieve_recursive(apr_hash
}
svn_error_t *
-svn_wc__get_pristine_props(apr_hash_t **props,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_wc_get_pristine_props(apr_hash_t **props,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- svn_wc__db_status_t status;
+ svn_error_t *err;
SVN_ERR_ASSERT(props != NULL);
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -1527,60 +1527,23 @@ svn_wc__get_pristine_props(apr_hash_t **
/* Certain node stats do not have properties defined on them. Check the
state, and return NULL for these situations. */
- SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool));
- if (status == svn_wc__db_status_added)
- {
- /* Resolve the status. copied and moved_here arrive with properties,
- while a simple add does not. */
- SVN_ERR(svn_wc__db_scan_addition(&status, NULL,
- NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool));
- }
- if (status == svn_wc__db_status_added
-#if 0
- /* ### the update editor needs to fetch properties while the directory
- ### is still marked incomplete */
- || status == svn_wc__db_status_incomplete
-#endif
- || status == svn_wc__db_status_excluded
- || status == svn_wc__db_status_server_excluded
- || status == svn_wc__db_status_not_present)
- {
- *props = NULL;
- return SVN_NO_ERROR;
- }
+ err = svn_wc__db_read_pristine_props(props, wc_ctx->db, local_abspath,
+ result_pool, scratch_pool);
- /* status: normal, moved_here, copied, deleted */
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
+ return svn_error_trace(err);
- /* After the above checks, these pristines should always be present. */
- return svn_error_trace(
- svn_wc__db_read_pristine_props(props, db, local_abspath,
- result_pool, scratch_pool));
-}
+ svn_error_clear(err);
+ /* Documented behavior is to set *PROPS to NULL */
+ *props = NULL;
+ }
-svn_error_t *
-svn_wc_get_pristine_props(apr_hash_t **props,
- svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- return svn_error_trace(svn_wc__get_pristine_props(props,
- wc_ctx->db,
- local_abspath,
- result_pool,
- scratch_pool));
+ return SVN_NO_ERROR;
}
-
svn_error_t *
svn_wc_prop_get2(const svn_string_t **value,
svn_wc_context_t *wc_ctx,
@@ -1590,6 +1553,7 @@ svn_wc_prop_get2(const svn_string_t **va
apr_pool_t *scratch_pool)
{
enum svn_prop_kind kind = svn_property_kind2(name);
+ svn_error_t *err;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -1600,8 +1564,18 @@ svn_wc_prop_get2(const svn_string_t **va
_("Property '%s' is an entry property"), name);
}
- SVN_ERR(svn_wc__internal_propget(value, wc_ctx->db, local_abspath, name,
- result_pool, scratch_pool));
+ err = svn_wc__internal_propget(value, wc_ctx->db, local_abspath, name,
+ result_pool, scratch_pool);
+
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ /* Documented behavior is to set *VALUE to NULL */
+ *value = NULL;
+ }
return SVN_NO_ERROR;
}
@@ -1616,35 +1590,15 @@ svn_wc__internal_propget(const svn_strin
{
apr_hash_t *prophash = NULL;
enum svn_prop_kind kind = svn_property_kind2(name);
- svn_boolean_t hidden;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
SVN_ERR_ASSERT(kind != svn_prop_entry_kind);
- /* This returns SVN_ERR_WC_PATH_NOT_FOUND for unversioned paths for us */
- SVN_ERR(svn_wc__db_node_hidden(&hidden, db, local_abspath, scratch_pool));
- if (hidden)
- {
- /* The node is not present, or not really "here". Therefore, the
- property is not present. */
- *value = NULL;
- return SVN_NO_ERROR;
- }
-
if (kind == svn_prop_wc_kind)
{
- svn_error_t *err;
- /* If no dav cache can be found, just set VALUE to NULL (for
- compatibility with pre-WC-NG code). */
- err = svn_wc__db_base_get_dav_cache(&prophash, db, local_abspath,
- result_pool, scratch_pool);
- if (err && (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND))
- {
- *value = NULL;
- svn_error_clear(err);
- return SVN_NO_ERROR;
- }
- SVN_ERR_W(err, _("Failed to load properties"));
+ SVN_ERR_W(svn_wc__db_base_get_dav_cache(&prophash, db, local_abspath,
+ result_pool, scratch_pool),
+ _("Failed to load properties"));
}
else
{
@@ -1665,47 +1619,38 @@ svn_wc__internal_propget(const svn_strin
/* The special Subversion properties are not valid for all node kinds.
Return an error if NAME is an invalid Subversion property for PATH which
- is of kind NODE_KIND. */
+ is of kind NODE_KIND. NAME must be in the "svn:" name space.
+
+ Note that we only disallow the property if we're sure it's one that
+ already has a meaning for a different node kind. We don't disallow
+ setting an *unknown* svn: prop here, at this level; a higher level
+ should disallow that if desired.
+ */
static svn_error_t *
validate_prop_against_node_kind(const char *name,
const char *path,
svn_node_kind_t node_kind,
apr_pool_t *pool)
{
-
- const char *file_prohibit[] = { SVN_PROP_IGNORE,
- SVN_PROP_EXTERNALS,
- SVN_PROP_INHERITABLE_AUTO_PROPS,
- SVN_PROP_INHERITABLE_IGNORES,
- NULL };
- const char *dir_prohibit[] = { SVN_PROP_EXECUTABLE,
- SVN_PROP_KEYWORDS,
- SVN_PROP_EOL_STYLE,
- SVN_PROP_MIME_TYPE,
- SVN_PROP_NEEDS_LOCK,
- NULL };
- const char **node_kind_prohibit;
const char *path_display
= svn_path_is_url(path) ? path : svn_dirent_local_style(path, pool);
switch (node_kind)
{
case svn_node_dir:
- node_kind_prohibit = dir_prohibit;
- while (*node_kind_prohibit)
- if (strcmp(name, *node_kind_prohibit++) == 0)
- return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
- _("Cannot set '%s' on a directory ('%s')"),
- name, path_display);
+ if (! svn_prop_is_known_svn_dir_prop(name)
+ && svn_prop_is_known_svn_file_prop(name))
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("Cannot set '%s' on a directory ('%s')"),
+ name, path_display);
break;
case svn_node_file:
- node_kind_prohibit = file_prohibit;
- while (*node_kind_prohibit)
- if (strcmp(name, *node_kind_prohibit++) == 0)
- return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
- _("Cannot set '%s' on a file ('%s')"),
- name,
- path_display);
+ if (! svn_prop_is_known_svn_file_prop(name)
+ && svn_prop_is_known_svn_dir_prop(name))
+ return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+ _("Cannot set '%s' on a file ('%s')"),
+ name,
+ path_display);
break;
default:
return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
@@ -1952,6 +1897,7 @@ do_propset(svn_wc__db_t *db,
notify_action,
scratch_pool);
notify->prop_name = name;
+ notify->kind = kind;
(*notify_func)(notify_baton, notify, scratch_pool);
}
@@ -2168,9 +2114,34 @@ svn_wc_canonicalize_svn_prop(const svn_s
an svn:externals line. As it happens, our parse code
checks for this, so all we have to is invoke it --
we're not interested in the parsed result, only in
- whether or the parsing errored. */
- SVN_ERR(svn_wc_parse_externals_description3
- (NULL, path, propval->data, FALSE, pool));
+ whether or not the parsing errored. */
+ apr_array_header_t *externals = NULL;
+ apr_array_header_t *duplicate_targets = NULL;
+ SVN_ERR(svn_wc_parse_externals_description3(&externals, path,
+ propval->data, FALSE,
+ /*scratch_*/pool));
+ SVN_ERR(svn_wc__externals_find_target_dups(&duplicate_targets,
+ externals,
+ /*scratch_*/pool,
+ /*scratch_*/pool));
+ if (duplicate_targets && duplicate_targets->nelts > 0)
+ {
+ const char *more_str = "";
+ if (duplicate_targets->nelts > 1)
+ {
+ more_str = apr_psprintf(/*scratch_*/pool,
+ _(" (%d more duplicate targets found)"),
+ duplicate_targets->nelts - 1);
+ }
+ return svn_error_createf(
+ SVN_ERR_WC_DUPLICATE_EXTERNALS_TARGET, NULL,
+ _("Invalid %s property on '%s': "
+ "target '%s' appears more than once%s"),
+ SVN_PROP_EXTERNALS,
+ svn_dirent_local_style(path, pool),
+ APR_ARRAY_IDX(duplicate_targets, 0, const char*),
+ more_str);
+ }
}
}
else if (strcmp(propname, SVN_PROP_KEYWORDS) == 0)
@@ -2338,129 +2309,6 @@ svn_wc__has_magic_property(const apr_arr
return FALSE;
}
-/* Remove all prop name value pairs from PROP_HASH where the property
- name is not PROPNAME. */
-static void
-filter_unwanted_props(apr_hash_t *prop_hash,
- const char * propname,
- apr_pool_t *scratch_pool)
-{
- apr_hash_index_t *hi;
-
- for (hi = apr_hash_first(scratch_pool, prop_hash);
- hi;
- hi = apr_hash_next(hi))
- {
- const char *ipropname = svn__apr_hash_index_key(hi);
-
- if (strcmp(ipropname, propname) != 0)
- apr_hash_set(prop_hash, ipropname, APR_HASH_KEY_STRING, NULL);
- }
- return;
-}
-
-svn_error_t *
-svn_wc__internal_get_iprops(apr_array_header_t **inherited_props,
- svn_wc__db_t *db,
- const char *local_abspath,
- const char *propname,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- int i;
- apr_array_header_t *cached_iprops = NULL;
- const char *parent_abspath = local_abspath;
- svn_boolean_t is_wc_root = FALSE;
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
- SVN_ERR_ASSERT(inherited_props);
- *inherited_props = apr_array_make(result_pool, 1,
- sizeof(svn_prop_inherited_item_t *));
-
- /* Walk up to the root of the WC looking for inherited properties. When we
- reach the WC root also check for cached inherited properties. */
- while (TRUE)
- {
- apr_hash_t *actual_props;
-
- svn_pool_clear(iterpool);
-
- SVN_ERR(svn_wc__internal_is_wc_root(&is_wc_root, db, parent_abspath,
- iterpool));
-
- if (is_wc_root)
- {
- /* If the WC root is also the root of the repository then by
- definition there are no inheritable properties to be had,
- but checking for that is just as expensive as fetching them
- anyway. */
-
- /* Grab the cached inherited properties for the WC root. */
- SVN_ERR(svn_wc__db_read_cached_iprops(&cached_iprops, db,
- parent_abspath,
- scratch_pool, iterpool));
- }
-
- /* If PARENT_ABSPATH is a true parent of LOCAL_ABSPATH, then
- LOCAL_ABSPATH can inherit properties from it. */
- if (strcmp(local_abspath, parent_abspath) != 0)
- {
- SVN_ERR(svn_wc__db_read_props(&actual_props, db, parent_abspath,
- result_pool, iterpool));
- if (actual_props)
- {
- /* If we only want PROPNAME filter out any other properties. */
- if (propname)
- filter_unwanted_props(actual_props, propname, iterpool);
-
- if (apr_hash_count(actual_props))
- {
- svn_prop_inherited_item_t *iprop_elt =
- apr_pcalloc(result_pool,
- sizeof(svn_prop_inherited_item_t));
- iprop_elt->path_or_url = apr_pstrdup(result_pool,
- parent_abspath);
- iprop_elt->prop_hash = actual_props;
- /* Build the output array in depth-first order. */
- svn_sort__array_insert(&iprop_elt, *inherited_props, 0);
- }
- }
- }
-
- /* Inheritance only goes as far as the nearest WC root. */
- if (is_wc_root)
- break;
-
- /* Keep looking for the WC root. */
- parent_abspath = svn_dirent_dirname(parent_abspath, scratch_pool);
- }
-
- if (cached_iprops)
- {
- for (i = cached_iprops->nelts - 1; i >= 0; i--)
- {
- svn_prop_inherited_item_t *cached_iprop =
- APR_ARRAY_IDX(cached_iprops, i, svn_prop_inherited_item_t *);
-
- /* An empty property hash in the iprops cache means there are no
- inherited properties. */
- if (apr_hash_count(cached_iprop->prop_hash) == 0)
- continue;
-
- if (propname)
- filter_unwanted_props(cached_iprop->prop_hash, propname,
- scratch_pool);
-
- /* If we didn't filter everything then keep this iprop. */
- if (apr_hash_count(cached_iprop->prop_hash))
- svn_sort__array_insert(&cached_iprop, *inherited_props, 0);
- }
- }
-
- svn_pool_destroy(iterpool);
- return SVN_NO_ERROR;
-}
-
svn_error_t *
svn_wc__get_iprops(apr_array_header_t **inherited_props,
svn_wc_context_t *wc_ctx,
@@ -2469,9 +2317,11 @@ svn_wc__get_iprops(apr_array_header_t **
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- return svn_error_trace(svn_wc__internal_get_iprops(inherited_props, wc_ctx->db,
- local_abspath, propname,
- result_pool, scratch_pool));
+ return svn_error_trace(
+ svn_wc__db_read_inherited_props(inherited_props,
+ wc_ctx->db, local_abspath,
+ propname,
+ result_pool, scratch_pool));
}
svn_error_t *
Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/props.h
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/props.h?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_wc/props.h (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_wc/props.h Fri Nov 30 18:12:52 2012
@@ -127,15 +127,6 @@ svn_wc__props_modified(svn_boolean_t *mo
const char *local_abspath,
apr_pool_t *scratch_pool);
-/* Internal version of svn_wc_get_pristine_props(). */
-svn_error_t *
-svn_wc__get_pristine_props(apr_hash_t **props,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
-
-
/* Internal version of svn_wc_prop_list2(). */
svn_error_t *
svn_wc__get_actual_props(apr_hash_t **props,
Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/status.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_wc/status.c Fri Nov 30 18:12:52 2012
@@ -1028,9 +1028,10 @@ collect_ignore_patterns(apr_array_header
FALSE, result_pool);
}
- SVN_ERR(svn_wc__internal_get_iprops(&inherited_props, db, local_abspath,
- SVN_PROP_INHERITABLE_IGNORES,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_inherited_props(&inherited_props,
+ db, local_abspath,
+ SVN_PROP_INHERITABLE_IGNORES,
+ scratch_pool, scratch_pool));
for (i = 0; i < inherited_props->nelts; i++)
{
apr_hash_index_t *hi;
Modified: subversion/branches/tree-read-api/subversion/libsvn_wc/translate.c
URL: http://svn.apache.org/viewvc/subversion/branches/tree-read-api/subversion/libsvn_wc/translate.c?rev=1415773&r1=1415772&r2=1415773&view=diff
==============================================================================
--- subversion/branches/tree-read-api/subversion/libsvn_wc/translate.c (original)
+++ subversion/branches/tree-read-api/subversion/libsvn_wc/translate.c Fri Nov 30 18:12:52 2012
@@ -409,8 +409,8 @@ svn_wc__sync_flags_with_props(svn_boolea
set the file read_only just yet. That happens upon commit. */
apr_hash_t *pristine_props;
- SVN_ERR(svn_wc__get_pristine_props(&pristine_props, db, local_abspath,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_pristine_props(&pristine_props, db, local_abspath,
+ scratch_pool, scratch_pool));
if (pristine_props
&& apr_hash_get(pristine_props,