Implement filter expression to bytecode compiler in liblttng-ctl
[lttng-tools.git] / src / lib / lttng-ctl / filter-visitor-xml.c
CommitLineData
953192ba
MD
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 * 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.
11 *
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.
16 *
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
20 */
21
22#include <stdio.h>
23#include <unistd.h>
24#include <string.h>
25#include <stdlib.h>
26#include <assert.h>
27#include <errno.h>
28#include <inttypes.h>
29#include "filter-parser.h"
30#include "filter-ast.h"
31
32#define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
33
34static
35int recursive_visit_print(struct filter_node *node, FILE *stream, int indent);
36
37static
38void print_tabs(FILE *fd, int depth)
39{
40 int i;
41
42 for (i = 0; i < depth; i++)
43 fprintf(fd, "\t");
44}
45
46static
47int recursive_visit_print_expression(struct filter_node *node,
48 FILE *stream, int indent)
49{
50 if (!node) {
51 fprintf(stderr, "[error] %s: NULL child\n", __func__);
52 return -EINVAL;
53 }
54 switch (node->u.expression.type) {
55 case AST_EXP_UNKNOWN:
56 default:
57 fprintf(stderr, "[error] %s: unknown expression\n", __func__);
58 return -EINVAL;
59 case AST_EXP_STRING:
60 print_tabs(stream, indent);
61 fprintf(stream, "<string value=\"%s\"/>\n",
62 node->u.expression.u.string);
63 break;
64 case AST_EXP_CONSTANT:
65 print_tabs(stream, indent);
66 fprintf(stream, "<constant value=\"%" PRIu64 "\"/>\n",
67 node->u.expression.u.constant);
68 break;
69 case AST_EXP_IDENTIFIER:
70 print_tabs(stream, indent);
71 fprintf(stream, "<identifier value=\"%s\"/>\n",
72 node->u.expression.u.identifier);
73 while (node->u.expression.next) {
74 print_tabs(stream, indent);
75 fprintf(stream, "<link type=\"");
76 switch (node->u.expression.pre_op) {
77 case AST_LINK_UNKNOWN:
78 default:
79 fprintf(stderr, "[error] %s: unknown link\n", __func__);
80 return -EINVAL;
81 case AST_LINK_DOT:
82 fprintf(stream, ".");
83 break;
84 case AST_LINK_RARROW:
85 fprintf(stream, "->");
86 break;
87 }
88 fprintf(stream, "\"/>\n");
89
90 node = node->u.expression.next;
91 if (node->type != NODE_EXPRESSION ||
92 node->u.expression.type != AST_EXP_IDENTIFIER) {
93 fprintf(stderr, "[error] %s: expecting identifier before link\n", __func__);
94 return -EINVAL;
95 }
96
97 print_tabs(stream, indent);
98 fprintf(stream, "<identifier value=\"%s\"/>\n",
99 node->u.expression.u.identifier);
100 }
101 break;
102 case AST_EXP_NESTED:
103 return recursive_visit_print(node->u.expression.u.child,
104 stream, indent + 1);
105 }
106 return 0;
107}
108
109
110static
111int recursive_visit_print(struct filter_node *node, FILE *stream, int indent)
112{
113 int ret;
114
115 if (!node) {
116 fprintf(stderr, "[error] %s: NULL child\n", __func__);
117 return -EINVAL;
118 }
119 switch (node->type) {
120 case NODE_UNKNOWN:
121 default:
122 fprintf(stderr, "[error] %s: unknown node type\n", __func__);
123 return -EINVAL;
124 case NODE_ROOT:
125 print_tabs(stream, indent);
126 fprintf(stream, "<root>\n");
127 ret = recursive_visit_print(node->u.root.child, stream,
128 indent + 1);
129 print_tabs(stream, indent);
130 fprintf(stream, "</root>\n");
131 return ret;
132 case NODE_EXPRESSION:
133 print_tabs(stream, indent);
134 fprintf(stream, "<expression>\n");
135 ret = recursive_visit_print_expression(node, stream,
136 indent + 1);
137 print_tabs(stream, indent);
138 fprintf(stream, "</expression>\n");
139 return ret;
140 case NODE_OP:
141 print_tabs(stream, indent);
142 fprintf(stream, "<op type=");
143 switch (node->u.op.type) {
144 case AST_OP_UNKNOWN:
145 default:
146 fprintf(stderr, "[error] %s: unknown op\n", __func__);
147 return -EINVAL;
148 case AST_OP_MUL:
149 fprintf(stream, "\"*\"");
150 break;
151 case AST_OP_DIV:
152 fprintf(stream, "\"/\"");
153 break;
154 case AST_OP_MOD:
155 fprintf(stream, "\"%%\"");
156 break;
157 case AST_OP_PLUS:
158 fprintf(stream, "\"+\"");
159 break;
160 case AST_OP_MINUS:
161 fprintf(stream, "\"-\"");
162 break;
163 case AST_OP_RSHIFT:
164 fprintf(stream, "\">>\"");
165 break;
166 case AST_OP_LSHIFT:
167 fprintf(stream, "\"<<\"");
168 break;
169 case AST_OP_AND:
170 fprintf(stream, "\"&&\"");
171 break;
172 case AST_OP_OR:
173 fprintf(stream, "\"||\"");
174 break;
175 case AST_OP_BIN_AND:
176 fprintf(stream, "\"&\"");
177 break;
178 case AST_OP_BIN_OR:
179 fprintf(stream, "\"|\"");
180 break;
181 case AST_OP_BIN_XOR:
182 fprintf(stream, "\"^\"");
183 break;
184
185 case AST_OP_EQ:
186 fprintf(stream, "\"==\"");
187 break;
188 case AST_OP_NE:
189 fprintf(stream, "\"!=\"");
190 break;
191 case AST_OP_GT:
192 fprintf(stream, "\">\"");
193 break;
194 case AST_OP_LT:
195 fprintf(stream, "\"<\"");
196 break;
197 case AST_OP_GE:
198 fprintf(stream, "\">=\"");
199 break;
200 case AST_OP_LE:
201 fprintf(stream, "\"<=\"");
202 break;
203 }
204 fprintf(stream, ">\n");
205 ret = recursive_visit_print(node->u.op.lchild,
206 stream, indent + 1);
207 if (ret)
208 return ret;
209 ret = recursive_visit_print(node->u.op.rchild,
210 stream, indent + 1);
211 if (ret)
212 return ret;
213 print_tabs(stream, indent);
214 fprintf(stream, "</op>\n");
215 return ret;
216 case NODE_UNARY_OP:
217 print_tabs(stream, indent);
218 fprintf(stream, "<unary_op type=");
219 switch (node->u.unary_op.type) {
220 case AST_UNARY_UNKNOWN:
221 default:
222 fprintf(stderr, "[error] %s: unknown unary_op\n", __func__);
223 return -EINVAL;
224 case AST_UNARY_PLUS:
225 fprintf(stream, "\"+\"");
226 break;
227 case AST_UNARY_MINUS:
228 fprintf(stream, "\"-\"");
229 break;
230 case AST_UNARY_NOT:
231 fprintf(stream, "\"!\"");
232 break;
233 }
234 fprintf(stream, ">\n");
235 ret = recursive_visit_print(node->u.unary_op.child,
236 stream, indent + 1);
237 print_tabs(stream, indent);
238 fprintf(stream, "</unary_op>\n");
239 return ret;
240 }
241 return 0;
242}
243
244int filter_visitor_print_xml(struct filter_parser_ctx *ctx, FILE *stream,
245 int indent)
246{
247 return recursive_visit_print(&ctx->ast->root, stream, indent);
248}
This page took 0.050177 seconds and 4 git commands to generate.