Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[sfrench/cifs-2.6.git] / tools / perf / util / expr.l
1 %option prefix="expr_"
2 %option reentrant
3 %option bison-bridge
4
5 %{
6 #include <linux/compiler.h>
7 #include "expr.h"
8 #include "expr-bison.h"
9 #include <math.h>
10
11 char *expr_get_text(yyscan_t yyscanner);
12 YYSTYPE *expr_get_lval(yyscan_t yyscanner);
13
14 static double __value(YYSTYPE *yylval, char *str, int token)
15 {
16         double num;
17
18         errno = 0;
19         num = strtod(str, NULL);
20         if (errno)
21                 return EXPR_ERROR;
22
23         yylval->num = num;
24         return token;
25 }
26
27 static int value(yyscan_t scanner)
28 {
29         YYSTYPE *yylval = expr_get_lval(scanner);
30         char *text = expr_get_text(scanner);
31
32         return __value(yylval, text, NUMBER);
33 }
34
35 /*
36  * Allow @ instead of / to be able to specify pmu/event/ without
37  * conflicts with normal division.
38  */
39 static char *normalize(char *str, int runtime)
40 {
41         char *ret = str;
42         char *dst = str;
43
44         while (*str) {
45                 if (*str == '\\')
46                         *dst++ = *++str;
47                 else if (*str == '?') {
48                         char *paramval;
49                         int i = 0;
50                         int size = asprintf(&paramval, "%d", runtime);
51
52                         if (size < 0)
53                                 *dst++ = '0';
54                         else {
55                                 while (i < size)
56                                         *dst++ = paramval[i++];
57                                 free(paramval);
58                         }
59                 }
60                 else
61                         *dst++ = *str;
62                 str++;
63         }
64
65         *dst = 0x0;
66         return ret;
67 }
68
69 static int str(yyscan_t scanner, int token, int runtime)
70 {
71         YYSTYPE *yylval = expr_get_lval(scanner);
72         char *text = expr_get_text(scanner);
73
74         yylval->str = normalize(strdup(text), runtime);
75         if (!yylval->str)
76                 return EXPR_ERROR;
77
78         yylval->str = normalize(yylval->str, runtime);
79         return token;
80 }
81
82 static int literal(yyscan_t scanner)
83 {
84         YYSTYPE *yylval = expr_get_lval(scanner);
85
86         yylval->num = expr__get_literal(expr_get_text(scanner));
87         if (isnan(yylval->num))
88                 return EXPR_ERROR;
89
90         return LITERAL;
91 }
92 %}
93
94 number          ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+)(e-?[0-9]+)?
95
96 sch             [-,=]
97 spec            \\{sch}
98 sym             [0-9a-zA-Z_\.:@?]+
99 symbol          ({spec}|{sym})+
100 literal         #[0-9a-zA-Z_\.\-]+
101
102 %%
103         struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
104
105 d_ratio         { return D_RATIO; }
106 max             { return MAX; }
107 min             { return MIN; }
108 if              { return IF; }
109 else            { return ELSE; }
110 source_count    { return SOURCE_COUNT; }
111 {literal}       { return literal(yyscanner); }
112 {number}        { return value(yyscanner); }
113 {symbol}        { return str(yyscanner, ID, sctx->runtime); }
114 "|"             { return '|'; }
115 "^"             { return '^'; }
116 "&"             { return '&'; }
117 "<"             { return '<'; }
118 ">"             { return '>'; }
119 "-"             { return '-'; }
120 "+"             { return '+'; }
121 "*"             { return '*'; }
122 "/"             { return '/'; }
123 "%"             { return '%'; }
124 "("             { return '('; }
125 ")"             { return ')'; }
126 ","             { return ','; }
127 .               { }
128 %%
129
130 int expr_wrap(void *scanner __maybe_unused)
131 {
132         return 1;
133 }