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