1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/test/harness/warningsparser.c Fri Sep 06 22:35:23 2013 +0100
1.3 @@ -0,0 +1,244 @@
1.4 +#include <stdlib.h>
1.5 +#include <string.h>
1.6 +#include <glib.h>
1.7 +#include "testcase.h"
1.8 +#include "warningsparser.h"
1.9 +
1.10 +/*
1.11 + * A GMarkupParser for the contents of a WARNINGS tag.
1.12 + */
1.13 +
1.14 +typedef struct {
1.15 + Testcase *testcase;
1.16 + TestcaseWarning *warning;
1.17 + TestcaseLocation *location;
1.18 + enum {
1.19 + WARNINGS_INIT,
1.20 + WARNINGS_IN_EXPECTED,
1.21 + WARNINGS_IN_WARNING,
1.22 + WARNINGS_IN_AT,
1.23 + WARNINGS_IN_TEXT,
1.24 + WARNINGS_DONE,
1.25 + } state;
1.26 +} WarningsBaton;
1.27 +
1.28 +static void warnings_parser_start_element(GMarkupParseContext *context,
1.29 + const char *element_name,const char **attribute_names,
1.30 + const char **attribute_values,void *user_data,GError **error)
1.31 +{
1.32 + int i;
1.33 + guint64 tmp;
1.34 + char *endp;
1.35 + WarningsBaton *baton=user_data;
1.36 + switch(baton->state)
1.37 + {
1.38 + case WARNINGS_INIT:
1.39 + if (strcmp(element_name,"expected"))
1.40 + g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
1.41 + "Unknown root element: '%s'",element_name);
1.42 + else if (attribute_names[0])
1.43 + g_set_error(error,G_MARKUP_ERROR,
1.44 + G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
1.45 + "Unknown attribute on element 'expected': '%s'",
1.46 + attribute_names[0]);
1.47 + else
1.48 + baton->state=WARNINGS_IN_EXPECTED;
1.49 + break;
1.50 + case WARNINGS_IN_EXPECTED:
1.51 + baton->warning=g_new0(TestcaseWarning,1);
1.52 + if (!strcmp(element_name,"error"))
1.53 + baton->warning->is_real=TRUE;
1.54 + else if (!strcmp(element_name,"false-positive"))
1.55 + baton->warning->xfail=TRUE;
1.56 + else if (!strcmp(element_name,"false-negative"))
1.57 + baton->warning->is_real=baton->warning->xfail=TRUE;
1.58 + else
1.59 + {
1.60 + g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
1.61 + "Unknown element in 'expected': '%s'",element_name);
1.62 + g_free(baton->warning);
1.63 + baton->warning=NULL;
1.64 + return;
1.65 + }
1.66 + if (attribute_names[0])
1.67 + {
1.68 + g_set_error(error,G_MARKUP_ERROR,
1.69 + G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
1.70 + "Unknown attribute on element '%s': '%s'",element_name,
1.71 + attribute_names[0]);
1.72 + g_free(baton->warning);
1.73 + baton->warning=NULL;
1.74 + return;
1.75 + }
1.76 + else
1.77 + baton->state=WARNINGS_IN_WARNING;
1.78 + break;
1.79 + case WARNINGS_IN_WARNING:
1.80 + if (!strcmp(element_name,"at"))
1.81 + {
1.82 + baton->location=g_new0(TestcaseLocation,1);
1.83 + for(i=0;attribute_names[i];i++)
1.84 + {
1.85 + if (!strcmp(attribute_names[i],"line"))
1.86 + {
1.87 + tmp=g_ascii_strtoull(attribute_values[i],&endp,0);
1.88 + if (tmp<1 || tmp>G_MAXUINT || tmp==G_MAXUINT64)
1.89 + {
1.90 + g_set_error(error,G_MARKUP_ERROR,
1.91 + G_MARKUP_ERROR_INVALID_CONTENT,"Invalid value "
1.92 + "for attribute 'line' on element '%s': '%s'",
1.93 + element_name,attribute_values[i]);
1.94 + return;
1.95 + }
1.96 + baton->location->line=(guint)tmp;
1.97 + }
1.98 + else if (!strcmp(attribute_names[i],"column"))
1.99 + {
1.100 + tmp=g_ascii_strtoull(attribute_values[i],&endp,0);
1.101 + if (tmp<1 || tmp>G_MAXUINT || tmp==G_MAXUINT64)
1.102 + {
1.103 + g_set_error(error,G_MARKUP_ERROR,
1.104 + G_MARKUP_ERROR_INVALID_CONTENT,"Invalid value "
1.105 + "for attribute 'column' on element '%s': '%s'",
1.106 + element_name,attribute_values[i]);
1.107 + return;
1.108 + }
1.109 + baton->location->column=(guint)tmp;
1.110 + }
1.111 + else
1.112 + {
1.113 + g_set_error(error,G_MARKUP_ERROR,
1.114 + G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
1.115 + "Unknown attribute on element '%s': '%s'",
1.116 + element_name,attribute_names[i]);
1.117 + return;
1.118 + }
1.119 + }
1.120 + if (!baton->location->line)
1.121 + {
1.122 + g_set_error(error,G_MARKUP_ERROR,
1.123 + G_MARKUP_ERROR_MISSING_ATTRIBUTE,
1.124 + "Missing attribute on element '%s': 'line'",element_name);
1.125 + return;
1.126 + }
1.127 + baton->state=WARNINGS_IN_AT;
1.128 + }
1.129 + else if (!strcmp(element_name,"text"))
1.130 + {
1.131 + if (attribute_names[0])
1.132 + {
1.133 + g_set_error(error,G_MARKUP_ERROR,
1.134 + G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
1.135 + "Unknown attribute on element 'text': '%s'",
1.136 + attribute_names[0]);
1.137 + return;
1.138 + }
1.139 + baton->state=WARNINGS_IN_TEXT;
1.140 + }
1.141 + break;
1.142 + case WARNINGS_IN_AT:
1.143 + g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
1.144 + "Unknown element in 'at': '%s'",element_name);
1.145 + return;
1.146 + case WARNINGS_IN_TEXT:
1.147 + g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
1.148 + "Unknown element in 'text': '%s'",element_name);
1.149 + return;
1.150 + default:
1.151 + g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
1.152 + "Unexpected element: '%s'",element_name);
1.153 + return;
1.154 + }
1.155 +}
1.156 +
1.157 +static void warnings_parser_end_element(GMarkupParseContext *context,
1.158 + const char *element_name,void *user_data,GError **error)
1.159 +{
1.160 + WarningsBaton *baton=user_data;
1.161 + switch(baton->state)
1.162 + {
1.163 + case WARNINGS_IN_EXPECTED:
1.164 + baton->testcase->warnings=
1.165 + g_slist_reverse(baton->testcase->warnings);
1.166 + baton->state=WARNINGS_DONE;
1.167 + break;
1.168 + case WARNINGS_IN_WARNING:
1.169 + baton->warning->locations=
1.170 + g_slist_reverse(baton->warning->locations);
1.171 + baton->testcase->warnings=g_slist_prepend(baton->testcase->warnings,
1.172 + baton->warning);
1.173 + baton->warning=NULL;
1.174 + baton->state=WARNINGS_IN_EXPECTED;
1.175 + break;
1.176 + case WARNINGS_IN_AT:
1.177 + baton->warning->locations=g_slist_prepend(baton->warning->locations,
1.178 + baton->location);
1.179 + baton->location=NULL;
1.180 + baton->state=WARNINGS_IN_WARNING;
1.181 + break;
1.182 + case WARNINGS_IN_TEXT:
1.183 + baton->state=WARNINGS_IN_WARNING;
1.184 + break;
1.185 + default:
1.186 + g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
1.187 + "Unexpected element ending: '%s'",element_name);
1.188 + return;
1.189 + }
1.190 +}
1.191 +
1.192 +static void warnings_parser_text(GMarkupParseContext *context,
1.193 + const char *text,gsize text_len,void *user_data,GError **error)
1.194 +{
1.195 + char *s,*t;
1.196 + WarningsBaton *baton=user_data;
1.197 + switch(baton->state)
1.198 + {
1.199 + case WARNINGS_IN_EXPECTED:
1.200 + if (strspn(text," \t\n")!=text_len)
1.201 + g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
1.202 + "The 'expected' tag does not take any content");
1.203 + break;
1.204 + case WARNINGS_IN_WARNING:
1.205 + if (strspn(text," \t\n")!=text_len)
1.206 + g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
1.207 + "The warning tags do not take any content");
1.208 + break;
1.209 + case WARNINGS_IN_AT:
1.210 + if (strspn(text," \t\n")!=text_len)
1.211 + g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
1.212 + "The 'at' tag does not take any content");
1.213 + break;
1.214 + case WARNINGS_IN_TEXT:
1.215 + s=g_strdup(text+strspn(text," \t\n"));
1.216 + g_strchomp(s);
1.217 + if (baton->warning->text)
1.218 + {
1.219 + t=g_strconcat(baton->warning->text,s,NULL);
1.220 + g_free(baton->warning->text);
1.221 + g_free(s);
1.222 + baton->warning->text=t;
1.223 + }
1.224 + else
1.225 + baton->warning->text=s;
1.226 + break;
1.227 + default:
1.228 + g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
1.229 + "Unexpected content: '%s'",text);
1.230 + return;
1.231 + }
1.232 +}
1.233 +
1.234 +GMarkupParseContext *warnings_parse_context_new(Testcase *testcase)
1.235 +{
1.236 + static GMarkupParser parser={0};
1.237 + WarningsBaton *baton;
1.238 + parser.start_element=warnings_parser_start_element;
1.239 + parser.end_element=warnings_parser_end_element;
1.240 + parser.text=warnings_parser_text;
1.241 + baton=g_new0(WarningsBaton,1);
1.242 + baton->testcase=testcase;
1.243 + baton->state=WARNINGS_INIT;
1.244 + return g_markup_parse_context_new(&parser,
1.245 + G_MARKUP_TREAT_CDATA_AS_TEXT|G_MARKUP_PREFIX_ERROR_POSITION,
1.246 + baton,g_free);
1.247 +}