summaryrefslogtreecommitdiff
path: root/qdbm/cbtest.c
diff options
context:
space:
mode:
Diffstat (limited to 'qdbm/cbtest.c')
-rw-r--r--qdbm/cbtest.c924
1 files changed, 924 insertions, 0 deletions
diff --git a/qdbm/cbtest.c b/qdbm/cbtest.c
new file mode 100644
index 00000000..d1c84e0d
--- /dev/null
+++ b/qdbm/cbtest.c
@@ -0,0 +1,924 @@
+/*************************************************************************************************
+ * Test cases of Cabin
+ * Copyright (C) 2000-2007 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 <cabin.h>
+#include <stdio.h>
+#include <cabin.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <time.h>
+
+#undef TRUE
+#define TRUE 1 /* boolean true */
+#undef FALSE
+#define FALSE 0 /* boolean false */
+
+#define RECBUFSIZ 32 /* buffer for records */
+#define TEXTBUFSIZ 262144 /* buffer for text */
+
+
+/* for RISC OS */
+#if defined(__riscos__) || defined(__riscos)
+#include <unixlib/local.h>
+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 runstrstr(int argc, char **argv);
+int runlist(int argc, char **argv);
+int runmap(int argc, char **argv);
+int runheap(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 intpcmp(const void *ap, const void *bp);
+int myrand(void);
+int dosort(int rnum, int disp);
+int dostrstr(int rnum, int disp);
+int dolist(int rnum, int disp);
+int domap(int rnum, int bnum, int disp);
+int doheap(int rnum, int max, int disp);
+int dowicked(int rnum);
+int domisc(void);
+
+
+/* main routine */
+int main(int argc, char **argv){
+ int rv;
+ cbstdiobin();
+ progname = argv[0];
+ if(argc < 2) usage();
+ rv = 0;
+ if(!strcmp(argv[1], "sort")){
+ rv = runsort(argc, argv);
+ } else if(!strcmp(argv[1], "strstr")){
+ rv = runstrstr(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], "heap")){
+ rv = runheap(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 strstr [-d] rnum\n", progname);
+ fprintf(stderr, " %s list [-d] rnum\n", progname);
+ fprintf(stderr, " %s map [-d] rnum [bnum]\n", progname);
+ fprintf(stderr, " %s heap [-d] rnum [top]\n", progname);
+ fprintf(stderr, " %s wicked rnum\n", progname);
+ fprintf(stderr, " %s misc\n", progname);
+ fprintf(stderr, "\n");
+ 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 strstr command */
+int runstrstr(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 = dostrstr(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, bnum, disp, rv;
+ char *rstr, *bstr;
+ rstr = NULL;
+ bstr = NULL;
+ rnum = 0;
+ bnum = -1;
+ 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 if(!bstr){
+ bstr = argv[i];
+ } else {
+ usage();
+ }
+ }
+ if(!rstr) usage();
+ rnum = atoi(rstr);
+ if(rnum < 1) usage();
+ if(bstr) bnum = atoi(bstr);
+ rv = domap(rnum, bnum, disp);
+ return rv;
+}
+
+
+/* parse arguments of heap command */
+int runheap(int argc, char **argv){
+ int i, rnum, max, disp, rv;
+ char *rstr, *mstr;
+ rstr = NULL;
+ mstr = NULL;
+ rnum = 0;
+ max = -1;
+ 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 if(!mstr){
+ mstr = argv[i];
+ } else {
+ usage();
+ }
+ }
+ if(!rstr) usage();
+ rnum = atoi(rstr);
+ if(rnum < 1) usage();
+ if(mstr) max = atoi(mstr);
+ if(max < 0) max = rnum;
+ rv = doheap(rnum, max, disp);
+ rv = 0;
+ 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 printfflush(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 for strings */
+int strpcmp(const void *ap, const void *bp){
+ return strcmp(*(char **)ap, *(char **)bp);
+}
+
+
+/* comparing function for integers */
+int intpcmp(const void *ap, const void *bp){
+ return *(int *)ap - *(int *)bp;
+}
+
+
+/* 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++)) & INT_MAX;
+}
+
+
+/* perform sort command */
+int dosort(int rnum, int disp){
+ char **ivector1, **ivector2, **ivector3, **ivector4, **ivector5;
+ char buf[RECBUFSIZ];
+ int i, len, err;
+ if(!disp) printfflush("<Sorting Test>\n rnum=%d\n\n", rnum);
+ 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) printfflush("Sorting with insert sort ... ");
+ cbisort(ivector1, rnum, sizeof(ivector1[0]), strpcmp);
+ if(!disp) printfflush("ok\n");
+ if(!disp) printfflush("Sorting with shell sort ... ");
+ cbssort(ivector2, rnum, sizeof(ivector2[0]), strpcmp);
+ if(!disp) printfflush("ok\n");
+ if(!disp) printfflush("Sorting with heap sort ... ");
+ cbhsort(ivector3, rnum, sizeof(ivector3[0]), strpcmp);
+ if(!disp) printfflush("ok\n");
+ if(!disp) printfflush("Sorting with quick sort ... ");
+ cbqsort(ivector4, rnum, sizeof(ivector4[0]), strpcmp);
+ if(!disp) printfflush("ok\n");
+ for(i = 0; i < rnum; i++){
+ if(disp) printfflush("%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) printfflush("all ok\n\n");
+ return err ? 1 : 0;
+}
+
+
+/* perform strstr command */
+int dostrstr(int rnum, int disp){
+ char *text, buf[RECBUFSIZ], *std, *kmp, *bm;
+ int i, j, len, err;
+ text = cbmalloc(TEXTBUFSIZ);
+ for(i = 0; i < TEXTBUFSIZ - 1; i++){
+ text[i] = 'a' + myrand() % ('z' - 'a');
+ }
+ text[i] = '\0';
+ err = FALSE;
+ if(!disp) printfflush("Locating substrings ... ");
+ for(i = 0; i < rnum; i++){
+ len = myrand() % (RECBUFSIZ - 1);
+ for(j = 0; j < len; j++){
+ buf[j] = 'a' + myrand() % ('z' - 'a');
+ }
+ buf[j] = 0;
+ std = strstr(text, buf);
+ kmp = cbstrstrkmp(text, buf);
+ bm = cbstrstrbm(text, buf);
+ if(kmp != std || bm != std){
+ err = TRUE;
+ break;
+ }
+ if(disp && std) printf("%s\n", buf);
+ }
+ if(err) fprintf(stderr, "%s: string scanning failed\n", progname);
+ if(!disp && !err){
+ printfflush("ok\n");
+ printfflush("all ok\n\n");
+ }
+ free(text);
+ return err ? 1 : 0;
+}
+
+
+/* perform list command */
+int dolist(int rnum, int disp){
+ CBLIST *list;
+ const char *vbuf;
+ char buf[RECBUFSIZ], *tmp;
+ int i, err, len, vsiz;
+ if(!disp) printfflush("<List Writing Test>\n rnum=%d\n\n", rnum);
+ 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){
+ printfflush(" (%08d)\n", i);
+ }
+ }
+ }
+ if(disp){
+ for(i = 0; i < cblistnum(list); i++){
+ if((vbuf = cblistval(list, i, &vsiz)) != NULL){
+ printfflush("%s:%d\n", vbuf, vsiz);
+ } else {
+ fprintf(stderr, "%s: val error\n", progname);
+ err = TRUE;
+ break;
+ }
+ }
+ printfflush("\n");
+ while((tmp = cblistpop(list, &vsiz)) != NULL){
+ printfflush("%s:%d\n", tmp, vsiz);
+ free(tmp);
+ }
+ }
+ cblistclose(list);
+ if(!disp && !err) printfflush("ok\n\n");
+ return err ? 1 : 0;
+}
+
+
+/* perform list command */
+int domap(int rnum, int bnum, int disp){
+ CBMAP *map;
+ const char *kbuf, *vbuf;
+ char buf[RECBUFSIZ];
+ int i, err, len, ksiz, vsiz;
+ if(!disp) printfflush("<Map Writing Test>\n rnum=%d bnum=%d\n\n", rnum, bnum);
+ map = bnum > 0 ? cbmapopenex(bnum) : 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){
+ printfflush(" (%08d)\n", i);
+ }
+ }
+ }
+ if(disp){
+ for(i = 1; i <= rnum; i++){
+ len = sprintf(buf, "%08d", i);
+ if((vbuf = cbmapget(map, buf, len, &vsiz)) != NULL){
+ printfflush("%s:%d\t%s:%d\n", buf, len, vbuf, vsiz);
+ } else {
+ fprintf(stderr, "%s: get error\n", progname);
+ }
+ }
+ printfflush("\n");
+ cbmapiterinit(map);
+ while((kbuf = cbmapiternext(map, &ksiz)) != NULL){
+ vbuf = cbmapiterval(kbuf, &vsiz);
+ printfflush("%s:%d\t%s:%d\n", kbuf, ksiz, vbuf, vsiz);
+ }
+ }
+ cbmapclose(map);
+ if(!disp && !err) printfflush("ok\n\n");
+ return err ? 1 : 0;
+}
+
+
+/* perform heap command */
+int doheap(int rnum, int max, int disp){
+ CBHEAP *heap;
+ int *orig, *ary;
+ int i, err, num, anum;
+ if(!disp) printfflush("<Heap Writing Test>\n rnum=%d max=%d\n\n", rnum, max);
+ orig = disp ? cbmalloc(rnum * sizeof(int) + 1) : NULL;
+ heap = cbheapopen(sizeof(int), max, intpcmp);
+ err = FALSE;
+ for(i = 1; i <= rnum; i++){
+ num = myrand() % rnum + 1;
+ if(orig) orig[i-1] = num;
+ cbheapinsert(heap, &num);
+ if(!disp && rnum > 250 && i % (rnum / 250) == 0){
+ putchar('.');
+ fflush(stdout);
+ if(i == rnum || i % (rnum / 10) == 0){
+ printfflush(" (%08d)\n", i);
+ }
+ }
+ }
+ if(disp){
+ for(i = 0; i < cbheapnum(heap); i++){
+ printf("%d\n", *(int *)cbheapval(heap, i));
+ }
+ printf("\n");
+ qsort(orig, rnum, sizeof(int), intpcmp);
+ ary = (int *)cbheaptomalloc(heap, &anum);
+ if(anum != rnum && anum != max) err = TRUE;
+ for(i = 0; i < anum; i++){
+ printf("%d\t%d\n", ary[i], orig[i]);
+ if(ary[i] != orig[i]) err = TRUE;
+ }
+ free(ary);
+ } else {
+ cbheapclose(heap);
+ }
+ free(orig);
+ if(!disp && !err) printfflush("ok\n\n");
+ return err ? 1 : 0;
+}
+
+
+/* perform wicked command */
+int dowicked(int rnum){
+ CBLIST *list;
+ CBMAP *map;
+ int i, len;
+ char buf[RECBUFSIZ], *tmp;
+ printfflush("<Wicked Writing Test>\n rnum=%d\n\n", rnum);
+ list = cblistopen();
+ for(i = 1; i <= rnum; i++){
+ len = sprintf(buf, "%d", 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;
+ case 5:
+ cblistover(list, myrand() % (cblistnum(list) + 1), buf, len);
+ putchar('V');
+ break;
+ case 6:
+ tmp = cbmemdup(buf, len);
+ cblistpushbuf(list, tmp, len);
+ putchar('B');
+ break;
+ default:
+ cblistpush(list, buf, len);
+ putchar('P');
+ break;
+ }
+ if(i % 50 == 0) printfflush(" (%08d)\n", i);
+ }
+ cblistclose(list);
+ map = cbmapopen();
+ for(i = 1; i <= rnum; i++){
+ len = sprintf(buf, "%d", myrand() % rnum + 1);
+ switch(myrand() % 16){
+ case 0:
+ cbmapput(map, buf, len, buf, len, FALSE);
+ putchar('I');
+ break;
+ case 1:
+ cbmapputcat(map, buf, len, buf, len);
+ putchar('C');
+ break;
+ case 2:
+ cbmapget(map, buf, len, NULL);
+ putchar('V');
+ break;
+ case 3:
+ cbmapout(map, buf, len);
+ putchar('D');
+ break;
+ case 4:
+ cbmapmove(map, buf, len, myrand() % 2);
+ putchar('M');
+ break;
+ default:
+ cbmapput(map, buf, len, buf, len, TRUE);
+ putchar('O');
+ break;
+ }
+ if(i % 50 == 0) printfflush(" (%08d)\n", i);
+ }
+ cbmapclose(map);
+ printfflush("ok\n\n");
+ return 0;
+}
+
+
+/* perform misc command */
+int domisc(void){
+ CBDATUM *odatum, *ndatum;
+ CBLIST *olist, *nlist, *elems, *glist;
+ CBMAP *omap, *nmap, *pairs, *gmap;
+ int i, j, ssiz, osiz, tsiz, jl;
+ char kbuf[RECBUFSIZ], vbuf[RECBUFSIZ], *sbuf, spbuf[1024], *tmp, *orig, renc[64];
+ const char *op, *np;
+ time_t t;
+ printfflush("<Miscellaneous Test>\n\n");
+ printfflush("Checking memory allocation ... ");
+ tmp = cbmalloc(1024);
+ for(i = 1; i <= 65536; i *= 2){
+ tmp = cbrealloc(tmp, i);
+ }
+ cbfree(tmp);
+ printfflush("ok\n");
+ printfflush("Checking basic datum ... ");
+ odatum = cbdatumopen("x", -1);
+ for(i = 0; i < 1000; i++){
+ cbdatumcat(odatum, "x", 1);
+ }
+ cbdatumclose(odatum);
+ tmp = cbmalloc(3);
+ memcpy(tmp, "abc", 3);
+ odatum = cbdatumopenbuf(tmp, 3);
+ for(i = 0; i < 1000; i++){
+ cbdatumcat(odatum, ".", 1);
+ }
+ ndatum = cbdatumdup(odatum);
+ for(i = 0; i < 1000; i++){
+ cbdatumcat(ndatum, "*", 1);
+ }
+ for(i = 0; i < 1000; i++){
+ tmp = cbmalloc(3);
+ memcpy(tmp, "123", 3);
+ cbdatumsetbuf(ndatum, tmp, 3);
+ }
+ cbdatumprintf(ndatum, "[%s\t%08d\t%08o\t%08x\t%08.1f\t%@\t%?\t%:]",
+ "mikio", 1978, 1978, 1978, 1978.0211, "<>&#!+-*/%", "<>&#!+-*/%", "<>&#!+-*/%");
+ cbdatumclose(ndatum);
+ cbdatumclose(odatum);
+ printfflush("ok\n");
+ printfflush("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);
+ printfflush("ok\n");
+ printfflush("Checking serialization of map ... ");
+ omap = cbmapopen();
+ for(i = 1; i <= 1000; i++){
+ sprintf(kbuf, "%X", i);
+ sprintf(vbuf, "[%d]", i);
+ cbmapput(omap, kbuf, -1, vbuf, -1, TRUE);
+ }
+ sbuf = cbmapdump(omap, &ssiz);
+ nmap = cbmapload(sbuf, ssiz);
+ free(cbmaploadone(sbuf, ssiz, "1", 2, &tsiz));
+ free(cbmaploadone(sbuf, ssiz, "33", 2, &tsiz));
+ 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);
+ printfflush("ok\n");
+ printfflush("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);
+ if(cbstricmp("abc", "ABC") || !cbstricmp("abc", "abcd")){
+ fprintf(stderr, "%s: cbstricmp is invalid\n", progname);
+ return 1;
+ }
+ if(!cbstrfwmatch("abcd", "abc") || cbstrfwmatch("abc", "abcd")){
+ fprintf(stderr, "%s: cbstrfwmatch is invalid\n", progname);
+ return 1;
+ }
+ if(!cbstrfwimatch("abcd", "ABC") || cbstrfwmatch("abc", "ABCD")){
+ fprintf(stderr, "%s: cbstrfwimatch is invalid\n", progname);
+ return 1;
+ }
+ if(!cbstrbwmatch("dcba", "cba") || cbstrbwmatch("cba", "dcba")){
+ fprintf(stderr, "%s: cbstrbwmatch is invalid\n", progname);
+ return 1;
+ }
+ if(!cbstrbwimatch("dcba", "CBA") || cbstrbwimatch("cba", "DCBA")){
+ fprintf(stderr, "%s: cbstrbwimatch is invalid\n", progname);
+ return 1;
+ }
+ tmp = cbmemdup(" \r\n[Quick Database Manager]\r\n ", -1);
+ if(cbstrtoupper(tmp) != tmp || strcmp(tmp, " \r\n[QUICK DATABASE MANAGER]\r\n ")){
+ free(tmp);
+ fprintf(stderr, "%s: cbstrtoupper is invalid\n", progname);
+ return 1;
+ }
+ if(cbstrtolower(tmp) != tmp || strcmp(tmp, " \r\n[quick database manager]\r\n ")){
+ free(tmp);
+ fprintf(stderr, "%s: cbstrtolower is invalid\n", progname);
+ return 1;
+ }
+ if(cbstrtrim(tmp) != tmp || strcmp(tmp, "[quick database manager]")){
+ free(tmp);
+ fprintf(stderr, "%s: cbstrtrim is invalid\n", progname);
+ return 1;
+ }
+ if(cbstrsqzspc(tmp) != tmp || strcmp(tmp, "[quick database manager]")){
+ free(tmp);
+ fprintf(stderr, "%s: cbstrsqzspc is invalid\n", progname);
+ return 1;
+ }
+ cbstrcututf(tmp, 5);
+ if(cbstrcountutf(tmp) != 5){
+ free(tmp);
+ fprintf(stderr, "%s: cbstrcututf or cbstrcountutf is invalid\n", progname);
+ return 1;
+ }
+ free(tmp);
+ printfflush("ok\n");
+ printfflush("Checking encoding utilities ... ");
+ strcpy(spbuf, "My name is \xca\xbf\xce\xd3\xb4\xb4\xcd\xba.\n\n<Love & Peace!>\n");
+ 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);
+ strcpy(spbuf, "My name is \xca\xbf\xce\xd3\xb4\xb4\xcd\xba.\n\n<Love & Peace!>\n");
+ 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);
+ strcpy(spbuf, "My name is \xca\xbf\xce\xd3\xb4\xb4\xcd\xba.\n\n<Love & Peace!>\n");
+ tmp = cbmimeencode(spbuf, "ISO-8859-1", TRUE);
+ orig = cbmimedecode(tmp, renc);
+ if(osiz != strlen(spbuf) || strcmp(orig, spbuf) || strcmp(renc, "ISO-8859-1")){
+ free(orig);
+ free(tmp);
+ fprintf(stderr, "%s: MIME encoding is invalid\n", progname);
+ return 1;
+ }
+ free(orig);
+ free(tmp);
+ strcpy(spbuf, "\"He says...\r\n\"\"What PROGRAM are they watching?\"\"\"");
+ tmp = cbcsvunescape(spbuf);
+ orig = cbcsvescape(tmp);
+ if(strcmp(orig, spbuf)){
+ free(orig);
+ free(tmp);
+ fprintf(stderr, "%s: CSV escaping is invalid\n", progname);
+ return 1;
+ }
+ free(orig);
+ free(tmp);
+ strcpy(spbuf, "&lt;Nuts&amp;Milk&gt; is &quot;very&quot; surfin&apos;!");
+ tmp = cbxmlunescape(spbuf);
+ orig = cbxmlescape(tmp);
+ if(strcmp(orig, spbuf)){
+ free(orig);
+ free(tmp);
+ fprintf(stderr, "%s: XML escaping is invalid\n", progname);
+ return 1;
+ }
+ free(orig);
+ free(tmp);
+ printfflush("ok\n");
+ printfflush("Checking date utilities ... ");
+ for(i = 0; i < 200; i++){
+ jl = (myrand() % 23) * 1800;
+ if(myrand() % 2 == 0) jl *= -1;
+ t = myrand() % (INT_MAX - 3600 * 24 * 365 * 6) + 3600 * 24 * 365 * 5;
+ tmp = cbdatestrwww(t, jl);
+ t = cbstrmktime(tmp);
+ orig = cbdatestrwww(t, jl);
+ if(strcmp(orig, tmp)){
+ free(orig);
+ free(tmp);
+ fprintf(stderr, "%s: W3CDTF formatter is invalid\n", progname);
+ return 1;
+ }
+ free(orig);
+ free(tmp);
+ tmp = cbdatestrhttp(t, jl);
+ t = cbstrmktime(tmp);
+ orig = cbdatestrhttp(t, jl);
+ if(strcmp(orig, tmp)){
+ free(orig);
+ free(tmp);
+ fprintf(stderr, "%s: RFC 822 date formatter is invalid\n", progname);
+ return 1;
+ }
+ free(orig);
+ free(tmp);
+ }
+ printfflush("ok\n");
+ printfflush("Checking the global garbage collector ... ");
+ for(i = 0; i < 512; i++){
+ glist = cblistopen();
+ cbglobalgc(glist, (void (*)(void *))cblistclose);
+ for(j = 0; j < 10; j++){
+ sprintf(kbuf, "%08d", j);
+ cblistpush(glist, kbuf, -1);
+ }
+ gmap = cbmapopen();
+ cbglobalgc(gmap, (void (*)(void *))cbmapclose);
+ for(j = 0; j < 10; j++){
+ sprintf(kbuf, "%08d", j);
+ cbmapput(gmap, kbuf, -1, kbuf, -1, TRUE);
+ }
+ if(myrand() % 64 == 0){
+ cbvmemavail(100);
+ cbggcsweep();
+ }
+ }
+ printfflush("ok\n");
+ printfflush("all ok\n\n");
+ return 0;
+}
+
+
+
+/* END OF FILE */