BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
    : ProjectConfiguration(target, id)
{
    Utils::MacroExpander *expander = macroExpander();
    expander->setDisplayName(tr("Build Settings"));
    expander->setAccumulating(true);
    expander->registerSubProvider([target] { return target->macroExpander(); });

    expander->registerVariable("buildDir", tr("Build directory"),
            [this] { return buildDirectory().toUserOutput(); });

    expander->registerVariable(Constants::VAR_CURRENTBUILD_NAME, tr("Name of current build"),
            [this] { return displayName(); }, false);

    expander->registerPrefix(Constants::VAR_CURRENTBUILD_ENV,
                             tr("Variables in the current build environment"),
                             [this](const QString &var) { return environment().value(var); });

    updateCacheAndEmitEnvironmentChanged();
    connect(target, &Target::kitChanged,
            this, &BuildConfiguration::updateCacheAndEmitEnvironmentChanged);
    connect(this, &BuildConfiguration::environmentChanged,
            this, &BuildConfiguration::emitBuildDirectoryChanged);
    // Many macroexpanders are based on the current project, so they may change the environment:
    connect(ProjectTree::instance(), &ProjectTree::currentProjectChanged,
            this, &BuildConfiguration::updateCacheAndEmitEnvironmentChanged);
}
示例#2
0
int DirectiveParser::parseExpressionIf(Token *token)
{
    assert((getDirective(token) == DIRECTIVE_IF) ||
           (getDirective(token) == DIRECTIVE_ELIF));

    MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true);
    ExpressionParser expressionParser(&macroExpander, mDiagnostics);

    int expression = 0;
    ExpressionParser::ErrorSettings errorSettings;
    errorSettings.integerLiteralsMustFit32BitSignedRange = false;
    errorSettings.unexpectedIdentifier                   = Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN;

    bool valid = true;
    expressionParser.parse(token, &expression, false, errorSettings, &valid);

    // Check if there are tokens after #if expression.
    if (!isEOD(token))
    {
        mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
                             token->location, token->text);
        skipUntilEOD(mTokenizer, token);
    }

    return expression;
}
QString QbsRunConfiguration::workingDirectory() const
{
    ProjectExplorer::EnvironmentAspect *aspect
            = extraAspect<ProjectExplorer::EnvironmentAspect>();
    QTC_ASSERT(aspect, baseWorkingDirectory());
    return QDir::cleanPath(aspect->environment().expandVariables(
                Utils::expandMacros(baseWorkingDirectory(), macroExpander())));
}
示例#4
0
int DirectiveParser::parseExpressionIf(Token *token)
{
    assert((getDirective(token) == DIRECTIVE_IF) ||
           (getDirective(token) == DIRECTIVE_ELIF));

    DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics);
    MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics);
    ExpressionParser expressionParser(&macroExpander, mDiagnostics);

    int expression = 0;
    macroExpander.lex(token);
    expressionParser.parse(token, &expression);

    // Warn if there are tokens after #if expression.
    if (!isEOD(token))
    {
        mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
                             token->location, token->text);
        skipUntilEOD(mTokenizer, token);
    }

    return expression;
}
示例#5
0
void DirectiveParser::parseLine(Token *token)
{
    assert(getDirective(token) == DIRECTIVE_LINE);

    enum State
    {
        LINE_NUMBER,
        FILE_NUMBER
    };

    bool valid = true;
    int line = 0, file = 0;
    int state = LINE_NUMBER;

    MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics);
    macroExpander.lex(token);
    while ((token->type != '\n') && (token->type != Token::LAST))
    {
        switch (state++)
        {
          case LINE_NUMBER:
            if (valid && (token->type != Token::CONST_INT))
            {
                mDiagnostics->report(Diagnostics::PP_INVALID_LINE_NUMBER,
                                     token->location, token->text);
                valid = false;
            }
            if (valid && !token->iValue(&line))
            {
                mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW,
                                     token->location, token->text);
                valid = false;
            }
            break;
          case FILE_NUMBER:
            if (valid && (token->type != Token::CONST_INT))
            {
                mDiagnostics->report(Diagnostics::PP_INVALID_FILE_NUMBER,
                                     token->location, token->text);
                valid = false;
            }
            if (valid && !token->iValue(&file))
            {
                mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW,
                                     token->location, token->text);
                valid = false;
            }
            break;
          default:
            if (valid)
            {
                mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
                                     token->location, token->text);
                valid = false;
            }
            break;
        }
        macroExpander.lex(token);
    }

    if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1))
    {
        mDiagnostics->report(Diagnostics::PP_INVALID_LINE_DIRECTIVE,
                             token->location, token->text);
        valid = false;
    }
    if (valid)
    {
        mTokenizer->setLineNumber(line);
        if (state == FILE_NUMBER + 1)
            mTokenizer->setFileNumber(file);
    }
}
示例#6
0
void DirectiveParser::parseLine(Token *token)
{
    assert(getDirective(token) == DIRECTIVE_LINE);

    bool valid = true;
    bool parsedFileNumber = false;
    int line = 0, file = 0;

    MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false);

    // Lex the first token after "#line" so we can check it for EOD.
    macroExpander.lex(token);

    if (isEOD(token))
    {
        mDiagnostics->report(Diagnostics::PP_INVALID_LINE_DIRECTIVE, token->location, token->text);
        valid = false;
    }
    else
    {
        ExpressionParser expressionParser(&macroExpander, mDiagnostics);
        ExpressionParser::ErrorSettings errorSettings;

        // See GLES3 section 12.42
        errorSettings.integerLiteralsMustFit32BitSignedRange = true;

        errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_LINE_NUMBER;
        // The first token was lexed earlier to check if it was EOD. Include
        // the token in parsing for a second time by setting the
        // parsePresetToken flag to true.
        expressionParser.parse(token, &line, true, errorSettings, &valid);
        if (!isEOD(token) && valid)
        {
            errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_FILE_NUMBER;
            // After parsing the line expression expressionParser has also
            // advanced to the first token of the file expression - this is the
            // token that makes the parser reduce the "input" rule for the line
            // expression and stop. So we're using parsePresetToken = true here
            // as well.
            expressionParser.parse(token, &file, true, errorSettings, &valid);
            parsedFileNumber = true;
        }
        if (!isEOD(token))
        {
            if (valid)
            {
                mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
                                     token->location, token->text);
                valid = false;
            }
            skipUntilEOD(mTokenizer, token);
        }
    }

    if (valid)
    {
        mTokenizer->setLineNumber(line);
        if (parsedFileNumber)
            mTokenizer->setFileNumber(file);
    }
}
QString QbsRunConfiguration::commandLineArguments() const
{
    return Utils::QtcProcess::expandMacros(m_commandLineArguments, macroExpander());
}
示例#8
0
/*!
 * Returns \a stringWithVariables with all variables replaced by their values.
 * See the VariableManager overview documentation for other ways to expand variables.
 *
 * \sa VariableManager
 * \sa macroExpander()
 */
QString VariableManager::expandedString(const QString &stringWithVariables)
{
    return Utils::expandMacros(stringWithVariables, macroExpander());
}
Utils::FileName BuildConfiguration::buildDirectory() const
{
    const QString path = QDir::cleanPath(macroExpander()->expand(environment().expandVariables(m_buildDirectory.toString())));
    return Utils::FileName::fromString(QDir::cleanPath(QDir(target()->project()->projectDirectory().toString()).absoluteFilePath(path)));
}