test/send-email: --[no-]xmailer tests
[gitweb.git] / config.c
index a1aef1cf3eca01e328b3e319636269236ea91ae0..9e42d3832bbcce428705ef616d5b2008c47ec91a 100644 (file)
--- a/config.c
+++ b/config.c
@@ -138,8 +138,7 @@ int git_config_include(const char *var, const char *value, void *data)
        if (ret < 0)
                return ret;
 
-       type = skip_prefix(var, "include.");
-       if (!type)
+       if (!skip_prefix(var, "include.", &type))
                return ret;
 
        if (!strcmp(type, "path"))
@@ -163,19 +162,27 @@ void git_config_push_parameter(const char *text)
 int git_config_parse_parameter(const char *text,
                               config_fn_t fn, void *data)
 {
+       const char *value;
        struct strbuf **pair;
+
        pair = strbuf_split_str(text, '=', 2);
        if (!pair[0])
                return error("bogus config parameter: %s", text);
-       if (pair[0]->len && pair[0]->buf[pair[0]->len - 1] == '=')
+
+       if (pair[0]->len && pair[0]->buf[pair[0]->len - 1] == '=') {
                strbuf_setlen(pair[0], pair[0]->len - 1);
+               value = pair[1] ? pair[1]->buf : "";
+       } else {
+               value = NULL;
+       }
+
        strbuf_trim(pair[0]);
        if (!pair[0]->len) {
                strbuf_list_free(pair);
                return error("bogus config parameter: %s", text);
        }
        strbuf_tolower(pair[0]);
-       if (fn(pair[0]->buf, pair[1] ? pair[1]->buf : NULL, data) < 0) {
+       if (fn(pair[0]->buf, value, data) < 0) {
                strbuf_list_free(pair);
                return -1;
        }
@@ -818,14 +825,12 @@ static int git_default_core_config(const char *var, const char *value)
                return git_config_string(&editor_program, var, value);
 
        if (!strcmp(var, "core.commentchar")) {
-               const char *comment;
-               int ret = git_config_string(&comment, var, value);
-               if (ret)
-                       return ret;
-               else if (!strcasecmp(comment, "auto"))
+               if (!value)
+                       return config_error_nonbool(var);
+               else if (!strcasecmp(value, "auto"))
                        auto_comment_line_char = 1;
-               else if (comment[0] && !comment[1]) {
-                       comment_line_char = comment[0];
+               else if (value[0] && !value[1]) {
+                       comment_line_char = value[0];
                        auto_comment_line_char = 0;
                } else
                        return error("core.commentChar should only be one character");
@@ -1231,10 +1236,15 @@ static struct {
 
 static int matches(const char *key, const char *value)
 {
-       return !strcmp(key, store.key) &&
-               (store.value_regex == NULL ||
-                (store.do_not_match ^
-                 !regexec(store.value_regex, value, 0, NULL, 0)));
+       if (strcmp(key, store.key))
+               return 0; /* not ours */
+       if (!store.value_regex)
+               return 1; /* always matches */
+       if (store.value_regex == CONFIG_REGEX_NONE)
+               return 0; /* never matches */
+
+       return store.do_not_match ^
+               (value && !regexec(store.value_regex, value, 0, NULL, 0));
 }
 
 static int store_aux(const char *key, const char *value, void *cb)
@@ -1496,6 +1506,8 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
 /*
  * 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
+ *     (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.
@@ -1579,6 +1591,8 @@ int git_config_set_multivar_in_file(const char *config_filename,
 
                if (value_regex == NULL)
                        store.value_regex = NULL;
+               else if (value_regex == CONFIG_REGEX_NONE)
+                       store.value_regex = CONFIG_REGEX_NONE;
                else {
                        if (value_regex[0] == '!') {
                                store.do_not_match = 1;
@@ -1610,7 +1624,8 @@ int git_config_set_multivar_in_file(const char *config_filename,
                if (git_config_from_file(store_aux, config_filename, NULL)) {
                        error("invalid config file %s", config_filename);
                        free(store.key);
-                       if (store.value_regex != NULL) {
+                       if (store.value_regex != NULL &&
+                           store.value_regex != CONFIG_REGEX_NONE) {
                                regfree(store.value_regex);
                                free(store.value_regex);
                        }
@@ -1619,7 +1634,8 @@ int git_config_set_multivar_in_file(const char *config_filename,
                }
 
                free(store.key);
-               if (store.value_regex != NULL) {
+               if (store.value_regex != NULL &&
+                   store.value_regex != CONFIG_REGEX_NONE) {
                        regfree(store.value_regex);
                        free(store.value_regex);
                }
@@ -1637,8 +1653,8 @@ int git_config_set_multivar_in_file(const char *config_filename,
                        MAP_PRIVATE, in_fd, 0);
                close(in_fd);
 
-               if (fchmod(fd, st.st_mode & 07777) < 0) {
-                       error("fchmod on %s failed: %s",
+               if (chmod(lock->filename, st.st_mode & 07777) < 0) {
+                       error("chmod on %s failed: %s",
                                lock->filename, strerror(errno));
                        ret = CONFIG_NO_WRITE;
                        goto out_free;
@@ -1816,8 +1832,8 @@ int git_config_rename_section_in_file(const char *config_filename,
 
        fstat(fileno(config_file), &st);
 
-       if (fchmod(out_fd, st.st_mode & 07777) < 0) {
-               ret = error("fchmod on %s failed: %s",
+       if (chmod(lock->filename, st.st_mode & 07777) < 0) {
+               ret = error("chmod on %s failed: %s",
                                lock->filename, strerror(errno));
                goto out;
        }