//
// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
// Copyright (C) 2013 LunarG, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//    Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//    Redistributions in binary form must reproduce the above
//    copyright notice, this list of conditions and the following
//    disclaimer in the documentation and/or other materials provided
//    with the distribution.
//
//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.

NVIDIA Corporation("NVIDIA") supplies this software to you in
consideration of your agreement to the following terms, and your use,
installation, modification or redistribution of this NVIDIA software
constitutes acceptance of these terms.  If you do not agree with these
terms, please do not use, install, modify or redistribute this NVIDIA
software.

In consideration of your agreement to abide by the following terms, and
subject to these terms, NVIDIA grants you a personal, non-exclusive
license, under NVIDIA's copyrights in this original NVIDIA software (the
"NVIDIA Software"), to use, reproduce, modify and redistribute the
NVIDIA Software, with or without modifications, in source and/or binary
forms; provided that if you redistribute the NVIDIA Software, you must
retain the copyright notice of NVIDIA, this notice and the following
text and disclaimers in all such redistributions of the NVIDIA Software.
Neither the name, trademarks, service marks nor logos of NVIDIA
Corporation may be used to endorse or promote products derived from the
NVIDIA Software without specific prior written permission from NVIDIA.
Except as expressly stated in this notice, no other rights or licenses
express or implied, are granted by NVIDIA herein, including but not
limited to any patent rights that may be infringed by your derivative
works or by other works in which the NVIDIA Software may be
incorporated. No hardware is licensed hereunder.

THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
PRODUCTS.

IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/

#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <sstream>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <climits>

#include "PpContext.h"
#include "PpTokens.h"

namespace glslang {

// Handle #define
int TPpContext::CPPdefine(TPpToken* ppToken)
{
    MacroSymbol mac;

    // get the macro name
    int token = scanToken(ppToken);
    if (token != PpAtomIdentifier) {
        parseContext.ppError(ppToken->loc, "must be followed by macro name", "#define", "");
        return token;
    }
    if (ppToken->loc.string >= 0) {
        // We are in user code; check for reserved name use:
        parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#define");
    }

    // save the macro name
    const int defAtom = atomStrings.getAddAtom(ppToken->name);
    TSourceLoc defineLoc = ppToken->loc; // because ppToken might go to the next line before we report errors

    // gather parameters to the macro, between (...)
    token = scanToken(ppToken);
    if (token == '(' && !ppToken->space) {
        mac.functionLike = 1;
        do {
            token = scanToken(ppToken);
            if (mac.args.size() == 0 && token == ')')
                break;
            if (token != PpAtomIdentifier) {
                parseContext.ppError(ppToken->loc, "bad argument", "#define", "");

                return token;
            }
            const int argAtom = atomStrings.getAddAtom(ppToken->name);

            // check for duplication of parameter name
            bool duplicate = false;
            for (size_t a = 0; a < mac.args.size(); ++a) {
                if (mac.args[a] == argAtom) {
                    parseContext.ppError(ppToken->loc, "duplicate macro parameter", "#define", "");
                    duplicate = true;
                    break;
                }
            }
            if (! duplicate)
                mac.args.push_back(argAtom);
            token = scanToken(ppToken);
        } while (token == ',');
        if (token != ')') {
            parseContext.ppError(ppToken->loc, "missing parenthesis", "#define", "");

            return token;
        }

        token = scanToken(ppToken);
    }

    // record the definition of the macro
    while (token != '\n' && token != EndOfInput) {
        mac.body.putToken(token, ppToken);
        token = scanToken(ppToken);
        if (token != '\n' && ppToken->space)
            mac.body.putToken(' ', ppToken);
    }

    // check for duplicate definition
    MacroSymbol* existing = lookupMacroDef(defAtom);
    if (existing != nullptr) {
        if (! existing->undef) {
            // Already defined -- need to make sure they are identical:
            // "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
            // ordering, spelling, and white-space separation, where all white-space separations are considered identical."
            if (existing->functionLike != mac.functionLike)
                parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define", atomStrings.getString(defAtom));
            else if (existing->args.size() != mac.args.size())
                parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom));
            else {
                if (existing->args != mac.args)
                    parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom));
                existing->body.reset();
                mac.body.reset();
                int newToken;
                do {
                    int oldToken;
                    TPpToken oldPpToken;
                    TPpToken newPpToken;
                    oldToken = existing->body.getToken(parseContext, &oldPpToken);
                    newToken = mac.body.getToken(parseContext, &newPpToken);
                    if (oldToken != newToken || oldPpToken != newPpToken) {
                        parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom));
                        break;
                    }
                } while (newToken > 0);
            }
        }
        *existing = mac;
    } else
        addMacroDef(defAtom, mac);

    return '\n';
}

