root/test.d

Revision 124:731ab26f07bf, 5.7 kB (checked in by korDen, 2 years ago)

testing tool added

Line 
1 import std.stdio;
2 import std.utf;
3 import std.file;
4 import std.path;
5 import std.algorithm;
6 import std.string;
7 import std.process;
8 import core.stdc.ctype;
9 import std.c.windows.windows;
10
11 string compiler = "dmd";
12
13 class Test
14 {
15     enum EXTRA_SOURCES = "EXTRA_SOURCES";
16     enum COMPILE_SEPARATELY = "COMPILE_SEPARATELY";
17     enum PERMUTE_ARGS = "PERMUTE_ARGS";
18     enum REQUIRED_ARGS = "REQUIRED_ARGS";
19     enum POST_SCRIPT = "POST_SCRIPT";
20     enum EXECUTE_ARGS = "EXECUTE_ARGS";
21    
22     this(string path, string outputDir)
23     {
24         this.outputDir = outputDir;
25         this.baseDir = dirname(path);
26        
27         this.baseName = getBaseName(path);
28         this.name = getName(baseName);
29        
30         this.fileNames ~= baseName;
31        
32         auto file = File(path);
33         while (true) {
34             auto line = file.readln();
35             if (!line.startsWith("// ")) {
36                 break;
37             }
38            
39             line = trim(line[3..$]);
40             if (line.startsWith(EXTRA_SOURCES)) {
41                 fileNames ~= split(line[EXTRA_SOURCES.length + 2..$], " ");
42             } else if (line.startsWith(COMPILE_SEPARATELY)) {
43                 compileSeparately = true;
44             } else if (line.startsWith(EXECUTE_ARGS)) {
45                 executeArgs = line[EXECUTE_ARGS.length + 2..$];
46             } else if (line.startsWith(PERMUTE_ARGS)) {
47                 // ignore for now
48             } else if (line.startsWith(REQUIRED_ARGS)) {
49                 requiredArgs = line[REQUIRED_ARGS.length + 2..$];
50             } else if (line.startsWith(POST_SCRIPT)) {
51                 // ignore for now
52             } else {
53                 continue;
54             }
55         }
56     }
57    
58     private string prefix()
59     {
60         return std.string.format(compiler ~ " -od%s -I%s %s", outputDir, baseDir, requiredArgs);
61     }
62    
63     private string csuffix(string fileName)
64     {
65         // output to console
66         return ""; //std.string.format(" > %s\\%s.clog", outputDir, getBaseName(fileName));
67     }
68    
69     private string lsuffix(string fileName)
70     {
71         return std.string.format(" > %s\\%s.llog", outputDir, getBaseName(fileName));
72     }
73    
74     private string output()
75     {
76         return std.string.format(" -of%s\\%s.exe", outputDir, name);
77     }
78    
79     private void execute(string command)
80     {
81         system(command);
82     }
83    
84     void compile()
85     {
86         if (compileSeparately) {
87             string link_command = compiler ~ output();
88             foreach (fileName; fileNames) {
89                 string compile_command = prefix();
90                
91                 compile_command ~= std.string.format(" %s\\%s -c", baseDir, fileName);
92                 compile_command ~= csuffix(fileName);
93                
94                 execute(compile_command);
95                 link_command ~= std.string.format(" %s\\%s.obj", outputDir, getName(getBaseName(fileName)));
96             }
97            
98             link_command ~= lsuffix(baseName);
99            
100             execute(link_command);         
101         } else {
102             string compile_command = prefix();
103             foreach (fileName; fileNames) {
104                 compile_command ~= std.string.format(" %s\\%s", baseDir, fileName);
105             }
106            
107             compile_command ~= output();
108             compile_command ~= csuffix(baseName);
109            
110             execute(compile_command);
111         }
112     }
113    
114     private string[] fileNames;
115    
116     private string name;
117     private string baseName;
118     private string outputDir;
119     private string baseDir;
120     private string requiredArgs;
121     private string executeArgs;
122    
123     private bool compileSeparately = false;
124 }
125
126 class RunnableTest : Test
127 {
128     this(string path, string outputDir)
129     {
130         super(path, outputDir);
131     }
132    
133     void run()
134     {
135         string run_command = std.string.format("%s\\%s.exe %s > %s\\%s.exe.rlog", outputDir, name, executeArgs, outputDir, name);
136         execute(run_command);
137     }
138 }
139
140 int main(string[] args)
141 {
142     auto runnable_tests = wildcard("runnable/*.d"/*, "runnable/*.html", "runnable/*.sh"*/);
143     auto runnable_test_results = map!q{"result/" ~ a ~ ".out"}(runnable_tests);
144
145     auto outputDir = "result";
146    
147     if (args.length >= 2) {
148         compiler = args[1];
149     } else {
150         // compiler = "dmd"; // value by default
151     }
152
153     foreach (fileName; runnable_tests) {
154         //fileName = "runnable\\a18.d";
155         writeln("testing ", fileName);
156         auto test = new RunnableTest(fileName, outputDir);
157         test.compile();
158 //      test.run();
159 //      break;
160     }
161    
162     return 0;
163 }
164
165 string[] wildcard(string[] paths...)
166 {
167     string[] fileNames;
168    
169     foreach (path; paths) {
170         filter(path, (string fileName) { fileNames ~= fileName; return true; });
171     }
172    
173     return fileNames;
174 }
175
176 string trimLeft(string s)
177 {
178     for (int i = 0; i < s.length; ++i) {
179         if (!isspace(s[i])) {
180             return s[i..$];
181         }
182     }
183    
184     return null;
185 }
186
187 string trimRight(string s)
188 {
189     for (int i = s.length - 1; i >= 0; --i) {
190         if (!isspace(s[i])) {
191             return s[0..i + 1];
192         }
193     }
194    
195     return null;
196 }
197
198 string trim(string s)
199 {
200     return trimLeft(trimRight(s));
201 }
202
203 version(Windows) void filter(string pattern, bool delegate(string fileName) callback)
204 {
205     WIN32_FIND_DATAW fileinfo;
206
207     auto h = FindFirstFileW(std.utf.toUTF16z(pattern), &fileinfo);
208     if (h == INVALID_HANDLE_VALUE)
209         return;
210
211     auto path = dirname(pattern);
212
213     do
214     {
215         // Skip "." and ".."
216         auto name = fileinfo.cFileName.ptr;
217         if (name[0] == '.' && (name[1] == 0 || name[1] == '.'))
218             continue;
219
220         size_t clength = std.string.wcslen(fileinfo.cFileName.ptr);
221         auto fileName = std.path.join(path, std.utf.toUTF8(fileinfo.cFileName[0 .. clength]));
222        
223         if (!callback(fileName)) {
224             break;
225         }
226     } while (FindNextFileW(h, &fileinfo) != FALSE);
227    
228     FindClose(h);
229 }
230
231 string getBaseName(string fullname, string extension = null)
232 {
233     auto i = fullname.length;
234     for (; i > 0; i--)
235     {
236         version(Windows)
237         {
238             if (fullname[i - 1] == ':' || fullname[i - 1] == '\\' || fullname[i - 1] == '/')
239                 break;
240         }
241         else version(Posix)
242         {
243             if (fullname[i - 1] == '/')
244                 break;
245         }
246         else
247         {
248             static assert(0);
249         }
250     }
251     return chomp(fullname[i .. fullname.length],
252             extension.length ? extension : "");
253 }
Note: See TracBrowser for help on using the browser.