]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Support for extracted-comments per keyword.
authorBruno Haible <bruno@clisp.org>
Mon, 20 Mar 2006 13:14:25 +0000 (13:14 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:13:04 +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 ae78a405e962e4c06a75bcaa2653811305e5977e..5a2530a155bdad4b17de98a8bc2aa33ad3c54dd0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -33,6 +33,9 @@
 * msggrep has a new option -X/--extracted-comment that allows to search for a
   pattern in the extracted comments.
 
+* xgettext's --keyword now allows to specify an extracted comment on the
+  command line, rather than in program's source code.
+
 * msgmerge is much faster now, when using a large compendium.
 
 * Programming languages support:
index 1473385d95431c76b0922a097009b0261a131290..e96f8f6b0ce496d3b66cf48f4818539526740aa2 100644 (file)
@@ -1,3 +1,7 @@
+2006-03-19  Bruno Haible  <bruno@clisp.org>
+
+       * xgettext.texi (--keyword): Document the extracted comments syntax.
+
 2006-03-16  Bruno Haible  <bruno@clisp.org>
 
        * gettext.texi (PO Files): Clarify the terms "automatic comments" and
index 61f8e662924b75932393f50a38d3f6aa295fa4f5..e8e2b00ed5c242ee9c6266f6fdc7c09674557358 100644 (file)
@@ -170,6 +170,13 @@ argument specification only if the number of actual arguments is equal to
 @var{totalnumargs}.  This is useful for disambiguating overloaded function
 calls in C++.
 @*
+Finally, if @var{keywordspec} is of the form
+@samp{@var{id}:@var{argnum}...,"@var{xcomment}"}, @code{xgettext}, when
+extracting a message from the specified argument strings, adds an extracted
+comment @var{xcomment} to the message.  Note that when used through a normal
+shell command line, the double-quotes around the @var{xcomment} need to be
+escaped.
+@*
 The default keyword specifications, which are always looked for if not
 explicitly disabled, are @code{gettext}, @code{dgettext:2},
 @code{dcgettext:2}, @code{ngettext:1,2}, @code{dngettext:2,3},
index 05e1eee23d7879e31d91b3a21d45950936f5c83b..3530975c34bf0f029126dc9f6757c173c9149ac4 100644 (file)
@@ -1,3 +1,15 @@
+2006-03-19  Bruno Haible  <bruno@clisp.org>
+
+       * xgettext.h (struct callshape): New field 'xcomments'.
+       (struct partial_call): New field 'xcomments'.
+       * xgettext.c (split_keywordspec): Accept the ID:ARGNUM...,"XCOMMENT"
+       syntax.
+       (insert_keyword_callshape): Store the xcomments from the new shape.
+       (arglist_parser_alloc, arglist_parser_clone): Update.
+       (arglist_parser_done): After calling remember_a_message, attach the
+       specified extracted comments.
+       * x-perl.c (extract_variable): Update.
+
 2006-03-19  Bruno Haible  <bruno@clisp.org>
 
        * xgettext.c (arglist_parser_done): Use error_at_line instead of error.
index f59e3d453cbb3afb8cf828af7f7f59da77ba70d9..10b9337291c25c9db35a17f4de6b6f47caf3f945 100644 (file)
@@ -1508,6 +1508,7 @@ extract_variable (message_list_ty *mlp, token_ty *tp, int first)
              shapes.shapes[0].argnum1_glib_context = false;
              shapes.shapes[0].argnum2_glib_context = false;
              shapes.shapes[0].argtotal = 0;
+             string_list_init (&shapes.shapes[0].xcomments);
 
              /* Extract a possible string from the key.  Before proceeding
                 we check whether the open curly is followed by a symbol and
index f936d9a59c75677ed29b4d48d5e49c8a15c80760..1fbda0b3525e23b372452a87d8aec48e09df0d0a 100644 (file)
@@ -984,6 +984,9 @@ split_keywordspec (const char *spec,
   bool argnum1_glib_context = false;
   bool argnum2_glib_context = false;
   int argtotal = 0;
+  string_list_ty xcomments;
+
+  string_list_init (&xcomments);
 
   /* Start parsing from the end.  */
   p = spec + strlen (spec);
@@ -1030,32 +1033,73 @@ split_keywordspec (const char *spec,
                  argnum1 = arg;
                  argnum1_glib_context = glibp;
                }
+           }
+         else
+           break;
+       }
+      else if (p[-1] == '"')
+       {
+         const char *xcomment_end;
+
+         p--;
+         xcomment_end = p;
+
+         while (p > spec && p[-1] != '"')
+           p--;
+
+         if (p > spec /* && p[-1] == '"' */)
+           {
+             const char *xcomment_start;
 
+             xcomment_start = p;
              p--;
-             if (*p == ':')
+             if (p > spec && (p[-1] == ',' || p[-1] == ':'))
                {
-                 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;
+                 size_t xcomment_len = xcomment_end - xcomment_start;
+                 char *xcomment = (char *) xmalloc (xcomment_len + 1);
+
+                 memcpy (xcomment, xcomment_start, xcomment_len);
+                 xcomment[xcomment_len] = '\0';
+                 string_list_append (&xcomments, xcomment);
                }
+             else
+               break;
            }
          else
            break;
        }
       else
        break;
