wined3d: Recognize Nvidia GT520 cards.
[wine] / dlls / msvcrt / tests / misc.c
1 /*
2  * Unit tests for miscellaneous msvcrt functions
3  *
4  * Copyright 2010 Andrew Nguyen
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "wine/test.h"
22 #include <errno.h>
23 #include "msvcrt.h"
24
25 static int (__cdecl *prand_s)(unsigned int *);
26 static int (__cdecl *pI10_OUTPUT)(long double, int, int, void*);
27 static int (__cdecl *pstrerror_s)(char *, MSVCRT_size_t, int);
28 static int (__cdecl *p_get_doserrno)(int *);
29 static int (__cdecl *p_get_errno)(int *);
30 static int (__cdecl *p_set_doserrno)(int);
31 static int (__cdecl *p_set_errno)(int);
32
33 static void init(void)
34 {
35     HMODULE hmod = GetModuleHandleA("msvcrt.dll");
36
37     prand_s = (void *)GetProcAddress(hmod, "rand_s");
38     pI10_OUTPUT = (void*)GetProcAddress(hmod, "$I10_OUTPUT");
39     pstrerror_s = (void *)GetProcAddress(hmod, "strerror_s");
40     p_get_doserrno = (void *)GetProcAddress(hmod, "_get_doserrno");
41     p_get_errno = (void *)GetProcAddress(hmod, "_get_errno");
42     p_set_doserrno = (void *)GetProcAddress(hmod, "_set_doserrno");
43     p_set_errno = (void *)GetProcAddress(hmod, "_set_errno");
44 }
45
46 static void test_rand_s(void)
47 {
48     int ret;
49     unsigned int rand;
50
51     if (!prand_s)
52     {
53         win_skip("rand_s is not available\n");
54         return;
55     }
56
57     errno = EBADF;
58     ret = prand_s(NULL);
59     ok(ret == EINVAL, "Expected rand_s to return EINVAL, got %d\n", ret);
60     ok(errno == EINVAL, "Expected errno to return EINVAL, got %d\n", errno);
61
62     ret = prand_s(&rand);
63     ok(ret == 0, "Expected rand_s to return 0, got %d\n", ret);
64 }
65
66 typedef struct _I10_OUTPUT_data {
67     short pos;
68     char sign;
69     BYTE len;
70     char str[100];
71 } I10_OUTPUT_data;
72
73 typedef struct _I10_OUTPUT_test {
74     long double d;
75     int size;
76     int flags;
77
78     I10_OUTPUT_data out;
79     int ret;
80     const char *remain;
81 } I10_OUTPUT_test;
82
83 static const I10_OUTPUT_test I10_OUTPUT_tests[] = {
84     /* arg3 = 0 */
85     { 0.0, 10, 0, {0, ' ', 1, "0"}, 1, "" },
86     { 1.0, 10, 0, {1, ' ', 1, "1"}, 1, "000000009" },
87     { -1.0, 10, 0, {1, '-', 1, "1"}, 1, "000000009" },
88     { 1.23, 10, 0, {1, ' ', 3, "123"}, 1, "0000009" },
89     { 1e13, 10, 0, {14, ' ', 1, "1"}, 1, "000000009" },
90     { 1e30, 30, 0, {31, ' ', 21, "100000000000000001988"}, 1, "" },
91     { 1e-13, 10, 0, {-12, ' ', 1, "1"}, 1, "000000000" },
92     { 0.25, 10, 0, {0, ' ', 2, "25"}, 1, "00000000" },
93     { 1.0000001, 10, 0, {1, ' ', 8, "10000001"}, 1, "00" },
94     /* arg3 = 1 */
95     { 0.0, 10, 1, {0, ' ', 1, "0"}, 1, "" },
96     { 1.0, 10, 1, {1, ' ', 1, "1"}, 1, "0000000009" },
97     { -1.0, 10, 1, {1, '-', 1, "1"}, 1, "0000000009" },
98     { 1.23, 10, 1, {1, ' ', 3, "123"}, 1, "00000009" },
99     { 1e13, 10, 1, {14, ' ', 1, "1"}, 1, "00000000000000000009" },
100     { 1e30, 30, 1, {31, ' ', 21, "100000000000000001988"}, 1, "" },
101     { 1e-13, 10, 1, {0, ' ', 1, "0"}, 1, "" },
102     { 1e-7, 10, 1, {-6, ' ', 1, "1"}, 1, "09" },
103     { 0.25, 10, 1, {0, ' ', 2, "25"}, 1, "00000000" },
104     { 1.0000001, 10, 1, {1, ' ', 8, "10000001"}, 1, "000" },
105     /* too small buffer */
106     { 0.0, 0, 0, {0, ' ', 1, "0"}, 1, "" },
107     { 0.0, 0, 1, {0, ' ', 1, "0"}, 1, "" },
108     { 123.0, 2, 0, {3, ' ', 2, "12"}, 1, "" },
109     { 123.0, 0, 0, {0, ' ', 1, "0"}, 1, "" },
110     { 123.0, 2, 1, {3, ' ', 3, "123"}, 1, "09" },
111     { 0.99, 1, 0, {1, ' ', 1, "1"}, 1, "" },
112     { 1264567.0, 2, 0, {7, ' ', 2, "13"}, 1, "" },
113     { 1264567.0, 2, 1, {7, ' ', 7, "1264567"}, 1, "00" },
114     { 1234567891.0, 2, 1, {10, ' ', 10, "1234567891"}, 1, "09" }
115 };
116
117 static void test_I10_OUTPUT(void)
118 {
119     I10_OUTPUT_data out;
120     int i, j = sizeof(long double), ret;
121
122     if(!pI10_OUTPUT) {
123         win_skip("I10_OUTPUT not available\n");
124         return;
125     }
126     if (j != 12)
127         trace("sizeof(long double) = %d on this machine\n", j);
128
129     for(i=0; i<sizeof(I10_OUTPUT_tests)/sizeof(I10_OUTPUT_test); i++) {
130         memset(out.str, '#', sizeof(out.str));
131
132         if (sizeof(long double) == 12)
133             ret = pI10_OUTPUT(I10_OUTPUT_tests[i].d, I10_OUTPUT_tests[i].size, I10_OUTPUT_tests[i].flags, &out);
134         else {
135             /* MS' "long double" is an 80 bit FP that takes 12 bytes*/
136             typedef struct { ULONG x80[3]; } uld; /* same calling convention */
137             union { long double ld; uld ld12; } fp80;
138             int (__cdecl *pI10_OUTPUT12)(uld, int, int, void*) = (void*)pI10_OUTPUT;
139             fp80.ld = I10_OUTPUT_tests[i].d;
140             ret = pI10_OUTPUT12(fp80.ld12, I10_OUTPUT_tests[i].size, I10_OUTPUT_tests[i].flags, &out);
141         }
142         ok(ret == I10_OUTPUT_tests[i].ret, "%d: ret = %d\n", i, ret);
143         ok(out.pos == I10_OUTPUT_tests[i].out.pos, "%d: out.pos = %hd\n", i, out.pos);
144         ok(out.sign == I10_OUTPUT_tests[i].out.sign, "%d: out.size = %c\n", i, out.sign);
145         ok(out.len == I10_OUTPUT_tests[i].out.len, "%d: out.len = %d\n", i, (int)out.len);
146         ok(!strcmp(out.str, I10_OUTPUT_tests[i].out.str), "%d: out.str = %s\n", i, out.str);
147
148         j = strlen(I10_OUTPUT_tests[i].remain);
149         if(j && I10_OUTPUT_tests[i].remain[j-1]=='9')
150             todo_wine ok(!strncmp(out.str+out.len+1, I10_OUTPUT_tests[i].remain, j),
151                     "%d: &out.str[%d] = %.25s...\n", i, out.len+1, out.str+out.len+1);
152         else
153             ok(!strncmp(out.str+out.len+1, I10_OUTPUT_tests[i].remain, j),
154                     "%d: &out.str[%d] = %.25s...\n", i, out.len+1, out.str+out.len+1);
155
156
157         for(j=out.len+strlen(I10_OUTPUT_tests[i].remain)+1; j<sizeof(out.str); j++)
158             if(out.str[j] != '#')
159                 ok(0, "%d: out.str[%d] = %c (expected \'#\')\n", i, j, out.str[j]);
160     }
161 }
162
163 static void test_strerror_s(void)
164 {
165     int ret;
166     char buf[256];
167
168     if (!pstrerror_s)
169     {
170         win_skip("strerror_s is not available\n");
171         return;
172     }
173
174     errno = EBADF;
175     ret = pstrerror_s(NULL, 0, 0);
176     ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret);
177     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
178
179     errno = EBADF;
180     ret = pstrerror_s(NULL, sizeof(buf), 0);
181     ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret);
182     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
183
184     memset(buf, 'X', sizeof(buf));
185     errno = EBADF;
186     ret = pstrerror_s(buf, 0, 0);
187     ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret);
188     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
189     ok(buf[0] == 'X', "Expected output buffer to be untouched\n");
190
191     memset(buf, 'X', sizeof(buf));
192     ret = pstrerror_s(buf, 1, 0);
193     ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
194     ok(strlen(buf) == 0, "Expected output buffer to be null terminated\n");
195
196     memset(buf, 'X', sizeof(buf));
197     ret = pstrerror_s(buf, 2, 0);
198     ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
199     ok(strlen(buf) == 1, "Expected output buffer to be truncated\n");
200
201     memset(buf, 'X', sizeof(buf));
202     ret = pstrerror_s(buf, sizeof(buf), 0);
203     ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
204
205     memset(buf, 'X', sizeof(buf));
206     ret = pstrerror_s(buf, sizeof(buf), -1);
207     ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
208 }
209
210 static void test__get_doserrno(void)
211 {
212     int ret, out;
213
214     if (!p_get_doserrno)
215     {
216         win_skip("_get_doserrno is not available\n");
217         return;
218     }
219
220     _doserrno = ERROR_INVALID_CMM;
221     errno = EBADF;
222     ret = p_get_doserrno(NULL);
223     ok(ret == EINVAL, "Expected _get_doserrno to return EINVAL, got %d\n", ret);
224     ok(_doserrno == ERROR_INVALID_CMM, "Expected _doserrno to be ERROR_INVALID_CMM, got %d\n", _doserrno);
225     ok(errno == EBADF, "Expected errno to be EBADF, got %d\n", errno);
226
227     _doserrno = ERROR_INVALID_CMM;
228     errno = EBADF;
229     out = 0xdeadbeef;
230     ret = p_get_doserrno(&out);
231     ok(ret == 0, "Expected _get_doserrno to return 0, got %d\n", ret);
232     ok(out == ERROR_INVALID_CMM, "Expected output variable to be ERROR_INVAID_CMM, got %d\n", out);
233 }
234
235 static void test__get_errno(void)
236 {
237     int ret, out;
238
239     if (!p_get_errno)
240     {
241         win_skip("_get_errno is not available\n");
242         return;
243     }
244
245     errno = EBADF;
246     ret = p_get_errno(NULL);
247     ok(ret == EINVAL, "Expected _get_errno to return EINVAL, got %d\n", ret);
248     ok(errno == EBADF, "Expected errno to be EBADF, got %d\n", errno);
249
250     errno = EBADF;
251     out = 0xdeadbeef;
252     ret = p_get_errno(&out);
253     ok(ret == 0, "Expected _get_errno to return 0, got %d\n", ret);
254     ok(out == EBADF, "Expected output variable to be EBADF, got %d\n", out);
255 }
256
257 static void test__set_doserrno(void)
258 {
259     int ret;
260
261     if (!p_set_doserrno)
262     {
263         win_skip("_set_doserrno is not available\n");
264         return;
265     }
266
267     _doserrno = ERROR_INVALID_CMM;
268     ret = p_set_doserrno(ERROR_FILE_NOT_FOUND);
269     ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret);
270     ok(_doserrno == ERROR_FILE_NOT_FOUND,
271        "Expected _doserrno to be ERROR_FILE_NOT_FOUND, got %d\n", _doserrno);
272
273     _doserrno = ERROR_INVALID_CMM;
274     ret = p_set_doserrno(-1);
275     ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret);
276     ok(_doserrno == -1,
277        "Expected _doserrno to be -1, got %d\n", _doserrno);
278
279     _doserrno = ERROR_INVALID_CMM;
280     ret = p_set_doserrno(0xdeadbeef);
281     ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret);
282     ok(_doserrno == 0xdeadbeef,
283        "Expected _doserrno to be 0xdeadbeef, got %d\n", _doserrno);
284 }
285
286 static void test__set_errno(void)
287 {
288     int ret;
289
290     if (!p_set_errno)
291     {
292         win_skip("_set_errno is not available\n");
293         return;
294     }
295
296     errno = EBADF;
297     ret = p_set_errno(EINVAL);
298     ok(ret == 0, "Expected _set_errno to return 0, got %d\n", ret);
299     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
300
301     errno = EBADF;
302     ret = p_set_errno(-1);
303     ok(ret == 0, "Expected _set_errno to return 0, got %d\n", ret);
304     ok(errno == -1, "Expected errno to be -1, got %d\n", errno);
305
306     errno = EBADF;
307     ret = p_set_errno(0xdeadbeef);
308     ok(ret == 0, "Expected _set_errno to return 0, got %d\n", ret);
309     ok(errno == 0xdeadbeef, "Expected errno to be 0xdeadbeef, got %d\n", errno);
310 }
311
312 START_TEST(misc)
313 {
314     init();
315
316     test_rand_s();
317     test_I10_OUTPUT();
318     test_strerror_s();
319     test__get_doserrno();
320     test__get_errno();
321     test__set_doserrno();
322     test__set_errno();
323 }