/src/tidy-html5/src/message.c
Line | Count | Source |
1 | | /* message.c -- General Message Writing Routines |
2 | | |
3 | | (c) 1998-2017 (W3C) MIT, ERCIM, Keio University, University of |
4 | | Toronto, HTACG |
5 | | See tidy.h for the copyright notice. |
6 | | |
7 | | */ |
8 | | |
9 | | #include "message.h" |
10 | | #include "messageobj.h" |
11 | | #include "limits.h" |
12 | | #include "tidy-int.h" |
13 | | #include "lexer.h" |
14 | | #include "streamio.h" |
15 | | #include "tmbstr.h" |
16 | | #include "utf8.h" |
17 | | #include "version.h" |
18 | | |
19 | | |
20 | | /********************************************************************* |
21 | | * Release Information |
22 | | *********************************************************************/ |
23 | | |
24 | | ctmbstr TY_(ReleaseDate)(void) |
25 | 0 | { |
26 | 0 | return TY_(release_date); |
27 | 0 | } |
28 | | |
29 | | |
30 | | ctmbstr TY_(tidyLibraryVersion)(void) |
31 | 20.4k | { |
32 | 20.4k | return TY_(library_version); |
33 | 20.4k | } |
34 | | |
35 | | |
36 | | /********************************************************************* |
37 | | * General Message Utility Functions |
38 | | *********************************************************************/ |
39 | | |
40 | | /* Returns the given node's tag as a string. */ |
41 | | static char* TagToString(Node* tag, char* buf, size_t count) |
42 | 11.0M | { |
43 | 11.0M | *buf = 0; |
44 | 11.0M | if (tag) |
45 | 9.29M | { |
46 | 9.29M | if (TY_(nodeIsElement)(tag)) |
47 | 9.15M | TY_(tmbsnprintf)(buf, count, "<%s>", tag->element); |
48 | 137k | else if (tag->type == EndTag) |
49 | 78.5k | TY_(tmbsnprintf)(buf, count, "</%s>", tag->element); |
50 | 58.8k | else if (tag->type == DocTypeTag) |
51 | 21.9k | TY_(tmbsnprintf)(buf, count, "<!DOCTYPE>"); |
52 | 36.9k | else if (tag->type == TextNode) |
53 | 33.7k | TY_(tmbsnprintf)(buf, count, "%s", "STRING_PLAIN_TEXT"); |
54 | 3.25k | else if (tag->type == XmlDecl) |
55 | 1.88k | TY_(tmbsnprintf)(buf, count, "%s", "STRING_XML_DECLARATION"); |
56 | 1.37k | else if (tag->element) |
57 | 996 | TY_(tmbsnprintf)(buf, count, "%s", tag->element); |
58 | 9.29M | } |
59 | 11.0M | return buf + TY_(tmbstrlen)(buf); |
60 | 11.0M | } |
61 | | |
62 | | |
63 | | /* Convert an integer to a string. */ |
64 | | static void NtoS(int n, tmbstr str) |
65 | 1.36k | { |
66 | 1.36k | tmbchar buf[40]; |
67 | 1.36k | int i; |
68 | | |
69 | 2.72k | for (i = 0;; ++i) |
70 | 4.08k | { |
71 | 4.08k | buf[i] = (tmbchar)( (n % 10) + '0' ); |
72 | | |
73 | 4.08k | n = n / 10; |
74 | | |
75 | 4.08k | if (n == 0) |
76 | 1.36k | break; |
77 | 4.08k | } |
78 | | |
79 | 1.36k | n = i; |
80 | | |
81 | 5.45k | while (i >= 0) |
82 | 4.08k | { |
83 | 4.08k | str[n-i] = buf[i]; |
84 | 4.08k | --i; |
85 | 4.08k | } |
86 | | |
87 | 1.36k | str[n+1] = '\0'; |
88 | 1.36k | } |
89 | | |
90 | | |
91 | | /* Get an HTML version string */ |
92 | | static ctmbstr HTMLVersion( TidyDocImpl* doc ) |
93 | 6.70k | { |
94 | 6.70k | uint versionEmitted = doc->lexer->versionEmitted; |
95 | 6.70k | uint declared = doc->lexer->doctype; |
96 | 6.70k | uint version = versionEmitted == 0 ? declared : versionEmitted; |
97 | 6.70k | ctmbstr result = TY_(HTMLVersionNameFromCode)(version, 0); |
98 | 6.70k | if (!result) |
99 | 0 | result = tidyLocalizedString(STRING_HTML_PROPRIETARY); |
100 | 6.70k | return result; |
101 | 6.70k | } |
102 | | |
103 | | |
104 | | /********************************************************************* |
105 | | * Message Writing Functions |
106 | | * These functions provide final, formatted output to the output sink. |
107 | | *********************************************************************/ |
108 | | |
109 | | |
110 | | /* Writes messages to the output sink unless they are suppressed by one of the |
111 | | ** message callback filters, or suppressed by the configuration settings. |
112 | | ** Report messages are messages that are included in the "error table," and |
113 | | ** dialogue messages are any other output that Tidy traditionally emits. |
114 | | */ |
115 | | static void messageOut( TidyMessageImpl *message ) |
116 | 7.11M | { |
117 | 7.11M | TidyDocImpl *doc; |
118 | 7.11M | Bool go = yes; |
119 | | |
120 | 7.11M | if ( !message ) |
121 | 0 | return; |
122 | | |
123 | 7.11M | doc = message->tidyDoc; |
124 | | |
125 | | /* The filter has had a chance to suppress *any* message from output. */ |
126 | 7.11M | go = message->allowMessage; |
127 | | |
128 | | /* Update the count of each report type. */ |
129 | 7.11M | switch ( message->level ) |
130 | 7.11M | { |
131 | 149k | case TidyInfo: |
132 | 149k | doc->infoMessages++; |
133 | 149k | break; |
134 | 6.82M | case TidyWarning: |
135 | 6.82M | doc->warnings++; |
136 | 6.82M | break; |
137 | 0 | case TidyConfig: |
138 | 0 | doc->optionErrors++; |
139 | 0 | break; |
140 | 0 | case TidyAccess: |
141 | 0 | doc->accessErrors++; |
142 | 0 | break; |
143 | 111k | case TidyError: |
144 | 111k | doc->errors++; |
145 | 111k | break; |
146 | 0 | case TidyBadDocument: |
147 | 0 | doc->docErrors++; |
148 | 0 | break; |
149 | 0 | case TidyFatal: |
150 | | /* Ack! */ |
151 | 0 | break; |
152 | 25.9k | default: |
153 | 25.9k | break; |
154 | 7.11M | } |
155 | | |
156 | | /* Suppress report messages if they've been muted. */ |
157 | 7.11M | go = go & !message->muted; |
158 | | |
159 | | /* Suppress report messages if we've already reached the reporting limit. */ |
160 | 7.11M | if ( message->level <= TidyFatal ) |
161 | 7.08M | { |
162 | 7.08M | go = go & ( doc->errors < cfg(doc, TidyShowErrors) ); |
163 | 7.08M | } |
164 | | |
165 | | /* Let TidyQuiet silence a lot of things. */ |
166 | 7.11M | if ( cfgBool( doc, TidyQuiet ) == yes ) |
167 | 0 | { |
168 | 0 | go = go && message->code != STRING_DOCTYPE_GIVEN; |
169 | 0 | go = go && message->code != STRING_CONTENT_LOOKS; |
170 | 0 | go = go && message->code != STRING_NO_SYSID; |
171 | 0 | go = go && message->level != TidyDialogueInfo; |
172 | 0 | go = go && message->level != TidyConfig; |
173 | 0 | go = go && message->level != TidyInfo; |
174 | 0 | go = go && !(message->level >= TidyDialogueSummary && |
175 | 0 | message->code != STRING_NEEDS_INTERVENTION); |
176 | 0 | } |
177 | | |
178 | | /* Let !TidyShowInfo silence some things. */ |
179 | 7.11M | if ( cfgBool( doc, TidyShowInfo ) == no ) |
180 | 0 | { |
181 | 0 | go = go && message->level != TidyInfo; |
182 | | |
183 | | /* Temporary; TidyShowInfo shouldn't affect TidyDialogueInfo, but |
184 | | right now such messages are hidden until we granularize the |
185 | | output controls. */ |
186 | 0 | go = go && message->level != TidyDialogueInfo; |
187 | 0 | } |
188 | | |
189 | | /* Let !TidyShowWarnings silence some things. */ |
190 | 7.11M | if ( cfgBool( doc, TidyShowWarnings ) == no ) |
191 | 0 | { |
192 | 0 | go = go && message->level != TidyWarning; |
193 | 0 | } |
194 | | |
195 | | /* Output the message if applicable. */ |
196 | 7.11M | if ( go ) |
197 | 3.71M | { |
198 | 3.71M | TidyOutputSink *outp = &doc->errout->sink; |
199 | 3.71M | ctmbstr cp; |
200 | 3.71M | byte b = '\0'; |
201 | 225M | for ( cp = message->messageOutput; *cp; ++cp ) |
202 | 222M | { |
203 | 222M | b = (*cp & 0xff); |
204 | 222M | if (b == (byte)'\n') |
205 | 36.6k | TY_(WriteChar)( b, doc->errout ); /* for EOL translation */ |
206 | 222M | else |
207 | 222M | outp->putByte( outp->sinkData, b ); /* #383 - no encoding */ |
208 | 222M | } |
209 | | |
210 | | /* Always add a trailing newline. Reports require this, and dialogue |
211 | | messages will be better spaced out without having to fill the |
212 | | language file with superfluous newlines. */ |
213 | 3.71M | TY_(WriteChar)( '\n', doc->errout ); |
214 | 3.71M | } |
215 | | |
216 | 7.11M | TY_(tidyMessageRelease)(message); |
217 | 7.11M | } |
218 | | |
219 | | |
220 | | /********************************************************************* |
221 | | * Report Formatting |
222 | | * In order to provide a single, predictable reporting system, Tidy |
223 | | * provides an extensible messaging system that provides most of the |
224 | | * basic requirements for most reports, while permitting simple |
225 | | * implementation of new reports in a flexible manner. By adding |
226 | | * additional formatters, new messages can be added easily while |
227 | | * maintaining Tidy's internal organization. |
228 | | *********************************************************************/ |
229 | | |
230 | | |
231 | | /* Functions of this type will create new instances of TidyMessage specific to |
232 | | ** the type of report being emitted. Many messages share the same formatter for |
233 | | ** messages, but new ones can be written as required. Please have a look at |
234 | | ** the existing formatters in order to determine if an existing signature is |
235 | | ** compatible with the report you wish to output before adding a new formatter. |
236 | | ** In particular, if an existing formatter provides most of the local variables |
237 | | ** required to populate your format string, try to use it. |
238 | | */ |
239 | | typedef TidyMessageImpl*(messageFormatter)(TidyDocImpl* doc, Node *element, Node *node, uint code, uint level, va_list args); |
240 | | |
241 | | |
242 | | /* Forward declarations of messageFormatter functions. */ |
243 | | static messageFormatter formatAccessReport; |
244 | | static messageFormatter formatAttributeReport; |
245 | | static messageFormatter formatEncodingReport; |
246 | | static messageFormatter formatStandard; |
247 | | static messageFormatter formatStandardDynamic; |
248 | | |
249 | | |
250 | | /* This structure ties together for each report Code the default |
251 | | ** TidyReportLevel, the Formatter to be used to construct the message, and the |
252 | | ** next code to output, if applicable. Assuming an existing formatter can, |
253 | | ** this it makes it simple to output new reports, or to change report level by |
254 | | ** modifying this array. |
255 | | */ |
256 | | static struct _dispatchTable { |
257 | | uint code; /**< The message code. */ |
258 | | TidyReportLevel level; /**< The default TidyReportLevel of the message. */ |
259 | | messageFormatter *handler; /**< The formatter for the report. */ |
260 | | uint next; /**< If multiple codes should be displayed, which is next? */ |
261 | | } dispatchTable[] = { |
262 | | { ADDED_MISSING_CHARSET, TidyInfo, formatStandard }, |
263 | | { ANCHOR_NOT_UNIQUE, TidyWarning, formatAttributeReport }, |
264 | | { ANCHOR_DUPLICATED, TidyWarning, formatAttributeReport }, |
265 | | { APOS_UNDEFINED, TidyWarning, formatStandard }, |
266 | | { ATTR_VALUE_NOT_LCASE, TidyWarning, formatAttributeReport }, |
267 | | { ATTRIBUTE_VALUE_REPLACED, TidyInfo, formatAttributeReport }, |
268 | | { ATTRIBUTE_IS_NOT_ALLOWED, TidyWarning, formatAttributeReport }, |
269 | | { BACKSLASH_IN_URI, TidyWarning, formatAttributeReport }, |
270 | | { BAD_ATTRIBUTE_VALUE_REPLACED, TidyWarning, formatAttributeReport }, |
271 | | { BAD_ATTRIBUTE_VALUE, TidyWarning, formatAttributeReport }, |
272 | | { BAD_CDATA_CONTENT, TidyWarning, formatStandard }, |
273 | | { BAD_SUMMARY_HTML5, TidyWarning, formatStandard }, |
274 | | { BAD_SURROGATE_LEAD, TidyWarning, formatStandard }, |
275 | | { BAD_SURROGATE_PAIR, TidyWarning, formatStandard }, |
276 | | { BAD_SURROGATE_TAIL, TidyWarning, formatStandard }, |
277 | | { CANT_BE_NESTED, TidyWarning, formatStandard }, |
278 | | { COERCE_TO_ENDTAG, TidyWarning, formatStandard }, |
279 | | { CONTENT_AFTER_BODY, TidyWarning, formatStandard }, |
280 | | { CUSTOM_TAG_DETECTED, TidyInfo, formatStandard }, |
281 | | { DISCARDING_UNEXPECTED, 0, formatStandardDynamic }, |
282 | | { DOCTYPE_AFTER_TAGS, TidyWarning, formatStandard }, |
283 | | { DUPLICATE_FRAMESET, TidyError, formatStandard }, |
284 | | { ELEMENT_NOT_EMPTY, TidyWarning, formatStandard }, |
285 | | { ELEMENT_VERS_MISMATCH_ERROR, TidyError, formatStandard }, |
286 | | { ELEMENT_VERS_MISMATCH_WARN, TidyWarning, formatStandard }, |
287 | | { ENCODING_MISMATCH, TidyWarning, formatEncodingReport }, |
288 | | { ESCAPED_ILLEGAL_URI, TidyWarning, formatAttributeReport }, |
289 | | { FILE_CANT_OPEN, TidyBadDocument, formatStandard }, |
290 | | { FILE_CANT_OPEN_CFG, TidyBadDocument, formatStandard }, |
291 | | { FILE_NOT_FILE, TidyBadDocument, formatStandard }, |
292 | | { FIXED_BACKSLASH, TidyWarning, formatAttributeReport }, |
293 | | { FOUND_STYLE_IN_BODY, TidyWarning, formatStandard }, |
294 | | { ID_NAME_MISMATCH, TidyWarning, formatAttributeReport }, |
295 | | { ILLEGAL_NESTING, TidyWarning, formatStandard }, |
296 | | { ILLEGAL_URI_CODEPOINT, TidyWarning, formatAttributeReport }, |
297 | | { ILLEGAL_URI_REFERENCE, TidyWarning, formatAttributeReport }, |
298 | | { INSERTING_AUTO_ATTRIBUTE, TidyWarning, formatAttributeReport }, |
299 | | { INSERTING_TAG, TidyWarning, formatStandard }, |
300 | | { INVALID_ATTRIBUTE, TidyWarning, formatAttributeReport }, |
301 | | { INVALID_NCR, TidyWarning, formatEncodingReport }, |
302 | | { INVALID_SGML_CHARS, TidyWarning, formatEncodingReport }, |
303 | | { INVALID_UTF8, TidyWarning, formatEncodingReport }, |
304 | | { INVALID_UTF16, TidyWarning, formatEncodingReport }, |
305 | | { INVALID_XML_ID, TidyWarning, formatAttributeReport }, |
306 | | { JOINING_ATTRIBUTE, TidyWarning, formatAttributeReport }, |
307 | | { MALFORMED_COMMENT, TidyInfo, formatStandard }, |
308 | | { MALFORMED_COMMENT_EOS, TidyError, formatStandard }, |
309 | | { MALFORMED_COMMENT_DROPPING, TidyWarning, formatStandard }, |
310 | | { MALFORMED_COMMENT_WARN, TidyWarning, formatStandard }, |
311 | | { MALFORMED_DOCTYPE, TidyWarning, formatStandard }, |
312 | | { MISMATCHED_ATTRIBUTE_ERROR, TidyError, formatAttributeReport }, |
313 | | { MISMATCHED_ATTRIBUTE_WARN, TidyWarning, formatAttributeReport }, |
314 | | { MISSING_ATTR_VALUE, TidyWarning, formatAttributeReport }, |
315 | | { MISSING_ATTRIBUTE, TidyWarning, formatStandard }, |
316 | | { MISSING_DOCTYPE, TidyWarning, formatStandard }, |
317 | | { MISSING_ENDTAG_BEFORE, TidyWarning, formatStandard }, |
318 | | { MISSING_ENDTAG_FOR, TidyWarning, formatStandard }, |
319 | | { MISSING_ENDTAG_OPTIONAL, TidyInfo, formatStandard }, |
320 | | { MISSING_IMAGEMAP, TidyWarning, formatAttributeReport }, |
321 | | { MISSING_QUOTEMARK, TidyWarning, formatAttributeReport }, |
322 | | { MISSING_QUOTEMARK_OPEN, TidyInfo, formatAttributeReport }, |
323 | | { MISSING_SEMICOLON_NCR, TidyWarning, formatStandard }, |
324 | | { MISSING_SEMICOLON, TidyWarning, formatStandard }, |
325 | | { MISSING_STARTTAG, TidyWarning, formatStandard }, |
326 | | { MISSING_TITLE_ELEMENT, TidyWarning, formatStandard }, |
327 | | { MOVED_STYLE_TO_HEAD, TidyWarning, formatStandard }, |
328 | | { NESTED_EMPHASIS, TidyWarning, formatStandard }, |
329 | | { NESTED_QUOTATION, TidyWarning, formatStandard }, |
330 | | { NEWLINE_IN_URI, TidyWarning, formatAttributeReport }, |
331 | | { NOFRAMES_CONTENT, TidyWarning, formatStandard }, |
332 | | { NON_MATCHING_ENDTAG, TidyWarning, formatStandard }, |
333 | | { OBSOLETE_ELEMENT, TidyWarning, formatStandard }, |
334 | | { OPTION_REMOVED, TidyConfig, formatStandard }, |
335 | | { OPTION_REMOVED_APPLIED, TidyConfig, formatStandard }, |
336 | | { OPTION_REMOVED_UNAPPLIED, TidyConfig, formatStandard }, |
337 | | { PREVIOUS_LOCATION, TidyInfo, formatStandard }, |
338 | | { PROPRIETARY_ATTR_VALUE, TidyWarning, formatAttributeReport }, |
339 | | { PROPRIETARY_ATTRIBUTE, TidyWarning, formatAttributeReport }, |
340 | | { PROPRIETARY_ELEMENT, TidyWarning, formatStandard }, |
341 | | { REMOVED_HTML5, TidyWarning, formatStandard }, |
342 | | { REPEATED_ATTRIBUTE, TidyWarning, formatAttributeReport }, |
343 | | { REPLACING_ELEMENT, TidyWarning, formatStandard }, |
344 | | { REPLACING_UNEX_ELEMENT, TidyWarning, formatStandard }, |
345 | | { SPACE_PRECEDING_XMLDECL, TidyWarning, formatStandard }, |
346 | | { STRING_ARGUMENT_BAD, TidyConfig, formatStandard }, |
347 | | { STRING_CONTENT_LOOKS, TidyInfo, formatStandard }, /* reportMarkupVersion() */ |
348 | | { STRING_DOCTYPE_GIVEN, TidyInfo, formatStandard }, /* reportMarkupVersion() */ |
349 | | { STRING_MISSING_MALFORMED, TidyConfig, formatStandard }, |
350 | | { STRING_MUTING_TYPE, TidyInfo, formatStandard }, |
351 | | { STRING_NO_SYSID, TidyInfo, formatStandard }, /* reportMarkupVersion() */ |
352 | | { STRING_UNKNOWN_OPTION, TidyConfig, formatStandard }, |
353 | | { SUSPECTED_MISSING_QUOTE, TidyWarning, formatStandard }, |
354 | | { TAG_NOT_ALLOWED_IN, TidyWarning, formatStandard, PREVIOUS_LOCATION }, |
355 | | { TOO_MANY_ELEMENTS_IN, TidyWarning, formatStandard, PREVIOUS_LOCATION }, |
356 | | { TOO_MANY_ELEMENTS, TidyWarning, formatStandard }, |
357 | | { TRIM_EMPTY_ELEMENT, TidyWarning, formatStandard }, |
358 | | { UNESCAPED_AMPERSAND, TidyWarning, formatStandard }, |
359 | | { UNEXPECTED_END_OF_FILE_ATTR, TidyWarning, formatAttributeReport }, |
360 | | { UNEXPECTED_END_OF_FILE, TidyWarning, formatStandard }, |
361 | | { UNEXPECTED_ENDTAG_IN, TidyError, formatStandard }, |
362 | | { UNEXPECTED_ENDTAG, TidyWarning, formatStandard }, |
363 | | { UNEXPECTED_ENDTAG_ERR, TidyError, formatStandard }, |
364 | | { UNEXPECTED_EQUALSIGN, TidyWarning, formatAttributeReport }, |
365 | | { UNEXPECTED_GT, TidyWarning, formatAttributeReport }, |
366 | | { UNEXPECTED_QUOTEMARK, TidyWarning, formatAttributeReport }, |
367 | | { UNKNOWN_ELEMENT_LOOKS_CUSTOM, TidyError, formatStandard }, |
368 | | { UNKNOWN_ELEMENT, TidyError, formatStandard }, |
369 | | { UNKNOWN_ENTITY, TidyWarning, formatStandard }, |
370 | | { USING_BR_INPLACE_OF, TidyWarning, formatStandard }, |
371 | | { VENDOR_SPECIFIC_CHARS, TidyWarning, formatEncodingReport }, |
372 | | { WHITE_IN_URI, TidyWarning, formatAttributeReport }, |
373 | | { XML_DECLARATION_DETECTED, TidyWarning, formatStandard }, |
374 | | { XML_ID_SYNTAX, TidyWarning, formatAttributeReport }, |
375 | | { BLANK_TITLE_ELEMENT, TidyWarning, formatStandard }, |
376 | | |
377 | | { APPLET_MISSING_ALT, TidyAccess, formatAccessReport }, |
378 | | { AREA_MISSING_ALT, TidyAccess, formatAccessReport }, |
379 | | { ASCII_REQUIRES_DESCRIPTION, TidyAccess, formatAccessReport }, |
380 | | { ASSOCIATE_LABELS_EXPLICITLY, TidyAccess, formatAccessReport }, |
381 | | { ASSOCIATE_LABELS_EXPLICITLY_FOR, TidyAccess, formatAccessReport }, |
382 | | { ASSOCIATE_LABELS_EXPLICITLY_ID, TidyAccess, formatAccessReport }, |
383 | | { AUDIO_MISSING_TEXT_AIFF, TidyAccess, formatAccessReport }, |
384 | | { AUDIO_MISSING_TEXT_AU, TidyAccess, formatAccessReport }, |
385 | | { AUDIO_MISSING_TEXT_RA, TidyAccess, formatAccessReport }, |
386 | | { AUDIO_MISSING_TEXT_RM, TidyAccess, formatAccessReport }, |
387 | | { AUDIO_MISSING_TEXT_SND, TidyAccess, formatAccessReport }, |
388 | | { AUDIO_MISSING_TEXT_WAV, TidyAccess, formatAccessReport }, |
389 | | { COLOR_CONTRAST_ACTIVE_LINK, TidyAccess, formatAccessReport }, |
390 | | { COLOR_CONTRAST_LINK, TidyAccess, formatAccessReport }, |
391 | | { COLOR_CONTRAST_TEXT, TidyAccess, formatAccessReport }, |
392 | | { COLOR_CONTRAST_VISITED_LINK, TidyAccess, formatAccessReport }, |
393 | | { DATA_TABLE_MISSING_HEADERS, TidyAccess, formatAccessReport }, |
394 | | { DATA_TABLE_MISSING_HEADERS_COLUMN, TidyAccess, formatAccessReport }, |
395 | | { DATA_TABLE_MISSING_HEADERS_ROW, TidyAccess, formatAccessReport }, |
396 | | { DATA_TABLE_REQUIRE_MARKUP_COLUMN_HEADERS, TidyAccess, formatAccessReport }, |
397 | | { DATA_TABLE_REQUIRE_MARKUP_ROW_HEADERS, TidyAccess, formatAccessReport }, |
398 | | { DOCTYPE_MISSING, TidyAccess, formatAccessReport }, |
399 | | { ENSURE_PROGRAMMATIC_OBJECTS_ACCESSIBLE_APPLET, TidyAccess, formatAccessReport }, |
400 | | { ENSURE_PROGRAMMATIC_OBJECTS_ACCESSIBLE_EMBED, TidyAccess, formatAccessReport }, |
401 | | { ENSURE_PROGRAMMATIC_OBJECTS_ACCESSIBLE_OBJECT, TidyAccess, formatAccessReport }, |
402 | | { ENSURE_PROGRAMMATIC_OBJECTS_ACCESSIBLE_SCRIPT, TidyAccess, formatAccessReport }, |
403 | | { FRAME_MISSING_LONGDESC, TidyAccess, formatAccessReport }, |
404 | | { FRAME_MISSING_NOFRAMES, TidyAccess, formatAccessReport }, |
405 | | { FRAME_MISSING_TITLE, TidyAccess, formatAccessReport }, |
406 | | { FRAME_SRC_INVALID, TidyAccess, formatAccessReport }, |
407 | | { FRAME_TITLE_INVALID_NULL, TidyAccess, formatAccessReport }, |
408 | | { FRAME_TITLE_INVALID_SPACES, TidyAccess, formatAccessReport }, |
409 | | { HEADER_USED_FORMAT_TEXT, TidyAccess, formatAccessReport }, |
410 | | { HEADERS_IMPROPERLY_NESTED, TidyAccess, formatAccessReport }, |
411 | | { IMAGE_MAP_SERVER_SIDE_REQUIRES_CONVERSION, TidyAccess, formatAccessReport }, |
412 | | { IMG_ALT_SUSPICIOUS_FILE_SIZE, TidyAccess, formatAccessReport }, |
413 | | { IMG_ALT_SUSPICIOUS_FILENAME, TidyAccess, formatAccessReport }, |
414 | | { IMG_ALT_SUSPICIOUS_PLACEHOLDER, TidyAccess, formatAccessReport }, |
415 | | { IMG_ALT_SUSPICIOUS_TOO_LONG, TidyAccess, formatAccessReport }, |
416 | | { IMG_BUTTON_MISSING_ALT, TidyAccess, formatAccessReport }, |
417 | | { IMG_MAP_CLIENT_MISSING_TEXT_LINKS, TidyAccess, formatAccessReport }, |
418 | | { IMG_MAP_SERVER_REQUIRES_TEXT_LINKS, TidyAccess, formatAccessReport }, |
419 | | { IMG_MISSING_ALT, TidyAccess, formatAccessReport }, |
420 | | { IMG_MISSING_DLINK, TidyAccess, formatAccessReport }, |
421 | | { IMG_MISSING_LONGDESC, TidyAccess, formatAccessReport }, |
422 | | { IMG_MISSING_LONGDESC_DLINK, TidyAccess, formatAccessReport }, |
423 | | { INFORMATION_NOT_CONVEYED_APPLET, TidyAccess, formatAccessReport }, |
424 | | { INFORMATION_NOT_CONVEYED_IMAGE, TidyAccess, formatAccessReport }, |
425 | | { INFORMATION_NOT_CONVEYED_INPUT, TidyAccess, formatAccessReport }, |
426 | | { INFORMATION_NOT_CONVEYED_OBJECT, TidyAccess, formatAccessReport }, |
427 | | { INFORMATION_NOT_CONVEYED_SCRIPT, TidyAccess, formatAccessReport }, |
428 | | { LANGUAGE_INVALID, TidyAccess, formatAccessReport }, |
429 | | { LANGUAGE_NOT_IDENTIFIED, TidyAccess, formatAccessReport }, |
430 | | { LAYOUT_TABLE_INVALID_MARKUP, TidyAccess, formatAccessReport }, |
431 | | { LAYOUT_TABLES_LINEARIZE_PROPERLY, TidyAccess, formatAccessReport }, |
432 | | { LINK_TEXT_MISSING, TidyAccess, formatAccessReport }, |
433 | | { LINK_TEXT_NOT_MEANINGFUL, TidyAccess, formatAccessReport }, |
434 | | { LINK_TEXT_NOT_MEANINGFUL_CLICK_HERE, TidyAccess, formatAccessReport }, |
435 | | { LINK_TEXT_TOO_LONG, TidyAccess, formatAccessReport }, |
436 | | { LIST_USAGE_INVALID_LI, TidyAccess, formatAccessReport }, |
437 | | { LIST_USAGE_INVALID_OL, TidyAccess, formatAccessReport }, |
438 | | { LIST_USAGE_INVALID_UL, TidyAccess, formatAccessReport }, |
439 | | { METADATA_MISSING, TidyAccess, formatAccessReport }, |
440 | | { METADATA_MISSING_REDIRECT_AUTOREFRESH, TidyAccess, formatAccessReport }, |
441 | | { MULTIMEDIA_REQUIRES_TEXT, TidyAccess, formatAccessReport }, |
442 | | { NEW_WINDOWS_REQUIRE_WARNING_BLANK, TidyAccess, formatAccessReport }, |
443 | | { NEW_WINDOWS_REQUIRE_WARNING_NEW, TidyAccess, formatAccessReport }, |
444 | | { NOFRAMES_INVALID_CONTENT, TidyAccess, formatAccessReport }, |
445 | | { NOFRAMES_INVALID_LINK, TidyAccess, formatAccessReport }, |
446 | | { NOFRAMES_INVALID_NO_VALUE, TidyAccess, formatAccessReport }, |
447 | | { OBJECT_MISSING_ALT, TidyAccess, formatAccessReport }, |
448 | | { POTENTIAL_HEADER_BOLD, TidyAccess, formatAccessReport }, |
449 | | { POTENTIAL_HEADER_ITALICS, TidyAccess, formatAccessReport }, |
450 | | { POTENTIAL_HEADER_UNDERLINE, TidyAccess, formatAccessReport }, |
451 | | { PROGRAMMATIC_OBJECTS_REQUIRE_TESTING_APPLET, TidyAccess, formatAccessReport }, |
452 | | { PROGRAMMATIC_OBJECTS_REQUIRE_TESTING_EMBED, TidyAccess, formatAccessReport }, |
453 | | { PROGRAMMATIC_OBJECTS_REQUIRE_TESTING_OBJECT, TidyAccess, formatAccessReport }, |
454 | | { PROGRAMMATIC_OBJECTS_REQUIRE_TESTING_SCRIPT, TidyAccess, formatAccessReport }, |
455 | | { REMOVE_AUTO_REDIRECT, TidyAccess, formatAccessReport }, |
456 | | { REMOVE_AUTO_REFRESH, TidyAccess, formatAccessReport }, |
457 | | { REMOVE_BLINK_MARQUEE, TidyAccess, formatAccessReport }, |
458 | | { REMOVE_FLICKER_ANIMATED_GIF, TidyAccess, formatAccessReport }, |
459 | | { REMOVE_FLICKER_APPLET, TidyAccess, formatAccessReport }, |
460 | | { REMOVE_FLICKER_EMBED, TidyAccess, formatAccessReport }, |
461 | | { REMOVE_FLICKER_OBJECT, TidyAccess, formatAccessReport }, |
462 | | { REMOVE_FLICKER_SCRIPT, TidyAccess, formatAccessReport }, |
463 | | { REPLACE_DEPRECATED_HTML_APPLET, TidyAccess, formatAccessReport }, |
464 | | { REPLACE_DEPRECATED_HTML_BASEFONT, TidyAccess, formatAccessReport }, |
465 | | { REPLACE_DEPRECATED_HTML_CENTER, TidyAccess, formatAccessReport }, |
466 | | { REPLACE_DEPRECATED_HTML_DIR, TidyAccess, formatAccessReport }, |
467 | | { REPLACE_DEPRECATED_HTML_FONT, TidyAccess, formatAccessReport }, |
468 | | { REPLACE_DEPRECATED_HTML_ISINDEX, TidyAccess, formatAccessReport }, |
469 | | { REPLACE_DEPRECATED_HTML_MENU, TidyAccess, formatAccessReport }, |
470 | | { REPLACE_DEPRECATED_HTML_S, TidyAccess, formatAccessReport }, |
471 | | { REPLACE_DEPRECATED_HTML_STRIKE, TidyAccess, formatAccessReport }, |
472 | | { REPLACE_DEPRECATED_HTML_U, TidyAccess, formatAccessReport }, |
473 | | { SCRIPT_MISSING_NOSCRIPT, TidyAccess, formatAccessReport }, |
474 | | { SCRIPT_NOT_KEYBOARD_ACCESSIBLE_ON_CLICK, TidyAccess, formatAccessReport }, |
475 | | { SCRIPT_NOT_KEYBOARD_ACCESSIBLE_ON_MOUSE_DOWN, TidyAccess, formatAccessReport }, |
476 | | { SCRIPT_NOT_KEYBOARD_ACCESSIBLE_ON_MOUSE_MOVE, TidyAccess, formatAccessReport }, |
477 | | { SCRIPT_NOT_KEYBOARD_ACCESSIBLE_ON_MOUSE_OUT, TidyAccess, formatAccessReport }, |
478 | | { SCRIPT_NOT_KEYBOARD_ACCESSIBLE_ON_MOUSE_OVER, TidyAccess, formatAccessReport }, |
479 | | { SCRIPT_NOT_KEYBOARD_ACCESSIBLE_ON_MOUSE_UP, TidyAccess, formatAccessReport }, |
480 | | { SKIPOVER_ASCII_ART, TidyAccess, formatAccessReport }, |
481 | | { STYLE_SHEET_CONTROL_PRESENTATION, TidyAccess, formatAccessReport }, |
482 | | { STYLESHEETS_REQUIRE_TESTING_LINK, TidyAccess, formatAccessReport }, |
483 | | { STYLESHEETS_REQUIRE_TESTING_STYLE_ATTR, TidyAccess, formatAccessReport }, |
484 | | { STYLESHEETS_REQUIRE_TESTING_STYLE_ELEMENT, TidyAccess, formatAccessReport }, |
485 | | { TABLE_MAY_REQUIRE_HEADER_ABBR, TidyAccess, formatAccessReport }, |
486 | | { TABLE_MAY_REQUIRE_HEADER_ABBR_NULL, TidyAccess, formatAccessReport }, |
487 | | { TABLE_MAY_REQUIRE_HEADER_ABBR_SPACES, TidyAccess, formatAccessReport }, |
488 | | { TABLE_MISSING_CAPTION, TidyAccess, formatAccessReport }, |
489 | | { TABLE_MISSING_SUMMARY, TidyAccess, formatAccessReport }, |
490 | | { TABLE_SUMMARY_INVALID_NULL, TidyAccess, formatAccessReport }, |
491 | | { TABLE_SUMMARY_INVALID_PLACEHOLDER, TidyAccess, formatAccessReport }, |
492 | | { TABLE_SUMMARY_INVALID_SPACES, TidyAccess, formatAccessReport }, |
493 | | { TEXT_EQUIVALENTS_REQUIRE_UPDATING_APPLET, TidyAccess, formatAccessReport }, |
494 | | { TEXT_EQUIVALENTS_REQUIRE_UPDATING_OBJECT, TidyAccess, formatAccessReport }, |
495 | | { TEXT_EQUIVALENTS_REQUIRE_UPDATING_SCRIPT, TidyAccess, formatAccessReport }, |
496 | | |
497 | | { 0, 0, NULL } |
498 | | }; |
499 | | |
500 | | |
501 | | /********************************************************************* |
502 | | * Message Formatting |
503 | | * These individual message formatters populate messages with the |
504 | | * correct, pertinent data. |
505 | | *********************************************************************/ |
506 | | |
507 | | |
508 | | /* Provides formatting for the Attribute-related reports. This formatter |
509 | | ** should be reserved for messages generated by Tidy's accessibility module, |
510 | | ** even if the signature matches some unrelated report that you wish to |
511 | | ** generate. |
512 | | */ |
513 | | TidyMessageImpl *formatAccessReport(TidyDocImpl* doc, Node *element, Node *node, uint code, uint level, va_list args) |
514 | 0 | { |
515 | 0 | doc->badAccess |= BA_WAI; |
516 | | |
517 | | /* Currently *all* cases are handled in the default, but maintain this |
518 | | structure for possible future cases. */ |
519 | 0 | switch (code) |
520 | 0 | { |
521 | 0 | default: |
522 | 0 | return TY_(tidyMessageCreateWithNode)(doc, node, code, level ); |
523 | 0 | } |
524 | | |
525 | 0 | return NULL; |
526 | 0 | } |
527 | | |
528 | | /* Provides formatting for the Attribute-related reports. This formatter |
529 | | ** provides local variables that are used principally in the formats used for |
530 | | ** the attribute related reports. |
531 | | */ |
532 | | TidyMessageImpl *formatAttributeReport(TidyDocImpl* doc, Node *element, Node *node, uint code, uint level, va_list args) |
533 | 698k | { |
534 | 698k | AttVal *av = NULL; |
535 | 698k | char const *name = "NULL"; |
536 | 698k | char const *value = "NULL"; |
537 | 698k | char tagdesc[64]; |
538 | | |
539 | 698k | TagToString(node, tagdesc, sizeof(tagdesc)); |
540 | | |
541 | 698k | if ( ( av = va_arg(args, AttVal*) ) ) |
542 | 435k | { |
543 | 435k | if (av->attribute) |
544 | 399k | name = av->attribute; |
545 | 435k | if (av->value) |
546 | 241k | value = av->value; |
547 | 435k | } |
548 | | |
549 | 698k | switch (code) |
550 | 698k | { |
551 | 43.3k | case MISSING_QUOTEMARK_OPEN: |
552 | 43.3k | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, name ); |
553 | | |
554 | 540 | case BACKSLASH_IN_URI: |
555 | 32.6k | case ESCAPED_ILLEGAL_URI: |
556 | 32.9k | case FIXED_BACKSLASH: |
557 | 33.5k | case ID_NAME_MISMATCH: |
558 | 64.6k | case ILLEGAL_URI_CODEPOINT: |
559 | 64.6k | case ILLEGAL_URI_REFERENCE: |
560 | 65.3k | case INVALID_XML_ID: |
561 | 65.5k | case MISSING_IMAGEMAP: |
562 | 66.4k | case MISSING_QUOTEMARK: |
563 | 67.2k | case NEWLINE_IN_URI: |
564 | 67.6k | case UNEXPECTED_EQUALSIGN: |
565 | 316k | case UNEXPECTED_GT: |
566 | 321k | case UNEXPECTED_QUOTEMARK: |
567 | 327k | case WHITE_IN_URI: |
568 | 327k | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc ); |
569 | | |
570 | 290 | case ATTRIBUTE_IS_NOT_ALLOWED: |
571 | 1.45k | case JOINING_ATTRIBUTE: |
572 | 112k | case MISSING_ATTR_VALUE: |
573 | 229k | case PROPRIETARY_ATTRIBUTE: |
574 | 229k | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc, name ); |
575 | | |
576 | 14 | case ATTRIBUTE_VALUE_REPLACED: |
577 | 41.7k | case BAD_ATTRIBUTE_VALUE: |
578 | 42.1k | case BAD_ATTRIBUTE_VALUE_REPLACED: |
579 | 42.1k | case INSERTING_AUTO_ATTRIBUTE: |
580 | 45.0k | case INVALID_ATTRIBUTE: |
581 | 45.0k | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc, name, value ); |
582 | | |
583 | 0 | case MISMATCHED_ATTRIBUTE_ERROR: |
584 | 6.70k | case MISMATCHED_ATTRIBUTE_WARN: |
585 | 6.70k | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc, name, HTMLVersion(doc)); |
586 | | |
587 | 3.39k | case ANCHOR_NOT_UNIQUE: |
588 | 37.1k | case ANCHOR_DUPLICATED: |
589 | 38.7k | case ATTR_VALUE_NOT_LCASE: |
590 | 38.9k | case PROPRIETARY_ATTR_VALUE: |
591 | 38.9k | case XML_ID_SYNTAX: |
592 | 38.9k | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc, value ); |
593 | | |
594 | 5.66k | case REPEATED_ATTRIBUTE: |
595 | 5.66k | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc, value, name ); |
596 | | |
597 | 2.17k | case UNEXPECTED_END_OF_FILE_ATTR: |
598 | | /* on end of file adjust reported position to end of input */ |
599 | 2.17k | doc->lexer->lines = doc->docIn->curline; |
600 | 2.17k | doc->lexer->columns = doc->docIn->curcol; |
601 | 2.17k | return TY_(tidyMessageCreateWithLexer)(doc, code, level, tagdesc ); |
602 | 698k | } |
603 | | |
604 | 0 | return NULL; |
605 | 698k | } |
606 | | |
607 | | |
608 | | /* Provides report formatting *and* additional status settings for Tidy's |
609 | | ** encoding reports. Provides the local variables typically used for this type |
610 | | ** of report. |
611 | | ** @todo: These status changes probably SHOULD be made in the calling code; |
612 | | ** however these states are captured to generate future output, which may be |
613 | | ** useful here in the long run. |
614 | | */ |
615 | | TidyMessageImpl *formatEncodingReport(TidyDocImpl* doc, Node *element, Node *node, uint code, uint level, va_list args) |
616 | 953k | { |
617 | 953k | char buf[ 32 ] = {'\0'}; |
618 | 953k | uint c = va_arg( args, uint ); |
619 | 953k | Bool discarded = va_arg( args, Bool ); |
620 | 953k | ctmbstr action = tidyLocalizedString(discarded ? STRING_DISCARDING : STRING_REPLACING); |
621 | | |
622 | 953k | switch (code) |
623 | 953k | { |
624 | 1.35k | case INVALID_NCR: |
625 | 1.35k | NtoS(c, buf); |
626 | 1.35k | doc->badChars |= BC_INVALID_NCR; |
627 | 1.35k | break; |
628 | | |
629 | 6 | case INVALID_SGML_CHARS: |
630 | 6 | NtoS(c, buf); |
631 | 6 | doc->badChars |= BC_INVALID_SGML_CHARS; |
632 | 6 | break; |
633 | | |
634 | 951k | case INVALID_UTF8: |
635 | 951k | TY_(tmbsnprintf)(buf, sizeof(buf), "U+%04X", c); |
636 | 951k | doc->badChars |= BC_INVALID_UTF8; |
637 | 951k | break; |
638 | | |
639 | 733 | case INVALID_UTF16: |
640 | 733 | TY_(tmbsnprintf)(buf, sizeof(buf), "U+%04X", c); |
641 | 733 | doc->badChars |= BC_INVALID_UTF16; |
642 | 733 | break; |
643 | | |
644 | 0 | case VENDOR_SPECIFIC_CHARS: |
645 | 0 | NtoS(c, buf); |
646 | 0 | doc->badChars |= BC_VENDOR_SPECIFIC_CHARS; |
647 | 0 | break; |
648 | | |
649 | 156 | case ENCODING_MISMATCH: |
650 | 156 | doc->badChars |= BC_ENCODING_MISMATCH; |
651 | 156 | return TY_(tidyMessageCreateWithLexer)(doc, |
652 | 156 | code, |
653 | 156 | level, |
654 | 156 | TY_(CharEncodingName)(doc->docIn->encoding), |
655 | 156 | TY_(CharEncodingName)(c)); |
656 | 0 | break; |
657 | 953k | } |
658 | | |
659 | 953k | return TY_(tidyMessageCreateWithLexer)(doc, code, level, action, buf ); |
660 | | |
661 | 953k | } |
662 | | |
663 | | |
664 | | /* Provides general formatting for the majority of Tidy's reports. Because most |
665 | | ** reports use the same basic data derived from the element and node, this |
666 | | ** formatter covers the vast majority of Tidy's report messages. Note that this |
667 | | ** formatter guarantees the values of TidyReportLevel in the dispatchTable[]. |
668 | | ** Some of the cases in this formatter start new contexts from the va_list |
669 | | ** when the required data is simple. For complex local variable needs, it may |
670 | | ** be preferred to write a new formatter. |
671 | | */ |
672 | | TidyMessageImpl *formatStandard(TidyDocImpl* doc, Node *element, Node *node, uint code, uint level, va_list args) |
673 | 5.24M | { |
674 | 5.24M | char nodedesc[ 256 ] = {0}; |
675 | 5.24M | char elemdesc[ 256 ] = {0}; |
676 | 5.24M | Node* rpt = ( element ? element : node ); |
677 | | |
678 | 5.24M | TagToString(node, nodedesc, sizeof(nodedesc)); |
679 | | |
680 | 5.24M | if ( element ) |
681 | 4.95M | TagToString(element, elemdesc, sizeof(elemdesc)); |
682 | | |
683 | 5.24M | switch ( code ) |
684 | 5.24M | { |
685 | 0 | case CUSTOM_TAG_DETECTED: |
686 | 0 | { |
687 | 0 | ctmbstr tagtype; |
688 | 0 | switch ( cfg( doc, TidyUseCustomTags ) ) |
689 | 0 | { |
690 | 0 | case TidyCustomBlocklevel: |
691 | 0 | tagtype = tidyLocalizedString( TIDYCUSTOMBLOCKLEVEL_STRING ); |
692 | 0 | break; |
693 | 0 | case TidyCustomEmpty: |
694 | 0 | tagtype = tidyLocalizedString( TIDYCUSTOMEMPTY_STRING ); |
695 | 0 | break; |
696 | 0 | case TidyCustomInline: |
697 | 0 | tagtype = tidyLocalizedString( TIDYCUSTOMINLINE_STRING ); |
698 | 0 | break; |
699 | 0 | case TidyCustomPre: |
700 | 0 | default: |
701 | 0 | tagtype = tidyLocalizedString( TIDYCUSTOMPRE_STRING ); |
702 | 0 | break; |
703 | 0 | } |
704 | 0 | return TY_(tidyMessageCreateWithNode)(doc, element, code, level, elemdesc, tagtype ); |
705 | 0 | } |
706 | | |
707 | 0 | case STRING_NO_SYSID: |
708 | 0 | return TY_(tidyMessageCreate)( doc, code, level ); |
709 | | |
710 | 0 | case FILE_CANT_OPEN: |
711 | 0 | case FILE_CANT_OPEN_CFG: |
712 | 0 | case FILE_NOT_FILE: |
713 | 20.4k | case STRING_CONTENT_LOOKS: |
714 | 20.5k | case STRING_DOCTYPE_GIVEN: |
715 | 20.5k | case STRING_MISSING_MALFORMED: |
716 | 20.5k | case STRING_MUTING_TYPE: |
717 | 20.5k | { |
718 | 20.5k | ctmbstr str; |
719 | 20.5k | if ( (str = va_arg( args, ctmbstr)) ) |
720 | 20.5k | return TY_(tidyMessageCreate)( doc, code, level, str ); |
721 | | |
722 | 20.5k | } break; |
723 | | |
724 | 0 | case APOS_UNDEFINED: |
725 | 668 | case MISSING_SEMICOLON_NCR: |
726 | 15.4k | case MISSING_SEMICOLON: |
727 | 30.3k | case UNESCAPED_AMPERSAND: |
728 | 55.0k | case UNKNOWN_ENTITY: |
729 | 55.0k | { |
730 | 55.0k | ctmbstr entityname; |
731 | 55.0k | if ( !(entityname = va_arg( args, ctmbstr)) ) |
732 | 0 | { |
733 | 0 | entityname = "NULL"; |
734 | 0 | } |
735 | 55.0k | return TY_(tidyMessageCreateWithLexer)(doc, code, level, entityname); |
736 | 30.3k | } |
737 | | |
738 | 9.36k | case MISSING_ATTRIBUTE: |
739 | 9.36k | { |
740 | 9.36k | ctmbstr name; |
741 | 9.36k | if ( (name = va_arg( args, ctmbstr)) ) |
742 | 9.36k | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, nodedesc, name ); |
743 | 9.36k | } break; |
744 | | |
745 | 0 | case STRING_UNKNOWN_OPTION: |
746 | 0 | case OPTION_REMOVED: |
747 | 0 | { |
748 | 0 | ctmbstr str; |
749 | 0 | if ( (str = va_arg( args, ctmbstr)) ) |
750 | 0 | return TY_(tidyMessageCreateWithLexer)(doc, code, level, str); |
751 | 0 | } break; |
752 | | |
753 | 0 | case OPTION_REMOVED_UNAPPLIED: |
754 | 0 | case STRING_ARGUMENT_BAD: |
755 | 0 | { |
756 | 0 | ctmbstr s1 = va_arg( args, ctmbstr ); |
757 | 0 | ctmbstr s2 = va_arg( args, ctmbstr ); |
758 | 0 | return TY_(tidyMessageCreateWithLexer)(doc, code, level, s1, s2); |
759 | 0 | } |
760 | | |
761 | 0 | case OPTION_REMOVED_APPLIED: |
762 | 0 | { |
763 | 0 | ctmbstr s1 = va_arg( args, ctmbstr ); |
764 | 0 | ctmbstr s2 = va_arg( args, ctmbstr ); |
765 | 0 | ctmbstr s3 = va_arg( args, ctmbstr ); |
766 | 0 | return TY_(tidyMessageCreateWithLexer)(doc, code, level, s1, s2, s3); |
767 | 0 | } |
768 | | |
769 | | |
770 | 1.57k | case BAD_SURROGATE_LEAD: |
771 | 1.76k | case BAD_SURROGATE_PAIR: |
772 | 10.8k | case BAD_SURROGATE_TAIL: |
773 | 10.8k | { |
774 | 10.8k | uint c1 = va_arg( args, uint ); |
775 | 10.8k | uint c2 = va_arg( args, uint ); |
776 | 10.8k | return TY_(tidyMessageCreateWithLexer)(doc, code, level, c1, c2); |
777 | 1.76k | } |
778 | | |
779 | 46 | case SPACE_PRECEDING_XMLDECL: |
780 | | /* @TODO: Should this be a TidyInfo "silent" fix? */ |
781 | 46 | return TY_(tidyMessageCreateWithNode)(doc, node, code, level ); |
782 | | |
783 | 17.4k | case CANT_BE_NESTED: |
784 | 18.2k | case NOFRAMES_CONTENT: |
785 | 22.4k | case USING_BR_INPLACE_OF: |
786 | | /* Can we use `rpt` here? No; `element` has a value in every case. */ |
787 | 22.4k | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, nodedesc ); |
788 | | |
789 | 0 | case ELEMENT_VERS_MISMATCH_ERROR: |
790 | 0 | case ELEMENT_VERS_MISMATCH_WARN: |
791 | 0 | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, nodedesc, HTMLVersion(doc) ); |
792 | | |
793 | 63.9k | case TAG_NOT_ALLOWED_IN: |
794 | | /* Can we use `rpt` here? No; `element` has a value in every case. */ |
795 | 63.9k | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, nodedesc, element ? element->element : NULL ); |
796 | | |
797 | 1.35M | case INSERTING_TAG: |
798 | 1.37M | case MISSING_STARTTAG: |
799 | 1.37M | case TOO_MANY_ELEMENTS: |
800 | 1.37M | case UNEXPECTED_ENDTAG: |
801 | 1.37M | case UNEXPECTED_ENDTAG_ERR: /* generated by XML docs */ |
802 | | /* Can we use `rpt` here? No; `element` has a value in every case. */ |
803 | 1.37M | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, node->element ); |
804 | | |
805 | 0 | case UNEXPECTED_ENDTAG_IN: |
806 | | /* Can we use `rpt` here? No; `element` has a value in every case. */ |
807 | 0 | return TY_(tidyMessageCreateWithNode)(doc, node, code, level, node->element, element ? element->element : NULL ); |
808 | | |
809 | 3.52k | case BAD_CDATA_CONTENT: |
810 | 9.42k | case CONTENT_AFTER_BODY: |
811 | 12.3k | case DOCTYPE_AFTER_TAGS: |
812 | 13.6k | case DUPLICATE_FRAMESET: |
813 | 22.1k | case MALFORMED_COMMENT: |
814 | 26.2k | case MALFORMED_COMMENT_DROPPING: |
815 | 26.3k | case MALFORMED_COMMENT_EOS: |
816 | 26.3k | case MALFORMED_COMMENT_WARN: |
817 | 73.0k | case MALFORMED_DOCTYPE: |
818 | 89.9k | case MISSING_DOCTYPE: |
819 | 110k | case MISSING_TITLE_ELEMENT: |
820 | 137k | case NESTED_QUOTATION: |
821 | 138k | case SUSPECTED_MISSING_QUOTE: |
822 | 138k | case XML_DECLARATION_DETECTED: |
823 | 138k | case BLANK_TITLE_ELEMENT: |
824 | 138k | return TY_(tidyMessageCreateWithNode)(doc, rpt, code, level ); |
825 | | |
826 | 0 | case ELEMENT_NOT_EMPTY: |
827 | 0 | case FOUND_STYLE_IN_BODY: |
828 | 3.50k | case ILLEGAL_NESTING: |
829 | 4.92k | case MOVED_STYLE_TO_HEAD: |
830 | 412k | case TRIM_EMPTY_ELEMENT: |
831 | 412k | case UNEXPECTED_END_OF_FILE: |
832 | 412k | return TY_(tidyMessageCreateWithNode)(doc, rpt, code, level, elemdesc ); |
833 | | |
834 | 2.38k | case OBSOLETE_ELEMENT: |
835 | 9.51k | case REPLACING_ELEMENT: |
836 | 9.51k | case REPLACING_UNEX_ELEMENT: |
837 | 9.51k | return TY_(tidyMessageCreateWithNode)(doc, rpt, code, level, elemdesc, nodedesc ); |
838 | | |
839 | 0 | case ADDED_MISSING_CHARSET: |
840 | 195 | case BAD_SUMMARY_HTML5: |
841 | 8.32k | case NESTED_EMPHASIS: |
842 | 10.5k | case PROPRIETARY_ELEMENT: |
843 | 1.19M | case REMOVED_HTML5: |
844 | 1.30M | case UNKNOWN_ELEMENT: |
845 | 1.30M | case UNKNOWN_ELEMENT_LOOKS_CUSTOM: |
846 | 1.30M | return TY_(tidyMessageCreateWithNode)(doc, rpt, code, level, nodedesc ); |
847 | | |
848 | 1.21M | case MISSING_ENDTAG_FOR: |
849 | 1.22M | case MISSING_ENDTAG_OPTIONAL: |
850 | 1.28M | case PREVIOUS_LOCATION: |
851 | 1.28M | return TY_(tidyMessageCreateWithNode)(doc, rpt, code, level, element? element->element : NULL ); |
852 | | |
853 | 520k | case MISSING_ENDTAG_BEFORE: |
854 | 520k | return TY_(tidyMessageCreateWithNode)(doc, rpt, code, level, element? element->element : NULL, nodedesc ); |
855 | | |
856 | 8.27k | case COERCE_TO_ENDTAG: |
857 | 12.5k | case NON_MATCHING_ENDTAG: |
858 | 12.5k | return TY_(tidyMessageCreateWithNode)(doc, rpt, code, level, node->element, node->element ); |
859 | 2.55k | case TOO_MANY_ELEMENTS_IN: |
860 | 2.55k | return TY_(tidyMessageCreateWithNode)(doc, rpt, code, level, node->element, element ? element->element : NULL); |
861 | | |
862 | 5.24M | } |
863 | | |
864 | 0 | return NULL; |
865 | 5.24M | } |
866 | | |
867 | | |
868 | | /* Provides general formatting as formatStandard, except TidyReportLevel is set |
869 | | ** dynamically for these items as it cannot be predicted except at runtime. |
870 | | */ |
871 | | TidyMessageImpl *formatStandardDynamic(TidyDocImpl* doc, Node *element, Node *node, uint code, uint level, va_list args) |
872 | 190k | { |
873 | 190k | char nodedesc[ 256 ] = {0}; |
874 | | |
875 | 190k | TagToString(node, nodedesc, sizeof(nodedesc)); |
876 | | |
877 | 190k | switch (code) |
878 | 190k | { |
879 | 190k | case DISCARDING_UNEXPECTED: |
880 | | /* Force error if in a bad form, or Issue #166 - repeated <main> element. */ |
881 | | /* Can we use `rpt` here? No; `element` has a value in every case. */ |
882 | 190k | return TY_(tidyMessageCreateWithNode)(doc, node, code, doc->badForm ? TidyError : TidyWarning, nodedesc ); |
883 | 0 | break; |
884 | 190k | } |
885 | | |
886 | 0 | return NULL; |
887 | 190k | } |
888 | | |
889 | | |
890 | | /********************************************************************* |
891 | | * High Level Message Writing Functions |
892 | | * When adding new reports to LibTidy, preference should be given |
893 | | * to one of the existing, general purpose message writing functions |
894 | | * above, if possible, otherwise try to use one of these, or as a |
895 | | * last resort add a new one in this section. |
896 | | *********************************************************************/ |
897 | | |
898 | | |
899 | | /* This function performs the heavy lifting for TY_(Report)(). Critically we |
900 | | ** can accept the va_list needed for recursion. |
901 | | */ |
902 | | static void vReport(TidyDocImpl* doc, Node *element, Node *node, uint code, va_list args) |
903 | 7.08M | { |
904 | 7.08M | int i = 0; |
905 | 7.08M | va_list args_copy; |
906 | | |
907 | 418M | while ( dispatchTable[i].code != 0 ) |
908 | 418M | { |
909 | 418M | if ( dispatchTable[i].code == code ) |
910 | 7.08M | { |
911 | 7.08M | TidyMessageImpl *message; |
912 | 7.08M | messageFormatter *handler = dispatchTable[i].handler; |
913 | 7.08M | TidyReportLevel level = dispatchTable[i].level; |
914 | | |
915 | 7.08M | va_copy(args_copy, args); |
916 | 7.08M | message = handler( doc, element, node, code, level, args_copy ); |
917 | 7.08M | va_end(args_copy); |
918 | | |
919 | 7.08M | messageOut( message ); |
920 | | |
921 | 7.08M | if ( dispatchTable[i].next ) |
922 | 66.5k | { |
923 | 66.5k | va_copy(args_copy, args); |
924 | 66.5k | vReport(doc, element, node, dispatchTable[i].next, args_copy); |
925 | 66.5k | va_end(args_copy); |
926 | 66.5k | } |
927 | 7.08M | break; |
928 | 7.08M | } |
929 | 411M | i++; |
930 | 411M | } |
931 | 7.08M | } |
932 | | |
933 | | |
934 | | /* This single Report output function uses the correct formatter with all |
935 | | ** possible, relevant data that can be reported. The only real drawbacks are |
936 | | ** having to pass NULL when some of the values aren't used, and the lack of |
937 | | ** type safety by using the variable arguments. To counter this some convenience |
938 | | ** report output functions exist, too. Any new reports you wish to create must |
939 | | ** be able to use this function signature, although convenience functions should |
940 | | ** be added to abstract the full function signature and to preserve type safety. |
941 | | */ |
942 | | void TY_(Report)(TidyDocImpl* doc, Node *element, Node *node, uint code, ...) |
943 | 7.01M | { |
944 | 7.01M | va_list args; |
945 | 7.01M | va_start(args, code); |
946 | 7.01M | vReport(doc, element, node, code, args); |
947 | 7.01M | va_end(args); |
948 | 7.01M | } |
949 | | |
950 | | |
951 | | /********************************************************************* |
952 | | * Convenience Reporting Functions |
953 | | * Functions that don't require the full signature of TY_(Report), |
954 | | * and help protect type safety by avoiding variable arguments in the |
955 | | * rest of Tidy's code. |
956 | | *********************************************************************/ |
957 | | |
958 | | void TY_(ReportAccessError)( TidyDocImpl* doc, Node* node, uint code ) |
959 | 0 | { |
960 | 0 | TY_(Report)( doc, NULL, node, code ); |
961 | 0 | } |
962 | | |
963 | | |
964 | | void TY_(ReportAttrError)(TidyDocImpl* doc, Node *node, AttVal *av, uint code) |
965 | 698k | { |
966 | 698k | TY_(Report)( doc, NULL, node, code, av ); |
967 | 698k | } |
968 | | |
969 | | |
970 | | void TY_(ReportBadArgument)( TidyDocImpl* doc, ctmbstr option ) |
971 | 0 | { |
972 | 0 | assert( option != NULL ); |
973 | 0 | TY_(Report)( doc, NULL, NULL, STRING_MISSING_MALFORMED, option ); |
974 | 0 | } |
975 | | |
976 | | |
977 | | void TY_(ReportEntityError)( TidyDocImpl* doc, uint code, ctmbstr entity, int ARG_UNUSED(c) ) |
978 | 55.0k | { |
979 | | /* Note that the report formatter currently doesn't use argument c */ |
980 | 55.0k | TY_(Report)( doc, NULL, NULL, code, entity, c ); |
981 | 55.0k | } |
982 | | |
983 | | |
984 | | void TY_(ReportFileError)( TidyDocImpl* doc, ctmbstr file, uint code ) |
985 | 0 | { |
986 | 0 | TY_(Report)( doc, NULL, NULL, code, file ); |
987 | 0 | } |
988 | | |
989 | | |
990 | | void TY_(ReportEncodingError)(TidyDocImpl* doc, uint code, uint c, Bool discarded) |
991 | 953k | { |
992 | 953k | TY_(Report)( doc, NULL, NULL, code, c, discarded ); |
993 | 953k | } |
994 | | |
995 | | void TY_(ReportEncodingWarning)(TidyDocImpl* doc, uint code, uint encoding) |
996 | 156 | { |
997 | | /* va_list in formatter expects trailing `no` argument */ |
998 | 156 | TY_(Report)( doc, NULL, NULL, code, encoding, no ); |
999 | 156 | } |
1000 | | |
1001 | | |
1002 | | void TY_(ReportMissingAttr)( TidyDocImpl* doc, Node* node, ctmbstr name ) |
1003 | 9.36k | { |
1004 | 9.36k | TY_(Report)( doc, NULL, node, MISSING_ATTRIBUTE, name ); |
1005 | 9.36k | } |
1006 | | |
1007 | | |
1008 | | void TY_(ReportSurrogateError)(TidyDocImpl* doc, uint code, uint c1, uint c2) |
1009 | 10.8k | { |
1010 | 10.8k | TY_(Report)( doc, NULL, NULL, code, c1,c2 ); |
1011 | 10.8k | } |
1012 | | |
1013 | | |
1014 | | void TY_(ReportUnknownOption)( TidyDocImpl* doc, ctmbstr option ) |
1015 | 0 | { |
1016 | | /* lexer is not defined when this is called */ |
1017 | 0 | TY_(Report)( doc, NULL, NULL, STRING_UNKNOWN_OPTION, option ); |
1018 | 0 | } |
1019 | | |
1020 | | |
1021 | | /********************************************************************* |
1022 | | * Dialogue Output Functions |
1023 | | * As for issuing reports, Tidy manages all dialogue output from a |
1024 | | * single source in order to manage message categories in a simple |
1025 | | * an consistent manner. |
1026 | | *********************************************************************/ |
1027 | | |
1028 | | |
1029 | | /* This structure ties together for each dialogue Code the default |
1030 | | ** TidyReportLevel. This it makes it simple to output new dialogue |
1031 | | ** messages, or to change report level by modifying this array. |
1032 | | */ |
1033 | | static struct _dialogueDispatchTable { |
1034 | | uint code; /**< The message code. */ |
1035 | | TidyReportLevel level; /**< The default TidyReportLevel of the message. */ |
1036 | | } dialogueDispatchTable[] = { |
1037 | | { STRING_HELLO_ACCESS, TidyDialogueInfo }, /* AccessibilityChecks() */ |
1038 | | { TEXT_GENERAL_INFO, TidyDialogueInfo }, /* tidyGeneralInfo() */ |
1039 | | { TEXT_GENERAL_INFO_PLEA, TidyDialogueInfo }, /* tidyGeneralInfo() */ |
1040 | | |
1041 | | { STRING_NEEDS_INTERVENTION, TidyDialogueSummary }, /* tidyDocRunDiagnostics() */ |
1042 | | { STRING_ERROR_COUNT, TidyDialogueSummary }, /* ReportNumWarnings() */ |
1043 | | { STRING_NO_ERRORS, TidyDialogueSummary }, /* ReportNumWarnings() */ |
1044 | | { STRING_NOT_ALL_SHOWN, TidyDialogueSummary }, /* ReportNumWarnings() */ |
1045 | | |
1046 | | { FOOTNOTE_TRIM_EMPTY_ELEMENT, TidyDialogueFootnote }, |
1047 | | { TEXT_ACCESS_ADVICE1, TidyDialogueFootnote }, /* errorSummary() */ |
1048 | | { TEXT_ACCESS_ADVICE2, TidyDialogueFootnote }, |
1049 | | { TEXT_BAD_FORM, TidyDialogueFootnote }, |
1050 | | { TEXT_BAD_MAIN, TidyDialogueFootnote }, |
1051 | | { TEXT_HTML_T_ALGORITHM, TidyDialogueFootnote }, |
1052 | | { TEXT_INVALID_URI, TidyDialogueFootnote }, |
1053 | | { TEXT_INVALID_UTF8, TidyDialogueFootnote }, |
1054 | | { TEXT_INVALID_UTF16, TidyDialogueFootnote }, |
1055 | | { TEXT_M_IMAGE_ALT, TidyDialogueFootnote }, |
1056 | | { TEXT_M_IMAGE_MAP, TidyDialogueFootnote }, |
1057 | | { TEXT_M_LINK_ALT, TidyDialogueFootnote }, |
1058 | | { TEXT_M_SUMMARY, TidyDialogueFootnote }, |
1059 | | { TEXT_SGML_CHARS, TidyDialogueFootnote }, |
1060 | | { TEXT_USING_BODY, TidyDialogueFootnote }, |
1061 | | { TEXT_USING_FONT, TidyDialogueFootnote }, |
1062 | | { TEXT_USING_FRAMES, TidyDialogueFootnote }, |
1063 | | { TEXT_USING_LAYER, TidyDialogueFootnote }, |
1064 | | { TEXT_USING_NOBR, TidyDialogueFootnote }, |
1065 | | { TEXT_USING_SPACER, TidyDialogueFootnote }, |
1066 | | { TEXT_VENDOR_CHARS, TidyDialogueFootnote }, |
1067 | | |
1068 | | { 0, 0 } |
1069 | | }; |
1070 | | |
1071 | | |
1072 | | /* This message formatter for dialogue messages should be capable of formatting |
1073 | | ** every message, because they're not all that complex and there aren't that |
1074 | | ** many. |
1075 | | */ |
1076 | | static TidyMessageImpl *formatDialogue( TidyDocImpl* doc, uint code, TidyReportLevel level, va_list args ) |
1077 | 25.9k | { |
1078 | 25.9k | switch (code) |
1079 | 25.9k | { |
1080 | 0 | case TEXT_SGML_CHARS: |
1081 | 0 | case TEXT_VENDOR_CHARS: |
1082 | 0 | { |
1083 | 0 | ctmbstr str = va_arg(args, ctmbstr); |
1084 | 0 | return TY_(tidyMessageCreate)( doc, code, level, str ); |
1085 | 0 | } |
1086 | | |
1087 | 19.0k | case STRING_ERROR_COUNT: |
1088 | 20.4k | case STRING_NOT_ALL_SHOWN: |
1089 | 20.4k | return TY_(tidyMessageCreate)( doc, code, level, |
1090 | 20.4k | doc->warnings, "STRING_ERROR_COUNT_WARNING", |
1091 | 20.4k | doc->errors, "STRING_ERROR_COUNT_ERROR" ); |
1092 | | |
1093 | 0 | case FOOTNOTE_TRIM_EMPTY_ELEMENT: |
1094 | 0 | case STRING_HELLO_ACCESS: |
1095 | 5.53k | case STRING_NEEDS_INTERVENTION: |
1096 | 5.53k | case STRING_NO_ERRORS: |
1097 | 5.53k | case TEXT_ACCESS_ADVICE1: |
1098 | 5.53k | case TEXT_ACCESS_ADVICE2: |
1099 | 5.53k | case TEXT_BAD_FORM: |
1100 | 5.53k | case TEXT_BAD_MAIN: |
1101 | 5.53k | case TEXT_GENERAL_INFO: |
1102 | 5.53k | case TEXT_GENERAL_INFO_PLEA: |
1103 | 5.53k | case TEXT_HTML_T_ALGORITHM: |
1104 | 5.53k | case TEXT_INVALID_URI: |
1105 | 5.53k | case TEXT_INVALID_UTF8: |
1106 | 5.53k | case TEXT_INVALID_UTF16: |
1107 | 5.53k | case TEXT_M_IMAGE_ALT: |
1108 | 5.53k | case TEXT_M_IMAGE_MAP: |
1109 | 5.53k | case TEXT_M_LINK_ALT: |
1110 | 5.53k | case TEXT_M_SUMMARY: |
1111 | 5.53k | case TEXT_USING_BODY: |
1112 | 5.53k | case TEXT_USING_FONT: |
1113 | 5.53k | case TEXT_USING_FRAMES: |
1114 | 5.53k | case TEXT_USING_LAYER: |
1115 | 5.53k | case TEXT_USING_NOBR: |
1116 | 5.53k | case TEXT_USING_SPACER: |
1117 | 5.53k | default: |
1118 | 5.53k | return TY_(tidyMessageCreate)( doc, code, level ); |
1119 | 25.9k | } |
1120 | | |
1121 | 0 | return NULL; |
1122 | 25.9k | } |
1123 | | |
1124 | | |
1125 | | /* This single Dialogue output function determines the correct message level |
1126 | | ** and formats the message with the appropriate formatter, and then outputs it. |
1127 | | ** This one dialogue function should be sufficient for every use case. |
1128 | | */ |
1129 | | void TY_(Dialogue)(TidyDocImpl* doc, uint code, ...) |
1130 | 25.9k | { |
1131 | 25.9k | int i = 0; |
1132 | 25.9k | va_list args; |
1133 | | |
1134 | 127k | while ( dialogueDispatchTable[i].code != 0 ) |
1135 | 127k | { |
1136 | 127k | if ( dialogueDispatchTable[i].code == code ) |
1137 | 25.9k | { |
1138 | 25.9k | TidyMessageImpl *message; |
1139 | 25.9k | TidyReportLevel level = dialogueDispatchTable[i].level; |
1140 | 25.9k | va_start(args, code); |
1141 | 25.9k | message = formatDialogue( doc, code, level, args ); |
1142 | 25.9k | va_end(args); |
1143 | 25.9k | messageOut( message ); |
1144 | 25.9k | break; |
1145 | 25.9k | } |
1146 | 101k | i++; |
1147 | 101k | } |
1148 | 25.9k | } |
1149 | | |
1150 | | |
1151 | | /********************************************************************* |
1152 | | * Output Dialogue Information |
1153 | | * In addition to reports that are added to the table, Tidy emits |
1154 | | * various dialogue type information. Most of these are specific to |
1155 | | * exact circumstances, although `TY_(Dialogue)` should be used |
1156 | | * instead of adding a new function, if possible. |
1157 | | *********************************************************************/ |
1158 | | |
1159 | | |
1160 | | /* Outputs the footnotes and other dialogue information after document cleanup |
1161 | | ** is complete. LibTidy users might consider capturing these individually in |
1162 | | ** the message callback rather than capturing this entire buffer. |
1163 | | ** Called by tidyErrorSummary(), in console. |
1164 | | ** @todo: This name is a bit misleading and should probably be renamed to |
1165 | | ** indicate its focus on printing footnotes. |
1166 | | */ |
1167 | | void TY_(ErrorSummary)( TidyDocImpl* doc ) |
1168 | 0 | { |
1169 | 0 | ctmbstr encnam = tidyLocalizedString(STRING_SPECIFIED); |
1170 | 0 | int charenc = cfg( doc, TidyCharEncoding ); |
1171 | 0 | if ( charenc == WIN1252 ) |
1172 | 0 | encnam = "Windows-1252"; |
1173 | 0 | else if ( charenc == MACROMAN ) |
1174 | 0 | encnam = "MacRoman"; |
1175 | 0 | else if ( charenc == IBM858 ) |
1176 | 0 | encnam = "ibm858"; |
1177 | 0 | else if ( charenc == LATIN0 ) |
1178 | 0 | encnam = "latin0"; |
1179 | | |
1180 | | /* adjust badAccess to that it is 0 if frames are ok */ |
1181 | 0 | if ( doc->badAccess & (BA_USING_FRAMES | BA_USING_NOFRAMES) ) |
1182 | 0 | { |
1183 | 0 | if (!((doc->badAccess & BA_USING_FRAMES) && !(doc->badAccess & BA_USING_NOFRAMES))) |
1184 | 0 | { |
1185 | 0 | doc->badAccess &= ~(BA_USING_FRAMES | BA_USING_NOFRAMES); |
1186 | 0 | } |
1187 | 0 | } |
1188 | |
|
1189 | 0 | if (doc->badChars) |
1190 | 0 | { |
1191 | 0 | if (doc->badChars & BC_VENDOR_SPECIFIC_CHARS) |
1192 | 0 | TY_(Dialogue)( doc, TEXT_VENDOR_CHARS, encnam ); |
1193 | |
|
1194 | 0 | if ((doc->badChars & BC_INVALID_SGML_CHARS) || (doc->badChars & BC_INVALID_NCR)) |
1195 | 0 | TY_(Dialogue)( doc, TEXT_SGML_CHARS, encnam ); |
1196 | |
|
1197 | 0 | if (doc->badChars & BC_INVALID_UTF8) |
1198 | 0 | TY_(Dialogue)( doc, TEXT_INVALID_UTF8 ); |
1199 | |
|
1200 | 0 | if (doc->badChars & BC_INVALID_UTF16) |
1201 | 0 | TY_(Dialogue)( doc, TEXT_INVALID_UTF16 ); |
1202 | |
|
1203 | 0 | if (doc->badChars & BC_INVALID_URI) |
1204 | 0 | TY_(Dialogue)( doc, TEXT_INVALID_URI ); |
1205 | 0 | } |
1206 | | |
1207 | 0 | if (doc->badForm) |
1208 | 0 | { |
1209 | 0 | if (doc->badForm & flg_BadForm) /* Issue #166 - changed to BIT flag to support other errors */ |
1210 | 0 | TY_(Dialogue)( doc, TEXT_BAD_FORM ); |
1211 | |
|
1212 | 0 | if (doc->badForm & flg_BadMain) /* Issue #166 - repeated <main> element */ |
1213 | 0 | TY_(Dialogue)( doc, TEXT_BAD_MAIN ); |
1214 | 0 | } |
1215 | |
|
1216 | 0 | if (doc->badAccess) |
1217 | 0 | { |
1218 | | /* Tidy "classic" accessibility tests */ |
1219 | 0 | if ( cfg(doc, TidyAccessibilityCheckLevel) == 0 ) |
1220 | 0 | { |
1221 | 0 | if (doc->badAccess & BA_MISSING_SUMMARY) |
1222 | 0 | TY_(Dialogue)( doc, TEXT_M_SUMMARY ); |
1223 | |
|
1224 | 0 | if (doc->badAccess & BA_MISSING_IMAGE_ALT) |
1225 | 0 | TY_(Dialogue)( doc, TEXT_M_IMAGE_ALT ); |
1226 | |
|
1227 | 0 | if (doc->badAccess & BA_MISSING_IMAGE_MAP) |
1228 | 0 | TY_(Dialogue)( doc, TEXT_M_IMAGE_MAP ); |
1229 | |
|
1230 | 0 | if (doc->badAccess & BA_MISSING_LINK_ALT) |
1231 | 0 | TY_(Dialogue)( doc, TEXT_M_LINK_ALT ); |
1232 | |
|
1233 | 0 | if ((doc->badAccess & BA_USING_FRAMES) && !(doc->badAccess & BA_USING_NOFRAMES)) |
1234 | 0 | TY_(Dialogue)( doc, TEXT_USING_FRAMES ); |
1235 | 0 | } |
1236 | |
|
1237 | 0 | if ( cfg(doc, TidyAccessibilityCheckLevel) > 0 ) |
1238 | 0 | TY_(Dialogue)( doc, TEXT_ACCESS_ADVICE2 ); |
1239 | 0 | else |
1240 | 0 | TY_(Dialogue)( doc, TEXT_ACCESS_ADVICE1 ); |
1241 | 0 | } |
1242 | |
|
1243 | 0 | if (doc->badLayout) |
1244 | 0 | { |
1245 | 0 | if (doc->badLayout & USING_LAYER) |
1246 | 0 | TY_(Dialogue)( doc, TEXT_USING_LAYER ); |
1247 | |
|
1248 | 0 | if (doc->badLayout & USING_SPACER) |
1249 | 0 | TY_(Dialogue)( doc, TEXT_USING_SPACER ); |
1250 | |
|
1251 | 0 | if (doc->badLayout & USING_FONT) |
1252 | 0 | TY_(Dialogue)( doc, TEXT_USING_FONT ); |
1253 | |
|
1254 | 0 | if (doc->badLayout & USING_NOBR) |
1255 | 0 | TY_(Dialogue)( doc, TEXT_USING_NOBR ); |
1256 | | |
1257 | 0 | if (doc->badLayout & USING_BODY) |
1258 | 0 | TY_(Dialogue)( doc, TEXT_USING_BODY ); |
1259 | 0 | } |
1260 | | |
1261 | 0 | if (doc->footnotes) |
1262 | 0 | { |
1263 | 0 | if (doc->footnotes & FN_TRIM_EMPTY_ELEMENT) |
1264 | 0 | TY_(Dialogue)( doc, FOOTNOTE_TRIM_EMPTY_ELEMENT ); |
1265 | 0 | } |
1266 | 0 | } |
1267 | | |
1268 | | |
1269 | | /* Outputs document HTML version and version-related information. |
1270 | | ** Called by tidyRunDiagnostics(), from console. |
1271 | | ** Called by tidyDocReportDoctype(), currently unused. |
1272 | | */ |
1273 | | void TY_(ReportMarkupVersion)( TidyDocImpl* doc ) |
1274 | 20.4k | { |
1275 | 20.4k | if ( doc->givenDoctype ) |
1276 | 80 | TY_(Report)( doc, NULL, NULL, STRING_DOCTYPE_GIVEN, doc->givenDoctype ); |
1277 | | |
1278 | 20.4k | if ( ! cfgBool(doc, TidyXmlTags) ) |
1279 | 20.4k | { |
1280 | 20.4k | Bool isXhtml = doc->lexer->isvoyager; |
1281 | 20.4k | uint apparentVers = TY_(ApparentVersion)( doc ); |
1282 | 20.4k | ctmbstr vers = TY_(HTMLVersionNameFromCode)( apparentVers, isXhtml ); |
1283 | | |
1284 | 20.4k | if ( !vers ) |
1285 | 76 | vers = tidyLocalizedString(STRING_HTML_PROPRIETARY); |
1286 | | |
1287 | 20.4k | TY_(Report)( doc, NULL, NULL, STRING_CONTENT_LOOKS, vers ); |
1288 | | |
1289 | | /* Warn about missing system identifier (SI) in emitted doctype */ |
1290 | 20.4k | if ( TY_(WarnMissingSIInEmittedDocType)( doc ) ) |
1291 | 0 | TY_(Report)( doc, NULL, NULL, STRING_NO_SYSID ); |
1292 | 20.4k | } |
1293 | 20.4k | } |
1294 | | |
1295 | | |
1296 | | /* Reports the number of warnings and errors found in the document. |
1297 | | ** Called by tidyRunDiagnostics(), from console. |
1298 | | */ |
1299 | | void TY_(ReportNumWarnings)( TidyDocImpl* doc ) |
1300 | 20.4k | { |
1301 | 20.4k | if ( doc->warnings > 0 || doc->errors > 0 ) |
1302 | 20.4k | { |
1303 | 20.4k | if ( doc->errors > cfg(doc, TidyShowErrors) || !cfgBool(doc, TidyShowWarnings) ) |
1304 | 1.36k | { |
1305 | 1.36k | TY_(Dialogue)( doc, STRING_NOT_ALL_SHOWN ); |
1306 | 1.36k | } |
1307 | 19.0k | else |
1308 | 19.0k | { |
1309 | 19.0k | TY_(Dialogue)( doc, STRING_ERROR_COUNT ); |
1310 | 19.0k | } |
1311 | | |
1312 | 20.4k | } |
1313 | 1 | else |
1314 | 1 | { |
1315 | 1 | TY_(Dialogue)( doc, STRING_NO_ERRORS ); |
1316 | 1 | } |
1317 | 20.4k | } |
1318 | | |
1319 | | |
1320 | | /********************************************************************* |
1321 | | * Message Muting |
1322 | | *********************************************************************/ |
1323 | | |
1324 | | |
1325 | | void TY_(FreeMutedMessageList)( TidyDocImpl* doc ) |
1326 | 20.4k | { |
1327 | 20.4k | TidyMutedMessages *list = &(doc->muted); |
1328 | | |
1329 | 20.4k | if ( list->list ) |
1330 | 0 | TidyFree( doc->allocator, list->list ); |
1331 | 20.4k | } |
1332 | | |
1333 | | |
1334 | | void TY_(DefineMutedMessage)(TidyDocImpl* doc, const TidyOptionImpl* opt, ctmbstr name) |
1335 | 0 | { |
1336 | 0 | enum { capacity = 10 }; |
1337 | 0 | TidyMutedMessages *list = &(doc->muted); |
1338 | 0 | tidyStrings message = TY_(tidyErrorCodeFromKey)( name ); |
1339 | |
|
1340 | 0 | if ( message <= REPORT_MESSAGE_FIRST || message >= REPORT_MESSAGE_LAST) |
1341 | 0 | { |
1342 | 0 | TY_(Report)( doc, NULL, NULL, STRING_ARGUMENT_BAD, opt->name, name ); |
1343 | 0 | return; |
1344 | 0 | } |
1345 | | |
1346 | 0 | if ( !list->list ) |
1347 | 0 | { |
1348 | 0 | list->list = TidyAlloc(doc->allocator, sizeof(tidyStrings) * capacity ); |
1349 | 0 | list->list[0] = 0; |
1350 | 0 | list->capacity = capacity; |
1351 | 0 | list->count = 0; |
1352 | 0 | } |
1353 | |
|
1354 | 0 | if ( list->count >= list->capacity ) |
1355 | 0 | { |
1356 | 0 | list->capacity = list->capacity * 2; |
1357 | 0 | list->list = TidyRealloc(doc->allocator, list->list, sizeof(tidyStrings) * list->capacity + 1 ); |
1358 | 0 | } |
1359 | |
|
1360 | 0 | list->list[list->count] = message; |
1361 | 0 | list->count++; |
1362 | 0 | list->list[list->count] = 0; |
1363 | | |
1364 | | /* Must come *after* adding to the list, in case it's muted, too. */ |
1365 | 0 | TY_(Report)( doc, NULL, NULL, STRING_MUTING_TYPE, name ); |
1366 | 0 | } |
1367 | | |
1368 | | |
1369 | | TidyIterator TY_(getMutedMessageList)( TidyDocImpl* doc ) |
1370 | 0 | { |
1371 | 0 | TidyMutedMessages *list = &(doc->muted); |
1372 | 0 | size_t result = list->count > 0 ? 1 : 0; |
1373 | |
|
1374 | 0 | return (TidyIterator) result; |
1375 | 0 | } |
1376 | | |
1377 | | |
1378 | | ctmbstr TY_(getNextMutedMessage)( TidyDocImpl* doc, TidyIterator* iter ) |
1379 | 0 | { |
1380 | 0 | TidyMutedMessages *list = &(doc->muted); |
1381 | 0 | size_t index; |
1382 | 0 | ctmbstr result = NULL; |
1383 | 0 | assert( iter != NULL ); |
1384 | 0 | index = (size_t)*iter; |
1385 | |
|
1386 | 0 | if ( index > 0 && index <= list->count ) |
1387 | 0 | { |
1388 | 0 | result = TY_(tidyErrorCodeAsKey)(list->list[index-1]); |
1389 | 0 | index++; |
1390 | 0 | } |
1391 | 0 | *iter = (TidyIterator) ( index <= list->count ? index : (size_t)0 ); |
1392 | |
|
1393 | 0 | return result; |
1394 | 0 | } |
1395 | | |
1396 | | |
1397 | | /********************************************************************* |
1398 | | * Key Discovery |
1399 | | *********************************************************************/ |
1400 | | |
1401 | | |
1402 | | /********************************************************************* |
1403 | | * LibTidy users may want to to enable their own localization lookup |
1404 | | * lookup methods. Because Tidy's errors codes are enums, the actual |
1405 | | * values can change over time. This table will the LibTidy users |
1406 | | * always have a static value available for use. |
1407 | | * |
1408 | | * For macro documentation, refer to the comments in `tidyenum.h`. |
1409 | | *********************************************************************/ |
1410 | | |
1411 | | typedef struct tidyStringsKeyItem { |
1412 | | ctmbstr key; |
1413 | | int value; |
1414 | | } tidyStringsKeyItem; |
1415 | | |
1416 | | static const tidyStringsKeyItem tidyStringsKeys[] = { |
1417 | | FOREACH_TIDYCONFIGCATEGORY(MAKE_STRUCT) |
1418 | | FOREACH_MSG_MISC(MAKE_STRUCT) |
1419 | | FOREACH_FOOTNOTE_MSG(MAKE_STRUCT) |
1420 | | FOREACH_DIALOG_MSG(MAKE_STRUCT) |
1421 | | FOREACH_REPORT_MSG(MAKE_STRUCT) |
1422 | | FOREACH_ACCESS_MSG(MAKE_STRUCT) |
1423 | | #if SUPPORT_CONSOLE_APP |
1424 | | FOREACH_MSG_CONSOLE(MAKE_STRUCT) |
1425 | | #endif |
1426 | | { "TIDYSTRINGS_FIRST", TIDYSTRINGS_FIRST }, |
1427 | | { "TIDYSTRINGS_LAST", TIDYSTRINGS_LAST }, |
1428 | | { NULL, 0 }, |
1429 | | }; |
1430 | | |
1431 | | |
1432 | | /** |
1433 | | * Given an error code, return the string associated with it. |
1434 | | */ |
1435 | | ctmbstr TY_(tidyErrorCodeAsKey)(uint code) |
1436 | 7.11M | { |
1437 | 7.11M | uint i = 0; |
1438 | 816M | while (tidyStringsKeys[i].key) { |
1439 | 816M | if ( tidyStringsKeys[i].value == code ) |
1440 | 7.11M | return tidyStringsKeys[i].key; |
1441 | 809M | i++; |
1442 | 809M | } |
1443 | 0 | return "UNDEFINED"; |
1444 | 7.11M | } |
1445 | | |
1446 | | |
1447 | | /** |
1448 | | * Given an error code string, return its uint. |
1449 | | */ |
1450 | | uint TY_(tidyErrorCodeFromKey)(ctmbstr code) |
1451 | 0 | { |
1452 | 0 | uint i = 0; |
1453 | 0 | while (tidyStringsKeys[i].key) { |
1454 | 0 | if ( strcmp(tidyStringsKeys[i].key, code) == 0 ) |
1455 | 0 | return tidyStringsKeys[i].value; |
1456 | 0 | i++; |
1457 | 0 | } |
1458 | 0 | return UINT_MAX; |
1459 | 0 | } |
1460 | | |
1461 | | |
1462 | | /** |
1463 | | * Determines the number of error codes used by Tidy. |
1464 | | */ |
1465 | | static const uint tidyErrorCodeListSize() |
1466 | 0 | { |
1467 | 0 | static uint array_size = 0; |
1468 | | |
1469 | 0 | if ( array_size == 0 ) |
1470 | 0 | { |
1471 | 0 | while ( tidyStringsKeys[array_size].key ) { |
1472 | 0 | array_size++; |
1473 | 0 | } |
1474 | 0 | } |
1475 | | |
1476 | 0 | return array_size; |
1477 | 0 | } |
1478 | | |
1479 | | /** |
1480 | | * Initializes the TidyIterator to point to the first item |
1481 | | * in Tidy's list of error codes. Individual items must be |
1482 | | * retrieved with getNextErrorCode(); |
1483 | | */ |
1484 | | TidyIterator TY_(getErrorCodeList)() |
1485 | 0 | { |
1486 | 0 | return (TidyIterator)(size_t)1; |
1487 | 0 | } |
1488 | | |
1489 | | /** |
1490 | | * Returns the next error code. |
1491 | | */ |
1492 | | uint TY_(getNextErrorCode)( TidyIterator* iter ) |
1493 | 0 | { |
1494 | 0 | const tidyStringsKeyItem *item = NULL; |
1495 | 0 | size_t itemIndex; |
1496 | 0 | assert( iter != NULL ); |
1497 | | |
1498 | 0 | itemIndex = (size_t)*iter; |
1499 | | |
1500 | 0 | if ( itemIndex > 0 && itemIndex <= tidyErrorCodeListSize() ) |
1501 | 0 | { |
1502 | 0 | item = &tidyStringsKeys[itemIndex - 1]; |
1503 | 0 | itemIndex++; |
1504 | 0 | } |
1505 | | |
1506 | 0 | *iter = (TidyIterator)( itemIndex <= tidyErrorCodeListSize() ? itemIndex : (size_t)0 ); |
1507 | 0 | return item ? item->value : 0; |
1508 | 0 | } |
1509 | | |
1510 | | |
1511 | | /********************************************************************* |
1512 | | * Documentation of configuration options |
1513 | | * |
1514 | | * Although most of the strings now come from the language module, |
1515 | | * generating the documentation by the console application requires a |
1516 | | * series of cross-references that are generated in this messaging |
1517 | | * module. |
1518 | | *********************************************************************/ |
1519 | | |
1520 | | |
1521 | | #if SUPPORT_CONSOLE_APP |
1522 | | /* Cross-references definitions. |
1523 | | * Note that each list must be terminated with `TidyUnknownOption`. |
1524 | | */ |
1525 | | static const TidyOptionId TidyAsciiCharsLinks[] = { TidyMakeClean, TidyUnknownOption }; |
1526 | | static const TidyOptionId TidyBlockTagsLinks[] = { TidyEmptyTags, TidyInlineTags, TidyPreTags, TidyUseCustomTags, TidyUnknownOption }; |
1527 | | static const TidyOptionId TidyCharEncodingLinks[] = { TidyInCharEncoding, TidyOutCharEncoding, TidyUnknownOption }; |
1528 | | static const TidyOptionId TidyDuplicateAttrsLinks[] = { TidyJoinClasses, TidyJoinStyles, TidyUnknownOption }; |
1529 | | static const TidyOptionId TidyEmacsLinks[] = { TidyShowFilename, TidyUnknownOption }; |
1530 | | static const TidyOptionId TidyEmptyTagsLinks[] = { TidyBlockTags, TidyInlineTags, TidyPreTags, TidyUseCustomTags, TidyUnknownOption }; |
1531 | | static const TidyOptionId TidyErrFileLinks[] = { TidyOutFile, TidyUnknownOption }; |
1532 | | static const TidyOptionId TidyInCharEncodingLinks[] = { TidyCharEncoding, TidyUnknownOption }; |
1533 | | static const TidyOptionId TidyIndentContentLinks[] = { TidyIndentSpaces, TidyUnknownOption }; |
1534 | | static const TidyOptionId TidyIndentSpacesLinks[] = { TidyIndentContent, TidyUnknownOption }; |
1535 | | static const TidyOptionId TidyInlineTagsLinks[] = { TidyBlockTags, TidyEmptyTags, TidyPreTags, TidyUseCustomTags, TidyUnknownOption }; |
1536 | | static const TidyOptionId TidyMergeDivsLinks[] = { TidyMakeClean, TidyMergeSpans, TidyUnknownOption }; |
1537 | | static const TidyOptionId TidyMergeSpansLinks[] = { TidyMakeClean, TidyMergeDivs, TidyUnknownOption }; |
1538 | | static const TidyOptionId TidyMuteLinks[] = { TidyMuteShow, TidyUnknownOption }; |
1539 | | static const TidyOptionId TidyMuteShowLinks[] = { TidyMuteReports, TidyUnknownOption }; |
1540 | | static const TidyOptionId TidyNumEntitiesLinks[] = { TidyDoctype, TidyPreserveEntities, TidyUnknownOption }; |
1541 | | static const TidyOptionId TidyOutCharEncodingLinks[] = { TidyCharEncoding, TidyUnknownOption }; |
1542 | | static const TidyOptionId TidyOutFileLinks[] = { TidyErrFile, TidyUnknownOption }; |
1543 | | static const TidyOptionId TidyPreTagsLinks[] = { TidyBlockTags, TidyEmptyTags, TidyInlineTags, TidyUseCustomTags, TidyUnknownOption }; |
1544 | | static const TidyOptionId TidyShowFilenameLinks[] = { TidyEmacs, TidyUnknownOption }; |
1545 | | static const TidyOptionId TidySortAttributesLinks[] = { TidyPriorityAttributes, TidyUnknownOption }; |
1546 | | static const TidyOptionId TidyUseCustomTagsLinks[] = { TidyBlockTags, TidyEmptyTags, TidyInlineTags, TidyPreTags, TidyUnknownOption }; |
1547 | | static const TidyOptionId TidyWrapAttValsLinks[] = { TidyWrapScriptlets, TidyLiteralAttribs, TidyUnknownOption }; |
1548 | | static const TidyOptionId TidyWrapScriptletsLinks[] = { TidyWrapAttVals, TidyUnknownOption }; |
1549 | | static const TidyOptionId TidyXmlDeclLinks[] = { TidyCharEncoding, TidyOutCharEncoding, TidyUnknownOption }; |
1550 | | |
1551 | | /* Cross-reference assignments. |
1552 | | * We can't build a complex array at compile time and we're not counting on |
1553 | | * any type of initialization, so this two-stage building process is required. |
1554 | | */ |
1555 | | static const TidyOptionDoc docs_xrefs[] = |
1556 | | { |
1557 | | { TidyAsciiChars, TidyAsciiCharsLinks }, |
1558 | | { TidyBlockTags, TidyBlockTagsLinks }, |
1559 | | { TidyCharEncoding, TidyCharEncodingLinks }, |
1560 | | { TidyDuplicateAttrs, TidyDuplicateAttrsLinks }, |
1561 | | { TidyEmacs, TidyEmacsLinks }, |
1562 | | { TidyEmptyTags, TidyEmptyTagsLinks }, |
1563 | | { TidyErrFile, TidyErrFileLinks }, |
1564 | | { TidyInCharEncoding, TidyInCharEncodingLinks }, |
1565 | | { TidyIndentContent, TidyIndentContentLinks }, |
1566 | | { TidyIndentSpaces, TidyIndentSpacesLinks }, |
1567 | | { TidyInlineTags, TidyInlineTagsLinks }, |
1568 | | { TidyMergeDivs, TidyMergeDivsLinks }, |
1569 | | { TidyMergeSpans, TidyMergeSpansLinks }, |
1570 | | { TidyMuteShow, TidyMuteShowLinks }, |
1571 | | { TidyNumEntities, TidyNumEntitiesLinks }, |
1572 | | { TidyOutCharEncoding, TidyOutCharEncodingLinks }, |
1573 | | { TidyOutFile, TidyOutFileLinks }, |
1574 | | { TidyPreTags, TidyPreTagsLinks }, |
1575 | | { TidyShowFilename, TidyShowFilenameLinks }, |
1576 | | { TidySortAttributes, TidySortAttributesLinks }, |
1577 | | { TidyMuteReports, TidyMuteLinks }, |
1578 | | { TidyUseCustomTags, TidyUseCustomTagsLinks }, |
1579 | | { TidyWrapAttVals, TidyWrapAttValsLinks }, |
1580 | | { TidyWrapScriptlets, TidyWrapScriptletsLinks }, |
1581 | | { TidyXmlDecl, TidyXmlDeclLinks }, |
1582 | | { N_TIDY_OPTIONS } |
1583 | | }; |
1584 | | |
1585 | | |
1586 | | /* Cross-reference retrieval. */ |
1587 | | const TidyOptionDoc* TY_(OptGetDocDesc)( TidyOptionId optId ) |
1588 | 0 | { |
1589 | 0 | uint i = 0; |
1590 | |
|
1591 | 0 | while( docs_xrefs[i].opt != N_TIDY_OPTIONS ) |
1592 | 0 | { |
1593 | 0 | if ( docs_xrefs[i].opt == optId ) |
1594 | 0 | return &docs_xrefs[i]; |
1595 | 0 | ++i; |
1596 | 0 | } |
1597 | 0 | return NULL; |
1598 | 0 | } |
1599 | | |
1600 | | #endif /* SUPPORT_CONSOLE_APP */ |
1601 | | |
1602 | | |
1603 | | /* |
1604 | | * local variables: |
1605 | | * mode: c |
1606 | | * indent-tabs-mode: nil |
1607 | | * c-basic-offset: 4 |
1608 | | * eval: (c-set-offset 'substatement-open 0) |
1609 | | * end: |
1610 | | */ |