diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2016-09-06 19:21:50 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2017-08-24 14:27:50 +0000 |
commit | 515b9051505d61af6be0eba87616c7281ee4ce62 (patch) | |
tree | 69bea4769022c2003f6ddf1cd1c8e1699e4b7f9e /tests/auto/tools | |
parent | 797530c3f81b6c5fb8e25e431105fdcd22d8775a (diff) |
Adapt qmake's raw-string parser to avoid confusion by macros
A macro name ending in R might expand to a string; if this precedes a
string constant, we're juxtaposing the strings. My first parser for
raw strings would mistake it for a raw string instead, ignoring the
part of the identifier before R. Re-worked the exploration of what
came before the string to catch these cases, too.
The backwards parsing would also allow any messy jumble of [RLUu8]* as
prefix for the string; but in fact R must (if present) be last in the
prefix and *it* can have at most one prefix, [LUu] or u8. Anything
else is an identifier that happens to precede the string. Reworked
the parsing to allow only one prefix and not treat R specially unless
it's immediately (modulo BSNL) before the string's open-quotes.
Add link to the cppreference page about string literals, on which the
grammar now parsed is based.
Added a test for the issue this addresses.
Verified that this fails on 5.6, dev and 5.9 without the fix.
Expanded the existing test to cover R-with-prefix cases.
Task-number: QTBUG-55633
Change-Id: I541486c2ec909cfb42050907c84bee83ead4a2f4
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Diffstat (limited to 'tests/auto/tools')
-rw-r--r-- | tests/auto/tools/qmake/testdata/rawString/main.cpp | 101 | ||||
-rw-r--r-- | tests/auto/tools/qmake/testdata/rawString/object2.h | 54 | ||||
-rw-r--r-- | tests/auto/tools/qmake/testdata/rawString/rawString.pro | 2 |
3 files changed, 155 insertions, 2 deletions
diff --git a/tests/auto/tools/qmake/testdata/rawString/main.cpp b/tests/auto/tools/qmake/testdata/rawString/main.cpp index 53a28f7bc0..bc557f39f8 100644 --- a/tests/auto/tools/qmake/testdata/rawString/main.cpp +++ b/tests/auto/tools/qmake/testdata/rawString/main.cpp @@ -26,8 +26,107 @@ ** ****************************************************************************/ +// macro names that *aren't* string-literal-prefixes: +#define Ru8 "rue-it" +#define RL "real life" +#define Ru "are you ?" +#define RU "Are You ?" +#define LLR "double-hockey-sticks" +#define LUR "Tricky" +#define LuR "tricky" +#define Lu8R "l'uber" +#define UUR "Double-Yew" +#define ULR "Eweler" +#define UuR "You ... you-are" +#define Uu8R "You ... you *ate* our ..." +#define uuR "water" +#define uLR "eweler" +#define uUR "double-Your" +#define uu8R "totally uber" +#define u8u8R "rubber-you" +#define u8LR "Uber left-to-right" +#define u8UR "Uber Upper-Right" +#define u8uR "Uber upper-right" +#define Ru8R "bouncy" +#define RLR "Marching" +#define RuR "Rossum's general-purpose workers" +#define RUR "Rossum's Universal Robots" + +static const char monstrosity[] = + Ru8"Ru8(" + RL"RL(" + Ru"Ru(" + RU"RU(" + LLR"LLR(" + LUR"LUR(" + LuR"LuR(" + Lu8R"Lu8R(" + UUR"UUR(" + ULR"ULR(" + UuR"UuR(" + Uu8R"Uu8R(" + uuR"uuR(" + uLR"uLR(" + uUR"uUR(" + uu8R"uu8R(" + u8u8R"u8u8R(" + u8LR"u8LR(" + u8UR"u8UR(" + u8uR"u8uR(" + Ru8R"Ru8R(" + RLR"RLR(" + RuR"RuR(" + RUR"RUR(" + "Finally, some content"; + +#include <moc_object2.cpp> + +static const char closure[] = + ")RUR" + ")RuR" + ")RLR" + ")Ru8R" + ")u8uR" + ")u8UR" + ")u8LR" + ")u8u8R" + ")uu8R" + ")uUR" + ")uLR" + ")uuR" + ")Uu8R" + ")UuR" + ")ULR" + ")UUR" + ")Lu8R" + ")LuR" + ")LUR" + ")LLR" + ")RU" + ")Ru" + ")RL" + ")Ru8"; +// If moc got confused, the confusion should now be over + +// Real raw strings, not actually leaving us inside any comments: static const char raw[] = R"blah(lorem " ipsum /*)blah"\ ; +static const wchar_t wider[] = LR"blah(lorem " ipsum /*)blah"\ +; +static const char32_t UCS4[] = UR"blah(lorem " ipsum /*)blah"\ +; +static const char16_t UCS2[] = uR"blah(lorem " ipsum /*)blah"\ +; +static const char utf8[] = u8R"blah(lorem " ipsum /*)blah"\ +; #include <moc_object1.cpp> -int main () { return 0; } +/* Avoid unused variable warnings by silly uses of arrays: */ +#define final(x) x[sizeof(x) - 1] // 0, of course +int main () { + return final(raw) + * (final(wider) - final(UCS4)) + * (final(UCS2) - final(utf8)) + * (final(monstrosity) - final(closure)); +} +#undef final diff --git a/tests/auto/tools/qmake/testdata/rawString/object2.h b/tests/auto/tools/qmake/testdata/rawString/object2.h new file mode 100644 index 0000000000..2ab77cd3bd --- /dev/null +++ b/tests/auto/tools/qmake/testdata/rawString/object2.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef TEST_QMAKE_RAWSTRING_OBJECT2_H +#define TEST_QMAKE_RAWSTRING_OBJECT2_H + +#define Lu8UR "land" +inline char opener(int i) { + const char text[] = Lu8UR"blah( not a raw string; just juxtaposed"; + return text[i]; +} + +#include <QObject> + +class Object2 : public QObject +{ + Q_OBJECT +}; + +inline char closer(int i) { + const char text[] = "pretend to close it, all the same )blah"; + return text[i]; +} + +#endif // TEST_QMAKE_RAWSTRING_OBJECT2_H diff --git a/tests/auto/tools/qmake/testdata/rawString/rawString.pro b/tests/auto/tools/qmake/testdata/rawString/rawString.pro index d2d8132ceb..19c81dfe97 100644 --- a/tests/auto/tools/qmake/testdata/rawString/rawString.pro +++ b/tests/auto/tools/qmake/testdata/rawString/rawString.pro @@ -1,4 +1,4 @@ DESTDIR = ./ -HEADERS += object1.h +HEADERS += object1.h object2.h SOURCES += main.cpp |