// Handle #undef
int TPpContext::CPPundef(TPpToken* ppToken)
{
    int token = scanToken(ppToken);
    if (token != PpAtomIdentifier) {
        parseContext.ppError(ppToken->loc, "must be followed by macro name", "#undef", "");

        return token;
    }

    parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#undef");

    MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
    if (macro != nullptr)
        macro->undef = 1;
    token = scanToken(ppToken);
    if (token != '\n')
        parseContext.ppError(ppToken->loc, "can only be followed by a single macro name", "#undef", "");

    return token;
}

// Handle #else
/* Skip forward to appropriate spot.  This is used both
** to skip to a #endif after seeing an #else, AND to skip to a #else,
** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false.
*/
int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
{
    int depth = 0;
    int token = scanToken(ppToken);

    while (token != EndOfInput) {
        if (token != '#') {
            while (token != '\n' && token != EndOfInput)
                token = scanToken(ppToken);

            if (token == EndOfInput)
                return token;

            token = scanToken(ppToken);
            continue;
        }

        if ((token = scanToken(ppToken)) != PpAtomIdentifier)
            continue;

        int nextAtom = atomStrings.getAtom(ppToken->name);
        if (nextAtom == PpAtomIf || nextAtom == PpAtomIfdef || nextAtom == PpAtomIfndef) {
            depth++;
            if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting) {
                parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if/#ifdef/#ifndef", "");
                return EndOfInput;
            } else {
                ifdepth++;
                elsetracker++;
            }
        } else if (nextAtom == PpAtomEndif) {
            token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
            elseSeen[elsetracker] = false;
            --elsetracker;
            if (depth == 0) {
                // found the #endif we are looking for
                if (ifdepth > 0)
                    --ifdepth;
                break;
            }
            --depth;
            --ifdepth;
        } else if (matchelse && depth == 0) {
            if (nextAtom == PpAtomElse) {
                elseSeen[elsetracker] = true;
                token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
                // found the #else we are looking for
                break;
            } else if (nextAtom == PpAtomElif) {
                if (elseSeen[elsetracker])
                    parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
                /* we decrement ifdepth here, because CPPif will increment
                * it and we really want to leave it alone */
                if (ifdepth > 0) {
                    --ifdepth;
                    elseSeen[elsetracker] = false;
                    --elsetracker;
                }

                return CPPif(ppToken);
            }
        } else if (nextAtom == PpAtomElse) {
            if (elseSeen[elsetracker])
                parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
            else
                elseSeen[elsetracker] = true;
            token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
        } else if (nextAtom == PpAtomElif) {
            if (elseSeen[elsetracker])
                parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
        }
    }

    return token;
}

// Call when there should be no more tokens left on a line.
int TPpContext::extraTokenCheck(int contextAtom, TPpToken* ppToken, int token)
{
    if (token != '\n' && token != EndOfInput) {
        static const char* message = "unexpected tokens following directive";

        const char* label;
        if (contextAtom == PpAtomElse)
            label = "#else";
        else if (contextAtom == PpAtomElif)
            label = "#elif";
        else if (contextAtom == PpAtomEndif)
            label = "#endif";
        else if (contextAtom == PpAtomIf)
            label = "#if";
        else if (contextAtom == PpAtomLine)
            label = "#line";
        else
            label = "";

        if (parseContext.relaxedErrors())
            parseContext.ppWarn(ppToken->loc, message, label, "");
        else
            parseContext.ppError(ppToken->loc, message, label, "");

        while (token != '\n' && token != EndOfInput)
            token = scanToken(ppToken);
    }

    return token;
}

enum eval_prec {
    MIN_PRECEDENCE,
    COND, LOGOR, LOGAND, OR, XOR, AND, EQUAL, RELATION, SHIFT, ADD, MUL, UNARY,
    MAX_PRECEDENCE
};

namespace {

    int op_logor(int a, int b) { return a || b; }
    int op_logand(int a, int b) { return a && b; }
    int op_or(int a, int b) { return a | b; }
    int op_xor(int a, int b) { return a ^ b; }
    int op_and(int a, int b) { return a & b; }
    int op_eq(int a, int b) { return a == b; }
    int op_ne(int a, int b) { return a != b; }
    int op_ge(int a, int b) { return a >= b; }
    int op_le(int a, int b) { return a <= b; }
    int op_gt(int a, int b) { return a > b; }
    int op_lt(int a, int b) { return a < b; }
    int op_shl(int a, int b) { return a << b; }
    int op_shr(int a, int b) { return a >> b; }
    int op_add(int a, int b) { return a + b; }
    int op_sub(int a, int b) { return a - b; }
    int op_mul(int a, int b) { return a * b; }
    int op_div(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a / b; }
    int op_mod(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a % b; }
    int op_pos(int a) { return a; }
    int op_neg(int a) { return -a; }
    int op_cmpl(int a) { return ~a; }
    int op_not(int a) { return !a; }

};

