perf config: Introduce perf_config_set class
This infrastructure code was designed for upcoming features of 'perf config'. That collect config key-value pairs from user and system config files (i.e. user wide ~/.perfconfig and system wide $(sysconfdir)/perfconfig) to manage perf's configs. Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Taeung Song <treeze.taeung@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1460620401-23430-2-git-send-email-treeze.taeung@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
ecfd7a9c04
commit
20105ca124
@ -13,6 +13,7 @@
|
||||
#include <subcmd/exec-cmd.h>
|
||||
#include "util/hist.h" /* perf_hist_config */
|
||||
#include "util/llvm-utils.h" /* perf_llvm_config */
|
||||
#include "config.h"
|
||||
|
||||
#define MAXNAME (256)
|
||||
|
||||
@ -524,6 +525,178 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct perf_config_section *find_section(struct list_head *sections,
|
||||
const char *section_name)
|
||||
{
|
||||
struct perf_config_section *section;
|
||||
|
||||
list_for_each_entry(section, sections, node)
|
||||
if (!strcmp(section->name, section_name))
|
||||
return section;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct perf_config_item *find_config_item(const char *name,
|
||||
struct perf_config_section *section)
|
||||
{
|
||||
struct perf_config_item *item;
|
||||
|
||||
list_for_each_entry(item, §ion->items, node)
|
||||
if (!strcmp(item->name, name))
|
||||
return item;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct perf_config_section *add_section(struct list_head *sections,
|
||||
const char *section_name)
|
||||
{
|
||||
struct perf_config_section *section = zalloc(sizeof(*section));
|
||||
|
||||
if (!section)
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(§ion->items);
|
||||
section->name = strdup(section_name);
|
||||
if (!section->name) {
|
||||
pr_debug("%s: strdup failed\n", __func__);
|
||||
free(section);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_add_tail(§ion->node, sections);
|
||||
return section;
|
||||
}
|
||||
|
||||
static struct perf_config_item *add_config_item(struct perf_config_section *section,
|
||||
const char *name)
|
||||
{
|
||||
struct perf_config_item *item = zalloc(sizeof(*item));
|
||||
|
||||
if (!item)
|
||||
return NULL;
|
||||
|
||||
item->name = strdup(name);
|
||||
if (!item->name) {
|
||||
pr_debug("%s: strdup failed\n", __func__);
|
||||
free(item);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_add_tail(&item->node, §ion->items);
|
||||
return item;
|
||||
}
|
||||
|
||||
static int set_value(struct perf_config_item *item, const char *value)
|
||||
{
|
||||
char *val = strdup(value);
|
||||
|
||||
if (!val)
|
||||
return -1;
|
||||
|
||||
zfree(&item->value);
|
||||
item->value = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int collect_config(const char *var, const char *value,
|
||||
void *perf_config_set)
|
||||
{
|
||||
int ret = -1;
|
||||
char *ptr, *key;
|
||||
char *section_name, *name;
|
||||
struct perf_config_section *section = NULL;
|
||||
struct perf_config_item *item = NULL;
|
||||
struct perf_config_set *set = perf_config_set;
|
||||
struct list_head *sections = &set->sections;
|
||||
|
||||
key = ptr = strdup(var);
|
||||
if (!key) {
|
||||
pr_debug("%s: strdup failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
section_name = strsep(&ptr, ".");
|
||||
name = ptr;
|
||||
if (name == NULL || value == NULL)
|
||||
goto out_free;
|
||||
|
||||
section = find_section(sections, section_name);
|
||||
if (!section) {
|
||||
section = add_section(sections, section_name);
|
||||
if (!section)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
item = find_config_item(name, section);
|
||||
if (!item) {
|
||||
item = add_config_item(section, name);
|
||||
if (!item)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = set_value(item, value);
|
||||
return ret;
|
||||
|
||||
out_free:
|
||||
free(key);
|
||||
perf_config_set__delete(set);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct perf_config_set *perf_config_set__new(void)
|
||||
{
|
||||
struct perf_config_set *set = zalloc(sizeof(*set));
|
||||
|
||||
if (set) {
|
||||
INIT_LIST_HEAD(&set->sections);
|
||||
perf_config(collect_config, set);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
static void perf_config_item__delete(struct perf_config_item *item)
|
||||
{
|
||||
zfree(&item->name);
|
||||
zfree(&item->value);
|
||||
free(item);
|
||||
}
|
||||
|
||||
static void perf_config_section__purge(struct perf_config_section *section)
|
||||
{
|
||||
struct perf_config_item *item, *tmp;
|
||||
|
||||
list_for_each_entry_safe(item, tmp, §ion->items, node) {
|
||||
list_del_init(&item->node);
|
||||
perf_config_item__delete(item);
|
||||
}
|
||||
}
|
||||
|
||||
static void perf_config_section__delete(struct perf_config_section *section)
|
||||
{
|
||||
perf_config_section__purge(section);
|
||||
zfree(§ion->name);
|
||||
free(section);
|
||||
}
|
||||
|
||||
static void perf_config_set__purge(struct perf_config_set *set)
|
||||
{
|
||||
struct perf_config_section *section, *tmp;
|
||||
|
||||
list_for_each_entry_safe(section, tmp, &set->sections, node) {
|
||||
list_del_init(§ion->node);
|
||||
perf_config_section__delete(section);
|
||||
}
|
||||
}
|
||||
|
||||
void perf_config_set__delete(struct perf_config_set *set)
|
||||
{
|
||||
perf_config_set__purge(set);
|
||||
free(set);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this to report error for your variable that should not
|
||||
* get a boolean value (i.e. "[my] var" means "true").
|
||||
|
26
tools/perf/util/config.h
Normal file
26
tools/perf/util/config.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef __PERF_CONFIG_H
|
||||
#define __PERF_CONFIG_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
struct perf_config_item {
|
||||
char *name;
|
||||
char *value;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
struct perf_config_section {
|
||||
char *name;
|
||||
struct list_head items;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
struct perf_config_set {
|
||||
struct list_head sections;
|
||||
};
|
||||
|
||||
struct perf_config_set *perf_config_set__new(void);
|
||||
void perf_config_set__delete(struct perf_config_set *set);
|
||||
|
||||
#endif /* __PERF_CONFIG_H */
|
Loading…
Reference in New Issue
Block a user