d70283ce50
From-SVN: r21536
543 lines
17 KiB
Plaintext
543 lines
17 KiB
Plaintext
Notes on GCC's Native Language Support
|
|
|
|
GCC's Native Language Support (NLS) is relatively new and
|
|
experimental, so NLS is currently disabled by default. Use
|
|
configure's --enable-nls option to enable it. Eventually, NLS will be
|
|
enabled by default, and you'll need --disable-nls to disable it. You
|
|
must enable NLS in order to make a GCC distribution.
|
|
|
|
By and large, only diagnostic messages have been internationalized.
|
|
Some work remains in other areas; for example, GCC does not yet allow
|
|
non-ASCII letters in identifiers.
|
|
|
|
Not all of GCC's diagnostic messages have been internationalized.
|
|
Programs like `enquire' and `genattr' are not internationalized, as
|
|
their users are GCC maintainers who typically need to be able to read
|
|
English anyway; internationalizing them would thus entail needless
|
|
work for the human translators. And no one has yet gotten around to
|
|
internationalizing the messages in the C++ compiler, or in the
|
|
specialized MIPS-specific programs mips-tdump and mips-tfile.
|
|
|
|
The GCC library should not contain any messages that need
|
|
internationalization, because it operates below the
|
|
internationalization library.
|
|
|
|
Currently, the only language translation supplied is en_UK (British English).
|
|
|
|
Unlike some other GNU programs, the GCC sources contain few instances
|
|
of explicit translation calls like _("string"). Instead, the
|
|
diagnostic printing routines automatically translate their arguments.
|
|
For example, GCC source code should not contain calls like `error
|
|
(_("unterminated comment"))'; it should contain calls like `error
|
|
("unterminated comment")' instead, as it is the `error' function's
|
|
responsibility to translate the message before the user sees it.
|
|
|
|
By convention, any function parameter in the GCC sources whose name
|
|
ends in `msgid' is expected to be a message requiring translation.
|
|
For example, the `error' function's first parameter is named `msgid'.
|
|
GCC's exgettext script uses this convention to determine which
|
|
function parameter strings need to be translated. The exgettext
|
|
script also assumes that any occurrence of `%eMSGID}' on a source
|
|
line, where MSGID does not contain `%' or `}', corresponds to a
|
|
message MSGID that requires translation; this is needed to identify
|
|
diagnostics in GCC spec strings.
|
|
|
|
If you enable NLS and modify source files, you'll need to use a
|
|
special version of the GNU gettext package to propagate the
|
|
modifications to the translation tables. Apply the following patch
|
|
(use `patch -p0') to GNU gettext 0.10.35, which you can retrieve from:
|
|
|
|
ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz
|
|
|
|
This patch has been submitted to the GNU gettext maintainer, so
|
|
eventually we shouldn't need this special gettext version.
|
|
|
|
This patch 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 patch 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 patch; see the file COPYING. If not, write to
|
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA.
|
|
|
|
1998-07-26 Paul Eggert <eggert@twinsun.com>
|
|
|
|
* po/Makefile.in.in (maintainer-clean): Remove cat-id-tbl.c and
|
|
stamp-cat-id.
|
|
|
|
1998-07-24 Paul Eggert <eggert@twinsun.com>
|
|
|
|
* po/Makefile.in.in (cat-id-tbl.o): Depend on
|
|
$(top_srcdir)/intl/libgettext.h, not ../intl/libgettext.h.
|
|
|
|
1998-07-20 Paul Eggert <eggert@twinsun.com>
|
|
|
|
* po/Makefile.in.in (.po.pox, all-yes, $(srcdir)/cat-id-tbl.c,
|
|
$(srcdir)/stamp-cat-id, update-po): Prepend `$(srcdir)/' to
|
|
files built in the source directory; this is needed for
|
|
VPATH-based make in Solaris 2.6.
|
|
|
|
1998-07-17 Paul Eggert <eggert@twinsun.com>
|
|
|
|
Add support for user-specified argument numbers for keywords.
|
|
Extract all strings from a keyword arg, not just the first one.
|
|
Handle parenthesized commas inside keyword args correctly.
|
|
Warn about nested keywords.
|
|
|
|
* doc/gettext.texi: Document --keyword=id:argnum.
|
|
|
|
* src/xgettext.c (scan_c_file):
|
|
Warn about nested keywords, e.g. _(_("xxx")).
|
|
Warn also about not-yet-implemented but allowed nesting, e.g.
|
|
dcgettext(..._("xxx")..., "yyy").
|
|
Get all strings in a keyword arg, not just the first one.
|
|
Handle parenthesized commas inside keyword args correctly.
|
|
|
|
* src/xget-lex.h (enum xgettext_token_type_ty):
|
|
Replace xgettext_token_type_keyword1 and
|
|
xgettext_token_type_keyword2 with just plain
|
|
xgettext_token_type_keyword; it now has argnum value.
|
|
Add xgettext_token_type_rp.
|
|
(struct xgettext_token_ty): Add argnum member.
|
|
line_number and file_name are now also set for
|
|
xgettext_token_type_keyword.
|
|
(xgettext_lex_keyword): Arg is const char *.
|
|
|
|
* src/xget-lex.c: Include "hash.h".
|
|
(enum token_type_ty): Add token_type_rp.
|
|
(keywords): Now a hash table.
|
|
(phase5_get): Return token_type_rp for ')'.
|
|
(xgettext_lex, xgettext_lex_keyword): Add support for keyword argnums.
|
|
(xgettext_lex): Return xgettext_token_type_rp for ')'.
|
|
Report keyword argnum, line number, and file name back to caller.
|
|
|
|
1998-07-09 Paul Eggert <eggert@twinsun.com>
|
|
|
|
* intl/Makefile.in (uninstall):
|
|
Do nothing unless $(PACKAGE) is gettext.
|
|
|
|
===================================================================
|
|
RCS file: doc/gettext.texi,v
|
|
retrieving revision 0.10.35.0
|
|
retrieving revision 0.10.35.1
|
|
diff -pu -r0.10.35.0 -r0.10.35.1
|
|
--- doc/gettext.texi 1998/05/01 05:53:32 0.10.35.0
|
|
+++ doc/gettext.texi 1998/07/18 00:25:15 0.10.35.1
|
|
@@ -1854,13 +1854,19 @@ List of directories searched for input f
|
|
Join messages with existing file.
|
|
|
|
@item -k @var{word}
|
|
-@itemx --keyword[=@var{word}]
|
|
-Additonal keyword to be looked for (without @var{word} means not to
|
|
+@itemx --keyword[=@var{keywordspec}]
|
|
+Additonal keyword to be looked for (without @var{keywordspec} means not to
|
|
use default keywords).
|
|
|
|
-The default keywords, which are always looked for if not explicitly
|
|
-disabled, are @code{gettext}, @code{dgettext}, @code{dcgettext} and
|
|
-@code{gettext_noop}.
|
|
+If @var{keywordspec} is a C identifer @var{id}, @code{xgettext} looks
|
|
+for strings in the first argument of each call to the function or macro
|
|
+@var{id}. If @var{keywordspec} is of the form
|
|
+@samp{@var{id}:@var{argnum}}, @code{xgettext} looks for strings in the
|
|
+@var{argnum}th argument of the call.
|
|
+
|
|
+The default keyword specifications, which are always looked for if not
|
|
+explicitly disabled, are @code{gettext}, @code{dgettext:2},
|
|
+@code{dcgettext:2} and @code{gettext_noop}.
|
|
|
|
@item -m [@var{string}]
|
|
@itemx --msgstr-prefix[=@var{string}]
|
|
===================================================================
|
|
RCS file: intl/Makefile.in,v
|
|
retrieving revision 0.10.35.0
|
|
retrieving revision 0.10.35.1
|
|
diff -pu -r0.10.35.0 -r0.10.35.1
|
|
--- intl/Makefile.in 1998/04/27 21:53:18 0.10.35.0
|
|
+++ intl/Makefile.in 1998/07/09 21:39:18 0.10.35.1
|
|
@@ -143,10 +143,14 @@ install-data: all
|
|
installcheck:
|
|
|
|
uninstall:
|
|
- dists="$(DISTFILES.common)"; \
|
|
- for file in $$dists; do \
|
|
- rm -f $(gettextsrcdir)/$$file; \
|
|
- done
|
|
+ if test "$(PACKAGE)" = "gettext"; then \
|
|
+ dists="$(DISTFILES.common)"; \
|
|
+ for file in $$dists; do \
|
|
+ rm -f $(gettextsrcdir)/$$file; \
|
|
+ done
|
|
+ else \
|
|
+ : ; \
|
|
+ fi
|
|
|
|
info dvi:
|
|
|
|
===================================================================
|
|
RCS file: src/xget-lex.c,v
|
|
retrieving revision 0.10.35.0
|
|
retrieving revision 0.10.35.1
|
|
diff -pu -r0.10.35.0 -r0.10.35.1
|
|
--- src/xget-lex.c 1998/07/09 22:49:48 0.10.35.0
|
|
+++ src/xget-lex.c 1998/07/18 00:25:15 0.10.35.1
|
|
@@ -33,6 +33,7 @@
|
|
#include "error.h"
|
|
#include "system.h"
|
|
#include "libgettext.h"
|
|
+#include "hash.h"
|
|
#include "str-list.h"
|
|
#include "xget-lex.h"
|
|
|
|
@@ -83,6 +84,7 @@ enum token_type_ty
|
|
token_type_eoln,
|
|
token_type_hash,
|
|
token_type_lp,
|
|
+ token_type_rp,
|
|
token_type_comma,
|
|
token_type_name,
|
|
token_type_number,
|
|
@@ -109,7 +111,7 @@ static FILE *fp;
|
|
static int trigraphs;
|
|
static int cplusplus_comments;
|
|
static string_list_ty *comment;
|
|
-static string_list_ty *keywords;
|
|
+static hash_table keywords;
|
|
static int default_keywords = 1;
|
|
|
|
/* These are for tracking whether comments count as immediately before
|
|
@@ -941,6 +943,10 @@ phase5_get (tp)
|
|
tp->type = token_type_lp;
|
|
return;
|
|
|
|
+ case ')':
|
|
+ tp->type = token_type_rp;
|
|
+ return;
|
|
+
|
|
case ',':
|
|
tp->type = token_type_comma;
|
|
return;
|
|
@@ -1179,6 +1185,7 @@ xgettext_lex (tp)
|
|
while (1)
|
|
{
|
|
token_ty token;
|
|
+ void *keyword_value;
|
|
|
|
phase8_get (&token);
|
|
switch (token.type)
|
|
@@ -1213,17 +1220,20 @@ xgettext_lex (tp)
|
|
if (default_keywords)
|
|
{
|
|
xgettext_lex_keyword ("gettext");
|
|
- xgettext_lex_keyword ("dgettext");
|
|
- xgettext_lex_keyword ("dcgettext");
|
|
+ xgettext_lex_keyword ("dgettext:2");
|
|
+ xgettext_lex_keyword ("dcgettext:2");
|
|
xgettext_lex_keyword ("gettext_noop");
|
|
default_keywords = 0;
|
|
}
|
|
|
|
- if (string_list_member (keywords, token.string))
|
|
- {
|
|
- tp->type = (strcmp (token.string, "dgettext") == 0
|
|
- || strcmp (token.string, "dcgettext") == 0)
|
|
- ? xgettext_token_type_keyword2 : xgettext_token_type_keyword1;
|
|
+ if (find_entry (&keywords, token.string, strlen (token.string),
|
|
+ &keyword_value)
|
|
+ == 0)
|
|
+ {
|
|
+ tp->type = xgettext_token_type_keyword;
|
|
+ tp->argnum = (int) keyword_value;
|
|
+ tp->line_number = token.line_number;
|
|
+ tp->file_name = logical_file_name;
|
|
}
|
|
else
|
|
tp->type = xgettext_token_type_symbol;
|
|
@@ -1236,6 +1246,12 @@ xgettext_lex (tp)
|
|
tp->type = xgettext_token_type_lp;
|
|
return;
|
|
|
|
+ case token_type_rp:
|
|
+ last_non_comment_line = newline_count;
|
|
+
|
|
+ tp->type = xgettext_token_type_rp;
|
|
+ return;
|
|
+
|
|
case token_type_comma:
|
|
last_non_comment_line = newline_count;
|
|
|
|
@@ -1263,16 +1279,32 @@ xgettext_lex (tp)
|
|
|
|
void
|
|
xgettext_lex_keyword (name)
|
|
- char *name;
|
|
+ const char *name;
|
|
{
|
|
if (name == NULL)
|
|
default_keywords = 0;
|
|
else
|
|
{
|
|
- if (keywords == NULL)
|
|
- keywords = string_list_alloc ();
|
|
+ int argnum;
|
|
+ size_t len;
|
|
+ const char *sp;
|
|
+
|
|
+ if (keywords.table == NULL)
|
|
+ init_hash (&keywords, 100);
|
|
+
|
|
+ sp = strchr (name, ':');
|
|
+ if (sp)
|
|
+ {
|
|
+ len = sp - name;
|
|
+ argnum = atoi (sp + 1);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ len = strlen (name);
|
|
+ argnum = 1;
|
|
+ }
|
|
|
|
- string_list_append_unique (keywords, name);
|
|
+ insert_entry (&keywords, name, len, (void *) argnum);
|
|
}
|
|
}
|
|
|
|
===================================================================
|
|
RCS file: src/xget-lex.h,v
|
|
retrieving revision 0.10.35.0
|
|
retrieving revision 0.10.35.1
|
|
diff -pu -r0.10.35.0 -r0.10.35.1
|
|
--- src/xget-lex.h 1998/07/09 22:49:48 0.10.35.0
|
|
+++ src/xget-lex.h 1998/07/18 00:25:15 0.10.35.1
|
|
@@ -23,9 +23,9 @@ Foundation, Inc., 59 Temple Place - Suit
|
|
enum xgettext_token_type_ty
|
|
{
|
|
xgettext_token_type_eof,
|
|
- xgettext_token_type_keyword1,
|
|
- xgettext_token_type_keyword2,
|
|
+ xgettext_token_type_keyword,
|
|
xgettext_token_type_lp,
|
|
+ xgettext_token_type_rp,
|
|
xgettext_token_type_comma,
|
|
xgettext_token_type_string_literal,
|
|
xgettext_token_type_symbol
|
|
@@ -37,8 +37,14 @@ struct xgettext_token_ty
|
|
{
|
|
xgettext_token_type_ty type;
|
|
|
|
- /* These 3 are only set for xgettext_token_type_string_literal. */
|
|
+ /* This 1 is set only for xgettext_token_type_keyword. */
|
|
+ int argnum;
|
|
+
|
|
+ /* This 1 is set only for xgettext_token_type_string_literal. */
|
|
char *string;
|
|
+
|
|
+ /* These 2 are set only for xgettext_token_type_keyword and
|
|
+ xgettext_token_type_string_literal. */
|
|
int line_number;
|
|
char *file_name;
|
|
};
|
|
@@ -50,7 +56,7 @@ void xgettext_lex PARAMS ((xgettext_toke
|
|
const char *xgettext_lex_comment PARAMS ((size_t __n));
|
|
void xgettext_lex_comment_reset PARAMS ((void));
|
|
/* void xgettext_lex_filepos PARAMS ((char **, int *)); FIXME needed? */
|
|
-void xgettext_lex_keyword PARAMS ((char *__name));
|
|
+void xgettext_lex_keyword PARAMS ((const char *__name));
|
|
void xgettext_lex_cplusplus PARAMS ((void));
|
|
void xgettext_lex_trigraphs PARAMS ((void));
|
|
|
|
===================================================================
|
|
RCS file: src/xgettext.c,v
|
|
retrieving revision 0.10.35.0
|
|
retrieving revision 0.10.35.1
|
|
diff -pu -r0.10.35.0 -r0.10.35.1
|
|
--- src/xgettext.c 1998/07/09 22:49:48 0.10.35.0
|
|
+++ src/xgettext.c 1998/07/18 00:25:15 0.10.35.1
|
|
@@ -835,6 +835,8 @@ scan_c_file(filename, mlp, is_cpp_file)
|
|
int is_cpp_file;
|
|
{
|
|
int state;
|
|
+ int commas_to_skip; /* defined only when in states 1 and 2 */
|
|
+ int paren_nesting; /* defined only when in state 2 */
|
|
|
|
/* Inform scanner whether we have C++ files or not. */
|
|
if (is_cpp_file)
|
|
@@ -854,63 +856,79 @@ scan_c_file(filename, mlp, is_cpp_file)
|
|
{
|
|
xgettext_token_ty token;
|
|
|
|
- /* A simple state machine is used to do the recognising:
|
|
+ /* A state machine is used to do the recognising:
|
|
State 0 = waiting for something to happen
|
|
- State 1 = seen one of our keywords with string in first parameter
|
|
- State 2 = was in state 1 and now saw a left paren
|
|
- State 3 = seen one of our keywords with string in second parameter
|
|
- State 4 = was in state 3 and now saw a left paren
|
|
- State 5 = waiting for comma after being in state 4
|
|
- State 6 = saw comma after being in state 5 */
|
|
+ State 1 = seen one of our keywords
|
|
+ State 2 = waiting for part of an argument */
|
|
xgettext_lex (&token);
|
|
switch (token.type)
|
|
{
|
|
- case xgettext_token_type_keyword1:
|
|
+ case xgettext_token_type_keyword:
|
|
+ if (!extract_all && state == 2)
|
|
+ {
|
|
+ if (commas_to_skip == 0)
|
|
+ {
|
|
+ error (0, 0,
|
|
+ _("%s:%d: warning: keyword nested in keyword arg"),
|
|
+ token.file_name, token.line_number);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ /* Here we should nest properly, but this would require a
|
|
+ potentially unbounded stack. We haven't run across an
|
|
+ example that needs this functionality yet. For now,
|
|
+ we punt and forget the outer keyword. */
|
|
+ error (0, 0,
|
|
+ _("%s:%d: warning: keyword between outer keyword and its arg"),
|
|
+ token.file_name, token.line_number);
|
|
+ }
|
|
+ commas_to_skip = token.argnum - 1;
|
|
state = 1;
|
|
continue;
|
|
|
|
- case xgettext_token_type_keyword2:
|
|
- state = 3;
|
|
- continue;
|
|
-
|
|
case xgettext_token_type_lp:
|
|
switch (state)
|
|
{
|
|
case 1:
|
|
+ paren_nesting = 0;
|
|
state = 2;
|
|
break;
|
|
- case 3:
|
|
- state = 4;
|
|
+ case 2:
|
|
+ paren_nesting++;
|
|
break;
|
|
- default:
|
|
- state = 0;
|
|
}
|
|
continue;
|
|
|
|
+ case xgettext_token_type_rp:
|
|
+ if (state == 2 && paren_nesting != 0)
|
|
+ paren_nesting--;
|
|
+ else
|
|
+ state = 0;
|
|
+ continue;
|
|
+
|
|
case xgettext_token_type_comma:
|
|
- state = state == 5 ? 6 : 0;
|
|
+ if (state == 2 && commas_to_skip != 0)
|
|
+ commas_to_skip -= paren_nesting == 0;
|
|
+ else
|
|
+ state = 0;
|
|
continue;
|
|
|
|
case xgettext_token_type_string_literal:
|
|
- if (extract_all || state == 2 || state == 6)
|
|
- {
|
|
- remember_a_message (mlp, &token);
|
|
- state = 0;
|
|
- }
|
|
+ if (extract_all || (state == 2 && commas_to_skip == 0))
|
|
+ remember_a_message (mlp, &token);
|
|
else
|
|
{
|
|
free (token.string);
|
|
- state = (state == 4 || state == 5) ? 5 : 0;
|
|
+ state = state == 2 ? 2 : 0;
|
|
}
|
|
continue;
|
|
|
|
case xgettext_token_type_symbol:
|
|
- state = (state == 4 || state == 5) ? 5 : 0;
|
|
+ state = state == 2 ? 2 : 0;
|
|
continue;
|
|
|
|
default:
|
|
- state = 0;
|
|
- continue;
|
|
+ abort ();
|
|
|
|
case xgettext_token_type_eof:
|
|
break;
|
|
===================================================================
|
|
RCS file: po/Makefile.in.in,v
|
|
retrieving revision 0.10.35.0
|
|
retrieving revision 0.10.35.5
|
|
diff -u -r0.10.35.0 -r0.10.35.5
|
|
--- po/Makefile.in.in 1998/07/20 20:20:38 0.10.35.0
|
|
+++ po/Makefile.in.in 1998/07/26 09:07:52 0.10.35.5
|
|
@@ -62,7 +62,7 @@
|
|
$(COMPILE) $<
|
|
|
|
.po.pox:
|
|
- $(MAKE) $(PACKAGE).pot
|
|
+ $(MAKE) $(srcdir)/$(PACKAGE).pot
|
|
$(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
|
|
|
|
.po.mo:
|
|
@@ -79,7 +79,7 @@
|
|
|
|
all: all-@USE_NLS@
|
|
|
|
-all-yes: cat-id-tbl.c $(CATALOGS)
|
|
+all-yes: $(srcdir)/cat-id-tbl.c $(CATALOGS)
|
|
all-no:
|
|
|
|
$(srcdir)/$(PACKAGE).pot: $(POTFILES)
|
|
@@ -90,8 +90,8 @@
|
|
|| ( rm -f $(srcdir)/$(PACKAGE).pot \
|
|
&& mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot )
|
|
|
|
-$(srcdir)/cat-id-tbl.c: stamp-cat-id; @:
|
|
-$(srcdir)/stamp-cat-id: $(PACKAGE).pot
|
|
+$(srcdir)/cat-id-tbl.c: $(srcdir)/stamp-cat-id; @:
|
|
+$(srcdir)/stamp-cat-id: $(srcdir)/$(PACKAGE).pot
|
|
rm -f cat-id-tbl.tmp
|
|
sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \
|
|
| sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp
|
|
@@ -180,7 +180,8 @@
|
|
|
|
check: all
|
|
|
|
-cat-id-tbl.o: ../intl/libgettext.h
|
|
+cat-id-tbl.o: $(srcdir)/cat-id-tbl.c $(top_srcdir)/intl/libgettext.h
|
|
+ $(COMPILE) $(srcdir)/cat-id-tbl.c
|
|
|
|
dvi info tags TAGS ID:
|
|
|
|
@@ -196,7 +197,7 @@
|
|
maintainer-clean: distclean
|
|
@echo "This command is intended for maintainers to use;"
|
|
@echo "it deletes files that may require special tools to rebuild."
|
|
- rm -f $(GMOFILES)
|
|
+ rm -f $(GMOFILES) cat-id-tbl.c stamp-cat-id
|
|
|
|
distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
|
|
dist distdir: update-po $(DISTFILES)
|
|
@@ -207,7 +208,7 @@
|
|
done
|
|
|
|
update-po: Makefile
|
|
- $(MAKE) $(PACKAGE).pot
|
|
+ $(MAKE) $(srcdir)/$(PACKAGE).pot
|
|
PATH=`pwd`/../src:$$PATH; \
|
|
cd $(srcdir); \
|
|
catalogs='$(CATALOGS)'; \
|