summaryrefslogtreecommitdiff
path: root/config.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2016-05-26 20:32:23 -0400
committerJunio C Hamano <gitster@pobox.com>2016-05-27 10:44:54 -0700
commit0d44a2dacc84fb7dcb5d684800e976f3b3c76d00 (patch)
tree2e66639973179ad660efd496b83eb328bd3a20de /config.c
parent3258258f51f45efeff5ce0e9f825f347a1404efa (diff)
downloadgit-0d44a2dacc84fb7dcb5d684800e976f3b3c76d00.tar.gz
config: return configset value for current_config_ functions
When 473166b (config: add 'origin_type' to config_source struct, 2016-02-19) added accessor functions for the origin type and name, it taught them only to look at the "cf" struct that is filled in while we are parsing the config. This is sufficient to make it work with git-config, which uses git_config_with_options() under the hood. That function freshly parses the config files and triggers the callback when it parses each key. Most git programs, however, use git_config(). This interface will populate a cache during the actual parse, and then serve values from the cache. Calling current_config_filename() in a callback here will find a NULL cf and produce an error. There are no such callers right now, but let's prepare for adding some by making this work. We already record source information in a struct attached to each value. We just need to make it globally available and then consult it from the accessor functions. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'config.c')
-rw-r--r--config.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/config.c b/config.c
index 571151f3e4..d555deeb9a 100644
--- a/config.c
+++ b/config.c
@@ -38,7 +38,24 @@ struct config_source {
long (*do_ftell)(struct config_source *c);
};
+/*
+ * These variables record the "current" config source, which
+ * can be accessed by parsing callbacks.
+ *
+ * The "cf" variable will be non-NULL only when we are actually parsing a real
+ * config source (file, blob, cmdline, etc).
+ *
+ * The "current_config_kvi" variable will be non-NULL only when we are feeding
+ * cached config from a configset into a callback.
+ *
+ * They should generally never be non-NULL at the same time. If they are both
+ * NULL, then we aren't parsing anything (and depending on the function looking
+ * at the variables, it's either a bug for it to be called in the first place,
+ * or it's a function which can be reused for non-config purposes, and should
+ * fall back to some sane behavior).
+ */
static struct config_source *cf;
+static struct key_value_info *current_config_kvi;
static int zlib_compression_seen;
@@ -1284,16 +1301,20 @@ static void configset_iter(struct config_set *cs, config_fn_t fn, void *data)
struct string_list *values;
struct config_set_element *entry;
struct configset_list *list = &cs->list;
- struct key_value_info *kv_info;
for (i = 0; i < list->nr; i++) {
entry = list->items[i].e;
value_index = list->items[i].value_index;
values = &entry->value_list;
- if (fn(entry->key, values->items[value_index].string, data) < 0) {
- kv_info = values->items[value_index].util;
- git_die_config_linenr(entry->key, kv_info->filename, kv_info->linenr);
- }
+
+ current_config_kvi = values->items[value_index].util;
+
+ if (fn(entry->key, values->items[value_index].string, data) < 0)
+ git_die_config_linenr(entry->key,
+ current_config_kvi->filename,
+ current_config_kvi->linenr);
+
+ current_config_kvi = NULL;
}
}
@@ -1355,10 +1376,12 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
if (cf->name) {
kv_info->filename = strintern(cf->name);
kv_info->linenr = cf->linenr;
+ kv_info->origin_type = strintern(cf->origin_type);
} else {
/* for values read from `git_config_from_parameters()` */
kv_info->filename = NULL;
kv_info->linenr = -1;
+ kv_info->origin_type = NULL;
}
si->util = kv_info;
@@ -2438,14 +2461,24 @@ int parse_config_key(const char *var,
const char *current_config_origin_type(void)
{
- if (!cf)
+ const char *type;
+ if (current_config_kvi)
+ type = current_config_kvi->origin_type;
+ else if(cf)
+ type = cf->origin_type;
+ else
die("BUG: current_config_origin_type called outside config callback");
- return cf->origin_type ? cf->origin_type : "command line";
+ return type ? type : "command line";
}
const char *current_config_name(void)
{
- if (!cf)
+ const char *name;
+ if (current_config_kvi)
+ name = current_config_kvi->filename;
+ else if (cf)
+ name = cf->name;
+ else
die("BUG: current_config_name called outside config callback");
- return cf->name ? cf->name : "";
+ return name ? name : "";
}