/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qmakeevaluator.h"

#include "qmakeevaluator_p.h"
#include "qmakeglobals.h"
#include "qmakeparser.h"
#include "qmakevfs.h"
#include "ioutils.h"

#include <qbytearray.h>
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qlist.h>
#include <qregexp.h>
#include <qset.h>
#include <qstringlist.h>
#include <qtextstream.h>
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
# include <qjsondocument.h>
# include <qjsonobject.h>
# include <qjsonarray.h>
#endif
#ifdef PROEVALUATOR_THREAD_SAFE
# include <qthreadpool.h>
#endif
#include <qversionnumber.h>
#ifdef Q_OS_WIN
# include <registry_p.h>
#endif

#include <algorithm>

#ifdef Q_OS_UNIX
#include <time.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#else
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>

#ifdef Q_OS_WIN32
#define QT_POPEN _popen
#define QT_POPEN_READ "rb"
#define QT_PCLOSE _pclose
#else
#define QT_POPEN popen
#define QT_POPEN_READ "r"
#define QT_PCLOSE pclose
#endif

using namespace QMakeInternal;

QT_BEGIN_NAMESPACE

#define fL1S(s) QString::fromLatin1(s)

enum ExpandFunc {
    E_INVALID = 0, E_MEMBER, E_STR_MEMBER, E_FIRST, E_TAKE_FIRST, E_LAST, E_TAKE_LAST,
    E_SIZE, E_STR_SIZE, E_CAT, E_FROMFILE, E_EVAL, E_LIST, E_SPRINTF, E_FORMAT_NUMBER,
    E_NUM_ADD, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION,
    E_FIND, E_SYSTEM, E_UNIQUE, E_SORTED, E_REVERSE, E_QUOTE, E_ESCAPE_EXPAND,
    E_UPPER, E_LOWER, E_TITLE, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE,
    E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS,
    E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH,
    E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE, E_GETENV, E_READ_REGISTRY
};

enum TestFunc {
    T_INVALID = 0, T_REQUIRES, T_GREATERTHAN, T_LESSTHAN, T_EQUALS,
    T_VERSION_AT_LEAST, T_VERSION_AT_MOST,
    T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
    T_DEFINED, T_DISCARD_FROM, T_CONTAINS, T_INFILE,
    T_COUNT, T_ISEMPTY, T_PARSE_JSON, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF,
    T_MKPATH, T_WRITE_FILE, T_TOUCH, T_CACHE, T_RELOAD_PROPERTIES
};

QMakeBuiltin::QMakeBuiltin(const QMakeBuiltinInit &d)
    : index(d.func), minArgs(qMax(0, d.min_args)), maxArgs(d.max_args)
{
    static const char * const nstr[6] = { "no", "one", "two", "three", "four", "five" };
    // For legacy reasons, there is actually no such thing as "no arguments"
    // - there is only "empty first argument", which needs to be mapped back.
    // -1 means "one, which may be empty", which is effectively zero, except
    // for the error message if there are too many arguments.
    int dmin = qAbs(d.min_args);
    int dmax = d.max_args;
    if (dmax == QMakeBuiltinInit::VarArgs) {
        Q_ASSERT_X(dmin < 2, "init", d.name);
        if (dmin == 1) {
            Q_ASSERT_X(d.args != nullptr, "init", d.name);
            usage = fL1S("%1(%2) requires at least one argument.")
                    .arg(fL1S(d.name), fL1S(d.args));
        }
        return;
    }
    int arange = dmax - dmin;
    Q_ASSERT_X(arange >= 0, "init", d.name);
    Q_ASSERT_X(d.args != nullptr, "init", d.name);
    usage = arange > 1
               ? fL1S("%1(%2) requires %3 to %4 arguments.")
                 .arg(fL1S(d.name), fL1S(d.args), fL1S(nstr[dmin]), fL1S(nstr[dmax]))
               : arange > 0
                   ? fL1S("%1(%2) requires %3 or %4 arguments.")
                     .arg(fL1S(d.name), fL1S(d.args), fL1S(nstr[dmin]), fL1S(nstr[dmax]))
                   : dmax != 1
                       ? fL1S("%1(%2) requires %3 arguments.")
                         .arg(fL1S(d.name), fL1S(d.args), fL1S(nstr[dmax]))
                       : fL1S("%1(%2) requires one argument.")
                         .arg(fL1S(d.name), fL1S(d.args));
}

void QMakeEvaluator::initFunctionStatics()
{
    static const QMakeBuiltinInit expandInits[] = {
        { "member", E_MEMBER, 1, 3, "var, [start, [end]]" },
        { "str_member", E_STR_MEMBER, -1, 3, "str, [start, [end]]" },
        { "first", E_FIRST, 1, 1, "var" },
        { "take_first", E_TAKE_FIRST, 1, 1, "var" },
        { "last", E_LAST, 1, 1, "var" },
        { "take_last", E_TAKE_LAST, 1, 1, "var" },
        { "size", E_SIZE, 1, 1, "var" },
        { "str_size", E_STR_SIZE, -1, 1, "str" },
        { "cat", E_CAT, 1, 2, "file, [mode=true|blob|lines]" },
        { "fromfile", E_FROMFILE, 2, 2, "file, var" },
        { "eval", E_EVAL, 1, 1, "var" },
        { "list", E_LIST, 0, QMakeBuiltinInit::VarArgs, nullptr },
        { "sprintf", E_SPRINTF, 1, QMakeBuiltinInit::VarArgs, "format, ..." },
        { "format_number", E_FORMAT_NUMBER, 1, 2, "number, [options...]" },
        { "num_add", E_NUM_ADD, 1, QMakeBuiltinInit::VarArgs, "num, ..." },
        { "join", E_JOIN, 1, 4, "var, [glue, [before, [after]]]" },
        { "split", E_SPLIT, 1, 2, "var, sep" },
        { "basename", E_BASENAME, 1, 1, "var" },
        { "dirname", E_DIRNAME, 1, 1, "var" },
        { "section", E_SECTION, 3, 4, "var, sep, begin, [end]" },
        { "find", E_FIND, 2, 2, "var, str" },
        { "system", E_SYSTEM, 1, 3, "command, [mode], [stsvar]" },
        { "unique", E_UNIQUE, 1, 1, "var" },
        { "sorted", E_SORTED, 1, 1, "var" },
        { "reverse", E_REVERSE, 1, 1, "var" },
        { "quote", E_QUOTE, 0, QMakeBuiltinInit::VarArgs, nullptr },
        { "escape_expand", E_ESCAPE_EXPAND, 0, QMakeBuiltinInit::VarArgs, nullptr },
        { "upper", E_UPPER, 0, QMakeBuiltinInit::VarArgs, nullptr },
        { "lower", E_LOWER, 0, QMakeBuiltinInit::VarArgs, nullptr },
        { "title", E_TITLE, 0, QMakeBuiltinInit::VarArgs, nullptr },
        { "re_escape", E_RE_ESCAPE, 0, QMakeBuiltinInit::VarArgs, nullptr },
        { "val_escape", E_VAL_ESCAPE, 1, 1, "var" },
        { "files", E_FILES, 1, 2, "pattern, [recursive=false]" },
        { "prompt", E_PROMPT, 1, 2, "question, [decorate=true]" },
        { "replace", E_REPLACE, 3, 3, "var, before, after" },
        { "sort_depends", E_SORT_DEPENDS, 1, 4, "var, [prefix, [suffixes, [prio-suffix]]]" },
        { "resolve_depends", E_RESOLVE_DEPENDS, 1, 4, "var, [prefix, [suffixes, [prio-suffix]]]" },
        { "enumerate_vars", E_ENUMERATE_VARS, 0, 0, "" },
        { "shadowed", E_SHADOWED, 1, 1, "path" },
        { "absolute_path", E_ABSOLUTE_PATH, -1, 2, "path, [base]" },
        { "relative_path", E_RELATIVE_PATH, -1, 2, "path, [base]" },
        { "clean_path", E_CLEAN_PATH, -1, 1, "path" },
        { "system_path", E_SYSTEM_PATH, -1, 1, "path" },
        { "shell_path", E_SHELL_PATH, -1, 1, "path" },
        { "system_quote", E_SYSTEM_QUOTE, -1, 1, "arg" },
        { "shell_quote", E_SHELL_QUOTE, -1, 1, "arg" },
        { "getenv", E_GETENV, 1, 1, "arg" },
        { "read_registry", E_READ_REGISTRY, 2, 3, "tree, key, [wow64]" },
    };
    statics.expands.reserve((int)(sizeof(expandInits)/sizeof(expandInits[0])));
    for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i)
        statics.expands.insert(ProKey(expandInits[i].name), QMakeBuiltin(expandInits[i]));

    static const QMakeBuiltinInit testInits[] = {
        { "requires", T_REQUIRES, 0, QMakeBuiltinInit::VarArgs, nullptr },
        { "greaterThan", T_GREATERTHAN, 2, 2, "var, val" },
        { "lessThan", T_LESSTHAN, 2, 2, "var, val" },
        { "equals", T_EQUALS, 2, 2, "var, val" },
        { "isEqual", T_EQUALS, 2, 2, "var, val" },
        { "versionAtLeast", T_VERSION_AT_LEAST, 2, 2, "var, version" },
        { "versionAtMost", T_VERSION_AT_MOST, 2, 2, "var, version" },
        { "exists", T_EXISTS, 1, 1, "file" },
        { "export", T_EXPORT, 1, 1, "var" },
        { "clear", T_CLEAR, 1, 1, "var" },
        { "unset", T_UNSET, 1, 1, "var" },
        { "eval", T_EVAL, 0, QMakeBuiltinInit::VarArgs, nullptr },
        { "CONFIG", T_CONFIG, 1, 2, "config, [mutuals]" },
        { "if", T_IF, 1, 1, "condition" },
        { "isActiveConfig", T_CONFIG, 1, 2, "config, [mutuals]" },
        { "system", T_SYSTEM, 1, 1, "exec" },
        { "discard_from", T_DISCARD_FROM, 1, 1, "file" },
        { "defined", T_DEFINED, 1, 2, "object, [\"test\"|\"replace\"|\"var\"]" },
        { "contains", T_CONTAINS, 2, 3, "var, val, [mutuals]" },
        { "infile", T_INFILE, 2, 3, "file, var, [values]" },
        { "count", T_COUNT, 2, 3, "var, count, [op=operator]" },
        { "isEmpty", T_ISEMPTY, 1, 1, "var" },
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
        { "parseJson", T_PARSE_JSON, 2, 2, "var, into" },
#endif
        { "load", T_LOAD, 1, 2, "feature, [ignore_errors=false]" },
        { "include", T_INCLUDE, 1, 3, "file, [into, [silent]]" },
        { "debug", T_DEBUG, 2, 2, "level, message" },
        { "log", T_LOG, 1, 1, "message" },
        { "message", T_MESSAGE, 1, 1, "message" },
        { "warning", T_WARNING, 1, 1, "message" },
        { "error", T_ERROR, 0, 1, "message" },
        { "mkpath", T_MKPATH, 1, 1, "path" },
        { "write_file", T_WRITE_FILE, 1, 3, "name, [content var, [append] [exe]]" },
        { "touch", T_TOUCH, 2, 2, "file, reffile" },
        { "cache", T_CACHE, 0, 3, "[var], [set|add|sub] [transient] [super|stash], [srcvar]" },
        { "reload_properties", T_RELOAD_PROPERTIES, 0, 0, "" },
    };
    statics.functions.reserve((int)(sizeof(testInits)/sizeof(testInits[0])));
    for (unsigned i = 0; i < sizeof(testInits)/sizeof(testInits[0]); ++i)
        statics.functions.insert(ProKey(testInits[i].name), QMakeBuiltin(testInits[i]));
}

