convert from svn repository: remove tags directory
[lttv.git] / trunk / lttv / lttv / lttv / filter.c
index f62755868f27f8958e4b13989556d2ef6effd5d1..28252b31bdfc3d32a41cf1a28cd9c731c210fa0e 100644 (file)
  *  \verbatim
  *  LttvTracefileContext{} 
  *  |->event\ 
- *  | |->name (String, converted to GQuark)
- *  | |->facility (String, converted to GQuark)
+ *  | |->name (String, converted to GQuark) (channel.event)
+ *  | |->subname (String, converted to GQuark)
  *  | |->category (String, not yet implemented)
  *  | |->time (LttTime)
  *  | |->tsc (LttCycleCount --> uint64)
  *  | |->target_pid (target PID of the event)
  *  | |->fields
- *  |   |->"facility_name
+ *  |   |->"channel name"
  *  |     |->"event name"
  *  |       |->"field name"
  *  |         |->"sub-field name"
  *  |           |->...
  *  |             |->"leaf-field name" (field type)
- *  |->tracefile
+ *  |->channel (or tracefile)
  *  | |->name (String, converted to GQuark)
  *  |->trace
  *  | |->name (String, converted to GQuark)
@@ -101,6 +101,26 @@ lttv_simple_expression_new() {
   return se;
 }
 
+/*
+ * Keeps the array order.
+ */
+static inline gpointer ltt_g_ptr_array_remove_index_slow(GPtrArray *fp,
+    int index)
+{
+  gpointer ptr;
+  int i;
+
+  if (fp->len == 0)
+    return NULL;
+
+  ptr = g_ptr_array_index(fp, index);
+  for (i = index; i < fp->len - 1; i++) {
+    g_ptr_array_index(fp, i) = g_ptr_array_index(fp, i + 1);
+  }
+  g_ptr_array_remove_index(fp, fp->len - 1);
+  return ptr;
+}
+
 /**
  *  @fn gboolean lttv_simple_expression_assign_field(GPtrArray*,LttvSimpleExpression*)
  * 
@@ -115,10 +135,11 @@ gboolean
 lttv_simple_expression_assign_field(GPtrArray* fp, LttvSimpleExpression* se) {
 
   GString* f = NULL;
-  
+
   if(fp->len < 2) return FALSE;
-  g_assert((f=g_ptr_array_remove_index(fp,0))); 
-  
+  g_assert((f=ltt_g_ptr_array_remove_index_slow(fp,0)));
+
+
   /*
    * Parse through the specified 
    * hardcoded fields.
@@ -132,13 +153,14 @@ lttv_simple_expression_assign_field(GPtrArray* fp, LttvSimpleExpression* se) {
    * subfields, it will be considered 
    * as a dynamic field
    */
