/****************************************************************************
**
** 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, Qt::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(';'), Qt::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
