Merge branch 'am/p4-branches-excludes'
[git/git.git] / trace2 / tr2_sysenv.c
CommitLineData
bce9db6d
JH
1#include "cache.h"
2#include "config.h"
3#include "dir.h"
4#include "tr2_sysenv.h"
5
6/*
7 * Each entry represents a trace2 setting.
8 * See Documentation/technical/api-trace2.txt
9 */
10struct tr2_sysenv_entry {
11 const char *env_var_name;
12 const char *git_config_name;
13
14 char *value;
15 unsigned int getenv_called : 1;
16};
17
18/*
19 * This table must match "enum tr2_sysenv_variable" in tr2_sysenv.h.
20 *
21 * The strings in this table are constant and must match the published
22 * config and environment variable names as described in the documentation.
23 *
e4b75d6a 24 * We do not define entries for the GIT_TRACE2_PARENT_* environment
bce9db6d
JH
25 * variables because they are transient and used to pass information
26 * from parent to child git processes, rather than settings.
27 */
28/* clang-format off */
29static struct tr2_sysenv_entry tr2_sysenv_settings[] = {
e4b75d6a 30 [TR2_SYSENV_CFG_PARAM] = { "GIT_TRACE2_CONFIG_PARAMS",
bce9db6d
JH
31 "trace2.configparams" },
32
e4b75d6a 33 [TR2_SYSENV_DST_DEBUG] = { "GIT_TRACE2_DST_DEBUG",
bce9db6d
JH
34 "trace2.destinationdebug" },
35
e4b75d6a 36 [TR2_SYSENV_NORMAL] = { "GIT_TRACE2",
bce9db6d 37 "trace2.normaltarget" },
e4b75d6a 38 [TR2_SYSENV_NORMAL_BRIEF] = { "GIT_TRACE2_BRIEF",
bce9db6d
JH
39 "trace2.normalbrief" },
40
e4b75d6a 41 [TR2_SYSENV_EVENT] = { "GIT_TRACE2_EVENT",
bce9db6d 42 "trace2.eventtarget" },
e4b75d6a 43 [TR2_SYSENV_EVENT_BRIEF] = { "GIT_TRACE2_EVENT_BRIEF",
bce9db6d 44 "trace2.eventbrief" },
e4b75d6a 45 [TR2_SYSENV_EVENT_NESTING] = { "GIT_TRACE2_EVENT_NESTING",
bce9db6d
JH
46 "trace2.eventnesting" },
47
e4b75d6a 48 [TR2_SYSENV_PERF] = { "GIT_TRACE2_PERF",
bce9db6d 49 "trace2.perftarget" },
e4b75d6a 50 [TR2_SYSENV_PERF_BRIEF] = { "GIT_TRACE2_PERF_BRIEF",
bce9db6d
JH
51 "trace2.perfbrief" },
52};
53/* clang-format on */
54
55static int tr2_sysenv_cb(const char *key, const char *value, void *d)
56{
57 int k;
58
59 if (!starts_with(key, "trace2."))
60 return 0;
61
62 for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) {
63 if (!strcmp(key, tr2_sysenv_settings[k].git_config_name)) {
64 free(tr2_sysenv_settings[k].value);
65 tr2_sysenv_settings[k].value = xstrdup(value);
66 return 0;
67 }
68 }
69
70 return 0;
71}
72
73/*
74 * Load Trace2 settings from the system config (usually "/etc/gitconfig"
75 * unless we were built with a runtime-prefix). These are intended to
76 * define the default values for Trace2 as requested by the administrator.
77 *
78 * Then override with the Trace2 settings from the global config.
79 */
80void tr2_sysenv_load(void)
81{
82 if (ARRAY_SIZE(tr2_sysenv_settings) != TR2_SYSENV_MUST_BE_LAST)
83 BUG("tr2_sysenv_settings size is wrong");
84
85 read_very_early_config(tr2_sysenv_cb, NULL);
86}
87
88/*
89 * Return the value for the requested Trace2 setting from these sources:
90 * the system config, the global config, and the environment.
91 */
92const char *tr2_sysenv_get(enum tr2_sysenv_variable var)
93{
94 if (var >= TR2_SYSENV_MUST_BE_LAST)
95 BUG("tr2_sysenv_get invalid var '%d'", var);
96
97 if (!tr2_sysenv_settings[var].getenv_called) {
98 const char *v = getenv(tr2_sysenv_settings[var].env_var_name);
99 if (v && *v) {
100 free(tr2_sysenv_settings[var].value);
101 tr2_sysenv_settings[var].value = xstrdup(v);
102 }
103 tr2_sysenv_settings[var].getenv_called = 1;
104 }
105
106 return tr2_sysenv_settings[var].value;
107}
108
109/*
110 * Return a friendly name for this setting that is suitable for printing
111 * in an error messages.
112 */
113const char *tr2_sysenv_display_name(enum tr2_sysenv_variable var)
114{
115 if (var >= TR2_SYSENV_MUST_BE_LAST)
116 BUG("tr2_sysenv_get invalid var '%d'", var);
117
118 return tr2_sysenv_settings[var].env_var_name;
119}
120
121void tr2_sysenv_release(void)
122{
123 int k;
124
125 for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++)
126 free(tr2_sysenv_settings[k].value);
127}