static bool isTrue(const ProString &str)
{
    return !str.compare(statics.strtrue, Qt::CaseInsensitive) || str.toInt();
}

bool
QMakeEvaluator::getMemberArgs(const ProKey &func, int srclen, const ProStringList &args,
                              int *start, int *end)
{
    *start = 0, *end = 0;
    if (args.count() >= 2) {
        bool ok = true;
        const ProString &start_str = args.at(1);
        *start = start_str.toInt(&ok);
        if (!ok) {
            if (args.count() == 2) {
                int dotdot = start_str.indexOf(statics.strDotDot);
                if (dotdot != -1) {
                    *start = start_str.left(dotdot).toInt(&ok);
                    if (ok)
                        *end = start_str.mid(dotdot+2).toInt(&ok);
                }
            }
            if (!ok) {
                ProStringRoUser u1(func, m_tmp1);
                ProStringRoUser u2(start_str, m_tmp2);
                evalError(fL1S("%1() argument 2 (start) '%2' invalid.").arg(u1.str(), u2.str()));
                return false;
            }
        } else {
            *end = *start;
            if (args.count() == 3)
                *end = args.at(2).toInt(&ok);
            if (!ok) {
                ProStringRoUser u1(func, m_tmp1);
                ProStringRoUser u2(args.at(2), m_tmp2);
                evalError(fL1S("%1() argument 3 (end) '%2' invalid.").arg(u1.str(), u2.str()));
                return false;
            }
        }
    }
    if (*start < 0)
        *start += srclen;
    if (*end < 0)
        *end += srclen;
    if (*start < 0 || *start >= srclen || *end < 0 || *end >= srclen)
        return false;
    return true;
}

QString
QMakeEvaluator::quoteValue(const ProString &val)
{
    QString ret;
    ret.reserve(val.size());
    const QChar *chars = val.constData();
    bool quote = val.isEmpty();
    bool escaping = false;
    for (int i = 0, l = val.size(); i < l; i++) {
        QChar c = chars[i];
        ushort uc = c.unicode();
        if (uc < 32) {
            if (!escaping) {
                escaping = true;
                ret += QLatin1String("$$escape_expand(");
            }
            switch (uc) {
            case '\r':
                ret += QLatin1String("\\\\r");
                break;
            case '\n':
                ret += QLatin1String("\\\\n");
                break;
            case '\t':
                ret += QLatin1String("\\\\t");
                break;
            default:
                ret += QString::fromLatin1("\\\\x%1").arg(uc, 2, 16, QLatin1Char('0'));
                break;
            }
        } else {
            if (escaping) {
                escaping = false;
                ret += QLatin1Char(')');
            }
            switch (uc) {
            case '\\':
                ret += QLatin1String("\\\\");
                break;
            case '"':
                ret += QLatin1String("\\\"");
                break;
            case '\'':
                ret += QLatin1String("\\'");
                break;
            case '$':
                ret += QLatin1String("\\$");
                break;
            case '#':
                ret += QLatin1String("$${LITERAL_HASH}");
                break;
            case 32:
                quote = true;
                Q_FALLTHROUGH();
            default:
                ret += c;
                break;
            }
        }
    }
    if (escaping)
        ret += QLatin1Char(')');
    if (quote) {
        ret.prepend(QLatin1Char('"'));
        ret.append(QLatin1Char('"'));
    }
    return ret;
}

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProValueMap *map);

static void insertJsonKeyValue(const QString &key, const QStringList &values, ProValueMap *map)
{
    map->insert(ProKey(key), ProStringList(values));
}

static void addJsonArray(const QJsonArray &array, const QString &keyPrefix, ProValueMap *map)
{
    QStringList keys;
    const int size = array.count();
    keys.reserve(size);
    for (int i = 0; i < size; ++i) {
        const QString number = QString::number(i);
        keys.append(number);
        addJsonValue(array.at(i), keyPrefix + number, map);
    }
    insertJsonKeyValue(keyPrefix + QLatin1String("_KEYS_"), keys, map);
}

static void addJsonObject(const QJsonObject &object, const QString &keyPrefix, ProValueMap *map)
{
    QStringList keys;
    keys.reserve(object.size());
    for (auto it = object.begin(), end = object.end(); it != end; ++it) {
        const QString key = it.key();
        keys.append(key);
        addJsonValue(it.value(), keyPrefix + key, map);
    }
    insertJsonKeyValue(keyPrefix + QLatin1String("_KEYS_"), keys, map);
}

static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProValueMap *map)
{
    switch (value.type()) {
    case QJsonValue::Bool:
        insertJsonKeyValue(keyPrefix, QStringList() << (value.toBool() ? QLatin1String("true") : QLatin1String("false")), map);
        break;
    case QJsonValue::Double:
        insertJsonKeyValue(keyPrefix, QStringList() << QString::number(value.toDouble()), map);
        break;
    case QJsonValue::String:
        insertJsonKeyValue(keyPrefix, QStringList() << value.toString(), map);
        break;
    case QJsonValue::Array:
        addJsonArray(value.toArray(), keyPrefix + QLatin1Char('.'), map);
        break;
    case QJsonValue::Object:
        addJsonObject(value.toObject(), keyPrefix + QLatin1Char('.'), map);
        break;
    default:
        break;
    }
}

struct ErrorPosition {
    int line;
    int column;
};