struct TBinop {
    int token, precedence, (*op)(int, int);
} binop[] = {
    { PpAtomOr, LOGOR, op_logor },
    { PpAtomAnd, LOGAND, op_logand },
    { '|', OR, op_or },
    { '^', XOR, op_xor },
    { '&', AND, op_and },
    { PpAtomEQ, EQUAL, op_eq },
    { PpAtomNE, EQUAL, op_ne },
    { '>', RELATION, op_gt },
    { PpAtomGE, RELATION, op_ge },
    { '<', RELATION, op_lt },
    { PpAtomLE, RELATION, op_le },
    { PpAtomLeft, SHIFT, op_shl },
    { PpAtomRight, SHIFT, op_shr },
    { '+', ADD, op_add },
    { '-', ADD, op_sub },
    { '*', MUL, op_mul },
    { '/', MUL, op_div },
    { '%', MUL, op_mod },
};

struct TUnop {
    int token, (*op)(int);
} unop[] = {
    { '+', op_pos },
    { '-', op_neg },
    { '~', op_cmpl },
    { '!', op_not },
};

#define NUM_ELEMENTS(A) (sizeof(A) / sizeof(A[0]))

int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, bool& err, TPpToken* ppToken)
{
    TSourceLoc loc = ppToken->loc;  // because we sometimes read the newline before reporting the error
    if (token == PpAtomIdentifier) {
        if (strcmp("defined", ppToken->name) == 0) {
            if (! parseContext.isReadingHLSL() && isMacroInput()) {
                if (parseContext.relaxedErrors())
                    parseContext.ppWarn(ppToken->loc, "nonportable when expanded from macros for preprocessor expression",
                                                      "defined", "");
                else
                    parseContext.ppError(ppToken->loc, "cannot use in preprocessor expression when expanded from macros",
                                                       "defined", "");
            }
            bool needclose = 0;
            token = scanToken(ppToken);
            if (token == '(') {
                needclose = true;
                token = scanToken(ppToken);
            }
            if (token != PpAtomIdentifier) {
                parseContext.ppError(loc, "incorrect directive, expected identifier", "preprocessor evaluation", "");
                err = true;
                res = 0;

                return token;
            }

            MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
            res = macro != nullptr ? !macro->undef : 0;
            token = scanToken(ppToken);
            if (needclose) {
                if (token != ')') {
                    parseContext.ppError(loc, "expected ')'", "preprocessor evaluation", "");
                    err = true;
                    res = 0;

                    return token;
                }
                token = scanToken(ppToken);
            }
        } else {
            token = evalToToken(token, shortCircuit, res, err, ppToken);
            return eval(token, precedence, shortCircuit, res, err, ppToken);
        }
    } else if (token == PpAtomConstInt) {
        res = ppToken->ival;
        token = scanToken(ppToken);
    } else if (token == '(') {
        token = scanToken(ppToken);
        token = eval(token, MIN_PRECEDENCE, shortCircuit, res, err, ppToken);
        if (! err) {
            if (token != ')') {
                parseContext.ppError(loc, "expected ')'", "preprocessor evaluation", "");
                err = true;
                res = 0;

                return token;
            }
            token = scanToken(ppToken);
        }
    } else {
        int op = NUM_ELEMENTS(unop) - 1;
        for (; op >= 0; op--) {
            if (unop[op].token == token)
                break;
        }
        if (op >= 0) {
            token = scanToken(ppToken);
            token = eval(token, UNARY, shortCircuit, res, err, ppToken);
            res = unop[op].op(res);
        } else {
            parseContext.ppError(loc, "bad expression", "preprocessor evaluation", "");
            err = true;
            res = 0;

            return token;
        }
    }

    token = evalToToken(token, shortCircuit, res, err, ppToken);

    // Perform evaluation of binary operation, if there is one, otherwise we are done.
    while (! err) {
        if (token == ')' || token == '\n')
            break;
        int op;
        for (op = NUM_ELEMENTS(binop) - 1; op >= 0; op--) {
            if (binop[op].token == token)
                break;
        }
        if (op < 0 || binop[op].precedence <= precedence)
            break;
        int leftSide = res;

        // Setup short-circuiting, needed for ES, unless already in a short circuit.
        // (Once in a short-circuit, can't turn off again, until that whole subexpression is done.
        if (! shortCircuit) {
            if ((token == PpAtomOr  && leftSide == 1) ||
                (token == PpAtomAnd && leftSide == 0))
                shortCircuit = true;
        }

        token = scanToken(ppToken);
        token = eval(token, binop[op].precedence, shortCircuit, res, err, ppToken);

        if (binop[op].op == op_div || binop[op].op == op_mod) {
            if (res == 0) {
                parseContext.ppError(loc, "division by 0", "preprocessor evaluation", "");
                res = 1;
            }
        }
        res = binop[op].op(leftSide, res);
    }

    return token;
}

