math: Allow "x" for multiplication

It's always a bit annoying that `*` requires quoting.

So we allow "x" as an alternative, only it needs to be followed by
whitespace to distinguish it from "0x" hexadecimal notation.
This commit is contained in:
Fabian Homborg 2019-05-30 16:00:45 +02:00
parent 42138f00c6
commit d1ca392393
5 changed files with 30 additions and 3 deletions

View file

@ -16,7 +16,7 @@ Description
By default, the output is as a float with trailing zeroes trimmed. To get a fixed representation, the ``--scale`` option can be used, including ``--scale=0`` for integer output.
Keep in mind that parameter expansion takes before expressions are evaluated. This can be very useful in order to perform calculations involving shell variables or the output of command substitutions, but it also means that parenthesis (``()``) and the asterisk (``*``) glob character have to be escaped or quoted.
Keep in mind that parameter expansion takes before expressions are evaluated. This can be very useful in order to perform calculations involving shell variables or the output of command substitutions, but it also means that parenthesis (``()``) and the asterisk (``*``) glob character have to be escaped or quoted. ``x`` can also be used to denote multiplication, but it needs to be followed by whitespace to distinguish it from hexadecimal numbers.
``math`` ignores whitespace between arguments and takes its input as multiple arguments (internally joined with a space), so ``math 2 +2`` and ``math "2 + 2"`` work the same. ``math 2 2`` is an error.
@ -43,7 +43,7 @@ Operators
- ``+`` for addition and ``-`` for subtraction.
- ``*`` for multiplication, ``/`` for division. (Note that ``*`` is the glob character and needs to be quoted or escaped.)
- ``*`` or ``x`` for multiplication, ``/`` for division. (Note that ``*`` is the glob character and needs to be quoted or escaped, ``x`` needs to be followed by whitespace or it looks like ``0x`` hexadecimal notation.)
- ``^`` for exponentiation.
@ -110,6 +110,8 @@ Examples
``math 5 \* 2`` or ``math "5 * 2"`` or ``math 5 "*" 2`` all output ``10``.
``math 0xFF`` outputs 255, ``math 0 x 3`` outputs 0 (because it computes 0 multiplied by 3).
Compatibility notes
-------------------

View file

@ -233,7 +233,10 @@ void next_token(state *s) {
s->type = TOK_NUMBER;
} else {
/* Look for a variable or builtin function call. */
if (s->next[0] >= 'a' && s->next[0] <= 'z') {
// But not when it's an "x" followed by whitespace
// - that's the alternative multiplication operator.
if (s->next[0] >= 'a' && s->next[0] <= 'z' &&
!(s->next[0] == 'x' && isspace(s->next[1]))) {
const char *start;
start = s->next;
while ((s->next[0] >= 'a' && s->next[0] <= 'z') ||
@ -269,7 +272,9 @@ void next_token(state *s) {
s->type = TOK_INFIX;
s->function = (const void *)(te_fun2)sub;
break;
case 'x':
case '*':
// We've already checked for whitespace above.
s->type = TOK_INFIX;
s->function = (const void *)(te_fun2)mul;
break;

View file

@ -34,3 +34,9 @@ math: Error: Result is infinite
'2^999999'
math: Error: Result is infinite
'1 / 0'
####################
# Validate x as multiplier
math: Error: Unknown variable
'2 x4'
^

View file

@ -52,3 +52,10 @@ not math
not math -s 12
not math 2^999999
not math 1 / 0
logmsg Validate "x" as multiplier
math 0x2 # Hex
math 5 x 4
math 2x 4
math 2 x4 # ERROR
math 0x 3

View file

@ -49,3 +49,10 @@
####################
# Validate math error reporting
####################
# Validate x as multiplier
2
20
8
0