static ErrorPosition calculateErrorPosition(const QByteArray &json, int offset)
{
    ErrorPosition pos = { 0, 0 };
    offset--; // offset is 1-based, switching to 0-based
    for (int i = 0; i < offset; ++i) {
        switch (json.at(i)) {
        case '\n':
            pos.line++;
            pos.column = 0;
            break;
        case '\r':
            break;
        case '\t':
            pos.column = (pos.column + 8) & ~7;
            break;
        default:
            pos.column++;
            break;
        }
    }
    // Lines and columns in text editors are 1-based:
    pos.line++;
    pos.column++;
    return pos;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::parseJsonInto(const QByteArray &json, const QString &into, ProValueMap *value)
{
    QJsonParseError error;
    QJsonDocument document = QJsonDocument::fromJson(json, &error);
    if (document.isNull()) {
        if (error.error != QJsonParseError::NoError) {
            ErrorPosition errorPos = calculateErrorPosition(json, error.offset);
            evalError(fL1S("Error parsing JSON at %1:%2: %3")
                      .arg(errorPos.line).arg(errorPos.column).arg(error.errorString()));
        }
        return QMakeEvaluator::ReturnFalse;
    }

    QString currentKey = into + QLatin1Char('.');

    // top-level item is either an array or object
    if (document.isArray())
        addJsonArray(document.array(), currentKey, value);
    else if (document.isObject())
        addJsonObject(document.object(), currentKey, value);
    else
        return QMakeEvaluator::ReturnFalse;

    return QMakeEvaluator::ReturnTrue;
}
#endif

QMakeEvaluator::VisitReturn
QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
                          QMakeVfs::VfsFlags flags, const QString &contents)
{
    int oldId = m_vfs->idForFileName(fn, flags | QMakeVfs::VfsAccessedOnly);
    int id = m_vfs->idForFileName(fn, flags | QMakeVfs::VfsCreate);
    QString errStr;
    if (!m_vfs->writeFile(id, mode, flags, contents, &errStr)) {
        evalError(fL1S("Cannot write %1file %2: %3")
                  .arg(ctx, QDir::toNativeSeparators(fn), errStr));
        return ReturnFalse;
    }
    if (oldId)
        m_parser->discardFileFromCache(oldId);
    return ReturnTrue;
}

#if QT_CONFIG(process)
void QMakeEvaluator::runProcess(QProcess *proc, const QString &command) const
{
    proc->setWorkingDirectory(currentDirectory());
# ifdef PROEVALUATOR_SETENV
    if (!m_option->environment.isEmpty())
        proc->setProcessEnvironment(m_option->environment);
# endif
# ifdef Q_OS_WIN
    proc->setNativeArguments(QLatin1String("/v:off /s /c \"") + command + QLatin1Char('"'));
    proc->start(m_option->getEnv(QLatin1String("COMSPEC")), QStringList());
# else
    proc->start(QLatin1String("/bin/sh"), QStringList() << QLatin1String("-c") << command);
# endif
    proc->waitForFinished(-1);
}
#endif

QByteArray QMakeEvaluator::getCommandOutput(const QString &args, int *exitCode) const
{
    QByteArray out;
#if QT_CONFIG(process)
    QProcess proc;
    runProcess(&proc, args);
    *exitCode = (proc.exitStatus() == QProcess::NormalExit) ? proc.exitCode() : -1;
    QByteArray errout = proc.readAllStandardError();
# ifdef PROEVALUATOR_FULL
    // FIXME: Qt really should have the option to set forwarding per channel
    fputs(errout.constData(), stderr);
# else
    if (!errout.isEmpty()) {
        if (errout.endsWith('\n'))
            errout.chop(1);
        m_handler->message(
            QMakeHandler::EvalError | (m_cumulative ? QMakeHandler::CumulativeEvalMessage : 0),
            QString::fromLocal8Bit(errout));
    }
# endif
    out = proc.readAllStandardOutput();
# ifdef Q_OS_WIN
    // FIXME: Qt's line end conversion on sequential files should really be fixed
    out.replace("\r\n", "\n");
# endif
#else
    if (FILE *proc = QT_POPEN(QString(QLatin1String("cd ")
                               + IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory()))
                               + QLatin1String(" && ") + args).toLocal8Bit().constData(), QT_POPEN_READ)) {
        while (!feof(proc)) {
            char buff[10 * 1024];
            int read_in = int(fread(buff, 1, sizeof(buff), proc));
            if (!read_in)
                break;
            out += QByteArray(buff, read_in);
        }
        int ec = QT_PCLOSE(proc);
# ifdef Q_OS_WIN
        *exitCode = ec >= 0 ? ec : -1;
# else
        *exitCode = WIFEXITED(ec) ? WEXITSTATUS(ec) : -1;
# endif
    }
# ifdef Q_OS_WIN
    out.replace("\r\n", "\n");
# endif
#endif
    return out;
}

void QMakeEvaluator::populateDeps(
        const ProStringList &deps, const ProString &prefix, const ProStringList &suffixes,
        const ProString &priosfx,
        QHash<ProKey, QSet<ProKey> > &dependencies, ProValueMap &dependees,
        QMultiMap<int, ProString> &rootSet) const
{
    for (const ProString &item : deps)
        if (!dependencies.contains(item.toKey())) {
            QSet<ProKey> &dset = dependencies[item.toKey()]; // Always create entry
            ProStringList depends;
            for (const ProString &suffix : suffixes)
                depends += values(ProKey(prefix + item + suffix));
            if (depends.isEmpty()) {
                rootSet.insert(first(ProKey(prefix + item + priosfx)).toInt(), item);
            } else {
                for (const ProString &dep : qAsConst(depends)) {
                    dset.insert(dep.toKey());
                    dependees[dep.toKey()] << item;
                }
                populateDeps(depends, prefix, suffixes, priosfx, dependencies, dependees, rootSet);
            }
        }
}

QString QMakeEvaluator::filePathArg0(const ProStringList &args)
{
    ProStringRoUser u1(args.at(0), m_tmp1);
    QString fn = resolvePath(u1.str());
    fn.detach();
    return fn;
}

