From: Bruno Haible Date: Sat, 20 Oct 2001 13:06:20 +0000 (+0000) Subject: Add support for FPC's RST files. X-Git-Tag: v0.11~447 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b3440fe6e726e4cb495f0967f119ebb3c12b1e4a;p=thirdparty%2Fgettext.git Add support for FPC's RST files. --- diff --git a/src/ChangeLog b/src/ChangeLog index 871082c9d..fac6b35ab 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,32 @@ +2001-09-19 Bruno Haible + + * 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 + + * 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 * format-pascal.c: New file. diff --git a/src/Makefile.am b/src/Makefile.am index 73846cd51..5ea14dc7f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/po-hash-gen.y b/src/po-hash-gen.y index 90b770735..22947e1a8 100644 --- a/src/po-hash-gen.y +++ b/src/po-hash-gen.y @@ -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 @@ -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 (;;) diff --git a/src/po.c b/src/po.c index 589d36eef..f8ea28693 100644 --- 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); diff --git a/src/po.h b/src/po.h index 30440c58a..35e20127e 100644 --- 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, diff --git a/src/read-po.c b/src/read-po.c index ad540f6d3..ca0d347c3 100644 --- a/src/read-po.c +++ b/src/read-po.c @@ -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; diff --git a/src/write-po.c b/src/write-po.c index 0313b2851..a71c24523 100644 --- a/src/write-po.c +++ b/src/write-po.c @@ -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); diff --git a/src/x-po.c b/src/x-po.c index 3063ba3d8..debedb8af 100644 --- a/src/x-po.c +++ b/src/x-po.c @@ -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 index 000000000..b8177baff --- /dev/null +++ b/src/x-rst.c @@ -0,0 +1,229 @@ +/* xgettext RST backend. + Copyright (C) 2001 Free Software Foundation, Inc. + + This file was written by Bruno Haible , 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 +#include +#include +#include + +#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 index 000000000..6f788c6ba --- /dev/null +++ b/src/x-rst.h @@ -0,0 +1,29 @@ +/* xgettext RST backend. + Copyright (C) 2001 Free Software Foundation, Inc. + Written by Bruno Haible , 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)); diff --git a/src/xgettext.c b/src/xgettext.c index 68096f100..3a71a0172 100644 --- a/src/xgettext.c +++ b/src/xgettext.c @@ -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 ... */ };