ReactOS  0.4.14-dev-50-g13bb5e2
regtests2xml.c
Go to the documentation of this file.
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 {
38  char testname[100];
39  char result[200];
40  int succeeded; /* 0 = failed, 1 = succeeded */
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;
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
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
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
109 
110  // Load it all into memory
112  if (file_buffer == NULL)
113  {
115  printf("Out of memory\n");
116  exit(1);
117  }
119  if (file_size > 0)
120  {
121  if (fread (file_buffer, 1, file_size, file_handle) < 1)
122  {
124  printf("Read error in file %s\n", filename);
125  exit(1);
126  }
127  }
128 
129  file_pointer = 0;
130 }
131 
132 static void
134 {
135  free(file_buffer);
136  file_buffer = NULL;
138  file_handle = NULL;
139  file_pointer = 0;
140 }
141 
142 static int
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
172 {
174  {
175  file_pointer++;
176  }
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
189 {
192  {
193  file_pointer++;
194  }
195 }
196 
197 static int
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  }
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  {
244  buf[file_pointer - start] = 0;
245  return 1;
246  }
247  file_pointer++;
248  }
249  return 0;
250 }
251 
252 static int
254 {
255  int start = file_pointer;
256  while ((file_pointer < file_size))
257  {
259  {
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
272 {
273  PTEST_RESULT_INFO test_result_info;
274 
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
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 
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 }
static int argc
Definition: ServiceArgs.c:12
static int file_pointer
Definition: regtests2xml.c:48
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static unsigned int file_size
Definition: regtests2xml.c:47
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define free
Definition: debug_ros.c:5
static int read_until_end(char *buf)
Definition: regtests2xml.c:253
struct _TEST_RESULT_INFO * next
Definition: regtests2xml.c:37
static void write_line(char *line)
Definition: regtests2xml.c:82
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
#define argv
Definition: mplay32.c:18
const char * filename
Definition: ioapi.h:135
static void generate_xml()
Definition: regtests2xml.c:337
struct _TEST_RESULT_INFO TEST_RESULT_INFO
static void skip_whitespace()
Definition: regtests2xml.c:188
#define sprintf(buf, format,...)
Definition: sprintf.c:55
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
smooth NULL
Definition: ftsmooth.c:416
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
static int read_until(char ch, char *buf)
Definition: regtests2xml.c:236
Definition: parser.c:48
static char * file_buffer
Definition: regtests2xml.c:46
static void read_file(char *filename)
Definition: regtests2xml.c:97
#define SEEK_SET
Definition: jmemansi.c:26
static PTEST_RESULT_INFO test_result_info_list
Definition: regtests2xml.c:49
static void parse_file(char *filename)
Definition: regtests2xml.c:271
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static FILE * out
Definition: regtests2xml.c:44
struct _TEST_RESULT_INFO * PTEST_RESULT_INFO
int main(int argc, char **argv)
Definition: regtests2xml.c:402
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
int puts(const char *string)
Definition: crtsupp.c:23
char testname[100]
Definition: regtests2xml.c:38
static int skip_to_next_test()
Definition: regtests2xml.c:198
static char * convert_path(char *origpath)
Definition: regtests2xml.c:53
GLuint start
Definition: gl.h:1545
static int is_eol_char(char ch)
Definition: regtests2xml.c:157
static void skip_line()
Definition: regtests2xml.c:171
char result[200]
Definition: regtests2xml.c:39
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
#define SEEK_END
Definition: cabinet.c:27
#define malloc
Definition: debug_ros.c:4
void exit(int exitcode)
Definition: _exit.c:33
static void close_file()
Definition: regtests2xml.c:133
static int is_whitespace(char ch)
Definition: regtests2xml.c:143
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
static FILE * file_handle
Definition: regtests2xml.c:45
static char HELP[]
Definition: regtests2xml.c:396
#define printf
Definition: config.h:203