QString QMakeEvaluator::filePathEnvArg0(const ProStringList &args)
{
    ProStringRoUser u1(args.at(0), m_tmp1);
    QString fn = resolvePath(m_option->expandEnvVars(u1.str()));
    fn.detach();
    return fn;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
        const QMakeBuiltin &adef, const ProKey &func, const ProStringList &args, ProStringList &ret)
{
    traceMsg("calling built-in $$%s(%s)", dbgKey(func), dbgSepStrList(args));
    int asz = args.size() > 1 ? args.size() : args.at(0).isEmpty() ? 0 : 1;
    if (asz < adef.minArgs || asz > adef.maxArgs) {
        evalError(adef.usage);
        return ReturnTrue;
    }

    int func_t = adef.index;
    switch (func_t) {
    case E_BASENAME:
    case E_DIRNAME:
    case E_SECTION: {
        bool regexp = false;
        QString sep;
        ProString var;
        int beg = 0;
        int end = -1;
        if (func_t == E_SECTION) {
            var = args[0];
            sep = args.at(1).toQString();
            beg = args.at(2).toInt();
            if (args.count() == 4)
                end = args.at(3).toInt();
        } else {
            var = args[0];
            regexp = true;
            sep = QLatin1String("[\\\\/]");
            if (func_t == E_DIRNAME)
                end = -2;
            else
                beg = -1;
        }
        if (!var.isEmpty()) {
            const auto strings = values(map(var));
            if (regexp) {
                QRegExp sepRx(sep);
                for (const ProString &str : strings) {
                    ProStringRwUser u1(str, m_tmp[m_toggle ^= 1]);
                    ret << u1.extract(u1.str().section(sepRx, beg, end));
                }
            } else {
                for (const ProString &str : strings) {
                    ProStringRwUser u1(str, m_tmp1);
                    ret << u1.extract(u1.str().section(sep, beg, end));
                }
            }
        }
        break;
    }
    case E_SPRINTF: {
        ProStringRwUser u1(args.at(0), m_tmp1);
        QString tmp = u1.str();
        for (int i = 1; i < args.count(); ++i)
            tmp = tmp.arg(args.at(i).toQStringView());
        ret << u1.extract(tmp);
        break;
    }
    case E_FORMAT_NUMBER: {
        int ibase = 10;
        int obase = 10;
        int width = 0;
        bool zeropad = false;
        bool leftalign = false;
        enum { DefaultSign, PadSign, AlwaysSign } sign = DefaultSign;
        if (args.count() >= 2) {
            const auto opts = split_value_list(args.at(1).toQStringRef());
            for (const ProString &opt : opts) {
                if (opt.startsWith(QLatin1String("ibase="))) {
                    ibase = opt.mid(6).toInt();
                } else if (opt.startsWith(QLatin1String("obase="))) {
                    obase = opt.mid(6).toInt();
                } else if (opt.startsWith(QLatin1String("width="))) {
                    width = opt.mid(6).toInt();
                } else if (opt == QLatin1String("zeropad")) {
                    zeropad = true;
                } else if (opt == QLatin1String("padsign")) {
                    sign = PadSign;
                } else if (opt == QLatin1String("alwayssign")) {
                    sign = AlwaysSign;
                } else if (opt == QLatin1String("leftalign")) {
                    leftalign = true;
                } else {
                    evalError(fL1S("format_number(): invalid format option %1.")
                              .arg(opt.toQStringView()));
                    goto allfail;
                }
            }
        }
        if (args.at(0).contains(QLatin1Char('.'))) {
            evalError(fL1S("format_number(): floats are currently not supported."));
            break;
        }
        bool ok;
        qlonglong num = args.at(0).toLongLong(&ok, ibase);
        if (!ok) {
            evalError(fL1S("format_number(): malformed number %2 for base %1.")
                      .arg(ibase).arg(args.at(0).toQStringView()));
            break;
        }
        QString outstr;
        if (num < 0) {
            num = -num;
            outstr = QLatin1Char('-');
        } else if (sign == AlwaysSign) {
            outstr = QLatin1Char('+');
        } else if (sign == PadSign) {
            outstr = QLatin1Char(' ');
        }
        QString numstr = QString::number(num, obase);
        int space = width - outstr.length() - numstr.length();
        if (space <= 0) {
            outstr += numstr;
        } else if (leftalign) {
            outstr += numstr + QString(space, QLatin1Char(' '));
        } else if (zeropad) {
            outstr += QString(space, QLatin1Char('0')) + numstr;
        } else {
            outstr.prepend(QString(space, QLatin1Char(' ')));
            outstr += numstr;
        }
        ret += ProString(outstr);
        break;
    }
    case E_NUM_ADD: {
        qlonglong sum = 0;
        for (const ProString &arg : qAsConst(args)) {
            if (arg.contains(QLatin1Char('.'))) {
                evalError(fL1S("num_add(): floats are currently not supported."));
                goto allfail;
            }
            bool ok;
            qlonglong num = arg.toLongLong(&ok);
            if (!ok) {
                evalError(fL1S("num_add(): malformed number %1.")
                          .arg(arg.toQStringView()));
                goto allfail;
            }
            sum += num;
        }
        ret += ProString(QString::number(sum));
        break;
    }
    case E_JOIN: {
        ProString glue, before, after;
        if (args.count() >= 2)
            glue = args.at(1);
        if (args.count() >= 3)
            before = args[2];
        if (args.count() == 4)
            after = args[3];
        const ProStringList &var = values(map(args.at(0)));
        if (!var.isEmpty()) {
            int src = currentFileId();
            for (const ProString &v : var)
                if (int s = v.sourceFile()) {
                    src = s;
                    break;
                }
            ret << ProString(before + var.join(glue) + after).setSource(src);
        }
        break;
    }
    case E_SPLIT: {
        ProStringRoUser u1(m_tmp1);
        const QString &sep = (args.count() == 2) ? u1.set(args.at(1)) : statics.field_sep;
        const auto vars = values(map(args.at(0)));
        for (const ProString &var : vars) {
            // FIXME: this is inconsistent with the "there are no empty strings" dogma.
            const auto splits = var.toQStringRef().split(sep, Qt::KeepEmptyParts);
            for (const auto &splt : splits)
                ret << ProString(splt).setSource(var);
        }
        break;
    }
    case E_MEMBER: {
        const ProStringList &src = values(map(args.at(0)));
        int start, end;
        if (getMemberArgs(func, src.size(), args, &start, &end)) {
            ret.reserve(qAbs(end - start) + 1);
            if (start < end) {
                for (int i = start; i <= end && src.size() >= i; i++)
                    ret += src.at(i);
            } else {
                for (int i = start; i >= end && src.size() >= i && i >= 0; i--)
                    ret += src.at(i);
            }
        }
        break;
    }
    case E_STR_MEMBER: {
        const ProString &src = args.at(0);
        int start, end;
        if (getMemberArgs(func, src.size(), args, &start, &end)) {
            QString res;
            res.reserve(qAbs(end - start) + 1);
            if (start < end) {
                for (int i = start; i <= end && src.size() >= i; i++)
                    res += src.at(i);
            } else {
                for (int i = start; i >= end && src.size() >= i && i >= 0; i--)
                    res += src.at(i);
            }
            ret += ProString(res);
        }
        break;
    }
    case E_FIRST:
    case E_LAST: {
        const ProStringList &var = values(map(args.at(0)));
        if (!var.isEmpty()) {
            if (func_t == E_FIRST)
                ret.append(var[0]);
            else
                ret.append(var.last());
        }
        break;
    }
    case E_TAKE_FIRST:
    case E_TAKE_LAST: {
        ProStringList &var = valuesRef(map(args.at(0)));
        if (!var.isEmpty()) {
            if (func_t == E_TAKE_FIRST)
                ret.append(var.takeFirst());
            else
                ret.append(var.takeLast());
        }
        break;
    }
    case E_SIZE:
        ret.append(ProString(QString::number(values(map(args.at(0))).size())));
        break;
    case E_STR_SIZE:
        ret.append(ProString(QString::number(args.at(0).size())));
        break;
    case E_CAT: {
        bool blob = false;
        bool lines = false;
        bool singleLine = true;
        if (args.count() > 1) {
            if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive))
                singleLine = false;
            else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive))
                blob = true;
            else if (!args.at(1).compare(QLatin1String("lines"), Qt::CaseInsensitive))
                lines = true;
        }
        QString fn = filePathEnvArg0(args);
        QFile qfile(fn);
        if (qfile.open(QIODevice::ReadOnly)) {
            QTextStream stream(&qfile);
            if (blob) {
                ret += ProString(stream.readAll());
            } else {
                while (!stream.atEnd()) {
                    if (lines) {
                        ret += ProString(stream.readLine());
                    } else {
                        const QString &line = stream.readLine();
                        ret += split_value_list(QStringRef(&line).trimmed());
                        if (!singleLine)
                            ret += ProString("\n");
                    }
                }
            }
        }
        break;
    }
    case E_FROMFILE: {
        ProValueMap vars;
        QString fn = filePathEnvArg0(args);
        if (evaluateFileInto(fn, &vars, LoadProOnly) == ReturnTrue)
            ret = vars.value(map(args.at(1)));
        break;
    }
    case E_EVAL:
        ret += values(map(args.at(0)));
        break;
    case E_LIST: {
        QString tmp(QString::asprintf(".QMAKE_INTERNAL_TMP_variableName_%d", m_listCount++));
        ret = ProStringList(ProString(tmp));
        ProStringList lst;
        for (const ProString &arg : args)
            lst += split_value_list(arg.toQStringRef(), arg.sourceFile()); // Relies on deep copy
        m_valuemapStack.top()[ret.at(0).toKey()] = lst;
        break; }
    case E_FIND: {
        QRegExp regx(args.at(1).toQString());
        const auto vals = values(map(args.at(0)));
        for (const ProString &val : vals) {
            ProStringRoUser u1(val, m_tmp[m_toggle ^= 1]);
            if (regx.indexIn(u1.str()) != -1)
                ret += val;
        }
        break;
    }
    case E_SYSTEM: {
        if (m_skipLevel)
            break;
        bool blob = false;
        bool lines = false;
        bool singleLine = true;
        if (args.count() > 1) {
            if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive))
                singleLine = false;
            else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive))
                blob = true;
            else if (!args.at(1).compare(QLatin1String("lines"), Qt::CaseInsensitive))
                lines = true;
        }
        int exitCode;
        QByteArray bytes = getCommandOutput(args.at(0).toQString(), &exitCode);
        if (args.count() > 2 && !args.at(2).isEmpty()) {
            m_valuemapStack.top()[args.at(2).toKey()] =
                    ProStringList(ProString(QString::number(exitCode)));
        }
        if (lines) {
            QTextStream stream(bytes);
            while (!stream.atEnd())
                ret += ProString(stream.readLine());
        } else {
            QString output = QString::fromLocal8Bit(bytes);
            if (blob) {
                ret += ProString(output);
            } else {
                output.replace(QLatin1Char('\t'), QLatin1Char(' '));
                if (singleLine)
                    output.replace(QLatin1Char('\n'), QLatin1Char(' '));
                ret += split_value_list(QStringRef(&output));
            }
        }
        break;
    }
    case E_UNIQUE:
        ret = values(map(args.at(0)));
        ret.removeDuplicates();
        break;
    case E_SORTED:
        ret = values(map(args.at(0)));
        std::sort(ret.begin(), ret.end());
        break;
    case E_REVERSE: {
        ProStringList var = values(args.at(0).toKey());
        for (int i = 0; i < var.size() / 2; i++)
            qSwap(var[i], var[var.size() - i - 1]);
        ret += var;
        break;
    }
    case E_QUOTE:
        ret += args;
        break;
    case E_ESCAPE_EXPAND:
        for (int i = 0; i < args.size(); ++i) {
            QString str = args.at(i).toQString();
            QChar *i_data = str.data();
            int i_len = str.length();
            for (int x = 0; x < i_len; ++x) {
                if (*(i_data+x) == QLatin1Char('\\') && x < i_len-1) {
                    if (*(i_data+x+1) == QLatin1Char('\\')) {
                        ++x;
                    } else {
                        struct {
                            char in, out;
                        } mapped_quotes[] = {
                            { 'n', '\n' },
                            { 't', '\t' },
                            { 'r', '\r' },
                            { 0, 0 }
                        };
                        for (int i = 0; mapped_quotes[i].in; ++i) {
                            if (*(i_data+x+1) == QLatin1Char(mapped_quotes[i].in)) {
                                *(i_data+x) = QLatin1Char(mapped_quotes[i].out);
                                if (x < i_len-2)
                                    memmove(i_data+x+1, i_data+x+2, (i_len-x-2)*sizeof(QChar));
                                --i_len;
                                break;
                            }
                        }
                    }
                }
            }
            ret.append(ProString(QString(i_data, i_len)).setSource(args.at(i)));
        }
        break;
    case E_RE_ESCAPE:
        for (int i = 0; i < args.size(); ++i) {
            ProStringRwUser u1(args.at(i), m_tmp1);
            ret << u1.extract(QRegExp::escape(u1.str()));
        }
        break;
    case E_VAL_ESCAPE: {
        const ProStringList &vals = values(args.at(0).toKey());
        ret.reserve(vals.size());
        for (const ProString &str : vals)
            ret += ProString(quoteValue(str));
        break;
    }
    case E_UPPER:
    case E_LOWER:
    case E_TITLE:
        for (int i = 0; i < args.count(); ++i) {
            ProStringRwUser u1(args.at(i), m_tmp1);
            QString rstr = u1.str();
            if (func_t == E_UPPER) {
                rstr = rstr.toUpper();
            } else {
                rstr = rstr.toLower();
                if (func_t == E_TITLE && rstr.length() > 0)
                    rstr[0] = rstr.at(0).toTitleCase();
            }
            ret << u1.extract(rstr);
        }
        break;
    case E_FILES: {
        bool recursive = false;
        if (args.count() == 2)
            recursive = isTrue(args.at(1));
        QStringList dirs;
        ProStringRoUser u1(args.at(0), m_tmp1);
        QString r = m_option->expandEnvVars(u1.str())
                    .replace(QLatin1Char('\\'), QLatin1Char('/'));
        QString pfx;
        if (IoUtils::isRelativePath(r)) {
            pfx = currentDirectory();
            if (!pfx.endsWith(QLatin1Char('/')))
                pfx += QLatin1Char('/');
        }
        int slash = r.lastIndexOf(QLatin1Char('/'));
        if (slash != -1) {
            dirs.append(r.left(slash+1));
            r = r.mid(slash+1);
        } else {
            dirs.append(QString());
        }

        r.detach(); // Keep m_tmp out of QRegExp's cache
        QRegExp regex(r, Qt::CaseSensitive, QRegExp::Wildcard);
        for (int d = 0; d < dirs.count(); d++) {
            QString dir = dirs[d];
            QDir qdir(pfx + dir);
            for (int i = 0, count = int(qdir.count()); i < count; ++i) {
                if (qdir[i] == statics.strDot || qdir[i] == statics.strDotDot)
                    continue;
                QString fname = dir + qdir[i];
                if (IoUtils::fileType(pfx + fname) == IoUtils::FileIsDir) {
                    if (recursive)
                        dirs.append(fname + QLatin1Char('/'));
                }
                if (regex.exactMatch(qdir[i]))
                      ret += ProString(fname).setSource(currentFileId());
            }
        }
        break;
    }
