libr/util: implement a simple stack

libr/util/t/stack: add test
This commit is contained in:
Riccardo Schirone 2015-06-08 10:04:15 +02:00 committed by pancake
parent 3536b9cb63
commit 0b091a6c5f
5 changed files with 131 additions and 2 deletions

View file

@ -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; // <RGraphNode>
@ -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);

View file

@ -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)

47
libr/util/stack.c Normal file
View file

@ -0,0 +1,47 @@
/* radare - LGPL - Copyright 2007-2015 - ret2libc */
#include <r_util.h>
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;
}

View file

@ -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

68
libr/util/t/test_stack.c Normal file
View file

@ -0,0 +1,68 @@
#include <r_util.h>
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;
}