// Copyright (C) 2020 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:provides-trusted-directory-paths

#include "qstandardpaths.h"

#include <qdir.h>
#include <qfileinfo.h>
#include <qvarlengtharray.h>

#ifndef QT_BOOTSTRAPPED
#include <qobject.h>
#include <qcoreapplication.h>
#endif

#if __has_include(<paths.h>)
#include <paths.h>
#endif

#ifdef Q_OS_UNIX
#include <unistd.h>
#endif

#ifndef QT_NO_STANDARDPATHS

QT_BEGIN_NAMESPACE

using namespace Qt::StringLiterals;
/*!
    \class QStandardPaths
    \inmodule QtCore
    \brief The QStandardPaths class provides methods for accessing standard paths.
    \since 5.0

    This class contains functions to query standard locations on the local
    filesystem, for common tasks such as user-specific directories or system-wide
    configuration directories.
*/

/*!
    \enum QStandardPaths::StandardLocation

    This enum describes the different locations that can be queried using
    methods such as QStandardPaths::writableLocation, QStandardPaths::standardLocations,
    and QStandardPaths::displayName.

    QStandardPaths describes each location along two independent axes:
    app scope (private to the calling application or shared between
    applications) and user scope (rooted in the calling user's directories
    or system-wide). Each enum value below indicates its app scope; the
    platform tables further down show its user scope.

    Data interchange with other users is out of the scope of QStandardPaths.

    \section2 App scope

    A location is either \e application-specific (private to the calling
    application) or \e generic (shared between applications run by the
    same user). Application-specific locations should be assumed to be
    unreachable by other applications, even when run by the same user.

    \section3 Sandboxed applications

    For sandboxed applications, on platforms such as iOS, Android, or macOS,
    even generic locations can be rooted in the application's sandbox container
    (\c{<APPROOT>} in the tables below). In practice this collapses the
    app-scope distinction, with every location becoming effectively
    application-specific, and the user's system-wide shared directories reachable
    only through system-provided pickers, for example, QFileDialog.

    \section2 User scope

    A location is either \e user-local (rooted in the calling user's
    home or per-user directories) or \e system-wide (populated by the OS
    or by package managers, shared across users, and usually read-only to
    applications).

    Querying writableLocation() returns the directory where files should be
    written, which is typically user-scoped. For application-specific locations
    it is also scoped to the calling application.

    Querying standardLocations() returns the writable path first (if it can be
    determined), followed by zero or more additional locations, including both
    user-local and system-wide fallbacks. The additional locations are used by
    locate() and locateAll() to find existing files.

    \section3 Sandboxed applications

    For sandboxed applications, system-wide locations typically fall outside
    the application's sandbox container, and may not exist from the
    application's point of view, let alone be readable or writable. They are
    still listed in the platform tables below for symmetry with the
    non-sandboxed case, and to cover applications that have been granted access
    through entitlements or user-driven pickers. Callers should not assume that
    every entry returned by standardLocations() exists or is accessible.

    \value DesktopLocation The user's desktop directory. On systems with no
           concept of a desktop, this is the same as HomeLocation. Generic.
    \value DocumentsLocation Directory containing document files. The
           returned path is never empty. Generic.
    \value FontsLocation Directory containing fonts. Note that installing
           fonts may require additional, platform-specific operations.
           Generic.
    \value ApplicationsLocation Directory containing applications (either
           executables, application bundles, or shortcuts to them). Note
           that installing applications may require additional,
           platform-specific operations. Files, folders, or shortcuts in this
           directory are platform-specific. Generic.
    \value MusicLocation Directory containing music or other audio files.
           If no such directory exists, a sensible fallback for storing
           documents is returned. Generic.
    \value MoviesLocation Directory containing movies and videos. If no
           such directory exists, a sensible fallback for storing documents
           is returned. Generic.
    \value PicturesLocation Directory containing pictures or photos. If no
           such directory exists, a sensible fallback for storing documents
           is returned. Generic.
    \value TempLocation Directory where temporary files can be stored. The
           returned value might be application-specific, shared among other
           applications for this user, or even system-wide. The returned
           path is never empty. Varies.
    \value HomeLocation The user's home directory (the same as
           QDir::homePath()). On Unix systems, this is equal to the HOME
           environment variable. The returned path is never empty. Generic.
    \value AppLocalDataLocation The local data path on Windows. On all
           other platforms, the same as AppDataLocation. Application-specific.
           This enum value was added in Qt 5.4.
    \value CacheLocation Directory where non-essential (cached) data should
           be written. The returned path is never empty.
           Application-specific.
    \value GenericCacheLocation Directory where non-essential (cached) data
           shared across applications should be written. Note that the
           returned path may be empty if the system has no concept of
           shared cache. Generic.
    \value GenericDataLocation Directory where persistent data shared
           across applications can be stored. The returned path is never
           empty. Generic.
    \value RuntimeLocation Directory where runtime communication files
           should be written, like Unix local sockets. The returned path
           may be empty on some systems. Generic.
    \value ConfigLocation Directory where configuration files should be
           written. The returned path is never empty. May be generic or
           application-specific (see AppConfigLocation and
           GenericConfigLocation for explicit variants). Varies.
    \value DownloadLocation Directory for downloaded files. If no such
           directory exists, a sensible fallback for storing documents is
           returned. Generic.
    \value GenericConfigLocation Directory where configuration files shared
           between multiple applications should be written. The returned
           path is never empty. Generic.
    \value AppDataLocation Directory where persistent application data can
           be stored. To obtain a path to store data to be shared with
           other applications, use GenericDataLocation. The returned path
           is never empty. On Windows, this returns the roaming path.
           Application-specific.
           This enum value was added in Qt 5.4.
    \value AppConfigLocation Directory where configuration files should be
           written. The returned path is never empty.
           Application-specific.
           This enum value was added in Qt 5.5.
    \value PublicShareLocation Directory where publicly shared files and
           directories can be stored. Note that the returned path may be
           empty if the system has no concept of a publicly shared location.
           Generic.
           This enum value was added in Qt 6.4.
    \value TemplatesLocation Directory where template files can be stored.
           Note that the returned path may be empty if the system has no
           concept of a templates location. Generic.
           This enum value was added in Qt 6.4.
    \value [since 6.7] StateLocation Directory where application state data
           files should be written. The returned path is never empty.
           Application-specific.
    \value [since 6.7] GenericStateLocation Directory where shared state
           data files across applications should be written. The returned
           path is never empty. Generic.

    The following table gives examples of paths on different operating systems.
    The first path is the writable path (unless noted). Other, additional
    paths, if any, represent non-writable locations.

    \table
    \header \li Path type \li \macos  \li Windows
    \row \li DesktopLocation
         \li "~/Desktop"
         \li "C:/Users/<USER>/Desktop"
    \row \li DocumentsLocation
         \li "~/Documents"
         \li "C:/Users/<USER>/Documents"
    \row \li FontsLocation
         \li "~/Library/Fonts", "/Library/Fonts", "/System/Library/Fonts"
         \li "C:/Windows/Fonts" (not writable)
    \row \li ApplicationsLocation
         \li "~/Applications", "/Applications"
         \li "C:/Users/<USER>/AppData/Roaming/Microsoft/Windows/Start Menu/Programs"
    \row \li MusicLocation
         \li "~/Music"
         \li "C:/Users/<USER>/Music"
    \row \li MoviesLocation
         \li "~/Movies"
         \li "C:/Users/<USER>/Videos"
    \row \li PicturesLocation
         \li "~/Pictures"
         \li "C:/Users/<USER>/Pictures"
    \row \li TempLocation
         \li randomly generated by the OS
         \li "C:/Users/<USER>/AppData/Local/Temp"
    \row \li HomeLocation
         \li "~"
         \li "C:/Users/<USER>"
    \row \li AppLocalDataLocation
         \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
         \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data", "<APPDIR>/data/<APPNAME>"
    \row \li CacheLocation
         \li "~/Library/Caches/<APPNAME>", "/Library/Caches/<APPNAME>"
         \li "C:/Users/<USER>/AppData/Local/<APPNAME>/cache"
    \row \li StateLocation
         \li "~/Library/Preferences/<APPNAME>/State"
         \li "C:/Users/<USER>/AppData/Local/<APPNAME>/State", "C:/ProgramData/<APPNAME>/State"
    \row \li GenericDataLocation
         \li "~/Library/Application Support", "/Library/Application Support"
         \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData", "<APPDIR>", "<APPDIR>/data"
    \row \li RuntimeLocation
         \li "~/Library/Application Support"
         \li "C:/Users/<USER>"
    \row \li ConfigLocation
         \li "~/Library/Preferences", "/Library/Preferences"
         \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>"
    \row \li GenericConfigLocation
         \li "~/Library/Preferences", "/Library/Preferences"
         \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
    \row \li DownloadLocation
         \li "~/Downloads"
         \li "C:/Users/<USER>/Downloads"
    \row \li GenericCacheLocation
         \li "~/Library/Caches", "/Library/Caches", "/System/Library/Caches"
         \li "C:/Users/<USER>/AppData/Local/cache"
    \row \li GenericStateLocation
         \li "~/Library/Preferences/State"
         \li "C:/Users/<USER>/AppData/Local/State", "C:/ProgramData/State"
    \row \li AppDataLocation
         \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
         \li "C:/Users/<USER>/AppData/Roaming/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data", "<APPDIR>/data/<APPNAME>"
    \row \li AppConfigLocation
         \li "~/Library/Preferences/<APPNAME>", "/Library/Preferences/<APPNAME>"
         \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>"
    \row \li PublicShareLocation
         \li "~/Public"
         \li "C:/Users/Public"
    \row \li TemplatesLocation
         \li not supported
         \li "C:/Users/<USER>/AppData/Roaming/Microsoft/Windows/Templates"
    \endtable

    \table
    \header \li Path type \li Linux and other UNIX operating systems
    \row \li DesktopLocation
         \li "~/Desktop"
    \row \li DocumentsLocation
         \li "~/Documents"
    \row \li FontsLocation
         \li "~/.fonts", "~/.local/share/fonts", "/usr/local/share/fonts", "/usr/share/fonts"
    \row \li ApplicationsLocation
         \li "~/.local/share/applications", "/usr/local/share/applications", "/usr/share/applications"
    \row \li MusicLocation
         \li "~/Music"
    \row \li MoviesLocation
         \li "~/Videos"
    \row \li PicturesLocation
         \li "~/Pictures"
    \row \li TempLocation
         \li "/tmp"
    \row \li HomeLocation
         \li "~"
    \row \li AppLocalDataLocation
         \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
    \row \li CacheLocation
         \li "~/.cache/<APPNAME>"
    \row \li StateLocation
         \li "~/.local/state/<APPNAME>"
    \row \li GenericDataLocation
         \li "~/.local/share", "/usr/local/share", "/usr/share"
    \row \li RuntimeLocation
         \li "/run/user/<USER>"
    \row \li ConfigLocation
         \li "~/.config", "/etc/xdg"
    \row \li GenericConfigLocation
         \li "~/.config", "/etc/xdg"
    \row \li DownloadLocation
         \li "~/Downloads"
    \row \li GenericCacheLocation
         \li "~/.cache"
    \row \li GenericStateLocation
         \li "~/.local/state"
    \row \li AppDataLocation
         \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
    \row \li AppConfigLocation
         \li "~/.config/<APPNAME>", "/etc/xdg/<APPNAME>"
    \row \li PublicShareLocation
         \li "~/Public"
    \row \li TemplatesLocation
         \li "~/Templates"
    \endtable

    \table
    \header \li Path type \li Android \li iOS
    \row \li DesktopLocation
         \li "<APPROOT>/files"
         \li "<APPROOT>/Documents/Desktop"
    \row \li DocumentsLocation
         \li "<USER>/Documents" [*], "<USER>/<APPNAME>/Documents"
         \li "<APPROOT>/Documents"
    \row \li FontsLocation
         \li "/system/fonts" (not writable)
         \li "<APPROOT>/Library/Fonts"
    \row \li ApplicationsLocation
         \li not supported (directory not readable)
         \li not supported
    \row \li MusicLocation
         \li "<USER>/Music" [*], "<USER>/<APPNAME>/Music"
         \li "<APPROOT>/Documents/Music"
    \row \li MoviesLocation
         \li "<USER>/Movies" [*], "<USER>/<APPNAME>/Movies"
         \li "<APPROOT>/Documents/Movies"
    \row \li PicturesLocation
         \li "<USER>/Pictures" [*], "<USER>/<APPNAME>/Pictures"
         \li "<APPROOT>/Documents/Pictures", "assets-library://"
    \row \li TempLocation
         \li "<APPROOT>/cache"
         \li "<APPROOT>/tmp"
    \row \li HomeLocation
         \li "<APPROOT>/files"
         \li system defined
    \row \li AppLocalDataLocation
         \li "<APPROOT>/files", "<USER>/<APPNAME>/files"
         \li "<APPROOT>/Library/Application Support"
    \row \li CacheLocation
         \li "<APPROOT>/cache", "<USER>/<APPNAME>/cache"
         \li "<APPROOT>/Library/Caches"
    \row \li StateLocation
         \li "<APPROOT>/files/state"
         \li "<APPROOT>/Library/Preferences/<APPNAME>/State"
    \row \li GenericStateLocation (there is shared state)
         \li "<APPROOT>/files/state"
         \li "<APPROOT>/Library/Preferences/State"
    \row \li GenericDataLocation
         \li "<USER>" [*] or "<USER>/<APPNAME>/files"
         \li "<APPROOT>/Library/Application Support"
    \row \li RuntimeLocation
         \li "<APPROOT>/cache"
         \li "<APPROOT>/Library/Application Support"
    \row \li ConfigLocation
         \li "<APPROOT>/files/settings"
         \li "<APPROOT>/Library/Preferences"
    \row \li GenericConfigLocation
         \li "<APPROOT>/files/settings" (there is no shared settings)
         \li "<APPROOT>/Library/Preferences"
    \row \li DownloadLocation
         \li "<USER>/Downloads" [*], "<USER>/<APPNAME>/Downloads"
         \li "<APPROOT>/Documents/Downloads"
    \row \li GenericCacheLocation
         \li "<APPROOT>/cache" (there is no shared cache)
         \li "<APPROOT>/Library/Caches"
    \row \li AppDataLocation
         \li "<APPROOT>/files", "<USER>/<APPNAME>/files"
         \li "<APPROOT>/Library/Application Support"
    \row \li AppConfigLocation
         \li "<APPROOT>/files/settings"
         \li "<APPROOT>/Library/Preferences/<APPNAME>"
    \row \li PublicShareLocation
         \li not supported
         \li "<APPROOT>/Public"
    \row \li TemplatesLocation
         \li not supported
         \li not supported
    \endtable

    In the table above, \c <APPNAME> is usually the organization name, the
    application name, or both, or a unique name generated at packaging.
    Similarly, <APPROOT> is the location where this application is installed
    (often a sandbox). <APPDIR> is the directory containing the application
    executable.

    The paths above should not be relied upon, as they may change according to
    OS configuration, locale, or they may change in future Qt versions.

    \note On Android, applications with open files on the external storage (<USER> locations),
        will be killed if the external storage is unmounted.

    \note On Android 6.0 (API 23) or higher, the "WRITE_EXTERNAL_STORAGE" permission must be
        requested at runtime when using QStandardPaths::writableLocation or QStandardPaths::standardLocations.

    \note On Android, reading/writing to GenericDataLocation needs the READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE permission granted.

    \note [*] On Android 11 and above, public directories are no longer directly accessible
    in scoped storage mode. Thus, paths of the form \c "<USER>/DirName" are not returned.
    Instead, you can use \l QFileDialog which uses the Storage Access Framework (SAF)
    to access such directories.

    \note On iOS, if you do pass \c {QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).last()}
        as argument to \l{QFileDialog::setDirectory()},
        a native image picker dialog will be used for accessing the user's photo album.
        The filename returned can be loaded using QFile and related APIs.
        This feature was added in Qt 5.5.

    \sa writableLocation(), standardLocations(), displayName(), locate(), locateAll()
*/