#ifdef PROEVALUATOR_FULL
    case E_PROMPT: {
        ProStringRoUser u1(args.at(0), m_tmp1);
        QString msg = m_option->expandEnvVars(u1.str());
        bool decorate = true;
        if (args.count() == 2)
            decorate = isTrue(args.at(1));
        if (decorate) {
            if (!msg.endsWith(QLatin1Char('?')))
                msg += QLatin1Char('?');
            fprintf(stderr, "Project PROMPT: %s ", qPrintable(msg));
        } else {
            fputs(qPrintable(msg), stderr);
        }
        QFile qfile;
        if (qfile.open(stdin, QIODevice::ReadOnly)) {
            QTextStream t(&qfile);
            const QString &line = t.readLine();
            if (t.atEnd()) {
                fputs("\n", stderr);
                evalError(fL1S("Unexpected EOF."));
                return ReturnError;
            }
            ret = split_value_list(QStringRef(&line));
        }
        break;
    }
#endif
    case E_REPLACE: {
        const QRegExp before(args.at(1).toQString());
        ProStringRwUser u2(args.at(2), m_tmp2);
        const QString &after = u2.str();
        const auto vals = values(map(args.at(0)));
        for (const ProString &val : vals) {
            ProStringRwUser u1(val, m_tmp1);
            QString rstr = u1.str();
            QString copy = rstr; // Force a detach on modify
            rstr.replace(before, after);
            ret << u1.extract(rstr, u2);
        }
        break;
    }
    case E_SORT_DEPENDS:
    case E_RESOLVE_DEPENDS: {
        QHash<ProKey, QSet<ProKey> > dependencies;
        ProValueMap dependees;
        QMultiMap<int, ProString> rootSet;
        ProStringList orgList = values(args.at(0).toKey());
        ProString prefix = args.count() < 2 ? ProString() : args.at(1);
        ProString priosfx = args.count() < 4 ? ProString(".priority") : args.at(3);
        populateDeps(orgList, prefix,
                     args.count() < 3 ? ProStringList(ProString(".depends"))
                                      : split_value_list(args.at(2).toQStringRef()),
                     priosfx, dependencies, dependees, rootSet);
        while (!rootSet.isEmpty()) {
            QMultiMap<int, ProString>::iterator it = rootSet.begin();
            const ProString item = *it;
            rootSet.erase(it);
            if ((func_t == E_RESOLVE_DEPENDS) || orgList.contains(item))
                ret.prepend(item);
            for (const ProString &dep : qAsConst(dependees[item.toKey()])) {
                QSet<ProKey> &dset = dependencies[dep.toKey()];
                dset.remove(item.toKey());
                if (dset.isEmpty())
                    rootSet.insert(first(ProKey(prefix + dep + priosfx)).toInt(), dep);
            }
        }
        break;
    }
    case E_ENUMERATE_VARS: {
        QSet<ProString> keys;
        for (const ProValueMap &vmap : qAsConst(m_valuemapStack))
            for (ProValueMap::ConstIterator it = vmap.constBegin(); it != vmap.constEnd(); ++it)
                keys.insert(it.key());
        ret.reserve(keys.size());
        for (const ProString &key : qAsConst(keys))
            ret << key;
        break; }
    case E_SHADOWED: {
        ProStringRwUser u1(args.at(0), m_tmp1);
        QString rstr = m_option->shadowedPath(resolvePath(u1.str()));
        if (!rstr.isEmpty())
            ret << u1.extract(rstr);
        break;
    }
    case E_ABSOLUTE_PATH: {
        ProStringRwUser u1(args.at(0), m_tmp1);
        ProStringRwUser u2(m_tmp2);
        QString baseDir = args.count() > 1
                ? IoUtils::resolvePath(currentDirectory(), u2.set(args.at(1)))
                : currentDirectory();
        QString rstr = u1.str().isEmpty() ? baseDir : IoUtils::resolvePath(baseDir, u1.str());
        ret << u1.extract(rstr, u2);
        break;
    }
    case E_RELATIVE_PATH: {
        ProStringRwUser u1(args.at(0), m_tmp1);
        ProStringRoUser u2(m_tmp2);
        QString baseDir = args.count() > 1
                ? IoUtils::resolvePath(currentDirectory(), u2.set(args.at(1)))
                : currentDirectory();
        QString absArg = u1.str().isEmpty() ? baseDir : IoUtils::resolvePath(baseDir, u1.str());
        QString rstr = QDir(baseDir).relativeFilePath(absArg);
        ret << u1.extract(rstr);
        break;
    }
    case E_CLEAN_PATH: {
        ProStringRwUser u1(args.at(0), m_tmp1);
        ret << u1.extract(QDir::cleanPath(u1.str()));
        break;
    }
    case E_SYSTEM_PATH: {
        ProStringRwUser u1(args.at(0), m_tmp1);
        QString rstr = u1.str();
#ifdef Q_OS_WIN
        rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
#else
        rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
#endif
        ret << u1.extract(rstr);
        break;
    }
    case E_SHELL_PATH: {
        ProStringRwUser u1(args.at(0), m_tmp1);
        QString rstr = u1.str();
        if (m_dirSep.startsWith(QLatin1Char('\\'))) {
            rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
        } else {
            rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
#ifdef Q_OS_WIN
            // Convert d:/foo/bar to msys-style /d/foo/bar.
            if (rstr.length() > 2 && rstr.at(1) == QLatin1Char(':') && rstr.at(2) == QLatin1Char('/')) {
                rstr[1] = rstr.at(0);
                rstr[0] = QLatin1Char('/');
            }
#endif
        }
        ret << u1.extract(rstr);
        break;
    }
    case E_SYSTEM_QUOTE: {
        ProStringRwUser u1(args.at(0), m_tmp1);
        ret << u1.extract(IoUtils::shellQuote(u1.str()));
        break;
    }
    case E_SHELL_QUOTE: {
        ProStringRwUser u1(args.at(0), m_tmp1);
        QString rstr = u1.str();
        if (m_dirSep.startsWith(QLatin1Char('\\')))
            rstr = IoUtils::shellQuoteWin(rstr);
        else
            rstr = IoUtils::shellQuoteUnix(rstr);
        ret << u1.extract(rstr);
        break;
    }
    case E_GETENV: {
        ProStringRoUser u1(args.at(0), m_tmp1);
        ret << ProString(m_option->getEnv(u1.str()));
        break;
    }
