xref: /dflybsd-src/contrib/tre/lib/tre-stack.c (revision 071cbfc5b674dbc05e198747dddf53a507e3290a)
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