// Expand macros, skipping empty expansions, to get to the first real token in those expansions.
int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken* ppToken)
{
    while (token == PpAtomIdentifier && strcmp("defined", ppToken->name) != 0) {
        switch (MacroExpand(ppToken, true, false)) {
        case MacroExpandNotStarted:
        case MacroExpandError:
            parseContext.ppError(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
            err = true;
            res = 0;
            break;
        case MacroExpandStarted:
            break;
        case MacroExpandUndef:
            if (! shortCircuit && parseContext.profile == EEsProfile) {
                const char* message = "undefined macro in expression not allowed in es profile";
                if (parseContext.relaxedErrors())
                    parseContext.ppWarn(ppToken->loc, message, "preprocessor evaluation", ppToken->name);
                else
                    parseContext.ppError(ppToken->loc, message, "preprocessor evaluation", ppToken->name);
            }
            break;
        }
        token = scanToken(ppToken);
        if (err)
            break;
    }

    return token;
}

// Handle #if
int TPpContext::CPPif(TPpToken* ppToken)
{
    int token = scanToken(ppToken);
    if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting) {
        parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
        return EndOfInput;
    } else {
        elsetracker++;
        ifdepth++;
    }
    int res = 0;
    bool err = false;
    token = eval(token, MIN_PRECEDENCE, false, res, err, ppToken);
    token = extraTokenCheck(PpAtomIf, ppToken, token);
    if (!res && !err)
        token = CPPelse(1, ppToken);

    return token;
}

// Handle #ifdef
int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
{
    int token = scanToken(ppToken);
    if (ifdepth > maxIfNesting || elsetracker > maxIfNesting) {
        parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", "");
        return EndOfInput;
    } else {
        elsetracker++;
        ifdepth++;
    }

    if (token != PpAtomIdentifier) {
        if (defined)
            parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifdef", "");
        else
            parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", "");
    } else {
        MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
        token = scanToken(ppToken);
        if (token != '\n') {
            parseContext.ppError(ppToken->loc, "unexpected tokens following #ifdef directive - expected a newline", "#ifdef", "");
            while (token != '\n' && token != EndOfInput)
                token = scanToken(ppToken);
        }
        if (((macro != nullptr && !macro->undef) ? 1 : 0) != defined)
            token = CPPelse(1, ppToken);
    }

    return token;
}

// Handle #include ...
// TODO: Handle macro expansions for the header name
int TPpContext::CPPinclude(TPpToken* ppToken)
{
    const TSourceLoc directiveLoc = ppToken->loc;
    bool startWithLocalSearch = true; // to additionally include the extra "" paths
    int token = scanToken(ppToken);

    // handle <header-name>-style #include
    if (token == '<') {
        startWithLocalSearch = false;
        token = scanHeaderName(ppToken, '>');
    }
    // otherwise ppToken already has the header name and it was "header-name" style

    if (token != PpAtomConstString) {
        parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", "");
        return token;
    }

    // Make a copy of the name because it will be overwritten by the next token scan.
    const std::string filename = ppToken->name;

    // See if the directive was well formed
    token = scanToken(ppToken);
    if (token != '\n') {
        if (token == EndOfInput)
            parseContext.ppError(ppToken->loc, "expected newline after header name:", "#include", "%s", filename.c_str());
        else
            parseContext.ppError(ppToken->loc, "extra content after header name:", "#include", "%s", filename.c_str());
        return token;
    }

    // Process well-formed directive

    // Find the inclusion, first look in "Local" ("") paths, if requested,
    // otherwise, only search the "System" (<>) paths.
    TShader::Includer::IncludeResult* res = nullptr;
    if (startWithLocalSearch)
        res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
    if (res == nullptr || res->headerName.empty()) {
        includer.releaseInclude(res);
        res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
    }

    // Process the results
    if (res != nullptr && !res->headerName.empty()) {
        if (res->headerData != nullptr && res->headerLength > 0) {
            // path for processing one or more tokens from an included header, hand off 'res'
            const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
            std::ostringstream prologue;
            std::ostringstream epilogue;
            prologue << "#line " << forNextLine << " " << "\"" << res->headerName << "\"\n";
            epilogue << (res->headerData[res->headerLength - 1] == '\n'? "" : "\n") <<
                "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
            pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this));
            // There's no "current" location anymore.
            parseContext.setCurrentColumn(0);
        } else {
            // things are okay, but there is nothing to process
            includer.releaseInclude(res);
        }
    } else {
        // error path, clean up
        std::string message =
            res != nullptr ? std::string(res->headerData, res->headerLength)
                           : std::string("Could not process include directive");
        parseContext.ppError(directiveLoc, message.c_str(), "#include", "for header name: %s", filename.c_str());
        includer.releaseInclude(res);
    }

    return token;
}

