Git fork

config: pass kvi to die_bad_number()

Plumb "struct key_value_info" through all code paths that end in
die_bad_number(), which lets us remove the helper functions that read
analogous values from "struct config_reader". As a result, nothing reads
config_reader.config_kvi any more, so remove that too.

In config.c, this requires changing the signature of
git_configset_get_value() to 'return' "kvi" in an out parameter so that
git_configset_get_<type>() can pass it to git_config_<type>(). Only
numeric types will use "kvi", so for non-numeric types (e.g.
git_configset_get_string()), pass NULL to indicate that the out
parameter isn't needed.

Outside of config.c, config callbacks now need to pass "ctx->kvi" to any
of the git_config_<type>() functions that parse a config string into a
number type. Included is a .cocci patch to make that refactor.

The only exceptional case is builtin/config.c, where git_config_<type>()
is called outside of a config callback (namely, on user-provided input),
so config source information has never been available. In this case,
die_bad_number() defaults to a generic, but perfectly descriptive
message. Let's provide a safe, non-NULL for "kvi" anyway, but make sure
not to change the message.

Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Glen Choo and committed by
Junio C Hamano
8868b1eb dc902084

+190 -182
+2 -2
archive-tar.c
··· 412 412 } 413 413 414 414 static int git_tar_config(const char *var, const char *value, 415 - const struct config_context *ctx UNUSED, void *cb) 415 + const struct config_context *ctx, void *cb) 416 416 { 417 417 if (!strcmp(var, "tar.umask")) { 418 418 if (value && !strcmp(value, "user")) { 419 419 tar_umask = umask(0); 420 420 umask(tar_umask); 421 421 } else { 422 - tar_umask = git_config_int(var, value); 422 + tar_umask = git_config_int(var, value, ctx->kvi); 423 423 } 424 424 return 0; 425 425 }
+2 -2
builtin/commit-graph.c
··· 186 186 } 187 187 188 188 static int git_commit_graph_write_config(const char *var, const char *value, 189 - const struct config_context *ctx UNUSED, 189 + const struct config_context *ctx, 190 190 void *cb UNUSED) 191 191 { 192 192 if (!strcmp(var, "commitgraph.maxnewfilters")) 193 - write_opts.max_new_filters = git_config_int(var, value); 193 + write_opts.max_new_filters = git_config_int(var, value, ctx->kvi); 194 194 /* 195 195 * No need to fall-back to 'git_default_config', since this was already 196 196 * called in 'cmd_commit_graph()'.
+6 -4
builtin/commit.c
··· 1415 1415 return git_column_config(k, v, "status", &s->colopts); 1416 1416 if (!strcmp(k, "status.submodulesummary")) { 1417 1417 int is_bool; 1418 - s->submodule_summary = git_config_bool_or_int(k, v, &is_bool); 1418 + s->submodule_summary = git_config_bool_or_int(k, v, ctx->kvi, 1419 + &is_bool); 1419 1420 if (is_bool && s->submodule_summary) 1420 1421 s->submodule_summary = -1; 1421 1422 return 0; ··· 1475 1476 } 1476 1477 if (!strcmp(k, "diff.renamelimit")) { 1477 1478 if (s->rename_limit == -1) 1478 - s->rename_limit = git_config_int(k, v); 1479 + s->rename_limit = git_config_int(k, v, ctx->kvi); 1479 1480 return 0; 1480 1481 } 1481 1482 if (!strcmp(k, "status.renamelimit")) { 1482 - s->rename_limit = git_config_int(k, v); 1483 + s->rename_limit = git_config_int(k, v, ctx->kvi); 1483 1484 return 0; 1484 1485 } 1485 1486 if (!strcmp(k, "diff.renames")) { ··· 1625 1626 } 1626 1627 if (!strcmp(k, "commit.verbose")) { 1627 1628 int is_bool; 1628 - config_commit_verbose = git_config_bool_or_int(k, v, &is_bool); 1629 + config_commit_verbose = git_config_bool_or_int(k, v, ctx->kvi, 1630 + &is_bool); 1629 1631 return 0; 1630 1632 } 1631 1633
+12 -9
builtin/config.c
··· 262 262 263 263 if (type == TYPE_INT) 264 264 strbuf_addf(buf, "%"PRId64, 265 - git_config_int64(key_, value_ ? value_ : "")); 265 + git_config_int64(key_, value_ ? value_ : "", kvi)); 266 266 else if (type == TYPE_BOOL) 267 267 strbuf_addstr(buf, git_config_bool(key_, value_) ? 268 268 "true" : "false"); 269 269 else if (type == TYPE_BOOL_OR_INT) { 270 270 int is_bool, v; 271 - v = git_config_bool_or_int(key_, value_, &is_bool); 271 + v = git_config_bool_or_int(key_, value_, kvi, 272 + &is_bool); 272 273 if (is_bool) 273 274 strbuf_addstr(buf, v ? "true" : "false"); 274 275 else ··· 424 425 return ret; 425 426 } 426 427 427 - static char *normalize_value(const char *key, const char *value) 428 + static char *normalize_value(const char *key, const char *value, 429 + struct key_value_info *kvi) 428 430 { 429 431 if (!value) 430 432 return NULL; ··· 439 441 */ 440 442 return xstrdup(value); 441 443 if (type == TYPE_INT) 442 - return xstrfmt("%"PRId64, git_config_int64(key, value)); 444 + return xstrfmt("%"PRId64, git_config_int64(key, value, kvi)); 443 445 if (type == TYPE_BOOL) 444 446 return xstrdup(git_config_bool(key, value) ? "true" : "false"); 445 447 if (type == TYPE_BOOL_OR_INT) { 446 448 int is_bool, v; 447 - v = git_config_bool_or_int(key, value, &is_bool); 449 + v = git_config_bool_or_int(key, value, kvi, &is_bool); 448 450 if (!is_bool) 449 451 return xstrfmt("%d", v); 450 452 else ··· 674 676 char *value = NULL; 675 677 int flags = 0; 676 678 int ret = 0; 679 + struct key_value_info default_kvi = KVI_INIT; 677 680 678 681 given_config_source.file = xstrdup_or_null(getenv(CONFIG_ENVIRONMENT)); 679 682 ··· 891 894 else if (actions == ACTION_SET) { 892 895 check_write(); 893 896 check_argc(argc, 2, 2); 894 - value = normalize_value(argv[0], argv[1]); 897 + value = normalize_value(argv[0], argv[1], &default_kvi); 895 898 ret = git_config_set_in_file_gently(given_config_source.file, argv[0], value); 896 899 if (ret == CONFIG_NOTHING_SET) 897 900 error(_("cannot overwrite multiple values with a single value\n" ··· 900 903 else if (actions == ACTION_SET_ALL) { 901 904 check_write(); 902 905 check_argc(argc, 2, 3); 903 - value = normalize_value(argv[0], argv[1]); 906 + value = normalize_value(argv[0], argv[1], &default_kvi); 904 907 ret = git_config_set_multivar_in_file_gently(given_config_source.file, 905 908 argv[0], value, argv[2], 906 909 flags); ··· 908 911 else if (actions == ACTION_ADD) { 909 912 check_write(); 910 913 check_argc(argc, 2, 2); 911 - value = normalize_value(argv[0], argv[1]); 914 + value = normalize_value(argv[0], argv[1], &default_kvi); 912 915 ret = git_config_set_multivar_in_file_gently(given_config_source.file, 913 916 argv[0], value, 914 917 CONFIG_REGEX_NONE, ··· 917 920 else if (actions == ACTION_REPLACE_ALL) { 918 921 check_write(); 919 922 check_argc(argc, 2, 3); 920 - value = normalize_value(argv[0], argv[1]); 923 + value = normalize_value(argv[0], argv[1], &default_kvi); 921 924 ret = git_config_set_multivar_in_file_gently(given_config_source.file, 922 925 argv[0], value, argv[2], 923 926 flags | CONFIG_FLAGS_MULTI_REPLACE);
+2 -2
builtin/fetch.c
··· 137 137 } 138 138 139 139 if (!strcmp(k, "submodule.fetchjobs")) { 140 - fetch_config->submodule_fetch_jobs = parse_submodule_fetchjobs(k, v); 140 + fetch_config->submodule_fetch_jobs = parse_submodule_fetchjobs(k, v, ctx->kvi); 141 141 return 0; 142 142 } else if (!strcmp(k, "fetch.recursesubmodules")) { 143 143 fetch_config->recurse_submodules = parse_fetch_recurse_submodules_arg(k, v); ··· 145 145 } 146 146 147 147 if (!strcmp(k, "fetch.parallel")) { 148 - fetch_config->parallel = git_config_int(k, v); 148 + fetch_config->parallel = git_config_int(k, v, ctx->kvi); 149 149 if (fetch_config->parallel < 0) 150 150 die(_("fetch.parallel cannot be negative")); 151 151 if (!fetch_config->parallel)
+3 -3
builtin/fsmonitor--daemon.c
··· 41 41 const struct config_context *ctx, void *cb) 42 42 { 43 43 if (!strcmp(var, FSMONITOR__IPC_THREADS)) { 44 - int i = git_config_int(var, value); 44 + int i = git_config_int(var, value, ctx->kvi); 45 45 if (i < 1) 46 46 return error(_("value of '%s' out of range: %d"), 47 47 FSMONITOR__IPC_THREADS, i); ··· 50 50 } 51 51 52 52 if (!strcmp(var, FSMONITOR__START_TIMEOUT)) { 53 - int i = git_config_int(var, value); 53 + int i = git_config_int(var, value, ctx->kvi); 54 54 if (i < 0) 55 55 return error(_("value of '%s' out of range: %d"), 56 56 FSMONITOR__START_TIMEOUT, i); ··· 60 60 61 61 if (!strcmp(var, FSMONITOR__ANNOUNCE_STARTUP)) { 62 62 int is_bool; 63 - int i = git_config_bool_or_int(var, value, &is_bool); 63 + int i = git_config_bool_or_int(var, value, ctx->kvi, &is_bool); 64 64 if (i < 0) 65 65 return error(_("value of '%s' not bool or int: %d"), 66 66 var, i);
+1 -1
builtin/grep.c
··· 301 301 st = -1; 302 302 303 303 if (!strcmp(var, "grep.threads")) { 304 - num_threads = git_config_int(var, value); 304 + num_threads = git_config_int(var, value, ctx->kvi); 305 305 if (num_threads < 0) 306 306 die(_("invalid number of threads specified (%d) for %s"), 307 307 num_threads, var);
+2 -2
builtin/index-pack.c
··· 1587 1587 struct pack_idx_option *opts = cb; 1588 1588 1589 1589 if (!strcmp(k, "pack.indexversion")) { 1590 - opts->version = git_config_int(k, v); 1590 + opts->version = git_config_int(k, v, ctx->kvi); 1591 1591 if (opts->version > 2) 1592 1592 die(_("bad pack.indexVersion=%"PRIu32), opts->version); 1593 1593 return 0; 1594 1594 } 1595 1595 if (!strcmp(k, "pack.threads")) { 1596 - nr_threads = git_config_int(k, v); 1596 + nr_threads = git_config_int(k, v, ctx->kvi); 1597 1597 if (nr_threads < 0) 1598 1598 die(_("invalid number of threads specified (%d)"), 1599 1599 nr_threads);
+1 -1
builtin/log.c
··· 574 574 if (!strcmp(var, "format.subjectprefix")) 575 575 return git_config_string(&fmt_patch_subject_prefix, var, value); 576 576 if (!strcmp(var, "format.filenamemaxlength")) { 577 - fmt_patch_name_max = git_config_int(var, value); 577 + fmt_patch_name_max = git_config_int(var, value, ctx->kvi); 578 578 return 0; 579 579 } 580 580 if (!strcmp(var, "format.encodeemailheaders")) {
+7 -7
builtin/pack-objects.c
··· 3139 3139 const struct config_context *ctx, void *cb) 3140 3140 { 3141 3141 if (!strcmp(k, "pack.window")) { 3142 - window = git_config_int(k, v); 3142 + window = git_config_int(k, v, ctx->kvi); 3143 3143 return 0; 3144 3144 } 3145 3145 if (!strcmp(k, "pack.windowmemory")) { 3146 - window_memory_limit = git_config_ulong(k, v); 3146 + window_memory_limit = git_config_ulong(k, v, ctx->kvi); 3147 3147 return 0; 3148 3148 } 3149 3149 if (!strcmp(k, "pack.depth")) { 3150 - depth = git_config_int(k, v); 3150 + depth = git_config_int(k, v, ctx->kvi); 3151 3151 return 0; 3152 3152 } 3153 3153 if (!strcmp(k, "pack.deltacachesize")) { 3154 - max_delta_cache_size = git_config_int(k, v); 3154 + max_delta_cache_size = git_config_int(k, v, ctx->kvi); 3155 3155 return 0; 3156 3156 } 3157 3157 if (!strcmp(k, "pack.deltacachelimit")) { 3158 - cache_max_small_delta_size = git_config_int(k, v); 3158 + cache_max_small_delta_size = git_config_int(k, v, ctx->kvi); 3159 3159 return 0; 3160 3160 } 3161 3161 if (!strcmp(k, "pack.writebitmaphashcache")) { ··· 3181 3181 return 0; 3182 3182 } 3183 3183 if (!strcmp(k, "pack.threads")) { 3184 - delta_search_threads = git_config_int(k, v); 3184 + delta_search_threads = git_config_int(k, v, ctx->kvi); 3185 3185 if (delta_search_threads < 0) 3186 3186 die(_("invalid number of threads specified (%d)"), 3187 3187 delta_search_threads); ··· 3192 3192 return 0; 3193 3193 } 3194 3194 if (!strcmp(k, "pack.indexversion")) { 3195 - pack_idx_opts.version = git_config_int(k, v); 3195 + pack_idx_opts.version = git_config_int(k, v, ctx->kvi); 3196 3196 if (pack_idx_opts.version > 2) 3197 3197 die(_("bad pack.indexVersion=%"PRIu32), 3198 3198 pack_idx_opts.version);
+5 -5
builtin/receive-pack.c
··· 158 158 } 159 159 160 160 if (strcmp(var, "receive.unpacklimit") == 0) { 161 - receive_unpack_limit = git_config_int(var, value); 161 + receive_unpack_limit = git_config_int(var, value, ctx->kvi); 162 162 return 0; 163 163 } 164 164 165 165 if (strcmp(var, "transfer.unpacklimit") == 0) { 166 - transfer_unpack_limit = git_config_int(var, value); 166 + transfer_unpack_limit = git_config_int(var, value, ctx->kvi); 167 167 return 0; 168 168 } 169 169 ··· 231 231 return git_config_string(&cert_nonce_seed, var, value); 232 232 233 233 if (strcmp(var, "receive.certnonceslop") == 0) { 234 - nonce_stamp_slop_limit = git_config_ulong(var, value); 234 + nonce_stamp_slop_limit = git_config_ulong(var, value, ctx->kvi); 235 235 return 0; 236 236 } 237 237 ··· 246 246 } 247 247 248 248 if (strcmp(var, "receive.keepalive") == 0) { 249 - keepalive_in_sec = git_config_int(var, value); 249 + keepalive_in_sec = git_config_int(var, value, ctx->kvi); 250 250 return 0; 251 251 } 252 252 253 253 if (strcmp(var, "receive.maxinputsize") == 0) { 254 - max_input_size = git_config_int64(var, value); 254 + max_input_size = git_config_int64(var, value, ctx->kvi); 255 255 return 0; 256 256 } 257 257
+2 -2
builtin/submodule--helper.c
··· 2192 2192 } 2193 2193 2194 2194 static int git_update_clone_config(const char *var, const char *value, 2195 - const struct config_context *ctx UNUSED, 2195 + const struct config_context *ctx, 2196 2196 void *cb) 2197 2197 { 2198 2198 int *max_jobs = cb; 2199 2199 2200 2200 if (!strcmp(var, "submodule.fetchjobs")) 2201 - *max_jobs = parse_submodule_fetchjobs(var, value); 2201 + *max_jobs = parse_submodule_fetchjobs(var, value, ctx->kvi); 2202 2202 return 0; 2203 2203 } 2204 2204
+61 -95
config.c
··· 73 73 * 74 74 * The "source" variable will be non-NULL only when we are actually 75 75 * parsing a real config source (file, blob, cmdline, etc). 76 - * 77 - * The "config_kvi" variable will be non-NULL only when we are feeding 78 - * cached config from a configset into a callback. 79 - * 80 - * They cannot be non-NULL at the same time. If they are both NULL, then 81 - * we aren't parsing anything (and depending on the function looking at 82 - * the variables, it's either a bug for it to be called in the first 83 - * place, or it's a function which can be reused for non-config 84 - * purposes, and should fall back to some sane behavior). 85 76 */ 86 77 struct config_source *source; 87 - struct key_value_info *config_kvi; 88 78 }; 89 79 /* 90 80 * Where possible, prefer to accept "struct config_reader" as an arg than to use ··· 96 86 static inline void config_reader_push_source(struct config_reader *reader, 97 87 struct config_source *top) 98 88 { 99 - if (reader->config_kvi) 100 - BUG("source should not be set while iterating a config set"); 101 89 top->prev = reader->source; 102 90 reader->source = top; 103 91 } ··· 110 98 ret = reader->source; 111 99 reader->source = reader->source->prev; 112 100 return ret; 113 - } 114 - 115 - static inline void config_reader_set_kvi(struct config_reader *reader, 116 - struct key_value_info *kvi) 117 - { 118 - reader->config_kvi = kvi; 119 101 } 120 102 121 103 static int pack_compression_seen; ··· 1346 1328 return 1; 1347 1329 } 1348 1330 1349 - static int reader_config_name(struct config_reader *reader, const char **out); 1350 - static int reader_origin_type(struct config_reader *reader, 1351 - enum config_origin_type *type); 1352 1331 NORETURN 1353 - static void die_bad_number(struct config_reader *reader, const char *name, 1354 - const char *value) 1332 + static void die_bad_number(const char *name, const char *value, 1333 + const struct key_value_info *kvi) 1355 1334 { 1356 1335 const char *error_type = (errno == ERANGE) ? 1357 1336 N_("out of range") : N_("invalid unit"); 1358 1337 const char *bad_numeric = N_("bad numeric config value '%s' for '%s': %s"); 1359 - const char *config_name = NULL; 1360 - enum config_origin_type config_origin = CONFIG_ORIGIN_UNKNOWN; 1338 + 1339 + if (!kvi) 1340 + BUG("kvi should not be NULL"); 1361 1341 1362 1342 if (!value) 1363 1343 value = ""; 1364 1344 1365 - /* Ignoring the return value is okay since we handle missing values. */ 1366 - reader_config_name(reader, &config_name); 1367 - reader_origin_type(reader, &config_origin); 1368 - 1369 - if (!config_name) 1345 + if (!kvi->filename) 1370 1346 die(_(bad_numeric), value, name, _(error_type)); 1371 1347 1372 - switch (config_origin) { 1348 + switch (kvi->origin_type) { 1373 1349 case CONFIG_ORIGIN_BLOB: 1374 1350 die(_("bad numeric config value '%s' for '%s' in blob %s: %s"), 1375 - value, name, config_name, _(error_type)); 1351 + value, name, kvi->filename, _(error_type)); 1376 1352 case CONFIG_ORIGIN_FILE: 1377 1353 die(_("bad numeric config value '%s' for '%s' in file %s: %s"), 1378 - value, name, config_name, _(error_type)); 1354 + value, name, kvi->filename, _(error_type)); 1379 1355 case CONFIG_ORIGIN_STDIN: 1380 1356 die(_("bad numeric config value '%s' for '%s' in standard input: %s"), 1381 1357 value, name, _(error_type)); 1382 1358 case CONFIG_ORIGIN_SUBMODULE_BLOB: 1383 1359 die(_("bad numeric config value '%s' for '%s' in submodule-blob %s: %s"), 1384 - value, name, config_name, _(error_type)); 1360 + value, name, kvi->filename, _(error_type)); 1385 1361 case CONFIG_ORIGIN_CMDLINE: 1386 1362 die(_("bad numeric config value '%s' for '%s' in command line %s: %s"), 1387 - value, name, config_name, _(error_type)); 1363 + value, name, kvi->filename, _(error_type)); 1388 1364 default: 1389 1365 die(_("bad numeric config value '%s' for '%s' in %s: %s"), 1390 - value, name, config_name, _(error_type)); 1366 + value, name, kvi->filename, _(error_type)); 1391 1367 } 1392 1368 } 1393 1369 1394 - int git_config_int(const char *name, const char *value) 1370 + int git_config_int(const char *name, const char *value, 1371 + const struct key_value_info *kvi) 1395 1372 { 1396 1373 int ret; 1397 1374 if (!git_parse_int(value, &ret)) 1398 - die_bad_number(&the_reader, name, value); 1375 + die_bad_number(name, value, kvi); 1399 1376 return ret; 1400 1377 } 1401 1378 1402 - int64_t git_config_int64(const char *name, const char *value) 1379 + int64_t git_config_int64(const char *name, const char *value, 1380 + const struct key_value_info *kvi) 1403 1381 { 1404 1382 int64_t ret; 1405 1383 if (!git_parse_int64(value, &ret)) 1406 - die_bad_number(&the_reader, name, value); 1384 + die_bad_number(name, value, kvi); 1407 1385 return ret; 1408 1386 } 1409 1387 1410 - unsigned long git_config_ulong(const char *name, const char *value) 1388 + unsigned long git_config_ulong(const char *name, const char *value, 1389 + const struct key_value_info *kvi) 1411 1390 { 1412 1391 unsigned long ret; 1413 1392 if (!git_parse_ulong(value, &ret)) 1414 - die_bad_number(&the_reader, name, value); 1393 + die_bad_number(name, value, kvi); 1415 1394 return ret; 1416 1395 } 1417 1396 1418 - ssize_t git_config_ssize_t(const char *name, const char *value) 1397 + ssize_t git_config_ssize_t(const char *name, const char *value, 1398 + const struct key_value_info *kvi) 1419 1399 { 1420 1400 ssize_t ret; 1421 1401 if (!git_parse_ssize_t(value, &ret)) 1422 - die_bad_number(&the_reader, name, value); 1402 + die_bad_number(name, value, kvi); 1423 1403 return ret; 1424 1404 } 1425 1405 ··· 1524 1504 return -1; 1525 1505 } 1526 1506 1527 - int git_config_bool_or_int(const char *name, const char *value, int *is_bool) 1507 + int git_config_bool_or_int(const char *name, const char *value, 1508 + const struct key_value_info *kvi, int *is_bool) 1528 1509 { 1529 1510 int v = git_parse_maybe_bool_text(value); 1530 1511 if (0 <= v) { ··· 1532 1513 return v; 1533 1514 } 1534 1515 *is_bool = 0; 1535 - return git_config_int(name, value); 1516 + return git_config_int(name, value, kvi); 1536 1517 } 1537 1518 1538 1519 int git_config_bool(const char *name, const char *value) ··· 1658 1639 else if (!git_parse_maybe_bool_text(value)) 1659 1640 default_abbrev = the_hash_algo->hexsz; 1660 1641 else { 1661 - int abbrev = git_config_int(var, value); 1642 + int abbrev = git_config_int(var, value, ctx->kvi); 1662 1643 if (abbrev < minimum_abbrev || abbrev > the_hash_algo->hexsz) 1663 1644 return error(_("abbrev length out of range: %d"), abbrev); 1664 1645 default_abbrev = abbrev; ··· 1670 1651 return set_disambiguate_hint_config(var, value); 1671 1652 1672 1653 if (!strcmp(var, "core.loosecompression")) { 1673 - int level = git_config_int(var, value); 1654 + int level = git_config_int(var, value, ctx->kvi); 1674 1655 if (level == -1) 1675 1656 level = Z_DEFAULT_COMPRESSION; 1676 1657 else if (level < 0 || level > Z_BEST_COMPRESSION) ··· 1681 1662 } 1682 1663 1683 1664 if (!strcmp(var, "core.compression")) { 1684 - int level = git_config_int(var, value); 1665 + int level = git_config_int(var, value, ctx->kvi); 1685 1666 if (level == -1) 1686 1667 level = Z_DEFAULT_COMPRESSION; 1687 1668 else if (level < 0 || level > Z_BEST_COMPRESSION) ··· 1695 1676 1696 1677 if (!strcmp(var, "core.packedgitwindowsize")) { 1697 1678 int pgsz_x2 = getpagesize() * 2; 1698 - packed_git_window_size = git_config_ulong(var, value); 1679 + packed_git_window_size = git_config_ulong(var, value, ctx->kvi); 1699 1680 1700 1681 /* This value must be multiple of (pagesize * 2) */ 1701 1682 packed_git_window_size /= pgsz_x2; ··· 1706 1687 } 1707 1688 1708 1689 if (!strcmp(var, "core.bigfilethreshold")) { 1709 - big_file_threshold = git_config_ulong(var, value); 1690 + big_file_threshold = git_config_ulong(var, value, ctx->kvi); 1710 1691 return 0; 1711 1692 } 1712 1693 1713 1694 if (!strcmp(var, "core.packedgitlimit")) { 1714 - packed_git_limit = git_config_ulong(var, value); 1695 + packed_git_limit = git_config_ulong(var, value, ctx->kvi); 1715 1696 return 0; 1716 1697 } 1717 1698 1718 1699 if (!strcmp(var, "core.deltabasecachelimit")) { 1719 - delta_base_cache_limit = git_config_ulong(var, value); 1700 + delta_base_cache_limit = git_config_ulong(var, value, ctx->kvi); 1720 1701 return 0; 1721 1702 } 1722 1703 ··· 1995 1976 } 1996 1977 1997 1978 if (!strcmp(var, "pack.packsizelimit")) { 1998 - pack_size_limit_cfg = git_config_ulong(var, value); 1979 + pack_size_limit_cfg = git_config_ulong(var, value, ctx->kvi); 1999 1980 return 0; 2000 1981 } 2001 1982 2002 1983 if (!strcmp(var, "pack.compression")) { 2003 - int level = git_config_int(var, value); 1984 + int level = git_config_int(var, value, ctx->kvi); 2004 1985 if (level == -1) 2005 1986 level = Z_DEFAULT_COMPRESSION; 2006 1987 else if (level < 0 || level > Z_BEST_COMPRESSION) ··· 2344 2325 value_index = list->items[i].value_index; 2345 2326 values = &entry->value_list; 2346 2327 2347 - config_reader_set_kvi(reader, values->items[value_index].util); 2348 2328 ctx.kvi = values->items[value_index].util; 2349 2329 if (fn(entry->key, values->items[value_index].string, &ctx, data) < 0) 2350 2330 git_die_config_linenr(entry->key, 2351 2331 ctx.kvi->filename, 2352 2332 ctx.kvi->linenr); 2353 - config_reader_set_kvi(reader, NULL); 2354 2333 } 2355 2334 } 2356 2335 ··· 2536 2515 return git_config_from_file(config_set_callback, filename, &data); 2537 2516 } 2538 2517 2539 - int git_configset_get_value(struct config_set *set, const char *key, const char **value) 2518 + int git_configset_get_value(struct config_set *set, const char *key, 2519 + const char **value, struct key_value_info *kvi) 2540 2520 { 2541 2521 const struct string_list *values = NULL; 2542 2522 int ret; 2543 - 2523 + struct string_list_item item; 2544 2524 /* 2545 2525 * Follows "last one wins" semantic, i.e., if there are multiple matches for the 2546 2526 * queried key in the files of the configset, the value returned will be the last ··· 2550 2530 return ret; 2551 2531 2552 2532 assert(values->nr > 0); 2553 - *value = values->items[values->nr - 1].string; 2533 + item = values->items[values->nr - 1]; 2534 + *value = item.string; 2535 + if (kvi) 2536 + *kvi = *((struct key_value_info *)item.util); 2554 2537 return 0; 2555 2538 } 2556 2539 ··· 2603 2586 int git_configset_get_string(struct config_set *set, const char *key, char **dest) 2604 2587 { 2605 2588 const char *value; 2606 - if (!git_configset_get_value(set, key, &value)) 2589 + if (!git_configset_get_value(set, key, &value, NULL)) 2607 2590 return git_config_string((const char **)dest, key, value); 2608 2591 else 2609 2592 return 1; ··· 2613 2596 const char **dest) 2614 2597 { 2615 2598 const char *value; 2616 - if (!git_configset_get_value(set, key, &value)) { 2599 + if (!git_configset_get_value(set, key, &value, NULL)) { 2617 2600 if (!value) 2618 2601 return config_error_nonbool(key); 2619 2602 *dest = value; ··· 2626 2609 int git_configset_get_int(struct config_set *set, const char *key, int *dest) 2627 2610 { 2628 2611 const char *value; 2629 - if (!git_configset_get_value(set, key, &value)) { 2630 - *dest = git_config_int(key, value); 2612 + struct key_value_info kvi; 2613 + 2614 + if (!git_configset_get_value(set, key, &value, &kvi)) { 2615 + *dest = git_config_int(key, value, &kvi); 2631 2616 return 0; 2632 2617 } else 2633 2618 return 1; ··· 2636 2621 int git_configset_get_ulong(struct config_set *set, const char *key, unsigned long *dest) 2637 2622 { 2638 2623 const char *value; 2639 - if (!git_configset_get_value(set, key, &value)) { 2640 - *dest = git_config_ulong(key, value); 2624 + struct key_value_info kvi; 2625 + 2626 + if (!git_configset_get_value(set, key, &value, &kvi)) { 2627 + *dest = git_config_ulong(key, value, &kvi); 2641 2628 return 0; 2642 2629 } else 2643 2630 return 1; ··· 2646 2633 int git_configset_get_bool(struct config_set *set, const char *key, int *dest) 2647 2634 { 2648 2635 const char *value; 2649 - if (!git_configset_get_value(set, key, &value)) { 2636 + if (!git_configset_get_value(set, key, &value, NULL)) { 2650 2637 *dest = git_config_bool(key, value); 2651 2638 return 0; 2652 2639 } else ··· 2657 2644 int *is_bool, int *dest) 2658 2645 { 2659 2646 const char *value; 2660 - if (!git_configset_get_value(set, key, &value)) { 2661 - *dest = git_config_bool_or_int(key, value, is_bool); 2647 + struct key_value_info kvi; 2648 + 2649 + if (!git_configset_get_value(set, key, &value, &kvi)) { 2650 + *dest = git_config_bool_or_int(key, value, &kvi, is_bool); 2662 2651 return 0; 2663 2652 } else 2664 2653 return 1; ··· 2667 2656 int git_configset_get_maybe_bool(struct config_set *set, const char *key, int *dest) 2668 2657 { 2669 2658 const char *value; 2670 - if (!git_configset_get_value(set, key, &value)) { 2659 + if (!git_configset_get_value(set, key, &value, NULL)) { 2671 2660 *dest = git_parse_maybe_bool(value); 2672 2661 if (*dest == -1) 2673 2662 return -1; ··· 2679 2668 int git_configset_get_pathname(struct config_set *set, const char *key, const char **dest) 2680 2669 { 2681 2670 const char *value; 2682 - if (!git_configset_get_value(set, key, &value)) 2671 + if (!git_configset_get_value(set, key, &value, NULL)) 2683 2672 return git_config_pathname(dest, key, value); 2684 2673 else 2685 2674 return 1; ··· 2749 2738 const char *key, const char **value) 2750 2739 { 2751 2740 git_config_check_init(repo); 2752 - return git_configset_get_value(repo->config, key, value); 2741 + return git_configset_get_value(repo->config, key, value, NULL); 2753 2742 } 2754 2743 2755 2744 int repo_config_get_value_multi(struct repository *repo, const char *key, ··· 3989 3978 return 0; 3990 3979 } 3991 3980 3992 - static int reader_origin_type(struct config_reader *reader, 3993 - enum config_origin_type *type) 3994 - { 3995 - if (the_reader.config_kvi) 3996 - *type = reader->config_kvi->origin_type; 3997 - else if(the_reader.source) 3998 - *type = reader->source->origin_type; 3999 - else 4000 - return 1; 4001 - return 0; 4002 - } 4003 - 4004 3981 const char *config_origin_type_name(enum config_origin_type type) 4005 3982 { 4006 3983 switch (type) { ··· 4037 4014 default: 4038 4015 return "unknown"; 4039 4016 } 4040 - } 4041 - 4042 - static int reader_config_name(struct config_reader *reader, const char **out) 4043 - { 4044 - if (the_reader.config_kvi) 4045 - *out = reader->config_kvi->filename; 4046 - else if (the_reader.source) 4047 - *out = reader->source->name; 4048 - else 4049 - return 1; 4050 - return 0; 4051 4017 } 4052 4018 4053 4019 int lookup_config(const char **mapping, int nr_mapping, const char *var)
+11 -6
config.h
··· 249 249 * Parse the string to an integer, including unit factors. Dies on error; 250 250 * otherwise, returns the parsed result. 251 251 */ 252 - int git_config_int(const char *, const char *); 252 + int git_config_int(const char *, const char *, const struct key_value_info *); 253 253 254 - int64_t git_config_int64(const char *, const char *); 254 + int64_t git_config_int64(const char *, const char *, 255 + const struct key_value_info *); 255 256 256 257 /** 257 258 * Identical to `git_config_int`, but for unsigned longs. 258 259 */ 259 - unsigned long git_config_ulong(const char *, const char *); 260 + unsigned long git_config_ulong(const char *, const char *, 261 + const struct key_value_info *); 260 262 261 - ssize_t git_config_ssize_t(const char *, const char *); 263 + ssize_t git_config_ssize_t(const char *, const char *, 264 + const struct key_value_info *); 262 265 263 266 /** 264 267 * Same as `git_config_bool`, except that integers are returned as-is, and 265 268 * an `is_bool` flag is unset. 266 269 */ 267 - int git_config_bool_or_int(const char *, const char *, int *); 270 + int git_config_bool_or_int(const char *, const char *, 271 + const struct key_value_info *, int *); 268 272 269 273 /** 270 274 * Parse a string into a boolean value, respecting keywords like "true" and ··· 529 533 * touching `value`. The caller should not free or modify `value`, as it 530 534 * is owned by the cache. 531 535 */ 532 - int git_configset_get_value(struct config_set *cs, const char *key, const char **dest); 536 + int git_configset_get_value(struct config_set *cs, const char *key, 537 + const char **dest, struct key_value_info *kvi); 533 538 534 539 int git_configset_get_string(struct config_set *cs, const char *key, char **dest); 535 540 int git_configset_get_int(struct config_set *cs, const char *key, int *dest);
+27
contrib/coccinelle/git_config_number.cocci
··· 1 + @@ 2 + identifier C1, C2, C3; 3 + @@ 4 + ( 5 + ( 6 + git_config_int 7 + | 8 + git_config_int64 9 + | 10 + git_config_ulong 11 + | 12 + git_config_ssize_t 13 + ) 14 + (C1, C2 15 + + , ctx->kvi 16 + ) 17 + | 18 + ( 19 + git_configset_get_value 20 + | 21 + git_config_bool_or_int 22 + ) 23 + (C1, C2 24 + + , ctx->kvi 25 + , C3 26 + ) 27 + )
+5 -4
diff.c
··· 379 379 return 0; 380 380 } 381 381 if (!strcmp(var, "diff.context")) { 382 - diff_context_default = git_config_int(var, value); 382 + diff_context_default = git_config_int(var, value, ctx->kvi); 383 383 if (diff_context_default < 0) 384 384 return -1; 385 385 return 0; 386 386 } 387 387 if (!strcmp(var, "diff.interhunkcontext")) { 388 - diff_interhunk_context_default = git_config_int(var, value); 388 + diff_interhunk_context_default = git_config_int(var, value, 389 + ctx->kvi); 389 390 if (diff_interhunk_context_default < 0) 390 391 return -1; 391 392 return 0; ··· 411 412 return 0; 412 413 } 413 414 if (!strcmp(var, "diff.statgraphwidth")) { 414 - diff_stat_graph_width = git_config_int(var, value); 415 + diff_stat_graph_width = git_config_int(var, value, ctx->kvi); 415 416 return 0; 416 417 } 417 418 if (!strcmp(var, "diff.external")) ··· 450 451 const char *name; 451 452 452 453 if (!strcmp(var, "diff.renamelimit")) { 453 - diff_rename_limit_default = git_config_int(var, value); 454 + diff_rename_limit_default = git_config_int(var, value, ctx->kvi); 454 455 return 0; 455 456 } 456 457
+1 -1
fmt-merge-msg.c
··· 25 25 { 26 26 if (!strcmp(key, "merge.log") || !strcmp(key, "merge.summary")) { 27 27 int is_bool; 28 - merge_log_config = git_config_bool_or_int(key, value, &is_bool); 28 + merge_log_config = git_config_bool_or_int(key, value, ctx->kvi, &is_bool); 29 29 if (!is_bool && merge_log_config < 0) 30 30 return error("%s: negative length %s", key, value); 31 31 if (is_bool && merge_log_config)
+2 -2
help.c
··· 545 545 #define AUTOCORRECT_IMMEDIATELY (-1) 546 546 547 547 static int git_unknown_cmd_config(const char *var, const char *value, 548 - const struct config_context *ctx UNUSED, 548 + const struct config_context *ctx, 549 549 void *cb UNUSED) 550 550 { 551 551 const char *p; ··· 560 560 } else if (!strcmp(value, "prompt")) { 561 561 autocorrect = AUTOCORRECT_PROMPT; 562 562 } else { 563 - int v = git_config_int(var, value); 563 + int v = git_config_int(var, value, ctx->kvi); 564 564 autocorrect = (v < 0) 565 565 ? AUTOCORRECT_IMMEDIATELY : v; 566 566 }
+5 -5
http.c
··· 414 414 } 415 415 416 416 if (!strcmp("http.minsessions", var)) { 417 - min_curl_sessions = git_config_int(var, value); 417 + min_curl_sessions = git_config_int(var, value, ctx->kvi); 418 418 if (min_curl_sessions > 1) 419 419 min_curl_sessions = 1; 420 420 return 0; 421 421 } 422 422 if (!strcmp("http.maxrequests", var)) { 423 - max_requests = git_config_int(var, value); 423 + max_requests = git_config_int(var, value, ctx->kvi); 424 424 return 0; 425 425 } 426 426 if (!strcmp("http.lowspeedlimit", var)) { 427 - curl_low_speed_limit = (long)git_config_int(var, value); 427 + curl_low_speed_limit = (long)git_config_int(var, value, ctx->kvi); 428 428 return 0; 429 429 } 430 430 if (!strcmp("http.lowspeedtime", var)) { 431 - curl_low_speed_time = (long)git_config_int(var, value); 431 + curl_low_speed_time = (long)git_config_int(var, value, ctx->kvi); 432 432 return 0; 433 433 } 434 434 ··· 464 464 } 465 465 466 466 if (!strcmp("http.postbuffer", var)) { 467 - http_post_buffer = git_config_ssize_t(var, value); 467 + http_post_buffer = git_config_ssize_t(var, value, ctx->kvi); 468 468 if (http_post_buffer < 0) 469 469 warning(_("negative value for http.postBuffer; defaulting to %d"), LARGE_PACKET_MAX); 470 470 if (http_post_buffer < LARGE_PACKET_MAX)
+1 -1
imap-send.c
··· 1342 1342 else if (!strcmp("imap.authmethod", var)) 1343 1343 return git_config_string(&server.auth_method, var, val); 1344 1344 else if (!strcmp("imap.port", var)) 1345 - server.port = git_config_int(var, val); 1345 + server.port = git_config_int(var, val, ctx->kvi); 1346 1346 else if (!strcmp("imap.host", var)) { 1347 1347 if (!val) { 1348 1348 git_die_config("imap.host", "Missing value for 'imap.host'");
+11 -11
sequencer.c
··· 2883 2883 } 2884 2884 2885 2885 static int populate_opts_cb(const char *key, const char *value, 2886 - const struct config_context *ctx UNUSED, 2886 + const struct config_context *ctx, 2887 2887 void *data) 2888 2888 { 2889 2889 struct replay_opts *opts = data; ··· 2892 2892 if (!value) 2893 2893 error_flag = 0; 2894 2894 else if (!strcmp(key, "options.no-commit")) 2895 - opts->no_commit = git_config_bool_or_int(key, value, &error_flag); 2895 + opts->no_commit = git_config_bool_or_int(key, value, ctx->kvi, &error_flag); 2896 2896 else if (!strcmp(key, "options.edit")) 2897 - opts->edit = git_config_bool_or_int(key, value, &error_flag); 2897 + opts->edit = git_config_bool_or_int(key, value, ctx->kvi, &error_flag); 2898 2898 else if (!strcmp(key, "options.allow-empty")) 2899 2899 opts->allow_empty = 2900 - git_config_bool_or_int(key, value, &error_flag); 2900 + git_config_bool_or_int(key, value, ctx->kvi, &error_flag); 2901 2901 else if (!strcmp(key, "options.allow-empty-message")) 2902 2902 opts->allow_empty_message = 2903 - git_config_bool_or_int(key, value, &error_flag); 2903 + git_config_bool_or_int(key, value, ctx->kvi, &error_flag); 2904 2904 else if (!strcmp(key, "options.keep-redundant-commits")) 2905 2905 opts->keep_redundant_commits = 2906 - git_config_bool_or_int(key, value, &error_flag); 2906 + git_config_bool_or_int(key, value, ctx->kvi, &error_flag); 2907 2907 else if (!strcmp(key, "options.signoff")) 2908 - opts->signoff = git_config_bool_or_int(key, value, &error_flag); 2908 + opts->signoff = git_config_bool_or_int(key, value, ctx->kvi, &error_flag); 2909 2909 else if (!strcmp(key, "options.record-origin")) 2910 - opts->record_origin = git_config_bool_or_int(key, value, &error_flag); 2910 + opts->record_origin = git_config_bool_or_int(key, value, ctx->kvi, &error_flag); 2911 2911 else if (!strcmp(key, "options.allow-ff")) 2912 - opts->allow_ff = git_config_bool_or_int(key, value, &error_flag); 2912 + opts->allow_ff = git_config_bool_or_int(key, value, ctx->kvi, &error_flag); 2913 2913 else if (!strcmp(key, "options.mainline")) 2914 - opts->mainline = git_config_int(key, value); 2914 + opts->mainline = git_config_int(key, value, ctx->kvi); 2915 2915 else if (!strcmp(key, "options.strategy")) 2916 2916 git_config_string_dup(&opts->strategy, key, value); 2917 2917 else if (!strcmp(key, "options.gpg-sign")) ··· 2920 2920 strvec_push(&opts->xopts, value); 2921 2921 } else if (!strcmp(key, "options.allow-rerere-auto")) 2922 2922 opts->allow_rerere_auto = 2923 - git_config_bool_or_int(key, value, &error_flag) ? 2923 + git_config_bool_or_int(key, value, ctx->kvi, &error_flag) ? 2924 2924 RERERE_AUTOUPDATE : RERERE_NOAUTOUPDATE; 2925 2925 else if (!strcmp(key, "options.default-msg-cleanup")) { 2926 2926 opts->explicit_cleanup = 1;
+1 -1
setup.c
··· 597 597 const char *ext; 598 598 599 599 if (strcmp(var, "core.repositoryformatversion") == 0) 600 - data->version = git_config_int(var, value); 600 + data->version = git_config_int(var, value, ctx->kvi); 601 601 else if (skip_prefix(var, "extensions.", &ext)) { 602 602 switch (handle_extension_v0(var, value, ext, data)) { 603 603 case EXTENSION_ERROR:
+7 -6
submodule-config.c
··· 304 304 } 305 305 } 306 306 307 - int parse_submodule_fetchjobs(const char *var, const char *value) 307 + int parse_submodule_fetchjobs(const char *var, const char *value, 308 + const struct key_value_info *kvi) 308 309 { 309 - int fetchjobs = git_config_int(var, value); 310 + int fetchjobs = git_config_int(var, value, kvi); 310 311 if (fetchjobs < 0) 311 312 die(_("negative values not allowed for submodule.fetchJobs")); 312 313 if (!fetchjobs) ··· 849 850 }; 850 851 851 852 static int gitmodules_fetch_config(const char *var, const char *value, 852 - const struct config_context *ctx UNUSED, 853 + const struct config_context *ctx, 853 854 void *cb) 854 855 { 855 856 struct fetch_config *config = cb; 856 857 if (!strcmp(var, "submodule.fetchjobs")) { 857 858 if (config->max_children) 858 859 *(config->max_children) = 859 - parse_submodule_fetchjobs(var, value); 860 + parse_submodule_fetchjobs(var, value, ctx->kvi); 860 861 return 0; 861 862 } else if (!strcmp(var, "fetch.recursesubmodules")) { 862 863 if (config->recurse_submodules) ··· 878 879 } 879 880 880 881 static int gitmodules_update_clone_config(const char *var, const char *value, 881 - const struct config_context *ctx UNUSED, 882 + const struct config_context *ctx, 882 883 void *cb) 883 884 { 884 885 int *max_jobs = cb; 885 886 if (!strcmp(var, "submodule.fetchjobs")) 886 - *max_jobs = parse_submodule_fetchjobs(var, value); 887 + *max_jobs = parse_submodule_fetchjobs(var, value, ctx->kvi); 887 888 return 0; 888 889 } 889 890
+2 -1
submodule-config.h
··· 50 50 51 51 void submodule_cache_free(struct submodule_cache *cache); 52 52 53 - int parse_submodule_fetchjobs(const char *var, const char *value); 53 + int parse_submodule_fetchjobs(const char *var, const char *value, 54 + const struct key_value_info *kvi); 54 55 int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg); 55 56 struct option; 56 57 int option_fetch_parse_recurse_submodules(const struct option *opt,
+3 -3
t/helper/test-config.c
··· 63 63 } 64 64 65 65 static int parse_int_cb(const char *var, const char *value, 66 - const struct config_context *ctx UNUSED, void *data) 66 + const struct config_context *ctx, void *data) 67 67 { 68 68 const char *key_to_match = data; 69 69 70 70 if (!strcmp(key_to_match, var)) { 71 - int parsed = git_config_int(value, value); 71 + int parsed = git_config_int(value, value, ctx->kvi); 72 72 printf("%d\n", parsed); 73 73 } 74 74 return 0; ··· 182 182 goto exit2; 183 183 } 184 184 } 185 - if (!git_configset_get_value(&cs, argv[2], &v)) { 185 + if (!git_configset_get_value(&cs, argv[2], &v, NULL)) { 186 186 if (!v) 187 187 printf("(NULL)\n"); 188 188 else
+7 -5
upload-pack.c
··· 1275 1275 } 1276 1276 1277 1277 static int parse_object_filter_config(const char *var, const char *value, 1278 - struct upload_pack_data *data) 1278 + const struct key_value_info *kvi, 1279 + struct upload_pack_data *data) 1279 1280 { 1280 1281 struct strbuf buf = STRBUF_INIT; 1281 1282 const char *sub, *key; ··· 1302 1303 } 1303 1304 string_list_insert(&data->allowed_filters, buf.buf)->util = 1304 1305 (void *)(intptr_t)1; 1305 - data->tree_filter_max_depth = git_config_ulong(var, value); 1306 + data->tree_filter_max_depth = git_config_ulong(var, value, 1307 + kvi); 1306 1308 } 1307 1309 1308 1310 strbuf_release(&buf); ··· 1310 1312 } 1311 1313 1312 1314 static int upload_pack_config(const char *var, const char *value, 1313 - const struct config_context *ctx UNUSED, 1315 + const struct config_context *ctx, 1314 1316 void *cb_data) 1315 1317 { 1316 1318 struct upload_pack_data *data = cb_data; ··· 1331 1333 else 1332 1334 data->allow_uor &= ~ALLOW_ANY_SHA1; 1333 1335 } else if (!strcmp("uploadpack.keepalive", var)) { 1334 - data->keepalive = git_config_int(var, value); 1336 + data->keepalive = git_config_int(var, value, ctx->kvi); 1335 1337 if (!data->keepalive) 1336 1338 data->keepalive = -1; 1337 1339 } else if (!strcmp("uploadpack.allowfilter", var)) { ··· 1346 1348 data->advertise_sid = git_config_bool(var, value); 1347 1349 } 1348 1350 1349 - if (parse_object_filter_config(var, value, data) < 0) 1351 + if (parse_object_filter_config(var, value, ctx->kvi, data) < 0) 1350 1352 return -1; 1351 1353 1352 1354 return parse_hide_refs_config(var, value, "uploadpack", &data->hidden_refs);
+1 -1
worktree.c
··· 835 835 * Relocate that value to avoid breaking all worktrees with this 836 836 * upgrade to worktree config. 837 837 */ 838 - if (!git_configset_get_value(&cs, "core.worktree", &core_worktree)) { 838 + if (!git_configset_get_value(&cs, "core.worktree", &core_worktree, NULL)) { 839 839 if ((res = move_config_setting("core.worktree", core_worktree, 840 840 common_config_file, 841 841 main_worktree_file)))