bd5e5a343cc884a9c7ff4c8223489cf4b23416fd
[lttng-tools.git] / src / lib / lttng-ctl / filter / filter-visitor-set-parent.c
1 /*
2 * filter-visitor-set-parent.c
3 *
4 * LTTng filter set parent 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-ast.h"
30 #include "filter-parser.h"
31
32 #include <common/macros.h>
33
34 static
35 int update_child(struct filter_node *parent,
36 struct filter_node *old_child,
37 struct filter_node *new_child)
38 {
39 switch (parent->type) {
40 case NODE_UNKNOWN:
41 default:
42 fprintf(stderr, "[error] %s: unknown node type\n", __func__);
43 return -EINVAL;
44 case NODE_ROOT:
45 assert(parent->u.root.child == old_child);
46 parent->u.root.child = new_child;
47 break;
48 case NODE_EXPRESSION:
49 assert(parent->u.expression.type == AST_EXP_NESTED);
50 assert(parent->u.expression.u.child == old_child);
51 parent->u.expression.u.child = new_child;
52 break;
53 case NODE_OP:
54 assert(parent->u.op.lchild == old_child ||
55 parent->u.op.rchild == old_child);
56 if (parent->u.op.lchild == old_child)
57 parent->u.op.lchild = new_child;
58 else
59 parent->u.op.rchild = new_child;
60 break;
61 case NODE_UNARY_OP:
62 assert(parent->u.unary_op.child == old_child);
63 parent->u.unary_op.child = new_child;
64 break;
65 }
66 return 0;
67 }
68
69 static
70 int recursive_visit_set_parent(struct filter_node *node,
71 struct filter_node *parent)
72 {
73 int ret;
74
75 if (!node) {
76 fprintf(stderr, "[error] %s: NULL child\n", __func__);
77 return -EINVAL;
78 }
79 node->parent = parent;
80 switch (node->type) {
81 case NODE_UNKNOWN:
82 default:
83 fprintf(stderr, "[error] %s: unknown node type\n", __func__);
84 return -EINVAL;
85 case NODE_ROOT:
86 assert(parent == NULL);
87 return recursive_visit_set_parent(node->u.root.child, node);
88 case NODE_EXPRESSION:
89 switch (node->u.expression.type) {
90 case AST_EXP_UNKNOWN:
91 default:
92 fprintf(stderr, "[error] %s: unknown expression type\n", __func__);
93 return -EINVAL;
94 case AST_EXP_NESTED:
95 return recursive_visit_set_parent(node->u.expression.u.child, node);
96 case AST_EXP_IDENTIFIER:
97 {
98 struct filter_node *orig_node = node;
99
100 while (node->u.expression.prev) {
101 struct filter_node *prev;
102
103 prev = node->u.expression.prev;
104 if (prev->type != NODE_EXPRESSION ||
105 prev->u.expression.type != AST_EXP_IDENTIFIER) {
106 fprintf(stderr, "[error] %s: expecting identifier before link\n", __func__);
107 return -EINVAL;
108 }
109
110 prev->u.expression.next = node;
111 prev->u.expression.pre_op =
112 node->u.expression.post_op;
113 prev->parent = node->parent;
114 node = prev;
115 }
116 /* Set first child as forward */
117 ret = update_child(parent, orig_node, node);
118 if (ret)
119 return ret;
120 }
121 case AST_EXP_CONSTANT:
122 case AST_EXP_FLOAT_CONSTANT:
123 case AST_EXP_STRING:
124 break;
125 }
126 break;
127 case NODE_OP:
128 ret = recursive_visit_set_parent(node->u.op.lchild, node);
129 if (ret)
130 return ret;
131 return recursive_visit_set_parent(node->u.op.rchild, node);
132 case NODE_UNARY_OP:
133 return recursive_visit_set_parent(node->u.unary_op.child, node);
134 }
135 return 0;
136 }
137
138 LTTNG_HIDDEN
139 int filter_visitor_set_parent(struct filter_parser_ctx *ctx)
140 {
141 return recursive_visit_set_parent(&ctx->ast->root, NULL);
142 }
This page took 0.045803 seconds and 4 git commands to generate.