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