/********************************************************************
 * COPYRIGHT:
 * Copyright (C) 2002-2003 IBM, Inc.   All Rights Reserved.
 *
 ********************************************************************/
/*****************************************************************************
* File charperf.cpp
*
* Modification History:
* Name                     Description
* Syn Wee Quek             First Version
******************************************************************************
*/

/** 
 * This program tests character properties performance.
 * APIs tested: 
 * ICU4C 
 * Windows
 */

#include "charperf.h"
#include "uoptions.h"

UOption options[] = {
						UOPTION_DEF("min", 'n', UOPT_REQUIRES_ARG),
						UOPTION_DEF("min", 'x', UOPT_REQUIRES_ARG),
					};
int MIN_OPTION_ = 0;
int MAX_OPTION_ = 1;

int main(int argc, const char *argv[])
{
    UErrorCode status = U_ZERO_ERROR;
    CharPerformanceTest test(argc, argv, status);
	if (U_FAILURE(status)){
        return status;
    }
    if (test.run() == FALSE){
        fprintf(stderr, "FAILED: Tests could not be run please check the "
			            "arguments.\n");
        return -1;
    }
    return 0;
}

CharPerformanceTest::CharPerformanceTest(int32_t argc, const char *argv[],
										 UErrorCode &status)
										: UPerfTest(argc, argv, status)
{
	if (status== U_ILLEGAL_ARGUMENT_ERROR){
       fprintf(stderr,gUsageString, "charperf");
       return;
    }
    if (U_FAILURE(status)){
        fprintf(stderr, "FAILED to create UPerfTest object. Error: %s\n", 
			    u_errorName(status));
        return;
    }

	if (_remainingArgc < 0) {
		// that means there are some -names not matched in the super class
		// first tag is always skipped in u_parseArgs
		int size = - _remainingArgc;
		argv += argc - size;
		argc = size;
		_remainingArgc = u_parseArgs(argc, (char**)argv, 
			        (int32_t)(sizeof(options)/sizeof(options[0])), options);
	}
	MIN_ = 0;
    if (sizeof(wchar_t) > 2)  {
        // for stdlibs like glibc that supports 32 bits wchar
        // we test for the whole unicode character set by default
        MAX_ = 0x10ffff;
    }
    else {
        MAX_ = 0xffff;
    }
    printf("MAX_ size will be 0x%x\n", MAX_);
	if (options[MIN_OPTION_].doesOccur) {
		MIN_ = atoi(options[MIN_OPTION_].value);
	}
	if (options[MAX_OPTION_].doesOccur) {
		MAX_ = atoi(options[MAX_OPTION_].value);
	}
}

CharPerformanceTest::~CharPerformanceTest()
{
}

UPerfFunction* CharPerformanceTest::runIndexedTest(int32_t index, UBool exec,
												   const char *&name, 
												   char* par) 
{
    switch (index) {
        TESTCASE(0, TestIsAlpha);
		TESTCASE(1, TestIsUpper);
		TESTCASE(2, TestIsLower);
		TESTCASE(3, TestIsDigit);
		TESTCASE(4, TestIsSpace);
		TESTCASE(5, TestIsAlphaNumeric);
		TESTCASE(6, TestIsPrint);
		TESTCASE(7, TestIsControl);
		TESTCASE(8, TestToLower);
		TESTCASE(9, TestToUpper);
		TESTCASE(10, TestIsWhiteSpace);
		TESTCASE(11, TestStdLibIsAlpha);
		TESTCASE(12, TestStdLibIsUpper);
		TESTCASE(13, TestStdLibIsLower);
		TESTCASE(14, TestStdLibIsDigit);
		TESTCASE(15, TestStdLibIsSpace);
		TESTCASE(16, TestStdLibIsAlphaNumeric);
		TESTCASE(17, TestStdLibIsPrint);
		TESTCASE(18, TestStdLibIsControl);
		TESTCASE(19, TestStdLibToLower);
		TESTCASE(20, TestStdLibToUpper);
		TESTCASE(21, TestStdLibIsWhiteSpace);
        default: 
            name = ""; 
            return NULL;
    }
    return NULL;
}

UPerfFunction* CharPerformanceTest::TestIsAlpha()
{
	return new CharPerfFunction(isAlpha, MIN_, MAX_);
}

UPerfFunction* CharPerformanceTest::TestIsUpper()
{
	return new CharPerfFunction(isUpper, MIN_, MAX_);
}

