/************************************************************************************************* * Test cases of Cabin * Copyright (C) 2000-2003 Mikio Hirabayashi * This file is part of QDBM, Quick Database Manager. * QDBM is free software; you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License as published by the Free Software Foundation; either version * 2.1 of the License or any later version. QDBM is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * You should have received a copy of the GNU Lesser General Public License along with QDBM; if * not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA. *************************************************************************************************/ #include #include #include #include #include #include #undef TRUE #define TRUE 1 /* boolean true */ #undef FALSE #define FALSE 0 /* boolean false */ #define RECBUFSIZ 32 /* buffer for records */ /* for RISC OS */ #if defined(__riscos__) || defined(__riscos) #include int __riscosify_control = __RISCOSIFY_NO_PROCESS; #endif /* global variables */ const char *progname; /* program name */ /* function prototypes */ int main(int argc, char **argv); void usage(void); int runsort(int argc, char **argv); int runlist(int argc, char **argv); int runmap(int argc, char **argv); int runwicked(int argc, char **argv); int runmisc(int argc, char **argv); int printfflush(const char *format, ...); int strpcmp(const void *ap, const void *bp); int myrand(void); int dosort(int rnum, int disp); int dolist(int rnum, int disp); int domap(int rnum, int disp); int dowicked(int rnum); int domisc(void); /* main routine */ int main(int argc, char **argv){ int rv; progname = argv[0]; if(argc < 2) usage(); rv = 0; if(!strcmp(argv[1], "sort")){ rv = runsort(argc, argv); } else if(!strcmp(argv[1], "list")){ rv = runlist(argc, argv); } else if(!strcmp(argv[1], "map")){ rv = runmap(argc, argv); } else if(!strcmp(argv[1], "wicked")){ rv = runwicked(argc, argv); } else if(!strcmp(argv[1], "misc")){ rv = runmisc(argc, argv); } else { usage(); } return rv; } /* print the usage and exit */ void usage(void){ fprintf(stderr, "%s: test cases for Cabin\n", progname); fprintf(stderr, "\n"); fprintf(stderr, "usage:\n"); fprintf(stderr, " %s sort [-d] rnum\n", progname); fprintf(stderr, " %s list [-d] rnum\n", progname); fprintf(stderr, " %s map [-d] rnum\n", progname); fprintf(stderr, " %s wicked rnum\n", progname); fprintf(stderr, " %s misc\n", progname); exit(1); } /* parse arguments of sort command */ int runsort(int argc, char **argv){ int i, rnum, disp, rv; char *rstr; rstr = NULL; rnum = 0; disp = FALSE; for(i = 2; i < argc; i++){ if(argv[i][0] == '-'){ if(!strcmp(argv[i], "-d")){ disp = TRUE; } else { usage(); } } else if(!rstr){ rstr = argv[i]; } else { usage(); } } if(!rstr) usage(); rnum = atoi(rstr); if(rnum < 1) usage(); rv = dosort(rnum, disp); return rv; } /* parse arguments of list command */ int runlist(int argc, char **argv){ int i, rnum, disp, rv; char *rstr; rstr = NULL; rnum = 0; disp = FALSE; for(i = 2; i < argc; i++){ if(argv[i][0] == '-'){ if(!strcmp(argv[i], "-d")){ disp = TRUE; } else { usage(); } } else if(!rstr){ rstr = argv[i]; } else { usage(); } } if(!rstr) usage(); rnum = atoi(rstr); if(rnum < 1) usage(); rv = dolist(rnum, disp); return rv; } /* parse arguments of map command */ int runmap(int argc, char **argv){ int i, rnum, disp, rv; char *rstr; rstr = NULL; rnum = 0; disp = FALSE; for(i = 2; i < argc; i++){ if(argv[i][0] == '-'){ if(!strcmp(argv[i], "-d")){ disp = TRUE; } else { usage(); } } else if(!rstr){ rstr = argv[i]; } else { usage(); } } if(!rstr) usage(); rnum = atoi(rstr); if(rnum < 1) usage(); rv = domap(rnum, disp); return rv; } /* parse arguments of wicked command */ int runwicked(int argc, char **argv){ int i, rnum, rv; char *rstr; rstr = NULL; rnum = 0; for(i = 2; i < argc; i++){ if(argv[i][0] == '-'){ usage(); } else if(!rstr){ rstr = argv[i]; } else { usage(); } } if(!rstr) usage(); rnum = atoi(rstr); if(rnum < 1) usage(); rv = dowicked(rnum); return rv; } /* parse arguments of misc command */ int runmisc(int argc, char **argv){ int rv; rv = domisc(); return rv; } /* print formatted string and flush the buffer */ int prinfflush(const char *format, ...){ va_list ap; int rv; va_start(ap, format); rv = vprintf(format, ap); if(fflush(stdout) == EOF) rv = -1; va_end(ap); return rv; } /* comparing function */ int strpcmp(const void *ap, const void *bp){ char *a, *b; a = *(char **)ap; b = *(char **)bp; return strcmp(a, b); } /* pseudo random number generator */ int myrand(void){ static int cnt = 0; if(cnt == 0) srand(time(NULL)); return (rand() * rand() + (rand() >> (sizeof(int) * 4)) + (cnt++)) & 0x7FFFFFFF; } /* perform sort command */ int dosort(int rnum, int disp){ char **ivector1, **ivector2, **ivector3, **ivector4, **ivector5; char buf[RECBUFSIZ]; int i, len, err; if(!disp) prinfflush("\n rnum=%d disp=%d\n\n", rnum, disp); ivector1 = cbmalloc(rnum * sizeof(ivector1[0])); ivector2 = cbmalloc(rnum * sizeof(ivector2[0])); ivector3 = cbmalloc(rnum * sizeof(ivector3[0])); ivector4 = cbmalloc(rnum * sizeof(ivector4[0])); ivector5 = cbmalloc(rnum * sizeof(ivector5[0])); err = FALSE; for(i = 0; i < rnum; i++){ len = sprintf(buf, "%08d", myrand() % rnum + 1); ivector1[i] = cbmemdup(buf, len); ivector2[i] = cbmemdup(buf, len); ivector3[i] = cbmemdup(buf, len); ivector4[i] = cbmemdup(buf, len); ivector5[i] = cbmemdup(buf, len); } if(!disp) prinfflush("Sorting with insert sort ... "); cbisort(ivector1, rnum, sizeof(ivector1[0]), strpcmp); if(!disp) prinfflush("ok\n"); if(!disp) prinfflush("Sorting with shell sort ... "); cbssort(ivector2, rnum, sizeof(ivector2[0]), strpcmp); if(!disp) prinfflush("ok\n"); if(!disp) prinfflush("Sorting with heap sort ... "); cbhsort(ivector3, rnum, sizeof(ivector3[0]), strpcmp); if(!disp) prinfflush("ok\n"); if(!disp) prinfflush("Sorting with quick sort ... "); cbqsort(ivector4, rnum, sizeof(ivector4[0]), strpcmp); if(!disp) prinfflush("ok\n"); for(i = 0; i < rnum; i++){ if(disp) prinfflush("%s\t%s\t%s\t%s\t[%s]\n", ivector1[i], ivector2[i], ivector3[i], ivector4[i], ivector5[i]); if(strcmp(ivector1[i], ivector2[i])) err = TRUE; if(strcmp(ivector1[i], ivector3[i])) err = TRUE; if(strcmp(ivector1[i], ivector4[i])) err = TRUE; free(ivector1[i]); free(ivector2[i]); free(ivector3[i]); free(ivector4[i]); free(ivector5[i]); } free(ivector1); free(ivector2); free(ivector3); free(ivector4); free(ivector5); if(err) fprintf(stderr, "%s: sorting failed\n", progname); if(!disp && !err) prinfflush("all ok\n\n"); return err ? 1 : 0; } /* perform list command */ int dolist(int rnum, int disp){ CBLIST *list; int i, err, len; char buf[RECBUFSIZ]; const char *val; if(!disp) prinfflush("\n rnum=%d disp=%d\n\n", rnum, disp); list = cblistopen(); err = FALSE; for(i = 1; i <= rnum; i++){ len = sprintf(buf, "%08d", i); cblistpush(list, buf, len); if(!disp && rnum > 250 && i % (rnum / 250) == 0){ putchar('.'); fflush(stdout); if(i == rnum || i % (rnum / 10) == 0){ prinfflush(" (%08d)\n", i); } } } if(disp){ for(i = 0; i < cblistnum(list); i++){ if((val = cblistval(list, i, NULL)) != NULL){ prinfflush("%s\n", val); } else { fprintf(stderr, "%s: val error\n", progname); err = TRUE; break; } } } cblistclose(list); if(!disp && !err) prinfflush("ok\n\n"); return err ? 1 : 0; } /* perform list command */ int domap(int rnum, int disp){ CBMAP *map; int i, err, len; char buf[RECBUFSIZ]; const char *val; if(!disp) prinfflush("\n rnum=%d disp=%d\n\n", rnum, disp); map = cbmapopen(); err = FALSE; for(i = 1; i <= rnum; i++){ len = sprintf(buf, "%08d", i); if(!cbmapput(map, buf, len, buf, len, FALSE)){ fprintf(stderr, "%s: put error\n", progname); err = TRUE; break; } if(!disp && rnum > 250 && i % (rnum / 250) == 0){ putchar('.'); fflush(stdout); if(i == rnum || i % (rnum / 10) == 0){ prinfflush(" (%08d)\n", i); } } } if(disp){ for(i = 1; i <= rnum; i++){ len = sprintf(buf, "%08d", i); if((val = cbmapget(map, buf, len, NULL)) != NULL){ prinfflush("%s\n", val); } else { fprintf(stderr, "%s: get error\n", progname); } } } cbmapclose(map); if(!disp && !err) prinfflush("ok\n\n"); return err ? 1 : 0; } /* perform wicked command */ int dowicked(int rnum){ CBLIST *list; CBMAP *map; int i, len; char buf[RECBUFSIZ]; prinfflush("\n rnum=%d\n\n", rnum); list = cblistopen(); for(i = 1; i <= rnum; i++){ len = sprintf(buf, "%08d", myrand() % rnum + 1); switch(myrand() % 16){ case 0: free(cblistpop(list, NULL)); putchar('O'); break; case 1: cblistunshift(list, buf, len); putchar('U'); break; case 2: free(cblistshift(list, NULL)); putchar('S'); break; case 3: cblistinsert(list, myrand() % (cblistnum(list) + 1), buf, len); putchar('I'); break; case 4: free(cblistremove(list, myrand() % (cblistnum(list) + 1), NULL)); putchar('R'); break; default: cblistpush(list, buf, len); putchar('P'); break; } if(i % 50 == 0) prinfflush(" (%08d)\n", i); } cblistclose(list); map = cbmapopen(); for(i = 1; i <= rnum; i++){ len = sprintf(buf, "%08d", myrand() % rnum + 1); switch(myrand() % 16){ case 0: cbmapput(map, buf, len, buf, len, FALSE); putchar('I'); break; case 1: cbmapget(map, buf, len, NULL); putchar('V'); break; case 2: cbmapout(map, buf, len); putchar('D'); break; case 3: cbmapmove(map, buf, len, myrand() % 2); putchar('M'); break; default: cbmapput(map, buf, len, buf, len, TRUE); putchar('O'); break; } if(i % 50 == 0) prinfflush(" (%08d)\n", i); } cbmapclose(map); prinfflush("ok\n\n"); return 0; } /* perform misc command */ int domisc(void){ CBLIST *olist, *nlist, *elems; CBMAP *omap, *nmap, *pairs; int i, ssiz, osiz; char kbuf[RECBUFSIZ], vbuf[RECBUFSIZ], *sbuf, spbuf[1024], *tmp, *orig; const char *op, *np; prinfflush("\n\n"); prinfflush("Checking serialization of list ... "); olist = cblistopen(); for(i = 1; i <= 1000; i++){ sprintf(vbuf, "%d", i); cblistpush(olist, vbuf, -1); } sbuf = cblistdump(olist, &ssiz); nlist = cblistload(sbuf, ssiz); free(sbuf); for(i = 0; i < cblistnum(olist); i++){ op = cblistval(olist, i, NULL); np = cblistval(nlist, i, NULL); if(!op || !np || strcmp(op, np)){ cblistclose(nlist); cblistclose(olist); fprintf(stderr, "%s: validation failed\n", progname); return 1; } } cblistclose(nlist); cblistclose(olist); prinfflush("ok\n"); prinfflush("Checking serialization of map ... "); omap = cbmapopen(); for(i = 1; i <= 1000; i++){ sprintf(kbuf, "%X", i); sprintf(vbuf, "[%d]", i); } sbuf = cbmapdump(omap, &ssiz); nmap = cbmapload(sbuf, ssiz); free(sbuf); cbmapiterinit(omap); while((op = cbmapiternext(omap, NULL)) != NULL){ if(!(np = cbmapget(nmap, op, -1, NULL))){ cbmapclose(nmap); cbmapclose(omap); fprintf(stderr, "%s: validation failed\n", progname); return 1; } } cbmapclose(nmap); cbmapclose(omap); prinfflush("ok\n"); prinfflush("Checking string utilities ... "); sprintf(spbuf, "[%08d/%08o/%08u/%08x/%08X/%08.3e/%08.3E/%08.3f/%08.3g/%08.3G/%c/%s/%%]", 123456, 123456, 123456, 123456, 123456, 123456.789, 123456.789, 123456.789, 123456.789, 123456.789, 'A', "hoge"); tmp = cbsprintf("[%08d/%08o/%08u/%08x/%08X/%08.3e/%08.3E/%08.3f/%08.3g/%08.3G/%c/%s/%%]", 123456, 123456, 123456, 123456, 123456, 123456.789, 123456.789, 123456.789, 123456.789, 123456.789, 'A', "hoge"); while(strcmp(spbuf, tmp)){ free(tmp); fprintf(stderr, "%s: cbsprintf is invalid\n", progname); return 1; } free(tmp); pairs = cbmapopen(); cbmapput(pairs, "aa", -1, "AAA", -1, TRUE); cbmapput(pairs, "bb", -1, "BBB", -1, TRUE); cbmapput(pairs, "cc", -1, "CCC", -1, TRUE); cbmapput(pairs, "ZZZ", -1, "z", -1, TRUE); tmp = cbreplace("[aaaaabbbbbcccccdddddZZZZ]", pairs); if(strcmp(tmp, "[AAAAAAaBBBBBBbCCCCCCcdddddzZ]")){ free(tmp); cbmapclose(pairs); fprintf(stderr, "%s: cbreplace is invalid\n", progname); return 1; } free(tmp); cbmapclose(pairs); elems = cbsplit("aa bb,ccc-dd,", -1, " ,-"); if(cblistnum(elems) != 5 || strcmp(cblistval(elems, 0, NULL), "aa") || strcmp(cblistval(elems, 1, NULL), "bb") || strcmp(cblistval(elems, 2, NULL), "ccc") || strcmp(cblistval(elems, 3, NULL), "dd") || strcmp(cblistval(elems, 4, NULL), "")){ cblistclose(elems); fprintf(stderr, "%s: cbsplit is invalid\n", progname); return 1; } cblistclose(elems); prinfflush("ok\n"); prinfflush("Checking encoding utilities ... "); strcpy(spbuf, "My name is \xca\xbf\xce\xd3\xb4\xb4\xcd\xba.\n\nGo ahead!\n"); tmp = cburlencode(spbuf, -1); orig = cburldecode(tmp, &osiz); if(osiz != strlen(spbuf) || strcmp(orig, spbuf)){ free(orig); free(tmp); fprintf(stderr, "%s: URL encoding is invalid\n", progname); return 1; } free(orig); free(tmp); tmp = cbbaseencode(spbuf, -1); orig = cbbasedecode(tmp, &osiz); if(osiz != strlen(spbuf) || strcmp(orig, spbuf)){ free(orig); free(tmp); fprintf(stderr, "%s: Base64 encoding is invalid\n", progname); return 1; } free(orig); free(tmp); tmp = cbquoteencode(spbuf, -1); orig = cbquotedecode(tmp, &osiz); if(osiz != strlen(spbuf) || strcmp(orig, spbuf)){ free(orig); free(tmp); fprintf(stderr, "%s: quoted-printable encoding is invalid\n", progname); return 1; } free(orig); free(tmp); prinfflush("ok\n"); prinfflush("all ok\n\n"); return 0; } /* END OF FILE */