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

[PATCH] Fix encoding of "svn list --xml" [was: svn commit: r12837 ...]

From: Julian Foad <julianfoad_at_btopenworld.com>
Date: 2005-01-26 01:20:53 CET

Peter N. Lundblad wrote:
> This will convert UTF8->console encoding, which we don't want in this
> case. See error_checked_fputs in log-cmd.c.

[[[
Fix the encoding of XML output from "svn list --xml": output it as UTF-8.

* subversion/clients/cmdline/log-cmd.c
   (error_checked_fputs): Extracted and made semi-public with svn_cl__ prefix.
   (log_message_receiver_xml, svn_cl__log): Adjust calls accordingly.

* subversion/clients/cmdline/cl.h
* subversion/clients/cmdline/util.c
   (svn_cl__error_checked_fputs): New; was log-cmd.c::error_checked_fputs.

* subversion/clients/cmdline/ls-cmd.c
   (print_header_xml, print_footer_xml): New helper functions, for tidiness.
   (print_dirents_xml, svn_cl__ls): Avoid converting UTF-8 to native encoding
     when writing XML output.
]]]

- Julian

Fix the encoding of XML output from "svn list --xml": output it as UTF-8.

* subversion/clients/cmdline/log-cmd.c
  (error_checked_fputs): Extracted and made semi-public with svn_cl__ prefix.
  (log_message_receiver_xml, svn_cl__log): Adjust calls accordingly.

* subversion/clients/cmdline/cl.h
* subversion/clients/cmdline/util.c
  (svn_cl__error_checked_fputs): New; was log-cmd.c::error_checked_fputs.

* subversion/clients/cmdline/ls-cmd.c
  (print_header_xml, print_footer_xml): New helper functions, for tidiness.
  (print_dirents_xml, svn_cl__ls): Avoid converting UTF-8 to native encoding
    when writing XML output.

Index: subversion/clients/cmdline/cl.h
===================================================================
--- subversion/clients/cmdline/cl.h (revision 12852)
+++ subversion/clients/cmdline/cl.h (working copy)
@@ -434,6 +434,9 @@ svn_error_t *svn_cl__cleanup_log_msg (vo
 /* Add a message about --force if appropriate */
 svn_error_t *svn_cl__may_need_force (svn_error_t *err);
 
+/* Write the STRING to the stdio STREAM, returning an error if it fails. */
+svn_error_t *svn_cl__error_checked_fputs (const char *string,
+ FILE* stream);
 
 #ifdef __cplusplus
 }
Index: subversion/clients/cmdline/log-cmd.c
===================================================================
--- subversion/clients/cmdline/log-cmd.c (revision 12852)
+++ subversion/clients/cmdline/log-cmd.c (working copy)
@@ -73,29 +73,6 @@ num_lines (const char *msg)
   return count;
 }
 
