1 /* radare - LGPL - Copyright 2007-2020 - ret2libc */
2 
3 #include <r_util.h>
4 
r_stack_new(ut32 n)5 R_API RStack *r_stack_new(ut32 n) {
6 	RStack *s = R_NEW0 (RStack);
7 	if (!s) {
8 		return NULL;
9 	}
10 	s->elems = R_NEWS0 (void *, n);
11 	if (!s->elems) {
12 		free (s);
13 		return NULL;
14 	}
15 	s->n_elems = n;
16 	s->top = -1;
17 	return s;
18 }
19 
r_stack_newf(ut32 n,RStackFree f)20 R_API RStack *r_stack_newf(ut32 n, RStackFree f) {
21 	RStack *s = r_stack_new (n);
22 	if (s) {
23 		s->free = f;
24 	}
25 	return s;
26 }
27 
r_stack_free(RStack * s)28 R_API void r_stack_free(RStack *s) {
29 	if (s) {
30 		if (s->free) {
31 			int i;
32 			for (i = 0; i <= s->top; i++) {
33 				s->free (s->elems[i]);
34 			}
35 		}
36 		free (s->elems);
37 		free (s);
38 	}
39 }
40 
r_stack_push(RStack * s,void * el)41 R_API bool r_stack_push(RStack *s, void *el) {
42 	if (s->top == s->n_elems - 1) {
43 		/* reallocate the stack */
44 		s->n_elems *= 2;
45 		void **elems = realloc (s->elems, s->n_elems * sizeof (void *));
46 		if (!elems) {
47 			return false;
48 		}
49 		s->elems = elems;
50 	}
51 
52 	s->top++;
53 	s->elems[s->top] = el;
54 	return true;
55 }
56 
57 //the caller should be take care of the object returned
r_stack_pop(RStack * s)58 R_API void *r_stack_pop(RStack *s) {
59 	if (s->top == -1) {
60 		return NULL;
61 	}
62 	void *res = s->elems[s->top];
63 	s->top--;
64 	return res;
65 }
66 
r_stack_is_empty(RStack * s)67 R_API bool r_stack_is_empty(RStack *s) {
68 	return s->top == -1;
69 }
70 
r_stack_size(RStack * s)71 R_API size_t r_stack_size(RStack *s) {
72 	return (size_t)(s->top + 1);
73 }
74 
r_stack_peek(RStack * s)75 R_API void *r_stack_peek(RStack *s) {
76 	return r_stack_is_empty (s)? NULL: s->elems[s->top];
77 }
78