rbtree
changeset 6:028a21468abf
added rbshell test
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 12 Oct 2011 07:03:03 +0300 |
parents | 56a08d00bb41 |
children | 2c0baa1fd419 |
files | .hgignore src/rbtree.h test/rbshell/Makefile test/rbshell/sym.c test/rbshell/sym.h test/rbshell/test.c |
diffstat | 6 files changed, 315 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- a/.hgignore Wed Oct 12 05:25:34 2011 +0300 1.2 +++ b/.hgignore Wed Oct 12 07:03:03 2011 +0300 1.3 @@ -4,3 +4,4 @@ 1.4 ^Makefile$ 1.5 rbtree\.a$ 1.6 rbtree\.so 1.7 +^test/.*test$
2.1 --- a/src/rbtree.h Wed Oct 12 05:25:34 2011 +0300 2.2 +++ b/src/rbtree.h Wed Oct 12 07:03:03 2011 +0300 2.3 @@ -36,6 +36,7 @@ 2.4 void rb_set_allocator(struct rbtree *rb, rb_alloc_func_t alloc, rb_free_func_t free); 2.5 void rb_set_compare_func(struct rbtree *rb, rb_cmp_func_t func); 2.6 void rb_set_delete_func(struct rbtree *rb, rb_del_func_t func, void *cls); 2.7 +/* TODO add user deep copy function */ 2.8 2.9 void rb_clear(struct rbtree *rb); 2.10 int rb_copy(struct rbtree *dest, struct rbtree *src);
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/rbshell/Makefile Wed Oct 12 07:03:03 2011 +0300 3.3 @@ -0,0 +1,14 @@ 3.4 +src = $(wildcard *.c) 3.5 +obj = $(src:.c=.o) 3.6 +bin = test 3.7 + 3.8 +CC = gcc 3.9 +CFLAGS = -pedantic -Wall -g -I../../src -I/usr/local/include 3.10 +LDFLAGS = -L../.. -L/usr/local/lib -lrbtree 3.11 + 3.12 +$(bin): $(obj) 3.13 + $(CC) -o $@ $(obj) $(LDFLAGS) 3.14 + 3.15 +.PHONY: clean 3.16 +clean: 3.17 + rm -f $(obj) $(bin)
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/rbshell/sym.c Wed Oct 12 07:03:03 2011 +0300 4.3 @@ -0,0 +1,73 @@ 4.4 +#include <stdio.h> 4.5 +#include <stdlib.h> 4.6 +#include <string.h> 4.7 +#include "sym.h" 4.8 +#include "rbtree.h" 4.9 + 4.10 +struct symbol { 4.11 + char *name; 4.12 + int id, arity; 4.13 +}; 4.14 + 4.15 +static void del_func(struct rbnode *node, void *cls); 4.16 + 4.17 +struct rbtree *symbols; 4.18 + 4.19 +int init_sym(void) 4.20 +{ 4.21 + if(!(symbols = rb_create(RB_KEY_STRING))) { 4.22 + fprintf(stderr, "failed to create symbol table\n"); 4.23 + return -1; 4.24 + } 4.25 + rb_set_delete_func(symbols, del_func, 0); 4.26 + return 0; 4.27 +} 4.28 + 4.29 +void destroy_sym(void) 4.30 +{ 4.31 + rb_free(symbols); 4.32 +} 4.33 + 4.34 +int add_sym(const char *name, int id, int arity) 4.35 +{ 4.36 + struct symbol *sym; 4.37 + 4.38 + if(!(sym = malloc(sizeof *sym)) || !(sym->name = malloc(strlen(name) + 1))) { 4.39 + perror("failed to allocate symbol"); 4.40 + free(sym); 4.41 + return -1; 4.42 + } 4.43 + strcpy(sym->name, name); 4.44 + sym->id = id; 4.45 + sym->arity = arity; 4.46 + 4.47 + return rb_insert(symbols, sym->name, sym); 4.48 +} 4.49 + 4.50 +int sym_lookup(const char *str) 4.51 +{ 4.52 + struct rbnode *node; 4.53 + 4.54 + if(!(node = rb_find(symbols, (char*)str))) { 4.55 + fprintf(stderr, "undefined symbol: %s\n", str); 4.56 + return -1; 4.57 + } 4.58 + return ((struct symbol*)node->data)->id; 4.59 +} 4.60 + 4.61 +int sym_arity(const char *str) 4.62 +{ 4.63 + struct rbnode *node; 4.64 + 4.65 + if(!(node = rb_find(symbols, (char*)str))) { 4.66 + fprintf(stderr, "undefined symbol: %s\n", str); 4.67 + return -1; 4.68 + } 4.69 + return ((struct symbol*)node->data)->arity; 4.70 +} 4.71 + 4.72 +static void del_func(struct rbnode *node, void *cls) 4.73 +{ 4.74 + free(((struct symbol*)node->data)->name); 4.75 + free(node->data); 4.76 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/rbshell/sym.h Wed Oct 12 07:03:03 2011 +0300 5.3 @@ -0,0 +1,12 @@ 5.4 +#ifndef SYM_H_ 5.5 +#define SYM_H_ 5.6 + 5.7 +int init_sym(void); 5.8 +void destroy_sym(void); 5.9 + 5.10 +int add_sym(const char *name, int id, int arity); 5.11 + 5.12 +int sym_lookup(const char *str); 5.13 +int sym_arity(const char *str); 5.14 + 5.15 +#endif /* SYM_H_ */
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/rbshell/test.c Wed Oct 12 07:03:03 2011 +0300 6.3 @@ -0,0 +1,214 @@ 6.4 +#include <stdio.h> 6.5 +#include <stdlib.h> 6.6 +#include <string.h> 6.7 +#include <ctype.h> 6.8 +#include "rbtree.h" 6.9 +#include "sym.h" 6.10 + 6.11 +#define SEP " \t\r\n,\"\'" 6.12 + 6.13 +/* commands */ 6.14 +enum { 6.15 + CMD_CREATE, 6.16 + CMD_DESTROY, 6.17 + CMD_CLEAR, 6.18 + CMD_COPY, 6.19 + CMD_SIZE, 6.20 + CMD_INSERT, 6.21 + CMD_DELETE, 6.22 + CMD_FIND, 6.23 + CMD_PRINT, 6.24 + 6.25 + MAX_CMD 6.26 +}; 6.27 + 6.28 +int runcmd(int cmd, int argc, char **argv); 6.29 + 6.30 +#define NUM_TREES 8 6.31 +struct rbtree *trees[NUM_TREES]; 6.32 + 6.33 + 6.34 +int main(void) 6.35 +{ 6.36 + char buf[512]; 6.37 + 6.38 + /* init symbol table */ 6.39 + if(init_sym() == -1) { 6.40 + return 1; 6.41 + } 6.42 + add_sym("create", CMD_CREATE, 0); 6.43 + add_sym("destroy", CMD_DESTROY, 1); 6.44 + add_sym("clear", CMD_CLEAR, 1); 6.45 + add_sym("copy", CMD_COPY, 2); 6.46 + add_sym("size", CMD_SIZE, 1); 6.47 + add_sym("insert", CMD_INSERT, 2); 6.48 + add_sym("delete", CMD_DELETE, 2); 6.49 + add_sym("find", CMD_FIND, 2); 6.50 + add_sym("print", CMD_PRINT, 1); 6.51 + 6.52 + for(;;) { 6.53 + int argc = 0; 6.54 + char *argv[8]; 6.55 + int cmd_id, cmd_arity; 6.56 + 6.57 + printf("rbshell> "); 6.58 + fflush(stdout); 6.59 + 6.60 + if(!fgets(buf, sizeof buf, stdin)) { 6.61 + putchar('\n'); 6.62 + break; 6.63 + } 6.64 + 6.65 + if(!(argv[argc] = strtok(buf, SEP)) || argv[argc][0] == '#') { 6.66 + return 0; /* empty / comment */ 6.67 + } 6.68 + argc++; 6.69 + 6.70 + if((cmd_id = sym_lookup(argv[0])) == -1) { 6.71 + continue; 6.72 + } 6.73 + cmd_arity = sym_arity(argv[0]); 6.74 + 6.75 + while((argv[argc] = strtok(0, SEP))) { 6.76 + argc++; 6.77 + if(argc >= sizeof argv / sizeof *argv) { 6.78 + break; 6.79 + } 6.80 + } 6.81 + 6.82 + if(argc - 1 != cmd_arity) { 6.83 + fprintf(stderr, "too many (%d) arguments for %s, expected %d\n", argc - 1, argv[0], cmd_arity); 6.84 + continue; 6.85 + } 6.86 + 6.87 + runcmd(cmd_id, argc, argv); 6.88 + } 6.89 + 6.90 + destroy_sym(); 6.91 + return 0; 6.92 +} 6.93 + 6.94 +#define CHECKINT(i) \ 6.95 + if(!isdigit(argv[i][0])) { \ 6.96 + fprintf(stderr, "expected number, got: %s\n", argv[i]); \ 6.97 + return -1; \ 6.98 + } 6.99 + 6.100 +#define CHECKVALID(idx) \ 6.101 + if((idx) < 0 || (idx) >= NUM_TREES || !trees[idx]) { \ 6.102 + fprintf(stderr, "invalid tree specified: %d\n", idx); \ 6.103 + return -1; \ 6.104 + } 6.105 + 6.106 + 6.107 +int runcmd(int cmd, int argc, char **argv) 6.108 +{ 6.109 + int i, idx, idx2, n; 6.110 + struct rbnode *node; 6.111 + 6.112 + switch(cmd) { 6.113 + case CMD_CREATE: 6.114 + for(i=0; i<NUM_TREES; i++) { 6.115 + if(trees[i] == 0) { 6.116 + if(!(trees[i] = rb_create(RB_KEY_INT))) { 6.117 + fprintf(stderr, "failed to create a new tree\n"); 6.118 + return -1; 6.119 + } 6.120 + printf("created new tree: %d\n", i); 6.121 + break; 6.122 + } 6.123 + } 6.124 + if(i == NUM_TREES) { 6.125 + fprintf(stderr, "can't create more trees\n"); 6.126 + return -1; 6.127 + } 6.128 + break; 6.129 + 6.130 + case CMD_DESTROY: 6.131 + CHECKINT(1); 6.132 + idx = atoi(argv[1]); 6.133 + CHECKVALID(idx); 6.134 + 6.135 + rb_free(trees[idx]); 6.136 + trees[idx] = 0; 6.137 + printf("destroyed tree: %d\n", idx); 6.138 + break; 6.139 + 6.140 + case CMD_CLEAR: 6.141 + CHECKINT(1); 6.142 + idx = atoi(argv[1]); 6.143 + CHECKVALID(idx); 6.144 + 6.145 + rb_clear(trees[idx]); 6.146 + printf("cleared tree: %d\n", idx); 6.147 + break; 6.148 + 6.149 + case CMD_COPY: 6.150 + CHECKINT(1); 6.151 + CHECKINT(2); 6.152 + idx = atoi(argv[1]); 6.153 + idx2 = atoi(argv[2]); 6.154 + CHECKVALID(idx); 6.155 + CHECKVALID(idx2); 6.156 + 6.157 + rb_copy(trees[idx2], trees[idx]); 6.158 + printf("copied %d -> %d\n", idx, idx2); 6.159 + break; 6.160 + 6.161 + case CMD_SIZE: 6.162 + CHECKINT(1); 6.163 + idx = atoi(argv[1]); 6.164 + CHECKVALID(idx); 6.165 + 6.166 + printf("tree size: %d\n", rb_size(trees[idx])); 6.167 + break; 6.168 + 6.169 + case CMD_INSERT: 6.170 + CHECKINT(1); 6.171 + CHECKINT(2); 6.172 + idx = atoi(argv[1]); 6.173 + CHECKVALID(idx); 6.174 + 6.175 + n = atoi(argv[2]); 6.176 + rb_inserti(trees[idx], n, 0); 6.177 + printf("inserted: %d\n", n); 6.178 + break; 6.179 + 6.180 + case CMD_DELETE: 6.181 + case CMD_FIND: 6.182 + CHECKINT(1); 6.183 + CHECKINT(2); 6.184 + idx = atoi(argv[1]); 6.185 + CHECKVALID(idx); 6.186 + n = atoi(argv[2]); 6.187 + 6.188 + if(!rb_findi(trees[idx], n)) { 6.189 + fprintf(stderr, "%d not found\n", n); 6.190 + } else { 6.191 + if(cmd == CMD_DELETE) { 6.192 + rb_deletei(trees[idx], n); 6.193 + printf("deleted %d\n", n); 6.194 + } else { 6.195 + printf("found %d\n", n); 6.196 + } 6.197 + } 6.198 + break; 6.199 + 6.200 + case CMD_PRINT: 6.201 + CHECKINT(1); 6.202 + idx = atoi(argv[1]); 6.203 + CHECKVALID(idx); 6.204 + 6.205 + rb_begin(trees[idx]); 6.206 + while((node = rb_next(trees[idx]))) { 6.207 + printf("%d ", rb_node_keyi(node)); 6.208 + } 6.209 + putchar('\n'); 6.210 + break; 6.211 + 6.212 + default: 6.213 + /* can't happen */ 6.214 + break; 6.215 + } 6.216 + return 0; 6.217 +}