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>
This commit is contained in:
parent
97ed50f93b
commit
7acdd6f0bc
@ -15,7 +15,6 @@ static int show_keys;
|
|||||||
static int use_key_regexp;
|
static int use_key_regexp;
|
||||||
static int do_all;
|
static int do_all;
|
||||||
static int do_not_match;
|
static int do_not_match;
|
||||||
static int seen;
|
|
||||||
static char delim = '=';
|
static char delim = '=';
|
||||||
static char key_delim = ' ';
|
static char key_delim = ' ';
|
||||||
static char term = '\n';
|
static char term = '\n';
|
||||||
@ -95,8 +94,16 @@ static int show_all_config(const char *key_, const char *value_, void *cb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int show_config(const char *key_, const char *value_, void *cb)
|
struct strbuf_list {
|
||||||
|
struct strbuf *items;
|
||||||
|
int nr;
|
||||||
|
int alloc;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int collect_config(const char *key_, const char *value_, void *cb)
|
||||||
{
|
{
|
||||||
|
struct strbuf_list *values = cb;
|
||||||
|
struct strbuf *buf;
|
||||||
char value[256];
|
char value[256];
|
||||||
const char *vptr = value;
|
const char *vptr = value;
|
||||||
int must_free_vptr = 0;
|
int must_free_vptr = 0;
|
||||||
@ -111,11 +118,15 @@ static int show_config(const char *key_, const char *value_, void *cb)
|
|||||||
(do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0)))
|
(do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
ALLOC_GROW(values->items, values->nr + 1, values->alloc);
|
||||||
|
buf = &values->items[values->nr++];
|
||||||
|
strbuf_init(buf, 0);
|
||||||
|
|
||||||
if (show_keys) {
|
if (show_keys) {
|
||||||
printf("%s", key_);
|
strbuf_addstr(buf, key_);
|
||||||
must_print_delim = 1;
|
must_print_delim = 1;
|
||||||
}
|
}
|
||||||
if (seen && !do_all)
|
if (values->nr > 1 && !do_all)
|
||||||
dup_error = 1;
|
dup_error = 1;
|
||||||
if (types == TYPE_INT)
|
if (types == TYPE_INT)
|
||||||
sprintf(value, "%d", git_config_int(key_, value_?value_:""));
|
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)
|
|||||||
vptr = "";
|
vptr = "";
|
||||||
must_print_delim = 0;
|
must_print_delim = 0;
|
||||||
}
|
}
|
||||||
seen++;
|
|
||||||
if (dup_error) {
|
if (dup_error) {
|
||||||
error("More than one value for the key %s: %s",
|
error("More than one value for the key %s: %s",
|
||||||
key_, vptr);
|
key_, vptr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (must_print_delim)
|
if (must_print_delim)
|
||||||
printf("%c", key_delim);
|
strbuf_addch(buf, key_delim);
|
||||||
printf("%s%c", vptr, term);
|
strbuf_addstr(buf, vptr);
|
||||||
|
strbuf_addch(buf, term);
|
||||||
}
|
}
|
||||||
if (must_free_vptr)
|
if (must_free_vptr)
|
||||||
/* If vptr must be freed, it's a pointer to a
|
/* 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_)
|
|||||||
struct config_include_data inc = CONFIG_INCLUDE_INIT;
|
struct config_include_data inc = CONFIG_INCLUDE_INIT;
|
||||||
config_fn_t fn;
|
config_fn_t fn;
|
||||||
void *data;
|
void *data;
|
||||||
|
struct strbuf_list values = {0};
|
||||||
|
int i;
|
||||||
|
|
||||||
local = given_config_file;
|
local = given_config_file;
|
||||||
if (!local) {
|
if (!local) {
|
||||||
@ -223,8 +236,8 @@ static int get_value(const char *key_, const char *regex_)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn = show_config;
|
fn = collect_config;
|
||||||
data = NULL;
|
data = &values;
|
||||||
if (respect_includes) {
|
if (respect_includes) {
|
||||||
inc.fn = fn;
|
inc.fn = fn;
|
||||||
inc.data = data;
|
inc.data = data;
|
||||||
@ -241,19 +254,26 @@ static int get_value(const char *key_, const char *regex_)
|
|||||||
if (do_all)
|
if (do_all)
|
||||||
git_config_from_file(fn, local, data);
|
git_config_from_file(fn, local, data);
|
||||||
git_config_from_parameters(fn, data);
|
git_config_from_parameters(fn, data);
|
||||||
if (!do_all && !seen)
|
if (!do_all && !values.nr)
|
||||||
git_config_from_file(fn, local, data);
|
git_config_from_file(fn, local, data);
|
||||||
if (!do_all && !seen && global)
|
if (!do_all && !values.nr && global)
|
||||||
git_config_from_file(fn, global, data);
|
git_config_from_file(fn, global, data);
|
||||||
if (!do_all && !seen && xdg)
|
if (!do_all && !values.nr && xdg)
|
||||||
git_config_from_file(fn, xdg, data);
|
git_config_from_file(fn, xdg, data);
|
||||||
if (!do_all && !seen && system_wide)
|
if (!do_all && !values.nr && system_wide)
|
||||||
git_config_from_file(fn, system_wide, data);
|
git_config_from_file(fn, system_wide, data);
|
||||||
|
|
||||||
if (do_all)
|
if (do_all)
|
||||||
ret = !seen;
|
ret = !values.nr;
|
||||||
else
|
else
|
||||||
ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1;
|
ret = (values.nr == 1) ? 0 : values.nr > 1 ? 2 : 1;
|
||||||
|
|
||||||
|
for (i = 0; i < values.nr; i++) {
|
||||||
|
struct strbuf *buf = values.items + i;
|
||||||
|
fwrite(buf->buf, 1, buf->len, stdout);
|
||||||
|
strbuf_release(buf);
|
||||||
|
}
|
||||||
|
free(values.items);
|
||||||
|
|
||||||
free_strings:
|
free_strings:
|
||||||
free(repo_config);
|
free(repo_config);
|
||||||
|
Loading…
Reference in New Issue
Block a user