free(entry->key);
string_list_clear(&entry->value_list, 1);
}
- hashmap_free_entries(&cs->config_hash, struct config_set_element, ent);
+ hashmap_clear_and_free(&cs->config_hash, struct config_set_element, ent);
cs->hash_initialized = 0;
free(cs->list.items);
cs->list.nr = 0;
return e ? &e->value_list : NULL;
}
-int git_configset_get_string_const(struct config_set *cs, const char *key, const char **dest)
+int git_configset_get_string(struct config_set *cs, const char *key, char **dest)
{
const char *value;
if (!git_configset_get_value(cs, key, &value))
- return git_config_string(dest, key, value);
+ return git_config_string((const char **)dest, key, value);
else
return 1;
}
-int git_configset_get_string(struct config_set *cs, const char *key, char **dest)
+int git_configset_get_string_tmp(struct config_set *cs, const char *key,
+ const char **dest)
{
- return git_configset_get_string_const(cs, key, (const char **)dest);
+ const char *value;
+ if (!git_configset_get_value(cs, key, &value)) {
+ if (!value)
+ return config_error_nonbool(key);
+ *dest = value;
+ return 0;
+ } else {
+ return 1;
+ }
}
int git_configset_get_int(struct config_set *cs, const char *key, int *dest)
return git_configset_get_value_multi(repo->config, key);
}
-int repo_config_get_string_const(struct repository *repo,
- const char *key, const char **dest)
+int repo_config_get_string(struct repository *repo,
+ const char *key, char **dest)
{
int ret;
git_config_check_init(repo);
- ret = git_configset_get_string_const(repo->config, key, dest);
+ ret = git_configset_get_string(repo->config, key, dest);
if (ret < 0)
git_die_config(key, NULL);
return ret;
}
-int repo_config_get_string(struct repository *repo,
- const char *key, char **dest)
+int repo_config_get_string_tmp(struct repository *repo,
+ const char *key, const char **dest)
{
+ int ret;
git_config_check_init(repo);
- return repo_config_get_string_const(repo, key, (const char **)dest);
+ ret = git_configset_get_string_tmp(repo->config, key, dest);
+ if (ret < 0)
+ git_die_config(key, NULL);
+ return ret;
}
int repo_config_get_int(struct repository *repo,
return repo_config_get_value_multi(the_repository, key);
}
-int git_config_get_string_const(const char *key, const char **dest)
+int git_config_get_string(const char *key, char **dest)
{
- return repo_config_get_string_const(the_repository, key, dest);
+ return repo_config_get_string(the_repository, key, dest);
}
-int git_config_get_string(const char *key, char **dest)
+int git_config_get_string_tmp(const char *key, const char **dest)
{
- return repo_config_get_string(the_repository, key, dest);
+ return repo_config_get_string_tmp(the_repository, key, dest);
}
int git_config_get_int(const char *key, int *dest)
int git_config_get_expiry(const char *key, const char **output)
{
- int ret = git_config_get_string_const(key, output);
+ int ret = git_config_get_string(key, (char **)output);
if (ret)
return ret;
if (strcmp(*output, "now")) {
int git_config_get_expiry_in_days(const char *key, timestamp_t *expiry, timestamp_t now)
{
- char *expiry_string;
+ const char *expiry_string;
intmax_t days;
timestamp_t when;
- if (git_config_get_string(key, &expiry_string))
+ if (git_config_get_string_tmp(key, &expiry_string))
return 1; /* no such thing */
if (git_parse_signed(expiry_string, &days, maximum_signed_value_of_type(int))) {
size_t baselen;
char *key;
int do_not_match;
- regex_t *value_regex;
+ const char *fixed_value;
+ regex_t *value_pattern;
int multi_replace;
struct {
size_t begin, end;
static void config_store_data_clear(struct config_store_data *store)
{
free(store->key);
- if (store->value_regex != NULL &&
- store->value_regex != CONFIG_REGEX_NONE) {
- regfree(store->value_regex);
- free(store->value_regex);
+ if (store->value_pattern != NULL &&
+ store->value_pattern != CONFIG_REGEX_NONE) {
+ regfree(store->value_pattern);
+ free(store->value_pattern);
}
free(store->parsed);
free(store->seen);
{
if (strcmp(key, store->key))
return 0; /* not ours */
- if (!store->value_regex)
+ if (store->fixed_value)
+ return !strcmp(store->fixed_value, value);
+ if (!store->value_pattern)
return 1; /* always matches */
- if (store->value_regex == CONFIG_REGEX_NONE)
+ if (store->value_pattern == CONFIG_REGEX_NONE)
return 0; /* never matches */
return store->do_not_match ^
- (value && !regexec(store->value_regex, value, 0, NULL, 0));
+ (value && !regexec(store->value_pattern, value, 0, NULL, 0));
}
static int store_aux_event(enum config_event_t type,
/*
* If value==NULL, unset in (remove from) config,
- * if value_regex!=NULL, disregard key/value pairs where value does not match.
- * if value_regex==CONFIG_REGEX_NONE, do not match any existing values
+ * if value_pattern!=NULL, disregard key/value pairs where value does not match.
+ * if value_pattern==CONFIG_REGEX_NONE, do not match any existing values
* (only add a new one)
- * if multi_replace==0, nothing, or only one matching key/value is replaced,
- * else all matching key/values (regardless how many) are removed,
- * before the new pair is written.
+ * if flags contains the CONFIG_FLAGS_MULTI_REPLACE flag, all matching
+ * key/values are removed before a single new pair is written. If the
+ * flag is not present, then replace only the first match.
*
* Returns 0 on success.
*
*/
int git_config_set_multivar_in_file_gently(const char *config_filename,
const char *key, const char *value,
- const char *value_regex,
- int multi_replace)
+ const char *value_pattern,
+ unsigned flags)
{
int fd = -1, in_fd = -1;
int ret;
if (ret)
goto out_free;
- store.multi_replace = multi_replace;
+ store.multi_replace = (flags & CONFIG_FLAGS_MULTI_REPLACE) != 0;
if (!config_filename)
config_filename = filename_buf = git_pathdup("config");
int i, new_line = 0;
struct config_options opts;
- if (value_regex == NULL)
- store.value_regex = NULL;
- else if (value_regex == CONFIG_REGEX_NONE)
- store.value_regex = CONFIG_REGEX_NONE;
+ if (value_pattern == NULL)
+ store.value_pattern = NULL;
+ else if (value_pattern == CONFIG_REGEX_NONE)
+ store.value_pattern = CONFIG_REGEX_NONE;
+ else if (flags & CONFIG_FLAGS_FIXED_VALUE)
+ store.fixed_value = value_pattern;
else {
- if (value_regex[0] == '!') {
+ if (value_pattern[0] == '!') {
store.do_not_match = 1;
- value_regex++;
+ value_pattern++;
} else
store.do_not_match = 0;
- store.value_regex = (regex_t*)xmalloc(sizeof(regex_t));
- if (regcomp(store.value_regex, value_regex,
+ store.value_pattern = (regex_t*)xmalloc(sizeof(regex_t));
+ if (regcomp(store.value_pattern, value_pattern,
REG_EXTENDED)) {
- error(_("invalid pattern: %s"), value_regex);
- FREE_AND_NULL(store.value_regex);
+ error(_("invalid pattern: %s"), value_pattern);
+ FREE_AND_NULL(store.value_pattern);
ret = CONFIG_INVALID_PATTERN;
goto out_free;
}
/* if nothing to unset, or too many matches, error out */
if ((store.seen_nr == 0 && value == NULL) ||
- (store.seen_nr > 1 && multi_replace == 0)) {
+ (store.seen_nr > 1 && !store.multi_replace)) {
ret = CONFIG_NOTHING_SET;
goto out_free;
}
void git_config_set_multivar_in_file(const char *config_filename,
const char *key, const char *value,
- const char *value_regex, int multi_replace)
+ const char *value_pattern, unsigned flags)
{
if (!git_config_set_multivar_in_file_gently(config_filename, key, value,
- value_regex, multi_replace))
+ value_pattern, flags))
return;
if (value)
die(_("could not set '%s' to '%s'"), key, value);
}
int git_config_set_multivar_gently(const char *key, const char *value,
- const char *value_regex, int multi_replace)
+ const char *value_pattern, unsigned flags)
{
- return git_config_set_multivar_in_file_gently(NULL, key, value, value_regex,
- multi_replace);
+ return git_config_set_multivar_in_file_gently(NULL, key, value, value_pattern,
+ flags);
}
void git_config_set_multivar(const char *key, const char *value,
- const char *value_regex, int multi_replace)
+ const char *value_pattern, unsigned flags)
{
- git_config_set_multivar_in_file(NULL, key, value, value_regex,
- multi_replace);
+ git_config_set_multivar_in_file(NULL, key, value, value_pattern,
+ flags);
}
static int section_name_match (const char *buf, const char *name)
}
while (fgets(buf, sizeof(buf), config_file)) {
- int i;
+ unsigned i;
int length;
int is_section = 0;
char *output = buf;