1 /*************************************************************************************************
2 * Test cases of Cabin
3 * Copyright (C) 2000-2007 Mikio Hirabayashi
4 * This file is part of QDBM, Quick Database Manager.
5 * QDBM is free software; you can redistribute it and/or modify it under the terms of the GNU
6 * Lesser General Public License as published by the Free Software Foundation; either version
7 * 2.1 of the License or any later version. QDBM is distributed in the hope that it will be
8 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
10 * details.
11 * You should have received a copy of the GNU Lesser General Public License along with QDBM; if
12 * not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
13 * 02111-1307 USA.
14 *************************************************************************************************/
15
16
17 #include <cabin.h>
18 #include <stdio.h>
19 #include <cabin.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <limits.h>
24 #include <time.h>
25
26 #undef TRUE
27 #define TRUE 1 /* boolean true */
28 #undef FALSE
29 #define FALSE 0 /* boolean false */
30
31 #define RECBUFSIZ 32 /* buffer for records */
32 #define TEXTBUFSIZ 262144 /* buffer for text */
33
34
35 /* for RISC OS */
36 #if defined(__riscos__) || defined(__riscos)
37 #include <unixlib/local.h>
38 int __riscosify_control = __RISCOSIFY_NO_PROCESS;
39 #endif
40
41
42 /* global variables */
43 const char *progname; /* program name */
44
45
46 /* function prototypes */
47 int main(int argc, char **argv);
48 void usage(void);
49 int runsort(int argc, char **argv);
50 int runstrstr(int argc, char **argv);
51 int runlist(int argc, char **argv);
52 int runmap(int argc, char **argv);
53 int runheap(int argc, char **argv);
54 int runwicked(int argc, char **argv);
55 int runmisc(int argc, char **argv);
56 int printfflush(const char *format, ...);
57 int strpcmp(const void *ap, const void *bp);
58 int intpcmp(const void *ap, const void *bp);
59 int myrand(void);
60 int dosort(int rnum, int disp);
61 int dostrstr(int rnum, int disp);
62 int dolist(int rnum, int disp);
63 int domap(int rnum, int bnum, int disp);
64 int doheap(int rnum, int max, int disp);
65 int dowicked(int rnum);
66 int domisc(void);
67
68
69 /* main routine */
main(int argc,char ** argv)70 int main(int argc, char **argv){
71 int rv;
72 cbstdiobin();
73 progname = argv[0];
74 if(argc < 2) usage();
75 rv = 0;
76 if(!strcmp(argv[1], "sort")){
77 rv = runsort(argc, argv);
78 } else if(!strcmp(argv[1], "strstr")){
79 rv = runstrstr(argc, argv);
80 } else if(!strcmp(argv[1], "list")){
81 rv = runlist(argc, argv);
82 } else if(!strcmp(argv[1], "map")){
83 rv = runmap(argc, argv);
84 } else if(!strcmp(argv[1], "heap")){
85 rv = runheap(argc, argv);
86 } else if(!strcmp(argv[1], "wicked")){
87 rv = runwicked(argc, argv);
88 } else if(!strcmp(argv[1], "misc")){
89 rv = runmisc(argc, argv);
90 } else {
91 usage();
92 }
93 return rv;
94 }
95
96
97 /* print the usage and exit */
usage(void)98 void usage(void){
99 fprintf(stderr, "%s: test cases for Cabin\n", progname);
100 fprintf(stderr, "\n");
101 fprintf(stderr, "usage:\n");
102 fprintf(stderr, " %s sort [-d] rnum\n", progname);
103 fprintf(stderr, " %s strstr [-d] rnum\n", progname);
104 fprintf(stderr, " %s list [-d] rnum\n", progname);
105 fprintf(stderr, " %s map [-d] rnum [bnum]\n", progname);
106 fprintf(stderr, " %s heap [-d] rnum [top]\n", progname);
107 fprintf(stderr, " %s wicked rnum\n", progname);
108 fprintf(stderr, " %s misc\n", progname);
109 fprintf(stderr, "\n");
110 exit(1);
111 }
112
113
114 /* parse arguments of sort command */
runsort(int argc,char ** argv)115 int runsort(int argc, char **argv){
116 int i, rnum, disp, rv;
117 char *rstr;
118 rstr = NULL;
119 rnum = 0;
120 disp = FALSE;
121 for(i = 2; i < argc; i++){
122 if(argv[i][0] == '-'){
123 if(!strcmp(argv[i], "-d")){
124 disp = TRUE;
125 } else {
126 usage();
127 }
128 } else if(!rstr){
129 rstr = argv[i];
130 } else {
131 usage();
132 }
133 }
134 if(!rstr) usage();
135 rnum = atoi(rstr);
136 if(rnum < 1) usage();
137 rv = dosort(rnum, disp);
138 return rv;
139 }
140
141
142 /* parse arguments of strstr command */
runstrstr(int argc,char ** argv)143 int runstrstr(int argc, char **argv){
144 int i, rnum, disp, rv;
145 char *rstr;
146 rstr = NULL;
147 rnum = 0;
148 disp = FALSE;
149 for(i = 2; i < argc; i++){
150 if(argv[i][0] == '-'){
151 if(!strcmp(argv[i], "-d")){
152 disp = TRUE;
153 } else {
154 usage();
155 }
156 } else if(!rstr){
157 rstr = argv[i];
158 } else {
159 usage();
160 }
161 }
162 if(!rstr) usage();
163 rnum = atoi(rstr);
164 if(rnum < 1) usage();
165 rv = dostrstr(rnum, disp);
166 return rv;
167 }
168
169
170 /* parse arguments of list command */
runlist(int argc,char ** argv)171 int runlist(int argc, char **argv){
172 int i, rnum, disp, rv;
173 char *rstr;
174 rstr = NULL;
175 rnum = 0;
176 disp = FALSE;
177 for(i = 2; i < argc; i++){
178 if(argv[i][0] == '-'){
179 if(!strcmp(argv[i], "-d")){
180 disp = TRUE;
181 } else {
182 usage();
183 }
184 } else if(!rstr){
185 rstr = argv[i];
186 } else {
187 usage();
188 }
189 }
190 if(!rstr) usage();
191 rnum = atoi(rstr);
192 if(rnum < 1) usage();
193 rv = dolist(rnum, disp);
194 return rv;
195 }
196
197
198 /* parse arguments of map command */
runmap(int argc,char ** argv)199 int runmap(int argc, char **argv){
200 int i, rnum, bnum, disp, rv;
201 char *rstr, *bstr;
202 rstr = NULL;
203 bstr = NULL;
204 rnum = 0;
205 bnum = -1;
206 disp = FALSE;
207 for(i = 2; i < argc; i++){
208 if(argv[i][0] == '-'){
209 if(!strcmp(argv[i], "-d")){
210 disp = TRUE;
211 } else {
212 usage();
213 }
214 } else if(!rstr){
215 rstr = argv[i];
216 } else if(!bstr){
217 bstr = argv[i];
218 } else {
219 usage();
220 }
221 }
222 if(!rstr) usage();
223 rnum = atoi(rstr);
224 if(rnum < 1) usage();
225 if(bstr) bnum = atoi(bstr);
226 rv = domap(rnum, bnum, disp);
227 return rv;
228 }
229
230
231 /* parse arguments of heap command */
runheap(int argc,char ** argv)232 int runheap(int argc, char **argv){
233 int i, rnum, max, disp, rv;
234 char *rstr, *mstr;
235 rstr = NULL;
236 mstr = NULL;
237 rnum = 0;
238 max = -1;
239 disp = FALSE;
240 for(i = 2; i < argc; i++){
241 if(argv[i][0] == '-'){
242 if(!strcmp(argv[i], "-d")){
243 disp = TRUE;
244 } else {
245 usage();
246 }
247 } else if(!rstr){
248 rstr = argv[i];
249 } else if(!mstr){
250 mstr = argv[i];
251 } else {
252 usage();
253 }
254 }
255 if(!rstr) usage();
256 rnum = atoi(rstr);
257 if(rnum < 1) usage();
258 if(mstr) max = atoi(mstr);
259 if(max < 0) max = rnum;
260 rv = doheap(rnum, max, disp);
261 rv = 0;
262 return rv;
263 }
264
265
266 /* parse arguments of wicked command */
runwicked(int argc,char ** argv)267 int runwicked(int argc, char **argv){
268 int i, rnum, rv;
269 char *rstr;
270 rstr = NULL;
271 rnum = 0;
272 for(i = 2; i < argc; i++){
273 if(argv[i][0] == '-'){
274 usage();
275 } else if(!rstr){
276 rstr = argv[i];
277 } else {
278 usage();
279 }
280 }
281 if(!rstr) usage();
282 rnum = atoi(rstr);
283 if(rnum < 1) usage();
284 rv = dowicked(rnum);
285 return rv;
286 }
287
288
289 /* parse arguments of misc command */
runmisc(int argc,char ** argv)290 int runmisc(int argc, char **argv){
291 int rv;
292 rv = domisc();
293 return rv;
294 }
295
296
297 /* print formatted string and flush the buffer */
printfflush(const char * format,...)298 int printfflush(const char *format, ...){
299 va_list ap;
300 int rv;
301 va_start(ap, format);
302 rv = vprintf(format, ap);
303 if(fflush(stdout) == EOF) rv = -1;
304 va_end(ap);
305 return rv;
306 }
307
308
309 /* comparing function for strings */
strpcmp(const void * ap,const void * bp)310 int strpcmp(const void *ap, const void *bp){
311 return strcmp(*(char **)ap, *(char **)bp);
312 }
313
314
315 /* comparing function for integers */
intpcmp(const void * ap,const void * bp)316 int intpcmp(const void *ap, const void *bp){
317 return *(int *)ap - *(int *)bp;
318 }
319
320
321 /* pseudo random number generator */
myrand(void)322 int myrand(void){
323 static int cnt = 0;
324 if(cnt == 0) srand(time(NULL));
325 return (rand() * rand() + (rand() >> (sizeof(int) * 4)) + (cnt++)) & INT_MAX;
326 }
327
328
329 /* perform sort command */
dosort(int rnum,int disp)330 int dosort(int rnum, int disp){
331 char **ivector1, **ivector2, **ivector3, **ivector4, **ivector5;
332 char buf[RECBUFSIZ];
333 int i, len, err;
334 if(!disp) printfflush("<Sorting Test>\n rnum=%d\n\n", rnum);
335 ivector1 = cbmalloc(rnum * sizeof(ivector1[0]));
336 ivector2 = cbmalloc(rnum * sizeof(ivector2[0]));
337 ivector3 = cbmalloc(rnum * sizeof(ivector3[0]));
338 ivector4 = cbmalloc(rnum * sizeof(ivector4[0]));
339 ivector5 = cbmalloc(rnum * sizeof(ivector5[0]));
340 err = FALSE;
341 for(i = 0; i < rnum; i++){
342 len = sprintf(buf, "%08d", myrand() % rnum + 1);
343 ivector1[i] = cbmemdup(buf, len);
344 ivector2[i] = cbmemdup(buf, len);
345 ivector3[i] = cbmemdup(buf, len);
346 ivector4[i] = cbmemdup(buf, len);
347 ivector5[i] = cbmemdup(buf, len);
348 }
349 if(!disp) printfflush("Sorting with insert sort ... ");
350 cbisort(ivector1, rnum, sizeof(ivector1[0]), strpcmp);
351 if(!disp) printfflush("ok\n");
352 if(!disp) printfflush("Sorting with shell sort ... ");
353 cbssort(ivector2, rnum, sizeof(ivector2[0]), strpcmp);
354 if(!disp) printfflush("ok\n");
355 if(!disp) printfflush("Sorting with heap sort ... ");
356 cbhsort(ivector3, rnum, sizeof(ivector3[0]), strpcmp);
357 if(!disp) printfflush("ok\n");
358 if(!disp) printfflush("Sorting with quick sort ... ");
359 cbqsort(ivector4, rnum, sizeof(ivector4[0]), strpcmp);
360 if(!disp) printfflush("ok\n");
361 for(i = 0; i < rnum; i++){
362 if(disp) printfflush("%s\t%s\t%s\t%s\t[%s]\n",
363 ivector1[i], ivector2[i], ivector3[i], ivector4[i], ivector5[i]);
364 if(strcmp(ivector1[i], ivector2[i])) err = TRUE;
365 if(strcmp(ivector1[i], ivector3[i])) err = TRUE;
366 if(strcmp(ivector1[i], ivector4[i])) err = TRUE;
367 free(ivector1[i]);
368 free(ivector2[i]);
369 free(ivector3[i]);
370 free(ivector4[i]);
371 free(ivector5[i]);
372 }
373 free(ivector1);
374 free(ivector2);
375 free(ivector3);
376 free(ivector4);
377 free(ivector5);
378 if(err) fprintf(stderr, "%s: sorting failed\n", progname);
379 if(!disp && !err) printfflush("all ok\n\n");
380 return err ? 1 : 0;
381 }
382
383
384 /* perform strstr command */
dostrstr(int rnum,int disp)385 int dostrstr(int rnum, int disp){
386 char *text, buf[RECBUFSIZ], *std, *kmp, *bm;
387 int i, j, len, err;
388 text = cbmalloc(TEXTBUFSIZ);
389 for(i = 0; i < TEXTBUFSIZ - 1; i++){
390 text[i] = 'a' + myrand() % ('z' - 'a');
391 }
392 text[i] = '\0';
393 err = FALSE;
394 if(!disp) printfflush("Locating substrings ... ");
395 for(i = 0; i < rnum; i++){
396 len = myrand() % (RECBUFSIZ - 1);
397 for(j = 0; j < len; j++){
398 buf[j] = 'a' + myrand() % ('z' - 'a');
399 }
400 buf[j] = 0;
401 std = strstr(text, buf);
402 kmp = cbstrstrkmp(text, buf);
403 bm = cbstrstrbm(text, buf);
404 if(kmp != std || bm != std){
405 err = TRUE;
406 break;
407 }
408 if(disp && std) printf("%s\n", buf);
409 }
410 if(err) fprintf(stderr, "%s: string scanning failed\n", progname);
411 if(!disp && !err){
412 printfflush("ok\n");
413 printfflush("all ok\n\n");
414 }
415 free(text);
416 return err ? 1 : 0;
417 }
418
419
420 /* perform list command */
dolist(int rnum,int disp)421 int dolist(int rnum, int disp){
422 CBLIST *list;
423 const char *vbuf;
424 char buf[RECBUFSIZ], *tmp;
425 int i, err, len, vsiz;
426 if(!disp) printfflush("<List Writing Test>\n rnum=%d\n\n", rnum);
427 list = cblistopen();
428 err = FALSE;
429 for(i = 1; i <= rnum; i++){
430 len = sprintf(buf, "%08d", i);
431 cblistpush(list, buf, len);
432 if(!disp && rnum > 250 && i % (rnum / 250) == 0){
433 putchar('.');
434 fflush(stdout);
435 if(i == rnum || i % (rnum / 10) == 0){
436 printfflush(" (%08d)\n", i);
437 }
438 }
439 }
440 if(disp){
441 for(i = 0; i < cblistnum(list); i++){
442 if((vbuf = cblistval(list, i, &vsiz)) != NULL){
443 printfflush("%s:%d\n", vbuf, vsiz);
444 } else {
445 fprintf(stderr, "%s: val error\n", progname);
446 err = TRUE;
447 break;
448 }
449 }
450 printfflush("\n");
451 while((tmp = cblistpop(list, &vsiz)) != NULL){
452 printfflush("%s:%d\n", tmp, vsiz);
453 free(tmp);
454 }
455 }
456 cblistclose(list);
457 if(!disp && !err) printfflush("ok\n\n");
458 return err ? 1 : 0;
459 }
460
461
462 /* perform list command */
domap(int rnum,int bnum,int disp)463 int domap(int rnum, int bnum, int disp){
464 CBMAP *map;
465 const char *kbuf, *vbuf;
466 char buf[RECBUFSIZ];
467 int i, err, len, ksiz, vsiz;
468 if(!disp) printfflush("<Map Writing Test>\n rnum=%d bnum=%d\n\n", rnum, bnum);
469 map = bnum > 0 ? cbmapopenex(bnum) : cbmapopen();
470 err = FALSE;
471 for(i = 1; i <= rnum; i++){
472 len = sprintf(buf, "%08d", i);
473 if(!cbmapput(map, buf, len, buf, len, FALSE)){
474 fprintf(stderr, "%s: put error\n", progname);
475 err = TRUE;
476 break;
477 }
478 if(!disp && rnum > 250 && i % (rnum / 250) == 0){
479 putchar('.');
480 fflush(stdout);
481 if(i == rnum || i % (rnum / 10) == 0){
482 printfflush(" (%08d)\n", i);
483 }
484 }
485 }
486 if(disp){
487 for(i = 1; i <= rnum; i++){
488 len = sprintf(buf, "%08d", i);
489 if((vbuf = cbmapget(map, buf, len, &vsiz)) != NULL){
490 printfflush("%s:%d\t%s:%d\n", buf, len, vbuf, vsiz);
491 } else {
492 fprintf(stderr, "%s: get error\n", progname);
493 }
494 }
495 printfflush("\n");
496 cbmapiterinit(map);
497 while((kbuf = cbmapiternext(map, &ksiz)) != NULL){
498 vbuf = cbmapiterval(kbuf, &vsiz);
499 printfflush("%s:%d\t%s:%d\n", kbuf, ksiz, vbuf, vsiz);
500 }
501 }
502 cbmapclose(map);
503 if(!disp && !err) printfflush("ok\n\n");
504 return err ? 1 : 0;
505 }
506
507
508 /* perform heap command */
doheap(int rnum,int max,int disp)509 int doheap(int rnum, int max, int disp){
510 CBHEAP *heap;
511 int *orig, *ary;
512 int i, err, num, anum;
513 if(!disp) printfflush("<Heap Writing Test>\n rnum=%d max=%d\n\n", rnum, max);
514 orig = disp ? cbmalloc(rnum * sizeof(int) + 1) : NULL;
515 heap = cbheapopen(sizeof(int), max, intpcmp);
516 err = FALSE;
517 for(i = 1; i <= rnum; i++){
518 num = myrand() % rnum + 1;
519 if(orig) orig[i-1] = num;
520 cbheapinsert(heap, &num);
521 if(!disp && rnum > 250 && i % (rnum / 250) == 0){
522 putchar('.');
523 fflush(stdout);
524 if(i == rnum || i % (rnum / 10) == 0){
525 printfflush(" (%08d)\n", i);
526 }
527 }
528 }
529 if(disp){
530 for(i = 0; i < cbheapnum(heap); i++){
531 printf("%d\n", *(int *)cbheapval(heap, i));
532 }
533 printf("\n");
534 qsort(orig, rnum, sizeof(int), intpcmp);
535 ary = (int *)cbheaptomalloc(heap, &anum);
536 if(anum != rnum && anum != max) err = TRUE;
537 for(i = 0; i < anum; i++){
538 printf("%d\t%d\n", ary[i], orig[i]);
539 if(ary[i] != orig[i]) err = TRUE;
540 }
541 free(ary);
542 } else {
543 cbheapclose(heap);
544 }
545 free(orig);
546 if(!disp && !err) printfflush("ok\n\n");
547 return err ? 1 : 0;
548 }
549
550
551 /* perform wicked command */
dowicked(int rnum)552 int dowicked(int rnum){
553 CBLIST *list;
554 CBMAP *map;
555 int i, len;
556 char buf[RECBUFSIZ], *tmp;
557 printfflush("<Wicked Writing Test>\n rnum=%d\n\n", rnum);
558 list = cblistopen();
559 for(i = 1; i <= rnum; i++){
560 len = sprintf(buf, "%d", myrand() % rnum + 1);
561 switch(myrand() % 16){
562 case 0:
563 free(cblistpop(list, NULL));
564 putchar('O');
565 break;
566 case 1:
567 cblistunshift(list, buf, len);
568 putchar('U');
569 break;
570 case 2:
571 free(cblistshift(list, NULL));
572 putchar('S');
573 break;
574 case 3:
575 cblistinsert(list, myrand() % (cblistnum(list) + 1), buf, len);
576 putchar('I');
577 break;
578 case 4:
579 free(cblistremove(list, myrand() % (cblistnum(list) + 1), NULL));
580 putchar('R');
581 break;
582 case 5:
583 cblistover(list, myrand() % (cblistnum(list) + 1), buf, len);
584 putchar('V');
585 break;
586 case 6:
587 tmp = cbmemdup(buf, len);
588 cblistpushbuf(list, tmp, len);
589 putchar('B');
590 break;
591 default:
592 cblistpush(list, buf, len);
593 putchar('P');
594 break;
595 }
596 if(i % 50 == 0) printfflush(" (%08d)\n", i);
597 }
598 cblistclose(list);
599 map = cbmapopen();
600 for(i = 1; i <= rnum; i++){
601 len = sprintf(buf, "%d", myrand() % rnum + 1);
602 switch(myrand() % 16){
603 case 0:
604 cbmapput(map, buf, len, buf, len, FALSE);
605 putchar('I');
606 break;
607 case 1:
608 cbmapputcat(map, buf, len, buf, len);
609 putchar('C');
610 break;
611 case 2:
612 cbmapget(map, buf, len, NULL);
613 putchar('V');
614 break;
615 case 3:
616 cbmapout(map, buf, len);
617 putchar('D');
618 break;
619 case 4:
620 cbmapmove(map, buf, len, myrand() % 2);
621 putchar('M');
622 break;
623 default:
624 cbmapput(map, buf, len, buf, len, TRUE);
625 putchar('O');
626 break;
627 }
628 if(i % 50 == 0) printfflush(" (%08d)\n", i);
629 }
630 cbmapclose(map);
631 printfflush("ok\n\n");
632 return 0;
633 }
634
635
636 /* perform misc command */
domisc(void)637 int domisc(void){
638 CBDATUM *odatum, *ndatum;
639 CBLIST *olist, *nlist, *elems, *glist;
640 CBMAP *omap, *nmap, *pairs, *gmap;
641 int i, j, ssiz, osiz, tsiz, jl;
642 char kbuf[RECBUFSIZ], vbuf[RECBUFSIZ], *sbuf, spbuf[1024], *tmp, *orig, renc[64];
643 const char *op, *np;
644 time_t t;
645 printfflush("<Miscellaneous Test>\n\n");
646 printfflush("Checking memory allocation ... ");
647 tmp = cbmalloc(1024);
648 for(i = 1; i <= 65536; i *= 2){
649 tmp = cbrealloc(tmp, i);
650 }
651 cbfree(tmp);
652 printfflush("ok\n");
653 printfflush("Checking basic datum ... ");
654 odatum = cbdatumopen("x", -1);
655 for(i = 0; i < 1000; i++){
656 cbdatumcat(odatum, "x", 1);
657 }
658 cbdatumclose(odatum);
659 tmp = cbmalloc(3);
660 memcpy(tmp, "abc", 3);
661 odatum = cbdatumopenbuf(tmp, 3);
662 for(i = 0; i < 1000; i++){
663 cbdatumcat(odatum, ".", 1);
664 }
665 ndatum = cbdatumdup(odatum);
666 for(i = 0; i < 1000; i++){
667 cbdatumcat(ndatum, "*", 1);
668 }
669 for(i = 0; i < 1000; i++){
670 tmp = cbmalloc(3);
671 memcpy(tmp, "123", 3);
672 cbdatumsetbuf(ndatum, tmp, 3);
673 }
674 cbdatumprintf(ndatum, "[%s\t%08d\t%08o\t%08x\t%08.1f\t%@\t%?\t%:]",
675 "mikio", 1978, 1978, 1978, 1978.0211, "<>&#!+-*/%", "<>&#!+-*/%", "<>&#!+-*/%");
676 cbdatumclose(ndatum);
677 cbdatumclose(odatum);
678 printfflush("ok\n");
679 printfflush("Checking serialization of list ... ");
680 olist = cblistopen();
681 for(i = 1; i <= 1000; i++){
682 sprintf(vbuf, "%d", i);
683 cblistpush(olist, vbuf, -1);
684 }
685 sbuf = cblistdump(olist, &ssiz);
686 nlist = cblistload(sbuf, ssiz);
687 free(sbuf);
688 for(i = 0; i < cblistnum(olist); i++){
689 op = cblistval(olist, i, NULL);
690 np = cblistval(nlist, i, NULL);
691 if(!op || !np || strcmp(op, np)){
692 cblistclose(nlist);
693 cblistclose(olist);
694 fprintf(stderr, "%s: validation failed\n", progname);
695 return 1;
696 }
697 }
698 cblistclose(nlist);
699 cblistclose(olist);
700 printfflush("ok\n");
701 printfflush("Checking serialization of map ... ");
702 omap = cbmapopen();
703 for(i = 1; i <= 1000; i++){
704 sprintf(kbuf, "%X", i);
705 sprintf(vbuf, "[%d]", i);
706 cbmapput(omap, kbuf, -1, vbuf, -1, TRUE);
707 }
708 sbuf = cbmapdump(omap, &ssiz);
709 nmap = cbmapload(sbuf, ssiz);
710 free(cbmaploadone(sbuf, ssiz, "1", 2, &tsiz));
711 free(cbmaploadone(sbuf, ssiz, "33", 2, &tsiz));
712 free(sbuf);
713 cbmapiterinit(omap);
714 while((op = cbmapiternext(omap, NULL)) != NULL){
715 if(!(np = cbmapget(nmap, op, -1, NULL))){
716 cbmapclose(nmap);
717 cbmapclose(omap);
718 fprintf(stderr, "%s: validation failed\n", progname);
719 return 1;
720 }
721 }
722 cbmapclose(nmap);
723 cbmapclose(omap);
724 printfflush("ok\n");
725 printfflush("Checking string utilities ... ");
726 sprintf(spbuf, "[%08d/%08o/%08u/%08x/%08X/%08.3e/%08.3E/%08.3f/%08.3g/%08.3G/%c/%s/%%]",
727 123456, 123456, 123456, 123456, 123456,
728 123456.789, 123456.789, 123456.789, 123456.789, 123456.789,
729 'A', "hoge");
730 tmp = cbsprintf("[%08d/%08o/%08u/%08x/%08X/%08.3e/%08.3E/%08.3f/%08.3g/%08.3G/%c/%s/%%]",
731 123456, 123456, 123456, 123456, 123456,
732 123456.789, 123456.789, 123456.789, 123456.789, 123456.789,
733 'A', "hoge");
734 while(strcmp(spbuf, tmp)){
735 free(tmp);
736 fprintf(stderr, "%s: cbsprintf is invalid\n", progname);
737 return 1;
738 }
739 free(tmp);
740 pairs = cbmapopen();
741 cbmapput(pairs, "aa", -1, "AAA", -1, TRUE);
742 cbmapput(pairs, "bb", -1, "BBB", -1, TRUE);
743 cbmapput(pairs, "cc", -1, "CCC", -1, TRUE);
744 cbmapput(pairs, "ZZZ", -1, "z", -1, TRUE);
745 tmp = cbreplace("[aaaaabbbbbcccccdddddZZZZ]", pairs);
746 if(strcmp(tmp, "[AAAAAAaBBBBBBbCCCCCCcdddddzZ]")){
747 free(tmp);
748 cbmapclose(pairs);
749 fprintf(stderr, "%s: cbreplace is invalid\n", progname);
750 return 1;
751 }
752 free(tmp);
753 cbmapclose(pairs);
754 elems = cbsplit("aa bb,ccc-dd,", -1, " ,-");
755 if(cblistnum(elems) != 5 || strcmp(cblistval(elems, 0, NULL), "aa") ||
756 strcmp(cblistval(elems, 1, NULL), "bb") || strcmp(cblistval(elems, 2, NULL), "ccc") ||
757 strcmp(cblistval(elems, 3, NULL), "dd") || strcmp(cblistval(elems, 4, NULL), "")){
758 cblistclose(elems);
759 fprintf(stderr, "%s: cbsplit is invalid\n", progname);
760 return 1;
761 }
762 cblistclose(elems);
763 if(cbstricmp("abc", "ABC") || !cbstricmp("abc", "abcd")){
764 fprintf(stderr, "%s: cbstricmp is invalid\n", progname);
765 return 1;
766 }
767 if(!cbstrfwmatch("abcd", "abc") || cbstrfwmatch("abc", "abcd")){
768 fprintf(stderr, "%s: cbstrfwmatch is invalid\n", progname);
769 return 1;
770 }
771 if(!cbstrfwimatch("abcd", "ABC") || cbstrfwmatch("abc", "ABCD")){
772 fprintf(stderr, "%s: cbstrfwimatch is invalid\n", progname);
773 return 1;
774 }
775 if(!cbstrbwmatch("dcba", "cba") || cbstrbwmatch("cba", "dcba")){
776 fprintf(stderr, "%s: cbstrbwmatch is invalid\n", progname);
777 return 1;
778 }
779 if(!cbstrbwimatch("dcba", "CBA") || cbstrbwimatch("cba", "DCBA")){
780 fprintf(stderr, "%s: cbstrbwimatch is invalid\n", progname);
781 return 1;
782 }
783 tmp = cbmemdup(" \r\n[Quick Database Manager]\r\n ", -1);
784 if(cbstrtoupper(tmp) != tmp || strcmp(tmp, " \r\n[QUICK DATABASE MANAGER]\r\n ")){
785 free(tmp);
786 fprintf(stderr, "%s: cbstrtoupper is invalid\n", progname);
787 return 1;
788 }
789 if(cbstrtolower(tmp) != tmp || strcmp(tmp, " \r\n[quick database manager]\r\n ")){
790 free(tmp);
791 fprintf(stderr, "%s: cbstrtolower is invalid\n", progname);
792 return 1;
793 }
794 if(cbstrtrim(tmp) != tmp || strcmp(tmp, "[quick database manager]")){
795 free(tmp);
796 fprintf(stderr, "%s: cbstrtrim is invalid\n", progname);
797 return 1;
798 }
799 if(cbstrsqzspc(tmp) != tmp || strcmp(tmp, "[quick database manager]")){
800 free(tmp);
801 fprintf(stderr, "%s: cbstrsqzspc is invalid\n", progname);
802 return 1;
803 }
804 cbstrcututf(tmp, 5);
805 if(cbstrcountutf(tmp) != 5){
806 free(tmp);
807 fprintf(stderr, "%s: cbstrcututf or cbstrcountutf is invalid\n", progname);
808 return 1;
809 }
810 free(tmp);
811 printfflush("ok\n");
812 printfflush("Checking encoding utilities ... ");
813 strcpy(spbuf, "My name is \xca\xbf\xce\xd3\xb4\xb4\xcd\xba.\n\n<Love & Peace!>\n");
814 tmp = cbbaseencode(spbuf, -1);
815 orig = cbbasedecode(tmp, &osiz);
816 if(osiz != strlen(spbuf) || strcmp(orig, spbuf)){
817 free(orig);
818 free(tmp);
819 fprintf(stderr, "%s: Base64 encoding is invalid\n", progname);
820 return 1;
821 }
822 free(orig);
823 free(tmp);
824 strcpy(spbuf, "My name is \xca\xbf\xce\xd3\xb4\xb4\xcd\xba.\n\n<Love & Peace!>\n");
825 tmp = cbquoteencode(spbuf, -1);
826 orig = cbquotedecode(tmp, &osiz);
827 if(osiz != strlen(spbuf) || strcmp(orig, spbuf)){
828 free(orig);
829 free(tmp);
830 fprintf(stderr, "%s: quoted-printable encoding is invalid\n", progname);
831 return 1;
832 }
833 free(orig);
834 free(tmp);
835 strcpy(spbuf, "My name is \xca\xbf\xce\xd3\xb4\xb4\xcd\xba.\n\n<Love & Peace!>\n");
836 tmp = cbmimeencode(spbuf, "ISO-8859-1", TRUE);
837 orig = cbmimedecode(tmp, renc);
838 if(osiz != strlen(spbuf) || strcmp(orig, spbuf) || strcmp(renc, "ISO-8859-1")){
839 free(orig);
840 free(tmp);
841 fprintf(stderr, "%s: MIME encoding is invalid\n", progname);
842 return 1;
843 }
844 free(orig);
845 free(tmp);
846 strcpy(spbuf, "\"He says...\r\n\"\"What PROGRAM are they watching?\"\"\"");
847 tmp = cbcsvunescape(spbuf);
848 orig = cbcsvescape(tmp);
849 if(strcmp(orig, spbuf)){
850 free(orig);
851 free(tmp);
852 fprintf(stderr, "%s: CSV escaping is invalid\n", progname);
853 return 1;
854 }
855 free(orig);
856 free(tmp);
857 strcpy(spbuf, "<Nuts&Milk> is "very" surfin'!");
858 tmp = cbxmlunescape(spbuf);
859 orig = cbxmlescape(tmp);
860 if(strcmp(orig, spbuf)){
861 free(orig);
862 free(tmp);
863 fprintf(stderr, "%s: XML escaping is invalid\n", progname);
864 return 1;
865 }
866 free(orig);
867 free(tmp);
868 printfflush("ok\n");
869 printfflush("Checking date utilities ... ");
870 for(i = 0; i < 200; i++){
871 jl = (myrand() % 23) * 1800;
872 if(myrand() % 2 == 0) jl *= -1;
873 t = myrand() % (INT_MAX - 3600 * 24 * 365 * 6) + 3600 * 24 * 365 * 5;
874 tmp = cbdatestrwww(t, jl);
875 t = cbstrmktime(tmp);
876 orig = cbdatestrwww(t, jl);
877 if(strcmp(orig, tmp)){
878 free(orig);
879 free(tmp);
880 fprintf(stderr, "%s: W3CDTF formatter is invalid\n", progname);
881 return 1;
882 }
883 free(orig);
884 free(tmp);
885 tmp = cbdatestrhttp(t, jl);
886 t = cbstrmktime(tmp);
887 orig = cbdatestrhttp(t, jl);
888 if(strcmp(orig, tmp)){
889 free(orig);
890 free(tmp);
891 fprintf(stderr, "%s: RFC 822 date formatter is invalid\n", progname);
892 return 1;
893 }
894 free(orig);
895 free(tmp);
896 }
897 printfflush("ok\n");
898 printfflush("Checking the global garbage collector ... ");
899 for(i = 0; i < 512; i++){
900 glist = cblistopen();
901 cbglobalgc(glist, (void (*)(void *))cblistclose);
902 for(j = 0; j < 10; j++){
903 sprintf(kbuf, "%08d", j);
904 cblistpush(glist, kbuf, -1);
905 }
906 gmap = cbmapopen();
907 cbglobalgc(gmap, (void (*)(void *))cbmapclose);
908 for(j = 0; j < 10; j++){
909 sprintf(kbuf, "%08d", j);
910 cbmapput(gmap, kbuf, -1, kbuf, -1, TRUE);
911 }
912 if(myrand() % 64 == 0){
913 cbvmemavail(100);
914 cbggcsweep();
915 }
916 }
917 printfflush("ok\n");
918 printfflush("all ok\n\n");
919 return 0;
920 }
921
922
923
924 /* END OF FILE */
925