5d1bdb9d393ee8c2f4a8a9624fa5348537f3000d
[lttng-tools.git] / src / common / filter / filter-visitor-xml.cpp
1 /*
2 * filter-visitor-xml.c
3 *
4 * LTTng filter XML pretty printer visitor
5 *
6 * Copyright 2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * SPDX-License-Identifier: LGPL-2.1-only
9 *
10 */
11
12 #include "filter-ast.hpp"
13 #include "filter-parser.hpp"
14
15 #include <common/compat/errno.hpp>
16 #include <common/macros.hpp>
17
18 #include <inttypes.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23
24 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ##args)
25
26 static int recursive_visit_print(struct filter_node *node, FILE *stream, int indent);
27
28 static void print_tabs(FILE *fd, int depth)
29 {
30 int i;
31
32 for (i = 0; i < depth; i++)
33 fprintf(fd, "\t");
34 }
35
36 static int recursive_visit_print_expression(struct filter_node *node, FILE *stream, int indent)
37 {
38 struct filter_node *iter_node;
39
40 if (!node) {
41 fprintf(stderr, "[error] %s: NULL child\n", __func__);
42 return -EINVAL;
43 }
44 switch (node->u.expression.type) {
45 case AST_EXP_UNKNOWN:
46 default:
47 fprintf(stderr, "[error] %s: unknown expression\n", __func__);
48 return -EINVAL;
49 case AST_EXP_STRING:
50 print_tabs(stream, indent);
51 fprintf(stream, "<string value=\"%s\"/>\n", node->u.expression.u.string);
52 break;
53 case AST_EXP_CONSTANT:
54 print_tabs(stream, indent);
55 fprintf(stream,
56 "<constant value=\"%" PRIu64 "\"/>\n",
57 node->u.expression.u.constant);
58 break;
59 case AST_EXP_FLOAT_CONSTANT:
60 print_tabs(stream, indent);
61 fprintf(stream,
62 "<float_constant value=\"%lg\"/>\n",
63 node->u.expression.u.float_constant);
64 break;
65 case AST_EXP_IDENTIFIER: /* fall-through */
66 case AST_EXP_GLOBAL_IDENTIFIER:
67 print_tabs(stream, indent);
68 fprintf(stream,
69 "<%s value=\"%s\"/>\n",
70 node->u.expression.type == AST_EXP_IDENTIFIER ? "identifier" :
71 "global_identifier",
72 node->u.expression.u.identifier);
73 iter_node = node->u.expression.next;
74 while (iter_node) {
75 print_tabs(stream, indent);
76 fprintf(stream, "<bracket>\n");
77 if (recursive_visit_print_expression(iter_node, stream, indent + 1)) {
78 return -EINVAL;
79 }
80 print_tabs(stream, indent);
81 fprintf(stream, "</bracket>\n");
82 iter_node = iter_node->u.expression.next;
83 }
84 break;
85 case AST_EXP_NESTED:
86 return recursive_visit_print(node->u.expression.u.child, stream, indent + 1);
87 }
88 return 0;
89 }
90
91 static int recursive_visit_print(struct filter_node *node, FILE *stream, int indent)
92 {
93 int ret;
94
95 if (!node) {
96 fprintf(stderr, "[error] %s: NULL child\n", __func__);
97 return -EINVAL;
98 }
99 switch (node->type) {
100 case NODE_UNKNOWN:
101 default:
102 fprintf(stderr, "[error] %s: unknown node type\n", __func__);
103 return -EINVAL;
104 case NODE_ROOT:
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");
110 return ret;
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");
117 return ret;
118 case NODE_OP:
119 print_tabs(stream, indent);
120 fprintf(stream, "<op type=");
121 switch (node->u.op.type) {
122 case AST_OP_UNKNOWN:
123 default:
124 fprintf(stderr, "[error] %s: unknown op\n", __func__);
125 return -EINVAL;
126 case AST_OP_MUL:
127 fprintf(stream, "\"*\"");
128 break;
129 case AST_OP_DIV:
130 fprintf(stream, "\"/\"");
131 break;
132 case AST_OP_MOD:
133 fprintf(stream, "\"%%\"");
134 break;
135 case AST_OP_PLUS:
136 fprintf(stream, "\"+\"");
137 break;
138 case AST_OP_MINUS:
139 fprintf(stream, "\"-\"");
140 break;
141 case AST_OP_BIT_RSHIFT:
142 fprintf(stream, "\">>\"");
143 break;
144 case AST_OP_BIT_LSHIFT:
145 fprintf(stream, "\"<<\"");
146 break;
147 case AST_OP_AND:
148 fprintf(stream, "\"&&\"");
149 break;
150 case AST_OP_OR:
151 fprintf(stream, "\"||\"");
152 break;
153 case AST_OP_BIT_AND:
154 fprintf(stream, "\"&\"");
155 break;
156 case AST_OP_BIT_OR:
157 fprintf(stream, "\"|\"");
158 break;
159 case AST_OP_BIT_XOR:
160 fprintf(stream, "\"^\"");
161 break;
162
163 case AST_OP_EQ:
164 fprintf(stream, "\"==\"");
165 break;
166 case AST_OP_NE:
167 fprintf(stream, "\"!=\"");
168 break;
169 case AST_OP_GT:
170 fprintf(stream, "\">\"");
171 break;
172 case AST_OP_LT:
173 fprintf(stream, "\"<\"");
174 break;
175 case AST_OP_GE:
176 fprintf(stream, "\">=\"");
177 break;
178 case AST_OP_LE:
179 fprintf(stream, "\"<=\"");
180 break;
181 }
182 fprintf(stream, ">\n");
183 ret = recursive_visit_print(node->u.op.lchild, stream, indent + 1);
184 if (ret)
185 return ret;
186 ret = recursive_visit_print(node->u.op.rchild, stream, indent + 1);
187 if (ret)
188 return ret;
189 print_tabs(stream, indent);
190 fprintf(stream, "</op>\n");
191 return ret;
192 case NODE_UNARY_OP:
193 print_tabs(stream, indent);
194 fprintf(stream, "<unary_op type=");
195 switch (node->u.unary_op.type) {
196 case AST_UNARY_UNKNOWN:
197 default:
198 fprintf(stderr, "[error] %s: unknown unary_op\n", __func__);
199 return -EINVAL;
200 case AST_UNARY_PLUS:
201 fprintf(stream, "\"+\"");
202 break;
203 case AST_UNARY_MINUS:
204 fprintf(stream, "\"-\"");
205 break;
206 case AST_UNARY_NOT:
207 fprintf(stream, "\"!\"");
208 break;
209 case AST_UNARY_BIT_NOT:
210 fprintf(stream, "\"~\"");
211 break;
212 }
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");
217 return ret;
218 }
219 return 0;
220 }
221
222 int filter_visitor_print_xml(struct filter_parser_ctx *ctx, FILE *stream, int indent)
223 {
224 return recursive_visit_print(&ctx->ast->root, stream, indent);
225 }
This page took 0.0336109999999999 seconds and 4 git commands to generate.