4 * LTTng filter XML pretty printer visitor
6 * Copyright 2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * This library is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License, version 2.1 only,
10 * as published by the Free Software Foundation.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "filter-ast.h"
30 #include "filter-parser.h"
32 #include <common/macros.h>
34 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
37 int recursive_visit_print(struct filter_node
*node
, FILE *stream
, int indent
);
40 void print_tabs(FILE *fd
, int depth
)
44 for (i
= 0; i
< depth
; i
++)
49 int recursive_visit_print_expression(struct filter_node
*node
,
50 FILE *stream
, int indent
)
52 struct filter_node
*iter_node
;
55 fprintf(stderr
, "[error] %s: NULL child\n", __func__
);
58 switch (node
->u
.expression
.type
) {
61 fprintf(stderr
, "[error] %s: unknown expression\n", __func__
);
64 print_tabs(stream
, indent
);
65 fprintf(stream
, "<string value=\"%s\"/>\n",
66 node
->u
.expression
.u
.string
);
68 case AST_EXP_CONSTANT
:
69 print_tabs(stream
, indent
);
70 fprintf(stream
, "<constant value=\"%" PRIu64
"\"/>\n",
71 node
->u
.expression
.u
.constant
);
73 case AST_EXP_FLOAT_CONSTANT
:
74 print_tabs(stream
, indent
);
75 fprintf(stream
, "<float_constant value=\"%lg\"/>\n",
76 node
->u
.expression
.u
.float_constant
);
78 case AST_EXP_IDENTIFIER
: /* fall-through */
79 case AST_EXP_GLOBAL_IDENTIFIER
:
80 print_tabs(stream
, indent
);
81 fprintf(stream
, "<%s value=\"%s\"/>\n",
82 node
->u
.expression
.type
== AST_EXP_IDENTIFIER
?
83 "identifier" : "global_identifier",
84 node
->u
.expression
.u
.identifier
);
85 iter_node
= node
->u
.expression
.next
;
87 print_tabs(stream
, indent
);
88 fprintf(stream
, "<bracket>\n");
89 if (recursive_visit_print_expression(iter_node
,
90 stream
, indent
+ 1)) {
93 print_tabs(stream
, indent
);
94 fprintf(stream
, "</bracket>\n");
95 iter_node
= iter_node
->u
.expression
.next
;
100 return recursive_visit_print(node
->u
.expression
.u
.child
,
108 int recursive_visit_print(struct filter_node
*node
, FILE *stream
, int indent
)
113 fprintf(stderr
, "[error] %s: NULL child\n", __func__
);
116 switch (node
->type
) {
119 fprintf(stderr
, "[error] %s: unknown node type\n", __func__
);
122 print_tabs(stream
, indent
);
123 fprintf(stream
, "<root>\n");
124 ret
= recursive_visit_print(node
->u
.root
.child
, stream
,
126 print_tabs(stream
, indent
);
127 fprintf(stream
, "</root>\n");
129 case NODE_EXPRESSION
:
130 print_tabs(stream
, indent
);
131 fprintf(stream
, "<expression>\n");
132 ret
= recursive_visit_print_expression(node
, stream
,
134 print_tabs(stream
, indent
);
135 fprintf(stream
, "</expression>\n");
138 print_tabs(stream
, indent
);
139 fprintf(stream
, "<op type=");
140 switch (node
->u
.op
.type
) {
143 fprintf(stderr
, "[error] %s: unknown op\n", __func__
);
146 fprintf(stream
, "\"*\"");
149 fprintf(stream
, "\"/\"");
152 fprintf(stream
, "\"%%\"");
155 fprintf(stream
, "\"+\"");
158 fprintf(stream
, "\"-\"");
160 case AST_OP_BIT_RSHIFT
:
161 fprintf(stream
, "\">>\"");
163 case AST_OP_BIT_LSHIFT
:
164 fprintf(stream
, "\"<<\"");
167 fprintf(stream
, "\"&&\"");
170 fprintf(stream
, "\"||\"");
173 fprintf(stream
, "\"&\"");
176 fprintf(stream
, "\"|\"");
179 fprintf(stream
, "\"^\"");
183 fprintf(stream
, "\"==\"");
186 fprintf(stream
, "\"!=\"");
189 fprintf(stream
, "\">\"");
192 fprintf(stream
, "\"<\"");
195 fprintf(stream
, "\">=\"");
198 fprintf(stream
, "\"<=\"");
201 fprintf(stream
, ">\n");
202 ret
= recursive_visit_print(node
->u
.op
.lchild
,
206 ret
= recursive_visit_print(node
->u
.op
.rchild
,
210 print_tabs(stream
, indent
);
211 fprintf(stream
, "</op>\n");
214 print_tabs(stream
, indent
);
215 fprintf(stream
, "<unary_op type=");
216 switch (node
->u
.unary_op
.type
) {
217 case AST_UNARY_UNKNOWN
:
219 fprintf(stderr
, "[error] %s: unknown unary_op\n", __func__
);
222 fprintf(stream
, "\"+\"");
224 case AST_UNARY_MINUS
:
225 fprintf(stream
, "\"-\"");
228 fprintf(stream
, "\"!\"");
230 case AST_UNARY_BIT_NOT
:
231 fprintf(stream
, "\"~\"");
234 fprintf(stream
, ">\n");
235 ret
= recursive_visit_print(node
->u
.unary_op
.child
,
237 print_tabs(stream
, indent
);
238 fprintf(stream
, "</unary_op>\n");
245 int filter_visitor_print_xml(struct filter_parser_ctx
*ctx
, FILE *stream
,
248 return recursive_visit_print(&ctx
->ast
->root
, stream
, indent
);