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