GIT 1.5.4-rc0
[gitweb.git] / config.c
index ffb418ccffc751ef87d8534264fa56b1ca8a6683..49d2b427e52008e612b534f0c567e9fadaeab6e3 100644 (file)
--- a/config.c
+++ b/config.c
@@ -6,6 +6,7 @@
  *
  */
 #include "cache.h"
+#include "exec_cmd.h"
 
 #define MAXNAME (256)
 
@@ -246,53 +247,6 @@ static unsigned long get_unit_factor(const char *end)
        die("unknown unit: '%s'", end);
 }
 
-static struct whitespace_rule {
-       const char *rule_name;
-       unsigned rule_bits;
-} whitespace_rule_names[] = {
-       { "trailing-space", WS_TRAILING_SPACE },
-       { "space-before-tab", WS_SPACE_BEFORE_TAB },
-};
-
-static unsigned parse_whitespace_rule(const char *string)
-{
-       unsigned rule = WS_DEFAULT_RULE;
-
-       while (string) {
-               int i;
-               size_t len;
-               const char *ep;
-               int negated = 0;
-
-               string = string + strspn(string, ", \t\n\r");
-               ep = strchr(string, ',');
-               if (!ep)
-                       len = strlen(string);
-               else
-                       len = ep - string;
-
-               if (*string == '-') {
-                       negated = 1;
-                       string++;
-                       len--;
-               }
-               if (!len)
-                       break;
-               for (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++) {
-                       if (strncmp(whitespace_rule_names[i].rule_name,
-                                   string, len))
-                               continue;
-                       if (negated)
-                               rule &= ~whitespace_rule_names[i].rule_bits;
-                       else
-                               rule |= whitespace_rule_names[i].rule_bits;
-                       break;
-               }
-               string = ep;
-       }
-       return rule;
-}
-
 int git_parse_long(const char *value, long *ret)
 {
        if (value && *value) {
@@ -478,8 +432,15 @@ int git_default_config(const char *var, const char *value)
                return 0;
        }
 
+       if (!strcmp(var, "core.excludesfile")) {
+               if (!value)
+                       die("core.excludesfile without value");
+               excludes_file = xstrdup(value);
+               return 0;
+       }
+
        if (!strcmp(var, "core.whitespace")) {
-               whitespace_rule = parse_whitespace_rule(value);
+               whitespace_rule_cfg = parse_whitespace_rule(value);
                return 0;
        }
 
@@ -504,6 +465,21 @@ int git_config_from_file(config_fn_t fn, const char *filename)
        return ret;
 }
 
+const char *git_etc_gitconfig(void)
+{
+       static const char *system_wide;
+       if (!system_wide) {
+               system_wide = ETC_GITCONFIG;
+               if (!is_absolute_path(system_wide)) {
+                       /* interpret path relative to exec-dir */
+                       const char *exec_path = git_exec_path();
+                       system_wide = prefix_path(exec_path, strlen(exec_path),
+                                               system_wide);
+               }
+       }
+       return system_wide;
+}
+
 int git_config(config_fn_t fn)
 {
        int ret = 0;
@@ -516,8 +492,8 @@ int git_config(config_fn_t fn)
         * config file otherwise. */
        filename = getenv(CONFIG_ENVIRONMENT);
        if (!filename) {
-               if (!access(ETC_GITCONFIG, R_OK))
-                       ret += git_config_from_file(fn, ETC_GITCONFIG);
+               if (!access(git_etc_gitconfig(), R_OK))
+                       ret += git_config_from_file(fn, git_etc_gitconfig());
                home = getenv("HOME");
                filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
                if (!filename)
@@ -675,13 +651,19 @@ static int store_write_pair(int fd, const char* key, const char* value)
        int length = strlen(key+store.baselen+1);
        int quote = 0;
 
-       /* Check to see if the value needs to be quoted. */
+       /*
+        * Check to see if the value needs to be surrounded with a dq pair.
+        * Note that problematic characters are always backslash-quoted; this
+        * check is about not losing leading or trailing SP and strings that
+        * follow beginning-of-comment characters (i.e. ';' and '#') by the
+        * configuration parser.
+        */
        if (value[0] == ' ')
                quote = 1;
        for (i = 0; value[i]; i++)
                if (value[i] == ';' || value[i] == '#')
                        quote = 1;
-       if (value[i-1] == ' ')
+       if (i && value[i-1] == ' ')
                quote = 1;
 
        if (write_in_full(fd, "\t", 1) != 1 ||