summaryrefslogtreecommitdiff
path: root/src/config_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/config_file.c')
-rw-r--r--src/config_file.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/config_file.c b/src/config_file.c
index e738064f2..3d29b202b 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -15,6 +15,8 @@
#include <ctype.h>
+#include <sys/types.h>
+#include <regex.h>
typedef struct cvar_t {
struct cvar_t *next;
@@ -294,6 +296,45 @@ static int config_get(git_config_file *cfg, const char *name, const char **out)
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to get config value for %s", name);
}
+static int config_get_multivar(git_config_file *cfg, const char *name, const char *regexp, int (*fn)(const char *, void *), void *data)
+{
+ cvar_t *var;
+ int error = GIT_SUCCESS;
+ diskfile_backend *b = (diskfile_backend *)cfg;
+ char *key;
+ regex_t preg;
+
+ if ((error = normalize_name(name, &key)) < GIT_SUCCESS)
+ return error;
+
+ var = git_hashtable_lookup(b->values, key);
+ git__free(key);
+
+ if (var == NULL)
+ return git__throw(GIT_ENOTFOUND, "Variable '%s' not found", name);
+
+ if (regexp != NULL) {
+ error = regcomp(&preg, regexp, 0);
+ if (error < 0)
+ return git__throw(GIT_EINVALIDARGS, "Failed to compile regex");
+ }
+
+ do {
+ if (regexp == NULL || !regexec(&preg, var->value, 0, NULL, 0)) {
+ error = fn(var->value, data);
+ if (error < GIT_SUCCESS)
+ goto exit;
+ }
+
+ var = var->next;
+ } while (var != NULL);
+
+ exit:
+ if (regexp != NULL)
+ regfree(&preg);
+ return error;
+}
+
static int config_delete(git_config_file *cfg, const char *name)
{
int error;
@@ -342,6 +383,7 @@ int git_config_file__ondisk(git_config_file **out, const char *path)
backend->parent.open = config_open;
backend->parent.get = config_get;
+ backend->parent.get_multivar = config_get_multivar;
backend->parent.set = config_set;
backend->parent.del = config_delete;
backend->parent.foreach = file_foreach;