xref: /netbsd-src/external/gpl3/gdb/dist/gdb/xml-support.c (revision 6cf6fe02a981b55727c49c3d37b0d8191a98c0ee)
1 /* Helper routines for parsing XML using Expat.
2 
3    Copyright (C) 2006-2014 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 #include "filestuff.h"
25 
26 #include <string.h>
27 #include "safe-ctype.h"
28 
29 /* Debugging flag.  */
30 static int debug_xml;
31 
32 /* The contents of this file are only useful if XML support is
33    available.  */
34 #ifdef HAVE_LIBEXPAT
35 
36 #include "gdb_expat.h"
37 
38 /* The maximum depth of <xi:include> nesting.  No need to be miserly,
39    we just want to avoid running out of stack on loops.  */
40 #define MAX_XINCLUDE_DEPTH 30
41 
42 /* Simplified XML parser infrastructure.  */
43 
44 /* A parsing level -- used to keep track of the current element
45    nesting.  */
46 struct scope_level
47 {
48   /* Elements we allow at this level.  */
49   const struct gdb_xml_element *elements;
50 
51   /* The element which we are within.  */
52   const struct gdb_xml_element *element;
53 
54   /* Mask of which elements we've seen at this level (used for
55      optional and repeatable checking).  */
56   unsigned int seen;
57 
58   /* Body text accumulation.  */
59   struct obstack *body;
60 };
61 typedef struct scope_level scope_level_s;
62 DEF_VEC_O(scope_level_s);
63 
64 /* The parser itself, and our additional state.  */
65 struct gdb_xml_parser
66 {
67   XML_Parser expat_parser;	/* The underlying expat parser.  */
68 
69   const char *name;		/* Name of this parser.  */
70   void *user_data;		/* The user's callback data, for handlers.  */
71 
72   VEC(scope_level_s) *scopes;	/* Scoping stack.  */
73 
74   struct gdb_exception error;	/* A thrown error, if any.  */
75   int last_line;		/* The line of the thrown error, or 0.  */
76 
77   const char *dtd_name;		/* The name of the expected / default DTD,
78 				   if specified.  */
79   int is_xinclude;		/* Are we the special <xi:include> parser?  */
80 };
81 
82 /* Process some body text.  We accumulate the text for later use; it's
83    wrong to do anything with it immediately, because a single block of
84    text might be broken up into multiple calls to this function.  */
85 
86 static void
87 gdb_xml_body_text (void *data, const XML_Char *text, int length)
88 {
89   struct gdb_xml_parser *parser = data;
90   struct scope_level *scope = VEC_last (scope_level_s, parser->scopes);
91 
92   if (parser->error.reason < 0)
93     return;
94 
95   if (scope->body == NULL)
96     {
97       scope->body = XZALLOC (struct obstack);
98       obstack_init (scope->body);
99     }
100 
101   obstack_grow (scope->body, text, length);
102 }
103 
104 /* Issue a debugging message from one of PARSER's handlers.  */
105 
106 void
107 gdb_xml_debug (struct gdb_xml_parser *parser, const char *format, ...)
108 {
109   int line = XML_GetCurrentLineNumber (parser->expat_parser);
110   va_list ap;
111   char *message;
112 
113   if (!debug_xml)
114     return;
115 
116   va_start (ap, format);
117   message = xstrvprintf (format, ap);
118   if (line)
119     fprintf_unfiltered (gdb_stderr, "%s (line %d): %s\n",
120 			parser->name, line, message);
121   else
122     fprintf_unfiltered (gdb_stderr, "%s: %s\n",
123 			parser->name, message);
124   xfree (message);
125 }
126 
127 /* Issue an error message from one of PARSER's handlers, and stop
128    parsing.  */
129 
130 void
131 gdb_xml_error (struct gdb_xml_parser *parser, const char *format, ...)
132 {
133   int line = XML_GetCurrentLineNumber (parser->expat_parser);
134   va_list ap;
135 
136   parser->last_line = line;
137   va_start (ap, format);
138   throw_verror (XML_PARSE_ERROR, format, ap);
139 }
140 
141 /* Find the attribute named NAME in the set of parsed attributes
142    ATTRIBUTES.  Returns NULL if not found.  */
143 
144 struct gdb_xml_value *
145 xml_find_attribute (VEC(gdb_xml_value_s) *attributes, const char *name)
146 {
147   struct gdb_xml_value *value;
148   int ix;
149 
150   for (ix = 0; VEC_iterate (gdb_xml_value_s, attributes, ix, value); ix++)
151     if (strcmp (value->name, name) == 0)
152       return value;
153 
154   return NULL;
155 }
156 
157 /* Clean up a vector of parsed attribute values.  */
158 
159 static void
160 gdb_xml_values_cleanup (void *data)
161 {
162   VEC(gdb_xml_value_s) **values = data;
163   struct gdb_xml_value *value;
164   int ix;
165 
166   for (ix = 0; VEC_iterate (gdb_xml_value_s, *values, ix, value); ix++)
167     xfree (value->value);
168   VEC_free (gdb_xml_value_s, *values);
169 }
170 
171 /* Handle the start of an element.  DATA is our local XML parser, NAME
172    is the element, and ATTRS are the names and values of this
173    element's attributes.  */
174 
175 static void
176 gdb_xml_start_element (void *data, const XML_Char *name,
177 		       const XML_Char **attrs)
178 {
179   struct gdb_xml_parser *parser = data;
180   struct scope_level *scope;
181   struct scope_level new_scope;
182   const struct gdb_xml_element *element;
183   const struct gdb_xml_attribute *attribute;
184   VEC(gdb_xml_value_s) *attributes = NULL;
185   unsigned int seen;
186   struct cleanup *back_to;
187 
188   /* Push an error scope.  If we return or throw an exception before
189      filling this in, it will tell us to ignore children of this
190      element.  */
191   VEC_reserve (scope_level_s, parser->scopes, 1);
192   scope = VEC_last (scope_level_s, parser->scopes);
193   memset (&new_scope, 0, sizeof (new_scope));
194   VEC_quick_push (scope_level_s, parser->scopes, &new_scope);
195 
196   gdb_xml_debug (parser, _("Entering element <%s>"), name);
197 
198   /* Find this element in the list of the current scope's allowed
199      children.  Record that we've seen it.  */
200 
201   seen = 1;
202   for (element = scope->elements; element && element->name;
203        element++, seen <<= 1)
204     if (strcmp (element->name, name) == 0)
205       break;
206 
207   if (element == NULL || element->name == NULL)
208     {
209       /* If we're working on XInclude, <xi:include> can be the child
210 	 of absolutely anything.  Copy the previous scope's element
211 	 list into the new scope even if there was no match.  */
212       if (parser->is_xinclude)
213 	{
214 	  struct scope_level *unknown_scope;
215 
216 	  XML_DefaultCurrent (parser->expat_parser);
217 
218 	  unknown_scope = VEC_last (scope_level_s, parser->scopes);
219 	  unknown_scope->elements = scope->elements;
220 	  return;
221 	}
222 
223       gdb_xml_debug (parser, _("Element <%s> unknown"), name);
224       return;
225     }
226 
227   if (!(element->flags & GDB_XML_EF_REPEATABLE) && (seen & scope->seen))
228     gdb_xml_error (parser, _("Element <%s> only expected once"), name);
229 
230   scope->seen |= seen;
231 
232   back_to = make_cleanup (gdb_xml_values_cleanup, &attributes);
233 
234   for (attribute = element->attributes;
235        attribute != NULL && attribute->name != NULL;
236        attribute++)
237     {
238       const char *val = NULL;
239       const XML_Char **p;
240       void *parsed_value;
241       struct gdb_xml_value new_value;
242 
243       for (p = attrs; *p != NULL; p += 2)
244 	if (!strcmp (attribute->name, p[0]))
245 	  {
246 	    val = p[1];
247 	    break;
248 	  }
249 
250       if (*p != NULL && val == NULL)
251 	{
252 	  gdb_xml_debug (parser, _("Attribute \"%s\" missing a value"),
253 			 attribute->name);
254 	  continue;
255 	}
256 
257       if (*p == NULL && !(attribute->flags & GDB_XML_AF_OPTIONAL))
258 	{
259 	  gdb_xml_error (parser, _("Required attribute \"%s\" of "
260 				   "<%s> not specified"),
261 			 attribute->name, element->name);
262 	  continue;
263 	}
264 
265       if (*p == NULL)
266 	continue;
267 
268       gdb_xml_debug (parser, _("Parsing attribute %s=\"%s\""),
269 		     attribute->name, val);
270 
271       if (attribute->handler)
272 	parsed_value = attribute->handler (parser, attribute, val);
273       else
274 	parsed_value = xstrdup (val);
275 
276       new_value.name = attribute->name;
277       new_value.value = parsed_value;
278       VEC_safe_push (gdb_xml_value_s, attributes, &new_value);
279     }
280 
281   /* Check for unrecognized attributes.  */
282   if (debug_xml)
283     {
284       const XML_Char **p;
285 
286       for (p = attrs; *p != NULL; p += 2)
287 	{
288 	  for (attribute = element->attributes;
289 	       attribute != NULL && attribute->name != NULL;
290 	       attribute++)
291 	    if (strcmp (attribute->name, *p) == 0)
292 	      break;
293 
294 	  if (attribute == NULL || attribute->name == NULL)
295 	    gdb_xml_debug (parser, _("Ignoring unknown attribute %s"), *p);
296 	}
297     }
298 
299   /* Call the element handler if there is one.  */
300   if (element->start_handler)
301     element->start_handler (parser, element, parser->user_data, attributes);
302 
303   /* Fill in a new scope level.  */
304   scope = VEC_last (scope_level_s, parser->scopes);
305   scope->element = element;
306   scope->elements = element->children;
307 
308   do_cleanups (back_to);
309 }
310 
311 /* Wrapper for gdb_xml_start_element, to prevent throwing exceptions
312    through expat.  */
313 
314 static void
315 gdb_xml_start_element_wrapper (void *data, const XML_Char *name,
316 			       const XML_Char **attrs)
317 {
318   struct gdb_xml_parser *parser = data;
319   volatile struct gdb_exception ex;
320 
321   if (parser->error.reason < 0)
322     return;
323 
324   TRY_CATCH (ex, RETURN_MASK_ALL)
325     {
326       gdb_xml_start_element (data, name, attrs);
327     }
328   if (ex.reason < 0)
329     {
330       parser->error = ex;
331 #ifdef HAVE_XML_STOPPARSER
332       XML_StopParser (parser->expat_parser, XML_FALSE);
333 #endif
334     }
335 }
336 
337 /* Handle the end of an element.  DATA is our local XML parser, and
338    NAME is the current element.  */
339 
340 static void
341 gdb_xml_end_element (void *data, const XML_Char *name)
342 {
343   struct gdb_xml_parser *parser = data;
344   struct scope_level *scope = VEC_last (scope_level_s, parser->scopes);
345   const struct gdb_xml_element *element;
346   unsigned int seen;
347 
348   gdb_xml_debug (parser, _("Leaving element <%s>"), name);
349 
350   for (element = scope->elements, seen = 1;
351        element != NULL && element->name != NULL;
352        element++, seen <<= 1)
353     if ((scope->seen & seen) == 0
354 	&& (element->flags & GDB_XML_EF_OPTIONAL) == 0)
355       gdb_xml_error (parser, _("Required element <%s> is missing"),
356 		     element->name);
357 
358   /* Call the element processor.  */
359   if (scope->element != NULL && scope->element->end_handler)
360     {
361       char *body;
362 
363       if (scope->body == NULL)
364 	body = "";
365       else
366 	{
367 	  int length;
368 
369 	  length = obstack_object_size (scope->body);
370 	  obstack_1grow (scope->body, '\0');
371 	  body = obstack_finish (scope->body);
372 
373 	  /* Strip leading and trailing whitespace.  */
374 	  while (length > 0 && ISSPACE (body[length-1]))
375 	    body[--length] = '\0';
376 	  while (*body && ISSPACE (*body))
377 	    body++;
378 	}
379 
380       scope->element->end_handler (parser, scope->element, parser->user_data,
381 				   body);
382     }
383   else if (scope->element == NULL)
384     XML_DefaultCurrent (parser->expat_parser);
385 
386   /* Pop the scope level.  */
387   if (scope->body)
388     {
389       obstack_free (scope->body, NULL);
390       xfree (scope->body);
391     }
392   VEC_pop (scope_level_s, parser->scopes);
393 }
394 
395 /* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
396    through expat.  */
397 
398 static void
399 gdb_xml_end_element_wrapper (void *data, const XML_Char *name)
400 {
401   struct gdb_xml_parser *parser = data;
402   volatile struct gdb_exception ex;
403 
404   if (parser->error.reason < 0)
405     return;
406 
407   TRY_CATCH (ex, RETURN_MASK_ALL)
408     {
409       gdb_xml_end_element (data, name);
410     }
411   if (ex.reason < 0)
412     {
413       parser->error = ex;
414 #ifdef HAVE_XML_STOPPARSER
415       XML_StopParser (parser->expat_parser, XML_FALSE);
416 #endif
417     }
418 }
419 
420 /* Free a parser and all its associated state.  */
421 
422 static void
423 gdb_xml_cleanup (void *arg)
424 {
425   struct gdb_xml_parser *parser = arg;
426   struct scope_level *scope;
427   int ix;
428 
429   XML_ParserFree (parser->expat_parser);
430 
431   /* Clean up the scopes.  */
432   for (ix = 0; VEC_iterate (scope_level_s, parser->scopes, ix, scope); ix++)
433     if (scope->body)
434       {
435 	obstack_free (scope->body, NULL);
436 	xfree (scope->body);
437       }
438   VEC_free (scope_level_s, parser->scopes);
439 
440   xfree (parser);
441 }
442 
443 /* Initialize a parser and store it to *PARSER_RESULT.  Register a
444    cleanup to destroy the parser.  */
445 
446 static struct cleanup *
447 gdb_xml_create_parser_and_cleanup (const char *name,
448 				   const struct gdb_xml_element *elements,
449 				   void *user_data,
450 				   struct gdb_xml_parser **parser_result)
451 {
452   struct gdb_xml_parser *parser;
453   struct scope_level start_scope;
454   struct cleanup *result;
455 
456   /* Initialize the parser.  */
457   parser = XZALLOC (struct gdb_xml_parser);
458   parser->expat_parser = XML_ParserCreateNS (NULL, '!');
459   if (parser->expat_parser == NULL)
460     {
461       xfree (parser);
462       malloc_failure (0);
463     }
464 
465   parser->name = name;
466 
467   parser->user_data = user_data;
468   XML_SetUserData (parser->expat_parser, parser);
469 
470   /* Set the callbacks.  */
471   XML_SetElementHandler (parser->expat_parser, gdb_xml_start_element_wrapper,
472 			 gdb_xml_end_element_wrapper);
473   XML_SetCharacterDataHandler (parser->expat_parser, gdb_xml_body_text);
474 
475   /* Initialize the outer scope.  */
476   memset (&start_scope, 0, sizeof (start_scope));
477   start_scope.elements = elements;
478   VEC_safe_push (scope_level_s, parser->scopes, &start_scope);
479 
480   *parser_result = parser;
481   return make_cleanup (gdb_xml_cleanup, parser);
482 }
483 
484 /* External entity handler.  The only external entities we support
485    are those compiled into GDB (we do not fetch entities from the
486    target).  */
487 
488 static int XMLCALL
489 gdb_xml_fetch_external_entity (XML_Parser expat_parser,
490 			       const XML_Char *context,
491 			       const XML_Char *base,
492 			       const XML_Char *systemId,
493 			       const XML_Char *publicId)
494 {
495   struct gdb_xml_parser *parser = XML_GetUserData (expat_parser);
496   XML_Parser entity_parser;
497   const char *text;
498   enum XML_Status status;
499 
500   if (systemId == NULL)
501     {
502       text = fetch_xml_builtin (parser->dtd_name);
503       if (text == NULL)
504 	internal_error (__FILE__, __LINE__,
505 			_("could not locate built-in DTD %s"),
506 			parser->dtd_name);
507     }
508   else
509     {
510       text = fetch_xml_builtin (systemId);
511       if (text == NULL)
512 	return XML_STATUS_ERROR;
513     }
514 
515   entity_parser = XML_ExternalEntityParserCreate (expat_parser, context, NULL);
516 
517   /* Don't use our handlers for the contents of the DTD.  Just let expat
518      process it.  */
519   XML_SetElementHandler (entity_parser, NULL, NULL);
520   XML_SetDoctypeDeclHandler (entity_parser, NULL, NULL);
521   XML_SetXmlDeclHandler (entity_parser, NULL);
522   XML_SetDefaultHandler (entity_parser, NULL);
523   XML_SetUserData (entity_parser, NULL);
524 
525   status = XML_Parse (entity_parser, text, strlen (text), 1);
526 
527   XML_ParserFree (entity_parser);
528   return status;
529 }
530 
531 /* Associate DTD_NAME, which must be the name of a compiled-in DTD,
532    with PARSER.  */
533 
534 void
535 gdb_xml_use_dtd (struct gdb_xml_parser *parser, const char *dtd_name)
536 {
537   enum XML_Error err;
538 
539   parser->dtd_name = dtd_name;
540 
541   XML_SetParamEntityParsing (parser->expat_parser,
542 			     XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
543   XML_SetExternalEntityRefHandler (parser->expat_parser,
544 				   gdb_xml_fetch_external_entity);
545 
546   /* Even if no DTD is provided, use the built-in DTD anyway.  */
547   err = XML_UseForeignDTD (parser->expat_parser, XML_TRUE);
548   if (err != XML_ERROR_NONE)
549     internal_error (__FILE__, __LINE__,
550 		    _("XML_UseForeignDTD failed: %s"),
551 		    XML_ErrorString (err));
552 }
553 
554 /* Invoke PARSER on BUFFER.  BUFFER is the data to parse, which
555    should be NUL-terminated.
556 
557    The return value is 0 for success or -1 for error.  It may throw,
558    but only if something unexpected goes wrong during parsing; parse
559    errors will be caught, warned about, and reported as failure.  */
560 
561 int
562 gdb_xml_parse (struct gdb_xml_parser *parser, const char *buffer)
563 {
564   enum XML_Status status;
565   const char *error_string;
566 
567   gdb_xml_debug (parser, _("Starting:\n%s"), buffer);
568 
569   status = XML_Parse (parser->expat_parser, buffer, strlen (buffer), 1);
570 
571   if (status == XML_STATUS_OK && parser->error.reason == 0)
572     return 0;
573 
574   if (parser->error.reason == RETURN_ERROR
575       && parser->error.error == XML_PARSE_ERROR)
576     {
577       gdb_assert (parser->error.message != NULL);
578       error_string = parser->error.message;
579     }
580   else if (status == XML_STATUS_ERROR)
581     {
582       enum XML_Error err = XML_GetErrorCode (parser->expat_parser);
583 
584       error_string = XML_ErrorString (err);
585     }
586   else
587     {
588       gdb_assert (parser->error.reason < 0);
589       throw_exception (parser->error);
590     }
591 
592   if (parser->last_line != 0)
593     warning (_("while parsing %s (at line %d): %s"), parser->name,
594 	     parser->last_line, error_string);
595   else
596     warning (_("while parsing %s: %s"), parser->name, error_string);
597 
598   return -1;
599 }
600 
601 int
602 gdb_xml_parse_quick (const char *name, const char *dtd_name,
603 		     const struct gdb_xml_element *elements,
604 		     const char *document, void *user_data)
605 {
606   struct gdb_xml_parser *parser;
607   struct cleanup *back_to;
608   int result;
609 
610   back_to = gdb_xml_create_parser_and_cleanup (name, elements,
611 					       user_data, &parser);
612   if (dtd_name != NULL)
613     gdb_xml_use_dtd (parser, dtd_name);
614   result = gdb_xml_parse (parser, document);
615 
616   do_cleanups (back_to);
617 
618   return result;
619 }
620 
621 /* Parse a field VALSTR that we expect to contain an integer value.
622    The integer is returned in *VALP.  The string is parsed with an
623    equivalent to strtoul.
624 
625    Returns 0 for success, -1 for error.  */
626 
627 static int
628 xml_parse_unsigned_integer (const char *valstr, ULONGEST *valp)
629 {
630   const char *endptr;
631   ULONGEST result;
632 
633   if (*valstr == '\0')
634     return -1;
635 
636   result = strtoulst (valstr, &endptr, 0);
637   if (*endptr != '\0')
638     return -1;
639 
640   *valp = result;
641   return 0;
642 }
643 
644 /* Parse an integer string into a ULONGEST and return it, or call
645    gdb_xml_error if it could not be parsed.  */
646 
647 ULONGEST
648 gdb_xml_parse_ulongest (struct gdb_xml_parser *parser, const char *value)
649 {
650   ULONGEST result;
651 
652   if (xml_parse_unsigned_integer (value, &result) != 0)
653     gdb_xml_error (parser, _("Can't convert \"%s\" to an integer"), value);
654 
655   return result;
656 }
657 
658 /* Parse an integer attribute into a ULONGEST.  */
659 
660 void *
661 gdb_xml_parse_attr_ulongest (struct gdb_xml_parser *parser,
662 			     const struct gdb_xml_attribute *attribute,
663 			     const char *value)
664 {
665   ULONGEST result;
666   void *ret;
667 
668   if (xml_parse_unsigned_integer (value, &result) != 0)
669     gdb_xml_error (parser, _("Can't convert %s=\"%s\" to an integer"),
670 		   attribute->name, value);
671 
672   ret = xmalloc (sizeof (result));
673   memcpy (ret, &result, sizeof (result));
674   return ret;
675 }
676 
677 /* A handler_data for yes/no boolean values.  */
678 
679 const struct gdb_xml_enum gdb_xml_enums_boolean[] = {
680   { "yes", 1 },
681   { "no", 0 },
682   { NULL, 0 }
683 };
684 
685 /* Map NAME to VALUE.  A struct gdb_xml_enum * should be saved as the
686    value of handler_data when using gdb_xml_parse_attr_enum to parse a
687    fixed list of possible strings.  The list is terminated by an entry
688    with NAME == NULL.  */
689 
690 void *
691 gdb_xml_parse_attr_enum (struct gdb_xml_parser *parser,
692 			 const struct gdb_xml_attribute *attribute,
693 			 const char *value)
694 {
695   const struct gdb_xml_enum *enums = attribute->handler_data;
696   void *ret;
697 
698   for (enums = attribute->handler_data; enums->name != NULL; enums++)
699     if (strcasecmp (enums->name, value) == 0)
700       break;
701 
702   if (enums->name == NULL)
703     gdb_xml_error (parser, _("Unknown attribute value %s=\"%s\""),
704 		 attribute->name, value);
705 
706   ret = xmalloc (sizeof (enums->value));
707   memcpy (ret, &enums->value, sizeof (enums->value));
708   return ret;
709 }
710 
711 
712 /* XInclude processing.  This is done as a separate step from actually
713    parsing the document, so that we can produce a single combined XML
714    document - e.g. to hand to a front end or to simplify comparing two
715    documents.  We make extensive use of XML_DefaultCurrent, to pass
716    input text directly into the output without reformatting or
717    requoting it.
718 
719    We output the DOCTYPE declaration for the first document unchanged,
720    if present, and discard DOCTYPEs from included documents.  Only the
721    one we pass through here is used when we feed the result back to
722    expat.  The XInclude standard explicitly does not discuss
723    validation of the result; we choose to apply the same DTD applied
724    to the outermost document.
725 
726    We can not simply include the external DTD subset in the document
727    as an internal subset, because <!IGNORE> and <!INCLUDE> are valid
728    only in external subsets.  But if we do not pass the DTD into the
729    output at all, default values will not be filled in.
730 
731    We don't pass through any <?xml> declaration because we generate
732    UTF-8, not whatever the input encoding was.  */
733 
734 struct xinclude_parsing_data
735 {
736   /* The obstack to build the output in.  */
737   struct obstack obstack;
738 
739   /* A count indicating whether we are in an element whose
740      children should not be copied to the output, and if so,
741      how deep we are nested.  This is used for anything inside
742      an xi:include, and for the DTD.  */
743   int skip_depth;
744 
745   /* The number of <xi:include> elements currently being processed,
746      to detect loops.  */
747   int include_depth;
748 
749   /* A function to call to obtain additional features, and its
750      baton.  */
751   xml_fetch_another fetcher;
752   void *fetcher_baton;
753 };
754 
755 static void
756 xinclude_start_include (struct gdb_xml_parser *parser,
757 			const struct gdb_xml_element *element,
758 			void *user_data, VEC(gdb_xml_value_s) *attributes)
759 {
760   struct xinclude_parsing_data *data = user_data;
761   char *href = xml_find_attribute (attributes, "href")->value;
762   struct cleanup *back_to;
763   char *text, *output;
764 
765   gdb_xml_debug (parser, _("Processing XInclude of \"%s\""), href);
766 
767   if (data->include_depth > MAX_XINCLUDE_DEPTH)
768     gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"),
769 		   MAX_XINCLUDE_DEPTH);
770 
771   text = data->fetcher (href, data->fetcher_baton);
772   if (text == NULL)
773     gdb_xml_error (parser, _("Could not load XML document \"%s\""), href);
774   back_to = make_cleanup (xfree, text);
775 
776   output = xml_process_xincludes (parser->name, text, data->fetcher,
777 				  data->fetcher_baton,
778 				  data->include_depth + 1);
779   if (output == NULL)
780     gdb_xml_error (parser, _("Parsing \"%s\" failed"), href);
781 
782   obstack_grow (&data->obstack, output, strlen (output));
783   xfree (output);
784 
785   do_cleanups (back_to);
786 
787   data->skip_depth++;
788 }
789 
790 static void
791 xinclude_end_include (struct gdb_xml_parser *parser,
792 		      const struct gdb_xml_element *element,
793 		      void *user_data, const char *body_text)
794 {
795   struct xinclude_parsing_data *data = user_data;
796 
797   data->skip_depth--;
798 }
799 
800 static void XMLCALL
801 xml_xinclude_default (void *data_, const XML_Char *s, int len)
802 {
803   struct gdb_xml_parser *parser = data_;
804   struct xinclude_parsing_data *data = parser->user_data;
805 
806   /* If we are inside of e.g. xi:include or the DTD, don't save this
807      string.  */
808   if (data->skip_depth)
809     return;
810 
811   /* Otherwise just add it to the end of the document we're building
812      up.  */
813   obstack_grow (&data->obstack, s, len);
814 }
815 
816 static void XMLCALL
817 xml_xinclude_start_doctype (void *data_, const XML_Char *doctypeName,
818 			    const XML_Char *sysid, const XML_Char *pubid,
819 			    int has_internal_subset)
820 {
821   struct gdb_xml_parser *parser = data_;
822   struct xinclude_parsing_data *data = parser->user_data;
823 
824   /* Don't print out the doctype, or the contents of the DTD internal
825      subset, if any.  */
826   data->skip_depth++;
827 }
828 
829 static void XMLCALL
830 xml_xinclude_end_doctype (void *data_)
831 {
832   struct gdb_xml_parser *parser = data_;
833   struct xinclude_parsing_data *data = parser->user_data;
834 
835   data->skip_depth--;
836 }
837 
838 static void XMLCALL
839 xml_xinclude_xml_decl (void *data_, const XML_Char *version,
840 		       const XML_Char *encoding, int standalone)
841 {
842   /* Do nothing - this function prevents the default handler from
843      being called, thus suppressing the XML declaration from the
844      output.  */
845 }
846 
847 static void
848 xml_xinclude_cleanup (void *data_)
849 {
850   struct xinclude_parsing_data *data = data_;
851 
852   obstack_free (&data->obstack, NULL);
853   xfree (data);
854 }
855 
856 const struct gdb_xml_attribute xinclude_attributes[] = {
857   { "href", GDB_XML_AF_NONE, NULL, NULL },
858   { NULL, GDB_XML_AF_NONE, NULL, NULL }
859 };
860 
861 const struct gdb_xml_element xinclude_elements[] = {
862   { "http://www.w3.org/2001/XInclude!include", xinclude_attributes, NULL,
863     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
864     xinclude_start_include, xinclude_end_include },
865   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
866 };
867 
868 /* The main entry point for <xi:include> processing.  */
869 
870 char *
871 xml_process_xincludes (const char *name, const char *text,
872 		       xml_fetch_another fetcher, void *fetcher_baton,
873 		       int depth)
874 {
875   struct gdb_xml_parser *parser;
876   struct xinclude_parsing_data *data;
877   struct cleanup *back_to;
878   char *result = NULL;
879 
880   data = XZALLOC (struct xinclude_parsing_data);
881   obstack_init (&data->obstack);
882   back_to = make_cleanup (xml_xinclude_cleanup, data);
883 
884   gdb_xml_create_parser_and_cleanup (name, xinclude_elements,
885 				     data, &parser);
886   parser->is_xinclude = 1;
887 
888   data->include_depth = depth;
889   data->fetcher = fetcher;
890   data->fetcher_baton = fetcher_baton;
891 
892   XML_SetCharacterDataHandler (parser->expat_parser, NULL);
893   XML_SetDefaultHandler (parser->expat_parser, xml_xinclude_default);
894 
895   /* Always discard the XML version declarations; the only important
896      thing this provides is encoding, and our result will have been
897      converted to UTF-8.  */
898   XML_SetXmlDeclHandler (parser->expat_parser, xml_xinclude_xml_decl);
899 
900   if (depth > 0)
901     /* Discard the doctype for included documents.  */
902     XML_SetDoctypeDeclHandler (parser->expat_parser,
903 			       xml_xinclude_start_doctype,
904 			       xml_xinclude_end_doctype);
905 
906   gdb_xml_use_dtd (parser, "xinclude.dtd");
907 
908   if (gdb_xml_parse (parser, text) == 0)
909     {
910       obstack_1grow (&data->obstack, '\0');
911       result = xstrdup (obstack_finish (&data->obstack));
912 
913       if (depth == 0)
914 	gdb_xml_debug (parser, _("XInclude processing succeeded."));
915     }
916   else
917     result = NULL;
918 
919   do_cleanups (back_to);
920   return result;
921 }
922 #endif /* HAVE_LIBEXPAT */
923 
924 
925 /* Return an XML document which was compiled into GDB, from
926    the given FILENAME, or NULL if the file was not compiled in.  */
927 
928 const char *
929 fetch_xml_builtin (const char *filename)
930 {
931   const char *(*p)[2];
932 
933   for (p = xml_builtin; (*p)[0]; p++)
934     if (strcmp ((*p)[0], filename) == 0)
935       return (*p)[1];
936 
937   return NULL;
938 }
939 
940 /* A to_xfer_partial helper function which reads XML files which were
941    compiled into GDB.  The target may call this function from its own
942    to_xfer_partial handler, after converting object and annex to the
943    appropriate filename.  */
944 
945 LONGEST
946 xml_builtin_xfer_partial (const char *filename,
947 			  gdb_byte *readbuf, const gdb_byte *writebuf,
948 			  ULONGEST offset, LONGEST len)
949 {
950   const char *buf;
951   LONGEST len_avail;
952 
953   gdb_assert (readbuf != NULL && writebuf == NULL);
954   gdb_assert (filename != NULL);
955 
956   buf = fetch_xml_builtin (filename);
957   if (buf == NULL)
958     return -1;
959 
960   len_avail = strlen (buf);
961   if (offset >= len_avail)
962     return 0;
963 
964   if (len > len_avail - offset)
965     len = len_avail - offset;
966   memcpy (readbuf, buf + offset, len);
967   return len;
968 }
969 
970 
971 static void
972 show_debug_xml (struct ui_file *file, int from_tty,
973 		struct cmd_list_element *c, const char *value)
974 {
975   fprintf_filtered (file, _("XML debugging is %s.\n"), value);
976 }
977 
978 void
979 obstack_xml_printf (struct obstack *obstack, const char *format, ...)
980 {
981   va_list ap;
982   const char *f;
983   const char *prev;
984   int percent = 0;
985 
986   va_start (ap, format);
987 
988   prev = format;
989   for (f = format; *f; f++)
990     {
991       if (percent)
992        {
993          switch (*f)
994            {
995            case 's':
996              {
997                char *p;
998                char *a = va_arg (ap, char *);
999 
1000                obstack_grow (obstack, prev, f - prev - 1);
1001                p = xml_escape_text (a);
1002                obstack_grow_str (obstack, p);
1003                xfree (p);
1004                prev = f + 1;
1005              }
1006              break;
1007            }
1008          percent = 0;
1009        }
1010       else if (*f == '%')
1011        percent = 1;
1012     }
1013 
1014   obstack_grow_str (obstack, prev);
1015   va_end (ap);
1016 }
1017 
1018 char *
1019 xml_fetch_content_from_file (const char *filename, void *baton)
1020 {
1021   const char *dirname = baton;
1022   FILE *file;
1023   struct cleanup *back_to;
1024   char *text;
1025   size_t len, offset;
1026 
1027   if (dirname && *dirname)
1028     {
1029       char *fullname = concat (dirname, "/", filename, (char *) NULL);
1030 
1031       if (fullname == NULL)
1032 	malloc_failure (0);
1033       file = gdb_fopen_cloexec (fullname, FOPEN_RT);
1034       xfree (fullname);
1035     }
1036   else
1037     file = gdb_fopen_cloexec (filename, FOPEN_RT);
1038 
1039   if (file == NULL)
1040     return NULL;
1041 
1042   back_to = make_cleanup_fclose (file);
1043 
1044   /* Read in the whole file, one chunk at a time.  */
1045   len = 4096;
1046   offset = 0;
1047   text = xmalloc (len);
1048   make_cleanup (free_current_contents, &text);
1049   while (1)
1050     {
1051       size_t bytes_read;
1052 
1053       /* Continue reading where the last read left off.  Leave at least
1054 	 one byte so that we can NUL-terminate the result.  */
1055       bytes_read = fread (text + offset, 1, len - offset - 1, file);
1056       if (ferror (file))
1057 	{
1058 	  warning (_("Read error from \"%s\""), filename);
1059 	  do_cleanups (back_to);
1060 	  return NULL;
1061 	}
1062 
1063       offset += bytes_read;
1064 
1065       if (feof (file))
1066 	break;
1067 
1068       len = len * 2;
1069       text = xrealloc (text, len);
1070     }
1071 
1072   fclose (file);
1073   discard_cleanups (back_to);
1074 
1075   text[offset] = '\0';
1076   return text;
1077 }
1078 
1079 void _initialize_xml_support (void);
1080 
1081 void
1082 _initialize_xml_support (void)
1083 {
1084   add_setshow_boolean_cmd ("xml", class_maintenance, &debug_xml,
1085 			   _("Set XML parser debugging."),
1086 			   _("Show XML parser debugging."),
1087 			   _("When set, debugging messages for XML parsers "
1088 			     "are displayed."),
1089 			   NULL, show_debug_xml,
1090 			   &setdebuglist, &showdebuglist);
1091 }
1092