]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Add support for FPC's RST files.
authorBruno Haible <bruno@clisp.org>
Sat, 20 Oct 2001 13:06:20 +0000 (13:06 +0000)
committerBruno Haible <bruno@clisp.org>
Sat, 20 Oct 2001 13:06:20 +0000 (13:06 +0000)
src/ChangeLog
src/Makefile.am
src/po-hash-gen.y
src/po.c
src/po.h
src/read-po.c
src/write-po.c
src/x-po.c
src/x-rst.c [new file with mode: 0644]
src/x-rst.h [new file with mode: 0644]
src/xgettext.c

index 871082c9d0a929e1d8262f6ab04aff539ee6a496..fac6b35abc0cdc6c6dd0e57ba5403c0d42a56695 100644 (file)
@@ -1,3 +1,32 @@
+2001-09-19  Bruno Haible  <haible@clisp.cons.org>
+
+       * po-hash-gen.y (number): Change type from 'int' to 'size_t'.
+       (filepos): Accept strings without line number.
+       (yylex): Change n from 'int' to 'size_t'.
+       * po.h (po_method_ty): In field comment_filepos, change line's type
+       from 'int' to 'size_t'.
+       (po_callback_comment_filepos): Change line's type from 'int' to
+       'size_t'.
+       * read-po.c (readall_comment_filepos): Likewise.
+       * x-po.c (extract_comment_filepos): Likewise.
+       * po.c (po_comment_filepos): Likewise.
+       (po_callback_comment_filepos): Likewise.
+       (po_callback_comment): Reduce the possibility that po_hash succeeds
+       if the comment is not a Sun file position comment.
+
+2001-09-16  Bruno Haible  <haible@clisp.cons.org>
+
+       * x-rst.h: New file.
+       * x-rst.c: New file.
+       * xgettext.c: Include x-rst.h.
+       (scan_rst_file): New function.
+       (language_to_scanner): Add RST rule.
+       (extension_to_language): Add RST rule.
+       * write-po.c (message_print): Don't print the line number if it is
+       = (size_t)(-1).
+       * Makefile.am (noinst_HEADERS): Add x-rst.h.
+       (xgettext_SOURCES): Add x-rst.c.
+
 2001-09-20  Bruno Haible  <haible@clisp.cons.org>
 
        * format-pascal.c: New file.
index 73846cd51ffb0f58590a06df701bb58c67766b79..5ea14dc7f3faccfc95523185378a8150506ed98d 100644 (file)
@@ -27,7 +27,7 @@ noinst_HEADERS = pos.h message.h po-gram.h po-hash.h po-charset.h po-lex.h \
 po.h open-po.h read-po.h str-list.h write-po.h dir-list.h file-list.h \
 po-gram-gen.h po-hash-gen.h msgl-charset.h msgl-iconv.h msgl-ascii.h \
 msgl-cat.h msgfmt.h read-mo.h write-mo.h xgettext.h x-c.h x-po.h x-java.h \
-x-ycp.h
+x-ycp.h x-rst.h
 
 EXTRA_DIST = FILES
 
@@ -69,7 +69,7 @@ msgcmp_SOURCES    = msgcmp.c    $(COMMON_SOURCES)
 msgfmt_SOURCES    = msgfmt.c    $(COMMON_SOURCES) msgl-ascii.c msgl-iconv.c write-mo.c write-java.c plural.c $(FORMAT_SOURCES)
 msgmerge_SOURCES  = msgmerge.c  $(COMMON_SOURCES) msgl-ascii.c write-po.c read-po.c
 msgunfmt_SOURCES  = msgunfmt.c  $(COMMON_SOURCES) msgl-ascii.c write-po.c read-po.c read-mo.c read-java.c
