Fill in replay_revstart to dump the revprops at the start of every revision. Add an additional write_hash_to_stringbuf helper function. Signed-off-by: Ramkumar Ramachandra <artagnon@xxxxxxxxx> --- Makefile | 4 +- dumpr_util.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ dumpr_util.h | 5 ++++ svndumpr.c | 38 ++++++++++++++++++++++++++++++++- 4 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 dumpr_util.c diff --git a/Makefile b/Makefile index fea646e..c0b5c8a 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ svndumpr: *.c *.h - $(CC) -Wall -Werror -DAPR_POOL_DEBUG -ggdb3 -O0 -o $@ svndumpr.c debug_editor.c dump_editor.c -lsvn_client-1 -I. -I/usr/local/include/subversion-1 -I/usr/include/apr-1.0 + $(CC) -Wall -Werror -DAPR_POOL_DEBUG -ggdb3 -O0 -o $@ svndumpr.c debug_editor.c dump_editor.c dumpr_util.c -lsvn_client-1 -I. -I/usr/local/include/subversion-1 -I/usr/include/apr-1.0 svndumpr_bench: *.c *.h - $(CC) -O2 -o $@ svndumpr.c debug_editor.c dump_editor.c -lsvn_client-1 -I. -I/usr/local/include/subversion-1 -I/usr/include/apr-1.0 + $(CC) -O2 -o $@ svndumpr.c debug_editor.c dump_editor.c dumpr_util.c -lsvn_client-1 -I. -I/usr/local/include/subversion-1 -I/usr/include/apr-1.0 clean: $(RM) svndumpr svndumpr_bench diff --git a/dumpr_util.c b/dumpr_util.c new file mode 100644 index 0000000..41940d4 --- /dev/null +++ b/dumpr_util.c @@ -0,0 +1,64 @@ +/* Licensed under a two-clause BSD-style license. + * See LICENSE for details. + */ + +#include "svn_pools.h" +#include "svn_cmdline.h" +#include "svn_client.h" +#include "svn_ra.h" +#include "svn_repos.h" + +#include "dumpr_util.h" + +void write_hash_to_stringbuf(apr_hash_t *properties, + svn_boolean_t deleted, + svn_stringbuf_t **strbuf, + apr_pool_t *pool) +{ + apr_hash_index_t *this; + const void *key; + void *val; + apr_ssize_t keylen; + svn_string_t *value; + + if (!deleted) { + for (this = apr_hash_first(pool, properties); this; + this = apr_hash_next(this)) { + /* Get this key and val. */ + apr_hash_this(this, &key, &keylen, &val); + value = val; + + /* Output name length, then name. */ + svn_stringbuf_appendcstr(*strbuf, + apr_psprintf(pool, "K %" APR_SSIZE_T_FMT "\n", + keylen)); + + svn_stringbuf_appendbytes(*strbuf, (const char *) key, keylen); + svn_stringbuf_appendbytes(*strbuf, "\n", 1); + + /* Output value length, then value. */ + svn_stringbuf_appendcstr(*strbuf, + apr_psprintf(pool, "V %" APR_SIZE_T_FMT "\n", + value->len)); + + svn_stringbuf_appendbytes(*strbuf, value->data, value->len); + svn_stringbuf_appendbytes(*strbuf, "\n", 1); + } + } + else { + /* Output a "D " entry for each deleted property */ + for (this = apr_hash_first(pool, properties); this; + this = apr_hash_next(this)) { + /* Get this key */ + apr_hash_this(this, &key, &keylen, NULL); + + /* Output name length, then name */ + svn_stringbuf_appendcstr(*strbuf, + apr_psprintf(pool, "D %" APR_SSIZE_T_FMT "\n", + keylen)); + + svn_stringbuf_appendbytes(*strbuf, (const char *) key, keylen); + svn_stringbuf_appendbytes(*strbuf, "\n", 1); + } + } +} diff --git a/dumpr_util.h b/dumpr_util.h index 166e214..1a5752b 100644 --- a/dumpr_util.h +++ b/dumpr_util.h @@ -31,4 +31,9 @@ struct edit_baton { svn_checksum_t *checksum; }; +void write_hash_to_stringbuf(apr_hash_t *properties, + svn_boolean_t deleted, + svn_stringbuf_t **strbuf, + apr_pool_t *pool); + #endif diff --git a/svndumpr.c b/svndumpr.c index 853facd..011941f 100644 --- a/svndumpr.c +++ b/svndumpr.c @@ -23,6 +23,37 @@ static svn_error_t *replay_revstart(svn_revnum_t revision, apr_hash_t *rev_props, apr_pool_t *pool) { + /* Editing this revision has just started; dump the revprops + before invoking the editor callbacks */ + svn_stringbuf_t *propstring = svn_stringbuf_create("", pool); + svn_stream_t *stdout_stream; + + /* Create an stdout stream */ + svn_stream_for_stdout(&stdout_stream, pool); + + /* Print revision number and prepare the propstring */ + SVN_ERR(svn_stream_printf(stdout_stream, pool, + SVN_REPOS_DUMPFILE_REVISION_NUMBER + ": %ld\n", revision)); + write_hash_to_stringbuf(rev_props, FALSE, &propstring, pool); + svn_stringbuf_appendbytes(propstring, "PROPS-END\n", 10); + + /* prop-content-length header */ + SVN_ERR(svn_stream_printf(stdout_stream, pool, + SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH + ": %" APR_SIZE_T_FMT "\n", propstring->len)); + + /* content-length header */ + SVN_ERR(svn_stream_printf(stdout_stream, pool, + SVN_REPOS_DUMPFILE_CONTENT_LENGTH + ": %" APR_SIZE_T_FMT "\n\n", propstring->len)); + + /* Print the revprops now */ + SVN_ERR(svn_stream_write(stdout_stream, propstring->data, + &(propstring->len))); + + svn_stream_close(stdout_stream); + /* Extract editor and editor_baton from the replay_baton and set them so that the editor callbacks can use them */ struct replay_baton *rb = replay_baton; @@ -39,6 +70,9 @@ static svn_error_t *replay_revend(svn_revnum_t revision, apr_hash_t *rev_props, apr_pool_t *pool) { + /* Editor has finished for this revision and close_edit has + been called; do nothing: just continue to the next + revision */ return SVN_NO_ERROR; } @@ -89,8 +123,8 @@ svn_error_t *replay_range(svn_revnum_t start_revision, svn_revnum_t end_revision dump_baton, pool)); struct replay_baton *replay_baton = apr_palloc(pool, sizeof(struct replay_baton)); - replay_baton->editor = debug_editor; - replay_baton->baton = debug_baton; + replay_baton->editor = dump_editor; + replay_baton->baton = dump_baton; SVN_ERR(svn_cmdline_printf(pool, SVN_REPOS_DUMPFILE_MAGIC_HEADER ": %d\n", SVN_REPOS_DUMPFILE_FORMAT_VERSION)); SVN_ERR(svn_ra_replay_range(session, start_revision, end_revision, -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html