Fix bug #21: False positive: Opening slanted double-quote, followed by single slanted quote, should be accepted by BL
5 #include "warningsparser.h"
8 * A GMarkupParser for the contents of a WARNINGS tag.
13 TestcaseWarning *warning;
14 TestcaseLocation *location;
25 static void warnings_parser_start_element(GMarkupParseContext *context,
26 const char *element_name,const char **attribute_names,
27 const char **attribute_values,void *user_data,GError **error)
32 WarningsBaton *baton=user_data;
36 if (strcmp(element_name,"expected"))
37 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
38 "Unknown root element: '%s'",element_name);
39 else if (attribute_names[0])
40 g_set_error(error,G_MARKUP_ERROR,
41 G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
42 "Unknown attribute on element 'expected': '%s'",
45 baton->state=WARNINGS_IN_EXPECTED;
47 case WARNINGS_IN_EXPECTED:
48 baton->warning=g_new0(TestcaseWarning,1);
49 if (!strcmp(element_name,"error"))
50 baton->warning->is_real=TRUE;
51 else if (!strcmp(element_name,"false-positive"))
52 baton->warning->xfail=TRUE;
53 else if (!strcmp(element_name,"false-negative"))
54 baton->warning->is_real=baton->warning->xfail=TRUE;
57 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
58 "Unknown element in 'expected': '%s'",element_name);
59 g_free(baton->warning);
63 if (attribute_names[0])
65 g_set_error(error,G_MARKUP_ERROR,
66 G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
67 "Unknown attribute on element '%s': '%s'",element_name,
69 g_free(baton->warning);
74 baton->state=WARNINGS_IN_WARNING;
76 case WARNINGS_IN_WARNING:
77 if (!strcmp(element_name,"at"))
79 baton->location=g_new0(TestcaseLocation,1);
80 for(i=0;attribute_names[i];i++)
82 if (!strcmp(attribute_names[i],"line"))
84 tmp=g_ascii_strtoull(attribute_values[i],&endp,0);
85 if (tmp<1 || tmp>G_MAXUINT || tmp==G_MAXUINT64)
87 g_set_error(error,G_MARKUP_ERROR,
88 G_MARKUP_ERROR_INVALID_CONTENT,"Invalid value "
89 "for attribute 'line' on element '%s': '%s'",
90 element_name,attribute_values[i]);
93 baton->location->line=(guint)tmp;
95 else if (!strcmp(attribute_names[i],"column"))
97 tmp=g_ascii_strtoull(attribute_values[i],&endp,0);
98 if (tmp<1 || tmp>G_MAXUINT || tmp==G_MAXUINT64)
100 g_set_error(error,G_MARKUP_ERROR,
101 G_MARKUP_ERROR_INVALID_CONTENT,"Invalid value "
102 "for attribute 'column' on element '%s': '%s'",
103 element_name,attribute_values[i]);
106 baton->location->column=(guint)tmp;
110 g_set_error(error,G_MARKUP_ERROR,
111 G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
112 "Unknown attribute on element '%s': '%s'",
113 element_name,attribute_names[i]);
117 if (!baton->location->line)
119 g_set_error(error,G_MARKUP_ERROR,
120 G_MARKUP_ERROR_MISSING_ATTRIBUTE,
121 "Missing attribute on element '%s': 'line'",element_name);
124 baton->state=WARNINGS_IN_AT;
126 else if (!strcmp(element_name,"text"))
128 if (attribute_names[0])
130 g_set_error(error,G_MARKUP_ERROR,
131 G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
132 "Unknown attribute on element 'text': '%s'",
136 baton->state=WARNINGS_IN_TEXT;
140 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
141 "Unknown element in 'at': '%s'",element_name);
143 case WARNINGS_IN_TEXT:
144 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
145 "Unknown element in 'text': '%s'",element_name);
148 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
149 "Unexpected element: '%s'",element_name);
154 static void warnings_parser_end_element(GMarkupParseContext *context,
155 const char *element_name,void *user_data,GError **error)
157 WarningsBaton *baton=user_data;
160 case WARNINGS_IN_EXPECTED:
161 baton->testcase->warnings=
162 g_slist_reverse(baton->testcase->warnings);
163 baton->state=WARNINGS_DONE;
165 case WARNINGS_IN_WARNING:
166 baton->warning->locations=
167 g_slist_reverse(baton->warning->locations);
168 baton->testcase->warnings=g_slist_prepend(baton->testcase->warnings,
171 baton->state=WARNINGS_IN_EXPECTED;
174 baton->warning->locations=g_slist_prepend(baton->warning->locations,
176 baton->location=NULL;
177 baton->state=WARNINGS_IN_WARNING;
179 case WARNINGS_IN_TEXT:
180 baton->state=WARNINGS_IN_WARNING;
183 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
184 "Unexpected element ending: '%s'",element_name);
189 static void warnings_parser_text(GMarkupParseContext *context,
190 const char *text,gsize text_len,void *user_data,GError **error)
193 WarningsBaton *baton=user_data;
196 case WARNINGS_IN_EXPECTED:
197 if (strspn(text," \t\n")!=text_len)
198 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
199 "The 'expected' tag does not take any content");
201 case WARNINGS_IN_WARNING:
202 if (strspn(text," \t\n")!=text_len)
203 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
204 "The warning tags do not take any content");
207 if (strspn(text," \t\n")!=text_len)
208 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
209 "The 'at' tag does not take any content");
211 case WARNINGS_IN_TEXT:
212 s=g_strdup(text+strspn(text," \t\n"));
214 if (baton->warning->text)
216 t=g_strconcat(baton->warning->text,s,NULL);
217 g_free(baton->warning->text);
219 baton->warning->text=t;
222 baton->warning->text=s;
225 g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
226 "Unexpected content: '%s'",text);
231 GMarkupParseContext *warnings_parse_context_new(Testcase *testcase)
233 static GMarkupParser parser={0};
234 WarningsBaton *baton;
235 parser.start_element=warnings_parser_start_element;
236 parser.end_element=warnings_parser_end_element;
237 parser.text=warnings_parser_text;
238 baton=g_new0(WarningsBaton,1);
239 baton->testcase=testcase;
240 baton->state=WARNINGS_INIT;
241 return g_markup_parse_context_new(&parser,
242 G_MARKUP_TREAT_CDATA_AS_TEXT|G_MARKUP_PREFIX_ERROR_POSITION,