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