Linux Perf
config.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * config.c
4  *
5  * Helper functions for parsing config items.
6  * Originally copied from GIT source.
7  *
8  * Copyright (C) Linus Torvalds, 2005
9  * Copyright (C) Johannes Schindelin, 2005
10  *
11  */
12 #include <errno.h>
13 #include <sys/param.h>
14 #include "util.h"
15 #include "cache.h"
16 #include <subcmd/exec-cmd.h>
17 #include "util/hist.h" /* perf_hist_config */
18 #include "util/llvm-utils.h" /* perf_llvm_config */
19 #include "config.h"
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include <linux/string.h>
24 
25 #include "sane_ctype.h"
26 
27 #define MAXNAME (256)
28 
29 #define DEBUG_CACHE_DIR ".debug"
30 
31 
32 char buildid_dir[MAXPATHLEN]; /* root dir for buildid, binary cache */
33 
34 static FILE *config_file;
35 static const char *config_file_name;
36 static int config_linenr;
37 static int config_file_eof;
38 static struct perf_config_set *config_set;
39 
41 
42 static int get_next_char(void)
43 {
44  int c;
45  FILE *f;
46 
47  c = '\n';
48  if ((f = config_file) != NULL) {
49  c = fgetc(f);
50  if (c == '\r') {
51  /* DOS like systems */
52  c = fgetc(f);
53  if (c != '\n') {
54  ungetc(c, f);
55  c = '\r';
56  }
57  }
58  if (c == '\n')
59  config_linenr++;
60  if (c == EOF) {
61  config_file_eof = 1;
62  c = '\n';
63  }
64  }
65  return c;
66 }
67 
68 static char *parse_value(void)
69 {
70  static char value[1024];
71  int quote = 0, comment = 0, space = 0;
72  size_t len = 0;
73 
74  for (;;) {
75  int c = get_next_char();
76 
77  if (len >= sizeof(value) - 1)
78  return NULL;
79  if (c == '\n') {
80  if (quote)
81  return NULL;
82  value[len] = 0;
83  return value;
84  }
85  if (comment)
86  continue;
87  if (isspace(c) && !quote) {
88  space = 1;
89  continue;
90  }
91  if (!quote) {
92  if (c == ';' || c == '#') {
93  comment = 1;
94  continue;
95  }
96  }
97  if (space) {
98  if (len)
99  value[len++] = ' ';
100  space = 0;
101  }
102  if (c == '\\') {
103  c = get_next_char();
104  switch (c) {
105  case '\n':
106  continue;
107  case 't':
108  c = '\t';
109  break;
110  case 'b':
111  c = '\b';
112  break;
113  case 'n':
114  c = '\n';
115  break;
116  /* Some characters escape as themselves */
117  case '\\': case '"':
118  break;
119  /* Reject unknown escape sequences */
120  default:
121  return NULL;
122  }
123  value[len++] = c;
124  continue;
125  }
126  if (c == '"') {
127  quote = 1-quote;
128  continue;
129  }
130  value[len++] = c;
131  }
132 }
133 
134 static inline int iskeychar(int c)
135 {
136  return isalnum(c) || c == '-' || c == '_';
137 }
138 
139 static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
140 {
141  int c;
142  char *value;
143 
144  /* Get the full name */
145  for (;;) {
146  c = get_next_char();
147  if (config_file_eof)
148  break;
149  if (!iskeychar(c))
150  break;
151  name[len++] = c;
152  if (len >= MAXNAME)
153  return -1;
154  }
155  name[len] = 0;
156  while (c == ' ' || c == '\t')
157  c = get_next_char();
158 
159  value = NULL;
160  if (c != '\n') {
161  if (c != '=')
162  return -1;
163  value = parse_value();
164  if (!value)
165  return -1;
166  }
167  return fn(name, value, data);
168 }
169 
170 static int get_extended_base_var(char *name, int baselen, int c)
171 {
172  do {
173  if (c == '\n')
174  return -1;
175  c = get_next_char();
176  } while (isspace(c));
177 
178  /* We require the format to be '[base "extension"]' */
179  if (c != '"')
180  return -1;
181  name[baselen++] = '.';
182 
183  for (;;) {
184  int ch = get_next_char();
185 
186  if (ch == '\n')
187  return -1;
188  if (ch == '"')
189  break;
190  if (ch == '\\') {
191  ch = get_next_char();
192  if (ch == '\n')
193  return -1;
194  }
195  name[baselen++] = ch;
196  if (baselen > MAXNAME / 2)
197  return -1;
198  }
199 
200  /* Final ']' */
201  if (get_next_char() != ']')
202  return -1;
203  return baselen;
204 }
205 
206 static int get_base_var(char *name)
207 {
208  int baselen = 0;
209 
210  for (;;) {
211  int c = get_next_char();
212  if (config_file_eof)
213  return -1;
214  if (c == ']')
215  return baselen;
216  if (isspace(c))
217  return get_extended_base_var(name, baselen, c);
218  if (!iskeychar(c) && c != '.')
219  return -1;
220  if (baselen > MAXNAME / 2)
221  return -1;
222  name[baselen++] = tolower(c);
223  }
224 }
225 
226 static int perf_parse_file(config_fn_t fn, void *data)
227 {
228  int comment = 0;
229  int baselen = 0;
230  static char var[MAXNAME];
231 
232  /* U+FEFF Byte Order Mark in UTF8 */
233  static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf";
234  const unsigned char *bomptr = utf8_bom;
235 
236  for (;;) {
237  int line, c = get_next_char();
238 
239  if (bomptr && *bomptr) {
240  /* We are at the file beginning; skip UTF8-encoded BOM
241  * if present. Sane editors won't put this in on their
242  * own, but e.g. Windows Notepad will do it happily. */
243  if ((unsigned char) c == *bomptr) {
244  bomptr++;
245  continue;
246  } else {
247  /* Do not tolerate partial BOM. */
248  if (bomptr != utf8_bom)
249  break;
250  /* No BOM at file beginning. Cool. */
251  bomptr = NULL;
252  }
253  }
254  if (c == '\n') {
255  if (config_file_eof)
256  return 0;
257  comment = 0;
258  continue;
259  }
260  if (comment || isspace(c))
261  continue;
262  if (c == '#' || c == ';') {
263  comment = 1;
264  continue;
265  }
266  if (c == '[') {
267  baselen = get_base_var(var);
268  if (baselen <= 0)
269  break;
270  var[baselen++] = '.';
271  var[baselen] = 0;
272  continue;
273  }
274  if (!isalpha(c))
275  break;
276  var[baselen] = tolower(c);
277 
278  /*
279  * The get_value function might or might not reach the '\n',
280  * so saving the current line number for error reporting.
281  */
282  line = config_linenr;
283  if (get_value(fn, data, var, baselen+1) < 0) {
284  config_linenr = line;
285  break;
286  }
287  }
288  pr_err("bad config file line %d in %s\n", config_linenr, config_file_name);
289  return -1;
290 }
291 
292 static int parse_unit_factor(const char *end, unsigned long *val)
293 {
294  if (!*end)
295  return 1;
296  else if (!strcasecmp(end, "k")) {
297  *val *= 1024;
298  return 1;
299  }
300  else if (!strcasecmp(end, "m")) {
301  *val *= 1024 * 1024;
302  return 1;
303  }
304  else if (!strcasecmp(end, "g")) {
305  *val *= 1024 * 1024 * 1024;
306  return 1;
307  }
308  return 0;
309 }
310 
311 static int perf_parse_llong(const char *value, long long *ret)
312 {
313  if (value && *value) {
314  char *end;
315  long long val = strtoll(value, &end, 0);
316  unsigned long factor = 1;
317 
318  if (!parse_unit_factor(end, &factor))
319  return 0;
320  *ret = val * factor;
321  return 1;
322  }
323  return 0;
324 }
325 
326 static int perf_parse_long(const char *value, long *ret)
327 {
328  if (value && *value) {
329  char *end;
330  long val = strtol(value, &end, 0);
331  unsigned long factor = 1;
332  if (!parse_unit_factor(end, &factor))
333  return 0;
334  *ret = val * factor;
335  return 1;
336  }
337  return 0;
338 }
339 
340 static void bad_config(const char *name)
341 {
342  if (config_file_name)
343  pr_warning("bad config value for '%s' in %s, ignoring...\n", name, config_file_name);
344  else
345  pr_warning("bad config value for '%s', ignoring...\n", name);
346 }
347 
348 int perf_config_u64(u64 *dest, const char *name, const char *value)
349 {
350  long long ret = 0;
351 
352  if (!perf_parse_llong(value, &ret)) {
353  bad_config(name);
354  return -1;
355  }
356 
357  *dest = ret;
358  return 0;
359 }
360 
361 int perf_config_int(int *dest, const char *name, const char *value)
362 {
363  long ret = 0;
364  if (!perf_parse_long(value, &ret)) {
365  bad_config(name);
366  return -1;
367  }
368  *dest = ret;
369  return 0;
370 }
371 
372 static int perf_config_bool_or_int(const char *name, const char *value, int *is_bool)
373 {
374  int ret;
375 
376  *is_bool = 1;
377  if (!value)
378  return 1;
379  if (!*value)
380  return 0;
381  if (!strcasecmp(value, "true") || !strcasecmp(value, "yes") || !strcasecmp(value, "on"))
382  return 1;
383  if (!strcasecmp(value, "false") || !strcasecmp(value, "no") || !strcasecmp(value, "off"))
384  return 0;
385  *is_bool = 0;
386  return perf_config_int(&ret, name, value) < 0 ? -1 : ret;
387 }
388 
389 int perf_config_bool(const char *name, const char *value)
390 {
391  int discard;
392  return !!perf_config_bool_or_int(name, value, &discard);
393 }
394 
395 static const char *perf_config_dirname(const char *name, const char *value)
396 {
397  if (!name)
398  return NULL;
399  return value;
400 }
401 
402 static int perf_buildid_config(const char *var, const char *value)
403 {
404  /* same dir for all commands */
405  if (!strcmp(var, "buildid.dir")) {
406  const char *dir = perf_config_dirname(var, value);
407 
408  if (!dir) {
409  pr_err("Invalid buildid directory!\n");
410  return -1;
411  }
412  strncpy(buildid_dir, dir, MAXPATHLEN-1);
413  buildid_dir[MAXPATHLEN-1] = '\0';
414  }
415 
416  return 0;
417 }
418 
419 static int perf_default_core_config(const char *var __maybe_unused,
420  const char *value __maybe_unused)
421 {
422  /* Add other config variables here. */
423  return 0;
424 }
425 
426 static int perf_ui_config(const char *var, const char *value)
427 {
428  /* Add other config variables here. */
429  if (!strcmp(var, "ui.show-headers"))
431 
432  return 0;
433 }
434 
435 int perf_default_config(const char *var, const char *value,
436  void *dummy __maybe_unused)
437 {
438  if (strstarts(var, "core."))
439  return perf_default_core_config(var, value);
440 
441  if (strstarts(var, "hist."))
442  return perf_hist_config(var, value);
443 
444  if (strstarts(var, "ui."))
445  return perf_ui_config(var, value);
446 
447  if (strstarts(var, "call-graph."))
448  return perf_callchain_config(var, value);
449 
450  if (strstarts(var, "llvm."))
451  return perf_llvm_config(var, value);
452 
453  if (strstarts(var, "buildid."))
454  return perf_buildid_config(var, value);
455 
456  /* Add other config variables here. */
457  return 0;
458 }
459 
460 static int perf_config_from_file(config_fn_t fn, const char *filename, void *data)
461 {
462  int ret;
463  FILE *f = fopen(filename, "r");
464 
465  ret = -1;
466  if (f) {
467  config_file = f;
469  config_linenr = 1;
470  config_file_eof = 0;
471  ret = perf_parse_file(fn, data);
472  fclose(f);
473  config_file_name = NULL;
474  }
475  return ret;
476 }
477 
478 const char *perf_etc_perfconfig(void)
479 {
480  static const char *system_wide;
481  if (!system_wide)
482  system_wide = system_path(ETC_PERFCONFIG);
483  return system_wide;
484 }
485 
486 static int perf_env_bool(const char *k, int def)
487 {
488  const char *v = getenv(k);
489  return v ? perf_config_bool(k, v) : def;
490 }
491 
492 static int perf_config_system(void)
493 {
494  return !perf_env_bool("PERF_CONFIG_NOSYSTEM", 0);
495 }
496 
497 static int perf_config_global(void)
498 {
499  return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0);
500 }
501 
502 static struct perf_config_section *find_section(struct list_head *sections,
503  const char *section_name)
504 {
505  struct perf_config_section *section;
506 
507  list_for_each_entry(section, sections, node)
508  if (!strcmp(section->name, section_name))
509  return section;
510 
511  return NULL;
512 }
513 
514 static struct perf_config_item *find_config_item(const char *name,
515  struct perf_config_section *section)
516 {
517  struct perf_config_item *item;
518 
519  list_for_each_entry(item, &section->items, node)
520  if (!strcmp(item->name, name))
521  return item;
522 
523  return NULL;
524 }
525 
526 static struct perf_config_section *add_section(struct list_head *sections,
527  const char *section_name)
528 {
529  struct perf_config_section *section = zalloc(sizeof(*section));
530 
531  if (!section)
532  return NULL;
533 
534  INIT_LIST_HEAD(&section->items);
535  section->name = strdup(section_name);
536  if (!section->name) {
537  pr_debug("%s: strdup failed\n", __func__);
538  free(section);
539  return NULL;
540  }
541 
542  list_add_tail(&section->node, sections);
543  return section;
544 }
545 
546 static struct perf_config_item *add_config_item(struct perf_config_section *section,
547  const char *name)
548 {
549  struct perf_config_item *item = zalloc(sizeof(*item));
550 
551  if (!item)
552  return NULL;
553 
554  item->name = strdup(name);
555  if (!item->name) {
556  pr_debug("%s: strdup failed\n", __func__);
557  free(item);
558  return NULL;
559  }
560 
561  list_add_tail(&item->node, &section->items);
562  return item;
563 }
564 
565 static int set_value(struct perf_config_item *item, const char *value)
566 {
567  char *val = strdup(value);
568 
569  if (!val)
570  return -1;
571 
572  zfree(&item->value);
573  item->value = val;
574  return 0;
575 }
576 
577 static int collect_config(const char *var, const char *value,
578  void *perf_config_set)
579 {
580  int ret = -1;
581  char *ptr, *key;
582  char *section_name, *name;
583  struct perf_config_section *section = NULL;
584  struct perf_config_item *item = NULL;
585  struct perf_config_set *set = perf_config_set;
586  struct list_head *sections;
587 
588  if (set == NULL)
589  return -1;
590 
591  sections = &set->sections;
592  key = ptr = strdup(var);
593  if (!key) {
594  pr_debug("%s: strdup failed\n", __func__);
595  return -1;
596  }
597 
598  section_name = strsep(&ptr, ".");
599  name = ptr;
600  if (name == NULL || value == NULL)
601  goto out_free;
602 
603  section = find_section(sections, section_name);
604  if (!section) {
605  section = add_section(sections, section_name);
606  if (!section)
607  goto out_free;
608  }
609 
610  item = find_config_item(name, section);
611  if (!item) {
612  item = add_config_item(section, name);
613  if (!item)
614  goto out_free;
615  }
616 
617  /* perf_config_set can contain both user and system config items.
618  * So we should know where each value is from.
619  * The classification would be needed when a particular config file
620  * is overwrited by setting feature i.e. set_config().
621  */
622  if (strcmp(config_file_name, perf_etc_perfconfig()) == 0) {
623  section->from_system_config = true;
624  item->from_system_config = true;
625  } else {
626  section->from_system_config = false;
627  item->from_system_config = false;
628  }
629 
630  ret = set_value(item, value);
631  return ret;
632 
633 out_free:
634  free(key);
635  return -1;
636 }
637 
638 int perf_config_set__collect(struct perf_config_set *set, const char *file_name,
639  const char *var, const char *value)
640 {
641  config_file_name = file_name;
642  return collect_config(var, value, set);
643 }
644 
645 static int perf_config_set__init(struct perf_config_set *set)
646 {
647  int ret = -1;
648  const char *home = NULL;
649  char *user_config;
650  struct stat st;
651 
652  /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */
655  if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) {
657  goto out;
658  }
659 
660  home = getenv("HOME");
661 
662  /*
663  * Skip reading user config if:
664  * - there is no place to read it from (HOME)
665  * - we are asked not to (PERF_CONFIG_NOGLOBAL=1)
666  */
667  if (!home || !*home || !perf_config_global())
668  return 0;
669 
670  user_config = strdup(mkpath("%s/.perfconfig", home));
671  if (user_config == NULL) {
672  pr_warning("Not enough memory to process %s/.perfconfig, ignoring it.", home);
673  goto out;
674  }
675 
676  if (stat(user_config, &st) < 0) {
677  if (errno == ENOENT)
678  ret = 0;
679  goto out_free;
680  }
681 
682  ret = 0;
683 
684  if (st.st_uid && (st.st_uid != geteuid())) {
685  pr_warning("File %s not owned by current user or root, ignoring it.", user_config);
686  goto out_free;
687  }
688 
689  if (st.st_size)
690  ret = perf_config_from_file(collect_config, user_config, set);
691 
692 out_free:
693  free(user_config);
694 out:
695  return ret;
696 }
697 
699 {
700  struct perf_config_set *set = zalloc(sizeof(*set));
701 
702  if (set) {
703  INIT_LIST_HEAD(&set->sections);
705  }
706 
707  return set;
708 }
709 
710 static int perf_config__init(void)
711 {
712  if (config_set == NULL)
713  config_set = perf_config_set__new();
714 
715  return config_set == NULL;
716 }
717 
719 {
720  int ret = 0;
721  char key[BUFSIZ];
722  struct perf_config_section *section;
723  struct perf_config_item *item;
724 
725  if (config_set == NULL && perf_config__init())
726  return -1;
727 
728  perf_config_set__for_each_entry(config_set, section, item) {
729  char *value = item->value;
730 
731  if (value) {
732  scnprintf(key, sizeof(key), "%s.%s",
733  section->name, item->name);
734  ret = fn(key, value, data);
735  if (ret < 0) {
736  pr_err("Error: wrong config key-value pair %s=%s\n",
737  key, value);
738  break;
739  }
740  }
741  }
742 
743  return ret;
744 }
745 
747 {
748  perf_config_set__delete(config_set);
749  config_set = NULL;
750 }
751 
753 {
756 }
757 
759 {
760  zfree(&item->name);
761  zfree(&item->value);
762  free(item);
763 }
764 
766 {
767  struct perf_config_item *item, *tmp;
768 
769  list_for_each_entry_safe(item, tmp, &section->items, node) {
770  list_del_init(&item->node);
772  }
773 }
774 
776 {
778  zfree(&section->name);
779  free(section);
780 }
781 
782 static void perf_config_set__purge(struct perf_config_set *set)
783 {
784  struct perf_config_section *section, *tmp;
785 
786  list_for_each_entry_safe(section, tmp, &set->sections, node) {
787  list_del_init(&section->node);
789  }
790 }
791 
793 {
794  if (set == NULL)
795  return;
796 
798  free(set);
799 }
800 
801 /*
802  * Call this to report error for your variable that should not
803  * get a boolean value (i.e. "[my] var" means "true").
804  */
805 int config_error_nonbool(const char *var)
806 {
807  pr_err("Missing value for '%s'", var);
808  return -1;
809 }
810 
811 void set_buildid_dir(const char *dir)
812 {
813  if (dir)
814  scnprintf(buildid_dir, MAXPATHLEN-1, "%s", dir);
815 
816  /* default to $HOME/.debug */
817  if (buildid_dir[0] == '\0') {
818  char *home = getenv("HOME");
819 
820  if (home) {
821  snprintf(buildid_dir, MAXPATHLEN-1, "%s/%s",
822  home, DEBUG_CACHE_DIR);
823  } else {
824  strncpy(buildid_dir, DEBUG_CACHE_DIR, MAXPATHLEN-1);
825  }
826  buildid_dir[MAXPATHLEN-1] = '\0';
827  }
828  /* for communicating with external commands */
829  setenv("PERF_BUILDID_DIR", buildid_dir, 1);
830 }
static const char * perf_config_dirname(const char *name, const char *value)
Definition: config.c:395
static void perf_config_set__purge(struct perf_config_set *set)
Definition: config.c:782
#define isalnum(x)
Definition: sane_ctype.h:38
#define isalpha(x)
Definition: sane_ctype.h:37
static int perf_parse_long(const char *value, long *ret)
Definition: config.c:326
Definition: mem2node.c:7
int value
Definition: python.c:1143
static struct perf_config_section * find_section(struct list_head *sections, const char *section_name)
Definition: config.c:502
char * name
Definition: config.h:9
static int iskeychar(int c)
Definition: config.c:134
#define MAXNAME
Definition: config.c:27
void perf_config_set__delete(struct perf_config_set *set)
Definition: config.c:792
static void bad_config(const char *name)
Definition: config.c:340
static int perf_config_from_file(config_fn_t fn, const char *filename, void *data)
Definition: config.c:460
static char * dir
Definition: attr.c:39
int perf_default_config(const char *var, const char *value, void *dummy __maybe_unused)
Definition: config.c:435
static int perf_config_set__init(struct perf_config_set *set)
Definition: config.c:645
#define isspace(x)
Definition: sane_ctype.h:33
int perf_config_int(int *dest, const char *name, const char *value)
Definition: config.c:361
const char * filename
Definition: hists_common.c:26
dictionary data
Definition: stat-cpi.py:4
int perf_hist_config(const char *var, const char *value)
Definition: hist.c:2554
static int parse_unit_factor(const char *end, unsigned long *val)
Definition: config.c:292
int perf_config_bool(const char *name, const char *value)
Definition: config.c:389
static void perf_config_section__purge(struct perf_config_section *section)
Definition: config.c:765
static int collect_config(const char *var, const char *value, void *perf_config_set)
Definition: config.c:577
static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
Definition: config.c:139
int perf_llvm_config(const char *var, const char *value)
Definition: llvm-utils.c:36
#define pr_err(fmt,...)
Definition: json.h:21
static int perf_buildid_config(const char *var, const char *value)
Definition: config.c:402
struct perf_config_set * perf_config_set__new(void)
Definition: config.c:698
const char * key
Definition: bpf-loader.c:196
const char * name
char * value
Definition: config.h:10
bool from_system_config
Definition: config.h:18
static bool system_wide
#define pr_debug(fmt,...)
Definition: json.h:27
char buildid_dir[MAXPATHLEN]
Definition: config.c:32
static struct perf_config_item * find_config_item(const char *name, struct perf_config_section *section)
Definition: config.c:514
static int get_extended_base_var(char *name, int baselen, int c)
Definition: config.c:170
struct list_head node
Definition: config.h:12
struct list_head items
Definition: config.h:17
static int perf_config_system(void)
Definition: config.c:492
const char * config_exclusive_filename
Definition: config.c:40
void perf_config__exit(void)
Definition: config.c:746
static int config_file_eof
Definition: config.c:37
#define DEBUG_CACHE_DIR
Definition: config.c:29
int perf_config_u64(u64 *dest, const char *name, const char *value)
Definition: config.c:348
bool from_system_config
Definition: config.h:11
static int perf_parse_llong(const char *value, long long *ret)
Definition: config.c:311
static int perf_config_global(void)
Definition: config.c:497
static FILE * config_file
Definition: config.c:34
static int perf_config_bool_or_int(const char *name, const char *value, int *is_bool)
Definition: config.c:372
static int perf_parse_file(config_fn_t fn, void *data)
Definition: config.c:226
static int config_linenr
Definition: config.c:36
bool show_hist_headers
Definition: symbol.h:93
void perf_config__refresh(void)
Definition: config.c:752
static struct perf_config_set * config_set
Definition: config.c:38
const char * perf_etc_perfconfig(void)
Definition: config.c:478
#define zfree(ptr)
Definition: util.h:25
static int perf_env_bool(const char *k, int def)
Definition: config.c:486
static int perf_default_core_config(const char *var __maybe_unused, const char *value __maybe_unused)
Definition: config.c:419
static int set_value(struct perf_config_item *item, const char *value)
Definition: config.c:565
static int get_next_char(void)
Definition: config.c:42
int perf_config(config_fn_t fn, void *data)
Definition: config.c:718
static void perf_config_section__delete(struct perf_config_section *section)
Definition: config.c:775
static char * parse_value(void)
Definition: config.c:68
static struct perf_config_item * add_config_item(struct perf_config_section *section, const char *name)
Definition: config.c:546
static struct perf_config_section * add_section(struct list_head *sections, const char *section_name)
Definition: config.c:526
int(* config_fn_t)(const char *, const char *, void *)
Definition: config.h:28
static int perf_config__init(void)
Definition: config.c:710
void free(void *)
static FILE * f
Definition: intel-pt-log.c:30
int perf_callchain_config(const char *var, const char *value)
Definition: callchain.c:306
void set_buildid_dir(const char *dir)
Definition: config.c:811
#define pr_warning(fmt,...)
Definition: debug.h:25
#define perf_config_set__for_each_entry(set, section, item)
Definition: config.h:66
static void perf_config_item__delete(struct perf_config_item *item)
Definition: config.c:758
static int get_base_var(char *name)
Definition: config.c:206
int config_error_nonbool(const char *var)
Definition: config.c:805
#define tolower(x)
Definition: sane_ctype.h:42
int perf_config_set__collect(struct perf_config_set *set, const char *file_name, const char *var, const char *value)
Definition: config.c:638
char * mkpath(const char *fmt,...) __printf(1
static const char * config_file_name
Definition: config.c:35
static int perf_ui_config(const char *var, const char *value)
Definition: config.c:426
void static void * zalloc(size_t size)
Definition: util.h:20
struct list_head node
Definition: config.h:19