Modified: subversion/branches/addremove/subversion/libsvn_delta/branch_compat.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/branch_compat.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_delta/branch_compat.c (original) +++ subversion/branches/addremove/subversion/libsvn_delta/branch_compat.c Sat May 23 14:16:56 2020 @@ -875,6 +875,8 @@ drive_ev1_props(const char *repos_relpat */ 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,10 +915,10 @@ 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. */ + /* No further 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));
Modified: subversion/branches/addremove/subversion/libsvn_delta/compat.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/compat.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_delta/compat.c (original) +++ subversion/branches/addremove/subversion/libsvn_delta/compat.c Sat May 23 14:16:56 2020 @@ -108,7 +108,7 @@ svn_compat_wrap_file_rev_handler(svn_fil * deletion has side effects (unlike deleting a non-existent regular property * would). To solve this, we introduce *another* function into the API, not * a part of the Ev2 callbacks, but a companion which is used to register - * the unlock of a path. See ev2_change_file_prop() for implemenation + * the unlock of a path. See ev2_change_file_prop() for implementation * details. */ @@ -467,7 +467,7 @@ run_ev2_actions(struct ev2_edit_baton *e iterpool = svn_pool_create(scratch_pool); - /* Possibly pick up where we left off. Ocassionally, we do some of these + /* Possibly pick up where we left off. Occasionally, we do some of these as part of close_edit() and then some more as part of abort_edit() */ for (; eb->paths_processed < eb->path_order->nelts; ++eb->paths_processed) { @@ -877,7 +877,7 @@ ev2_change_file_prop(void *file_baton, if (!strcmp(name, SVN_PROP_ENTRY_LOCK_TOKEN) && value == NULL) { - /* We special case the lock token propery deletion, which is the + /* We special case the lock token property deletion, which is the server's way of telling the client to unlock the path. */ /* ### this duplicates much of apply_propedit(). fix in future. */ @@ -1577,6 +1577,8 @@ drive_ev1_props(const struct editor_bato /* 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,10 +1616,10 @@ 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. */ + /* No further 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 /* 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)); Modified: subversion/branches/addremove/subversion/libsvn_delta/compose_delta.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/compose_delta.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_delta/compose_delta.c (original) +++ subversion/branches/addremove/subversion/libsvn_delta/compose_delta.c Sat May 23 14:16:56 2020 @@ -128,7 +128,7 @@ free_block(void *ptr, alloc_block_t **fr /* ==================================================================== */ -/* Mapping offsets in the target streem to txdelta ops. */ +/* Mapping offsets in the target stream to txdelta ops. */ typedef struct offset_index_t { Modified: subversion/branches/addremove/subversion/libsvn_delta/debug_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/debug_editor.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_delta/debug_editor.c (original) +++ subversion/branches/addremove/subversion/libsvn_delta/debug_editor.c Sat May 23 14:16:56 2020 @@ -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_de 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_de 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; Modified: subversion/branches/addremove/subversion/libsvn_delta/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/deprecated.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_delta/deprecated.c (original) +++ subversion/branches/addremove/subversion/libsvn_delta/deprecated.c Sat May 23 14:16:56 2020 @@ -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, Modified: subversion/branches/addremove/subversion/libsvn_delta/element.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/element.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_delta/element.c (original) +++ subversion/branches/addremove/subversion/libsvn_delta/element.c Sat May 23 14:16:56 2020 @@ -375,14 +375,12 @@ svn_element__tree_get(const svn_element_ 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 Modified: subversion/branches/addremove/subversion/libsvn_delta/path_driver.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/path_driver.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_delta/path_driver.c (original) +++ subversion/branches/addremove/subversion/libsvn_delta/path_driver.c Sat May 23 14:16:56 2020 @@ -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 *); + relpath = APR_ARRAY_IDX(relpaths, 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)); - } - } + SVN_ERR(svn_delta_path_driver_step(state, relpath, iterpool)); + } - /*** 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); + /* Destroy the iteration subpool. */ + svn_pool_destroy(iterpool); - if (strlen(pdir) > common_len) - { - const char *piece = pdir + common_len + 1; + SVN_ERR(svn_delta_path_driver_finish(state, pool)); - 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; - } - } + return SVN_NO_ERROR; +} - /*** 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) +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; Modified: subversion/branches/addremove/subversion/libsvn_delta/svndiff.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/svndiff.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_delta/svndiff.c (original) +++ subversion/branches/addremove/subversion/libsvn_delta/svndiff.c Sat May 23 14:16:56 2020 @@ -396,7 +396,7 @@ struct decode_baton }; -/* Wrapper aroung svn__deencode_uint taking a file size as *VAL. */ +/* Wrapper around svn__deencode_uint taking a file size as *VAL. */ static const unsigned char * decode_file_offset(svn_filesize_t *val, const unsigned char *p, @@ -1026,11 +1026,11 @@ svndiff_stream_read_fn(void *baton, char apr_size_t left = *len; apr_size_t read = 0; - while (left && !b->hit_eof) + while (left) { apr_size_t chunk_size; - if (b->read_pos == b->window_buffer->len) + if (b->read_pos == b->window_buffer->len && !b->hit_eof) { svn_txdelta_window_t *window; @@ -1050,6 +1050,9 @@ svndiff_stream_read_fn(void *baton, char else chunk_size = left; + if (!chunk_size) + break; + memcpy(buffer, b->window_buffer->data + b->read_pos, chunk_size); b->read_pos += chunk_size; buffer += chunk_size; Modified: subversion/branches/addremove/subversion/libsvn_delta/xdelta.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_delta/xdelta.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_delta/xdelta.c (original) +++ subversion/branches/addremove/subversion/libsvn_delta/xdelta.c Sat May 23 14:16:56 2020 @@ -124,7 +124,7 @@ struct blocks This value has an upper bound proportionate to the text delta window size, so unless we dramatically increase the window size, it's safe to make this a 32-bit value. In any case, it has to be - hte same width as the block position index, (struct + the same width as the block position index, (struct block).pos. */ apr_uint32_t max; Modified: subversion/branches/addremove/subversion/libsvn_diff/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_diff/deprecated.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_diff/deprecated.c (original) +++ subversion/branches/addremove/subversion/libsvn_diff/deprecated.c Sat May 23 14:16:56 2020 @@ -409,7 +409,7 @@ svn_diff_mem_string_output_merge2(svn_st conflict_latest, conflict_separator, style, - /* no cancelation */ + /* no cancellation */ NULL, NULL, pool)); } Modified: subversion/branches/addremove/subversion/libsvn_diff/diff_file.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_diff/diff_file.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_diff/diff_file.c (original) +++ subversion/branches/addremove/subversion/libsvn_diff/diff_file.c Sat May 23 14:16:56 2020 @@ -1095,7 +1095,7 @@ token_compare(void *baton, void *token1, if (length[i] == 0) { /* Error if raw_length is 0, that's an unexpected change - * of the file that can happen when ingoring whitespace + * of the file that can happen when ignoring whitespace * and that can lead to an infinite loop. */ if (raw_length[i] == 0) return svn_error_createf(SVN_ERR_DIFF_DATASOURCE_MODIFIED, @@ -1253,7 +1253,7 @@ svn_diff_file_options_parse(svn_diff_fil apr_array_cat(argv, args); APR_ARRAY_PUSH(argv, const char *) = NULL; - apr_getopt_init(&os, pool, + apr_getopt_init(&os, pool, argv->nelts - 1 /* Exclude trailing NULL */, (const char *const *) argv->elts); Modified: subversion/branches/addremove/subversion/libsvn_diff/diff_tree.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_diff/diff_tree.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_diff/diff_tree.c (original) +++ subversion/branches/addremove/subversion/libsvn_diff/diff_tree.c Sat May 23 14:16:56 2020 @@ -37,14 +37,6 @@ #include "private/svn_diff_tree.h" #include "svn_private_config.h" -typedef struct tree_processor_t -{ - svn_diff_tree_processor_t tp; - - /* void *future_extension */ -} tree_processor_t; - - static svn_error_t * default_dir_opened(void **new_dir_baton, svn_boolean_t *skip, @@ -215,33 +207,30 @@ svn_diff_tree_processor_t * svn_diff__tree_processor_create(void *baton, apr_pool_t *result_pool) { - tree_processor_t *wrapper; - wrapper = apr_pcalloc(result_pool, sizeof(*wrapper)); + svn_diff_tree_processor_t *tp = apr_pcalloc(result_pool, sizeof(*tp)); - wrapper->tp.baton = baton; + tp->baton = baton; - wrapper->tp.dir_opened = default_dir_opened; - wrapper->tp.dir_added = default_dir_added; - wrapper->tp.dir_deleted = default_dir_deleted; - wrapper->tp.dir_changed = default_dir_changed; - wrapper->tp.dir_closed = default_dir_closed; + tp->dir_opened = default_dir_opened; + tp->dir_added = default_dir_added; + tp->dir_deleted = default_dir_deleted; + tp->dir_changed = default_dir_changed; + tp->dir_closed = default_dir_closed; - wrapper->tp.file_opened = default_file_opened; - wrapper->tp.file_added = default_file_added; - wrapper->tp.file_deleted = default_file_deleted; - wrapper->tp.file_changed = default_file_changed; - wrapper->tp.file_closed = default_file_closed; + tp->file_opened = default_file_opened; + tp->file_added = default_file_added; + tp->file_deleted = default_file_deleted; + tp->file_changed = default_file_changed; + tp->file_closed = default_file_closed; - wrapper->tp.node_absent = default_node_absent; + tp->node_absent = default_node_absent; - - return &wrapper->tp; + return tp; } struct reverse_tree_baton_t { const svn_diff_tree_processor_t *processor; - const char *prefix_relpath; }; static svn_error_t * @@ -259,9 +248,6 @@ reverse_dir_opened(void **new_dir_baton, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->dir_opened(new_dir_baton, skip, skip_children, relpath, right_source, left_source, @@ -284,9 +270,6 @@ reverse_dir_added(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->dir_deleted(relpath, right_source, right_props, @@ -307,9 +290,6 @@ reverse_dir_deleted(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->dir_added(relpath, NULL, left_source, @@ -335,9 +315,6 @@ reverse_dir_changed(const char *relpath, struct reverse_tree_baton_t *rb = processor->baton; apr_array_header_t *reversed_prop_changes = NULL; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - if (prop_changes) { SVN_ERR_ASSERT(left_props != NULL && right_props != NULL); @@ -367,9 +344,6 @@ reverse_dir_closed(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->dir_closed(relpath, right_source, left_source, @@ -393,9 +367,6 @@ reverse_file_opened(void **new_file_bato { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->file_opened(new_file_baton, skip, relpath, @@ -423,9 +394,6 @@ reverse_file_added(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->file_deleted(relpath, right_source, right_file, @@ -447,9 +415,6 @@ reverse_file_deleted(const char *relpath { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->file_added(relpath, NULL /* copyfrom src */, left_source, @@ -480,9 +445,6 @@ reverse_file_changed(const char *relpath struct reverse_tree_baton_t *rb = processor->baton; apr_array_header_t *reversed_prop_changes = NULL; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - if (prop_changes) { SVN_ERR_ASSERT(left_props != NULL && right_props != NULL); @@ -515,9 +477,6 @@ reverse_file_closed(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->file_closed(relpath, right_source, left_source, @@ -536,9 +495,6 @@ reverse_node_absent(const char *relpath, { struct reverse_tree_baton_t *rb = processor->baton; - if (rb->prefix_relpath) - relpath = svn_relpath_join(rb->prefix_relpath, relpath, scratch_pool); - SVN_ERR(rb->processor->node_absent(relpath, dir_baton, rb->processor, @@ -549,7 +505,6 @@ reverse_node_absent(const char *relpath, const svn_diff_tree_processor_t * svn_diff__tree_processor_reverse_create(const svn_diff_tree_processor_t * processor, - const char *prefix_relpath, apr_pool_t *result_pool) { struct reverse_tree_baton_t *rb; @@ -557,8 +512,6 @@ svn_diff__tree_processor_reverse_create( rb = apr_pcalloc(result_pool, sizeof(*rb)); rb->processor = processor; - if (prefix_relpath) - rb->prefix_relpath = apr_pstrdup(result_pool, prefix_relpath); reverse = svn_diff__tree_processor_create(rb, result_pool); Modified: subversion/branches/addremove/subversion/libsvn_diff/parse-diff.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_diff/parse-diff.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_diff/parse-diff.c (original) +++ subversion/branches/addremove/subversion/libsvn_diff/parse-diff.c Sat May 23 14:16:56 2020 @@ -69,6 +69,11 @@ struct svn_diff_hunk_t { /* APR file handle to the patch file this hunk came from. */ apr_file_t *apr_file; + /* Whether the hunk was interpreted as pretty-print mergeinfo. If so, + the hunk content is in PATCH and the rest of this hunk object is + mostly uninitialized. */ + svn_boolean_t is_pretty_print_mergeinfo; + /* Ranges used to keep track of this hunk's texts positions within * the patch file. */ struct svn_diff__hunk_range diff_text_range; @@ -210,7 +215,7 @@ svn_diff_hunk__create_adds_single_line(s apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - SVN_ERR(add_or_delete_single_line(hunk_out, line, patch, + SVN_ERR(add_or_delete_single_line(hunk_out, line, patch, (!patch->reverse), result_pool, scratch_pool)); return SVN_NO_ERROR; @@ -899,10 +904,6 @@ parse_prop_name(const char **prop_name, * The hunk header has the following format: * ## -0,NUMBER_OF_REVERSE_MERGES +0,NUMBER_OF_FORWARD_MERGES ## * - * At this point, the number of reverse merges has already been - * parsed into HUNK->ORIGINAL_LENGTH, and the number of forward - * merges has been parsed into HUNK->MODIFIED_LENGTH. - * * The header is followed by a list of mergeinfo, one path per line. * This function parses such lines. Lines describing reverse merges * appear first, and then all lines describing forward merges appear. @@ -914,18 +915,27 @@ parse_prop_name(const char **prop_name, * ":r", which in turn is followed by a mergeinfo revision range, * which is terminated by whitespace or end-of-string. * - * If the current line meets the above criteria and we're able - * to parse valid mergeinfo from it, the resulting mergeinfo - * is added to patch->mergeinfo or patch->reverse_mergeinfo, - * and we proceed to the next line. + * *NUMBER_OF_REVERSE_MERGES and *NUMBER_OF_FORWARD_MERGES are the + * numbers of reverse and forward merges remaining to be read. This + * function decrements *NUMBER_OF_REVERSE_MERGES for each LINE + * parsed until that is zero, then *NUMBER_OF_FORWARD_MERGES for + * each LINE parsed until that is zero. If both are zero, it parses + * and discards LINE. + * + * If LINE is successfully parsed, *FOUND_MERGEINFO is set to TRUE, + * otherwise to FALSE. + * + * If LINE is successfully parsed and counted, the resulting mergeinfo + * is added to PATCH->mergeinfo or PATCH->reverse_mergeinfo. */ static svn_error_t * -parse_mergeinfo(svn_boolean_t *found_mergeinfo, - svn_stringbuf_t *line, - svn_diff_hunk_t *hunk, - svn_patch_t *patch, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +parse_pretty_mergeinfo_line(svn_boolean_t *found_mergeinfo, + svn_linenum_t *number_of_reverse_merges, + svn_linenum_t *number_of_forward_merges, + svn_stringbuf_t *line, + svn_patch_t *patch, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { char *slash = strchr(line->data, '/'); char *colon = strrchr(line->data, ':'); @@ -972,7 +982,7 @@ parse_mergeinfo(svn_boolean_t *found_mer if (mergeinfo) { - if (hunk->original_length > 0) /* reverse merges */ + if (*number_of_reverse_merges > 0) /* reverse merges */ { if (patch->reverse) { @@ -994,9 +1004,9 @@ parse_mergeinfo(svn_boolean_t *found_mer result_pool, scratch_pool)); } - hunk->original_length--; + (*number_of_reverse_merges)--; } - else if (hunk->modified_length > 0) /* forward merges */ + else if (number_of_forward_merges > 0) /* forward merges */ { if (patch->reverse) { @@ -1018,7 +1028,7 @@ parse_mergeinfo(svn_boolean_t *found_mer result_pool, scratch_pool)); } - hunk->modified_length--; + (*number_of_forward_merges)--; } *found_mergeinfo = TRUE; @@ -1165,18 +1175,48 @@ parse_next_hunk(svn_diff_hunk_t **hunk, if (in_hunk && *is_property && *prop_name && strcmp(*prop_name, SVN_PROP_MERGEINFO) == 0) { - svn_boolean_t found_mergeinfo; + svn_boolean_t found_pretty_mergeinfo_line; - SVN_ERR(parse_mergeinfo(&found_mergeinfo, line, *hunk, patch, - result_pool, iterpool)); - if (found_mergeinfo) - continue; /* Proceed to the next line in the svn:mergeinfo hunk. */ - else + if (! hunk_seen) { - /* Perhaps we can also use original_lines/modified_lines here */ + /* We're reading the first line of the hunk, so the start + * of the line just read is the hunk text's byte offset. */ + start = last_line; + } - in_hunk = FALSE; /* On to next property */ + SVN_ERR(parse_pretty_mergeinfo_line(&found_pretty_mergeinfo_line, + &original_lines, &modified_lines, + line, patch, + result_pool, iterpool)); + if (found_pretty_mergeinfo_line) + { + hunk_seen = TRUE; + (*hunk)->is_pretty_print_mergeinfo = TRUE; + continue; /* Proceed to the next line in the svn:mergeinfo hunk. */ } + + if ((*hunk)->is_pretty_print_mergeinfo) + { + /* We have reached the end of the pretty-print-mergeinfo hunk. + (This format uses only one hunk.) */ + if (eof) + { + /* The hunk ends at EOF. */ + end = pos; + } + else + { + /* The start of the current line marks the first byte + * after the hunk text. */ + end = last_line; + } + original_end = end; + modified_end = end; + break; + } + + /* Otherwise, this is a property diff in the + regular format so fall through to normal processing. */ } if (in_hunk) @@ -1195,7 +1235,7 @@ parse_next_hunk(svn_diff_hunk_t **hunk, c = line->data[0]; if (c == ' ' || ((original_lines > 0 && modified_lines > 0) - && ( + && ( /* Tolerate chopped leading spaces on empty lines. */ (! eof && line->len == 0) /* Maybe tolerate chopped leading spaces on non-empty lines. */ @@ -1971,10 +2011,10 @@ parse_hunks(svn_patch_t *patch, apr_file else last_prop_name = prop_name; - /* Skip svn:mergeinfo properties. - * Mergeinfo data cannot be represented as a hunk and + /* Skip pretty-printed svn:mergeinfo property hunks. + * Pretty-printed mergeinfo data cannot be represented as a hunk and * is therefore stored in PATCH itself. */ - if (strcmp(prop_name, SVN_PROP_MERGEINFO) == 0) + if (hunk->is_pretty_print_mergeinfo) continue; SVN_ERR(add_property_hunk(patch, prop_name, hunk, prop_operation, @@ -2045,7 +2085,7 @@ parse_binary_patch(svn_patch_t *patch, a else if (in_src) { patch->binary_patch = bpatch; /* SUCCESS! */ - break; + break; } else { Modified: subversion/branches/addremove/subversion/libsvn_fs/fs-loader.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs/fs-loader.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs/fs-loader.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs/fs-loader.c Sat May 23 14:16:56 2020 @@ -438,7 +438,7 @@ svn_fs_initialize(apr_pool_t *pool) static void default_warning_func(void *baton, svn_error_t *err) { - /* The one unforgiveable sin is to fail silently. Dumping to stderr + /* The one unforgivable sin is to fail silently. Dumping to stderr or /dev/tty is not acceptable default behavior for server processes, since those may both be equivalent to /dev/null. @@ -2221,3 +2221,42 @@ svn_fs_info_dup(const void *info_void, return apr_pmemdup(result_pool, info, sizeof(*info)); } +svn_error_t * +svn_fs_ioctl(svn_fs_t *fs, + svn_fs_ioctl_code_t ctlcode, + void *input, + void **output_p, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + void *output; + + if (fs) + { + if (!fs->vtable->ioctl) + return svn_error_create(SVN_ERR_FS_UNRECOGNIZED_IOCTL_CODE, NULL, NULL); + + SVN_ERR(fs->vtable->ioctl(fs, ctlcode, input, &output, + cancel_func, cancel_baton, + result_pool, scratch_pool)); + } + else + { + fs_library_vtable_t *vtable; + + SVN_ERR(get_library_vtable(&vtable, ctlcode.fs_type, scratch_pool)); + + if (!vtable->ioctl) + return svn_error_create(SVN_ERR_FS_UNRECOGNIZED_IOCTL_CODE, NULL, NULL); + + SVN_ERR(vtable->ioctl(ctlcode, input, &output, + cancel_func, cancel_baton, + result_pool, scratch_pool)); + } + + if (output_p) + *output_p = output; + return SVN_NO_ERROR; +} Modified: subversion/branches/addremove/subversion/libsvn_fs/fs-loader.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs/fs-loader.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs/fs-loader.h (original) +++ subversion/branches/addremove/subversion/libsvn_fs/fs-loader.h Sat May 23 14:16:56 2020 @@ -159,6 +159,13 @@ typedef struct fs_library_vtable_t /* For svn_fs_info_fsfs_dup(). */ void *(*info_fsap_dup)(const void *fsap_info, apr_pool_t *result_pool); + + svn_error_t *(*ioctl)(svn_fs_ioctl_code_t ctlcode, + void *input, void **output_p, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); } fs_library_vtable_t; /* This is the type of symbol an FS module defines to fetch the @@ -200,12 +207,12 @@ typedef struct fs_vtable_t svn_error_t *(*revision_prop)(svn_string_t **value_p, svn_fs_t *fs, svn_revnum_t rev, const char *propname, svn_boolean_t refresh, - apr_pool_t *result_pool, + apr_pool_t *result_pool, apr_pool_t *scratch_pool); svn_error_t *(*revision_proplist)(apr_hash_t **table_p, svn_fs_t *fs, svn_revnum_t rev, svn_boolean_t refresh, - apr_pool_t *result_pool, + apr_pool_t *result_pool, apr_pool_t *scratch_pool); svn_error_t *(*change_rev_prop)(svn_fs_t *fs, svn_revnum_t rev, const char *name, @@ -266,6 +273,12 @@ typedef struct fs_vtable_t svn_error_t *(*bdb_set_errcall)(svn_fs_t *fs, void (*handler)(const char *errpfx, char *msg)); + svn_error_t *(*ioctl)(svn_fs_t *fs, svn_fs_ioctl_code_t ctlcode, + void *input, void **output_p, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); } fs_vtable_t; Modified: subversion/branches/addremove/subversion/libsvn_fs_base/bdb/locks-table.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/bdb/locks-table.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_base/bdb/locks-table.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_base/bdb/locks-table.c Sat May 23 14:16:56 2020 @@ -261,7 +261,7 @@ svn_fs_bdb__locks_get(svn_fs_t *fs, lookup_len = strlen(lookup_path); /* As long as the prefix of the returned KEY matches LOOKUP_PATH we - know it is either LOOKUP_PATH or a decendant thereof. */ + know it is either LOOKUP_PATH or a descendant thereof. */ while ((! db_err) && lookup_len < key.size && strncmp(lookup_path, key.data, lookup_len) == 0) Modified: subversion/branches/addremove/subversion/libsvn_fs_base/fs.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/fs.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_base/fs.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_base/fs.c Sat May 23 14:16:56 2020 @@ -574,6 +574,7 @@ static fs_vtable_t fs_vtable = { base_bdb_verify_root, base_bdb_freeze, base_bdb_set_errcall, + NULL /* ioctl */ }; /* Where the format number is stored. */ @@ -906,7 +907,7 @@ bdb_recover(const char *path, svn_boolea will simply join it instead, and will then be running with incorrectly sized (and probably terribly small) caches. */ - /* Note that since we're using a private environment, we shoudl + /* Note that since we're using a private environment, we should /not/ initialize locking. We want the environment files to go away. */ @@ -1077,7 +1078,7 @@ base_bdb_logfiles(apr_array_header_t **l /* Copying a live Berkeley DB-base filesystem. */ /** - * Delete all unused log files from DBD enviroment at @a live_path that exist + * Delete all unused log files from DBD environment at @a live_path that exist * in @a backup_path. */ static svn_error_t * @@ -1515,7 +1516,8 @@ static fs_library_vtable_t library_vtabl base_bdb_logfiles, svn_fs_base__id_parse, base_set_svn_fs_open, - NULL /* info_fsap_dup */ + NULL /* info_fsap_dup */, + NULL /* ioctl */ }; svn_error_t * Modified: subversion/branches/addremove/subversion/libsvn_fs_base/key-gen.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/key-gen.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_base/key-gen.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_base/key-gen.c Sat May 23 14:16:56 2020 @@ -50,7 +50,7 @@ svn_fs_base__next_key(const char *this, * from being propagated further. */ SVN_ERR_ASSERT_NO_RETURN(olen != 0 && (olen == 1 || this[0] != '0')); - i = olen - 1; /* initial index: we work backwords */ + i = olen - 1; /* initial index: we work backwards */ while (1729) { c = this[i]; Modified: subversion/branches/addremove/subversion/libsvn_fs_base/notes/fs-history URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/notes/fs-history?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_base/notes/fs-history (original) +++ subversion/branches/addremove/subversion/libsvn_fs_base/notes/fs-history Sat May 23 14:16:56 2020 @@ -128,7 +128,7 @@ node-revision ID consists of the same no that was cloned (since this is just another point along the historical lineage of this versioned resource), a copy ID (which will be discussed later), and the txn ID in which this modification is -occuring. +occurring. There are some cool things we can read between the lines above. Since the only time a node-revision comes into existence is when it is brand Modified: subversion/branches/addremove/subversion/libsvn_fs_base/reps-strings.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/reps-strings.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_base/reps-strings.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_base/reps-strings.c Sat May 23 14:16:56 2020 @@ -1,4 +1,4 @@ -/* reps-strings.c : intepreting representations with respect to strings +/* reps-strings.c : interpreting representations with respect to strings * * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one Modified: subversion/branches/addremove/subversion/libsvn_fs_base/tree.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_base/tree.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_base/tree.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_base/tree.c Sat May 23 14:16:56 2020 @@ -1627,7 +1627,7 @@ base_dir_optimal_order(apr_array_header_ apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - /* 1:1 copy of entries with no differnce in ordering */ + /* 1:1 copy of entries with no difference in ordering */ apr_hash_index_t *hi; apr_array_header_t *result = apr_array_make(result_pool, apr_hash_count(entries), @@ -3936,7 +3936,7 @@ txn_body_fulltext_finalize_edits(void *b trail->pool); } -/* Write function for the publically returned stream. */ +/* Write function for the publicly returned stream. */ static svn_error_t * text_stream_writer(void *baton, const char *data, @@ -3948,7 +3948,7 @@ text_stream_writer(void *baton, return svn_stream_write(tb->file_stream, data, len); } -/* Close function for the publically returned stream. */ +/* Close function for the publicly returned stream. */ static svn_error_t * text_stream_closer(void *baton) { Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.c Sat May 23 14:16:56 2020 @@ -1224,7 +1224,7 @@ struct rep_read_baton /* Used for temporary allocations during the read. */ apr_pool_t *pool; - /* Pool used to store file handles and other data that is persistant + /* Pool used to store file handles and other data that is persistent for the entire stream read. */ apr_pool_t *filehandle_pool; }; @@ -1268,7 +1268,7 @@ parse_raw_window(void **out, stream = svn_stream_from_string(&raw_window, result_pool); /* parse it */ - SVN_ERR(svn_txdelta_read_svndiff_window(&result->window, stream, 1, + SVN_ERR(svn_txdelta_read_svndiff_window(&result->window, stream, window->ver, result_pool)); /* complete the window and return it */ @@ -1775,7 +1775,7 @@ get_combined_window(svn_stringbuf_t **re return SVN_NO_ERROR; } -/* Returns whether or not the expanded fulltext of the file is cachable +/* Returns whether or not the expanded fulltext of the file is cacheable * based on its size SIZE. The decision depends on the cache used by FFD. */ static svn_boolean_t @@ -2103,13 +2103,14 @@ skip_contents(struct rep_read_baton *bat /* BATON is of type `rep_read_baton'; read the next *LEN bytes of the representation and store them in *BUF. Sum as we read and verify - the MD5 sum at the end. */ + the MD5 sum at the end. This is a READ_FULL_FN for svn_stream_t. */ static svn_error_t * rep_read_contents(void *baton, char *buf, apr_size_t *len) { struct rep_read_baton *rb = baton; + apr_size_t len_requested = *len; /* Get data from the fulltext cache for as long as we can. */ if (rb->fulltext_cache) @@ -2150,6 +2151,28 @@ rep_read_contents(void *baton, if (rb->current_fulltext) svn_stringbuf_appendbytes(rb->current_fulltext, buf, *len); + /* This is a FULL_READ_FN so a short read implies EOF and we can + verify the length. */ + rb->off += *len; + if (*len < len_requested && rb->off != rb->len) + { + /* A warning rather than an error to allow the data to be + retrieved when the length is wrong but the data is + present, i.e. if repository corruption has stored the wrong + expanded length. */ + svn_error_t *err = svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, + _("Length mismatch while reading representation:" + " expected %s," + " got %s"), + apr_psprintf(rb->pool, "%" SVN_FILESIZE_T_FMT, + rb->len), + apr_psprintf(rb->pool, "%" SVN_FILESIZE_T_FMT, + rb->off)); + + rb->fs->warning(rb->fs->warning_baton, err); + svn_error_clear(err); + } + /* Perform checksumming. We want to check the checksum as soon as the last byte of data is read, in case the caller never performs a short read, but we don't want to finalize the MD5 context @@ -2157,7 +2180,6 @@ rep_read_contents(void *baton, if (!rb->checksum_finalized) { SVN_ERR(svn_checksum_update(rb->md5_checksum_ctx, buf, *len)); - rb->off += *len; if (rb->off == rb->len) { svn_checksum_t *md5_checksum; @@ -2315,7 +2337,7 @@ svn_fs_fs__get_contents_from_file(svn_st rb->filehandle_pool)); /* Insert the access to REP as the first element of the delta chain. */ - svn_sort__array_insert(rb->rs_list, &rs, 0); + SVN_ERR(svn_sort__array_insert2(rb->rs_list, &rs, 0)); } /* Now, the baton is complete and we can assemble the stream around it. */ @@ -2677,7 +2699,7 @@ read_dir_entries(apr_array_header_t **en } /* For directory NODEREV in FS, return the *FILESIZE of its in-txn - * representation. If the directory representation is comitted data, + * representation. If the directory representation is committed data, * set *FILESIZE to SVN_INVALID_FILESIZE. Use SCRATCH_POOL for temporaries. */ static svn_error_t * @@ -3206,7 +3228,7 @@ init_rep_state(rep_state_t *rs, rs->start = entry->offset + rs->header_size; rs->current = rep_header->type == svn_fs_fs__rep_plain ? 0 : 4; rs->size = entry->size - rep_header->header_size - 7; - rs->ver = 1; + rs->ver = -1; rs->chunk_index = 0; rs->raw_window_cache = ffd->raw_window_cache; rs->window_cache = ffd->txdelta_window_cache; @@ -3264,6 +3286,9 @@ cache_windows(svn_fs_t *fs, apr_pool_t *pool) { apr_pool_t *iterpool = svn_pool_create(pool); + + SVN_ERR(auto_read_diff_version(rs, iterpool)); + while (rs->current < rs->size) { apr_off_t end_offset; @@ -3320,10 +3345,11 @@ cache_windows(svn_fs_t *fs, /* update relative offset in representation */ rs->current += window_len; - /* Construct the cachable raw window object. */ + /* Construct the cacheable raw window object. */ window.end_offset = rs->current; window.window.len = window_len; window.window.data = buf; + window.ver = rs->ver; /* cache the window now */ SVN_ERR(svn_cache__set(rs->raw_window_cache, &key, &window, Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.h (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/cached_data.h Sat May 23 14:16:56 2020 @@ -171,7 +171,7 @@ svn_fs_fs__get_proplist(apr_hash_t **pro apr_pool_t *pool); /* Create a changes retrieval context object in *RESULT_POOL and return it - * in *CONTEXT. It will allow svn_fs_x__get_changes to fetch consecutive + * in *CONTEXT. It will allow svn_fs_fs__get_changes to fetch consecutive * blocks (one per invocation) from REV's changed paths list in FS. */ svn_error_t * svn_fs_fs__create_changes_context(svn_fs_fs__changes_context_t **context, Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/dag.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/dag.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/dag.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/dag.c Sat May 23 14:16:56 2020 @@ -1166,7 +1166,7 @@ svn_fs_fs__dag_serialize(void **data, (const void * const *)&node->node_pool); /* serialize other sub-structures */ - svn_fs_fs__id_serialize(context, (const svn_fs_id_t **)&node->id); + svn_fs_fs__id_serialize(context, (const svn_fs_id_t *const *)&node->id); svn_fs_fs__id_serialize(context, &node->fresh_root_predecessor_id); svn_temp_serializer__add_string(context, &node->created_path); Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/dump-index.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/dump-index.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/dump-index.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/dump-index.c Sat May 23 14:16:56 2020 @@ -21,8 +21,8 @@ */ #include "svn_pools.h" -#include "private/svn_fs_fs_private.h" +#include "fs_fs.h" #include "index.h" #include "rev_file.h" #include "util.h" Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/fs.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/fs.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/fs.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/fs.c Sat May 23 14:16:56 2020 @@ -47,6 +47,7 @@ #include "verify.h" #include "svn_private_config.h" #include "private/svn_fs_util.h" +#include "private/svn_fs_fs_private.h" #include "../libsvn_fs/fs-loader.h" @@ -254,6 +255,83 @@ fs_set_uuid(svn_fs_t *fs, } +static svn_error_t * +fs_ioctl(svn_fs_t *fs, svn_fs_ioctl_code_t ctlcode, + void *input_void, void **output_p, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + if (strcmp(ctlcode.fs_type, SVN_FS_TYPE_FSFS) == 0) + { + if (ctlcode.code == SVN_FS_FS__IOCTL_GET_STATS.code) + { + svn_fs_fs__ioctl_get_stats_input_t *input = input_void; + svn_fs_fs__ioctl_get_stats_output_t *output; + + output = apr_pcalloc(result_pool, sizeof(*output)); + SVN_ERR(svn_fs_fs__get_stats(&output->stats, fs, + input->progress_func, + input->progress_baton, + cancel_func, cancel_baton, + result_pool, scratch_pool)); + *output_p = output; + return SVN_NO_ERROR; + } + else if (ctlcode.code == SVN_FS_FS__IOCTL_DUMP_INDEX.code) + { + svn_fs_fs__ioctl_dump_index_input_t *input = input_void; + + SVN_ERR(svn_fs_fs__dump_index(fs, input->revision, + input->callback_func, + input->callback_baton, + cancel_func, cancel_baton, + scratch_pool)); + *output_p = NULL; + return SVN_NO_ERROR; + } + else if (ctlcode.code == SVN_FS_FS__IOCTL_LOAD_INDEX.code) + { + svn_fs_fs__ioctl_load_index_input_t *input = input_void; + + SVN_ERR(svn_fs_fs__load_index(fs, input->revision, input->entries, + scratch_pool)); + *output_p = NULL; + return SVN_NO_ERROR; + } + else if (ctlcode.code == SVN_FS_FS__IOCTL_REVISION_SIZE.code) + { + svn_fs_fs__ioctl_revision_size_input_t *input = input_void; + svn_fs_fs__ioctl_revision_size_output_t *output + = apr_pcalloc(result_pool, sizeof(*output)); + + SVN_ERR(svn_fs_fs__revision_size(&output->rev_size, + fs, input->revision, + scratch_pool)); + *output_p = output; + return SVN_NO_ERROR; + } + else if (ctlcode.code == SVN_FS_FS__IOCTL_BUILD_REP_CACHE.code) + { + svn_fs_fs__ioctl_build_rep_cache_input_t *input = input_void; + + SVN_ERR(svn_fs_fs__build_rep_cache(fs, + input->start_rev, + input->end_rev, + input->progress_func, + input->progress_baton, + cancel_func, + cancel_baton, + scratch_pool)); + + *output_p = NULL; + return SVN_NO_ERROR; + } + } + + return svn_error_create(SVN_ERR_FS_UNRECOGNIZED_IOCTL_CODE, NULL, NULL); +} /* The vtable associated with a specific open filesystem. */ static fs_vtable_t fs_vtable = { @@ -279,7 +357,8 @@ static fs_vtable_t fs_vtable = { fs_info, svn_fs_fs__verify_root, fs_freeze, - fs_set_errcall + fs_set_errcall, + fs_ioctl }; @@ -602,7 +681,8 @@ static fs_library_vtable_t library_vtabl fs_logfiles, NULL /* parse_id */, fs_set_svn_fs_open, - fs_info_dup + fs_info_dup, + NULL /* ioctl */ }; svn_error_t *