virtio: Fix and activate PCI MSI-X support.
[dragonfly.git] / contrib / gdb-7 / gdb / xml-support.c
blob7ace5b9880a4815cbf061d9b3268e93615abb0ec
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/>. */
20 #include "defs.h"
21 #include "gdbcmd.h"
22 #include "exceptions.h"
23 #include "xml-support.h"
25 #include "gdb_string.h"
26 #include "safe-ctype.h"
28 /* Debugging flag. */
29 static int debug_xml;
31 /* The contents of this file are only useful if XML support is
32 available. */
33 #ifdef HAVE_LIBEXPAT
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
44 nesting. */
45 struct scope_level
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). */
55 unsigned int seen;
57 /* Body text accumulation. */
58 struct obstack *body;
60 typedef struct scope_level scope_level_s;
61 DEF_VEC_O(scope_level_s);
63 /* The parser itself, and our additional state. */
64 struct gdb_xml_parser
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,
77 if specified. */
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. */
85 static void
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)
92 return;
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. */
105 void
106 gdb_xml_debug (struct gdb_xml_parser *parser, const char *format, ...)
108 int line = XML_GetCurrentLineNumber (parser->expat_parser);
109 va_list ap;
110 char *message;
112 if (!debug_xml)
113 return;
115 va_start (ap, format);
116 message = xstrvprintf (format, ap);
117 if (line)
118 fprintf_unfiltered (gdb_stderr, "%s (line %d): %s\n",
119 parser->name, line, message);
120 else
121 fprintf_unfiltered (gdb_stderr, "%s: %s\n",
122 parser->name, message);
123 xfree (message);
126 /* Issue an error message from one of PARSER's handlers, and stop
127 parsing. */
129 void
130 gdb_xml_error (struct gdb_xml_parser *parser, const char *format, ...)
132 int line = XML_GetCurrentLineNumber (parser->expat_parser);
133 va_list ap;
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;
147 int ix;
149 for (ix = 0; VEC_iterate (gdb_xml_value_s, attributes, ix, value); ix++)
150 if (strcmp (value->name, name) == 0)
151 return value;
153 return NULL;
156 /* Clean up a vector of parsed attribute values. */
158 static void
159 gdb_xml_values_cleanup (void *data)
161 VEC(gdb_xml_value_s) **values = data;
162 struct gdb_xml_value *value;
163 int ix;
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. */
174 static void
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;
184 unsigned int seen;
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
189 element. */
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. */
200 seen = 1;
201 for (element = scope->elements; element && element->name;
202 element++, seen <<= 1)
203 if (strcmp (element->name, name) == 0)
204 break;
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;
219 return;
222 gdb_xml_debug (parser, _("Element <%s> unknown"), name);
223 return;
226 if (!(element->flags & GDB_XML_EF_REPEATABLE) && (seen & scope->seen))
227 gdb_xml_error (parser, _("Element <%s> only expected once"), name);
229 scope->seen |= seen;
231 back_to = make_cleanup (gdb_xml_values_cleanup, &attributes);
233 for (attribute = element->attributes;
234 attribute != NULL && attribute->name != NULL;
235 attribute++)
237 const char *val = NULL;
238 const XML_Char **p;
239 void *parsed_value;
240 struct gdb_xml_value new_value;
242 for (p = attrs; *p != NULL; p += 2)
243 if (!strcmp (attribute->name, p[0]))
245 val = p[1];
246 break;
249 if (*p != NULL && val == NULL)
251 gdb_xml_debug (parser, _("Attribute \"%s\" missing a value"),
252 attribute->name);
253 continue;
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);
261 continue;
264 if (*p == NULL)
265 continue;
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);
272 else
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. */
281 if (debug_xml)
283 const XML_Char **p;
285 for (p = attrs; *p != NULL; p += 2)
287 for (attribute = element->attributes;
288 attribute != NULL && attribute->name != NULL;
289 attribute++)
290 if (strcmp (attribute->name, *p) == 0)
291 break;
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
311 through expat. */
313 static void
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)
321 return;
323 TRY_CATCH (ex, RETURN_MASK_ALL)
325 gdb_xml_start_element (data, name, attrs);
327 if (ex.reason < 0)
329 parser->error = ex;
330 #ifdef HAVE_XML_STOPPARSER
331 XML_StopParser (parser->expat_parser, XML_FALSE);
332 #endif
336 /* Handle the end of an element. DATA is our local XML parser, and
337 NAME is the current element. */
339 static void
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;
345 unsigned int seen;
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"),
355 element->name);
357 /* Call the element processor. */
358 if (scope->element != NULL && scope->element->end_handler)
360 char *body;
362 if (scope->body == NULL)
363 body = "";
364 else
366 int length;
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))
376 body++;
379 scope->element->end_handler (parser, scope->element, parser->user_data,
380 body);
382 else if (scope->element == NULL)
383 XML_DefaultCurrent (parser->expat_parser);
385 /* Pop the scope level. */
386 if (scope->body)
388 obstack_free (scope->body, NULL);
389 xfree (scope->body);
391 VEC_pop (scope_level_s, parser->scopes);
394 /* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
395 through expat. */
397 static void
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)
404 return;
406 TRY_CATCH (ex, RETURN_MASK_ALL)
408 gdb_xml_end_element (data, name);
410 if (ex.reason < 0)
412 parser->error = ex;
413 #ifdef HAVE_XML_STOPPARSER
414 XML_StopParser (parser->expat_parser, XML_FALSE);
415 #endif
419 /* Free a parser and all its associated state. */
421 static void
422 gdb_xml_cleanup (void *arg)
424 struct gdb_xml_parser *parser = arg;
425 struct scope_level *scope;
426 int ix;
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++)
432 if (scope->body)
434 obstack_free (scope->body, NULL);
435 xfree (scope->body);
437 VEC_free (scope_level_s, parser->scopes);
439 xfree (parser);
442 /* Initialize and return a parser. Register a cleanup to destroy the
443 parser. */
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)
459 xfree (parser);
460 malloc_failure (0);
463 parser->name = name;
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)
479 old_chain = &dummy;
481 *old_chain = make_cleanup (gdb_xml_cleanup, parser);
482 return parser;
485 /* Initialize and return a parser. Register a cleanup to destroy the
486 parser. */
488 struct gdb_xml_parser *
489 gdb_xml_create_parser_and_cleanup (const char *name,
490 const struct gdb_xml_element *elements,
491 void *user_data)
493 struct cleanup *old_chain;
495 return gdb_xml_create_parser_and_cleanup_1 (name, elements, user_data,
496 &old_chain);
499 /* External entity handler. The only external entities we support
500 are those compiled into GDB (we do not fetch entities from the
501 target). */
503 static int XMLCALL
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;
512 const char *text;
513 enum XML_Status status;
515 if (systemId == NULL)
517 text = fetch_xml_builtin (parser->dtd_name);
518 if (text == NULL)
519 internal_error (__FILE__, __LINE__,
520 _("could not locate built-in DTD %s"),
521 parser->dtd_name);
523 else
525 text = fetch_xml_builtin (systemId);
526 if (text == NULL)
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
533 process it. */
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);
543 return status;
546 /* Associate DTD_NAME, which must be the name of a compiled-in DTD,
547 with PARSER. */
549 void
550 gdb_xml_use_dtd (struct gdb_xml_parser *parser, const char *dtd_name)
552 enum XML_Error err;
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)
587 return 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);
601 else
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);
610 else
611 warning (_("while parsing %s: %s"), parser->name, error_string);
613 return -1;
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;
623 int result;
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);
633 return result;
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. */
642 static int
643 xml_parse_unsigned_integer (const char *valstr, ULONGEST *valp)
645 const char *endptr;
646 ULONGEST result;
648 if (*valstr == '\0')
649 return -1;
651 result = strtoulst (valstr, &endptr, 0);
652 if (*endptr != '\0')
653 return -1;
655 *valp = result;
656 return 0;
659 /* Parse an integer string into a ULONGEST and return it, or call
660 gdb_xml_error if it could not be parsed. */
662 ULONGEST
663 gdb_xml_parse_ulongest (struct gdb_xml_parser *parser, const char *value)
665 ULONGEST result;
667 if (xml_parse_unsigned_integer (value, &result) != 0)
668 gdb_xml_error (parser, _("Can't convert \"%s\" to an integer"), value);
670 return result;
673 /* Parse an integer attribute into a ULONGEST. */
675 void *
676 gdb_xml_parse_attr_ulongest (struct gdb_xml_parser *parser,
677 const struct gdb_xml_attribute *attribute,
678 const char *value)
680 ULONGEST result;
681 void *ret;
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));
689 return ret;
692 /* A handler_data for yes/no boolean values. */
694 const struct gdb_xml_enum gdb_xml_enums_boolean[] = {
695 { "yes", 1 },
696 { "no", 0 },
697 { NULL, 0 }
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. */
705 void *
706 gdb_xml_parse_attr_enum (struct gdb_xml_parser *parser,
707 const struct gdb_xml_attribute *attribute,
708 const char *value)
710 const struct gdb_xml_enum *enums = attribute->handler_data;
711 void *ret;
713 for (enums = attribute->handler_data; enums->name != NULL; enums++)
714 if (strcasecmp (enums->name, value) == 0)
715 break;
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));
723 return ret;
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
732 requoting it.
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. */
758 int skip_depth;
760 /* The number of <xi:include> elements currently being processed,
761 to detect loops. */
762 int include_depth;
764 /* A function to call to obtain additional features, and its
765 baton. */
766 xml_fetch_another fetcher;
767 void *fetcher_baton;
770 static void
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;
778 char *text, *output;
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"),
784 MAX_XINCLUDE_DEPTH);
786 text = data->fetcher (href, data->fetcher_baton);
787 if (text == NULL)
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,
792 data->fetcher_baton,
793 data->include_depth + 1);
794 if (output == NULL)
795 gdb_xml_error (parser, _("Parsing \"%s\" failed"), href);
797 obstack_grow (&data->obstack, output, strlen (output));
798 xfree (output);
800 do_cleanups (back_to);
802 data->skip_depth++;
805 static void
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;
812 data->skip_depth--;
815 static void XMLCALL
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
822 string. */
823 if (data->skip_depth)
824 return;
826 /* Otherwise just add it to the end of the document we're building
827 up. */
828 obstack_grow (&data->obstack, s, len);
831 static void XMLCALL
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
840 subset, if any. */
841 data->skip_depth++;
844 static void XMLCALL
845 xml_xinclude_end_doctype (void *data_)
847 struct gdb_xml_parser *parser = data_;
848 struct xinclude_parsing_data *data = parser->user_data;
850 data->skip_depth--;
853 static void XMLCALL
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
859 output. */
862 static void
863 xml_xinclude_cleanup (void *data_)
865 struct xinclude_parsing_data *data = data_;
867 obstack_free (&data->obstack, NULL);
868 xfree (data);
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. */
885 char *
886 xml_process_xincludes (const char *name, const char *text,
887 xml_fetch_another fetcher, void *fetcher_baton,
888 int depth)
890 struct gdb_xml_parser *parser;
891 struct xinclude_parsing_data *data;
892 struct cleanup *back_to;
893 char *result = NULL;
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);
914 if (depth > 0)
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));
927 if (depth == 0)
928 gdb_xml_debug (parser, _("XInclude processing succeeded."));
930 else
931 result = NULL;
933 do_cleanups (back_to);
934 return result;
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. */
942 const char *
943 fetch_xml_builtin (const char *filename)
945 const char *(*p)[2];
947 for (p = xml_builtin; (*p)[0]; p++)
948 if (strcmp ((*p)[0], filename) == 0)
949 return (*p)[1];
951 return NULL;
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. */
959 LONGEST
960 xml_builtin_xfer_partial (const char *filename,
961 gdb_byte *readbuf, const gdb_byte *writebuf,
962 ULONGEST offset, LONGEST len)
964 const char *buf;
965 LONGEST len_avail;
967 gdb_assert (readbuf != NULL && writebuf == NULL);
968 gdb_assert (filename != NULL);
970 buf = fetch_xml_builtin (filename);
971 if (buf == NULL)
972 return -1;
974 len_avail = strlen (buf);
975 if (offset >= len_avail)
976 return 0;
978 if (len > len_avail - offset)
979 len = len_avail - offset;
980 memcpy (readbuf, buf + offset, len);
981 return len;
985 static void
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);
992 void
993 obstack_xml_printf (struct obstack *obstack, const char *format, ...)
995 va_list ap;
996 const char *f;
997 const char *prev;
998 int percent = 0;
1000 va_start (ap, format);
1002 prev = format;
1003 for (f = format; *f; f++)
1005 if (percent)
1007 switch (*f)
1009 case 's':
1011 char *p;
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);
1017 xfree (p);
1018 prev = f + 1;
1020 break;
1022 percent = 0;
1024 else if (*f == '%')
1025 percent = 1;
1028 obstack_grow_str (obstack, prev);
1029 va_end (ap);
1032 char *
1033 xml_fetch_content_from_file (const char *filename, void *baton)
1035 const char *dirname = baton;
1036 FILE *file;
1037 struct cleanup *back_to;
1038 char *text;
1039 size_t len, offset;
1041 if (dirname && *dirname)
1043 char *fullname = concat (dirname, "/", filename, (char *) NULL);
1045 if (fullname == NULL)
1046 malloc_failure (0);
1047 file = fopen (fullname, FOPEN_RT);
1048 xfree (fullname);
1050 else
1051 file = fopen (filename, FOPEN_RT);
1053 if (file == NULL)
1054 return NULL;
1056 back_to = make_cleanup_fclose (file);
1058 /* Read in the whole file, one chunk at a time. */
1059 len = 4096;
1060 offset = 0;
1061 text = xmalloc (len);
1062 make_cleanup (free_current_contents, &text);
1063 while (1)
1065 size_t bytes_read;
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);
1070 if (ferror (file))
1072 warning (_("Read error from \"%s\""), filename);
1073 do_cleanups (back_to);
1074 return NULL;
1077 offset += bytes_read;
1079 if (feof (file))
1080 break;
1082 len = len * 2;
1083 text = xrealloc (text, len);
1086 fclose (file);
1087 discard_cleanups (back_to);
1089 text[offset] = '\0';
1090 return text;
1093 void _initialize_xml_support (void);
1095 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 "
1102 "are displayed."),
1103 NULL, show_debug_xml,
1104 &setdebuglist, &showdebuglist);