Fixes and tweaks to please clang's static analyzer.
[mpdm.git] / stress.c
blob66f7cec32e184e48f6b66104505c7112731af7db
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 ***",
53 src_line);
54 printf("%s", tmp);
56 tests++;
58 if (ok)
59 oks++;
60 else
61 failed_msgs[i_failed_msgs++] = strdup(tmp);
64 #define do_test(str, ok) _do_test(str, ok, __LINE__)
66 #define C { int CC = mpdm->count
67 #define T(i) do_test("v counter", CC + i == mpdm->count); }
69 /** tests **/
71 void test_counter(void)
73 mpdm_t v, w;
76 v = MPDM_S(L"hi");
77 T(1);
80 w = MPDM_A(0);
81 T(1);
84 mpdm_push(w, v);
85 T(0);
88 mpdm_adel(w, 0);
89 T(0); /* should fail in 2.x */
92 mpdm_queue(w, v, 10);
93 T(0);
96 v = MPDM_S(L"this is a phrase");
97 T(1);
99 w = mpdm_split_s(v, L" ");
100 T(5);
104 void test_basic(void)
106 int i;
107 double r;
108 mpdm_t v;
109 mpdm_t w;
110 mpdm_t t;
112 v = mpdm_ref(MPDM_S(L"65536"));
113 mpdm_dump(v);
114 i = mpdm_ival(v);
115 r = mpdm_rval(v);
117 do_test("i == 65536", (i == 65536));
118 do_test("r == 65536", (r == 65536));
119 do_test("v has MPDM_IVAL", (v->flags & MPDM_IVAL));
121 r = mpdm_rval(v);
122 do_test("r == 65536", (r == 65536.0));
123 do_test("v has MPDM_RVAL", (v->flags & MPDM_RVAL));
125 mpdm_unref(v);
127 printf("mpdm_string: %ls\n", mpdm_string(MPDM_H(0)));
128 printf("mpdm_string: %ls\n", mpdm_string(MPDM_H(0)));
130 /* partial copies of strings */
131 v = MPDM_LS(L"this is not America");
132 v = MPDM_NS((wchar_t *) v->data + 4, 4);
134 do_test("Partial string values", mpdm_cmp(v, MPDM_LS(L" is ")) == 0);
136 v = mpdm_ref(MPDM_S(L"MUAHAHAHA!"));
137 w = mpdm_ref(mpdm_clone(v));
138 do_test("Testing mpdm_clone semantics 1", w == v);
139 mpdm_unref(v);
140 mpdm_unref(w);
142 v = mpdm_ref(MPDM_A(2));
143 mpdm_aset(v, MPDM_S(L"evil"), 0);
144 mpdm_aset(v, MPDM_S(L"dead"), 1);
145 w = mpdm_ref(mpdm_clone(v));
147 do_test("Testing mpdm_clone semantics 2.1", w != v);
149 t = mpdm_aget(v, 0);
150 do_test("Testing mpdm_clone semantics 2.2", t->ref > 1);
151 do_test("Testing mpdm_clone semantics 2.3", mpdm_aget(w, 0) == t);
153 mpdm_unref(w);
154 mpdm_unref(v);
156 /* mbs / wcs tests */
157 v = MPDM_MBS("This is (was) a multibyte string");
158 mpdm_dump(v);
160 /* greek omega is 03a9 */
161 v = MPDM_MBS("?Espa?a! (non-ASCII string, as ISO-8859-1 char *)");
162 mpdm_dump(v);
163 printf
164 ("(Previous value will be NULL if locale doesn't match stress.c encoding)\n");
166 v = MPDM_LS(L"A capital greek omega between brackets [\x03a9]");
167 mpdm_dump(v);
168 printf("(Previous value will only show on an Unicode terminal)\n");
170 v = mpdm_ref(MPDM_R(3.1416));
171 mpdm_dump(v);
172 do_test("rval 1", mpdm_rval(v) == 3.1416);
173 do_test("ival 1", mpdm_ival(v) == 3);
174 mpdm_unref(v);
176 v = MPDM_R(777777.0 / 2.0);
177 mpdm_dump(v);
178 do_test("mpdm_rnew 1", mpdm_cmp(v, MPDM_LS(L"388888.5")) == 0);
180 v = MPDM_R(388888.500);
181 mpdm_dump(v);
182 do_test("mpdm_rnew 2", mpdm_cmp(v, MPDM_LS(L"388888.5")) == 0);
184 v = MPDM_R(388888.412);
185 mpdm_dump(v);
186 do_test("mpdm_rnew 3", mpdm_cmp(v, MPDM_LS(L"388888.412")) == 0);
188 v = MPDM_R(388888.6543);
189 mpdm_dump(v);
190 do_test("mpdm_rnew 4", mpdm_cmp(v, MPDM_LS(L"388888.6543")) == 0);
192 v = MPDM_R(388888.0);
193 mpdm_dump(v);
194 do_test("mpdm_rnew 5", mpdm_cmp(v, MPDM_LS(L"388888")) == 0);
196 v = MPDM_R(0.050000);
197 mpdm_dump(v);
198 do_test("mpdm_rnew 6", mpdm_cmp(v, MPDM_LS(L"0.05")) == 0);
200 v = MPDM_R(0.000);
201 mpdm_dump(v);
202 do_test("mpdm_rnew 7", mpdm_cmp(v, MPDM_LS(L"0")) == 0);
204 v = MPDM_LS(L"0177");
205 do_test("mpdm_ival() for octal numbers", mpdm_ival(v) == 0x7f);
207 v = MPDM_LS(L"0xFF");
208 do_test("mpdm_ival() for hexadecimal numbers", mpdm_ival(v) == 255);
210 v = MPDM_LS(L"001");
211 do_test("mpdm_rval() for octal numbers", mpdm_rval(v) == 1.0);
213 v = MPDM_LS(L"0x7f");
214 do_test("mpdm_rval() for hexadecimal numbers", mpdm_rval(v) == 127.0);
216 do_test("Two NULLs are equal", mpdm_cmp(NULL, NULL) == 0);
218 v = MPDM_LS(L"hahaha");
219 mpdm_ref(v);
220 do_test("mpdm_cmp_s 1", mpdm_cmp_s(v, L"hahaha") == 0);
221 do_test("mpdm_cmp_s 2", mpdm_cmp_s(v, L"aahaha") > 0);
222 do_test("mpdm_cmp_s 3", mpdm_cmp_s(v, L"zahaha") < 0);
223 mpdm_unref(v);
226 mpdm_t sort_cb(mpdm_t args)
228 int d;
230 /* sorts reversely */
231 d = mpdm_cmp(mpdm_aget(args, 1), mpdm_aget(args, 0));
232 return (MPDM_I(d));
236 void test_array(void)
238 int n;
239 mpdm_t a;
240 mpdm_t v;
242 a = MPDM_A(0);
243 mpdm_ref(a);
245 do_test("a->size == 0", (a->size == 0));
247 mpdm_push(a, MPDM_LS(L"sunday"));
248 mpdm_push(a, MPDM_LS(L"monday"));
249 mpdm_push(a, MPDM_LS(L"tuesday"));
250 mpdm_push(a, MPDM_LS(L"wednesday"));
251 mpdm_push(a, MPDM_LS(L"thursday"));
252 mpdm_push(a, MPDM_LS(L"friday"));
253 mpdm_push(a, MPDM_LS(L"saturday"));
254 mpdm_dump(a);
255 do_test("a->size == 7", (a->size == 7));
257 v = mpdm_aget(a, 3);
258 mpdm_ref(v);
259 mpdm_aset(a, NULL, 3);
260 mpdm_dump(a);
262 mpdm_sort(a, 1);
263 do_test("NULLs are sorted on top", (mpdm_aget(a, 0) == NULL));
265 mpdm_aset(a, v, 0);
266 mpdm_unref(v);
268 v = mpdm_aget(a, 3);
269 do_test("v is referenced again", (v != NULL && v->ref > 0));
271 mpdm_sort(a, 1);
272 do_test("mpdm_asort() works (1)",
273 mpdm_cmp(mpdm_aget(a, 0), MPDM_LS(L"friday")) == 0);
274 do_test("mpdm_asort() works (2)",
275 mpdm_cmp(mpdm_aget(a, 6), MPDM_LS(L"wednesday")) == 0);
277 /* asort_cb sorts reversely */
278 mpdm_sort_cb(a, 1, MPDM_X(sort_cb));
280 do_test("mpdm_asort_cb() works (1)",
281 mpdm_cmp(mpdm_aget(a, 6), MPDM_LS(L"friday")) == 0);
282 do_test("mpdm_asort_cb() works (2)",
283 mpdm_cmp(mpdm_aget(a, 0), MPDM_LS(L"wednesday")) == 0);
285 v = mpdm_aget(a, 3);
286 mpdm_ref(v);
287 n = v->ref;
288 mpdm_collapse(a, 3, 1);
289 do_test("acollapse unrefs values", (v->ref < n));
290 mpdm_unref(v);
292 mpdm_unref(a);
294 /* test queues */
295 a = MPDM_A(0);
296 mpdm_ref(a);
298 /* add several values */
299 for (n = 0; n < 10; n++)
300 v = mpdm_queue(a, MPDM_I(n), 10);
302 do_test("queue should still output NULL", (v == NULL));
304 v = mpdm_queue(a, MPDM_I(11), 10);
305 do_test("queue should no longer output NULL", (v != NULL));
307 v = mpdm_queue(a, MPDM_I(12), 10);
308 do_test("queue should return 1", mpdm_ival(v) == 1);
309 v = mpdm_queue(a, MPDM_I(13), 10);
310 do_test("queue should return 2", mpdm_ival(v) == 2);
311 do_test("queue size should be 10", a->size == 10);
313 mpdm_dump(a);
314 v = mpdm_queue(a, MPDM_I(14), 5);
315 mpdm_dump(a);
317 do_test("queue size should be 5", a->size == 5);
318 do_test("last taken value should be 8", mpdm_ival(v) == 8);
319 mpdm_unref(a);
321 a = MPDM_A(4);
322 mpdm_ref(a);
323 mpdm_aset(a, MPDM_I(666), 6000);
325 do_test("array should have been automatically expanded",
326 mpdm_size(a) == 6001);
328 v = mpdm_aget(a, -1);
329 do_test("negative offsets in arrays 1", mpdm_ival(v) == 666);
331 mpdm_aset(a, MPDM_I(777), -2);
332 v = mpdm_aget(a, 5999);
333 do_test("negative offsets in arrays 2", mpdm_ival(v) == 777);
335 mpdm_push(a, MPDM_I(888));
336 v = mpdm_aget(a, -1);
337 do_test("negative offsets in arrays 3", mpdm_ival(v) == 888);
339 v = MPDM_A(0);
340 mpdm_ref(v);
341 mpdm_push(v, MPDM_I(100));
342 mpdm_pop(v);
343 mpdm_unref(v);
345 mpdm_unref(a);
347 /* array comparisons with mpdm_cmp() */
348 a = MPDM_A(2);
349 mpdm_ref(a);
350 mpdm_aset(a, MPDM_I(10), 0);
351 mpdm_aset(a, MPDM_I(60), 1);
353 v = mpdm_ref(mpdm_clone(a));
354 do_test("mpdm_cmp: array clones are equal", mpdm_cmp(a, v) == 0);
356 mpdm_adel(v, -1);
357 do_test("mpdm_cmp: shorter arrays are lesser", mpdm_cmp(a, v) > 0);
359 mpdm_push(v, MPDM_I(80));
360 do_test("mpdm_cmp: 2# element is bigger, so array is bigger",
361 mpdm_cmp(a, v) < 0);
363 mpdm_unref(v);
364 mpdm_unref(a);
368 void test_hash(void)
370 mpdm_t h;
371 mpdm_t v;
372 int i, n;
374 h = MPDM_H(0);
375 mpdm_ref(h);
377 do_test("hsize 1", mpdm_hsize(h) == 0);
379 mpdm_hset(h, MPDM_S(L"mp"), MPDM_I(6));
380 v = mpdm_hget(h, MPDM_S(L"mp"));
382 do_test("hsize 2", mpdm_hsize(h) == 1);
384 do_test("hash: v != NULL", (v != NULL));
385 i = mpdm_ival(v);
386 do_test("hash: v == 6", (i == 6));
388 mpdm_hset(h, MPDM_S(L"mp2"), MPDM_I(66));
389 v = mpdm_hget(h, MPDM_S(L"mp2"));
391 do_test("hsize 3", mpdm_hsize(h) == 2);
393 do_test("hash: v != NULL", (v != NULL));
394 i = mpdm_ival(v);
395 do_test("hash: v == 66", (i == 66));
397 /* fills 100 values */
398 for (n = 0; n < 50; n++)
399 mpdm_hset(h, MPDM_I(n), MPDM_I(n * 10));
400 for (n = 100; n >= 50; n--)
401 mpdm_hset(h, MPDM_I(n), MPDM_I(n * 10));
403 do_test("hsize 4", mpdm_hsize(h) == 103);
405 /* tests 100 values */
406 for (n = 0; n < 100; n++) {
407 v = mpdm_hget(h, MPDM_I(n));
409 if (v != NULL) {
410 i = mpdm_ival(v);
411 if (!(i == n * 10))
412 do_test("hash: ival", (i == n * 10));
414 else
415 do_test("hash: hget", (v != NULL));
418 printf("h's size: %d\n", mpdm_hsize(h));
420 mpdm_hdel(h, MPDM_LS(L"mp"));
421 do_test("hsize 5", mpdm_hsize(h) == 102);
423 mpdm_unref(h);
426 mpdm_dump(h);
428 v=mpdm_hkeys(h);
429 mpdm_dump(v);
431 /* use of non-strings as hashes */
432 h = MPDM_H(0);
433 mpdm_ref(h);
435 v = MPDM_A(0);
436 mpdm_hset(h, v, MPDM_I(1234));
437 v = MPDM_H(0);
438 mpdm_hset(h, v, MPDM_I(12345));
439 v = MPDM_H(0);
440 mpdm_hset(h, v, MPDM_I(9876));
441 v = MPDM_A(0);
442 mpdm_ref(v);
443 mpdm_hset(h, v, MPDM_I(6543));
444 i = mpdm_ival(mpdm_hget(h, v));
445 mpdm_unref(v);
447 mpdm_dump(h);
448 do_test("hash: using non-strings as hash keys", (i == 6543));
450 mpdm_hset(h, MPDM_LS(L"ok"), MPDM_I(666));
452 do_test("exists 1", mpdm_exists(h, MPDM_LS(L"ok")));
453 do_test("exists 2", !mpdm_exists(h, MPDM_LS(L"notok")));
455 mpdm_dump(h);
456 v = mpdm_hget_s(h, L"ok");
457 printf("v %s\n", v == NULL ? "is NULL" : "is NOT NULL");
458 do_test("hget_s 1", mpdm_ival(v) == 666);
459 mpdm_dump(v);
460 mpdm_dump(h);
462 i = 0;
463 for (n = 0; n < 1000; n++) {
464 if (mpdm_hget_s(h, L"ok") != NULL)
465 i++;
467 printf("i: %d\n", i);
468 do_test("hget_s 1.2", i == 1000);
470 if (i != 1000)
471 mpdm_hget_s(h, L"ok");
473 do_test("hget 1.2.1", mpdm_hget(h, MPDM_LS(L"ok")) != NULL);
475 mpdm_hset_s(h, L"ok", MPDM_I(777));
477 v = mpdm_hget_s(h, L"ok");
478 do_test("hget_s + hset_s", mpdm_ival(v) == 777);
480 mpdm_unref(h);
484 void test_splice(void)
486 mpdm_t w;
487 mpdm_t v;
489 w = mpdm_splice(MPDM_LS(L"I'm agent Johnson"), MPDM_LS(L"special "), 4,
491 do_test("splice insertion",
492 mpdm_cmp(mpdm_aget(w, 0),
493 MPDM_LS(L"I'm special agent Johnson")) == 0);
494 mpdm_dump(w);
496 w = mpdm_splice(MPDM_LS(L"Life is a shit"), MPDM_LS(L"cheat"), 10, 4);
497 do_test("splice insertion and deletion (1)",
498 mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"Life is a cheat")) == 0);
499 do_test("splice insertion and deletion (2)",
500 mpdm_cmp(mpdm_aget(w, 1), MPDM_LS(L"shit")) == 0);
501 mpdm_dump(w);
503 w = mpdm_splice(MPDM_LS(L"I'm with dumb"), NULL, 4, 4);
504 do_test("splice deletion (1)",
505 mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm dumb")) == 0);
506 do_test("splice deletion (2)",
507 mpdm_cmp(mpdm_aget(w, 1), MPDM_LS(L"with")) == 0);
508 mpdm_dump(w);
510 v = MPDM_LS(L"It doesn't matter");
511 w = mpdm_splice(v, MPDM_LS(L" two"), v->size, 0);
512 do_test("splice insertion at the end",
513 mpdm_cmp(mpdm_aget(w, 0),
514 MPDM_LS(L"It doesn't matter two")) == 0);
515 mpdm_dump(w);
517 w = mpdm_splice(NULL, NULL, 0, 0);
518 do_test("splice with two NULLS", (mpdm_aget(w, 0) == NULL));
520 w = mpdm_splice(NULL, MPDM_LS(L"foo"), 0, 0);
521 do_test("splice with first value NULL",
522 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"foo")) == 0));
524 w = mpdm_splice(MPDM_LS(L"foo"), NULL, 0, 0);
525 do_test("splice with second value NULL",
526 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"foo")) == 0));
528 v = MPDM_LS(L"I'm testing");
529 mpdm_ref(v);
531 w = mpdm_splice(v, NULL, 0, -1);
532 do_test("splice with negative del (1)",
533 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"")) == 0));
535 w = mpdm_splice(v, NULL, 4, -1);
536 do_test("splice with negative del (2)",
537 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm ")) == 0));
539 w = mpdm_splice(v, NULL, 4, -2);
540 do_test("splice with negative del (3)",
541 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm g")) == 0));
543 w = mpdm_splice(v, NULL, 0, -4);
544 do_test("splice with negative del (4)",
545 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"ing")) == 0));
546 mpdm_dump(mpdm_aget(w, 0));
548 w = mpdm_splice(v, NULL, 4, -20);
549 do_test("splice with out-of-bounds negative del",
550 (mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I'm testing")) == 0));
551 mpdm_unref(v);
555 void test_strcat(void)
557 mpdm_t v;
558 mpdm_t w;
560 w = MPDM_LS(L"something");
561 mpdm_ref(w);
563 v = mpdm_strcat(NULL, NULL);
564 do_test("mpdm_strcat(NULL, NULL) returns NULL", v == NULL);
566 v = mpdm_strcat(NULL, w);
567 do_test("mpdm_strcat(NULL, w) returns w", mpdm_cmp(v, w) == 0);
569 v = mpdm_strcat(w, NULL);
570 do_test("mpdm_strcat(w, NULL) returns w", mpdm_cmp(v, w) == 0);
571 mpdm_unref(w);
573 w = MPDM_LS(L"");
574 mpdm_ref(w);
575 v = mpdm_strcat(NULL, w);
576 do_test("mpdm_strcat(NULL, \"\") returns \"\"", mpdm_cmp(v, w) == 0);
578 v = mpdm_strcat(w, NULL);
579 do_test("mpdm_strcat(\"\", NULL) returns \"\"", mpdm_cmp(v, w) == 0);
581 v = mpdm_strcat(w, w);
582 do_test("mpdm_strcat(\"\", \"\") returns \"\"", mpdm_cmp(v, w) == 0);
584 mpdm_unref(w);
588 void test_split(void)
590 mpdm_t w;
592 printf("mpdm_split test\n\n");
594 w = mpdm_split(MPDM_S(L"four.elems.in.string"), MPDM_S(L"."));
595 mpdm_dump(w);
596 do_test("4 elems: ", (w->size == 4));
598 w = mpdm_split(MPDM_S(L"unseparated string"), MPDM_S(L"."));
599 mpdm_dump(w);
600 do_test("1 elem: ", (w->size == 1));
602 w = mpdm_split(MPDM_S(L".dot.at start"), MPDM_S(L"."));
603 mpdm_dump(w);
604 do_test("3 elems: ", (w->size == 3));
606 w = mpdm_split(MPDM_S(L"dot.at end."), MPDM_S(L"."));
607 mpdm_dump(w);
608 do_test("3 elems: ", (w->size == 3));
610 w = mpdm_split(MPDM_S(L"three...dots (two empty elements)"), MPDM_S(L"."));
611 mpdm_dump(w);
612 do_test("4 elems: ", (w->size == 4));
614 w = mpdm_split(MPDM_S(L"."), MPDM_S(L"."));
615 mpdm_dump(w);
616 do_test("2 elems: ", (w->size == 2));
618 w = mpdm_split(MPDM_S(L"I am the man"), NULL);
619 do_test("NULL split 1: ", mpdm_size(w) == 12);
620 do_test("NULL split 2: ",
621 mpdm_cmp(mpdm_aget(w, 0), MPDM_LS(L"I")) == 0);
625 void test_join(void)
627 mpdm_t v;
628 mpdm_t s;
629 mpdm_t w;
631 printf("mpdm_join test\n\n");
633 /* separator */
634 s = mpdm_ref(MPDM_LS(L"--"));
636 w = MPDM_A(1);
637 mpdm_ref(w);
638 mpdm_aset(w, MPDM_S(L"ce"), 0);
640 v = mpdm_join(w, NULL);
641 do_test("1 elem, no separator", (mpdm_cmp(v, MPDM_LS(L"ce")) == 0));
643 v = mpdm_join(w, s);
644 do_test("1 elem, '--' separator", (mpdm_cmp(v, MPDM_LS(L"ce")) == 0));
646 mpdm_push(w, MPDM_LS(L"n'est"));
647 v = mpdm_join(w, s);
648 do_test("2 elems, '--' separator",
649 (mpdm_cmp(v, MPDM_LS(L"ce--n'est")) == 0));
651 mpdm_push(w, MPDM_LS(L"pas"));
652 v = mpdm_join(w, s);
653 do_test("3 elems, '--' separator",
654 (mpdm_cmp(v, MPDM_LS(L"ce--n'est--pas")) == 0));
656 v = mpdm_join(w, NULL);
657 do_test("3 elems, no separator",
658 (mpdm_cmp(v, MPDM_LS(L"cen'estpas")) == 0));
660 mpdm_unref(w);
661 mpdm_unref(s);
665 static mpdm_t active(mpdm_t args)
667 return MPDM_H(0);
671 void test_sym(void)
673 mpdm_t v;
674 int i;
676 printf("mpdm_sset / mpdm_sget tests\n\n");
678 mpdm_sset(NULL, MPDM_LS(L"mp"), MPDM_H(7));
679 mpdm_sset(NULL, MPDM_LS(L"mp.config"), MPDM_H(7));
680 mpdm_sset(NULL, MPDM_LS(L"mp.config.auto_indent"), MPDM_I(16384));
681 mpdm_sset(NULL, MPDM_LS(L"mp.config.use_regex"), MPDM_I(1357));
682 mpdm_sset(NULL, MPDM_LS(L"mp.config.gtk_font_face"),
683 MPDM_LS(L"profontwindows"));
684 mpdm_sset(NULL, MPDM_LS(L"mp.lines"), MPDM_A(2));
685 mpdm_sset(NULL, MPDM_LS(L"mp.lines.0"), MPDM_LS(L"First post!"));
686 mpdm_sset(NULL, MPDM_LS(L"mp.lines.1"), MPDM_LS(L"Second post!"));
687 mpdm_sset(NULL, MPDM_LS(L"mp.active"), MPDM_X(active));
688 mpdm_sset(NULL, MPDM_LS(L"mp.active.syntax"), NULL);
689 mpdm_dump(mpdm_root());
691 v = mpdm_sget(NULL, MPDM_LS(L"mp.config.auto_indent"));
692 i = mpdm_ival(v);
694 do_test("auto_indent == 16384", (i == 16384));
698 void test_file(void)
700 mpdm_t f;
701 mpdm_t v;
702 mpdm_t eol = MPDM_LS(L"\n");
704 mpdm_ref(eol);
706 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"w"));
708 if (f == NULL) {
709 printf("Can't create test.txt; no further file tests possible.\n");
710 return;
713 do_test("Create test.txt", f != NULL);
715 mpdm_write(f, MPDM_LS(L"0"));
716 mpdm_write(f, eol);
717 mpdm_write(f, MPDM_LS(L"1"));
718 mpdm_write(f, eol);
720 /* write WITHOUT eol */
721 mpdm_write(f, MPDM_LS(L"2"));
723 mpdm_close(f);
725 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r"));
727 do_test("test written file 0",
728 mpdm_cmp(mpdm_read(f), MPDM_LS(L"0\n")) == 0);
729 do_test("test written file 1",
730 mpdm_cmp(mpdm_read(f), MPDM_LS(L"1\n")) == 0);
731 do_test("test written file 2",
732 mpdm_cmp(mpdm_read(f), MPDM_LS(L"2")) == 0);
733 do_test("test written file 3", mpdm_read(f) == NULL);
735 mpdm_close(f);
737 mpdm_unlink(MPDM_LS(L"test.txt"));
738 do_test("unlink",
739 mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r")) == NULL);
741 v = mpdm_stat(MPDM_LS(L"stress.c"));
742 printf("Stat from stress.c:\n");
743 mpdm_dump(v);
745 /* v=mpdm_glob(MPDM_LS(L"*"));*/
746 printf("Glob:\n");
747 v = mpdm_glob(NULL, NULL);
748 mpdm_dump(v);
750 mpdm_unref(eol);
754 void test_regex(void)
756 mpdm_t v;
757 mpdm_t w;
759 v = mpdm_regex(MPDM_LS(L"123456"), MPDM_LS(L"/[0-9]+/"), 0);
760 do_test("regex 0", v != NULL);
762 v = mpdm_regex(MPDM_I(65536), MPDM_LS(L"/[0-9]+/"), 0);
763 do_test("regex 1", v != NULL);
765 v = mpdm_regex(MPDM_LS(L"12345678"), MPDM_LS(L"/^[0-9]+$/"), 0);
766 do_test("regex 2", v != NULL);
768 v = mpdm_regex(MPDM_I(1), MPDM_LS(L"/^[0-9]+$/"), 0);
769 do_test("regex 3", v != NULL);
771 v = mpdm_regex(MPDM_LS(L"A12345-678"), MPDM_LS(L"/^[0-9]+$/"), 0);
772 do_test("regex 4", v == NULL);
774 w = MPDM_LS(L"Hell street, 666");
775 mpdm_ref(w);
776 v = mpdm_regex(w, MPDM_LS(L"/[0-9]+/"), 0);
778 mpdm_dump(v);
780 do_test("regex 5", mpdm_cmp(v, MPDM_I(666)) == 0);
782 v = mpdm_regex(MPDM_LS(L"CASE-INSENSITIVE REGEX"), MPDM_LS(L"/regex/"),
784 do_test("regex 6.1 (case sensitive)", v == NULL);
786 v = mpdm_regex(MPDM_LS(L"CASE-INSENSITIVE REGEX"),
787 MPDM_LS(L"/regex/i"),
789 do_test("regex 6.2 (case insensitive)", v != NULL);
791 v=mpdm_regex(MPDM_LS(L"/[A-Z]+/"), MPDM_LS(L"case SENSITIVE regex"), 0);
792 do_test("regex 6.3 (case sensitive)", mpdm_cmp(v, MPDM_LS(L"SENSITIVE")) == 0);
794 v = mpdm_regex(MPDM_LS(L"123456"), MPDM_LS(L"/^\\s*/"), 0);
795 do_test("regex 7", v != NULL);
797 v = mpdm_regex(MPDM_LS(L"123456"), MPDM_LS(L"/^\\s+/"), 0);
798 do_test("regex 8", v == NULL);
800 v = mpdm_regex(NULL, MPDM_LS(L"/^\\s+/"), 0);
801 do_test("regex 9 (NULL string to match)", v == NULL);
803 /* sregex */
805 v = mpdm_sregex(MPDM_LS(L"change all A to A"),
806 MPDM_LS(L"/A/"),
807 MPDM_LS(L"E"), 0);
808 do_test("sregex 0", mpdm_cmp(v, MPDM_LS(L"change all E to A")) == 0);
810 v = mpdm_sregex(MPDM_LS(L"change all A to A"),
811 MPDM_LS(L"/A/g"),
812 MPDM_LS(L"E"), 0);
813 do_test("sregex 1", mpdm_cmp(v, MPDM_LS(L"change all E to E")) == 0);
815 v = mpdm_sregex(MPDM_LS(L"change all AAAAAA to E"),
816 MPDM_LS(L"/A+/g"),
817 MPDM_LS(L"E"), 0);
818 do_test("sregex 2", mpdm_cmp(v, MPDM_LS(L"change all E to E")) == 0);
820 v = mpdm_sregex(MPDM_LS(L"change all A A A A A A to E"),
821 MPDM_LS(L"/A+/g"),
822 MPDM_LS(L"E"),
824 do_test("sregex 3",
825 mpdm_cmp(v, MPDM_LS(L"change all E E E E E E to E")) == 0);
827 v = mpdm_sregex(MPDM_LS(L"change all AAA A AA AAAAA A AAA to E"),
828 MPDM_LS(L"/A+/g"),
829 MPDM_LS(L"E"), 0);
830 do_test("sregex 3.2",
831 mpdm_cmp(v, MPDM_LS(L"change all E E E E E E to E")) == 0);
833 v = mpdm_sregex(MPDM_LS(L"1, 20, 333, 40 all are numbers"),
834 MPDM_LS(L"/[0-9]+/g"),
835 MPDM_LS(L"numbers"), 0);
836 do_test("sregex 4",
837 mpdm_cmp(v,
838 MPDM_LS
839 (L"numbers, numbers, numbers, numbers all are numbers"))
840 == 0);
842 v = mpdm_sregex(MPDM_LS(L"regex, mpdm_regex, TexMex"),
843 MPDM_LS(L"/[a-zA-Z_]+/g"),
844 MPDM_LS(L"sex"),
846 do_test("sregex 5", mpdm_cmp(v, MPDM_LS(L"sex, sex, sex")) == 0);
848 v = mpdm_sregex(MPDM_LS(L"regex, mpdm_regex, TexMex"),
849 MPDM_LS(L"/[a-zA-Z]+/g"),
850 NULL, 0);
851 do_test("sregex 6", mpdm_cmp(v, MPDM_LS(L", _, ")) == 0);
853 v = mpdm_sregex(MPDM_LS(L"\\MSDOS\\style\\path"),
854 MPDM_LS(L"/\\\\/g"),
855 MPDM_LS(L"/"), 0);
856 do_test("sregex 7", mpdm_cmp(v, MPDM_LS(L"/MSDOS/style/path")) == 0);
858 v = mpdm_sregex(MPDM_LS(L"regex, Regex, REGEX"),
859 MPDM_LS(L"/regex/gi"),
860 MPDM_LS(L"sex"), 0);
861 do_test("sregex 8", mpdm_cmp(v, MPDM_LS(L"sex, sex, sex")) == 0);
863 v = mpdm_sregex(NULL, NULL, NULL, 0);
864 do_test("Previous sregex substitutions must be 3", mpdm_ival(v) == 3);
866 /* & in substitution tests */
867 v = MPDM_LS(L"this string has many words");
868 v = mpdm_sregex(v, MPDM_LS(L"/[a-z]+/g"), MPDM_LS(L"[&]"), 0);
869 do_test("& in sregex target",
870 mpdm_cmp(v,
871 MPDM_LS(L"[this] [string] [has] [many] [words]")) ==
874 v = MPDM_LS(L"this string has many words");
875 v = mpdm_sregex(v, MPDM_LS(L"/[a-z]+/g"), MPDM_LS(L"[\\&]"), 0);
876 do_test("escaped & in sregex target",
877 mpdm_cmp(v, MPDM_LS(L"[&] [&] [&] [&] [&]")) == 0);
879 v = MPDM_LS(L"this string has many words");
880 v = mpdm_sregex(v, MPDM_LS(L"/[a-z]+/g"), MPDM_LS(L"\\\\&"), 0);
881 do_test("escaped \\ in sregex target",
882 mpdm_cmp(v,
883 MPDM_LS(L"\\this \\string \\has \\many \\words")) ==
886 v = MPDM_LS(L"hola ");
887 v = mpdm_sregex(v, MPDM_LS(L"/[ \t]$/"), MPDM_LS(L""), 0);
888 do_test("sregex output size 1", v->size == 4);
890 v = MPDM_LS(L"hola ");
891 v = mpdm_sregex(v, MPDM_LS(L"/[ \t]$/"), NULL, 0);
892 do_test("sregex output size 2", v->size == 4);
894 v = MPDM_LS(L"hola ");
895 v = mpdm_sregex(v, MPDM_LS(L"/[ \t]$/"), MPDM_LS(L"!"), 0);
896 do_test("sregex output size 3", v->size == 5);
898 v = MPDM_LS(L"holo");
899 v = mpdm_sregex(v, MPDM_LS(L"/o/g"), MPDM_LS(L"!!"), 0);
900 do_test("sregex output size 4", v->size == 6);
902 /* multiple regex tests */
903 w = MPDM_A(0);
904 mpdm_ref(w);
906 mpdm_push(w, MPDM_LS(L"/^[ \t]*/"));
907 mpdm_push(w, MPDM_LS(L"/[^ \t=]+/"));
908 mpdm_push(w, MPDM_LS(L"/[ \t]*=[ \t]*/"));
909 mpdm_push(w, MPDM_LS(L"/[^ \t]+/"));
910 mpdm_push(w, MPDM_LS(L"/[ \t]*$/"));
912 v = mpdm_regex(MPDM_LS(L"key=value"), w, 0);
913 mpdm_ref(v);
914 do_test("multi-regex 1.1",
915 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"key")) == 0);
916 do_test("multi-regex 1.2",
917 mpdm_cmp(mpdm_aget(v, 3), MPDM_LS(L"value")) == 0);
918 mpdm_unref(v);
920 v = mpdm_regex(MPDM_LS(L" key = value"), w, 0);
921 mpdm_ref(v);
922 do_test("multi-regex 2.1",
923 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"key")) == 0);
924 do_test("multi-regex 2.2",
925 mpdm_cmp(mpdm_aget(v, 3), MPDM_LS(L"value")) == 0);
926 mpdm_unref(v);
928 v = mpdm_regex(MPDM_LS(L"\t\tkey\t=\tvalue "), w, 0);
929 mpdm_ref(v);
930 do_test("multi-regex 3.1",
931 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"key")) == 0);
932 do_test("multi-regex 3.2",
933 mpdm_cmp(mpdm_aget(v, 3), MPDM_LS(L"value")) == 0);
934 mpdm_unref(v);
936 mpdm_unref(w);
938 /* v = mpdm_regex(w, MPDM_LS(L"key= "), 0);
939 do_test("multi-regex 4", v == NULL);
941 printf("Multiple line regexes\n");
942 w = MPDM_LS(L"/* this is\na C-like comment */");
943 mpdm_ref(w);
945 v = mpdm_regex(w, MPDM_LS(L"|/\\*.+\\*/|"), 0);
946 do_test("Multiline regex 1", mpdm_cmp(v, w) == 0);
948 v = mpdm_regex(w, MPDM_LS(L"/is$/"), 0);
949 do_test("Multiline regex 2", v == NULL);
951 v = mpdm_regex(w, MPDM_LS(L"/is$/m"), 0);
952 do_test("Multiline regex 3", mpdm_cmp(v, MPDM_LS(L"is")) == 0);
953 mpdm_unref(w);
955 printf("Pitfalls on multibyte locales (f.e. utf-8)\n");
957 w = MPDM_LS(L"-\x03a9-");
958 mpdm_ref(w);
960 v = mpdm_regex(w, MPDM_LS(L"/-$/"), 0);
961 do_test("Multibyte environment regex 1",
962 mpdm_cmp(v, MPDM_LS(L"-")) == 0);
964 if (do_multibyte_sregex_tests) {
965 v = mpdm_sregex(w, MPDM_LS(L"/-$/"), MPDM_LS(L"~"), 0);
966 do_test("Multibyte environment sregex 1",
967 mpdm_cmp(v, MPDM_LS(L"-\x03a9~")) == 0);
969 v = mpdm_sregex(w, MPDM_LS(L"/-/g"), MPDM_LS(L"~"), 0);
970 do_test("Multibyte environment sregex 2",
971 mpdm_cmp(v, MPDM_LS(L"~\x03a9~")) == 0);
973 else
974 printf("Multibyte sregex test omitted; activate with -m\n");
976 mpdm_unref(w);
978 /* 'last' flag tests */
979 v = MPDM_LS(L"this string has many words");
980 v = mpdm_regex(v, MPDM_LS(L"/[a-z]+/l"), 0);
981 do_test("Flag l in mpdm_regex", mpdm_cmp(v, MPDM_LS(L"words")) == 0);
985 static mpdm_t dumper(mpdm_t args, mpdm_t ctxt)
986 /* executable value */
988 mpdm_dump(args);
989 return (NULL);
993 static mpdm_t sum(mpdm_t args, mpdm_t ctxt)
994 /* executable value: sum all args */
996 int n, t = 0;
998 if (args != NULL) {
999 for (n = t = 0; n < args->size; n++)
1000 t += mpdm_ival(mpdm_aget(args, n));
1003 return (MPDM_I(t));
1007 static mpdm_t calculator(mpdm_t c, mpdm_t args, mpdm_t ctxt)
1008 /* 3 argument version: calculator. c contains a 'script' to
1009 do things with the arguments */
1011 int n, t;
1012 mpdm_t v;
1013 mpdm_t a;
1014 mpdm_t o;
1016 mpdm_ref(args);
1018 /* to avoid destroying args */
1019 a = mpdm_ref(mpdm_clone(args));
1021 /* shift first argument */
1022 v = mpdm_shift(a);
1023 t = mpdm_ival(v);
1025 for (n = 0; n < mpdm_size(c); n++) {
1026 /* gets operator */
1027 o = mpdm_aget(c, n);
1029 /* gets next value */
1030 v = mpdm_shift(a);
1032 switch (*(wchar_t *) o->data) {
1033 case '+':
1034 t += mpdm_ival(v);
1035 break;
1036 case '-':
1037 t -= mpdm_ival(v);
1038 break;
1039 case '*':
1040 t *= mpdm_ival(v);
1041 break;
1042 case '/':
1043 t /= mpdm_ival(v);
1044 break;
1048 mpdm_unref(a);
1049 mpdm_unref(args);
1051 return (MPDM_I(t));
1055 void test_exec(void)
1057 mpdm_t x;
1058 mpdm_t w;
1059 mpdm_t p;
1061 printf("test_exec\n");
1063 x = MPDM_X(dumper);
1065 /* a simple value */
1066 mpdm_ref(x);
1067 mpdm_exec(x, NULL, NULL);
1068 mpdm_exec(x, x, NULL);
1069 mpdm_unref(x);
1071 x = mpdm_ref(MPDM_X(sum));
1072 w = mpdm_ref(MPDM_A(3));
1073 mpdm_aset(w, MPDM_I(100), 0);
1074 mpdm_aset(w, MPDM_I(220), 1);
1075 mpdm_aset(w, MPDM_I(333), 2);
1077 do_test("exec 0", mpdm_ival(mpdm_exec(x, w, NULL)) == 653);
1078 x = mpdm_unref(x);
1080 mpdm_push(w, MPDM_I(1));
1082 /* multiple executable value: vm and compiler support */
1084 /* calculator 'script' */
1085 p = mpdm_ref(MPDM_A(0));
1086 mpdm_push(p, MPDM_LS(L"+"));
1087 mpdm_push(p, MPDM_LS(L"-"));
1088 mpdm_push(p, MPDM_LS(L"+"));
1090 /* the value */
1091 x = mpdm_ref(MPDM_A(2));
1092 x->flags |= MPDM_EXEC;
1094 mpdm_aset(x, MPDM_X(calculator), 0);
1095 mpdm_aset(x, p, 1);
1097 do_test("exec 1", mpdm_ival(mpdm_exec(x, w, NULL)) == -12);
1099 mpdm_unref(p);
1101 /* another 'script', different operations with the same values */
1102 p = mpdm_ref(MPDM_A(0));
1103 mpdm_push(p, MPDM_LS(L"*"));
1104 mpdm_push(p, MPDM_LS(L"/"));
1105 mpdm_push(p, MPDM_LS(L"+"));
1107 mpdm_aset(x, p, 1);
1109 do_test("exec 2", mpdm_ival(mpdm_exec(x, w, NULL)) == 67);
1110 x = mpdm_unref(x);
1111 p = mpdm_unref(p);
1112 w = mpdm_unref(w);
1116 void test_encoding(void)
1118 mpdm_t f;
1119 mpdm_t v;
1120 mpdm_t w;
1121 const wchar_t *ptr;
1123 v = MPDM_MBS("?Espa?a!\n");
1124 mpdm_ref(v);
1126 printf
1127 ("\nLocale encoding tests (will look bad if terminal is not ISO-8859-1)\n\n");
1129 if ((f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"w"))) == NULL) {
1130 printf("Can't write test.txt; no further file test possible.\n");
1131 return;
1134 mpdm_write(f, v);
1135 mpdm_close(f);
1137 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r"));
1138 w = mpdm_read(f);
1139 mpdm_dump(w);
1140 do_test("Locale encoding", mpdm_cmp(w, v) == 0);
1141 mpdm_close(f);
1143 printf
1144 ("\nutf8.txt loading (should look good only in UTF-8 terminals with good fonts)\n");
1146 f = mpdm_open(MPDM_LS(L"utf8.txt"), MPDM_LS(L"r"));
1147 w = mpdm_read(f);
1148 mpdm_dump(w);
1149 mpdm_close(f);
1151 for (ptr = w->data; *ptr != L'\0'; ptr++)
1152 printf("%d", mpdm_wcwidth(*ptr));
1153 printf("\n");
1155 if (mpdm_encoding(MPDM_LS(L"UTF-8")) < 0) {
1156 printf
1157 ("No multiple encoding (iconv) support; no more tests possible.\n");
1158 return;
1161 printf
1162 ("\nForced utf8.txt loading (should look good only in UTF-8 terminals with good fonts)\n");
1164 f = mpdm_open(MPDM_LS(L"utf8.txt"), MPDM_LS(L"r"));
1165 w = mpdm_read(f);
1166 mpdm_dump(w);
1167 mpdm_close(f);
1169 /* new open file will use the specified encoding */
1170 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"w"));
1171 mpdm_write(f, v);
1172 mpdm_close(f);
1174 f = mpdm_open(MPDM_LS(L"test.txt"), MPDM_LS(L"r"));
1175 w = mpdm_read(f);
1176 mpdm_dump(w);
1177 do_test("iconv encoding", mpdm_cmp(w, v) == 0);
1178 mpdm_close(f);
1180 mpdm_encoding(NULL);
1181 mpdm_unref(v);
1185 void test_gettext(void)
1187 mpdm_t v;
1188 mpdm_t h;
1190 printf("\nTesting gettext...\n");
1192 mpdm_gettext_domain(MPDM_LS(L"stress"), MPDM_LS(L"./po"));
1194 printf
1195 ("Should follow a translated string of 'This is a test string':\n");
1196 v = mpdm_gettext(MPDM_LS(L"This is a test string"));
1197 mpdm_dump(v);
1199 printf("The same, but cached:\n");
1200 v = mpdm_gettext(MPDM_LS(L"This is a test string"));
1201 mpdm_dump(v);
1203 v = mpdm_gettext(MPDM_LS(L"This string is not translated"));
1204 mpdm_dump(v);
1206 printf("Ad-hoc translation hash:\n");
1208 h = MPDM_H(0);
1209 mpdm_ref(h);
1210 mpdm_hset(h, MPDM_LS(L"test string"), MPDM_LS(L"cadena de prueba"));
1212 mpdm_gettext_domain(MPDM_LS(L"stress"), h);
1213 v = mpdm_gettext(MPDM_LS(L"test string"));
1214 mpdm_dump(v);
1215 mpdm_unref(h);
1219 void timer(int secs)
1221 static clock_t clks = 0;
1223 switch (secs) {
1224 case 0:
1225 clks = clock();
1226 break;
1228 case -1:
1229 printf("%.2f seconds\n",
1230 (float) (clock() - clks) / (float) CLOCKS_PER_SEC);
1231 break;
1236 void bench_hash(int i, mpdm_t l, int buckets)
1238 mpdm_t h;
1239 mpdm_t v;
1240 int n;
1242 printf("Hash of %d buckets: \n", buckets);
1243 h = MPDM_H(buckets);
1244 mpdm_ref(h);
1246 timer(0);
1247 for (n = 0; n < i; n++) {
1248 v = mpdm_aget(l, n);
1249 mpdm_hset(h, v, v);
1251 timer(-1);
1253 mpdm_unref(h);
1256 printf("Bucket usage:\n");
1257 for(n=0;n < mpdm_size(h);n++)
1258 printf("\t%d: %d\n", n, mpdm_size(mpdm_aget(h, n)));
1263 void benchmark(void)
1265 mpdm_t l;
1266 int i, n;
1267 char tmp[64];
1269 printf("\n");
1271 if (!do_benchmarks) {
1272 printf("Skipping benchmarks\nRun them with 'stress -b'\n");
1273 return;
1276 printf("BENCHMARKS\n");
1278 i = 500000;
1280 printf("Creating %d values...\n", i);
1282 l = mpdm_ref(MPDM_A(i));
1283 for (n = 0; n < i; n++) {
1284 sprintf(tmp, "%08x", n);
1285 /* mpdm_aset(l, MPDM_MBS(tmp), n);*/
1286 mpdm_aset(l, MPDM_I(n), n);
1289 printf("OK\n");
1291 bench_hash(i, l, 0);
1292 bench_hash(i, l, 61);
1293 bench_hash(i, l, 89);
1294 bench_hash(i, l, 127);
1296 mpdm_unref(l);
1300 void test_conversion(void)
1302 wchar_t *wptr = NULL;
1303 char *ptr = NULL;
1304 int size = 0;
1306 ptr = mpdm_wcstombs(L"", &size);
1307 do_test("mpdm_wcstombs converts an empty string", ptr != NULL);
1309 wptr = mpdm_mbstowcs("", &size, 0);
1310 do_test("mpdm_mbstowcs converts an empty string", wptr != NULL);
1314 void test_pipes(void)
1316 mpdm_t f;
1318 printf("\n");
1320 if ((f = mpdm_popen(MPDM_LS(L"date"), MPDM_LS(L"r"))) != NULL) {
1321 mpdm_t v;
1323 v = mpdm_read(f);
1324 mpdm_pclose(f);
1326 printf("Pipe from 'date':\n");
1327 mpdm_dump(v);
1329 else
1330 printf("Can't pipe to 'date'\n");
1334 void test_misc(void)
1336 printf("Home dir:\n");
1337 mpdm_dump(mpdm_home_dir());
1338 printf("App dir:\n");
1339 mpdm_dump(mpdm_app_dir());
1343 void test_sprintf(void)
1345 mpdm_t v;
1346 mpdm_t w;
1348 printf("sprintf tests\n");
1350 v = MPDM_A(0);
1351 mpdm_ref(v);
1352 mpdm_push(v, MPDM_I(100));
1353 mpdm_push(v, MPDM_LS(L"beers"));
1355 w = mpdm_sprintf(MPDM_LS(L"%d %s for me"), v);
1356 do_test("sprintf 1", mpdm_cmp(w, MPDM_LS(L"100 beers for me")) == 0);
1358 w = mpdm_sprintf(MPDM_LS(L"%d %s for me %d"), v);
1359 do_test("sprintf 2", mpdm_cmp(w, MPDM_LS(L"100 beers for me 0")) == 0);
1361 w = mpdm_sprintf(MPDM_LS(L"%10d %s for me"), v);
1362 do_test("sprintf 3",
1363 mpdm_cmp(w, MPDM_LS(L" 100 beers for me")) == 0);
1365 w = mpdm_sprintf(MPDM_LS(L"%010d %s for me"), v);
1366 do_test("sprintf 4",
1367 mpdm_cmp(w, MPDM_LS(L"0000000100 beers for me")) == 0);
1369 mpdm_unref(v);
1371 v = MPDM_A(0);
1372 mpdm_ref(v);
1373 mpdm_push(v, MPDM_R(3.1416));
1375 w = mpdm_sprintf(MPDM_LS(L"Value for PI is %6.4f"), v);
1376 do_test("sprintf 2.1",
1377 mpdm_cmp(w, MPDM_LS(L"Value for PI is 3.1416")) == 0);
1379 /* w = mpdm_sprintf(MPDM_LS(L"Value for PI is %08.2f"), v);
1380 do_test("sprintf 2.2", mpdm_cmp(w, MPDM_LS(L"Value for PI is 00003.14")) == 0);
1382 mpdm_unref(v);
1384 v = MPDM_A(0);
1385 mpdm_ref(v);
1386 mpdm_push(v, MPDM_LS(L"stress"));
1388 w = mpdm_sprintf(MPDM_LS(L"This is a |%10s| test"), v);
1389 do_test("sprintf 3.1",
1390 mpdm_cmp(w, MPDM_LS(L"This is a | stress| test")) == 0);
1392 w = mpdm_sprintf(MPDM_LS(L"This is a |%-10s| test"), v);
1393 do_test("sprintf 3.2",
1394 mpdm_cmp(w, MPDM_LS(L"This is a |stress | test")) == 0);
1396 mpdm_unref(v);
1398 v = MPDM_A(0);
1399 mpdm_ref(v);
1400 mpdm_push(v, MPDM_I(0x263a));
1402 w = mpdm_sprintf(MPDM_LS(L"%c"), v);
1403 do_test("sprintf 3.3", mpdm_cmp(w, MPDM_LS(L"\x263a")) == 0);
1404 mpdm_unref(v);
1406 v = MPDM_A(0);
1407 mpdm_ref(v);
1408 mpdm_push(v, MPDM_I(75));
1410 w = mpdm_sprintf(MPDM_LS(L"%d%%"), v);
1411 do_test("sprintf 4.1", mpdm_cmp(w, MPDM_LS(L"75%")) == 0);
1413 w = mpdm_sprintf(MPDM_LS(L"%b"), v);
1414 do_test("sprintf 5.1", mpdm_cmp(w, MPDM_LS(L"1001011")) == 0);
1415 mpdm_unref(v);
1419 void test_ulc(void)
1421 mpdm_t v = mpdm_ref(MPDM_S(L"string"));
1422 mpdm_t w = mpdm_ref(mpdm_ulc(v, 1));
1424 do_test("mpdm_ulc 1", mpdm_cmp(mpdm_ulc(v, 1), w) == 0);
1425 do_test("mpdm_ulc 2", mpdm_cmp(mpdm_ulc(w, 0), v) == 0);
1427 mpdm_unref(w);
1429 do_test("mpdm_tr",
1430 mpdm_cmp(mpdm_tr(v, MPDM_LS(L"si"), MPDM_LS(L"Z1")),
1431 MPDM_LS(L"Ztr1ng")) == 0
1434 mpdm_unref(v);
1438 void test_scanf(void)
1440 mpdm_t v;
1442 v = mpdm_sscanf(MPDM_LS(L"1234 5678"), MPDM_LS(L"%d %d"), 0);
1443 do_test("mpdm_sscanf_1.1",
1444 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"1234")) == 0);
1445 do_test("mpdm_sscanf_1.2",
1446 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"5678")) == 0);
1448 v = mpdm_sscanf(MPDM_LS(L"this 12.34 5678"), MPDM_LS(L"%s %f %d"), 0);
1449 do_test("mpdm_sscanf_2.1",
1450 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"this")) == 0);
1451 do_test("mpdm_sscanf_2.2",
1452 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"12.34")) == 0);
1453 do_test("mpdm_sscanf_2.3",
1454 mpdm_cmp(mpdm_aget(v, 2), MPDM_LS(L"5678")) == 0);
1456 v = mpdm_sscanf(MPDM_LS(L"this 12.34 5678"), MPDM_LS(L"%s %*f %d"), 0);
1457 do_test("mpdm_sscanf_3.1",
1458 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"this")) == 0);
1459 do_test("mpdm_sscanf_3.2",
1460 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"5678")) == 0);
1462 v = mpdm_sscanf(MPDM_LS(L"12341234121234567890"),
1463 MPDM_LS(L"%4d%4d%2d%10d"),
1465 do_test("mpdm_sscanf_4.1",
1466 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"1234")) == 0);
1467 do_test("mpdm_sscanf_4.2",
1468 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"1234")) == 0);
1469 do_test("mpdm_sscanf_4.3",
1470 mpdm_cmp(mpdm_aget(v, 2), MPDM_LS(L"12")) == 0);
1471 do_test("mpdm_sscanf_4.4",
1472 mpdm_cmp(mpdm_aget(v, 3), MPDM_LS(L"1234567890")) == 0);
1474 v = mpdm_sscanf(MPDM_LS(L"ccbaabcxaaae and more"),
1475 MPDM_LS(L"%[abc]%s"),
1477 do_test("mpdm_sscanf_5.1",
1478 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"ccbaabc")) == 0);
1479 do_test("mpdm_sscanf_5.2",
1480 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"xaaae")) == 0);
1482 v = mpdm_sscanf(MPDM_LS(L"ccbaabcxaaae and more"),
1483 MPDM_LS(L"%[a-d]%s"),
1485 do_test("mpdm_sscanf_6.1",
1486 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"ccbaabc")) == 0);
1487 do_test("mpdm_sscanf_6.2",
1488 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"xaaae")) == 0);
1490 v = mpdm_sscanf(MPDM_LS(L"ccbaabcxaaae and more"),
1491 MPDM_LS(L"%[^x]%s"),
1493 do_test("mpdm_sscanf_7.1",
1494 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"ccbaabc")) == 0);
1495 do_test("mpdm_sscanf_7.2",
1496 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"xaaae")) == 0);
1498 v = mpdm_sscanf(MPDM_LS(L"key: value"),
1499 MPDM_LS(L"%[^:]: %s"),
1501 do_test("mpdm_sscanf_8.1",
1502 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"key")) == 0);
1503 do_test("mpdm_sscanf_8.2",
1504 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"value")) == 0);
1506 v = mpdm_sscanf(MPDM_LS(L"this is code /* comment */ more code"),
1507 MPDM_LS(L"%*[^/]/* %s */"),
1509 do_test("mpdm_sscanf_9.1",
1510 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"comment")) == 0);
1512 v = mpdm_sscanf(MPDM_LS(L"1234%5678"), MPDM_LS(L"%d%%%d"), 0);
1513 do_test("mpdm_sscanf_10.1",
1514 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"1234")) == 0);
1515 do_test("mpdm_sscanf_10.2",
1516 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"5678")) == 0);
1518 v = mpdm_sscanf(MPDM_LS(L"ccbaabcxaaae and more"),
1519 MPDM_LS(L"%*[abc]%n%*[^ ]%n"),
1521 do_test("mpdm_sscanf_11.1", mpdm_ival(mpdm_aget(v, 0)) == 7);
1522 do_test("mpdm_sscanf_11.2", mpdm_ival(mpdm_aget(v, 1)) == 12);
1524 v = mpdm_sscanf(MPDM_LS(L"/* inside the comment */"),
1525 MPDM_LS(L"/* %S */"),
1527 do_test("mpdm_sscanf_12.1",
1528 mpdm_cmp(mpdm_aget(v, 0),
1529 MPDM_LS(L"inside the comment")) == 0);
1531 v = mpdm_sscanf(MPDM_LS(L"/* inside the comment */outside"),
1532 MPDM_LS(L"/* %S */%s"),
1534 do_test("mpdm_sscanf_13.1",
1535 mpdm_cmp(mpdm_aget(v, 0),
1536 MPDM_LS(L"inside the comment")) == 0);
1537 do_test("mpdm_sscanf_13.2",
1538 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"outside")) == 0);
1540 v = mpdm_sscanf(MPDM_LS(L""), MPDM_LS(L"%n"), 0);
1541 do_test("mpdm_sscanf_14.1", mpdm_size(v) == 1
1542 && mpdm_ival(mpdm_aget(v, 0)) == 0);
1544 v = mpdm_sscanf(MPDM_LS(L"this 12.34 5678#12@34"),
1545 MPDM_LS(L"%[^%f]%f %[#%d@]"),
1547 do_test("mpdm_sscanf_15.1",
1548 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"this ")) == 0);
1549 do_test("mpdm_sscanf_15.2",
1550 mpdm_cmp(mpdm_aget(v, 1), MPDM_LS(L"12.34")) == 0);
1551 do_test("mpdm_sscanf_15.3",
1552 mpdm_cmp(mpdm_aget(v, 2), MPDM_LS(L"5678#12@34")) == 0);
1554 v = mpdm_sscanf( MPDM_LS(L"a \"bbb\" c;"),
1555 MPDM_LS(L"%*S\"%[^\n\"]\""),
1557 do_test("mpdm_sscanf_16",
1558 mpdm_cmp(mpdm_aget(v, 0), MPDM_LS(L"bbb")) == 0);
1560 do_test("mpdm_sscanf_17", mpdm_aget(v, 0)->size == 3);
1564 mpdm_t mutex = NULL;
1565 int t_finished = -1;
1567 mpdm_t the_thread(mpdm_t args, mpdm_t ctxt)
1568 /* running from a thread */
1570 mpdm_t fn = mpdm_ref(MPDM_LS(L"thread.txt"));
1571 mpdm_t f;
1573 printf("thread: start writing from thread\n");
1575 if ((f = mpdm_open(fn, MPDM_LS(L"w"))) != NULL) {
1576 int n;
1578 for (n = 0; n < 1000; n++) {
1579 mpdm_write(f, MPDM_I(n));
1580 mpdm_write(f, MPDM_LS(L"\n"));
1583 mpdm_close(f);
1586 printf("thread: finished writing from thread\n");
1588 mpdm_mutex_lock(mutex);
1589 t_finished = 1;
1590 mpdm_mutex_unlock(mutex);
1592 printf("thread: t_finished set\n");
1594 return NULL;
1598 void test_thread(void)
1600 mpdm_t fn = mpdm_ref(MPDM_LS(L"thread.txt"));
1601 mpdm_t x, v;
1602 int done;
1604 printf("Testing threads and mutexes...\n");
1606 mpdm_unlink(fn);
1608 /* create the executable value */
1609 x = mpdm_ref(MPDM_X(the_thread));
1611 /* create a mutex */
1612 mutex = mpdm_ref(mpdm_new_mutex());
1614 t_finished = 0;
1616 v = mpdm_exec_thread(x, NULL, NULL);
1618 printf("parent: waiting for the thread to finish...\n");
1619 mpdm_ref(v);
1621 done = 0;
1622 while (!done) {
1623 mpdm_sleep(10);
1625 mpdm_mutex_lock(mutex);
1627 if (t_finished > 0)
1628 done = 1;
1630 mpdm_mutex_unlock(mutex);
1633 printf("parent: thread said it has finished.\n");
1635 mpdm_unref(v);
1637 mpdm_unref(mutex);
1638 mpdm_unref(x);
1639 mpdm_unref(fn);
1643 mpdm_t sem = NULL;
1645 mpdm_t sem_thread(mpdm_t args, mpdm_t ctxt)
1647 printf("thread: waiting for semaphore...\n");
1649 mpdm_semaphore_wait(sem);
1651 printf("thread: got semaphore.\n");
1653 return NULL;
1657 void test_sem(void)
1659 mpdm_t x, v;
1661 printf("Testing threads and semaphores...\n");
1663 /* create the executable value */
1664 x = mpdm_ref(MPDM_X(sem_thread));
1666 /* creates the semaphore */
1667 sem = mpdm_ref(mpdm_new_semaphore(0));
1669 printf("parent: launching thread.\n");
1671 v = mpdm_exec_thread(x, NULL, NULL);
1672 mpdm_ref(v);
1674 mpdm_sleep(10);
1676 printf("parent: posting semaphore.\n");
1678 mpdm_semaphore_post(sem);
1680 mpdm_sleep(10);
1682 mpdm_unref(v);
1683 mpdm_unref(sem);
1684 mpdm_unref(x);
1688 void (*func) (void) = NULL;
1690 int main(int argc, char *argv[])
1692 if (argc > 1) {
1693 if (strcmp(argv[1], "-b") == 0)
1694 do_benchmarks = 1;
1695 if (strcmp(argv[1], "-m") == 0)
1696 do_multibyte_sregex_tests = 1;
1699 mpdm_startup();
1701 printf("sizeof(struct mpdm_val): %ld\n",
1702 (long) sizeof(struct mpdm_val));
1703 printf("sizeof(void *): %d\n", sizeof(void *));
1704 printf("sizeof(void (*func)(void)): %d\n", sizeof(func));
1706 /* test_counter();*/
1707 test_basic();
1708 test_array();
1709 test_hash();
1710 test_splice();
1711 test_strcat();
1712 test_split();
1713 test_join();
1714 test_sym();
1715 test_file();
1716 test_regex();
1717 test_exec();
1718 test_encoding();
1719 test_gettext();
1720 test_conversion();
1721 test_pipes();
1722 test_misc();
1723 test_sprintf();
1724 test_ulc();
1725 test_scanf();
1726 test_thread();
1727 test_sem();
1729 benchmark();
1731 mpdm_shutdown();
1733 printf("\n*** Total tests passed: %d/%d\n", oks, tests);
1735 if (oks == tests)
1736 printf("*** ALL TESTS PASSED\n");
1737 else {
1738 int n;
1740 printf("*** %d %s\n", tests - oks, "TESTS ---FAILED---");
1742 printf("\nFailed tests:\n\n");
1743 for (n = 0; n < i_failed_msgs; n++)
1744 printf("%s", failed_msgs[n]);
1747 return oks == tests ? 0 : 1;