1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
24 * pointer stack routines
27 static const char id_stack
[] = "\n@(#)$Id: stack (AT&T Bell Laboratories) 1984-05-01 $\0\n";
37 stackalloc(register int size
, void* error
)
40 register struct stackblock
*b
;
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)))
49 if (!(b
->stack
= newof(0, void*, size
, 0)))
58 stack
->position
.block
= b
;
59 stack
->position
.index
= -1;
70 stackfree(register STACK stack
)
72 register struct stackblock
* b
;
73 register struct stackblock
* p
;
90 stackclear(register STACK stack
)
92 stack
->position
.block
= stack
->blocks
;
93 stack
->position
.index
= -1;
97 * get value on top of stack
101 stackget(register STACK stack
)
103 if (stack
->position
.index
< 0) return(stack
->error
);
104 else return(stack
->position
.block
->stack
[stack
->position
.index
]);
108 * push value on to stack
112 stackpush(register STACK stack
, void* value
)
114 register struct stackblock
*b
;
116 if (++stack
->position
.index
>= stack
->size
)
118 b
= stack
->position
.block
;
119 if (b
->next
) b
= b
->next
;
122 if (!(b
->next
= newof(0, struct stackblock
, 1, 0)))
125 if (!(b
->stack
= newof(0, void*, stack
->size
, 0)))
127 b
->prev
= stack
->position
.block
;
130 stack
->position
.block
= b
;
131 stack
->position
.index
= 0;
133 stack
->position
.block
->stack
[stack
->position
.index
] = value
;
138 * pop value off stack
142 stackpop(register STACK stack
)
147 * -1 if stack empty before pop
148 * 0 if stack empty after pop
149 * 1 if stack not empty before & after pop
152 if (stack
->position
.index
< 0) return(-1);
153 else if (--stack
->position
.index
< 0)
155 if (!stack
->position
.block
->prev
) return(0);
156 stack
->position
.block
= stack
->position
.block
->prev
;
157 stack
->position
.index
= stack
->size
- 1;
164 * set|get stack position
168 stacktell(register STACK stack
, int set
, STACKPOS
* position
)
170 if (set
) stack
->position
= *position
;
171 else *position
= stack
->position
;