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