xml-support.c revision 1.1
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.  */
30static 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.  */
46struct 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};
61typedef struct scope_level scope_level_s;
62DEF_VEC_O(scope_level_s);
63
64/* The parser itself, and our additional state.  */
65struct 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
86static void
87gdb_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
106void
107gdb_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
130void
131gdb_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
144struct gdb_xml_value *
145xml_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
159static void
160gdb_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
175static void
176gdb_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
314static void
315gdb_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
340static void
341gdb_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
398static void
399gdb_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
422static void
423gdb_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
446static struct cleanup *
447gdb_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
488static int XMLCALL
489gdb_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
534void
535gdb_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
561int
562gdb_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
601int
602gdb_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
627static int
628xml_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
647ULONGEST
648gdb_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
660void *
661gdb_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
679const 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
690void *
691gdb_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
734struct 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
755static void
756xinclude_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
790static void
791xinclude_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
800static void XMLCALL
801xml_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
816static void XMLCALL
817xml_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
829static void XMLCALL
830xml_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
838static void XMLCALL
839xml_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
847static void
848xml_xinclude_cleanup (void *data_)
849{
850  struct xinclude_parsing_data *data = data_;
851
852  obstack_free (&data->obstack, NULL);
853  xfree (data);
854}
855
856const struct gdb_xml_attribute xinclude_attributes[] = {
857  { "href", GDB_XML_AF_NONE, NULL, NULL },
858  { NULL, GDB_XML_AF_NONE, NULL, NULL }
859};
860
861const 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
870char *
871xml_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
928const char *
929fetch_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
945LONGEST
946xml_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
971static void
972show_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
978void
979obstack_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
1018char *
1019xml_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
1079void _initialize_xml_support (void);
1080
1081void
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