/*!
    \fn QString QStandardPaths::writableLocation(StandardLocation type)

    \include standardpath/functiondocs.qdocinc writableLocation
*/


/*!
   \fn QStringList QStandardPaths::standardLocations(StandardLocation type)

   \include standardpath/functiondocs.qdocinc standardLocations

   \sa writableLocation()
 */

/*!
    \enum QStandardPaths::LocateOption

    This enum describes the different flags that can be used for
    controlling the behavior of QStandardPaths::locate and
    QStandardPaths::locateAll.

    \value LocateFile return only files
    \value LocateDirectory return only directories
*/

static bool existsAsSpecified(const QString &path, QStandardPaths::LocateOptions options)
{
    if (options & QStandardPaths::LocateDirectory)
        return QDir(path).exists();
    return QFileInfo(path).isFile();
}

/*!
    \include standardpath/functiondocs.qdocinc locate
 */
QString QStandardPaths::locate(StandardLocation type, const QString &fileName, LocateOptions options)
{
    const QStringList &dirs = standardLocations(type);
    for (QStringList::const_iterator dir = dirs.constBegin(); dir != dirs.constEnd(); ++dir) {
        const QString path = *dir + u'/' + fileName;
        if (existsAsSpecified(path, options))
            return path;
    }
    return QString();
}