#ifdef Q_OS_WIN
    case E_READ_REGISTRY: {
        HKEY tree;
        const auto par = args.at(0);
        if (!par.compare(QLatin1String("HKCU"), Qt::CaseInsensitive)
                || !par.compare(QLatin1String("HKEY_CURRENT_USER"), Qt::CaseInsensitive)) {
            tree = HKEY_CURRENT_USER;
        } else if (!par.compare(QLatin1String("HKLM"), Qt::CaseInsensitive)
                || !par.compare(QLatin1String("HKEY_LOCAL_MACHINE"), Qt::CaseInsensitive)) {
            tree = HKEY_LOCAL_MACHINE;
        } else {
            evalError(fL1S("read_registry(): invalid or unsupported registry tree %1.")
                      .arg(par.toQStringView()));
            goto allfail;
        }
        int flags = 0;
        if (args.count() > 2) {
            const auto opt = args.at(2);
            if (opt == "32"
                    || !opt.compare(QLatin1String("wow64_32key"), Qt::CaseInsensitive)) {
                flags = KEY_WOW64_32KEY;
            } else if (opt == "64"
                    || !opt.compare(QLatin1String("wow64_64key"), Qt::CaseInsensitive)) {
                flags = KEY_WOW64_64KEY;
            } else {
                evalError(fL1S("read_registry(): invalid option %1.")
                          .arg(opt.toQStringView()));
                goto allfail;
            }
        }
        ret << ProString(qt_readRegistryKey(tree, args.at(1).toQString(m_tmp1), flags));
        break;
    }
