Re: [PATCH 2/4] perf tools: Add functions which can get or set perf config variables.

2015-05-10 Thread taeung

Hi, Jiri Olsa

Thanks for your feedbacks on my patches.

There are one thing I don't understand very well.
I wrote a number 1) in the middle of the your feedbacks to mark it.

I don't follow, could you elaborate it little more?


On 05/05/2015 04:16 AM, Jiri Olsa wrote:

On Mon, Apr 27, 2015 at 03:34:24PM +0900, Taeung Song wrote:

This patch consists of functions
which can get, set specific config variables.
For the syntax examples,

perf config [options] [section.subkey[=value] ...]

display key-value pairs of specific config variables
# perf config report.queue-size report.children

[jolsa@krava perf]$ ./perf config krava.krava
krava.krava=true

?

some comments below


set specific config variables
# perf config report.queue-size=100M report.children=true

Signed-off-by: Taeung Song 
---
  tools/perf/Documentation/perf-config.txt |   2 +
  tools/perf/builtin-config.c  | 276 ++-
  tools/perf/util/cache.h  |  17 ++
  tools/perf/util/config.c |  30 +++-
  4 files changed, 320 insertions(+), 5 deletions(-)

SNIP


+static int set_spec_config(const char *section_name, const char *subkey,
+  const char *value)
  {
int ret = 0;
+   ret += set_config(section_name, subkey, value);
+   ret += perf_configset_write_in_full();
+
+   return ret;
+}
+
+static void parse_key(const char *var, const char **section_name, const char 
**subkey)
+{
+   char *key = strdup(var);
+
+   if (!key)
+   die("%s: strdup failed\n", __func__);
+
+   *section_name = strsep(, ".");
+   *subkey = strsep(, ".");

should this check the config syntax? could be used for command line check as 
well

+}
+
+static int collect_config(const char *var, const char *value,
+ void *cb __maybe_unused)
+{
+   struct config_section *section_node;
+   const char *section_name, *subkey;

SNIP


+   }
+   for (i = 0; key[i]; i++) {
+   if (i == 0 && !isalpha(key[i++]))
+   goto out_err;
+
+   switch (key[i]) {
+   case '.':
+   num_dot += 1;
+   if (!isalpha(key[++i]))
+   goto out_err;
+   break;
+   case '=':
+   num_equals += 1;
+   break;
+   default:
+   if (!isalpha(key[i]) && !isalnum(key[i]))
+   goto out_err;

you dont allow '-' in the key report.queue-size, I think we should support also 
_

also please put the name checks into separated function


+   }
+   }
+
+   if (num_equals > 1 || num_dot > 1)
+   goto out_err;
+
+   given_value = strchr(key, '=');
+   if (given_value == NULL || given_value == key)
+   given_value = NULL;

SNIP


argc = parse_options(argc, argv, config_options, config_usage,
 PARSE_OPT_STOP_AT_NON_OPTION);
+   if (origin_argc > argc)
+   is_option = true;
+   else
+   is_option = false;
+
+   if (!is_option && argc >= 0) {
+   switch (argc) {
+   case 0:
+   break;
+   default:
+   for (i = 0; argv[i]; i++) {
+   value = strrchr(argv[i], '=');
+   if (value == NULL || value == argv[i])

hum, so you let go in args like '=krava' ?

why dont you completely check the name (assignment string) first
and decide later about the callback


1) I understood that the name must be completely checked first.
   But I don't know the callback. What does it mean ?
   Could you elaborate it little more?

Thanks,
Taeung


+   ret = 
perf_configset_with_option(show_spec_config, argv[i]);
+   else
+   ret = 
perf_configset_with_option(set_spec_config, argv[i]);
+   if (ret < 0)
+   break;
+   }
+   goto out;
+   }
+   }

SNIP


@@ -502,6 +501,31 @@ out:
return ret;
  }
  
+int perf_configset_write_in_full(void)

