2 * Copyright 2014 Yifu Wang for ESRI
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/test.h"
24 typedef int MSVCRT_long
;
39 static char* (__cdecl
*p_setlocale
)(int, const char*);
40 static int (__cdecl
*p__setmbcp
)(int);
41 static int (__cdecl
*p_isleadbyte
)(int);
43 static MSVCRT_long (__cdecl
*p__Xtime_diff_to_millis2
)(const xtime
*, const xtime
*);
44 static int (__cdecl
*p_xtime_get
)(xtime
*, int);
45 static _Cvtvec
* (__cdecl
*p__Getcvt
)(_Cvtvec
*);
46 static void (CDECL
*p__Call_once
)(int *once
, void (CDECL
*func
)(void));
47 static void (CDECL
*p__Call_onceEx
)(int *once
, void (CDECL
*func
)(void*), void *argv
);
48 static void (CDECL
*p__Do_call
)(void *this);
52 static BOOL
init(void)
56 msvcp
= LoadLibraryA("msvcp120.dll");
59 win_skip("msvcp120.dll not installed\n");
63 p__Xtime_diff_to_millis2
= (void*)GetProcAddress(msvcp
, "_Xtime_diff_to_millis2");
64 p_xtime_get
= (void*)GetProcAddress(msvcp
, "xtime_get");
65 p__Getcvt
= (void*)GetProcAddress(msvcp
, "_Getcvt");
66 p__Call_once
= (void*)GetProcAddress(msvcp
, "_Call_once");
67 p__Call_onceEx
= (void*)GetProcAddress(msvcp
, "_Call_onceEx");
68 p__Do_call
= (void*)GetProcAddress(msvcp
, "_Do_call");
70 msvcr
= GetModuleHandleA("msvcr120.dll");
71 p_setlocale
= (void*)GetProcAddress(msvcr
, "setlocale");
72 p__setmbcp
= (void*)GetProcAddress(msvcr
, "_setmbcp");
73 p_isleadbyte
= (void*)GetProcAddress(msvcr
, "isleadbyte");
77 static void test__Xtime_diff_to_millis2(void)
80 __time64_t sec_before
;
81 MSVCRT_long nsec_before
;
83 MSVCRT_long nsec_after
;
87 {0, 1000000000, 0, 2000000000, 1000},
88 {1, 100000000, 2, 100000000, 1000},
89 {1, 100000000, 1, 200000000, 100},
90 {0, 0, 0, 1000000000, 1000},
91 {0, 0, 0, 1200000000, 1200},
92 {0, 0, 0, 1230000000, 1230},
93 {0, 0, 0, 1234000000, 1234},
94 {0, 0, 0, 1234100000, 1235},
95 {0, 0, 0, 1234900000, 1235},
96 {0, 0, 0, 1234010000, 1235},
97 {0, 0, 0, 1234090000, 1235},
98 {0, 0, 0, 1234000001, 1235},
99 {0, 0, 0, 1234000009, 1235},
101 {0, 0, 0, -10000000, 0},
102 {0, 0, -1, -100000000, 0},
104 {0, -100000000, 0, 0, 100},
105 {-1, -100000000, 0, 0, 1100},
106 {0, 0, -1, 2000000000, 1000},
107 {0, 0, -2, 2000000000, 0},
108 {0, 0, -2, 2100000000, 100}
114 for(i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); ++ i
)
116 t1
.sec
= tests
[i
].sec_before
;
117 t1
.nsec
= tests
[i
].nsec_before
;
118 t2
.sec
= tests
[i
].sec_after
;
119 t2
.nsec
= tests
[i
].nsec_after
;
120 ret
= p__Xtime_diff_to_millis2(&t2
, &t1
);
121 ok(ret
== tests
[i
].expect
,
122 "_Xtime_diff_to_millis2(): test: %d expect: %d, got: %d\n",
123 i
, tests
[i
].expect
, ret
);
127 static void test_xtime_get(void)
129 static const MSVCRT_long tests
[] = {1, 50, 100, 200, 500};
134 for(i
= 0; i
< sizeof(tests
) / sizeof(tests
[0]); i
++)
136 p_xtime_get(&before
, 1);
138 p_xtime_get(&after
, 1);
140 diff
= p__Xtime_diff_to_millis2(&after
, &before
);
143 "xtime_get() not functioning correctly, test: %d, expect: ge %d, got: %d\n",
147 /* Test parameter and return value */
148 before
.sec
= 0xdeadbeef, before
.nsec
= 0xdeadbeef;
149 i
= p_xtime_get(&before
, 0);
150 ok(i
== 0, "expect xtime_get() to return 0, got: %d\n", i
);
151 ok(before
.sec
== 0xdeadbeef && before
.nsec
== 0xdeadbeef,
152 "xtime_get() shouldn't have modified the xtime struct with the given option\n");
154 before
.sec
= 0xdeadbeef, before
.nsec
= 0xdeadbeef;
155 i
= p_xtime_get(&before
, 1);
156 ok(i
== 1, "expect xtime_get() to return 1, got: %d\n", i
);
157 ok(before
.sec
!= 0xdeadbeef && before
.nsec
!= 0xdeadbeef,
158 "xtime_get() should have modified the xtime struct with the given option\n");
161 static void test__Getcvt(void)
167 ok(cvtvec
.page
== 0, "cvtvec.page = %d\n", cvtvec
.page
);
168 ok(cvtvec
.mb_max
== 1, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
169 todo_wine
ok(cvtvec
.unk
== 1, "cvtvec.unk = %d\n", cvtvec
.unk
);
171 ok(cvtvec
.isleadbyte
[i
] == 0, "cvtvec.isleadbyte[%d] = %x\n", i
, cvtvec
.isleadbyte
[i
]);
173 if(!p_setlocale(LC_ALL
, ".936")) {
174 win_skip("_Getcvt tests\n");
178 ok(cvtvec
.page
== 936, "cvtvec.page = %d\n", cvtvec
.page
);
179 ok(cvtvec
.mb_max
== 2, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
180 ok(cvtvec
.unk
== 0, "cvtvec.unk = %d\n", cvtvec
.unk
);
182 ok(cvtvec
.isleadbyte
[i
] == 0, "cvtvec.isleadbyte[%d] = %x\n", i
, cvtvec
.isleadbyte
[i
]);
186 ok(cvtvec
.page
== 936, "cvtvec.page = %d\n", cvtvec
.page
);
187 ok(cvtvec
.mb_max
== 2, "cvtvec.mb_max = %d\n", cvtvec
.mb_max
);
188 ok(cvtvec
.unk
== 0, "cvtvec.unk = %d\n", cvtvec
.unk
);
189 for(i
=0; i
<32; i
++) {
194 b
|= (p_isleadbyte(i
*8+j
) ? 1 : 0) << j
;
195 ok(cvtvec
.isleadbyte
[i
] ==b
, "cvtvec.isleadbyte[%d] = %x (%x)\n", i
, cvtvec
.isleadbyte
[i
], b
);
202 static void __cdecl
call_once_func(void)
204 ok(!once
, "once != 0\n");
208 static void __cdecl
call_once_ex_func(void *arg
)
212 ok(!once
, "once != 0\n");
216 DWORD WINAPI
call_once_thread(void *arg
)
218 p__Call_once(&once
, call_once_func
);
222 DWORD WINAPI
call_once_ex_thread(void *arg
)
224 p__Call_onceEx(&once
, call_once_ex_func
, &cnt
);
228 static void test__Call_once(void)
234 h
[i
] = CreateThread(NULL
, 0, call_once_thread
, &once
, 0, NULL
);
235 ok(WaitForMultipleObjects(4, h
, TRUE
, INFINITE
) == WAIT_OBJECT_0
,
236 "error waiting for all threads to finish\n");
237 ok(cnt
== 0x10000, "cnt = %x\n", cnt
);
238 ok(once
== 1, "once = %x\n", once
);
242 h
[i
] = CreateThread(NULL
, 0, call_once_ex_thread
, &once
, 0, NULL
);
243 ok(WaitForMultipleObjects(4, h
, TRUE
, INFINITE
) == WAIT_OBJECT_0
,
244 "error waiting for all threads to finish\n");
245 ok(cnt
== 1, "cnt = %x\n", cnt
);
246 ok(once
== 1, "once = %x\n", once
);
249 static void **vtbl_func0
;
251 /* TODO: this should be a __thiscall function */
252 static void __stdcall
thiscall_func(void)
257 static void __cdecl
thiscall_func(void *this)
259 ok(this == &vtbl_func0
, "incorrect this value\n");
264 static void test__Do_call(void)
266 void *pfunc
= thiscall_func
;
270 p__Do_call(&vtbl_func0
);
271 ok(cnt
== 1, "func was not called\n");
277 test__Xtime_diff_to_millis2();