#endif
    default:
        evalError(fL1S("Function '%1' is not implemented.").arg(func.toQStringView()));
        break;
    }

  allfail:
    return ReturnTrue;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::testFunc_cache(const ProStringList &args)
{
    bool persist = true;
    enum { TargetStash, TargetCache, TargetSuper } target = TargetCache;
    enum { CacheSet, CacheAdd, CacheSub } mode = CacheSet;
    ProKey srcvar;
    if (args.count() >= 2) {
        const auto opts = split_value_list(args.at(1).toQStringRef());
        for (const ProString &opt : opts) {
            if (opt == QLatin1String("transient")) {
                persist = false;
            } else if (opt == QLatin1String("super")) {
                target = TargetSuper;
            } else if (opt == QLatin1String("stash")) {
                target = TargetStash;
            } else if (opt == QLatin1String("set")) {
                mode = CacheSet;
            } else if (opt == QLatin1String("add")) {
                mode = CacheAdd;
            } else if (opt == QLatin1String("sub")) {
                mode = CacheSub;
            } else {
                evalError(fL1S("cache(): invalid flag %1.").arg(opt.toQStringView()));
                return ReturnFalse;
            }
        }
        if (args.count() >= 3) {
            srcvar = args.at(2).toKey();
        } else if (mode != CacheSet) {
            evalError(fL1S("cache(): modes other than 'set' require a source variable."));
            return ReturnFalse;
        }
    }
    QString varstr;
    ProKey dstvar = args.at(0).toKey();
    if (!dstvar.isEmpty()) {
        if (srcvar.isEmpty())
            srcvar = dstvar;
        ProValueMap::Iterator srcvarIt;
        if (!findValues(srcvar, &srcvarIt)) {
            evalError(fL1S("Variable %1 is not defined.").arg(srcvar.toQStringView()));
            return ReturnFalse;
        }
        // The caches for the host and target may differ (e.g., when we are manipulating
        // CONFIG), so we cannot compute a common new value for both.
        const ProStringList &diffval = *srcvarIt;
        ProStringList newval;
        bool changed = false;
        for (bool hostBuild = false; ; hostBuild = true) {
#ifdef PROEVALUATOR_THREAD_SAFE
            m_option->mutex.lock();
#endif
            QMakeBaseEnv *baseEnv =
                m_option->baseEnvs.value(QMakeBaseKey(m_buildRoot, m_stashfile, hostBuild));
#ifdef PROEVALUATOR_THREAD_SAFE
            // It's ok to unlock this before locking baseEnv,
            // as we have no intention to initialize the env.
            m_option->mutex.unlock();
#endif
            do {
                if (!baseEnv)
                    break;
#ifdef PROEVALUATOR_THREAD_SAFE
                QMutexLocker locker(&baseEnv->mutex);
                if (baseEnv->inProgress && baseEnv->evaluator != this) {
                    // The env is still in the works, but it may be already past the cache
                    // loading. So we need to wait for completion and amend it as usual.
                    QThreadPool::globalInstance()->releaseThread();
                    baseEnv->cond.wait(&baseEnv->mutex);
                    QThreadPool::globalInstance()->reserveThread();
                }
                if (!baseEnv->isOk)
                    break;
#endif
                QMakeEvaluator *baseEval = baseEnv->evaluator;
                const ProStringList &oldval = baseEval->values(dstvar);
                if (mode == CacheSet) {
                    newval = diffval;
                } else {
                    newval = oldval;
                    if (mode == CacheAdd)
                        newval += diffval;
                    else
                        newval.removeEach(diffval);
                }
                if (oldval != newval) {
                    if (target != TargetStash || !m_stashfile.isEmpty()) {
                        baseEval->valuesRef(dstvar) = newval;
                        if (target == TargetSuper) {
                            do {
                                if (dstvar == QLatin1String("QMAKEPATH")) {
                                    baseEval->m_qmakepath = newval.toQStringList();
                                    baseEval->updateMkspecPaths();
                                } else if (dstvar == QLatin1String("QMAKEFEATURES")) {
                                    baseEval->m_qmakefeatures = newval.toQStringList();
                                } else {
                                    break;
                                }
                                baseEval->updateFeaturePaths();
                                if (hostBuild == m_hostBuild)
                                    m_featureRoots = baseEval->m_featureRoots;
                            } while (false);
                        }
                    }
                    changed = true;
                }
            } while (false);
            if (hostBuild)
                break;
        }
        // We assume that whatever got the cached value to be what it is now will do so
        // the next time as well, so we just skip the persisting if nothing changed.
        if (!persist || !changed)
            return ReturnTrue;
        varstr = dstvar.toQString();
        if (mode == CacheAdd)
            varstr += QLatin1String(" +=");
        else if (mode == CacheSub)
            varstr += QLatin1String(" -=");
        else
            varstr += QLatin1String(" =");
        if (diffval.count() == 1) {
            varstr += QLatin1Char(' ');
            varstr += quoteValue(diffval.at(0));
        } else if (!diffval.isEmpty()) {
            for (const ProString &vval : diffval) {
                varstr += QLatin1String(" \\\n    ");
                varstr += quoteValue(vval);
            }
        }
        varstr += QLatin1Char('\n');
    }
    QString fn;
    QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
    if (target == TargetSuper) {
        if (m_superfile.isEmpty()) {
            m_superfile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.super"));
            printf("Info: creating super cache file %s\n", qPrintable(QDir::toNativeSeparators(m_superfile)));
            valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
        }
        fn = m_superfile;
    } else if (target == TargetCache) {
        if (m_cachefile.isEmpty()) {
            m_cachefile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.cache"));
            printf("Info: creating cache file %s\n", qPrintable(QDir::toNativeSeparators(m_cachefile)));
            valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile);
            // We could update m_{source,build}Root and m_featureRoots here, or even
            // "re-home" our rootEnv, but this doesn't sound too useful - if somebody
            // wanted qmake to find something in the build directory, he could have
            // done so "from the outside".
            // The sub-projects will find the new cache all by themselves.
        }
        fn = m_cachefile;
    } else {
        fn = m_stashfile;
        if (fn.isEmpty())
            fn = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.stash"));
        if (!m_vfs->exists(fn, flags)) {
            printf("Info: creating stash file %s\n", qPrintable(QDir::toNativeSeparators(fn)));
            valuesRef(ProKey("_QMAKE_STASH_")) << ProString(fn);
        }
    }
    return writeFile(fL1S("cache "), fn, QIODevice::Append, flags, varstr);
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
        const QMakeInternal::QMakeBuiltin &adef, const ProKey &function, const ProStringList &args)
{
    traceMsg("calling built-in %s(%s)", dbgKey(function), dbgSepStrList(args));
    int asz = args.size() > 1 ? args.size() : args.at(0).isEmpty() ? 0 : 1;
    if (asz < adef.minArgs || asz > adef.maxArgs) {
        evalError(adef.usage);
        return ReturnFalse;
    }

    int func_t = adef.index;
    switch (func_t) {
    case T_DEFINED: {
        const ProKey &var = args.at(0).toKey();
        if (args.count() > 1) {
            if (args[1] == QLatin1String("test")) {
                return returnBool(m_functionDefs.testFunctions.contains(var));
            } else if (args[1] == QLatin1String("replace")) {
                return returnBool(m_functionDefs.replaceFunctions.contains(var));
            } else if (args[1] == QLatin1String("var")) {
                ProValueMap::Iterator it;
                return returnBool(findValues(var, &it));
            }
            evalError(fL1S("defined(function, type): unexpected type [%1].")
                      .arg(args.at(1).toQStringView()));
            return ReturnFalse;
        }
        return returnBool(m_functionDefs.replaceFunctions.contains(var)
                          || m_functionDefs.testFunctions.contains(var));
    }
    case T_EXPORT: {
        const ProKey &var = map(args.at(0));
        for (ProValueMapStack::iterator vmi = m_valuemapStack.end();
             --vmi != m_valuemapStack.begin(); ) {
            ProValueMap::Iterator it = (*vmi).find(var);
            if (it != (*vmi).end()) {
                if (it->constBegin() == statics.fakeValue.constBegin()) {
                    // This is stupid, but qmake doesn't propagate deletions
                    m_valuemapStack.front()[var] = ProStringList();
                } else {
                    m_valuemapStack.front()[var] = *it;
                }
                (*vmi).erase(it);
                while (--vmi != m_valuemapStack.begin())
                    (*vmi).remove(var);
                break;
            }
        }
        return ReturnTrue;
    }
    case T_DISCARD_FROM: {
        if (m_valuemapStack.size() != 1) {
            evalError(fL1S("discard_from() cannot be called from functions."));
            return ReturnFalse;
        }
        ProStringRoUser u1(args.at(0), m_tmp1);
        QString fn = resolvePath(u1.str());
        QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
        int pro = m_vfs->idForFileName(fn, flags | QMakeVfs::VfsAccessedOnly);
        if (!pro)
            return ReturnFalse;
        ProValueMap &vmap = m_valuemapStack.front();
        for (auto vit = vmap.begin(); vit != vmap.end(); ) {
            if (!vit->isEmpty()) {
                auto isFrom = [pro](const ProString &s) {
                    return s.sourceFile() == pro;
                };
                vit->erase(std::remove_if(vit->begin(), vit->end(), isFrom), vit->end());
                if (vit->isEmpty()) {
                    // When an initially non-empty variable becomes entirely empty,
                    // undefine it altogether.
                    vit = vmap.erase(vit);
                    continue;
                }
            }
            ++vit;
        }
        for (auto fit = m_functionDefs.testFunctions.begin(); fit != m_functionDefs.testFunctions.end(); ) {
            if (fit->pro()->id() == pro)
                fit = m_functionDefs.testFunctions.erase(fit);
            else
                ++fit;
        }
        for (auto fit = m_functionDefs.replaceFunctions.begin(); fit != m_functionDefs.replaceFunctions.end(); ) {
            if (fit->pro()->id() == pro)
                fit = m_functionDefs.replaceFunctions.erase(fit);
            else
                ++fit;
        }
        ProStringList &iif = m_valuemapStack.front()[ProKey("QMAKE_INTERNAL_INCLUDED_FILES")];
        int idx = iif.indexOf(ProString(fn));
        if (idx >= 0)
            iif.removeAt(idx);
        return ReturnTrue;
    }
    case T_INFILE: {
        ProValueMap vars;
        QString fn = filePathEnvArg0(args);
        VisitReturn ok = evaluateFileInto(fn, &vars, LoadProOnly);
        if (ok != ReturnTrue)
            return ok;
        if (args.count() == 2)
            return returnBool(vars.contains(map(args.at(1))));
        QRegExp regx;
        ProStringRoUser u1(args.at(2), m_tmp1);
        const QString &qry = u1.str();
        if (qry != QRegExp::escape(qry)) {
            QString copy = qry;
            copy.detach();
            regx.setPattern(copy);
        }
        const auto strings = vars.value(map(args.at(1)));
        for (const ProString &s : strings) {
            if (s == qry)
                return ReturnTrue;
            if (!regx.isEmpty()) {
                ProStringRoUser u2(s, m_tmp[m_toggle ^= 1]);
                if (regx.exactMatch(u2.str()))
                    return ReturnTrue;
            }
        }
        return ReturnFalse;
    }
    case T_REQUIRES:
#ifdef PROEVALUATOR_FULL
        if (checkRequirements(args) == ReturnError)
            return ReturnError;
#endif
        return ReturnFalse; // Another qmake breakage
    case T_EVAL: {
        VisitReturn ret = ReturnFalse;
        QString contents = args.join(statics.field_sep);
        ProFile *pro = m_parser->parsedProBlock(QStringRef(&contents),
                                                0, m_current.pro->fileName(), m_current.line);
        if (m_cumulative || pro->isOk()) {
            m_locationStack.push(m_current);
            visitProBlock(pro, pro->tokPtr());
            ret = ReturnTrue; // This return value is not too useful, but that's qmake
            m_current = m_locationStack.pop();
        }
        pro->deref();
        return ret;
    }
    case T_IF: {
        return evaluateConditional(args.at(0).toQStringRef(),
                                   m_current.pro->fileName(), m_current.line);
    }
    case T_CONFIG: {
        if (args.count() == 1)
            return returnBool(isActiveConfig(args.at(0).toQStringRef()));
        const auto mutuals = args.at(1).toQStringRef().split(QLatin1Char('|'),
                                                             Qt::SkipEmptyParts);
        const ProStringList &configs = values(statics.strCONFIG);

        for (int i = configs.size() - 1; i >= 0; i--) {
            for (int mut = 0; mut < mutuals.count(); mut++) {
                if (configs[i].toQStringRef() == mutuals[mut].trimmed())
                    return returnBool(configs[i] == args[0]);
            }
        }
        return ReturnFalse;
    }
    case T_CONTAINS: {
        ProStringRoUser u1(args.at(1), m_tmp1);
        const QString &qry = u1.str();
        QRegExp regx;
        if (qry != QRegExp::escape(qry)) {
            QString copy = qry;
            copy.detach();
            regx.setPattern(copy);
        }
        const ProStringList &l = values(map(args.at(0)));
        if (args.count() == 2) {
            for (int i = 0; i < l.size(); ++i) {
                const ProString &val = l[i];
                if (val == qry)
                    return ReturnTrue;
                if (!regx.isEmpty()) {
                    ProStringRoUser u2(val, m_tmp[m_toggle ^= 1]);
                    if (regx.exactMatch(u2.str()))
                        return ReturnTrue;
                }
            }
        } else {
            const auto mutuals = args.at(2).toQStringRef().split(QLatin1Char('|'),
                                                                 Qt::SkipEmptyParts);
            for (int i = l.size() - 1; i >= 0; i--) {
                const ProString &val = l[i];
                for (int mut = 0; mut < mutuals.count(); mut++) {
                    if (val.toQStringRef() == mutuals[mut].trimmed()) {
                        if (val == qry)
                            return ReturnTrue;
                        if (!regx.isEmpty()) {
                            ProStringRoUser u2(val, m_tmp[m_toggle ^= 1]);
                            if (regx.exactMatch(u2.str()))
                                return ReturnTrue;
                        }
                        return ReturnFalse;
                    }
                }
            }
        }
        return ReturnFalse;
    }
    case T_COUNT: {
        int cnt = values(map(args.at(0))).count();
        int val = args.at(1).toInt();
        if (args.count() == 3) {
            const ProString &comp = args.at(2);
            if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) {
                return returnBool(cnt > val);
            } else if (comp == QLatin1String(">=")) {
                return returnBool(cnt >= val);
            } else if (comp == QLatin1String("<") || comp == QLatin1String("lessThan")) {
                return returnBool(cnt < val);
            } else if (comp == QLatin1String("<=")) {
                return returnBool(cnt <= val);
            } else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual")
                       || comp == QLatin1String("=") || comp == QLatin1String("==")) {
                // fallthrough
            } else {
                evalError(fL1S("Unexpected modifier to count(%2).").arg(comp.toQStringView()));
                return ReturnFalse;
            }
        }
        return returnBool(cnt == val);
    }
    case T_GREATERTHAN:
    case T_LESSTHAN: {
        const ProString &rhs = args.at(1);
        const QString &lhs = values(map(args.at(0))).join(statics.field_sep);
        bool ok;
        int rhs_int = rhs.toInt(&ok);
        if (ok) { // do integer compare
            int lhs_int = lhs.toInt(&ok);
            if (ok) {
                if (func_t == T_GREATERTHAN)
                    return returnBool(lhs_int > rhs_int);
                return returnBool(lhs_int < rhs_int);
            }
        }
        if (func_t == T_GREATERTHAN)
            return returnBool(lhs > rhs.toQStringRef());
        return returnBool(lhs < rhs.toQStringRef());
    }
    case T_EQUALS:
        return returnBool(values(map(args.at(0))).join(statics.field_sep)
                          == args.at(1).toQStringView());
    case T_VERSION_AT_LEAST:
    case T_VERSION_AT_MOST: {
        const QVersionNumber lvn = QVersionNumber::fromString(values(args.at(0).toKey()).join('.'));
        const QVersionNumber rvn = QVersionNumber::fromString(args.at(1).toQStringView());
        if (func_t == T_VERSION_AT_LEAST)
            return returnBool(lvn >= rvn);
        return returnBool(lvn <= rvn);
    }
    case T_CLEAR: {
        ProValueMap *hsh;
        ProValueMap::Iterator it;
        const ProKey &var = map(args.at(0));
        if (!(hsh = findValues(var, &it)))
            return ReturnFalse;
        if (hsh == &m_valuemapStack.top())
            it->clear();
        else
            m_valuemapStack.top()[var].clear();
        return ReturnTrue;
    }
    case T_UNSET: {
        ProValueMap *hsh;
        ProValueMap::Iterator it;
        const ProKey &var = map(args.at(0));
        if (!(hsh = findValues(var, &it)))
            return ReturnFalse;
        if (m_valuemapStack.size() == 1)
            hsh->erase(it);
        else if (hsh == &m_valuemapStack.top())
            *it = statics.fakeValue;
        else
            m_valuemapStack.top()[var] = statics.fakeValue;
        return ReturnTrue;
    }
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
    case T_PARSE_JSON: {
        QByteArray json = values(args.at(0).toKey()).join(QLatin1Char(' ')).toUtf8();
        ProStringRoUser u1(args.at(1), m_tmp2);
        QString parseInto = u1.str();
        return parseJsonInto(json, parseInto, &m_valuemapStack.top());
    }
