1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)********************************************************************************
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Copyright (C) 1996-2010, International Business Machines
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Corporation and others.  All Rights Reserved.
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)********************************************************************************
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdio.h>
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdlib.h>
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <string.h>
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <assert.h>
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdarg.h>
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <ctype.h>
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utrace.h"
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uclean.h"
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "umutex.h"
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "putilimp.h"
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* NOTES:
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)   3/20/1999 srl - strncpy called w/o setting nulls at the end
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAXTESTNAME 128
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAXTESTS  512
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_TEST_LOG 4096
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *  How may columns to indent the 'OK' markers.
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define FLAG_INDENT 45
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   How many lines of scrollage can go by before we need to remind the user what the test is.
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define PAGE_SIZE_LIMIT 25
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef SHOW_TIMES
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define SHOW_TIMES 1
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)struct TestNode
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  void (*test)(void);
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  struct TestNode* sibling;
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  struct TestNode* child;
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  char name[1]; /* This is dynamically allocated off the end with malloc. */
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const struct TestNode* currentTest;
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef enum { RUNTESTS, SHOWTESTS } TestMode;
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define TEST_SEPARATOR '/'
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef C_TEST_IMPL
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define C_TEST_IMPL
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ctest.h"
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char ERROR_LOG[MAX_TEST_LOG][MAXTESTNAME];
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Local prototypes */
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static TestNode* addTestNode( TestNode *root, const char *name );
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static TestNode *createTestNode(const char* name, int32_t nameLen);
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int strncmp_nullcheck( const char* s1,
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  const char* s2,
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  int n );
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void getNextLevel( const char* name,
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              int* nameLen,
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              const char** nextName );
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void iterateTestsWithLevel( const TestNode *root, int depth,
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   const TestNode** nodeList,
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   TestMode mode);
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void help ( const char *argv0 );
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Do the work of logging an error. Doesn't increase the error count.
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @prefix optional prefix prepended to message, or NULL.
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param pattern printf style pattern
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param ap vprintf style arg list
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void vlog_err(const char *prefix, const char *pattern, va_list ap);
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void vlog_verbose(const char *prefix, const char *pattern, va_list ap);
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Log test structure, with indent
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param pattern printf pattern
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void log_testinfo_i(const char *pattern, ...);
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Log test structure, NO indent
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param pattern printf pattern
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void log_testinfo(const char *pattern, ...);
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* If we need to make the framework multi-thread safe
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)   we need to pass around the following vars
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int ERRONEOUS_FUNCTION_COUNT = 0;
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int ERROR_COUNT = 0; /* Count of errors from all tests. */
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int ONE_ERROR = 0; /* were there any other errors? */
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int DATA_ERROR_COUNT = 0; /* count of data related errors or warnings */
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int INDENT_LEVEL = 0;
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool ON_LINE = FALSE; /* are we on the top line with our test name? */
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool HANGING_OUTPUT = FALSE; /* did the user leave us without a trailing \n ? */
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int GLOBAL_PRINT_COUNT = 0; /* global count of printouts */
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int REPEAT_TESTS_INIT = 0; /* Was REPEAT_TESTS initialized? */
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int REPEAT_TESTS = 1; /* Number of times to run the test */
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int VERBOSITY = 0; /* be No-verbose by default */
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int ERR_MSG =1; /* error messages will be displayed by default*/
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int QUICK = 1;  /* Skip some of the slower tests? */
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int WARN_ON_MISSING_DATA = 0; /* Reduce data errs to warnings? */
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UTraceLevel ICU_TRACE = UTRACE_OFF;  /* ICU tracing level */
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)size_t MINIMUM_MEMORY_SIZE_FAILURE = (size_t)-1; /* Minimum library memory allocation window that will fail. */
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)size_t MAXIMUM_MEMORY_SIZE_FAILURE = (size_t)-1; /* Maximum library memory allocation window that will fail. */
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t ALLOCATION_COUNT = 0;
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char *ARGV_0 = "[ALL]";
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char *XML_FILE_NAME=NULL;
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char XML_PREFIX[256];
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)FILE *XML_FILE = NULL;
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*-------------------------------------------*/
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* strncmp that also makes sure there's a \0 at s2[0] */
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int strncmp_nullcheck( const char* s1,
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               const char* s2,
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               int n )
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (((int)strlen(s2) >= n) && s2[n] != 0) {
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 3; /* null check fails */
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else {
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return strncmp ( s1, s2, n );
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void getNextLevel( const char* name,
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           int* nameLen,
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           const char** nextName )
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Get the next component of the name */
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    *nextName = strchr(name, TEST_SEPARATOR);
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if( *nextName != 0 )
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        char n[255];
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *nameLen = (int)((*nextName) - name);
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        (*nextName)++; /* skip '/' */
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        strncpy(n, name, *nameLen);
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        n[*nameLen] = 0;
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /*printf("->%s-< [%d] -> [%s]\n", name, *nameLen, *nextName);*/
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else {
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *nameLen = (int)strlen(name);
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static TestNode *createTestNode(const char* name, int32_t nameLen)
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNode *newNode;
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    newNode = (TestNode*)malloc(sizeof(TestNode) + (nameLen + 1));
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    newNode->test = NULL;
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    newNode->sibling = NULL;
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    newNode->child = NULL;
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    strncpy( newNode->name, name, nameLen );
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    newNode->name[nameLen] = 0;
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return  newNode;
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)cleanUpTestTree(TestNode *tn)
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(tn->child != NULL) {
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cleanUpTestTree(tn->child);
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(tn->sibling != NULL) {
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cleanUpTestTree(tn->sibling);
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    free(tn);
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addTest(TestNode** root,
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        TestFunctionPtr test,
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        const char* name )
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNode *newNode;
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*if this is the first Test created*/
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (*root == NULL)
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *root = createTestNode("", 0);
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    newNode = addTestNode( *root, name );
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    assert(newNode != 0 );
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*  printf("addTest: nreName = %s\n", newNode->name );*/
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    newNode->test = test;
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* non recursive insert function */
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static TestNode *addTestNode ( TestNode *root, const char *name )
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const char* nextName;
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNode *nextNode, *curNode;
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int nameLen; /* length of current 'name' */
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* remove leading slash */
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ( *name == TEST_SEPARATOR )
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        name++;
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    curNode = root;
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(;;)
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Start with the next child */
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        nextNode = curNode->child;
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        getNextLevel ( name, &nameLen, &nextName );
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /*      printf("* %s\n", name );*/
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* if nextNode is already null, then curNode has no children
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        -- add them */
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if( nextNode == NULL )
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* Add all children of the node */
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            do
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                /* Get the next component of the name */
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                getNextLevel(name, &nameLen, &nextName);
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                /* update curName to have the next name segment */
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                curNode->child = createTestNode(name, nameLen);
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                /* printf("*** added %s\n", curNode->child->name );*/
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                curNode = curNode->child;
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                name = nextName;
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            while( name != NULL );
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return curNode;
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Search across for the name */
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        while (strncmp_nullcheck ( name, nextNode->name, nameLen) != 0 )
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            curNode = nextNode;
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            nextNode = nextNode -> sibling;
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ( nextNode == NULL )
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                /* Did not find 'name' on this level. */
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                nextNode = createTestNode(name, nameLen);
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                curNode->sibling = nextNode;
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* nextNode matches 'name' */
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (nextName == NULL) /* end of the line */
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return nextNode;
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Loop again with the next item */
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        name = nextName;
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        curNode = nextNode;
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Log the time taken. May not output anything.
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param deltaTime change in time
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2 str_timeDelta(char *str, UDate deltaTime) {
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (deltaTime > 110000.0 ) {
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    double mins = uprv_floor(deltaTime/60000.0);
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    sprintf(str, "[(%.0fm %.1fs)]", mins, (deltaTime-(mins*60000.0))/1000.0);
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  } else if (deltaTime > 1500.0) {
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    sprintf(str, "((%.1fs))", deltaTime/1000.0);
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  } else if(deltaTime>900.0) {
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    sprintf(str, "( %.2fs )", deltaTime/1000.0);
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  } else if(deltaTime > 5.0) {
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    sprintf(str, " (%.0fms) ", deltaTime);
301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  } else {
302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    str[0]=0; /* at least terminate it. */
303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void print_timeDelta(UDate deltaTime) {
307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  char str[256];
308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  str_timeDelta(str, deltaTime);
309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(str[0]) {
310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("%s", str);
311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Run or list tests (according to mode) in a subtree.
316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param root root of the subtree to operate on
318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param depth The depth of this tree (0=root)
319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param nodeList an array of MAXTESTS depth that's used for keeping track of where we are. nodeList[depth] points to the 'parent' at depth depth.
320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param mode what mode we are operating in.
321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void iterateTestsWithLevel ( const TestNode* root,
323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                 int depth,
324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                 const TestNode** nodeList,
325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                 TestMode mode)
326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int i;
328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char pathToFunction[MAXTESTNAME] = "";
330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char separatorString[2] = { TEST_SEPARATOR, '\0'};
331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if SHOW_TIMES
332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDate allStartTime = -1, allStopTime = -1;
333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(depth<2) {
336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      allStartTime = uprv_getRawUTCtime();
337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ( root == NULL )
340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* record the current root node, and increment depth. */
343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    nodeList[depth++] = root;
344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* depth is now the depth of root's children. */
345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Collect the 'path' to the current subtree. */
347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for ( i=0;i<(depth-1);i++ )
348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        strcat(pathToFunction, nodeList[i]->name);
350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        strcat(pathToFunction, separatorString);
351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    strcat(pathToFunction, nodeList[i]->name); /* including 'root' */
353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* print test name and space. */
355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    INDENT_LEVEL = depth-1;
356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(root->name[0]) {
357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	log_testinfo_i("%s ", root->name);
358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	log_testinfo_i("(%s) ", ARGV_0);
360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ON_LINE = TRUE;  /* we are still on the line with the test name */
362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ( (mode == RUNTESTS) &&
365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)		(root->test != NULL))  /* if root is a leaf node, run it */
366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int myERROR_COUNT = ERROR_COUNT;
368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int myGLOBAL_PRINT_COUNT = GLOBAL_PRINT_COUNT;
369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if SHOW_TIMES
370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UDate startTime, stopTime;
371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        char timeDelta[256];
372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        char timeSeconds[256];
373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else
374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        const char timeDelta[] = "(unknown)";
375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        const char timeSeconds[] = "0.000";
376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        currentTest = root;
378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        INDENT_LEVEL = depth;  /* depth of subitems */
379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ONE_ERROR=0;
380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        HANGING_OUTPUT=FALSE;
381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if SHOW_TIMES
382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        startTime = uprv_getRawUTCtime();
383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        root->test();   /* PERFORM THE TEST ************************/
385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if SHOW_TIMES
386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        stopTime = uprv_getRawUTCtime();
387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(HANGING_OUTPUT) {
389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          log_testinfo("\n");
390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          HANGING_OUTPUT=FALSE;
391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        INDENT_LEVEL = depth-1;  /* depth of root */
393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        currentTest = NULL;
394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if((ONE_ERROR>0)&&(ERROR_COUNT==0)) {
395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          ERROR_COUNT++; /* There was an error without a newline */
396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ONE_ERROR=0;
398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if SHOW_TIMES
400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        str_timeDelta(timeDelta, stopTime-startTime);
401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        sprintf(timeSeconds, "%f", (stopTime-startTime)/1000.0);
402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ctest_xml_testcase(pathToFunction, pathToFunction, timeSeconds, (myERROR_COUNT!=ERROR_COUNT)?"error":NULL);
404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (myERROR_COUNT != ERROR_COUNT) {
406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          log_testinfo_i("} ---[%d ERRORS in %s] ", ERROR_COUNT - myERROR_COUNT, pathToFunction);
407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          strcpy(ERROR_LOG[ERRONEOUS_FUNCTION_COUNT++], pathToFunction);
408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          if(!ON_LINE) { /* had some output */
410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int spaces = FLAG_INDENT-(depth-1);
411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_testinfo_i("} %*s[OK] ", spaces, "---");
412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if((GLOBAL_PRINT_COUNT-myGLOBAL_PRINT_COUNT)>PAGE_SIZE_LIMIT) {
413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              log_testinfo(" %s ", pathToFunction); /* in case they forgot. */
414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          } else {
416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* put -- out at 30 sp. */
417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int spaces = FLAG_INDENT-(strlen(root->name)+depth);
418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(spaces<0) spaces=0;
419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            log_testinfo(" %*s[OK] ", spaces,"---");
420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          }
421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if SHOW_TIMES
424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(timeDelta[0]) printf("%s", timeDelta);
425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ON_LINE = TRUE; /* we are back on-line */
428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    INDENT_LEVEL = depth-1; /* root */
431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* we want these messages to be at 0 indent. so just push the indent level breifly. */
433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(mode==SHOWTESTS) {
434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	log_testinfo("---%s%c\n",pathToFunction, nodeList[i]->test?' ':TEST_SEPARATOR );
435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    INDENT_LEVEL = depth;
438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(root->child) {
440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int myERROR_COUNT = ERROR_COUNT;
441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int myGLOBAL_PRINT_COUNT = GLOBAL_PRINT_COUNT;
442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(mode!=SHOWTESTS) {
443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    		INDENT_LEVEL=depth-1;
444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    		log_testinfo("{\n");
445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    		INDENT_LEVEL=depth;
446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	}
447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	iterateTestsWithLevel ( root->child, depth, nodeList, mode );
449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	if(mode!=SHOWTESTS) {
451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    		INDENT_LEVEL=depth-1;
452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    		log_testinfo_i("} "); /* TODO:  summarize subtests */
453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    		if((depth>1) && (ERROR_COUNT > myERROR_COUNT)) {
454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    			log_testinfo("[%d %s in %s] ", ERROR_COUNT-myERROR_COUNT, (ERROR_COUNT-myERROR_COUNT)==1?"error":"errors", pathToFunction);
455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    		} else if((GLOBAL_PRINT_COUNT-myGLOBAL_PRINT_COUNT)>PAGE_SIZE_LIMIT || (depth<1)) {
456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  if(pathToFunction[0]) {
457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    log_testinfo(" %s ", pathToFunction); /* in case they forgot. */
458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  } else {
459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    log_testinfo(" / (%s) ", ARGV_0);
460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  }
461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    		ON_LINE=TRUE;
464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	}
465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)	}
466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    depth--;
467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if SHOW_TIMES
469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(depth<2) {
470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      allStopTime = uprv_getRawUTCtime();
471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      print_timeDelta(allStopTime-allStartTime);
472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(mode!=SHOWTESTS && ON_LINE) {
476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	log_testinfo("\n");
477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ( depth != 0 ) { /* DO NOT iterate over siblings of the root. TODO: why not? */
480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        iterateTestsWithLevel ( root->sibling, depth, nodeList, mode );
481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2
487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)showTests ( const TestNode *root )
488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* make up one for them */
490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const TestNode *nodeList[MAXTESTS];
491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (root == NULL)
493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("TEST CAN'T BE FOUND!");
494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iterateTestsWithLevel ( root, 0, nodeList, SHOWTESTS );
496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2
500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)runTests ( const TestNode *root )
501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int i;
503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const TestNode *nodeList[MAXTESTS];
504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* make up one for them */
505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (root == NULL)
508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("TEST CAN'T BE FOUND!\n");
509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ERRONEOUS_FUNCTION_COUNT = ERROR_COUNT = 0;
511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    iterateTestsWithLevel ( root, 0, nodeList, RUNTESTS );
512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*print out result summary*/
514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ON_LINE=FALSE; /* just in case */
516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (ERROR_COUNT)
518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stdout,"\nSUMMARY:\n");
520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	fflush(stdout);
521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stdout,"******* [Total error count:\t%d]\n", ERROR_COUNT);
522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	fflush(stdout);
523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stdout, " Errors in\n");
524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (i=0;i < ERRONEOUS_FUNCTION_COUNT; i++)
525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stdout, "[%s]\n",ERROR_LOG[i]);
526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else
528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      log_testinfo("\n[All tests passed successfully...]\n");
530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(DATA_ERROR_COUNT) {
533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      if(WARN_ON_MISSING_DATA==0) {
534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	  log_testinfo("\t*Note* some errors are data-loading related. If the data used is not the \n"
535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                 "\tstock ICU data (i.e some have been added or removed), consider using\n"
536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                 "\tthe '-w' option to turn these errors into warnings.\n");
537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      } else {
538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	  log_testinfo("\t*WARNING* some data-loading errors were ignored by the -w option.\n");
539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const char* T_CTEST_EXPORT2
544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getTestName(void)
545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(currentTest != NULL) {
547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return currentTest->name;
548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  } else {
549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return NULL;
550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const TestNode* T_CTEST_EXPORT2
554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getTest(const TestNode* root, const char* name)
555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const char* nextName;
557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestNode *nextNode;
558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const TestNode* curNode;
559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int nameLen; /* length of current 'name' */
560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (root == NULL) {
562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log_err("TEST CAN'T BE FOUND!\n");
563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return NULL;
564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* remove leading slash */
566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ( *name == TEST_SEPARATOR )
567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        name++;
568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    curNode = root;
570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(;;)
572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Start with the next child */
574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        nextNode = curNode->child;
575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        getNextLevel ( name, &nameLen, &nextName );
577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /*      printf("* %s\n", name );*/
579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* if nextNode is already null, then curNode has no children
581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        -- add them */
582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if( nextNode == NULL )
583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return NULL;
585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Search across for the name */
588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        while (strncmp_nullcheck ( name, nextNode->name, nameLen) != 0 )
589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            curNode = nextNode;
591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            nextNode = nextNode -> sibling;
592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ( nextNode == NULL )
594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                /* Did not find 'name' on this level. */
596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return NULL;
597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* nextNode matches 'name' */
601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (nextName == NULL) /* end of the line */
603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return nextNode;
605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Loop again with the next item */
608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        name = nextName;
609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        curNode = nextNode;
610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*  =========== io functions ======== */
614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void go_offline_with_marker(const char *mrk) {
616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UBool wasON_LINE = ON_LINE;
617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(ON_LINE) {
619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    log_testinfo(" {\n");
620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ON_LINE=FALSE;
621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(!HANGING_OUTPUT || wasON_LINE) {
624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(mrk != NULL) {
625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      fputs(mrk, stdout);
626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void go_offline() {
631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)	go_offline_with_marker(NULL);
632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void go_offline_err() {
635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)	go_offline();
636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void first_line_verbose() {
639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    go_offline_with_marker("v");
640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void first_line_err() {
643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    go_offline_with_marker("!");
644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void first_line_info() {
647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    go_offline_with_marker("\"");
648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void first_line_test() {
651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)	fputs(" ", stdout);
652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void vlog_err(const char *prefix, const char *pattern, va_list ap)
656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if( ERR_MSG == FALSE){
658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fputs("!", stdout); /* col 1 - bang */
661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fprintf(stdout, "%-*s", INDENT_LEVEL,"" );
662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(prefix) {
663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fputs(prefix, stdout);
664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    vfprintf(stdout, pattern, ap);
666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fflush(stdout);
667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_end(ap);
668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if((*pattern==0) || (pattern[strlen(pattern)-1]!='\n')) {
669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	HANGING_OUTPUT=1;
670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	HANGING_OUTPUT=0;
672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    GLOBAL_PRINT_COUNT++;
674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2
677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)vlog_info(const char *prefix, const char *pattern, va_list ap)
678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)	first_line_info();
680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fprintf(stdout, "%-*s", INDENT_LEVEL,"" );
681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(prefix) {
682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fputs(prefix, stdout);
683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    vfprintf(stdout, pattern, ap);
685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fflush(stdout);
686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_end(ap);
687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if((*pattern==0) || (pattern[strlen(pattern)-1]!='\n')) {
688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	HANGING_OUTPUT=1;
689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	HANGING_OUTPUT=0;
691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    GLOBAL_PRINT_COUNT++;
693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Log test structure, with indent
696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void log_testinfo_i(const char *pattern, ...)
698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_list ap;
700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    first_line_test();
701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fprintf(stdout, "%-*s", INDENT_LEVEL,"" );
702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_start(ap, pattern);
703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    vfprintf(stdout, pattern, ap);
704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fflush(stdout);
705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_end(ap);
706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    GLOBAL_PRINT_COUNT++;
707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Log test structure (no ident)
710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void log_testinfo(const char *pattern, ...)
712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_list ap;
714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_start(ap, pattern);
715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    first_line_test();
716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    vfprintf(stdout, pattern, ap);
717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fflush(stdout);
718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_end(ap);
719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    GLOBAL_PRINT_COUNT++;
720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void vlog_verbose(const char *prefix, const char *pattern, va_list ap)
724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ( VERBOSITY == FALSE )
726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    first_line_verbose();
729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fprintf(stdout, "%-*s", INDENT_LEVEL,"" );
730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(prefix) {
731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fputs(prefix, stdout);
732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    vfprintf(stdout, pattern, ap);
734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fflush(stdout);
735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_end(ap);
736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    GLOBAL_PRINT_COUNT++;
737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if((*pattern==0) || (pattern[strlen(pattern)-1]!='\n')) {
738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	HANGING_OUTPUT=1;
739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	HANGING_OUTPUT=0;
741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2
745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)log_err(const char* pattern, ...)
746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_list ap;
748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    first_line_err();
749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(strchr(pattern, '\n') != NULL) {
750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /*
751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         * Count errors only if there is a line feed in the pattern
752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         * so that we do not exaggerate our error count.
753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         */
754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ++ERROR_COUNT;
755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	/* Count at least one error. */
757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	ONE_ERROR=1;
758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_start(ap, pattern);
760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    vlog_err(NULL, pattern, ap);
761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2
764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)log_err_status(UErrorCode status, const char* pattern, ...)
765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_list ap;
767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_start(ap, pattern);
768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    first_line_err();
770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ((status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR)) {
771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ++DATA_ERROR_COUNT; /* for informational message at the end */
772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (WARN_ON_MISSING_DATA == 0) {
774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* Fatal error. */
775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (strchr(pattern, '\n') != NULL) {
776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                ++ERROR_COUNT;
777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)				++ONE_ERROR;
779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            vlog_err(NULL, pattern, ap); /* no need for prefix in default case */
781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            vlog_info("[DATA] ", pattern, ap);
783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Fatal error. */
786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(strchr(pattern, '\n') != NULL) {
787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++ERROR_COUNT;
788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)			++ONE_ERROR;
790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        vlog_err(NULL, pattern, ap); /* no need for prefix in default case */
792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2
796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)log_info(const char* pattern, ...)
797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_list ap;
799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_start(ap, pattern);
801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    vlog_info(NULL, pattern, ap);
802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2
805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)log_verbose(const char* pattern, ...)
806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_list ap;
808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_start(ap, pattern);
810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    vlog_verbose(NULL, pattern, ap);
811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2
815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)log_data_err(const char* pattern, ...)
816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_list ap;
818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    va_start(ap, pattern);
819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    go_offline_err();
821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ++DATA_ERROR_COUNT; /* for informational message at the end */
822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(WARN_ON_MISSING_DATA == 0) {
824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Fatal error. */
825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(strchr(pattern, '\n') != NULL) {
826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++ERROR_COUNT;
827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        vlog_err(NULL, pattern, ap); /* no need for prefix in default case */
829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        vlog_info("[DATA] ", pattern, ap);
831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Tracing functions.
837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int traceFnNestingDepth = 0;
839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_BEGIN
840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void U_CALLCONV TraceEntry(const void *context, int32_t fnNumber) {
841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char buf[500];
842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    utrace_format(buf, sizeof(buf), traceFnNestingDepth*3, "%s() enter.\n", utrace_functionName(fnNumber));    buf[sizeof(buf)-1]=0;
843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fputs(buf, stdout);
844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    traceFnNestingDepth++;
845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void U_CALLCONV TraceExit(const void *context, int32_t fnNumber, const char *fmt, va_list args) {    char buf[500];
848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (traceFnNestingDepth>0) {
850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        traceFnNestingDepth--;
851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    utrace_format(buf, sizeof(buf), traceFnNestingDepth*3, "%s() ", utrace_functionName(fnNumber));    buf[sizeof(buf)-1]=0;
853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fputs(buf, stdout);
854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    utrace_vformat(buf, sizeof(buf), traceFnNestingDepth*3, fmt, args);
855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    buf[sizeof(buf)-1]=0;
856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fputs(buf, stdout);
857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    putc('\n', stdout);
858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void U_CALLCONV TraceData(const void *context, int32_t fnNumber,
861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          int32_t level, const char *fmt, va_list args) {
862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char buf[500];
863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    utrace_vformat(buf, sizeof(buf), traceFnNestingDepth*3, fmt, args);
864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    buf[sizeof(buf)-1]=0;
865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fputs(buf, stdout);
866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    putc('\n', stdout);
867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void *U_CALLCONV ctest_libMalloc(const void *context, size_t size) {
870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*if (VERBOSITY) {
871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        printf("Allocated %ld\n", (long)size);
872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }*/
873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (MINIMUM_MEMORY_SIZE_FAILURE <= size && size <= MAXIMUM_MEMORY_SIZE_FAILURE) {
874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return NULL;
875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_atomic_inc(&ALLOCATION_COUNT);
877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return malloc(size);
878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void *U_CALLCONV ctest_libRealloc(const void *context, void *mem, size_t size) {
880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*if (VERBOSITY) {
881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        printf("Reallocated %ld\n", (long)size);
882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }*/
883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (MINIMUM_MEMORY_SIZE_FAILURE <= size && size <= MAXIMUM_MEMORY_SIZE_FAILURE) {
884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /*free(mem);*/ /* Realloc doesn't free on failure. */
885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return NULL;
886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (mem == NULL) {
888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* New allocation. */
889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        umtx_atomic_inc(&ALLOCATION_COUNT);
890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return realloc(mem, size);
892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void U_CALLCONV ctest_libFree(const void *context, void *mem) {
894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (mem != NULL) {
895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        umtx_atomic_dec(&ALLOCATION_COUNT);
896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    free(mem);
898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int T_CTEST_EXPORT2
901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)initArgs( int argc, const char* const argv[], ArgHandlerPtr argHandler, void *context)
902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int                i;
904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int                doList = FALSE;
905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)	int                argSkip = 0;
906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    VERBOSITY = FALSE;
908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ERR_MSG = TRUE;
909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ARGV_0=argv[0];
911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for( i=1; i<argc; i++)
913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if ( argv[i][0] == '/' )
915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* We don't run the tests here. */
917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            continue;
918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if ((strcmp( argv[i], "-a") == 0) || (strcmp(argv[i],"-all") == 0))
920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* We don't run the tests here. */
922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            continue;
923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-v" )==0 || strcmp( argv[i], "-verbose")==0)
925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            VERBOSITY = TRUE;
927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-l" )==0 )
929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            doList = TRUE;
931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-e1") == 0)
933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            QUICK = -1;
935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-e") ==0)
937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            QUICK = 0;
939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-w") ==0)
941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            WARN_ON_MISSING_DATA = TRUE;
943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-m") ==0)
945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UErrorCode errorCode = U_ZERO_ERROR;
947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (i+1 < argc) {
948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                char *endPtr = NULL;
949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                i++;
950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                MINIMUM_MEMORY_SIZE_FAILURE = (size_t)strtol(argv[i], &endPtr, 10);
951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (endPtr == argv[i]) {
952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    printf("Can't parse %s\n", argv[i]);
953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    help(argv[0]);
954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    return 0;
955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (*endPtr == '-') {
957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    char *maxPtr = endPtr+1;
958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    endPtr = NULL;
959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    MAXIMUM_MEMORY_SIZE_FAILURE = (size_t)strtol(maxPtr, &endPtr, 10);
960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (endPtr == argv[i]) {
961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        printf("Can't parse %s\n", argv[i]);
962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        help(argv[0]);
963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        return 0;
964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* Use the default value */
968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            u_setMemoryFunctions(NULL, ctest_libMalloc, ctest_libRealloc, ctest_libFree, &errorCode);
969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (U_FAILURE(errorCode)) {
970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                printf("u_setMemoryFunctions returned %s\n", u_errorName(errorCode));
971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return 0;
972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if(strcmp( argv[i], "-n") == 0 || strcmp( argv[i], "-no_err_msg") == 0)
975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ERR_MSG = FALSE;
977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-r") == 0)
979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (!REPEAT_TESTS_INIT) {
981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                REPEAT_TESTS++;
982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-x") == 0)
985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          if(++i>=argc) {
987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            printf("* Error: '-x' option requires an argument. usage: '-x outfile.xml'.\n");
988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return 0;
989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          }
990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          if(ctest_xml_setFileName(argv[i])) { /* set the name */
991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return 0;
992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          }
993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-t_info") == 0) {
995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ICU_TRACE = UTRACE_INFO;
996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-t_error") == 0) {
998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ICU_TRACE = UTRACE_ERROR;
999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-t_warn") == 0) {
1001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ICU_TRACE = UTRACE_WARNING;
1002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-t_verbose") == 0) {
1004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ICU_TRACE = UTRACE_VERBOSE;
1005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-t_oc") == 0) {
1007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ICU_TRACE = UTRACE_OPEN_CLOSE;
1008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (strcmp( argv[i], "-h" )==0 || strcmp( argv[i], "--help" )==0)
1010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
1011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            help( argv[0] );
1012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return 0;
1013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (argHandler != NULL && (argSkip = argHandler(i, argc, argv, context)) > 0)
1015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
1016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            i += argSkip - 1;
1017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else
1019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
1020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            printf("* unknown option: %s\n", argv[i]);
1021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            help( argv[0] );
1022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return 0;
1023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (ICU_TRACE != UTRACE_OFF) {
1026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        utrace_setFunctions(NULL, TraceEntry, TraceExit, TraceData);
1027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        utrace_setLevel(ICU_TRACE);
1028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return 1; /* total error count */
1031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int T_CTEST_EXPORT2
1034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)runTestRequest(const TestNode* root,
1035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)             int argc,
1036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)             const char* const argv[])
1037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
1038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /**
1039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * This main will parse the l, v, h, n, and path arguments
1040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
1041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const TestNode*    toRun;
1042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int                i;
1043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int                doList = FALSE;
1044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int                subtreeOptionSeen = FALSE;
1045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int                errorCount = 0;
1047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    toRun = root;
1049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(ctest_xml_init(ARGV_0)) {
1051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return 1; /* couldn't fire up XML thing */
1052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for( i=1; i<argc; i++)
1055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
1056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if ( argv[i][0] == '/' )
1057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
1058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            printf("Selecting subtree '%s'\n", argv[i]);
1059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ( argv[i][1] == 0 )
1061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                toRun = root;
1062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else
1063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                toRun = getTest(root, argv[i]);
1064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ( toRun == NULL )
1066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
1067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                printf("* Could not find any matching subtree\n");
1068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return -1;
1069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ON_LINE=FALSE; /* just in case */
1072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if( doList == TRUE)
1074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                showTests(toRun);
1075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else
1076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                runTests(toRun);
1077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ON_LINE=FALSE; /* just in case */
1079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            errorCount += ERROR_COUNT;
1081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            subtreeOptionSeen = TRUE;
1083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else if ((strcmp( argv[i], "-a") == 0) || (strcmp(argv[i],"-all") == 0)) {
1084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            subtreeOptionSeen=FALSE;
1085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else if (strcmp( argv[i], "-l") == 0) {
1086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            doList = TRUE;
1087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* else option already handled by initArgs */
1089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if( subtreeOptionSeen == FALSE) /* no other subtree given, run the default */
1092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
1093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ON_LINE=FALSE; /* just in case */
1094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if( doList == TRUE)
1095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            showTests(toRun);
1096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else
1097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            runTests(toRun);
1098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ON_LINE=FALSE; /* just in case */
1099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errorCount += ERROR_COUNT;
1101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else
1103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
1104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if( ( doList == FALSE ) && ( errorCount > 0 ) )
1105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            printf(" Total errors: %d\n", errorCount );
1106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    REPEAT_TESTS_INIT = 1;
1109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(ctest_xml_fini()) {
1111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      errorCount++;
1112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return errorCount; /* total error count */
1115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
1118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Display program invocation arguments
1119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
1120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void help ( const char *argv0 )
1122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
1123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("Usage: %s [ -l ] [ -v ] [ -verbose] [-a] [ -all] [-n] [ -no_err_msg]\n"
1124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           "    [ -h ] [-t_info | -t_error | -t_warn | -t_oc | -t_verbose] [-m n[-q] ]\n"
1125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           "    [ /path/to/test ]\n",
1126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            argv0);
1127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -l  To get a list of test names\n");
1128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -e  to do exhaustive testing\n");
1129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -verbose To turn ON verbosity\n");
1130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -v  To turn ON verbosity(same as -verbose)\n");
1131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -x file.xml   Write junit format output to file.xml\n");
1132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -h  To print this message\n");
1133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -n  To turn OFF printing error messages\n");
1134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -w  Don't fail on data-loading errs, just warn. Useful if\n"
1135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           "        user has reduced/changed the common set of ICU data \n");
1136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -t_info | -t_error | -t_warn | -t_oc | -t_verbose  Enable ICU tracing\n");
1137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -no_err_msg (same as -n) \n");
1138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -m n[-q] Min-Max memory size that will cause an allocation failure.\n");
1139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("        The default is the maximum value of size_t. Max is optional.\n");
1140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    -r  Repeat tests after calling u_cleanup \n");
1141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    [/subtest]  To run a subtest \n");
1142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    printf("    eg: to run just the utility tests type: cintltest /tsutil) \n");
1143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t T_CTEST_EXPORT2
1146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getTestOption ( int32_t testOption ) {
1147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    switch (testOption) {
1148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        case VERBOSITY_OPTION:
1149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return VERBOSITY;
1150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        case WARN_ON_MISSING_DATA_OPTION:
1151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return WARN_ON_MISSING_DATA;
1152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        case QUICK_OPTION:
1153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return QUICK;
1154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        case REPEAT_TESTS_OPTION:
1155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return REPEAT_TESTS;
1156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        case ERR_MSG_OPTION:
1157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return ERR_MSG;
1158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        case ICU_TRACE_OPTION:
1159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return ICU_TRACE;
1160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        default :
1161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return 0;
1162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void T_CTEST_EXPORT2
1166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)setTestOption ( int32_t testOption, int32_t value) {
1167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (value == DECREMENT_OPTION_VALUE) {
1168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        value = getTestOption(testOption);
1169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        --value;
1170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    switch (testOption) {
1172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        case VERBOSITY_OPTION:
1173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            VERBOSITY = value;
1174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
1175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        case WARN_ON_MISSING_DATA_OPTION:
1176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            WARN_ON_MISSING_DATA = value;
1177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
1178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        case QUICK_OPTION:
1179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            QUICK = value;
1180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
1181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        case REPEAT_TESTS_OPTION:
1182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            REPEAT_TESTS = value;
1183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
1184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        case ICU_TRACE_OPTION:
1185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ICU_TRACE = value;
1186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
1187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        default :
1188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
1189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
1194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ================== JUnit support ================================
1195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
1196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
1198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)T_CTEST_EXPORT2
1199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ctest_xml_setFileName(const char *name) {
1200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  XML_FILE_NAME=name;
1201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return 0;
1202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
1206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)T_CTEST_EXPORT2
1207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ctest_xml_init(const char *rootName) {
1208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(!XML_FILE_NAME) return 0;
1209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  XML_FILE = fopen(XML_FILE_NAME,"w");
1210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(!XML_FILE) {
1211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    perror("fopen");
1212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fprintf(stderr," Error: couldn't open XML output file %s\n", XML_FILE_NAME);
1213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return 1;
1214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
1215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  while(*rootName&&!isalnum(*rootName)) {
1216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    rootName++;
1217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
1218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  strcpy(XML_PREFIX,rootName);
1219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  {
1220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *p = XML_PREFIX+strlen(XML_PREFIX);
1221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(p--;*p&&p>XML_PREFIX&&!isalnum(*p);p--) {
1222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      *p=0;
1223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
1225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  /* write prefix */
1226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fprintf(XML_FILE, "<testsuite name=\"%s\">\n", XML_PREFIX);
1227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return 0;
1229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
1232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)T_CTEST_EXPORT2
1233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ctest_xml_fini(void) {
1234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(!XML_FILE) return 0;
1235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fprintf(XML_FILE, "</testsuite>\n");
1237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fclose(XML_FILE);
1238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  printf(" ( test results written to %s )\n", XML_FILE_NAME);
1239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  XML_FILE=0;
1240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return 0;
1241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
1245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)T_CTEST_EXPORT2
1246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ctest_xml_testcase(const char *classname, const char *name, const char *time, const char *failMsg) {
1247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(!XML_FILE) return 0;
1248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fprintf(XML_FILE, "\t<testcase classname=\"%s:%s\" name=\"%s:%s\" time=\"%s\"", XML_PREFIX, classname, XML_PREFIX, name, time);
1250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(failMsg) {
1251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fprintf(XML_FILE, ">\n\t\t<failure type=\"err\" message=\"%s\"/>\n\t</testcase>\n", failMsg);
1252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  } else {
1253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fprintf(XML_FILE, "/>\n");
1254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
1255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return 0;
1257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1260