1*5f2eab64SJohn Marino /*
2*5f2eab64SJohn Marino tre-stack.c - Simple stack implementation
3*5f2eab64SJohn Marino
4*5f2eab64SJohn Marino This software is released under a BSD-style license.
5*5f2eab64SJohn Marino See the file LICENSE for details and copyright.
6*5f2eab64SJohn Marino
7*5f2eab64SJohn Marino */
8*5f2eab64SJohn Marino
9*5f2eab64SJohn Marino #ifdef HAVE_CONFIG_H
10*5f2eab64SJohn Marino #include <config.h>
11*5f2eab64SJohn Marino #endif /* HAVE_CONFIG_H */
12*5f2eab64SJohn Marino #include <stdlib.h>
13*5f2eab64SJohn Marino #include <assert.h>
14*5f2eab64SJohn Marino
15*5f2eab64SJohn Marino #include "tre-internal.h"
16*5f2eab64SJohn Marino #include "tre-stack.h"
17*5f2eab64SJohn Marino #include "xmalloc.h"
18*5f2eab64SJohn Marino
19*5f2eab64SJohn Marino union tre_stack_item {
20*5f2eab64SJohn Marino void *voidptr_value;
21*5f2eab64SJohn Marino int int_value;
22*5f2eab64SJohn Marino };
23*5f2eab64SJohn Marino
24*5f2eab64SJohn Marino struct tre_stack_rec {
25*5f2eab64SJohn Marino int size;
26*5f2eab64SJohn Marino int max_size;
27*5f2eab64SJohn Marino int increment;
28*5f2eab64SJohn Marino int ptr;
29*5f2eab64SJohn Marino union tre_stack_item *stack;
30*5f2eab64SJohn Marino };
31*5f2eab64SJohn Marino
32*5f2eab64SJohn Marino
33*5f2eab64SJohn Marino tre_stack_t *
tre_stack_new(int size,int max_size,int increment)34*5f2eab64SJohn Marino tre_stack_new(int size, int max_size, int increment)
35*5f2eab64SJohn Marino {
36*5f2eab64SJohn Marino tre_stack_t *s;
37*5f2eab64SJohn Marino
38*5f2eab64SJohn Marino s = xmalloc(sizeof(*s));
39*5f2eab64SJohn Marino if (s != NULL)
40*5f2eab64SJohn Marino {
41*5f2eab64SJohn Marino s->stack = xmalloc(sizeof(*s->stack) * size);
42*5f2eab64SJohn Marino if (s->stack == NULL)
43*5f2eab64SJohn Marino {
44*5f2eab64SJohn Marino xfree(s);
45*5f2eab64SJohn Marino return NULL;
46*5f2eab64SJohn Marino }
47*5f2eab64SJohn Marino s->size = size;
48*5f2eab64SJohn Marino s->max_size = max_size;
49*5f2eab64SJohn Marino s->increment = increment;
50*5f2eab64SJohn Marino s->ptr = 0;
51*5f2eab64SJohn Marino }
52*5f2eab64SJohn Marino return s;
53*5f2eab64SJohn Marino }
54*5f2eab64SJohn Marino
55*5f2eab64SJohn Marino void
tre_stack_destroy(tre_stack_t * s)56*5f2eab64SJohn Marino tre_stack_destroy(tre_stack_t *s)
57*5f2eab64SJohn Marino {
58*5f2eab64SJohn Marino xfree(s->stack);
59*5f2eab64SJohn Marino xfree(s);
60*5f2eab64SJohn Marino }
61*5f2eab64SJohn Marino
62*5f2eab64SJohn Marino int
tre_stack_num_objects(tre_stack_t * s)63*5f2eab64SJohn Marino tre_stack_num_objects(tre_stack_t *s)
64*5f2eab64SJohn Marino {
65*5f2eab64SJohn Marino return s->ptr;
66*5f2eab64SJohn Marino }
67*5f2eab64SJohn Marino
68*5f2eab64SJohn Marino static reg_errcode_t
tre_stack_push(tre_stack_t * s,union tre_stack_item value)69*5f2eab64SJohn Marino tre_stack_push(tre_stack_t *s, union tre_stack_item value)
70*5f2eab64SJohn Marino {
71*5f2eab64SJohn Marino if (s->ptr < s->size)
72*5f2eab64SJohn Marino {
73*5f2eab64SJohn Marino s->stack[s->ptr] = value;
74*5f2eab64SJohn Marino s->ptr++;
75*5f2eab64SJohn Marino }
76*5f2eab64SJohn Marino else
77*5f2eab64SJohn Marino {
78*5f2eab64SJohn Marino if (s->size >= s->max_size)
79*5f2eab64SJohn Marino {
80*5f2eab64SJohn Marino DPRINT(("tre_stack_push: stack full\n"));
81*5f2eab64SJohn Marino return REG_ESPACE;
82*5f2eab64SJohn Marino }
83*5f2eab64SJohn Marino else
84*5f2eab64SJohn Marino {
85*5f2eab64SJohn Marino union tre_stack_item *new_buffer;
86*5f2eab64SJohn Marino int new_size;
87*5f2eab64SJohn Marino DPRINT(("tre_stack_push: trying to realloc more space\n"));
88*5f2eab64SJohn Marino new_size = s->size + s->increment;
89*5f2eab64SJohn Marino if (new_size > s->max_size)
90*5f2eab64SJohn Marino new_size = s->max_size;
91*5f2eab64SJohn Marino new_buffer = xrealloc(s->stack, sizeof(*new_buffer) * new_size);
92*5f2eab64SJohn Marino if (new_buffer == NULL)
93*5f2eab64SJohn Marino {
94*5f2eab64SJohn Marino DPRINT(("tre_stack_push: realloc failed.\n"));
95*5f2eab64SJohn Marino return REG_ESPACE;
96*5f2eab64SJohn Marino }
97*5f2eab64SJohn Marino DPRINT(("tre_stack_push: realloc succeeded.\n"));
98*5f2eab64SJohn Marino assert(new_size > s->size);
99*5f2eab64SJohn Marino s->size = new_size;
100*5f2eab64SJohn Marino s->stack = new_buffer;
101*5f2eab64SJohn Marino tre_stack_push(s, value);
102*5f2eab64SJohn Marino }
103*5f2eab64SJohn Marino }
104*5f2eab64SJohn Marino return REG_OK;
105*5f2eab64SJohn Marino }
106*5f2eab64SJohn Marino
107*5f2eab64SJohn Marino #define define_pushf(typetag, type) \
108*5f2eab64SJohn Marino declare_pushf(typetag, type) { \
109*5f2eab64SJohn Marino union tre_stack_item item; \
110*5f2eab64SJohn Marino item.typetag ## _value = value; \
111*5f2eab64SJohn Marino return tre_stack_push(s, item); \
112*5f2eab64SJohn Marino }
113*5f2eab64SJohn Marino
114*5f2eab64SJohn Marino define_pushf(int, int)
115*5f2eab64SJohn Marino define_pushf(voidptr, void *)
116*5f2eab64SJohn Marino
117*5f2eab64SJohn Marino #define define_popf(typetag, type) \
118*5f2eab64SJohn Marino declare_popf(typetag, type) { \
119*5f2eab64SJohn Marino return s->stack[--s->ptr].typetag ## _value; \
120*5f2eab64SJohn Marino }
121*5f2eab64SJohn Marino
122*5f2eab64SJohn Marino define_popf(int, int)
123*5f2eab64SJohn Marino define_popf(voidptr, void *)
124*5f2eab64SJohn Marino
125*5f2eab64SJohn Marino /* EOF */
126