diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2021-08-12 16:20:57 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2021-08-21 01:28:27 +0200 |
commit | d07742f333df89dc399fc5d9cabf2bdef0b346c5 (patch) | |
tree | 0f7f6ca843b695effc6e2fdabd06e5e55ac3496a /src/corelib/plugin | |
parent | bd52059eef7c96031972b5bee03067f3cb0f038d (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.cpp | 40 |
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 } |