// Handle #line
int TPpContext::CPPline(TPpToken* ppToken)
{
    // "#line must have, after macro substitution, one of the following forms:
    // "#line line
    // "#line line source-string-number"

    int token = scanToken(ppToken);
    const TSourceLoc directiveLoc = ppToken->loc;
    if (token == '\n') {
        parseContext.ppError(ppToken->loc, "must by followed by an integral literal", "#line", "");
        return token;
    }

    int lineRes = 0; // Line number after macro expansion.
    int lineToken = 0;
    bool hasFile = false;
    int fileRes = 0; // Source file number after macro expansion.
    const char* sourceName = nullptr; // Optional source file name.
    bool lineErr = false;
    bool fileErr = false;
    token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken);
    if (! lineErr) {
        lineToken = lineRes;
        if (token == '\n')
            ++lineRes;

        if (parseContext.lineDirectiveShouldSetNextLine())
            --lineRes;
        parseContext.setCurrentLine(lineRes);

        if (token != '\n') {
            if (token == PpAtomConstString) {
                parseContext.ppRequireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line");
                // We need to save a copy of the string instead of pointing
                // to the name field of the token since the name field
                // will likely be overwritten by the next token scan.
                sourceName = atomStrings.getString(atomStrings.getAddAtom(ppToken->name));
                parseContext.setCurrentSourceName(sourceName);
                hasFile = true;
                token = scanToken(ppToken);
            } else {
                token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
                if (! fileErr) {
                    parseContext.setCurrentString(fileRes);
                    hasFile = true;
                }
            }
        }
    }
    if (!fileErr && !lineErr) {
        parseContext.notifyLineDirective(directiveLoc.line, lineToken, hasFile, fileRes, sourceName);
    }
    token = extraTokenCheck(PpAtomLine, ppToken, token);

    return token;
}

// Handle #error
int TPpContext::CPPerror(TPpToken* ppToken)
{
    int token = scanToken(ppToken);
    std::string message;
    TSourceLoc loc = ppToken->loc;

    while (token != '\n' && token != EndOfInput) {
        if (token == PpAtomConstInt16 || token == PpAtomConstUint16 ||
            token == PpAtomConstInt   || token == PpAtomConstUint   ||
            token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
            token == PpAtomConstFloat16 ||
            token == PpAtomConstFloat || token == PpAtomConstDouble) {
                message.append(ppToken->name);
        } else if (token == PpAtomIdentifier || token == PpAtomConstString) {
            message.append(ppToken->name);
        } else {
            message.append(atomStrings.getString(token));
        }
        message.append(" ");
        token = scanToken(ppToken);
    }
    parseContext.notifyErrorDirective(loc.line, message.c_str());
    // store this msg into the shader's information log..set the Compile Error flag!!!!
    parseContext.ppError(loc, message.c_str(), "#error", "");

    return '\n';
}

// Handle #pragma
int TPpContext::CPPpragma(TPpToken* ppToken)
{
    char SrcStrName[2];
    TVector<TString> tokens;

    TSourceLoc loc = ppToken->loc;  // because we go to the next line before processing
    int token = scanToken(ppToken);
    while (token != '\n' && token != EndOfInput) {
        switch (token) {
        case PpAtomIdentifier:
        case PpAtomConstInt:
        case PpAtomConstUint:
        case PpAtomConstInt64:
        case PpAtomConstUint64:
#ifdef AMD_EXTENSIONS
        case PpAtomConstInt16:
        case PpAtomConstUint16:
#endif
        case PpAtomConstFloat:
        case PpAtomConstDouble:
        case PpAtomConstFloat16:
            tokens.push_back(ppToken->name);
            break;
        default:
            SrcStrName[0] = (char)token;
            SrcStrName[1] = '\0';
            tokens.push_back(SrcStrName);
        }
        token = scanToken(ppToken);
    }

    if (token == EndOfInput)
        parseContext.ppError(loc, "directive must end with a newline", "#pragma", "");
    else
        parseContext.handlePragma(loc, tokens);

    return token;
}

