• 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 **********************************************************************
5 * Copyright (C) 1998-2014, International Business Machines Corporation
6 * and others.  All Rights Reserved.
7 **********************************************************************
8 *
9 * File cstrtest.c
10 *
11 * Modification History:
12 *
13 *   Date        Name        Description
14 *   07/13/2000  Madhu         created
15 *******************************************************************************
16 */
17 
18 #include "unicode/ustring.h"
19 #include "unicode/ucnv.h"
20 #include "cstring.h"
21 #include "uinvchar.h"
22 #include "cintltst.h"
23 #include "cmemory.h"
24 
25 static void TestAPI(void);
26 void addCStringTest(TestNode** root);
27 
28 static void TestInvariant(void);
29 static void TestCompareInvEbcdicAsAscii(void);
30 static void TestLocaleAtSign(void);
31 static void TestNoInvariantAtSign(void);
32 static void TestInvCharToAscii(void);
33 
addCStringTest(TestNode ** root)34 void addCStringTest(TestNode** root) {
35     addTest(root, &TestAPI, "tsutil/cstrtest/TestAPI");
36     addTest(root, &TestInvariant, "tsutil/cstrtest/TestInvariant");
37     addTest(root, &TestCompareInvEbcdicAsAscii, "tsutil/cstrtest/TestCompareInvEbcdicAsAscii");
38     addTest(root, &TestLocaleAtSign, "tsutil/cstrtest/TestLocaleAtSign");
39     addTest(root, &TestNoInvariantAtSign, "tsutil/cstrtest/TestNoInvariantAtSign");
40     addTest(root, &TestInvCharToAscii, "tsutil/cstrtest/TestInvCharToAscii");
41 }
42 
TestAPI(void)43 static void TestAPI(void)
44 {
45     int32_t intValue=0;
46     char src[30]="HELLO THERE", dest[30];
47     static const char *const abc="abcdefghijklmnopqrstuvwxyz", *const ABC="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
48     const char *temp;
49     int32_t i;
50 
51     log_verbose("Testing uprv_tolower() and uprv_toupper()\n");
52     for(i=0; i<=26; ++i) {
53         dest[i]=uprv_tolower(abc[i]);
54     }
55     if(0!=strcmp(abc, dest)) {
56         log_err("uprv_tolower(abc) failed\n");
57     }
58 
59     for(i=0; i<=26; ++i) {
60         dest[i]=uprv_tolower(ABC[i]);
61     }
62     if(0!=strcmp(abc, dest)) {
63         log_err("uprv_tolower(ABC) failed\n");
64     }
65 
66     for(i=0; i<=26; ++i) {
67         dest[i]=uprv_toupper(abc[i]);
68     }
69     if(0!=strcmp(ABC, dest)) {
70         log_err("uprv_toupper(abc) failed\n");
71     }
72 
73     for(i=0; i<=26; ++i) {
74         dest[i]=uprv_toupper(ABC[i]);
75     }
76     if(0!=strcmp(ABC, dest)) {
77         log_err("uprv_toupper(ABC) failed\n");
78     }
79 
80     log_verbose("Testing the API in cstring\n");
81     T_CString_toLowerCase(src);
82     if(uprv_strcmp(src, "hello there") != 0){
83         log_err("FAIL: *** T_CString_toLowerCase() failed. Expected: \"hello there\", Got: \"%s\"\n", src);
84     }
85     T_CString_toUpperCase(src);
86     if(uprv_strcmp(src, "HELLO THERE") != 0){
87         log_err("FAIL: *** T_CString_toUpperCase() failed. Expected: \"HELLO THERE\", Got: \"%s\"\n", src);
88     }
89 
90     intValue=T_CString_stringToInteger("34556", 10);
91     if(intValue != 34556){
92         log_err("FAIL: ****T_CString_stringToInteger(\"34556\", 10) failed. Expected: 34556, Got: %d\n", intValue);
93     }
94     intValue=T_CString_stringToInteger("100", 16);
95     if(intValue != 256){
96         log_err("FAIL: ****T_CString_stringToInteger(\"100\", 16) failed. Expected: 256, Got: %d\n", intValue);
97     }
98     i = T_CString_integerToString(src, 34556, 10);
99     if(uprv_strcmp(src, "34556") != 0 || i != 5){
100         log_err("FAIL: ****integerToString(src, 34566, 10); failed. Expected: \"34556\", Got: %s\n", src);
101     }
102     i = T_CString_integerToString(src, 431, 16);
103     if(uprv_stricmp(src, "1AF") != 0 || i != 3){
104         log_err("FAIL: ****integerToString(src, 431, 16); failed. Expected: \"1AF\", Got: %s\n", src);
105     }
106     i = T_CString_int64ToString(src, U_INT64_MAX, 10);
107     if(uprv_strcmp(src,  "9223372036854775807") != 0 || i != 19){
108         log_err("FAIL: ****integerToString(src, 9223372036854775807, 10); failed. Got: %s\n", src);
109     }
110     i = T_CString_int64ToString(src, U_INT64_MAX, 16);
111     if(uprv_stricmp(src, "7FFFFFFFFFFFFFFF") != 0 || i != 16){
112         log_err("FAIL: ****integerToString(src, 7FFFFFFFFFFFFFFF, 16); failed. Got: %s\n", src);
113     }
114 
115     uprv_strcpy(src, "this is lower case");
116     if(uprv_stricmp(src, "THIS is lower CASE") != 0){
117         log_err("FAIL: *****uprv_stricmp() failed.");
118     }
119     if((intValue=uprv_stricmp(NULL, "first string is null") )!= -1){
120         log_err("FAIL: uprv_stricmp() where the first string is null failed. Expected: -1, returned %d\n", intValue);
121     }
122     if((intValue=uprv_stricmp("second string is null", NULL)) != 1){
123         log_err("FAIL: uprv_stricmp() where the second string is null failed. Expected: 1, returned %d\n", intValue);
124     }
125     if((intValue=uprv_stricmp(NULL, NULL)) != 0){
126         log_err("FAIL: uprv_stricmp(NULL, NULL) failed.  Expected:  0, returned %d\n", intValue);
127     }
128     if((intValue=uprv_stricmp("", "")) != 0){
129         log_err("FAIL: uprv_stricmp(\"\", \"\") failed.  Expected:  0, returned %d\n", intValue);
130     }
131     if((intValue=uprv_stricmp("", "abc")) != -1){
132         log_err("FAIL: uprv_stricmp(\"\", \"abc\") failed.  Expected: -1, returned %d\n", intValue);
133     }
134     if((intValue=uprv_stricmp("abc", "")) != 1){
135         log_err("FAIL: uprv_stricmp(\"abc\", \"\") failed.  Expected: 1, returned %d\n", intValue);
136     }
137 
138     temp=uprv_strdup("strdup");
139     if(uprv_strcmp(temp, "strdup") !=0 ){
140         log_err("FAIL: uprv_strdup() failed. Expected: \"strdup\", Got: %s\n", temp);
141     }
142     uprv_free((char *)temp);
143 
144     uprv_strcpy(src, "this is lower case");
145     if(uprv_strnicmp(src, "THIS", 4 ) != 0){
146         log_err("FAIL: *****uprv_strnicmp() failed.");
147     }
148     if((intValue=uprv_strnicmp(NULL, "first string is null", 10) )!= -1){
149         log_err("FAIL: uprv_strnicmp() where the first string is null failed. Expected: -1, returned %d\n", intValue);
150     }
151     if((intValue=uprv_strnicmp("second string is null", NULL, 10)) != 1){
152         log_err("FAIL: uprv_strnicmp() where the second string is null failed. Expected: 1, returned %d\n", intValue);
153     }
154     if((intValue=uprv_strnicmp(NULL, NULL, 10)) != 0){
155         log_err("FAIL: uprv_strnicmp(NULL, NULL, 10) failed.  Expected:  0, returned %d\n", intValue);
156     }
157     if((intValue=uprv_strnicmp("", "", 10)) != 0){
158         log_err("FAIL: uprv_strnicmp(\"\", \"\") failed.  Expected:  0, returned %d\n", intValue);
159     }
160     if((intValue=uprv_strnicmp("", "abc", 10)) != -1){
161         log_err("FAIL: uprv_stricmp(\"\", \"abc\", 10) failed.  Expected: -1, returned %d\n", intValue);
162     }
163     if((intValue=uprv_strnicmp("abc", "", 10)) != 1){
164         log_err("FAIL: uprv_strnicmp(\"abc\", \"\", 10) failed.  Expected: 1, returned %d\n", intValue);
165     }
166 
167 }
168 
169 /* test invariant-character handling */
170 static void
TestInvariant()171 TestInvariant() {
172     /* all invariant graphic chars and some control codes (not \n!) */
173     const char invariantChars[]=
174         "\t\r \"%&'()*+,-./"
175         "0123456789:;<=>?"
176         "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"
177         "abcdefghijklmnopqrstuvwxyz";
178 
179     const UChar invariantUChars[]={
180         9, 0xd, 0x20, 0x22, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
181         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
182         0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
183         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5f,
184         0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
185         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0
186     };
187 
188     const char variantChars[]="\n!#$@[\\]^`{|}~";
189 
190     const UChar variantUChars[]={
191         0x0a, 0x21, 0x23, 0x24, 0x40, 0x5b, 0x5c, 0x5d, 0x5e, 0x60, 0x7b, 0x7c, 0x7d, 0x7e, 0
192     };
193 
194     const UChar nonASCIIUChars[]={ 0x80, 0xa0, 0x900, 0xff51 };
195 
196     UChar us[120];
197     char cs[120];
198 
199     int32_t i, length;
200 
201     /* make sure that all invariant characters convert both ways */
202     length=sizeof(invariantChars);
203     u_charsToUChars(invariantChars, us, length);
204     if(u_strcmp(us, invariantUChars)!=0) {
205         log_err("u_charsToUChars(invariantChars) failed\n");
206     }
207 
208     u_UCharsToChars(invariantUChars, cs, length);
209     if(strcmp(cs, invariantChars)!=0) {
210         log_err("u_UCharsToChars(invariantUChars) failed\n");
211     }
212 
213 
214     /*
215      * make sure that variant characters convert from source code literals to Unicode
216      * but not back to char *
217      */
218     length=sizeof(variantChars);
219     u_charsToUChars(variantChars, us, length);
220     if(u_strcmp(us, variantUChars)!=0) {
221         log_err("u_charsToUChars(variantChars) failed\n");
222     }
223 
224 #ifndef U_DEBUG
225     /*
226      * Test u_UCharsToChars(variantUChars) only in release mode because it will
227      * cause an assertion failure in debug builds.
228      */
229     u_UCharsToChars(variantUChars, cs, length);
230     for(i=0; i<length; ++i) {
231         if(cs[i]!=0) {
232             log_err("u_UCharsToChars(variantUChars) converted the %d-th character to %02x instead of 00\n", i, cs[i]);
233         }
234     }
235 #endif
236 
237     /*
238      * Verify that invariant characters roundtrip from Unicode to the
239      * default converter and back.
240      */
241     {
242         UConverter *cnv;
243         UErrorCode errorCode;
244 
245         errorCode=U_ZERO_ERROR;
246         cnv=ucnv_open(NULL, &errorCode);
247         if(U_FAILURE(errorCode)) {
248             log_err("unable to open the default converter\n");
249         } else {
250             length=ucnv_fromUChars(cnv, cs, sizeof(cs), invariantUChars, -1, &errorCode);
251             if(U_FAILURE(errorCode)) {
252                 log_err("ucnv_fromUChars(invariantUChars) failed - %s\n", u_errorName(errorCode));
253             } else if(length!=sizeof(invariantChars)-1 || strcmp(cs, invariantChars)!=0) {
254                 log_err("ucnv_fromUChars(invariantUChars) failed\n");
255             }
256 
257             errorCode=U_ZERO_ERROR;
258             length=ucnv_toUChars(cnv, us, UPRV_LENGTHOF(us), invariantChars, -1, &errorCode);
259             if(U_FAILURE(errorCode)) {
260                 log_err("ucnv_toUChars(invariantChars) failed - %s\n", u_errorName(errorCode));
261             } else if(length!=UPRV_LENGTHOF(invariantUChars)-1 || u_strcmp(us, invariantUChars)!=0) {
262                 log_err("ucnv_toUChars(invariantChars) failed\n");
263             }
264 
265             ucnv_close(cnv);
266         }
267     }
268 
269     /* API tests */
270     if(!uprv_isInvariantString(invariantChars, -1)) {
271         log_err("uprv_isInvariantString(invariantChars) failed\n");
272     }
273     if(!uprv_isInvariantUString(invariantUChars, -1)) {
274         log_err("uprv_isInvariantUString(invariantUChars) failed\n");
275     }
276     if(!uprv_isInvariantString(invariantChars+strlen(invariantChars), 1)) {
277         log_err("uprv_isInvariantString(\"\\0\") failed\n");
278     }
279 
280     for(i=0; i<(int32_t)(sizeof(variantChars)-1); ++i) {
281         if(uprv_isInvariantString(variantChars+i, 1)) {
282             log_err("uprv_isInvariantString(variantChars[%d]) failed\n", i);
283         }
284         if(uprv_isInvariantUString(variantUChars+i, 1)) {
285             log_err("uprv_isInvariantUString(variantUChars[%d]) failed\n", i);
286         }
287     }
288 
289     for(i=0; i<UPRV_LENGTHOF(nonASCIIUChars); ++i) {
290         if(uprv_isInvariantUString(nonASCIIUChars+i, 1)) {
291             log_err("uprv_isInvariantUString(nonASCIIUChars[%d]) failed\n", i);
292         }
293     }
294 }
295 
getSign(int32_t n)296 static int32_t getSign(int32_t n) {
297     if(n<0) {
298         return -1;
299     } else if(n==0) {
300         return 0;
301     } else {
302         return 1;
303     }
304 }
305 
306 static void
TestCompareInvEbcdicAsAscii()307 TestCompareInvEbcdicAsAscii() {
308     static const char *const invStrings[][2]={
309         /* invariant-character strings in ascending ASCII order */
310         /* EBCDIC       native */
311         { "",             "" },
312         { "\x6c",         "%" },
313         { "\xf0",         "0" },
314         { "\xf0\xf0",     "00" },
315         { "\xf0\xf0\x81", "00a" },
316         { "\x7e",         "=" },
317         { "\xc1",         "A" },
318         { "\xc1\xf0\xf0", "A00" },
319         { "\xc1\xf0\xf0", "A00" },
320         { "\xc1\xc1",     "AA" },
321         { "\xc1\xc1\xf0", "AA0" },
322         { "\x6d",         "_" },
323         { "\x81",         "a" },
324         { "\x81\xf0\xf0", "a00" },
325         { "\x81\xf0\xf0", "a00" },
326         { "\x81\x81",     "aa" },
327         { "\x81\x81\xf0", "aa0" },
328         { "\x81\x81\x81", "aaa" },
329         { "\x81\x81\x82", "aab" }
330     };
331     int32_t i;
332     for(i=1; i<UPRV_LENGTHOF(invStrings); ++i) {
333         int32_t diff1, diff2;
334         /* compare previous vs. current */
335         diff1=getSign(uprv_compareInvEbcdicAsAscii(invStrings[i-1][0], invStrings[i][0]));
336         if(diff1>0 || (diff1==0 && 0!=uprv_strcmp(invStrings[i-1][0], invStrings[i][0]))) {
337             log_err("uprv_compareInvEbcdicAsAscii(%s, %s)=%hd is wrong\n",
338                     invStrings[i-1][1], invStrings[i][1], (short)diff1);
339         }
340         /* compare current vs. previous, should be inverse diff */
341         diff2=getSign(uprv_compareInvEbcdicAsAscii(invStrings[i][0], invStrings[i-1][0]));
342         if(diff2!=-diff1) {
343             log_err("uprv_compareInvEbcdicAsAscii(%s, %s)=%hd is wrong\n",
344                     invStrings[i][1], invStrings[i-1][1], (short)diff2);
345         }
346     }
347 }
348 
349 // See U_CHARSET_FAMILY in unicode/platform.h.
350 static const char *nativeInvChars =
351     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
352     "abcdefghijklmnopqrstuvwxyz"
353     "0123456789 \"%&'()*+,-./:;<=>?_";
354 static const UChar *asciiInvChars =
355     u"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
356     u"abcdefghijklmnopqrstuvwxyz"
357     u"0123456789 \"%&'()*+,-./:;<=>?_";
358 
359 static void
TestLocaleAtSign()360 TestLocaleAtSign() {
361     static const char *invLocale = "de-Latn_DE@PHONEBOOK";
362     for (int32_t i = 0;; ++i) {
363         char ic = invLocale[i];
364         if (ic == 0) { break; }
365         UBool expected = i == 10;
366         UBool actual = uprv_isAtSign(ic);
367         if (actual != expected) {
368             log_err("uprv_isAtSign('%c')=%d is wrong\n", ic, (int)actual);
369         }
370     }
371 }
372 
373 // The at sign is not an invariant character.
374 static void
TestNoInvariantAtSign()375 TestNoInvariantAtSign() {
376     for (int32_t i = 0;; ++i) {
377         char ic = nativeInvChars[i];
378         UBool actual = uprv_isAtSign(ic);
379         if (actual) {
380             log_err("uprv_isAtSign(invariant '%c')=TRUE is wrong\n", ic);
381         }
382         if (ic == 0) { break; }
383     }
384 }
385 
386 static void
TestInvCharToAscii()387 TestInvCharToAscii() {
388     for (int32_t i = 0;; ++i) {
389         char ic = nativeInvChars[i];
390         uint8_t ac = asciiInvChars[i];
391         uint8_t actual = uprv_invCharToAscii(ic);
392         if (actual != ac) {
393             log_err("uprv_invCharToAscii('%c') did not convert to ASCII 0x%02x\n", ic, (int)ac);
394         }
395         if (ic == 0) { break; }
396     }
397 }
398