summaryrefslogtreecommitdiff
path: root/subversion/libsvn_delta
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_delta')
-rw-r--r--subversion/libsvn_delta/branch.c2
-rw-r--r--subversion/libsvn_delta/branch_compat.c54
-rw-r--r--subversion/libsvn_delta/compat.c50
-rw-r--r--subversion/libsvn_delta/debug_editor.c159
-rw-r--r--subversion/libsvn_delta/deprecated.c73
-rw-r--r--subversion/libsvn_delta/element.c4
-rw-r--r--subversion/libsvn_delta/libsvn_delta.pc.in8
-rw-r--r--subversion/libsvn_delta/path_driver.c313
8 files changed, 421 insertions, 242 deletions
diff --git a/subversion/libsvn_delta/branch.c b/subversion/libsvn_delta/branch.c
index 95355d44650d4..57cdea7ce0747 100644
--- a/subversion/libsvn_delta/branch.c
+++ b/subversion/libsvn_delta/branch.c
@@ -157,7 +157,7 @@ branch_txn_delete_branch(svn_branch__txn_t *txn,
if (strcmp(b->bid, bid) == 0)
{
- svn_sort__array_delete(txn->priv->branches, i, 1);
+ SVN_ERR(svn_sort__array_delete2(txn->priv->branches, i, 1));
break;
}
}
diff --git a/subversion/libsvn_delta/branch_compat.c b/subversion/libsvn_delta/branch_compat.c
index dac0e191cf24a..635b31a5eb683 100644
--- a/subversion/libsvn_delta/branch_compat.c
+++ b/subversion/libsvn_delta/branch_compat.c
@@ -875,6 +875,8 @@ drive_ev1_props(const char *repos_relpath,
*/
static svn_error_t *
apply_change(void **dir_baton,
+ const svn_delta_editor_t *editor,
+ void *edit_baton,
void *parent_baton,
void *callback_baton,
const char *ev1_relpath,
@@ -905,7 +907,7 @@ apply_change(void **dir_baton,
/* Only property edits are allowed on the root. */
SVN_ERR_ASSERT(change->action == RESTRUCTURE_NONE);
SVN_ERR(drive_ev1_props(ev1_relpath, change, base_props,
- eb->deditor, *dir_baton, scratch_pool));
+ editor, *dir_baton, scratch_pool));
/* No further action possible for the root. */
return SVN_NO_ERROR;
@@ -913,8 +915,8 @@ apply_change(void **dir_baton,
if (change->action == RESTRUCTURE_DELETE)
{
- SVN_ERR(eb->deditor->delete_entry(ev1_relpath, change->deleting_rev,
- parent_baton, scratch_pool));
+ SVN_ERR(editor->delete_entry(ev1_relpath, change->deleting_rev,
+ parent_baton, scratch_pool));
/* No futher action possible for this node. */
return SVN_NO_ERROR;
@@ -927,11 +929,11 @@ apply_change(void **dir_baton,
if (change->action == RESTRUCTURE_ADD_ABSENT)
{
if (change->kind == svn_node_dir)
- SVN_ERR(eb->deditor->absent_directory(ev1_relpath, parent_baton,
- scratch_pool));
- else if (change->kind == svn_node_file)
- SVN_ERR(eb->deditor->absent_file(ev1_relpath, parent_baton,
+ SVN_ERR(editor->absent_directory(ev1_relpath, parent_baton,
scratch_pool));
+ else if (change->kind == svn_node_file)
+ SVN_ERR(editor->absent_file(ev1_relpath, parent_baton,
+ scratch_pool));
else
SVN_ERR_MALFUNCTION();
@@ -948,8 +950,8 @@ apply_change(void **dir_baton,
/* Do we have an old node to delete first? If so, delete it. */
if (change->deleting)
- SVN_ERR(eb->deditor->delete_entry(ev1_relpath, change->deleting_rev,
- parent_baton, scratch_pool));
+ SVN_ERR(editor->delete_entry(ev1_relpath, change->deleting_rev,
+ parent_baton, scratch_pool));
/* If it's a copy, determine the copy source location. */
if (change->copyfrom_path)
@@ -974,13 +976,13 @@ apply_change(void **dir_baton,
}
if (change->kind == svn_node_dir)
- SVN_ERR(eb->deditor->add_directory(ev1_relpath, parent_baton,
- copyfrom_url, copyfrom_rev,
- result_pool, dir_baton));
- else if (change->kind == svn_node_file)
- SVN_ERR(eb->deditor->add_file(ev1_relpath, parent_baton,
+ SVN_ERR(editor->add_directory(ev1_relpath, parent_baton,
copyfrom_url, copyfrom_rev,
- result_pool, &file_baton));
+ result_pool, dir_baton));
+ else if (change->kind == svn_node_file)
+ SVN_ERR(editor->add_file(ev1_relpath, parent_baton,
+ copyfrom_url, copyfrom_rev,
+ result_pool, &file_baton));
else
SVN_ERR_MALFUNCTION();
}
@@ -993,13 +995,13 @@ apply_change(void **dir_baton,
when we fetch the base properties.) */
if (change->kind == svn_node_dir)
- SVN_ERR(eb->deditor->open_directory(ev1_relpath, parent_baton,
- change->changing_rev,
- result_pool, dir_baton));
- else if (change->kind == svn_node_file)
- SVN_ERR(eb->deditor->open_file(ev1_relpath, parent_baton,
+ SVN_ERR(editor->open_directory(ev1_relpath, parent_baton,
change->changing_rev,
- result_pool, &file_baton));
+ result_pool, dir_baton));
+ else if (change->kind == svn_node_file)
+ SVN_ERR(editor->open_file(ev1_relpath, parent_baton,
+ change->changing_rev,
+ result_pool, &file_baton));
else
SVN_ERR_MALFUNCTION();
}
@@ -1007,10 +1009,10 @@ apply_change(void **dir_baton,
/* Apply any properties in CHANGE to the node. */
if (change->kind == svn_node_dir)
SVN_ERR(drive_ev1_props(ev1_relpath, change, base_props,
- eb->deditor, *dir_baton, scratch_pool));
+ editor, *dir_baton, scratch_pool));
else
SVN_ERR(drive_ev1_props(ev1_relpath, change, base_props,
- eb->deditor, file_baton, scratch_pool));
+ editor, file_baton, scratch_pool));
/* Send the text content delta, if new text content is provided. */
if (change->contents_text)
@@ -1023,7 +1025,7 @@ apply_change(void **dir_baton,
scratch_pool);
/* ### would be nice to have a BASE_CHECKSUM, but hey: this is the
### shim code... */
- SVN_ERR(eb->deditor->apply_textdelta(file_baton, NULL, scratch_pool,
+ SVN_ERR(editor->apply_textdelta(file_baton, NULL, scratch_pool,
&handler, &handler_baton));
/* ### it would be nice to send a true txdelta here, but whatever. */
SVN_ERR(svn_txdelta_send_stream(read_stream, handler, handler_baton,
@@ -1033,7 +1035,7 @@ apply_change(void **dir_baton,
if (file_baton)
{
- SVN_ERR(eb->deditor->close_file(file_baton, NULL, scratch_pool));
+ SVN_ERR(editor->close_file(file_baton, NULL, scratch_pool));
}
return SVN_NO_ERROR;
@@ -1740,7 +1742,7 @@ drive_changes(svn_branch__txn_priv_t *eb,
/* Apply the appropriate Ev1 change to each Ev1-relative path. */
paths = get_unsorted_paths(eb->changes, scratch_pool);
- SVN_ERR(svn_delta_path_driver2(eb->deditor, eb->dedit_baton,
+ SVN_ERR(svn_delta_path_driver3(eb->deditor, eb->dedit_baton,
paths, TRUE /*sort*/,
apply_change, (void *)eb,
scratch_pool));
diff --git a/subversion/libsvn_delta/compat.c b/subversion/libsvn_delta/compat.c
index c89e9367cd370..817e23eb18194 100644
--- a/subversion/libsvn_delta/compat.c
+++ b/subversion/libsvn_delta/compat.c
@@ -1577,6 +1577,8 @@ drive_ev1_props(const struct editor_baton *eb,
/* Conforms to svn_delta_path_driver_cb_func_t */
static svn_error_t *
apply_change(void **dir_baton,
+ const svn_delta_editor_t *deditor,
+ void *dedit_baton,
void *parent_baton,
void *callback_baton,
const char *ev1_relpath,
@@ -1614,8 +1616,8 @@ apply_change(void **dir_baton,
if (change->action == RESTRUCTURE_DELETE)
{
- SVN_ERR(eb->deditor->delete_entry(ev1_relpath, change->deleting,
- parent_baton, scratch_pool));
+ SVN_ERR(deditor->delete_entry(ev1_relpath, change->deleting,
+ parent_baton, scratch_pool));
/* No futher action possible for this node. */
return SVN_NO_ERROR;
@@ -1627,11 +1629,11 @@ apply_change(void **dir_baton,
if (change->action == RESTRUCTURE_ADD_ABSENT)
{
if (change->kind == svn_node_dir)
- SVN_ERR(eb->deditor->absent_directory(ev1_relpath, parent_baton,
- scratch_pool));
+ SVN_ERR(deditor->absent_directory(ev1_relpath, parent_baton,
+ scratch_pool));
else
- SVN_ERR(eb->deditor->absent_file(ev1_relpath, parent_baton,
- scratch_pool));
+ SVN_ERR(deditor->absent_file(ev1_relpath, parent_baton,
+ scratch_pool));
/* No further action possible for this node. */
return SVN_NO_ERROR;
@@ -1645,8 +1647,8 @@ apply_change(void **dir_baton,
/* Do we have an old node to delete first? */
if (SVN_IS_VALID_REVNUM(change->deleting))
- SVN_ERR(eb->deditor->delete_entry(ev1_relpath, change->deleting,
- parent_baton, scratch_pool));
+ SVN_ERR(deditor->delete_entry(ev1_relpath, change->deleting,
+ parent_baton, scratch_pool));
/* Are we copying the node from somewhere? */
if (change->copyfrom_path)
@@ -1669,24 +1671,24 @@ apply_change(void **dir_baton,
}
if (change->kind == svn_node_dir)
- SVN_ERR(eb->deditor->add_directory(ev1_relpath, parent_baton,
- copyfrom_url, copyfrom_rev,
- result_pool, dir_baton));
+ SVN_ERR(deditor->add_directory(ev1_relpath, parent_baton,
+ copyfrom_url, copyfrom_rev,
+ result_pool, dir_baton));
else
- SVN_ERR(eb->deditor->add_file(ev1_relpath, parent_baton,
- copyfrom_url, copyfrom_rev,
- result_pool, &file_baton));
+ SVN_ERR(deditor->add_file(ev1_relpath, parent_baton,
+ copyfrom_url, copyfrom_rev,
+ result_pool, &file_baton));
}
else
{
if (change->kind == svn_node_dir)
- SVN_ERR(eb->deditor->open_directory(ev1_relpath, parent_baton,
- change->changing,
- result_pool, dir_baton));
+ SVN_ERR(deditor->open_directory(ev1_relpath, parent_baton,
+ change->changing,
+ result_pool, dir_baton));
else
- SVN_ERR(eb->deditor->open_file(ev1_relpath, parent_baton,
- change->changing,
- result_pool, &file_baton));
+ SVN_ERR(deditor->open_file(ev1_relpath, parent_baton,
+ change->changing,
+ result_pool, &file_baton));
}
/* Apply any properties in CHANGE to the node. */
@@ -1703,8 +1705,8 @@ apply_change(void **dir_baton,
/* ### would be nice to have a BASE_CHECKSUM, but hey: this is the
### shim code... */
- SVN_ERR(eb->deditor->apply_textdelta(file_baton, NULL, scratch_pool,
- &handler, &handler_baton));
+ SVN_ERR(deditor->apply_textdelta(file_baton, NULL, scratch_pool,
+ &handler, &handler_baton));
SVN_ERR(svn_stream_open_readonly(&contents, change->contents_abspath,
scratch_pool, scratch_pool));
/* ### it would be nice to send a true txdelta here, but whatever. */
@@ -1718,7 +1720,7 @@ apply_change(void **dir_baton,
const char *digest = svn_checksum_to_cstring(change->checksum,
scratch_pool);
- SVN_ERR(eb->deditor->close_file(file_baton, digest, scratch_pool));
+ SVN_ERR(deditor->close_file(file_baton, digest, scratch_pool));
}
return SVN_NO_ERROR;
@@ -1747,7 +1749,7 @@ drive_changes(const struct editor_baton *eb,
/* Get a sorted list of Ev1-relative paths. */
paths = get_sorted_paths(eb->changes, eb->base_relpath, scratch_pool);
- SVN_ERR(svn_delta_path_driver2(eb->deditor, eb->dedit_baton, paths,
+ SVN_ERR(svn_delta_path_driver3(eb->deditor, eb->dedit_baton, paths,
FALSE, apply_change, (void *)eb,
scratch_pool));
diff --git a/subversion/libsvn_delta/debug_editor.c b/subversion/libsvn_delta/debug_editor.c
index 5f26936d621b1..c5dbc9b0321b5 100644
--- a/subversion/libsvn_delta/debug_editor.c
+++ b/subversion/libsvn_delta/debug_editor.c
@@ -71,9 +71,11 @@ set_target_revision(void *edit_baton,
SVN_ERR(svn_stream_printf(eb->out, pool, "set_target_revision : %ld\n",
target_revision));
- return eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton,
- target_revision,
- pool);
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton,
+ target_revision,
+ pool));
+ return SVN_NO_ERROR;
}
static svn_error_t *
@@ -90,10 +92,11 @@ open_root(void *edit_baton,
base_revision));
eb->indent_level++;
- SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton,
- base_revision,
- pool,
- &dir_baton->wrapped_dir_baton));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton,
+ base_revision,
+ pool,
+ &dir_baton->wrapped_dir_baton));
dir_baton->edit_baton = edit_baton;
@@ -115,10 +118,12 @@ delete_entry(const char *path,
SVN_ERR(svn_stream_printf(eb->out, pool, "delete_entry : %s:%ld\n",
path, base_revision));
- return eb->wrapped_editor->delete_entry(path,
- base_revision,
- pb->wrapped_dir_baton,
- pool);
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->delete_entry(path,
+ base_revision,
+ pb->wrapped_dir_baton,
+ pool));
+ return SVN_NO_ERROR;
}
static svn_error_t *
@@ -139,12 +144,13 @@ add_directory(const char *path,
path, copyfrom_path, copyfrom_revision));
eb->indent_level++;
- SVN_ERR(eb->wrapped_editor->add_directory(path,
- pb->wrapped_dir_baton,
- copyfrom_path,
- copyfrom_revision,
- pool,
- &b->wrapped_dir_baton));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->add_directory(path,
+ pb->wrapped_dir_baton,
+ copyfrom_path,
+ copyfrom_revision,
+ pool,
+ &b->wrapped_dir_baton));
b->edit_baton = eb;
*child_baton = b;
@@ -168,11 +174,12 @@ open_directory(const char *path,
path, base_revision));
eb->indent_level++;
- SVN_ERR(eb->wrapped_editor->open_directory(path,
- pb->wrapped_dir_baton,
- base_revision,
- pool,
- &db->wrapped_dir_baton));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->open_directory(path,
+ pb->wrapped_dir_baton,
+ base_revision,
+ pool,
+ &db->wrapped_dir_baton));
db->edit_baton = eb;
*child_baton = db;
@@ -199,12 +206,13 @@ add_file(const char *path,
eb->indent_level++;
- SVN_ERR(eb->wrapped_editor->add_file(path,
- pb->wrapped_dir_baton,
- copyfrom_path,
- copyfrom_revision,
- pool,
- &fb->wrapped_file_baton));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->add_file(path,
+ pb->wrapped_dir_baton,
+ copyfrom_path,
+ copyfrom_revision,
+ pool,
+ &fb->wrapped_file_baton));
fb->edit_baton = eb;
*file_baton = fb;
@@ -229,11 +237,12 @@ open_file(const char *path,
eb->indent_level++;
- SVN_ERR(eb->wrapped_editor->open_file(path,
- pb->wrapped_dir_baton,
- base_revision,
- pool,
- &fb->wrapped_file_baton));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->open_file(path,
+ pb->wrapped_dir_baton,
+ base_revision,
+ pool,
+ &fb->wrapped_file_baton));
fb->edit_baton = eb;
*file_baton = fb;
@@ -255,11 +264,38 @@ apply_textdelta(void *file_baton,
SVN_ERR(svn_stream_printf(eb->out, pool, "apply_textdelta : %s\n",
base_checksum));
- SVN_ERR(eb->wrapped_editor->apply_textdelta(fb->wrapped_file_baton,
- base_checksum,
- pool,
- handler,
- handler_baton));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->apply_textdelta(fb->wrapped_file_baton,
+ base_checksum,
+ pool,
+ handler,
+ handler_baton));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+apply_textdelta_stream(const struct svn_delta_editor_t *editor,
+ void *file_baton,
+ const char *base_checksum,
+ svn_txdelta_stream_open_func_t open_func,
+ void *open_baton,
+ apr_pool_t *scratch_pool)
+{
+ struct file_baton *fb = file_baton;
+ struct edit_baton *eb = fb->edit_baton;
+
+ SVN_ERR(write_indent(eb, scratch_pool));
+ SVN_ERR(svn_stream_printf(eb->out, scratch_pool,
+ "apply_textdelta_stream : %s\n",
+ base_checksum));
+
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->apply_textdelta_stream(eb->wrapped_editor,
+ fb->wrapped_file_baton,
+ base_checksum,
+ open_func, open_baton,
+ scratch_pool));
return SVN_NO_ERROR;
}
@@ -278,8 +314,9 @@ close_file(void *file_baton,
SVN_ERR(svn_stream_printf(eb->out, pool, "close_file : %s\n",
text_checksum));
- SVN_ERR(eb->wrapped_editor->close_file(fb->wrapped_file_baton,
- text_checksum, pool));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->close_file(fb->wrapped_file_baton,
+ text_checksum, pool));
return SVN_NO_ERROR;
}
@@ -295,8 +332,9 @@ absent_file(const char *path,
SVN_ERR(write_indent(eb, pool));
SVN_ERR(svn_stream_printf(eb->out, pool, "absent_file : %s\n", path));
- SVN_ERR(eb->wrapped_editor->absent_file(path, fb->wrapped_file_baton,
- pool));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->absent_file(path, fb->wrapped_file_baton,
+ pool));
return SVN_NO_ERROR;
}
@@ -312,8 +350,9 @@ close_directory(void *dir_baton,
SVN_ERR(write_indent(eb, pool));
SVN_ERR(svn_stream_printf(eb->out, pool, "close_directory\n"));
- SVN_ERR(eb->wrapped_editor->close_directory(db->wrapped_dir_baton,
- pool));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->close_directory(db->wrapped_dir_baton,
+ pool));
return SVN_NO_ERROR;
}
@@ -330,8 +369,9 @@ absent_directory(const char *path,
SVN_ERR(svn_stream_printf(eb->out, pool, "absent_directory : %s\n",
path));
- SVN_ERR(eb->wrapped_editor->absent_directory(path, db->wrapped_dir_baton,
- pool));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->absent_directory(path, db->wrapped_dir_baton,
+ pool));
return SVN_NO_ERROR;
}
@@ -349,10 +389,11 @@ change_file_prop(void *file_baton,
SVN_ERR(svn_stream_printf(eb->out, pool, "change_file_prop : %s -> %s\n",
name, value ? value->data : "<deleted>"));
- SVN_ERR(eb->wrapped_editor->change_file_prop(fb->wrapped_file_baton,
- name,
- value,
- pool));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->change_file_prop(fb->wrapped_file_baton,
+ name,
+ value,
+ pool));
return SVN_NO_ERROR;
}
@@ -370,10 +411,11 @@ change_dir_prop(void *dir_baton,
SVN_ERR(svn_stream_printf(eb->out, pool, "change_dir_prop : %s -> %s\n",
name, value ? value->data : "<deleted>"));
- SVN_ERR(eb->wrapped_editor->change_dir_prop(db->wrapped_dir_baton,
- name,
- value,
- pool));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->change_dir_prop(db->wrapped_dir_baton,
+ name,
+ value,
+ pool));
return SVN_NO_ERROR;
}
@@ -387,7 +429,8 @@ close_edit(void *edit_baton,
SVN_ERR(write_indent(eb, pool));
SVN_ERR(svn_stream_printf(eb->out, pool, "close_edit\n"));
- SVN_ERR(eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool));
return SVN_NO_ERROR;
}
@@ -401,7 +444,8 @@ abort_edit(void *edit_baton,
SVN_ERR(write_indent(eb, pool));
SVN_ERR(svn_stream_printf(eb->out, pool, "abort_edit\n"));
- SVN_ERR(eb->wrapped_editor->abort_edit(eb->wrapped_edit_baton, pool));
+ if (eb->wrapped_editor)
+ SVN_ERR(eb->wrapped_editor->abort_edit(eb->wrapped_edit_baton, pool));
return SVN_NO_ERROR;
}
@@ -414,7 +458,7 @@ svn_delta__get_debug_editor(const svn_delta_editor_t **editor,
const char *prefix,
apr_pool_t *pool)
{
- svn_delta_editor_t *tree_editor = apr_palloc(pool, sizeof(*tree_editor));
+ svn_delta_editor_t *tree_editor = svn_delta_default_editor(pool);
struct edit_baton *eb = apr_palloc(pool, sizeof(*eb));
apr_file_t *errfp;
svn_stream_t *out;
@@ -436,6 +480,7 @@ svn_delta__get_debug_editor(const svn_delta_editor_t **editor,
tree_editor->add_file = add_file;
tree_editor->open_file = open_file;
tree_editor->apply_textdelta = apply_textdelta;
+ tree_editor->apply_textdelta_stream = apply_textdelta_stream;
tree_editor->change_file_prop = change_file_prop;
tree_editor->close_file = close_file;
tree_editor->absent_file = absent_file;
diff --git a/subversion/libsvn_delta/deprecated.c b/subversion/libsvn_delta/deprecated.c
index 41712440baf48..f00c410cc6eca 100644
--- a/subversion/libsvn_delta/deprecated.c
+++ b/subversion/libsvn_delta/deprecated.c
@@ -30,6 +30,79 @@
#include "svn_sorts.h"
+struct path_driver_2_to_3_baton_t
+{
+ svn_delta_path_driver_cb_func_t callback_func;
+ void *callback_baton;
+ svn_boolean_t slash_prefix;
+};
+
+/* Convert from a newer to older callback
+ */
+static svn_error_t *
+path_driver_2_to_3_func(void **dir_baton,
+ const svn_delta_editor_t *editor,
+ void *edit_baton,
+ void *parent_baton,
+ void *callback_baton,
+ const char *path,
+ apr_pool_t *pool)
+{
+ struct path_driver_2_to_3_baton_t *b = callback_baton;
+
+ if (b->slash_prefix)
+ path = apr_pstrcat(pool, "/", path, SVN_VA_NULL);
+
+ /* Just drop the 'editor' parameters */
+ SVN_ERR(b->callback_func(dir_baton, parent_baton,
+ b->callback_baton,
+ path, pool));
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_delta_path_driver2(const svn_delta_editor_t *editor,
+ void *edit_baton,
+ const apr_array_header_t *paths,
+ svn_boolean_t sort_paths,
+ svn_delta_path_driver_cb_func_t callback_func,
+ void *callback_baton,
+ apr_pool_t *pool)
+{
+ struct path_driver_2_to_3_baton_t b;
+ int i;
+
+ b.callback_func = callback_func;
+ b.callback_baton = callback_baton;
+ b.slash_prefix = FALSE;
+
+ /* Remove any '/' prefix from incoming paths. Arrange to add a '/'
+ prefix to all paths for the callback, if any incoming path had one. */
+ for (i = 0; i < paths->nelts; i++)
+ {
+ const char *path = APR_ARRAY_IDX(paths, i, const char *);
+
+ if (path[0] == '/')
+ {
+ /* Re-allocate the array and note that we found a '/' prefix. */
+ if (!b.slash_prefix)
+ {
+ paths = apr_array_copy(pool, paths);
+ b.slash_prefix = TRUE;
+ }
+
+ /* Modify each array element that had a '/' prefix */
+ APR_ARRAY_IDX(paths, i, const char *) = path + 1;
+ }
+ }
+
+ SVN_ERR(svn_delta_path_driver3(editor, edit_baton,
+ paths, sort_paths,
+ path_driver_2_to_3_func, &b,
+ pool));
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_delta_path_driver(const svn_delta_editor_t *editor,
void *edit_baton,
diff --git a/subversion/libsvn_delta/element.c b/subversion/libsvn_delta/element.c
index be7b2171b9b46..798296412bb82 100644
--- a/subversion/libsvn_delta/element.c
+++ b/subversion/libsvn_delta/element.c
@@ -375,14 +375,12 @@ svn_element__tree_get(const svn_element__tree_t *tree,
return svn_eid__hash_get(tree->e_map, eid);
}
-svn_error_t *
+void
svn_element__tree_set(svn_element__tree_t *tree,
int eid,
const svn_element__content_t *element)
{
svn_eid__hash_set(tree->e_map, eid, element);
-
- return SVN_NO_ERROR;
}
void
diff --git a/subversion/libsvn_delta/libsvn_delta.pc.in b/subversion/libsvn_delta/libsvn_delta.pc.in
index b96e6ab3c282f..9759e74e21695 100644
--- a/subversion/libsvn_delta/libsvn_delta.pc.in
+++ b/subversion/libsvn_delta/libsvn_delta.pc.in
@@ -6,7 +6,7 @@ includedir=@includedir@
Name: libsvn_delta
Description: Subversion Delta Library
Version: @PACKAGE_VERSION@
-Requires: apr-util-@SVN_APR_MAJOR_VERSION@ apr-@SVN_APR_MAJOR_VERSION@
-Requires.private: libsvn_subr
-Libs: -L${libdir} -lsvn_delta @SVN_ZLIB_LIBS@
-Cflags: -I${includedir}
+Requires: apr-util-@SVN_APR_MAJOR_VERSION@, apr-@SVN_APR_MAJOR_VERSION@
+Requires.private: libsvn_subr
+Libs: -L${libdir} -lsvn_delta-1 @SVN_ZLIB_LIBS@
+Cflags: -I${includedir}/subversion-1
diff --git a/subversion/libsvn_delta/path_driver.c b/subversion/libsvn_delta/path_driver.c
index c1f3e07b818a7..5840cc7f29099 100644
--- a/subversion/libsvn_delta/path_driver.c
+++ b/subversion/libsvn_delta/path_driver.c
@@ -31,7 +31,6 @@
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_sorts.h"
-#include "private/svn_fspath.h"
#include "private/svn_sorts_private.h"
@@ -45,6 +44,22 @@ typedef struct dir_stack_t
} dir_stack_t;
+/* Push onto dir_stack a new item allocated in POOL and containing
+ * DIR_BATON and POOL.
+ */
+static void
+push_dir_stack_item(apr_array_header_t *db_stack,
+ void *dir_baton,
+ apr_pool_t *pool)
+{
+ dir_stack_t *item = apr_pcalloc(pool, sizeof(*item));
+
+ item->dir_baton = dir_baton;
+ item->pool = pool;
+ APR_ARRAY_PUSH(db_stack, dir_stack_t *) = item;
+}
+
+
/* Call EDITOR's open_directory() function with the PATH argument, then
* add the resulting dir baton to the dir baton stack.
*/
@@ -72,10 +87,7 @@ open_dir(apr_array_header_t *db_stack,
&db));
/* Now add the dir baton to the stack. */
- item = apr_pcalloc(subpool, sizeof(*item));
- item->dir_baton = db;
- item->pool = subpool;
- APR_ARRAY_PUSH(db_stack, dir_stack_t *) = item;
+ push_dir_stack_item(db_stack, db, subpool);
return SVN_NO_ERROR;
}
@@ -131,168 +143,215 @@ count_components(const char *path)
/*** Public interfaces ***/
svn_error_t *
-svn_delta_path_driver2(const svn_delta_editor_t *editor,
+svn_delta_path_driver3(const svn_delta_editor_t *editor,
void *edit_baton,
- const apr_array_header_t *paths,
+ const apr_array_header_t *relpaths,
svn_boolean_t sort_paths,
- svn_delta_path_driver_cb_func_t callback_func,
+ svn_delta_path_driver_cb_func2_t callback_func,
void *callback_baton,
apr_pool_t *pool)
{
- apr_array_header_t *db_stack = apr_array_make(pool, 4, sizeof(void *));
- const char *last_path = NULL;
- int i = 0;
- void *parent_db = NULL, *db = NULL;
- const char *path;
+ svn_delta_path_driver_state_t *state;
+ int i;
apr_pool_t *subpool, *iterpool;
- dir_stack_t *item;
/* Do nothing if there are no paths. */
- if (! paths->nelts)
+ if (! relpaths->nelts)
return SVN_NO_ERROR;
subpool = svn_pool_create(pool);
iterpool = svn_pool_create(pool);
/* sort paths if necessary */
- if (sort_paths && paths->nelts > 1)
+ if (sort_paths && relpaths->nelts > 1)
{
- apr_array_header_t *sorted = apr_array_copy(subpool, paths);
+ apr_array_header_t *sorted = apr_array_copy(subpool, relpaths);
svn_sort__array(sorted, svn_sort_compare_paths);
- paths = sorted;
+ relpaths = sorted;
}
- item = apr_pcalloc(subpool, sizeof(*item));
-
- /* If the root of the edit is also a target path, we want to call
- the callback function to let the user open the root directory and
- do what needs to be done. Otherwise, we'll do the open_root()
- ourselves. */
- path = APR_ARRAY_IDX(paths, 0, const char *);
- if (svn_path_is_empty(path))
- {
- SVN_ERR(callback_func(&db, NULL, callback_baton, path, subpool));
- last_path = path;
- i++;
- }
- else
- {
- SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM, subpool, &db));
- }
- item->pool = subpool;
- item->dir_baton = db;
- APR_ARRAY_PUSH(db_stack, void *) = item;
+ SVN_ERR(svn_delta_path_driver_start(&state,
+ editor, edit_baton,
+ callback_func, callback_baton,
+ pool));
/* Now, loop over the commit items, traversing the URL tree and
driving the editor. */
- for (; i < paths->nelts; i++)
+ for (i = 0; i < relpaths->nelts; i++)
{
- const char *pdir;
- const char *common = "";
- size_t common_len;
+ const char *relpath;
/* Clear the iteration pool. */
svn_pool_clear(iterpool);
/* Get the next path. */
- path = APR_ARRAY_IDX(paths, i, const char *);
-
- /*** Step A - Find the common ancestor of the last path and the
- current one. For the first iteration, this is just the
- empty string. ***/
- if (i > 0)
- common = (last_path[0] == '/')
- ? svn_fspath__get_longest_ancestor(last_path, path, iterpool)
- : svn_relpath_get_longest_ancestor(last_path, path, iterpool);
- common_len = strlen(common);
-
- /*** Step B - Close any directories between the last path and
- the new common ancestor, if any need to be closed.
- Sometimes there is nothing to do here (like, for the first
- iteration, or when the last path was an ancestor of the
- current one). ***/
- if ((i > 0) && (strlen(last_path) > common_len))
- {
- const char *rel = last_path + (common_len ? (common_len + 1) : 0);
- int count = count_components(rel);
- while (count--)
- {
- SVN_ERR(pop_stack(db_stack, editor));
- }
- }
+ relpath = APR_ARRAY_IDX(relpaths, i, const char *);
- /*** Step C - Open any directories between the common ancestor
- and the parent of the current path. ***/
- if (*path == '/')
- pdir = svn_fspath__dirname(path, iterpool);
- else
- pdir = svn_relpath_dirname(path, iterpool);
+ SVN_ERR(svn_delta_path_driver_step(state, relpath, iterpool));
+ }
- if (strlen(pdir) > common_len)
- {
- const char *piece = pdir + common_len + 1;
-
- while (1)
- {
- const char *rel = pdir;
-
- /* Find the first separator. */
- piece = strchr(piece, '/');
-
- /* Calculate REL as the portion of PDIR up to (but not
- including) the location to which PIECE is pointing. */
- if (piece)
- rel = apr_pstrmemdup(iterpool, pdir, piece - pdir);
-
- /* Open the subdirectory. */
- SVN_ERR(open_dir(db_stack, editor, rel, pool));
-
- /* If we found a '/', advance our PIECE pointer to
- character just after that '/'. Otherwise, we're
- done. */
- if (piece)
- piece++;
- else
- break;
- }
- }
+ /* Destroy the iteration subpool. */
+ svn_pool_destroy(iterpool);
- /*** Step D - Tell our caller to handle the current path. ***/
- item = APR_ARRAY_IDX(db_stack, db_stack->nelts - 1, void *);
- parent_db = item->dir_baton;
- subpool = svn_pool_create(pool);
- SVN_ERR(callback_func(&db, parent_db, callback_baton, path, subpool));
- if (db)
+ SVN_ERR(svn_delta_path_driver_finish(state, pool));
+
+ return SVN_NO_ERROR;
+}
+
+struct svn_delta_path_driver_state_t
+{
+ const svn_delta_editor_t *editor;
+ void *edit_baton;
+ svn_delta_path_driver_cb_func2_t callback_func;
+ void *callback_baton;
+ apr_array_header_t *db_stack;
+ const char *last_path;
+ apr_pool_t *pool; /* at least the lifetime of the entire drive */
+};
+
+svn_error_t *
+svn_delta_path_driver_start(svn_delta_path_driver_state_t **state_p,
+ const svn_delta_editor_t *editor,
+ void *edit_baton,
+ svn_delta_path_driver_cb_func2_t callback_func,
+ void *callback_baton,
+ apr_pool_t *pool)
+{
+ svn_delta_path_driver_state_t *state = apr_pcalloc(pool, sizeof(*state));
+
+ state->editor = editor;
+ state->edit_baton = edit_baton;
+ state->callback_func = callback_func;
+ state->callback_baton = callback_baton;
+ state->db_stack = apr_array_make(pool, 4, sizeof(void *));
+ state->last_path = NULL;
+ state->pool = pool;
+
+ *state_p = state;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_delta_path_driver_step(svn_delta_path_driver_state_t *state,
+ const char *relpath,
+ apr_pool_t *scratch_pool)
+{
+ const char *pdir;
+ const char *common = "";
+ size_t common_len;
+ apr_pool_t *subpool;
+ dir_stack_t *item;
+ void *parent_db, *db;
+
+ SVN_ERR_ASSERT(svn_relpath_is_canonical(relpath));
+
+ /* If the first target path is not the root of the edit, we must first
+ call open_root() ourselves. (If the first target path is the root of
+ the edit, then we expect the user's callback to do so.) */
+ if (!state->last_path && !svn_path_is_empty(relpath))
+ {
+ subpool = svn_pool_create(state->pool);
+ SVN_ERR(state->editor->open_root(state->edit_baton, SVN_INVALID_REVNUM,
+ subpool, &db));
+ push_dir_stack_item(state->db_stack, db, subpool);
+ }
+
+ /*** Step A - Find the common ancestor of the last path and the
+ current one. For the first iteration, this is just the
+ empty string. ***/
+ if (state->last_path)
+ common = svn_relpath_get_longest_ancestor(state->last_path, relpath,
+ scratch_pool);
+ common_len = strlen(common);
+
+ /*** Step B - Close any directories between the last path and
+ the new common ancestor, if any need to be closed.
+ Sometimes there is nothing to do here (like, for the first
+ iteration, or when the last path was an ancestor of the
+ current one). ***/
+ if ((state->last_path) && (strlen(state->last_path) > common_len))
+ {
+ const char *rel = state->last_path + (common_len ? (common_len + 1) : 0);
+ int count = count_components(rel);
+ while (count--)
{
- item = apr_pcalloc(subpool, sizeof(*item));
- item->dir_baton = db;
- item->pool = subpool;
- APR_ARRAY_PUSH(db_stack, void *) = item;
+ SVN_ERR(pop_stack(state->db_stack, state->editor));
}
- else
+ }
+
+ /*** Step C - Open any directories between the common ancestor
+ and the parent of the current path. ***/
+ pdir = svn_relpath_dirname(relpath, scratch_pool);
+
+ if (strlen(pdir) > common_len)
+ {
+ const char *piece = pdir + common_len + 1;
+
+ while (1)
{
- svn_pool_destroy(subpool);
+ const char *rel = pdir;
+
+ /* Find the first separator. */
+ piece = strchr(piece, '/');
+
+ /* Calculate REL as the portion of PDIR up to (but not
+ including) the location to which PIECE is pointing. */
+ if (piece)
+ rel = apr_pstrmemdup(scratch_pool, pdir, piece - pdir);
+
+ /* Open the subdirectory. */
+ SVN_ERR(open_dir(state->db_stack, state->editor, rel, state->pool));
+
+ /* If we found a '/', advance our PIECE pointer to
+ character just after that '/'. Otherwise, we're
+ done. */
+ if (piece)
+ piece++;
+ else
+ break;
}
+ }
- /*** Step E - Save our state for the next iteration. If our
- caller opened or added PATH as a directory, that becomes
- our LAST_PATH. Otherwise, we use PATH's parent
- directory. ***/
-
- /* NOTE: The variable LAST_PATH needs to outlive the loop. */
- if (db)
- last_path = path; /* lives in a pool outside our control. */
- else
- last_path = apr_pstrdup(pool, pdir); /* duping into POOL. */
+ /*** Step D - Tell our caller to handle the current path. ***/
+ if (state->db_stack->nelts)
+ {
+ item = APR_ARRAY_IDX(state->db_stack, state->db_stack->nelts - 1, void *);
+ parent_db = item->dir_baton;
+ }
+ else
+ parent_db = NULL;
+ db = NULL; /* predictable behaviour for callbacks that don't set it */
+ subpool = svn_pool_create(state->pool);
+ SVN_ERR(state->callback_func(&db,
+ state->editor, state->edit_baton, parent_db,
+ state->callback_baton,
+ relpath, subpool));
+ if (db)
+ {
+ push_dir_stack_item(state->db_stack, db, subpool);
+ }
+ else
+ {
+ svn_pool_destroy(subpool);
}
- /* Destroy the iteration subpool. */
- svn_pool_destroy(iterpool);
+ /*** Step E - Save our state for the next iteration. If our
+ caller opened or added PATH as a directory, that becomes
+ our LAST_PATH. Otherwise, we use PATH's parent
+ directory. ***/
+ state->last_path = apr_pstrdup(state->pool, db ? relpath : pdir);
+
+ return SVN_NO_ERROR;
+}
+svn_error_t *
+svn_delta_path_driver_finish(svn_delta_path_driver_state_t *state,
+ apr_pool_t *scratch_pool)
+{
/* Close down any remaining open directory batons. */
- while (db_stack->nelts)
+ while (state->db_stack->nelts)
{
- SVN_ERR(pop_stack(db_stack, editor));
+ SVN_ERR(pop_stack(state->db_stack, state->editor));
}
return SVN_NO_ERROR;