filter core
[lttv.git] / ltt / branches / poly / lttv / lttv / filter.c
CommitLineData
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
31452f49 19/*
a4c292d4 20 read_token
48f6f3c2 21
a4c292d4 22 read_expression
23 ( read expr )
24 simple expr [ op expr ]
48f6f3c2 25
a4c292d4 26 read_simple_expression
27 read_field_path [ rel value ]
48f6f3c2 28
a4c292d4 29 read_field_path
30 read_field_component [. field path]
48f6f3c2 31
a4c292d4 32 read_field_component
33 name [ \[ value \] ]
48f6f3c2 34
a4c292d4 35 data struct:
36 and/or(left/right)
37 not(child)
38 op(left/right)
39 path(component...) -> field
150f0d33 40
41 consist in AND, OR and NOT nested expressions, forming a tree with
42 simple relations as leaves. The simple relations test is a field
43 in an event is equal, not equal, smaller, smaller or equal, larger, or
44 larger or equal to a specified value.
31452f49 45*/
46
150f0d33 47/*
48 * YET TO BE ANSWERED
49 * - none yet
50 */
51
52/*
53 * TODO
54 * - refine switch of expression in multiple uses functions
55 * - remove the idle expressions in the tree ****
56 * - add the current simple expression to the tree
389ba50e 57 * * clear the field_path array after use
150f0d33 58 */
59
60#include <lttv/filter.h>
46c40a93 61#include <ltt/time.h>
150f0d33 62
63/*
1a7fa682 64GQuark
65 LTTV_FILTER_TRACE,
66 LTTV_FILTER_TRACESET,
67 LTTV_FILTER_TRACEFILE,
68 LTTV_FILTER_STATE,
91ad3f0a 69 LTTV_FILTER_EVENT,
70 LTTV_FILTER_NAME,
71 LTTV_FILTER_CATEGORY,
72 LTTV_FILTER_TIME,
73 LTTV_FILTER_TSC,
74 LTTV_FILTER_PID,
75 LTTV_FILTER_PPID,
76 LTTV_FILTER_C_TIME,
77 LTTV_FILTER_I_TIME,
78 LTTV_FILTER_P_NAME,
79 LTTV_FILTER_EX_MODE,
80 LTTV_FILTER_EX_SUBMODE,
81 LTTV_FILTER_P_STATUS,
82 LTTV_FILTER_CPU;
150f0d33 83*/
0cdc2470 84
80f9611a 85
86/**
56e29124 87 * @fn LttvSimpleExpression* lttv_simple_expression_new()
88 *
80f9611a 89 * Constructor for LttvSimpleExpression
90 * @return pointer to new LttvSimpleExpression
91 */
92LttvSimpleExpression*
93lttv_simple_expression_new() {
94
95 LttvSimpleExpression* se = g_new(LttvSimpleExpression,1);
96
97 se->field = LTTV_FILTER_UNDEFINED;
98 se->op = NULL;
99 se->offset = 0;
80f9611a 100
101 return se;
102}
103
0769c82f 104/**
56e29124 105 * @fn gboolean lttv_simple_expression_add_field(GPtrArray*,LttvSimpleExpression*)
106 *
0769c82f 107 * Parse through filtering field hierarchy as specified
108 * by user. This function compares each value to
109 * predetermined quarks
110 * @param fp The field path list
bb87caa7 111 * @param se current simple expression
0769c82f 112 * @return success/failure of operation
113 */
114gboolean
9ab5ebd7 115lttv_simple_expression_assign_field(GPtrArray* fp, LttvSimpleExpression* se) {
0769c82f 116
f4e9dd16 117 GString* f = NULL;
73050a5f 118
2b99ec10 119 if(fp->len < 2) return FALSE;
56e29124 120 g_assert(f=g_ptr_array_remove_index(fp,0));
73050a5f 121
47aa6e58 122 /*
123 * Parse through the specified
124 * hardcoded fields.
125 *
126 * Take note however that the
127 * 'event' subfields might change
128 * depending on values specified
129 * in core.xml file. Hence, if
130 * none of the subfields in the
131 * array match the hardcoded
132 * subfields, it will be considered
133 * as a dynamic field
134 */
80f9611a 135 if(!g_strcasecmp(f->str,"trace") ) {
47aa6e58 136 /*
137 * Possible values:
138 * trace.name
139 */
73050a5f 140 g_string_free(f,TRUE);
141 f=g_ptr_array_remove_index(fp,0);
80f9611a 142 if(!g_strcasecmp(f->str,"name")) {
389ba50e 143 se->field = LTTV_FILTER_TRACE_NAME;
144 }
80f9611a 145 } else if(!g_strcasecmp(f->str,"traceset") ) {
47aa6e58 146 /*
147 * FIXME: not yet implemented !
148 */
80f9611a 149 } else if(!g_strcasecmp(f->str,"tracefile") ) {
47aa6e58 150 /*
151 * Possible values:
152 * tracefile.name
153 */
73050a5f 154 g_string_free(f,TRUE);
155 f=g_ptr_array_remove_index(fp,0);
80f9611a 156 if(!g_strcasecmp(f->str,"name")) {
389ba50e 157 se->field = LTTV_FILTER_TRACEFILE_NAME;
158 }
80f9611a 159 } else if(!g_strcasecmp(f->str,"state") ) {
47aa6e58 160 /*
161 * Possible values:
162 * state.pid
163 * state.ppid
164 * state.creation_time
165 * state.insertion_time
166 * state.process_name
167 * state.execution_mode
168 * state.execution_submode
169 * state.process_status
170 * state.cpu
171 */
73050a5f 172 g_string_free(f,TRUE);
173 f=g_ptr_array_remove_index(fp,0);
80f9611a 174 if(!g_strcasecmp(f->str,"pid") ) {
389ba50e 175 se->field = LTTV_FILTER_STATE_PID;
176 }
80f9611a 177 else if(!g_strcasecmp(f->str,"ppid") ) {
389ba50e 178 se->field = LTTV_FILTER_STATE_PPID;
179 }
80f9611a 180 else if(!g_strcasecmp(f->str,"creation_time") ) {
389ba50e 181 se->field = LTTV_FILTER_STATE_CT;
182 }
80f9611a 183 else if(!g_strcasecmp(f->str,"insertion_time") ) {
389ba50e 184 se->field = LTTV_FILTER_STATE_IT;
185 }
80f9611a 186 else if(!g_strcasecmp(f->str,"process_name") ) {
389ba50e 187 se->field = LTTV_FILTER_STATE_P_NAME;
188 }
80f9611a 189 else if(!g_strcasecmp(f->str,"execution_mode") ) {
389ba50e 190 se->field = LTTV_FILTER_STATE_EX_MODE;
191 }
80f9611a 192 else if(!g_strcasecmp(f->str,"execution_submode") ) {
389ba50e 193 se->field = LTTV_FILTER_STATE_EX_SUBMODE;
194 }
80f9611a 195 else if(!g_strcasecmp(f->str,"process_status") ) {
389ba50e 196 se->field = LTTV_FILTER_STATE_P_STATUS;
197 }
80f9611a 198 else if(!g_strcasecmp(f->str,"cpu") ) {
389ba50e 199 se->field = LTTV_FILTER_STATE_CPU;
200 }
80f9611a 201 } else if(!g_strcasecmp(f->str,"event") ) {
389ba50e 202 /*
203 * Possible values:
204 * event.name
205 * event.category
206 * event.time
207 * event.tsc
208 */
73050a5f 209 g_string_free(f,TRUE);
210 f=g_ptr_array_remove_index(fp,0);
80f9611a 211 if(!g_strcasecmp(f->str,"name") ) {
389ba50e 212 se->field = LTTV_FILTER_EVENT_NAME;
213 }
80f9611a 214 else if(!g_strcasecmp(f->str,"category") ) {
389ba50e 215 /*
216 * FIXME: Category not yet functional in lttv
217 */
218 se->field = LTTV_FILTER_EVENT_CATEGORY;
219 }
80f9611a 220 else if(!g_strcasecmp(f->str,"time") ) {
389ba50e 221 se->field = LTTV_FILTER_EVENT_TIME;
2b99ec10 222 }
80f9611a 223 else if(!g_strcasecmp(f->str,"tsc") ) {
389ba50e 224 se->field = LTTV_FILTER_EVENT_TSC;
2b99ec10 225 }
226 else { /* core.xml specified options */
389ba50e 227 se->field = LTTV_FILTER_EVENT_FIELD;
2b99ec10 228 }
91ad3f0a 229 } else {
230 g_warning("Unrecognized field in filter string");
0769c82f 231 }
47aa6e58 232
56e29124 233 /* free memory for last string */
73050a5f 234 g_string_free(f,TRUE);
56e29124 235
236 /* array should be empty */
73050a5f 237 g_assert(fp->len == 0);
56e29124 238
56e29124 239 if(se->field == LTTV_FILTER_UNDEFINED) {
240 g_warning("The specified field was not recognized !");
241 return FALSE;
242 }
91ad3f0a 243 return TRUE;
0769c82f 244}
245
bb87caa7 246/**
56e29124 247 * @fn gboolean lttv_simple_expression_assign_operator(LttvSimpleExpression*,LttvExpressionOp)
248 *
bb87caa7 249 * Sets the function pointer for the current
250 * Simple Expression
251 * @param se current simple expression
252 * @return success/failure of operation
253 */
56e29124 254gboolean lttv_simple_expression_assign_operator(LttvSimpleExpression* se, LttvExpressionOp op) {
aa4600f3 255
bb87caa7 256 switch(se->field) {
56e29124 257 /*
258 * string
259 */
bb87caa7 260 case LTTV_FILTER_TRACE_NAME:
261 case LTTV_FILTER_TRACEFILE_NAME:
262 case LTTV_FILTER_STATE_P_NAME:
263 case LTTV_FILTER_EVENT_NAME:
264 switch(op) {
265 case LTTV_FIELD_EQ:
c6832b57 266 se->op = lttv_apply_op_eq_quark;
bb87caa7 267 break;
268 case LTTV_FIELD_NE:
c6832b57 269 se->op = lttv_apply_op_ne_quark;
bb87caa7 270 break;
271 default:
73050a5f 272 g_warning("Error encountered in operator assignment = or != expected");
bb87caa7 273 return FALSE;
274 }
275 break;
56e29124 276 /*
277 * integer
278 */
bb87caa7 279 case LTTV_FILTER_STATE_PID:
280 case LTTV_FILTER_STATE_PPID:
281 case LTTV_FILTER_STATE_EX_MODE:
282 case LTTV_FILTER_STATE_EX_SUBMODE:
283 case LTTV_FILTER_STATE_P_STATUS:
284 switch(op) {
285 case LTTV_FIELD_EQ:
286 se->op = lttv_apply_op_eq_uint64;
287 break;
288 case LTTV_FIELD_NE:
289 se->op = lttv_apply_op_ne_uint64;
290 break;
291 case LTTV_FIELD_LT:
292 se->op = lttv_apply_op_lt_uint64;
293 break;
294 case LTTV_FIELD_LE:
295 se->op = lttv_apply_op_le_uint64;
296 break;
297 case LTTV_FIELD_GT:
298 se->op = lttv_apply_op_gt_uint64;
299 break;
300 case LTTV_FIELD_GE:
301 se->op = lttv_apply_op_ge_uint64;
302 break;
303 default:
304 g_warning("Error encountered in operator assignment");
305 return FALSE;
306 }
307 break;
56e29124 308 /*
7145a073 309 * Ltttime
56e29124 310 */
bb87caa7 311 case LTTV_FILTER_STATE_CT:
312 case LTTV_FILTER_STATE_IT:
313 case LTTV_FILTER_EVENT_TIME:
314 case LTTV_FILTER_EVENT_TSC:
315 switch(op) {
316 case LTTV_FIELD_EQ:
7145a073 317 se->op = lttv_apply_op_eq_ltttime;
bb87caa7 318 break;
319 case LTTV_FIELD_NE:
7145a073 320 se->op = lttv_apply_op_ne_ltttime;
bb87caa7 321 break;
322 case LTTV_FIELD_LT:
7145a073 323 se->op = lttv_apply_op_lt_ltttime;
bb87caa7 324 break;
325 case LTTV_FIELD_LE:
7145a073 326 se->op = lttv_apply_op_le_ltttime;
bb87caa7 327 break;
328 case LTTV_FIELD_GT:
7145a073 329 se->op = lttv_apply_op_gt_ltttime;
bb87caa7 330 break;
331 case LTTV_FIELD_GE:
7145a073 332 se->op = lttv_apply_op_ge_ltttime;
bb87caa7 333 break;
334 default:
335 g_warning("Error encountered in operator assignment");
336 return FALSE;
337 }
338 break;
339 default:
9ab5ebd7 340 g_warning("Error encountered in operator assignation ! Field type:%i",se->field);
bb87caa7 341 return FALSE;
342 }
aa4600f3 343
344 return TRUE;
bb87caa7 345
346}
347
9ab5ebd7 348/**
349 * @fn void lttv_simple_expression_assign_value(LttvSimpleExpression*,char*)
350 *
351 * Assign the value field to the current LttvSimpleExpression
352 * @param se pointer to the current LttvSimpleExpression
353 * @param value string value for simple expression
354 */
355gboolean lttv_simple_expression_assign_value(LttvSimpleExpression* se, char* value) {
356
c684db06 357// g_print("se->value:%s\n",value);
46c40a93 358 unsigned i;
359 gboolean is_double = FALSE;
c6832b57 360 LttTime t = ltt_time_zero;
361 GString* v;
362 GQuark quark;
9ab5ebd7 363
364 switch(se->field) {
365 /*
c6832b57 366 * string --> g_quark
9ab5ebd7 367 */
368 case LTTV_FILTER_TRACE_NAME:
369 case LTTV_FILTER_TRACEFILE_NAME:
370 case LTTV_FILTER_STATE_P_NAME:
371 case LTTV_FILTER_EVENT_NAME:
c6832b57 372// se->value.v_string = value;
852f16bb 373 se->value.v_uint32 = g_quark_to_string(value);
c6832b57 374 g_free(value);
9ab5ebd7 375 break;
376 /*
377 * integer
378 */
379 case LTTV_FILTER_STATE_PID:
380 case LTTV_FILTER_STATE_PPID:
381 case LTTV_FILTER_STATE_EX_MODE:
382 case LTTV_FILTER_STATE_EX_SUBMODE:
383 case LTTV_FILTER_STATE_P_STATUS:
384 se->value.v_uint64 = atoi(value);
385 g_free(value);
386 break;
387 /*
7145a073 388 * LttTime
9ab5ebd7 389 */
390 case LTTV_FILTER_STATE_CT:
391 case LTTV_FILTER_STATE_IT:
392 case LTTV_FILTER_EVENT_TIME:
393 case LTTV_FILTER_EVENT_TSC:
7145a073 394 //se->value.v_double = atof(value);
46c40a93 395 /*
396 * parsing logic could be optimised,
397 * but as for now, simpler this way
398 */
399 v = g_string_new("");
400 for(i=0;i<strlen(value);i++) {
401 if(value[i] == '.') {
402 /* cannot specify number with more than one '.' */
403 if(is_double) return FALSE;
404 else is_double = TRUE;
405 t.tv_sec = atoi(v);
406 g_string_free(v,TRUE);
407 v = g_string_new("");
408 } else g_string_append_c(v,value[i]);
409 }
410 /* number can be integer or double */
411 if(is_double) t.tv_nsec = atoi(v);
c6832b57 412 else t.tv_sec = atoi(v);
413
46c40a93 414 g_string_free(v,TRUE);
415
416 se->value.v_ltttime = t;
9ab5ebd7 417 g_free(value);
418 break;
419 default:
420 g_warning("Error encountered in value assignation ! Field type = %i",se->field);
c6832b57 421 g_free(value);
9ab5ebd7 422 return FALSE;
423 }
424
425 return TRUE;
426
427}
428
31452f49 429/**
56e29124 430 * @fn void lttv_simple_expression_destroy(LttvSimpleExpression*)
431 *
9ab5ebd7 432 * Disallocate memory for the current
56e29124 433 * simple expression
434 * @param se pointer to the current LttvSimpleExpression
435 */
436void
437lttv_simple_expression_destroy(LttvSimpleExpression* se) {
438
9ab5ebd7 439 // g_free(se->value);
f3020899 440 switch(se->field) {
441 case LTTV_FILTER_TRACE_NAME:
442 case LTTV_FILTER_TRACEFILE_NAME:
443 case LTTV_FILTER_STATE_P_NAME:
444 case LTTV_FILTER_EVENT_NAME:
445 g_free(se->value.v_string);
446 break;
447 }
56e29124 448 g_free(se);
449
450}
451
452/**
453 * @fn gint lttv_struct_type(gint)
454 *
80f9611a 455 * Finds the structure type depending
456 * on the fields in parameters
457 * @params ft Field of the current structure
458 * @return LttvStructType enum or -1 for error
84a333d6 459 */
80f9611a 460gint
461lttv_struct_type(gint ft) {
5f185a2b 462
80f9611a 463 switch(ft) {
464 case LTTV_FILTER_TRACE_NAME:
465 return LTTV_FILTER_TRACE;
466 break;
467 case LTTV_FILTER_TRACEFILE_NAME:
468 return LTTV_FILTER_TRACEFILE;
469 break;
470 case LTTV_FILTER_STATE_PID:
471 case LTTV_FILTER_STATE_PPID:
472 case LTTV_FILTER_STATE_CT:
473 case LTTV_FILTER_STATE_IT:
474 case LTTV_FILTER_STATE_P_NAME:
475 case LTTV_FILTER_STATE_EX_MODE:
476 case LTTV_FILTER_STATE_EX_SUBMODE:
477 case LTTV_FILTER_STATE_P_STATUS:
478 case LTTV_FILTER_STATE_CPU:
479 return LTTV_FILTER_STATE;
480 break;
481 case LTTV_FILTER_EVENT_NAME:
482 case LTTV_FILTER_EVENT_CATEGORY:
483 case LTTV_FILTER_EVENT_TIME:
484 case LTTV_FILTER_EVENT_TSC:
485 case LTTV_FILTER_EVENT_FIELD:
486 return LTTV_FILTER_EVENT;
487 break;
488 default:
489 return -1;
490 }
84a333d6 491}
492
150f0d33 493/**
4d9ff942 494 * @fn gboolean lttv_apply_op_eq_uint64(const gpointer,LttvFieldValue)
56e29124 495 *
150f0d33 496 * Applies the 'equal' operator to the
47aa6e58 497 * specified structure and value
498 * @param v1 left member of comparison
499 * @param v2 right member of comparison
150f0d33 500 * @return success/failure of operation
501 */
4d9ff942 502gboolean lttv_apply_op_eq_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 503
504 guint64* r = (guint64*) v1;
9ab5ebd7 505 return (*r == v2.v_uint64);
83aa92fc 506
507}
150f0d33 508
5b729fcf 509/**
4d9ff942 510 * @fn gboolean lttv_apply_op_eq_uint32(const gpointer,LttvFieldValue)
56e29124 511 *
5b729fcf 512 * Applies the 'equal' operator to the
47aa6e58 513 * specified structure and value
514 * @param v1 left member of comparison
515 * @param v2 right member of comparison
5b729fcf 516 * @return success/failure of operation
517 */
4d9ff942 518gboolean lttv_apply_op_eq_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 519 guint32* r = (guint32*) v1;
9ab5ebd7 520 return (*r == v2.v_uint32);
83aa92fc 521}
5b729fcf 522
523/**
4d9ff942 524 * @fn gboolean lttv_apply_op_eq_uint16(const gpointer,LttvFieldValue)
56e29124 525 *
5b729fcf 526 * Applies the 'equal' operator to the
47aa6e58 527 * specified structure and value
528 * @param v1 left member of comparison
529 * @param v2 right member of comparison
5b729fcf 530 * @return success/failure of operation
531 */
4d9ff942 532gboolean lttv_apply_op_eq_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 533 guint16* r = (guint16*) v1;
9ab5ebd7 534 return (*r == v2.v_uint16);
83aa92fc 535}
5b729fcf 536
537/**
4d9ff942 538 * @fn gboolean lttv_apply_op_eq_double(const gpointer,LttvFieldValue)
56e29124 539 *
5b729fcf 540 * Applies the 'equal' operator to the
47aa6e58 541 * specified structure and value
542 * @param v1 left member of comparison
543 * @param v2 right member of comparison
5b729fcf 544 * @return success/failure of operation
545 */
4d9ff942 546gboolean lttv_apply_op_eq_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 547 double* r = (double*) v1;
9ab5ebd7 548 return (*r == v2.v_double);
83aa92fc 549}
5b729fcf 550
551/**
4d9ff942 552 * @fn gboolean lttv_apply_op_eq_string(const gpointer,LttvFieldValue)
56e29124 553 *
5b729fcf 554 * Applies the 'equal' operator to the
47aa6e58 555 * specified structure and value
556 * @param v1 left member of comparison
557 * @param v2 right member of comparison
5b729fcf 558 * @return success/failure of operation
559 */
4d9ff942 560gboolean lttv_apply_op_eq_string(const gpointer v1, LttvFieldValue v2) {
83aa92fc 561 char* r = (char*) v1;
9ab5ebd7 562 return (!g_strcasecmp(r,v2.v_string));
83aa92fc 563}
150f0d33 564
c6832b57 565/**
566 * @fn gboolean lttv_apply_op_eq_quark(const gpointer,LttvFieldValue)
567 *
568 * Applies the 'equal' operator to the
569 * specified structure and value
570 * @param v1 left member of comparison
571 * @param v2 right member of comparison
572 * @return success/failure of operation
573 */
574gboolean lttv_apply_op_eq_quark(const gpointer v1, LttvFieldValue v2) {
575 GQuark* r = (GQuark*) v1;
576 g_print("v1:%i v2:%i\n",*r,v2.v_uint32);
577 return (*r == v2.v_uint32);
578}
579
7145a073 580/**
4d9ff942 581 * @fn gboolean lttv_apply_op_eq_ltttime(const gpointer,LttvFieldValue)
7145a073 582 *
583 * Applies the 'equal' operator to the
584 * specified structure and value
585 * @param v1 left member of comparison
586 * @param v2 right member of comparison
587 * @return success/failure of operation
588 */
4d9ff942 589gboolean lttv_apply_op_eq_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 590 LttTime* r = (LttTime*) v1;
c6832b57 591// return ((r->tv_sec == v2.v_ltttime.tv_sec) && (r->tv_nsec == v2.v_ltttime.tv_nsec));
592 return ltt_time_compare(*r, v2.v_ltttime)==0?1:0;
7145a073 593}
594
595
150f0d33 596/**
4d9ff942 597 * @fn gboolean lttv_apply_op_ne_uint64(const gpointer,LttvFieldValue)
56e29124 598 *
150f0d33 599 * Applies the 'not equal' operator to the
47aa6e58 600 * specified structure and value
601 * @param v1 left member of comparison
602 * @param v2 right member of comparison
150f0d33 603 * @return success/failure of operation
604 */
4d9ff942 605gboolean lttv_apply_op_ne_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 606 guint64* r = (guint64*) v1;
9ab5ebd7 607 return (*r != v2.v_uint64);
83aa92fc 608}
150f0d33 609
5b729fcf 610/**
4d9ff942 611 * @fn gboolean lttv_apply_op_ne_uint32(const gpointer,LttvFieldValue)
56e29124 612 *
5b729fcf 613 * Applies the 'not equal' operator to the
47aa6e58 614 * specified structure and value
615 * @param v1 left member of comparison
616 * @param v2 right member of comparison
5b729fcf 617 * @return success/failure of operation
618 */
4d9ff942 619gboolean lttv_apply_op_ne_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 620 guint32* r = (guint32*) v1;
9ab5ebd7 621 return (*r != v2.v_uint32);
83aa92fc 622}
5b729fcf 623
624/**
4d9ff942 625 * @fn gboolean lttv_apply_op_ne_uint16(const gpointer,LttvFieldValue)
56e29124 626 *
5b729fcf 627 * Applies the 'not equal' operator to the
47aa6e58 628 * specified structure and value
629 * @param v1 left member of comparison
630 * @param v2 right member of comparison
5b729fcf 631 * @return success/failure of operation
632 */
4d9ff942 633gboolean lttv_apply_op_ne_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 634 guint16* r = (guint16*) v1;
9ab5ebd7 635 return (*r != v2.v_uint16);
83aa92fc 636}
5b729fcf 637
638/**
4d9ff942 639 * @fn gboolean lttv_apply_op_ne_double(const gpointer,LttvFieldValue)
56e29124 640 *
5b729fcf 641 * Applies the 'not equal' operator to the
47aa6e58 642 * specified structure and value
643 * @param v1 left member of comparison
644 * @param v2 right member of comparison
5b729fcf 645 * @return success/failure of operation
646 */
4d9ff942 647gboolean lttv_apply_op_ne_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 648 double* r = (double*) v1;
9ab5ebd7 649 return (*r != v2.v_double);
83aa92fc 650}
5b729fcf 651
652/**
4d9ff942 653 * @fn gboolean lttv_apply_op_ne_string(const gpointer,LttvFieldValue)
56e29124 654 *
5b729fcf 655 * Applies the 'not equal' operator to the
47aa6e58 656 * specified structure and value
657 * @param v1 left member of comparison
658 * @param v2 right member of comparison
5b729fcf 659 * @return success/failure of operation
660 */
4d9ff942 661gboolean lttv_apply_op_ne_string(const gpointer v1, LttvFieldValue v2) {
83aa92fc 662 char* r = (char*) v1;
9ab5ebd7 663 return (g_strcasecmp(r,v2.v_string));
83aa92fc 664}
150f0d33 665
c6832b57 666/**
667 * @fn gboolean lttv_apply_op_ne_quark(const gpointer,LttvFieldValue)
668 *
669 * Applies the 'not equal' operator to the
670 * specified structure and value
671 * @param v1 left member of comparison
672 * @param v2 right member of comparison
673 * @return success/failure of operation
674 */
675gboolean lttv_apply_op_ne_quark(const gpointer v1, LttvFieldValue v2) {
676 GQuark* r = (GQuark*) v1;
677 return (*r != v2.v_uint32);
678}
679
680
7145a073 681/**
4d9ff942 682 * @fn gboolean lttv_apply_op_ne_ltttime(const gpointer,LttvFieldValue)
7145a073 683 *
684 * Applies the 'not equal' operator to the
685 * specified structure and value
686 * @param v1 left member of comparison
687 * @param v2 right member of comparison
688 * @return success/failure of operation
689 */
4d9ff942 690gboolean lttv_apply_op_ne_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 691 LttTime* r = (LttTime*) v1;
46c40a93 692 return ltt_time_compare(*r, v2.v_ltttime)!=0?1:0;
7145a073 693}
694
695
150f0d33 696/**
4d9ff942 697 * @fn gboolean lttv_apply_op_lt_uint64(const gpointer,LttvFieldValue)
56e29124 698 *
150f0d33 699 * Applies the 'lower than' operator to the
47aa6e58 700 * specified structure and value
701 * @param v1 left member of comparison
702 * @param v2 right member of comparison
150f0d33 703 * @return success/failure of operation
704 */
4d9ff942 705gboolean lttv_apply_op_lt_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 706 guint64* r = (guint64*) v1;
9ab5ebd7 707 return (*r < v2.v_uint64);
83aa92fc 708}
150f0d33 709
5b729fcf 710/**
4d9ff942 711 * @fn gboolean lttv_apply_op_lt_uint32(const gpointer,LttvFieldValue)
56e29124 712 *
5b729fcf 713 * Applies the 'lower than' operator to the
47aa6e58 714 * specified structure and value
715 * @param v1 left member of comparison
716 * @param v2 right member of comparison
5b729fcf 717 * @return success/failure of operation
718 */
4d9ff942 719gboolean lttv_apply_op_lt_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 720 guint32* r = (guint32*) v1;
9ab5ebd7 721 return (*r < v2.v_uint32);
83aa92fc 722}
5b729fcf 723
724/**
4d9ff942 725 * @fn gboolean lttv_apply_op_lt_uint16(const gpointer,LttvFieldValue)
56e29124 726 *
5b729fcf 727 * Applies the 'lower than' operator to the
47aa6e58 728 * specified structure and value
729 * @param v1 left member of comparison
730 * @param v2 right member of comparison
5b729fcf 731 * @return success/failure of operation
732 */
4d9ff942 733gboolean lttv_apply_op_lt_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 734 guint16* r = (guint16*) v1;
9ab5ebd7 735 return (*r < v2.v_uint16);
83aa92fc 736}
5b729fcf 737
738/**
4d9ff942 739 * @fn gboolean lttv_apply_op_lt_double(const gpointer,LttvFieldValue)
56e29124 740 *
5b729fcf 741 * Applies the 'lower than' operator to the
47aa6e58 742 * specified structure and value
743 * @param v1 left member of comparison
744 * @param v2 right member of comparison
5b729fcf 745 * @return success/failure of operation
746 */
4d9ff942 747gboolean lttv_apply_op_lt_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 748 double* r = (double*) v1;
9ab5ebd7 749 return (*r < v2.v_double);
83aa92fc 750}
5b729fcf 751
7145a073 752/**
4d9ff942 753 * @fn gboolean lttv_apply_op_lt_ltttime(const gpointer,LttvFieldValue)
7145a073 754 *
755 * Applies the 'lower than' operator to the
756 * specified structure and value
757 * @param v1 left member of comparison
758 * @param v2 right member of comparison
759 * @return success/failure of operation
760 */
4d9ff942 761gboolean lttv_apply_op_lt_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 762 LttTime* r = (LttTime*) v1;
c6832b57 763// return ((r->tv_sec < v2.v_ltttime.tv_sec) || ((r->tv_sec == v2.v_ltttime.tv_sec) && (r->tv_nsec < v2.v_ltttime.tv_nsec)));
764 return ltt_time_compare(*r, v2.v_ltttime)==-1?1:0;
7145a073 765}
766
767
5b729fcf 768/**
4d9ff942 769 * @fn gboolean lttv_apply_op_le_uint64(const gpointer,LttvFieldValue)
56e29124 770 *
771 * Applies the 'lower or equal' operator to the
47aa6e58 772 * specified structure and value
773 * @param v1 left member of comparison
774 * @param v2 right member of comparison
5b729fcf 775 * @return success/failure of operation
776 */
4d9ff942 777gboolean lttv_apply_op_le_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 778 guint64* r = (guint64*) v1;
9ab5ebd7 779 return (*r <= v2.v_uint64);
83aa92fc 780}
150f0d33 781
782/**
4d9ff942 783 * @fn gboolean lttv_apply_op_le_uint32(const gpointer,LttvFieldValue)
56e29124 784 *
150f0d33 785 * Applies the 'lower or equal' operator to the
47aa6e58 786 * specified structure and value
787 * @param v1 left member of comparison
788 * @param v2 right member of comparison
150f0d33 789 * @return success/failure of operation
790 */
4d9ff942 791gboolean lttv_apply_op_le_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 792 guint32* r = (guint32*) v1;
9ab5ebd7 793 return (*r <= v2.v_uint32);
83aa92fc 794}
150f0d33 795
5b729fcf 796/**
4d9ff942 797 * @fn gboolean lttv_apply_op_le_uint16(const gpointer,LttvFieldValue)
56e29124 798 *
5b729fcf 799 * Applies the 'lower or equal' operator to the
47aa6e58 800 * specified structure and value
801 * @param v1 left member of comparison
802 * @param v2 right member of comparison
5b729fcf 803 * @return success/failure of operation
804 */
4d9ff942 805gboolean lttv_apply_op_le_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 806 guint16* r = (guint16*) v1;
9ab5ebd7 807 return (*r <= v2.v_uint16);
83aa92fc 808}
5b729fcf 809
810/**
4d9ff942 811 * @fn gboolean lttv_apply_op_le_double(const gpointer,LttvFieldValue)
56e29124 812 *
5b729fcf 813 * Applies the 'lower or equal' operator to the
47aa6e58 814 * specified structure and value
815 * @param v1 left member of comparison
816 * @param v2 right member of comparison
5b729fcf 817 * @return success/failure of operation
818 */
4d9ff942 819gboolean lttv_apply_op_le_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 820 double* r = (double*) v1;
9ab5ebd7 821 return (*r <= v2.v_double);
83aa92fc 822}
5b729fcf 823
7145a073 824/**
4d9ff942 825 * @fn gboolean lttv_apply_op_le_ltttime(const gpointer,LttvFieldValue)
7145a073 826 *
827 * Applies the 'lower or equal' operator to the
828 * specified structure and value
829 * @param v1 left member of comparison
830 * @param v2 right member of comparison
831 * @return success/failure of operation
832 */
4d9ff942 833gboolean lttv_apply_op_le_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 834 LttTime* r = (LttTime*) v1;
c6832b57 835// return ((r->tv_sec < v2.v_ltttime.tv_sec) || ((r->tv_sec == v2.v_ltttime.tv_sec) && (r->tv_nsec <= v2.v_ltttime.tv_nsec)));
836 return ltt_time_compare(*r, v2.v_ltttime)<1?1:0;
7145a073 837}
838
839
5b729fcf 840/**
4d9ff942 841 * @fn gboolean lttv_apply_op_gt_uint64(const gpointer,LttvFieldValue)
56e29124 842 *
83aa92fc 843 * Applies the 'greater than' operator to the
47aa6e58 844 * specified structure and value
845 * @param v1 left member of comparison
846 * @param v2 right member of comparison
5b729fcf 847 * @return success/failure of operation
848 */
4d9ff942 849gboolean lttv_apply_op_gt_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 850 guint64* r = (guint64*) v1;
9ab5ebd7 851 return (*r > v2.v_uint64);
83aa92fc 852}
150f0d33 853
854/**
4d9ff942 855 * @fn gboolean lttv_apply_op_gt_uint32(const gpointer,LttvFieldValue)
56e29124 856 *
150f0d33 857 * Applies the 'greater than' operator to the
47aa6e58 858 * specified structure and value
859 * @param v1 left member of comparison
860 * @param v2 right member of comparison
150f0d33 861 * @return success/failure of operation
862 */
4d9ff942 863gboolean lttv_apply_op_gt_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 864 guint32* r = (guint32*) v1;
9ab5ebd7 865 return (*r > v2.v_uint32);
83aa92fc 866}
150f0d33 867
5b729fcf 868/**
4d9ff942 869 * @fn gboolean lttv_apply_op_gt_uint16(const gpointer,LttvFieldValue)
56e29124 870 *
5b729fcf 871 * Applies the 'greater than' operator to the
47aa6e58 872 * specified structure and value
873 * @param v1 left member of comparison
874 * @param v2 right member of comparison
5b729fcf 875 * @return success/failure of operation
876 */
4d9ff942 877gboolean lttv_apply_op_gt_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 878 guint16* r = (guint16*) v1;
9ab5ebd7 879 return (*r > v2.v_uint16);
83aa92fc 880}
5b729fcf 881
882/**
4d9ff942 883 * @fn gboolean lttv_apply_op_gt_double(const gpointer,LttvFieldValue)
56e29124 884 *
5b729fcf 885 * Applies the 'greater than' operator to the
47aa6e58 886 * specified structure and value
887 * @param v1 left member of comparison
888 * @param v2 right member of comparison
5b729fcf 889 * @return success/failure of operation
890 */
4d9ff942 891gboolean lttv_apply_op_gt_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 892 double* r = (double*) v1;
9ab5ebd7 893 return (*r > v2.v_double);
83aa92fc 894}
5b729fcf 895
7145a073 896/**
4d9ff942 897 * @fn gboolean lttv_apply_op_gt_ltttime(const gpointer,LttvFieldValue)
7145a073 898 *
899 * Applies the 'greater than' operator to the
900 * specified structure and value
901 * @param v1 left member of comparison
902 * @param v2 right member of comparison
903 * @return success/failure of operation
904 */
4d9ff942 905gboolean lttv_apply_op_gt_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 906 LttTime* r = (LttTime*) v1;
c6832b57 907// return ((r->tv_sec > v2.v_ltttime.tv_sec) || ((r->tv_sec == v2.v_ltttime.tv_sec) && (r->tv_nsec > v2.v_ltttime.tv_nsec)));
908 return ltt_time_compare(*r, v2.v_ltttime)==1?1:0;
7145a073 909}
910
911
5b729fcf 912/**
4d9ff942 913 * @fn gboolean lttv_apply_op_ge_uint64(const gpointer,LttvFieldValue)
56e29124 914 *
83aa92fc 915 * Applies the 'greater or equal' operator to the
47aa6e58 916 * specified structure and value
917 * @param v1 left member of comparison
918 * @param v2 right member of comparison
5b729fcf 919 * @return success/failure of operation
920 */
4d9ff942 921gboolean lttv_apply_op_ge_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 922 guint64* r = (guint64*) v1;
9ab5ebd7 923 return (*r >= v2.v_uint64);
83aa92fc 924}
150f0d33 925
926/**
4d9ff942 927 * @fn gboolean lttv_apply_op_ge_uint32(const gpointer,LttvFieldValue)
56e29124 928 *
150f0d33 929 * Applies the 'greater or equal' operator to the
47aa6e58 930 * specified structure and value
931 * @param v1 left member of comparison
932 * @param v2 right member of comparison
150f0d33 933 * @return success/failure of operation
934 */
4d9ff942 935gboolean lttv_apply_op_ge_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 936 guint32* r = (guint32*) v1;
9ab5ebd7 937 return (*r >= v2.v_uint32);
83aa92fc 938}
150f0d33 939
5b729fcf 940/**
4d9ff942 941 * @fn gboolean lttv_apply_op_ge_uint16(const gpointer,LttvFieldValue)
56e29124 942 *
5b729fcf 943 * Applies the 'greater or equal' operator to the
47aa6e58 944 * specified structure and value
945 * @param v1 left member of comparison
946 * @param v2 right member of comparison
5b729fcf 947 * @return success/failure of operation
948 */
4d9ff942 949gboolean lttv_apply_op_ge_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 950 guint16* r = (guint16*) v1;
9ab5ebd7 951 return (*r >= v2.v_uint16);
83aa92fc 952}
150f0d33 953
5b729fcf 954/**
4d9ff942 955 * @fn gboolean lttv_apply_op_ge_double(const gpointer,LttvFieldValue)
56e29124 956 *
5b729fcf 957 * Applies the 'greater or equal' operator to the
47aa6e58 958 * specified structure and value
959 * @param v1 left member of comparison
960 * @param v2 right member of comparison
5b729fcf 961 * @return success/failure of operation
962 */
4d9ff942 963gboolean lttv_apply_op_ge_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 964 double* r = (double*) v1;
9ab5ebd7 965 return (*r >= v2.v_double);
83aa92fc 966}
150f0d33 967
7145a073 968/**
4d9ff942 969 * @fn gboolean lttv_apply_op_ge_ltttime(const gpointer,LttvFieldValue)
7145a073 970 *
971 * Applies the 'greater or equal' operator to the
972 * specified structure and value
973 * @param v1 left member of comparison
974 * @param v2 right member of comparison
975 * @return success/failure of operation
976 */
4d9ff942 977gboolean lttv_apply_op_ge_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 978 LttTime* r = (LttTime*) v1;
c6832b57 979// return ((r->tv_sec > v2.v_ltttime.tv_sec) || ((r->tv_sec == v2.v_ltttime.tv_sec) && (r->tv_nsec >= v2.v_ltttime.tv_nsec)));
980 return ltt_time_compare(*r, v2.v_ltttime)>-1?1:0;
7145a073 981}
982
983
150f0d33 984
985/**
56e29124 986 * @fn LttvFilterTree* lttv_filter_tree_clone(LttvFilterTree*)
987 *
988 * Makes a copy of the current filter tree
989 * @param tree pointer to the current tree
990 * @return new copy of the filter tree
150f0d33 991 */
992LttvFilterTree*
4d9ff942 993lttv_filter_tree_clone(const LttvFilterTree* tree) {
150f0d33 994
8c89f5a8 995 LttvFilterTree* newtree = lttv_filter_tree_new();
150f0d33 996
8c89f5a8 997 newtree->node = tree->node;
998
999 newtree->left = tree->left;
1000 if(newtree->left == LTTV_TREE_NODE) {
1001 newtree->l_child.t = lttv_filter_tree_clone(tree->l_child.t);
1002 } else if(newtree->left == LTTV_TREE_LEAF) {
1003 newtree->l_child.leaf = lttv_simple_expression_new();
1004 newtree->l_child.leaf->field = tree->l_child.leaf->field;
1005 newtree->l_child.leaf->offset = tree->l_child.leaf->offset;
1006 newtree->l_child.leaf->op = tree->l_child.leaf->op;
9ab5ebd7 1007 /* FIXME: special case for string copy ! */
1008 newtree->l_child.leaf->value = tree->l_child.leaf->value;
8c89f5a8 1009 }
1010
1011 newtree->right = tree->right;
1012 if(newtree->right == LTTV_TREE_NODE) {
1013 newtree->r_child.t = lttv_filter_tree_clone(tree->r_child.t);
1014 } else if(newtree->right == LTTV_TREE_LEAF) {
1015 newtree->r_child.leaf = lttv_simple_expression_new();
1016 newtree->r_child.leaf->field = tree->r_child.leaf->field;
1017 newtree->r_child.leaf->offset = tree->r_child.leaf->offset;
1018 newtree->r_child.leaf->op = tree->r_child.leaf->op;
9ab5ebd7 1019 newtree->r_child.leaf->value = tree->r_child.leaf->value;
8c89f5a8 1020 }
1021
1022 return newtree;
1023
150f0d33 1024}
1025
1026/**
56e29124 1027 * @fn LttvFilter* lttv_filter_clone(LttvFilter*)
1028 *
1029 * Makes a copy of the current filter
1030 * @param filter pointer to the current filter
1031 * @return new copy of the filter
150f0d33 1032 */
1033LttvFilter*
4d9ff942 1034lttv_filter_clone(const LttvFilter* filter) {
150f0d33 1035
1036 LttvFilter* newfilter = g_new(LttvFilter,1);
1037
1038 // newfilter->expression = g_new(char,1)
1039 strcpy(newfilter->expression,filter->expression);
1040
1041 newfilter->head = lttv_filter_tree_clone(filter->head);
1042
1043 return newfilter;
1044
1045}
1046
1047
84a333d6 1048/**
56e29124 1049 * @fn LttvFilter* lttv_filter_new()
1050 *
84a333d6 1051 * Creates a new lttv_filter
31452f49 1052 * @param expression filtering options string
1053 * @param t pointer to the current LttvTrace
84a333d6 1054 * @return the current lttv_filter or NULL if error
31452f49 1055 */
2ea36caf 1056LttvFilter*
5f185a2b 1057lttv_filter_new() {
a4c292d4 1058
5f185a2b 1059 LttvFilter* filter = g_new(LttvFilter,1);
1060 filter->expression = NULL;
1061 filter->head = NULL;
1062
1063}
a4c292d4 1064
8c89f5a8 1065/**
56e29124 1066 * @fn gboolean lttv_filter_update(LttvFilter*)
1067 *
8c89f5a8 1068 * Updates the current LttvFilter by building
1069 * its tree based upon the expression string
1070 * @param filter pointer to the current LttvFilter
1071 * @return Failure/Success of operation
1072 */
5f185a2b 1073gboolean
1074lttv_filter_update(LttvFilter* filter) {
1075
4d9ff942 1076// g_print("filter::lttv_filter_new()\n"); /* debug */
5f185a2b 1077
1078 if(filter->expression == NULL) return FALSE;
1079
f3020899 1080 int
a4c292d4 1081 i,
56e29124 1082 p_nesting=0; /* parenthesis nesting value */
1601b365 1083
1084 /* trees */
5b729fcf 1085 LttvFilterTree
1601b365 1086 *tree = lttv_filter_tree_new(), /* main tree */
1087 *subtree = NULL, /* buffer for subtrees */
1088 *t1, /* buffer #1 */
1089 *t2; /* buffer #2 */
1090
5f185a2b 1091 /*
1092 * the filter
1093 * If the tree already exists,
1094 * destroy it and build a new one
1095 */
1096 if(filter->head != NULL) lttv_filter_tree_destroy(filter->head);
f3020899 1097 filter->head = NULL; /* will be assigned at the end */
5f185a2b 1098
1601b365 1099 /*
1100 * Tree Stack
f4e9dd16 1101 * each element of the list
1102 * is a sub tree created
1103 * by the use of parenthesis in the
1104 * global expression. The final tree
1601b365 1105 * will be the one left at the root of
f4e9dd16 1106 * the list
1107 */
18d1226f 1108 GPtrArray *tree_stack = g_ptr_array_new();
1109 g_ptr_array_add( tree_stack,(gpointer) tree );
f4e9dd16 1110
a4c292d4 1111 /* temporary values */
0769c82f 1112 GString *a_field_component = g_string_new("");
56e29124 1113 GPtrArray *a_field_path = g_ptr_array_new();
1114
1115 /* simple expression buffer */
389ba50e 1116 LttvSimpleExpression* a_simple_expression = lttv_simple_expression_new();
0769c82f 1117
a4c292d4 1118 /*
1119 * Parse entire expression and construct
1120 * the binary tree. There are two steps
1121 * in browsing that string
f4e9dd16 1122 * 1. finding boolean ops " &,|,^,! " and parenthesis " {,(,[,],),} "
a4c292d4 1123 * 2. finding simple expressions
0769c82f 1124 * - field path ( separated by dots )
a4c292d4 1125 * - op ( >, <, =, >=, <=, !=)
0769c82f 1126 * - value ( integer, string ... )
1127 * To spare computing time, the whole
1128 * string is parsed in this loop for a
1129 * O(n) complexity order.
1601b365 1130 *
18d1226f 1131 * When encountering logical op &,|,^
1132 * 1. parse the last value if any
1133 * 2. create a new tree
1134 * 3. add the expression (simple exp, or exp (subtree)) to the tree
1135 * 4. concatenate this tree with the current tree on top of the stack
1136 * When encountering math ops >,>=,<,<=,=,!=
1137 * 1. add to op to the simple expression
1138 * 2. concatenate last field component to field path
1139 * When encountering concatening ops .
1140 * 1. concatenate last field component to field path
1141 * When encountering opening parenthesis (,{,[
1142 * 1. create a new subtree on top of tree stack
1143 * When encountering closing parenthesis ),},]
1144 * 1. add the expression on right child of the current tree
1145 * 2. the subtree is completed, allocate a new subtree
1146 * 3. pop the tree value from the tree stack
1147 */
1148
5f185a2b 1149 for(i=0;i<strlen(filter->expression);i++) {
1150 // debug
4d9ff942 1151 //g_print("%c ",filter->expression[i]);
1152
5f185a2b 1153 switch(filter->expression[i]) {
a4c292d4 1154 /*
1155 * logical operators
1156 */
1157 case '&': /* and */
aa4600f3 1158
5b729fcf 1159 t1 = (LttvFilterTree*)g_ptr_array_index(tree_stack,tree_stack->len-1);
9ab5ebd7 1160 while(t1->right != LTTV_TREE_IDLE) {
1161 g_assert(t1->right == LTTV_TREE_NODE);
1162 t1 = t1->r_child.t;
1163 }
18d1226f 1164 t2 = lttv_filter_tree_new();
0cdc2470 1165 t2->node = LTTV_LOGICAL_AND;
bb87caa7 1166 if(subtree != NULL) { /* append subtree to current tree */
18d1226f 1167 t2->left = LTTV_TREE_NODE;
1168 t2->l_child.t = subtree;
f4e9dd16 1169 subtree = NULL;
18d1226f 1170 t1->right = LTTV_TREE_NODE;
410c83da 1171 t1->r_child.t = t2;
bb87caa7 1172 } else { /* append a simple expression */
9ab5ebd7 1173 lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE));
18d1226f 1174 a_field_component = g_string_new("");
1175 t2->left = LTTV_TREE_LEAF;
0cdc2470 1176 t2->l_child.leaf = a_simple_expression;
389ba50e 1177 a_simple_expression = lttv_simple_expression_new();
18d1226f 1178 t1->right = LTTV_TREE_NODE;
9ab5ebd7 1179 t1->r_child.t = t2;
f4e9dd16 1180 }
f4e9dd16 1181 break;
aa4600f3 1182
a4c292d4 1183 case '|': /* or */
aa4600f3 1184
e00d6a24 1185 t1 = (LttvFilterTree*)g_ptr_array_index(tree_stack,tree_stack->len-1);
9ab5ebd7 1186 while(t1->right != LTTV_TREE_IDLE) {
1187 g_assert(t1->right == LTTV_TREE_NODE);
1188 t1 = t1->r_child.t;
1189 }
1601b365 1190 t2 = lttv_filter_tree_new();
0cdc2470 1191 t2->node = LTTV_LOGICAL_OR;
bb87caa7 1192 if(subtree != NULL) { /* append subtree to current tree */
1601b365 1193 t2->left = LTTV_TREE_NODE;
1194 t2->l_child.t = subtree;
1195 subtree = NULL;
1196 t1->right = LTTV_TREE_NODE;
1197 t1->r_child.t = t2;
bb87caa7 1198 } else { /* append a simple expression */
9ab5ebd7 1199 lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE));
1601b365 1200 a_field_component = g_string_new("");
1201 t2->left = LTTV_TREE_LEAF;
0cdc2470 1202 t2->l_child.leaf = a_simple_expression;
389ba50e 1203 a_simple_expression = lttv_simple_expression_new();
1601b365 1204 t1->right = LTTV_TREE_NODE;
1205 t1->r_child.t = t2;
1206 }
f4e9dd16 1207 break;
aa4600f3 1208
a4c292d4 1209 case '^': /* xor */
aa4600f3 1210
e00d6a24 1211 t1 = (LttvFilterTree*)g_ptr_array_index(tree_stack,tree_stack->len-1);
9ab5ebd7 1212 while(t1->right != LTTV_TREE_IDLE) {
1213 g_assert(t1->right == LTTV_TREE_NODE);
1214 t1 = t1->r_child.t;
1215 }
1601b365 1216 t2 = lttv_filter_tree_new();
0cdc2470 1217 t2->node = LTTV_LOGICAL_XOR;
bb87caa7 1218 if(subtree != NULL) { /* append subtree to current tree */
1601b365 1219 t2->left = LTTV_TREE_NODE;
1220 t2->l_child.t = subtree;
1221 subtree = NULL;
1222 t1->right = LTTV_TREE_NODE;
1223 t1->r_child.t = t2;
bb87caa7 1224 } else { /* append a simple expression */
9ab5ebd7 1225 lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE));
1601b365 1226 a_field_component = g_string_new("");
1227 t2->left = LTTV_TREE_LEAF;
0cdc2470 1228 t2->l_child.leaf = a_simple_expression;
389ba50e 1229 a_simple_expression = lttv_simple_expression_new();
1601b365 1230 t1->right = LTTV_TREE_NODE;
1231 t1->r_child.t = t2;
1232 }
a4c292d4 1233 break;
aa4600f3 1234
a4c292d4 1235 case '!': /* not, or not equal (math op) */
aa4600f3 1236
5f185a2b 1237 if(filter->expression[i+1] == '=') { /* != */
0cdc2470 1238 g_ptr_array_add( a_field_path,(gpointer) a_field_component );
9ab5ebd7 1239 lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
0cdc2470 1240 a_field_component = g_string_new("");
56e29124 1241 lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_NE);
aa4600f3 1242 i++;
a4c292d4 1243 } else { /* ! */
e00d6a24 1244 t1 = (LttvFilterTree*)g_ptr_array_index(tree_stack,tree_stack->len-1);
9ab5ebd7 1245 while(t1->right != LTTV_TREE_IDLE) {
1246 g_assert(t1->right == LTTV_TREE_NODE);
1247 t1 = t1->r_child.t;
1248 }
1601b365 1249 t2 = lttv_filter_tree_new();
0cdc2470 1250 t2->node = LTTV_LOGICAL_NOT;
1601b365 1251 t1->right = LTTV_TREE_NODE;
1252 t1->r_child.t = t2;
a4c292d4 1253 }
1254 break;
aa4600f3 1255
a4c292d4 1256 case '(': /* start of parenthesis */
91ad3f0a 1257 case '[':
1258 case '{':
aa4600f3 1259
91ad3f0a 1260 p_nesting++; /* incrementing parenthesis nesting value */
1601b365 1261 t1 = lttv_filter_tree_new();
1262 g_ptr_array_add( tree_stack,(gpointer) t1 );
a4c292d4 1263 break;
aa4600f3 1264
a4c292d4 1265 case ')': /* end of parenthesis */
91ad3f0a 1266 case ']':
1267 case '}':
aa4600f3 1268
91ad3f0a 1269 p_nesting--; /* decrementing parenthesis nesting value */
18d1226f 1270 if(p_nesting<0 || tree_stack->len<2) {
f4e9dd16 1271 g_warning("Wrong filtering options, the string\n\"%s\"\n\
5f185a2b 1272 is not valid due to parenthesis incorrect use",filter->expression);
1273 return FALSE;
f4e9dd16 1274 }
56e29124 1275
1276 /* there must at least be the root tree left in the array */
18d1226f 1277 g_assert(tree_stack->len>0);
56e29124 1278
bb87caa7 1279 if(subtree != NULL) { /* append subtree to current tree */
18d1226f 1280 t1 = g_ptr_array_index(tree_stack,tree_stack->len-1);
9ab5ebd7 1281 while(t1->right != LTTV_TREE_IDLE) {
1282 g_assert(t1->right == LTTV_TREE_NODE);
1283 t1 = t1->r_child.t;
18d1226f 1284 }
1285 t1->right = LTTV_TREE_NODE;
1286 t1->r_child.t = subtree;
1287 subtree = g_ptr_array_index(tree_stack,tree_stack->len-1);
1288 g_ptr_array_remove_index(tree_stack,tree_stack->len-1);
bb87caa7 1289 } else { /* assign subtree as current tree */
9ab5ebd7 1290 lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE));
18d1226f 1291 a_field_component = g_string_new("");
1292 t1 = g_ptr_array_index(tree_stack,tree_stack->len-1);
9ab5ebd7 1293 while(t1->right != LTTV_TREE_IDLE) {
9ab5ebd7 1294 g_assert(t1->right == LTTV_TREE_NODE);
1295 g_assert(t1->r_child.t != NULL);
1296 t1 = t1->r_child.t;
1297 }
18d1226f 1298 t1->right = LTTV_TREE_LEAF;
0cdc2470 1299 t1->r_child.leaf = a_simple_expression;
389ba50e 1300 a_simple_expression = lttv_simple_expression_new();
9ab5ebd7 1301 subtree = g_ptr_array_remove_index(tree_stack,tree_stack->len-1);
18d1226f 1302 }
a4c292d4 1303 break;
1304
1305 /*
1306 * mathematic operators
1307 */
1308 case '<': /* lower, lower or equal */
aa4600f3 1309
1310 g_ptr_array_add( a_field_path,(gpointer) a_field_component );
9ab5ebd7 1311 lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
aa4600f3 1312 a_field_component = g_string_new("");
5f185a2b 1313 if(filter->expression[i+1] == '=') { /* <= */
a4c292d4 1314 i++;
56e29124 1315 lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_LE);
1316 } else lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_LT);
aa4600f3 1317 break;
1318
1319 case '>': /* higher, higher or equal */
1320
1321 g_ptr_array_add( a_field_path,(gpointer) a_field_component );
9ab5ebd7 1322 lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
f4e9dd16 1323 a_field_component = g_string_new("");
5f185a2b 1324 if(filter->expression[i+1] == '=') { /* >= */
a4c292d4 1325 i++;
56e29124 1326 lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_GE);
1327 } else lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_GT);
aa4600f3 1328 break;
1329
a4c292d4 1330 case '=': /* equal */
aa4600f3 1331
f4e9dd16 1332 g_ptr_array_add( a_field_path,(gpointer) a_field_component );
9ab5ebd7 1333 lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
f4e9dd16 1334 a_field_component = g_string_new("");
56e29124 1335 lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_EQ);
a4c292d4 1336 break;
aa4600f3 1337
0769c82f 1338 /*
1339 * Field concatening caracter
1340 */
1341 case '.': /* dot */
aa4600f3 1342
bb87caa7 1343 /*
1344 * divide field expression into elements
1345 * in a_field_path array.
4d9ff942 1346 *
1347 * A dot can also be present in double values
bb87caa7 1348 */
8ff6243c 1349 if(a_simple_expression->field == LTTV_FILTER_UNDEFINED) {
bb87caa7 1350 g_ptr_array_add( a_field_path,(gpointer) a_field_component );
1351 a_field_component = g_string_new("");
8ff6243c 1352 }
1353 break;
4d9ff942 1354 case ' ': /* ignore */
1355 case '\n': /* ignore */
0769c82f 1356 break;
a4c292d4 1357 default: /* concatening current string */
73050a5f 1358 g_string_append_c(a_field_component,filter->expression[i]);
a4c292d4 1359 }
1360 }
1601b365 1361
0cdc2470 1362 /*
1363 * Preliminary check to see
1364 * if tree was constructed correctly
1365 */
1366 if( p_nesting>0 ) {
1367 g_warning("Wrong filtering options, the string\n\"%s\"\n\
5f185a2b 1368 is not valid due to parenthesis incorrect use",filter->expression);
1369 return FALSE;
0cdc2470 1370 }
1371
1372 if(tree_stack->len != 1) /* only root tree should remain */
5f185a2b 1373 return FALSE;
1601b365 1374
410c83da 1375 /* processing last element of expression */
410c83da 1376 t1 = g_ptr_array_index(tree_stack,tree_stack->len-1);
9ab5ebd7 1377 while(t1->right != LTTV_TREE_IDLE) {
1378 g_assert(t1->right == LTTV_TREE_NODE);
1379 t1 = t1->r_child.t;
1380 }
410c83da 1381 if(subtree != NULL) { /* add the subtree */
1382 t1->right = LTTV_TREE_NODE;
0cdc2470 1383 t1->r_child.t = subtree;
410c83da 1384 subtree = NULL;
1385 } else { /* add a leaf */
9ab5ebd7 1386 lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE));
56e29124 1387 a_field_component = NULL;
410c83da 1388 t1->right = LTTV_TREE_LEAF;
0cdc2470 1389 t1->r_child.leaf = a_simple_expression;
56e29124 1390 a_simple_expression = NULL;
410c83da 1391 }
1392
56e29124 1393
73050a5f 1394 /* free the pointer array */
1395 g_assert(a_field_path->len == 0);
1396 g_ptr_array_free(a_field_path,TRUE);
56e29124 1397
1398 /* free the tree stack -- but keep the root tree */
f3020899 1399 filter->head = g_ptr_array_remove_index(tree_stack,0);
1400 g_ptr_array_free(tree_stack,TRUE);
1401
56e29124 1402 /* free the field buffer if allocated */
1403 if(a_field_component != NULL) g_string_free(a_field_component,TRUE);
1404
1405 /* free the simple expression buffer if allocated */
1406 if(a_simple_expression != NULL) lttv_simple_expression_destroy(a_simple_expression);
73050a5f 1407
f3020899 1408 g_assert(filter->head != NULL); /* tree should exist */
56e29124 1409 g_assert(subtree == NULL); /* remaining subtree should be included in main tree */
a4c292d4 1410
56e29124 1411 /* debug */
1412 g_print("+++++++++++++++ BEGIN PRINT ++++++++++++++++\n");
1413 lttv_print_tree(filter->head) ;
1414 g_print("+++++++++++++++ END PRINT ++++++++++++++++++\n");
1415
1416 /* success */
5f185a2b 1417 return TRUE;
80f9611a 1418
31452f49 1419}
1420
8c89f5a8 1421/**
56e29124 1422 * @fn void lttv_filter_destroy(LttvFilter*)
1423 *
8c89f5a8 1424 * Destroy the current LttvFilter
1425 * @param filter pointer to the current LttvFilter
1426 */
1da1525d 1427void
2ea36caf 1428lttv_filter_destroy(LttvFilter* filter) {
5f185a2b 1429
1430 g_free(filter->expression);
1431 lttv_filter_tree_destroy(filter->head);
1432 g_free(filter);
1433
1da1525d 1434}
1435
150f0d33 1436/**
8ff6243c 1437 * @fn LttvFilterTree* lttv_filter_tree_new()
56e29124 1438 *
150f0d33 1439 * Assign a new tree for the current expression
1440 * or sub expression
1441 * @return pointer of LttvFilterTree
1442 */
5f185a2b 1443LttvFilterTree*
1444lttv_filter_tree_new() {
150f0d33 1445 LttvFilterTree* tree;
1446
e00d6a24 1447 tree = g_new(LttvFilterTree,1);
150f0d33 1448 tree->node = 0; //g_new(lttv_expression,1);
150f0d33 1449 tree->left = LTTV_TREE_IDLE;
1450 tree->right = LTTV_TREE_IDLE;
f3020899 1451 tree->r_child.t = NULL;
1452 tree->l_child.t = NULL;
1453
150f0d33 1454 return tree;
1455}
1456
80f9611a 1457/**
56e29124 1458 * @fn void lttv_filter_append_expression(LttvFilter*,char*)
1459 *
80f9611a 1460 * Append a new expression to the expression
1461 * defined in the current filter
1462 * @param filter pointer to the current LttvFilter
1463 * @param expression string that must be appended
56e29124 1464 * @return Success/Failure of operation
80f9611a 1465 */
56e29124 1466gboolean lttv_filter_append_expression(LttvFilter* filter, char *expression) {
80f9611a 1467
56e29124 1468 if(expression == NULL) return FALSE;
80f9611a 1469 if(filter == NULL) {
1470 filter = lttv_filter_new();
1471 filter->expression = expression;
1472 } else if(filter->expression == NULL) {
1473 filter->expression = expression;
1474 } else {
1475 filter->expression = g_strconcat(filter->expression,"&",expression);
4d9ff942 1476
1477 /* clear expression */
1478 g_free(expression);
80f9611a 1479 }
1480
56e29124 1481 return lttv_filter_update(filter);
80f9611a 1482
1483}
1484
1485/**
56e29124 1486 * @fn void lttv_filter_clear_expression(LttvFilter*)
1487 *
80f9611a 1488 * Clear the filter expression from the
1489 * current filter and sets its pointer to NULL
1490 * @param filter pointer to the current LttvFilter
1491 */
1492void lttv_filter_clear_expression(LttvFilter* filter) {
1493
1494 if(filter->expression != NULL) {
1495 g_free(filter->expression);
1496 filter->expression = NULL;
1497 }
1498
1499}
1500
150f0d33 1501/**
56e29124 1502 * @fn void lttv_filter_tree_destroy(LttvFilterTree*)
1503 *
150f0d33 1504 * Destroys the tree and his sub-trees
1505 * @param tree Tree which must be destroyed
1506 */
5f185a2b 1507void
1508lttv_filter_tree_destroy(LttvFilterTree* tree) {
56e29124 1509
150f0d33 1510 if(tree == NULL) return;
1511
56e29124 1512 if(tree->left == LTTV_TREE_LEAF) lttv_simple_expression_destroy(tree->l_child.leaf);
150f0d33 1513 else if(tree->left == LTTV_TREE_NODE) lttv_filter_tree_destroy(tree->l_child.t);
1514
56e29124 1515 if(tree->right == LTTV_TREE_LEAF) lttv_simple_expression_destroy(tree->r_child.leaf);
150f0d33 1516 else if(tree->right == LTTV_TREE_NODE) lttv_filter_tree_destroy(tree->r_child.t);
1517
e00d6a24 1518// g_free(tree->node);
150f0d33 1519 g_free(tree);
1520}
1521
84a333d6 1522/**
8ff6243c 1523 * @fn gboolean lttv_filter_tree_parse(LttvFilterTree*,LttEvent,LttTracefile,LttTrace,LttvProcessState)
56e29124 1524 *
80f9611a 1525 * Global parsing function for the current
1526 * LttvFilterTree
1527 * @param tree pointer to the current LttvFilterTree
1528 * @param event current LttEvent, NULL if not used
1529 * @param tracefile current LttTracefile, NULL if not used
1530 * @param trace current LttTrace, NULL if not used
1531 * @param state current LttvProcessState, NULL if not used
4d9ff942 1532 * @param context current LttvTracefileContext, NULL if not used
1533 * @return response of filter
84a333d6 1534 */
31452f49 1535gboolean
80f9611a 1536lttv_filter_tree_parse(
4d9ff942 1537 const LttvFilterTree* t,
1538 const LttEvent* event,
1539 const LttTracefile* tracefile,
1540 const LttTrace* trace,
1541 const LttvProcessState* state,
1542 const LttvTracefileContext* context
80f9611a 1543 /*,...*/)
1544{
0769c82f 1545
80f9611a 1546 /*
1601b365 1547 * Each tree is parsed in inorder.
1548 * This way, it's possible to apply the left filter of the
1549 * tree, then decide whether or not the right branch should
1550 * be parsed depending on the linking logical operator
1551 *
80f9611a 1552 * Each node consists in a
1553 * 1. logical operator
1554 * 2. left child ( node or simple expression )
1555 * 3. right child ( node or simple expression )
1556 *
1557 * When the child is a simple expression, we must
1558 * before all determine if the expression refers to
1559 * a structure which is whithin observation ( not NULL ).
1560 * -If so, the expression is evaluated.
1561 * -If not, the result is set to TRUE since this particular
1562 * operation does not interfere with the lttv structure
1563 *
1564 * The result of each simple expression will directly
1565 * affect the next branch. This way, depending on
1566 * the linking logical operator, the parser will decide
1567 * to explore or not the next branch.
1568 * 1. AND OPERATOR
1569 * -If result of left branch is 0 / FALSE
1570 * then don't explore right branch and return 0;
1571 * -If result of left branch is 1 / TRUE then explore
1572 * 2. OR OPERATOR
1573 * -If result of left branch is 1 / TRUE
1574 * then don't explore right branch and return 1;
1575 * -If result of left branch is 0 / FALSE then explore
1576 * 3. XOR OPERATOR
56e29124 1577 * -Result of left branch will not affect exploration of
80f9611a 1578 * right branch
1601b365 1579 */
73050a5f 1580
80f9611a 1581 gboolean lresult = FALSE, rresult = FALSE;
0769c82f 1582
80f9611a 1583 /*
1584 * Parse left branch
1585 */
4d9ff942 1586 if(t->left == LTTV_TREE_NODE) {
1587 lresult = lttv_filter_tree_parse(t->l_child.t,event,tracefile,trace,state,context);
1588 }
5b729fcf 1589 else if(t->left == LTTV_TREE_LEAF) {
4d9ff942 1590 lresult = lttv_filter_tree_parse_branch(t->l_child.leaf,event,tracefile,trace,state,context);
0cdc2470 1591 }
4d9ff942 1592
80f9611a 1593 /*
1594 * Parse linking operator
1595 * make a cutoff if possible
1596 */
1597 if((t->node & LTTV_LOGICAL_OR) && lresult == TRUE) return TRUE;
1598 if((t->node & LTTV_LOGICAL_AND) && lresult == FALSE) return FALSE;
1599
1600 /*
1601 * Parse right branch
1602 */
4d9ff942 1603 if(t->right == LTTV_TREE_NODE) {
1604 rresult = lttv_filter_tree_parse(t->r_child.t,event,tracefile,trace,state,context);
1605 }
5b729fcf 1606 else if(t->right == LTTV_TREE_LEAF) {
4d9ff942 1607 rresult = lttv_filter_tree_parse_branch(t->r_child.leaf,event,tracefile,trace,state,context);
1608 }
1609
1610 /*
1611 * Apply and return the
1612 * logical link between the
1613 * two operation
1614 */
1615 switch(t->node) {
1616 case LTTV_LOGICAL_OR: return (lresult | rresult);
1617 case LTTV_LOGICAL_AND: return (lresult & rresult);
1618 case LTTV_LOGICAL_NOT: return (!rresult);
1619 case LTTV_LOGICAL_XOR: return (lresult ^ rresult);
1620 case 0: return (rresult);
1621 default:
1622 /*
1623 * This case should never be
1624 * parsed, if so, this subtree
1625 * is cancelled !
1626 */
1627 return TRUE;
1628 }
1629
1630}
1631
1632/**
1633 * @fn gboolean lttv_filter_tree_parse_branch(LttvFilterTree*,LttEvent*,LttTracefile*,LttTrace*,LttvProcessState*,LttvTracefileContext*)
1634 *
1635 * This function parses a particular branch of the tree
1636 * @param tree pointer to the current LttvFilterTree
1637 * @param event current LttEvent, NULL if not used
1638 * @param tracefile current LttTracefile, NULL if not used
1639 * @param trace current LttTrace, NULL if not used
1640 * @param state current LttvProcessState, NULL if not used
1641 * @param context current LttvTracefileContext, NULL if not used
1642 * @return response of filter
1643 */
1644gboolean lttv_filter_tree_parse_branch(
1645 const LttvSimpleExpression* se,
1646 const LttEvent* event,
1647 const LttTracefile* tracefile,
1648 const LttTrace* trace,
1649 const LttvProcessState* state,
1650 const LttvTracefileContext* context) {
1651
9ab5ebd7 1652 LttvFieldValue v;
4d9ff942 1653 v = se->value;
1654 switch(se->field) {
80f9611a 1655 case LTTV_FILTER_TRACE_NAME:
4d9ff942 1656 if(trace == NULL) return TRUE;
c6832b57 1657 else {
852f16bb 1658 GQuark quark = g_quark_to_string(ltt_trace_name(trace));
c6832b57 1659 return se->op((gpointer)&quark,v);
1660 }
80f9611a 1661 break;
1662 case LTTV_FILTER_TRACEFILE_NAME:
4d9ff942 1663 if(tracefile == NULL) return TRUE;
c6832b57 1664 else {
852f16bb 1665 GQuark quark = g_quark_to_string(ltt_tracefile_name(tracefile));
c6832b57 1666 return se->op((gpointer)&quark,v);
1667 }
80f9611a 1668 break;
1669 case LTTV_FILTER_STATE_PID:
4d9ff942 1670 if(state == NULL) return TRUE;
1671 else return se->op((gpointer)&state->pid,v);
80f9611a 1672 break;
1673 case LTTV_FILTER_STATE_PPID:
4d9ff942 1674 if(state == NULL) return TRUE;
1675 else return se->op((gpointer)&state->ppid,v);
80f9611a 1676 break;
1677 case LTTV_FILTER_STATE_CT:
4d9ff942 1678 if(state == NULL) return TRUE;
80f9611a 1679 else {
4d9ff942 1680 return se->op((gpointer)&state->creation_time,v);
80f9611a 1681 }
1682 break;
1683 case LTTV_FILTER_STATE_IT:
4d9ff942 1684 if(state == NULL) return TRUE;
80f9611a 1685 else {
4d9ff942 1686 return se->op((gpointer)&state->insertion_time,v);
80f9611a 1687 }
1688 break;
1689 case LTTV_FILTER_STATE_P_NAME:
1690 /*
4d9ff942 1691 * All 'unnamed' for the moment
80f9611a 1692 */
4d9ff942 1693 if(state == NULL) return TRUE;
46c40a93 1694 else {
852f16bb 1695 GQuark quark = g_quark_to_string(state->name);
c6832b57 1696 return se->op((gpointer)&quark,v);
46c40a93 1697 }
80f9611a 1698 break;
1699 case LTTV_FILTER_STATE_EX_MODE:
4d9ff942 1700 if(state == NULL) return TRUE;
1701 else return se->op((gpointer)&state->state->t,v);
80f9611a 1702 break;
1703 case LTTV_FILTER_STATE_EX_SUBMODE:
4d9ff942 1704 if(state == NULL) return TRUE;
1705 else return se->op((gpointer)&state->state->n,v);
80f9611a 1706 break;
1707 case LTTV_FILTER_STATE_P_STATUS:
4d9ff942 1708 if(state == NULL) return TRUE;
1709 else return se->op((gpointer)&state->state->s,v);
80f9611a 1710 break;
1711 case LTTV_FILTER_STATE_CPU:
4d9ff942 1712 if(context == NULL) return TRUE;
46c40a93 1713 else {
c6832b57 1714 /* FIXME: not sure of that one */
852f16bb 1715 return se->op((gpointer)g_quark_to_string(((LttvTracefileState*)context)->cpu_name),v);
46c40a93 1716 }
80f9611a 1717 break;
1718 case LTTV_FILTER_EVENT_NAME:
4d9ff942 1719 if(event == NULL) return TRUE;
1720 else {
46c40a93 1721 LttEventType* et;
1722 et = ltt_event_eventtype(event);
c6832b57 1723 g_print("v:%s\n",ltt_eventtype_name(et));
852f16bb 1724 GQuark quark = g_quark_to_string(ltt_eventtype_name(et));
c6832b57 1725 return se->op((gpointer)&quark,v);
4d9ff942 1726 }
1727 break;
1728
80f9611a 1729 case LTTV_FILTER_EVENT_CATEGORY:
1730 /*
c6832b57 1731 * TODO: Not yet implemented
80f9611a 1732 */
4d9ff942 1733 return TRUE;
80f9611a 1734 break;
1735 case LTTV_FILTER_EVENT_TIME:
4d9ff942 1736 if(event == NULL) return TRUE;
46c40a93 1737 else {
1738 LttTime time = ltt_event_time(event);
4d9ff942 1739 return se->op((gpointer)&time,v);
46c40a93 1740 }
80f9611a 1741 break;
1742 case LTTV_FILTER_EVENT_TSC:
4d9ff942 1743// if(event == NULL) return TRUE;
80f9611a 1744// else {
1745// double val = ltt_time_to_double(event->event_time);
4d9ff942 1746// return se->op((gpointer)&val,v);
80f9611a 1747// }
1748 /*
1749 * FIXME: Where is event.tsc
1750 */
4d9ff942 1751 return TRUE;
80f9611a 1752 break;
1753 case LTTV_FILTER_EVENT_FIELD:
1754 /*
1755 * TODO: Use the offset to
1756 * find the dynamic field
1757 * in the event struct
1758 */
4d9ff942 1759 return TRUE;
80f9611a 1760 default:
1761 /*
1762 * This case should never be
4d9ff942 1763 * parsed, if so, the whole
1764 * filtering is cancelled
80f9611a 1765 */
1766 g_warning("Error while parsing the filter tree");
1767 return TRUE;
1768 }
4d9ff942 1769
1770 /* should never get here */
1771 return TRUE;
1772
80f9611a 1773}
0769c82f 1774
4d9ff942 1775
1776
80f9611a 1777/**
56e29124 1778 * @fn void lttv_print_tree(LttvFilterTree*)
1779 *
1780 * Debug
1781 * @param t the pointer to the current LttvFilterTree
80f9611a 1782 */
1783void
4d9ff942 1784lttv_print_tree(const LttvFilterTree* t) {
0769c82f 1785
73050a5f 1786 g_print("node:%p lchild:%p rchild:%p\n",t, //t->l_child.t,t->r_child.t);
80f9611a 1787 (t->left==LTTV_TREE_NODE)?t->l_child.t:NULL,
1788 (t->right==LTTV_TREE_NODE)?t->r_child.t:NULL);
1789 g_print("node type: %i / [left] %i / [right] %i\n",t->node,t->left,t->right);
1790 if(t->left == LTTV_TREE_NODE) lttv_print_tree(t->l_child.t);
1791 else if(t->left == LTTV_TREE_LEAF) {
9ab5ebd7 1792 g_print("%p: left is %i %p value\n",t,t->l_child.leaf->field,t->l_child.leaf->op);
0769c82f 1793 }
80f9611a 1794 if(t->right == LTTV_TREE_NODE) lttv_print_tree(t->r_child.t);
1795 else if(t->right == LTTV_TREE_LEAF) {
9ab5ebd7 1796 g_print("%p: right is %i %p value\n",t,t->r_child.leaf->field,t->r_child.leaf->op);
80f9611a 1797 }
80f9611a 1798
1799}
1800
91ad3f0a 1801/**
56e29124 1802 * @fn static void module_init()
1803 *
91ad3f0a 1804 * Initializes the filter module and specific values
1805 */
1a7fa682 1806static void module_init()
1807{
91ad3f0a 1808
1a7fa682 1809}
1810
91ad3f0a 1811/**
8ff6243c 1812 * @fn Destroys the filter module and specific values
91ad3f0a 1813 */
1a7fa682 1814static void module_destroy()
1815{
56e29124 1816
1a7fa682 1817}
1818
1819
91ad3f0a 1820LTTV_MODULE("filter", "Filters traceset and events", \
1821 "Filters traceset and events specifically to user input", \
1a7fa682 1822 module_init, module_destroy)
1823
1824
1825
This page took 0.129658 seconds and 4 git commands to generate.