Merge branch 'develop' into collected-small-fixes
This commit is contained in:
@ -156,27 +156,28 @@ and Boolean operators:
|
||||
Each A and B is a number or string or a variable reference like $a or
|
||||
${abc}, or A or B can be another Boolean expression.
|
||||
|
||||
If a variable is used it can produce a number when evaluated, like an
|
||||
:doc:`equal-style variable <variable>`. Or it can produce a string,
|
||||
like an :doc:`index-style variable <variable>`. For an individual
|
||||
Boolean operator, A and B must both be numbers or must both be
|
||||
strings. You cannot compare a number to a string.
|
||||
Note that all variables used will be substituted for before the
|
||||
Boolean expression in evaluated. A variable can produce a number,
|
||||
like an :doc:`equal-style variable <variable>`. Or it can produce a
|
||||
string, like an :doc:`index-style variable <variable>`.
|
||||
|
||||
The Boolean operators "==" and "!=" can operate on a pair or strings
|
||||
or numbers. They cannot compare a number to a string. All the other
|
||||
Boolean operations can only operate on numbers.
|
||||
|
||||
Expressions are evaluated left to right and have the usual C-style
|
||||
precedence: the unary logical NOT operator "!" has the highest
|
||||
precedence, the 4 relational operators "<", "<=", ">", and ">=" are
|
||||
next; the two remaining relational operators "==" and "!=" are next;
|
||||
then the logical AND operator "&&"; and finally the logical OR
|
||||
operator "\|\|" and logical XOR (exclusive or) operator "\|\^" have the
|
||||
lowest precedence. Parenthesis can be used to group one or more
|
||||
operator "\|\|" and logical XOR (exclusive or) operator "\|\^" have
|
||||
the lowest precedence. Parenthesis can be used to group one or more
|
||||
portions of an expression and/or enforce a different order of
|
||||
evaluation than what would occur with the default precedence.
|
||||
|
||||
When the 6 relational operators (first 6 in list above) compare 2
|
||||
numbers, they return either a 1.0 or 0.0 depending on whether the
|
||||
relationship between A and B is TRUE or FALSE. When the 6 relational
|
||||
operators compare 2 strings, they also return a 1.0 or 0.0 for TRUE or
|
||||
FALSE, but the comparison is done by the C function strcmp().
|
||||
relationship between A and B is TRUE or FALSE.
|
||||
|
||||
When the 3 logical operators (last 3 in list above) compare 2 numbers,
|
||||
they also return either a 1.0 or 0.0 depending on whether the
|
||||
@ -190,8 +191,16 @@ returns 1.0 if its argument is 0.0, else it returns 0.0. The 3
|
||||
logical operators can only be used to operate on numbers, not on
|
||||
strings.
|
||||
|
||||
The overall Boolean expression produces a TRUE result if the result is
|
||||
non-zero. If the result is zero, the expression result is FALSE.
|
||||
The overall Boolean expression produces a TRUE result if the numeric
|
||||
result is non-zero. If the result is zero, the expression result is
|
||||
FALSE.
|
||||
|
||||
.. note::
|
||||
|
||||
If the Boolean expression is a single numeric value with no Boolean
|
||||
operators, it will be FALSE if the value = 0.0, otherwise TRUE. If
|
||||
the Boolean expression is a single string, an error message will be
|
||||
issued.
|
||||
|
||||
----------
|
||||
|
||||
|
||||
@ -4770,12 +4770,14 @@ double Variable::evaluate_boolean(char *str)
|
||||
}
|
||||
|
||||
if (opprevious == NOT) {
|
||||
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (flag2)
|
||||
error->all(FLERR,"If command boolean not cannot operate on string");
|
||||
if (value2 == 0.0) argstack[nargstack].value = 1.0;
|
||||
else argstack[nargstack].value = 0.0;
|
||||
|
||||
} else if (opprevious == EQ) {
|
||||
if (flag1 != flag2)
|
||||
error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
error->all(FLERR,"If command boolean is comparing string to number");
|
||||
if (flag2 == 0) {
|
||||
if (value1 == value2) argstack[nargstack].value = 1.0;
|
||||
else argstack[nargstack].value = 0.0;
|
||||
@ -4787,7 +4789,7 @@ double Variable::evaluate_boolean(char *str)
|
||||
}
|
||||
} else if (opprevious == NE) {
|
||||
if (flag1 != flag2)
|
||||
error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
error->all(FLERR,"If command boolean is comparing string to number");
|
||||
if (flag2 == 0) {
|
||||
if (value1 != value2) argstack[nargstack].value = 1.0;
|
||||
else argstack[nargstack].value = 0.0;
|
||||
@ -4797,32 +4799,40 @@ double Variable::evaluate_boolean(char *str)
|
||||
delete[] str1;
|
||||
delete[] str2;
|
||||
}
|
||||
|
||||
} else if (opprevious == LT) {
|
||||
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (value1 < value2) argstack[nargstack].value = 1.0;
|
||||
if (flag1 || flag2)
|
||||
error->all(FLERR,"If command boolean can only operate on numbers");
|
||||
else argstack[nargstack].value = 0.0;
|
||||
} else if (opprevious == LE) {
|
||||
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (flag1 || flag2)
|
||||
error->all(FLERR,"If command boolean can only operate on numbers");
|
||||
if (value1 <= value2) argstack[nargstack].value = 1.0;
|
||||
else argstack[nargstack].value = 0.0;
|
||||
} else if (opprevious == GT) {
|
||||
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (flag1 || flag2)
|
||||
error->all(FLERR,"If command boolean can only operate on numbers");
|
||||
if (value1 > value2) argstack[nargstack].value = 1.0;
|
||||
else argstack[nargstack].value = 0.0;
|
||||
} else if (opprevious == GE) {
|
||||
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (flag1 || flag2)
|
||||
error->all(FLERR,"If command boolean can only operate on numbers");
|
||||
if (value1 >= value2) argstack[nargstack].value = 1.0;
|
||||
else argstack[nargstack].value = 0.0;
|
||||
|
||||
} else if (opprevious == AND) {
|
||||
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (flag1 || flag2)
|
||||
error->all(FLERR,"If command boolean can only operate on numbers");
|
||||
if (value1 != 0.0 && value2 != 0.0) argstack[nargstack].value = 1.0;
|
||||
else argstack[nargstack].value = 0.0;
|
||||
} else if (opprevious == OR) {
|
||||
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (flag1 || flag2)
|
||||
error->all(FLERR,"If command boolean can only operate on numbers");
|
||||
if (value1 != 0.0 || value2 != 0.0) argstack[nargstack].value = 1.0;
|
||||
else argstack[nargstack].value = 0.0;
|
||||
} else if (opprevious == XOR) {
|
||||
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (flag1 || flag2)
|
||||
error->all(FLERR,"If command boolean can only operate on numbers");
|
||||
if ((value1 == 0.0 && value2 != 0.0) ||
|
||||
(value1 != 0.0 && value2 == 0.0))
|
||||
argstack[nargstack].value = 1.0;
|
||||
@ -4845,6 +4855,13 @@ double Variable::evaluate_boolean(char *str)
|
||||
|
||||
if (nopstack) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (nargstack != 1) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
|
||||
// if flag == 1, Boolean expression was a single string with no operator
|
||||
// error b/c invalid, only single number with no operator is allowed
|
||||
|
||||
if (argstack[0].flag == 1)
|
||||
error->all(FLERR,"If command boolean cannot be single string");
|
||||
|
||||
return argstack[0].value;
|
||||
}
|
||||
|
||||
|
||||
@ -389,6 +389,8 @@ TEST_F(VariableTest, IfCommand)
|
||||
{
|
||||
BEGIN_HIDE_OUTPUT();
|
||||
command("variable one index 1");
|
||||
command("variable two string xx");
|
||||
command("variable three equal 1");
|
||||
END_HIDE_OUTPUT();
|
||||
|
||||
BEGIN_CAPTURE_OUTPUT();
|
||||
@ -444,7 +446,11 @@ TEST_F(VariableTest, IfCommand)
|
||||
BEGIN_CAPTURE_OUTPUT();
|
||||
command("if x!=x|^a!=b then 'print \"bingo!\"'");
|
||||
text = END_CAPTURE_OUTPUT();
|
||||
ASSERT_THAT(text, ContainsRegex(".*bingo!.*"));
|
||||
|
||||
BEGIN_CAPTURE_OUTPUT();
|
||||
command("if (${three}) then 'print \"bingo!\"'");
|
||||
text = END_CAPTURE_OUTPUT();
|
||||
ASSERT_THAT(text, ContainsRegex(".*bingo!.*"));
|
||||
|
||||
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
|
||||
@ -455,8 +461,16 @@ TEST_F(VariableTest, IfCommand)
|
||||
command("if 1a then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
|
||||
command("if 1=<2 then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
|
||||
TEST_FAILURE(".*ERROR: If command boolean is comparing string to number.*",
|
||||
command("if 1!=a then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: If command boolean can only operate on numbers.*",
|
||||
command("if a<b then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: If command boolean can only operate on numbers.*",
|
||||
command("if a>b then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: If command boolean can only operate on numbers.*",
|
||||
command("if a<=b then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: If command boolean can only operate on numbers.*",
|
||||
command("if a<=b then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
|
||||
command("if 1&<2 then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
|
||||
@ -465,8 +479,14 @@ TEST_F(VariableTest, IfCommand)
|
||||
command("if (1)( then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
|
||||
command("if (1)1 then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
|
||||
TEST_FAILURE(".*ERROR: If command boolean is comparing string to number.*",
|
||||
command("if (v_one==1.0)&&(2>=1) then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: If command boolean cannot be single string.*",
|
||||
command("if (something) then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: If command boolean cannot be single string.*",
|
||||
command("if (v_one) then 'print \"bingo!\"'"););
|
||||
TEST_FAILURE(".*ERROR: If command boolean cannot be single string.*",
|
||||
command("if (${two}) then 'print \"bingo!\"'"););
|
||||
}
|
||||
|
||||
TEST_F(VariableTest, NextCommand)
|
||||
|
||||
Reference in New Issue
Block a user