Added version information.
[wine] / dlls / ntdll / tests / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 <stdlib.h>
25
26 #include "winbase.h"
27 #include "wine/test.h"
28 #include "winnt.h"
29 #include "winnls.h"
30 #include "winternl.h"
31
32 /* Function ptrs for ntdll calls */
33 static HMODULE hntdll = 0;
34 static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);
35 static VOID     (WINAPI *pRtlFreeAnsiString)(PSTRING);
36 static BOOLEAN  (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING,LPCSTR);
37 static VOID     (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
38
39 static int      (WINAPIV *patoi)(const char *);
40 static long     (WINAPIV *patol)(const char *);
41 static LONGLONG (WINAPIV *p_atoi64)(const char *);
42 static LPSTR    (WINAPIV *p_itoa)(int, LPSTR, INT);
43 static LPSTR    (WINAPIV *p_ltoa)(long, LPSTR, INT);
44 static LPSTR    (WINAPIV *p_ultoa)(unsigned long, LPSTR, INT);
45 static LPSTR    (WINAPIV *p_i64toa)(LONGLONG, LPSTR, INT);
46 static LPSTR    (WINAPIV *p_ui64toa)(ULONGLONG, LPSTR, INT);
47
48 static int      (WINAPIV *p_wtoi)(LPWSTR);
49 static long     (WINAPIV *p_wtol)(LPWSTR);
50 static LONGLONG (WINAPIV *p_wtoi64)(LPWSTR);
51 static LPWSTR   (WINAPIV *p_itow)(int, LPWSTR, int);
52 static LPWSTR   (WINAPIV *p_ltow)(long, LPWSTR, INT);
53 static LPWSTR   (WINAPIV *p_ultow)(unsigned long, LPWSTR, INT);
54 static LPWSTR   (WINAPIV *p_i64tow)(LONGLONG, LPWSTR, INT);
55 static LPWSTR   (WINAPIV *p_ui64tow)(ULONGLONG, LPWSTR, INT);
56
57 static long     (WINAPIV *pwcstol)(LPCWSTR, LPWSTR *, INT);
58 static ULONG    (WINAPIV *pwcstoul)(LPCWSTR, LPWSTR *, INT);
59
60
61 static void InitFunctionPtrs()
62 {
63     hntdll = LoadLibraryA("ntdll.dll");
64     ok(hntdll != 0, "LoadLibrary failed");
65     if (hntdll) {
66         pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString");
67         pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString");
68         pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
69         pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
70
71         patoi = (void *)GetProcAddress(hntdll, "atoi");
72         patol = (void *)GetProcAddress(hntdll, "atol");
73         p_atoi64 = (void *)GetProcAddress(hntdll, "_atoi64");
74         p_itoa = (void *)GetProcAddress(hntdll, "_itoa");
75         p_ltoa = (void *)GetProcAddress(hntdll, "_ltoa");
76         p_ultoa = (void *)GetProcAddress(hntdll, "_ultoa");
77         p_i64toa = (void *)GetProcAddress(hntdll, "_i64toa");
78         p_ui64toa = (void *)GetProcAddress(hntdll, "_ui64toa");
79
80         p_wtoi = (void *)GetProcAddress(hntdll, "_wtoi");
81         p_wtol = (void *)GetProcAddress(hntdll, "_wtol");
82         p_wtoi64 = (void *)GetProcAddress(hntdll, "_wtoi64");
83         p_itow = (void *)GetProcAddress(hntdll, "_itow");
84         p_ltow = (void *)GetProcAddress(hntdll, "_ltow");
85         p_ultow = (void *)GetProcAddress(hntdll, "_ultow");
86         p_i64tow = (void *)GetProcAddress(hntdll, "_i64tow");
87         p_ui64tow = (void *)GetProcAddress(hntdll, "_ui64tow");
88
89         pwcstol = (void *)GetProcAddress(hntdll, "wcstol");
90         pwcstoul = (void *)GetProcAddress(hntdll, "wcstoul");
91     } /* if */
92 }
93
94
95 #define LARGE_STRI_BUFFER_LENGTH 67
96
97 typedef struct {
98     int base;
99     ULONG value;
100     char *Buffer;
101     int mask; /* ntdll/msvcrt: 0x01=itoa, 0x02=ltoa, 0x04=ultoa */
102               /*               0x10=itow, 0x20=ltow, 0x40=ultow */
103 } ulong2str_t;
104
105 static const ulong2str_t ulong2str[] = {
106     {10,         123, "123\0---------------------------------------------------------------", 0x77},
107
108     { 2, 0x80000000U, "10000000000000000000000000000000\0----------------------------------", 0x67},
109     { 2, -2147483647, "10000000000000000000000000000001\0----------------------------------", 0x67},
110     { 2,      -65537, "11111111111111101111111111111111\0----------------------------------", 0x67},
111     { 2,      -65536, "11111111111111110000000000000000\0----------------------------------", 0x67},
112     { 2,      -65535, "11111111111111110000000000000001\0----------------------------------", 0x67},
113     { 2,      -32768, "11111111111111111000000000000000\0----------------------------------", 0x67},
114     { 2,      -32767, "11111111111111111000000000000001\0----------------------------------", 0x67},
115     { 2,          -2, "11111111111111111111111111111110\0----------------------------------", 0x67},
116     { 2,          -1, "11111111111111111111111111111111\0----------------------------------", 0x67},
117     { 2,           0, "0\0-----------------------------------------------------------------", 0x77},
118     { 2,           1, "1\0-----------------------------------------------------------------", 0x77},
119     { 2,          10, "1010\0--------------------------------------------------------------", 0x77},
120     { 2,         100, "1100100\0-----------------------------------------------------------", 0x77},
121     { 2,        1000, "1111101000\0--------------------------------------------------------", 0x77},
122     { 2,       10000, "10011100010000\0----------------------------------------------------", 0x77},
123     { 2,       32767, "111111111111111\0---------------------------------------------------", 0x77},
124     { 2,       32768, "1000000000000000\0--------------------------------------------------", 0x77},
125     { 2,       65535, "1111111111111111\0--------------------------------------------------", 0x77},
126     { 2,      100000, "11000011010100000\0-------------------------------------------------", 0x77},
127     { 2,      234567, "111001010001000111\0------------------------------------------------", 0x77},
128     { 2,      300000, "1001001001111100000\0-----------------------------------------------", 0x77},
129     { 2,      524287, "1111111111111111111\0-----------------------------------------------", 0x77},
130     { 2,      524288, "10000000000000000000\0----------------------------------------------", 0x67},
131     { 2,     1000000, "11110100001001000000\0----------------------------------------------", 0x67},
132     { 2,    10000000, "100110001001011010000000\0------------------------------------------", 0x67},
133     { 2,   100000000, "101111101011110000100000000\0---------------------------------------", 0x67},
134     { 2,  1000000000, "111011100110101100101000000000\0------------------------------------", 0x67},
135     { 2,  1073741823, "111111111111111111111111111111\0------------------------------------", 0x67},
136     { 2,  2147483646, "1111111111111111111111111111110\0-----------------------------------", 0x67},
137     { 2,  2147483647, "1111111111111111111111111111111\0-----------------------------------", 0x67},
138     { 2, 2147483648U, "10000000000000000000000000000000\0----------------------------------", 0x67},
139     { 2, 2147483649U, "10000000000000000000000000000001\0----------------------------------", 0x67},
140     { 2, 4294967294U, "11111111111111111111111111111110\0----------------------------------", 0x67},
141     { 2,  0xFFFFFFFF, "11111111111111111111111111111111\0----------------------------------", 0x67},
142
143     { 8, 0x80000000U, "20000000000\0-------------------------------------------------------", 0x77},
144     { 8, -2147483647, "20000000001\0-------------------------------------------------------", 0x77},
145     { 8,          -2, "37777777776\0-------------------------------------------------------", 0x77},
146     { 8,          -1, "37777777777\0-------------------------------------------------------", 0x77},
147     { 8,           0, "0\0-----------------------------------------------------------------", 0x77},
148     { 8,           1, "1\0-----------------------------------------------------------------", 0x77},
149     { 8,  2147483646, "17777777776\0-------------------------------------------------------", 0x77},
150     { 8,  2147483647, "17777777777\0-------------------------------------------------------", 0x77},
151     { 8, 2147483648U, "20000000000\0-------------------------------------------------------", 0x77},
152     { 8, 2147483649U, "20000000001\0-------------------------------------------------------", 0x77},
153     { 8, 4294967294U, "37777777776\0-------------------------------------------------------", 0x77},
154     { 8, 4294967295U, "37777777777\0-------------------------------------------------------", 0x77},
155
156     {10, 0x80000000U, "-2147483648\0-------------------------------------------------------", 0x33},
157     {10, 0x80000000U, "2147483648\0--------------------------------------------------------", 0x44},
158     {10, -2147483647, "-2147483647\0-------------------------------------------------------", 0x33},
159     {10, -2147483647, "2147483649\0--------------------------------------------------------", 0x44},
160     {10,          -2, "-2\0----------------------------------------------------------------", 0x33},
161     {10,          -2, "4294967294\0--------------------------------------------------------", 0x44},
162     {10,          -1, "-1\0----------------------------------------------------------------", 0x33},
163     {10,          -1, "4294967295\0--------------------------------------------------------", 0x44},
164     {10,           0, "0\0-----------------------------------------------------------------", 0x77},
165     {10,           1, "1\0-----------------------------------------------------------------", 0x77},
166     {10,          12, "12\0----------------------------------------------------------------", 0x77},
167     {10,         123, "123\0---------------------------------------------------------------", 0x77},
168     {10,        1234, "1234\0--------------------------------------------------------------", 0x77},
169     {10,       12345, "12345\0-------------------------------------------------------------", 0x77},
170     {10,      123456, "123456\0------------------------------------------------------------", 0x77},
171     {10,     1234567, "1234567\0-----------------------------------------------------------", 0x77},
172     {10,    12345678, "12345678\0----------------------------------------------------------", 0x77},
173     {10,   123456789, "123456789\0---------------------------------------------------------", 0x77},
174     {10,  2147483646, "2147483646\0--------------------------------------------------------", 0x77},
175     {10,  2147483647, "2147483647\0--------------------------------------------------------", 0x77},
176     {10, 2147483648U, "-2147483648\0-------------------------------------------------------", 0x33},
177     {10, 2147483648U, "2147483648\0--------------------------------------------------------", 0x44},
178     {10, 2147483649U, "-2147483647\0-------------------------------------------------------", 0x33},
179     {10, 2147483649U, "2147483649\0--------------------------------------------------------", 0x44},
180     {10, 4294967294U, "-2\0----------------------------------------------------------------", 0x33},
181     {10, 4294967294U, "4294967294\0--------------------------------------------------------", 0x44},
182     {10, 4294967295U, "-1\0----------------------------------------------------------------", 0x33},
183     {10, 4294967295U, "4294967295\0--------------------------------------------------------", 0x44},
184
185     {16,           0, "0\0-----------------------------------------------------------------", 0x77},
186     {16,           1, "1\0-----------------------------------------------------------------", 0x77},
187     {16,  2147483646, "7ffffffe\0----------------------------------------------------------", 0x77},
188     {16,  2147483647, "7fffffff\0----------------------------------------------------------", 0x77},
189     {16,  0x80000000, "80000000\0----------------------------------------------------------", 0x77},
190     {16,  0x80000001, "80000001\0----------------------------------------------------------", 0x77},
191     {16,  0xFFFFFFFE, "fffffffe\0----------------------------------------------------------", 0x77},
192     {16,  0xFFFFFFFF, "ffffffff\0----------------------------------------------------------", 0x77},
193
194     { 2,       32768, "1000000000000000\0--------------------------------------------------", 0x77},
195     { 2,       65536, "10000000000000000\0-------------------------------------------------", 0x77},
196     { 2,      131072, "100000000000000000\0------------------------------------------------", 0x77},
197     {16,  0xffffffff, "ffffffff\0----------------------------------------------------------", 0x77},
198     {16,         0xa, "a\0-----------------------------------------------------------------", 0x77},
199     {16,           0, "0\0-----------------------------------------------------------------", 0x77},
200     {20,     3368421, "111111\0------------------------------------------------------------", 0x77},
201     {36,    62193781, "111111\0------------------------------------------------------------", 0x77},
202     {37,    71270178, "111111\0------------------------------------------------------------", 0x77},
203 };
204 #define NB_ULONG2STR (sizeof(ulong2str)/sizeof(*ulong2str))
205
206
207 static void one_itoa_test(int test_num, const ulong2str_t *ulong2str)
208 {
209     char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
210     int value;
211     LPSTR result;
212
213     memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
214     dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
215     value = ulong2str->value;
216     result = p_itoa(value, dest_str, ulong2str->base);
217     ok(result == dest_str,
218        "(test %d): _itoa(%d, [out], %d) has result %p, expected: %p",
219        test_num, value, ulong2str->base, result, dest_str);
220     ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
221        "(test %d): _itoa(%d, [out], %d) assigns string \"%s\", expected: \"%s\"",
222        test_num, value, ulong2str->base, dest_str, ulong2str->Buffer);
223 }
224
225
226 static void one_ltoa_test(int test_num, const ulong2str_t *ulong2str)
227 {
228     char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
229     long value;
230     LPSTR result;
231
232     memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
233     dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
234     value = ulong2str->value;
235     result = p_ltoa(ulong2str->value, dest_str, ulong2str->base);
236     ok(result == dest_str,
237        "(test %d): _ltoa(%ld, [out], %d) has result %p, expected: %p",
238        test_num, value, ulong2str->base, result, dest_str);
239     ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
240        "(test %d): _ltoa(%ld, [out], %d) assigns string \"%s\", expected: \"%s\"",
241        test_num, value, ulong2str->base, dest_str, ulong2str->Buffer);
242 }
243
244
245 static void one_ultoa_test(int test_num, const ulong2str_t *ulong2str)
246 {
247     char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
248     unsigned long value;
249     LPSTR result;
250
251     memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
252     dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
253     value = ulong2str->value;
254     result = p_ultoa(ulong2str->value, dest_str, ulong2str->base);
255     ok(result == dest_str,
256        "(test %d): _ultoa(%lu, [out], %d) has result %p, expected: %p",
257        test_num, value, ulong2str->base, result, dest_str);
258     ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
259        "(test %d): _ultoa(%lu, [out], %d) assigns string \"%s\", expected: \"%s\"",
260        test_num, value, ulong2str->base, dest_str, ulong2str->Buffer);
261 }
262
263
264 static void test_ulongtoa(void)
265 {
266     int test_num;
267
268     for (test_num = 0; test_num < NB_ULONG2STR; test_num++) {
269         if (ulong2str[test_num].mask & 0x01) {
270             one_itoa_test(test_num, &ulong2str[test_num]);
271         } /* if */
272         if (ulong2str[test_num].mask & 0x02) {
273             one_ltoa_test(test_num, &ulong2str[test_num]);
274         } /* if */
275         if (ulong2str[test_num].mask & 0x04) {
276             one_ultoa_test(test_num, &ulong2str[test_num]);
277         } /* if */
278     } /* for */
279 }
280
281
282 static void one_itow_test(int test_num, const ulong2str_t *ulong2str)
283 {
284     int pos;
285     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
286     WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
287     UNICODE_STRING unicode_string;
288     STRING ansi_str;
289     int value;
290     LPWSTR result;
291
292     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
293         expected_wstr[pos] = ulong2str->Buffer[pos];
294     } /* for */
295     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
296
297     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
298         dest_wstr[pos] = '-';
299     } /* for */
300     dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
301     unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
302     unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
303     unicode_string.Buffer = dest_wstr;
304     value = ulong2str->value;
305     result = p_itow(value, dest_wstr, ulong2str->base);
306     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
307     ok(result == dest_wstr,
308        "(test %d): _itow(%d, [out], %d) has result %p, expected: %p",
309        test_num, value, ulong2str->base, result, dest_wstr);
310     ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
311        "(test %d): _itow(%d, [out], %d) assigns string \"%s\", expected: \"%s\"",
312        test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer);
313     pRtlFreeAnsiString(&ansi_str);
314 }
315
316
317 static void one_ltow_test(int test_num, const ulong2str_t *ulong2str)
318 {
319     int pos;
320     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
321     WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
322     UNICODE_STRING unicode_string;
323     STRING ansi_str;
324     long value;
325     LPWSTR result;
326
327     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
328         expected_wstr[pos] = ulong2str->Buffer[pos];
329     } /* for */
330     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
331
332     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
333         dest_wstr[pos] = '-';
334     } /* for */
335     dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
336     unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
337     unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
338     unicode_string.Buffer = dest_wstr;
339
340     value = ulong2str->value;
341     result = p_ltow(value, dest_wstr, ulong2str->base);
342     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
343     ok(result == dest_wstr,
344        "(test %d): _ltow(%ld, [out], %d) has result %p, expected: %p",
345        test_num, value, ulong2str->base, result, dest_wstr);
346     ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
347        "(test %d): _ltow(%ld, [out], %d) assigns string \"%s\", expected: \"%s\"",
348        test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer);
349     pRtlFreeAnsiString(&ansi_str);
350 }
351
352
353 static void one_ultow_test(int test_num, const ulong2str_t *ulong2str)
354 {
355     int pos;
356     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
357     WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
358     UNICODE_STRING unicode_string;
359     STRING ansi_str;
360     unsigned long value;
361     LPWSTR result;
362
363     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
364         expected_wstr[pos] = ulong2str->Buffer[pos];
365     } /* for */
366     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
367
368     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
369         dest_wstr[pos] = '-';
370     } /* for */
371     dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
372     unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
373     unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
374     unicode_string.Buffer = dest_wstr;
375
376     value = ulong2str->value;
377     result = p_ultow(value, dest_wstr, ulong2str->base);
378     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
379     ok(result == dest_wstr,
380        "(test %d): _ultow(%lu, [out], %d) has result %p, expected: %p",
381        test_num, value, ulong2str->base, result, dest_wstr);
382     ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
383        "(test %d): _ultow(%lu, [out], %d) assigns string \"%s\", expected: \"%s\"",
384        test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer);
385     pRtlFreeAnsiString(&ansi_str);
386 }
387
388
389 static void test_ulongtow(void)
390 {
391     int test_num;
392     int pos;
393     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
394     LPWSTR result;
395
396     for (test_num = 0; test_num < NB_ULONG2STR; test_num++) {
397         if (ulong2str[test_num].mask & 0x10) {
398             one_itow_test(test_num, &ulong2str[test_num]);
399         } /* if */
400         if (ulong2str[test_num].mask & 0x20) {
401             one_ltow_test(test_num, &ulong2str[test_num]);
402         } /* if */
403         if (ulong2str[test_num].mask & 0x40) {
404             one_ultow_test(test_num, &ulong2str[test_num]);
405         } /* if */
406     } /* for */
407
408     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
409         expected_wstr[pos] = ulong2str[0].Buffer[pos];
410     } /* for */
411     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
412     result = p_itow(ulong2str[0].value, NULL, 10);
413     ok(result == NULL,
414        "(test a): _itow(%ld, NULL, 10) has result %p, expected: NULL",
415        ulong2str[0].value, result);
416
417     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
418         expected_wstr[pos] = ulong2str[0].Buffer[pos];
419     } /* for */
420     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
421     result = p_ltow(ulong2str[0].value, NULL, 10);
422     ok(result == NULL,
423        "(test b): _ltow(%ld, NULL, 10) has result %p, expected: NULL",
424        ulong2str[0].value, result);
425
426     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
427         expected_wstr[pos] = ulong2str[0].Buffer[pos];
428     } /* for */
429     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
430     result = p_ultow(ulong2str[0].value, NULL, 10);
431     ok(result == NULL,
432        "(test c): _ultow(%ld, NULL, 10) has result %p, expected: NULL",
433        ulong2str[0].value, result);
434 }
435
436
437 typedef struct {
438     int base;
439     ULONGLONG value;
440     char *Buffer;
441     int mask; /* ntdll/msvcrt: 0x01=i64toa, 0x02=ui64toa, 0x04=wrong _i64toa try next example */
442               /*               0x10=i64tow, 0x20=ui64tow, 0x40=wrong _i64tow try next example */
443 } ulonglong2str_t;
444
445 static const ulonglong2str_t ulonglong2str[] = {
446     {10,          123, "123\0---------------------------------------------------------------", 0x33},
447
448     { 2,  0x80000000U, "10000000000000000000000000000000\0----------------------------------", 0x33},
449     { 2,  -2147483647, "1111111111111111111111111111111110000000000000000000000000000001\0--", 0x33},
450     { 2,       -65537, "1111111111111111111111111111111111111111111111101111111111111111\0--", 0x33},
451     { 2,       -65536, "1111111111111111111111111111111111111111111111110000000000000000\0--", 0x33},
452     { 2,       -65535, "1111111111111111111111111111111111111111111111110000000000000001\0--", 0x33},
453     { 2,       -32768, "1111111111111111111111111111111111111111111111111000000000000000\0--", 0x33},
454     { 2,       -32767, "1111111111111111111111111111111111111111111111111000000000000001\0--", 0x33},
455     { 2,           -2, "1111111111111111111111111111111111111111111111111111111111111110\0--", 0x33},
456     { 2,           -1, "1111111111111111111111111111111111111111111111111111111111111111\0--", 0x33},
457     { 2,            0, "0\0-----------------------------------------------------------------", 0x33},
458     { 2,            1, "1\0-----------------------------------------------------------------", 0x33},
459     { 2,           10, "1010\0--------------------------------------------------------------", 0x33},
460     { 2,          100, "1100100\0-----------------------------------------------------------", 0x33},
461     { 2,         1000, "1111101000\0--------------------------------------------------------", 0x33},
462     { 2,        10000, "10011100010000\0----------------------------------------------------", 0x33},
463     { 2,        32767, "111111111111111\0---------------------------------------------------", 0x33},
464     { 2,        32768, "1000000000000000\0--------------------------------------------------", 0x33},
465     { 2,        65535, "1111111111111111\0--------------------------------------------------", 0x33},
466     { 2,       100000, "11000011010100000\0-------------------------------------------------", 0x33},
467     { 2,       234567, "111001010001000111\0------------------------------------------------", 0x33},
468     { 2,       300000, "1001001001111100000\0-----------------------------------------------", 0x33},
469     { 2,       524287, "1111111111111111111\0-----------------------------------------------", 0x33},
470     { 2,       524288, "10000000000000000000\0----------------------------------------------", 0x33},
471     { 2,      1000000, "11110100001001000000\0----------------------------------------------", 0x33},
472     { 2,     10000000, "100110001001011010000000\0------------------------------------------", 0x33},
473     { 2,    100000000, "101111101011110000100000000\0---------------------------------------", 0x33},
474     { 2,   1000000000, "111011100110101100101000000000\0------------------------------------", 0x33},
475     { 2,   1073741823, "111111111111111111111111111111\0------------------------------------", 0x33},
476     { 2,   2147483646, "1111111111111111111111111111110\0-----------------------------------", 0x33},
477     { 2,   2147483647, "1111111111111111111111111111111\0-----------------------------------", 0x33},
478     { 2,  2147483648U, "10000000000000000000000000000000\0----------------------------------", 0x33},
479     { 2,  2147483649U, "10000000000000000000000000000001\0----------------------------------", 0x33},
480     { 2,  4294967294U, "11111111111111111111111111111110\0----------------------------------", 0x33},
481     { 2,   0xFFFFFFFF, "11111111111111111111111111111111\0----------------------------------", 0x33},
482     { 2,  0x1FFFFFFFF, "111111111111111111111111111111111\0---------------------------------", 0x33},
483     { 2,  10000000000, "1001010100000010111110010000000000\0--------------------------------", 0x33},
484     { 2,  0x3FFFFFFFF, "1111111111111111111111111111111111\0--------------------------------", 0x33},
485     { 2,  0x7FFFFFFFF, "11111111111111111111111111111111111\0-------------------------------", 0x33},
486     { 2,  0xFFFFFFFFF, "111111111111111111111111111111111111\0------------------------------", 0x33},
487     { 2, 100000000000, "1011101001000011101101110100000000000\0-----------------------------", 0x33},
488     { 2, 0x1FFFFFFFFF, "1111111111111111111111111111111111111\0-----------------------------", 0x33},
489     { 2, 0x3FFFFFFFFF, "11111111111111111111111111111111111111\0----------------------------", 0x33},
490     { 2, 0x7FFFFFFFFF, "111111111111111111111111111111111111111\0---------------------------", 0x33},
491     { 2, 0xFFFFFFFFFF, "1111111111111111111111111111111111111111\0--------------------------", 0x33},
492
493     { 8,  0x80000000U, "20000000000\0-------------------------------------------------------", 0x33},
494     { 8,  -2147483647, "1777777777760000000001\0--------------------------------------------", 0x33},
495     { 8,           -2, "1777777777777777777776\0--------------------------------------------", 0x33},
496     { 8,           -1, "1777777777777777777777\0--------------------------------------------", 0x33},
497     { 8,            0, "0\0-----------------------------------------------------------------", 0x33},
498     { 8,            1, "1\0-----------------------------------------------------------------", 0x33},
499     { 8,   2147483646, "17777777776\0-------------------------------------------------------", 0x33},
500     { 8,   2147483647, "17777777777\0-------------------------------------------------------", 0x33},
501     { 8,  2147483648U, "20000000000\0-------------------------------------------------------", 0x33},
502     { 8,  2147483649U, "20000000001\0-------------------------------------------------------", 0x33},
503     { 8,  4294967294U, "37777777776\0-------------------------------------------------------", 0x33},
504     { 8,  4294967295U, "37777777777\0-------------------------------------------------------", 0x33},
505
506     {10,  0x80000000U, "2147483648\0--------------------------------------------------------", 0x33},
507     {10,  -2147483647, "-2147483647\0-------------------------------------------------------", 0x55},
508     {10,  -2147483647, "-18446744071562067969\0---------------------------------------------", 0x00},
509     {10,  -2147483647, "18446744071562067969\0----------------------------------------------", 0x22},
510     {10,           -2, "-2\0----------------------------------------------------------------", 0x55},
511     {10,           -2, "-18446744073709551614\0---------------------------------------------", 0x00},
512     {10,           -2, "18446744073709551614\0----------------------------------------------", 0x22},
513     {10,           -1, "-1\0----------------------------------------------------------------", 0x55},
514     {10,           -1, "-18446744073709551615\0---------------------------------------------", 0x00},
515     {10,           -1, "18446744073709551615\0----------------------------------------------", 0x22},
516     {10,            0, "0\0-----------------------------------------------------------------", 0x33},
517     {10,            1, "1\0-----------------------------------------------------------------", 0x33},
518     {10,           12, "12\0----------------------------------------------------------------", 0x33},
519     {10,          123, "123\0---------------------------------------------------------------", 0x33},
520     {10,         1234, "1234\0--------------------------------------------------------------", 0x33},
521     {10,        12345, "12345\0-------------------------------------------------------------", 0x33},
522     {10,       123456, "123456\0------------------------------------------------------------", 0x33},
523     {10,      1234567, "1234567\0-----------------------------------------------------------", 0x33},
524     {10,     12345678, "12345678\0----------------------------------------------------------", 0x33},
525     {10,    123456789, "123456789\0---------------------------------------------------------", 0x33},
526     {10,   2147483646, "2147483646\0--------------------------------------------------------", 0x33},
527     {10,   2147483647, "2147483647\0--------------------------------------------------------", 0x33},
528     {10,  2147483648U, "2147483648\0--------------------------------------------------------", 0x33},
529     {10,  2147483649U, "2147483649\0--------------------------------------------------------", 0x33},
530     {10,  4294967294U, "4294967294\0--------------------------------------------------------", 0x33},
531     {10,  4294967295U, "4294967295\0--------------------------------------------------------", 0x33},
532     {10,       12345678901U, "12345678901\0-------------------------------------------------------", 0x33},
533     {10,      987654321012U, "987654321012\0------------------------------------------------------", 0x33},
534     {10,     1928374656574U, "1928374656574\0-----------------------------------------------------", 0x33},
535     {10,      0xBADCAFEFACE, "12841062955726\0----------------------------------------------------", 0x33},
536     {10,     0x5BADCAFEFACE, "100801993177806\0---------------------------------------------------", 0x33},
537     {10,    0xAFACEBEEFCAFE, "3090515640699646\0--------------------------------------------------", 0x33},
538     {10,   0xA5BEEFABCDCAFE, "46653307746110206\0-------------------------------------------------", 0x33},
539     {10,  0x1F8CF9BF2DF3AF1, "142091656963767025\0------------------------------------------------", 0x33},
540     {10,  0xFFFFFFFFFFFFFFF, "1152921504606846975\0-----------------------------------------------", 0x33},
541     {10, 0x7FFFFFFFFFFFFFFF, "9223372036854775807\0-----------------------------------------------", 0x33},
542     {10, 0x8000000000000000, "-9223372036854775808\0----------------------------------------------", 0x11},
543     {10, 0x8000000000000000, "9223372036854775808\0-----------------------------------------------", 0x22},
544     {10, 0x8000000000000001, "-9223372036854775807\0----------------------------------------------", 0x55},
545     {10, 0x8000000000000001, "-9223372036854775809\0----------------------------------------------", 0x00},
546     {10, 0x8000000000000001, "9223372036854775809\0-----------------------------------------------", 0x22},
547     {10, 0x8000000000000002, "-9223372036854775806\0----------------------------------------------", 0x55},
548     {10, 0x8000000000000002, "-9223372036854775810\0----------------------------------------------", 0x00},
549     {10, 0x8000000000000002, "9223372036854775810\0-----------------------------------------------", 0x22},
550     {10, 0xFFFFFFFFFFFFFFFE, "-2\0----------------------------------------------------------------", 0x55},
551     {10, 0xFFFFFFFFFFFFFFFE, "-18446744073709551614\0---------------------------------------------", 0x00},
552     {10, 0xFFFFFFFFFFFFFFFE, "18446744073709551614\0----------------------------------------------", 0x22},
553     {10, 0xFFFFFFFFFFFFFFFF, "-1\0----------------------------------------------------------------", 0x55},
554     {10, 0xFFFFFFFFFFFFFFFF, "-18446744073709551615\0---------------------------------------------", 0x00},
555     {10, 0xFFFFFFFFFFFFFFFF, "18446744073709551615\0----------------------------------------------", 0x22},
556
557     {16,                  0, "0\0-----------------------------------------------------------------", 0x33},
558     {16,                  1, "1\0-----------------------------------------------------------------", 0x33},
559     {16,         2147483646, "7ffffffe\0----------------------------------------------------------", 0x33},
560     {16,         2147483647, "7fffffff\0----------------------------------------------------------", 0x33},
561     {16,         0x80000000, "80000000\0----------------------------------------------------------", 0x33},
562     {16,         0x80000001, "80000001\0----------------------------------------------------------", 0x33},
563     {16,         0xFFFFFFFE, "fffffffe\0----------------------------------------------------------", 0x33},
564     {16,         0xFFFFFFFF, "ffffffff\0----------------------------------------------------------", 0x33},
565     {16,        0x100000000, "100000000\0---------------------------------------------------------", 0x33},
566     {16,      0xBADDEADBEEF, "baddeadbeef\0-------------------------------------------------------", 0x33},
567     {16, 0x8000000000000000, "8000000000000000\0--------------------------------------------------", 0x33},
568     {16, 0xFEDCBA9876543210, "fedcba9876543210\0--------------------------------------------------", 0x33},
569     {16, 0xFFFFFFFF80000001, "ffffffff80000001\0--------------------------------------------------", 0x33},
570     {16, 0xFFFFFFFFFFFFFFFE, "fffffffffffffffe\0--------------------------------------------------", 0x33},
571     {16, 0xFFFFFFFFFFFFFFFF, "ffffffffffffffff\0--------------------------------------------------", 0x33},
572
573     { 2,        32768, "1000000000000000\0--------------------------------------------------", 0x33},
574     { 2,        65536, "10000000000000000\0-------------------------------------------------", 0x33},
575     { 2,       131072, "100000000000000000\0------------------------------------------------", 0x33},
576     {16,   0xffffffff, "ffffffff\0----------------------------------------------------------", 0x33},
577     {16,          0xa, "a\0-----------------------------------------------------------------", 0x33},
578     {16,            0, "0\0-----------------------------------------------------------------", 0x33},
579     {20,      3368421, "111111\0------------------------------------------------------------", 0x33},
580     {36,     62193781, "111111\0------------------------------------------------------------", 0x33},
581     {37,     71270178, "111111\0------------------------------------------------------------", 0x33},
582     {99,   9606940300, "111111\0------------------------------------------------------------", 0x33},
583 };
584 #define NB_ULONGLONG2STR (sizeof(ulonglong2str)/sizeof(*ulonglong2str))
585
586
587 static void one_i64toa_test(int test_num, const ulonglong2str_t *ulonglong2str)
588 {
589     LPSTR result;
590     char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
591
592     memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
593     dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
594     result = p_i64toa(ulonglong2str->value, dest_str, ulonglong2str->base);
595     ok(result == dest_str,
596        "(test %d): _i64toa(%Lu, [out], %d) has result %p, expected: %p",
597        test_num, ulonglong2str->value, ulonglong2str->base, result, dest_str);
598     if (ulonglong2str->mask & 0x04) {
599         if (memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) != 0) {
600             if (memcmp(dest_str, ulonglong2str[1].Buffer, LARGE_STRI_BUFFER_LENGTH) != 0) {
601                 ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
602                    "(test %d): _i64toa(%Lu, [out], %d) assigns string \"%s\", expected: \"%s\"",
603                    test_num, ulonglong2str->value, ulonglong2str->base, dest_str, ulonglong2str->Buffer);
604             } /* if */
605         } /* if */
606     } else {
607         ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
608            "(test %d): _i64toa(%Lu, [out], %d) assigns string \"%s\", expected: \"%s\"",
609            test_num, ulonglong2str->value, ulonglong2str->base, dest_str, ulonglong2str->Buffer);
610     } /* if */
611 }
612
613
614 static void one_ui64toa_test(int test_num, const ulonglong2str_t *ulonglong2str)
615 {
616     LPSTR result;
617     char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
618
619     memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
620     dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
621     result = p_ui64toa(ulonglong2str->value, dest_str, ulonglong2str->base);
622     ok(result == dest_str,
623        "(test %d): _ui64toa(%Lu, [out], %d) has result %p, expected: %p",
624        test_num, ulonglong2str->value, ulonglong2str->base, result, dest_str);
625     ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
626        "(test %d): _ui64toa(%Lu, [out], %d) assigns string \"%s\", expected: \"%s\"",
627        test_num, ulonglong2str->value, ulonglong2str->base, dest_str, ulonglong2str->Buffer);
628 }
629
630
631 static void test_ulonglongtoa(void)
632 {
633     int test_num;
634
635     for (test_num = 0; test_num < NB_ULONGLONG2STR; test_num++) {
636         if (ulonglong2str[test_num].mask & 0x01) {
637             one_i64toa_test(test_num, &ulonglong2str[test_num]);
638         } /* if */
639         if (p_ui64toa != NULL) {
640             if (ulonglong2str[test_num].mask & 0x02) {
641                 one_ui64toa_test(test_num, &ulonglong2str[test_num]);
642             } /* if */
643         } /* if */
644     } /* for */
645 }
646
647
648 static void one_i64tow_test(int test_num, const ulonglong2str_t *ulonglong2str)
649 {
650     int pos;
651     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
652     WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
653     UNICODE_STRING unicode_string;
654     STRING ansi_str;
655     LPWSTR result;
656
657     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
658         expected_wstr[pos] = ulonglong2str->Buffer[pos];
659     } /* for */
660     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
661
662     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
663         dest_wstr[pos] = '-';
664     } /* for */
665     dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
666     unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
667     unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
668     unicode_string.Buffer = dest_wstr;
669
670     result = p_i64tow(ulonglong2str->value, dest_wstr, ulonglong2str->base);
671     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
672     ok(result == dest_wstr,
673        "(test %d): _i64tow(%llu, [out], %d) has result %p, expected: %p",
674        test_num, ulonglong2str->value, ulonglong2str->base, result, dest_wstr);
675     if (ulonglong2str->mask & 0x04) {
676         if (memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) != 0) {
677             for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
678                 expected_wstr[pos] = ulonglong2str[1].Buffer[pos];
679             } /* for */
680             expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
681             if (memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) != 0) {
682                 ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
683                    "(test %d): _i64tow(%llu, [out], %d) assigns string \"%s\", expected: \"%s\"",
684                    test_num, ulonglong2str->value, ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer);
685             } /* if */
686         } /* if */
687     } else {
688         ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
689            "(test %d): _i64tow(%llu, [out], %d) assigns string \"%s\", expected: \"%s\"",
690            test_num, ulonglong2str->value, ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer);
691     } /* if */
692     pRtlFreeAnsiString(&ansi_str);
693 }
694
695
696 static void one_ui64tow_test(int test_num, const ulonglong2str_t *ulonglong2str)
697 {
698     int pos;
699     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
700     WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
701     UNICODE_STRING unicode_string;
702     STRING ansi_str;
703     LPWSTR result;
704
705     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
706         expected_wstr[pos] = ulonglong2str->Buffer[pos];
707     } /* for */
708     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
709
710     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
711         dest_wstr[pos] = '-';
712     } /* for */
713     dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
714     unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
715     unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
716     unicode_string.Buffer = dest_wstr;
717
718     result = p_ui64tow(ulonglong2str->value, dest_wstr, ulonglong2str->base);
719     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
720     ok(result == dest_wstr,
721        "(test %d): _ui64tow(%llu, [out], %d) has result %p, expected: %p",
722        test_num, ulonglong2str->value, ulonglong2str->base, result, dest_wstr);
723     ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
724        "(test %d): _ui64tow(%llu, [out], %d) assigns string \"%s\", expected: \"%s\"",
725        test_num, ulonglong2str->value, ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer);
726     pRtlFreeAnsiString(&ansi_str);
727 }
728
729
730 static void test_ulonglongtow(void)
731 {
732     int test_num;
733     int pos;
734     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
735     LPWSTR result;
736
737     for (test_num = 0; test_num < NB_ULONGLONG2STR; test_num++) {
738         if (ulonglong2str[test_num].mask & 0x10) {
739             one_i64tow_test(test_num, &ulonglong2str[test_num]);
740         } /* if */
741         if (p_ui64tow) {
742             if (ulonglong2str[test_num].mask & 0x20) {
743                 one_ui64tow_test(test_num, &ulonglong2str[test_num]);
744             } /* if */
745         } /* if */
746     } /* for */
747
748     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
749         expected_wstr[pos] = ulong2str[0].Buffer[pos];
750     } /* for */
751     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
752     result = p_i64tow(ulong2str[0].value, NULL, 10);
753     ok(result == NULL,
754        "(test d): _i64tow(%llu, NULL, 10) has result %p, expected: NULL",
755        ulonglong2str[0].value, result);
756
757     if (p_ui64tow) {
758         for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
759             expected_wstr[pos] = ulong2str[0].Buffer[pos];
760         } /* for */
761         expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
762         result = p_ui64tow(ulong2str[0].value, NULL, 10);
763         ok(result == NULL,
764            "(test e): _ui64tow(%llu, NULL, 10) has result %p, expected: NULL",
765            ulonglong2str[0].value, result);
766     } /* if */
767 }
768
769
770 typedef struct {
771     char *str;
772     LONG value;
773 } str2long_t;
774
775 static const str2long_t str2long[] = {
776     { "1011101100",   1011101100   },
777     { "1234567",         1234567   },
778     { "-214",               -214   },
779     { "+214",                214   }, /* The + sign is allowed also */
780     { "--214",                 0   }, /* Do not accept more than one sign */
781     { "-+214",                 0   },
782     { "++214",                 0   },
783     { "+-214",                 0   },
784     { "\00141",                0   }, /* not whitespace char  1 */
785     { "\00242",                0   }, /* not whitespace char  2 */
786     { "\00343",                0   }, /* not whitespace char  3 */
787     { "\00444",                0   }, /* not whitespace char  4 */
788     { "\00545",                0   }, /* not whitespace char  5 */
789     { "\00646",                0   }, /* not whitespace char  6 */
790     { "\00747",                0   }, /* not whitespace char  7 */
791     { "\01050",                0   }, /* not whitespace char  8 */
792     { "\01151",               51   }, /*  is whitespace char  9 (tab) */
793     { "\01252",               52   }, /*  is whitespace char 10 (lf) */
794     { "\01353",               53   }, /*  is whitespace char 11 (vt) */
795     { "\01454",               54   }, /*  is whitespace char 12 (ff) */
796     { "\01555",               55   }, /*  is whitespace char 13 (cr) */
797     { "\01656",                0   }, /* not whitespace char 14 */
798     { "\01757",                0   }, /* not whitespace char 15 */
799     { "\02060",                0   }, /* not whitespace char 16 */
800     { "\02161",                0   }, /* not whitespace char 17 */
801     { "\02262",                0   }, /* not whitespace char 18 */
802     { "\02363",                0   }, /* not whitespace char 19 */
803     { "\02464",                0   }, /* not whitespace char 20 */
804     { "\02565",                0   }, /* not whitespace char 21 */
805     { "\02666",                0   }, /* not whitespace char 22 */
806     { "\02767",                0   }, /* not whitespace char 23 */
807     { "\03070",                0   }, /* not whitespace char 24 */
808     { "\03171",                0   }, /* not whitespace char 25 */
809     { "\03272",                0   }, /* not whitespace char 26 */
810     { "\03373",                0   }, /* not whitespace char 27 */
811     { "\03474",                0   }, /* not whitespace char 28 */
812     { "\03575",                0   }, /* not whitespace char 29 */
813     { "\03676",                0   }, /* not whitespace char 30 */
814     { "\03777",                0   }, /* not whitespace char 31 */
815     { "\04080",               80   }, /*  is whitespace char 32 (space) */
816     { " \n \r \t214",        214   },
817     { " \n \r \t+214",       214   }, /* Signs can be used after whitespace */
818     { " \n \r \t-214",      -214   },
819     { "+214 0",              214   }, /* Space terminates the number */
820     { " 214.01",             214   }, /* Decimal point not accepted */
821     { " 214,01",             214   }, /* Decimal comma not accepted */
822     { "f81",                   0   },
823     { "0x12345",               0   }, /* Hex not accepted */
824     { "00x12345",              0   },
825     { "0xx12345",              0   },
826     { "1x34",                  1   },
827     { "-9999999999", -1410065407   }, /* Big negative integer */
828     { "-2147483649",  2147483647   }, /* Too small to fit in 32 Bits */
829     { "-2147483648",  0x80000000   }, /* Smallest negative integer */
830     { "-2147483647", -2147483647   },
831     { "-1",                   -1   },
832     { "0",                     0   },
833     { "1",                     1   },
834     { "2147483646",   2147483646   },
835     { "2147483647",   2147483647   }, /* Largest signed positive integer */
836     { "2147483648",   2147483648UL }, /* Positive int equal to smallest negative int */
837     { "2147483649",   2147483649UL },
838     { "4294967294",   4294967294UL },
839     { "4294967295",   4294967295UL }, /* Largest unsigned integer */
840     { "4294967296",            0   }, /* Too big to fit in 32 Bits */
841     { "9999999999",   1410065407   }, /* Big positive integer */
842     { "056789",            56789   }, /* Leading zero and still decimal */
843     { "b1011101100",           0   }, /* Binary (b-notation) */
844     { "-b1011101100",          0   }, /* Negative Binary (b-notation) */
845     { "b10123456789",          0   }, /* Binary with nonbinary digits (2-9) */
846     { "0b1011101100",          0   }, /* Binary (0b-notation) */
847     { "-0b1011101100",         0   }, /* Negative binary (0b-notation) */
848     { "0b10123456789",         0   }, /* Binary with nonbinary digits (2-9) */
849     { "-0b10123456789",        0   }, /* Negative binary with nonbinary digits (2-9) */
850     { "0b1",                   0   }, /* one digit binary */
851     { "0b2",                   0   }, /* empty binary */
852     { "0b",                    0   }, /* empty binary */
853     { "o1234567",              0   }, /* Octal (o-notation) */
854     { "-o1234567",             0   }, /* Negative Octal (o-notation) */
855     { "o56789",                0   }, /* Octal with nonoctal digits (8 and 9) */
856     { "0o1234567",             0   }, /* Octal (0o-notation) */
857     { "-0o1234567",            0   }, /* Negative octal (0o-notation) */
858     { "0o56789",               0   }, /* Octal with nonoctal digits (8 and 9) */
859     { "-0o56789",              0   }, /* Negative octal with nonoctal digits (8 and 9) */
860     { "0o7",                   0   }, /* one digit octal */
861     { "0o8",                   0   }, /* empty octal */
862     { "0o",                    0   }, /* empty octal */
863     { "0d1011101100",          0   }, /* explizit decimal with 0d */
864     { "x89abcdef",             0   }, /* Hex with lower case digits a-f (x-notation) */
865     { "xFEDCBA00",             0   }, /* Hex with upper case digits A-F (x-notation) */
866     { "-xFEDCBA00",            0   }, /* Negative Hexadecimal (x-notation) */
867     { "0x89abcdef",            0   }, /* Hex with lower case digits a-f (0x-notation) */
868     { "0xFEDCBA00",            0   }, /* Hex with upper case digits A-F (0x-notation) */
869     { "-0xFEDCBA00",           0   }, /* Negative Hexadecimal (0x-notation) */
870     { "0xabcdefgh",            0   }, /* Hex with illegal lower case digits (g-z) */
871     { "0xABCDEFGH",            0   }, /* Hex with illegal upper case digits (G-Z) */
872     { "0xF",                   0   }, /* one digit hexadecimal */
873     { "0xG",                   0   }, /* empty hexadecimal */
874     { "0x",                    0   }, /* empty hexadecimal */
875     { "",                      0   }, /* empty string */
876 /*  { NULL,                    0   }, */ /* NULL as string */
877 };
878 #define NB_STR2LONG (sizeof(str2long)/sizeof(*str2long))
879
880
881 static void test_wtoi(void)
882 {
883     int test_num;
884     UNICODE_STRING uni;
885     int result;
886
887     for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
888         pRtlCreateUnicodeStringFromAsciiz(&uni, str2long[test_num].str);
889         result = p_wtoi(uni.Buffer);
890         ok(result == str2long[test_num].value,
891            "(test %d): call failed: _wtoi(\"%s\") has result %d, expected: %ld",
892            test_num, str2long[test_num].str, result, str2long[test_num].value);
893         pRtlFreeUnicodeString(&uni);
894     } /* for */
895 }
896
897
898 static void test_wtol(void)
899 {
900     int test_num;
901     UNICODE_STRING uni;
902     LONG result;
903
904     for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
905         pRtlCreateUnicodeStringFromAsciiz(&uni, str2long[test_num].str);
906         result = p_wtol(uni.Buffer);
907         ok(result == str2long[test_num].value,
908            "(test %d): call failed: _wtol(\"%s\") has result %ld, expected: %ld",
909            test_num, str2long[test_num].str, result, str2long[test_num].value);
910         pRtlFreeUnicodeString(&uni);
911     } /* for */
912 }
913
914
915 typedef struct {
916     char *str;
917     LONGLONG value;
918 } str2longlong_t;
919
920 static const str2longlong_t str2longlong[] = {
921     { "1011101100",   1011101100   },
922     { "1234567",         1234567   },
923     { "-214",               -214   },
924     { "+214",                214   }, /* The + sign is allowed also */
925     { "--214",                 0   }, /* Do not accept more than one sign */
926     { "-+214",                 0   },
927     { "++214",                 0   },
928     { "+-214",                 0   },
929     { "\00141",                0   }, /* not whitespace char  1 */
930     { "\00242",                0   }, /* not whitespace char  2 */
931     { "\00343",                0   }, /* not whitespace char  3 */
932     { "\00444",                0   }, /* not whitespace char  4 */
933     { "\00545",                0   }, /* not whitespace char  5 */
934     { "\00646",                0   }, /* not whitespace char  6 */
935     { "\00747",                0   }, /* not whitespace char  7 */
936     { "\01050",                0   }, /* not whitespace char  8 */
937     { "\01151",               51   }, /*  is whitespace char  9 (tab) */
938     { "\01252",               52   }, /*  is whitespace char 10 (lf) */
939     { "\01353",               53   }, /*  is whitespace char 11 (vt) */
940     { "\01454",               54   }, /*  is whitespace char 12 (ff) */
941     { "\01555",               55   }, /*  is whitespace char 13 (cr) */
942     { "\01656",                0   }, /* not whitespace char 14 */
943     { "\01757",                0   }, /* not whitespace char 15 */
944     { "\02060",                0   }, /* not whitespace char 16 */
945     { "\02161",                0   }, /* not whitespace char 17 */
946     { "\02262",                0   }, /* not whitespace char 18 */
947     { "\02363",                0   }, /* not whitespace char 19 */
948     { "\02464",                0   }, /* not whitespace char 20 */
949     { "\02565",                0   }, /* not whitespace char 21 */
950     { "\02666",                0   }, /* not whitespace char 22 */
951     { "\02767",                0   }, /* not whitespace char 23 */
952     { "\03070",                0   }, /* not whitespace char 24 */
953     { "\03171",                0   }, /* not whitespace char 25 */
954     { "\03272",                0   }, /* not whitespace char 26 */
955     { "\03373",                0   }, /* not whitespace char 27 */
956     { "\03474",                0   }, /* not whitespace char 28 */
957     { "\03575",                0   }, /* not whitespace char 29 */
958     { "\03676",                0   }, /* not whitespace char 30 */
959     { "\03777",                0   }, /* not whitespace char 31 */
960     { "\04080",               80   }, /*  is whitespace char 32 (space) */
961     { " \n \r \t214",        214   },
962     { " \n \r \t+214",       214   }, /* Signs can be used after whitespace */
963     { " \n \r \t-214",      -214   },
964     { "+214 0",              214   }, /* Space terminates the number */
965     { " 214.01",             214   }, /* Decimal point not accepted */
966     { " 214,01",             214   }, /* Decimal comma not accepted */
967     { "f81",                   0   },
968     { "0x12345",               0   }, /* Hex not accepted */
969     { "00x12345",              0   },
970     { "0xx12345",              0   },
971     { "1x34",                  1   },
972     { "-99999999999999999999",  -7766279631452241919   }, /* Big negative integer */
973     { "-9223372036854775809",    9223372036854775807   }, /* Too small to fit in 64 bits */
974     { "-9223372036854775808",     0x8000000000000000   }, /* Smallest negativ 64 bit integer */
975     { "-9223372036854775807",   -9223372036854775807   },
976     { "-9999999999",                     -9999999999   },
977     { "-2147483649",                     -2147483649LL }, /* Too small to fit in 32 bits */
978     { "-2147483648",                     -2147483648LL }, /* Smallest 32 bits negative integer */
979     { "-2147483647",                     -2147483647   },
980     { "-1",                                       -1   },
981     { "0",                                         0   },
982     { "1",                                         1   },
983     { "2147483646",                       2147483646   },
984     { "2147483647",                       2147483647   }, /* Largest signed positive 32 bit integer */
985     { "2147483648",                       2147483648LL }, /* Pos int equal to smallest neg 32 bit int */
986     { "2147483649",                       2147483649LL },
987     { "4294967294",                       4294967294LL },
988     { "4294967295",                       4294967295LL }, /* Largest unsigned 32 bit integer */
989     { "4294967296",                       4294967296   }, /* Too big to fit in 32 Bits */
990     { "9999999999",                       9999999999   },
991     { "9223372036854775806",     9223372036854775806   }, 
992     { "9223372036854775807",     9223372036854775807   }, /* Largest signed positive 64 bit integer */
993     { "9223372036854775808",     9223372036854775808ULL}, /* Pos int equal to smallest neg 64 bit int */
994     { "9223372036854775809",     9223372036854775809ULL},
995     { "18446744073709551614",   18446744073709551614ULL},
996     { "18446744073709551615",   18446744073709551615ULL}, /* Largest unsigned 64 bit integer */
997     { "18446744073709551616",                      0   }, /* Too big to fit in 64 bits */
998     { "99999999999999999999",    7766279631452241919   }, /* Big positive integer */
999     { "056789",            56789   }, /* Leading zero and still decimal */
1000     { "b1011101100",           0   }, /* Binary (b-notation) */
1001     { "-b1011101100",          0   }, /* Negative Binary (b-notation) */
1002     { "b10123456789",          0   }, /* Binary with nonbinary digits (2-9) */
1003     { "0b1011101100",          0   }, /* Binary (0b-notation) */
1004     { "-0b1011101100",         0   }, /* Negative binary (0b-notation) */
1005     { "0b10123456789",         0   }, /* Binary with nonbinary digits (2-9) */
1006     { "-0b10123456789",        0   }, /* Negative binary with nonbinary digits (2-9) */
1007     { "0b1",                   0   }, /* one digit binary */
1008     { "0b2",                   0   }, /* empty binary */
1009     { "0b",                    0   }, /* empty binary */
1010     { "o1234567",              0   }, /* Octal (o-notation) */
1011     { "-o1234567",             0   }, /* Negative Octal (o-notation) */
1012     { "o56789",                0   }, /* Octal with nonoctal digits (8 and 9) */
1013     { "0o1234567",             0   }, /* Octal (0o-notation) */
1014     { "-0o1234567",            0   }, /* Negative octal (0o-notation) */
1015     { "0o56789",               0   }, /* Octal with nonoctal digits (8 and 9) */
1016     { "-0o56789",              0   }, /* Negative octal with nonoctal digits (8 and 9) */
1017     { "0o7",                   0   }, /* one digit octal */
1018     { "0o8",                   0   }, /* empty octal */
1019     { "0o",                    0   }, /* empty octal */
1020     { "0d1011101100",          0   }, /* explizit decimal with 0d */
1021     { "x89abcdef",             0   }, /* Hex with lower case digits a-f (x-notation) */
1022     { "xFEDCBA00",             0   }, /* Hex with upper case digits A-F (x-notation) */
1023     { "-xFEDCBA00",            0   }, /* Negative Hexadecimal (x-notation) */
1024     { "0x89abcdef",            0   }, /* Hex with lower case digits a-f (0x-notation) */
1025     { "0xFEDCBA00",            0   }, /* Hex with upper case digits A-F (0x-notation) */
1026     { "-0xFEDCBA00",           0   }, /* Negative Hexadecimal (0x-notation) */
1027     { "0xabcdefgh",            0   }, /* Hex with illegal lower case digits (g-z) */
1028     { "0xABCDEFGH",            0   }, /* Hex with illegal upper case digits (G-Z) */
1029     { "0xF",                   0   }, /* one digit hexadecimal */
1030     { "0xG",                   0   }, /* empty hexadecimal */
1031     { "0x",                    0   }, /* empty hexadecimal */
1032     { "",                      0   }, /* empty string */
1033 /*  { NULL,                    0   }, */ /* NULL as string */
1034 };
1035 #define NB_STR2LONGLONG (sizeof(str2longlong)/sizeof(*str2longlong))
1036
1037
1038 static void test_atoi64(void)
1039 {
1040     int test_num;
1041     LONGLONG result;
1042
1043     for (test_num = 0; test_num < NB_STR2LONGLONG; test_num++) {
1044         result = p_atoi64(str2longlong[test_num].str);
1045         ok(result == str2longlong[test_num].value,
1046            "(test %d): call failed: _atoi64(\"%s\") has result %lld, expected: %lld",
1047            test_num, str2longlong[test_num].str, result, str2longlong[test_num].value);
1048     } /* for */
1049 }
1050
1051
1052 static void test_wtoi64(void)
1053 {
1054     int test_num;
1055     UNICODE_STRING uni;
1056     LONGLONG result;
1057
1058     for (test_num = 0; test_num < NB_STR2LONGLONG; test_num++) {
1059         pRtlCreateUnicodeStringFromAsciiz(&uni, str2longlong[test_num].str);
1060         result = p_wtoi64(uni.Buffer);
1061         ok(result == str2longlong[test_num].value,
1062            "(test %d): call failed: _wtoi64(\"%s\") has result %lld, expected: %lld",
1063            test_num, str2longlong[test_num].str, result, str2longlong[test_num].value);
1064         pRtlFreeUnicodeString(&uni);
1065     } /* for */
1066 }
1067
1068
1069 START_TEST(string)
1070 {
1071     InitFunctionPtrs();
1072
1073     test_ulongtoa();
1074     test_ulonglongtoa();
1075     test_atoi64();
1076
1077     test_ulongtow();
1078     test_ulonglongtow();
1079     test_wtoi();
1080     test_wtol();
1081     test_wtoi64();
1082 }