4 * LTTng filter XML pretty printer visitor
6 * Copyright 2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * SPDX-License-Identifier: LGPL-2.1-only
17 #include "filter-ast.hpp"
18 #include "filter-parser.hpp"
20 #include <common/compat/errno.hpp>
21 #include <common/macros.hpp>
23 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
26 int recursive_visit_print(struct filter_node
*node
, FILE *stream
, int indent
);
29 void print_tabs(FILE *fd
, int depth
)
33 for (i
= 0; i
< depth
; i
++)
38 int recursive_visit_print_expression(struct filter_node
*node
,
39 FILE *stream
, int indent
)
41 struct filter_node
*iter_node
;
44 fprintf(stderr
, "[error] %s: NULL child\n", __func__
);
47 switch (node
->u
.expression
.type
) {
50 fprintf(stderr
, "[error] %s: unknown expression\n", __func__
);
53 print_tabs(stream
, indent
);
54 fprintf(stream
, "<string value=\"%s\"/>\n",
55 node
->u
.expression
.u
.string
);
57 case AST_EXP_CONSTANT
:
58 print_tabs(stream
, indent
);
59 fprintf(stream
, "<constant value=\"%" PRIu64
"\"/>\n",
60 node
->u
.expression
.u
.constant
);
62 case AST_EXP_FLOAT_CONSTANT
:
63 print_tabs(stream
, indent
);
64 fprintf(stream
, "<float_constant value=\"%lg\"/>\n",
65 node
->u
.expression
.u
.float_constant
);
67 case AST_EXP_IDENTIFIER
: /* fall-through */
68 case AST_EXP_GLOBAL_IDENTIFIER
:
69 print_tabs(stream
, indent
);
70 fprintf(stream
, "<%s value=\"%s\"/>\n",
71 node
->u
.expression
.type
== AST_EXP_IDENTIFIER
?
72 "identifier" : "global_identifier",
73 node
->u
.expression
.u
.identifier
);
74 iter_node
= node
->u
.expression
.next
;
76 print_tabs(stream
, indent
);
77 fprintf(stream
, "<bracket>\n");
78 if (recursive_visit_print_expression(iter_node
,
79 stream
, indent
+ 1)) {
82 print_tabs(stream
, indent
);
83 fprintf(stream
, "</bracket>\n");
84 iter_node
= iter_node
->u
.expression
.next
;
89 return recursive_visit_print(node
->u
.expression
.u
.child
,
97 int recursive_visit_print(struct filter_node
*node
, FILE *stream
, int indent
)
102 fprintf(stderr
, "[error] %s: NULL child\n", __func__
);
105 switch (node
->type
) {
108 fprintf(stderr
, "[error] %s: unknown node type\n", __func__
);
111 print_tabs(stream
, indent
);
112 fprintf(stream
, "<root>\n");
113 ret
= recursive_visit_print(node
->u
.root
.child
, stream
,
115 print_tabs(stream
, indent
);
116 fprintf(stream
, "</root>\n");
118 case NODE_EXPRESSION
:
119 print_tabs(stream
, indent
);
120 fprintf(stream
, "<expression>\n");
121 ret
= recursive_visit_print_expression(node
, stream
,
123 print_tabs(stream
, indent
);
124 fprintf(stream
, "</expression>\n");
127 print_tabs(stream
, indent
);
128 fprintf(stream
, "<op type=");
129 switch (node
->u
.op
.type
) {
132 fprintf(stderr
, "[error] %s: unknown op\n", __func__
);
135 fprintf(stream
, "\"*\"");
138 fprintf(stream
, "\"/\"");
141 fprintf(stream
, "\"%%\"");
144 fprintf(stream
, "\"+\"");
147 fprintf(stream
, "\"-\"");
149 case AST_OP_BIT_RSHIFT
:
150 fprintf(stream
, "\">>\"");
152 case AST_OP_BIT_LSHIFT
:
153 fprintf(stream
, "\"<<\"");
156 fprintf(stream
, "\"&&\"");
159 fprintf(stream
, "\"||\"");
162 fprintf(stream
, "\"&\"");
165 fprintf(stream
, "\"|\"");
168 fprintf(stream
, "\"^\"");
172 fprintf(stream
, "\"==\"");
175 fprintf(stream
, "\"!=\"");
178 fprintf(stream
, "\">\"");
181 fprintf(stream
, "\"<\"");
184 fprintf(stream
, "\">=\"");
187 fprintf(stream
, "\"<=\"");
190 fprintf(stream
, ">\n");
191 ret
= recursive_visit_print(node
->u
.op
.lchild
,
195 ret
= recursive_visit_print(node
->u
.op
.rchild
,
199 print_tabs(stream
, indent
);
200 fprintf(stream
, "</op>\n");
203 print_tabs(stream
, indent
);
204 fprintf(stream
, "<unary_op type=");
205 switch (node
->u
.unary_op
.type
) {
206 case AST_UNARY_UNKNOWN
:
208 fprintf(stderr
, "[error] %s: unknown unary_op\n", __func__
);
211 fprintf(stream
, "\"+\"");
213 case AST_UNARY_MINUS
:
214 fprintf(stream
, "\"-\"");
217 fprintf(stream
, "\"!\"");
219 case AST_UNARY_BIT_NOT
:
220 fprintf(stream
, "\"~\"");
223 fprintf(stream
, ">\n");
224 ret
= recursive_visit_print(node
->u
.unary_op
.child
,
226 print_tabs(stream
, indent
);
227 fprintf(stream
, "</unary_op>\n");
233 int filter_visitor_print_xml(struct filter_parser_ctx
*ctx
, FILE *stream
,
236 return recursive_visit_print(&ctx
->ast
->root
, stream
, indent
);