diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2013-08-09 12:29:11 +0400 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2013-08-12 13:40:57 +0400 |
commit | 54f3a572b4fac419008afa83da56c1b0daee1257 (patch) | |
tree | 5a89bdbb596c65128646b42b02a17096beadafae /src/config.c | |
parent | 5880962d90958bc37c08c21d37c9da480ef20e7f (diff) |
config: introduce a regex-filtering iterator
Diffstat (limited to 'src/config.c')
-rw-r--r-- | src/config.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/config.c b/src/config.c index f7ea6f795..9d809f8f1 100644 --- a/src/config.c +++ b/src/config.c @@ -319,6 +319,8 @@ typedef struct { git_config_iterator parent; git_config_iterator *current; const git_config *cfg; + regex_t regex; + int has_regex; size_t i; } all_iter; @@ -380,6 +382,27 @@ static int all_iter_next(git_config_entry **entry, git_config_iterator *_iter) return GIT_ITEROVER; } +static int all_iter_glob_next(git_config_entry **entry, git_config_iterator *_iter) +{ + int error; + all_iter *iter = (all_iter *) _iter; + + /* + * We use the "normal" function to grab the next one across + * backends and then apply the regex + */ + while ((error = all_iter_next(entry, _iter)) == 0) { + /* skip non-matching keys if regexp was provided */ + if (regexec(&iter->regex, (*entry)->name, 0, NULL, 0) != 0) + continue; + + /* and simply return if we like the entry's name */ + return 0; + } + + return error; +} + static void all_iter_free(git_config_iterator *_iter) { all_iter *iter = (all_iter *) _iter; @@ -390,6 +413,14 @@ static void all_iter_free(git_config_iterator *_iter) git__free(iter); } +static void all_iter_glob_free(git_config_iterator *_iter) +{ + all_iter *iter = (all_iter *) _iter; + + regfree(&iter->regex); + all_iter_free(_iter); +} + int git_config_iterator_new(git_config_iterator **out, const git_config *cfg) { all_iter *iter; @@ -408,6 +439,36 @@ int git_config_iterator_new(git_config_iterator **out, const git_config *cfg) return 0; } +int git_config_iterator_glob_new(git_config_iterator **out, const git_config *cfg, const char *regexp) +{ + all_iter *iter; + int result; + + iter = git__calloc(1, sizeof(all_iter)); + GITERR_CHECK_ALLOC(iter); + + if (regexp != NULL) { + if ((result = regcomp(&iter->regex, regexp, REG_EXTENDED)) < 0) { + giterr_set_regex(&iter->regex, result); + regfree(&iter->regex); + return -1; + } + + iter->parent.next = all_iter_glob_next; + } else { + iter->parent.next = all_iter_next; + } + + iter->parent.free = all_iter_glob_free; + + iter->i = cfg->files.length; + iter->cfg = cfg; + + *out = (git_config_iterator *) iter; + + return 0; +} + int git_config_foreach( const git_config *cfg, git_config_foreach_cb cb, void *payload) { |