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