summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu/icu-xetex/tools/ctestfw
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/icu/icu-xetex/tools/ctestfw')
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/Makefile.in116
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/ctest.c672
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/ctestfw.vcproj313
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/datamap.cpp221
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/dbgutil.cpp142
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/testdata.cpp142
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/tstdtmod.cpp170
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/udbgutil.cpp198
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/ctest.h199
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/datamap.h138
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/dbgutil.h38
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testdata.h111
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testlog.h29
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testtype.h39
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/tstdtmod.h115
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/udbgutil.h58
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/uperf.h179
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/utimer.h277
-rw-r--r--Build/source/libs/icu/icu-xetex/tools/ctestfw/uperf.cpp526
19 files changed, 3683 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/Makefile.in b/Build/source/libs/icu/icu-xetex/tools/ctestfw/Makefile.in
new file mode 100644
index 00000000000..4651a2fbd65
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/Makefile.in
@@ -0,0 +1,116 @@
+#******************************************************************************
+#
+# Copyright (C) 1999-2007, International Business Machines
+# Corporation and others. All Rights Reserved.
+#
+#******************************************************************************
+## Makefile.in for ICU - tools/ctestfw
+## Stephen F. Booth
+
+## Source directory information
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+top_builddir = ../..
+
+## All the flags and other definitions are included here.
+include $(top_builddir)/icudefs.mk
+
+## Build directory information
+subdir = tools/ctestfw
+
+## Extra files to remove for 'make clean'
+CLEANFILES = *~ $(DEPS) $(IMPORT_LIB) $(MIDDLE_IMPORT_LIB) $(FINAL_IMPORT_LIB)
+
+## Target information
+
+TARGET_STUBNAME=$(CTESTFW_STUBNAME)
+
+ifneq ($(ENABLE_STATIC),)
+TARGET = $(LIBSICU)$(TARGET_STUBNAME)$(ICULIBSUFFIX).$(A)
+endif
+
+ifneq ($(ENABLE_SHARED),)
+SO_TARGET = $(LIBICU)$(TARGET_STUBNAME)$(ICULIBSUFFIX).$(SO)
+ALL_SO_TARGETS = $(SO_TARGET) $(MIDDLE_SO_TARGET) $(FINAL_SO_TARGET) $(SHARED_OBJECT)
+endif
+
+ALL_TARGETS = $(TARGET) $(ALL_SO_TARGETS)
+
+DYNAMICCPPFLAGS = $(SHAREDLIBCPPFLAGS)
+DYNAMICCFLAGS = $(SHAREDLIBCFLAGS)
+DYNAMICCXXFLAGS = $(SHAREDLIBCXXFLAGS)
+CFLAGS += $(LIBCFLAGS)
+CXXFLAGS += $(LIBCXXFLAGS)
+
+ifneq ($(top_builddir),$(top_srcdir))
+CPPFLAGS += -I$(top_builddir)/common
+endif
+CPPFLAGS += -I$(top_srcdir)/common -I$(top_srcdir)/i18n -I$(srcdir)/../toolutil -I$(srcdir) $(LIBCPPFLAGS)
+DEFS += -DT_CTEST_IMPLEMENTATION
+LDFLAGS += $(LDFLAGSCTESTFW)
+LIBS = $(LIBICUTOOLUTIL) $(LIBICUI18N) $(LIBICUUC) $(DEFAULT_LIBS)
+
+OBJECTS = ctest.o tstdtmod.o testdata.o datamap.o uperf.o dbgutil.o udbgutil.o
+
+STATIC_OBJECTS = $(OBJECTS:.o=.$(STATIC_O))
+
+DEPS = $(OBJECTS:.o=.d)
+
+-include Makefile.local
+
+## List of phony targets
+.PHONY : all all-local install install-local clean clean-local \
+distclean distclean-local dist dist-local check check-local
+
+## Clear suffix list
+.SUFFIXES :
+
+## List of standard targets
+all: all-local
+install: install-local
+clean: clean-local
+distclean : distclean-local
+dist: dist-local
+check: all check-local
+
+all-local: $(ALL_TARGETS)
+
+install-local: install-library
+
+install-library: all-local
+
+dist-local:
+
+clean-local:
+ test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES)
+ $(RMV) $(OBJECTS) $(STATIC_OBJECTS) $(ALL_TARGETS)
+
+distclean-local: clean-local
+ $(RMV) Makefile
+
+check-local: all-local
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+ifneq ($(ENABLE_STATIC),)
+$(TARGET): $(STATIC_OBJECTS)
+ $(AR) $(ARFLAGS) $(AR_OUTOPT)$@ $^
+ $(RANLIB) $@
+endif
+
+ifneq ($(ENABLE_SHARED),)
+$(SHARED_OBJECT): $(OBJECTS)
+ $(SHLIB.cc) $(LD_SONAME) $(OUTOPT)$@ $^ $(LIBS)
+endif
+
+ifeq (,$(MAKECMDGOALS))
+-include $(DEPS)
+else
+ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),)
+-include $(DEPS)
+endif
+endif
+
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/ctest.c b/Build/source/libs/icu/icu-xetex/tools/ctestfw/ctest.c
new file mode 100644
index 00000000000..d99450b1d62
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/ctest.c
@@ -0,0 +1,672 @@
+/*
+********************************************************************************
+*
+* Copyright (C) 1996-2006, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+********************************************************************************
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#include "unicode/utrace.h"
+
+/* NOTES:
+ 3/20/1999 srl - strncpy called w/o setting nulls at the end
+ */
+
+#define MAXTESTNAME 128
+#define MAXTESTS 512
+#define MAX_TEST_LOG 4096
+
+struct TestNode
+{
+ char name[MAXTESTNAME];
+ void (*test)(void);
+ struct TestNode* sibling;
+ struct TestNode* child;
+};
+
+
+static const struct TestNode* currentTest;
+
+typedef enum { RUNTESTS, SHOWTESTS } TestMode;
+#define TEST_SEPARATOR '/'
+
+#ifndef C_TEST_IMPL
+#define C_TEST_IMPL
+#endif
+
+#include "unicode/ctest.h"
+
+static char ERROR_LOG[MAX_TEST_LOG][MAXTESTNAME];
+
+/* Local prototypes */
+static TestNode* addTestNode( TestNode *root, const char *name );
+
+static TestNode* createTestNode();
+
+static int strncmp_nullcheck( const char* s1,
+ const char* s2,
+ int n );
+
+static void getNextLevel( const char* name,
+ int* nameLen,
+ const char** nextName );
+
+static void iterateTestsWithLevel( const TestNode *root, int len,
+ const TestNode** list,
+ TestMode mode);
+
+static void help ( const char *argv0 );
+
+/**
+ * Do the work of logging an error. Doesn't increase the error count.
+ *
+ * @prefix optional prefix prepended to message, or NULL.
+ * @param pattern printf style pattern
+ * @param ap vprintf style arg list
+ */
+static void vlog_err(const char *prefix, const char *pattern, va_list ap);
+static void vlog_verbose(const char *prefix, const char *pattern, va_list ap);
+
+/* If we need to make the framework multi-thread safe
+ we need to pass around the following vars
+*/
+static int ERRONEOUS_FUNCTION_COUNT = 0;
+static int ERROR_COUNT = 0; /* Count of errors from all tests. */
+static int DATA_ERROR_COUNT = 0; /* count of data related errors or warnings */
+static int INDENT_LEVEL = 0;
+int REPEAT_TESTS_INIT = 0; /* Was REPEAT_TESTS initialized? */
+int REPEAT_TESTS = 1; /* Number of times to run the test */
+int VERBOSITY = 0; /* be No-verbose by default */
+int ERR_MSG =1; /* error messages will be displayed by default*/
+int QUICK = 1; /* Skip some of the slower tests? */
+int WARN_ON_MISSING_DATA = 0; /* Reduce data errs to warnings? */
+UTraceLevel ICU_TRACE = UTRACE_OFF; /* ICU tracing level */
+/*-------------------------------------------*/
+
+/* strncmp that also makes sure there's a \0 at s2[0] */
+static int strncmp_nullcheck( const char* s1,
+ const char* s2,
+ int n )
+{
+ if (((int)strlen(s2) >= n) && s2[n] != 0) {
+ return 3; /* null check fails */
+ }
+ else {
+ return strncmp ( s1, s2, n );
+ }
+}
+
+static void getNextLevel( const char* name,
+ int* nameLen,
+ const char** nextName )
+{
+ /* Get the next component of the name */
+ *nextName = strchr(name, TEST_SEPARATOR);
+
+ if( *nextName != 0 )
+ {
+ char n[255];
+ *nameLen = (int)((*nextName) - name);
+ (*nextName)++; /* skip '/' */
+ strncpy(n, name, *nameLen);
+ n[*nameLen] = 0;
+ /*printf("->%s-< [%d] -> [%s]\n", name, *nameLen, *nextName);*/
+ }
+ else {
+ *nameLen = (int)strlen(name);
+ }
+}
+
+static TestNode *createTestNode( )
+{
+ TestNode *newNode;
+
+ newNode = (TestNode*)malloc ( sizeof ( TestNode ) );
+
+ newNode->name[0] = '\0';
+ newNode->test = NULL;
+ newNode->sibling = NULL;
+ newNode->child = NULL;
+
+ return newNode;
+}
+
+void T_CTEST_EXPORT2
+cleanUpTestTree(TestNode *tn)
+{
+ if(tn->child != NULL) {
+ cleanUpTestTree(tn->child);
+ }
+ if(tn->sibling != NULL) {
+ cleanUpTestTree(tn->sibling);
+ }
+
+ free(tn);
+}
+
+
+void T_CTEST_EXPORT2
+addTest(TestNode** root,
+ TestFunctionPtr test,
+ const char* name )
+{
+ TestNode *newNode;
+
+ /*if this is the first Test created*/
+ if (*root == NULL)
+ *root = createTestNode();
+
+ newNode = addTestNode( *root, name );
+ assert(newNode != 0 );
+ /* printf("addTest: nreName = %s\n", newNode->name );*/
+
+ newNode->test = test;
+}
+
+/* non recursive insert function */
+static TestNode *addTestNode ( TestNode *root, const char *name )
+{
+ const char* nextName;
+ TestNode *nextNode, *curNode;
+ int nameLen; /* length of current 'name' */
+
+ /* remove leading slash */
+ if ( *name == TEST_SEPARATOR )
+ name++;
+
+ curNode = root;
+
+ for(;;)
+ {
+ /* Start with the next child */
+ nextNode = curNode->child;
+
+ getNextLevel ( name, &nameLen, &nextName );
+
+ /* printf("* %s\n", name );*/
+
+ /* if nextNode is already null, then curNode has no children
+ -- add them */
+ if( nextNode == NULL )
+ {
+ /* Add all children of the node */
+ do
+ {
+ curNode->child = createTestNode ( );
+
+ /* Get the next component of the name */
+ getNextLevel ( name, &nameLen, &nextName );
+
+ /* update curName to have the next name segment */
+ strncpy ( curNode->child->name , name, nameLen );
+ curNode->child->name[nameLen] = 0;
+ /* printf("*** added %s\n", curNode->child->name );*/
+ curNode = curNode->child;
+ name = nextName;
+ }
+ while( name != NULL );
+
+ return curNode;
+ }
+
+ /* Search across for the name */
+ while (strncmp_nullcheck ( name, nextNode->name, nameLen) != 0 )
+ {
+ curNode = nextNode;
+ nextNode = nextNode -> sibling;
+
+ if ( nextNode == NULL )
+ {
+ /* Did not find 'name' on this level. */
+ nextNode = createTestNode ( );
+ strncpy( nextNode->name, name, nameLen );
+ nextNode->name[nameLen] = 0;
+ curNode->sibling = nextNode;
+ break;
+ }
+ }
+
+ /* nextNode matches 'name' */
+
+ if (nextName == NULL) /* end of the line */
+ {
+ return nextNode;
+ }
+
+ /* Loop again with the next item */
+ name = nextName;
+ curNode = nextNode;
+ }
+}
+
+static void iterateTestsWithLevel ( const TestNode* root,
+ int len,
+ const TestNode** list,
+ TestMode mode)
+{
+ int i;
+ int saveIndent;
+
+ char pathToFunction[MAXTESTNAME] = "";
+ char separatorString[2] = { TEST_SEPARATOR, '\0'};
+
+ if ( root == NULL )
+ return;
+
+ list[len++] = root;
+
+ for ( i=0;i<(len-1);i++ )
+ {
+ strcat(pathToFunction, list[i]->name);
+ strcat(pathToFunction, separatorString);
+ }
+
+ strcat(pathToFunction, list[i]->name);
+
+ INDENT_LEVEL = len;
+ if ( (mode == RUNTESTS) && (root->test != NULL))
+ {
+ int myERROR_COUNT = ERROR_COUNT;
+ currentTest = root;
+ root->test();
+ currentTest = NULL;
+ if (myERROR_COUNT != ERROR_COUNT)
+ {
+
+ log_info("---[%d ERRORS] ", ERROR_COUNT - myERROR_COUNT);
+ strcpy(ERROR_LOG[ERRONEOUS_FUNCTION_COUNT++], pathToFunction);
+ }
+ else
+ log_info("---[OK] ");
+ }
+
+
+ /* we want these messages to be at 0 indent. so just push the indent level breifly. */
+ saveIndent = INDENT_LEVEL;
+ INDENT_LEVEL = 0;
+ log_info("%s%s%c\n", (list[i]->test||mode==SHOWTESTS)?"---":"",pathToFunction, list[i]->test?' ':TEST_SEPARATOR );
+ INDENT_LEVEL = saveIndent;
+
+ iterateTestsWithLevel ( root->child, len, list, mode );
+
+ len--;
+
+ if ( len != 0 ) /* DO NOT iterate over siblings of the root. */
+ iterateTestsWithLevel ( root->sibling, len, list, mode );
+}
+
+
+
+void T_CTEST_EXPORT2
+showTests ( const TestNode *root )
+{
+ /* make up one for them */
+ const TestNode *aList[MAXTESTS];
+
+ if (root == NULL)
+ log_err("TEST CAN'T BE FOUND!");
+
+ iterateTestsWithLevel ( root, 0, aList, SHOWTESTS );
+
+}
+
+void T_CTEST_EXPORT2
+runTests ( const TestNode *root )
+{
+ int i;
+ const TestNode *aList[MAXTESTS];
+ /* make up one for them */
+
+
+ if (root == NULL)
+ log_err("TEST CAN'T BE FOUND!\n");
+
+ ERRONEOUS_FUNCTION_COUNT = ERROR_COUNT = 0;
+ iterateTestsWithLevel ( root, 0, aList, RUNTESTS );
+
+ /*print out result summary*/
+
+ if (ERROR_COUNT)
+ {
+ log_info("\nSUMMARY:\n******* [Total error count:\t%d]\n Errors in\n", ERROR_COUNT);
+ for (i=0;i < ERRONEOUS_FUNCTION_COUNT; i++)
+ log_info("[%s]\n",ERROR_LOG[i]);
+ }
+ else
+ {
+ log_info("\n[All tests passed successfully...]\n");
+ }
+
+ if(DATA_ERROR_COUNT) {
+ if(WARN_ON_MISSING_DATA==0) {
+ log_info("\t*Note* some errors are data-loading related. If the data used is not the \n"
+ "\tstock ICU data (i.e some have been added or removed), consider using\n"
+ "\tthe '-w' option to turn these errors into warnings.\n");
+ } else {
+ log_info("\t*WARNING* some data-loading errors were ignored by the -w option.\n");
+ }
+ }
+}
+
+const char* T_CTEST_EXPORT2
+getTestName(void)
+{
+ if(currentTest != NULL) {
+ return currentTest->name;
+ } else {
+ return NULL;
+ }
+}
+
+const TestNode* T_CTEST_EXPORT2
+getTest(const TestNode* root, const char* name)
+{
+ const char* nextName;
+ TestNode *nextNode;
+ const TestNode* curNode;
+ int nameLen; /* length of current 'name' */
+
+ if (root == NULL) {
+ log_err("TEST CAN'T BE FOUND!\n");
+ return NULL;
+ }
+ /* remove leading slash */
+ if ( *name == TEST_SEPARATOR )
+ name++;
+
+ curNode = root;
+
+ for(;;)
+ {
+ /* Start with the next child */
+ nextNode = curNode->child;
+
+ getNextLevel ( name, &nameLen, &nextName );
+
+ /* printf("* %s\n", name );*/
+
+ /* if nextNode is already null, then curNode has no children
+ -- add them */
+ if( nextNode == NULL )
+ {
+ return NULL;
+ }
+
+ /* Search across for the name */
+ while (strncmp_nullcheck ( name, nextNode->name, nameLen) != 0 )
+ {
+ curNode = nextNode;
+ nextNode = nextNode -> sibling;
+
+ if ( nextNode == NULL )
+ {
+ /* Did not find 'name' on this level. */
+ return NULL;
+ }
+ }
+
+ /* nextNode matches 'name' */
+
+ if (nextName == NULL) /* end of the line */
+ {
+ return nextNode;
+ }
+
+ /* Loop again with the next item */
+ name = nextName;
+ curNode = nextNode;
+ }
+}
+
+static void vlog_err(const char *prefix, const char *pattern, va_list ap)
+{
+ if( ERR_MSG == FALSE){
+ return;
+ }
+ fprintf(stderr, "%-*s", INDENT_LEVEL," " );
+ if(prefix) {
+ fputs(prefix, stderr);
+ }
+ vfprintf(stderr, pattern, ap);
+ fflush(stderr);
+ va_end(ap);
+}
+
+void T_CTEST_EXPORT2
+vlog_info(const char *prefix, const char *pattern, va_list ap)
+{
+ fprintf(stdout, "%-*s", INDENT_LEVEL," " );
+ if(prefix) {
+ fputs(prefix, stdout);
+ }
+ vfprintf(stdout, pattern, ap);
+ fflush(stdout);
+ va_end(ap);
+}
+
+static void vlog_verbose(const char *prefix, const char *pattern, va_list ap)
+{
+ if ( VERBOSITY == FALSE )
+ return;
+
+ fprintf(stdout, "%-*s", INDENT_LEVEL," " );
+ if(prefix) {
+ fputs(prefix, stdout);
+ }
+ vfprintf(stdout, pattern, ap);
+ fflush(stdout);
+ va_end(ap);
+}
+
+void T_CTEST_EXPORT2
+log_err(const char* pattern, ...)
+{
+ va_list ap;
+ if(strchr(pattern, '\n') != NULL) {
+ /*
+ * Count errors only if there is a line feed in the pattern
+ * so that we do not exaggerate our error count.
+ */
+ ++ERROR_COUNT;
+ }
+ va_start(ap, pattern);
+ vlog_err(NULL, pattern, ap);
+}
+
+void T_CTEST_EXPORT2
+log_info(const char* pattern, ...)
+{
+ va_list ap;
+
+ va_start(ap, pattern);
+ vlog_info(NULL, pattern, ap);
+}
+
+void T_CTEST_EXPORT2
+log_verbose(const char* pattern, ...)
+{
+ va_list ap;
+
+ va_start(ap, pattern);
+ vlog_verbose(NULL, pattern, ap);
+}
+
+
+void T_CTEST_EXPORT2
+log_data_err(const char* pattern, ...)
+{
+ va_list ap;
+ va_start(ap, pattern);
+
+ ++DATA_ERROR_COUNT; /* for informational message at the end */
+
+ if(WARN_ON_MISSING_DATA == 0) {
+ /* Fatal error. */
+ if(strchr(pattern, '\n') != NULL) {
+ ++ERROR_COUNT;
+ }
+ vlog_err(NULL, pattern, ap); /* no need for prefix in default case */
+ } else {
+ vlog_info("[Data] ", pattern, ap);
+ }
+}
+
+
+int T_CTEST_EXPORT2
+processArgs(const TestNode* root,
+ int argc,
+ const char* const argv[])
+{
+ /**
+ * This main will parse the l, v, h, n, and path arguments
+ */
+ const TestNode* toRun;
+ int i;
+ int doList = FALSE;
+ int subtreeOptionSeen = FALSE;
+
+ int errorCount = 0;
+
+ toRun = root;
+ VERBOSITY = FALSE;
+ ERR_MSG = TRUE;
+
+ for( i=1; i<argc; i++)
+ {
+ if ( argv[i][0] == '/' )
+ {
+ printf("Selecting subtree '%s'\n", argv[i]);
+
+ if ( argv[i][1] == 0 )
+ toRun = root;
+ else
+ toRun = getTest(root, argv[i]);
+
+ if ( toRun == NULL )
+ {
+ printf("* Could not find any matching subtree\n");
+ return -1;
+ }
+
+ if( doList == TRUE)
+ showTests(toRun);
+ else
+ runTests(toRun);
+
+ errorCount += ERROR_COUNT;
+
+ subtreeOptionSeen = TRUE;
+ }
+ else if (strcmp( argv[i], "-v" )==0 || strcmp( argv[i], "-verbose")==0)
+ {
+ VERBOSITY = TRUE;
+ }
+ else if (strcmp( argv[i], "-l" )==0 )
+ {
+ doList = TRUE;
+ }
+ else if (strcmp( argv[i], "-e1") == 0)
+ {
+ QUICK = -1;
+ }
+ else if (strcmp( argv[i], "-e") ==0)
+ {
+ QUICK = 0;
+ }
+ else if (strcmp( argv[i], "-w") ==0)
+ {
+ WARN_ON_MISSING_DATA = TRUE;
+ }
+ else if(strcmp( argv[i], "-n") == 0 || strcmp( argv[i], "-no_err_msg") == 0)
+ {
+ ERR_MSG = FALSE;
+ }
+ else if (strcmp( argv[i], "-r") == 0)
+ {
+ if (!REPEAT_TESTS_INIT) {
+ REPEAT_TESTS++;
+ }
+ }
+ else if ((strcmp( argv[i], "-a") == 0) || (strcmp(argv[i],"-all") == 0))
+ {
+ subtreeOptionSeen=FALSE;
+ }
+ else if (strcmp( argv[i], "-t_info") == 0) {
+ ICU_TRACE = UTRACE_INFO;
+ }
+ else if (strcmp( argv[i], "-t_error") == 0) {
+ ICU_TRACE = UTRACE_ERROR;
+ }
+ else if (strcmp( argv[i], "-t_warn") == 0) {
+ ICU_TRACE = UTRACE_WARNING;
+ }
+ else if (strcmp( argv[i], "-t_verbose") == 0) {
+ ICU_TRACE = UTRACE_VERBOSE;
+ }
+ else if (strcmp( argv[i], "-t_oc") == 0) {
+ ICU_TRACE = UTRACE_OPEN_CLOSE;
+ }
+ else if (strcmp( argv[i], "-h" )==0 || strcmp( argv[i], "--help" )==0)
+ {
+ help( argv[0] );
+ return 0;
+ }
+ else
+ {
+ printf("* unknown option: %s\n", argv[i]);
+ help( argv[0] );
+ return -1;
+ }
+ }
+
+ if( subtreeOptionSeen == FALSE) /* no other subtree given, run the default */
+ {
+ if( doList == TRUE)
+ showTests(toRun);
+ else
+ runTests(toRun);
+
+ errorCount += ERROR_COUNT;
+ }
+ else
+ {
+ if( ( doList == FALSE ) && ( errorCount > 0 ) )
+ printf(" Total errors: %d\n", errorCount );
+ }
+
+ REPEAT_TESTS_INIT = 1;
+
+ return errorCount; /* total error count */
+}
+
+/**
+ * Display program invocation arguments
+ */
+
+static void help ( const char *argv0 )
+{
+ printf("Usage: %s [ -l ] [ -v ] [ -verbose] [-a] [ -all] [-n] [ -no_err_msg]\n"
+ " [ -h ] [-t_info | -t_error | -t_warn | -t_oc | -t_verbose]"
+ " [ /path/to/test ]\n",
+ argv0);
+ printf(" -l To get a list of test names\n");
+ printf(" -e to do exhaustive testing\n");
+ printf(" -verbose To turn ON verbosity\n");
+ printf(" -v To turn ON verbosity(same as -verbose)\n");
+ printf(" -h To print this message\n");
+ printf(" -n To turn OFF printing error messages\n");
+ printf(" -w Don't fail on data-loading errs, just warn. Useful if\n"
+ " user has reduced/changed the common set of ICU data \n");
+ printf(" -t_info | -t_error | -t_warn | -t_oc | -t_verbose Enable ICU tracing\n");
+ printf(" -no_err_msg (same as -n) \n");
+ printf(" -r repeat tests after calling u_cleanup \n");
+ printf(" -[/subtest] To run a subtest \n");
+ printf(" eg: to run just the utility tests type: cintltest /tsutil) \n");
+}
+
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/ctestfw.vcproj b/Build/source/libs/icu/icu-xetex/tools/ctestfw/ctestfw.vcproj
new file mode 100644
index 00000000000..a3d3b326a65
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/ctestfw.vcproj
@@ -0,0 +1,313 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="ctestfw"
+ ProjectGUID="{ECA6B435-B4FA-4F9F-BF95-F451D078FC47}"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\..\..\..\lib"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\..\..\..\lib\icutest.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="..\..\..\include;..\..\common;..\toolutil"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;T_CTEST_IMPLEMENTATION"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ DisableLanguageExtensions="true"
+ TreatWChar_tAsBuiltInType="true"
+ PrecompiledHeaderFile=".\Release/icutest.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="..\..\..\bin\icutest.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ ProgramDatabaseFile=".\..\..\..\lib\icutest.pdb"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ LinkTimeCodeGeneration="1"
+ ImportLibrary=".\..\..\..\lib\icutest.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\..\..\..\lib"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\..\..\..\lib\icutestd.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\include;..\..\common;..\toolutil"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;T_CTEST_IMPLEMENTATION"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="true"
+ DisableLanguageExtensions="true"
+ TreatWChar_tAsBuiltInType="true"
+ PrecompiledHeaderFile=".\Debug/icutest.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="..\..\..\bin\icutestd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\..\..\..\lib\icutestd.pdb"
+ ImportLibrary=".\..\..\..\lib\icutestd.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ UseFAT32Workaround="true"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath=".\ctest.c"
+ >
+ </File>
+ <File
+ RelativePath=".\datamap.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\dbgutil.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\testdata.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\tstdtmod.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\udbgutil.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\uperf.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ DisableLanguageExtensions="false"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ DisableLanguageExtensions="false"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath=".\unicode\ctest.h"
+ >
+ </File>
+ <File
+ RelativePath=".\unicode\datamap.h"
+ >
+ </File>
+ <File
+ RelativePath=".\unicode\dbgutil.h"
+ >
+ </File>
+ <File
+ RelativePath=".\unicode\testdata.h"
+ >
+ </File>
+ <File
+ RelativePath=".\unicode\testlog.h"
+ >
+ </File>
+ <File
+ RelativePath=".\unicode\testtype.h"
+ >
+ </File>
+ <File
+ RelativePath=".\unicode\tstdtmod.h"
+ >
+ </File>
+ <File
+ RelativePath=".\unicode\udbgutil.h"
+ >
+ </File>
+ <File
+ RelativePath=".\unicode\uperf.h"
+ >
+ </File>
+ <File
+ RelativePath=".\unicode\utimer.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/datamap.cpp b/Build/source/libs/icu/icu-xetex/tools/ctestfw/datamap.cpp
new file mode 100644
index 00000000000..c59447c8a7e
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/datamap.cpp
@@ -0,0 +1,221 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 2002-2006, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+
+/* Created by weiv 05/09/2002 */
+
+#include "unicode/datamap.h"
+#include "unicode/resbund.h"
+#include "hash.h"
+#include <stdlib.h>
+
+DataMap::~DataMap() {}
+DataMap::DataMap() {}
+
+int32_t
+DataMap::utoi(const UnicodeString &s) const
+{
+ char ch[256];
+ const UChar *u = s.getBuffer();
+ int32_t len = s.length();
+ u_UCharsToChars(u, ch, len);
+ ch[len] = 0; /* include terminating \0 */
+ return atoi(ch);
+}
+
+U_CDECL_BEGIN
+void U_CALLCONV
+deleteResBund(void *obj) {
+ delete (ResourceBundle *)obj;
+}
+U_CDECL_END
+
+
+RBDataMap::~RBDataMap()
+{
+ delete fData;
+}
+
+RBDataMap::RBDataMap()
+{
+ UErrorCode status = U_ZERO_ERROR;
+ fData = new Hashtable(TRUE, status);
+ fData->setValueDeleter(deleteResBund);
+}
+
+// init from table resource
+// will put stuff in hashtable according to
+// keys.
+RBDataMap::RBDataMap(UResourceBundle *data, UErrorCode &status)
+{
+ fData = new Hashtable(TRUE, status);
+ fData->setValueDeleter(deleteResBund);
+ init(data, status);
+}
+
+// init from headers and resource
+// with checking the whether the size of resource matches
+// header size
+RBDataMap::RBDataMap(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status)
+{
+ fData = new Hashtable(TRUE, status);
+ fData->setValueDeleter(deleteResBund);
+ init(headers, data, status);
+}
+
+
+void RBDataMap::init(UResourceBundle *data, UErrorCode &status) {
+ int32_t i = 0;
+ fData->removeAll();
+ UResourceBundle *t = NULL;
+ for(i = 0; i < ures_getSize(data); i++) {
+ t = ures_getByIndex(data, i, t, &status);
+ fData->put(UnicodeString(ures_getKey(t), -1, US_INV), new ResourceBundle(t, status), status);
+ }
+ ures_close(t);
+}
+
+void RBDataMap::init(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status)
+{
+ int32_t i = 0;
+ fData->removeAll();
+ UResourceBundle *t = NULL;
+ const UChar *key = NULL;
+ int32_t keyLen = 0;
+ if(ures_getSize(headers) == ures_getSize(data)) {
+ for(i = 0; i < ures_getSize(data); i++) {
+ t = ures_getByIndex(data, i, t, &status);
+ key = ures_getStringByIndex(headers, i, &keyLen, &status);
+ fData->put(UnicodeString(key, keyLen), new ResourceBundle(t, status), status);
+ }
+ } else {
+ // error
+ status = U_INVALID_FORMAT_ERROR;
+ }
+ ures_close(t);
+}
+
+const ResourceBundle *RBDataMap::getItem(const char* key, UErrorCode &status) const
+{
+ if(U_FAILURE(status)) {
+ return NULL;
+ }
+
+ UnicodeString hashKey(key, -1, US_INV);
+ const ResourceBundle *r = (ResourceBundle *)fData->get(hashKey);
+ if(r != NULL) {
+ return r;
+ } else {
+ status = U_MISSING_RESOURCE_ERROR;
+ return NULL;
+ }
+}
+
+const UnicodeString RBDataMap::getString(const char* key, UErrorCode &status) const
+{
+ const ResourceBundle *r = getItem(key, status);
+ if(U_SUCCESS(status)) {
+ return r->getString(status);
+ } else {
+ return UnicodeString();
+ }
+}
+
+int32_t
+RBDataMap::getInt28(const char* key, UErrorCode &status) const
+{
+ const ResourceBundle *r = getItem(key, status);
+ if(U_SUCCESS(status)) {
+ return r->getInt(status);
+ } else {
+ return 0;
+ }
+}
+
+uint32_t
+RBDataMap::getUInt28(const char* key, UErrorCode &status) const
+{
+ const ResourceBundle *r = getItem(key, status);
+ if(U_SUCCESS(status)) {
+ return r->getUInt(status);
+ } else {
+ return 0;
+ }
+}
+
+const int32_t *
+RBDataMap::getIntVector(int32_t &length, const char *key, UErrorCode &status) const {
+ const ResourceBundle *r = getItem(key, status);
+ if(U_SUCCESS(status)) {
+ return r->getIntVector(length, status);
+ } else {
+ return NULL;
+ }
+}
+
+const uint8_t *
+RBDataMap::getBinary(int32_t &length, const char *key, UErrorCode &status) const {
+ const ResourceBundle *r = getItem(key, status);
+ if(U_SUCCESS(status)) {
+ return r->getBinary(length, status);
+ } else {
+ return NULL;
+ }
+}
+
+int32_t RBDataMap::getInt(const char* key, UErrorCode &status) const
+{
+ UnicodeString r = this->getString(key, status);
+ if(U_SUCCESS(status)) {
+ return utoi(r);
+ } else {
+ return 0;
+ }
+}
+
+const UnicodeString* RBDataMap::getStringArray(int32_t& count, const char* key, UErrorCode &status) const
+{
+ const ResourceBundle *r = getItem(key, status);
+ if(U_SUCCESS(status)) {
+ int32_t i = 0;
+
+ count = r->getSize();
+ if(count <= 0) {
+ return NULL;
+ }
+
+ UnicodeString *result = new UnicodeString[count];
+ for(i = 0; i<count; i++) {
+ result[i] = r->getStringEx(i, status);
+ }
+ return result;
+ } else {
+ return NULL;
+ }
+}
+
+const int32_t* RBDataMap::getIntArray(int32_t& count, const char* key, UErrorCode &status) const
+{
+ const ResourceBundle *r = getItem(key, status);
+ if(U_SUCCESS(status)) {
+ int32_t i = 0;
+
+ count = r->getSize();
+ if(count <= 0) {
+ return NULL;
+ }
+
+ int32_t *result = new int32_t[count];
+ UnicodeString stringRes;
+ for(i = 0; i<count; i++) {
+ stringRes = r->getStringEx(i, status);
+ result[i] = utoi(stringRes);
+ }
+ return result;
+ } else {
+ return NULL;
+ }
+}
+
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/dbgutil.cpp b/Build/source/libs/icu/icu-xetex/tools/ctestfw/dbgutil.cpp
new file mode 100644
index 00000000000..46c7f0c05e4
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/dbgutil.cpp
@@ -0,0 +1,142 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 2007, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+
+#include "unicode/udbgutil.h"
+#include "unicode/dbgutil.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/unistr.h"
+#include "unicode/ustring.h"
+#include "util.h"
+#include "ucln.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static UnicodeString **strs = NULL;
+
+static const UnicodeString& _fieldString(UDebugEnumType type, int32_t field, UnicodeString& fillin) {
+ const char *str = udbg_enumName(type, field);
+ if(str == NULL) {
+ return fillin.remove();
+ } else {
+ return fillin = UnicodeString(str, ""); // optimize?
+ }
+}
+
+U_CDECL_BEGIN
+static void udbg_cleanup(void) {
+ if(strs != NULL) {
+ for(int t=0;t<=UDBG_ENUM_COUNT;t++) {
+ delete [] strs[t];
+ }
+ delete[] strs;
+ strs = NULL;
+ }
+}
+
+static UBool ctestfw_cleanup(void)
+{
+ udbg_cleanup();
+ return TRUE;
+}
+
+static void udbg_register_cleanup(void) {
+ ucln_registerCleanup(UCLN_CTESTFW, ctestfw_cleanup);
+}
+U_CDECL_END
+
+static void udbg_setup(void) {
+ if(strs == NULL) {
+ udbg_register_cleanup();
+ //fprintf(stderr,"Initializing string cache..\n");
+ //fflush(stderr);
+ UnicodeString **newStrs = new UnicodeString*[UDBG_ENUM_COUNT+1];
+ for(int t=0;t<UDBG_ENUM_COUNT;t++) {
+ int32_t c = udbg_enumCount((UDebugEnumType)t);
+ newStrs[t] = new UnicodeString[c+1];
+ for(int f=0;f<=c;f++) {
+ _fieldString((UDebugEnumType)t, f, newStrs[t][f]);
+ }
+ }
+ newStrs[UDBG_ENUM_COUNT] = new UnicodeString[1]; // empty string
+
+ strs = newStrs;
+ }
+}
+
+
+
+T_CTEST_API const UnicodeString& T_CTEST_EXPORT2 udbg_enumString(UDebugEnumType type, int32_t field) {
+ if(strs == NULL ) {
+ udbg_setup();
+ }
+ if(type<0||type>=UDBG_ENUM_COUNT) {
+ // use UDBG_ENUM_COUNT,0 to mean an empty string
+ //fprintf(stderr, "** returning out of range on %d\n",type);
+ //fflush(stderr);
+ return strs[UDBG_ENUM_COUNT][0];
+ }
+ int32_t count = udbg_enumCount(type);
+ //fprintf(stderr, "enumString [%d,%d]: typecount %d, fieldcount %d\n", type,field,UDBG_ENUM_COUNT,count);
+ //fflush(stderr);
+ if(field<0 || field > count) {
+ return strs[type][count];
+ } else { return strs[type][field];
+ }
+}
+
+T_CTEST_API int32_t T_CTEST_EXPORT2 udbg_enumByString(UDebugEnumType type, const UnicodeString& string) {
+ if(type<0||type>=UDBG_ENUM_COUNT) {
+ return -1;
+ }
+ // initialize array
+ udbg_enumString(type,0);
+ // search
+ for(int i=0;i<udbg_enumCount(type);i++) {
+ if(string == (strs[type][i])) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+// from DataMap::utoi
+T_CTEST_API int32_t
+udbg_stoi(const UnicodeString &s)
+{
+ char ch[256];
+ const UChar *u = s.getBuffer();
+ int32_t len = s.length();
+ u_UCharsToChars(u, ch, len);
+ ch[len] = 0; /* include terminating \0 */
+ return atoi(ch);
+}
+
+T_CTEST_API UnicodeString *
+udbg_escape(const UnicodeString &src, UnicodeString *dst)
+{
+ dst->remove();
+ for (int32_t i = 0; i < src.length(); ++i) {
+ UChar c = src[i];
+ if(ICU_Utility::isUnprintable(c)) {
+ *dst += UnicodeString("[");
+ ICU_Utility::escapeUnprintable(*dst, c);
+ *dst += UnicodeString("]");
+ }
+ else {
+ *dst += c;
+ }
+ }
+
+ return dst;
+}
+
+
+
+#endif
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/testdata.cpp b/Build/source/libs/icu/icu-xetex/tools/ctestfw/testdata.cpp
new file mode 100644
index 00000000000..0925cb59e9c
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/testdata.cpp
@@ -0,0 +1,142 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 2002-2005, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+
+/* Created by weiv 05/09/2002 */
+
+#include "unicode/testdata.h"
+
+
+TestData::TestData(const char* testName)
+: name(testName),
+fInfo(NULL),
+fCurrSettings(NULL),
+fCurrCase(NULL),
+fSettingsSize(0),
+fCasesSize(0),
+fCurrentSettings(0),
+fCurrentCase(0)
+
+{
+}
+
+TestData::~TestData() {
+ if(fInfo != NULL) {
+ delete fInfo;
+ }
+ if(fCurrSettings != NULL) {
+ delete fCurrSettings;
+ }
+ if(fCurrCase != NULL) {
+ delete fCurrCase;
+ }
+}
+
+const char * TestData::getName() const
+{
+ return name;
+}
+
+
+
+RBTestData::RBTestData(const char* testName)
+: TestData(testName),
+fData(NULL),
+fHeaders(NULL),
+fSettings(NULL),
+fCases(NULL)
+{
+}
+
+RBTestData::RBTestData(UResourceBundle *data, UResourceBundle *headers, UErrorCode& status)
+: TestData(ures_getKey(data)),
+fData(data),
+fHeaders(headers),
+fSettings(NULL),
+fCases(NULL)
+{
+ UErrorCode intStatus = U_ZERO_ERROR;
+ UResourceBundle *currHeaders = ures_getByKey(data, "Headers", NULL, &intStatus);
+ if(intStatus == U_ZERO_ERROR) {
+ ures_close(fHeaders);
+ fHeaders = currHeaders;
+ } else {
+ intStatus = U_ZERO_ERROR;
+ }
+ fSettings = ures_getByKey(data, "Settings", NULL, &intStatus);
+ fSettingsSize = ures_getSize(fSettings);
+ UResourceBundle *info = ures_getByKey(data, "Info", NULL, &intStatus);
+ if(U_SUCCESS(intStatus)) {
+ fInfo = new RBDataMap(info, status);
+ } else {
+ intStatus = U_ZERO_ERROR;
+ }
+ fCases = ures_getByKey(data, "Cases", NULL, &status);
+ fCasesSize = ures_getSize(fCases);
+
+ ures_close(info);
+}
+
+
+RBTestData::~RBTestData()
+{
+ ures_close(fData);
+ ures_close(fHeaders);
+ ures_close(fSettings);
+ ures_close(fCases);
+}
+
+UBool RBTestData::getInfo(const DataMap *& info, UErrorCode &/*status*/) const
+{
+ if(fInfo) {
+ info = fInfo;
+ return TRUE;
+ } else {
+ info = NULL;
+ return FALSE;
+ }
+}
+
+UBool RBTestData::nextSettings(const DataMap *& settings, UErrorCode &status)
+{
+ UErrorCode intStatus = U_ZERO_ERROR;
+ UResourceBundle *data = ures_getByIndex(fSettings, fCurrentSettings++, NULL, &intStatus);
+ if(U_SUCCESS(intStatus)) {
+ // reset the cases iterator
+ fCurrentCase = 0;
+ if(fCurrSettings == NULL) {
+ fCurrSettings = new RBDataMap(data, status);
+ } else {
+ ((RBDataMap *)fCurrSettings)->init(data, status);
+ }
+ ures_close(data);
+ settings = fCurrSettings;
+ return TRUE;
+ } else {
+ settings = NULL;
+ return FALSE;
+ }
+}
+
+UBool RBTestData::nextCase(const DataMap *& nextCase, UErrorCode &status)
+{
+ UErrorCode intStatus = U_ZERO_ERROR;
+ UResourceBundle *currCase = ures_getByIndex(fCases, fCurrentCase++, NULL, &intStatus);
+ if(U_SUCCESS(intStatus)) {
+ if(fCurrCase == NULL) {
+ fCurrCase = new RBDataMap(fHeaders, currCase, status);
+ } else {
+ ((RBDataMap *)fCurrCase)->init(fHeaders, currCase, status);
+ }
+ ures_close(currCase);
+ nextCase = fCurrCase;
+ return TRUE;
+ } else {
+ nextCase = NULL;
+ return FALSE;
+ }
+}
+
+
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/tstdtmod.cpp b/Build/source/libs/icu/icu-xetex/tools/ctestfw/tstdtmod.cpp
new file mode 100644
index 00000000000..2f050296c37
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/tstdtmod.cpp
@@ -0,0 +1,170 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 2002-2006, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+
+/* Created by weiv 05/09/2002 */
+
+#include "unicode/tstdtmod.h"
+#include "cmemory.h"
+
+TestLog::~TestLog() {}
+
+TestDataModule *TestDataModule::getTestDataModule(const char* name, TestLog& log, UErrorCode &status)
+{
+ if(U_FAILURE(status)) {
+ return NULL;
+ }
+ TestDataModule *result = NULL;
+
+ // TODO: probe for resource bundle and then for XML.
+ // According to that, construct an appropriate driver object
+
+ result = new RBTestDataModule(name, log, status);
+ if(U_SUCCESS(status)) {
+ return result;
+ } else {
+ delete result;
+ return NULL;
+ }
+}
+
+TestDataModule::TestDataModule(const char* name, TestLog& log, UErrorCode& /*status*/)
+: testName(name),
+fInfo(NULL),
+fLog(log)
+{
+}
+
+TestDataModule::~TestDataModule() {
+ if(fInfo != NULL) {
+ delete fInfo;
+ }
+}
+
+const char * TestDataModule::getName() const
+{
+ return testName;
+}
+
+
+
+RBTestDataModule::~RBTestDataModule()
+{
+ ures_close(fTestData);
+ ures_close(fModuleBundle);
+ ures_close(fInfoRB);
+ uprv_free(tdpath);
+}
+
+RBTestDataModule::RBTestDataModule(const char* name, TestLog& log, UErrorCode& status)
+: TestDataModule(name, log, status),
+ fModuleBundle(NULL),
+ fTestData(NULL),
+ fInfoRB(NULL),
+ tdpath(NULL)
+{
+ fNumberOfTests = 0;
+ fDataTestValid = TRUE;
+ fModuleBundle = getTestBundle(name, status);
+ if(fDataTestValid) {
+ fTestData = ures_getByKey(fModuleBundle, "TestData", NULL, &status);
+ fNumberOfTests = ures_getSize(fTestData);
+ fInfoRB = ures_getByKey(fModuleBundle, "Info", NULL, &status);
+ if(status != U_ZERO_ERROR) {
+ log.errln(UNICODE_STRING_SIMPLE("Unable to initalize test data - missing mandatory description resources!"));
+ fDataTestValid = FALSE;
+ } else {
+ fInfo = new RBDataMap(fInfoRB, status);
+ }
+ }
+}
+
+UBool RBTestDataModule::getInfo(const DataMap *& info, UErrorCode &/*status*/) const
+{
+ info = fInfo;
+ if(fInfo) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+TestData* RBTestDataModule::createTestData(int32_t index, UErrorCode &status) const
+{
+ TestData *result = NULL;
+ UErrorCode intStatus = U_ZERO_ERROR;
+
+ if(fDataTestValid == TRUE) {
+ // Both of these resources get adopted by a TestData object.
+ UResourceBundle *DataFillIn = ures_getByIndex(fTestData, index, NULL, &status);
+ UResourceBundle *headers = ures_getByKey(fInfoRB, "Headers", NULL, &intStatus);
+
+ if(U_SUCCESS(status)) {
+ result = new RBTestData(DataFillIn, headers, status);
+
+ if(U_SUCCESS(status)) {
+ return result;
+ } else {
+ delete result;
+ }
+ } else {
+ ures_close(DataFillIn);
+ ures_close(headers);
+ }
+ } else {
+ status = U_MISSING_RESOURCE_ERROR;
+ }
+ return NULL;
+}
+
+TestData* RBTestDataModule::createTestData(const char* name, UErrorCode &status) const
+{
+ TestData *result = NULL;
+ UErrorCode intStatus = U_ZERO_ERROR;
+
+ if(fDataTestValid == TRUE) {
+ // Both of these resources get adopted by a TestData object.
+ UResourceBundle *DataFillIn = ures_getByKey(fTestData, name, NULL, &status);
+ UResourceBundle *headers = ures_getByKey(fInfoRB, "Headers", NULL, &intStatus);
+
+ if(U_SUCCESS(status)) {
+ result = new RBTestData(DataFillIn, headers, status);
+ if(U_SUCCESS(status)) {
+ return result;
+ } else {
+ delete result;
+ }
+ } else {
+ ures_close(DataFillIn);
+ ures_close(headers);
+ }
+ } else {
+ status = U_MISSING_RESOURCE_ERROR;
+ }
+ return NULL;
+}
+
+
+
+//Get test data from ResourceBundles
+UResourceBundle*
+RBTestDataModule::getTestBundle(const char* bundleName, UErrorCode &status)
+{
+ if(U_SUCCESS(status)) {
+ UResourceBundle *testBundle = NULL;
+ const char* icu_data = fLog.getTestDataPath(status);
+ if (testBundle == NULL) {
+ testBundle = ures_openDirect(icu_data, bundleName, &status);
+ if (status != U_ZERO_ERROR) {
+ fLog.errln(UNICODE_STRING_SIMPLE("Failed: could not load test data from resourcebundle: ") + UnicodeString(bundleName, -1, US_INV));
+ fDataTestValid = FALSE;
+ }
+ }
+ return testBundle;
+ } else {
+ return NULL;
+ }
+}
+
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/udbgutil.cpp b/Build/source/libs/icu/icu-xetex/tools/ctestfw/udbgutil.cpp
new file mode 100644
index 00000000000..c4f55966b17
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/udbgutil.cpp
@@ -0,0 +1,198 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 2007, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+
+#include "unicode/udbgutil.h"
+
+
+
+struct Field {
+ int32_t prefix; /* how many characters to remove - i.e. UCHAR_ = 5 */
+ const char *str;
+ int32_t num;
+};
+
+#define DBG_ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0]))
+
+
+// The fields
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/ucal.h"
+// Calendar
+
+
+// 'UCAL_' = 5
+#define FIELD_NAME_STR(y,x) { y, #x, x }
+
+#define LEN_UCAL 5 /* UCAL_ */
+
+static const int32_t count_UCalendarDateFields = UCAL_FIELD_COUNT;
+
+static const Field names_UCalendarDateFields[] =
+{
+ FIELD_NAME_STR( LEN_UCAL, UCAL_ERA ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_YEAR ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_MONTH ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_WEEK_OF_YEAR ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_WEEK_OF_MONTH ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_DATE ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_DAY_OF_YEAR ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_DAY_OF_WEEK ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_DAY_OF_WEEK_IN_MONTH ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_AM_PM ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_HOUR ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_HOUR_OF_DAY ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_MINUTE ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_SECOND ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_MILLISECOND ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_ZONE_OFFSET ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_DST_OFFSET ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_YEAR_WOY ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_DOW_LOCAL ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_EXTENDED_YEAR ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_JULIAN_DAY ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_MILLISECONDS_IN_DAY ),
+};
+
+
+static const int32_t count_UCalendarMonths = UCAL_UNDECIMBER+1;
+
+static const Field names_UCalendarMonths[] =
+{
+ FIELD_NAME_STR( LEN_UCAL, UCAL_JANUARY ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_FEBRUARY ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_MARCH ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_APRIL ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_MAY ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_JUNE ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_JULY ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_AUGUST ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_SEPTEMBER ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_OCTOBER ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_NOVEMBER ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_DECEMBER ),
+ FIELD_NAME_STR( LEN_UCAL, UCAL_UNDECIMBER)
+};
+
+#include "unicode/udat.h"
+
+#define LEN_UDAT 5 /* "UDAT_" */
+
+static const int32_t count_UDateFormatStyle = UDAT_SHORT+1;
+
+static const Field names_UDateFormatStyle[] =
+{
+ FIELD_NAME_STR( LEN_UDAT, UDAT_FULL ),
+ FIELD_NAME_STR( LEN_UDAT, UDAT_LONG ),
+ FIELD_NAME_STR( LEN_UDAT, UDAT_MEDIUM ),
+ FIELD_NAME_STR( LEN_UDAT, UDAT_SHORT ),
+ /* end regular */
+ /*
+ * negative enums.. leave out for now.
+ FIELD_NAME_STR( LEN_UDAT, UDAT_NONE ),
+ FIELD_NAME_STR( LEN_UDAT, UDAT_IGNORE ),
+ */
+};
+
+
+
+#define LEN_UDBG 5 /* "UDBG_" */
+
+static const int32_t count_UDebugEnumType = UDBG_ENUM_COUNT;
+
+static const Field names_UDebugEnumType[] =
+{
+ FIELD_NAME_STR( LEN_UDBG, UDBG_UDebugEnumType ),
+ FIELD_NAME_STR( LEN_UDBG, UDBG_UCalendarDateFields ),
+ FIELD_NAME_STR( LEN_UDBG, UDBG_UCalendarMonths ),
+ FIELD_NAME_STR( LEN_UDBG, UDBG_UDateFormatStyle ),
+};
+
+
+#define COUNT_CASE(x) case UDBG_##x: return (actual?count_##x:DBG_ARRAY_COUNT(names_##x));
+#define COUNT_FAIL_CASE(x) case UDBG_##x: return -1;
+
+#define FIELD_CASE(x) case UDBG_##x: return names_##x;
+#define FIELD_FAIL_CASE(x) case UDBG_##x: return NULL;
+
+#else
+
+#define COUNT_CASE(x)
+#define COUNT_FAIL_CASE(x)
+
+#define FIELD_CASE(X)
+#define FIELD_FAIL_CASE(x)
+
+#endif
+
+// low level
+
+/**
+ * @param type type of item
+ * @param actual TRUE: for the actual enum's type (UCAL_FIELD_COUNT, etc), or FALSE for the string count
+ */
+static int32_t _udbg_enumCount(UDebugEnumType type, UBool actual) {
+ switch(type) {
+ COUNT_CASE(UDebugEnumType)
+ COUNT_CASE(UCalendarDateFields)
+ COUNT_CASE(UCalendarMonths)
+ COUNT_CASE(UDateFormatStyle)
+ // COUNT_FAIL_CASE(UNonExistentEnum)
+ default:
+ return -1;
+ }
+}
+
+static const Field* _udbg_enumFields(UDebugEnumType type) {
+ switch(type) {
+ FIELD_CASE(UDebugEnumType)
+ FIELD_CASE(UCalendarDateFields)
+ FIELD_CASE(UCalendarMonths)
+ FIELD_CASE(UDateFormatStyle)
+ // FIELD_FAIL_CASE(UNonExistentEnum)
+ default:
+ return NULL;
+ }
+}
+
+// implementation
+
+int32_t udbg_enumCount(UDebugEnumType type) {
+ return _udbg_enumCount(type, FALSE);
+}
+
+int32_t udbg_enumExpectedCount(UDebugEnumType type) {
+ return _udbg_enumCount(type, TRUE);
+}
+
+const char * udbg_enumName(UDebugEnumType type, int32_t field) {
+ if(field<0 ||
+ field>=_udbg_enumCount(type,FALSE)) { // also will catch unsupported items
+ return NULL;
+ } else {
+ const Field *fields = _udbg_enumFields(type);
+ if(fields == NULL) {
+ return NULL;
+ } else {
+ return fields[field].str + fields[field].prefix;
+ }
+ }
+}
+
+int32_t udbg_enumArrayValue(UDebugEnumType type, int32_t field) {
+ if(field<0 ||
+ field>=_udbg_enumCount(type,FALSE)) { // also will catch unsupported items
+ return -1;
+ } else {
+ const Field *fields = _udbg_enumFields(type);
+ if(fields == NULL) {
+ return -1;
+ } else {
+ return fields[field].num;
+ }
+ }
+}
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/ctest.h b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/ctest.h
new file mode 100644
index 00000000000..9c2f04c5ee7
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/ctest.h
@@ -0,0 +1,199 @@
+/*
+********************************************************************************
+*
+* Copyright (C) 1996-2004, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+********************************************************************************
+*/
+
+#ifndef CTEST_H
+#define CTEST_H
+
+#include "unicode/testtype.h"
+#include "unicode/utrace.h"
+
+
+/* prototypes *********************************/
+
+U_CDECL_BEGIN
+typedef void (U_CALLCONV *TestFunctionPtr)(void);
+typedef struct TestNode TestNode;
+U_CDECL_END
+
+/**
+ * Set this to zero to disable log_verbose() messages.
+ * Otherwise nonzero to see log_verbose() messages.
+ *
+ * @internal Internal APIs for testing purpose only
+ */
+extern T_CTEST_EXPORT_API int REPEAT_TESTS;
+
+/**
+ * Set this to zero to disable log_verbose() messages.
+ * Otherwise nonzero to see log_verbose() messages.
+ *
+ * @internal Internal APIs for testing purpose only
+ */
+extern T_CTEST_EXPORT_API int VERBOSITY;
+
+/**
+ * Set this to zero to disable log_verbose() messages.
+ * Otherwise nonzero to see log_verbose() messages.
+ *
+ * @internal Internal APIs for testing purpose only
+ */
+extern T_CTEST_EXPORT_API int ERR_MSG;
+
+/**
+ * Set this to zero to disable some of the slower tests.
+ * Otherwise nonzero to run the slower tests.
+ *
+ * @internal Internal APIs for testing purpose only
+ */
+extern T_CTEST_EXPORT_API int QUICK;
+
+/**
+ * Set this to nonzero to warn (not error) on missing data.
+ * Otherwise, zero will cause an error to be propagated when data is not available.
+ * Affects the behavior of log_dataerr.
+ *
+ * @see log_data_err
+ * @internal Internal APIs for testing purpose only
+ */
+extern T_CTEST_EXPORT_API int WARN_ON_MISSING_DATA;
+
+/**
+ * ICU tracing level, is set by command line option
+ *
+ * @internal
+ */
+extern T_CTEST_EXPORT_API UTraceLevel ICU_TRACE;
+
+/**
+ * Show the names of all nodes.
+ *
+ * @param root Subtree of tests.
+ * @internal Internal APIs for testing purpose only
+ */
+T_CTEST_API void T_CTEST_EXPORT2
+showTests ( const TestNode *root);
+
+/**
+ * Run a subtree of tests.
+ *
+ * @param root Subtree of tests.
+ * @internal Internal APIs for testing purpose only
+ */
+T_CTEST_API void T_CTEST_EXPORT2
+runTests ( const TestNode* root);
+
+/**
+ * Add a test to the subtree.
+ * Example usage:
+ * <PRE>
+ * TestNode* root=NULL;
+ * addTest(&root, &mytest, "/a/b/mytest" );
+ * </PRE>
+ * @param root Pointer to the root pointer.
+ * @param test Pointer to 'void function(void)' for actual test.
+ * @param path Path from root under which test will be placed. Ex. '/a/b/mytest'
+ * @internal Internal APIs for testing purpose only
+ */
+T_CTEST_API void T_CTEST_EXPORT2
+addTest(TestNode** root,
+ TestFunctionPtr test,
+ const char *path);
+
+/**
+ * Clean up any allocated memory.
+ * Conditions for calling this function are the same as u_cleanup().
+ * @see u_cleanup
+ * @internal Internal APIs for testing purpose only
+ */
+T_CTEST_API void T_CTEST_EXPORT2
+cleanUpTestTree(TestNode *tn);
+
+/**
+ * Retreive a specific subtest. (subtree).
+ *
+ * @param root Pointer to the root.
+ * @param path Path relative to the root, Ex. '/a/b'
+ * @return The subtest, or NULL on failure.
+ * @internal Internal APIs for testing purpose only
+ */
+T_CTEST_API const TestNode* T_CTEST_EXPORT2
+getTest(const TestNode* root,
+ const char *path);
+
+
+/**
+ * Log an error message. (printf style)
+ * @param pattern printf-style format string
+ * @internal Internal APIs for testing purpose only
+ */
+T_CTEST_API void T_CTEST_EXPORT2
+log_err(const char* pattern, ...);
+
+/**
+ * Log an informational message. (printf style)
+ * @param pattern printf-style format string
+ * @internal Internal APIs for testing purpose only
+ */
+T_CTEST_API void T_CTEST_EXPORT2
+log_info(const char* pattern, ...);
+
+/**
+ * Log an informational message. (vprintf style)
+ * @param prefix a string that is output before the pattern and without formatting
+ * @param pattern printf-style format string
+ * @param ap variable-arguments list
+ * @internal Internal APIs for testing purpose only
+ */
+T_CTEST_API void T_CTEST_EXPORT2
+vlog_info(const char *prefix, const char *pattern, va_list ap);
+
+/**
+ * Log a verbose informational message. (printf style)
+ * This message will only appear if the global VERBOSITY is nonzero
+ * @param pattern printf-style format string
+ * @internal Internal APIs for testing purpose only
+ */
+T_CTEST_API void T_CTEST_EXPORT2
+log_verbose(const char* pattern, ...);
+
+/**
+ * Log an error message concerning missing data. (printf style)
+ * If WARN_ON_MISSING_DATA is nonzero, this will case a log_info (warning) to be
+ * printed, but if it is zero this will produce an error (log_err).
+ * @param pattern printf-style format string
+ * @internal Internal APIs for testing purpose only
+ */
+T_CTEST_API void T_CTEST_EXPORT2
+log_data_err(const char *pattern, ...);
+
+/**
+ * Processes the command line arguments.
+ * This is a sample implementation
+ * <PRE>Usage: %s [ -l ] [ -v ] [ -? ] [ /path/to/test ]
+ * -l List only, do not run\
+ * -v turn OFF verbosity
+ * -? print this message</PRE>
+ * @param root Testnode root with tests already attached to it
+ * @param argv argument list from main (stdio.h)
+ * @param argc argument list count from main (stdio.h)
+ * @return positive for error count, 0 for success, negative for illegal argument
+ * @internal Internal APIs for testing purpose only
+ */
+T_CTEST_API int T_CTEST_EXPORT2
+processArgs(const TestNode* root,
+ int argc,
+ const char* const argv[]);
+
+
+T_CTEST_API const char* T_CTEST_EXPORT2
+getTestName(void);
+
+
+
+#endif
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/datamap.h b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/datamap.h
new file mode 100644
index 00000000000..00d8b05eaca
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/datamap.h
@@ -0,0 +1,138 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 2002-2006, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+
+/* Created by weiv 05/09/2002 */
+
+#ifndef U_TESTFW_DATAMAP
+#define U_TESTFW_DATAMAP
+
+#include "unicode/resbund.h"
+#include "unicode/testtype.h"
+
+
+
+U_NAMESPACE_BEGIN
+class Hashtable;
+U_NAMESPACE_END
+
+/** Holder of test data and settings. Allows addressing of items by name.
+ * For test cases, names are defined in the "Headers" section. For settings
+ * and info data, names are keys in data. Currently, we return scalar strings
+ * and integers and arrays of strings and integers. Arrays should be deposited
+ * of by the user.
+ */
+class T_CTEST_EXPORT_API DataMap {
+public:
+ virtual ~DataMap();
+
+protected:
+ DataMap();
+ int32_t utoi(const UnicodeString &s) const;
+
+
+public:
+ /** get the string from the DataMap. Addressed by name
+ * @param key name of the data field.
+ * @return a string containing the data
+ */
+ virtual const UnicodeString getString(const char* key, UErrorCode &status) const = 0;
+
+ /** get the string from the DataMap. Addressed by name
+ * parses a bundle string into an integer
+ * @param key name of the data field.
+ * @return an integer containing the data
+ */
+ virtual int32_t getInt(const char* key, UErrorCode &status) const = 0;
+
+ /**
+ * Get a signed integer without runtime parsing.
+ * @param key name of the data field.
+ * @param status UErrorCode in/out parameter
+ * @return the integer
+ */
+ virtual int32_t getInt28(const char* key, UErrorCode &status) const = 0;
+
+ /**
+ * Get an unsigned integer without runtime parsing.
+ * @param key name of the data field.
+ * @param status UErrorCode in/out parameter
+ * @return the integer
+ */
+ virtual uint32_t getUInt28(const char* key, UErrorCode &status) const = 0;
+
+ /**
+ * Get a vector of integers without runtime parsing.
+ * @param length output parameter for the length of the vector
+ * @param key name of the data field.
+ * @param status UErrorCode in/out parameter
+ * @return the integer vector, do not delete
+ */
+ virtual const int32_t *getIntVector(int32_t &length, const char *key, UErrorCode &status) const = 0;
+
+ /**
+ * Get binary data without runtime parsing.
+ * @param length output parameter for the length of the data
+ * @param key name of the data field.
+ * @param status UErrorCode in/out parameter
+ * @return the binary data, do not delete
+ */
+ virtual const uint8_t *getBinary(int32_t &length, const char *key, UErrorCode &status) const = 0;
+
+ /** get an array of strings from the DataMap. Addressed by name.
+ * The user must dispose of it after usage, using delete.
+ * @param key name of the data field.
+ * @return a string array containing the data
+ */
+ virtual const UnicodeString* getStringArray(int32_t& count, const char* key, UErrorCode &status) const = 0;
+
+ /** get an array of integers from the DataMap. Addressed by name.
+ * The user must dispose of it after usage, using delete.
+ * @param key name of the data field.
+ * @return an integer array containing the data
+ */
+ virtual const int32_t* getIntArray(int32_t& count, const char* key, UErrorCode &status) const = 0;
+
+ // ... etc ...
+};
+
+// This one is already concrete - it is going to be instantiated from
+// concrete data by TestData children...
+class T_CTEST_EXPORT_API RBDataMap : public DataMap{
+private:
+ Hashtable *fData;
+
+public:
+ virtual ~RBDataMap();
+
+public:
+ RBDataMap();
+
+ RBDataMap(UResourceBundle *data, UErrorCode &status);
+ RBDataMap(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status);
+
+public:
+ void init(UResourceBundle *data, UErrorCode &status);
+ void init(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status);
+
+ virtual const ResourceBundle *getItem(const char* key, UErrorCode &status) const;
+
+ virtual const UnicodeString getString(const char* key, UErrorCode &status) const;
+ virtual int32_t getInt28(const char* key, UErrorCode &status) const;
+ virtual uint32_t getUInt28(const char* key, UErrorCode &status) const;
+ virtual const int32_t *getIntVector(int32_t &length, const char *key, UErrorCode &status) const;
+ virtual const uint8_t *getBinary(int32_t &length, const char *key, UErrorCode &status) const;
+
+ virtual int32_t getInt(const char* key, UErrorCode &status) const;
+
+ virtual const UnicodeString* getStringArray(int32_t& count, const char* key, UErrorCode &status) const;
+ virtual const int32_t* getIntArray(int32_t& count, const char* key, UErrorCode &status) const;
+
+ // ... etc ...
+};
+
+
+#endif
+
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/dbgutil.h b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/dbgutil.h
new file mode 100644
index 00000000000..e4d9cc7f1a8
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/dbgutil.h
@@ -0,0 +1,38 @@
+
+/*
+************************************************************************
+* Copyright (c) 2007, International Business Machines
+* Corporation and others. All Rights Reserved.
+************************************************************************
+*/
+
+/** C++ Utilities to aid in debugging **/
+
+#ifndef _DBGUTIL_H
+#define _DBGUTIL_H
+
+#include "unicode/utypes.h"
+#include "unicode/udbgutil.h"
+#include "unicode/unistr.h"
+#include "unicode/testtype.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+//class UnicodeString;
+
+T_CTEST_API const UnicodeString& T_CTEST_EXPORT2 udbg_enumString(UDebugEnumType type, int32_t field);
+
+T_CTEST_API int32_t T_CTEST_EXPORT2 udbg_enumByString(UDebugEnumType type, const UnicodeString& string);
+
+/**
+ * Convert a UnicodeString (with ascii digits) into a number.
+ * @param s string
+ * @return numerical value, or 0 on error
+ */
+T_CTEST_API int32_t T_CTEST_EXPORT2 udbg_stoi(const UnicodeString &s);
+
+T_CTEST_API UnicodeString *udbg_escape(const UnicodeString &s, UnicodeString *dst);
+
+#endif
+
+#endif
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testdata.h b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testdata.h
new file mode 100644
index 00000000000..a248bf568dc
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testdata.h
@@ -0,0 +1,111 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 2002-2006, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+
+/* Created by weiv 05/09/2002 */
+
+/* Base class for data driven tests */
+
+#ifndef U_TESTFW_TESTDATA
+#define U_TESTFW_TESTDATA
+
+#include "unicode/tstdtmod.h"
+#include "unicode/datamap.h"
+
+
+ /** This is the class that abstracts one of the tests in a data file
+ * It is usually instantiated using TestDataModule::CreateTestData method
+ * This class provides two important methods: nextSettings and nextCase
+ * Usually, one walks through all settings and executes all cases for
+ * each setting. Each call to nextSettings resets the cases iterator.
+ * Individual test cases have to have the same number of fields as the
+ * number of entries in headers. Default headers can be specified in
+ * the TestDataModule info section. The default headers will be overriden
+ * by per-test headers.
+ * Example:
+ * DataMap *settings = NULL;
+ * DataMap *cases = NULL;
+ * while(nextSettings(settings, status)) {
+ * // set settings for the subtest
+ * while(nextCase(cases, status) {
+ * // process testcase
+ * }
+ * }
+ */
+
+class T_CTEST_EXPORT_API TestData {
+ const char* name;
+
+protected:
+ DataMap *fInfo;
+ DataMap *fCurrSettings;
+ DataMap *fCurrCase;
+ int32_t fSettingsSize;
+ int32_t fCasesSize;
+ int32_t fCurrentSettings;
+ int32_t fCurrentCase;
+ /** constructor - don't use */
+ TestData(const char* name);
+
+public:
+ virtual ~TestData();
+
+ const char* getName() const;
+
+ /** Get a pointer to an object owned DataMap that contains more information on this
+ * TestData object.
+ * Usual fields is "Description".
+ * @param info pass in a const DataMap pointer. If no info, it will be set to NULL
+ */
+ virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const = 0;
+
+ /** Gets the next set of settings for the test. Resets the cases iterator.
+ * DataMap is owned by the object and should not be deleted.
+ * @param settings a DataMap pointer provided by the user. Will be NULL if
+ * no more settings are available.
+ * @param status for reporting unexpected errors.
+ * @return A boolean, TRUE if there are settings, FALSE if there is no more
+ * settings.
+ */
+ virtual UBool nextSettings(const DataMap *& settings, UErrorCode &status) = 0;
+
+ /** Gets the next test case.
+ * DataMap is owned by the object and should not be deleted.
+ * @param data a DataMap pointer provided by the user. Will be NULL if
+ * no more cases are available.
+ * @param status for reporting unexpected errors.
+ * @return A boolean, TRUE if there are cases, FALSE if there is no more
+ * cases.
+ */
+ virtual UBool nextCase(const DataMap *& data, UErrorCode &status) = 0;
+};
+
+// implementation of TestData that uses resource bundles
+
+class T_CTEST_EXPORT_API RBTestData : public TestData {
+ UResourceBundle *fData;
+ UResourceBundle *fHeaders;
+ UResourceBundle *fSettings;
+ UResourceBundle *fCases;
+
+public:
+ RBTestData(const char* name);
+ RBTestData(UResourceBundle *data, UResourceBundle *headers, UErrorCode& status);
+private:
+// RBTestData() {};
+// RBTestData(const RBTestData& original) {};
+ RBTestData& operator=(const RBTestData& /*original*/);
+
+public:
+ virtual ~RBTestData();
+
+ virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const;
+
+ virtual UBool nextSettings(const DataMap *& settings, UErrorCode &status);
+ virtual UBool nextCase(const DataMap *& nextCase, UErrorCode &status);
+};
+
+#endif
+
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testlog.h b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testlog.h
new file mode 100644
index 00000000000..a6c8f0d1f0c
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testlog.h
@@ -0,0 +1,29 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 2004-2006, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+
+/* Created by grhoten 03/17/2004 */
+
+/* Base class for data driven tests */
+
+#ifndef U_TESTFW_TESTLOG
+#define U_TESTFW_TESTLOG
+
+#include "unicode/unistr.h"
+#include "unicode/testtype.h"
+
+/** Facilitates internal logging of data driven test service
+ * It would be interesting to develop this into a full
+ * fledged control system as in Java.
+ */
+class T_CTEST_EXPORT_API TestLog {
+public:
+ virtual ~TestLog();
+ virtual void errln( const UnicodeString &message ) = 0;
+ virtual const char* getTestDataPath(UErrorCode& err) = 0;
+};
+
+
+#endif
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testtype.h b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testtype.h
new file mode 100644
index 00000000000..6deb1cdff09
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/testtype.h
@@ -0,0 +1,39 @@
+/*
+ *****************************************************************************************
+ * Copyright (C) 2004-2007, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ *****************************************************************************************
+ */
+
+#include "unicode/utypes.h"
+
+/*Deals with imports and exports of the dynamic library*/
+#if !defined(U_STATIC_IMPLEMENTATION)
+ #define T_CTEST_EXPORT U_EXPORT
+ #define T_CTEST_IMPORT U_IMPORT
+#else
+ #define T_CTEST_EXPORT
+ #define T_CTEST_IMPORT
+#endif
+
+#if defined(U_WINDOWS)
+#define T_CTEST_EXPORT2 __cdecl
+#else
+#define T_CTEST_EXPORT2
+#endif
+
+#ifdef __cplusplus
+ #define C_CTEST_API extern "C"
+ U_NAMESPACE_USE
+#else
+ #define C_CTEST_API
+#endif
+
+#ifdef T_CTEST_IMPLEMENTATION
+ #define T_CTEST_API C_CTEST_API T_CTEST_EXPORT
+ #define T_CTEST_EXPORT_API T_CTEST_EXPORT
+#else
+ #define T_CTEST_API C_CTEST_API T_CTEST_IMPORT
+ #define T_CTEST_EXPORT_API T_CTEST_IMPORT
+#endif
+
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/tstdtmod.h b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/tstdtmod.h
new file mode 100644
index 00000000000..06799b5f688
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/tstdtmod.h
@@ -0,0 +1,115 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 2002-2005, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+
+/* Created by weiv 05/09/2002 */
+
+/* Base class for data driven tests */
+
+#ifndef U_TESTFW_TESTMODULE
+#define U_TESTFW_TESTMODULE
+
+#include "unicode/unistr.h"
+#include "unicode/ures.h"
+#include "unicode/testtype.h"
+#include "unicode/testdata.h"
+#include "unicode/datamap.h"
+#include "unicode/testlog.h"
+
+
+/* This class abstracts the actual organization of the
+ * data for data driven tests
+ */
+
+
+class DataMap;
+class TestData;
+
+
+/** Main data driven test class. Corresponds to one named data
+ * unit (such as a resource bundle. It is instantiated using
+ * a factory method getTestDataModule
+ */
+class T_CTEST_EXPORT_API TestDataModule {
+ const char* testName;
+
+protected:
+ DataMap *fInfo;
+ TestLog& fLog;
+
+public:
+ /** Factory method.
+ * @param name name of the test module. Usually name of a resource bundle or a XML file
+ * @param log a logging class, used for internal error reporting.
+ * @param status if something goes wrong, status will be set
+ * @return a TestDataModule object. Use it to get test data from it
+ */
+ static TestDataModule *getTestDataModule(const char* name, TestLog& log, UErrorCode &status);
+ virtual ~TestDataModule();
+
+protected:
+ TestDataModule(const char* name, TestLog& log, UErrorCode& status);
+
+public:
+ /** Name of this TestData module.
+ * @return a name
+ */
+ const char * getName() const;
+
+ /** Get a pointer to an object owned DataMap that contains more information on this module
+ * Usual fields are "Description", "LongDescription", "Settings". Also, if containing a
+ * field "Headers" these will be used as the default headers, so that you don't have to
+ * to specify per test headers.
+ * @param info pass in a const DataMap pointer. If no info, it will be set to NULL
+ */
+ virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const = 0;
+
+ /** Create a test data object from an index. Helpful for integrating tests with current
+ * intltest framework which addresses the tests by index.
+ * @param index index of the test to be instantiated
+ * @return an instantiated TestData object, ready to provide settings and cases for
+ * the tests.
+ */
+ virtual TestData* createTestData(int32_t index, UErrorCode &status) const = 0;
+
+ /** Create a test data object from a name.
+ * @param name name of the test to be instantiated
+ * @return an instantiated TestData object, ready to provide settings and cases for
+ * the tests.
+ */
+ virtual TestData* createTestData(const char* name, UErrorCode &status) const = 0;
+};
+
+class T_CTEST_EXPORT_API RBTestDataModule : public TestDataModule {
+public:
+ virtual ~RBTestDataModule();
+
+public:
+ RBTestDataModule(const char* name, TestLog& log, UErrorCode& status);
+
+public:
+ virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const;
+
+ virtual TestData* createTestData(int32_t index, UErrorCode &status) const;
+ virtual TestData* createTestData(const char* name, UErrorCode &status) const;
+
+private:
+ UResourceBundle *getTestBundle(const char* bundleName, UErrorCode &status);
+
+private:
+ UResourceBundle *fModuleBundle;
+ UResourceBundle *fTestData;
+ UResourceBundle *fInfoRB;
+ UBool fDataTestValid;
+ char *tdpath;
+
+/* const char* fTestName;*/ /* See name */
+ int32_t fNumberOfTests;
+
+};
+
+
+#endif
+
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/udbgutil.h b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/udbgutil.h
new file mode 100644
index 00000000000..e1decd4d026
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/udbgutil.h
@@ -0,0 +1,58 @@
+/*
+************************************************************************
+* Copyright (c) 2007, International Business Machines
+* Corporation and others. All Rights Reserved.
+************************************************************************
+*/
+
+/** C Utilities to aid in debugging **/
+
+#ifndef _UDBGUTIL_H
+#define _UDBGUTIL_H
+
+#include "unicode/testtype.h"
+#include "unicode/utypes.h"
+
+
+enum UDebugEnumType {
+ UDBG_UDebugEnumType = 0, /* Self-referential, strings for UDebugEnumType. Count=ENUM_COUNT. */
+ UDBG_UCalendarDateFields, /* UCalendarDateFields. Count=UCAL_FIELD_COUNT. Unsupported if UCONFIG_NO_FORMATTING. */
+ UDBG_UCalendarMonths, /* UCalendarMonths. Count= (UCAL_UNDECIMBER+1) */
+ UDBG_UDateFormatStyle, /* Count = UDAT_SHORT=1 */
+ UDBG_ENUM_COUNT
+};
+
+typedef enum UDebugEnumType UDebugEnumType;
+
+/**
+ * @param type the type of enum
+ * Print how many enums are contained for this type.
+ * Should be equal to the appropriate _COUNT constant or there is an error. Return -1 if unsupported.
+ */
+T_CTEST_API int32_t T_CTEST_EXPORT2 udbg_enumCount(UDebugEnumType type);
+
+/**
+ * Convert an enum to a string
+ * @param type type of enum
+ * @param field field number
+ * @return string of the format "ERA", "YEAR", etc, or NULL if out of range or unsupported
+ */
+T_CTEST_API const char * T_CTEST_EXPORT2 udbg_enumName(UDebugEnumType type, int32_t field);
+
+/**
+ * for consistency checking
+ * @param type the type of enum
+ * Print how many enums should be contained for this type.
+ * This is equal to the appropriate _COUNT constant or there is an error. Returns -1 if unsupported.
+ */
+T_CTEST_API int32_t T_CTEST_EXPORT2 udbg_enumExpectedCount(UDebugEnumType type);
+
+/**
+ * For consistency checking, returns the expected enum ordinal value for the given index value.
+ * @param type which type
+ * @param field field number
+ * @return should be equal to 'field' or -1 if out of range.
+ */
+T_CTEST_API int32_t T_CTEST_EXPORT2 udbg_enumArrayValue(UDebugEnumType type, int32_t field);
+
+#endif
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/uperf.h b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/uperf.h
new file mode 100644
index 00000000000..5568f0e6652
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/uperf.h
@@ -0,0 +1,179 @@
+/*
+**********************************************************************
+* Copyright (c) 2002-2007, International Business Machines
+* Corporation and others. All Rights Reserved.
+**********************************************************************
+*/
+#ifndef _UPERF_H
+#define _UPERF_H
+
+#include "unicode/utypes.h"
+#include "unicode/unistr.h"
+#include "unicode/ustring.h"
+
+#include "unicode/testtype.h"
+#include "unicode/utimer.h"
+#include "ucbuf.h"
+
+// Forward declarations from uoptions.h.
+struct UOption;
+typedef struct UOption UOption;
+
+#if !UCONFIG_NO_CONVERSION
+
+U_NAMESPACE_USE
+// Use the TESTCASE macro in subclasses of IntlTest. Define the
+// runIndexedTest method in this fashion:
+//
+//| void MyTest::runIndexedTest(int32_t index, UBool exec,
+//| const char* &name, char* /*par*/) {
+//| switch (index) {
+//| TESTCASE(0,TestSomething);
+//| TESTCASE(1,TestSomethingElse);
+//| TESTCASE(2,TestAnotherThing);
+//| default:
+//| name = "";
+//| return NULL;
+//| }
+//| }
+#if 0
+#define TESTCASE(id,test) \
+ case id: \
+ name = #test; \
+ if (exec) { \
+ fprintf(stdout,#test "---"); \
+ fprintf(stdout,"\n"); \
+ return test(); \
+ } \
+ break
+
+#endif
+#define TESTCASE(id,test) \
+ case id: \
+ name = #test; \
+ if (exec) { \
+ return test(); \
+ } \
+ break
+
+/**
+ * Subclasses of PerfTest will need to create subclasses of
+ * Function that define a call() method which contains the code to
+ * be timed. They then call setTestFunction() in their "Test..."
+ * method to establish this as the current test functor.
+ */
+class T_CTEST_EXPORT_API UPerfFunction {
+public:
+ /**
+ * Subclasses must implement this method to do the action to be
+ * measured.
+ */
+ virtual void call(UErrorCode* status)=0;
+
+ /**
+ * Subclasses must implement this method to return positive
+ * integer indicating the number of operations in a single
+ * call to this object's call() method.
+ */
+ virtual long getOperationsPerIteration()=0;
+ /**
+ * Subclasses should override this method to return either positive
+ * or negative integer indicating the number of events in a single
+ * call to this object's call() method, if applicable
+ * e.g: Number of breaks / iterations for break iterator
+ */
+ virtual long getEventsPerIteration(){
+ return -1;
+ }
+ /**
+ * destructor
+ */
+ virtual ~UPerfFunction() {}
+
+ /**
+ * Call call() n times in a tight loop and return the elapsed
+ * milliseconds. If n is small and call() is fast the return
+ * result may be zero. Small return values have limited
+ * meaningfulness, depending on the underlying CPU and OS.
+ */
+ virtual double time(int32_t n, UErrorCode* status) {
+ UTimer start, stop;
+ utimer_getTime(&start);
+ while (n-- > 0) {
+ call(status);
+ }
+ utimer_getTime(&stop);
+ return utimer_getDeltaSeconds(&start,&stop); // ms
+ }
+
+};
+
+
+class T_CTEST_EXPORT_API UPerfTest {
+public:
+ UBool run();
+ UBool runTest( char* name = NULL, char* par = NULL ); // not to be overidden
+
+ virtual void usage( void ) ;
+
+ virtual ~UPerfTest();
+
+ void setCaller( UPerfTest* callingTest ); // for internal use only
+
+ void setPath( char* path ); // for internal use only
+
+ ULine* getLines(UErrorCode& status);
+
+ const UChar* getBuffer(int32_t& len,UErrorCode& status);
+
+protected:
+ UPerfTest(int32_t argc, const char* argv[], UErrorCode& status);
+
+ UPerfTest(int32_t argc, const char* argv[],
+ UOption addOptions[], int32_t addOptionsCount,
+ const char *addUsage,
+ UErrorCode& status);
+
+ void init(UOption addOptions[], int32_t addOptionsCount,
+ UErrorCode& status);
+
+ virtual UPerfFunction* runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide !
+
+ virtual UBool runTestLoop( char* testname, char* par );
+
+ virtual UBool callTest( UPerfTest& testToBeCalled, char* par );
+
+ int32_t _argc;
+ const char** _argv;
+ const char * _addUsage;
+ char* resolvedFileName;
+ UCHARBUF* ucharBuf;
+ const char* encoding;
+ UBool uselen;
+ const char* fileName;
+ const char* sourceDir;
+ int32_t _remainingArgc;
+ ULine* lines;
+ int32_t numLines;
+ UBool line_mode;
+ UChar* buffer;
+ int32_t bufferLen;
+ UBool verbose;
+ UBool bulk_mode;
+ int32_t passes;
+ int32_t iterations;
+ int32_t time;
+ const char* locale;
+private:
+ UPerfTest* caller;
+ char* path; // specifies subtests
+
+// static members
+public:
+ static UPerfTest* gTest;
+ static const char gUsageString[];
+};
+
+#endif
+#endif
+
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/utimer.h b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/utimer.h
new file mode 100644
index 00000000000..e08deae0555
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/unicode/utimer.h
@@ -0,0 +1,277 @@
+/*
+************************************************************************
+* Copyright (c) 1997-2006, International Business Machines
+* Corporation and others. All Rights Reserved.
+************************************************************************
+*/
+
+#ifndef _UTIMER_H
+#define _UTIMER_H
+
+#include "unicode/utypes.h"
+
+#if defined(U_WINDOWS)
+# define VC_EXTRALEAN
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#else
+# include <time.h>
+# include <sys/time.h>
+# include <unistd.h>
+#endif
+
+/**
+ * This API provides functions for performing performance measurement
+ * There are 3 main usage scenarios.
+ * i) Loop until a threshold time is reached:
+ * Example:
+ * <code>
+ * typedef Params Params;
+ * struct Params{
+ * UChar* target;
+ * int32_t targetLen;
+ * const UChar* source;
+ * int32_t sourceLen;
+ * UNormalizationMode mode;
+ * }
+ * void NormFn( void* param){
+ * Params* parameters = ( Params*) param;
+ * UErrorCode error = U_ZERO_ERROR;
+ * unorm_normalize(parameters->source, parameters->sourceLen, parameters->mode, 0, parameters->target, parameters->targetLen, &error);
+ * if(U_FAILURE(error)){
+ * printf("Normalization failed\n");
+ * }
+ * }
+ *
+ * int main(){
+ * // time the normalization function
+ * double timeTaken = 0;
+ * Params param;
+ * param.source // set up the source buffer
+ * param.target // set up the target buffer
+ * .... so on ...
+ * UTimer timer;
+ * // time the loop for 10 seconds at least and find out the loop count and time taken
+ * timeTaken = utimer_loopUntilDone((double)10,(void*) param, NormFn, &loopCount);
+ * }
+ * </code>
+ *
+ * ii) Measure the time taken
+ * Example:
+ * <code>
+ * double perfNormalization(NormFn fn,const char* mode,Line* fileLines,int32_t loopCount){
+ * int line;
+ * int loops;
+ * UErrorCode error = U_ZERO_ERROR;
+ * UChar* dest=NULL;
+ * int32_t destCapacity=0;
+ * int len =-1;
+ * double elapsedTime = 0;
+ * int retVal=0;
+ *
+ * UChar arr[5000];
+ * dest=arr;
+ * destCapacity = 5000;
+ * UTimer start;
+ *
+ * // Initialize cache and ensure the data is loaded.
+ * // This loop checks for errors in Normalization. Once we pass the initialization
+ * // without errors we can safelly assume that there are no errors while timing the
+ * // funtion
+ * for (loops=0; loops<10; loops++) {
+ * for (line=0; line < gNumFileLines; line++) {
+ * if (opt_uselen) {
+ * len = fileLines[line].len;
+ * }
+ *
+ * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error);
+ * #if defined(U_WINDOWS)
+ * if(retVal==0 ){
+ * fprintf(stderr,"Normalization of string in Windows API failed for mode %s. ErrorNo: %i at line number %i\n",mode,GetLastError(),line);
+ * return 0;
+ * }
+ * #endif
+ * if(U_FAILURE(error)){
+ * fprintf(stderr,"Normalization of string in ICU API failed for mode %s. Error: %s at line number %i\n",mode,u_errorName(error),line);
+ * return 0;
+ * }
+ *
+ * }
+ * }
+ *
+ * //compute the time
+ *
+ * utimer_getTime(&start);
+ * for (loops=0; loops<loopCount; loops++) {
+ * for (line=0; line < gNumFileLines; line++) {
+ * if (opt_uselen) {
+ * len = fileLines[line].len;
+ * }
+ *
+ * retVal= fn(fileLines[line].name,len,dest,destCapacity,&error);
+ *
+ * }
+ * }
+ *
+ * return utimer_getElapsedSeconds(&start);
+ * }
+ * </code>
+ *
+ * iii) Let a higher level function do the calculation of confidence levels etc.
+ * Example:
+ * <code>
+ * void perf(UTimer* timer, UChar* source, int32_t sourceLen, UChar* target, int32_t targetLen, int32_t loopCount,UNormalizationMode mode, UErrorCode* error){
+ * int32_t loops;
+ * for (loops=0; loops<loopCount; loops++) {
+ * unorm_normalize(source,sourceLen,target, targetLen,mode,error);
+ * }
+ * utimer_getTime(timer);
+ * }
+ * void main(const char* argsc, int argv){
+ * // read the file and setup the data
+ * // set up options
+ * UTimer start,timer1, timer2, timer3, timer4;
+ * double NFDTimeTaken, NFCTimeTaken, FCDTimeTaken;
+ * switch(opt){
+ * case 0:
+ * utimer_getTime(start);
+ * perf(timer1, source,sourceLen, target, targetLen,loopCount,UNORM_NFD,&error);
+ * NFDTimeTaken = utimer_getDeltaSeconds(start,timer1);
+ * case 1:
+ * timer_getTime(start);
+ * perf(timer2,source,sourceLen,target,targetLen,loopCount,UNORM_NFC,&error);
+ * NFCTimeTaken = utimer_getDeltaSeconds(start,timer2);
+ * perf(timer3, source, sourceLen, target,targetLen, loopCount, UNORM_FCD,&error);
+ * // ........so on .............
+ * }
+ * // calculate confidence levels etc and print
+ *
+ * }
+ *
+ * </code>
+ *
+ */
+
+typedef struct UTimer UTimer;
+
+typedef void FuntionToBeTimed(void* param);
+
+
+#if defined(U_WINDOWS)
+
+ struct UTimer{
+ LARGE_INTEGER start;
+ LARGE_INTEGER placeHolder;
+ };
+
+ int uprv_initFrequency(UTimer* timer)
+ {
+ return QueryPerformanceFrequency(&timer->placeHolder);
+ }
+ void uprv_start(UTimer* timer)
+ {
+ QueryPerformanceCounter(&timer->start);
+ }
+ double uprv_delta(UTimer* timer1, UTimer* timer2){
+ return ((double)(timer2->start.QuadPart - timer1->start.QuadPart))/((double)timer1->placeHolder.QuadPart);
+ }
+ UBool uprv_compareFrequency(UTimer* timer1, UTimer* timer2){
+ return (timer1->placeHolder.QuadPart == timer2->placeHolder.QuadPart);
+ }
+
+#else
+
+ struct UTimer{
+ struct timeval start;
+ struct timeval placeHolder;
+ };
+
+ int32_t uprv_initFrequency(UTimer* /*timer*/)
+ {
+ return 0;
+ }
+ void uprv_start(UTimer* timer)
+ {
+ gettimeofday(&timer->start, 0);
+ }
+ double uprv_delta(UTimer* timer1, UTimer* timer2){
+ double t1, t2;
+
+ t1 = (double)timer1->start.tv_sec + (double)timer1->start.tv_usec/(1000*1000);
+ t2 = (double)timer2->start.tv_sec + (double)timer2->start.tv_usec/(1000*1000);
+ return (t2-t1);
+ }
+ UBool uprv_compareFrequency(UTimer* /*timer1*/, UTimer* /*timer2*/){
+ return TRUE;
+ }
+
+#endif
+/**
+ * Intializes the timer with the current time
+ *
+ * @param timer A pointer to UTimer struct to recieve the current time
+ */
+static U_INLINE void U_EXPORT2
+utimer_getTime(UTimer* timer){
+ uprv_initFrequency(timer);
+ uprv_start(timer);
+}
+
+/**
+ * Returns the difference in times between timer1 and timer2 by subtracting
+ * timer1's time from timer2's time
+ *
+ * @param timer1 A pointer to UTimer struct to be used as starting time
+ * @param timer2 A pointer to UTimer struct to be used as end time
+ * @return Time in seconds
+ */
+static U_INLINE double U_EXPORT2
+utimer_getDeltaSeconds(UTimer* timer1, UTimer* timer2){
+ if(uprv_compareFrequency(timer1,timer2)){
+ return uprv_delta(timer1,timer2);
+ }
+ /* got error return -1 */
+ return -1;
+}
+
+/**
+ * Returns the time elapsed from the starting time represented by the
+ * UTimer struct pointer passed
+ * @param timer A pointer to UTimer struct to be used as starting time
+ * @return Time elapsed in seconds
+ */
+static U_INLINE double U_EXPORT2
+utimer_getElapsedSeconds(UTimer* timer){
+ UTimer temp;
+ utimer_getTime(&temp);
+ return uprv_delta(timer,&temp);
+}
+
+/**
+ * Executes the function pointed to for a given time and returns exact time
+ * taken and number of iterations of the loop
+ * @param thresholTimeVal
+ * @param loopCount output param to recieve the number of iterations
+ * @param fn The funtion to be executed
+ * @param param Parameters to be passed to the fn
+ * @return the time elapsed in seconds
+ */
+static U_INLINE double U_EXPORT2
+utimer_loopUntilDone(double thresholdTimeVal,
+ int32_t* loopCount,
+ FuntionToBeTimed fn,
+ void* param){
+ UTimer timer;
+ double currentVal=0;
+ *loopCount = 0;
+ utimer_getTime(&timer);
+ for(;currentVal<thresholdTimeVal;){
+ fn(param);
+ currentVal = utimer_getElapsedSeconds(&timer);
+ *loopCount++;
+ }
+ return currentVal;
+}
+
+#endif
+
diff --git a/Build/source/libs/icu/icu-xetex/tools/ctestfw/uperf.cpp b/Build/source/libs/icu/icu-xetex/tools/ctestfw/uperf.cpp
new file mode 100644
index 00000000000..5b2dbe667b0
--- /dev/null
+++ b/Build/source/libs/icu/icu-xetex/tools/ctestfw/uperf.cpp
@@ -0,0 +1,526 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 2002-2007, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+
+/* z/OS needs this definition for timeval */
+#if !defined(_XOPEN_SOURCE_EXTENDED)
+#define _XOPEN_SOURCE_EXTENDED 1
+#endif
+
+#include "unicode/uperf.h"
+#include "uoptions.h"
+#include "cmemory.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#if !UCONFIG_NO_CONVERSION
+static const char delim = '/';
+static int32_t execCount = 0;
+UPerfTest* UPerfTest::gTest = NULL;
+static const int MAXLINES = 40000;
+const char UPerfTest::gUsageString[] =
+ "Usage: %s [OPTIONS] [FILES]\n"
+ "\tReads the input file and prints out time taken in seconds\n"
+ "Options:\n"
+ "\t-h or -? or --help this usage text\n"
+ "\t-v or --verbose print extra information when processing files\n"
+ "\t-s or --sourcedir source directory for files followed by path\n"
+ "\t followed by path\n"
+ "\t-e or --encoding encoding of source files\n"
+ "\t-u or --uselen perform timing analysis on non-null terminated buffer using length\n"
+ "\t-f or --file-name file to be used as input data\n"
+ "\t-p or --passes Number of passes to be performed. Requires Numeric argument.\n"
+ "\t Cannot be used with --time\n"
+ "\t-i or --iterations Number of iterations to be performed. Requires Numeric argument\n"
+ "\t-t or --time Threshold time for looping until in seconds. Requires Numeric argument.\n"
+ "\t Cannot be used with --iterations\n"
+ "\t-l or --line-mode The data file should be processed in line mode\n"
+ "\t-b or --bulk-mode The data file should be processed in file based.\n"
+ "\t Cannot be used with --line-mode\n"
+ "\t-L or --locale Locale for the test\n";
+
+enum
+{
+ HELP1,
+ HELP2,
+ VERBOSE,
+ SOURCEDIR,
+ ENCODING,
+ USELEN,
+ FILE_NAME,
+ PASSES,
+ ITERATIONS,
+ TIME,
+ LINE_MODE,
+ BULK_MODE,
+ LOCALE,
+ OPTIONS_COUNT
+};
+
+
+static UOption options[OPTIONS_COUNT+20]={
+ UOPTION_HELP_H,
+ UOPTION_HELP_QUESTION_MARK,
+ UOPTION_VERBOSE,
+ UOPTION_SOURCEDIR,
+ UOPTION_ENCODING,
+ UOPTION_DEF( "uselen", 'u', UOPT_NO_ARG),
+ UOPTION_DEF( "file-name", 'f', UOPT_REQUIRES_ARG),
+ UOPTION_DEF( "passes", 'p', UOPT_REQUIRES_ARG),
+ UOPTION_DEF( "iterations", 'i', UOPT_REQUIRES_ARG),
+ UOPTION_DEF( "time", 't', UOPT_REQUIRES_ARG),
+ UOPTION_DEF( "line-mode", 'l', UOPT_NO_ARG),
+ UOPTION_DEF( "bulk-mode", 'b', UOPT_NO_ARG),
+ UOPTION_DEF( "locale", 'L', UOPT_REQUIRES_ARG)
+};
+
+UPerfTest::UPerfTest(int32_t argc, const char* argv[], UErrorCode& status)
+ : _argc(argc), _argv(argv), _addUsage(NULL),
+ ucharBuf(NULL), encoding(""),
+ uselen(FALSE),
+ fileName(NULL), sourceDir("."),
+ lines(NULL), numLines(0), line_mode(TRUE),
+ buffer(NULL), bufferLen(0),
+ verbose(FALSE), bulk_mode(FALSE),
+ passes(1), iterations(0), time(0),
+ locale(NULL) {
+ init(NULL, 0, status);
+}
+
+UPerfTest::UPerfTest(int32_t argc, const char* argv[],
+ UOption addOptions[], int32_t addOptionsCount,
+ const char *addUsage,
+ UErrorCode& status)
+ : _argc(argc), _argv(argv), _addUsage(addUsage),
+ ucharBuf(NULL), encoding(""),
+ uselen(FALSE),
+ fileName(NULL), sourceDir("."),
+ lines(NULL), numLines(0), line_mode(TRUE),
+ buffer(NULL), bufferLen(0),
+ verbose(FALSE), bulk_mode(FALSE),
+ passes(1), iterations(0), time(0),
+ locale(NULL) {
+ init(addOptions, addOptionsCount, status);
+}
+
+void UPerfTest::init(UOption addOptions[], int32_t addOptionsCount,
+ UErrorCode& status) {
+ //initialize the argument list
+ U_MAIN_INIT_ARGS(_argc, _argv);
+
+ // add specific options
+ int32_t optionsCount = OPTIONS_COUNT;
+ if (addOptionsCount > 0) {
+ memcpy(options+optionsCount, addOptions, addOptionsCount*sizeof(UOption));
+ optionsCount += addOptionsCount;
+ }
+
+ //parse the arguments
+ _remainingArgc = u_parseArgs(_argc, (char**)_argv, optionsCount, options);
+
+ // copy back values for additional options
+ if (addOptionsCount > 0) {
+ memcpy(addOptions, options+OPTIONS_COUNT, addOptionsCount*sizeof(UOption));
+ }
+
+ // Now setup the arguments
+ if(_argc==1 || options[HELP1].doesOccur || options[HELP2].doesOccur) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+
+ if(options[VERBOSE].doesOccur) {
+ verbose = TRUE;
+ }
+
+ if(options[SOURCEDIR].doesOccur) {
+ sourceDir = options[SOURCEDIR].value;
+ }
+
+ if(options[ENCODING].doesOccur) {
+ encoding = options[ENCODING].value;
+ }
+
+ if(options[USELEN].doesOccur) {
+ uselen = TRUE;
+ }
+
+ if(options[FILE_NAME].doesOccur){
+ fileName = options[FILE_NAME].value;
+ }
+
+ if(options[PASSES].doesOccur) {
+ passes = atoi(options[PASSES].value);
+ }
+ if(options[ITERATIONS].doesOccur) {
+ iterations = atoi(options[ITERATIONS].value);
+ if(options[TIME].doesOccur) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+ } else if(options[TIME].doesOccur) {
+ time = atoi(options[TIME].value);
+ } else {
+ iterations = 1000; // some default
+ }
+
+ if(options[LINE_MODE].doesOccur) {
+ line_mode = TRUE;
+ bulk_mode = FALSE;
+ }
+
+ if(options[BULK_MODE].doesOccur) {
+ bulk_mode = TRUE;
+ line_mode = FALSE;
+ }
+
+ if(options[LOCALE].doesOccur) {
+ locale = options[LOCALE].value;
+ }
+
+ int32_t len = 0;
+ resolvedFileName = NULL;
+ if(fileName!=NULL){
+ //pre-flight
+ ucbuf_resolveFileName(sourceDir, fileName, NULL, &len, &status);
+ resolvedFileName = (char*) uprv_malloc(len);
+ if(resolvedFileName==NULL){
+ status= U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ if(status == U_BUFFER_OVERFLOW_ERROR){
+ status = U_ZERO_ERROR;
+ }
+ ucbuf_resolveFileName(sourceDir, fileName, resolvedFileName, &len, &status);
+ ucharBuf = ucbuf_open(resolvedFileName,&encoding,TRUE,FALSE,&status);
+
+ if(U_FAILURE(status)){
+ printf("Could not open the input file %s. Error: %s\n", fileName, u_errorName(status));
+ return;
+ }
+ }
+}
+
+ULine* UPerfTest::getLines(UErrorCode& status){
+ lines = new ULine[MAXLINES];
+ int maxLines = MAXLINES;
+ numLines=0;
+ const UChar* line=NULL;
+ int32_t len =0;
+ for (;;) {
+ line = ucbuf_readline(ucharBuf,&len,&status);
+ if(line == NULL || U_FAILURE(status)){
+ break;
+ }
+ lines[numLines].name = new UChar[len];
+ lines[numLines].len = len;
+ memcpy(lines[numLines].name, line, len * U_SIZEOF_UCHAR);
+
+ numLines++;
+ len = 0;
+ if (numLines >= maxLines) {
+ maxLines += MAXLINES;
+ ULine *newLines = new ULine[maxLines];
+ if(newLines == NULL) {
+ fprintf(stderr, "Out of memory reading line %d.\n", (int)numLines);
+ status= U_MEMORY_ALLOCATION_ERROR;
+ delete []lines;
+ return NULL;
+ }
+
+ memcpy(newLines, lines, numLines*sizeof(ULine));
+ delete []lines;
+ lines = newLines;
+ }
+ }
+ return lines;
+}
+const UChar* UPerfTest::getBuffer(int32_t& len, UErrorCode& status){
+ if (U_FAILURE(status)) {
+ return NULL;
+ }
+ len = ucbuf_size(ucharBuf);
+ buffer = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * (len+1));
+ u_strncpy(buffer,ucbuf_getBuffer(ucharBuf,&bufferLen,&status),len);
+ buffer[len]=0;
+ len = bufferLen;
+ return buffer;
+}
+UBool UPerfTest::run(){
+ if(_remainingArgc==1){
+ // Testing all methods
+ return runTest();
+ }
+ UBool res=FALSE;
+ // Test only the specified fucntion
+ for (int i = 1; i < _remainingArgc; ++i) {
+ if (_argv[i][0] != '-') {
+ char* name = (char*) _argv[i];
+ if(verbose==TRUE){
+ //fprintf(stdout, "\n=== Handling test: %s: ===\n", name);
+ //fprintf(stdout, "\n%s:\n", name);
+ }
+ char* parameter = strchr( name, '@' );
+ if (parameter) {
+ *parameter = 0;
+ parameter += 1;
+ }
+ execCount = 0;
+ res = runTest( name, parameter );
+ if (!res || (execCount <= 0)) {
+ fprintf(stdout, "\n---ERROR: Test doesn't exist: %s!\n", name);
+ return FALSE;
+ }
+ }
+ }
+ return res;
+}
+UBool UPerfTest::runTest(char* name, char* par ){
+ UBool rval;
+ char* pos = NULL;
+
+ if (name)
+ pos = strchr( name, delim ); // check if name contains path (by looking for '/')
+ if (pos) {
+ path = pos+1; // store subpath for calling subtest
+ *pos = 0; // split into two strings
+ }else{
+ path = NULL;
+ }
+
+ if (!name || (name[0] == 0) || (strcmp(name, "*") == 0)) {
+ rval = runTestLoop( NULL, NULL );
+
+ }else if (strcmp( name, "LIST" ) == 0) {
+ this->usage();
+ rval = TRUE;
+
+ }else{
+ rval = runTestLoop( name, par );
+ }
+
+ if (pos)
+ *pos = delim; // restore original value at pos
+ return rval;
+}
+
+
+void UPerfTest::setPath( char* pathVal )
+{
+ this->path = pathVal;
+}
+
+// call individual tests, to be overriden to call implementations
+UPerfFunction* UPerfTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* par )
+{
+ // to be overriden by a method like:
+ /*
+ switch (index) {
+ case 0: name = "First Test"; if (exec) FirstTest( par ); break;
+ case 1: name = "Second Test"; if (exec) SecondTest( par ); break;
+ default: name = ""; break;
+ }
+ */
+ fprintf(stderr,"*** runIndexedTest needs to be overriden! ***");
+ name = ""; exec = exec; index = index; par = par;
+ return NULL;
+}
+
+
+UBool UPerfTest::runTestLoop( char* testname, char* par )
+{
+ int32_t index = 0;
+ const char* name;
+ UBool run_this_test;
+ UBool rval = FALSE;
+ UErrorCode status = U_ZERO_ERROR;
+ UPerfTest* saveTest = gTest;
+ gTest = this;
+ int32_t loops = 0;
+ double t=0;
+ int32_t n = 1;
+ long ops;
+ do {
+ this->runIndexedTest( index, FALSE, name );
+ if (!name || (name[0] == 0))
+ break;
+ if (!testname) {
+ run_this_test = TRUE;
+ }else{
+ run_this_test = (UBool) (strcmp( name, testname ) == 0);
+ }
+ if (run_this_test) {
+ UPerfFunction* testFunction = this->runIndexedTest( index, TRUE, name, par );
+ execCount++;
+ rval=TRUE;
+ if(testFunction==NULL){
+ fprintf(stderr,"%s function returned NULL", name);
+ return FALSE;
+ }
+ ops = testFunction->getOperationsPerIteration();
+ if (ops < 1) {
+ fprintf(stderr, "%s returned an illegal operations/iteration()\n", name);
+ return FALSE;
+ }
+ if(iterations == 0) {
+ n = time;
+ // Run for specified duration in seconds
+ if(verbose==TRUE){
+ fprintf(stdout,"= %s calibrating %i seconds \n", name, (int)n);
+ }
+
+ //n *= 1000; // s => ms
+ //System.out.println("# " + meth.getName() + " " + n + " sec");
+ int32_t failsafe = 1; // last resort for very fast methods
+ t = 0;
+ while (t < (int)(n * 0.9)) { // 90% is close enough
+ if (loops == 0 || t == 0) {
+ loops = failsafe;
+ failsafe *= 10;
+ } else {
+ //System.out.println("# " + meth.getName() + " x " + loops + " = " + t);
+ loops = (int)((double)n / t * loops + 0.5);
+ if (loops == 0) {
+ fprintf(stderr,"Unable to converge on desired duration");
+ return FALSE;
+ }
+ }
+ //System.out.println("# " + meth.getName() + " x " + loops);
+ t = testFunction->time(loops,&status);
+ if(U_FAILURE(status)){
+ printf("Performance test failed with error: %s \n", u_errorName(status));
+ break;
+ }
+ }
+ } else {
+ loops = iterations;
+ }
+
+ double min_t=1000000.0, sum_t=0.0;
+ long events = -1;
+
+ for(int32_t ps =0; ps < passes; ps++){
+ fprintf(stdout,"= %s begin " ,name);
+ if(verbose==TRUE){
+ if(iterations > 0) {
+ fprintf(stdout, "%i\n", (int)loops);
+ } else {
+ fprintf(stdout, "%i\n", (int)n);
+ }
+ } else {
+ fprintf(stdout, "\n");
+ }
+ t = testFunction->time(loops, &status);
+ if(U_FAILURE(status)){
+ printf("Performance test failed with error: %s \n", u_errorName(status));
+ break;
+ }
+ sum_t+=t;
+ if(t<min_t) {
+ min_t=t;
+ }
+ events = testFunction->getEventsPerIteration();
+ //print info only in verbose mode
+ if(verbose==TRUE){
+ if(events == -1){
+ fprintf(stdout, "= %s end: %f loops: %i operations: %li \n", name, t, (int)loops, ops);
+ }else{
+ fprintf(stdout, "= %s end: %f loops: %i operations: %li events: %li\n", name, t, (int)loops, ops, events);
+ }
+ }else{
+ if(events == -1){
+ fprintf(stdout,"= %s end %f %i %li\n", name, t, (int)loops, ops);
+ }else{
+ fprintf(stdout,"= %s end %f %i %li %li\n", name, t, (int)loops, ops, events);
+ }
+ }
+ }
+ if(verbose && U_SUCCESS(status)) {
+ double avg_t = sum_t/passes;
+ if (loops == 0 || ops == 0) {
+ fprintf(stderr, "%s did not run\n", name);
+ }
+ else if(events == -1) {
+ fprintf(stdout, "%%= %s avg: %.4g loops: %i avg/op: %.4g ns\n",
+ name, avg_t, (int)loops, (avg_t*1E9)/(loops*ops));
+ fprintf(stdout, "_= %s min: %.4g loops: %i min/op: %.4g ns\n",
+ name, min_t, (int)loops, (min_t*1E9)/(loops*ops));
+ }
+ else {
+ fprintf(stdout, "%%= %s avg: %.4g loops: %i avg/op: %.4g ns avg/event: %.4g ns\n",
+ name, avg_t, (int)loops, (avg_t*1E9)/(loops*ops), (avg_t*1E9)/(loops*events));
+ fprintf(stdout, "_= %s min: %.4g loops: %i min/op: %.4g ns min/event: %.4g ns\n",
+ name, min_t, (int)loops, (min_t*1E9)/(loops*ops), (min_t*1E9)/(loops*events));
+ }
+ }
+ delete testFunction;
+ }
+ index++;
+ }while(name);
+
+ gTest = saveTest;
+ return rval;
+}
+
+/**
+* Print a usage message for this test class.
+*/
+void UPerfTest::usage( void )
+{
+ puts(gUsageString);
+ if (_addUsage != NULL) {
+ puts(_addUsage);
+ }
+
+ UBool save_verbose = verbose;
+ verbose = TRUE;
+ fprintf(stdout,"Test names:\n");
+ fprintf(stdout,"-----------\n");
+
+ int32_t index = 0;
+ const char* name = NULL;
+ do{
+ this->runIndexedTest( index, FALSE, name );
+ if (!name)
+ break;
+ fprintf(stdout,name);
+ fprintf(stdout,"\n");
+ index++;
+ }while (name && (name[0] != 0));
+ verbose = save_verbose;
+}
+
+
+
+
+void UPerfTest::setCaller( UPerfTest* callingTest )
+{
+ caller = callingTest;
+ if (caller) {
+ verbose = caller->verbose;
+ }
+}
+
+UBool UPerfTest::callTest( UPerfTest& testToBeCalled, char* par )
+{
+ execCount--; // correct a previously assumed test-exec, as this only calls a subtest
+ testToBeCalled.setCaller( this );
+ return testToBeCalled.runTest( path, par );
+}
+
+UPerfTest::~UPerfTest(){
+ if(lines!=NULL){
+ delete[] lines;
+ }
+ if(buffer!=NULL){
+ uprv_free(buffer);
+ }
+ if(resolvedFileName!=NULL){
+ uprv_free(resolvedFileName);
+ }
+ ucbuf_close(ucharBuf);
+}
+
+#endif