msvcrt: Test and fix _mbsnextc.
[wine/gsoc_dplay.git] / dlls / msvcrt / tests / string.c
blob8b55cf3c89faa112b1878ef4bf536055bb73f5e9
1 /*
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"
22 #include "winbase.h"
23 #include <string.h>
24 #include <mbstring.h>
25 #include <stdlib.h>
26 #include <mbctype.h>
28 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
30 static void* (*pmemcpy)(void *, const void *, size_t n);
31 static int* (*pmemcmp)(void *, const void *, size_t n);
33 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y)
34 #define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y)
36 static void test_swab( void ) {
37 char original[] = "BADCFEHGJILKNMPORQTSVUXWZY@#";
38 char expected1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ@#";
39 char expected2[] = "ABCDEFGHIJKLMNOPQRSTUVWX$";
40 char expected3[] = "$";
42 char from[30];
43 char to[30];
45 int testsize;
47 /* Test 1 - normal even case */
48 memset(to,'$', sizeof(to));
49 memset(from,'@', sizeof(from));
50 testsize = 26;
51 memcpy(from, original, testsize);
52 _swab( from, to, testsize );
53 ok(memcmp(to,expected1,testsize) == 0, "Testing even size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
55 /* Test 2 - uneven case */
56 memset(to,'$', sizeof(to));
57 memset(from,'@', sizeof(from));
58 testsize = 25;
59 memcpy(from, original, testsize);
60 _swab( from, to, testsize );
61 ok(memcmp(to,expected2,testsize) == 0, "Testing odd size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
63 /* Test 3 - from = to */
64 memset(to,'$', sizeof(to));
65 memset(from,'@', sizeof(from));
66 testsize = 26;
67 memcpy(to, original, testsize);
68 _swab( to, to, testsize );
69 ok(memcmp(to,expected1,testsize) == 0, "Testing overlapped size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
71 /* Test 4 - 1 bytes */
72 memset(to,'$', sizeof(to));
73 memset(from,'@', sizeof(from));
74 testsize = 1;
75 memcpy(from, original, testsize);
76 _swab( from, to, testsize );
77 ok(memcmp(to,expected3,testsize) == 0, "Testing small size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
80 #if 0 /* use this to generate more tests */
82 static void test_codepage(int cp)
84 int i;
85 int prev;
86 int count = 1;
88 ok(_setmbcp(cp) == 0, "Couldn't set mbcp\n");
90 prev = _mbctype[0];
91 printf("static int result_cp_%d_mbctype[] = { ", cp);
92 for (i = 1; i < 257; i++)
94 if (_mbctype[i] != prev)
96 printf("0x%x,%d, ", prev, count);
97 prev = _mbctype[i];
98 count = 1;
100 else
101 count++;
103 printf("0x%x,%d };\n", prev, count);
106 #define test_codepage_todo(cp, todo) test_codepage(cp)
108 #else
110 /* RLE-encoded mbctype tables for given codepages */
111 static int result_cp_1252_mbctype[] = { 0x0,66, 0x10,26, 0x0,6, 0x20,26, 0x0,8, 0x20,1,
112 0x0,6, 0x10,1, 0x0,1, 0x10,1, 0x0,1, 0x10,1, 0x0,11, 0x20,1, 0x0,1, 0x20,1, 0x0,1,
113 0x20,1, 0x10,1, 0x0,10, 0x20,1, 0x0,10, 0x20,1, 0x0,4, 0x20,1, 0x0,5, 0x10,23, 0x0,1,
114 0x10,7, 0x20,24, 0x0,1, 32,8 };
115 static int result_cp_1250_mbctype[] = { 0x0,66, 0x10,26, 0x0,6, 0x20,26, 0x0,15, 0x10,1,
116 0x0,1, 0x10,4, 0x0,10, 0x20,1, 0x0,1, 0x20,4, 0x0,3, 0x10,1, 0x0,1, 0x10,1, 0x0,4,
117 0x10,1, 0x0,4, 0x10,1, 0x0,3, 0x20,1, 0x0,1, 0x20,1, 0x0,3, 0x20,2, 0x0,1, 0x10,1,
118 0x0,1, 0x20,2, 0x10,23, 0x0,1, 0x10,7, 0x20,24, 0x0,1, 0x20,7, 0,1 };
119 static int result_cp_932_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,4,
120 0x0,1, 0x8,1, 0xc,31, 0x8,1, 0xa,5, 0x9,58, 0xc,29, 0,3 };
121 static int result_cp_936_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,6,
122 0xc,126, 0,1 };
123 static int result_cp_949_mbctype[] = { 0x0,66, 0x18,26, 0x8,6, 0x28,26, 0x8,6, 0xc,126,
124 0,1 };
125 static int result_cp_950_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,4,
126 0x0,2, 0x4,32, 0xc,94, 0,1 };
127 static int result_cp_20932_mbctype[] = { 0x0,2, 0x8,64, 0x18,26, 0x8,6, 0x28,26, 0x8,19,
128 0xc,1, 0x8,18, 0xc,94, 0,1 };
130 static int todo_none[] = { -2 };
131 static int todo_cp_932[] = { 254, -2 };
132 static int todo_cp_20932[] = { 143, -2 };
134 void test_cp_table(int cp, int *result, int *todo)
136 int i;
137 int count = 0;
138 int curr = 0;
139 _setmbcp(cp);
140 for (i = 0; i < 256; i++)
142 if (count == 0)
144 curr = result[0];
145 count = result[1];
146 result += 2;
148 if (i == *todo + 1)
150 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);
151 todo++;
153 else
154 ok(_mbctype[i] == curr, "CP%d: Mismatch in ctype for character %d - %d instead of %d\n", cp, i-1, _mbctype[i], curr);
155 count--;
159 #define test_codepage(num) test_cp_table(num, result_cp_##num##_mbctype, todo_none);
160 #define test_codepage_todo(num, todo) test_cp_table(num, result_cp_##num##_mbctype, todo);
162 #endif
164 static void test_mbcp(void)
166 int mb_orig_max = __mb_cur_max;
167 int curr_mbcp = _getmbcp();
168 unsigned char *mbstring = (unsigned char *)"\xb0\xb1\xb2 \xb3\xb4 \xb5"; /* incorrect string */
170 /* some two single-byte code pages*/
171 test_codepage(1252);
172 test_codepage(1250);
173 /* double byte code pages */
174 test_codepage_todo(932, todo_cp_932);
175 test_codepage(936);
176 test_codepage(949);
177 test_codepage(950);
178 test_codepage_todo(20932, todo_cp_20932);
180 _setmbcp(936);
181 ok(__mb_cur_max == mb_orig_max, "__mb_cur_max shouldn't be updated (is %d != %d)\n", __mb_cur_max, mb_orig_max);
182 ok(_ismbblead('\354'), "\354 should be a lead byte\n");
183 ok(_ismbblead(' ') == FALSE, "' ' should not be a lead byte\n");
184 ok(_ismbblead(0x1234b0), "0x1234b0 should not be a lead byte\n");
185 ok(_ismbblead(0x123420) == FALSE, "0x123420 should not be a lead byte\n");
186 ok(_ismbbtrail('\xb0'), "\xa0 should be a trail byte\n");
187 ok(_ismbbtrail(' ') == FALSE, "' ' should not be a trail byte\n");
190 /* _mbsnextc */
191 expect_eq(_mbsnextc(mbstring), 0xb0b1, int, "%x");
192 expect_eq(_mbsnextc(&mbstring[2]), 0xb220, int, "%x"); /* lead + invalid tail */
193 expect_eq(_mbsnextc(&mbstring[3]), 0x20, int, "%x"); /* single char */
195 _setmbcp(curr_mbcp);
198 static void test_mbsspn( void)
200 unsigned char str1[]="cabernet";
201 unsigned char str2[]="shiraz";
202 unsigned char set[]="abc";
203 unsigned char empty[]="";
204 int ret;
205 ret=_mbsspn( str1, set);
206 ok( ret==3, "_mbsspn returns %d should be 3\n", ret);
207 ret=_mbsspn( str2, set);
208 ok( ret==0, "_mbsspn returns %d should be 0\n", ret);
209 ret=_mbsspn( str1, empty);
210 ok( ret==0, "_mbsspn returns %d should be 0\n", ret);
213 static void test_mbsspnp( void)
215 unsigned char str1[]="cabernet";
216 unsigned char str2[]="shiraz";
217 unsigned char set[]="abc";
218 unsigned char empty[]="";
219 unsigned char full[]="abcenrt";
220 unsigned char* ret;
221 ret=_mbsspnp( str1, set);
222 ok( ret[0]=='e', "_mbsspnp returns %c should be e\n", ret[0]);
223 ret=_mbsspnp( str2, set);
224 ok( ret[0]=='s', "_mbsspnp returns %c should be s\n", ret[0]);
225 ret=_mbsspnp( str1, empty);
226 ok( ret[0]=='c', "_mbsspnp returns %c should be c\n", ret[0]);
227 ret=_mbsspnp( str1, full);
228 ok( ret==NULL, "_mbsspnp returns %p should be NULL\n", ret);
231 static void test_strdup(void)
233 char *str;
234 str = _strdup( 0 );
235 ok( str == 0, "strdup returns %s should be 0\n", str);
236 free( str );
239 START_TEST(string)
241 void *mem;
242 static const char xilstring[]="c:/xilinx";
243 int nLen;
244 HMODULE hMsvcrt;
246 hMsvcrt = GetModuleHandleA("msvcrt.dll");
247 if (!hMsvcrt)
248 hMsvcrt = GetModuleHandleA("msvcrtd.dll");
249 ok(hMsvcrt != 0, "GetModuleHandleA failed\n");
250 SET(pmemcpy,"memcpy");
251 SET(pmemcmp,"memcmp");
253 /* MSVCRT memcpy behaves like memmove for overlapping moves,
254 MFC42 CString::Insert seems to rely on that behaviour */
255 mem = malloc(100);
256 ok(mem != NULL, "memory not allocated for size 0\n");
257 strcpy((char*)mem,xilstring);
258 nLen=strlen(xilstring);
259 pmemcpy((char*)mem+5, mem,nLen+1);
260 ok(pmemcmp((char*)mem+5,xilstring, nLen) == 0,
261 "Got result %s\n",(char*)mem+5);
263 /* Test _swab function */
264 test_swab();
266 /* Test ismbblead*/
267 test_mbcp();
268 /* test _mbsspn */
269 test_mbsspn();
270 test_mbsspnp();
271 /* test _strdup */
272 test_strdup();