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