1 /* Helper routines for parsing XML using Expat.
3 Copyright (C) 2006-2017 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
22 #include "xml-support.h"
23 #include "filestuff.h"
24 #include "safe-ctype.h"
31 /* The contents of this file are only useful if XML support is
35 #include "gdb_expat.h"
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
41 /* Simplified XML parser infrastructure. */
43 /* A parsing level -- used to keep track of the current element
47 explicit scope_level (const gdb_xml_element
*elements_
= NULL
)
48 : elements (elements_
),
53 /* Elements we allow at this level. */
54 const struct gdb_xml_element
*elements
;
56 /* The element which we are within. */
57 const struct gdb_xml_element
*element
;
59 /* Mask of which elements we've seen at this level (used for
60 optional and repeatable checking). */
63 /* Body text accumulation. */
67 /* The parser itself, and our additional state. */
70 gdb_xml_parser (const char *name
,
71 const gdb_xml_element
*elements
,
75 XML_Parser expat_parser
; /* The underlying expat parser. */
77 const char *name
; /* Name of this parser. */
78 void *user_data
; /* The user's callback data, for handlers. */
81 std::vector
<scope_level
> scopes
;
83 struct gdb_exception error
; /* A thrown error, if any. */
84 int last_line
; /* The line of the thrown error, or 0. */
86 const char *dtd_name
; /* The name of the expected / default DTD,
88 bool is_xinclude
; /* Are we the special <xi:include> parser? */
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. */
96 gdb_xml_body_text (void *data
, const XML_Char
*text
, int length
)
98 struct gdb_xml_parser
*parser
= (struct gdb_xml_parser
*) data
;
100 if (parser
->error
.reason
< 0)
103 scope_level
&scope
= parser
->scopes
.back ();
104 scope
.body
.append (text
, length
);
107 /* Issue a debugging message from one of PARSER's handlers. */
110 gdb_xml_debug (struct gdb_xml_parser
*parser
, const char *format
, ...)
112 int line
= XML_GetCurrentLineNumber (parser
->expat_parser
);
119 va_start (ap
, format
);
120 message
= xstrvprintf (format
, ap
);
122 fprintf_unfiltered (gdb_stderr
, "%s (line %d): %s\n",
123 parser
->name
, line
, message
);
125 fprintf_unfiltered (gdb_stderr
, "%s: %s\n",
126 parser
->name
, message
);
130 /* Issue an error message from one of PARSER's handlers, and stop
134 gdb_xml_error (struct gdb_xml_parser
*parser
, const char *format
, ...)
136 int line
= XML_GetCurrentLineNumber (parser
->expat_parser
);
139 parser
->last_line
= line
;
140 va_start (ap
, format
);
141 throw_verror (XML_PARSE_ERROR
, format
, ap
);
144 /* Find the attribute named NAME in the set of parsed attributes
145 ATTRIBUTES. Returns NULL if not found. */
147 struct gdb_xml_value
*
148 xml_find_attribute (VEC(gdb_xml_value_s
) *attributes
, const char *name
)
150 struct gdb_xml_value
*value
;
153 for (ix
= 0; VEC_iterate (gdb_xml_value_s
, attributes
, ix
, value
); ix
++)
154 if (strcmp (value
->name
, name
) == 0)
160 /* Clean up a vector of parsed attribute values. */
163 gdb_xml_values_cleanup (void *data
)
165 VEC(gdb_xml_value_s
) **values
= (VEC(gdb_xml_value_s
) **) data
;
166 struct gdb_xml_value
*value
;
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
);
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. */
179 gdb_xml_start_element (void *data
, const XML_Char
*name
,
180 const XML_Char
**attrs
)
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
;
187 struct cleanup
*back_to
;
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 ();
199 /* Get a reference to the current scope. */
200 scope_level
&scope
= parser
->scopes
[parser
->scopes
.size () - 2];
202 gdb_xml_debug (parser
, _("Entering element <%s>"), name
);
204 /* Find this element in the list of the current scope's allowed
205 children. Record that we've seen it. */
208 for (element
= scope
.elements
; element
&& element
->name
;
209 element
++, seen
<<= 1)
210 if (strcmp (element
->name
, name
) == 0)
213 if (element
== NULL
|| element
->name
== NULL
)
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
)
220 XML_DefaultCurrent (parser
->expat_parser
);
222 scope_level
&unknown_scope
= parser
->scopes
.back ();
223 unknown_scope
.elements
= scope
.elements
;
227 gdb_xml_debug (parser
, _("Element <%s> unknown"), name
);
231 if (!(element
->flags
& GDB_XML_EF_REPEATABLE
) && (seen
& scope
.seen
))
232 gdb_xml_error (parser
, _("Element <%s> only expected once"), name
);
236 back_to
= make_cleanup (gdb_xml_values_cleanup
, &attributes
);
238 for (attribute
= element
->attributes
;
239 attribute
!= NULL
&& attribute
->name
!= NULL
;
242 const char *val
= NULL
;
245 struct gdb_xml_value new_value
;
247 for (p
= attrs
; *p
!= NULL
; p
+= 2)
248 if (!strcmp (attribute
->name
, p
[0]))
254 if (*p
!= NULL
&& val
== NULL
)
256 gdb_xml_debug (parser
, _("Attribute \"%s\" missing a value"),
261 if (*p
== NULL
&& !(attribute
->flags
& GDB_XML_AF_OPTIONAL
))
263 gdb_xml_error (parser
, _("Required attribute \"%s\" of "
264 "<%s> not specified"),
265 attribute
->name
, element
->name
);
272 gdb_xml_debug (parser
, _("Parsing attribute %s=\"%s\""),
273 attribute
->name
, val
);
275 if (attribute
->handler
)
276 parsed_value
= attribute
->handler (parser
, attribute
, val
);
278 parsed_value
= xstrdup (val
);
280 new_value
.name
= attribute
->name
;
281 new_value
.value
= parsed_value
;
282 VEC_safe_push (gdb_xml_value_s
, attributes
, &new_value
);
285 /* Check for unrecognized attributes. */
290 for (p
= attrs
; *p
!= NULL
; p
+= 2)
292 for (attribute
= element
->attributes
;
293 attribute
!= NULL
&& attribute
->name
!= NULL
;
295 if (strcmp (attribute
->name
, *p
) == 0)
298 if (attribute
== NULL
|| attribute
->name
== NULL
)
299 gdb_xml_debug (parser
, _("Ignoring unknown attribute %s"), *p
);
303 /* Call the element handler if there is one. */
304 if (element
->start_handler
)
305 element
->start_handler (parser
, element
, parser
->user_data
, attributes
);
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
;
315 do_cleanups (back_to
);
318 /* Wrapper for gdb_xml_start_element, to prevent throwing exceptions
322 gdb_xml_start_element_wrapper (void *data
, const XML_Char
*name
,
323 const XML_Char
**attrs
)
325 struct gdb_xml_parser
*parser
= (struct gdb_xml_parser
*) data
;
327 if (parser
->error
.reason
< 0)
332 gdb_xml_start_element (data
, name
, attrs
);
334 CATCH (ex
, RETURN_MASK_ALL
)
337 #ifdef HAVE_XML_STOPPARSER
338 XML_StopParser (parser
->expat_parser
, XML_FALSE
);
344 /* Handle the end of an element. PARSER is our local XML parser, and
345 NAME is the current element. */
348 gdb_xml_end_element (gdb_xml_parser
*parser
, const XML_Char
*name
)
350 struct scope_level
*scope
= &parser
->scopes
.back ();
351 const struct gdb_xml_element
*element
;
354 gdb_xml_debug (parser
, _("Leaving element <%s>"), name
);
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"),
364 /* Call the element processor. */
365 if (scope
->element
!= NULL
&& scope
->element
->end_handler
)
369 if (scope
->body
.empty ())
375 length
= scope
->body
.size ();
376 body
= scope
->body
.c_str ();
378 /* Strip leading and trailing whitespace. */
379 while (length
> 0 && ISSPACE (body
[length
- 1]))
381 scope
->body
.erase (length
);
382 while (*body
&& ISSPACE (*body
))
386 scope
->element
->end_handler (parser
, scope
->element
, parser
->user_data
,
389 else if (scope
->element
== NULL
)
390 XML_DefaultCurrent (parser
->expat_parser
);
392 /* Pop the scope level. */
393 parser
->scopes
.pop_back ();
396 /* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
400 gdb_xml_end_element_wrapper (void *data
, const XML_Char
*name
)
402 struct gdb_xml_parser
*parser
= (struct gdb_xml_parser
*) data
;
404 if (parser
->error
.reason
< 0)
409 gdb_xml_end_element (parser
, name
);
411 CATCH (ex
, RETURN_MASK_ALL
)
414 #ifdef HAVE_XML_STOPPARSER
415 XML_StopParser (parser
->expat_parser
, XML_FALSE
);
421 /* Free a parser and all its associated state. */
423 gdb_xml_parser::~gdb_xml_parser ()
425 XML_ParserFree (this->expat_parser
);
428 /* Initialize a parser. */
430 gdb_xml_parser::gdb_xml_parser (const char *name_
,
431 const gdb_xml_element
*elements
,
434 user_data (user_data_
),
435 error (exception_none
),
440 this->expat_parser
= XML_ParserCreateNS (NULL
, '!');
441 if (this->expat_parser
== NULL
)
444 XML_SetUserData (this->expat_parser
, this);
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
);
451 /* Initialize the outer scope. */
452 this->scopes
.emplace_back (elements
);
455 /* External entity handler. The only external entities we support
456 are those compiled into GDB (we do not fetch entities from the
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
)
466 struct gdb_xml_parser
*parser
467 = (struct gdb_xml_parser
*) XML_GetUserData (expat_parser
);
468 XML_Parser entity_parser
;
470 enum XML_Status status
;
472 if (systemId
== NULL
)
474 text
= fetch_xml_builtin (parser
->dtd_name
);
476 internal_error (__FILE__
, __LINE__
,
477 _("could not locate built-in DTD %s"),
482 text
= fetch_xml_builtin (systemId
);
484 return XML_STATUS_ERROR
;
487 entity_parser
= XML_ExternalEntityParserCreate (expat_parser
, context
, NULL
);
489 /* Don't use our handlers for the contents of the DTD. Just let expat
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
);
497 status
= XML_Parse (entity_parser
, text
, strlen (text
), 1);
499 XML_ParserFree (entity_parser
);
503 /* Associate DTD_NAME, which must be the name of a compiled-in DTD,
507 gdb_xml_use_dtd (struct gdb_xml_parser
*parser
, const char *dtd_name
)
511 parser
->dtd_name
= dtd_name
;
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
);
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
));
526 /* Invoke PARSER on BUFFER. BUFFER is the data to parse, which
527 should be NUL-terminated.
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. */
534 gdb_xml_parse (struct gdb_xml_parser
*parser
, const char *buffer
)
536 enum XML_Status status
;
537 const char *error_string
;
539 gdb_xml_debug (parser
, _("Starting:\n%s"), buffer
);
541 status
= XML_Parse (parser
->expat_parser
, buffer
, strlen (buffer
), 1);
543 if (status
== XML_STATUS_OK
&& parser
->error
.reason
== 0)
546 if (parser
->error
.reason
== RETURN_ERROR
547 && parser
->error
.error
== XML_PARSE_ERROR
)
549 gdb_assert (parser
->error
.message
!= NULL
);
550 error_string
= parser
->error
.message
;
552 else if (status
== XML_STATUS_ERROR
)
554 enum XML_Error err
= XML_GetErrorCode (parser
->expat_parser
);
556 error_string
= XML_ErrorString (err
);
560 gdb_assert (parser
->error
.reason
< 0);
561 throw_exception (parser
->error
);
564 if (parser
->last_line
!= 0)
565 warning (_("while parsing %s (at line %d): %s"), parser
->name
,
566 parser
->last_line
, error_string
);
568 warning (_("while parsing %s: %s"), parser
->name
, error_string
);
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
)
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
);
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.
588 Returns 0 for success, -1 for error. */
591 xml_parse_unsigned_integer (const char *valstr
, ULONGEST
*valp
)
599 result
= strtoulst (valstr
, &endptr
, 0);
607 /* Parse an integer string into a ULONGEST and return it, or call
608 gdb_xml_error if it could not be parsed. */
611 gdb_xml_parse_ulongest (struct gdb_xml_parser
*parser
, const char *value
)
615 if (xml_parse_unsigned_integer (value
, &result
) != 0)
616 gdb_xml_error (parser
, _("Can't convert \"%s\" to an integer"), value
);
621 /* Parse an integer attribute into a ULONGEST. */
624 gdb_xml_parse_attr_ulongest (struct gdb_xml_parser
*parser
,
625 const struct gdb_xml_attribute
*attribute
,
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
);
635 ret
= XNEW (ULONGEST
);
636 memcpy (ret
, &result
, sizeof (result
));
640 /* A handler_data for yes/no boolean values. */
642 const struct gdb_xml_enum gdb_xml_enums_boolean
[] = {
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. */
654 gdb_xml_parse_attr_enum (struct gdb_xml_parser
*parser
,
655 const struct gdb_xml_attribute
*attribute
,
658 const struct gdb_xml_enum
*enums
659 = (const struct gdb_xml_enum
*) attribute
->handler_data
;
662 for (enums
= (const struct gdb_xml_enum
*) attribute
->handler_data
;
663 enums
->name
!= NULL
; enums
++)
664 if (strcasecmp (enums
->name
, value
) == 0)
667 if (enums
->name
== NULL
)
668 gdb_xml_error (parser
, _("Unknown attribute value %s=\"%s\""),
669 attribute
->name
, value
);
671 ret
= xmalloc (sizeof (enums
->value
));
672 memcpy (ret
, &enums
->value
, sizeof (enums
->value
));
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
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.
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.
696 We don't pass through any <?xml> declaration because we generate
697 UTF-8, not whatever the input encoding was. */
699 struct xinclude_parsing_data
701 xinclude_parsing_data (std::string
&output_
,
702 xml_fetch_another fetcher_
, void *fetcher_baton_
,
706 include_depth (include_depth_
),
708 fetcher_baton (fetcher_baton_
)
711 /* Where the output goes. */
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. */
720 /* The number of <xi:include> elements currently being processed,
724 /* A function to call to obtain additional features, and its
726 xml_fetch_another fetcher
;
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
)
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
;
741 gdb_xml_debug (parser
, _("Processing XInclude of \"%s\""), href
);
743 if (data
->include_depth
> MAX_XINCLUDE_DEPTH
)
744 gdb_xml_error (parser
, _("Maximum XInclude depth (%d) exceeded"),
747 text
= data
->fetcher (href
, data
->fetcher_baton
);
749 gdb_xml_error (parser
, _("Could not load XML document \"%s\""), href
);
750 back_to
= make_cleanup (xfree
, text
);
752 if (!xml_process_xincludes (data
->output
, parser
->name
, text
, data
->fetcher
,
754 data
->include_depth
+ 1))
755 gdb_xml_error (parser
, _("Parsing \"%s\" failed"), href
);
757 do_cleanups (back_to
);
763 xinclude_end_include (struct gdb_xml_parser
*parser
,
764 const struct gdb_xml_element
*element
,
765 void *user_data
, const char *body_text
)
767 struct xinclude_parsing_data
*data
768 = (struct xinclude_parsing_data
*) user_data
;
774 xml_xinclude_default (void *data_
, const XML_Char
*s
, int len
)
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
;
780 /* If we are inside of e.g. xi:include or the DTD, don't save this
782 if (data
->skip_depth
)
785 /* Otherwise just add it to the end of the document we're building
787 data
->output
.append (s
, len
);
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
)
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
;
799 /* Don't print out the doctype, or the contents of the DTD internal
805 xml_xinclude_end_doctype (void *data_
)
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
;
815 xml_xinclude_xml_decl (void *data_
, const XML_Char
*version
,
816 const XML_Char
*encoding
, int standalone
)
818 /* Do nothing - this function prevents the default handler from
819 being called, thus suppressing the XML declaration from the
823 const struct gdb_xml_attribute xinclude_attributes
[] = {
824 { "href", GDB_XML_AF_NONE
, NULL
, NULL
},
825 { NULL
, GDB_XML_AF_NONE
, NULL
, NULL
}
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
}
835 /* The main entry point for <xi:include> processing. */
838 xml_process_xincludes (std::string
&result
,
839 const char *name
, const char *text
,
840 xml_fetch_another fetcher
, void *fetcher_baton
,
843 xinclude_parsing_data
data (result
, fetcher
, fetcher_baton
, depth
);
845 gdb_xml_parser
parser (name
, xinclude_elements
, &data
);
846 parser
.is_xinclude
= true;
848 XML_SetCharacterDataHandler (parser
.expat_parser
, NULL
);
849 XML_SetDefaultHandler (parser
.expat_parser
, xml_xinclude_default
);
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
);
857 /* Discard the doctype for included documents. */
858 XML_SetDoctypeDeclHandler (parser
.expat_parser
,
859 xml_xinclude_start_doctype
,
860 xml_xinclude_end_doctype
);
862 gdb_xml_use_dtd (&parser
, "xinclude.dtd");
864 if (gdb_xml_parse (&parser
, text
) == 0)
867 gdb_xml_debug (&parser
, _("XInclude processing succeeded."));
873 #endif /* HAVE_LIBEXPAT */
876 /* Return an XML document which was compiled into GDB, from
877 the given FILENAME, or NULL if the file was not compiled in. */
880 fetch_xml_builtin (const char *filename
)
884 for (p
= xml_builtin
; (*p
)[0]; p
++)
885 if (strcmp ((*p
)[0], filename
) == 0)
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. */
897 xml_builtin_xfer_partial (const char *filename
,
898 gdb_byte
*readbuf
, const gdb_byte
*writebuf
,
899 ULONGEST offset
, LONGEST len
)
904 gdb_assert (readbuf
!= NULL
&& writebuf
== NULL
);
905 gdb_assert (filename
!= NULL
);
907 buf
= fetch_xml_builtin (filename
);
911 len_avail
= strlen (buf
);
912 if (offset
>= len_avail
)
915 if (len
> len_avail
- offset
)
916 len
= len_avail
- offset
;
917 memcpy (readbuf
, buf
+ offset
, len
);
923 show_debug_xml (struct ui_file
*file
, int from_tty
,
924 struct cmd_list_element
*c
, const char *value
)
926 fprintf_filtered (file
, _("XML debugging is %s.\n"), value
);
930 obstack_xml_printf (struct obstack
*obstack
, const char *format
, ...)
937 va_start (ap
, format
);
940 for (f
= format
; *f
; f
++)
949 char *a
= va_arg (ap
, char *);
951 obstack_grow (obstack
, prev
, f
- prev
- 1);
952 p
= xml_escape_text (a
);
953 obstack_grow_str (obstack
, p
);
965 obstack_grow_str (obstack
, prev
);
970 xml_fetch_content_from_file (const char *filename
, void *baton
)
972 const char *dirname
= (const char *) baton
;
974 struct cleanup
*back_to
;
978 if (dirname
&& *dirname
)
980 char *fullname
= concat (dirname
, "/", filename
, (char *) NULL
);
982 if (fullname
== NULL
)
984 file
= gdb_fopen_cloexec (fullname
, FOPEN_RT
);
988 file
= gdb_fopen_cloexec (filename
, FOPEN_RT
);
993 back_to
= make_cleanup_fclose (file
);
995 /* Read in the whole file, one chunk at a time. */
998 text
= (char *) xmalloc (len
);
999 make_cleanup (free_current_contents
, &text
);
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
);
1009 warning (_("Read error from \"%s\""), filename
);
1010 do_cleanups (back_to
);
1014 offset
+= bytes_read
;
1020 text
= (char *) xrealloc (text
, len
);
1024 discard_cleanups (back_to
);
1026 text
[offset
] = '\0';
1030 void _initialize_xml_support (void);
1033 _initialize_xml_support (void)
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 "
1040 NULL
, show_debug_xml
,
1041 &setdebuglist
, &showdebuglist
);