Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libast / misc / stack.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: stack.c /main/3 1995/11/01 18:04:55 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *         THIS IS PROPRIETARY SOURCE CODE LICENSED BY          *
29 *                          AT&T CORP.                          *
30 *                                                              *
31 *                Copyright (c) 1995 AT&T Corp.                 *
32 *                     All Rights Reserved                      *
33 *                                                              *
34 *           This software is licensed by AT&T Corp.            *
35 *       under the terms and conditions of the license in       *
36 *       http://www.research.att.com/orgs/ssr/book/reuse        *
37 *                                                              *
38 *               This software was created by the               *
39 *           Software Engineering Research Department           *
40 *                    AT&T Bell Laboratories                    *
41 *                                                              *
42 *               For further information contact                *
43 *                     gsf@research.att.com                     *
44 *                                                              *
45 ***************************************************************/
46
47 /* : : generated by proto : : */
48
49 #if !defined(__PROTO__)
50 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
51 #if defined(__cplusplus)
52 #define __MANGLE__      "C"
53 #else
54 #define __MANGLE__
55 #endif
56 #define __STDARG__
57 #define __PROTO__(x)    x
58 #define __OTORP__(x)
59 #define __PARAM__(n,o)  n
60 #if !defined(__STDC__) && !defined(__cplusplus)
61 #if !defined(c_plusplus)
62 #define const
63 #endif
64 #define signed
65 #define void            int
66 #define volatile
67 #define __V_            char
68 #else
69 #define __V_            void
70 #endif
71 #else
72 #define __PROTO__(x)    ()
73 #define __OTORP__(x)    x
74 #define __PARAM__(n,o)  o
75 #define __MANGLE__
76 #define __V_            char
77 #define const
78 #define signed
79 #define void            int
80 #define volatile
81 #endif
82 #if defined(__cplusplus) || defined(c_plusplus)
83 #define __VARARG__      ...
84 #else
85 #define __VARARG__
86 #endif
87 #if defined(__STDARG__)
88 #define __VA_START__(p,a)       va_start(p,a)
89 #else
90 #define __VA_START__(p,a)       va_start(p)
91 #endif
92 #endif
93 static const char id_stack[] = "\n@(#)stack (AT&T Bell Laboratories) 05/01/84\0\n";
94
95 #include <ast.h>
96 #include <stack.h>
97
98 /*
99  * create a new stack
100  */
101
102 STACK
103 stackalloc __PARAM__((register int size, __V_* error), (size, error)) __OTORP__(register int size; __V_* error;){
104         register STACK                  stack;
105         register struct stackblock      *b;
106
107         if (size <= 0) size = 100;
108         if (!(stack = newof(0, struct stacktable, 1, 0))) return(0);
109         if (!(b = newof(0, struct stackblock, 1, 0)))
110         {
111                 free(stack);
112                 return(0);
113         }
114         if (!(b->stack = newof(0, __V_*, size, 0)))
115         {
116                 free(b);
117                 free(stack);
118                 return(0);
119         }
120         stack->blocks = b;
121         stack->size = size;
122         stack->error = error;
123         stack->position.block = b;
124         stack->position.index = -1;
125         b->next = 0;
126         b->prev = 0;
127         return(stack);
128 }
129
130 /*
131  * remove a stack
132  */
133
134 void
135 stackfree __PARAM__((register STACK stack), (stack)) __OTORP__(register STACK stack;){
136         register struct stackblock*     b;
137         register struct stackblock*     p;
138
139         b = stack->blocks;
140         while (p = b)
141         {
142                 b = p->next;
143                 free(p->stack);
144                 free(p);
145         }
146         free(stack);
147 }
148
149 /*
150  * clear stack
151  */
152
153 void
154 stackclear __PARAM__((register STACK stack), (stack)) __OTORP__(register STACK stack;){
155         stack->position.block = stack->blocks;
156         stack->position.index = -1;
157 }
158
159 /*
160  * get value on top of stack
161  */
162
163 __V_*
164 stackget __PARAM__((register STACK stack), (stack)) __OTORP__(register STACK stack;){
165         if (stack->position.index < 0) return(stack->error);
166         else return(stack->position.block->stack[stack->position.index]);
167 }
168
169 /*
170  * push value on to stack
171  */
172
173 int
174 stackpush __PARAM__((register STACK stack, __V_* value), (stack, value)) __OTORP__(register STACK stack; __V_* value;){
175         register struct stackblock      *b;
176
177         if (++stack->position.index >= stack->size)
178         {
179                 b = stack->position.block;
180                 if (b->next) b = b->next;
181                 else
182                 {
183                         if (!(b->next = newof(0, struct stackblock, 1, 0)))
184                                 return(-1);
185                         b = b->next;
186                         if (!(b->stack = newof(0, __V_*, stack->size, 0)))
187                                 return(-1);
188                         b->prev = stack->position.block;
189                         b->next = 0;
190                 }
191                 stack->position.block = b;
192                 stack->position.index = 0;
193         }
194         stack->position.block->stack[stack->position.index] = value;
195         return(0);
196 }
197
198 /*
199  * pop value off stack
200  */
201
202 int
203 stackpop __PARAM__((register STACK stack), (stack)) __OTORP__(register STACK stack;){
204         /*
205          * return:
206          *
207          *      -1      if stack empty before pop
208          *       0      if stack empty after pop
209          *       1      if stack not empty before & after pop
210          */
211
212         if (stack->position.index < 0) return(-1);
213         else if (--stack->position.index < 0)
214         {
215                 if (!stack->position.block->prev) return(0);
216                 stack->position.block = stack->position.block->prev;
217                 stack->position.index = stack->size - 1;
218                 return(1);
219         }
220         else return(1);
221 }
222
223 /*
224  * set|get stack position
225  */
226
227 void
228 stacktell __PARAM__((register STACK stack, int set, STACKPOS* position), (stack, set, position)) __OTORP__(register STACK stack; int set; STACKPOS* position;){
229         if (set) stack->position = *position;
230         else *position = stack->position;
231 }