1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************************
3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   Copyright (C) 1996-2009, International Business Machines
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************************
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h>
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdlib.h>
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <string.h>
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <assert.h>
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdarg.h>
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utrace.h"
1685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/uclean.h"
1785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "umutex.h"
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* NOTES:
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru   3/20/1999 srl - strncpy called w/o setting nulls at the end
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MAXTESTNAME 128
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MAXTESTS  512
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MAX_TEST_LOG 4096
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct TestNode
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  void (*test)(void);
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  struct TestNode* sibling;
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  struct TestNode* child;
3285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  char name[1]; /* This is dynamically allocated off the end with malloc. */
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const struct TestNode* currentTest;
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef enum { RUNTESTS, SHOWTESTS } TestMode;
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define TEST_SEPARATOR '/'
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifndef C_TEST_IMPL
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define C_TEST_IMPL
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ctest.h"
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic char ERROR_LOG[MAX_TEST_LOG][MAXTESTNAME];
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Local prototypes */
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic TestNode* addTestNode( TestNode *root, const char *name );
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
5285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic TestNode *createTestNode(const char* name, int32_t nameLen);
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int strncmp_nullcheck( const char* s1,
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                  const char* s2,
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                  int n );
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void getNextLevel( const char* name,
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              int* nameLen,
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              const char** nextName );
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void iterateTestsWithLevel( const TestNode *root, int len,
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                   const TestNode** list,
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                   TestMode mode);
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void help ( const char *argv0 );
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Do the work of logging an error. Doesn't increase the error count.
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @prefix optional prefix prepended to message, or NULL.
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param pattern printf style pattern
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param ap vprintf style arg list
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void vlog_err(const char *prefix, const char *pattern, va_list ap);
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void vlog_verbose(const char *prefix, const char *pattern, va_list ap);
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* If we need to make the framework multi-thread safe
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru   we need to pass around the following vars
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int ERRONEOUS_FUNCTION_COUNT = 0;
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int ERROR_COUNT = 0; /* Count of errors from all tests. */
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int DATA_ERROR_COUNT = 0; /* count of data related errors or warnings */
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int INDENT_LEVEL = 0;
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint REPEAT_TESTS_INIT = 0; /* Was REPEAT_TESTS initialized? */
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint REPEAT_TESTS = 1; /* Number of times to run the test */
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint VERBOSITY = 0; /* be No-verbose by default */
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint ERR_MSG =1; /* error messages will be displayed by default*/
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint QUICK = 1;  /* Skip some of the slower tests? */
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint WARN_ON_MISSING_DATA = 0; /* Reduce data errs to warnings? */
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUTraceLevel ICU_TRACE = UTRACE_OFF;  /* ICU tracing level */
9285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hosize_t MINIMUM_MEMORY_SIZE_FAILURE = (size_t)-1; /* Minimum library memory allocation window that will fail. */
9385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hosize_t MAXIMUM_MEMORY_SIZE_FAILURE = (size_t)-1; /* Maximum library memory allocation window that will fail. */
9485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoint32_t ALLOCATION_COUNT = 0;
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*-------------------------------------------*/
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* strncmp that also makes sure there's a \0 at s2[0] */
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int strncmp_nullcheck( const char* s1,
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru               const char* s2,
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru               int n )
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (((int)strlen(s2) >= n) && s2[n] != 0) {
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 3; /* null check fails */
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else {
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return strncmp ( s1, s2, n );
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void getNextLevel( const char* name,
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           int* nameLen,
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           const char** nextName )
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Get the next component of the name */
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *nextName = strchr(name, TEST_SEPARATOR);
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if( *nextName != 0 )
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        char n[255];
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *nameLen = (int)((*nextName) - name);
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        (*nextName)++; /* skip '/' */
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        strncpy(n, name, *nameLen);
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        n[*nameLen] = 0;
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /*printf("->%s-< [%d] -> [%s]\n", name, *nameLen, *nextName);*/
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else {
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *nameLen = (int)strlen(name);
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
13185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic TestNode *createTestNode(const char* name, int32_t nameLen)
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TestNode *newNode;
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
13585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    newNode = (TestNode*)malloc(sizeof(TestNode) + (nameLen + 1));
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    newNode->test = NULL;
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    newNode->sibling = NULL;
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    newNode->child = NULL;
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
14185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    strncpy( newNode->name, name, nameLen );
14285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    newNode->name[nameLen] = 0;
14385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return  newNode;
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid T_CTEST_EXPORT2
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerucleanUpTestTree(TestNode *tn)
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(tn->child != NULL) {
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cleanUpTestTree(tn->child);
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(tn->sibling != NULL) {
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cleanUpTestTree(tn->sibling);
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    free(tn);
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid T_CTEST_EXPORT2
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruaddTest(TestNode** root,
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TestFunctionPtr test,
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        const char* name )
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TestNode *newNode;
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*if this is the first Test created*/
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (*root == NULL)
17085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        *root = createTestNode("", 0);
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    newNode = addTestNode( *root, name );
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    assert(newNode != 0 );
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*  printf("addTest: nreName = %s\n", newNode->name );*/
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    newNode->test = test;
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* non recursive insert function */
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic TestNode *addTestNode ( TestNode *root, const char *name )
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char* nextName;
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TestNode *nextNode, *curNode;
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int nameLen; /* length of current 'name' */
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* remove leading slash */
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ( *name == TEST_SEPARATOR )
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        name++;
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    curNode = root;
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(;;)
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* Start with the next child */
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        nextNode = curNode->child;
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        getNextLevel ( name, &nameLen, &nextName );
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /*      printf("* %s\n", name );*/
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* if nextNode is already null, then curNode has no children
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        -- add them */
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if( nextNode == NULL )
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* Add all children of the node */
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            do
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* Get the next component of the name */
20985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                getNextLevel(name, &nameLen, &nextName);
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* update curName to have the next name segment */
21285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                curNode->child = createTestNode(name, nameLen);
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* printf("*** added %s\n", curNode->child->name );*/
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                curNode = curNode->child;
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                name = nextName;
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while( name != NULL );
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return curNode;
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* Search across for the name */
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (strncmp_nullcheck ( name, nextNode->name, nameLen) != 0 )
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            curNode = nextNode;
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            nextNode = nextNode -> sibling;
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if ( nextNode == NULL )
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* Did not find 'name' on this level. */
23185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                nextNode = createTestNode(name, nameLen);
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                curNode->sibling = nextNode;
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* nextNode matches 'name' */
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (nextName == NULL) /* end of the line */
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return nextNode;
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* Loop again with the next item */
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        name = nextName;
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        curNode = nextNode;
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void iterateTestsWithLevel ( const TestNode* root,
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 int len,
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 const TestNode** list,
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 TestMode mode)
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int i;
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int saveIndent;
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char pathToFunction[MAXTESTNAME] = "";
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char separatorString[2] = { TEST_SEPARATOR, '\0'};
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ( root == NULL )
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    list[len++] = root;
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for ( i=0;i<(len-1);i++ )
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        strcat(pathToFunction, list[i]->name);
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        strcat(pathToFunction, separatorString);
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    strcat(pathToFunction, list[i]->name);
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    INDENT_LEVEL = len;
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ( (mode == RUNTESTS) && (root->test != NULL))
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int myERROR_COUNT = ERROR_COUNT;
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        currentTest = root;
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        root->test();
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        currentTest = NULL;
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (myERROR_COUNT != ERROR_COUNT)
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_info("---[%d ERRORS] ", ERROR_COUNT - myERROR_COUNT);
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            strcpy(ERROR_LOG[ERRONEOUS_FUNCTION_COUNT++], pathToFunction);
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_info("---[OK] ");
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we want these messages to be at 0 indent. so just push the indent level breifly. */
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    saveIndent = INDENT_LEVEL;
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    INDENT_LEVEL = 0;
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    log_info("%s%s%c\n", (list[i]->test||mode==SHOWTESTS)?"---":"",pathToFunction, list[i]->test?' ':TEST_SEPARATOR );
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    INDENT_LEVEL = saveIndent;
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    iterateTestsWithLevel ( root->child, len, list, mode );
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len--;
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ( len != 0 ) /* DO NOT iterate over siblings of the root. */
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        iterateTestsWithLevel ( root->sibling, len, list, mode );
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid T_CTEST_EXPORT2
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerushowTests ( const TestNode *root )
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* make up one for them */
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const TestNode *aList[MAXTESTS];
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (root == NULL)
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_err("TEST CAN'T BE FOUND!");
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    iterateTestsWithLevel ( root, 0, aList, SHOWTESTS );
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid T_CTEST_EXPORT2
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerurunTests ( const TestNode *root )
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int i;
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const TestNode *aList[MAXTESTS];
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* make up one for them */
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (root == NULL)
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_err("TEST CAN'T BE FOUND!\n");
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ERRONEOUS_FUNCTION_COUNT = ERROR_COUNT = 0;
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    iterateTestsWithLevel ( root, 0, aList, RUNTESTS );
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*print out result summary*/
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (ERROR_COUNT)
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_info("\nSUMMARY:\n******* [Total error count:\t%d]\n Errors in\n", ERROR_COUNT);
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (i=0;i < ERRONEOUS_FUNCTION_COUNT; i++)
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            log_info("[%s]\n",ERROR_LOG[i]);
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      log_info("\n[All tests passed successfully...]\n");
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(DATA_ERROR_COUNT) {
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      if(WARN_ON_MISSING_DATA==0) {
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_info("\t*Note* some errors are data-loading related. If the data used is not the \n"
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 "\tstock ICU data (i.e some have been added or removed), consider using\n"
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 "\tthe '-w' option to turn these errors into warnings.\n");
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      } else {
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_info("\t*WARNING* some data-loading errors were ignored by the -w option.\n");
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      }
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst char* T_CTEST_EXPORT2
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerugetTestName(void)
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  if(currentTest != NULL) {
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return currentTest->name;
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  } else {
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return NULL;
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  }
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst TestNode* T_CTEST_EXPORT2
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerugetTest(const TestNode* root, const char* name)
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char* nextName;
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TestNode *nextNode;
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const TestNode* curNode;
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int nameLen; /* length of current 'name' */
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (root == NULL) {
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        log_err("TEST CAN'T BE FOUND!\n");
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return NULL;
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* remove leading slash */
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ( *name == TEST_SEPARATOR )
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        name++;
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    curNode = root;
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(;;)
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* Start with the next child */
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        nextNode = curNode->child;
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        getNextLevel ( name, &nameLen, &nextName );
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /*      printf("* %s\n", name );*/
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* if nextNode is already null, then curNode has no children
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        -- add them */
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if( nextNode == NULL )
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return NULL;
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* Search across for the name */
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (strncmp_nullcheck ( name, nextNode->name, nameLen) != 0 )
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            curNode = nextNode;
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            nextNode = nextNode -> sibling;
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if ( nextNode == NULL )
410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* Did not find 'name' on this level. */
412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return NULL;
413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* nextNode matches 'name' */
417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (nextName == NULL) /* end of the line */
419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return nextNode;
421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* Loop again with the next item */
424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        name = nextName;
425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        curNode = nextNode;
426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void vlog_err(const char *prefix, const char *pattern, va_list ap)
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if( ERR_MSG == FALSE){
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(stderr, "%-*s", INDENT_LEVEL," " );
435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(prefix) {
436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fputs(prefix, stderr);
437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    vfprintf(stderr, pattern, ap);
439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fflush(stderr);
440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    va_end(ap);
441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid T_CTEST_EXPORT2
444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvlog_info(const char *prefix, const char *pattern, va_list ap)
445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(stdout, "%-*s", INDENT_LEVEL," " );
447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(prefix) {
448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fputs(prefix, stdout);
449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    vfprintf(stdout, pattern, ap);
451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fflush(stdout);
452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    va_end(ap);
453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void vlog_verbose(const char *prefix, const char *pattern, va_list ap)
456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ( VERBOSITY == FALSE )
458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(stdout, "%-*s", INDENT_LEVEL," " );
461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(prefix) {
462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fputs(prefix, stdout);
463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    vfprintf(stdout, pattern, ap);
465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fflush(stdout);
466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    va_end(ap);
467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid T_CTEST_EXPORT2
470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querulog_err(const char* pattern, ...)
471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    va_list ap;
473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(strchr(pattern, '\n') != NULL) {
474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /*
475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         * Count errors only if there is a line feed in the pattern
476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         * so that we do not exaggerate our error count.
477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru         */
478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ++ERROR_COUNT;
479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    va_start(ap, pattern);
481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    vlog_err(NULL, pattern, ap);
482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid T_CTEST_EXPORT2
48585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Holog_err_status(UErrorCode status, const char* pattern, ...)
48685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{
48785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    va_list ap;
48885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    va_start(ap, pattern);
48985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
49085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if ((status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR)) {
49185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ++DATA_ERROR_COUNT; /* for informational message at the end */
49285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
49385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (WARN_ON_MISSING_DATA == 0) {
49485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* Fatal error. */
49585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (strchr(pattern, '\n') != NULL) {
49685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                ++ERROR_COUNT;
49785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
49885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            vlog_err(NULL, pattern, ap); /* no need for prefix in default case */
49985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
50085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            vlog_info("[DATA] ", pattern, ap);
50185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
50285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
50385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* Fatal error. */
50485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(strchr(pattern, '\n') != NULL) {
50585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ++ERROR_COUNT;
50685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
50785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        vlog_err(NULL, pattern, ap); /* no need for prefix in default case */
50885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
50985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
51085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
51185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid T_CTEST_EXPORT2
512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querulog_info(const char* pattern, ...)
513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    va_list ap;
515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    va_start(ap, pattern);
517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    vlog_info(NULL, pattern, ap);
518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid T_CTEST_EXPORT2
521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querulog_verbose(const char* pattern, ...)
522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    va_list ap;
524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    va_start(ap, pattern);
526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    vlog_verbose(NULL, pattern, ap);
527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid T_CTEST_EXPORT2
531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querulog_data_err(const char* pattern, ...)
532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
53385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    va_list ap;
53485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    va_start(ap, pattern);
535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
53685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    ++DATA_ERROR_COUNT; /* for informational message at the end */
537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
53885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if(WARN_ON_MISSING_DATA == 0) {
53985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* Fatal error. */
54085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(strchr(pattern, '\n') != NULL) {
54185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ++ERROR_COUNT;
54285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
54385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        vlog_err(NULL, pattern, ap); /* no need for prefix in default case */
54485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
54585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        vlog_info("[DATA] ", pattern, ap);
546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
55085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/*
55185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Tracing functions.
55285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */
55385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic int traceFnNestingDepth = 0;
55485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_CDECL_BEGIN
55585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void U_CALLCONV TraceEntry(const void *context, int32_t fnNumber) {
55685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char buf[500];
55785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrace_format(buf, sizeof(buf), traceFnNestingDepth*3, "%s() enter.\n", utrace_functionName(fnNumber));    buf[sizeof(buf)-1]=0;
55885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fputs(buf, stdout);
55985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    traceFnNestingDepth++;
56085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
56185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
56285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void U_CALLCONV TraceExit(const void *context, int32_t fnNumber, const char *fmt, va_list args) {    char buf[500];
56385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
56485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (traceFnNestingDepth>0) {
56585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        traceFnNestingDepth--;
56685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
56785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrace_format(buf, sizeof(buf), traceFnNestingDepth*3, "%s() ", utrace_functionName(fnNumber));    buf[sizeof(buf)-1]=0;
56885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fputs(buf, stdout);
56985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrace_vformat(buf, sizeof(buf), traceFnNestingDepth*3, fmt, args);
57085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    buf[sizeof(buf)-1]=0;
57185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fputs(buf, stdout);
57285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    putc('\n', stdout);
57385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
57485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
57585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void U_CALLCONV TraceData(const void *context, int32_t fnNumber,
57685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                          int32_t level, const char *fmt, va_list args) {
57785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    char buf[500];
57885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    utrace_vformat(buf, sizeof(buf), traceFnNestingDepth*3, fmt, args);
57985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    buf[sizeof(buf)-1]=0;
58085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fputs(buf, stdout);
58185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    putc('\n', stdout);
58285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
58385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
58485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void *U_CALLCONV ctest_libMalloc(const void *context, size_t size) {
58585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*if (VERBOSITY) {
58685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        printf("Allocated %ld\n", (long)size);
58785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }*/
58885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (MINIMUM_MEMORY_SIZE_FAILURE <= size && size <= MAXIMUM_MEMORY_SIZE_FAILURE) {
58985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return NULL;
59085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
59185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    umtx_atomic_inc(&ALLOCATION_COUNT);
59285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return malloc(size);
59385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
59485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void *U_CALLCONV ctest_libRealloc(const void *context, void *mem, size_t size) {
59585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*if (VERBOSITY) {
59685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        printf("Reallocated %ld\n", (long)size);
59785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }*/
59885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (MINIMUM_MEMORY_SIZE_FAILURE <= size && size <= MAXIMUM_MEMORY_SIZE_FAILURE) {
59985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /*free(mem);*/ /* Realloc doesn't free on failure. */
60085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return NULL;
60185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
60285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (mem == NULL) {
60385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* New allocation. */
60485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        umtx_atomic_inc(&ALLOCATION_COUNT);
60585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
60685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return realloc(mem, size);
60785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
60885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic void U_CALLCONV ctest_libFree(const void *context, void *mem) {
60985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (mem != NULL) {
61085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        umtx_atomic_dec(&ALLOCATION_COUNT);
61185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
61285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    free(mem);
61385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
61485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint T_CTEST_EXPORT2
61685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoinitArgs( int argc, const char* const argv[], ArgHandlerPtr argHandler, void *context)
617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int                i;
619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int                doList = FALSE;
62085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho	int                argSkip = 0;
621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    VERBOSITY = FALSE;
623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ERR_MSG = TRUE;
624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for( i=1; i<argc; i++)
626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if ( argv[i][0] == '/' )
628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
62985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* We don't run the tests here. */
63085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            continue;
63185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
63285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        else if ((strcmp( argv[i], "-a") == 0) || (strcmp(argv[i],"-all") == 0))
63385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {
63485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* We don't run the tests here. */
63585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            continue;
636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-v" )==0 || strcmp( argv[i], "-verbose")==0)
638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            VERBOSITY = TRUE;
640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-l" )==0 )
642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            doList = TRUE;
644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-e1") == 0)
646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            QUICK = -1;
648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-e") ==0)
650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            QUICK = 0;
652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-w") ==0)
654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            WARN_ON_MISSING_DATA = TRUE;
656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
65785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        else if (strcmp( argv[i], "-m") ==0)
65885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {
65985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UErrorCode errorCode = U_ZERO_ERROR;
66085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (i+1 < argc) {
66185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                char *endPtr = NULL;
66285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                i++;
66385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                MINIMUM_MEMORY_SIZE_FAILURE = (size_t)strtol(argv[i], &endPtr, 10);
66485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if (endPtr == argv[i]) {
66585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    printf("Can't parse %s\n", argv[i]);
66685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    help(argv[0]);
66785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    return 0;
66885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
66985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if (*endPtr == '-') {
67085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    char *maxPtr = endPtr+1;
67185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    endPtr = NULL;
67285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    MAXIMUM_MEMORY_SIZE_FAILURE = (size_t)strtol(maxPtr, &endPtr, 10);
67385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    if (endPtr == argv[i]) {
67485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        printf("Can't parse %s\n", argv[i]);
67585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        help(argv[0]);
67685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        return 0;
67785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    }
67885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
67985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
68085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            /* Use the default value */
68185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            u_setMemoryFunctions(NULL, ctest_libMalloc, ctest_libRealloc, ctest_libFree, &errorCode);
68285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (U_FAILURE(errorCode)) {
68385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                printf("u_setMemoryFunctions returned %s\n", u_errorName(errorCode));
68485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return 0;
68585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
68685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if(strcmp( argv[i], "-n") == 0 || strcmp( argv[i], "-no_err_msg") == 0)
688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ERR_MSG = FALSE;
690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-r") == 0)
692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (!REPEAT_TESTS_INIT) {
694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                REPEAT_TESTS++;
695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-t_info") == 0) {
698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ICU_TRACE = UTRACE_INFO;
699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-t_error") == 0) {
701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ICU_TRACE = UTRACE_ERROR;
702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-t_warn") == 0) {
704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ICU_TRACE = UTRACE_WARNING;
705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-t_verbose") == 0) {
707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ICU_TRACE = UTRACE_VERBOSE;
708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-t_oc") == 0) {
710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ICU_TRACE = UTRACE_OPEN_CLOSE;
711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (strcmp( argv[i], "-h" )==0 || strcmp( argv[i], "--help" )==0)
713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            help( argv[0] );
715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return 0;
716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
71785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        else if (argHandler != NULL && (argSkip = argHandler(i, argc, argv, context)) > 0)
71885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {
71985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            i += argSkip - 1;
72085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            printf("* unknown option: %s\n", argv[i]);
724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            help( argv[0] );
72585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return 0;
72685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
72785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
72885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (ICU_TRACE != UTRACE_OFF) {
72985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrace_setFunctions(NULL, TraceEntry, TraceExit, TraceData);
73085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        utrace_setLevel(ICU_TRACE);
73185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
73285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
73385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return 1; /* total error count */
73485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
73585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
73685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoint T_CTEST_EXPORT2
73785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HorunTestRequest(const TestNode* root,
73885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho             int argc,
73985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho             const char* const argv[])
74085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{
74185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /**
74285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     * This main will parse the l, v, h, n, and path arguments
74385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho     */
74485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const TestNode*    toRun;
74585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int                i;
74685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int                doList = FALSE;
74785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int                subtreeOptionSeen = FALSE;
74885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
74985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int                errorCount = 0;
75085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
75185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    toRun = root;
75285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
75385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for( i=1; i<argc; i++)
75485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    {
75585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if ( argv[i][0] == '/' )
75685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {
75785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            printf("Selecting subtree '%s'\n", argv[i]);
75885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
75985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if ( argv[i][1] == 0 )
76085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                toRun = root;
76185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            else
76285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                toRun = getTest(root, argv[i]);
76385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
76485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if ( toRun == NULL )
76585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            {
76685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                printf("* Could not find any matching subtree\n");
76785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return -1;
76885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
76985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
77085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if( doList == TRUE)
77185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                showTests(toRun);
77285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            else
77385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                runTests(toRun);
77485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
77585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            errorCount += ERROR_COUNT;
77685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
77785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            subtreeOptionSeen = TRUE;
77885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else if ((strcmp( argv[i], "-a") == 0) || (strcmp(argv[i],"-all") == 0)) {
77985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            subtreeOptionSeen=FALSE;
78085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else if (strcmp( argv[i], "-l") == 0) {
78185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            doList = TRUE;
782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
78385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* else option already handled by initArgs */
784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if( subtreeOptionSeen == FALSE) /* no other subtree given, run the default */
787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if( doList == TRUE)
789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            showTests(toRun);
790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            runTests(toRun);
792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        errorCount += ERROR_COUNT;
794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else
796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if( ( doList == FALSE ) && ( errorCount > 0 ) )
798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            printf(" Total errors: %d\n", errorCount );
799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    REPEAT_TESTS_INIT = 1;
802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return errorCount; /* total error count */
804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Display program invocation arguments
808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void help ( const char *argv0 )
811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printf("Usage: %s [ -l ] [ -v ] [ -verbose] [-a] [ -all] [-n] [ -no_err_msg]\n"
81385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           "    [ -h ] [-t_info | -t_error | -t_warn | -t_oc | -t_verbose] [-m n[-q] ]\n"
81485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           "    [ /path/to/test ]\n",
815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            argv0);
816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printf("    -l  To get a list of test names\n");
817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printf("    -e  to do exhaustive testing\n");
818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printf("    -verbose To turn ON verbosity\n");
819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printf("    -v  To turn ON verbosity(same as -verbose)\n");
820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printf("    -h  To print this message\n");
821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printf("    -n  To turn OFF printing error messages\n");
822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printf("    -w  Don't fail on data-loading errs, just warn. Useful if\n"
823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           "        user has reduced/changed the common set of ICU data \n");
824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printf("    -t_info | -t_error | -t_warn | -t_oc | -t_verbose  Enable ICU tracing\n");
825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printf("    -no_err_msg (same as -n) \n");
82685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    printf("    -m n[-q] Min-Max memory size that will cause an allocation failure.\n");
82785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    printf("        The default is the maximum value of size_t. Max is optional.\n");
82885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    printf("    -r  Repeat tests after calling u_cleanup \n");
82985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    printf("    [/subtest]  To run a subtest \n");
830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printf("    eg: to run just the utility tests type: cintltest /tsutil) \n");
831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
833