builtin/config: move display options into local variables

The display options are tracked via a set of global variables. Move them into a self-contained structure so that we can easily parse all relevant options and hand them over to the various functions that require them. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed May 15, 2024 at 08:42 UTC c0c1e263264fcb60296e2540f39799e925822d6c
1 file changed +101 -70
builtin/config.c
+101 -70
@@ -82,25 +82,42 @@ struct config_location_options {
82 };
83 #define CONFIG_LOCATION_OPTIONS_INIT {0}
84
85 +#define CONFIG_DISPLAY_OPTIONS(opts) \
86 + OPT_GROUP(N_("Display options")), \
87 + OPT_BOOL('z', "null", &opts.end_nul, N_("terminate values with NUL byte")), \
88 + OPT_BOOL(0, "name-only", &opts.omit_values, N_("show variable names only")), \
89 + OPT_BOOL(0, "show-origin", &opts.show_origin, N_("show origin of config (file, standard input, blob, command line)")), \
90 + OPT_BOOL(0, "show-scope", &opts.show_scope, N_("show scope of config (worktree, local, global, system, command)")), \
91 + OPT_BOOL(0, "show-names", &opts.show_keys, N_("show config keys in addition to their values"))
92 +
93 +struct config_display_options {
94 + int end_nul;
95 + int omit_values;
96 + int show_origin;
97 + int show_scope;
98 + int show_keys;
99 + /* Populated via `display_options_init()`. */
100 + int term;
101 + int delim;
102 + int key_delim;
103 +};
104 +#define CONFIG_DISPLAY_OPTIONS_INIT { \
105 + .term = '\n', \
106 + .delim = '=', \
107 + .key_delim = ' ', \
108 +}
109 +
110 static char *key;
111 static regex_t *key_regexp;
112 static const char *value_pattern;
113 static regex_t *regexp;
89 -static int show_keys;
90 -static int omit_values;
114 static int use_key_regexp;
115 static int do_all;
116 static int do_not_match;
94 -static char delim = '=';
95 -static char key_delim = ' ';
96 -static char term = '\n';
117
118 static int type;
119 static char *default_value;
100 -static int end_nul;
120 static int respect_includes_opt = -1;
102 -static int show_origin;
103 -static int show_scope;
121 static int fixed_value;
122
123 #define TYPE_BOOL 1
@@ -178,24 +195,26 @@ static void check_argc(int argc, int min, int max)
195 exit(129);
196 }
197
181 -static void show_config_origin(const struct key_value_info *kvi,
198 +static void show_config_origin(const struct config_display_options *opts,
199 + const struct key_value_info *kvi,
200 struct strbuf *buf)
201 {
184 - const char term = end_nul ? '\0' : '\t';
202 + const char term = opts->end_nul ? '\0' : '\t';
203
204 strbuf_addstr(buf, config_origin_type_name(kvi->origin_type));
205 strbuf_addch(buf, ':');
188 - if (end_nul)
206 + if (opts->end_nul)
207 strbuf_addstr(buf, kvi->filename ? kvi->filename : "");
208 else
209 quote_c_style(kvi->filename ? kvi->filename : "", buf, NULL, 0);
210 strbuf_addch(buf, term);
211 }
212
195 -static void show_config_scope(const struct key_value_info *kvi,
213 +static void show_config_scope(const struct config_display_options *opts,
214 + const struct key_value_info *kvi,
215 struct strbuf *buf)
216 {
198 - const char term = end_nul ? '\0' : '\t';
217 + const char term = opts->end_nul ? '\0' : '\t';
218 const char *scope = config_scope_name(kvi->scope);
219
220 strbuf_addstr(buf, N_(scope));
@@ -204,24 +223,25 @@ static void show_config_scope(const struct key_value_info *kvi,
223
224 static int show_all_config(const char *key_, const char *value_,
225 const struct config_context *ctx,
207 - void *cb UNUSED)
226 + void *cb)
227 {
228 + const struct config_display_options *opts = cb;
229 const struct key_value_info *kvi = ctx->kvi;
230
211 - if (show_origin || show_scope) {
231 + if (opts->show_origin || opts->show_scope) {
232 struct strbuf buf = STRBUF_INIT;
213 - if (show_scope)
214 - show_config_scope(kvi, &buf);
215 - if (show_origin)
216 - show_config_origin(kvi, &buf);
233 + if (opts->show_scope)
234 + show_config_scope(opts, kvi, &buf);
235 + if (opts->show_origin)
236 + show_config_origin(opts, kvi, &buf);
237 /* Use fwrite as "buf" can contain \0's if "end_null" is set. */
238 fwrite(buf.buf, 1, buf.len, stdout);
239 strbuf_release(&buf);
240 }
221 - if (!omit_values && value_)
222 - printf("%s%c%s%c", key_, delim, value_, term);
241 + if (!opts->omit_values && value_)
242 + printf("%s%c%s%c", key_, opts->delim, value_, opts->term);
243 else
224 - printf("%s%c", key_, term);
244 + printf("%s%c", key_, opts->term);
245 return 0;
246 }
247
@@ -231,18 +251,19 @@ struct strbuf_list {
251 int alloc;
252 };
253
234 -static int format_config(struct strbuf *buf, const char *key_,
254 +static int format_config(const struct config_display_options *opts,
255 + struct strbuf *buf, const char *key_,
256 const char *value_, const struct key_value_info *kvi)
257 {
237 - if (show_scope)
238 - show_config_scope(kvi, buf);
239 - if (show_origin)
240 - show_config_origin(kvi, buf);
241 - if (show_keys)
258 + if (opts->show_scope)
259 + show_config_scope(opts, kvi, buf);
260 + if (opts->show_origin)
261 + show_config_origin(opts, kvi, buf);
262 + if (opts->show_keys)
263 strbuf_addstr(buf, key_);
243 - if (!omit_values) {
244 - if (show_keys)
245 - strbuf_addch(buf, key_delim);
264 + if (!opts->omit_values) {
265 + if (opts->show_keys)
266 + strbuf_addch(buf, opts->key_delim);
267
268 if (type == TYPE_INT)
269 strbuf_addf(buf, "%"PRId64,
@@ -284,18 +305,24 @@ static int format_config(struct strbuf *buf, const char *key_,
305 strbuf_addstr(buf, value_);
306 } else {
307 /* Just show the key name; back out delimiter */
287 - if (show_keys)
308 + if (opts->show_keys)
309 strbuf_setlen(buf, buf->len - 1);
310 }
311 }
291 - strbuf_addch(buf, term);
312 + strbuf_addch(buf, opts->term);
313 return 0;
314 }
315
316 +struct collect_config_data {
317 + const struct config_display_options *display_opts;
318 + struct strbuf_list *values;
319 +};
320 +
321 static int collect_config(const char *key_, const char *value_,
322 const struct config_context *ctx, void *cb)
323 {
298 - struct strbuf_list *values = cb;
324 + struct collect_config_data *data = cb;
325 + struct strbuf_list *values = data->values;
326 const struct key_value_info *kvi = ctx->kvi;
327
328 if (!use_key_regexp && strcmp(key_, key))
@@ -311,14 +338,20 @@ static int collect_config(const char *key_, const char *value_,
338 ALLOC_GROW(values->items, values->nr + 1, values->alloc);
339 strbuf_init(&values->items[values->nr], 0);
340
314 - return format_config(&values->items[values->nr++], key_, value_, kvi);
341 + return format_config(data->display_opts, &values->items[values->nr++],
342 + key_, value_, kvi);
343 }
344
345 static int get_value(const struct config_location_options *opts,
346 + const struct config_display_options *display_opts,
347 const char *key_, const char *regex_, unsigned flags)
348 {
349 int ret = CONFIG_GENERIC_ERROR;
350 struct strbuf_list values = {NULL};
351 + struct collect_config_data data = {
352 + .display_opts = display_opts,
353 + .values = &values,
354 + };
355 int i;
356
357 if (use_key_regexp) {
@@ -369,7 +402,7 @@ static int get_value(const struct config_location_options *opts,
402 }
403 }
404
372 - config_with_options(collect_config, &values,
405 + config_with_options(collect_config, &data,
406 &opts->source, the_repository,
407 &opts->options);
408
@@ -381,7 +414,7 @@ static int get_value(const struct config_location_options *opts,
414 ALLOC_GROW(values.items, values.nr + 1, values.alloc);
415 item = &values.items[values.nr++];
416 strbuf_init(item, 0);
384 - if (format_config(item, key_, default_value, &kvi) < 0)
417 + if (format_config(display_opts, item, key_, default_value, &kvi) < 0)
418 die(_("failed to format default config value: %s"),
419 default_value);
420 }
@@ -592,10 +625,12 @@ static int urlmatch_collect_fn(const char *var, const char *value,
625 }
626
627 static int get_urlmatch(const struct config_location_options *opts,
628 + const struct config_display_options *_display_opts,
629 const char *var, const char *url)
630 {
631 int ret;
632 char *section_tail;
633 + struct config_display_options display_opts = *_display_opts;
634 struct string_list_item *item;
635 struct urlmatch_config config = URLMATCH_CONFIG_INIT;
636 struct string_list values = STRING_LIST_INIT_DUP;
@@ -612,10 +647,10 @@ static int get_urlmatch(const struct config_location_options *opts,
647 if (section_tail) {
648 *section_tail = '\0';
649 config.key = section_tail + 1;
615 - show_keys = 0;
650 + display_opts.show_keys = 0;
651 } else {
652 config.key = NULL;
618 - show_keys = 1;
653 + display_opts.show_keys = 1;
654 }
655
656 config_with_options(urlmatch_config_entry, &config,
@@ -628,7 +663,7 @@ static int get_urlmatch(const struct config_location_options *opts,
663 struct urlmatch_current_candidate_value *matched = item->util;
664 struct strbuf buf = STRBUF_INIT;
665
631 - format_config(&buf, item->string,
666 + format_config(&display_opts, &buf, item->string,
667 matched->value_is_null ? NULL : matched->value.buf,
668 &matched->kvi);
669 fwrite(buf.buf, 1, buf.len, stdout);
@@ -745,11 +780,12 @@ static void location_options_release(struct config_location_options *opts)
780 free(opts->file_to_free);
781 }
782
748 -static void handle_nul(void) {
749 - if (end_nul) {
750 - term = '\0';
751 - delim = '\n';
752 - key_delim = '\n';
783 +static void display_options_init(struct config_display_options *opts)
784 +{
785 + if (opts->end_nul) {
786 + opts->term = '\0';
787 + opts->delim = '\n';
788 + opts->key_delim = '\n';
789 }
790 }
791
@@ -763,19 +799,13 @@ static void handle_nul(void) {
799 OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH), \
800 OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE)
801
766 -#define CONFIG_DISPLAY_OPTIONS \
767 - OPT_GROUP(N_("Display options")), \
768 - OPT_BOOL('z', "null", &end_nul, N_("terminate values with NUL byte")), \
769 - OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")), \
770 - OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")), \
771 - OPT_BOOL(0, "show-scope", &show_scope, N_("show scope of config (worktree, local, global, system, command)"))
772 -
802 static int cmd_config_list(int argc, const char **argv, const char *prefix)
803 {
804 struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
805 + struct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;
806 struct option opts[] = {
807 CONFIG_LOCATION_OPTIONS(location_opts),
778 - CONFIG_DISPLAY_OPTIONS,
808 + CONFIG_DISPLAY_OPTIONS(display_opts),
809 OPT_GROUP(N_("Other")),
810 OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
811 OPT_END(),
@@ -785,11 +815,11 @@ static int cmd_config_list(int argc, const char **argv, const char *prefix)
815 check_argc(argc, 0, 0);
816
817 location_options_init(&location_opts, prefix);
788 - handle_nul();
818 + display_options_init(&display_opts);
819
820 setup_auto_pager("config", 1);
821
792 - if (config_with_options(show_all_config, NULL,
822 + if (config_with_options(show_all_config, &display_opts,
823 &location_opts.source, the_repository,
824 &location_opts.options) < 0) {
825 if (location_opts.source.file)
@@ -806,6 +836,7 @@ static int cmd_config_list(int argc, const char **argv, const char *prefix)
836 static int cmd_config_get(int argc, const char **argv, const char *prefix)
837 {
838 struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
839 + struct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;
840 const char *value_pattern = NULL, *url = NULL;
841 int flags = 0;
842 struct option opts[] = {
@@ -817,8 +848,7 @@ static int cmd_config_get(int argc, const char **argv, const char *prefix)
848 OPT_STRING(0, "value", &value_pattern, N_("pattern"), N_("show config with values matching the pattern")),
849 OPT_BIT(0, "fixed-value", &flags, N_("use string equality when comparing values to value pattern"), CONFIG_FLAGS_FIXED_VALUE),
850 OPT_STRING(0, "url", &url, N_("URL"), N_("show config matching the given URL")),
820 - CONFIG_DISPLAY_OPTIONS,
821 - OPT_BOOL(0, "show-names", &show_keys, N_("show config keys in addition to their values")),
851 + CONFIG_DISPLAY_OPTIONS(display_opts),
852 OPT_GROUP(N_("Other")),
853 OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
854 OPT_STRING(0, "default", &default_value, N_("value"), N_("use default value when missing entry")),
@@ -838,14 +868,14 @@ static int cmd_config_get(int argc, const char **argv, const char *prefix)
868 die(_("--url= cannot be used with --all, --regexp or --value"));
869
870 location_options_init(&location_opts, prefix);
841 - handle_nul();
871 + display_options_init(&display_opts);
872
873 setup_auto_pager("config", 1);
874
875 if (url)
846 - ret = get_urlmatch(&location_opts, argv[0], url);
876 + ret = get_urlmatch(&location_opts, &display_opts, argv[0], url);
877 else
848 - ret = get_value(&location_opts, argv[0], value_pattern, flags);
878 + ret = get_value(&location_opts, &display_opts, argv[0], value_pattern, flags);
879
880 location_options_release(&location_opts);
881 return ret;
@@ -1076,6 +1106,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
1106 ACTION_GET_URLMATCH = (1<<15),
1107 };
1108 struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
1109 + struct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;
1110 const char *comment_arg = NULL;
1111 int actions = 0;
1112 struct option opts[] = {
@@ -1096,7 +1127,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
1127 OPT_CMDMODE(0, "get-color", &actions, N_("find the color configured: slot [<default>]"), ACTION_GET_COLOR),
1128 OPT_CMDMODE(0, "get-colorbool", &actions, N_("find the color setting: slot [<stdout-is-tty>]"), ACTION_GET_COLORBOOL),
1129 CONFIG_TYPE_OPTIONS,
1099 - CONFIG_DISPLAY_OPTIONS,
1130 + CONFIG_DISPLAY_OPTIONS(display_opts),
1131 OPT_GROUP(N_("Other")),
1132 OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")),
1133 OPT_STRING(0, "comment", &comment_arg, N_("value"), N_("human-readable comment string (# will be prepended as needed)")),
@@ -1114,7 +1145,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
1145 PARSE_OPT_STOP_AT_NON_OPTION);
1146
1147 location_options_init(&location_opts, prefix);
1117 - handle_nul();
1148 + display_options_init(&display_opts);
1149
1150 if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && type) {
1151 error(_("--get-color and variable type are incoherent"));
@@ -1130,13 +1161,13 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
1161 error(_("no action specified"));
1162 exit(129);
1163 }
1133 - if (omit_values &&
1164 + if (display_opts.omit_values &&
1165 !(actions == ACTION_LIST || actions == ACTION_GET_REGEXP)) {
1166 error(_("--name-only is only applicable to --list or --get-regexp"));
1167 exit(129);
1168 }
1169
1139 - if (show_origin && !(actions &
1170 + if (display_opts.show_origin && !(actions &
1171 (ACTION_GET|ACTION_GET_ALL|ACTION_GET_REGEXP|ACTION_LIST))) {
1172 error(_("--show-origin is only applicable to --get, --get-all, "
1173 "--get-regexp, and --list"));
@@ -1201,7 +1232,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
1232
1233 if (actions == ACTION_LIST) {
1234 check_argc(argc, 0, 0);
1204 - if (config_with_options(show_all_config, NULL,
1235 + if (config_with_options(show_all_config, &display_opts,
1236 &location_opts.source, the_repository,
1237 &location_opts.options) < 0) {
1238 if (location_opts.source.file)
@@ -1250,23 +1281,23 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
1281 }
1282 else if (actions == ACTION_GET) {
1283 check_argc(argc, 1, 2);
1253 - ret = get_value(&location_opts, argv[0], argv[1], flags);
1284 + ret = get_value(&location_opts, &display_opts, argv[0], argv[1], flags);
1285 }
1286 else if (actions == ACTION_GET_ALL) {
1287 do_all = 1;
1288 check_argc(argc, 1, 2);
1258 - ret = get_value(&location_opts, argv[0], argv[1], flags);
1289 + ret = get_value(&location_opts, &display_opts, argv[0], argv[1], flags);
1290 }
1291 else if (actions == ACTION_GET_REGEXP) {
1261 - show_keys = 1;
1292 + display_opts.show_keys = 1;
1293 use_key_regexp = 1;
1294 do_all = 1;
1295 check_argc(argc, 1, 2);
1265 - ret = get_value(&location_opts, argv[0], argv[1], flags);
1296 + ret = get_value(&location_opts, &display_opts, argv[0], argv[1], flags);
1297 }
1298 else if (actions == ACTION_GET_URLMATCH) {
1299 check_argc(argc, 2, 2);
1269 - ret = get_urlmatch(&location_opts, argv[0], argv[1]);
1300 + ret = get_urlmatch(&location_opts, &display_opts, argv[0], argv[1]);
1301 }
1302 else if (actions == ACTION_UNSET) {
1303 check_write(&location_opts.source);