From: Bruno Haible Date: Thu, 16 Mar 2006 13:10:48 +0000 (+0000) Subject: Support extraction of contexts in GNOME glib syntax. X-Git-Tag: v0.15~285 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5ea8c31fe01181f47961977fc513e7c8ba2785b6;p=thirdparty%2Fgettext.git Support extraction of contexts in GNOME glib syntax. --- diff --git a/NEWS b/NEWS index 9ff6ae4de..e49edc4f8 100644 --- a/NEWS +++ b/NEWS @@ -7,7 +7,9 @@ msgid "original" msgstr "translation" - The xgettext program can be told through the --keyword flag which - function/macro argument has the role of a context. + function/macro argument has the role of a context. It also supports + the GNOME glib convention to specify the context and original string + in the same string literal: "context|original". - The (non-public) include file gettext.h defines macros pgettext, dpgettext etc. that take a context argument. For more information, see the node "Contexts" in the manual. diff --git a/gettext-tools/doc/ChangeLog b/gettext-tools/doc/ChangeLog index e645b48ff..16df02db4 100644 --- a/gettext-tools/doc/ChangeLog +++ b/gettext-tools/doc/ChangeLog @@ -1,3 +1,7 @@ +2006-03-16 Bruno Haible + + * xgettext.texi (--keyword): Document suffix 'g'. + 2006-02-26 Bruno Haible * gettext.texi (Introduction): Fix typo. diff --git a/gettext-tools/doc/xgettext.texi b/gettext-tools/doc/xgettext.texi index 46106bded..61f8e6629 100644 --- a/gettext-tools/doc/xgettext.texi +++ b/gettext-tools/doc/xgettext.texi @@ -159,6 +159,10 @@ with plural handling. Also, if @var{keywordspec} is of the form @samp{@var{id}:@var{contextargnum}c,@var{argnum}} or @samp{@var{id}:@var{argnum},@var{contextargnum}c}, @code{xgettext} treats strings in the @var{contextargnum}th argument as a context specifier. +And, as a special-purpose support for GNOME, if @var{keywordspec} is of the +form @samp{@var{id}:@var{argnum}g}, @code{xgettext} recognizes the +@var{argnum}th argument as a string with context, using the GNOME @code{glib} +syntax @samp{"msgctxt|msgid"}. @* Furthermore, if @var{keywordspec} is of the form @samp{@var{id}:@dots{},@var{totalnumargs}t}, @code{xgettext} recognizes this diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index 2ad82f2a2..493cfb12b 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,18 @@ +2006-03-16 Bruno Haible + + Handle GNOME glib context syntax. + * xgettext.h (struct callshape): Add fields argnum1_glib_context, + argnum2_glib_context. + (struct partial_call): Add fields argnum1_glib_context, + argnum2_glib_context. + * xgettext.c (split_keywordspec): Recognize suffix 'g' and set the + argnum1_glib_context, argnum2_glib_context fields. + (insert_keyword_callshape, arglist_parser_alloc, arglist_parser_clone): + Update. + (arglist_parser_done): When suffix 'g' was specified, split off the + context from the msgid and/or msgid_plural. + * x-perl.c (extract_variable): Update. + 2006-03-16 Bruno Haible * xgettext.c (set_format_flags_from_context): Break long line. diff --git a/gettext-tools/src/x-perl.c b/gettext-tools/src/x-perl.c index 5981f6b96..f59e3d453 100644 --- a/gettext-tools/src/x-perl.c +++ b/gettext-tools/src/x-perl.c @@ -1,5 +1,5 @@ /* xgettext Perl backend. - Copyright (C) 2002-2005 Free Software Foundation, Inc. + Copyright (C) 2002-2006 Free Software Foundation, Inc. This file was written by Guido Flohr , 2002-2003. @@ -1505,6 +1505,8 @@ extract_variable (message_list_ty *mlp, token_ty *tp, int first) shapes.shapes[0].argnum1 = 1; shapes.shapes[0].argnum2 = 0; shapes.shapes[0].argnumc = 0; + shapes.shapes[0].argnum1_glib_context = false; + shapes.shapes[0].argnum2_glib_context = false; shapes.shapes[0].argtotal = 0; /* Extract a possible string from the key. Before proceeding diff --git a/gettext-tools/src/xgettext.c b/gettext-tools/src/xgettext.c index 1815c8daf..66359027b 100644 --- a/gettext-tools/src/xgettext.c +++ b/gettext-tools/src/xgettext.c @@ -981,6 +981,8 @@ split_keywordspec (const char *spec, int argnum1 = 0; int argnum2 = 0; int argnumc = 0; + bool argnum1_glib_context = false; + bool argnum2_glib_context = false; int argtotal = 0; /* Start parsing from the end. */ @@ -988,10 +990,11 @@ split_keywordspec (const char *spec, while (p > spec) { if (isdigit ((unsigned char) p[-1]) - || ((p[-1] == 'c' || p[-1] == 't') + || ((p[-1] == 'c' || p[-1] == 'g' || p[-1] == 't') && p - 1 > spec && isdigit ((unsigned char) p[-2]))) { bool contextp = (p[-1] == 'c'); + bool glibp = (p[-1] == 'g'); bool totalp = (p[-1] == 't'); do @@ -1023,7 +1026,9 @@ split_keywordspec (const char *spec, /* At most two normal arguments can be given. */ break; argnum2 = argnum1; + argnum2_glib_context = argnum1_glib_context; argnum1 = arg; + argnum1_glib_context = glibp; } p--; @@ -1032,10 +1037,16 @@ split_keywordspec (const char *spec, if (argnum1 == 0 && argnum2 == 0) /* At least one non-context argument must be given. */ break; + if (argnumc != 0 + && (argnum1_glib_context || argnum2_glib_context)) + /* Incompatible ways to specify the context. */ + break; *endp = p; shapep->argnum1 = (argnum1 > 0 ? argnum1 : 1); shapep->argnum2 = argnum2; shapep->argnumc = argnumc; + shapep->argnum1_glib_context = argnum1_glib_context; + shapep->argnum2_glib_context = argnum2_glib_context; shapep->argtotal = argtotal; return; } @@ -1052,6 +1063,8 @@ split_keywordspec (const char *spec, shapep->argnum1 = 1; shapep->argnum2 = 0; shapep->argnumc = 0; + shapep->argnum1_glib_context = false; + shapep->argnum2_glib_context = false; shapep->argtotal = 0; } @@ -1090,6 +1103,10 @@ insert_keyword_callshape (hash_table *table, if (old_shapes->shapes[i].argnum1 == shape->argnum1 && old_shapes->shapes[i].argnum2 == shape->argnum2 && old_shapes->shapes[i].argnumc == shape->argnumc + && old_shapes->shapes[i].argnum1_glib_context + == shape->argnum1_glib_context + && old_shapes->shapes[i].argnum2_glib_context + == shape->argnum2_glib_context && old_shapes->shapes[i].argtotal == shape->argtotal) { found = true; @@ -2288,6 +2305,10 @@ arglist_parser_alloc (message_list_ty *mlp, const struct callshapes *shapes) ap->alternative[i].argnumc = shapes->shapes[i].argnumc; ap->alternative[i].argnum1 = shapes->shapes[i].argnum1; ap->alternative[i].argnum2 = shapes->shapes[i].argnum2; + ap->alternative[i].argnum1_glib_context = + shapes->shapes[i].argnum1_glib_context; + ap->alternative[i].argnum2_glib_context = + shapes->shapes[i].argnum2_glib_context; ap->alternative[i].argtotal = shapes->shapes[i].argtotal; ap->alternative[i].msgctxt = NULL; ap->alternative[i].msgctxt_pos.file_name = NULL; @@ -2329,6 +2350,8 @@ arglist_parser_clone (struct arglist_parser *ap) ccp->argnumc = cp->argnumc; ccp->argnum1 = cp->argnum1; ccp->argnum2 = cp->argnum2; + ccp->argnum1_glib_context = cp->argnum1_glib_context; + ccp->argnum2_glib_context = cp->argnum2_glib_context; ccp->argtotal = cp->argtotal; ccp->msgctxt = (cp->msgctxt != NULL ? xstrdup (cp->msgctxt) : NULL); ccp->msgctxt_pos = cp->msgctxt_pos; @@ -2565,6 +2588,76 @@ arglist_parser_done (struct arglist_parser *ap, int argnum) Now call remember_a_message. */ message_ty *mp; + /* Split strings in the GNOME glib syntax "msgctxt|msgid". */ + if (best_cp->argnum1_glib_context || best_cp->argnum2_glib_context) + /* split_keywordspec should not allow the context to be specified + in two different ways. */ + if (best_cp->msgctxt != NULL) + abort (); + if (best_cp->argnum1_glib_context) + { + const char *separator = strchr (best_cp->msgid, '|'); + + if (separator == NULL) + { + error_with_progname = false; + error (0, 0, + _("%s:%d: warning: missing context for keyword '%.*s'"), + best_cp->msgid_pos.file_name, best_cp->msgid_pos.line_number, + ap->keyword_len, ap->keyword); + error_with_progname = true; + } + else + { + size_t ctxt_len = separator - best_cp->msgid; + char *ctxt = (char *) xmalloc (ctxt_len + 1); + + memcpy (ctxt, best_cp->msgid, ctxt_len); + ctxt[ctxt_len] = '\0'; + best_cp->msgctxt = ctxt; + best_cp->msgid = xstrdup (separator + 1); + } + } + if (best_cp->msgid_plural != NULL && best_cp->argnum2_glib_context) + { + const char *separator = strchr (best_cp->msgid_plural, '|'); + + if (separator == NULL) + { + error_with_progname = false; + error (0, 0, + _("%s:%d: warning: missing context for plural argument of keyword '%.*s'"), + best_cp->msgid_plural_pos.file_name, + best_cp->msgid_plural_pos.line_number, + ap->keyword_len, ap->keyword); + error_with_progname = true; + } + else + { + size_t ctxt_len = separator - best_cp->msgid_plural; + char *ctxt = (char *) xmalloc (ctxt_len + 1); + + memcpy (ctxt, best_cp->msgid_plural, ctxt_len); + ctxt[ctxt_len] = '\0'; + if (best_cp->msgctxt == NULL) + best_cp->msgctxt = ctxt; + else + { + if (strcmp (ctxt, best_cp->msgctxt) != 0) + { + error_with_progname = false; + error (0, 0, + _("%s:%d: context mismatch between singular and plural form"), + best_cp->msgid_plural_pos.file_name, + best_cp->msgid_plural_pos.line_number); + error_with_progname = true; + } + free (ctxt); + } + best_cp->msgid_plural = xstrdup (separator + 1); + } + } + mp = remember_a_message (ap->mlp, best_cp->msgctxt, best_cp->msgid, best_cp->msgid_context, &best_cp->msgid_pos, diff --git a/gettext-tools/src/xgettext.h b/gettext-tools/src/xgettext.h index fcbde3eef..021cda492 100644 --- a/gettext-tools/src/xgettext.h +++ b/gettext-tools/src/xgettext.h @@ -1,5 +1,5 @@ /* xgettext common functions. - Copyright (C) 2001-2003, 2005 Free Software Foundation, Inc. + Copyright (C) 2001-2003, 2005-2006 Free Software Foundation, Inc. Written by Peter Miller and Bruno Haible , 2001. @@ -54,6 +54,8 @@ struct callshape int argnum1; /* argument number to use for msgid */ int argnum2; /* argument number to use for msgid_plural */ int argnumc; /* argument number to use for msgctxt */ + bool argnum1_glib_context; /* argument argnum1 has the syntax "ctxt|msgid" */ + bool argnum2_glib_context; /* argument argnum2 has the syntax "ctxt|msgid" */ int argtotal; /* total number of arguments */ }; @@ -251,6 +253,8 @@ struct partial_call int argnumc; /* number of context argument, 0 when seen */ int argnum1; /* number of singular argument, 0 when seen */ int argnum2; /* number of plural argument, 0 when seen */ + bool argnum1_glib_context; /* argument argnum1 has the syntax "ctxt|msgid" */ + bool argnum2_glib_context; /* argument argnum2 has the syntax "ctxt|msgid" */ int argtotal; /* total number of arguments, 0 if unspecified */ char *msgctxt; /* context - owned string, or NULL */ lex_pos_ty msgctxt_pos; diff --git a/gettext-tools/tests/ChangeLog b/gettext-tools/tests/ChangeLog index 7915a4593..c26eb42b0 100644 --- a/gettext-tools/tests/ChangeLog +++ b/gettext-tools/tests/ChangeLog @@ -1,3 +1,8 @@ +2006-03-16 Bruno Haible + + * xgettext-c-15: New file. + * Makefile.am (TESTS): Add it. + 2006-03-11 Bruno Haible * lang-c: Put the -I flags before ${CFLAGS} ${CPPFLAGS}. diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am index baa8567de..1757fef99 100644 --- a/gettext-tools/tests/Makefile.am +++ b/gettext-tools/tests/Makefile.am @@ -64,7 +64,7 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \ xgettext-awk-1 \ xgettext-c-1 xgettext-c-2 xgettext-c-3 xgettext-c-4 xgettext-c-5 \ xgettext-c-6 xgettext-c-7 xgettext-c-8 xgettext-c-9 xgettext-c-10 \ - xgettext-c-11 xgettext-c-12 xgettext-c-13 xgettext-c-14 \ + xgettext-c-11 xgettext-c-12 xgettext-c-13 xgettext-c-14 xgettext-c-15 \ xgettext-csharp-1 xgettext-csharp-2 xgettext-csharp-3 \ xgettext-csharp-4 xgettext-csharp-5 \ xgettext-elisp-1 \