From 0996f18b252504ccc2db94b16c751835e3b9be8e Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 26 Mar 2018 13:52:17 +0200 Subject: Fix CONFIG+=qtquickcompiler with umlauts in the file path Instead of replacing every character that is not allowed in C++ identifiers with an underscore (which in turn could lead to collissions), replace it with the hexadecimal value of the offending character's unicode value. In addition we must use the complete suffix when mapping Foo.qml to Foo_qml.cpp. Task-number: QTBUG-68608 Started-by: Erik Verbruggen Change-Id: I7e2153f0e6671b37dcaee4efb9aaae1d9b230f0c Reviewed-by: Ulf Hermann --- tools/qmlcachegen/generateloader.cpp | 54 ++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 6 deletions(-) (limited to 'tools/qmlcachegen/generateloader.cpp') diff --git a/tools/qmlcachegen/generateloader.cpp b/tools/qmlcachegen/generateloader.cpp index 96528a9477..178a109791 100644 --- a/tools/qmlcachegen/generateloader.cpp +++ b/tools/qmlcachegen/generateloader.cpp @@ -35,6 +35,52 @@ #include #include +/*! + * \internal + * Mangles \a str to be a unique C++ identifier. Characters that are invalid for C++ identifiers + * are replaced by the pattern \c _0x_ where is the hexadecimal unicode + * representation of the character. As identifiers with leading underscores followed by either + * another underscore or a capital letter are reserved in C++, we also escape those, by escaping + * the first underscore, using the above method. + * + * \note + * Although C++11 allows for non-ascii (unicode) characters to be used in identifiers, + * many compilers forgot to read the spec and do not implement this. Some also do not + * implement C99 identifiers, because that is \e {at the implementation's discretion}. So, + * we are stuck with plain old boring identifiers. + */ +QString mangledIdentifier(const QString &str) +{ + Q_ASSERT(!str.isEmpty()); + + QString mangled; + mangled.reserve(str.size()); + + int i = 0; + if (str.startsWith(QLatin1Char('_')) && str.size() > 1) { + QChar ch = str.at(1); + if (ch == QLatin1Char('_') + || (ch >= QLatin1Char('A') && ch <= QLatin1Char('Z'))) { + mangled += QLatin1String("_0x5f_"); + ++i; + } + } + + for (int ei = str.length(); i != ei; ++i) { + auto c = str.at(i).unicode(); + if ((c >= QLatin1Char('0') && c <= QLatin1Char('9')) + || (c >= QLatin1Char('a') && c <= QLatin1Char('z')) + || (c >= QLatin1Char('A') && c <= QLatin1Char('Z')) + || c == QLatin1Char('_')) { + mangled += c; + } else { + mangled += QLatin1String("_0x") + QString::number(c, 16) + QLatin1Char('_'); + } + } + + return mangled; +} + QString symbolNamespaceForPath(const QString &relativePath) { QFileInfo fi(relativePath); @@ -47,12 +93,8 @@ QString symbolNamespaceForPath(const QString &relativePath) } symbol += fi.baseName(); symbol += QLatin1Char('_'); - symbol += fi.suffix(); - symbol.replace(QLatin1Char('.'), QLatin1Char('_')); - symbol.replace(QLatin1Char('+'), QLatin1Char('_')); - symbol.replace(QLatin1Char('-'), QLatin1Char('_')); - symbol.replace(QLatin1Char(' '), QLatin1Char('_')); - return symbol; + symbol += fi.completeSuffix(); + return mangledIdentifier(symbol); } struct VirtualDirectoryEntry -- cgit v1.2.3 From 27a6b122343322a02e0fe26fb76c05f6105c4b94 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 13 Jun 2018 08:05:03 +0200 Subject: qmlcachegen: Remove superfluous semicolons from generated code This fixes the "extra ';'" warnings when compiling generated code with -Werror=pedantic. Task-number: QTBUG-68809 Change-Id: Ie26cdc4e06bc26587766dd72b258624773a7f990 Reviewed-by: Simon Hausmann --- tools/qmlcachegen/generateloader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/qmlcachegen/generateloader.cpp') diff --git a/tools/qmlcachegen/generateloader.cpp b/tools/qmlcachegen/generateloader.cpp index 178a109791..68aacf78ce 100644 --- a/tools/qmlcachegen/generateloader.cpp +++ b/tools/qmlcachegen/generateloader.cpp @@ -360,7 +360,7 @@ bool generateLoader(const QStringList &compiledFiles, const QString &outputFileN stream << " QHash resourcePathToCachedUnit;\n"; stream << " static const QQmlPrivate::CachedQmlUnit *lookupCachedUnit(const QUrl &url);\n"; stream << "};\n\n"; - stream << "Q_GLOBAL_STATIC(Registry, unitRegistry);\n"; + stream << "Q_GLOBAL_STATIC(Registry, unitRegistry)\n"; stream << "\n\n"; stream << "Registry::Registry() {\n"; @@ -410,7 +410,7 @@ bool generateLoader(const QStringList &compiledFiles, const QString &outputFileN stream << " Q_INIT_RESOURCE(" << qtResourceNameForFile(newResourceFile) << ");\n"; stream << " return 1;\n"; stream << "}\n"; - stream << "Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(" << initFunction << "));\n"; + stream << "Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(" << initFunction << "))\n"; const QString cleanupFunction = QLatin1String("qCleanupResources_") + suffix; stream << QStringLiteral("int QT_MANGLE_NAMESPACE(%1)() {\n").arg(cleanupFunction); -- cgit v1.2.3