From: Bruno Haible Date: Sat, 6 Jan 2018 17:45:22 +0000 (+0100) Subject: Add support for new C++ preprocessing number tokens. X-Git-Tag: v0.20~426 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6d86e6f80d60c414888ba54eb313f897776cecf1;p=thirdparty%2Fgettext.git Add support for new C++ preprocessing number tokens. Reported by Moritz Bunkus at . * gettext-tools/src/x-c.c (phase5_get): Recognize C++14 and C++17 extensions of preprocessing number tokens. * gettext-tools/tests/xgettext-c-22: New file. * gettext-tools/tests/Makefile.am (TESTS): Add it. * NEWS: Mention the change. --- diff --git a/NEWS b/NEWS index ffbb141c1..bdfb2689e 100644 --- a/NEWS +++ b/NEWS @@ -2,8 +2,11 @@ - update-po target in Makefile.in.in now uses msgfmt --previous. * Programming languages support: + - C++: + xgettext now supports single-quotes and 'p'/'P' exponent markers in + number tokens, as specified in C++14 and C++17, respectively. - Java: - xgettext now support UTF-8 encoded .properties files (a new feature + xgettext now supports UTF-8 encoded .properties files (a new feature of Java 9). - Perl: o Native support for context functions (pgettext, dpgettext, dcpgettext, diff --git a/gettext-tools/src/x-c.c b/gettext-tools/src/x-c.c index 1844a5df7..8debf01cf 100644 --- a/gettext-tools/src/x-c.c +++ b/gettext-tools/src/x-c.c @@ -1,5 +1,5 @@ /* xgettext C/C++/ObjectiveC backend. - Copyright (C) 1995-1998, 2000-2009, 2012, 2015-2016 Free Software + Copyright (C) 1995-1998, 2000-2009, 2012, 2015-2016, 2018 Free Software Foundation, Inc. This file was written by Peter Miller @@ -1402,6 +1402,12 @@ phase5_get (token_ty *tp) c = phase4_getc (); switch (c) { + case 'p': + case 'P': + if (!cxx_extensions) + continue; + /* In C++17, 'p' and 'P' can be used as an exponent marker. */ + /* FALLTHROUGH */ case 'e': case 'E': if (bufpos >= bufmax) @@ -1420,12 +1426,12 @@ phase5_get (token_ty *tp) case 'A': case 'B': case 'C': case 'D': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': - case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'M': case 'N': case 'O': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case 'a': case 'b': case 'c': case 'd': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': - case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 'm': case 'n': case 'o': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case '0': case '1': case '2': case '3': case '4': @@ -1433,6 +1439,45 @@ phase5_get (token_ty *tp) case '.': continue; + case '\'': + if (cxx_extensions) + { + /* In C++14, a single-quote followed by a digit, ASCII letter, + or underscore can be part of a preprocessing number token. */ + int c1 = phase4_getc (); + switch (c1) + { + 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 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case '_': + if (bufpos >= bufmax) + { + bufmax = 2 * bufmax + 10; + buffer = xrealloc (buffer, bufmax); + } + buffer[bufpos++] = c; + c = c1; + continue; + default: + /* The two phase4_getc() calls that returned c and c1 did + nothing more than to call phase3_getc(), without any + lookahead. Therefore 2 pushback characters are + supported in this case. */ + phase4_ungetc (c1); + break; + } + } + /* FALLTHROUGH */ default: phase4_ungetc (c); break; diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am index 75542358e..720268a2e 100644 --- a/gettext-tools/tests/Makefile.am +++ b/gettext-tools/tests/Makefile.am @@ -80,7 +80,7 @@ TESTS = gettext-1 gettext-2 gettext-3 gettext-4 gettext-5 gettext-6 gettext-7 \ xgettext-c-6 xgettext-c-7 xgettext-c-8 xgettext-c-9 xgettext-c-10 \ xgettext-c-11 xgettext-c-12 xgettext-c-13 xgettext-c-14 xgettext-c-15 \ xgettext-c-16 xgettext-c-17 xgettext-c-18 xgettext-c-19 xgettext-c-20 \ - xgettext-c-21 \ + xgettext-c-21 xgettext-c-22 \ xgettext-csharp-1 xgettext-csharp-2 xgettext-csharp-3 \ xgettext-csharp-4 xgettext-csharp-5 xgettext-csharp-6 \ xgettext-csharp-7 xgettext-csharp-8 \ diff --git a/gettext-tools/tests/xgettext-c-22 b/gettext-tools/tests/xgettext-c-22 new file mode 100644 index 000000000..566800b75 --- /dev/null +++ b/gettext-tools/tests/xgettext-c-22 @@ -0,0 +1,22 @@ +#! /bin/sh +. "${srcdir=.}/init.sh"; path_prepend_ . ../src + +# Test C++ support: C++14 preprocessing number tokens. + +: ${XGETTEXT=xgettext} + +cat <<\EOF > xg-c-22.cc +auto i = 1'234; gettext ("hello"); +EOF + +: ${XGETTEXT=xgettext} +${XGETTEXT} --omit-header --no-location -d xg-c-22.tmp xg-c-22.cc || Exit 1 +LC_ALL=C tr -d '\r' < xg-c-22.tmp.po > xg-c-22.po || Exit 1 + +cat <<\EOF > xg-c-22.ok +msgid "hello" +msgstr "" +EOF + +: ${DIFF=diff} +${DIFF} xg-c-22.ok xg-c-22.po || Exit 1