1 : /*
2 : +----------------------------------------------------------------------+
3 : | Zend Engine |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1998-2009 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: zend_stack.c 272367 2008-12-31 11:12:40Z sebastian $ */
21 :
22 : #include "zend.h"
23 : #include "zend_stack.h"
24 :
25 : ZEND_API int zend_stack_init(zend_stack *stack) /* {{{ */
26 263525 : {
27 263525 : stack->top = 0;
28 263525 : stack->elements = (void **) emalloc(sizeof(void **) * STACK_BLOCK_SIZE);
29 263525 : if (!stack->elements) {
30 0 : return FAILURE;
31 : } else {
32 263525 : stack->max = STACK_BLOCK_SIZE;
33 263525 : return SUCCESS;
34 : }
35 : }
36 : /* }}} */
37 :
38 : ZEND_API int zend_stack_push(zend_stack *stack, const void *element, int size) /* {{{ */
39 2049907 : {
40 2049907 : if (stack->top >= stack->max) { /* we need to allocate more memory */
41 1248 : stack->elements = (void **) erealloc(stack->elements,
42 : (sizeof(void **) * (stack->max += STACK_BLOCK_SIZE)));
43 1248 : if (!stack->elements) {
44 0 : return FAILURE;
45 : }
46 : }
47 2049907 : stack->elements[stack->top] = (void *) emalloc(size);
48 2049907 : memcpy(stack->elements[stack->top], element, size);
49 2049907 : return stack->top++;
50 : }
51 : /* }}} */
52 :
53 : ZEND_API int zend_stack_top(const zend_stack *stack, void **element) /* {{{ */
54 1690883 : {
55 1690883 : if (stack->top > 0) {
56 1668487 : *element = stack->elements[stack->top - 1];
57 1668487 : return SUCCESS;
58 : } else {
59 22396 : *element = NULL;
60 22396 : return FAILURE;
61 : }
62 : }
63 : /* }}} */
64 :
65 : ZEND_API int zend_stack_del_top(zend_stack *stack) /* {{{ */
66 1308354 : {
67 1308354 : if (stack->top > 0) {
68 1308354 : efree(stack->elements[--stack->top]);
69 : }
70 1308354 : return SUCCESS;
71 : }
72 : /* }}} */
73 :
74 : ZEND_API int zend_stack_int_top(const zend_stack *stack) /* {{{ */
75 0 : {
76 : int *e;
77 :
78 0 : if (zend_stack_top(stack, (void **) &e) == FAILURE) {
79 0 : return FAILURE; /* this must be a negative number, since negative numbers can't be address numbers */
80 : } else {
81 0 : return *e;
82 : }
83 : }
84 : /* }}} */
85 :
86 : ZEND_API int zend_stack_is_empty(const zend_stack *stack) /* {{{ */
87 137784 : {
88 137784 : if (stack->top == 0) {
89 25060 : return 1;
90 : } else {
91 112724 : return 0;
92 : }
93 : }
94 : /* }}} */
95 :
96 : ZEND_API int zend_stack_destroy(zend_stack *stack) /* {{{ */
97 263474 : {
98 : int i;
99 :
100 263474 : if (stack->elements) {
101 1005014 : for (i = 0; i < stack->top; i++) {
102 741540 : efree(stack->elements[i]);
103 : }
104 :
105 263474 : efree(stack->elements);
106 : }
107 :
108 263474 : return SUCCESS;
109 : }
110 : /* }}} */
111 :
112 : ZEND_API void **zend_stack_base(const zend_stack *stack) /* {{{ */
113 0 : {
114 0 : return stack->elements;
115 : }
116 : /* }}} */
117 :
118 : ZEND_API int zend_stack_count(const zend_stack *stack) /* {{{ */
119 212378 : {
120 212378 : return stack->top;
121 : }
122 : /* }}} */
123 :
124 : ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function)(void *element)) /* {{{ */
125 153156 : {
126 : int i;
127 :
128 153156 : switch (type) {
129 : case ZEND_STACK_APPLY_TOPDOWN:
130 154323 : for (i=stack->top-1; i>=0; i--) {
131 103157 : if (apply_function(stack->elements[i])) {
132 101990 : break;
133 : }
134 : }
135 153156 : break;
136 : case ZEND_STACK_APPLY_BOTTOMUP:
137 0 : for (i=0; i<stack->top; i++) {
138 0 : if (apply_function(stack->elements[i])) {
139 0 : break;
140 : }
141 : }
142 : break;
143 : }
144 153156 : }
145 : /* }}} */
146 :
147 : ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (*apply_function)(void *element, void *arg), void *arg) /* {{{ */
148 147012 : {
149 : int i;
150 :
151 147012 : switch (type) {
152 : case ZEND_STACK_APPLY_TOPDOWN:
153 147002 : for (i=stack->top-1; i>=0; i--) {
154 147002 : if (apply_function(stack->elements[i], arg)) {
155 147002 : break;
156 : }
157 : }
158 147002 : break;
159 : case ZEND_STACK_APPLY_BOTTOMUP:
160 29 : for (i=0; i<stack->top; i++) {
161 19 : if (apply_function(stack->elements[i], arg)) {
162 0 : break;
163 : }
164 : }
165 : break;
166 : }
167 147012 : }
168 : /* }}} */
169 :
170 : /*
171 : * Local variables:
172 : * tab-width: 4
173 : * c-basic-offset: 4
174 : * indent-tabs-mode: t
175 : * End:
176 : */
|