/* Helper routines for parsing XML using Expat.

   Copyright (C) 2006-2018 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "gdbcmd.h"
#include "xml-support.h"
#include "filestuff.h"
#include "safe-ctype.h"
#include <vector>
#include <string>

/* Debugging flag.  */
static int debug_xml;

/* The contents of this file are only useful if XML support is
   available.  */
#ifdef HAVE_LIBEXPAT

#include "gdb_expat.h"

/* The maximum depth of <xi:include> nesting.  No need to be miserly,
   we just want to avoid running out of stack on loops.  */
#define MAX_XINCLUDE_DEPTH 30

/* Simplified XML parser infrastructure.  */

/* A parsing level -- used to keep track of the current element
   nesting.  */
struct scope_level
{
  explicit scope_level (const gdb_xml_element *elements_ = NULL)
    : elements (elements_),
      element (NULL),
      seen (0)
  {}

  /* Elements we allow at this level.  */
  const struct gdb_xml_element *elements;

  /* The element which we are within.  */
  const struct gdb_xml_element *element;

  /* Mask of which elements we've seen at this level (used for
     optional and repeatable checking).  */
  unsigned int seen;

  /* Body text accumulation.  */
  std::string body;
};

/* The parser itself, and our additional state.  */
struct gdb_xml_parser
{
  gdb_xml_parser (const char *name,
		  const gdb_xml_element *elements,
		  void *user_data);
  ~gdb_xml_parser();

  /* Associate DTD_NAME, which must be the name of a compiled-in DTD,
     with the parser.  */
  void use_dtd (const char *dtd_name);

  /* Return the name of the expected / default DTD, if specified.  */
  const char *dtd_name ()
  { return m_dtd_name; }

  /* Invoke the parser on BUFFER.  BUFFER is the data to parse, which
     should be NUL-terminated.

     The return value is 0 for success or -1 for error.  It may throw,
     but only if something unexpected goes wrong during parsing; parse
     errors will be caught, warned about, and reported as failure.  */
  int parse (const char *buffer);

  /* Issue a debugging message.  */
  void vdebug (const char *format, va_list ap)
    ATTRIBUTE_PRINTF (2, 0);

  /* Issue an error message, and stop parsing.  */
  void verror (const char *format, va_list ap)
    ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0);

  void body_text (const XML_Char *text, int length);
  void start_element (const XML_Char *name, const XML_Char **attrs);
  void end_element (const XML_Char *name);

  /* Return the name of this parser.  */
  const char *name ()
  { return m_name; }

  /* Return the user's callback data, for handlers.  */
  void *user_data ()
  { return m_user_data; };

  /* Are we the special <xi:include> parser?  */
  void set_is_xinclude (bool is_xinclude)
  { m_is_xinclude = is_xinclude; }

  /* A thrown error, if any.  */
  void set_error (gdb_exception error)
  {
    m_error = error;
#ifdef HAVE_XML_STOPPARSER
    XML_StopParser (m_expat_parser, XML_FALSE);
#endif
  }

  /* Return the underlying expat parser.  */
  XML_Parser expat_parser ()
  { return m_expat_parser; }

private:
  /* The underlying expat parser.  */
  XML_Parser m_expat_parser;

  /* Name of this parser.  */
  const char *m_name;

  /* The user's callback data, for handlers.  */
  void *m_user_data;

  /* Scoping stack.  */
  std::vector<scope_level> m_scopes;

/* A thrown error, if any.  */
  struct gdb_exception m_error;

  /* The line of the thrown error, or 0.  */
  int m_last_line;

  /* The name of the expected / default DTD, if specified.  */
  const char *m_dtd_name;

  /* Are we the special <xi:include> parser?  */
  bool m_is_xinclude;
};

/* Process some body text.  We accumulate the text for later use; it's
   wrong to do anything with it immediately, because a single block of
   text might be broken up into multiple calls to this function.  */

void
gdb_xml_parser::body_text (const XML_Char *text, int length)
{
  if (m_error.reason < 0)
    return;

  scope_level &scope = m_scopes.back ();
  scope.body.append (text, length);
}

