VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/include/wine/test.h@ 38565

最後變更 在這個檔案從38565是 33656,由 vboxsync 提交於 14 年 前

*: rebrand Sun (L)GPL disclaimers

  • 屬性 svn:eol-style 設為 native
檔案大小: 17.3 KB
 
1/*
2 * Definitions for Wine C unit tests.
3 *
4 * Copyright (C) 2002 Alexandre Julliard
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/*
22 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
23 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
24 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
25 * a choice of LGPL license versions is made available with the language indicating
26 * that LGPLv2 or any later version may be used, or where a choice of which version
27 * of the LGPL is applied is otherwise unspecified.
28 */
29
30#ifndef __WINE_WINE_TEST_H
31#define __WINE_WINE_TEST_H
32
33#include <stdarg.h>
34#include <stdlib.h>
35#include <windef.h>
36#include <winbase.h>
37
38#ifdef __WINE_CONFIG_H
39#error config.h should not be used in Wine tests
40#endif
41#ifdef __WINE_WINE_LIBRARY_H
42#error wine/library.h should not be used in Wine tests
43#endif
44#ifdef __WINE_WINE_UNICODE_H
45#error wine/unicode.h should not be used in Wine tests
46#endif
47#ifdef __WINE_WINE_DEBUG_H
48#error wine/debug.h should not be used in Wine tests
49#endif
50
51#ifndef INVALID_FILE_ATTRIBUTES
52#define INVALID_FILE_ATTRIBUTES (~0u)
53#endif
54#ifndef INVALID_SET_FILE_POINTER
55#define INVALID_SET_FILE_POINTER (~0u)
56#endif
57
58/* debug level */
59extern int winetest_debug;
60
61/* running in interactive mode? */
62extern int winetest_interactive;
63
64/* current platform */
65extern const char *winetest_platform;
66
67extern void winetest_set_location( const char* file, int line );
68extern void winetest_start_todo( const char* platform );
69extern int winetest_loop_todo(void);
70extern void winetest_end_todo( const char* platform );
71extern int winetest_get_mainargs( char*** pargv );
72extern void winetest_wait_child_process( HANDLE process );
73
74extern const char *wine_dbgstr_wn( const WCHAR *str, int n );
75static inline const char *wine_dbgstr_w( const WCHAR *s ) { return wine_dbgstr_wn( s, -1 ); }
76
77/* strcmpW is avaiable for tests compiled under Wine, but not in standalone
78 * builds under Windows, so we reimplement it under a different name. */
79static inline int winetest_strcmpW( const WCHAR *str1, const WCHAR *str2 )
80{
81 while (*str1 && (*str1 == *str2)) { str1++; str2++; }
82 return *str1 - *str2;
83}
84
85#ifdef STANDALONE
86#define START_TEST(name) \
87 static void func_##name(void); \
88 const struct test winetest_testlist[] = { { #name, func_##name }, { 0, 0 } }; \
89 static void func_##name(void)
90#else
91#define START_TEST(name) void func_##name(void)
92#endif
93
94#if defined(__x86_64__) && defined(__GNUC__) && defined(__WINE_USE_MSVCRT)
95#define __winetest_cdecl __cdecl
96#define __winetest_va_list __builtin_ms_va_list
97#else
98#define __winetest_cdecl
99#define __winetest_va_list va_list
100#endif
101
102extern int broken( int condition );
103extern int winetest_vok( int condition, const char *msg, __winetest_va_list ap );
104extern void winetest_vskip( const char *msg, __winetest_va_list ap );
105
106#ifdef __GNUC__
107
108extern void __winetest_cdecl winetest_ok( int condition, const char *msg, ... ) __attribute__((format (printf,2,3) ));
109extern void __winetest_cdecl winetest_skip( const char *msg, ... ) __attribute__((format (printf,1,2)));
110extern void __winetest_cdecl winetest_win_skip( const char *msg, ... ) __attribute__((format (printf,1,2)));
111extern void __winetest_cdecl winetest_trace( const char *msg, ... ) __attribute__((format (printf,1,2)));
112
113#else /* __GNUC__ */
114
115extern void __winetest_cdecl winetest_ok( int condition, const char *msg, ... );
116extern void __winetest_cdecl winetest_skip( const char *msg, ... );
117extern void __winetest_cdecl winetest_win_skip( const char *msg, ... );
118extern void __winetest_cdecl winetest_trace( const char *msg, ... );
119
120#endif /* __GNUC__ */
121
122#define ok_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_ok
123#define skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_skip
124#define win_skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_win_skip
125#define trace_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_trace
126
127#define ok ok_(__FILE__, __LINE__)
128#define skip skip_(__FILE__, __LINE__)
129#define win_skip win_skip_(__FILE__, __LINE__)
130#define trace trace_(__FILE__, __LINE__)
131
132#define todo(platform) for (winetest_start_todo(platform); \
133 winetest_loop_todo(); \
134 winetest_end_todo(platform))
135#define todo_wine todo("wine")
136
137
138#ifdef NONAMELESSUNION
139# define U(x) (x).u
140# define U1(x) (x).u1
141# define U2(x) (x).u2
142# define U3(x) (x).u3
143# define U4(x) (x).u4
144# define U5(x) (x).u5
145# define U6(x) (x).u6
146# define U7(x) (x).u7
147# define U8(x) (x).u8
148#else
149# define U(x) (x)
150# define U1(x) (x)
151# define U2(x) (x)
152# define U3(x) (x)
153# define U4(x) (x)
154# define U5(x) (x)
155# define U6(x) (x)
156# define U7(x) (x)
157# define U8(x) (x)
158#endif
159
160#ifdef NONAMELESSSTRUCT
161# define S(x) (x).s
162# define S1(x) (x).s1
163# define S2(x) (x).s2
164# define S3(x) (x).s3
165# define S4(x) (x).s4
166# define S5(x) (x).s5
167#else
168# define S(x) (x)
169# define S1(x) (x)
170# define S2(x) (x)
171# define S3(x) (x)
172# define S4(x) (x)
173# define S5(x) (x)
174#endif
175
176
177/************************************************************************/
178/* Below is the implementation of the various functions, to be included
179 * directly into the generated testlist.c file.
180 * It is done that way so that the dlls can build the test routines with
181 * different includes or flags if needed.
182 */
183
184#ifdef STANDALONE
185
186#include <stdio.h>
187
188#if defined(__x86_64__) && defined(__GNUC__) && defined(__WINE_USE_MSVCRT)
189# define __winetest_va_start(list,arg) __builtin_ms_va_start(list,arg)
190# define __winetest_va_end(list) __builtin_ms_va_end(list)
191#else
192# define __winetest_va_start(list,arg) va_start(list,arg)
193# define __winetest_va_end(list) va_end(list)
194#endif
195
196struct test
197{
198 const char *name;
199 void (*func)(void);
200};
201
202extern const struct test winetest_testlist[];
203
204/* debug level */
205int winetest_debug = 1;
206
207/* interactive mode? */
208int winetest_interactive = 0;
209
210/* current platform */
211const char *winetest_platform = "windows";
212
213/* report successful tests (BOOL) */
214static int report_success = 0;
215
216/* passing arguments around */
217static int winetest_argc;
218static char** winetest_argv;
219
220static const struct test *current_test; /* test currently being run */
221
222static LONG successes; /* number of successful tests */
223static LONG failures; /* number of failures */
224static LONG skipped; /* number of skipped test chunks */
225static LONG todo_successes; /* number of successful tests inside todo block */
226static LONG todo_failures; /* number of failures inside todo block */
227
228/* The following data must be kept track of on a per-thread basis */
229typedef struct
230{
231 const char* current_file; /* file of current check */
232 int current_line; /* line of current check */
233 int todo_level; /* current todo nesting level */
234 int todo_do_loop;
235 char *str_pos; /* position in debug buffer */
236 char strings[2000]; /* buffer for debug strings */
237} tls_data;
238static DWORD tls_index;
239
240static tls_data* get_tls_data(void)
241{
242 tls_data* data;
243 DWORD last_error;
244
245 last_error=GetLastError();
246 data=TlsGetValue(tls_index);
247 if (!data)
248 {
249 data=HeapAlloc(GetProcessHeap(), 0, sizeof(tls_data));
250 data->todo_level = 0;
251 data->str_pos = data->strings;
252 TlsSetValue(tls_index,data);
253 }
254 SetLastError(last_error);
255 return data;
256}
257
258/* allocate some tmp space for a string */
259static char *get_temp_buffer( size_t n )
260{
261 tls_data *data = get_tls_data();
262 char *res = data->str_pos;
263
264 if (res + n >= &data->strings[sizeof(data->strings)]) res = data->strings;
265 data->str_pos = res + n;
266 return res;
267}
268
269/* release extra space that we requested in gimme1() */
270static void release_temp_buffer( char *ptr, size_t size )
271{
272 tls_data *data = get_tls_data();
273 data->str_pos = ptr + size;
274}
275
276static void exit_process( int code )
277{
278 fflush( stdout );
279 ExitProcess( code );
280}
281
282
283void winetest_set_location( const char* file, int line )
284{
285 tls_data* data=get_tls_data();
286 data->current_file=strrchr(file,'/');
287 if (data->current_file==NULL)
288 data->current_file=strrchr(file,'\\');
289 if (data->current_file==NULL)
290 data->current_file=file;
291 else
292 data->current_file++;
293 data->current_line=line;
294}
295
296int broken( int condition )
297{
298 return (strcmp(winetest_platform, "windows") == 0) && condition;
299}
300
301/*
302 * Checks condition.
303 * Parameters:
304 * - condition - condition to check;
305 * - msg test description;
306 * - file - test application source code file name of the check
307 * - line - test application source code file line number of the check
308 * Return:
309 * 0 if condition does not have the expected value, 1 otherwise
310 */
311int winetest_vok( int condition, const char *msg, __winetest_va_list args )
312{
313 tls_data* data=get_tls_data();
314
315 if (data->todo_level)
316 {
317 if (condition)
318 {
319 fprintf( stdout, "%s:%d: Test succeeded inside todo block: ",
320 data->current_file, data->current_line );
321 vfprintf(stdout, msg, args);
322 InterlockedIncrement(&todo_failures);
323 return 0;
324 }
325 else
326 {
327 if (winetest_debug > 0)
328 {
329 fprintf( stdout, "%s:%d: Test marked todo: ",
330 data->current_file, data->current_line );
331 vfprintf(stdout, msg, args);
332 }
333 InterlockedIncrement(&todo_successes);
334 return 1;
335 }
336 }
337 else
338 {
339 if (!condition)
340 {
341 fprintf( stdout, "%s:%d: Test failed: ",
342 data->current_file, data->current_line );
343 vfprintf(stdout, msg, args);
344 InterlockedIncrement(&failures);
345 return 0;
346 }
347 else
348 {
349 if (report_success)
350 fprintf( stdout, "%s:%d: Test succeeded\n",
351 data->current_file, data->current_line);
352 InterlockedIncrement(&successes);
353 return 1;
354 }
355 }
356}
357
358void __winetest_cdecl winetest_ok( int condition, const char *msg, ... )
359{
360 __winetest_va_list valist;
361
362 __winetest_va_start(valist, msg);
363 winetest_vok(condition, msg, valist);
364 __winetest_va_end(valist);
365}
366
367void __winetest_cdecl winetest_trace( const char *msg, ... )
368{
369 __winetest_va_list valist;
370 tls_data* data=get_tls_data();
371
372 if (winetest_debug > 0)
373 {
374 fprintf( stdout, "%s:%d: ", data->current_file, data->current_line );
375 __winetest_va_start(valist, msg);
376 vfprintf(stdout, msg, valist);
377 __winetest_va_end(valist);
378 }
379}
380
381void winetest_vskip( const char *msg, __winetest_va_list args )
382{
383 tls_data* data=get_tls_data();
384
385 fprintf( stdout, "%s:%d: Tests skipped: ", data->current_file, data->current_line );
386 vfprintf(stdout, msg, args);
387 skipped++;
388}
389
390void __winetest_cdecl winetest_skip( const char *msg, ... )
391{
392 __winetest_va_list valist;
393 __winetest_va_start(valist, msg);
394 winetest_vskip(msg, valist);
395 __winetest_va_end(valist);
396}
397
398void __winetest_cdecl winetest_win_skip( const char *msg, ... )
399{
400 __winetest_va_list valist;
401 __winetest_va_start(valist, msg);
402 if (strcmp(winetest_platform, "windows") == 0)
403 winetest_vskip(msg, valist);
404 else
405 winetest_vok(0, msg, valist);
406 __winetest_va_end(valist);
407}
408
409void winetest_start_todo( const char* platform )
410{
411 tls_data* data=get_tls_data();
412 if (strcmp(winetest_platform,platform)==0)
413 data->todo_level++;
414 data->todo_do_loop=1;
415}
416
417int winetest_loop_todo(void)
418{
419 tls_data* data=get_tls_data();
420 int do_loop=data->todo_do_loop;
421 data->todo_do_loop=0;
422 return do_loop;
423}
424
425void winetest_end_todo( const char* platform )
426{
427 if (strcmp(winetest_platform,platform)==0)
428 {
429 tls_data* data=get_tls_data();
430 data->todo_level--;
431 }
432}
433
434int winetest_get_mainargs( char*** pargv )
435{
436 *pargv = winetest_argv;
437 return winetest_argc;
438}
439
440void winetest_wait_child_process( HANDLE process )
441{
442 DWORD exit_code = 1;
443
444 if (WaitForSingleObject( process, 30000 ))
445 fprintf( stdout, "%s: child process wait failed\n", current_test->name );
446 else
447 GetExitCodeProcess( process, &exit_code );
448
449 if (exit_code)
450 {
451 if (exit_code > 255)
452 {
453 fprintf( stdout, "%s: exception 0x%08x in child process\n", current_test->name, exit_code );
454 InterlockedIncrement( &failures );
455 }
456 else
457 {
458 fprintf( stdout, "%s: %u failures in child process\n",
459 current_test->name, exit_code );
460 while (exit_code-- > 0)
461 InterlockedIncrement(&failures);
462 }
463 }
464}
465
466const char *wine_dbgstr_wn( const WCHAR *str, int n )
467{
468 char *dst, *res;
469 size_t size;
470
471 if (!((ULONG_PTR)str >> 16))
472 {
473 if (!str) return "(null)";
474 res = get_temp_buffer( 6 );
475 sprintf( res, "#%04x", LOWORD(str) );
476 return res;
477 }
478 if (n == -1)
479 {
480 const WCHAR *end = str;
481 while (*end) end++;
482 n = end - str;
483 }
484 if (n < 0) n = 0;
485 size = 12 + min( 300, n * 5 );
486 dst = res = get_temp_buffer( size );
487 *dst++ = 'L';
488 *dst++ = '"';
489 while (n-- > 0 && dst <= res + size - 10)
490 {
491 WCHAR c = *str++;
492 switch (c)
493 {
494 case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
495 case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
496 case '\t': *dst++ = '\\'; *dst++ = 't'; break;
497 case '"': *dst++ = '\\'; *dst++ = '"'; break;
498 case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
499 default:
500 if (c >= ' ' && c <= 126)
501 *dst++ = c;
502 else
503 {
504 *dst++ = '\\';
505 sprintf(dst,"%04x",c);
506 dst+=4;
507 }
508 }
509 }
510 *dst++ = '"';
511 if (n > 0)
512 {
513 *dst++ = '.';
514 *dst++ = '.';
515 *dst++ = '.';
516 }
517 *dst++ = 0;
518 release_temp_buffer( res, dst - res );
519 return res;
520}
521
522/* Find a test by name */
523static const struct test *find_test( const char *name )
524{
525 const struct test *test;
526 const char *p;
527 size_t len;
528
529 if ((p = strrchr( name, '/' ))) name = p + 1;
530 if ((p = strrchr( name, '\\' ))) name = p + 1;
531 len = strlen(name);
532 if (len > 2 && !strcmp( name + len - 2, ".c" )) len -= 2;
533
534 for (test = winetest_testlist; test->name; test++)
535 {
536 if (!strncmp( test->name, name, len ) && !test->name[len]) break;
537 }
538 return test->name ? test : NULL;
539}
540
541
542/* Display list of valid tests */
543static void list_tests(void)
544{
545 const struct test *test;
546
547 fprintf( stdout, "Valid test names:\n" );
548 for (test = winetest_testlist; test->name; test++) fprintf( stdout, " %s\n", test->name );
549}
550
551
552/* Run a named test, and return exit status */
553static int run_test( const char *name )
554{
555 const struct test *test;
556 int status;
557
558 if (!(test = find_test( name )))
559 {
560 fprintf( stdout, "Fatal: test '%s' does not exist.\n", name );
561 exit_process(1);
562 }
563 successes = failures = todo_successes = todo_failures = 0;
564 tls_index=TlsAlloc();
565 current_test = test;
566 test->func();
567
568 if (winetest_debug)
569 {
570 fprintf( stdout, "%s: %d tests executed (%d marked as todo, %d %s), %d skipped.\n",
571 test->name, successes + failures + todo_successes + todo_failures,
572 todo_successes, failures + todo_failures,
573 (failures + todo_failures != 1) ? "failures" : "failure",
574 skipped );
575 }
576 status = (failures + todo_failures < 255) ? failures + todo_failures : 255;
577 return status;
578}
579
580
581/* Display usage and exit */
582static void usage( const char *argv0 )
583{
584 fprintf( stdout, "Usage: %s test_name\n\n", argv0 );
585 list_tests();
586 exit_process(1);
587}
588
589
590/* main function */
591int main( int argc, char **argv )
592{
593 char p[128];
594
595 setvbuf (stdout, NULL, _IONBF, 0);
596
597 winetest_argc = argc;
598 winetest_argv = argv;
599
600 if (GetEnvironmentVariableA( "WINETEST_PLATFORM", p, sizeof(p) )) winetest_platform = strdup(p);
601 if (GetEnvironmentVariableA( "WINETEST_DEBUG", p, sizeof(p) )) winetest_debug = atoi(p);
602 if (GetEnvironmentVariableA( "WINETEST_INTERACTIVE", p, sizeof(p) )) winetest_interactive = atoi(p);
603 if (GetEnvironmentVariableA( "WINETEST_REPORT_SUCCESS", p, sizeof(p) )) report_success = atoi(p);
604
605 if (!argv[1])
606 {
607 if (winetest_testlist[0].name && !winetest_testlist[1].name) /* only one test */
608 return run_test( winetest_testlist[0].name );
609 usage( argv[0] );
610 }
611 if (!strcmp( argv[1], "--list" ))
612 {
613 list_tests();
614 return 0;
615 }
616 return run_test(argv[1]);
617}
618
619#endif /* STANDALONE */
620
621#endif /* __WINE_WINE_TEST_H */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette