1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 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@php.net> |
16 | Zeev Suraski <zeev@php.net> |
17 +----------------------------------------------------------------------+
18 */
19
20 #include "zend.h"
21 #include "zend_ptr_stack.h"
22 #include <stdarg.h>
23
zend_ptr_stack_init_ex(zend_ptr_stack * stack,bool persistent)24 ZEND_API void zend_ptr_stack_init_ex(zend_ptr_stack *stack, bool persistent)
25 {
26 stack->top_element = stack->elements = NULL;
27 stack->top = stack->max = 0;
28 stack->persistent = persistent;
29 }
30
zend_ptr_stack_init(zend_ptr_stack * stack)31 ZEND_API void zend_ptr_stack_init(zend_ptr_stack *stack)
32 {
33 zend_ptr_stack_init_ex(stack, 0);
34 }
35
36
zend_ptr_stack_n_push(zend_ptr_stack * stack,int count,...)37 ZEND_API void zend_ptr_stack_n_push(zend_ptr_stack *stack, int count, ...)
38 {
39 va_list ptr;
40 void *elem;
41
42 ZEND_PTR_STACK_RESIZE_IF_NEEDED(stack, count)
43
44 va_start(ptr, count);
45 while (count>0) {
46 elem = va_arg(ptr, void *);
47 stack->top++;
48 *(stack->top_element++) = elem;
49 count--;
50 }
51 va_end(ptr);
52 }
53
54
zend_ptr_stack_n_pop(zend_ptr_stack * stack,int count,...)55 ZEND_API void zend_ptr_stack_n_pop(zend_ptr_stack *stack, int count, ...)
56 {
57 va_list ptr;
58 void **elem;
59
60 va_start(ptr, count);
61 while (count>0) {
62 elem = va_arg(ptr, void **);
63 *elem = *(--stack->top_element);
64 stack->top--;
65 count--;
66 }
67 va_end(ptr);
68 }
69
70
71
zend_ptr_stack_destroy(zend_ptr_stack * stack)72 ZEND_API void zend_ptr_stack_destroy(zend_ptr_stack *stack)
73 {
74 if (stack->elements) {
75 pefree(stack->elements, stack->persistent);
76 }
77 }
78
79
zend_ptr_stack_apply(zend_ptr_stack * stack,void (* func)(void *))80 ZEND_API void zend_ptr_stack_apply(zend_ptr_stack *stack, void (*func)(void *))
81 {
82 int i = stack->top;
83
84 while (--i >= 0) {
85 func(stack->elements[i]);
86 }
87 }
88
zend_ptr_stack_reverse_apply(zend_ptr_stack * stack,void (* func)(void *))89 ZEND_API void zend_ptr_stack_reverse_apply(zend_ptr_stack *stack, void (*func)(void *))
90 {
91 int i = 0;
92
93 while (i < stack->top) {
94 func(stack->elements[i++]);
95 }
96 }
97
98
zend_ptr_stack_clean(zend_ptr_stack * stack,void (* func)(void *),bool free_elements)99 ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *), bool free_elements)
100 {
101 zend_ptr_stack_apply(stack, func);
102 if (free_elements) {
103 int i = stack->top;
104
105 while (--i >= 0) {
106 pefree(stack->elements[i], stack->persistent);
107 }
108 }
109 stack->top = 0;
110 stack->top_element = stack->elements;
111 }
112
113
zend_ptr_stack_num_elements(zend_ptr_stack * stack)114 ZEND_API int zend_ptr_stack_num_elements(zend_ptr_stack *stack)
115 {
116 return stack->top;
117 }
118