9c312311 |
1 | /* This file is part of the Linux Trace Toolkit viewer |
852f16bb |
2 | * Copyright (C) 2003-2005 Michel Dagenais and Simon Bouvier-Zappa |
9c312311 |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License Version 2 as |
6 | * published by the Free Software Foundation; |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License |
14 | * along with this program; if not, write to the Free Software |
15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
16 | * MA 02111-1307, USA. |
17 | */ |
18 | |
48f6f3c2 |
19 | #ifndef FILTER_H |
20 | #define FILTER_H |
21 | |
31452f49 |
22 | #include <lttv/traceset.h> |
a4c292d4 |
23 | #include <lttv/tracecontext.h> |
24 | #include <lttv/state.h> |
91ad3f0a |
25 | #include <lttv/module.h> |
a4c292d4 |
26 | #include <ltt/ltt.h> |
7145a073 |
27 | #include <ltt/time.h> |
a4c292d4 |
28 | #include <ltt/event.h> |
29 | |
31452f49 |
30 | |
56e29124 |
31 | /* |
32 | A filter expression consists in nested AND, OR and NOT expressions |
48f6f3c2 |
33 | involving boolean relation (>, >=, =, !=, <, <=) between event fields and |
34 | specific values. It is compiled into an efficient data structure which |
35 | is used in functions to check if a given event or tracefile satisfies the |
36 | filter. |
37 | |
38 | The grammar for filters is: |
39 | |
40 | filter = expression |
41 | |
42 | expression = "(" expression ")" | "!" expression | |
43 | expression "&&" expression | expression "||" expression | |
44 | simpleExpression |
45 | |
46 | simpleExpression = fieldPath op value |
47 | |
48 | fieldPath = fieldComponent [ "." fieldPath ] |
49 | |
50 | fieldComponent = name [ "[" integer "]" ] |
51 | |
52 | value = integer | double | string |
48f6f3c2 |
53 | */ |
54 | |
e00d6a24 |
55 | /* structures prototypes */ |
56 | typedef enum _LttvStructType LttvStructType; |
57 | typedef enum _LttvFieldType LttvFieldType; |
58 | typedef enum _LttvExpressionOp LttvExpressionOp; |
59 | typedef enum _LttvTreeElement LttvTreeElement; |
60 | typedef enum _LttvLogicalOp LttvLogicalOp; |
61 | |
62 | typedef union _LttvFieldValue LttvFieldValue; |
63 | |
64 | typedef struct _LttvSimpleExpression LttvSimpleExpression; |
65 | typedef struct _LttvFilterTree LttvFilterTree; |
66 | typedef struct _LttvFilter LttvFilter; |
67 | |
68 | |
80f9611a |
69 | /** |
70 | * @enum LttvStructType |
71 | * @brief The lttv structures |
72 | * |
73 | * the LttvStructType enumerates |
74 | * the possible structures for the |
75 | * lttv core filter |
76 | */ |
77 | enum _LttvStructType { |
78 | LTTV_FILTER_TRACE, |
79 | LTTV_FILTER_TRACESET, |
80 | LTTV_FILTER_TRACEFILE, |
81 | LTTV_FILTER_EVENT, |
82 | LTTV_FILTER_STATE |
e00d6a24 |
83 | }; |
80f9611a |
84 | |
150f0d33 |
85 | /** |
86 | * @enum LttvFieldType |
80f9611a |
87 | * @brief Possible fields for the structures |
150f0d33 |
88 | * |
89 | * the LttvFieldType enum consists on |
90 | * all the hardcoded structures and |
91 | * their appropriate fields on which |
92 | * filters can be applied. |
93 | */ |
94 | enum _LttvFieldType { |
bb87caa7 |
95 | LTTV_FILTER_TRACE_NAME, /** trace.name (char*) */ |
96 | LTTV_FILTER_TRACEFILE_NAME, /** tracefile.name (char*) */ |
97 | LTTV_FILTER_STATE_PID, /** state.pid (guint) */ |
98 | LTTV_FILTER_STATE_PPID, /** state.ppid (guint) */ |
99 | LTTV_FILTER_STATE_CT, /** state.creation_time (double) */ |
100 | LTTV_FILTER_STATE_IT, /** state.insertion_time (double) */ |
101 | LTTV_FILTER_STATE_P_NAME, /** state.process_name (char*) */ |
102 | LTTV_FILTER_STATE_EX_MODE, /** state.execution_mode (LttvExecutionMode) */ |
103 | LTTV_FILTER_STATE_EX_SUBMODE, /** state.execution_submode (LttvExecutionSubmode) */ |
104 | LTTV_FILTER_STATE_P_STATUS, /** state.process_status (LttvProcessStatus) */ |
105 | LTTV_FILTER_STATE_CPU, /** state.cpu (?last_cpu?) */ |
106 | LTTV_FILTER_EVENT_NAME, /** event.name (char*) */ |
107 | LTTV_FILTER_EVENT_CATEGORY, /** FIXME: not implemented */ |
108 | LTTV_FILTER_EVENT_TIME, /** event.time (double) */ |
109 | LTTV_FILTER_EVENT_TSC, /** event.tsc (double) */ |
110 | LTTV_FILTER_EVENT_FIELD, |
56e29124 |
111 | LTTV_FILTER_UNDEFINED /** undefined field */ |
e00d6a24 |
112 | }; |
91ad3f0a |
113 | |
84a333d6 |
114 | /** |
150f0d33 |
115 | * @enum LttvExpressionOp |
56e29124 |
116 | * @brief Contains possible operators |
117 | * |
118 | * This enumeration defines the |
119 | * possible operator used to compare |
120 | * right and left member in simple |
121 | * expression |
84a333d6 |
122 | */ |
e00d6a24 |
123 | enum _LttvExpressionOp |
84a333d6 |
124 | { |
56e29124 |
125 | LTTV_FIELD_EQ, /** equal */ |
126 | LTTV_FIELD_NE, /** not equal */ |
127 | LTTV_FIELD_LT, /** lower than */ |
128 | LTTV_FIELD_LE, /** lower or equal */ |
129 | LTTV_FIELD_GT, /** greater than */ |
130 | LTTV_FIELD_GE /** greater or equal */ |
e00d6a24 |
131 | }; |
84a333d6 |
132 | |
56e29124 |
133 | /** |
134 | * @union LttvFieldValue |
135 | * |
136 | * @brief Contains possible field values |
137 | * This particular union defines the |
138 | * possible set of values taken by the |
139 | * right member of a simple expression. |
140 | * It is used for comparison whithin the |
141 | * 'operators' functions |
142 | */ |
e00d6a24 |
143 | union _LttvFieldValue { |
56e29124 |
144 | guint64 v_uint64; |
145 | guint32 v_uint32; |
146 | guint16 v_uint16; |
147 | double v_double; |
148 | char* v_string; |
7145a073 |
149 | LttTime v_ltttime; |
e00d6a24 |
150 | }; |
56e29124 |
151 | |
150f0d33 |
152 | /** |
153 | * @enum LttvTreeElement |
154 | * @brief element types for the tree nodes |
155 | * |
156 | * LttvTreeElement defines the possible |
157 | * types of nodes which build the LttvFilterTree. |
2ea36caf |
158 | */ |
e00d6a24 |
159 | enum _LttvTreeElement { |
56e29124 |
160 | LTTV_TREE_IDLE, /** this node does nothing */ |
161 | LTTV_TREE_NODE, /** this node contains a logical operator */ |
162 | LTTV_TREE_LEAF /** this node is a leaf and contains a simple expression */ |
e00d6a24 |
163 | }; |
f4e9dd16 |
164 | |
56e29124 |
165 | |
150f0d33 |
166 | /** |
e00d6a24 |
167 | * @struct LttvSimpleExpression |
150f0d33 |
168 | * @brief simple expression structure |
169 | * |
170 | * An LttvSimpleExpression is the base |
171 | * of all filtering operations. It also |
172 | * populates the leaves of the |
173 | * LttvFilterTree. Each expression |
174 | * consists basically in a structure |
175 | * field, an operator and a specific |
176 | * value. |
177 | */ |
e00d6a24 |
178 | struct _LttvSimpleExpression |
84a333d6 |
179 | { |
9ab5ebd7 |
180 | gint field; /** left member of simple expression */ |
181 | gint offset; /** offset used for dynamic fields */ |
182 | gboolean (*op)(gpointer,LttvFieldValue); /** operator of simple expression */ |
183 | // char *value; |
184 | LttvFieldValue value; /** right member of simple expression */ |
e00d6a24 |
185 | }; |
84a333d6 |
186 | |
150f0d33 |
187 | /** |
188 | * @enum LttvLogicalOp |
189 | * @brief logical operators |
190 | * |
191 | * Contains the possible values taken |
192 | * by logical operator used to link |
193 | * simple expression. Values are |
194 | * AND, OR, XOR or NOT |
195 | */ |
e00d6a24 |
196 | enum _LttvLogicalOp { |
56e29124 |
197 | LTTV_LOGICAL_OR = 1, /** OR (1) */ |
198 | LTTV_LOGICAL_AND = 1<<1, /** AND (2) */ |
199 | LTTV_LOGICAL_NOT = 1<<2, /** NOT (4) */ |
200 | LTTV_LOGICAL_XOR = 1<<3 /** XOR (8) */ |
e00d6a24 |
201 | }; |
1a7fa682 |
202 | |
150f0d33 |
203 | /** |
204 | * @struct LttvFilterTree |
205 | * The filtering tree is used to represent the |
206 | * expression string in its entire hierarchy |
207 | * composed of simple expressions and logical |
208 | * operators |
2ea36caf |
209 | */ |
e00d6a24 |
210 | struct _LttvFilterTree { |
2ea36caf |
211 | int node; /** value of LttvLogicalOp */ |
212 | LttvTreeElement left; |
213 | LttvTreeElement right; |
f4e9dd16 |
214 | union { |
e00d6a24 |
215 | LttvFilterTree* t; |
2ea36caf |
216 | LttvSimpleExpression* leaf; |
f4e9dd16 |
217 | } l_child; |
218 | union { |
e00d6a24 |
219 | LttvFilterTree* t; |
2ea36caf |
220 | LttvSimpleExpression* leaf; |
f4e9dd16 |
221 | } r_child; |
e00d6a24 |
222 | }; |
84a333d6 |
223 | |
31452f49 |
224 | /** |
225 | * @struct lttv_filter |
150f0d33 |
226 | * Contains a binary tree of filtering options along |
227 | * with the expression itself. |
31452f49 |
228 | */ |
e00d6a24 |
229 | struct _LttvFilter { |
150f0d33 |
230 | char *expression; |
231 | LttvFilterTree *head; |
e00d6a24 |
232 | }; |
84a333d6 |
233 | |
56e29124 |
234 | /* |
235 | * Simple Expression |
236 | */ |
237 | LttvSimpleExpression* lttv_simple_expression_new(); |
238 | |
239 | gboolean lttv_simple_expression_add_field(GPtrArray* fp, LttvSimpleExpression* se); |
91ad3f0a |
240 | |
56e29124 |
241 | gboolean lttv_simple_expression_assign_operator(LttvSimpleExpression* se, LttvExpressionOp op); |
bb87caa7 |
242 | |
9ab5ebd7 |
243 | gboolean lttv_simple_expression_assign_value(LttvSimpleExpression* se, char* value); |
244 | |
56e29124 |
245 | void lttv_simple_expression_destroy(LttvSimpleExpression* se); |
5f185a2b |
246 | |
5f185a2b |
247 | |
150f0d33 |
248 | /* |
249 | * Logical operators functions |
250 | */ |
251 | |
4d9ff942 |
252 | gboolean lttv_apply_op_eq_uint64(const gpointer v1, LttvFieldValue v2); |
253 | gboolean lttv_apply_op_eq_uint32(const gpointer v1, LttvFieldValue v2); |
254 | gboolean lttv_apply_op_eq_uint16(const gpointer v1, LttvFieldValue v2); |
255 | gboolean lttv_apply_op_eq_double(const gpointer v1, LttvFieldValue v2); |
256 | gboolean lttv_apply_op_eq_string(const gpointer v1, LttvFieldValue v2); |
c6832b57 |
257 | gboolean lttv_apply_op_eq_quark(const gpointer v1, LttvFieldValue v2); |
4d9ff942 |
258 | gboolean lttv_apply_op_eq_ltttime(const gpointer v1, LttvFieldValue v2); |
259 | |
260 | gboolean lttv_apply_op_ne_uint64(const gpointer v1, LttvFieldValue v2); |
261 | gboolean lttv_apply_op_ne_uint32(const gpointer v1, LttvFieldValue v2); |
262 | gboolean lttv_apply_op_ne_uint16(const gpointer v1, LttvFieldValue v2); |
263 | gboolean lttv_apply_op_ne_double(const gpointer v1, LttvFieldValue v2); |
264 | gboolean lttv_apply_op_ne_string(const gpointer v1, LttvFieldValue v2); |
c6832b57 |
265 | gboolean lttv_apply_op_ne_quark(const gpointer v1, LttvFieldValue v2); |
4d9ff942 |
266 | gboolean lttv_apply_op_ne_ltttime(const gpointer v1, LttvFieldValue v2); |
267 | |
268 | gboolean lttv_apply_op_lt_uint64(const gpointer v1, LttvFieldValue v2); |
269 | gboolean lttv_apply_op_lt_uint32(const gpointer v1, LttvFieldValue v2); |
270 | gboolean lttv_apply_op_lt_uint16(const gpointer v1, LttvFieldValue v2); |
271 | gboolean lttv_apply_op_lt_double(const gpointer v1, LttvFieldValue v2); |
272 | gboolean lttv_apply_op_lt_ltttime(const gpointer v1, LttvFieldValue v2); |
273 | |
274 | gboolean lttv_apply_op_le_uint64(const gpointer v1, LttvFieldValue v2); |
275 | gboolean lttv_apply_op_le_uint32(const gpointer v1, LttvFieldValue v2); |
276 | gboolean lttv_apply_op_le_uint16(const gpointer v1, LttvFieldValue v2); |
277 | gboolean lttv_apply_op_le_double(const gpointer v1, LttvFieldValue v2); |
278 | gboolean lttv_apply_op_le_ltttime(const gpointer v1, LttvFieldValue v2); |
279 | |
280 | gboolean lttv_apply_op_gt_uint64(const gpointer v1, LttvFieldValue v2); |
281 | gboolean lttv_apply_op_gt_uint32(const gpointer v1, LttvFieldValue v2); |
282 | gboolean lttv_apply_op_gt_uint16(const gpointer v1, LttvFieldValue v2); |
283 | gboolean lttv_apply_op_gt_double(const gpointer v1, LttvFieldValue v2); |
284 | gboolean lttv_apply_op_gt_ltttime(const gpointer v1, LttvFieldValue v2); |
285 | |
286 | gboolean lttv_apply_op_ge_uint64(const gpointer v1, LttvFieldValue v2); |
287 | gboolean lttv_apply_op_ge_uint32(const gpointer v1, LttvFieldValue v2); |
288 | gboolean lttv_apply_op_ge_uint16(const gpointer v1, LttvFieldValue v2); |
289 | gboolean lttv_apply_op_ge_double(const gpointer v1, LttvFieldValue v2); |
290 | gboolean lttv_apply_op_ge_ltttime(const gpointer v1, LttvFieldValue v2); |
150f0d33 |
291 | |
292 | /* |
293 | * Cloning |
294 | */ |
295 | |
4d9ff942 |
296 | LttvFilterTree* lttv_filter_tree_clone(const LttvFilterTree* tree); |
150f0d33 |
297 | |
4d9ff942 |
298 | LttvFilter* lttv_filter_clone(const LttvFilter* filter); |
150f0d33 |
299 | |
56e29124 |
300 | /* |
301 | * LttvFilter |
150f0d33 |
302 | */ |
5f185a2b |
303 | LttvFilter *lttv_filter_new(); |
304 | |
305 | gboolean lttv_filter_update(LttvFilter* filter); |
48f6f3c2 |
306 | |
2ea36caf |
307 | void lttv_filter_destroy(LttvFilter* filter); |
1da1525d |
308 | |
56e29124 |
309 | gboolean lttv_filter_append_expression(LttvFilter* filter, char *expression); |
80f9611a |
310 | |
311 | void lttv_filter_clear_expression(LttvFilter* filter); |
312 | |
56e29124 |
313 | /* |
314 | * LttvFilterTree |
315 | */ |
150f0d33 |
316 | LttvFilterTree* lttv_filter_tree_new(); |
317 | |
318 | void lttv_filter_tree_destroy(LttvFilterTree* tree); |
319 | |
80f9611a |
320 | gboolean lttv_filter_tree_parse( |
4d9ff942 |
321 | const LttvFilterTree* t, |
322 | const LttEvent* event, |
323 | const LttTracefile* tracefile, |
324 | const LttTrace* trace, |
325 | const LttvProcessState* state, |
326 | const LttvTracefileContext* context); |
327 | |
328 | gboolean lttv_filter_tree_parse_branch( |
329 | const LttvSimpleExpression* se, |
330 | const LttEvent* event, |
331 | const LttTracefile* tracefile, |
332 | const LttTrace* trace, |
333 | const LttvProcessState* state, |
334 | const LttvTracefileContext* context); |
48f6f3c2 |
335 | |
80f9611a |
336 | /* |
337 | * Debug functions |
338 | */ |
4d9ff942 |
339 | void lttv_print_tree(const LttvFilterTree* t); |
80f9611a |
340 | |
48f6f3c2 |
341 | #endif // FILTER_H |
342 | |