Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qstandardpaths.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qstandardpaths.h"
6
7#include <qdir.h>
8#include <qfileinfo.h>
9
10#ifndef QT_BOOTSTRAPPED
11#include <qobject.h>
12#include <qcoreapplication.h>
13#endif
14
15#if __has_include(<paths.h>)
16#include <paths.h>
17#endif
18
19#ifdef Q_OS_UNIX
20#include <unistd.h>
21#endif
22
23#ifndef QT_NO_STANDARDPATHS
24
26
27using namespace Qt::StringLiterals;
371static bool existsAsSpecified(const QString &path, QStandardPaths::LocateOptions options)
372{
374 return QDir(path).exists();
375 return QFileInfo(path).isFile();
376}
377
382{
383 const QStringList &dirs = standardLocations(type);
384 for (QStringList::const_iterator dir = dirs.constBegin(); dir != dirs.constEnd(); ++dir) {
385 const QString path = *dir + u'/' + fileName;
386 if (existsAsSpecified(path, options))
387 return path;
388 }
389 return QString();
390}
391
396{
397 const QStringList &dirs = standardLocations(type);
399 for (QStringList::const_iterator dir = dirs.constBegin(); dir != dirs.constEnd(); ++dir) {
400 const QString path = *dir + u'/' + fileName;
401 if (existsAsSpecified(path, options))
402 result.append(path);
403 }
404 return result;
405}
406
407#ifdef Q_OS_WIN
408static QStringList executableExtensions()
409{
410 // If %PATHEXT% does not contain .exe, it is either empty, malformed, or distorted in ways that we cannot support, anyway.
411 const QStringList pathExt = QString::fromLocal8Bit(qgetenv("PATHEXT")).toLower().split(u';');
412 return pathExt.contains(".exe"_L1, Qt::CaseInsensitive) ?
413 pathExt : QStringList{".exe"_L1, ".com"_L1, ".bat"_L1, ".cmd"_L1};
414}
415#endif
416
418{
419 const QFileInfo info(path);
420 if (info.isBundle())
421 return info.bundleName();
422 if (info.isFile() && info.isExecutable())
423 return QDir::cleanPath(path);
424 return QString();
425}
426
427static inline QString searchExecutable(const QStringList &searchPaths,
428 const QString &executableName)
429{
430 const QDir currentDir = QDir::current();
431 for (const QString &searchPath : searchPaths) {
432 const QString candidate = currentDir.absoluteFilePath(searchPath + u'/' + executableName);
433 const QString absPath = checkExecutable(candidate);
434 if (!absPath.isEmpty())
435 return absPath;
436 }
437 return QString();
438}
439
440#ifdef Q_OS_WIN
441
442// Find executable appending candidate suffixes, used for suffix-less executables
443// on Windows.
444static inline QString
445 searchExecutableAppendSuffix(const QStringList &searchPaths,
446 const QString &executableName,
447 const QStringList &suffixes)
448{
449 const QDir currentDir = QDir::current();
450 for (const QString &searchPath : searchPaths) {
451 const QString candidateRoot = currentDir.absoluteFilePath(searchPath + u'/' + executableName);
452 for (const QString &suffix : suffixes) {
453 const QString absPath = checkExecutable(candidateRoot + suffix);
454 if (!absPath.isEmpty())
455 return absPath;
456 }
457 }
458 return QString();
459}
460
461#endif // Q_OS_WIN
462
467{
468 if (QFileInfo(executableName).isAbsolute())
469 return checkExecutable(executableName);
470
471 QStringList searchPaths = paths;
472 if (paths.isEmpty()) {
473 QByteArray pEnv = qgetenv("PATH");
474 if (Q_UNLIKELY(pEnv.isNull())) {
475 // Get a default path. POSIX.1 does not actually require this, but
476 // most Unix libc fall back to confstr(_CS_PATH) if the PATH
477 // environment variable isn't set. Let's try to do the same.
478#if defined(_PATH_DEFPATH)
479 // BSD API.
480 pEnv = _PATH_DEFPATH;
481#elif defined(_CS_PATH)
482 // POSIX API.
483 size_t n = confstr(_CS_PATH, nullptr, 0);
484 if (n) {
485 pEnv.resize(n);
486 // size()+1 is ok because QByteArray always has an extra NUL-terminator
487 confstr(_CS_PATH, pEnv.data(), pEnv.size() + 1);
488 }
489#else
490 // Windows SDK's execvpe() does not have a fallback, so we won't
491 // apply one either.
492#endif
493 }
494
495 // Remove trailing slashes, which occur on Windows.
496 const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(
498 searchPaths.reserve(rawPaths.size());
499 for (const QString &rawPath : rawPaths) {
501 if (cleanPath.size() > 1 && cleanPath.endsWith(u'/'))
503 searchPaths.push_back(cleanPath);
504 }
505 }
506
507#ifdef Q_OS_WIN
508 // On Windows, if the name does not have a suffix or a suffix not
509 // in PATHEXT ("xx.foo"), append suffixes from PATHEXT.
510 static const QStringList executable_extensions = executableExtensions();
511 if (executableName.contains(u'.')) {
512 const QString suffix = QFileInfo(executableName).suffix();
513 if (suffix.isEmpty() || !executable_extensions.contains(u'.' + suffix, Qt::CaseInsensitive))
514 return searchExecutableAppendSuffix(searchPaths, executableName, executable_extensions);
515 } else {
516 return searchExecutableAppendSuffix(searchPaths, executableName, executable_extensions);
517 }
518#endif
519 return searchExecutable(searchPaths, executableName);
520}
521
526#if !defined(Q_OS_DARWIN) && !defined(QT_BOOTSTRAPPED)
528{
529 switch (type) {
530 case DesktopLocation:
531 return QCoreApplication::translate("QStandardPaths", "Desktop");
533 return QCoreApplication::translate("QStandardPaths", "Documents");
534 case FontsLocation:
535 return QCoreApplication::translate("QStandardPaths", "Fonts");
537 return QCoreApplication::translate("QStandardPaths", "Applications");
538 case MusicLocation:
539 return QCoreApplication::translate("QStandardPaths", "Music");
540 case MoviesLocation:
541 return QCoreApplication::translate("QStandardPaths", "Movies");
542 case PicturesLocation:
543 return QCoreApplication::translate("QStandardPaths", "Pictures");
544 case TempLocation:
545 return QCoreApplication::translate("QStandardPaths", "Temporary Directory");
546 case HomeLocation:
547 return QCoreApplication::translate("QStandardPaths", "Home");
549 return QCoreApplication::translate("QStandardPaths", "Application Data");
550 case CacheLocation:
551 return QCoreApplication::translate("QStandardPaths", "Cache");
553 return QCoreApplication::translate("QStandardPaths", "Shared Data");
554 case RuntimeLocation:
555 return QCoreApplication::translate("QStandardPaths", "Runtime");
556 case ConfigLocation:
557 return QCoreApplication::translate("QStandardPaths", "Configuration");
559 return QCoreApplication::translate("QStandardPaths", "Shared Configuration");
561 return QCoreApplication::translate("QStandardPaths", "Shared Cache");
562 case DownloadLocation:
563 return QCoreApplication::translate("QStandardPaths", "Download");
564 case AppDataLocation:
566 return QCoreApplication::translate("QStandardPaths", "Application Configuration");
568 return QCoreApplication::translate("QStandardPaths", "Public");
570 return QCoreApplication::translate("QStandardPaths", "Templates");
571 }
572 // not reached
573 return QString();
574}
575#endif
576
583Q_CONSTINIT static bool qsp_testMode = false;
584
586{
587 qsp_testMode = testMode;
588}
589
599{
600 return qsp_testMode;
601}
602
603
605
606#ifndef QT_NO_QOBJECT
607#include "moc_qstandardpaths.cpp"
608#endif
609
610#endif // QT_NO_STANDARDPATHS
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:534
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:474
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
bool isNull() const noexcept
Returns true if this byte array is null; otherwise returns false.
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
\inmodule QtCore
Definition qdir.h:19
static QDir current()
Returns the application's current directory.
Definition qdir.h:216
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qdir.cpp:1715
static QString cleanPath(const QString &path)
Returns path with directory separators normalized (that is, platform-native separators converted to "...
Definition qdir.cpp:2395
QString absoluteFilePath(const QString &fileName) const
Returns the absolute path name of a file in the directory.
Definition qdir.cpp:809
static constexpr QChar listSeparator() noexcept
Definition qdir.h:197
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
bool isBundle() const
QString suffix() const
Returns the suffix (extension) of the file.
QString bundleName() const
bool isExecutable() const
Returns true if the file is executable; otherwise returns false.
bool isFile() const
Returns true if this object points to a file or to a symbolic link to a file.
static QStringList locateAll(StandardLocation type, const QString &fileName, LocateOptions options=LocateFile)
[0]
static bool isTestModeEnabled()
static void setTestModeEnabled(bool testMode)
static QStringList standardLocations(StandardLocation type)
static QString displayName(StandardLocation type)
static QString findExecutable(const QString &executableName, const QStringList &paths=QStringList())
static QString locate(StandardLocation type, const QString &fileName, LocateOptions options=LocateFile)
StandardLocation
This enum describes the different locations that can be queried using methods such as QStandardPaths:...
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
Definition qstring.cpp:7956
void truncate(qsizetype pos)
Truncates the string at the given position index.
Definition qstring.cpp:6159
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5788
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition qstring.cpp:5350
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QString toLower() const &
Definition qstring.h:368
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.h:1217
Combined button and popup list for selecting options.
@ CaseInsensitive
@ SkipEmptyParts
Definition qnamespace.h:127
#define Q_UNLIKELY(x)
GLenum type
GLsizei const GLuint * paths
GLfloat n
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
static QString cleanPath(const QString &_path)
static bool existsAsSpecified(const QString &path, QStandardPaths::LocateOptions options)
static QString searchExecutable(const QStringList &searchPaths, const QString &executableName)
static Q_CONSTINIT bool qsp_testMode
static QString checkExecutable(const QString &path)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QFileInfo info(fileName)
[8]
QString dir
[11]