2 * Unit test suite for string functions.
4 * Copyright 2004 Uwe Bonnes
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/test.h"
30 static char *buf_to_string(const unsigned char *bin, int len, int nr)
32 static char buf[2][1024];
36 for (i = 0; i < len; i++)
38 sprintf(w, "%02x ", (unsigned char)bin[i]);
44 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
45 #define expect_bin(buf, value, len) { ok(memcmp((buf), value, len) == 0, "Binary buffer mismatch - expected %s, got %s\n", buf_to_string((unsigned char *)value, len, 1), buf_to_string((buf), len, 0)); }
47 static void* (*pmemcpy)(void *, const void *, size_t n);
48 static int* (*pmemcmp)(void *, const void *, size_t n);
50 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y)
51 #define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y)
55 static void test_swab( void ) {
56 char original[] = "BADCFEHGJILKNMPORQTSVUXWZY@#";
57 char expected1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ@#";
58 char expected2[] = "ABCDEFGHIJKLMNOPQRSTUVWX$";
59 char expected3[] = "$";
66 /* Test 1 - normal even case */
67 memset(to,'$', sizeof(to));
68 memset(from,'@', sizeof(from));
70 memcpy(from, original, testsize);
71 _swab( from, to, testsize );
72 ok(memcmp(to,expected1,testsize) == 0, "Testing even size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
74 /* Test 2 - uneven case */
75 memset(to,'$', sizeof(to));
76 memset(from,'@', sizeof(from));
78 memcpy(from, original, testsize);
79 _swab( from, to, testsize );
80 ok(memcmp(to,expected2,testsize) == 0, "Testing odd size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
82 /* Test 3 - from = to */
83 memset(to,'$', sizeof(to));
84 memset(from,'@', sizeof(from));
86 memcpy(to, original, testsize);
87 _swab( to, to, testsize );
88 ok(memcmp(to,expected1,testsize) == 0, "Testing overlapped size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
90 /* Test 4 - 1 bytes */
91 memset(to,'$', sizeof(to));
92 memset(from,'@', sizeof(from));
94 memcpy(from, original, testsize);
95 _swab( from, to, testsize );
96 ok(memcmp(to,expected3,testsize) == 0, "Testing small size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
99 #if 0 /* use this to generate more tests */
101 static void test_codepage(int cp)
107 ok(_setmbcp(cp) == 0, "Couldn't set mbcp\n");
110 printf("static int result_cp_%d_mbctype[] = { ", cp);
111 for (i = 1; i < 257; i++)
113 if (_mbctype[i] != prev)
115 printf("0x%x,%d, ", prev, count);
122 printf("0x%x,%d };\n", prev, count);
125 #define test_codepage_todo(cp, todo) test_codepage(cp)
129 /* RLE-encoded mbctype tables for given codepages */
130 static int result_cp_1252_mbctype[] = { 0x0,66, 0x10,26, 0x0,6, 0x20,26, 0x0,8, 0x20,1,
131 0x0,6, 0x10,1, 0x0,1, 0x10,1, 0x0,1, 0x10,1, 0x0,11, 0x20,1, 0x0,1, 0x20,1, 0x0,1,
132 0x20,1, 0x10,1, 0x0,10, 0x20,1, 0x0,10, 0x20,1, 0x0,4, 0x20,1, 0x0,5, 0x10,23, 0x0,1,
133 0x10,7, 0x20,24, 0x0,1, 32,8 };
134 static int result_cp_1250_mbctype[] = { 0x0,66, 0x10,26, 0x0,6, 0x20,26, 0x0,15, 0x10,1,
135 0x0,1, 0x10,4, 0x0,10, 0x20,1, 0x0,1, 0x20,4, 0x0,3, 0x10,1, 0x0,1, 0x10,1, 0x0,4,
136 0x10,1, 0x0,4, 0x10,1, 0x0,3, 0x20,1, 0x0,1, 0x20,1, 0x0,3, 0x20,2, 0x0,1, 0x10,1,
137 0x0,1, 0x20,2, 0x10,23, 0x0,1, 0x10,7, 0x20,24, 0x0,1, 0x20,7, 0,1 };
138 static int result_cp_932_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,4,
139 0x0,1, 0x8,1, 0xc,31, 0x8,1, 0xa,5, 0x9,58, 0xc,29, 0,3 };
140 static int result_cp_936_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,6,
142 static int result_cp_949_mbctype[] = { 0x0,66, 0x18,26, 0x8,6, 0x28,26, 0x8,6, 0xc,126,
144 static int result_cp_950_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,4,
145 0x0,2, 0x4,32, 0xc,94, 0,1 };
146 static int result_cp_20932_mbctype[] = { 0x0,2, 0x8,64, 0x18,26, 0x8,6, 0x28,26, 0x8,19,
147 0xc,1, 0x8,18, 0xc,94, 0,1 };
149 static int todo_none[] = { -2 };
150 static int todo_cp_932[] = { 254, -2 };
151 static int todo_cp_20932[] = { 143, -2 };
153 void test_cp_table(int cp, int *result, int *todo)
159 for (i = 0; i < 256; i++)
169 todo_wine ok(_mbctype[i] == curr, "CP%d: Mismatch in ctype for character %d - %d instead of %d\n", cp, i-1, _mbctype[i], curr);
173 ok(_mbctype[i] == curr, "CP%d: Mismatch in ctype for character %d - %d instead of %d\n", cp, i-1, _mbctype[i], curr);
178 #define test_codepage(num) test_cp_table(num, result_cp_##num##_mbctype, todo_none);
179 #define test_codepage_todo(num, todo) test_cp_table(num, result_cp_##num##_mbctype, todo);
183 static void test_mbcp(void)
185 int mb_orig_max = __mb_cur_max;
186 int curr_mbcp = _getmbcp();
187 unsigned char *mbstring = (unsigned char *)"\xb0\xb1\xb2 \xb3\xb4 \xb5"; /* incorrect string */
188 unsigned char *mbstring2 = (unsigned char *)"\xb0\xb1\xb2\xb3Q\xb4\xb5"; /* correct string */
189 unsigned char *mbsonlylead = (unsigned char *)"\xb0\0\xb1\xb2";
190 unsigned char buf[16];
192 /* some two single-byte code pages*/
195 /* double byte code pages */
196 test_codepage_todo(932, todo_cp_932);
200 test_codepage_todo(20932, todo_cp_20932);
203 ok(__mb_cur_max == mb_orig_max, "__mb_cur_max shouldn't be updated (is %d != %d)\n", __mb_cur_max, mb_orig_max);
204 ok(_ismbblead('\354'), "\354 should be a lead byte\n");
205 ok(_ismbblead(' ') == FALSE, "' ' should not be a lead byte\n");
206 ok(_ismbblead(0x1234b0), "0x1234b0 should not be a lead byte\n");
207 ok(_ismbblead(0x123420) == FALSE, "0x123420 should not be a lead byte\n");
208 ok(_ismbbtrail('\xb0'), "\xa0 should be a trail byte\n");
209 ok(_ismbbtrail(' ') == FALSE, "' ' should not be a trail byte\n");
212 expect_eq(_mbsnextc(mbstring), 0xb0b1, int, "%x");
213 expect_eq(_mbsnextc(&mbstring[2]), 0xb220, int, "%x"); /* lead + invalid tail */
214 expect_eq(_mbsnextc(&mbstring[3]), 0x20, int, "%x"); /* single char */
216 /* _mbclen/_mbslen */
217 expect_eq(_mbclen(mbstring), 2, int, "%d");
218 expect_eq(_mbclen(&mbstring[2]), 2, int, "%d");
219 expect_eq(_mbclen(&mbstring[3]), 1, int, "%d");
220 expect_eq(_mbslen(mbstring2), 4, int, "%d");
221 expect_eq(_mbslen(mbsonlylead), 0, int, "%d"); /* lead + NUL not counted as character */
222 expect_eq(_mbslen(mbstring), 4, int, "%d"); /* lead + invalid trail counted */
224 /* _mbccpy/_mbsncpy */
225 memset(buf, 0xff, sizeof(buf));
226 _mbccpy(buf, mbstring);
227 expect_bin(buf, "\xb0\xb1\xff", 3);
229 memset(buf, 0xff, sizeof(buf));
230 _mbsncpy(buf, mbstring, 1);
231 expect_bin(buf, "\xb0\xb1\xff", 3);
232 memset(buf, 0xff, sizeof(buf));
233 _mbsncpy(buf, mbstring, 2);
234 expect_bin(buf, "\xb0\xb1\xb2 \xff", 5);
235 memset(buf, 0xff, sizeof(buf));
236 _mbsncpy(buf, mbstring, 3);
237 expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4\xff", 7);
238 memset(buf, 0xff, sizeof(buf));
239 _mbsncpy(buf, mbstring, 4);
240 expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4 \xff", 8);
241 memset(buf, 0xff, sizeof(buf));
242 _mbsncpy(buf, mbstring, 5);
243 expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4 \0\0\xff", 10);
244 memset(buf, 0xff, sizeof(buf));
245 _mbsncpy(buf, mbsonlylead, 6);
246 expect_bin(buf, "\0\0\0\0\0\0\0\xff", 8);
248 memset(buf, 0xff, sizeof(buf));
249 _mbsnbcpy(buf, mbstring2, 2);
250 expect_bin(buf, "\xb0\xb1\xff", 3);
251 _mbsnbcpy(buf, mbstring2, 3);
252 expect_bin(buf, "\xb0\xb1\0\xff", 4);
253 _mbsnbcpy(buf, mbstring2, 4);
254 expect_bin(buf, "\xb0\xb1\xb2\xb3\xff", 5);
255 memset(buf, 0xff, sizeof(buf));
256 _mbsnbcpy(buf, mbsonlylead, 5);
257 expect_bin(buf, "\0\0\0\0\0\xff", 6);
259 /* functions that depend on locale codepage, not mbcp.
260 * we hope the current locale to be SBCS because setlocale(LC_ALL, ".1252") seems not to work yet
261 * (as of Wine 0.9.43)
263 if (__mb_cur_max == 1)
265 expect_eq(mblen((char *)mbstring, 3), 1, int, "%x");
266 expect_eq(_mbstrlen((char *)mbstring2), 7, int, "%d");
269 skip("Current locale has double-byte charset - could leave to false positives\n");
274 static void test_mbsspn( void)
276 unsigned char str1[]="cabernet";
277 unsigned char str2[]="shiraz";
278 unsigned char set[]="abc";
279 unsigned char empty[]="";
281 ret=_mbsspn( str1, set);
282 ok( ret==3, "_mbsspn returns %d should be 3\n", ret);
283 ret=_mbsspn( str2, set);
284 ok( ret==0, "_mbsspn returns %d should be 0\n", ret);
285 ret=_mbsspn( str1, empty);
286 ok( ret==0, "_mbsspn returns %d should be 0\n", ret);
289 static void test_mbsspnp( void)
291 unsigned char str1[]="cabernet";
292 unsigned char str2[]="shiraz";
293 unsigned char set[]="abc";
294 unsigned char empty[]="";
295 unsigned char full[]="abcenrt";
297 ret=_mbsspnp( str1, set);
298 ok( ret[0]=='e', "_mbsspnp returns %c should be e\n", ret[0]);
299 ret=_mbsspnp( str2, set);
300 ok( ret[0]=='s', "_mbsspnp returns %c should be s\n", ret[0]);
301 ret=_mbsspnp( str1, empty);
302 ok( ret[0]=='c', "_mbsspnp returns %c should be c\n", ret[0]);
303 ret=_mbsspnp( str1, full);
304 ok( ret==NULL, "_mbsspnp returns %p should be NULL\n", ret);
307 static void test_strdup(void)
311 ok( str == 0, "strdup returns %s should be 0\n", str);
318 static const char xilstring[]="c:/xilinx";
321 hMsvcrt = GetModuleHandleA("msvcrt.dll");
323 hMsvcrt = GetModuleHandleA("msvcrtd.dll");
324 ok(hMsvcrt != 0, "GetModuleHandleA failed\n");
325 SET(pmemcpy,"memcpy");
326 SET(pmemcmp,"memcmp");
328 /* MSVCRT memcpy behaves like memmove for overlapping moves,
329 MFC42 CString::Insert seems to rely on that behaviour */
331 ok(mem != NULL, "memory not allocated for size 0\n");
332 strcpy((char*)mem,xilstring);
333 nLen=strlen(xilstring);
334 pmemcpy((char*)mem+5, mem,nLen+1);
335 ok(pmemcmp((char*)mem+5,xilstring, nLen) == 0,
336 "Got result %s\n",(char*)mem+5);
338 /* Test _swab function */