/****************************************************************************
**
** 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 "qmakeparser.h"

#include "qmakevfs.h"
#include "ioutils.h"
using namespace QMakeInternal;

#include <qfile.h>
#ifdef PROPARSER_THREAD_SAFE
# include <qthreadpool.h>
#endif

QT_BEGIN_NAMESPACE

///////////////////////////////////////////////////////////////////////
//
// ProFileCache
//
///////////////////////////////////////////////////////////////////////

ProFileCache::ProFileCache()
{
    QMakeVfs::ref();
}

ProFileCache::~ProFileCache()
{
    for (const Entry &ent : qAsConst(parsed_files))
        if (ent.pro)
            ent.pro->deref();
    QMakeVfs::deref();
}

void ProFileCache::discardFile(const QString &fileName, QMakeVfs *vfs)
{
    int eid = vfs->idForFileName(fileName, QMakeVfs::VfsExact | QMakeVfs::VfsAccessedOnly);
    if (eid)
        discardFile(eid);
    int cid = vfs->idForFileName(fileName, QMakeVfs::VfsCumulative | QMakeVfs::VfsAccessedOnly);
    if (cid && cid != eid)
        discardFile(cid);
}

void ProFileCache::discardFile(int id)
{
#ifdef PROPARSER_THREAD_SAFE
    QMutexLocker lck(&mutex);
#endif
    auto it = parsed_files.find(id);
    if (it != parsed_files.end()) {
#ifdef PROPARSER_THREAD_SAFE
        if (it->locker) {
            if (!it->locker->done) {
                ++it->locker->waiters;
                it->locker->cond.wait(&mutex);
                if (!--it->locker->waiters) {
                    delete it->locker;
                    it->locker = 0;
                }
            }
        }
#endif
        if (it->pro)
            it->pro->deref();
        parsed_files.erase(it);
    }
}

void ProFileCache::discardFiles(const QString &prefix, QMakeVfs *vfs)
{
#ifdef PROPARSER_THREAD_SAFE
    QMutexLocker lck(&mutex);
#endif
    auto it = parsed_files.begin(), end = parsed_files.end();
    while (it != end) {
        // Note: this is empty for virtual files from other VFSes.
        QString fn = vfs->fileNameForId(it.key());
        if (fn.startsWith(prefix)) {
#ifdef PROPARSER_THREAD_SAFE
            if (it->locker) {
                if (!it->locker->done) {
                    ++it->locker->waiters;
                    it->locker->cond.wait(&mutex);
                    if (!--it->locker->waiters) {
                        delete it->locker;
                        it->locker = 0;
                    }
                }
            }
#endif
            if (it->pro)
                it->pro->deref();
            it = parsed_files.erase(it);
        } else {
            ++it;
        }
    }
}

////////// Parser ///////////

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

namespace { // MSVC2010 doesn't seem to know the semantics of "static" ...

static struct {
    QString strelse;
    QString strfor;
    QString strdefineTest;
    QString strdefineReplace;
    QString strbypassNesting;
    QString stroption;
    QString strreturn;
    QString strnext;
    QString strbreak;
    QString strhost_build;
    QString strLINE;
    QString strFILE;
    QString strLITERAL_HASH;
    QString strLITERAL_DOLLAR;
    QString strLITERAL_WHITESPACE;
} statics;

}

void QMakeParser::initialize()
{
    if (!statics.strelse.isNull())
        return;

    statics.strelse = QLatin1String("else");
    statics.strfor = QLatin1String("for");
    statics.strdefineTest = QLatin1String("defineTest");
    statics.strdefineReplace = QLatin1String("defineReplace");
    statics.strbypassNesting = QLatin1String("bypassNesting");
    statics.stroption = QLatin1String("option");
    statics.strreturn = QLatin1String("return");
    statics.strnext = QLatin1String("next");
    statics.strbreak = QLatin1String("break");
    statics.strhost_build = QLatin1String("host_build");
    statics.strLINE = QLatin1String("_LINE_");
    statics.strFILE = QLatin1String("_FILE_");
    statics.strLITERAL_HASH = QLatin1String("LITERAL_HASH");
    statics.strLITERAL_DOLLAR = QLatin1String("LITERAL_DOLLAR");
    statics.strLITERAL_WHITESPACE = QLatin1String("LITERAL_WHITESPACE");
}

QMakeParser::QMakeParser(ProFileCache *cache, QMakeVfs *vfs, QMakeParserHandler *handler)
    : m_cache(cache)
    , m_handler(handler)
    , m_vfs(vfs)
{
    // So that single-threaded apps don't have to call initialize() for now.
    initialize();
}

ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
{
    ProFile *pro;
    QMakeVfs::VfsFlags vfsFlags = ((flags & ParseCumulative) ? QMakeVfs::VfsCumulative
                                                             : QMakeVfs::VfsExact);
    int id = m_vfs->idForFileName(fileName, vfsFlags);
    if ((flags & ParseUseCache) && m_cache) {
        ProFileCache::Entry *ent;
#ifdef PROPARSER_THREAD_SAFE
        QMutexLocker locker(&m_cache->mutex);
#endif
        auto it = m_cache->parsed_files.find(id);
        if (it != m_cache->parsed_files.end()) {
            ent = &*it;
#ifdef PROPARSER_THREAD_SAFE
            if (ent->locker && !ent->locker->done) {
                ++ent->locker->waiters;
                QThreadPool::globalInstance()->releaseThread();
                ent->locker->cond.wait(locker.mutex());
                QThreadPool::globalInstance()->reserveThread();
                if (!--ent->locker->waiters) {
                    delete ent->locker;
                    ent->locker = 0;
                }
            }
#endif
            if ((pro = ent->pro))
                pro->ref();
        } else {
            ent = &m_cache->parsed_files[id];
#ifdef PROPARSER_THREAD_SAFE
            ent->locker = new ProFileCache::Entry::Locker;
            locker.unlock();
#endif
            QString contents;
            if (readFile(id, flags, &contents)) {
                pro = parsedProBlock(QStringRef(&contents), id, fileName, 1, FullGrammar);
                pro->itemsRef()->squeeze();
                pro->ref();
            } else {
                pro = nullptr;
            }
            ent->pro = pro;
#ifdef PROPARSER_THREAD_SAFE
            locker.relock();
            if (ent->locker->waiters) {
                ent->locker->done = true;
                ent->locker->cond.wakeAll();
            } else {
                delete ent->locker;
                ent->locker = 0;
            }
#endif
        }
    } else {
        QString contents;
        if (readFile(id, flags, &contents))
            pro = parsedProBlock(QStringRef(&contents), id, fileName, 1, FullGrammar);
        else
            pro = nullptr;
    }
    return pro;
}

ProFile *QMakeParser::parsedProBlock(
        const QStringRef &contents, int id, const QString &name, int line, SubGrammar grammar)
{
    ProFile *pro = new ProFile(id, name);
    read(pro, contents, line, grammar);
    return pro;
}

void QMakeParser::discardFileFromCache(int id)
{
    if (m_cache)
        m_cache->discardFile(id);
}

bool QMakeParser::readFile(int id, ParseFlags flags, QString *contents)
{
    QString errStr;
    QMakeVfs::ReadResult result = m_vfs->readFile(id, contents, &errStr);
    if (result != QMakeVfs::ReadOk) {
        if (m_handler && ((flags & ParseReportMissing) || result != QMakeVfs::ReadNotFound))
            m_handler->message(QMakeParserHandler::ParserIoError,
                               fL1S("Cannot read %1: %2").arg(m_vfs->fileNameForId(id), errStr));
        return false;
    }
    return true;
}

void QMakeParser::putTok(ushort *&tokPtr, ushort tok)
{
    *tokPtr++ = tok;
}

void QMakeParser::putBlockLen(ushort *&tokPtr, uint len)
{
    *tokPtr++ = (ushort)len;
    *tokPtr++ = (ushort)(len >> 16);
}

void QMakeParser::putBlock(ushort *&tokPtr, const ushort *buf, uint len)
{
    memcpy(tokPtr, buf, len * 2);
    tokPtr += len;
}

void QMakeParser::putHashStr(ushort *&pTokPtr, const ushort *buf, uint len)
{
    uint hash = ProString::hash((const QChar *)buf, len);
    ushort *tokPtr = pTokPtr;
    *tokPtr++ = (ushort)hash;
    *tokPtr++ = (ushort)(hash >> 16);
    *tokPtr++ = (ushort)len;
    if (len) // buf may be nullptr; don't pass that to memcpy (-> undefined behavior)
        memcpy(tokPtr, buf, len * 2);
    pTokPtr = tokPtr + len;
}

void QMakeParser::finalizeHashStr(ushort *buf, uint len)
{
    buf[-4] = TokHashLiteral;
    buf[-1] = len;
    uint hash = ProString::hash((const QChar *)buf, len);
    buf[-3] = (ushort)hash;
    buf[-2] = (ushort)(hash >> 16);
}

void QMakeParser::read(ProFile *pro, const QStringRef &in, int line, SubGrammar grammar)
{
    m_proFile = pro;
    m_lineNo = line;

    // Final precompiled token stream buffer
    QString tokBuff;
    // Worst-case size calculations:
    // - line marker adds 1 (2-nl) to 1st token of each line
    // - empty assignment "A=":2 =>
    //   TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) + size_hint(1) +
    //   TokValueTerminator(1) == 8 (9)
    // - non-empty assignment "A=B C":5 =>
    //   TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokAssign(1) + size_hint(1) +
    //   TokLiteral(1) + len(1) + "B"(1) +
    //   TokLiteral(1) + len(1) + "C"(1) + TokValueTerminator(1) == 14 (15)
    // - variable expansion: "$$f":3 =>
    //   TokVariable(1) + hash(2) + len(1) + "f"(1) = 5
    // - function expansion: "$$f()":5 =>
    //   TokFuncName(1) + hash(2) + len(1) + "f"(1) + TokFuncTerminator(1) = 6
    // - test literal: "X":1 =>
    //   TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokCondition(1) = 6 (7)
    // - scope: "X:":2 =>
    //   TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokCondition(1) +
    //   TokBranch(1) + len(2) + ... + len(2) + ... == 11 (12)
    // - test call: "X():":4 =>
    //   TokHashLiteral(1) + hash(2) + len(1) + "A"(1) + TokTestCall(1) + TokFuncTerminator(1) +
    //   TokBranch(1) + len(2) + ... + len(2) + ... == 12 (13)
    // - "for(A,B):":9 =>
    //   TokForLoop(1) + hash(2) + len(1) + "A"(1) +
    //   len(2) + TokLiteral(1) + len(1) + "B"(1) + TokValueTerminator(1) +
    //   len(2) + ... + TokTerminator(1) == 14 (15)
    // One extra for possibly missing trailing newline.
    tokBuff.reserve((in.size() + 1) * 7);
    ushort *tokPtr = (ushort *)tokBuff.constData(); // Current writing position

    // Expression precompiler buffer.
    QString xprBuff;
    xprBuff.reserve(tokBuff.capacity()); // Excessive, but simple
    ushort *buf = (ushort *)xprBuff.constData();

    // Parser state
    m_blockstack.clear();
    m_blockstack.resize(1);

    QStack<ParseCtx> xprStack;
    xprStack.reserve(10);

    const ushort *cur = (const ushort *)in.unicode();
    const ushort *inend = cur + in.length();
    m_canElse = false;
  freshLine:
    m_state = StNew;
    m_invert = 0;
    m_operator = NoOperator;
    m_markLine = m_lineNo;
    m_inError = false;
    int parens = 0; // Braces in value context
    int argc = 0;
    int wordCount = 0; // Number of words in currently accumulated expression
    int lastIndent = 0; // Previous line's indentation, to detect accidental continuation abuse
    bool lineMarked = true; // For in-expression markers
    ushort needSep = TokNewStr; // Met unquoted whitespace
    ushort quote = 0;
    ushort term = 0;

    Context context;
    ushort *ptr;
    if (grammar == ValueGrammar) {
        context = CtxPureValue;
        ptr = tokPtr + 2;
    } else {
        context = CtxTest;
        ptr = buf + 4;
    }
    ushort *xprPtr = ptr;

#define FLUSH_LHS_LITERAL() \
    do { \
        if ((tlen = ptr - xprPtr)) { \
            finalizeHashStr(xprPtr, tlen); \
            if (needSep) { \
                wordCount++; \
                needSep = 0; \
            } \
        } else { \
            ptr -= 4; \
        } \
    } while (0)

#define FLUSH_RHS_LITERAL() \
    do { \
        if ((tlen = ptr - xprPtr)) { \
            xprPtr[-2] = TokLiteral | needSep; \
            xprPtr[-1] = tlen; \
            if (needSep) { \
                wordCount++; \
                needSep = 0; \
            } \
        } else { \
            ptr -= 2; \
        } \
    } while (0)

#define FLUSH_LITERAL() \
    do { \
        if (context == CtxTest) \
            FLUSH_LHS_LITERAL(); \
        else \
            FLUSH_RHS_LITERAL(); \
    } while (0)

#define FLUSH_VALUE_LIST() \
    do { \
        if (wordCount > 1) { \
            xprPtr = tokPtr; \
            if (*xprPtr == TokLine) \
                xprPtr += 2; \
            tokPtr[-1] = ((*xprPtr & TokMask) == TokLiteral) ? wordCount : 0; \
        } else { \
            tokPtr[-1] = 0; \
        } \
        tokPtr = ptr; \
        putTok(tokPtr, TokValueTerminator); \
    } while (0)

    const ushort *end; // End of this line
    const ushort *cptr; // Start of next line
    bool lineCont;
    int indent;

    if (context == CtxPureValue) {
        end = inend;
        cptr = nullptr;
        lineCont = false;
        indent = 0; // just gcc being stupid
        goto nextChr;
    }

    forever {
        ushort c;

        // First, skip leading whitespace
        for (indent = 0; ; ++cur, ++indent) {
            if (cur == inend) {
                cur = nullptr;
                goto flushLine;
            }
            c = *cur;
            if (c == '\n') {
                ++cur;
                goto flushLine;
            }
            if (c != ' ' && c != '\t' && c != '\r')
                break;
        }

        // Then strip comments. Yep - no escaping is possible.
        for (cptr = cur;; ++cptr) {
            if (cptr == inend) {
                end = cptr;
                break;
            }
            c = *cptr;
            if (c == '#') {
                end = cptr;
                while (++cptr < inend) {
                    if (*cptr == '\n') {
                        ++cptr;
                        break;
                    }
                }
                if (end == cur) { // Line with only a comment (sans whitespace)
                    if (m_markLine == m_lineNo)
                        m_markLine++;
                    // Qmake bizarreness: such lines do not affect line continuations
                    goto ignore;
                }
                break;
            }
            if (c == '\n') {
                end = cptr++;
                break;
            }
        }

        // Then look for line continuations. Yep - no escaping here as well.
        forever {
            // We don't have to check for underrun here, as we already determined
            // that the line is non-empty.
            ushort ec = *(end - 1);
            if (ec == '\\') {
                --end;
                lineCont = true;
                break;
            }
            if (ec != ' ' && ec != '\t' && ec != '\r') {
                lineCont = false;
                break;
            }
            --end;
        }

            // Finally, do the tokenization
            ushort tok, rtok;
            int tlen;
          newWord:
            do {
                if (cur == end)
                    goto lineEnd;
                c = *cur++;
            } while (c == ' ' || c == '\t');
            forever {
                if (c == '$') {
                    if (*cur == '$') { // may be EOF, EOL, WS, '#' or '\\' if past end
                        cur++;
                        FLUSH_LITERAL();
                        if (!lineMarked) {
                            lineMarked = true;
                            *ptr++ = TokLine;
                            *ptr++ = (ushort)m_lineNo;
                        }
                        term = 0;
                        tok = TokVariable;
                        c = *cur;
                        if (c == '[') {
                            ptr += 4;
                            tok = TokProperty;
                            term = ']';
                            c = *++cur;
                        } else if (c == '{') {
                            ptr += 4;
                            term = '}';
                            c = *++cur;
                        } else if (c == '(') {
                            ptr += 2;
                            tok = TokEnvVar;
                            term = ')';
                            c = *++cur;
                        } else {
                            ptr += 4;
                        }
                        xprPtr = ptr;
                        rtok = tok;
                        while ((c & 0xFF00) || c == '.' || c == '_' ||
                               (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
                               (c >= '0' && c <= '9') || (c == '/' && term)) {
                            *ptr++ = c;
                            if (++cur == end) {
                                c = 0;
                                goto notfunc;
                            }
                            c = *cur;
                        }
                        if (tok == TokVariable && c == '(')
                            tok = TokFuncName;
                      notfunc:
                        if (ptr == xprPtr)
                            languageWarning(fL1S("Missing name in expansion"));
                        if (quote)
                            tok |= TokQuoted;
                        if (needSep) {
                            tok |= needSep;
                            wordCount++;
                        }
                        tlen = ptr - xprPtr;
                        if (rtok != TokVariable
                            || !resolveVariable(xprPtr, tlen, needSep, &ptr,
                                                &buf, &xprBuff, &tokPtr, &tokBuff, cur, in)) {
                            if (rtok == TokVariable || rtok == TokProperty) {
                                xprPtr[-4] = tok;
                                uint hash = ProString::hash((const QChar *)xprPtr, tlen);
                                xprPtr[-3] = (ushort)hash;
                                xprPtr[-2] = (ushort)(hash >> 16);
                                xprPtr[-1] = tlen;
                            } else {
                                xprPtr[-2] = tok;
                                xprPtr[-1] = tlen;
                            }
                        }
                        if ((tok & TokMask) == TokFuncName) {
                            cur++;
                          funcCall:
                            {
                                xprStack.resize(xprStack.size() + 1);
                                ParseCtx &top = xprStack.top();
                                top.parens = parens;
                                top.quote = quote;
                                top.terminator = term;
                                top.context = context;
                                top.argc = argc;
                                top.wordCount = wordCount;
                            }
                            parens = 0;
                            quote = 0;
                            term = 0;
                            argc = 1;
                            context = CtxArgs;
                          nextToken:
                            wordCount = 0;
                          nextWord:
                            ptr += (context == CtxTest) ? 4 : 2;
                            xprPtr = ptr;
                            needSep = TokNewStr;
                            goto newWord;
                        }
                        if (term) {
                          checkTerm:
                            if (c != term) {
                                parseError(fL1S("Missing %1 terminator [found %2]")
                                    .arg(QChar(term))
                                    .arg(c ? QString(QChar(c)) : QString::fromLatin1("end-of-line")));
                                m_inError = true;
                                // Just parse on, as if there was a terminator ...
                            } else {
                                cur++;
                            }
                        }
                      joinToken:
                        ptr += (context == CtxTest) ? 4 : 2;
                        xprPtr = ptr;
                        needSep = 0;
                        goto nextChr;
                    }
                } else if (c == '\\') {
                    static const char symbols[] = "[]{}()$\\'\"";
                    ushort c2;
                    if (cur != end && !((c2 = *cur) & 0xff00) && strchr(symbols, c2)) {
                        c = c2;
                        cur++;
                    } else {
                        deprecationWarning(fL1S("Unescaped backslashes are deprecated"));
                    }
                } else if (quote) {
                    if (c == quote) {
                        quote = 0;
                        goto nextChr;
                    } else if (c == '!' && ptr == xprPtr && context == CtxTest) {
                        m_invert++;
                        goto nextChr;
                    }
                } else if (c == '\'' || c == '"') {
                    quote = c;
                    goto nextChr;
                } else if (context == CtxArgs) {
                    // Function arg context
                    if (c == ' ' || c == '\t') {
                        FLUSH_RHS_LITERAL();
                        goto nextWord;
                    } else if (c == '(') {
                        ++parens;
                    } else if (c == ')') {
                        if (--parens < 0) {
                            FLUSH_RHS_LITERAL();
                            *ptr++ = TokFuncTerminator;
                            int theargc = argc;
                            {
                                ParseCtx &top = xprStack.top();
                                parens = top.parens;
                                quote = top.quote;
                                term = top.terminator;
                                context = top.context;
                                argc = top.argc;
                                wordCount = top.wordCount;
                                xprStack.resize(xprStack.size() - 1);
                            }
                            if (term == ':') {
                                finalizeCall(tokPtr, buf, ptr, theargc);
                                goto nextItem;
                            } else if (term == '}') {
                                c = (cur == end) ? 0 : *cur;
                                goto checkTerm;
                            } else {
                                Q_ASSERT(!term);
                                goto joinToken;
                            }
                        }
                    } else if (!parens && c == ',') {
                        FLUSH_RHS_LITERAL();
                        *ptr++ = TokArgSeparator;
                        argc++;
                        goto nextToken;
                    }
                } else if (context == CtxTest) {
                    // Test or LHS context
                    if (c == ' ' || c == '\t') {
                        FLUSH_LHS_LITERAL();
                        goto nextWord;
                    } else if (c == '(') {
                        FLUSH_LHS_LITERAL();
                        if (wordCount != 1) {
                            if (wordCount)
                                parseError(fL1S("Extra characters after test expression."));
                            else
                                parseError(fL1S("Opening parenthesis without prior test name."));
                            ptr = buf; // Put empty function name
                        }
                        *ptr++ = TokTestCall;
                        term = ':';
                        goto funcCall;
                    } else if (c == '!' && ptr == xprPtr) {
                        m_invert++;
                        goto nextChr;
                    } else if (c == ':') {
                        FLUSH_LHS_LITERAL();
                        finalizeCond(tokPtr, buf, ptr, wordCount);
                        warnOperator("in front of AND operator");
                        if (m_state == StNew)
                            parseError(fL1S("AND operator without prior condition."));
                        else
                            m_operator = AndOperator;
                      nextItem:
                        ptr = buf;
                        goto nextToken;
                    } else if (c == '|') {
                        FLUSH_LHS_LITERAL();
                        finalizeCond(tokPtr, buf, ptr, wordCount);
                        warnOperator("in front of OR operator");
                        if (m_state != StCond)
                            parseError(fL1S("OR operator without prior condition."));
                        else
                            m_operator = OrOperator;
                        goto nextItem;
                    } else if (c == '{') {
                        FLUSH_LHS_LITERAL();
                        finalizeCond(tokPtr, buf, ptr, wordCount);
                        if (m_operator == AndOperator) {
                            languageWarning(fL1S("Excess colon in front of opening brace."));
                            m_operator = NoOperator;
                        }
                        failOperator("in front of opening brace");
                        flushCond(tokPtr);
                        m_state = StNew; // Reset possible StCtrl, so colons get rejected.
                        ++m_blockstack.top().braceLevel;
                        if (grammar == TestGrammar)
                            parseError(fL1S("Opening scope not permitted in this context."));
                        goto nextItem;
                    } else if (c == '}') {
                        FLUSH_LHS_LITERAL();
                        finalizeCond(tokPtr, buf, ptr, wordCount);
                        m_state = StNew; // De-facto newline
                      closeScope:
                        flushScopes(tokPtr);
                        failOperator("in front of closing brace");
                        if (!m_blockstack.top().braceLevel) {
                            parseError(fL1S("Excess closing brace."));
                        } else if (!--m_blockstack.top().braceLevel
                                   && m_blockstack.count() != 1) {
                            leaveScope(tokPtr);
                            m_state = StNew;
                            m_canElse = false;
                            m_markLine = m_lineNo;
                        }
                        goto nextItem;
                    } else if (c == '+') {
                        tok = TokAppend;
                        goto do2Op;
                    } else if (c == '-') {
                        tok = TokRemove;
                        goto do2Op;
                    } else if (c == '*') {
                        tok = TokAppendUnique;
                        goto do2Op;
                    } else if (c == '~') {
                        tok = TokReplace;
                      do2Op:
                        if (*cur == '=') {
                            cur++;
                            goto doOp;
                        }
                    } else if (c == '=') {
                        tok = TokAssign;
                      doOp:
                        FLUSH_LHS_LITERAL();
                        flushCond(tokPtr);
                        acceptColon("in front of assignment");
                        putLineMarker(tokPtr);
                        if (grammar == TestGrammar) {
                            parseError(fL1S("Assignment not permitted in this context."));
                        } else if (wordCount != 1) {
                            parseError(fL1S("Assignment needs exactly one word on the left hand side."));
                            // Put empty variable name.
                        } else {
                            putBlock(tokPtr, buf, ptr - buf);
                        }
                        putTok(tokPtr, tok);
                        context = CtxValue;
                        ptr = ++tokPtr;
                        goto nextToken;
                    }
                } else if (context == CtxValue) {
                    if (c == ' ' || c == '\t') {
                        FLUSH_RHS_LITERAL();
                        goto nextWord;
                    } else if (c == '{') {
                        ++parens;
                    } else if (c == '}') {
                        if (!parens) {
                            FLUSH_RHS_LITERAL();
                            FLUSH_VALUE_LIST();
                            context = CtxTest;
                            goto closeScope;
                        }
                        --parens;
                    } else if (c == '=') {
                        if (indent < lastIndent)
                            languageWarning(fL1S("Possible accidental line continuation"));
                    }
                }
                *ptr++ = c;
              nextChr:
                if (cur == end)
                    goto lineEnd;
                c = *cur++;
            }

          lineEnd:
            if (lineCont) {
                if (quote) {
                    *ptr++ = ' ';
                } else {
                    FLUSH_LITERAL();
                    needSep = TokNewStr;
                    ptr += (context == CtxTest) ? 4 : 2;
                    xprPtr = ptr;
                }
            } else {
                cur = cptr;
              flushLine:
                FLUSH_LITERAL();
                if (quote) {
                    parseError(fL1S("Missing closing %1 quote").arg(QChar(quote)));
                    if (!xprStack.isEmpty()) {
                        context = xprStack.at(0).context;
                        xprStack.clear();
                    }
                    goto flErr;
                } else if (!xprStack.isEmpty()) {
                    parseError(fL1S("Missing closing parenthesis in function call"));
                    context = xprStack.at(0).context;
                    xprStack.clear();
                  flErr:
                    pro->setOk(false);
                    if (context == CtxValue) {
                        tokPtr[-1] = 0; // sizehint
                        putTok(tokPtr, TokValueTerminator);
                    } else if (context == CtxPureValue) {
                        putTok(tokPtr, TokValueTerminator);
                    } else {
                        bogusTest(tokPtr, QString());
                    }
                } else if (context == CtxValue) {
                    FLUSH_VALUE_LIST();
                    if (parens)
                        languageWarning(fL1S("Possible braces mismatch"));
                } else if (context == CtxPureValue) {
                    tokPtr = ptr;
                    putTok(tokPtr, TokValueTerminator);
                } else {
                    finalizeCond(tokPtr, buf, ptr, wordCount);
                    warnOperator("at end of line");
                }
                if (!cur)
                    break;
                ++m_lineNo;
                goto freshLine;
            }

        lastIndent = indent;
        lineMarked = false;
      ignore:
        cur = cptr;
        ++m_lineNo;
    }

    flushScopes(tokPtr);
    if (m_blockstack.size() > 1 || m_blockstack.top().braceLevel)
        parseError(fL1S("Missing closing brace(s)."));
    while (m_blockstack.size())
        leaveScope(tokPtr);
    tokBuff.resize(tokPtr - (ushort *)tokBuff.constData()); // Reserved capacity stays
    *pro->itemsRef() = tokBuff;

#undef FLUSH_VALUE_LIST
#undef FLUSH_LITERAL
#undef FLUSH_LHS_LITERAL
#undef FLUSH_RHS_LITERAL
}

void QMakeParser::putLineMarker(ushort *&tokPtr)
{
    if (m_markLine) {
        *tokPtr++ = TokLine;
        *tokPtr++ = (ushort)m_markLine;
        m_markLine = 0;
    }
}

void QMakeParser::enterScope(ushort *&tokPtr, bool special, ScopeState state)
{
    uchar nest = m_blockstack.top().nest;
    m_blockstack.resize(m_blockstack.size() + 1);
    m_blockstack.top().special = special;
    m_blockstack.top().start = tokPtr;
    m_blockstack.top().nest = nest;
    tokPtr += 2;
    m_state = state;
    m_canElse = false;
    if (special)
        m_markLine = m_lineNo;
}

void QMakeParser::leaveScope(ushort *&tokPtr)
{
    if (m_blockstack.top().inBranch) {
        // Put empty else block
        putBlockLen(tokPtr, 0);
    }
    if (ushort *start = m_blockstack.top().start) {
        putTok(tokPtr, TokTerminator);
        uint len = tokPtr - start - 2;
        start[0] = (ushort)len;
        start[1] = (ushort)(len >> 16);
    }
    m_blockstack.resize(m_blockstack.size() - 1);
}

// If we are on a fresh line, close all open one-line scopes.
void QMakeParser::flushScopes(ushort *&tokPtr)
{
    if (m_state == StNew) {
        while (!m_blockstack.top().braceLevel && m_blockstack.size() > 1)
            leaveScope(tokPtr);
        if (m_blockstack.top().inBranch) {
            m_blockstack.top().inBranch = false;
            // Put empty else block
            putBlockLen(tokPtr, 0);
        }
        m_canElse = false;
    }
}

// If there is a pending conditional, enter a new scope, otherwise flush scopes.
void QMakeParser::flushCond(ushort *&tokPtr)
{
    if (m_state == StCond) {
        putTok(tokPtr, TokBranch);
        m_blockstack.top().inBranch = true;
        enterScope(tokPtr, false, StNew);
    } else {
        flushScopes(tokPtr);
    }
}

void QMakeParser::warnOperator(const char *msg)
{
    if (m_invert) {
        languageWarning(fL1S("Stray NOT operator %1.").arg(fL1S(msg)));
        m_invert = 0;
    }
    if (m_operator == AndOperator) {
        languageWarning(fL1S("Stray AND operator %1.").arg(fL1S(msg)));
        m_operator = NoOperator;
    } else if (m_operator == OrOperator) {
        languageWarning(fL1S("Stray OR operator %1.").arg(fL1S(msg)));
        m_operator = NoOperator;
    }
}

bool QMakeParser::failOperator(const char *msg)
{
    bool fail = false;
    if (m_invert) {
        parseError(fL1S("Unexpected NOT operator %1.").arg(fL1S(msg)));
        m_invert = 0;
        fail = true;
    }
    if (m_operator == AndOperator) {
        parseError(fL1S("Unexpected AND operator %1.").arg(fL1S(msg)));
        m_operator = NoOperator;
        fail = true;
    } else if (m_operator == OrOperator) {
        parseError(fL1S("Unexpected OR operator %1.").arg(fL1S(msg)));
        m_operator = NoOperator;
        fail = true;
    }
    return fail;
}

bool QMakeParser::acceptColon(const char *msg)
{
    if (m_operator == AndOperator)
        m_operator = NoOperator;
    return !failOperator(msg);
}

void QMakeParser::putOperator(ushort *&tokPtr)
{
    if (m_operator== AndOperator) {
        // A colon must be used after else and for() if no brace is used,
        // but in this case it is obviously not a binary operator.
        if (m_state == StCond)
            putTok(tokPtr, TokAnd);
        m_operator = NoOperator;
    } else if (m_operator == OrOperator) {
        putTok(tokPtr, TokOr);
        m_operator = NoOperator;
    }
}

void QMakeParser::finalizeTest(ushort *&tokPtr)
{
    flushScopes(tokPtr);
    putLineMarker(tokPtr);
    putOperator(tokPtr);
    if (m_invert & 1)
        putTok(tokPtr, TokNot);
    m_invert = 0;
    m_state = StCond;
    m_canElse = true;
}

void QMakeParser::bogusTest(ushort *&tokPtr, const QString &msg)
{
    if (!msg.isEmpty())
        parseError(msg);
    flushScopes(tokPtr);
    m_operator = NoOperator;
    m_invert = 0;
    m_state = StCond;
    m_canElse = true;
}

void QMakeParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount)
{
    if (wordCount != 1) {
        if (wordCount)
            bogusTest(tokPtr, fL1S("Extra characters after test expression."));
        return;
    }

    // Check for magic tokens
    if (*uc == TokHashLiteral) {
        uint nlen = uc[3];
        ushort *uce = uc + 4 + nlen;
        if (uce == ptr) {
            m_tmp.setRawData((QChar *)uc + 4, nlen);
            if (!m_tmp.compare(statics.strelse, Qt::CaseInsensitive)) {
                if (failOperator("in front of else"))
                    return;
                BlockScope &top = m_blockstack.top();
                if (m_canElse && (!top.special || top.braceLevel)) {
                    // A list of tests (the last one likely with side effects),
                    // but no assignment, scope, etc.
                    putTok(tokPtr, TokBranch);
                    // Put empty then block
                    putBlockLen(tokPtr, 0);
                    enterScope(tokPtr, false, StCtrl);
                    return;
                }
                forever {
                    BlockScope &top = m_blockstack.top();
                    if (top.inBranch && (!top.special || top.braceLevel)) {
                        top.inBranch = false;
                        enterScope(tokPtr, false, StCtrl);
                        return;
                    }
                    if (top.braceLevel || m_blockstack.size() == 1)
                        break;
                    leaveScope(tokPtr);
                }
                parseError(fL1S("Unexpected 'else'."));
                return;
            }
        }
    }

    finalizeTest(tokPtr);
    putBlock(tokPtr, uc, ptr - uc);
    putTok(tokPtr, TokCondition);
}

void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc)
{
    // Check for magic tokens
    if (*uc == TokHashLiteral) {
        uint nlen = uc[3];
        ushort *uce = uc + 4 + nlen;
        if (*uce == TokTestCall) {
            uce++;
            m_tmp.setRawData((QChar *)uc + 4, nlen);
            const QString *defName;
            ushort defType;
            if (m_tmp == statics.strfor) {
                if (!acceptColon("in front of for()")) {
                    bogusTest(tokPtr, QString());
                    return;
                }
                flushCond(tokPtr);
                putLineMarker(tokPtr);
                --ptr;
                Q_ASSERT(*ptr == TokFuncTerminator);
                if (*uce == (TokLiteral|TokNewStr)) {
                    nlen = uce[1];
                    uc = uce + 2 + nlen;
                    if (uc == ptr) {
                        // for(literal) (only "ever" would be legal if qmake was sane)
                        putTok(tokPtr, TokForLoop);
                        putHashStr(tokPtr, nullptr, (uint)0);
                        putBlockLen(tokPtr, 1 + 3 + nlen + 1);
                        putTok(tokPtr, TokHashLiteral);
                        putHashStr(tokPtr, uce + 2, nlen);
                      didFor:
                        putTok(tokPtr, TokValueTerminator);
                        enterScope(tokPtr, true, StCtrl);
                        m_blockstack.top().nest |= NestLoop;
                        return;
                    } else if (*uc == TokArgSeparator && argc == 2) {
                        // for(var, something)
                        uc++;
                        putTok(tokPtr, TokForLoop);
                        putHashStr(tokPtr, uce + 2, nlen);
                      doFor:
                        nlen = ptr - uc;
                        putBlockLen(tokPtr, nlen + 1);
                        putBlock(tokPtr, uc, nlen);
                        goto didFor;
                    }
                } else if (argc == 1) {
                    // for(non-literal) (this wouldn't be here if qmake was sane)
                    putTok(tokPtr, TokForLoop);
                    putHashStr(tokPtr, nullptr, (uint)0);
                    uc = uce;
                    goto doFor;
                }
                parseError(fL1S("Syntax is for(var, list), for(var, forever) or for(ever)."));
                return;
            } else if (m_tmp == statics.strdefineReplace) {
                defName = &statics.strdefineReplace;
                defType = TokReplaceDef;
                goto deffunc;
            } else if (m_tmp == statics.strdefineTest) {
                defName = &statics.strdefineTest;
                defType = TokTestDef;
              deffunc:
                if (m_invert) {
                    bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of function definition."));
                    return;
                }
                flushScopes(tokPtr);
                putLineMarker(tokPtr);
                if (*uce == (TokLiteral|TokNewStr)) {
                    uint nlen = uce[1];
                    if (uce[nlen + 2] == TokFuncTerminator) {
                        putOperator(tokPtr);
                        putTok(tokPtr, defType);
                        putHashStr(tokPtr, uce + 2, nlen);
                        enterScope(tokPtr, true, StCtrl);
                        m_blockstack.top().nest = NestFunction;
                        return;
                    }
                }
                parseError(fL1S("%1(function) requires one literal argument.").arg(*defName));
                return;
            } else if (m_tmp == statics.strbypassNesting) {
                if (*uce != TokFuncTerminator) {
                    bogusTest(tokPtr, fL1S("%1() requires zero arguments.").arg(m_tmp));
                    return;
                }
                if (!(m_blockstack.top().nest & NestFunction)) {
                    bogusTest(tokPtr, fL1S("Unexpected %1().").arg(m_tmp));
                    return;
                }
                if (m_invert) {
                    bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp));
                    return;
                }
                flushScopes(tokPtr);
                putLineMarker(tokPtr);
                putOperator(tokPtr);
                putTok(tokPtr, TokBypassNesting);
                enterScope(tokPtr, true, StCtrl);
                return;
            } else if (m_tmp == statics.strreturn) {
                if (m_blockstack.top().nest & NestFunction) {
                    if (argc > 1) {
                        bogusTest(tokPtr, fL1S("return() requires zero or one argument."));
                        return;
                    }
                } else {
                    if (*uce != TokFuncTerminator) {
                        bogusTest(tokPtr, fL1S("Top-level return() requires zero arguments."));
                        return;
                    }
                }
                defType = TokReturn;
                goto ctrlstm2;
            } else if (m_tmp == statics.strnext) {
                defType = TokNext;
                goto ctrlstm;
            } else if (m_tmp == statics.strbreak) {
                defType = TokBreak;
              ctrlstm:
                if (*uce != TokFuncTerminator) {
                    bogusTest(tokPtr, fL1S("%1() requires zero arguments.").arg(m_tmp));
                    return;
                }
                if (!(m_blockstack.top().nest & NestLoop)) {
                    bogusTest(tokPtr, fL1S("Unexpected %1().").arg(m_tmp));
                    return;
                }
              ctrlstm2:
                if (m_invert) {
                    bogusTest(tokPtr, fL1S("Unexpected NOT operator in front of %1().").arg(m_tmp));
                    return;
                }
                finalizeTest(tokPtr);
                putBlock(tokPtr, uce, ptr - uce - 1); // Only for TokReturn
                putTok(tokPtr, defType);
                return;
            } else if (m_tmp == statics.stroption) {
                if (m_state != StNew || m_blockstack.top().braceLevel || m_blockstack.size() > 1
                        || m_invert || m_operator != NoOperator) {
                    bogusTest(tokPtr, fL1S("option() must appear outside any control structures."));
                    return;
                }
                if (*uce == (TokLiteral|TokNewStr)) {
                    uint nlen = uce[1];
                    if (uce[nlen + 2] == TokFuncTerminator) {
                        m_tmp.setRawData((QChar *)uce + 2, nlen);
                        if (m_tmp == statics.strhost_build)
                            m_proFile->setHostBuild(true);
                        else
                            parseError(fL1S("Unknown option() %1.").arg(m_tmp));
                        return;
                    }
                }
                parseError(fL1S("option() requires one literal argument."));
                return;
            }
        }
    }

    finalizeTest(tokPtr);
    putBlock(tokPtr, uc, ptr - uc);
}

bool QMakeParser::resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort **ptr,
                                  ushort **buf, QString *xprBuff,
                                  ushort **tokPtr, QString *tokBuff,
                                  const ushort *cur, const QStringRef &in)
{
    QString out;
    m_tmp.setRawData((const QChar *)xprPtr, tlen);
    if (m_tmp == statics.strLINE) {
        out.setNum(m_lineNo);
    } else if (m_tmp == statics.strFILE) {
        out = m_proFile->fileName();
        // The string is typically longer than the variable reference, so we need
        // to ensure that there is enough space in the output buffer - as unlikely
        // as an overflow is to actually happen in practice.
        int need = (in.length() - (cur - (const ushort *)in.constData()) + 2) * 5 + out.length();
        int tused = *tokPtr - (ushort *)tokBuff->constData();
        int xused;
        int total;
        bool ptrFinal = xprPtr >= (ushort *)tokBuff->constData()
                && xprPtr < (ushort *)tokBuff->constData() + tokBuff->capacity();
        if (ptrFinal) {
            xused = xprPtr - (ushort *)tokBuff->constData();
            total = xused + need;
        } else {
            xused = xprPtr - *buf;
            total = tused + xused + need;
        }
        if (tokBuff->capacity() < total) {
            tokBuff->reserve(total);
            *tokPtr = (ushort *)tokBuff->constData() + tused;
            xprBuff->reserve(total);
            *buf = (ushort *)xprBuff->constData();
            xprPtr = (ptrFinal ? (ushort *)tokBuff->constData() : *buf) + xused;
        }
    } else if (m_tmp == statics.strLITERAL_HASH) {
        out = QLatin1String("#");
    } else if (m_tmp == statics.strLITERAL_DOLLAR) {
        out = QLatin1String("$");
    } else if (m_tmp == statics.strLITERAL_WHITESPACE) {
        out = QLatin1String("\t");
    } else {
        return false;
    }
    xprPtr -= 2; // Was set up for variable reference
    xprPtr[-2] = TokLiteral | needSep;
    xprPtr[-1] = out.length();
    memcpy(xprPtr, out.constData(), out.length() * 2);
    *ptr = xprPtr + out.length();
    return true;
}

void QMakeParser::message(int type, const QString &msg) const
{
    if (!m_inError && m_handler)
        m_handler->message(type, msg, m_proFile->fileName(), m_lineNo);
}

#ifdef PROPARSER_DEBUG

#define BOUNDS_CHECK(need) \
    do { \
        int have = limit - offset; \
        if (have < (int)need) { \
            *outStr += fL1S("<out of bounds (need %1, got %2)>").arg(need).arg(have); \
            return false; \
        } \
    } while (0)

static bool getRawUshort(const ushort *tokens, int limit, int &offset, ushort *outVal, QString *outStr)
{
    BOUNDS_CHECK(1);
    uint val = tokens[offset++];
    *outVal = val;
    return true;
}

static bool getUshort(const ushort *tokens, int limit, int &offset, ushort *outVal, QString *outStr)
{
    *outStr += fL1S(" << H(");
    if (!getRawUshort(tokens, limit, offset, outVal, outStr))
        return false;
    *outStr += QString::number(*outVal) + QLatin1Char(')');
    return true;
}

static bool getRawUint(const ushort *tokens, int limit, int &offset, uint *outVal, QString *outStr)
{
    BOUNDS_CHECK(2);
    uint val = tokens[offset++];
    val |= (uint)tokens[offset++] << 16;
    *outVal = val;
    return true;
}

static bool getUint(const ushort *tokens, int limit, int &offset, uint *outVal, QString *outStr)
{
    *outStr += fL1S(" << I(");
    if (!getRawUint(tokens, limit, offset, outVal, outStr))
        return false;
    *outStr += QString::number(*outVal) + QLatin1Char(')');
    return true;
}

static bool getRawStr(const ushort *tokens, int limit, int &offset, int strLen, QString *outStr)
{
    BOUNDS_CHECK(strLen);
    *outStr += fL1S("L\"");
    bool attn = false;
    for (int i = 0; i < strLen; i++) {
        ushort val = tokens[offset++];
        switch (val) {
        case '"': *outStr += fL1S("\\\""); break;
        case '\n': *outStr += fL1S("\\n"); break;
        case '\r': *outStr += fL1S("\\r"); break;
        case '\t': *outStr += fL1S("\\t"); break;
        case '\\': *outStr += fL1S("\\\\"); break;
        default:
            if (val < 32 || val > 126) {
                *outStr += (val > 255 ? fL1S("\\u") : fL1S("\\x")) + QString::number(val, 16);
                attn = true;
                continue;
            }
            if (attn && isxdigit(val))
                *outStr += fL1S("\"\"");
            *outStr += QChar(val);
            break;
        }
        attn = false;
    }
    *outStr += QLatin1Char('"');
    return true;
}

static bool getStr(const ushort *tokens, int limit, int &offset, QString *outStr)
{
    *outStr += fL1S(" << S(");
    ushort len;
    if (!getRawUshort(tokens, limit, offset, &len, outStr))
        return false;
    if (!getRawStr(tokens, limit, offset, len, outStr))
        return false;
    *outStr += QLatin1Char(')');
    return true;
}

static bool getHashStr(const ushort *tokens, int limit, int &offset, QString *outStr)
{
    *outStr += fL1S(" << HS(");
    uint hash;
    if (!getRawUint(tokens, limit, offset, &hash, outStr))
        return false;
    ushort len;
    if (!getRawUshort(tokens, limit, offset, &len, outStr))
        return false;
    const QChar *chars = (const QChar *)tokens + offset;
    if (!getRawStr(tokens, limit, offset, len, outStr))
        return false;
    uint realhash = ProString::hash(chars, len);
    if (realhash != hash)
        *outStr += fL1S(" /* Bad hash ") + QString::number(hash) + fL1S(" */");
    *outStr += QLatin1Char(')');
    return true;
}

