Began to work on the guifilter module
[lttv.git] / ltt / branches / poly / lttv / lttv / filter.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2005 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
19 /*
20 consist in AND, OR and NOT nested expressions, forming a tree with
21 simple relations as leaves. The simple relations test is a field
22 in an event is equal, not equal, smaller, smaller or equal, larger, or
23 larger or equal to a specified value.
24 */
25
26 /*
27 * YET TO BE ANSWERED
28 * - nothing for now
29 */
30
31 #include <lttv/filter.h>
32
33 /*
34 read_token
35
36 read_expression
37 ( read expr )
38 simple expr [ op expr ]
39
40 read_simple_expression
41 read_field_path [ rel value ]
42
43 read_field_path
44 read_field_component [. field path]
45
46 read_field_component
47 name [ \[ value \] ]
48
49 data struct:
50 and/or(left/right)
51 not(child)
52 op(left/right)
53 path(component...) -> field
54 */
55
56 GQuark
57 LTTV_FILTER_TRACE,
58 LTTV_FILTER_TRACESET,
59 LTTV_FILTER_TRACEFILE,
60 LTTV_FILTER_STATE,
61 LTTV_FILTER_EVENT,
62 LTTV_FILTER_NAME,
63 LTTV_FILTER_CATEGORY,
64 LTTV_FILTER_TIME,
65 LTTV_FILTER_TSC,
66 LTTV_FILTER_PID,
67 LTTV_FILTER_PPID,
68 LTTV_FILTER_C_TIME,
69 LTTV_FILTER_I_TIME,
70 LTTV_FILTER_P_NAME,
71 LTTV_FILTER_EX_MODE,
72 LTTV_FILTER_EX_SUBMODE,
73 LTTV_FILTER_P_STATUS,
74 LTTV_FILTER_CPU;
75
76
77 /**
78 * Parse through filtering field hierarchy as specified
79 * by user. This function compares each value to
80 * predetermined quarks
81 * @param fp The field path list
82 * @return success/failure of operation
83 */
84 gboolean
85 parse_field_path(GList* fp) {
86
87 GString* f = g_list_first(fp)->data;
88
89 if(g_quark_try_string(f->str) == LTTV_FILTER_EVENT) {
90 // parse_subfield(fp, LTTV_FILTER_EVENT);
91
92 } else if(g_quark_try_string(f->str) == LTTV_FILTER_TRACEFILE) {
93
94 } else if(g_quark_try_string(f->str) == LTTV_FILTER_TRACE) {
95
96 } else if(g_quark_try_string(f->str) == LTTV_FILTER_STATE) {
97
98 } else {
99 g_warning("Unrecognized field in filter string");
100 return FALSE;
101 }
102 return TRUE;
103 }
104
105 /**
106 * Add an filtering option to the current tree
107 * @param expression Current expression to parse
108 * @return success/failure of operation
109 */
110 gboolean
111 parse_simple_expression(GString* expression) {
112
113 unsigned i;
114
115
116
117
118 }
119
120 /**
121 * Creates a new lttv_filter
122 * @param expression filtering options string
123 * @param t pointer to the current LttvTrace
124 * @return the current lttv_filter or NULL if error
125 */
126 lttv_filter_t*
127 lttv_filter_new(char *expression, LttvTraceState *tcs) {
128
129 g_print("filter::lttv_filter_new()\n"); /* debug */
130
131 unsigned
132 i,
133 p_nesting=0, /* parenthesis nesting value */
134 b=0; /* current breakpoint in expression string */
135
136 /* temporary values */
137 GString *a_field_component = g_string_new("");
138 GList *a_field_path = NULL;
139 lttv_simple_expression a_simple_expression;
140
141 /*
142 * 1. parse expression
143 * 2. construct binary tree
144 * 3. return corresponding filter
145 */
146
147 /*
148 * Binary tree memory allocation
149 * - based upon a preliminary block size
150 */
151 // gulong size = (strlen(expression)/AVERAGE_EXPRESSION_LENGTH)*MAX_FACTOR;
152 // tree = g_malloc(size*sizeof(lttv_filter_tree));
153
154 /*
155 * Parse entire expression and construct
156 * the binary tree. There are two steps
157 * in browsing that string
158 * 1. finding boolean ops ( &,|,^,! ) and parenthesis
159 * 2. finding simple expressions
160 * - field path ( separated by dots )
161 * - op ( >, <, =, >=, <=, !=)
162 * - value ( integer, string ... )
163 * To spare computing time, the whole
164 * string is parsed in this loop for a
165 * O(n) complexity order.
166 */
167 for(i=0;i<strlen(expression);i++) {
168 g_print("%s\n",a_field_component->str);
169 switch(expression[i]) {
170 /*
171 * logical operators
172 */
173 case '&': /* and */
174 case '|': /* or */
175 case '^': /* xor */
176 g_list_append( a_field_path, a_field_component );
177 a_field_component = g_string_new("");
178 break;
179 case '!': /* not, or not equal (math op) */
180 if(expression[i+1] == '=') { /* != */
181 a_simple_expression.op = LTTV_FIELD_NE;
182 i++;
183 } else { /* ! */
184 g_print("%s\n",a_field_component);
185 a_field_component = g_string_new("");
186 }
187 break;
188 case '(': /* start of parenthesis */
189 case '[':
190 case '{':
191 p_nesting++; /* incrementing parenthesis nesting value */
192 break;
193 case ')': /* end of parenthesis */
194 case ']':
195 case '}':
196 p_nesting--; /* decrementing parenthesis nesting value */
197 break;
198
199 /*
200 * mathematic operators
201 */
202 case '<': /* lower, lower or equal */
203 if(expression[i+1] == '=') { /* <= */
204 i++;
205 a_simple_expression.op = LTTV_FIELD_LE;
206 } else a_simple_expression.op = LTTV_FIELD_LT;
207 break;
208 case '>': /* higher, higher or equal */
209 if(expression[i+1] == '=') { /* >= */
210 i++;
211 a_simple_expression.op = LTTV_FIELD_GE;
212 } else a_simple_expression.op = LTTV_FIELD_GT;
213 break;
214 case '=': /* equal */
215 a_simple_expression.op = LTTV_FIELD_EQ;
216 break;
217 /*
218 * Field concatening caracter
219 */
220 case '.': /* dot */
221 g_list_append( a_field_path, a_field_component );
222 a_field_component = g_string_new("");
223 break;
224 default: /* concatening current string */
225 g_string_append_c(a_field_component,expression[i]);
226 }
227 }
228
229
230
231 if( p_nesting>0 ) {
232 g_warning("Wrong filtering options, the string\n\"%s\"\n\
233 is not valid due to parenthesis incorrect use",expression);
234 return NULL;
235 }
236 }
237
238 /**
239 * Apply the filter to a specific trace
240 * @param filter the current filter applied
241 * @param tracefile the trace to apply the filter to
242 * @return success/failure of operation
243 */
244 gboolean
245 lttv_filter_tracefile(lttv_filter_t *filter, LttTracefile *tracefile) {
246
247
248
249 /* test */
250 /* int i, nb;
251 char *f_name, *e_name;
252
253 char* field = "cpu";
254
255 LttvTraceHook h;
256
257 LttEventType *et;
258
259 LttType *t;
260
261 GString *fe_name = g_string_new("");
262
263 nb = ltt_trace_eventtype_number(tcs->parent.t);
264 g_print("NB:%i\n",nb);
265 for(i = 0 ; i < nb ; i++) {
266 et = ltt_trace_eventtype_get(tcs->parent.t, i);
267 e_name = ltt_eventtype_name(et);
268 f_name = ltt_facility_name(ltt_eventtype_facility(et));
269 g_string_printf(fe_name, "%s.%s", f_name, e_name);
270 g_print("facility:%s and event:%s\n",f_name,e_name);
271 }
272 */
273 }
274
275 gboolean
276 lttv_filter_tracestate(lttv_filter_t *filter, LttvTraceState *tracestate) {
277
278 }
279
280 /**
281 * Apply the filter to a specific event
282 * @param filter the current filter applied
283 * @param event the event to apply the filter to
284 * @return success/failure of operation
285 */
286 gboolean
287 lttv_filter_event(lttv_filter_t *filter, LttEvent *event) {
288
289 }
290
291 /**
292 * Initializes the filter module and specific values
293 */
294 static void module_init()
295 {
296
297 /*
298 * Quarks initialization
299 * for hardcoded filtering options
300 *
301 * TODO: traceset has no yet been defined
302 */
303
304 /* top fields */
305 LTTV_FILTER_EVENT = g_quark_from_string("event");
306 LTTV_FILTER_TRACE = g_quark_from_string("trace");
307 LTTV_FILTER_TRACESET = g_quark_from_string("traceset");
308 LTTV_FILTER_STATE = g_quark_from_string("state");
309 LTTV_FILTER_TRACEFILE = g_quark_from_string("tracefile");
310
311 /* event.name, tracefile.name, trace.name */
312 LTTV_FILTER_NAME = g_quark_from_string("name");
313
314 /* event sub fields */
315 LTTV_FILTER_CATEGORY = g_quark_from_string("category");
316 LTTV_FILTER_TIME = g_quark_from_string("time");
317 LTTV_FILTER_TSC = g_quark_from_string("tsc");
318
319 /* state sub fields */
320 LTTV_FILTER_PID = g_quark_from_string("pid");
321 LTTV_FILTER_PPID = g_quark_from_string("ppid");
322 LTTV_FILTER_C_TIME = g_quark_from_string("creation_time");
323 LTTV_FILTER_I_TIME = g_quark_from_string("insertion_time");
324 LTTV_FILTER_P_NAME = g_quark_from_string("process_name");
325 LTTV_FILTER_EX_MODE = g_quark_from_string("execution_mode");
326 LTTV_FILTER_EX_SUBMODE = g_quark_from_string("execution_submode");
327 LTTV_FILTER_P_STATUS = g_quark_from_string("process_status");
328 LTTV_FILTER_CPU = g_quark_from_string("cpu");
329
330 }
331
332 /**
333 * Destroys the filter module and specific values
334 */
335 static void module_destroy()
336 {
337 }
338
339
340 LTTV_MODULE("filter", "Filters traceset and events", \
341 "Filters traceset and events specifically to user input", \
342 module_init, module_destroy)
343
344
345
This page took 0.037661 seconds and 4 git commands to generate.