]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Support for user-specified argument numbers for keywords. From Paul Eggert.
authorBruno Haible <bruno@clisp.org>
Fri, 28 Jul 2000 21:11:32 +0000 (21:11 +0000)
committerBruno Haible <bruno@clisp.org>
Fri, 28 Jul 2000 21:11:32 +0000 (21:11 +0000)
doc/gettext.texi
src/ChangeLog
src/xget-lex.c
src/xget-lex.h
src/xgettext.c

index 343ffb41ac311941f04613fc9afe33ffbee75220..870db5bc4b2024f09f2915fb7868ebd806f14cee 100644 (file)
@@ -1859,13 +1859,19 @@ List of directories searched for input files.
 Join messages with existing file.
 
 @item -k @var{word}
-@itemx --keyword[=@var{word}]
-Additonal keyword to be looked for (without @var{word} means not to
+@itemx --keyword[=@var{keywordspec}]
+Additional keyword to be looked for (without @var{keywordspec} means not to
 use default keywords).
 
-The default keywords, which are always looked for if not explicitly
-disabled, are @code{gettext}, @code{dgettext}, @code{dcgettext} and
-@code{gettext_noop}.
+If @var{keywordspec} is a C identifer @var{id}, @code{xgettext} looks
+for strings in the first argument of each call to the function or macro
+@var{id}.  If @var{keywordspec} is of the form
+@samp{@var{id}:@var{argnum}}, @code{xgettext} looks for strings in the
+@var{argnum}th argument of the call.
+
+The default keyword specifications, which are always looked for if not
+explicitly disabled, are @code{gettext}, @code{dgettext:2},
+@code{dcgettext:2} and @code{gettext_noop}.
 
 @item -m [@var{string}]
 @itemx --msgstr-prefix[=@var{string}]
index 4c08e959b481479f09bcf9b0c49c093c7ac8ae52..8ef5a6aff61d6bd1cfa7c6f6a7c6f8951dabbdf2 100644 (file)
@@ -1,3 +1,45 @@
+2000-07-28  Bruno Haible  <haible@clisp.cons.org>
+
+       * xget-lex.h (enum xgettext_token_type_ty): Rename
+       xgettext_token_type_lp/rp to xgettext_token_type_lparen/rparen.
+       * xget-lex.c (enum token_type_ty): Rename token_type_lp/rp to
+       token_type_lparen/rparen.
+       (xgettext_any_keywords): `keywords' is now a hash table.
+       * xgettext.c (construct_header): Change two printf directives %02d
+       to %02ld.
+
+1998-07-17  Paul Eggert  <eggert@twinsun.com>
+
+       Add support for user-specified argument numbers for keywords.
+       Extract all strings from a keyword arg, not just the first one.
+       Handle parenthesized commas inside keyword args correctly.
+       Warn about nested keywords.
+
+       * xgettext.c (scan_c_file):
+       Warn about nested keywords, e.g. _(_("xxx")).
+       Warn also about not-yet-implemented but allowed nesting, e.g.
+       dcgettext(..._("xxx")..., "yyy").
+       Get all strings in a keyword arg, not just the first one.
+       Handle parenthesized commas inside keyword args correctly.
+
+       * xget-lex.h (enum xgettext_token_type_ty):
+       Replace xgettext_token_type_keyword1 and
+       xgettext_token_type_keyword2 with just plain
+       xgettext_token_type_keyword; it now has argnum value.
+       Add xgettext_token_type_rp.
+       (struct xgettext_token_ty): Add argnum member.
+       line_number and file_name are now also set for
+       xgettext_token_type_keyword.
+       (xgettext_lex_keyword): Arg is const char *.
+
+       * xget-lex.c: Include "hash.h".
+       (enum token_type_ty): Add token_type_rp.
+       (keywords): Now a hash table.
+       (phase5_get): Return token_type_rp for ')'.
+       (xgettext_lex, xgettext_lex_keyword): Add support for keyword argnums.
+       (xgettext_lex): Return xgettext_token_type_rp for ')'.
+       Report keyword argnum, line number, and file name back to caller.
+
 2000-05-06  Ulrich Drepper  <drepper@redhat.com>
 
        * Makefile.am (EXTRA_DIST): Replace po-gram.gen.h and po-hash.gen.h
index a838e4cae8b3f1bff90cbb02bed6ef0b9f95181a..3fa5cf6d22c6d74be3cecef36e6280af04ba8e18 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU gettext - internationalization aids
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
 
@@ -33,6 +33,7 @@
 #include "error.h"
 #include "system.h"
 #include "libgettext.h"
+#include "hash.h"
 #include "str-list.h"
 #include "xget-lex.h"
 
@@ -82,7 +83,8 @@ enum token_type_ty
   token_type_eof,
   token_type_eoln,
   token_type_hash,
-  token_type_lp,
+  token_type_lparen,
+  token_type_rparen,
   token_type_comma,
   token_type_name,
   token_type_number,
@@ -109,7 +111,7 @@ static FILE *fp;
 static int trigraphs;
 static int cplusplus_comments;
 static string_list_ty *comment;
-static string_list_ty *keywords;
+static hash_table keywords;
 static int default_keywords = 1;
 
 /* These are for tracking whether comments count as immediately before
@@ -938,7 +940,11 @@ phase5_get (tp)
       return;
 
     case '(':
-      tp->type = token_type_lp;
+      tp->type = token_type_lparen;
+      return;
+
+    case ')':
+      tp->type = token_type_rparen;
       return;
 
     case ',':
@@ -1179,6 +1185,7 @@ xgettext_lex (tp)
   while (1)
     {
       token_ty token;
+      void *keyword_value;
 
       phase8_get (&token);
       switch (token.type)
@@ -1213,27 +1220,36 @@ xgettext_lex (tp)
          if (default_keywords)
            {
              xgettext_lex_keyword ("gettext");
-             xgettext_lex_keyword ("dgettext");
-             xgettext_lex_keyword ("dcgettext");
+             xgettext_lex_keyword ("dgettext:2");
+             xgettext_lex_keyword ("dcgettext:2");
              xgettext_lex_keyword ("gettext_noop");
              default_keywords = 0;
            }
 
-         if (string_list_member (keywords, token.string))
+         if (find_entry (&keywords, token.string, strlen (token.string),
+                         &keyword_value)
+             == 0)
            {
-             tp->type = (strcmp (token.string, "dgettext") == 0
-                         || strcmp (token.string, "dcgettext") == 0)
-               ? xgettext_token_type_keyword2 : xgettext_token_type_keyword1;
+             tp->type = xgettext_token_type_keyword;
+             tp->argnum = (int) (long) keyword_value;
+             tp->line_number = token.line_number;
+             tp->file_name = logical_file_name;
            }
          else
            tp->type = xgettext_token_type_symbol;
          free (token.string);
          return;
 
-       case token_type_lp:
+       case token_type_lparen:
+         last_non_comment_line = newline_count;
+
+         tp->type = xgettext_token_type_lparen;
+         return;
+
+       case token_type_rparen:
          last_non_comment_line = newline_count;
 
-         tp->type = xgettext_token_type_lp;
+         tp->type = xgettext_token_type_rparen;
          return;
 
        case token_type_comma:
@@ -1263,16 +1279,32 @@ xgettext_lex (tp)
 
 void
 xgettext_lex_keyword (name)
-     char *name;
+     const char *name;
 {
   if (name == NULL)
     default_keywords = 0;
   else
     {
-      if (keywords == NULL)
-       keywords = string_list_alloc ();
+      int argnum;
+      size_t len;
+      const char *sp;
+
+      if (keywords.table == NULL)
+       init_hash (&keywords, 100);
+
+      sp = strchr (name, ':');
+      if (sp)
+       {
+         len = sp - name;
+         argnum = atoi (sp + 1);
+       }
+      else
+       {
+         len = strlen (name);
+         argnum = 1;
+       }
 
-      string_list_append_unique (keywords, name);
+      insert_entry (&keywords, name, len, (void *) (long) argnum);
     }
 }
 
@@ -1280,7 +1312,7 @@ xgettext_lex_keyword (name)
 int
 xgettext_any_keywords ()
 {
-  return keywords != NULL || default_keywords;
+  return (keywords.filled > 0) || default_keywords;
 }
 
 
index 18491ca73aa1b79086f857fd98fb2130c686aec4..ccdaf342575cde33a0a82dc4ca14f2202eb7522d 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU gettext - internationalization aids
-   Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1998, 2000 Free Software Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
 
@@ -23,9 +23,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 enum xgettext_token_type_ty
 {
   xgettext_token_type_eof,
-  xgettext_token_type_keyword1,
-  xgettext_token_type_keyword2,
-  xgettext_token_type_lp,
+  xgettext_token_type_keyword,
+  xgettext_token_type_lparen,
+  xgettext_token_type_rparen,
   xgettext_token_type_comma,
   xgettext_token_type_string_literal,
   xgettext_token_type_symbol
@@ -37,8 +37,15 @@ struct xgettext_token_ty
 {
   xgettext_token_type_ty type;
 
-  /* These 3 are only set for xgettext_token_type_string_literal.  */
+  /* This field is used only for xgettext_token_type_keyword.  */
+  int argnum;
+
+  /* This field is used only for xgettext_token_type_string_literal.  */
   char *string;
+
+  /* These fields are only for
+       xgettext_token_type_keyword,
+       xgettext_token_type_string_literal.  */
   int line_number;
   char *file_name;
 };
@@ -50,7 +57,7 @@ void xgettext_lex PARAMS ((xgettext_token_ty *__tp));
 const char *xgettext_lex_comment PARAMS ((size_t __n));
 void xgettext_lex_comment_reset PARAMS ((void));
 /* void xgettext_lex_filepos PARAMS ((char **, int *)); FIXME needed?  */
-void xgettext_lex_keyword PARAMS ((char *__name));
+void xgettext_lex_keyword PARAMS ((const char *__name));
 int xgettext_any_keywords PARAMS ((void));
 void xgettext_lex_cplusplus PARAMS ((void));
 void xgettext_lex_trigraphs PARAMS ((void));
index 552a25867300f749cc64206402bd7902579e4d18..db8113f4022fa9c7da83c0ddaea42a78d54563c9 100644 (file)
@@ -1,5 +1,5 @@
 /* Extracts strings from C source file to Uniforum style .po file.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, April 1995.
 
    This program is free software; you can redistribute it and/or modify
@@ -842,6 +842,8 @@ scan_c_file(filename, mlp, is_cpp_file)
      int is_cpp_file;
 {
   int state;
+  int commas_to_skip = 0;      /* defined only when in states 1 and 2 */
+  int paren_nesting = 0;       /* defined only when in state 2 */
 
   /* Inform scanner whether we have C++ files or not.  */
   if (is_cpp_file)
@@ -861,66 +863,87 @@ scan_c_file(filename, mlp, is_cpp_file)
    {
      xgettext_token_ty token;
 
-     /* A simple state machine is used to do the recognising:
+     /* A state machine is used to do the recognising:
         State 0 = waiting for something to happen
-        State 1 = seen one of our keywords with string in first parameter
-        State 2 = was in state 1 and now saw a left paren
-       State 3 = seen one of our keywords with string in second parameter
-       State 4 = was in state 3 and now saw a left paren
-       State 5 = waiting for comma after being in state 4
-       State 6 = saw comma after being in state 5  */
+        State 1 = seen one of our keywords
+        State 2 = waiting for part of an argument */
      xgettext_lex (&token);
      switch (token.type)
        {
-       case xgettext_token_type_keyword1:
+       case xgettext_token_type_keyword:
+        if (!extract_all && state == 2)
+          {
+            if (commas_to_skip == 0)
+              {
+                error (0, 0,
+                       _("%s:%d: warning: keyword nested in keyword arg"),
+                       token.file_name, token.line_number);
+                continue;
+              }
+
+            /* Here we should nest properly, but this would require a
+               potentially unbounded stack.  We haven't run across an
+               example that needs this functionality yet.  For now,
+               we punt and forget the outer keyword.  */
+            error (0, 0,
+                   _("%s:%d: warning: keyword between outer keyword and its arg"),
+                   token.file_name, token.line_number);
+          }
+        commas_to_skip = token.argnum - 1;
         state = 1;
         continue;
 
-       case xgettext_token_type_keyword2:
-        state = 3;
-        continue;
-
-       case xgettext_token_type_lp:
+       case xgettext_token_type_lparen:
         switch (state)
           {
           case 1:
+            paren_nesting = 0;
             state = 2;
             break;
-          case 3:
-            state = 4;
+          case 2:
+            paren_nesting++;
             break;
-          default:
-            state = 0;
           }
         continue;
 
-       case xgettext_token_type_comma:
-        state = state == 5 ? 6 : 0;
+       case xgettext_token_type_rparen:
+        if (state == 2 && paren_nesting != 0)
+          paren_nesting--;
+        else
+          state = 0;
         continue;
 
-       case xgettext_token_type_string_literal:
-        if (extract_all || state == 2 || state == 6)
+       case xgettext_token_type_comma:
+        if (state == 2 && commas_to_skip != 0)
           {
-            remember_a_message (mlp, &token);
-            state = 0;
+            if (paren_nesting == 0)
+              commas_to_skip--;
           }
+        else
+          state = 0;
+        continue;
+
+       case xgettext_token_type_string_literal:
+        if (extract_all || (state == 2 && commas_to_skip == 0))
+          remember_a_message (mlp, &token);
         else
           {
             free (token.string);
-            state = (state == 4 || state == 5) ? 5 : 0;
+            if (state == 1)
+              state = 0;
           }
         continue;
 
        case xgettext_token_type_symbol:
-        state = (state == 4 || state == 5) ? 5 : 0;
-        continue;
-
-       default:
-        state = 0;
+        if (state == 1)
+          state = 0;
         continue;
 
        case xgettext_token_type_eof:
         break;
+
+       default:
+        abort ();
        }
      break;
    }
@@ -1247,7 +1270,7 @@ FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n");
 
   asprintf (&msgstr, "\
 Project-Id-Version: PACKAGE VERSION\n\
-POT-Creation-Date: %d-%02d-%02d %02d:%02d%c%02d%02d\n\
+POT-Creation-Date: %d-%02d-%02d %02d:%02d%c%02ld%02ld\n\
 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n\
 Last-Translator: FULL NAME <EMAIL@ADDRESS>\n\
 Language-Team: LANGUAGE <LL@li.org>\n\