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;
                }
        }
 \n     return 0;
-[+-/*()]       return yytext[0];
+[+-/*()^]      return yytext[0];
+
 .      {
                yylval.v.has_error = 1;
                return NUMBER;  
 .      {
                yylval.v.has_error = 1;
                return NUMBER;  
index 1c1ebf88492028c25a91ab935b08c486a916b5ff..f5a7981f2fbfa8eb6bdacc61d5d99c6e81c9e1f5 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <stdio.h>
 #include <string.h>
 
 #include <stdio.h>
 #include <string.h>
-
+#include <math.h>
 struct parser_value_type {
        double dval;
        long long ival;
 struct parser_value_type {
        double dval;
        long long ival;
@@ -58,6 +58,7 @@ extern void yyrestart(FILE *file);
 %token <v> SUFFIX 
 %left '-' '+'
 %left '*' '/'
 %token <v> SUFFIX 
 %left '-' '+'
 %left '*' '/'
+%right '^'
 %nonassoc UMINUS
 %parse-param { long long *result }
 %parse-param { double *dresult }
 %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;
                }
                                $$.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; };
 %%
        |       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
 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).
 For time values in expressions
 units are microseconds by default.  This is different than for time
 values not in expressions (not enclosed in parentheses).