fio: support exponentiation in expression parser
authorStephen M. Cameron <stephenmcameron@gmail.com>
Mon, 29 Sep 2014 18:16:54 +0000 (12:16 -0600)
committerJens Axboe <axboe@fb.com>
Mon, 29 Sep 2014 18:18:37 +0000 (12:18 -0600)
Signed-off-by: Stephen M. Cameron <stephenmcameron@gmail.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
exp/expression-parser.l
exp/expression-parser.y
fio.1

index f688da11684e16b68b88df9a1837c894e8b484b3..a0c6b24d362ed59d6fc991d81f993477055c935f 100644 (file)
@@ -158,7 +158,8 @@ bye         return BYE;
                }
        }
 \n     return 0;
-[+-/*()]       return yytext[0];
+[+-/*()^]      return yytext[0];
+
 .      {
                yylval.v.has_error = 1;
                return NUMBER;  
index 1c1ebf88492028c25a91ab935b08c486a916b5ff..f5a7981f2fbfa8eb6bdacc61d5d99c6e81c9e1f5 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <stdio.h>
 #include <string.h>
-
+#include <math.h>
 struct parser_value_type {
        double dval;
        long long ival;
@@ -58,6 +58,7 @@ extern void yyrestart(FILE *file);
 %token <v> 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 fb5ca46d0f6d7ff0838499e62fc1e34e771b23e6..66c9cb03b42a3a9d712e9f5e58054a30627edb56 100644 (file)
--- 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).