Add strfilter__string to recover rules string from strfilter.
This will be good for debugging.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu...@hitachi.com>
---
 tools/perf/util/strfilter.c |   67 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/strfilter.h |    9 ++++++
 2 files changed, 76 insertions(+)

diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c
index f3429cd..bcae659 100644
--- a/tools/perf/util/strfilter.c
+++ b/tools/perf/util/strfilter.c
@@ -237,3 +237,70 @@ bool strfilter__compare(struct strfilter *filter, const 
char *str)
                return false;
        return strfilter_node__compare(filter->root, str);
 }
+
+static int strfilter_node__sprint(struct strfilter_node *node, char *buf);
+
+/* sprint node in parenthesis if needed */
+static int strfilter_node__sprint_pt(struct strfilter_node *node, char *buf)
+{
+       int len;
+       int pt = node->r ? 2 : 0;       /* don't need to check node->l */
+
+       if (buf && pt)
+               *buf++ = '(';
+       len = strfilter_node__sprint(node, buf);
+       if (len < 0)
+               return len;
+       if (buf && pt)
+               *(buf + len) = ')';
+       return len + pt;
+}
+
+static int strfilter_node__sprint(struct strfilter_node *node, char *buf)
+{
+       int len = 0, rlen;
+
+       if (!node || !node->p)
+               return -EINVAL;
+
+       switch (*node->p) {
+       case '|':
+       case '&':
+               len = strfilter_node__sprint_pt(node->l, buf);
+               if (len < 0)
+                       return len;
+       case '!':
+               if (buf) {
+                       *(buf + len++) = *node->p;
+                       buf += len;
+               } else
+                       len++;
+               rlen = strfilter_node__sprint_pt(node->r, buf);
+               if (rlen < 0)
+                       return rlen;
+               len += rlen;
+               break;
+       default:
+               len = strlen(node->p);
+               if (buf)
+                       strcpy(buf, node->p);
+       }
+
+       return len;
+}
+
+char *strfilter__string(struct strfilter *filter)
+{
+       int len;
+       char *ret = NULL;
+
+       len = strfilter_node__sprint(filter->root, NULL);
+       if (len < 0)
+               return NULL;
+
+       ret = malloc(len + 1);
+       if (ret)
+               strfilter_node__sprint(filter->root, ret);
+
+       return ret;
+}
diff --git a/tools/perf/util/strfilter.h b/tools/perf/util/strfilter.h
index d007cdc..cff5eda 100644
--- a/tools/perf/util/strfilter.h
+++ b/tools/perf/util/strfilter.h
@@ -71,4 +71,13 @@ bool strfilter__compare(struct strfilter *filter, const char 
*str);
  */
 void strfilter__delete(struct strfilter *filter);
 
+/**
+ * strfilter__string - Reconstruct a rule string from filter
+ * @filter: String filter to reconstruct
+ *
+ * Reconstruct a rule string from @filter. This will be good for
+ * debug messages. Note that returning string must be freed afterward.
+ */
+char *strfilter__string(struct strfilter *filter);
+
 #endif

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to