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