xref: /original-bsd/lib/libc/db/test/btree.tests/main.c (revision ba762ddc)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Mike Olson.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #if defined(LIBC_SCCS) && !defined(lint)
12 static char sccsid[] = "@(#)main.c	5.1 (Berkeley) 04/12/91";
13 #endif /* LIBC_SCCS and not lint */
14 
15 /*
16  *  test1.c -- simple btree test program.
17  */
18 
19 #include <stdio.h>
20 #include <ctype.h>
21 #include <sys/param.h>
22 #include <sys/types.h>
23 #include <sys/file.h>
24 #include <db.h>
25 #include <btree.h>
26 
27 #define	DICTIONARY	"/usr/share/dict/words"
28 
29 typedef struct cmd_table {
30 	char *cmd;
31 	int nargs;
32 	int (*func)();
33 	char *descrip;
34 } cmd_table;
35 
36 extern int cursor(), delcur(), delete(), first(), help(), insert();
37 extern int last(), lookup(), next(), previous();
38 
39 cmd_table Commands[] = {
40 	"cursor", 2, cursor,
41 		"cursor <word>:  point the scan cursor at <word>",
42 	"delcur", 1, delcur,
43 		"delcur:  delete the word under the scan cursor",
44 	"delete", 2, delete,
45 		"delete <word>:  delete <word> from the dictionary",
46 	"first", 1, first,
47 		"first: point the scan cursor at the first dictionary entry",
48 	"help", 1, help,
49 		"help:  print this command summary",
50 	"insert", 3, insert,
51 		"insert <word> <def>:  insert <word> into the dictionary with definition <def>",
52 	"last", 1, last,
53 		"last:  point the scan cursor at the last dictionary entry",
54 	"lookup", 2, lookup,
55 		"lookup <word>:  look up <word> in the dictionary",
56 	"next", 1, next,
57 		"next:  move the scan cursor forward one word",
58 	"previous", 1, previous,
59 		"previous:  move the scan cursor back one word",
60 	(char *) NULL, 0, NULL, (char *) NULL,
61 };
62 
63 char *Usage = "[-p pagesize] [-c cachesize] [-u] [-l|b|n] [dbname]";
64 
65 main(argc, argv)
66 	int argc;
67 	char **argv;
68 {
69 	char *dbname;
70 	int c;
71 	char *progname;
72 	extern int strcmp();
73 	extern char *optarg;
74 	extern int optind;
75 	DB *t;
76 	BTREEINFO b;
77 
78 	progname = *argv;
79 
80 	b.psize = 0;
81 	b.cachesize = 0;
82 	b.lorder = 0;
83 	b.flags = R_DUP;
84 	b.compare = strcmp;
85 
86 	while ((c = getopt(argc, argv, "p:c:ulb")) != EOF) {
87 		switch (c) {
88 		  case 'p':
89 			b.psize = atoi(optarg);
90 			break;
91 
92 		  case 'c':
93 			b.cachesize = atoi(optarg);
94 			break;
95 
96 		  case 'u':
97 			b.flags = 0;
98 			break;
99 
100 		  case 'l':
101 			b.lorder = LITTLE_ENDIAN;
102 			break;
103 
104 		  case 'b':
105 			b.lorder = BIG_ENDIAN;
106 			break;
107 
108 		  default:
109 			fprintf(stderr, "%s: usage: %s\n", progname, Usage);
110 			exit (1);
111 		}
112 	}
113 
114 	if (argv[optind] != (char *) NULL)
115 		dbname = argv[optind];
116 
117 	if ((t = btree_open(dbname, O_CREAT|O_RDWR, 0600, &b)) == (DB *) NULL) {
118 		perror(progname);
119 		exit (1);
120 	}
121 
122 	load(t);
123 
124 	user(t);
125 }
126 
127 load(t)
128 	DB *t;
129 {
130 	char *lbuf;
131 	int i, l;
132 	int status;
133 	FILE *fp;
134 	DBT key;
135 	DBT data;
136 	char word[64];
137 	char drow[64];
138 
139 	printf("loading %s...\n", DICTIONARY);
140 	fflush(stdout);
141 	if ((fp = fopen(DICTIONARY, "r")) == (FILE *) NULL) {
142 		perror("/usr/dict/words");
143 		(void) (*(t->close))(t->internal);
144 		exit (1);
145 	}
146 
147 	key.data = &word[0];
148 	data.data = &drow[0];
149 	while ((lbuf = fgets(word, 64, fp)) != (char *) NULL) {
150 		l = strlen(lbuf) - 1;
151 		lbuf[l] = '\0';
152 		for (i = 0; i < l; i++)
153 			drow[l - (i + 1)] = word[i];
154 		drow[l] = '\0';
155 
156 		key.size = data.size = l + 1;
157 
158 		status = (*(t->put))(t->internal, &key, &data, R_NOOVERWRITE);
159 
160 		switch (status) {
161 		  case RET_SUCCESS:
162 			break;
163 
164 		  case RET_ERROR:
165 			perror("put");
166 			break;
167 
168 		  case RET_SPECIAL:
169 			fprintf(stderr, "%s is a duplicate key!\n", lbuf);
170 			fflush(stderr);
171 			break;
172 		}
173 	}
174 
175 	(void) fclose(fp);
176 	printf("done\n");
177 	fflush(stdout);
178 }
179 
180 user(t)
181 	DB *t;
182 {
183 	char *lbuf;
184 	int argc;
185 	int i;
186 	char *argv[4];
187 	char buf[512];
188 
189 	for (;;) {
190 		printf("> ");
191 		fflush(stdout);
192 		if ((lbuf = fgets(&buf[0], 512, stdin)) == (char *) NULL)
193 			break;
194 		lbuf[strlen(lbuf) - 1] = '\0';
195 
196 		if (strcmp(lbuf, "quit") == 0)
197 			break;
198 
199 		argc = parse(lbuf, &argv[0], 3);
200 		if (argc == 0)
201 			continue;
202 
203 		for (i = 0; Commands[i].cmd != (char *) NULL; i++) {
204 			if (strcmp(Commands[i].cmd, argv[0]) == 0)
205 				break;
206 		}
207 
208 		if (Commands[i].cmd == (char *) NULL) {
209 			fprintf(stderr,
210 				"%s: command unknown ('help' for help)\n",
211 				lbuf);
212 			fflush(stderr);
213 			continue;
214 		}
215 
216 		if (Commands[i].nargs != argc) {
217 			fprintf(stderr, "arg count\n");
218 			fflush(stderr);
219 			continue;
220 		}
221 
222 		switch (argc) {
223 		  case 1:
224 			(*(Commands[i].func))(t);
225 			break;
226 		  case 2:
227 			(*(Commands[i].func))(t, argv[1]);
228 			break;
229 		  case 3:
230 			(*(Commands[i].func))(t, argv[1], argv[2]);
231 			break;
232 		  case 4:
233 			(*(Commands[i].func))(t, argv[1], argv[2], argv[3]);
234 			break;
235 		}
236 	}
237 	(void) (*(t->close))(t->internal);
238 	exit (0);
239 }
240 
241 int
242 parse(lbuf, argv, maxargc)
243 	char *lbuf;
244 	char **argv;
245 	int maxargc;
246 {
247 	int argc = 0;
248 	char *c;
249 
250 	c = lbuf;
251 	while (isspace(*c))
252 		c++;
253 	while (*c != '\0' && argc < maxargc) {
254 		*argv++ = c;
255 		argc++;
256 		while (!isspace(*c) && *c != '\0') {
257 			c++;
258 		}
259 		while (isspace(*c))
260 			*c++ = '\0';
261 	}
262 	return (argc);
263 }
264 
265 int
266 cursor(t, arg)
267 	DB *t;
268 	char *arg;
269 {
270 	int status;
271 	DBT key;
272 	DBT data;
273 
274 	key.data = arg;
275 	key.size = strlen(arg + 1);
276 	status = (*(t->seq))(t->internal, &key, &data, R_CURSOR);
277 	if (status == RET_SUCCESS)
278 		show(&key, &data);
279 	else
280 		perror("cursor");
281 }
282 
283 int
284 delcur(t)
285 	DB *t;
286 {
287 	int status;
288 
289 	status = (*(t->delete))(t->internal, (DBT *) NULL, R_CURSOR);
290 
291 	if (status == RET_ERROR)
292 		perror("delcur");
293 }
294 
295 int
296 delete(t, arg)
297 	DB *t;
298 	char *arg;
299 {
300 	int status;
301 	DBT key;
302 
303 	key.data = arg;
304 	key.size = strlen(arg) + 1;
305 
306 	status = (*(t->delete))(t->internal, &key, 0);
307 	switch (status) {
308 	  case RET_SUCCESS:
309 		break;
310 
311 	  case RET_ERROR:
312 		perror("delete");
313 		break;
314 
315 	  case RET_SPECIAL:
316 		fprintf(stderr, "%s not found\n", arg);
317 		fflush(stderr);
318 		break;
319 	}
320 }
321 
322 int
323 first(t)
324 	DB *t;
325 {
326 	int status;
327 	DBT key;
328 	DBT data;
329 
330 	status = (*(t->seq))(t->internal, &key, &data, R_FIRST);
331 
332 	switch (status) {
333 	  case RET_ERROR:
334 		perror("first");
335 		break;
336 
337 	  case RET_SPECIAL:
338 		printf("no more keys");
339 		break;
340 
341 	  case RET_SUCCESS:
342 		show(&key, &data);
343 		break;
344 	}
345 }
346 int
347 help(t)
348 	DB *t;
349 {
350 	int i;
351 
352 #ifdef lint
353 	t = t;
354 #endif /* lint */
355 	for (i = 0; Commands[i].cmd != (char *) NULL; i++)
356 		printf("%s\n", Commands[i].descrip);
357 	printf("type 'quit' to quit\n");
358 }
359 
360 int
361 insert(t, arg, def)
362 	DB *t;
363 	char *arg;
364 	char *def;
365 {
366 	int status;
367 	DBT key;
368 	DBT data;
369 
370 	key.data = arg;
371 	key.size = strlen(arg) + 1;
372 	data.data = def;
373 	data.size = strlen(def) + 1;
374 
375 	status = (*(t->put))(t->internal, &key, &data, R_NOOVERWRITE);
376 	switch (status) {
377 	  case RET_SUCCESS:
378 		break;
379 
380 	  case RET_ERROR:
381 		perror("put");
382 		break;
383 
384 	  case RET_SPECIAL:
385 		fprintf(stderr, "%s is a duplicate key!\n", arg);
386 		fflush(stderr);
387 		break;
388 	}
389 }
390 
391 int
392 last(t)
393 	DB *t;
394 {
395 	int status;
396 	DBT key;
397 	DBT data;
398 
399 	status = (*(t->seq))(t->internal, &key, &data, R_LAST);
400 
401 	switch (status) {
402 	  case RET_ERROR:
403 		perror("last");
404 		break;
405 
406 	  case RET_SPECIAL:
407 		printf("no more keys");
408 		break;
409 
410 	  case RET_SUCCESS:
411 		show(&key, &data);
412 		break;
413 	}
414 }
415 
416 int
417 lookup(t, arg)
418 	DB *t;
419 	char *arg;
420 {
421 	int status;
422 	DBT key;
423 	DBT data;
424 
425 	key.data = arg;
426 	key.size = strlen(arg) + 1;
427 
428 	status = (*(t->get))(t->internal, &key, &data, 0);
429 
430 	switch (status) {
431 	  case RET_SPECIAL:
432 		printf("not found\n");
433 		break;
434 	  case RET_SUCCESS:
435 		show(&key, &data);
436 		break;
437 	  case RET_ERROR:
438 		perror("get");
439 		break;
440 	}
441 }
442 
443 int
444 next(t)
445 	DB *t;
446 {
447 	int status;
448 	DBT key;
449 	DBT data;
450 
451 	status = (*(t->seq))(t->internal, &key, &data, R_NEXT);
452 
453 	switch (status) {
454 	  case RET_ERROR:
455 		perror("next");
456 		break;
457 
458 	  case RET_SPECIAL:
459 		printf("no more keys");
460 		break;
461 
462 	  case RET_SUCCESS:
463 		show(&key, &data);
464 		break;
465 	}
466 }
467 
468 int
469 previous(t)
470 	DB *t;
471 {
472 	int status;
473 	DBT key;
474 	DBT data;
475 
476 	status = (*(t->seq))(t->internal, &key, &data, R_PREV);
477 
478 	switch (status) {
479 	  case RET_ERROR:
480 		perror("previous");
481 		break;
482 
483 	  case RET_SPECIAL:
484 		printf("no more keys");
485 		break;
486 
487 	  case RET_SUCCESS:
488 		show(&key, &data);
489 		break;
490 	}
491 }
492 
493 show(key, data)
494 	DBT *key;
495 	DBT *data;
496 {
497 	if (key->size > 0)
498 		printf("%s", key->data);
499 	if (data->size > 0)
500 		printf("/%s", data->data);
501 	printf("\n");
502 }
503