/*!
    \include standardpath/functiondocs.qdocinc locateAll
 */
QStringList QStandardPaths::locateAll(StandardLocation type, const QString &fileName, LocateOptions options)
{
    const QStringList &dirs = standardLocations(type);
    QStringList result;
    for (QStringList::const_iterator dir = dirs.constBegin(); dir != dirs.constEnd(); ++dir) {
        const QString path = *dir + u'/' + fileName;
        if (existsAsSpecified(path, options))
            result.append(path);
    }
    return result;
}

static Q_DECL_COLD_FUNCTION QString fallbackPathVariable()
{
#if defined(_PATH_DEFPATH)
    // BSD API.
    return QString::fromLocal8Bit(_PATH_DEFPATH);
#endif
#if defined(_CS_PATH)
    // POSIX API.
    size_t n = confstr(_CS_PATH, nullptr, 0);
    if (n) {
        // n includes the terminating null
        QVarLengthArray<char, 1024> rawpath(n);
        confstr(_CS_PATH, rawpath.data(), n);
        return QString::fromLocal8Bit(QByteArrayView(rawpath.data(), n - 1));
    }
#else
    // Windows SDK's execvpe() does not have a fallback, so we won't
    // apply one either.
#endif
    return {};
}

#ifdef Q_OS_WIN
static QStringList executableExtensions()
{
    // If %PATHEXT% does not contain .exe, it is either empty, malformed, or distorted in ways that we cannot support, anyway.
    const QStringList pathExt = QString::fromLocal8Bit(qgetenv("PATHEXT")).toLower().split(u';');
    return pathExt.contains(".exe"_L1, Qt::CaseInsensitive) ?
           pathExt : QStringList{".exe"_L1, ".com"_L1, ".bat"_L1, ".cmd"_L1};
}
#endif

