4 * LTTng filter XML pretty printer visitor
6 * Copyright 2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * SPDX-License-Identifier: LGPL-2.1-only
12 #include "filter-ast.hpp"
13 #include "filter-parser.hpp"
15 #include <common/compat/errno.hpp>
16 #include <common/macros.hpp>
24 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ##args)
26 static int recursive_visit_print(struct filter_node
*node
, FILE *stream
, int indent
);
28 static void print_tabs(FILE *fd
, int depth
)
32 for (i
= 0; i
< depth
; i
++)
36 static int recursive_visit_print_expression(struct filter_node
*node
, FILE *stream
, int indent
)
38 struct filter_node
*iter_node
;
41 fprintf(stderr
, "[error] %s: NULL child\n", __func__
);
44 switch (node
->u
.expression
.type
) {
47 fprintf(stderr
, "[error] %s: unknown expression\n", __func__
);
50 print_tabs(stream
, indent
);
51 fprintf(stream
, "<string value=\"%s\"/>\n", node
->u
.expression
.u
.string
);
53 case AST_EXP_CONSTANT
:
54 print_tabs(stream
, indent
);
56 "<constant value=\"%" PRIu64
"\"/>\n",
57 node
->u
.expression
.u
.constant
);
59 case AST_EXP_FLOAT_CONSTANT
:
60 print_tabs(stream
, indent
);
62 "<float_constant value=\"%lg\"/>\n",
63 node
->u
.expression
.u
.float_constant
);
65 case AST_EXP_IDENTIFIER
: /* fall-through */
66 case AST_EXP_GLOBAL_IDENTIFIER
:
67 print_tabs(stream
, indent
);
69 "<%s value=\"%s\"/>\n",
70 node
->u
.expression
.type
== AST_EXP_IDENTIFIER
? "identifier" :
72 node
->u
.expression
.u
.identifier
);
73 iter_node
= node
->u
.expression
.next
;
75 print_tabs(stream
, indent
);
76 fprintf(stream
, "<bracket>\n");
77 if (recursive_visit_print_expression(iter_node
, stream
, indent
+ 1)) {
80 print_tabs(stream
, indent
);
81 fprintf(stream
, "</bracket>\n");
82 iter_node
= iter_node
->u
.expression
.next
;
86 return recursive_visit_print(node
->u
.expression
.u
.child
, stream
, indent
+ 1);
91 static int recursive_visit_print(struct filter_node
*node
, FILE *stream
, int indent
)
96 fprintf(stderr
, "[error] %s: NULL child\n", __func__
);
102 fprintf(stderr
, "[error] %s: unknown node type\n", __func__
);
105 print_tabs(stream
, indent
);
106 fprintf(stream
, "<root>\n");
107 ret
= recursive_visit_print(node
->u
.root
.child
, stream
, indent
+ 1);
108 print_tabs(stream
, indent
);
109 fprintf(stream
, "</root>\n");
111 case NODE_EXPRESSION
:
112 print_tabs(stream
, indent
);
113 fprintf(stream
, "<expression>\n");
114 ret
= recursive_visit_print_expression(node
, stream
, indent
+ 1);
115 print_tabs(stream
, indent
);
116 fprintf(stream
, "</expression>\n");
119 print_tabs(stream
, indent
);
120 fprintf(stream
, "<op type=");
121 switch (node
->u
.op
.type
) {
124 fprintf(stderr
, "[error] %s: unknown op\n", __func__
);
127 fprintf(stream
, "\"*\"");
130 fprintf(stream
, "\"/\"");
133 fprintf(stream
, "\"%%\"");
136 fprintf(stream
, "\"+\"");
139 fprintf(stream
, "\"-\"");
141 case AST_OP_BIT_RSHIFT
:
142 fprintf(stream
, "\">>\"");
144 case AST_OP_BIT_LSHIFT
:
145 fprintf(stream
, "\"<<\"");
148 fprintf(stream
, "\"&&\"");
151 fprintf(stream
, "\"||\"");
154 fprintf(stream
, "\"&\"");
157 fprintf(stream
, "\"|\"");
160 fprintf(stream
, "\"^\"");
164 fprintf(stream
, "\"==\"");
167 fprintf(stream
, "\"!=\"");
170 fprintf(stream
, "\">\"");
173 fprintf(stream
, "\"<\"");
176 fprintf(stream
, "\">=\"");
179 fprintf(stream
, "\"<=\"");
182 fprintf(stream
, ">\n");
183 ret
= recursive_visit_print(node
->u
.op
.lchild
, stream
, indent
+ 1);
186 ret
= recursive_visit_print(node
->u
.op
.rchild
, stream
, indent
+ 1);
189 print_tabs(stream
, indent
);
190 fprintf(stream
, "</op>\n");
193 print_tabs(stream
, indent
);
194 fprintf(stream
, "<unary_op type=");
195 switch (node
->u
.unary_op
.type
) {
196 case AST_UNARY_UNKNOWN
:
198 fprintf(stderr
, "[error] %s: unknown unary_op\n", __func__
);
201 fprintf(stream
, "\"+\"");
203 case AST_UNARY_MINUS
:
204 fprintf(stream
, "\"-\"");
207 fprintf(stream
, "\"!\"");
209 case AST_UNARY_BIT_NOT
:
210 fprintf(stream
, "\"~\"");
213 fprintf(stream
, ">\n");
214 ret
= recursive_visit_print(node
->u
.unary_op
.child
, stream
, indent
+ 1);
215 print_tabs(stream
, indent
);
216 fprintf(stream
, "</unary_op>\n");
222 int filter_visitor_print_xml(struct filter_parser_ctx
*ctx
, FILE *stream
, int indent
)
224 return recursive_visit_print(&ctx
->ast
->root
, stream
, indent
);