Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151%option prefix="expr_"%option reentrant%option bison-bridge
%{#include <linux/compiler.h>#include "expr.h"#include "expr-bison.h"#include <math.h>
char *expr_get_text(yyscan_t yyscanner);YYSTYPE *expr_get_lval(yyscan_t yyscanner);
static double __value(YYSTYPE *yylval, char *str, int token){ double num;
errno = 0; num = strtod(str, NULL); if (errno) return EXPR_ERROR;
yylval->num = num; return token;}
static int value(yyscan_t scanner){ YYSTYPE *yylval = expr_get_lval(scanner); char *text = expr_get_text(scanner);
return __value(yylval, text, NUMBER);}
/* * Allow @ instead of / to be able to specify pmu/event/ without * conflicts with normal division. */static char *normalize(char *str, int runtime){ char *ret = str; char *dst = str;
while (*str) { if (*str == '\\') { *dst++ = *++str; if (!*str) break; } else if (*str == '?') { char *paramval; int i = 0; int size = asprintf(¶mval, "%d", runtime);
if (size < 0) *dst++ = '0'; else { while (i < size) *dst++ = paramval[i++]; free(paramval); } } else *dst++ = *str; str++; }
*dst = 0x0; return ret;}
static int str(yyscan_t scanner, int token, int runtime){ YYSTYPE *yylval = expr_get_lval(scanner); char *text = expr_get_text(scanner);
yylval->str = normalize(strdup(text), runtime); if (!yylval->str) return EXPR_ERROR;
yylval->str = normalize(yylval->str, runtime); return token;}
static int literal(yyscan_t scanner, const struct expr_scanner_ctx *sctx){ YYSTYPE *yylval = expr_get_lval(scanner);
yylval->num = expr__get_literal(expr_get_text(scanner), sctx); if (isnan(yylval->num)) { if (!sctx->is_test) return EXPR_ERROR; yylval->num = 1; } return LITERAL;}
static int nan_value(yyscan_t scanner){ YYSTYPE *yylval = expr_get_lval(scanner);
yylval->num = NAN; return NUMBER;}%}
number ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+)(e-?[0-9]+)?
sch [-,=]spec \\{sch}sym [0-9a-zA-Z_\.:@?]+symbol ({spec}|{sym})+literal #[0-9a-zA-Z_\.\-]+
%% struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
d_ratio { return D_RATIO; }max { return MAX; }min { return MIN; }if { return IF; }else { return ELSE; }source_count { return SOURCE_COUNT; }aggr_nr { return AGGR_NR; }has_event { return HAS_EVENT; }strcmp_cpuid_str { return STRCMP_CPUID_STR; }NaN { return nan_value(yyscanner); }{literal} { return literal(yyscanner, sctx); }{number} { return value(yyscanner); }{symbol} { return str(yyscanner, ID, sctx->runtime); }"|" { return '|'; }"^" { return '^'; }"&" { return '&'; }"<" { return '<'; }">" { return '>'; }"-" { return '-'; }"+" { return '+'; }"*" { return '*'; }"/" { return '/'; }"%" { return '%'; }"(" { return '('; }")" { return ')'; }"," { return ','; }. { }%%
int expr_wrap(void *scanner __maybe_unused){ return 1;}