diff options
author | Daniel Franke <franke@edf-online.de> | 2018-05-18 19:59:46 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2018-07-03 13:55:58 (GMT) |
commit | 5dbee9d2d0f68e1fc343d04ac00a4a35d43df6fa (patch) | |
tree | 85375da2fabdfbc7982fe4ba58a76acc3167c71e /Source | |
parent | 8661e7052c4f711f13e7168231276e23c4c0defd (diff) | |
download | CMake-5dbee9d2d0f68e1fc343d04ac00a4a35d43df6fa.zip CMake-5dbee9d2d0f68e1fc343d04ac00a4a35d43df6fa.tar.gz CMake-5dbee9d2d0f68e1fc343d04ac00a4a35d43df6fa.tar.bz2 |
math: Add options to calculate and format output as hexadecimal
Diffstat (limited to 'Source')
-rw-r--r-- | Source/LexerParser/cmExprLexer.cxx | 112 | ||||
-rw-r--r-- | Source/LexerParser/cmExprLexer.in.l | 1 | ||||
-rw-r--r-- | Source/cmMathCommand.cxx | 58 |
3 files changed, 118 insertions, 53 deletions
diff --git a/Source/LexerParser/cmExprLexer.cxx b/Source/LexerParser/cmExprLexer.cxx index 93b3ffd..1548daf 100644 --- a/Source/LexerParser/cmExprLexer.cxx +++ b/Source/LexerParser/cmExprLexer.cxx @@ -548,8 +548,8 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 17 -#define YY_END_OF_BUFFER 18 +#define YY_NUM_RULES 18 +#define YY_END_OF_BUFFER 19 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -557,11 +557,11 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[25] = +static const flex_int16_t yy_accept[29] = { 0, - 0, 0, 18, 16, 1, 17, 7, 9, 14, 15, - 5, 3, 4, 6, 2, 16, 16, 10, 8, 11, - 2, 12, 13, 0 + 0, 0, 19, 17, 1, 18, 8, 10, 15, 16, + 6, 4, 5, 7, 2, 2, 17, 17, 11, 9, + 12, 2, 0, 13, 14, 3, 3, 0 } ; static const YY_CHAR yy_ec[256] = @@ -570,16 +570,16 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 4, 5, 1, 6, - 7, 8, 9, 1, 10, 1, 11, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 1, 1, 13, - 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, + 7, 8, 9, 1, 10, 1, 11, 12, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 1, 1, 14, + 1, 15, 1, 1, 16, 16, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, + 1, 1, 1, 18, 1, 1, 16, 16, 16, 16, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 16, 1, 17, 1, 1, 1, 1, + 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 17, + 1, 1, 1, 19, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -596,40 +596,46 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1 } ; -static const YY_CHAR yy_meta[18] = +static const YY_CHAR yy_meta[21] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1 + 1, 2, 2, 1, 1, 3, 4, 1, 1, 1 } ; -static const flex_int16_t yy_base[25] = +static const flex_int16_t yy_base[32] = { 0, - 0, 0, 22, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 9, 7, 5, 23, 23, 23, - 6, 23, 23, 23 + 0, 0, 34, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 16, 9, 18, 11, 35, 35, + 35, 11, 0, 35, 35, 0, 0, 35, 23, 26, + 28 } ; -static const flex_int16_t yy_def[25] = +static const flex_int16_t yy_def[32] = { 0, - 24, 1, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 0 + 28, 1, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 29, 28, 28, 28, 28, 28, + 28, 28, 30, 28, 28, 31, 31, 0, 28, 28, + 28 } ; -static const flex_int16_t yy_nxt[41] = +static const flex_int16_t yy_nxt[56] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 23, 22, - 21, 24, 3, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 + 14, 15, 16, 17, 18, 4, 4, 19, 20, 21, + 22, 22, 22, 22, 22, 25, 22, 26, 26, 27, + 27, 24, 23, 28, 3, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28 } ; -static const flex_int16_t yy_chk[41] = +static const flex_int16_t yy_chk[56] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 21, 17, 16, - 15, 3, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 16, 16, 22, 22, 29, 18, 29, 30, 30, 31, + 31, 17, 15, 3, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28 } ; /* The intent behind this definition is that it'll catch @@ -948,13 +954,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 25 ) + if ( yy_current_state >= 29 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 23 ); + while ( yy_base[yy_current_state] != 35 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -988,62 +994,66 @@ YY_RULE_SETUP YY_BREAK case 3: YY_RULE_SETUP -{ return exp_PLUS; } +{ yylvalp->Number = std::stoll(yytext, nullptr, 16); return exp_NUMBER; } YY_BREAK case 4: YY_RULE_SETUP -{ return exp_MINUS; } +{ return exp_PLUS; } YY_BREAK case 5: YY_RULE_SETUP -{ return exp_TIMES; } +{ return exp_MINUS; } YY_BREAK case 6: YY_RULE_SETUP -{ return exp_DIVIDE; } +{ return exp_TIMES; } YY_BREAK case 7: YY_RULE_SETUP -{ return exp_MOD; } +{ return exp_DIVIDE; } YY_BREAK case 8: YY_RULE_SETUP -{ return exp_OR; } +{ return exp_MOD; } YY_BREAK case 9: YY_RULE_SETUP -{ return exp_AND; } +{ return exp_OR; } YY_BREAK case 10: YY_RULE_SETUP -{ return exp_XOR; } +{ return exp_AND; } YY_BREAK case 11: YY_RULE_SETUP -{ return exp_NOT; } +{ return exp_XOR; } YY_BREAK case 12: YY_RULE_SETUP -{ return exp_SHIFTLEFT; } +{ return exp_NOT; } YY_BREAK case 13: YY_RULE_SETUP -{ return exp_SHIFTRIGHT; } +{ return exp_SHIFTLEFT; } YY_BREAK case 14: YY_RULE_SETUP -{ return exp_OPENPARENT; } +{ return exp_SHIFTRIGHT; } YY_BREAK case 15: YY_RULE_SETUP -{ return exp_CLOSEPARENT; } +{ return exp_OPENPARENT; } YY_BREAK case 16: YY_RULE_SETUP -{return exp_UNEXPECTED;} +{ return exp_CLOSEPARENT; } YY_BREAK case 17: YY_RULE_SETUP +{return exp_UNEXPECTED;} + YY_BREAK +case 18: +YY_RULE_SETUP ECHO; YY_BREAK case YY_STATE_EOF(INITIAL): @@ -1344,7 +1354,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 25 ) + if ( yy_current_state >= 29 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; @@ -1373,11 +1383,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 25 ) + if ( yy_current_state >= 29 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 24); + yy_is_jam = (yy_current_state == 28); (void)yyg; return yy_is_jam ? 0 : yy_current_state; diff --git a/Source/LexerParser/cmExprLexer.in.l b/Source/LexerParser/cmExprLexer.in.l index 0c4eb9e..87237d1 100644 --- a/Source/LexerParser/cmExprLexer.in.l +++ b/Source/LexerParser/cmExprLexer.in.l @@ -43,6 +43,7 @@ Modify cmExprLexer.cxx: [ \t] {} [0-9][0-9]* { yylvalp->Number = std::stoll(yytext, nullptr, 10); return exp_NUMBER; } +0[xX][0-9a-fA-F][0-9a-fA-F]* { yylvalp->Number = std::stoll(yytext, nullptr, 16); return exp_NUMBER; } "+" { return exp_PLUS; } "-" { return exp_MINUS; } diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx index ab77dc3..5d1b099 100644 --- a/Source/cmMathCommand.cxx +++ b/Source/cmMathCommand.cxx @@ -28,16 +28,59 @@ bool cmMathCommand::InitialPass(std::vector<std::string> const& args, bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args) { - if (args.size() != 3) { + if ((args.size() != 3) && (args.size() != 5)) { this->SetError("EXPR called with incorrect arguments."); return false; } + enum class NumericFormat + { + UNINITIALIZED, + DECIMAL, + HEXADECIMAL, + }; + const std::string& outputVariable = args[1]; const std::string& expression = args[2]; + size_t argumentIndex = 3; + NumericFormat outputFormat = NumericFormat::UNINITIALIZED; this->Makefile->AddDefinition(outputVariable, "ERROR"); + if (argumentIndex < args.size()) { + const std::string messageHint = "sub-command EXPR "; + const std::string option = args[argumentIndex++]; + if (option == "OUTPUT_FORMAT") { + if (argumentIndex < args.size()) { + const std::string argument = args[argumentIndex++]; + if (argument == "DECIMAL") { + outputFormat = NumericFormat::DECIMAL; + } else if (argument == "HEXADECIMAL") { + outputFormat = NumericFormat::HEXADECIMAL; + } else { + std::string error = messageHint + "value \"" + argument + + "\" for option \"" + option + "\" is invalid."; + this->SetError(error); + return false; + } + } else { + std::string error = + messageHint + "missing argument for option \"" + option + "\"."; + this->SetError(error); + return false; + } + } else { + std::string error = + messageHint + "option \"" + option + "\" is unknown."; + this->SetError(error); + return false; + } + } + + if (outputFormat == NumericFormat::UNINITIALIZED) { + outputFormat = NumericFormat::DECIMAL; + } + cmExprParserHelper helper; if (!helper.ParseString(expression.c_str(), 0)) { this->SetError(helper.GetError()); @@ -45,7 +88,18 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args) } char buffer[1024]; - sprintf(buffer, "%" KWIML_INT_PRId64, helper.GetResult()); + const char* fmt; + switch (outputFormat) { + case NumericFormat::HEXADECIMAL: + fmt = "0x%" KWIML_INT_PRIx64; + break; + case NumericFormat::DECIMAL: + CM_FALLTHROUGH; + default: + fmt = "%" KWIML_INT_PRId64; + break; + } + sprintf(buffer, fmt, helper.GetResult()); this->Makefile->AddDefinition(outputVariable, buffer); return true; |