14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin /*
244887Schin * pointer stack routines
254887Schin */
264887Schin
274887Schin static const char id_stack[] = "\n@(#)$Id: stack (AT&T Bell Laboratories) 1984-05-01 $\0\n";
284887Schin
294887Schin #include <ast.h>
304887Schin #include <stack.h>
314887Schin
324887Schin /*
334887Schin * create a new stack
344887Schin */
354887Schin
364887Schin STACK
stackalloc(register int size,void * error)374887Schin stackalloc(register int size, void* error)
384887Schin {
394887Schin register STACK stack;
404887Schin register struct stackblock *b;
414887Schin
424887Schin if (size <= 0) size = 100;
434887Schin if (!(stack = newof(0, struct stacktable, 1, 0))) return(0);
444887Schin if (!(b = newof(0, struct stackblock, 1, 0)))
454887Schin {
464887Schin free(stack);
474887Schin return(0);
484887Schin }
494887Schin if (!(b->stack = newof(0, void*, size, 0)))
504887Schin {
514887Schin free(b);
524887Schin free(stack);
534887Schin return(0);
544887Schin }
554887Schin stack->blocks = b;
564887Schin stack->size = size;
574887Schin stack->error = error;
584887Schin stack->position.block = b;
594887Schin stack->position.index = -1;
604887Schin b->next = 0;
614887Schin b->prev = 0;
624887Schin return(stack);
634887Schin }
644887Schin
654887Schin /*
664887Schin * remove a stack
674887Schin */
684887Schin
694887Schin void
stackfree(register STACK stack)704887Schin stackfree(register STACK stack)
714887Schin {
724887Schin register struct stackblock* b;
734887Schin register struct stackblock* p;
744887Schin
754887Schin b = stack->blocks;
764887Schin while (p = b)
774887Schin {
784887Schin b = p->next;
794887Schin free(p->stack);
804887Schin free(p);
814887Schin }
824887Schin free(stack);
834887Schin }
844887Schin
854887Schin /*
864887Schin * clear stack
874887Schin */
884887Schin
894887Schin void
stackclear(register STACK stack)904887Schin stackclear(register STACK stack)
914887Schin {
924887Schin stack->position.block = stack->blocks;
934887Schin stack->position.index = -1;
944887Schin }
954887Schin
964887Schin /*
974887Schin * get value on top of stack
984887Schin */
994887Schin
1004887Schin void*
stackget(register STACK stack)1014887Schin stackget(register STACK stack)
1024887Schin {
1034887Schin if (stack->position.index < 0) return(stack->error);
1044887Schin else return(stack->position.block->stack[stack->position.index]);
1054887Schin }
1064887Schin
1074887Schin /*
1084887Schin * push value on to stack
1094887Schin */
1104887Schin
1114887Schin int
stackpush(register STACK stack,void * value)1124887Schin stackpush(register STACK stack, void* value)
1134887Schin {
1144887Schin register struct stackblock *b;
1154887Schin
1164887Schin if (++stack->position.index >= stack->size)
1174887Schin {
1184887Schin b = stack->position.block;
1194887Schin if (b->next) b = b->next;
1204887Schin else
1214887Schin {
1224887Schin if (!(b->next = newof(0, struct stackblock, 1, 0)))
1234887Schin return(-1);
1244887Schin b = b->next;
1254887Schin if (!(b->stack = newof(0, void*, stack->size, 0)))
1264887Schin return(-1);
1274887Schin b->prev = stack->position.block;
1284887Schin b->next = 0;
1294887Schin }
1304887Schin stack->position.block = b;
1314887Schin stack->position.index = 0;
1324887Schin }
1334887Schin stack->position.block->stack[stack->position.index] = value;
1344887Schin return(0);
1354887Schin }
1364887Schin
1374887Schin /*
1384887Schin * pop value off stack
1394887Schin */
1404887Schin
1414887Schin int
stackpop(register STACK stack)1424887Schin stackpop(register STACK stack)
1434887Schin {
1444887Schin /*
1454887Schin * return:
1464887Schin *
1474887Schin * -1 if stack empty before pop
1484887Schin * 0 if stack empty after pop
1494887Schin * 1 if stack not empty before & after pop
1504887Schin */
1514887Schin
1524887Schin if (stack->position.index < 0) return(-1);
1534887Schin else if (--stack->position.index < 0)
1544887Schin {
1554887Schin if (!stack->position.block->prev) return(0);
1564887Schin stack->position.block = stack->position.block->prev;
1574887Schin stack->position.index = stack->size - 1;
1584887Schin return(1);
1594887Schin }
1604887Schin else return(1);
1614887Schin }
1624887Schin
1634887Schin /*
1644887Schin * set|get stack position
1654887Schin */
1664887Schin
1674887Schin void
stacktell(register STACK stack,int set,STACKPOS * position)1684887Schin stacktell(register STACK stack, int set, STACKPOS* position)
1694887Schin {
1704887Schin if (set) stack->position = *position;
1714887Schin else *position = stack->position;
1724887Schin }
173