/*
docCopyright("Steve Dekorte", 2002)
docLicense("BSD revised")
docDescription("""
Stack - array of void pointers
supports setting marks - when a mark is popped,
all stack items above it are popped as well
""")
*/
#ifdef STACK_C
#define IO_IN_C_FILE
#endif
#include "Common_inline.h"
#ifdef IO_DECLARE_INLINES
IOINLINE void Stack_clear(Stack *self)
{
self->top = self->items;
self->lastMark = 0;
}
IOINLINE size_t Stack_totalSize(Stack *self)
{
return (self->top - self->items);
}
IOINLINE int Stack_count(Stack *self)
{
return (self->top - self->items);
}
IOINLINE void Stack_push_(Stack *self, void *item)
{
self->top ++;
if (self->top == self->memEnd)
{
Stack_resize(self);
}
*(self->top) = item;
}
IOINLINE void Stack_pushMark(Stack *self)
{
Stack_push_(self, (void *)self->lastMark);
self->lastMark = self->top - self->items;
}
IOINLINE ptrdiff_t Stack_pushMarkPoint(Stack *self)
{
Stack_push_(self, (void *)self->lastMark);
self->lastMark = self->top - self->items;
return self->lastMark;
}
IOINLINE void *Stack_pop(Stack *self)
{
void *top = *(self->top);
if (self->items != self->top)
{
self->top --;
}
return top;
}
IOINLINE void Stack_popMark(Stack *self)
{
self->top = self->items + self->lastMark - 1;
if (self->lastMark)
{
self->lastMark = (ptrdiff_t)(self->items[self->lastMark]);
}
}
IOINLINE int Stack_popMarkPoint_(Stack *self, ptrdiff_t mark)
{
while (self->lastMark && self->lastMark != mark)
{
Stack_popMark(self);
}
if (self->lastMark != mark)
{
return 0;
}
Stack_popMark(self);
return 1;
}
IOINLINE void Stack_clearTop(Stack *self)
{
self->top = self->items + self->lastMark;
}
IOINLINE void *Stack_top(Stack *self)
{
return *(self->top);
}
IOINLINE void *Stack_at_(Stack *self, int i)
{
return self->items[i + 1];
}
IOINLINE void Stack_do_(Stack *self, StackDoCallback *callback)
{
void **itemP = self->top;
ptrdiff_t mark = self->lastMark;
while (itemP > self->items)
{
if (itemP - self->items == mark)
{
mark = (ptrdiff_t)(*itemP);
}
else
{
(*callback)(*itemP);
}
itemP --;
}
}
IOINLINE void Stack_doUntilMark_(Stack *self, StackDoCallback *callback)
{
void **itemP = self->top;
ptrdiff_t mark = self->lastMark;
while (itemP > self->items)
{
if (itemP - self->items == mark)
{
return;
}
else
{
(*callback)(*itemP);
}
itemP --;
}
}
#undef IO_IN_C_FILE
#endif
syntax highlighted by Code2HTML, v. 0.9.1