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