diff options
author | Peter Breitenlohner <peb@mppmu.mpg.de> | 2009-04-20 18:13:48 +0000 |
---|---|---|
committer | Peter Breitenlohner <peb@mppmu.mpg.de> | 2009-04-20 18:13:48 +0000 |
commit | e5786f530f9555469c01435f86039b06aa53feba (patch) | |
tree | c868e8d32282422d7d445b729db95c3fcdafb6d0 /Build/source/libs/icu/icu-xetex/tools/ctestfw | |
parent | ebaa1768b43c8606d923d2e861b5286b74207b3e (diff) |
new build system: build icu libs and xetex plus misc updates
git-svn-id: svn://tug.org/texlive/trunk@12759 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/icu/icu-xetex/tools/ctestfw')
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 |