/src/git/trace2/tr2_cfg.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "git-compat-util.h" |
2 | | #include "config.h" |
3 | | #include "strbuf.h" |
4 | | #include "trace2.h" |
5 | | #include "trace2/tr2_cfg.h" |
6 | | #include "trace2/tr2_sysenv.h" |
7 | | #include "wildmatch.h" |
8 | | |
9 | | static struct strbuf **tr2_cfg_patterns; |
10 | | static int tr2_cfg_count_patterns; |
11 | | static int tr2_cfg_loaded; |
12 | | |
13 | | static struct strbuf **tr2_cfg_env_vars; |
14 | | static int tr2_cfg_env_vars_count; |
15 | | static int tr2_cfg_env_vars_loaded; |
16 | | |
17 | | /* |
18 | | * Parse a string containing a comma-delimited list of config keys |
19 | | * or wildcard patterns into a list of strbufs. |
20 | | */ |
21 | | static int tr2_cfg_load_patterns(void) |
22 | 0 | { |
23 | 0 | struct strbuf **s; |
24 | 0 | const char *envvar; |
25 | |
|
26 | 0 | if (tr2_cfg_loaded) |
27 | 0 | return tr2_cfg_count_patterns; |
28 | 0 | tr2_cfg_loaded = 1; |
29 | |
|
30 | 0 | envvar = tr2_sysenv_get(TR2_SYSENV_CFG_PARAM); |
31 | 0 | if (!envvar || !*envvar) |
32 | 0 | return tr2_cfg_count_patterns; |
33 | | |
34 | 0 | tr2_cfg_patterns = strbuf_split_buf(envvar, strlen(envvar), ',', -1); |
35 | 0 | for (s = tr2_cfg_patterns; *s; s++) { |
36 | 0 | struct strbuf *buf = *s; |
37 | |
|
38 | 0 | if (buf->len && buf->buf[buf->len - 1] == ',') |
39 | 0 | strbuf_setlen(buf, buf->len - 1); |
40 | 0 | strbuf_trim_trailing_newline(*s); |
41 | 0 | strbuf_trim(*s); |
42 | 0 | } |
43 | |
|
44 | 0 | tr2_cfg_count_patterns = s - tr2_cfg_patterns; |
45 | 0 | return tr2_cfg_count_patterns; |
46 | 0 | } |
47 | | |
48 | | void tr2_cfg_free_patterns(void) |
49 | 0 | { |
50 | 0 | if (tr2_cfg_patterns) |
51 | 0 | strbuf_list_free(tr2_cfg_patterns); |
52 | 0 | tr2_cfg_count_patterns = 0; |
53 | 0 | tr2_cfg_loaded = 0; |
54 | 0 | } |
55 | | |
56 | | /* |
57 | | * Parse a string containing a comma-delimited list of environment variable |
58 | | * names into a list of strbufs. |
59 | | */ |
60 | | static int tr2_load_env_vars(void) |
61 | 0 | { |
62 | 0 | struct strbuf **s; |
63 | 0 | const char *varlist; |
64 | |
|
65 | 0 | if (tr2_cfg_env_vars_loaded) |
66 | 0 | return tr2_cfg_env_vars_count; |
67 | 0 | tr2_cfg_env_vars_loaded = 1; |
68 | |
|
69 | 0 | varlist = tr2_sysenv_get(TR2_SYSENV_ENV_VARS); |
70 | 0 | if (!varlist || !*varlist) |
71 | 0 | return tr2_cfg_env_vars_count; |
72 | | |
73 | 0 | tr2_cfg_env_vars = strbuf_split_buf(varlist, strlen(varlist), ',', -1); |
74 | 0 | for (s = tr2_cfg_env_vars; *s; s++) { |
75 | 0 | struct strbuf *buf = *s; |
76 | |
|
77 | 0 | if (buf->len && buf->buf[buf->len - 1] == ',') |
78 | 0 | strbuf_setlen(buf, buf->len - 1); |
79 | 0 | strbuf_trim_trailing_newline(*s); |
80 | 0 | strbuf_trim(*s); |
81 | 0 | } |
82 | |
|
83 | 0 | tr2_cfg_env_vars_count = s - tr2_cfg_env_vars; |
84 | 0 | return tr2_cfg_env_vars_count; |
85 | 0 | } |
86 | | |
87 | | void tr2_cfg_free_env_vars(void) |
88 | 0 | { |
89 | 0 | if (tr2_cfg_env_vars) |
90 | 0 | strbuf_list_free(tr2_cfg_env_vars); |
91 | 0 | tr2_cfg_env_vars_count = 0; |
92 | 0 | tr2_cfg_env_vars_loaded = 0; |
93 | 0 | } |
94 | | |
95 | | struct tr2_cfg_data { |
96 | | const char *file; |
97 | | int line; |
98 | | }; |
99 | | |
100 | | /* |
101 | | * See if the given config key matches any of our patterns of interest. |
102 | | */ |
103 | | static int tr2_cfg_cb(const char *key, const char *value, |
104 | | const struct config_context *ctx, void *d) |
105 | 0 | { |
106 | 0 | struct strbuf **s; |
107 | 0 | struct tr2_cfg_data *data = (struct tr2_cfg_data *)d; |
108 | |
|
109 | 0 | for (s = tr2_cfg_patterns; *s; s++) { |
110 | 0 | struct strbuf *buf = *s; |
111 | 0 | int wm = wildmatch(buf->buf, key, WM_CASEFOLD); |
112 | 0 | if (wm == WM_MATCH) { |
113 | 0 | trace2_def_param_fl(data->file, data->line, key, value, |
114 | 0 | ctx->kvi); |
115 | 0 | return 0; |
116 | 0 | } |
117 | 0 | } |
118 | | |
119 | 0 | return 0; |
120 | 0 | } |
121 | | |
122 | | void tr2_cfg_list_config_fl(const char *file, int line) |
123 | 0 | { |
124 | 0 | struct tr2_cfg_data data = { file, line }; |
125 | |
|
126 | 0 | if (tr2_cfg_load_patterns() > 0) |
127 | 0 | read_early_config(tr2_cfg_cb, &data); |
128 | 0 | } |
129 | | |
130 | | void tr2_list_env_vars_fl(const char *file, int line) |
131 | 0 | { |
132 | 0 | struct key_value_info kvi = KVI_INIT; |
133 | 0 | struct strbuf **s; |
134 | |
|
135 | 0 | kvi_from_param(&kvi); |
136 | 0 | if (tr2_load_env_vars() <= 0) |
137 | 0 | return; |
138 | | |
139 | 0 | for (s = tr2_cfg_env_vars; *s; s++) { |
140 | 0 | struct strbuf *buf = *s; |
141 | 0 | const char *val = getenv(buf->buf); |
142 | 0 | if (val && *val) |
143 | 0 | trace2_def_param_fl(file, line, buf->buf, val, &kvi); |
144 | 0 | } |
145 | 0 | } |
146 | | |
147 | | void tr2_cfg_set_fl(const char *file, int line, const char *key, |
148 | | const char *value) |
149 | 0 | { |
150 | 0 | struct key_value_info kvi = KVI_INIT; |
151 | 0 | struct config_context ctx = { |
152 | 0 | .kvi = &kvi, |
153 | 0 | }; |
154 | 0 | struct tr2_cfg_data data = { file, line }; |
155 | |
|
156 | 0 | if (tr2_cfg_load_patterns() > 0) |
157 | 0 | tr2_cfg_cb(key, value, &ctx, &data); |
158 | 0 | } |