Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/misc/stack.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
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
174