1 /* Helper routines for parsing XML using Expat.
3 Copyright (C) 2006, 2007 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 2 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, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
24 #include "exceptions.h"
25 #include "xml-support.h"
27 #include "gdb_string.h"
28 #include "safe-ctype.h"
33 /* The contents of this file are only useful if XML support is
37 #include "gdb_expat.h"
39 /* The maximum depth of <xi:include> nesting. No need to be miserly,
40 we just want to avoid running out of stack on loops. */
41 #define MAX_XINCLUDE_DEPTH 30
43 /* Simplified XML parser infrastructure. */
45 /* A parsing level -- used to keep track of the current element
49 /* Elements we allow at this level. */
50 const struct gdb_xml_element
*elements
;
52 /* The element which we are within. */
53 const struct gdb_xml_element
*element
;
55 /* Mask of which elements we've seen at this level (used for
56 optional and repeatable checking). */
59 /* Body text accumulation. */
62 typedef struct scope_level scope_level_s
;
63 DEF_VEC_O(scope_level_s
);
65 /* The parser itself, and our additional state. */
68 XML_Parser expat_parser
; /* The underlying expat parser. */
70 const char *name
; /* Name of this parser. */
71 void *user_data
; /* The user's callback data, for handlers. */
73 VEC(scope_level_s
) *scopes
; /* Scoping stack. */
75 struct gdb_exception error
; /* A thrown error, if any. */
76 int last_line
; /* The line of the thrown error, or 0. */
78 const char *dtd_name
; /* The name of the expected / default DTD,
80 int is_xinclude
; /* Are we the special <xi:include> parser? */
83 /* Process some body text. We accumulate the text for later use; it's
84 wrong to do anything with it immediately, because a single block of
85 text might be broken up into multiple calls to this function. */
88 gdb_xml_body_text (void *data
, const XML_Char
*text
, int length
)
90 struct gdb_xml_parser
*parser
= data
;
91 struct scope_level
*scope
= VEC_last (scope_level_s
, parser
->scopes
);
93 if (parser
->error
.reason
< 0)
96 if (scope
->body
== NULL
)
98 scope
->body
= XZALLOC (struct obstack
);
99 obstack_init (scope
->body
);
102 obstack_grow (scope
->body
, text
, length
);
105 /* Issue a debugging message from one of PARSER's handlers. */
108 gdb_xml_debug (struct gdb_xml_parser
*parser
, const char *format
, ...)
110 int line
= XML_GetCurrentLineNumber (parser
->expat_parser
);
117 va_start (ap
, format
);
118 message
= xstrvprintf (format
, ap
);
120 fprintf_unfiltered (gdb_stderr
, "%s (line %d): %s\n",
121 parser
->name
, line
, message
);
123 fprintf_unfiltered (gdb_stderr
, "%s: %s\n",
124 parser
->name
, message
);
128 /* Issue an error message from one of PARSER's handlers, and stop
132 gdb_xml_error (struct gdb_xml_parser
*parser
, const char *format
, ...)
134 int line
= XML_GetCurrentLineNumber (parser
->expat_parser
);
137 parser
->last_line
= line
;
138 va_start (ap
, format
);
139 throw_verror (XML_PARSE_ERROR
, format
, ap
);
142 /* Clean up a vector of parsed attribute values. */
145 gdb_xml_values_cleanup (void *data
)
147 VEC(gdb_xml_value_s
) **values
= data
;
148 struct gdb_xml_value
*value
;
151 for (ix
= 0; VEC_iterate (gdb_xml_value_s
, *values
, ix
, value
); ix
++)
152 xfree (value
->value
);
153 VEC_free (gdb_xml_value_s
, *values
);
156 /* Handle the start of an element. DATA is our local XML parser, NAME
157 is the element, and ATTRS are the names and values of this
158 element's attributes. */
161 gdb_xml_start_element (void *data
, const XML_Char
*name
,
162 const XML_Char
**attrs
)
164 struct gdb_xml_parser
*parser
= data
;
165 struct scope_level
*scope
;
166 struct scope_level new_scope
;
167 const struct gdb_xml_element
*element
;
168 const struct gdb_xml_attribute
*attribute
;
169 VEC(gdb_xml_value_s
) *attributes
= NULL
;
171 struct cleanup
*back_to
;
173 /* Push an error scope. If we return or throw an exception before
174 filling this in, it will tell us to ignore children of this
176 VEC_reserve (scope_level_s
, parser
->scopes
, 1);
177 scope
= VEC_last (scope_level_s
, parser
->scopes
);
178 memset (&new_scope
, 0, sizeof (new_scope
));
179 VEC_quick_push (scope_level_s
, parser
->scopes
, &new_scope
);
181 gdb_xml_debug (parser
, _("Entering element <%s>"), name
);
183 /* Find this element in the list of the current scope's allowed
184 children. Record that we've seen it. */
187 for (element
= scope
->elements
; element
&& element
->name
;
188 element
++, seen
<<= 1)
189 if (strcmp (element
->name
, name
) == 0)
192 if (element
== NULL
|| element
->name
== NULL
)
194 /* If we're working on XInclude, <xi:include> can be the child
195 of absolutely anything. Copy the previous scope's element
196 list into the new scope even if there was no match. */
197 if (parser
->is_xinclude
)
199 struct scope_level
*unknown_scope
;
201 XML_DefaultCurrent (parser
->expat_parser
);
203 unknown_scope
= VEC_last (scope_level_s
, parser
->scopes
);
204 unknown_scope
->elements
= scope
->elements
;
208 gdb_xml_debug (parser
, _("Element <%s> unknown"), name
);
212 if (!(element
->flags
& GDB_XML_EF_REPEATABLE
) && (seen
& scope
->seen
))
213 gdb_xml_error (parser
, _("Element <%s> only expected once"), name
);
217 back_to
= make_cleanup (gdb_xml_values_cleanup
, &attributes
);
219 for (attribute
= element
->attributes
;
220 attribute
!= NULL
&& attribute
->name
!= NULL
;
223 const char *val
= NULL
;
226 struct gdb_xml_value new_value
;
228 for (p
= attrs
; *p
!= NULL
; p
+= 2)
229 if (!strcmp (attribute
->name
, p
[0]))
235 if (*p
!= NULL
&& val
== NULL
)
237 gdb_xml_debug (parser
, _("Attribute \"%s\" missing a value"),
242 if (*p
== NULL
&& !(attribute
->flags
& GDB_XML_AF_OPTIONAL
))
244 gdb_xml_error (parser
, _("Required attribute \"%s\" of "
245 "<%s> not specified"),
246 attribute
->name
, element
->name
);
253 gdb_xml_debug (parser
, _("Parsing attribute %s=\"%s\""),
254 attribute
->name
, val
);
256 if (attribute
->handler
)
257 parsed_value
= attribute
->handler (parser
, attribute
, val
);
259 parsed_value
= xstrdup (val
);
261 new_value
.name
= attribute
->name
;
262 new_value
.value
= parsed_value
;
263 VEC_safe_push (gdb_xml_value_s
, attributes
, &new_value
);
266 /* Check for unrecognized attributes. */
271 for (p
= attrs
; *p
!= NULL
; p
+= 2)
273 for (attribute
= element
->attributes
;
274 attribute
!= NULL
&& attribute
->name
!= NULL
;
276 if (strcmp (attribute
->name
, *p
) == 0)
279 if (attribute
== NULL
|| attribute
->name
== NULL
)
280 gdb_xml_debug (parser
, _("Ignoring unknown attribute %s"), *p
);
284 /* Call the element handler if there is one. */
285 if (element
->start_handler
)
286 element
->start_handler (parser
, element
, parser
->user_data
, attributes
);
288 /* Fill in a new scope level. */
289 scope
= VEC_last (scope_level_s
, parser
->scopes
);
290 scope
->element
= element
;
291 scope
->elements
= element
->children
;
293 do_cleanups (back_to
);
296 /* Wrapper for gdb_xml_start_element, to prevent throwing exceptions
300 gdb_xml_start_element_wrapper (void *data
, const XML_Char
*name
,
301 const XML_Char
**attrs
)
303 struct gdb_xml_parser
*parser
= data
;
304 volatile struct gdb_exception ex
;
306 if (parser
->error
.reason
< 0)
309 TRY_CATCH (ex
, RETURN_MASK_ALL
)
311 gdb_xml_start_element (data
, name
, attrs
);
316 #ifdef HAVE_XML_STOPPARSER
317 XML_StopParser (parser
->expat_parser
, XML_FALSE
);
322 /* Handle the end of an element. DATA is our local XML parser, and
323 NAME is the current element. */
326 gdb_xml_end_element (void *data
, const XML_Char
*name
)
328 struct gdb_xml_parser
*parser
= data
;
329 struct scope_level
*scope
= VEC_last (scope_level_s
, parser
->scopes
);
330 const struct gdb_xml_element
*element
;
333 gdb_xml_debug (parser
, _("Leaving element <%s>"), name
);
335 for (element
= scope
->elements
, seen
= 1;
336 element
!= NULL
&& element
->name
!= NULL
;
337 element
++, seen
<<= 1)
338 if ((scope
->seen
& seen
) == 0
339 && (element
->flags
& GDB_XML_EF_OPTIONAL
) == 0)
340 gdb_xml_error (parser
, _("Required element <%s> is missing"),
343 /* Call the element processor. */
344 if (scope
->element
!= NULL
&& scope
->element
->end_handler
)
348 if (scope
->body
== NULL
)
354 length
= obstack_object_size (scope
->body
);
355 obstack_1grow (scope
->body
, '\0');
356 body
= obstack_finish (scope
->body
);
358 /* Strip leading and trailing whitespace. */
359 while (length
> 0 && ISSPACE (body
[length
-1]))
360 body
[--length
] = '\0';
361 while (*body
&& ISSPACE (*body
))
365 scope
->element
->end_handler (parser
, scope
->element
, parser
->user_data
,
368 else if (scope
->element
== NULL
)
369 XML_DefaultCurrent (parser
->expat_parser
);
371 /* Pop the scope level. */
374 obstack_free (scope
->body
, NULL
);
377 VEC_pop (scope_level_s
, parser
->scopes
);
380 /* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
384 gdb_xml_end_element_wrapper (void *data
, const XML_Char
*name
)
386 struct gdb_xml_parser
*parser
= data
;
387 volatile struct gdb_exception ex
;
389 if (parser
->error
.reason
< 0)
392 TRY_CATCH (ex
, RETURN_MASK_ALL
)
394 gdb_xml_end_element (data
, name
);
399 #ifdef HAVE_XML_STOPPARSER
400 XML_StopParser (parser
->expat_parser
, XML_FALSE
);
405 /* Free a parser and all its associated state. */
408 gdb_xml_cleanup (void *arg
)
410 struct gdb_xml_parser
*parser
= arg
;
411 struct scope_level
*scope
;
414 XML_ParserFree (parser
->expat_parser
);
416 /* Clean up the scopes. */
417 for (ix
= 0; VEC_iterate (scope_level_s
, parser
->scopes
, ix
, scope
); ix
++)
420 obstack_free (scope
->body
, NULL
);
423 VEC_free (scope_level_s
, parser
->scopes
);
428 /* Initialize and return a parser. Register a cleanup to destroy the
431 struct gdb_xml_parser
*
432 gdb_xml_create_parser_and_cleanup (const char *name
,
433 const struct gdb_xml_element
*elements
,
436 struct gdb_xml_parser
*parser
;
437 struct scope_level start_scope
;
439 /* Initialize the parser. */
440 parser
= XZALLOC (struct gdb_xml_parser
);
441 parser
->expat_parser
= XML_ParserCreateNS (NULL
, '!');
442 if (parser
->expat_parser
== NULL
)
450 parser
->user_data
= user_data
;
451 XML_SetUserData (parser
->expat_parser
, parser
);
453 /* Set the callbacks. */
454 XML_SetElementHandler (parser
->expat_parser
, gdb_xml_start_element_wrapper
,
455 gdb_xml_end_element_wrapper
);
456 XML_SetCharacterDataHandler (parser
->expat_parser
, gdb_xml_body_text
);
458 /* Initialize the outer scope. */
459 memset (&start_scope
, 0, sizeof (start_scope
));
460 start_scope
.elements
= elements
;
461 VEC_safe_push (scope_level_s
, parser
->scopes
, &start_scope
);
463 make_cleanup (gdb_xml_cleanup
, parser
);
468 /* External entity handler. The only external entities we support
469 are those compiled into GDB (we do not fetch entities from the
473 gdb_xml_fetch_external_entity (XML_Parser expat_parser
,
474 const XML_Char
*context
,
475 const XML_Char
*base
,
476 const XML_Char
*systemId
,
477 const XML_Char
*publicId
)
479 struct gdb_xml_parser
*parser
= XML_GetUserData (expat_parser
);
480 XML_Parser entity_parser
;
482 enum XML_Status status
;
484 if (systemId
== NULL
)
486 text
= fetch_xml_builtin (parser
->dtd_name
);
488 internal_error (__FILE__
, __LINE__
, "could not locate built-in DTD %s",
493 text
= fetch_xml_builtin (systemId
);
495 return XML_STATUS_ERROR
;
498 entity_parser
= XML_ExternalEntityParserCreate (expat_parser
, context
, NULL
);
500 /* Don't use our handlers for the contents of the DTD. Just let expat
502 XML_SetElementHandler (entity_parser
, NULL
, NULL
);
503 XML_SetDoctypeDeclHandler (entity_parser
, NULL
, NULL
);
504 XML_SetXmlDeclHandler (entity_parser
, NULL
);
505 XML_SetDefaultHandler (entity_parser
, NULL
);
506 XML_SetUserData (entity_parser
, NULL
);
508 status
= XML_Parse (entity_parser
, text
, strlen (text
), 1);
510 XML_ParserFree (entity_parser
);
514 /* Associate DTD_NAME, which must be the name of a compiled-in DTD,
518 gdb_xml_use_dtd (struct gdb_xml_parser
*parser
, const char *dtd_name
)
522 parser
->dtd_name
= dtd_name
;
524 XML_SetParamEntityParsing (parser
->expat_parser
,
525 XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
);
526 XML_SetExternalEntityRefHandler (parser
->expat_parser
,
527 gdb_xml_fetch_external_entity
);
529 /* Even if no DTD is provided, use the built-in DTD anyway. */
530 err
= XML_UseForeignDTD (parser
->expat_parser
, XML_TRUE
);
531 if (err
!= XML_ERROR_NONE
)
532 internal_error (__FILE__
, __LINE__
,
533 "XML_UseForeignDTD failed: %s", XML_ErrorString (err
));
536 /* Invoke PARSER on BUFFER. BUFFER is the data to parse, which
537 should be NUL-terminated.
539 The return value is 0 for success or -1 for error. It may throw,
540 but only if something unexpected goes wrong during parsing; parse
541 errors will be caught, warned about, and reported as failure. */
544 gdb_xml_parse (struct gdb_xml_parser
*parser
, const char *buffer
)
546 enum XML_Status status
;
547 const char *error_string
;
549 status
= XML_Parse (parser
->expat_parser
, buffer
, strlen (buffer
), 1);
551 if (status
== XML_STATUS_OK
&& parser
->error
.reason
== 0)
554 if (parser
->error
.reason
== RETURN_ERROR
555 && parser
->error
.error
== XML_PARSE_ERROR
)
557 gdb_assert (parser
->error
.message
!= NULL
);
558 error_string
= parser
->error
.message
;
560 else if (status
== XML_STATUS_ERROR
)
562 enum XML_Error err
= XML_GetErrorCode (parser
->expat_parser
);
563 error_string
= XML_ErrorString (err
);
567 gdb_assert (parser
->error
.reason
< 0);
568 throw_exception (parser
->error
);
571 if (parser
->last_line
!= 0)
572 warning (_("while parsing %s (at line %d): %s"), parser
->name
,
573 parser
->last_line
, error_string
);
575 warning (_("while parsing %s: %s"), parser
->name
, error_string
);
580 /* Parse a field VALSTR that we expect to contain an integer value.
581 The integer is returned in *VALP. The string is parsed with an
582 equivalent to strtoul.
584 Returns 0 for success, -1 for error. */
587 xml_parse_unsigned_integer (const char *valstr
, ULONGEST
*valp
)
595 result
= strtoulst (valstr
, &endptr
, 0);
603 /* Parse an integer string into a ULONGEST and return it, or call
604 gdb_xml_error if it could not be parsed. */
607 gdb_xml_parse_ulongest (struct gdb_xml_parser
*parser
, const char *value
)
611 if (xml_parse_unsigned_integer (value
, &result
) != 0)
612 gdb_xml_error (parser
, _("Can't convert \"%s\" to an integer"), value
);
617 /* Parse an integer attribute into a ULONGEST. */
620 gdb_xml_parse_attr_ulongest (struct gdb_xml_parser
*parser
,
621 const struct gdb_xml_attribute
*attribute
,
627 if (xml_parse_unsigned_integer (value
, &result
) != 0)
628 gdb_xml_error (parser
, _("Can't convert %s=\"%s\" to an integer"),
629 attribute
->name
, value
);
631 ret
= xmalloc (sizeof (result
));
632 memcpy (ret
, &result
, sizeof (result
));
636 /* A handler_data for yes/no boolean values. */
638 const struct gdb_xml_enum gdb_xml_enums_boolean
[] = {
644 /* Map NAME to VALUE. A struct gdb_xml_enum * should be saved as the
645 value of handler_data when using gdb_xml_parse_attr_enum to parse a
646 fixed list of possible strings. The list is terminated by an entry
647 with NAME == NULL. */
650 gdb_xml_parse_attr_enum (struct gdb_xml_parser
*parser
,
651 const struct gdb_xml_attribute
*attribute
,
654 const struct gdb_xml_enum
*enums
= attribute
->handler_data
;
657 for (enums
= attribute
->handler_data
; enums
->name
!= NULL
; enums
++)
658 if (strcasecmp (enums
->name
, value
) == 0)
661 if (enums
->name
== NULL
)
662 gdb_xml_error (parser
, _("Unknown attribute value %s=\"%s\""),
663 attribute
->name
, value
);
665 ret
= xmalloc (sizeof (enums
->value
));
666 memcpy (ret
, &enums
->value
, sizeof (enums
->value
));
671 /* XInclude processing. This is done as a separate step from actually
672 parsing the document, so that we can produce a single combined XML
673 document - e.g. to hand to a front end or to simplify comparing two
674 documents. We make extensive use of XML_DefaultCurrent, to pass
675 input text directly into the output without reformatting or
678 We output the DOCTYPE declaration for the first document unchanged,
679 if present, and discard DOCTYPEs from included documents. Only the
680 one we pass through here is used when we feed the result back to
681 expat. The XInclude standard explicitly does not discuss
682 validation of the result; we choose to apply the same DTD applied
683 to the outermost document.
685 We can not simply include the external DTD subset in the document
686 as an internal subset, because <!IGNORE> and <!INCLUDE> are valid
687 only in external subsets. But if we do not pass the DTD into the
688 output at all, default values will not be filled in.
690 We don't pass through any <?xml> declaration because we generate
691 UTF-8, not whatever the input encoding was. */
693 struct xinclude_parsing_data
695 /* The obstack to build the output in. */
696 struct obstack obstack
;
698 /* A count indicating whether we are in an element whose
699 children should not be copied to the output, and if so,
700 how deep we are nested. This is used for anything inside
701 an xi:include, and for the DTD. */
704 /* The number of <xi:include> elements currently being processed,
708 /* A function to call to obtain additional features, and its
710 xml_fetch_another fetcher
;
715 xinclude_start_include (struct gdb_xml_parser
*parser
,
716 const struct gdb_xml_element
*element
,
717 void *user_data
, VEC(gdb_xml_value_s
) *attributes
)
719 struct xinclude_parsing_data
*data
= user_data
;
720 char *href
= VEC_index (gdb_xml_value_s
, attributes
, 0)->value
;
721 struct cleanup
*back_to
;
725 gdb_xml_debug (parser
, _("Processing XInclude of \"%s\""), href
);
727 if (data
->include_depth
> MAX_XINCLUDE_DEPTH
)
728 gdb_xml_error (parser
, _("Maximum XInclude depth (%d) exceeded"),
731 text
= data
->fetcher (href
, data
->fetcher_baton
);
733 gdb_xml_error (parser
, _("Could not load XML document \"%s\""), href
);
734 back_to
= make_cleanup (xfree
, text
);
736 output
= xml_process_xincludes (parser
->name
, text
, data
->fetcher
,
738 data
->include_depth
+ 1);
740 gdb_xml_error (parser
, _("Parsing \"%s\" failed"), href
);
742 obstack_grow (&data
->obstack
, output
, strlen (output
));
745 do_cleanups (back_to
);
751 xinclude_end_include (struct gdb_xml_parser
*parser
,
752 const struct gdb_xml_element
*element
,
753 void *user_data
, const char *body_text
)
755 struct xinclude_parsing_data
*data
= user_data
;
761 xml_xinclude_default (void *data_
, const XML_Char
*s
, int len
)
763 struct gdb_xml_parser
*parser
= data_
;
764 struct xinclude_parsing_data
*data
= parser
->user_data
;
766 /* If we are inside of e.g. xi:include or the DTD, don't save this
768 if (data
->skip_depth
)
771 /* Otherwise just add it to the end of the document we're building
773 obstack_grow (&data
->obstack
, s
, len
);
777 xml_xinclude_start_doctype (void *data_
, const XML_Char
*doctypeName
,
778 const XML_Char
*sysid
, const XML_Char
*pubid
,
779 int has_internal_subset
)
781 struct gdb_xml_parser
*parser
= data_
;
782 struct xinclude_parsing_data
*data
= parser
->user_data
;
784 /* Don't print out the doctype, or the contents of the DTD internal
790 xml_xinclude_end_doctype (void *data_
)
792 struct gdb_xml_parser
*parser
= data_
;
793 struct xinclude_parsing_data
*data
= parser
->user_data
;
799 xml_xinclude_xml_decl (void *data_
, const XML_Char
*version
,
800 const XML_Char
*encoding
, int standalone
)
802 /* Do nothing - this function prevents the default handler from
803 being called, thus suppressing the XML declaration from the
808 xml_xinclude_cleanup (void *data_
)
810 struct xinclude_parsing_data
*data
= data_
;
812 obstack_free (&data
->obstack
, NULL
);
816 const struct gdb_xml_attribute xinclude_attributes
[] = {
817 { "href", GDB_XML_AF_NONE
, NULL
, NULL
},
818 { NULL
, GDB_XML_AF_NONE
, NULL
, NULL
}
821 const struct gdb_xml_element xinclude_elements
[] = {
822 { "http://www.w3.org/2001/XInclude!include", xinclude_attributes
, NULL
,
823 GDB_XML_EF_OPTIONAL
| GDB_XML_EF_REPEATABLE
,
824 xinclude_start_include
, xinclude_end_include
},
825 { NULL
, NULL
, NULL
, GDB_XML_EF_NONE
, NULL
, NULL
}
828 /* The main entry point for <xi:include> processing. */
831 xml_process_xincludes (const char *name
, const char *text
,
832 xml_fetch_another fetcher
, void *fetcher_baton
,
836 struct gdb_xml_parser
*parser
;
837 struct xinclude_parsing_data
*data
;
838 struct cleanup
*back_to
;
841 data
= XZALLOC (struct xinclude_parsing_data
);
842 obstack_init (&data
->obstack
);
843 back_to
= make_cleanup (xml_xinclude_cleanup
, data
);
845 parser
= gdb_xml_create_parser_and_cleanup (name
, xinclude_elements
, data
);
846 parser
->is_xinclude
= 1;
848 data
->include_depth
= depth
;
849 data
->fetcher
= fetcher
;
850 data
->fetcher_baton
= fetcher_baton
;
852 XML_SetCharacterDataHandler (parser
->expat_parser
, NULL
);
853 XML_SetDefaultHandler (parser
->expat_parser
, xml_xinclude_default
);
855 /* Always discard the XML version declarations; the only important
856 thing this provides is encoding, and our result will have been
857 converted to UTF-8. */
858 XML_SetXmlDeclHandler (parser
->expat_parser
, xml_xinclude_xml_decl
);
861 /* Discard the doctype for included documents. */
862 XML_SetDoctypeDeclHandler (parser
->expat_parser
,
863 xml_xinclude_start_doctype
,
864 xml_xinclude_end_doctype
);
866 gdb_xml_use_dtd (parser
, "xinclude.dtd");
868 if (gdb_xml_parse (parser
, text
) == 0)
870 obstack_1grow (&data
->obstack
, '\0');
871 result
= xstrdup (obstack_finish (&data
->obstack
));
874 gdb_xml_debug (parser
, _("XInclude processing succeeded:\n%s"),
880 do_cleanups (back_to
);
883 #endif /* HAVE_LIBEXPAT */
886 /* Return an XML document which was compiled into GDB, from
887 the given FILENAME, or NULL if the file was not compiled in. */
890 fetch_xml_builtin (const char *filename
)
894 for (p
= xml_builtin
; (*p
)[0]; p
++)
895 if (strcmp ((*p
)[0], filename
) == 0)
901 /* A to_xfer_partial helper function which reads XML files which were
902 compiled into GDB. The target may call this function from its own
903 to_xfer_partial handler, after converting object and annex to the
904 appropriate filename. */
907 xml_builtin_xfer_partial (const char *filename
,
908 gdb_byte
*readbuf
, const gdb_byte
*writebuf
,
909 ULONGEST offset
, LONGEST len
)
914 gdb_assert (readbuf
!= NULL
&& writebuf
== NULL
);
915 gdb_assert (filename
!= NULL
);
917 buf
= fetch_xml_builtin (filename
);
921 len_avail
= strlen (buf
);
922 if (offset
>= len_avail
)
925 if (len
> len_avail
- offset
)
926 len
= len_avail
- offset
;
927 memcpy (readbuf
, buf
+ offset
, len
);
933 show_debug_xml (struct ui_file
*file
, int from_tty
,
934 struct cmd_list_element
*c
, const char *value
)
936 fprintf_filtered (file
, _("XML debugging is %s.\n"), value
);
939 void _initialize_xml_support (void);
942 _initialize_xml_support (void)
944 add_setshow_boolean_cmd ("xml", class_maintenance
, &debug_xml
,
945 _("Set XML parser debugging."),
946 _("Show XML parser debugging."),
947 _("When set, debugging messages for XML parsers "
949 NULL
, show_debug_xml
,
950 &setdebuglist
, &showdebuglist
);