#ifndef lint static char *rcs = "$Header: stack.c,v 1.1 88/01/15 13:05:28 simpson Rel $"; #endif /* $Log: stack.c,v $ * Revision 1.1 88/01/15 13:05:28 simpson * initial release * * Revision 0.1 87/12/11 18:31:20 simpson * beta test * */ /* Generalized stack manipulation routines. Routines provided are: * * char *push(p) * char *p; * * Pushes the stack with the data in pointer p. Space is not allocated * for the data; that is, the data is by reference. Consequently, you should * not delete the data until you have popped it from the stack. A pointer to * the passed data is returned. NULL is returned if memory could not be * allocated to push the data. If the data passed is larger than * elementsize, then only elementsize bytes will be copied. If it is * smaller, you will probably get a segmentation violation. * * char *pop() * * Pops the stack and returns the popped value. If the stack is empty, NULL * is returned. * * Implementation rationale: We don't copy data by value since we would have * trouble popping the data. When we pop data, we want to free its space but * we also want to return the data popped. We could store the data in a * temporary buffer of the element size but it would get written over with * every pop. Also, copying by value slows things down. */ #include #define NULL 0 /* Represent the stack as a linked list of elements */ static struct element { char *data; /* Pointer to actual data */ struct element *next; /* Pointer to next element down */ } *Head; /* Push the stack */ char *push(data) char *data; { struct element *p; char *malloc(); if (!data || !(p = (struct element *)malloc((unsigned)sizeof(struct element)))) return NULL; p->next = Head, Head = p; p->data = data; return data; } /* Pop the stack */ char *pop() { char *p; struct element *ep; if (!Head) return NULL; p = Head->data; ep = Head; Head = Head->next; free((char *)ep); return p; }