+
   if(!g_strcasecmp(f->str,"trace") ) {
     /*
      * Possible values:
      *  trace.name
      */
     g_string_free(f,TRUE);
-    f=g_ptr_array_remove_index(fp,0);
+    f=ltt_g_ptr_array_remove_index_slow(fp,0);
     if(!g_strcasecmp(f->str,"name")) {
       se->field = LTTV_FILTER_TRACE_NAME;    
     }
@@ -146,13 +168,15 @@ lttv_simple_expression_assign_field(GPtrArray* fp, LttvSimpleExpression* se) {
     /* 
      * FIXME: not yet implemented !
      */
-  } else if(!g_strcasecmp(f->str,"tracefile") ) {
+  } else if(!g_strcasecmp(f->str,"tracefile")
+            || !g_strcasecmp(f->str,"channel") ) {
     /*
      * Possible values:
      *  tracefile.name
+     *  channel.name
      */
     g_string_free(f,TRUE);
-    f=g_ptr_array_remove_index(fp,0);
+    f=ltt_g_ptr_array_remove_index_slow(fp,0);
     if(!g_strcasecmp(f->str,"name")) {
       se->field = LTTV_FILTER_TRACEFILE_NAME;
     }
@@ -171,7 +195,7 @@ lttv_simple_expression_assign_field(GPtrArray* fp, LttvSimpleExpression* se) {
      *  state.cpu
      */
     g_string_free(f,TRUE);
-    f=g_ptr_array_remove_index(fp,0);
+    f=ltt_g_ptr_array_remove_index_slow(fp,0);
     if(!g_strcasecmp(f->str,"pid") ) { 
       se->field = LTTV_FILTER_STATE_PID; 
     }
@@ -206,6 +230,7 @@ lttv_simple_expression_assign_field(GPtrArray* fp, LttvSimpleExpression* se) {
     /*
      * Possible values:
      *  event.name
+     *  event.channel
      *  event.category
      *  event.time
      *  event.tsc
@@ -213,10 +238,14 @@ lttv_simple_expression_assign_field(GPtrArray* fp, LttvSimpleExpression* se) {
      *  event.field
      */
     g_string_free(f,TRUE);
-    f=g_ptr_array_remove_index(fp,0);
+    f=ltt_g_ptr_array_remove_index_slow(fp,0);
+
     if(!g_strcasecmp(f->str,"name") ) {
       se->field = LTTV_FILTER_EVENT_NAME;
     }
+    else if(!g_strcasecmp(f->str,"subname") ) {
+      se->field = LTTV_FILTER_EVENT_SUBNAME;
+    }
     else if(!g_strcasecmp(f->str,"category") ) {
       /*
        * FIXME: Category not yet functional in lttv
@@ -235,16 +264,16 @@ lttv_simple_expression_assign_field(GPtrArray* fp, LttvSimpleExpression* se) {
     else if(!g_strcasecmp(f->str,"field") ) {
       se->field = LTTV_FILTER_EVENT_FIELD;
       g_string_free(f,TRUE);
-      f=g_ptr_array_remove_index(fp,0);
+      f=ltt_g_ptr_array_remove_index_slow(fp,0);
 
     } else {
-      g_string_free(f,TRUE);
-      f=g_ptr_array_remove_index(fp,0);
+      //g_string_free(f,TRUE);
+      //f=ltt_g_ptr_array_remove_index_slow(fp,0);
       g_warning("Unknown event filter subtype %s", f->str);
     }
   } else {
     g_string_free(f,TRUE);
-    f=g_ptr_array_remove_index(fp,0);
+    f=ltt_g_ptr_array_remove_index_slow(fp,0);
 
     g_warning("Unrecognized field in filter string");
   }
@@ -282,7 +311,7 @@ lttv_simple_expression_assign_operator(LttvSimpleExpression* se, LttvExpressionO
      case LTTV_FILTER_TRACEFILE_NAME:
      case LTTV_FILTER_STATE_P_NAME:
      case LTTV_FILTER_STATE_T_BRAND:
-     case LTTV_FILTER_EVENT_NAME:
+     case LTTV_FILTER_EVENT_SUBNAME:
      case LTTV_FILTER_STATE_EX_MODE:
      case LTTV_FILTER_STATE_EX_SUBMODE:
      case LTTV_FILTER_STATE_P_STATUS:
@@ -298,6 +327,21 @@ lttv_simple_expression_assign_operator(LttvSimpleExpression* se, LttvExpressionO
            return FALSE;
        }
        break;
+     /*
+      * two strings.
+      */
+     case LTTV_FILTER_EVENT_NAME:
+       switch(op) {
+         case LTTV_FIELD_EQ:
+           se->op = lttv_apply_op_eq_quarks;
+           break;
+         case LTTV_FIELD_NE:
+           se->op = lttv_apply_op_ne_quarks;
+           break;
+         default:
+           g_warning("Error encountered in operator assignment = or != expected");
+           return FALSE;
+       }
      /* 
       * integer
       */
@@ -444,7 +488,7 @@ lttv_simple_expression_assign_value(LttvSimpleExpression* se, char* value) {
      case LTTV_FILTER_TRACEFILE_NAME:
      case LTTV_FILTER_STATE_P_NAME:
      case LTTV_FILTER_STATE_T_BRAND:
-     case LTTV_FILTER_EVENT_NAME:
+     case LTTV_FILTER_EVENT_SUBNAME:
      case LTTV_FILTER_STATE_EX_MODE:
      case LTTV_FILTER_STATE_EX_SUBMODE:
      case LTTV_FILTER_STATE_P_STATUS:
@@ -452,6 +496,25 @@ lttv_simple_expression_assign_value(LttvSimpleExpression* se, char* value) {
        se->value.v_quark = g_quark_from_string(value);
        g_free(value);
        break;
+     /*
+      * Two strings.
+      */
+     case LTTV_FILTER_EVENT_NAME:
+       {
+         /* channel.event */
+         char *end = strchr(value, '.');
+         if (end) {
+           *end = '\0';
+           end++;
+           se->value.v_quarks.q[0] = g_quark_from_string(value);
+           se->value.v_quarks.q[1] = g_quark_from_string(end);
+         } else {
+           se->value.v_quarks.q[0] = (GQuark)0;
+           se->value.v_quarks.q[1] = g_quark_from_string(value);
+         }
+         g_free(value);
+       }
+       break;
      /* 
       * integer -- supposed to be uint64
       */
@@ -560,7 +623,7 @@ lttv_struct_type(gint ft) {
         case LTTV_FILTER_STATE_CT:
         case LTTV_FILTER_STATE_IT:
         case LTTV_FILTER_STATE_P_NAME:
-  case LTTV_FILTER_STATE_T_BRAND:
+        case LTTV_FILTER_STATE_T_BRAND:
         case LTTV_FILTER_STATE_EX_MODE:
         case LTTV_FILTER_STATE_EX_SUBMODE:
         case LTTV_FILTER_STATE_P_STATUS:
@@ -568,6 +631,7 @@ lttv_struct_type(gint ft) {
             return LTTV_FILTER_STATE;
             break;
         case LTTV_FILTER_EVENT_NAME:
+        case LTTV_FILTER_EVENT_SUBNAME:
         case LTTV_FILTER_EVENT_CATEGORY:
         case LTTV_FILTER_EVENT_TIME:
         case LTTV_FILTER_EVENT_TSC:
@@ -682,6 +746,25 @@ gboolean lttv_apply_op_eq_quark(const gpointer v1, LttvFieldValue v2) {
   return (*r == v2.v_quark);
 }
 
+/**
+ *  @fn gboolean lttv_apply_op_eq_quarks(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'equal' operator to the
+ *  specified structure and value
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_eq_quarks(const gpointer v1, LttvFieldValue v2) {
+  GQuark *r1 = (GQuark *) v1;
+  GQuark *r2 = r1 + 1;
+  if (likely(*r1 != (GQuark)0) && *r1 != v2.v_quarks.q[0])
+    return 0;
+  if (*r2 != v2.v_quarks.q[1])
+    return 0;
+  return 1;
+}
+
 /**
  *  @fn gboolean lttv_apply_op_eq_ltttime(gpointer,LttvFieldValue) 
  * 
@@ -794,6 +877,23 @@ gboolean lttv_apply_op_ne_quark(const gpointer v1, LttvFieldValue v2) {
   return (*r != v2.v_quark);
 }
 
+/**
+ *  @fn gboolean lttv_apply_op_ne_quarks(gpointer,LttvFieldValue) 
+ * 
+ *  Applies the 'equal' operator to the
+ *  specified structure and value
+ *  @param v1 left member of comparison
+ *  @param v2 right member of comparison
+ *  @return success/failure of operation
+ */
+gboolean lttv_apply_op_ne_quarks(const gpointer v1, LttvFieldValue v2) {
+  GQuark *r1 = (GQuark *) v1;
+  GQuark *r2 = r1 + 1;
+  if ((*r1 == (GQuark)0 || *r1 == v2.v_quarks.q[0]) && *r2 == v2.v_quarks.q[1])
+    return 0;
+  else
+    return 1;
+}
 
 /**
  *  @fn gboolean lttv_apply_op_ne_ltttime(gpointer,LttvFieldValue) 
@@ -1666,7 +1766,7 @@ lttv_filter_update(LttvFilter* filter) {
   g_ptr_array_free(a_field_path,TRUE);
 
   /* free the tree stack -- but keep the root tree */
-  filter->head = g_ptr_array_remove_index(tree_stack,0);
+  filter->head = ltt_g_ptr_array_remove_index_slow(tree_stack,0);
   g_ptr_array_free(tree_stack,TRUE);
   
   /* free the field buffer if allocated */
@@ -1868,7 +1968,7 @@ lttv_filter_tree_parse(
     
   gboolean lresult = FALSE, rresult = FALSE;
 
-  LttvTraceState *ts;
+  LttvTraceState *ts = NULL;
   LttvTracefileState *tfs = (LttvTracefileState*)context;
   if(tc)
     ts = (LttvTraceState*)tc;
@@ -2024,7 +2124,21 @@ lttv_filter_tree_parse_branch(
             if(event == NULL) return TRUE;
             else {
               struct marker_info *info;
-              info = marker_get_info_from_id((LttTrace *)trace, event->event_id);
+              GQuark qtuple[2];
+             LttTracefile *tf = context->tf;
+              qtuple[0] = ltt_tracefile_name(tracefile);
+              info = marker_get_info_from_id(tf->mdata, event->event_id);
+              g_assert(info != NULL);
+              qtuple[1] = info->name;
+              return se->op((gpointer)qtuple,v);
+            }
+            break;
+        case LTTV_FILTER_EVENT_SUBNAME:
+            if(event == NULL) return TRUE;
+            else {
+              struct marker_info *info;
+             LttTracefile *tf = context->tf;
+              info = marker_get_info_from_id(tf->mdata, event->event_id);
               g_assert(info != NULL);
               GQuark quark = info->name;
               return se->op((gpointer)&quark,v);
This page took 0.027061 seconds and 4 git commands to generate.