From e90d856165cc1110ac0d4c657a001c47236d6de8 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 13 Jul 2012 13:05:59 -0400 Subject: [PATCH] Filter: add floating point support Signed-off-by: Mathieu Desnoyers --- src/lib/lttng-ctl/filter-ast.h | 2 ++ src/lib/lttng-ctl/filter-bytecode.h | 6 +++++ src/lib/lttng-ctl/filter-ir.h | 2 ++ src/lib/lttng-ctl/filter-lexer.l | 24 ++++++++++++++++--- src/lib/lttng-ctl/filter-parser.y | 9 ++++++- .../filter-visitor-generate-bytecode.c | 18 ++++++++++++++ .../lttng-ctl/filter-visitor-generate-ir.c | 23 ++++++++++++++++-- src/lib/lttng-ctl/filter-visitor-set-parent.c | 1 + src/lib/lttng-ctl/filter-visitor-xml.c | 5 ++++ 9 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/lib/lttng-ctl/filter-ast.h b/src/lib/lttng-ctl/filter-ast.h index 97a3ae410..a42ac164d 100644 --- a/src/lib/lttng-ctl/filter-ast.h +++ b/src/lib/lttng-ctl/filter-ast.h @@ -114,6 +114,7 @@ struct filter_node { AST_EXP_UNKNOWN = 0, AST_EXP_STRING, AST_EXP_CONSTANT, + AST_EXP_FLOAT_CONSTANT, AST_EXP_IDENTIFIER, AST_EXP_NESTED, } type; @@ -122,6 +123,7 @@ struct filter_node { union { char *string; uint64_t constant; + double float_constant; char *identifier; /* * child can be nested. diff --git a/src/lib/lttng-ctl/filter-bytecode.h b/src/lib/lttng-ctl/filter-bytecode.h index af0733076..07cf99b2d 100644 --- a/src/lib/lttng-ctl/filter-bytecode.h +++ b/src/lib/lttng-ctl/filter-bytecode.h @@ -40,6 +40,7 @@ enum field_ref_type { FIELD_REF_STRING, FIELD_REF_SEQUENCE, FIELD_REF_S64, + FIELD_REF_DOUBLE, }; struct field_ref { @@ -52,6 +53,10 @@ struct literal_numeric { int64_t v; } __attribute__((packed)); +struct literal_double { + double v; +} __attribute__((packed)); + struct literal_string { char string[0]; } __attribute__((packed)); @@ -92,6 +97,7 @@ enum filter_op { FILTER_OP_LOAD_FIELD_REF, FILTER_OP_LOAD_STRING, FILTER_OP_LOAD_S64, + FILTER_OP_LOAD_DOUBLE, NR_FILTER_OPS, }; diff --git a/src/lib/lttng-ctl/filter-ir.h b/src/lib/lttng-ctl/filter-ir.h index 2ec4cc56f..39ac76c41 100644 --- a/src/lib/lttng-ctl/filter-ir.h +++ b/src/lib/lttng-ctl/filter-ir.h @@ -35,6 +35,7 @@ enum ir_data_type { IR_DATA_UNKNOWN = 0, IR_DATA_STRING, IR_DATA_NUMERIC, /* numeric and boolean */ + IR_DATA_FLOAT, IR_DATA_FIELD_REF, }; @@ -62,6 +63,7 @@ struct ir_op_load { union { char *string; int64_t num; + double flt; char *ref; } u; }; diff --git a/src/lib/lttng-ctl/filter-lexer.l b/src/lib/lttng-ctl/filter-lexer.l index 5853b0003..de74e7a09 100644 --- a/src/lib/lttng-ctl/filter-lexer.l +++ b/src/lib/lttng-ctl/filter-lexer.l @@ -33,6 +33,15 @@ static int input (yyscan_t yyscanner) __attribute__((unused)); %option reentrant yylineno noyywrap bison-bridge %option extra-type="struct filter_parser_ctx *" /* bison-locations */ + +D [0-9] +L [a-zA-Z_] +H [a-fA-F0-9] +E ([Ee][+-]?{D}+) +P ([Pp][+-]?{D}+) +FS (f|F|l|L) +IS ((u|U)|(u|U)?(l|L|ll|LL)|(l|L|ll|LL)(u|U)) + INTEGER_SUFFIX [ \n\t]*(U|UL|ULL|LU|LLU|Ul|Ull|lU|llU|u|uL|uLL|Lu|LLu|ul|ull|lu|llu) DIGIT [0-9] NONDIGIT [a-zA-Z_] @@ -71,6 +80,18 @@ L\" BEGIN(string_lit); return STRING_LITERAL_START; \n ; /* ignore */ . setstring(yyextra, yylval, yytext); return CHAR_STRING_TOKEN; + +0[xX]{H}+{IS}? setstring(yyextra, yylval, yytext); return HEXADECIMAL_CONSTANT; +0[0-7]*{IS}? setstring(yyextra, yylval, yytext); return OCTAL_CONSTANT; +[1-9]{D}*{IS}? setstring(yyextra, yylval, yytext); return DECIMAL_CONSTANT; + +{D}+{E}{FS}? setstring(yyextra, yylval, yytext); return FLOAT_CONSTANT; +{D}*"."{D}+{E}?{FS}? setstring(yyextra, yylval, yytext); return FLOAT_CONSTANT; +{D}+"."{D}*{E}?{FS}? setstring(yyextra, yylval, yytext); return FLOAT_CONSTANT; +0[xX]{H}+{P}{FS}? setstring(yyextra, yylval, yytext); return FLOAT_CONSTANT; +0[xX]{H}*"."{H}+{P}?{FS}? setstring(yyextra, yylval, yytext); return FLOAT_CONSTANT; +0[xX]{H}+"."{H}*{P}?{FS}? setstring(yyextra, yylval, yytext); return FLOAT_CONSTANT; + "[" return LSBRAC; "]" return RSBRAC; "(" return LPAREN; @@ -109,9 +130,6 @@ L\" BEGIN(string_lit); return STRING_LITERAL_START; "&" return AND_BIN; "|" return OR_BIN; "~" return NOT_BIN; -[1-9]{DIGIT}*{INTEGER_SUFFIX}? setstring(yyextra, yylval, yytext); return DECIMAL_CONSTANT; -0{OCTALDIGIT}*{INTEGER_SUFFIX}? setstring(yyextra, yylval, yytext); return OCTAL_CONSTANT; -0[xX]{HEXDIGIT}+{INTEGER_SUFFIX}? setstring(yyextra, yylval, yytext); return HEXADECIMAL_CONSTANT; {IDENTIFIER} printf_debug("\n", yytext); setstring(yyextra, yylval, yytext); return IDENTIFIER; [ \t\n]+ ; /* ignore */ . return ERROR; diff --git a/src/lib/lttng-ctl/filter-parser.y b/src/lib/lttng-ctl/filter-parser.y index 30c208ab1..d6f00a095 100644 --- a/src/lib/lttng-ctl/filter-parser.y +++ b/src/lib/lttng-ctl/filter-parser.y @@ -287,7 +287,7 @@ void filter_parser_ctx_free(struct filter_parser_ctx *parser_ctx) %start translation_unit %token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE %token ESCSEQ CHAR_STRING_TOKEN -%token DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT +%token DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT FLOAT_CONSTANT %token LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW %token STAR PLUS MINUS %token MOD_OP DIV_OP RIGHT_OP LEFT_OP @@ -390,6 +390,13 @@ primary_expression sscanf(yylval.gs->s, "0x%" PRIx64, &$$->u.expression.u.constant); } + | FLOAT_CONSTANT + { + $$ = make_node(parser_ctx, NODE_EXPRESSION); + $$->u.expression.type = AST_EXP_FLOAT_CONSTANT; + sscanf(yylval.gs->s, "%lg", + &$$->u.expression.u.float_constant); + } | STRING_LITERAL_START DQUOTE { $$ = make_node(parser_ctx, NODE_EXPRESSION); diff --git a/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c b/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c index 25128b6a2..8e18a1a62 100644 --- a/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c +++ b/src/lib/lttng-ctl/filter-visitor-generate-bytecode.c @@ -200,6 +200,24 @@ int visit_node_load(struct filter_parser_ctx *ctx, struct ir_op *node) free(insn); return ret; } + case IR_DATA_FLOAT: + { + struct load_op *insn; + uint32_t insn_len = sizeof(struct load_op) + + sizeof(struct literal_double); + + insn = calloc(insn_len, 1); + if (!insn) + return -ENOMEM; + insn->op = FILTER_OP_LOAD_DOUBLE; + insn->reg = reg_sel(node); + if (insn->reg == REG_ERROR) + return -EINVAL; + *(double *) insn->data = node->u.load.u.flt; + ret = bytecode_push(&ctx->bytecode, insn, 1, insn_len); + free(insn); + return ret; + } case IR_DATA_FIELD_REF: { struct load_op *insn; diff --git a/src/lib/lttng-ctl/filter-visitor-generate-ir.c b/src/lib/lttng-ctl/filter-visitor-generate-ir.c index 9d44b2349..dd0d7ffaf 100644 --- a/src/lib/lttng-ctl/filter-visitor-generate-ir.c +++ b/src/lib/lttng-ctl/filter-visitor-generate-ir.c @@ -100,6 +100,22 @@ struct ir_op *make_op_load_numeric(int64_t v, enum ir_side side) return op; } +static +struct ir_op *make_op_load_float(double v, enum ir_side side) +{ + struct ir_op *op; + + op = calloc(sizeof(struct ir_op), 1); + if (!op) + return NULL; + op->op = IR_OP_LOAD; + op->data_type = IR_DATA_FLOAT; + op->signedness = IR_SIGN_UNKNOWN; + op->side = side; + op->u.load.u.flt = v; + return op; +} + static struct ir_op *make_op_load_field_ref(char *string, enum ir_side side) { @@ -314,8 +330,8 @@ struct ir_op *make_op_binary_compare(enum op_type bin_op_type, } if ((left->data_type == IR_DATA_STRING - && right->data_type == IR_DATA_NUMERIC) - || (left->data_type == IR_DATA_NUMERIC && + && (right->data_type == IR_DATA_NUMERIC || right->data_type == IR_DATA_FLOAT)) + || ((left->data_type == IR_DATA_NUMERIC || left->data_type == IR_DATA_FLOAT) && right->data_type == IR_DATA_STRING)) { fprintf(stderr, "[error] binary operation '%s' operand type mismatch\n", op_str); goto error; @@ -492,6 +508,9 @@ struct ir_op *make_expression(struct filter_parser_ctx *ctx, case AST_EXP_CONSTANT: return make_op_load_numeric(node->u.expression.u.constant, side); + case AST_EXP_FLOAT_CONSTANT: + return make_op_load_float(node->u.expression.u.float_constant, + side); case AST_EXP_IDENTIFIER: if (node->u.expression.pre_op != AST_LINK_UNKNOWN) { fprintf(stderr, "[error] %s: dotted and dereferenced identifiers not supported\n", __func__); diff --git a/src/lib/lttng-ctl/filter-visitor-set-parent.c b/src/lib/lttng-ctl/filter-visitor-set-parent.c index 9ddd10275..2cc5f53f6 100644 --- a/src/lib/lttng-ctl/filter-visitor-set-parent.c +++ b/src/lib/lttng-ctl/filter-visitor-set-parent.c @@ -117,6 +117,7 @@ int recursive_visit_set_parent(struct filter_node *node, return ret; } case AST_EXP_CONSTANT: + case AST_EXP_FLOAT_CONSTANT: case AST_EXP_STRING: break; } diff --git a/src/lib/lttng-ctl/filter-visitor-xml.c b/src/lib/lttng-ctl/filter-visitor-xml.c index 670a7f320..bf52724ef 100644 --- a/src/lib/lttng-ctl/filter-visitor-xml.c +++ b/src/lib/lttng-ctl/filter-visitor-xml.c @@ -66,6 +66,11 @@ int recursive_visit_print_expression(struct filter_node *node, fprintf(stream, "\n", node->u.expression.u.constant); break; + case AST_EXP_FLOAT_CONSTANT: + print_tabs(stream, indent); + fprintf(stream, "\n", + node->u.expression.u.float_constant); + break; case AST_EXP_IDENTIFIER: print_tabs(stream, indent); fprintf(stream, "\n", -- 2.34.1