Message ID | 74a63fed7054da8049d4a32ecdb582726368c5a8.1677631097.git.gitgitgadget@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | config.c: use struct for config reading state | expand |
On Wed, Mar 01 2023, Glen Choo via GitGitGadget wrote: > From: Glen Choo <chooglen@google.com> > > The remaining references to "cf" are in config callback functions. > Remove them by plumbing "struct config_reader" via the "*data" arg. > > [...] > * All remote URLs discovered when reading all config files. > @@ -461,6 +457,7 @@ static int include_condition_is_true(struct config_source *cs, > static int git_config_include(const char *var, const char *value, void *data) > { > struct config_include_data *inc = data; > + struct config_source *cs = inc->config_reader->source; > const char *cond, *key; > size_t cond_len; > int ret; > @@ -474,16 +471,16 @@ static int git_config_include(const char *var, const char *value, void *data) > return ret; > > if (!strcmp(var, "include.path")) > - ret = handle_path_include(cf, value, inc); > + ret = handle_path_include(cs, value, inc); So, there's a lot of churn in this topic from renaming "cf" to "cs" all over the place, I really wish that could be avoided for the size of the overall diff, but haven't looked into in detail how easy that is, but... > > if (!parse_config_key(var, "includeif", &cond, &cond_len, &key) && > - cond && include_condition_is_true(cf, inc, cond, cond_len) && > + cond && include_condition_is_true(cs, inc, cond, cond_len) && > !strcmp(key, "path")) { > config_fn_t old_fn = inc->fn; > > if (inc->opts->unconditional_remote_url) > inc->fn = forbid_remote_url; > - ret = handle_path_include(cf, value, inc); > + ret = handle_path_include(cs, value, inc); > inc->fn = old_fn; > } > > @@ -2224,6 +2221,7 @@ int config_with_options(config_fn_t fn, void *data, > inc.data = data; > inc.opts = opts; > inc.config_source = config_source; > + inc.config_reader = &the_reader; > fn = git_config_include; > data = &inc; > } > @@ -2344,7 +2342,9 @@ static struct config_set_element *configset_find_element(struct config_set *cs, > return found_entry; > } > > -static int configset_add_value(struct config_set *cs, const char *key, const char *value) > +static int configset_add_value(struct config_reader *reader, > + struct config_set *cs, const char *key, > + const char *value) ...this is an existing name just seen in the context, but could we in this topic at least avoid having a "cs" refer to both a "struct config_set" and a "struct config_source" in the end-state? I tried the below on top of this topic, and the overall diff looks much nicer as a result: diff --git a/config.c b/config.c index 19bab84c47f..c27c128e3c0 100644 --- a/config.c +++ b/config.c @@ -199,7 +199,7 @@ static const char include_depth_advice[] = N_( "from\n" " %s\n" "This might be due to circular includes."); -static int handle_path_include(struct config_source *cs, const char *path, +static int handle_path_include(struct config_source *cf, const char *path, struct config_include_data *inc) { int ret = 0; @@ -221,14 +221,14 @@ static int handle_path_include(struct config_source *cs, const char *path, if (!is_absolute_path(path)) { char *slash; - if (!cs || !cs->path) { + if (!cf || !cf->path) { ret = error(_("relative config includes must come from files")); goto cleanup; } - slash = find_last_dir_sep(cs->path); + slash = find_last_dir_sep(cf->path); if (slash) - strbuf_add(&buf, cs->path, slash - cs->path + 1); + strbuf_add(&buf, cf->path, slash - cf->path + 1); strbuf_addstr(&buf, path); path = buf.buf; } @@ -236,8 +236,8 @@ static int handle_path_include(struct config_source *cs, const char *path, if (!access_or_die(path, R_OK, 0)) { if (++inc->depth > MAX_INCLUDE_DEPTH) die(_(include_depth_advice), MAX_INCLUDE_DEPTH, path, - !cs ? "<unknown>" : - cs->name ? cs->name : + !cf ? "<unknown>" : + cf->name ? cf->name : "the command line"); ret = git_config_from_file(git_config_include, path, inc); inc->depth--; @@ -254,7 +254,7 @@ static void add_trailing_starstar_for_dir(struct strbuf *pat) strbuf_addstr(pat, "**"); } -static int prepare_include_condition_pattern(struct config_source *cs, +static int prepare_include_condition_pattern(struct config_source *cf, struct strbuf *pat) { struct strbuf path = STRBUF_INIT; @@ -271,11 +271,11 @@ static int prepare_include_condition_pattern(struct config_source *cs, if (pat->buf[0] == '.' && is_dir_sep(pat->buf[1])) { const char *slash; - if (!cs || !cs->path) + if (!cf || !cf->path) return error(_("relative config include " "conditionals must come from files")); - strbuf_realpath(&path, cs->path, 1); + strbuf_realpath(&path, cf->path, 1); slash = find_last_dir_sep(path.buf); if (!slash) BUG("how is this possible?"); @@ -290,7 +290,7 @@ static int prepare_include_condition_pattern(struct config_source *cs, return prefix; } -static int include_by_gitdir(struct config_source *cs, +static int include_by_gitdir(struct config_source *cf, const struct config_options *opts, const char *cond, size_t cond_len, int icase) { @@ -307,7 +307,7 @@ static int include_by_gitdir(struct config_source *cs, strbuf_realpath(&text, git_dir, 1); strbuf_add(&pattern, cond, cond_len); - prefix = prepare_include_condition_pattern(cs, &pattern); + prefix = prepare_include_condition_pattern(cf, &pattern); again: if (prefix < 0) @@ -446,16 +446,16 @@ static int include_by_remote_url(struct config_include_data *inc, inc->remote_urls); } -static int include_condition_is_true(struct config_source *cs, +static int include_condition_is_true(struct config_source *cf, struct config_include_data *inc, const char *cond, size_t cond_len) { const struct config_options *opts = inc->opts; if (skip_prefix_mem(cond, cond_len, "gitdir:", &cond, &cond_len)) - return include_by_gitdir(cs, opts, cond, cond_len, 0); + return include_by_gitdir(cf, opts, cond, cond_len, 0); else if (skip_prefix_mem(cond, cond_len, "gitdir/i:", &cond, &cond_len)) - return include_by_gitdir(cs, opts, cond, cond_len, 1); + return include_by_gitdir(cf, opts, cond, cond_len, 1); else if (skip_prefix_mem(cond, cond_len, "onbranch:", &cond, &cond_len)) return include_by_branch(cond, cond_len); else if (skip_prefix_mem(cond, cond_len, "hasconfig:remote.*.url:", &cond, @@ -469,7 +469,7 @@ static int include_condition_is_true(struct config_source *cs, static int git_config_include(const char *var, const char *value, void *data) { struct config_include_data *inc = data; - struct config_source *cs = inc->config_reader->source; + struct config_source *cf = inc->config_reader->source; const char *cond, *key; size_t cond_len; int ret; @@ -483,16 +483,16 @@ static int git_config_include(const char *var, const char *value, void *data) return ret; if (!strcmp(var, "include.path")) - ret = handle_path_include(cs, value, inc); + ret = handle_path_include(cf, value, inc); if (!parse_config_key(var, "includeif", &cond, &cond_len, &key) && - cond && include_condition_is_true(cs, inc, cond, cond_len) && + cond && include_condition_is_true(cf, inc, cond, cond_len) && !strcmp(key, "path")) { config_fn_t old_fn = inc->fn; if (inc->opts->unconditional_remote_url) inc->fn = forbid_remote_url; - ret = handle_path_include(cs, value, inc); + ret = handle_path_include(cf, value, inc); inc->fn = old_fn; } @@ -817,21 +817,21 @@ int git_config_from_parameters(config_fn_t fn, void *data) return ret; } -static int get_next_char(struct config_source *cs) +static int get_next_char(struct config_source *cf) { - int c = cs->do_fgetc(cs); + int c = cf->do_fgetc(cf); if (c == '\r') { /* DOS like systems */ - c = cs->do_fgetc(cs); + c = cf->do_fgetc(cf); if (c != '\n') { if (c != EOF) - cs->do_ungetc(c, cs); + cf->do_ungetc(c, cf); c = '\r'; } } - if (c != EOF && ++cs->total_len > INT_MAX) { + if (c != EOF && ++cf->total_len > INT_MAX) { /* * This is an absurdly long config file; refuse to parse * further in order to protect downstream code from integer @@ -839,38 +839,38 @@ static int get_next_char(struct config_source *cs) * but we can mark EOF and put trash in the return value, * which will trigger a parse error. */ - cs->eof = 1; + cf->eof = 1; return 0; } if (c == '\n') - cs->linenr++; + cf->linenr++; if (c == EOF) { - cs->eof = 1; - cs->linenr++; + cf->eof = 1; + cf->linenr++; c = '\n'; } return c; } -static char *parse_value(struct config_source *cs) +static char *parse_value(struct config_source *cf) { int quote = 0, comment = 0, space = 0; - strbuf_reset(&cs->value); + strbuf_reset(&cf->value); for (;;) { - int c = get_next_char(cs); + int c = get_next_char(cf); if (c == '\n') { if (quote) { - cs->linenr--; + cf->linenr--; return NULL; } - return cs->value.buf; + return cf->value.buf; } if (comment) continue; if (isspace(c) && !quote) { - if (cs->value.len) + if (cf->value.len) space++; continue; } @@ -881,9 +881,9 @@ static char *parse_value(struct config_source *cs) } } for (; space; space--) - strbuf_addch(&cs->value, ' '); + strbuf_addch(&cf->value, ' '); if (c == '\\') { - c = get_next_char(cs); + c = get_next_char(cf); switch (c) { case '\n': continue; @@ -903,18 +903,18 @@ static char *parse_value(struct config_source *cs) default: return NULL; } - strbuf_addch(&cs->value, c); + strbuf_addch(&cf->value, c); continue; } if (c == '"') { quote = 1-quote; continue; } - strbuf_addch(&cs->value, c); + strbuf_addch(&cf->value, c); } } -static int get_value(struct config_source *cs, config_fn_t fn, void *data, +static int get_value(struct config_source *cf, config_fn_t fn, void *data, struct strbuf *name) { int c; @@ -923,8 +923,8 @@ static int get_value(struct config_source *cs, config_fn_t fn, void *data, /* Get the full name */ for (;;) { - c = get_next_char(cs); - if (cs->eof) + c = get_next_char(cf); + if (cf->eof) break; if (!iskeychar(c)) break; @@ -932,13 +932,13 @@ static int get_value(struct config_source *cs, config_fn_t fn, void *data, } while (c == ' ' || c == '\t') - c = get_next_char(cs); + c = get_next_char(cf); value = NULL; if (c != '\n') { if (c != '=') return -1; - value = parse_value(cs); + value = parse_value(cf); if (!value) return -1; } @@ -947,21 +947,21 @@ static int get_value(struct config_source *cs, config_fn_t fn, void *data, * the line we just parsed during the call to fn to get * accurate line number in error messages. */ - cs->linenr--; + cf->linenr--; ret = fn(name->buf, value, data); if (ret >= 0) - cs->linenr++; + cf->linenr++; return ret; } -static int get_extended_base_var(struct config_source *cs, struct strbuf *name, +static int get_extended_base_var(struct config_source *cf, struct strbuf *name, int c) { - cs->subsection_case_sensitive = 0; + cf->subsection_case_sensitive = 0; do { if (c == '\n') goto error_incomplete_line; - c = get_next_char(cs); + c = get_next_char(cf); } while (isspace(c)); /* We require the format to be '[base "extension"]' */ @@ -970,13 +970,13 @@ static int get_extended_base_var(struct config_source *cs, struct strbuf *name, strbuf_addch(name, '.'); for (;;) { - int c = get_next_char(cs); + int c = get_next_char(cf); if (c == '\n') goto error_incomplete_line; if (c == '"') break; if (c == '\\') { - c = get_next_char(cs); + c = get_next_char(cf); if (c == '\n') goto error_incomplete_line; } @@ -984,25 +984,25 @@ static int get_extended_base_var(struct config_source *cs, struct strbuf *name, } /* Final ']' */ - if (get_next_char(cs) != ']') + if (get_next_char(cf) != ']') return -1; return 0; error_incomplete_line: - cs->linenr--; + cf->linenr--; return -1; } -static int get_base_var(struct config_source *cs, struct strbuf *name) +static int get_base_var(struct config_source *cf, struct strbuf *name) { - cs->subsection_case_sensitive = 1; + cf->subsection_case_sensitive = 1; for (;;) { - int c = get_next_char(cs); - if (cs->eof) + int c = get_next_char(cf); + if (cf->eof) return -1; if (c == ']') return 0; if (isspace(c)) - return get_extended_base_var(cs, name, c); + return get_extended_base_var(cf, name, c); if (!iskeychar(c) && c != '.') return -1; strbuf_addch(name, tolower(c)); @@ -1015,7 +1015,7 @@ struct parse_event_data { const struct config_options *opts; }; -static int do_event(struct config_source *cs, enum config_event_t type, +static int do_event(struct config_source *cf, enum config_event_t type, struct parse_event_data *data) { size_t offset; @@ -1027,7 +1027,7 @@ static int do_event(struct config_source *cs, enum config_event_t type, data->previous_type == type) return 0; - offset = cs->do_ftell(cs); + offset = cf->do_ftell(cf); /* * At EOF, the parser always "inserts" an extra '\n', therefore * the end offset of the event is the current file position, otherwise @@ -1047,12 +1047,12 @@ static int do_event(struct config_source *cs, enum config_event_t type, return 0; } -static int git_parse_source(struct config_source *cs, config_fn_t fn, +static int git_parse_source(struct config_source *cf, config_fn_t fn, void *data, const struct config_options *opts) { int comment = 0; size_t baselen = 0; - struct strbuf *var = &cs->var; + struct strbuf *var = &cf->var; int error_return = 0; char *error_msg = NULL; @@ -1067,7 +1067,7 @@ static int git_parse_source(struct config_source *cs, config_fn_t fn, for (;;) { int c; - c = get_next_char(cs); + c = get_next_char(cf); if (bomptr && *bomptr) { /* We are at the file beginning; skip UTF8-encoded BOM * if present. Sane editors won't put this in on their @@ -1084,12 +1084,12 @@ static int git_parse_source(struct config_source *cs, config_fn_t fn, } } if (c == '\n') { - if (cs->eof) { - if (do_event(cs, CONFIG_EVENT_EOF, &event_data) < 0) + if (cf->eof) { + if (do_event(cf, CONFIG_EVENT_EOF, &event_data) < 0) return -1; return 0; } - if (do_event(cs, CONFIG_EVENT_WHITESPACE, &event_data) < 0) + if (do_event(cf, CONFIG_EVENT_WHITESPACE, &event_data) < 0) return -1; comment = 0; continue; @@ -1097,23 +1097,23 @@ static int git_parse_source(struct config_source *cs, config_fn_t fn, if (comment) continue; if (isspace(c)) { - if (do_event(cs, CONFIG_EVENT_WHITESPACE, &event_data) < 0) + if (do_event(cf, CONFIG_EVENT_WHITESPACE, &event_data) < 0) return -1; continue; } if (c == '#' || c == ';') { - if (do_event(cs, CONFIG_EVENT_COMMENT, &event_data) < 0) + if (do_event(cf, CONFIG_EVENT_COMMENT, &event_data) < 0) return -1; comment = 1; continue; } if (c == '[') { - if (do_event(cs, CONFIG_EVENT_SECTION, &event_data) < 0) + if (do_event(cf, CONFIG_EVENT_SECTION, &event_data) < 0) return -1; /* Reset prior to determining a new stem */ strbuf_reset(var); - if (get_base_var(cs, var) < 0 || var->len < 1) + if (get_base_var(cf, var) < 0 || var->len < 1) break; strbuf_addch(var, '.'); baselen = var->len; @@ -1122,7 +1122,7 @@ static int git_parse_source(struct config_source *cs, config_fn_t fn, if (!isalpha(c)) break; - if (do_event(cs, CONFIG_EVENT_ENTRY, &event_data) < 0) + if (do_event(cf, CONFIG_EVENT_ENTRY, &event_data) < 0) return -1; /* @@ -1132,42 +1132,42 @@ static int git_parse_source(struct config_source *cs, config_fn_t fn, */ strbuf_setlen(var, baselen); strbuf_addch(var, tolower(c)); - if (get_value(cs, fn, data, var) < 0) + if (get_value(cf, fn, data, var) < 0) break; } - if (do_event(cs, CONFIG_EVENT_ERROR, &event_data) < 0) + if (do_event(cf, CONFIG_EVENT_ERROR, &event_data) < 0) return -1; - switch (cs->origin_type) { + switch (cf->origin_type) { case CONFIG_ORIGIN_BLOB: error_msg = xstrfmt(_("bad config line %d in blob %s"), - cs->linenr, cs->name); + cf->linenr, cf->name); break; case CONFIG_ORIGIN_FILE: error_msg = xstrfmt(_("bad config line %d in file %s"), - cs->linenr, cs->name); + cf->linenr, cf->name); break; case CONFIG_ORIGIN_STDIN: error_msg = xstrfmt(_("bad config line %d in standard input"), - cs->linenr); + cf->linenr); break; case CONFIG_ORIGIN_SUBMODULE_BLOB: error_msg = xstrfmt(_("bad config line %d in submodule-blob %s"), - cs->linenr, cs->name); + cf->linenr, cf->name); break; case CONFIG_ORIGIN_CMDLINE: error_msg = xstrfmt(_("bad config line %d in command line %s"), - cs->linenr, cs->name); + cf->linenr, cf->name); break; default: error_msg = xstrfmt(_("bad config line %d in %s"), - cs->linenr, cs->name); + cf->linenr, cf->name); } switch (opts && opts->error_action ? opts->error_action : - cs->default_error_action) { + cf->default_error_action) { case CONFIG_ERROR_DIE: die("%s", error_msg); break; @@ -1309,7 +1309,7 @@ int git_parse_ssize_t(const char *value, ssize_t *ret) } NORETURN -static void die_bad_number(struct config_source *cs, const char *name, +static void die_bad_number(struct config_source *cf, const char *name, const char *value) { const char *error_type = (errno == ERANGE) ? @@ -1319,28 +1319,28 @@ static void die_bad_number(struct config_source *cs, const char *name, if (!value) value = ""; - if (!(cs && cs->name)) + if (!(cf && cf->name)) die(_(bad_numeric), value, name, _(error_type)); - switch (cs->origin_type) { + switch (cf->origin_type) { case CONFIG_ORIGIN_BLOB: die(_("bad numeric config value '%s' for '%s' in blob %s: %s"), - value, name, cs->name, _(error_type)); + value, name, cf->name, _(error_type)); case CONFIG_ORIGIN_FILE: die(_("bad numeric config value '%s' for '%s' in file %s: %s"), - value, name, cs->name, _(error_type)); + value, name, cf->name, _(error_type)); case CONFIG_ORIGIN_STDIN: die(_("bad numeric config value '%s' for '%s' in standard input: %s"), value, name, _(error_type)); case CONFIG_ORIGIN_SUBMODULE_BLOB: die(_("bad numeric config value '%s' for '%s' in submodule-blob %s: %s"), - value, name, cs->name, _(error_type)); + value, name, cf->name, _(error_type)); case CONFIG_ORIGIN_CMDLINE: die(_("bad numeric config value '%s' for '%s' in command line %s: %s"), - value, name, cs->name, _(error_type)); + value, name, cf->name, _(error_type)); default: die(_("bad numeric config value '%s' for '%s' in %s: %s"), - value, name, cs->name, _(error_type)); + value, name, cf->name, _(error_type)); } } @@ -2274,12 +2274,12 @@ struct configset_iter_data { }; #define CONFIGSET_ITER_INIT { 0 } -static void configset_iter(struct config_set *cs, config_fn_t fn, void *data) +static void configset_iter(struct config_set *cf, config_fn_t fn, void *data) { int i, value_index; struct string_list *values; struct config_set_element *entry; - struct configset_list *list = &cs->list; + struct configset_list *list = &cf->list; struct configset_iter_data *iter_data = data; for (i = 0; i < list->nr; i++) { @@ -2975,7 +2975,7 @@ static int store_aux_event(enum config_event_t type, size_t begin, size_t end, void *data) { struct config_store_data *store = data; - struct config_source *cs = store->config_reader->source; + struct config_source *cf = store->config_reader->source; ALLOC_GROW(store->parsed, store->parsed_nr + 1, store->parsed_alloc); store->parsed[store->parsed_nr].begin = begin; @@ -2985,10 +2985,10 @@ static int store_aux_event(enum config_event_t type, if (type == CONFIG_EVENT_SECTION) { int (*cmpfn)(const char *, const char *, size_t); - if (cs->var.len < 2 || cs->var.buf[cs->var.len - 1] != '.') - return error(_("invalid section name '%s'"), cs->var.buf); + if (cf->var.len < 2 || cf->var.buf[cf->var.len - 1] != '.') + return error(_("invalid section name '%s'"), cf->var.buf); - if (cs->subsection_case_sensitive) + if (cf->subsection_case_sensitive) cmpfn = strncasecmp; else cmpfn = strncmp; @@ -2996,8 +2996,8 @@ static int store_aux_event(enum config_event_t type, /* Is this the section we were looking for? */ store->is_keys_section = store->parsed[store->parsed_nr].is_keys_section = - cs->var.len - 1 == store->baselen && - !cmpfn(cs->var.buf, store->key, store->baselen); + cf->var.len - 1 == store->baselen && + !cmpfn(cf->var.buf, store->key, store->baselen); if (store->is_keys_section) { store->section_seen = 1; ALLOC_GROW(store->seen, store->seen_nr + 1, diff --git a/config.h b/config.h index 7606246531a..5421c48e287 100644 --- a/config.h +++ b/config.h @@ -614,7 +614,7 @@ int git_config_get_expiry_in_days(const char *key, timestamp_t *, timestamp_t no struct key_value_info { const char *filename; - int linenr; + int linenr2; enum config_origin_type origin_type; enum config_scope scope; };
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > So, there's a lot of churn in this topic from renaming "cf" to "cs" all > over the place, I really wish that could be avoided for the size of the > overall diff, but haven't looked into in detail how easy that is, but... Yeah, I think it can be avoided by taking Junio's suggestion to rename the global "cf" to "cf_global" or something, then accepting a "cf" parameter. https://lore.kernel.org/git/xmqqh6v1g1d3.fsf@gitster.g >> -static int configset_add_value(struct config_set *cs, const char *key, const char *value) >> +static int configset_add_value(struct config_reader *reader, >> + struct config_set *cs, const char *key, >> + const char *value) > > ...this is an existing name just seen in the context, but could we in > this topic at least avoid having a "cs" refer to both a "struct > config_set" and a "struct config_source" in the end-state? Fair. This also irked me when I first saw it. As an aside, I found "struct config_source cf" to be a bit of an eyesore too. It's an unfortunate holdover from before 4d8dd1494e (config: make parsing stack struct independent from actual data source, 2013-07-12) when the struct was called "config_file". Unfortunately, "cs" is already taken by at least one parameter, so maybe we'll never be able to properly rename it...
Glen Choo <chooglen@google.com> writes: > As an aside, I found "struct config_source cf" to be a bit of an eyesore > too. It's an unfortunate holdover from before 4d8dd1494e (config: make > parsing stack struct independent from actual data source, 2013-07-12) > when the struct was called "config_file". Ah, thanks for digging---I was wondering why it was called cf myself.
diff --git a/config.c b/config.c index 866cd54dd40..9676734b1b7 100644 --- a/config.c +++ b/config.c @@ -58,6 +58,9 @@ struct config_reader { static struct config_reader the_reader; /* + * FIXME The comments are temporarily out of date since "cf" been moved to + * the_reader, but not current_*. + * * These variables record the "current" config source, which * can be accessed by parsing callbacks. * @@ -72,11 +75,7 @@ static struct config_reader the_reader; * 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). - * - * FIXME "cf" has been replaced by "the_reader.source", remove - * "cf" once we plumb "the_reader" through all of the callback functions. */ -static struct config_source *cf; static struct key_value_info *current_config_kvi; /* @@ -94,8 +93,6 @@ static inline void config_reader_push_source(struct config_reader *reader, if (reader->source) top->prev = reader->source; reader->source = top; - /* FIXME remove this when cf is removed. */ - cf = reader->source; } static inline struct config_source *config_reader_pop_source(struct config_reader *reader) @@ -105,8 +102,6 @@ static inline struct config_source *config_reader_pop_source(struct config_reade BUG("tried to pop config source, but we weren't reading config"); ret = reader->source; reader->source = reader->source->prev; - /* FIXME remove this when cf is removed. */ - cf = reader->source; return ret; } @@ -171,6 +166,7 @@ struct config_include_data { void *data; const struct config_options *opts; struct git_config_source *config_source; + struct config_reader *config_reader; /* * All remote URLs discovered when reading all config files. @@ -461,6 +457,7 @@ static int include_condition_is_true(struct config_source *cs, static int git_config_include(const char *var, const char *value, void *data) { struct config_include_data *inc = data; + struct config_source *cs = inc->config_reader->source; const char *cond, *key; size_t cond_len; int ret; @@ -474,16 +471,16 @@ static int git_config_include(const char *var, const char *value, void *data) return ret; if (!strcmp(var, "include.path")) - ret = handle_path_include(cf, value, inc); + ret = handle_path_include(cs, value, inc); if (!parse_config_key(var, "includeif", &cond, &cond_len, &key) && - cond && include_condition_is_true(cf, inc, cond, cond_len) && + cond && include_condition_is_true(cs, inc, cond, cond_len) && !strcmp(key, "path")) { config_fn_t old_fn = inc->fn; if (inc->opts->unconditional_remote_url) inc->fn = forbid_remote_url; - ret = handle_path_include(cf, value, inc); + ret = handle_path_include(cs, value, inc); inc->fn = old_fn; } @@ -2224,6 +2221,7 @@ int config_with_options(config_fn_t fn, void *data, inc.data = data; inc.opts = opts; inc.config_source = config_source; + inc.config_reader = &the_reader; fn = git_config_include; data = &inc; } @@ -2344,7 +2342,9 @@ static struct config_set_element *configset_find_element(struct config_set *cs, return found_entry; } -static int configset_add_value(struct config_set *cs, const char *key, const char *value) +static int configset_add_value(struct config_reader *reader, + struct config_set *cs, const char *key, + const char *value) { struct config_set_element *e; struct string_list_item *si; @@ -2370,12 +2370,12 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha l_item->e = e; l_item->value_index = e->value_list.nr - 1; - if (!cf) + if (!reader->source) BUG("configset_add_value has no source"); - if (cf->name) { - kv_info->filename = strintern(cf->name); - kv_info->linenr = cf->linenr; - kv_info->origin_type = cf->origin_type; + if (reader->source->name) { + kv_info->filename = strintern(reader->source->name); + kv_info->linenr = reader->source->linenr; + kv_info->origin_type = reader->source->origin_type; } else { /* for values read from `git_config_from_parameters()` */ kv_info->filename = NULL; @@ -2430,16 +2430,25 @@ void git_configset_clear(struct config_set *cs) cs->list.items = NULL; } +struct configset_add_data { + struct config_set *config_set; + struct config_reader *config_reader; +}; +#define CONFIGSET_ADD_INIT { 0 } + static int config_set_callback(const char *key, const char *value, void *cb) { - struct config_set *cs = cb; - configset_add_value(cs, key, value); + struct configset_add_data *data = cb; + configset_add_value(data->config_reader, data->config_set, key, value); return 0; } int git_configset_add_file(struct config_set *cs, const char *filename) { - return git_config_from_file(config_set_callback, filename, cs); + struct configset_add_data data = CONFIGSET_ADD_INIT; + data.config_reader = &the_reader; + data.config_set = cs; + return git_config_from_file(config_set_callback, filename, &data); } int git_configset_get_value(struct config_set *cs, const char *key, const char **value) @@ -2554,6 +2563,7 @@ int git_configset_get_pathname(struct config_set *cs, const char *key, const cha static void repo_read_config(struct repository *repo) { struct config_options opts = { 0 }; + struct configset_add_data data = CONFIGSET_ADD_INIT; opts.respect_includes = 1; opts.commondir = repo->commondir; @@ -2565,8 +2575,10 @@ static void repo_read_config(struct repository *repo) git_configset_clear(repo->config); git_configset_init(repo->config); + data.config_set = repo->config; + data.config_reader = &the_reader; - if (config_with_options(config_set_callback, repo->config, NULL, &opts) < 0) + if (config_with_options(config_set_callback, &data, NULL, &opts) < 0) /* * config_with_options() normally returns only * zero, as most errors are fatal, and @@ -2692,9 +2704,12 @@ static void read_protected_config(void) .ignore_worktree = 1, .system_gently = 1, }; + struct configset_add_data data = CONFIGSET_ADD_INIT; + git_configset_init(&protected_config); - config_with_options(config_set_callback, &protected_config, - NULL, &opts); + data.config_set = &protected_config; + data.config_reader = &the_reader; + config_with_options(config_set_callback, &data, NULL, &opts); } void git_protected_config(config_fn_t fn, void *data) @@ -2879,6 +2894,7 @@ void git_die_config(const char *key, const char *err, ...) */ struct config_store_data { + struct config_reader *config_reader; size_t baselen; char *key; int do_not_match; @@ -2893,6 +2909,7 @@ struct config_store_data { unsigned int parsed_nr, parsed_alloc, *seen, seen_nr, seen_alloc; unsigned int key_seen:1, section_seen:1, is_keys_section:1; }; +#define CONFIG_STORE_INIT { 0 } static void config_store_data_clear(struct config_store_data *store) { @@ -2927,6 +2944,7 @@ static int store_aux_event(enum config_event_t type, size_t begin, size_t end, void *data) { struct config_store_data *store = data; + struct config_source *cs = store->config_reader->source; ALLOC_GROW(store->parsed, store->parsed_nr + 1, store->parsed_alloc); store->parsed[store->parsed_nr].begin = begin; @@ -2936,10 +2954,10 @@ static int store_aux_event(enum config_event_t type, if (type == CONFIG_EVENT_SECTION) { int (*cmpfn)(const char *, const char *, size_t); - if (cf->var.len < 2 || cf->var.buf[cf->var.len - 1] != '.') - return error(_("invalid section name '%s'"), cf->var.buf); + if (cs->var.len < 2 || cs->var.buf[cs->var.len - 1] != '.') + return error(_("invalid section name '%s'"), cs->var.buf); - if (cf->subsection_case_sensitive) + if (cs->subsection_case_sensitive) cmpfn = strncasecmp; else cmpfn = strncmp; @@ -2947,8 +2965,8 @@ static int store_aux_event(enum config_event_t type, /* Is this the section we were looking for? */ store->is_keys_section = store->parsed[store->parsed_nr].is_keys_section = - cf->var.len - 1 == store->baselen && - !cmpfn(cf->var.buf, store->key, store->baselen); + cs->var.len - 1 == store->baselen && + !cmpfn(cs->var.buf, store->key, store->baselen); if (store->is_keys_section) { store->section_seen = 1; ALLOC_GROW(store->seen, store->seen_nr + 1, @@ -3244,9 +3262,9 @@ int git_config_set_multivar_in_file_gently(const char *config_filename, char *filename_buf = NULL; char *contents = NULL; size_t contents_sz; - struct config_store_data store; + struct config_store_data store = CONFIG_STORE_INIT; - memset(&store, 0, sizeof(store)); + store.config_reader = &the_reader; /* parse-key returns negative; flip the sign to feed exit(3) */ ret = 0 - git_config_parse_key(key, &store.key, &store.baselen);