// #version: This is just for error checking: the version and profile are decided before preprocessing starts
int TPpContext::CPPversion(TPpToken* ppToken)
{
    int token = scanToken(ppToken);

    if (errorOnVersion || versionSeen) {
        if (parseContext.isReadingHLSL())
            parseContext.ppError(ppToken->loc, "invalid preprocessor command", "#version", "");
        else
            parseContext.ppError(ppToken->loc, "must occur first in shader", "#version", "");
    }
    versionSeen = true;

    if (token == '\n') {
        parseContext.ppError(ppToken->loc, "must be followed by version number", "#version", "");

        return token;
    }

    if (token != PpAtomConstInt)
        parseContext.ppError(ppToken->loc, "must be followed by version number", "#version", "");

    ppToken->ival = atoi(ppToken->name);
    int versionNumber = ppToken->ival;
    int line = ppToken->loc.line;
    token = scanToken(ppToken);

    if (token == '\n') {
        parseContext.notifyVersion(line, versionNumber, nullptr);
        return token;
    } else {
        int profileAtom = atomStrings.getAtom(ppToken->name);
        if (profileAtom != PpAtomCore &&
            profileAtom != PpAtomCompatibility &&
            profileAtom != PpAtomEs)
            parseContext.ppError(ppToken->loc, "bad profile name; use es, core, or compatibility", "#version", "");
        parseContext.notifyVersion(line, versionNumber, ppToken->name);
        token = scanToken(ppToken);

        if (token == '\n')
            return token;
        else
            parseContext.ppError(ppToken->loc, "bad tokens following profile -- expected newline", "#version", "");
    }

    return token;
}

// Handle #extension
int TPpContext::CPPextension(TPpToken* ppToken)
{
    int line = ppToken->loc.line;
    int token = scanToken(ppToken);
    char extensionName[MaxTokenLength + 1];

    if (token=='\n') {
        parseContext.ppError(ppToken->loc, "extension name not specified", "#extension", "");
        return token;
    }

    if (token != PpAtomIdentifier)
        parseContext.ppError(ppToken->loc, "extension name expected", "#extension", "");

    assert(strlen(ppToken->name) <= MaxTokenLength);
    strcpy(extensionName, ppToken->name);

    token = scanToken(ppToken);
    if (token != ':') {
        parseContext.ppError(ppToken->loc, "':' missing after extension name", "#extension", "");
        return token;
    }

    token = scanToken(ppToken);
    if (token != PpAtomIdentifier) {
        parseContext.ppError(ppToken->loc, "behavior for extension not specified", "#extension", "");
        return token;
    }

    parseContext.updateExtensionBehavior(line, extensionName, ppToken->name);
    parseContext.notifyExtensionDirective(line, extensionName, ppToken->name);

    token = scanToken(ppToken);
    if (token == '\n')
        return token;
    else
        parseContext.ppError(ppToken->loc,  "extra tokens -- expected newline", "#extension","");

    return token;
}

int TPpContext::readCPPline(TPpToken* ppToken)
{
    int token = scanToken(ppToken);

    if (token == PpAtomIdentifier) {
        switch (atomStrings.getAtom(ppToken->name)) {
        case PpAtomDefine:
            token = CPPdefine(ppToken);
            break;
        case PpAtomElse:
            if (elseSeen[elsetracker])
                parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
            elseSeen[elsetracker] = true;
            if (ifdepth == 0)
                parseContext.ppError(ppToken->loc, "mismatched statements", "#else", "");
            token = extraTokenCheck(PpAtomElse, ppToken, scanToken(ppToken));
            token = CPPelse(0, ppToken);
            break;
        case PpAtomElif:
            if (ifdepth == 0)
                parseContext.ppError(ppToken->loc, "mismatched statements", "#elif", "");
            if (elseSeen[elsetracker])
                parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
            // this token is really a dont care, but we still need to eat the tokens
            token = scanToken(ppToken);
            while (token != '\n' && token != EndOfInput)
                token = scanToken(ppToken);
            token = CPPelse(0, ppToken);
            break;
        case PpAtomEndif:
            if (ifdepth == 0)
                parseContext.ppError(ppToken->loc, "mismatched statements", "#endif", "");
            else {
                elseSeen[elsetracker] = false;
                --elsetracker;
                --ifdepth;
            }
            token = extraTokenCheck(PpAtomEndif, ppToken, scanToken(ppToken));
            break;
        case PpAtomIf:
            token = CPPif(ppToken);
            break;
        case PpAtomIfdef:
            token = CPPifdef(1, ppToken);
            break;
        case PpAtomIfndef:
            token = CPPifdef(0, ppToken);
            break;
        case PpAtomInclude:
            if(!parseContext.isReadingHLSL()) {
                parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
            }
            token = CPPinclude(ppToken);
            break;
        case PpAtomLine:
            token = CPPline(ppToken);
            break;
        case PpAtomPragma:
            token = CPPpragma(ppToken);
            break;
        case PpAtomUndef:
            token = CPPundef(ppToken);
            break;
        case PpAtomError:
            token = CPPerror(ppToken);
            break;
        case PpAtomVersion:
            token = CPPversion(ppToken);
            break;
        case PpAtomExtension:
            token = CPPextension(ppToken);
            break;
        default:
            parseContext.ppError(ppToken->loc, "invalid directive:", "#", ppToken->name);
            break;
        }
    } else if (token != '\n' && token != EndOfInput)
        parseContext.ppError(ppToken->loc, "invalid directive", "#", "");

    while (token != '\n' && token != EndOfInput)
        token = scanToken(ppToken);

    return token;
}