+{
+   struct config_section *section_node;
+   struct config_element *element_node;
+   const char *first_line = "# this file is auto-generated.";

so you parse whole config, change it and write back..
hum, I dont see better way.. and I like the first line ;-)


+   FILE *fp = fopen(config_file_name, "w");
+
+   if (!fp)
+   return -1;
+
+   fprintf(fp, "%s\n", first_line);
+   /* overwrite configvariables */
+   list_for_each_entry(section_node, sections, list) {
+   fprintf(fp, "[%s]\n", section_node->name);
+   

Re: [PATCH 2/4] perf tools: Add functions which can get or set perf config variables.

2015-05-10 Thread taeung

Hi, Jiri Olsa

Thanks for your feedbacks on my patches.

There are one thing I don't understand very well.
I wrote a number 1) in the middle of the your feedbacks to mark it.

I don't follow, could you elaborate it little more?


On 05/05/2015 04:16 AM, Jiri Olsa wrote:

On Mon, Apr 27, 2015 at 03:34:24PM +0900, Taeung Song wrote:

This patch consists of functions
which can get, set specific config variables.
For the syntax examples,

perf config [options] [section.subkey[=value] ...]

display key-value pairs of specific config variables
# perf config report.queue-size report.children

[jolsa@krava perf]$ ./perf config krava.krava
krava.krava=true

?

some comments below


set specific config variables
# perf config report.queue-size=100M report.children=true

Signed-off-by: Taeung Song treeze.tae...@gmail.com
---
  tools/perf/Documentation/perf-config.txt |   2 +
  tools/perf/builtin-config.c  | 276 ++-
  tools/perf/util/cache.h  |  17 ++
  tools/perf/util/config.c |  30 +++-
  4 files changed, 320 insertions(+), 5 deletions(-)

SNIP


+static int set_spec_config(const char *section_name, const char *subkey,
+  const char *value)
  {
int ret = 0;
+   ret += set_config(section_name, subkey, value);
+   ret += perf_configset_write_in_full();
+
+   return ret;
+}
+
+static void parse_key(const char *var, const char **section_name, const char 
**subkey)
+{
+   char *key = strdup(var);
+
+   if (!key)
+   die(%s: strdup failed\n, __func__);
+
+   *section_name = strsep(key, .);
+   *subkey = strsep(key, .);

should this check the config syntax? could be used for command line check as 
well

+}
+
+static int collect_config(const char *var, const char *value,
+ void *cb __maybe_unused)
+{
+   struct config_section *section_node;
+   const char *section_name, *subkey;

SNIP


+   }
+   for (i = 0; key[i]; i++) {
+   if (i == 0  !isalpha(key[i++]))
+   goto out_err;
+
+   switch (key[i]) {
+   case '.':
+   num_dot += 1;
+   if (!isalpha(key[++i]))
+   goto out_err;
+   break;
+   case '=':
+   num_equals += 1;
+   break;
+   default:
+   if (!isalpha(key[i])  !isalnum(key[i]))
+   goto out_err;

you dont allow '-' in the key report.queue-size, I think we should support also 
_

also please put the name checks into separated function


+   }
+   }
+
+   if (num_equals  1 || num_dot  1)
+   goto out_err;
+
+   given_value = strchr(key, '=');
+   if (given_value == NULL || given_value == key)
+   given_value = NULL;

SNIP


argc = parse_options(argc, argv, config_options, config_usage,
 PARSE_OPT_STOP_AT_NON_OPTION);
+   if (origin_argc  argc)
+   is_option = true;
+   else
+   is_option = false;
+
+   if (!is_option  argc = 0) {
+   switch (argc) {
+   case 0:
+   break;
+   default:
+   for (i = 0; argv[i]; i++) {
+   value = strrchr(argv[i], '=');
+   if (value == NULL || value == argv[i])

hum, so you let go in args like '=krava' ?

why dont you completely check the name (assignment string) first
and decide later about the callback


1) I understood that the name must be completely checked first.
   But I don't know the callback. What does it mean ?
   Could you elaborate it little more?

Thanks,
Taeung


+   ret = 
perf_configset_with_option(show_spec_config, argv[i]);
+   else
+   ret = 
perf_configset_with_option(set_spec_config, argv[i]);
+   if (ret  0)
+   break;
+   }
+   goto out;
+   }
+   }

