Support fusion for ELFv2 stubs
[deliverable/binutils-gdb.git] / gdb / xml-support.c
index 49a10d72d56f6974d033072831148fa4deda3fd4..5062bc155f841361d8aec16066b18ab04fc72977 100644 (file)
@@ -1,12 +1,12 @@
 /* Helper routines for parsing XML using Expat.
 
-   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2006-2014 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 2 of the License, or
+   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,
    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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "gdbcmd.h"
 #include "exceptions.h"
 #include "xml-support.h"
+#include "filestuff.h"
 
-#include "gdb_string.h"
+#include <string.h>
 #include "safe-ctype.h"
 
 /* Debugging flag.  */
@@ -95,7 +94,7 @@ gdb_xml_body_text (void *data, const XML_Char *text, int length)
 
   if (scope->body == NULL)
     {
-      scope->body = XZALLOC (struct obstack);
+      scope->body = XCNEW (struct obstack);
       obstack_init (scope->body);
     }
 
@@ -139,6 +138,22 @@ gdb_xml_error (struct gdb_xml_parser *parser, const char *format, ...)
   throw_verror (XML_PARSE_ERROR, format, 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 (VEC(gdb_xml_value_s) *attributes, const char *name)
+{
+  struct gdb_xml_value *value;
+  int ix;
+
+  for (ix = 0; VEC_iterate (gdb_xml_value_s, attributes, ix, value); ix++)
+    if (strcmp (value->name, name) == 0)
+      return value;
+
+  return NULL;
+}
+
 /* Clean up a vector of parsed attribute values.  */
 
 static void
@@ -340,7 +355,7 @@ gdb_xml_end_element (void *data, const XML_Char *name)
       gdb_xml_error (parser, _("Required element <%s> is missing"),
                     element->name);
 
-  /* Call the element processor. */
+  /* Call the element processor.  */
   if (scope->element != NULL && scope->element->end_handler)
     {
       char *body;
@@ -425,24 +440,26 @@ gdb_xml_cleanup (void *arg)
   xfree (parser);
 }
 
-/* Initialize and return a parser.  Register a cleanup to destroy the
-   parser.  */
+/* Initialize a parser and store it to *PARSER_RESULT.  Register a
+   cleanup to destroy the parser.  */
 
-struct gdb_xml_parser *
+static struct cleanup *
 gdb_xml_create_parser_and_cleanup (const char *name,
                                   const struct gdb_xml_element *elements,
-                                  void *user_data)
+                                  void *user_data,
+                                  struct gdb_xml_parser **parser_result)
 {
   struct gdb_xml_parser *parser;
   struct scope_level start_scope;
+  struct cleanup *result;
 
   /* Initialize the parser.  */
-  parser = XZALLOC (struct gdb_xml_parser);
+  parser = XCNEW (struct gdb_xml_parser);
   parser->expat_parser = XML_ParserCreateNS (NULL, '!');
   if (parser->expat_parser == NULL)
     {
       xfree (parser);
-      nomem (0);
+      malloc_failure (0);
     }
 
   parser->name = name;
@@ -460,9 +477,8 @@ gdb_xml_create_parser_and_cleanup (const char *name,
   start_scope.elements = elements;
   VEC_safe_push (scope_level_s, parser->scopes, &start_scope);
 
-  make_cleanup (gdb_xml_cleanup, parser);
-
-  return parser;
+  *parser_result = parser;
+  return make_cleanup (gdb_xml_cleanup, parser);
 }
 
 /* External entity handler.  The only external entities we support
@@ -485,7 +501,8 @@ gdb_xml_fetch_external_entity (XML_Parser expat_parser,
     {
       text = fetch_xml_builtin (parser->dtd_name);
       if (text == NULL)
-       internal_error (__FILE__, __LINE__, "could not locate built-in DTD %s",
+       internal_error (__FILE__, __LINE__,
+                       _("could not locate built-in DTD %s"),
                        parser->dtd_name);
     }
   else
@@ -530,7 +547,8 @@ gdb_xml_use_dtd (struct gdb_xml_parser *parser, const char *dtd_name)
   err = XML_UseForeignDTD (parser->expat_parser, XML_TRUE);
   if (err != XML_ERROR_NONE)
     internal_error (__FILE__, __LINE__,
-                   "XML_UseForeignDTD failed: %s", XML_ErrorString (err));
+                   _("XML_UseForeignDTD failed: %s"),
+                   XML_ErrorString (err));
 }
 
 /* Invoke PARSER on BUFFER.  BUFFER is the data to parse, which
@@ -546,6 +564,8 @@ gdb_xml_parse (struct gdb_xml_parser *parser, const char *buffer)
   enum XML_Status status;
   const char *error_string;
 
+  gdb_xml_debug (parser, _("Starting:\n%s"), buffer);
+
   status = XML_Parse (parser->expat_parser, buffer, strlen (buffer), 1);
 
   if (status == XML_STATUS_OK && parser->error.reason == 0)
@@ -560,6 +580,7 @@ gdb_xml_parse (struct gdb_xml_parser *parser, const char *buffer)
   else if (status == XML_STATUS_ERROR)
     {
       enum XML_Error err = XML_GetErrorCode (parser->expat_parser);
+
       error_string = XML_ErrorString (err);
     }
   else
@@ -577,6 +598,26 @@ gdb_xml_parse (struct gdb_xml_parser *parser, const char *buffer)
   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)
+{
+  struct gdb_xml_parser *parser;
+  struct cleanup *back_to;
+  int result;
+
+  back_to = gdb_xml_create_parser_and_cleanup (name, elements,
+                                              user_data, &parser);
+  if (dtd_name != NULL)
+    gdb_xml_use_dtd (parser, dtd_name);
+  result = gdb_xml_parse (parser, document);
+
+  do_cleanups (back_to);
+
+  return result;
+}
+
 /* 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.
@@ -717,10 +758,9 @@ xinclude_start_include (struct gdb_xml_parser *parser,
                        void *user_data, VEC(gdb_xml_value_s) *attributes)
 {
   struct xinclude_parsing_data *data = user_data;
-  char *href = VEC_index (gdb_xml_value_s, attributes, 0)->value;
+  char *href = xml_find_attribute (attributes, "href")->value;
   struct cleanup *back_to;
   char *text, *output;
-  int ret;
 
   gdb_xml_debug (parser, _("Processing XInclude of \"%s\""), href);
 
@@ -832,17 +872,17 @@ xml_process_xincludes (const char *name, const char *text,
                       xml_fetch_another fetcher, void *fetcher_baton,
                       int depth)
 {
-  enum XML_Error err;
   struct gdb_xml_parser *parser;
   struct xinclude_parsing_data *data;
   struct cleanup *back_to;
   char *result = NULL;
 
-  data = XZALLOC (struct xinclude_parsing_data);
+  data = XCNEW (struct xinclude_parsing_data);
   obstack_init (&data->obstack);
   back_to = make_cleanup (xml_xinclude_cleanup, data);
 
-  parser = gdb_xml_create_parser_and_cleanup (name, xinclude_elements, data);
+  gdb_xml_create_parser_and_cleanup (name, xinclude_elements,
+                                    data, &parser);
   parser->is_xinclude = 1;
 
   data->include_depth = depth;
@@ -871,8 +911,7 @@ xml_process_xincludes (const char *name, const char *text,
       result = xstrdup (obstack_finish (&data->obstack));
 
       if (depth == 0)
-       gdb_xml_debug (parser, _("XInclude processing succeeded:\n%s"),
-                      result);
+       gdb_xml_debug (parser, _("XInclude processing succeeded."));
     }
   else
     result = NULL;
@@ -936,6 +975,107 @@ show_debug_xml (struct ui_file *file, int from_tty,
   fprintf_filtered (file, _("XML debugging is %s.\n"), value);
 }
 
+void
+obstack_xml_printf (struct obstack *obstack, const char *format, ...)
+{
+  va_list ap;
+  const char *f;
+  const char *prev;
+  int percent = 0;
+
+  va_start (ap, format);
+
+  prev = format;
+  for (f = format; *f; f++)
+    {
+      if (percent)
+       {
+         switch (*f)
+           {
+           case 's':
+             {
+               char *p;
+               char *a = va_arg (ap, char *);
+
+               obstack_grow (obstack, prev, f - prev - 1);
+               p = xml_escape_text (a);
+               obstack_grow_str (obstack, p);
+               xfree (p);
+               prev = f + 1;
+             }
+             break;
+           }
+         percent = 0;
+       }
+      else if (*f == '%')
+       percent = 1;
+    }
+
+  obstack_grow_str (obstack, prev);
+  va_end (ap);
+}
+
+char *
+xml_fetch_content_from_file (const char *filename, void *baton)
+{
+  const char *dirname = baton;
+  FILE *file;
+  struct cleanup *back_to;
+  char *text;
+  size_t len, offset;
+
+  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 NULL;
+
+  back_to = make_cleanup_fclose (file);
+
+  /* Read in the whole file, one chunk at a time.  */
+  len = 4096;
+  offset = 0;
+  text = xmalloc (len);
+  make_cleanup (free_current_contents, &text);
+  while (1)
+    {
+      size_t bytes_read;
+
+      /* Continue reading where the last read left off.  Leave at least
+        one byte so that we can NUL-terminate the result.  */
+      bytes_read = fread (text + offset, 1, len - offset - 1, file);
+      if (ferror (file))
+       {
+         warning (_("Read error from \"%s\""), filename);
+         do_cleanups (back_to);
+         return NULL;
+       }
+
+      offset += bytes_read;
+
+      if (feof (file))
+       break;
+
+      len = len * 2;
+      text = xrealloc (text, len);
+    }
+
+  fclose (file);
+  discard_cleanups (back_to);
+
+  text[offset] = '\0';
+  return text;
+}
+
 void _initialize_xml_support (void);
 
 void
This page took 0.029486 seconds and 4 git commands to generate.