diff options
author | Daiki Ueno <ueno@gnu.org> | 2014-05-07 18:48:25 +0900 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2014-05-09 17:32:09 +0900 |
commit | 5839a8821d825fa6c00baddeeca9a1544f925689 (patch) | |
tree | 1258335bb537eeb8230153b211afaa9caa46ea89 /gettext-tools/src | |
parent | 014af300f8da693fa15361c9ae310b45fc7c16b2 (diff) | |
download | external_gettext-5839a8821d825fa6c00baddeeca9a1544f925689.zip external_gettext-5839a8821d825fa6c00baddeeca9a1544f925689.tar.gz external_gettext-5839a8821d825fa6c00baddeeca9a1544f925689.tar.bz2 |
xgettext: Provide a way to interpret string literals lazily
* xgettext.c (extract_ty): New field 'literalstring_parser'.
(current_literalstring_parser): New variable.
(extract_from_file): Set 'current_literalstring_parser'.
(savable_comment_convert_encoding): New function.
(arglist_parser_remember_literal): New function.
(arglist_parser_remember): Call 'arglist_parser_remember_literal'.
(arglist_parser_done): Call literalstring_parser on msgctxt,
msgid, and msgid_plural before calling 'remember_a_message';
convert encoding of msgid_comment.
* x-*.h: Register 'literalstring_parser' through SCANNER_*.
* xgettext.h (enum literalstring_escape_type): New enum.
(struct literalstring_parser): New struct.
(struct partial_call): New fields 'msgctxt_escape',
'msgid_escape', and 'msgid_plural_escape'.
(arglist_parser_remember_literal): New function declaration.
(savable_comment_convert_encoding): New function declaration.
Diffstat (limited to 'gettext-tools/src')
28 files changed, 219 insertions, 37 deletions
diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index a220e2c..26a4b15 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,23 @@ +2014-05-09 Daiki Ueno <ueno@gnu.org> + + xgettext: Provide a way to interpret string literals lazily + * xgettext.c (extract_ty): New field 'literalstring_parser'. + (current_literalstring_parser): New variable. + (extract_from_file): Set 'current_literalstring_parser'. + (savable_comment_convert_encoding): New function. + (arglist_parser_remember_literal): New function. + (arglist_parser_remember): Call 'arglist_parser_remember_literal'. + (arglist_parser_done): Call literalstring_parser on msgctxt, + msgid, and msgid_plural before calling 'remember_a_message'; + convert encoding of msgid_comment. + * x-*.h: Register 'literalstring_parser' through SCANNER_*. + * xgettext.h (enum literalstring_escape_type): New enum. + (struct literalstring_parser): New struct. + (struct partial_call): New fields 'msgctxt_escape', + 'msgid_escape', and 'msgid_plural_escape'. + (arglist_parser_remember_literal): New function declaration. + (savable_comment_convert_encoding): New function declaration. + 2014-05-03 Daiki Ueno <ueno@gnu.org> xgettext: Recognize prefixed comment tag diff --git a/gettext-tools/src/x-awk.h b/gettext-tools/src/x-awk.h index 6cfd33b..642c0e2 100644 --- a/gettext-tools/src/x-awk.h +++ b/gettext-tools/src/x-awk.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_AWK \ { "awk", extract_awk, \ - &flag_table_awk, &formatstring_awk, NULL }, \ + &flag_table_awk, &formatstring_awk, NULL, NULL }, \ /* Scan an awk file and add its translatable strings to mdlp. */ extern void extract_awk (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-c.h b/gettext-tools/src/x-c.h index 643345f..28c5b92 100644 --- a/gettext-tools/src/x-c.h +++ b/gettext-tools/src/x-c.h @@ -43,16 +43,16 @@ extern "C" { #define SCANNERS_C \ { "C", extract_c, \ &flag_table_c, \ - &formatstring_c, NULL }, \ + &formatstring_c, NULL, NULL }, \ { "C++", extract_c, \ &flag_table_c, \ - &formatstring_c, NULL }, \ + &formatstring_c, NULL, NULL }, \ { "ObjectiveC", extract_objc, \ &flag_table_objc, \ - &formatstring_c, &formatstring_objc }, \ + &formatstring_c, &formatstring_objc, NULL }, \ { "GCC-source", extract_c, \ &flag_table_gcc_internal, \ - &formatstring_gcc_internal, &formatstring_gfc_internal }, \ + &formatstring_gcc_internal, &formatstring_gfc_internal, NULL }, \ /* Scan a C/C++ file and add its translatable strings to mdlp. */ extern void extract_c (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-csharp.h b/gettext-tools/src/x-csharp.h index 9cfb1d8..de37789 100644 --- a/gettext-tools/src/x-csharp.h +++ b/gettext-tools/src/x-csharp.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_CSHARP \ { "C#", extract_csharp, \ - &flag_table_csharp, &formatstring_csharp, NULL }, \ + &flag_table_csharp, &formatstring_csharp, NULL, NULL }, \ extern void extract_csharp (FILE *fp, const char *real_filename, const char *logical_filename, diff --git a/gettext-tools/src/x-desktop.h b/gettext-tools/src/x-desktop.h index d9f1ff4..d24f174 100644 --- a/gettext-tools/src/x-desktop.h +++ b/gettext-tools/src/x-desktop.h @@ -31,7 +31,7 @@ extern "C" { { "desktop", "Desktop" }, \ #define SCANNERS_DESKTOP \ - { "Desktop", extract_desktop, NULL, NULL, NULL }, \ + { "Desktop", extract_desktop, NULL, NULL, NULL, NULL }, \ /* Scan a Desktop Entry file and add its translatable strings to mdlp. */ extern void extract_desktop (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-elisp.h b/gettext-tools/src/x-elisp.h index b0f7123..f939957 100644 --- a/gettext-tools/src/x-elisp.h +++ b/gettext-tools/src/x-elisp.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_ELISP \ { "EmacsLisp", extract_elisp, \ - &flag_table_elisp, &formatstring_elisp, NULL }, \ + &flag_table_elisp, &formatstring_elisp, NULL, NULL }, \ /* Scan an Emacs Lisp file and add its translatable strings to mdlp. */ extern void extract_elisp (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-glade.h b/gettext-tools/src/x-glade.h index e3cc253..f212d2b 100644 --- a/gettext-tools/src/x-glade.h +++ b/gettext-tools/src/x-glade.h @@ -33,7 +33,7 @@ extern "C" { { "ui", "glade" }, \ #define SCANNERS_GLADE \ - { "glade", extract_glade, NULL, NULL, NULL }, \ + { "glade", extract_glade, NULL, NULL, NULL, NULL }, \ /* Scan a glade XML file and add its translatable strings to mdlp. */ extern void extract_glade (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-gsettings.h b/gettext-tools/src/x-gsettings.h index 073b418..b06016d 100644 --- a/gettext-tools/src/x-gsettings.h +++ b/gettext-tools/src/x-gsettings.h @@ -31,7 +31,7 @@ extern "C" { { "gschema.xml", "gsettings" }, \ #define SCANNERS_GSETTINGS \ - { "gsettings", extract_gsettings, NULL, NULL, NULL }, \ + { "gsettings", extract_gsettings, NULL, NULL, NULL, NULL }, \ /* Scan a gsettings XML file and add its translatable strings to mdlp. */ extern void extract_gsettings (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-java.h b/gettext-tools/src/x-java.h index 31436c5..49f2af9 100644 --- a/gettext-tools/src/x-java.h +++ b/gettext-tools/src/x-java.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_JAVA \ { "Java", extract_java, \ - &flag_table_java, &formatstring_java, NULL }, \ + &flag_table_java, &formatstring_java, NULL, NULL }, \ extern void extract_java (FILE *fp, const char *real_filename, const char *logical_filename, diff --git a/gettext-tools/src/x-javascript.h b/gettext-tools/src/x-javascript.h index da40f71..a2f6418 100644 --- a/gettext-tools/src/x-javascript.h +++ b/gettext-tools/src/x-javascript.h @@ -33,7 +33,7 @@ extern "C" { #define SCANNERS_JAVASCRIPT \ { "JavaScript", extract_javascript, \ - &flag_table_javascript, &formatstring_javascript, NULL }, \ + &flag_table_javascript, &formatstring_javascript, NULL, NULL }, \ /* Scan a Python file and add its translatable strings to mdlp. */ extern void extract_javascript (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-librep.h b/gettext-tools/src/x-librep.h index 8937d51..5747db1 100644 --- a/gettext-tools/src/x-librep.h +++ b/gettext-tools/src/x-librep.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_LIBREP \ { "librep", extract_librep, \ - &flag_table_librep, &formatstring_librep, NULL }, \ + &flag_table_librep, &formatstring_librep, NULL, NULL }, \ /* Scan a librep file and add its translatable strings to mdlp. */ extern void extract_librep (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-lisp.h b/gettext-tools/src/x-lisp.h index 9988f62..97b593d 100644 --- a/gettext-tools/src/x-lisp.h +++ b/gettext-tools/src/x-lisp.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_LISP \ { "Lisp", extract_lisp, \ - &flag_table_lisp, &formatstring_lisp, NULL }, \ + &flag_table_lisp, &formatstring_lisp, NULL, NULL }, \ /* Scan a Lisp file and add its translatable strings to mdlp. */ extern void extract_lisp (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-lua.h b/gettext-tools/src/x-lua.h index bca0304..3161638 100644 --- a/gettext-tools/src/x-lua.h +++ b/gettext-tools/src/x-lua.h @@ -30,7 +30,7 @@ extern "C" #define SCANNERS_LUA \ { "Lua", extract_lua, \ - &flag_table_lua, &formatstring_lua, NULL }, \ + &flag_table_lua, &formatstring_lua, NULL, NULL }, \ /* Scan a Lua file and add its translatable strings to mdlp. */ extern void extract_lua (FILE * fp, const char *real_filename, diff --git a/gettext-tools/src/x-perl.h b/gettext-tools/src/x-perl.h index 0ee1703..8e140e9 100644 --- a/gettext-tools/src/x-perl.h +++ b/gettext-tools/src/x-perl.h @@ -36,7 +36,7 @@ extern "C" { #define SCANNERS_PERL \ { "perl", extract_perl, \ - &flag_table_perl, &formatstring_perl, &formatstring_perl_brace }, \ + &flag_table_perl, &formatstring_perl, &formatstring_perl_brace, NULL }, \ /* Scan a Perl file and add its translatable strings to mdlp. */ extern void extract_perl (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-php.h b/gettext-tools/src/x-php.h index 765f3f0..79442b4 100644 --- a/gettext-tools/src/x-php.h +++ b/gettext-tools/src/x-php.h @@ -34,7 +34,7 @@ extern "C" { #define SCANNERS_PHP \ { "PHP", extract_php, \ - &flag_table_php, &formatstring_php, NULL }, \ + &flag_table_php, &formatstring_php, NULL, NULL }, \ /* Scan a PHP file and add its translatable strings to mdlp. */ extern void extract_php (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-po.h b/gettext-tools/src/x-po.h index eda1669..0d350d8 100644 --- a/gettext-tools/src/x-po.h +++ b/gettext-tools/src/x-po.h @@ -32,7 +32,7 @@ extern "C" { { "pot", "PO" }, \ #define SCANNERS_PO \ - { "PO", extract_po, NULL, NULL, NULL }, \ + { "PO", extract_po, NULL, NULL, NULL, NULL }, \ /* Scan a PO file and add its translatable strings to mdlp. */ extern void extract_po (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-properties.h b/gettext-tools/src/x-properties.h index b877ae4..fd16ab3 100644 --- a/gettext-tools/src/x-properties.h +++ b/gettext-tools/src/x-properties.h @@ -31,7 +31,7 @@ extern "C" { { "properties", "JavaProperties" }, \ #define SCANNERS_PROPERTIES \ - { "JavaProperties", extract_properties, NULL, NULL, NULL }, \ + { "JavaProperties", extract_properties, NULL, NULL, NULL, NULL }, \ /* Scan a JavaProperties file and add its translatable strings to mdlp. */ extern void extract_properties (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-python.h b/gettext-tools/src/x-python.h index b70b048..f7861fb 100644 --- a/gettext-tools/src/x-python.h +++ b/gettext-tools/src/x-python.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_PYTHON \ { "Python", extract_python, \ - &flag_table_python, &formatstring_python, &formatstring_python_brace }, \ + &flag_table_python, &formatstring_python, &formatstring_python_brace, NULL }, \ /* Scan a Python file and add its translatable strings to mdlp. */ extern void extract_python (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-rst.h b/gettext-tools/src/x-rst.h index dd214fc..6507d0d 100644 --- a/gettext-tools/src/x-rst.h +++ b/gettext-tools/src/x-rst.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_RST \ { "RST", extract_rst, \ - NULL, &formatstring_pascal, NULL }, \ + NULL, &formatstring_pascal, NULL, NULL }, \ /* Scan an RST file and add its translatable strings to mdlp. */ extern void extract_rst (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-scheme.h b/gettext-tools/src/x-scheme.h index 3eb100c..a159ab1 100644 --- a/gettext-tools/src/x-scheme.h +++ b/gettext-tools/src/x-scheme.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_SCHEME \ { "Scheme", extract_scheme, \ - &flag_table_scheme, &formatstring_scheme, NULL }, \ + &flag_table_scheme, &formatstring_scheme, NULL, NULL }, \ /* Scan a Scheme file and add its translatable strings to mdlp. */ extern void extract_scheme (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-sh.h b/gettext-tools/src/x-sh.h index a07954e..d235751 100644 --- a/gettext-tools/src/x-sh.h +++ b/gettext-tools/src/x-sh.h @@ -33,7 +33,7 @@ extern "C" { #define SCANNERS_SH \ { "Shell", extract_sh, \ - &flag_table_sh, &formatstring_sh, NULL }, \ + &flag_table_sh, &formatstring_sh, NULL, NULL }, \ /* Scan a shell script file and add its translatable strings to mdlp. */ extern void extract_sh (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-smalltalk.h b/gettext-tools/src/x-smalltalk.h index def25ff..10767d9 100644 --- a/gettext-tools/src/x-smalltalk.h +++ b/gettext-tools/src/x-smalltalk.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_SMALLTALK \ { "Smalltalk", extract_smalltalk, \ - NULL, &formatstring_smalltalk, NULL }, \ + NULL, &formatstring_smalltalk, NULL, NULL }, \ /* Scan a Smalltalk file and add its translatable strings to mdlp. */ extern void extract_smalltalk (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-stringtable.h b/gettext-tools/src/x-stringtable.h index c405c0c..57df745 100644 --- a/gettext-tools/src/x-stringtable.h +++ b/gettext-tools/src/x-stringtable.h @@ -31,7 +31,7 @@ extern "C" { { "strings", "NXStringTable" }, \ #define SCANNERS_STRINGTABLE \ - { "NXStringTable", extract_stringtable, NULL, NULL, NULL }, \ + { "NXStringTable", extract_stringtable, NULL, NULL, NULL, NULL }, \ /* Scan a JavaProperties file and add its translatable strings to mdlp. */ extern void extract_stringtable (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-tcl.h b/gettext-tools/src/x-tcl.h index aafe6a0..1dc5412 100644 --- a/gettext-tools/src/x-tcl.h +++ b/gettext-tools/src/x-tcl.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_TCL \ { "Tcl", extract_tcl, \ - &flag_table_tcl, &formatstring_tcl, NULL }, \ + &flag_table_tcl, &formatstring_tcl, NULL, NULL }, \ /* Scan a Tcl file and add its translatable strings to mdlp. */ extern void extract_tcl (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-vala.h b/gettext-tools/src/x-vala.h index db9a66d..249709f 100644 --- a/gettext-tools/src/x-vala.h +++ b/gettext-tools/src/x-vala.h @@ -31,7 +31,7 @@ extern "C" { #define SCANNERS_VALA \ { "Vala", extract_vala, \ - &flag_table_vala, &formatstring_c, NULL }, \ + &flag_table_vala, &formatstring_c, NULL, NULL }, \ /* Scan a Vala file and add its translatable strings to mdlp. */ extern void extract_vala (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/x-ycp.h b/gettext-tools/src/x-ycp.h index 01eaf62..78cc853 100644 --- a/gettext-tools/src/x-ycp.h +++ b/gettext-tools/src/x-ycp.h @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_YCP \ { "YCP", extract_ycp, \ - &flag_table_ycp, &formatstring_ycp, NULL }, \ + &flag_table_ycp, &formatstring_ycp, NULL, NULL }, \ /* Scan an YCP file and add its translatable strings to mdlp. */ extern void extract_ycp (FILE *fp, const char *real_filename, diff --git a/gettext-tools/src/xgettext.c b/gettext-tools/src/xgettext.c index 7481d3a..891613e 100644 --- a/gettext-tools/src/xgettext.c +++ b/gettext-tools/src/xgettext.c @@ -265,6 +265,7 @@ struct extractor_ty struct formatstring_parser *formatstring_parser1; struct formatstring_parser *formatstring_parser2; struct formatstring_parser *formatstring_parser3; + struct literalstring_parser *literalstring_parser; }; @@ -1923,6 +1924,32 @@ savable_comment_to_xgettext_comment (refcounted_string_list_ty *rslp) } } +refcounted_string_list_ty * +savable_comment_convert_encoding (refcounted_string_list_ty *comment, + lex_pos_ty *pos) +{ + refcounted_string_list_ty *result; + size_t i; + + result = XMALLOC (refcounted_string_list_ty); + result->refcount = 1; + string_list_init (&result->contents); + + for (i = 0; i < comment->contents.nitems; i++) + { + const char *old_string = comment->contents.item[i]; + char *string = from_current_source_encoding (old_string, + lc_comment, + pos->file_name, + pos->line_number); + string_list_append (&result->contents, string); + if (string != old_string) + free (string); + } + + return result; +} + static FILE * @@ -1992,6 +2019,7 @@ static struct formatstring_parser *current_formatstring_parser1; static struct formatstring_parser *current_formatstring_parser2; static struct formatstring_parser *current_formatstring_parser3; +static struct literalstring_parser *current_literalstring_parser; static void extract_from_file (const char *file_name, extractor_ty extractor, @@ -2011,6 +2039,7 @@ extract_from_file (const char *file_name, extractor_ty extractor, current_formatstring_parser1 = extractor.formatstring_parser1; current_formatstring_parser2 = extractor.formatstring_parser2; current_formatstring_parser3 = extractor.formatstring_parser3; + current_literalstring_parser = extractor.literalstring_parser; extractor.func (fp, real_file_name, logical_file_name, extractor.flag_table, mdlp); @@ -2655,14 +2684,17 @@ arglist_parser_alloc (message_list_ty *mlp, const struct callshapes *shapes) ap->alternative[i].argtotal = shapes->shapes[i].argtotal; ap->alternative[i].xcomments = shapes->shapes[i].xcomments; ap->alternative[i].msgctxt = NULL; + ap->alternative[i].msgctxt_escape = 0; ap->alternative[i].msgctxt_pos.file_name = NULL; ap->alternative[i].msgctxt_pos.line_number = (size_t)(-1); ap->alternative[i].msgid = NULL; + ap->alternative[i].msgid_escape = 0; ap->alternative[i].msgid_context = null_context; ap->alternative[i].msgid_pos.file_name = NULL; ap->alternative[i].msgid_pos.line_number = (size_t)(-1); ap->alternative[i].msgid_comment = NULL; ap->alternative[i].msgid_plural = NULL; + ap->alternative[i].msgid_plural_escape = 0; ap->alternative[i].msgid_plural_context = null_context; ap->alternative[i].msgid_plural_pos.file_name = NULL; ap->alternative[i].msgid_plural_pos.line_number = (size_t)(-1); @@ -2699,13 +2731,16 @@ arglist_parser_clone (struct arglist_parser *ap) ccp->argtotal = cp->argtotal; ccp->xcomments = cp->xcomments; ccp->msgctxt = (cp->msgctxt != NULL ? xstrdup (cp->msgctxt) : NULL); + ccp->msgctxt_escape = cp->msgctxt_escape; ccp->msgctxt_pos = cp->msgctxt_pos; ccp->msgid = (cp->msgid != NULL ? xstrdup (cp->msgid) : NULL); + ccp->msgid_escape = cp->msgid_escape; ccp->msgid_context = cp->msgid_context; ccp->msgid_pos = cp->msgctxt_pos; ccp->msgid_comment = add_reference (cp->msgid_comment); ccp->msgid_plural = (cp->msgid_plural != NULL ? xstrdup (cp->msgid_plural) : NULL); + ccp->msgid_plural_escape = cp->msgid_plural_escape; ccp->msgid_plural_context = cp->msgid_plural_context; ccp->msgid_plural_pos = cp->msgid_plural_pos; } @@ -2715,11 +2750,12 @@ arglist_parser_clone (struct arglist_parser *ap) void -arglist_parser_remember (struct arglist_parser *ap, - int argnum, char *string, - flag_context_ty context, - char *file_name, size_t line_number, - refcounted_string_list_ty *comment) +arglist_parser_remember_literal (struct arglist_parser *ap, + int argnum, char *string, + flag_context_ty context, + char *file_name, size_t line_number, + refcounted_string_list_ty *comment, + enum literalstring_escape_type type) { bool stored_string = false; size_t nalternatives = ap->nalternatives; @@ -2734,6 +2770,7 @@ arglist_parser_remember (struct arglist_parser *ap, if (argnum == cp->argnumc) { cp->msgctxt = string; + cp->msgctxt_escape = type; cp->msgctxt_pos.file_name = file_name; cp->msgctxt_pos.line_number = line_number; stored_string = true; @@ -2745,6 +2782,7 @@ arglist_parser_remember (struct arglist_parser *ap, if (argnum == cp->argnum1) { cp->msgid = string; + cp->msgid_escape = type; cp->msgid_context = context; cp->msgid_pos.file_name = file_name; cp->msgid_pos.line_number = line_number; @@ -2756,6 +2794,7 @@ arglist_parser_remember (struct arglist_parser *ap, if (argnum == cp->argnum2) { cp->msgid_plural = string; + cp->msgid_plural_escape = type; cp->msgid_plural_context = context; cp->msgid_plural_pos.file_name = file_name; cp->msgid_plural_pos.line_number = line_number; @@ -2771,6 +2810,17 @@ arglist_parser_remember (struct arglist_parser *ap, free (string); } +void +arglist_parser_remember (struct arglist_parser *ap, + int argnum, char *string, + flag_context_ty context, + char *file_name, size_t line_number, + refcounted_string_list_ty *comment) +{ + arglist_parser_remember_literal (ap, argnum, string, context, + file_name, line_number, + comment, 0); +} bool arglist_parser_decidedp (struct arglist_parser *ap, int argnum) @@ -3011,6 +3061,8 @@ arglist_parser_done (struct arglist_parser *ap, int argnum) { flag_context_ty msgid_context = best_cp->msgid_context; flag_context_ty msgid_plural_context = best_cp->msgid_plural_context; + struct literalstring_parser *parser = current_literalstring_parser; + const char *encoding; /* Special support for the 3-argument tr operator in Qt: When --qt and --keyword=tr:1,1,2c,3t are specified, add to the @@ -3024,15 +3076,90 @@ arglist_parser_done (struct arglist_parser *ap, int argnum) msgid_plural_context.is_format3 = yes_according_to_context; } + if (best_cp->msgctxt != NULL) + { + if (parser != NULL && best_cp->msgctxt_escape != 0) + { + char *msgctxt = + parser->parse (best_cp->msgctxt, + &best_cp->msgctxt_pos, + best_cp->msgctxt_escape); + free (best_cp->msgctxt); + best_cp->msgctxt = msgctxt; + } + else + { + lex_pos_ty *pos = &best_cp->msgctxt_pos; + CONVERT_STRING (best_cp->msgctxt, lc_string); + } + } + + if (parser != NULL && best_cp->msgid_escape != 0) + { + char *msgid = parser->parse (best_cp->msgid, + &best_cp->msgid_pos, + best_cp->msgid_escape); + free (best_cp->msgid); + if (best_cp->msgid_plural == best_cp->msgid) + best_cp->msgid_plural = msgid; + best_cp->msgid = msgid; + } + else + { + lex_pos_ty *pos = &best_cp->msgid_pos; + CONVERT_STRING (best_cp->msgid, lc_string); + } + + if (best_cp->msgid_comment != NULL) + { + refcounted_string_list_ty *msgid_comment = + savable_comment_convert_encoding (best_cp->msgid_comment, + &best_cp->msgid_pos); + drop_reference (best_cp->msgid_comment); + best_cp->msgid_comment = msgid_comment; + } + + /* best_cp->msgctxt and best_cp->msgid are already in + UTF-8. Prevent further conversion in remember_a_message. */ + encoding = xgettext_current_source_encoding; + xgettext_current_source_encoding = po_charset_utf8; mp = remember_a_message (ap->mlp, best_cp->msgctxt, best_cp->msgid, msgid_context, &best_cp->msgid_pos, NULL, best_cp->msgid_comment); + xgettext_current_source_encoding = encoding; + if (mp != NULL && best_cp->msgid_plural != NULL) - remember_a_message_plural (mp, best_cp->msgid_plural, - msgid_plural_context, + { + /* best_cp->msgid_plural may point to best_cp->msgid. + In that case, it is already interpreted and converted. */ + if (best_cp->msgid_plural != best_cp->msgid) + { + if (parser != NULL + && best_cp->msgid_plural_escape != 0) + { + char *msgid_plural = + parser->parse (best_cp->msgid_plural, &best_cp->msgid_plural_pos, - NULL); + best_cp->msgid_plural_escape); + free (best_cp->msgid_plural); + best_cp->msgid_plural = msgid_plural; + } + else + { + lex_pos_ty *pos = &best_cp->msgid_plural_pos; + CONVERT_STRING (best_cp->msgid_plural, lc_string); + } + } + + encoding = xgettext_current_source_encoding; + xgettext_current_source_encoding = po_charset_utf8; + remember_a_message_plural (mp, best_cp->msgid_plural, + msgid_plural_context, + &best_cp->msgid_plural_pos, + NULL); + xgettext_current_source_encoding = encoding; + } } if (best_cp->xcomments.nitems > 0) @@ -3434,6 +3561,7 @@ language_to_extractor (const char *name) flag_context_list_table_ty *flag_table; struct formatstring_parser *formatstring_parser1; struct formatstring_parser *formatstring_parser2; + struct literalstring_parser *literalstring_parser; }; typedef struct table_ty table_ty; @@ -3480,6 +3608,7 @@ language_to_extractor (const char *name) result.formatstring_parser1 = tp->formatstring_parser1; result.formatstring_parser2 = tp->formatstring_parser2; result.formatstring_parser3 = NULL; + result.literalstring_parser = tp->literalstring_parser; /* Handle --qt. It's preferrable to handle this facility here rather than through an option --language=C++/Qt because the latter would diff --git a/gettext-tools/src/xgettext.h b/gettext-tools/src/xgettext.h index 059a419..baba1de 100644 --- a/gettext-tools/src/xgettext.h +++ b/gettext-tools/src/xgettext.h @@ -242,6 +242,24 @@ extern refcounted_string_list_ty *savable_comment; extern void savable_comment_add (const char *str); extern void savable_comment_reset (void); +/* Convert character encoding of COMMENT according to the current + source encoding. Returns a new refcounted_string_list_ty. */ +extern refcounted_string_list_ty * + savable_comment_convert_encoding (refcounted_string_list_ty *comment, + lex_pos_ty *pos); + + +enum literalstring_escape_type +{ + LET_ANSI_C = 1 << 0, + LET_UNICODE = 1 << 1 +}; + +struct literalstring_parser +{ + char * (*parse) (const char *string, lex_pos_ty *pos, + enum literalstring_escape_type type); +}; /* Add a message to the list of extracted messages. msgctxt must be either NULL or a malloc()ed string; its ownership is passed @@ -275,7 +293,6 @@ extern void remember_a_message_plural (message_ty *mp, lex_pos_ty *pos, refcounted_string_list_ty *comment); - /* Represents the progressive parsing of an argument list w.r.t. a single 'struct callshape'. */ struct partial_call @@ -288,12 +305,15 @@ struct partial_call int argtotal; /* total number of arguments, 0 if unspecified */ string_list_ty xcomments; /* auto-extracted comments */ char *msgctxt; /* context - owned string, or NULL */ + enum literalstring_escape_type msgctxt_escape; lex_pos_ty msgctxt_pos; char *msgid; /* msgid - owned string, or NULL */ + enum literalstring_escape_type msgid_escape; flag_context_ty msgid_context; lex_pos_ty msgid_pos; refcounted_string_list_ty *msgid_comment; char *msgid_plural; /* msgid_plural - owned string, or NULL */ + enum literalstring_escape_type msgid_plural_escape; flag_context_ty msgid_plural_context; lex_pos_ty msgid_plural_pos; }; @@ -326,6 +346,19 @@ extern void arglist_parser_remember (struct arglist_parser *ap, flag_context_ty context, char *file_name, size_t line_number, refcounted_string_list_ty *comment); +/* Adds an uninterpreted string argument to an arglist_parser. ARGNUM + must be > 0. + STRING is must be malloc()ed string; its ownership is passed to the callee. + FILE_NAME must be allocated with indefinite extent. + COMMENT may be savable_comment, or it may be a saved copy of savable_comment + (then add_reference must be used when saving it, and drop_reference while + dropping it). Clear savable_comment. */ +extern void arglist_parser_remember_literal (struct arglist_parser *ap, + int argnum, char *string, + flag_context_ty context, + char *file_name, size_t line_number, + refcounted_string_list_ty *comment, + enum literalstring_escape_type type); /* Tests whether an arglist_parser has is not waiting for more arguments after argument ARGNUM. */ extern bool arglist_parser_decidedp (struct arglist_parser *ap, int argnum); |