ali@17
|
1 |
#include <stdlib.h>
|
ali@17
|
2 |
#include <string.h>
|
ali@17
|
3 |
#include <glib.h>
|
ali@17
|
4 |
#include "testcase.h"
|
ali@17
|
5 |
#include "warningsparser.h"
|
ali@17
|
6 |
|
ali@17
|
7 |
/*
|
ali@17
|
8 |
* A GMarkupParser for the contents of a WARNINGS tag.
|
ali@17
|
9 |
*/
|
ali@17
|
10 |
|
ali@17
|
11 |
typedef struct {
|
ali@17
|
12 |
Testcase *testcase;
|
ali@17
|
13 |
TestcaseWarning *warning;
|
ali@17
|
14 |
TestcaseLocation *location;
|
ali@17
|
15 |
enum {
|
ali@17
|
16 |
WARNINGS_INIT,
|
ali@17
|
17 |
WARNINGS_IN_EXPECTED,
|
ali@17
|
18 |
WARNINGS_IN_WARNING,
|
ali@17
|
19 |
WARNINGS_IN_AT,
|
ali@17
|
20 |
WARNINGS_IN_TEXT,
|
ali@17
|
21 |
WARNINGS_DONE,
|
ali@17
|
22 |
} state;
|
ali@17
|
23 |
} WarningsBaton;
|
ali@17
|
24 |
|
ali@17
|
25 |
static void warnings_parser_start_element(GMarkupParseContext *context,
|
ali@17
|
26 |
const char *element_name,const char **attribute_names,
|
ali@17
|
27 |
const char **attribute_values,void *user_data,GError **error)
|
ali@17
|
28 |
{
|
ali@17
|
29 |
int i;
|
ali@17
|
30 |
guint64 tmp;
|
ali@17
|
31 |
char *endp;
|
ali@17
|
32 |
WarningsBaton *baton=user_data;
|
ali@17
|
33 |
switch(baton->state)
|
ali@17
|
34 |
{
|
ali@17
|
35 |
case WARNINGS_INIT:
|
ali@17
|
36 |
if (strcmp(element_name,"expected"))
|
ali@17
|
37 |
g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
|
ali@17
|
38 |
"Unknown root element: '%s'",element_name);
|
ali@17
|
39 |
else if (attribute_names[0])
|
ali@17
|
40 |
g_set_error(error,G_MARKUP_ERROR,
|
ali@17
|
41 |
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
ali@17
|
42 |
"Unknown attribute on element 'expected': '%s'",
|
ali@17
|
43 |
attribute_names[0]);
|
ali@17
|
44 |
else
|
ali@17
|
45 |
baton->state=WARNINGS_IN_EXPECTED;
|
ali@17
|
46 |
break;
|
ali@17
|
47 |
case WARNINGS_IN_EXPECTED:
|
ali@17
|
48 |
baton->warning=g_new0(TestcaseWarning,1);
|
ali@17
|
49 |
if (!strcmp(element_name,"error"))
|
ali@17
|
50 |
baton->warning->is_real=TRUE;
|
ali@17
|
51 |
else if (!strcmp(element_name,"false-positive"))
|
ali@17
|
52 |
baton->warning->xfail=TRUE;
|
ali@17
|
53 |
else if (!strcmp(element_name,"false-negative"))
|
ali@17
|
54 |
baton->warning->is_real=baton->warning->xfail=TRUE;
|
ali@17
|
55 |
else
|
ali@17
|
56 |
{
|
ali@17
|
57 |
g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
|
ali@17
|
58 |
"Unknown element in 'expected': '%s'",element_name);
|
ali@17
|
59 |
g_free(baton->warning);
|
ali@17
|
60 |
baton->warning=NULL;
|
ali@17
|
61 |
return;
|
ali@17
|
62 |
}
|
ali@17
|
63 |
if (attribute_names[0])
|
ali@17
|
64 |
{
|
ali@17
|
65 |
g_set_error(error,G_MARKUP_ERROR,
|
ali@17
|
66 |
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
ali@17
|
67 |
"Unknown attribute on element '%s': '%s'",element_name,
|
ali@17
|
68 |
attribute_names[0]);
|
ali@17
|
69 |
g_free(baton->warning);
|
ali@17
|
70 |
baton->warning=NULL;
|
ali@17
|
71 |
return;
|
ali@17
|
72 |
}
|
ali@17
|
73 |
else
|
ali@17
|
74 |
baton->state=WARNINGS_IN_WARNING;
|
ali@17
|
75 |
break;
|
ali@17
|
76 |
case WARNINGS_IN_WARNING:
|
ali@17
|
77 |
if (!strcmp(element_name,"at"))
|
ali@17
|
78 |
{
|
ali@17
|
79 |
baton->location=g_new0(TestcaseLocation,1);
|
ali@17
|
80 |
for(i=0;attribute_names[i];i++)
|
ali@17
|
81 |
{
|
ali@17
|
82 |
if (!strcmp(attribute_names[i],"line"))
|
ali@17
|
83 |
{
|
ali@17
|
84 |
tmp=g_ascii_strtoull(attribute_values[i],&endp,0);
|
ali@17
|
85 |
if (tmp<1 || tmp>G_MAXUINT || tmp==G_MAXUINT64)
|
ali@17
|
86 |
{
|
ali@17
|
87 |
g_set_error(error,G_MARKUP_ERROR,
|
ali@17
|
88 |
G_MARKUP_ERROR_INVALID_CONTENT,"Invalid value "
|
ali@17
|
89 |
"for attribute 'line' on element '%s': '%s'",
|
ali@17
|
90 |
element_name,attribute_values[i]);
|
ali@17
|
91 |
return;
|
ali@17
|
92 |
}
|
ali@17
|
93 |
baton->location->line=(guint)tmp;
|
ali@17
|
94 |
}
|
ali@17
|
95 |
else if (!strcmp(attribute_names[i],"column"))
|
ali@17
|
96 |
{
|
ali@17
|
97 |
tmp=g_ascii_strtoull(attribute_values[i],&endp,0);
|
ali@17
|
98 |
if (tmp<1 || tmp>G_MAXUINT || tmp==G_MAXUINT64)
|
ali@17
|
99 |
{
|
ali@17
|
100 |
g_set_error(error,G_MARKUP_ERROR,
|
ali@17
|
101 |
G_MARKUP_ERROR_INVALID_CONTENT,"Invalid value "
|
ali@17
|
102 |
"for attribute 'column' on element '%s': '%s'",
|
ali@17
|
103 |
element_name,attribute_values[i]);
|
ali@17
|
104 |
return;
|
ali@17
|
105 |
}
|
ali@17
|
106 |
baton->location->column=(guint)tmp;
|
ali@17
|
107 |
}
|
ali@17
|
108 |
else
|
ali@17
|
109 |
{
|
ali@17
|
110 |
g_set_error(error,G_MARKUP_ERROR,
|
ali@17
|
111 |
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
ali@17
|
112 |
"Unknown attribute on element '%s': '%s'",
|
ali@17
|
113 |
element_name,attribute_names[i]);
|
ali@17
|
114 |
return;
|
ali@17
|
115 |
}
|
ali@17
|
116 |
}
|
ali@17
|
117 |
if (!baton->location->line)
|
ali@17
|
118 |
{
|
ali@17
|
119 |
g_set_error(error,G_MARKUP_ERROR,
|
ali@17
|
120 |
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
ali@17
|
121 |
"Missing attribute on element '%s': 'line'",element_name);
|
ali@17
|
122 |
return;
|
ali@17
|
123 |
}
|
ali@17
|
124 |
baton->state=WARNINGS_IN_AT;
|
ali@17
|
125 |
}
|
ali@17
|
126 |
else if (!strcmp(element_name,"text"))
|
ali@17
|
127 |
{
|
ali@17
|
128 |
if (attribute_names[0])
|
ali@17
|
129 |
{
|
ali@17
|
130 |
g_set_error(error,G_MARKUP_ERROR,
|
ali@17
|
131 |
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
ali@17
|
132 |
"Unknown attribute on element 'text': '%s'",
|
ali@17
|
133 |
attribute_names[0]);
|
ali@17
|
134 |
return;
|
ali@17
|
135 |
}
|
ali@17
|
136 |
baton->state=WARNINGS_IN_TEXT;
|
ali@17
|
137 |
}
|
ali@17
|
138 |
break;
|
ali@17
|
139 |
case WARNINGS_IN_AT:
|
ali@17
|
140 |
g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
|
ali@17
|
141 |
"Unknown element in 'at': '%s'",element_name);
|
ali@17
|
142 |
return;
|
ali@17
|
143 |
case WARNINGS_IN_TEXT:
|
ali@17
|
144 |
g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
|
ali@17
|
145 |
"Unknown element in 'text': '%s'",element_name);
|
ali@17
|
146 |
return;
|
ali@17
|
147 |
default:
|
ali@17
|
148 |
g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
|
ali@17
|
149 |
"Unexpected element: '%s'",element_name);
|
ali@17
|
150 |
return;
|
ali@17
|
151 |
}
|
ali@17
|
152 |
}
|
ali@17
|
153 |
|
ali@17
|
154 |
static void warnings_parser_end_element(GMarkupParseContext *context,
|
ali@17
|
155 |
const char *element_name,void *user_data,GError **error)
|
ali@17
|
156 |
{
|
ali@17
|
157 |
WarningsBaton *baton=user_data;
|
ali@17
|
158 |
switch(baton->state)
|
ali@17
|
159 |
{
|
ali@17
|
160 |
case WARNINGS_IN_EXPECTED:
|
ali@17
|
161 |
baton->testcase->warnings=
|
ali@17
|
162 |
g_slist_reverse(baton->testcase->warnings);
|
ali@17
|
163 |
baton->state=WARNINGS_DONE;
|
ali@17
|
164 |
break;
|
ali@17
|
165 |
case WARNINGS_IN_WARNING:
|
ali@17
|
166 |
baton->warning->locations=
|
ali@17
|
167 |
g_slist_reverse(baton->warning->locations);
|
ali@17
|
168 |
baton->testcase->warnings=g_slist_prepend(baton->testcase->warnings,
|
ali@17
|
169 |
baton->warning);
|
ali@17
|
170 |
baton->warning=NULL;
|
ali@17
|
171 |
baton->state=WARNINGS_IN_EXPECTED;
|
ali@17
|
172 |
break;
|
ali@17
|
173 |
case WARNINGS_IN_AT:
|
ali@17
|
174 |
baton->warning->locations=g_slist_prepend(baton->warning->locations,
|
ali@17
|
175 |
baton->location);
|
ali@17
|
176 |
baton->location=NULL;
|
ali@17
|
177 |
baton->state=WARNINGS_IN_WARNING;
|
ali@17
|
178 |
break;
|
ali@17
|
179 |
case WARNINGS_IN_TEXT:
|
ali@17
|
180 |
baton->state=WARNINGS_IN_WARNING;
|
ali@17
|
181 |
break;
|
ali@17
|
182 |
default:
|
ali@17
|
183 |
g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
|
ali@17
|
184 |
"Unexpected element ending: '%s'",element_name);
|
ali@17
|
185 |
return;
|
ali@17
|
186 |
}
|
ali@17
|
187 |
}
|
ali@17
|
188 |
|
ali@17
|
189 |
static void warnings_parser_text(GMarkupParseContext *context,
|
ali@17
|
190 |
const char *text,gsize text_len,void *user_data,GError **error)
|
ali@17
|
191 |
{
|
ali@17
|
192 |
char *s,*t;
|
ali@17
|
193 |
WarningsBaton *baton=user_data;
|
ali@17
|
194 |
switch(baton->state)
|
ali@17
|
195 |
{
|
ali@17
|
196 |
case WARNINGS_IN_EXPECTED:
|
ali@17
|
197 |
if (strspn(text," \t\n")!=text_len)
|
ali@17
|
198 |
g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
|
ali@17
|
199 |
"The 'expected' tag does not take any content");
|
ali@17
|
200 |
break;
|
ali@17
|
201 |
case WARNINGS_IN_WARNING:
|
ali@17
|
202 |
if (strspn(text," \t\n")!=text_len)
|
ali@17
|
203 |
g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
|
ali@17
|
204 |
"The warning tags do not take any content");
|
ali@17
|
205 |
break;
|
ali@17
|
206 |
case WARNINGS_IN_AT:
|
ali@17
|
207 |
if (strspn(text," \t\n")!=text_len)
|
ali@17
|
208 |
g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
|
ali@17
|
209 |
"The 'at' tag does not take any content");
|
ali@17
|
210 |
break;
|
ali@17
|
211 |
case WARNINGS_IN_TEXT:
|
ali@17
|
212 |
s=g_strdup(text+strspn(text," \t\n"));
|
ali@17
|
213 |
g_strchomp(s);
|
ali@17
|
214 |
if (baton->warning->text)
|
ali@17
|
215 |
{
|
ali@17
|
216 |
t=g_strconcat(baton->warning->text,s,NULL);
|
ali@17
|
217 |
g_free(baton->warning->text);
|
ali@17
|
218 |
g_free(s);
|
ali@17
|
219 |
baton->warning->text=t;
|
ali@17
|
220 |
}
|
ali@17
|
221 |
else
|
ali@17
|
222 |
baton->warning->text=s;
|
ali@17
|
223 |
break;
|
ali@17
|
224 |
default:
|
ali@17
|
225 |
g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
|
ali@17
|
226 |
"Unexpected content: '%s'",text);
|
ali@17
|
227 |
return;
|
ali@17
|
228 |
}
|
ali@17
|
229 |
}
|
ali@17
|
230 |
|
ali@17
|
231 |
GMarkupParseContext *warnings_parse_context_new(Testcase *testcase)
|
ali@17
|
232 |
{
|
ali@17
|
233 |
static GMarkupParser parser={0};
|
ali@17
|
234 |
WarningsBaton *baton;
|
ali@17
|
235 |
parser.start_element=warnings_parser_start_element;
|
ali@17
|
236 |
parser.end_element=warnings_parser_end_element;
|
ali@17
|
237 |
parser.text=warnings_parser_text;
|
ali@17
|
238 |
baton=g_new0(WarningsBaton,1);
|
ali@17
|
239 |
baton->testcase=testcase;
|
ali@17
|
240 |
baton->state=WARNINGS_INIT;
|
ali@17
|
241 |
return g_markup_parse_context_new(&parser,
|
ali@17
|
242 |
G_MARKUP_TREAT_CDATA_AS_TEXT|G_MARKUP_PREFIX_ERROR_POSITION,
|
ali@17
|
243 |
baton,g_free);
|
ali@17
|
244 |
}
|