New functions mpdm_void() and mpdm_is_null().
[mpdm.git] / stress.c
blob8a036c635115abb7d81b96510df89d5da1ee4ba7
1 /*
3 MPDM - Minimum Profit Data Manager
4 Copyright (C) 2003/2010 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;
46 /** code **/
48 void _do_test(char *str, int ok, int src_line)
50 char tmp[1024];
52 sprintf(tmp, "%s: %s (line %d)\n", str, ok ? "OK!" : "*** Failed ***", src_line);
53 printf(tmp);
55 tests++;
57 if (ok)
58 oks++;
59 else
60 failed_msgs[i_failed_msgs++] = strdup(tmp);
63 #define do_test(str, ok) _do_test(str, ok, __LINE__)
65 #define C { int CC = mpdm->count
66 #define T(i) do_test("v counter", CC + i == mpdm->count); }
68 /** tests **/
70 void test_counter(void)
72 mpdm_t v, w;
74 C; v = MPDM_S(L"hi"); T(1);
76 C; w = MPDM_A(0); T(1);
78 C; mpdm_push(w, v); T(0);
80 C; mpdm_adel(w, 0); T(0); /* should fail in 2.x */
82 C; mpdm_queue(w, v, 10); T(0);
84 C; v = MPDM_S(L"this is a phrase"); T(1);
85 C; w = mpdm_split_s(L" ", v); T(5);
89 void test_basic(void)
91 int i;
92 double r;
93 mpdm_t v;
94 mpdm_t w;
95 mpdm_t t;
97 v = mpdm_ref(MPDM_S(L"65536"));
98 mpdm_dump(v);
99 i = mpdm_ival(v);
101 do_test("i == 65536", (i == 65536));
102 do_test("v has MPDM_IVAL", (v->flags & MPDM_IVAL));
104 r = mpdm_rval(v);
105 do_test("r == 65536", (r == 65536.0));
106 do_test("v has MPDM_RVAL", (v->flags & MPDM_RVAL));
108 mpdm_unref(v);
110 printf("mpdm_string: %ls\n", mpdm_string(MPDM_H(0)));
111 printf("mpdm_string: %ls\n", mpdm_string(MPDM_H(0)));
113 /* partial copies of strings */
114 v = MPDM_LS(L"this is not America");
115 v = MPDM_NS((wchar_t *) v->data + 4, 4);
117 do_test("Partial string values", mpdm_cmp(v, MPDM_LS(L" is ")) == 0);
119 v = mpdm_ref(MPDM_S(L"MUAHAHAHA!"));
120 w = mpdm_ref(mpdm_clone(v));
121 do_test("Testing mpdm_clone semantics 1", w == v);
122 mpdm_unref(v);
123 mpdm_unref(w);
125 v = mpdm_ref(MPDM_A(2));
126 mpdm_aset(v, MPDM_S(L"evil"), 0);
127 mpdm_aset(v, MPDM_S(L"dead"), 1);
128 w = mpdm_ref(mpdm_clone(v));
130 do_test("Testing mpdm_clone semantics 2.1", w != v);
132 t = mpdm_aget(v, 0);
133 do_test("Testing mpdm_clone semantics 2.2", t->ref > 1);
134 do_test("Testing mpdm_clone semantics 2.3", mpdm_aget(w, 0) == t);
136 mpdm_unref(w);
137 mpdm_unref(v);
139 /* mbs / wcs tests */
140 v = MPDM_MBS("This is (was) a multibyte string");
141 mpdm_dump(v);
143 /* greek omega is 03a9 */
144 v = MPDM_MBS("?Espa?a! (non-ASCII string, as ISO-8859-1 char *)");
145 mpdm_dump(v);
146 printf("(Previous value will be NULL if locale doesn't match stress.c encoding)\n");
148 v = MPDM_LS(L"A capital greek omega between brackets [\x03a9]");
149 mpdm_dump(v);
150 printf("(Previous value will only show on an Unicode terminal)\n");
152 v = mpdm_ref(MPDM_R(3.1416));
153 mpdm_dump(v);
154 do_test("rval 1", mpdm_rval(v) == 3.1416);
155 do_test("ival 1", mpdm_ival(v) == 3);
156 mpdm_unref(v);
158 v = MPDM_R(777777.0 / 2.0);
159 mpdm_dump(v);
160 do_test("mpdm_rnew 1", mpdm_cmp(v, MPDM_LS(L"388888.5")) == 0);
162 v = MPDM_R(388888.500);
163 mpdm_dump(v);
164 do_test("mpdm_rnew 2", mpdm_cmp(v, MPDM_LS(L"388888.5")) == 0);
166 v = MPDM_R(388888.412);
167 mpdm_dump(v);
168 do_test("mpdm_rnew 3", mpdm_cmp(v, MPDM_LS(L"388888.412")) == 0);
170 v = MPDM_R(388888.6543);
171 mpdm_dump(v);
172 do_test("mpdm_rnew 4", mpdm_cmp(v, MPDM_LS(L"388888.6543")) == 0);
174 v = MPDM_R(388888.0);
175 mpdm_dump(v);
176 do_test("mpdm_rnew 5", mpdm_cmp(v, MPDM_LS(L"388888")) == 0);
178 v = MPDM_R(0.050000);
179 mpdm_dump(v);
180 do_test("mpdm_rnew 6", mpdm_cmp(v, MPDM_LS(L"0.05")) == 0);
182 v = MPDM_R(0.000);
183 mpdm_dump(v);
184 do_test("mpdm_rnew 7", mpdm_cmp(v, MPDM_LS(L"0")) == 0);
186 v = MPDM_LS(L"0177");
187 do_test("mpdm_ival() for octal numbers", mpdm_ival(v) == 0x7f);
189 v = MPDM_LS(L"0xFF");
190 do_test("mpdm_ival() for hexadecimal numbers", mpdm_ival(v) == 255);
192 v = MPDM_LS(L"001");
193 do_test("mpdm_rval() for octal numbers", mpdm_rval(v) == 1.0);
195 v = MPDM_LS(L"0x7f");
196 do_test("mpdm_rval() for hexadecimal numbers", mpdm_ival(v) == 127.0);
198 do_test("Two NULLs are equal", mpdm_cmp(NULL, NULL) == 0);
200 v = MPDM_LS(L"hahaha");
201 mpdm_ref(v);
202 do_test("mpdm_cmp_s 1", mpdm_cmp_s(v, L"hahaha") == 0);
203 do_test("mpdm_cmp_s 2", mpdm_cmp_s(v, L"aahaha") > 0);
204 do_test("mpdm_cmp_s 3", mpdm_cmp_s(v, L"zahaha") < 0);
205 mpdm_unref(v);
208 mpdm_t sort_cb(mpdm_t args)
210 int d;
212 /* sorts reversely */
213 d = mpdm_cmp(mpdm_aget(args, 1), mpdm_aget(args, 0));
214 return (MPDM_I(d));
218 void test_array(void)
220 int n;
221 mpdm_t a;
222 mpdm_t v;
224 a = MPDM_A(0);
225 mpdm_ref(a);
227 do_test("a->size == 0", (a->size == 0));
229 mpdm_push(a, MPDM_LS(L"sunday"));
230 mpdm_push(a, MPDM_LS(L"monday"));
231 mpdm_push(a, MPDM_LS(L"tuesday"));
232 mpdm_push(a, MPDM_LS(L"wednesday"));
233 mpdm_push(a, MPDM_LS(L"thursday"));
234 mpdm_push(a, MPDM_LS(L"friday"));
235 mpdm_push(a, MPDM_LS(L"saturday"));
236 mpdm_dump(a);
237 do_test("a->size == 7", (a->size == 7));
239 v = mpdm_aget(a, 3);
240 mpdm_ref(v);
241 mpdm_aset(a, NULL, 3);
242 mpdm_dump(a);
244 mpdm_sort(a, 1);
245 do_test("NULLs are sorted on top", (mpdm_aget(a, 0) == NULL));
247 mpdm_aset(a, v, 0);
248 mpdm_unref(v);
250 v = mpdm_aget(a, 3);
251 do_test("v is referenced again", (v != NULL && v->ref > 0));
253 mpdm_sort(a, 1);
254 do_test("mpdm_asort() works (1)", mpdm_cmp(mpdm_aget(a, 0), MPDM_LS(L"friday")) == 0);
255 do_test("mpdm_asort() works (2)",
256 mpdm_cmp(mpdm_aget(a, 6), MPDM_LS(L"wednesday")) == 0);
258 /* asort_cb sorts reversely */
259 mpdm_sort_cb(a, 1, MPDM_X(sort_cb));
261 do_test("mpdm_asort_cb() works (1)",
262 mpdm_cmp(mpdm_aget(a, 6), MPDM_LS(L"friday")) == 0);
263 do_test("mpdm_asort_cb() works (2)",
264 mpdm_cmp(mpdm_aget(a, 0), MPDM_LS(L"wednesday")) == 0);
266 n = v->ref;
267 v = mpdm_aget(a, 3);
268 mpdm_collapse(a, 3, 1);
269 do_test("acollapse unrefs values", (v->ref < n));
271 mpdm_unref(a);
273 /* test queues */
274 a = MPDM_A(0);
275 mpdm_ref(a);
277 /* add several values */
278 for (n = 0; n < 10; n++)
279 v = mpdm_queue(a, MPDM_I(n), 10);
281 do_test("queue should still output NULL", (v == NULL));
283 v = mpdm_queue(a, MPDM_I(11), 10);
284 do_test("queue should no longer output NULL", (v != NULL));
286 v = mpdm_queue(a, MPDM_I(12), 10);
287 do_test("queue should return 1", mpdm_ival(v) == 1);
288 v = mpdm_queue(a, MPDM_I(13), 10);
289 do_test("queue should return 2", mpdm_ival(v) == 2);
290 do_test("queue size should be 10", a->size == 10);
292 mpdm_dump(a);
293 v = mpdm_queue(a, MPDM_I(14), 5);
294 mpdm_dump(a);
296 do_test("queue size should be 5", a->size == 5);
297 do_test("last taken value should be 8", mpdm_ival(v) == 8);
298 mpdm_unref(a);
300 a = MPDM_A(4);
301 mpdm_ref(a);
302 mpdm_aset(a, MPDM_I(666), 6000);
304 do_test("array should have been automatically expanded", mpdm_size(a) == 6001);
306 v = mpdm_aget(a, -1);
307 do_test("negative offsets in arrays 1", mpdm_ival(v) == 666);
309 mpdm_aset(a, MPDM_I(777), -2);
310 v = mpdm_aget(a, 5999);
311 do_test("negative offsets in arrays 2", mpdm_ival(v) == 777);
313 mpdm_push(a, MPDM_I(888));
314 v = mpdm_aget(a, -1);
315 do_test("negative offsets in arrays 3", mpdm_ival(v) == 888);
317 v = MPDM_A(0);
318 mpdm_ref(v);
319 mpdm_push(v, MPDM_I(100));
320 mpdm_pop(v);
321 mpdm_unref(v);
323 mpdm_unref(a);
325 /* array comparisons with mpdm_cmp() */
326 a = MPDM_A(2);
327 mpdm_ref(a);
328 mpdm_aset(a, MPDM_I(10), 0);
329 mpdm_aset(a, MPDM_I(60), 1);
331 v = mpdm_ref(mpdm_clone(a));
332 do_test("mpdm_cmp: array clones are equal", mpdm_cmp(a, v) == 0);
334 mpdm_adel(v, -1);
335 do_test("mpdm_cmp: shorter arrays are lesser", mpdm_cmp(a, v) > 0);
337 mpdm_push(v, MPDM_I(80));
338 do_test("mpdm_cmp: 2# element is bigger, so array is bigger", mpdm_cmp(a, v) < 0);
340 mpdm_unref(v);
341 mpdm_unref(a);
345 void test_hash(void)
347 mpdm_t h;
348 mpdm_t v;
349 int i, n;
351 h = MPDM_H(0);
352 mpdm_ref(h);
354 do_test("hsize 1", mpdm_hsize(h) == 0);
356 mpdm_hset(h, MPDM_S(L"mp"), MPDM_I(6));
357 v = mpdm_hget(h, MPDM_S(L"mp"));
359 do_test("hsize 2", mpdm_hsize(h) == 1);
361 do_test("hash: v != NULL", (v != NULL));
362 i = mpdm_ival(v);
363 do_test("hash: v == 6", (i == 6));
365 mpdm_hset(h, MPDM_S(L"mp2"), MPDM_I(66));
366 v = mpdm_hget(h, MPDM_S(L"mp2"));
368 do_test("hsize 3", mpdm_hsize(h) == 2);
370 do_test("hash: v != NULL", (v != NULL));
371 i = mpdm_ival(v);
372 do_test("hash: v == 66", (i == 66));
374 /* fills 100 values */
375 for (n = 0; n < 50; n++)
376 mpdm_hset(h, MPDM_I(n), MPDM_I(n * 10));
377 for (n = 100; n >= 50; n--)
378 mpdm_hset(h, MPDM_I(n), MPDM_I(n * 10));
380 do_test("hsize 4", mpdm_hsize(h) == 103);
382 /* tests 100 values */
383 for (n = 0; n < 100; n++) {
384 v = mpdm_hget(h, MPDM_I(n));
386 if (v != NULL) {
387 i = mpdm_ival(v);
388 if (!(i == n * 10))
389 do_test("hash: ival", (i == n * 10));
391 else
392 do_test("hash: hget", (v != NULL));
395 printf("h's size: %d\n", mpdm_hsize(h));
397 mpdm_hdel(h, MPDM_LS(L"mp"));
398 do_test("hsize 5", mpdm_hsize(h) == 102);
400 mpdm_unref(h);
403 mpdm_dump(h);
405 v=mpdm_hkeys(h);
406 mpdm_dump(v);
408 /* use of non-strings as hashes */
409 h = MPDM_H(0);
410 mpdm_ref(h);
412 v = MPDM_A(0);
413 mpdm_hset(h, v, MPDM_I(1234));
414 v = MPDM_H(0);
415 mpdm_hset(h, v, MPDM_I(12345));
416 v = MPDM_H(0);
417 mpdm_hset(h, v, MPDM_I(9876));
418 v = MPDM_A(0);
419 mpdm_ref(v);
420 mpdm_hset(h, v, MPDM_I(6543));
421 i = mpdm_ival(mpdm_hget(h, v));
422 mpdm_unref(v);
424 mpdm_dump(h);
425 do_test("hash: using non-strings as hash keys", (i == 6543));
427 mpdm_hset(h, MPDM_LS(L"ok"), MPDM_I(666));
429 do_test("exists 1", mpdm_exists(h, MPDM_LS(L"ok")));
430 do_test("exists 2", !mpdm_exists(h, MPDM_LS(L"notok")));
432 mpdm_dump(h);
433 v = mpdm_hget_s(h, L"ok");
434 printf("v %s\n", v == NULL ? "is NULL" : "is NOT NULL");
435 do_test("hget_s 1", mpdm_ival(v) == 666);
436 mpdm_dump(v);
437 mpdm_dump(h);
439 i = 0;
440 for (n = 0; n < 1000; n++) {
441 if (mpdm_hget_s(h, L"ok") != NULL)
442 i++;
444 printf("i: %d\n", i);
445 do_test("hget_s 1.2", i == 1000);
447 if (i != 1000)
448 mpdm_hget_s(h, L"ok");
450 do_test("hget 1.2.1", mpdm_hget(h, MPDM_LS(L"ok")) != NULL);
452 mpdm_hset_s(h, L"ok", MPDM_I(777));
454 v = mpdm_hget_s(h, L"ok");
455 do_test("hget_s + hset_s", mpdm_ival(v) == 777);
457 mpdm_unref(h);
461 void test_splice(void)
463 mpdm_t w;
464 mpdm_t v;
466 w = mpdm_splice(MPDM_LS(L"I'm agent Johnson"), MPDM_LS(L"special "), 4, 0);
467 do_test("splice insertion",
468 mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm special agent Johnson")) == 0);
469 mpdm_dump(w);
471 w = mpdm_splice(MPDM_LS(L"Life is a shit"), MPDM_LS(L"cheat"), 10, 4);
472 do_test("splice insertion and deletion (1)",
473 mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"Life is a cheat")) == 0);
474 do_test("splice insertion and deletion (2)",
475 mpdm_cmp(mpdm_aget(w, 1), MPDM_LS(L"shit")) == 0);
476 mpdm_dump(w);
478 w = mpdm_splice(MPDM_LS(L"I'm with dumb"), NULL, 4, 4);
479 do_test("splice deletion (1)", mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm dumb")) == 0);
480 do_test("splice deletion (2)", mpdm_cmp(mpdm_aget(w, 1), MPDM_LS(L"with")) == 0);
481 mpdm_dump(w);
483 v = MPDM_LS(L"It doesn't matter");
484 w = mpdm_splice(v, MPDM_LS(L" two"), v->size, 0);
485 do_test("splice insertion at the end",
486 mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"It doesn't matter two")) == 0);
487 mpdm_dump(w);
489 w = mpdm_splice(NULL, NULL, 0, 0);
490 do_test("splice with two NULLS", (mpdm_aget(w, 0) == NULL));
492 w = mpdm_splice(NULL, MPDM_LS(L"foo"), 0, 0);
493 do_test("splice with first value NULL",
494 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"foo")) == 0));
496 w = mpdm_splice(MPDM_LS(L"foo"), NULL, 0, 0);
497 do_test("splice with second value NULL",
498 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"foo")) == 0));
500 v = MPDM_LS(L"I'm testing");
501 mpdm_ref(v);
503 w = mpdm_splice(v, NULL, 0, -1);
504 do_test("splice with negative del (1)",
505 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"")) == 0));
507 w = mpdm_splice(v, NULL, 4, -1);
508 do_test("splice with negative del (2)",
509 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm ")) == 0));
511 w = mpdm_splice(v, NULL, 4, -2);
512 do_test("splice with negative del (3)",
513 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm g")) == 0));
515 w = mpdm_splice(v, NULL, 0, -4);
516 do_test("splice with negative del (4)",
517 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"ing")) == 0));
518 mpdm_dump(mpdm_aget(w, 0));
520 w = mpdm_splice(v, NULL, 4, -20);
521 do_test("splice with out-of-bounds negative del",
522 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm testing")) == 0));
523 mpdm_unref(v);
527 void test_strcat(void)
529 mpdm_t v;
530 mpdm_t w;
532 w = MPDM_LS(L"something");
533 mpdm_ref(w);
535 v = mpdm_strcat(NULL, NULL);
536 do_test("mpdm_strcat(NULL, NULL) returns NULL", v == NULL);
538 v = mpdm_strcat(NULL, w);
539 do_test("mpdm_strcat(NULL, w) returns w", mpdm_cmp(v, w) == 0);
541 v = mpdm_strcat(w, NULL);
542 do_test("mpdm_strcat(w, NULL) returns w", mpdm_cmp(v, w) == 0);
543 mpdm_unref(w);
545 w = MPDM_LS(L"");
546 mpdm_ref(w);
547 v = mpdm_strcat(NULL, w);
548 do_test("mpdm_strcat(NULL, \"\") returns \"\"", mpdm_cmp(v, w) == 0);
550 v = mpdm_strcat(w, NULL);
551 do_test("mpdm_strcat(\"\", NULL) returns \"\"", mpdm_cmp(v, w) == 0);
553 v = mpdm_strcat(w, w);
554 do_test("mpdm_strcat(\"\", \"\") returns \"\"", mpdm_cmp(v, w) == 0);
556 mpdm_unref(w);
560 void test_split(void)
562 mpdm_t w;
564 printf("mpdm_split test\n\n");
566 w = mpdm_split(MPDM_S(L"."), MPDM_S(L"four.elems.in.string"));
567 mpdm_dump(w);
568 do_test("4 elems: ", (w->size == 4));
570 w = mpdm_split(MPDM_S(L"."), MPDM_S(L"unseparated string"));
571 mpdm_dump(w);
572 do_test("1 elem: ", (w->size == 1));
574 w = mpdm_split(MPDM_S(L"."), MPDM_S(L".dot.at start"));
575 mpdm_dump(w);
576 do_test("3 elems: ", (w->size == 3));
578 w = mpdm_split(MPDM_S(L"."), MPDM_S(L"dot.at end."));
579 mpdm_dump(w);
580 do_test("3 elems: ", (w->size == 3));
582 w = mpdm_split(MPDM_S(L"."), MPDM_S(L"three...dots (two empty elements)"));
583 mpdm_dump(w);
584 do_test("4 elems: ", (w->size == 4));
586 w = mpdm_split(MPDM_S(L"."), MPDM_S(L"."));
587 mpdm_dump(w);
588 do_test("2 elems: ", (w->size == 2));
590 w = mpdm_split(NULL, MPDM_S(L"I am the man"));
591 do_test("NULL split 1: ", mpdm_size(w) == 12);
592 do_test("NULL split 2: ", mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I")) == 0);
596 void test_join(void)
598 mpdm_t v;
599 mpdm_t s;
600 mpdm_t w;
602 printf("mpdm_join test\n\n");
604 /* separator */
605 s = mpdm_ref(MPDM_LS(L"--"));
607 w = MPDM_A(1);
608 mpdm_ref(w);
609 mpdm_aset(w, MPDM_S(L"ce"), 0);
611 v = mpdm_join(NULL, w);
612 do_test("1 elem, no separator", (mpdm_cmp(v, MPDM_LS(L"ce")) == 0));
614 v = mpdm_join(s, w);
615 do_test("1 elem, '--' separator", (mpdm_cmp(v, MPDM_LS(L"ce")) == 0));
617 mpdm_push(w, MPDM_LS(L"n'est"));
618 v = mpdm_join(s, w);
619 do_test("2 elems, '--' separator", (mpdm_cmp(v, MPDM_LS(L"ce--n'est")) == 0));
621 mpdm_push(w, MPDM_LS(L"pas"));
622 v = mpdm_join(s, w);
623 do_test("3 elems, '--' separator", (mpdm_cmp(v, MPDM_LS(L"ce--n'est--pas")) == 0));
625 v = mpdm_join(NULL, w);
626 do_test("3 elems, no separator", (mpdm_cmp(v, MPDM_LS(L"cen'estpas")) == 0));
628 mpdm_unref(w);
629 mpdm_unref(s);
633 static mpdm_t active(mpdm_t args)
635 return MPDM_H(0);
639 void test_sym(void)
641 mpdm_t v;
642 int i;
644 printf("mpdm_sset / mpdm_sget tests\n\n");
646 mpdm_sset(NULL, MPDM_LS(L"mp"), MPDM_H(7));
647 mpdm_sset(NULL, MPDM_LS(L"mp.config"), MPDM_H(7));
648 mpdm_sset(NULL, MPDM_LS(L"mp.config.auto_indent"), MPDM_I(16384));
649 mpdm_sset(NULL, MPDM_LS(L"mp.config.use_regex"), MPDM_I(1357));
650 mpdm_sset(NULL, MPDM_LS(L"mp.config.gtk_font_face"), MPDM_LS(L"profontwindows"));
651 mpdm_sset(NULL, MPDM_LS(L"mp.lines"), MPDM_A(2));
652 mpdm_sset(NULL, MPDM_LS(L"mp.lines.0"), MPDM_LS(L"First post!"));
653 mpdm_sset(NULL, MPDM_LS(L"mp.lines.1"), MPDM_LS(L"Second post!"));
654 mpdm_sset(NULL, MPDM_LS(L"mp.active"), MPDM_X(active));
655 mpdm_sset(NULL, MPDM_LS(L"mp.active.syntax"), NULL);
656 mpdm_dump(mpdm_root());
658 v = mpdm_sget(NULL, MPDM_LS(L"mp.config.auto_indent"));
659 i = mpdm_ival(v);
661 do_test("auto_indent == 16384", (i == 16384));
665 void test_file(void)
667 mpdm_t f;
668 mpdm_t v;
669 mpdm_t eol = MPDM_LS(L"\n");
671 mpdm_ref(eol);
673 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"w"));
675 if (f == NULL) {
676 printf("Can't create test.txt; no further file tests possible.\n");
677 return;
680 do_test("Create test.txt", f != NULL);
682 mpdm_write(f, MPDM_LS(L"0"));
683 mpdm_write(f, eol);
684 mpdm_write(f, MPDM_LS(L"1"));
685 mpdm_write(f, eol);
687 /* write WITHOUT eol */
688 mpdm_write(f, MPDM_LS(L"2"));
690 mpdm_close(f);
692 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r"));
694 do_test("test written file 0", mpdm_cmp(mpdm_read(f), MPDM_LS(L"0\n")) == 0);
695 do_test("test written file 1", mpdm_cmp(mpdm_read(f), MPDM_LS(L"1\n")) == 0);
696 do_test("test written file 2", mpdm_cmp(mpdm_read(f), MPDM_LS(L"2")) == 0);
697 do_test("test written file 3", mpdm_read(f) == NULL);
699 mpdm_close(f);
701 mpdm_unlink(MPDM_LS(L"test.txt"));
702 do_test("unlink", mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r")) == NULL);
704 v = mpdm_stat(MPDM_LS(L"stress.c"));
705 printf("Stat from stress.c:\n");
706 mpdm_dump(v);
708 /* v=mpdm_glob(MPDM_LS(L"*"));*/
709 printf("Glob:\n");
710 v = mpdm_glob(NULL, NULL);
711 mpdm_dump(v);
713 mpdm_unref(eol);
717 void test_regex(void)
719 mpdm_t v;
720 mpdm_t w;
722 v = mpdm_regex(MPDM_LS(L"/[0-9]+/"), MPDM_LS(L"123456"), 0);
723 do_test("regex 0", v != NULL);
725 v = mpdm_regex(MPDM_LS(L"/[0-9]+/"), MPDM_I(65536), 0);
726 do_test("regex 1", v != NULL);
728 v = mpdm_regex(MPDM_LS(L"/^[0-9]+$/"), MPDM_LS(L"12345678"), 0);
729 do_test("regex 2", v != NULL);
731 v = mpdm_regex(MPDM_LS(L"/^[0-9]+$/"), MPDM_I(1), 0);
732 do_test("regex 3", v != NULL);
734 v = mpdm_regex(MPDM_LS(L"/^[0-9]+$/"), MPDM_LS(L"A12345-678"), 0);
735 do_test("regex 4", v == NULL);
737 w = MPDM_LS(L"Hell street, 666");
738 mpdm_ref(w);
739 v = mpdm_regex(MPDM_LS(L"/[0-9]+/"), w, 0);
741 mpdm_dump(v);
743 do_test("regex 5", mpdm_cmp(v, MPDM_I(666)) == 0);
745 v = mpdm_regex(MPDM_LS(L"/regex/"), MPDM_LS(L"CASE-INSENSITIVE REGEX"), 0);
746 do_test("regex 6.1 (case sensitive)", v == NULL);
748 v = mpdm_regex(MPDM_LS(L"/regex/i"), MPDM_LS(L"CASE-INSENSITIVE REGEX"), 0);
749 do_test("regex 6.2 (case insensitive)", v != NULL);
751 v=mpdm_regex(MPDM_LS(L"/[A-Z]+/"), MPDM_LS(L"case SENSITIVE regex"), 0);
752 do_test("regex 6.3 (case sensitive)", mpdm_cmp(v, MPDM_LS(L"SENSITIVE")) == 0);
754 v = mpdm_regex(MPDM_LS(L"/^\\s*/"), MPDM_LS(L"123456"), 0);
755 do_test("regex 7", v != NULL);
757 v = mpdm_regex(MPDM_LS(L"/^\\s+/"), MPDM_LS(L"123456"), 0);
758 do_test("regex 8", v == NULL);
760 v = mpdm_regex(MPDM_LS(L"/^\\s+/"), NULL, 0);
761 do_test("regex 9 (NULL string to match)", v == NULL);
763 /* sregex */
765 v = mpdm_sregex(MPDM_LS(L"/A/"), MPDM_LS(L"change all A to A"), MPDM_LS(L"E"), 0);
766 do_test("sregex 0", mpdm_cmp(v, MPDM_LS(L"change all E to A")) == 0);
768 v = mpdm_sregex(MPDM_LS(L"/A/g"), MPDM_LS(L"change all A to A"), MPDM_LS(L"E"), 0);
769 do_test("sregex 1", mpdm_cmp(v, MPDM_LS(L"change all E to E")) == 0);
771 v = mpdm_sregex(MPDM_LS(L"/A+/g"), MPDM_LS(L"change all AAAAAA to E"),
772 MPDM_LS(L"E"), 0);
773 do_test("sregex 2", mpdm_cmp(v, MPDM_LS(L"change all E to E")) == 0);
775 v = mpdm_sregex(MPDM_LS(L"/A+/g"), MPDM_LS(L"change all A A A A A A to E"),
776 MPDM_LS(L"E"), 0);
777 do_test("sregex 3", mpdm_cmp(v, MPDM_LS(L"change all E E E E E E to E")) == 0);
779 v = mpdm_sregex(MPDM_LS(L"/A+/g"), MPDM_LS(L"change all AAA A AA AAAAA A AAA to E"),
780 MPDM_LS(L"E"), 0);
781 do_test("sregex 3.2", mpdm_cmp(v, MPDM_LS(L"change all E E E E E E to E")) == 0);
783 v = mpdm_sregex(MPDM_LS(L"/[0-9]+/g"), MPDM_LS(L"1, 20, 333, 40 all are numbers"),
784 MPDM_LS(L"numbers"), 0);
785 do_test("sregex 4",
786 mpdm_cmp(v,
787 MPDM_LS(L"numbers, numbers, numbers, numbers all are numbers")) == 0);
789 v = mpdm_sregex(MPDM_LS(L"/[a-zA-Z_]+/g"), MPDM_LS(L"regex, mpdm_regex, TexMex"),
790 MPDM_LS(L"sex"), 0);
791 do_test("sregex 5", mpdm_cmp(v, MPDM_LS(L"sex, sex, sex")) == 0);
793 v = mpdm_sregex(MPDM_LS(L"/[a-zA-Z]+/g"), MPDM_LS(L"regex, mpdm_regex, TexMex"),
794 NULL, 0);
795 do_test("sregex 6", mpdm_cmp(v, MPDM_LS(L", _, ")) == 0);
797 v = mpdm_sregex(MPDM_LS(L"/\\\\/g"), MPDM_LS(L"\\MSDOS\\style\\path"),
798 MPDM_LS(L"/"), 0);
799 do_test("sregex 7", mpdm_cmp(v, MPDM_LS(L"/MSDOS/style/path")) == 0);
801 v = mpdm_sregex(MPDM_LS(L"/regex/gi"), MPDM_LS(L"regex, Regex, REGEX"),
802 MPDM_LS(L"sex"), 0);
803 do_test("sregex 8", mpdm_cmp(v, MPDM_LS(L"sex, sex, sex")) == 0);
805 v = mpdm_sregex(NULL, NULL, NULL, 0);
806 do_test("Previous sregex substitutions must be 3", mpdm_ival(v) == 3);
808 /* & in substitution tests */
809 v = MPDM_LS(L"this string has many words");
810 v = mpdm_sregex(MPDM_LS(L"/[a-z]+/g"), v, MPDM_LS(L"[&]"), 0);
811 do_test("& in sregex target",
812 mpdm_cmp(v, MPDM_LS(L"[this] [string] [has] [many] [words]")) == 0);
814 v = MPDM_LS(L"this string has many words");
815 v = mpdm_sregex(MPDM_LS(L"/[a-z]+/g"), v, MPDM_LS(L"[\\&]"), 0);
816 do_test("escaped & in sregex target",
817 mpdm_cmp(v, MPDM_LS(L"[&] [&] [&] [&] [&]")) == 0);
819 v = MPDM_LS(L"this string has many words");
820 v = mpdm_sregex(MPDM_LS(L"/[a-z]+/g"), v, MPDM_LS(L"\\\\&"), 0);
821 do_test("escaped \\ in sregex target",
822 mpdm_cmp(v, MPDM_LS(L"\\this \\string \\has \\many \\words")) == 0);
824 v = MPDM_LS(L"hola ");
825 v = mpdm_sregex(MPDM_LS(L"/[ \t]$/"), v, MPDM_LS(L""), 0);
826 do_test("sregex output size 1", v->size == 4);
828 v = MPDM_LS(L"hola ");
829 v = mpdm_sregex(MPDM_LS(L"/[ \t]$/"), v, NULL, 0);
830 do_test("sregex output size 2", v->size == 4);
832 v = MPDM_LS(L"hola ");
833 v = mpdm_sregex(MPDM_LS(L"/[ \t]$/"), v, MPDM_LS(L"!"), 0);
834 do_test("sregex output size 3", v->size == 5);
836 v = MPDM_LS(L"holo");
837 v = mpdm_sregex(MPDM_LS(L"/o/g"), v, MPDM_LS(L"!!"), 0);
838 do_test("sregex output size 4", v->size == 6);
840 /* multiple regex tests */
841 w = MPDM_A(0);
842 mpdm_ref(w);
844 mpdm_push(w, MPDM_LS(L"/^[ \t]*/"));
845 mpdm_push(w, MPDM_LS(L"/[^ \t=]+/"));
846 mpdm_push(w, MPDM_LS(L"/[ \t]*=[ \t]*/"));
847 mpdm_push(w, MPDM_LS(L"/[^ \t]+/"));
848 mpdm_push(w, MPDM_LS(L"/[ \t]*$/"));
850 v = mpdm_regex(w, MPDM_LS(L"key=value"), 0);
851 mpdm_ref(v);
852 do_test("multi-regex 1.1", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"key")) == 0);
853 do_test("multi-regex 1.2", mpdm_cmp(mpdm_aget(v, 3), MPDM_LS(L"value")) == 0);
854 mpdm_unref(v);
856 v = mpdm_regex(w, MPDM_LS(L" key = value"), 0);
857 mpdm_ref(v);
858 do_test("multi-regex 2.1", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"key")) == 0);
859 do_test("multi-regex 2.2", mpdm_cmp(mpdm_aget(v, 3), MPDM_LS(L"value")) == 0);
860 mpdm_unref(v);
862 v = mpdm_regex(w, MPDM_LS(L"\t\tkey\t=\tvalue "), 0);
863 mpdm_ref(v);
864 do_test("multi-regex 3.1", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"key")) == 0);
865 do_test("multi-regex 3.2", mpdm_cmp(mpdm_aget(v, 3), MPDM_LS(L"value")) == 0);
866 mpdm_unref(v);
868 mpdm_unref(w);
870 /* v = mpdm_regex(w, MPDM_LS(L"key= "), 0);
871 do_test("multi-regex 4", v == NULL);
873 printf("Multiple line regexes\n");
874 w = MPDM_LS(L"/* this is\na C-like comment */");
875 mpdm_ref(w);
877 v = mpdm_regex(MPDM_LS(L"|/\\*.+\\*/|"), w, 0);
878 do_test("Multiline regex 1", mpdm_cmp(v, w) == 0);
880 v = mpdm_regex(MPDM_LS(L"/is$/"), w, 0);
881 do_test("Multiline regex 2", v == NULL);
883 v = mpdm_regex(MPDM_LS(L"/is$/m"), w, 0);
884 do_test("Multiline regex 3", mpdm_cmp(v, MPDM_LS(L"is")) == 0);
885 mpdm_unref(w);
887 printf("Pitfalls on multibyte locales (f.e. utf-8)\n");
889 w = MPDM_LS(L"-\x03a9-");
890 mpdm_ref(w);
892 v = mpdm_regex(MPDM_LS(L"/-$/"), w, 0);
893 do_test("Multibyte environment regex 1", mpdm_cmp(v, MPDM_LS(L"-")) == 0);
895 if (do_multibyte_sregex_tests) {
896 v = mpdm_sregex(MPDM_LS(L"/-$/"), w, MPDM_LS(L"~"), 0);
897 do_test("Multibyte environment sregex 1",
898 mpdm_cmp(v, MPDM_LS(L"-\x03a9~")) == 0);
900 v = mpdm_sregex(MPDM_LS(L"/-/g"), w, MPDM_LS(L"~"), 0);
901 do_test("Multibyte environment sregex 2",
902 mpdm_cmp(v, MPDM_LS(L"~\x03a9~")) == 0);
904 else
905 printf("Multibyte sregex test omitted; activate with -m\n");
907 mpdm_unref(w);
909 /* 'last' flag tests */
910 v = MPDM_LS(L"this string has many words");
911 v = mpdm_regex(MPDM_LS(L"/[a-z]+/l"), v, 0);
912 do_test("Flag l in mpdm_regex", mpdm_cmp(v, MPDM_LS(L"words")) == 0);
916 static mpdm_t dumper(mpdm_t args, mpdm_t ctxt)
917 /* executable value */
919 mpdm_dump(args);
920 return (NULL);
924 static mpdm_t sum(mpdm_t args, mpdm_t ctxt)
925 /* executable value: sum all args */
927 int n, t = 0;
929 if (args != NULL) {
930 for (n = t = 0; n < args->size; n++)
931 t += mpdm_ival(mpdm_aget(args, n));
934 return (MPDM_I(t));
938 static mpdm_t calculator(mpdm_t c, mpdm_t args, mpdm_t ctxt)
939 /* 3 argument version: calculator. c contains a 'script' to
940 do things with the arguments */
942 int n, t;
943 mpdm_t v;
944 mpdm_t a;
945 mpdm_t o;
947 mpdm_ref(args);
949 /* to avoid destroying args */
950 a = mpdm_ref(mpdm_clone(args));
952 /* shift first argument */
953 v = mpdm_shift(a);
954 t = mpdm_ival(v);
956 for (n = 0; n < mpdm_size(c); n++) {
957 /* gets operator */
958 o = mpdm_aget(c, n);
960 /* gets next value */
961 v = mpdm_shift(a);
963 switch (*(wchar_t *) o->data) {
964 case '+':
965 t += mpdm_ival(v);
966 break;
967 case '-':
968 t -= mpdm_ival(v);
969 break;
970 case '*':
971 t *= mpdm_ival(v);
972 break;
973 case '/':
974 t /= mpdm_ival(v);
975 break;
979 mpdm_unref(a);
980 mpdm_unref(args);
982 return (MPDM_I(t));
986 void test_exec(void)
988 mpdm_t x;
989 mpdm_t w;
990 mpdm_t p;
992 printf("test_exec\n");
994 x = MPDM_X(dumper);
996 /* a simple value */
997 mpdm_ref(x);
998 mpdm_exec(x, NULL, NULL);
999 mpdm_exec(x, x, NULL);
1000 mpdm_unref(x);
1002 x = mpdm_ref(MPDM_X(sum));
1003 w = mpdm_ref(MPDM_A(3));
1004 mpdm_aset(w, MPDM_I(100), 0);
1005 mpdm_aset(w, MPDM_I(220), 1);
1006 mpdm_aset(w, MPDM_I(333), 2);
1008 do_test("exec 0", mpdm_ival(mpdm_exec(x, w, NULL)) == 653);
1009 x = mpdm_unref(x);
1011 mpdm_push(w, MPDM_I(1));
1013 /* multiple executable value: vm and compiler support */
1015 /* calculator 'script' */
1016 p = mpdm_ref(MPDM_A(0));
1017 mpdm_push(p, MPDM_LS(L"+"));
1018 mpdm_push(p, MPDM_LS(L"-"));
1019 mpdm_push(p, MPDM_LS(L"+"));
1021 /* the value */
1022 x = mpdm_ref(MPDM_A(2));
1023 x->flags |= MPDM_EXEC;
1025 mpdm_aset(x, MPDM_X(calculator), 0);
1026 mpdm_aset(x, p, 1);
1028 do_test("exec 1", mpdm_ival(mpdm_exec(x, w, NULL)) == -12);
1030 mpdm_unref(p);
1032 /* another 'script', different operations with the same values */
1033 p = mpdm_ref(MPDM_A(0));
1034 mpdm_push(p, MPDM_LS(L"*"));
1035 mpdm_push(p, MPDM_LS(L"/"));
1036 mpdm_push(p, MPDM_LS(L"+"));
1038 mpdm_aset(x, p, 1);
1040 do_test("exec 2", mpdm_ival(mpdm_exec(x, w, NULL)) == 67);
1041 x = mpdm_unref(x);
1042 p = mpdm_unref(p);
1043 w = mpdm_unref(w);
1047 void test_encoding(void)
1049 mpdm_t f;
1050 mpdm_t v;
1051 mpdm_t w;
1052 const wchar_t *ptr;
1054 v = MPDM_MBS("?Espa?a!\n");
1055 mpdm_ref(v);
1057 printf("\nLocale encoding tests (will look bad if terminal is not ISO-8859-1)\n\n");
1059 if ((f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"w"))) == NULL) {
1060 printf("Can't write test.txt; no further file test possible.\n");
1061 return;
1064 mpdm_write(f, v);
1065 mpdm_close(f);
1067 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r"));
1068 w = mpdm_read(f);
1069 mpdm_dump(w);
1070 do_test("Locale encoding", mpdm_cmp(w, v) == 0);
1071 mpdm_close(f);
1073 printf
1074 ("\nutf8.txt loading (should look good only in UTF-8 terminals with good fonts)\n");
1076 f = mpdm_open(MPDM_LS(L"utf8.txt"), MPDM_LS(L"r"));
1077 w = mpdm_read(f);
1078 mpdm_dump(w);
1079 mpdm_close(f);
1081 for (ptr = w->data; *ptr != L'\0'; ptr++)
1082 printf("%d", mpdm_wcwidth(*ptr));
1083 printf("\n");
1085 if (mpdm_encoding(MPDM_LS(L"UTF-8")) < 0) {
1086 printf("No multiple encoding (iconv) support; no more tests possible.\n");
1087 return;
1090 printf
1091 ("\nForced utf8.txt loading (should look good only in UTF-8 terminals with good fonts)\n");
1093 f = mpdm_open(MPDM_LS(L"utf8.txt"), MPDM_LS(L"r"));
1094 w = mpdm_read(f);
1095 mpdm_dump(w);
1096 mpdm_close(f);
1098 /* new open file will use the specified encoding */
1099 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"w"));
1100 mpdm_write(f, v);
1101 mpdm_close(f);
1103 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r"));
1104 w = mpdm_read(f);
1105 mpdm_dump(w);
1106 do_test("iconv encoding", mpdm_cmp(w, v) == 0);
1107 mpdm_close(f);
1109 mpdm_encoding(NULL);
1110 mpdm_unref(v);
1114 void test_gettext(void)
1116 mpdm_t v;
1117 mpdm_t h;
1119 printf("\nTesting gettext...\n");
1121 mpdm_gettext_domain(MPDM_LS(L"stress"), MPDM_LS(L"./po"));
1123 printf("Should follow a translated string of 'This is a test string':\n");
1124 v = mpdm_gettext(MPDM_LS(L"This is a test string"));
1125 mpdm_dump(v);
1127 printf("The same, but cached:\n");
1128 v = mpdm_gettext(MPDM_LS(L"This is a test string"));
1129 mpdm_dump(v);
1131 v = mpdm_gettext(MPDM_LS(L"This string is not translated"));
1132 mpdm_dump(v);
1134 printf("Ad-hoc translation hash:\n");
1136 h = MPDM_H(0);
1137 mpdm_ref(h);
1138 mpdm_hset(h, MPDM_LS(L"test string"), MPDM_LS(L"cadena de prueba"));
1140 mpdm_gettext_domain(MPDM_LS(L"stress"), h);
1141 v = mpdm_gettext(MPDM_LS(L"test string"));
1142 mpdm_dump(v);
1143 mpdm_unref(h);
1147 void timer(int secs)
1149 static clock_t clks = 0;
1151 switch (secs) {
1152 case 0:
1153 clks = clock();
1154 break;
1156 case -1:
1157 printf("%.2f seconds\n", (float) (clock() - clks) / (float) CLOCKS_PER_SEC);
1158 break;
1163 void bench_hash(int i, mpdm_t l, int buckets)
1165 mpdm_t h;
1166 mpdm_t v;
1167 int n;
1169 printf("Hash of %d buckets: \n", buckets);
1170 h = MPDM_H(buckets);
1171 mpdm_ref(h);
1173 timer(0);
1174 for (n = 0; n < i; n++) {
1175 v = mpdm_aget(l, n);
1176 mpdm_hset(h, v, v);
1178 timer(-1);
1180 mpdm_unref(h);
1183 printf("Bucket usage:\n");
1184 for(n=0;n < mpdm_size(h);n++)
1185 printf("\t%d: %d\n", n, mpdm_size(mpdm_aget(h, n)));
1190 void benchmark(void)
1192 mpdm_t l;
1193 int i, n;
1194 char tmp[64];
1196 printf("\n");
1198 if (!do_benchmarks) {
1199 printf("Skipping benchmarks\nRun them with 'stress -b'\n");
1200 return;
1203 printf("BENCHMARKS\n");
1205 i = 500000;
1207 printf("Creating %d values...\n", i);
1209 l = mpdm_ref(MPDM_A(i));
1210 for (n = 0; n < i; n++) {
1211 sprintf(tmp, "%08x", n);
1212 /* mpdm_aset(l, MPDM_MBS(tmp), n);*/
1213 mpdm_aset(l, MPDM_I(n), n);
1216 printf("OK\n");
1218 bench_hash(i, l, 0);
1219 bench_hash(i, l, 61);
1220 bench_hash(i, l, 89);
1221 bench_hash(i, l, 127);
1223 mpdm_unref(l);
1227 void test_conversion(void)
1229 wchar_t *wptr = NULL;
1230 char *ptr = NULL;
1231 int size = 0;
1233 ptr = mpdm_wcstombs(L"", &size);
1234 do_test("mpdm_wcstombs converts an empty string", ptr != NULL);
1236 wptr = mpdm_mbstowcs("", &size, 0);
1237 do_test("mpdm_mbstowcs converts an empty string", wptr != NULL);
1241 void test_pipes(void)
1243 mpdm_t f;
1245 printf("\n");
1247 if ((f = mpdm_popen(MPDM_LS(L"date"), MPDM_LS(L"r"))) != NULL) {
1248 mpdm_t v;
1250 v = mpdm_read(f);
1251 mpdm_pclose(f);
1253 printf("Pipe from 'date':\n");
1254 mpdm_dump(v);
1256 else
1257 printf("Can't pipe to 'date'\n");
1261 void test_misc(void)
1263 printf("Home dir:\n");
1264 mpdm_dump(mpdm_home_dir());
1265 printf("App dir:\n");
1266 mpdm_dump(mpdm_app_dir());
1270 void test_sprintf(void)
1272 mpdm_t v;
1273 mpdm_t w;
1275 printf("sprintf tests\n");
1277 v = MPDM_A(0);
1278 mpdm_ref(v);
1279 mpdm_push(v, MPDM_I(100));
1280 mpdm_push(v, MPDM_LS(L"beers"));
1282 w = mpdm_sprintf(MPDM_LS(L"%d %s for me"), v);
1283 do_test("sprintf 1", mpdm_cmp(w, MPDM_LS(L"100 beers for me")) == 0);
1285 w = mpdm_sprintf(MPDM_LS(L"%d %s for me %d"), v);
1286 do_test("sprintf 2", mpdm_cmp(w, MPDM_LS(L"100 beers for me 0")) == 0);
1288 w = mpdm_sprintf(MPDM_LS(L"%10d %s for me"), v);
1289 do_test("sprintf 3", mpdm_cmp(w, MPDM_LS(L" 100 beers for me")) == 0);
1291 w = mpdm_sprintf(MPDM_LS(L"%010d %s for me"), v);
1292 do_test("sprintf 4", mpdm_cmp(w, MPDM_LS(L"0000000100 beers for me")) == 0);
1294 mpdm_unref(v);
1296 v = MPDM_A(0);
1297 mpdm_ref(v);
1298 mpdm_push(v, MPDM_R(3.1416));
1300 w = mpdm_sprintf(MPDM_LS(L"Value for PI is %6.4f"), v);
1301 do_test("sprintf 2.1", mpdm_cmp(w, MPDM_LS(L"Value for PI is 3.1416")) == 0);
1303 /* w = mpdm_sprintf(MPDM_LS(L"Value for PI is %08.2f"), v);
1304 do_test("sprintf 2.2", mpdm_cmp(w, MPDM_LS(L"Value for PI is 00003.14")) == 0);
1306 mpdm_unref(v);
1308 v = MPDM_A(0);
1309 mpdm_ref(v);
1310 mpdm_push(v, MPDM_LS(L"stress"));
1312 w = mpdm_sprintf(MPDM_LS(L"This is a |%10s| test"), v);
1313 do_test("sprintf 3.1", mpdm_cmp(w, MPDM_LS(L"This is a | stress| test")) == 0);
1315 w = mpdm_sprintf(MPDM_LS(L"This is a |%-10s| test"), v);
1316 do_test("sprintf 3.2", mpdm_cmp(w, MPDM_LS(L"This is a |stress | test")) == 0);
1318 mpdm_unref(v);
1320 v = MPDM_A(0);
1321 mpdm_ref(v);
1322 mpdm_push(v, MPDM_I(0x263a));
1324 w = mpdm_sprintf(MPDM_LS(L"%c"), v);
1325 do_test("sprintf 3.3", mpdm_cmp(w, MPDM_LS(L"\x263a")) == 0);
1326 mpdm_unref(v);
1328 v = MPDM_A(0);
1329 mpdm_ref(v);
1330 mpdm_push(v, MPDM_I(75));
1332 w = mpdm_sprintf(MPDM_LS(L"%d%%"), v);
1333 do_test("sprintf 4.1", mpdm_cmp(w, MPDM_LS(L"75%")) == 0);
1335 w = mpdm_sprintf(MPDM_LS(L"%b"), v);
1336 do_test("sprintf 5.1", mpdm_cmp(w, MPDM_LS(L"1001011")) == 0);
1337 mpdm_unref(v);
1341 void test_ulc(void)
1343 mpdm_t v = mpdm_ref(MPDM_S(L"string"));
1344 mpdm_t w = mpdm_ref(mpdm_ulc(v, 1));
1346 do_test("mpdm_ulc 1", mpdm_cmp(mpdm_ulc(v, 1), w) == 0);
1347 do_test("mpdm_ulc 2", mpdm_cmp(mpdm_ulc(w, 0), v) == 0);
1349 mpdm_unref(w);
1350 mpdm_unref(v);
1354 void test_scanf(void)
1356 mpdm_t v;
1358 v = mpdm_sscanf(MPDM_LS(L"%d %d"), MPDM_LS(L"1234 5678"), 0);
1359 do_test("mpdm_sscanf_1.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"1234")) == 0);
1360 do_test("mpdm_sscanf_1.2", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"5678")) == 0);
1362 v = mpdm_sscanf(MPDM_LS(L"%s %f %d"), MPDM_LS(L"this 12.34 5678"), 0);
1363 do_test("mpdm_sscanf_2.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"this")) == 0);
1364 do_test("mpdm_sscanf_2.2", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"12.34")) == 0);
1365 do_test("mpdm_sscanf_2.3", mpdm_cmp(mpdm_aget(v, 2), MPDM_LS(L"5678")) == 0);
1367 v = mpdm_sscanf(MPDM_LS(L"%s %*f %d"), MPDM_LS(L"this 12.34 5678"), 0);
1368 do_test("mpdm_sscanf_3.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"this")) == 0);
1369 do_test("mpdm_sscanf_3.2", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"5678")) == 0);
1371 v = mpdm_sscanf(MPDM_LS(L"%4d%4d%2d%10d"), MPDM_LS(L"12341234121234567890"), 0);
1372 do_test("mpdm_sscanf_4.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"1234")) == 0);
1373 do_test("mpdm_sscanf_4.2", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"1234")) == 0);
1374 do_test("mpdm_sscanf_4.3", mpdm_cmp(mpdm_aget(v, 2), MPDM_LS(L"12")) == 0);
1375 do_test("mpdm_sscanf_4.4", mpdm_cmp(mpdm_aget(v, 3), MPDM_LS(L"1234567890")) == 0);
1377 v = mpdm_sscanf(MPDM_LS(L"%[abc]%s"), MPDM_LS(L"ccbaabcxaaae and more"), 0);
1378 do_test("mpdm_sscanf_5.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"ccbaabc")) == 0);
1379 do_test("mpdm_sscanf_5.2", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"xaaae")) == 0);
1381 v = mpdm_sscanf(MPDM_LS(L"%[a-d]%s"), MPDM_LS(L"ccbaabcxaaae and more"), 0);
1382 do_test("mpdm_sscanf_6.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"ccbaabc")) == 0);
1383 do_test("mpdm_sscanf_6.2", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"xaaae")) == 0);
1385 v = mpdm_sscanf(MPDM_LS(L"%[^x]%s"), MPDM_LS(L"ccbaabcxaaae and more"), 0);
1386 do_test("mpdm_sscanf_7.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"ccbaabc")) == 0);
1387 do_test("mpdm_sscanf_7.2", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"xaaae")) == 0);
1389 v = mpdm_sscanf(MPDM_LS(L"%[^:]: %s"), MPDM_LS(L"key: value"), 0);
1390 do_test("mpdm_sscanf_8.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"key")) == 0);
1391 do_test("mpdm_sscanf_8.2", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"value")) == 0);
1393 v = mpdm_sscanf(MPDM_LS(L"%*[^/]/* %s */"), MPDM_LS(L"this is code /* comment */ more code"), 0);
1394 do_test("mpdm_sscanf_9.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"comment")) == 0);
1396 v = mpdm_sscanf(MPDM_LS(L"%d%%%d"), MPDM_LS(L"1234%5678"), 0);
1397 do_test("mpdm_sscanf_10.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"1234")) == 0);
1398 do_test("mpdm_sscanf_10.2", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"5678")) == 0);
1400 v = mpdm_sscanf(MPDM_LS(L"%*[abc]%n%*[^ ]%n"), MPDM_LS(L"ccbaabcxaaae and more"), 0);
1401 do_test("mpdm_sscanf_11.1", mpdm_ival(mpdm_aget(v, 0)) == 7);
1402 do_test("mpdm_sscanf_11.2", mpdm_ival(mpdm_aget(v, 1)) == 12);
1404 v = mpdm_sscanf(MPDM_LS(L"/* %S */"), MPDM_LS(L"/* inside the comment */"), 0);
1405 do_test("mpdm_sscanf_12.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"inside the comment")) == 0);
1407 v = mpdm_sscanf(MPDM_LS(L"/* %S */%s"), MPDM_LS(L"/* inside the comment */outside"), 0);
1408 do_test("mpdm_sscanf_13.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"inside the comment")) == 0);
1409 do_test("mpdm_sscanf_13.2", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"outside")) == 0);
1411 v = mpdm_sscanf(MPDM_LS(L"%n"), MPDM_LS(L""), 0);
1412 do_test("mpdm_sscanf_14.1", mpdm_size(v) == 1 && mpdm_ival(mpdm_aget(v, 0)) == 0);
1414 v = mpdm_sscanf(MPDM_LS(L"%[^%f]%f %[#%d@]"), MPDM_LS(L"this 12.34 5678#12@34"), 0);
1415 do_test("mpdm_sscanf_15.1", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"this ")) == 0);
1416 do_test("mpdm_sscanf_15.2", mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"12.34")) == 0);
1417 do_test("mpdm_sscanf_15.3", mpdm_cmp(mpdm_aget(v, 2), MPDM_LS(L"5678#12@34")) == 0);
1419 v = mpdm_sscanf(MPDM_LS(L"%*S\"%[^\n\"]\""), MPDM_LS(L"a \"bbb\" c;"), 0);
1420 do_test("mpdm_sscanf_16", mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"bbb")) == 0);
1422 do_test("mpdm_sscanf_17", mpdm_aget(v, 0)->size == 3);
1426 mpdm_t mutex = NULL;
1427 int t_finished = -1;
1429 mpdm_t the_thread(mpdm_t args, mpdm_t ctxt)
1430 /* running from a thread */
1432 mpdm_t fn = mpdm_ref(MPDM_LS(L"thread.txt"));
1433 mpdm_t f;
1435 printf("thread: start writing from thread\n");
1437 if ((f = mpdm_open(fn, MPDM_LS(L"w"))) != NULL) {
1438 int n;
1440 for (n = 0; n < 1000; n++) {
1441 mpdm_write(f, MPDM_I(n));
1442 mpdm_write(f, MPDM_LS(L"\n"));
1445 mpdm_close(f);
1448 printf("thread: finished writing from thread\n");
1450 mpdm_mutex_lock(mutex);
1451 t_finished = 1;
1452 mpdm_mutex_unlock(mutex);
1454 printf("thread: t_finished set\n");
1456 return NULL;
1460 void test_thread(void)
1462 mpdm_t fn = mpdm_ref(MPDM_LS(L"thread.txt"));
1463 mpdm_t x, v;
1464 int done;
1466 printf("Testing threads and mutexes...\n");
1468 mpdm_unlink(fn);
1470 /* create the executable value */
1471 x = mpdm_ref(MPDM_X(the_thread));
1473 /* create a mutex */
1474 mutex = mpdm_ref(mpdm_new_mutex());
1476 t_finished = 0;
1478 v = mpdm_exec_thread(x, NULL, NULL);
1480 printf("parent: waiting for the thread to finish...\n");
1481 mpdm_ref(v);
1483 done = 0;
1484 while (!done) {
1485 mpdm_sleep(10);
1487 mpdm_mutex_lock(mutex);
1489 if (t_finished > 0)
1490 done = 1;
1492 mpdm_mutex_unlock(mutex);
1495 printf("parent: thread said it has finished.\n");
1497 mpdm_unref(v);
1499 mpdm_unref(mutex);
1500 mpdm_unref(x);
1501 mpdm_unref(fn);
1505 mpdm_t sem = NULL;
1507 mpdm_t sem_thread(mpdm_t args, mpdm_t ctxt)
1509 printf("thread: waiting for semaphore...\n");
1511 mpdm_semaphore_wait(sem);
1513 printf("thread: got semaphore.\n");
1515 return NULL;
1519 void test_sem(void)
1521 mpdm_t x, v;
1523 printf("Testing threads and semaphores...\n");
1525 /* create the executable value */
1526 x = mpdm_ref(MPDM_X(sem_thread));
1528 /* creates the semaphore */
1529 sem = mpdm_ref(mpdm_new_semaphore(0));
1531 printf("parent: launching thread.\n");
1533 v = mpdm_exec_thread(x, NULL, NULL);
1534 mpdm_ref(v);
1536 mpdm_sleep(10);
1538 printf("parent: posting semaphore.\n");
1540 mpdm_semaphore_post(sem);
1542 mpdm_sleep(10);
1544 mpdm_unref(v);
1545 mpdm_unref(sem);
1546 mpdm_unref(x);
1550 void (*func)(void) = NULL;
1552 int main(int argc, char *argv[])
1554 if (argc > 1) {
1555 if (strcmp(argv[1], "-b") == 0)
1556 do_benchmarks = 1;
1557 if (strcmp(argv[1], "-m") == 0)
1558 do_multibyte_sregex_tests = 1;
1561 mpdm_startup();
1563 printf("sizeof(struct mpdm_val): %ld\n", (long) sizeof(struct mpdm_val));
1564 printf("sizeof(void *): %d\n", sizeof(void *));
1565 printf("sizeof(void (*func)(void)): %d\n", sizeof(func));
1567 /* test_counter();*/
1568 test_basic();
1569 test_array();
1570 test_hash();
1571 test_splice();
1572 test_strcat();
1573 test_split();
1574 test_join();
1575 test_sym();
1576 test_file();
1577 test_regex();
1578 test_exec();
1579 test_encoding();
1580 test_gettext();
1581 test_conversion();
1582 test_pipes();
1583 test_misc();
1584 test_sprintf();
1585 test_ulc();
1586 test_scanf();
1587 test_thread();
1588 test_sem();
1590 benchmark();
1592 mpdm_shutdown();
1594 printf("\n*** Total tests passed: %d/%d\n", oks, tests);
1596 if (oks == tests)
1597 printf("*** ALL TESTS PASSED\n");
1598 else {
1599 int n;
1601 printf("*** %d %s\n", tests - oks, "TESTS ---FAILED---");
1603 printf("\nFailed tests:\n\n");
1604 for (n = 0; n < i_failed_msgs; n++)
1605 printf("%s", failed_msgs[n]);
1608 return (0);