+/**
+ * Constructor for LttvSimpleExpression
+ * @return pointer to new LttvSimpleExpression
+ */
+LttvSimpleExpression*
+lttv_simple_expression_new() {
+
+ LttvSimpleExpression* se = g_new(LttvSimpleExpression,1);
+
+ se->field = LTTV_FILTER_UNDEFINED;
+ se->op = NULL;
+ se->offset = 0;
+ se->value = NULL;
+
+ return se;
+}
+/**
+ * add a node to the current tree
+ * FIXME: Might be used to lower coding in lttv_filter_new switch expression
+ * @param stack the tree stack
+ * @param subtree the subtree if available (pointer or NULL)
+ * @param op the logical operator that will form the node
+ */
+void
+lttv_filter_tree_add_node(GPtrArray* stack, LttvFilterTree* subtree, LttvLogicalOp op) {
+
+ LttvFilterTree* t1 = NULL;
+ LttvFilterTree* t2 = NULL;
+
+ t1 = (LttvFilterTree*)g_ptr_array_index(stack,stack->len-1);
+ while(t1->right != LTTV_TREE_IDLE) t1 = t1->r_child.t;
+ t2 = lttv_filter_tree_new();
+ t2->node = op;
+ if(subtree != NULL) {
+ t2->left = LTTV_TREE_NODE;
+ t2->l_child.t = subtree;
+ subtree = NULL;
+ t1->right = LTTV_TREE_NODE;
+ t1->r_child.t = t2;
+ } else {
+// a_simple_expression->value = a_field_component->str;
+// a_field_component = g_string_new("");
+ t2->left = LTTV_TREE_LEAF;
+// t2->l_child.leaf = a_simple_expression;
+// a_simple_expression = g_new(lttv_simple_expression,1);
+ t1->right = LTTV_TREE_NODE;
+ t1->r_child.t = t2;
+ }
+
+}
+
+/**
+ * Parse through filtering field hierarchy as specified
+ * by user. This function compares each value to
+ * predetermined quarks
+ * @param fp The field path list
+ * @param se current simple expression
+ * @return success/failure of operation
+ */
+gboolean
+parse_field_path(GPtrArray* fp, LttvSimpleExpression* se) {
+
+ GString* f = NULL;
+ if(fp->len < 2) return FALSE;
+ g_assert(f=g_ptr_array_index(fp,0)); //list_first(fp)->data;
+
+ /*
+ * Parse through the specified
+ * hardcoded fields.
+ *
+ * Take note however that the
+ * 'event' subfields might change
+ * depending on values specified
+ * in core.xml file. Hence, if
+ * none of the subfields in the
+ * array match the hardcoded
+ * subfields, it will be considered
+ * as a dynamic field
+ */
+ if(g_strcasecmp(f->str,"trace") ) {
+ /*
+ * Possible values:
+ * trace.name
+ */
+ f=g_ptr_array_index(fp,1);
+ if(g_strcasecmp(f->str,"name")) {
+ se->field = LTTV_FILTER_TRACE_NAME;
+ }
+ else return FALSE;
+ } else if(g_strcasecmp(f->str,"traceset") ) {
+ /*
+ * FIXME: not yet implemented !
+ */
+ } else if(g_strcasecmp(f->str,"tracefile") ) {
+ /*
+ * Possible values:
+ * tracefile.name
+ */
+ f=g_ptr_array_index(fp,1);
+ if(g_strcasecmp(f->str,"name")) {
+ se->field = LTTV_FILTER_TRACEFILE_NAME;
+ }
+ else return FALSE;
+ } else if(g_strcasecmp(f->str,"state") ) {
+ /*
+ * Possible values:
+ * state.pid
+ * state.ppid
+ * state.creation_time
+ * state.insertion_time
+ * state.process_name
+ * state.execution_mode
+ * state.execution_submode
+ * state.process_status
+ * state.cpu
+ */
+ f=g_ptr_array_index(fp,1);
+ if(g_strcasecmp(f->str,"pid") ) {
+ se->field = LTTV_FILTER_STATE_PID;
+ }
+ else if(g_strcasecmp(f->str,"ppid") ) {
+ se->field = LTTV_FILTER_STATE_PPID;
+ }
+ else if(g_strcasecmp(f->str,"creation_time") ) {
+ se->field = LTTV_FILTER_STATE_CT;
+ }
+ else if(g_strcasecmp(f->str,"insertion_time") ) {
+ se->field = LTTV_FILTER_STATE_IT;
+ }
+ else if(g_strcasecmp(f->str,"process_name") ) {
+ se->field = LTTV_FILTER_STATE_P_NAME;
+ }
+ else if(g_strcasecmp(f->str,"execution_mode") ) {
+ se->field = LTTV_FILTER_STATE_EX_MODE;
+ }
+ else if(g_strcasecmp(f->str,"execution_submode") ) {
+ se->field = LTTV_FILTER_STATE_EX_SUBMODE;
+ }
+ else if(g_strcasecmp(f->str,"process_status") ) {
+ se->field = LTTV_FILTER_STATE_P_STATUS;
+ }
+ else if(g_strcasecmp(f->str,"cpu") ) {
+ se->field = LTTV_FILTER_STATE_CPU;
+ }
+ else return FALSE;
+ } else if(g_strcasecmp(f->str,"event") ) {
+ /*
+ * Possible values:
+ * event.name
+ * event.category
+ * event.time
+ * event.tsc
+ */
+ f=g_ptr_array_index(fp,1);
+ if(g_strcasecmp(f->str,"name") ) {
+ se->field = LTTV_FILTER_EVENT_NAME;
+ }
+ else if(g_strcasecmp(f->str,"category") ) {
+ /*
+ * FIXME: Category not yet functional in lttv
+ */
+ se->field = LTTV_FILTER_EVENT_CATEGORY;
+ }
+ else if(g_strcasecmp(f->str,"time") ) {
+ se->field = LTTV_FILTER_EVENT_TIME;
+ // offset = &((LttEvent*)NULL)->event_time);
+ }
+ else if(g_strcasecmp(f->str,"tsc") ) {
+ se->field = LTTV_FILTER_EVENT_TSC;
+ // offset = &((LttEvent*)NULL)->event_cycle_count);
+ }
+ else { /* core.xml specified options */
+ se->field = LTTV_FILTER_EVENT_FIELD;
+ //se->offset = (...);
+ }
+ } else {
+ g_warning("Unrecognized field in filter string");
+ return FALSE;
+ }
+
+ /* free the pointer array */
+ g_ptr_array_free(fp,FALSE);
+
+ return TRUE;
+}
+
+/**
+ * Sets the function pointer for the current
+ * Simple Expression
+ * @param se current simple expression
+ * @return success/failure of operation
+ */
+gboolean assign_operator(LttvSimpleExpression* se, LttvExpressionOp op) {
+
+ switch(se->field) {
+ /* char */
+ case LTTV_FILTER_TRACE_NAME:
+ case LTTV_FILTER_TRACEFILE_NAME:
+ case LTTV_FILTER_STATE_P_NAME:
+ case LTTV_FILTER_EVENT_NAME:
+ switch(op) {
+ case LTTV_FIELD_EQ:
+ se->op = lttv_apply_op_eq_string;
+ break;
+ case LTTV_FIELD_NE:
+ se->op = lttv_apply_op_eq_string;
+ break;
+ default:
+ g_warning("Error encountered in operator assignment");
+ return FALSE;
+ }
+ break;
+ case LTTV_FILTER_STATE_PID:
+ case LTTV_FILTER_STATE_PPID:
+ case LTTV_FILTER_STATE_EX_MODE:
+ case LTTV_FILTER_STATE_EX_SUBMODE:
+ case LTTV_FILTER_STATE_P_STATUS:
+ switch(op) {
+ case LTTV_FIELD_EQ:
+ se->op = lttv_apply_op_eq_uint64;
+ break;
+ case LTTV_FIELD_NE:
+ se->op = lttv_apply_op_ne_uint64;
+ break;
+ case LTTV_FIELD_LT:
+ se->op = lttv_apply_op_lt_uint64;
+ break;
+ case LTTV_FIELD_LE:
+ se->op = lttv_apply_op_le_uint64;
+ break;
+ case LTTV_FIELD_GT:
+ se->op = lttv_apply_op_gt_uint64;
+ break;
+ case LTTV_FIELD_GE:
+ se->op = lttv_apply_op_ge_uint64;
+ break;
+ default:
+ g_warning("Error encountered in operator assignment");
+ return FALSE;
+ }
+ break;
+ case LTTV_FILTER_STATE_CT:
+ case LTTV_FILTER_STATE_IT:
+ case LTTV_FILTER_EVENT_TIME:
+ case LTTV_FILTER_EVENT_TSC:
+ switch(op) {
+ case LTTV_FIELD_EQ:
+ se->op = lttv_apply_op_eq_double;
+ break;
+ case LTTV_FIELD_NE:
+ se->op = lttv_apply_op_ne_double;
+ break;
+ case LTTV_FIELD_LT:
+ se->op = lttv_apply_op_lt_double;
+ break;
+ case LTTV_FIELD_LE:
+ se->op = lttv_apply_op_le_double;
+ break;
+ case LTTV_FIELD_GT:
+ se->op = lttv_apply_op_gt_double;
+ break;
+ case LTTV_FIELD_GE:
+ se->op = lttv_apply_op_ge_double;
+ break;
+ default:
+ g_warning("Error encountered in operator assignment");
+ return FALSE;
+ }
+ break;
+ default:
+ g_warning("Error encountered in operator assignment");
+ return FALSE;
+ }
+
+}
+