static QString checkExecutable(const QString &path)
{
    const QFileInfo info(path);
    if (info.isBundle())
        return info.bundleName();
    if (info.isFile() && info.isExecutable())
        return QDir::cleanPath(path);
    return QString();
}

static inline QString searchExecutable(const QStringList &searchPaths,
                                       const QString &executableName)
{
    const QDir currentDir = QDir::current();
    for (const QString &searchPath : searchPaths) {
        const QString candidate = currentDir.absoluteFilePath(searchPath + u'/' + executableName);
        const QString absPath = checkExecutable(candidate);
        if (!absPath.isEmpty())
            return absPath;
    }
    return QString();
}

#ifdef Q_OS_WIN

// Find executable appending candidate suffixes, used for suffix-less executables
// on Windows.
static inline QString
    searchExecutableAppendSuffix(const QStringList &searchPaths,
                                 const QString &executableName,
                                 const QStringList &suffixes)
{
    const QDir currentDir = QDir::current();
    for (const QString &searchPath : searchPaths) {
        const QString candidateRoot = currentDir.absoluteFilePath(searchPath + u'/' + executableName);
        for (const QString &suffix : suffixes) {
            const QString absPath = checkExecutable(candidateRoot + suffix);
            if (!absPath.isEmpty())
                return absPath;
        }
    }
    return QString();
}

