[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] add --xml to proplist command

From: se˝ior ┐tyrtle? <machtyrtle_at_gmail.com>
Date: 2005-07-22 15:36:00 CEST

 [[[
   Added support for "svn proplist" to print in xml.
   
   * subversion/subversion/clients/cmdline/cl.h:
     Removed declaration of svn_cl__print_prop_hash.
     It was only being used in proplist-cmd.c, and
     needed to be re-factored to print different formats.

   * subversion/subversion/clients/cmdline/props.c:
     Removed svn_cl__print_prop_hash.

   * subversion/subversion/clients/cmdline/proplist-cmd.c:
     Added support for printing properties in xml.
     Moved the old extern svn_cl__print_prop_hash function
     to static svn__print_prop_hash.

   * subversion/subversion/clients/cmdline/main.c:
     Allow "--xml" for proplist command.
]]]

Index: subversion/subversion/clients/cmdline/props.c
===================================================================
--- subversion/subversion/clients/cmdline/props.c (revision 17)
+++ subversion/subversion/clients/cmdline/props.c (working copy)
@@ -41,42 +41,4 @@
     (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
      _("Must specify revision explicitly when operating on a "
        "revision property"));
-}
-
-
-svn_error_t *
-svn_cl__print_prop_hash (apr_hash_t *prop_hash,
- svn_boolean_t names_only,
- apr_pool_t *pool)
-{
- apr_hash_index_t *hi;
-
- for (hi = apr_hash_first (pool, prop_hash); hi; hi = apr_hash_next (hi))
- {
- const void *key;
- void *val;
- const char *pname;
- svn_string_t *propval;
- const char *pname_stdout;
-
- apr_hash_this (hi, &key, NULL, &val);
- pname = key;
- propval = val;
-
- if (svn_prop_needs_translation (pname))
- SVN_ERR (svn_subst_detranslate_string (&propval, propval,
- TRUE, pool));
-
- SVN_ERR (svn_cmdline_cstring_from_utf8 (&pname_stdout, pname, pool));
-
- /* ### We leave these printfs for now, since if propval wasn't translated
- * above, we don't know anything about its encoding. In fact, it
- * might be binary data... */
- if (names_only)
- printf (" %s\n", pname_stdout);
- else
- printf (" %s : %s\n", pname_stdout, propval->data);
- }
-
- return SVN_NO_ERROR;
-}
+}
\ No newline at end of file
Index: subversion/subversion/clients/cmdline/cl.h
===================================================================
--- subversion/subversion/clients/cmdline/cl.h (revision 17)
+++ subversion/subversion/clients/cmdline/cl.h (working copy)
@@ -254,18 +254,6 @@
                                    svn_boolean_t repos_locks,
                                    apr_pool_t *pool);
 
-/* Print a hash that maps property names (char *) to property values
- (svn_string_t *). The names are assumed to be in UTF-8 format;
- the values are either in UTF-8 (the special Subversion props) or
- plain binary values.
-
- If NAMES_ONLY is true, print just names, else print names and
- values. */
-svn_error_t *
-svn_cl__print_prop_hash (apr_hash_t *prop_hash,
- svn_boolean_t names_only,
- apr_pool_t *pool);
-
 /* Return a SVN_ERR_CL_ARG_PARSING_ERROR error, with a message stating
    that one must give an explicit revision when operating on a
    revision property. */
Index: subversion/subversion/clients/cmdline/proplist-cmd.c
===================================================================
--- subversion/subversion/clients/cmdline/proplist-cmd.c (revision 17)
+++ subversion/subversion/clients/cmdline/proplist-cmd.c (working copy)
@@ -26,7 +26,9 @@
 #include "svn_pools.h"
 #include "svn_client.h"
 #include "svn_error.h"
+#include "svn_subst.h"
 #include "svn_path.h"
+#include "svn_xml.h"
 #include "cl.h"
 
 #include "svn_private_config.h"
@@ -34,6 +36,178 @@
 
 /*** Code. ***/
 
