Move "active" code out of debug statements
[lttv.git] / 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\
6471e71f 33 * | |->name (String, converted to GQuark) (channel.event)
34 * | |->subname (String, converted to GQuark)
7e7af7f2 35 * | |->category (String, not yet implemented)
36 * | |->time (LttTime)
bbd9d557 37 * | |->tsc (LttCycleCount --> uint64)
33bdc8dd 38 * | |->target_pid (target PID of the event)
7e7af7f2 39 * | |->fields
6471e71f 40 * | |->"channel name"
c56a714e 41 * | |->"event name"
42 * | |->"field name"
43 * | |->"sub-field name"
44 * | |->...
45 * | |->"leaf-field name" (field type)
6471e71f 46 * |->channel (or tracefile)
7e7af7f2 47 * | |->name (String, converted to GQuark)
48 * |->trace
49 * | |->name (String, converted to GQuark)
50 * |->state
2ec11087 51 * |->pid (guint)
52 * |->ppid (guint)
7e7af7f2 53 * |->creation_time (LttTime)
54 * |->insertion_time (LttTime)
55 * |->process_name (String, converted to GQuark)
7b5f6cf1 56 * |->thread_brand (String, converted to GQuark)
7e7af7f2 57 * |->execution_mode (LttvExecutionMode)
58 * |->execution_submode (LttvExecutionSubmode)
59 * |->process_status (LttvProcessStatus)
6e0d58d6 60 * |->cpu (guint)
da2e1bfb 61 * \endverbatim
150f0d33 62 */
63
64/*
bbd9d557 65 * \todo
150f0d33 66 * - refine switch of expression in multiple uses functions
be66ef34 67 * - remove the idle expressions in the tree
150f0d33 68 */
69
4e4d11b3 70#ifdef HAVE_CONFIG_H
71#include <config.h>
72#endif
73
72911c5d 74//#define TEST
be66ef34 75#ifdef TEST
76#include <time.h>
77#include <sys/time.h>
78#endif
79
87834cd1 80#include <lttv/lttv.h>
150f0d33 81#include <lttv/filter.h>
327a4314 82#include <ltt/trace.h>
83#include <stdlib.h>
84#include <string.h>
80f9611a 85
86/**
56e29124 87 * @fn LttvSimpleExpression* lttv_simple_expression_new()
88 *
80f9611a 89 * Constructor for LttvSimpleExpression
90 * @return pointer to new LttvSimpleExpression
91 */
92LttvSimpleExpression*
93lttv_simple_expression_new() {
94
95 LttvSimpleExpression* se = g_new(LttvSimpleExpression,1);
96
97 se->field = LTTV_FILTER_UNDEFINED;
98 se->op = NULL;
99 se->offset = 0;
80f9611a 100
101 return se;
102}
103
9354c7da 104/*
105 * Keeps the array order.
106 */
107static inline gpointer ltt_g_ptr_array_remove_index_slow(GPtrArray *fp,
108 int index)
109{
110 gpointer ptr;
111 int i;
112
113 if (fp->len == 0)
114 return NULL;
115
116 ptr = g_ptr_array_index(fp, index);
117 for (i = index; i < fp->len - 1; i++) {
118 g_ptr_array_index(fp, i) = g_ptr_array_index(fp, i + 1);
119 }
120 g_ptr_array_remove_index(fp, fp->len - 1);
121 return ptr;
122}
123
0769c82f 124/**
7e7af7f2 125 * @fn gboolean lttv_simple_expression_assign_field(GPtrArray*,LttvSimpleExpression*)
56e29124 126 *
0769c82f 127 * Parse through filtering field hierarchy as specified
128 * by user. This function compares each value to
129 * predetermined quarks
130 * @param fp The field path list
bb87caa7 131 * @param se current simple expression
0769c82f 132 * @return success/failure of operation
133 */
134gboolean
9ab5ebd7 135lttv_simple_expression_assign_field(GPtrArray* fp, LttvSimpleExpression* se) {
0769c82f 136
f4e9dd16 137 GString* f = NULL;
6668c31b 138
2b99ec10 139 if(fp->len < 2) return FALSE;
8f318283
BP
140 f=ltt_g_ptr_array_remove_index_slow(fp,0);
141 g_assert(f);
9354c7da 142
143
47aa6e58 144 /*
145 * Parse through the specified
146 * hardcoded fields.
147 *
148 * Take note however that the
149 * 'event' subfields might change
150 * depending on values specified
151 * in core.xml file. Hence, if
152 * none of the subfields in the
153 * array match the hardcoded
154 * subfields, it will be considered
155 * as a dynamic field
156 */
6668c31b 157
80f9611a 158 if(!g_strcasecmp(f->str,"trace") ) {
47aa6e58 159 /*
160 * Possible values:
161 * trace.name
162 */
73050a5f 163 g_string_free(f,TRUE);
9354c7da 164 f=ltt_g_ptr_array_remove_index_slow(fp,0);
80f9611a 165 if(!g_strcasecmp(f->str,"name")) {
389ba50e 166 se->field = LTTV_FILTER_TRACE_NAME;
167 }
80f9611a 168 } else if(!g_strcasecmp(f->str,"traceset") ) {
47aa6e58 169 /*
170 * FIXME: not yet implemented !
171 */
6471e71f 172 } else if(!g_strcasecmp(f->str,"tracefile")
173 || !g_strcasecmp(f->str,"channel") ) {
47aa6e58 174 /*
175 * Possible values:
176 * tracefile.name
6471e71f 177 * channel.name
47aa6e58 178 */
73050a5f 179 g_string_free(f,TRUE);
9354c7da 180 f=ltt_g_ptr_array_remove_index_slow(fp,0);
80f9611a 181 if(!g_strcasecmp(f->str,"name")) {
389ba50e 182 se->field = LTTV_FILTER_TRACEFILE_NAME;
183 }
80f9611a 184 } else if(!g_strcasecmp(f->str,"state") ) {
47aa6e58 185 /*
186 * Possible values:
187 * state.pid
188 * state.ppid
189 * state.creation_time
190 * state.insertion_time
191 * state.process_name
7b5f6cf1 192 * state.thread_brand
47aa6e58 193 * state.execution_mode
194 * state.execution_submode
195 * state.process_status
196 * state.cpu
197 */
73050a5f 198 g_string_free(f,TRUE);
9354c7da 199 f=ltt_g_ptr_array_remove_index_slow(fp,0);
80f9611a 200 if(!g_strcasecmp(f->str,"pid") ) {
389ba50e 201 se->field = LTTV_FILTER_STATE_PID;
202 }
80f9611a 203 else if(!g_strcasecmp(f->str,"ppid") ) {
389ba50e 204 se->field = LTTV_FILTER_STATE_PPID;
205 }
80f9611a 206 else if(!g_strcasecmp(f->str,"creation_time") ) {
389ba50e 207 se->field = LTTV_FILTER_STATE_CT;
208 }
80f9611a 209 else if(!g_strcasecmp(f->str,"insertion_time") ) {
389ba50e 210 se->field = LTTV_FILTER_STATE_IT;
211 }
80f9611a 212 else if(!g_strcasecmp(f->str,"process_name") ) {
389ba50e 213 se->field = LTTV_FILTER_STATE_P_NAME;
214 }
7b5f6cf1 215 else if(!g_strcasecmp(f->str,"thread_brand") ) {
216 se->field = LTTV_FILTER_STATE_T_BRAND;
217 }
80f9611a 218 else if(!g_strcasecmp(f->str,"execution_mode") ) {
389ba50e 219 se->field = LTTV_FILTER_STATE_EX_MODE;
220 }
80f9611a 221 else if(!g_strcasecmp(f->str,"execution_submode") ) {
389ba50e 222 se->field = LTTV_FILTER_STATE_EX_SUBMODE;
223 }
80f9611a 224 else if(!g_strcasecmp(f->str,"process_status") ) {
389ba50e 225 se->field = LTTV_FILTER_STATE_P_STATUS;
226 }
80f9611a 227 else if(!g_strcasecmp(f->str,"cpu") ) {
389ba50e 228 se->field = LTTV_FILTER_STATE_CPU;
229 }
80f9611a 230 } else if(!g_strcasecmp(f->str,"event") ) {
389ba50e 231 /*
232 * Possible values:
233 * event.name
6471e71f 234 * event.channel
389ba50e 235 * event.category
236 * event.time
237 * event.tsc
33bdc8dd 238 * event.target_pid
c56a714e 239 * event.field
389ba50e 240 */
73050a5f 241 g_string_free(f,TRUE);
9354c7da 242 f=ltt_g_ptr_array_remove_index_slow(fp,0);
6668c31b 243
80f9611a 244 if(!g_strcasecmp(f->str,"name") ) {
389ba50e 245 se->field = LTTV_FILTER_EVENT_NAME;
246 }
6471e71f 247 else if(!g_strcasecmp(f->str,"subname") ) {
248 se->field = LTTV_FILTER_EVENT_SUBNAME;
249 }
80f9611a 250 else if(!g_strcasecmp(f->str,"category") ) {
389ba50e 251 /*
252 * FIXME: Category not yet functional in lttv
253 */
254 se->field = LTTV_FILTER_EVENT_CATEGORY;
255 }
80f9611a 256 else if(!g_strcasecmp(f->str,"time") ) {
389ba50e 257 se->field = LTTV_FILTER_EVENT_TIME;
2b99ec10 258 }
80f9611a 259 else if(!g_strcasecmp(f->str,"tsc") ) {
389ba50e 260 se->field = LTTV_FILTER_EVENT_TSC;
2b99ec10 261 }
33bdc8dd 262 else if(!g_strcasecmp(f->str,"target_pid") ) {
263 se->field = LTTV_FILTER_EVENT_TARGET_PID;
264 }
c56a714e 265 else if(!g_strcasecmp(f->str,"field") ) {
389ba50e 266 se->field = LTTV_FILTER_EVENT_FIELD;
c8f08e26 267 g_string_free(f,TRUE);
9354c7da 268 f=ltt_g_ptr_array_remove_index_slow(fp,0);
c56a714e 269
270 } else {
9354c7da 271 //g_string_free(f,TRUE);
272 //f=ltt_g_ptr_array_remove_index_slow(fp,0);
c56a714e 273 g_warning("Unknown event filter subtype %s", f->str);
2b99ec10 274 }
91ad3f0a 275 } else {
fb04197e 276 g_string_free(f,TRUE);
9354c7da 277 f=ltt_g_ptr_array_remove_index_slow(fp,0);
fb04197e 278
91ad3f0a 279 g_warning("Unrecognized field in filter string");
0769c82f 280 }
47aa6e58 281
56e29124 282 /* free memory for last string */
73050a5f 283 g_string_free(f,TRUE);
56e29124 284
285 /* array should be empty */
73050a5f 286 g_assert(fp->len == 0);
56e29124 287
56e29124 288 if(se->field == LTTV_FILTER_UNDEFINED) {
289 g_warning("The specified field was not recognized !");
290 return FALSE;
291 }
91ad3f0a 292 return TRUE;
0769c82f 293}
294
bb87caa7 295/**
56e29124 296 * @fn gboolean lttv_simple_expression_assign_operator(LttvSimpleExpression*,LttvExpressionOp)
297 *
bb87caa7 298 * Sets the function pointer for the current
299 * Simple Expression
300 * @param se current simple expression
7e7af7f2 301 * @param op current operator
bb87caa7 302 * @return success/failure of operation
303 */
be66ef34 304gboolean
305lttv_simple_expression_assign_operator(LttvSimpleExpression* se, LttvExpressionOp op) {
aa4600f3 306
bb87caa7 307 switch(se->field) {
56e29124 308 /*
309 * string
310 */
bb87caa7 311 case LTTV_FILTER_TRACE_NAME:
312 case LTTV_FILTER_TRACEFILE_NAME:
313 case LTTV_FILTER_STATE_P_NAME:
7b5f6cf1 314 case LTTV_FILTER_STATE_T_BRAND:
6471e71f 315 case LTTV_FILTER_EVENT_SUBNAME:
be66ef34 316 case LTTV_FILTER_STATE_EX_MODE:
317 case LTTV_FILTER_STATE_EX_SUBMODE:
318 case LTTV_FILTER_STATE_P_STATUS:
bb87caa7 319 switch(op) {
320 case LTTV_FIELD_EQ:
c6832b57 321 se->op = lttv_apply_op_eq_quark;
bb87caa7 322 break;
323 case LTTV_FIELD_NE:
c6832b57 324 se->op = lttv_apply_op_ne_quark;
bb87caa7 325 break;
326 default:
73050a5f 327 g_warning("Error encountered in operator assignment = or != expected");
bb87caa7 328 return FALSE;
329 }
330 break;
6471e71f 331 /*
332 * two strings.
333 */
334 case LTTV_FILTER_EVENT_NAME:
335 switch(op) {
336 case LTTV_FIELD_EQ:
337 se->op = lttv_apply_op_eq_quarks;
338 break;
339 case LTTV_FIELD_NE:
340 se->op = lttv_apply_op_ne_quarks;
341 break;
342 default:
343 g_warning("Error encountered in operator assignment = or != expected");
344 return FALSE;
345 }
56e29124 346 /*
347 * integer
348 */
bbd9d557 349 case LTTV_FILTER_EVENT_TSC:
bb87caa7 350 switch(op) {
351 case LTTV_FIELD_EQ:
352 se->op = lttv_apply_op_eq_uint64;
353 break;
354 case LTTV_FIELD_NE:
355 se->op = lttv_apply_op_ne_uint64;
356 break;
357 case LTTV_FIELD_LT:
358 se->op = lttv_apply_op_lt_uint64;
359 break;
360 case LTTV_FIELD_LE:
361 se->op = lttv_apply_op_le_uint64;
362 break;
363 case LTTV_FIELD_GT:
364 se->op = lttv_apply_op_gt_uint64;
365 break;
366 case LTTV_FIELD_GE:
367 se->op = lttv_apply_op_ge_uint64;
368 break;
369 default:
370 g_warning("Error encountered in operator assignment");
371 return FALSE;
372 }
373 break;
6e0d58d6 374 /*
2ec11087 375 * unsigned integers
6e0d58d6 376 */
377 case LTTV_FILTER_STATE_CPU:
378 case LTTV_FILTER_STATE_PID:
379 case LTTV_FILTER_STATE_PPID:
33bdc8dd 380 case LTTV_FILTER_EVENT_TARGET_PID:
6e0d58d6 381 switch(op) {
382 case LTTV_FIELD_EQ:
2ec11087 383 se->op = lttv_apply_op_eq_uint;
6e0d58d6 384 break;
385 case LTTV_FIELD_NE:
2ec11087 386 se->op = lttv_apply_op_ne_uint;
6e0d58d6 387 break;
388 case LTTV_FIELD_LT:
2ec11087 389 se->op = lttv_apply_op_lt_uint;
6e0d58d6 390 break;
391 case LTTV_FIELD_LE:
2ec11087 392 se->op = lttv_apply_op_le_uint;
6e0d58d6 393 break;
394 case LTTV_FIELD_GT:
2ec11087 395 se->op = lttv_apply_op_gt_uint;
6e0d58d6 396 break;
397 case LTTV_FIELD_GE:
2ec11087 398 se->op = lttv_apply_op_ge_uint;
6e0d58d6 399 break;
400 default:
401 g_warning("Error encountered in operator assignment");
402 return FALSE;
403 }
404 break;
405
f017db44 406 /*
407 * Enums
be66ef34 408 * Entered as string, converted to enum
409 *
f017db44 410 * can only be compared with 'equal' or 'not equal' operators
411 *
412 * unsigned int of 16 bits are used here since enums
be66ef34 413 * should not go over 2^16-1 values
f017db44 414 */
be66ef34 415// case /*NOTHING*/:
416// switch(op) {
417// case LTTV_FIELD_EQ:
418// se->op = lttv_apply_op_eq_uint16;
419// break;
420// case LTTV_FIELD_NE:
421// se->op = lttv_apply_op_ne_uint16;
422// break;
423// default:
424// g_warning("Error encountered in operator assignment = or != expected");
425// return FALSE;
426// }
427// break;
56e29124 428 /*
7145a073 429 * Ltttime
56e29124 430 */
bb87caa7 431 case LTTV_FILTER_STATE_CT:
432 case LTTV_FILTER_STATE_IT:
433 case LTTV_FILTER_EVENT_TIME:
bb87caa7 434 switch(op) {
435 case LTTV_FIELD_EQ:
7145a073 436 se->op = lttv_apply_op_eq_ltttime;
bb87caa7 437 break;
438 case LTTV_FIELD_NE:
7145a073 439 se->op = lttv_apply_op_ne_ltttime;
bb87caa7 440 break;
441 case LTTV_FIELD_LT:
7145a073 442 se->op = lttv_apply_op_lt_ltttime;
bb87caa7 443 break;
444 case LTTV_FIELD_LE:
7145a073 445 se->op = lttv_apply_op_le_ltttime;
bb87caa7 446 break;
447 case LTTV_FIELD_GT:
7145a073 448 se->op = lttv_apply_op_gt_ltttime;
bb87caa7 449 break;
450 case LTTV_FIELD_GE:
7145a073 451 se->op = lttv_apply_op_ge_ltttime;
bb87caa7 452 break;
453 default:
454 g_warning("Error encountered in operator assignment");
455 return FALSE;
456 }
457 break;
458 default:
9ab5ebd7 459 g_warning("Error encountered in operator assignation ! Field type:%i",se->field);
bb87caa7 460 return FALSE;
461 }
aa4600f3 462
463 return TRUE;
bb87caa7 464
465}
466
9ab5ebd7 467/**
7e7af7f2 468 * @fn gboolean lttv_simple_expression_assign_value(LttvSimpleExpression*,char*)
9ab5ebd7 469 *
470 * Assign the value field to the current LttvSimpleExpression
471 * @param se pointer to the current LttvSimpleExpression
472 * @param value string value for simple expression
473 */
be66ef34 474gboolean
475lttv_simple_expression_assign_value(LttvSimpleExpression* se, char* value) {
9ab5ebd7 476
46c40a93 477 unsigned i;
478 gboolean is_double = FALSE;
c6832b57 479 LttTime t = ltt_time_zero;
480 GString* v;
571ef1ed 481 guint string_len;
9ab5ebd7 482
483 switch(se->field) {
484 /*
be66ef34 485 * Strings
486 * entered as strings, converted to Quarks
9ab5ebd7 487 */
488 case LTTV_FILTER_TRACE_NAME:
489 case LTTV_FILTER_TRACEFILE_NAME:
490 case LTTV_FILTER_STATE_P_NAME:
7b5f6cf1 491 case LTTV_FILTER_STATE_T_BRAND:
6471e71f 492 case LTTV_FILTER_EVENT_SUBNAME:
be66ef34 493 case LTTV_FILTER_STATE_EX_MODE:
494 case LTTV_FILTER_STATE_EX_SUBMODE:
495 case LTTV_FILTER_STATE_P_STATUS:
496 // se->value.v_string = value;
c56a714e 497 se->value.v_quark = g_quark_from_string(value);
c6832b57 498 g_free(value);
9ab5ebd7 499 break;
6471e71f 500 /*
501 * Two strings.
502 */
503 case LTTV_FILTER_EVENT_NAME:
504 {
505 /* channel.event */
506 char *end = strchr(value, '.');
507 if (end) {
508 *end = '\0';
509 end++;
510 se->value.v_quarks.q[0] = g_quark_from_string(value);
511 se->value.v_quarks.q[1] = g_quark_from_string(end);
512 } else {
513 se->value.v_quarks.q[0] = (GQuark)0;
514 se->value.v_quarks.q[1] = g_quark_from_string(value);
515 }
516 g_free(value);
517 }
518 break;
9ab5ebd7 519 /*
be66ef34 520 * integer -- supposed to be uint64
9ab5ebd7 521 */
bbd9d557 522 case LTTV_FILTER_EVENT_TSC:
9ab5ebd7 523 se->value.v_uint64 = atoi(value);
524 g_free(value);
525 break;
6e0d58d6 526 /*
2ec11087 527 * unsigned integers
6e0d58d6 528 */
529 case LTTV_FILTER_STATE_PID:
530 case LTTV_FILTER_STATE_PPID:
531 case LTTV_FILTER_STATE_CPU:
33bdc8dd 532 case LTTV_FILTER_EVENT_TARGET_PID:
2ec11087 533 se->value.v_uint = atoi(value);
6e0d58d6 534 g_free(value);
535 break;
9ab5ebd7 536 /*
7145a073 537 * LttTime
9ab5ebd7 538 */
539 case LTTV_FILTER_STATE_CT:
540 case LTTV_FILTER_STATE_IT:
541 case LTTV_FILTER_EVENT_TIME:
7145a073 542 //se->value.v_double = atof(value);
46c40a93 543 /*
544 * parsing logic could be optimised,
545 * but as for now, simpler this way
546 */
547 v = g_string_new("");
571ef1ed 548 string_len = strlen(value);
549 for(i=0;i<string_len;i++) {
46c40a93 550 if(value[i] == '.') {
551 /* cannot specify number with more than one '.' */
552 if(is_double) return FALSE;
553 else is_double = TRUE;
826f1ab2 554 t.tv_sec = atoi(v->str);
46c40a93 555 g_string_free(v,TRUE);
556 v = g_string_new("");
4ec0c904 557 } else v = g_string_append_c(v,value[i]);
46c40a93 558 }
559 /* number can be integer or double */
826f1ab2 560 if(is_double) t.tv_nsec = atoi(v->str);
571ef1ed 561 else {
562 t.tv_sec = atoi(v->str);
563 t.tv_nsec = 0;
564 }
c6832b57 565
46c40a93 566 g_string_free(v,TRUE);
567
568 se->value.v_ltttime = t;
9ab5ebd7 569 g_free(value);
570 break;
571 default:
572 g_warning("Error encountered in value assignation ! Field type = %i",se->field);
c6832b57 573 g_free(value);
9ab5ebd7 574 return FALSE;
575 }
576
577 return TRUE;
578
579}
580
31452f49 581/**
56e29124 582 * @fn void lttv_simple_expression_destroy(LttvSimpleExpression*)
583 *
9ab5ebd7 584 * Disallocate memory for the current
56e29124 585 * simple expression
586 * @param se pointer to the current LttvSimpleExpression
587 */
588void
589lttv_simple_expression_destroy(LttvSimpleExpression* se) {
590
9ab5ebd7 591 // g_free(se->value);
786c5c3b 592// switch(se->field) {
593// case LTTV_FILTER_TRACE_NAME:
594// case LTTV_FILTER_TRACEFILE_NAME:
595// case LTTV_FILTER_STATE_P_NAME:
596// case LTTV_FILTER_EVENT_NAME:
597// g_free(se->value.v_string);
598// break;
599// }
56e29124 600 g_free(se);
601
602}
603
604/**
605 * @fn gint lttv_struct_type(gint)
606 *
80f9611a 607 * Finds the structure type depending
608 * on the fields in parameters
609 * @params ft Field of the current structure
610 * @return LttvStructType enum or -1 for error
84a333d6 611 */
80f9611a 612gint
613lttv_struct_type(gint ft) {
5f185a2b 614
80f9611a 615 switch(ft) {
616 case LTTV_FILTER_TRACE_NAME:
617 return LTTV_FILTER_TRACE;
618 break;
619 case LTTV_FILTER_TRACEFILE_NAME:
620 return LTTV_FILTER_TRACEFILE;
621 break;
622 case LTTV_FILTER_STATE_PID:
623 case LTTV_FILTER_STATE_PPID:
624 case LTTV_FILTER_STATE_CT:
625 case LTTV_FILTER_STATE_IT:
626 case LTTV_FILTER_STATE_P_NAME:
6471e71f 627 case LTTV_FILTER_STATE_T_BRAND:
80f9611a 628 case LTTV_FILTER_STATE_EX_MODE:
629 case LTTV_FILTER_STATE_EX_SUBMODE:
630 case LTTV_FILTER_STATE_P_STATUS:
631 case LTTV_FILTER_STATE_CPU:
632 return LTTV_FILTER_STATE;
633 break;
634 case LTTV_FILTER_EVENT_NAME:
6471e71f 635 case LTTV_FILTER_EVENT_SUBNAME:
80f9611a 636 case LTTV_FILTER_EVENT_CATEGORY:
637 case LTTV_FILTER_EVENT_TIME:
638 case LTTV_FILTER_EVENT_TSC:
33bdc8dd 639 case LTTV_FILTER_EVENT_TARGET_PID:
80f9611a 640 case LTTV_FILTER_EVENT_FIELD:
641 return LTTV_FILTER_EVENT;
642 break;
643 default:
644 return -1;
645 }
84a333d6 646}
647
2ec11087 648/**
649 * @fn gboolean lttv_apply_op_eq_uint(gpointer,LttvFieldValue)
650 *
651 * Applies the 'equal' operator to the
652 * specified structure and value
653 * @param v1 left member of comparison
654 * @param v2 right member of comparison
655 * @return success/failure of operation
656 */
657gboolean lttv_apply_op_eq_uint(const gpointer v1, LttvFieldValue v2) {
658
659 guint* r = (guint*) v1;
660 return (*r == v2.v_uint);
661
662}
663
150f0d33 664/**
7e7af7f2 665 * @fn gboolean lttv_apply_op_eq_uint64(gpointer,LttvFieldValue)
56e29124 666 *
150f0d33 667 * Applies the 'equal' operator to the
47aa6e58 668 * specified structure and value
669 * @param v1 left member of comparison
670 * @param v2 right member of comparison
150f0d33 671 * @return success/failure of operation
672 */
4d9ff942 673gboolean lttv_apply_op_eq_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 674
675 guint64* r = (guint64*) v1;
9ab5ebd7 676 return (*r == v2.v_uint64);
83aa92fc 677
678}
150f0d33 679
5b729fcf 680/**
7e7af7f2 681 * @fn gboolean lttv_apply_op_eq_uint32(gpointer,LttvFieldValue)
56e29124 682 *
5b729fcf 683 * Applies the 'equal' operator to the
47aa6e58 684 * specified structure and value
685 * @param v1 left member of comparison
686 * @param v2 right member of comparison
5b729fcf 687 * @return success/failure of operation
688 */
4d9ff942 689gboolean lttv_apply_op_eq_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 690 guint32* r = (guint32*) v1;
9ab5ebd7 691 return (*r == v2.v_uint32);
83aa92fc 692}
5b729fcf 693
694/**
7e7af7f2 695 * @fn gboolean lttv_apply_op_eq_uint16(gpointer,LttvFieldValue)
56e29124 696 *
5b729fcf 697 * Applies the 'equal' operator to the
47aa6e58 698 * specified structure and value
699 * @param v1 left member of comparison
700 * @param v2 right member of comparison
5b729fcf 701 * @return success/failure of operation
702 */
4d9ff942 703gboolean lttv_apply_op_eq_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 704 guint16* r = (guint16*) v1;
9ab5ebd7 705 return (*r == v2.v_uint16);
83aa92fc 706}
5b729fcf 707
708/**
7e7af7f2 709 * @fn gboolean lttv_apply_op_eq_double(gpointer,LttvFieldValue)
56e29124 710 *
5b729fcf 711 * Applies the 'equal' operator to the
47aa6e58 712 * specified structure and value
713 * @param v1 left member of comparison
714 * @param v2 right member of comparison
5b729fcf 715 * @return success/failure of operation
716 */
4d9ff942 717gboolean lttv_apply_op_eq_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 718 double* r = (double*) v1;
9ab5ebd7 719 return (*r == v2.v_double);
83aa92fc 720}
5b729fcf 721
722/**
7e7af7f2 723 * @fn gboolean lttv_apply_op_eq_string(gpointer,LttvFieldValue)
56e29124 724 *
5b729fcf 725 * Applies the 'equal' operator to the
47aa6e58 726 * specified structure and value
727 * @param v1 left member of comparison
728 * @param v2 right member of comparison
5b729fcf 729 * @return success/failure of operation
730 */
4d9ff942 731gboolean lttv_apply_op_eq_string(const gpointer v1, LttvFieldValue v2) {
83aa92fc 732 char* r = (char*) v1;
9ab5ebd7 733 return (!g_strcasecmp(r,v2.v_string));
83aa92fc 734}
150f0d33 735
c6832b57 736/**
7e7af7f2 737 * @fn gboolean lttv_apply_op_eq_quark(gpointer,LttvFieldValue)
c6832b57 738 *
739 * Applies the 'equal' operator to the
740 * specified structure and value
741 * @param v1 left member of comparison
742 * @param v2 right member of comparison
743 * @return success/failure of operation
744 */
745gboolean lttv_apply_op_eq_quark(const gpointer v1, LttvFieldValue v2) {
746 GQuark* r = (GQuark*) v1;
c56a714e 747 return (*r == v2.v_quark);
c6832b57 748}
749
6471e71f 750/**
751 * @fn gboolean lttv_apply_op_eq_quarks(gpointer,LttvFieldValue)
752 *
753 * Applies the 'equal' operator to the
754 * specified structure and value
755 * @param v1 left member of comparison
756 * @param v2 right member of comparison
757 * @return success/failure of operation
758 */
759gboolean lttv_apply_op_eq_quarks(const gpointer v1, LttvFieldValue v2) {
760 GQuark *r1 = (GQuark *) v1;
761 GQuark *r2 = r1 + 1;
762 if (likely(*r1 != (GQuark)0) && *r1 != v2.v_quarks.q[0])
763 return 0;
764 if (*r2 != v2.v_quarks.q[1])
765 return 0;
766 return 1;
767}
768
7145a073 769/**
7e7af7f2 770 * @fn gboolean lttv_apply_op_eq_ltttime(gpointer,LttvFieldValue)
7145a073 771 *
772 * Applies the 'equal' operator to the
773 * specified structure and value
774 * @param v1 left member of comparison
775 * @param v2 right member of comparison
776 * @return success/failure of operation
777 */
4d9ff942 778gboolean lttv_apply_op_eq_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 779 LttTime* r = (LttTime*) v1;
c6832b57 780 return ltt_time_compare(*r, v2.v_ltttime)==0?1:0;
7145a073 781}
782
2ec11087 783/**
784 * @fn gboolean lttv_apply_op_ne_uint(gpointer,LttvFieldValue)
785 *
786 * Applies the 'not equal' operator to the
787 * specified structure and value
788 * @param v1 left member of comparison
789 * @param v2 right member of comparison
790 * @return success/failure of operation
791 */
792gboolean lttv_apply_op_ne_uint(const gpointer v1, LttvFieldValue v2) {
793 guint* r = (guint*) v1;
794 return (*r != v2.v_uint);
795}
7145a073 796
150f0d33 797/**
7e7af7f2 798 * @fn gboolean lttv_apply_op_ne_uint64(gpointer,LttvFieldValue)
56e29124 799 *
150f0d33 800 * Applies the 'not equal' operator to the
47aa6e58 801 * specified structure and value
802 * @param v1 left member of comparison
803 * @param v2 right member of comparison
150f0d33 804 * @return success/failure of operation
805 */
4d9ff942 806gboolean lttv_apply_op_ne_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 807 guint64* r = (guint64*) v1;
9ab5ebd7 808 return (*r != v2.v_uint64);
83aa92fc 809}
150f0d33 810
5b729fcf 811/**
7e7af7f2 812 * @fn gboolean lttv_apply_op_ne_uint32(gpointer,LttvFieldValue)
56e29124 813 *
5b729fcf 814 * Applies the 'not equal' operator to the
47aa6e58 815 * specified structure and value
816 * @param v1 left member of comparison
817 * @param v2 right member of comparison
5b729fcf 818 * @return success/failure of operation
819 */
4d9ff942 820gboolean lttv_apply_op_ne_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 821 guint32* r = (guint32*) v1;
9ab5ebd7 822 return (*r != v2.v_uint32);
83aa92fc 823}
5b729fcf 824
825/**
7e7af7f2 826 * @fn gboolean lttv_apply_op_ne_uint16(gpointer,LttvFieldValue)
56e29124 827 *
5b729fcf 828 * Applies the 'not equal' operator to the
47aa6e58 829 * specified structure and value
830 * @param v1 left member of comparison
831 * @param v2 right member of comparison
5b729fcf 832 * @return success/failure of operation
833 */
4d9ff942 834gboolean lttv_apply_op_ne_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 835 guint16* r = (guint16*) v1;
9ab5ebd7 836 return (*r != v2.v_uint16);
83aa92fc 837}
5b729fcf 838
839/**
7e7af7f2 840 * @fn gboolean lttv_apply_op_ne_double(gpointer,LttvFieldValue)
56e29124 841 *
5b729fcf 842 * Applies the 'not equal' operator to the
47aa6e58 843 * specified structure and value
844 * @param v1 left member of comparison
845 * @param v2 right member of comparison
5b729fcf 846 * @return success/failure of operation
847 */
4d9ff942 848gboolean lttv_apply_op_ne_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 849 double* r = (double*) v1;
9ab5ebd7 850 return (*r != v2.v_double);
83aa92fc 851}
5b729fcf 852
853/**
7e7af7f2 854 * @fn gboolean lttv_apply_op_ne_string(gpointer,LttvFieldValue)
56e29124 855 *
5b729fcf 856 * Applies the 'not equal' operator to the
47aa6e58 857 * specified structure and value
858 * @param v1 left member of comparison
859 * @param v2 right member of comparison
5b729fcf 860 * @return success/failure of operation
861 */
4d9ff942 862gboolean lttv_apply_op_ne_string(const gpointer v1, LttvFieldValue v2) {
83aa92fc 863 char* r = (char*) v1;
9ab5ebd7 864 return (g_strcasecmp(r,v2.v_string));
83aa92fc 865}
150f0d33 866
c6832b57 867/**
7e7af7f2 868 * @fn gboolean lttv_apply_op_ne_quark(gpointer,LttvFieldValue)
c6832b57 869 *
870 * Applies the 'not equal' operator to the
871 * specified structure and value
872 * @param v1 left member of comparison
873 * @param v2 right member of comparison
874 * @return success/failure of operation
875 */
876gboolean lttv_apply_op_ne_quark(const gpointer v1, LttvFieldValue v2) {
877 GQuark* r = (GQuark*) v1;
c56a714e 878 return (*r != v2.v_quark);
c6832b57 879}
880
6471e71f 881/**
882 * @fn gboolean lttv_apply_op_ne_quarks(gpointer,LttvFieldValue)
883 *
884 * Applies the 'equal' operator to the
885 * specified structure and value
886 * @param v1 left member of comparison
887 * @param v2 right member of comparison
888 * @return success/failure of operation
889 */
890gboolean lttv_apply_op_ne_quarks(const gpointer v1, LttvFieldValue v2) {
891 GQuark *r1 = (GQuark *) v1;
892 GQuark *r2 = r1 + 1;
893 if ((*r1 == (GQuark)0 || *r1 == v2.v_quarks.q[0]) && *r2 == v2.v_quarks.q[1])
894 return 0;
895 else
896 return 1;
897}
c6832b57 898
7145a073 899/**
7e7af7f2 900 * @fn gboolean lttv_apply_op_ne_ltttime(gpointer,LttvFieldValue)
7145a073 901 *
902 * Applies the 'not equal' operator to the
903 * specified structure and value
904 * @param v1 left member of comparison
905 * @param v2 right member of comparison
906 * @return success/failure of operation
907 */
4d9ff942 908gboolean lttv_apply_op_ne_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 909 LttTime* r = (LttTime*) v1;
46c40a93 910 return ltt_time_compare(*r, v2.v_ltttime)!=0?1:0;
7145a073 911}
912
2ec11087 913/**
914 * @fn gboolean lttv_apply_op_lt_uint(gpointer,LttvFieldValue)
915 *
916 * Applies the 'lower than' operator to the
917 * specified structure and value
918 * @param v1 left member of comparison
919 * @param v2 right member of comparison
920 * @return success/failure of operation
921 */
922gboolean lttv_apply_op_lt_uint(const gpointer v1, LttvFieldValue v2) {
923 guint* r = (guint*) v1;
924 return (*r < v2.v_uint);
925}
7145a073 926
150f0d33 927/**
7e7af7f2 928 * @fn gboolean lttv_apply_op_lt_uint64(gpointer,LttvFieldValue)
56e29124 929 *
150f0d33 930 * Applies the 'lower than' operator to the
47aa6e58 931 * specified structure and value
932 * @param v1 left member of comparison
933 * @param v2 right member of comparison
150f0d33 934 * @return success/failure of operation
935 */
4d9ff942 936gboolean lttv_apply_op_lt_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 937 guint64* r = (guint64*) v1;
9ab5ebd7 938 return (*r < v2.v_uint64);
83aa92fc 939}
150f0d33 940
5b729fcf 941/**
7e7af7f2 942 * @fn gboolean lttv_apply_op_lt_uint32(gpointer,LttvFieldValue)
56e29124 943 *
5b729fcf 944 * Applies the 'lower than' operator to the
47aa6e58 945 * specified structure and value
946 * @param v1 left member of comparison
947 * @param v2 right member of comparison
5b729fcf 948 * @return success/failure of operation
949 */
4d9ff942 950gboolean lttv_apply_op_lt_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 951 guint32* r = (guint32*) v1;
9ab5ebd7 952 return (*r < v2.v_uint32);
83aa92fc 953}
5b729fcf 954
955/**
7e7af7f2 956 * @fn gboolean lttv_apply_op_lt_uint16(gpointer,LttvFieldValue)
56e29124 957 *
5b729fcf 958 * Applies the 'lower than' operator to the
47aa6e58 959 * specified structure and value
960 * @param v1 left member of comparison
961 * @param v2 right member of comparison
5b729fcf 962 * @return success/failure of operation
963 */
4d9ff942 964gboolean lttv_apply_op_lt_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 965 guint16* r = (guint16*) v1;
9ab5ebd7 966 return (*r < v2.v_uint16);
83aa92fc 967}
5b729fcf 968
969/**
7e7af7f2 970 * @fn gboolean lttv_apply_op_lt_double(gpointer,LttvFieldValue)
56e29124 971 *
5b729fcf 972 * Applies the 'lower than' operator to the
47aa6e58 973 * specified structure and value
974 * @param v1 left member of comparison
975 * @param v2 right member of comparison
5b729fcf 976 * @return success/failure of operation
977 */
4d9ff942 978gboolean lttv_apply_op_lt_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 979 double* r = (double*) v1;
9ab5ebd7 980 return (*r < v2.v_double);
83aa92fc 981}
5b729fcf 982
7145a073 983/**
7e7af7f2 984 * @fn gboolean lttv_apply_op_lt_ltttime(gpointer,LttvFieldValue)
7145a073 985 *
986 * Applies the 'lower than' operator to the
987 * specified structure and value
988 * @param v1 left member of comparison
989 * @param v2 right member of comparison
990 * @return success/failure of operation
991 */
4d9ff942 992gboolean lttv_apply_op_lt_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 993 LttTime* r = (LttTime*) v1;
c6832b57 994// 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)));
995 return ltt_time_compare(*r, v2.v_ltttime)==-1?1:0;
7145a073 996}
997
2ec11087 998/**
999 * @fn gboolean lttv_apply_op_le_uint(gpointer,LttvFieldValue)
1000 *
1001 * Applies the 'lower or equal' operator to the
1002 * specified structure and value
1003 * @param v1 left member of comparison
1004 * @param v2 right member of comparison
1005 * @return success/failure of operation
1006 */
1007gboolean lttv_apply_op_le_uint(const gpointer v1, LttvFieldValue v2) {
1008 guint* r = (guint*) v1;
1009 return (*r <= v2.v_uint);
1010}
7145a073 1011
5b729fcf 1012/**
7e7af7f2 1013 * @fn gboolean lttv_apply_op_le_uint64(gpointer,LttvFieldValue)
56e29124 1014 *
1015 * Applies the 'lower or equal' operator to the
47aa6e58 1016 * specified structure and value
1017 * @param v1 left member of comparison
1018 * @param v2 right member of comparison
5b729fcf 1019 * @return success/failure of operation
1020 */
4d9ff942 1021gboolean lttv_apply_op_le_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1022 guint64* r = (guint64*) v1;
9ab5ebd7 1023 return (*r <= v2.v_uint64);
83aa92fc 1024}
150f0d33 1025
1026/**
7e7af7f2 1027 * @fn gboolean lttv_apply_op_le_uint32(gpointer,LttvFieldValue)
56e29124 1028 *
150f0d33 1029 * Applies the 'lower or equal' operator to the
47aa6e58 1030 * specified structure and value
1031 * @param v1 left member of comparison
1032 * @param v2 right member of comparison
150f0d33 1033 * @return success/failure of operation
1034 */
4d9ff942 1035gboolean lttv_apply_op_le_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1036 guint32* r = (guint32*) v1;
9ab5ebd7 1037 return (*r <= v2.v_uint32);
83aa92fc 1038}
150f0d33 1039
5b729fcf 1040/**
7e7af7f2 1041 * @fn gboolean lttv_apply_op_le_uint16(gpointer,LttvFieldValue)
56e29124 1042 *
5b729fcf 1043 * Applies the 'lower or equal' operator to the
47aa6e58 1044 * specified structure and value
1045 * @param v1 left member of comparison
1046 * @param v2 right member of comparison
5b729fcf 1047 * @return success/failure of operation
1048 */
4d9ff942 1049gboolean lttv_apply_op_le_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1050 guint16* r = (guint16*) v1;
9ab5ebd7 1051 return (*r <= v2.v_uint16);
83aa92fc 1052}
5b729fcf 1053
1054/**
7e7af7f2 1055 * @fn gboolean lttv_apply_op_le_double(gpointer,LttvFieldValue)
56e29124 1056 *
5b729fcf 1057 * Applies the 'lower or equal' operator to the
47aa6e58 1058 * specified structure and value
1059 * @param v1 left member of comparison
1060 * @param v2 right member of comparison
5b729fcf 1061 * @return success/failure of operation
1062 */
4d9ff942 1063gboolean lttv_apply_op_le_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1064 double* r = (double*) v1;
9ab5ebd7 1065 return (*r <= v2.v_double);
83aa92fc 1066}
5b729fcf 1067
7145a073 1068/**
7e7af7f2 1069 * @fn gboolean lttv_apply_op_le_ltttime(gpointer,LttvFieldValue)
7145a073 1070 *
1071 * Applies the 'lower or equal' operator to the
1072 * specified structure and value
1073 * @param v1 left member of comparison
1074 * @param v2 right member of comparison
1075 * @return success/failure of operation
1076 */
4d9ff942 1077gboolean lttv_apply_op_le_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 1078 LttTime* r = (LttTime*) v1;
c6832b57 1079// 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)));
1080 return ltt_time_compare(*r, v2.v_ltttime)<1?1:0;
7145a073 1081}
1082
1083
2ec11087 1084/**
1085 * @fn gboolean lttv_apply_op_gt_uint(gpointer,LttvFieldValue)
1086 *
1087 * Applies the 'greater than' operator to the
1088 * specified structure and value
1089 * @param v1 left member of comparison
1090 * @param v2 right member of comparison
1091 * @return success/failure of operation
1092 */
1093gboolean lttv_apply_op_gt_uint(const gpointer v1, LttvFieldValue v2) {
1094 guint* r = (guint*) v1;
1095 return (*r > v2.v_uint);
1096}
1097
5b729fcf 1098/**
7e7af7f2 1099 * @fn gboolean lttv_apply_op_gt_uint64(gpointer,LttvFieldValue)
56e29124 1100 *
83aa92fc 1101 * Applies the 'greater than' operator to the
47aa6e58 1102 * specified structure and value
1103 * @param v1 left member of comparison
1104 * @param v2 right member of comparison
5b729fcf 1105 * @return success/failure of operation
1106 */
4d9ff942 1107gboolean lttv_apply_op_gt_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1108 guint64* r = (guint64*) v1;
9ab5ebd7 1109 return (*r > v2.v_uint64);
83aa92fc 1110}
150f0d33 1111
1112/**
7e7af7f2 1113 * @fn gboolean lttv_apply_op_gt_uint32(gpointer,LttvFieldValue)
56e29124 1114 *
150f0d33 1115 * Applies the 'greater than' operator to the
47aa6e58 1116 * specified structure and value
1117 * @param v1 left member of comparison
1118 * @param v2 right member of comparison
150f0d33 1119 * @return success/failure of operation
1120 */
4d9ff942 1121gboolean lttv_apply_op_gt_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1122 guint32* r = (guint32*) v1;
9ab5ebd7 1123 return (*r > v2.v_uint32);
83aa92fc 1124}
150f0d33 1125
5b729fcf 1126/**
7e7af7f2 1127 * @fn gboolean lttv_apply_op_gt_uint16(gpointer,LttvFieldValue)
56e29124 1128 *
5b729fcf 1129 * Applies the 'greater than' operator to the
47aa6e58 1130 * specified structure and value
1131 * @param v1 left member of comparison
1132 * @param v2 right member of comparison
5b729fcf 1133 * @return success/failure of operation
1134 */
4d9ff942 1135gboolean lttv_apply_op_gt_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1136 guint16* r = (guint16*) v1;
9ab5ebd7 1137 return (*r > v2.v_uint16);
83aa92fc 1138}
5b729fcf 1139
1140/**
7e7af7f2 1141 * @fn gboolean lttv_apply_op_gt_double(gpointer,LttvFieldValue)
56e29124 1142 *
5b729fcf 1143 * Applies the 'greater than' operator to the
47aa6e58 1144 * specified structure and value
1145 * @param v1 left member of comparison
1146 * @param v2 right member of comparison
5b729fcf 1147 * @return success/failure of operation
1148 */
4d9ff942 1149gboolean lttv_apply_op_gt_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1150 double* r = (double*) v1;
9ab5ebd7 1151 return (*r > v2.v_double);
83aa92fc 1152}
5b729fcf 1153
7145a073 1154/**
7e7af7f2 1155 * @fn gboolean lttv_apply_op_gt_ltttime(gpointer,LttvFieldValue)
7145a073 1156 *
1157 * Applies the 'greater than' operator to the
1158 * specified structure and value
1159 * @param v1 left member of comparison
1160 * @param v2 right member of comparison
1161 * @return success/failure of operation
1162 */
4d9ff942 1163gboolean lttv_apply_op_gt_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 1164 LttTime* r = (LttTime*) v1;
c6832b57 1165// 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)));
1166 return ltt_time_compare(*r, v2.v_ltttime)==1?1:0;
7145a073 1167}
1168
2ec11087 1169/**
1170 * @fn gboolean lttv_apply_op_ge_uint(gpointer,LttvFieldValue)
1171 *
1172 * Applies the 'greater or equal' operator to the
1173 * specified structure and value
1174 * @param v1 left member of comparison
1175 * @param v2 right member of comparison
1176 * @return success/failure of operation
1177 */
1178gboolean lttv_apply_op_ge_uint(const gpointer v1, LttvFieldValue v2) {
1179 guint* r = (guint*) v1;
1180 return (*r >= v2.v_uint);
1181}
7145a073 1182
5b729fcf 1183/**
7e7af7f2 1184 * @fn gboolean lttv_apply_op_ge_uint64(gpointer,LttvFieldValue)
56e29124 1185 *
83aa92fc 1186 * Applies the 'greater or equal' operator to the
47aa6e58 1187 * specified structure and value
1188 * @param v1 left member of comparison
1189 * @param v2 right member of comparison
5b729fcf 1190 * @return success/failure of operation
1191 */
4d9ff942 1192gboolean lttv_apply_op_ge_uint64(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1193 guint64* r = (guint64*) v1;
9ab5ebd7 1194 return (*r >= v2.v_uint64);
83aa92fc 1195}
150f0d33 1196
1197/**
7e7af7f2 1198 * @fn gboolean lttv_apply_op_ge_uint32(gpointer,LttvFieldValue)
56e29124 1199 *
150f0d33 1200 * Applies the 'greater or equal' operator to the
47aa6e58 1201 * specified structure and value
1202 * @param v1 left member of comparison
1203 * @param v2 right member of comparison
150f0d33 1204 * @return success/failure of operation
1205 */
4d9ff942 1206gboolean lttv_apply_op_ge_uint32(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1207 guint32* r = (guint32*) v1;
9ab5ebd7 1208 return (*r >= v2.v_uint32);
83aa92fc 1209}
150f0d33 1210
5b729fcf 1211/**
7e7af7f2 1212 * @fn gboolean lttv_apply_op_ge_uint16(gpointer,LttvFieldValue)
56e29124 1213 *
5b729fcf 1214 * Applies the 'greater or equal' operator to the
47aa6e58 1215 * specified structure and value
1216 * @param v1 left member of comparison
1217 * @param v2 right member of comparison
5b729fcf 1218 * @return success/failure of operation
1219 */
4d9ff942 1220gboolean lttv_apply_op_ge_uint16(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1221 guint16* r = (guint16*) v1;
9ab5ebd7 1222 return (*r >= v2.v_uint16);
83aa92fc 1223}
150f0d33 1224
5b729fcf 1225/**
7e7af7f2 1226 * @fn gboolean lttv_apply_op_ge_double(gpointer,LttvFieldValue)
56e29124 1227 *
5b729fcf 1228 * Applies the 'greater or equal' operator to the
47aa6e58 1229 * specified structure and value
1230 * @param v1 left member of comparison
1231 * @param v2 right member of comparison
5b729fcf 1232 * @return success/failure of operation
1233 */
4d9ff942 1234gboolean lttv_apply_op_ge_double(const gpointer v1, LttvFieldValue v2) {
83aa92fc 1235 double* r = (double*) v1;
9ab5ebd7 1236 return (*r >= v2.v_double);
83aa92fc 1237}
150f0d33 1238
7145a073 1239/**
7e7af7f2 1240 * @fn gboolean lttv_apply_op_ge_ltttime(gpointer,LttvFieldValue)
7145a073 1241 *
1242 * Applies the 'greater or equal' operator to the
1243 * specified structure and value
1244 * @param v1 left member of comparison
1245 * @param v2 right member of comparison
1246 * @return success/failure of operation
1247 */
4d9ff942 1248gboolean lttv_apply_op_ge_ltttime(const gpointer v1, LttvFieldValue v2) {
7145a073 1249 LttTime* r = (LttTime*) v1;
c6832b57 1250// 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)));
1251 return ltt_time_compare(*r, v2.v_ltttime)>-1?1:0;
7145a073 1252}
1253
1254
150f0d33 1255
1256/**
56e29124 1257 * Makes a copy of the current filter tree
1258 * @param tree pointer to the current tree
1259 * @return new copy of the filter tree
150f0d33 1260 */
1261LttvFilterTree*
4d9ff942 1262lttv_filter_tree_clone(const LttvFilterTree* tree) {
150f0d33 1263
8c89f5a8 1264 LttvFilterTree* newtree = lttv_filter_tree_new();
150f0d33 1265
8c89f5a8 1266 newtree->node = tree->node;
1267
1268 newtree->left = tree->left;
1269 if(newtree->left == LTTV_TREE_NODE) {
1270 newtree->l_child.t = lttv_filter_tree_clone(tree->l_child.t);
1271 } else if(newtree->left == LTTV_TREE_LEAF) {
1272 newtree->l_child.leaf = lttv_simple_expression_new();
1273 newtree->l_child.leaf->field = tree->l_child.leaf->field;
1274 newtree->l_child.leaf->offset = tree->l_child.leaf->offset;
1275 newtree->l_child.leaf->op = tree->l_child.leaf->op;
9ab5ebd7 1276 /* FIXME: special case for string copy ! */
1277 newtree->l_child.leaf->value = tree->l_child.leaf->value;
8c89f5a8 1278 }
1279
1280 newtree->right = tree->right;
1281 if(newtree->right == LTTV_TREE_NODE) {
1282 newtree->r_child.t = lttv_filter_tree_clone(tree->r_child.t);
1283 } else if(newtree->right == LTTV_TREE_LEAF) {
1284 newtree->r_child.leaf = lttv_simple_expression_new();
1285 newtree->r_child.leaf->field = tree->r_child.leaf->field;
1286 newtree->r_child.leaf->offset = tree->r_child.leaf->offset;
1287 newtree->r_child.leaf->op = tree->r_child.leaf->op;
9ab5ebd7 1288 newtree->r_child.leaf->value = tree->r_child.leaf->value;
8c89f5a8 1289 }
1290
1291 return newtree;
1292
150f0d33 1293}
1294
1295/**
56e29124 1296 * Makes a copy of the current filter
1297 * @param filter pointer to the current filter
1298 * @return new copy of the filter
150f0d33 1299 */
1300LttvFilter*
4d9ff942 1301lttv_filter_clone(const LttvFilter* filter) {
ebcead4a 1302
571ef1ed 1303 if(!filter) return NULL;
ebcead4a 1304
150f0d33 1305 LttvFilter* newfilter = g_new(LttvFilter,1);
1306
150f0d33 1307 strcpy(newfilter->expression,filter->expression);
1308
1309 newfilter->head = lttv_filter_tree_clone(filter->head);
1310
1311 return newfilter;
1312
1313}
1314
1315
84a333d6 1316/**
56e29124 1317 * @fn LttvFilter* lttv_filter_new()
1318 *
571ef1ed 1319 * Creates a new LttvFilter
1320 * @return the current LttvFilter or NULL if error
31452f49 1321 */
2ea36caf 1322LttvFilter*
5f185a2b 1323lttv_filter_new() {
a4c292d4 1324
5f185a2b 1325 LttvFilter* filter = g_new(LttvFilter,1);
1326 filter->expression = NULL;
1327 filter->head = NULL;
7e7af7f2 1328
1329 return filter;
5f185a2b 1330
1331}
a4c292d4 1332
8c89f5a8 1333/**
56e29124 1334 * @fn gboolean lttv_filter_update(LttvFilter*)
1335 *
8c89f5a8 1336 * Updates the current LttvFilter by building
1337 * its tree based upon the expression string
1338 * @param filter pointer to the current LttvFilter
1339 * @return Failure/Success of operation
1340 */
5f185a2b 1341gboolean
1342lttv_filter_update(LttvFilter* filter) {
1343
571ef1ed 1344// g_print("filter::lttv_filter_new()\n"); /* debug */
5f185a2b 1345
1346 if(filter->expression == NULL) return FALSE;
1347
571ef1ed 1348 int
a4c292d4 1349 i,
571ef1ed 1350 p_nesting=0, /* parenthesis nesting value */
72911c5d 1351 not=0;
571ef1ed 1352 guint expression_len;
72911c5d 1353
1601b365 1354 /* trees */
5b729fcf 1355 LttvFilterTree
1601b365 1356 *tree = lttv_filter_tree_new(), /* main tree */
1357 *subtree = NULL, /* buffer for subtrees */
1358 *t1, /* buffer #1 */
72911c5d 1359 *t2, /* buffer #2 */
1360 *t3; /* buffer #3 */
1601b365 1361
5f185a2b 1362 /*
1363 * the filter
1364 * If the tree already exists,
1365 * destroy it and build a new one
1366 */
1367 if(filter->head != NULL) lttv_filter_tree_destroy(filter->head);
f3020899 1368 filter->head = NULL; /* will be assigned at the end */
5f185a2b 1369
1601b365 1370 /*
1371 * Tree Stack
f4e9dd16 1372 * each element of the list
1373 * is a sub tree created
1374 * by the use of parenthesis in the
1375 * global expression. The final tree
1601b365 1376 * will be the one left at the root of
f4e9dd16 1377 * the list
1378 */
18d1226f 1379 GPtrArray *tree_stack = g_ptr_array_new();
1380 g_ptr_array_add( tree_stack,(gpointer) tree );
f4e9dd16 1381
a4c292d4 1382 /* temporary values */
0769c82f 1383 GString *a_field_component = g_string_new("");
ef2b07c1 1384 GString *a_string_spaces = g_string_new("");
56e29124 1385 GPtrArray *a_field_path = g_ptr_array_new();
1386
1387 /* simple expression buffer */
389ba50e 1388 LttvSimpleExpression* a_simple_expression = lttv_simple_expression_new();
d564d2ad 1389
1390 gint nest_quotes = 0;
0769c82f 1391
a4c292d4 1392 /*
571ef1ed 1393 * Parse entire expression and construct
1394 * the binary tree. There are two steps
1395 * in browsing that string
1396 * 1. finding boolean ops " &,|,^,! " and parenthesis " {,(,[,],),} "
1397 * 2. finding simple expressions
1398 * - field path ( separated by dots )
1399 * - op ( >, <, =, >=, <=, !=)
1400 * - value ( integer, string ... )
1401 * To spare computing time, the whole
1402 * string is parsed in this loop for a
1403 * O(n) complexity order.
1601b365 1404 *
18d1226f 1405 * When encountering logical op &,|,^
1406 * 1. parse the last value if any
1407 * 2. create a new tree
1408 * 3. add the expression (simple exp, or exp (subtree)) to the tree
1409 * 4. concatenate this tree with the current tree on top of the stack
1410 * When encountering math ops >,>=,<,<=,=,!=
1411 * 1. add to op to the simple expression
1412 * 2. concatenate last field component to field path
1413 * When encountering concatening ops .
1414 * 1. concatenate last field component to field path
1415 * When encountering opening parenthesis (,{,[
1416 * 1. create a new subtree on top of tree stack
1417 * When encountering closing parenthesis ),},]
1418 * 1. add the expression on right child of the current tree
1419 * 2. the subtree is completed, allocate a new subtree
1420 * 3. pop the tree value from the tree stack
1421 */
be66ef34 1422
1423#ifdef TEST
1424 struct timeval starttime;
1425 struct timeval endtime;
1426 gettimeofday(&starttime, NULL);
1427#endif
18d1226f 1428
571ef1ed 1429 expression_len = strlen(filter->expression);
1430 for(i=0;i<expression_len;i++) {
5f185a2b 1431 // debug
72911c5d 1432// g_print("%c\n ",filter->expression[i]);
d564d2ad 1433 if(nest_quotes) {
1434 switch(filter->expression[i]) {
571ef1ed 1435 case '\\' :
1436 if(filter->expression[i+1] == '\"') {
1437 i++;
1438 }
1439 break;
2db17921 1440 case '\"':
571ef1ed 1441 nest_quotes = 0;
2db17921 1442 i++;
571ef1ed 1443 break;
d564d2ad 1444 }
1445 if(a_string_spaces->len != 0) {
1446 a_field_component = g_string_append(
1447 a_field_component, a_string_spaces->str);
2db17921 1448 a_string_spaces = g_string_set_size(a_string_spaces, 0);
d564d2ad 1449 }
1450 a_field_component = g_string_append_c(a_field_component,
1451 filter->expression[i]);
1452 continue;
1453 }
1454
5f185a2b 1455 switch(filter->expression[i]) {
a4c292d4 1456 /*
1457 * logical operators
1458 */
1459 case '&': /* and */
72911c5d 1460
1461 /* get current tree in tree stack */
5b729fcf 1462 t1 = (LttvFilterTree*)g_ptr_array_index(tree_stack,tree_stack->len-1);
72911c5d 1463
1464 /* get current node at absolute right */
9ab5ebd7 1465 while(t1->right != LTTV_TREE_IDLE) {
1466 g_assert(t1->right == LTTV_TREE_NODE);
1467 t1 = t1->r_child.t;
1468 }
18d1226f 1469 t2 = lttv_filter_tree_new();
0cdc2470 1470 t2->node = LTTV_LOGICAL_AND;
72911c5d 1471 t1->right = LTTV_TREE_NODE;
1472 t1->r_child.t = t2;
1473 if(not) { /* add not operator to tree */
1474 t3 = lttv_filter_tree_new();
1475 t3->node = LTTV_LOGICAL_NOT;
1476 t2->left = LTTV_TREE_NODE;
1477 t2->l_child.t = t3;
72911c5d 1478 t2 = t3;
1479 not = 0;
72911c5d 1480 }
bb87caa7 1481 if(subtree != NULL) { /* append subtree to current tree */
18d1226f 1482 t2->left = LTTV_TREE_NODE;
1483 t2->l_child.t = subtree;
f4e9dd16 1484 subtree = NULL;
bb87caa7 1485 } else { /* append a simple expression */
9ab5ebd7 1486 lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE));
18d1226f 1487 a_field_component = g_string_new("");
571ef1ed 1488 g_string_free(a_string_spaces, TRUE);
1489 a_string_spaces = g_string_new("");
18d1226f 1490 t2->left = LTTV_TREE_LEAF;
0cdc2470 1491 t2->l_child.leaf = a_simple_expression;
389ba50e 1492 a_simple_expression = lttv_simple_expression_new();
f4e9dd16 1493 }
f4e9dd16 1494 break;
aa4600f3 1495
a4c292d4 1496 case '|': /* or */
aa4600f3 1497
e00d6a24 1498 t1 = (LttvFilterTree*)g_ptr_array_index(tree_stack,tree_stack->len-1);
9ab5ebd7 1499 while(t1->right != LTTV_TREE_IDLE) {
1500 g_assert(t1->right == LTTV_TREE_NODE);
1501 t1 = t1->r_child.t;
1502 }
1601b365 1503 t2 = lttv_filter_tree_new();
0cdc2470 1504 t2->node = LTTV_LOGICAL_OR;
72911c5d 1505 t1->right = LTTV_TREE_NODE;
1506 t1->r_child.t = t2;
1507 if(not) { // add not operator to tree
1508 t3 = lttv_filter_tree_new();
1509 t3->node = LTTV_LOGICAL_NOT;
1510 t2->left = LTTV_TREE_NODE;
1511 t2->l_child.t = t3;
1512 t2 = t3;
1513 not = 0;
1514 }
1515 if(subtree != NULL) { /* append subtree to current tree */
1601b365 1516 t2->left = LTTV_TREE_NODE;
1517 t2->l_child.t = subtree;
1518 subtree = NULL;
72911c5d 1519 } else { /* append a simple expression */
9ab5ebd7 1520 lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE));
1601b365 1521 a_field_component = g_string_new("");
571ef1ed 1522 g_string_free(a_string_spaces, TRUE);
1523 a_string_spaces = g_string_new("");
1601b365 1524 t2->left = LTTV_TREE_LEAF;
0cdc2470 1525 t2->l_child.leaf = a_simple_expression;
389ba50e 1526 a_simple_expression = lttv_simple_expression_new();
1601b365 1527 }
f4e9dd16 1528 break;
aa4600f3 1529
a4c292d4 1530 case '^': /* xor */
aa4600f3 1531
e00d6a24 1532 t1 = (LttvFilterTree*)g_ptr_array_index(tree_stack,tree_stack->len-1);
9ab5ebd7 1533 while(t1->right != LTTV_TREE_IDLE) {
1534 g_assert(t1->right == LTTV_TREE_NODE);
1535 t1 = t1->r_child.t;
1536 }
1601b365 1537 t2 = lttv_filter_tree_new();
0cdc2470 1538 t2->node = LTTV_LOGICAL_XOR;
72911c5d 1539 t1->right = LTTV_TREE_NODE;
1540 t1->r_child.t = t2;
1541 if(not) { // add not operator to tree
1542 t3 = lttv_filter_tree_new();
1543 t3->node = LTTV_LOGICAL_NOT;
1544 t2->left = LTTV_TREE_NODE;
1545 t2->l_child.t = t3;
1546 t2 = t3;
1547 not = 0;
1548 }
bb87caa7 1549 if(subtree != NULL) { /* append subtree to current tree */
1601b365 1550 t2->left = LTTV_TREE_NODE;
1551 t2->l_child.t = subtree;
1552 subtree = NULL;
bb87caa7 1553 } else { /* append a simple expression */
9ab5ebd7 1554 lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE));
1601b365 1555 a_field_component = g_string_new("");
571ef1ed 1556 g_string_free(a_string_spaces, TRUE);
1557 a_string_spaces = g_string_new("");
1601b365 1558 t2->left = LTTV_TREE_LEAF;
0cdc2470 1559 t2->l_child.leaf = a_simple_expression;
389ba50e 1560 a_simple_expression = lttv_simple_expression_new();
1601b365 1561 }
a4c292d4 1562 break;
aa4600f3 1563
a4c292d4 1564 case '!': /* not, or not equal (math op) */
aa4600f3 1565
5f185a2b 1566 if(filter->expression[i+1] == '=') { /* != */
0cdc2470 1567 g_ptr_array_add( a_field_path,(gpointer) a_field_component );
9ab5ebd7 1568 lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
0cdc2470 1569 a_field_component = g_string_new("");
571ef1ed 1570 g_string_free(a_string_spaces, TRUE);
1571 a_string_spaces = g_string_new("");
56e29124 1572 lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_NE);
aa4600f3 1573 i++;
a4c292d4 1574 } else { /* ! */
72911c5d 1575 not=1;
a4c292d4 1576 }
1577 break;
aa4600f3 1578
a4c292d4 1579 case '(': /* start of parenthesis */
91ad3f0a 1580 case '[':
1581 case '{':
aa4600f3 1582
91ad3f0a 1583 p_nesting++; /* incrementing parenthesis nesting value */
1601b365 1584 t1 = lttv_filter_tree_new();
72911c5d 1585 if(not) { /* add not operator to tree */
1586 t3 = lttv_filter_tree_new();
1587 t3->node = LTTV_LOGICAL_NOT;
1588 t1->right = LTTV_TREE_NODE;
1589 t1->r_child.t = t3;
1590 not = 0;
1591 }
1601b365 1592 g_ptr_array_add( tree_stack,(gpointer) t1 );
a4c292d4 1593 break;
aa4600f3 1594
a4c292d4 1595 case ')': /* end of parenthesis */
91ad3f0a 1596 case ']':
1597 case '}':
aa4600f3 1598
91ad3f0a 1599 p_nesting--; /* decrementing parenthesis nesting value */
18d1226f 1600 if(p_nesting<0 || tree_stack->len<2) {
f4e9dd16 1601 g_warning("Wrong filtering options, the string\n\"%s\"\n\
571ef1ed 1602 is not valid due to parenthesis incorrect use",filter->expression);
5f185a2b 1603 return FALSE;
f4e9dd16 1604 }
56e29124 1605
1606 /* there must at least be the root tree left in the array */
18d1226f 1607 g_assert(tree_stack->len>0);
72911c5d 1608
1609 t1 = g_ptr_array_index(tree_stack,tree_stack->len-1);
1610 while(t1->right != LTTV_TREE_IDLE) {
1611 t1 = t1->r_child.t;
1612 }
1613 if(not) { // add not operator to tree
1614 g_print("ici");
1615 t3 = lttv_filter_tree_new();
1616 t3->node = LTTV_LOGICAL_NOT;
1617 t1->right = LTTV_TREE_NODE;
1618 t1->r_child.t = t3;
1619 t1 = t3;
1620 not = 0;
1621 }
bb87caa7 1622 if(subtree != NULL) { /* append subtree to current tree */
18d1226f 1623 t1->right = LTTV_TREE_NODE;
1624 t1->r_child.t = subtree;
1625 subtree = g_ptr_array_index(tree_stack,tree_stack->len-1);
1626 g_ptr_array_remove_index(tree_stack,tree_stack->len-1);
bb87caa7 1627 } else { /* assign subtree as current tree */
9ab5ebd7 1628 lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE));
18d1226f 1629 a_field_component = g_string_new("");
571ef1ed 1630 g_string_free(a_string_spaces, TRUE);
1631 a_string_spaces = g_string_new("");
18d1226f 1632 t1->right = LTTV_TREE_LEAF;
0cdc2470 1633 t1->r_child.leaf = a_simple_expression;
389ba50e 1634 a_simple_expression = lttv_simple_expression_new();
9ab5ebd7 1635 subtree = g_ptr_array_remove_index(tree_stack,tree_stack->len-1);
18d1226f 1636 }
a4c292d4 1637 break;
1638
571ef1ed 1639 /*
1640 * mathematic operators
a4c292d4 1641 */
1642 case '<': /* lower, lower or equal */
aa4600f3 1643
1644 g_ptr_array_add( a_field_path,(gpointer) a_field_component );
9ab5ebd7 1645 lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
aa4600f3 1646 a_field_component = g_string_new("");
571ef1ed 1647 g_string_free(a_string_spaces, TRUE);
1648 a_string_spaces = g_string_new("");
5f185a2b 1649 if(filter->expression[i+1] == '=') { /* <= */
a4c292d4 1650 i++;
56e29124 1651 lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_LE);
1652 } else lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_LT);
aa4600f3 1653 break;
1654
1655 case '>': /* higher, higher or equal */
1656
1657 g_ptr_array_add( a_field_path,(gpointer) a_field_component );
9ab5ebd7 1658 lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
f4e9dd16 1659 a_field_component = g_string_new("");
571ef1ed 1660 g_string_free(a_string_spaces, TRUE);
1661 a_string_spaces = g_string_new("");
5f185a2b 1662 if(filter->expression[i+1] == '=') { /* >= */
a4c292d4 1663 i++;
56e29124 1664 lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_GE);
1665 } else lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_GT);
aa4600f3 1666 break;
1667
a4c292d4 1668 case '=': /* equal */
aa4600f3 1669
f4e9dd16 1670 g_ptr_array_add( a_field_path,(gpointer) a_field_component );
9ab5ebd7 1671 lttv_simple_expression_assign_field(a_field_path,a_simple_expression);
f4e9dd16 1672 a_field_component = g_string_new("");
571ef1ed 1673 g_string_free(a_string_spaces, TRUE);
1674 a_string_spaces = g_string_new("");
56e29124 1675 lttv_simple_expression_assign_operator(a_simple_expression,LTTV_FIELD_EQ);
a4c292d4 1676 break;
aa4600f3 1677
0769c82f 1678 /*
1679 * Field concatening caracter
1680 */
1681 case '.': /* dot */
aa4600f3 1682
bb87caa7 1683 /*
1684 * divide field expression into elements
1685 * in a_field_path array.
4d9ff942 1686 *
1687 * A dot can also be present in double values
bb87caa7 1688 */
8ff6243c 1689 if(a_simple_expression->field == LTTV_FILTER_UNDEFINED) {
bb87caa7 1690 g_ptr_array_add( a_field_path,(gpointer) a_field_component );
1691 a_field_component = g_string_new("");
571ef1ed 1692 g_string_free(a_string_spaces, TRUE);
1693 a_string_spaces = g_string_new("");
2db17921 1694 } else {
1695 /* Operator found, we are in the value field */
1696 g_string_append_c(a_field_component, filter->expression[i]);
8ff6243c 1697 }
1698 break;
ef2b07c1 1699 case ' ': /* keep spaces that are within a field component */
2db17921 1700 if(a_field_component->len == 0) break; /* ignore */
571ef1ed 1701 else
1702 a_string_spaces = g_string_append_c(a_string_spaces,
1703 filter->expression[i]);
ef2b07c1 1704
4d9ff942 1705 case '\n': /* ignore */
0769c82f 1706 break;
d564d2ad 1707 case '\"':
1708 nest_quotes?(nest_quotes=0):(nest_quotes=1);
1709 break;
a4c292d4 1710 default: /* concatening current string */
d564d2ad 1711 if(a_string_spaces->len != 0) {
2db17921 1712 a_field_component = g_string_append(
4ec0c904 1713 a_field_component, a_string_spaces->str);
2db17921 1714 a_string_spaces = g_string_set_size(a_string_spaces, 0);
d564d2ad 1715 }
1716 a_field_component = g_string_append_c(a_field_component,
1717 filter->expression[i]);
a4c292d4 1718 }
1719 }
1601b365 1720
0cdc2470 1721 /*
1722 * Preliminary check to see
1723 * if tree was constructed correctly
1724 */
1725 if( p_nesting>0 ) {
1726 g_warning("Wrong filtering options, the string\n\"%s\"\n\
571ef1ed 1727 is not valid due to parenthesis incorrect use",filter->expression);
5f185a2b 1728 return FALSE;
0cdc2470 1729 }
1730
1731 if(tree_stack->len != 1) /* only root tree should remain */
5f185a2b 1732 return FALSE;
1601b365 1733
72911c5d 1734 /*
1735 * processing last element of expression
1736 */
410c83da 1737 t1 = g_ptr_array_index(tree_stack,tree_stack->len-1);
9ab5ebd7 1738 while(t1->right != LTTV_TREE_IDLE) {
1739 g_assert(t1->right == LTTV_TREE_NODE);
1740 t1 = t1->r_child.t;
1741 }
72911c5d 1742 if(not) { // add not operator to tree
1743 t3 = lttv_filter_tree_new();
1744 t3->node = LTTV_LOGICAL_NOT;
1745 t1->right = LTTV_TREE_NODE;
1746 t1->r_child.t = t3;
1747 t1 = t3;
1748 not = 0;
1749 }
410c83da 1750 if(subtree != NULL) { /* add the subtree */
1751 t1->right = LTTV_TREE_NODE;
0cdc2470 1752 t1->r_child.t = subtree;
410c83da 1753 subtree = NULL;
1754 } else { /* add a leaf */
9ab5ebd7 1755 lttv_simple_expression_assign_value(a_simple_expression,g_string_free(a_field_component,FALSE));
56e29124 1756 a_field_component = NULL;
571ef1ed 1757 g_string_free(a_string_spaces, TRUE);
1758 a_string_spaces = NULL;
410c83da 1759 t1->right = LTTV_TREE_LEAF;
0cdc2470 1760 t1->r_child.leaf = a_simple_expression;
56e29124 1761 a_simple_expression = NULL;
410c83da 1762 }
1763
56e29124 1764
73050a5f 1765 /* free the pointer array */
1766 g_assert(a_field_path->len == 0);
1767 g_ptr_array_free(a_field_path,TRUE);
56e29124 1768
1769 /* free the tree stack -- but keep the root tree */
9354c7da 1770 filter->head = ltt_g_ptr_array_remove_index_slow(tree_stack,0);
f3020899 1771 g_ptr_array_free(tree_stack,TRUE);
1772
56e29124 1773 /* free the field buffer if allocated */
1774 if(a_field_component != NULL) g_string_free(a_field_component,TRUE);
571ef1ed 1775 if(a_string_spaces != NULL) g_string_free(a_string_spaces, TRUE);
ef2b07c1 1776
56e29124 1777 /* free the simple expression buffer if allocated */
1778 if(a_simple_expression != NULL) lttv_simple_expression_destroy(a_simple_expression);
73050a5f 1779
f3020899 1780 g_assert(filter->head != NULL); /* tree should exist */
56e29124 1781 g_assert(subtree == NULL); /* remaining subtree should be included in main tree */
be66ef34 1782
1783#ifdef TEST
1784 gettimeofday(&endtime, NULL);
1785
1786 /* Calcul du temps de l'algorithme */
1787 double time1 = starttime.tv_sec + (starttime.tv_usec/1000000.0);
1788 double time2 = endtime.tv_sec + (endtime.tv_usec/1000000.0);
1789// g_print("Tree build took %.10f ms for strlen of %i\n",(time2-time1)*1000,strlen(filter->expression));
1790 g_print("%.10f %i\n",(time2-time1)*1000,strlen(filter->expression));
1791#endif
a4c292d4 1792
56e29124 1793 /* debug */
c2a4581e 1794 g_debug("+++++++++++++++ BEGIN PRINT ++++++++++++++++\n");
72911c5d 1795 lttv_print_tree(filter->head,0) ;
c2a4581e 1796 g_debug("+++++++++++++++ END PRINT ++++++++++++++++++\n");
56e29124 1797
1798 /* success */
5f185a2b 1799 return TRUE;
80f9611a 1800
31452f49 1801}
1802
8c89f5a8 1803/**
56e29124 1804 * @fn void lttv_filter_destroy(LttvFilter*)
1805 *
8c89f5a8 1806 * Destroy the current LttvFilter
1807 * @param filter pointer to the current LttvFilter
1808 */
1da1525d 1809void
2ea36caf 1810lttv_filter_destroy(LttvFilter* filter) {
5f185a2b 1811
571ef1ed 1812 if(!filter) return;
ebcead4a 1813
571ef1ed 1814 if(filter->expression)
1815 g_free(filter->expression);
1816 if(filter->head)
1817 lttv_filter_tree_destroy(filter->head);
5f185a2b 1818 g_free(filter);
1819
1da1525d 1820}
1821
150f0d33 1822/**
8ff6243c 1823 * @fn LttvFilterTree* lttv_filter_tree_new()
56e29124 1824 *
150f0d33 1825 * Assign a new tree for the current expression
1826 * or sub expression
1827 * @return pointer of LttvFilterTree
1828 */
5f185a2b 1829LttvFilterTree*
1830lttv_filter_tree_new() {
150f0d33 1831 LttvFilterTree* tree;
1832
e00d6a24 1833 tree = g_new(LttvFilterTree,1);
150f0d33 1834 tree->node = 0; //g_new(lttv_expression,1);
150f0d33 1835 tree->left = LTTV_TREE_IDLE;
1836 tree->right = LTTV_TREE_IDLE;
f3020899 1837 tree->r_child.t = NULL;
1838 tree->l_child.t = NULL;
1839
150f0d33 1840 return tree;
1841}
1842
80f9611a 1843/**
56e29124 1844 * @fn void lttv_filter_append_expression(LttvFilter*,char*)
1845 *
80f9611a 1846 * Append a new expression to the expression
1847 * defined in the current filter
1848 * @param filter pointer to the current LttvFilter
1849 * @param expression string that must be appended
56e29124 1850 * @return Success/Failure of operation
80f9611a 1851 */
be66ef34 1852gboolean
1853lttv_filter_append_expression(LttvFilter* filter, const char *expression) {
80f9611a 1854
56e29124 1855 if(expression == NULL) return FALSE;
da2e1bfb 1856 if(filter == NULL) return FALSE;
0bc23ba9 1857 if(expression[0] == '\0') return FALSE; /* Empty expression */
80f9611a 1858
da2e1bfb 1859 GString* s = g_string_new("");
1860 if(filter->expression != NULL) {
4ec0c904 1861 s = g_string_append(s,filter->expression);
1862 s = g_string_append_c(s,'&');
da2e1bfb 1863 }
4ec0c904 1864 s = g_string_append(s,expression);
786c5c3b 1865
1866 g_free(filter->expression);
da2e1bfb 1867 filter->expression = g_string_free(s,FALSE);
1868
1869 /* TRUE if construction of tree proceeded without errors */
56e29124 1870 return lttv_filter_update(filter);
80f9611a 1871
1872}
1873
1874/**
56e29124 1875 * @fn void lttv_filter_clear_expression(LttvFilter*)
1876 *
80f9611a 1877 * Clear the filter expression from the
1878 * current filter and sets its pointer to NULL
1879 * @param filter pointer to the current LttvFilter
1880 */
be66ef34 1881void
1882lttv_filter_clear_expression(LttvFilter* filter) {
80f9611a 1883
1884 if(filter->expression != NULL) {
1885 g_free(filter->expression);
1886 filter->expression = NULL;
1887 }
1888
1889}
1890
150f0d33 1891/**
56e29124 1892 * @fn void lttv_filter_tree_destroy(LttvFilterTree*)
1893 *
150f0d33 1894 * Destroys the tree and his sub-trees
1895 * @param tree Tree which must be destroyed
1896 */
5f185a2b 1897void
1898lttv_filter_tree_destroy(LttvFilterTree* tree) {
56e29124 1899
150f0d33 1900 if(tree == NULL) return;
1901
56e29124 1902 if(tree->left == LTTV_TREE_LEAF) lttv_simple_expression_destroy(tree->l_child.leaf);
150f0d33 1903 else if(tree->left == LTTV_TREE_NODE) lttv_filter_tree_destroy(tree->l_child.t);
1904
56e29124 1905 if(tree->right == LTTV_TREE_LEAF) lttv_simple_expression_destroy(tree->r_child.leaf);
150f0d33 1906 else if(tree->right == LTTV_TREE_NODE) lttv_filter_tree_destroy(tree->r_child.t);
1907
e00d6a24 1908// g_free(tree->node);
150f0d33 1909 g_free(tree);
1910}
1911
84a333d6 1912/**
80f9611a 1913 * Global parsing function for the current
1914 * LttvFilterTree
7e7af7f2 1915 * @param t pointer to the current LttvFilterTree
80f9611a 1916 * @param event current LttEvent, NULL if not used
1917 * @param tracefile current LttTracefile, NULL if not used
1918 * @param trace current LttTrace, NULL if not used
1919 * @param state current LttvProcessState, NULL if not used
4d9ff942 1920 * @param context current LttvTracefileContext, NULL if not used
1921 * @return response of filter
84a333d6 1922 */
31452f49 1923gboolean
80f9611a 1924lttv_filter_tree_parse(
4d9ff942 1925 const LttvFilterTree* t,
1926 const LttEvent* event,
1927 const LttTracefile* tracefile,
1928 const LttTrace* trace,
b6ef18af 1929 const LttvTracefileContext* context,
1930 const LttvProcessState* state,
1931 const LttvTraceContext* tc
80f9611a 1932 /*,...*/)
1933{
0769c82f 1934
80f9611a 1935 /*
1601b365 1936 * Each tree is parsed in inorder.
1937 * This way, it's possible to apply the left filter of the
1938 * tree, then decide whether or not the right branch should
1939 * be parsed depending on the linking logical operator
1940 *
80f9611a 1941 * Each node consists in a
1942 * 1. logical operator
1943 * 2. left child ( node or simple expression )
1944 * 3. right child ( node or simple expression )
1945 *
1946 * When the child is a simple expression, we must
1947 * before all determine if the expression refers to
1948 * a structure which is whithin observation ( not NULL ).
1949 * -If so, the expression is evaluated.
1950 * -If not, the result is set to TRUE since this particular
1951 * operation does not interfere with the lttv structure
1952 *
1953 * The result of each simple expression will directly
1954 * affect the next branch. This way, depending on
1955 * the linking logical operator, the parser will decide
1956 * to explore or not the next branch.
1957 * 1. AND OPERATOR
1958 * -If result of left branch is 0 / FALSE
1959 * then don't explore right branch and return 0;
1960 * -If result of left branch is 1 / TRUE then explore
1961 * 2. OR OPERATOR
1962 * -If result of left branch is 1 / TRUE
1963 * then don't explore right branch and return 1;
1964 * -If result of left branch is 0 / FALSE then explore
1965 * 3. XOR OPERATOR
56e29124 1966 * -Result of left branch will not affect exploration of
80f9611a 1967 * right branch
1601b365 1968 */
73050a5f 1969
80f9611a 1970 gboolean lresult = FALSE, rresult = FALSE;
33e44b82 1971
43ed82b5 1972 LttvTraceState *ts = NULL;
ae3d0f50 1973 LttvTracefileState *tfs = (LttvTracefileState*)context;
b6ef18af 1974 if(tc)
1975 ts = (LttvTraceState*)tc;
1976 else if(context)
1977 ts = (LttvTraceState*)context->t_context;
1978
1979 if(tfs) {
1980 guint cpu = tfs->cpu;
1981 if(ts)
1982 state = ts->running_process[cpu];
1983 }
0769c82f 1984
80f9611a 1985 /*
1986 * Parse left branch
1987 */
4d9ff942 1988 if(t->left == LTTV_TREE_NODE) {
b6ef18af 1989 lresult = lttv_filter_tree_parse(t->l_child.t,event,tracefile,trace,context,NULL,NULL);
4d9ff942 1990 }
5b729fcf 1991 else if(t->left == LTTV_TREE_LEAF) {
4d9ff942 1992 lresult = lttv_filter_tree_parse_branch(t->l_child.leaf,event,tracefile,trace,state,context);
0cdc2470 1993 }
4d9ff942 1994
80f9611a 1995 /*
1996 * Parse linking operator
1997 * make a cutoff if possible
1998 */
1999 if((t->node & LTTV_LOGICAL_OR) && lresult == TRUE) return TRUE;
2000 if((t->node & LTTV_LOGICAL_AND) && lresult == FALSE) return FALSE;
2001
2002 /*
2003 * Parse right branch
2004 */
4d9ff942 2005 if(t->right == LTTV_TREE_NODE) {
b6ef18af 2006 rresult = lttv_filter_tree_parse(t->r_child.t,event,tracefile,trace,context,NULL,NULL);
4d9ff942 2007 }
5b729fcf 2008 else if(t->right == LTTV_TREE_LEAF) {
4d9ff942 2009 rresult = lttv_filter_tree_parse_branch(t->r_child.leaf,event,tracefile,trace,state,context);
2010 }
2bdb97c5 2011
2bdb97c5 2012
4d9ff942 2013 /*
2014 * Apply and return the
2015 * logical link between the
2016 * two operation
2017 */
2018 switch(t->node) {
2019 case LTTV_LOGICAL_OR: return (lresult | rresult);
2020 case LTTV_LOGICAL_AND: return (lresult & rresult);
72911c5d 2021 case LTTV_LOGICAL_NOT:
2022 return (t->left==LTTV_TREE_LEAF)?!lresult:((t->right==LTTV_TREE_LEAF)?!rresult:TRUE);
4d9ff942 2023 case LTTV_LOGICAL_XOR: return (lresult ^ rresult);
2024 case 0: return (rresult);
2025 default:
2026 /*
2027 * This case should never be
2028 * parsed, if so, this subtree
2029 * is cancelled !
2030 */
2031 return TRUE;
2032 }
2033
2034}
2035
2036/**
4d9ff942 2037 * This function parses a particular branch of the tree
7e7af7f2 2038 * @param se pointer to the current LttvSimpleExpression
4d9ff942 2039 * @param event current LttEvent, NULL if not used
2040 * @param tracefile current LttTracefile, NULL if not used
2041 * @param trace current LttTrace, NULL if not used
2042 * @param state current LttvProcessState, NULL if not used
2043 * @param context current LttvTracefileContext, NULL if not used
2044 * @return response of filter
2045 */
be66ef34 2046gboolean
2047lttv_filter_tree_parse_branch(
4d9ff942 2048 const LttvSimpleExpression* se,
2049 const LttEvent* event,
2050 const LttTracefile* tracefile,
2051 const LttTrace* trace,
2052 const LttvProcessState* state,
2053 const LttvTracefileContext* context) {
2054
9ab5ebd7 2055 LttvFieldValue v;
4d9ff942 2056 v = se->value;
2057 switch(se->field) {
80f9611a 2058 case LTTV_FILTER_TRACE_NAME:
4d9ff942 2059 if(trace == NULL) return TRUE;
c6832b57 2060 else {
eed2ef37 2061 GQuark quark = ltt_trace_name(trace);
c6832b57 2062 return se->op((gpointer)&quark,v);
2063 }
80f9611a 2064 break;
2065 case LTTV_FILTER_TRACEFILE_NAME:
4d9ff942 2066 if(tracefile == NULL) return TRUE;
c6832b57 2067 else {
eed2ef37 2068 GQuark quark = ltt_tracefile_name(tracefile);
c6832b57 2069 return se->op((gpointer)&quark,v);
2070 }
80f9611a 2071 break;
2072 case LTTV_FILTER_STATE_PID:
4d9ff942 2073 if(state == NULL) return TRUE;
2074 else return se->op((gpointer)&state->pid,v);
80f9611a 2075 break;
2076 case LTTV_FILTER_STATE_PPID:
4d9ff942 2077 if(state == NULL) return TRUE;
2078 else return se->op((gpointer)&state->ppid,v);
80f9611a 2079 break;
2080 case LTTV_FILTER_STATE_CT:
4d9ff942 2081 if(state == NULL) return TRUE;
80f9611a 2082 else {
4d9ff942 2083 return se->op((gpointer)&state->creation_time,v);
80f9611a 2084 }
2085 break;
2086 case LTTV_FILTER_STATE_IT:
4d9ff942 2087 if(state == NULL) return TRUE;
80f9611a 2088 else {
4d9ff942 2089 return se->op((gpointer)&state->insertion_time,v);
80f9611a 2090 }
2091 break;
2092 case LTTV_FILTER_STATE_P_NAME:
4d9ff942 2093 if(state == NULL) return TRUE;
46c40a93 2094 else {
bbd9d557 2095 GQuark quark = state->name;
c6832b57 2096 return se->op((gpointer)&quark,v);
46c40a93 2097 }
80f9611a 2098 break;
d4dd4885 2099 case LTTV_FILTER_STATE_T_BRAND:
7b5f6cf1 2100 if(state == NULL) return TRUE;
2101 else {
2102 GQuark quark = state->brand;
2103 return se->op((gpointer)&quark,v);
2104 }
2105 break;
80f9611a 2106 case LTTV_FILTER_STATE_EX_MODE:
4d9ff942 2107 if(state == NULL) return TRUE;
2108 else return se->op((gpointer)&state->state->t,v);
80f9611a 2109 break;
2110 case LTTV_FILTER_STATE_EX_SUBMODE:
4d9ff942 2111 if(state == NULL) return TRUE;
2112 else return se->op((gpointer)&state->state->n,v);
80f9611a 2113 break;
2114 case LTTV_FILTER_STATE_P_STATUS:
4d9ff942 2115 if(state == NULL) return TRUE;
2116 else return se->op((gpointer)&state->state->s,v);
80f9611a 2117 break;
2118 case LTTV_FILTER_STATE_CPU:
e3162168 2119 if(state == NULL) return TRUE;
46c40a93 2120 else {
e3162168 2121 return se->op((gpointer)&state->cpu,v);
46c40a93 2122 }
80f9611a 2123 break;
2124 case LTTV_FILTER_EVENT_NAME:
6471e71f 2125 if(event == NULL) return TRUE;
2126 else {
2127 struct marker_info *info;
2128 GQuark qtuple[2];
2129 LttTracefile *tf = context->tf;
2130 qtuple[0] = ltt_tracefile_name(tracefile);
2131 info = marker_get_info_from_id(tf->mdata, event->event_id);
2132 g_assert(info != NULL);
2133 qtuple[1] = info->name;
2134 return se->op((gpointer)qtuple,v);
2135 }
2136 break;
2137 case LTTV_FILTER_EVENT_SUBNAME:
4d9ff942 2138 if(event == NULL) return TRUE;
2139 else {
0ad10e7f 2140 struct marker_info *info;
750eb11a 2141 LttTracefile *tf = context->tf;
2142 info = marker_get_info_from_id(tf->mdata, event->event_id);
0ad10e7f 2143 g_assert(info != NULL);
2144 GQuark quark = info->name;
ffd088ef 2145 return se->op((gpointer)&quark,v);
2146 }
2147 break;
80f9611a 2148 case LTTV_FILTER_EVENT_CATEGORY:
2149 /*
c6832b57 2150 * TODO: Not yet implemented
80f9611a 2151 */
4d9ff942 2152 return TRUE;
80f9611a 2153 break;
2154 case LTTV_FILTER_EVENT_TIME:
4d9ff942 2155 if(event == NULL) return TRUE;
46c40a93 2156 else {
2157 LttTime time = ltt_event_time(event);
4d9ff942 2158 return se->op((gpointer)&time,v);
46c40a93 2159 }
80f9611a 2160 break;
2161 case LTTV_FILTER_EVENT_TSC:
bbd9d557 2162 if(event == NULL) return TRUE;
2163 else {
2164 LttCycleCount count = ltt_event_cycle_count(event);
2165 return se->op((gpointer)&count,v);
2166 }
80f9611a 2167 break;
33bdc8dd 2168 case LTTV_FILTER_EVENT_TARGET_PID:
2169 if(context == NULL) return TRUE;
2170 else {
2171 guint target_pid =
2172 lttv_state_get_target_pid((LttvTracefileState*)context);
2173 return se->op((gpointer)&target_pid,v);
2174 }
2175 break;
80f9611a 2176 case LTTV_FILTER_EVENT_FIELD:
2177 /*
2178 * TODO: Use the offset to
2179 * find the dynamic field
2180 * in the event struct
2181 */
4d9ff942 2182 return TRUE;
80f9611a 2183 default:
2184 /*
2185 * This case should never be
4d9ff942 2186 * parsed, if so, the whole
2187 * filtering is cancelled
80f9611a 2188 */
2189 g_warning("Error while parsing the filter tree");
2190 return TRUE;
2191 }
4d9ff942 2192
2193 /* should never get here */
2194 return TRUE;
2195
80f9611a 2196}
0769c82f 2197
4d9ff942 2198
2199
80f9611a 2200/**
7e7af7f2 2201 * Debug function. Prints tree memory allocation.
56e29124 2202 * @param t the pointer to the current LttvFilterTree
80f9611a 2203 */
2204void
72911c5d 2205lttv_print_tree(const LttvFilterTree* t, const int count) {
0769c82f 2206
c2a4581e 2207 g_debug("node:%p lchild:%p rchild:%p depth:%i\n",t, //t->l_child.t,t->r_child.t);
80f9611a 2208 (t->left==LTTV_TREE_NODE)?t->l_child.t:NULL,
72911c5d 2209 (t->right==LTTV_TREE_NODE)?t->r_child.t:NULL,
2210 count);
c2a4581e 2211 g_debug("logic operator: %s\n",(t->node&1)?"OR":((t->node&2)?"AND":((t->node&4)?"NOT":((t->node&8)?"XOR":"IDLE"))));
2212 g_debug("|-> left branch %p is a %s\n",t->l_child.t,(t->left==LTTV_TREE_NODE)?"NODE":((t->left==LTTV_TREE_LEAF)?"LEAF":"IDLE"));
72911c5d 2213 if(t->left == LTTV_TREE_LEAF) {
c2a4581e 2214 g_debug("| |-> field type number: %i\n",t->l_child.leaf->field);
2215 g_debug("| |-> offset is: %i\n",t->l_child.leaf->offset);
2216 g_debug("| |-> operator function is: %p\n",t->l_child.leaf->op);
0769c82f 2217 }
c2a4581e 2218 g_debug("|-> right branch %p is a %s\n",t->r_child.t,(t->right==LTTV_TREE_NODE)?"NODE":((t->right==LTTV_TREE_LEAF)?"LEAF":"IDLE"));
72911c5d 2219 if(t->right == LTTV_TREE_LEAF) {
c2a4581e 2220 g_debug("| |-> field type number: %i\n",t->r_child.leaf->field);
2221 g_debug("| |-> offset is: %i\n",t->r_child.leaf->offset);
2222 g_debug("| |-> operator function is: %p\n",t->r_child.leaf->op);
80f9611a 2223 }
72911c5d 2224
2225 if(t->left == LTTV_TREE_NODE) lttv_print_tree(t->l_child.t,count+1);
2226 if(t->right == LTTV_TREE_NODE) lttv_print_tree(t->r_child.t,count+1);
80f9611a 2227}
2228
91ad3f0a 2229/**
56e29124 2230 * @fn static void module_init()
2231 *
91ad3f0a 2232 * Initializes the filter module and specific values
2233 */
1a7fa682 2234static void module_init()
2235{
91ad3f0a 2236
1a7fa682 2237}
2238
91ad3f0a 2239/**
7e7af7f2 2240 * Destroys the filter module and specific values
91ad3f0a 2241 */
1a7fa682 2242static void module_destroy()
2243{
56e29124 2244
1a7fa682 2245}
2246
2247
91ad3f0a 2248LTTV_MODULE("filter", "Filters traceset and events", \
2249 "Filters traceset and events specifically to user input", \
1a7fa682 2250 module_init, module_destroy)
2251
2252
2253
This page took 0.176348 seconds and 4 git commands to generate.