perf strlist: Allow substitutions from file contents in a given directory
authorArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 17 Jul 2015 15:07:25 +0000 (12:07 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 20 Jul 2015 17:44:59 +0000 (14:44 -0300)
So, if we have an strlist equal to:

   "file,close"

And we call it as:

   struct strlist_config *config = { .dirname = "~/strace/groups", };
   struct strlist *slist = strlist__new("file, close", &config);

And we have:
  $ cat ~/strace/groups/file
  access
  open
  openat
  statfs

Then the resulting strlist will have these contents:

  [ "access", "open", "openat", "statfs", "close" ]

This will be used to implement strace syscall groups in 'perf trace',
but can be used in some other tool, thus being implemented in 'strlist'.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-wi6l6qtomqlywwr6005jvs05@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/strlist.c
tools/perf/util/strlist.h

index dd403850dfab7d97e4a4106e352e435a54dc839c..7abc75a0abf3304bbe7317db0c2c887a4aa74501 100644 (file)
@@ -108,29 +108,47 @@ struct str_node *strlist__find(struct strlist *slist, const char *entry)
        return snode;
 }
 
-static int strlist__parse_list_entry(struct strlist *slist, const char *s)
+static int strlist__parse_list_entry(struct strlist *slist, const char *s,
+                                    const char *subst_dir)
 {
+       int err;
+       char *subst = NULL;
+
        if (strncmp(s, "file://", 7) == 0)
                return strlist__load(slist, s + 7);
 
-       return strlist__add(slist, s);
+       if (subst_dir) {
+               err = -ENOMEM;
+               if (asprintf(&subst, "%s/%s", subst_dir, s) < 0)
+                       goto out;
+
+               if (access(subst, F_OK) == 0) {
+                       err = strlist__load(slist, subst);
+                       goto out;
+               }
+       }
+
+       err = strlist__add(slist, s);
+out:
+       free(subst);
+       return err;
 }
 
-int strlist__parse_list(struct strlist *slist, const char *s)
+int strlist__parse_list(struct strlist *slist, const char *s, const char *subst_dir)
 {
        char *sep;
        int err;
 
        while ((sep = strchr(s, ',')) != NULL) {
                *sep = '\0';
-               err = strlist__parse_list_entry(slist, s);
+               err = strlist__parse_list_entry(slist, s, subst_dir);
                *sep = ',';
                if (err != 0)
                        return err;
                s = sep + 1;
        }
 
-       return *s ? strlist__parse_list_entry(slist, s) : 0;
+       return *s ? strlist__parse_list_entry(slist, s, subst_dir) : 0;
 }
 
 struct strlist *strlist__new(const char *list, const struct strlist_config *config)
@@ -138,13 +156,22 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf
        struct strlist *slist = malloc(sizeof(*slist));
 
        if (slist != NULL) {
+               bool dupstr = true;
+               const char *dirname = NULL;
+
+               if (config) {
+                       dupstr = !config->dont_dupstr;
+                       dirname = config->dirname;
+               }
+
                rblist__init(&slist->rblist);
                slist->rblist.node_cmp    = strlist__node_cmp;
                slist->rblist.node_new    = strlist__node_new;
                slist->rblist.node_delete = strlist__node_delete;
 
-               slist->dupstr    = config ? !config->dont_dupstr : true;
-               if (list && strlist__parse_list(slist, list) != 0)
+               slist->dupstr    = dupstr;
+
+               if (list && strlist__parse_list(slist, list, dirname) != 0)
                        goto out_error;
        }
 
index a182785d9428b4efc485d8c9a6e5d5afaddc673f..9bb9823268b88c0bcb684d838b8cf67168eef14e 100644 (file)
@@ -18,6 +18,7 @@ struct strlist {
 
 struct strlist_config {
        bool dont_dupstr;
+       const char *dirname;
 };
 
 struct strlist *strlist__new(const char *slist, const struct strlist_config *config);
@@ -79,5 +80,5 @@ static inline struct str_node *strlist__next(struct str_node *sn)
        for (pos = strlist__first(slist), n = strlist__next(pos); pos;\
             pos = n, n = strlist__next(n))
 
-int strlist__parse_list(struct strlist *slist, const char *s);
+int strlist__parse_list(struct strlist *slist, const char *s, const char *subst_dir);
 #endif /* __PERF_STRLIST_H */