1 /* Helper routines for parsing XML using Expat.
3 Copyright (C) 2006-2013 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 "exceptions.h"
23 #include "xml-support.h"
25 #include "gdb_string.h"
26 #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 /* Elements we allow at this level. */
48 const struct gdb_xml_element
*elements
;
50 /* The element which we are within. */
51 const struct gdb_xml_element
*element
;
53 /* Mask of which elements we've seen at this level (used for
54 optional and repeatable checking). */
57 /* Body text accumulation. */
60 typedef struct scope_level scope_level_s
;
61 DEF_VEC_O(scope_level_s
);
63 /* The parser itself, and our additional state. */
66 XML_Parser expat_parser
; /* The underlying expat parser. */
68 const char *name
; /* Name of this parser. */
69 void *user_data
; /* The user's callback data, for handlers. */
71 VEC(scope_level_s
) *scopes
; /* Scoping stack. */
73 struct gdb_exception error
; /* A thrown error, if any. */
74 int last_line
; /* The line of the thrown error, or 0. */
76 const char *dtd_name
; /* The name of the expected / default DTD,
78 int is_xinclude
; /* Are we the special <xi:include> parser? */
81 /* Process some body text. We accumulate the text for later use; it's
82 wrong to do anything with it immediately, because a single block of
83 text might be broken up into multiple calls to this function. */
86 gdb_xml_body_text (void *data
, const XML_Char
*text
, int length
)
88 struct gdb_xml_parser
*parser
= data
;
89 struct scope_level
*scope
= VEC_last (scope_level_s
, parser
->scopes
);
91 if (parser
->error
.reason
< 0)
94 if (scope
->body
== NULL
)
96 scope
->body
= XZALLOC (struct obstack
);
97 obstack_init (scope
->body
);
100 obstack_grow (scope
->body
, text
, length
);
103 /* Issue a debugging message from one of PARSER's handlers. */
106 gdb_xml_debug (struct gdb_xml_parser
*parser
, const char *format
, ...)
108 int line
= XML_GetCurrentLineNumber (parser
->expat_parser
);
115 va_start (ap
, format
);
116 message
= xstrvprintf (format
, ap
);
118 fprintf_unfiltered (gdb_stderr
, "%s (line %d): %s\n",
119 parser
->name
, line
, message
);
121 fprintf_unfiltered (gdb_stderr
, "%s: %s\n",
122 parser
->name
, message
);
126 /* Issue an error message from one of PARSER's handlers, and stop
130 gdb_xml_error (struct gdb_xml_parser
*parser
, const char *format
, ...)
132 int line
= XML_GetCurrentLineNumber (parser
->expat_parser
);
135 parser
->last_line
= line
;
136 va_start (ap
, format
);
137 throw_verror (XML_PARSE_ERROR
, format
, ap
);
140 /* Find the attribute named NAME in the set of parsed attributes
141 ATTRIBUTES. Returns NULL if not found. */
143 struct gdb_xml_value
*
144 xml_find_attribute (VEC(gdb_xml_value_s
) *attributes
, const char *name
)
146 struct gdb_xml_value
*value
;
149 for (ix
= 0; VEC_iterate (gdb_xml_value_s
, attributes
, ix
, value
); ix
++)
150 if (strcmp (value
->name
, name
) == 0)
156 /* Clean up a vector of parsed attribute values. */
159 gdb_xml_values_cleanup (void *data
)
161 VEC(gdb_xml_value_s
) **values
= data
;
162 struct gdb_xml_value
*value
;
165 for (ix
= 0; VEC_iterate (gdb_xml_value_s
, *values
, ix
, value
); ix
++)
166 xfree (value
->value
);
167 VEC_free (gdb_xml_value_s
, *values
);
170 /* Handle the start of an element. DATA is our local XML parser, NAME
171 is the element, and ATTRS are the names and values of this
172 element's attributes. */
175 gdb_xml_start_element (void *data
, const XML_Char
*name
,
176 const XML_Char
**attrs
)
178 struct gdb_xml_parser
*parser
= data
;
179 struct scope_level
*scope
;
180 struct scope_level new_scope
;
181 const struct gdb_xml_element
*element
;
182 const struct gdb_xml_attribute
*attribute
;
183 VEC(gdb_xml_value_s
) *attributes
= NULL
;
185 struct cleanup
*back_to
;
187 /* Push an error scope. If we return or throw an exception before
188 filling this in, it will tell us to ignore children of this
190 VEC_reserve (scope_level_s
, parser
->scopes
, 1);
191 scope
= VEC_last (scope_level_s
, parser
->scopes
);
192 memset (&new_scope
, 0, sizeof (new_scope
));
193 VEC_quick_push (scope_level_s
, parser
->scopes
, &new_scope
);
195 gdb_xml_debug (parser
, _("Entering element <%s>"), name
);
197 /* Find this element in the list of the current scope's allowed
198 children. Record that we've seen it. */
201 for (element
= scope
->elements
; element
&& element
->name
;
202 element
++, seen
<<= 1)
203 if (strcmp (element
->name
, name
) == 0)
206 if (element
== NULL
|| element
->name
== NULL
)
208 /* If we're working on XInclude, <xi:include> can be the child
209 of absolutely anything. Copy the previous scope's element
210 list into the new scope even if there was no match. */
211 if (parser
->is_xinclude
)
213 struct scope_level
*unknown_scope
;
215 XML_DefaultCurrent (parser
->expat_parser
);
217 unknown_scope
= VEC_last (scope_level_s
, parser
->scopes
);
218 unknown_scope
->elements
= scope
->elements
;
222 gdb_xml_debug (parser
, _("Element <%s> unknown"), name
);
226 if (!(element
->flags
& GDB_XML_EF_REPEATABLE
) && (seen
& scope
->seen
))
227 gdb_xml_error (parser
, _("Element <%s> only expected once"), name
);
231 back_to
= make_cleanup (gdb_xml_values_cleanup
, &attributes
);
233 for (attribute
= element
->attributes
;
234 attribute
!= NULL
&& attribute
->name
!= NULL
;
237 const char *val
= NULL
;
240 struct gdb_xml_value new_value
;
242 for (p
= attrs
; *p
!= NULL
; p
+= 2)
243 if (!strcmp (attribute
->name
, p
[0]))
249 if (*p
!= NULL
&& val
== NULL
)
251 gdb_xml_debug (parser
, _("Attribute \"%s\" missing a value"),
256 if (*p
== NULL
&& !(attribute
->flags
& GDB_XML_AF_OPTIONAL
))
258 gdb_xml_error (parser
, _("Required attribute \"%s\" of "
259 "<%s> not specified"),
260 attribute
->name
, element
->name
);
267 gdb_xml_debug (parser
, _("Parsing attribute %s=\"%s\""),
268 attribute
->name
, val
);
270 if (attribute
->handler
)
271 parsed_value
= attribute
->handler (parser
, attribute
, val
);
273 parsed_value
= xstrdup (val
);
275 new_value
.name
= attribute
->name
;
276 new_value
.value
= parsed_value
;
277 VEC_safe_push (gdb_xml_value_s
, attributes
, &new_value
);
280 /* Check for unrecognized attributes. */
285 for (p
= attrs
; *p
!= NULL
; p
+= 2)
287 for (attribute
= element
->attributes
;
288 attribute
!= NULL
&& attribute
->name
!= NULL
;
290 if (strcmp (attribute
->name
, *p
) == 0)
293 if (attribute
== NULL
|| attribute
->name
== NULL
)
294 gdb_xml_debug (parser
, _("Ignoring unknown attribute %s"), *p
);
298 /* Call the element handler if there is one. */
299 if (element
->start_handler
)
300 element
->start_handler (parser
, element
, parser
->user_data
, attributes
);
302 /* Fill in a new scope level. */
303 scope
= VEC_last (scope_level_s
, parser
->scopes
);
304 scope
->element
= element
;
305 scope
->elements
= element
->children
;
307 do_cleanups (back_to
);
310 /* Wrapper for gdb_xml_start_element, to prevent throwing exceptions
314 gdb_xml_start_element_wrapper (void *data
, const XML_Char
*name
,
315 const XML_Char
**attrs
)
317 struct gdb_xml_parser
*parser
= data
;
318 volatile struct gdb_exception ex
;
320 if (parser
->error
.reason
< 0)
323 TRY_CATCH (ex
, RETURN_MASK_ALL
)
325 gdb_xml_start_element (data
, name
, attrs
);
330 #ifdef HAVE_XML_STOPPARSER
331 XML_StopParser (parser
->expat_parser
, XML_FALSE
);
336 /* Handle the end of an element. DATA is our local XML parser, and
337 NAME is the current element. */
340 gdb_xml_end_element (void *data
, const XML_Char
*name
)
342 struct gdb_xml_parser
*parser
= data
;
343 struct scope_level
*scope
= VEC_last (scope_level_s
, parser
->scopes
);
344 const struct gdb_xml_element
*element
;
347 gdb_xml_debug (parser
, _("Leaving element <%s>"), name
);
349 for (element
= scope
->elements
, seen
= 1;
350 element
!= NULL
&& element
->name
!= NULL
;
351 element
++, seen
<<= 1)
352 if ((scope
->seen
& seen
) == 0
353 && (element
->flags
& GDB_XML_EF_OPTIONAL
) == 0)
354 gdb_xml_error (parser
, _("Required element <%s> is missing"),
357 /* Call the element processor. */
358 if (scope
->element
!= NULL
&& scope
->element
->end_handler
)
362 if (scope
->body
== NULL
)
368 length
= obstack_object_size (scope
->body
);
369 obstack_1grow (scope
->body
, '\0');
370 body
= obstack_finish (scope
->body
);
372 /* Strip leading and trailing whitespace. */
373 while (length
> 0 && ISSPACE (body
[length
-1]))
374 body
[--length
] = '\0';
375 while (*body
&& ISSPACE (*body
))
379 scope
->element
->end_handler (parser
, scope
->element
, parser
->user_data
,
382 else if (scope
->element
== NULL
)
383 XML_DefaultCurrent (parser
->expat_parser
);
385 /* Pop the scope level. */
388 obstack_free (scope
->body
, NULL
);
391 VEC_pop (scope_level_s
, parser
->scopes
);
394 /* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
398 gdb_xml_end_element_wrapper (void *data
, const XML_Char
*name
)
400 struct gdb_xml_parser
*parser
= data
;
401 volatile struct gdb_exception ex
;
403 if (parser
->error
.reason
< 0)
406 TRY_CATCH (ex
, RETURN_MASK_ALL
)
408 gdb_xml_end_element (data
, name
);
413 #ifdef HAVE_XML_STOPPARSER
414 XML_StopParser (parser
->expat_parser
, XML_FALSE
);
419 /* Free a parser and all its associated state. */
422 gdb_xml_cleanup (void *arg
)
424 struct gdb_xml_parser
*parser
= arg
;
425 struct scope_level
*scope
;
428 XML_ParserFree (parser
->expat_parser
);
430 /* Clean up the scopes. */
431 for (ix
= 0; VEC_iterate (scope_level_s
, parser
->scopes
, ix
, scope
); ix
++)
434 obstack_free (scope
->body
, NULL
);
437 VEC_free (scope_level_s
, parser
->scopes
);
442 /* Initialize and return a parser. Register a cleanup to destroy the
445 static struct gdb_xml_parser
*
446 gdb_xml_create_parser_and_cleanup_1 (const char *name
,
447 const struct gdb_xml_element
*elements
,
448 void *user_data
, struct cleanup
**old_chain
)
450 struct gdb_xml_parser
*parser
;
451 struct scope_level start_scope
;
452 struct cleanup
*dummy
;
454 /* Initialize the parser. */
455 parser
= XZALLOC (struct gdb_xml_parser
);
456 parser
->expat_parser
= XML_ParserCreateNS (NULL
, '!');
457 if (parser
->expat_parser
== NULL
)
465 parser
->user_data
= user_data
;
466 XML_SetUserData (parser
->expat_parser
, parser
);
468 /* Set the callbacks. */
469 XML_SetElementHandler (parser
->expat_parser
, gdb_xml_start_element_wrapper
,
470 gdb_xml_end_element_wrapper
);
471 XML_SetCharacterDataHandler (parser
->expat_parser
, gdb_xml_body_text
);
473 /* Initialize the outer scope. */
474 memset (&start_scope
, 0, sizeof (start_scope
));
475 start_scope
.elements
= elements
;
476 VEC_safe_push (scope_level_s
, parser
->scopes
, &start_scope
);
478 if (old_chain
== NULL
)
481 *old_chain
= make_cleanup (gdb_xml_cleanup
, parser
);
485 /* Initialize and return a parser. Register a cleanup to destroy the
488 struct gdb_xml_parser
*
489 gdb_xml_create_parser_and_cleanup (const char *name
,
490 const struct gdb_xml_element
*elements
,
493 struct cleanup
*old_chain
;
495 return gdb_xml_create_parser_and_cleanup_1 (name
, elements
, user_data
,
499 /* External entity handler. The only external entities we support
500 are those compiled into GDB (we do not fetch entities from the
504 gdb_xml_fetch_external_entity (XML_Parser expat_parser
,
505 const XML_Char
*context
,
506 const XML_Char
*base
,
507 const XML_Char
*systemId
,
508 const XML_Char
*publicId
)
510 struct gdb_xml_parser
*parser
= XML_GetUserData (expat_parser
);
511 XML_Parser entity_parser
;
513 enum XML_Status status
;
515 if (systemId
== NULL
)
517 text
= fetch_xml_builtin (parser
->dtd_name
);
519 internal_error (__FILE__
, __LINE__
,
520 _("could not locate built-in DTD %s"),
525 text
= fetch_xml_builtin (systemId
);
527 return XML_STATUS_ERROR
;
530 entity_parser
= XML_ExternalEntityParserCreate (expat_parser
, context
, NULL
);
532 /* Don't use our handlers for the contents of the DTD. Just let expat
534 XML_SetElementHandler (entity_parser
, NULL
, NULL
);
535 XML_SetDoctypeDeclHandler (entity_parser
, NULL
, NULL
);
536 XML_SetXmlDeclHandler (entity_parser
, NULL
);
537 XML_SetDefaultHandler (entity_parser
, NULL
);
538 XML_SetUserData (entity_parser
, NULL
);
540 status
= XML_Parse (entity_parser
, text
, strlen (text
), 1);
542 XML_ParserFree (entity_parser
);
546 /* Associate DTD_NAME, which must be the name of a compiled-in DTD,
550 gdb_xml_use_dtd (struct gdb_xml_parser
*parser
, const char *dtd_name
)
554 parser
->dtd_name
= dtd_name
;
556 XML_SetParamEntityParsing (parser
->expat_parser
,
557 XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
);
558 XML_SetExternalEntityRefHandler (parser
->expat_parser
,
559 gdb_xml_fetch_external_entity
);
561 /* Even if no DTD is provided, use the built-in DTD anyway. */
562 err
= XML_UseForeignDTD (parser
->expat_parser
, XML_TRUE
);
563 if (err
!= XML_ERROR_NONE
)
564 internal_error (__FILE__
, __LINE__
,
565 _("XML_UseForeignDTD failed: %s"),
566 XML_ErrorString (err
));
569 /* Invoke PARSER on BUFFER. BUFFER is the data to parse, which
570 should be NUL-terminated.
572 The return value is 0 for success or -1 for error. It may throw,
573 but only if something unexpected goes wrong during parsing; parse
574 errors will be caught, warned about, and reported as failure. */
577 gdb_xml_parse (struct gdb_xml_parser
*parser
, const char *buffer
)
579 enum XML_Status status
;
580 const char *error_string
;
582 gdb_xml_debug (parser
, _("Starting:\n%s"), buffer
);
584 status
= XML_Parse (parser
->expat_parser
, buffer
, strlen (buffer
), 1);
586 if (status
== XML_STATUS_OK
&& parser
->error
.reason
== 0)
589 if (parser
->error
.reason
== RETURN_ERROR
590 && parser
->error
.error
== XML_PARSE_ERROR
)
592 gdb_assert (parser
->error
.message
!= NULL
);
593 error_string
= parser
->error
.message
;
595 else if (status
== XML_STATUS_ERROR
)
597 enum XML_Error err
= XML_GetErrorCode (parser
->expat_parser
);
599 error_string
= XML_ErrorString (err
);
603 gdb_assert (parser
->error
.reason
< 0);
604 throw_exception (parser
->error
);
607 if (parser
->last_line
!= 0)
608 warning (_("while parsing %s (at line %d): %s"), parser
->name
,
609 parser
->last_line
, error_string
);
611 warning (_("while parsing %s: %s"), parser
->name
, error_string
);
617 gdb_xml_parse_quick (const char *name
, const char *dtd_name
,
618 const struct gdb_xml_element
*elements
,
619 const char *document
, void *user_data
)
621 struct gdb_xml_parser
*parser
;
622 struct cleanup
*back_to
;
625 parser
= gdb_xml_create_parser_and_cleanup_1 (name
, elements
,
626 user_data
, &back_to
);
627 if (dtd_name
!= NULL
)
628 gdb_xml_use_dtd (parser
, dtd_name
);
629 result
= gdb_xml_parse (parser
, document
);
631 do_cleanups (back_to
);
636 /* Parse a field VALSTR that we expect to contain an integer value.
637 The integer is returned in *VALP. The string is parsed with an
638 equivalent to strtoul.
640 Returns 0 for success, -1 for error. */
643 xml_parse_unsigned_integer (const char *valstr
, ULONGEST
*valp
)
651 result
= strtoulst (valstr
, &endptr
, 0);
659 /* Parse an integer string into a ULONGEST and return it, or call
660 gdb_xml_error if it could not be parsed. */
663 gdb_xml_parse_ulongest (struct gdb_xml_parser
*parser
, const char *value
)
667 if (xml_parse_unsigned_integer (value
, &result
) != 0)
668 gdb_xml_error (parser
, _("Can't convert \"%s\" to an integer"), value
);
673 /* Parse an integer attribute into a ULONGEST. */
676 gdb_xml_parse_attr_ulongest (struct gdb_xml_parser
*parser
,
677 const struct gdb_xml_attribute
*attribute
,
683 if (xml_parse_unsigned_integer (value
, &result
) != 0)
684 gdb_xml_error (parser
, _("Can't convert %s=\"%s\" to an integer"),
685 attribute
->name
, value
);
687 ret
= xmalloc (sizeof (result
));
688 memcpy (ret
, &result
, sizeof (result
));
692 /* A handler_data for yes/no boolean values. */
694 const struct gdb_xml_enum gdb_xml_enums_boolean
[] = {
700 /* Map NAME to VALUE. A struct gdb_xml_enum * should be saved as the
701 value of handler_data when using gdb_xml_parse_attr_enum to parse a
702 fixed list of possible strings. The list is terminated by an entry
703 with NAME == NULL. */
706 gdb_xml_parse_attr_enum (struct gdb_xml_parser
*parser
,
707 const struct gdb_xml_attribute
*attribute
,
710 const struct gdb_xml_enum
*enums
= attribute
->handler_data
;
713 for (enums
= attribute
->handler_data
; enums
->name
!= NULL
; enums
++)
714 if (strcasecmp (enums
->name
, value
) == 0)
717 if (enums
->name
== NULL
)
718 gdb_xml_error (parser
, _("Unknown attribute value %s=\"%s\""),
719 attribute
->name
, value
);
721 ret
= xmalloc (sizeof (enums
->value
));
722 memcpy (ret
, &enums
->value
, sizeof (enums
->value
));
727 /* XInclude processing. This is done as a separate step from actually
728 parsing the document, so that we can produce a single combined XML
729 document - e.g. to hand to a front end or to simplify comparing two
730 documents. We make extensive use of XML_DefaultCurrent, to pass
731 input text directly into the output without reformatting or
734 We output the DOCTYPE declaration for the first document unchanged,
735 if present, and discard DOCTYPEs from included documents. Only the
736 one we pass through here is used when we feed the result back to
737 expat. The XInclude standard explicitly does not discuss
738 validation of the result; we choose to apply the same DTD applied
739 to the outermost document.
741 We can not simply include the external DTD subset in the document
742 as an internal subset, because <!IGNORE> and <!INCLUDE> are valid
743 only in external subsets. But if we do not pass the DTD into the
744 output at all, default values will not be filled in.
746 We don't pass through any <?xml> declaration because we generate
747 UTF-8, not whatever the input encoding was. */
749 struct xinclude_parsing_data
751 /* The obstack to build the output in. */
752 struct obstack obstack
;
754 /* A count indicating whether we are in an element whose
755 children should not be copied to the output, and if so,
756 how deep we are nested. This is used for anything inside
757 an xi:include, and for the DTD. */
760 /* The number of <xi:include> elements currently being processed,
764 /* A function to call to obtain additional features, and its
766 xml_fetch_another fetcher
;
771 xinclude_start_include (struct gdb_xml_parser
*parser
,
772 const struct gdb_xml_element
*element
,
773 void *user_data
, VEC(gdb_xml_value_s
) *attributes
)
775 struct xinclude_parsing_data
*data
= user_data
;
776 char *href
= xml_find_attribute (attributes
, "href")->value
;
777 struct cleanup
*back_to
;
780 gdb_xml_debug (parser
, _("Processing XInclude of \"%s\""), href
);
782 if (data
->include_depth
> MAX_XINCLUDE_DEPTH
)
783 gdb_xml_error (parser
, _("Maximum XInclude depth (%d) exceeded"),
786 text
= data
->fetcher (href
, data
->fetcher_baton
);
788 gdb_xml_error (parser
, _("Could not load XML document \"%s\""), href
);
789 back_to
= make_cleanup (xfree
, text
);
791 output
= xml_process_xincludes (parser
->name
, text
, data
->fetcher
,
793 data
->include_depth
+ 1);
795 gdb_xml_error (parser
, _("Parsing \"%s\" failed"), href
);
797 obstack_grow (&data
->obstack
, output
, strlen (output
));
800 do_cleanups (back_to
);
806 xinclude_end_include (struct gdb_xml_parser
*parser
,
807 const struct gdb_xml_element
*element
,
808 void *user_data
, const char *body_text
)
810 struct xinclude_parsing_data
*data
= user_data
;
816 xml_xinclude_default (void *data_
, const XML_Char
*s
, int len
)
818 struct gdb_xml_parser
*parser
= data_
;
819 struct xinclude_parsing_data
*data
= parser
->user_data
;
821 /* If we are inside of e.g. xi:include or the DTD, don't save this
823 if (data
->skip_depth
)
826 /* Otherwise just add it to the end of the document we're building
828 obstack_grow (&data
->obstack
, s
, len
);
832 xml_xinclude_start_doctype (void *data_
, const XML_Char
*doctypeName
,
833 const XML_Char
*sysid
, const XML_Char
*pubid
,
834 int has_internal_subset
)
836 struct gdb_xml_parser
*parser
= data_
;
837 struct xinclude_parsing_data
*data
= parser
->user_data
;
839 /* Don't print out the doctype, or the contents of the DTD internal
845 xml_xinclude_end_doctype (void *data_
)
847 struct gdb_xml_parser
*parser
= data_
;
848 struct xinclude_parsing_data
*data
= parser
->user_data
;
854 xml_xinclude_xml_decl (void *data_
, const XML_Char
*version
,
855 const XML_Char
*encoding
, int standalone
)
857 /* Do nothing - this function prevents the default handler from
858 being called, thus suppressing the XML declaration from the
863 xml_xinclude_cleanup (void *data_
)
865 struct xinclude_parsing_data
*data
= data_
;
867 obstack_free (&data
->obstack
, NULL
);
871 const struct gdb_xml_attribute xinclude_attributes
[] = {
872 { "href", GDB_XML_AF_NONE
, NULL
, NULL
},
873 { NULL
, GDB_XML_AF_NONE
, NULL
, NULL
}
876 const struct gdb_xml_element xinclude_elements
[] = {
877 { "http://www.w3.org/2001/XInclude!include", xinclude_attributes
, NULL
,
878 GDB_XML_EF_OPTIONAL
| GDB_XML_EF_REPEATABLE
,
879 xinclude_start_include
, xinclude_end_include
},
880 { NULL
, NULL
, NULL
, GDB_XML_EF_NONE
, NULL
, NULL
}
883 /* The main entry point for <xi:include> processing. */
886 xml_process_xincludes (const char *name
, const char *text
,
887 xml_fetch_another fetcher
, void *fetcher_baton
,
890 struct gdb_xml_parser
*parser
;
891 struct xinclude_parsing_data
*data
;
892 struct cleanup
*back_to
;
895 data
= XZALLOC (struct xinclude_parsing_data
);
896 obstack_init (&data
->obstack
);
897 back_to
= make_cleanup (xml_xinclude_cleanup
, data
);
899 parser
= gdb_xml_create_parser_and_cleanup (name
, xinclude_elements
, data
);
900 parser
->is_xinclude
= 1;
902 data
->include_depth
= depth
;
903 data
->fetcher
= fetcher
;
904 data
->fetcher_baton
= fetcher_baton
;
906 XML_SetCharacterDataHandler (parser
->expat_parser
, NULL
);
907 XML_SetDefaultHandler (parser
->expat_parser
, xml_xinclude_default
);
909 /* Always discard the XML version declarations; the only important
910 thing this provides is encoding, and our result will have been
911 converted to UTF-8. */
912 XML_SetXmlDeclHandler (parser
->expat_parser
, xml_xinclude_xml_decl
);
915 /* Discard the doctype for included documents. */
916 XML_SetDoctypeDeclHandler (parser
->expat_parser
,
917 xml_xinclude_start_doctype
,
918 xml_xinclude_end_doctype
);
920 gdb_xml_use_dtd (parser
, "xinclude.dtd");
922 if (gdb_xml_parse (parser
, text
) == 0)
924 obstack_1grow (&data
->obstack
, '\0');
925 result
= xstrdup (obstack_finish (&data
->obstack
));
928 gdb_xml_debug (parser
, _("XInclude processing succeeded."));
933 do_cleanups (back_to
);
936 #endif /* HAVE_LIBEXPAT */
939 /* Return an XML document which was compiled into GDB, from
940 the given FILENAME, or NULL if the file was not compiled in. */
943 fetch_xml_builtin (const char *filename
)
947 for (p
= xml_builtin
; (*p
)[0]; p
++)
948 if (strcmp ((*p
)[0], filename
) == 0)
954 /* A to_xfer_partial helper function which reads XML files which were
955 compiled into GDB. The target may call this function from its own
956 to_xfer_partial handler, after converting object and annex to the
957 appropriate filename. */
960 xml_builtin_xfer_partial (const char *filename
,
961 gdb_byte
*readbuf
, const gdb_byte
*writebuf
,
962 ULONGEST offset
, LONGEST len
)
967 gdb_assert (readbuf
!= NULL
&& writebuf
== NULL
);
968 gdb_assert (filename
!= NULL
);
970 buf
= fetch_xml_builtin (filename
);
974 len_avail
= strlen (buf
);
975 if (offset
>= len_avail
)
978 if (len
> len_avail
- offset
)
979 len
= len_avail
- offset
;
980 memcpy (readbuf
, buf
+ offset
, len
);
986 show_debug_xml (struct ui_file
*file
, int from_tty
,
987 struct cmd_list_element
*c
, const char *value
)
989 fprintf_filtered (file
, _("XML debugging is %s.\n"), value
);
993 obstack_xml_printf (struct obstack
*obstack
, const char *format
, ...)
1000 va_start (ap
, format
);
1003 for (f
= format
; *f
; f
++)
1012 char *a
= va_arg (ap
, char *);
1014 obstack_grow (obstack
, prev
, f
- prev
- 1);
1015 p
= xml_escape_text (a
);
1016 obstack_grow_str (obstack
, p
);
1028 obstack_grow_str (obstack
, prev
);
1033 xml_fetch_content_from_file (const char *filename
, void *baton
)
1035 const char *dirname
= baton
;
1037 struct cleanup
*back_to
;
1041 if (dirname
&& *dirname
)
1043 char *fullname
= concat (dirname
, "/", filename
, (char *) NULL
);
1045 if (fullname
== NULL
)
1047 file
= fopen (fullname
, FOPEN_RT
);
1051 file
= fopen (filename
, FOPEN_RT
);
1056 back_to
= make_cleanup_fclose (file
);
1058 /* Read in the whole file, one chunk at a time. */
1061 text
= xmalloc (len
);
1062 make_cleanup (free_current_contents
, &text
);
1067 /* Continue reading where the last read left off. Leave at least
1068 one byte so that we can NUL-terminate the result. */
1069 bytes_read
= fread (text
+ offset
, 1, len
- offset
- 1, file
);
1072 warning (_("Read error from \"%s\""), filename
);
1073 do_cleanups (back_to
);
1077 offset
+= bytes_read
;
1083 text
= xrealloc (text
, len
);
1087 discard_cleanups (back_to
);
1089 text
[offset
] = '\0';
1093 void _initialize_xml_support (void);
1096 _initialize_xml_support (void)
1098 add_setshow_boolean_cmd ("xml", class_maintenance
, &debug_xml
,
1099 _("Set XML parser debugging."),
1100 _("Show XML parser debugging."),
1101 _("When set, debugging messages for XML parsers "
1103 NULL
, show_debug_xml
,
1104 &setdebuglist
, &showdebuglist
);