Пример #1
0
// Handle #line
int TPpContext::CPPline(TPpToken* ppToken) 
{
    int token = currentInput->scan(this, currentInput, ppToken);
    if (token == '\n') {
        parseContext.error(ppToken->loc, "must by followed by an integral literal", "#line", "");
        return token;
    }

    int lineRes = 0;
    bool lineErr = false;
    token = eval(token, MIN_PRECEDENCE, lineRes, lineErr, ppToken);
    if (! lineErr) {
        if (token == '\n')
            ++lineRes;
        parseContext.setCurrentLine(lineRes);
        if (token != '\n') {
            int fileRes = 0;
            bool fileErr = false;
            token = eval(token, MIN_PRECEDENCE, fileRes, fileErr, ppToken);
            if (! fileErr)
                parseContext.setCurrentString(fileRes);
        }
    }
    token = extraTokenCheck(lineAtom, ppToken, token);

    return token;
}
Пример #2
0
// 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 = GetAtomString(LookUpAddString(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;
}
Пример #3
0
// Handle #if
int TPpContext::CPPif(TPpToken* ppToken) 
{
    int token = scanToken(ppToken);
    elsetracker++;
    ifdepth++;
    if (ifdepth > maxIfNesting) {
        parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
        return 0;
    }
    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;
}
Пример #4
0
// Handle #if
int TPpContext::CPPif(TPpToken* ppToken) 
{
    int token = currentInput->scan(this, currentInput, ppToken);
    elsetracker++;
    if (! ifdepth++)
        ifloc = ppToken->loc;
    if (ifdepth > maxIfNesting) {
        parseContext.error(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
        return 0;
    }
    int res = 0;
    bool err = false;
    token = eval(token, MIN_PRECEDENCE, res, err, ppToken);
    token = extraTokenCheck(ifAtom, ppToken, token);
    if (!res && !err)
        token = CPPelse(1, ppToken);

    return token;
}
Пример #5
0
int TPpContext::readCPPline(TPpToken* ppToken)
{
    int token = scanToken(ppToken);

    if (token == PpAtomIdentifier) {
        switch (ppToken->atom) {
        case PpAtomDefine:
            token = CPPdefine(ppToken);
            break;
        case PpAtomElse:
            if (elsetracker[elseSeen])
                parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
            elsetracker[elseSeen] = true;
            if (! ifdepth)
                parseContext.ppError(ppToken->loc, "mismatched statements", "#else", "");
            token = extraTokenCheck(PpAtomElse, ppToken, scanToken(ppToken));
            token = CPPelse(0, ppToken);
            break;
        case PpAtomElif:
            if (! ifdepth)
                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:
            elseSeen[elsetracker] = false;
            --elsetracker;
            if (! ifdepth)
                parseContext.ppError(ppToken->loc, "mismatched statements", "#endif", "");
            else
                --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:
            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;
}
Пример #6
0
/* 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 atom;
    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;

        atom = ppToken->atom;
        if (atom == PpAtomIf || atom == PpAtomIfdef || atom == PpAtomIfndef) {
            depth++; 
            ifdepth++; 
            elsetracker++;
        } else if (atom == PpAtomEndif) {
            token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
            elseSeen[elsetracker] = false;
            --elsetracker;
            if (depth == 0) {
                // found the #endif we are looking for
                if (ifdepth) 
                    --ifdepth;
                break;
            }
            --depth;
            --ifdepth;
        } else if (matchelse && depth == 0) {
            if (atom == PpAtomElse) {
                elseSeen[elsetracker] = true;
                token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
                // found the #else we are looking for
                break;
            } else if (atom == 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) {
                    --ifdepth;
                    elseSeen[elsetracker] = false;
                    --elsetracker;
                }

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

    return token;
}
Пример #7
0
int TPpContext::readCPPline(TPpToken* ppToken)
{
    int token = currentInput->scan(this, currentInput, ppToken);
    bool isVersion = false;

    if (token == CPP_IDENTIFIER) {
        if (ppToken->atom == defineAtom) {
            token = CPPdefine(ppToken);
        } else if (ppToken->atom == elseAtom) {
            if (! elsetracker[elseSeen]) {
                elsetracker[elseSeen] = true;
                if (! ifdepth)
                    parseContext.error(ppToken->loc, "mismatched statements", "#else", "");
                token = extraTokenCheck(elseAtom, ppToken, currentInput->scan(this, currentInput, ppToken));
                token = CPPelse(0, ppToken);
            } else {
                parseContext.error(ppToken->loc, "#else after a #else", "#else", "");
                ifdepth = 0;
                return 0;
            }
        } else if (ppToken->atom == elifAtom) {
            if (! ifdepth)
                parseContext.error(ppToken->loc, "mismatched statements", "#elif", "");
            // this token is really a dont care, but we still need to eat the tokens
            token = currentInput->scan(this, currentInput, ppToken); 
            while (token != '\n')
                token = currentInput->scan(this, currentInput, ppToken);
            token = CPPelse(0, ppToken);
        } else if (ppToken->atom == endifAtom) {
            elseSeen[elsetracker] = false;
            --elsetracker;
            if (! ifdepth)
                parseContext.error(ppToken->loc, "mismatched statements", "#endif", "");
            else
                --ifdepth;
            token = extraTokenCheck(endifAtom, ppToken, currentInput->scan(this, currentInput, ppToken));
        } else if (ppToken->atom == ifAtom) {
            token = CPPif (ppToken);
        } else if (ppToken->atom == ifdefAtom) {
            token = CPPifdef(1, ppToken);
        } else if (ppToken->atom == ifndefAtom) {
            token = CPPifdef(0, ppToken);
        } else if (ppToken->atom == lineAtom) {
            token = CPPline(ppToken);
        } else if (ppToken->atom == pragmaAtom) {
            token = CPPpragma(ppToken);
        } else if (ppToken->atom == undefAtom) {
            token = CPPundef(ppToken);
        } else if (ppToken->atom == errorAtom) {
            token = CPPerror(ppToken);
        } else if (ppToken->atom == versionAtom) {
            token = CPPversion(ppToken);
            isVersion = true;
        } else if (ppToken->atom == extensionAtom) {
            token = CPPextension(ppToken);
        } else {
            parseContext.error(ppToken->loc, "invalid directive:", "#", GetAtomString(ppToken->atom));
        }
    } else if (token != '\n' && token > 0)
        parseContext.error(ppToken->loc, "invalid directive", "#", "");

    while (token != '\n' && token != 0 && token != EOF)
        token = currentInput->scan(this, currentInput, ppToken);

    return token;
}
Пример #8
0
/* 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 atom;
    int depth = 0;
    int token = currentInput->scan(this, currentInput, ppToken);

    while (token != EOF) {
        if (token != '#') {
            while (token != '\n' && token != EOF)
                token = currentInput->scan(this, currentInput, ppToken);
            
            if (token == EOF)
                return EOF;

            token = currentInput->scan(this, currentInput, ppToken);
            continue;
        }

        if ((token = currentInput->scan(this, currentInput, ppToken)) != CPP_IDENTIFIER)
            continue;

        atom = ppToken->atom;
        if (atom == ifAtom || atom == ifdefAtom || atom == ifndefAtom) {
            depth++; 
            ifdepth++; 
            elsetracker++;
        } else if (atom == endifAtom) {
            token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
            elseSeen[elsetracker] = false;
            --elsetracker;
            if (depth == 0) {
                // found the #endif we are looking for
                if (ifdepth) 
                    --ifdepth;
                break;
            }
            --depth;
            --ifdepth;
        } else if (matchelse && depth == 0) {
            if (atom == elseAtom ) {
                token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
                // found the #else we are looking for
                break;
            } else if (atom == elifAtom) {
                /* we decrement ifdepth here, because CPPif will increment
                * it and we really want to leave it alone */
                if (ifdepth) {
                    --ifdepth;
                    elseSeen[elsetracker] = false;
                    --elsetracker;
                }

                return CPPif(ppToken);
            }
        } else if (atom == elseAtom) {
            if (elseSeen[elsetracker])
                parseContext.error(ppToken->loc, "#else after #else", "#else", "");
            else
                elseSeen[elsetracker] = true;
            token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
        } else if (atom == elifAtom) {
            if (elseSeen[elsetracker])
                parseContext.error(ppToken->loc, "#elif after #else", "#else", "");
        }
    }

    return token;
}