Filter: add floating point support
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 13 Jul 2012 17:05:59 +0000 (13:05 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 13 Jul 2012 17:05:59 +0000 (13:05 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
src/lib/lttng-ctl/filter-ast.h
src/lib/lttng-ctl/filter-bytecode.h
src/lib/lttng-ctl/filter-ir.h
src/lib/lttng-ctl/filter-lexer.l
src/lib/lttng-ctl/filter-parser.y
src/lib/lttng-ctl/filter-visitor-generate-bytecode.c
src/lib/lttng-ctl/filter-visitor-generate-ir.c
src/lib/lttng-ctl/filter-visitor-set-parent.c
src/lib/lttng-ctl/filter-visitor-xml.c

index 97a3ae410001a91f62c98d4dbb1f54ea331a96cf..a42ac164d605d0dfe1cae5f27a6c18ec427153f7 100644 (file)
@@ -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.
index af0733076a473201edd6ca94d032342ffe71b9ad..07cf99b2dcd46f8f06423046857dcd193812c117 100644 (file)
@@ -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,
 };
index 2ec4cc56f6090758c40ada4f388d6bd549421173..39ac76c4174c53beca08bd21cd126a3298e66726 100644 (file)
@@ -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;
 };
index 5853b000380ab23c69418152fa38d4ef3c67c556..de74e7a09715c11206d207b519f3c3e0dfcc53c0 100644 (file)
@@ -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;
 <char_const,string_lit>\n      ; /* ignore */
 <char_const,string_lit>.       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("<IDENTIFIER %s>\n", yytext); setstring(yyextra, yylval, yytext); return IDENTIFIER;
 [ \t\n]+                       ; /* ignore */
 .                              return ERROR;
index 30c208ab15ccaf6095527df50d7cee012ae4896b..d6f00a095e35f934019145a28dcd94ebe2cdd21d 100644 (file)
@@ -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);
index 25128b6a2fc6b9f2bd1826f66efbe8909d8f4a23..8e18a1a622ac65a918792012ada24c3719fc9f8c 100644 (file)
@@ -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;
index 9d44b234924da53f2d6a97b0333419ca0d4b0b78..dd0d7ffaf7137fc49f938462e4e7c4950a5a9cd8 100644 (file)
@@ -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__);
index 9ddd10275c337afc54dd7bc7188995b5d41f2826..2cc5f53f62275d0fbd372ee37424ca4bc29ec04a 100644 (file)
@@ -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;
                }
index 670a7f3200cee9ae15ed7d5d66453010212ded9c..bf52724ef4df253bcdfa715cbd4589b7772b152d 100644 (file)
@@ -66,6 +66,11 @@ int recursive_visit_print_expression(struct filter_node *node,
                fprintf(stream, "<constant value=\"%" PRIu64 "\"/>\n",
                        node->u.expression.u.constant);
                break;
+       case AST_EXP_FLOAT_CONSTANT:
+               print_tabs(stream, indent);
+               fprintf(stream, "<float_constant value=\"%lg\"/>\n",
+                       node->u.expression.u.float_constant);
+               break;
        case AST_EXP_IDENTIFIER:
                print_tabs(stream, indent);
                fprintf(stream, "<identifier value=\"%s\"/>\n",
This page took 0.029923 seconds and 4 git commands to generate.