bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gettext for skeletons


From: Joel E. Denny
Subject: gettext for skeletons
Date: Thu, 18 Jan 2007 00:15:16 -0500 (EST)

I'm very new to gettext.  It would be nice if someone who understands it 
well would look over this patch.  I'm specifically concerned with the new 
test case where I had to play with environment variables to make gettext 
translate.

In any case, I think this patch is mostly good, so I committed it.

Index: ChangeLog
===================================================================
RCS file: /sources/bison/bison/ChangeLog,v
retrieving revision 1.1668
diff -p -u -r1.1668 ChangeLog
--- ChangeLog   18 Jan 2007 02:18:17 -0000      1.1668
+++ ChangeLog   18 Jan 2007 05:07:44 -0000
@@ -1,3 +1,27 @@
+2007-01-18  Joel E. Denny  <address@hidden>
+
+       Implement @gettext<...@> directive to call gettext from skeletons.  It
+       can be used anywhere including inside arguments of directives of the
+       form @foo(...@).  Eventually, it should be possible to write an
+       xgettext-like utility to extract @gettext<...@> text from skeletons.
+       * data/bison.m4 (b4_check_user_names): Use @gettext<...@> when invoking
+       b4_warn_at since b4_warn_at doesn't invoke gettext anymore.
+       * data/glr.cc, data/lalr1.cc: Likewise but for b4_fatal and
+       b4_complain reporting a push-parsing request or a missing %defines.
+       * src/scan-skel.l (INITIAL): Recognize address@hidden<' to start...
+       (SC_AT_GETTEXT_ARG): ... this new start condition where gettext is
+       invoked.
+       (SC_AT_DIRECTIVE_ARG): Rename to...
+       (SC_AT_DIRECTIVE_ARGS): ... this, and recognize address@hidden<' to 
start
+       SC_AT_GETTEXT_ARG.
+       (at_directive_perform): Don't invoke gettext for @warn(...@),
+       @warn_at(...@), etc.  Instead, let the skeletons decide what should be
+       passed to @gettext<...@>.
+       * tests/skeletons.at (@gettext<...@>): New test case.
+
+       * tests/skeletons.at (installed skeleton file name): Rename to...
+       (installed skeleton file names): ... this.
+
 2007-01-17  Joel E. Denny  <address@hidden>
 
        Implement support for relative and absolute skeleton file names.
Index: data/bison.m4
===================================================================
RCS file: /sources/bison/bison/data/bison.m4,v
retrieving revision 1.12
diff -p -u -r1.12 bison.m4
--- data/bison.m4       16 Jan 2007 06:16:03 -0000      1.12
+++ data/bison.m4       18 Jan 2007 05:07:44 -0000
@@ -328,7 +328,7 @@ m4_pushdef([b4_start], m4_car(m4_shift(b
 m4_pushdef([b4_end], m4_shift(m4_shift(b4_occurrence)))dnl
 m4_ifndef($3[(]m4_quote(b4_user_name)[)],
           [b4_warn_at([b4_start], [b4_end],
-                      [[%s `%s' is not used]],
+                      address@hidden<%s `%s' is not used@>]],
                       [$1], [b4_user_name])])[]dnl
 m4_popdef([b4_occurrence])dnl
 m4_popdef([b4_user_name])dnl
Index: data/c++-skel.m4
===================================================================
RCS file: /sources/bison/bison/data/c++-skel.m4,v
retrieving revision 1.3
diff -p -u -r1.3 c++-skel.m4
--- data/c++-skel.m4    17 Jan 2007 08:36:07 -0000      1.3
+++ data/c++-skel.m4    18 Jan 2007 05:07:44 -0000
@@ -21,7 +21,7 @@
 b4_glr_if(             [m4_define([b4_used_skeleton], 
[b4_pkgdatadir/[glr.cc]])])
 b4_nondeterministic_if([m4_define([b4_used_skeleton], 
[b4_pkgdatadir/[glr.cc]])])
 
-b4_push_if([b4_complain([[C++ push parsers are not supported]])])
+b4_push_if([b4_complain(address@hidden<C++ push parsers are not 
supported@>]])])
 
 m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[lalr1.cc]])
 m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"])
Index: data/glr.c
===================================================================
RCS file: /sources/bison/bison/data/glr.c,v
retrieving revision 1.201
diff -p -u -r1.201 glr.c
--- data/glr.c  17 Jan 2007 08:36:07 -0000      1.201
+++ data/glr.c  18 Jan 2007 05:07:45 -0000
@@ -23,7 +23,7 @@
 m4_include(b4_pkgdatadir/[c.m4])
 
 b4_push_if([
-b4_complain([[non-deterministic push parsers are not yet supported]])])
+b4_complain(address@hidden<non-deterministic push parsers are not yet 
supported@>]])])
 
 ## ---------------- ##
 ## Default values.  ##
