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 } 449