static void
gdb_xml_body_text (void *data, const XML_Char *text, int length)
{
  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;

  parser->body_text (text, length);
}

/* Issue a debugging message from one of PARSER's handlers.  */

void
gdb_xml_parser::vdebug (const char *format, va_list ap)
{
  int line = XML_GetCurrentLineNumber (m_expat_parser);

  std::string message = string_vprintf (format, ap);
  if (line)
    fprintf_unfiltered (gdb_stderr, "%s (line %d): %s\n",
			m_name, line, message.c_str ());
  else
    fprintf_unfiltered (gdb_stderr, "%s: %s\n",
			m_name, message.c_str ());
}

void
gdb_xml_debug (struct gdb_xml_parser *parser, const char *format, ...)
{
  if (!debug_xml)
    return;

  va_list ap;
  va_start (ap, format);
  parser->vdebug (format, ap);
  va_end (ap);
}

/* Issue an error message from one of PARSER's handlers, and stop
   parsing.  */

void
gdb_xml_parser::verror (const char *format, va_list ap)
{
  int line = XML_GetCurrentLineNumber (m_expat_parser);

  m_last_line = line;
  throw_verror (XML_PARSE_ERROR, format, ap);
}

void
gdb_xml_error (struct gdb_xml_parser *parser, const char *format, ...)
{
  va_list ap;
  va_start (ap, format);
  parser->verror (format, ap);
  va_end (ap);
}

/* Find the attribute named NAME in the set of parsed attributes
   ATTRIBUTES.  Returns NULL if not found.  */

struct gdb_xml_value *
xml_find_attribute (std::vector<gdb_xml_value> &attributes,
		    const char *name)
{
  for (gdb_xml_value &value : attributes)
    if (strcmp (value.name, name) == 0)
      return &value;

  return NULL;
}

/* Handle the start of an element.  NAME is the element, and ATTRS are
   the names and values of this element's attributes.  */

void
gdb_xml_parser::start_element (const XML_Char *name,
			       const XML_Char **attrs)
{
  if (m_error.reason < 0)
    return;

  const struct gdb_xml_element *element;
  const struct gdb_xml_attribute *attribute;
  unsigned int seen;

  /* Push an error scope.  If we return or throw an exception before
     filling this in, it will tell us to ignore children of this
     element.  Note we don't take a reference to the element yet
     because further below we'll process the element which may recurse
     back here and push more elements to the vector.  When the
     recursion unrolls all such elements will have been popped back
     already, but if one of those pushes reallocates the vector,
     previous element references will be invalidated.  */
  m_scopes.emplace_back ();

  /* Get a reference to the current scope.  */
  scope_level &scope = m_scopes[m_scopes.size () - 2];

  gdb_xml_debug (this, _("Entering element <%s>"), name);

  /* Find this element in the list of the current scope's allowed
     children.  Record that we've seen it.  */

  seen = 1;
  for (element = scope.elements; element && element->name;
       element++, seen <<= 1)
    if (strcmp (element->name, name) == 0)
      break;

  if (element == NULL || element->name == NULL)
    {
      /* If we're working on XInclude, <xi:include> can be the child
	 of absolutely anything.  Copy the previous scope's element
	 list into the new scope even if there was no match.  */
      if (m_is_xinclude)
	{
	  XML_DefaultCurrent (m_expat_parser);

	  scope_level &unknown_scope = m_scopes.back ();
	  unknown_scope.elements = scope.elements;
	  return;
	}

      gdb_xml_debug (this, _("Element <%s> unknown"), name);
      return;
    }

  if (!(element->flags & GDB_XML_EF_REPEATABLE) && (seen & scope.seen))
    gdb_xml_error (this, _("Element <%s> only expected once"), name);

  scope.seen |= seen;

  std::vector<gdb_xml_value> attributes;

  for (attribute = element->attributes;
       attribute != NULL && attribute->name != NULL;
       attribute++)
    {
      const char *val = NULL;
      const XML_Char **p;
      void *parsed_value;

      for (p = attrs; *p != NULL; p += 2)
	if (!strcmp (attribute->name, p[0]))
	  {
	    val = p[1];
	    break;
	  }

      if (*p != NULL && val == NULL)
	{
	  gdb_xml_debug (this, _("Attribute \"%s\" missing a value"),
			 attribute->name);
	  continue;
	}

      if (*p == NULL && !(attribute->flags & GDB_XML_AF_OPTIONAL))
	{
	  gdb_xml_error (this, _("Required attribute \"%s\" of "
				   "<%s> not specified"),
			 attribute->name, element->name);
	  continue;
	}

      if (*p == NULL)
	continue;

      gdb_xml_debug (this, _("Parsing attribute %s=\"%s\""),
		     attribute->name, val);

      if (attribute->handler)
	parsed_value = attribute->handler (this, attribute, val);
      else
	parsed_value = xstrdup (val);

      attributes.emplace_back (attribute->name, parsed_value);
    }

  /* Check for unrecognized attributes.  */
  if (debug_xml)
    {
      const XML_Char **p;

      for (p = attrs; *p != NULL; p += 2)
	{
	  for (attribute = element->attributes;
	       attribute != NULL && attribute->name != NULL;
	       attribute++)
	    if (strcmp (attribute->name, *p) == 0)
	      break;

	  if (attribute == NULL || attribute->name == NULL)
	    gdb_xml_debug (this, _("Ignoring unknown attribute %s"), *p);
	}
    }

  /* Call the element handler if there is one.  */
  if (element->start_handler)
    element->start_handler (this, element, m_user_data, attributes);

  /* Fill in a new scope level.  Note that we must delay getting a
     back reference till here because above we might have recursed,
     which may have reallocated the vector which invalidates
     iterators/pointers/references.  */
  scope_level &new_scope = m_scopes.back ();
  new_scope.element = element;
  new_scope.elements = element->children;
}

