Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2023-04-06 23:38:28 +0300
committerJunio C Hamano <gitster@pobox.com>2023-04-06 23:38:29 +0300
commit87daf40750c9e344dd50495fdca1809aebcb1a94 (patch)
tree3f08482461e3484d5e77c7575c3fa35af28a33a4 /config.c
parente9dffbc7f11704bd25e5a36e41e5fe5c5d1f7183 (diff)
parent3611f7467fddcff6063ed2c99484047b410969fc (diff)
Merge branch 'ab/config-multi-and-nonbool'
Assorted config API updates. * ab/config-multi-and-nonbool: for-each-repo: with bad config, don't conflate <path> and <cmd> config API: add "string" version of *_value_multi(), fix segfaults config API users: test for *_get_value_multi() segfaults for-each-repo: error on bad --config config API: have *_multi() return an "int" and take a "dest" versioncmp.c: refactor config reading next commit config API: add and use a "git_config_get()" family of functions config tests: add "NULL" tests for *_get_value_multi() config tests: cover blind spots in git_die_config() tests
Diffstat (limited to 'config.c')
-rw-r--r--config.c109
1 files changed, 92 insertions, 17 deletions
diff --git a/config.c b/config.c
index 0b2679994e..a30490fd58 100644
--- a/config.c
+++ b/config.c
@@ -2292,23 +2292,29 @@ void read_very_early_config(config_fn_t cb, void *data)
config_with_options(cb, data, NULL, &opts);
}
-static struct config_set_element *configset_find_element(struct config_set *cs, const char *key)
+RESULT_MUST_BE_USED
+static int configset_find_element(struct config_set *cs, const char *key,
+ struct config_set_element **dest)
{
struct config_set_element k;
struct config_set_element *found_entry;
char *normalized_key;
+ int ret;
+
/*
* `key` may come from the user, so normalize it before using it
* for querying entries from the hashmap.
*/
- if (git_config_parse_key(key, &normalized_key, NULL))
- return NULL;
+ ret = git_config_parse_key(key, &normalized_key, NULL);
+ if (ret)
+ return ret;
hashmap_entry_init(&k.ent, strhash(normalized_key));
k.key = normalized_key;
found_entry = hashmap_get_entry(&cs->config_hash, &k, ent, NULL);
free(normalized_key);
- return found_entry;
+ *dest = found_entry;
+ return 0;
}
static int configset_add_value(struct config_set *cs, const char *key, const char *value)
@@ -2317,8 +2323,11 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
struct string_list_item *si;
struct configset_list_item *l_item;
struct key_value_info *kv_info = xmalloc(sizeof(*kv_info));
+ int ret;
- e = configset_find_element(cs, key);
+ ret = configset_find_element(cs, key, &e);
+ if (ret)
+ return ret;
/*
* Since the keys are being fed by git_config*() callback mechanism, they
* are already normalized. So simply add them without any further munging.
@@ -2412,24 +2421,65 @@ int git_configset_add_file(struct config_set *cs, const char *filename)
int git_configset_get_value(struct config_set *cs, const char *key, const char **value)
{
const struct string_list *values = NULL;
+ int ret;
+
/*
* Follows "last one wins" semantic, i.e., if there are multiple matches for the
* queried key in the files of the configset, the value returned will be the last
* value in the value list for that key.
*/
- values = git_configset_get_value_multi(cs, key);
+ if ((ret = git_configset_get_value_multi(cs, key, &values)))
+ return ret;
- if (!values)
- return 1;
assert(values->nr > 0);
*value = values->items[values->nr - 1].string;
return 0;
}
-const struct string_list *git_configset_get_value_multi(struct config_set *cs, const char *key)
+int git_configset_get_value_multi(struct config_set *cs, const char *key,
+ const struct string_list **dest)
+{
+ struct config_set_element *e;
+ int ret;
+
+ if ((ret = configset_find_element(cs, key, &e)))
+ return ret;
+ else if (!e)
+ return 1;
+ *dest = &e->value_list;
+
+ return 0;
+}
+
+static int check_multi_string(struct string_list_item *item, void *util)
+{
+ return item->string ? 0 : config_error_nonbool(util);
+}
+
+int git_configset_get_string_multi(struct config_set *cs, const char *key,
+ const struct string_list **dest)
+{
+ int ret;
+
+ if ((ret = git_configset_get_value_multi(cs, key, dest)))
+ return ret;
+ if ((ret = for_each_string_list((struct string_list *)*dest,
+ check_multi_string, (void *)key)))
+ return ret;
+
+ return 0;
+}
+
+int git_configset_get(struct config_set *cs, const char *key)
{
- struct config_set_element *e = configset_find_element(cs, key);
- return e ? &e->value_list : NULL;
+ struct config_set_element *e;
+ int ret;
+
+ if ((ret = configset_find_element(cs, key, &e)))
+ return ret;
+ else if (!e)
+ return 1;
+ return 0;
}
int git_configset_get_string(struct config_set *cs, const char *key, char **dest)
@@ -2568,6 +2618,12 @@ void repo_config(struct repository *repo, config_fn_t fn, void *data)
configset_iter(repo->config, fn, data);
}
+int repo_config_get(struct repository *repo, const char *key)
+{
+ git_config_check_init(repo);
+ return git_configset_get(repo->config, key);
+}
+
int repo_config_get_value(struct repository *repo,
const char *key, const char **value)
{
@@ -2575,11 +2631,18 @@ int repo_config_get_value(struct repository *repo,
return git_configset_get_value(repo->config, key, value);
}
-const struct string_list *repo_config_get_value_multi(struct repository *repo,
- const char *key)
+int repo_config_get_value_multi(struct repository *repo, const char *key,
+ const struct string_list **dest)
+{
+ git_config_check_init(repo);
+ return git_configset_get_value_multi(repo->config, key, dest);
+}
+
+int repo_config_get_string_multi(struct repository *repo, const char *key,
+ const struct string_list **dest)
{
git_config_check_init(repo);
- return git_configset_get_value_multi(repo->config, key);
+ return git_configset_get_string_multi(repo->config, key, dest);
}
int repo_config_get_string(struct repository *repo,
@@ -2682,14 +2745,25 @@ void git_config_clear(void)
repo_config_clear(the_repository);
}
+int git_config_get(const char *key)
+{
+ return repo_config_get(the_repository, key);
+}
+
int git_config_get_value(const char *key, const char **value)
{
return repo_config_get_value(the_repository, key, value);
}
-const struct string_list *git_config_get_value_multi(const char *key)
+int git_config_get_value_multi(const char *key, const struct string_list **dest)
+{
+ return repo_config_get_value_multi(the_repository, key, dest);
+}
+
+int git_config_get_string_multi(const char *key,
+ const struct string_list **dest)
{
- return repo_config_get_value_multi(the_repository, key);
+ return repo_config_get_string_multi(the_repository, key, dest);
}
int git_config_get_string(const char *key, char **dest)
@@ -2836,7 +2910,8 @@ void git_die_config(const char *key, const char *err, ...)
error_fn(err, params);
va_end(params);
}
- values = git_config_get_value_multi(key);
+ if (git_config_get_value_multi(key, &values))
+ BUG("for key '%s' we must have a value to report on", key);
kv_info = values->items[values->nr - 1].util;
git_die_config_linenr(key, kv_info->filename, kv_info->linenr);
}