1 /*
2 Copyright (C) 2003 Cedric Cellier, Dominique Lavault
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 #include "stack.h"
19 #include "log.h"
20 #include "memspool.h"
21 #include <assert.h>
22 #define STR(x) #x
23 #define XSTR(x) STR(x)
24
25 struct s_gltv_stack {
26 unsigned next;
27 unsigned max_size;
28 char resizeable;
29 void **entries;
30 };
31
32 /* TODO add stack_compact and use it if resizeable in pop and clear to match initial size */
33
gltv_stack_new(unsigned max_size,char resizeable)34 gltv_stack *gltv_stack_new(unsigned max_size, char resizeable) {
35 gltv_stack *this_stack;
36 this_stack = gltv_memspool_alloc(sizeof(*this_stack));
37 if (!this_stack) return 0;
38 this_stack->entries = gltv_memspool_alloc(max_size*sizeof(*this_stack->entries));
39 if (!this_stack->entries) {
40 gltv_memspool_unregister(this_stack);
41 return 0;
42 }
43 this_stack->max_size = max_size;
44 this_stack->next = 0;
45 this_stack->resizeable = resizeable;
46 return this_stack;
47 }
48
gltv_stack_del(gltv_stack * s)49 void gltv_stack_del(gltv_stack *s) {
50 gltv_memspool_unregister(s->entries);
51 gltv_memspool_unregister(s);
52 }
53
gltv_stack_push(gltv_stack * s,void * value)54 int gltv_stack_push(gltv_stack *s, void *value) {
55 assert(s->next<=s->max_size);
56 if (s->next == s->max_size) {
57 if (s->resizeable) {
58 s->max_size <<= 1;
59 if (!(s->entries = gltv_memspool_realloc(s->entries, s->max_size*sizeof(*s->entries))) )
60 gltv_log_fatal(XSTR(__FILE__) XSTR(__LINE__) "Can't resize stack");
61 } else {
62 return 0;
63 }
64 }
65 s->entries[s->next++] = value;
66 return 1;
67 }
68
gltv_stack_pop(gltv_stack * s)69 void *gltv_stack_pop(gltv_stack *s) {
70 assert(s->next>0);
71 return s->entries[--s->next];
72 }
73
gltv_stack_clear(gltv_stack * s)74 void gltv_stack_clear(gltv_stack *s) {
75 s->next = 0;
76 }
77
gltv_stack_size(gltv_stack * s)78 unsigned gltv_stack_size(gltv_stack *s) {
79 return s->next;
80 }
81
82