config: let `config_store_data_clear()` handle `key`
[gitweb.git] / config.c
index 40d46b3325ed7787c8645f150e73a1f5f05cc5e3..339a92235deace1a67a53b332294e1993e535592 100644 (file)
--- a/config.c
+++ b/config.c
@@ -16,6 +16,7 @@
 #include "string-list.h"
 #include "utf8.h"
 #include "dir.h"
+#include "color.h"
 
 struct config_source {
        struct config_source *prev;
@@ -1067,6 +1068,15 @@ int git_config_expiry_date(timestamp_t *timestamp, const char *var, const char *
        return 0;
 }
 
+int git_config_color(char *dest, const char *var, const char *value)
+{
+       if (!value)
+               return config_error_nonbool(var);
+       if (color_parse(value, dest) < 0)
+               return -1;
+       return 0;
+}
+
 static int git_default_core_config(const char *var, const char *value)
 {
        /* This needs a better name */
@@ -1239,6 +1249,11 @@ static int git_default_core_config(const char *var, const char *value)
                return 0;
        }
 
+       if (!strcmp(var, "core.checkroundtripencoding")) {
+               check_roundtrip_encoding = xstrdup(value);
+               return 0;
+       }
+
        if (!strcmp(var, "core.notesref")) {
                notes_ref_name = xstrdup(value);
                return 0;
@@ -1437,7 +1452,7 @@ int git_default_config(const char *var, const char *value, void *dummy)
        if (starts_with(var, "mailmap."))
                return git_default_mailmap_config(var, value);
 
-       if (starts_with(var, "advice."))
+       if (starts_with(var, "advice.") || starts_with(var, "color.advice"))
                return git_default_advice_config(var, value);
 
        if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) {
@@ -2318,6 +2333,19 @@ struct config_store_data {
        unsigned int key_seen:1, section_seen:1, is_keys_section:1;
 };
 
+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);
+       }
+       free(store->parsed);
+       free(store->seen);
+       memset(store, 0, sizeof(*store));
+}
+
 static int matches(const char *key, const char *value,
                   const struct config_store_data *store)
 {
@@ -2652,7 +2680,6 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
        fd = hold_lock_file_for_update(&lock, config_filename, 0);
        if (fd < 0) {
                error_errno("could not lock config file %s", config_filename);
-               free(store.key);
                ret = CONFIG_NO_LOCK;
                goto out_free;
        }
@@ -2662,8 +2689,6 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
         */
        in_fd = open(config_filename, O_RDONLY);
        if ( in_fd < 0 ) {
-               free(store.key);
-
                if ( ENOENT != errno ) {
                        error_errno("opening %s", config_filename);
                        ret = CONFIG_INVALID_FILE; /* same as "invalid config file" */
@@ -2675,7 +2700,8 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
                        goto out_free;
                }
 
-               store.key = (char *)key;
+               free(store.key);
+               store.key = xstrdup(key);
                if (write_section(fd, key, &store) < 0 ||
                    write_pair(fd, key, value, &store) < 0)
                        goto write_err_out;
@@ -2700,7 +2726,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
                        if (regcomp(store.value_regex, value_regex,
                                        REG_EXTENDED)) {
                                error("invalid pattern: %s", value_regex);
-                               free(store.value_regex);
+                               FREE_AND_NULL(store.value_regex);
                                ret = CONFIG_INVALID_PATTERN;
                                goto out_free;
                        }
@@ -2725,23 +2751,10 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
                                                      config_filename,
                                                      &store, &opts)) {
                        error("invalid config file %s", config_filename);
-                       free(store.key);
-                       if (store.value_regex != NULL &&
-                           store.value_regex != CONFIG_REGEX_NONE) {
-                               regfree(store.value_regex);
-                               free(store.value_regex);
-                       }
                        ret = CONFIG_INVALID_FILE;
                        goto out_free;
                }
 
-               free(store.key);
-               if (store.value_regex != NULL &&
-                   store.value_regex != CONFIG_REGEX_NONE) {
-                       regfree(store.value_regex);
-                       free(store.value_regex);
-               }
-
                /* if nothing to unset, or too many matches, error out */
                if ((store.seen_nr == 0 && value == NULL) ||
                    (store.seen_nr > 1 && multi_replace == 0)) {
@@ -2872,6 +2885,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
                munmap(contents, contents_sz);
        if (in_fd >= 0)
                close(in_fd);
+       config_store_data_clear(&store);
        return ret;
 
 write_err_out:
@@ -3112,6 +3126,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
        rollback_lock_file(&lock);
 out_no_rollback:
        free(filename_buf);
+       config_store_data_clear(&store);
        return ret;
 }