From bd370b14fefdba3844a9bf0bbf87171ca48f49be Mon Sep 17 00:00:00 2001 From: Russell Belfer Date: Fri, 30 Dec 2011 15:00:14 -0800 Subject: 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. --- src/vector.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) (limited to 'src/vector.c') 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"); } -- cgit v1.2.1