• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
4  * COPYRIGHT:
5  * Copyright (c) 1998-2016, International Business Machines Corporation and
6  * others. All Rights Reserved.
7  ********************************************************************/
8 /*
9 * File putiltst.c (Tests the API in putil)
10 *
11 * Modification History:
12 *
13 *   Date          Name        Description
14 *   07/12/2000    Madhu       Creation
15 *******************************************************************************
16 */
17 
18 #include "unicode/utypes.h"
19 #include "cintltst.h"
20 #include "cmemory.h"
21 #include "unicode/putil.h"
22 #include "unicode/ustring.h"
23 #include "unicode/icudataver.h"
24 #include "cstring.h"
25 #include "putilimp.h"
26 #include "toolutil.h"
27 #include "uinvchar.h"
28 #include <stdbool.h>
29 #include <stdio.h>
30 #if U_PLATFORM_USES_ONLY_WIN32_API
31 #include "wintz.h"
32 #endif
33 
34 /* See the comments on U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC. */
TestSignedRightShiftIsArithmetic(void)35 static void TestSignedRightShiftIsArithmetic(void) {
36     int32_t x=0xfff5fff3;
37     int32_t m=-1;
38     int32_t x4=x>>4;
39     int32_t m1=m>>1;
40     UBool signedRightShiftIsArithmetic= (x4==(int32_t)0xffff5fff && m1==-1);
41     if(signedRightShiftIsArithmetic==U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC) {
42         log_info("signed right shift is Arithmetic Shift Right: %d\n",
43                  signedRightShiftIsArithmetic);
44     } else {
45         log_err("error: unexpected signed right shift is Arithmetic Shift Right: %d\n"
46                 "       You need to change the value of U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC "
47                 "for your platform.\n",
48                 signedRightShiftIsArithmetic);
49     }
50 }
51 
52 static UBool compareWithNAN(double x, double y);
53 static void doAssert(double expect, double got, const char *message);
54 
TestPUtilAPI(void)55 static void TestPUtilAPI(void){
56 
57     double  n1=0.0, y1=0.0, expn1, expy1;
58     double  value1 = 0.021;
59     char *str=0;
60     UBool isTrue=false;
61 
62     log_verbose("Testing the API uprv_modf()\n");
63     y1 = uprv_modf(value1, &n1);
64     expn1=0;
65     expy1=0.021;
66     if(y1 != expy1   || n1 != expn1){
67         log_err("Error in uprv_modf.  Expected IntegralValue=%f, Got=%f, \n Expected FractionalValue=%f, Got=%f\n",
68              expn1, n1, expy1, y1);
69     }
70     if(getTestOption(VERBOSITY_OPTION)){
71         log_verbose("[float]  x = %f  n = %f y = %f\n", value1, n1, y1);
72     }
73     log_verbose("Testing the API uprv_fmod()\n");
74     expn1=uprv_fmod(30.50, 15.00);
75     doAssert(expn1, 0.5, "uprv_fmod(30.50, 15.00) failed.");
76 
77     log_verbose("Testing the API uprv_ceil()\n");
78     expn1=uprv_ceil(value1);
79     doAssert(expn1, 1, "uprv_ceil(0.021) failed.");
80 
81     log_verbose("Testing the API uprv_floor()\n");
82     expn1=uprv_floor(value1);
83     doAssert(expn1, 0, "uprv_floor(0.021) failed.");
84 
85     log_verbose("Testing the API uprv_fabs()\n");
86     expn1=uprv_fabs((2.02-1.345));
87     doAssert(expn1, 0.675, "uprv_fabs(2.02-1.345) failed.");
88 
89     log_verbose("Testing the API uprv_fmax()\n");
90     doAssert(uprv_fmax(2.4, 1.2), 2.4, "uprv_fmax(2.4, 1.2) failed.");
91 
92     log_verbose("Testing the API uprv_fmax() with x value= NaN\n");
93     expn1=uprv_fmax(uprv_getNaN(), 1.2);
94     doAssert(expn1, uprv_getNaN(), "uprv_fmax(uprv_getNaN(), 1.2) failed. when one parameter is NaN");
95 
96     log_verbose("Testing the API uprv_fmin()\n");
97     doAssert(uprv_fmin(2.4, 1.2), 1.2, "uprv_fmin(2.4, 1.2) failed.");
98 
99     log_verbose("Testing the API uprv_fmin() with x value= NaN\n");
100     expn1=uprv_fmin(uprv_getNaN(), 1.2);
101     doAssert(expn1, uprv_getNaN(), "uprv_fmin(uprv_getNaN(), 1.2) failed. when one parameter is NaN");
102 
103     log_verbose("Testing the API uprv_max()\n");
104     doAssert(uprv_max(4, 2), 4, "uprv_max(4, 2) failed.");
105 
106     log_verbose("Testing the API uprv_min()\n");
107     doAssert(uprv_min(-4, 2), -4, "uprv_min(-4, 2) failed.");
108 
109     log_verbose("Testing the API uprv_trunc()\n");
110     doAssert(uprv_trunc(12.3456), 12, "uprv_trunc(12.3456) failed.");
111     doAssert(uprv_trunc(12.234E2), 1223, "uprv_trunc(12.234E2) failed.");
112     doAssert(uprv_trunc(uprv_getNaN()), uprv_getNaN(), "uprv_trunc(uprv_getNaN()) failed. with parameter=NaN");
113     doAssert(uprv_trunc(uprv_getInfinity()), uprv_getInfinity(), "uprv_trunc(uprv_getInfinity()) failed. with parameter=Infinity");
114 
115 
116     log_verbose("Testing the API uprv_pow10()\n");
117     doAssert(uprv_pow10(4), 10000, "uprv_pow10(4) failed.");
118 
119     log_verbose("Testing the API uprv_isNegativeInfinity()\n");
120     isTrue=uprv_isNegativeInfinity(uprv_getInfinity() * -1);
121     if(isTrue != true){
122         log_err("ERROR: uprv_isNegativeInfinity failed.\n");
123     }
124     log_verbose("Testing the API uprv_isPositiveInfinity()\n");
125     isTrue=uprv_isPositiveInfinity(uprv_getInfinity());
126     if(isTrue != true){
127         log_err("ERROR: uprv_isPositiveInfinity failed.\n");
128     }
129     log_verbose("Testing the API uprv_isInfinite()\n");
130     isTrue=uprv_isInfinite(uprv_getInfinity());
131     if(isTrue != true){
132         log_err("ERROR: uprv_isInfinite failed.\n");
133     }
134 
135     log_verbose("Testing the APIs uprv_add32_overflow and uprv_mul32_overflow\n");
136     int32_t overflow_result;
137     doAssert(false, uprv_add32_overflow(INT32_MAX - 2, 1, &overflow_result), "should not overflow");
138     doAssert(INT32_MAX - 1, overflow_result, "should equal INT32_MAX - 1");
139     doAssert(false, uprv_add32_overflow(INT32_MAX - 2, 2, &overflow_result), "should not overflow");
140     doAssert(INT32_MAX, overflow_result, "should equal exactly INT32_MAX");
141     doAssert(true, uprv_add32_overflow(INT32_MAX - 2, 3, &overflow_result), "should overflow");
142     doAssert(false, uprv_mul32_overflow(INT32_MAX / 5, 4, &overflow_result), "should not overflow");
143     doAssert(INT32_MAX / 5 * 4, overflow_result, "should equal INT32_MAX / 5 * 4");
144     doAssert(true, uprv_mul32_overflow(INT32_MAX / 5, 6, &overflow_result), "should overflow");
145     // Test on negative numbers:
146     doAssert(false, uprv_add32_overflow(-3, -2, &overflow_result), "should not overflow");
147     doAssert(-5, overflow_result, "should equal -5");
148 
149 #if 0
150     log_verbose("Testing the API uprv_digitsAfterDecimal()....\n");
151     doAssert(uprv_digitsAfterDecimal(value1), 3, "uprv_digitsAfterDecimal() failed.");
152     doAssert(uprv_digitsAfterDecimal(1.2345E2), 2, "uprv_digitsAfterDecimal(1.2345E2) failed.");
153     doAssert(uprv_digitsAfterDecimal(1.2345E-2), 6, "uprv_digitsAfterDecimal(1.2345E-2) failed.");
154     doAssert(uprv_digitsAfterDecimal(1.2345E2), 2, "uprv_digitsAfterDecimal(1.2345E2) failed.");
155     doAssert(uprv_digitsAfterDecimal(-1.2345E-20), 24, "uprv_digitsAfterDecimal(1.2345E-20) failed.");
156     doAssert(uprv_digitsAfterDecimal(1.2345E20), 0, "uprv_digitsAfterDecimal(1.2345E20) failed.");
157     doAssert(uprv_digitsAfterDecimal(-0.021), 3, "uprv_digitsAfterDecimal(-0.021) failed.");
158     doAssert(uprv_digitsAfterDecimal(23.0), 0, "uprv_digitsAfterDecimal(23.0) failed.");
159     doAssert(uprv_digitsAfterDecimal(0.022223333321), 9, "uprv_digitsAfterDecimal(0.022223333321) failed.");
160 #endif
161 
162     log_verbose("Testing the API u_errorName()...\n");
163     str=(char*)u_errorName((UErrorCode)0);
164     if(strcmp(str, "U_ZERO_ERROR") != 0){
165         log_err("ERROR: u_getVersion() failed. Expected: U_ZERO_ERROR Got=%s\n",  str);
166     }
167     log_verbose("Testing the API u_errorName()...\n");
168     str=(char*)u_errorName((UErrorCode)-127);
169     if(strcmp(str, "U_USING_DEFAULT_WARNING") != 0){
170         log_err("ERROR: u_getVersion() failed. Expected: U_USING_DEFAULT_WARNING Got=%s\n",  str);
171     }
172     log_verbose("Testing the API u_errorName().. with BOGUS ERRORCODE...\n");
173     str=(char*)u_errorName((UErrorCode)200);
174     if(strcmp(str, "[BOGUS UErrorCode]") != 0){
175         log_err("ERROR: u_getVersion() failed. Expected: [BOGUS UErrorCode] Got=%s\n",  str);
176     }
177 
178     {
179         const char* dataDirectory;
180         int32_t dataDirectoryLen;
181         UChar *udataDir=0;
182         UChar temp[100];
183         char *charvalue=0;
184         log_verbose("Testing chars to UChars\n");
185 
186          /* This cannot really work on a japanese system. u_uastrcpy will have different results than */
187         /* u_charsToUChars when there is a backslash in the string! */
188         /*dataDirectory=u_getDataDirectory();*/
189 
190         dataDirectory="directory1";  /*no backslashes*/
191         dataDirectoryLen=(int32_t)strlen(dataDirectory);
192         udataDir=(UChar*)malloc(sizeof(UChar) * (dataDirectoryLen + 1));
193         u_charsToUChars(dataDirectory, udataDir, (dataDirectoryLen + 1));
194         u_uastrcpy(temp, dataDirectory);
195 
196         if(u_strcmp(temp, udataDir) != 0){
197             log_err("ERROR: u_charsToUChars failed. Expected %s, Got %s\n", austrdup(temp), austrdup(udataDir));
198         }
199         log_verbose("Testing UChars to chars\n");
200         charvalue=(char*)malloc(sizeof(char) * (u_strlen(udataDir) + 1));
201 
202         u_UCharsToChars(udataDir, charvalue, (u_strlen(udataDir)+1));
203         if(strcmp(charvalue, dataDirectory) != 0){
204             log_err("ERROR: u_UCharsToChars failed. Expected %s, Got %s\n", charvalue, dataDirectory);
205         }
206         free(charvalue);
207         free(udataDir);
208     }
209 
210     log_verbose("Testing uprv_timezone()....\n");
211     {
212         int32_t tzoffset = uprv_timezone();
213         log_verbose("Value returned from uprv_timezone = %d\n",  tzoffset);
214         if (tzoffset != 28800) {
215             log_verbose("***** WARNING: If testing in the PST timezone, t_timezone should return 28800! *****");
216         }
217         if ((tzoffset % 1800 != 0)) {
218             log_info("Note: t_timezone offset of %ld (for %s : %s) is not a multiple of 30min.", tzoffset, uprv_tzname(0), uprv_tzname(1));
219         }
220         /*tzoffset=uprv_getUTCtime();*/
221     }
222 
223 #if U_PLATFORM_USES_ONLY_WIN32_API
224     log_verbose("Testing uprv_detectWindowsTimeZone() ....\n");
225     {
226         const char* timezone = uprv_detectWindowsTimeZone();
227         if (timezone == NULL) {
228             log_err("ERROR: uprv_detectWindowsTimeZone failed (returned NULL).\n");
229         } else {
230             log_verbose("Detected TimeZone = %s\n", timezone);
231         }
232     }
233 #endif
234 }
235 
TestVersion(void)236 static void TestVersion(void)
237 {
238     UVersionInfo versionArray = {0x01, 0x00, 0x02, 0x02};
239     UVersionInfo versionArray2 = {0x01, 0x00, 0x02, 0x02};
240     char versionString[17]; /* xxx.xxx.xxx.xxx\0 */
241     UChar versionUString[] = { 0x0031, 0x002E, 0x0030, 0x002E,
242                                0x0032, 0x002E, 0x0038, 0x0000 }; /* 1.0.2.8 */
243     UVersionInfo version;
244     UErrorCode status = U_ZERO_ERROR;
245 
246     log_verbose("Testing the API u_versionToString().....\n");
247     u_versionToString(versionArray, versionString);
248     if(strcmp(versionString, "1.0.2.2") != 0){
249         log_err("ERROR: u_versionToString() failed. Expected: 1.0.2.2, Got=%s\n", versionString);
250     }
251     log_verbose("Testing the API u_versionToString().....with versionArray=NULL\n");
252     u_versionToString(NULL, versionString);
253     if(strcmp(versionString, "") != 0){
254         log_err("ERROR: u_versionToString() failed. with versionArray=NULL. It should just return\n");
255     }
256     log_verbose("Testing the API u_versionToString().....with versionArray=NULL\n");
257     u_versionToString(NULL, versionString);
258     if(strcmp(versionString, "") != 0){
259         log_err("ERROR: u_versionToString() failed . It should just return\n");
260     }
261     log_verbose("Testing the API u_versionToString().....with versionString=NULL\n");
262     u_versionToString(versionArray, NULL);
263     if(strcmp(versionString, "") != 0){
264         log_err("ERROR: u_versionToString() failed. with versionArray=NULL  It should just return\n");
265     }
266     versionArray[0] = 0x0a;
267     log_verbose("Testing the API u_versionToString().....\n");
268     u_versionToString(versionArray, versionString);
269     if(strcmp(versionString, "10.0.2.2") != 0){
270         log_err("ERROR: u_versionToString() failed. Expected: 10.0.2.2, Got=%s\n", versionString);
271     }
272     versionArray[0] = 0xa0;
273     u_versionToString(versionArray, versionString);
274     if(strcmp(versionString, "160.0.2.2") != 0){
275         log_err("ERROR: u_versionToString() failed. Expected: 160.0.2.2, Got=%s\n", versionString);
276     }
277     versionArray[0] = 0xa0;
278     versionArray[1] = 0xa0;
279     u_versionToString(versionArray, versionString);
280     if(strcmp(versionString, "160.160.2.2") != 0){
281         log_err("ERROR: u_versionToString() failed. Expected: 160.160.2.2, Got=%s\n", versionString);
282     }
283     versionArray[0] = 0x01;
284     versionArray[1] = 0x0a;
285     u_versionToString(versionArray, versionString);
286     if(strcmp(versionString, "1.10.2.2") != 0){
287         log_err("ERROR: u_versionToString() failed. Expected: 160.160.2.2, Got=%s\n", versionString);
288     }
289 
290     log_verbose("Testing the API u_versionFromString() ....\n");
291     u_versionFromString(versionArray, "1.3.5.6");
292     u_versionToString(versionArray, versionString);
293     if(strcmp(versionString, "1.3.5.6") != 0){
294         log_err("ERROR: u_getVersion() failed. Expected: 1.3.5.6, Got=%s\n",  versionString);
295     }
296     log_verbose("Testing the API u_versionFromString() where versionArray=NULL....\n");
297     u_versionFromString(NULL, "1.3.5.6");
298     u_versionToString(versionArray, versionString);
299     if(strcmp(versionString, "1.3.5.6") != 0){
300         log_err("ERROR: u_getVersion() failed. Expected: 1.3.5.6, Got=%s\n",  versionString);
301     }
302 
303     log_verbose("Testing the API u_getVersion().....\n");
304     u_getVersion(versionArray);
305     u_versionToString(versionArray, versionString);
306     if(strcmp(versionString, U_ICU_VERSION) != 0){
307         log_err("ERROR: u_getVersion() failed. Got=%s, expected %s\n",  versionString, U_ICU_VERSION);
308     }
309     /* test unicode */
310     log_verbose("Testing u_versionFromUString...\n");
311     u_versionFromString(versionArray,"1.0.2.8");
312     u_versionFromUString(versionArray2, versionUString);
313     u_versionToString(versionArray2, versionString);
314     if(memcmp(versionArray, versionArray2, sizeof(UVersionInfo))) {
315        log_err("FAIL: u_versionFromUString produced a different result - not 1.0.2.8 but %s [%x.%x.%x.%x]\n",
316           versionString,
317         (int)versionArray2[0],
318         (int)versionArray2[1],
319         (int)versionArray2[2],
320         (int)versionArray2[3]);
321     }
322     else {
323        log_verbose(" from UString: %s\n", versionString);
324     }
325 
326     /* Test the data version API for better code coverage */
327     u_getDataVersion(version, &status);
328     if (U_FAILURE(status)) {
329         log_data_err("ERROR: Unable to get data version. %s\n", u_errorName(status));
330     }
331 }
332 
TestCompareVersions(void)333 static void TestCompareVersions(void)
334 {
335    /* use a 1d array to be palatable to java */
336    const char *testCases[] = {
337       /*  v1          <|=|>       v2  */
338     "0.0.0.0",    "=",        "0.0.0.0",
339     "3.1.2.0",    ">",        "3.0.9.0",
340     "3.2.8.6",    "<",        "3.4",
341     "4.0",        ">",        "3.2",
342     NULL,        NULL,        NULL
343    };
344    const char *v1str;
345    const char *opstr;
346    const char *v2str;
347    int32_t op, invop, got, invgot;
348    UVersionInfo v1, v2;
349    int32_t j;
350    log_verbose("Testing memcmp()\n");
351    for(j=0;testCases[j]!=NULL;j+=3) {
352     v1str = testCases[j+0];
353     opstr = testCases[j+1];
354     v2str = testCases[j+2];
355     switch(opstr[0]) {
356         case '-':
357         case '<': op = -1; break;
358         case '0':
359         case '=': op = 0; break;
360         case '+':
361         case '>': op = 1; break;
362         default:  log_err("Bad operator at j/3=%d\n", (j/3)); return;
363     }
364     invop = 0-op; /* inverse operation: with v1 and v2 switched */
365     u_versionFromString(v1, v1str);
366     u_versionFromString(v2, v2str);
367     got = memcmp(v1, v2, sizeof(UVersionInfo));
368     invgot = memcmp(v2, v1, sizeof(UVersionInfo)); /* Opposite */
369     if((got <= 0 && op <= 0) || (got >= 0 && op >= 0)) {
370         log_verbose("%d: %s %s %s, OK\n", (j/3), v1str, opstr, v2str);
371     } else {
372         log_err("%d: %s %s %s: wanted values of the same sign, %d got %d\n", (j/3), v1str, opstr, v2str, op, got);
373     }
374     if((invgot >= 0 && invop >= 0) || (invgot <= 0 && invop <= 0)) {
375         log_verbose("%d: %s (%d) %s, OK (inverse)\n", (j/3), v2str, invop, v1str);
376     } else {
377         log_err("%d: %s (%d) %s: wanted values of the same sign, %d got %d\n", (j/3), v2str, invop, v1str, invop, invgot);
378     }
379    }
380 }
381 
382 
383 
384 #if 0
385 static void testIEEEremainder()
386 {
387     double    pinf        = uprv_getInfinity();
388     double    ninf        = -uprv_getInfinity();
389     double    nan         = uprv_getNaN();
390 /*    double    pzero       = 0.0;*/
391 /*    double    nzero       = 0.0;
392     nzero *= -1;*/
393 
394      /* simple remainder checks*/
395     remainderTest(7.0, 2.5, -0.5);
396     remainderTest(7.0, -2.5, -0.5);
397      /* this should work
398      remainderTest(43.7, 2.5, 1.2);
399      */
400 
401     /* infinity and real*/
402     remainderTest(1.0, pinf, 1.0);
403     remainderTest(1.0, ninf, 1.0);
404 
405     /*test infinity and real*/
406     remainderTest(nan, 1.0, nan);
407     remainderTest(1.0, nan, nan);
408     /*test infinity and nan*/
409     remainderTest(ninf, nan, nan);
410     remainderTest(pinf, nan, nan);
411 
412     /* test infinity and zero */
413 /*    remainderTest(pinf, pzero, 1.25);
414     remainderTest(pinf, nzero, 1.25);
415     remainderTest(ninf, pzero, 1.25);
416     remainderTest(ninf, nzero, 1.25); */
417 }
418 
419 static void remainderTest(double x, double y, double exp)
420 {
421     double result = uprv_IEEEremainder(x,y);
422 
423     if(        uprv_isNaN(result) &&
424         ! ( uprv_isNaN(x) || uprv_isNaN(y))) {
425         log_err("FAIL: got NaN as result without NaN as argument");
426         log_err("      IEEEremainder(%f, %f) is %f, expected %f\n", x, y, result, exp);
427     }
428     else if(!compareWithNAN(result, exp)) {
429         log_err("FAIL:  IEEEremainder(%f, %f) is %f, expected %f\n", x, y, result, exp);
430     } else{
431         log_verbose("OK: IEEEremainder(%f, %f) is %f\n", x, y, result);
432     }
433 
434 }
435 #endif
436 
compareWithNAN(double x,double y)437 static UBool compareWithNAN(double x, double y)
438 {
439   if( uprv_isNaN(x) || uprv_isNaN(y) ) {
440     if(!uprv_isNaN(x) || !uprv_isNaN(y) ) {
441       return false;
442     }
443   }
444   else if (y != x) { /* no NaN's involved */
445     return false;
446   }
447 
448   return true;
449 }
450 
doAssert(double got,double expect,const char * message)451 static void doAssert(double got, double expect, const char *message)
452 {
453   if(! compareWithNAN(expect, got) ) {
454     log_err("ERROR :  %s. Expected : %lf, Got: %lf\n", message, expect, got);
455   }
456 }
457 
458 
459 #define _CODE_ARR_LEN 8
460 static const UErrorCode errorCode[_CODE_ARR_LEN] = {
461     U_USING_FALLBACK_WARNING,
462     U_STRING_NOT_TERMINATED_WARNING,
463     U_ILLEGAL_ARGUMENT_ERROR,
464     U_STATE_TOO_OLD_ERROR,
465     U_BAD_VARIABLE_DEFINITION,
466     U_RULE_MASK_ERROR,
467     U_UNEXPECTED_TOKEN,
468     U_UNSUPPORTED_ATTRIBUTE
469 };
470 
471 static const char* str[] = {
472     "U_USING_FALLBACK_WARNING",
473     "U_STRING_NOT_TERMINATED_WARNING",
474     "U_ILLEGAL_ARGUMENT_ERROR",
475     "U_STATE_TOO_OLD_ERROR",
476     "U_BAD_VARIABLE_DEFINITION",
477     "U_RULE_MASK_ERROR",
478     "U_UNEXPECTED_TOKEN",
479     "U_UNSUPPORTED_ATTRIBUTE"
480 };
481 
TestErrorName(void)482 static void TestErrorName(void){
483     int32_t code=0;
484     const char* errorName ;
485     for(;code<U_ERROR_LIMIT;code++){
486         errorName = u_errorName((UErrorCode)code);
487         if(!errorName || errorName[0] == 0) {
488           log_err("Error:  u_errorName(0x%X) failed.\n",code);
489         }
490     }
491 
492     for(code=0;code<_CODE_ARR_LEN; code++){
493         errorName = u_errorName(errorCode[code]);
494         if(uprv_strcmp(str[code],errorName )!=0){
495             log_err("Error : u_errorName failed. Expected: %s Got: %s \n",str[code],errorName);
496         }
497     }
498 }
499 
500 #define AESTRNCPY_SIZE 13
501 
dump_binline(uint8_t * bytes)502 static const char * dump_binline(uint8_t *bytes) {
503   static char buf[512];
504   int32_t i;
505   for(i=0;i<13;i++) {
506     sprintf(buf+(i*3), "%02x ", bytes[i]);
507   }
508   return buf;
509 }
510 
Test_aestrncpy(int32_t line,const uint8_t * expect,const uint8_t * src,int32_t len)511 static void Test_aestrncpy(int32_t line, const uint8_t *expect, const uint8_t *src, int32_t len)
512 {
513   uint8_t str_buf[AESTRNCPY_SIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
514   uint8_t *ret;
515 
516   log_verbose("\n%s:%d: Beginning test of uprv_aestrncpy(dst, src, %d)\n", __FILE__, line, len);
517   ret = uprv_aestrncpy(str_buf, src, len);
518   if(ret != str_buf) {
519     log_err("\n%s:%d: FAIL: uprv_aestrncpy returned %p expected %p\n", __FILE__, line, (void*)ret, (void*)str_buf);
520   }
521   if(!uprv_memcmp(str_buf, expect, AESTRNCPY_SIZE)) {
522     log_verbose("\n%s:%d: OK - compared OK.", __FILE__, line);
523     log_verbose("\n%s:%d:         expected: %s", __FILE__, line, dump_binline((uint8_t *)expect));
524     log_verbose("\n%s:%d:         got     : %s\n", __FILE__, line, dump_binline(str_buf));
525   } else {
526     log_err    ("\n%s:%d: FAIL: uprv_aestrncpy output differs", __FILE__, line);
527     log_err    ("\n%s:%d:         expected: %s", __FILE__, line, dump_binline((uint8_t *)expect));
528     log_err    ("\n%s:%d:         got     : %s\n", __FILE__, line, dump_binline(str_buf));
529   }
530 }
531 
TestString(void)532 static void TestString(void)
533 {
534 
535   uint8_t str_tst[AESTRNCPY_SIZE] = { 0x81, 0x4b, 0x5c, 0x82, 0x25, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f };
536 
537   uint8_t str_exp1[AESTRNCPY_SIZE] = { 0x61, 0x2e, 0x2a, 0x62, 0x0a, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
538   uint8_t str_exp2[AESTRNCPY_SIZE] = { 0x61, 0x2e, 0x2a, 0x62, 0x0a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
539   uint8_t str_exp3[AESTRNCPY_SIZE] = { 0x61, 0x2e, 0x2a, 0x62, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff };
540 
541 
542 
543   /* test #1- copy with -1 length */
544   Test_aestrncpy(__LINE__, str_exp1, str_tst, -1);
545   Test_aestrncpy(__LINE__, str_exp1, str_tst, 6);
546   Test_aestrncpy(__LINE__, str_exp2, str_tst, 5);
547   Test_aestrncpy(__LINE__, str_exp3, str_tst, 8);
548 }
549 
550 void addPUtilTest(TestNode** root);
551 
552 static void addToolUtilTests(TestNode** root);
553 
554 void
addPUtilTest(TestNode ** root)555 addPUtilTest(TestNode** root)
556 {
557     addTest(root, &TestVersion,       "putiltst/TestVersion");
558     addTest(root, &TestCompareVersions,       "putiltst/TestCompareVersions");
559 /*    addTest(root, &testIEEEremainder,  "putiltst/testIEEEremainder"); */
560     addTest(root, &TestErrorName, "putiltst/TestErrorName");
561     addTest(root, &TestPUtilAPI,       "putiltst/TestPUtilAPI");
562     addTest(root, &TestString,    "putiltst/TestString");
563     addToolUtilTests(root);
564 }
565 
566 /* Tool Util Tests ================ */
567 #define TOOLUTIL_TESTBUF_SIZE 2048
568 static char toolutil_testBuf[TOOLUTIL_TESTBUF_SIZE];
569 static const char *NULLSTR="NULL";
570 
571 /**
572  * Normalize NULL to 'NULL'  for testing
573  */
574 #define STRNULL(x) ((x)?(x):NULLSTR)
575 
toolutil_findBasename(void)576 static void toolutil_findBasename(void)
577 {
578   struct {
579     const char *inBuf;
580     const char *expectResult;
581   } testCases[] = {
582     {
583       U_FILE_SEP_STRING "usr" U_FILE_SEP_STRING "bin" U_FILE_SEP_STRING "pkgdata",
584       "pkgdata"
585     },
586     {
587       U_FILE_SEP_STRING "usr" U_FILE_SEP_STRING "bin" U_FILE_SEP_STRING,
588       ""
589     },
590     {
591       U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" U_FILE_ALT_SEP_STRING "pkgdata",
592       "pkgdata"
593     },
594     {
595       U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" U_FILE_ALT_SEP_STRING,
596       ""
597     },
598   };
599   int32_t count=UPRV_LENGTHOF(testCases);
600   int32_t i;
601 
602 
603   log_verbose("Testing findBaseName()\n");
604   for(i=0;i<count;i++) {
605     const char *result;
606     const char *input = STRNULL(testCases[i].inBuf);
607     const char *expect = STRNULL(testCases[i].expectResult);
608     log_verbose("Test case [%d/%d]: %s\n", i, count-1, input);
609     result = STRNULL(findBasename(testCases[i].inBuf));
610     if(result==expect||!strcmp(result,expect)) {
611       log_verbose(" -> %s PASS\n", result);
612     } else {
613       log_err("FAIL: Test case [%d/%d]: %s -> %s but expected %s\n", i, count-1, input, result, expect);
614     }
615   }
616 }
617 
618 
toolutil_findDirname(void)619 static void toolutil_findDirname(void)
620 {
621   int i;
622   struct {
623     const char *inBuf;
624     int32_t outBufLen;
625     UErrorCode expectStatus;
626     const char *expectResult;
627   } testCases[] = {
628     {
629       U_FILE_SEP_STRING "usr" U_FILE_SEP_STRING "bin" U_FILE_SEP_STRING "pkgdata",
630       200,
631       U_ZERO_ERROR,
632       U_FILE_SEP_STRING "usr" U_FILE_SEP_STRING "bin",
633     },
634     {
635       U_FILE_SEP_STRING "usr" U_FILE_SEP_STRING "bin" U_FILE_SEP_STRING "pkgdata",
636       2,
637       U_BUFFER_OVERFLOW_ERROR,
638       NULL
639     },
640     {
641       U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" U_FILE_ALT_SEP_STRING "pkgdata",
642       200,
643       U_ZERO_ERROR,
644       U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin"
645     },
646     {
647       U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" U_FILE_ALT_SEP_STRING "pkgdata",
648       2,
649       U_BUFFER_OVERFLOW_ERROR,
650       NULL
651     },
652     {
653       U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" U_FILE_SEP_STRING "pkgdata",
654       200,
655       U_ZERO_ERROR,
656       U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin"
657     },
658     {
659       U_FILE_ALT_SEP_STRING "usr" U_FILE_SEP_STRING "bin" U_FILE_ALT_SEP_STRING "pkgdata",
660       200,
661       U_ZERO_ERROR,
662       U_FILE_ALT_SEP_STRING "usr" U_FILE_SEP_STRING "bin"
663     },
664     {
665       U_FILE_ALT_SEP_STRING "usr" U_FILE_ALT_SEP_STRING "bin" U_FILE_ALT_SEP_STRING "pkgdata",
666       2,
667       U_BUFFER_OVERFLOW_ERROR,
668       NULL
669     },
670     {
671       U_FILE_ALT_SEP_STRING "vmlinuz",
672       200,
673       U_ZERO_ERROR,
674       U_FILE_ALT_SEP_STRING
675     },
676     {
677       U_FILE_SEP_STRING "vmlinux",
678       200,
679       U_ZERO_ERROR,
680       U_FILE_SEP_STRING
681     },
682     {
683       "pkgdata",
684       0,
685       U_BUFFER_OVERFLOW_ERROR,
686       NULL
687     },
688     {
689       "pkgdata",
690       2,
691       U_ZERO_ERROR,
692       ""
693     }
694   };
695   int32_t count=UPRV_LENGTHOF(testCases);
696 
697   log_verbose("Testing findDirname()\n");
698   for(i=0;i<count;i++) {
699     const char *result;
700     const char *input = STRNULL(testCases[i].inBuf);
701     const char *expect = STRNULL(testCases[i].expectResult);
702     UErrorCode status = U_ZERO_ERROR;
703     uprv_memset(toolutil_testBuf, 0x55, TOOLUTIL_TESTBUF_SIZE);
704 
705     log_verbose("Test case [%d/%d]: %s\n", i, count-1, input);
706     result = STRNULL(findDirname(testCases[i].inBuf, toolutil_testBuf, testCases[i].outBufLen, &status));
707     log_verbose(" -> %s, \n", u_errorName(status));
708     if(status != testCases[i].expectStatus) {
709       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));
710     }
711     if(result==expect||!strcmp(result,expect)) {
712       log_verbose(" = -> %s \n", result);
713     } else {
714       log_err("FAIL: Test case [%d/%d]: %s -> %s but expected %s\n", i, count-1, input, result, expect);
715     }
716   }
717 }
718 
719 
720 
addToolUtilTests(TestNode ** root)721 static void addToolUtilTests(TestNode** root) {
722     addTest(root, &toolutil_findBasename,       "putiltst/toolutil/findBasename");
723     addTest(root, &toolutil_findDirname,       "putiltst/toolutil/findDirname");
724     addTest(root, &TestSignedRightShiftIsArithmetic, "putiltst/toolutil/TestSignedRightShiftIsArithmetic");
725   /*
726     Not yet tested:
727 
728     addTest(root, &toolutil_getLongPathname,       "putiltst/toolutil/getLongPathname");
729     addTest(root, &toolutil_getCurrentYear,       "putiltst/toolutil/getCurrentYear");
730     addTest(root, &toolutil_UToolMemory,       "putiltst/toolutil/UToolMemory");
731   */
732 }
733