static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent);

static bool getSubBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent,
                        const char *scope)
{
    *outStr += fL1S("\n    /* %1 */ ").arg(offset, 5)
               + QString(indent * 4, QLatin1Char(' '))
               + fL1S("/* ") + fL1S(scope) + fL1S(" */");
    uint len;
    if (!getUint(tokens, limit, offset, &len, outStr))
        return false;
    if (len) {
        BOUNDS_CHECK(len);
        int tmpOff = offset;
        offset += len;
        forever {
            if (!getBlock(tokens, offset, tmpOff, outStr, indent + 1))
                break;  // Error was already reported, try to continue
            if (tmpOff == offset)
                break;
            *outStr += QLatin1Char('\n') + QString(20 + indent * 4, QLatin1Char(' '))
                       + fL1S("/* Warning: Excess tokens follow. */");
        }
    }
    return true;
}

static bool getBlock(const ushort *tokens, int limit, int &offset, QString *outStr, int indent)
{
    static const char * const tokNames[] = {
        "TokTerminator",
        "TokLine",
        "TokAssign", "TokAppend", "TokAppendUnique", "TokRemove", "TokReplace",
        "TokValueTerminator",
        "TokLiteral", "TokHashLiteral", "TokVariable", "TokProperty", "TokEnvVar",
        "TokFuncName", "TokArgSeparator", "TokFuncTerminator",
        "TokCondition", "TokTestCall",
        "TokReturn", "TokBreak", "TokNext",
        "TokNot", "TokAnd", "TokOr",
        "TokBranch", "TokForLoop",
        "TokTestDef", "TokReplaceDef", "TokBypassNesting"
    };

    while (offset != limit) {
        *outStr += fL1S("\n    /* %1 */").arg(offset, 5)
                   + QString(indent * 4, QLatin1Char(' '));
        BOUNDS_CHECK(1);
        ushort tok = tokens[offset++];
        ushort maskedTok = tok & TokMask;
        if (maskedTok >= sizeof(tokNames)/sizeof(tokNames[0])
            || (tok & ~(TokNewStr | TokQuoted | TokMask))) {
            *outStr += fL1S(" << {invalid token %1}").arg(tok);
            return false;
        }
        *outStr += fL1S(" << H(") + fL1S(tokNames[maskedTok]);
        if (tok & TokNewStr)
            *outStr += fL1S(" | TokNewStr");
        if (tok & TokQuoted)
            *outStr += fL1S(" | TokQuoted");
        *outStr += QLatin1Char(')');
        bool ok;
        switch (maskedTok) {
        case TokFuncTerminator:   // Recursion, but not a sub-block
            return true;
        case TokArgSeparator:
        case TokValueTerminator:  // Not recursion
        case TokTerminator:       // Recursion, and limited by (sub-)block length
        case TokCondition:
        case TokReturn:
        case TokBreak:
        case TokNext:
        case TokNot:
        case TokAnd:
        case TokOr:
            ok = true;
            break;
        case TokTestCall:
            ok = getBlock(tokens, limit, offset, outStr, indent + 1);
            break;
        case TokBranch:
            ok = getSubBlock(tokens, limit, offset, outStr, indent, "then branch");
            if (ok)
                ok = getSubBlock(tokens, limit, offset, outStr, indent, "else branch");
            break;
        default:
            switch (maskedTok) {
            case TokAssign:
            case TokAppend:
            case TokAppendUnique:
            case TokRemove:
            case TokReplace:
                // The parameter is the sizehint for the output.
                // fallthrough
            case TokLine: {
                ushort dummy;
                ok = getUshort(tokens, limit, offset, &dummy, outStr);
                break; }
            case TokLiteral:
            case TokEnvVar:
                ok = getStr(tokens, limit, offset, outStr);
                break;
            case TokHashLiteral:
            case TokVariable:
            case TokProperty:
                ok = getHashStr(tokens, limit, offset, outStr);
                break;
            case TokFuncName:
                ok = getHashStr(tokens, limit, offset, outStr);
                if (ok)
                    ok = getBlock(tokens, limit, offset, outStr, indent + 1);
                break;
            case TokForLoop:
                ok = getHashStr(tokens, limit, offset, outStr);
                if (ok)
                    ok = getSubBlock(tokens, limit, offset, outStr, indent, "iterator");
                if (ok)
                    ok = getSubBlock(tokens, limit, offset, outStr, indent, "body");
                break;
            case TokTestDef:
            case TokReplaceDef:
                ok = getHashStr(tokens, limit, offset, outStr);
                if (ok)
                    ok = getSubBlock(tokens, limit, offset, outStr, indent, "body");
                break;
            case TokBypassNesting:
                ok = getSubBlock(tokens, limit, offset, outStr, indent, "block");
                break;
            default:
                Q_ASSERT(!"unhandled token");
            }
        }
        if (!ok)
            return false;
    }
    return true;
}

QString QMakeParser::formatProBlock(const QString &block)
{
    QString outStr;
    outStr += fL1S("\n            << TS(");
    int offset = 0;
    getBlock(reinterpret_cast<const ushort *>(block.constData()), block.length(),
             offset, &outStr, 0);
    outStr += QLatin1Char(')');
    return outStr;
}

#endif // PROPARSER_DEBUG

QT_END_NAMESPACE
