+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.
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
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
%union
{
char *string;
- int number;
+ size_t number;
}
%type <number> NUMBER
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 */
static char *buf;
static size_t bufmax;
size_t bufpos;
- int n;
+ size_t n;
int c;
for (;;)
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. */
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
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);
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);
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
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,
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
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;
for (j = 0; j < mp->filepos_count; ++j)
{
lex_pos_ty *pp;
- char buffer[20];
+ char buffer[21];
char *cp;
size_t len;
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);
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));
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;
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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));
#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. */
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));
}
+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. */
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,
EXTENSIONS_PO
EXTENSIONS_JAVA
EXTENSIONS_YCP
+ EXTENSIONS_RST
/* Here will follow more file extensions: sh, pl, tcl, lisp ... */
};