+typedef svn_error_t* (*prop_print_function_t)(const char* pname,
+ svn_string_t *propval,
+ void *refcon,
+ apr_pool_t *pool);
+
+/* Print a hash that maps property names (char *) to property values
+ (svn_string_t *). The names are assumed to be in UTF-8 format;
+ the values are either in UTF-8 (the special Subversion props) or
+ plain binary values.
+
+ Pass the property name and a (possibly de-translated) value
+ to the print function. */
+
+static svn_error_t *
+svn__print_prop_hash (apr_hash_t *prop_hash,
+ prop_print_function_t print_func,
+ void *baton,
+ apr_pool_t *pool)
+{
+ apr_hash_index_t *hi;
+
+ for (hi = apr_hash_first (pool, prop_hash); hi; hi = apr_hash_next (hi))
+ {
+ const void *key;
+ void *val;
+ const char *pname;
+ svn_string_t *propval;
+
+ apr_hash_this (hi, &key, NULL, &val);
+ pname = key;
+ propval = val;
+
+ if (svn_prop_needs_translation (pname))
+ SVN_ERR (svn_subst_detranslate_string (&propval, propval,
+ TRUE, pool));
+
+ SVN_ERR (print_func(pname, propval, baton, pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Iterate an array of props, where each element is a hash that maps
+ property names (char *) to property values (svn_string_t *).
+
+ Pass one hash and the current property's path to the receiving print-function.
+ */
+
+typedef svn_error_t* (*prop_path_print_function_t)(apr_hash_t *prop_hash,
+ const char *path,
+ void *baton,
+ apr_pool_t *pool);
+
+static svn_error_t*
+svn__print_props(apr_array_header_t *props,
+ svn_boolean_t is_url,
+ prop_path_print_function_t print_func,
+ void *baton,
+ apr_pool_t *pool)
+{
+ int j;
+ for (j = 0; j < props->nelts; ++j)
+ {
+ svn_client_proplist_item_t *item
+ = ((svn_client_proplist_item_t **)props->elts)[j];
+ const char *name_local;
+
+ if (! is_url)
+ name_local = svn_path_local_style (item->node_name->data,
+ pool);
+ else
+ name_local = item->node_name->data;
+
+ SVN_ERR (print_func(item->prop_hash, name_local, baton, pool));
+ }
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+svn__do_print_prop_xml (const char *pname,
+ svn_string_t *propval,
+ void *baton,
+ apr_pool_t *pool)
+{
+ svn_stringbuf_t *sb = (svn_stringbuf_t*) baton;
+ svn_xml_make_open_tag (&sb, pool, svn_xml_protect_pcdata, "key",
+ NULL);
+ svn_xml_escape_cdata_cstring (&sb, pname, pool);
+ svn_xml_make_close_tag (&sb, pool, "key");
+
+ svn_xml_make_open_tag (&sb, pool, svn_xml_protect_pcdata, "value",
+ NULL);
+ svn_xml_escape_cdata_cstring (&sb, propval->data, pool);
+ svn_xml_make_close_tag (&sb, pool, "value");
+
+ return SVN_NO_ERROR;
+}
+
+/* Print a bunch of properties in xml.
+
+ Basically just a wrapper to get all the properties within
+ a <properties></properties tag */
+
+static svn_error_t *
+svn__print_prop_hash_xml (apr_hash_t *prop_hash,
+ svn_stringbuf_t *sb,
+ apr_pool_t *pool)
+{
+ /* <properties> */
+ svn_xml_make_open_tag (&sb, pool, svn_xml_normal, "properties",
+ NULL);
+
+ SVN_ERR (svn__print_prop_hash(prop_hash, svn__do_print_prop_xml, sb, pool));
+
+ /* </properties> */
+ svn_xml_make_close_tag (&sb, pool, "properties");
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+svn__do_print_prop_cl (const char *pname,
+ svn_string_t *propval,
+ void *names_only,
+ apr_pool_t *pool)
+{
+ const char *pname_stdout;
+ SVN_ERR (svn_cmdline_cstring_from_utf8 (&pname_stdout, pname, pool));
+ /* ### We leave these printfs for now, since if propval wasn't translated
+ * above, we don't know anything about its encoding. In fact, it
+ * might be binary data... */
+ if (names_only)
+ printf (" %s\n", pname_stdout);
+ else
+ printf (" %s : %s\n", pname_stdout, propval->data);
+
+ return SVN_NO_ERROR;
+}
+
+
+/* Print a property as xml */
+
+static svn_error_t*
+svn__do_print_props_xml(apr_hash_t *prop_hash,
+ const char *path,
+ void *baton,
+ apr_pool_t *pool)
+{
+ svn_stringbuf_t *sb = (svn_stringbuf_t*) baton;
+ /* <path> */
+ svn_xml_make_open_tag (&sb, pool, svn_xml_protect_pcdata, "path", NULL);
+ svn_xml_escape_cdata_cstring (&sb, path, pool);
+ svn_xml_make_close_tag (&sb, pool, "path");
+ /* </path> */
+
+ SVN_ERR (svn__print_prop_hash_xml(prop_hash, sb, pool));
+}
+
+/* Print a property. */
+
+static svn_error_t*
+svn__do_print_props_cl(apr_hash_t *prop_hash,
+ const char *path,
+ void *baton,
+ apr_pool_t *pool)
+ {
+ SVN_ERR (svn_cmdline_printf(pool, "Properties on '%s':\n", path));
+ SVN_ERR (svn__print_prop_hash(prop_hash, svn__do_print_prop_cl, baton, pool));
+ return SVN_NO_ERROR;
+}
+
+
 /* This implements the `svn_opt_subcommand_t' interface. */
 svn_error_t *
 svn_cl__proplist (apr_getopt_t *os,
@@ -43,6 +217,7 @@
   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
+ svn_stringbuf_t *sb;
   int i;
 
   /* Suck up all remaining args in the target array. */
@@ -81,14 +256,22 @@
       SVN_ERR (svn_client_revprop_list (&proplist,
                                         URL, &(opt_state->start_revision),
                                         &rev, ctx, pool));
-
- SVN_ERR
- (svn_cmdline_printf (pool,
+
+ if (opt_state->xml)
+ {
+ sb = svn_stringbuf_create ("", pool);
+ SVN_ERR (svn__print_prop_hash_xml(proplist, sb, pool));
+ SVN_ERR (svn_cl__error_checked_fputs (sb->data, stdout));
+ }
+ else
+ {
+ SVN_ERR (svn_cmdline_printf (pool,
                              _("Unversioned properties on revision %ld:\n"),
                              rev));
 
- SVN_ERR (svn_cl__print_prop_hash
- (proplist, (! opt_state->verbose), pool));
+ SVN_ERR (svn__print_prop_hash
+ (proplist, svn__do_print_prop_cl, (void*)(! opt_state->verbose), pool));
+ }
     }
   else /* operate on normal, versioned properties (not revprops) */
     {
@@ -98,7 +281,6 @@
         {
           const char *target = ((const char **) (targets->elts))[i];
           apr_array_header_t *props;
- int j;
           svn_error_t *err;
           svn_boolean_t is_url = svn_path_is_url (target);
           const char *truepath;
@@ -129,23 +311,15 @@
                 return err;
             }
 
- for (j = 0; j < props->nelts; ++j)
+ if (opt_state->xml)
             {
- svn_client_proplist_item_t *item
- = ((svn_client_proplist_item_t **)props->elts)[j];
- const char *name_local;
+ sb = svn_stringbuf_create ("", pool);
+ SVN_ERR (svn__print_props(props, is_url, svn__do_print_props_xml, sb, pool));
+ SVN_ERR (svn_cl__error_checked_fputs (sb->data, stdout));
+ }
+ else
+ SVN_ERR (svn__print_props(props, is_url, svn__do_print_props_cl, (void*)opt_state->verbose, pool));
 
- if (! is_url)
- name_local = svn_path_local_style (item->node_name->data,
- subpool);
- else
- name_local = item->node_name->data;
-
- SVN_ERR (svn_cmdline_printf(subpool, "Properties on '%s':\n",
- name_local));
- SVN_ERR (svn_cl__print_prop_hash
- (item->prop_hash, (! opt_state->verbose), subpool));
- }
         }
       svn_pool_destroy (subpool);
     }
Index: subversion/subversion/clients/cmdline/main.c
===================================================================
--- subversion/subversion/clients/cmdline/main.c (revision 17)
+++ subversion/subversion/clients/cmdline/main.c (working copy)
@@ -533,7 +533,7 @@
        " 1. Lists versioned props. If specified, REV determines in which\n"
        " revision the target is first looked up.\n"
        " 2. Lists unversioned remote props on repos revision.\n"),
- {'v', 'R', 'r', 'q', svn_cl__revprop_opt, SVN_CL__AUTH_OPTIONS,
+ {'v', 'R', 'r', 'q', svn_cl__revprop_opt, svn_cl__xml_opt, SVN_CL__AUTH_OPTIONS,
      svn_cl__config_dir_opt} },
 
   { "propset", svn_cl__propset, {"pset", "ps"},

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Received on Fri Jul 22 17:38:25 2005

This is an archived mail posted to the Subversion Dev mailing list.