xref: /dragonfly/contrib/gdb-7/gdb/xml-support.c (revision 6ca88057)
1 /* Helper routines for parsing XML using Expat.
2 
3    Copyright (C) 2006-2013 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "defs.h"
21 #include "gdbcmd.h"
22 #include "exceptions.h"
23 #include "xml-support.h"
24 
25 #include "gdb_string.h"
26 #include "safe-ctype.h"
27 
28 /* Debugging flag.  */
29 static int debug_xml;
30 
31 /* The contents of this file are only useful if XML support is
32    available.  */
33 #ifdef HAVE_LIBEXPAT
34 
35 #include "gdb_expat.h"
36 
37 /* The maximum depth of <xi:include> nesting.  No need to be miserly,
38    we just want to avoid running out of stack on loops.  */
39 #define MAX_XINCLUDE_DEPTH 30
40 
41 /* Simplified XML parser infrastructure.  */
42 
43 /* A parsing level -- used to keep track of the current element
44    nesting.  */
45 struct scope_level
46 {
47   /* Elements we allow at this level.  */
48   const struct gdb_xml_element *elements;
49 
50   /* The element which we are within.  */
51   const struct gdb_xml_element *element;
52 
53   /* Mask of which elements we've seen at this level (used for
54      optional and repeatable checking).  */
55   unsigned int seen;
56 
57   /* Body text accumulation.  */
58   struct obstack *body;
59 };
60 typedef struct scope_level scope_level_s;
61 DEF_VEC_O(scope_level_s);
62 
63 /* The parser itself, and our additional state.  */
64 struct gdb_xml_parser
65 {
66   XML_Parser expat_parser;	/* The underlying expat parser.  */
67 
68   const char *name;		/* Name of this parser.  */
69   void *user_data;		/* The user's callback data, for handlers.  */
70 
71   VEC(scope_level_s) *scopes;	/* Scoping stack.  */
72 
73   struct gdb_exception error;	/* A thrown error, if any.  */
74   int last_line;		/* The line of the thrown error, or 0.  */
75 
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?  */
79 };
80 
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.  */
84 
85 static void
86 gdb_xml_body_text (void *data, const XML_Char *text, int length)
87 {
88   struct gdb_xml_parser *parser = data;
89   struct scope_level *scope = VEC_last (scope_level_s, parser->scopes);
90 
91   if (parser->error.reason < 0)
92     return;
93 
94   if (scope->body == NULL)
95     {
96       scope->body = XZALLOC (struct obstack);
97       obstack_init (scope->body);
98     }
99 
100   obstack_grow (scope->body, text, length);
101 }
102 
103 /* Issue a debugging message from one of PARSER's handlers.  */
104 
105 void
106 gdb_xml_debug (struct gdb_xml_parser *parser, const char *format, ...)
107 {
108   int line = XML_GetCurrentLineNumber (parser->expat_parser);
109   va_list ap;
110   char *message;
111 
112   if (!debug_xml)
113     return;
114 
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);
124 }
125 
126 /* Issue an error message from one of PARSER's handlers, and stop
127    parsing.  */
128 
129 void
130 gdb_xml_error (struct gdb_xml_parser *parser, const char *format, ...)
131 {
132   int line = XML_GetCurrentLineNumber (parser->expat_parser);
133   va_list ap;
134 
135   parser->last_line = line;
136   va_start (ap, format);
137   throw_verror (XML_PARSE_ERROR, format, ap);
138 }
139 
140 /* Find the attribute named NAME in the set of parsed attributes
141    ATTRIBUTES.  Returns NULL if not found.  */
142 
143 struct gdb_xml_value *
144 xml_find_attribute (VEC(gdb_xml_value_s) *attributes, const char *name)
145 {
146   struct gdb_xml_value *value;
147   int ix;
148 
149   for (ix = 0; VEC_iterate (gdb_xml_value_s, attributes, ix, value); ix++)
150     if (strcmp (value->name, name) == 0)
151       return value;
152 
153   return NULL;
154 }
155 
156 /* Clean up a vector of parsed attribute values.  */
157 
158 static void
159 gdb_xml_values_cleanup (void *data)
160 {
161   VEC(gdb_xml_value_s) **values = data;
162   struct gdb_xml_value *value;
163   int ix;
164 
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);
168 }
169 
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.  */
173 
174 static void
175 gdb_xml_start_element (void *data, const XML_Char *name,
176 		       const XML_Char **attrs)
177 {
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;
186 
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);
194 
195   gdb_xml_debug (parser, _("Entering element <%s>"), name);
196 
197   /* Find this element in the list of the current scope's allowed
198      children.  Record that we've seen it.  */
199 
200   seen = 1;
201   for (element = scope->elements; element && element->name;
202        element++, seen <<= 1)
203     if (strcmp (element->name, name) == 0)
204       break;
205 
206   if (element == NULL || element->name == NULL)
207     {
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)
212 	{
213 	  struct scope_level *unknown_scope;
214 
215 	  XML_DefaultCurrent (parser->expat_parser);
216 
217 	  unknown_scope = VEC_last (scope_level_s, parser->scopes);
218 	  unknown_scope->elements = scope->elements;
219 	  return;
220 	}
221 
222       gdb_xml_debug (parser, _("Element <%s> unknown"), name);
223       return;
224     }
225 
226   if (!(element->flags & GDB_XML_EF_REPEATABLE) && (seen & scope->seen))
227     gdb_xml_error (parser, _("Element <%s> only expected once"), name);
228 
229   scope->seen |= seen;
230 
231   back_to = make_cleanup (gdb_xml_values_cleanup, &attributes);
232 
233   for (attribute = element->attributes;
234        attribute != NULL && attribute->name != NULL;
235        attribute++)
236     {
237       const char *val = NULL;
238       const XML_Char **p;
239       void *parsed_value;
240       struct gdb_xml_value new_value;
241 
242       for (p = attrs; *p != NULL; p += 2)
243 	if (!strcmp (attribute->name, p[0]))
244 	  {
245 	    val = p[1];
246 	    break;
247 	  }
248 
249       if (*p != NULL && val == NULL)
250 	{
251 	  gdb_xml_debug (parser, _("Attribute \"%s\" missing a value"),
252 			 attribute->name);
253 	  continue;
254 	}
255 
256       if (*p == NULL && !(attribute->flags & GDB_XML_AF_OPTIONAL))
257 	{
258 	  gdb_xml_error (parser, _("Required attribute \"%s\" of "
259 				   "<%s> not specified"),
260 			 attribute->name, element->name);
261 	  continue;
262 	}
263 
264       if (*p == NULL)
265 	continue;
266 
267       gdb_xml_debug (parser, _("Parsing attribute %s=\"%s\""),
268 		     attribute->name, val);
269 
270       if (attribute->handler)
271 	parsed_value = attribute->handler (parser, attribute, val);
272       else
273 	parsed_value = xstrdup (val);
274 
275       new_value.name = attribute->name;
276       new_value.value = parsed_value;
277       VEC_safe_push (gdb_xml_value_s, attributes, &new_value);
278     }
279 
280   /* Check for unrecognized attributes.  */
281   if (debug_xml)
282     {
283       const XML_Char **p;
284 
285       for (p = attrs; *p != NULL; p += 2)
286 	{
287 	  for (attribute = element->attributes;
288 	       attribute != NULL && attribute->name != NULL;
289 	       attribute++)
290 	    if (strcmp (attribute->name, *p) == 0)
291 	      break;
292 
293 	  if (attribute == NULL || attribute->name == NULL)
294 	    gdb_xml_debug (parser, _("Ignoring unknown attribute %s"), *p);
295 	}
296     }
297 
298   /* Call the element handler if there is one.  */
299   if (element->start_handler)
300     element->start_handler (parser, element, parser->user_data, attributes);
301 
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;
306 
307   do_cleanups (back_to);
308 }
309 
310 /* Wrapper for gdb_xml_start_element, to prevent throwing exceptions
311    through expat.  */
312 
313 static void
314 gdb_xml_start_element_wrapper (void *data, const XML_Char *name,
315 			       const XML_Char **attrs)
316 {
317   struct gdb_xml_parser *parser = data;
318   volatile struct gdb_exception ex;
319 
320   if (parser->error.reason < 0)
321     return;
322 
323   TRY_CATCH (ex, RETURN_MASK_ALL)
324     {
325       gdb_xml_start_element (data, name, attrs);
326     }
327   if (ex.reason < 0)
328     {
329       parser->error = ex;
330 #ifdef HAVE_XML_STOPPARSER
331       XML_StopParser (parser->expat_parser, XML_FALSE);
332 #endif
333     }
334 }
335 
336 /* Handle the end of an element.  DATA is our local XML parser, and
337    NAME is the current element.  */
338 
339 static void
340 gdb_xml_end_element (void *data, const XML_Char *name)
341 {
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;
346 
347   gdb_xml_debug (parser, _("Leaving element <%s>"), name);
348 
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);
356 
357   /* Call the element processor.  */
358   if (scope->element != NULL && scope->element->end_handler)
359     {
360       char *body;
361 
362       if (scope->body == NULL)
363 	body = "";
364       else
365 	{
366 	  int length;
367 
368 	  length = obstack_object_size (scope->body);
369 	  obstack_1grow (scope->body, '\0');
370 	  body = obstack_finish (scope->body);
371 
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++;
377 	}
378 
379       scope->element->end_handler (parser, scope->element, parser->user_data,
380 				   body);
381     }
382   else if (scope->element == NULL)
383     XML_DefaultCurrent (parser->expat_parser);
384 
385   /* Pop the scope level.  */
386   if (scope->body)
387     {
388       obstack_free (scope->body, NULL);
389       xfree (scope->body);
390     }
391   VEC_pop (scope_level_s, parser->scopes);
392 }
393 
394 /* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
395    through expat.  */
396 
397 static void
398 gdb_xml_end_element_wrapper (void *data, const XML_Char *name)
399 {
400   struct gdb_xml_parser *parser = data;
401   volatile struct gdb_exception ex;
402 
403   if (parser->error.reason < 0)
404     return;
405 
406   TRY_CATCH (ex, RETURN_MASK_ALL)
407     {
408       gdb_xml_end_element (data, name);
409     }
410   if (ex.reason < 0)
411     {
412       parser->error = ex;
413 #ifdef HAVE_XML_STOPPARSER
414       XML_StopParser (parser->expat_parser, XML_FALSE);
415 #endif
416     }
417 }
418 
419 /* Free a parser and all its associated state.  */
420 
421 static void
422 gdb_xml_cleanup (void *arg)
423 {
424   struct gdb_xml_parser *parser = arg;
425   struct scope_level *scope;
426   int ix;
427 
428   XML_ParserFree (parser->expat_parser);
429 
430   /* Clean up the scopes.  */
431   for (ix = 0; VEC_iterate (scope_level_s, parser->scopes, ix, scope); ix++)
432     if (scope->body)
433       {
434 	obstack_free (scope->body, NULL);
435 	xfree (scope->body);
436       }
437   VEC_free (scope_level_s, parser->scopes);
438 
439   xfree (parser);
440 }
441 
442 /* Initialize and return a parser.  Register a cleanup to destroy the
443    parser.  */
444 
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)
449 {
450   struct gdb_xml_parser *parser;
451   struct scope_level start_scope;
452   struct cleanup *dummy;
453 
454   /* Initialize the parser.  */
455   parser = XZALLOC (struct gdb_xml_parser);
456   parser->expat_parser = XML_ParserCreateNS (NULL, '!');
457   if (parser->expat_parser == NULL)
458     {
459       xfree (parser);
460       malloc_failure (0);
461     }
462 
463   parser->name = name;
464 
465   parser->user_data = user_data;
466   XML_SetUserData (parser->expat_parser, parser);
467 
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);
472 
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);
477 
478   if (old_chain == NULL)
479     old_chain = &dummy;
480 
481   *old_chain = make_cleanup (gdb_xml_cleanup, parser);
482   return parser;
483 }
484 
485 /* Initialize and return a parser.  Register a cleanup to destroy the
486    parser.  */
487 
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)
492 {
493   struct cleanup *old_chain;
494 
495   return gdb_xml_create_parser_and_cleanup_1 (name, elements, user_data,
496 					      &old_chain);
497 }
498 
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).  */
502 
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)
509 {
510   struct gdb_xml_parser *parser = XML_GetUserData (expat_parser);
511   XML_Parser entity_parser;
512   const char *text;
513   enum XML_Status status;
514 
515   if (systemId == NULL)
516     {
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);
522     }
523   else
524     {
525       text = fetch_xml_builtin (systemId);
526       if (text == NULL)
527 	return XML_STATUS_ERROR;
528     }
529 
530   entity_parser = XML_ExternalEntityParserCreate (expat_parser, context, NULL);
531 
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);
539 
540   status = XML_Parse (entity_parser, text, strlen (text), 1);
541 
542   XML_ParserFree (entity_parser);
543   return status;
544 }
545 
546 /* Associate DTD_NAME, which must be the name of a compiled-in DTD,
547    with PARSER.  */
548 
549 void
550 gdb_xml_use_dtd (struct gdb_xml_parser *parser, const char *dtd_name)
551 {
552   enum XML_Error err;
553 
554   parser->dtd_name = dtd_name;
555 
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);
560 
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));
567 }
568 
569 /* Invoke PARSER on BUFFER.  BUFFER is the data to parse, which
570    should be NUL-terminated.
571 
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.  */
575 
576 int
577 gdb_xml_parse (struct gdb_xml_parser *parser, const char *buffer)
578 {
579   enum XML_Status status;
580   const char *error_string;
581 
582   gdb_xml_debug (parser, _("Starting:\n%s"), buffer);
583 
584   status = XML_Parse (parser->expat_parser, buffer, strlen (buffer), 1);
585 
586   if (status == XML_STATUS_OK && parser->error.reason == 0)
587     return 0;
588 
589   if (parser->error.reason == RETURN_ERROR
590       && parser->error.error == XML_PARSE_ERROR)
591     {
592       gdb_assert (parser->error.message != NULL);
593       error_string = parser->error.message;
594     }
595   else if (status == XML_STATUS_ERROR)
596     {
597       enum XML_Error err = XML_GetErrorCode (parser->expat_parser);
598 
599       error_string = XML_ErrorString (err);
600     }
601   else
602     {
603       gdb_assert (parser->error.reason < 0);
604       throw_exception (parser->error);
605     }
606 
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);
612 
613   return -1;
614 }
615 
616 int
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)
620 {
621   struct gdb_xml_parser *parser;
622   struct cleanup *back_to;
623   int result;
624 
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);
630 
631   do_cleanups (back_to);
632 
633   return result;
634 }
635 
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.
639 
640    Returns 0 for success, -1 for error.  */
641 
642 static int
643 xml_parse_unsigned_integer (const char *valstr, ULONGEST *valp)
644 {
645   const char *endptr;
646   ULONGEST result;
647 
648   if (*valstr == '\0')
649     return -1;
650 
651   result = strtoulst (valstr, &endptr, 0);
652   if (*endptr != '\0')
653     return -1;
654 
655   *valp = result;
656   return 0;
657 }
658 
659 /* Parse an integer string into a ULONGEST and return it, or call
660    gdb_xml_error if it could not be parsed.  */
661 
662 ULONGEST
663 gdb_xml_parse_ulongest (struct gdb_xml_parser *parser, const char *value)
664 {
665   ULONGEST result;
666 
667   if (xml_parse_unsigned_integer (value, &result) != 0)
668     gdb_xml_error (parser, _("Can't convert \"%s\" to an integer"), value);
669 
670   return result;
671 }
672 
673 /* Parse an integer attribute into a ULONGEST.  */
674 
675 void *
676 gdb_xml_parse_attr_ulongest (struct gdb_xml_parser *parser,
677 			     const struct gdb_xml_attribute *attribute,
678 			     const char *value)
679 {
680   ULONGEST result;
681   void *ret;
682 
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);
686 
687   ret = xmalloc (sizeof (result));
688   memcpy (ret, &result, sizeof (result));
689   return ret;
690 }
691 
692 /* A handler_data for yes/no boolean values.  */
693 
694 const struct gdb_xml_enum gdb_xml_enums_boolean[] = {
695   { "yes", 1 },
696   { "no", 0 },
697   { NULL, 0 }
698 };
699 
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.  */
704 
705 void *
706 gdb_xml_parse_attr_enum (struct gdb_xml_parser *parser,
707 			 const struct gdb_xml_attribute *attribute,
708 			 const char *value)
709 {
710   const struct gdb_xml_enum *enums = attribute->handler_data;
711   void *ret;
712 
713   for (enums = attribute->handler_data; enums->name != NULL; enums++)
714     if (strcasecmp (enums->name, value) == 0)
715       break;
716 
717   if (enums->name == NULL)
718     gdb_xml_error (parser, _("Unknown attribute value %s=\"%s\""),
719 		 attribute->name, value);
720 
721   ret = xmalloc (sizeof (enums->value));
722   memcpy (ret, &enums->value, sizeof (enums->value));
723   return ret;
724 }
725 
726 
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.
733 
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.
740 
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.
745 
746    We don't pass through any <?xml> declaration because we generate
747    UTF-8, not whatever the input encoding was.  */
748 
749 struct xinclude_parsing_data
750 {
751   /* The obstack to build the output in.  */
752   struct obstack obstack;
753 
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;
759 
760   /* The number of <xi:include> elements currently being processed,
761      to detect loops.  */
762   int include_depth;
763 
764   /* A function to call to obtain additional features, and its
765      baton.  */
766   xml_fetch_another fetcher;
767   void *fetcher_baton;
768 };
769 
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)
774 {
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;
779 
780   gdb_xml_debug (parser, _("Processing XInclude of \"%s\""), href);
781 
782   if (data->include_depth > MAX_XINCLUDE_DEPTH)
783     gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"),
784 		   MAX_XINCLUDE_DEPTH);
785 
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);
790 
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);
796 
797   obstack_grow (&data->obstack, output, strlen (output));
798   xfree (output);
799 
800   do_cleanups (back_to);
801 
802   data->skip_depth++;
803 }
804 
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)
809 {
810   struct xinclude_parsing_data *data = user_data;
811 
812   data->skip_depth--;
813 }
814 
815 static void XMLCALL
816 xml_xinclude_default (void *data_, const XML_Char *s, int len)
817 {
818   struct gdb_xml_parser *parser = data_;
819   struct xinclude_parsing_data *data = parser->user_data;
820 
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;
825 
826   /* Otherwise just add it to the end of the document we're building
827      up.  */
828   obstack_grow (&data->obstack, s, len);
829 }
830 
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)
835 {
836   struct gdb_xml_parser *parser = data_;
837   struct xinclude_parsing_data *data = parser->user_data;
838 
839   /* Don't print out the doctype, or the contents of the DTD internal
840      subset, if any.  */
841   data->skip_depth++;
842 }
843 
844 static void XMLCALL
845 xml_xinclude_end_doctype (void *data_)
846 {
847   struct gdb_xml_parser *parser = data_;
848   struct xinclude_parsing_data *data = parser->user_data;
849 
850   data->skip_depth--;
851 }
852 
853 static void XMLCALL
854 xml_xinclude_xml_decl (void *data_, const XML_Char *version,
855 		       const XML_Char *encoding, int standalone)
856 {
857   /* Do nothing - this function prevents the default handler from
858      being called, thus suppressing the XML declaration from the
859      output.  */
860 }
861 
862 static void
863 xml_xinclude_cleanup (void *data_)
864 {
865   struct xinclude_parsing_data *data = data_;
866 
867   obstack_free (&data->obstack, NULL);
868   xfree (data);
869 }
870 
871 const struct gdb_xml_attribute xinclude_attributes[] = {
872   { "href", GDB_XML_AF_NONE, NULL, NULL },
873   { NULL, GDB_XML_AF_NONE, NULL, NULL }
874 };
875 
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 }
881 };
882 
883 /* The main entry point for <xi:include> processing.  */
884 
885 char *
886 xml_process_xincludes (const char *name, const char *text,
887 		       xml_fetch_another fetcher, void *fetcher_baton,
888 		       int depth)
889 {
890   struct gdb_xml_parser *parser;
891   struct xinclude_parsing_data *data;
892   struct cleanup *back_to;
893   char *result = NULL;
894 
895   data = XZALLOC (struct xinclude_parsing_data);
896   obstack_init (&data->obstack);
897   back_to = make_cleanup (xml_xinclude_cleanup, data);
898 
899   parser = gdb_xml_create_parser_and_cleanup (name, xinclude_elements, data);
900   parser->is_xinclude = 1;
901 
902   data->include_depth = depth;
903   data->fetcher = fetcher;
904   data->fetcher_baton = fetcher_baton;
905 
906   XML_SetCharacterDataHandler (parser->expat_parser, NULL);
907   XML_SetDefaultHandler (parser->expat_parser, xml_xinclude_default);
908 
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);
913 
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);
919 
920   gdb_xml_use_dtd (parser, "xinclude.dtd");
921 
922   if (gdb_xml_parse (parser, text) == 0)
923     {
924       obstack_1grow (&data->obstack, '\0');
925       result = xstrdup (obstack_finish (&data->obstack));
926 
927       if (depth == 0)
928 	gdb_xml_debug (parser, _("XInclude processing succeeded."));
929     }
930   else
931     result = NULL;
932 
933   do_cleanups (back_to);
934   return result;
935 }
936 #endif /* HAVE_LIBEXPAT */
937 
938 
939 /* Return an XML document which was compiled into GDB, from
940    the given FILENAME, or NULL if the file was not compiled in.  */
941 
942 const char *
943 fetch_xml_builtin (const char *filename)
944 {
945   const char *(*p)[2];
946 
947   for (p = xml_builtin; (*p)[0]; p++)
948     if (strcmp ((*p)[0], filename) == 0)
949       return (*p)[1];
950 
951   return NULL;
952 }
953 
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.  */
958 
959 LONGEST
960 xml_builtin_xfer_partial (const char *filename,
961 			  gdb_byte *readbuf, const gdb_byte *writebuf,
962 			  ULONGEST offset, LONGEST len)
963 {
964   const char *buf;
965   LONGEST len_avail;
966 
967   gdb_assert (readbuf != NULL && writebuf == NULL);
968   gdb_assert (filename != NULL);
969 
970   buf = fetch_xml_builtin (filename);
971   if (buf == NULL)
972     return -1;
973 
974   len_avail = strlen (buf);
975   if (offset >= len_avail)
976     return 0;
977 
978   if (len > len_avail - offset)
979     len = len_avail - offset;
980   memcpy (readbuf, buf + offset, len);
981   return len;
982 }
983 
984 
985 static void
986 show_debug_xml (struct ui_file *file, int from_tty,
987 		struct cmd_list_element *c, const char *value)
988 {
989   fprintf_filtered (file, _("XML debugging is %s.\n"), value);
990 }
991 
992 void
993 obstack_xml_printf (struct obstack *obstack, const char *format, ...)
994 {
995   va_list ap;
996   const char *f;
997   const char *prev;
998   int percent = 0;
999 
1000   va_start (ap, format);
1001 
1002   prev = format;
1003   for (f = format; *f; f++)
1004     {
1005       if (percent)
1006        {
1007          switch (*f)
1008            {
1009            case 's':
1010              {
1011                char *p;
1012                char *a = va_arg (ap, char *);
1013 
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;
1019              }
1020              break;
1021            }
1022          percent = 0;
1023        }
1024       else if (*f == '%')
1025        percent = 1;
1026     }
1027 
1028   obstack_grow_str (obstack, prev);
1029   va_end (ap);
1030 }
1031 
1032 char *
1033 xml_fetch_content_from_file (const char *filename, void *baton)
1034 {
1035   const char *dirname = baton;
1036   FILE *file;
1037   struct cleanup *back_to;
1038   char *text;
1039   size_t len, offset;
1040 
1041   if (dirname && *dirname)
1042     {
1043       char *fullname = concat (dirname, "/", filename, (char *) NULL);
1044 
1045       if (fullname == NULL)
1046 	malloc_failure (0);
1047       file = fopen (fullname, FOPEN_RT);
1048       xfree (fullname);
1049     }
1050   else
1051     file = fopen (filename, FOPEN_RT);
1052 
1053   if (file == NULL)
1054     return NULL;
1055 
1056   back_to = make_cleanup_fclose (file);
1057 
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)
1064     {
1065       size_t bytes_read;
1066 
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))
1071 	{
1072 	  warning (_("Read error from \"%s\""), filename);
1073 	  do_cleanups (back_to);
1074 	  return NULL;
1075 	}
1076 
1077       offset += bytes_read;
1078 
1079       if (feof (file))
1080 	break;
1081 
1082       len = len * 2;
1083       text = xrealloc (text, len);
1084     }
1085 
1086   fclose (file);
1087   discard_cleanups (back_to);
1088 
1089   text[offset] = '\0';
1090   return text;
1091 }
1092 
1093 void _initialize_xml_support (void);
1094 
1095 void
1096 _initialize_xml_support (void)
1097 {
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);
1105 }
1106