Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* vim:set ts=2 sw=2 et cindent: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include "nsStringAPI.h"
9 #include "nsXPCOM.h"
10 #include "nsMemory.h"
12 static const char kAsciiData[] = "Hello World";
14 static const char16_t kUnicodeData[] =
15 {'H','e','l','l','o',' ','W','o','r','l','d','\0'};
17 static bool test_basic_1()
18 {
19 nsCStringContainer s;
20 NS_CStringContainerInit(s);
22 const char *ptr;
23 uint32_t len;
24 char *clone;
26 NS_CStringGetData(s, &ptr);
27 if (ptr == nullptr || *ptr != '\0')
28 {
29 NS_ERROR("unexpected result");
30 return false;
31 }
33 NS_CStringSetData(s, kAsciiData, UINT32_MAX);
34 len = NS_CStringGetData(s, &ptr);
35 if (ptr == nullptr || strcmp(ptr, kAsciiData) != 0)
36 {
37 NS_ERROR("unexpected result");
38 return false;
39 }
40 if (len != sizeof(kAsciiData)-1)
41 {
42 NS_ERROR("unexpected result");
43 return false;
44 }
46 clone = NS_CStringCloneData(s);
47 if (ptr == nullptr || strcmp(ptr, kAsciiData) != 0)
48 {
49 NS_ERROR("unexpected result");
50 return false;
51 }
52 NS_Free(clone);
54 nsCStringContainer temp;
55 NS_CStringContainerInit(temp);
56 NS_CStringCopy(temp, s);
58 len = NS_CStringGetData(temp, &ptr);
59 if (ptr == nullptr || strcmp(ptr, kAsciiData) != 0)
60 {
61 NS_ERROR("unexpected result");
62 return false;
63 }
64 if (len != sizeof(kAsciiData)-1)
65 {
66 NS_ERROR("unexpected result");
67 return false;
68 }
70 NS_CStringContainerFinish(temp);
72 NS_CStringContainerFinish(s);
73 return true;
74 }
76 static bool test_basic_2()
77 {
78 nsStringContainer s;
79 NS_StringContainerInit(s);
81 const char16_t *ptr;
82 uint32_t len;
83 char16_t *clone;
85 NS_StringGetData(s, &ptr);
86 if (ptr == nullptr || *ptr != '\0')
87 {
88 NS_ERROR("unexpected result");
89 return false;
90 }
92 NS_StringSetData(s, kUnicodeData, UINT32_MAX);
93 len = NS_StringGetData(s, &ptr);
94 if (len != sizeof(kUnicodeData)/2 - 1)
95 {
96 NS_ERROR("unexpected result");
97 return false;
98 }
99 if (ptr == nullptr || memcmp(ptr, kUnicodeData, sizeof(kUnicodeData)) != 0)
100 {
101 NS_ERROR("unexpected result");
102 return false;
103 }
105 clone = NS_StringCloneData(s);
106 if (ptr == nullptr || memcmp(ptr, kUnicodeData, sizeof(kUnicodeData)) != 0)
107 {
108 NS_ERROR("unexpected result");
109 return false;
110 }
111 NS_Free(clone);
113 nsStringContainer temp;
114 NS_StringContainerInit(temp);
115 NS_StringCopy(temp, s);
117 len = NS_StringGetData(temp, &ptr);
118 if (len != sizeof(kUnicodeData)/2 - 1)
119 {
120 NS_ERROR("unexpected result");
121 return false;
122 }
123 if (ptr == nullptr || memcmp(ptr, kUnicodeData, sizeof(kUnicodeData)) != 0)
124 {
125 NS_ERROR("unexpected result");
126 return false;
127 }
129 NS_StringContainerFinish(temp);
131 NS_StringContainerFinish(s);
133 return true;
134 }
136 static bool test_convert()
137 {
138 nsStringContainer s;
139 NS_StringContainerInit(s);
140 NS_StringSetData(s, kUnicodeData, sizeof(kUnicodeData)/2 - 1);
142 nsCStringContainer temp;
143 NS_CStringContainerInit(temp);
145 const char *data;
147 NS_UTF16ToCString(s, NS_CSTRING_ENCODING_ASCII, temp);
148 NS_CStringGetData(temp, &data);
149 if (strcmp(data, kAsciiData) != 0)
150 return false;
152 NS_UTF16ToCString(s, NS_CSTRING_ENCODING_UTF8, temp);
153 NS_CStringGetData(temp, &data);
154 if (strcmp(data, kAsciiData) != 0)
155 return false;
157 NS_CStringContainerFinish(temp);
159 NS_StringContainerFinish(s);
160 return true;
161 }
163 static bool test_append()
164 {
165 nsCStringContainer s;
166 NS_CStringContainerInit(s);
168 NS_CStringSetData(s, "foo");
169 NS_CStringAppendData(s, "bar");
171 NS_CStringContainerFinish(s);
172 return true;
173 }
175 // Replace all occurrences of |matchVal| with |newVal|
176 static void ReplaceSubstring( nsACString& str,
177 const nsACString& matchVal,
178 const nsACString& newVal )
179 {
180 const char* sp, *mp, *np;
181 uint32_t sl, ml, nl;
183 sl = NS_CStringGetData(str, &sp);
184 ml = NS_CStringGetData(matchVal, &mp);
185 nl = NS_CStringGetData(newVal, &np);
187 for (const char* iter = sp; iter <= sp + sl - ml; ++iter)
188 {
189 if (memcmp(iter, mp, ml) == 0)
190 {
191 uint32_t offset = iter - sp;
193 NS_CStringSetDataRange(str, offset, ml, np, nl);
195 sl = NS_CStringGetData(str, &sp);
197 iter = sp + offset + nl - 1;
198 }
199 }
200 }
202 static bool test_replace_driver(const char *strVal,
203 const char *matchVal,
204 const char *newVal,
205 const char *finalVal)
206 {
207 nsCStringContainer a;
208 NS_CStringContainerInit(a);
209 NS_CStringSetData(a, strVal);
211 nsCStringContainer b;
212 NS_CStringContainerInit(b);
213 NS_CStringSetData(b, matchVal);
215 nsCStringContainer c;
216 NS_CStringContainerInit(c);
217 NS_CStringSetData(c, newVal);
219 ReplaceSubstring(a, b, c);
221 const char *data;
222 NS_CStringGetData(a, &data);
223 if (strcmp(data, finalVal) != 0)
224 return false;
226 NS_CStringContainerFinish(c);
227 NS_CStringContainerFinish(b);
228 NS_CStringContainerFinish(a);
229 return true;
230 }
232 static bool test_replace()
233 {
234 bool rv;
236 rv = test_replace_driver("hello world, hello again!",
237 "hello",
238 "goodbye",
239 "goodbye world, goodbye again!");
240 if (!rv)
241 return rv;
243 rv = test_replace_driver("foofoofoofoo!",
244 "foo",
245 "bar",
246 "barbarbarbar!");
247 if (!rv)
248 return rv;
250 rv = test_replace_driver("foo bar systems",
251 "xyz",
252 "crazy",
253 "foo bar systems");
254 if (!rv)
255 return rv;
257 rv = test_replace_driver("oh",
258 "xyz",
259 "crazy",
260 "oh");
261 if (!rv)
262 return rv;
264 return true;
265 }
267 static const char* kWhitespace="\b\t\r\n ";
269 static void
270 CompressWhitespace(nsACString &str)
271 {
272 const char *p;
273 int32_t i, len = (int32_t) NS_CStringGetData(str, &p);
275 // trim leading whitespace
277 for (i=0; i<len; ++i)
278 {
279 if (!strchr(kWhitespace, (char) p[i]))
280 break;
281 }
283 if (i>0)
284 {
285 NS_CStringCutData(str, 0, i);
286 len = (int32_t) NS_CStringGetData(str, &p);
287 }
289 // trim trailing whitespace
291 for (i=len-1; i>=0; --i)
292 {
293 if (!strchr(kWhitespace, (char) p[i]))
294 break;
295 }
297 if (++i < len)
298 NS_CStringCutData(str, i, len - i);
299 }
301 static bool test_compress_ws()
302 {
303 nsCStringContainer s;
304 NS_CStringContainerInit(s);
305 NS_CStringSetData(s, " \thello world\r \n");
306 CompressWhitespace(s);
307 const char *d;
308 NS_CStringGetData(s, &d);
309 bool rv = !strcmp(d, "hello world");
310 if (!rv)
311 printf("=> \"%s\"\n", d);
312 NS_CStringContainerFinish(s);
313 return rv;
314 }
316 static bool test_depend()
317 {
318 static const char kData[] = "hello world";
320 nsCStringContainer s;
321 NS_ENSURE_SUCCESS(
322 NS_CStringContainerInit2(s, kData, sizeof(kData)-1,
323 NS_CSTRING_CONTAINER_INIT_DEPEND),
324 false);
326 const char *sd;
327 NS_CStringGetData(s, &sd);
329 bool rv = (sd == kData);
330 NS_CStringContainerFinish(s);
331 return rv;
332 }
334 static bool test_depend_sub()
335 {
336 static const char kData[] = "hello world";
338 nsCStringContainer s;
339 NS_ENSURE_SUCCESS(
340 NS_CStringContainerInit2(s, kData, sizeof(kData)-1,
341 NS_CSTRING_CONTAINER_INIT_DEPEND |
342 NS_CSTRING_CONTAINER_INIT_SUBSTRING),
343 false);
345 bool terminated;
346 const char *sd;
347 uint32_t len = NS_CStringGetData(s, &sd, &terminated);
349 bool rv = (sd == kData && len == sizeof(kData)-1 && !terminated);
350 NS_CStringContainerFinish(s);
351 return rv;
352 }
354 static bool test_adopt()
355 {
356 static const char kData[] = "hello world";
358 char *data = (char *) nsMemory::Clone(kData, sizeof(kData));
359 if (!data)
360 return false;
362 nsCStringContainer s;
363 NS_ENSURE_SUCCESS(
364 NS_CStringContainerInit2(s, data, UINT32_MAX,
365 NS_CSTRING_CONTAINER_INIT_ADOPT),
366 false); // leaks data on failure *shrug*
368 const char *sd;
369 NS_CStringGetData(s, &sd);
371 bool rv = (sd == data);
372 NS_CStringContainerFinish(s);
373 return rv;
374 }
376 static bool test_adopt_sub()
377 {
378 static const char kData[] = "hello world";
380 char *data = (char *) nsMemory::Clone(kData, sizeof(kData)-1);
381 if (!data)
382 return false;
384 nsCStringContainer s;
385 NS_ENSURE_SUCCESS(
386 NS_CStringContainerInit2(s, data, sizeof(kData)-1,
387 NS_CSTRING_CONTAINER_INIT_ADOPT |
388 NS_CSTRING_CONTAINER_INIT_SUBSTRING),
389 false); // leaks data on failure *shrug*
391 bool terminated;
392 const char *sd;
393 uint32_t len = NS_CStringGetData(s, &sd, &terminated);
395 bool rv = (sd == data && len == sizeof(kData)-1 && !terminated);
396 NS_CStringContainerFinish(s);
397 return rv;
398 }
400 static bool test_mutation()
401 {
402 nsCStringContainer s;
403 NS_CStringContainerInit(s);
405 const char kText[] = "Every good boy does fine.";
407 char *buf;
408 uint32_t len = NS_CStringGetMutableData(s, sizeof(kText) - 1, &buf);
409 if (!buf || len != sizeof(kText) - 1)
410 return false;
411 memcpy(buf, kText, sizeof(kText));
413 const char *data;
414 NS_CStringGetData(s, &data);
415 if (strcmp(data, kText) != 0)
416 return false;
418 uint32_t newLen = len + 1;
419 len = NS_CStringGetMutableData(s, newLen, &buf);
420 if (!buf || len != newLen)
421 return false;
423 buf[len - 1] = '.';
425 NS_CStringGetData(s, &data);
426 if (strncmp(data, kText, len - 1) != 0 || data[len - 1] != '.')
427 return false;
429 NS_CStringContainerFinish(s);
430 return true;
431 }
433 static bool test_ascii()
434 {
435 nsCString testCString;
436 testCString.AppendASCII(kAsciiData);
437 if (!testCString.EqualsLiteral(kAsciiData))
438 return false;
440 testCString.AssignASCII(kAsciiData);
441 if (!testCString.LowerCaseEqualsLiteral("hello world"))
442 return false;
444 nsString testString;
445 testString.AppendASCII(kAsciiData);
446 if (!testString.EqualsLiteral(kAsciiData))
447 return false;
449 testString.AssignASCII(kAsciiData);
450 if (!testString.LowerCaseEqualsLiteral("hello world"))
451 return false;
453 return true;
454 }
456 static bool test_chars()
457 {
458 nsCString testCString(kAsciiData);
459 if (testCString.First() != 'H')
460 return false;
461 if (testCString.Last() != 'd')
462 return false;
463 testCString.SetCharAt('u', 8);
464 if (!testCString.EqualsASCII("Hello Would"))
465 return false;
467 nsString testString(kUnicodeData);
468 if (testString.First() != 'H')
469 return false;
470 if (testString.Last() != 'd')
471 return false;
472 testString.SetCharAt('u', 8);
473 if (!testString.EqualsASCII("Hello Would"))
474 return false;
476 return true;
477 }
479 static bool test_stripchars()
480 {
481 nsCString test(kAsciiData);
482 test.StripChars("ld");
483 if (!test.Equals("Heo Wor"))
484 return false;
486 test.Assign(kAsciiData);
487 test.StripWhitespace();
488 if (!test.Equals("HelloWorld"))
489 return false;
491 return true;
492 }
494 static bool test_trim()
495 {
496 static const char kWS[] = "\n\t\r ";
497 static const char kTestString[] = " \n\tTesting...\n\r";
499 nsCString test1(kTestString);
500 nsCString test2(kTestString);
501 nsCString test3(kTestString);
503 test1.Trim(kWS);
504 test2.Trim(kWS, true, false);
505 test3.Trim(kWS, false, true);
507 if (!test1.Equals("Testing..."))
508 return false;
510 if (!test2.Equals("Testing...\n\r"))
511 return false;
513 if (!test3.Equals(" \n\tTesting..."))
514 return false;
516 return true;
517 }
519 static bool test_find()
520 {
521 nsString uni(kUnicodeData);
523 static const char kHello[] = "Hello";
524 static const char khello[] = "hello";
525 static const char kBye[] = "Bye!";
527 int32_t found;
529 found = uni.Find(kHello);
530 if (found != 0)
531 return false;
533 found = uni.Find(khello, false);
534 if (found != -1)
535 return false;
537 found = uni.Find(khello, true);
538 if (found != 0)
539 return false;
541 found = uni.Find(kBye);
542 if (found != -1)
543 return false;
545 found = uni.Find(NS_LITERAL_STRING("World"));
546 if (found != 6)
547 return false;
549 found = uni.Find(uni);
550 if (found != 0)
551 return false;
553 return true;
554 }
556 static bool test_compressws()
557 {
558 nsString check(NS_LITERAL_STRING(" \tTesting \n\t1\n 2 3\n "));
559 CompressWhitespace(check);
560 return check.Equals(NS_LITERAL_STRING("Testing 1 2 3"));
561 }
563 static bool test_comparisons()
564 {
565 bool result;
567 // nsString
569 NS_NAMED_LITERAL_STRING(shortString1, "Foo");
570 NS_NAMED_LITERAL_STRING(shortString2, "Bar");
571 NS_NAMED_LITERAL_STRING(shortString3, "Bar");
572 NS_NAMED_LITERAL_STRING(shortString4, "bar");
573 NS_NAMED_LITERAL_STRING(longString, "FooBar");
575 // ==
577 result = (shortString1 == shortString2);
578 if (result)
579 return false;
581 result = (shortString2 == shortString3);
582 if (!result)
583 return false;
585 result = (shortString3 == shortString4);
586 if (result)
587 return false;
589 result = (shortString1 == longString);
590 if (result)
591 return false;
593 result = (longString == shortString1);
594 if (result)
595 return false;
597 // !=
599 result = (shortString1 != shortString2);
600 if (!result)
601 return false;
603 result = (shortString2 != shortString3);
604 if (result)
605 return false;
607 result = (shortString3 != shortString4);
608 if (!result)
609 return false;
611 result = (shortString1 != longString);
612 if (!result)
613 return false;
615 result = (longString != shortString1);
616 if (!result)
617 return false;
619 // <
621 result = (shortString1 < shortString2);
622 if (result)
623 return false;
625 result = (shortString2 < shortString1);
626 if (!result)
627 return false;
629 result = (shortString1 < longString);
630 if (!result)
631 return false;
633 result = (longString < shortString1);
634 if (result)
635 return false;
637 result = (shortString2 < shortString3);
638 if (result)
639 return false;
641 result = (shortString3 < shortString4);
642 if (!result)
643 return false;
645 result = (shortString4 < shortString3);
646 if (result)
647 return false;
649 // <=
651 result = (shortString1 <= shortString2);
652 if (result)
653 return false;
655 result = (shortString2 <= shortString1);
656 if (!result)
657 return false;
659 result = (shortString1 <= longString);
660 if (!result)
661 return false;
663 result = (longString <= shortString1);
664 if (result)
665 return false;
667 result = (shortString2 <= shortString3);
668 if (!result)
669 return false;
671 result = (shortString3 <= shortString4);
672 if (!result)
673 return false;
675 result = (shortString4 <= shortString3);
676 if (result)
677 return false;
679 // >
681 result = (shortString1 > shortString2);
682 if (!result)
683 return false;
685 result = (shortString2 > shortString1);
686 if (result)
687 return false;
689 result = (shortString1 > longString);
690 if (result)
691 return false;
693 result = (longString > shortString1);
694 if (!result)
695 return false;
697 result = (shortString2 > shortString3);
698 if (result)
699 return false;
701 result = (shortString3 > shortString4);
702 if (result)
703 return false;
705 result = (shortString4 > shortString3);
706 if (!result)
707 return false;
709 // >=
711 result = (shortString1 >= shortString2);
712 if (!result)
713 return false;
715 result = (shortString2 >= shortString1);
716 if (result)
717 return false;
719 result = (shortString1 >= longString);
720 if (result)
721 return false;
723 result = (longString >= shortString1);
724 if (!result)
725 return false;
727 result = (shortString2 >= shortString3);
728 if (!result)
729 return false;
731 result = (shortString3 >= shortString4);
732 if (result)
733 return false;
735 result = (shortString4 >= shortString3);
736 if (!result)
737 return false;
739 // nsCString
741 NS_NAMED_LITERAL_CSTRING(shortCString1, "Foo");
742 NS_NAMED_LITERAL_CSTRING(shortCString2, "Bar");
743 NS_NAMED_LITERAL_CSTRING(shortCString3, "Bar");
744 NS_NAMED_LITERAL_CSTRING(shortCString4, "bar");
745 NS_NAMED_LITERAL_CSTRING(longCString, "FooBar");
747 // ==
749 result = (shortCString1 == shortCString2);
750 if (result)
751 return false;
753 result = (shortCString2 == shortCString3);
754 if (!result)
755 return false;
757 result = (shortCString3 == shortCString4);
758 if (result)
759 return false;
761 result = (shortCString1 == longCString);
762 if (result)
763 return false;
765 result = (longCString == shortCString1);
766 if (result)
767 return false;
769 // !=
771 result = (shortCString1 != shortCString2);
772 if (!result)
773 return false;
775 result = (shortCString2 != shortCString3);
776 if (result)
777 return false;
779 result = (shortCString3 != shortCString4);
780 if (!result)
781 return false;
783 result = (shortCString1 != longCString);
784 if (!result)
785 return false;
787 result = (longCString != shortCString1);
788 if (!result)
789 return false;
791 // <
793 result = (shortCString1 < shortCString2);
794 if (result)
795 return false;
797 result = (shortCString2 < shortCString1);
798 if (!result)
799 return false;
801 result = (shortCString1 < longCString);
802 if (!result)
803 return false;
805 result = (longCString < shortCString1);
806 if (result)
807 return false;
809 result = (shortCString2 < shortCString3);
810 if (result)
811 return false;
813 result = (shortCString3 < shortCString4);
814 if (!result)
815 return false;
817 result = (shortCString4 < shortCString3);
818 if (result)
819 return false;
821 // <=
823 result = (shortCString1 <= shortCString2);
824 if (result)
825 return false;
827 result = (shortCString2 <= shortCString1);
828 if (!result)
829 return false;
831 result = (shortCString1 <= longCString);
832 if (!result)
833 return false;
835 result = (longCString <= shortCString1);
836 if (result)
837 return false;
839 result = (shortCString2 <= shortCString3);
840 if (!result)
841 return false;
843 result = (shortCString3 <= shortCString4);
844 if (!result)
845 return false;
847 result = (shortCString4 <= shortCString3);
848 if (result)
849 return false;
851 // >
853 result = (shortCString1 > shortCString2);
854 if (!result)
855 return false;
857 result = (shortCString2 > shortCString1);
858 if (result)
859 return false;
861 result = (shortCString1 > longCString);
862 if (result)
863 return false;
865 result = (longCString > shortCString1);
866 if (!result)
867 return false;
869 result = (shortCString2 > shortCString3);
870 if (result)
871 return false;
873 result = (shortCString3 > shortCString4);
874 if (result)
875 return false;
877 result = (shortCString4 > shortCString3);
878 if (!result)
879 return false;
881 // >=
883 result = (shortCString1 >= shortCString2);
884 if (!result)
885 return false;
887 result = (shortCString2 >= shortCString1);
888 if (result)
889 return false;
891 result = (shortCString1 >= longCString);
892 if (result)
893 return false;
895 result = (longCString >= shortCString1);
896 if (!result)
897 return false;
899 result = (shortCString2 >= shortCString3);
900 if (!result)
901 return false;
903 result = (shortCString3 >= shortCString4);
904 if (result)
905 return false;
907 result = (shortCString4 >= shortCString3);
908 if (!result)
909 return false;
911 return true;
912 }
914 static bool test_parse_string_helper(const char* str, char separator, int len,
915 const char* s1, const char* s2)
916 {
917 nsCString data(str);
918 nsTArray<nsCString> results;
919 if (!ParseString(data, separator, results))
920 return false;
921 if (int(results.Length()) != len)
922 return false;
923 const char* strings[] = { s1, s2 };
924 for (int i = 0; i < len; ++i) {
925 if (!results[i].Equals(strings[i]))
926 return false;
927 }
928 return true;
929 }
931 static bool test_parse_string_helper0(const char* str, char separator)
932 {
933 return test_parse_string_helper(str, separator, 0, nullptr, nullptr);
934 }
936 static bool test_parse_string_helper1(const char* str, char separator, const char* s1)
937 {
938 return test_parse_string_helper(str, separator, 1, s1, nullptr);
939 }
941 static bool test_parse_string_helper2(const char* str, char separator, const char* s1, const char* s2)
942 {
943 return test_parse_string_helper(str, separator, 2, s1, s2);
944 }
946 static bool test_parse_string()
947 {
948 return test_parse_string_helper1("foo, bar", '_', "foo, bar") &&
949 test_parse_string_helper2("foo, bar", ',', "foo", " bar") &&
950 test_parse_string_helper2("foo, bar ", ' ', "foo,", "bar") &&
951 test_parse_string_helper2("foo,bar", 'o', "f", ",bar") &&
952 test_parse_string_helper0("", '_') &&
953 test_parse_string_helper0(" ", ' ') &&
954 test_parse_string_helper1(" foo", ' ', "foo") &&
955 test_parse_string_helper1(" foo", ' ', "foo");
956 }
958 //----
960 typedef bool (*TestFunc)();
962 static const struct Test
963 {
964 const char* name;
965 TestFunc func;
966 }
967 tests[] =
968 {
969 { "test_basic_1", test_basic_1 },
970 { "test_basic_2", test_basic_2 },
971 { "test_convert", test_convert },
972 { "test_append", test_append },
973 { "test_replace", test_replace },
974 { "test_compress_ws", test_compress_ws },
975 { "test_depend", test_depend },
976 { "test_depend_sub", test_depend_sub },
977 { "test_adopt", test_adopt },
978 { "test_adopt_sub", test_adopt_sub },
979 { "test_mutation", test_mutation },
980 { "test_ascii", test_ascii },
981 { "test_chars", test_chars },
982 { "test_stripchars", test_stripchars },
983 { "test_trim", test_trim },
984 { "test_find", test_find },
985 { "test_compressws", test_compressws },
986 { "test_comparisons", test_comparisons },
987 { "test_parse_string", test_parse_string },
988 { nullptr, nullptr }
989 };
991 //----
993 int main(int argc, char **argv)
994 {
995 int count = 1;
996 if (argc > 1)
997 count = atoi(argv[1]);
999 while (count--)
1000 {
1001 for (const Test* t = tests; t->name != nullptr; ++t)
1002 {
1003 printf("%25s : %s\n", t->name, t->func() ? "SUCCESS" : "FAILURE");
1004 }
1005 }
1007 return 0;
1008 }