コード例 #1
0
ファイル: Pp.cpp プロジェクト: kseitz/glslang
// Handle #include
int TPpContext::CPPinclude(TPpToken* ppToken)
{
    const TSourceLoc directiveLoc = ppToken->loc;
    int token = scanToken(ppToken);
    if (token != PpAtomConstString) {
        // TODO: handle angle brackets.
        parseContext.ppError(directiveLoc, "must be followed by a file designation", "#include", "");
    } else {
        // Make a copy of the name because it will be overwritten by the next token scan.
        const std::string filename = ppToken->name;
        token = scanToken(ppToken);
        if (token != '\n' && token != EndOfInput) {
            parseContext.ppError(ppToken->loc, "extra content after file designation", "#include", "");
        } else {
            std::string sourceName;
            std::string replacement;
            std::tie(sourceName, replacement) = includer.include(filename.c_str());
            if (!sourceName.empty()) {
                if (!replacement.empty()) {
                    const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
                    std::ostringstream content;
                    content << "#line " << forNextLine << " " << "\"" << sourceName << "\"\n";
                    content << replacement << (replacement.back() == '\n' ? "" : "\n");
                    content << "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
                    pushInput(new TokenizableString(directiveLoc, content.str(), this));
                }
                // At EOF, there's no "current" location anymore.
                if (token != EndOfInput) parseContext.setCurrentColumn(0);
                // Don't accidentally return EndOfInput, which will end all preprocessing.
                return '\n';
            } else {
                parseContext.ppError(directiveLoc, replacement.c_str(), "#include", "");
            }
        }
    }
    return token;
}
コード例 #2
0
ファイル: Pp.cpp プロジェクト: Alprog/Judy
// Handle #include
int TPpContext::CPPinclude(TPpToken* ppToken)
{
    const TSourceLoc directiveLoc = ppToken->loc;
    int token = scanToken(ppToken);
    if (token != PpAtomConstString) {
        // TODO: handle angle brackets.
        parseContext.ppError(directiveLoc, "must be followed by a file designation", "#include", "");
    } else {
        // Make a copy of the name because it will be overwritten by the next token scan.
        const std::string filename = ppToken->name;
        token = scanToken(ppToken);
        if (token != '\n' && token != EndOfInput) {
            parseContext.ppError(ppToken->loc, "extra content after file designation", "#include", "");
        } else {
            TShader::Includer::IncludeResult* res = includer.include(filename.c_str(), TShader::Includer::EIncludeRelative, currentSourceFile.c_str(), includeStack.size() + 1);
            if (res && !res->file_name.empty()) {
                if (res->file_data && res->file_length) {
                    const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
                    std::ostringstream prologue;
                    std::ostringstream epilogue;
                    prologue << "#line " << forNextLine << " " << "\"" << res->file_name << "\"\n";
                    epilogue << (res->file_data[res->file_length - 1] == '\n'? "" : "\n") << "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
                    pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this));
                }
                // At EOF, there's no "current" location anymore.
                if (token != EndOfInput) parseContext.setCurrentColumn(0);
                // Don't accidentally return EndOfInput, which will end all preprocessing.
                return '\n';
            } else {
                std::string message =
                    res ? std::string(res->file_data, res->file_length)
                        : std::string("Could not process include directive");
                parseContext.ppError(directiveLoc, message.c_str(), "#include", "");
                if (res) {
                    includer.releaseInclude(res);
                }
            }
        }
    }
    return token;
}
コード例 #3
0
ファイル: Pp.cpp プロジェクト: MIPS/prebuilts-ndk
// 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;
}