#endif
    case T_INCLUDE: {
        QString parseInto;
        LoadFlags flags;
        if (m_cumulative)
            flags = LoadSilent;
        if (args.count() >= 2) {
            if (!args.at(1).isEmpty())
                parseInto = args.at(1) + QLatin1Char('.');
            if (args.count() >= 3 && isTrue(args.at(2)))
                flags = LoadSilent;
        }
        QString fn = filePathEnvArg0(args);
        VisitReturn ok;
        if (parseInto.isEmpty()) {
            ok = evaluateFileChecked(fn, QMakeHandler::EvalIncludeFile, LoadProOnly | flags);
        } else {
            ProValueMap symbols;
            if ((ok = evaluateFileInto(fn, &symbols, LoadAll | flags)) == ReturnTrue) {
                ProValueMap newMap;
                for (ProValueMap::ConstIterator
                        it = m_valuemapStack.top().constBegin(),
                        end = m_valuemapStack.top().constEnd();
                        it != end; ++it) {
                    const ProString &ky = it.key();
                    if (!ky.startsWith(parseInto))
                        newMap[it.key()] = it.value();
                }
                for (ProValueMap::ConstIterator it = symbols.constBegin();
                     it != symbols.constEnd(); ++it) {
                    if (!it.key().startsWith(QLatin1Char('.')))
                        newMap.insert(ProKey(parseInto + it.key()), it.value());
                }
                m_valuemapStack.top() = newMap;
            }
        }
        if (ok == ReturnFalse && (flags & LoadSilent))
            ok = ReturnTrue;
        return ok;
    }
    case T_LOAD: {
        bool ignore_error = (args.count() == 2 && isTrue(args.at(1)));
        VisitReturn ok = evaluateFeatureFile(m_option->expandEnvVars(args.at(0).toQString()),
                                             ignore_error);
        if (ok == ReturnFalse && ignore_error)
            ok = ReturnTrue;
        return ok;
    }
    case T_DEBUG: {
#ifdef PROEVALUATOR_DEBUG
        int level = args.at(0).toInt();
        if (level <= m_debugLevel) {
            ProStringRoUser u1(args.at(1), m_tmp1);
            const QString &msg = m_option->expandEnvVars(u1.str());
            debugMsg(level, "Project DEBUG: %s", qPrintable(msg));
        }
#endif
        return ReturnTrue;
    }
    case T_LOG:
    case T_ERROR:
    case T_WARNING:
    case T_MESSAGE: {
        ProStringRoUser u1(args.at(0), m_tmp1);
        const QString &msg = m_option->expandEnvVars(u1.str());
        if (!m_skipLevel) {
            if (func_t == T_LOG) {
#ifdef PROEVALUATOR_FULL
                fputs(msg.toLatin1().constData(), stderr);
#endif
            } else if (!msg.isEmpty() || func_t != T_ERROR) {
                ProStringRoUser u2(function, m_tmp2);
                m_handler->fileMessage(
                        (func_t == T_ERROR   ? QMakeHandler::ErrorMessage :
                         func_t == T_WARNING ? QMakeHandler::WarningMessage :
                                               QMakeHandler::InfoMessage)
                        | (m_cumulative ? QMakeHandler::CumulativeEvalMessage : 0),
                        fL1S("Project %1: %2").arg(u2.str().toUpper(), msg));
            }
        }
        return (func_t == T_ERROR && !m_cumulative) ? ReturnError : ReturnTrue;
    }
    case T_SYSTEM: {
#ifdef PROEVALUATOR_FULL
        if (m_cumulative) // Anything else would be insanity
            return ReturnFalse;
#if QT_CONFIG(process)
        QProcess proc;
        proc.setProcessChannelMode(QProcess::ForwardedChannels);
        runProcess(&proc, args.at(0).toQString());
        return returnBool(proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0);
#else
        int ec = system((QLatin1String("cd ")
                         + IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory()))
                         + QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData());
#  ifdef Q_OS_UNIX
        if (ec != -1 && WIFSIGNALED(ec) && (WTERMSIG(ec) == SIGQUIT || WTERMSIG(ec) == SIGINT))
            raise(WTERMSIG(ec));
#  endif
        return returnBool(ec == 0);
#endif
#else
        return ReturnTrue;
#endif
    }
    case T_ISEMPTY: {
        return returnBool(values(map(args.at(0))).isEmpty());
    }
    case T_EXISTS: {
        QString file = filePathEnvArg0(args);
        // Don't use VFS here:
        // - it supports neither listing nor even directories
        // - it's unlikely that somebody would test for files they created themselves
        if (IoUtils::exists(file))
            return ReturnTrue;
        int slsh = file.lastIndexOf(QLatin1Char('/'));
        QString fn = file.mid(slsh+1);
        if (fn.contains(QLatin1Char('*')) || fn.contains(QLatin1Char('?'))) {
            QString dirstr = file.left(slsh+1);
            dirstr.detach();
            if (!QDir(dirstr).entryList(QStringList(fn)).isEmpty())
                return ReturnTrue;
        }

        return ReturnFalse;
    }
    case T_MKPATH: {
#ifdef PROEVALUATOR_FULL
        QString fn = filePathArg0(args);
        if (!QDir::current().mkpath(fn)) {
            evalError(fL1S("Cannot create directory %1.").arg(QDir::toNativeSeparators(fn)));
            return ReturnFalse;
        }
#endif
        return ReturnTrue;
    }
    case T_WRITE_FILE: {
        QIODevice::OpenMode mode = QIODevice::Truncate;
        QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
        QString contents;
        if (args.count() >= 2) {
            const ProStringList &vals = values(args.at(1).toKey());
            if (!vals.isEmpty())
                contents = vals.join(QLatin1Char('\n')) + QLatin1Char('\n');
            if (args.count() >= 3) {
                const auto opts = split_value_list(args.at(2).toQStringRef());
                for (const ProString &opt : opts) {
                    if (opt == QLatin1String("append")) {
                        mode = QIODevice::Append;
                    } else if (opt == QLatin1String("exe")) {
                        flags |= QMakeVfs::VfsExecutable;
                    } else {
                        evalError(fL1S("write_file(): invalid flag %1.").arg(opt.toQStringView()));
                        return ReturnFalse;
                    }
                }
            }
        }
        QString path = filePathArg0(args);
        return writeFile(QString(), path, mode, flags, contents);
    }
    case T_TOUCH: {
#ifdef PROEVALUATOR_FULL
        ProStringRoUser u1(args.at(0), m_tmp1);
        ProStringRoUser u2(args.at(1), m_tmp2);
        const QString &tfn = resolvePath(u1.str());
        const QString &rfn = resolvePath(u2.str());
        QString error;
        if (!IoUtils::touchFile(tfn, rfn, &error)) {
            evalError(error);
            return ReturnFalse;
        }
#endif
        return ReturnTrue;
    }
    case T_CACHE:
        return testFunc_cache(args);
    case T_RELOAD_PROPERTIES:
#ifdef QT_BUILD_QMAKE
        m_option->reloadProperties();
#endif
        return ReturnTrue;
    default:
        evalError(fL1S("Function '%1' is not implemented.").arg(function.toQStringView()));
        return ReturnFalse;
    }
}

QT_END_NAMESPACE
