config.c: plumb config_source through static fns

This reduces the direct dependence on the global "struct config_source", which will make it easier to remove in a later commit. To minimize the changes we need to make, we rename the current variable from "cf" to "cf_global", and the plumbed arg uses the old name "cf". This is a little unfortunate, since we now have the confusingly named "struct config_source cf" everywhere (which is a holdover from before 4d8dd1494e (config: make parsing stack struct independent from actual data source, 2013-07-12), when the struct used to be called "config_file"), but we will rename "cf" to "cs" by the end of the series. In some cases (public functions and config callback functions), there isn't an obvious way to plumb "struct config_source" through function args. As a workaround, add references to "cf_global" that we'll address in later commits. The remaining references to "cf_global" are direct assignments to "cf_global", which we'll also address in a later commit. Signed-off-by: Glen Choo <chooglen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Glen Choo committed Mar 28, 2023 at 17:51 UTC c97f3ed25611eb816c291ac283be8b7146a8e099
1 file changed +84 -69
config.c
+84 -69
@@ -54,8 +54,8 @@ struct config_source {
54 * These variables record the "current" config source, which
55 * can be accessed by parsing callbacks.
56 *
57 - * The "cf" variable will be non-NULL only when we are actually parsing a real
58 - * config source (file, blob, cmdline, etc).
57 + * The "cf_global" variable will be non-NULL only when we are actually
58 + * parsing a real config source (file, blob, cmdline, etc).
59 *
60 * The "current_config_kvi" variable will be non-NULL only when we are feeding
61 * cached config from a configset into a callback.
@@ -66,15 +66,16 @@ struct config_source {
66 * or it's a function which can be reused for non-config purposes, and should
67 * fall back to some sane behavior).
68 */
69 -static struct config_source *cf;
69 +static struct config_source *cf_global;
70 static struct key_value_info *current_config_kvi;
71
72 /*
73 * Similar to the variables above, this gives access to the "scope" of the
74 * current value (repo, global, etc). For cached values, it can be found via
75 * the current_config_kvi as above. During parsing, the current value can be
76 - * found in this variable. It's not part of "cf" because it transcends a single
77 - * file (i.e., a file included from .git/config is still in "repo" scope).
76 + * found in this variable. It's not part of "cf_global" because it transcends a
77 + * single file (i.e., a file included from .git/config is still in "repo"
78 + * scope).
79 */
80 static enum config_scope current_parsing_scope;
81
@@ -156,7 +157,8 @@ static const char include_depth_advice[] = N_(
157 "from\n"
158 " %s\n"
159 "This might be due to circular includes.");
159 -static int handle_path_include(const char *path, struct config_include_data *inc)
160 +static int handle_path_include(struct config_source *cf, const char *path,
161 + struct config_include_data *inc)
162 {
163 int ret = 0;
164 struct strbuf buf = STRBUF_INIT;
@@ -210,7 +212,8 @@ static void add_trailing_starstar_for_dir(struct strbuf *pat)
212 strbuf_addstr(pat, "**");
213 }
214
213 -static int prepare_include_condition_pattern(struct strbuf *pat)
215 +static int prepare_include_condition_pattern(struct config_source *cf,
216 + struct strbuf *pat)
217 {
218 struct strbuf path = STRBUF_INIT;
219 char *expanded;
@@ -245,7 +248,8 @@ static int prepare_include_condition_pattern(struct strbuf *pat)
248 return prefix;
249 }
250
248 -static int include_by_gitdir(const struct config_options *opts,
251 +static int include_by_gitdir(struct config_source *cf,
252 + const struct config_options *opts,
253 const char *cond, size_t cond_len, int icase)
254 {
255 struct strbuf text = STRBUF_INIT;
@@ -261,7 +265,7 @@ static int include_by_gitdir(const struct config_options *opts,
265
266 strbuf_realpath(&text, git_dir, 1);
267 strbuf_add(&pattern, cond, cond_len);
264 - prefix = prepare_include_condition_pattern(&pattern);
268 + prefix = prepare_include_condition_pattern(cf, &pattern);
269
270 again:
271 if (prefix < 0)
@@ -342,14 +346,14 @@ static void populate_remote_urls(struct config_include_data *inc)
346 {
347 struct config_options opts;
348
345 - struct config_source *store_cf = cf;
349 + struct config_source *store_cf = cf_global;
350 struct key_value_info *store_kvi = current_config_kvi;
351 enum config_scope store_scope = current_parsing_scope;
352
353 opts = *inc->opts;
354 opts.unconditional_remote_url = 1;
355
352 - cf = NULL;
356 + cf_global = NULL;
357 current_config_kvi = NULL;
358 current_parsing_scope = 0;
359
@@ -357,7 +361,7 @@ static void populate_remote_urls(struct config_include_data *inc)
361 string_list_init_dup(inc->remote_urls);
362 config_with_options(add_remote_url, inc->remote_urls, inc->config_source, &opts);
363
360 - cf = store_cf;
364 + cf_global = store_cf;
365 current_config_kvi = store_kvi;
366 current_parsing_scope = store_scope;
367 }
@@ -406,15 +410,16 @@ static int include_by_remote_url(struct config_include_data *inc,
410 inc->remote_urls);
411 }
412
409 -static int include_condition_is_true(struct config_include_data *inc,
413 +static int include_condition_is_true(struct config_source *cf,
414 + struct config_include_data *inc,
415 const char *cond, size_t cond_len)
416 {
417 const struct config_options *opts = inc->opts;
418
419 if (skip_prefix_mem(cond, cond_len, "gitdir:", &cond, &cond_len))
415 - return include_by_gitdir(opts, cond, cond_len, 0);
420 + return include_by_gitdir(cf, opts, cond, cond_len, 0);
421 else if (skip_prefix_mem(cond, cond_len, "gitdir/i:", &cond, &cond_len))
417 - return include_by_gitdir(opts, cond, cond_len, 1);
422 + return include_by_gitdir(cf, opts, cond, cond_len, 1);
423 else if (skip_prefix_mem(cond, cond_len, "onbranch:", &cond, &cond_len))
424 return include_by_branch(cond, cond_len);
425 else if (skip_prefix_mem(cond, cond_len, "hasconfig:remote.*.url:", &cond,
@@ -441,16 +446,16 @@ static int git_config_include(const char *var, const char *value, void *data)
446 return ret;
447
448 if (!strcmp(var, "include.path"))
444 - ret = handle_path_include(value, inc);
449 + ret = handle_path_include(cf_global, value, inc);
450
451 if (!parse_config_key(var, "includeif", &cond, &cond_len, &key) &&
447 - cond && include_condition_is_true(inc, cond, cond_len) &&
452 + cond && include_condition_is_true(cf_global, inc, cond, cond_len) &&
453 !strcmp(key, "path")) {
454 config_fn_t old_fn = inc->fn;
455
456 if (inc->opts->unconditional_remote_url)
457 inc->fn = forbid_remote_url;
453 - ret = handle_path_include(value, inc);
458 + ret = handle_path_include(cf_global, value, inc);
459 inc->fn = old_fn;
460 }
461
@@ -713,9 +718,9 @@ int git_config_from_parameters(config_fn_t fn, void *data)
718 struct config_source source;
719
720 memset(&source, 0, sizeof(source));
716 - source.prev = cf;
721 + source.prev = cf_global;
722 source.origin_type = CONFIG_ORIGIN_CMDLINE;
718 - cf = &source;
723 + cf_global = &source;
724
725 env = getenv(CONFIG_COUNT_ENVIRONMENT);
726 if (env) {
@@ -773,11 +778,11 @@ out:
778 strbuf_release(&envvar);
779 strvec_clear(&to_free);
780 free(envw);
776 - cf = source.prev;
781 + cf_global = source.prev;
782 return ret;
783 }
784
780 -static int get_next_char(void)
785 +static int get_next_char(struct config_source *cf)
786 {
787 int c = cf->do_fgetc(cf);
788
@@ -813,13 +818,13 @@ static int get_next_char(void)
818 return c;
819 }
820
816 -static char *parse_value(void)
821 +static char *parse_value(struct config_source *cf)
822 {
823 int quote = 0, comment = 0, space = 0;
824
825 strbuf_reset(&cf->value);
826 for (;;) {
822 - int c = get_next_char();
827 + int c = get_next_char(cf);
828 if (c == '\n') {
829 if (quote) {
830 cf->linenr--;
@@ -843,7 +848,7 @@ static char *parse_value(void)
848 for (; space; space--)
849 strbuf_addch(&cf->value, ' ');
850 if (c == '\\') {
846 - c = get_next_char();
851 + c = get_next_char(cf);
852 switch (c) {
853 case '\n':
854 continue;
@@ -874,7 +879,8 @@ static char *parse_value(void)
879 }
880 }
881
877 -static int get_value(config_fn_t fn, void *data, struct strbuf *name)
882 +static int get_value(struct config_source *cf, config_fn_t fn, void *data,
883 + struct strbuf *name)
884 {
885 int c;
886 char *value;
@@ -882,7 +888,7 @@ static int get_value(config_fn_t fn, void *data, struct strbuf *name)
888
889 /* Get the full name */
890 for (;;) {
885 - c = get_next_char();
891 + c = get_next_char(cf);
892 if (cf->eof)
893 break;
894 if (!iskeychar(c))
@@ -891,13 +897,13 @@ static int get_value(config_fn_t fn, void *data, struct strbuf *name)
897 }
898
899 while (c == ' ' || c == '\t')
894 - c = get_next_char();
900 + c = get_next_char(cf);
901
902 value = NULL;
903 if (c != '\n') {
904 if (c != '=')
905 return -1;
900 - value = parse_value();
906 + value = parse_value(cf);
907 if (!value)
908 return -1;
909 }
@@ -913,13 +919,14 @@ static int get_value(config_fn_t fn, void *data, struct strbuf *name)
919 return ret;
920 }
921
916 -static int get_extended_base_var(struct strbuf *name, int c)
922 +static int get_extended_base_var(struct config_source *cf, struct strbuf *name,
923 + int c)
924 {
925 cf->subsection_case_sensitive = 0;
926 do {
927 if (c == '\n')
928 goto error_incomplete_line;
922 - c = get_next_char();
929 + c = get_next_char(cf);
930 } while (isspace(c));
931
932 /* We require the format to be '[base "extension"]' */
@@ -928,13 +935,13 @@ static int get_extended_base_var(struct strbuf *name, int c)
935 strbuf_addch(name, '.');
936
937 for (;;) {
931 - int c = get_next_char();
938 + int c = get_next_char(cf);
939 if (c == '\n')
940 goto error_incomplete_line;
941 if (c == '"')
942 break;
943 if (c == '\\') {
937 - c = get_next_char();
944 + c = get_next_char(cf);
945 if (c == '\n')
946 goto error_incomplete_line;
947 }
@@ -942,7 +949,7 @@ static int get_extended_base_var(struct strbuf *name, int c)
949 }
950
951 /* Final ']' */
945 - if (get_next_char() != ']')
952 + if (get_next_char(cf) != ']')
953 return -1;
954 return 0;
955 error_incomplete_line:
@@ -950,17 +957,17 @@ error_incomplete_line:
957 return -1;
958 }
959
953 -static int get_base_var(struct strbuf *name)
960 +static int get_base_var(struct config_source *cf, struct strbuf *name)
961 {
962 cf->subsection_case_sensitive = 1;
963 for (;;) {
957 - int c = get_next_char();
964 + int c = get_next_char(cf);
965 if (cf->eof)
966 return -1;
967 if (c == ']')
968 return 0;
969 if (isspace(c))
963 - return get_extended_base_var(name, c);
970 + return get_extended_base_var(cf, name, c);
971 if (!iskeychar(c) && c != '.')
972 return -1;
973 strbuf_addch(name, tolower(c));
@@ -973,7 +980,8 @@ struct parse_event_data {
980 const struct config_options *opts;
981 };
982
976 -static int do_event(enum config_event_t type, struct parse_event_data *data)
983 +static int do_event(struct config_source *cf, enum config_event_t type,
984 + struct parse_event_data *data)
985 {
986 size_t offset;
987
@@ -1004,8 +1012,8 @@ static int do_event(enum config_event_t type, struct parse_event_data *data)
1012 return 0;
1013 }
1014
1007 -static int git_parse_source(config_fn_t fn, void *data,
1008 - const struct config_options *opts)
1015 +static int git_parse_source(struct config_source *cf, config_fn_t fn,
1016 + void *data, const struct config_options *opts)
1017 {
1018 int comment = 0;
1019 size_t baselen = 0;
@@ -1024,7 +1032,7 @@ static int git_parse_source(config_fn_t fn, void *data,
1032 for (;;) {
1033 int c;
1034
1027 - c = get_next_char();
1035 + c = get_next_char(cf);
1036 if (bomptr && *bomptr) {
1037 /* We are at the file beginning; skip UTF8-encoded BOM
1038 * if present. Sane editors won't put this in on their
@@ -1042,11 +1050,11 @@ static int git_parse_source(config_fn_t fn, void *data,
1050 }
1051 if (c == '\n') {
1052 if (cf->eof) {
1045 - if (do_event(CONFIG_EVENT_EOF, &event_data) < 0)
1053 + if (do_event(cf, CONFIG_EVENT_EOF, &event_data) < 0)
1054 return -1;
1055 return 0;
1056 }
1049 - if (do_event(CONFIG_EVENT_WHITESPACE, &event_data) < 0)
1057 + if (do_event(cf, CONFIG_EVENT_WHITESPACE, &event_data) < 0)
1058 return -1;
1059 comment = 0;
1060 continue;
@@ -1054,23 +1062,23 @@ static int git_parse_source(config_fn_t fn, void *data,
1062 if (comment)
1063 continue;
1064 if (isspace(c)) {
1057 - if (do_event(CONFIG_EVENT_WHITESPACE, &event_data) < 0)
1065 + if (do_event(cf, CONFIG_EVENT_WHITESPACE, &event_data) < 0)
1066 return -1;
1067 continue;
1068 }
1069 if (c == '#' || c == ';') {
1062 - if (do_event(CONFIG_EVENT_COMMENT, &event_data) < 0)
1070 + if (do_event(cf, CONFIG_EVENT_COMMENT, &event_data) < 0)
1071 return -1;
1072 comment = 1;
1073 continue;
1074 }
1075 if (c == '[') {
1068 - if (do_event(CONFIG_EVENT_SECTION, &event_data) < 0)
1076 + if (do_event(cf, CONFIG_EVENT_SECTION, &event_data) < 0)
1077 return -1;
1078
1079 /* Reset prior to determining a new stem */
1080 strbuf_reset(var);
1073 - if (get_base_var(var) < 0 || var->len < 1)
1081 + if (get_base_var(cf, var) < 0 || var->len < 1)
1082 break;
1083 strbuf_addch(var, '.');
1084 baselen = var->len;
@@ -1079,7 +1087,7 @@ static int git_parse_source(config_fn_t fn, void *data,
1087 if (!isalpha(c))
1088 break;
1089
1082 - if (do_event(CONFIG_EVENT_ENTRY, &event_data) < 0)
1090 + if (do_event(cf, CONFIG_EVENT_ENTRY, &event_data) < 0)
1091 return -1;
1092
1093 /*
@@ -1089,11 +1097,11 @@ static int git_parse_source(config_fn_t fn, void *data,
1097 */
1098 strbuf_setlen(var, baselen);
1099 strbuf_addch(var, tolower(c));
1092 - if (get_value(fn, data, var) < 0)
1100 + if (get_value(cf, fn, data, var) < 0)
1101 break;
1102 }
1103
1096 - if (do_event(CONFIG_EVENT_ERROR, &event_data) < 0)
1104 + if (do_event(cf, CONFIG_EVENT_ERROR, &event_data) < 0)
1105 return -1;
1106
1107 switch (cf->origin_type) {
@@ -1266,7 +1274,8 @@ int git_parse_ssize_t(const char *value, ssize_t *ret)
1274 }
1275
1276 NORETURN
1269 -static void die_bad_number(const char *name, const char *value)
1277 +static void die_bad_number(struct config_source *cf, const char *name,
1278 + const char *value)
1279 {
1280 const char *error_type = (errno == ERANGE) ?
1281 N_("out of range") : N_("invalid unit");
@@ -1304,7 +1313,7 @@ int git_config_int(const char *name, const char *value)
1313 {
1314 int ret;
1315 if (!git_parse_int(value, &ret))
1307 - die_bad_number(name, value);
1316 + die_bad_number(cf_global, name, value);
1317 return ret;
1318 }
1319
@@ -1312,7 +1321,7 @@ int64_t git_config_int64(const char *name, const char *value)
1321 {
1322 int64_t ret;
1323 if (!git_parse_int64(value, &ret))
1315 - die_bad_number(name, value);
1324 + die_bad_number(cf_global, name, value);
1325 return ret;
1326 }
1327
@@ -1320,7 +1329,7 @@ unsigned long git_config_ulong(const char *name, const char *value)
1329 {
1330 unsigned long ret;
1331 if (!git_parse_ulong(value, &ret))
1323 - die_bad_number(name, value);
1332 + die_bad_number(cf_global, name, value);
1333 return ret;
1334 }
1335
@@ -1328,7 +1337,7 @@ ssize_t git_config_ssize_t(const char *name, const char *value)
1337 {
1338 ssize_t ret;
1339 if (!git_parse_ssize_t(value, &ret))
1331 - die_bad_number(name, value);
1340 + die_bad_number(cf_global, name, value);
1341 return ret;
1342 }
1343
@@ -1940,20 +1949,20 @@ static int do_config_from(struct config_source *top, config_fn_t fn, void *data,
1949 int ret;
1950
1951 /* push config-file parsing state stack */
1943 - top->prev = cf;
1952 + top->prev = cf_global;
1953 top->linenr = 1;
1954 top->eof = 0;
1955 top->total_len = 0;
1956 strbuf_init(&top->value, 1024);
1957 strbuf_init(&top->var, 1024);
1949 - cf = top;
1958 + cf_global = top;
1959
1951 - ret = git_parse_source(fn, data, opts);
1960 + ret = git_parse_source(top, fn, data, opts);
1961
1962 /* pop config-file parsing state stack */
1963 strbuf_release(&top->value);
1964 strbuf_release(&top->var);
1956 - cf = top->prev;
1965 + cf_global = top->prev;
1966
1967 return ret;
1968 }
@@ -2334,12 +2343,12 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
2343 l_item->e = e;
2344 l_item->value_index = e->value_list.nr - 1;
2345
2337 - if (!cf)
2346 + if (!cf_global)
2347 BUG("configset_add_value has no source");
2339 - if (cf->name) {
2340 - kv_info->filename = strintern(cf->name);
2341 - kv_info->linenr = cf->linenr;
2342 - kv_info->origin_type = cf->origin_type;
2348 + if (cf_global->name) {
2349 + kv_info->filename = strintern(cf_global->name);
2350 + kv_info->linenr = cf_global->linenr;
2351 + kv_info->origin_type = cf_global->origin_type;
2352 } else {
2353 /* for values read from `git_config_from_parameters()` */
2354 kv_info->filename = NULL;
@@ -2891,6 +2900,12 @@ static int store_aux_event(enum config_event_t type,
2900 size_t begin, size_t end, void *data)
2901 {
2902 struct config_store_data *store = data;
2903 + /*
2904 + * FIXME Keep using "cf" so that we can avoid rewrapping a
2905 + * really long line below. Remove this when "cf" gets plumbed
2906 + * correctly.
2907 + */
2908 + struct config_source *cf = cf_global;
2909
2910 ALLOC_GROW(store->parsed, store->parsed_nr + 1, store->parsed_alloc);
2911 store->parsed[store->parsed_nr].begin = begin;
@@ -3771,8 +3786,8 @@ const char *current_config_origin_type(void)
3786 int type;
3787 if (current_config_kvi)
3788 type = current_config_kvi->origin_type;
3774 - else if(cf)
3775 - type = cf->origin_type;
3789 + else if(cf_global)
3790 + type = cf_global->origin_type;
3791 else
3792 BUG("current_config_origin_type called outside config callback");
3793
@@ -3817,8 +3832,8 @@ const char *current_config_name(void)
3832 const char *name;
3833 if (current_config_kvi)
3834 name = current_config_kvi->filename;
3820 - else if (cf)
3821 - name = cf->name;
3835 + else if (cf_global)
3836 + name = cf_global->name;
3837 else
3838 BUG("current_config_name called outside config callback");
3839 return name ? name : "";
@@ -3837,7 +3852,7 @@ int current_config_line(void)
3852 if (current_config_kvi)
3853 return current_config_kvi->linenr;
3854 else
3840 - return cf->linenr;
3855 + return cf_global->linenr;
3856 }
3857
3858 int lookup_config(const char **mapping, int nr_mapping, const char *var)