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