diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2018-03-26 13:52:17 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-06-19 13:30:35 +0000 |
commit | 0996f18b252504ccc2db94b16c751835e3b9be8e (patch) | |
tree | 704c832290bcb119c6ba9438f8823004798115ed /tools | |
parent | 16cf097972a72656142ab0ed797282ad95ee5713 (diff) |
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 <erik.verbruggen@qt.io>
Change-Id: I7e2153f0e6671b37dcaee4efb9aaae1d9b230f0c
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qmlcachegen/generateloader.cpp | 54 |
1 files changed, 48 insertions, 6 deletions
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 <QFileInfo> #include <QSaveFile> +/*! + * \internal + * Mangles \a str to be a unique C++ identifier. Characters that are invalid for C++ identifiers + * are replaced by the pattern \c _0x<hex>_ where <hex> 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 |