From: Michael D. Lowis Date: Fri, 29 Aug 2014 14:22:17 +0000 (-0400) Subject: Added an rt.h header for common runtime-related includes used by all modules X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=87d661e41281f30bcf7a3cc5d61f7ccbdcad467f;p=projs%2Flibcds.git Added an rt.h header for common runtime-related includes used by all modules --- diff --git a/Rakefile b/Rakefile index 16641e1..e48ffb5 100644 --- a/Rakefile +++ b/Rakefile @@ -15,7 +15,7 @@ require 'rbconfig' #------------------------------------------------------------------------------ # Define the compiler environment Env = Rscons::Environment.new do |env| - env.build_dir('source/','build/obj/source') + env.build_dir('source','build/obj/source') env["CFLAGS"] += ['--std=c99', '--pedantic', '--coverage', '-Wall', '-Wextra', '-Werror'] env["LDFLAGS"] += ['--coverage'] env['CPPPATH'] += Dir['source/**/'] @@ -51,6 +51,14 @@ task :test do TestEnv.Program('build/test_libcds', Dir['source/**/*.c', 'tests/**/*.c']) TestEnv.process sh "build/test_libcds" + FileList['build/obj/test_source/**/*.gcno'].each do |gcno| + obj = gcno.ext('o') + path = File.dirname(obj) + gcov = File.basename(obj).ext('c.gcov') + sh *['gcov', '-abc', obj] + FileUtils.cp(gcov,"#{path}/#{gcov}") + FileUtils.rm(gcov) + end end #------------------------------------------------------------------------------ diff --git a/source/buffer/buf.c b/source/buffer/buf.c index 5a8bc79..eae75cc 100644 --- a/source/buffer/buf.c +++ b/source/buffer/buf.c @@ -4,9 +4,7 @@ $Revision$ $HeadURL$ */ -#include #include "buf.h" -#include "mem.h" static void buf_free(void* p_buf); diff --git a/source/buffer/buf.h b/source/buffer/buf.h index b9a53b6..2c15e85 100644 --- a/source/buffer/buf.h +++ b/source/buffer/buf.h @@ -11,15 +11,14 @@ extern "C" { #endif -#include -#include +#include "rt.h" /** A structure defining a circular buffer */ typedef struct { void** buffer; /**< Pointer to the buffer */ - size_t size /**< Size of the allocated buffer */; - size_t reads /**< Total number of reads that have occurred */; - size_t writes /**< Total number of writes that have occrurred */; + size_t size; /**< Size of the allocated buffer */ + size_t reads; /**< Total number of reads that have occurred */ + size_t writes; /**< Total number of writes that have occrurred */ } buf_t; /** diff --git a/source/exn/exn.c b/source/exn/exn.c index cd81cc7..b081db5 100755 --- a/source/exn/exn.c +++ b/source/exn/exn.c @@ -6,7 +6,6 @@ */ #include "exn.h" #include -#include #ifndef EXN_MAX_NUM_HANDLERS #define EXN_MAX_NUM_HANDLERS (8) diff --git a/source/exn/exn.h b/source/exn/exn.h index 2a6d9c6..3c7febb 100755 --- a/source/exn/exn.h +++ b/source/exn/exn.h @@ -7,8 +7,12 @@ #ifndef EXN_H #define EXN_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "rt.h" #include -#include typedef struct exn_t { const struct exn_t* p_parent; @@ -70,4 +74,8 @@ void exn_assert(bool expr); #define assert(expr) exn_assert(expr) #endif +#ifdef __cplusplus +} +#endif + #endif /* EXN_H */ diff --git a/source/list/list.c b/source/list/list.c index e5492d2..7d807f6 100644 --- a/source/list/list.c +++ b/source/list/list.c @@ -1,10 +1,12 @@ -#include -#include +/** + @file list.c + @brief See header for details + $Revision$ + $HeadURL$ + */ #include "list.h" -#include "mem.h" static void list_free(void* p_list); - static void list_node_free(void* p_node); list_t* list_new(void) diff --git a/source/list/list.h b/source/list/list.h index 38608e0..b9ae7ad 100644 --- a/source/list/list.h +++ b/source/list/list.h @@ -5,8 +5,7 @@ extern "C" { #endif -#include -#include +#include "rt.h" /** A linked list node. */ typedef struct list_node_t diff --git a/source/mem/mem.c b/source/mem/mem.c index feb8c80..f95dfa3 100644 --- a/source/mem/mem.c +++ b/source/mem/mem.c @@ -1,8 +1,5 @@ #include "mem.h" -#include -#include #ifdef LEAK_DETECT_LEVEL -#include #include #endif diff --git a/source/mem/mem.h b/source/mem/mem.h index b621e4e..fcdfb4d 100644 --- a/source/mem/mem.h +++ b/source/mem/mem.h @@ -1,19 +1,18 @@ /** @file mem.h - @brief TODO: Describe this file + @brief Implements reference counting routines for C. $Revision$ $HeadURL$ */ #ifndef MEM_H #define MEM_H -#include -#include - #ifdef __cplusplus extern "C" { #endif +#include "rt.h" + /** A function pointer for object destructors */ typedef void (*destructor_t)(void* p_val); diff --git a/source/rbt/rbt.c b/source/rbt/rbt.c index 830ef7e..8e42fc9 100644 --- a/source/rbt/rbt.c +++ b/source/rbt/rbt.c @@ -1,11 +1,16 @@ -#include "mem.h" +/** + @file rbt.c + @brief See header for details + $Revision$ + $HeadURL$ + */ #include "rbt.h" //nodes are compared by memory address by default static int rbt_default_comparator(void* v_a, void* v_b){ - uintptr_t a = (intptr_t)v_a; - uintptr_t b = (intptr_t)v_b; - return (a == b ? 0 : (aroot) mem_release(tree->root); + rbt_t* tree = (rbt_t*) v_tree; + if(tree && tree->root) mem_release(tree->root); } + rbt_t* rbt_new(comparator_t comparator){ - rbt_t* tree = mem_allocate(sizeof(rbt_t), &rbt_free); - tree->root = NULL; - tree->comp = comparator ? comparator : rbt_default_comparator; - return tree; + rbt_t* tree = mem_allocate(sizeof(rbt_t), &rbt_free); + tree->root = NULL; + tree->comp = comparator ? comparator : rbt_default_comparator; + return tree; } /* rbt_node_t */ static void rbt_node_free(void* v_node){ - rbt_node_t* node = (rbt_node_t*) v_node; - if(node){ - mem_release(node->contents); - if(node->left) mem_release(node->left); - if(node->right) mem_release(node->right); - } + rbt_node_t* node = (rbt_node_t*) v_node; + if(node){ + mem_release(node->contents); + if(node->left) mem_release(node->left); + if(node->right) mem_release(node->right); + } } + rbt_node_t* rbt_node_new(void* contents){ - rbt_node_t* node = mem_allocate(sizeof(rbt_node_t), &rbt_node_free); - node->left = NULL; - node->right = NULL; - node->parent = NULL; - node->contents = contents; - node->color = RED; - return node; + rbt_node_t* node = mem_allocate(sizeof(rbt_node_t), &rbt_node_free); + node->left = NULL; + node->right = NULL; + node->parent = NULL; + node->contents = contents; + node->color = RED; + return node; } @@ -49,34 +56,34 @@ rbt_node_t* rbt_node_new(void* contents){ /* ---------------------------------------- */ rbt_color_t rbt_node_color(rbt_node_t* node){ - //leaves are NULL and black implicitly - return (node ? node->color : BLACK); + //leaves are NULL and black implicitly + return (node ? node->color : BLACK); } static rbt_node_t* rbt_lookup_node(rbt_t* tree, rbt_node_t* node, void* value){ - rbt_node_t* ret = NULL; - if(node){ - int c = tree->comp(value, node->contents); - if(c == 0) ret = node; - else if(c > 0) ret = rbt_lookup_node(tree, node->right, value); - else if(c < 0) ret = rbt_lookup_node(tree, node->left, value); - } - return ret; + rbt_node_t* ret = NULL; + if(node){ + int c = tree->comp(value, node->contents); + if(c == 0) ret = node; + else if(c > 0) ret = rbt_lookup_node(tree, node->right, value); + else if(c < 0) ret = rbt_lookup_node(tree, node->left, value); + } + return ret; } rbt_node_t* rbt_lookup(rbt_t* tree, void* value){ - return rbt_lookup_node(tree, tree->root, value); + return rbt_lookup_node(tree, tree->root, value); } static rbt_node_t* rightmost_descendant(rbt_node_t* node){ - return (node->right) ? rightmost_descendant(node->right) : node; + return (node->right) ? rightmost_descendant(node->right) : node; } static int rbt_count(rbt_node_t* node){ - return (!node ? 0 : (1 + rbt_count(node->left) + rbt_count(node->right))); + return (!node ? 0 : (1 + rbt_count(node->left) + rbt_count(node->right))); } int rbt_count_nodes(rbt_t* tree){ - return rbt_count(tree->root); + return rbt_count(tree->root); } /* ----------------------------------------- */ @@ -84,27 +91,27 @@ int rbt_count_nodes(rbt_t* tree){ /* ----------------------------------------- */ static void rbt_node_replace(rbt_t* tree, rbt_node_t* target, rbt_node_t* replacement){ - if(NULL == target->parent) tree->root = replacement; - else if(target == target->parent->left) target->parent->left = replacement; - else target->parent->right = replacement; - if(replacement) replacement->parent = target->parent; + if(NULL == target->parent) tree->root = replacement; + else if(target == target->parent->left) target->parent->left = replacement; + else target->parent->right = replacement; + if(replacement) replacement->parent = target->parent; } typedef enum { - LEFT = 0, RIGHT + LEFT = 0, RIGHT } direction_t; static void rbt_rotate(rbt_t* tree, rbt_node_t* node, direction_t direction){ - rbt_node_t* edon = (direction == LEFT) ? node->right : node->left; - if(edon){ - rbt_node_t** edon_side = (direction == LEFT ? &(edon->left) : &(edon->right)); - rbt_node_t** node_side = (direction == LEFT ? &(node->right) : &(node->left)); - rbt_node_replace(tree, node, edon); - *node_side = *edon_side; //safe to overwrite; points to edon - if(*edon_side) (*edon_side)->parent = node; - *edon_side = node; - node->parent = edon; - } /* else rotation isn't allowed */ + rbt_node_t* edon = (direction == LEFT) ? node->right : node->left; + if(edon){ + rbt_node_t** edon_side = (direction == LEFT ? &(edon->left) : &(edon->right)); + rbt_node_t** node_side = (direction == LEFT ? &(node->right) : &(node->left)); + rbt_node_replace(tree, node, edon); + *node_side = *edon_side; //safe to overwrite; points to edon + if(*edon_side) (*edon_side)->parent = node; + *edon_side = node; + node->parent = edon; + } /* else rotation isn't allowed */ } @@ -113,58 +120,58 @@ static void rbt_rotate(rbt_t* tree, rbt_node_t* node, direction_t direction){ /* -------------------- */ static void rbt_ins_rebalance(rbt_t* tree, rbt_node_t* node, direction_t heavy_side){ - rbt_node_t* parent = node->parent; - rbt_node_t* grandparent = (parent ? parent->parent : NULL); - rbt_rotate(tree, grandparent, (heavy_side == LEFT ? RIGHT : LEFT)); - parent->color = BLACK; - grandparent->color = RED; + rbt_node_t* parent = node->parent; + rbt_node_t* grandparent = (parent ? parent->parent : NULL); + rbt_rotate(tree, grandparent, (heavy_side == LEFT ? RIGHT : LEFT)); + parent->color = BLACK; + grandparent->color = RED; } static void rbt_ins_recolor(rbt_t* tree, rbt_node_t* node){ - rbt_node_t* parent = node->parent; - rbt_node_t* grandparent = (parent ? parent->parent : NULL); - rbt_node_t* uncle = (grandparent ? (parent == grandparent->left ? grandparent->right : grandparent->left) : NULL); - if(NULL == parent){ - node->color = BLACK; - }else if(RED == rbt_node_color(parent)){ - if(rbt_node_color(uncle) == RED){ - grandparent->color = RED; - parent->color = BLACK; - uncle->color = BLACK; - rbt_ins_recolor(tree, grandparent); - }else{ - direction_t node_side = (node == parent->left ? LEFT : RIGHT); - direction_t parent_side = (parent == grandparent->left ? LEFT : RIGHT); - if(node_side != parent_side){ // "inside" case - rbt_rotate(tree, parent, parent_side); //transform to "outside" case - node = parent; //parent now lowest node. - } - rbt_ins_rebalance(tree, node, parent_side); - } - } + rbt_node_t* parent = node->parent; + rbt_node_t* grandparent = (parent ? parent->parent : NULL); + rbt_node_t* uncle = (grandparent ? (parent == grandparent->left ? grandparent->right : grandparent->left) : NULL); + if(NULL == parent){ + node->color = BLACK; + }else if(RED == rbt_node_color(parent)){ + if(rbt_node_color(uncle) == RED){ + grandparent->color = RED; + parent->color = BLACK; + uncle->color = BLACK; + rbt_ins_recolor(tree, grandparent); + }else{ + direction_t node_side = (node == parent->left ? LEFT : RIGHT); + direction_t parent_side = (parent == grandparent->left ? LEFT : RIGHT); + if(node_side != parent_side){ // "inside" case + rbt_rotate(tree, parent, parent_side); //transform to "outside" case + node = parent; //parent now lowest node. + } + rbt_ins_rebalance(tree, node, parent_side); + } + } } static void rbt_insert_node(rbt_t* tree, rbt_node_t* node, rbt_node_t* parent){ - if(NULL == parent){ /* inserting root of the tree */ - tree->root = node; - rbt_ins_recolor(tree, node); - }else{ - int c = tree->comp(node->contents, parent->contents); - rbt_node_t** relevant_child = (c<0 ? &(parent->left) : &(parent->right)); - if(*relevant_child){ - rbt_insert_node(tree, node, *relevant_child); - }else{ - node->parent = parent; - *relevant_child = node; - rbt_ins_recolor(tree, node); - } - } + if(NULL == parent){ /* inserting root of the tree */ + tree->root = node; + rbt_ins_recolor(tree, node); + }else{ + int c = tree->comp(node->contents, parent->contents); + rbt_node_t** relevant_child = (c<0 ? &(parent->left) : &(parent->right)); + if(*relevant_child){ + rbt_insert_node(tree, node, *relevant_child); + }else{ + node->parent = parent; + *relevant_child = node; + rbt_ins_recolor(tree, node); + } + } } rbt_node_t* rbt_insert(rbt_t* tree, void* value){ - rbt_node_t* new_node = rbt_node_new(value); - rbt_insert_node(tree, new_node, tree->root); - return new_node; + rbt_node_t* new_node = rbt_node_new(value); + rbt_insert_node(tree, new_node, tree->root); + return new_node; } @@ -174,70 +181,70 @@ rbt_node_t* rbt_insert(rbt_t* tree, void* value){ //node has a count -1 of black nodes to leaves relative to the rest of the tree static void rbt_del_rebalance(rbt_t* tree, rbt_node_t* node){ - rbt_node_t* parent = node->parent; - if(parent){ - direction_t node_side = (node == parent->left ? LEFT : RIGHT); - rbt_node_t* sib = (node_side == LEFT ? parent->right : parent->left); - //nibling: gender neutral term for niece or nephew. - rbt_node_t* inside_nibling = sib ? (node_side == LEFT ? sib->left : sib->right) : NULL; - rbt_node_t* outside_nibling = sib ? (node_side == LEFT ? sib->right : sib->left) : NULL; - if(RED == rbt_node_color(sib)){ - //rotate so sib is black & recurse w/ new scenario - rbt_rotate(tree, parent, node_side); - parent->color = RED; - sib->color = BLACK; - rbt_del_rebalance(tree, node); - }else if(BLACK == rbt_node_color(inside_nibling) && BLACK == rbt_node_color(outside_nibling)){ - //both niblings are black ; can paint sib red & rebalance on parent - sib->color = RED; - if(RED == rbt_node_color(parent)) parent->color = BLACK; - else rbt_del_rebalance(tree, parent); - }else if(BLACK == rbt_node_color(outside_nibling)){ - //convert "inside" case to "outside" case & recurse w/ new scenario - rbt_rotate(tree, sib, (node_side == LEFT ? RIGHT : LEFT)); - sib->color = RED; - inside_nibling->color = BLACK; - rbt_del_rebalance(tree, node); - }else{ - rbt_rotate(tree, parent, node_side); - sib->color = parent->color; - parent->color = BLACK; - outside_nibling->color = BLACK; - } - }else{ - node->color = BLACK; //TODO: verify this is necessary - } + rbt_node_t* parent = node->parent; + if(parent){ + direction_t node_side = (node == parent->left ? LEFT : RIGHT); + rbt_node_t* sib = (node_side == LEFT ? parent->right : parent->left); + //nibling: gender neutral term for niece or nephew. + rbt_node_t* inside_nibling = sib ? (node_side == LEFT ? sib->left : sib->right) : NULL; + rbt_node_t* outside_nibling = sib ? (node_side == LEFT ? sib->right : sib->left) : NULL; + if(RED == rbt_node_color(sib)){ + //rotate so sib is black & recurse w/ new scenario + rbt_rotate(tree, parent, node_side); + parent->color = RED; + sib->color = BLACK; + rbt_del_rebalance(tree, node); + }else if(BLACK == rbt_node_color(inside_nibling) && BLACK == rbt_node_color(outside_nibling)){ + //both niblings are black ; can paint sib red & rebalance on parent + sib->color = RED; + if(RED == rbt_node_color(parent)) parent->color = BLACK; + else rbt_del_rebalance(tree, parent); + }else if(BLACK == rbt_node_color(outside_nibling)){ + //convert "inside" case to "outside" case & recurse w/ new scenario + rbt_rotate(tree, sib, (node_side == LEFT ? RIGHT : LEFT)); + sib->color = RED; + inside_nibling->color = BLACK; + rbt_del_rebalance(tree, node); + }else{ + rbt_rotate(tree, parent, node_side); + sib->color = parent->color; + parent->color = BLACK; + outside_nibling->color = BLACK; + } + }else{ + node->color = BLACK; //TODO: verify this is necessary + } } static void rbt_delete_node(rbt_t* tree, rbt_node_t* node){ - rbt_node_t* descendant = NULL; - if(node->left && node->right){ - descendant = rightmost_descendant(node->left); - mem_retain(descendant); - rbt_delete_node(tree, descendant); - if(node->left) node->left->parent = descendant; - if(node->right) node->right->parent = descendant; - descendant->left = node->left; - descendant->right = node->right; - descendant->color = node->color; - }else if(BLACK == rbt_node_color(node)){ - //black node with at most one non-leaf child - if(RED == rbt_node_color(node->left) || RED == rbt_node_color(node->right)){ - descendant = node->left ? node->left : node->right; - descendant->color = BLACK; - } else { - rbt_del_rebalance(tree, node); - } - } - rbt_node_replace(tree, node, descendant); - node->left = NULL; - node->right = NULL; - node->parent = NULL; - mem_release(node); + rbt_node_t* descendant = NULL; + if(node->left && node->right){ + descendant = rightmost_descendant(node->left); + mem_retain(descendant); + rbt_delete_node(tree, descendant); + if(node->left) node->left->parent = descendant; + if(node->right) node->right->parent = descendant; + descendant->left = node->left; + descendant->right = node->right; + descendant->color = node->color; + }else if(BLACK == rbt_node_color(node)){ + //black node with at most one non-leaf child + if(RED == rbt_node_color(node->left) || RED == rbt_node_color(node->right)){ + descendant = node->left ? node->left : node->right; + descendant->color = BLACK; + } else { + rbt_del_rebalance(tree, node); + } + } + rbt_node_replace(tree, node, descendant); + node->left = NULL; + node->right = NULL; + node->parent = NULL; + mem_release(node); } void rbt_delete(rbt_t* tree, void* value){ - rbt_node_t* doomed = rbt_lookup(tree, value); - if(doomed) rbt_delete_node(tree, doomed); + rbt_node_t* doomed = rbt_lookup(tree, value); + if(doomed) rbt_delete_node(tree, doomed); } diff --git a/source/rbt/rbt.h b/source/rbt/rbt.h index 5834e56..53429d1 100644 --- a/source/rbt/rbt.h +++ b/source/rbt/rbt.h @@ -5,6 +5,8 @@ extern "C" { #endif +#include "rt.h" + /** node colors */ typedef enum { RED = 0, diff --git a/source/rt.h b/source/rt.h new file mode 100755 index 0000000..bed0c74 --- /dev/null +++ b/source/rt.h @@ -0,0 +1,20 @@ +/** + @file hdr.h + @brief A helper file with runtime specific includes used by all files in the + library. + $Revision$ + $HeadURL$ + */ +#ifndef HDR_H +#define HDR_H + +#include +#include +#include +#include +#include +#include +#include "exn.h" +#include "mem.h" + +#endif /* HDR_H */ diff --git a/source/string/str.c b/source/string/str.c index d95ba17..6b64233 100644 --- a/source/string/str.c +++ b/source/string/str.c @@ -5,7 +5,6 @@ $HeadURL$ */ #include "str.h" -#include /* Forward declare our struct */ struct str_t diff --git a/source/string/str.h b/source/string/str.h index 95d2c2e..1a6a15a 100644 --- a/source/string/str.h +++ b/source/string/str.h @@ -11,9 +11,7 @@ extern "C" { #endif -#include -#include -#include "mem.h" +#include "rt.h" /* Forward declare our struct */ struct str_t; diff --git a/source/vector/vec.c b/source/vector/vec.c index 5295447..4573725 100644 --- a/source/vector/vec.c +++ b/source/vector/vec.c @@ -5,10 +5,6 @@ $HeadURL$ */ #include "vec.h" -#include "mem.h" -#include -#include -#include static void vec_free(void* p_vec); diff --git a/source/vector/vec.h b/source/vector/vec.h index 30242c5..2ec79ca 100644 --- a/source/vector/vec.h +++ b/source/vector/vec.h @@ -1,16 +1,18 @@ /** @file vec.h - @brief TODO: Describe this file + @brief A vector implementation. $Revision$ $HeadURL$ */ #ifndef VEC_H #define VEC_H -#include +#ifdef __cplusplus +extern "C" { +#endif + +#include "rt.h" #include -#include -#include /** A vector implementation */ typedef struct { @@ -19,10 +21,6 @@ typedef struct { void** p_buffer; /*< Pointer to the array */ } vec_t; -#ifdef __cplusplus -extern "C" { -#endif - /** The default capacity of the vector if no initializing elements have been * provided. */ #ifndef DEFAULT_VEC_CAPACITY