git-config: collect values instead of immediately printing
This is a refactor that will allow us to more easily tweak the behavior for multi-valued variables, and it will ultimately allow us to remove a lot git-config's custom code in favor of the regular git_config code. It does mean we're no longer streaming, and we're storing more in memory for the --get-all case, but in practice it is a tiny amount of data, and the results are instantaneous. Signed-off-by: Jeff King <peff@peff.net>
Jeff King committed
Oct 23, 2012 at 15:51 UTC
7acdd6f0bc27bba37591e2d5fc2ca84e2af13ce4
1 file changed
+35
-15
builtin/config.c
+35
-15
@@ -15,7 +15,6 @@ static int show_keys;
15
static int use_key_regexp;
16
static int do_all;
17
static int do_not_match;
18
-static int seen;
18
static char delim = '=';
19
static char key_delim = ' ';
20
static char term = '\n';
@@ -95,8 +94,16 @@ static int show_all_config(const char *key_, const char *value_, void *cb)
94
return 0;
95
}
96
98
-static int show_config(const char *key_, const char *value_, void *cb)
97
+struct strbuf_list {
98
+ struct strbuf *items;
99
+ int nr;
100
+ int alloc;
101
+};
102
+
103
+static int collect_config(const char *key_, const char *value_, void *cb)
104
{
105
+ struct strbuf_list *values = cb;
106
+ struct strbuf *buf;
107
char value[256];
108
const char *vptr = value;
109
int must_free_vptr = 0;
@@ -111,11 +118,15 @@ static int show_config(const char *key_, const char *value_, void *cb)
118
(do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0)))
119
return 0;
120
121
+ ALLOC_GROW(values->items, values->nr + 1, values->alloc);
122
+ buf = &values->items[values->nr++];
123
+ strbuf_init(buf, 0);
124
+
125
if (show_keys) {
115
- printf("%s", key_);
126
+ strbuf_addstr(buf, key_);
127
must_print_delim = 1;
128
}
118
- if (seen && !do_all)
129
+ if (values->nr > 1 && !do_all)
130
dup_error = 1;
131
if (types == TYPE_INT)
132
sprintf(value, "%d", git_config_int(key_, value_?value_:""));
@@ -138,15 +149,15 @@ static int show_config(const char *key_, const char *value_, void *cb)
149
vptr = "";
150
must_print_delim = 0;
151
}
141
- seen++;
152
if (dup_error) {
153
error("More than one value for the key %s: %s",
154
key_, vptr);
155
}
156
else {
157
if (must_print_delim)
148
- printf("%c", key_delim);
149
- printf("%s%c", vptr, term);
158
+ strbuf_addch(buf, key_delim);
159
+ strbuf_addstr(buf, vptr);
160
+ strbuf_addch(buf, term);
161
}
162
if (must_free_vptr)
163
/* If vptr must be freed, it's a pointer to a
@@ -166,6 +177,8 @@ static int get_value(const char *key_, const char *regex_)
177
struct config_include_data inc = CONFIG_INCLUDE_INIT;
178
config_fn_t fn;
179
void *data;
180
+ struct strbuf_list values = {0};
181
+ int i;
182
183
local = given_config_file;
184
if (!local) {
@@ -223,8 +236,8 @@ static int get_value(const char *key_, const char *regex_)
236
}
237
}
238
226
- fn = show_config;
227
- data = NULL;
239
+ fn = collect_config;
240
+ data = &values;
241
if (respect_includes) {
242
inc.fn = fn;
243
inc.data = data;
@@ -241,19 +254,26 @@ static int get_value(const char *key_, const char *regex_)
254
if (do_all)
255
git_config_from_file(fn, local, data);
256
git_config_from_parameters(fn, data);
244
- if (!do_all && !seen)
257
+ if (!do_all && !values.nr)
258
git_config_from_file(fn, local, data);
246
- if (!do_all && !seen && global)
259
+ if (!do_all && !values.nr && global)
260
git_config_from_file(fn, global, data);
248
- if (!do_all && !seen && xdg)
261
+ if (!do_all && !values.nr && xdg)
262
git_config_from_file(fn, xdg, data);
250
- if (!do_all && !seen && system_wide)
263
+ if (!do_all && !values.nr && system_wide)
264
git_config_from_file(fn, system_wide, data);
265
266
if (do_all)
254
- ret = !seen;
267
+ ret = !values.nr;
268
else
256
- ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1;
269
+ ret = (values.nr == 1) ? 0 : values.nr > 1 ? 2 : 1;
270
+
271
+ for (i = 0; i < values.nr; i++) {
272
+ struct strbuf *buf = values.items + i;
273
+ fwrite(buf->buf, 1, buf->len, stdout);
274
+ strbuf_release(buf);
275
+ }
276
+ free(values.items);
277
278
free_strings:
279
free(repo_config);