SNIP


@@ -502,6 +501,31 @@ out:
return ret;
  }
  
+int perf_configset_write_in_full(void)

+{
+   struct config_section *section_node;
+   struct config_element *element_node;
+   const char *first_line = # this file is auto-generated.;

so you parse whole config, change it and write back..
hum, I dont see better way.. and I like the first line ;-)


+   FILE *fp = fopen(config_file_name, w);
+
+   if (!fp)
+   return -1;
+
+   fprintf(fp, %s\n, first_line);
+   /* overwrite configvariables */
+   list_for_each_entry(section_node, sections, list) {
+   fprintf(fp, [%s]\n, section_node-name);
+   

Re: [PATCH 2/4] perf tools: Add functions which can get or set perf config variables.

2015-05-04 Thread Jiri Olsa
On Mon, Apr 27, 2015 at 03:34:24PM +0900, Taeung Song wrote:
> This patch consists of functions
> which can get, set specific config variables.
> For the syntax examples,
> 
>perf config [options] [section.subkey[=value] ...]
> 
>display key-value pairs of specific config variables
># perf config report.queue-size report.children

[jolsa@krava perf]$ ./perf config krava.krava
krava.krava=true

?

some comments below

> 
>set specific config variables
># perf config report.queue-size=100M report.children=true
> 
> Signed-off-by: Taeung Song 
> ---
>  tools/perf/Documentation/perf-config.txt |   2 +
>  tools/perf/builtin-config.c  | 276 
> ++-
>  tools/perf/util/cache.h  |  17 ++
>  tools/perf/util/config.c |  30 +++-
>  4 files changed, 320 insertions(+), 5 deletions(-)

SNIP

> +static int set_spec_config(const char *section_name, const char *subkey,
> +const char *value)
>  {
>   int ret = 0;
> + ret += set_config(section_name, subkey, value);
> + ret += perf_configset_write_in_full();
> +
> + return ret;
> +}
> +
> +static void parse_key(const char *var, const char **section_name, const char 
> **subkey)
> +{
> + char *key = strdup(var);
> +
> + if (!key)
> + die("%s: strdup failed\n", __func__);
> +
> + *section_name = strsep(, ".");
> + *subkey = strsep(, ".");

should this check the config syntax? could be used for command line check as 
well

> +}
> +
> +static int collect_config(const char *var, const char *value,
> +   void *cb __maybe_unused)
> +{
> + struct config_section *section_node;
> + const char *section_name, *subkey;

SNIP

> + }
> + for (i = 0; key[i]; i++) {
> + if (i == 0 && !isalpha(key[i++]))
> + goto out_err;
> +
> + switch (key[i]) {
> + case '.':
> + num_dot += 1;
> + if (!isalpha(key[++i]))
> + goto out_err;
> + break;
> + case '=':
> + num_equals += 1;
> + break;
> + default:
> + if (!isalpha(key[i]) && !isalnum(key[i]))
> + goto out_err;

you dont allow '-' in the key report.queue-size, I think we should support also 
_ 

also please put the name checks into separated function

> + }
> + }
> +
> + if (num_equals > 1 || num_dot > 1)
> + goto out_err;
> +
> + given_value = strchr(key, '=');
> + if (given_value == NULL || given_value == key)
> + given_value = NULL;

SNIP

>   argc = parse_options(argc, argv, config_options, config_usage,
>PARSE_OPT_STOP_AT_NON_OPTION);
> + if (origin_argc > argc)
> + is_option = true;
> + else
> + is_option = false;
> +
> + if (!is_option && argc >= 0) {
> + switch (argc) {
> + case 0:
> + break;
> + default:
> + for (i = 0; argv[i]; i++) {
> + value = strrchr(argv[i], '=');
> + if (value == NULL || value == argv[i])

hum, so you let go in args like '=krava' ?

why dont you completely check the name (assignment string) first
and decide later about the callback

> + ret = 
> perf_configset_with_option(show_spec_config, argv[i]);
> + else
> + ret = 
> perf_configset_with_option(set_spec_config, argv[i]);
> + if (ret < 0)
> + break;
> + }
> + goto out;
> + }
> + }

SNIP

> @@ -502,6 +501,31 @@ out:
>   return ret;
>  }
>  
> +int perf_configset_write_in_full(void)
> +{
> + struct config_section *section_node;
> + struct config_element *element_node;
> + const char *first_line = "# this file is auto-generated.";

so you parse whole config, change it and write back..
hum, I dont see better way.. and I like the first line ;-)

