]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/tokyocabinet/tcutest.c
ebl Add tokyocabinet source to bacula
[bacula/bacula] / bacula / src / lib / tokyocabinet / tcutest.c
1 /*************************************************************************************************
2  * The test cases of the utility API
3  *                                                      Copyright (C) 2006-2008 Mikio Hirabayashi
4  * This file is part of Tokyo Cabinet.
5  * Tokyo Cabinet is free software; you can redistribute it and/or modify it under the terms of
6  * the GNU Lesser General Public License as published by the Free Software Foundation; either
7  * version 2.1 of the License or any later version.  Tokyo Cabinet is distributed in the hope
8  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
10  * License for more details.
11  * You should have received a copy of the GNU Lesser General Public License along with Tokyo
12  * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
13  * Boston, MA 02111-1307 USA.
14  *************************************************************************************************/
15
16
17 #include <tcutil.h>
18 #include "myconf.h"
19
20 #define RECBUFSIZ      32                // buffer for records
21
22
23 /* global variables */
24 const char *g_progname;                  // program name
25
26
27 /* function prototypes */
28 int main(int argc, char **argv);
29 static void usage(void);
30 static void iprintf(const char *format, ...);
31 static int myrand(int range);
32 static int runxstr(int argc, char **argv);
33 static int runlist(int argc, char **argv);
34 static int runmap(int argc, char **argv);
35 static int runmdb(int argc, char **argv);
36 static int runmisc(int argc, char **argv);
37 static int runwicked(int argc, char **argv);
38 static int procxstr(int rnum);
39 static int proclist(int rnum, int anum);
40 static int procmap(int rnum, int bnum);
41 static int procmdb(int rnum, int bnum);
42 static int procmisc(int rnum);
43 static int procwicked(int rnum);
44
45
46 /* main routine */
47 int main(int argc, char **argv){
48   g_progname = argv[0];
49   srand((unsigned int)(tctime() * 1000) % UINT_MAX);
50   if(argc < 2) usage();
51   int rv = 0;
52   if(!strcmp(argv[1], "xstr")){
53     rv = runxstr(argc, argv);
54   } else if(!strcmp(argv[1], "list")){
55     rv = runlist(argc, argv);
56   } else if(!strcmp(argv[1], "map")){
57     rv = runmap(argc, argv);
58   } else if(!strcmp(argv[1], "mdb")){
59     rv = runmdb(argc, argv);
60   } else if(!strcmp(argv[1], "misc")){
61     rv = runmisc(argc, argv);
62   } else if(!strcmp(argv[1], "wicked")){
63     rv = runwicked(argc, argv);
64   } else {
65     usage();
66   }
67   return rv;
68 }
69
70
71 /* print the usage and exit */
72 static void usage(void){
73   fprintf(stderr, "%s: test cases of the utility API of Tokyo Cabinet\n", g_progname);
74   fprintf(stderr, "\n");
75   fprintf(stderr, "usage:\n");
76   fprintf(stderr, "  %s xstr rnum\n", g_progname);
77   fprintf(stderr, "  %s list rnum [anum]\n", g_progname);
78   fprintf(stderr, "  %s map rnum [bnum]\n", g_progname);
79   fprintf(stderr, "  %s mdb rnum [bnum]\n", g_progname);
80   fprintf(stderr, "  %s misc rnum\n", g_progname);
81   fprintf(stderr, "  %s wicked rnum\n", g_progname);
82   fprintf(stderr, "\n");
83   exit(1);
84 }
85
86
87 /* print formatted information string and flush the buffer */
88 static void iprintf(const char *format, ...){
89   va_list ap;
90   va_start(ap, format);
91   vprintf(format, ap);
92   fflush(stdout);
93   va_end(ap);
94 }
95
96
97 /* get a random number */
98 static int myrand(int range){
99   return (int)((double)range * rand() / (RAND_MAX + 1.0));
100 }
101
102
103 /* parse arguments of xstr command */
104 static int runxstr(int argc, char **argv){
105   char *rstr = NULL;
106   for(int i = 2; i < argc; i++){
107     if(!rstr && argv[i][0] == '-'){
108       usage();
109     } else if(!rstr){
110       rstr = argv[i];
111     } else {
112       usage();
113     }
114   }
115   if(!rstr) usage();
116   int rnum = atoi(rstr);
117   if(rnum < 1) usage();
118   int rv = procxstr(rnum);
119   return rv;
120 }
121
122
123 /* parse arguments of list command */
124 static int runlist(int argc, char **argv){
125   char *rstr = NULL;
126   char *astr = NULL;
127   for(int i = 2; i < argc; i++){
128     if(!rstr && argv[i][0] == '-'){
129       usage();
130     } else if(!rstr){
131       rstr = argv[i];
132     } else if(!astr){
133       astr = argv[i];
134     } else {
135       usage();
136     }
137   }
138   if(!rstr) usage();
139   int rnum = atoi(rstr);
140   if(rnum < 1) usage();
141   int anum = astr ? atoi(astr) : -1;
142   int rv = proclist(rnum, anum);
143   return rv;
144 }
145
146
147 /* parse arguments of map command */
148 static int runmap(int argc, char **argv){
149   char *rstr = NULL;
150   char *bstr = NULL;
151   for(int i = 2; i < argc; i++){
152     if(!rstr && argv[i][0] == '-'){
153       usage();
154     } else if(!rstr){
155       rstr = argv[i];
156     } else if(!bstr){
157       bstr = argv[i];
158     } else {
159       usage();
160     }
161   }
162   if(!rstr) usage();
163   int rnum = atoi(rstr);
164   if(rnum < 1) usage();
165   int bnum = bstr ? atoi(bstr) : -1;
166   int rv = procmap(rnum, bnum);
167   return rv;
168 }
169
170
171 /* parse arguments of mdb command */
172 static int runmdb(int argc, char **argv){
173   char *rstr = NULL;
174   char *bstr = NULL;
175   for(int i = 2; i < argc; i++){
176     if(!rstr && argv[i][0] == '-'){
177       usage();
178     } else if(!rstr){
179       rstr = argv[i];
180     } else if(!bstr){
181       bstr = argv[i];
182     } else {
183       usage();
184     }
185   }
186   if(!rstr) usage();
187   int rnum = atoi(rstr);
188   if(rnum < 1) usage();
189   int bnum = bstr ? atoi(bstr) : -1;
190   int rv = procmdb(rnum, bnum);
191   return rv;
192 }
193
194
195 /* parse arguments of misc command */
196 static int runmisc(int argc, char **argv){
197   char *rstr = NULL;
198   for(int i = 2; i < argc; i++){
199     if(!rstr && argv[i][0] == '-'){
200       usage();
201     } else if(!rstr){
202       rstr = argv[i];
203     } else {
204       usage();
205     }
206   }
207   if(!rstr) usage();
208   int rnum = atoi(rstr);
209   if(rnum < 1) usage();
210   int rv = procmisc(rnum);
211   return rv;
212 }
213
214
215 /* parse arguments of wicked command */
216 static int runwicked(int argc, char **argv){
217   char *rstr = NULL;
218   for(int i = 2; i < argc; i++){
219     if(!rstr && argv[i][0] == '-'){
220       usage();
221     } else if(!rstr){
222       rstr = argv[i];
223     } else {
224       usage();
225     }
226   }
227   if(!rstr) usage();
228   int rnum = atoi(rstr);
229   if(rnum < 1) usage();
230   int rv = procwicked(rnum);
231   return rv;
232 }
233
234
235 /* perform xstr command */
236 static int procxstr(int rnum){
237   iprintf("<Extensible String Writing Test>\n  rnum=%d\n\n", rnum);
238   double stime = tctime();
239   TCXSTR *xstr = tcxstrnew();
240   for(int i = 1; i <= rnum; i++){
241     char buf[RECBUFSIZ];
242     int len = sprintf(buf, "%08d", i);
243     tcxstrcat(xstr, buf, len);
244     if(rnum > 250 && i % (rnum / 250) == 0){
245       putchar('.');
246       fflush(stdout);
247       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
248     }
249   }
250   tcxstrdel(xstr);
251   iprintf("time: %.3f\n", tctime() - stime);
252   iprintf("ok\n\n");
253   return 0;
254 }
255
256
257 /* perform list command */
258 static int proclist(int rnum, int anum){
259   iprintf("<List Writing Test>\n  rnum=%d  anum=%d\n\n", rnum, anum);
260   double stime = tctime();
261   TCLIST *list = (anum > 0) ? tclistnew2(anum) : tclistnew();
262   for(int i = 1; i <= rnum; i++){
263     char buf[RECBUFSIZ];
264     int len = sprintf(buf, "%08d", i);
265     tclistpush(list, buf, len);
266     if(rnum > 250 && i % (rnum / 250) == 0){
267       putchar('.');
268       fflush(stdout);
269       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
270     }
271   }
272   tclistdel(list);
273   iprintf("time: %.3f\n", tctime() - stime);
274   iprintf("ok\n\n");
275   return 0;
276 }
277
278
279 /* perform map command */
280 static int procmap(int rnum, int bnum){
281   iprintf("<Map Writing Test>\n  rnum=%d\n\n", rnum);
282   double stime = tctime();
283   TCMAP *map = (bnum > 0) ? tcmapnew2(bnum) : tcmapnew();
284   for(int i = 1; i <= rnum; i++){
285     char buf[RECBUFSIZ];
286     int len = sprintf(buf, "%08d", i);
287     tcmapput(map, buf, len, buf, len);
288     if(rnum > 250 && i % (rnum / 250) == 0){
289       putchar('.');
290       fflush(stdout);
291       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
292     }
293   }
294   tcmapdel(map);
295   iprintf("time: %.3f\n", tctime() - stime);
296   iprintf("ok\n\n");
297   return 0;
298 }
299
300
301 /* perform mdb command */
302 static int procmdb(int rnum, int bnum){
303   iprintf("<On-memory Database Writing Test>\n  rnum=%d\n\n", rnum);
304   double stime = tctime();
305   TCMDB *mdb = (bnum > 0) ? tcmdbnew2(bnum) : tcmdbnew();
306   for(int i = 1; i <= rnum; i++){
307     char buf[RECBUFSIZ];
308     int len = sprintf(buf, "%08d", i);
309     tcmdbput(mdb, buf, len, buf, len);
310     if(rnum > 250 && i % (rnum / 250) == 0){
311       putchar('.');
312       fflush(stdout);
313       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
314     }
315   }
316   iprintf("record number: %llu\n", (unsigned long long)tcmdbrnum(mdb));
317   iprintf("size: %llu\n", (unsigned long long)tcmdbmsiz(mdb));
318   tcmdbdel(mdb);
319   iprintf("time: %.3f\n", tctime() - stime);
320   iprintf("ok\n\n");
321   return 0;
322 }
323
324
325 /* perform misc command */
326 static int procmisc(int rnum){
327   iprintf("<Miscellaneous Test>\n  rnum=%d\n\n", rnum);
328   double stime = tctime();
329   bool err = false;
330   for(int i = 1; i <= rnum && !err; i++){
331     const char *str = "5%2+3-1=4 \"Yes/No\" <a&b>";
332     int slen = strlen(str);
333     char *buf, *dec;
334     int bsiz, dsiz, jl;
335     time_t date, ddate;
336     TCXSTR *xstr;
337     TCLIST *list;
338     TCMAP *map;
339     buf = tcmemdup(str, slen);
340     xstr = tcxstrfrommalloc(buf, slen);
341     buf = tcxstrtomalloc(xstr);
342     if(strcmp(buf, str)) err = true;
343     free(buf);
344     if(tclmax(1, 2) != 2) err = true;
345     if(tclmin(1, 2) != 1) err = true;
346     tclrand();
347     if(tcdrand() >= 1.0) err = true;
348     tcdrandnd(50, 10);
349     if(tcstricmp("abc", "ABC") != 0) err = true;
350     if(!tcstrfwm("abc", "ab") || !tcstrifwm("abc", "AB")) err = true;
351     if(!tcstrbwm("abc", "bc") || !tcstribwm("abc", "BC")) err = true;
352     if(tcstrdist("abcde", "abdfgh") != 4 || tcstrdist("abdfgh", "abcde") != 4) err = true;
353     if(tcstrdistutf("abcde", "abdfgh") != 4 || tcstrdistutf("abdfgh", "abcde") != 4) err = true;
354     buf = tcmemdup("abcde", 5);
355     tcstrtoupper(buf);
356     if(strcmp(buf, "ABCDE")) err = true;
357     tcstrtolower(buf);
358     if(strcmp(buf, "abcde")) err = true;
359     free(buf);
360     buf = tcmemdup("  ab  cd  ", 10);
361     tcstrtrim(buf);
362     if(strcmp(buf, "ab  cd")) err = true;
363     tcstrsqzspc(buf);
364     if(strcmp(buf, "ab cd")) err = true;
365     tcstrsubchr(buf, "cd", "C");
366     if(strcmp(buf, "ab C")) err = true;
367     if(tcstrcntutf(buf) != 4) err = true;
368     tcstrcututf(buf, 2);
369     if(strcmp(buf, "ab")) err = true;
370     free(buf);
371     if(i % 10 == 1){
372       int anum = myrand(30);
373       uint16_t ary[anum+1];
374       for(int j = 0; j < anum; j++){
375         ary[j] = myrand(65535) + 1;
376       }
377       char ustr[anum*3+1];
378       tcstrucstoutf(ary, anum, ustr);
379       uint16_t dary[anum+1];
380       int danum;
381       tcstrutftoucs(ustr, dary, &danum);
382       if(danum != anum){
383         err = true;
384       } else {
385         for(int j = 0; j < danum; j++){
386           if(dary[j] != dary[j]) err = true;
387         }
388       }
389       list = tcstrsplit(",a,b..c,d,", ",.");
390       if(tclistnum(list) != 7) err = true;
391       buf = tcstrjoin(list, ':');
392       if(strcmp(buf, ":a:b::c:d:")) err = true;
393       free(buf);
394       tclistdel(list);
395       if(!tcregexmatch("ABCDEFGHI", "*(b)c[d-f]*g(h)")) err = true;
396       buf = tcregexreplace("ABCDEFGHI", "*(b)c[d-f]*g(h)", "[\\1][\\2][&]");
397       if(strcmp(buf, "A[B][H][BCDEFGH]I")) err = true;
398       free(buf);
399     }
400     buf = tcmalloc(48);
401     date = myrand(INT_MAX - 1000000);
402     jl = 3600 * (myrand(23) - 11);
403     tcdatestrwww(date, jl, buf);
404     ddate = tcstrmktime(buf);
405     if(ddate != date) err = true;
406     tcdatestrhttp(date, jl, buf);
407     ddate = tcstrmktime(buf);
408     if(ddate != date) err = true;
409     free(buf);
410     if(i % 100){
411       map = tcmapnew();
412       for(int j = 0; j < 10; j++){
413         char kbuf[RECBUFSIZ];
414         int ksiz = sprintf(kbuf, "%d", myrand(10));
415         tcmapaddint(map, kbuf, ksiz, 1);
416         const char *vbuf = tcmapget2(map, kbuf);
417         if(*(int *)vbuf < 1) err = true;
418       }
419       tcmapdel(map);
420     }
421     buf = tcurlencode(str, slen);
422     if(strcmp(buf, "5%252%2B3-1%3D4%20%22Yes%2FNo%22%20%3Ca%26b%3E")) err = true;
423     dec = tcurldecode(buf, &dsiz);
424     if(dsiz != slen || strcmp(dec, str)) err = true;
425     free(dec);
426     free(buf);
427     if(i % 10 == 1){
428       map = tcurlbreak("http://mikio:oikim@estraier.net:1978/foo/bar/baz.cgi?ab=cd&ef=jkl#quux");
429       const char *elem;
430       if(!(elem = tcmapget2(map, "self")) ||
431          strcmp(elem, "http://mikio:oikim@estraier.net:1978/foo/bar/baz.cgi?ab=cd&ef=jkl#quux"))
432         err = true;
433       if(!(elem = tcmapget2(map, "scheme")) || strcmp(elem, "http")) err = true;
434       if(!(elem = tcmapget2(map, "host")) || strcmp(elem, "estraier.net")) err = true;
435       if(!(elem = tcmapget2(map, "port")) || strcmp(elem, "1978")) err = true;
436       if(!(elem = tcmapget2(map, "authority")) || strcmp(elem, "mikio:oikim")) err = true;
437       if(!(elem = tcmapget2(map, "path")) || strcmp(elem, "/foo/bar/baz.cgi")) err = true;
438       if(!(elem = tcmapget2(map, "file")) || strcmp(elem, "baz.cgi")) err = true;
439       if(!(elem = tcmapget2(map, "query")) || strcmp(elem, "ab=cd&ef=jkl")) err = true;
440       if(!(elem = tcmapget2(map, "fragment")) || strcmp(elem, "quux")) err = true;
441       tcmapdel(map);
442       buf = tcurlresolve("http://a:b@c.d:1/e/f/g.h?i=j#k", "http://A:B@C.D:1/E/F/G.H?I=J#K");
443       if(strcmp(buf, "http://A:B@c.d:1/E/F/G.H?I=J#K")) err = true;
444       free(buf);
445       buf = tcurlresolve("http://a:b@c.d:1/e/f/g.h?i=j#k", "/E/F/G.H?I=J#K");
446       if(strcmp(buf, "http://a:b@c.d:1/E/F/G.H?I=J#K")) err = true;
447       free(buf);
448       buf = tcurlresolve("http://a:b@c.d:1/e/f/g.h?i=j#k", "G.H?I=J#K");
449       if(strcmp(buf, "http://a:b@c.d:1/e/f/G.H?I=J#K")) err = true;
450       free(buf);
451       buf = tcurlresolve("http://a:b@c.d:1/e/f/g.h?i=j#k", "?I=J#K");
452       if(strcmp(buf, "http://a:b@c.d:1/e/f/g.h?I=J#K")) err = true;
453       free(buf);
454       buf = tcurlresolve("http://a:b@c.d:1/e/f/g.h?i=j#k", "#K");
455       if(strcmp(buf, "http://a:b@c.d:1/e/f/g.h?i=j#K")) err = true;
456       free(buf);
457     }
458     buf = tcbaseencode(str, slen);
459     if(strcmp(buf, "NSUyKzMtMT00ICJZZXMvTm8iIDxhJmI+")) err = true;
460     dec = tcbasedecode(buf, &dsiz);
461     if(dsiz != slen || strcmp(dec, str)) err = true;
462     free(dec);
463     free(buf);
464     buf = tcquoteencode(str, slen);
465     if(strcmp(buf, "5%2+3-1=3D4 \"Yes/No\" <a&b>")) err = true;
466     dec = tcquotedecode(buf, &dsiz);
467     if(dsiz != slen || strcmp(dec, str)) err = true;
468     free(dec);
469     free(buf);
470     buf = tcmimeencode(str, "UTF-8", true);
471     if(strcmp(buf, "=?UTF-8?B?NSUyKzMtMT00ICJZZXMvTm8iIDxhJmI+?=")) err = true;
472     char encname[32];
473     dec = tcmimedecode(buf, encname);
474     if(strcmp(dec, str) || strcmp(encname, "UTF-8")) err = true;
475     free(dec);
476     free(buf);
477     buf = tcpackencode(str, slen, &bsiz);
478     dec = tcpackdecode(buf, bsiz, &dsiz);
479     if(dsiz != slen || strcmp(dec, str)) err = true;
480     free(dec);
481     free(buf);
482     buf = tcbsencode(str, slen, &bsiz);
483     dec = tcbsdecode(buf, bsiz, &dsiz);
484     if(dsiz != slen || strcmp(dec, str)) err = true;
485     free(dec);
486     free(buf);
487     int idx;
488     buf = tcbwtencode(str, slen, &idx);
489     if(memcmp(buf, "4\"o 5a23s-%+=> 1b/\"<&YNe", slen) || idx != 13) err = true;
490     dec = tcbwtdecode(buf, slen, idx);
491     if(memcmp(dec, str, slen)) err = true;
492     free(dec);
493     free(buf);
494     if(_tc_deflate){
495       if((buf = tcdeflate(str, slen, &bsiz)) != NULL){
496         if((dec = tcinflate(buf, bsiz, &dsiz)) != NULL){
497           if(slen != dsiz || memcmp(str, dec, dsiz)) err = true;
498           free(dec);
499         } else {
500           err = true;
501         }
502         free(buf);
503       } else {
504         err = true;
505       }
506       if((buf = tcgzipencode(str, slen, &bsiz)) != NULL){
507         if((dec = tcgzipdecode(buf, bsiz, &dsiz)) != NULL){
508           if(slen != dsiz || memcmp(str, dec, dsiz)) err = true;
509           free(dec);
510         } else {
511           err = true;
512         }
513         free(buf);
514       } else {
515         err = true;
516       }
517       if(tcgetcrc("hoge", 4) % 10000 != 7034) err = true;
518     }
519     int anum = myrand(50)+1;
520     unsigned int ary[anum];
521     for(int j = 0; j < anum; j++){
522       ary[j] = myrand(INT_MAX);
523     }
524     buf = tcberencode(ary, anum, &bsiz);
525     int dnum;
526     unsigned int *dary = tcberdecode(buf, bsiz, &dnum);
527     if(anum != dnum || memcmp(ary, dary, sizeof(*dary) * dnum)) err = true;
528     free(dary);
529     free(buf);
530     buf = tcxmlescape(str);
531     if(strcmp(buf, "5%2+3-1=4 &quot;Yes/No&quot; &lt;a&amp;b&gt;")) err = true;
532     dec = tcxmlunescape(buf);
533     if(strcmp(dec, str)) err = true;
534     free(dec);
535     free(buf);
536     if(i % 10 == 1){
537       list = tcxmlbreak("<abc de=\"foo&amp;\" gh='&lt;bar&gt;'>xyz<br>\na<!--<mikio>--></abc>");
538       for(int j = 0; j < tclistnum(list); j++){
539         const char *elem = tclistval2(list, j);
540         TCMAP *attrs = tcxmlattrs(elem);
541         tcmapdel(attrs);
542       }
543       tclistdel(list);
544     }
545     if(i % 10 == 1){
546       for(int16_t j = 1; j <= 0x2000; j *= 2){
547         for(int16_t num = j - 1; num <= j + 1; num++){
548           int16_t nnum = TCHTOIS(num);
549           if(num != TCITOHS(nnum)) err = true;
550         }
551       }
552       for(int32_t j = 1; j <= 0x20000000; j *= 2){
553         for(int32_t num = j - 1; num <= j + 1; num++){
554           int32_t nnum = TCHTOIL(num);
555           if(num != TCITOHL(nnum)) err = true;
556           char buf[TCNUMBUFSIZ];
557           int step, nstep;
558           TCSETVNUMBUF(step, buf, num);
559           TCREADVNUMBUF(buf, nnum, nstep);
560           if(num != nnum || step != nstep) err = true;
561         }
562       }
563       for(int64_t j = 1; j <= 0x2000000000000000; j *= 2){
564         for(int64_t num = j - 1; num <= j + 1; num++){
565           int64_t nnum = TCHTOILL(num);
566           if(num != TCITOHLL(nnum)) err = true;
567           char buf[TCNUMBUFSIZ];
568           int step, nstep;
569           TCSETVNUMBUF64(step, buf, num);
570           TCREADVNUMBUF64(buf, nnum, nstep);
571           if(num != nnum || step != nstep) err = true;
572         }
573       }
574       char *bitmap = TCBITMAPNEW(100);
575       for(int j = 0; j < 100; j++){
576         if(j % 3 == 0) TCBITMAPON(bitmap, j);
577         if(j % 5 == 0) TCBITMAPOFF(bitmap, j);
578       }
579       for(int j = 0; j < 100; j++){
580         if(j % 5 == 0){
581           if(TCBITMAPCHECK(bitmap, j)) err = true;
582         } else if(j % 3 == 0){
583           if(!TCBITMAPCHECK(bitmap, j)) err = true;
584         }
585       }
586       TCBITMAPDEL(bitmap);
587       buf = tcmalloc(i / 8 + 2);
588       TCBITSTRM strm;
589       TCBITSTRMINITW(strm, buf);
590       for(int j = 0; j < i; j++){
591         int sign = j % 3 == 0 || j % 7 == 0;
592         TCBITSTRMCAT(strm, sign);
593       }
594       TCBITSTRMSETEND(strm);
595       int bnum = TCBITSTRMNUM(strm);
596       if(bnum != i) err = true;
597       TCBITSTRMINITR(strm, buf, bsiz);
598       for(int j = 0; j < i; j++){
599         int sign;
600         TCBITSTRMREAD(strm, sign);
601         if(sign != (j % 3 == 0 || j % 7 == 0)) err = true;
602       }
603       free(buf);
604     }
605     if(rnum > 250 && i % (rnum / 250) == 0){
606       putchar('.');
607       fflush(stdout);
608       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
609     }
610   }
611   iprintf("time: %.3f\n", tctime() - stime);
612   if(err){
613     iprintf("error\n\n");
614     return 1;
615   }
616   iprintf("ok\n\n");
617   return 0;
618 }
619
620
621 /* perform wicked command */
622 static int procwicked(int rnum){
623   iprintf("<Wicked Writing Test>\n  rnum=%d\n\n", rnum);
624   double stime = tctime();
625   TCMPOOL *mpool = tcmpoolglobal();
626   TCXSTR *xstr = myrand(2) > 0 ? tcxstrnew() : tcxstrnew2("hello world");
627   tcmpoolputxstr(mpool, xstr);
628   TCLIST *list = myrand(2) > 0 ? tclistnew() : tclistnew2(myrand(rnum) + rnum / 2);
629   tcmpoolputlist(mpool, list);
630   TCMAP *map = myrand(2) > 0 ? tcmapnew() : tcmapnew2(myrand(rnum) + rnum / 2);
631   tcmpoolputmap(mpool, map);
632   TCMDB *mdb = myrand(2) > 0 ? tcmdbnew() : tcmdbnew2(myrand(rnum) + rnum / 2);
633   tcmpoolput(mpool, mdb, (void (*)(void*))tcmdbdel);
634   for(int i = 1; i <= rnum; i++){
635     char kbuf[RECBUFSIZ];
636     int ksiz = sprintf(kbuf, "%d", myrand(i));
637     char vbuf[RECBUFSIZ];
638     int vsiz = sprintf(vbuf, "%d", myrand(i));
639     char *tmp;
640     switch(myrand(69)){
641     case 0:
642       putchar('0');
643       tcxstrcat(xstr, kbuf, ksiz);
644       break;
645     case 1:
646       putchar('1');
647       tcxstrcat2(xstr, kbuf);
648       break;
649     case 2:
650       putchar('2');
651       if(myrand(rnum / 100 + 1) == 0) tcxstrclear(xstr);
652       break;
653     case 3:
654       putchar('3');
655       tcxstrprintf(xstr, "[%s:%d]", kbuf, i);
656       break;
657     case 4:
658       putchar('4');
659       tclistpush(list, kbuf, ksiz);
660       break;
661     case 5:
662       putchar('5');
663       tclistpush2(list, kbuf);
664       break;
665     case 6:
666       putchar('6');
667       tmp = tcmemdup(kbuf, ksiz);
668       tclistpushmalloc(list, tmp, strlen(tmp));
669       break;
670     case 7:
671       putchar('7');
672       if(myrand(10) == 0) free(tclistpop(list, &ksiz));
673       break;
674     case 8:
675       putchar('8');
676       if(myrand(10) == 0) free(tclistpop2(list));
677       break;
678     case 9:
679       putchar('9');
680       tclistunshift(list, kbuf, ksiz);
681       break;
682     case 10:
683       putchar('A');
684       tclistunshift2(list, kbuf);
685       break;
686     case 11:
687       putchar('B');
688       if(myrand(10) == 0) free(tclistshift(list, &ksiz));
689       break;
690     case 12:
691       putchar('C');
692       if(myrand(10) == 0) free(tclistshift2(list));
693       break;
694     case 13:
695       putchar('D');
696       tclistinsert(list, i / 10, kbuf, ksiz);
697       break;
698     case 14:
699       putchar('E');
700       tclistinsert2(list, i / 10, kbuf);
701       break;
702     case 15:
703       putchar('F');
704       if(myrand(10) == 0) free(tclistremove(list, i / 10, &ksiz));
705       break;
706     case 16:
707       putchar('G');
708       if(myrand(10) == 0) free(tclistremove2(list, i / 10));
709       break;
710     case 17:
711       putchar('H');
712       tclistover(list, i / 10, kbuf, ksiz);
713       break;
714     case 18:
715       putchar('I');
716       tclistover2(list, i / 10, kbuf);
717       break;
718     case 19:
719       putchar('J');
720       if(myrand(rnum / 1000 + 1) == 0) tclistsort(list);
721       break;
722     case 20:
723       putchar('K');
724       if(myrand(rnum / 1000 + 1) == 0) tclistsortci(list);
725       break;
726     case 21:
727       putchar('L');
728       if(myrand(rnum / 1000 + 1) == 0) tclistlsearch(list, kbuf, ksiz);
729       break;
730     case 22:
731       putchar('M');
732       if(myrand(rnum / 1000 + 1) == 0) tclistbsearch(list, kbuf, ksiz);
733       break;
734     case 23:
735       putchar('N');
736       if(myrand(rnum / 100 + 1) == 0) tclistclear(list);
737       break;
738     case 24:
739       putchar('O');
740       if(myrand(rnum / 100 + 1) == 0){
741         int dsiz;
742         char *dbuf = tclistdump(list, &dsiz);
743         tclistdel(tclistload(dbuf, dsiz));
744         free(dbuf);
745       }
746       break;
747     case 25:
748       putchar('P');
749       if(myrand(100) == 0){
750         if(myrand(2) == 0){
751           for(int j = 0; j < tclistnum(list); j++){
752             int rsiz;
753             tclistval(list, j, &rsiz);
754           }
755         } else {
756           for(int j = 0; j < tclistnum(list); j++){
757             tclistval2(list, j);
758           }
759         }
760       }
761       break;
762     case 26:
763       putchar('Q');
764       tcmapput(map, kbuf, ksiz, vbuf, vsiz);
765       break;
766     case 27:
767       putchar('R');
768       tcmapput2(map, kbuf, vbuf);
769       break;
770     case 28:
771       putchar('S');
772       tcmapput3(map, kbuf, ksiz, vbuf, vsiz, vbuf, vsiz);
773       break;
774     case 29:
775       putchar('T');
776       tcmapputkeep(map, kbuf, ksiz, vbuf, vsiz);
777       break;
778     case 30:
779       putchar('U');
780       tcmapputkeep2(map, kbuf, vbuf);
781       break;
782     case 31:
783       putchar('V');
784       tcmapputcat(map, kbuf, ksiz, vbuf, vsiz);
785       break;
786     case 32:
787       putchar('W');
788       tcmapputcat2(map, kbuf, vbuf);
789       break;
790     case 33:
791       putchar('X');
792       if(myrand(10) == 0) tcmapout(map, kbuf, ksiz);
793       break;
794     case 34:
795       putchar('Y');
796       if(myrand(10) == 0) tcmapout2(map, kbuf);
797       break;
798     case 35:
799       putchar('Z');
800       tcmapget3(map, kbuf, ksiz, &vsiz);
801       break;
802     case 36:
803       putchar('a');
804       tcmapmove(map, kbuf, ksiz, true);
805       break;
806     case 37:
807       putchar('b');
808       tcmapmove(map, kbuf, ksiz, false);
809       break;
810     case 38:
811       putchar('c');
812       tcmapmove2(map, kbuf, true);
813       break;
814     case 39:
815       putchar('d');
816       if(myrand(100) == 0) tcmapiterinit(map);
817       break;
818     case 40:
819       putchar('e');
820       tcmapiternext(map, &vsiz);
821       break;
822     case 41:
823       putchar('f');
824       tcmapiternext2(map);
825       break;
826     case 42:
827       putchar('g');
828       if(myrand(100) == 0){
829         if(myrand(2) == 0){
830           tclistdel(tcmapkeys(map));
831         } else {
832           tclistdel(tcmapvals(map));
833         }
834       }
835       break;
836     case 43:
837       putchar('h');
838       if(myrand(rnum / 100 + 1) == 0) tcmapclear(map);
839       break;
840     case 44:
841       putchar('i');
842       if(myrand(20) == 0) tcmapcutfront(map, myrand(10));
843       break;
844     case 45:
845       putchar('j');
846       if(myrand(rnum / 100 + 1) == 0){
847         int dsiz;
848         char *dbuf = tcmapdump(map, &dsiz);
849         free(tcmaploadone(dbuf, dsiz, kbuf, ksiz, &vsiz));
850         tcmapdel(tcmapload(dbuf, dsiz));
851         free(dbuf);
852       }
853       break;
854     case 46:
855       putchar('k');
856       tcmdbput(mdb, kbuf, ksiz, vbuf, vsiz);
857       break;
858     case 47:
859       putchar('l');
860       tcmdbput2(mdb, kbuf, vbuf);
861       break;
862     case 48:
863       putchar('m');
864       tcmdbputkeep(mdb, kbuf, ksiz, vbuf, vsiz);
865       break;
866     case 49:
867       putchar('n');
868       tcmdbputkeep2(mdb, kbuf, vbuf);
869       break;
870     case 50:
871       putchar('o');
872       tcmdbputcat(mdb, kbuf, ksiz, vbuf, vsiz);
873       break;
874     case 51:
875       putchar('p');
876       tcmdbputcat2(mdb, kbuf, vbuf);
877       break;
878     case 52:
879       putchar('q');
880       if(myrand(10) == 0) tcmdbout(mdb, kbuf, ksiz);
881       break;
882     case 53:
883       putchar('r');
884       if(myrand(10) == 0) tcmdbout2(mdb, kbuf);
885       break;
886     case 54:
887       putchar('s');
888       free(tcmdbget(mdb, kbuf, ksiz, &vsiz));
889       break;
890     case 55:
891       putchar('t');
892       free(tcmdbget3(mdb, kbuf, ksiz, &vsiz));
893       break;
894     case 56:
895       putchar('u');
896       if(myrand(100) == 0) tcmdbiterinit(mdb);
897       break;
898     case 57:
899       putchar('v');
900       free(tcmdbiternext(mdb, &vsiz));
901       break;
902     case 58:
903       putchar('w');
904       tmp = tcmdbiternext2(mdb);
905       free(tmp);
906       break;
907     case 59:
908       putchar('x');
909       if(myrand(rnum / 100 + 1) == 0) tcmdbvanish(mdb);
910       break;
911     case 60:
912       putchar('y');
913       if(myrand(200) == 0) tcmdbcutfront(mdb, myrand(100));
914       break;
915     case 61:
916       putchar('+');
917       if(myrand(100) == 0) tcmpoolmalloc(mpool, 1);
918       break;
919     case 62:
920       putchar('+');
921       if(myrand(100) == 0) tcmpoolxstrnew(mpool);
922       break;
923     case 63:
924       putchar('+');
925       if(myrand(100) == 0) tcmpoollistnew(mpool);
926       break;
927     case 64:
928       putchar('+');
929       if(myrand(100) == 0) tcmpoolmapnew(mpool);
930       break;
931     default:
932       putchar('@');
933       if(myrand(10000) == 0) srand((unsigned int)(tctime() * 1000) % UINT_MAX);
934       break;
935     }
936     if(i % 50 == 0) iprintf(" (%08d)\n", i);
937   }
938   if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum);
939   iprintf("time: %.3f\n", tctime() - stime);
940   iprintf("ok\n\n");
941   return 0;
942 }
943
944
945
946 // END OF FILE