Updated TODO.
[mpdm.git] / stress.c
blob2d027d01adf1978599be69391a129cf9217483c8
1 /*
3 MPDM - Minimum Profit Data Manager
4 Copyright (C) 2003/2007 Angel Ortega <angel@triptico.com>
6 stress.c - Stress tests for MPDM.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 http://www.triptico.com
26 #include <stdio.h>
27 #include <string.h>
28 #include <wchar.h>
30 #include <time.h>
32 #include "mpdm.h"
34 /* total number of tests and oks */
35 int tests = 0;
36 int oks = 0;
38 /* failed tests messages */
39 char *failed_msgs[5000];
40 int i_failed_msgs = 0;
42 int do_benchmarks = 0;
43 int do_multibyte_sregex_tests = 0;
45 /*******************
46 Code
47 ********************/
49 void do_test(char *str, int ok)
51 char tmp[1024];
53 sprintf(tmp, "%s: %s\n", str, ok ? "OK!" : "*** Failed ***");
54 printf(tmp);
56 tests++;
58 if (ok)
59 oks++;
60 else
61 failed_msgs[i_failed_msgs++] = strdup(tmp);
65 /* tests */
67 void test_basic(void)
69 int i;
70 double r;
71 mpdm_t v;
72 mpdm_t w;
74 v = MPDM_S(L"65536");
75 mpdm_dump(v);
76 i = mpdm_ival(v);
78 do_test("i == 65536", (i == 65536));
79 do_test("v has MPDM_IVAL", (v->flags & MPDM_IVAL));
81 r = mpdm_rval(v);
82 do_test("r == 65536", (r == 65536.0));
83 do_test("v has MPDM_RVAL", (v->flags & MPDM_RVAL));
85 printf("mpdm_string: %ls\n", mpdm_string(MPDM_H(0)));
86 printf("mpdm_string: %ls\n", mpdm_string(MPDM_H(0)));
88 /* partial copies of strings */
89 v = MPDM_LS(L"this is not America");
90 v = MPDM_NS((wchar_t *) v->data + 4, 4);
92 do_test("Partial string values", mpdm_cmp(v, MPDM_LS(L" is ")) == 0);
94 v = MPDM_S(L"MUAHAHAHA!");
95 do_test("Testing mpdm_clone semantics 1", mpdm_clone(v) == v);
97 v = MPDM_A(2);
98 mpdm_aset(v, MPDM_S(L"evil"), 0);
99 mpdm_aset(v, MPDM_S(L"dead"), 1);
100 w = mpdm_clone(v);
102 do_test("Testing mpdm_clone semantics 2.1", w != v);
104 v = mpdm_aget(v, 0);
105 do_test("Testing mpdm_clone semantics 2.2", v->ref > 1);
106 do_test("Testing mpdm_clone semantics 2.3", mpdm_aget(w, 0) == v);
108 /* mbs / wcs tests */
109 v = MPDM_MBS("This is (was) a multibyte string");
110 mpdm_dump(v);
112 /* greek omega is 03a9 */
113 v = MPDM_MBS("?Espa?a! (non-ASCII string, as ISO-8859-1 char *)");
114 mpdm_dump(v);
115 printf("(Previous value will be NULL if locale doesn't match stress.c encoding)\n");
117 v = MPDM_LS(L"A capital greek omega between brackets [\x03a9]");
118 mpdm_dump(v);
119 printf("(Previous value will only show on an Unicode terminal)\n");
121 v = MPDM_R(3.1416);
122 mpdm_dump(v);
123 do_test("rval 1", mpdm_rval(v) == 3.1416);
124 do_test("ival 1", mpdm_ival(v) == 3);
126 v = MPDM_R(777777.0 / 2.0);
127 mpdm_dump(v);
128 do_test("mpdm_rnew 1", mpdm_cmp(v, MPDM_LS(L"388888.5")) == 0);
130 v = MPDM_R(388888.500);
131 mpdm_dump(v);
132 do_test("mpdm_rnew 2", mpdm_cmp(v, MPDM_LS(L"388888.5")) == 0);
134 v = MPDM_R(388888.412);
135 mpdm_dump(v);
136 do_test("mpdm_rnew 3", mpdm_cmp(v, MPDM_LS(L"388888.412")) == 0);
138 v = MPDM_R(388888.6543);
139 mpdm_dump(v);
140 do_test("mpdm_rnew 4", mpdm_cmp(v, MPDM_LS(L"388888.6543")) == 0);
142 v = MPDM_R(388888.0);
143 mpdm_dump(v);
144 do_test("mpdm_rnew 5", mpdm_cmp(v, MPDM_LS(L"388888")) == 0);
146 v = MPDM_R(0.050000);
147 mpdm_dump(v);
148 do_test("mpdm_rnew 6", mpdm_cmp(v, MPDM_LS(L"0.05")) == 0);
150 v = MPDM_R(0.000);
151 mpdm_dump(v);
152 do_test("mpdm_rnew 7", mpdm_cmp(v, MPDM_LS(L"0")) == 0);
154 v = MPDM_LS(L"0177");
155 do_test("mpdm_ival() for octal numbers", mpdm_ival(v) == 0x7f);
157 v = MPDM_LS(L"0xFF");
158 do_test("mpdm_ival() for hexadecimal numbers", mpdm_ival(v) == 255);
160 v = MPDM_LS(L"001");
161 do_test("mpdm_rval() for octal numbers", mpdm_rval(v) == 1.0);
163 v = MPDM_LS(L"0x7f");
164 do_test("mpdm_rval() for hexadecimal numbers", mpdm_ival(v) == 127.0);
166 do_test("Two NULLs are equal", mpdm_cmp(NULL, NULL) == 0);
169 mpdm_t sort_cb(mpdm_t args)
171 int d;
173 /* sorts reversely */
174 d = mpdm_cmp(mpdm_aget(args, 1), mpdm_aget(args, 0));
175 return (MPDM_I(d));
179 void test_array(void)
181 int n;
182 mpdm_t a;
183 mpdm_t v;
185 a = MPDM_A(0);
186 do_test("a->size == 0", (a->size == 0));
188 mpdm_push(a, MPDM_LS(L"sunday"));
189 mpdm_push(a, MPDM_LS(L"monday"));
190 mpdm_push(a, MPDM_LS(L"tuesday"));
191 mpdm_push(a, MPDM_LS(L"wednesday"));
192 mpdm_push(a, MPDM_LS(L"thursday"));
193 mpdm_push(a, MPDM_LS(L"friday"));
194 mpdm_push(a, MPDM_LS(L"saturday"));
195 mpdm_dump(a);
196 do_test("a->size == 7", (a->size == 7));
198 v = mpdm_aset(a, NULL, 3);
199 do_test("v->ref == 0", (v->ref == 0));
200 mpdm_dump(a);
202 a = mpdm_sort(a, 1);
203 do_test("NULLs are sorted on top", (mpdm_aget(a, 0) == NULL));
205 mpdm_aset(a, v, 0);
206 v = mpdm_aget(a, 3);
207 do_test("v is referenced again", (v != NULL && v->ref > 0));
209 a = mpdm_sort(a, 1);
210 do_test("mpdm_asort() works (1)", mpdm_cmp(mpdm_aget(a, 0), MPDM_LS(L"friday")) == 0);
211 do_test("mpdm_asort() works (2)",
212 mpdm_cmp(mpdm_aget(a, 6), MPDM_LS(L"wednesday")) == 0);
214 /* asort_cb sorts reversely */
215 a = mpdm_sort_cb(a, 1, MPDM_X(sort_cb));
217 do_test("mpdm_asort_cb() works (1)",
218 mpdm_cmp(mpdm_aget(a, 6), MPDM_LS(L"friday")) == 0);
219 do_test("mpdm_asort_cb() works (2)",
220 mpdm_cmp(mpdm_aget(a, 0), MPDM_LS(L"wednesday")) == 0);
222 n = v->ref;
223 v = mpdm_aget(a, 3);
224 mpdm_collapse(a, 3, 1);
225 do_test("acollapse unrefs values", (v->ref < n));
227 /* test queues */
228 a = MPDM_A(0);
230 /* add several values */
231 for (n = 0; n < 10; n++)
232 v = mpdm_queue(a, MPDM_I(n), 10);
234 do_test("queue should still output NULL", (v == NULL));
236 v = mpdm_queue(a, MPDM_I(11), 10);
237 do_test("queue should no longer output NULL", (v != NULL));
239 v = mpdm_queue(a, MPDM_I(12), 10);
240 do_test("queue should return 1", mpdm_ival(v) == 1);
241 v = mpdm_queue(a, MPDM_I(13), 10);
242 do_test("queue should return 2", mpdm_ival(v) == 2);
243 do_test("queue size should be 10", a->size == 10);
245 mpdm_dump(a);
246 v = mpdm_queue(a, MPDM_I(14), 5);
247 mpdm_dump(a);
249 do_test("queue size should be 5", a->size == 5);
250 do_test("last taken value should be 8", mpdm_ival(v) == 8);
252 a = MPDM_A(4);
253 mpdm_aset(a, MPDM_I(666), 6000);
255 do_test("array should have been automatically expanded", mpdm_size(a) == 6001);
257 v = mpdm_aget(a, -1);
258 do_test("negative offsets in arrays 1", mpdm_ival(v) == 666);
260 mpdm_aset(a, MPDM_I(777), -2);
261 v = mpdm_aget(a, 5999);
262 do_test("negative offsets in arrays 2", mpdm_ival(v) == 777);
264 mpdm_push(a, MPDM_I(888));
265 v = mpdm_aget(a, -1);
266 do_test("negative offsets in arrays 3", mpdm_ival(v) == 888);
268 v = MPDM_A(0);
269 mpdm_push(v, MPDM_I(100));
270 mpdm_pop(v);
272 /* array comparisons with mpdm_cmp() */
273 a = MPDM_A(2);
274 mpdm_aset(a, MPDM_I(10), 0);
275 mpdm_aset(a, MPDM_I(60), 1);
277 v = mpdm_clone(a);
278 do_test("mpdm_cmp: array clones are equal", mpdm_cmp(a, v) == 0);
280 mpdm_adel(v, -1);
281 do_test("mpdm_cmp: shorter arrays are lesser", mpdm_cmp(a, v) > 0);
283 mpdm_push(v, MPDM_I(80));
284 do_test("mpdm_cmp: 2# element is bigger, so array is bigger", mpdm_cmp(a, v) < 0);
288 void test_hash(void)
290 mpdm_t h;
291 mpdm_t v;
292 int i, n;
294 h = MPDM_H(0);
296 do_test("hsize 1", mpdm_hsize(h) == 0);
298 mpdm_hset(h, MPDM_S(L"mp"), MPDM_I(6));
299 v = mpdm_hget(h, MPDM_S(L"mp"));
301 do_test("hsize 2", mpdm_hsize(h) == 1);
303 do_test("hash: v != NULL", (v != NULL));
304 i = mpdm_ival(v);
305 do_test("hash: v == 6", (i == 6));
307 mpdm_hset(h, MPDM_S(L"mp2"), MPDM_I(66));
308 v = mpdm_hget(h, MPDM_S(L"mp2"));
310 do_test("hsize 3", mpdm_hsize(h) == 2);
312 do_test("hash: v != NULL", (v != NULL));
313 i = mpdm_ival(v);
314 do_test("hash: v == 66", (i == 66));
316 /* fills 100 values */
317 for (n = 0; n < 50; n++)
318 mpdm_hset(h, MPDM_I(n), MPDM_I(n * 10));
319 for (n = 100; n >= 50; n--)
320 mpdm_hset(h, MPDM_I(n), MPDM_I(n * 10));
322 do_test("hsize 4", mpdm_hsize(h) == 103);
324 /* tests 100 values */
325 for (n = 0; n < 100; n++) {
326 v = mpdm_hget(h, MPDM_I(n));
328 if (v != NULL) {
329 i = mpdm_ival(v);
330 if (!(i == n * 10))
331 do_test("hash: ival", (i == n * 10));
333 else
334 do_test("hash: hget", (v != NULL));
337 printf("h's size: %d\n", mpdm_hsize(h));
339 v = mpdm_hdel(h, MPDM_LS(L"mp"));
340 do_test("hdel", mpdm_ival(v) == 6);
341 do_test("hsize 5", mpdm_hsize(h) == 102);
344 mpdm_dump(h);
346 v=mpdm_hkeys(h);
347 mpdm_dump(v);
349 /* use of non-strings as hashes */
350 h = MPDM_H(0);
352 v = MPDM_A(0);
353 mpdm_hset(h, v, MPDM_I(1234));
354 v = MPDM_H(0);
355 mpdm_hset(h, v, MPDM_I(12345));
356 v = MPDM_H(0);
357 mpdm_hset(h, v, MPDM_I(9876));
358 v = MPDM_A(0);
359 mpdm_hset(h, v, MPDM_I(6543));
360 i = mpdm_ival(mpdm_hget(h, v));
362 mpdm_dump(h);
363 do_test("hash: using non-strings as hash keys", (i == 6543));
365 mpdm_hset(h, MPDM_LS(L"ok"), MPDM_I(666));
367 do_test("exists 1", mpdm_exists(h, MPDM_LS(L"ok")));
368 do_test("exists 2", !mpdm_exists(h, MPDM_LS(L"notok")));
370 v = mpdm_hget_s(h, L"ok");
371 do_test("hget_s 1", mpdm_ival(v) == 666);
373 mpdm_hset_s(h, L"ok", MPDM_I(777));
375 v = mpdm_hget_s(h, L"ok");
376 do_test("hget_s + hset_s", mpdm_ival(v) == 777);
380 void test_splice(void)
382 mpdm_t w;
383 mpdm_t v;
385 w = mpdm_splice(MPDM_LS(L"I'm agent Johnson"), MPDM_LS(L"special "), 4, 0);
386 do_test("splice insertion",
387 mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm special agent Johnson")) == 0);
388 mpdm_dump(w);
390 w = mpdm_splice(MPDM_LS(L"Life is a shit"), MPDM_LS(L"cheat"), 10, 4);
391 do_test("splice insertion and deletion (1)",
392 mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"Life is a cheat")) == 0);
393 do_test("splice insertion and deletion (2)",
394 mpdm_cmp(mpdm_aget(w, 1), MPDM_LS(L"shit")) == 0);
395 mpdm_dump(w);
397 w = mpdm_splice(MPDM_LS(L"I'm with dumb"), NULL, 4, 4);
398 do_test("splice deletion (1)", mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm dumb")) == 0);
399 do_test("splice deletion (2)", mpdm_cmp(mpdm_aget(w, 1), MPDM_LS(L"with")) == 0);
400 mpdm_dump(w);
402 v = MPDM_LS(L"It doesn't matter");
403 w = mpdm_splice(v, MPDM_LS(L" two"), v->size, 0);
404 do_test("splice insertion at the end",
405 mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"It doesn't matter two")) == 0);
406 mpdm_dump(w);
408 w = mpdm_splice(NULL, NULL, 0, 0);
409 do_test("splice with two NULLS", (mpdm_aget(w, 0) == NULL));
411 w = mpdm_splice(NULL, MPDM_LS(L"foo"), 0, 0);
412 do_test("splice with first value NULL",
413 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"foo")) == 0));
415 w = mpdm_splice(MPDM_LS(L"foo"), NULL, 0, 0);
416 do_test("splice with second value NULL",
417 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"foo")) == 0));
419 v = MPDM_LS(L"I'm testing");
421 w = mpdm_splice(v, NULL, 0, -1);
422 do_test("splice with negative del (1)",
423 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"")) == 0));
425 w = mpdm_splice(v, NULL, 4, -1);
426 do_test("splice with negative del (2)",
427 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm ")) == 0));
429 w = mpdm_splice(v, NULL, 4, -2);
430 do_test("splice with negative del (3)",
431 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm g")) == 0));
433 w = mpdm_splice(v, NULL, 0, -4);
434 do_test("splice with negative del (4)",
435 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"ing")) == 0));
436 mpdm_dump(mpdm_aget(w, 0));
438 w = mpdm_splice(v, NULL, 4, -20);
439 do_test("splice with out-of-bounds negative del",
440 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm testing")) == 0));
444 void test_strcat(void)
446 mpdm_t v;
447 mpdm_t w;
449 w = MPDM_LS(L"something");
451 v = mpdm_strcat(NULL, NULL);
452 do_test("mpdm_strcat(NULL, NULL) returns NULL", v == NULL);
454 v = mpdm_strcat(NULL, w);
455 do_test("mpdm_strcat(NULL, w) returns w", mpdm_cmp(v, w) == 0);
457 v = mpdm_strcat(w, NULL);
458 do_test("mpdm_strcat(w, NULL) returns w", mpdm_cmp(v, w) == 0);
460 w = MPDM_LS(L"");
461 v = mpdm_strcat(NULL, w);
462 do_test("mpdm_strcat(NULL, \"\") returns \"\"", mpdm_cmp(v, w) == 0);
464 v = mpdm_strcat(w, NULL);
465 do_test("mpdm_strcat(\"\", NULL) returns \"\"", mpdm_cmp(v, w) == 0);
467 v = mpdm_strcat(w, w);
468 do_test("mpdm_strcat(\"\", \"\") returns \"\"", mpdm_cmp(v, w) == 0);
473 void test_split(void)
475 mpdm_t w;
477 printf("mpdm_split test\n\n");
479 w = mpdm_split(MPDM_S(L"."), MPDM_S(L"four.elems.in.string"));
480 mpdm_dump(w);
481 do_test("4 elems: ", (w->size == 4));
483 w = mpdm_split(MPDM_S(L"."), MPDM_S(L"unseparated string"));
484 mpdm_dump(w);
485 do_test("1 elem: ", (w->size == 1));
487 w = mpdm_split(MPDM_S(L"."), MPDM_S(L".dot.at start"));
488 mpdm_dump(w);
489 do_test("3 elems: ", (w->size == 3));
491 w = mpdm_split(MPDM_S(L"."), MPDM_S(L"dot.at end."));
492 mpdm_dump(w);
493 do_test("3 elems: ", (w->size == 3));
495 w = mpdm_split(MPDM_S(L"."), MPDM_S(L"three...dots (two empty elements)"));
496 mpdm_dump(w);
497 do_test("4 elems: ", (w->size == 4));
499 w = mpdm_split(MPDM_S(L"."), MPDM_S(L"."));
500 mpdm_dump(w);
501 do_test("2 elems: ", (w->size == 2));
503 w = mpdm_split(NULL, MPDM_S(L"I am the man"));
504 do_test("NULL split 1: ", mpdm_size(w) == 12);
505 do_test("NULL split 2: ", mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I")) == 0);
509 void test_join(void)
511 mpdm_t v;
512 mpdm_t s;
513 mpdm_t w;
515 printf("mpdm_join test\n\n");
517 /* separator */
518 s = MPDM_LS(L"--");
520 w = MPDM_A(1);
521 mpdm_aset(w, MPDM_S(L"ce"), 0);
523 v = mpdm_join(NULL, w);
524 do_test("1 elem, no separator", (mpdm_cmp(v, MPDM_LS(L"ce")) == 0));
526 v = mpdm_join(s, w);
527 do_test("1 elem, '--' separator", (mpdm_cmp(v, MPDM_LS(L"ce")) == 0));
529 mpdm_push(w, MPDM_LS(L"n'est"));
530 v = mpdm_join(s, w);
531 do_test("2 elems, '--' separator", (mpdm_cmp(v, MPDM_LS(L"ce--n'est")) == 0));
533 mpdm_push(w, MPDM_LS(L"pas"));
534 v = mpdm_join(s, w);
535 do_test("3 elems, '--' separator", (mpdm_cmp(v, MPDM_LS(L"ce--n'est--pas")) == 0));
537 v = mpdm_join(NULL, w);
538 do_test("3 elems, no separator", (mpdm_cmp(v, MPDM_LS(L"cen'estpas")) == 0));
542 void test_sym(void)
544 mpdm_t v;
545 int i;
547 printf("mpdm_sset / mpdm_sget tests\n\n");
549 mpdm_sset(NULL, MPDM_LS(L"mp"), MPDM_H(7));
550 mpdm_sset(NULL, MPDM_LS(L"mp.config"), MPDM_H(7));
551 mpdm_sset(NULL, MPDM_LS(L"mp.config.auto_indent"), MPDM_I(16384));
552 mpdm_sset(NULL, MPDM_LS(L"mp.config.use_regex"), MPDM_I(1357));
553 mpdm_sset(NULL, MPDM_LS(L"mp.config.gtk_font_face"), MPDM_LS(L"profontwindows"));
554 mpdm_sset(NULL, MPDM_LS(L"mp.lines"), MPDM_A(2));
555 mpdm_sset(NULL, MPDM_LS(L"mp.lines.0"), MPDM_LS(L"First post!"));
556 mpdm_sset(NULL, MPDM_LS(L"mp.lines.1"), MPDM_LS(L"Second post!"));
557 mpdm_dump(mpdm_root());
559 v = mpdm_sget(NULL, MPDM_LS(L"mp.config.auto_indent"));
560 i = mpdm_ival(v);
562 do_test("auto_indent == 16384", (i == 16384));
564 mpdm_sweep(-1);
568 void test_file(void)
570 mpdm_t f;
571 mpdm_t v;
572 mpdm_t eol = MPDM_LS(L"\n");
574 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"w"));
576 if (f == NULL) {
577 printf("Can't create test.txt; no further file tests possible.\n");
578 return;
581 do_test("Create test.txt", f != NULL);
583 mpdm_write(f, MPDM_LS(L"0"));
584 mpdm_write(f, eol);
585 mpdm_write(f, MPDM_LS(L"1"));
586 mpdm_write(f, eol);
588 /* write WITHOUT eol */
589 mpdm_write(f, MPDM_LS(L"2"));
591 mpdm_close(f);
593 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r"));
595 do_test("test written file 0", mpdm_cmp(mpdm_read(f), MPDM_LS(L"0\n")) == 0);
596 do_test("test written file 1", mpdm_cmp(mpdm_read(f), MPDM_LS(L"1\n")) == 0);
597 do_test("test written file 2", mpdm_cmp(mpdm_read(f), MPDM_LS(L"2")) == 0);
598 do_test("test written file 3", mpdm_read(f) == NULL);
600 mpdm_close(f);
602 mpdm_unlink(MPDM_LS(L"test.txt"));
603 do_test("unlink", mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r")) == NULL);
605 v = mpdm_stat(MPDM_LS(L"stress.c"));
606 printf("Stat from stress.c:\n");
607 mpdm_dump(v);
609 /* v=mpdm_glob(MPDM_LS(L"*"));*/
610 printf("Glob:\n");
611 v = mpdm_glob(NULL);
612 mpdm_dump(v);
616 void test_regex(void)
618 mpdm_t v;
619 mpdm_t w;
621 v = mpdm_regex(MPDM_LS(L"/[0-9]+/"), MPDM_LS(L"123456"), 0);
622 do_test("regex 0", v != NULL);
624 v = mpdm_regex(MPDM_LS(L"/[0-9]+/"), MPDM_I(65536), 0);
625 do_test("regex 1", v != NULL);
627 v = mpdm_regex(MPDM_LS(L"/^[0-9]+$/"), MPDM_LS(L"12345678"), 0);
628 do_test("regex 2", v != NULL);
630 v = mpdm_regex(MPDM_LS(L"/^[0-9]+$/"), MPDM_I(1), 0);
631 do_test("regex 3", v != NULL);
633 v = mpdm_regex(MPDM_LS(L"/^[0-9]+$/"), MPDM_LS(L"A12345-678"), 0);
634 do_test("regex 4", v == NULL);
636 w = MPDM_LS(L"Hell street, 666");
637 v = mpdm_regex(MPDM_LS(L"/[0-9]+/"), w, 0);
638 do_test("regex 5", mpdm_cmp(v, MPDM_I(666)) == 0);
640 mpdm_dump(v);
642 v = mpdm_regex(MPDM_LS(L"/regex/"), MPDM_LS(L"CASE-INSENSITIVE REGEX"), 0);
643 do_test("regex 6.1 (case sensitive)", v == NULL);
645 v = mpdm_regex(MPDM_LS(L"/regex/i"), MPDM_LS(L"CASE-INSENSITIVE REGEX"), 0);
646 do_test("regex 6.2 (case insensitive)", v != NULL);
648 v=mpdm_regex(MPDM_LS(L"/[A-Z]+/"), MPDM_LS(L"case SENSITIVE regex"), 0);
649 do_test("regex 6.3 (case sensitive)", mpdm_cmp(v, MPDM_LS(L"SENSITIVE")) == 0);
651 v = mpdm_regex(MPDM_LS(L"/^\\s*/"), MPDM_LS(L"123456"), 0);
652 do_test("regex 7", v != NULL);
654 v = mpdm_regex(MPDM_LS(L"/^\\s+/"), MPDM_LS(L"123456"), 0);
655 do_test("regex 8", v == NULL);
657 v = mpdm_regex(MPDM_LS(L"/^\\s+/"), NULL, 0);
658 do_test("regex 9 (NULL string to match)", v == NULL);
660 /* sregex */
662 v = mpdm_sregex(MPDM_LS(L"/A/"), MPDM_LS(L"change all A to A"), MPDM_LS(L"E"), 0);
663 do_test("sregex 0", mpdm_cmp(v, MPDM_LS(L"change all E to A")) == 0);
665 v = mpdm_sregex(MPDM_LS(L"/A/g"), MPDM_LS(L"change all A to A"), MPDM_LS(L"E"), 0);
666 do_test("sregex 1", mpdm_cmp(v, MPDM_LS(L"change all E to E")) == 0);
668 v = mpdm_sregex(MPDM_LS(L"/A+/g"), MPDM_LS(L"change all AAAAAA to E"),
669 MPDM_LS(L"E"), 0);
670 do_test("sregex 2", mpdm_cmp(v, MPDM_LS(L"change all E to E")) == 0);
672 v = mpdm_sregex(MPDM_LS(L"/A+/g"), MPDM_LS(L"change all A A A A A A to E"),
673 MPDM_LS(L"E"), 0);
674 do_test("sregex 3", mpdm_cmp(v, MPDM_LS(L"change all E E E E E E to E")) == 0);
676 v = mpdm_sregex(MPDM_LS(L"/A+/g"), MPDM_LS(L"change all AAA A AA AAAAA A AAA to E"),
677 MPDM_LS(L"E"), 0);
678 do_test("sregex 3.2", mpdm_cmp(v, MPDM_LS(L"change all E E E E E E to E")) == 0);
680 v = mpdm_sregex(MPDM_LS(L"/[0-9]+/g"), MPDM_LS(L"1, 20, 333, 40 all are numbers"),
681 MPDM_LS(L"numbers"), 0);
682 do_test("sregex 4",
683 mpdm_cmp(v,
684 MPDM_LS(L"numbers, numbers, numbers, numbers all are numbers")) == 0);
686 v = mpdm_sregex(MPDM_LS(L"/[a-zA-Z_]+/g"), MPDM_LS(L"regex, mpdm_regex, TexMex"),
687 MPDM_LS(L"sex"), 0);
688 do_test("sregex 5", mpdm_cmp(v, MPDM_LS(L"sex, sex, sex")) == 0);
690 v = mpdm_sregex(MPDM_LS(L"/[a-zA-Z]+/g"), MPDM_LS(L"regex, mpdm_regex, TexMex"),
691 NULL, 0);
692 do_test("sregex 6", mpdm_cmp(v, MPDM_LS(L", _, ")) == 0);
694 v = mpdm_sregex(MPDM_LS(L"/\\\\/g"), MPDM_LS(L"\\MSDOS\\style\\path"),
695 MPDM_LS(L"/"), 0);
696 do_test("sregex 7", mpdm_cmp(v, MPDM_LS(L"/MSDOS/style/path")) == 0);
698 v = mpdm_sregex(MPDM_LS(L"/regex/gi"), MPDM_LS(L"regex, Regex, REGEX"),
699 MPDM_LS(L"sex"), 0);
700 do_test("sregex 8", mpdm_cmp(v, MPDM_LS(L"sex, sex, sex")) == 0);
702 v = mpdm_sregex(NULL, NULL, NULL, 0);
703 do_test("Previous sregex substitutions must be 3", mpdm_ival(v) == 3);
705 /* & in substitution tests */
706 v = MPDM_LS(L"this string has many words");
707 v = mpdm_sregex(MPDM_LS(L"/[a-z]+/g"), v, MPDM_LS(L"[&]"), 0);
708 do_test("& in sregex target",
709 mpdm_cmp(v, MPDM_LS(L"[this] [string] [has] [many] [words]")) == 0);
711 v = MPDM_LS(L"this string has many words");
712 v = mpdm_sregex(MPDM_LS(L"/[a-z]+/g"), v, MPDM_LS(L"[\\&]"), 0);
713 do_test("escaped & in sregex target",
714 mpdm_cmp(v, MPDM_LS(L"[&] [&] [&] [&] [&]")) == 0);
716 /* multiple regex tests */
717 w = MPDM_A(0);
719 mpdm_push(w, MPDM_LS(L"/^[ \t]*/"));
720 mpdm_push(w, MPDM_LS(L"/[^ \t=]+/"));
721 mpdm_push(w, MPDM_LS(L"/[ \t]*=[ \t]*/"));
722 mpdm_push(w, MPDM_LS(L"/[^ \t]+/"));
723 mpdm_push(w, MPDM_LS(L"/[ \t]*$/"));
725 v = mpdm_regex(w, MPDM_LS(L"key=value"), 0);
726 do_test("multi-regex 1.1", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"key")) == 0);
727 do_test("multi-regex 1.2", mpdm_cmp(mpdm_aget(v, 3), MPDM_LS(L"value")) == 0);
729 v = mpdm_regex(w, MPDM_LS(L" key = value"), 0);
730 do_test("multi-regex 2.1", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"key")) == 0);
731 do_test("multi-regex 2.2", mpdm_cmp(mpdm_aget(v, 3), MPDM_LS(L"value")) == 0);
733 v = mpdm_regex(w, MPDM_LS(L"\t\tkey\t=\tvalue "), 0);
734 do_test("multi-regex 3.1", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"key")) == 0);
735 do_test("multi-regex 3.2", mpdm_cmp(mpdm_aget(v, 3), MPDM_LS(L"value")) == 0);
737 v = mpdm_regex(w, MPDM_LS(L"key= "), 0);
738 do_test("multi-regex 4", v == NULL);
740 printf("Multiple line regexes\n");
741 w = MPDM_LS(L"/* this is\na C-like comment */");
742 v = mpdm_regex(MPDM_LS(L"|/\\*.+\\*/|"), w, 0);
743 do_test("Multiline regex 1", mpdm_cmp(v, w) == 0);
745 v = mpdm_regex(MPDM_LS(L"/is$/"), w, 0);
746 do_test("Multiline regex 2", v == NULL);
748 v = mpdm_regex(MPDM_LS(L"/is$/m"), w, 0);
749 do_test("Multiline regex 3", mpdm_cmp(v, MPDM_LS(L"is")) == 0);
751 printf("Pitfalls on multibyte locales (f.e. utf-8)\n");
753 w = MPDM_LS(L"-\x03a9-");
755 v = mpdm_regex(MPDM_LS(L"/-$/"), w, 0);
756 do_test("Multibyte environment regex 1", mpdm_cmp(v, MPDM_LS(L"-")) == 0);
758 if (do_multibyte_sregex_tests) {
759 v = mpdm_sregex(MPDM_LS(L"/-$/"), w, MPDM_LS(L"~"), 0);
760 do_test("Multibyte environment sregex 1",
761 mpdm_cmp(v, MPDM_LS(L"-\x03a9~")) == 0);
763 v = mpdm_sregex(MPDM_LS(L"/-/g"), w, MPDM_LS(L"~"), 0);
764 do_test("Multibyte environment sregex 2",
765 mpdm_cmp(v, MPDM_LS(L"~\x03a9~")) == 0);
767 else
768 printf("Multibyte sregex test omitted; activate with -m\n");
770 /* 'last' flag tests */
771 v = MPDM_LS(L"this string has many words");
772 v = mpdm_regex(MPDM_LS(L"/[a-z]+/l"), v, 0);
773 do_test("Flag l in mpdm_regex", mpdm_cmp(v, MPDM_LS(L"words")) == 0);
777 static mpdm_t dumper(mpdm_t args)
778 /* executable value */
780 mpdm_dump(args);
781 return (NULL);
785 static mpdm_t sum(mpdm_t args)
786 /* executable value: sum all args */
788 int n, t = 0;
790 if (args != NULL) {
791 for (n = t = 0; n < args->size; n++)
792 t += mpdm_ival(mpdm_aget(args, n));
795 return (MPDM_I(t));
799 static mpdm_t calculator(mpdm_t c, mpdm_t args)
800 /* 2 argument version: calculator. c contains a 'script' to
801 do things with the arguments */
803 int n, t;
804 mpdm_t v;
805 mpdm_t a;
806 mpdm_t o;
808 /* to avoid destroying args */
809 a = mpdm_clone(args);
811 /* unshift first argument */
812 v = mpdm_adel(a, 0);
813 t = mpdm_ival(v);
815 for (n = 0; n < mpdm_size(c); n++) {
816 /* gets operator */
817 o = mpdm_aget(c, n);
819 /* gets next value */
820 v = mpdm_adel(a, 0);
822 switch (*(wchar_t *) o->data) {
823 case '+':
824 t += mpdm_ival(v);
825 break;
826 case '-':
827 t -= mpdm_ival(v);
828 break;
829 case '*':
830 t *= mpdm_ival(v);
831 break;
832 case '/':
833 t /= mpdm_ival(v);
834 break;
838 return (MPDM_I(t));
842 void test_exec(void)
844 mpdm_t x;
845 mpdm_t w;
846 mpdm_t p;
848 printf("test_exec\n");
850 x = MPDM_X(dumper);
852 /* a simple value */
853 mpdm_exec(x, NULL);
854 mpdm_exec(x, x);
856 x = MPDM_X(sum);
857 w = MPDM_A(3);
858 mpdm_aset(w, MPDM_I(100), 0);
859 mpdm_aset(w, MPDM_I(220), 1);
860 mpdm_aset(w, MPDM_I(333), 2);
862 do_test("exec 0", mpdm_ival(mpdm_exec(x, w)) == 653);
864 mpdm_push(w, MPDM_I(1));
866 /* multiple executable value: vm and compiler support */
868 /* calculator 'script' */
869 p = MPDM_A(0);
870 mpdm_push(p, MPDM_LS(L"+"));
871 mpdm_push(p, MPDM_LS(L"-"));
872 mpdm_push(p, MPDM_LS(L"+"));
874 /* the value */
875 x = MPDM_A(2);
876 x->flags |= MPDM_EXEC;
878 mpdm_aset(x, MPDM_X(calculator), 0);
879 mpdm_aset(x, p, 1);
881 do_test("exec 1", mpdm_ival(mpdm_exec(x, w)) == -12);
883 /* another 'script', different operations with the same values */
884 p = MPDM_A(0);
885 mpdm_push(p, MPDM_LS(L"*"));
886 mpdm_push(p, MPDM_LS(L"/"));
887 mpdm_push(p, MPDM_LS(L"+"));
889 mpdm_aset(x, p, 1);
891 do_test("exec 2", mpdm_ival(mpdm_exec(x, w)) == 67);
895 void test_encoding(void)
897 mpdm_t f;
898 mpdm_t v;
899 mpdm_t w;
900 const wchar_t *ptr;
902 v = MPDM_MBS("?Espa?a!\n");
904 printf("\nLocale encoding tests (will look bad if terminal is not ISO-8859-1)\n\n");
906 if ((f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"w"))) == NULL) {
907 printf("Can't write test.txt; no further file test possible.\n");
908 return;
911 mpdm_write(f, v);
912 mpdm_close(f);
914 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r"));
915 w = mpdm_read(f);
916 mpdm_dump(w);
917 do_test("Locale encoding", mpdm_cmp(w, v) == 0);
918 mpdm_close(f);
920 printf
921 ("\nutf8.txt loading (should look good only in UTF-8 terminals with good fonts)\n");
923 f = mpdm_open(MPDM_LS(L"utf8.txt"), MPDM_LS(L"r"));
924 w = mpdm_read(f);
925 mpdm_dump(w);
926 mpdm_close(f);
928 for (ptr = w->data; *ptr != L'\0'; ptr++)
929 printf("%d", mpdm_wcwidth(*ptr));
930 printf("\n");
932 if (mpdm_encoding(MPDM_LS(L"UTF-8")) < 0) {
933 printf("No multiple encoding (iconv) support; no more tests possible.\n");
934 return;
937 printf
938 ("\nForced utf8.txt loading (should look good only in UTF-8 terminals with good fonts)\n");
940 f = mpdm_open(MPDM_LS(L"utf8.txt"), MPDM_LS(L"r"));
941 w = mpdm_read(f);
942 mpdm_dump(w);
943 mpdm_close(f);
945 /* new open file will use the specified encoding */
946 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"w"));
947 mpdm_write(f, v);
948 mpdm_close(f);
950 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r"));
951 w = mpdm_read(f);
952 mpdm_dump(w);
953 do_test("iconv encoding", mpdm_cmp(w, v) == 0);
954 mpdm_close(f);
956 mpdm_encoding(NULL);
960 void test_gettext(void)
962 mpdm_t v;
963 mpdm_t h;
965 printf("\nTesting gettext...\n");
967 mpdm_gettext_domain(MPDM_LS(L"stress"), MPDM_LS(L"./po"));
969 printf("Should follow a translated string of 'This is a test string':\n");
970 v = mpdm_gettext(MPDM_LS(L"This is a test string"));
971 mpdm_dump(v);
973 printf("The same, but cached:\n");
974 v = mpdm_gettext(MPDM_LS(L"This is a test string"));
975 mpdm_dump(v);
977 v = mpdm_gettext(MPDM_LS(L"This string is not translated"));
978 mpdm_dump(v);
980 printf("Ad-hoc translation hash:\n");
981 h = MPDM_H(0);
982 mpdm_hset(h, MPDM_LS(L"test string"), MPDM_LS(L"cadena de prueba"));
984 mpdm_gettext_domain(MPDM_LS(L"stress"), h);
985 v = mpdm_gettext(MPDM_LS(L"test string"));
986 mpdm_dump(v);
990 void timer(int secs)
992 static clock_t clks = 0;
994 switch (secs) {
995 case 0:
996 clks = clock();
997 break;
999 case -1:
1000 printf("%.2f seconds\n", (float) (clock() - clks) / (float) CLOCKS_PER_SEC);
1001 break;
1006 void bench_hash(int i, mpdm_t l, int buckets)
1008 mpdm_t h;
1009 mpdm_t v;
1010 int n;
1012 printf("Hash of %d buckets: \n", buckets);
1013 h = MPDM_H(buckets);
1015 timer(0);
1016 for (n = 0; n < i; n++) {
1017 v = mpdm_aget(l, n);
1018 mpdm_hset(h, v, v);
1020 timer(-1);
1022 printf("Bucket usage:\n");
1023 for(n=0;n < mpdm_size(h);n++)
1024 printf("\t%d: %d\n", n, mpdm_size(mpdm_aget(h, n)));
1026 mpdm_sweep(-1);
1030 void benchmark(void)
1032 mpdm_t l;
1033 int i, n;
1034 char tmp[64];
1036 printf("\n");
1038 if (!do_benchmarks) {
1039 printf("Skipping benchmarks\nRun them with 'stress -b'\n");
1040 return;
1043 printf("BENCHMARKS\n");
1045 i = 500000;
1047 printf("Creating %d values...\n", i);
1049 l = mpdm_ref(MPDM_A(i));
1050 for (n = 0; n < i; n++) {
1051 sprintf(tmp, "%08x", n);
1052 /* mpdm_aset(l, MPDM_MBS(tmp), n);*/
1053 mpdm_aset(l, MPDM_I(n), n);
1056 printf("OK\n");
1058 bench_hash(i, l, 0);
1059 bench_hash(i, l, 61);
1060 bench_hash(i, l, 89);
1061 bench_hash(i, l, 127);
1063 mpdm_unref(l);
1067 void test_conversion(void)
1069 wchar_t *wptr = NULL;
1070 char *ptr = NULL;
1071 int size = 0;
1073 ptr = mpdm_wcstombs(L"", &size);
1074 do_test("mpdm_wcstombs converts an empty string", ptr != NULL);
1076 wptr = mpdm_mbstowcs("", &size, 0);
1077 do_test("mpdm_mbstowcs converts an empty string", wptr != NULL);
1081 void test_pipes(void)
1083 mpdm_t f;
1085 printf("\n");
1087 if ((f = mpdm_popen(MPDM_LS(L"date"), MPDM_LS(L"r"))) != NULL) {
1088 mpdm_t v;
1090 v = mpdm_read(f);
1091 mpdm_pclose(f);
1093 printf("Pipe from 'date':\n");
1094 mpdm_dump(v);
1096 else
1097 printf("Can't pipe to 'date'\n");
1101 void test_misc(void)
1103 printf("Home dir:\n");
1104 mpdm_dump(mpdm_home_dir());
1105 printf("App dir:\n");
1106 mpdm_dump(mpdm_app_dir());
1110 void test_sprintf(void)
1112 mpdm_t v;
1113 mpdm_t w;
1115 printf("sprintf tests\n");
1117 v = MPDM_A(0);
1118 mpdm_push(v, MPDM_I(100));
1119 mpdm_push(v, MPDM_LS(L"beers"));
1121 w = mpdm_sprintf(MPDM_LS(L"%d %s for me"), v);
1122 do_test("sprintf 1", mpdm_cmp(w, MPDM_LS(L"100 beers for me")) == 0);
1124 w = mpdm_sprintf(MPDM_LS(L"%d %s for me %d"), v);
1125 do_test("sprintf 2", mpdm_cmp(w, MPDM_LS(L"100 beers for me %d")) == 0);
1127 w = mpdm_sprintf(MPDM_LS(L"%10d %s for me"), v);
1128 do_test("sprintf 3", mpdm_cmp(w, MPDM_LS(L" 100 beers for me")) == 0);
1130 w = mpdm_sprintf(MPDM_LS(L"%010d %s for me"), v);
1131 do_test("sprintf 4", mpdm_cmp(w, MPDM_LS(L"0000000100 beers for me")) == 0);
1133 v = MPDM_A(0);
1134 mpdm_push(v, MPDM_R(3.1416));
1136 w = mpdm_sprintf(MPDM_LS(L"Value for PI is %6.4f"), v);
1137 do_test("sprintf 2.1", mpdm_cmp(w, MPDM_LS(L"Value for PI is 3.1416")) == 0);
1139 w = mpdm_sprintf(MPDM_LS(L"Value for PI is %08.2f"), v);
1140 do_test("sprintf 2.1", mpdm_cmp(w, MPDM_LS(L"Value for PI is 00003.14")) == 0);
1142 v = MPDM_A(0);
1143 mpdm_push(v, MPDM_LS(L"stress"));
1145 w = mpdm_sprintf(MPDM_LS(L"This is a |%10s| test"), v);
1146 do_test("sprintf 3.1", mpdm_cmp(w, MPDM_LS(L"This is a | stress| test")) == 0);
1148 w = mpdm_sprintf(MPDM_LS(L"This is a |%-10s| test"), v);
1149 do_test("sprintf 3.2", mpdm_cmp(w, MPDM_LS(L"This is a |stress | test")) == 0);
1151 v = MPDM_A(0);
1152 mpdm_push(v, MPDM_I(0x263a));
1154 w = mpdm_sprintf(MPDM_LS(L"%c"), v);
1155 do_test("sprintf 3.3", mpdm_cmp(w, MPDM_LS(L"\x263a")) == 0);
1159 void test_ulc(void)
1161 mpdm_t v = MPDM_S(L"string");
1162 mpdm_t w = mpdm_ulc(v, 1);
1164 do_test("mpdm_ulc 1", mpdm_cmp(mpdm_ulc(v, 1), w) == 0);
1165 do_test("mpdm_ulc 2", mpdm_cmp(mpdm_ulc(w, 0), v) == 0);
1169 int main(int argc, char *argv[])
1171 if (argc > 1) {
1172 if (strcmp(argv[1], "-b") == 0)
1173 do_benchmarks = 1;
1174 if (strcmp(argv[1], "-m") == 0)
1175 do_multibyte_sregex_tests = 1;
1178 mpdm_startup();
1180 test_basic();
1181 test_array();
1182 test_hash();
1183 test_splice();
1184 test_strcat();
1185 test_split();
1186 test_join();
1187 test_sym();
1188 test_file();
1189 test_regex();
1190 test_exec();
1191 test_encoding();
1192 test_gettext();
1193 test_conversion();
1194 test_pipes();
1195 test_misc();
1196 test_sprintf();
1197 test_ulc();
1199 benchmark();
1201 /* mpdm_dump_unref();*/
1203 printf("memory: %d\n", mpdm->memory_usage);
1204 mpdm_sweep(-1);
1205 mpdm_sweep(-1);
1206 mpdm_sweep(-1);
1207 mpdm_sweep(-1);
1208 mpdm_sweep(-1);
1209 mpdm_sweep(-1);
1210 mpdm_sweep(-1);
1211 mpdm_sweep(-1);
1212 mpdm_sweep(-1);
1213 printf("memory: %d\n", mpdm->memory_usage);
1215 /* mpdm_dump_unref();*/
1217 mpdm_shutdown();
1219 printf("\n*** Total tests passed: %d/%d\n", oks, tests);
1221 if (oks == tests)
1222 printf("*** ALL TESTS PASSED\n");
1223 else {
1224 int n;
1226 printf("*** %d %s\n", tests - oks, "TESTS ---FAILED---");
1228 printf("\nFailed tests:\n\n");
1229 for (n = 0; n < i_failed_msgs; n++)
1230 printf("%s", failed_msgs[n]);
1233 return (0);