From 32234541f6d1576149960aa272ccb7219b68ff01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 17 May 2011 14:18:42 +0200 Subject: [PATCH 1/3] Implement git_config_open_global MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Carlos Martín Nieto --- include/git2/config.h | 7 +++++++ src/config.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/git2/config.h b/include/git2/config.h index 3ebbe64de..4e10a5c7a 100644 --- a/include/git2/config.h +++ b/include/git2/config.h @@ -50,6 +50,13 @@ GIT_EXTERN(int) git_config_new(git_config **out); */ GIT_EXTERN(int) git_config_open_bare(git_config **cfg_out, const char *path); +/** + * Open the global configuration file at $HOME/.gitconfig + * + * @param cfg pointer to the configuration + */ +GIT_EXTERN(int) git_config_open_global(git_config **cfg); + /** * */ diff --git a/src/config.c b/src/config.c index cd0a73ccd..0ade5cf97 100644 --- a/src/config.c +++ b/src/config.c @@ -70,6 +70,40 @@ int git_config_open_bare(git_config **out, const char *path) return error; } +int git_config_open_global(git_config **out) +{ + char *home = NULL, *filename = NULL; + const char *gitconfig = ".gitconfig"; + int filename_len, ret, error; + + home = git__strdup(getenv("HOME")); + if (home == NULL) + return GIT_ENOMEM; + + filename_len = strlen(home) + strlen(gitconfig) + 1; + filename = git__malloc(filename_len + 1); + if (filename == NULL) { + error = GIT_ENOMEM; + goto out; + } + + ret = snprintf(filename, filename_len, "%s/%s", home, gitconfig); + if (ret < 0) { + error = git__throw(GIT_EOSERR, "Failed to build global filename. OS err: %s", strerror(errno)); + goto out; + } else if (ret >= filename_len) { + error = git__throw(GIT_ERROR, "Failed to build global filename. Length calulation wrong"); + goto out; + } + + error = git_config_open_bare(out, filename); + + out: + free(home); + free(filename); + return error; +} + void git_config_free(git_config *cfg) { unsigned int i; From f44cbec4799538b201c5e14419fac9cc1544882e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 17 May 2011 14:59:23 +0200 Subject: [PATCH 2/3] Add documentation for git_config_add_backend --- include/git2/config.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/git2/config.h b/include/git2/config.h index 4e10a5c7a..9ae54f112 100644 --- a/include/git2/config.h +++ b/include/git2/config.h @@ -58,7 +58,14 @@ GIT_EXTERN(int) git_config_open_bare(git_config **cfg_out, const char *path); GIT_EXTERN(int) git_config_open_global(git_config **cfg); /** + * Add a config backend to an existing instance * + * Note that the configuration will call the backend's ->free() + * function. + * + * @param cfg the configuration to add the backend to + * @param backend the backend to add + * @param priority the priority the backend should have */ GIT_EXTERN(int) git_config_add_backend(git_config *cfg, git_config_backend *backend, int priority); From 6421c49a3726b4132aafcc780016f5a984832caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 17 May 2011 18:55:52 +0200 Subject: [PATCH 3/3] Fix variable name normalization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When I changed it over to use different strings for the variable and the name, cvar_name_normalize was left behind. Fix this and rename to cvar_normalize_name to reflect the incompatible change. Signed-off-by: Carlos Martín Nieto --- src/config_file.c | 61 ++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/src/config_file.c b/src/config_file.c index 37bb2794e..74a7b5872 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -197,36 +197,49 @@ static cvar_t *cvar_list_find(cvar_t_list *list, const char *name) return NULL; } -static int cvar_name_normalize(const char *input, char **output) +static int cvar_normalize_name(cvar_t *var, char **output) { - char *input_sp = strchr(input, ' '); - char *quote, *str; - int i; - - /* We need to make a copy anyway */ - str = git__strdup(input); - if (str == NULL) - return GIT_ENOMEM; - - *output = str; - - /* If there aren't any spaces, we don't need to do anything */ - if (input_sp == NULL) - return GIT_SUCCESS; + char *section_sp = strchr(var->section, ' '); + char *quote, *name; + int len, ret; /* - * If there are spaces, we replace the space by a dot, move the - * variable name so that the dot before it replaces the last - * quotation mark and repeat so that the first quotation mark - * disappears. + * The final string is going to be at most one char longer than + * the input */ - str[input_sp - input] = '.'; + len = strlen(var->section) + strlen(var->name) + 1; + name = git__malloc(len + 1); + if (name == NULL) + return GIT_ENOMEM; - for (i = 0; i < 2; ++i) { - quote = strrchr(str, '"'); - memmove(quote, quote + 1, strlen(quote)); + /* If there aren't any spaces in the section, it's easy */ + if (section_sp == NULL) { + ret = snprintf(name, len + 1, "%s.%s", var->section, var->name); + if (ret < 0) + return git__throw(GIT_EOSERR, "Failed to normalize name. OS err: %s", strerror(errno)); + + *output = name; + return GIT_SUCCESS; } + /* + * If there are spaces, we replace the space by a dot, move + * section name so it overwrites the first quotation mark and + * replace the last quotation mark by a dot. We then append the + * variable name. + */ + strcpy(name, var->section); + section_sp = strchr(name, ' '); + *section_sp = '.'; + /* Remove first quote */ + quote = strchr(name, '"'); + memmove(quote, quote+1, strlen(quote+1)); + /* Remove second quote */ + quote = strchr(name, '"'); + *quote = '.'; + strcpy(quote+1, var->name); + + *output = name; return GIT_SUCCESS; } @@ -276,7 +289,7 @@ static int file_foreach(git_config_backend *backend, int (*fn)(const char *, voi file_backend *b = (file_backend *)backend; CVAR_LIST_FOREACH(&b->var_list, var) { - ret = cvar_name_normalize(var->name, &normalized); + ret = cvar_normalize_name(var, &normalized); if (ret < GIT_SUCCESS) return ret;