-static svn_error_t *
-error_checked_fputs(const char *string, FILE* stream)
-{
- /* This function is equal to svn_cmdline_fputs() minus
- the utf8->local encoding translation */
-
- /* On POSIX systems, errno will be set on an error in fputs, but this might
- not be the case on other platforms. We reset errno and only
- use it if it was set by the below fputs call. Else, we just return
- a generic error. */
- errno = 0;
-
- if (fputs (string, stream) == EOF)
- {
- if (errno)
- return svn_error_wrap_apr (errno, _("Write error"));
- else
- return svn_error_create (SVN_ERR_IO_WRITE_ERROR, NULL, NULL);
- }
-
- return SVN_NO_ERROR;
-}
-
 /* Baton for log_message_receiver() and log_message_receiver_xml(). */
 struct log_receiver_baton
 {
@@ -435,7 +412,7 @@ log_message_receiver_xml (void *baton,
   /* </logentry> */
   svn_xml_make_close_tag (&sb, pool, "logentry");
 
- SVN_ERR (error_checked_fputs (sb->data, stdout));
+ SVN_ERR (svn_cl__error_checked_fputs (sb->data, stdout));
 
   return SVN_NO_ERROR;
 }
@@ -538,7 +515,7 @@ svn_cl__log (apr_getopt_t *os,
           /* "<log>" */
           svn_xml_make_open_tag (&sb, pool, svn_xml_normal, "log", NULL);
 
- SVN_ERR (error_checked_fputs (sb->data, stdout));
+ SVN_ERR (svn_cl__error_checked_fputs (sb->data, stdout));
         }
       
       SVN_ERR (svn_client_log2 (targets,
@@ -559,7 +536,7 @@ svn_cl__log (apr_getopt_t *os,
           /* "</log>" */
           svn_xml_make_close_tag (&sb, pool, "log");
 
- SVN_ERR (error_checked_fputs (sb->data, stdout));
+ SVN_ERR (svn_cl__error_checked_fputs (sb->data, stdout));
         }
     }
   else /* default output format */
Index: subversion/clients/cmdline/ls-cmd.c
===================================================================
--- subversion/clients/cmdline/ls-cmd.c (revision 12852)
+++ subversion/clients/cmdline/ls-cmd.c (working copy)
@@ -138,27 +138,44 @@ kind_str (svn_node_kind_t kind)
 
 
 static svn_error_t *
+print_header_xml (apr_pool_t *pool)
+{
+ svn_stringbuf_t *sb = svn_stringbuf_create ("", pool);
+
+ /* <?xml version="1.0" encoding="utf-8"?> */
+ svn_xml_make_header (&sb, pool);
+
+ /* "<lists>" */
+ svn_xml_make_open_tag (&sb, pool, svn_xml_normal, "lists", NULL);
+
+ return svn_cl__error_checked_fputs (sb->data, stdout);
+}
+
+
+static svn_error_t *
 print_dirents_xml (apr_hash_t *dirents,
                    const char *path,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *pool)
 {
- /* Collate whole list into sb before printing. */
- svn_stringbuf_t *sb = svn_stringbuf_create ("", pool);
-
   apr_array_header_t *array;
   int i;
   apr_pool_t *subpool = svn_pool_create (pool);
 
   array = svn_sort__hash (dirents, svn_sort_compare_items_as_paths, pool);
-
- /* "<list path=...>" */
- svn_xml_make_open_tag (&sb, pool, svn_xml_normal, "list",
- "path", path[0] == '\0' ? "." : path,
- NULL);
+
+ {
+ /* "<list path=...>" */
+ svn_stringbuf_t *sb = svn_stringbuf_create ("", pool);
+ svn_xml_make_open_tag (&sb, pool, svn_xml_normal, "list",
+ "path", path[0] == '\0' ? "." : path,
+ NULL);
+ SVN_ERR (svn_cl__error_checked_fputs (sb->data, stdout));
+ }
 
   for (i = 0; i < array->nelts; ++i)
     {
+ svn_stringbuf_t *sb;
       const char *utf8_entryname;
       svn_dirent_t *dirent;
       svn_sort__item_t *item;
@@ -174,6 +191,8 @@ print_dirents_xml (apr_hash_t *dirents,
 
       dirent = apr_hash_get (dirents, utf8_entryname, item->klen);
 
+ sb = svn_stringbuf_create ("", subpool);
+
       /* "<entry ...>" */
       svn_xml_make_open_tag (&sb, subpool, svn_xml_protect_pcdata, "entry",
                              "kind", kind_str (dirent->kind),
@@ -221,14 +240,30 @@ print_dirents_xml (apr_hash_t *dirents,
 
       /* "</entry>" */
       svn_xml_make_close_tag (&sb, subpool, "entry");
+
+ SVN_ERR (svn_cl__error_checked_fputs (sb->data, stdout));
     }
 
   svn_pool_destroy (subpool);
   
- /* "</list>" */
- svn_xml_make_close_tag (&sb, pool, "list");
+ {
+ /* "</list>" */
+ svn_stringbuf_t *sb = svn_stringbuf_create ("", pool);
+ svn_xml_make_close_tag (&sb, pool, "list");
+ SVN_ERR (svn_cl__error_checked_fputs (sb->data, stdout));
+ }
 
- return svn_cmdline_printf (pool, "%s", sb->data);
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+print_footer_xml (apr_pool_t *pool)
+{
+ /* "</lists>" */
+ svn_stringbuf_t *sb = svn_stringbuf_create ("", pool);
+ svn_xml_make_close_tag (&sb, pool, "lists");
+ return svn_cl__error_checked_fputs (sb->data, stdout);
 }
 
 
@@ -262,17 +297,7 @@ svn_cl__ls (apr_getopt_t *os,
          everything in a top-level element. This makes the output in
          its entirety a well-formed XML document. */
       if (! opt_state->incremental)
- {
- svn_stringbuf_t *sb = svn_stringbuf_create ("", pool);
-
- /* <?xml version="1.0" encoding="utf-8"?> */
- svn_xml_make_header (&sb, pool);
-
- /* "<lists>" */
- svn_xml_make_open_tag (&sb, pool, svn_xml_normal, "lists", NULL);
-
- SVN_ERR (svn_cmdline_printf (pool, "%s", sb->data));
- }
+ SVN_ERR (print_header_xml (pool));
     }
   else
     {
@@ -312,12 +337,7 @@ svn_cl__ls (apr_getopt_t *os,
   if (opt_state->xml)
     {
       if (! opt_state->incremental)
- {
- svn_stringbuf_t *sb = svn_stringbuf_create ("", pool);
- /* "</lists>" */
- svn_xml_make_close_tag (&sb, pool, "lists");
- SVN_ERR (svn_cmdline_printf (pool, "%s", sb->data));
- }
+ SVN_ERR (print_footer_xml (pool));
     }
 
   return SVN_NO_ERROR;
Index: subversion/clients/cmdline/util.c
===================================================================
--- subversion/clients/cmdline/util.c (revision 12852)
+++ subversion/clients/cmdline/util.c (working copy)
@@ -634,3 +634,27 @@ svn_cl__may_need_force (svn_error_t *err
 
   return err;
 }
+
+
+svn_error_t *
+svn_cl__error_checked_fputs (const char *string, FILE* stream)
+{
+ /* This function is equal to svn_cmdline_fputs() minus
+ the utf8->local encoding translation */
+
+ /* On POSIX systems, errno will be set on an error in fputs, but this might
+ not be the case on other platforms. We reset errno and only
+ use it if it was set by the below fputs call. Else, we just return
+ a generic error. */
+ errno = 0;
+
+ if (fputs (string, stream) == EOF)
+ {
+ if (errno)
+ return svn_error_wrap_apr (errno, _("Write error"));
+ else
+ return svn_error_create (SVN_ERR_IO_WRITE_ERROR, NULL, NULL);
+ }
+
+ return SVN_NO_ERROR;
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Jan 26 01:22:20 2005

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.