Merge topic 'math-err'

406f397e8b math: Restore toleration of unexpected characters in an expression
dd5c54600b cmExprParserHelper: Simplify error state tracking
185bcface4 cmExprParserHelper: Remove some unused code

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2218
This commit is contained in:
Brad King
2018-07-17 11:14:42 +00:00
committed by Kitware Robot
12 changed files with 104 additions and 92 deletions
+1 -1
View File
@@ -1050,7 +1050,7 @@ YY_RULE_SETUP
YY_BREAK
case 17:
YY_RULE_SETUP
{return exp_UNEXPECTED;}
{ yyextra->UnexpectedChar(yytext[0]); }
YY_BREAK
case 18:
YY_RULE_SETUP
+1 -1
View File
@@ -58,6 +58,6 @@ Modify cmExprLexer.cxx:
">>" { return exp_SHIFTRIGHT; }
"(" { return exp_OPENPARENT; }
")" { return exp_CLOSEPARENT; }
. {return exp_UNEXPECTED;}
. { yyextra->UnexpectedChar(yytext[0]); }
%%
+64 -67
View File
@@ -157,8 +157,7 @@ extern int cmExpr_yydebug;
exp_AND = 268,
exp_XOR = 269,
exp_NOT = 270,
exp_NUMBER = 271,
exp_UNEXPECTED = 272
exp_NUMBER = 271
};
#endif
/* Tokens. */
@@ -176,7 +175,6 @@ extern int cmExpr_yydebug;
#define exp_XOR 269
#define exp_NOT 270
#define exp_NUMBER 271
#define exp_UNEXPECTED 272
/* Value type. */
@@ -188,7 +186,7 @@ int cmExpr_yyparse (yyscan_t yyscanner);
/* Copy the second part of user declarations. */
#line 192 "cmExprParser.cxx" /* yacc.c:358 */
#line 190 "cmExprParser.cxx" /* yacc.c:358 */
#ifdef short
# undef short
@@ -433,7 +431,7 @@ union yyalloc
#define YYLAST 30
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 18
#define YYNTOKENS 17
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 10
/* YYNRULES -- Number of rules. */
@@ -444,7 +442,7 @@ union yyalloc
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
#define YYMAXUTOK 272
#define YYMAXUTOK 271
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -480,16 +478,16 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17
15, 16
};
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
0, 75, 75, 80, 83, 88, 91, 96, 99, 104,
107, 110, 115, 118, 121, 126, 129, 132, 138, 143,
146, 149, 154, 157
0, 74, 74, 79, 82, 87, 90, 95, 98, 103,
106, 109, 114, 117, 120, 125, 128, 131, 137, 142,
145, 148, 153, 156
};
#endif
@@ -501,9 +499,8 @@ static const char *const yytname[] =
"$end", "error", "$undefined", "exp_PLUS", "exp_MINUS", "exp_TIMES",
"exp_DIVIDE", "exp_MOD", "exp_SHIFTLEFT", "exp_SHIFTRIGHT",
"exp_OPENPARENT", "exp_CLOSEPARENT", "exp_OR", "exp_AND", "exp_XOR",
"exp_NOT", "exp_NUMBER", "\"character\"", "$accept", "start", "exp",
"bitwiseor", "bitwisexor", "bitwiseand", "shift", "term", "unary",
"factor", YY_NULLPTR
"exp_NOT", "exp_NUMBER", "$accept", "start", "exp", "bitwiseor",
"bitwisexor", "bitwiseand", "shift", "term", "unary", "factor", YY_NULLPTR
};
#endif
@@ -513,7 +510,7 @@ static const char *const yytname[] =
static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272
265, 266, 267, 268, 269, 270, 271
};
# endif
@@ -583,18 +580,18 @@ static const yytype_int8 yycheck[] =
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
0, 3, 4, 10, 16, 19, 20, 21, 22, 23,
24, 25, 26, 27, 26, 26, 20, 0, 12, 14,
13, 8, 9, 3, 4, 5, 6, 7, 11, 21,
22, 23, 24, 24, 25, 25, 26, 26, 26
0, 3, 4, 10, 16, 18, 19, 20, 21, 22,
23, 24, 25, 26, 25, 25, 19, 0, 12, 14,
13, 8, 9, 3, 4, 5, 6, 7, 11, 20,
21, 22, 23, 23, 24, 24, 25, 25, 25
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
0, 18, 19, 20, 20, 21, 21, 22, 22, 23,
23, 23, 24, 24, 24, 25, 25, 25, 25, 26,
26, 26, 27, 27
0, 17, 18, 19, 19, 20, 20, 21, 21, 22,
22, 22, 23, 23, 23, 24, 24, 24, 24, 25,
25, 25, 26, 26
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
@@ -1285,186 +1282,186 @@ yyreduce:
switch (yyn)
{
case 2:
#line 75 "cmExprParser.y" /* yacc.c:1646 */
#line 74 "cmExprParser.y" /* yacc.c:1646 */
{
cmExpr_yyget_extra(yyscanner)->SetResult((yyvsp[0].Number));
}
#line 1293 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1290 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 3:
#line 80 "cmExprParser.y" /* yacc.c:1646 */
#line 79 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1301 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1298 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 4:
#line 83 "cmExprParser.y" /* yacc.c:1646 */
#line 82 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[-2].Number) | (yyvsp[0].Number);
}
#line 1309 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1306 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 5:
#line 88 "cmExprParser.y" /* yacc.c:1646 */
#line 87 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1317 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1314 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 6:
#line 91 "cmExprParser.y" /* yacc.c:1646 */
#line 90 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[-2].Number) ^ (yyvsp[0].Number);
}
#line 1325 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1322 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 7:
#line 96 "cmExprParser.y" /* yacc.c:1646 */
#line 95 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1333 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1330 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 8:
#line 99 "cmExprParser.y" /* yacc.c:1646 */
#line 98 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[-2].Number) & (yyvsp[0].Number);
}
#line 1341 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1338 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 9:
#line 104 "cmExprParser.y" /* yacc.c:1646 */
#line 103 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1349 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1346 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 10:
#line 107 "cmExprParser.y" /* yacc.c:1646 */
#line 106 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[-2].Number) << (yyvsp[0].Number);
}
#line 1357 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1354 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 11:
#line 110 "cmExprParser.y" /* yacc.c:1646 */
#line 109 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[-2].Number) >> (yyvsp[0].Number);
}
#line 1365 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1362 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 12:
#line 115 "cmExprParser.y" /* yacc.c:1646 */
#line 114 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1373 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1370 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 13:
#line 118 "cmExprParser.y" /* yacc.c:1646 */
#line 117 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[-2].Number) + (yyvsp[0].Number);
}
#line 1381 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1378 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 14:
#line 121 "cmExprParser.y" /* yacc.c:1646 */
#line 120 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[-2].Number) - (yyvsp[0].Number);
}
#line 1389 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1386 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 15:
#line 126 "cmExprParser.y" /* yacc.c:1646 */
#line 125 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1397 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1394 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 16:
#line 129 "cmExprParser.y" /* yacc.c:1646 */
#line 128 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[-2].Number) * (yyvsp[0].Number);
}
#line 1405 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1402 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 17:
#line 132 "cmExprParser.y" /* yacc.c:1646 */
#line 131 "cmExprParser.y" /* yacc.c:1646 */
{
if (yyvsp[0].Number == 0) {
throw std::overflow_error("divide by zero");
}
(yyval.Number) = (yyvsp[-2].Number) / (yyvsp[0].Number);
}
#line 1416 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1413 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 18:
#line 138 "cmExprParser.y" /* yacc.c:1646 */
#line 137 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[-2].Number) % (yyvsp[0].Number);
}
#line 1424 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1421 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 19:
#line 143 "cmExprParser.y" /* yacc.c:1646 */
#line 142 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1432 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1429 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 20:
#line 146 "cmExprParser.y" /* yacc.c:1646 */
#line 145 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = + (yyvsp[0].Number);
}
#line 1440 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1437 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 21:
#line 149 "cmExprParser.y" /* yacc.c:1646 */
#line 148 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = - (yyvsp[0].Number);
}
#line 1448 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1445 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 22:
#line 154 "cmExprParser.y" /* yacc.c:1646 */
#line 153 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[0].Number);
}
#line 1456 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1453 "cmExprParser.cxx" /* yacc.c:1646 */
break;
case 23:
#line 157 "cmExprParser.y" /* yacc.c:1646 */
#line 156 "cmExprParser.y" /* yacc.c:1646 */
{
(yyval.Number) = (yyvsp[-1].Number);
}
#line 1464 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1461 "cmExprParser.cxx" /* yacc.c:1646 */
break;
#line 1468 "cmExprParser.cxx" /* yacc.c:1646 */
#line 1465 "cmExprParser.cxx" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1694,7 +1691,7 @@ yyreturn:
#endif
return yyresult;
}
#line 162 "cmExprParser.y" /* yacc.c:1906 */
#line 161 "cmExprParser.y" /* yacc.c:1906 */
/* End of grammar */
-1
View File
@@ -64,7 +64,6 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
%token exp_XOR;
%token exp_NOT;
%token exp_NUMBER;
%token exp_UNEXPECTED "character";
/*-------------------------------------------------------------------------*/
/* grammar */
+1 -3
View File
@@ -58,8 +58,7 @@ extern int cmExpr_yydebug;
exp_AND = 268,
exp_XOR = 269,
exp_NOT = 270,
exp_NUMBER = 271,
exp_UNEXPECTED = 272
exp_NUMBER = 271
};
#endif
/* Tokens. */
@@ -77,7 +76,6 @@ extern int cmExpr_yydebug;
#define exp_XOR 269
#define exp_NOT 270
#define exp_NUMBER 271
#define exp_UNEXPECTED 272
/* Value type. */
+11 -15
View File
@@ -20,7 +20,6 @@ cmExprParserHelper::cmExprParserHelper()
cmExprParserHelper::~cmExprParserHelper()
{
this->CleanupParser();
}
int cmExprParserHelper::ParseString(const char* str, int verb)
@@ -40,10 +39,9 @@ int cmExprParserHelper::ParseString(const char* str, int verb)
yyscan_t yyscanner;
cmExpr_yylex_init(&yyscanner);
cmExpr_yyset_extra(this, yyscanner);
int res;
try {
res = cmExpr_yyparse(yyscanner);
int res = cmExpr_yyparse(yyscanner);
if (res != 0) {
std::string e = "cannot parse the expression: \"" + InputBuffer + "\": ";
e += ErrorString;
@@ -56,26 +54,19 @@ int cmExprParserHelper::ParseString(const char* str, int verb)
e += fail.what();
e += ".";
this->SetError(std::move(e));
res = 1;
} catch (std::out_of_range const&) {
std::string e = "cannot evaluate the expression: \"" + InputBuffer +
"\": a numeric value is out of range.";
this->SetError(std::move(e));
res = 1;
} catch (...) {
std::string e = "cannot parse the expression: \"" + InputBuffer + "\".";
this->SetError(std::move(e));
res = 1;
}
cmExpr_yylex_destroy(yyscanner);
if (res != 0) {
// str << "CAL_Parser returned: " << res << std::endl;
// std::cerr << "When parsing: [" << str << "]" << std::endl;
if (!this->ErrorString.empty()) {
return 0;
}
this->CleanupParser();
if (Verbose) {
std::cerr << "Expanding [" << str << "] produced: [" << this->Result << "]"
<< std::endl;
@@ -83,10 +74,6 @@ int cmExprParserHelper::ParseString(const char* str, int verb)
return 1;
}
void cmExprParserHelper::CleanupParser()
{
}
int cmExprParserHelper::LexInput(char* buf, int maxlen)
{
// std::cout << "JPLexInput ";
@@ -114,6 +101,15 @@ void cmExprParserHelper::Error(const char* str)
this->ErrorString = ostr.str();
}
void cmExprParserHelper::UnexpectedChar(char c)
{
unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
std::ostringstream ostr;
ostr << "Unexpected character in expression at position " << pos << ": " << c
<< "\n";
this->WarningString += ostr.str();
}
void cmExprParserHelper::SetResult(KWIML_INT_int64_t value)
{
this->Result = value;
+5 -1
View File
@@ -32,6 +32,10 @@ public:
const char* GetError() { return this->ErrorString.c_str(); }
void UnexpectedChar(char c);
std::string const& GetWarning() const { return this->WarningString; }
private:
std::string::size_type InputBufferPos;
std::string InputBuffer;
@@ -41,13 +45,13 @@ private:
void Print(const char* place, const char* str);
void CleanupParser();
void SetError(std::string errorString);
KWIML_INT_int64_t Result;
const char* FileName;
long FileLine;
std::string ErrorString;
std::string WarningString;
};
#define YYSTYPE cmExprParserHelper::ParserType
+6
View File
@@ -5,6 +5,7 @@
#include "cmExprParserHelper.h"
#include "cmMakefile.h"
#include "cm_kwiml.h"
#include "cmake.h"
#include <stdio.h>
@@ -101,6 +102,11 @@ bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
}
sprintf(buffer, fmt, helper.GetResult());
std::string const& w = helper.GetWarning();
if (!w.empty()) {
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w);
}
this->Makefile->AddDefinition(outputVariable, buffer);
return true;
}
@@ -1,6 +1,5 @@
^CMake Error at MATH-InvalidExpression.cmake:1 \(math\):
*math cannot parse the expression: "INVALID": syntax error, unexpected
*character, expecting exp_PLUS or exp_MINUS or exp_OPENPARENT or exp_NUMBER
*\(1\).
math cannot parse the expression: "INVALID": syntax error, unexpected \$end,
expecting exp_PLUS or exp_MINUS or exp_OPENPARENT or exp_NUMBER \(7\).
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)$
@@ -0,0 +1,8 @@
^CMake Warning \(dev\) at MATH-ToleratedExpression.cmake:1 \(math\):
Unexpected character in expression at position 1: '
Unexpected character in expression at position 7: '
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.$
@@ -0,0 +1,4 @@
math(EXPR var "'2*1-1'")
if(NOT var EQUAL 1)
message(FATAL_ERROR "Expression did not evaluate to 1")
endif()
+1
View File
@@ -5,4 +5,5 @@ run_cmake(MATH-WrongArgument)
run_cmake(MATH-DoubleOption)
run_cmake(MATH-TooManyArguments)
run_cmake(MATH-InvalidExpression)
run_cmake(MATH-ToleratedExpression)
run_cmake(MATH-DivideByZero)