1 /*
   2  * Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  *
   9  * 1. Redistributions of source code must retain the above copyright
  10  *    notice, this list of conditions and the following disclaimer.
  11  *
  12  * 2. Redistributions in binary form must reproduce the above copyright
  13  *    notice, this list of conditions and the following disclaimer in the
  14  *    documentation and/or other materials provided with the distribution.
  15  *
  16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
  17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  19  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
  20  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27  */
  28 
  29 /*
  30   tre-stack.h: Stack definitions
  31 */
  32 
  33 #ifndef _TRE_STACK_H
  34 #define _TRE_STACK_H
  35 
  36 #include "tre.h"
  37 
  38 typedef struct tre_stack_rec tre_stack_t;
  39 
  40 /* Creates a new stack object.  `size' is initial size in bytes, `max_size'
  41    is maximum size, and `increment' specifies how much more space will be
  42    allocated with realloc() if all space gets used up.  Returns the stack
  43    object or NULL if out of memory. */
  44 tre_stack_t *
  45 tre_stack_new(int size, int max_size, int increment);
  46 
  47 /* Frees the stack object. */
  48 void
  49 tre_stack_destroy(tre_stack_t *s);
  50 
  51 /* Returns the current number of objects in the stack. */
  52 int
  53 tre_stack_num_objects(tre_stack_t *s);
  54 
  55 /* Each tre_stack_push_*(tre_stack_t *s, <type> value) function pushes
  56    `value' on top of stack `s'.  Returns REG_ESPACE if out of memory.
  57    This tries to realloc() more space before failing if maximum size
  58    has not yet been reached.  Returns REG_OK if successful. */
  59 #define declare_pushf(typetag, type)                                          \
  60   reg_errcode_t tre_stack_push_ ## typetag(tre_stack_t *s, type value)
  61 
  62 declare_pushf(voidptr, void *);
  63 declare_pushf(int, int);
  64 
  65 /* Each tre_stack_pop_*(tre_stack_t *s) function pops the topmost
  66    element off of stack `s' and returns it.  The stack must not be
  67    empty. */
  68 #define declare_popf(typetag, type)               \
  69   type tre_stack_pop_ ## typetag(tre_stack_t *s)
  70 
  71 declare_popf(voidptr, void *);
  72 declare_popf(int, int);
  73 
  74 /* Just to save some typing. */
  75 #define STACK_PUSH(s, typetag, value)                                         \
  76   do                                                                          \
  77     {                                                                         \
  78       status = tre_stack_push_ ## typetag(s, value);                          \
  79     }                                                                         \
  80   while (/*CONSTCOND*/0)
  81 
  82 #define STACK_PUSHX(s, typetag, value)                                        \
  83   {                                                                           \
  84     status = tre_stack_push_ ## typetag(s, value);                            \
  85     if (status != REG_OK)                                                     \
  86       break;                                                                  \
  87   }
  88 
  89 #define STACK_PUSHR(s, typetag, value)                                        \
  90   {                                                                           \
  91     reg_errcode_t _status;                                                    \
  92     _status = tre_stack_push_ ## typetag(s, value);                           \
  93     if (_status != REG_OK)                                                    \
  94       return _status;                                                         \
  95   }
  96 
  97 #endif  /* _TRE_STACK_H */