Add a foreach function to ref_trie.
This commit is contained in:
		
							parent
							
								
									28f7cd1b30
								
							
						
					
					
						commit
						27c79d44f5
					
				@ -3,6 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#include "refcount.h"
 | 
			
		||||
#include "result.h"
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A node in the trie.
 | 
			
		||||
@ -75,6 +76,16 @@ libab_result libab_ref_trie_put(libab_ref_trie* trie, const char* key,
 | 
			
		||||
 */
 | 
			
		||||
void libab_ref_trie_get(const libab_ref_trie* trie, const char* key,
 | 
			
		||||
                        libab_ref* into);
 | 
			
		||||
/**
 | 
			
		||||
 * Calls the given function on every element in the reference-counted
 | 
			
		||||
 * tree.
 | 
			
		||||
 * @param trie the trie to run the operation on.
 | 
			
		||||
 * @param func the function to call.
 | 
			
		||||
 * return the result of the functions, and any necessary allocations.
 | 
			
		||||
 */
 | 
			
		||||
libab_result libab_ref_trie_foreach(const libab_ref_trie* trie,
 | 
			
		||||
                            libab_result (*func)(const libab_ref*, const char*, va_list),
 | 
			
		||||
                            ...);
 | 
			
		||||
/**
 | 
			
		||||
 * Releases the trie, decrementing the refcounts of all
 | 
			
		||||
 * the values stored inside.
 | 
			
		||||
 | 
			
		||||
@ -134,6 +134,65 @@ void libab_ref_trie_get(const libab_ref_trie* trie, const char* key,
 | 
			
		||||
    libab_ref_null(into);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
libab_result _ref_trie_foreach(libab_ref_trie_node* node,
 | 
			
		||||
                               char** str, size_t* str_size, size_t depth,
 | 
			
		||||
                               libab_result (*func)(const libab_ref*, const char*, va_list),
 | 
			
		||||
                               va_list args) {
 | 
			
		||||
    va_list args_copy;
 | 
			
		||||
    libab_result result = LIBAB_SUCCESS;
 | 
			
		||||
    if(node == NULL) {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(depth + 1 >= *str_size) {
 | 
			
		||||
        char* new_str = realloc(*str, (*str_size) *= 2);
 | 
			
		||||
        if(new_str) {
 | 
			
		||||
            *str = new_str;
 | 
			
		||||
        } else {
 | 
			
		||||
            result = LIBAB_MALLOC;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (result == LIBAB_SUCCESS) {
 | 
			
		||||
        (*str)[depth] = node->key;
 | 
			
		||||
        (*str)[depth + 1] = '\0';
 | 
			
		||||
 | 
			
		||||
        if(libab_ref_get(&node->ref)) {
 | 
			
		||||
            va_copy(args_copy, args);
 | 
			
		||||
            result = func(&node->ref, (*str), args_copy);
 | 
			
		||||
            va_end(args_copy);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(result == LIBAB_SUCCESS)
 | 
			
		||||
            result = _ref_trie_foreach(node->child, str, str_size, depth + 1, func, args);
 | 
			
		||||
        if(result == LIBAB_SUCCESS)
 | 
			
		||||
            result = _ref_trie_foreach(node->next, str, str_size, depth, func, args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
libab_result libab_ref_trie_foreach(const libab_ref_trie* trie,
 | 
			
		||||
                            libab_result (*func)(const libab_ref*, const char*, va_list),
 | 
			
		||||
                            ...) {
 | 
			
		||||
    va_list args;
 | 
			
		||||
    libab_result result = LIBAB_SUCCESS;
 | 
			
		||||
    char* str;
 | 
			
		||||
    size_t string_size = 4;
 | 
			
		||||
 | 
			
		||||
    if((str = malloc(sizeof(*str) * 4))) {
 | 
			
		||||
        va_start(args, func);
 | 
			
		||||
        result = _ref_trie_foreach(trie->head, &str, &string_size, 0, func, args);
 | 
			
		||||
        va_end(args);
 | 
			
		||||
    } else {
 | 
			
		||||
        result = LIBAB_MALLOC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(str);
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void libab_ref_trie_free(libab_ref_trie* trie) {
 | 
			
		||||
    _libab_ref_trie_free(trie->head);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user