Implement per-context filtering
[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: /* fall-through */
97 case AST_EXP_GLOBAL_IDENTIFIER:
98 {
99 struct filter_node *orig_node = node;
100
101 while (node->u.expression.prev) {
102 struct filter_node *prev;
103
104 prev = node->u.expression.prev;
105 if (prev->type != NODE_EXPRESSION ||
106 (prev->u.expression.type != AST_EXP_IDENTIFIER
107 && prev->u.expression.type != AST_EXP_GLOBAL_IDENTIFIER)) {
108 fprintf(stderr, "[error] %s: expecting identifier before link\n", __func__);
109 return -EINVAL;
110 }
111
112 prev->u.expression.next = node;
113 prev->u.expression.pre_op =
114 node->u.expression.post_op;
115 prev->parent = node->parent;
116 node = prev;
117 }
118 /* Set first child as forward */
119 ret = update_child(parent, orig_node, node);
120 if (ret)
121 return ret;
122 }
123 case AST_EXP_CONSTANT:
124 case AST_EXP_FLOAT_CONSTANT:
125 case AST_EXP_STRING:
126 break;
127 }
128 break;
129 case NODE_OP:
130 ret = recursive_visit_set_parent(node->u.op.lchild, node);
131 if (ret)
132 return ret;
133 return recursive_visit_set_parent(node->u.op.rchild, node);
134 case NODE_UNARY_OP:
135 return recursive_visit_set_parent(node->u.unary_op.child, node);
136 }
137 return 0;
138 }
139
140 LTTNG_HIDDEN
141 int filter_visitor_set_parent(struct filter_parser_ctx *ctx)
142 {
143 return recursive_visit_set_parent(&ctx->ast->root, NULL);
144 }
This page took 0.047759 seconds and 5 git commands to generate.