9de0039fe9ff6b965366bb55766672fe4d542ddb
[reactos.git] / modules / rostests / winetests / ntdll / string.c
1 /* Unit test suite for string functions and some wcstring functions
2 *
3 * Copyright 2003 Thomas Mertes
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 *
19 * NOTES
20 * We use function pointers here as there is no import library for NTDLL on
21 * windows.
22 */
23
24 #include "ntdll_test.h"
25
26 /* Function ptrs for ntdll calls */
27 static HMODULE hntdll = 0;
28 static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);
29 static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING);
30 static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING,LPCSTR);
31 static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
32
33 static int (WINAPIV *patoi)(const char *);
34 static long (WINAPIV *patol)(const char *);
35 static LONGLONG (WINAPIV *p_atoi64)(const char *);
36 static LPSTR (WINAPIV *p_itoa)(int, LPSTR, INT);
37 static LPSTR (WINAPIV *p_ltoa)(LONG, LPSTR, INT);
38 static LPSTR (WINAPIV *p_ultoa)(ULONG, LPSTR, INT);
39 static LPSTR (WINAPIV *p_i64toa)(LONGLONG, LPSTR, INT);
40 static LPSTR (WINAPIV *p_ui64toa)(ULONGLONG, LPSTR, INT);
41
42 static int (WINAPIV *p_wtoi)(LPWSTR);
43 static long (WINAPIV *p_wtol)(LPWSTR);
44 static LONGLONG (WINAPIV *p_wtoi64)(LPWSTR);
45 static LPWSTR (WINAPIV *p_itow)(int, LPWSTR, int);
46 static LPWSTR (WINAPIV *p_ltow)(LONG, LPWSTR, INT);
47 static LPWSTR (WINAPIV *p_ultow)(ULONG, LPWSTR, INT);
48 static LPWSTR (WINAPIV *p_i64tow)(LONGLONG, LPWSTR, INT);
49 static LPWSTR (WINAPIV *p_ui64tow)(ULONGLONG, LPWSTR, INT);
50
51 static LPWSTR (__cdecl *p_wcslwr)(LPWSTR);
52 static LPWSTR (__cdecl *p_wcsupr)(LPWSTR);
53
54 static LPWSTR (WINAPIV *p_wcschr)(LPCWSTR, WCHAR);
55 static LPWSTR (WINAPIV *p_wcsrchr)(LPCWSTR, WCHAR);
56
57 static void (__cdecl *p_qsort)(void *,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
58 static void* (__cdecl *p_bsearch)(void *,void*,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
59 static int (__cdecl *p__snprintf)(char *, size_t, const char *, ...);
60
61
62 static void InitFunctionPtrs(void)
63 {
64 hntdll = LoadLibraryA("ntdll.dll");
65 ok(hntdll != 0, "LoadLibrary failed\n");
66 if (hntdll) {
67 pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString");
68 pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString");
69 pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
70 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
71
72 patoi = (void *)GetProcAddress(hntdll, "atoi");
73 patol = (void *)GetProcAddress(hntdll, "atol");
74 p_atoi64 = (void *)GetProcAddress(hntdll, "_atoi64");
75 p_itoa = (void *)GetProcAddress(hntdll, "_itoa");
76 p_ltoa = (void *)GetProcAddress(hntdll, "_ltoa");
77 p_ultoa = (void *)GetProcAddress(hntdll, "_ultoa");
78 p_i64toa = (void *)GetProcAddress(hntdll, "_i64toa");
79 p_ui64toa = (void *)GetProcAddress(hntdll, "_ui64toa");
80
81 p_wtoi = (void *)GetProcAddress(hntdll, "_wtoi");
82 p_wtol = (void *)GetProcAddress(hntdll, "_wtol");
83 p_wtoi64 = (void *)GetProcAddress(hntdll, "_wtoi64");
84 p_itow = (void *)GetProcAddress(hntdll, "_itow");
85 p_ltow = (void *)GetProcAddress(hntdll, "_ltow");
86 p_ultow = (void *)GetProcAddress(hntdll, "_ultow");
87 p_i64tow = (void *)GetProcAddress(hntdll, "_i64tow");
88 p_ui64tow = (void *)GetProcAddress(hntdll, "_ui64tow");
89
90 p_wcslwr = (void *)GetProcAddress(hntdll, "_wcslwr");
91 p_wcsupr = (void *)GetProcAddress(hntdll, "_wcsupr");
92
93 p_wcschr= (void *)GetProcAddress(hntdll, "wcschr");
94 p_wcsrchr= (void *)GetProcAddress(hntdll, "wcsrchr");
95 p_qsort= (void *)GetProcAddress(hntdll, "qsort");
96 p_bsearch= (void *)GetProcAddress(hntdll, "bsearch");
97
98 p__snprintf = (void *)GetProcAddress(hntdll, "_snprintf");
99 } /* if */
100 }
101
102
103 #define LARGE_STRI_BUFFER_LENGTH 67
104
105 typedef struct {
106 int base;
107 ULONG value;
108 const char *Buffer;
109 int mask; /* ntdll/msvcrt: 0x01=itoa, 0x02=ltoa, 0x04=ultoa */
110 /* 0x10=itow, 0x20=ltow, 0x40=ultow */
111 } ulong2str_t;
112
113 static const ulong2str_t ulong2str[] = {
114 {10, 123, "123\0---------------------------------------------------------------", 0x77},
115
116 { 2, 0x80000000U, "10000000000000000000000000000000\0----------------------------------", 0x67},
117 { 2, -2147483647, "10000000000000000000000000000001\0----------------------------------", 0x67},
118 { 2, -65537, "11111111111111101111111111111111\0----------------------------------", 0x67},
119 { 2, -65536, "11111111111111110000000000000000\0----------------------------------", 0x67},
120 { 2, -65535, "11111111111111110000000000000001\0----------------------------------", 0x67},
121 { 2, -32768, "11111111111111111000000000000000\0----------------------------------", 0x67},
122 { 2, -32767, "11111111111111111000000000000001\0----------------------------------", 0x67},
123 { 2, -2, "11111111111111111111111111111110\0----------------------------------", 0x67},
124 { 2, -1, "11111111111111111111111111111111\0----------------------------------", 0x67},
125 { 2, 0, "0\0-----------------------------------------------------------------", 0x77},
126 { 2, 1, "1\0-----------------------------------------------------------------", 0x77},
127 { 2, 10, "1010\0--------------------------------------------------------------", 0x77},
128 { 2, 100, "1100100\0-----------------------------------------------------------", 0x77},
129 { 2, 1000, "1111101000\0--------------------------------------------------------", 0x77},
130 { 2, 10000, "10011100010000\0----------------------------------------------------", 0x77},
131 { 2, 32767, "111111111111111\0---------------------------------------------------", 0x77},
132 { 2, 32768, "1000000000000000\0--------------------------------------------------", 0x77},
133 { 2, 65535, "1111111111111111\0--------------------------------------------------", 0x77},
134 { 2, 100000, "11000011010100000\0-------------------------------------------------", 0x77},
135 { 2, 234567, "111001010001000111\0------------------------------------------------", 0x77},
136 { 2, 300000, "1001001001111100000\0-----------------------------------------------", 0x77},
137 { 2, 524287, "1111111111111111111\0-----------------------------------------------", 0x77},
138 { 2, 524288, "10000000000000000000\0----------------------------------------------", 0x67},
139 { 2, 1000000, "11110100001001000000\0----------------------------------------------", 0x67},
140 { 2, 10000000, "100110001001011010000000\0------------------------------------------", 0x67},
141 { 2, 100000000, "101111101011110000100000000\0---------------------------------------", 0x67},
142 { 2, 1000000000, "111011100110101100101000000000\0------------------------------------", 0x67},
143 { 2, 1073741823, "111111111111111111111111111111\0------------------------------------", 0x67},
144 { 2, 2147483646, "1111111111111111111111111111110\0-----------------------------------", 0x67},
145 { 2, 2147483647, "1111111111111111111111111111111\0-----------------------------------", 0x67},
146 { 2, 2147483648U, "10000000000000000000000000000000\0----------------------------------", 0x67},
147 { 2, 2147483649U, "10000000000000000000000000000001\0----------------------------------", 0x67},
148 { 2, 4294967294U, "11111111111111111111111111111110\0----------------------------------", 0x67},
149 { 2, 0xFFFFFFFF, "11111111111111111111111111111111\0----------------------------------", 0x67},
150
151 { 8, 0x80000000U, "20000000000\0-------------------------------------------------------", 0x77},
152 { 8, -2147483647, "20000000001\0-------------------------------------------------------", 0x77},
153 { 8, -2, "37777777776\0-------------------------------------------------------", 0x77},
154 { 8, -1, "37777777777\0-------------------------------------------------------", 0x77},
155 { 8, 0, "0\0-----------------------------------------------------------------", 0x77},
156 { 8, 1, "1\0-----------------------------------------------------------------", 0x77},
157 { 8, 2147483646, "17777777776\0-------------------------------------------------------", 0x77},
158 { 8, 2147483647, "17777777777\0-------------------------------------------------------", 0x77},
159 { 8, 2147483648U, "20000000000\0-------------------------------------------------------", 0x77},
160 { 8, 2147483649U, "20000000001\0-------------------------------------------------------", 0x77},
161 { 8, 4294967294U, "37777777776\0-------------------------------------------------------", 0x77},
162 { 8, 4294967295U, "37777777777\0-------------------------------------------------------", 0x77},
163
164 {10, 0x80000000U, "-2147483648\0-------------------------------------------------------", 0x33},
165 {10, 0x80000000U, "2147483648\0--------------------------------------------------------", 0x44},
166 {10, -2147483647, "-2147483647\0-------------------------------------------------------", 0x33},
167 {10, -2147483647, "2147483649\0--------------------------------------------------------", 0x44},
168 {10, -2, "-2\0----------------------------------------------------------------", 0x33},
169 {10, -2, "4294967294\0--------------------------------------------------------", 0x44},
170 {10, -1, "-1\0----------------------------------------------------------------", 0x33},
171 {10, -1, "4294967295\0--------------------------------------------------------", 0x44},
172 {10, 0, "0\0-----------------------------------------------------------------", 0x77},
173 {10, 1, "1\0-----------------------------------------------------------------", 0x77},
174 {10, 12, "12\0----------------------------------------------------------------", 0x77},
175 {10, 123, "123\0---------------------------------------------------------------", 0x77},
176 {10, 1234, "1234\0--------------------------------------------------------------", 0x77},
177 {10, 12345, "12345\0-------------------------------------------------------------", 0x77},
178 {10, 123456, "123456\0------------------------------------------------------------", 0x77},
179 {10, 1234567, "1234567\0-----------------------------------------------------------", 0x77},
180 {10, 12345678, "12345678\0----------------------------------------------------------", 0x77},
181 {10, 123456789, "123456789\0---------------------------------------------------------", 0x77},
182 {10, 2147483646, "2147483646\0--------------------------------------------------------", 0x77},
183 {10, 2147483647, "2147483647\0--------------------------------------------------------", 0x77},
184 {10, 2147483648U, "-2147483648\0-------------------------------------------------------", 0x33},
185 {10, 2147483648U, "2147483648\0--------------------------------------------------------", 0x44},
186 {10, 2147483649U, "-2147483647\0-------------------------------------------------------", 0x33},
187 {10, 2147483649U, "2147483649\0--------------------------------------------------------", 0x44},
188 {10, 4294967294U, "-2\0----------------------------------------------------------------", 0x33},
189 {10, 4294967294U, "4294967294\0--------------------------------------------------------", 0x44},
190 {10, 4294967295U, "-1\0----------------------------------------------------------------", 0x33},
191 {10, 4294967295U, "4294967295\0--------------------------------------------------------", 0x44},
192
193 {16, 0, "0\0-----------------------------------------------------------------", 0x77},
194 {16, 1, "1\0-----------------------------------------------------------------", 0x77},
195 {16, 2147483646, "7ffffffe\0----------------------------------------------------------", 0x77},
196 {16, 2147483647, "7fffffff\0----------------------------------------------------------", 0x77},
197 {16, 0x80000000, "80000000\0----------------------------------------------------------", 0x77},
198 {16, 0x80000001, "80000001\0----------------------------------------------------------", 0x77},
199 {16, 0xFFFFFFFE, "fffffffe\0----------------------------------------------------------", 0x77},
200 {16, 0xFFFFFFFF, "ffffffff\0----------------------------------------------------------", 0x77},
201
202 { 2, 32768, "1000000000000000\0--------------------------------------------------", 0x77},
203 { 2, 65536, "10000000000000000\0-------------------------------------------------", 0x77},
204 { 2, 131072, "100000000000000000\0------------------------------------------------", 0x77},
205 {16, 0xffffffff, "ffffffff\0----------------------------------------------------------", 0x77},
206 {16, 0xa, "a\0-----------------------------------------------------------------", 0x77},
207 {16, 0, "0\0-----------------------------------------------------------------", 0x77},
208 {20, 3368421, "111111\0------------------------------------------------------------", 0x77},
209 {36, 62193781, "111111\0------------------------------------------------------------", 0x77},
210 {37, 71270178, "111111\0------------------------------------------------------------", 0x77},
211 };
212 #define NB_ULONG2STR (sizeof(ulong2str)/sizeof(*ulong2str))
213
214
215 static void one_itoa_test(int test_num, const ulong2str_t *ulong2str)
216 {
217 char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
218 int value;
219 LPSTR result;
220
221 memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
222 dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
223 value = ulong2str->value;
224 result = p_itoa(value, dest_str, ulong2str->base);
225 ok(result == dest_str,
226 "(test %d): _itoa(%d, [out], %d) has result %p, expected: %p\n",
227 test_num, value, ulong2str->base, result, dest_str);
228 ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
229 "(test %d): _itoa(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
230 test_num, value, ulong2str->base, dest_str, ulong2str->Buffer);
231 }
232
233
234 static void one_ltoa_test(int test_num, const ulong2str_t *ulong2str)
235 {
236 char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
237 LONG value;
238 LPSTR result;
239
240 memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
241 dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
242 value = ulong2str->value;
243 result = p_ltoa(ulong2str->value, dest_str, ulong2str->base);
244 ok(result == dest_str,
245 "(test %d): _ltoa(%d, [out], %d) has result %p, expected: %p\n",
246 test_num, value, ulong2str->base, result, dest_str);
247 ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
248 "(test %d): _ltoa(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
249 test_num, value, ulong2str->base, dest_str, ulong2str->Buffer);
250 }
251
252
253 static void one_ultoa_test(int test_num, const ulong2str_t *ulong2str)
254 {
255 char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
256 ULONG value;
257 LPSTR result;
258
259 memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
260 dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
261 value = ulong2str->value;
262 result = p_ultoa(ulong2str->value, dest_str, ulong2str->base);
263 ok(result == dest_str,
264 "(test %d): _ultoa(%u, [out], %d) has result %p, expected: %p\n",
265 test_num, value, ulong2str->base, result, dest_str);
266 ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
267 "(test %d): _ultoa(%u, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
268 test_num, value, ulong2str->base, dest_str, ulong2str->Buffer);
269 }
270
271
272 static void test_ulongtoa(void)
273 {
274 int test_num;
275
276 for (test_num = 0; test_num < NB_ULONG2STR; test_num++) {
277 if (ulong2str[test_num].mask & 0x01) {
278 one_itoa_test(test_num, &ulong2str[test_num]);
279 } /* if */
280 if (ulong2str[test_num].mask & 0x02) {
281 one_ltoa_test(test_num, &ulong2str[test_num]);
282 } /* if */
283 if (ulong2str[test_num].mask & 0x04) {
284 one_ultoa_test(test_num, &ulong2str[test_num]);
285 } /* if */
286 } /* for */
287 }
288
289
290 static void one_itow_test(int test_num, const ulong2str_t *ulong2str)
291 {
292 int pos;
293 WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
294 WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
295 UNICODE_STRING unicode_string;
296 STRING ansi_str;
297 int value;
298 LPWSTR result;
299
300 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
301 expected_wstr[pos] = ulong2str->Buffer[pos];
302 } /* for */
303 expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
304
305 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
306 dest_wstr[pos] = '-';
307 } /* for */
308 dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
309 unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
310 unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
311 unicode_string.Buffer = dest_wstr;
312 value = ulong2str->value;
313 result = p_itow(value, dest_wstr, ulong2str->base);
314 pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
315 ok(result == dest_wstr,
316 "(test %d): _itow(%d, [out], %d) has result %p, expected: %p\n",
317 test_num, value, ulong2str->base, result, dest_wstr);
318 ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
319 "(test %d): _itow(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
320 test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer);
321 pRtlFreeAnsiString(&ansi_str);
322 }
323
324
325 static void one_ltow_test(int test_num, const ulong2str_t *ulong2str)
326 {
327 int pos;
328 WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
329 WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
330 UNICODE_STRING unicode_string;
331 STRING ansi_str;
332 LONG value;
333 LPWSTR result;
334
335 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
336 expected_wstr[pos] = ulong2str->Buffer[pos];
337 } /* for */
338 expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
339
340 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
341 dest_wstr[pos] = '-';
342 } /* for */
343 dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
344 unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
345 unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
346 unicode_string.Buffer = dest_wstr;
347
348 value = ulong2str->value;
349 result = p_ltow(value, dest_wstr, ulong2str->base);
350 pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
351 ok(result == dest_wstr,
352 "(test %d): _ltow(%d, [out], %d) has result %p, expected: %p\n",
353 test_num, value, ulong2str->base, result, dest_wstr);
354 ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
355 "(test %d): _ltow(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
356 test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer);
357 pRtlFreeAnsiString(&ansi_str);
358 }
359
360
361 static void one_ultow_test(int test_num, const ulong2str_t *ulong2str)
362 {
363 int pos;
364 WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
365 WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
366 UNICODE_STRING unicode_string;
367 STRING ansi_str;
368 ULONG value;
369 LPWSTR result;
370
371 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
372 expected_wstr[pos] = ulong2str->Buffer[pos];
373 } /* for */
374 expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
375
376 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
377 dest_wstr[pos] = '-';
378 } /* for */
379 dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
380 unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
381 unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
382 unicode_string.Buffer = dest_wstr;
383
384 value = ulong2str->value;
385 result = p_ultow(value, dest_wstr, ulong2str->base);
386 pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
387 ok(result == dest_wstr,
388 "(test %d): _ultow(%u, [out], %d) has result %p, expected: %p\n",
389 test_num, value, ulong2str->base, result, dest_wstr);
390 ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
391 "(test %d): _ultow(%u, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
392 test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer);
393 pRtlFreeAnsiString(&ansi_str);
394 }
395
396
397 static void test_ulongtow(void)
398 {
399 int test_num;
400 LPWSTR result;
401
402 for (test_num = 0; test_num < NB_ULONG2STR; test_num++) {
403 if (ulong2str[test_num].mask & 0x10) {
404 one_itow_test(test_num, &ulong2str[test_num]);
405 } /* if */
406 if (ulong2str[test_num].mask & 0x20) {
407 one_ltow_test(test_num, &ulong2str[test_num]);
408 } /* if */
409 if (ulong2str[test_num].mask & 0x40) {
410 one_ultow_test(test_num, &ulong2str[test_num]);
411 } /* if */
412 } /* for */
413
414 if (0) {
415 /* Crashes on XP and W2K3 */
416 result = p_itow(ulong2str[0].value, NULL, 10);
417 ok(result == NULL,
418 "(test a): _itow(%d, NULL, 10) has result %p, expected: NULL\n",
419 ulong2str[0].value, result);
420 }
421
422 if (0) {
423 /* Crashes on XP and W2K3 */
424 result = p_ltow(ulong2str[0].value, NULL, 10);
425 ok(result == NULL,
426 "(test b): _ltow(%d, NULL, 10) has result %p, expected: NULL\n",
427 ulong2str[0].value, result);
428 }
429
430 if (0) {
431 /* Crashes on XP and W2K3 */
432 result = p_ultow(ulong2str[0].value, NULL, 10);
433 ok(result == NULL,
434 "(test c): _ultow(%d, NULL, 10) has result %p, expected: NULL\n",
435 ulong2str[0].value, result);
436 }
437 }
438
439 #define ULL(a,b) (((ULONGLONG)(a) << 32) | (b))
440
441 typedef struct {
442 int base;
443 ULONGLONG value;
444 const char *Buffer;
445 int mask; /* ntdll/msvcrt: 0x01=i64toa, 0x02=ui64toa, 0x04=wrong _i64toa try next example */
446 /* 0x10=i64tow, 0x20=ui64tow, 0x40=wrong _i64tow try next example */
447 } ulonglong2str_t;
448
449 static const ulonglong2str_t ulonglong2str[] = {
450 {10, 123, "123\0---------------------------------------------------------------", 0x33},
451
452 { 2, 0x80000000U, "10000000000000000000000000000000\0----------------------------------", 0x33},
453 { 2, -2147483647, "1111111111111111111111111111111110000000000000000000000000000001\0--", 0x33},
454 { 2, -65537, "1111111111111111111111111111111111111111111111101111111111111111\0--", 0x33},
455 { 2, -65536, "1111111111111111111111111111111111111111111111110000000000000000\0--", 0x33},
456 { 2, -65535, "1111111111111111111111111111111111111111111111110000000000000001\0--", 0x33},
457 { 2, -32768, "1111111111111111111111111111111111111111111111111000000000000000\0--", 0x33},
458 { 2, -32767, "1111111111111111111111111111111111111111111111111000000000000001\0--", 0x33},
459 { 2, -2, "1111111111111111111111111111111111111111111111111111111111111110\0--", 0x33},
460 { 2, -1, "1111111111111111111111111111111111111111111111111111111111111111\0--", 0x33},
461 { 2, 0, "0\0-----------------------------------------------------------------", 0x33},
462 { 2, 1, "1\0-----------------------------------------------------------------", 0x33},
463 { 2, 10, "1010\0--------------------------------------------------------------", 0x33},
464 { 2, 100, "1100100\0-----------------------------------------------------------", 0x33},
465 { 2, 1000, "1111101000\0--------------------------------------------------------", 0x33},
466 { 2, 10000, "10011100010000\0----------------------------------------------------", 0x33},
467 { 2, 32767, "111111111111111\0---------------------------------------------------", 0x33},
468 { 2, 32768, "1000000000000000\0--------------------------------------------------", 0x33},
469 { 2, 65535, "1111111111111111\0--------------------------------------------------", 0x33},
470 { 2, 100000, "11000011010100000\0-------------------------------------------------", 0x33},
471 { 2, 234567, "111001010001000111\0------------------------------------------------", 0x33},
472 { 2, 300000, "1001001001111100000\0-----------------------------------------------", 0x33},
473 { 2, 524287, "1111111111111111111\0-----------------------------------------------", 0x33},
474 { 2, 524288, "10000000000000000000\0----------------------------------------------", 0x33},
475 { 2, 1000000, "11110100001001000000\0----------------------------------------------", 0x33},
476 { 2, 10000000, "100110001001011010000000\0------------------------------------------", 0x33},
477 { 2, 100000000, "101111101011110000100000000\0---------------------------------------", 0x33},
478 { 2, 1000000000, "111011100110101100101000000000\0------------------------------------", 0x33},
479 { 2, 1073741823, "111111111111111111111111111111\0------------------------------------", 0x33},
480 { 2, 2147483646, "1111111111111111111111111111110\0-----------------------------------", 0x33},
481 { 2, 2147483647, "1111111111111111111111111111111\0-----------------------------------", 0x33},
482 { 2, 2147483648U, "10000000000000000000000000000000\0----------------------------------", 0x33},
483 { 2, 2147483649U, "10000000000000000000000000000001\0----------------------------------", 0x33},
484 { 2, 4294967294U, "11111111111111111111111111111110\0----------------------------------", 0x33},
485 { 2, 0xFFFFFFFF, "11111111111111111111111111111111\0----------------------------------", 0x33},
486 { 2, ULL(0x1,0xffffffff), "111111111111111111111111111111111\0---------------------------------", 0x33},
487 { 2, ((ULONGLONG)100000)*100000, "1001010100000010111110010000000000\0--------------------------------", 0x33},
488 { 2, ULL(0x3,0xffffffff), "1111111111111111111111111111111111\0--------------------------------", 0x33},
489 { 2, ULL(0x7,0xffffffff), "11111111111111111111111111111111111\0-------------------------------", 0x33},
490 { 2, ULL(0xf,0xffffffff), "111111111111111111111111111111111111\0------------------------------", 0x33},
491 { 2, ((ULONGLONG)100000)*1000000, "1011101001000011101101110100000000000\0-----------------------------", 0x33},
492 { 2, ULL(0x1f,0xffffffff), "1111111111111111111111111111111111111\0-----------------------------", 0x33},
493 { 2, ULL(0x3f,0xffffffff), "11111111111111111111111111111111111111\0----------------------------", 0x33},
494 { 2, ULL(0x7f,0xffffffff), "111111111111111111111111111111111111111\0---------------------------", 0x33},
495 { 2, ULL(0xff,0xffffffff), "1111111111111111111111111111111111111111\0--------------------------", 0x33},
496
497 { 8, 0x80000000U, "20000000000\0-------------------------------------------------------", 0x33},
498 { 8, -2147483647, "1777777777760000000001\0--------------------------------------------", 0x33},
499 { 8, -2, "1777777777777777777776\0--------------------------------------------", 0x33},
500 { 8, -1, "1777777777777777777777\0--------------------------------------------", 0x33},
501 { 8, 0, "0\0-----------------------------------------------------------------", 0x33},
502 { 8, 1, "1\0-----------------------------------------------------------------", 0x33},
503 { 8, 2147483646, "17777777776\0-------------------------------------------------------", 0x33},
504 { 8, 2147483647, "17777777777\0-------------------------------------------------------", 0x33},
505 { 8, 2147483648U, "20000000000\0-------------------------------------------------------", 0x33},
506 { 8, 2147483649U, "20000000001\0-------------------------------------------------------", 0x33},
507 { 8, 4294967294U, "37777777776\0-------------------------------------------------------", 0x33},
508 { 8, 4294967295U, "37777777777\0-------------------------------------------------------", 0x33},
509
510 {10, 0x80000000U, "2147483648\0--------------------------------------------------------", 0x33},
511 {10, -2147483647, "-2147483647\0-------------------------------------------------------", 0x55},
512 {10, -2147483647, "-18446744071562067969\0---------------------------------------------", 0x00},
513 {10, -2147483647, "18446744071562067969\0----------------------------------------------", 0x22},
514 {10, -2, "-2\0----------------------------------------------------------------", 0x55},
515 {10, -2, "-18446744073709551614\0---------------------------------------------", 0x00},
516 {10, -2, "18446744073709551614\0----------------------------------------------", 0x22},
517 {10, -1, "-1\0----------------------------------------------------------------", 0x55},
518 {10, -1, "-18446744073709551615\0---------------------------------------------", 0x00},
519 {10, -1, "18446744073709551615\0----------------------------------------------", 0x22},
520 {10, 0, "0\0-----------------------------------------------------------------", 0x33},
521 {10, 1, "1\0-----------------------------------------------------------------", 0x33},
522 {10, 12, "12\0----------------------------------------------------------------", 0x33},
523 {10, 123, "123\0---------------------------------------------------------------", 0x33},
524 {10, 1234, "1234\0--------------------------------------------------------------", 0x33},
525 {10, 12345, "12345\0-------------------------------------------------------------", 0x33},
526 {10, 123456, "123456\0------------------------------------------------------------", 0x33},
527 {10, 1234567, "1234567\0-----------------------------------------------------------", 0x33},
528 {10, 12345678, "12345678\0----------------------------------------------------------", 0x33},
529 {10, 123456789, "123456789\0---------------------------------------------------------", 0x33},
530 {10, 2147483646, "2147483646\0--------------------------------------------------------", 0x33},
531 {10, 2147483647, "2147483647\0--------------------------------------------------------", 0x33},
532 {10, 2147483648U, "2147483648\0--------------------------------------------------------", 0x33},
533 {10, 2147483649U, "2147483649\0--------------------------------------------------------", 0x33},
534 {10, 4294967294U, "4294967294\0--------------------------------------------------------", 0x33},
535 {10, 4294967295U, "4294967295\0--------------------------------------------------------", 0x33},
536 {10, ULL(0x2,0xdfdc1c35), "12345678901\0-------------------------------------------------------", 0x33},
537 {10, ULL(0xe5,0xf4c8f374), "987654321012\0------------------------------------------------------", 0x33},
538 {10, ULL(0x1c0,0xfc161e3e), "1928374656574\0-----------------------------------------------------", 0x33},
539 {10, ULL(0xbad,0xcafeface), "12841062955726\0----------------------------------------------------", 0x33},
540 {10, ULL(0x5bad,0xcafeface), "100801993177806\0---------------------------------------------------", 0x33},
541 {10, ULL(0xaface,0xbeefcafe), "3090515640699646\0--------------------------------------------------", 0x33},
542 {10, ULL(0xa5beef,0xabcdcafe), "46653307746110206\0-------------------------------------------------", 0x33},
543 {10, ULL(0x1f8cf9b,0xf2df3af1), "142091656963767025\0------------------------------------------------", 0x33},
544 {10, ULL(0x0fffffff,0xffffffff), "1152921504606846975\0-----------------------------------------------", 0x33},
545 {10, ULL(0x7fffffff,0xffffffff), "9223372036854775807\0-----------------------------------------------", 0x33},
546 {10, ULL(0x80000000,0x00000000), "-9223372036854775808\0----------------------------------------------", 0x11},
547 {10, ULL(0x80000000,0x00000000), "9223372036854775808\0-----------------------------------------------", 0x22},
548 {10, ULL(0x80000000,0x00000001), "-9223372036854775807\0----------------------------------------------", 0x55},
549 {10, ULL(0x80000000,0x00000001), "-9223372036854775809\0----------------------------------------------", 0x00},
550 {10, ULL(0x80000000,0x00000001), "9223372036854775809\0-----------------------------------------------", 0x22},
551 {10, ULL(0x80000000,0x00000002), "-9223372036854775806\0----------------------------------------------", 0x55},
552 {10, ULL(0x80000000,0x00000002), "-9223372036854775810\0----------------------------------------------", 0x00},
553 {10, ULL(0x80000000,0x00000002), "9223372036854775810\0-----------------------------------------------", 0x22},
554 {10, ULL(0xffffffff,0xfffffffe), "-2\0----------------------------------------------------------------", 0x55},
555 {10, ULL(0xffffffff,0xfffffffe), "-18446744073709551614\0---------------------------------------------", 0x00},
556 {10, ULL(0xffffffff,0xfffffffe), "18446744073709551614\0----------------------------------------------", 0x22},
557 {10, ULL(0xffffffff,0xffffffff), "-1\0----------------------------------------------------------------", 0x55},
558 {10, ULL(0xffffffff,0xffffffff), "-18446744073709551615\0---------------------------------------------", 0x00},
559 {10, ULL(0xffffffff,0xffffffff), "18446744073709551615\0----------------------------------------------", 0x22},
560
561 {16, 0, "0\0-----------------------------------------------------------------", 0x33},
562 {16, 1, "1\0-----------------------------------------------------------------", 0x33},
563 {16, 2147483646, "7ffffffe\0----------------------------------------------------------", 0x33},
564 {16, 2147483647, "7fffffff\0----------------------------------------------------------", 0x33},
565 {16, 0x80000000, "80000000\0----------------------------------------------------------", 0x33},
566 {16, 0x80000001, "80000001\0----------------------------------------------------------", 0x33},
567 {16, 0xFFFFFFFE, "fffffffe\0----------------------------------------------------------", 0x33},
568 {16, 0xFFFFFFFF, "ffffffff\0----------------------------------------------------------", 0x33},
569 {16, ULL(0x1,0x00000000), "100000000\0---------------------------------------------------------", 0x33},
570 {16, ULL(0xbad,0xdeadbeef), "baddeadbeef\0-------------------------------------------------------", 0x33},
571 {16, ULL(0x80000000,0x00000000), "8000000000000000\0--------------------------------------------------", 0x33},
572 {16, ULL(0xfedcba98,0x76543210), "fedcba9876543210\0--------------------------------------------------", 0x33},
573 {16, ULL(0xffffffff,0x80000001), "ffffffff80000001\0--------------------------------------------------", 0x33},
574 {16, ULL(0xffffffff,0xfffffffe), "fffffffffffffffe\0--------------------------------------------------", 0x33},
575 {16, ULL(0xffffffff,0xffffffff), "ffffffffffffffff\0--------------------------------------------------", 0x33},
576
577 { 2, 32768, "1000000000000000\0--------------------------------------------------", 0x33},
578 { 2, 65536, "10000000000000000\0-------------------------------------------------", 0x33},
579 { 2, 131072, "100000000000000000\0------------------------------------------------", 0x33},
580 {16, 0xffffffff, "ffffffff\0----------------------------------------------------------", 0x33},
581 {16, 0xa, "a\0-----------------------------------------------------------------", 0x33},
582 {16, 0, "0\0-----------------------------------------------------------------", 0x33},
583 {20, 3368421, "111111\0------------------------------------------------------------", 0x33},
584 {36, 62193781, "111111\0------------------------------------------------------------", 0x33},
585 {37, 71270178, "111111\0------------------------------------------------------------", 0x33},
586 {99, ULL(0x2,0x3c9e468c), "111111\0------------------------------------------------------------", 0x33},
587 };
588 #define NB_ULONGLONG2STR (sizeof(ulonglong2str)/sizeof(*ulonglong2str))
589
590
591 static void one_i64toa_test(int test_num, const ulonglong2str_t *ulonglong2str)
592 {
593 LPSTR result;
594 char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
595
596 memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
597 dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
598 result = p_i64toa(ulonglong2str->value, dest_str, ulonglong2str->base);
599 ok(result == dest_str,
600 "(test %d): _i64toa(%s, [out], %d) has result %p, expected: %p\n",
601 test_num, wine_dbgstr_longlong(ulonglong2str->value), ulonglong2str->base, result, dest_str);
602 if (ulonglong2str->mask & 0x04) {
603 if (memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) != 0) {
604 if (memcmp(dest_str, ulonglong2str[1].Buffer, LARGE_STRI_BUFFER_LENGTH) != 0) {
605 ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
606 "(test %d): _i64toa(%s, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
607 test_num, wine_dbgstr_longlong(ulonglong2str->value),
608 ulonglong2str->base, dest_str, ulonglong2str->Buffer);
609 } /* if */
610 } /* if */
611 } else {
612 ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
613 "(test %d): _i64toa(%s, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
614 test_num, wine_dbgstr_longlong(ulonglong2str->value),
615 ulonglong2str->base, dest_str, ulonglong2str->Buffer);
616 } /* if */
617 }
618
619
620 static void one_ui64toa_test(int test_num, const ulonglong2str_t *ulonglong2str)
621 {
622 LPSTR result;
623 char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
624
625 memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
626 dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
627 result = p_ui64toa(ulonglong2str->value, dest_str, ulonglong2str->base);
628 ok(result == dest_str,
629 "(test %d): _ui64toa(%s, [out], %d) has result %p, expected: %p\n",
630 test_num, wine_dbgstr_longlong(ulonglong2str->value), ulonglong2str->base, result, dest_str);
631 ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
632 "(test %d): _ui64toa(%s, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
633 test_num, wine_dbgstr_longlong(ulonglong2str->value),
634 ulonglong2str->base, dest_str, ulonglong2str->Buffer);
635 }
636
637
638 static void test_ulonglongtoa(void)
639 {
640 int test_num;
641
642 for (test_num = 0; test_num < NB_ULONGLONG2STR; test_num++) {
643 if (ulonglong2str[test_num].mask & 0x01) {
644 one_i64toa_test(test_num, &ulonglong2str[test_num]);
645 } /* if */
646 if (p_ui64toa != NULL) {
647 if (ulonglong2str[test_num].mask & 0x02) {
648 one_ui64toa_test(test_num, &ulonglong2str[test_num]);
649 } /* if */
650 } /* if */
651 } /* for */
652 }
653
654
655 static void one_i64tow_test(int test_num, const ulonglong2str_t *ulonglong2str)
656 {
657 int pos;
658 WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
659 WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
660 UNICODE_STRING unicode_string;
661 STRING ansi_str;
662 LPWSTR result;
663
664 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
665 expected_wstr[pos] = ulonglong2str->Buffer[pos];
666 } /* for */
667 expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
668
669 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
670 dest_wstr[pos] = '-';
671 } /* for */
672 dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
673 unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
674 unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
675 unicode_string.Buffer = dest_wstr;
676
677 result = p_i64tow(ulonglong2str->value, dest_wstr, ulonglong2str->base);
678 pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
679 ok(result == dest_wstr,
680 "(test %d): _i64tow(0x%s, [out], %d) has result %p, expected: %p\n",
681 test_num, wine_dbgstr_longlong(ulonglong2str->value), ulonglong2str->base, result, dest_wstr);
682 if (ulonglong2str->mask & 0x04) {
683 if (memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) != 0) {
684 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
685 expected_wstr[pos] = ulonglong2str[1].Buffer[pos];
686 } /* for */
687 expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
688 if (memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) != 0) {
689 ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
690 "(test %d): _i64tow(0x%s, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
691 test_num, wine_dbgstr_longlong(ulonglong2str->value),
692 ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer);
693 } /* if */
694 } /* if */
695 } else {
696 ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
697 "(test %d): _i64tow(0x%s, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
698 test_num, wine_dbgstr_longlong(ulonglong2str->value),
699 ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer);
700 } /* if */
701 pRtlFreeAnsiString(&ansi_str);
702 }
703
704
705 static void one_ui64tow_test(int test_num, const ulonglong2str_t *ulonglong2str)
706 {
707 int pos;
708 WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
709 WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
710 UNICODE_STRING unicode_string;
711 STRING ansi_str;
712 LPWSTR result;
713
714 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
715 expected_wstr[pos] = ulonglong2str->Buffer[pos];
716 } /* for */
717 expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
718
719 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
720 dest_wstr[pos] = '-';
721 } /* for */
722 dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
723 unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
724 unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
725 unicode_string.Buffer = dest_wstr;
726
727 result = p_ui64tow(ulonglong2str->value, dest_wstr, ulonglong2str->base);
728 pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
729 ok(result == dest_wstr,
730 "(test %d): _ui64tow(0x%s, [out], %d) has result %p, expected: %p\n",
731 test_num, wine_dbgstr_longlong(ulonglong2str->value),
732 ulonglong2str->base, result, dest_wstr);
733 ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
734 "(test %d): _ui64tow(0x%s, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
735 test_num, wine_dbgstr_longlong(ulonglong2str->value),
736 ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer);
737 pRtlFreeAnsiString(&ansi_str);
738 }
739
740
741 static void test_ulonglongtow(void)
742 {
743 int test_num;
744 LPWSTR result;
745
746 for (test_num = 0; test_num < NB_ULONGLONG2STR; test_num++) {
747 if (ulonglong2str[test_num].mask & 0x10) {
748 one_i64tow_test(test_num, &ulonglong2str[test_num]);
749 } /* if */
750 if (p_ui64tow) {
751 if (ulonglong2str[test_num].mask & 0x20) {
752 one_ui64tow_test(test_num, &ulonglong2str[test_num]);
753 } /* if */
754 } /* if */
755 } /* for */
756
757 if (0) {
758 /* Crashes on XP and W2K3 */
759 result = p_i64tow(ulonglong2str[0].value, NULL, 10);
760 ok(result == NULL,
761 "(test d): _i64tow(0x%s, NULL, 10) has result %p, expected: NULL\n",
762 wine_dbgstr_longlong(ulonglong2str[0].value), result);
763 }
764
765 if (p_ui64tow) {
766 if (0) {
767 /* Crashes on XP and W2K3 */
768 result = p_ui64tow(ulonglong2str[0].value, NULL, 10);
769 ok(result == NULL,
770 "(test e): _ui64tow(0x%s, NULL, 10) has result %p, expected: NULL\n",
771 wine_dbgstr_longlong(ulonglong2str[0].value), result);
772 }
773 } /* if */
774 }
775
776
777 typedef struct {
778 const char *str;
779 LONG value;
780 } str2long_t;
781
782 static const str2long_t str2long[] = {
783 { "1011101100", 1011101100 },
784 { "1234567", 1234567 },
785 { "-214", -214 },
786 { "+214", 214 }, /* The + sign is allowed also */
787 { "--214", 0 }, /* Do not accept more than one sign */
788 { "-+214", 0 },
789 { "++214", 0 },
790 { "+-214", 0 },
791 { "\00141", 0 }, /* not whitespace char 1 */
792 { "\00242", 0 }, /* not whitespace char 2 */
793 { "\00343", 0 }, /* not whitespace char 3 */
794 { "\00444", 0 }, /* not whitespace char 4 */
795 { "\00545", 0 }, /* not whitespace char 5 */
796 { "\00646", 0 }, /* not whitespace char 6 */
797 { "\00747", 0 }, /* not whitespace char 7 */
798 { "\01050", 0 }, /* not whitespace char 8 */
799 { "\01151", 51 }, /* is whitespace char 9 (tab) */
800 { "\01252", 52 }, /* is whitespace char 10 (lf) */
801 { "\01353", 53 }, /* is whitespace char 11 (vt) */
802 { "\01454", 54 }, /* is whitespace char 12 (ff) */
803 { "\01555", 55 }, /* is whitespace char 13 (cr) */
804 { "\01656", 0 }, /* not whitespace char 14 */
805 { "\01757", 0 }, /* not whitespace char 15 */
806 { "\02060", 0 }, /* not whitespace char 16 */
807 { "\02161", 0 }, /* not whitespace char 17 */
808 { "\02262", 0 }, /* not whitespace char 18 */
809 { "\02363", 0 }, /* not whitespace char 19 */
810 { "\02464", 0 }, /* not whitespace char 20 */
811 { "\02565", 0 }, /* not whitespace char 21 */
812 { "\02666", 0 }, /* not whitespace char 22 */
813 { "\02767", 0 }, /* not whitespace char 23 */
814 { "\03070", 0 }, /* not whitespace char 24 */
815 { "\03171", 0 }, /* not whitespace char 25 */
816 { "\03272", 0 }, /* not whitespace char 26 */
817 { "\03373", 0 }, /* not whitespace char 27 */
818 { "\03474", 0 }, /* not whitespace char 28 */
819 { "\03575", 0 }, /* not whitespace char 29 */
820 { "\03676", 0 }, /* not whitespace char 30 */
821 { "\03777", 0 }, /* not whitespace char 31 */
822 { "\04080", 80 }, /* is whitespace char 32 (space) */
823 { " \n \r \t214", 214 },
824 { " \n \r \t+214", 214 }, /* Signs can be used after whitespace */
825 { " \n \r \t-214", -214 },
826 { "+214 0", 214 }, /* Space terminates the number */
827 { " 214.01", 214 }, /* Decimal point not accepted */
828 { " 214,01", 214 }, /* Decimal comma not accepted */
829 { "f81", 0 },
830 { "0x12345", 0 }, /* Hex not accepted */
831 { "00x12345", 0 },
832 { "0xx12345", 0 },
833 { "1x34", 1 },
834 { "-9999999999", -1410065407 }, /* Big negative integer */
835 { "-2147483649", 2147483647 }, /* Too small to fit in 32 Bits */
836 { "-2147483648", 0x80000000 }, /* Smallest negative integer */
837 { "-2147483647", -2147483647 },
838 { "-1", -1 },
839 { "0", 0 },
840 { "1", 1 },
841 { "2147483646", 2147483646 },
842 { "2147483647", 2147483647 }, /* Largest signed positive integer */
843 { "2147483648", 2147483648UL }, /* Positive int equal to smallest negative int */
844 { "2147483649", 2147483649UL },
845 { "4294967294", 4294967294UL },
846 { "4294967295", 4294967295UL }, /* Largest unsigned integer */
847 { "4294967296", 0 }, /* Too big to fit in 32 Bits */
848 { "9999999999", 1410065407 }, /* Big positive integer */
849 { "056789", 56789 }, /* Leading zero and still decimal */
850 { "b1011101100", 0 }, /* Binary (b-notation) */
851 { "-b1011101100", 0 }, /* Negative Binary (b-notation) */
852 { "b10123456789", 0 }, /* Binary with nonbinary digits (2-9) */
853 { "0b1011101100", 0 }, /* Binary (0b-notation) */
854 { "-0b1011101100", 0 }, /* Negative binary (0b-notation) */
855 { "0b10123456789", 0 }, /* Binary with nonbinary digits (2-9) */
856 { "-0b10123456789", 0 }, /* Negative binary with nonbinary digits (2-9) */
857 { "0b1", 0 }, /* one digit binary */
858 { "0b2", 0 }, /* empty binary */
859 { "0b", 0 }, /* empty binary */
860 { "o1234567", 0 }, /* Octal (o-notation) */
861 { "-o1234567", 0 }, /* Negative Octal (o-notation) */
862 { "o56789", 0 }, /* Octal with nonoctal digits (8 and 9) */
863 { "0o1234567", 0 }, /* Octal (0o-notation) */
864 { "-0o1234567", 0 }, /* Negative octal (0o-notation) */
865 { "0o56789", 0 }, /* Octal with nonoctal digits (8 and 9) */
866 { "-0o56789", 0 }, /* Negative octal with nonoctal digits (8 and 9) */
867 { "0o7", 0 }, /* one digit octal */
868 { "0o8", 0 }, /* empty octal */
869 { "0o", 0 }, /* empty octal */
870 { "0d1011101100", 0 }, /* explicit decimal with 0d */
871 { "x89abcdef", 0 }, /* Hex with lower case digits a-f (x-notation) */
872 { "xFEDCBA00", 0 }, /* Hex with upper case digits A-F (x-notation) */
873 { "-xFEDCBA00", 0 }, /* Negative Hexadecimal (x-notation) */
874 { "0x89abcdef", 0 }, /* Hex with lower case digits a-f (0x-notation) */
875 { "0xFEDCBA00", 0 }, /* Hex with upper case digits A-F (0x-notation) */
876 { "-0xFEDCBA00", 0 }, /* Negative Hexadecimal (0x-notation) */
877 { "0xabcdefgh", 0 }, /* Hex with illegal lower case digits (g-z) */
878 { "0xABCDEFGH", 0 }, /* Hex with illegal upper case digits (G-Z) */
879 { "0xF", 0 }, /* one digit hexadecimal */
880 { "0xG", 0 }, /* empty hexadecimal */
881 { "0x", 0 }, /* empty hexadecimal */
882 { "", 0 }, /* empty string */
883 /* { NULL, 0 }, */ /* NULL as string */
884 };
885 #define NB_STR2LONG (sizeof(str2long)/sizeof(*str2long))
886
887
888 static void test_wtoi(void)
889 {
890 int test_num;
891 UNICODE_STRING uni;
892 int result;
893
894 for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
895 pRtlCreateUnicodeStringFromAsciiz(&uni, str2long[test_num].str);
896 result = p_wtoi(uni.Buffer);
897 ok(result == str2long[test_num].value,
898 "(test %d): call failed: _wtoi(\"%s\") has result %d, expected: %d\n",
899 test_num, str2long[test_num].str, result, str2long[test_num].value);
900 pRtlFreeUnicodeString(&uni);
901 } /* for */
902 }
903
904 static void test_atoi(void)
905 {
906 int test_num;
907 int result;
908
909 for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
910 result = patoi(str2long[test_num].str);
911 ok(result == str2long[test_num].value,
912 "(test %d): call failed: _atoi(\"%s\") has result %d, expected: %d\n",
913 test_num, str2long[test_num].str, result, str2long[test_num].value);
914 }
915 }
916
917 static void test_atol(void)
918 {
919 int test_num;
920 int result;
921
922 for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
923 result = patol(str2long[test_num].str);
924 ok(result == str2long[test_num].value,
925 "(test %d): call failed: _atol(\"%s\") has result %d, expected: %d\n",
926 test_num, str2long[test_num].str, result, str2long[test_num].value);
927 }
928 }
929
930 static void test_wtol(void)
931 {
932 int test_num;
933 UNICODE_STRING uni;
934 LONG result;
935
936 for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
937 pRtlCreateUnicodeStringFromAsciiz(&uni, str2long[test_num].str);
938 result = p_wtol(uni.Buffer);
939 ok(result == str2long[test_num].value,
940 "(test %d): call failed: _wtol(\"%s\") has result %d, expected: %d\n",
941 test_num, str2long[test_num].str, result, str2long[test_num].value);
942 pRtlFreeUnicodeString(&uni);
943 } /* for */
944 }
945
946
947 typedef struct {
948 const char *str;
949 LONGLONG value;
950 int overflow;
951 } str2longlong_t;
952
953 static const str2longlong_t str2longlong[] = {
954 { "1011101100", 1011101100 },
955 { "1234567", 1234567 },
956 { "-214", -214 },
957 { "+214", 214 }, /* The + sign is allowed also */
958 { "--214", 0 }, /* Do not accept more than one sign */
959 { "-+214", 0 },
960 { "++214", 0 },
961 { "+-214", 0 },
962 { "\00141", 0 }, /* not whitespace char 1 */
963 { "\00242", 0 }, /* not whitespace char 2 */
964 { "\00343", 0 }, /* not whitespace char 3 */
965 { "\00444", 0 }, /* not whitespace char 4 */
966 { "\00545", 0 }, /* not whitespace char 5 */
967 { "\00646", 0 }, /* not whitespace char 6 */
968 { "\00747", 0 }, /* not whitespace char 7 */
969 { "\01050", 0 }, /* not whitespace char 8 */
970 { "\01151", 51 }, /* is whitespace char 9 (tab) */
971 { "\01252", 52 }, /* is whitespace char 10 (lf) */
972 { "\01353", 53 }, /* is whitespace char 11 (vt) */
973 { "\01454", 54 }, /* is whitespace char 12 (ff) */
974 { "\01555", 55 }, /* is whitespace char 13 (cr) */
975 { "\01656", 0 }, /* not whitespace char 14 */
976 { "\01757", 0 }, /* not whitespace char 15 */
977 { "\02060", 0 }, /* not whitespace char 16 */
978 { "\02161", 0 }, /* not whitespace char 17 */
979 { "\02262", 0 }, /* not whitespace char 18 */
980 { "\02363", 0 }, /* not whitespace char 19 */
981 { "\02464", 0 }, /* not whitespace char 20 */
982 { "\02565", 0 }, /* not whitespace char 21 */
983 { "\02666", 0 }, /* not whitespace char 22 */
984 { "\02767", 0 }, /* not whitespace char 23 */
985 { "\03070", 0 }, /* not whitespace char 24 */
986 { "\03171", 0 }, /* not whitespace char 25 */
987 { "\03272", 0 }, /* not whitespace char 26 */
988 { "\03373", 0 }, /* not whitespace char 27 */
989 { "\03474", 0 }, /* not whitespace char 28 */
990 { "\03575", 0 }, /* not whitespace char 29 */
991 { "\03676", 0 }, /* not whitespace char 30 */
992 { "\03777", 0 }, /* not whitespace char 31 */
993 { "\04080", 80 }, /* is whitespace char 32 (space) */
994 { " \n \r \t214", 214 },
995 { " \n \r \t+214", 214 }, /* Signs can be used after whitespace */
996 { " \n \r \t-214", -214 },
997 { "+214 0", 214 }, /* Space terminates the number */
998 { " 214.01", 214 }, /* Decimal point not accepted */
999 { " 214,01", 214 }, /* Decimal comma not accepted */
1000 { "f81", 0 },
1001 { "0x12345", 0 }, /* Hex not accepted */
1002 { "00x12345", 0 },
1003 { "0xx12345", 0 },
1004 { "1x34", 1 },
1005 { "-99999999999999999999", -ULL(0x6bc75e2d,0x630fffff), -1 }, /* Big negative integer */
1006 { "-9223372036854775809", ULL(0x7fffffff,0xffffffff), -1 }, /* Too small to fit in 64 bits */
1007 { "-9223372036854775808", ULL(0x80000000,0x00000000) }, /* Smallest negative 64 bit integer */
1008 { "-9223372036854775807", -ULL(0x7fffffff,0xffffffff) },
1009 { "-9999999999", -ULL(0x00000002,0x540be3ff) },
1010 { "-2147483649", -ULL(0x00000000,0x80000001) }, /* Too small to fit in 32 bits */
1011 { "-2147483648", -ULL(0x00000000,0x80000000) }, /* Smallest 32 bits negative integer */
1012 { "-2147483647", -2147483647 },
1013 { "-1", -1 },
1014 { "0", 0 },
1015 { "1", 1 },
1016 { "2147483646", 2147483646 },
1017 { "2147483647", 2147483647 }, /* Largest signed positive 32 bit integer */
1018 { "2147483648", ULL(0x00000000,0x80000000) }, /* Pos int equal to smallest neg 32 bit int */
1019 { "2147483649", ULL(0x00000000,0x80000001) },
1020 { "4294967294", ULL(0x00000000,0xfffffffe) },
1021 { "4294967295", ULL(0x00000000,0xffffffff) }, /* Largest unsigned 32 bit integer */
1022 { "4294967296", ULL(0x00000001,0x00000000) }, /* Too big to fit in 32 Bits */
1023 { "9999999999", ULL(0x00000002,0x540be3ff) },
1024 { "9223372036854775806", ULL(0x7fffffff,0xfffffffe) },
1025 { "9223372036854775807", ULL(0x7fffffff,0xffffffff) }, /* Largest signed positive 64 bit integer */
1026 { "9223372036854775808", ULL(0x80000000,0x00000000), 1 }, /* Pos int equal to smallest neg 64 bit int */
1027 { "9223372036854775809", ULL(0x80000000,0x00000001), 1 },
1028 { "18446744073709551614", ULL(0xffffffff,0xfffffffe), 1 },
1029 { "18446744073709551615", ULL(0xffffffff,0xffffffff), 1 }, /* Largest unsigned 64 bit integer */
1030 { "18446744073709551616", 0, 1 }, /* Too big to fit in 64 bits */
1031 { "99999999999999999999", ULL(0x6bc75e2d,0x630fffff), 1 }, /* Big positive integer */
1032 { "056789", 56789 }, /* Leading zero and still decimal */
1033 { "b1011101100", 0 }, /* Binary (b-notation) */
1034 { "-b1011101100", 0 }, /* Negative Binary (b-notation) */
1035 { "b10123456789", 0 }, /* Binary with nonbinary digits (2-9) */
1036 { "0b1011101100", 0 }, /* Binary (0b-notation) */
1037 { "-0b1011101100", 0 }, /* Negative binary (0b-notation) */
1038 { "0b10123456789", 0 }, /* Binary with nonbinary digits (2-9) */
1039 { "-0b10123456789", 0 }, /* Negative binary with nonbinary digits (2-9) */
1040 { "0b1", 0 }, /* one digit binary */
1041 { "0b2", 0 }, /* empty binary */
1042 { "0b", 0 }, /* empty binary */
1043 { "o1234567", 0 }, /* Octal (o-notation) */
1044 { "-o1234567", 0 }, /* Negative Octal (o-notation) */
1045 { "o56789", 0 }, /* Octal with nonoctal digits (8 and 9) */
1046 { "0o1234567", 0 }, /* Octal (0o-notation) */
1047 { "-0o1234567", 0 }, /* Negative octal (0o-notation) */
1048 { "0o56789", 0 }, /* Octal with nonoctal digits (8 and 9) */
1049 { "-0o56789", 0 }, /* Negative octal with nonoctal digits (8 and 9) */
1050 { "0o7", 0 }, /* one digit octal */
1051 { "0o8", 0 }, /* empty octal */
1052 { "0o", 0 }, /* empty octal */
1053 { "0d1011101100", 0 }, /* explicit decimal with 0d */
1054 { "x89abcdef", 0 }, /* Hex with lower case digits a-f (x-notation) */
1055 { "xFEDCBA00", 0 }, /* Hex with upper case digits A-F (x-notation) */
1056 { "-xFEDCBA00", 0 }, /* Negative Hexadecimal (x-notation) */
1057 { "0x89abcdef", 0 }, /* Hex with lower case digits a-f (0x-notation) */
1058 { "0xFEDCBA00", 0 }, /* Hex with upper case digits A-F (0x-notation) */
1059 { "-0xFEDCBA00", 0 }, /* Negative Hexadecimal (0x-notation) */
1060 { "0xabcdefgh", 0 }, /* Hex with illegal lower case digits (g-z) */
1061 { "0xABCDEFGH", 0 }, /* Hex with illegal upper case digits (G-Z) */
1062 { "0xF", 0 }, /* one digit hexadecimal */
1063 { "0xG", 0 }, /* empty hexadecimal */
1064 { "0x", 0 }, /* empty hexadecimal */
1065 { "", 0 }, /* empty string */
1066 /* { NULL, 0 }, */ /* NULL as string */
1067 };
1068 #define NB_STR2LONGLONG (sizeof(str2longlong)/sizeof(*str2longlong))
1069
1070
1071 static void test_atoi64(void)
1072 {
1073 int test_num;
1074 LONGLONG result;
1075
1076 for (test_num = 0; test_num < NB_STR2LONGLONG; test_num++) {
1077 result = p_atoi64(str2longlong[test_num].str);
1078 if (str2longlong[test_num].overflow)
1079 ok(result == str2longlong[test_num].value ||
1080 (result == ((str2longlong[test_num].overflow == -1) ?
1081 ULL(0x80000000,0x00000000) : ULL(0x7fffffff,0xffffffff))),
1082 "(test %d): call failed: _atoi64(\"%s\") has result 0x%s, expected: 0x%s\n",
1083 test_num, str2longlong[test_num].str, wine_dbgstr_longlong(result),
1084 wine_dbgstr_longlong(str2longlong[test_num].value));
1085 else
1086 ok(result == str2longlong[test_num].value,
1087 "(test %d): call failed: _atoi64(\"%s\") has result 0x%s, expected: 0x%s\n",
1088 test_num, str2longlong[test_num].str, wine_dbgstr_longlong(result),
1089 wine_dbgstr_longlong(str2longlong[test_num].value));
1090 }
1091 }
1092
1093
1094 static void test_wtoi64(void)
1095 {
1096 int test_num;
1097 UNICODE_STRING uni;
1098 LONGLONG result;
1099
1100 for (test_num = 0; test_num < NB_STR2LONGLONG; test_num++) {
1101 pRtlCreateUnicodeStringFromAsciiz(&uni, str2longlong[test_num].str);
1102 result = p_wtoi64(uni.Buffer);
1103 if (str2longlong[test_num].overflow)
1104 ok(result == str2longlong[test_num].value ||
1105 (result == ((str2longlong[test_num].overflow == -1) ?
1106 ULL(0x80000000,0x00000000) : ULL(0x7fffffff,0xffffffff))),
1107 "(test %d): call failed: _atoi64(\"%s\") has result 0x%s, expected: 0x%s\n",
1108 test_num, str2longlong[test_num].str, wine_dbgstr_longlong(result),
1109 wine_dbgstr_longlong(str2longlong[test_num].value));
1110 else
1111 ok(result == str2longlong[test_num].value,
1112 "(test %d): call failed: _atoi64(\"%s\") has result 0x%s, expected: 0x%s\n",
1113 test_num, str2longlong[test_num].str, wine_dbgstr_longlong(result),
1114 wine_dbgstr_longlong(str2longlong[test_num].value));
1115 pRtlFreeUnicodeString(&uni);
1116 }
1117 }
1118
1119 static void test_wcschr(void)
1120 {
1121 static const WCHAR teststringW[] = {'a','b','r','a','c','a','d','a','b','r','a',0};
1122
1123 ok(p_wcschr(teststringW, 'a') == teststringW + 0,
1124 "wcschr should have returned a pointer to the first 'a' character\n");
1125 ok(p_wcschr(teststringW, 0) == teststringW + 11,
1126 "wcschr should have returned a pointer to the null terminator\n");
1127 ok(p_wcschr(teststringW, 'x') == NULL,
1128 "wcschr should have returned NULL\n");
1129 }
1130
1131 static void test_wcsrchr(void)
1132 {
1133 static const WCHAR teststringW[] = {'a','b','r','a','c','a','d','a','b','r','a',0};
1134
1135 ok(p_wcsrchr(teststringW, 'a') == teststringW + 10,
1136 "wcsrchr should have returned a pointer to the last 'a' character\n");
1137 ok(p_wcsrchr(teststringW, 0) == teststringW + 11,
1138 "wcsrchr should have returned a pointer to the null terminator\n");
1139 ok(p_wcsrchr(teststringW, 'x') == NULL,
1140 "wcsrchr should have returned NULL\n");
1141 }
1142
1143 static void test_wcslwrupr(void)
1144 {
1145 static WCHAR teststringW[] = {'a','b','r','a','c','a','d','a','b','r','a',0};
1146 static WCHAR emptyW[] = {0};
1147 static const WCHAR constemptyW[] = {0};
1148
1149 if (0) /* crashes on native */
1150 {
1151 static const WCHAR conststringW[] = {'a','b','r','a','c','a','d','a','b','r','a',0};
1152 ok(p_wcslwr((LPWSTR)conststringW) == conststringW, "p_wcslwr returned different string\n");
1153 ok(p_wcsupr((LPWSTR)conststringW) == conststringW, "p_wcsupr returned different string\n");
1154 ok(p_wcslwr(NULL) == NULL, "p_wcslwr didn't returned NULL\n");
1155 ok(p_wcsupr(NULL) == NULL, "p_wcsupr didn't returned NULL\n");
1156 }
1157 ok(p_wcslwr(teststringW) == teststringW, "p_wcslwr returned different string\n");
1158 ok(p_wcsupr(teststringW) == teststringW, "p_wcsupr returned different string\n");
1159 ok(p_wcslwr(emptyW) == emptyW, "p_wcslwr returned different string\n");
1160 ok(p_wcsupr(emptyW) == emptyW, "p_wcsupr returned different string\n");
1161 ok(p_wcslwr((LPWSTR)constemptyW) == constemptyW, "p_wcslwr returned different string\n");
1162 ok(p_wcsupr((LPWSTR)constemptyW) == constemptyW, "p_wcsupr returned different string\n");
1163 }
1164
1165 static int __cdecl intcomparefunc(const void *a, const void *b)
1166 {
1167 const int *p = a, *q = b;
1168
1169 ok (a != b, "must never get the same pointer\n");
1170
1171 return *p - *q;
1172 }
1173
1174 static int __cdecl charcomparefunc(const void *a, const void *b)
1175 {
1176 const char *p = a, *q = b;
1177
1178 ok (a != b, "must never get the same pointer\n");
1179
1180 return *p - *q;
1181 }
1182
1183 static int __cdecl strcomparefunc(const void *a, const void *b)
1184 {
1185 const char * const *p = a;
1186 const char * const *q = b;
1187
1188 ok (a != b, "must never get the same pointer\n");
1189
1190 return lstrcmpA(*p, *q);
1191 }
1192
1193 static void test_qsort(void)
1194 {
1195 int arr[5] = { 23, 42, 8, 4, 16 };
1196 char carr[5] = { 42, 23, 4, 8, 16 };
1197 const char *strarr[7] = {
1198 "Hello",
1199 "Wine",
1200 "World",
1201 "!",
1202 "Hopefully",
1203 "Sorted",
1204 "."
1205 };
1206
1207 p_qsort ((void*)arr, 0, sizeof(int), intcomparefunc);
1208 ok(arr[0] == 23, "badly sorted, nmemb=0, arr[0] is %d\n", arr[0]);
1209 ok(arr[1] == 42, "badly sorted, nmemb=0, arr[1] is %d\n", arr[1]);
1210 ok(arr[2] == 8, "badly sorted, nmemb=0, arr[2] is %d\n", arr[2]);
1211 ok(arr[3] == 4, "badly sorted, nmemb=0, arr[3] is %d\n", arr[3]);
1212 ok(arr[4] == 16, "badly sorted, nmemb=0, arr[4] is %d\n", arr[4]);
1213
1214 p_qsort ((void*)arr, 1, sizeof(int), intcomparefunc);
1215 ok(arr[0] == 23, "badly sorted, nmemb=1, arr[0] is %d\n", arr[0]);
1216 ok(arr[1] == 42, "badly sorted, nmemb=1, arr[1] is %d\n", arr[1]);
1217 ok(arr[2] == 8, "badly sorted, nmemb=1, arr[2] is %d\n", arr[2]);
1218 ok(arr[3] == 4, "badly sorted, nmemb=1, arr[3] is %d\n", arr[3]);
1219 ok(arr[4] == 16, "badly sorted, nmemb=1, arr[4] is %d\n", arr[4]);
1220
1221 p_qsort ((void*)arr, 5, 0, intcomparefunc);
1222 ok(arr[0] == 23, "badly sorted, size=0, arr[0] is %d\n", arr[0]);
1223 ok(arr[1] == 42, "badly sorted, size=0, arr[1] is %d\n", arr[1]);
1224 ok(arr[2] == 8, "badly sorted, size=0, arr[2] is %d\n", arr[2]);
1225 ok(arr[3] == 4, "badly sorted, size=0, arr[3] is %d\n", arr[3]);
1226 ok(arr[4] == 16, "badly sorted, size=0, arr[4] is %d\n", arr[4]);
1227
1228 p_qsort ((void*)arr, 5, sizeof(int), intcomparefunc);
1229 ok(arr[0] == 4, "badly sorted, arr[0] is %d\n", arr[0]);
1230 ok(arr[1] == 8, "badly sorted, arr[1] is %d\n", arr[1]);
1231 ok(arr[2] == 16, "badly sorted, arr[2] is %d\n", arr[2]);
1232 ok(arr[3] == 23, "badly sorted, arr[3] is %d\n", arr[3]);
1233 ok(arr[4] == 42, "badly sorted, arr[4] is %d\n", arr[4]);
1234
1235 p_qsort ((void*)carr, 5, sizeof(char), charcomparefunc);
1236 ok(carr[0] == 4, "badly sorted, carr[0] is %d\n", carr[0]);
1237 ok(carr[1] == 8, "badly sorted, carr[1] is %d\n", carr[1]);
1238 ok(carr[2] == 16, "badly sorted, carr[2] is %d\n", carr[2]);
1239 ok(carr[3] == 23, "badly sorted, carr[3] is %d\n", carr[3]);
1240 ok(carr[4] == 42, "badly sorted, carr[4] is %d\n", carr[4]);
1241
1242 p_qsort ((void*)strarr, 7, sizeof(char*), strcomparefunc);
1243 ok(!strcmp(strarr[0],"!"), "badly sorted, strarr[0] is %s\n", strarr[0]);
1244 ok(!strcmp(strarr[1],"."), "badly sorted, strarr[1] is %s\n", strarr[1]);
1245 ok(!strcmp(strarr[2],"Hello"), "badly sorted, strarr[2] is %s\n", strarr[2]);
1246 ok(!strcmp(strarr[3],"Hopefully"), "badly sorted, strarr[3] is %s\n", strarr[3]);
1247 ok(!strcmp(strarr[4],"Sorted"), "badly sorted, strarr[4] is %s\n", strarr[4]);
1248 ok(!strcmp(strarr[5],"Wine"), "badly sorted, strarr[5] is %s\n", strarr[5]);
1249 ok(!strcmp(strarr[6],"World"), "badly sorted, strarr[6] is %s\n", strarr[6]);
1250 }
1251
1252 static void test_bsearch(void)
1253 {
1254 int arr[7] = { 1, 3, 4, 8, 16, 23, 42 };
1255 int *x, l, i, j;
1256
1257 /* just try all array sizes */
1258 for (j=1;j<sizeof(arr)/sizeof(arr[0]);j++) {
1259 for (i=0;i<j;i++) {
1260 l = arr[i];
1261 x = p_bsearch (&l, arr, j, sizeof(arr[0]), intcomparefunc);
1262 ok (x == &arr[i], "bsearch did not find %d entry in loopsize %d.\n", i, j);
1263 }
1264 l = 4242;
1265 x = p_bsearch (&l, arr, j, sizeof(arr[0]), intcomparefunc);
1266 ok (x == NULL, "bsearch did find 4242 entry in loopsize %d.\n", j);
1267 }
1268 }
1269
1270 static void test__snprintf(void)
1271 {
1272 const char *origstring = "XXXXXXXXXXXX";
1273 const char *teststring = "hello world";
1274 char buffer[32];
1275 int res;
1276
1277 res = p__snprintf(NULL, 0, teststring);
1278 ok(res == lstrlenA(teststring) || broken(res == -1) /* <= w2k */,
1279 "_snprintf returned %d, expected %d.\n", res, lstrlenA(teststring));
1280
1281 if (res != -1)
1282 {
1283 res = p__snprintf(NULL, 1, teststring);
1284 ok(res == lstrlenA(teststring) /* WinXP */ || res < 0 /* Vista and greater */,
1285 "_snprintf returned %d, expected %d or < 0.\n", res, lstrlenA(teststring));
1286 }
1287 res = p__snprintf(buffer, strlen(teststring) - 1, teststring);
1288 ok(res < 0, "_snprintf returned %d, expected < 0.\n", res);
1289
1290 strcpy(buffer, origstring);
1291 res = p__snprintf(buffer, strlen(teststring), teststring);
1292 ok(res == lstrlenA(teststring), "_snprintf returned %d, expected %d.\n", res, lstrlenA(teststring));
1293 ok(!strcmp(buffer, "hello worldX"), "_snprintf returned buffer '%s', expected 'hello worldX'.\n", buffer);
1294
1295 strcpy(buffer, origstring);
1296 res = p__snprintf(buffer, strlen(teststring) + 1, teststring);
1297 ok(res == lstrlenA(teststring), "_snprintf returned %d, expected %d.\n", res, lstrlenA(teststring));
1298 ok(!strcmp(buffer, teststring), "_snprintf returned buffer '%s', expected '%s'.\n", buffer, teststring);
1299 }
1300
1301 START_TEST(string)
1302 {
1303 InitFunctionPtrs();
1304
1305 if (p_ultoa)
1306 test_ulongtoa();
1307 if (p_ui64toa)
1308 test_ulonglongtoa();
1309 if (p_atoi64)
1310 test_atoi64();
1311 if (p_ultow)
1312 test_ulongtow();
1313 if (p_ui64tow)
1314 test_ulonglongtow();
1315 if (p_wtoi)
1316 test_wtoi();
1317 if (p_wtol)
1318 test_wtol();
1319 if (p_wtoi64)
1320 test_wtoi64();
1321 if (p_wcschr)
1322 test_wcschr();
1323 if (p_wcsrchr)
1324 test_wcsrchr();
1325 if (p_wcslwr && p_wcsupr)
1326 test_wcslwrupr();
1327 if (patoi)
1328 test_atoi();
1329 if (patol)
1330 test_atol();
1331 if (p_qsort)
1332 test_qsort();
1333 if (p_bsearch)
1334 test_bsearch();
1335 if (p__snprintf)
1336 test__snprintf();
1337 }