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