diff options
author | Russell Belfer <arrbee@arrbee.com> | 2011-12-31 03:00:14 +0400 |
---|---|---|
committer | Russell Belfer <arrbee@arrbee.com> | 2011-12-31 03:00:14 +0400 |
commit | bd370b14fefdba3844a9bf0bbf87171ca48f49be (patch) | |
tree | b16a3e4ee778d33fb7782b26c7cffb3068b63087 /src/vector.c | |
parent | c6d2a2c0946ff32c16578b68b39824f4fea8f782 (diff) |
Improved gitattributes macro implementation
This updates to implementation of gitattribute macros to be much more
similar to core git (albeit not 100%) and to handle expansion of
macros within macros, etc. It also cleans up the refcounting usage
with macros to be much cleaner.
Also, this adds a new vector function `git_vector_insert_sorted()`
which allows you to maintain a sorted list as you go. In order to
write that function, this changes the function `git__bsearch()` to
take a somewhat different set of parameters, although the core
functionality is still the same.
Diffstat (limited to 'src/vector.c')
-rw-r--r-- | src/vector.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/src/vector.c b/src/vector.c index e745d77dd..593d037d4 100644 --- a/src/vector.c +++ b/src/vector.c @@ -74,6 +74,45 @@ int git_vector_insert(git_vector *v, void *element) return GIT_SUCCESS; } +int git_vector_insert_sorted(git_vector *v, void *element, int (*on_dup)(void **old, void *new)) +{ + int error = GIT_SUCCESS; + size_t pos; + + assert(v && v->_cmp); + + if (!v->sorted) + git_vector_sort(v); + + if (v->length >= v->_alloc_size) { + if (resize_vector(v) < 0) + return GIT_ENOMEM; + } + + error = git__bsearch(v->contents, v->length, element, v->_cmp, &pos); + + /* If we found the element and have a duplicate handler callback, + * invoke it. If it returns an error, then cancel insert, otherwise + * proceed with normal insert. + */ + if (error == GIT_SUCCESS && on_dup != NULL) { + error = on_dup(&v->contents[pos], element); + if (error != GIT_SUCCESS) + return error; + } + + /* shift elements to the right */ + if (pos < v->length) { + memmove(v->contents + pos + 1, v->contents + pos, + (v->length - pos) * sizeof(void *)); + } + + v->contents[pos] = element; + v->length++; + + return GIT_SUCCESS; +} + void git_vector_sort(git_vector *v) { assert(v); @@ -87,7 +126,7 @@ void git_vector_sort(git_vector *v) int git_vector_bsearch2(git_vector *v, git_vector_cmp key_lookup, const void *key) { - void **find; + size_t pos; assert(v && key && key_lookup); @@ -97,9 +136,9 @@ int git_vector_bsearch2(git_vector *v, git_vector_cmp key_lookup, const void *ke git_vector_sort(v); - find = git__bsearch(key, v->contents, v->length, key_lookup); - if (find != NULL) - return (int)(find - v->contents); + if (git__bsearch(v->contents, v->length, key, key_lookup, + &pos) == GIT_SUCCESS) + return (int)pos; return git__throw(GIT_ENOTFOUND, "Can't find element"); } |