summaryrefslogtreecommitdiffstats
path: root/src/corelib/plugin
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2021-08-12 16:20:57 +0200
committerMarc Mutz <marc.mutz@kdab.com>2021-08-21 01:28:27 +0200
commitd07742f333df89dc399fc5d9cabf2bdef0b346c5 (patch)
tree0f7f6ca843b695effc6e2fdabd06e5e55ac3496a /src/corelib/plugin
parentbd52059eef7c96031972b5bee03067f3cb0f038d (diff)
QLibrary: use QStringTokenizer in isLibrary()
Rewrite the whole function for readability _and_ performance: - Extract Method isValidSuffix() as a lambda - Extract Method isNumeric() as a lambda - Use a C array of QLatin1String instead of a QStringList to hold the statically-sized list of candidate suffixes. This has the nice side-effect that the compiler will now throw an error in case the #ifdef'ery yields zero candidates (C arrays cannot have no elements), e.g. when porting to a new platform. - Last, not least, replace the parsing with a loop that makes clear what's going on and which is forward-iteration-only-compatible, so we can use QStringTokenizer directly, without toContainer() to get a random-access sequence. Need to use the C++20 version of all_of(), since QStringTokenizer uses sentinels instead of end-iterators. Even though we use higher-level constructs now, the code is still more efficient than the index-twisting we had before. Change-Id: I9f3faf3e30f58c9eb8a1487a7ca190681e87767b Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/corelib/plugin')
-rw-r--r--src/corelib/plugin/qlibrary.cpp40
1 files changed, 25 insertions, 15 deletions
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 67df0a31a6..810cbc5a79 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -66,6 +66,8 @@
#include <qtcore_tracepoints_p.h>
+#include <QtCore/q20algorithm.h>
+
QT_BEGIN_NAMESPACE
#ifdef QT_NO_DEBUG
@@ -672,26 +674,32 @@ bool QLibrary::isLibrary(const QString &fileName)
QString completeSuffix = QFileInfo(fileName).completeSuffix();
if (completeSuffix.isEmpty())
return false;
- const auto suffixes = QStringView{completeSuffix}.split(QLatin1Char('.'));
- QStringList validSuffixList;
+ auto isValidSuffix = [](QStringView s) {
+ // if this throws an empty-array error, you need to fix the #ifdef's:
+ const QLatin1String candidates[] = {
# if defined(Q_OS_HPUX)
/*
See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF":
"In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit),
the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix."
*/
- validSuffixList << QLatin1String("sl");
+ QLatin1String("sl"),
# if defined __ia64
- validSuffixList << QLatin1String("so");
+ QLatin1String("so"),
# endif
# elif defined(Q_OS_AIX)
- validSuffixList << QLatin1String("a") << QLatin1String("so");
+ QLatin1String("a"),
+ QLatin1String("so"),
# elif defined(Q_OS_DARWIN)
- validSuffixList << QLatin1String("so") << QLatin1String("bundle");
+ QLatin1String("so"),
+ QLatin1String("bundle"),
# elif defined(Q_OS_UNIX)
- validSuffixList << QLatin1String("so");
+ QLatin1String("so"),
# endif
+ }; // candidates
+ return std::find(std::begin(candidates), std::end(candidates), s) != std::end(candidates);
+ };
// Examples of valid library names:
// libfoo.so
@@ -700,15 +708,17 @@ bool QLibrary::isLibrary(const QString &fileName)
// libfoo-0.3.so
// libfoo-0.3.so.0.3.0
- int suffix;
- int suffixPos = -1;
- for (suffix = 0; suffix < validSuffixList.count() && suffixPos == -1; ++suffix)
- suffixPos = suffixes.indexOf(validSuffixList.at(suffix));
+ auto suffixes = qTokenize(completeSuffix, u'.');
+ auto it = suffixes.begin();
+ const auto end = suffixes.end();
- bool valid = suffixPos != -1;
- for (int i = suffixPos + 1; i < suffixes.count() && valid; ++i)
- (void)suffixes.at(i).toInt(&valid);
- return valid;
+ auto isNumeric = [](QStringView s) { bool ok; (void)s.toInt(&ok); return ok; };
+
+ while (it != end) {
+ if (isValidSuffix(*it++))
+ return q20::ranges::all_of(it, end, isNumeric);
+ }
+ return false; // no valid suffix found
#endif
}