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
13#include "cvs.h"
14#include <assert.h>
15
16
17
18static void
19do_push (stack, elem, isstring)
20    List *stack;
21    void *elem;
22    int isstring;
23{
24    Node *p = getnode();
25
26    if (isstring)
27	p->key = elem;
28    else
29	p->data = elem;
30
31    addnode(stack, p);
32}
33
34
35
36void
37push (stack, elem)
38    List *stack;
39    void *elem;
40{
41    do_push (stack, elem, 0);
42}
43
44
45
46void
47push_string (stack, elem)
48    List *stack;
49    char *elem;
50{
51    do_push (stack, elem, 1);
52}
53
54
55
56static void *
57do_pop (stack, isstring)
58    List *stack;
59    int isstring;
60{
61    void *elem;
62
63    if (isempty (stack)) return NULL;
64
65    if (isstring)
66    {
67	elem = stack->list->prev->key;
68	stack->list->prev->key = NULL;
69    }
70    else
71    {
72	elem = stack->list->prev->data;
73	stack->list->prev->data = NULL;
74    }
75
76    delnode (stack->list->prev);
77    return elem;
78}
79
80
81
82void *
83pop (stack)
84    List *stack;
85{
86    return do_pop (stack, 0);
87}
88
89
90
91char *
92pop_string (stack)
93    List *stack;
94{
95    return do_pop (stack, 1);
96}
97
98
99
100static void
101do_unshift (stack, elem, isstring)
102    List *stack;
103    void *elem;
104    int isstring;
105{
106    Node *p = getnode();
107
108    if (isstring)
109	p->key = elem;
110    else
111	p->data = elem;
112
113    addnode_at_front(stack, p);
114}
115
116
117
118void
119unshift (stack, elem)
120    List *stack;
121    void *elem;
122{
123    do_unshift (stack, elem, 0);
124}
125
126
127
128void
129unshift_string (stack, elem)
130    List *stack;
131    char *elem;
132{
133    do_unshift (stack, elem, 1);
134}
135
136
137
138static void *
139do_shift (stack, isstring)
140    List *stack;
141    int isstring;
142{
143    void *elem;
144
145    if (isempty (stack)) return NULL;
146
147    if (isstring)
148    {
149	elem = stack->list->next->key;
150	stack->list->next->key = NULL;
151    }
152    else
153    {
154	elem = stack->list->next->data;
155	stack->list->next->data = NULL;
156    }
157    delnode (stack->list->next);
158    return elem;
159}
160
161
162
163void *
164shift (stack)
165    List *stack;
166{
167    return do_shift (stack, 0);
168}
169
170
171
172char *
173shift_string (stack)
174    List *stack;
175{
176    return do_shift (stack, 1);
177}
178
179
180
181int
182isempty (stack)
183    List *stack;
184{
185    if (stack->list == stack->list->next)
186	return 1;
187    return 0;
188}
189