From 4628351c3f53e3239e304b906a0f6f9a6daab985 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 7 Jun 2019 18:54:33 +0200 Subject: QStandardPaths: don't build a QHash just to look up one key The code parses a file, looking for XDG_*_DIR entries and stores each one's key and raw value in a QHash. After parsing, it, however, looked up exactly once, by a key it could have known all along. So, move the key computation before the opening of the file, and look for the correct key directly, consciously striving to continue to find, as the old code implicitly did, the last entry, since man 5 user-dirs.dirs explains: > The format of user-dirs.dirs is designed to allow direct sourcing of > this file in shell scripts. Which means last one wins. Port to QStringView API of QRegularExpression, too. Change-Id: Ie92b689b5b9221df918c67b96f2f6a09827e7b1e Reviewed-by: Volker Hilsheimer Reviewed-by: David Faure --- src/corelib/io/qstandardpaths_unix.cpp | 75 +++++++++++++++------------------- 1 file changed, 34 insertions(+), 41 deletions(-) (limited to 'src/corelib/io/qstandardpaths_unix.cpp') diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index f4f8787968..6425890e3f 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -71,6 +71,28 @@ static void appendOrganizationAndApp(QString &path) #endif } +#if QT_CONFIG(regularexpression) +static QLatin1String xdg_key_name(QStandardPaths::StandardLocation type) +{ + switch (type) { + case QStandardPaths::DesktopLocation: + return QLatin1String("DESKTOP"); + case QStandardPaths::DocumentsLocation: + return QLatin1String("DOCUMENTS"); + case QStandardPaths::PicturesLocation: + return QLatin1String("PICTURES"); + case QStandardPaths::MusicLocation: + return QLatin1String("MUSIC"); + case QStandardPaths::MoviesLocation: + return QLatin1String("VIDEOS"); + case QStandardPaths::DownloadLocation: + return QLatin1String("DOWNLOAD"); + default: + return QLatin1String(); + } +} +#endif + QString QStandardPaths::writableLocation(StandardLocation type) { switch (type) { @@ -182,61 +204,32 @@ QString QStandardPaths::writableLocation(StandardLocation type) if (xdgConfigHome.isEmpty()) xdgConfigHome = QDir::homePath() + QLatin1String("/.config"); QFile file(xdgConfigHome + QLatin1String("/user-dirs.dirs")); - if (!isTestModeEnabled() && file.open(QIODevice::ReadOnly)) { - QHash lines; + const QLatin1String key = xdg_key_name(type); + if (!key.isEmpty() && !isTestModeEnabled() && file.open(QIODevice::ReadOnly)) { QTextStream stream(&file); // Only look for lines like: XDG_DESKTOP_DIR="$HOME/Desktop" QRegularExpression exp(QLatin1String("^XDG_(.*)_DIR=(.*)$")); + QString result; while (!stream.atEnd()) { const QString &line = stream.readLine(); QRegularExpressionMatch match = exp.match(line); - if (match.hasMatch()) { - const QStringList lst = match.capturedTexts(); - const QString key = lst.at(1); - QString value = lst.at(2); + if (match.hasMatch() && match.capturedView(1) == key) { + QStringView value = match.capturedView(2); if (value.length() > 2 && value.startsWith(QLatin1Char('\"')) && value.endsWith(QLatin1Char('\"'))) value = value.mid(1, value.length() - 2); - // Store the key and value: "DESKTOP", "$HOME/Desktop" - lines[key] = value; - } - } - - QString key; - switch (type) { - case DesktopLocation: - key = QLatin1String("DESKTOP"); - break; - case DocumentsLocation: - key = QLatin1String("DOCUMENTS"); - break; - case PicturesLocation: - key = QLatin1String("PICTURES"); - break; - case MusicLocation: - key = QLatin1String("MUSIC"); - break; - case MoviesLocation: - key = QLatin1String("VIDEOS"); - break; - case DownloadLocation: - key = QLatin1String("DOWNLOAD"); - break; - default: - break; - } - if (!key.isEmpty()) { - QString value = lines.value(key); - if (!value.isEmpty()) { // value can start with $HOME if (value.startsWith(QLatin1String("$HOME"))) - value = QDir::homePath() + value.midRef(5); - if (value.length() > 1 && value.endsWith(QLatin1Char('/'))) - value.chop(1); - return value; + result = QDir::homePath() + value.mid(5); + else + result = value.toString(); + if (result.length() > 1 && result.endsWith(QLatin1Char('/'))) + result.chop(1); } } + if (!result.isNull()) + return result; } #endif // QT_CONFIG(regularexpression) -- cgit v1.2.3