Create the AHCI branch for Aman's work
[reactos.git] / sdk / tools / regtests2xml / regtests2xml.c
1 /*
2 * Convert debug output from running the regression tests
3 * on ReactOS to an xml document.
4 * Casper S. Hornstrup <chorns@users.sourceforge.net>
5 */
6
7 #include <stdio.h>
8 #include <fcntl.h>
9 #include <sys/stat.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 #ifdef WIN32
14 #include <io.h>
15 #include <dos.h>
16 #else
17 #include <sys/io.h>
18 #include <errno.h>
19 #include <sys/types.h>
20 #include <dirent.h>
21 #include <unistd.h>
22 #endif
23 #include <ctype.h>
24 #ifndef WIN32
25 #ifndef MAX_PATH
26 #define MAX_PATH 260
27 #endif
28 #define DIR_SEPARATOR_CHAR '/'
29 #define DIR_SEPARATOR_STRING "/"
30 #else
31 #define DIR_SEPARATOR_CHAR '\\'
32 #define DIR_SEPARATOR_STRING "\\"
33 #endif
34
35 typedef struct _TEST_RESULT_INFO
36 {
37 struct _TEST_RESULT_INFO *next;
38 char testname[100];
39 char result[200];
40 int succeeded; /* 0 = failed, 1 = succeeded */
41 } TEST_RESULT_INFO, *PTEST_RESULT_INFO;
42
43
44 static FILE *out;
45 static FILE *file_handle = NULL;
46 static char *file_buffer = NULL;
47 static unsigned int file_size = 0;
48 static int file_pointer = 0;
49 static PTEST_RESULT_INFO test_result_info_list = NULL;
50
51
52 static char*
53 convert_path(char* origpath)
54 {
55 char* newpath;
56 int i;
57
58 newpath = strdup(origpath);
59
60 i = 0;
61 while (newpath[i] != 0)
62 {
63 #ifndef WIN32
64 if (newpath[i] == '\\')
65 {
66 newpath[i] = '/';
67 }
68 #else
69 #ifdef WIN32
70 if (newpath[i] == '/')
71 {
72 newpath[i] = '\\';
73 }
74 #endif
75 #endif
76 i++;
77 }
78 return(newpath);
79 }
80
81 static void
82 write_line(char *line)
83 {
84 char buf[200];
85
86 memset(buf, 0, sizeof(buf));
87 strcpy(buf, line);
88 /* Terminate the line */
89 buf[strlen(buf)] = '\r';
90 buf[strlen(buf)] = '\n';
91
92 (void)fwrite(&buf[0], 1, strlen(buf), out);
93 }
94
95
96 static void
97 read_file(char *filename)
98 {
99 file_handle = fopen(filename, "rb");
100 if (file_handle == NULL)
101 {
102 printf("Can't open %s\n", filename);
103 exit(1);
104 }
105
106 // Get the size of the file
107 fseek(file_handle, 0, SEEK_END);
108 file_size = ftell(file_handle);
109
110 // Load it all into memory
111 file_buffer = malloc(file_size);
112 if (file_buffer == NULL)
113 {
114 fclose(file_handle);
115 printf("Out of memory\n");
116 exit(1);
117 }
118 fseek(file_handle, 0, SEEK_SET);
119 if (file_size > 0)
120 {
121 if (fread (file_buffer, 1, file_size, file_handle) < 1)
122 {
123 fclose(file_handle);
124 printf("Read error in file %s\n", filename);
125 exit(1);
126 }
127 }
128
129 file_pointer = 0;
130 }
131
132 static void
133 close_file()
134 {
135 free(file_buffer);
136 file_buffer = NULL;
137 fclose(file_handle);
138 file_handle = NULL;
139 file_pointer = 0;
140 }
141
142 static int
143 is_whitespace(char ch)
144 {
145 if (ch == ' ')
146 {
147 return 1;
148 }
149 if (ch == '\t')
150 {
151 return 1;
152 }
153 return 0;
154 }
155
156 static int
157 is_eol_char(char ch)
158 {
159 if (ch == '\r')
160 {
161 return 1;
162 }
163 if (ch == '\n')
164 {
165 return 1;
166 }
167 return 0;
168 }
169
170 static void
171 skip_line()
172 {
173 while ((file_pointer < file_size) && (!is_eol_char(file_buffer[file_pointer])))
174 {
175 file_pointer++;
176 }
177 if ((file_pointer < file_size) && (is_eol_char(file_buffer[file_pointer])))
178 {
179 file_pointer++;
180 if ((file_pointer < file_size) && (file_buffer[file_pointer] == '\n'))
181 {
182 file_pointer++;
183 }
184 }
185 }
186
187 static void
188 skip_whitespace()
189 {
190 while ((file_pointer < file_size) && !is_eol_char(file_buffer[file_pointer])
191 && is_whitespace(file_buffer[file_pointer]))
192 {
193 file_pointer++;
194 }
195 }
196
197 static int
198 skip_to_next_test()
199 {
200 static char test_marker[] = "ROSREGTEST:";
201 int found_test = 0;
202
203 while ((file_pointer < file_size) && (!found_test))
204 {
205 skip_whitespace();
206 found_test = 1;
207 int i = 0;
208 while (1)
209 {
210 if (i >= strlen(test_marker))
211 {
212 break;
213 }
214 if (is_eol_char(file_buffer[file_pointer]))
215 {
216 found_test = 0;
217 break;
218 }
219 if (file_buffer[file_pointer] != test_marker[i])
220 {
221 found_test = 0;
222 break;
223 }
224 file_pointer++;
225 i++;
226 }
227 if (!found_test)
228 {
229 skip_line();
230 }
231 }
232 return found_test;
233 }
234
235 static int
236 read_until(char ch, char* buf)
237 {
238 int start = file_pointer;
239 while ((file_pointer < file_size))
240 {
241 if (file_buffer[file_pointer] == ch)
242 {
243 strncpy(buf, &file_buffer[start], file_pointer - start);
244 buf[file_pointer - start] = 0;
245 return 1;
246 }
247 file_pointer++;
248 }
249 return 0;
250 }
251
252 static int
253 read_until_end(char* buf)
254 {
255 int start = file_pointer;
256 while ((file_pointer < file_size))
257 {
258 if (is_eol_char(file_buffer[file_pointer]))
259 {
260 strncpy(buf, &file_buffer[start], file_pointer - start);
261 buf[file_pointer - start] = 0;
262 skip_line();
263 return 1;
264 }
265 file_pointer++;
266 }
267 return 0;
268 }
269
270 static void
271 parse_file(char *filename)
272 {
273 PTEST_RESULT_INFO test_result_info;
274
275 read_file(filename);
276
277 do
278 {
279 if (!skip_to_next_test())
280 {
281 break;
282 }
283
284 /*
285 * FORMAT:
286 * [ROSREGTEST:][space][|][<testname>][|][space][Status:][space][<result of running test>]
287 */
288
289 test_result_info = malloc(sizeof(TEST_RESULT_INFO));
290 if (test_result_info == NULL)
291 {
292 printf("Out of memory\n");
293 exit(1);
294 }
295
296 /* Skip whitespaces */
297 skip_whitespace();
298
299 /* [|] */
300 file_pointer++;
301
302 /* <testname> */
303 read_until(')', test_result_info->testname);
304
305 /* [|] */
306 file_pointer++;
307
308 /* [space] */
309 file_pointer++;
310
311 /* Status: */
312 file_pointer += 7;
313
314 /* [space] */
315 file_pointer++;
316
317 /* <result of running test> */
318 read_until_end(test_result_info->result);
319
320 if (strncmp(test_result_info->result, "Success", 7) == 0)
321 {
322 test_result_info->succeeded = 1;
323 }
324 else
325 {
326 test_result_info->succeeded = 0;
327 }
328
329 test_result_info->next = test_result_info_list;
330 test_result_info_list = test_result_info;
331 } while (1);
332
333 close_file();
334 }
335
336 static void
337 generate_xml()
338 {
339 PTEST_RESULT_INFO test_result_info;
340 char buf[200];
341 int success_rate;
342 int succeeded_total;
343 int failed_total;
344
345 succeeded_total = 0;
346 failed_total = 0;
347
348 test_result_info = test_result_info_list;
349 while (test_result_info != NULL)
350 {
351 if (test_result_info->succeeded)
352 {
353 succeeded_total++;
354 }
355 else
356 {
357 failed_total++;
358 }
359 test_result_info = test_result_info->next;
360 }
361
362 if (succeeded_total + failed_total > 0)
363 {
364 success_rate = ((succeeded_total) * 100) / (succeeded_total + failed_total);
365 }
366 else
367 {
368 success_rate = 100;
369 }
370
371 write_line("<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>");
372 write_line("");
373
374 sprintf(buf, "<testresults success_rate=\"%d\" succeeded_total=\"%d\" failed_total=\"%d\">",
375 success_rate, succeeded_total, failed_total);
376 write_line(buf);
377
378 if (test_result_info_list != NULL)
379 {
380 test_result_info = test_result_info_list;
381 while (test_result_info != NULL)
382 {
383 sprintf(buf, "<testresult testname=\"%s\" succeeded=\"%s\" result=\"%s\">",
384 test_result_info->testname,
385 test_result_info->succeeded == 1 ? "true" : "false",
386 test_result_info->result);
387 write_line(buf);
388 write_line("</testresult>");
389 test_result_info = test_result_info->next;
390 }
391 }
392
393 write_line("</testresults>");
394 }
395
396 static char HELP[] =
397 "REGTESTS2XML input-filename output-filename\n"
398 "\n"
399 " input-filename File containing output from running regression tests\n"
400 " output-filename File to create\n";
401
402 int main(int argc, char **argv)
403 {
404 char *input_file;
405 char *output_file;
406
407 if (argc < 3)
408 {
409 puts(HELP);
410 return 1;
411 }
412
413 input_file = convert_path(argv[1]);
414 if (input_file[0] == 0)
415 {
416 free(input_file);
417 printf("Missing input-filename\n");
418 return 1;
419 }
420
421 output_file = convert_path(argv[2]);
422 if (output_file[0] == 0)
423 {
424 free(output_file);
425 free(input_file);
426 printf("Missing output-filename\n");
427 return 1;
428 }
429
430 out = fopen(output_file, "wb");
431 if (out == NULL)
432 {
433 free(input_file);
434 free(output_file);
435 printf("Cannot open output file");
436 return 1;
437 }
438
439 parse_file(input_file);
440
441 generate_xml();
442
443 free(input_file);
444 free(output_file);
445 fclose(out);
446
447 return 0;
448 }