UPerfFunction* CharPerformanceTest::TestIsLower()
{
	return new CharPerfFunction(isLower, MIN_, MAX_);
}

UPerfFunction* CharPerformanceTest::TestIsDigit()
{
	return new CharPerfFunction(isDigit, MIN_, MAX_);
}

UPerfFunction* CharPerformanceTest::TestIsSpace()
{
	return new CharPerfFunction(isSpace, MIN_, MAX_);
}

UPerfFunction* CharPerformanceTest::TestIsAlphaNumeric()
{
	return new CharPerfFunction(isAlphaNumeric, MIN_, MAX_);
}

/**
 * This test may be different since c lib has a type PUNCT and it is printable.
 * iswgraph is not used for testing since it is a subset of iswprint with the
 * exception of returning true for white spaces. no match found in icu4c.
 */
UPerfFunction* CharPerformanceTest::TestIsPrint()
{
	return new CharPerfFunction(isPrint, MIN_, MAX_);
}

UPerfFunction* CharPerformanceTest::TestIsControl()
{
	return new CharPerfFunction(isControl, MIN_, MAX_);
}

UPerfFunction* CharPerformanceTest::TestToLower()
{
	return new CharPerfFunction(toLower, MIN_, MAX_);
}

UPerfFunction* CharPerformanceTest::TestToUpper()
{
	return new CharPerfFunction(toUpper, MIN_, MAX_);
}

UPerfFunction* CharPerformanceTest::TestIsWhiteSpace()
{
	return new CharPerfFunction(isWhiteSpace, MIN_, MAX_);
}

UPerfFunction* CharPerformanceTest::TestStdLibIsAlpha()
{
	return new StdLibCharPerfFunction(StdLibIsAlpha, (wchar_t)MIN_, 
		                              (wchar_t)MAX_);
}

UPerfFunction* CharPerformanceTest::TestStdLibIsUpper()
{
	return new StdLibCharPerfFunction(StdLibIsUpper, (wchar_t)MIN_, 
		                              (wchar_t)MAX_);
}

UPerfFunction* CharPerformanceTest::TestStdLibIsLower()
{
	return new StdLibCharPerfFunction(StdLibIsLower, (wchar_t)MIN_, 
		                              (wchar_t)MAX_);
}

UPerfFunction* CharPerformanceTest::TestStdLibIsDigit()
{
	return new StdLibCharPerfFunction(StdLibIsDigit, (wchar_t)MIN_, 
		                              (wchar_t)MAX_);
}

UPerfFunction* CharPerformanceTest::TestStdLibIsSpace()
{
	return new StdLibCharPerfFunction(StdLibIsSpace, (wchar_t)MIN_, 
		                              (wchar_t)MAX_);
}

UPerfFunction* CharPerformanceTest::TestStdLibIsAlphaNumeric()
{
	return new StdLibCharPerfFunction(StdLibIsAlphaNumeric, (wchar_t)MIN_, 
		                              (wchar_t)MAX_);
}

/**
 * This test may be different since c lib has a type PUNCT and it is printable.
 * iswgraph is not used for testing since it is a subset of iswprint with the
 * exception of returning true for white spaces. no match found in icu4c.
 */
UPerfFunction* CharPerformanceTest::TestStdLibIsPrint()
{
	return new StdLibCharPerfFunction(StdLibIsPrint, (wchar_t)MIN_, 
		                              (wchar_t)MAX_);
}

UPerfFunction* CharPerformanceTest::TestStdLibIsControl()
{
	return new StdLibCharPerfFunction(StdLibIsControl, (wchar_t)MIN_, 
		                              (wchar_t)MAX_);
}

UPerfFunction* CharPerformanceTest::TestStdLibToLower()
{
	return new StdLibCharPerfFunction(StdLibToLower, (wchar_t)MIN_, 
		                              (wchar_t)MAX_);
}

UPerfFunction* CharPerformanceTest::TestStdLibToUpper()
{
	return new StdLibCharPerfFunction(StdLibToUpper, (wchar_t)MIN_, 
		                              (wchar_t)MAX_);
}

UPerfFunction* CharPerformanceTest::TestStdLibIsWhiteSpace()
{
	return new StdLibCharPerfFunction(StdLibIsWhiteSpace, (wchar_t)MIN_, 
		                              (wchar_t)MAX_);
}
