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