/*#io
docCopyright("Steve Dekorte", 2002)
docLicense("BSD revised")
docDescription("""
Notes: first element of items is always 0x0.
""")
*/
#define STACK_C
#include "Stack.h"
#undef STACK_C
#if !defined(_MSC_VER)
#include <inttypes.h>
#endif
#include "Datum.h"
Stack *Stack_new(void)
{
// size is the number of pointers, including the starting NULL.
int size = STACK_START_SIZE;
Stack *self = (Stack *)calloc(1, sizeof(Stack));
self->items = (void **)calloc(1, size*sizeof(void *));
// memEnd points past the end of the items memory block.
self->memEnd = self->items + size;
self->top = self->items;
//self->lastMark = self->items;
return self;
}
void Stack_free(Stack *self)
{
free(self->items);
free(self);
}
Stack *Stack_clone(Stack *self)
{
Stack *s = (Stack *)cpalloc(self, sizeof(Stack));
ptrdiff_t nItems = self->top - self->items;
ptrdiff_t size = nItems + 1;
s->items = (void **)cpalloc(self->items, size*sizeof(void *));
s->memEnd = s->items + size;
s->top = s->items + nItems;
return s;
}
void Stack_copy_(Stack *self, Stack *other)
{
ptrdiff_t nItems = self->top - self->items;
ptrdiff_t size = nItems + 1;
ptrdiff_t sizeInBytes = size*sizeof(void *);
self->items = (void **)realloc(self->items, sizeInBytes);
memcpy(self->items, other->items, sizeInBytes);
self->memEnd = self->items + size;
self->top = self->items + nItems;
}
// stack --------------------------------------------------
size_t Stack_memorySize(Stack *self)
{
return sizeof(Stack) + (self->memEnd - self->items);
}
void Stack_compact(Stack *self)
{
int oldSize = (1 + self->top - self->items)*sizeof(void *);
self->items = (void **)realloc(self->items, oldSize);
}
void Stack_resize(Stack *self)
{
int oldSize = (self->memEnd - self->items)*sizeof(void *);
int newSize = oldSize*STACK_RESIZE_FACTOR;
int i = self->top - self->items;
self->items = (void **)realloc(self->items, newSize);
self->top = self->items + i;
self->memEnd = self->items + (newSize/sizeof(void *));
}
// sizing ------------------------------------------------
void Stack_do_on_(Stack *self, StackDoOnCallback *callback, void *target)
{
Stack *stack = Stack_newCopyWithNullMarks(self);
int i;
for(i = 0; i < Stack_count(stack) - 1; i ++)
{
void *v = Stack_at_(stack, i);
if (v) (*callback)(target, v);
}
Stack_free(stack);
}
void Stack_makeMarksNull(Stack *self)
{
ptrdiff_t mark = self->lastMark;
while (mark)
{
ptrdiff_t nextMark = (ptrdiff_t)self->items[mark];
self->items[mark] = NULL;
mark = nextMark;
}
}
Stack *Stack_newCopyWithNullMarks(Stack *self)
{
Stack *newStack = Stack_clone(self);
Stack_makeMarksNull(newStack);
return newStack;
}
void Stack_popToMark_(Stack *self, ptrdiff_t mark)
{
while (self->lastMark && self->lastMark != mark)
{
Stack_popMark(self);
}
if (self->lastMark == 0)
{
printf("Stack error: unable to find mark %p in %p\n", (void *)mark, (void *)self);
exit(1);
}
Stack_popMark(self);
}
List *Stack_asList(Stack *self) // slow
{
List *list = List_new();
Stack_do_on_(self, (StackDoOnCallback *)List_append_, list);
return list;
}
syntax highlighted by Code2HTML, v. 0.9.1