]> git.saurik.com Git - bison.git/commitdiff
Implement @gettext<...@> directive to call gettext from skeletons. It
authorJoel E. Denny <jdenny@ces.clemson.edu>
Thu, 18 Jan 2007 05:14:59 +0000 (05:14 +0000)
committerJoel E. Denny <jdenny@ces.clemson.edu>
Thu, 18 Jan 2007 05:14:59 +0000 (05:14 +0000)
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 `@gettext<' 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 `@gettext<' 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.

ChangeLog
data/bison.m4
data/c++-skel.m4
data/glr.c
data/glr.cc
data/lalr1.cc
src/scan-skel.l
tests/skeletons.at

index 873f2ace636240824ae11fb2eb38a2c26ffa8aa3..c78d94461411ef2fa12fa2ac54f46d038d0708dc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2007-01-18  Joel E. Denny  <jdenny@ces.clemson.edu>
+
+       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 `@gettext<' 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 `@gettext<' 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  <jdenny@ces.clemson.edu>
 
        Implement support for relative and absolute skeleton file names.
index 6d37e9809a1cafd1cb6b3629cce9e7dca8bb2932..adc8d996cdd477f4c5ebae8831c5eb718fb5b54b 100644 (file)
@@ -328,7 +328,7 @@ m4_pushdef([b4_start], m4_car(m4_shift(b4_occurrence)))dnl
 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]],
+                      [[@gettext<%s `%s' is not used@>]],
                       [$1], [b4_user_name])])[]dnl
 m4_popdef([b4_occurrence])dnl
 m4_popdef([b4_user_name])dnl
index 5d6120d1bf5b9dd9049c021abddc3571590febac..920e5b56af54c25874f84fc5d5af835c2f7ecf5c 100644 (file)
@@ -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([[@gettext<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 5a40a3133b36c84230d099788659fe7759757ecc..0fed39388d3bb368a1057374eb6327948a47e788 100644 (file)
@@ -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([[@gettext<non-deterministic push parsers are not yet supported@>]])])
 
 ## ---------------- ##
 ## Default values.  ##
index d33d23e5fd52cd06cbef08c59be26c4328216929..16150b74584dac983cb2678a4c7bee55136c0b9f 100644 (file)
@@ -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 2d53bf9c6403e1c055ce0f22917c2508b4c992bb..5246e0dff16fc80b20a7c1d81704f058d70a7e93 100644 (file)
@@ -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 d9ca8e28c6427d33cad716b9caaf70849c9d4ef8..aab570c604c12355f2f3dd7e135fbe9e5621a12b 100644 (file)
@@ -53,7 +53,7 @@ static void fail_for_at_directive_too_few_args (void);
 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_DIRECTIVE_ARGC_MAX];
 "@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. */
-@[^@{}(\n]* fail_for_invalid_at (yytext);
+@[^<@{}(\n]* fail_for_invalid_at (yytext);
 \n        out_lineno++; ECHO;
 [^@\n]+           ECHO;
 
@@ -101,15 +104,48 @@ static char *at_directive_argv[AT_DIRECTIVE_ARGC_MAX];
   return EOF;
 }
 
-<SC_AT_DIRECTIVE_ARG>{
-  [^@]+ { 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_DIRECTIVE_ARGC_MAX];
         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>{
+  [^@]+ { 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 **outnamep, int *out_linenop)
       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 **outnamep, int *out_linenop)
       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 79f903ee7519a4928b753167c2096cd571b9057b..0a9c3677a20e9d0c1090929645b275a0e82f40a0 100644 (file)
@@ -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]], [[0]],
 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([[@gettext<...@>]])
+
+AT_DATA([[skel.c]],
+[[m4@&t@_divert_push(0)d@&t@nl
+@output(b4_parser_file_name@)d@&t@nl
+b4_warn([[@gettext<cannot close file@>]])d@&t@nl
+`@gettext<cannot close file@>'
+m4@&t@_divert_pop(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