// Context-dependent parsing of a #include <header-name>.
// Assumes no macro expansions etc. are being done; the name is just on the current input.
// Always creates a name and returns PpAtomicConstString, unless we run out of input.
int TPpContext::scanHeaderName(TPpToken* ppToken, char delimit)
{
    bool tooLong = false;

    if (inputStack.empty())
        return EndOfInput;

    int len = 0;
    ppToken->name[0] = '\0';
    do {
        int ch = inputStack.back()->getch();

        // done yet?
        if (ch == delimit) {
            ppToken->name[len] = '\0';
            if (tooLong)
                parseContext.ppError(ppToken->loc, "header name too long", "", "");
            return PpAtomConstString;
        } else if (ch == EndOfInput)
            return EndOfInput;

        // found a character to expand the name with
        if (len < MaxTokenLength)
            ppToken->name[len++] = (char)ch;
        else
            tooLong = true;
    } while (true);
}

// Macro-expand a macro argument 'arg' to create 'expandedArg'.
// Does not replace 'arg'.
// Returns nullptr if no expanded argument is created.
TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* ppToken, bool newLineOkay)
{
    // expand the argument
    TokenStream* expandedArg = new TokenStream;
    pushInput(new tMarkerInput(this));
    pushTokenStreamInput(arg);
    int token;
    while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) {
        token = tokenPaste(token, *ppToken);
        if (token == PpAtomIdentifier) {
            switch (MacroExpand(ppToken, false, newLineOkay)) {
            case MacroExpandNotStarted:
                break;
            case MacroExpandError:
                token = EndOfInput;
                break;
            case MacroExpandStarted:
            case MacroExpandUndef:
                continue;
            }
        }
        if (token == tMarkerInput::marker || token == EndOfInput)
            break;
        expandedArg->putToken(token, ppToken);
    }

    if (token == EndOfInput) {
        // Error, or MacroExpand ate the marker, so had bad input, recover
        delete expandedArg;
        expandedArg = nullptr;
    } else {
        // remove the marker
        popInput();
    }

    return expandedArg;
}

//
// Return the next token for a macro expansion, handling macro arguments,
// whose semantics are dependent on being adjacent to ##.
//
int TPpContext::tMacroInput::scan(TPpToken* ppToken)
{
    int token;
    do {
        token = mac->body.getToken(pp->parseContext, ppToken);
    } while (token == ' ');  // handle white space in macro

    // Hash operators basically turn off a round of macro substitution
    // (the round done on the argument before the round done on the RHS of the
    // macro definition):
    //
    // "A parameter in the replacement list, unless preceded by a # or ##
    // preprocessing token or followed by a ## preprocessing token (see below),
    // is replaced by the corresponding argument after all macros contained
    // therein have been expanded."
    //
    // "If, in the replacement list, a parameter is immediately preceded or
    // followed by a ## preprocessing token, the parameter is replaced by the
    // corresponding argument's preprocessing token sequence."

    bool pasting = false;
    if (postpaste) {
        // don't expand next token
        pasting = true;
        postpaste = false;
    }

    if (prepaste) {
        // already know we should be on a ##, verify
        assert(token == PpAtomPaste);
        prepaste = false;
        postpaste = true;
    }

    // see if are preceding a ##
    if (mac->body.peekUntokenizedPasting()) {
        prepaste = true;
        pasting = true;
    }

    // HLSL does expand macros before concatenation
    if (pasting && pp->parseContext.isReadingHLSL())
        pasting = false;

    // TODO: preprocessor:  properly handle whitespace (or lack of it) between tokens when expanding
    if (token == PpAtomIdentifier) {
        int i;
        for (i = (int)mac->args.size() - 1; i >= 0; i--)
            if (strcmp(pp->atomStrings.getString(mac->args[i]), ppToken->name) == 0)
                break;
        if (i >= 0) {
            TokenStream* arg = expandedArgs[i];
            if (arg == nullptr || pasting)
                arg = args[i];
            pp->pushTokenStreamInput(*arg, prepaste);

            return pp->scanToken(ppToken);
        }
    }

    if (token == EndOfInput)
        mac->busy = 0;

    return token;
}

// return a textual zero, for scanning a macro that was never defined
int TPpContext::tZeroInput::scan(TPpToken* ppToken)
{
    if (done)
        return EndOfInput;

    strcpy(ppToken->name, "0");
    ppToken->ival = 0;
    ppToken->space = false;
    done = true;

    return PpAtomConstInt;
}

