diff --git a/libr/include/r_util.h b/libr/include/r_util.h index f30f8349fe..32e1c9142c 100644 --- a/libr/include/r_util.h +++ b/libr/include/r_util.h @@ -211,6 +211,13 @@ typedef struct r_list_range_t { //RListComparator c; } RListRange; +/* stack api */ +typedef struct r_stack_t { + void **elems; + unsigned int n_elems; + int top; +} RStack; + /* graph api */ typedef struct r_graph_node_t { RList *parents; // @@ -232,6 +239,12 @@ typedef struct r_graph_t { } RGraph; #ifdef R_API +R_API RStack *r_stack_new (unsigned int n); +R_API void r_stack_free (RStack *s); +R_API int r_stack_push (RStack *s, void *el); +R_API void *r_stack_pop (RStack *s); +R_API int r_stack_is_empty (RStack *s); + R_API RGraphNode *r_graph_node_new (ut64 addr, void *data); R_API void r_graph_node_free (RGraphNode *n); R_API void r_graph_traverse(RGraph *t); diff --git a/libr/util/Makefile b/libr/util/Makefile index 669de5f323..80df7c6d2c 100644 --- a/libr/util/Makefile +++ b/libr/util/Makefile @@ -11,7 +11,7 @@ OBJS+=sandbox.o calc.o thread.o thread_lock.o thread_msg.o OBJS+=strpool.o bitmap.o strht.o p_date.o p_format.o print.o OBJS+=p_seven.o slist.o randomart.o log.o zip.o debruijn.o OBJS+=utf8.o strbuf.o lib.o name.o -OBJS+=diff.o bdiff.o +OBJS+=diff.o bdiff.o stack.o # DO NOT BUILD r_big api (not yet used and its buggy) ifeq (1,0) diff --git a/libr/util/stack.c b/libr/util/stack.c new file mode 100644 index 0000000000..73d80e526e --- /dev/null +++ b/libr/util/stack.c @@ -0,0 +1,47 @@ +/* radare - LGPL - Copyright 2007-2015 - ret2libc */ + +#include + +R_API RStack *r_stack_new (unsigned int n) { + RStack *s = R_NEW0 (RStack); + s->elems = calloc(n, sizeof(void *)); + if (!s->elems) + return NULL; + + s->n_elems = n; + s->top = -1; + return s; +} + +R_API void r_stack_free (RStack *s) { + free (s->elems); + free (s); +} + +R_API int r_stack_push (RStack *s, void *el) { + if (s->top == s->n_elems - 1) { + /* reallocate the stack */ + s->n_elems *= 2; + s->elems = realloc (s->elems, s->n_elems * sizeof(void *)); + if (!s->elems) + return R_FALSE; + } + + s->top++; + s->elems[s->top] = el; + return R_TRUE; +} + +R_API void *r_stack_pop (RStack *s) { + void *res; + if (s->top == -1) + return NULL; + + res = s->elems[s->top]; + s->top--; + return res; +} + +R_API int r_stack_is_empty (RStack *s) { + return s->top == -1; +} diff --git a/libr/util/t/Makefile b/libr/util/t/Makefile index b7bf1f915e..26a94588b2 100644 --- a/libr/util/t/Makefile +++ b/libr/util/t/Makefile @@ -16,11 +16,12 @@ BINS+=test_sys BINS+=test_str BINS+=test_file_slurp_hexpairs BINS+=test_cmd_str +BINS+=test_stack all: ${BINS} ${BINS}: $(addsuffix .o,$(BINS)) - $(CC) $(LDFLAGS) -o $@ $< + $(CC) $(LDFLAGS) -o $@ $@.o myclean: rm -f ${BINS} *.o diff --git a/libr/util/t/test_stack.c b/libr/util/t/test_stack.c new file mode 100644 index 0000000000..b98852087f --- /dev/null +++ b/libr/util/t/test_stack.c @@ -0,0 +1,68 @@ +#include + +void check (int n, int exp) { + if (n == exp) { + printf("[+] test passed (actual: %d; expected: %d)\n", n, exp); + } else { + printf("[-] test failed (actual: %d; expected: %d)\n", n, exp); + } +} + +void check_empty(RStack *s, int exp) { + if (r_stack_is_empty(s) == exp) { + printf("[+] test passed (stack empty status)\n"); + } else { + printf("[-] test failed (stack empty status)\n"); + } +} + +int main(int argc, char **argv) { + RStack *s = r_stack_new(5); + int n; + + r_stack_push(s, (void *)10); + r_stack_push(s, (void *)1); + r_stack_push(s, (void *)2); + r_stack_push(s, (void *)3); + r_stack_push(s, (void *)4); + r_stack_push(s, (void *)5); + r_stack_push(s, (void *)6); + r_stack_push(s, (void *)8); + r_stack_push(s, (void *)9); + r_stack_push(s, (void *)6); + n = (int)r_stack_pop(s); + check(n, 6); + n = (int)r_stack_pop(s); + check(n, 9); + n = (int)r_stack_pop(s); + check(n, 8); + n = (int)r_stack_pop(s); + check(n, 6); + n = (int)r_stack_pop(s); + check(n, 5); + n = (int)r_stack_pop(s); + check(n, 4); + n = (int)r_stack_pop(s); + check(n, 3); + n = (int)r_stack_pop(s); + check(n, 2); + n = (int)r_stack_pop(s); + check(n, 1); + check_empty(s, R_FALSE); + n = (int)r_stack_pop(s); + check(n, 10); + + check_empty(s, R_TRUE); + n = (int)r_stack_pop(s); + check(n, 0); + n = (int)r_stack_pop(s); + check(n, 0); + check_empty(s, R_TRUE); + + r_stack_push(s, (void *)10); + r_stack_push(s, (void *)1); + check_empty(s, R_FALSE); + + r_stack_free(s); + return 0; +}