/* Wrapper for gdb_xml_start_element, to prevent throwing exceptions
   through expat.  */

static void
gdb_xml_start_element_wrapper (void *data, const XML_Char *name,
			       const XML_Char **attrs)
{
  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;

  TRY
    {
      parser->start_element (name, attrs);
    }
  CATCH (ex, RETURN_MASK_ALL)
    {
      parser->set_error (ex);
    }
  END_CATCH
}

/* Handle the end of an element.  NAME is the current element.  */

void
gdb_xml_parser::end_element (const XML_Char *name)
{
  if (m_error.reason < 0)
    return;

  struct scope_level *scope = &m_scopes.back ();
  const struct gdb_xml_element *element;
  unsigned int seen;

  gdb_xml_debug (this, _("Leaving element <%s>"), name);

  for (element = scope->elements, seen = 1;
       element != NULL && element->name != NULL;
       element++, seen <<= 1)
    if ((scope->seen & seen) == 0
	&& (element->flags & GDB_XML_EF_OPTIONAL) == 0)
      gdb_xml_error (this, _("Required element <%s> is missing"),
		     element->name);

  /* Call the element processor.  */
  if (scope->element != NULL && scope->element->end_handler)
    {
      const char *body;

      if (scope->body.empty ())
	body = "";
      else
	{
	  int length;

	  length = scope->body.size ();
	  body = scope->body.c_str ();

	  /* Strip leading and trailing whitespace.  */
	  while (length > 0 && ISSPACE (body[length - 1]))
	    length--;
	  scope->body.erase (length);
	  while (*body && ISSPACE (*body))
	    body++;
	}

      scope->element->end_handler (this, scope->element,
				   m_user_data, body);
    }
  else if (scope->element == NULL)
    XML_DefaultCurrent (m_expat_parser);

  /* Pop the scope level.  */
  m_scopes.pop_back ();
}

/* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
   through expat.  */

static void
gdb_xml_end_element_wrapper (void *data, const XML_Char *name)
{
  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;

  TRY
    {
      parser->end_element (name);
    }
  CATCH (ex, RETURN_MASK_ALL)
    {
      parser->set_error (ex);
    }
  END_CATCH
}

/* Free a parser and all its associated state.  */

gdb_xml_parser::~gdb_xml_parser ()
{
  XML_ParserFree (m_expat_parser);
}

/* Initialize a parser.  */

