root/dstress.c

Revision 1628:c6ef09dfba4d, 33.5 kB (checked in by Moritz Warning <moritzwarning@web.de>, 1 year ago)

add mini test set from ldc project

Line 
1 /*
2  * core test tool for the DStress test suite
3  * http://dstress.kuehne.cn
4  *
5  * Copyright (C)
6  *  2005, 2006 Thomas Kuehne <thomas@kuehne.cn>
7  *  2005 Carlos Santander (Windows files)
8  *  2005 Stewart Gordon <smjg_1998@yahoo.com> (Windows crashRun)
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  *
24  * $HeadURL$
25  * $Date$
26  * $Author$
27  *
28  */
29
30 /* Beware: the code doesn't care about freeing allocated memory etc. ... */
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <ctype.h>
37
38 /* number's choice: XOR and printf :) */
39 #define MODE_RUN    (0x10000)
40 #define MODE_NORUN  (0x01000)
41 #define MODE_COMPILE    (0x00100)
42 #define MODE_NOCOMPILE  (0x00010)
43 #define MODE_TORTURE    (0x00002)
44
45 #define RES_BASE_MASK   (0xFFFFFF0)
46 #define RES_PASS    (0x1000000)
47 #define RES_XFAIL   (0x0100000)
48 #define RES_XPASS   (0x0010000)
49 #define RES_FAIL    (0x0001000)
50 #define RES_ERROR   (0x0000100)
51 #define RES_UNTESTED    (0x0000010)
52 #define RES_BAD_GDB (0x0000004)
53 #define RES_BAD_MSG (0x0000002)
54
55 #if defined(__GNU_LIBRARY__) || defined(__GLIBC__)
56 #define USE_POSIX 1
57 #endif
58
59 #if defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__)
60 #define USE_POSIX 1
61 #endif
62
63 #if defined(__APPLE__) && defined(__MACH__)
64 #define USE_POSIX 1
65 #endif
66
67 #if defined(WIN) || defined(WIN32) || defined(WIN64)
68 #define USE_WINDOWS 1
69 #endif
70
71 /* prefere USE_POSIX over USE_WINDOWS if both APIs are detected */
72 #ifdef USE_POSIX
73
74 #include <sys/types.h>
75 #include <sys/stat.h>
76 #include <fcntl.h>
77 #include <unistd.h>
78 #include <regex.h>
79 #include <limits.h>
80
81 /* not every STDLIB propperly supports C99's "%z" for printf formating */
82 /* (I just love those non-conforming headers...) */
83 #undef ZU
84
85 #if !defined(ZU) && defined(SSIZE_MAX)
86 #if defined(INT_MAX) && SSIZE_MAX == INT_MAX
87 #define ZU "%u"
88 #elif defined(LONG_MAX) && SSIZE_MAX == LONG_MAX
89 #define ZU "%lu"
90 #elif defined(LLONG_MAX) && SSIZE_MAX == LLONG_MAX
91 #define ZU "%llu"
92 #elif defined(SHRT_MAX) && SSIZE_MAX == SHRT_MAX
93 #define ZU "%hu"
94 #endif
95 #endif /* SSIZE_MAX */
96
97 #if !defined(ZU) && defined(SIZE_T_MAX)
98 #if defined(UINT_MAX) && SIZE_T_MAX == UINT_MAX
99 #define ZU "%u"
100 #elif defined(ULONG_MAX) && SIZE_T_MAX == ULONG_MAX
101 #define ZU "%lu"
102 #elif defined(ULLONG_MAX) && SIZE_T_MAX == ULLONG_MAX
103 #define ZU "%llu"
104 #elif defined(USHRT_MAX) && SIZE_T_MAX == USHRT_MAX
105 #define ZU "%hu"
106 #endif
107 #endif /* SIZE_T_MAX */
108
109 #ifndef ZU
110 #include <stdint.h>
111 #undef ZU
112 #ifdef PTRDIFF_MAX
113 #if defined(INT_MAX) && PTRDIFF_MAX == INT_MAX
114 #define ZU "%u"
115 #elif defined(LONG_MAX) && PTRDIFF_MAX == LONG_MAX
116 #define ZU "%lu"
117 #elif defined(LLONG_MAX) && PTRDIFF_MAX == LLONG_MAX
118 #define ZU "%llu"
119 #elif defined(SHRT_MAX) && PTRDIFF_MAX == SHRT_MAX
120 #define ZU "%hu"
121 #endif
122 #endif
123 #endif /* PTRDIFF_MAX */
124
125 #ifndef ZU
126 #error what is the size of a pointer?
127 #endif
128
129 #else
130 #ifdef USE_WINDOWS
131
132 #include <process.h>
133 typedef int pid_t;
134
135 #include <windows.h>
136 #define snprintf _snprintf
137 #ifndef INVALID_FILE_SIZE
138 #define INVALID_FILE_SIZE (-1)
139 #endif
140
141 /* not every STDLIB supports C99's "%z" for printf formating */
142 #ifdef WIN32
143 #define ZU "%u"
144 #else
145 #ifdef WIN64
146 #define ZU "%llu"
147 #else
148 #error what is the size of a pointer?
149 #endif
150 #endif
151
152 #else
153 #error neither POSIX nor MSWindows API detected
154 #endif /* USE_WINDOWS else */
155 #endif /* USE_POSIX else */
156
157 #define TORTURE_PREFIX      "torture-"
158
159 #ifdef USE_POSIX
160 #define     CRASH_RUN   "./crashRun 10 256"
161 #ifdef USE_VALGRIND
162 #define     VALGRIND    "valgrind --leak-check=no -q --suppressions=valgrind.suppress" 
163 #else
164 #define     VALGRIND    NULL
165 #endif
166 #define     TMP_DIR     "./obj"
167 #define     RM_DIR      "rm -rf"
168 #else
169 #ifdef USE_WINDOWS
170 #define     VALGRIND    NULL
171 #define     TMP_DIR     ".\\obj"
172 #define     RM_DIR      "rd /sq"
173 #else
174 #error OS dependent file names not defined
175 #endif
176 #endif
177
178 char* tmp_dir;
179
180 #ifdef USE_WINDOWS
181 HANDLE originalStdout, originalStderr;
182 #endif
183
184 const char* torture[] = {
185     /* 0 args */
186     "",
187
188     /* 1 args */
189     "-g",
190     "-inline",
191     "-fPIC",
192     "-O",
193     "-release",
194
195     /* 2 args */
196     "-g -inline",
197     "-g -fPIC",
198     "-g -O",
199     "-g -release",
200     "-inline -fPIC",
201     "-inline -O",
202     "-inline -release",
203     "-fPIC -O",
204     "-fPIC -release",
205     "-O -release",
206
207     /* 3 args */
208     "-g -inline -fPIC",
209     "-g -inline -O",
210     "-g -inline -release",
211     "-g -fPIC -O",
212     "-g -fPIC -release",
213     "-g -O -release",
214     "-inline -fPIC -O",
215     "-inline -fPIC -release",
216     "-inline -O -release",
217     "-fPIC -O -release",
218
219     /* 4 args */
220     "-g -inline -fPIC -O",
221     "-g -inline -fPIC -release",
222     "-g -fPIC -O -release",
223     "-inline -fPIC -O -release",
224
225     /* 5 args */
226     "-g -inline -fPIC -O -release",
227
228     /* 4 args - ommitted */
229     "-g -inline -O -release"
230 };
231
232 /* secure malloc */
233 void *xmalloc(size_t size){
234     void *p = malloc(size);
235     if (p == NULL){
236         fprintf(stderr, "Failed to allocate " ZU " bytes!\n", size);
237         exit(EXIT_FAILURE);
238     }
239     return p;
240 }
241 #define malloc xmalloc
242
243 /* secure calloc */
244 void* xcalloc(size_t members, size_t size){
245     void* ptr = calloc(members, size);
246     if(ptr == NULL){
247         fprintf(stderr, "Failed to allocate " ZU " elements"
248             "(" ZU " bytes each)!\n", members, size);
249         exit(EXIT_FAILURE);
250     }
251     return ptr;
252 }
253 #define calloc xcalloc
254
255
256 void printResult(int result, int modus, char* case_file, FILE* stream){
257     char* msg = NULL;
258 #ifdef DEBUG
259     fprintf(stderr, "case: %s, modus: %x, result: %x\n", case_file, modus,
260             result);
261 #endif
262
263     if(result & RES_PASS){
264         msg = "PASS: ";
265     }else if(result & RES_XFAIL){
266         msg = "XFAIL:";
267     }else if(result & RES_XPASS){
268         msg = "XPASS:";
269     }else if(result & RES_FAIL){
270         msg = "FAIL: ";
271     }else if(result & RES_ERROR){
272         msg = "ERROR:";
273     }
274
275     fprintf(stream, "%s\t%s%s%s\n", msg, case_file,
276             (result & RES_BAD_MSG) ? " [bad error message]" : "",
277             (result & RES_BAD_GDB) ? " [bad debugger message]" : "");
278 }
279
280 char* strip(char* buffer){
281     char* tmp = NULL;
282
283     if(buffer!=NULL){
284         while(isspace(buffer[0])){
285             buffer++;
286         }
287
288         for(tmp=buffer+strlen(buffer)-1; isspace(tmp[0]); tmp=buffer+strlen(buffer)-1){
289             tmp[0]='\x00';
290         }
291     }
292     return buffer;
293 }
294
295 unsigned int genTempFileNameCount;
296 char* genTempFileName(){
297     char* back;
298     size_t len;
299
300     len = strlen(tmp_dir) + 128;
301     back = (char*) malloc(len);
302
303 #ifdef USE_POSIX
304     snprintf(back, len, "%s/t%x-%x-%x.tmp", tmp_dir, getpid(), rand(), ++genTempFileNameCount);
305 #else
306     snprintf(back, len, "%s\\t%x-%x-%x.tmp", tmp_dir, getpid(), rand(), ++genTempFileNameCount);
307 #endif
308
309     return back;
310 }
311
312 /* cleanup "/" versus "\" in filenames */
313 char* cleanPathSeperator(char* filename){
314     char* pos = NULL;
315 #ifdef USE_POSIX
316     for(pos=strchr(filename, '\\'); pos; pos=strchr(filename, '\\')){
317         *pos='/';
318     }
319 #else
320 #if USE_WINDOWS
321     for(pos=strchr(filename, '/'); pos; pos=strchr(filename, '/')){
322         *pos='\\';
323     }
324 #else
325
326 #error no cleanPathSeperator implementation available for this system
327
328 #endif /* USE_WINDOWS else */
329 #endif /* USE_POSIX else */
330     return filename;
331 }
332
333 char* loadFile(char* filename, size_t* len){
334 #ifdef USE_POSIX
335     char* back;
336     struct stat fileInfo;
337     int file = open(filename, O_RDONLY);
338
339     back = NULL;
340
341     if(errno == 0 && file != 0 && file != -1){
342         if(0==fstat(file, &fileInfo)){
343             back = (char*) malloc(fileInfo.st_size+1);
344             fileInfo.st_size = read(file, back, fileInfo.st_size);
345             if(fileInfo.st_size>=0){
346                 *(back+fileInfo.st_size) = '\x00';
347                 *len = fileInfo.st_size;
348             }else{
349                 back = NULL;
350                 *len = 0;
351             }
352         }
353         close(file);
354     }
355
356     if(back){
357         return back;
358     }
359
360     fprintf(stderr, "File not found \"%s\" (%s)\n", filename, strerror(errno));
361     exit(EXIT_FAILURE);
362 #else /* USE_POSIX */
363 #ifdef USE_WINDOWS
364     /* @todo@ check for 32bit/64bit */
365     char* back;
366     DWORD size, numread;
367     HANDLE file=CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
368         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
369
370     back = NULL;
371     size = 0;
372     numread = 0;
373     if (file != INVALID_HANDLE_VALUE){
374         size = GetFileSize(file, NULL);
375         if (size != INVALID_FILE_SIZE){
376             back=malloc((size+1)*sizeof(char));
377             if (ReadFile(file,back,size,&numread,NULL) == 1){
378                 if (numread==size){
379                     *(back+size) = '\x00';
380                     *len = size;
381                 }else{
382                     back = NULL;
383                     *len = 0;
384                 }
385             }else{
386                 back = NULL;
387                 *len = 0;
388             }
389         }
390         CloseHandle(file);
391     }
392     if(back){
393         errno = 0;
394         return back;
395     }
396
397     fprintf(stderr, "File not found \"%s\"\n", filename);
398     exit(EXIT_FAILURE);
399 #else /* USE_WINDOWS */
400
401 #error no loadFile implementation present
402
403 #endif /* USE_WINDOWS */
404 #endif /* USE_POSIX else */
405 }
406
407 void writeFile(const char* filename, const char* content){
408     size_t len;
409     FILE* file;
410
411     len = strlen(content);
412     errno = 0;
413     file = fopen(filename, "w+");
414
415     if(errno == 0 && file != NULL){
416         if((fwrite(content, sizeof(char), len, file) != len) || (errno != 0)){
417             fprintf(stderr, "failed to write file \"%s\" (%s)\n", filename, strerror(errno));
418             exit(EXIT_FAILURE);
419         }
420         if(fclose(file) || (errno != 0)){
421             fprintf(stderr, "failed to close file \"%s\" (%s)\n", filename, strerror(errno));
422             exit(EXIT_FAILURE);
423         }
424         return;
425     }
426
427     fprintf(stderr, "couldn't open file \"%s\" for writing (%s)\n", filename, strerror(errno));
428     exit(EXIT_FAILURE);
429 }
430
431 /* query the environment for the compiler name */
432 char* getCompiler(void){
433     char* back = getenv("DMD");
434
435     if(back==NULL){
436         back = "dmd";
437     }
438
439     return strip(cleanPathSeperator(back));
440 }
441
442 /* query the environment for the debugger name */
443 char* getGDB(void){
444     char* back = getenv("GDB");
445
446     if(back==NULL){
447         back = "gdb";
448     }
449
450     return strip(cleanPathSeperator(back));
451 }
452
453 char* getTortureBlock(void){
454     char* back = getenv("DSTRESS_TORTURE_BLOCK");
455
456     if(back!=NULL){
457         back = strip(back);
458         if(strlen(back)<1){
459             back = NULL;
460         }
461     }
462
463     return back;
464 }
465
466 /* extract the FIRST occurance of a given TAG until the next linebreak */
467 char* getCaseFlag(const char* data, const char* tag){
468     char* begin;
469     char* end1;
470     char* end2;
471     char* back;
472
473     begin = NULL;
474     end1 = NULL;
475     end2 = NULL;
476     back = NULL;
477
478     if(data!=NULL && tag!=NULL){
479         begin = strstr(data, tag);
480         if(begin!=NULL){
481             begin = begin+strlen(tag);
482             end1 = strstr(begin, "\n");
483             end2 = strstr(begin, "\r");
484             if(end2!=NULL && ((end1!=NULL && end2<end1) || end1==NULL)){
485                 end1=end2;
486             }
487             if(end1==NULL){
488                 end1 = begin + strlen(begin);
489             }
490             back = (char*) malloc(end1-begin+1);
491             strncpy(back, begin, end1-begin);
492             back[end1-begin]='\x00';
493             return strip(back);
494         }
495     }
496
497     back = (char*) malloc(1);
498     back[0] = 0;
499     return back;
500 }
501
502 /* check compile-time error messages */
503 int checkErrorMessage(const char* file, const char* line, const char* buffer){
504
505     char* dmd;
506     char* gdc;
507     size_t len;
508     int back;
509
510     dmd = NULL;
511     gdc = NULL;
512     len = 0;
513     back = 0;
514
515     /* clean arguments */
516     if(file && !file[0]){
517         file = NULL;
518     }
519
520     if(line && !line[0]){
521         line = NULL;
522     }
523
524     /* gen patterns*/
525     if(file!=NULL){
526         if(line!=NULL){
527             len = strlen(file)+strlen(line)+3;
528             dmd = (char*) malloc(len);
529             snprintf(dmd, len, "%s(%s)", file, line);
530
531             gdc = (char*) malloc(--len);
532             snprintf(gdc, len, "%s:%s", file, line);
533         }else{
534             len = strlen(file)+2;
535             dmd = (char*) malloc(len);
536             snprintf(dmd, len, "%s(", file);
537
538             gdc = (char*) malloc(len);
539             snprintf(gdc, len, "%s:", file);
540         }
541     }else if(line!=NULL){
542         len = strlen(line)+3;
543         dmd = (char*) malloc(len);
544         snprintf(dmd, len, "(%s)", line);
545
546         gdc = (char*) malloc(--len);
547         snprintf(gdc, len, ":%s", line);
548     }else{
549         return 1;
550     }
551
552     /* specific error messages */
553 #ifdef DEBUG
554     fprintf(stderr, "pattern(dmd):\t%s\n", dmd);
555     fprintf(stderr, "pattern(gdc):\t%s\n", gdc);
556 #endif
557
558     if( (dmd!=NULL && strstr(buffer, dmd))
559             || (gdc!=NULL && strstr(buffer, gdc))
560             || (dmd==NULL && gdc==NULL)){
561         back=1;
562     }
563
564     free(dmd);
565     free(gdc);
566
567     return back;
568 }
569
570 int checkRuntimeErrorMessage(const char* file, const char* line, const char* buffer){
571     /* PhobosLong   dir/file.d(2)
572      * Phobos   package.module(2)
573      */
574
575     char* phobos;
576     char* phobosLong;
577
578     const char* begin;
579     const char* end;
580     size_t len;
581
582     int back=0;
583
584     phobos = NULL;
585     phobosLong = NULL;
586
587     begin = NULL;
588     end = NULL;
589     len = 0;
590
591     /* clean arguments */
592     if(file && !file[0]){
593         file = NULL;
594     }
595
596     if(line && !line[0]){
597         line = NULL;
598     }
599
600     /* gen patterns*/
601     if(file!=NULL){
602         if(line!=NULL){
603             len = strlen(file)+strlen(line)+3;
604             phobos = (char*) malloc(len);
605             begin=strrchr(file,'/');
606             if(begin){
607                 begin++;
608             }else{
609                 begin=strrchr(file,'\\');
610                 if(begin){
611                     begin++;
612                 }else{
613                     begin=file;
614                 }
615             }
616             end=strrchr(file,'.');
617             strncat(phobos, begin, end-begin);
618             snprintf(phobos, len, "%.*s(%s)",
619                 (int)(end-begin), begin,
620                 line);
621
622             phobosLong = (char*) malloc(len);
623             snprintf(phobosLong, len, "%s(%s)", file, line);
624         }else{
625             len = strlen(file)+2;
626             phobos = (char*) malloc(len);
627             begin=strrchr(file,'/');
628             if(begin){
629                 begin++;
630             }else{
631                 begin=strrchr(file,'\\');
632                 if(begin){
633                     begin++;
634                 }else{
635                     begin=file;
636                 }
637             }
638             end=strrchr(file,'.');
639             snprintf(phobos, len, "%.*s(", (int)(end-begin), begin);
640
641             phobosLong = (char*) malloc(len);
642             snprintf(phobosLong, len, "%s(", file);
643         }
644     }else if(line!=NULL){
645         len = strlen(line)+3;
646         phobos = (char*) malloc(len);
647         snprintf(phobos, len, "(%s)", line);
648
649         phobosLong=NULL;
650     }else{
651         return 1;
652     }
653
654     /* specific error messages */
655
656 #ifdef DEBUG
657     fprintf(stderr, "pattern(phobosShort):\t%s\n", phobos);
658     fprintf(stderr, "pattern(phobosLong):\t%s\n", phobosLong);
659 #endif
660
661     if( (phobos && strstr(buffer, phobos))
662         || (phobosLong && strstr(buffer, phobosLong)))
663     {
664         back=1;
665     }
666
667     free(phobos);
668     if(phobosLong){
669         free(phobosLong);
670     }
671
672     return back;
673 }
674
675 int hadExecCrash(const char* buffer){
676     if(strstr(buffer, "Segmentation fault")
677             || strstr(buffer, "Internal error")
678             || strstr(buffer, "gcc.gnu.org/bugs")
679             || strstr(buffer, "EXIT CODE: signal")
680             || strstr(buffer, "Assertion failure")
681             || strstr(buffer, "Access Violation")
682             || strstr(buffer, "Invalid read of size")
683             || strstr(buffer, "Conditional jump or move depends on uninitialised value")
684             || strstr(buffer, "Use of uninitialised value of size"))
685     {
686         return 1;
687     }
688     return 0;
689 }
690
691 int conditionalResult(const char* buffer){
692     if(strstr(buffer, "DSTRESS{XFAIL}")){
693         return RES_XFAIL;
694     }else if(strstr(buffer, "DSTRESS{XPASS}")){
695         return RES_XPASS;
696     }else if(strstr(buffer, "DSTRESS{FAIL}")){
697         return RES_FAIL;
698     }else if(strstr(buffer, "DSTRESS{PASS}")){
699         return RES_PASS;
700     }else if(strstr(buffer, "DSTRESS{ERROR}")){
701         return RES_ERROR;
702     }else{
703         return 0;
704     }
705    
706 }
707
708 /* system call with time-out */
709 int crashRun(const char* cmd, char** logFile){
710
711     size_t len;
712     char* buffer;
713     int back;
714 #ifdef USE_WINDOWS
715     PROCESS_INFORMATION processInfo;
716     STARTUPINFO startupInfo;
717     SECURITY_ATTRIBUTES sa = {
718         sizeof(SECURITY_ATTRIBUTES), NULL, TRUE
719     };
720     HANDLE tLogFile;
721     unsigned long exitCode;
722     int timeLeft = 600; /* time limit in iterations of WFX loop */
723 #endif
724
725     *logFile = genTempFileName();
726 #ifdef USE_POSIX
727     len = 40 + strlen(CRASH_RUN) + strlen(cmd) + strlen(*logFile);
728     buffer = (char*) malloc(len);
729
730     snprintf(buffer, len, "%s %s 2>&1 | head -n 200 > %s", CRASH_RUN, cmd, *logFile);
731
732     system(buffer);
733     free(buffer);
734
735     buffer=loadFile(*logFile, &len);
736
737     /* @todo@ use: len */
738     if(strstr(buffer, "EXIT CODE: 0")){
739         back = EXIT_SUCCESS;
740     }else if(strstr(buffer, "EXIT CODE: 256")
741             || strstr(buffer, "EXIT CODE: timeout") || strstr(buffer, "Cputime limit exceeded"))
742     {
743         back = EXIT_FAILURE;
744     }else{
745         back = RAND_MAX;
746     }
747     free(buffer);
748
749     return back;
750 #elif defined USE_WINDOWS
751     memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
752     memset(&startupInfo, 0, sizeof(STARTUPINFO));
753     startupInfo.cb = sizeof(STARTUPINFO);
754
755     tLogFile = CreateFile(*logFile, GENERIC_WRITE,
756       0, &sa, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
757
758     if (tLogFile == NULL) {
759         printf("ERROR: could not open log file");
760         return RAND_MAX;
761     }
762
763     SetStdHandle(STD_OUTPUT_HANDLE, tLogFile);
764     SetStdHandle(STD_ERROR_HANDLE, originalStdout);
765
766     if (!CreateProcess(NULL, (char*) cmd, NULL, NULL, TRUE, 0, NULL, NULL,
767           &startupInfo, &processInfo)) {
768         void *message;
769
770         FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
771           | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
772            (char*) &message, 0, NULL);
773
774         SetStdHandle(STD_OUTPUT_HANDLE, originalStdout);
775         SetStdHandle(STD_ERROR_HANDLE, originalStderr);
776         CloseHandle(tLogFile);
777
778         /* this should never happen */
779         fprintf(stderr, "ERROR running %s:\n", cmd);
780         fprintf(stderr, "%s\n", message);
781         LocalFree((HLOCAL) message);
782         return RAND_MAX;
783     }
784
785     /* wait for exit */
786     while (TRUE) {
787         GetExitCodeProcess(processInfo.hProcess, &exitCode);
788         if (exitCode == 0x103) {
789             if (--timeLeft == 0) {
790                 TerminateProcess(processInfo.hProcess, EXIT_FAILURE);
791                 SetStdHandle(STD_OUTPUT_HANDLE, originalStdout);
792                 SetStdHandle(STD_ERROR_HANDLE, originalStderr);
793                 CloseHandle(tLogFile);
794                 printf("EXIT CODE: timeout\n");
795                 Sleep(100);
796                 return RAND_MAX;
797             }
798             Sleep(100);
799         } else {
800             SetStdHandle(STD_OUTPUT_HANDLE, originalStdout);
801             SetStdHandle(STD_ERROR_HANDLE, originalStderr);
802
803             CloseHandle(tLogFile);
804
805             printf("EXIT CODE: %i\n", exitCode);
806             return exitCode;
807         }
808     }
809
810 #else /* USE_WINDOWS */
811 #error comment me out, if your test cases produce neither eternal loops nor Access Violations
812
813     len = 10 + strlen(cmd) + strlen(*logFile);
814     buffer = malloc(len);
815
816     snprintf(buffer, len, "%s > %s 2>&1", cmd, *logFile);
817
818     int i = system(buffer);
819     printf("EXIT CODE: %i\n", i);
820
821     return i;
822 #endif /* USE_POSIX else */
823 }
824
825 int target_compile(int modus, char* compiler, char* arguments, char* case_file,
826         char* error_file, char* error_line)
827 {
828     size_t bufferLen;
829     char* buffer;
830     int res;
831     int testResult;
832     int good_error;
833     char* logFile;
834
835     bufferLen = 0;
836     buffer = NULL;
837     res = -1;
838     testResult = -1;
839     good_error = 0;
840     logFile = NULL;
841
842     if(!(modus & MODE_COMPILE) && !(modus & MODE_NOCOMPILE)){
843         fprintf(stderr, "BUG: badly handled mode %i (->compile)\n",
844             modus);
845         exit(EXIT_FAILURE);
846     }
847
848     /* gen command */
849     bufferLen = strlen(compiler) + strlen(arguments) + strlen(tmp_dir)
850         + strlen(case_file) + 21;
851     buffer = (char*) malloc(bufferLen);
852     snprintf(buffer, bufferLen, "%s %s ", compiler, arguments);
853
854     if(NULL == strstr(buffer, "-od")){
855         snprintf(buffer, bufferLen, "%s %s -od%s -c %s",
856             compiler, arguments, tmp_dir, case_file);
857     }else{
858         snprintf(buffer, bufferLen, "%s %s -c %s",
859             compiler, arguments, case_file);
860     }
861
862     /* test */
863     if(modus & MODE_COMPILE){
864         printf("compile: %s\n", buffer);
865     }else{
866         printf("nocompile: %s\n", buffer);
867     }
868     res = crashRun(buffer, &logFile);
869     free(buffer);
870
871     /* diagnostic */
872     buffer = loadFile(logFile, &bufferLen);
873     printf("%.*s\n", (int)bufferLen, buffer);
874     remove(logFile);
875     free(logFile);
876     good_error = checkErrorMessage(error_file, error_line, buffer);
877
878     testResult = conditionalResult(buffer);
879
880     if(testResult){
881         /* conditional result */
882     }else if(hadExecCrash(buffer)){
883         testResult = RES_ERROR;
884     }else if(modus & MODE_COMPILE){
885         if(res == EXIT_SUCCESS){
886             testResult = RES_PASS;
887         }else if(res == EXIT_FAILURE){
888             testResult = RES_FAIL | (good_error ? 0 : RES_BAD_MSG);
889         }else{
890             testResult = RES_ERROR | (good_error ? 0 : RES_BAD_MSG);
891         }
892     }else{
893         if(res == EXIT_FAILURE){
894             if(good_error){
895                 testResult = RES_XFAIL;
896             }else{
897                 testResult = RES_FAIL | RES_BAD_MSG;
898             }
899         }else if(res == EXIT_SUCCESS){
900             testResult = RES_XPASS;
901         }else{
902             testResult = RES_ERROR;
903         }
904     }
905
906     free(buffer);
907
908     return testResult;
909 }
910
911 int target_run(int modus, char* compiler, char* arguments, char* case_file,
912     char* error_file, char* error_line
913 #ifdef REG_EXTENDED
914     , char* gdb, char* gdb_script, regex_t* gdb_pattern
915 #endif
916     )
917 {
918     size_t bufferLen;
919     char* buffer;
920     int res;
921     int testResult;
922     int good_error;
923     char* logFile;
924     char* gdb_scripter;
925     int good_gdb;
926
927     bufferLen = 0;
928     buffer = NULL;
929     res = -1;
930     testResult = -1;
931     good_error = 0;
932     logFile = NULL;
933     good_gdb = 0;
934     gdb_scripter = NULL;
935
936     if(!(modus & MODE_RUN) && !(modus & MODE_NORUN)){
937         fprintf(stderr, "BUG: badly handled mode %i (->run)\n", modus);
938         exit(EXIT_FAILURE);
939     }
940
941     /* gen command */
942
943     bufferLen = strlen(compiler) + strlen(arguments) + strlen(tmp_dir)
944             + strlen(case_file) * 2 + 64;
945     buffer = (char*) malloc(bufferLen);
946     snprintf(buffer, bufferLen, "%s %s ", compiler, arguments);
947
948     if(NULL == strstr(buffer, "-od")){
949         if(NULL == strstr(buffer, "-of")){
950             snprintf(buffer, bufferLen,
951                 "%s %s -od%s -of%s.exe %s",
952                 compiler, arguments, tmp_dir, case_file,
953                 case_file);
954         }else{
955             snprintf(buffer, bufferLen,
956                 "%s %s -od%s %s",
957                 compiler, arguments, tmp_dir, case_file);
958         }
959     }else if(NULL == strstr(buffer, "-of")){
960         snprintf(buffer, bufferLen,
961             "%s %s -of%s.exe %s",
962             compiler, arguments, case_file, case_file);
963     }else{
964         snprintf(buffer, bufferLen, "%s %s %s",
965             compiler, arguments, case_file);
966     }
967
968     /* test 1/3 - compile */
969     if(modus & MODE_RUN){
970         printf("run: %s\n", buffer);
971     }else{
972         printf("norun: %s\n", buffer);
973     }
974     res = crashRun(buffer, &logFile);
975     free(buffer);
976
977     /* diagnostic 1/3 */
978     buffer = loadFile(logFile, &bufferLen);
979     printf("%.*s", (int)bufferLen, buffer);
980     remove(logFile);
981     free(logFile);
982
983     if(modus & MODE_RUN){
984         good_error = checkErrorMessage(error_file, error_line,
985             buffer);
986     }else{
987         good_error = 1;
988     }
989
990     testResult = conditionalResult(buffer);
991     if(hadExecCrash(buffer)){
992         free(buffer);
993         return RES_ERROR;
994     }else{
995         free(buffer);
996         if(testResult){
997             return testResult;
998         }else if((res == EXIT_FAILURE) && good_error){
999             return RES_FAIL;
1000         }else if(res!=EXIT_SUCCESS){
1001             return RES_ERROR | (good_error ? 0 : RES_BAD_MSG);
1002         }
1003     }
1004
1005     /* test 2/3 - run */
1006     if((modus & MODE_NORUN) && (strstr(case_file, "/asm_")
1007                 || strstr(case_file, "\\asm_")
1008                 || (case_file == strstr(case_file, "asm_"))))
1009     {
1010         /* Valgrind doesn't support privileged instructions */
1011         goto no_valgrind;
1012     }else if(strstr(case_file, "/asm_") || strstr(case_file, "\\asm_")
1013             || (case_file == strstr(case_file, "asm_")))
1014     {
1015         /* FIXME asm workaround due to Valgrind bugs (mainly SSE3) */
1016         goto no_valgrind;
1017     }else if(VALGRIND){
1018         bufferLen = strlen(VALGRIND) + strlen(case_file) + 8;
1019         buffer = (char*) malloc(bufferLen);
1020         snprintf(buffer, bufferLen, "%s %s.exe", VALGRIND, case_file);
1021     }else{
1022 no_valgrind:
1023         bufferLen = strlen(case_file) + 8;
1024         buffer = (char*) malloc(bufferLen);
1025         snprintf(buffer, bufferLen, "%s.exe", case_file);
1026     }
1027     printf("%s\n", buffer);
1028     res=crashRun(buffer, &logFile);
1029     testResult = conditionalResult(buffer);
1030     if(testResult){
1031         free(buffer);
1032         return testResult;
1033     }
1034     free(buffer);
1035
1036     /* diagnostic 2/3 */
1037     buffer = loadFile(logFile, &bufferLen);
1038     printf("%.*s\n", (int) bufferLen, buffer);
1039     remove(logFile);
1040     free(logFile);
1041
1042     if(modus & MODE_NORUN){
1043         good_error = checkRuntimeErrorMessage(error_file, error_line,
1044                 buffer);
1045     }else{
1046         good_error = 1;
1047     }
1048
1049 #ifdef REG_EXTENDED
1050     if(((res==EXIT_SUCCESS && (modus & MODE_RUN))
1051             ||(res != EXIT_FAILURE && (modus & MODE_NORUN)))
1052             && gdb_script != NULL)
1053     {
1054         testResult = conditionalResult(buffer);
1055         if(testResult){
1056             return testResult;
1057         }
1058
1059         free(buffer);
1060         good_gdb = 0;
1061         /* test 3/3 - gdb */
1062         gdb_scripter = genTempFileName();
1063         writeFile(gdb_scripter, gdb_script);
1064         bufferLen = strlen(gdb) + strlen(case_file)
1065             + strlen(gdb_scripter) + 20;
1066         buffer = (char*) malloc(bufferLen);
1067         snprintf(buffer, bufferLen, "%s %s.exe < %s",
1068             gdb, case_file, gdb_scripter);
1069         printf("%s\n", buffer);
1070         if(EXIT_SUCCESS==crashRun(buffer, &logFile)){
1071             /* diagnostic 3/3 */
1072             buffer = loadFile(logFile, &bufferLen);
1073             printf("%.*s\n", (int)bufferLen, buffer);
1074             good_gdb = (regexec(gdb_pattern, buffer, 0, NULL, 0)==0);
1075         }
1076         remove(logFile);
1077         remove(gdb_scripter);
1078     }else{
1079         good_gdb = 1;
1080     }
1081 #else
1082     good_gdb = 1;
1083 #endif /* REG_EXTENDED else */
1084
1085     testResult = conditionalResult(buffer);
1086     if(testResult){
1087         return testResult;
1088     }
1089
1090     if(modus & MODE_RUN){
1091         if(hadExecCrash(buffer)){
1092             testResult = RES_ERROR;
1093         }else if((res==EXIT_SUCCESS) && good_gdb){
1094             testResult = RES_PASS;
1095         }else if((res==EXIT_FAILURE) && good_error && good_gdb){
1096             testResult = RES_FAIL;
1097         }else{
1098             testResult = RES_ERROR | (good_error ? 0 : RES_BAD_MSG)
1099                 | (good_gdb ? 0 : RES_BAD_GDB);
1100         }
1101     }else{
1102         if(res==EXIT_SUCCESS){
1103             testResult = RES_XPASS;
1104         }else if(good_error && good_gdb){
1105             testResult = RES_XFAIL;
1106         }else{
1107             testResult = RES_FAIL | (good_error ? 0 : RES_BAD_MSG)
1108                 | (good_gdb ? 0 : RES_BAD_GDB);
1109         }
1110     }
1111     free(buffer);
1112
1113     return testResult;
1114 }
1115
1116 int main(int argc, char* arg[]){
1117
1118     char* compiler;     /* the compiler - from enviroment flag "DMD" */
1119     char* cmd_arg_case; /* additional arguments - from the testcase file */
1120     char* buffer;       /* general purpose buffer */
1121     size_t bufferLen;
1122     int index;
1123     int modus;      /* test modus: RUN NORUN COMPILE NOCOMPILE */
1124     char* case_file;
1125     int case_result;
1126     int torture_result[sizeof(torture)/sizeof(char*)];
1127     char* torture_block_global;
1128     char* torture_block_case;
1129     char* torture_require;
1130     char* error_file;   /* expected sourcefile containing the error */
1131     char* error_line;   /* expected error line */
1132     char* gdb;      /* the debugger - from environment flag "GDB" */
1133     char* gdb_script;   /* gdb command sequence */
1134     char* gdb_pattern_raw;  /* POSIX regexp expected in GDB's output */
1135 #ifdef REG_EXTENDED
1136     regex_t* gdb_pattern;
1137 #endif
1138
1139     compiler    = NULL;
1140     cmd_arg_case    = NULL;
1141     buffer      = NULL;
1142     bufferLen   = 0;
1143     modus       = -1;
1144     case_file   = NULL;
1145     torture_block_global    = NULL;
1146     torture_block_case  = NULL;
1147     torture_require = NULL;
1148     error_file  = NULL;
1149     error_line  = NULL;
1150     gdb     = NULL;
1151     gdb_script  = NULL;
1152     gdb_pattern_raw = NULL;
1153 #ifdef REG_EXTENDED
1154     gdb_pattern     = NULL;
1155 #endif
1156
1157     /* check arguments */
1158     if(argc != 3){
1159 err:
1160         fprintf(stderr, "DStress test executer (revision 1083)\n"
1161             "Copyright by Thomas Kuehne <thomas@kuehne.cn> 2005, 2006\n"
1162             "\n");
1163
1164         if(argc!=0){
1165             fprintf(stderr,
1166                 "%s <run|norun|compile|nocompile> <source>\n",
1167                 arg[0]);
1168         }else{
1169             fprintf(stderr,
1170                 "dstress <run|norun|compile|nocompile>"
1171                 " <source>\n");
1172         }
1173
1174         fprintf(stderr, "\n"
1175         "== eniroment settings (usually $NAME or %%NAME%%)  ==\n"
1176         "* DMD                - compiler (including standard arguments)\n"
1177         "* GDB                - debugger (including standard arguments)\n");
1178         fprintf(stderr, "\n"
1179         "== case setting (line in the case source) ==\n"
1180         "* __DSTRESS_DFLAGS__ - additional compiler arguments\n"
1181         "only evaluated if it is a \"nocompile\" or \"norun\" test:\n"
1182         "* __DSTRESS_ELINE__  - expected source line to throw an error message\n"
1183         "* __DSTRESS_EFILE__  - expected source file to throw an error message\n"
1184         "                       (defaults to the case file)\n");
1185         fprintf(stderr,
1186         "only evaluated if it is a \"run\" or \"norun\" test:\n"
1187         "* __GDB_SCRIPT__     - command sequence to feed to the debugger\n"
1188         "                       (use \\n to encode a line break)\n"
1189         "* __GDB_PATTERN__    - expected regular expression in the debugger's\n"
1190         "                       output\n");
1191         fprintf(stderr, "\n"
1192         "== note ==\n"
1193         "* the current directory is required to contain the sub-directory \"obj\"\n"
1194         "  (used for temporary files)\n"
1195         );
1196         exit(EXIT_FAILURE);
1197     }
1198
1199     modus = 0;
1200     if(0==strncmp(arg[1], TORTURE_PREFIX, strlen(TORTURE_PREFIX))){
1201         modus |= MODE_TORTURE;
1202         arg[1] += strlen(TORTURE_PREFIX);
1203     }
1204     if(0==strcmp(arg[1], "run")){
1205         modus |= MODE_RUN;
1206     }else if(0==strcmp(arg[1], "norun")){
1207         modus |= MODE_NORUN;
1208     }else if(0==strcmp(arg[1], "compile")){
1209         modus |= MODE_COMPILE;
1210     }else if(0==strcmp(arg[1], "nocompile")){
1211         modus |= MODE_NOCOMPILE;
1212     }else{
1213         goto err;
1214     }
1215
1216     /* gen flags */
1217     case_file = cleanPathSeperator(arg[2]);
1218     compiler = getCompiler();
1219     gdb = getGDB();
1220     torture_block_global = getTortureBlock();
1221     buffer = loadFile(case_file, &bufferLen);
1222     bufferLen = 0;
1223
1224     cmd_arg_case =  cleanPathSeperator(getCaseFlag(buffer, "__DSTRESS_DFLAGS__"));
1225     error_line = getCaseFlag(buffer, "__DSTRESS_ELINE__");
1226     error_file =  cleanPathSeperator(getCaseFlag(buffer, "__DSTRESS_EFILE__"));
1227     gdb_script = getCaseFlag(buffer, "__GDB_SCRIPT__");
1228     gdb_pattern_raw = getCaseFlag(buffer, "__GDB_PATTERN__");
1229     torture_block_case = getCaseFlag(buffer, "__DSTRESS_TORTURE_BLOCK__");
1230     torture_require = getCaseFlag(buffer, "__DSTRESS_TORTURE_REQUIRE__");
1231
1232     free(buffer);
1233
1234     /* tmp_dir */
1235     if(!cmd_arg_case || !cmd_arg_case[0]){
1236         tmp_dir = TMP_DIR;
1237     }else{
1238         pid_t pid;
1239         pid = getpid();
1240         bufferLen = strlen(TMP_DIR) + 4 + sizeof(pid_t) * 4;
1241         buffer = (char*) malloc(bufferLen);
1242         snprintf(buffer, bufferLen, "%s/_%X", TMP_DIR, pid);
1243         tmp_dir = cleanPathSeperator(buffer);
1244         if(mkdir(tmp_dir, 0770)){
1245             fprintf(stderr, "failed to create tmp dir: %s (%d, %s)\n",
1246                     tmp_dir, errno, strerror(errno));
1247             return EXIT_FAILURE;
1248         }
1249     }
1250
1251     /* set implicit source file */
1252     if(strcmp(error_line, "")!=0 && strcmp(error_file, "")==0){
1253         error_file=case_file;
1254     }
1255
1256     /* gdb pattern */
1257 #ifdef REG_EXTENDED
1258     if(gdb_pattern_raw!=NULL && gdb_pattern_raw[0]!='\x00'){
1259
1260         gdb_pattern = (regex_t*) malloc(sizeof(regex_t));
1261         if(regcomp(gdb_pattern, gdb_pattern_raw, REG_EXTENDED | REG_NOSUB)){
1262             fprintf(stderr, "failed to compile regular expression:"
1263                 "\n\t%s\n", gdb_pattern_raw);
1264             exit(EXIT_FAILURE);
1265         }else if(gdb_script==NULL){
1266             fprintf(stderr, "GDB pattern without GDB script\n");
1267             exit(EXIT_FAILURE);
1268         }
1269     }else{
1270         gdb_pattern = NULL;
1271     }
1272
1273     /* gdb script */
1274     if(gdb_script!=NULL && gdb_script[0]!='\x00'){
1275         if(gdb_pattern==NULL){
1276             fprintf(stderr, "GDB script without GDB pattern\n");
1277             exit(EXIT_FAILURE);
1278         }
1279         buffer=gdb_script;
1280         for(; *buffer; buffer++){
1281             if(buffer[0]=='\\'){
1282                 if(buffer[1]=='n'){
1283                     buffer[0]=' ';
1284                     buffer[1]='\n';
1285                 }
1286                 buffer++;
1287             }
1288         }
1289
1290         bufferLen = strlen(gdb_script)+11;
1291         buffer = (char*) malloc(bufferLen);
1292         snprintf(buffer, bufferLen, "%s\n\nquit\ny\n\n", gdb_script);
1293         gdb_script=buffer;
1294     }else if(gdb_script){
1295         free(gdb_script);
1296         gdb_script = NULL;
1297     }
1298
1299 #else
1300
1301     if(gdb_script && strlen(gdb_script)){
1302         if(gdb_pattern_raw && strlen(gdb_pattern_raw)){
1303             fprintf(stderr, "WARNING: GDB/regex support inactive\n");
1304         }else{
1305             fprintf(stderr, "GDB script without GDB pattern\n");
1306             exit(EXIT_FAILURE);
1307         }
1308     }else if(gdb_pattern_raw && strlen(gdb_pattern_raw)){
1309         fprintf(stderr, "GDB pattern without GDB script\n");
1310         exit(EXIT_FAILURE);
1311     }
1312
1313 #endif /* REG_EXTENDED else */
1314
1315 #ifdef DEBUG
1316     fprintf(stderr, "case    : \"%s\"\n", case_file);
1317     fprintf(stderr, "compiler: \"%s\"\n", compiler);
1318     fprintf(stderr, "DFLAGS C: \"%s\"\n", cmd_arg_case);
1319     fprintf(stderr, "ELINE   : \"%s\"\n", error_line);
1320     fprintf(stderr, "EFILE   : \"%s\"\n", error_file);
1321 #ifdef REG_EXTENDED
1322     fprintf(stderr, "GDB Scri: \"%s\"\n", gdb_script);
1323     fprintf(stderr, "GDB Patt: \"%s\"\n", gdb_pattern_raw);
1324 #endif
1325     fprintf(stderr, "block G : \"%s\"\n", torture_block_global);
1326     fprintf(stderr, "block C : \"%s\"\n", torture_block_case);
1327     fprintf(stderr, "modus   : %x\n", modus);
1328 #endif
1329
1330
1331     /* let's get serious */
1332 #ifdef USE_WINDOWS
1333     originalStdout = GetStdHandle(STD_OUTPUT_HANDLE);
1334     originalStderr = GetStdHandle(STD_ERROR_HANDLE);
1335 #endif
1336
1337     if(modus & MODE_TORTURE){
1338         if((modus & (MODE_COMPILE | MODE_NOCOMPILE))
1339             && (modus & (MODE_RUN | MODE_NORUN)))
1340         {
1341             fprintf(stderr, "BUG: unhandled torture modus %x\n", modus);
1342             exit(EXIT_FAILURE);
1343         }else if(!(modus & (MODE_COMPILE | MODE_NOCOMPILE | MODE_RUN | MODE_NORUN))){
1344             fprintf(stderr, "BUG: unhandled torture modus %x\n", modus);
1345             exit(EXIT_FAILURE);
1346         }
1347
1348         bufferLen = strlen(torture[(sizeof(torture) / sizeof(char*))-1])
1349             + 128 + strlen(cmd_arg_case) + 3;
1350
1351         if(torture_block_case!=NULL && strlen(torture_block_case)<1){
1352             torture_block_case=NULL;
1353         }
1354
1355         buffer = (char*) malloc(bufferLen);
1356         for(index=0; index < sizeof(torture)/sizeof(char*); index++){
1357             if((torture_block_global && strstr(torture[index], torture_block_global))
1358                 || (torture_block_case && strstr(torture[index], torture_block_case))
1359                 || (torture_require && !strstr(torture[index], torture_require)))
1360             {
1361                 torture_result[index]=RES_UNTESTED;
1362                 continue;
1363             }
1364
1365             buffer[0]=0;
1366             snprintf(buffer, bufferLen, "%s %s", torture[index], cmd_arg_case);
1367
1368             if(modus & (MODE_COMPILE | MODE_NOCOMPILE)){
1369                 torture_result[index] = target_compile(modus,
1370                     compiler, buffer, case_file,
1371                     error_file, error_line);
1372             }else if(modus & (MODE_RUN | MODE_NORUN)){
1373                 torture_result[index] = target_run(modus,
1374                     compiler, buffer, case_file,
1375                     error_file, error_line
1376 #ifdef REG_EXTENDED
1377                     , gdb, gdb_script, gdb_pattern
1378 #endif
1379                 );
1380             }
1381
1382             printf("Torture-Sub-%i/" ZU "-", index+1,
1383                     sizeof(torture)/sizeof(char*));
1384             printResult(torture_result[index], modus, case_file,
1385                     stdout);
1386             printf("--------\n");
1387         }
1388     }else{
1389         if(torture_require && torture_require[0]){
1390             if(!cmd_arg_case || !cmd_arg_case[0]){
1391                 cmd_arg_case = torture_require;
1392             }else{
1393                 bufferLen = strlen(cmd_arg_case);
1394                 bufferLen += strlen(torture_require);
1395                 bufferLen += 2;
1396                 buffer = (char*) malloc(bufferLen);
1397                 snprintf(buffer, bufferLen, "%s %s", cmd_arg_case, torture_require);
1398                 cmd_arg_case = buffer;
1399             }
1400         }
1401         if(modus & (MODE_RUN | MODE_NORUN)){
1402             case_result = target_run(modus, compiler, cmd_arg_case,
1403                     case_file, error_file, error_line
1404 #ifdef REG_EXTENDED
1405                     , gdb, gdb_script, gdb_pattern
1406 #endif
1407                     );
1408         }else if(modus & (MODE_COMPILE | MODE_NOCOMPILE)){
1409             case_result = target_compile(modus, compiler,
1410                     cmd_arg_case, case_file, error_file,
1411                     error_line);
1412         }else{
1413             fprintf(stderr, "BUG: unhandled non-torture modus %x\n", modus);
1414             exit(EXIT_FAILURE);
1415         }
1416
1417         printf("Torture-Sub-1/" ZU "-",
1418             sizeof(torture)/sizeof(char*));
1419         printResult(case_result, modus, case_file, stdout);
1420     }
1421
1422     if(strcmp(TMP_DIR, tmp_dir)){
1423         bufferLen = strlen(tmp_dir);
1424         bufferLen += strlen(RM_DIR);
1425         bufferLen += 2;
1426         buffer = (char*) malloc(bufferLen);
1427         snprintf(buffer, bufferLen, "%s %s", RM_DIR, tmp_dir);
1428         system(buffer);
1429     }
1430     exit(EXIT_SUCCESS);
1431 }
Note: See TracBrowser for help on using the browser.