Allow passing of configuration parameters in the command line
[gitweb.git] / config.c
index 37385ce9d338ecbd2556cef9455000784ebab7e5..b6a4257627373b2ce83321a7f21b0c86e50b9641 100644 (file)
--- a/config.c
+++ b/config.c
@@ -18,6 +18,62 @@ static int zlib_compression_seen;
 
 const char *config_exclusive_filename = NULL;
 
+struct config_item
+{
+       struct config_item *next;
+       char *value;
+       char name[1 /* NUL */];
+};
+static struct config_item *config_parameters;
+static struct config_item **config_parameters_tail = &config_parameters;
+
+static void lowercase(char *p)
+{
+       for (; *p; p++)
+               *p = tolower(*p);
+}
+static char *skip_space(const char *p)
+{
+       for (; *p; p++)
+               if (!isspace(*p))
+                       break;
+       return (char *)p;
+}
+static char *trailing_space(const char *begin, const char *p)
+{
+       while (p-- > begin)
+               if (!isspace(*p))
+                       break;
+       return (char *)p + 1;
+}
+
+int git_config_parse_parameter(const char *text)
+{
+       struct config_item *ct;
+       const char *name;
+       const char *val;
+       name = skip_space(text);
+       text = val = strchr(name, '=');
+       if (!text)
+               text = name + strlen(name);
+       text = trailing_space(name, text);
+       if (text <= name)
+               return -1;
+       ct = xcalloc(1, sizeof(struct config_item) + (text - name));
+       memcpy(ct->name, name, text - name);
+       lowercase(ct->name);
+       if (!val)
+               ct->value = NULL;
+       else {
+               val = skip_space(++val /* skip "=" */);
+               text = trailing_space(val, val + strlen(val));
+               ct->value = xstrndup(val, text - val);
+       }
+       *config_parameters_tail = ct;
+       config_parameters_tail = &ct->next;
+       return 0;
+}
+
 static int get_next_char(void)
 {
        int c;
@@ -518,6 +574,11 @@ static int git_default_core_config(const char *var, const char *value)
                return 0;
        }
 
+       if (!strcmp(var, "core.sparsecheckout")) {
+               core_apply_sparse_checkout = git_config_bool(var, value);
+               return 0;
+       }
+
        /* Add other config variables here and to Documentation/config.txt. */
        return 0;
 }
@@ -528,8 +589,7 @@ static int git_default_user_config(const char *var, const char *value)
                if (!value)
                        return config_error_nonbool(var);
                strlcpy(git_default_name, value, sizeof(git_default_name));
-               if (git_default_email[0])
-                       user_ident_explicitly_given = 1;
+               user_ident_explicitly_given |= IDENT_NAME_GIVEN;
                return 0;
        }
 
@@ -537,8 +597,7 @@ static int git_default_user_config(const char *var, const char *value)
                if (!value)
                        return config_error_nonbool(var);
                strlcpy(git_default_email, value, sizeof(git_default_email));
-               if (git_default_name[0])
-                       user_ident_explicitly_given = 1;
+               user_ident_explicitly_given |= IDENT_MAIL_GIVEN;
                return 0;
        }
 
@@ -696,6 +755,15 @@ int git_config_global(void)
        return !git_env_bool("GIT_CONFIG_NOGLOBAL", 0);
 }
 
+int git_config_from_parameters(config_fn_t fn, void *data)
+{
+       const struct config_item *ct;
+       for (ct = config_parameters; ct; ct = ct->next)
+               if (fn(ct->name, ct->value, data) < 0)
+                       return -1;
+       return 0;
+}
+
 int git_config(config_fn_t fn, void *data)
 {
        int ret = 0, found = 0;
@@ -727,6 +795,12 @@ int git_config(config_fn_t fn, void *data)
                found += 1;
        }
        free(repo_config);
+
+       if (config_parameters) {
+               ret += git_config_from_parameters(fn, data);
+               found += 1;
+       }
+
        if (found == 0)
                return -1;
        return ret;