gdb_xml_parser::gdb_xml_parser (const char *name,
				const gdb_xml_element *elements,
				void *user_data)
  : m_name (name),
    m_user_data (user_data),
    m_error (exception_none),
    m_last_line (0),
    m_dtd_name (NULL),
    m_is_xinclude (false)
{
  m_expat_parser = XML_ParserCreateNS (NULL, '!');
  if (m_expat_parser == NULL)
    malloc_failure (0);

  XML_SetUserData (m_expat_parser, this);

  /* Set the callbacks.  */
  XML_SetElementHandler (m_expat_parser, gdb_xml_start_element_wrapper,
			 gdb_xml_end_element_wrapper);
  XML_SetCharacterDataHandler (m_expat_parser, gdb_xml_body_text);

  /* Initialize the outer scope.  */
  m_scopes.emplace_back (elements);
}

/* External entity handler.  The only external entities we support
   are those compiled into GDB (we do not fetch entities from the
   target).  */

static int XMLCALL
gdb_xml_fetch_external_entity (XML_Parser expat_parser,
			       const XML_Char *context,
			       const XML_Char *base,
			       const XML_Char *systemId,
			       const XML_Char *publicId)
{
  XML_Parser entity_parser;
  const char *text;
  enum XML_Status status;

  if (systemId == NULL)
    {
      gdb_xml_parser *parser
	= (gdb_xml_parser *) XML_GetUserData (expat_parser);

      text = fetch_xml_builtin (parser->dtd_name ());
      if (text == NULL)
	internal_error (__FILE__, __LINE__,
			_("could not locate built-in DTD %s"),
			parser->dtd_name ());
    }
  else
    {
      text = fetch_xml_builtin (systemId);
      if (text == NULL)
	return XML_STATUS_ERROR;
    }

  entity_parser = XML_ExternalEntityParserCreate (expat_parser,
						  context, NULL);

  /* Don't use our handlers for the contents of the DTD.  Just let expat
     process it.  */
  XML_SetElementHandler (entity_parser, NULL, NULL);
  XML_SetDoctypeDeclHandler (entity_parser, NULL, NULL);
  XML_SetXmlDeclHandler (entity_parser, NULL);
  XML_SetDefaultHandler (entity_parser, NULL);
  XML_SetUserData (entity_parser, NULL);

  status = XML_Parse (entity_parser, text, strlen (text), 1);

  XML_ParserFree (entity_parser);
  return status;
}

