xref: /netbsd-src/external/bsd/tre/dist/lib/tre-stack.c (revision f2a3d14797d93b3276c22bce2e57926bf739c955)
163d4abf0Sagc /*
263d4abf0Sagc   tre-stack.c - Simple stack implementation
363d4abf0Sagc 
463d4abf0Sagc   This software is released under a BSD-style license.
563d4abf0Sagc   See the file LICENSE for details and copyright.
663d4abf0Sagc 
763d4abf0Sagc */
863d4abf0Sagc 
963d4abf0Sagc #ifdef HAVE_CONFIG_H
1063d4abf0Sagc #include <config.h>
1163d4abf0Sagc #endif /* HAVE_CONFIG_H */
1263d4abf0Sagc #include <stdlib.h>
1363d4abf0Sagc #include <assert.h>
1463d4abf0Sagc 
1563d4abf0Sagc #include "tre-internal.h"
1663d4abf0Sagc #include "tre-stack.h"
1763d4abf0Sagc #include "xmalloc.h"
1863d4abf0Sagc 
1963d4abf0Sagc union tre_stack_item {
2063d4abf0Sagc   void *voidptr_value;
21*f2a3d147Schristos   long long_value;
2263d4abf0Sagc };
2363d4abf0Sagc 
2463d4abf0Sagc struct tre_stack_rec {
2563d4abf0Sagc   int size;
2663d4abf0Sagc   int max_size;
2763d4abf0Sagc   int increment;
2863d4abf0Sagc   int ptr;
2963d4abf0Sagc   union tre_stack_item *stack;
3063d4abf0Sagc };
3163d4abf0Sagc 
3263d4abf0Sagc 
3363d4abf0Sagc tre_stack_t *
tre_stack_new(int size,int max_size,int increment)3463d4abf0Sagc tre_stack_new(int size, int max_size, int increment)
3563d4abf0Sagc {
3663d4abf0Sagc   tre_stack_t *s;
3763d4abf0Sagc 
3863d4abf0Sagc   s = xmalloc(sizeof(*s));
3963d4abf0Sagc   if (s != NULL)
4063d4abf0Sagc     {
4163d4abf0Sagc       s->stack = xmalloc(sizeof(*s->stack) * size);
4263d4abf0Sagc       if (s->stack == NULL)
4363d4abf0Sagc 	{
4463d4abf0Sagc 	  xfree(s);
4563d4abf0Sagc 	  return NULL;
4663d4abf0Sagc 	}
4763d4abf0Sagc       s->size = size;
4863d4abf0Sagc       s->max_size = max_size;
4963d4abf0Sagc       s->increment = increment;
5063d4abf0Sagc       s->ptr = 0;
5163d4abf0Sagc     }
5263d4abf0Sagc   return s;
5363d4abf0Sagc }
5463d4abf0Sagc 
5563d4abf0Sagc void
tre_stack_destroy(tre_stack_t * s)5663d4abf0Sagc tre_stack_destroy(tre_stack_t *s)
5763d4abf0Sagc {
5863d4abf0Sagc   xfree(s->stack);
5963d4abf0Sagc   xfree(s);
6063d4abf0Sagc }
6163d4abf0Sagc 
6263d4abf0Sagc int
tre_stack_num_objects(tre_stack_t * s)6363d4abf0Sagc tre_stack_num_objects(tre_stack_t *s)
6463d4abf0Sagc {
6563d4abf0Sagc   return s->ptr;
6663d4abf0Sagc }
6763d4abf0Sagc 
6863d4abf0Sagc static reg_errcode_t
tre_stack_push(tre_stack_t * s,union tre_stack_item value)6963d4abf0Sagc tre_stack_push(tre_stack_t *s, union tre_stack_item value)
7063d4abf0Sagc {
7163d4abf0Sagc   if (s->ptr < s->size)
7263d4abf0Sagc     {
7363d4abf0Sagc       s->stack[s->ptr] = value;
7463d4abf0Sagc       s->ptr++;
7563d4abf0Sagc     }
7663d4abf0Sagc   else
7763d4abf0Sagc     {
7863d4abf0Sagc       if (s->size >= s->max_size)
7963d4abf0Sagc 	{
8063d4abf0Sagc 	  DPRINT(("tre_stack_push: stack full\n"));
8163d4abf0Sagc 	  return REG_ESPACE;
8263d4abf0Sagc 	}
8363d4abf0Sagc       else
8463d4abf0Sagc 	{
8563d4abf0Sagc 	  union tre_stack_item *new_buffer;
8663d4abf0Sagc 	  int new_size;
8763d4abf0Sagc 	  DPRINT(("tre_stack_push: trying to realloc more space\n"));
8863d4abf0Sagc 	  new_size = s->size + s->increment;
8963d4abf0Sagc 	  if (new_size > s->max_size)
9063d4abf0Sagc 	    new_size = s->max_size;
9163d4abf0Sagc 	  new_buffer = xrealloc(s->stack, sizeof(*new_buffer) * new_size);
9263d4abf0Sagc 	  if (new_buffer == NULL)
9363d4abf0Sagc 	    {
9463d4abf0Sagc 	      DPRINT(("tre_stack_push: realloc failed.\n"));
9563d4abf0Sagc 	      return REG_ESPACE;
9663d4abf0Sagc 	    }
9763d4abf0Sagc 	  DPRINT(("tre_stack_push: realloc succeeded.\n"));
9863d4abf0Sagc 	  assert(new_size > s->size);
9963d4abf0Sagc 	  s->size = new_size;
10063d4abf0Sagc 	  s->stack = new_buffer;
10163d4abf0Sagc 	  tre_stack_push(s, value);
10263d4abf0Sagc 	}
10363d4abf0Sagc     }
10463d4abf0Sagc   return REG_OK;
10563d4abf0Sagc }
10663d4abf0Sagc 
10763d4abf0Sagc #define define_pushf(typetag, type)  \
10863d4abf0Sagc   declare_pushf(typetag, type) {     \
10963d4abf0Sagc     union tre_stack_item item;	     \
11063d4abf0Sagc     item.typetag ## _value = value;  \
11163d4abf0Sagc     return tre_stack_push(s, item);  \
11263d4abf0Sagc }
11363d4abf0Sagc 
114*f2a3d147Schristos define_pushf(long, long)
11563d4abf0Sagc define_pushf(voidptr, void *)
11663d4abf0Sagc 
11763d4abf0Sagc #define define_popf(typetag, type)		    \
11863d4abf0Sagc   declare_popf(typetag, type) {			    \
11963d4abf0Sagc     return s->stack[--s->ptr].typetag ## _value;    \
12063d4abf0Sagc   }
12163d4abf0Sagc 
122*f2a3d147Schristos define_popf(long, long)
12363d4abf0Sagc define_popf(voidptr, void *)
12463d4abf0Sagc 
12563d4abf0Sagc /* EOF */
126