+
+      /* Here an element of the comma-separated list has been parsed.  */
+      if (!(p > spec && (p[-1] == ',' || p[-1] == ':')))
+       abort ();
+      p--;
+      if (*p == ':')
+       {
+         size_t i;
+
+         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;
+         /* Reverse the order of the xcomments.  */
+         string_list_init (&shapep->xcomments);
+         for (i = xcomments.nitems; i > 0; )
+           string_list_append (&shapep->xcomments, xcomments.item[--i]);
+         string_list_destroy (&xcomments);
+         return;
+       }
     }
 
   /* Couldn't parse the desired syntax.  */
@@ -1066,6 +1110,8 @@ split_keywordspec (const char *spec,
   shapep->argnum1_glib_context = false;
   shapep->argnum2_glib_context = false;
   shapep->argtotal = 0;
+  string_list_init (&shapep->xcomments);
+  string_list_destroy (&xcomments);
 }
 
 
@@ -1109,6 +1155,7 @@ insert_keyword_callshape (hash_table *table,
               == shape->argnum2_glib_context
            && old_shapes->shapes[i].argtotal == shape->argtotal)
          {
+           old_shapes->shapes[i].xcomments = shape->xcomments;
            found = true;
            break;
          }
@@ -2310,6 +2357,7 @@ arglist_parser_alloc (message_list_ty *mlp, const struct callshapes *shapes)
          ap->alternative[i].argnum2_glib_context =
            shapes->shapes[i].argnum2_glib_context;
          ap->alternative[i].argtotal = shapes->shapes[i].argtotal;
+         ap->alternative[i].xcomments = shapes->shapes[i].xcomments;
          ap->alternative[i].msgctxt = NULL;
          ap->alternative[i].msgctxt_pos.file_name = NULL;
          ap->alternative[i].msgctxt_pos.line_number = (size_t)(-1);
@@ -2353,6 +2401,7 @@ arglist_parser_clone (struct arglist_parser *ap)
       ccp->argnum1_glib_context = cp->argnum1_glib_context;
       ccp->argnum2_glib_context = cp->argnum2_glib_context;
       ccp->argtotal = cp->argtotal;
+      ccp->xcomments = cp->xcomments;
       ccp->msgctxt = (cp->msgctxt != NULL ? xstrdup (cp->msgctxt) : NULL);
       ccp->msgctxt_pos = cp->msgctxt_pos;
       ccp->msgid = (cp->msgid != NULL ? xstrdup (cp->msgid) : NULL);
@@ -2669,6 +2718,32 @@ arglist_parser_done (struct arglist_parser *ap, int argnum)
                                       best_cp->msgid_plural_context,
                                       &best_cp->msgid_plural_pos,
                                       NULL);
+         if (best_cp->xcomments.nitems > 0)
+           {
+             /* Add best_cp->xcomments to mp->comment_dot, unless already
+                present.  */
+             size_t i;
+
+             for (i = 0; i < best_cp->xcomments.nitems; i++)
+               {
+                 const char *xcomment = best_cp->xcomments.item[i];
+                 bool found = false;
+
+                 if (mp->comment_dot != NULL)
+                   {
+                     size_t j;
+
+                     for (j = 0; j < mp->comment_dot->nitems; j++)
+                       if (strcmp (xcomment, mp->comment_dot->item[j]) == 0)
+                         {
+                           found = true;
+                           break;
+                         }
+                   }
+                 if (!found)
+                   message_comment_dot_append (mp, xcomment);
+               }
+           }
        }
     }
   else
index 021cda49235377e8ad9de6178e9dad03db2fbc9d..f95b70881c567c3232682f455430b0f4addc0f49 100644 (file)
@@ -57,6 +57,7 @@ struct callshape
   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 */
+  string_list_ty xcomments; /* auto-extracted comments */
 };
 
 /* Split keyword spec into keyword, argnum1, argnum2, argnumc.  */
@@ -256,6 +257,7 @@ struct partial_call
   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 */
+  string_list_ty xcomments;     /* auto-extracted comments */
   char *msgctxt;                /* context - owned string, or NULL */
   lex_pos_ty msgctxt_pos;
   char *msgid;                  /* msgid - owned string, or NULL */
index f794f27bb1a2d14b9fc9e01317633f29190b12cf..29ad8883882149d174a053d7f59e65a7114808a1 100644 (file)
@@ -1,3 +1,8 @@
+2006-03-19  Bruno Haible  <bruno@clisp.org>
+
+       * xgettext-9: New file.
+       * Makefile.am (TESTS): Add it.
+
 2006-03-16  Bruno Haible  <bruno@clisp.org>
 
        * msggrep-8: New file.
index 9a48e17b79363f55e8749449a6b46c226658e978..9a187ae52d24d7af93c9b1fba38ec43e55b0cb9c 100644 (file)
@@ -61,7 +61,7 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \
        msgunfmt-tcl-1 \
        msguniq-1 msguniq-2 msguniq-3 msguniq-4 msguniq-5 \
        xgettext-1 xgettext-2 xgettext-3 xgettext-4 xgettext-5 xgettext-6 \
-       xgettext-7 xgettext-8 \
+       xgettext-7 xgettext-8 xgettext-9 \
        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 \