root/Zend/zend_stack.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zend_stack_init
  2. zend_stack_push
  3. zend_stack_top
  4. zend_stack_del_top
  5. zend_stack_int_top
  6. zend_stack_is_empty
  7. zend_stack_destroy
  8. zend_stack_base
  9. zend_stack_count
  10. zend_stack_apply
  11. zend_stack_apply_with_argument
  12. zend_stack_clean

   1 /*
   2    +----------------------------------------------------------------------+
   3    | Zend Engine                                                          |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1998-2016 Zend Technologies Ltd. (http://www.zend.com) |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 2.00 of the Zend license,     |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.zend.com/license/2_00.txt.                                |
  11    | If you did not receive a copy of the Zend license and are unable to  |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@zend.com so we can mail you a copy immediately.              |
  14    +----------------------------------------------------------------------+
  15    | Authors: Andi Gutmans <andi@zend.com>                                |
  16    |          Zeev Suraski <zeev@zend.com>                                |
  17    +----------------------------------------------------------------------+
  18 */
  19 
  20 /* $Id$ */
  21 
  22 #include "zend.h"
  23 #include "zend_stack.h"
  24 
  25 #define ZEND_STACK_ELEMENT(stack, n) ((void *)((char *) (stack)->elements + (stack)->size * (n)))
  26 
  27 ZEND_API int zend_stack_init(zend_stack *stack, int size)
  28 {
  29         stack->size = size;
  30         stack->top = 0;
  31         stack->max = 0;
  32         stack->elements = NULL;
  33         return SUCCESS;
  34 }
  35 
  36 ZEND_API int zend_stack_push(zend_stack *stack, const void *element)
  37 {
  38         /* We need to allocate more memory */
  39         if (stack->top >= stack->max) {
  40                 stack->max += STACK_BLOCK_SIZE;
  41                 stack->elements = safe_erealloc(stack->elements, stack->size, stack->max, 0);
  42         }
  43         memcpy(ZEND_STACK_ELEMENT(stack, stack->top), element, stack->size);
  44         return stack->top++;
  45 }
  46 
  47 
  48 ZEND_API void *zend_stack_top(const zend_stack *stack)
  49 {
  50         if (stack->top > 0) {
  51                 return ZEND_STACK_ELEMENT(stack, stack->top - 1);
  52         } else {
  53                 return NULL;
  54         }
  55 }
  56 
  57 
  58 ZEND_API int zend_stack_del_top(zend_stack *stack)
  59 {
  60         --stack->top;
  61         return SUCCESS;
  62 }
  63 
  64 
  65 ZEND_API int zend_stack_int_top(const zend_stack *stack)
  66 {
  67         int *e = zend_stack_top(stack);
  68         if (e) {
  69                 return *e;
  70         } else {
  71                 return FAILURE;
  72         }
  73 }
  74 
  75 
  76 ZEND_API int zend_stack_is_empty(const zend_stack *stack)
  77 {
  78         return stack->top == 0;
  79 }
  80 
  81 
  82 ZEND_API int zend_stack_destroy(zend_stack *stack)
  83 {
  84         if (stack->elements) {
  85                 efree(stack->elements);
  86                 stack->elements = NULL;
  87         }
  88 
  89         return SUCCESS;
  90 }
  91 
  92 
  93 ZEND_API void *zend_stack_base(const zend_stack *stack)
  94 {
  95         return stack->elements;
  96 }
  97 
  98 
  99 ZEND_API int zend_stack_count(const zend_stack *stack)
 100 {
 101         return stack->top;
 102 }
 103 
 104 
 105 ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function)(void *element))
 106 {
 107         int i;
 108 
 109         switch (type) {
 110                 case ZEND_STACK_APPLY_TOPDOWN:
 111                         for (i=stack->top-1; i>=0; i--) {
 112                                 if (apply_function(ZEND_STACK_ELEMENT(stack, i))) {
 113                                         break;
 114                                 }
 115                         }
 116                         break;
 117                 case ZEND_STACK_APPLY_BOTTOMUP:
 118                         for (i=0; i<stack->top; i++) {
 119                                 if (apply_function(ZEND_STACK_ELEMENT(stack, i))) {
 120                                         break;
 121                                 }
 122                         }
 123                         break;
 124         }
 125 }
 126 
 127 
 128 ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (*apply_function)(void *element, void *arg), void *arg)
 129 {
 130         int i;
 131 
 132         switch (type) {
 133                 case ZEND_STACK_APPLY_TOPDOWN:
 134                         for (i=stack->top-1; i>=0; i--) {
 135                                 if (apply_function(ZEND_STACK_ELEMENT(stack, i), arg)) {
 136                                         break;
 137                                 }
 138                         }
 139                         break;
 140                 case ZEND_STACK_APPLY_BOTTOMUP:
 141                         for (i=0; i<stack->top; i++) {
 142                                 if (apply_function(ZEND_STACK_ELEMENT(stack, i), arg)) {
 143                                         break;
 144                                 }
 145                         }
 146                         break;
 147         }
 148 }
 149 
 150 ZEND_API void zend_stack_clean(zend_stack *stack, void (*func)(void *), zend_bool free_elements)
 151 {
 152         int i;
 153 
 154         if (func) {
 155                 for (i = 0; i < stack->top; i++) {
 156                         func(ZEND_STACK_ELEMENT(stack, i));
 157                 }
 158         }
 159         if (free_elements) {
 160                 if (stack->elements) {
 161                         efree(stack->elements);
 162                         stack->elements = NULL;
 163                 }
 164                 stack->top = stack->max = 0;
 165         }
 166 }
 167 
 168 /*
 169  * Local variables:
 170  * tab-width: 4
 171  * c-basic-offset: 4
 172  * indent-tabs-mode: t
 173  * End:
 174  */

/* [<][>][^][v][top][bottom][index][help] */