--- /dev/null
+Explanation of process for using accounting code.
+
+ First, acc_open(&acc_live_channels, mode); ---acc_NULL or acc_SELF only, decide whether to track memory allocation for channels themselves
+
+ To begin an accounting channel, declare an Acc_channel and initialize it by passing a pointer to it into acc_open. You will also need to pass in a Mode.
+
+-acc_NULL does not track
+-acc_BALANCE will give you a count of outstanding mallocs and spurious frees when reported
+-acc_FULL will give you a robust accounting with a list of up to 10 outstanding/spurious pointers, then it will default to a count instead and just give the first 10 addresses.
+-acc_SELF is solely for the accounting software to account for its own memory allocation, therefore listing outstanding/spurious pointers to Acc_channels in the same format as acc_FULL.
+
+ When initializing a Da, you must pass in a pointer to the Da, its element size, and a pointer to the (already initialized) Acc_channel on which it will be stored into da_init. Among its other initialization tasks, this function will call acc_malloc for the base pointer of the Da with the appropriate channel.
+ When allocating memory for anything else in the program, you must pass the size of the memory to be allocated as well as the channel on which it is to be tracked to acc_malloc.
+
+ To free a Da, pass a pointer to the Da into da_free. It will automatically call acc_free for the base pointer, set the size to 0 and set the channel to NULL.
+ To free anything other else in the program, simply call acc_free, passing in the pointer and the channel the pointer is being tracked in. This will zero it out from the channel, call da_pts_nullify to clean up any zeroes at the end of the channel, and then free the pointer.
+
+ To find out if there are any memory leaks in a particular channel, call acc_report with a pointer to the Acc_channel as the argument. Depending on the channel's mode, it will pretty print a current report of memory allocation and frees. If you call a report on acc_live_channels and it is set to Mode acc_SELF, it will report on the memory currently in use for the accounting system itself.
+
+ When finished with a channel, call acc_close and pass in the channel pointer. This will free up the memory used by it and remove it from the acc_live_channels outstanding_malloc list if there is SELF tracking on. Any allocation information being tracked by this channel will be lost, so it is advised to call acc_report before deciding whether to free the channel.
--- /dev/null
+#ifndef ACC_LIB_H
+#define ACC_LIB_H
+
+typedef struct AccChannel_struct AccChannel;
+typedef struct Da_struct Da; // Da_struct defined in da.lib.h
+
+enum Mode_enum{acc_NULL, acc_BALANCE, acc_FULL, acc_SELF};//0,1,2,3
+typedef enum Mode_enum Mode;
+
+struct AccChannel_struct{
+ Da *outstanding_malloc;
+ Da *spurious_free;
+ Mode mode;
+}; //name instances of channels with handles
+
+
+extern AccChannel acc_live_channels;//acc_NULL or acc_SELF to track acc channels or not, other options return invalid upon report
+
+//function declarations for accounting
+ AccChannel *acc_open(AccChannel *channel, Mode mode);//initializes channel structs
+ void *acc_malloc(size_t size, AccChannel *channel);//works for things besides Das too
+ void acc_free(void *pt, AccChannel *channel);//works for things besides Das too
+ AccChannel *acc_report(AccChannel *channel);//reports on channels based on mode
+ void acc_close(AccChannel *channel);//frees channel itself
+
+ void *crash_and_burn_malloc(size_t size);//sends error message in case of accidental regular malloc
+ void crash_and_burn_free(void *);// sends error message in case of accidental regular free
+
+
+#endif
--- /dev/null
+#ifndef DA_LIB_H
+#define DA_LIB_H
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+typedef struct AccChannel_struct AccChannel; // AccChannel_struct defined in acc.lib.h
+typedef struct Da_struct Da;
+
+struct Da_struct{
+ char *base;
+ char *end; // one byte/one element off the end of the array
+ size_t size; // size >= (end - base) + 1;
+ size_t element_size;
+ AccChannel *channel;
+};
+
+// constructors / destructors
+//
+ Da *da_init(Da *dap, size_t element_size, AccChannel *channel);//calls da_malloc for base pointer
+ void da_free(Da *dap);
+ void da_rewind(Da *dap);
+ void da_rebase(Da *dap, char *old_base, void *pta);
+ char *da_expand(Da *dap);
+ bool da_boundq(Da *dap);
+ void da_erase(Da *dap);
+
+// status / attributes
+//
+ bool da_is_empty(Da *dap);
+ bool da_equal(Da *da_0, Da *da_1);
+ size_t da_length(Da *dap);
+ bool da_length_equal(Da *dap0, Da *dap1);
+
+// accessing
+//
+ char *da_index(Da *dap, size_t i);
+ char *da_push(Da *dap, void *element);
+ bool da_pop(Da *dap, void *element);
+
+// iteration, f is given a pointer to an element and a pointer to the closure
+ bool da_endq(Da *dap, void *pt);
+ bool da_right_bound(Da *dap, void *pt);
+ void da_foreach(Da *dap, void f(void *, void *), void *closure); //used to be da_map
+ bool da_exists(Da *dap, bool f(void *, void*), void *closure);
+ bool da_all(Da *dap, bool f(void *, void*), void *closure);
+
+// elements are pointers
+// would be better if exists returned NULL or a pointer to the existing element-
+ void *da_pts_exists(Da *dap, void *test_element);
+ void da_pts_free_all(Da *dap); // calls free on all elements
+ void da_pts_nullify(Da *dap, void **ept); // sets *ept to NULL, pops all NULLs from top of stack
+
+// elements are integers
+ void da_ints_print(Da *dap, char *sep);
+ bool da_integer_repeats(Da *dap);
+ int da_integer_sum(Da *dap);
+
+// the array itself is a string
+// careful if you add a null terminator it will become part of the da_string, affects iteration etc.
+ char *da_string_input(Da *dap, FILE *file);
+ void da_string_push(Da *dap0, char *string);
+ void da_cat(Da *dap_base, Da *dap_cat);
+
+// when the array holds pointers to C strings
+ void da_strings_print(Da *dap, char *sep);
+ bool da_strings_exists(Da *string_arrp, char *test_string);
+ void da_strings_set_insert(Da *string_arrp, char *proffered_string, void destruct(void *));
+ void da_strings_set_union(Da *string_arrp, Da *proffered_string_arrp, void destruct(void *));
+
+#endif
+
.PHONY: lib
lib:
cp $(SRCDIR)/da.lib.h $(INCDIR)/da.h
- cp $(SRCDIR)/da_na.lib.h $(INCDIR)/da_na.h
cp $(SRCDIR)/acc.lib.h $(INCDIR)/acc.h
$(MAKE) $@
/*
dynamic memory accounting
-Alternative version of malloc and free that will invoke accounting for pointers that are allocated
-but not freed, or freed but not allocated.
-
*/
-
-//new sed file for changes to rest of project
-//da_alloc -> da_init
-//da_map -> da_foreach
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
#include "da.lib.h"
-#include "da_na.lib.h"
#include "acc.lib.h"
-Da *acc_live_checkers = NULL;
+//-----------------------------------------------------------------
+//function definitions for accounting
-void acc_init(){ //open
- if( acc_live_checkers == NULL ){
- acc_live_checkers = malloc(sizeof(Da));
- da_na_init(acc_live_checkers, sizeof(AccChecker));
+AccChannel *acc_open(AccChannel *channel, Mode mode){//acc init
+ if( channel == &acc_live_channels ) {//avoid pushing channel tracker onto itself
+ Da os; Da sf;
+ channel->outstanding_malloc = da_init(&os, sizeof(void *), NULL);
+ channel->spurious_free = da_init(&sf, sizeof(void *), NULL);
+ channel->mode = mode;
+ return channel;
}
- AccChecker *acp = malloc(sizeof(AccChecker));
- da_na_alloc(&(acp->outstanding_malloc), sizeof(void *));
- da_na_alloc(&(acp->spurious_free), sizeof(void *));
- da_na_push(acc_live_checkers, acp);
-}
-void acc_free(){//close
-
-}
-void acc_report(){
-}
-
-void *acc_malloc(size_t mem_size){
- void *an_allocation_pt = malloc(mem_size);
-
- // push an_allocation_pt on to all live checkers
- AccChecker *acp = acc_live_checkers->base;
- while(!da_endq(acc_live_checkers, acp)){
- if(*acp) da_na_push(&(acp->outstanding_malloc), an_allocation_pt);
- acp++;
+ else if( acc_live_channels.mode == acc_NULL ){//accounting NULL
+ //channel = (AccChannel *)acc_malloc(sizeof(AccChannel), NULL);//accounting channel still on the heap but not tracked in SELF mode
+ Da os; Da sf;
+ channel->outstanding_malloc = da_init(&os, sizeof(void *), NULL);
+ channel->spurious_free = da_init(&sf, sizeof(void *), NULL);
+ channel->mode = mode;
+ return channel;
+ }
+ else if( acc_live_channels.mode == acc_SELF ){//accounting tracks itself
+ channel = (AccChannel *)acc_malloc(sizeof(AccChannel), &acc_live_channels);
+ Da os; Da sf;
+ channel->outstanding_malloc = da_init(&os, sizeof(void *), NULL);
+ channel->spurious_free = da_init(&sf, sizeof(void *), NULL);
+ channel->mode = mode;
+ return channel;
+ }
+ else{ //cerr, optional acc_live_channels only tracks channels, not other mallocs/frees
+ return channel;
}
-
- return an_allocation_pt;
}
-
-void *acc_malloc(size_t mem_size){//pushes pointer onto heap_acc before mallocing
- void *temp = malloc(mem_size);
- da_na_push(&heap_acc, &temp);
- return (void *)temp;
+void *acc_malloc(size_t size, AccChannel *channel){
+ void *an_allocation_pt = malloc(size);
+ if( channel ) da_push((Da *)(channel->outstanding_malloc), &an_allocation_pt);
+ return (void *)an_allocation_pt;
}
-void acc_free(void *pt){
- if( accounting == true ) {
- void *i = heap_acc.base;
+void acc_free(void *pt, AccChannel *channel){
+ if( channel ){
+ void **i = (void **)(((Da *)(channel->outstanding_malloc))->base);
bool present = false;
- while( i < (void *)heap_acc.end ){
- if( pt == *(void **)i ){//matches and zeroes out pointer from heap_acc
- *(int *)i = 0;
+ while( i < (void **)(((Da *)(channel->outstanding_malloc))->end) ){
+ if( *i == pt ){
+ da_pts_nullify((Da *)(channel->outstanding_malloc), i);
present = true;
- if( (i + heap_acc.element_size) == heap_acc.end ){//pops excess 0s from end of heap_acc
- void *j = i;
- while( (*(int *)j == 0) && ((void *)j >= (void *)heap_acc.base) ){
- da_pop(&heap_acc, NULL);
- j-=heap_acc.element_size;
- }}}
+ }
i++;
}
- if( present == false ) da_push(&extra_frees, &pt);//stores pointer in extra_frees if tried to free one that we didn't count
+ if( present == false ) da_push((Da *)(channel->spurious_free), &pt);
+ }
+ free(pt);
+}
+static void count_balance(void *element, void *closure){
+ int *counter = (int *)closure;
+ if( (void *)element ) (*counter)++;
+}
+static void acc_rep_helper_BALANCE(AccChannel *channel){
+ int count = 0;
+ da_foreach((Da *)channel->outstanding_malloc, count_balance, &count);
+ printf("There are %d outstanding allocations.\n", count);
+ count = 0;
+ da_foreach((Da *)channel->spurious_free, count_balance, &count);
+ printf("There are %d spurious frees.\n", count);
+}
+static void print_pointer(void *element, void *closure){
+ if( element ) printf("%d ", *(int *)element);
+}
+static void acc_rep_helper_FULL(AccChannel *channel){
+ int count = 0;
+ da_foreach((Da *)channel->outstanding_malloc, count_balance, &count);
+ printf("There are %d outstanding mallocs.\n", count);
+ if( count < 10 ){
+ printf("The outstanding allocated pointers are: ");
+ da_foreach((Da *)channel->outstanding_malloc, print_pointer, NULL);
+ printf(".\n");
+ }
+ count = 0;
+ da_foreach((Da *)channel->spurious_free, count_balance, &count);
+ printf("There are %d spurious frees.\n", count);
+ if( count < 10 ){
+ printf("The spuriously freed pointers are: ");
+ da_foreach((Da *)channel->outstanding_malloc, print_pointer, NULL);
+ printf(".\n");
+ }
+}
+AccChannel *acc_report(AccChannel *channel){
+ if( channel->mode == acc_NULL ){
+ printf("Accounting mode is NULL.");
+ return channel;
+ }
+ if( channel->mode == acc_BALANCE ){
+ printf("Accounting mode is BALANCE.\n");
+ if( da_is_empty((Da *)(channel->outstanding_malloc)) && da_is_empty((Da *)(channel->spurious_free)) ){
+ printf("This channel is in balance.");
+ }
+ else{
+ printf("This channel is out of balance.\n");
+ acc_rep_helper_BALANCE(channel);
+ }
+ return channel;
+ }
+ if( channel->mode == acc_FULL ){
+ printf("Accounting mode is FULL.\n");
+ if( da_is_empty((Da *)(channel->outstanding_malloc)) && da_is_empty((Da *)(channel->spurious_free)) ){
+ printf("This channel is in balance.");
+ }
+ else{
+ printf("This channel is out of balance.\n");
+ acc_rep_helper_FULL(channel);
+ }
+ return channel;
+ }
+ if( channel->mode == acc_SELF ){
+ printf("Accounting mode is SELF.\n");
+ if( da_is_empty((Da *)(channel->outstanding_malloc)) && da_is_empty((Da *)(channel->spurious_free)) ){
+ printf("There are no open channels.");
+ }
+ else {
+ printf("The accounting code is out of balance.\n");
+ acc_rep_helper_FULL(channel);
+ }
+ return channel;
}
- free(pt);//frees pointer
}
-bool acc_result(){//returns false if accounting wasn't being used or heap_acc is not empty or if we tried to free more pointers than we malloced for
- if ( accounting == true ){
- bool flag1 = da_empty(&heap_acc);
- bool flag2 = da_empty(&extra_frees);
- return flag1 && flag2;
- } else return false;
+void acc_close(AccChannel *channel){
+ da_free((Da *)(channel->outstanding_malloc));
+ da_free((Da *)(channel->spurious_free));
+ if( (channel != &acc_live_channels)
+ && (acc_live_channels.mode == acc_SELF) ){
+ acc_free(channel, &acc_live_channels);
+ return;
+ }
+ else return;
}
+void *crash_and_burn_malloc(size_t size){}
+void crash_and_burn_free(void *pt){}
+
#ifndef ACC_LIB_H
#define ACC_LIB_H
-typedef struct{
- Da outstanding_malloc;
- Da spurious_free;
-} AccChecker;
-
-extern Da *acc_live_checkers;
-
-#define MALLOC acc_malloc
-#define FREE acc_free
-#define ACCOUNT acc_start()
-#define BALANCE acc_result()
-#define CLOSE_ACC da_na_free(&heap_acc); da_na_free(&extra_frees)
+typedef struct AccChannel_struct AccChannel;
+typedef struct Da_struct Da; // Da_struct defined in da.lib.h
+
+enum Mode_enum{acc_NULL, acc_BALANCE, acc_FULL, acc_SELF};//0,1,2,3
+typedef enum Mode_enum Mode;
+
+struct AccChannel_struct{
+ Da *outstanding_malloc;
+ Da *spurious_free;
+ Mode mode;
+}; //name instances of channels with handles
+
+
+extern AccChannel acc_live_channels;//acc_NULL or acc_SELF to track acc channels or not, other options return invalid upon report
+
+//function declarations for accounting
+ AccChannel *acc_open(AccChannel *channel, Mode mode);//initializes channel structs
+ void *acc_malloc(size_t size, AccChannel *channel);//works for things besides Das too
+ void acc_free(void *pt, AccChannel *channel);//works for things besides Das too
+ AccChannel *acc_report(AccChannel *channel);//reports on channels based on mode
+ void acc_close(AccChannel *channel);//frees channel itself
+
+ void *crash_and_burn_malloc(size_t size);//sends error message in case of accidental regular malloc
+ void crash_and_burn_free(void *);// sends error message in case of accidental regular free
#endif
#include<stdbool.h>
#include<string.h>
-#include "da.lib.h"
#include "acc.lib.h"
+#include "da.lib.h"
//--------------------------------------------------------------------------------
// constructors / destructors
-// this really should be called da_init, as it doesn't do any allocation ...
-void da_alloc(Da *dap, size_t element_size){
+Da *da_init(Da *dap, size_t element_size, AccChannel *channel){
dap->element_size = element_size;
dap->size = 4 * element_size;
- dap->base = MALLOC(dap->size);
+ dap->base = acc_malloc(dap->size, channel);
dap->end = dap->base;
+ dap->channel = channel;
+ return dap;
}
void da_free(Da *dap){
- FREE(dap->base);
+ acc_free(dap->base, dap->channel);
dap->size = 0;
+ dap->channel = NULL;
}
void da_rewind(Da *dap){
dap->end = dap->base;
}
-
void da_rebase(Da *dap, char *old_base, void *pta){
char **pt = (char **)pta;
size_t offset = *pt - old_base;
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 );
+ char *new_base = acc_malloc(new_size, (AccChannel *)(dap->channel));
memcpy( new_base, old_base, end_offset + dap->element_size);
- FREE(old_base);
+ acc_free(old_base, (AccChannel *)(dap->channel));
dap->base = new_base;
dap->end = new_base + end_offset;
dap->size = new_size;
return dap->end > (dap->base + dap->size);
}
-void da_erase(Da *dap){//same as da_free, don't tell anyone
- FREE(dap->base);
- dap->size = 0;
+// erases all the elements in the array
+// a push followed by an erase should work, but I don't think it does right now
+/*
+void da_erase(Da *dap){
+ da_free(Da *dap);
}
+*/
//--------------------------------------------------------------------------------
// status / attributes
-bool da_empty(Da *dap){
+bool da_is_empty(Da *dap){
return dap->end == dap->base;
}
// 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){
+void da_foreach(Da *dap, void f(void *, void *), void *closure){
char *pt = dap->base;
while( pt != dap->end ){
f(pt, closure);
char *pt = dap->base;
bool result = false;
while( (complement? !result : result) && (pt != dap->end) ){
- result = f(pt, closure);
+ result = pred(pt, closure);
pt += dap->element_size;
}
return result;
//--------------------------------------------------------------------------------
// elements are pointers
-
+// elements are pointers
+//
+static bool da_pts_exists_0(void *element, void *test_element){ return element == test_element; }
+void *da_pts_exists(Da *dap, void *test_element){
+ if( da_exists(dap, da_pts_exists_0, test_element) ) return test_element;
+ else return NULL;
+}
+/*
static da_pts_exists_0(void *element, void *pt){ return element == pt; }
bool da_pts_exists(Da *dap, void *test_element){
return da_exists(dap, da_pts_exists_0, test_element);
}
-
-// elements were MALLOCed, now they will all be FREEd
+*/
+// elements were allocated, now they will all be freed
static void da_pts_free_all_0(void *pt, void *closure){
- FREE(*(char **)pt); // FREE does not care about the pointer type
+ acc_free(*(char **)pt, closure);
+ // FREE(*(char **)pt); // FREE does not care about the pointer type
}
void da_pts_free_all(Da *dap){
- da_map(dap, da_pts_free_all_0, NULL);
+ da_foreach(dap, da_pts_free_all_0, dap->channel);
+ // da_map(dap, da_pts_free_all_0, NULL);
da_rewind(dap);
}
// ept points at an element, we set *ept to NULL
// we pop all NULLs off the top of the stack
void da_pts_nullify(Da *dap, void **ept){
- if(ept >= dap->base && ept < dap->end){
+ if(ept >= (void **)(dap->base) && ept < (void **)(dap->end)){
+ // if(ept >= dap->base && ept < dap->end){
*ept = NULL;
}
while(
dap->end > dap->base
&&
- *(void **)(dap->end - dap->element_size) == NULL
- ){
+ // *(void **)(dap->end - dap->element_size) == NULL
+ // ){
+ *(void **)(dap->end - dap->element_size) == NULL){
da_pop(dap, NULL);
}
}
da_strings_exists_closure sec;
sec.string = test_string;
sec.found = false;
- da_map(string_arrp, string_equal, &sec);
+ da_foreach(string_arrp, string_equal, &sec);
return sec.found;
}
}
-//-----------------------------------------------------
-
-
-//-------------------------------------------------------
-
-// all things Da matrix
-// a DaMa (Doubling array Matrix) is a Da whose elements are Da's
-// forms a matrix if you treat what's pointed to by base pointers of the elements of the DaMa as the first column of elements and fill in each row with the contents of the Das
-// The "row major" nomenclature is used to remain consistent with database logic.
-/* Example:
-Da dar0; Da *dap0 = &dar0; da_alloc(dap0, sizeof(int));
-Da dar1; Da *dap1 = &dar1; da_alloc(dap1, sizeof(int));
-Da dama; Da *damp = &dama; da_alloc(damp, sizeof(Da));
-da_push(damp, dap0);
-da_push(damp, dap1);
-*/
-
-Da *da_mat_push_row_alloc(Da *damp){
- size_t row_off = (Da *)(damp->end) - (Da *)(damp->base);
- damp->end += damp->element_size;
- if( damp->end > damp->base + damp->size ) da_expand(damp);
- return (Da *)(damp->base) + row_off;
-}
-Da *da_mat_push_row(Da *damp, Da *dap){// Dama won't track changes to Das after pushing onto rows
- Da *row_pt = da_mat_push_row_alloc(damp);
- memcpy(row_pt, dap, damp->element_size);
- return row_pt;
-}
-
-void da_mat_push_column(Da *damp, Da *dap, void *fill){
- Da *tran = da_mat_transpose(damp, fill);
- da_mat_push_row(tran, dap);
- Da *new_dama = da_mat_transpose(tran, fill);
- //add protection against memory overwrite - expand if necessary
- memcpy(damp, new_dama, new_dama->size);
-}
-
-void da_mat_every_row(Da *damp, void f(void *, void *), void *closure){//like every but for rows instead of elements
- Da *dpt = (Da *)(damp->base);
- while( dpt != (Da *)damp->end ){
- f(dpt, closure);
- dpt++;
- }
-}
-
-// da_mat_every_column uses da_mat_longest and therefore da_mat_longer, written for the purpose of terminating the while loop in the appropriate place
-// will return dap1 if equal, cannot determine equality
-Da *da_mat_longer(Da *dap0, Da *dap1){
- if (da_length(dap0) > da_length(dap1)) return dap0;
- else return dap1;
-}
-// returns Da in DaMa with longest length
-Da *da_mat_longest(Da *damp){
- Da *dap = (Da *)(damp->base);
- Da *longest = (Da *)((damp->base) + sizeof(Da));
- while( dap < (Da *)(damp->end) ){
- longest = da_mat_longer(dap,longest);
- dap++;
- }
- return longest;
-}
-void da_mat_every_column(Da *damp, void f(void *, void *), void *closure){//like every but for columns instead of elements
- Da *dpt = (Da *)(damp->base);
- size_t rows = damp->size/damp->element_size;
- size_t columns = da_length(da_mat_longest(damp));
- size_t j = 0;
- while( j < columns ){
- int *col = MALLOC(sizeof(rows*sizeof(int)));
- size_t i = 0;
- while( i < rows ) {
- if (da_endq(dpt,(dpt->base + j*(dpt->element_size))))
- *(col+i) = 0;
- else *(col+i) = *(dpt->base + j*(dpt->element_size));
- dpt++;
- i++;
- }
- f(col, closure);
- j++;
- }
-}
-
-Da *da_mat_transpose(Da *damp, void *fill){// all Das must have same element type, will sort to integer, char, or char * transpose function
- Da *dap = (Da *)(damp->base);
- Da tran; da_alloc(&tran, sizeof(damp->element_size));
- Da *transpose = &tran;
- if( dap->element_size == sizeof(int) ){
- int *filler = (int *)fill;
- transpose = da_mat_ints_transpose(damp, filler);
- }
- /*else if( dap->element_size == sizeof(char) ){
- char *filler = (char *)fill;
- transpose = da_character_transpose(damp, filler);
- }
- else if( dap->element_size == sizeof(char *) ){
- char **filler = (char **)fill;
- transpose = da_c_string_transpose(damp, filler);
- }*/
- //else error?
- return transpose;
-}
-
-
-//--------------------------------------------------------------------
-// DaMa is a matrix of integers (stored in Das as columns)
-
-// integer repeats across columns
-bool da_mat_all_rows_same_length(Da *damp){
- Da *dap = (Da *)(damp->base);
- Da *pt = dap;
- bool flag = true;
- while( flag && pt != (Da *)(damp->end) ){
- flag = da_length_equal(dap, pt);
- }
- return flag;
-}
-bool da_mat_ints_all_rows_repeat(Da *damp){// if rows are made of repeating integers, then all columns read the same thing
- Da *dpt = (Da *)(damp->base);
- bool flag = false;
- if( da_mat_all_rows_same_length((Da *)damp) ){// columns can't be equal if rows not all same length, will return false
- flag = true;
- while( flag && dpt != (Da *)(damp->end) ){
- flag = da_integer_repeats(dpt); // in "da is array of integers" section
- dpt++;
- }
- return flag;
- }
- else return flag;
-}
-bool da_mat_ints_all_columns_repeat(Da *damp){// rows are repeating in transpose = columns are repeating
- int x = 0; //have to pass in fill for transpose, this nullifies effect same_length test
- Da *test_da = da_mat_transpose(damp, &x);
- return da_mat_ints_all_rows_repeat(test_da);
-}
-bool da_mat_ints_repeats_matrix(Da *damp){// all elements in matrix are same
- bool flag1 = da_mat_ints_all_rows_repeat(damp);
- bool flag2 = da_mat_ints_all_columns_repeat(damp);
- return flag1 && flag2;
-}
-
-// to transpose directly from one DaMa to another
-Da *da_mat_ints_transpose(Da *damp, int *fill){
- size_t rows = damp->size/damp->element_size;
- size_t columns = da_length(da_mat_longest(damp));
- Da *matrix = damp;
- Da tran;
- da_alloc(&tran, sizeof(Da));
- Da *transpose = &tran;
-
- Da *dpt = (Da *)(matrix->base);
- int i = 0, j = 0;
- while( j < columns ){
- Da new_row; da_alloc(&new_row, sizeof(int));
- int *ept = fill;
- while( i < rows ){
- if( !da_endq(dpt, (dpt->base + j*(dpt->element_size))) ){
- *ept = *(dpt->base + j*(dpt->element_size));
- }
- da_push(&new_row, ept);
- dpt++;
- i++;
- }
- da_mat_push_row(transpose, &new_row);
- j++;
- }
- return transpose;
-}
-
-//to create raw matrix image in memory, no longer a Da struct
-int *da_mat_ints_to_raw_image_matrix(Da *damp, int fill){
- size_t rows = damp->size / damp->element_size;
- size_t columns = da_length(da_mat_longest(damp));
- int *matrix = MALLOC(sizeof(rows*columns));//[rows][columns]
- int i = 0;
- Da *dpt = (Da *)(damp->base);
- while( i < rows )
- {
- int *ept = (int *)(dpt->base);
- int j = 0;
- while( j < columns )
- {//matrix[i][j]
- if (da_endq(dpt,(dpt->base + j*(dpt->element_size))))
- *(matrix + (i*columns + j)*sizeof(int)) = fill;
- else *(matrix + (i*columns + j)*sizeof(int)) = *(ept);
- ept++;
- j++;
- }
- dpt++;
- i++;
- }
- return matrix;
-}
-int *da_mat_ints_to_raw_image_transpose(Da *damp, int fill){
- size_t rows = damp->size/damp->element_size;
- size_t columns = da_length(da_mat_longest(damp));
- int *matrix = da_mat_ints_to_raw_image_matrix(damp, fill);//[rows][columns]
- int *transpose = MALLOC(sizeof(columns*rows));
- int i, j;
- for(i=0;i<rows;i++)
- {
- for(j=0;j<columns;j++)
- {//transpose[j][i]=matrix[i][j];
- *(transpose + (j*rows + i)*sizeof(int)) =
- *(matrix + (i*columns + j)*sizeof(int));
- }//
- }
- return transpose;
-}
-
-
-
-
-
-//When you say "like every" do you mean like map? Are we renaming map every? Instead of foreach?
-/* Would be for every element in every row:
-Da *dpt = damp->base;
- char *ept = dpt->base;
- while( dpt != damp->end ){
- while( ept != dpt->end ){
- f(ept, closure);
- ept+=dpt->element_size;
- }
- dpt++;
- }
-*/
-
-
-//------------------------------------
-
-//first pass at array of Das, exists, etc turned into this
-
-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;
-}
-
-
-void da_mat_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;
-}
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
+#include <string.h>
-typedef struct {
+typedef struct AccChannel_struct AccChannel; // AccChannel_struct defined in acc.lib.h
+typedef struct Da_struct Da;
+
+struct Da_struct{
char *base;
char *end; // one byte/one element off the end of the array
size_t size; // size >= (end - base) + 1;
size_t element_size;
-} Da;
-
-#define RETURN(dap, r) \
- { da_pts_free_all(dap); return r; }
-
+ AccChannel *channel;
+};
// constructors / destructors
//
- void da_alloc(Da *dap, size_t element_size);
+ Da *da_init(Da *dap, size_t element_size, AccChannel *channel);//calls da_malloc for base pointer
void da_free(Da *dap);
void da_rewind(Da *dap);
void da_rebase(Da *dap, char *old_base, void *pta);
// status / attributes
//
- bool da_empty(Da *dap);
+ bool da_is_empty(Da *dap);
bool da_equal(Da *da_0, Da *da_1);
size_t da_length(Da *dap);
bool da_length_equal(Da *dap0, Da *dap1);
// iteration, f is given a pointer to an element and a pointer to the closure
bool da_endq(Da *dap, void *pt);
bool da_right_bound(Da *dap, void *pt);
- void da_map(Da *dap, void f(void *, void *), void *closure); // this is really 'foreach' to be renamed
+ void da_foreach(Da *dap, void f(void *, void *), void *closure); //used to be da_map
bool da_exists(Da *dap, bool f(void *, void*), void *closure);
bool da_all(Da *dap, bool f(void *, void*), void *closure);
// elements are pointers
// would be better if exists returned NULL or a pointer to the existing element-
- bool da_pts_exists(Da *dap, void *test_element);
+ void *da_pts_exists(Da *dap, void *test_element);
void da_pts_free_all(Da *dap); // calls free on all elements
void da_pts_nullify(Da *dap, void **ept); // sets *ept to NULL, pops all NULLs from top of stack
void da_strings_set_insert(Da *string_arrp, char *proffered_string, void destruct(void *));
void da_strings_set_union(Da *string_arrp, Da *proffered_string_arrp, void destruct(void *));
-// matrix
-// There is a top level master da array. Its elements are da arrays, these are said to be rows
- void da_mat_map(Da **dar, int dar_size, void f(void *,void*), void *closure);
-
- Da *da_mat_push_row_alloc(Da *damp);
- Da *da_mat_push_row(Da *damp, Da *dap);
- void da_mat_push_column(Da *damp, Da *dap, void *fill);
-
- void da_mat_every_row(Da *damp, void f(void *, void *), void *closure);
- Da *da_mat_longer(Da *dap0, Da *dap1);
- Da *da_mat_longest(Da *damp);
- void da_mat_every_column(Da *damp, void f(void *, void *), void *closure);
-
- Da *da_mat_transpose(Da *damp, void *fill);
-
- bool da_mat_all_rows_same_length(Da *damp);
- bool da_mat_ints_all_rows_repeat(Da *damp);
- bool da_mat_ints_all_columns_repeat(Da *damp);
- bool da_mat_ints_repeats_matrix(Da *damp);
-
- Da *da_mat_ints_transpose(Da *damp, int *fill);
- int *da_mat_ints_to_raw_image_matrix(Da *damp, int fill);
- int *da_mat_ints_to_raw_image_transpose(Da *damp, int fill);
-
#endif
--- /dev/null
+
+//-----------------------------------------------------
+
+
+//-------------------------------------------------------
+
+// all things Da matrix
+// a DaMa (Doubling array Matrix) is a Da whose elements are Da's
+// forms a matrix if you treat what's pointed to by base pointers of the elements of the DaMa as the first column of elements and fill in each row with the contents of the Das
+// The "row major" nomenclature is used to remain consistent with database logic.
+/* Example:
+Da dar0; Da *dap0 = &dar0; da_alloc(dap0, sizeof(int));
+Da dar1; Da *dap1 = &dar1; da_alloc(dap1, sizeof(int));
+Da dama; Da *damp = &dama; da_alloc(damp, sizeof(Da));
+da_push(damp, dap0);
+da_push(damp, dap1);
+*/
+
+/*
+
+Da *da_mat_push_row_alloc(Da *damp){
+ size_t row_off = (Da *)(damp->end) - (Da *)(damp->base);
+ damp->end += damp->element_size;
+ if( damp->end > damp->base + damp->size ) da_expand(damp);
+ return (Da *)(damp->base) + row_off;
+}
+Da *da_mat_push_row(Da *damp, Da *dap){// Dama won't track changes to Das after pushing onto rows
+ Da *row_pt = da_mat_push_row_alloc(damp);
+ memcpy(row_pt, dap, damp->element_size);
+ return row_pt;
+}
+
+void da_mat_push_column(Da *damp, Da *dap, void *fill){
+ Da *tran = da_mat_transpose(damp, fill);
+ da_mat_push_row(tran, dap);
+ Da *new_dama = da_mat_transpose(tran, fill);
+ //add protection against memory overwrite - expand if necessary
+ memcpy(damp, new_dama, new_dama->size);
+}
+
+void da_mat_every_row(Da *damp, void f(void *, void *), void *closure){//like every but for rows instead of elements
+ Da *dpt = (Da *)(damp->base);
+ while( dpt != (Da *)damp->end ){
+ f(dpt, closure);
+ dpt++;
+ }
+}
+
+// da_mat_every_column uses da_mat_longest and therefore da_mat_longer, written for the purpose of terminating the while loop in the appropriate place
+// will return dap1 if equal, cannot determine equality
+Da *da_mat_longer(Da *dap0, Da *dap1){
+ if (da_length(dap0) > da_length(dap1)) return dap0;
+ else return dap1;
+}
+// returns Da in DaMa with longest length
+Da *da_mat_longest(Da *damp){
+ Da *dap = (Da *)(damp->base);
+ Da *longest = (Da *)((damp->base) + sizeof(Da));
+ while( dap < (Da *)(damp->end) ){
+ longest = da_mat_longer(dap,longest);
+ dap++;
+ }
+ return longest;
+}
+void da_mat_every_column(Da *damp, void f(void *, void *), void *closure){//like every but for columns instead of elements
+ Da *dpt = (Da *)(damp->base);
+ size_t rows = damp->size/damp->element_size;
+ size_t columns = da_length(da_mat_longest(damp));
+ size_t j = 0;
+ while( j < columns ){
+ int *col = MALLOC(sizeof(rows*sizeof(int)));
+ size_t i = 0;
+ while( i < rows ) {
+ if (da_endq(dpt,(dpt->base + j*(dpt->element_size))))
+ *(col+i) = 0;
+ else *(col+i) = *(dpt->base + j*(dpt->element_size));
+ dpt++;
+ i++;
+ }
+ f(col, closure);
+ j++;
+ }
+}
+
+Da *da_mat_transpose(Da *damp, void *fill){// all Das must have same element type, will sort to integer, char, or char * transpose function
+ Da *dap = (Da *)(damp->base);
+ Da tran; da_alloc(&tran, sizeof(damp->element_size));
+ Da *transpose = &tran;
+ if( dap->element_size == sizeof(int) ){
+ int *filler = (int *)fill;
+ transpose = da_mat_ints_transpose(damp, filler);
+ }
+ /*else if( dap->element_size == sizeof(char) ){
+ char *filler = (char *)fill;
+ transpose = da_character_transpose(damp, filler);
+ }
+ else if( dap->element_size == sizeof(char *) ){
+ char **filler = (char **)fill;
+ transpose = da_c_string_transpose(damp, filler);
+ }*/
+ //else error?
+ return transpose;
+}
+
+
+//--------------------------------------------------------------------
+// DaMa is a matrix of integers (stored in Das as columns)
+
+// integer repeats across columns
+bool da_mat_all_rows_same_length(Da *damp){
+ Da *dap = (Da *)(damp->base);
+ Da *pt = dap;
+ bool flag = true;
+ while( flag && pt != (Da *)(damp->end) ){
+ flag = da_length_equal(dap, pt);
+ }
+ return flag;
+}
+bool da_mat_ints_all_rows_repeat(Da *damp){// if rows are made of repeating integers, then all columns read the same thing
+ Da *dpt = (Da *)(damp->base);
+ bool flag = false;
+ if( da_mat_all_rows_same_length((Da *)damp) ){// columns can't be equal if rows not all same length, will return false
+ flag = true;
+ while( flag && dpt != (Da *)(damp->end) ){
+ flag = da_integer_repeats(dpt); // in "da is array of integers" section
+ dpt++;
+ }
+ return flag;
+ }
+ else return flag;
+}
+bool da_mat_ints_all_columns_repeat(Da *damp){// rows are repeating in transpose = columns are repeating
+ int x = 0; //have to pass in fill for transpose, this nullifies effect same_length test
+ Da *test_da = da_mat_transpose(damp, &x);
+ return da_mat_ints_all_rows_repeat(test_da);
+}
+bool da_mat_ints_repeats_matrix(Da *damp){// all elements in matrix are same
+ bool flag1 = da_mat_ints_all_rows_repeat(damp);
+ bool flag2 = da_mat_ints_all_columns_repeat(damp);
+ return flag1 && flag2;
+}
+
+// to transpose directly from one DaMa to another
+Da *da_mat_ints_transpose(Da *damp, int *fill){
+ size_t rows = damp->size/damp->element_size;
+ size_t columns = da_length(da_mat_longest(damp));
+ Da *matrix = damp;
+ Da tran;
+ da_alloc(&tran, sizeof(Da));
+ Da *transpose = &tran;
+
+ Da *dpt = (Da *)(matrix->base);
+ int i = 0, j = 0;
+ while( j < columns ){
+ Da new_row; da_alloc(&new_row, sizeof(int));
+ int *ept = fill;
+ while( i < rows ){
+ if( !da_endq(dpt, (dpt->base + j*(dpt->element_size))) ){
+ *ept = *(dpt->base + j*(dpt->element_size));
+ }
+ da_push(&new_row, ept);
+ dpt++;
+ i++;
+ }
+ da_mat_push_row(transpose, &new_row);
+ j++;
+ }
+ return transpose;
+}
+
+//to create raw matrix image in memory, no longer a Da struct
+int *da_mat_ints_to_raw_image_matrix(Da *damp, int fill){
+ size_t rows = damp->size / damp->element_size;
+ size_t columns = da_length(da_mat_longest(damp));
+ int *matrix = MALLOC(sizeof(rows*columns));//[rows][columns]
+ int i = 0;
+ Da *dpt = (Da *)(damp->base);
+ while( i < rows )
+ {
+ int *ept = (int *)(dpt->base);
+ int j = 0;
+ while( j < columns )
+ {//matrix[i][j]
+ if (da_endq(dpt,(dpt->base + j*(dpt->element_size))))
+ *(matrix + (i*columns + j)*sizeof(int)) = fill;
+ else *(matrix + (i*columns + j)*sizeof(int)) = *(ept);
+ ept++;
+ j++;
+ }
+ dpt++;
+ i++;
+ }
+ return matrix;
+}
+int *da_mat_ints_to_raw_image_transpose(Da *damp, int fill){
+ size_t rows = damp->size/damp->element_size;
+ size_t columns = da_length(da_mat_longest(damp));
+ int *matrix = da_mat_ints_to_raw_image_matrix(damp, fill);//[rows][columns]
+ int *transpose = MALLOC(sizeof(columns*rows));
+ int i, j;
+ for(i=0;i<rows;i++)
+ {
+ for(j=0;j<columns;j++)
+ {//transpose[j][i]=matrix[i][j];
+ *(transpose + (j*rows + i)*sizeof(int)) =
+ *(matrix + (i*columns + j)*sizeof(int));
+ }//
+ }
+ return transpose;
+}
+
+
+
+
+
+//When you say "like every" do you mean like map? Are we renaming map every? Instead of foreach?
+/* Would be for every element in every row:
+Da *dpt = damp->base;
+ char *ept = dpt->base;
+ while( dpt != damp->end ){
+ while( ept != dpt->end ){
+ f(ept, closure);
+ ept+=dpt->element_size;
+ }
+ dpt++;
+ }
+*/
+
+
+//------------------------------------
+
+//first pass at array of Das, exists, etc turned into this
+
+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;
+}
+
+
+void da_mat_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;
+}
--- /dev/null
+/*
+// matrix
+// There is a top level master da array. Its elements are da arrays, these are said to be rows
+ void da_mat_map(Da **dar, int dar_size, void f(void *,void*), void *closure);
+
+ Da *da_mat_push_row_alloc(Da *damp);
+ Da *da_mat_push_row(Da *damp, Da *dap);
+ void da_mat_push_column(Da *damp, Da *dap, void *fill);
+
+ void da_mat_every_row(Da *damp, void f(void *, void *), void *closure);
+ Da *da_mat_longer(Da *dap0, Da *dap1);
+ Da *da_mat_longest(Da *damp);
+ void da_mat_every_column(Da *damp, void f(void *, void *), void *closure);
+
+ Da *da_mat_transpose(Da *damp, void *fill);
+
+ bool da_mat_all_rows_same_length(Da *damp);
+ bool da_mat_ints_all_rows_repeat(Da *damp);
+ bool da_mat_ints_all_columns_repeat(Da *damp);
+ bool da_mat_ints_repeats_matrix(Da *damp);
+
+ Da *da_mat_ints_transpose(Da *damp, int *fill);
+ int *da_mat_ints_to_raw_image_matrix(Da *damp, int fill);
+ int *da_mat_ints_to_raw_image_transpose(Da *damp, int fill);
+*/
+++ /dev/null
-/*
-Alternative versions of the da array constructors and destructors for avoiding the accounting
-versions of malloc and free.
-
- */
-
-#include<stdlib.h>
-#include<stdbool.h>
-#include<string.h>
-
-#include "da.lib.h"
-#include "da_na.lib.h"
-
-#undef MALLOC
-#undef FREE
-#define MALLOC malloc
-#define FREE free
-
-#define da_alloc da_na_alloc
-#define da_free da_na_free
-#define da_expand da_na_expand
-#define da_push_alloc da_na_push_alloc
-#define da_push da_na_push
-#define da_pts_free_all_0 da_na_pts_free_all_0
-#define da_pts_free_all da_na_pts_free_all
-
-// the following is just cut and paste from da.lib.c
-// ...
-
-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;
-}
-
-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;
-}
-
-// allocate space for a new element at the end of the array
-static 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;
-}
-
-static void da_pts_free_all_0(void *pt, void *closure){
- FREE(*(char **)pt); // FREE does not care about the pointer type
-}
-void da_pts_free_all(Da *dap){
- da_map(dap, da_pts_free_all_0, NULL);
- da_rewind(dap);
-}
-
+++ /dev/null
-#ifndef DA_NA_LIB_H
-#define DA_NA_LIB_H
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdio.h>
-
-/*
-Alternative versions of the da array constructors and destructors for avoiding the accounting
-versions of malloc and free. We use these in the accounting code itself.
-
-Note the accounting software does not use int, string, strings, or matrix da methods, so those
-have not been replaced.
-
-Why are we afraid to let accounting account for itself? Well otherwise there is a possibility
-of a hickup where an array in the accounting code expands while testing a block
-of code.
-
-*/
-
-void da_na_alloc(Da *dap, size_t element_size);
-void da_na_free(Da *dap);
-char *da_na_expand(Da *dap);
-char *da_na_push_alloc(Da *dap);
-char *da_na_push(Da *dap, void *element);
-void da_na_pts_free_all(Da *dap);
-
-#endif
--- /dev/null
+
+
+typedef struct AccChannel_struct AccChannel;
+typedef struct Da_struct Da;
+
+typedef long long int size_t;
+
+struct AccChannel_struct{
+ struct Da *outstanding_malloc;
+ Da *spurious_free;
+ // enum Mode mode;
+}; //name instances of channels with handles
+
+struct Da_struct{
+ char *base;
+ char *end; // one byte/one element off the end of the array
+ size_t size; // size >= (end - base) + 1;
+ size_t element_size;
+ AccChannel *channel;//assign during init, set to NULL during free
+};
+
+
+int main(){
+ Da x;
+ AccChannel y;
+ return 5;
+}
+++ /dev/null
-#include <stdio.h>
-
-
-typedef struct {
- int a;
- int b;
-}pair;
-
-
-int main(){
- pair s0, s1, s2;
- s0.a = 10;
- s0.b = 11;
- s1.a = 20;
- s1.b = 21;
- s2.a = 10;
- s2.b = 11;
-
- if( s0 == s1 ) {
- printf("s0 s1 are equal!\n");
- }else{
- printf("s0 s1 are not equal!\n");
- }
- if( s0 == s2 ) {
- printf("s0 s2 are equal!\n");
- }else{
- printf("s0 s2 are not equal!\n");
- }
-
-
- return 0;
-}
-
-
-
+++ /dev/null
-s/da_start_accounting/acc_start/g
-s/da_malloc_counted/acc_malloc/g
-s/da_free_counted/acc_free/g
-s/da_result_accounting/acc_result/g
-s/da_free_elements/da_pts_free_all/g
-s/da_matrix_map/da_mat_map/g
-s/da_push_row_alloc/da_mat_push_row_alloc/g
-s/da_push_column/da_mat_push_column/g
-s/da_push_row/da_mat_push_row/g
-s/da_every_row/da_mat_every_row/g
-s/da_longer/da_mat_longer/g
-s/da_longest/da_mat_longest/g
-s/da_every_column/da_mat_every_column/g
-s/da_matrix_transpose/da_mat_transpose/g
-s/da_all_rows_same_length/da_mat_all_rows_same_length/g
-s/da_integer_all_rows_repeat/da_mat_ints_all_rows_repeat/g
-s/da_integer_all_columns_repeat/da_mat_ints_all_columns_repeat/g
-s/da_integer_repeats_matrix/da_mat_ints_repeats_matrix/g
-s/da_integer_transpose/da_mat_ints_transpose/g
-s/da_integer_to_raw_image_matrix/da_mat_ints_to_raw_image_matrix/g
-s/da_integer_to_raw_image_transpose/da_mat_ints_to_raw_image_transpose/g
\ No newline at end of file
--- /dev/null
+s/Acc_channel/AccChannel/g
--- /dev/null
+s/da_start_accounting/acc_start/g
+s/da_malloc_counted/acc_malloc/g
+s/da_free_counted/acc_free/g
+s/da_result_accounting/acc_result/g
+s/da_free_elements/da_pts_free_all/g
+s/da_matrix_map/da_mat_map/g
+s/da_push_row_alloc/da_mat_push_row_alloc/g
+s/da_push_column/da_mat_push_column/g
+s/da_push_row/da_mat_push_row/g
+s/da_every_row/da_mat_every_row/g
+s/da_longer/da_mat_longer/g
+s/da_longest/da_mat_longest/g
+s/da_every_column/da_mat_every_column/g
+s/da_matrix_transpose/da_mat_transpose/g
+s/da_all_rows_same_length/da_mat_all_rows_same_length/g
+s/da_integer_all_rows_repeat/da_mat_ints_all_rows_repeat/g
+s/da_integer_all_columns_repeat/da_mat_ints_all_columns_repeat/g
+s/da_integer_repeats_matrix/da_mat_ints_repeats_matrix/g
+s/da_integer_transpose/da_mat_ints_transpose/g
+s/da_integer_to_raw_image_matrix/da_mat_ints_to_raw_image_matrix/g
+s/da_integer_to_raw_image_transpose/da_mat_ints_to_raw_image_transpose/g
\ No newline at end of file
--- /dev/null
+s/da_alloc/da_init/g
+s/da_map/da_foreach/g
+++ /dev/null
-Explanation of process for using accounting code.
-
- First, acc_open(&acc_live_channels, mode); ---acc_NULL or acc_SELF only, decide whether to track memory allocation for channels themselves
-
- To begin an accounting channel, declare an Acc_channel and initialize it by passing a pointer to it into acc_open. You will also need to pass in a Mode.
-
--acc_NULL does not track
--acc_BALANCE will give you a count of outstanding mallocs and spurious frees when reported
--acc_FULL will give you a robust accounting with a list of up to 10 outstanding/spurious pointers, then it will default to a count instead and just give the first 10 addresses.
--acc_SELF is solely for the accounting software to account for its own memory allocation, therefore listing outstanding/spurious pointers to Acc_channels in the same format as acc_FULL.
-
- When initializing a Da, you must pass in a pointer to the Da, its element size, and a pointer to the (already initialized) Acc_channel on which it will be stored into da_init. Among its other initialization tasks, this function will call acc_malloc for the base pointer of the Da with the appropriate channel.
- When allocating memory for anything else in the program, you must pass the size of the memory to be allocated as well as the channel on which it is to be tracked to acc_malloc.
-
- To free a Da, pass a pointer to the Da into da_free. It will automatically call acc_free for the base pointer, set the size to 0 and set the channel to NULL.
- To free anything other else in the program, simply call acc_free, passing in the pointer and the channel the pointer is being tracked in. This will zero it out from the channel, call da_pts_nullify to clean up any zeroes at the end of the channel, and then free the pointer.
-
- To find out if there are any memory leaks in a particular channel, call acc_report with a pointer to the Acc_channel as the argument. Depending on the channel's mode, it will pretty print a current report of memory allocation and frees. If you call a report on acc_live_channels and it is set to Mode acc_SELF, it will report on the memory currently in use for the accounting system itself.
-
- When finished with a channel, call acc_close and pass in the channel pointer. This will free up the memory used by it and remove it from the acc_live_channels outstanding_malloc list if there is SELF tracking on. Any allocation information being tracked by this channel will be lost, so it is advised to call acc_report before deciding whether to free the channel.
+++ /dev/null
-/*
- Dynamic Array
-
- Cannot expand an empty array.
-
- Accounting built into code. Alternative version of malloc and free that will invoke accounting for pointers that are allocated
- but not freed, or freed but not allocated.
-
-*/
-
-#include "da.lib.h"
-
-//-----------------------------------------------------------------
-//function definitions for accounting
-
-Acc_channel *acc_open(Acc_channel *channel, enum Mode mode){//acc init
- if( channel == &acc_live_channels ) {//avoid pushing channel tracker onto itself
- Da os; Da sf;
- channel->outstanding_malloc = da_init(&os, sizeof(void *), NULL);
- channel->spurious_free = da_init(&sf, sizeof(void *), NULL);
- channel->mode = mode;
- return channel;
- }
- else if( acc_live_channels.mode == acc_NULL ){//accounting NULL
- //channel = (Acc_channel *)acc_malloc(sizeof(Acc_channel), NULL);//accounting channel still on the heap but not tracked in SELF mode
- Da os; Da sf;
- channel->outstanding_malloc = da_init(&os, sizeof(void *), NULL);
- channel->spurious_free = da_init(&sf, sizeof(void *), NULL);
- channel->mode = mode;
- return channel;
- }
- else if( acc_live_channels.mode == acc_SELF ){//accounting tracks itself
- channel = (Acc_channel *)acc_malloc(sizeof(Acc_channel), &acc_live_channels);
- Da os; Da sf;
- channel->outstanding_malloc = da_init(&os, sizeof(void *), NULL);
- channel->spurious_free = da_init(&sf, sizeof(void *), NULL);
- channel->mode = mode;
- return channel;
- }
- else{ //cerr, optional acc_live_channels only tracks channels, not other mallocs/frees
- return channel;
- }
-}
-void *acc_malloc(size_t size, Acc_channel *channel){
- void *an_allocation_pt = malloc(size);
- if( channel ) da_push((Da *)(channel->outstanding_malloc), &an_allocation_pt);
- return (void *)an_allocation_pt;
-}
-void acc_free(void *pt, Acc_channel *channel){
- if( channel ){
- void **i = (void **)(((Da *)(channel->outstanding_malloc))->base);
- bool present = false;
- while( i < (void **)(((Da *)(channel->outstanding_malloc))->end) ){
- if( *i == pt ){
- da_pts_nullify((Da *)(channel->outstanding_malloc), i);
- present = true;
- }
- i++;
- }
- if( present == false ) da_push((Da *)(channel->spurious_free), &pt);
- }
- free(pt);
-}
-static void count_balance(void *element, void *closure){
- int *counter = (int *)closure;
- if( (void *)element ) (*counter)++;
-}
-static void acc_rep_helper_BALANCE(Acc_channel *channel){
- int count = 0;
- da_foreach((Da *)channel->outstanding_malloc, count_balance, &count);
- printf("There are %d outstanding allocations.\n", count);
- count = 0;
- da_foreach((Da *)channel->spurious_free, count_balance, &count);
- printf("There are %d spurious frees.\n", count);
-}
-static void print_pointer(void *element, void *closure){
- if( element ) printf("%d ", *(int *)element);
-}
-static void acc_rep_helper_FULL(Acc_channel *channel){
- int count = 0;
- da_foreach((Da *)channel->outstanding_malloc, count_balance, &count);
- printf("There are %d outstanding mallocs.\n", count);
- if( count < 10 ){
- printf("The outstanding allocated pointers are: ");
- da_foreach((Da *)channel->outstanding_malloc, print_pointer, NULL);
- printf(".\n");
- }
- count = 0;
- da_foreach((Da *)channel->spurious_free, count_balance, &count);
- printf("There are %d spurious frees.\n", count);
- if( count < 10 ){
- printf("The spuriously freed pointers are: ");
- da_foreach((Da *)channel->outstanding_malloc, print_pointer, NULL);
- printf(".\n");
- }
-}
-Acc_channel *acc_report(Acc_channel *channel){
- if( channel->mode == acc_NULL ){
- printf("Accounting mode is NULL.");
- return channel;
- }
- if( channel->mode == acc_BALANCE ){
- printf("Accounting mode is BALANCE.\n");
- if( da_emptyq((Da *)(channel->outstanding_malloc)) && da_emptyq((Da *)(channel->spurious_free)) ){
- printf("This channel is in balance.");
- }
- else{
- printf("This channel is out of balance.\n");
- acc_rep_helper_BALANCE(channel);
- }
- return channel;
- }
- if( channel->mode == acc_FULL ){
- printf("Accounting mode is FULL.\n");
- if( da_emptyq((Da *)(channel->outstanding_malloc)) && da_emptyq((Da *)(channel->spurious_free)) ){
- printf("This channel is in balance.");
- }
- else{
- printf("This channel is out of balance.\n");
- acc_rep_helper_FULL(channel);
- }
- return channel;
- }
- if( channel->mode == acc_SELF ){
- printf("Accounting mode is SELF.\n");
- if( da_emptyq((Da *)(channel->outstanding_malloc)) && da_emptyq((Da *)(channel->spurious_free)) ){
- printf("There are no open channels.");
- }
- else {
- printf("The accounting code is out of balance.\n");
- acc_rep_helper_FULL(channel);
- }
- return channel;
- }
-}
-void acc_close(Acc_channel *channel){
- da_free((Da *)(channel->outstanding_malloc));
- da_free((Da *)(channel->spurious_free));
- if( (channel != &acc_live_channels)
- && (acc_live_channels.mode == acc_SELF) ){
- acc_free(channel, &acc_live_channels);
- return;
- }
- else return;
-}
-
-void *crash_and_burn_malloc(size_t size){}
-void crash_and_burn_free(void *pt){}
-
-
-//-----------------------------------------------------------------
-//functions definitions for Das
-
-// constructors / destructors
-Da *da_init(Da *dap, size_t element_size, Acc_channel *channel){
- dap->element_size = element_size;
- dap->size = 4 * element_size;
- dap->base = acc_malloc(dap->size, channel);
- dap->end = dap->base;
- dap->channel = channel;
- return dap;
-}
-void da_free(Da *dap){
- acc_free(dap->base, dap->channel);
- dap->size = 0;
- dap->channel = NULL;
-}
-void da_rewind(Da *dap){
- dap->end = dap->base;
-}
-void da_rebase(Da *dap, char *old_base, void *pta){
- char **pt = (char **)pta;
- size_t offset = *pt - old_base;
- *pt = dap->base + offset;
-}
-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 = acc_malloc(new_size, (Acc_channel *)(dap->channel));
- memcpy( new_base, old_base, end_offset + dap->element_size);
- acc_free(old_base, (Acc_channel *)(dap->channel));
- dap->base = new_base;
- dap->end = new_base + end_offset;
- dap->size = new_size;
- return old_base;
-}
-bool da_boundq(Da *dap){
- return dap->end > (dap->base + dap->size);
-}
-
-// status / attributes
-//
-bool da_emptyq(Da *dap){
- return dap->end == dap->base;
-}
-bool da_equal(Da *da_0, Da *da_1){
- return !bcmp(da_0, da_1, sizeof(Da));
-}
-size_t da_length(Da *dap){
- return (dap->end - dap->base)/dap->element_size;
-}
-bool da_length_equal(Da *dap0, Da *dap1){
- return da_length(dap0) == da_length(dap1);
-}
-
-// accessing
-//
-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
-static 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, f is given a pointer to an element and a pointer to the closure
-
-// true when pt has run off the end
-bool da_endq(Da *dap, void *pt){
- return (char *)pt >= dap->end;
-}
-// array is a row of elements, pt points at the rightmost element
-bool da_right_bound(Da *dap, void *pt){
- return ((char *)pt + dap->element_size) >= 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_foreach(Da *dap, void f(void *, void *), void *closure){
- char *pt = dap->base;
- while( pt != dap->end ){
- f(pt, closure);
- pt += dap->element_size;
- }
-}
-//would like da_exists and da_all to return pointer to element
-//abstract helper for da_exists and da_all
-static bool da_quantifier(bool complement, Da *dap, bool pred(void *, void*), void *closure){
- char *pt = dap->base;
- bool result = false;
- while( (complement? !result : result) && (pt != dap->end) ){
- result = pred(pt, closure);
- pt += dap->element_size;
- }
- return result;
-}
-//∃, OR foreach
-bool da_exists(Da *dap, bool pred(void *, void*), void *closure){
- return da_quantifier(true, dap, pred, closure);
-}
-//∀, AND foreach
-bool da_all(Da *dap, bool pred(void *, void*), void *closure){
- return da_quantifier(false, dap, pred, closure);
-}
-
-// elements are pointers
-//
-static bool da_pts_exists_0(void *element, void *test_element){ return element == test_element; }
-void *da_pts_exists(Da *dap, void *test_element){
- if( da_exists(dap, da_pts_exists_0, test_element) ) return test_element;
- else return NULL;
-}
-// elements were allocated, now they will all be freed
-static void da_pts_free_all_0(void *pt, void *closure){
- acc_free(*(char **)pt, closure);
-}
-void da_pts_free_all(Da *dap){
- da_foreach(dap, da_pts_free_all_0, dap->channel);
- da_rewind(dap);
-}
-// elements are pointers
-// ept points at an element, we set *ept to NULL
-// we pop all NULLs off the top of the stack
-void da_pts_nullify(Da *dap, void **ept){
- if(ept >= (void **)(dap->base) && ept < (void **)(dap->end)){
- *ept = NULL;
- }
- while(
- dap->end > dap->base
- &&
- *(void **)(dap->end - dap->element_size) == NULL){
- da_pop(dap, NULL);
- }
-}
-
-// matrices - elements are das
-//need to rename/sed a lot of functions before adding
+++ /dev/null
-#ifndef DA_LIB_H
-#define DA_LIB_H
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-//#define malloc crash_and_burn_malloc
-//#define free crash_and_burn_free
-//shouldn't define these in header bc need to use malloc and free in functions, put definitions after header if going to use
-
-// See acc_doc.txt for explanation of process for using accounting code.
-
-enum Mode{acc_NULL, acc_BALANCE, acc_FULL, acc_SELF};//0,1,2,3
-
-struct Da;//forward declaration because mutually referential structs
-
-typedef struct {
- struct Da *outstanding_malloc;
- struct Da *spurious_free;
- enum Mode mode;
-} Acc_channel; //name instances of channels with handles
-
-typedef struct Da {
- char *base;
- char *end; // one byte/one element off the end of the array
- size_t size; // size >= (end - base) + 1;
- size_t element_size;
- Acc_channel *channel;//assign during init, set to NULL during free
-} Da;
-
-extern Acc_channel acc_live_channels;//acc_NULL or acc_SELF to track acc channels or not, other options return invalid upon report
-
-//function declarations for accounting
- Acc_channel *acc_open(Acc_channel *channel, enum Mode mode);//initializes channel structs
- void *acc_malloc(size_t size, Acc_channel *channel);//works for things besides Das too
- void acc_free(void *pt, Acc_channel *channel);//works for things besides Das too
- Acc_channel *acc_report(Acc_channel *channel);//reports on channels based on mode
- void acc_close(Acc_channel *channel);//frees channel itself
-
- void *crash_and_burn_malloc(size_t size);//sends error message in case of accidental regular malloc
- void crash_and_burn_free(void *);// sends error message in case of accidental regular free
-
-//function declarations for Das
-
-// constructors / destructors
- Da *da_init(Da *dap, size_t element_size, Acc_channel *channel);//calls da_malloc for base pointer
- void da_free(Da *dap);
- void da_rewind(Da *dap);
- void da_rebase(Da *dap, char *old_base, void *pta);
- char *da_expand(Da *dap);
- bool da_boundq(Da *dap);
-
-// status / attributes
-//
- bool da_emptyq(Da *dap);
- bool da_equal(Da *da_0, Da *da_1);
- size_t da_length(Da *dap);
- bool da_length_equal(Da *dap0, Da *dap1);
-
-// accessing
-//
- char *da_index(Da *dap, size_t i);
- char *da_push(Da *dap, void *element);
- bool da_pop(Da *dap, void *element);
-
-// iteration, f is given a pointer to an element and a pointer to the closure
- bool da_endq(Da *dap, void *pt);
- bool da_right_bound(Da *dap, void *pt);
- void da_foreach(Da *dap, void f(void *, void *), void *closure); //used to be da_map
- bool da_exists(Da *dap, bool f(void *, void*), void *closure);
- bool da_all(Da *dap, bool f(void *, void*), void *closure);
-
-// elements are pointers
-//
- void *da_pts_exists(Da *dap, void *test_element);
- void da_pts_free_all(Da *dap); // calls free on all elements
- void da_pts_nullify(Da *dap, void **ept); // sets *ept to NULL, pops all NULLs from top of stack
-
-
-// matrices - elements are das
-//need to rename/sed a lot of functions before adding
-void da_mat_erase(Da *dap);//same as free
-
-
-
-#endif
-
+++ /dev/null
-s/&/&/g
\ No newline at end of file