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