void
gdb_xml_parser::use_dtd (const char *dtd_name)
{
  enum XML_Error err;

  m_dtd_name = dtd_name;

  XML_SetParamEntityParsing (m_expat_parser,
			     XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
  XML_SetExternalEntityRefHandler (m_expat_parser,
				   gdb_xml_fetch_external_entity);

  /* Even if no DTD is provided, use the built-in DTD anyway.  */
  err = XML_UseForeignDTD (m_expat_parser, XML_TRUE);
  if (err != XML_ERROR_NONE)
    internal_error (__FILE__, __LINE__,
		    _("XML_UseForeignDTD failed: %s"),
		    XML_ErrorString (err));
}

/* Invoke PARSER on BUFFER.  BUFFER is the data to parse, which
   should be NUL-terminated.

   The return value is 0 for success or -1 for error.  It may throw,
   but only if something unexpected goes wrong during parsing; parse
   errors will be caught, warned about, and reported as failure.  */

int
gdb_xml_parser::parse (const char *buffer)
{
  enum XML_Status status;
  const char *error_string;

  gdb_xml_debug (this, _("Starting:\n%s"), buffer);

  status = XML_Parse (m_expat_parser, buffer, strlen (buffer), 1);

  if (status == XML_STATUS_OK && m_error.reason == 0)
    return 0;

  if (m_error.reason == RETURN_ERROR
      && m_error.error == XML_PARSE_ERROR)
    {
      gdb_assert (m_error.message != NULL);
      error_string = m_error.message;
    }
  else if (status == XML_STATUS_ERROR)
    {
      enum XML_Error err = XML_GetErrorCode (m_expat_parser);

      error_string = XML_ErrorString (err);
    }
  else
    {
      gdb_assert (m_error.reason < 0);
      throw_exception (m_error);
    }

  if (m_last_line != 0)
    warning (_("while parsing %s (at line %d): %s"), m_name,
	     m_last_line, error_string);
  else
    warning (_("while parsing %s: %s"), m_name, error_string);

  return -1;
}

int
gdb_xml_parse_quick (const char *name, const char *dtd_name,
		     const struct gdb_xml_element *elements,
		     const char *document, void *user_data)
{
  gdb_xml_parser parser (name, elements, user_data);
  if (dtd_name != NULL)
    parser.use_dtd (dtd_name);
  return parser.parse (document);
}

/* Parse a field VALSTR that we expect to contain an integer value.
   The integer is returned in *VALP.  The string is parsed with an
   equivalent to strtoul.

   Returns 0 for success, -1 for error.  */

static int
xml_parse_unsigned_integer (const char *valstr, ULONGEST *valp)
{
  const char *endptr;
  ULONGEST result;

  if (*valstr == '\0')
    return -1;

  result = strtoulst (valstr, &endptr, 0);
  if (*endptr != '\0')
    return -1;

  *valp = result;
  return 0;
}

/* Parse an integer string into a ULONGEST and return it, or call
   gdb_xml_error if it could not be parsed.  */

ULONGEST
gdb_xml_parse_ulongest (struct gdb_xml_parser *parser, const char *value)
{
  ULONGEST result;

  if (xml_parse_unsigned_integer (value, &result) != 0)
    gdb_xml_error (parser, _("Can't convert \"%s\" to an integer"), value);

  return result;
}

/* Parse an integer attribute into a ULONGEST.  */

void *
gdb_xml_parse_attr_ulongest (struct gdb_xml_parser *parser,
			     const struct gdb_xml_attribute *attribute,
			     const char *value)
{
  ULONGEST result;
  void *ret;

  if (xml_parse_unsigned_integer (value, &result) != 0)
    gdb_xml_error (parser, _("Can't convert %s=\"%s\" to an integer"),
		   attribute->name, value);

  ret = XNEW (ULONGEST);
  memcpy (ret, &result, sizeof (result));
  return ret;
}

/* A handler_data for yes/no boolean values.  */

const struct gdb_xml_enum gdb_xml_enums_boolean[] = {
  { "yes", 1 },
  { "no", 0 },
  { NULL, 0 }
};

/* Map NAME to VALUE.  A struct gdb_xml_enum * should be saved as the
   value of handler_data when using gdb_xml_parse_attr_enum to parse a
   fixed list of possible strings.  The list is terminated by an entry
   with NAME == NULL.  */

void *
gdb_xml_parse_attr_enum (struct gdb_xml_parser *parser,
			 const struct gdb_xml_attribute *attribute,
			 const char *value)
{
  const struct gdb_xml_enum *enums
    = (const struct gdb_xml_enum *) attribute->handler_data;
  void *ret;

  for (enums = (const struct gdb_xml_enum *) attribute->handler_data;
       enums->name != NULL; enums++)
    if (strcasecmp (enums->name, value) == 0)
      break;

  if (enums->name == NULL)
    gdb_xml_error (parser, _("Unknown attribute value %s=\"%s\""),
		 attribute->name, value);

  ret = xmalloc (sizeof (enums->value));
  memcpy (ret, &enums->value, sizeof (enums->value));
  return ret;
}


/* XInclude processing.  This is done as a separate step from actually
   parsing the document, so that we can produce a single combined XML
   document - e.g. to hand to a front end or to simplify comparing two
   documents.  We make extensive use of XML_DefaultCurrent, to pass
   input text directly into the output without reformatting or
   requoting it.

   We output the DOCTYPE declaration for the first document unchanged,
   if present, and discard DOCTYPEs from included documents.  Only the
   one we pass through here is used when we feed the result back to
   expat.  The XInclude standard explicitly does not discuss
   validation of the result; we choose to apply the same DTD applied
   to the outermost document.

   We can not simply include the external DTD subset in the document
   as an internal subset, because <!IGNORE> and <!INCLUDE> are valid
   only in external subsets.  But if we do not pass the DTD into the
   output at all, default values will not be filled in.

   We don't pass through any <?xml> declaration because we generate
   UTF-8, not whatever the input encoding was.  */

struct xinclude_parsing_data
{
  xinclude_parsing_data (std::string &output_,
			 xml_fetch_another fetcher_, void *fetcher_baton_,
			 int include_depth_)
    : output (output_),
      skip_depth (0),
      include_depth (include_depth_),
      fetcher (fetcher_),
      fetcher_baton (fetcher_baton_)
  {}

  /* Where the output goes.  */
  std::string &output;

  /* A count indicating whether we are in an element whose
     children should not be copied to the output, and if so,
     how deep we are nested.  This is used for anything inside
     an xi:include, and for the DTD.  */
  int skip_depth;

  /* The number of <xi:include> elements currently being processed,
     to detect loops.  */
  int include_depth;

  /* A function to call to obtain additional features, and its
     baton.  */
  xml_fetch_another fetcher;
  void *fetcher_baton;
};

static void
xinclude_start_include (struct gdb_xml_parser *parser,
			const struct gdb_xml_element *element,
			void *user_data,
			std::vector<gdb_xml_value> &attributes)
{
  struct xinclude_parsing_data *data
    = (struct xinclude_parsing_data *) user_data;
  char *href = (char *) xml_find_attribute (attributes, "href")->value.get ();

  gdb_xml_debug (parser, _("Processing XInclude of \"%s\""), href);

  if (data->include_depth > MAX_XINCLUDE_DEPTH)
    gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"),
		   MAX_XINCLUDE_DEPTH);

  gdb::optional<gdb::char_vector> text
    = data->fetcher (href, data->fetcher_baton);
  if (!text)
    gdb_xml_error (parser, _("Could not load XML document \"%s\""), href);

  if (!xml_process_xincludes (data->output, parser->name (),
			      text->data (), data->fetcher,
			      data->fetcher_baton,
			      data->include_depth + 1))
    gdb_xml_error (parser, _("Parsing \"%s\" failed"), href);

  data->skip_depth++;
}

