From: Bruno Haible Date: Sun, 4 Nov 2018 19:09:47 +0000 (+0100) Subject: xgettext: Fix result for concatenation of strings with escape sequences. X-Git-Tag: v0.20~271 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a8773dd6049b2b7b37e7ccade07e12ba8bc8aa73;p=thirdparty%2Fgettext.git xgettext: Fix result for concatenation of strings with escape sequences. Reported by Morten Welinder in and . Revert commits from 2014-05-07 xgettext: Provide a way to interpret string literals lazily 2014-05-07 c: Interpret string literals lazily 2014-05-09 vala: Interpret string literals lazily 2014-12-02 c: Support C++11 string literals and subsequent fixes of these. * gettext-tools/src/xgettext.h (savable_comment_convert_encoding): Remove declaration. (enum literalstring_escape_type, struct literalstring_parser): Remove types. (struct partial_call): Update. (arglist_parser_remember_literal): Remove declaration. * gettext-tools/src/xgettext.c (struct extractor_ty): Remove 'literalstring_parser' field. (savable_comment_convert_encoding): Remove function. (current_literalstring_parser): Remove variable. (extract_from_file, arglist_parser_alloc, arglist_parser_clone): Update. (arglist_parser_remember_literal): Remove function. (arglist_parser_remember_msgctxt): Simplify accordingly. * gettext-tools/src/x-*.h (SCANNERS_*): Remove literalstring_parser initializer. * gettext-tools/src/x-c.h (literalstring_c): Remove declaration. * gettext-tools/src/x-c.c: Remove all traces of literalstring_escape_type and literalstring_parser. (phase7_getc, phase7_ungetc): Reinstantiate functions. (phase5_get): Simplify. Use phase7_getc. * gettext-tools/src/x-vala.c: Remove all traces of literalstring_escape_type and literalstring_parser. (phase7_getc, phase7_ungetc): Reinstantiate functions. (phase3_get): Simplify. Use phase7_getc. (extract_balanced): Simplify. --- diff --git a/gettext-tools/src/x-appdata.h b/gettext-tools/src/x-appdata.h index f020337de..6b18992ec 100644 --- a/gettext-tools/src/x-appdata.h +++ b/gettext-tools/src/x-appdata.h @@ -1,6 +1,5 @@ /* xgettext AppData file backend. - Copyright (C) 2002-2003, 2006, 2013, 2015-2017 Free Software Foundation, - Inc. + Copyright (C) 2002-2003, 2006, 2013, 2015-2017 Free Software Foundation, Inc. Written by Philip Withnall , 2015. This program is free software: you can redistribute it and/or modify diff --git a/gettext-tools/src/x-awk.h b/gettext-tools/src/x-awk.h index 62b53f7e9..f818d5582 100644 --- a/gettext-tools/src/x-awk.h +++ b/gettext-tools/src/x-awk.h @@ -1,5 +1,5 @@ /* xgettext awk backend. - Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2003, 2006, 2014-2015, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2002. This program is free software: you can redistribute it and/or modify @@ -34,7 +34,7 @@ extern "C" { #define SCANNERS_AWK \ { "awk", extract_awk, \ - &flag_table_awk, &formatstring_awk, NULL, NULL }, \ + &flag_table_awk, &formatstring_awk, 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.c b/gettext-tools/src/x-c.c index ec3948d4a..1b81dfd5f 100644 --- a/gettext-tools/src/x-c.c +++ b/gettext-tools/src/x-c.c @@ -1,6 +1,5 @@ /* xgettext C/C++/ObjectiveC backend. - Copyright (C) 1995-1998, 2000-2009, 2012, 2015-2016, 2018 Free Software - Foundation, Inc. + Copyright (C) 1995-1998, 2000-2009, 2012-2015, 2018 Free Software Foundation, Inc. This file was written by Peter Miller @@ -955,243 +954,232 @@ struct token_ty char *string; /* for token_type_name, token_type_string_literal */ refcounted_string_list_ty *comment; /* for token_type_string_literal, token_type_objc_special */ - enum literalstring_escape_type escape; /* for token_type_string_literal */ long number; int line_number; }; -/* Free the memory pointed to by a 'struct token_ty'. */ -static inline void -free_token (token_ty *tp) -{ - if (tp->type == token_type_name || tp->type == token_type_string_literal) - free (tp->string); - if (tp->type == token_type_string_literal - || tp->type == token_type_objc_special) - drop_reference (tp->comment); -} +/* 7. Replace escape sequences within character strings with their + single character equivalents. This is called from phase 5, because + we don't have to worry about the #include argument. There are + pathological cases which could bite us (like the DOS directory + separator), but just pretend it can't happen. */ +/* Return value of phase7_getc when EOF is reached. */ +#define P7_EOF (-1) +#define P7_STRING_END (-2) -static char * -literalstring_parse (const char *string, lex_pos_ty *pos, - enum literalstring_escape_type type) -{ - struct mixed_string_buffer *bp; - const char *p; +/* Replace escape sequences within character strings with their single + character equivalents. */ +#define P7_QUOTES (-3) +#define P7_QUOTE (-4) +#define P7_NEWLINE (-5) - /* Start accumulating the string. */ - bp = mixed_string_buffer_alloc (lc_string, - logical_file_name, - line_number); +/* Convert an UTF-16 or UTF-32 code point to a return value that can be + distinguished from a single-byte return value. */ +#define UNICODE(code) (0x100 + (code)) - for (p = string; ; ) - { - int c = *p++; +/* Test a return value of phase7_getuc whether it designates an UTF-16 or + UTF-32 code point. */ +#define IS_UNICODE(p7_result) ((p7_result) >= 0x100) - if (c == '\0') - break; +/* Extract the UTF-16 or UTF-32 code of a return value that satisfies + IS_UNICODE. */ +#define UNICODE_VALUE(p7_result) ((p7_result) - 0x100) - if (c != '\\') - { - mixed_string_buffer_append_char (bp, c); - continue; - } - if (!(type & LET_ANSI_C) && !(type & LET_UNICODE)) - { - mixed_string_buffer_append_char (bp, '\\'); - continue; - } +static int +phase7_getc () +{ + int c, n, j; - c = *p++; - if (c == '\0') - break; + /* Use phase 3, because phase 4 elides comments. */ + c = phase3_getc (); - if (type & LET_ANSI_C) - switch (c) - { - case '"': - case '\'': - case '?': - case '\\': - mixed_string_buffer_append_char (bp, c); - continue; - - case 'a': - mixed_string_buffer_append_char (bp, '\a'); - continue; - case 'b': - mixed_string_buffer_append_char (bp, '\b'); - continue; - - /* The \e escape is preculiar to gcc, and assumes an ASCII - character set (or superset). We don't provide support for it - here. */ - - case 'f': - mixed_string_buffer_append_char (bp, '\f'); - continue; - case 'n': - mixed_string_buffer_append_char (bp, '\n'); - continue; - case 'r': - mixed_string_buffer_append_char (bp, '\r'); - continue; - case 't': - mixed_string_buffer_append_char (bp, '\t'); - continue; - case 'v': - mixed_string_buffer_append_char (bp, '\v'); - continue; - - case 'x': - c = *p++; - if (c == '\0') - break; - switch (c) - { - default: - mixed_string_buffer_append_char (bp, '\\'); - mixed_string_buffer_append_char (bp, 'x'); - mixed_string_buffer_append_char (bp, c); - break; + /* Return a magic newline indicator, so that we can distinguish + between the user requesting a newline in the string (e.g. using + "\n" or "\012") from the user failing to terminate the string or + character constant. The ANSI C standard says: 3.1.3.4 Character + Constants contain "any character except single quote, backslash or + newline; or an escape sequence" and 3.1.4 String Literals contain + "any character except double quote, backslash or newline; or an + escape sequence". + + Most compilers give a fatal error in this case, however gcc is + stupidly silent, even though this is a very common typo. OK, so + "gcc --pedantic" will tell me, but that gripes about too much other + stuff. Could I have a "gcc -Wnewline-in-string" option, or + better yet a "gcc -fno-newline-in-string" option, please? Gcc is + also inconsistent between string literals and character constants: + you may not embed newlines in character constants; try it, you get + a useful diagnostic. --PMiller */ + if (c == '\n') + return P7_NEWLINE; + + if (c == '"') + return P7_QUOTES; + if (c == '\'') + return P7_QUOTE; + if (c != '\\') + return c; + c = phase3_getc (); + switch (c) + { + default: + /* Unknown escape sequences really should be an error, but just + ignore them, and let the real compiler complain. */ + phase3_ungetc (c); + return '\\'; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - { - int n; + case '"': + case '\'': + case '?': + case '\\': + return c; - for (n = 0; ; c = *p++) - { - switch (c) - { - default: - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - n = n * 16 + c - '0'; - continue; - - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': - n = n * 16 + 10 + c - 'A'; - continue; - - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': - n = n * 16 + 10 + c - 'a'; - continue; - } - break; - } + case 'a': + return '\a'; + case 'b': + return '\b'; - mixed_string_buffer_append_char (bp, n); - --p; - } - break; - } - continue; + /* The \e escape is preculiar to gcc, and assumes an ASCII + character set (or superset). We don't provide support for it + here. */ - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'v': + return '\v'; + + case 'x': + c = phase3_getc (); + switch (c) + { + default: + phase3_ungetc (c); + phase3_ungetc ('x'); + return '\\'; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + break; + } + n = 0; + for (;;) + { + switch (c) { - int n, j; + default: + phase3_ungetc (c); + return n; - for (n = 0, j = 0; j < 3; ++j) - { - n = n * 8 + c - '0'; - c = *p++; - switch (c) - { - default: - break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = n * 16 + c - '0'; + break; - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - continue; - } - break; - } + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + n = n * 16 + 10 + c - 'A'; + break; - mixed_string_buffer_append_char (bp, n); - --p; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + n = n * 16 + 10 + c - 'a'; + break; } - continue; - } + c = phase3_getc (); + } + return n; - if (type & LET_UNICODE) - switch (c) - { - case 'U': case 'u': + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + n = 0; + for (j = 0; j < 3; ++j) + { + n = n * 8 + c - '0'; + c = phase3_getc (); + switch (c) { - unsigned char buf[8]; - int prefix = c; - int length = prefix == 'u' ? 4 : 8; - int n, j; - - for (n = 0, j = 0; j < length; j++) - { - c = *p++; - - if (c >= '0' && c <= '9') - n = (n << 4) + (c - '0'); - else if (c >= 'A' && c <= 'F') - n = (n << 4) + (c - 'A' + 10); - else if (c >= 'a' && c <= 'f') - n = (n << 4) + (c - 'a' + 10); - else - break; - - buf[j] = c; - } + default: + break; - if (j == length) - { - if (n < 0x110000) - mixed_string_buffer_append_unicode (bp, n); - else - { - error_with_progname = false; - error_at_line (0, 0, - pos->file_name, pos->line_number, - _("\ -warning: invalid Unicode character")); - error_with_progname = true; - } - } - else - { - int i; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + continue; + } + break; + } + phase3_ungetc (c); + return n; - mixed_string_buffer_append_char (bp, '\\'); - mixed_string_buffer_append_char (bp, prefix); + case 'U': case 'u': + { + unsigned char buf[8]; - for (i = 0; i < j; i++) - mixed_string_buffer_append_char (bp, buf[i]); + n = 0; + for (j = 0; j < (c == 'u' ? 4 : 8); j++) + { + int c1 = phase3_getc (); + + if (c1 >= '0' && c1 <= '9') + n = (n << 4) + (c1 - '0'); + else if (c1 >= 'A' && c1 <= 'F') + n = (n << 4) + (c1 - 'A' + 10); + else if (c1 >= 'a' && c1 <= 'f') + n = (n << 4) + (c1 - 'a' + 10); + else + { + phase3_ungetc (c1); + while (--j >= 0) + phase3_ungetc (buf[j]); + phase3_ungetc (c); + return '\\'; + } - --p; - } - } - continue; + buf[j] = c1; } - if (c == '\0') - break; + if (n < 0x110000) + return UNICODE (n); + + error_with_progname = false; + error (0, 0, _("%s:%d: warning: invalid Unicode character"), + logical_file_name, line_number); + error_with_progname = true; - mixed_string_buffer_append_char (bp, c); + while (--j >= 0) + phase3_ungetc (buf[j]); + phase3_ungetc (c); + return '\\'; + } } +} + - return mixed_string_buffer_done (bp); +static void +phase7_ungetc (int c) +{ + phase3_ungetc (c); } -struct literalstring_parser literalstring_c = - { - literalstring_parse - }; + +/* Free the memory pointed to by a 'struct token_ty'. */ +static inline void +free_token (token_ty *tp) +{ + if (tp->type == token_type_name || tp->type == token_type_string_literal) + free (tp->string); + if (tp->type == token_type_string_literal + || tp->type == token_type_objc_special) + drop_reference (tp->comment); +} /* 5. Parse each resulting logical line as preprocessing tokens and @@ -1208,11 +1196,6 @@ phase5_get (token_ty *tp) static int bufmax; int bufpos; int c; - int last_was_backslash; - bool raw_expected = false; - int delimiter_left_end; - int delimiter_right_start; - int last_rparen; if (phase5_pushback_length) { @@ -1292,68 +1275,6 @@ phase5_get (token_ty *tp) continue; default: - /* Recognize string literals prefixed by R, u8, u8R, u, - uR, U, UR, L, or LR. It is defined in the C standard - ISO/IEC 9899:201x and the C++ standard ISO/IEC - 14882:2011. The raw string literals prefixed by R, - u8R, uR, UR, or LR are only valid in C++. - - Since gettext's argument is a byte sequence, we are - only interested in u8, R, and u8R. */ - if (c == '"') - { - bool is_prefix = false; - - switch (buffer[0]) - { - case 'R': - if (cxx_extensions && bufpos == 1) - { - is_prefix = true; - raw_expected = true; - } - break; - case 'u': - if (bufpos == 1) - is_prefix = true; - else - switch (buffer[1]) - { - case 'R': - if (cxx_extensions && bufpos == 2) - { - is_prefix = true; - raw_expected = true; - } - break; - case '8': - if (bufpos == 2) - is_prefix = true; - else if (cxx_extensions - && bufpos == 3 && buffer[2] == 'R') - { - is_prefix = true; - raw_expected = true; - } - break; - } - break; - case 'U': - case 'L': - if (bufpos == 1) - is_prefix = true; - else if (cxx_extensions - && bufpos == 2 && buffer[1] == 'R') - { - is_prefix = true; - raw_expected = true; - } - break; - } - - if (is_prefix) - goto string; - } phase4_ungetc (c); break; } @@ -1509,148 +1430,69 @@ phase5_get (token_ty *tp) but ignoring it has no effect unless one of the keywords is "L". Just pretend it won't happen. Also, we don't need to remember the character constant. */ - last_was_backslash = false; for (;;) { - c = phase3_getc (); - if (last_was_backslash) - { - last_was_backslash = false; - continue; - } - switch (c) + c = phase7_getc (); + if (c == P7_NEWLINE) { - case '\\': - last_was_backslash = true; - /* FALLTHROUGH */ - default: - continue; - case '\n': error_with_progname = false; error (0, 0, _("%s:%d: warning: unterminated character constant"), logical_file_name, line_number - 1); error_with_progname = true; - phase3_ungetc ('\n'); - break; - case EOF: case '\'': + phase7_ungetc ('\n'); break; } - break; + if (c == EOF || c == P7_QUOTE) + break; } tp->type = token_type_character_constant; return; case '"': { - string: + struct mixed_string_buffer *bp; + + /* Start accumulating the string. */ + bp = mixed_string_buffer_alloc (lc_string, + logical_file_name, + line_number); + /* We could worry about the 'L' before wide string constants, but since gettext's argument is not a wide character string, let the compiler complain about the argument not matching the prototype. Just pretend it won't happen. */ - last_was_backslash = false; - delimiter_left_end = -1; - delimiter_right_start = -1; - last_rparen = -1; - bufpos = 0; for (;;) { - c = phase3_getc (); - if (last_was_backslash && !raw_expected) - { - last_was_backslash = false; - if (bufpos >= bufmax) - { - bufmax = 2 * bufmax + 10; - buffer = xrealloc (buffer, bufmax); - } - buffer[bufpos++] = c; - continue; - } - switch (c) - { - case '\\': - last_was_backslash = true; - /* FALLTHROUGH */ - default: - if (raw_expected) - { - if (c == '(' && delimiter_left_end < 0) - delimiter_left_end = bufpos; - else if (c == ')' && delimiter_left_end >= 0) - last_rparen = bufpos; - } - else if (c == '\n') - { - error_with_progname = false; - error (0, 0, - _("%s:%d: warning: unterminated string literal"), - logical_file_name, line_number - 1); - error_with_progname = true; - phase3_ungetc ('\n'); - break; - } - if (bufpos >= bufmax) - { - bufmax = 2 * bufmax + 10; - buffer = xrealloc (buffer, bufmax); - } - buffer[bufpos++] = c; - continue; + c = phase7_getc (); - case '"': - if (raw_expected && delimiter_left_end >= 0) - { - if (last_rparen < 0 - || delimiter_left_end != bufpos - (last_rparen + 1) - || strncmp (buffer, buffer + last_rparen + 1, - delimiter_left_end) != 0) - { - if (bufpos >= bufmax) - { - bufmax = 2 * bufmax + 10; - buffer = xrealloc (buffer, bufmax); - } - buffer[bufpos++] = c; - continue; - } - delimiter_right_start = last_rparen; - } - break; + /* Keep line_number in sync. */ + bp->line_number = line_number; - case EOF: - break; - } - break; - } - if (bufpos >= bufmax) - { - bufmax = 2 * bufmax + 10; - buffer = xrealloc (buffer, bufmax); - } - buffer[bufpos] = 0; - - if (raw_expected) - { - if (delimiter_left_end < 0 || delimiter_right_start < 0) + if (c == P7_NEWLINE) { error_with_progname = false; error (0, 0, _("%s:%d: warning: unterminated string literal"), logical_file_name, line_number - 1); error_with_progname = true; + phase7_ungetc ('\n'); + break; } - else + if (c == EOF || c == P7_QUOTES) + break; + if (c == P7_QUOTE) + c = '\''; + if (IS_UNICODE (c)) { - buffer[delimiter_right_start] = '\0'; - tp->type = token_type_string_literal; - tp->string = xstrdup (&buffer[delimiter_left_end + 1]); - tp->escape = LET_NONE; - tp->comment = add_reference (savable_comment); - return; + assert (UNICODE_VALUE (c) >= 0 + && UNICODE_VALUE (c) < 0x110000); + mixed_string_buffer_append_unicode (bp, + UNICODE_VALUE (c)); } + else + mixed_string_buffer_append_char (bp, c); } tp->type = token_type_string_literal; - tp->string = xstrdup (buffer); - tp->escape = LET_ANSI_C | LET_UNICODE; + tp->string = mixed_string_buffer_done (bp); tp->comment = add_reference (savable_comment); return; } @@ -1904,7 +1746,6 @@ phase8a_get (token_ty *tp) tp->string = new_string; tp->comment = add_reference (savable_comment); tp->type = token_type_string_literal; - tp->escape = LET_ANSI_C | LET_UNICODE; } } @@ -1985,10 +1826,7 @@ phase8c_unget (token_ty *tp) /* 8. Concatenate adjacent string literals to form single string literals (because we don't expand macros, there are a few things we - will miss). - - FIXME: handle the case when the string literals have different - tp->escape setting. */ + will miss). */ static void phase8_get (token_ty *tp) @@ -2044,9 +1882,6 @@ struct xgettext_token_ty xgettext_token_type_keyword, xgettext_token_type_symbol. */ char *string; - /* This field is used only for xgettext_token_type_string_literal. */ - enum literalstring_escape_type escape; - /* This field is used only for xgettext_token_type_string_literal. */ refcounted_string_list_ty *comment; @@ -2122,7 +1957,6 @@ x_c_lex (xgettext_token_ty *tp) tp->type = xgettext_token_type_string_literal; tp->string = token.string; - tp->escape = token.escape; tp->comment = token.comment; tp->pos.file_name = logical_file_name; tp->pos.line_number = token.line_number; @@ -2234,7 +2068,10 @@ extract_parenthesized (message_list_ty *mlp, arglist_parser_alloc (mlp, state ? next_shapes : NULL))) { + xgettext_current_source_encoding = po_charset_utf8; arglist_parser_done (argparser, arg); + xgettext_current_source_encoding = + xgettext_global_source_encoding; return true; } next_context_iter = null_context_list_iterator; @@ -2243,7 +2080,9 @@ extract_parenthesized (message_list_ty *mlp, continue; case xgettext_token_type_rparen: + xgettext_current_source_encoding = po_charset_utf8; arglist_parser_done (argparser, arg); + xgettext_current_source_encoding = xgettext_global_source_encoding; return false; case xgettext_token_type_comma: @@ -2277,41 +2116,16 @@ extract_parenthesized (message_list_ty *mlp, continue; case xgettext_token_type_string_literal: + xgettext_current_source_encoding = po_charset_utf8; if (extract_all) - { - char *string; - refcounted_string_list_ty *comment; - const char *encoding; - - string = literalstring_parse (token.string, &token.pos, - token.escape); - free (token.string); - token.string = string; - - if (token.comment != NULL) - { - comment = savable_comment_convert_encoding (token.comment, - &token.pos); - drop_reference (token.comment); - token.comment = comment; - } - - /* token.string and token.comment are already converted - to UTF-8. Prevent further conversion in - remember_a_message. */ - encoding = xgettext_current_source_encoding; - xgettext_current_source_encoding = po_charset_utf8; - remember_a_message (mlp, NULL, token.string, inner_context, - &token.pos, NULL, token.comment); - xgettext_current_source_encoding = encoding; - } + remember_a_message (mlp, NULL, token.string, inner_context, + &token.pos, NULL, token.comment); else - arglist_parser_remember_literal (argparser, arg, token.string, - inner_context, - token.pos.file_name, - token.pos.line_number, - token.comment, - token.escape); + arglist_parser_remember (argparser, arg, token.string, + inner_context, + token.pos.file_name, token.pos.line_number, + token.comment); + xgettext_current_source_encoding = xgettext_global_source_encoding; drop_reference (token.comment); next_context_iter = null_context_list_iterator; selectorcall_context_iter = null_context_list_iterator; @@ -2325,7 +2139,9 @@ extract_parenthesized (message_list_ty *mlp, continue; case xgettext_token_type_eof: + xgettext_current_source_encoding = po_charset_utf8; arglist_parser_done (argparser, arg); + xgettext_current_source_encoding = xgettext_global_source_encoding; return true; default: diff --git a/gettext-tools/src/x-c.h b/gettext-tools/src/x-c.h index 29b6f3674..5413aea6c 100644 --- a/gettext-tools/src/x-c.h +++ b/gettext-tools/src/x-c.h @@ -1,6 +1,5 @@ /* xgettext C/C++/ObjectiveC backend. - Copyright (C) 2001-2003, 2006, 2009, 2015-2016 Free Software Foundation, - Inc. + Copyright (C) 2001-2003, 2006, 2009, 2014-2015, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2001. This program is free software: you can redistribute it and/or modify @@ -44,20 +43,16 @@ extern "C" { #define SCANNERS_C \ { "C", extract_c, \ &flag_table_c, \ - &formatstring_c, NULL, \ - &literalstring_c }, \ + &formatstring_c, NULL }, \ { "C++", extract_cxx, \ &flag_table_c, \ - &formatstring_c, NULL, \ - &literalstring_c }, \ + &formatstring_c, NULL }, \ { "ObjectiveC", extract_objc, \ &flag_table_objc, \ - &formatstring_c, &formatstring_objc, \ - &literalstring_c }, \ + &formatstring_c, &formatstring_objc }, \ { "GCC-source", extract_c, \ &flag_table_gcc_internal, \ - &formatstring_gcc_internal, &formatstring_gfc_internal, \ - &literalstring_c }, \ + &formatstring_gcc_internal, &formatstring_gfc_internal }, \ /* Scan a C file and add its translatable strings to mdlp. */ extern void extract_c (FILE *fp, const char *real_filename, @@ -93,9 +88,6 @@ extern void init_flag_table_gcc_internal (void); extern void init_flag_table_kde (void); -extern struct literalstring_parser literalstring_c; - - #ifdef __cplusplus } #endif diff --git a/gettext-tools/src/x-csharp.h b/gettext-tools/src/x-csharp.h index 1fcece4ba..27f0b0241 100644 --- a/gettext-tools/src/x-csharp.h +++ b/gettext-tools/src/x-csharp.h @@ -1,5 +1,5 @@ /* xgettext C# backend. - Copyright (C) 2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2003. This program is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_CSHARP \ { "C#", extract_csharp, \ - &flag_table_csharp, &formatstring_csharp, NULL, NULL }, \ + &flag_table_csharp, &formatstring_csharp, 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 f73d5b63c..47242e3a9 100644 --- a/gettext-tools/src/x-desktop.h +++ b/gettext-tools/src/x-desktop.h @@ -1,5 +1,5 @@ /* xgettext Desktop Entry backend. - Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copyright (C) 2014, 2018 Free Software Foundation, Inc. Written by Daiki Ueno , 2014. This program is free software: you can redistribute it and/or modify @@ -31,7 +31,7 @@ extern "C" { { "desktop", "Desktop" }, \ #define SCANNERS_DESKTOP \ - { "Desktop", extract_desktop, NULL, NULL, NULL, NULL }, \ + { "Desktop", extract_desktop, 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 009b71db8..99490c258 100644 --- a/gettext-tools/src/x-elisp.h +++ b/gettext-tools/src/x-elisp.h @@ -1,5 +1,5 @@ /* xgettext Emacs Lisp backend. - Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2002. This program is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_ELISP \ { "EmacsLisp", extract_elisp, \ - &flag_table_elisp, &formatstring_elisp, NULL, NULL }, \ + &flag_table_elisp, &formatstring_elisp, 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 19d33ceea..1c70bba37 100644 --- a/gettext-tools/src/x-glade.h +++ b/gettext-tools/src/x-glade.h @@ -1,5 +1,5 @@ /* xgettext glade backend. - Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2003, 2006, 2013-2015, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2002. This program is free software: you can redistribute it and/or modify @@ -36,7 +36,7 @@ extern "C" { { "ui", NULL }, \ #define SCANNERS_GLADE \ - { "glade", NULL, NULL, NULL, NULL, NULL }, \ + { "glade", NULL, NULL, NULL, NULL }, \ #ifdef __cplusplus diff --git a/gettext-tools/src/x-gsettings.h b/gettext-tools/src/x-gsettings.h index e7f53fc9c..2f1da540f 100644 --- a/gettext-tools/src/x-gsettings.h +++ b/gettext-tools/src/x-gsettings.h @@ -1,6 +1,5 @@ /* xgettext GSettings schema file backend. - Copyright (C) 2002-2003, 2006, 2013, 2015-2016 Free Software Foundation, - Inc. + Copyright (C) 2002-2003, 2006, 2013-2015, 2018 Free Software Foundation, Inc. Written by Daiki Ueno , 2013. This program is free software: you can redistribute it and/or modify @@ -34,7 +33,7 @@ extern "C" { { "gschema.xml", NULL }, \ #define SCANNERS_GSETTINGS \ - { "gsettings", NULL, NULL, NULL, NULL, NULL }, \ + { "gsettings", NULL, NULL, NULL, NULL }, \ #ifdef __cplusplus diff --git a/gettext-tools/src/x-java.h b/gettext-tools/src/x-java.h index 3863f1621..b2487e2dc 100644 --- a/gettext-tools/src/x-java.h +++ b/gettext-tools/src/x-java.h @@ -1,5 +1,5 @@ /* xgettext Java backend. - Copyright (C) 2001-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Tommy Johansson , 2001. This program is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_JAVA \ { "Java", extract_java, \ - &flag_table_java, &formatstring_java, NULL, NULL }, \ + &flag_table_java, &formatstring_java, 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 87dc42784..c59acc306 100644 --- a/gettext-tools/src/x-javascript.h +++ b/gettext-tools/src/x-javascript.h @@ -1,6 +1,5 @@ /* xgettext JavaScript backend. - Copyright (C) 2002-2003, 2006, 2013, 2015-2016 Free Software Foundation, - Inc. + Copyright (C) 2002-2003, 2006, 2010, 2013-2014, 2018 Free Software Foundation, Inc. This file was written by Andreas Stricker , 2010. It's based on x-python from Bruno Haible. @@ -34,7 +33,7 @@ extern "C" { #define SCANNERS_JAVASCRIPT \ { "JavaScript", extract_javascript, \ - &flag_table_javascript, &formatstring_javascript, NULL, NULL }, \ + &flag_table_javascript, &formatstring_javascript, 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 6e57f38be..e1b735b6e 100644 --- a/gettext-tools/src/x-librep.h +++ b/gettext-tools/src/x-librep.h @@ -1,5 +1,5 @@ /* xgettext librep backend. - Copyright (C) 2001-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2001. This program is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_LIBREP \ { "librep", extract_librep, \ - &flag_table_librep, &formatstring_librep, NULL, NULL }, \ + &flag_table_librep, &formatstring_librep, 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 9a762c680..ea7512395 100644 --- a/gettext-tools/src/x-lisp.h +++ b/gettext-tools/src/x-lisp.h @@ -1,5 +1,5 @@ /* xgettext Lisp backend. - Copyright (C) 2001-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2001. This program is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_LISP \ { "Lisp", extract_lisp, \ - &flag_table_lisp, &formatstring_lisp, NULL, NULL }, \ + &flag_table_lisp, &formatstring_lisp, 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 f4b615ed0..e30c751e2 100644 --- a/gettext-tools/src/x-lua.h +++ b/gettext-tools/src/x-lua.h @@ -1,5 +1,5 @@ /* xgettext Lua backend. - Copyright (C) 2011, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2011-2014, 2018 Free Software Foundation, Inc. Written by Ľubomír Remák , 2011 This program is free software: you can redistribute it and/or modify @@ -30,7 +30,7 @@ extern "C" #define SCANNERS_LUA \ { "Lua", extract_lua, \ - &flag_table_lua, &formatstring_lua, NULL, NULL }, \ + &flag_table_lua, &formatstring_lua, 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 a5845503c..4832c9ba4 100644 --- a/gettext-tools/src/x-perl.h +++ b/gettext-tools/src/x-perl.h @@ -1,6 +1,5 @@ /* xgettext Perl backend. - Copyright (C) 2002-2003, 2006, 2010, 2015-2016 Free Software Foundation, - Inc. + Copyright (C) 2002-2003, 2006, 2010, 2014, 2018 Free Software Foundation, Inc. Written by Guido Flohr , 2002-2003 This program is free software: you can redistribute it and/or modify @@ -37,7 +36,7 @@ extern "C" { #define SCANNERS_PERL \ { "perl", extract_perl, \ - &flag_table_perl, &formatstring_perl, &formatstring_perl_brace, NULL }, \ + &flag_table_perl, &formatstring_perl, &formatstring_perl_brace }, \ /* 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 12e016b1e..2a0c216f9 100644 --- a/gettext-tools/src/x-php.h +++ b/gettext-tools/src/x-php.h @@ -1,5 +1,5 @@ /* xgettext PHP backend. - Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2002. This program is free software: you can redistribute it and/or modify @@ -34,7 +34,7 @@ extern "C" { #define SCANNERS_PHP \ { "PHP", extract_php, \ - &flag_table_php, &formatstring_php, NULL, NULL }, \ + &flag_table_php, &formatstring_php, 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 332b9bbbf..c2f8ead40 100644 --- a/gettext-tools/src/x-po.h +++ b/gettext-tools/src/x-po.h @@ -1,5 +1,5 @@ /* xgettext PO backend. - Copyright (C) 2001-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2001. This program is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ extern "C" { { "pot", "PO" }, \ #define SCANNERS_PO \ - { "PO", extract_po, NULL, NULL, NULL, NULL }, \ + { "PO", extract_po, 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 21092d6d0..09a422ce0 100644 --- a/gettext-tools/src/x-properties.h +++ b/gettext-tools/src/x-properties.h @@ -1,5 +1,5 @@ /* xgettext JavaProperties backend. - Copyright (C) 2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2003. This program is free software: you can redistribute it and/or modify @@ -31,7 +31,7 @@ extern "C" { { "properties", "JavaProperties" }, \ #define SCANNERS_PROPERTIES \ - { "JavaProperties", extract_properties, NULL, NULL, NULL, NULL }, \ + { "JavaProperties", extract_properties, 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 72822a339..8b0ff366c 100644 --- a/gettext-tools/src/x-python.h +++ b/gettext-tools/src/x-python.h @@ -1,5 +1,5 @@ /* xgettext Python backend. - Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2003, 2006, 2013-2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2002. This program is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_PYTHON \ { "Python", extract_python, \ - &flag_table_python, &formatstring_python, &formatstring_python_brace, NULL }, \ + &flag_table_python, &formatstring_python, &formatstring_python_brace }, \ /* 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 ee7c191d6..c470d0e4e 100644 --- a/gettext-tools/src/x-rst.h +++ b/gettext-tools/src/x-rst.h @@ -1,5 +1,5 @@ /* xgettext RST/RSJ backend. - Copyright (C) 2001-2003, 2006, 2015-2016, 2018 Free Software Foundation, Inc. + Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2001. This program is free software: you can redistribute it and/or modify @@ -33,9 +33,9 @@ extern "C" { #define SCANNERS_RST \ { "RST", extract_rst, \ - NULL, &formatstring_pascal, NULL, NULL }, \ + NULL, &formatstring_pascal, NULL }, \ { "RSJ", extract_rsj, \ - NULL, &formatstring_pascal, NULL, NULL }, \ + NULL, &formatstring_pascal, 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 8d045065d..b6ef0669a 100644 --- a/gettext-tools/src/x-scheme.h +++ b/gettext-tools/src/x-scheme.h @@ -1,5 +1,5 @@ /* xgettext Scheme backend. - Copyright (C) 2004, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2004, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2004. This program is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_SCHEME \ { "Scheme", extract_scheme, \ - &flag_table_scheme, &formatstring_scheme, NULL, NULL }, \ + &flag_table_scheme, &formatstring_scheme, 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 2c4ab9ef8..4bda07d2f 100644 --- a/gettext-tools/src/x-sh.h +++ b/gettext-tools/src/x-sh.h @@ -1,5 +1,5 @@ /* xgettext sh backend. - Copyright (C) 2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2003. This program is free software: you can redistribute it and/or modify @@ -33,7 +33,7 @@ extern "C" { #define SCANNERS_SH \ { "Shell", extract_sh, \ - &flag_table_sh, &formatstring_sh, NULL, NULL }, \ + &flag_table_sh, &formatstring_sh, 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 b8e2d0bdf..f851b5607 100644 --- a/gettext-tools/src/x-smalltalk.h +++ b/gettext-tools/src/x-smalltalk.h @@ -1,5 +1,5 @@ /* xgettext Smalltalk backend. - Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2002. This program is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_SMALLTALK \ { "Smalltalk", extract_smalltalk, \ - NULL, &formatstring_smalltalk, NULL, NULL }, \ + NULL, &formatstring_smalltalk, 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 2df0c87c1..e9ec1755f 100644 --- a/gettext-tools/src/x-stringtable.h +++ b/gettext-tools/src/x-stringtable.h @@ -1,5 +1,5 @@ /* xgettext NXStringTable backend. - Copyright (C) 2003, 2006, 2015-2016, 2018 Free Software Foundation, Inc. + Copyright (C) 2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2003. This program is free software: you can redistribute it and/or modify @@ -31,7 +31,7 @@ extern "C" { { "strings", "NXStringTable" }, \ #define SCANNERS_STRINGTABLE \ - { "NXStringTable", extract_stringtable, NULL, NULL, NULL, NULL }, \ + { "NXStringTable", extract_stringtable, NULL, NULL, NULL }, \ /* Scan an NXStringTable 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 5b4be7f50..e802950eb 100644 --- a/gettext-tools/src/x-tcl.h +++ b/gettext-tools/src/x-tcl.h @@ -1,5 +1,5 @@ /* xgettext Tcl Lisp backend. - Copyright (C) 2002-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2002. This program is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_TCL \ { "Tcl", extract_tcl, \ - &flag_table_tcl, &formatstring_tcl, NULL, NULL }, \ + &flag_table_tcl, &formatstring_tcl, 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.c b/gettext-tools/src/x-vala.c index cda642e05..073448f71 100644 --- a/gettext-tools/src/x-vala.c +++ b/gettext-tools/src/x-vala.c @@ -1,5 +1,5 @@ /* xgettext Vala backend. - Copyright (C) 2013, 2015-2018 Free Software Foundation, Inc. + Copyright (C) 2013-2014, 2018 Free Software Foundation, Inc. This file was written by Daiki Ueno , 2013. @@ -366,7 +366,6 @@ struct token_ty token_type_ty type; char *string; /* for token_type_symbol, token_type_string_literal */ refcounted_string_list_ty *comment; /* for token_type_string_literal */ - enum literalstring_escape_type escape; int line_number; }; @@ -381,6 +380,211 @@ free_token (token_ty *tp) } +/* Return value of phase7_getc when EOF is reached. */ +#define P7_EOF (-1) +#define P7_STRING_END (-2) + +/* Replace escape sequences within character strings with their single + character equivalents. */ +#define P7_QUOTES (-3) +#define P7_QUOTE (-4) +#define P7_NEWLINE (-5) + +/* Convert an UTF-16 or UTF-32 code point to a return value that can be + distinguished from a single-byte return value. */ +#define UNICODE(code) (0x100 + (code)) + +/* Test a return value of phase7_getuc whether it designates an UTF-16 or + UTF-32 code point. */ +#define IS_UNICODE(p7_result) ((p7_result) >= 0x100) + +/* Extract the UTF-16 or UTF-32 code of a return value that satisfies + IS_UNICODE. */ +#define UNICODE_VALUE(p7_result) ((p7_result) - 0x100) + + +static int +phase7_getc () +{ + int c, n, j; + + /* Use phase 1, because phase 2 elides comments. */ + c = phase1_getc (); + + /* Return a magic newline indicator, so that we can distinguish + between the user requesting a newline in the string (e.g. using + "\n" or "\012") from the user failing to terminate the string or + character constant. The ANSI C standard says: 3.1.3.4 Character + Constants contain "any character except single quote, backslash or + newline; or an escape sequence" and 3.1.4 String Literals contain + "any character except double quote, backslash or newline; or an + escape sequence". + + Most compilers give a fatal error in this case, however gcc is + stupidly silent, even though this is a very common typo. OK, so + "gcc --pedantic" will tell me, but that gripes about too much other + stuff. Could I have a "gcc -Wnewline-in-string" option, or + better yet a "gcc -fno-newline-in-string" option, please? Gcc is + also inconsistent between string literals and character constants: + you may not embed newlines in character constants; try it, you get + a useful diagnostic. --PMiller */ + if (c == '\n') + return P7_NEWLINE; + + if (c == '"') + return P7_QUOTES; + if (c == '\'') + return P7_QUOTE; + if (c != '\\') + return c; + c = phase1_getc (); + switch (c) + { + default: + /* Unknown escape sequences really should be an error, but just + ignore them, and let the real compiler complain. */ + phase1_ungetc (c); + return '\\'; + + case '"': + case '\'': + case '?': + case '\\': + return c; + + case 'a': + return '\a'; + case 'b': + return '\b'; + + /* The \e escape is preculiar to gcc, and assumes an ASCII + character set (or superset). We don't provide support for it + here. */ + + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'v': + return '\v'; + + case 'x': + c = phase1_getc (); + switch (c) + { + default: + phase1_ungetc (c); + phase1_ungetc ('x'); + return '\\'; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + break; + } + n = 0; + for (;;) + { + switch (c) + { + default: + phase1_ungetc (c); + return n; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = n * 16 + c - '0'; + break; + + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + n = n * 16 + 10 + c - 'A'; + break; + + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + n = n * 16 + 10 + c - 'a'; + break; + } + c = phase1_getc (); + } + return n; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + n = 0; + for (j = 0; j < 3; ++j) + { + n = n * 8 + c - '0'; + c = phase1_getc (); + switch (c) + { + default: + break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + continue; + } + break; + } + phase1_ungetc (c); + return n; + + case 'U': case 'u': + { + unsigned char buf[8]; + + n = 0; + for (j = 0; j < (c == 'u' ? 4 : 8); j++) + { + int c1 = phase1_getc (); + + if (c1 >= '0' && c1 <= '9') + n = (n << 4) + (c1 - '0'); + else if (c1 >= 'A' && c1 <= 'F') + n = (n << 4) + (c1 - 'A' + 10); + else if (c1 >= 'a' && c1 <= 'f') + n = (n << 4) + (c1 - 'a' + 10); + else + { + phase1_ungetc (c1); + while (--j >= 0) + phase1_ungetc (buf[j]); + phase1_ungetc (c); + return '\\'; + } + + buf[j] = c1; + } + + if (n < 0x110000) + return UNICODE (n); + + error_with_progname = false; + error (0, 0, _("%s:%d: warning: invalid Unicode character"), + logical_file_name, line_number); + error_with_progname = true; + + while (--j >= 0) + phase1_ungetc (buf[j]); + phase1_ungetc (c); + return '\\'; + } + } +} + + +static void +phase7_ungetc (int c) +{ + phase1_ungetc (c); +} + + /* 3. Parse each resulting logical line as preprocessing tokens and white space. Preprocessing tokens and Vala tokens don't always match. */ @@ -429,7 +633,6 @@ phase3_get (token_ty *tp) static char *buffer; static int bufmax; int bufpos; - int last_was_backslash; #undef APPEND #define APPEND(c) \ @@ -598,33 +801,20 @@ phase3_get (token_ty *tp) return; case '\'': - last_was_backslash = false; for (;;) { - c = phase2_getc (); - if (last_was_backslash) + c = phase7_getc (); + if (c == P7_NEWLINE) { - last_was_backslash = false; - continue; - } - switch (c) - { - case '\\': - last_was_backslash = true; - /* FALLTHROUGH */ - default: - continue; - case '\n': error_with_progname = false; error (0, 0, _("%s:%d: warning: unterminated character constant"), logical_file_name, line_number - 1); error_with_progname = true; - phase2_ungetc ('\n'); - break; - case EOF: case '\'': + phase7_ungetc ('\n'); break; } - break; + if (c == EOF || c == P7_QUOTE) + break; } tp->type = last_token_type = token_type_character_constant; return; @@ -637,7 +827,7 @@ phase3_get (token_ty *tp) """...""" (where ... can include newlines and double quotes) String templates. @"...", @"""...""" - + Note that, with the current implementation string templates are not subject to translation, because they are inspected at compile time. For example, the following code @@ -660,90 +850,90 @@ phase3_get (token_ty *tp) /* FALLTHROUGH */ case '"': { - int c2 = phase2_getc (); + struct mixed_string_buffer *bp; + int c2 = phase1_getc (); if (c2 == '"') { - int c3 = phase2_getc (); + int c3 = phase1_getc (); if (c3 == '"') verbatim = true; else { - phase2_ungetc (c3); - phase2_ungetc (c2); + phase1_ungetc (c3); + phase1_ungetc (c2); } } else phase2_ungetc (c2); + /* Start accumulating the string. */ + bp = mixed_string_buffer_alloc (lc_string, + logical_file_name, + line_number); if (verbatim) - { - bufpos = 0; - for (;;) - { - /* Use phase 1, because phase 2 elides comments. */ - c = phase1_getc (); - if (c == EOF) - break; + for (;;) + { + c = phase1_getc (); - if (c == '"') - { - int c2 = phase1_getc (); - if (c2 == '"') - { - int c3 = phase1_getc (); - if (c3 == '"') - break; - phase1_ungetc (c3); - } - phase1_ungetc (c2); - } - APPEND (c); - } - } + /* Keep line_number in sync. */ + bp->line_number = line_number; + + if (c == '"') + { + int c2 = phase1_getc (); + if (c2 == '"') + { + int c3 = phase1_getc (); + if (c3 == '"') + break; + phase1_ungetc (c3); + } + phase1_ungetc (c2); + } + if (c == EOF) + break; + mixed_string_buffer_append_char (bp, c); + } else - { - last_was_backslash = false; - bufpos = 0; - for (;;) - { - c = phase1_getc (); - if (last_was_backslash) - { - last_was_backslash = false; - APPEND (c); - continue; - } - - switch (c) - { - case '\\': - last_was_backslash = true; - /* FALLTHROUGH */ - default: - APPEND (c); - continue; - - case '\n': - error_with_progname = false; - error (0, 0, _("\ + for (;;) + { + c = phase7_getc (); + + /* Keep line_number in sync. */ + bp->line_number = line_number; + + if (c == P7_NEWLINE) + { + error_with_progname = false; + error (0, 0, _("\ %s:%d: warning: unterminated string literal"), - logical_file_name, line_number - 1); - error_with_progname = true; - phase1_ungetc ('\n'); - break; - case EOF: case '"': - break; - } + logical_file_name, line_number - 1); + error_with_progname = true; + phase7_ungetc ('\n'); + break; + } + if (c == P7_QUOTES) break; - } - } - APPEND (0); - tp->type = last_token_type = template - ? token_type_string_template : token_type_string_literal; - tp->string = xstrdup (buffer); + if (c == EOF) + break; + if (c == P7_QUOTE) + c = '\''; + if (IS_UNICODE (c)) + { + assert (UNICODE_VALUE (c) >= 0 + && UNICODE_VALUE (c) < 0x110000); + mixed_string_buffer_append_unicode (bp, + UNICODE_VALUE (c)); + } + else + mixed_string_buffer_append_char (bp, c); + } + /* Done accumulating the string. */ + tp->type = last_token_type = + template ? token_type_string_template : token_type_string_literal; + tp->string = mixed_string_buffer_done (bp); tp->comment = add_reference (savable_comment); - tp->escape = verbatim ? 0 : LET_ANSI_C | LET_UNICODE; return; } @@ -878,7 +1068,7 @@ phase3_get (token_ty *tp) } return; } - + case '>': case '<': { @@ -904,7 +1094,7 @@ phase3_get (token_ty *tp) } return; } - + case ',': tp->type = last_token_type = token_type_comma; return; @@ -1012,8 +1202,6 @@ x_vala_lex (token_ty *tp) /* Context lookup table. */ static flag_context_list_table_ty *flag_context_list_table; -/* Use the same literalstring_parser provided by the C scanner. */ -extern struct literalstring_parser literalstring_c; /* The file is broken into tokens. Scan the token stream, looking for a keyword, followed by a left paren, followed by a string. When we @@ -1094,7 +1282,9 @@ extract_balanced (message_list_ty *mlp, token_type_ty delim, arglist_parser_alloc (mlp, state ? next_shapes : NULL))) { + xgettext_current_source_encoding = po_charset_utf8; arglist_parser_done (argparser, arg); + xgettext_current_source_encoding = xgettext_global_source_encoding; return true; } next_context_iter = null_context_list_iterator; @@ -1104,7 +1294,9 @@ extract_balanced (message_list_ty *mlp, token_type_ty delim, case token_type_rparen: if (delim == token_type_rparen || delim == token_type_eof) { + xgettext_current_source_encoding = po_charset_utf8; arglist_parser_done (argparser, arg); + xgettext_current_source_encoding = xgettext_global_source_encoding; return false; } @@ -1123,7 +1315,9 @@ extract_balanced (message_list_ty *mlp, token_type_ty delim, continue; case token_type_eof: + xgettext_current_source_encoding = po_charset_utf8; arglist_parser_done (argparser, arg); + xgettext_current_source_encoding = xgettext_global_source_encoding; return true; case token_type_string_literal: @@ -1132,59 +1326,29 @@ extract_balanced (message_list_ty *mlp, token_type_ty delim, pos.file_name = logical_file_name; pos.line_number = token.line_number; + xgettext_current_source_encoding = po_charset_utf8; if (extract_all) - { - char *string; - refcounted_string_list_ty *comment; - const char *encoding; - - string = literalstring_c.parse (token.string, &pos, - token.escape); - free (token.string); - token.string = string; - - if (token.comment != NULL) - { - comment = savable_comment_convert_encoding (token.comment, - &pos); - drop_reference (token.comment); - token.comment = comment; - } - - /* token.string and token.comment are already converted - to UTF-8. Prevent further conversion in - remember_a_message. */ - encoding = xgettext_current_source_encoding; - xgettext_current_source_encoding = po_charset_utf8; - remember_a_message (mlp, NULL, token.string, inner_context, - &pos, NULL, token.comment); - xgettext_current_source_encoding = encoding; - } + remember_a_message (mlp, NULL, token.string, inner_context, + &pos, NULL, token.comment); else { - /* A string immediately after a symbol means a - function call. */ + /* A string immediately after a symbol means a function call. */ if (state) { struct arglist_parser *tmp_argparser; tmp_argparser = arglist_parser_alloc (mlp, next_shapes); - arglist_parser_remember_literal (tmp_argparser, 1, - token.string, - inner_context, - pos.file_name, - pos.line_number, - token.comment, - token.escape); + arglist_parser_remember (tmp_argparser, 1, token.string, + inner_context, pos.file_name, + pos.line_number, token.comment); arglist_parser_done (tmp_argparser, 1); } else - arglist_parser_remember_literal (argparser, arg, token.string, - inner_context, pos.file_name, - pos.line_number, - token.comment, - token.escape); + arglist_parser_remember (argparser, arg, token.string, + inner_context, pos.file_name, + pos.line_number, token.comment); } + xgettext_current_source_encoding = xgettext_global_source_encoding; } drop_reference (token.comment); next_context_iter = null_context_list_iterator; diff --git a/gettext-tools/src/x-vala.h b/gettext-tools/src/x-vala.h index 4554d76e6..47ef5b5d8 100644 --- a/gettext-tools/src/x-vala.h +++ b/gettext-tools/src/x-vala.h @@ -1,6 +1,5 @@ /* xgettext Vala backend. - Copyright (C) 2002-2003, 2006, 2013, 2015-2016 Free Software Foundation, - Inc. + Copyright (C) 2002-2003, 2006, 2013-2014, 2018 Free Software Foundation, Inc. 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 @@ -31,8 +30,8 @@ extern "C" { { "vala", "Vala" }, \ #define SCANNERS_VALA \ - { "Vala", extract_vala, \ - &flag_table_vala, &formatstring_c, NULL, &literalstring_c }, \ + { "Vala", extract_vala, \ + &flag_table_vala, &formatstring_c, 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 22b5cf368..b6d139a22 100644 --- a/gettext-tools/src/x-ycp.h +++ b/gettext-tools/src/x-ycp.h @@ -1,5 +1,5 @@ /* xgettext YCP backend. - Copyright (C) 2001-2003, 2006, 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2003, 2006, 2014, 2018 Free Software Foundation, Inc. Written by Bruno Haible , 2001. This program is free software: you can redistribute it and/or modify @@ -32,7 +32,7 @@ extern "C" { #define SCANNERS_YCP \ { "YCP", extract_ycp, \ - &flag_table_ycp, &formatstring_ycp, NULL, NULL }, \ + &flag_table_ycp, &formatstring_ycp, 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 00d5a946b..adec0dff7 100644 --- a/gettext-tools/src/xgettext.c +++ b/gettext-tools/src/xgettext.c @@ -295,7 +295,6 @@ struct extractor_ty struct formatstring_parser *formatstring_parser1; struct formatstring_parser *formatstring_parser2; struct formatstring_parser *formatstring_parser3; - struct literalstring_parser *literalstring_parser; }; @@ -2127,32 +2126,6 @@ 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 * @@ -2222,7 +2195,6 @@ 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, @@ -2242,7 +2214,6 @@ 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); @@ -2992,17 +2963,14 @@ 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 = LET_NONE; 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 = LET_NONE; 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 = LET_NONE; 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); @@ -3040,16 +3008,13 @@ 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; } @@ -3059,12 +3024,11 @@ arglist_parser_clone (struct arglist_parser *ap) 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) +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) { bool stored_string = false; size_t nalternatives = ap->nalternatives; @@ -3079,7 +3043,6 @@ arglist_parser_remember_literal (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; @@ -3091,7 +3054,6 @@ arglist_parser_remember_literal (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; @@ -3103,7 +3065,6 @@ arglist_parser_remember_literal (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; @@ -3120,19 +3081,6 @@ arglist_parser_remember_literal (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 (ap, argnum, string, context, - file_name, line_number, - comment, LET_NONE); -} - - void arglist_parser_remember_msgctxt (struct arglist_parser *ap, char *string, @@ -3148,7 +3096,6 @@ arglist_parser_remember_msgctxt (struct arglist_parser *ap, struct partial_call *cp = &ap->alternative[i]; cp->msgctxt = string; - cp->msgctxt_escape = LET_NONE; cp->msgctxt_pos.file_name = file_name; cp->msgctxt_pos.line_number = line_number; stored_string = true; @@ -3401,8 +3348,6 @@ 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 @@ -3416,98 +3361,15 @@ 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); - if (best_cp->msgid_plural == best_cp->msgid) - best_cp->msgid_plural = msgid; - free (best_cp->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_plural) - { - /* 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, - 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); - } - } - - /* If best_cp->msgid_plural equals to best_cp->msgid, - the ownership will be transferred to - remember_a_message before it is passed to - remember_a_message_plural. - - Make a copy of the string in that case. */ - if (best_cp->msgid_plural == best_cp->msgid) - best_cp->msgid_plural = xstrdup (best_cp->msgid); - } - - 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, best_cp->msgid, and best_cp->msgid_plural - 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); if (mp != NULL && best_cp->msgid_plural != NULL) - remember_a_message_plural (mp, - best_cp->msgid_plural, + 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) @@ -3906,7 +3768,6 @@ 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; @@ -3954,7 +3815,6 @@ 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 926881e37..7c3712a9b 100644 --- a/gettext-tools/src/xgettext.h +++ b/gettext-tools/src/xgettext.h @@ -242,25 +242,6 @@ 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_NONE = 0, - 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 @@ -294,6 +275,7 @@ 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 @@ -306,15 +288,12 @@ 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; }; @@ -348,19 +327,6 @@ 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); /* Adds a string argument as msgctxt to an arglist_parser, without incrementing the current argument number. STRING must be malloc()ed string; its ownership is passed to the callee.