/****************************************************************************
**
** 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 <qdatetime.h>
#include <qdebug.h>
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qlist.h>
#include <qregexp.h>
#include <qset.h>
#include <qstack.h>
#include <qstring.h>
#include <qstringlist.h>
#ifdef PROEVALUATOR_THREAD_SAFE
# include <qthreadpool.h>
#endif

#ifdef Q_OS_UNIX
#include <unistd.h>
#include <sys/utsname.h>
#  ifdef Q_OS_BSD4
#    include <sys/sysctl.h>
#  endif
#else
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>

using namespace QMakeInternal;

QT_BEGIN_NAMESPACE

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

// we can't use QThread in qmake
// this function is a merger of QThread::idealThreadCount from qthread_win.cpp and qthread_unix.cpp
static int idealThreadCount()
{
#ifdef PROEVALUATOR_THREAD_SAFE
    return QThread::idealThreadCount();
#elif defined(Q_OS_WIN)
    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo);
    return sysinfo.dwNumberOfProcessors;
#else
    // there are a couple more definitions in the Unix QThread::idealThreadCount, but
    // we don't need them all here
    int cores = 1;
#  if defined(Q_OS_BSD4)
    // FreeBSD, OpenBSD, NetBSD, BSD/OS, OS X
    size_t len = sizeof(cores);
    int mib[2];
    mib[0] = CTL_HW;
    mib[1] = HW_NCPU;
    if (sysctl(mib, 2, &cores, &len, NULL, 0) != 0) {
        perror("sysctl");
    }
#  elif defined(_SC_NPROCESSORS_ONLN)
    // the rest: Linux, Solaris, AIX, Tru64
    cores = (int)sysconf(_SC_NPROCESSORS_ONLN);
    if (cores == -1)
        return 1;
#  endif
    return cores;
#endif
}


QMakeBaseKey::QMakeBaseKey(const QString &_root, const QString &_stash, bool _hostBuild)
    : root(_root), stash(_stash), hostBuild(_hostBuild)
{
}

uint qHash(const QMakeBaseKey &key)
{
    return qHash(key.root) ^ qHash(key.stash) ^ (uint)key.hostBuild;
}

bool operator==(const QMakeBaseKey &one, const QMakeBaseKey &two)
{
    return one.root == two.root && one.stash == two.stash && one.hostBuild == two.hostBuild;
}

QMakeBaseEnv::QMakeBaseEnv()
    : evaluator(nullptr)
{
#ifdef PROEVALUATOR_THREAD_SAFE
    inProgress = false;
#endif
}

QMakeBaseEnv::~QMakeBaseEnv()
{
    delete evaluator;
}

namespace QMakeInternal {
QMakeStatics statics;
}

void QMakeEvaluator::initStatics()
{
    if (!statics.field_sep.isNull())
        return;

    statics.field_sep = QLatin1String(" ");
    statics.strtrue = QLatin1String("true");
    statics.strfalse = QLatin1String("false");
    statics.strCONFIG = ProKey("CONFIG");
    statics.strARGS = ProKey("ARGS");
    statics.strARGC = ProKey("ARGC");
    statics.strDot = QLatin1String(".");
    statics.strDotDot = QLatin1String("..");
    statics.strever = QLatin1String("ever");
    statics.strforever = QLatin1String("forever");
    statics.strhost_build = QLatin1String("host_build");
    statics.strTEMPLATE = ProKey("TEMPLATE");
    statics.strQMAKE_PLATFORM = ProKey("QMAKE_PLATFORM");
    statics.strQMAKE_DIR_SEP = ProKey("QMAKE_DIR_SEP");
    statics.strQMAKESPEC = ProKey("QMAKESPEC");
#ifdef PROEVALUATOR_FULL
    statics.strREQUIRES = ProKey("REQUIRES");
#endif

    statics.fakeValue = ProStringList(ProString("_FAKE_")); // It has to have a unique begin() value

    initFunctionStatics();

    static const struct {
        const char * const oldname, * const newname;
    } mapInits[] = {
        { "INTERFACES", "FORMS" },
        { "QMAKE_POST_BUILD", "QMAKE_POST_LINK" },
        { "TARGETDEPS", "POST_TARGETDEPS" },
        { "LIBPATH", "QMAKE_LIBDIR" },
        { "QMAKE_EXT_MOC", "QMAKE_EXT_CPP_MOC" },
        { "QMAKE_MOD_MOC", "QMAKE_H_MOD_MOC" },
        { "QMAKE_LFLAGS_SHAPP", "QMAKE_LFLAGS_APP" },
        { "PRECOMPH", "PRECOMPILED_HEADER" },
        { "PRECOMPCPP", "PRECOMPILED_SOURCE" },
        { "INCPATH", "INCLUDEPATH" },
        { "QMAKE_EXTRA_WIN_COMPILERS", "QMAKE_EXTRA_COMPILERS" },
        { "QMAKE_EXTRA_UNIX_COMPILERS", "QMAKE_EXTRA_COMPILERS" },
        { "QMAKE_EXTRA_WIN_TARGETS", "QMAKE_EXTRA_TARGETS" },
        { "QMAKE_EXTRA_UNIX_TARGETS", "QMAKE_EXTRA_TARGETS" },
        { "QMAKE_EXTRA_UNIX_INCLUDES", "QMAKE_EXTRA_INCLUDES" },
        { "QMAKE_EXTRA_UNIX_VARIABLES", "QMAKE_EXTRA_VARIABLES" },
        { "QMAKE_RPATH", "QMAKE_LFLAGS_RPATH" },
        { "QMAKE_FRAMEWORKDIR", "QMAKE_FRAMEWORKPATH" },
        { "QMAKE_FRAMEWORKDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS" },
        { "IN_PWD", "PWD" },
        { "DEPLOYMENT", "INSTALLS" }
    };
    statics.varMap.reserve((int)(sizeof(mapInits)/sizeof(mapInits[0])));
    for (unsigned i = 0; i < sizeof(mapInits)/sizeof(mapInits[0]); ++i)
        statics.varMap.insert(ProKey(mapInits[i].oldname), ProKey(mapInits[i].newname));
}

const ProKey &QMakeEvaluator::map(const ProKey &var)
{
    QHash<ProKey, ProKey>::ConstIterator it = statics.varMap.constFind(var);
    if (it == statics.varMap.constEnd())
        return var;
    deprecationWarning(fL1S("Variable %1 is deprecated; use %2 instead.")
                       .arg(var.toQString(), it.value().toQString()));
    return it.value();
}


QMakeEvaluator::QMakeEvaluator(QMakeGlobals *option, QMakeParser *parser, QMakeVfs *vfs,
                               QMakeHandler *handler)
  :
#ifdef PROEVALUATOR_DEBUG
    m_debugLevel(option->debugLevel),
#endif
    m_option(option), m_parser(parser), m_handler(handler), m_vfs(vfs)
{
    // So that single-threaded apps don't have to call initialize() for now.
    initStatics();

    // Configuration, more or less
    m_caller = nullptr;
#ifdef PROEVALUATOR_CUMULATIVE
    m_cumulative = false;
#endif
    m_hostBuild = false;

    // Evaluator state
#ifdef PROEVALUATOR_CUMULATIVE
    m_skipLevel = 0;
#endif
    m_listCount = 0;
    m_toggle = 0;
    m_valuemapStack.push(ProValueMap());
    m_valuemapInited = false;
}

QMakeEvaluator::~QMakeEvaluator()
{
}

void QMakeEvaluator::initFrom(const QMakeEvaluator *other)
{
    Q_ASSERT_X(other, "QMakeEvaluator::visitProFile", "Project not prepared");
    m_functionDefs = other->m_functionDefs;
    m_valuemapStack = other->m_valuemapStack;
    m_valuemapInited = true;
    m_qmakespec = other->m_qmakespec;
    m_qmakespecName = other->m_qmakespecName;
    m_mkspecPaths = other->m_mkspecPaths;
    m_featureRoots = other->m_featureRoots;
    m_dirSep = other->m_dirSep;
}

//////// Evaluator tools /////////

uint QMakeEvaluator::getBlockLen(const ushort *&tokPtr)
{
    uint len = *tokPtr++;
    len |= (uint)*tokPtr++ << 16;
    return len;
}

void QMakeEvaluator::skipStr(const ushort *&tokPtr)
{
    uint len = *tokPtr++;
    tokPtr += len;
}

void QMakeEvaluator::skipHashStr(const ushort *&tokPtr)
{
    tokPtr += 2;
    uint len = *tokPtr++;
    tokPtr += len;
}

// FIXME: this should not build new strings for direct sections.
// Note that the E_SPRINTF and E_LIST implementations rely on the deep copy.
ProStringList QMakeEvaluator::split_value_list(const QStringRef &vals, int source)
{
    QString build;
    ProStringList ret;

    if (!source)
        source = currentFileId();

    const QChar *vals_data = vals.data();
    const int vals_len = vals.length();
    ushort quote = 0;
    bool hadWord = false;
    for (int x = 0; x < vals_len; x++) {
        ushort unicode = vals_data[x].unicode();
        if (unicode == quote) {
            quote = 0;
            hadWord = true;
            build += QChar(unicode);
            continue;
        }
        switch (unicode) {
        case '"':
        case '\'':
            if (!quote)
                quote = unicode;
            // FIXME: this is inconsistent with the "there are no empty strings" dogma.
            hadWord = true;
            break;
        case ' ':
        case '\t':
            if (!quote) {
                if (hadWord) {
                    ret << ProString(build).setSource(source);
                    build.clear();
                    hadWord = false;
                }
                continue;
            }
            break;
        case '\\':
            if (x + 1 != vals_len) {
                ushort next = vals_data[++x].unicode();
                if (next == '\'' || next == '"' || next == '\\') {
                    build += QChar(unicode);
                    unicode = next;
                } else {
                    --x;
                }
            }
            Q_FALLTHROUGH();
        default:
            hadWord = true;
            break;
        }
        build += QChar(unicode);
    }
    if (hadWord)
        ret << ProString(build).setSource(source);
    return ret;
}

static void replaceInList(ProStringList *varlist,
        const QRegExp &regexp, const QString &replace, bool global, QString &tmp)
{
    for (ProStringList::Iterator varit = varlist->begin(); varit != varlist->end(); ) {
        ProStringRoUser u1(*varit, tmp);
        QString val = u1.str();
        QString copy = val; // Force detach and have a reference value
        val.replace(regexp, replace);
        if (!val.isSharedWith(copy) && val != copy) {
            if (val.isEmpty()) {
                varit = varlist->erase(varit);
            } else {
                (*varit).setValue(val);
                ++varit;
            }
            if (!global)
                break;
        } else {
            ++varit;
        }
    }
}

//////// Evaluator /////////

static ALWAYS_INLINE void addStr(
        const ProString &str, ProStringList *ret, bool &pending, bool joined)
{
    if (joined) {
        ret->last().append(str, &pending);
    } else {
        if (!pending) {
            pending = true;
            *ret << str;
        } else {
            ret->last().append(str);
        }
    }
}

static ALWAYS_INLINE void addStrList(
        const ProStringList &list, ushort tok, ProStringList *ret, bool &pending, bool joined)
{
    if (!list.isEmpty()) {
        if (joined) {
            ret->last().append(list, &pending, !(tok & TokQuoted));
        } else {
            if (tok & TokQuoted) {
                if (!pending) {
                    pending = true;
                    *ret << ProString();
                }
                ret->last().append(list);
            } else {
                if (!pending) {
                    // Another qmake bizzarity: if nothing is pending and the
                    // first element is empty, it will be eaten
                    if (!list.at(0).isEmpty()) {
                        // The common case
                        pending = true;
                        *ret += list;
                        return;
                    }
                } else {
                    ret->last().append(list.at(0));
                }
                // This is somewhat slow, but a corner case
                for (int j = 1; j < list.size(); ++j) {
                    pending = true;
                    *ret << list.at(j);
                }
            }
        }
    }
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateExpression(
        const ushort *&tokPtr, ProStringList *ret, bool joined)
{
    debugMsg(2, joined ? "evaluating joined expression" : "evaluating expression");
    ProFile *pro = m_current.pro;
    if (joined)
        *ret << ProString();
    bool pending = false;
    forever {
        ushort tok = *tokPtr++;
        if (tok & TokNewStr) {
            debugMsg(2, "new string");
            pending = false;
        }
        ushort maskedTok = tok & TokMask;
        switch (maskedTok) {
        case TokLine:
            m_current.line = *tokPtr++;
            break;
        case TokLiteral: {
            const ProString &val = pro->getStr(tokPtr);
            debugMsg(2, "literal %s", dbgStr(val));
            addStr(val, ret, pending, joined);
            break; }
        case TokHashLiteral: {
            const ProKey &val = pro->getHashStr(tokPtr);
            debugMsg(2, "hashed literal %s", dbgStr(val.toString()));
            addStr(val, ret, pending, joined);
            break; }
        case TokVariable: {
            const ProKey &var = pro->getHashStr(tokPtr);
            const ProStringList &val = values(map(var));
            debugMsg(2, "variable %s => %s", dbgKey(var), dbgStrList(val));
            addStrList(val, tok, ret, pending, joined);
            break; }
        case TokProperty: {
            const ProKey &var = pro->getHashStr(tokPtr);
            const ProString &val = propertyValue(var);
            debugMsg(2, "property %s => %s", dbgKey(var), dbgStr(val));
            addStr(val, ret, pending, joined);
            break; }
        case TokEnvVar: {
            const ProString &var = pro->getStr(tokPtr);
            const ProString &val = ProString(m_option->getEnv(var.toQString()));
            debugMsg(2, "env var %s => %s", dbgStr(var), dbgStr(val));
            addStr(val, ret, pending, joined);
            break; }
        case TokFuncName: {
            const ProKey &func = pro->getHashStr(tokPtr);
            debugMsg(2, "function %s", dbgKey(func));
            ProStringList val;
            if (evaluateExpandFunction(func, tokPtr, &val) == ReturnError)
                return ReturnError;
            addStrList(val, tok, ret, pending, joined);
            break; }
        default:
            debugMsg(2, "evaluated expression => %s", dbgStrList(*ret));
            tokPtr--;
            return ReturnTrue;
        }
    }
}

void QMakeEvaluator::skipExpression(const ushort *&pTokPtr)
{
    const ushort *tokPtr = pTokPtr;
    forever {
        ushort tok = *tokPtr++;
        switch (tok) {
        case TokLine:
            m_current.line = *tokPtr++;
            break;
        case TokValueTerminator:
        case TokFuncTerminator:
            pTokPtr = tokPtr;
            return;
        case TokArgSeparator:
            break;
        default:
            switch (tok & TokMask) {
            case TokLiteral:
            case TokEnvVar:
                skipStr(tokPtr);
                break;
            case TokHashLiteral:
            case TokVariable:
            case TokProperty:
                skipHashStr(tokPtr);
                break;
            case TokFuncName:
                skipHashStr(tokPtr);
                pTokPtr = tokPtr;
                skipExpression(pTokPtr);
                tokPtr = pTokPtr;
                break;
            default:
                Q_ASSERT_X(false, "skipExpression", "Unrecognized token");
                break;
            }
        }
    }
}

QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
        ProFile *pro, const ushort *tokPtr)
{
    m_current.pro = pro;
    m_current.line = 0;
    return visitProBlock(tokPtr);
}

QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(
        const ushort *tokPtr)
{
    traceMsg("entering block");
    ProStringList curr;
    ProFile *pro = m_current.pro;
    bool okey = true, or_op = false, invert = false;
    uint blockLen;
    while (ushort tok = *tokPtr++) {
        VisitReturn ret;
        switch (tok) {
        case TokLine:
            m_current.line = *tokPtr++;
            continue;
        case TokAssign:
        case TokAppend:
        case TokAppendUnique:
        case TokRemove:
        case TokReplace:
            ret = visitProVariable(tok, curr, tokPtr);
            if (ret == ReturnError)
                break;
            curr.clear();
            continue;
        case TokBranch:
            blockLen = getBlockLen(tokPtr);
            if (m_cumulative) {
#ifdef PROEVALUATOR_CUMULATIVE
                if (!okey)
                    m_skipLevel++;
                ret = blockLen ? visitProBlock(tokPtr) : ReturnTrue;
                tokPtr += blockLen;
                blockLen = getBlockLen(tokPtr);
                if (!okey)
                    m_skipLevel--;
                else
                    m_skipLevel++;
                if ((ret == ReturnTrue || ret == ReturnFalse) && blockLen)
                    ret = visitProBlock(tokPtr);
                if (okey)
                    m_skipLevel--;
#endif
            } else {
                if (okey) {
                    traceMsg("taking 'then' branch");
                    ret = blockLen ? visitProBlock(tokPtr) : ReturnTrue;
                    traceMsg("finished 'then' branch");
                }
                tokPtr += blockLen;
                blockLen = getBlockLen(tokPtr);
                if (!okey) {
                    traceMsg("taking 'else' branch");
                    ret = blockLen ? visitProBlock(tokPtr) : ReturnTrue;
                    traceMsg("finished 'else' branch");
                }
            }
            tokPtr += blockLen;
            okey = true, or_op = false; // force next evaluation
            break;
        case TokForLoop:
            if (m_cumulative || okey != or_op) {
                const ProKey &variable = pro->getHashStr(tokPtr);
                uint exprLen = getBlockLen(tokPtr);
                const ushort *exprPtr = tokPtr;
                tokPtr += exprLen;
                blockLen = getBlockLen(tokPtr);
                ret = visitProLoop(variable, exprPtr, tokPtr);
            } else {
                skipHashStr(tokPtr);
                uint exprLen = getBlockLen(tokPtr);
                tokPtr += exprLen;
                blockLen = getBlockLen(tokPtr);
                traceMsg("skipped loop");
                ret = ReturnTrue;
            }
            tokPtr += blockLen;
            okey = true, or_op = false; // force next evaluation
            break;
        case TokBypassNesting:
            blockLen = getBlockLen(tokPtr);
            if ((m_cumulative || okey != or_op) && blockLen) {
                ProValueMapStack savedValuemapStack = std::move(m_valuemapStack);
                m_valuemapStack.clear();
                m_valuemapStack.splice(m_valuemapStack.end(),
                                       savedValuemapStack, savedValuemapStack.begin());
                traceMsg("visiting nesting-bypassing block");
                ret = visitProBlock(tokPtr);
                traceMsg("visited nesting-bypassing block");
                savedValuemapStack.splice(savedValuemapStack.begin(),
                                          m_valuemapStack, m_valuemapStack.begin());
                m_valuemapStack = std::move(savedValuemapStack);
            } else {
                traceMsg("skipped nesting-bypassing block");
                ret = ReturnTrue;
            }
            tokPtr += blockLen;
            okey = true, or_op = false; // force next evaluation
            break;
        case TokTestDef:
        case TokReplaceDef:
            if (m_cumulative || okey != or_op) {
                const ProKey &name = pro->getHashStr(tokPtr);
                blockLen = getBlockLen(tokPtr);
                visitProFunctionDef(tok, name, tokPtr);
                traceMsg("defined %s function %s",
                      tok == TokTestDef ? "test" : "replace", dbgKey(name));
            } else {
                traceMsg("skipped function definition");
                skipHashStr(tokPtr);
                blockLen = getBlockLen(tokPtr);
            }
            tokPtr += blockLen;
            okey = true, or_op = false; // force next evaluation
            continue;
        case TokNot:
            traceMsg("NOT");
            invert ^= true;
            continue;
        case TokAnd:
            traceMsg("AND");
            or_op = false;
            continue;
        case TokOr:
            traceMsg("OR");
            or_op = true;
            continue;
        case TokCondition:
            if (!m_skipLevel && okey != or_op) {
                if (curr.size() != 1) {
                    if (!m_cumulative || !curr.isEmpty())
                        evalError(fL1S("Conditional must expand to exactly one word."));
                    okey = false;
                } else {
                    okey = isActiveConfig(curr.at(0).toQStringRef(), true);
                    traceMsg("condition %s is %s", dbgStr(curr.at(0)), dbgBool(okey));
                    okey ^= invert;
                }
            } else {
                traceMsg("skipped condition %s", curr.size() == 1 ? dbgStr(curr.at(0)) : "<invalid>");
            }
            or_op = !okey; // tentatively force next evaluation
            invert = false;
            curr.clear();
            continue;
        case TokTestCall:
            if (!m_skipLevel && okey != or_op) {
                if (curr.size() != 1) {
                    if (!m_cumulative || !curr.isEmpty())
                        evalError(fL1S("Test name must expand to exactly one word."));
                    skipExpression(tokPtr);
                    okey = false;
                } else {
                    traceMsg("evaluating test function %s", dbgStr(curr.at(0)));
                    ret = evaluateConditionalFunction(curr.at(0).toKey(), tokPtr);
                    switch (ret) {
                    case ReturnTrue: okey = true; break;
                    case ReturnFalse: okey = false; break;
                    default:
                        traceMsg("aborting block, function status: %s", dbgReturn(ret));
                        return ret;
                    }
                    traceMsg("test function returned %s", dbgBool(okey));
                    okey ^= invert;
                }
            } else if (m_cumulative) {
#ifdef PROEVALUATOR_CUMULATIVE
                m_skipLevel++;
                if (curr.size() != 1)
                    skipExpression(tokPtr);
                else
                    evaluateConditionalFunction(curr.at(0).toKey(), tokPtr);
                m_skipLevel--;
#endif
            } else {
                skipExpression(tokPtr);
                traceMsg("skipped test function %s", curr.size() == 1 ? dbgStr(curr.at(0)) : "<invalid>");
            }
            or_op = !okey; // tentatively force next evaluation
            invert = false;
            curr.clear();
            continue;
        case TokReturn:
            m_returnValue = curr;
            curr.clear();
            ret = ReturnReturn;
            goto ctrlstm;
        case TokBreak:
            ret = ReturnBreak;
            goto ctrlstm;
        case TokNext:
            ret = ReturnNext;
          ctrlstm:
            if (!m_skipLevel && okey != or_op) {
                traceMsg("flow control statement '%s', aborting block", dbgReturn(ret));
                return ret;
            }
            traceMsg("skipped flow control statement '%s'", dbgReturn(ret));
            okey = false, or_op = true; // force next evaluation
            continue;
        default: {
                const ushort *oTokPtr = --tokPtr;
                ret = evaluateExpression(tokPtr, &curr, false);
                if (ret == ReturnError || tokPtr != oTokPtr)
                    break;
            }
            Q_ASSERT_X(false, "visitProBlock", "unexpected item type");
            continue;
        }
        if (ret != ReturnTrue && ret != ReturnFalse) {
            traceMsg("aborting block, status: %s", dbgReturn(ret));
            return ret;
        }
    }
    traceMsg("leaving block, okey=%s", dbgBool(okey));
    return returnBool(okey);
}


void QMakeEvaluator::visitProFunctionDef(
        ushort tok, const ProKey &name, const ushort *tokPtr)
{
    QHash<ProKey, ProFunctionDef> *hash =
            (tok == TokTestDef
             ? &m_functionDefs.testFunctions
             : &m_functionDefs.replaceFunctions);
    hash->insert(name, ProFunctionDef(m_current.pro, tokPtr - m_current.pro->tokPtr()));
}

QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop(
        const ProKey &_variable, const ushort *exprPtr, const ushort *tokPtr)
{
    VisitReturn ret = ReturnTrue;
    bool infinite = false;
    int index = 0;
    ProKey variable;
    ProStringList oldVarVal;
    ProStringList it_list_out;
    if (expandVariableReferences(exprPtr, 0, &it_list_out, true) == ReturnError)
        return ReturnError;
    ProString it_list = it_list_out.at(0);
    if (_variable.isEmpty()) {
        if (it_list != statics.strever) {
            evalError(fL1S("Invalid loop expression."));
            return ReturnFalse;
        }
        it_list = ProString(statics.strforever);
    } else {
        variable = map(_variable);
        oldVarVal = values(variable);
    }
    ProStringList list = values(it_list.toKey());
    if (list.isEmpty()) {
        if (it_list == statics.strforever) {
            if (m_cumulative) {
                // The termination conditions wouldn't be evaluated, so we must skip it.
                traceMsg("skipping forever loop in cumulative mode");
                return ReturnFalse;
            }
            infinite = true;
        } else {
            const QStringRef &itl = it_list.toQStringRef();
            int dotdot = itl.indexOf(statics.strDotDot);
            if (dotdot != -1) {
                bool ok;
                int start = itl.left(dotdot).toInt(&ok);
                if (ok) {
                    int end = itl.mid(dotdot+2).toInt(&ok);
                    if (ok) {
                        const int absDiff = qAbs(end - start);
                        if (m_cumulative && absDiff > 100) {
                            // Such a loop is unlikely to contribute something useful to the
                            // file collection, and may cause considerable delay.
                            traceMsg("skipping excessive loop in cumulative mode");
                            return ReturnFalse;
                        }
                        list.reserve(absDiff + 1);
                        if (start < end) {
                            for (int i = start; i <= end; i++)
                                list << ProString(QString::number(i));
                        } else {
                            for (int i = start; i >= end; i--)
                                list << ProString(QString::number(i));
                        }
                    }
                }
            }
        }
    }

    if (infinite)
        traceMsg("entering infinite loop for %s", dbgKey(variable));
    else
        traceMsg("entering loop for %s over %s", dbgKey(variable), dbgStrList(list));

    forever {
        if (infinite) {
            if (!variable.isEmpty())
                m_valuemapStack.top()[variable] = ProStringList(ProString(QString::number(index)));
            if (++index > 1000) {
                evalError(fL1S("Ran into infinite loop (> 1000 iterations)."));
                break;
            }
            traceMsg("loop iteration %d", index);
        } else {
            ProString val;
            do {
                if (index >= list.count())
                    goto do_break;
                val = list.at(index++);
            } while (val.isEmpty()); // stupid, but qmake is like that
            traceMsg("loop iteration %s", dbgStr(val));
            m_valuemapStack.top()[variable] = ProStringList(val);
        }

        ret = visitProBlock(tokPtr);
        switch (ret) {
        case ReturnTrue:
        case ReturnFalse:
            break;
        case ReturnNext:
            ret = ReturnTrue;
            break;
        case ReturnBreak:
            ret = ReturnTrue;
            goto do_break;
        default:
            goto do_break;
        }
    }
  do_break:

    traceMsg("done looping");

    if (!variable.isEmpty())
        m_valuemapStack.top()[variable] = oldVarVal;
    return ret;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable(
        ushort tok, const ProStringList &curr, const ushort *&tokPtr)
{
    int sizeHint = *tokPtr++;

    if (curr.size() != 1) {
        skipExpression(tokPtr);
        if (!m_cumulative || !curr.isEmpty())
            evalError(fL1S("Left hand side of assignment must expand to exactly one word."));
        return ReturnTrue;
    }
    const ProKey &varName = map(curr.first());

    if (tok == TokReplace) {      // ~=
        // DEFINES ~= s/a/b/?[gqi]

        ProStringList varVal;
        if (expandVariableReferences(tokPtr, sizeHint, &varVal, true) == ReturnError)
            return ReturnError;
        const QStringRef &val = varVal.at(0).toQStringRef();
        if (val.length() < 4 || val.at(0) != QLatin1Char('s')) {
            evalError(fL1S("The ~= operator can handle only the s/// function."));
            return ReturnTrue;
        }
        QChar sep = val.at(1);
        auto func = val.split(sep, QString::KeepEmptyParts);
        if (func.count() < 3 || func.count() > 4) {
            evalError(fL1S("The s/// function expects 3 or 4 arguments."));
            return ReturnTrue;
        }

        bool global = false, quote = false, case_sense = false;
        if (func.count() == 4) {
            global = func[3].indexOf(QLatin1Char('g')) != -1;
            case_sense = func[3].indexOf(QLatin1Char('i')) == -1;
            quote = func[3].indexOf(QLatin1Char('q')) != -1;
        }
        QString pattern = func[1].toString();
        QString replace = func[2].toString();
        if (quote)
            pattern = QRegExp::escape(pattern);

        QRegExp regexp(pattern, case_sense ? Qt::CaseSensitive : Qt::CaseInsensitive);

        // We could make a union of modified and unmodified values,
        // but this will break just as much as it fixes, so leave it as is.
        replaceInList(&valuesRef(varName), regexp, replace, global, m_tmp2);
        debugMsg(2, "replaced %s with %s", dbgQStr(pattern), dbgQStr(replace));
    } else {
        ProStringList varVal;
        if (expandVariableReferences(tokPtr, sizeHint, &varVal, false) == ReturnError)
            return ReturnError;
        switch (tok) {
        default: // whatever - cannot happen
        case TokAssign:          // =
            varVal.removeEmpty();
            // FIXME: add check+warning about accidental value removal.
            // This may be a bit too noisy, though.
            m_valuemapStack.top()[varName] = varVal;
            debugMsg(2, "assigning");
            break;
        case TokAppendUnique:    // *=
            valuesRef(varName).insertUnique(varVal);
            debugMsg(2, "appending unique");
            break;
        case TokAppend:          // +=
            varVal.removeEmpty();
            valuesRef(varName) += varVal;
            debugMsg(2, "appending");
            break;
        case TokRemove:       // -=
            if (!m_cumulative) {
                valuesRef(varName).removeEach(varVal);
            } else {
                // We are stingy with our values.
            }
            debugMsg(2, "removing");
            break;
        }
    }
    traceMsg("%s := %s", dbgKey(varName), dbgStrList(values(varName)));

    if (varName == statics.strTEMPLATE)
        setTemplate();
    else if (varName == statics.strQMAKE_PLATFORM)
        m_featureRoots = nullptr;
    else if (varName == statics.strQMAKE_DIR_SEP)
        m_dirSep = first(varName);
    else if (varName == statics.strQMAKESPEC) {
        if (!values(varName).isEmpty()) {
            QString spec = values(varName).first().toQString();
            if (IoUtils::isAbsolutePath(spec)) {
                m_qmakespec = spec;
                m_qmakespecName = IoUtils::fileName(m_qmakespec).toString();
                m_featureRoots = nullptr;
            }
        }
    }
#ifdef PROEVALUATOR_FULL
    else if (varName == statics.strREQUIRES)
        return checkRequirements(values(varName));
#endif

    return ReturnTrue;
}

void QMakeEvaluator::setTemplate()
{
    ProStringList &values = valuesRef(statics.strTEMPLATE);
    if (!m_option->user_template.isEmpty()) {
        // Don't allow override
        values = ProStringList(ProString(m_option->user_template));
    } else {
        if (values.isEmpty())
            values.append(ProString("app"));
        else
            values.erase(values.begin() + 1, values.end());
    }
    if (!m_option->user_template_prefix.isEmpty()) {
        ProString val = values.first();
        if (!val.startsWith(m_option->user_template_prefix))
            values = ProStringList(ProString(m_option->user_template_prefix + val));
    }
}

#if defined(Q_CC_MSVC)
static ProString msvcBinDirToQMakeArch(QString subdir)
{
    int idx = subdir.indexOf(QLatin1Char('\\'));
    if (idx == -1)
        return ProString("x86");
    subdir.remove(0, idx + 1);
    idx = subdir.indexOf(QLatin1Char('_'));
    if (idx >= 0)
        subdir.remove(0, idx + 1);
    subdir = subdir.toLower();
    if (subdir == QLatin1String("amd64"))
        return ProString("x86_64");
    // Since 2017 the folder structure from here is HostX64|X86/x64|x86
    idx = subdir.indexOf(QLatin1Char('\\'));
    if (idx == -1)
        return ProString("x86");
    subdir.remove(0, idx + 1);
    if (subdir == QLatin1String("x64"))
        return ProString("x86_64");
    return ProString(subdir);
}

static ProString defaultMsvcArchitecture()
{
#if defined(Q_OS_WIN64)
    return ProString("x86_64");
#else
    return ProString("x86");
#endif
}

static ProString msvcArchitecture(const QString &vcInstallDir, const QString &pathVar)
{
    if (vcInstallDir.isEmpty())
        return defaultMsvcArchitecture();
    QString vcBinDir = vcInstallDir;
    if (vcBinDir.endsWith(QLatin1Char('\\')))
        vcBinDir.chop(1);
    const auto dirs = pathVar.split(QLatin1Char(';'), QString::SkipEmptyParts);
    for (const QString &dir : dirs) {
        if (!dir.startsWith(vcBinDir, Qt::CaseInsensitive))
            continue;
        const ProString arch = msvcBinDirToQMakeArch(dir.mid(vcBinDir.length() + 1));
        if (!arch.isEmpty())
            return arch;
    }
    return defaultMsvcArchitecture();
}
#endif // defined(Q_CC_MSVC)

void QMakeEvaluator::loadDefaults()
{
    ProValueMap &vars = m_valuemapStack.top();

    vars[ProKey("DIR_SEPARATOR")] << ProString(m_option->dir_sep);
    vars[ProKey("DIRLIST_SEPARATOR")] << ProString(m_option->dirlist_sep);
    vars[ProKey("_DATE_")] << ProString(QDateTime::currentDateTime().toString());
    if (!m_option->qmake_abslocation.isEmpty())
        vars[ProKey("QMAKE_QMAKE")] << ProString(m_option->qmake_abslocation);
    if (!m_option->qmake_args.isEmpty())
        vars[ProKey("QMAKE_ARGS")] = ProStringList(m_option->qmake_args);
    if (!m_option->qtconf.isEmpty())
        vars[ProKey("QMAKE_QTCONF")] = ProString(m_option->qtconf);
    vars[ProKey("QMAKE_HOST.cpu_count")] = ProString(QString::number(idealThreadCount()));
#if defined(Q_OS_WIN32)
    vars[ProKey("QMAKE_HOST.os")] << ProString("Windows");

    DWORD name_length = 1024;
    wchar_t name[1024];
    if (GetComputerName(name, &name_length))
        vars[ProKey("QMAKE_HOST.name")] << ProString(QString::fromWCharArray(name));

    vars[ProKey("QMAKE_HOST.version")] << ProString(QSysInfo::kernelVersion());
    vars[ProKey("QMAKE_HOST.version_string")] << ProString(QSysInfo::productVersion());

    SYSTEM_INFO info;
    GetSystemInfo(&info);
    ProString archStr;
    switch (info.wProcessorArchitecture) {
# ifdef PROCESSOR_ARCHITECTURE_AMD64
    case PROCESSOR_ARCHITECTURE_AMD64:
        archStr = ProString("x86_64");
        break;
# endif
    case PROCESSOR_ARCHITECTURE_INTEL:
        archStr = ProString("x86");
        break;
    case PROCESSOR_ARCHITECTURE_IA64:
# ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
    case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
# endif
        archStr = ProString("IA64");
        break;
    default:
        archStr = ProString("Unknown");
        break;
    }
    vars[ProKey("QMAKE_HOST.arch")] << archStr;

# if defined(Q_CC_MSVC) // ### bogus condition, but nobody x-builds for msvc with a different qmake
    // Since VS 2017 we need VCToolsInstallDir instead of VCINSTALLDIR
    QString vcInstallDir = m_option->getEnv(QLatin1String("VCToolsInstallDir"));
    if (vcInstallDir.isEmpty())
        vcInstallDir = m_option->getEnv(QLatin1String("VCINSTALLDIR"));
    vars[ProKey("QMAKE_TARGET.arch")] = msvcArchitecture(
                vcInstallDir,
                m_option->getEnv(QLatin1String("PATH")));
# endif
#elif defined(Q_OS_UNIX)
    struct utsname name;
    if (uname(&name) != -1) {
        vars[ProKey("QMAKE_HOST.os")] << ProString(name.sysname);
        vars[ProKey("QMAKE_HOST.name")] << ProString(QString::fromLocal8Bit(name.nodename));
        vars[ProKey("QMAKE_HOST.version")] << ProString(name.release);
        vars[ProKey("QMAKE_HOST.version_string")] << ProString(name.version);
        vars[ProKey("QMAKE_HOST.arch")] << ProString(name.machine);
    }
#endif

    m_valuemapInited = true;
}

bool QMakeEvaluator::prepareProject(const QString &inDir)
{
    QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
    QString superdir;
    if (m_option->do_cache) {
        QString conffile;
        QString cachefile = m_option->cachefile;
        if (cachefile.isEmpty())  { //find it as it has not been specified
            if (m_outputDir.isEmpty())
                goto no_cache;
            superdir = m_outputDir;
            forever {
                QString superfile = superdir + QLatin1String("/.qmake.super");
                if (m_vfs->exists(superfile, flags)) {
                    m_superfile = QDir::cleanPath(superfile);
                    break;
                }
                QFileInfo qdfi(superdir);
                if (qdfi.isRoot()) {
                    superdir.clear();
                    break;
                }
                superdir = qdfi.path();
            }
            QString sdir = inDir;
            QString dir = m_outputDir;
            forever {
                conffile = sdir + QLatin1String("/.qmake.conf");
                if (!m_vfs->exists(conffile, flags))
                    conffile.clear();
                cachefile = dir + QLatin1String("/.qmake.cache");
                if (!m_vfs->exists(cachefile, flags))
                    cachefile.clear();
                if (!conffile.isEmpty() || !cachefile.isEmpty()) {
                    if (dir != sdir)
                        m_sourceRoot = sdir;
                    m_buildRoot = dir;
                    break;
                }
                if (dir == superdir)
                    goto no_cache;
                QFileInfo qsdfi(sdir);
                QFileInfo qdfi(dir);
                if (qsdfi.isRoot() || qdfi.isRoot())
                    goto no_cache;
                sdir = qsdfi.path();
                dir = qdfi.path();
            }
        } else {
            m_buildRoot = QFileInfo(cachefile).path();
        }
        m_conffile = QDir::cleanPath(conffile);
        m_cachefile = QDir::cleanPath(cachefile);
    }
  no_cache:

    QString dir = m_outputDir;
    forever {
        QString stashfile = dir + QLatin1String("/.qmake.stash");
        if (dir == (!superdir.isEmpty() ? superdir : m_buildRoot) || m_vfs->exists(stashfile, flags)) {
            m_stashfile = QDir::cleanPath(stashfile);
            break;
        }
        QFileInfo qdfi(dir);
        if (qdfi.isRoot())
            break;
        dir = qdfi.path();
    }

    return true;
}

bool QMakeEvaluator::loadSpecInternal()
{
    if (evaluateFeatureFile(QLatin1String("spec_pre.prf")) != ReturnTrue)
        return false;
    QString spec = m_qmakespec + QLatin1String("/qmake.conf");
    if (evaluateFile(spec, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue) {
        evalError(fL1S("Could not read qmake configuration file %1.").arg(spec));
        return false;
    }
#ifndef QT_BUILD_QMAKE
    // Legacy support for Qt4 default specs
#  ifdef Q_OS_UNIX
    if (m_qmakespec.endsWith(QLatin1String("/default-host"))
        || m_qmakespec.endsWith(QLatin1String("/default"))) {
        QString rspec = QFileInfo(m_qmakespec).symLinkTarget();
        if (!rspec.isEmpty())
            m_qmakespec = QDir::cleanPath(QDir(m_qmakespec).absoluteFilePath(rspec));
    }
#  else
    // We can't resolve symlinks as they do on Unix, so configure.exe puts
    // the source of the qmake.conf at the end of the default/qmake.conf in
    // the QMAKESPEC_ORIGINAL variable.
    const ProString &orig_spec = first(ProKey("QMAKESPEC_ORIGINAL"));
    if (!orig_spec.isEmpty()) {
        QString spec = orig_spec.toQString();
        if (IoUtils::isAbsolutePath(spec))
            m_qmakespec = spec;
    }
#  endif
#endif
    valuesRef(ProKey("QMAKESPEC")) = ProString(m_qmakespec);
    m_qmakespecName = IoUtils::fileName(m_qmakespec).toString();
    // This also ensures that m_featureRoots is valid.
    if (evaluateFeatureFile(QLatin1String("spec_post.prf")) != ReturnTrue)
        return false;
    return true;
}

bool QMakeEvaluator::loadSpec()
{
    QString qmakespec = m_option->expandEnvVars(
                m_hostBuild ? m_option->qmakespec : m_option->xqmakespec);

    {
        QMakeEvaluator evaluator(m_option, m_parser, m_vfs, m_handler);
        evaluator.m_sourceRoot = m_sourceRoot;
        evaluator.m_buildRoot = m_buildRoot;

        if (!m_superfile.isEmpty() && evaluator.evaluateFile(
                m_superfile, QMakeHandler::EvalConfigFile, LoadProOnly|LoadHidden) != ReturnTrue) {
            return false;
        }
        if (!m_conffile.isEmpty() && evaluator.evaluateFile(
                m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly|LoadHidden) != ReturnTrue) {
            return false;
        }
        if (!m_cachefile.isEmpty() && evaluator.evaluateFile(
                m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly|LoadHidden) != ReturnTrue) {
            return false;
        }
        if (qmakespec.isEmpty()) {
            if (!m_hostBuild)
                qmakespec = evaluator.first(ProKey("XQMAKESPEC")).toQString();
            if (qmakespec.isEmpty())
                qmakespec = evaluator.first(ProKey("QMAKESPEC")).toQString();
        }
        m_qmakepath = evaluator.values(ProKey("QMAKEPATH")).toQStringList();
        m_qmakefeatures = evaluator.values(ProKey("QMAKEFEATURES")).toQStringList();
    }

    updateMkspecPaths();
    if (qmakespec.isEmpty())
        qmakespec = propertyValue(ProKey(m_hostBuild ? "QMAKE_SPEC" : "QMAKE_XSPEC")).toQString();
#ifndef QT_BUILD_QMAKE
    // Legacy support for Qt4 qmake in Qt Creator, etc.
    if (qmakespec.isEmpty())
        qmakespec = m_hostBuild ? QLatin1String("default-host") : QLatin1String("default");
#endif
    if (IoUtils::isRelativePath(qmakespec)) {
        for (const QString &root : qAsConst(m_mkspecPaths)) {
            QString mkspec = root + QLatin1Char('/') + qmakespec;
            if (IoUtils::exists(mkspec)) {
                qmakespec = mkspec;
                goto cool;
            }
        }
        evalError(fL1S("Could not find qmake spec '%1'.").arg(qmakespec));
        return false;
    }
  cool:
    m_qmakespec = QDir::cleanPath(qmakespec);

    if (!m_superfile.isEmpty()) {
        valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
        if (evaluateFile(
                m_superfile, QMakeHandler::EvalConfigFile, LoadProOnly|LoadHidden) != ReturnTrue)
            return false;
    }
    if (!loadSpecInternal())
        return false;
    if (!m_conffile.isEmpty()) {
        valuesRef(ProKey("_QMAKE_CONF_")) << ProString(m_conffile);
        if (evaluateFile(
                m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
            return false;
    }
    if (!m_cachefile.isEmpty()) {
        valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile);
        if (evaluateFile(
                m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
            return false;
    }
    QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
    if (!m_stashfile.isEmpty() && m_vfs->exists(m_stashfile, flags)) {
        valuesRef(ProKey("_QMAKE_STASH_")) << ProString(m_stashfile);
        if (evaluateFile(
                m_stashfile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
            return false;
    }
    return true;
}

void QMakeEvaluator::setupProject()
{
    setTemplate();
    ProValueMap &vars = m_valuemapStack.top();
    int proFile = currentFileId();
    vars[ProKey("TARGET")] << ProString(QFileInfo(currentFileName()).baseName()).setSource(proFile);
    vars[ProKey("_PRO_FILE_")] << ProString(currentFileName()).setSource(proFile);
    vars[ProKey("_PRO_FILE_PWD_")] << ProString(currentDirectory()).setSource(proFile);
    vars[ProKey("OUT_PWD")] << ProString(m_outputDir).setSource(proFile);
}

void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where)
{
    if (!cmds.isEmpty()) {
        ProFile *pro = m_parser->parsedProBlock(QStringRef(&cmds), 0, where, -1);
        if (pro->isOk()) {
            m_locationStack.push(m_current);
            visitProBlock(pro, pro->tokPtr());
            m_current = m_locationStack.pop();
        }
        pro->deref();
    }
}

void QMakeEvaluator::applyExtraConfigs()
{
    if (m_extraConfigs.isEmpty())
        return;

    evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(QLatin1Char(' ')), fL1S("(extra configs)"));
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConfigFeatures()
{
    QSet<QString> processed;
    forever {
        bool finished = true;
        ProStringList configs = values(statics.strCONFIG);
        for (int i = configs.size() - 1; i >= 0; --i) {
            ProStringRoUser u1(configs.at(i), m_tmp1);
            QString config = u1.str().toLower();
            if (!processed.contains(config)) {
                config.detach();
                processed.insert(config);
                VisitReturn vr = evaluateFeatureFile(config, true);
                if (vr == ReturnError && !m_cumulative)
                    return vr;
                if (vr == ReturnTrue) {
                    finished = false;
                    break;
                }
            }
        }
        if (finished)
            break;
    }
    return ReturnTrue;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
        ProFile *pro, QMakeHandler::EvalFileType type, LoadFlags flags)
{
    if (!m_cumulative && !pro->isOk())
        return ReturnFalse;

    if (flags & LoadPreFiles) {
        if (!prepareProject(pro->directoryName()))
            return ReturnFalse;

        m_hostBuild = pro->isHostBuild();

#ifdef PROEVALUATOR_THREAD_SAFE
        m_option->mutex.lock();
#endif
        QMakeBaseEnv **baseEnvPtr = &m_option->baseEnvs[QMakeBaseKey(m_buildRoot, m_stashfile, m_hostBuild)];
        if (!*baseEnvPtr)
            *baseEnvPtr = new QMakeBaseEnv;
        QMakeBaseEnv *baseEnv = *baseEnvPtr;

#ifdef PROEVALUATOR_THREAD_SAFE
        QMutexLocker locker(&baseEnv->mutex);
        m_option->mutex.unlock();
        if (baseEnv->inProgress) {
            QThreadPool::globalInstance()->releaseThread();
            baseEnv->cond.wait(&baseEnv->mutex);
            QThreadPool::globalInstance()->reserveThread();
            if (!baseEnv->isOk)
                return ReturnFalse;
        } else
#endif
        if (!baseEnv->evaluator) {
#ifdef PROEVALUATOR_THREAD_SAFE
            baseEnv->inProgress = true;
            locker.unlock();
#endif

            QMakeEvaluator *baseEval = new QMakeEvaluator(m_option, m_parser, m_vfs, m_handler);
            baseEnv->evaluator = baseEval;
            baseEval->m_superfile = m_superfile;
            baseEval->m_conffile = m_conffile;
            baseEval->m_cachefile = m_cachefile;
            baseEval->m_stashfile = m_stashfile;
            baseEval->m_sourceRoot = m_sourceRoot;
            baseEval->m_buildRoot = m_buildRoot;
            baseEval->m_hostBuild = m_hostBuild;
            bool ok = baseEval->loadSpec();

#ifdef PROEVALUATOR_THREAD_SAFE
            locker.relock();
            baseEnv->isOk = ok;
            baseEnv->inProgress = false;
            baseEnv->cond.wakeAll();
#endif

            if (!ok)
                return ReturnFalse;
        }
#ifdef PROEVALUATOR_THREAD_SAFE
        else if (!baseEnv->isOk)
            return ReturnFalse;
#endif

        initFrom(baseEnv->evaluator);
    } else {
        if (!m_valuemapInited)
            loadDefaults();
    }

    VisitReturn vr;

    m_handler->aboutToEval(currentProFile(), pro, type);
    m_profileStack.push(pro);
    valuesRef(ProKey("PWD")) = ProStringList(ProString(currentDirectory()));
    if (flags & LoadPreFiles) {
        setupProject();

        if (!m_option->extra_cmds[QMakeEvalEarly].isEmpty())
            evaluateCommand(m_option->extra_cmds[QMakeEvalEarly], fL1S("(command line -early)"));

        for (ProValueMap::ConstIterator it = m_extraVars.constBegin();
             it != m_extraVars.constEnd(); ++it)
            m_valuemapStack.front().insert(it.key(), it.value());

        // In case default_pre needs to make decisions based on the current
        // build pass configuration.
        applyExtraConfigs();

        if ((vr = evaluateFeatureFile(QLatin1String("default_pre.prf"))) == ReturnError)
            goto failed;

        if (!m_option->extra_cmds[QMakeEvalBefore].isEmpty()) {
            evaluateCommand(m_option->extra_cmds[QMakeEvalBefore], fL1S("(command line)"));

            // Again, after user configs, to override them
            applyExtraConfigs();
        }
    }

    debugMsg(1, "visiting file %s", qPrintable(pro->fileName()));
    if ((vr = visitProBlock(pro, pro->tokPtr())) == ReturnError)
        goto failed;
    debugMsg(1, "done visiting file %s", qPrintable(pro->fileName()));

    if (flags & LoadPostFiles) {
        evaluateCommand(m_option->extra_cmds[QMakeEvalAfter], fL1S("(command line -after)"));

        // Again, to ensure the project does not mess with us.
        // Specifically, do not allow a project to override debug/release within a
        // debug_and_release build pass - it's too late for that at this point anyway.
        applyExtraConfigs();

        if ((vr = evaluateFeatureFile(QLatin1String("default_post.prf"))) == ReturnError)
            goto failed;

        if (!m_option->extra_cmds[QMakeEvalLate].isEmpty())
            evaluateCommand(m_option->extra_cmds[QMakeEvalLate], fL1S("(command line -late)"));

        if ((vr = evaluateConfigFeatures()) == ReturnError)
            goto failed;
    }
    vr = ReturnTrue;
  failed:
    m_profileStack.pop();
    valuesRef(ProKey("PWD")) = ProStringList(ProString(currentDirectory()));
    m_handler->doneWithEval(currentProFile());

    return vr;
}


void QMakeEvaluator::updateMkspecPaths()
{
    QStringList ret;
    const QString concat = QLatin1String("/mkspecs");

    const auto paths = m_option->getPathListEnv(QLatin1String("QMAKEPATH"));
    for (const QString &it : paths)
        ret << it + concat;

    for (const QString &it : qAsConst(m_qmakepath))
        ret << it + concat;

    if (!m_buildRoot.isEmpty())
        ret << m_buildRoot + concat;
    if (!m_sourceRoot.isEmpty())
        ret << m_sourceRoot + concat;

    ret << m_option->propertyValue(ProKey("QT_HOST_DATA/get")) + concat;
    ret << m_option->propertyValue(ProKey("QT_HOST_DATA/src")) + concat;

    ret.removeDuplicates();
    m_mkspecPaths = ret;
}

void QMakeEvaluator::updateFeaturePaths()
{
    QString mkspecs_concat = QLatin1String("/mkspecs");
    QString features_concat = QLatin1String("/features/");

    QStringList feature_roots;

    feature_roots += m_option->getPathListEnv(QLatin1String("QMAKEFEATURES"));
    feature_roots += m_qmakefeatures;
    feature_roots += m_option->splitPathList(
                m_option->propertyValue(ProKey("QMAKEFEATURES")).toQString());

    QStringList feature_bases;
    if (!m_buildRoot.isEmpty()) {
        feature_bases << m_buildRoot + mkspecs_concat;
        feature_bases << m_buildRoot;
    }
    if (!m_sourceRoot.isEmpty()) {
        feature_bases << m_sourceRoot + mkspecs_concat;
        feature_bases << m_sourceRoot;
    }

    const auto items = m_option->getPathListEnv(QLatin1String("QMAKEPATH"));
    for (const QString &item : items)
        feature_bases << (item + mkspecs_concat);

    for (const QString &item : qAsConst(m_qmakepath))
        feature_bases << (item + mkspecs_concat);

    if (!m_qmakespec.isEmpty()) {
        // The spec is already platform-dependent, so no subdirs here.
        feature_roots << (m_qmakespec + features_concat);

        // Also check directly under the root directory of the mkspecs collection
        QDir specdir(m_qmakespec);
        while (!specdir.isRoot() && specdir.cdUp()) {
            const QString specpath = specdir.path();
            if (specpath.endsWith(mkspecs_concat)) {
                if (IoUtils::exists(specpath + features_concat))
                    feature_bases << specpath;
                break;
            }
        }
    }

    feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/get")) + mkspecs_concat);
    feature_bases << (m_option->propertyValue(ProKey("QT_HOST_DATA/src")) + mkspecs_concat);

    for (const QString &fb : qAsConst(feature_bases)) {
        const auto sfxs = values(ProKey("QMAKE_PLATFORM"));
        for (const ProString &sfx : sfxs)
            feature_roots << (fb + features_concat + sfx + QLatin1Char('/'));
        feature_roots << (fb + features_concat);
    }

    for (int i = 0; i < feature_roots.count(); ++i)
        if (!feature_roots.at(i).endsWith(QLatin1Char('/')))
            feature_roots[i].append(QLatin1Char('/'));

    feature_roots.removeDuplicates();

    QStringList ret;
    for (const QString &root : qAsConst(feature_roots))
        if (IoUtils::exists(root))
            ret << root;
    m_featureRoots = new QMakeFeatureRoots(ret);
}

ProString QMakeEvaluator::propertyValue(const ProKey &name) const
{
    if (name == QLatin1String("QMAKE_MKSPECS"))
        return ProString(m_mkspecPaths.join(m_option->dirlist_sep));
    ProString ret = m_option->propertyValue(name);
//    if (ret.isNull())
//        evalError(fL1S("Querying unknown property %1").arg(name.toQStringView()));
    return ret;
}

ProFile *QMakeEvaluator::currentProFile() const
{
    if (m_profileStack.count() > 0)
        return m_profileStack.top();
    return nullptr;
}

int QMakeEvaluator::currentFileId() const
{
    ProFile *pro = currentProFile();
    if (pro)
        return pro->id();
    return 0;
}

QString QMakeEvaluator::currentFileName() const
{
    ProFile *pro = currentProFile();
    if (pro)
        return pro->fileName();
    return QString();
}

QString QMakeEvaluator::currentDirectory() const
{
    ProFile *pro = currentProFile();
    if (pro)
        return pro->directoryName();
    return QString();
}

bool QMakeEvaluator::isActiveConfig(const QStringRef &config, bool regex)
{
    // magic types for easy flipping
    if (config == statics.strtrue)
        return true;
    if (config == statics.strfalse)
        return false;

    if (config == statics.strhost_build)
        return m_hostBuild;

    if (regex && (config.contains(QLatin1Char('*')) || config.contains(QLatin1Char('?')))) {
        QRegExp re(config.toString(), Qt::CaseSensitive, QRegExp::Wildcard);

        // mkspecs
        if (re.exactMatch(m_qmakespecName))
            return true;

        // CONFIG variable
        const auto configValues = values(statics.strCONFIG);
        for (const ProString &configValue : configValues) {
            ProStringRoUser u1(configValue, m_tmp[m_toggle ^= 1]);
            if (re.exactMatch(u1.str()))
                return true;
        }
    } else {
        // mkspecs
        if (m_qmakespecName == config)
            return true;

        // CONFIG variable
        if (values(statics.strCONFIG).contains(config))
            return true;
    }

    return false;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::expandVariableReferences(
        const ushort *&tokPtr, int sizeHint, ProStringList *ret, bool joined)
{
    ret->reserve(sizeHint);
    forever {
        if (evaluateExpression(tokPtr, ret, joined) == ReturnError)
            return ReturnError;
        switch (*tokPtr) {
        case TokValueTerminator:
        case TokFuncTerminator:
            tokPtr++;
            return ReturnTrue;
        case TokArgSeparator:
            if (joined) {
                tokPtr++;
                continue;
            }
            Q_FALLTHROUGH();
        default:
            Q_ASSERT_X(false, "expandVariableReferences", "Unrecognized token");
            break;
        }
    }
}

QMakeEvaluator::VisitReturn QMakeEvaluator::prepareFunctionArgs(
        const ushort *&tokPtr, QList<ProStringList> *ret)
{
    if (*tokPtr != TokFuncTerminator) {
        for (;; tokPtr++) {
            ProStringList arg;
            if (evaluateExpression(tokPtr, &arg, false) == ReturnError)
                return ReturnError;
            *ret << arg;
            if (*tokPtr == TokFuncTerminator)
                break;
            Q_ASSERT(*tokPtr == TokArgSeparator);
        }
    }
    tokPtr++;
    return ReturnTrue;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFunction(
        const ProFunctionDef &func, const QList<ProStringList> &argumentsList, ProStringList *ret)
{
    VisitReturn vr;

    if (m_valuemapStack.size() >= 100) {
        evalError(fL1S("Ran into infinite recursion (depth > 100)."));
        vr = ReturnError;
    } else {
        m_valuemapStack.push(ProValueMap());
        m_locationStack.push(m_current);

        ProStringList args;
        for (int i = 0; i < argumentsList.count(); ++i) {
            args += argumentsList[i];
            m_valuemapStack.top()[ProKey(QString::number(i+1))] = argumentsList[i];
        }
        m_valuemapStack.top()[statics.strARGS] = args;
        m_valuemapStack.top()[statics.strARGC] = ProStringList(ProString(QString::number(argumentsList.count())));
        vr = visitProBlock(func.pro(), func.tokPtr());
        if (vr == ReturnReturn)
            vr = ReturnTrue;
        if (vr == ReturnTrue)
            *ret = m_returnValue;
        m_returnValue.clear();

        m_current = m_locationStack.pop();
        m_valuemapStack.pop();
    }
    return vr;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBoolFunction(
        const ProFunctionDef &func, const QList<ProStringList> &argumentsList,
        const ProString &function)
{
    ProStringList ret;
    VisitReturn vr = evaluateFunction(func, argumentsList, &ret);
    if (vr == ReturnTrue) {
        if (ret.isEmpty())
            return ReturnTrue;
        if (ret.at(0) != statics.strfalse) {
            if (ret.at(0) == statics.strtrue)
                return ReturnTrue;
            bool ok;
            int val = ret.at(0).toInt(&ok);
            if (ok) {
                if (val)
                    return ReturnTrue;
            } else {
                ProStringRoUser u1(function, m_tmp1);
                evalError(fL1S("Unexpected return value from test '%1': %2.")
                          .arg(u1.str(), ret.join(QLatin1String(" :: "))));
            }
        }
        return ReturnFalse;
    }
    return vr;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
        const ProKey &func, const ushort *&tokPtr)
{
    auto adef = statics.functions.constFind(func);
    if (adef != statics.functions.constEnd()) {
        //why don't the builtin functions just use args_list? --Sam
        ProStringList args;
        if (expandVariableReferences(tokPtr, 5, &args, true) == ReturnError)
            return ReturnError;
        return evaluateBuiltinConditional(*adef, func, args);
    }

    QHash<ProKey, ProFunctionDef>::ConstIterator it =
            m_functionDefs.testFunctions.constFind(func);
    if (it != m_functionDefs.testFunctions.constEnd()) {
        QList<ProStringList> args;
        if (prepareFunctionArgs(tokPtr, &args) == ReturnError)
            return ReturnError;
        traceMsg("calling %s(%s)", dbgKey(func), dbgStrListList(args));
        return evaluateBoolFunction(*it, args, func);
    }

    skipExpression(tokPtr);
    evalError(fL1S("'%1' is not a recognized test function.").arg(func.toQStringView()));
    return ReturnFalse;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateExpandFunction(
        const ProKey &func, const ushort *&tokPtr, ProStringList *ret)
{
    auto adef = statics.expands.constFind(func);
    if (adef != statics.expands.constEnd()) {
        //why don't the builtin functions just use args_list? --Sam
        ProStringList args;
        if (expandVariableReferences(tokPtr, 5, &args, true) == ReturnError)
            return ReturnError;
        return evaluateBuiltinExpand(*adef, func, args, *ret);
    }

    QHash<ProKey, ProFunctionDef>::ConstIterator it =
            m_functionDefs.replaceFunctions.constFind(func);
    if (it != m_functionDefs.replaceFunctions.constEnd()) {
        QList<ProStringList> args;
        if (prepareFunctionArgs(tokPtr, &args) == ReturnError)
            return ReturnError;
        traceMsg("calling $$%s(%s)", dbgKey(func), dbgStrListList(args));
        return evaluateFunction(*it, args, ret);
    }

    skipExpression(tokPtr);
    evalError(fL1S("'%1' is not a recognized replace function.").arg(func.toQStringView()));
    return ReturnFalse;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditional(
        const QStringRef &cond, const QString &where, int line)
{
    VisitReturn ret = ReturnFalse;
    ProFile *pro = m_parser->parsedProBlock(cond, 0, where, line, QMakeParser::TestGrammar);
    if (pro->isOk()) {
        m_locationStack.push(m_current);
        ret = visitProBlock(pro, pro->tokPtr());
        m_current = m_locationStack.pop();
    }
    pro->deref();
    return ret;
}

#ifdef PROEVALUATOR_FULL
QMakeEvaluator::VisitReturn QMakeEvaluator::checkRequirements(const ProStringList &deps)
{
    ProStringList &failed = valuesRef(ProKey("QMAKE_FAILED_REQUIREMENTS"));
    for (const ProString &dep : deps) {
        VisitReturn vr = evaluateConditional(dep.toQStringRef(), m_current.pro->fileName(), m_current.line);
        if (vr == ReturnError)
            return ReturnError;
        if (vr != ReturnTrue)
            failed << dep;
    }
    return ReturnTrue;
}
#endif

static bool isFunctParam(const ProKey &variableName)
{
    const int len = variableName.size();
    const QChar *data = variableName.constData();
    for (int i = 0; i < len; i++) {
        ushort c = data[i].unicode();
        if (c < '0' || c > '9')
            return false;
    }
    return true;
}

ProValueMap *QMakeEvaluator::findValues(const ProKey &variableName, ProValueMap::Iterator *rit)
{
    ProValueMapStack::iterator vmi = m_valuemapStack.end();
    for (bool first = true; ; first = false) {
        --vmi;
        ProValueMap::Iterator it = (*vmi).find(variableName);
        if (it != (*vmi).end()) {
            if (it->constBegin() == statics.fakeValue.constBegin())
                break;
            *rit = it;
            return &(*vmi);
        }
        if (vmi == m_valuemapStack.begin())
            break;
        if (first && isFunctParam(variableName))
            break;
    }
    return nullptr;
}

ProStringList &QMakeEvaluator::valuesRef(const ProKey &variableName)
{
    ProValueMap::Iterator it = m_valuemapStack.top().find(variableName);
    if (it != m_valuemapStack.top().end()) {
        if (it->constBegin() == statics.fakeValue.constBegin())
            it->clear();
        return *it;
    }
    if (!isFunctParam(variableName)) {
        ProValueMapStack::iterator vmi = m_valuemapStack.end();
        if (--vmi != m_valuemapStack.begin()) {
            do {
                --vmi;
                ProValueMap::ConstIterator it = (*vmi).constFind(variableName);
                if (it != (*vmi).constEnd()) {
                    ProStringList &ret = m_valuemapStack.top()[variableName];
                    if (it->constBegin() != statics.fakeValue.constBegin())
                        ret = *it;
                    return ret;
                }
            } while (vmi != m_valuemapStack.begin());
        }
    }
    return m_valuemapStack.top()[variableName];
}

ProStringList QMakeEvaluator::values(const ProKey &variableName) const
{
    ProValueMapStack::const_iterator vmi = m_valuemapStack.cend();
    for (bool first = true; ; first = false) {
        --vmi;
        ProValueMap::ConstIterator it = (*vmi).constFind(variableName);
        if (it != (*vmi).constEnd()) {
            if (it->constBegin() == statics.fakeValue.constBegin())
                break;
            return *it;
        }
        if (vmi == m_valuemapStack.cbegin())
            break;
        if (first && isFunctParam(variableName))
            break;
    }
    return ProStringList();
}

ProString QMakeEvaluator::first(const ProKey &variableName) const
{
    const ProStringList &vals = values(variableName);
    if (!vals.isEmpty())
        return vals.first();
    return ProString();
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFile(
        const QString &fileName, QMakeHandler::EvalFileType type, LoadFlags flags)
{
    QMakeParser::ParseFlags pflags = QMakeParser::ParseUseCache;
    if (!(flags & LoadSilent))
        pflags |= QMakeParser::ParseReportMissing;
    if (ProFile *pro = m_parser->parsedProFile(fileName, pflags)) {
        m_locationStack.push(m_current);
        VisitReturn ok = visitProFile(pro, type, flags);
        m_current = m_locationStack.pop();
        pro->deref();
        if (ok == ReturnTrue && !(flags & LoadHidden)) {
            ProStringList &iif = m_valuemapStack.front()[ProKey("QMAKE_INTERNAL_INCLUDED_FILES")];
            ProString ifn(fileName);
            if (!iif.contains(ifn))
                iif << ifn;
        }
        return ok;
    } else {
        return ReturnFalse;
    }
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFileChecked(
        const QString &fileName, QMakeHandler::EvalFileType type, LoadFlags flags)
{
    if (fileName.isEmpty())
        return ReturnFalse;
    const QMakeEvaluator *ref = this;
    do {
        for (const ProFile *pf : ref->m_profileStack)
            if (pf->fileName() == fileName) {
                evalError(fL1S("Circular inclusion of %1.").arg(fileName));
                return ReturnFalse;
            }
    } while ((ref = ref->m_caller));
    return evaluateFile(fileName, type, flags);
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
        const QString &fileName, bool silent)
{
    QString fn = fileName;
    if (!fn.endsWith(QLatin1String(".prf")))
        fn += QLatin1String(".prf");

    if (!m_featureRoots)
        updateFeaturePaths();
#ifdef PROEVALUATOR_THREAD_SAFE
    m_featureRoots->mutex.lock();
#endif
    QString currFn = currentFileName();
    if (IoUtils::fileName(currFn) != IoUtils::fileName(fn))
        currFn.clear();
    // Null values cannot regularly exist in the hash, so they indicate that the value still
    // needs to be determined. Failed lookups are represented via non-null empty strings.
    QString *fnp = &m_featureRoots->cache[qMakePair(fn, currFn)];
    if (fnp->isNull()) {
#ifdef QMAKE_OVERRIDE_PRFS
        {
            QString ovrfn(QLatin1String(":/qmake/override_features/") + fn);
            if (QFileInfo::exists(ovrfn)) {
                fn = ovrfn;
                goto cool;
            }
        }
#endif
        {
            int start_root = 0;
            const QStringList &paths = m_featureRoots->paths;
            if (!currFn.isEmpty()) {
                QStringRef currPath = IoUtils::pathName(currFn);
                for (int root = 0; root < paths.size(); ++root)
                    if (currPath == paths.at(root)) {
                        start_root = root + 1;
                        break;
                    }
            }
            for (int root = start_root; root < paths.size(); ++root) {
                QString fname = paths.at(root) + fn;
                if (IoUtils::exists(fname)) {
                    fn = fname;
                    goto cool;
                }
            }
        }
#ifdef QMAKE_BUILTIN_PRFS
        fn.prepend(QLatin1String(":/qmake/features/"));
        if (QFileInfo::exists(fn))
            goto cool;
#endif
        fn = QLatin1String(""); // Indicate failed lookup. See comment above.

      cool:
        *fnp = fn;
    } else {
        fn = *fnp;
    }
#ifdef PROEVALUATOR_THREAD_SAFE
    m_featureRoots->mutex.unlock();
#endif
    if (fn.isEmpty()) {
        if (!silent)
            evalError(fL1S("Cannot find feature %1").arg(fileName));
        return ReturnFalse;
    }
    ProStringList &already = valuesRef(ProKey("QMAKE_INTERNAL_INCLUDED_FEATURES"));
    ProString afn(fn);
    if (already.contains(afn)) {
        if (!silent)
            languageWarning(fL1S("Feature %1 already included").arg(fileName));
        return ReturnTrue;
    }
    already.append(afn);

#ifdef PROEVALUATOR_CUMULATIVE
    bool cumulative = m_cumulative;
    m_cumulative = false;
#endif

    // The path is fully normalized already.
    VisitReturn ok = evaluateFile(fn, QMakeHandler::EvalFeatureFile, LoadProOnly);

#ifdef PROEVALUATOR_CUMULATIVE
    m_cumulative = cumulative;
#endif
    return ok;
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFileInto(
        const QString &fileName, ProValueMap *values, LoadFlags flags)
{
    QMakeEvaluator visitor(m_option, m_parser, m_vfs, m_handler);
    visitor.m_caller = this;
    visitor.m_outputDir = m_outputDir;
    visitor.m_featureRoots = m_featureRoots;
    VisitReturn ret = visitor.evaluateFileChecked(fileName, QMakeHandler::EvalAuxFile, flags);
    if (ret != ReturnTrue)
        return ret;
    *values = visitor.m_valuemapStack.top();
    ProKey qiif("QMAKE_INTERNAL_INCLUDED_FILES");
    ProStringList &iif = m_valuemapStack.front()[qiif];
    const auto ifns = values->value(qiif);
    for (const ProString &ifn : ifns)
        if (!iif.contains(ifn))
            iif << ifn;
    return ReturnTrue;
}

void QMakeEvaluator::message(int type, const QString &msg) const
{
    if (!m_skipLevel)
        m_handler->message(type | (m_cumulative ? QMakeHandler::CumulativeEvalMessage : 0), msg,
                m_current.line ? m_current.pro->fileName() : QString(),
                m_current.line != 0xffff ? m_current.line : -1);
}

#ifdef PROEVALUATOR_DEBUG
void QMakeEvaluator::debugMsgInternal(int level, const char *fmt, ...) const
{
    va_list ap;

    if (level <= m_debugLevel) {
        fprintf(stderr, "DEBUG %d: ", level);
        va_start(ap, fmt);
        vfprintf(stderr, fmt, ap);
        va_end(ap);
        fputc('\n', stderr);
    }
}

void QMakeEvaluator::traceMsgInternal(const char *fmt, ...) const
{
    va_list ap;

    if (!m_current.pro)
        fprintf(stderr, "DEBUG 1: ");
    else if (m_current.line <= 0)
        fprintf(stderr, "DEBUG 1: %s: ", qPrintable(m_current.pro->fileName()));
    else
        fprintf(stderr, "DEBUG 1: %s:%d: ", qPrintable(m_current.pro->fileName()), m_current.line);
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
    fputc('\n', stderr);
}

QString QMakeEvaluator::formatValue(const ProString &val, bool forceQuote)
{
    QString ret;
    ret.reserve(val.size() + 2);
    const QChar *chars = val.constData();
    bool quote = forceQuote || val.isEmpty();
    for (int i = 0, l = val.size(); i < l; i++) {
        QChar c = chars[i];
        ushort uc = c.unicode();
        if (uc < 32) {
            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 {
            switch (uc) {
            case '\\':
                ret += QLatin1String("\\\\");
                break;
            case '"':
                ret += QLatin1String("\\\"");
                break;
            case '\'':
                ret += QLatin1String("\\'");
                break;
            case 32:
                quote = true;
                Q_FALLTHROUGH();
            default:
                ret += c;
                break;
            }
        }
    }
    if (quote) {
        ret.prepend(QLatin1Char('"'));
        ret.append(QLatin1Char('"'));
    }
    return ret;
}

QString QMakeEvaluator::formatValueList(const ProStringList &vals, bool commas)
{
    QString ret;

    for (const ProString &str : vals) {
        if (!ret.isEmpty()) {
            if (commas)
                ret += QLatin1Char(',');
            ret += QLatin1Char(' ');
        }
        ret += formatValue(str);
    }
    return ret;
}

QString QMakeEvaluator::formatValueListList(const QList<ProStringList> &lists)
{
    QString ret;

    for (const ProStringList &list : lists) {
        if (!ret.isEmpty())
            ret += QLatin1String(", ");
        ret += formatValueList(list);
    }
    return ret;
}
#endif

QT_END_NAMESPACE