#endif // Q_OS_WIN

/*!
    \include standardpath/functiondocs.qdocinc findExecutable
 */
QString QStandardPaths::findExecutable(const QString &executableName, const QStringList &paths)
{
    if (QFileInfo(executableName).isAbsolute())
        return checkExecutable(executableName);

    QStringList searchPaths = paths;
    if (paths.isEmpty()) {
        QString pEnv = qEnvironmentVariable("PATH");
        if (Q_UNLIKELY(pEnv.isNull())) {
            // Get a default path. POSIX.1 does not actually require this, but
            // most Unix libc fall back to confstr(_CS_PATH) if the PATH
            // environment variable isn't set. Let's try to do the same.
            pEnv = fallbackPathVariable();
        }

        // Remove trailing slashes, which occur on Windows.
        searchPaths.reserve(pEnv.count(QDir::listSeparator()));
        auto tokenizer = qTokenize(pEnv, QDir::listSeparator(), Qt::SkipEmptyParts);
        for (QStringView rawPath : tokenizer) {
            QString cleanPath = QDir::cleanPath(rawPath.toString());
            if (cleanPath.size() > 1 && cleanPath.endsWith(u'/'))
                cleanPath.truncate(cleanPath.size() - 1);
            searchPaths.push_back(cleanPath);
        }
    }

#ifdef Q_OS_WIN
    // On Windows, if the name does not have a suffix or a suffix not
    // in PATHEXT ("xx.foo"), append suffixes from PATHEXT.
    static const QStringList executable_extensions = executableExtensions();
    if (executableName.contains(u'.')) {
        const QString suffix = QFileInfo(executableName).suffix();
        if (suffix.isEmpty() || !executable_extensions.contains(u'.' + suffix, Qt::CaseInsensitive))
            return searchExecutableAppendSuffix(searchPaths, executableName, executable_extensions);
    } else {
        return searchExecutableAppendSuffix(searchPaths, executableName, executable_extensions);
    }
#endif
    return searchExecutable(searchPaths, executableName);
}

