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); }
int DirectiveParser::parseExpressionIf(Token *token) { assert((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF)); MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true); ExpressionParser expressionParser(¯oExpander, 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()))); }
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(¯oExpander, 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; }
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); } }
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(¯oExpander, 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()); }
/*! * 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))); }