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

Make option parsing error messages translatable

From: Mattias Engdegård <mattiase_at_bredband.net>
Date: Thu, 2 May 2013 22:45:00 +0200

It is quite annoying that some of the more common error messages, the

svn: invalid option: --gurgle

kind, are entirely untranslatable because they are printed directly by
APR which does not have any concept of translation at all. (This was
reported before but met with silence: http://svn.haxx.se/dev/archive-2008-05/1445.shtml)

It is not easy to fix it in a clean way; ideally, APR would return a
detailed error code together with the required string parameters, but
it doesn't. Even if we did change APR to that effect, it would be an
incompatibility requiring a new APR version for use with Subversion.

This patch, instead, installs an apr_getopt_err_fn_t, acting as a
replacement for fprintf. It is admittedly a hack, but quite a
localised one -- it doesn't foul up any other code -- and does not
have any negative effects that I can think of. In short, it should be
a strict improvement.

Should APR's getopt error strings change, all that will happen is that
they are shown untranslated, just like any other translated strings.

Index: subversion/libsvn_subr/cmdline.c
===================================================================
--- subversion/libsvn_subr/cmdline.c (revision 1478474)
+++ subversion/libsvn_subr/cmdline.c (working copy)
@@ -634,6 +634,65 @@
   return SVN_NO_ERROR;
 }
 
+/* Registered as apr_getopt_t->errfn, this fprintf-compatible function
+ is called by APR to emit option parsing error messages. We
+ intercept some of those here in order to make them available for
+ translation. */
+static void
+emit_option_error(void *baton, const char *fmt, ...)
+{
+ apr_pool_t *pool = baton;
+ svn_boolean_t match = TRUE;
+ svn_error_t *err = NULL;
+ va_list va;
+ va_start(va, fmt);
+ if (strcmp(fmt, "%s: %s: %s\n") == 0)
+ {
+ const char *prog = va_arg(va, const char *);
+ const char *msg = va_arg(va, const char *);
+ const char *par = va_arg(va, const char *);
+ if (strcmp(msg, "invalid option") == 0)
+ err = svn_cmdline_fprintf(stderr, pool,
+ _("%s: invalid option: %s\n"), prog, par);
+ else if (strcmp(msg, "missing argument") == 0)
+ err = svn_cmdline_fprintf(stderr, pool,
+ _("%s: missing argument: %s\n"), prog, par);
+ else if (strcmp(msg, "erroneous argument") == 0)
+ err = svn_cmdline_fprintf(stderr, pool,
+ _("%s: erroneous argument: %s\n"), prog, par);
+ else
+ match = FALSE;
+ }
+ else if (strcmp(fmt, "%s: %s: %c\n") == 0)
+ {
+ const char *prog = va_arg(va, const char *);
+ const char *msg = va_arg(va, const char *);
+ int par = va_arg(va, int);
+ if (strcmp(msg, "invalid option character") == 0)
+ err = svn_cmdline_fprintf(stderr, pool,
+ _("%s: invalid option character: %c\n"),
+ prog, par);
+ else if (strcmp(msg, "missing argument") == 0)
+ err = svn_cmdline_fprintf(stderr, pool,
+ _("%s: missing argument: %c\n"), prog, par);
+ else
+ match = FALSE;
+ }
+ else
+ match = FALSE;
+
+ if (err)
+ svn_error_clear(err);
+
+ if (!match)
+ {
+ /* This is what apr_getopt normally does with error messages, so it
+ should be safe. */
+ vfprintf(stderr, fmt, va);
+ }
+ va_end(va);
+}
+
 svn_error_t *
 svn_cmdline__getopt_init(apr_getopt_t **os,
                          int argc,
@@ -644,6 +703,8 @@
   if (apr_err)
     return svn_error_wrap_apr(apr_err,
                               _("Error initializing command line arguments"));
+ (*os)->errfn = emit_option_error;
+ (*os)->errarg = pool;
   return SVN_NO_ERROR;
 }
 

Received on 2013-05-02 22:45:36 CEST

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