0001
0002
0003
0004
0005
0006
0007
0008 #include "builtin.h"
0009
0010 #include "util/cache.h"
0011 #include <subcmd/parse-options.h>
0012 #include "util/debug.h"
0013 #include "util/config.h"
0014 #include <linux/string.h>
0015 #include <stdio.h>
0016 #include <stdlib.h>
0017
0018 static bool use_system_config, use_user_config;
0019
0020 static const char * const config_usage[] = {
0021 "perf config [<file-option>] [options] [section.name[=value] ...]",
0022 NULL
0023 };
0024
0025 enum actions {
0026 ACTION_LIST = 1
0027 } actions;
0028
0029 static struct option config_options[] = {
0030 OPT_SET_UINT('l', "list", &actions,
0031 "show current config variables", ACTION_LIST),
0032 OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
0033 OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
0034 OPT_END()
0035 };
0036
0037 static int set_config(struct perf_config_set *set, const char *file_name)
0038 {
0039 struct perf_config_section *section = NULL;
0040 struct perf_config_item *item = NULL;
0041 const char *first_line = "# this file is auto-generated.";
0042 FILE *fp;
0043
0044 if (set == NULL)
0045 return -1;
0046
0047 fp = fopen(file_name, "w");
0048 if (!fp)
0049 return -1;
0050
0051 fprintf(fp, "%s\n", first_line);
0052
0053
0054 perf_config_items__for_each_entry(&set->sections, section) {
0055 if (!use_system_config && section->from_system_config)
0056 continue;
0057 fprintf(fp, "[%s]\n", section->name);
0058
0059 perf_config_items__for_each_entry(§ion->items, item) {
0060 if (!use_system_config && item->from_system_config)
0061 continue;
0062 if (item->value)
0063 fprintf(fp, "\t%s = %s\n",
0064 item->name, item->value);
0065 }
0066 }
0067 fclose(fp);
0068
0069 return 0;
0070 }
0071
0072 static int show_spec_config(struct perf_config_set *set, const char *var)
0073 {
0074 struct perf_config_section *section;
0075 struct perf_config_item *item;
0076
0077 if (set == NULL)
0078 return -1;
0079
0080 perf_config_items__for_each_entry(&set->sections, section) {
0081 if (!strstarts(var, section->name))
0082 continue;
0083
0084 perf_config_items__for_each_entry(§ion->items, item) {
0085 const char *name = var + strlen(section->name) + 1;
0086
0087 if (strcmp(name, item->name) == 0) {
0088 char *value = item->value;
0089
0090 if (value) {
0091 printf("%s=%s\n", var, value);
0092 return 0;
0093 }
0094 }
0095
0096 }
0097 }
0098
0099 return 0;
0100 }
0101
0102 static int show_config(struct perf_config_set *set)
0103 {
0104 struct perf_config_section *section;
0105 struct perf_config_item *item;
0106
0107 if (set == NULL)
0108 return -1;
0109
0110 perf_config_set__for_each_entry(set, section, item) {
0111 char *value = item->value;
0112
0113 if (value)
0114 printf("%s.%s=%s\n", section->name,
0115 item->name, value);
0116 }
0117
0118 return 0;
0119 }
0120
0121 static int parse_config_arg(char *arg, char **var, char **value)
0122 {
0123 const char *last_dot = strchr(arg, '.');
0124
0125
0126
0127
0128
0129 if (last_dot == NULL || last_dot == arg) {
0130 pr_err("The config variable does not contain a section name: %s\n", arg);
0131 return -1;
0132 }
0133 if (!last_dot[1]) {
0134 pr_err("The config variable does not contain a variable name: %s\n", arg);
0135 return -1;
0136 }
0137
0138 *value = strchr(arg, '=');
0139 if (*value == NULL)
0140 *var = arg;
0141 else if (!strcmp(*value, "=")) {
0142 pr_err("The config variable does not contain a value: %s\n", arg);
0143 return -1;
0144 } else {
0145 *value = *value + 1;
0146 *var = strsep(&arg, "=");
0147 if (*var[0] == '\0') {
0148 pr_err("invalid config variable: %s\n", arg);
0149 return -1;
0150 }
0151 }
0152
0153 return 0;
0154 }
0155
0156 int cmd_config(int argc, const char **argv)
0157 {
0158 int i, ret = -1;
0159 struct perf_config_set *set;
0160 char *user_config = mkpath("%s/.perfconfig", getenv("HOME"));
0161 const char *config_filename;
0162 bool changed = false;
0163
0164 argc = parse_options(argc, argv, config_options, config_usage,
0165 PARSE_OPT_STOP_AT_NON_OPTION);
0166
0167 if (use_system_config && use_user_config) {
0168 pr_err("Error: only one config file at a time\n");
0169 parse_options_usage(config_usage, config_options, "user", 0);
0170 parse_options_usage(NULL, config_options, "system", 0);
0171 return -1;
0172 }
0173
0174 if (use_system_config)
0175 config_exclusive_filename = perf_etc_perfconfig();
0176 else if (use_user_config)
0177 config_exclusive_filename = user_config;
0178
0179 if (!config_exclusive_filename)
0180 config_filename = user_config;
0181 else
0182 config_filename = config_exclusive_filename;
0183
0184
0185
0186
0187
0188 set = perf_config_set__new();
0189 if (!set)
0190 goto out_err;
0191
0192 switch (actions) {
0193 case ACTION_LIST:
0194 if (argc) {
0195 pr_err("Error: takes no arguments\n");
0196 parse_options_usage(config_usage, config_options, "l", 1);
0197 } else {
0198 do_action_list:
0199 if (show_config(set) < 0) {
0200 pr_err("Nothing configured, "
0201 "please check your %s \n", config_filename);
0202 goto out_err;
0203 }
0204 }
0205 break;
0206 default:
0207 if (!argc)
0208 goto do_action_list;
0209
0210 for (i = 0; argv[i]; i++) {
0211 char *var, *value;
0212 char *arg = strdup(argv[i]);
0213
0214 if (!arg) {
0215 pr_err("%s: strdup failed\n", __func__);
0216 goto out_err;
0217 }
0218
0219 if (parse_config_arg(arg, &var, &value) < 0) {
0220 free(arg);
0221 goto out_err;
0222 }
0223
0224 if (value == NULL) {
0225 if (show_spec_config(set, var) < 0) {
0226 pr_err("%s is not configured: %s\n",
0227 var, config_filename);
0228 free(arg);
0229 goto out_err;
0230 }
0231 } else {
0232 if (perf_config_set__collect(set, config_filename,
0233 var, value) < 0) {
0234 pr_err("Failed to add '%s=%s'\n",
0235 var, value);
0236 free(arg);
0237 goto out_err;
0238 }
0239 changed = true;
0240 }
0241 free(arg);
0242 }
0243
0244 if (!changed)
0245 break;
0246
0247 if (set_config(set, config_filename) < 0) {
0248 pr_err("Failed to set the configs on %s\n",
0249 config_filename);
0250 goto out_err;
0251 }
0252 }
0253
0254 ret = 0;
0255 out_err:
0256 perf_config_set__delete(set);
0257 return ret;
0258 }