5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#ifndef lint
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstatic char *rcsid = "$Id";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#endif
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews/*
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * Copyright (c) 2002 Japan Network Information Center.
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * All rights reserved.
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * By using this file, you agree to the terms and conditions set forth bellow.
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * LICENSE TERMS AND CONDITIONS
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * The following License Terms and Conditions apply, unless a different
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * license is obtained from Japan Network Information Center ("JPNIC"),
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * Chiyoda-ku, Tokyo 101-0047, Japan.
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * 1. Use, Modification and Redistribution (including distribution of any
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * modified or derived work) in source and/or binary forms is permitted
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * under this License Terms and Conditions.
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * 2. Redistribution of source code must retain the copyright notices as they
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * appear in each source code file, this License Terms and Conditions.
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * 3. Redistribution in binary form must reproduce the Copyright Notice,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * this License Terms and Conditions, in the documentation and/or other
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * materials provided with the distribution. For the purposes of binary
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * distribution the "Copyright Notice" refers to the following language:
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * 4. The name of JPNIC may not be used to endorse or promote products
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * derived from this Software without specific prior written approval of
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * JPNIC.
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews */
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#include <stddef.h>
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#include <stdio.h>
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#include <stdlib.h>
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#include <string.h>
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#include <assert.h>
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#include <idn/result.h>
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#include <idn/ucs4.h>
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#include <testsuite.h>
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewstypedef struct idn_testcase *idn_testcase_t;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstruct idn_testcase {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *title;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_testproc_t proc;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews};
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstruct idn_testsuite {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testcase_t testcases;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews int ntestcases;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews int testcase_size;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews int npassed;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews int nfailed;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews int nskipped;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testcase_t current_testcase;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_teststatus_t current_status;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_msgproc_t msgproc;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews int verbose;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews};
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#define INITIAL_TESTCASE_SIZE 16
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#define INITIAL_SETUP_SIZE 4
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#define INITIAL_TEARDOWN_SIZE 4
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstatic void run_internal(idn_testsuite_t ctx, char *titles[]);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstatic char *make_hex_string(const char *string);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstatic char *make_hex_ucs4string(const unsigned long *string);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstatic void put_failure_message(idn_testsuite_t ctx, const char *msg,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const char *file, int lineno);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstatic void idn_testsuite_msgtostderr(const char *msg);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsint
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_create(idn_testsuite_t *ctxp) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_t ctx = NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctxp != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx = (idn_testsuite_t) malloc(sizeof(struct idn_testsuite));
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (ctx == NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews goto error;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->testcases = NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->ntestcases = 0;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->testcase_size = 0;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->npassed = 0;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->nfailed = 0;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->nskipped = 0;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->current_testcase = NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->current_status = idn_teststatus_pass;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->msgproc = NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->verbose = 0;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->testcases = (idn_testcase_t) malloc(sizeof(struct idn_testcase)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews * INITIAL_TESTCASE_SIZE);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (ctx->testcases == NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews goto error;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->testcase_size = INITIAL_TESTCASE_SIZE;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *ctxp = ctx;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return (1);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewserror:
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (ctx != NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(ctx->testcases);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(ctx);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return (0);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_destroy(idn_testsuite_t ctx) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews int i;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews for (i = 0; i < ctx->ntestcases; i++)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(ctx->testcases[i].title);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(ctx->testcases);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(ctx);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsint
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_addtestcase(idn_testsuite_t ctx, const char *title,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_testproc_t proc) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *dup_title = NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testcase_t new_buffer = NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testcase_t new_testcase;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews int new_size;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL && title != NULL && proc != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews dup_title = (char *)malloc(strlen(title) + 1);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (dup_title == NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews goto error;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews strcpy(dup_title, title);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (ctx->ntestcases == ctx->testcase_size) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews new_size = ctx->testcase_size + INITIAL_TESTCASE_SIZE;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews new_buffer = (idn_testcase_t)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews realloc(ctx->testcases,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews sizeof(struct idn_testcase) * new_size);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (new_buffer == NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews goto error;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->testcases = new_buffer;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->testcase_size = new_size;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews new_testcase = ctx->testcases + ctx->ntestcases;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews new_testcase->title = dup_title;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews new_testcase->proc = proc;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->ntestcases++;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return (1);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewserror:
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(dup_title);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(new_buffer);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return (0);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsint
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_ntestcases(idn_testsuite_t ctx) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return (ctx->ntestcases);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_setverbose(idn_testsuite_t ctx) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->verbose = 1;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_unsetverbose(idn_testsuite_t ctx) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->verbose = 0;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstatic void
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsrun_internal(idn_testsuite_t ctx, char *titles[]) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews int i, j;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews int run_testcase;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const char *status;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->npassed = 0;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->nfailed = 0;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->nskipped = 0;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews for (i = 0; i < ctx->ntestcases; i++) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->current_testcase = ctx->testcases + i;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->current_status = idn_teststatus_pass;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (titles == NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews run_testcase = 1;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews else {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews run_testcase = 0;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews for (j = 0; titles[j] != NULL; j++) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (strcmp(ctx->current_testcase->title,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews titles[j]) == 0) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews run_testcase = 1;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews break;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (!run_testcase) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->nskipped++;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews continue;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (ctx->verbose) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews fprintf(stderr, "start testcase %d: %s\n", i + 1,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->testcases[i].title);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews (ctx->testcases[i].proc)(ctx);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews status = idn_teststatus_tostring(ctx->current_status);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (ctx->verbose) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews fprintf(stderr, "end testcase %d: %s\n", i + 1,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews status);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews switch (ctx->current_status) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews case idn_teststatus_pass:
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->npassed++;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews break;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews case idn_teststatus_fail:
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->nfailed++;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews break;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews case idn_teststatus_skip:
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->nskipped++;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews break;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_runall(idn_testsuite_t ctx) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews run_internal(ctx, NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_run(idn_testsuite_t ctx, char *titles[]) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL && titles != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews run_internal(ctx, titles);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsint
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_npassed(idn_testsuite_t ctx) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return (ctx->npassed);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsint
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_nfailed(idn_testsuite_t ctx) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return (ctx->nfailed);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsint
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_nskipped(idn_testsuite_t ctx) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return (ctx->nskipped);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_teststatus_t
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_getstatus(idn_testsuite_t ctx) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return (ctx->current_status);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_setstatus(idn_testsuite_t ctx, idn_teststatus_t status) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(status == idn_teststatus_pass ||
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews status == idn_teststatus_fail ||
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews status == idn_teststatus_skip);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->current_status = status;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsconst char *
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_teststatus_tostring(idn_teststatus_t status) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(status == idn_teststatus_pass ||
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews status == idn_teststatus_fail ||
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews status == idn_teststatus_skip);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews switch (status) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews case idn_teststatus_pass:
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return "pass";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews break;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews case idn_teststatus_fail:
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return "failed";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews break;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews case idn_teststatus_skip:
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return "skipped";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews break;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return "unknown";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_assert(idn_testsuite_t ctx, const char *msg,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const char *file, int lineno) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL && msg != NULL && file != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (idn_testsuite_getstatus(ctx) != idn_teststatus_pass)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_setstatus(ctx, idn_teststatus_fail);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews put_failure_message(ctx, msg, file, lineno);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_assertint(idn_testsuite_t ctx, int gotten, int expected,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const char *file, int lineno) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char msg[256]; /* large enough */
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL && file != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (idn_testsuite_getstatus(ctx) != idn_teststatus_pass)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (expected == gotten)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_setstatus(ctx, idn_teststatus_fail);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews sprintf(msg, "`%d' expected, but got `%d'", expected, gotten);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews put_failure_message(ctx, msg, file, lineno);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_assertstring(idn_testsuite_t ctx,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const char *gotten, const char *expected,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const char *file, int lineno) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *expected_hex = NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *gotten_hex = NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *msg;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL && gotten != NULL && expected != NULL &&
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews file != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (idn_testsuite_getstatus(ctx) != idn_teststatus_pass)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (strcmp(expected, gotten) == 0)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_setstatus(ctx, idn_teststatus_fail);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews msg = (char *)malloc(strlen(expected) * 4 + strlen(gotten) * 4 + 32);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews expected_hex = make_hex_string(expected);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews gotten_hex = make_hex_string(gotten);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (msg == NULL || expected_hex == NULL || gotten_hex == NULL) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews msg = "";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews } else {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews sprintf(msg, "`%s' expected, but got `%s'",
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews expected_hex, gotten_hex);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews put_failure_message(ctx, msg, file, lineno);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(msg);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(expected_hex);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(gotten_hex);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_assertptr(idn_testsuite_t ctx, const void *gotten,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const void *expected, const char *file, int lineno) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *msg;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL && file != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (idn_testsuite_getstatus(ctx) != idn_teststatus_pass)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (expected == gotten)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_setstatus(ctx, idn_teststatus_fail);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (expected == NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews msg = "NULL expected, but got non-NULL";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews else if (gotten == NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews msg = "non-NULL expected, but got NULL";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews else
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews msg = "expected pointer != gotten pointer";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews put_failure_message(ctx, msg, file, lineno);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_assertptrne(idn_testsuite_t ctx,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const void *gotten, const void *unexpected,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const char *file, int lineno) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *msg;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL && file != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (idn_testsuite_getstatus(ctx) != idn_teststatus_pass)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (unexpected != gotten)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_setstatus(ctx, idn_teststatus_fail);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (unexpected == NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews msg = "non-NULL unexpected, but got NULL";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews else if (gotten == NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews msg = "non-NULL expected, but got NULL";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews else
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews msg = "expected pointer == gotten pointer";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews put_failure_message(ctx, msg, file, lineno);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_assertresult(idn_testsuite_t ctx,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_result_t gotten, idn_result_t expected,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const char *file, int lineno) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char msg[256]; /* large enough */
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL && file != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (idn_testsuite_getstatus(ctx) != idn_teststatus_pass)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (expected == gotten)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_setstatus(ctx, idn_teststatus_fail);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews sprintf(msg, "`%s' expected, but got `%s'",
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_result_tostring(expected), idn_result_tostring(gotten));
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews put_failure_message(ctx, msg, file, lineno);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsvoid
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_assertucs4string(idn_testsuite_t ctx,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const unsigned long *gotten,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const unsigned long *expected,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const char *file, int lineno) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *expected_hex = NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *gotten_hex = NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *msg;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews assert(ctx != NULL && gotten != NULL && expected != NULL &&
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews file != NULL);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (idn_testsuite_getstatus(ctx) != idn_teststatus_pass)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (idn_ucs4_strcmp(expected, gotten) == 0)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_setstatus(ctx, idn_teststatus_fail);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews msg = (char *)malloc(idn_ucs4_strlen(expected) * 8 +
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_ucs4_strlen(gotten) * 8 + 32);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews expected_hex = make_hex_ucs4string(expected);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews gotten_hex = make_hex_ucs4string(gotten);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (msg == NULL || expected_hex == NULL || gotten_hex == NULL) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews msg = "";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews } else {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews sprintf(msg, "`%s' expected, but got `%s'",
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews expected_hex, gotten_hex);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews put_failure_message(ctx, msg, file, lineno);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(msg);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(expected_hex);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews free(gotten_hex);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstatic char *
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsmake_hex_string(const char *string) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews static const char hex[] = {"0123456789abcdef"};
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *hex_string;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const char *src;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *dst;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews hex_string = (char *)malloc((strlen(string)) * 4 + 1);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (hex_string == NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews for (src = string, dst = hex_string; *src != '\0'; src++) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (0x20 <= *src && *src <= 0x7e && *src != '\\') {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = *src;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews } else {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = '\\';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = 'x';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = hex[*(const unsigned char *)src >> 4];
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = hex[*src & 0x0f];
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst = '\0';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return hex_string;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews#define UCS4_MAX 0x10fffffUL
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstatic char *
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsmake_hex_ucs4string(const unsigned long *string) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews static const char hex[] = {"0123456789abcdef"};
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *hex_string;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const unsigned long *src;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char *dst;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews hex_string = (char *)malloc((idn_ucs4_strlen(string)) * 8 + 1);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (hex_string == NULL)
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return NULL;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews for (src = string, dst = hex_string; *src != '\0'; src++) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (0x20 <= *src && *src <= 0x7e && *src != '\\') {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = *src;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews } else if (*src <= UCS4_MAX) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = '\\';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = 'u';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (*src >= 0x100000) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = hex[(*src >> 20) & 0x0f];
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews if (*src >= 0x10000) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = hex[(*src >> 16) & 0x0f];
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = hex[(*src >> 12) & 0x0f];
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = hex[(*src >> 8) & 0x0f];
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = hex[(*src >> 4) & 0x0f];
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = hex[*src & 0x0f];
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews } else {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = '\\';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = 'u';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = '?';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = '?';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = '?';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst++ = '?';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews }
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews *dst = '\0';
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews return hex_string;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstatic void
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsput_failure_message(idn_testsuite_t ctx, const char *msg, const char *file,
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews int lineno) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_msgproc_t proc;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews char buffer[256];
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews const char *title;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews proc = (ctx->msgproc == NULL) ?
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews idn_testsuite_msgtostderr : ctx->msgproc;
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews title = (ctx->current_testcase != NULL &&
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->current_testcase->title != NULL) ?
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews ctx->current_testcase->title : "anonymous";
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews sprintf(buffer, "%.100s: In test `%.100s':", file, title);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews (*proc)(buffer);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews sprintf(buffer, "%.100s:%d: failed (%.100s)", file, lineno, msg);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews (*proc)(buffer);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsstatic void
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrewsidn_testsuite_msgtostderr(const char *msg) {
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews fputs(msg, stderr);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews fputc('\n', stderr);
5c526acb82c882e41b655c31f5fa4425c87b671cMark Andrews}