reactos/sdk/tools/regtests2xml/regtests2xml.c

449 lines
8.2 KiB
C

/*
* Convert debug output from running the regression tests
* on ReactOS to an xml document.
* Casper S. Hornstrup <chorns@users.sourceforge.net>
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <io.h>
#include <dos.h>
#else
#include <sys/io.h>
#include <errno.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#endif
#include <ctype.h>
#ifndef WIN32
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
#define DIR_SEPARATOR_CHAR '/'
#define DIR_SEPARATOR_STRING "/"
#else
#define DIR_SEPARATOR_CHAR '\\'
#define DIR_SEPARATOR_STRING "\\"
#endif
typedef struct _TEST_RESULT_INFO
{
struct _TEST_RESULT_INFO *next;
char testname[100];
char result[200];
int succeeded; /* 0 = failed, 1 = succeeded */
} TEST_RESULT_INFO, *PTEST_RESULT_INFO;
static FILE *out;
static FILE *file_handle = NULL;
static char *file_buffer = NULL;
static unsigned int file_size = 0;
static int file_pointer = 0;
static PTEST_RESULT_INFO test_result_info_list = NULL;
static char*
convert_path(char* origpath)
{
char* newpath;
int i;
newpath = strdup(origpath);
i = 0;
while (newpath[i] != 0)
{
#ifndef WIN32
if (newpath[i] == '\\')
{
newpath[i] = '/';
}
#else
#ifdef WIN32
if (newpath[i] == '/')
{
newpath[i] = '\\';
}
#endif
#endif
i++;
}
return(newpath);
}
static void
write_line(char *line)
{
char buf[200];
memset(buf, 0, sizeof(buf));
strcpy(buf, line);
/* Terminate the line */
buf[strlen(buf)] = '\r';
buf[strlen(buf)] = '\n';
(void)fwrite(&buf[0], 1, strlen(buf), out);
}
static void
read_file(char *filename)
{
file_handle = fopen(filename, "rb");
if (file_handle == NULL)
{
printf("Can't open %s\n", filename);
exit(1);
}
// Get the size of the file
fseek(file_handle, 0, SEEK_END);
file_size = ftell(file_handle);
// Load it all into memory
file_buffer = malloc(file_size);
if (file_buffer == NULL)
{
fclose(file_handle);
printf("Out of memory\n");
exit(1);
}
fseek(file_handle, 0, SEEK_SET);
if (file_size > 0)
{
if (fread (file_buffer, 1, file_size, file_handle) < 1)
{
fclose(file_handle);
printf("Read error in file %s\n", filename);
exit(1);
}
}
file_pointer = 0;
}
static void
close_file()
{
free(file_buffer);
file_buffer = NULL;
fclose(file_handle);
file_handle = NULL;
file_pointer = 0;
}
static int
is_whitespace(char ch)
{
if (ch == ' ')
{
return 1;
}
if (ch == '\t')
{
return 1;
}
return 0;
}
static int
is_eol_char(char ch)
{
if (ch == '\r')
{
return 1;
}
if (ch == '\n')
{
return 1;
}
return 0;
}
static void
skip_line()
{
while ((file_pointer < file_size) && (!is_eol_char(file_buffer[file_pointer])))
{
file_pointer++;
}
if ((file_pointer < file_size) && (is_eol_char(file_buffer[file_pointer])))
{
file_pointer++;
if ((file_pointer < file_size) && (file_buffer[file_pointer] == '\n'))
{
file_pointer++;
}
}
}
static void
skip_whitespace()
{
while ((file_pointer < file_size) && !is_eol_char(file_buffer[file_pointer])
&& is_whitespace(file_buffer[file_pointer]))
{
file_pointer++;
}
}
static int
skip_to_next_test()
{
static char test_marker[] = "ROSREGTEST:";
int found_test = 0;
while ((file_pointer < file_size) && (!found_test))
{
skip_whitespace();
found_test = 1;
int i = 0;
while (1)
{
if (i >= strlen(test_marker))
{
break;
}
if (is_eol_char(file_buffer[file_pointer]))
{
found_test = 0;
break;
}
if (file_buffer[file_pointer] != test_marker[i])
{
found_test = 0;
break;
}
file_pointer++;
i++;
}
if (!found_test)
{
skip_line();
}
}
return found_test;
}
static int
read_until(char ch, char* buf)
{
int start = file_pointer;
while ((file_pointer < file_size))
{
if (file_buffer[file_pointer] == ch)
{
strncpy(buf, &file_buffer[start], file_pointer - start);
buf[file_pointer - start] = 0;
return 1;
}
file_pointer++;
}
return 0;
}
static int
read_until_end(char* buf)
{
int start = file_pointer;
while ((file_pointer < file_size))
{
if (is_eol_char(file_buffer[file_pointer]))
{
strncpy(buf, &file_buffer[start], file_pointer - start);
buf[file_pointer - start] = 0;
skip_line();
return 1;
}
file_pointer++;
}
return 0;
}
static void
parse_file(char *filename)
{
PTEST_RESULT_INFO test_result_info;
read_file(filename);
do
{
if (!skip_to_next_test())
{
break;
}
/*
* FORMAT:
* [ROSREGTEST:][space][|][<testname>][|][space][Status:][space][<result of running test>]
*/
test_result_info = malloc(sizeof(TEST_RESULT_INFO));
if (test_result_info == NULL)
{
printf("Out of memory\n");
exit(1);
}
/* Skip whitespaces */
skip_whitespace();
/* [|] */
file_pointer++;
/* <testname> */
read_until(')', test_result_info->testname);
/* [|] */
file_pointer++;
/* [space] */
file_pointer++;
/* Status: */
file_pointer += 7;
/* [space] */
file_pointer++;
/* <result of running test> */
read_until_end(test_result_info->result);
if (strncmp(test_result_info->result, "Success", 7) == 0)
{
test_result_info->succeeded = 1;
}
else
{
test_result_info->succeeded = 0;
}
test_result_info->next = test_result_info_list;
test_result_info_list = test_result_info;
} while (1);
close_file();
}
static void
generate_xml()
{
PTEST_RESULT_INFO test_result_info;
char buf[200];
int success_rate;
int succeeded_total;
int failed_total;
succeeded_total = 0;
failed_total = 0;
test_result_info = test_result_info_list;
while (test_result_info != NULL)
{
if (test_result_info->succeeded)
{
succeeded_total++;
}
else
{
failed_total++;
}
test_result_info = test_result_info->next;
}
if (succeeded_total + failed_total > 0)
{
success_rate = ((succeeded_total) * 100) / (succeeded_total + failed_total);
}
else
{
success_rate = 100;
}
write_line("<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>");
write_line("");
sprintf(buf, "<testresults success_rate=\"%d\" succeeded_total=\"%d\" failed_total=\"%d\">",
success_rate, succeeded_total, failed_total);
write_line(buf);
if (test_result_info_list != NULL)
{
test_result_info = test_result_info_list;
while (test_result_info != NULL)
{
sprintf(buf, "<testresult testname=\"%s\" succeeded=\"%s\" result=\"%s\">",
test_result_info->testname,
test_result_info->succeeded == 1 ? "true" : "false",
test_result_info->result);
write_line(buf);
write_line("</testresult>");
test_result_info = test_result_info->next;
}
}
write_line("</testresults>");
}
static char HELP[] =
"REGTESTS2XML input-filename output-filename\n"
"\n"
" input-filename File containing output from running regression tests\n"
" output-filename File to create\n";
int main(int argc, char **argv)
{
char *input_file;
char *output_file;
if (argc < 3)
{
puts(HELP);
return 1;
}
input_file = convert_path(argv[1]);
if (input_file[0] == 0)
{
free(input_file);
printf("Missing input-filename\n");
return 1;
}
output_file = convert_path(argv[2]);
if (output_file[0] == 0)
{
free(output_file);
free(input_file);
printf("Missing output-filename\n");
return 1;
}
out = fopen(output_file, "wb");
if (out == NULL)
{
free(input_file);
free(output_file);
printf("Cannot open output file");
return 1;
}
parse_file(input_file);
generate_xml();
free(input_file);
free(output_file);
fclose(out);
return 0;
}