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