2 * filter-visitor-set-parent.c
4 * LTTng filter set parent visitor
6 * Copyright 2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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.
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.
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
29 #include "filter-ast.h"
30 #include "filter-parser.h"
32 #include <common/macros.h>
35 int update_child(struct filter_node
*parent
,
36 struct filter_node
*old_child
,
37 struct filter_node
*new_child
)
40 fprintf(stderr
, "[error] %s: NULL parent\n", __func__
);
44 switch (parent
->type
) {
47 fprintf(stderr
, "[error] %s: unknown node type\n", __func__
);
50 assert(parent
->u
.root
.child
== old_child
);
51 parent
->u
.root
.child
= new_child
;
54 assert(parent
->u
.expression
.type
== AST_EXP_NESTED
);
55 assert(parent
->u
.expression
.u
.child
== old_child
);
56 parent
->u
.expression
.u
.child
= new_child
;
59 assert(parent
->u
.op
.lchild
== old_child
||
60 parent
->u
.op
.rchild
== old_child
);
61 if (parent
->u
.op
.lchild
== old_child
)
62 parent
->u
.op
.lchild
= new_child
;
64 parent
->u
.op
.rchild
= new_child
;
67 assert(parent
->u
.unary_op
.child
== old_child
);
68 parent
->u
.unary_op
.child
= new_child
;
75 int recursive_visit_set_parent(struct filter_node
*node
,
76 struct filter_node
*parent
)
81 fprintf(stderr
, "[error] %s: NULL child\n", __func__
);
84 node
->parent
= parent
;
88 fprintf(stderr
, "[error] %s: unknown node type\n", __func__
);
91 assert(parent
== NULL
);
92 return recursive_visit_set_parent(node
->u
.root
.child
, node
);
94 switch (node
->u
.expression
.type
) {
97 fprintf(stderr
, "[error] %s: unknown expression type\n", __func__
);
100 return recursive_visit_set_parent(node
->u
.expression
.u
.child
, node
);
101 case AST_EXP_IDENTIFIER
: /* fall-through */
102 case AST_EXP_GLOBAL_IDENTIFIER
:
104 struct filter_node
*orig_node
= node
;
106 while (node
->u
.expression
.prev
) {
107 struct filter_node
*prev
;
109 prev
= node
->u
.expression
.prev
;
110 if (prev
->type
!= NODE_EXPRESSION
||
111 (prev
->u
.expression
.type
!= AST_EXP_IDENTIFIER
112 && prev
->u
.expression
.type
!= AST_EXP_GLOBAL_IDENTIFIER
)) {
113 fprintf(stderr
, "[error] %s: expecting identifier before link\n", __func__
);
117 prev
->u
.expression
.next
= node
;
118 prev
->u
.expression
.pre_op
=
119 node
->u
.expression
.post_op
;
120 prev
->parent
= node
->parent
;
123 /* Set first child as forward */
124 ret
= update_child(parent
, orig_node
, node
);
128 case AST_EXP_CONSTANT
:
129 case AST_EXP_FLOAT_CONSTANT
:
135 ret
= recursive_visit_set_parent(node
->u
.op
.lchild
, node
);
138 return recursive_visit_set_parent(node
->u
.op
.rchild
, node
);
140 return recursive_visit_set_parent(node
->u
.unary_op
.child
, node
);
146 int filter_visitor_set_parent(struct filter_parser_ctx
*ctx
)
148 return recursive_visit_set_parent(&ctx
->ast
->root
, NULL
);