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