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