Implemented --xml option to 'svn log'. It makes the log output come
out as XML, with full dates. Example of the output:
,----[ svn log -r1:188 --xml README ]
| <log>
| <logentry
| revision="1">
| <author>svn</author>
| <date>Thu 30 Aug 2001 23:24:14.966996 (day 242, dst 1, gmt_off -18000)</date>
| <msg>Initial import.</msg>
| </logentry>
| <logentry
| revision="188">
| <author>kfogel</author>
| <date>Mon 1 Oct 2001 10:35:02.330226 (day 274, dst 1, gmt_off -18000)</date>
| <msg>* packages/, packages/rpm: new directories.
|
| * README: Describe new top-level directory.
|
| * packages/README: New file.
|
| * packages/rpm/subversion.spec: Spec file for source rpm, contributed
| by David Summers <david@summersoft.fay.ar.us>.
| </msg>
| </logentry>
| </log>
`----
Changelog:
2002-05-01 Nuutti Kotivuori <naked@iki.fi>
* main.c: Add --xml option to svn_cl__options.
(svn_cl__cmd_table): Add svn_cl__xml_opt to log.
(main): Add handling for svn_cl__xml_opt.
* cl.h: Add svn_cl__xml_opt to enum svn_cl__longopt_t.
(svn_cl__opt_state_t): Add xml option.
* log-cmd.c: Include svn_pools.h and svn_xml.h.
(log_message_receiver_xml): New function
(svn_cl__log): Use log_message_receiver_xml when specified.
Patch:
Index: ./subversion/clients/cmdline/cl.h
===================================================================
--- ./subversion/clients/cmdline/cl.h
+++ ./subversion/clients/cmdline/cl.h Wed May 1 17:48:22 2002
@@ -52,6 +52,7 @@
svn_cl__auth_username_opt,
svn_cl__auth_password_opt,
svn_cl__targets_opt,
+ svn_cl__xml_opt,
} svn_cl__longopt_t;
@@ -99,6 +100,7 @@
svn_stringbuf_t *extensions;
/* Targets supplied from a file with --targets */
apr_array_header_t *targets;
+ svn_boolean_t xml; /* output in xml */
} svn_cl__opt_state_t;
Index: ./subversion/clients/cmdline/log-cmd.c
===================================================================
--- ./subversion/clients/cmdline/log-cmd.c
+++ ./subversion/clients/cmdline/log-cmd.c Wed May 1 23:05:44 2002
@@ -31,6 +31,8 @@
#include "svn_path.h"
#include "svn_delta.h"
#include "svn_error.h"
+#include "svn_pools.h"
+#include "svn_xml.h"
#include "cl.h"
@@ -165,6 +167,94 @@
}
+/* This implements `svn_log_message_receiver_t' aswell,
+ but outputs XML instead. */
+static svn_error_t *
+log_message_receiver_xml (void *baton,
+ apr_hash_t *changed_paths,
+ svn_revnum_t rev,
+ const char *author,
+ const char *date,
+ const char *msg)
+{
+ struct log_message_receiver_baton *lb = baton;
+ /* New pool for every received message. */
+ apr_pool_t *subpool = svn_pool_create(lb->pool);
+ /* Collate whole log message into sb before printing. */
+ svn_stringbuf_t *sb = svn_stringbuf_create("", subpool);
+ char *revstr;
+
+ revstr = apr_psprintf(subpool, "%" SVN_REVNUM_T_FMT, rev);
+ /* <logentry revision="xxx"> */
+ svn_xml_make_open_tag (&sb, subpool, svn_xml_normal, "logentry",
+ "revision", svn_stringbuf_create(revstr, subpool),
+ NULL);
+
+ /* <author>xxx</author> */
+ svn_xml_make_open_tag (&sb, subpool, svn_xml_protect_pcdata, "author",
+ NULL);
+ svn_xml_escape_nts(&sb, author, subpool);
+ svn_xml_make_close_tag (&sb, subpool, "author");
+
+ /* Print the full, uncut, date. This is machine output. */
+ /* <date>xxx</date> */
+ svn_xml_make_open_tag (&sb, subpool, svn_xml_protect_pcdata, "date",
+ NULL);
+ svn_xml_escape_nts(&sb, date, subpool);
+ svn_xml_make_close_tag (&sb, subpool, "date");
+
+ if (changed_paths)
+ {
+ apr_hash_index_t *hi;
+ char *path;
+
+ /* <files> */
+ svn_xml_make_open_tag (&sb, subpool, svn_xml_normal, "files",
+ NULL);
+
+ for (hi = apr_hash_first(subpool, changed_paths);
+ hi != NULL;
+ hi = apr_hash_next(hi))
+ {
+ void *val;
+ char action;
+ char *actionstr;
+
+ apr_hash_this(hi, (void *) &path, NULL, &val);
+ action = (char) ((int) val);
+
+ actionstr = apr_psprintf(subpool, "%c",
+ (action == 'R' ? 'U' : action));
+ /* <path action="X">xxx</path> */
+ svn_xml_make_open_tag (&sb, subpool, svn_xml_protect_pcdata,
+ "path", "action",
+ svn_stringbuf_create(actionstr, subpool),
+ NULL);
+ svn_xml_escape_nts(&sb, path, subpool);
+ svn_xml_make_close_tag (&sb, subpool, "path");
+ }
+
+ /* </files> */
+ svn_xml_make_close_tag (&sb, subpool, "files");
+ }
+
+ /* <msg>xxx</msg> */
+ svn_xml_make_open_tag (&sb, subpool, svn_xml_protect_pcdata, "msg",
+ NULL);
+ svn_xml_escape_nts(&sb, msg, subpool);
+ svn_xml_make_close_tag (&sb, subpool, "msg");
+
+ /* </logentry> */
+ svn_xml_make_close_tag (&sb, subpool, "logentry");
+
+ printf ("%s", sb->data);
+
+ svn_pool_destroy(subpool);
+
+ return SVN_NO_ERROR;
+}
+
+
svn_error_t *
svn_cl__log (apr_getopt_t *os,
svn_cl__opt_state_t *opt_state,
@@ -217,14 +307,51 @@
lb.first_call = 1;
lb.pool = pool;
- SVN_ERR (svn_client_log (auth_baton,
- targets,
- &(opt_state->start_revision),
- &(opt_state->end_revision),
- opt_state->verbose,
- log_message_receiver,
- &lb,
- pool));
+ if(!opt_state->xml)
+ {
+ SVN_ERR (svn_client_log (auth_baton,
+ targets,
+ &(opt_state->start_revision),
+ &(opt_state->end_revision),
+ opt_state->verbose,
+ log_message_receiver,
+ &lb,
+ pool));
+ }
+ else
+ {
+ svn_stringbuf_t *sb;
+
+ sb = NULL;
+
+ /* The header generation is commented out because it might not
+ be certain that the log messages are indeed the advertised
+ encoding, UTF-8. The absence of the header should not matter
+ to people processing the output, and they should add it
+ themselves if storing the output as a fully-formed XML
+ document. */
+ /* <?xml version="1.0" encoding="utf-8"?> */
+ /* svn_xml_make_header (&sb, pool); */
+
+ /* <log> */
+ svn_xml_make_open_tag (&sb, pool, svn_xml_normal, "log",
+ NULL);
+ printf ("%s", sb->data);
+
+ SVN_ERR (svn_client_log (auth_baton,
+ targets,
+ &(opt_state->start_revision),
+ &(opt_state->end_revision),
+ opt_state->verbose,
+ log_message_receiver_xml,
+ &lb,
+ pool));
+
+ sb = NULL;
+ /* </log> */
+ svn_xml_make_close_tag (&sb, pool, "log");
+ printf ("%s", sb->data);
+ }
return SVN_NO_ERROR;
}
Index: ./subversion/clients/cmdline/main.c
===================================================================
--- ./subversion/clients/cmdline/main.c
+++ ./subversion/clients/cmdline/main.c Wed May 1 17:53:05 2002
@@ -70,6 +70,7 @@
{"password", svn_cl__auth_password_opt, 1, "specify a password ARG"},
{"extensions", 'x', 1, "pass \"ARG\" as bundled options to GNU diff"},
{"targets", svn_cl__targets_opt, 1, "pass contents of file \"ARG\" as additional args"},
+ {"xml", svn_cl__xml_opt, 0, "output in xml"},
{0, 0, 0}
};
@@ -227,7 +228,7 @@
"\n"
" svn log http://www.example.com/repo/project foo.c bar.c\n",
{'r', 'D', 'v', svn_cl__targets_opt, svn_cl__auth_username_opt,
- svn_cl__auth_password_opt} },
+ svn_cl__auth_password_opt, svn_cl__xml_opt} },
{ "merge", svn_cl__merge, {0},
"merge: apply the differences between two paths to a working copy path.\n"
@@ -978,6 +979,9 @@
opt_arg);
svn_handle_error (err, stderr, FALSE);
}
+ break;
+ case svn_cl__xml_opt:
+ opt_state.xml = TRUE;
break;
case 'x':
opt_state.extensions = svn_stringbuf_create(opt_arg, pool);
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed May 1 22:41:52 2002