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