-xgettext_SOURCES  = xgettext.c  $(COMMON_SOURCES) msgl-ascii.c write-po.c file-list.c x-c.c x-po.c x-java.l x-ycp.c $(FORMAT_SOURCES)
+xgettext_SOURCES  = xgettext.c  $(COMMON_SOURCES) msgl-ascii.c write-po.c file-list.c x-c.c x-po.c x-java.l x-ycp.c x-rst.c $(FORMAT_SOURCES)
 msgattrib_SOURCES = msgattrib.c $(COMMON_SOURCES) msgl-ascii.c write-po.c read-po.c
 msgcat_SOURCES    = msgcat.c    $(COMMON_SOURCES) msgl-ascii.c write-po.c read-po.c msgl-iconv.c msgl-cat.c file-list.c
 msgcomm_SOURCES   = msgcomm.c   $(COMMON_SOURCES) msgl-ascii.c write-po.c read-po.c msgl-iconv.c msgl-cat.c file-list.c
index 90b770735e616ed9343645c60a3dff1b471303dc..22947e1a89c8f7667b8a76178001226aa40b9639 100644 (file)
@@ -92,7 +92,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 %union
 {
   char *string;
-  int number;
+  size_t number;
 }
 
 %type <number> NUMBER
@@ -140,6 +140,12 @@ filepos
                  po_callback_comment_filepos ($1, $3);
                  free ($1);
                }
