Commit-ID:  8ff9daf3c16769817d0eaf16154d9e9198ec1bda
Gitweb:     http://git.kernel.org/tip/8ff9daf3c16769817d0eaf16154d9e9198ec1bda
Author:     Arnaldo Carvalho de Melo <[email protected]>
AuthorDate: Fri, 17 Jul 2015 12:07:25 -0300
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 20 Jul 2015 14:44:59 -0300

perf strlist: Allow substitutions from file contents in a given directory

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 <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/n/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
 tools/perf/util/strlist.c | 41 ++++++++++++++++++++++++++++++++++-------
 tools/perf/util/strlist.h |  3 ++-
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c
index dd40385..7abc75a 100644
--- a/tools/perf/util/strlist.c
+++ b/tools/perf/util/strlist.c
@@ -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;
        }
 
diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h
index a182785..9bb9823 100644
--- a/tools/perf/util/strlist.h
+++ b/tools/perf/util/strlist.h
@@ -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 */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
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