X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Ffilter.c;h=7bfcc25951d49762d81ee4cb6fb0bf46a36ed3f7;hb=f4e9dd16df04f26cdbe885ea7c9744d423fe6869;hp=aa29b2c5c521b70d77c23752e62908a1994789bd;hpb=1a7fa6824f9bd614ff78181c96d239b322411d7f;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/filter.c b/ltt/branches/poly/lttv/lttv/filter.c index aa29b2c5..7bfcc259 100644 --- a/ltt/branches/poly/lttv/lttv/filter.c +++ b/ltt/branches/poly/lttv/lttv/filter.c @@ -25,7 +25,7 @@ /* * YET TO BE ANSWERED - * - should all the structures and field types be associated with GQuarks + * - the exists an other lttv_filter which conflicts with this one */ #include @@ -58,7 +58,53 @@ GQuark LTTV_FILTER_TRACESET, LTTV_FILTER_TRACEFILE, LTTV_FILTER_STATE, - LTTV_FILTER_EVENT; + LTTV_FILTER_EVENT, + LTTV_FILTER_NAME, + LTTV_FILTER_CATEGORY, + LTTV_FILTER_TIME, + LTTV_FILTER_TSC, + LTTV_FILTER_PID, + LTTV_FILTER_PPID, + LTTV_FILTER_C_TIME, + LTTV_FILTER_I_TIME, + LTTV_FILTER_P_NAME, + LTTV_FILTER_EX_MODE, + LTTV_FILTER_EX_SUBMODE, + LTTV_FILTER_P_STATUS, + LTTV_FILTER_CPU; + +/** + * Assign a new tree for the current expression + * or sub expression + * @return pointer of lttv_filter_tree + */ +lttv_filter_tree* lttv_filter_tree_new() { + lttv_filter_tree* tree; + + tree = g_new(lttv_filter_tree,1); + tree->node = g_new(lttv_expression,1); + tree->node->type = LTTV_UNDEFINED_EXPRESSION; + tree->left = LTTV_TREE_UNDEFINED; + tree->right = LTTV_TREE_UNDEFINED; + + return tree; +} + +/** + * Destroys the tree and his sub-trees + * @param tree Tree which must be destroyed + */ +void lttv_filter_tree_destroy(lttv_filter_tree* tree) { + + if(tree->left == LTTV_TREE_LEAF) g_free(tree->l_child.leaf); + else if(tree->left == LTTV_TREE_NODE) lttv_filter_tree_destroy(tree->l_child.t); + + if(tree->right == LTTV_TREE_LEAF) g_free(tree->r_child.leaf); + else if(tree->right == LTTV_TREE_NODE) lttv_filter_tree_destroy(tree->r_child.t); + + g_free(tree->node); + g_free(tree); +} /** * Parse through filtering field hierarchy as specified @@ -68,31 +114,25 @@ GQuark * @return success/failure of operation */ gboolean -parse_field_path(GList* fp) { +parse_field_path(GPtrArray* fp) { - GString* f = g_list_first(fp)->data; + GString* f = NULL; + g_assert(f=g_ptr_array_index(fp,0)); //list_first(fp)->data; - switch(g_quark_try_string(f->str)) { - case LTTV_FILTER_TRACE: - - break; - case LTTV_FILTER_TRACEFILE: + if(g_quark_try_string(f->str) == LTTV_FILTER_EVENT) { +// parse_subfield(fp, LTTV_FILTER_EVENT); - break; - case LTTV_FILTER_TRACESET: - - break; - case LTTV_FILTER_STATE: + } else if(g_quark_try_string(f->str) == LTTV_FILTER_TRACEFILE) { + + } else if(g_quark_try_string(f->str) == LTTV_FILTER_TRACE) { - break; - case LTTV_FILTER_EVENT: + } else if(g_quark_try_string(f->str) == LTTV_FILTER_STATE) { - break; - default: /* Quark value unrecognized or equal to 0 */ - g_warning("Unrecognized field in filter string"); - return FALSE; + } else { + g_warning("Unrecognized field in filter string"); + return FALSE; } - return TRUE; + return TRUE; } /** @@ -116,42 +156,42 @@ parse_simple_expression(GString* expression) { * @param t pointer to the current LttvTrace * @return the current lttv_filter or NULL if error */ -lttv_filter* +lttv_filter_tree* lttv_filter_new(char *expression, LttvTraceState *tcs) { g_print("filter::lttv_filter_new()\n"); /* debug */ unsigned i, - p=0, /* parenthesis nesting value */ + p_nesting=0, /* parenthesis nesting value */ b=0; /* current breakpoint in expression string */ - - gpointer tree = NULL; + /* + * Main tree & Tree concatening list + * each element of the list + * is a sub tree created + * by the use of parenthesis in the + * global expression. The final tree + * will be the one created at the root of + * the list + */ + lttv_filter_tree* tree = NULL; + lttv_filter_tree* subtree = NULL; + lttv_filter_tree* current_tree = NULL; + GPtrArray *tree_list = g_ptr_array_new(); + g_ptr_array_add( tree_list,(gpointer) tree ); /* temporary values */ GString *a_field_component = g_string_new(""); - GList *a_field_path = NULL; + GPtrArray *a_field_path = NULL; + lttv_simple_expression a_simple_expression; - /* - * 1. parse expression - * 2. construct binary tree - * 3. return corresponding filter - */ - - /* - * Binary tree memory allocation - * - based upon a preliminary block size - */ - gulong size = (strlen(expression)/AVERAGE_EXPRESSION_LENGTH)*MAX_FACTOR; - tree = g_malloc(size*sizeof(lttv_filter_tree)); - /* * Parse entire expression and construct * the binary tree. There are two steps * in browsing that string - * 1. finding boolean ops ( &,|,^,! ) and parenthesis + * 1. finding boolean ops " &,|,^,! " and parenthesis " {,(,[,],),} " * 2. finding simple expressions * - field path ( separated by dots ) * - op ( >, <, =, >=, <=, !=) @@ -160,6 +200,10 @@ lttv_filter_new(char *expression, LttvTraceState *tcs) { * string is parsed in this loop for a * O(n) complexity order. */ + + a_field_path = g_ptr_array_new(); + g_ptr_array_set_size(a_field_path,2); /* by default, recording 2 field expressions */ + for(i=0;istr); switch(expression[i]) { @@ -167,10 +211,25 @@ lttv_filter_new(char *expression, LttvTraceState *tcs) { * logical operators */ case '&': /* and */ + a_simple_expression.value = a_field_component->str; + a_field_component = g_string_new(""); + lttv_filter_tree* t; + t = lttv_filter_tree_new(); + t->node->type = LTTV_EXPRESSION_OP; + t->node->e.op = LTTV_LOGICAL_AND; + if(subtree != NULL) { + t->left = LTTV_TREE_NODE; + t->l_child.t = subtree; + subtree = NULL; + } else { + t->left = LTTV_TREE_LEAF; + t->l_child.leaf = g_new(lttv_simple_expression,1); + } + + break; case '|': /* or */ + break; case '^': /* xor */ - g_list_append( a_field_path, a_field_component ); - a_field_component = g_string_new(""); break; case '!': /* not, or not equal (math op) */ if(expression[i+1] == '=') { /* != */ @@ -182,10 +241,37 @@ lttv_filter_new(char *expression, LttvTraceState *tcs) { } break; case '(': /* start of parenthesis */ - p++; /* incrementing parenthesis nesting value */ + case '[': + case '{': + p_nesting++; /* incrementing parenthesis nesting value */ + lttv_filter_tree* subtree = lttv_filter_tree_new(); + g_ptr_array_add( tree_list,(gpointer) subtree ); break; case ')': /* end of parenthesis */ - p--; /* decrementing parenthesis nesting value */ + case ']': + case '}': + p_nesting--; /* decrementing parenthesis nesting value */ + a_simple_expression.value = a_field_component->str; + a_field_component = g_string_new(""); + if(p_nesting<0 || tree_list->len<2) { + g_warning("Wrong filtering options, the string\n\"%s\"\n\ + is not valid due to parenthesis incorrect use",expression); + return NULL; + } + /* lttv_filter_tree *sub1 = g_ptr_array_index(tree_list,tree_list->len-1); + lttv_filter_tree *sub2 = g_ptr_array_index(tree_list,tree_list->len); + if(sub1->left == LTTV_TREE_UNDEFINED){ + sub1->l_child.t = sub2; + sub1->left = LTTV_TREE_NODE; + } else if(sub1->right == LTTV_TREE_UNDEFINED){ + sub1->r_child.t = sub2; + sub1->right = LTTV_TREE_NODE; + } else g_error("error during tree assignation"); + g_ptr_array_remove_index(tree_list,tree_list->len); + break; + */ + subtree = g_ptr_array_index(tree_list,tree_list->len); + g_ptr_array_remove_index(tree_list,tree_list->len); break; /* @@ -194,23 +280,29 @@ lttv_filter_new(char *expression, LttvTraceState *tcs) { case '<': /* lower, lower or equal */ if(expression[i+1] == '=') { /* <= */ i++; - a_simple_expression.op = LTTV_FIELD_LE; + a_simple_expression.op = LTTV_FIELD_LE; } else a_simple_expression.op = LTTV_FIELD_LT; + g_ptr_array_add( a_field_path,(gpointer) a_field_component ); + a_field_component = g_string_new(""); break; case '>': /* higher, higher or equal */ if(expression[i+1] == '=') { /* >= */ i++; - a_simple_expression.op = LTTV_FIELD_GE; + a_simple_expression.op = LTTV_FIELD_GE; } else a_simple_expression.op = LTTV_FIELD_GT; + g_ptr_array_add( a_field_path,(gpointer) a_field_component ); + a_field_component = g_string_new(""); break; case '=': /* equal */ a_simple_expression.op = LTTV_FIELD_EQ; + g_ptr_array_add( a_field_path,(gpointer) a_field_component ); + a_field_component = g_string_new(""); break; /* * Field concatening caracter */ case '.': /* dot */ - g_list_append( a_field_path, a_field_component ); + g_ptr_array_add( a_field_path,(gpointer) a_field_component ); a_field_component = g_string_new(""); break; default: /* concatening current string */ @@ -220,7 +312,7 @@ lttv_filter_new(char *expression, LttvTraceState *tcs) { - if( p>0 ) { + if( p_nesting>0 ) { g_warning("Wrong filtering options, the string\n\"%s\"\n\ is not valid due to parenthesis incorrect use",expression); return NULL; @@ -234,7 +326,7 @@ lttv_filter_new(char *expression, LttvTraceState *tcs) { * @return success/failure of operation */ gboolean -lttv_filter_tracefile(lttv_filter *filter, LttTracefile *tracefile) { +lttv_filter_tracefile(lttv_filter_t *filter, LttTracefile *tracefile) { @@ -265,7 +357,9 @@ lttv_filter_tracefile(lttv_filter *filter, LttTracefile *tracefile) { } gboolean -lttv_filter_tracestate(lttv_filter *filter, LttvTraceState *tracestate) {} +lttv_filter_tracestate(lttv_filter_t *filter, LttvTraceState *tracestate) { + +} /** * Apply the filter to a specific event @@ -274,27 +368,61 @@ lttv_filter_tracestate(lttv_filter *filter, LttvTraceState *tracestate) {} * @return success/failure of operation */ gboolean -lttv_filter_event(lttv_filter *filter, LttEvent *event) { +lttv_filter_event(lttv_filter_t *filter, LttEvent *event) { } +/** + * Initializes the filter module and specific values + */ static void module_init() { - LTTV_FILTER_EVENT = g_quark_from_string("event"); - LTTV_FILTER_TRACE = g_quark_from_string("trace"); - LTTV_FILTER_TRACESET = g_quark_from_string("traceset"); - LTTV_FILTER_STATE = g_quark_from_string("state"); - LTTV_FILTER_TRACEFILE = g_quark_from_string("tracefile"); + + /* + * Quarks initialization + * for hardcoded filtering options + * + * TODO: traceset has no yet been defined + */ + + /* top fields */ + LTTV_FILTER_EVENT = g_quark_from_string("event"); + LTTV_FILTER_TRACE = g_quark_from_string("trace"); + LTTV_FILTER_TRACESET = g_quark_from_string("traceset"); + LTTV_FILTER_STATE = g_quark_from_string("state"); + LTTV_FILTER_TRACEFILE = g_quark_from_string("tracefile"); + /* event.name, tracefile.name, trace.name */ + LTTV_FILTER_NAME = g_quark_from_string("name"); + + /* event sub fields */ + LTTV_FILTER_CATEGORY = g_quark_from_string("category"); + LTTV_FILTER_TIME = g_quark_from_string("time"); + LTTV_FILTER_TSC = g_quark_from_string("tsc"); + + /* state sub fields */ + LTTV_FILTER_PID = g_quark_from_string("pid"); + LTTV_FILTER_PPID = g_quark_from_string("ppid"); + LTTV_FILTER_C_TIME = g_quark_from_string("creation_time"); + LTTV_FILTER_I_TIME = g_quark_from_string("insertion_time"); + LTTV_FILTER_P_NAME = g_quark_from_string("process_name"); + LTTV_FILTER_EX_MODE = g_quark_from_string("execution_mode"); + LTTV_FILTER_EX_SUBMODE = g_quark_from_string("execution_submode"); + LTTV_FILTER_P_STATUS = g_quark_from_string("process_status"); + LTTV_FILTER_CPU = g_quark_from_string("cpu"); + } +/** + * Destroys the filter module and specific values + */ static void module_destroy() { } -LTTV_MODULE("filter", "Filter state & event", \ - "Filters the current tracestate and events from user expression", \ +LTTV_MODULE("filter", "Filters traceset and events", \ + "Filters traceset and events specifically to user input", \ module_init, module_destroy)