static void
xinclude_end_include (struct gdb_xml_parser *parser,
		      const struct gdb_xml_element *element,
		      void *user_data, const char *body_text)
{
  struct xinclude_parsing_data *data
    = (struct xinclude_parsing_data *) user_data;

  data->skip_depth--;
}

static void XMLCALL
xml_xinclude_default (void *data_, const XML_Char *s, int len)
{
  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data_;
  xinclude_parsing_data *data = (xinclude_parsing_data *) parser->user_data ();

  /* If we are inside of e.g. xi:include or the DTD, don't save this
     string.  */
  if (data->skip_depth)
    return;

  /* Otherwise just add it to the end of the document we're building
     up.  */
  data->output.append (s, len);
}

static void XMLCALL
xml_xinclude_start_doctype (void *data_, const XML_Char *doctypeName,
			    const XML_Char *sysid, const XML_Char *pubid,
			    int has_internal_subset)
{
  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data_;
  xinclude_parsing_data *data = (xinclude_parsing_data *) parser->user_data ();

  /* Don't print out the doctype, or the contents of the DTD internal
     subset, if any.  */
  data->skip_depth++;
}

static void XMLCALL
xml_xinclude_end_doctype (void *data_)
{
  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data_;
  xinclude_parsing_data *data = (xinclude_parsing_data *) parser->user_data ();

  data->skip_depth--;
}

static void XMLCALL
xml_xinclude_xml_decl (void *data_, const XML_Char *version,
		       const XML_Char *encoding, int standalone)
{
  /* Do nothing - this function prevents the default handler from
     being called, thus suppressing the XML declaration from the
     output.  */
}

