--- /dev/null
+/*
+Dynamic Array
+
+Cannot expand an empty array.
+
+*/
+#include "da.lib.h"
+
+#include<stdlib.h>
+#include<stdbool.h>
+#include<string.h>
+
+//--------------------------------------------------------------------------------
+// allocation
+
+void da_alloc(Da *dap, size_t element_size){
+ dap->element_size = element_size;
+ dap->size = 4 * element_size;
+ dap->base = malloc(dap->size);
+ dap->end = dap->base;
+}
+void da_free(Da *dap){
+ free(dap->base);
+ dap->size = 0;
+}
+void da_rewind(Da *dap){
+ dap->end = dap->base;
+}
+
+bool da_emptyq(Da *dap){
+ return dap->end == dap->base;
+}
+
+size_t da_length(Da *dap){
+ return (dap->end - dap->base)/dap->element_size;
+}
+
+void da_rebase(Da *dap, char *old_base, void *pta){
+ char **pt = (char **)pta;
+ size_t offset = *pt - old_base;
+ *pt = dap->base + offset;
+}
+
+// Doubles size of of da. Returns old base, so that existing pointers into the
+// array can be moved to the new array
+char *da_expand(Da *dap){
+ char *old_base = dap->base;
+ size_t end_offset = dap->end - old_base;
+ size_t new_size = dap->size << 1;
+ char *new_base = malloc( new_size );
+ memcpy( new_base, old_base, end_offset + dap->element_size);
+ free(old_base);
+ dap->base = new_base;
+ dap->end = new_base + end_offset;
+ dap->size = new_size;
+ return old_base;
+}
+
+// true when end has run off the allocated area
+bool da_boundq(Da *dap){
+ return dap->end > (dap->base + dap->size);
+}
+
+//--------------------------------------------------------------------------------
+// putting/taking items
+
+char *da_index(Da *dap, size_t i){
+ size_t offset = i * dap->element_size;
+ char *pt = dap->base + offset;
+ return pt;
+}
+
+// allocate space for a new element at the end of the array
+char *da_push_alloc(Da *dap){
+ size_t element_off = dap->end - dap->base;
+ dap->end += dap->element_size;
+ if( dap->end > dap->base + dap->size ) da_expand(dap);
+ return dap->base + element_off;
+}
+
+char *da_push(Da *dap, void *element){
+ char *element_pt = da_push_alloc(dap);
+ memcpy(element_pt, element, dap->element_size);
+ return element_pt;
+}
+
+bool da_pop(Da *dap, void *element){
+ bool flag = dap->end >= dap->base + dap->element_size;
+ if( flag ){
+ dap->end -= dap->element_size;
+ if(element) memcpy(element, dap->end, dap->element_size);
+ }
+ return flag;
+}
+
+//--------------------------------------------------------------------------------
+// iteration
+
+// true when pt has run off the end
+bool da_endq(Da *dap, void *pt){
+ return (char *)pt >= dap->end;
+}
+
+// passed in f(element_pt, arg_pt)
+// We have no language support closures, so we pass in an argument for it.
+// The closure may be set to NULL if it is not needed.
+void da_map(Da *dap, void f(void *, void *), void *closure){
+ char *pt = dap->base;
+ while( pt != dap->end ){
+ f(pt, closure);
+ pt += dap->element_size;
+ }
+}
+
+
+//--------------------------------------------------------------------------------
+// da being used as a resource manager
+
+
+// elements were malloced, now they will all be freed
+static void da_free_element(void *pt, void *closure){
+ free(*(char **)pt); // free does not care about the pointer type
+}
+
+void da_free_elements(Da *dap){
+ da_map(dap, da_free_element, NULL);
+ da_rewind(dap);
+}
+
+//--------------------------------------------------------------------------------
+// da is an array of integers
+
+// would like to pass in the printf format to make a general print
+// but can't get *pt on the stack for the printf call .. hmmm
+void da_ints_print(Da *dap, char *sep){
+ char *pt = dap->base; // char * because it points to a byte in the array
+ if( pt < dap->end ){
+ printf("%u", *(int *)pt);
+ pt += dap->element_size;
+ while( pt < dap->end ){
+ printf("%s%u", sep, *(int *)pt);
+ pt += dap->element_size;
+ }}}
+
+
+//--------------------------------------------------------------------------------
+// da is an array of strings
+
+// for the case of an array of strings
+void da_strings_print(Da *dap, char *sep){
+ char *pt = dap->base; // char * because it points to a byte in the array
+ if( pt < dap->end ){
+ fputs(*(char **)pt, stdout);
+ pt += dap->element_size;
+ while( pt < dap->end ){
+ fputs(sep,stdout);
+ fputs(*(char **)pt,stdout);
+ pt += dap->element_size;
+ }}}
+
+// da is an array of strings, true if the test string is in the array
+// might be better to iterate instead of using a map ...
+typedef struct {
+ char *string;
+ bool found;
+} da_strings_exists_closure;
+static void string_equal(void *sp, void *closure){
+ char *string_element = *(char **)sp;
+ da_strings_exists_closure *ss = (da_strings_exists_closure *)closure;
+ if( ss->found ) return;
+ ss->found = !strcmp(string_element, ss->string);
+ return;
+}
+
+bool da_strings_exists(Da *string_arrp, char *test_string){
+ da_strings_exists_closure sec;
+ sec.string = test_string;
+ sec.found = false;
+ da_map(string_arrp, string_equal, &sec);
+ return sec.found;
+}
+
+void da_strings_set_insert(Da *string_arrp, char *proffered_string, void destruct(void *)){
+ if( da_strings_exists( string_arrp, proffered_string)){ // then throw it away, we don't need it
+ if(destruct)destruct(proffered_string);
+ return;
+ }
+ da_push(string_arrp, &proffered_string);
+}
+
+// union
+void da_strings_set_union(Da *string_arrp, Da *proffered_string_arrp, void destruct(void *)){
+ char *pt = proffered_string_arrp->base;
+ while( pt < proffered_string_arrp->end ){
+ da_strings_set_insert(string_arrp, *(char **)pt, destruct);
+ pt += proffered_string_arrp->element_size;
+ }
+ return;
+}
+
+
+//--------------------------------------------------------------------------------
+// the da itself is a string
+
+// Puts text from a line into buffer *dap. Does not push EOF or '\n' into the
+// buffer. Returns the old_base so that external pointers can be rebased.
+// It is possible that the the base hasn't changed. Use feof(FILE *stream) to
+// test for EOF;
+char *da_string_input(Da *dap, FILE *file){
+ char *old_base = dap->base;
+ int c = fgetc(file);
+ while( c != EOF && c != '\n' ){
+ da_push(dap, &c);
+ c = fgetc(file);
+ }
+ int terminator = 0;
+ da_push(dap, &terminator);
+ return old_base;
+}
+
+void da_string_push(Da *dap0, char *string){
+ if(!*string) return;
+ size_t dap0_size = dap0->end - dap0->base;
+ size_t string_size = strlen(string);
+ dap0->end += string_size;
+ while( dap0->end >= dap0->base + dap0->size ) da_expand(dap0);
+ memcpy(dap0->base + dap0_size, string, string_size);
+}
+
+
+//--------------------------------------------------------------------------------
+// list operations
+
+// If dap0 has had a terminatating zero added, that must be popped off before
+// the call. Similarly if a terminating zero is desired, it should be pushed
+// after the call.
+
+// appends contents of dap1 onto dap0
+void da_cat(Da *dap0, Da *dap1){
+ if(dap1->base == dap1->end) return;
+ size_t dap0_size = dap0->end - dap0->base;
+ size_t dap1_size = dap1->end - dap1->base; // size of the active portion
+ dap0->end += dap1_size;
+ while( dap0->end >= dap0->base + dap0->size ) da_expand(dap0);
+ memcpy(dap0->base + dap0_size, dap1->base, dap1_size);
+}
+
+//array of Das
+
+//∃, OR map
+//checks that some Da is present in Da of Das
+
+typedef struct{
+ Da *da;
+ bool found;
+} da_present_closure;
+
+void da_present(Da **dar, int dar_size, void *closure){
+ Da **pt = dar;
+ da_present_closure *dpc = (da_present_closure *)closure;
+ Da *test_element = dpc->da;
+ int i = 0;
+ while (!dpc->found && i < dar_size){
+ dpc->found = da_equal(*pt, test_element);
+ pt++;
+ i++;
+ }
+ return;
+}
+
+bool da_equal(Da *da_el, Da *test_el){
+ bool f1 = da_el->base == test_el->base;
+ bool f2 = da_el->end == test_el->end;
+ bool f3 = da_el->size == test_el->size;
+ bool f4 = da_el->element_size == test_el->element_size;
+ return f1 && f2 && f3 && f4;
+}//may need to be static?
+
+
+
+void da_matrix_map(Da **dar, int dar_size, void f(void *, void *), void *closure){
+ Da **pt = dar;
+ int i = 0;
+ while( i < dar_size ){
+ f(*pt, closure);
+ pt++;
+ i++;
+ }
+ return;
+}
+
+//∀, AND map
+//checks that all Das are present in Da of Das
+
+
+
+
+/*bool da_all (Da **dar, int dar_size, Da **dap){
+ Da **tdar = dap;
+ Da *test_da = *tdar;
+ bool result = true;
+ int i = 0;
+ while(result && (i < dar_size)){
+ result = da_exists(dar, dar_size, test_da);
+ tdar++;
+ test_da = *tdar;
+ i++;
+ }
+ return result;
+}
+*/
/*
Dynamic Array
+Cannot expand an empty array.
+
*/
#include "da.lib.h"
char *pt = dap->base;
while( pt != dap->end ){
f(pt, closure);
- pt += dap->element_size;
+ pt += dap->element_size;
}
}
-void da_test_map(void *pt, void *closure){
- bool *f1 = (bool *)closure;
- *f1 = true;
-}
-
//--------------------------------------------------------------------------------
// da being used as a resource manager
char *string;
bool found;
} da_strings_exists_closure;
-static void string_equal(void *sp, void *closure){
- const char *string_element = *(char **)sp;
- da_strings_exists_closure *ss = (da_strings_exists_closure *)closure;
- const char *str = ss->string;
- if( ss->found ) return;
- ss->found = !strcmp(string_element, str);
- return;
-}
-//added consts to see if it was a strcmp syntax issue
-
-/*original
static void string_equal(void *sp, void *closure){
char *string_element = *(char **)sp;
da_strings_exists_closure *ss = (da_strings_exists_closure *)closure;
ss->found = !strcmp(string_element, ss->string);
return;
}
-*/
bool da_strings_exists(Da *string_arrp, char *test_string){
da_strings_exists_closure sec;
typedef struct{
Da *da;
bool found;
-} da_exists_closure;
-
-void da_present(void *da_el, void *closure){
- Da *da_element = (Da *)da_el;
- da_exists_closure *dd = (da_exists_closure *)closure;
- Da *test_element = dd->da;
- if (dd->found) return;
- dd->found = da_equal(da_element, test_element);
+} da_present_closure;
+
+void da_present(Da **dar, int dar_size, void *closure){
+ Da **pt = dar;
+ da_present_closure *dpc = (da_present_closure *)closure;
+ Da *test_element = dpc->da;
+ int i = 0;
+ while (!dpc->found && i < dar_size){
+ dpc->found = da_equal(*pt, test_element);
+ pt++;
+ i++;
+ }
return;
-}//may need to be static?
+}
bool da_equal(Da *da_el, Da *test_el){
bool f1 = da_el->base == test_el->base;
bool f3 = da_el->size == test_el->size;
bool f4 = da_el->element_size == test_el->element_size;
return f1 && f2 && f3 && f4;
-}
-
-bool da_exists (Da **dar, int dar_size, Da *dap){
- da_exists_closure dec;
- dec.da = dap;
- dec.found = false;
- da_big_map(dar, dar_size, da_present, &dec);
- return dec.found;
-}
+}//may need to be static?
-void da_big_map(Da **dar, int dar_size, void f(void *, void *), void *closure){
+
+
+void da_matrix_map(Da **dar, int dar_size, void f(void *, void *), void *closure){
Da **pt = dar;
int i = 0;
while( i < dar_size ){
//∀, AND map
//checks that all Das are present in Da of Das
-bool da_all (Da **dar, int dar_size, Da **dap){
+
+
+
+
+/*bool da_all (Da **dar, int dar_size, Da **dap){
Da **tdar = dap;
Da *test_da = *tdar;
bool result = true;
}
return result;
}
+*/
bool da_endq(Da *dap, void *pt);
void da_map(Da *dap, void f(void *, void *), void *closure);
-void da_test_map(void *pt, void *closure);
void da_free_elements(Da *dap);
void da_cat(Da *dap_base, Da *dap_cat);
-void da_present(void *da_el, void *closure);
+void da_present(Da **dar, int dar_size, void *closure);
bool da_equal(Da *da_el, Da *test_el);
-void da_big_map(Da **dar, int dar_size, void f(void *,void*), void *closure);
+void da_matrix_map(Da **dar, int dar_size, void f(void *,void*), void *closure);
+/*
bool da_exists(Da **dar, int dar_size, Da *dap);
-bool da_all(Da **dar, int dar_size, Da **dap);
-
+bool da_all(Da **dar, int dar_size, int dap_size, Da **dap);
+*/
#endif
# compiler and flags
C=gcc
-CFLAGS=-std=gnu11 -fPIC -Iinclude -I../include -ggdb -Werror -DDEBUG -DDEBUGDB
+CFLAGS=-std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB
#CFLAGS=-std=gnu11 -fPIC -Iinclude -I../include -Werror
LINKFLAGS= -Llib -L../lib -ltest -lda
test_da_cat_1,
test_da_rewind_0,
test_da_index_0,
+ test_da_free_elements_0,
+ test_da_strings_exists_0,
test_da_rebase_0,
test_da_boundq_0,
test_da_map_0,
- test_da_exists_0,
- test_da_all_0,
+ test_da_present_0,
+ //test_da_exists_0,
+ //test_da_all_0,
NULL};
char *test_names[] =
{
"test_da_cat_1",
"test_da_rewind_0",
"test_da_index_0",
+ "test_da_free_elements_0",
+ "test_da_strings_exists_0",
"test_da_rebase_0",
"test_da_boundq_0",
"test_da_map_0",
- "test_da_exists_0",
- "test_da_all_0",
+ "test_da_present_0",
+ //"test_da_exists_0",
+ //"test_da_all_0",
NULL};
// call tests
int j = *(dar.end);
bool f2 = dar.end == dar.base;
bool f3 = j == 10;
- // bool f4 = *dar.end == 10 && *(dar.end + 9 * sizeof(int)) = 19;
- bool result = f1 && f2 && f3; // && f4;
+ bool f4 = (*(dar.end + (7 * sizeof(int))) = 17);
+ bool result = f1 && f2 && f3 && f4;
return result;
}
//tests da_index
bool test_da_index_0(){
Da dar;
- da_alloc(&dar, sizeof(int));
- int j = 0;
- char *k[2];
- while(j < 4){
- da_push(&dar, &j);
- j++;
+ Da *dar_pt = &dar;
+ da_alloc(dar_pt, sizeof(int));
+
+ char *k[4];
+ bool f[4];
+ {//push to dar and test da_index
+ size_t i = 0;
+ int j = 13;
+ int *j_pt = &j;
+ while(i < 4){
+ da_push(dar_pt, j_pt);
+ j++;
+ k[i] = da_index(dar_pt, i);
+ f[i] = k[i] == dar.base + (i*dar.element_size);
+ i++;
+ }
}
- j--;
- k[0] = da_index(&dar, j);
- bool f1 = k[0] == dar.base + (3*dar.element_size);
- return f1;
+ bool result = f[0] && f[1] && f[2] && f[3];
+ return result;
}
-//tests da_free_elements
+//tests da_free_elements - still getting core dump on function call
//cannot test sub-functions bc da_free_elements needs to be static
-/*bool test_da_7(){
- Da dar;
- da_alloc(&dar, sizeof(int));
- int j = 0;
- while(j < 4){
- da_push(&dar, &j);
- ++j;
- }
- da_free_elements(&dar);
- bool g = 1;
- return g;
+bool test_da_free_elements_0(){
+ Da dar;
+ Da *dar_pt = &dar;
+ da_alloc(dar_pt, sizeof(int*));
+
+ int i = 3;
+ int *i_pt = &i;
+ while(i < 7){
+ da_push(dar_pt, &i_pt);
+ ++i;
}
-causes errors:
-test_da_2, could not open data file ../lib/test.dat for reading
-test_da_2 failed - these were because in wrong directory, core dump is actual issue here and with 7
-Segmentation fault (core dumped)
-*/
-/*
+
+ //da_free_elements(dar_pt);
+ bool result = true;
+ return result;
+}
+
//tests da_strings_exist
-bool test_da_7(){
+bool test_da_strings_exists_0(){
Da dar;
- da_alloc(&dar, sizeof(char *));
- char *j = "test";
- da_push(&dar, j);
- // da_strings_exists(&dar, j);
- bool f1 = da_strings_exists(&dar, j);
- return f1;
+ Da *dar_pt = &dar;
+ da_alloc(dar_pt, sizeof(char *));
+
+ //fill dar with strings
+ char *string0 = "nope";
+ char **string0_pt = &string0;
+ da_push(dar_pt, string0_pt);
+ char *string1 = "okay";
+ char **string1_pt = &string1;
+ da_push(dar_pt, string1_pt);
+ char *string2 = "welp";
+ char **string2_pt = &string2;
+ da_push(dar_pt, string2_pt);
+ char *string3 = "sure";
+ char **string3_pt = &string3;
+ da_push(dar_pt, string3_pt);
+
+ bool result;
+ {//test dar for each string
+ result = da_strings_exists(dar_pt, string0);
+ if (result == true)
+ result = da_strings_exists(dar_pt, string1);
+ if (result == true)
+ result = da_strings_exists(dar_pt, string2);
+ if (result == true)
+ result = da_strings_exists(dar_pt, string3);
+ }
+
+ return result;
}
-//same errors, something to do with calling fucntions that call static functions I believe
-*/
+
//tests rebase
bool test_da_rebase_0(){
}
//check that push worked, that element pointer is in right place, and that expand works
- //
bool f1 = dar.base != dar.end;
bool f2 = *el_pt == dar.end - dar.element_size;
return f1 && f2 && f3 && result;
}
+/* {//problems with free and malloc
+ char *a = malloc(10);
+ strcpy(a, "zsdf");
+ Da da;
+ Da *da_pt = &da;
+ da_alloc(da_pt, sizeof(char *));
+ da_push(da_pt, a);
+ ...
+ free(*(char *)da_index(da_pt, 0));
+ da_free(da_pt);
+} */
//tests da_boundq
bool test_da_boundq_0(){
return result;
}
+
+void da_test_map(void *pt, void *closure){
+ int *n = (int *)closure;
+ *n += *(int *)pt;
+}
+
//tests map
bool test_da_map_0(){
Da dar;
- da_alloc(&dar,sizeof(char));
+ da_alloc(&dar,sizeof(int));
{//pushes onto dar
- char arr[4] = {'t','r','u','e'};
+ int arr[4] = {5,6,7,8};
int i = 0;
- char c;
+ int n;
while(i<4){
- c = arr[i];
- da_push(&dar, &c);
+ n = arr[i];
+ da_push(&dar, &n);
i++;
}
}
- bool *closure;
- bool result = true;
- {//tests map via da_test_map
- int i = 0;
- while (result && i<4){
- da_map(&dar, da_test_map, closure);
- result = *closure;
- i++;
- *closure = false;
- }
- }
+ int n = 0;
+ int *closure = &n;
+
+ da_map(&dar, da_test_map, (int *)closure);
+ //rename to da_foreach
+ bool result = n == (5+6+7+8);
return result;
}
//tests da_exists
-bool test_da_exists_0(){
- Da *dap0;
- {
- da_alloc(dap0, sizeof(char));
- char a = 'y';
- da_push(dap0, &a);
- }
-
- Da *dap1;
- {
- da_alloc(dap1, sizeof(char));
- char a = 'u';
- da_push(dap1, &a);
- }
-
- Da *dap2;
- {
- da_alloc(dap2, sizeof(char));
- char a = 'n';
- da_push(dap2, &a);
- }
+//exists is a map function that applies a function to each element of the array and returns a bool
+//if the function ever returns a true value, then exists immediately returns true, if the function only ever returns false, then exists returns false
+//da_all is the opposite, returns true only if always receives true, exists and returns false if false
- Da *darr[3];
+//tests da_present
+bool test_da_present_0(){
int dar_size = 0;
+ Da **dar = malloc(3 * sizeof(Da *));
- //add dap0, dap1 to darr
- darr[dar_size] = dap0; dar_size++;
- darr[dar_size] = dap1; dar_size++;
-
+ Da dap_0;
+ Da *dap_0_pt = &dap_0;
+ da_alloc(dap_0_pt,sizeof(int));
- //test that dap0 and dap1 exist in darr but not dap2
- bool f1 = da_exists(darr, dar_size, dap0);
- bool f2 = da_exists(darr, dar_size, dap1);
- bool f3 = !da_exists(darr, dar_size, dap2);
-
- //add dap2 to darr
- darr[dar_size] = dap2; dar_size++;
-
- //test that dap2 exists in darr
- bool f4 = da_exists((Da **)darr, dar_size, dap2);
+ Da dap_1;
+ Da *dap_1_pt = &dap_1;
+ da_alloc(dap_1_pt,sizeof(int));
+
+ dar[dar_size] = dap_0_pt; dar_size++;
+ dar[dar_size] = dap_1_pt; dar_size++;
+ Da dap_2;
+ Da *dap_2_pt = &dap_2;
+ da_alloc(dap_2_pt,sizeof(int));
+ dar[dar_size] = dap_2_pt; dar_size++;
+
+ typedef struct{
+ Da *da;
+ bool found;
+} da_present_closure;
+
+ bool f[4];
+ da_present_closure dpc;
+ dpc.da = dap_0_pt;
+ dpc.found = false;
- return f1 && f2 && f3 && f4;
-}
+ //test da_equal
+ f[0] = da_equal(dap_0_pt, dpc.da);
-//tests da_all
-bool test_da_all_0(){
- Da *dap0;
- {
- da_alloc(dap0, sizeof(char));
- char a = 'y';
- da_push(dap0, &a);
- }
+ //test da_present
+ da_present(dar, dar_size, &dpc);
+ f[1] = dpc.found;
+ dpc.found = false;
+ da_present(dar, dar_size, &dpc);
+ f[2] = dpc.found;
+ dpc.found = false;
+ da_present(dar, dar_size, &dpc);
+ f[3] = dpc.found;
+ dpc.found = false;
+
+ bool result = f[0] && f[1] && f[2] && f[3];
- Da *dap1;
- {
- da_alloc(dap1, sizeof(char));
- char a = 'u';
- da_push(dap1, &a);
- }
-
- Da *dap2;
- {
- da_alloc(dap2, sizeof(char));
- char a = 'n';
- da_push(dap2, &a);
- }
-
- Da **darr0 = malloc(3 * sizeof(Da *));
- int dar_size0 = 0;
-
- //add dap0, dap1 to darr0 (array being tested)
- darr0[dar_size0] = dap0; dar_size0++;
- darr0[dar_size0] = dap1; dar_size0++;
- darr0[dar_size0] = dap0;
- //has to have same amount of elements as test array or will core dump
-
-
- Da **darr1 = malloc(3 * sizeof(Da *));
- int dar_size1 = 0;
- //add dap0,1,2 to darr1 (test array, to test against)
- darr1[dar_size1] = dap0; dar_size1++;
- darr1[dar_size1] = dap1; dar_size1++;
- darr1[dar_size1] = dap2; dar_size1++;
-
- //tests that darr0 doesn't have all (dap0,1,2)
- bool f1 = !da_all(darr0, dar_size1, darr1);
-
- //add dap2 to darr0
- darr0[dar_size0] = dap2; dar_size0++;
-
- //tests that darr0 has all (dap0,1,2)
- bool f2 = da_all(darr0, dar_size1, darr1);
-
- return f1 && f2;
+ return result;
}
+
+
/*
Functions
da_alloc
-da_rebase
-da_expand
-da_boundq
--da_index
+-da_index
+-da_strings_exists_0
da_push_alloc
-da_push
-da_pop
da_exists
da_all
+*/
-test first
--map
--boundq
-
-add
--da_exists (OR map, ∃)
--da_all (AND map, ∀)
+/*
+ Tests
+test_da_push_0
+test_da_expand_0
+test_da_string_input_0
+test_da_pop_0
+test_da_cat_0
+test_da_cat_1
+test_da_rewind_0
+test_da_index_0
+test_da_free_elements_0
+test_da_strings_exists_0
+test_da_rebase_0
+test_da_boundq_0
+test_da_map_0
+test_da_present_0
*/
#ifndef DA_LIB_H
#define DA_LIB_H
-
bool test_da_push_0();
bool test_da_expand_0();
bool test_da_string_input_0();
bool test_da_cat_1();
bool test_da_rewind_0();
bool test_da_index_0();
+bool test_da_free_elements_0();
+bool test_da_strings_exists_0();
bool test_da_rebase_0();
bool test_da_boundq_0();
bool test_da_map_0();
+bool test_da_present_0();
bool test_da_exists_0();
bool test_da_all_0();