+       | STRING
+               {
+                 /* GNU style, without line number (e.g. from Pascal .rst) */
+                 po_callback_comment_filepos ($1, (size_t)(-1));
+                 free ($1);
+               }
        | FILE_KEYWORD COLON STRING COMMA LINE_KEYWORD COLON NUMBER
                {
                  /* SunOS style */
@@ -169,7 +175,7 @@ yylex ()
   static char *buf;
   static size_t bufmax;
   size_t bufpos;
-  int n;
+  size_t n;
   int c;
 
   for (;;)
index 589d36eefc0c2526c42105d99b0baa36f97bfa7e..f8ea286934364d9b594056e5ef8f1351f0df528d 100644 (file)
--- a/src/po.c
+++ b/src/po.c
@@ -48,7 +48,7 @@ static void po_directive_message PARAMS ((po_ty *pop, char *msgid,
 static void po_comment PARAMS ((po_ty *pop, const char *s));
 static void po_comment_dot PARAMS ((po_ty *pop, const char *s));
 static void po_comment_filepos PARAMS ((po_ty *pop, const char *name,
-                                       int line));
+                                       size_t line));
 static void po_comment_special PARAMS ((po_ty *pop, const char *s));
 
 /* Local variables.  */
@@ -269,6 +269,7 @@ po_callback_comment (s)
         memory leaks on failed parses.  If the parse succeeds, the
         appropriate callback will be invoked.  */
       if (s[0] == ' ' && (s[1] == 'F' || s[1] == 'f') && s[2] == 'i'
+         && s[3] == 'l' && s[4] == 'e' && s[5] == ':'
          && po_hash (s) == 0)
        /* Do nothing, it is a Sun-style file pos line.  */ ;
       else
@@ -281,7 +282,7 @@ static void
 po_comment_filepos (pop, name, line)
      po_ty *pop;
      const char *name;
-     int line;
+     size_t line;
 {
   if (pop->method->comment_filepos)
     pop->method->comment_filepos (pop, name, line);
@@ -291,7 +292,7 @@ po_comment_filepos (pop, name, line)
 void
 po_callback_comment_filepos (name, line)
      const char *name;
-     int line;
+     size_t line;
 {
   /* assert(callback_arg); */
   po_comment_filepos (callback_arg, name, line);
index 30440c58a665c167e5dd2c164d75f8c68de1a8cf..35e20127e1bd8d04ef1b36a62097a597d3eded33 100644 (file)
--- a/src/po.h
+++ b/src/po.h
@@ -91,7 +91,7 @@ struct po_method_ty
      they will be accumulated, and added to the next message
      definition seen.  Or completely ignored.  */
   void (*comment_filepos) PARAMS ((struct po_ty *pop, const char *s,
-                                  int line));
+                                  size_t line));
 
   /* What to do with a comment that starts with a `!' - this is a
      special comment.  One of the possible uses is to indicate a
@@ -147,7 +147,7 @@ extern void po_callback_message PARAMS ((char *msgid, lex_pos_ty *msgid_pos,
                                         bool obsolete));
 extern void po_callback_comment PARAMS ((const char *s));
 extern void po_callback_comment_dot PARAMS ((const char *s));
-extern void po_callback_comment_filepos PARAMS ((const char *s, int line));
+extern void po_callback_comment_filepos PARAMS ((const char *s, size_t line));
 
 /* Parse a special comment and put the result in *fuzzyp, formatp, *wrapp.  */
 extern void po_parse_comment_special PARAMS ((const char *s, bool *fuzzyp,
index ad540f6d3be203fd85ae071872cda762127f119e..ca0d347c30e91f0b8661dab40f7312ed18c220c9 100644 (file)
@@ -91,7 +91,7 @@ static void readall_comment PARAMS ((po_ty *that, const char *s));
 static void readall_comment_dot PARAMS ((po_ty *that, const char *s));
 static void readall_comment_special PARAMS ((po_ty *that, const char *s));
 static void readall_comment_filepos PARAMS ((po_ty *that, const char *name,
-                                            int line));
+                                            size_t line));
 
 
 static void
@@ -298,7 +298,7 @@ static void
 readall_comment_filepos (that, name, line)
      po_ty *that;
      const char *name;
-     int line;
+     size_t line;
 {
   readall_class_ty *this = (readall_class_ty *) that;
   size_t nbytes;
index 0313b2851b7fb515b3744d2d1f02406bd5defdc8..a71c245235023ce7b99b747bc64b58e1cac36c36 100644 (file)
@@ -614,7 +614,7 @@ message_print (mp, fp, charset, blank_line, debug)
          for (j = 0; j < mp->filepos_count; ++j)
            {
              lex_pos_ty *pp;
-             char buffer[20];
+             char buffer[21];
              char *cp;
              size_t len;
 
@@ -622,14 +622,18 @@ message_print (mp, fp, charset, blank_line, debug)
              cp = pp->file_name;
              while (cp[0] == '.' && cp[1] == '/')
                cp += 2;
-             sprintf (buffer, "%ld", (long) pp->line_number);
-             len = strlen (cp) + strlen (buffer) + 2;
+             /* Some xgettext input formats, like RST, lack line numbers.  */
+             if (pp->line_number == (size_t)(-1))
+               buffer[0] = '\0';
+             else
+               sprintf (buffer, ":%ld", (long) pp->line_number);
+             len = strlen (cp) + strlen (buffer) + 1;
              if (column > 2 && column + len >= page_width)
                {
                  fputs ("\n#:", fp);
                  column = 2;
                }
-             fprintf (fp, " %s:%s", cp, buffer);
+             fprintf (fp, " %s%s", cp, buffer);
              column += len;
            }
          putc ('\n', fp);
index 3063ba3d8a009af92e044a424cf61f189d6f47a6..debedb8af4194ba7bb15d3e527d97e6ad69021c2 100644 (file)
@@ -52,7 +52,7 @@ static void extract_parse_brief PARAMS ((po_ty *that));
 static void extract_comment PARAMS ((po_ty *that, const char *s));
 static void extract_comment_dot PARAMS ((po_ty *that, const char *s));
 static void extract_comment_filepos PARAMS ((po_ty *that, const char *name,
-                                            int line));
+                                            size_t line));
 static void extract_comment_special PARAMS ((po_ty *that, const char *s));
 
 
@@ -248,7 +248,7 @@ static void
 extract_comment_filepos (that, name, line)
      po_ty *that;
      const char *name;
