]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Support extraction of contexts in GNOME glib syntax.
authorBruno Haible <bruno@clisp.org>
Thu, 16 Mar 2006 13:10:48 +0000 (13:10 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:13:03 +0000 (12:13 +0200)
NEWS
gettext-tools/doc/ChangeLog
gettext-tools/doc/xgettext.texi
gettext-tools/src/ChangeLog
gettext-tools/src/x-perl.c
gettext-tools/src/xgettext.c
gettext-tools/src/xgettext.h
gettext-tools/tests/ChangeLog
gettext-tools/tests/Makefile.am

diff --git a/NEWS b/NEWS
index 9ff6ae4de4d704b4bf956ae12bc6af2afe4c581f..e49edc4f86232bf6c35eeb42af9696178f09317c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,7 +7,9 @@
       msgid "original"
       msgstr "translation"
   - The xgettext program can be told through the --keyword flag which
-    function/macro argument has the role of a context.
+    function/macro argument has the role of a context.  It also supports
+    the GNOME glib convention to specify the context and original string
+    in the same string literal: "context|original".
   - The (non-public) include file gettext.h defines macros pgettext, dpgettext
     etc. that take a context argument.
   For more information, see the node "Contexts" in the manual.
index e645b48ff4996f8a742324c822362a7a88102307..16df02db44b070c685f151e35a656176bb5c82b7 100644 (file)
@@ -1,3 +1,7 @@
+2006-03-16  Bruno Haible  <bruno@clisp.org>
+
+       * xgettext.texi (--keyword): Document suffix 'g'.
+
 2006-02-26  Bruno Haible  <bruno@clisp.org>
 
        * gettext.texi (Introduction): Fix typo.
index 46106bded20b9284cdbbb862a44bc92f0c1aa6de..61f8e662924b75932393f50a38d3f6aa295fa4f5 100644 (file)
@@ -159,6 +159,10 @@ with plural handling.  Also, if @var{keywordspec} is of the form
 @samp{@var{id}:@var{contextargnum}c,@var{argnum}} or
 @samp{@var{id}:@var{argnum},@var{contextargnum}c}, @code{xgettext} treats
 strings in the @var{contextargnum}th argument as a context specifier.
+And, as a special-purpose support for GNOME, if @var{keywordspec} is of the
+form @samp{@var{id}:@var{argnum}g}, @code{xgettext} recognizes the
+@var{argnum}th argument as a string with context, using the GNOME @code{glib}
+syntax @samp{"msgctxt|msgid"}.
 @*
 Furthermore, if @var{keywordspec} is of the form
 @samp{@var{id}:@dots{},@var{totalnumargs}t}, @code{xgettext} recognizes this
index 2ad82f2a20f879ec87a3ec836db274aa5b8556b2..493cfb12b365ee0f1aa1e2083854b6b4f26fd690 100644 (file)
@@ -1,3 +1,18 @@
+2006-03-16  Bruno Haible  <bruno@clisp.org>
+
+       Handle GNOME glib context syntax.
+       * xgettext.h (struct callshape): Add fields argnum1_glib_context,
+       argnum2_glib_context.
+       (struct partial_call): Add fields argnum1_glib_context,
+       argnum2_glib_context.
+       * xgettext.c (split_keywordspec): Recognize suffix 'g' and set the
+       argnum1_glib_context, argnum2_glib_context fields.
+       (insert_keyword_callshape, arglist_parser_alloc, arglist_parser_clone):
+       Update.
+       (arglist_parser_done): When suffix 'g' was specified, split off the
+       context from the msgid and/or msgid_plural.
+       * x-perl.c (extract_variable): Update.
+
 2006-03-16  Bruno Haible  <bruno@clisp.org>
 
        * xgettext.c (set_format_flags_from_context): Break long line.
index 5981f6b96032808978c66b8194bf83eeaa397868..f59e3d453cbb3afb8cf828af7f7f59da77ba70d9 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext Perl backend.
-   Copyright (C) 2002-2005 Free Software Foundation, Inc.
+   Copyright (C) 2002-2006 Free Software Foundation, Inc.
 
    This file was written by Guido Flohr <guido@imperia.net>, 2002-2003.
 
@@ -1505,6 +1505,8 @@ extract_variable (message_list_ty *mlp, token_ty *tp, int first)
              shapes.shapes[0].argnum1 = 1;
              shapes.shapes[0].argnum2 = 0;
              shapes.shapes[0].argnumc = 0;
+             shapes.shapes[0].argnum1_glib_context = false;
+             shapes.shapes[0].argnum2_glib_context = false;
              shapes.shapes[0].argtotal = 0;
 
              /* Extract a possible string from the key.  Before proceeding
index 1815c8daf7f66e3409bd24849958fb1a81b6edc7..66359027bcb51cc0afdfb3a2d46549edae480728 100644 (file)
@@ -981,6 +981,8 @@ split_keywordspec (const char *spec,
   int argnum1 = 0;
   int argnum2 = 0;
   int argnumc = 0;
+  bool argnum1_glib_context = false;
+  bool argnum2_glib_context = false;
   int argtotal = 0;
 
   /* Start parsing from the end.  */
@@ -988,10 +990,11 @@ split_keywordspec (const char *spec,
   while (p > spec)
     {
       if (isdigit ((unsigned char) p[-1])
-         || ((p[-1] == 'c' || p[-1] == 't')
+         || ((p[-1] == 'c' || p[-1] == 'g' || p[-1] == 't')
              && p - 1 > spec && isdigit ((unsigned char) p[-2])))
        {
          bool contextp = (p[-1] == 'c');
+         bool glibp = (p[-1] == 'g');
          bool totalp = (p[-1] == 't');
 
          do
@@ -1023,7 +1026,9 @@ split_keywordspec (const char *spec,
                    /* At most two normal arguments can be given.  */
                    break;
                  argnum2 = argnum1;
+                 argnum2_glib_context = argnum1_glib_context;
                  argnum1 = arg;
+                 argnum1_glib_context = glibp;
                }
 
              p--;
@@ -1032,10 +1037,16 @@ split_keywordspec (const char *spec,
                  if (argnum1 == 0 && argnum2 == 0)
                    /* At least one non-context argument must be given.  */
                    break;
+                 if (argnumc != 0
+                     && (argnum1_glib_context || argnum2_glib_context))
+                   /* Incompatible ways to specify the context.  */
+                   break;
                  *endp = p;
                  shapep->argnum1 = (argnum1 > 0 ? argnum1 : 1);
                  shapep->argnum2 = argnum2;
                  shapep->argnumc = argnumc;
+                 shapep->argnum1_glib_context = argnum1_glib_context;
+                 shapep->argnum2_glib_context = argnum2_glib_context;
                  shapep->argtotal = argtotal;
                  return;
                }
@@ -1052,6 +1063,8 @@ split_keywordspec (const char *spec,
   shapep->argnum1 = 1;
   shapep->argnum2 = 0;
   shapep->argnumc = 0;
+  shapep->argnum1_glib_context = false;
+  shapep->argnum2_glib_context = false;
   shapep->argtotal = 0;
 }
 
@@ -1090,6 +1103,10 @@ insert_keyword_callshape (hash_table *table,
        if (old_shapes->shapes[i].argnum1 == shape->argnum1
            && old_shapes->shapes[i].argnum2 == shape->argnum2
            && old_shapes->shapes[i].argnumc == shape->argnumc
+           && old_shapes->shapes[i].argnum1_glib_context
+              == shape->argnum1_glib_context
+           && old_shapes->shapes[i].argnum2_glib_context
+              == shape->argnum2_glib_context
            && old_shapes->shapes[i].argtotal == shape->argtotal)
          {
            found = true;
@@ -2288,6 +2305,10 @@ arglist_parser_alloc (message_list_ty *mlp, const struct callshapes *shapes)
          ap->alternative[i].argnumc = shapes->shapes[i].argnumc;
          ap->alternative[i].argnum1 = shapes->shapes[i].argnum1;
          ap->alternative[i].argnum2 = shapes->shapes[i].argnum2;
+         ap->alternative[i].argnum1_glib_context =
+           shapes->shapes[i].argnum1_glib_context;
+         ap->alternative[i].argnum2_glib_context =
+           shapes->shapes[i].argnum2_glib_context;
          ap->alternative[i].argtotal = shapes->shapes[i].argtotal;
          ap->alternative[i].msgctxt = NULL;
          ap->alternative[i].msgctxt_pos.file_name = NULL;
@@ -2329,6 +2350,8 @@ arglist_parser_clone (struct arglist_parser *ap)
       ccp->argnumc = cp->argnumc;
       ccp->argnum1 = cp->argnum1;
       ccp->argnum2 = cp->argnum2;
+      ccp->argnum1_glib_context = cp->argnum1_glib_context;
+      ccp->argnum2_glib_context = cp->argnum2_glib_context;
       ccp->argtotal = cp->argtotal;
       ccp->msgctxt = (cp->msgctxt != NULL ? xstrdup (cp->msgctxt) : NULL);
       ccp->msgctxt_pos = cp->msgctxt_pos;
@@ -2565,6 +2588,76 @@ arglist_parser_done (struct arglist_parser *ap, int argnum)
             Now call remember_a_message.  */
          message_ty *mp;
 
+         /* Split strings in the GNOME glib syntax "msgctxt|msgid".  */
+         if (best_cp->argnum1_glib_context || best_cp->argnum2_glib_context)
+           /* split_keywordspec should not allow the context to be specified
+              in two different ways.  */
+           if (best_cp->msgctxt != NULL)
+             abort ();
+         if (best_cp->argnum1_glib_context)
+           {
+             const char *separator = strchr (best_cp->msgid, '|');
+
+             if (separator == NULL)
+               {
+                 error_with_progname = false;
+                 error (0, 0,
+                        _("%s:%d: warning: missing context for keyword '%.*s'"),
+                        best_cp->msgid_pos.file_name, best_cp->msgid_pos.line_number,
+                        ap->keyword_len, ap->keyword);
+                 error_with_progname = true;
+               }
+             else
+               {
+                 size_t ctxt_len = separator - best_cp->msgid;
+                 char *ctxt = (char *) xmalloc (ctxt_len + 1);
+
+                 memcpy (ctxt, best_cp->msgid, ctxt_len);
+                 ctxt[ctxt_len] = '\0';
+                 best_cp->msgctxt = ctxt;
+                 best_cp->msgid = xstrdup (separator + 1);
+               }
+           }
+         if (best_cp->msgid_plural != NULL && best_cp->argnum2_glib_context)
+           {
+             const char *separator = strchr (best_cp->msgid_plural, '|');
+
+             if (separator == NULL)
+               {
+                 error_with_progname = false;
+                 error (0, 0,
+                        _("%s:%d: warning: missing context for plural argument of keyword '%.*s'"),
+                        best_cp->msgid_plural_pos.file_name,
+                        best_cp->msgid_plural_pos.line_number,
+                        ap->keyword_len, ap->keyword);
+                 error_with_progname = true;
+               }
+             else
+               {
+                 size_t ctxt_len = separator - best_cp->msgid_plural;
+                 char *ctxt = (char *) xmalloc (ctxt_len + 1);
+
+                 memcpy (ctxt, best_cp->msgid_plural, ctxt_len);
+                 ctxt[ctxt_len] = '\0';
+                 if (best_cp->msgctxt == NULL)
+                   best_cp->msgctxt = ctxt;
+                 else
+                   {
+                     if (strcmp (ctxt, best_cp->msgctxt) != 0)
+                       {
+                         error_with_progname = false;
+                         error (0, 0,
+                                _("%s:%d: context mismatch between singular and plural form"),
+                                best_cp->msgid_plural_pos.file_name,
+                                best_cp->msgid_plural_pos.line_number);
+                         error_with_progname = true;
+                       }
+                     free (ctxt);
+                   }
+                 best_cp->msgid_plural = xstrdup (separator + 1);
+               }
+           }
+
          mp = remember_a_message (ap->mlp, best_cp->msgctxt, best_cp->msgid,
                                   best_cp->msgid_context,
                                   &best_cp->msgid_pos,
index fcbde3eefa360269bd22d97b94ce4c5e7cad268b..021cda49235377e8ad9de6178e9dad03db2fbc9d 100644 (file)
@@ -1,5 +1,5 @@
 /* xgettext common functions.
-   Copyright (C) 2001-2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2005-2006 Free Software Foundation, Inc.
    Written by Peter Miller <millerp@canb.auug.org.au>
    and Bruno Haible <haible@clisp.cons.org>, 2001.
 
@@ -54,6 +54,8 @@ struct callshape
   int argnum1; /* argument number to use for msgid */
   int argnum2; /* argument number to use for msgid_plural */
   int argnumc; /* argument number to use for msgctxt */
+  bool argnum1_glib_context; /* argument argnum1 has the syntax "ctxt|msgid" */
+  bool argnum2_glib_context; /* argument argnum2 has the syntax "ctxt|msgid" */
   int argtotal; /* total number of arguments */
 };
 
@@ -251,6 +253,8 @@ struct partial_call
   int argnumc;                  /* number of context argument, 0 when seen */
   int argnum1;                  /* number of singular argument, 0 when seen */
   int argnum2;                  /* number of plural argument, 0 when seen */
+  bool argnum1_glib_context;    /* argument argnum1 has the syntax "ctxt|msgid" */
+  bool argnum2_glib_context;    /* argument argnum2 has the syntax "ctxt|msgid" */
   int argtotal;                 /* total number of arguments, 0 if unspecified */
   char *msgctxt;                /* context - owned string, or NULL */
   lex_pos_ty msgctxt_pos;
index 7915a4593d95036f410b333fe500eaf5ddde251d..c26eb42b037ed35beb3722c69775800f2c8f805e 100644 (file)
@@ -1,3 +1,8 @@
+2006-03-16  Bruno Haible  <bruno@clisp.org>
+
+       * xgettext-c-15: New file.
+       * Makefile.am (TESTS): Add it.
+
 2006-03-11  Bruno Haible  <bruno@clisp.org>
 
        * lang-c: Put the -I flags before ${CFLAGS} ${CPPFLAGS}.
index baa8567def96c0f4a50e31c97be20a6d59478f93..1757fef99dca85a7cb785376eae785f8063cf134 100644 (file)
@@ -64,7 +64,7 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \
        xgettext-awk-1 \
        xgettext-c-1 xgettext-c-2 xgettext-c-3 xgettext-c-4 xgettext-c-5 \
        xgettext-c-6 xgettext-c-7 xgettext-c-8 xgettext-c-9 xgettext-c-10 \
-       xgettext-c-11 xgettext-c-12 xgettext-c-13 xgettext-c-14 \
+       xgettext-c-11 xgettext-c-12 xgettext-c-13 xgettext-c-14 xgettext-c-15 \
        xgettext-csharp-1 xgettext-csharp-2 xgettext-csharp-3 \
        xgettext-csharp-4 xgettext-csharp-5 \
        xgettext-elisp-1 \