1 /* $NetBSD: testsuite.c,v 1.3 2014/12/10 04:37:56 christos Exp $ */
4 static char *rcsid
= "$Id";
8 * Copyright (c) 2002 Japan Network Information Center.
11 * By using this file, you agree to the terms and conditions set forth bellow.
13 * LICENSE TERMS AND CONDITIONS
15 * The following License Terms and Conditions apply, unless a different
16 * license is obtained from Japan Network Information Center ("JPNIC"),
17 * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
18 * Chiyoda-ku, Tokyo 101-0047, Japan.
20 * 1. Use, Modification and Redistribution (including distribution of any
21 * modified or derived work) in source and/or binary forms is permitted
22 * under this License Terms and Conditions.
24 * 2. Redistribution of source code must retain the copyright notices as they
25 * appear in each source code file, this License Terms and Conditions.
27 * 3. Redistribution in binary form must reproduce the Copyright Notice,
28 * this License Terms and Conditions, in the documentation and/or other
29 * materials provided with the distribution. For the purposes of binary
30 * distribution the "Copyright Notice" refers to the following language:
31 * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
33 * 4. The name of JPNIC may not be used to endorse or promote products
34 * derived from this Software without specific prior written approval of
37 * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
38 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
40 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
45 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
46 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
56 #include <idn/result.h>
58 #include <testsuite.h>
60 typedef struct idn_testcase
*idn_testcase_t
;
64 idn_testsuite_testproc_t proc
;
67 struct idn_testsuite
{
68 idn_testcase_t testcases
;
75 idn_testcase_t current_testcase
;
76 idn_teststatus_t current_status
;
78 idn_testsuite_msgproc_t msgproc
;
82 #define INITIAL_TESTCASE_SIZE 16
83 #define INITIAL_SETUP_SIZE 4
84 #define INITIAL_TEARDOWN_SIZE 4
86 static void run_internal(idn_testsuite_t ctx
, char *titles
[]);
87 static char *make_hex_string(const char *string
);
88 static char *make_hex_ucs4string(const unsigned long *string
);
89 static void put_failure_message(idn_testsuite_t ctx
, const char *msg
,
90 const char *file
, int lineno
);
91 static void idn_testsuite_msgtostderr(const char *msg
);
94 idn_testsuite_create(idn_testsuite_t
*ctxp
) {
95 idn_testsuite_t ctx
= NULL
;
99 ctx
= (idn_testsuite_t
) malloc(sizeof(struct idn_testsuite
));
103 ctx
->testcases
= NULL
;
105 ctx
->testcase_size
= 0;
109 ctx
->current_testcase
= NULL
;
110 ctx
->current_status
= idn_teststatus_pass
;
114 ctx
->testcases
= (idn_testcase_t
) malloc(sizeof(struct idn_testcase
)
115 * INITIAL_TESTCASE_SIZE
);
116 if (ctx
->testcases
== NULL
)
118 ctx
->testcase_size
= INITIAL_TESTCASE_SIZE
;
125 free(ctx
->testcases
);
131 idn_testsuite_destroy(idn_testsuite_t ctx
) {
136 for (i
= 0; i
< ctx
->ntestcases
; i
++)
137 free(ctx
->testcases
[i
].title
);
139 free(ctx
->testcases
);
144 idn_testsuite_addtestcase(idn_testsuite_t ctx
, const char *title
,
145 idn_testsuite_testproc_t proc
) {
146 char *dup_title
= NULL
;
147 idn_testcase_t new_buffer
= NULL
;
148 idn_testcase_t new_testcase
;
151 assert(ctx
!= NULL
&& title
!= NULL
&& proc
!= NULL
);
153 dup_title
= (char *)malloc(strlen(title
) + 1);
154 if (dup_title
== NULL
)
156 strcpy(dup_title
, title
);
158 if (ctx
->ntestcases
== ctx
->testcase_size
) {
159 new_size
= ctx
->testcase_size
+ INITIAL_TESTCASE_SIZE
;
160 new_buffer
= (idn_testcase_t
)
161 realloc(ctx
->testcases
,
162 sizeof(struct idn_testcase
) * new_size
);
163 if (new_buffer
== NULL
)
165 ctx
->testcases
= new_buffer
;
166 ctx
->testcase_size
= new_size
;
169 new_testcase
= ctx
->testcases
+ ctx
->ntestcases
;
170 new_testcase
->title
= dup_title
;
171 new_testcase
->proc
= proc
;
182 idn_testsuite_ntestcases(idn_testsuite_t ctx
) {
184 return (ctx
->ntestcases
);
188 idn_testsuite_setverbose(idn_testsuite_t ctx
) {
194 idn_testsuite_unsetverbose(idn_testsuite_t ctx
) {
200 run_internal(idn_testsuite_t ctx
, char *titles
[]) {
211 for (i
= 0; i
< ctx
->ntestcases
; i
++) {
212 ctx
->current_testcase
= ctx
->testcases
+ i
;
213 ctx
->current_status
= idn_teststatus_pass
;
219 for (j
= 0; titles
[j
] != NULL
; j
++) {
220 if (strcmp(ctx
->current_testcase
->title
,
233 fprintf(stderr
, "start testcase %d: %s\n", i
+ 1,
234 ctx
->testcases
[i
].title
);
236 (ctx
->testcases
[i
].proc
)(ctx
);
237 status
= idn_teststatus_tostring(ctx
->current_status
);
239 fprintf(stderr
, "end testcase %d: %s\n", i
+ 1,
243 switch (ctx
->current_status
) {
244 case idn_teststatus_pass
:
247 case idn_teststatus_fail
:
250 case idn_teststatus_skip
:
258 idn_testsuite_runall(idn_testsuite_t ctx
) {
260 run_internal(ctx
, NULL
);
264 idn_testsuite_run(idn_testsuite_t ctx
, char *titles
[]) {
265 assert(ctx
!= NULL
&& titles
!= NULL
);
266 run_internal(ctx
, titles
);
270 idn_testsuite_npassed(idn_testsuite_t ctx
) {
272 return (ctx
->npassed
);
276 idn_testsuite_nfailed(idn_testsuite_t ctx
) {
278 return (ctx
->nfailed
);
282 idn_testsuite_nskipped(idn_testsuite_t ctx
) {
284 return (ctx
->nskipped
);
288 idn_testsuite_getstatus(idn_testsuite_t ctx
) {
290 return (ctx
->current_status
);
294 idn_testsuite_setstatus(idn_testsuite_t ctx
, idn_teststatus_t status
) {
296 assert(status
== idn_teststatus_pass
||
297 status
== idn_teststatus_fail
||
298 status
== idn_teststatus_skip
);
300 ctx
->current_status
= status
;
304 idn_teststatus_tostring(idn_teststatus_t status
) {
305 assert(status
== idn_teststatus_pass
||
306 status
== idn_teststatus_fail
||
307 status
== idn_teststatus_skip
);
310 case idn_teststatus_pass
:
313 case idn_teststatus_fail
:
316 case idn_teststatus_skip
:
325 idn_testsuite_assert(idn_testsuite_t ctx
, const char *msg
,
326 const char *file
, int lineno
) {
327 assert(ctx
!= NULL
&& msg
!= NULL
&& file
!= NULL
);
329 if (idn_testsuite_getstatus(ctx
) != idn_teststatus_pass
)
331 idn_testsuite_setstatus(ctx
, idn_teststatus_fail
);
332 put_failure_message(ctx
, msg
, file
, lineno
);
336 idn_testsuite_assertint(idn_testsuite_t ctx
, int gotten
, int expected
,
337 const char *file
, int lineno
) {
338 char msg
[256]; /* large enough */
340 assert(ctx
!= NULL
&& file
!= NULL
);
342 if (idn_testsuite_getstatus(ctx
) != idn_teststatus_pass
)
344 if (expected
== gotten
)
346 idn_testsuite_setstatus(ctx
, idn_teststatus_fail
);
348 sprintf(msg
, "`%d' expected, but got `%d'", expected
, gotten
);
349 put_failure_message(ctx
, msg
, file
, lineno
);
353 idn_testsuite_assertstring(idn_testsuite_t ctx
,
354 const char *gotten
, const char *expected
,
355 const char *file
, int lineno
) {
356 char *expected_hex
= NULL
;
357 char *gotten_hex
= NULL
;
360 assert(ctx
!= NULL
&& gotten
!= NULL
&& expected
!= NULL
&&
363 if (idn_testsuite_getstatus(ctx
) != idn_teststatus_pass
)
365 if (strcmp(expected
, gotten
) == 0)
367 idn_testsuite_setstatus(ctx
, idn_teststatus_fail
);
369 msg
= (char *)malloc(strlen(expected
) * 4 + strlen(gotten
) * 4 + 32);
370 expected_hex
= make_hex_string(expected
);
371 gotten_hex
= make_hex_string(gotten
);
372 if (msg
== NULL
|| expected_hex
== NULL
|| gotten_hex
== NULL
) {
375 sprintf(msg
, "`%s' expected, but got `%s'",
376 expected_hex
, gotten_hex
);
379 put_failure_message(ctx
, msg
, file
, lineno
);
387 idn_testsuite_assertptr(idn_testsuite_t ctx
, const void *gotten
,
388 const void *expected
, const char *file
, int lineno
) {
391 assert(ctx
!= NULL
&& file
!= NULL
);
393 if (idn_testsuite_getstatus(ctx
) != idn_teststatus_pass
)
395 if (expected
== gotten
)
397 idn_testsuite_setstatus(ctx
, idn_teststatus_fail
);
399 if (expected
== NULL
)
400 msg
= "NULL expected, but got non-NULL";
401 else if (gotten
== NULL
)
402 msg
= "non-NULL expected, but got NULL";
404 msg
= "expected pointer != gotten pointer";
405 put_failure_message(ctx
, msg
, file
, lineno
);
409 idn_testsuite_assertptrne(idn_testsuite_t ctx
,
410 const void *gotten
, const void *unexpected
,
411 const char *file
, int lineno
) {
414 assert(ctx
!= NULL
&& file
!= NULL
);
416 if (idn_testsuite_getstatus(ctx
) != idn_teststatus_pass
)
418 if (unexpected
!= gotten
)
420 idn_testsuite_setstatus(ctx
, idn_teststatus_fail
);
422 if (unexpected
== NULL
)
423 msg
= "non-NULL unexpected, but got NULL";
424 else if (gotten
== NULL
)
425 msg
= "non-NULL expected, but got NULL";
427 msg
= "expected pointer == gotten pointer";
428 put_failure_message(ctx
, msg
, file
, lineno
);
432 idn_testsuite_assertresult(idn_testsuite_t ctx
,
433 idn_result_t gotten
, idn_result_t expected
,
434 const char *file
, int lineno
) {
435 char msg
[256]; /* large enough */
437 assert(ctx
!= NULL
&& file
!= NULL
);
439 if (idn_testsuite_getstatus(ctx
) != idn_teststatus_pass
)
441 if (expected
== gotten
)
443 idn_testsuite_setstatus(ctx
, idn_teststatus_fail
);
445 sprintf(msg
, "`%s' expected, but got `%s'",
446 idn_result_tostring(expected
), idn_result_tostring(gotten
));
447 put_failure_message(ctx
, msg
, file
, lineno
);
451 idn_testsuite_assertucs4string(idn_testsuite_t ctx
,
452 const unsigned long *gotten
,
453 const unsigned long *expected
,
454 const char *file
, int lineno
) {
455 char *expected_hex
= NULL
;
456 char *gotten_hex
= NULL
;
459 assert(ctx
!= NULL
&& gotten
!= NULL
&& expected
!= NULL
&&
462 if (idn_testsuite_getstatus(ctx
) != idn_teststatus_pass
)
464 if (idn_ucs4_strcmp(expected
, gotten
) == 0)
466 idn_testsuite_setstatus(ctx
, idn_teststatus_fail
);
468 msg
= (char *)malloc(idn_ucs4_strlen(expected
) * 8 +
469 idn_ucs4_strlen(gotten
) * 8 + 32);
470 expected_hex
= make_hex_ucs4string(expected
);
471 gotten_hex
= make_hex_ucs4string(gotten
);
472 if (msg
== NULL
|| expected_hex
== NULL
|| gotten_hex
== NULL
) {
475 sprintf(msg
, "`%s' expected, but got `%s'",
476 expected_hex
, gotten_hex
);
479 put_failure_message(ctx
, msg
, file
, lineno
);
487 make_hex_string(const char *string
) {
488 static const char hex
[] = {"0123456789abcdef"};
493 hex_string
= (char *)malloc((strlen(string
)) * 4 + 1);
494 if (hex_string
== NULL
)
497 for (src
= string
, dst
= hex_string
; *src
!= '\0'; src
++) {
498 if (0x20 <= *src
&& *src
<= 0x7e && *src
!= '\\') {
503 *dst
++ = hex
[*(const unsigned char *)src
>> 4];
504 *dst
++ = hex
[*src
& 0x0f];
512 #define UCS4_MAX 0x10fffffUL
515 make_hex_ucs4string(const unsigned long *string
) {
516 static const char hex
[] = {"0123456789abcdef"};
518 const unsigned long *src
;
521 hex_string
= (char *)malloc((idn_ucs4_strlen(string
)) * 8 + 1);
522 if (hex_string
== NULL
)
525 for (src
= string
, dst
= hex_string
; *src
!= '\0'; src
++) {
526 if (0x20 <= *src
&& *src
<= 0x7e && *src
!= '\\') {
528 } else if (*src
<= UCS4_MAX
) {
531 if (*src
>= 0x100000) {
532 *dst
++ = hex
[(*src
>> 20) & 0x0f];
534 if (*src
>= 0x10000) {
535 *dst
++ = hex
[(*src
>> 16) & 0x0f];
537 *dst
++ = hex
[(*src
>> 12) & 0x0f];
538 *dst
++ = hex
[(*src
>> 8) & 0x0f];
539 *dst
++ = hex
[(*src
>> 4) & 0x0f];
540 *dst
++ = hex
[*src
& 0x0f];
556 put_failure_message(idn_testsuite_t ctx
, const char *msg
, const char *file
,
558 idn_testsuite_msgproc_t proc
;
562 proc
= (ctx
->msgproc
== NULL
) ?
563 idn_testsuite_msgtostderr
: ctx
->msgproc
;
564 title
= (ctx
->current_testcase
!= NULL
&&
565 ctx
->current_testcase
->title
!= NULL
) ?
566 ctx
->current_testcase
->title
: "anonymous";
568 sprintf(buffer
, "%.100s: In test `%.100s':", file
, title
);
571 sprintf(buffer
, "%.100s:%d: failed (%.100s)", file
, lineno
, msg
);
577 idn_testsuite_msgtostderr(const char *msg
) {