From ae46966a4a0f0db7eb34a7b82d39a86735a8a293 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 29 Sep 2014 12:16:54 -0600 Subject: [PATCH 1/1] fio: support exponentiation in expression parser Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- exp/expression-parser.l | 3 ++- exp/expression-parser.y | 33 ++++++++++++++++++++++++++++++++- fio.1 | 2 +- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/exp/expression-parser.l b/exp/expression-parser.l index f688da11..a0c6b24d 100644 --- a/exp/expression-parser.l +++ b/exp/expression-parser.l @@ -158,7 +158,8 @@ bye return BYE; } } \n return 0; -[+-/*()] return yytext[0]; +[+-/*()^] return yytext[0]; + . { yylval.v.has_error = 1; return NUMBER; diff --git a/exp/expression-parser.y b/exp/expression-parser.y index 1c1ebf88..f5a7981f 100644 --- a/exp/expression-parser.y +++ b/exp/expression-parser.y @@ -20,7 +20,7 @@ #include #include - +#include struct parser_value_type { double dval; long long ival; @@ -58,6 +58,7 @@ extern void yyrestart(FILE *file); %token SUFFIX %left '-' '+' %left '*' '/' +%right '^' %nonassoc UMINUS %parse-param { long long *result } %parse-param { double *dresult } @@ -131,6 +132,36 @@ expression: expression '+' expression { $$.dval = $1.ival * $2.ival; $$.has_error = $1.has_error || $2.has_error; } + | expression '^' expression { + $$.has_error = $1.has_error || $3.has_error; + if (!$1.has_dval && !$3.has_dval) { + int i; + + if ($3.ival == 0) { + $$.ival = 1; + } else if ($3.ival > 0) { + long long tmp = $1.ival; + $$.ival = 1.0; + for (i = 0; i < $3.ival; i++) + $$.ival *= tmp; + } else { + /* integers, 2^-3, ok, we now have doubles */ + double tmp; + if ($1.ival == 0 && $3.ival == 0) { + tmp = 1.0; + $$.has_error = 1; + } else { + tmp = pow((double) $1.ival, + (double) $3.ival); + } + $$.ival = (long long) tmp; + } + $$.dval = pow($1.dval, $3.dval); + } else { + $$.dval = pow($1.dval, $3.dval); + $$.ival = (long long) $$.dval; + } + } | NUMBER { $$ = $1; } | BYE { $$ = $1; *bye = 1; }; %% diff --git a/fio.1 b/fio.1 index fb5ca46d..66c9cb03 100644 --- a/fio.1 +++ b/fio.1 @@ -119,7 +119,7 @@ Some parameters may take arguments of a specific type. Anywhere a numeric value is required, an arithmetic expression may be used, provided it is surrounded by parentheses. Supported operators are -addition, subtraction, multiplication and division. +addition, subtraction, multiplication, division and exponentiation. For time values in expressions units are microseconds by default. This is different than for time values not in expressions (not enclosed in parentheses). -- 2.25.1