📄 main.c
字号:
break;
case WAIT_TIMEOUT:
report (R_ERROR, "Can't kill process '%s'", cmd);
break;
default:
report (R_ERROR, "Waiting for termination: %d",
wait);
}
}
CloseHandle (pi.hProcess);
}
if (out) {
close (1);
if (-1 == dup2 (oldstdout, 1))
report (R_FATAL, "Can't recover stdout: %d", errno);
close (oldstdout);
}
return status;
}
static void
get_subtests (const char *tempdir, struct wine_test *test, int id)
{
char *subname, *cmd;
FILE *subfile;
size_t total;
char buffer[8192], *index;
static const char header[] = "Valid test names:";
int allocated;
test->subtest_count = 0;
subname = tempnam (0, "sub");
if (!subname) report (R_FATAL, "Can't name subtests file.");
extract_test (test, tempdir, id);
cmd = strmake (NULL, "%s --list", test->exename);
run_ex (cmd, subname, 5000);
free (cmd);
subfile = fopen (subname, "r");
if (!subfile) {
report (R_ERROR, "Can't open subtests output of %s: %d",
test->name, errno);
goto quit;
}
total = fread (buffer, 1, sizeof buffer, subfile);
fclose (subfile);
if (sizeof buffer == total) {
report (R_ERROR, "Subtest list of %s too big.",
test->name, sizeof buffer);
goto quit;
}
buffer[total] = 0;
index = strstr (buffer, header);
if (!index) {
report (R_ERROR, "Can't parse subtests output of %s",
test->name);
goto quit;
}
index += sizeof header;
allocated = 10;
test->subtests = xmalloc (allocated * sizeof(char*));
index = strtok (index, whitespace);
while (index) {
if (test->subtest_count == allocated) {
allocated *= 2;
test->subtests = xrealloc (test->subtests,
allocated * sizeof(char*));
}
test->subtests[test->subtest_count++] = strdup (index);
index = strtok (NULL, whitespace);
}
test->subtests = xrealloc (test->subtests,
test->subtest_count * sizeof(char*));
quit:
if (remove (subname))
report (R_WARNING, "Can't delete file '%s': %d",
subname, errno);
free (subname);
}
static void
run_test (struct wine_test* test, const char* subtest)
{
int status;
const char* file = get_test_source_file(test->name, subtest);
const char* rev = get_file_rev(file);
char *cmd = strmake (NULL, "%s %s", test->exename, subtest);
xprintf ("%s:%s start %s %s\n", test->name, subtest, file, rev);
status = run_ex (cmd, NULL, 120000);
free (cmd);
xprintf ("%s:%s done (%d)\n", test->name, subtest, status);
}
static BOOL CALLBACK
EnumTestFileProc (HMODULE hModule, LPCTSTR lpszType,
LPTSTR lpszName, LONG_PTR lParam)
{
(*(int*)lParam)++;
return TRUE;
}
static char *
run_tests (char *logname)
{
int nr_of_files = 0, nr_of_tests = 0, i;
char *tempdir, *shorttempdir;
int logfile;
char *strres, *eol, *nextline;
DWORD strsize;
SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
if (!logname) {
logname = tempnam (0, "res");
if (!logname) report (R_FATAL, "Can't name logfile.");
}
report (R_OUT, logname);
logfile = open (logname, O_WRONLY | O_CREAT | O_EXCL | O_APPEND,
0666);
if (-1 == logfile) {
if (EEXIST == errno)
report (R_FATAL, "File %s already exists.", logname);
else report (R_FATAL, "Could not open logfile: %d", errno);
}
if (-1 == dup2 (logfile, 1))
report (R_FATAL, "Can't redirect stdout: %d", errno);
close (logfile);
tempdir = tempnam (0, "wct");
if (!tempdir)
report (R_FATAL, "Can't name temporary dir (check %%TEMP%%).");
shorttempdir = strdup (tempdir);
if (shorttempdir) { /* try stable path for ZoneAlarm */
strstr (shorttempdir, "wct")[3] = 0;
if (CreateDirectoryA (shorttempdir, NULL)) {
free (tempdir);
tempdir = shorttempdir;
} else free (shorttempdir);
}
if (tempdir != shorttempdir && !CreateDirectoryA (tempdir, NULL))
report (R_FATAL, "Could not create directory: %s", tempdir);
report (R_DIR, tempdir);
xprintf ("Version 3\n");
strres = extract_rcdata (WINE_BUILD, STRINGRES, &strsize);
xprintf ("Tests from build ");
if (strres) xprintf ("%.*s", strsize, strres);
else xprintf ("-\n");
strres = extract_rcdata (TESTS_URL, STRINGRES, &strsize);
xprintf ("Archive: ");
if (strres) xprintf ("%.*s", strsize, strres);
else xprintf ("-\n");
xprintf ("Tag: %s\n", tag);
xprintf ("Build info:\n");
strres = extract_rcdata (BUILD_INFO, STRINGRES, &strsize);
while (strres) {
eol = memchr (strres, '\n', strsize);
if (!eol) {
nextline = NULL;
eol = strres + strsize;
} else {
strsize -= eol - strres + 1;
nextline = strsize?eol+1:NULL;
if (eol > strres && *(eol-1) == '\r') eol--;
}
xprintf (" %.*s\n", eol-strres, strres);
strres = nextline;
}
xprintf ("Operating system version:\n");
print_version ();
xprintf ("Test output:\n" );
report (R_STATUS, "Counting tests");
if (!EnumResourceNames (NULL, MAKEINTRESOURCE(TESTRES),
EnumTestFileProc, (LPARAM)&nr_of_files))
report (R_FATAL, "Can't enumerate test files: %d",
GetLastError ());
wine_tests = xmalloc (nr_of_files * sizeof wine_tests[0]);
report (R_STATUS, "Extracting tests");
report (R_PROGRESS, 0, nr_of_files);
for (i = 0; i < nr_of_files; i++) {
get_subtests (tempdir, wine_tests+i, i);
nr_of_tests += wine_tests[i].subtest_count;
}
report (R_DELTA, 0, "Extracting: Done");
report (R_STATUS, "Running tests");
report (R_PROGRESS, 1, nr_of_tests);
for (i = 0; i < nr_of_files; i++) {
struct wine_test *test = wine_tests + i;
int j;
for (j = 0; j < test->subtest_count; j++) {
report (R_STEP, "Running: %s:%s", test->name,
test->subtests[j]);
run_test (test, test->subtests[j]);
}
}
report (R_DELTA, 0, "Running: Done");
report (R_STATUS, "Cleaning up");
close (1);
remove_dir (tempdir);
free (tempdir);
free (wine_tests);
return logname;
}
static void
usage (void)
{
fprintf (stderr, "\
Usage: winetest [OPTION]...\n\n\
-c console mode, no GUI\n\
-e preserve the environment\n\
-h print this message and exit\n\
-q quiet mode, no output at all\n\
-o FILE put report into FILE, do not submit\n\
-s FILE submit FILE, do not run tests\n\
-t TAG include TAG of characters [-.0-9a-zA-Z] in the report\n");
}
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
LPSTR cmdLine, int cmdShow)
{
char *logname = NULL;
const char *cp, *submit = NULL;
int reset_env = 1;
int interactive = 1;
/* initialize the revision information first */
extract_rev_infos();
cmdLine = strtok (cmdLine, whitespace);
while (cmdLine) {
if (cmdLine[0] != '-' || cmdLine[2]) {
report (R_ERROR, "Not a single letter option: %s", cmdLine);
usage ();
exit (2);
}
switch (cmdLine[1]) {
case 'c':
report (R_TEXTMODE);
interactive = 0;
break;
case 'e':
reset_env = 0;
break;
case 'h':
usage ();
exit (0);
case 'q':
report (R_QUIET);
interactive = 0;
break;
case 's':
submit = strtok (NULL, whitespace);
if (tag)
report (R_WARNING, "ignoring tag for submission");
send_file (submit);
break;
case 'o':
logname = strtok (NULL, whitespace);
break;
case 't':
tag = strtok (NULL, whitespace);
if (strlen (tag) > MAXTAGLEN)
report (R_FATAL, "tag is too long (maximum %d characters)",
MAXTAGLEN);
cp = findbadtagchar (tag);
if (cp) {
report (R_ERROR, "invalid char in tag: %c", *cp);
usage ();
exit (2);
}
break;
default:
report (R_ERROR, "invalid option: -%c", cmdLine[1]);
usage ();
exit (2);
}
cmdLine = strtok (NULL, whitespace);
}
if (!submit) {
report (R_STATUS, "Starting up");
if (!running_on_visible_desktop ())
report (R_FATAL, "Tests must be run on a visible desktop");
if (reset_env && (putenv ("WINETEST_PLATFORM=windows") ||
putenv ("WINETEST_DEBUG=1") ||
putenv ("WINETEST_INTERACTIVE=0") ||
putenv ("WINETEST_REPORT_SUCCESS=0")))
report (R_FATAL, "Could not reset environment: %d", errno);
if (!tag) {
if (!interactive)
report (R_FATAL, "Please specify a tag (-t option) if "
"running noninteractive!");
if (guiAskTag () == IDABORT) exit (1);
}
report (R_TAG);
if (!logname) {
logname = run_tests (NULL);
if (report (R_ASK, MB_YESNO, "Do you want to submit the "
"test results?") == IDYES)
if (!send_file (logname) && remove (logname))
report (R_WARNING, "Can't remove logfile: %d.", errno);
free (logname);
} else run_tests (logname);
report (R_STATUS, "Finished");
}
exit (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -