1*4887Schin /*********************************************************************** 2*4887Schin * * 3*4887Schin * This software is part of the ast package * 4*4887Schin * Copyright (c) 1985-2007 AT&T Knowledge Ventures * 5*4887Schin * and is licensed under the * 6*4887Schin * Common Public License, Version 1.0 * 7*4887Schin * by AT&T Knowledge Ventures * 8*4887Schin * * 9*4887Schin * A copy of the License is available at * 10*4887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 11*4887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*4887Schin * * 13*4887Schin * Information and Software Systems Research * 14*4887Schin * AT&T Research * 15*4887Schin * Florham Park NJ * 16*4887Schin * * 17*4887Schin * Glenn Fowler <gsf@research.att.com> * 18*4887Schin * David Korn <dgk@research.att.com> * 19*4887Schin * Phong Vo <kpv@research.att.com> * 20*4887Schin * * 21*4887Schin ***********************************************************************/ 22*4887Schin #pragma prototyped 23*4887Schin /* 24*4887Schin * pointer stack routines 25*4887Schin */ 26*4887Schin 27*4887Schin static const char id_stack[] = "\n@(#)$Id: stack (AT&T Bell Laboratories) 1984-05-01 $\0\n"; 28*4887Schin 29*4887Schin #include <ast.h> 30*4887Schin #include <stack.h> 31*4887Schin 32*4887Schin /* 33*4887Schin * create a new stack 34*4887Schin */ 35*4887Schin 36*4887Schin STACK 37*4887Schin stackalloc(register int size, void* error) 38*4887Schin { 39*4887Schin register STACK stack; 40*4887Schin register struct stackblock *b; 41*4887Schin 42*4887Schin if (size <= 0) size = 100; 43*4887Schin if (!(stack = newof(0, struct stacktable, 1, 0))) return(0); 44*4887Schin if (!(b = newof(0, struct stackblock, 1, 0))) 45*4887Schin { 46*4887Schin free(stack); 47*4887Schin return(0); 48*4887Schin } 49*4887Schin if (!(b->stack = newof(0, void*, size, 0))) 50*4887Schin { 51*4887Schin free(b); 52*4887Schin free(stack); 53*4887Schin return(0); 54*4887Schin } 55*4887Schin stack->blocks = b; 56*4887Schin stack->size = size; 57*4887Schin stack->error = error; 58*4887Schin stack->position.block = b; 59*4887Schin stack->position.index = -1; 60*4887Schin b->next = 0; 61*4887Schin b->prev = 0; 62*4887Schin return(stack); 63*4887Schin } 64*4887Schin 65*4887Schin /* 66*4887Schin * remove a stack 67*4887Schin */ 68*4887Schin 69*4887Schin void 70*4887Schin stackfree(register STACK stack) 71*4887Schin { 72*4887Schin register struct stackblock* b; 73*4887Schin register struct stackblock* p; 74*4887Schin 75*4887Schin b = stack->blocks; 76*4887Schin while (p = b) 77*4887Schin { 78*4887Schin b = p->next; 79*4887Schin free(p->stack); 80*4887Schin free(p); 81*4887Schin } 82*4887Schin free(stack); 83*4887Schin } 84*4887Schin 85*4887Schin /* 86*4887Schin * clear stack 87*4887Schin */ 88*4887Schin 89*4887Schin void 90*4887Schin stackclear(register STACK stack) 91*4887Schin { 92*4887Schin stack->position.block = stack->blocks; 93*4887Schin stack->position.index = -1; 94*4887Schin } 95*4887Schin 96*4887Schin /* 97*4887Schin * get value on top of stack 98*4887Schin */ 99*4887Schin 100*4887Schin void* 101*4887Schin stackget(register STACK stack) 102*4887Schin { 103*4887Schin if (stack->position.index < 0) return(stack->error); 104*4887Schin else return(stack->position.block->stack[stack->position.index]); 105*4887Schin } 106*4887Schin 107*4887Schin /* 108*4887Schin * push value on to stack 109*4887Schin */ 110*4887Schin 111*4887Schin int 112*4887Schin stackpush(register STACK stack, void* value) 113*4887Schin { 114*4887Schin register struct stackblock *b; 115*4887Schin 116*4887Schin if (++stack->position.index >= stack->size) 117*4887Schin { 118*4887Schin b = stack->position.block; 119*4887Schin if (b->next) b = b->next; 120*4887Schin else 121*4887Schin { 122*4887Schin if (!(b->next = newof(0, struct stackblock, 1, 0))) 123*4887Schin return(-1); 124*4887Schin b = b->next; 125*4887Schin if (!(b->stack = newof(0, void*, stack->size, 0))) 126*4887Schin return(-1); 127*4887Schin b->prev = stack->position.block; 128*4887Schin b->next = 0; 129*4887Schin } 130*4887Schin stack->position.block = b; 131*4887Schin stack->position.index = 0; 132*4887Schin } 133*4887Schin stack->position.block->stack[stack->position.index] = value; 134*4887Schin return(0); 135*4887Schin } 136*4887Schin 137*4887Schin /* 138*4887Schin * pop value off stack 139*4887Schin */ 140*4887Schin 141*4887Schin int 142*4887Schin stackpop(register STACK stack) 143*4887Schin { 144*4887Schin /* 145*4887Schin * return: 146*4887Schin * 147*4887Schin * -1 if stack empty before pop 148*4887Schin * 0 if stack empty after pop 149*4887Schin * 1 if stack not empty before & after pop 150*4887Schin */ 151*4887Schin 152*4887Schin if (stack->position.index < 0) return(-1); 153*4887Schin else if (--stack->position.index < 0) 154*4887Schin { 155*4887Schin if (!stack->position.block->prev) return(0); 156*4887Schin stack->position.block = stack->position.block->prev; 157*4887Schin stack->position.index = stack->size - 1; 158*4887Schin return(1); 159*4887Schin } 160*4887Schin else return(1); 161*4887Schin } 162*4887Schin 163*4887Schin /* 164*4887Schin * set|get stack position 165*4887Schin */ 166*4887Schin 167*4887Schin void 168*4887Schin stacktell(register STACK stack, int set, STACKPOS* position) 169*4887Schin { 170*4887Schin if (set) stack->position = *position; 171*4887Schin else *position = stack->position; 172*4887Schin } 173