Index: data/glr.cc
===================================================================
RCS file: /sources/bison/bison/data/glr.cc,v
retrieving revision 1.36
diff -p -u -r1.36 glr.cc
--- data/glr.cc 17 Jan 2007 08:36:07 -0000      1.36
+++ data/glr.cc 18 Jan 2007 05:07:45 -0000
@@ -53,7 +53,7 @@ m4_define([b4_pure_flag],      [1])
 
 # The header is mandatory.
 b4_defines_if([],
-              [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
+              [b4_fatal([b4_skeleton[: @gettext<using %%defines is 
mandatory@>]])])
 
 m4_include(b4_pkgdatadir/[c++.m4])
 m4_include(b4_pkgdatadir/[location.cc])
Index: data/lalr1.cc
===================================================================
RCS file: /sources/bison/bison/data/lalr1.cc,v
retrieving revision 1.154
diff -p -u -r1.154 lalr1.cc
--- data/lalr1.cc       17 Jan 2007 08:36:07 -0000      1.154
+++ data/lalr1.cc       18 Jan 2007 05:07:45 -0000
@@ -27,7 +27,7 @@ m4_define([b4_namespace],
 
 # The header is mandatory.
 b4_defines_if([],
-              [b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
+              [b4_fatal([b4_skeleton[: @gettext<using %%defines is 
mandatory@>]])])
 
 # Backward compatibility.
 m4_define([b4_location_constructors])
Index: src/scan-skel.l
===================================================================
RCS file: /sources/bison/bison/src/scan-skel.l,v
retrieving revision 1.47
diff -p -u -r1.47 scan-skel.l
--- src/scan-skel.l     17 Jan 2007 08:36:07 -0000      1.47
+++ src/scan-skel.l     18 Jan 2007 05:07:45 -0000
@@ -53,7 +53,7 @@ static void fail_for_at_directive_too_fe
 static void fail_for_invalid_at (char const *at);
 
 /* In SC_AT_DIRECTIVE_ARG context, the name of the directive.  */
-static char *at_directive_name;
+static char *at_directive_name = NULL;
 
 /* Currently, only the @warn, @complain, @fatal, @warn_at, @complain_at, and
    @fatal_at directives take multiple arguments, and the last three already
@@ -63,7 +63,8 @@ static int at_directive_argc = 0;
 static char *at_directive_argv[AT_DIRECTIVE_ARGC_MAX];
 %}
 
-%x SC_AT_DIRECTIVE_ARG
+%x SC_AT_GETTEXT_ARG
+%x SC_AT_DIRECTIVE_ARGS
 %x SC_AT_DIRECTIVE_SKIP_WS
 
 %%
@@ -81,14 +82,16 @@ static char *at_directive_argv[AT_DIRECT
 "@ofile@"  QPUTS (outname);
 "@dir_prefix@" QPUTS (dir_prefix);
 
+"@gettext<" BEGIN SC_AT_GETTEXT_ARG;
+
 @[a-z_]+"(" {
   yytext[yyleng-1] = '\0';
   at_directive_name = xstrdup (yytext);
-  BEGIN SC_AT_DIRECTIVE_ARG;
+  BEGIN SC_AT_DIRECTIVE_ARGS;
 }
 
   /* This pattern must not match more than the previous @ patterns. */
address@hidden@{}(\n]* fail_for_invalid_at (yytext);
address@hidden<@{}(\n]* fail_for_invalid_at (yytext);
 \n        out_lineno++; ECHO;
 address@hidden    ECHO;
 
@@ -101,15 +104,48 @@ static char *at_directive_argv[AT_DIRECT
   return EOF;
 }
 
-<SC_AT_DIRECTIVE_ARG>{
-  address@hidden { STRING_GROW; }
+<SC_AT_GETTEXT_ARG>{
+  "@>" {
+    char *arg;
+    obstack_1grow (&obstack_for_string, '\0');
+    arg = obstack_finish (&obstack_for_string);
+    if (!at_directive_name)
+      {
+        fprintf (yyout, "%s", _(arg));
+        obstack_free (&obstack_for_string, arg);
+        BEGIN INITIAL;
+      }
+    else
+      {
+        char const *translated = _(arg);
+        size_t parent_size = strlen (at_directive_argv[at_directive_argc]);
+        size_t translated_size = strlen (translated);
+        char *copy = xmalloc (parent_size + translated_size + 1);
+        strcpy (copy, at_directive_argv[at_directive_argc]);
+        strcpy (copy + parent_size, translated);
+        obstack_free (&obstack_for_string,
+                      at_directive_argv[at_directive_argc]);
+        obstack_grow (&obstack_for_string, copy,
+                      parent_size + translated_size);
+        free (copy);
+        BEGIN SC_AT_DIRECTIVE_ARGS;
+      }
+  }
+}
 
-  "@@" { obstack_1grow (&obstack_for_string, '@'); }
-  "@{" { obstack_1grow (&obstack_for_string, '['); }
-  "@}" { obstack_1grow (&obstack_for_string, ']'); }
+<SC_AT_DIRECTIVE_ARGS>{
   "@`" /* Emtpy.  Useful for starting an argument
           that begins with whitespace. */
 
+  "@gettext<" {
+    if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX)
+      fail_for_at_directive_too_many_args ();
+    obstack_1grow (&obstack_for_string, '\0');
+    at_directive_argv[at_directive_argc] =
+      obstack_finish (&obstack_for_string);
+    BEGIN SC_AT_GETTEXT_ARG;
+  }
+
   @[,)] {
     if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX)
       fail_for_at_directive_too_many_args ();
@@ -127,21 +163,29 @@ static char *at_directive_argv[AT_DIRECT
         obstack_free (&obstack_for_string, at_directive_argv[0]);
         at_directive_argc = 0;
         free (at_directive_name);
+        at_directive_name = NULL;
         BEGIN INITIAL;
       }
   }
+}
 
+<SC_AT_GETTEXT_ARG,SC_AT_DIRECTIVE_ARGS>{
+  address@hidden { STRING_GROW; }
+  "@@" { obstack_1grow (&obstack_for_string, '@'); }
+  "@{" { obstack_1grow (&obstack_for_string, '['); }
+  "@}" { obstack_1grow (&obstack_for_string, ']'); }
   @.? { fail_for_invalid_at (yytext); }
 }
 
 <SC_AT_DIRECTIVE_SKIP_WS>{
   [ \t\r\n]
-  . { yyless (0); BEGIN SC_AT_DIRECTIVE_ARG; }
+  . { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; }
 }
 
-<SC_AT_DIRECTIVE_ARG,SC_AT_DIRECTIVE_SKIP_WS>{
+<SC_AT_GETTEXT_ARG,SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>{
   <<EOF>> {
-    fatal (_("unclosed %s directive in skeleton"), at_directive_name);
+    fatal (_("unclosed %s directive in skeleton"),
+           at_directive_name ? at_directive_name : "@gettext");
   }
 }
 
@@ -197,21 +241,21 @@ void at_directive_perform (char **outnam
       switch (at_directive_argc)
         {
           case 1:
-            func (_(at_directive_argv[0]));
+            func (at_directive_argv[0]);
             break;
           case 2:
-            func (_(at_directive_argv[0]), at_directive_argv[1]);
+            func (at_directive_argv[0], at_directive_argv[1]);
             break;
           case 3:
-            func (_(at_directive_argv[0]), at_directive_argv[1],
+            func (at_directive_argv[0], at_directive_argv[1],
                   at_directive_argv[2]);
             break;
           case 4:
-            func (_(at_directive_argv[0]), at_directive_argv[1],
+            func (at_directive_argv[0], at_directive_argv[1],
                   at_directive_argv[2], at_directive_argv[3]);
             break;
           case 5:
-            func (_(at_directive_argv[0]), at_directive_argv[1],
+            func (at_directive_argv[0], at_directive_argv[1],
                   at_directive_argv[2], at_directive_argv[3],
                   at_directive_argv[4]);
             break;
@@ -240,21 +284,21 @@ void at_directive_perform (char **outnam
       switch (at_directive_argc)
         {
           case 3:
-            func (loc, _(at_directive_argv[2]));
+            func (loc, at_directive_argv[2]);
             break;
           case 4:
-            func (loc, _(at_directive_argv[2]), at_directive_argv[3]);
+            func (loc, at_directive_argv[2], at_directive_argv[3]);
             break;
           case 5:
-            func (loc, _(at_directive_argv[2]), at_directive_argv[3],
+            func (loc, at_directive_argv[2], at_directive_argv[3],
                   at_directive_argv[4]);
             break;
           case 6:
-            func (loc, _(at_directive_argv[2]), at_directive_argv[3],
+            func (loc, at_directive_argv[2], at_directive_argv[3],
                   at_directive_argv[4], at_directive_argv[5]);
             break;
           case 7:
-            func (loc, _(at_directive_argv[2]), at_directive_argv[3],
+            func (loc, at_directive_argv[2], at_directive_argv[3],
                   at_directive_argv[4], at_directive_argv[5],
                   at_directive_argv[6]);
             break;
Index: tests/skeletons.at
===================================================================
RCS file: /sources/bison/bison/tests/skeletons.at,v
retrieving revision 1.1
diff -p -u -r1.1 skeletons.at
--- tests/skeletons.at  18 Jan 2007 02:18:17 -0000      1.1
+++ tests/skeletons.at  18 Jan 2007 05:07:45 -0000
@@ -16,7 +16,7 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 # 02110-1301, USA.
 
-AT_BANNER([[Skeletons Support.]])
+AT_BANNER([[Skeleton Support.]])
 
 ## ------------------------------ ##
 ## relative skeleton file names.  ##
@@ -78,11 +78,11 @@ AT_CHECK([[cat input-cmd-line.tab.c]], [
 AT_CLEANUP
 
 
-## ------------------------------ ##
-## installed skeleton file name.  ##
-## ------------------------------ ##
+## ------------------------------- ##
+## installed skeleton file names.  ##
+## ------------------------------- ##
 
-AT_SETUP([[installed skeleton file name]])
+AT_SETUP([[installed skeleton file names]])
 
 m4_pushdef([AT_GRAM],
 [[%{
@@ -141,3 +141,35 @@ AT_PARSER_CHECK([[./input-gram]], [[1]],
 m4_popdef([AT_GRAM])
 
 AT_CLEANUP
+
+
+## ---------------- ##
+## @gettext<...@>.  ##
+## ---------------- ##
+
+AT_SETUP(address@hidden<...@>]])
+
+AT_DATA([[skel.c]],
+[[m4@&address@hidden(0)d@&address@hidden
address@hidden(b4_parser_file_name@)d@&address@hidden
+b4_warn(address@hidden<cannot close file@>]])d@&address@hidden
address@hidden<cannot close file@>'
+m4@&address@hidden(0)
+]])
+
+AT_DATA([[input.y]],
+[[%skeleton "./skel.c"
+%%
+start: ;
+]])
+
+AT_CHECK([[LC_ALL= LC_MESSAGES= LANGUAGE=fr LANG=fr_FR bison input.y]], [[0]],
+[],
+[[input.y: AVERTISSEMENT: ne peut fermer le fichier
+]])
+
+AT_CHECK([[cat input.tab.c]], [[0]],
+[[`ne peut fermer le fichier'
+]])
+
+AT_CLEANUP




reply via email to

[Prev in Thread] Current Thread [Next in Thread]