const struct gdb_xml_attribute xinclude_attributes[] = {
  { "href", GDB_XML_AF_NONE, NULL, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};

const struct gdb_xml_element xinclude_elements[] = {
  { "http://www.w3.org/2001/XInclude!include", xinclude_attributes, NULL,
    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
    xinclude_start_include, xinclude_end_include },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};

/* The main entry point for <xi:include> processing.  */

bool
xml_process_xincludes (std::string &result,
		       const char *name, const char *text,
		       xml_fetch_another fetcher, void *fetcher_baton,
		       int depth)
{
  xinclude_parsing_data data (result, fetcher, fetcher_baton, depth);

  gdb_xml_parser parser (name, xinclude_elements, &data);
  parser.set_is_xinclude (true);

  XML_SetCharacterDataHandler (parser.expat_parser (), NULL);
  XML_SetDefaultHandler (parser.expat_parser (), xml_xinclude_default);

  /* Always discard the XML version declarations; the only important
     thing this provides is encoding, and our result will have been
     converted to UTF-8.  */
  XML_SetXmlDeclHandler (parser.expat_parser (), xml_xinclude_xml_decl);

  if (depth > 0)
    /* Discard the doctype for included documents.  */
    XML_SetDoctypeDeclHandler (parser.expat_parser (),
			       xml_xinclude_start_doctype,
			       xml_xinclude_end_doctype);

  parser.use_dtd ("xinclude.dtd");

  if (parser.parse (text) == 0)
    {
      if (depth == 0)
	gdb_xml_debug (&parser, _("XInclude processing succeeded."));
      return true;
    }

  return false;
}
#endif /* HAVE_LIBEXPAT */


/* Return an XML document which was compiled into GDB, from
   the given FILENAME, or NULL if the file was not compiled in.  */

const char *
fetch_xml_builtin (const char *filename)
{
  const char *(*p)[2];

  for (p = xml_builtin; (*p)[0]; p++)
    if (strcmp ((*p)[0], filename) == 0)
      return (*p)[1];

  return NULL;
}

/* A to_xfer_partial helper function which reads XML files which were
   compiled into GDB.  The target may call this function from its own
   to_xfer_partial handler, after converting object and annex to the
   appropriate filename.  */

LONGEST
xml_builtin_xfer_partial (const char *filename,
			  gdb_byte *readbuf, const gdb_byte *writebuf,
			  ULONGEST offset, LONGEST len)
{
  const char *buf;
  LONGEST len_avail;

  gdb_assert (readbuf != NULL && writebuf == NULL);
  gdb_assert (filename != NULL);

  buf = fetch_xml_builtin (filename);
  if (buf == NULL)
    return -1;

  len_avail = strlen (buf);
  if (offset >= len_avail)
    return 0;

  if (len > len_avail - offset)
    len = len_avail - offset;
  memcpy (readbuf, buf + offset, len);
  return len;
}


static void
show_debug_xml (struct ui_file *file, int from_tty,
		struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("XML debugging is %s.\n"), value);
}

gdb::optional<gdb::char_vector>
xml_fetch_content_from_file (const char *filename, void *baton)
{
  const char *dirname = (const char *) baton;
  gdb_file_up file;

  if (dirname && *dirname)
    {
      char *fullname = concat (dirname, "/", filename, (char *) NULL);

      if (fullname == NULL)
	malloc_failure (0);
      file = gdb_fopen_cloexec (fullname, FOPEN_RT);
      xfree (fullname);
    }
  else
    file = gdb_fopen_cloexec (filename, FOPEN_RT);

  if (file == NULL)
    return {};

  /* Read in the whole file.  */

  size_t len;

  if (fseek (file.get (), 0, SEEK_END) == -1)
    perror_with_name (_("seek to end of file"));
  len = ftell (file.get ());
  rewind (file.get ());

  gdb::char_vector text (len + 1);

  if (fread (text.data (), 1, len, file.get ()) != len
      || ferror (file.get ()))
    {
      warning (_("Read error from \"%s\""), filename);
      return {};
    }

  text.back () = '\0';
  return text;
}

void
_initialize_xml_support (void)
{
  add_setshow_boolean_cmd ("xml", class_maintenance, &debug_xml,
			   _("Set XML parser debugging."),
			   _("Show XML parser debugging."),
			   _("When set, debugging messages for XML parsers "
			     "are displayed."),
			   NULL, show_debug_xml,
			   &setdebuglist, &showdebuglist);
}
