config: add '--name-only' option to list only variable names
[gitweb.git] / config.c
index 039647d247e0ac1e3a523800bbb90c86d89354de..ab46462e151dd5cd9d1e5a1fecd23fe5c6607c5d 100644 (file)
--- a/config.c
+++ b/config.c
@@ -6,11 +6,13 @@
  *
  */
 #include "cache.h"
+#include "lockfile.h"
 #include "exec_cmd.h"
 #include "strbuf.h"
 #include "quote.h"
 #include "hashmap.h"
 #include "string-list.h"
+#include "utf8.h"
 
 struct config_source {
        struct config_source *prev;
@@ -48,7 +50,7 @@ static struct config_set the_config_set;
 
 static int config_file_fgetc(struct config_source *conf)
 {
-       return fgetc(conf->u.file);
+       return getc_unlocked(conf->u.file);
 }
 
 static int config_file_ungetc(int c, struct config_source *conf)
@@ -72,8 +74,12 @@ static int config_buf_fgetc(struct config_source *conf)
 
 static int config_buf_ungetc(int c, struct config_source *conf)
 {
-       if (conf->u.buf.pos > 0)
-               return conf->u.buf.buf[--conf->u.buf.pos];
+       if (conf->u.buf.pos > 0) {
+               conf->u.buf.pos--;
+               if (conf->u.buf.buf[conf->u.buf.pos] != c)
+                       die("BUG: config_buf can only ungetc the same character");
+               return c;
+       }
 
        return EOF;
 }
@@ -234,7 +240,8 @@ static int get_next_char(void)
                /* DOS like systems */
                c = cf->do_fgetc(cf);
                if (c != '\n') {
-                       cf->do_ungetc(c, cf);
+                       if (c != EOF)
+                               cf->do_ungetc(c, cf);
                        c = '\r';
                }
        }
@@ -411,8 +418,7 @@ static int git_parse_source(config_fn_t fn, void *data)
        struct strbuf *var = &cf->var;
 
        /* U+FEFF Byte Order Mark in UTF8 */
-       static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf";
-       const unsigned char *bomptr = utf8_bom;
+       const char *bomptr = utf8_bom;
 
        for (;;) {
                int c = get_next_char();
@@ -420,7 +426,7 @@ static int git_parse_source(config_fn_t fn, void *data)
                        /* We are at the file beginning; skip UTF8-encoded BOM
                         * if present. Sane editors won't put this in on their
                         * own, but e.g. Windows Notepad will do it happily. */
-                       if ((unsigned char) c == *bomptr) {
+                       if (c == (*bomptr & 0377)) {
                                bomptr++;
                                continue;
                        } else {
@@ -505,9 +511,9 @@ static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
                        errno = EINVAL;
                        return 0;
                }
-               uval = abs(val);
+               uval = labs(val);
                uval *= factor;
-               if (uval > max || abs(val) > uval) {
+               if (uval > max || labs(val) > uval) {
                        errno = ERANGE;
                        return 0;
                }
@@ -895,6 +901,16 @@ static int git_default_core_config(const char *var, const char *value)
                return 0;
        }
 
+       if (!strcmp(var, "core.protecthfs")) {
+               protect_hfs = git_config_bool(var, value);
+               return 0;
+       }
+
+       if (!strcmp(var, "core.protectntfs")) {
+               protect_ntfs = git_config_bool(var, value);
+               return 0;
+       }
+
        /* Add other config variables here and to Documentation/config.txt. */
        return 0;
 }
@@ -1072,7 +1088,9 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
 
        f = fopen(filename, "r");
        if (f) {
+               flockfile(f);
                ret = do_config_from_file(fn, filename, filename, f, data);
+               funlockfile(f);
                fclose(f);
        }
        return ret;
@@ -1169,10 +1187,8 @@ int git_config_system(void)
 int git_config_early(config_fn_t fn, void *data, const char *repo_config)
 {
        int ret = 0, found = 0;
-       char *xdg_config = NULL;
-       char *user_config = NULL;
-
-       home_config_paths(&user_config, &xdg_config, "config");
+       char *xdg_config = xdg_config_home("config");
+       char *user_config = expand_user_path("~/.gitconfig");
 
        if (git_config_system() && !access_or_die(git_etc_gitconfig(), R_OK, 0)) {
                ret += git_config_from_file(fn, git_etc_gitconfig(),
@@ -1329,7 +1345,7 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
                string_list_init(&e->value_list, 1);
                hashmap_add(&cs->config_hash, e);
        }
-       si = string_list_append_nodup(&e->value_list, value ? xstrdup(value) : NULL);
+       si = string_list_append_nodup(&e->value_list, xstrdup_or_null(value));
 
        ALLOC_GROW(cs->list.items, cs->list.nr + 1, cs->list.alloc);
        l_item = &cs->list.items[cs->list.nr++];
@@ -2040,9 +2056,9 @@ int git_config_set_multivar_in_file(const char *config_filename,
                        MAP_PRIVATE, in_fd, 0);
                close(in_fd);
 
-               if (chmod(lock->filename, st.st_mode & 07777) < 0) {
+               if (chmod(lock->filename.buf, st.st_mode & 07777) < 0) {
                        error("chmod on %s failed: %s",
-                               lock->filename, strerror(errno));
+                               lock->filename.buf, strerror(errno));
                        ret = CONFIG_NO_WRITE;
                        goto out_free;
                }
@@ -2099,6 +2115,7 @@ int git_config_set_multivar_in_file(const char *config_filename,
        if (commit_lock_file(lock) < 0) {
                error("could not commit config file %s", config_filename);
                ret = CONFIG_NO_WRITE;
+               lock = NULL;
                goto out_free;
        }
 
@@ -2121,7 +2138,7 @@ int git_config_set_multivar_in_file(const char *config_filename,
        return ret;
 
 write_err_out:
-       ret = write_error(lock->filename);
+       ret = write_error(lock->filename.buf);
        goto out_free;
 
 }
@@ -2222,9 +2239,9 @@ int git_config_rename_section_in_file(const char *config_filename,
 
        fstat(fileno(config_file), &st);
 
-       if (chmod(lock->filename, st.st_mode & 07777) < 0) {
+       if (chmod(lock->filename.buf, st.st_mode & 07777) < 0) {
                ret = error("chmod on %s failed: %s",
-                               lock->filename, strerror(errno));
+                               lock->filename.buf, strerror(errno));
                goto out;
        }
 
@@ -2245,7 +2262,7 @@ int git_config_rename_section_in_file(const char *config_filename,
                                }
                                store.baselen = strlen(new_name);
                                if (!store_write_section(out_fd, new_name)) {
-                                       ret = write_error(lock->filename);
+                                       ret = write_error(lock->filename.buf);
                                        goto out;
                                }
                                /*
@@ -2271,7 +2288,7 @@ int git_config_rename_section_in_file(const char *config_filename,
                        continue;
                length = strlen(output);
                if (write_in_full(out_fd, output, length) != length) {
-                       ret = write_error(lock->filename);
+                       ret = write_error(lock->filename.buf);
                        goto out;
                }
        }