rbtree

annotate test/rbshell/test.c @ 15:1b77b72688fe

- fixed bug in rb_init making it ignore comparison functions other than the builtin - fixed rb_find and rb_findi return type, which should be struct rbnode*, not void*
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 02 Nov 2014 11:00:27 +0200
parents
children
rev   line source
nuclear@6 1 #include <stdio.h>
nuclear@6 2 #include <stdlib.h>
nuclear@6 3 #include <string.h>
nuclear@6 4 #include <ctype.h>
nuclear@6 5 #include "rbtree.h"
nuclear@6 6 #include "sym.h"
nuclear@6 7
nuclear@6 8 #define SEP " \t\r\n,\"\'"
nuclear@6 9
nuclear@6 10 /* commands */
nuclear@6 11 enum {
nuclear@6 12 CMD_CREATE,
nuclear@6 13 CMD_DESTROY,
nuclear@6 14 CMD_CLEAR,
nuclear@6 15 CMD_COPY,
nuclear@6 16 CMD_SIZE,
nuclear@6 17 CMD_INSERT,
nuclear@6 18 CMD_DELETE,
nuclear@6 19 CMD_FIND,
nuclear@6 20 CMD_PRINT,
nuclear@6 21
nuclear@6 22 MAX_CMD
nuclear@6 23 };
nuclear@6 24
nuclear@6 25 int runcmd(int cmd, int argc, char **argv);
nuclear@6 26
nuclear@6 27 #define NUM_TREES 8
nuclear@6 28 struct rbtree *trees[NUM_TREES];
nuclear@6 29
nuclear@6 30
nuclear@6 31 int main(void)
nuclear@6 32 {
nuclear@6 33 char buf[512];
nuclear@6 34
nuclear@6 35 /* init symbol table */
nuclear@6 36 if(init_sym() == -1) {
nuclear@6 37 return 1;
nuclear@6 38 }
nuclear@6 39 add_sym("create", CMD_CREATE, 0);
nuclear@6 40 add_sym("destroy", CMD_DESTROY, 1);
nuclear@6 41 add_sym("clear", CMD_CLEAR, 1);
nuclear@6 42 add_sym("copy", CMD_COPY, 2);
nuclear@6 43 add_sym("size", CMD_SIZE, 1);
nuclear@6 44 add_sym("insert", CMD_INSERT, 2);
nuclear@6 45 add_sym("delete", CMD_DELETE, 2);
nuclear@6 46 add_sym("find", CMD_FIND, 2);
nuclear@6 47 add_sym("print", CMD_PRINT, 1);
nuclear@6 48
nuclear@6 49 for(;;) {
nuclear@6 50 int argc = 0;
nuclear@6 51 char *argv[8];
nuclear@6 52 int cmd_id, cmd_arity;
nuclear@6 53
nuclear@6 54 printf("rbshell> ");
nuclear@6 55 fflush(stdout);
nuclear@6 56
nuclear@6 57 if(!fgets(buf, sizeof buf, stdin)) {
nuclear@6 58 putchar('\n');
nuclear@6 59 break;
nuclear@6 60 }
nuclear@6 61
nuclear@6 62 if(!(argv[argc] = strtok(buf, SEP)) || argv[argc][0] == '#') {
nuclear@6 63 return 0; /* empty / comment */
nuclear@6 64 }
nuclear@6 65 argc++;
nuclear@6 66
nuclear@6 67 if((cmd_id = sym_lookup(argv[0])) == -1) {
nuclear@6 68 continue;
nuclear@6 69 }
nuclear@6 70 cmd_arity = sym_arity(argv[0]);
nuclear@6 71
nuclear@6 72 while((argv[argc] = strtok(0, SEP))) {
nuclear@6 73 argc++;
nuclear@6 74 if(argc >= sizeof argv / sizeof *argv) {
nuclear@6 75 break;
nuclear@6 76 }
nuclear@6 77 }
nuclear@6 78
nuclear@6 79 if(argc - 1 != cmd_arity) {
nuclear@6 80 fprintf(stderr, "too many (%d) arguments for %s, expected %d\n", argc - 1, argv[0], cmd_arity);
nuclear@6 81 continue;
nuclear@6 82 }
nuclear@6 83
nuclear@6 84 runcmd(cmd_id, argc, argv);
nuclear@6 85 }
nuclear@6 86
nuclear@6 87 destroy_sym();
nuclear@6 88 return 0;
nuclear@6 89 }
nuclear@6 90
nuclear@6 91 #define CHECKINT(i) \
nuclear@6 92 if(!isdigit(argv[i][0])) { \
nuclear@6 93 fprintf(stderr, "expected number, got: %s\n", argv[i]); \
nuclear@6 94 return -1; \
nuclear@6 95 }
nuclear@6 96
nuclear@6 97 #define CHECKVALID(idx) \
nuclear@6 98 if((idx) < 0 || (idx) >= NUM_TREES || !trees[idx]) { \
nuclear@6 99 fprintf(stderr, "invalid tree specified: %d\n", idx); \
nuclear@6 100 return -1; \
nuclear@6 101 }
nuclear@6 102
nuclear@6 103
nuclear@6 104 int runcmd(int cmd, int argc, char **argv)
nuclear@6 105 {
nuclear@6 106 int i, idx, idx2, n;
nuclear@6 107 struct rbnode *node;
nuclear@6 108
nuclear@6 109 switch(cmd) {
nuclear@6 110 case CMD_CREATE:
nuclear@6 111 for(i=0; i<NUM_TREES; i++) {
nuclear@6 112 if(trees[i] == 0) {
nuclear@6 113 if(!(trees[i] = rb_create(RB_KEY_INT))) {
nuclear@6 114 fprintf(stderr, "failed to create a new tree\n");
nuclear@6 115 return -1;
nuclear@6 116 }
nuclear@6 117 printf("created new tree: %d\n", i);
nuclear@6 118 break;
nuclear@6 119 }
nuclear@6 120 }
nuclear@6 121 if(i == NUM_TREES) {
nuclear@6 122 fprintf(stderr, "can't create more trees\n");
nuclear@6 123 return -1;
nuclear@6 124 }
nuclear@6 125 break;
nuclear@6 126
nuclear@6 127 case CMD_DESTROY:
nuclear@6 128 CHECKINT(1);
nuclear@6 129 idx = atoi(argv[1]);
nuclear@6 130 CHECKVALID(idx);
nuclear@6 131
nuclear@6 132 rb_free(trees[idx]);
nuclear@6 133 trees[idx] = 0;
nuclear@6 134 printf("destroyed tree: %d\n", idx);
nuclear@6 135 break;
nuclear@6 136
nuclear@6 137 case CMD_CLEAR:
nuclear@6 138 CHECKINT(1);
nuclear@6 139 idx = atoi(argv[1]);
nuclear@6 140 CHECKVALID(idx);
nuclear@6 141
nuclear@6 142 rb_clear(trees[idx]);
nuclear@6 143 printf("cleared tree: %d\n", idx);
nuclear@6 144 break;
nuclear@6 145
nuclear@6 146 case CMD_COPY:
nuclear@6 147 CHECKINT(1);
nuclear@6 148 CHECKINT(2);
nuclear@6 149 idx = atoi(argv[1]);
nuclear@6 150 idx2 = atoi(argv[2]);
nuclear@6 151 CHECKVALID(idx);
nuclear@6 152 CHECKVALID(idx2);
nuclear@6 153
nuclear@6 154 rb_copy(trees[idx2], trees[idx]);
nuclear@6 155 printf("copied %d -> %d\n", idx, idx2);
nuclear@6 156 break;
nuclear@6 157
nuclear@6 158 case CMD_SIZE:
nuclear@6 159 CHECKINT(1);
nuclear@6 160 idx = atoi(argv[1]);
nuclear@6 161 CHECKVALID(idx);
nuclear@6 162
nuclear@6 163 printf("tree size: %d\n", rb_size(trees[idx]));
nuclear@6 164 break;
nuclear@6 165
nuclear@6 166 case CMD_INSERT:
nuclear@6 167 CHECKINT(1);
nuclear@6 168 CHECKINT(2);
nuclear@6 169 idx = atoi(argv[1]);
nuclear@6 170 CHECKVALID(idx);
nuclear@6 171
nuclear@6 172 n = atoi(argv[2]);
nuclear@6 173 rb_inserti(trees[idx], n, 0);
nuclear@6 174 printf("inserted: %d\n", n);
nuclear@6 175 break;
nuclear@6 176
nuclear@6 177 case CMD_DELETE:
nuclear@6 178 case CMD_FIND:
nuclear@6 179 CHECKINT(1);
nuclear@6 180 CHECKINT(2);
nuclear@6 181 idx = atoi(argv[1]);
nuclear@6 182 CHECKVALID(idx);
nuclear@6 183 n = atoi(argv[2]);
nuclear@6 184
nuclear@6 185 if(!rb_findi(trees[idx], n)) {
nuclear@6 186 fprintf(stderr, "%d not found\n", n);
nuclear@6 187 } else {
nuclear@6 188 if(cmd == CMD_DELETE) {
nuclear@6 189 rb_deletei(trees[idx], n);
nuclear@6 190 printf("deleted %d\n", n);
nuclear@6 191 } else {
nuclear@6 192 printf("found %d\n", n);
nuclear@6 193 }
nuclear@6 194 }
nuclear@6 195 break;
nuclear@6 196
nuclear@6 197 case CMD_PRINT:
nuclear@6 198 CHECKINT(1);
nuclear@6 199 idx = atoi(argv[1]);
nuclear@6 200 CHECKVALID(idx);
nuclear@6 201
nuclear@6 202 rb_begin(trees[idx]);
nuclear@6 203 while((node = rb_next(trees[idx]))) {
nuclear@6 204 printf("%d ", rb_node_keyi(node));
nuclear@6 205 }
nuclear@6 206 putchar('\n');
nuclear@6 207 break;
nuclear@6 208
nuclear@6 209 default:
nuclear@6 210 /* can't happen */
nuclear@6 211 break;
nuclear@6 212 }
nuclear@6 213 return 0;
nuclear@6 214 }