test/harness/testcaseio.c
author ali <ali@juiblex.co.uk>
Fri Oct 25 11:15:18 2013 +0100 (2013-10-25)
changeset 102 ff0aa9b1397a
parent 101 f44c530f80da
permissions -rw-r--r--
Fix bug #14: Add a configuration file
     1 #include <stdlib.h>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <glib.h>
     5 #include <bl/bl.h>
     6 #include "testcaseparser.h"
     7 #include "testcaseinput.h"
     8 #include "testcaseoutput.h"
     9 #include "testcaseio.h"
    10 #include "warningsparser.h"
    11 
    12 /*
    13  * Read a testcase in from a file.
    14  * On error, print a suitable message using g_printerr and return NULL.
    15  * The returned testcase should be freed with testcase_free().
    16  */
    17 Testcase *testcase_parse_file(const char *filename)
    18 {
    19     Testcase *testcase;
    20     TestcaseParser *parser;
    21     TestcaseInput *input=NULL;
    22     GMarkupParseContext *context;
    23     GError *err=NULL;
    24     char *s,*arg;
    25     const char *tag,*text;
    26     gboolean found_tag=FALSE,newlines_set=FALSE;
    27     parser=testcase_parser_new_from_file(filename);
    28     if (!parser)
    29 	return NULL;
    30     if (!*testcase_parser_get_flag(parser))
    31     {
    32 	g_printerr("%s: Not a valid testcase (flag)\n",filename);
    33 	testcase_parser_free(parser);
    34 	return NULL;
    35     }
    36     testcase=g_new0(Testcase,1);
    37     testcase->basename=g_path_get_basename(filename);
    38     s=strrchr(testcase->basename,'.');
    39     if (s)
    40 	*s='\0';
    41     while(testcase_parser_get_next_tag(parser,&tag,&text))
    42     {
    43 	if (!input && !strcmp(tag,"INPUT"))
    44 	    input=testcase_input_new("TEST-XXXXXX",text);
    45 	else if (g_str_has_prefix(tag,"INPUT(") && tag[strlen(tag)-1]==')')
    46 	{
    47 	    arg=g_strndup(tag+6,strlen(tag)-7);
    48 	    s=g_path_get_dirname(arg);
    49 	    if (strcmp(s,"."))
    50 	    {
    51 		/*
    52 		 * Otherwise it would be possible to overwrite an arbitary
    53 		 * file on somebody's computer by getting them to run a
    54 		 * testcase!
    55 		 */
    56 		g_printerr(
    57 		  "%s: Input files may not have a directory component\n",arg);
    58 		g_free(s);
    59 		g_free(arg);
    60 		testcase_free(testcase);
    61 		testcase_parser_free(parser);
    62 		return NULL;
    63 	    }
    64 	    g_free(s);
    65 	    testcase->inputs=g_slist_prepend(testcase->inputs,
    66 	      testcase_input_new(arg,text));
    67 	    if (!strstr(arg,"XXXXXX"))
    68 		testcase->flags|=TESTCASE_TMP_DIR;
    69 	    g_free(arg);
    70 	}
    71 	else if (!testcase->expected && !testcase->warnings &&
    72 	  !strcmp(tag,"EXPECTED"))
    73 	    testcase->expected=g_strdup(text);
    74 	else if (g_str_has_prefix(tag,"EXPECTED(") && tag[strlen(tag)-1]==')')
    75 	{
    76 	    arg=g_strndup(tag+9,strlen(tag)-10);
    77 	    s=g_path_get_dirname(arg);
    78 	    if (strcmp(s,"."))
    79 	    {
    80 		g_printerr("%s: Expected files may not have a "
    81 		  "directory component\n",arg);
    82 		g_free(s);
    83 		g_free(arg);
    84 		testcase_free(testcase);
    85 		testcase_parser_free(parser);
    86 		return NULL;
    87 	    }
    88 	    g_free(s);
    89 	    testcase->outputs=g_slist_prepend(testcase->outputs,
    90 	      testcase_output_new(arg,text));
    91 	    g_free(arg);
    92 	}
    93 	else if (!testcase->expected && !testcase->warnings &&
    94 	  !strcmp(tag,"WARNINGS"))
    95 	{
    96 	    context=warnings_parse_context_new(testcase);
    97 	    if (!g_markup_parse_context_parse(context,text,-1,&err) ||
    98 	      !g_markup_parse_context_end_parse(context,&err))
    99 	    {
   100 		g_markup_parse_context_free(context);
   101 		g_printerr("%s\n",err->message);
   102 		g_clear_error(&err);
   103 		testcase_free(testcase);
   104 		testcase_parser_free(parser);
   105 		return NULL;
   106 	    }
   107 	    g_markup_parse_context_free(context);
   108 	}
   109 	else if (!testcase->encoding && !strcmp(tag,"ENCODING"))
   110 	    testcase->encoding=g_strchomp(g_strdup(text));
   111 	else if (!newlines_set && !strcmp(tag,"NEWLINES"))
   112 	{
   113 	    newlines_set=TRUE;
   114 	    s=g_strdup(text);
   115 	    g_strchomp(s);
   116 	    if (!strcmp(s,"LF"))
   117 		testcase->flags|=TESTCASE_UNIX_NEWLINES;
   118 	    else if (!strcmp(s,"CR"))
   119 		testcase->flags|=TESTCASE_OS9_NEWLINES;
   120 	    else if (strcmp(s,"CRLF"))
   121 	    {
   122 		g_printerr(
   123 		  "%s: Unrecognised style for newlines. Try CR or LF.\n",s);
   124 		g_free(s);
   125 		testcase_free(testcase);
   126 		testcase_parser_free(parser);
   127 		return NULL;
   128 	    }
   129 	    g_free(s);
   130 	}
   131 	else if (!testcase->options && !strcmp(tag,"OPTIONS"))
   132 	{
   133 	    testcase->options=g_strsplit(text,"\n",0);
   134 	    if (testcase->options && g_strv_length(testcase->options)>0)
   135 	    {
   136 		g_free(testcase->options[g_strv_length(testcase->options)-1]);
   137 		testcase->options[g_strv_length(testcase->options)-1]=NULL;
   138 	    }
   139 	}
   140 	else
   141 	{
   142 	    g_printerr("%s: Not a valid testcase (%s)\n",filename,tag);
   143 	    testcase_free(testcase);
   144 	    testcase_parser_free(parser);
   145 	    return NULL;
   146 	}
   147 	found_tag=TRUE;
   148     }
   149     if (!testcase_parser_at_eof(parser))
   150     {
   151 	if (found_tag)
   152 	    g_printerr("%s: Not a valid testcase (garbage at end)\n",
   153 	      filename);
   154 	else
   155 	    g_printerr("%s: Not a valid testcase (no valid tags)\n",
   156 	      filename);
   157 	testcase_free(testcase);
   158 	testcase_parser_free(parser);
   159 	return NULL;
   160     }
   161     if (!input)
   162 	input=testcase_input_new("TEST-XXXXXX",NULL);
   163     testcase->inputs=g_slist_prepend(testcase->inputs,input);
   164     testcase_parser_free(parser);
   165     return testcase;
   166 }