xref: /netbsd-src/external/gpl2/xcvs/dist/src/stack.c (revision 5a6c14c844c4c665da5632061aebde7bb2cb5766)
1 /*
2  * Copyright (C) 2004-2005 The Free Software Foundation, Inc.
3  *
4  * Portions Copyright (C) 2004-2005 Derek Price, Ximbiot <http://ximbiot.com>,
5  *                                  and others.
6  *
7  * You may distribute under the terms of the GNU General Public License as
8  * specified in the README file that comes with the CVS source distribution.
9  *
10  * This module uses the hash.c module to implement a stack.
11  */
12 #include <sys/cdefs.h>
13 __RCSID("$NetBSD: stack.c,v 1.2 2016/05/17 14:00:09 christos Exp $");
14 
15 #include "cvs.h"
16 #include <assert.h>
17 
18 
19 
20 static void
do_push(List * stack,void * elem,int isstring)21 do_push (List *stack, void *elem, int isstring)
22 {
23     Node *p = getnode();
24 
25     if (isstring)
26 	p->key = elem;
27     else
28 	p->data = elem;
29 
30     addnode(stack, p);
31 }
32 
33 
34 
35 void
push(List * stack,void * elem)36 push (List *stack, void *elem)
37 {
38     do_push (stack, elem, 0);
39 }
40 
41 
42 
43 void
push_string(List * stack,char * elem)44 push_string (List *stack, char *elem)
45 {
46     do_push (stack, elem, 1);
47 }
48 
49 
50 
51 static void *
do_pop(List * stack,int isstring)52 do_pop (List *stack, int isstring)
53 {
54     void *elem;
55 
56     if (isempty (stack)) return NULL;
57 
58     if (isstring)
59     {
60 	elem = stack->list->prev->key;
61 	stack->list->prev->key = NULL;
62     }
63     else
64     {
65 	elem = stack->list->prev->data;
66 	stack->list->prev->data = NULL;
67     }
68 
69     delnode (stack->list->prev);
70     return elem;
71 }
72 
73 
74 
75 void *
pop(List * stack)76 pop (List *stack)
77 {
78     return do_pop (stack, 0);
79 }
80 
81 
82 
83 char *
pop_string(List * stack)84 pop_string (List *stack)
85 {
86     return do_pop (stack, 1);
87 }
88 
89 
90 
91 static void
do_unshift(List * stack,void * elem,int isstring)92 do_unshift (List *stack, void *elem, int isstring)
93 {
94     Node *p = getnode();
95 
96     if (isstring)
97 	p->key = elem;
98     else
99 	p->data = elem;
100 
101     addnode_at_front(stack, p);
102 }
103 
104 
105 
106 void
unshift(List * stack,void * elem)107 unshift (List *stack, void *elem)
108 {
109     do_unshift (stack, elem, 0);
110 }
111 
112 
113 
114 void
unshift_string(List * stack,char * elem)115 unshift_string (List *stack, char *elem)
116 {
117     do_unshift (stack, elem, 1);
118 }
119 
120 
121 
122 static void *
do_shift(List * stack,int isstring)123 do_shift (List *stack, int isstring)
124 {
125     void *elem;
126 
127     if (isempty (stack)) return NULL;
128 
129     if (isstring)
130     {
131 	elem = stack->list->next->key;
132 	stack->list->next->key = NULL;
133     }
134     else
135     {
136 	elem = stack->list->next->data;
137 	stack->list->next->data = NULL;
138     }
139     delnode (stack->list->next);
140     return elem;
141 }
142 
143 
144 
145 void *
shift(List * stack)146 shift (List *stack)
147 {
148     return do_shift (stack, 0);
149 }
150 
151 
152 
153 char *
shift_string(List * stack)154 shift_string (List *stack)
155 {
156     return do_shift (stack, 1);
157 }
158 
159 
160 
161 int
isempty(List * stack)162 isempty (List *stack)
163 {
164     if (stack->list == stack->list->next)
165 	return 1;
166     return 0;
167 }
168