> + FILE *fp = fopen(config_file_name, "w");
> +
> + if (!fp)
> + return -1;
> +
> + fprintf(fp, "%s\n", first_line);
> + /* overwrite configvariables */
> + list_for_each_entry(section_node, sections, list) {
> + fprintf(fp, "[%s]\n", section_node->name);
> + list_for_each_entry(element_node, _node->element_head, 
> list) {
> + if (element_node->value)
> + fprintf(fp, "\t%s = %s\n",
> + element_node->subkey, 
> element_node->value);
> + }
> + }
> + fclose(fp);
> +
> + return 0;
> +}
> +
>  /*
>   * Call this to report error for your variable that 

Re: [PATCH 2/4] perf tools: Add functions which can get or set perf config variables.

2015-05-04 Thread Jiri Olsa
On Mon, Apr 27, 2015 at 03:34:24PM +0900, Taeung Song wrote:
> This patch consists of functions
> which can get, set specific config variables.
> For the syntax examples,
> 
>perf config [options] [section.subkey[=value] ...]

not sure this gets fixed later on, but after applying
up to this patch I've got following error:

> 
>display key-value pairs of specific config variables
># perf config report.queue-size report.children

[jolsa@krava perf]$ ./perf config report.queue-size
invalid key: report.queue-size[jolsa@krava perf]$ 

> 
>set specific config variables
># perf config report.queue-size=100M report.children=true

[jolsa@krava perf]$ ./perf config report.queue-size=50M
invalid key: report.queue-size=50M[jolsa@krava perf]$ 

jirka

> 
> Signed-off-by: Taeung Song 
> ---
>  tools/perf/Documentation/perf-config.txt |   2 +
>  tools/perf/builtin-config.c  | 276 
> ++-
>  tools/perf/util/cache.h  |  17 ++
>  tools/perf/util/config.c |  30 +++-
>  4 files changed, 320 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/perf/Documentation/perf-config.txt 
> b/tools/perf/Documentation/perf-config.txt
> index 489c2c6..b2b3321 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -8,6 +8,8 @@ perf-config - Get and set variables in configuration file.
>  SYNOPSIS
>  
>  [verse]
> +'perf config' [section.subkey[=value] ...]
> +or
>  'perf config' -l | --list
>  
>  DESCRIPTION
> diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
> index 9e4ba72..99292f6 100644
> --- a/tools/perf/builtin-config.c
> +++ b/tools/perf/builtin-config.c
> @@ -15,10 +15,14 @@
>  
>  static struct {
>   bool list_action;
> + bool get_action;
> + bool set_action;
>  } params;
>  
> +struct list_head *sections;
> +
>  static const char * const config_usage[] = {
> - "perf config [options]",
> + "perf config [options] [section.subkey[=value] ...]",
>   NULL
>  };
>  static const struct option config_options[] = {
> @@ -27,6 +31,74 @@ static const struct option config_options[] = {
>   OPT_END()
>  };
>  
> +static struct config_section *find_config_section(const char *section_name)
> +{
> + struct config_section *section_node;
> + list_for_each_entry(section_node, sections, list)
> + if (!strcmp(section_node->name, section_name))
> + return section_node;
> +
> + return NULL;
> +}
> +
> +static struct config_element *find_config_element(const char *subkey,
> +   struct config_section 
> *section_node)
> +{
> + struct config_element *element_node;
> +
> + list_for_each_entry(element_node, _node->element_head, list)
> + if (!strcmp(element_node->subkey, subkey))
> + return element_node;
> +
> + return NULL;
> +}
> +
> +static struct config_section *init_config_section(const char *section_name)
> +{
> + struct config_section *section_node;
> +
> + section_node = zalloc(sizeof(*section_node));
> + if (!section_node)
> + return NULL;
> +
> + INIT_LIST_HEAD(_node->element_head);
> + section_node->name = strdup(section_name);
> + if (!section_node->name) {
> + pr_err("%s: strdup failed\n", __func__);
> + free(section_node);
> + return NULL;
> + }
> +
> + return section_node;
> +}
> +
> +static int add_config_element(struct list_head *head,
> +   const char *subkey, const char *value)
> +{
> + struct config_element *element_node;
> + element_node = zalloc(sizeof(*element_node));
> + element_node->subkey = strdup(subkey);
> + if (!element_node->subkey) {
> + pr_err("%s: strdup failed\n", __func__);
> + goto out_free;
> + }
> + if (value) {
> + element_node->value = strdup(value);
> + if (!element_node->value) {
> + pr_err("%s: strdup failed\n", __func__);
> + goto out_free;
> + }
> + } else
> + element_node->value = NULL;
> +
> + list_add_tail(_node->list, head);
> + return 0;
> +
> +out_free:
> + free(element_node);
> + return -1;
> +}
> +
>  static int show_config(const char *key, const char *value,
>  void *cb __maybe_unused)
>  {
> @@ -38,12 +110,211 @@ static int show_config(const char *key, const char 
> *value,
>   return 0;
>  }
>  
> -int cmd_config(int argc, const char **argv, const char *prefix 
> __maybe_unused)
> +static void find_config(struct config_section **section_node, struct 
> config_element **element_node,
> + const char *given_section_name, const char 
> *given_subkey)
> +{
> + *section_node = find_config_section(given_section_name);
> +
> + if (*section_node != NULL)
> + 

Re: [PATCH 2/4] perf tools: Add functions which can get or set perf config variables.

2015-05-04 Thread Jiri Olsa
On Mon, Apr 27, 2015 at 03:34:24PM +0900, Taeung Song wrote:
 This patch consists of functions
 which can get, set specific config variables.
 For the syntax examples,
 
perf config [options] [section.subkey[=value] ...]

not sure this gets fixed later on, but after applying
up to this patch I've got following error:

 
display key-value pairs of specific config variables
# perf config report.queue-size report.children

[jolsa@krava perf]$ ./perf config report.queue-size
invalid key: report.queue-size[jolsa@krava perf]$ 

 
set specific config variables
# perf config report.queue-size=100M report.children=true

[jolsa@krava perf]$ ./perf config report.queue-size=50M
invalid key: report.queue-size=50M[jolsa@krava perf]$ 

jirka

 
 Signed-off-by: Taeung Song treeze.tae...@gmail.com
 ---
  tools/perf/Documentation/perf-config.txt |   2 +
  tools/perf/builtin-config.c  | 276 
 ++-
  tools/perf/util/cache.h  |  17 ++
  tools/perf/util/config.c |  30 +++-
  4 files changed, 320 insertions(+), 5 deletions(-)
 
 diff --git a/tools/perf/Documentation/perf-config.txt 
 b/tools/perf/Documentation/perf-config.txt
 index 489c2c6..b2b3321 100644
 --- a/tools/perf/Documentation/perf-config.txt
 +++ b/tools/perf/Documentation/perf-config.txt
 @@ -8,6 +8,8 @@ perf-config - Get and set variables in configuration file.
  SYNOPSIS
  
  [verse]
 +'perf config' [section.subkey[=value] ...]
 +or
  'perf config' -l | --list
  
  DESCRIPTION
 diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
 index 9e4ba72..99292f6 100644
 --- a/tools/perf/builtin-config.c
 +++ b/tools/perf/builtin-config.c
 @@ -15,10 +15,14 @@
  
  static struct {
   bool list_action;
 + bool get_action;
 + bool set_action;
  } params;
  
 +struct list_head *sections;
 +
  static const char * const config_usage[] = {
 - perf config [options],
 + perf config [options] [section.subkey[=value] ...],
   NULL
  };
  static const struct option config_options[] = {
 @@ -27,6 +31,74 @@ static const struct option config_options[] = {
   OPT_END()
  };
  
 +static struct config_section *find_config_section(const char *section_name)
 +{
 + struct config_section *section_node;
 + list_for_each_entry(section_node, sections, list)
 + if (!strcmp(section_node-name, section_name))
 + return section_node;
 +
 + return NULL;
 +}
 +
 +static struct config_element *find_config_element(const char *subkey,
 +   struct config_section 
 *section_node)
 +{
 + struct config_element *element_node;
 +
 + list_for_each_entry(element_node, section_node-element_head, list)
 + if (!strcmp(element_node-subkey, subkey))
 + return element_node;
 +
 + return NULL;
 +}
 +
 +static struct config_section *init_config_section(const char *section_name)
 +{
 + struct config_section *section_node;
 +
 + section_node = zalloc(sizeof(*section_node));
 + if (!section_node)
 + return NULL;
 +
 + INIT_LIST_HEAD(section_node-element_head);
 + section_node-name = strdup(section_name);
 + if (!section_node-name) {
 + pr_err(%s: strdup failed\n, __func__);
 + free(section_node);
 + return NULL;
 + }
 +
 + return section_node;
 +}
 +
 +static int add_config_element(struct list_head *head,
 +   const char *subkey, const char *value)
 +{
 + struct config_element *element_node;
 + element_node = zalloc(sizeof(*element_node));
 + element_node-subkey = strdup(subkey);
 + if (!element_node-subkey) {
 + pr_err(%s: strdup failed\n, __func__);
 + goto out_free;
 + }
 + if (value) {
 + element_node-value = strdup(value);
 + if (!element_node-value) {
 + pr_err(%s: strdup failed\n, __func__);
 + goto out_free;
 + }
 + } else
 + element_node-value = NULL;
 +
 + list_add_tail(element_node-list, head);
 + return 0;
 +
 +out_free:
 + free(element_node);
 + return -1;
 +}
 +
  static int show_config(const char *key, const char *value,
  void *cb __maybe_unused)
  {
 @@ -38,12 +110,211 @@ static int show_config(const char *key, const char 
 *value,
   return 0;
  }
  
 -int cmd_config(int argc, const char **argv, const char *prefix 
 __maybe_unused)
 +static void find_config(struct config_section **section_node, struct 
 config_element **element_node,
 + const char *given_section_name, const char 
 *given_subkey)
 +{
 + *section_node = find_config_section(given_section_name);
 +
 + if (*section_node != NULL)
 + *element_node = find_config_element(given_subkey, 
 *section_node);
 + else
 + *element_node = NULL;
 +}
 +
 

Re: [PATCH 2/4] perf tools: Add functions which can get or set perf config variables.

2015-05-04 Thread Jiri Olsa
On Mon, Apr 27, 2015 at 03:34:24PM +0900, Taeung Song wrote:
 This patch consists of functions
 which can get, set specific config variables.
 For the syntax examples,
 
perf config [options] [section.subkey[=value] ...]
 
display key-value pairs of specific config variables
# perf config report.queue-size report.children

[jolsa@krava perf]$ ./perf config krava.krava
krava.krava=true

?

some comments below

 
set specific config variables
# perf config report.queue-size=100M report.children=true
 
 Signed-off-by: Taeung Song treeze.tae...@gmail.com
 ---
  tools/perf/Documentation/perf-config.txt |   2 +
  tools/perf/builtin-config.c  | 276 
 ++-
  tools/perf/util/cache.h  |  17 ++
  tools/perf/util/config.c |  30 +++-
  4 files changed, 320 insertions(+), 5 deletions(-)

SNIP

 +static int set_spec_config(const char *section_name, const char *subkey,
 +const char *value)
  {
   int ret = 0;
 + ret += set_config(section_name, subkey, value);
 + ret += perf_configset_write_in_full();
 +
 + return ret;
 +}
 +
 +static void parse_key(const char *var, const char **section_name, const char 
 **subkey)
 +{
 + char *key = strdup(var);
 +
 + if (!key)
 + die(%s: strdup failed\n, __func__);
 +
 + *section_name = strsep(key, .);
 + *subkey = strsep(key, .);

should this check the config syntax? could be used for command line check as 
well

 +}
 +
 +static int collect_config(const char *var, const char *value,
 +   void *cb __maybe_unused)
 +{
 + struct config_section *section_node;
 + const char *section_name, *subkey;

SNIP

 + }
 + for (i = 0; key[i]; i++) {
 + if (i == 0  !isalpha(key[i++]))
 + goto out_err;
 +
 + switch (key[i]) {
 + case '.':
 + num_dot += 1;
 + if (!isalpha(key[++i]))
 + goto out_err;
 + break;
 + case '=':
 + num_equals += 1;
 + break;
 + default:
 + if (!isalpha(key[i])  !isalnum(key[i]))
 + goto out_err;

you dont allow '-' in the key report.queue-size, I think we should support also 
_ 

also please put the name checks into separated function

 + }
 + }
 +
 + if (num_equals  1 || num_dot  1)
 + goto out_err;
 +
 + given_value = strchr(key, '=');
 + if (given_value == NULL || given_value == key)
 + given_value = NULL;

SNIP

   argc = parse_options(argc, argv, config_options, config_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
 + if (origin_argc  argc)
 + is_option = true;
 + else
 + is_option = false;
 +
 + if (!is_option  argc = 0) {
 + switch (argc) {
 + case 0:
 + break;
 + default:
 + for (i = 0; argv[i]; i++) {
 + value = strrchr(argv[i], '=');
 + if (value == NULL || value == argv[i])

hum, so you let go in args like '=krava' ?

why dont you completely check the name (assignment string) first
and decide later about the callback

 + ret = 
 perf_configset_with_option(show_spec_config, argv[i]);
 + else
 + ret = 
 perf_configset_with_option(set_spec_config, argv[i]);
 + if (ret  0)
 + break;
 + }
 + goto out;
 + }
 + }

SNIP

 @@ -502,6 +501,31 @@ out:
   return ret;
  }
  
 +int perf_configset_write_in_full(void)
 +{
 + struct config_section *section_node;
 + struct config_element *element_node;
 + const char *first_line = # this file is auto-generated.;

so you parse whole config, change it and write back..
hum, I dont see better way.. and I like the first line ;-)

 + FILE *fp = fopen(config_file_name, w);
 +
 + if (!fp)
 + return -1;
 +
 + fprintf(fp, %s\n, first_line);
 + /* overwrite configvariables */
 + list_for_each_entry(section_node, sections, list) {
 + fprintf(fp, [%s]\n, section_node-name);
 + list_for_each_entry(element_node, section_node-element_head, 
 list) {
 + if (element_node-value)
 + fprintf(fp, \t%s = %s\n,
 + element_node-subkey, 
 element_node-value);
 + }
 + }
 + fclose(fp);
 +
 + return 0;
 +}
 +
  /*
   * Call this to report error for your variable that should not
   * get a boolean value (i.e. [my] var means true).
 -- 
 1.9.1
 
--
To unsubscribe from this list: send the line