/*!
    \fn QString QStandardPaths::displayName(StandardLocation type)

    \include standardpath/functiondocs.qdocinc displayName
*/

#if !defined(Q_OS_DARWIN) && !defined(QT_BOOTSTRAPPED)
QString QStandardPaths::displayName(StandardLocation type)
{
    switch (type) {
    case DesktopLocation:
        return QCoreApplication::translate("QStandardPaths", "Desktop");
    case DocumentsLocation:
        return QCoreApplication::translate("QStandardPaths", "Documents");
    case FontsLocation:
        return QCoreApplication::translate("QStandardPaths", "Fonts");
    case ApplicationsLocation:
        return QCoreApplication::translate("QStandardPaths", "Applications");
    case MusicLocation:
        return QCoreApplication::translate("QStandardPaths", "Music");
    case MoviesLocation:
        return QCoreApplication::translate("QStandardPaths", "Movies");
    case PicturesLocation:
        return QCoreApplication::translate("QStandardPaths", "Pictures");
    case TempLocation:
        return QCoreApplication::translate("QStandardPaths", "Temporary Directory");
    case HomeLocation:
        return QCoreApplication::translate("QStandardPaths", "Home");
    case AppLocalDataLocation:
        return QCoreApplication::translate("QStandardPaths", "Application Data");
    case CacheLocation:
        return QCoreApplication::translate("QStandardPaths", "Cache");
    case StateLocation:
        return QCoreApplication::translate("QStandardPaths", "State");
    case GenericDataLocation:
        return QCoreApplication::translate("QStandardPaths", "Shared Data");
    case RuntimeLocation:
        return QCoreApplication::translate("QStandardPaths", "Runtime");
    case ConfigLocation:
        return QCoreApplication::translate("QStandardPaths", "Configuration");
    case GenericConfigLocation:
        return QCoreApplication::translate("QStandardPaths", "Shared Configuration");
    case GenericCacheLocation:
        return QCoreApplication::translate("QStandardPaths", "Shared Cache");
    case GenericStateLocation:
        return QCoreApplication::translate("QStandardPaths", "Shared State");
    case DownloadLocation:
        return QCoreApplication::translate("QStandardPaths", "Downloads");
    case AppDataLocation:
    case AppConfigLocation:
        return QCoreApplication::translate("QStandardPaths", "Application Configuration");
    case PublicShareLocation:
        return QCoreApplication::translate("QStandardPaths", "Public");
    case TemplatesLocation:
        return QCoreApplication::translate("QStandardPaths", "Templates");
    }
    // not reached
    return QString();
}
#endif

/*!
  \fn void QStandardPaths::setTestModeEnabled(bool testMode)

  \include standardpath/functiondocs.qdocinc setTestModeEnabled
*/

Q_CONSTINIT static bool qsp_testMode = false;

void QStandardPaths::setTestModeEnabled(bool testMode)
{
    qsp_testMode = testMode;
}

/*!
  \fn void QStandardPaths::isTestModeEnabled()

  \internal

  Returns \c true if test mode is enabled in QStandardPaths; otherwise returns \c false.
*/

bool QStandardPaths::isTestModeEnabled()
{
    return qsp_testMode;
}


QT_END_NAMESPACE

#ifndef QT_NO_QOBJECT
#include "moc_qstandardpaths.cpp"
#endif

#endif // QT_NO_STANDARDPATHS
