ReactOS 0.4.15-dev-8219-ge8b88cf
misc.c
Go to the documentation of this file.
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 <stdio.h>
24#include <math.h>
25#include "msvcrt.h"
26#include <process.h>
27
28static inline float __port_infinity(void)
29{
30 static const unsigned __inf_bytes = 0x7f800000;
31 return *(const float *)&__inf_bytes;
32}
33#ifdef __REACTOS__
34#undef INFINITY
35#endif
36#define INFINITY __port_infinity()
37
38static inline float __port_nan(void)
39{
40 static const unsigned __nan_bytes = 0x7fc00000;
41 return *(const float *)&__nan_bytes;
42}
43#ifdef __REACTOS__
44#undef NAN
45#endif
46#define NAN __port_nan()
47
48static inline BOOL almost_equal(double d1, double d2) {
49 if(d1-d2>-1e-30 && d1-d2<1e-30)
50 return TRUE;
51 return FALSE;
52}
53
54/* MS' "long double" is an 80 bit FP that takes 12 bytes*/
55struct uld { ULONG lo, hi, exp; };
56
57static int (__cdecl *prand_s)(unsigned int *);
58static int (__cdecl *pI10_OUTPUT)(struct uld, int, int, void*);
59static int (__cdecl *pstrerror_s)(char *, MSVCRT_size_t, int);
60static int (__cdecl *p_get_doserrno)(int *);
61static int (__cdecl *p_get_errno)(int *);
62static int (__cdecl *p_set_doserrno)(int);
63static int (__cdecl *p_set_errno)(int);
64static void (__cdecl *p__invalid_parameter)(const wchar_t*,
65 const wchar_t*, const wchar_t*, unsigned int, uintptr_t);
66static void (__cdecl *p_qsort_s)(void*, MSVCRT_size_t, MSVCRT_size_t,
67 int (__cdecl*)(void*, const void*, const void*), void*);
68static double (__cdecl *p_atan)(double);
69static double (__cdecl *p_exp)(double);
70static double (__cdecl *p_tanh)(double);
71static void *(__cdecl *p_lfind_s)(const void*, const void*, unsigned int*,
72 size_t, int (__cdecl *)(void*, const void*, const void*), void*);
73
74static void init(void)
75{
76 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
77
78 prand_s = (void *)GetProcAddress(hmod, "rand_s");
79 pI10_OUTPUT = (void*)GetProcAddress(hmod, "$I10_OUTPUT");
80 pstrerror_s = (void *)GetProcAddress(hmod, "strerror_s");
81 p_get_doserrno = (void *)GetProcAddress(hmod, "_get_doserrno");
82 p_get_errno = (void *)GetProcAddress(hmod, "_get_errno");
83 p_set_doserrno = (void *)GetProcAddress(hmod, "_set_doserrno");
84 p_set_errno = (void *)GetProcAddress(hmod, "_set_errno");
85 p__invalid_parameter = (void *)GetProcAddress(hmod, "_invalid_parameter");
86 p_qsort_s = (void *)GetProcAddress(hmod, "qsort_s");
87 p_atan = (void *)GetProcAddress(hmod, "atan");
88 p_exp = (void *)GetProcAddress(hmod, "exp");
89 p_tanh = (void *)GetProcAddress(hmod, "tanh");
90 p_lfind_s = (void *)GetProcAddress(hmod, "_lfind_s");
91}
92
93static void test_rand_s(void)
94{
95 int ret;
96 unsigned int rand;
97
98 if (!prand_s)
99 {
100 win_skip("rand_s is not available\n");
101 return;
102 }
103
104 errno = EBADF;
105 ret = prand_s(NULL);
106 ok(ret == EINVAL, "Expected rand_s to return EINVAL, got %d\n", ret);
107 ok(errno == EINVAL, "Expected errno to return EINVAL, got %d\n", errno);
108
109 ret = prand_s(&rand);
110 ok(ret == 0, "Expected rand_s to return 0, got %d\n", ret);
111}
112
113typedef struct _I10_OUTPUT_data {
114 short pos;
115 char sign;
117 char str[100];
119
120typedef struct _I10_OUTPUT_test {
121 struct uld d;
122 int size;
123 int flags;
124
126 int ret;
127 const char *remain;
129
131 /* arg3 = 0 */
132 { { 0x00000000, 0x00000000, 0x0000 /* 0.0 */ }, 10, 0, {0, ' ', 1, "0"}, 1, "" },
133 { { 0x00000000, 0x80000000, 0x3fff /* 1.0 */ }, 10, 0, {1, ' ', 1, "1"}, 1, "000000009" },
134 { { 0x00000000, 0x80000000, 0xbfff /* -1.0 */ }, 10, 0, {1, '-', 1, "1"}, 1, "000000009" },
135 { { 0x0a3d7000, 0x9d70a3d7, 0x3fff /* 1.23 */ }, 10, 0, {1, ' ', 3, "123"}, 1, "0000009" },
136 { { 0x00000000, 0x9184e72a, 0x402a /* 1e13 */ }, 10, 0, {14, ' ', 1, "1"}, 1, "000000009" },
137 { { 0x04675000, 0xc9f2c9cd, 0x4062 /* 1e30 */ }, 30, 0, {31, ' ', 21, "100000000000000001988"}, 1, "" },
138 { { 0x4bb41000, 0xe12e1342, 0x3fd3 /* 1e-13 */ }, 10, 0, {-12, ' ', 1, "1"}, 1, "000000000" },
139 { { 0x00000000, 0x80000000, 0x3ffd /* 0.25 */ }, 10, 0, {0, ' ', 2, "25"}, 1, "00000000" },
140 { { 0xbf94d800, 0x800000d6, 0x3fff /* 1.0000001 */ }, 10, 0, {1, ' ', 8, "10000001"}, 1, "00" },
141 { { 0x00000000, 0x80000000, 0x7fff /* +inf */ }, 10, 0, {1, ' ', 5, "1#INF"}, 0, "" },
142 { { 0x00000000, 0x80000000, 0xffff /* -inf */ }, 10, 0, {1, '-', 5, "1#INF"}, 0, "" },
143 { { 0x00000001, 0x80000000, 0x7fff /* snan */ }, 10, 0, {1, ' ', 6, "1#SNAN"}, 0, "" },
144 { { 0x00000001, 0x80000000, 0xffff /* snan */ }, 10, 0, {1, '-', 6, "1#SNAN"}, 0, "" },
145 { { 0x00000000, 0xc0000000, 0x7fff /* qnan */ }, 10, 0, {1, ' ', 6, "1#QNAN"}, 0, "" },
146 { { 0x00000000, 0x40000000, 0xffff /* qnan */ }, 10, 0, {1, '-', 6, "1#QNAN"}, 0, "" },
147 /* arg3 = 1 */
148 { { 0x00000000, 0x00000000, 0x0000 /* 0 */ }, 10, 1, {0, ' ', 1, "0"}, 1, "" },
149 { { 0x00000000, 0x80000000, 0x3fff /* 1 */ }, 10, 1, {1, ' ', 1, "1"}, 1, "0000000009" },
150 { { 0x00000000, 0x80000000, 0xbfff /* -1 */ }, 10, 1, {1, '-', 1, "1"}, 1, "0000000009" },
151 { { 0x0a3d7000, 0x9d70a3d7, 0x3fff /* 1.23 */ }, 10, 1, {1, ' ', 3, "123"}, 1, "00000009" },
152 { { 0x00000000, 0x9184e72a, 0x402a /* 1e13 */ }, 10, 1, {14, ' ', 1, "1"}, 1, "00000000000000000009" },
153 { { 0x04675000, 0xc9f2c9cd, 0x4062 /* 1e30 */ }, 30, 1, {31, ' ', 21, "100000000000000001988"}, 1, "" },
154 { { 0x4bb41000, 0xe12e1342, 0x3fd3 /* 1e-13 */ }, 10, 1, {0, ' ', 1, "0"}, 1, "" },
155 { { 0xe57a4000, 0xd6bf94d5, 0x3fe7 /* 1e-7 */ }, 10, 1, {-6, ' ', 1, "1"}, 1, "09" },
156 { { 0x00000000, 0x80000000, 0x3ffd /* 0.25 */ }, 10, 1, {0, ' ', 2, "25"}, 1, "00000000" },
157 { { 0xbf94d800, 0x800000d6, 0x3fff /* 1.0000001 */ }, 10, 1, {1, ' ', 8, "10000001"}, 1, "000" },
158 { { 0x00000000, 0x80000000, 0x7fff /* +inf */ }, 10, 1, {1, ' ', 5, "1#INF"}, 0, "" },
159 { { 0x00000000, 0x80000000, 0xffff /* -inf */ }, 10, 1, {1, '-', 5, "1#INF"}, 0, "" },
160 { { 0x00000001, 0x80000000, 0x7fff /* snan */ }, 10, 1, {1, ' ', 6, "1#SNAN"}, 0, "" },
161 { { 0x00000000, 0xc0000000, 0x7fff /* qnan */ }, 10, 1, {1, ' ', 6, "1#QNAN"}, 0, "" },
162 { { 0x00000000, 0x40000000, 0x7fff /* qnan */ }, 10, 1, {1, ' ', 6, "1#QNAN"}, 0, "" },
163 /* too small buffer */
164 { { 0x00000000, 0x00000000, 0x0000 /* 0 */ }, 0, 0, {0, ' ', 1, "0"}, 1, "" },
165 { { 0x00000000, 0x00000000, 0x0000 /* 0 */ }, 0, 1, {0, ' ', 1, "0"}, 1, "" },
166 { { 0x00000000, 0xf6000000, 0x4005 /* 123 */ }, 2, 0, {3, ' ', 2, "12"}, 1, "" },
167 { { 0x00000000, 0xf6000000, 0x4005 /* 123 */ }, 0, 0, {0, ' ', 1, "0"}, 1, "" },
168 { { 0x00000000, 0xf6000000, 0x4005 /* 123 */ }, 2, 1, {3, ' ', 3, "123"}, 1, "09" },
169 { { 0x0a3d7000, 0xfd70a3d7, 0x3ffe /* 0.99 */ }, 1, 0, {1, ' ', 1, "1"}, 1, "" },
170 { { 0x00000000, 0x9a5db800, 0x4013 /* 1264567.0 */ }, 2, 0, {7, ' ', 2, "13"}, 1, "" },
171 { { 0x00000000, 0x9a5db800, 0x4013 /* 1264567.0 */ }, 2, 1, {7, ' ', 7, "1264567"}, 1, "00" },
172 { { 0x00000000, 0x932c05a6, 0x401d /* 1234567891.0 */ }, 2, 1, {10, ' ', 10, "1234567891"}, 1, "09" }
173};
174
175static void test_I10_OUTPUT(void)
176{
178 int i, j, ret;
179
180 if(!pI10_OUTPUT) {
181 win_skip("I10_OUTPUT not available\n");
182 return;
183 }
184
185 for(i=0; i<ARRAY_SIZE(I10_OUTPUT_tests); i++) {
186 memset(out.str, '#', sizeof(out.str));
188 ok(ret == I10_OUTPUT_tests[i].ret, "%d: ret = %d\n", i, ret);
189 ok(out.pos == I10_OUTPUT_tests[i].out.pos, "%d: out.pos = %hd\n", i, out.pos);
190 ok(out.sign == I10_OUTPUT_tests[i].out.sign, "%d: out.size = %c\n", i, out.sign);
191 ok(out.len == I10_OUTPUT_tests[i].out.len, "%d: out.len = %d\n", i, (int)out.len);
192 ok(!strcmp(out.str, I10_OUTPUT_tests[i].out.str), "%d: out.str = %s\n", i, out.str);
193
194 j = strlen(I10_OUTPUT_tests[i].remain);
195 todo_wine_if(j && I10_OUTPUT_tests[i].remain[j-1]=='9')
196 ok(!strncmp(out.str+out.len+1, I10_OUTPUT_tests[i].remain, j),
197 "%d: &out.str[%d] = %.25s...\n", i, out.len+1, out.str+out.len+1);
198
199 for(j=out.len+strlen(I10_OUTPUT_tests[i].remain)+1; j<sizeof(out.str); j++)
200 if(out.str[j] != '#')
201 ok(0, "%d: out.str[%d] = %c (expected \'#\')\n", i, j, out.str[j]);
202 }
203}
204
205static void test_strerror_s(void)
206{
207 int ret;
208 char buf[256];
209
210 if (!pstrerror_s)
211 {
212 win_skip("strerror_s is not available\n");
213 return;
214 }
215
216 errno = EBADF;
217 ret = pstrerror_s(NULL, 0, 0);
218 ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret);
219 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
220
221 errno = EBADF;
222 ret = pstrerror_s(NULL, sizeof(buf), 0);
223 ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret);
224 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
225
226 memset(buf, 'X', sizeof(buf));
227 errno = EBADF;
228 ret = pstrerror_s(buf, 0, 0);
229 ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret);
230 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
231 ok(buf[0] == 'X', "Expected output buffer to be untouched\n");
232
233 memset(buf, 'X', sizeof(buf));
234 ret = pstrerror_s(buf, 1, 0);
235 ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
236 ok(strlen(buf) == 0, "Expected output buffer to be null terminated\n");
237
238 memset(buf, 'X', sizeof(buf));
239 ret = pstrerror_s(buf, 2, 0);
240 ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
241 ok(strlen(buf) == 1, "Expected output buffer to be truncated\n");
242
243 memset(buf, 'X', sizeof(buf));
244 ret = pstrerror_s(buf, sizeof(buf), 0);
245 ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
246
247 memset(buf, 'X', sizeof(buf));
248 ret = pstrerror_s(buf, sizeof(buf), -1);
249 ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
250}
251
252static void test__get_doserrno(void)
253{
254 int ret, out;
255
256 if (!p_get_doserrno)
257 {
258 win_skip("_get_doserrno is not available\n");
259 return;
260 }
261
263 errno = EBADF;
264 ret = p_get_doserrno(NULL);
265 ok(ret == EINVAL, "Expected _get_doserrno to return EINVAL, got %d\n", ret);
266 ok(_doserrno == ERROR_INVALID_CMM, "Expected _doserrno to be ERROR_INVALID_CMM, got %d\n", _doserrno);
267 ok(errno == EBADF, "Expected errno to be EBADF, got %d\n", errno);
268
270 errno = EBADF;
271 out = 0xdeadbeef;
272 ret = p_get_doserrno(&out);
273 ok(ret == 0, "Expected _get_doserrno to return 0, got %d\n", ret);
274 ok(out == ERROR_INVALID_CMM, "Expected output variable to be ERROR_INVALID_CMM, got %d\n", out);
275}
276
277static void test__get_errno(void)
278{
279 int ret, out;
280
281 if (!p_get_errno)
282 {
283 win_skip("_get_errno is not available\n");
284 return;
285 }
286
287 errno = EBADF;
288 ret = p_get_errno(NULL);
289 ok(ret == EINVAL, "Expected _get_errno to return EINVAL, got %d\n", ret);
290 ok(errno == EBADF, "Expected errno to be EBADF, got %d\n", errno);
291
292 errno = EBADF;
293 out = 0xdeadbeef;
294 ret = p_get_errno(&out);
295 ok(ret == 0, "Expected _get_errno to return 0, got %d\n", ret);
296 ok(out == EBADF, "Expected output variable to be EBADF, got %d\n", out);
297}
298
299static void test__set_doserrno(void)
300{
301 int ret;
302
303 if (!p_set_doserrno)
304 {
305 win_skip("_set_doserrno is not available\n");
306 return;
307 }
308
310 ret = p_set_doserrno(ERROR_FILE_NOT_FOUND);
311 ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret);
313 "Expected _doserrno to be ERROR_FILE_NOT_FOUND, got %d\n", _doserrno);
314
316 ret = p_set_doserrno(-1);
317 ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret);
318 ok(_doserrno == -1,
319 "Expected _doserrno to be -1, got %d\n", _doserrno);
320
322 ret = p_set_doserrno(0xdeadbeef);
323 ok(ret == 0, "Expected _set_doserrno to return 0, got %d\n", ret);
324 ok(_doserrno == 0xdeadbeef,
325 "Expected _doserrno to be 0xdeadbeef, got %d\n", _doserrno);
326}
327
328static void test__set_errno(void)
329{
330 int ret;
331
332 if (!p_set_errno)
333 {
334 win_skip("_set_errno is not available\n");
335 return;
336 }
337
338 errno = EBADF;
339 ret = p_set_errno(EINVAL);
340 ok(ret == 0, "Expected _set_errno to return 0, got %d\n", ret);
341 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
342
343 errno = EBADF;
344 ret = p_set_errno(-1);
345 ok(ret == 0, "Expected _set_errno to return 0, got %d\n", ret);
346 ok(errno == -1, "Expected errno to be -1, got %d\n", errno);
347
348 errno = EBADF;
349 ret = p_set_errno(0xdeadbeef);
350 ok(ret == 0, "Expected _set_errno to return 0, got %d\n", ret);
351 ok(errno == 0xdeadbeef, "Expected errno to be 0xdeadbeef, got %d\n", errno);
352}
353
354static void test__popen_child(void)
355{
356 /* don't execute any tests here */
357 /* ExitProcess is used to set return code of _pclose */
358 printf("child output\n");
359 ExitProcess(0x37);
360}
361
362static void test__popen(const char *name)
363{
364 FILE *pipe;
365 char buf[1024];
366 int ret;
367
368 sprintf(buf, "\"%s\" misc popen", name);
369 pipe = _popen(buf, "r");
370 ok(pipe != NULL, "_popen failed with error: %d\n", errno);
371
372 fgets(buf, sizeof(buf), pipe);
373 ok(!strcmp(buf, "child output\n"), "buf = %s\n", buf);
374
375 ret = _pclose(pipe);
376 ok(ret == 0x37, "_pclose returned %x, expected 0x37\n", ret);
377
378 errno = 0xdeadbeef;
379 ret = _pclose((FILE*)0xdeadbeef);
380 ok(ret == -1, "_pclose returned %x, expected -1\n", ret);
381 if(p_set_errno)
382 ok(errno == EBADF, "errno = %d\n", errno);
383}
384
385static void test__invalid_parameter(void)
386{
387 if(!p__invalid_parameter) {
388 win_skip("_invalid_parameter not available\n");
389 return;
390 }
391
392 p__invalid_parameter(NULL, NULL, NULL, 0, 0);
393}
394
396{
397 int pos;
398 int *base;
399
400 struct {
401 int l;
402 int r;
403 } cmp[64];
404};
405
406static int __cdecl qsort_comp(void *ctx, const void *l, const void *r)
407{
408 struct qsort_test *qt = ctx;
409
410 if(qt) {
411 ok(qt->pos < 64, "qt->pos = %d\n", qt->pos);
412 ok(qt->cmp[qt->pos].l == (int*)l-qt->base,
413 "%d) l on %ld position\n", qt->pos, (long)((int*)l - qt->base));
414 ok(qt->cmp[qt->pos].r == (int*)r-qt->base,
415 "%d) r on %ld position\n", qt->pos, (long)((int*)r - qt->base));
416 qt->pos++;
417 }
418
419 return *(int*)l%1000 - *(int*)r%1000;
420}
421
422static void test_qsort_s(void)
423{
424 static const int nonstable_test[] = {9000, 8001, 7002, 6003, 1003, 5004, 4005, 3006, 2007};
425 int tab[100], i;
426
427 struct qsort_test small_sort = {
428 0, tab, {
429 {1, 0}, {2, 1}, {3, 2}, {4, 3}, {5, 4}, {6, 5}, {7, 6},
430 {1, 0}, {2, 1}, {3, 2}, {4, 3}, {5, 4}, {6, 5},
431 {1, 0}, {2, 1}, {3, 2}, {4, 3}, {5, 4},
432 {1, 0}, {2, 1}, {3, 2}, {4, 3},
433 {1, 0}, {2, 1}, {3, 2},
434 {1, 0}, {2, 1},
435 {1, 0}
436 }
437 }, small_sort2 = {
438 0, tab, {
439 {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0},
440 {1, 0}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1},
441 {1, 0}, {2, 1}, {3, 2}, {4, 2}, {5, 2},
442 {1, 0}, {2, 1}, {3, 2}, {4, 3},
443 {1, 0}, {2, 1}, {3, 2},
444 {1, 0}, {2, 1},
445 {1, 0}
446 }
447 }, quick_sort = {
448 0, tab, {
449 {0, 4}, {0, 8}, {4, 8},
450 {1, 4}, {2, 4}, {3, 4}, {5, 4}, {6, 4}, {7, 4}, {7, 4}, {6, 4},
451 {6, 4},
452 {8, 7},
453 {1, 0}, {2, 1}, {3, 2}, {4, 3}, {5, 4}, {6, 4},
454 {1, 0}, {2, 1}, {3, 2}, {4, 3}, {5, 3},
455 {1, 0}, {2, 1}, {3, 2}, {4, 2},
456 {1, 0}, {2, 1}, {3, 2},
457 {1, 0}, {2, 1},
458 {1, 0}
459 }
460 };
461
462 if(!p_qsort_s) {
463 win_skip("qsort_s not available\n");
464 return;
465 }
466
467 for(i=0; i<8; i++) tab[i] = i;
468 p_qsort_s(tab, 8, sizeof(int), qsort_comp, &small_sort);
469 ok(small_sort.pos == 28, "small_sort.pos = %d\n", small_sort.pos);
470 for(i=0; i<8; i++)
471 ok(tab[i] == i, "tab[%d] = %d\n", i, tab[i]);
472
473 for(i=0; i<8; i++) tab[i] = 7-i;
474 p_qsort_s(tab, 8, sizeof(int), qsort_comp, &small_sort2);
475 ok(small_sort2.pos == 28, "small_sort2.pos = %d\n", small_sort2.pos);
476 for(i=0; i<8; i++)
477 ok(tab[i] == i, "tab[%d] = %d\n", i, tab[i]);
478
479 for(i=0; i<9; i++) tab[i] = i;
480 tab[5] = 1;
481 tab[6] = 2;
482 p_qsort_s(tab, 9, sizeof(int), qsort_comp, &quick_sort);
483 ok(quick_sort.pos == 34, "quick_sort.pos = %d\n", quick_sort.pos);
484
485 /* show that qsort is not stable */
486 for(i=0; i<9; i++) tab[i] = 8-i + 1000*(i+1);
487 tab[0] = 1003;
488 p_qsort_s(tab, 9, sizeof(int), qsort_comp, NULL);
489 for(i=0; i<9; i++)
490 ok(tab[i] == nonstable_test[i], "tab[%d] = %d, expected %d\n", i, tab[i], nonstable_test[i]);
491
492 /* check if random data is sorted */
493 srand(0);
494 for(i=0; i<100; i++) tab[i] = rand()%1000;
495 p_qsort_s(tab, 100, sizeof(int), qsort_comp, NULL);
496 for(i=1; i<100; i++)
497 ok(tab[i-1] <= tab[i], "data sorted incorrectly on position %d: %d <= %d\n", i, tab[i-1], tab[i]);
498
499 /* test if random permutation is sorted correctly */
500 for(i=0; i<100; i++) tab[i] = i;
501 for(i=0; i<100; i++) {
502 int b = rand()%100;
503 int e = rand()%100;
504
505 if(b == e) continue;
506 tab[b] ^= tab[e];
507 tab[e] ^= tab[b];
508 tab[b] ^= tab[e];
509 }
510 p_qsort_s(tab, 100, sizeof(int), qsort_comp, NULL);
511 for(i=0; i<100; i++)
512 ok(tab[i] == i, "data sorted incorrectly on position %d: %d\n", i, tab[i]);
513}
514
515static void test_math_functions(void)
516{
517 double ret;
518
519 errno = 0xdeadbeef;
520 p_atan(NAN);
521 ok(errno == EDOM, "errno = %d\n", errno);
522
523 errno = 0xdeadbeef;
524 ret = p_atan(INFINITY);
525 ok(almost_equal(ret, 1.57079632679489661923), "ret = %lf\n", ret);
526 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
527
528 errno = 0xdeadbeef;
529 ret = p_atan(-INFINITY);
530 ok(almost_equal(ret, -1.57079632679489661923), "ret = %lf\n", ret);
531 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
532
533 errno = 0xdeadbeef;
534 p_tanh(NAN);
535 ok(errno == EDOM, "errno = %d\n", errno);
536
537 errno = 0xdeadbeef;
538 ret = p_tanh(INFINITY);
539 ok(almost_equal(ret, 1.0), "ret = %lf\n", ret);
540 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
541
542 errno = 0xdeadbeef;
543 p_exp(NAN);
544 ok(errno == EDOM, "errno = %d\n", errno);
545
546 errno = 0xdeadbeef;
547 p_exp(INFINITY);
548 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
549}
550
551static void __cdecl test_thread_func(void *end_thread_type)
552{
553 if (end_thread_type == (void*)1)
554 _endthread();
555 else if (end_thread_type == (void*)2)
556 ExitThread(0);
557 else if (end_thread_type == (void*)3)
558 _endthreadex(0);
559}
560
561static unsigned __stdcall test_thread_func_ex(void *arg)
562{
563 _endthread();
564 return 0;
565}
566
568{
570 DWORD ret;
571
572 /* _beginthread: handle is not closed on ExitThread and _endthreadex */
574 ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
577 ok(!ret, "ret = %d\n", ret);
578
580 ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
583 ok(!ret, "ret = %d\n", ret);
584
586 ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
587 Sleep(150);
589 ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret);
591 ok(ret, "ret = %d\n", ret);
592
594 ok(hThread != INVALID_HANDLE_VALUE, "_beginthread failed (%d)\n", errno);
595 Sleep(150);
597 ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret);
599 ok(ret, "ret = %d\n", ret);
600
601 /* _beginthreadex: handle is not closed on _endthread */
603 ok(hThread != NULL, "_beginthreadex failed (%d)\n", errno);
604 Sleep(150);
606 ok(ret == WAIT_OBJECT_0, "ret = %d\n", ret);
608 ok(ret, "ret = %d\n", ret);
609}
610
611static int __cdecl _lfind_s_comp(void *ctx, const void *l, const void *r)
612{
613 *(int *)ctx = 0xdeadc0de;
614 return *(int *)l - *(int *)r;
615}
616
617static void test__lfind_s(void)
618{
619 static const int tests[] = {9000, 8001, 7002, 6003, 1003, 5004, 4005, 3006, 2007};
620 unsigned int num;
621 void *found;
622 int ctx;
623 int key;
624
625 if (!p_lfind_s)
626 {
627 win_skip("_lfind_s is not available\n");
628 return;
629 }
630
631 key = 1234;
633
634 errno = 0xdeadbeef;
635 found = p_lfind_s(NULL, tests, &num, sizeof(int), _lfind_s_comp, NULL);
636 ok(errno == EINVAL, "errno = %d\n", errno);
637 ok(!found, "Expected NULL, got %p\n", found);
638
639 errno = 0xdeadbeef;
640 found = p_lfind_s(&key, NULL, &num, sizeof(int), _lfind_s_comp, NULL);
641 ok(errno == EINVAL, "errno = %d\n", errno);
642 ok(!found, "Expected NULL, got %p\n", found);
643
644 errno = 0xdeadbeef;
645 found = p_lfind_s(&key, tests, &num, 0, _lfind_s_comp, NULL);
646 ok(errno == EINVAL, "errno = %d\n", errno);
647 ok(!found, "Expected NULL, got %p\n", found);
648
649 errno = 0xdeadbeef;
650 found = p_lfind_s(&key, tests, &num, sizeof(int), NULL, NULL);
651 ok(errno == EINVAL, "errno = %d\n", errno);
652 ok(!found, "Expected NULL, got %p\n", found);
653
654 ctx = -1;
655 key = 9000;
656 errno = 0xdeadbeef;
657 found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
658 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
659 ok(found == tests, "Expected %p, got %p\n", tests, found);
660 ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
661
662 ctx = -1;
663 key = 2007;
664 errno = 0xdeadbeef;
665 found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
666 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
667 ok(found == tests+8, "Expected %p, got %p\n", tests+8, found);
668 ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
669
670 ctx = -1;
671 key = 1234;
672 errno = 0xdeadbeef;
673 found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
674 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
675 ok(!found, "Expected NULL, got %p\n", found);
676 ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
677}
678
680{
681 int arg_c;
682 char** arg_v;
683
684 init();
685
686 arg_c = winetest_get_mainargs(&arg_v);
687 if(arg_c >= 3) {
688 if(!strcmp(arg_v[2], "popen"))
690 else
691 ok(0, "invalid argument '%s'\n", arg_v[2]);
692
693 return;
694 }
695
696 test_rand_s();
703 test__popen(arg_v[0]);
705 test_qsort_s();
709}
#define EINVAL
Definition: acclib.h:90
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define EBADF
Definition: acclib.h:82
#define __cdecl
Definition: accygwin.h:79
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:33
r l[0]
Definition: byte_order.h:168
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define EDOM
Definition: errno.h:39
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define printf
Definition: freeldr.h:97
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLuint GLuint num
Definition: glext.h:9618
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_Check_return_opt_ _CRTIMP int __cdecl _pclose(_Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl _popen(_In_z_ const char *_Command, _In_z_ const char *_Mode)
void __cdecl srand(_In_ unsigned int _Seed)
#define _doserrno
Definition: stdlib.h:131
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
#define b
Definition: ke_i.h:79
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static struct test_info tests[]
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
#define todo_wine_if(is_todo)
Definition: custom.c:76
static void test__popen_child(void)
Definition: misc.c:354
static void test__invalid_parameter(void)
Definition: misc.c:385
static void test__lfind_s(void)
Definition: misc.c:617
struct _I10_OUTPUT_data I10_OUTPUT_data
static void test__set_doserrno(void)
Definition: misc.c:299
static void test_math_functions(void)
Definition: misc.c:515
static const I10_OUTPUT_test I10_OUTPUT_tests[]
Definition: misc.c:130
static void __cdecl test_thread_func(void *end_thread_type)
Definition: misc.c:551
static void test_qsort_s(void)
Definition: misc.c:422
static void test__get_errno(void)
Definition: misc.c:277
static unsigned __stdcall test_thread_func_ex(void *arg)
Definition: misc.c:561
static void test_thread_handle_close(void)
Definition: misc.c:567
static void *static MSVCRT_size_t
Definition: misc.c:59
struct _I10_OUTPUT_test I10_OUTPUT_test
static void test__set_errno(void)
Definition: misc.c:328
static void test__get_doserrno(void)
Definition: misc.c:252
#define NAN
Definition: misc.c:46
static void test_I10_OUTPUT(void)
Definition: misc.c:175
#define INFINITY
Definition: misc.c:36
static int __cdecl _lfind_s_comp(void *ctx, const void *l, const void *r)
Definition: misc.c:611
static void test_strerror_s(void)
Definition: misc.c:205
static BOOL almost_equal(double d1, double d2)
Definition: misc.c:48
static float __port_infinity(void)
Definition: misc.c:28
static int __cdecl qsort_comp(void *ctx, const void *l, const void *r)
Definition: misc.c:406
static void test__popen(const char *name)
Definition: misc.c:362
static void test_rand_s(void)
Definition: misc.c:93
static const wchar_t const wchar_t unsigned uintptr_t
Definition: misc.c:65
static float __port_nan(void)
Definition: misc.c:38
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
HANDLE hThread
Definition: wizard.c:28
static FILE * out
Definition: regtests2xml.c:44
#define errno
Definition: errno.h:18
_CRTIMP void __cdecl _endthreadex(_In_ unsigned _Retval)
_CRTIMP uintptr_t __cdecl _beginthreadex(_In_opt_ void *_Security, _In_ unsigned _StackSize, _In_ unsigned(__stdcall *_StartAddress)(void *), _In_opt_ void *_ArgList, _In_ unsigned _InitFlag, _Out_opt_ unsigned *_ThrdAddr)
_CRTIMP uintptr_t __cdecl _beginthread(_In_ void(__cdecl *_StartAddress)(void *), _In_ unsigned _StackSize, _In_opt_ void *_ArgList)
_CRTIMP void __cdecl _endthread(void)
Definition: thread.c:95
#define win_skip
Definition: test.h:163
int winetest_get_mainargs(char ***pargv)
#define memset(x, y, z)
Definition: compat.h:39
short pos
Definition: misc.c:114
char str[100]
Definition: misc.c:117
I10_OUTPUT_data out
Definition: misc.c:125
const char * remain
Definition: misc.c:127
struct uld d
Definition: misc.c:121
Definition: copy.c:22
Definition: name.c:39
int pos
Definition: misc.c:397
int l
Definition: misc.c:401
struct qsort_test::@1689 cmp[64]
int * base
Definition: misc.c:398
int r
Definition: misc.c:402
Definition: misc.c:55
ULONG exp
Definition: misc.c:55
ULONG lo
Definition: misc.c:55
ULONG hi
Definition: misc.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
PVOID HANDLE
Definition: typedefs.h:73
#define __stdcall
Definition: typedefs.h:25
uint32_t ULONG
Definition: typedefs.h:59
int ret
#define WAIT_OBJECT_0
Definition: winbase.h:406
#define ERROR_INVALID_CMM
Definition: winerror.h:1185
static int init
Definition: wintirpc.c:33
unsigned char BYTE
Definition: xxhash.c:193