diff options
Diffstat (limited to 'gettext-tools/src/xgettext.c')
-rw-r--r-- | gettext-tools/src/xgettext.c | 145 |
1 files changed, 137 insertions, 8 deletions
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 |