5 #include "warningsparser.h"
8 * A GMarkupParser for the contents of a WARNINGS tag.
13 TestcaseWarning *warning;
14 TestcaseLocation *location;
26 static void warnings_parser_start_element(GMarkupParseContext *context,
27 const char *element_name,const char **attribute_names,
28 const char **attribute_values,void *user_data,GError **error)
33 WarningsBaton *baton=user_data;
34 baton->parent_state=baton->state;
38 if (strcmp(element_name,"expected"))
39 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
40 "Unknown root element: '%s'",element_name);
41 else if (attribute_names[0])
42 g_set_error(error,G_MARKUP_ERROR,
43 G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
44 "Unknown attribute on element 'expected': '%s'",
47 baton->state=WARNINGS_IN_EXPECTED;
49 case WARNINGS_IN_EXPECTED:
50 if (!strcmp(element_name,"summary"))
52 if (baton->testcase->summary.texts)
54 g_set_error(error,G_MARKUP_ERROR,
55 G_MARKUP_ERROR_INVALID_CONTENT,"Multiple summary "
56 "elements are not valid");
59 baton->state=WARNINGS_IN_SUMMARY;
63 baton->warning=g_new0(TestcaseWarning,1);
64 if (!strcmp(element_name,"error"))
65 baton->warning->is_real=TRUE;
66 else if (!strcmp(element_name,"false-positive"))
67 baton->warning->xfail=TRUE;
68 else if (!strcmp(element_name,"false-negative"))
69 baton->warning->is_real=baton->warning->xfail=TRUE;
72 g_set_error(error,G_MARKUP_ERROR,
73 G_MARKUP_ERROR_UNKNOWN_ELEMENT,
74 "Unknown element in 'expected': '%s'",element_name);
75 g_free(baton->warning);
79 baton->state=WARNINGS_IN_WARNING;
81 if (attribute_names[0])
83 g_set_error(error,G_MARKUP_ERROR,
84 G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
85 "Unknown attribute on element '%s': '%s'",element_name,
87 if (baton->state==WARNINGS_IN_WARNING)
89 g_free(baton->warning);
92 baton->state=WARNINGS_IN_EXPECTED;
96 case WARNINGS_IN_SUMMARY:
97 if (!strcmp(element_name,"text"))
99 if (attribute_names[0])
101 g_set_error(error,G_MARKUP_ERROR,
102 G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
103 "Unknown attribute on element 'text': '%s'",
107 baton->state=WARNINGS_IN_TEXT;
110 case WARNINGS_IN_WARNING:
111 if (!strcmp(element_name,"at"))
113 baton->location=g_new0(TestcaseLocation,1);
114 for(i=0;attribute_names[i];i++)
116 if (!strcmp(attribute_names[i],"line"))
118 tmp=g_ascii_strtoull(attribute_values[i],&endp,0);
119 if (tmp<1 || tmp>G_MAXUINT || tmp==G_MAXUINT64)
121 g_set_error(error,G_MARKUP_ERROR,
122 G_MARKUP_ERROR_INVALID_CONTENT,"Invalid value "
123 "for attribute 'line' on element '%s': '%s'",
124 element_name,attribute_values[i]);
127 baton->location->line=(guint)tmp;
129 else if (!strcmp(attribute_names[i],"column"))
131 tmp=g_ascii_strtoull(attribute_values[i],&endp,0);
132 if (tmp<1 || tmp>G_MAXUINT || tmp==G_MAXUINT64)
134 g_set_error(error,G_MARKUP_ERROR,
135 G_MARKUP_ERROR_INVALID_CONTENT,"Invalid value "
136 "for attribute 'column' on element '%s': '%s'",
137 element_name,attribute_values[i]);
140 baton->location->column=(guint)tmp;
144 g_set_error(error,G_MARKUP_ERROR,
145 G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
146 "Unknown attribute on element '%s': '%s'",
147 element_name,attribute_names[i]);
151 if (!baton->location->line)
153 g_set_error(error,G_MARKUP_ERROR,
154 G_MARKUP_ERROR_MISSING_ATTRIBUTE,
155 "Missing attribute on element '%s': 'line'",element_name);
158 baton->state=WARNINGS_IN_AT;
160 else if (!strcmp(element_name,"text"))
162 if (attribute_names[0])
164 g_set_error(error,G_MARKUP_ERROR,
165 G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
166 "Unknown attribute on element 'text': '%s'",
170 baton->state=WARNINGS_IN_TEXT;
174 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
175 "Unknown element in 'at': '%s'",element_name);
177 case WARNINGS_IN_TEXT:
178 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
179 "Unknown element in 'text': '%s'",element_name);
182 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
183 "Unexpected element: '%s'",element_name);
188 static void warnings_parser_end_element(GMarkupParseContext *context,
189 const char *element_name,void *user_data,GError **error)
191 WarningsBaton *baton=user_data;
194 case WARNINGS_IN_EXPECTED:
195 baton->testcase->warnings=
196 g_slist_reverse(baton->testcase->warnings);
197 baton->state=WARNINGS_DONE;
199 case WARNINGS_IN_SUMMARY:
200 if (!baton->testcase->summary.texts)
201 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
202 "Summary element must contain at least one text element");
204 baton->testcase->summary.texts=
205 g_slist_reverse(baton->testcase->summary.texts);
206 baton->state=WARNINGS_IN_EXPECTED;
208 case WARNINGS_IN_WARNING:
209 baton->warning->locations=
210 g_slist_reverse(baton->warning->locations);
211 baton->testcase->warnings=g_slist_prepend(baton->testcase->warnings,
214 baton->state=WARNINGS_IN_EXPECTED;
217 baton->warning->locations=g_slist_prepend(baton->warning->locations,
219 baton->location=NULL;
220 baton->state=WARNINGS_IN_WARNING;
222 case WARNINGS_IN_TEXT:
223 baton->state=baton->parent_state;
226 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
227 "Unexpected element ending: '%s'",element_name);
232 static void warnings_parser_text(GMarkupParseContext *context,
233 const char *text,gsize text_len,void *user_data,GError **error)
236 WarningsBaton *baton=user_data;
239 case WARNINGS_IN_EXPECTED:
240 if (strspn(text," \t\n")!=text_len)
241 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
242 "The 'expected' tag does not take any content");
244 case WARNINGS_IN_SUMMARY:
245 if (strspn(text," \t\n")!=text_len)
246 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
247 "The summary tags do not take any content");
249 case WARNINGS_IN_WARNING:
250 if (strspn(text," \t\n")!=text_len)
251 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
252 "The warning tags do not take any content");
255 if (strspn(text," \t\n")!=text_len)
256 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
257 "The 'at' tag does not take any content");
259 case WARNINGS_IN_TEXT:
260 s=g_strdup(text+strspn(text," \t\n"));
262 if (baton->parent_state==WARNINGS_IN_SUMMARY)
263 baton->testcase->summary.texts=
264 g_slist_prepend(baton->testcase->summary.texts,s);
265 else if (baton->warning->text)
267 t=g_strconcat(baton->warning->text,s,NULL);
268 g_free(baton->warning->text);
270 baton->warning->text=t;
273 baton->warning->text=s;
276 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
277 "Unexpected content: '%s'",text);
282 GMarkupParseContext *warnings_parse_context_new(Testcase *testcase)
284 static GMarkupParser parser={0};
285 WarningsBaton *baton;
286 parser.start_element=warnings_parser_start_element;
287 parser.end_element=warnings_parser_end_element;
288 parser.text=warnings_parser_text;
289 baton=g_new0(WarningsBaton,1);
290 baton->testcase=testcase;
291 baton->parent_state=WARNINGS_INIT;
292 baton->state=WARNINGS_INIT;
293 return g_markup_parse_context_new(&parser,
294 G_MARKUP_TREAT_CDATA_AS_TEXT|G_MARKUP_PREFIX_ERROR_POSITION,