summaryrefslogtreecommitdiff
path: root/src/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c279
1 files changed, 147 insertions, 132 deletions
diff --git a/src/config.c b/src/config.c
index 912224158..0ab0cd424 100644
--- a/src/config.c
+++ b/src/config.c
@@ -7,7 +7,6 @@
#include "common.h"
#include "fileops.h"
-#include "hashtable.h"
#include "config.h"
#include "git2/config.h"
#include "vector.h"
@@ -60,84 +59,77 @@ int git_config_new(git_config **out)
git_config *cfg;
cfg = git__malloc(sizeof(git_config));
- if (cfg == NULL)
- return GIT_ENOMEM;
+ GITERR_CHECK_ALLOC(cfg);
memset(cfg, 0x0, sizeof(git_config));
if (git_vector_init(&cfg->files, 3, config_backend_cmp) < 0) {
git__free(cfg);
- return GIT_ENOMEM;
+ return -1;
}
*out = cfg;
GIT_REFCOUNT_INC(cfg);
- return GIT_SUCCESS;
+ return 0;
}
int git_config_add_file_ondisk(git_config *cfg, const char *path, int priority)
{
git_config_file *file = NULL;
- int error;
- error = git_config_file__ondisk(&file, path);
- if (error < GIT_SUCCESS)
- return error;
+ if (git_config_file__ondisk(&file, path) < 0)
+ return -1;
- error = git_config_add_file(cfg, file, priority);
- if (error < GIT_SUCCESS) {
+ if (git_config_add_file(cfg, file, priority) < 0) {
/*
* free manually; the file is not owned by the config
* instance yet and will not be freed on cleanup
*/
file->free(file);
- return error;
+ return -1;
}
- return GIT_SUCCESS;
+ return 0;
}
int git_config_open_ondisk(git_config **cfg, const char *path)
{
- int error;
-
- error = git_config_new(cfg);
- if (error < GIT_SUCCESS)
- return error;
+ if (git_config_new(cfg) < 0)
+ return -1;
- error = git_config_add_file_ondisk(*cfg, path, 1);
- if (error < GIT_SUCCESS)
+ if (git_config_add_file_ondisk(*cfg, path, 1) < 0) {
git_config_free(*cfg);
+ return -1;
+ }
- return error;
+ return 0;
}
int git_config_add_file(git_config *cfg, git_config_file *file, int priority)
{
file_internal *internal;
- int error;
+ int result;
assert(cfg && file);
- if ((error = file->open(file)) < GIT_SUCCESS)
- return git__throw(error, "Failed to open config file");
+ if ((result = file->open(file)) < 0)
+ return result;
internal = git__malloc(sizeof(file_internal));
- if (internal == NULL)
- return GIT_ENOMEM;
+ GITERR_CHECK_ALLOC(internal);
internal->file = file;
internal->priority = priority;
if (git_vector_insert(&cfg->files, internal) < 0) {
git__free(internal);
- return GIT_ENOMEM;
+ return -1;
}
git_vector_sort(&cfg->files);
internal->file->cfg = cfg;
- return GIT_SUCCESS;
+ return 0;
}
/*
@@ -146,7 +138,7 @@ int git_config_add_file(git_config *cfg, git_config_file *file, int priority)
int git_config_foreach(git_config *cfg, int (*fn)(const char *, const char *, void *), void *data)
{
- int ret = GIT_SUCCESS;
+ int ret = 0;
unsigned int i;
file_internal *internal;
git_config_file *file;
@@ -165,8 +157,7 @@ int git_config_delete(git_config *cfg, const char *name)
file_internal *internal;
git_config_file *file;
- if (cfg->files.length == 0)
- return git__throw(GIT_EINVALIDARGS, "Cannot delete variable; no files open in the `git_config` instance");
+ assert(cfg->files.length);
internal = git_vector_get(&cfg->files, 0);
file = internal->file;
@@ -200,8 +191,7 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
file_internal *internal;
git_config_file *file;
- if (cfg->files.length == 0)
- return git__throw(GIT_EINVALIDARGS, "Cannot set variable value; no files open in the `git_config` instance");
+ assert(cfg->files.length);
internal = git_vector_get(&cfg->files, 0);
file = internal->file;
@@ -209,28 +199,28 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
return file->set(file, name, value);
}
-static int parse_bool(int *out, const char *value)
+int git_config_parse_bool(int *out, const char *value)
{
/* A missing value means true */
if (value == NULL) {
*out = 1;
- return GIT_SUCCESS;
+ return 0;
}
if (!strcasecmp(value, "true") ||
!strcasecmp(value, "yes") ||
!strcasecmp(value, "on")) {
*out = 1;
- return GIT_SUCCESS;
+ return 0;
}
if (!strcasecmp(value, "false") ||
!strcasecmp(value, "no") ||
!strcasecmp(value, "off")) {
*out = 0;
- return GIT_SUCCESS;
+ return 0;
}
- return GIT_EINVALIDTYPE;
+ return -1;
}
static int parse_int64(int64_t *out, const char *value)
@@ -239,7 +229,7 @@ static int parse_int64(int64_t *out, const char *value)
int64_t num;
if (git__strtol64(&num, value, &num_end, 0) < 0)
- return GIT_EINVALIDTYPE;
+ return -1;
switch (*num_end) {
case 'g':
@@ -259,7 +249,7 @@ static int parse_int64(int64_t *out, const char *value)
/* check that that there are no more characters after the
* given modifier suffix */
if (num_end[1] != '\0')
- return GIT_EINVALIDTYPE;
+ return -1;
/* fallthrough */
@@ -268,7 +258,7 @@ static int parse_int64(int64_t *out, const char *value)
return 0;
default:
- return GIT_EINVALIDTYPE;
+ return -1;
}
}
@@ -278,11 +268,11 @@ static int parse_int32(int32_t *out, const char *value)
int32_t truncate;
if (parse_int64(&tmp, value) < 0)
- return GIT_EINVALIDTYPE;
+ return -1;
truncate = tmp & 0xFFFFFFFF;
if (truncate != tmp)
- return GIT_EOVERFLOW;
+ return -1;
*out = truncate;
return 0;
@@ -291,49 +281,62 @@ static int parse_int32(int32_t *out, const char *value)
/***********
* Getters
***********/
-int git_config_get_mapped(git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n, int *out)
+int git_config_lookup_map_value(
+ git_cvar_map *maps, size_t map_n, const char *value, int *out)
{
size_t i;
- const char *value;
- int error;
- error = git_config_get_string(cfg, name, &value);
- if (error < GIT_SUCCESS)
- return error;
+ if (!value)
+ return GIT_ENOTFOUND;
for (i = 0; i < map_n; ++i) {
git_cvar_map *m = maps + i;
switch (m->cvar_type) {
- case GIT_CVAR_FALSE:
- case GIT_CVAR_TRUE: {
- int bool_val;
+ case GIT_CVAR_FALSE:
+ case GIT_CVAR_TRUE: {
+ int bool_val;
+
+ if (git_config_parse_bool(&bool_val, value) == 0 &&
+ bool_val == (int)m->cvar_type) {
+ *out = m->map_value;
+ return 0;
+ }
+ break;
+ }
- if (parse_bool(&bool_val, value) == 0 &&
- bool_val == (int)m->cvar_type) {
- *out = m->map_value;
- return 0;
- }
+ case GIT_CVAR_INT32:
+ if (parse_int32(out, value) == 0)
+ return 0;
+ break;
- break;
+ case GIT_CVAR_STRING:
+ if (strcasecmp(value, m->str_match) == 0) {
+ *out = m->map_value;
+ return 0;
}
+ break;
+ }
+ }
- case GIT_CVAR_INT32:
- if (parse_int32(out, value) == 0)
- return 0;
+ return GIT_ENOTFOUND;
+}
- break;
+int git_config_get_mapped(git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n, int *out)
+{
+ const char *value;
+ int ret;
- case GIT_CVAR_STRING:
- if (strcasecmp(value, m->str_match) == 0) {
- *out = m->map_value;
- return 0;
- }
- }
- }
+ ret = git_config_get_string(cfg, name, &value);
+ if (ret < 0)
+ return ret;
+
+ if (!git_config_lookup_map_value(maps, map_n, value, out))
+ return 0;
- return git__throw(GIT_ENOTFOUND,
+ giterr_set(GITERR_CONFIG,
"Failed to map the '%s' config variable with a valid value", name);
+ return -1;
}
int git_config_get_int64(git_config *cfg, const char *name, int64_t *out)
@@ -342,69 +345,73 @@ int git_config_get_int64(git_config *cfg, const char *name, int64_t *out)
int ret;
ret = git_config_get_string(cfg, name, &value);
- if (ret < GIT_SUCCESS)
- return git__rethrow(ret, "Failed to retrieve value for '%s'", name);
+ if (ret < 0)
+ return ret;
- if (parse_int64(out, value) < 0)
- return git__throw(GIT_EINVALIDTYPE, "Failed to parse '%s' as an integer", value);
+ if (parse_int64(out, value) < 0) {
+ giterr_set(GITERR_CONFIG, "Failed to parse '%s' as an integer", value);
+ return -1;
+ }
- return GIT_SUCCESS;
+ return 0;
}
int git_config_get_int32(git_config *cfg, const char *name, int32_t *out)
{
const char *value;
- int error;
+ int ret;
- error = git_config_get_string(cfg, name, &value);
- if (error < GIT_SUCCESS)
- return git__rethrow(error, "Failed to get value for %s", name);
+ ret = git_config_get_string(cfg, name, &value);
+ if (ret < 0)
+ return ret;
- error = parse_int32(out, value);
- if (error < GIT_SUCCESS)
- return git__throw(GIT_EINVALIDTYPE, "Failed to parse '%s' as a 32-bit integer", value);
-
- return GIT_SUCCESS;
+ if (parse_int32(out, value) < 0) {
+ giterr_set(GITERR_CONFIG, "Failed to parse '%s' as a 32-bit integer", value);
+ return -1;
+ }
+
+ return 0;
}
int git_config_get_bool(git_config *cfg, const char *name, int *out)
{
const char *value;
- int error = GIT_SUCCESS;
+ int ret;
- error = git_config_get_string(cfg, name, &value);
- if (error < GIT_SUCCESS)
- return git__rethrow(error, "Failed to get value for %s", name);
+ ret = git_config_get_string(cfg, name, &value);
+ if (ret < 0)
+ return ret;
- if (parse_bool(out, value) == 0)
- return GIT_SUCCESS;
+ if (git_config_parse_bool(out, value) == 0)
+ return 0;
if (parse_int32(out, value) == 0) {
*out = !!(*out);
- return GIT_SUCCESS;
+ return 0;
}
- return git__throw(GIT_EINVALIDTYPE, "Failed to parse '%s' as a boolean value", value);
+ giterr_set(GITERR_CONFIG, "Failed to parse '%s' as a boolean value", value);
+ return -1;
}
int git_config_get_string(git_config *cfg, const char *name, const char **out)
{
file_internal *internal;
- git_config_file *file;
- int error = GIT_ENOTFOUND;
unsigned int i;
- if (cfg->files.length == 0)
- return git__throw(GIT_EINVALIDARGS, "Cannot get variable value; no files open in the `git_config` instance");
+ assert(cfg->files.length);
- for (i = 0; i < cfg->files.length; ++i) {
- internal = git_vector_get(&cfg->files, i);
- file = internal->file;
- if ((error = file->get(file, name, out)) == GIT_SUCCESS)
- return GIT_SUCCESS;
+ *out = NULL;
+
+ git_vector_foreach(&cfg->files, i, internal) {
+ git_config_file *file = internal->file;
+ int ret = file->get(file, name, out);
+ if (ret != GIT_ENOTFOUND)
+ return ret;
}
- return git__throw(error, "Config value '%s' not found", name);
+ giterr_set(GITERR_CONFIG, "Config variable '%s' not found", name);
+ return GIT_ENOTFOUND;
}
int git_config_get_multivar(git_config *cfg, const char *name, const char *regexp,
@@ -412,12 +419,10 @@ int git_config_get_multivar(git_config *cfg, const char *name, const char *regex
{
file_internal *internal;
git_config_file *file;
- int error = GIT_ENOTFOUND;
+ int ret = GIT_ENOTFOUND;
unsigned int i;
-
- if (cfg->files.length == 0)
- return git__throw(GIT_EINVALIDARGS, "Cannot get variable value; no files open in the `git_config` instance");
+ assert(cfg->files.length);
/*
* This loop runs the "wrong" way 'round because we need to
@@ -426,30 +431,30 @@ int git_config_get_multivar(git_config *cfg, const char *name, const char *regex
for (i = cfg->files.length; i > 0; --i) {
internal = git_vector_get(&cfg->files, i - 1);
file = internal->file;
- error = file->get_multivar(file, name, regexp, fn, data);
- if (error < GIT_SUCCESS && error != GIT_ENOTFOUND)
- git__rethrow(error, "Failed to get multivar");
+ ret = file->get_multivar(file, name, regexp, fn, data);
+ if (ret < 0 && ret != GIT_ENOTFOUND)
+ return ret;
}
- return GIT_SUCCESS;
+ return 0;
}
int git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value)
{
file_internal *internal;
git_config_file *file;
- int error = GIT_ENOTFOUND;
+ int ret = GIT_ENOTFOUND;
unsigned int i;
for (i = cfg->files.length; i > 0; --i) {
internal = git_vector_get(&cfg->files, i - 1);
file = internal->file;
- error = file->set_multivar(file, name, regexp, value);
- if (error < GIT_SUCCESS && error != GIT_ENOTFOUND)
- git__rethrow(error, "Failed to replace multivar");
+ ret = file->set_multivar(file, name, regexp, value);
+ if (ret < 0 && ret != GIT_ENOTFOUND)
+ return ret;
}
- return GIT_SUCCESS;
+ return 0;
}
int git_config_find_global_r(git_buf *path)
@@ -460,18 +465,23 @@ int git_config_find_global_r(git_buf *path)
int git_config_find_global(char *global_config_path)
{
git_buf path = GIT_BUF_INIT;
- int error = git_config_find_global_r(&path);
+ int ret = git_config_find_global_r(&path);
- if (error == GIT_SUCCESS) {
- if (path.size > GIT_PATH_MAX)
- error = git__throw(GIT_ESHORTBUFFER, "Path is too long");
- else
- git_buf_copy_cstr(global_config_path, GIT_PATH_MAX, &path);
+ if (ret < 0) {
+ git_buf_free(&path);
+ return ret;
}
- git_buf_free(&path);
+ if (path.size > GIT_PATH_MAX) {
+ git_buf_free(&path);
+ giterr_set(GITERR_NOMEMORY,
+ "Path is to long to fit on the given buffer");
+ return -1;
+ }
- return error;
+ git_buf_copy_cstr(global_config_path, GIT_PATH_MAX, &path);
+ git_buf_free(&path);
+ return 0;
}
int git_config_find_system_r(git_buf *path)
@@ -482,18 +492,23 @@ int git_config_find_system_r(git_buf *path)
int git_config_find_system(char *system_config_path)
{
git_buf path = GIT_BUF_INIT;
- int error = git_config_find_system_r(&path);
+ int ret = git_config_find_system_r(&path);
- if (error == GIT_SUCCESS) {
- if (path.size > GIT_PATH_MAX)
- error = git__throw(GIT_ESHORTBUFFER, "Path is too long");
- else
- git_buf_copy_cstr(system_config_path, GIT_PATH_MAX, &path);
+ if (ret < 0) {
+ git_buf_free(&path);
+ return ret;
}
- git_buf_free(&path);
+ if (path.size > GIT_PATH_MAX) {
+ git_buf_free(&path);
+ giterr_set(GITERR_NOMEMORY,
+ "Path is to long to fit on the given buffer");
+ return -1;
+ }
- return error;
+ git_buf_copy_cstr(system_config_path, GIT_PATH_MAX, &path);
+ git_buf_free(&path);
+ return 0;
}
int git_config_open_global(git_config **out)
@@ -501,7 +516,7 @@ int git_config_open_global(git_config **out)
int error;
char global_path[GIT_PATH_MAX];
- if ((error = git_config_find_global(global_path)) < GIT_SUCCESS)
+ if ((error = git_config_find_global(global_path)) < 0)
return error;
return git_config_open_ondisk(out, global_path);