X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..249c4c5ea9376c24572daf9c2effa7484a282f14:/icuSources/test/cintltst/putiltst.c?ds=sidebyside diff --git a/icuSources/test/cintltst/putiltst.c b/icuSources/test/cintltst/putiltst.c index b15e502b..1c3e0730 100644 --- a/icuSources/test/cintltst/putiltst.c +++ b/icuSources/test/cintltst/putiltst.c @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: - * Copyright (c) 1998-2003, International Business Machines Corporation and + * Copyright (c) 1998-2016, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ /* @@ -18,7 +20,30 @@ #include "cmemory.h" #include "unicode/putil.h" #include "unicode/ustring.h" +#include "unicode/icudataver.h" #include "cstring.h" +#include "putilimp.h" +#include "toolutil.h" +#include "uinvchar.h" +#include + +/* See the comments on U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC. */ +static void TestSignedRightShiftIsArithmetic(void) { + int32_t x=0xfff5fff3; + int32_t m=-1; + int32_t x4=x>>4; + int32_t m1=m>>1; + UBool signedRightShiftIsArithmetic= x4==0xffff5fff && m1==-1; + if(signedRightShiftIsArithmetic==U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC) { + log_info("signed right shift is Arithmetic Shift Right: %d\n", + signedRightShiftIsArithmetic); + } else { + log_err("error: unexpected signed right shift is Arithmetic Shift Right: %d\n" + " You need to change the value of U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC " + "for your platform.\n", + signedRightShiftIsArithmetic); + } +} static UBool compareWithNAN(double x, double y); static void doAssert(double expect, double got, const char *message); @@ -27,8 +52,6 @@ static void TestPUtilAPI(void){ double n1=0.0, y1=0.0, expn1, expy1; double value1 = 0.021; - UVersionInfo versionArray = {0x01, 0x00, 0x02, 0x02}; - char versionString[17]; /* xxx.xxx.xxx.xxx\0 */ char *str=0; UBool isTrue=FALSE; @@ -40,7 +63,7 @@ static void TestPUtilAPI(void){ log_err("Error in uprv_modf. Expected IntegralValue=%f, Got=%f, \n Expected FractionalValue=%f, Got=%f\n", expn1, n1, expy1, y1); } - if(VERBOSITY){ + if(getTestOption(VERBOSITY_OPTION)){ log_verbose("[float] x = %f n = %f y = %f\n", value1, n1, y1); } log_verbose("Testing the API uprv_fmod()\n"); @@ -89,13 +112,6 @@ static void TestPUtilAPI(void){ log_verbose("Testing the API uprv_pow10()\n"); doAssert(uprv_pow10(4), 10000, "uprv_pow10(4) failed."); - log_verbose("Testing the API uprv_log10()\n"); - doAssert(uprv_log10(3456), 3, "uprv_log10(3456) failed."); -#ifdef OS390 - doAssert(uprv_log10(1.0e55), 55, "uprv_log10(1.0e55) failed."); -#else - doAssert(uprv_log10(1.0e300), 300, "uprv_log10(1.0e300) failed."); -#endif log_verbose("Testing the API uprv_isNegativeInfinity()\n"); isTrue=uprv_isNegativeInfinity(uprv_getInfinity() * -1); if(isTrue != TRUE){ @@ -112,6 +128,21 @@ static void TestPUtilAPI(void){ log_err("ERROR: uprv_isInfinite failed.\n"); } + log_verbose("Testing the APIs uprv_add32_overflow and uprv_mul32_overflow\n"); + int32_t overflow_result; + doAssert(FALSE, uprv_add32_overflow(INT32_MAX - 2, 1, &overflow_result), "should not overflow"); + doAssert(INT32_MAX - 1, overflow_result, "should equal INT32_MAX - 1"); + doAssert(FALSE, uprv_add32_overflow(INT32_MAX - 2, 2, &overflow_result), "should not overflow"); + doAssert(INT32_MAX, overflow_result, "should equal exactly INT32_MAX"); + doAssert(TRUE, uprv_add32_overflow(INT32_MAX - 2, 3, &overflow_result), "should overflow"); + doAssert(FALSE, uprv_mul32_overflow(INT32_MAX / 5, 4, &overflow_result), "should not overflow"); + doAssert(INT32_MAX / 5 * 4, overflow_result, "should equal INT32_MAX / 5 * 4"); + doAssert(TRUE, uprv_mul32_overflow(INT32_MAX / 5, 6, &overflow_result), "should overflow"); + // Test on negative numbers: + doAssert(FALSE, uprv_add32_overflow(-3, -2, &overflow_result), "should not overflow"); + doAssert(-5, overflow_result, "should equal -5"); + +#if 0 log_verbose("Testing the API uprv_digitsAfterDecimal()....\n"); doAssert(uprv_digitsAfterDecimal(value1), 3, "uprv_digitsAfterDecimal() failed."); doAssert(uprv_digitsAfterDecimal(1.2345E2), 2, "uprv_digitsAfterDecimal(1.2345E2) failed."); @@ -122,7 +153,80 @@ static void TestPUtilAPI(void){ doAssert(uprv_digitsAfterDecimal(-0.021), 3, "uprv_digitsAfterDecimal(-0.021) failed."); doAssert(uprv_digitsAfterDecimal(23.0), 0, "uprv_digitsAfterDecimal(23.0) failed."); doAssert(uprv_digitsAfterDecimal(0.022223333321), 9, "uprv_digitsAfterDecimal(0.022223333321) failed."); +#endif + + log_verbose("Testing the API u_errorName()...\n"); + str=(char*)u_errorName((UErrorCode)0); + if(strcmp(str, "U_ZERO_ERROR") != 0){ + log_err("ERROR: u_getVersion() failed. Expected: U_ZERO_ERROR Got=%s\n", str); + } + log_verbose("Testing the API u_errorName()...\n"); + str=(char*)u_errorName((UErrorCode)-127); + if(strcmp(str, "U_USING_DEFAULT_WARNING") != 0){ + log_err("ERROR: u_getVersion() failed. Expected: U_USING_DEFAULT_WARNING Got=%s\n", str); + } + log_verbose("Testing the API u_errorName().. with BOGUS ERRORCODE...\n"); + str=(char*)u_errorName((UErrorCode)200); + if(strcmp(str, "[BOGUS UErrorCode]") != 0){ + log_err("ERROR: u_getVersion() failed. Expected: [BOGUS UErrorCode] Got=%s\n", str); + } + + { + const char* dataDirectory; + int32_t dataDirectoryLen; + UChar *udataDir=0; + UChar temp[100]; + char *charvalue=0; + log_verbose("Testing chars to UChars\n"); + + /* This cannot really work on a japanese system. u_uastrcpy will have different results than */ + /* u_charsToUChars when there is a backslash in the string! */ + /*dataDirectory=u_getDataDirectory();*/ + + dataDirectory="directory1"; /*no backslashes*/ + dataDirectoryLen=(int32_t)strlen(dataDirectory); + udataDir=(UChar*)malloc(sizeof(UChar) * (dataDirectoryLen + 1)); + u_charsToUChars(dataDirectory, udataDir, (dataDirectoryLen + 1)); + u_uastrcpy(temp, dataDirectory); + + if(u_strcmp(temp, udataDir) != 0){ + log_err("ERROR: u_charsToUChars failed. Expected %s, Got %s\n", austrdup(temp), austrdup(udataDir)); + } + log_verbose("Testing UChars to chars\n"); + charvalue=(char*)malloc(sizeof(char) * (u_strlen(udataDir) + 1)); + + u_UCharsToChars(udataDir, charvalue, (u_strlen(udataDir)+1)); + if(strcmp(charvalue, dataDirectory) != 0){ + log_err("ERROR: u_UCharsToChars failed. Expected %s, Got %s\n", charvalue, dataDirectory); + } + free(charvalue); + free(udataDir); + } + + log_verbose("Testing uprv_timezone()....\n"); + { + int32_t tzoffset = uprv_timezone(); + log_verbose("Value returned from uprv_timezone = %d\n", tzoffset); + if (tzoffset != 28800) { + log_verbose("***** WARNING: If testing in the PST timezone, t_timezone should return 28800! *****"); + } + if ((tzoffset % 1800 != 0)) { + log_info("Note: t_timezone offset of %ld (for %s : %s) is not a multiple of 30min.", tzoffset, uprv_tzname(0), uprv_tzname(1)); + } + /*tzoffset=uprv_getUTCtime();*/ + } +} + +static void TestVersion(void) +{ + UVersionInfo versionArray = {0x01, 0x00, 0x02, 0x02}; + UVersionInfo versionArray2 = {0x01, 0x00, 0x02, 0x02}; + char versionString[17]; /* xxx.xxx.xxx.xxx\0 */ + UChar versionUString[] = { 0x0031, 0x002E, 0x0030, 0x002E, + 0x0032, 0x002E, 0x0038, 0x0000 }; /* 1.0.2.8 */ + UVersionInfo version; + UErrorCode status = U_ZERO_ERROR; log_verbose("Testing the API u_versionToString().....\n"); u_versionToString(versionArray, versionString); @@ -187,67 +291,81 @@ static void TestPUtilAPI(void){ if(strcmp(versionString, U_ICU_VERSION) != 0){ log_err("ERROR: u_getVersion() failed. Got=%s, expected %s\n", versionString, U_ICU_VERSION); } - log_verbose("Testing the API u_errorName()...\n"); - str=(char*)u_errorName((UErrorCode)0); - if(strcmp(str, "U_ZERO_ERROR") != 0){ - log_err("ERROR: u_getVersion() failed. Expected: U_ZERO_ERROR Got=%s\n", str); - } - log_verbose("Testing the API u_errorName()...\n"); - str=(char*)u_errorName((UErrorCode)-127); - if(strcmp(str, "U_USING_DEFAULT_WARNING") != 0){ - log_err("ERROR: u_getVersion() failed. Expected: U_USING_DEFAULT_WARNING Got=%s\n", str); - } - log_verbose("Testing the API u_errorName().. with BOGUS ERRORCODE...\n"); - str=(char*)u_errorName((UErrorCode)200); - if(strcmp(str, "[BOGUS UErrorCode]") != 0){ - log_err("ERROR: u_getVersion() failed. Expected: [BOGUS UErrorCode] Got=%s\n", str); + /* test unicode */ + log_verbose("Testing u_versionFromUString...\n"); + u_versionFromString(versionArray,"1.0.2.8"); + u_versionFromUString(versionArray2, versionUString); + u_versionToString(versionArray2, versionString); + if(memcmp(versionArray, versionArray2, sizeof(UVersionInfo))) { + log_err("FAIL: u_versionFromUString produced a different result - not 1.0.2.8 but %s [%x.%x.%x.%x]\n", + versionString, + (int)versionArray2[0], + (int)versionArray2[1], + (int)versionArray2[2], + (int)versionArray2[3]); + } + else { + log_verbose(" from UString: %s\n", versionString); } - { - const char* dataDirectory; - UChar *udataDir=0; - UChar temp[100]; - char *charvalue=0; - log_verbose("Testing chars to UChars\n"); - - /* This cannot really work on a japanese system. u_uastrcpy will have different results than */ - /* u_charsToUChars when there is a backslash in the string! */ - /*dataDirectory=u_getDataDirectory();*/ - - dataDirectory="directory1"; /*no backslashes*/ - udataDir=(UChar*)malloc(sizeof(UChar) * (strlen(dataDirectory) + 1)); - u_charsToUChars(dataDirectory, udataDir, (strlen(dataDirectory)+1)); - u_uastrcpy(temp, dataDirectory); - - if(u_strcmp(temp, udataDir) != 0){ - log_err("ERROR: u_charsToUChars failed. Expected %s, Got %s\n", austrdup(temp), austrdup(udataDir)); - } - log_verbose("Testing UChars to chars\n"); - charvalue=(char*)malloc(sizeof(char) * (u_strlen(udataDir) + 1)); - - u_UCharsToChars(udataDir, charvalue, (u_strlen(udataDir)+1)); - if(strcmp(charvalue, dataDirectory) != 0){ - log_err("ERROR: u_UCharsToChars failed. Expected %s, Got %s\n", charvalue, dataDirectory); - } - free(charvalue); - free(udataDir); + /* Test the data version API for better code coverage */ + u_getDataVersion(version, &status); + if (U_FAILURE(status)) { + log_data_err("ERROR: Unable to get data version. %s\n", u_errorName(status)); } - - log_verbose("Testing uprv_timezone()....\n"); - { - int32_t tzoffset = uprv_timezone(); - log_verbose("Value returned from uprv_timezone = %d\n", tzoffset); - if (tzoffset != 28800) { - log_verbose("***** WARNING: If testing in the PST timezone, t_timezone should return 28800! *****"); - } - if ((tzoffset % 1800 != 0)) { - log_err("FAIL: t_timezone may be incorrect. It is not a multiple of 30min."); - } - tzoffset=uprv_getUTCtime(); +} +static void TestCompareVersions(void) +{ + /* use a 1d array to be palatable to java */ + const char *testCases[] = { + /* v1 <|=|> v2 */ + "0.0.0.0", "=", "0.0.0.0", + "3.1.2.0", ">", "3.0.9.0", + "3.2.8.6", "<", "3.4", + "4.0", ">", "3.2", + NULL, NULL, NULL + }; + const char *v1str; + const char *opstr; + const char *v2str; + int32_t op, invop, got, invgot; + UVersionInfo v1, v2; + int32_t j; + log_verbose("Testing memcmp()\n"); + for(j=0;testCases[j]!=NULL;j+=3) { + v1str = testCases[j+0]; + opstr = testCases[j+1]; + v2str = testCases[j+2]; + switch(opstr[0]) { + case '-': + case '<': op = -1; break; + case '0': + case '=': op = 0; break; + case '+': + case '>': op = 1; break; + default: log_err("Bad operator at j/3=%d\n", (j/3)); return; } + invop = 0-op; /* inverse operation: with v1 and v2 switched */ + u_versionFromString(v1, v1str); + u_versionFromString(v2, v2str); + got = memcmp(v1, v2, sizeof(UVersionInfo)); + invgot = memcmp(v2, v1, sizeof(UVersionInfo)); /* Opposite */ + if((got <= 0 && op <= 0) || (got >= 0 && op >= 0)) { + log_verbose("%d: %s %s %s, OK\n", (j/3), v1str, opstr, v2str); + } else { + log_err("%d: %s %s %s: wanted values of the same sign, %d got %d\n", (j/3), v1str, opstr, v2str, op, got); + } + if((invgot >= 0 && invop >= 0) || (invgot <= 0 && invop <= 0)) { + log_verbose("%d: %s (%d) %s, OK (inverse)\n", (j/3), v2str, invop, v1str); + } else { + log_err("%d: %s (%d) %s: wanted values of the same sign, %d got %d\n", (j/3), v2str, invop, v1str, invop, invgot); + } + } } + + #if 0 static void testIEEEremainder() { @@ -351,6 +469,9 @@ static void TestErrorName(void){ const char* errorName ; for(;code %s PASS\n", result); + } else { + log_err("FAIL: Test case [%d/%d]: %s -> %s but expected %s\n", i, count-1, input, result, expect); + } + } +} + + +static void toolutil_findDirname(void) +{ + int i; + struct { + const char *inBuf; + int32_t outBufLen; + UErrorCode expectStatus; + const char *expectResult; + } testCases[] = { + { + U_FILE_SEP_STRING "usr" U_FILE_SEP_STRING "bin" U_FILE_SEP_STRING "pkgdata", + 200, + U_ZERO_ERROR, + U_FILE_SEP_STRING "usr" U_FILE_SEP_STRING "bin", + }, + { + U_FILE_SEP_STRING "usr" U_FILE_SEP_STRING "bin" U_FILE_SEP_STRING "pkgdata", + 2, + U_BUFFER_OVERFLOW_ERROR, + NULL + }, + { + U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" U_FILE_ALT_SEP_STRING "pkgdata", + 200, + U_ZERO_ERROR, + U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" + }, + { + U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" U_FILE_ALT_SEP_STRING "pkgdata", + 2, + U_BUFFER_OVERFLOW_ERROR, + NULL + }, + { + U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" U_FILE_SEP_STRING "pkgdata", + 200, + U_ZERO_ERROR, + U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" + }, + { + U_FILE_ALT_SEP_STRING "usr" U_FILE_SEP_STRING "bin" U_FILE_ALT_SEP_STRING "pkgdata", + 200, + U_ZERO_ERROR, + U_FILE_ALT_SEP_STRING "usr" U_FILE_SEP_STRING "bin" + }, + { + U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" U_FILE_ALT_SEP_STRING "pkgdata", + 2, + U_BUFFER_OVERFLOW_ERROR, + NULL + }, + { + U_FILE_ALT_SEP_STRING "vmlinuz", + 200, + U_ZERO_ERROR, + U_FILE_ALT_SEP_STRING + }, + { + U_FILE_SEP_STRING "vmlinux", + 200, + U_ZERO_ERROR, + U_FILE_SEP_STRING + }, + { + "pkgdata", + 0, + U_BUFFER_OVERFLOW_ERROR, + NULL + }, + { + "pkgdata", + 2, + U_ZERO_ERROR, + "" + } + }; + int32_t count=UPRV_LENGTHOF(testCases); + + log_verbose("Testing findDirname()\n"); + for(i=0;i %s, \n", u_errorName(status)); + if(status != testCases[i].expectStatus) { + log_verbose("FAIL: Test case [%d/%d]: %s got error code %s but expected %s\n", i, count-1, input, u_errorName(status), u_errorName(testCases[i].expectStatus)); + } + if(result==expect||!strcmp(result,expect)) { + log_verbose(" = -> %s \n", result); + } else { + log_err("FAIL: Test case [%d/%d]: %s -> %s but expected %s\n", i, count-1, input, result, expect); + } + } } + + +static void addToolUtilTests(TestNode** root) { + addTest(root, &toolutil_findBasename, "putiltst/toolutil/findBasename"); + addTest(root, &toolutil_findDirname, "putiltst/toolutil/findDirname"); + addTest(root, &TestSignedRightShiftIsArithmetic, "putiltst/toolutil/TestSignedRightShiftIsArithmetic"); + /* + Not yet tested: + + addTest(root, &toolutil_getLongPathname, "putiltst/toolutil/getLongPathname"); + addTest(root, &toolutil_getCurrentYear, "putiltst/toolutil/getCurrentYear"); + addTest(root, &toolutil_UToolMemory, "putiltst/toolutil/UToolMemory"); + */ +}