Commit cca5df63 by Carlos Martín Nieto

config: hopefully get the iterator to work on multivars

parent 3a7ffc29
......@@ -39,7 +39,7 @@ struct git_config_iterator {
* Return the current entry and advance the iterator. The
* memory belongs to the library.
*/
int (*next)(const git_config_entry *entry, git_config_iterator *iter);
int (*next)(git_config_entry *entry, git_config_iterator *iter);
/**
* Free the iterator
......
......@@ -602,18 +602,89 @@ int git_config_get_multivar_foreach(
return (ret == GIT_ENOTFOUND) ? config_error_notfound(name) : 0;
}
struct config_multivar_iter {
typedef struct {
git_config_iterator parent;
};
git_config_iterator *current;
const char *name;
const char *regexp;
const git_config *cfg;
size_t i;
} multivar_iter;
static int find_next_backend(size_t *out, const git_config *cfg, size_t i)
{
file_internal *internal;
for (; i > 0; --i) {
internal = git_vector_get(&cfg->files, i - 1);
if (!internal || !internal->file)
continue;
*out = i;
return 0;
}
return -1;
}
static int multivar_iter_next_empty(git_config_entry *entry, git_config_iterator *_iter)
{
GIT_UNUSED(entry);
GIT_UNUSED(_iter);
return GIT_ITEROVER;
}
static int multivar_iter_next(git_config_entry *entry, git_config_iterator *_iter)
{
multivar_iter *iter = (multivar_iter *) _iter;
git_config_iterator *current = iter->current;
file_internal *internal;
git_config_backend *backend;
size_t i;
int error;
if (current != NULL &&
(error = current->next(entry, current)) == 0)
return 0;
if (error != GIT_ITEROVER)
return error;
do {
if (find_next_backend(&i, iter->cfg, iter->i) < 0)
return GIT_ITEROVER;
internal = git_vector_get(&iter->cfg->files, i - 1);
backend = internal->file;
if ((error = backend->get_multivar(&iter->current, backend, iter->name, iter->regexp)) < 0)
return -1;
iter->i = i;
return iter->current->next(entry, iter->current);
} while(1);
return GIT_ITEROVER;
}
int git_config_get_multivar(git_config_iterator **out, const git_config *cfg, const char *name, const char *regexp)
{
struct config_multivar_iter *iter;
multivar_iter *iter;
size_t i;
iter = git__calloc(1, sizeof(struct config_multivar_iter));
iter = git__calloc(1, sizeof(multivar_iter));
GITERR_CHECK_ALLOC(iter);
/* get multivar from each */
if (find_next_backend(&i, cfg, cfg->files.length) < 0)
iter->parent.next = multivar_iter_next_empty;
else
iter->parent.next = multivar_iter_next;
iter->i = cfg->files.length;
iter->cfg = cfg;
iter->name = name;
iter->regexp = regexp;
*out = (git_config_iterator *) iter;
......
......@@ -433,7 +433,7 @@ static void foreach_iter_free(git_config_iterator *_iter)
git__free(iter);
}
static int foreach_iter_next(git_config_entry **out, git_config_iterator *_iter)
static int foreach_iter_next(git_config_entry *out, git_config_iterator *_iter)
{
foreach_iter *iter = (foreach_iter *) _iter;
......@@ -443,7 +443,9 @@ static int foreach_iter_next(git_config_entry **out, git_config_iterator *_iter)
return GIT_ITEROVER;
if (!iter->have_regex) {
*out = var->entry;
out->name = var->entry->name;
out->value = var->entry->value;
iter->var = var->next;
return 0;
}
......@@ -453,7 +455,8 @@ static int foreach_iter_next(git_config_entry **out, git_config_iterator *_iter)
git_config_entry *entry = var->entry;
regex_t *regex = &iter->regex;;
if (regexec(regex, entry->value, 0, NULL, 0) == 0) {
*out = entry;
out->name = entry->name;
out->value = entry->value;
return 0;
}
} while(var != NULL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment