From: Daiki Ueno Date: Tue, 2 Dec 2014 06:11:26 +0000 (+0900) Subject: c: Support C++11 string literals X-Git-Tag: v0.19.4~50 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cadb9172479a75bd74f3c6ed2d7d5389202874f1;p=thirdparty%2Fgettext.git c: Support C++11 string literals * x-c.c (phase5_get): Recognize C++ string literals, defined in ISO/IEC 9899:2011. Reported at: . --- diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index 4fb7bdbf0..8b4695347 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,10 @@ +2014-12-02 Daiki Ueno + + c: Support C++11 string literals + * x-c.c (phase5_get): Recognize C++ string literals, defined in + ISO/IEC 9899:2011. Reported at: + . + 2014-12-01 Daiki Ueno c#: Recognize Unicode surrogate character pair diff --git a/gettext-tools/src/x-c.c b/gettext-tools/src/x-c.c index a5978c9f6..5ce6f4934 100644 --- a/gettext-tools/src/x-c.c +++ b/gettext-tools/src/x-c.c @@ -1097,6 +1097,7 @@ phase5_get (token_ty *tp) int bufpos; int c; int last_was_backslash; + bool raw_expected = false; if (phase5_pushback_length) { @@ -1176,6 +1177,52 @@ phase5_get (token_ty *tp) continue; default: + /* Recognize C++ string literals prefixed by R, u8, u8R, + u, uR, U, UR, L, or LR. It is defined in ISO/IEC + 9899:2011 2.14.5. 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 (bufpos == 1) + is_prefix = true; + break; + case 'u': + if (bufpos == 1) + is_prefix = true; + else + switch (buffer[1]) + { + case 'R': + if (bufpos == 2) + is_prefix = true; + break; + case '8': + if (bufpos == 2 + || (bufpos == 3 && buffer[2] == 'R')) + is_prefix = true; + break; + } + break; + case 'U': + case 'L': + if (bufpos == 1 + || (bufpos == 2 && buffer[1] == 'R')) + is_prefix = true; + break; + } + + if (is_prefix) + { + raw_expected = is_prefix && buffer[bufpos - 1] == 'R'; + bufpos = 0; + goto string; + } + } phase4_ungetc (c); break; } @@ -1309,6 +1356,7 @@ phase5_get (token_ty *tp) case '"': { + string: /* 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 @@ -1335,21 +1383,26 @@ phase5_get (token_ty *tp) last_was_backslash = true; /* FALLTHROUGH */ default: - if (bufpos >= bufmax) + if (c == '\n' && !raw_expected) { - bufmax = 2 * bufmax + 10; - buffer = xrealloc (buffer, bufmax); + 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; + } + else + { + if (bufpos >= bufmax) + { + bufmax = 2 * bufmax + 10; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos++] = c; + continue; } - buffer[bufpos++] = c; - continue; - case '\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; case EOF: case '"': break; } @@ -1361,6 +1414,31 @@ phase5_get (token_ty *tp) buffer = xrealloc (buffer, bufmax); } buffer[bufpos] = 0; + + if (raw_expected) + { + char *delimiter_left_end; + char *delimiter_right_start; + + if (!(delimiter_left_end = strchr (buffer, '(')) + || !(delimiter_right_start = strrchr (buffer, ')')) + || strncmp (buffer, delimiter_right_start + 1, + (delimiter_left_end - buffer)) != 0) + { + error_with_progname = false; + error (0, 0, _("%s:%d: warning: unterminated string literal"), + logical_file_name, line_number - 1); + error_with_progname = true; + } + else + { + *delimiter_right_start = '\0'; + tp->type = token_type_string_literal; + tp->string = xstrdup (delimiter_left_end + 1); + tp->comment = add_reference (savable_comment); + return; + } + } tp->type = token_type_string_literal; tp->string = xstrdup (buffer); tp->comment = add_reference (savable_comment);