//
// Check a token to see if it is a macro that should be expanded:
// - If it is, and defined, push a tInput that will produce the appropriate
//   expansion and return MacroExpandStarted.
// - If it is, but undefined, and expandUndef is requested, push a tInput
//   that will expand to 0 and return MacroExpandUndef.
// - Otherwise, there is no expansion, and there are two cases:
//   * It might be okay there is no expansion, and no specific error was
//     detected. Returns MacroExpandNotStarted.
//   * The expansion was started, but could not be completed, due to an error
//     that cannot be recovered from. Returns MacroExpandError.
//
MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay)
{
    ppToken->space = false;
    int macroAtom = atomStrings.getAtom(ppToken->name);
    switch (macroAtom) {
    case PpAtomLineMacro:
        ppToken->ival = parseContext.getCurrentLoc().line;
        snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return MacroExpandStarted;

    case PpAtomFileMacro: {
        if (parseContext.getCurrentLoc().name)
            parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__");
        ppToken->ival = parseContext.getCurrentLoc().string;
        snprintf(ppToken->name, sizeof(ppToken->name), "%s", ppToken->loc.getStringNameOrNum().c_str());
        UngetToken(PpAtomConstInt, ppToken);
        return MacroExpandStarted;
    }

    case PpAtomVersionMacro:
        ppToken->ival = parseContext.version;
        snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return MacroExpandStarted;

    default:
        break;
    }

    MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom);

    // no recursive expansions
    if (macro != nullptr && macro->busy)
        return MacroExpandNotStarted;

    // not expanding undefined macros
    if ((macro == nullptr || macro->undef) && ! expandUndef)
        return MacroExpandNotStarted;

    // 0 is the value of an undefined macro
    if ((macro == nullptr || macro->undef) && expandUndef) {
        pushInput(new tZeroInput(this));
        return MacroExpandUndef;
    }

    tMacroInput *in = new tMacroInput(this);

    TSourceLoc loc = ppToken->loc;  // in case we go to the next line before discovering the error
    in->mac = macro;
    if (macro->functionLike) {
        // We don't know yet if this will be a successful call of a
        // function-like macro; need to look for a '(', but without trashing
        // the passed in ppToken, until we know we are no longer speculative.
        TPpToken parenToken;
        int token = scanToken(&parenToken);
        if (newLineOkay) {
            while (token == '\n')
                token = scanToken(&parenToken);
        }
        if (token != '(') {
            // Function-like macro called with object-like syntax: okay, don't expand.
            // (We ate exactly one token that might not be white space; put it back.
            UngetToken(token, &parenToken);
            delete in;
            return MacroExpandNotStarted;
        }
        in->args.resize(in->mac->args.size());
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->args[i] = new TokenStream;
        in->expandedArgs.resize(in->mac->args.size());
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->expandedArgs[i] = nullptr;
        size_t arg = 0;
        bool tokenRecorded = false;
        do {
            TVector<char> nestStack;
            while (true) {
                token = scanToken(ppToken);
                if (token == EndOfInput || token == tMarkerInput::marker) {
                    parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
                    delete in;
                    return MacroExpandError;
                }
                if (token == '\n') {
                    if (! newLineOkay) {
                        parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", atomStrings.getString(macroAtom));
                        delete in;
                        return MacroExpandError;
                    }
                    continue;
                }
                if (token == '#') {
                    parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", atomStrings.getString(macroAtom));
                    delete in;
                    return MacroExpandError;
                }
                if (in->mac->args.size() == 0 && token != ')')
                    break;
                if (nestStack.size() == 0 && (token == ',' || token == ')'))
                    break;
                if (token == '(')
                    nestStack.push_back(')');
                else if (token == '{' && parseContext.isReadingHLSL())
                    nestStack.push_back('}');
                else if (nestStack.size() > 0 && token == nestStack.back())
                    nestStack.pop_back();
                in->args[arg]->putToken(token, ppToken);
                tokenRecorded = true;
            }
            // end of single argument scan

            if (token == ')') {
                // closing paren of call
                if (in->mac->args.size() == 1 && tokenRecorded == 0)
                    break;
                arg++;
                break;
            }
            arg++;
        } while (arg < in->mac->args.size());
        // end of all arguments scan

        if (arg < in->mac->args.size())
            parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom));
        else if (token != ')') {
            // Error recover code; find end of call, if possible
            int depth = 0;
            while (token != EndOfInput && (depth > 0 || token != ')')) {
                if (token == ')' || token == '}')
                    depth--;
                token = scanToken(ppToken);
                if (token == '(' || token == '{')
                    depth++;
            }

            if (token == EndOfInput) {
                parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
                delete in;
                return MacroExpandError;
            }
            parseContext.ppError(loc, "Too many args in macro", "macro expansion", atomStrings.getString(macroAtom));
        }

        // We need both expanded and non-expanded forms of the argument, for whether or
        // not token pasting will be applied later when the argument is consumed next to ##.
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->expandedArgs[i] = PrescanMacroArg(*in->args[i], ppToken, newLineOkay);
    }

    pushInput(in);
    macro->busy = 1;
    macro->body.reset();

    return MacroExpandStarted;
}

} // end namespace glslang
