This source file includes following definitions.
- zend_stack_init
- zend_stack_push
- zend_stack_top
- zend_stack_del_top
- zend_stack_int_top
- zend_stack_is_empty
- zend_stack_destroy
- zend_stack_base
- zend_stack_count
- zend_stack_apply
- zend_stack_apply_with_argument
- zend_stack_clean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
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
170
171
172
173
174