config.c: create config_reader and the_reader
Create "struct config_reader" to hold the state of the config source currently being read. Then, create a static instance of it, "the_reader", and use "the_reader.source" to replace references to "cf_global" in public functions. This doesn't create much immediate benefit (since we're mostly replacing static variables with a bigger static variable), but it prepares us for a future where this state doesn't have to be global; "struct config_reader" (or a similar struct) could be provided by the caller, or constructed internally by a function like "do_config_from()". A more typical approach would be to put this struct on "the_repository", but that's a worse fit for this use case since config reading is not scoped to a repository. E.g. we can read config before the repository is known ("read_very_early_config()"), blatantly ignore the repo ("read_protected_config()"), or read only from a file ("git_config_from_file()"). This is especially evident in t5318 and t9210, where test-tool and scalar parse config but don't fully initialize "the_repository". We could have also replaced the references to "cf_global" in callback functions (which are the only ones left), but we'll eventually plumb "the_reader" through the callback "*data" arg, so that would be unnecessary churn. Until we remove "cf_global" altogether, add logic to "config_reader_*_source()" to keep "cf_global" and "the_reader.source" in sync. Signed-off-by: Glen Choo <chooglen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
c009bc898b
commit
0c60285147
82
config.c
82
config.c
@ -51,6 +51,16 @@ struct config_source {
|
|||||||
};
|
};
|
||||||
#define CONFIG_SOURCE_INIT { 0 }
|
#define CONFIG_SOURCE_INIT { 0 }
|
||||||
|
|
||||||
|
struct config_reader {
|
||||||
|
struct config_source *source;
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
* Where possible, prefer to accept "struct config_reader" as an arg than to use
|
||||||
|
* "the_reader". "the_reader" should only be used if that is infeasible, e.g. in
|
||||||
|
* a public function.
|
||||||
|
*/
|
||||||
|
static struct config_reader the_reader;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These variables record the "current" config source, which
|
* These variables record the "current" config source, which
|
||||||
* can be accessed by parsing callbacks.
|
* can be accessed by parsing callbacks.
|
||||||
@ -66,6 +76,9 @@ struct config_source {
|
|||||||
* at the variables, it's either a bug for it to be called in the first place,
|
* 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
|
* or it's a function which can be reused for non-config purposes, and should
|
||||||
* fall back to some sane behavior).
|
* fall back to some sane behavior).
|
||||||
|
*
|
||||||
|
* FIXME "cf_global" has been replaced by "the_reader.source", remove
|
||||||
|
* "cf_global" once we plumb "the_reader" through all of the callback functions.
|
||||||
*/
|
*/
|
||||||
static struct config_source *cf_global;
|
static struct config_source *cf_global;
|
||||||
static struct key_value_info *current_config_kvi;
|
static struct key_value_info *current_config_kvi;
|
||||||
@ -80,19 +93,24 @@ static struct key_value_info *current_config_kvi;
|
|||||||
*/
|
*/
|
||||||
static enum config_scope current_parsing_scope;
|
static enum config_scope current_parsing_scope;
|
||||||
|
|
||||||
static inline void config_reader_push_source(struct config_source *top)
|
static inline void config_reader_push_source(struct config_reader *reader,
|
||||||
|
struct config_source *top)
|
||||||
{
|
{
|
||||||
top->prev = cf_global;
|
top->prev = reader->source;
|
||||||
cf_global = top;
|
reader->source = top;
|
||||||
|
/* FIXME remove this when cf_global is removed. */
|
||||||
|
cf_global = reader->source;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct config_source *config_reader_pop_source()
|
static inline struct config_source *config_reader_pop_source(struct config_reader *reader)
|
||||||
{
|
{
|
||||||
struct config_source *ret;
|
struct config_source *ret;
|
||||||
if (!cf_global)
|
if (!reader->source)
|
||||||
BUG("tried to pop config source, but we weren't reading config");
|
BUG("tried to pop config source, but we weren't reading config");
|
||||||
ret = cf_global;
|
ret = reader->source;
|
||||||
cf_global = cf_global->prev;
|
reader->source = reader->source->prev;
|
||||||
|
/* FIXME remove this when cf_global is removed. */
|
||||||
|
cf_global = reader->source;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -732,7 +750,7 @@ int git_config_from_parameters(config_fn_t fn, void *data)
|
|||||||
struct config_source source = CONFIG_SOURCE_INIT;
|
struct config_source source = CONFIG_SOURCE_INIT;
|
||||||
|
|
||||||
source.origin_type = CONFIG_ORIGIN_CMDLINE;
|
source.origin_type = CONFIG_ORIGIN_CMDLINE;
|
||||||
config_reader_push_source(&source);
|
config_reader_push_source(&the_reader, &source);
|
||||||
|
|
||||||
env = getenv(CONFIG_COUNT_ENVIRONMENT);
|
env = getenv(CONFIG_COUNT_ENVIRONMENT);
|
||||||
if (env) {
|
if (env) {
|
||||||
@ -790,7 +808,7 @@ int git_config_from_parameters(config_fn_t fn, void *data)
|
|||||||
strbuf_release(&envvar);
|
strbuf_release(&envvar);
|
||||||
strvec_clear(&to_free);
|
strvec_clear(&to_free);
|
||||||
free(envw);
|
free(envw);
|
||||||
config_reader_pop_source();
|
config_reader_pop_source(&the_reader);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1325,7 +1343,7 @@ int git_config_int(const char *name, const char *value)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
if (!git_parse_int(value, &ret))
|
if (!git_parse_int(value, &ret))
|
||||||
die_bad_number(cf_global, name, value);
|
die_bad_number(the_reader.source, name, value);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1333,7 +1351,7 @@ int64_t git_config_int64(const char *name, const char *value)
|
|||||||
{
|
{
|
||||||
int64_t ret;
|
int64_t ret;
|
||||||
if (!git_parse_int64(value, &ret))
|
if (!git_parse_int64(value, &ret))
|
||||||
die_bad_number(cf_global, name, value);
|
die_bad_number(the_reader.source, name, value);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1341,7 +1359,7 @@ unsigned long git_config_ulong(const char *name, const char *value)
|
|||||||
{
|
{
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
if (!git_parse_ulong(value, &ret))
|
if (!git_parse_ulong(value, &ret))
|
||||||
die_bad_number(cf_global, name, value);
|
die_bad_number(the_reader.source, name, value);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1349,7 +1367,7 @@ ssize_t git_config_ssize_t(const char *name, const char *value)
|
|||||||
{
|
{
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
if (!git_parse_ssize_t(value, &ret))
|
if (!git_parse_ssize_t(value, &ret))
|
||||||
die_bad_number(cf_global, name, value);
|
die_bad_number(the_reader.source, name, value);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1955,7 +1973,8 @@ int git_default_config(const char *var, const char *value, void *cb)
|
|||||||
* fgetc, ungetc, ftell of top need to be initialized before calling
|
* fgetc, ungetc, ftell of top need to be initialized before calling
|
||||||
* this function.
|
* this function.
|
||||||
*/
|
*/
|
||||||
static int do_config_from(struct config_source *top, config_fn_t fn, void *data,
|
static int do_config_from(struct config_reader *reader,
|
||||||
|
struct config_source *top, config_fn_t fn, void *data,
|
||||||
const struct config_options *opts)
|
const struct config_options *opts)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -1966,22 +1985,23 @@ static int do_config_from(struct config_source *top, config_fn_t fn, void *data,
|
|||||||
top->total_len = 0;
|
top->total_len = 0;
|
||||||
strbuf_init(&top->value, 1024);
|
strbuf_init(&top->value, 1024);
|
||||||
strbuf_init(&top->var, 1024);
|
strbuf_init(&top->var, 1024);
|
||||||
config_reader_push_source(top);
|
config_reader_push_source(reader, top);
|
||||||
|
|
||||||
ret = git_parse_source(top, fn, data, opts);
|
ret = git_parse_source(top, fn, data, opts);
|
||||||
|
|
||||||
/* pop config-file parsing state stack */
|
/* pop config-file parsing state stack */
|
||||||
strbuf_release(&top->value);
|
strbuf_release(&top->value);
|
||||||
strbuf_release(&top->var);
|
strbuf_release(&top->var);
|
||||||
config_reader_pop_source();
|
config_reader_pop_source(reader);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_config_from_file(config_fn_t fn,
|
static int do_config_from_file(struct config_reader *reader,
|
||||||
const enum config_origin_type origin_type,
|
config_fn_t fn,
|
||||||
const char *name, const char *path, FILE *f,
|
const enum config_origin_type origin_type,
|
||||||
void *data, const struct config_options *opts)
|
const char *name, const char *path, FILE *f,
|
||||||
|
void *data, const struct config_options *opts)
|
||||||
{
|
{
|
||||||
struct config_source top = CONFIG_SOURCE_INIT;
|
struct config_source top = CONFIG_SOURCE_INIT;
|
||||||
int ret;
|
int ret;
|
||||||
@ -1996,15 +2016,15 @@ static int do_config_from_file(config_fn_t fn,
|
|||||||
top.do_ftell = config_file_ftell;
|
top.do_ftell = config_file_ftell;
|
||||||
|
|
||||||
flockfile(f);
|
flockfile(f);
|
||||||
ret = do_config_from(&top, fn, data, opts);
|
ret = do_config_from(reader, &top, fn, data, opts);
|
||||||
funlockfile(f);
|
funlockfile(f);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int git_config_from_stdin(config_fn_t fn, void *data)
|
static int git_config_from_stdin(config_fn_t fn, void *data)
|
||||||
{
|
{
|
||||||
return do_config_from_file(fn, CONFIG_ORIGIN_STDIN, "", NULL, stdin,
|
return do_config_from_file(&the_reader, fn, CONFIG_ORIGIN_STDIN, "",
|
||||||
data, NULL);
|
NULL, stdin, data, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_config_from_file_with_options(config_fn_t fn, const char *filename,
|
int git_config_from_file_with_options(config_fn_t fn, const char *filename,
|
||||||
@ -2018,8 +2038,8 @@ int git_config_from_file_with_options(config_fn_t fn, const char *filename,
|
|||||||
BUG("filename cannot be NULL");
|
BUG("filename cannot be NULL");
|
||||||
f = fopen_or_warn(filename, "r");
|
f = fopen_or_warn(filename, "r");
|
||||||
if (f) {
|
if (f) {
|
||||||
ret = do_config_from_file(fn, CONFIG_ORIGIN_FILE, filename,
|
ret = do_config_from_file(&the_reader, fn, CONFIG_ORIGIN_FILE,
|
||||||
filename, f, data, opts);
|
filename, filename, f, data, opts);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -2048,7 +2068,7 @@ int git_config_from_mem(config_fn_t fn,
|
|||||||
top.do_ungetc = config_buf_ungetc;
|
top.do_ungetc = config_buf_ungetc;
|
||||||
top.do_ftell = config_buf_ftell;
|
top.do_ftell = config_buf_ftell;
|
||||||
|
|
||||||
return do_config_from(&top, fn, data, opts);
|
return do_config_from(&the_reader, &top, fn, data, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_config_from_blob_oid(config_fn_t fn,
|
int git_config_from_blob_oid(config_fn_t fn,
|
||||||
@ -3797,8 +3817,8 @@ const char *current_config_origin_type(void)
|
|||||||
int type;
|
int type;
|
||||||
if (current_config_kvi)
|
if (current_config_kvi)
|
||||||
type = current_config_kvi->origin_type;
|
type = current_config_kvi->origin_type;
|
||||||
else if(cf_global)
|
else if(the_reader.source)
|
||||||
type = cf_global->origin_type;
|
type = the_reader.source->origin_type;
|
||||||
else
|
else
|
||||||
BUG("current_config_origin_type called outside config callback");
|
BUG("current_config_origin_type called outside config callback");
|
||||||
|
|
||||||
@ -3843,8 +3863,8 @@ const char *current_config_name(void)
|
|||||||
const char *name;
|
const char *name;
|
||||||
if (current_config_kvi)
|
if (current_config_kvi)
|
||||||
name = current_config_kvi->filename;
|
name = current_config_kvi->filename;
|
||||||
else if (cf_global)
|
else if (the_reader.source)
|
||||||
name = cf_global->name;
|
name = the_reader.source->name;
|
||||||
else
|
else
|
||||||
BUG("current_config_name called outside config callback");
|
BUG("current_config_name called outside config callback");
|
||||||
return name ? name : "";
|
return name ? name : "";
|
||||||
@ -3863,7 +3883,7 @@ int current_config_line(void)
|
|||||||
if (current_config_kvi)
|
if (current_config_kvi)
|
||||||
return current_config_kvi->linenr;
|
return current_config_kvi->linenr;
|
||||||
else
|
else
|
||||||
return cf_global->linenr;
|
return the_reader.source->linenr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lookup_config(const char **mapping, int nr_mapping, const char *var)
|
int lookup_config(const char **mapping, int nr_mapping, const char *var)
|
||||||
|
Loading…
Reference in New Issue
Block a user