xml-support.c: Use std::string for growing string buffer
[deliverable/binutils-gdb.git] / gdb / xml-support.c
1 /* Helper routines for parsing XML using Expat.
2
3 Copyright (C) 2006-2017 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "defs.h"
21 #include "gdbcmd.h"
22 #include "xml-support.h"
23 #include "filestuff.h"
24 #include "safe-ctype.h"
25 #include <vector>
26 #include <string>
27
28 /* Debugging flag. */
29 static int debug_xml;
30
31 /* The contents of this file are only useful if XML support is
32 available. */
33 #ifdef HAVE_LIBEXPAT
34
35 #include "gdb_expat.h"
36
37 /* The maximum depth of <xi:include> nesting. No need to be miserly,
38 we just want to avoid running out of stack on loops. */
39 #define MAX_XINCLUDE_DEPTH 30
40
41 /* Simplified XML parser infrastructure. */
42
43 /* A parsing level -- used to keep track of the current element
44 nesting. */
45 struct scope_level
46 {
47 explicit scope_level (const gdb_xml_element *elements_ = NULL)
48 : elements (elements_),
49 element (NULL),
50 seen (0)
51 {}
52
53 /* Elements we allow at this level. */
54 const struct gdb_xml_element *elements;
55
56 /* The element which we are within. */
57 const struct gdb_xml_element *element;
58
59 /* Mask of which elements we've seen at this level (used for
60 optional and repeatable checking). */
61 unsigned int seen;
62
63 /* Body text accumulation. */
64 std::string body;
65 };
66
67 /* The parser itself, and our additional state. */
68 struct gdb_xml_parser
69 {
70 gdb_xml_parser (const char *name,
71 const gdb_xml_element *elements,
72 void *user_data);
73 ~gdb_xml_parser();
74
75 XML_Parser expat_parser; /* The underlying expat parser. */
76
77 const char *name; /* Name of this parser. */
78 void *user_data; /* The user's callback data, for handlers. */
79
80 /* Scoping stack. */
81 std::vector<scope_level> scopes;
82
83 struct gdb_exception error; /* A thrown error, if any. */
84 int last_line; /* The line of the thrown error, or 0. */
85
86 const char *dtd_name; /* The name of the expected / default DTD,
87 if specified. */
88 bool is_xinclude; /* Are we the special <xi:include> parser? */
89 };
90
91 /* Process some body text. We accumulate the text for later use; it's
92 wrong to do anything with it immediately, because a single block of
93 text might be broken up into multiple calls to this function. */
94
95 static void
96 gdb_xml_body_text (void *data, const XML_Char *text, int length)
97 {
98 struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;
99
100 if (parser->error.reason < 0)
101 return;
102
103 scope_level &scope = parser->scopes.back ();
104 scope.body.append (text, length);
105 }
106
107 /* Issue a debugging message from one of PARSER's handlers. */
108
109 void
110 gdb_xml_debug (struct gdb_xml_parser *parser, const char *format, ...)
111 {
112 int line = XML_GetCurrentLineNumber (parser->expat_parser);
113 va_list ap;
114 char *message;
115
116 if (!debug_xml)
117 return;
118
119 va_start (ap, format);
120 message = xstrvprintf (format, ap);
121 if (line)
122 fprintf_unfiltered (gdb_stderr, "%s (line %d): %s\n",
123 parser->name, line, message);
124 else
125 fprintf_unfiltered (gdb_stderr, "%s: %s\n",
126 parser->name, message);
127 xfree (message);
128 }
129
130 /* Issue an error message from one of PARSER's handlers, and stop
131 parsing. */
132
133 void
134 gdb_xml_error (struct gdb_xml_parser *parser, const char *format, ...)
135 {
136 int line = XML_GetCurrentLineNumber (parser->expat_parser);
137 va_list ap;
138
139 parser->last_line = line;
140 va_start (ap, format);
141 throw_verror (XML_PARSE_ERROR, format, ap);
142 }
143
144 /* Find the attribute named NAME in the set of parsed attributes
145 ATTRIBUTES. Returns NULL if not found. */
146
147 struct gdb_xml_value *
148 xml_find_attribute (VEC(gdb_xml_value_s) *attributes, const char *name)
149 {
150 struct gdb_xml_value *value;
151 int ix;
152
153 for (ix = 0; VEC_iterate (gdb_xml_value_s, attributes, ix, value); ix++)
154 if (strcmp (value->name, name) == 0)
155 return value;
156
157 return NULL;
158 }
159
160 /* Clean up a vector of parsed attribute values. */
161
162 static void
163 gdb_xml_values_cleanup (void *data)
164 {
165 VEC(gdb_xml_value_s) **values = (VEC(gdb_xml_value_s) **) data;
166 struct gdb_xml_value *value;
167 int ix;
168
169 for (ix = 0; VEC_iterate (gdb_xml_value_s, *values, ix, value); ix++)
170 xfree (value->value);
171 VEC_free (gdb_xml_value_s, *values);
172 }
173
174 /* Handle the start of an element. DATA is our local XML parser, NAME
175 is the element, and ATTRS are the names and values of this
176 element's attributes. */
177
178 static void
179 gdb_xml_start_element (void *data, const XML_Char *name,
180 const XML_Char **attrs)
181 {
182 struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;
183 const struct gdb_xml_element *element;
184 const struct gdb_xml_attribute *attribute;
185 VEC(gdb_xml_value_s) *attributes = NULL;
186 unsigned int seen;
187 struct cleanup *back_to;
188
189 /* Push an error scope. If we return or throw an exception before
190 filling this in, it will tell us to ignore children of this
191 element. Note we don't take a reference to the element yet
192 because further below we'll process the element which may recurse
193 back here and push more elements to the vector. When the
194 recursion unrolls all such elements will have been popped back
195 already, but if one of those pushes reallocates the vector,
196 previous element references will be invalidated. */
197 parser->scopes.emplace_back ();
198
199 /* Get a reference to the current scope. */
200 scope_level &scope = parser->scopes[parser->scopes.size () - 2];
201
202 gdb_xml_debug (parser, _("Entering element <%s>"), name);
203
204 /* Find this element in the list of the current scope's allowed
205 children. Record that we've seen it. */
206
207 seen = 1;
208 for (element = scope.elements; element && element->name;
209 element++, seen <<= 1)
210 if (strcmp (element->name, name) == 0)
211 break;
212
213 if (element == NULL || element->name == NULL)
214 {
215 /* If we're working on XInclude, <xi:include> can be the child
216 of absolutely anything. Copy the previous scope's element
217 list into the new scope even if there was no match. */
218 if (parser->is_xinclude)
219 {
220 XML_DefaultCurrent (parser->expat_parser);
221
222 scope_level &unknown_scope = parser->scopes.back ();
223 unknown_scope.elements = scope.elements;
224 return;
225 }
226
227 gdb_xml_debug (parser, _("Element <%s> unknown"), name);
228 return;
229 }
230
231 if (!(element->flags & GDB_XML_EF_REPEATABLE) && (seen & scope.seen))
232 gdb_xml_error (parser, _("Element <%s> only expected once"), name);
233
234 scope.seen |= seen;
235
236 back_to = make_cleanup (gdb_xml_values_cleanup, &attributes);
237
238 for (attribute = element->attributes;
239 attribute != NULL && attribute->name != NULL;
240 attribute++)
241 {
242 const char *val = NULL;
243 const XML_Char **p;
244 void *parsed_value;
245 struct gdb_xml_value new_value;
246
247 for (p = attrs; *p != NULL; p += 2)
248 if (!strcmp (attribute->name, p[0]))
249 {
250 val = p[1];
251 break;
252 }
253
254 if (*p != NULL && val == NULL)
255 {
256 gdb_xml_debug (parser, _("Attribute \"%s\" missing a value"),
257 attribute->name);
258 continue;
259 }
260
261 if (*p == NULL && !(attribute->flags & GDB_XML_AF_OPTIONAL))
262 {
263 gdb_xml_error (parser, _("Required attribute \"%s\" of "
264 "<%s> not specified"),
265 attribute->name, element->name);
266 continue;
267 }
268
269 if (*p == NULL)
270 continue;
271
272 gdb_xml_debug (parser, _("Parsing attribute %s=\"%s\""),
273 attribute->name, val);
274
275 if (attribute->handler)
276 parsed_value = attribute->handler (parser, attribute, val);
277 else
278 parsed_value = xstrdup (val);
279
280 new_value.name = attribute->name;
281 new_value.value = parsed_value;
282 VEC_safe_push (gdb_xml_value_s, attributes, &new_value);
283 }
284
285 /* Check for unrecognized attributes. */
286 if (debug_xml)
287 {
288 const XML_Char **p;
289
290 for (p = attrs; *p != NULL; p += 2)
291 {
292 for (attribute = element->attributes;
293 attribute != NULL && attribute->name != NULL;
294 attribute++)
295 if (strcmp (attribute->name, *p) == 0)
296 break;
297
298 if (attribute == NULL || attribute->name == NULL)
299 gdb_xml_debug (parser, _("Ignoring unknown attribute %s"), *p);
300 }
301 }
302
303 /* Call the element handler if there is one. */
304 if (element->start_handler)
305 element->start_handler (parser, element, parser->user_data, attributes);
306
307 /* Fill in a new scope level. Note that we must delay getting a
308 back reference till here because above we might have recursed,
309 which may have reallocated the vector which invalidates
310 iterators/pointers/references. */
311 scope_level &new_scope = parser->scopes.back ();
312 new_scope.element = element;
313 new_scope.elements = element->children;
314
315 do_cleanups (back_to);
316 }
317
318 /* Wrapper for gdb_xml_start_element, to prevent throwing exceptions
319 through expat. */
320
321 static void
322 gdb_xml_start_element_wrapper (void *data, const XML_Char *name,
323 const XML_Char **attrs)
324 {
325 struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;
326
327 if (parser->error.reason < 0)
328 return;
329
330 TRY
331 {
332 gdb_xml_start_element (data, name, attrs);
333 }
334 CATCH (ex, RETURN_MASK_ALL)
335 {
336 parser->error = ex;
337 #ifdef HAVE_XML_STOPPARSER
338 XML_StopParser (parser->expat_parser, XML_FALSE);
339 #endif
340 }
341 END_CATCH
342 }
343
344 /* Handle the end of an element. PARSER is our local XML parser, and
345 NAME is the current element. */
346
347 static void
348 gdb_xml_end_element (gdb_xml_parser *parser, const XML_Char *name)
349 {
350 struct scope_level *scope = &parser->scopes.back ();
351 const struct gdb_xml_element *element;
352 unsigned int seen;
353
354 gdb_xml_debug (parser, _("Leaving element <%s>"), name);
355
356 for (element = scope->elements, seen = 1;
357 element != NULL && element->name != NULL;
358 element++, seen <<= 1)
359 if ((scope->seen & seen) == 0
360 && (element->flags & GDB_XML_EF_OPTIONAL) == 0)
361 gdb_xml_error (parser, _("Required element <%s> is missing"),
362 element->name);
363
364 /* Call the element processor. */
365 if (scope->element != NULL && scope->element->end_handler)
366 {
367 const char *body;
368
369 if (scope->body.empty ())
370 body = "";
371 else
372 {
373 int length;
374
375 length = scope->body.size ();
376 body = scope->body.c_str ();
377
378 /* Strip leading and trailing whitespace. */
379 while (length > 0 && ISSPACE (body[length - 1]))
380 length--;
381 scope->body.erase (length);
382 while (*body && ISSPACE (*body))
383 body++;
384 }
385
386 scope->element->end_handler (parser, scope->element, parser->user_data,
387 body);
388 }
389 else if (scope->element == NULL)
390 XML_DefaultCurrent (parser->expat_parser);
391
392 /* Pop the scope level. */
393 parser->scopes.pop_back ();
394 }
395
396 /* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
397 through expat. */
398
399 static void
400 gdb_xml_end_element_wrapper (void *data, const XML_Char *name)
401 {
402 struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;
403
404 if (parser->error.reason < 0)
405 return;
406
407 TRY
408 {
409 gdb_xml_end_element (parser, name);
410 }
411 CATCH (ex, RETURN_MASK_ALL)
412 {
413 parser->error = ex;
414 #ifdef HAVE_XML_STOPPARSER
415 XML_StopParser (parser->expat_parser, XML_FALSE);
416 #endif
417 }
418 END_CATCH
419 }
420
421 /* Free a parser and all its associated state. */
422
423 gdb_xml_parser::~gdb_xml_parser ()
424 {
425 XML_ParserFree (this->expat_parser);
426 }
427
428 /* Initialize a parser. */
429
430 gdb_xml_parser::gdb_xml_parser (const char *name_,
431 const gdb_xml_element *elements,
432 void *user_data_)
433 : name (name_),
434 user_data (user_data_),
435 error (exception_none),
436 last_line (0),
437 dtd_name (NULL),
438 is_xinclude (false)
439 {
440 this->expat_parser = XML_ParserCreateNS (NULL, '!');
441 if (this->expat_parser == NULL)
442 malloc_failure (0);
443
444 XML_SetUserData (this->expat_parser, this);
445
446 /* Set the callbacks. */
447 XML_SetElementHandler (this->expat_parser, gdb_xml_start_element_wrapper,
448 gdb_xml_end_element_wrapper);
449 XML_SetCharacterDataHandler (this->expat_parser, gdb_xml_body_text);
450
451 /* Initialize the outer scope. */
452 this->scopes.emplace_back (elements);
453 }
454
455 /* External entity handler. The only external entities we support
456 are those compiled into GDB (we do not fetch entities from the
457 target). */
458
459 static int XMLCALL
460 gdb_xml_fetch_external_entity (XML_Parser expat_parser,
461 const XML_Char *context,
462 const XML_Char *base,
463 const XML_Char *systemId,
464 const XML_Char *publicId)
465 {
466 struct gdb_xml_parser *parser
467 = (struct gdb_xml_parser *) XML_GetUserData (expat_parser);
468 XML_Parser entity_parser;
469 const char *text;
470 enum XML_Status status;
471
472 if (systemId == NULL)
473 {
474 text = fetch_xml_builtin (parser->dtd_name);
475 if (text == NULL)
476 internal_error (__FILE__, __LINE__,
477 _("could not locate built-in DTD %s"),
478 parser->dtd_name);
479 }
480 else
481 {
482 text = fetch_xml_builtin (systemId);
483 if (text == NULL)
484 return XML_STATUS_ERROR;
485 }
486
487 entity_parser = XML_ExternalEntityParserCreate (expat_parser, context, NULL);
488
489 /* Don't use our handlers for the contents of the DTD. Just let expat
490 process it. */
491 XML_SetElementHandler (entity_parser, NULL, NULL);
492 XML_SetDoctypeDeclHandler (entity_parser, NULL, NULL);
493 XML_SetXmlDeclHandler (entity_parser, NULL);
494 XML_SetDefaultHandler (entity_parser, NULL);
495 XML_SetUserData (entity_parser, NULL);
496
497 status = XML_Parse (entity_parser, text, strlen (text), 1);
498
499 XML_ParserFree (entity_parser);
500 return status;
501 }
502
503 /* Associate DTD_NAME, which must be the name of a compiled-in DTD,
504 with PARSER. */
505
506 void
507 gdb_xml_use_dtd (struct gdb_xml_parser *parser, const char *dtd_name)
508 {
509 enum XML_Error err;
510
511 parser->dtd_name = dtd_name;
512
513 XML_SetParamEntityParsing (parser->expat_parser,
514 XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
515 XML_SetExternalEntityRefHandler (parser->expat_parser,
516 gdb_xml_fetch_external_entity);
517
518 /* Even if no DTD is provided, use the built-in DTD anyway. */
519 err = XML_UseForeignDTD (parser->expat_parser, XML_TRUE);
520 if (err != XML_ERROR_NONE)
521 internal_error (__FILE__, __LINE__,
522 _("XML_UseForeignDTD failed: %s"),
523 XML_ErrorString (err));
524 }
525
526 /* Invoke PARSER on BUFFER. BUFFER is the data to parse, which
527 should be NUL-terminated.
528
529 The return value is 0 for success or -1 for error. It may throw,
530 but only if something unexpected goes wrong during parsing; parse
531 errors will be caught, warned about, and reported as failure. */
532
533 int
534 gdb_xml_parse (struct gdb_xml_parser *parser, const char *buffer)
535 {
536 enum XML_Status status;
537 const char *error_string;
538
539 gdb_xml_debug (parser, _("Starting:\n%s"), buffer);
540
541 status = XML_Parse (parser->expat_parser, buffer, strlen (buffer), 1);
542
543 if (status == XML_STATUS_OK && parser->error.reason == 0)
544 return 0;
545
546 if (parser->error.reason == RETURN_ERROR
547 && parser->error.error == XML_PARSE_ERROR)
548 {
549 gdb_assert (parser->error.message != NULL);
550 error_string = parser->error.message;
551 }
552 else if (status == XML_STATUS_ERROR)
553 {
554 enum XML_Error err = XML_GetErrorCode (parser->expat_parser);
555
556 error_string = XML_ErrorString (err);
557 }
558 else
559 {
560 gdb_assert (parser->error.reason < 0);
561 throw_exception (parser->error);
562 }
563
564 if (parser->last_line != 0)
565 warning (_("while parsing %s (at line %d): %s"), parser->name,
566 parser->last_line, error_string);
567 else
568 warning (_("while parsing %s: %s"), parser->name, error_string);
569
570 return -1;
571 }
572
573 int
574 gdb_xml_parse_quick (const char *name, const char *dtd_name,
575 const struct gdb_xml_element *elements,
576 const char *document, void *user_data)
577 {
578 gdb_xml_parser parser (name, elements, user_data);
579 if (dtd_name != NULL)
580 gdb_xml_use_dtd (&parser, dtd_name);
581 return gdb_xml_parse (&parser, document);
582 }
583
584 /* Parse a field VALSTR that we expect to contain an integer value.
585 The integer is returned in *VALP. The string is parsed with an
586 equivalent to strtoul.
587
588 Returns 0 for success, -1 for error. */
589
590 static int
591 xml_parse_unsigned_integer (const char *valstr, ULONGEST *valp)
592 {
593 const char *endptr;
594 ULONGEST result;
595
596 if (*valstr == '\0')
597 return -1;
598
599 result = strtoulst (valstr, &endptr, 0);
600 if (*endptr != '\0')
601 return -1;
602
603 *valp = result;
604 return 0;
605 }
606
607 /* Parse an integer string into a ULONGEST and return it, or call
608 gdb_xml_error if it could not be parsed. */
609
610 ULONGEST
611 gdb_xml_parse_ulongest (struct gdb_xml_parser *parser, const char *value)
612 {
613 ULONGEST result;
614
615 if (xml_parse_unsigned_integer (value, &result) != 0)
616 gdb_xml_error (parser, _("Can't convert \"%s\" to an integer"), value);
617
618 return result;
619 }
620
621 /* Parse an integer attribute into a ULONGEST. */
622
623 void *
624 gdb_xml_parse_attr_ulongest (struct gdb_xml_parser *parser,
625 const struct gdb_xml_attribute *attribute,
626 const char *value)
627 {
628 ULONGEST result;
629 void *ret;
630
631 if (xml_parse_unsigned_integer (value, &result) != 0)
632 gdb_xml_error (parser, _("Can't convert %s=\"%s\" to an integer"),
633 attribute->name, value);
634
635 ret = XNEW (ULONGEST);
636 memcpy (ret, &result, sizeof (result));
637 return ret;
638 }
639
640 /* A handler_data for yes/no boolean values. */
641
642 const struct gdb_xml_enum gdb_xml_enums_boolean[] = {
643 { "yes", 1 },
644 { "no", 0 },
645 { NULL, 0 }
646 };
647
648 /* Map NAME to VALUE. A struct gdb_xml_enum * should be saved as the
649 value of handler_data when using gdb_xml_parse_attr_enum to parse a
650 fixed list of possible strings. The list is terminated by an entry
651 with NAME == NULL. */
652
653 void *
654 gdb_xml_parse_attr_enum (struct gdb_xml_parser *parser,
655 const struct gdb_xml_attribute *attribute,
656 const char *value)
657 {
658 const struct gdb_xml_enum *enums
659 = (const struct gdb_xml_enum *) attribute->handler_data;
660 void *ret;
661
662 for (enums = (const struct gdb_xml_enum *) attribute->handler_data;
663 enums->name != NULL; enums++)
664 if (strcasecmp (enums->name, value) == 0)
665 break;
666
667 if (enums->name == NULL)
668 gdb_xml_error (parser, _("Unknown attribute value %s=\"%s\""),
669 attribute->name, value);
670
671 ret = xmalloc (sizeof (enums->value));
672 memcpy (ret, &enums->value, sizeof (enums->value));
673 return ret;
674 }
675 \f
676
677 /* XInclude processing. This is done as a separate step from actually
678 parsing the document, so that we can produce a single combined XML
679 document - e.g. to hand to a front end or to simplify comparing two
680 documents. We make extensive use of XML_DefaultCurrent, to pass
681 input text directly into the output without reformatting or
682 requoting it.
683
684 We output the DOCTYPE declaration for the first document unchanged,
685 if present, and discard DOCTYPEs from included documents. Only the
686 one we pass through here is used when we feed the result back to
687 expat. The XInclude standard explicitly does not discuss
688 validation of the result; we choose to apply the same DTD applied
689 to the outermost document.
690
691 We can not simply include the external DTD subset in the document
692 as an internal subset, because <!IGNORE> and <!INCLUDE> are valid
693 only in external subsets. But if we do not pass the DTD into the
694 output at all, default values will not be filled in.
695
696 We don't pass through any <?xml> declaration because we generate
697 UTF-8, not whatever the input encoding was. */
698
699 struct xinclude_parsing_data
700 {
701 xinclude_parsing_data (std::string &output_,
702 xml_fetch_another fetcher_, void *fetcher_baton_,
703 int include_depth_)
704 : output (output_),
705 skip_depth (0),
706 include_depth (include_depth_),
707 fetcher (fetcher_),
708 fetcher_baton (fetcher_baton_)
709 {}
710
711 /* Where the output goes. */
712 std::string &output;
713
714 /* A count indicating whether we are in an element whose
715 children should not be copied to the output, and if so,
716 how deep we are nested. This is used for anything inside
717 an xi:include, and for the DTD. */
718 int skip_depth;
719
720 /* The number of <xi:include> elements currently being processed,
721 to detect loops. */
722 int include_depth;
723
724 /* A function to call to obtain additional features, and its
725 baton. */
726 xml_fetch_another fetcher;
727 void *fetcher_baton;
728 };
729
730 static void
731 xinclude_start_include (struct gdb_xml_parser *parser,
732 const struct gdb_xml_element *element,
733 void *user_data, VEC(gdb_xml_value_s) *attributes)
734 {
735 struct xinclude_parsing_data *data
736 = (struct xinclude_parsing_data *) user_data;
737 char *href = (char *) xml_find_attribute (attributes, "href")->value;
738 struct cleanup *back_to;
739 char *text, *output;
740
741 gdb_xml_debug (parser, _("Processing XInclude of \"%s\""), href);
742
743 if (data->include_depth > MAX_XINCLUDE_DEPTH)
744 gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"),
745 MAX_XINCLUDE_DEPTH);
746
747 text = data->fetcher (href, data->fetcher_baton);
748 if (text == NULL)
749 gdb_xml_error (parser, _("Could not load XML document \"%s\""), href);
750 back_to = make_cleanup (xfree, text);
751
752 if (!xml_process_xincludes (data->output, parser->name, text, data->fetcher,
753 data->fetcher_baton,
754 data->include_depth + 1))
755 gdb_xml_error (parser, _("Parsing \"%s\" failed"), href);
756
757 do_cleanups (back_to);
758
759 data->skip_depth++;
760 }
761
762 static void
763 xinclude_end_include (struct gdb_xml_parser *parser,
764 const struct gdb_xml_element *element,
765 void *user_data, const char *body_text)
766 {
767 struct xinclude_parsing_data *data
768 = (struct xinclude_parsing_data *) user_data;
769
770 data->skip_depth--;
771 }
772
773 static void XMLCALL
774 xml_xinclude_default (void *data_, const XML_Char *s, int len)
775 {
776 struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data_;
777 struct xinclude_parsing_data *data
778 = (struct xinclude_parsing_data *) parser->user_data;
779
780 /* If we are inside of e.g. xi:include or the DTD, don't save this
781 string. */
782 if (data->skip_depth)
783 return;
784
785 /* Otherwise just add it to the end of the document we're building
786 up. */
787 data->output.append (s, len);
788 }
789
790 static void XMLCALL
791 xml_xinclude_start_doctype (void *data_, const XML_Char *doctypeName,
792 const XML_Char *sysid, const XML_Char *pubid,
793 int has_internal_subset)
794 {
795 struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data_;
796 struct xinclude_parsing_data *data
797 = (struct xinclude_parsing_data *) parser->user_data;
798
799 /* Don't print out the doctype, or the contents of the DTD internal
800 subset, if any. */
801 data->skip_depth++;
802 }
803
804 static void XMLCALL
805 xml_xinclude_end_doctype (void *data_)
806 {
807 struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data_;
808 struct xinclude_parsing_data *data
809 = (struct xinclude_parsing_data *) parser->user_data;
810
811 data->skip_depth--;
812 }
813
814 static void XMLCALL
815 xml_xinclude_xml_decl (void *data_, const XML_Char *version,
816 const XML_Char *encoding, int standalone)
817 {
818 /* Do nothing - this function prevents the default handler from
819 being called, thus suppressing the XML declaration from the
820 output. */
821 }
822
823 const struct gdb_xml_attribute xinclude_attributes[] = {
824 { "href", GDB_XML_AF_NONE, NULL, NULL },
825 { NULL, GDB_XML_AF_NONE, NULL, NULL }
826 };
827
828 const struct gdb_xml_element xinclude_elements[] = {
829 { "http://www.w3.org/2001/XInclude!include", xinclude_attributes, NULL,
830 GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
831 xinclude_start_include, xinclude_end_include },
832 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
833 };
834
835 /* The main entry point for <xi:include> processing. */
836
837 bool
838 xml_process_xincludes (std::string &result,
839 const char *name, const char *text,
840 xml_fetch_another fetcher, void *fetcher_baton,
841 int depth)
842 {
843 xinclude_parsing_data data (result, fetcher, fetcher_baton, depth);
844
845 gdb_xml_parser parser (name, xinclude_elements, &data);
846 parser.is_xinclude = true;
847
848 XML_SetCharacterDataHandler (parser.expat_parser, NULL);
849 XML_SetDefaultHandler (parser.expat_parser, xml_xinclude_default);
850
851 /* Always discard the XML version declarations; the only important
852 thing this provides is encoding, and our result will have been
853 converted to UTF-8. */
854 XML_SetXmlDeclHandler (parser.expat_parser, xml_xinclude_xml_decl);
855
856 if (depth > 0)
857 /* Discard the doctype for included documents. */
858 XML_SetDoctypeDeclHandler (parser.expat_parser,
859 xml_xinclude_start_doctype,
860 xml_xinclude_end_doctype);
861
862 gdb_xml_use_dtd (&parser, "xinclude.dtd");
863
864 if (gdb_xml_parse (&parser, text) == 0)
865 {
866 if (depth == 0)
867 gdb_xml_debug (&parser, _("XInclude processing succeeded."));
868 return true;
869 }
870
871 return false;
872 }
873 #endif /* HAVE_LIBEXPAT */
874 \f
875
876 /* Return an XML document which was compiled into GDB, from
877 the given FILENAME, or NULL if the file was not compiled in. */
878
879 const char *
880 fetch_xml_builtin (const char *filename)
881 {
882 const char *(*p)[2];
883
884 for (p = xml_builtin; (*p)[0]; p++)
885 if (strcmp ((*p)[0], filename) == 0)
886 return (*p)[1];
887
888 return NULL;
889 }
890
891 /* A to_xfer_partial helper function which reads XML files which were
892 compiled into GDB. The target may call this function from its own
893 to_xfer_partial handler, after converting object and annex to the
894 appropriate filename. */
895
896 LONGEST
897 xml_builtin_xfer_partial (const char *filename,
898 gdb_byte *readbuf, const gdb_byte *writebuf,
899 ULONGEST offset, LONGEST len)
900 {
901 const char *buf;
902 LONGEST len_avail;
903
904 gdb_assert (readbuf != NULL && writebuf == NULL);
905 gdb_assert (filename != NULL);
906
907 buf = fetch_xml_builtin (filename);
908 if (buf == NULL)
909 return -1;
910
911 len_avail = strlen (buf);
912 if (offset >= len_avail)
913 return 0;
914
915 if (len > len_avail - offset)
916 len = len_avail - offset;
917 memcpy (readbuf, buf + offset, len);
918 return len;
919 }
920 \f
921
922 static void
923 show_debug_xml (struct ui_file *file, int from_tty,
924 struct cmd_list_element *c, const char *value)
925 {
926 fprintf_filtered (file, _("XML debugging is %s.\n"), value);
927 }
928
929 void
930 obstack_xml_printf (struct obstack *obstack, const char *format, ...)
931 {
932 va_list ap;
933 const char *f;
934 const char *prev;
935 int percent = 0;
936
937 va_start (ap, format);
938
939 prev = format;
940 for (f = format; *f; f++)
941 {
942 if (percent)
943 {
944 switch (*f)
945 {
946 case 's':
947 {
948 char *p;
949 char *a = va_arg (ap, char *);
950
951 obstack_grow (obstack, prev, f - prev - 1);
952 p = xml_escape_text (a);
953 obstack_grow_str (obstack, p);
954 xfree (p);
955 prev = f + 1;
956 }
957 break;
958 }
959 percent = 0;
960 }
961 else if (*f == '%')
962 percent = 1;
963 }
964
965 obstack_grow_str (obstack, prev);
966 va_end (ap);
967 }
968
969 char *
970 xml_fetch_content_from_file (const char *filename, void *baton)
971 {
972 const char *dirname = (const char *) baton;
973 FILE *file;
974 struct cleanup *back_to;
975 char *text;
976 size_t len, offset;
977
978 if (dirname && *dirname)
979 {
980 char *fullname = concat (dirname, "/", filename, (char *) NULL);
981
982 if (fullname == NULL)
983 malloc_failure (0);
984 file = gdb_fopen_cloexec (fullname, FOPEN_RT);
985 xfree (fullname);
986 }
987 else
988 file = gdb_fopen_cloexec (filename, FOPEN_RT);
989
990 if (file == NULL)
991 return NULL;
992
993 back_to = make_cleanup_fclose (file);
994
995 /* Read in the whole file, one chunk at a time. */
996 len = 4096;
997 offset = 0;
998 text = (char *) xmalloc (len);
999 make_cleanup (free_current_contents, &text);
1000 while (1)
1001 {
1002 size_t bytes_read;
1003
1004 /* Continue reading where the last read left off. Leave at least
1005 one byte so that we can NUL-terminate the result. */
1006 bytes_read = fread (text + offset, 1, len - offset - 1, file);
1007 if (ferror (file))
1008 {
1009 warning (_("Read error from \"%s\""), filename);
1010 do_cleanups (back_to);
1011 return NULL;
1012 }
1013
1014 offset += bytes_read;
1015
1016 if (feof (file))
1017 break;
1018
1019 len = len * 2;
1020 text = (char *) xrealloc (text, len);
1021 }
1022
1023 fclose (file);
1024 discard_cleanups (back_to);
1025
1026 text[offset] = '\0';
1027 return text;
1028 }
1029
1030 void _initialize_xml_support (void);
1031
1032 void
1033 _initialize_xml_support (void)
1034 {
1035 add_setshow_boolean_cmd ("xml", class_maintenance, &debug_xml,
1036 _("Set XML parser debugging."),
1037 _("Show XML parser debugging."),
1038 _("When set, debugging messages for XML parsers "
1039 "are displayed."),
1040 NULL, show_debug_xml,
1041 &setdebuglist, &showdebuglist);
1042 }
This page took 0.057209 seconds and 4 git commands to generate.