rbtree
changeset 9:8d7233ff61d3
merged fixes with rbshell
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 16 Apr 2012 00:26:38 +0300 |
parents | b266386d19ce 2c0baa1fd419 |
children | b45febfd2922 |
files | src/rbtree.h |
diffstat | 7 files changed, 318 insertions(+), 1 deletions(-) [+] |
line diff
1.1 --- a/.hgignore Mon Apr 16 00:25:05 2012 +0300 1.2 +++ b/.hgignore Mon Apr 16 00:26:38 2012 +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.c Mon Apr 16 00:25:05 2012 +0300 2.2 +++ b/src/rbtree.c Mon Apr 16 00:26:38 2012 +0300 2.3 @@ -261,7 +261,9 @@ 2.4 del_tree(node->left, delfunc, cls); 2.5 del_tree(node->right, delfunc, cls); 2.6 2.7 - delfunc(node, cls); 2.8 + if(delfunc) { 2.9 + delfunc(node, cls); 2.10 + } 2.11 free(node); 2.12 } 2.13
3.1 --- a/src/rbtree.h Mon Apr 16 00:25:05 2012 +0300 3.2 +++ b/src/rbtree.h Mon Apr 16 00:26:38 2012 +0300 3.3 @@ -36,6 +36,7 @@ 3.4 void rb_set_allocator(struct rbtree *rb, rb_alloc_func_t alloc, rb_free_func_t free); 3.5 void rb_set_compare_func(struct rbtree *rb, rb_cmp_func_t func); 3.6 void rb_set_delete_func(struct rbtree *rb, rb_del_func_t func, void *cls); 3.7 +/* TODO add user deep copy function */ 3.8 3.9 void rb_clear(struct rbtree *rb); 3.10 int rb_copy(struct rbtree *dest, struct rbtree *src);
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/rbshell/Makefile Mon Apr 16 00:26:38 2012 +0300 4.3 @@ -0,0 +1,14 @@ 4.4 +src = $(wildcard *.c) 4.5 +obj = $(src:.c=.o) 4.6 +bin = test 4.7 + 4.8 +CC = gcc 4.9 +CFLAGS = -pedantic -Wall -g -I../../src -I/usr/local/include 4.10 +LDFLAGS = -L../.. -L/usr/local/lib -lrbtree 4.11 + 4.12 +$(bin): $(obj) 4.13 + $(CC) -o $@ $(obj) $(LDFLAGS) 4.14 + 4.15 +.PHONY: clean 4.16 +clean: 4.17 + rm -f $(obj) $(bin)
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/rbshell/sym.c Mon Apr 16 00:26:38 2012 +0300 5.3 @@ -0,0 +1,73 @@ 5.4 +#include <stdio.h> 5.5 +#include <stdlib.h> 5.6 +#include <string.h> 5.7 +#include "sym.h" 5.8 +#include "rbtree.h" 5.9 + 5.10 +struct symbol { 5.11 + char *name; 5.12 + int id, arity; 5.13 +}; 5.14 + 5.15 +static void del_func(struct rbnode *node, void *cls); 5.16 + 5.17 +struct rbtree *symbols; 5.18 + 5.19 +int init_sym(void) 5.20 +{ 5.21 + if(!(symbols = rb_create(RB_KEY_STRING))) { 5.22 + fprintf(stderr, "failed to create symbol table\n"); 5.23 + return -1; 5.24 + } 5.25 + rb_set_delete_func(symbols, del_func, 0); 5.26 + return 0; 5.27 +} 5.28 + 5.29 +void destroy_sym(void) 5.30 +{ 5.31 + rb_free(symbols); 5.32 +} 5.33 + 5.34 +int add_sym(const char *name, int id, int arity) 5.35 +{ 5.36 + struct symbol *sym; 5.37 + 5.38 + if(!(sym = malloc(sizeof *sym)) || !(sym->name = malloc(strlen(name) + 1))) { 5.39 + perror("failed to allocate symbol"); 5.40 + free(sym); 5.41 + return -1; 5.42 + } 5.43 + strcpy(sym->name, name); 5.44 + sym->id = id; 5.45 + sym->arity = arity; 5.46 + 5.47 + return rb_insert(symbols, sym->name, sym); 5.48 +} 5.49 + 5.50 +int sym_lookup(const char *str) 5.51 +{ 5.52 + struct rbnode *node; 5.53 + 5.54 + if(!(node = rb_find(symbols, (char*)str))) { 5.55 + fprintf(stderr, "undefined symbol: %s\n", str); 5.56 + return -1; 5.57 + } 5.58 + return ((struct symbol*)node->data)->id; 5.59 +} 5.60 + 5.61 +int sym_arity(const char *str) 5.62 +{ 5.63 + struct rbnode *node; 5.64 + 5.65 + if(!(node = rb_find(symbols, (char*)str))) { 5.66 + fprintf(stderr, "undefined symbol: %s\n", str); 5.67 + return -1; 5.68 + } 5.69 + return ((struct symbol*)node->data)->arity; 5.70 +} 5.71 + 5.72 +static void del_func(struct rbnode *node, void *cls) 5.73 +{ 5.74 + free(((struct symbol*)node->data)->name); 5.75 + free(node->data); 5.76 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/rbshell/sym.h Mon Apr 16 00:26:38 2012 +0300 6.3 @@ -0,0 +1,12 @@ 6.4 +#ifndef SYM_H_ 6.5 +#define SYM_H_ 6.6 + 6.7 +int init_sym(void); 6.8 +void destroy_sym(void); 6.9 + 6.10 +int add_sym(const char *name, int id, int arity); 6.11 + 6.12 +int sym_lookup(const char *str); 6.13 +int sym_arity(const char *str); 6.14 + 6.15 +#endif /* SYM_H_ */
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/rbshell/test.c Mon Apr 16 00:26:38 2012 +0300 7.3 @@ -0,0 +1,214 @@ 7.4 +#include <stdio.h> 7.5 +#include <stdlib.h> 7.6 +#include <string.h> 7.7 +#include <ctype.h> 7.8 +#include "rbtree.h" 7.9 +#include "sym.h" 7.10 + 7.11 +#define SEP " \t\r\n,\"\'" 7.12 + 7.13 +/* commands */ 7.14 +enum { 7.15 + CMD_CREATE, 7.16 + CMD_DESTROY, 7.17 + CMD_CLEAR, 7.18 + CMD_COPY, 7.19 + CMD_SIZE, 7.20 + CMD_INSERT, 7.21 + CMD_DELETE, 7.22 + CMD_FIND, 7.23 + CMD_PRINT, 7.24 + 7.25 + MAX_CMD 7.26 +}; 7.27 + 7.28 +int runcmd(int cmd, int argc, char **argv); 7.29 + 7.30 +#define NUM_TREES 8 7.31 +struct rbtree *trees[NUM_TREES]; 7.32 + 7.33 + 7.34 +int main(void) 7.35 +{ 7.36 + char buf[512]; 7.37 + 7.38 + /* init symbol table */ 7.39 + if(init_sym() == -1) { 7.40 + return 1; 7.41 + } 7.42 + add_sym("create", CMD_CREATE, 0); 7.43 + add_sym("destroy", CMD_DESTROY, 1); 7.44 + add_sym("clear", CMD_CLEAR, 1); 7.45 + add_sym("copy", CMD_COPY, 2); 7.46 + add_sym("size", CMD_SIZE, 1); 7.47 + add_sym("insert", CMD_INSERT, 2); 7.48 + add_sym("delete", CMD_DELETE, 2); 7.49 + add_sym("find", CMD_FIND, 2); 7.50 + add_sym("print", CMD_PRINT, 1); 7.51 + 7.52 + for(;;) { 7.53 + int argc = 0; 7.54 + char *argv[8]; 7.55 + int cmd_id, cmd_arity; 7.56 + 7.57 + printf("rbshell> "); 7.58 + fflush(stdout); 7.59 + 7.60 + if(!fgets(buf, sizeof buf, stdin)) { 7.61 + putchar('\n'); 7.62 + break; 7.63 + } 7.64 + 7.65 + if(!(argv[argc] = strtok(buf, SEP)) || argv[argc][0] == '#') { 7.66 + return 0; /* empty / comment */ 7.67 + } 7.68 + argc++; 7.69 + 7.70 + if((cmd_id = sym_lookup(argv[0])) == -1) { 7.71 + continue; 7.72 + } 7.73 + cmd_arity = sym_arity(argv[0]); 7.74 + 7.75 + while((argv[argc] = strtok(0, SEP))) { 7.76 + argc++; 7.77 + if(argc >= sizeof argv / sizeof *argv) { 7.78 + break; 7.79 + } 7.80 + } 7.81 + 7.82 + if(argc - 1 != cmd_arity) { 7.83 + fprintf(stderr, "too many (%d) arguments for %s, expected %d\n", argc - 1, argv[0], cmd_arity); 7.84 + continue; 7.85 + } 7.86 + 7.87 + runcmd(cmd_id, argc, argv); 7.88 + } 7.89 + 7.90 + destroy_sym(); 7.91 + return 0; 7.92 +} 7.93 + 7.94 +#define CHECKINT(i) \ 7.95 + if(!isdigit(argv[i][0])) { \ 7.96 + fprintf(stderr, "expected number, got: %s\n", argv[i]); \ 7.97 + return -1; \ 7.98 + } 7.99 + 7.100 +#define CHECKVALID(idx) \ 7.101 + if((idx) < 0 || (idx) >= NUM_TREES || !trees[idx]) { \ 7.102 + fprintf(stderr, "invalid tree specified: %d\n", idx); \ 7.103 + return -1; \ 7.104 + } 7.105 + 7.106 + 7.107 +int runcmd(int cmd, int argc, char **argv) 7.108 +{ 7.109 + int i, idx, idx2, n; 7.110 + struct rbnode *node; 7.111 + 7.112 + switch(cmd) { 7.113 + case CMD_CREATE: 7.114 + for(i=0; i<NUM_TREES; i++) { 7.115 + if(trees[i] == 0) { 7.116 + if(!(trees[i] = rb_create(RB_KEY_INT))) { 7.117 + fprintf(stderr, "failed to create a new tree\n"); 7.118 + return -1; 7.119 + } 7.120 + printf("created new tree: %d\n", i); 7.121 + break; 7.122 + } 7.123 + } 7.124 + if(i == NUM_TREES) { 7.125 + fprintf(stderr, "can't create more trees\n"); 7.126 + return -1; 7.127 + } 7.128 + break; 7.129 + 7.130 + case CMD_DESTROY: 7.131 + CHECKINT(1); 7.132 + idx = atoi(argv[1]); 7.133 + CHECKVALID(idx); 7.134 + 7.135 + rb_free(trees[idx]); 7.136 + trees[idx] = 0; 7.137 + printf("destroyed tree: %d\n", idx); 7.138 + break; 7.139 + 7.140 + case CMD_CLEAR: 7.141 + CHECKINT(1); 7.142 + idx = atoi(argv[1]); 7.143 + CHECKVALID(idx); 7.144 + 7.145 + rb_clear(trees[idx]); 7.146 + printf("cleared tree: %d\n", idx); 7.147 + break; 7.148 + 7.149 + case CMD_COPY: 7.150 + CHECKINT(1); 7.151 + CHECKINT(2); 7.152 + idx = atoi(argv[1]); 7.153 + idx2 = atoi(argv[2]); 7.154 + CHECKVALID(idx); 7.155 + CHECKVALID(idx2); 7.156 + 7.157 + rb_copy(trees[idx2], trees[idx]); 7.158 + printf("copied %d -> %d\n", idx, idx2); 7.159 + break; 7.160 + 7.161 + case CMD_SIZE: 7.162 + CHECKINT(1); 7.163 + idx = atoi(argv[1]); 7.164 + CHECKVALID(idx); 7.165 + 7.166 + printf("tree size: %d\n", rb_size(trees[idx])); 7.167 + break; 7.168 + 7.169 + case CMD_INSERT: 7.170 + CHECKINT(1); 7.171 + CHECKINT(2); 7.172 + idx = atoi(argv[1]); 7.173 + CHECKVALID(idx); 7.174 + 7.175 + n = atoi(argv[2]); 7.176 + rb_inserti(trees[idx], n, 0); 7.177 + printf("inserted: %d\n", n); 7.178 + break; 7.179 + 7.180 + case CMD_DELETE: 7.181 + case CMD_FIND: 7.182 + CHECKINT(1); 7.183 + CHECKINT(2); 7.184 + idx = atoi(argv[1]); 7.185 + CHECKVALID(idx); 7.186 + n = atoi(argv[2]); 7.187 + 7.188 + if(!rb_findi(trees[idx], n)) { 7.189 + fprintf(stderr, "%d not found\n", n); 7.190 + } else { 7.191 + if(cmd == CMD_DELETE) { 7.192 + rb_deletei(trees[idx], n); 7.193 + printf("deleted %d\n", n); 7.194 + } else { 7.195 + printf("found %d\n", n); 7.196 + } 7.197 + } 7.198 + break; 7.199 + 7.200 + case CMD_PRINT: 7.201 + CHECKINT(1); 7.202 + idx = atoi(argv[1]); 7.203 + CHECKVALID(idx); 7.204 + 7.205 + rb_begin(trees[idx]); 7.206 + while((node = rb_next(trees[idx]))) { 7.207 + printf("%d ", rb_node_keyi(node)); 7.208 + } 7.209 + putchar('\n'); 7.210 + break; 7.211 + 7.212 + default: 7.213 + /* can't happen */ 7.214 + break; 7.215 + } 7.216 + return 0; 7.217 +}