2009-09-24 20:02:18 +04:00
# ifndef __PERF_STRLIST_H
# define __PERF_STRLIST_H
2009-07-01 02:01:20 +04:00
2009-07-01 19:28:37 +04:00
# include <linux/rbtree.h>
2009-07-01 02:01:20 +04:00
# include <stdbool.h>
2012-07-31 08:31:33 +04:00
# include "rblist.h"
2009-07-01 02:01:20 +04:00
struct str_node {
struct rb_node rb_node ;
const char * s ;
} ;
struct strlist {
2012-07-31 08:31:33 +04:00
struct rblist rblist ;
2016-01-09 13:16:27 +03:00
bool dupstr ;
bool file_only ;
2009-07-01 02:01:20 +04:00
} ;
2016-01-09 13:16:27 +03:00
/*
* @ file_only : When dirname is present , only consider entries as filenames ,
* that should not be added to the list if dirname / entry is not
* found
*/
2015-07-20 18:13:34 +03:00
struct strlist_config {
bool dont_dupstr ;
2016-01-09 13:16:27 +03:00
bool file_only ;
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 <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>
2015-07-17 18:07:25 +03:00
const char * dirname ;
2015-07-20 18:13:34 +03:00
} ;
struct strlist * strlist__new ( const char * slist , const struct strlist_config * config ) ;
2013-01-25 04:59:59 +04:00
void strlist__delete ( struct strlist * slist ) ;
2009-07-01 02:01:20 +04:00
2013-01-25 04:59:59 +04:00
void strlist__remove ( struct strlist * slist , struct str_node * sn ) ;
int strlist__load ( struct strlist * slist , const char * filename ) ;
int strlist__add ( struct strlist * slist , const char * str ) ;
2009-07-01 02:01:20 +04:00
2013-01-25 04:59:59 +04:00
struct str_node * strlist__entry ( const struct strlist * slist , unsigned int idx ) ;
struct str_node * strlist__find ( struct strlist * slist , const char * entry ) ;
2009-12-15 18:31:49 +03:00
2013-01-25 04:59:59 +04:00
static inline bool strlist__has_entry ( struct strlist * slist , const char * entry )
2009-12-15 18:31:49 +03:00
{
2013-01-25 04:59:59 +04:00
return strlist__find ( slist , entry ) ! = NULL ;
2009-12-15 18:31:49 +03:00
}
2009-07-01 02:01:20 +04:00
2013-01-25 04:59:59 +04:00
static inline bool strlist__empty ( const struct strlist * slist )
2009-07-01 02:01:20 +04:00
{
2013-01-25 04:59:59 +04:00
return rblist__empty ( & slist - > rblist ) ;
2009-07-11 19:18:34 +04:00
}
2013-01-25 04:59:59 +04:00
static inline unsigned int strlist__nr_entries ( const struct strlist * slist )
2009-07-11 19:18:34 +04:00
{
2013-01-25 04:59:59 +04:00
return rblist__nr_entries ( & slist - > rblist ) ;
2009-07-01 02:01:20 +04:00
}
2009-12-15 18:31:56 +03:00
/* For strlist iteration */
2013-01-25 04:59:59 +04:00
static inline struct str_node * strlist__first ( struct strlist * slist )
2009-12-15 18:31:56 +03:00
{
2013-01-25 04:59:59 +04:00
struct rb_node * rn = rb_first ( & slist - > rblist . entries ) ;
2009-12-15 18:31:56 +03:00
return rn ? rb_entry ( rn , struct str_node , rb_node ) : NULL ;
}
static inline struct str_node * strlist__next ( struct str_node * sn )
{
struct rb_node * rn ;
if ( ! sn )
return NULL ;
rn = rb_next ( & sn - > rb_node ) ;
return rn ? rb_entry ( rn , struct str_node , rb_node ) : NULL ;
}
/**
* strlist_for_each - iterate over a strlist
* @ pos : the & struct str_node to use as a loop cursor .
2013-01-25 04:59:59 +04:00
* @ slist : the & struct strlist for loop .
2009-12-15 18:31:56 +03:00
*/
2016-06-23 17:31:20 +03:00
# define strlist__for_each_entry(pos, slist) \
2013-01-25 04:59:59 +04:00
for ( pos = strlist__first ( slist ) ; pos ; pos = strlist__next ( pos ) )
2009-12-15 18:31:56 +03:00
/**
* strlist_for_each_safe - iterate over a strlist safe against removal of
* str_node
* @ pos : the & struct str_node to use as a loop cursor .
* @ n : another & struct str_node to use as temporary storage .
2013-01-25 04:59:59 +04:00
* @ slist : the & struct strlist for loop .
2009-12-15 18:31:56 +03:00
*/
2016-06-23 17:31:20 +03:00
# define strlist__for_each_entry_safe(pos, n, slist) \
2013-01-25 04:59:59 +04:00
for ( pos = strlist__first ( slist ) , n = strlist__next ( pos ) ; pos ; \
2009-12-15 18:31:56 +03:00
pos = n , n = strlist__next ( n ) )
2009-09-24 20:02:18 +04:00
# endif /* __PERF_STRLIST_H */