root/tools/perf/builtin-config.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_config
  2. show_spec_config
  3. show_config
  4. parse_config_arg
  5. cmd_config

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * builtin-config.c
   4  *
   5  * Copyright (C) 2015, Taeung Song <treeze.taeung@gmail.com>
   6  *
   7  */
   8 #include "builtin.h"
   9 
  10 #include "util/cache.h"
  11 #include <subcmd/parse-options.h>
  12 #include "util/debug.h"
  13 #include "util/config.h"
  14 #include <linux/string.h>
  15 #include <stdio.h>
  16 #include <stdlib.h>
  17 
  18 static bool use_system_config, use_user_config;
  19 
  20 static const char * const config_usage[] = {
  21         "perf config [<file-option>] [options] [section.name[=value] ...]",
  22         NULL
  23 };
  24 
  25 enum actions {
  26         ACTION_LIST = 1
  27 } actions;
  28 
  29 static struct option config_options[] = {
  30         OPT_SET_UINT('l', "list", &actions,
  31                      "show current config variables", ACTION_LIST),
  32         OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
  33         OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
  34         OPT_END()
  35 };
  36 
  37 static int set_config(struct perf_config_set *set, const char *file_name)
  38 {
  39         struct perf_config_section *section = NULL;
  40         struct perf_config_item *item = NULL;
  41         const char *first_line = "# this file is auto-generated.";
  42         FILE *fp;
  43 
  44         if (set == NULL)
  45                 return -1;
  46 
  47         fp = fopen(file_name, "w");
  48         if (!fp)
  49                 return -1;
  50 
  51         fprintf(fp, "%s\n", first_line);
  52 
  53         /* overwrite configvariables */
  54         perf_config_items__for_each_entry(&set->sections, section) {
  55                 if (!use_system_config && section->from_system_config)
  56                         continue;
  57                 fprintf(fp, "[%s]\n", section->name);
  58 
  59                 perf_config_items__for_each_entry(&section->items, item) {
  60                         if (!use_system_config && item->from_system_config)
  61                                 continue;
  62                         if (item->value)
  63                                 fprintf(fp, "\t%s = %s\n",
  64                                         item->name, item->value);
  65                 }
  66         }
  67         fclose(fp);
  68 
  69         return 0;
  70 }
  71 
  72 static int show_spec_config(struct perf_config_set *set, const char *var)
  73 {
  74         struct perf_config_section *section;
  75         struct perf_config_item *item;
  76 
  77         if (set == NULL)
  78                 return -1;
  79 
  80         perf_config_items__for_each_entry(&set->sections, section) {
  81                 if (!strstarts(var, section->name))
  82                         continue;
  83 
  84                 perf_config_items__for_each_entry(&section->items, item) {
  85                         const char *name = var + strlen(section->name) + 1;
  86 
  87                         if (strcmp(name, item->name) == 0) {
  88                                 char *value = item->value;
  89 
  90                                 if (value) {
  91                                         printf("%s=%s\n", var, value);
  92                                         return 0;
  93                                 }
  94                         }
  95 
  96                 }
  97         }
  98 
  99         return 0;
 100 }
 101 
 102 static int show_config(struct perf_config_set *set)
 103 {
 104         struct perf_config_section *section;
 105         struct perf_config_item *item;
 106 
 107         if (set == NULL)
 108                 return -1;
 109 
 110         perf_config_set__for_each_entry(set, section, item) {
 111                 char *value = item->value;
 112 
 113                 if (value)
 114                         printf("%s.%s=%s\n", section->name,
 115                                item->name, value);
 116         }
 117 
 118         return 0;
 119 }
 120 
 121 static int parse_config_arg(char *arg, char **var, char **value)
 122 {
 123         const char *last_dot = strchr(arg, '.');
 124 
 125         /*
 126          * Since "var" actually contains the section name and the real
 127          * config variable name separated by a dot, we have to know where the dot is.
 128          */
 129         if (last_dot == NULL || last_dot == arg) {
 130                 pr_err("The config variable does not contain a section name: %s\n", arg);
 131                 return -1;
 132         }
 133         if (!last_dot[1]) {
 134                 pr_err("The config variable does not contain a variable name: %s\n", arg);
 135                 return -1;
 136         }
 137 
 138         *value = strchr(arg, '=');
 139         if (*value == NULL)
 140                 *var = arg;
 141         else if (!strcmp(*value, "=")) {
 142                 pr_err("The config variable does not contain a value: %s\n", arg);
 143                 return -1;
 144         } else {
 145                 *value = *value + 1; /* excluding a first character '=' */
 146                 *var = strsep(&arg, "=");
 147                 if (*var[0] == '\0') {
 148                         pr_err("invalid config variable: %s\n", arg);
 149                         return -1;
 150                 }
 151         }
 152 
 153         return 0;
 154 }
 155 
 156 int cmd_config(int argc, const char **argv)
 157 {
 158         int i, ret = -1;
 159         struct perf_config_set *set;
 160         char *user_config = mkpath("%s/.perfconfig", getenv("HOME"));
 161         const char *config_filename;
 162         bool changed = false;
 163 
 164         argc = parse_options(argc, argv, config_options, config_usage,
 165                              PARSE_OPT_STOP_AT_NON_OPTION);
 166 
 167         if (use_system_config && use_user_config) {
 168                 pr_err("Error: only one config file at a time\n");
 169                 parse_options_usage(config_usage, config_options, "user", 0);
 170                 parse_options_usage(NULL, config_options, "system", 0);
 171                 return -1;
 172         }
 173 
 174         if (use_system_config)
 175                 config_exclusive_filename = perf_etc_perfconfig();
 176         else if (use_user_config)
 177                 config_exclusive_filename = user_config;
 178 
 179         if (!config_exclusive_filename)
 180                 config_filename = user_config;
 181         else
 182                 config_filename = config_exclusive_filename;
 183 
 184         /*
 185          * At only 'config' sub-command, individually use the config set
 186          * because of reinitializing with options config file location.
 187          */
 188         set = perf_config_set__new();
 189         if (!set)
 190                 goto out_err;
 191 
 192         switch (actions) {
 193         case ACTION_LIST:
 194                 if (argc) {
 195                         pr_err("Error: takes no arguments\n");
 196                         parse_options_usage(config_usage, config_options, "l", 1);
 197                 } else {
 198 do_action_list:
 199                         if (show_config(set) < 0) {
 200                                 pr_err("Nothing configured, "
 201                                        "please check your %s \n", config_filename);
 202                                 goto out_err;
 203                         }
 204                 }
 205                 break;
 206         default:
 207                 if (!argc)
 208                         goto do_action_list;
 209 
 210                 for (i = 0; argv[i]; i++) {
 211                         char *var, *value;
 212                         char *arg = strdup(argv[i]);
 213 
 214                         if (!arg) {
 215                                 pr_err("%s: strdup failed\n", __func__);
 216                                 goto out_err;
 217                         }
 218 
 219                         if (parse_config_arg(arg, &var, &value) < 0) {
 220                                 free(arg);
 221                                 goto out_err;
 222                         }
 223 
 224                         if (value == NULL) {
 225                                 if (show_spec_config(set, var) < 0) {
 226                                         pr_err("%s is not configured: %s\n",
 227                                                var, config_filename);
 228                                         free(arg);
 229                                         goto out_err;
 230                                 }
 231                         } else {
 232                                 if (perf_config_set__collect(set, config_filename,
 233                                                              var, value) < 0) {
 234                                         pr_err("Failed to add '%s=%s'\n",
 235                                                var, value);
 236                                         free(arg);
 237                                         goto out_err;
 238                                 }
 239                                 changed = true;
 240                         }
 241                         free(arg);
 242                 }
 243 
 244                 if (!changed)
 245                         break;
 246 
 247                 if (set_config(set, config_filename) < 0) {
 248                         pr_err("Failed to set the configs on %s\n",
 249                                config_filename);
 250                         goto out_err;
 251                 }
 252         }
 253 
 254         ret = 0;
 255 out_err:
 256         perf_config_set__delete(set);
 257         return ret;
 258 }

/* [<][>][^][v][top][bottom][index][help] */