To avoid duplicated config variables and
use perf_config_set classifying between standard
perf config variables and unknown or new config
variables other than them, initialize perf_config_set
with all default configs.

And this will be needed when showing all configs with
default value or checking correct type of a config
variable in the near future.

Cc: Masami Hiramatsu <mhira...@kernel.org>
Cc: Namhyung Kim <namhy...@kernel.org>
Cc: Jiri Olsa <jo...@kernel.org>
Signed-off-by: Taeung Song <treeze.tae...@gmail.com>
---
 tools/perf/builtin-config.c | 11 +++++++----
 tools/perf/util/config.c    | 39 ++++++++++++++++++++++++++++++++++-----
 tools/perf/util/config.h    |  7 +++++++
 3 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index fe1b77f..0fe9bc5 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -35,6 +35,7 @@ static struct option config_options[] = {
 
 static int show_config(struct perf_config_set *set)
 {
+       bool has_value = false;
        struct perf_config_section *section;
        struct perf_config_item *item;
        struct list_head *sections;
@@ -43,19 +44,21 @@ static int show_config(struct perf_config_set *set)
                return -1;
 
        sections = &set->sections;
-       if (list_empty(sections))
-               return -1;
-
        list_for_each_entry(section, sections, node) {
                list_for_each_entry(item, &section->items, node) {
                        char *value = item->value;
 
-                       if (value)
+                       if (value) {
                                printf("%s.%s=%s\n", section->name,
                                       item->name, value);
+                               has_value = true;
+                       }
                }
        }
 
+       if (!has_value)
+               return -1;
+
        return 0;
 }
 
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index fb9361e..cca8932 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -705,6 +705,7 @@ static struct perf_config_section *add_section(struct 
list_head *sections,
        if (!section)
                return NULL;
 
+       section->is_allocated = true;
        INIT_LIST_HEAD(&section->items);
        section->name = strdup(section_name);
        if (!section->name) {
@@ -725,6 +726,7 @@ static struct perf_config_item *add_config_item(struct 
perf_config_section *sect
        if (!item)
                return NULL;
 
+       item->is_allocated = true;
        item->name = strdup(name);
        if (!item->name) {
                pr_debug("%s: strdup failed\n", __func__);
@@ -793,12 +795,35 @@ out_free:
        return -1;
 }
 
+static struct perf_config_set *perf_config_set__init(struct perf_config_set 
*set)
+{
+       unsigned int i, j;
+       struct perf_config_section *section;
+       struct perf_config_item *items;
+       struct list_head *sections = &set->sections;
+
+       INIT_LIST_HEAD(&set->sections);
+
+       for (i = 0; i < ARRAY_SIZE(default_sections); i++) {
+               section = &default_sections[i];
+               INIT_LIST_HEAD(&section->items);
+
+               items = default_config_items[i];
+               for (j = 0; items[j].name != NULL; j++)
+                       list_add_tail(&items[j].node, &section->items);
+
+               list_add_tail(&section->node, sections);
+       }
+
+       return set;
+}
+
 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_set__init(set);
                perf_config(collect_config, set);
        }
 
@@ -807,9 +832,11 @@ struct perf_config_set *perf_config_set__new(void)
 
 static void perf_config_item__delete(struct perf_config_item *item)
 {
-       zfree((char **)&item->name);
        zfree(&item->value);
-       free(item);
+       if (item->is_allocated) {
+               zfree((char **)&item->name);
+               free(item);
+       }
 }
 
 static void perf_config_section__purge(struct perf_config_section *section)
@@ -825,8 +852,10 @@ static void perf_config_section__purge(struct 
perf_config_section *section)
 static void perf_config_section__delete(struct perf_config_section *section)
 {
        perf_config_section__purge(section);
-       zfree((char **)&section->name);
-       free(section);
+       if (section->is_allocated) {
+               zfree((char **)&section->name);
+               free(section);
+       }
 }
 
 static void perf_config_set__purge(struct perf_config_set *set)
diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h
index 297b33e..e093143 100644
--- a/tools/perf/util/config.h
+++ b/tools/perf/util/config.h
@@ -14,6 +14,11 @@ enum perf_config_type {
        CONFIG_TYPE_STRING
 };
 
+/**
+ * struct perf_config_item - element of perf's configs
+ *
+ * @is_allocated: unknown or new config other than default config
+ */
 struct perf_config_item {
        const char *name;
        char *value;
@@ -27,11 +32,13 @@ struct perf_config_item {
                const char *s;
        } default_value;
        enum perf_config_type type;
+       bool is_allocated;
        struct list_head node;
 };
 
 struct perf_config_section {
        const char *name;
+       bool is_allocated;
        struct list_head items;
        struct list_head node;
 };
-- 
2.5.0

Reply via email to