-     int line;
+     size_t line;
 {
   extract_class_ty *this = (extract_class_ty *) that;
   size_t nbytes;
diff --git a/src/x-rst.c b/src/x-rst.c
new file mode 100644 (file)
index 0000000..b8177ba
--- /dev/null
@@ -0,0 +1,229 @@
+/* xgettext RST backend.
+   Copyright (C) 2001 Free Software Foundation, Inc.
+
+   This file was written by Bruno Haible <haible@clisp.cons.org>, 2001.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "message.h"
+#include "x-rst.h"
+#include "xgettext.h"
+#include "error.h"
+#include "progname.h"
+#include "xmalloc.h"
+#include "system.h"
+#include "libgettext.h"
+
+#define _(s) gettext(s)
+
+/* RST stands for Resource String Table.
+
+   An RST file consists of several string definitions.  A string definition
+   starts at the beginning of a line and looks like this:
+       ModuleName.ConstName=StringExpression
+   A StringExpression consists of string pieces of the form 'xyz',
+   single characters of the form #nnn (decimal integer), and +
+   at the end of the line to designate continuation on the next line.
+   String definitions can be separated by blank lines or comment lines
+   beginning with '#'.
+
+   This backend attempts to be functionally equivalent to the 'rstconv'
+   program, part of the Free Pascal run time library, written by
+   Sebastian Guenther.  Except that the locations are output as
+   "ModuleName.ConstName", not "ModuleName:ConstName".
+ */
+
+void
+extract_rst (f, real_filename, logical_filename, mdlp)
+     FILE *f;
+     const char *real_filename;
+     const char *logical_filename;
+     msgdomain_list_ty *mdlp;
+{
+  static char *buffer;
+  static int bufmax;
+  message_list_ty *mlp = mdlp->item[0]->messages;
+  int line_number;
+
+  line_number = 1;
+  for (;;)
+    {
+      int c;
+      int bufpos;
+      char *location;
+      char *msgid;
+      lex_pos_ty pos;
+
+      c = getc (f);
+      if (c == EOF)
+       break;
+
+      /* Ignore blank line.  */
+      if (c == '\n')
+       {
+         line_number++;
+         continue;
+       }
+
+      /* Ignore comment line.  */
+      if (c == '#')
+       {
+         do
+           c = getc (f);
+         while (c != EOF && c != '\n');
+         if (c == EOF)
+           break;
+         line_number++;
+         continue;
+       }
+
+      /* Read ModuleName.ConstName.  */
+      bufpos = 0;
+      for (;;)
+       {
+         if (c == EOF || c == '\n')
+           {
+             error_with_progname = false;
+             error (EXIT_FAILURE, 0, _("%s:%d: invalid string definition"),
+                    logical_filename, line_number);
+             error_with_progname = true;
+           }
+         if (bufpos >= bufmax)
+           {
+             bufmax += 100;
+             buffer = xrealloc (buffer, bufmax);
+           }
+         if (c == '=')
+           break;
+         buffer[bufpos++] = c;
+         c = getc (f);
+       }
+      buffer[bufpos] = '\0';
+      location = xstrdup (buffer);
+
+      /* Read StringExpression.  */
+      bufpos = 0;
+      for (;;)
+       {
+         c = getc (f);
+         if (c == EOF)
+           break;
+         else if (c == '\n')
+           {
+             line_number++;
+             break;
+           }
+         else if (c == '\'')
+           {
+             for (;;)
+               {
+                 c = getc (f);
+                 /* Embedded single quotes like 'abc''def' don't occur.
+                    See fpc-1.0.4/compiler/cresstr.pas.  */
+                 if (c == EOF || c == '\n' || c == '\'')
+                   break;
+                 if (bufpos >= bufmax)
+                   {
+                     bufmax += 100;
+                     buffer = xrealloc (buffer, bufmax);
+                   }
+                 buffer[bufpos++] = c;
+               }
+             if (c == EOF)
+               break;
+             else if (c == '\n')
+               {
+                 line_number++;
+                 break;
+               }
+           }
+         else if (c == '#')
+           {
+             int n;
+             c = getc (f);
+             if (c == EOF || !isdigit (c))
+               {
+                 error_with_progname = false;
+                 error (EXIT_FAILURE, 0, _("%s:%d: missing number after #"),
+                        logical_filename, line_number);
+                 error_with_progname = true;
+               }
+             n = (c - '0');
+             for (;;)
+               {
+                 c = getc (f);
+                 if (c == EOF || !isdigit (c))
+                   break;
+                 n = n * 10 + (c - '0');
+               }
+             if (bufpos >= bufmax)
+               {
+                 bufmax += 100;
+                 buffer = xrealloc (buffer, bufmax);
+               }
+             buffer[bufpos++] = (unsigned char) n;
+             if (c == EOF)
+               break;
+             ungetc (c, f);
+           }
+         else if (c == '+')
+           {
+             c = getc (f);
+             if (c == EOF)
+               break;
+             if (c == '\n')
+               line_number++;
+             else
+               ungetc (c, f);
+           }
+         else
+           {
+             error_with_progname = false;
+             error (EXIT_FAILURE, 0, _("%s:%d: invalid string expression"),
+                    logical_filename, line_number);
+             error_with_progname = true;
+           }
+       }
+      if (bufpos >= bufmax)
+       {
+         bufmax += 100;
+         buffer = xrealloc (buffer, bufmax);
+       }
+      buffer[bufpos] = '\0';
+      msgid = xstrdup (buffer);
+
+      pos.file_name = location;
+      pos.line_number = (size_t)(-1);
+
+      remember_a_message (mlp, msgid, &pos);
+
+      /* Here c is the last read character: EOF or '\n'.  */
+      if (c == EOF)
+       break;
+    }
+
+  if (ferror (f))
+    error (EXIT_FAILURE, errno, _("error while reading \"%s\""),
+          real_filename);
+}
diff --git a/src/x-rst.h b/src/x-rst.h
new file mode 100644 (file)
index 0000000..6f788c6
--- /dev/null
@@ -0,0 +1,29 @@
+/* xgettext RST backend.
+   Copyright (C) 2001 Free Software Foundation, Inc.
+   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+#define EXTENSIONS_RST \
+  { "rst",    "RST"   },                                               \
+
+#define SCANNERS_RST \
+  { "RST",        scan_rst_file, &formatstring_pascal },               \
+
+/* Scan an RST file and add its translatable strings to mdlp.  */
+extern void extract_rst PARAMS ((FILE *fp, const char *real_filename,
+                                const char *logical_filename,
+                                msgdomain_list_ty *mdlp));
index 68096f1001a9fc872f6d1bf9f577cbe69e89af9d..3a71a0172a0d175743435fc5f238ad4d1204bf6d 100644 (file)
@@ -66,6 +66,7 @@ struct passwd *getpwuid ();
 #include "x-po.h"
 #include "x-java.h"
 #include "x-ycp.h"
+#include "x-rst.h"
 
 
 /* If nonzero add all comments immediately preceding one of the keywords. */
@@ -174,6 +175,8 @@ static void scan_java_file PARAMS ((const char *file_name,
                                    msgdomain_list_ty *mdlp));
 static void scan_ycp_file PARAMS ((const char *file_name,
                                   msgdomain_list_ty *mdlp));
+static void scan_rst_file PARAMS ((const char *file_name,
+                                  msgdomain_list_ty *mdlp));
 static long difftm PARAMS ((const struct tm *a, const struct tm *b));
 static message_ty *construct_header PARAMS ((void));
 
@@ -1074,6 +1077,24 @@ scan_ycp_file (file_name, mdlp)
 }
 
 
+static void
+scan_rst_file (file_name, mdlp)
+     const char *file_name;
+     msgdomain_list_ty *mdlp;
+{
+  char *logical_file_name;
+  char *real_file_name;
+  FILE *fp = xgettext_open (file_name, &logical_file_name, &real_file_name);
+
+  extract_rst (fp, real_file_name, logical_file_name, mdlp);
+
+  if (fp != stdin)
+    fclose (fp);
+  free (logical_file_name);
+  free (real_file_name);
+}
+
+
 #define TM_YEAR_ORIGIN 1900
 
 /* Yield A - B, measured in seconds.  */
@@ -1178,6 +1199,7 @@ language_to_scanner (name)
     SCANNERS_PO
     SCANNERS_JAVA
     SCANNERS_YCP
+    SCANNERS_RST
     { "Python", scan_c_file, &formatstring_python },
     { "Lisp", scan_c_file, &formatstring_lisp },
     /* Here will follow more languages and their scanners: awk, perl,
@@ -1218,6 +1240,7 @@ extension_to_language (extension)
     EXTENSIONS_PO
     EXTENSIONS_JAVA
     EXTENSIONS_YCP
+    EXTENSIONS_RST
     /* Here will follow more file extensions: sh, pl, tcl, lisp ... */
   };