This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Simplify XML parsing a bit.


I find the the cleanup handling around calling gdb_parse a
bit more complicated than it needs to be.  At least, I always find
myself needing to think about it carefuly.

This patch factors out  a bit of code that all gdb_parse callers
end up doing into a new gdb_parse_quick function.  And then,
simplifies current gdb_parse callers by instead using this
new function.

I couldn't come up with a better name for the function.  I was 
using "gdb_parse_once" in a previous version of the patch...

Tested on x86_64-linux native&gdbserver and applied.

-- 
Pedro Alves

2011-01-25  Pedro Alves  <pedro@codesourcery.com>

	Simplify XML parsing a bit.

	gdb/
	* xml-support.h (gdb_xml_parse_quick): Declare.
	* xml-support.c (gdb_xml_create_parser_and_cleanup_1): Renamed
	from gdb_xml_create_parser_and_cleanup, and added `old_chain'
	parameter.
	(gdb_xml_create_parser_and_cleanup): Reimplement on top of
	gdb_xml_create_parser_and_cleanup_1.
	(gdb_xml_parse_quick): New.
	* memory-map.c (parse_memory_map): Use gdb_xml_parse_quick.
	* osdata.c (osdata_parse): Ditto.
	* remote.c (remote_threads_info): Ditto.
	* solib-target.c (solib_target_parse_libraries): Ditto.
	* xml-syscall.c (syscall_parse_xml): Ditto.
	* xml-tdesc.c (tdesc_parse_xml): Ditto.

---
 gdb/memory-map.c   |   23 ++++++++++-------------
 gdb/osdata.c       |   22 ++++++++++------------
 gdb/remote.c       |   21 +++++----------------
 gdb/solib-target.c |   24 ++++++++++--------------
 gdb/xml-support.c  |   47 ++++++++++++++++++++++++++++++++++++++++++-----
 gdb/xml-support.h  |   12 ++++++++++++
 gdb/xml-syscall.c  |    8 ++------
 gdb/xml-tdesc.c    |    7 ++-----
 8 files changed, 93 insertions(+), 71 deletions(-)

Index: src/gdb/xml-support.c
===================================================================
--- src.orig/gdb/xml-support.c	2011-01-25 09:31:36.567639998 +0000
+++ src/gdb/xml-support.c	2011-01-25 09:39:16.687639991 +0000
@@ -427,13 +427,14 @@ gdb_xml_cleanup (void *arg)
 /* Initialize and return a parser.  Register a cleanup to destroy the
    parser.  */
 
-struct gdb_xml_parser *
-gdb_xml_create_parser_and_cleanup (const char *name,
-				   const struct gdb_xml_element *elements,
-				   void *user_data)
+static struct gdb_xml_parser *
+gdb_xml_create_parser_and_cleanup_1 (const char *name,
+				     const struct gdb_xml_element *elements,
+				     void *user_data, struct cleanup **old_chain)
 {
   struct gdb_xml_parser *parser;
   struct scope_level start_scope;
+  struct cleanup *dummy;
 
   /* Initialize the parser.  */
   parser = XZALLOC (struct gdb_xml_parser);
@@ -459,11 +460,27 @@ gdb_xml_create_parser_and_cleanup (const
   start_scope.elements = elements;
   VEC_safe_push (scope_level_s, parser->scopes, &start_scope);
 
-  make_cleanup (gdb_xml_cleanup, parser);
+  if (old_chain == NULL)
+    old_chain = &dummy;
 
+  *old_chain = make_cleanup (gdb_xml_cleanup, parser);
   return parser;
 }
 
+/* Initialize and return a parser.  Register a cleanup to destroy the
+   parser.  */
+
+struct gdb_xml_parser *
+gdb_xml_create_parser_and_cleanup (const char *name,
+				   const struct gdb_xml_element *elements,
+				   void *user_data)
+{
+  struct cleanup *old_chain;
+
+  return gdb_xml_create_parser_and_cleanup_1 (name, elements, user_data,
+					      &old_chain);
+}
+
 /* External entity handler.  The only external entities we support
    are those compiled into GDB (we do not fetch entities from the
    target).  */
@@ -581,6 +598,26 @@ gdb_xml_parse (struct gdb_xml_parser *pa
   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;
+
+  parser = gdb_xml_create_parser_and_cleanup_1 (name, elements,
+						user_data, &back_to);
+  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.
Index: src/gdb/xml-support.h
===================================================================
--- src.orig/gdb/xml-support.h	2011-01-25 09:31:36.567639998 +0000
+++ src/gdb/xml-support.h	2011-01-25 09:39:16.687639991 +0000
@@ -197,6 +197,18 @@ void gdb_xml_use_dtd (struct gdb_xml_par
 
 int gdb_xml_parse (struct gdb_xml_parser *parser, const char *buffer);
 
+/* Parse a XML document.  DOCUMENT is the data to parse, which should
+   be NUL-terminated. If non-NULL, use the compiled-in DTD named
+   DTD_NAME to drive the parsing.
+
+   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_parse_quick (const char *name, const char *dtd_name,
+			 const struct gdb_xml_element *elements,
+			 const char *document, void *user_data);
+
 /* Issue a debugging message from one of PARSER's handlers.  */
 
 void gdb_xml_debug (struct gdb_xml_parser *parser, const char *format, ...)
Index: src/gdb/memory-map.c
===================================================================
--- src.orig/gdb/memory-map.c	2011-01-25 09:31:36.567639998 +0000
+++ src/gdb/memory-map.c	2011-01-25 09:39:16.687639991 +0000
@@ -178,25 +178,22 @@ const struct gdb_xml_element memory_map_
 VEC(mem_region_s) *
 parse_memory_map (const char *memory_map)
 {
-  struct gdb_xml_parser *parser;
   VEC(mem_region_s) *result = NULL;
-  struct cleanup *before_deleting_result, *back_to;
+  struct cleanup *back_to;
   struct memory_map_parsing_data data = { NULL };
 
-  back_to = make_cleanup (null_cleanup, NULL);
-  parser = gdb_xml_create_parser_and_cleanup (_("target memory map"),
-					      memory_map_elements, &data);
-
-  /* Note: 'clear_result' will zero 'result'.  */
-  before_deleting_result = make_cleanup (clear_result, &result);
   data.memory_map = &result;
-
-  if (gdb_xml_parse (parser, memory_map) == 0)
-    /* Parsed successfully, don't need to delete the result.  */
-    discard_cleanups (before_deleting_result);
+  back_to = make_cleanup (clear_result, &result);
+  if (gdb_xml_parse_quick (_("target memory map"), NULL, memory_map_elements,
+			   memory_map, &data) == 0)
+    {
+      /* Parsed successfully, keep the result.  */
+      discard_cleanups (back_to);
+      return result;
+    }
 
   do_cleanups (back_to);
-  return result;
+  return NULL;
 }
 
 #endif /* HAVE_LIBEXPAT */
Index: src/gdb/osdata.c
===================================================================
--- src.orig/gdb/osdata.c	2011-01-25 09:31:36.567639998 +0000
+++ src/gdb/osdata.c	2011-01-25 09:39:16.697639988 +0000
@@ -168,23 +168,21 @@ const struct gdb_xml_element osdata_elem
 struct osdata *
 osdata_parse (const char *xml)
 {
-  struct gdb_xml_parser *parser;
-  struct cleanup *before_deleting_result, *back_to;
+  struct cleanup *back_to;
   struct osdata_parsing_data data = { NULL };
 
-  back_to = make_cleanup (null_cleanup, NULL);
-  parser = gdb_xml_create_parser_and_cleanup (_("osdata"),
-                                             osdata_elements, &data);
-  gdb_xml_use_dtd (parser, "osdata.dtd");
+  back_to = make_cleanup (clear_parsing_data, &data);
 
-  before_deleting_result = make_cleanup (clear_parsing_data, &data);
-
-  if (gdb_xml_parse (parser, xml) == 0)
-    /* Parsed successfully, don't need to delete the result.  */
-    discard_cleanups (before_deleting_result);
+  if (gdb_xml_parse_quick (_("osdata"), "osdata.dtd",
+			   osdata_elements, xml, &data) == 0)
+    {
+      /* Parsed successfully, don't need to delete the result.  */
+      discard_cleanups (back_to);
+      return data.osdata;
+    }
 
   do_cleanups (back_to);
-  return data.osdata;
+  return NULL;
 }
 #endif
 
Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c	2011-01-25 09:31:36.567639998 +0000
+++ src/gdb/remote.c	2011-01-25 09:39:16.697639988 +0000
@@ -2595,25 +2595,16 @@ remote_threads_info (struct target_ops *
 					 TARGET_OBJECT_THREADS, NULL);
 
       struct cleanup *back_to = make_cleanup (xfree, xml);
+
       if (xml && *xml)
 	{
-	  struct gdb_xml_parser *parser;
 	  struct threads_parsing_context context;
-	  struct cleanup *clear_parsing_context;
-
-	  context.items = 0;
-	  /* Note: this parser cleanup is already guarded by BACK_TO
-	     above.  */
-	  parser = gdb_xml_create_parser_and_cleanup (_("threads"),
-						      threads_elements,
-						      &context);
 
-	  gdb_xml_use_dtd (parser, "threads.dtd");
+	  context.items = NULL;
+	  make_cleanup (clear_threads_parsing_context, &context);
 
-	  clear_parsing_context
-	    = make_cleanup (clear_threads_parsing_context, &context);
-
-	  if (gdb_xml_parse (parser, xml) == 0)
+	  if (gdb_xml_parse_quick (_("threads"), "threads.dtd",
+				   threads_elements, xml, &context) == 0)
 	    {
 	      int i;
 	      struct thread_item *item;
@@ -2640,8 +2631,6 @@ remote_threads_info (struct target_ops *
 		    }
 		}
 	    }
-
-	  do_cleanups (clear_parsing_context);
 	}
 
       do_cleanups (back_to);
Index: src/gdb/solib-target.c
===================================================================
--- src.orig/gdb/solib-target.c	2011-01-25 09:31:36.567639998 +0000
+++ src/gdb/solib-target.c	2011-01-25 09:39:16.697639988 +0000
@@ -227,24 +227,20 @@ const struct gdb_xml_element library_lis
 static VEC(lm_info_p) *
 solib_target_parse_libraries (const char *library)
 {
-  struct gdb_xml_parser *parser;
   VEC(lm_info_p) *result = NULL;
-  struct cleanup *before_deleting_result, *back_to;
+  struct cleanup *back_to = make_cleanup (solib_target_free_library_list,
+					  &result);
 
-  back_to = make_cleanup (null_cleanup, NULL);
-  parser = gdb_xml_create_parser_and_cleanup (_("target library list"),
-					      library_list_elements, &result);
-  gdb_xml_use_dtd (parser, "library-list.dtd");
-
-  before_deleting_result = make_cleanup (solib_target_free_library_list,
-					 &result);
-
-  if (gdb_xml_parse (parser, library) == 0)
-    /* Parsed successfully, don't need to delete the result.  */
-    discard_cleanups (before_deleting_result);
+  if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd",
+			   library_list_elements, library, &result) == 0)
+    {
+      /* Parsed successfully, keep the result.  */
+      discard_cleanups (back_to);
+      return result;
+    }
 
   do_cleanups (back_to);
-  return result;
+  return NULL;
 }
 #endif
 
Index: src/gdb/xml-syscall.c
===================================================================
--- src.orig/gdb/xml-syscall.c	2011-01-25 09:31:36.567639998 +0000
+++ src/gdb/xml-syscall.c	2011-01-25 09:39:16.697639988 +0000
@@ -224,17 +224,13 @@ syscall_parse_xml (const char *document,
                    void *fetcher_baton)
 {
   struct cleanup *result_cleanup;
-  struct gdb_xml_parser *parser;
   struct syscall_parsing_data data;
 
-  parser = gdb_xml_create_parser_and_cleanup (_("syscalls info"),
-					      syselements, &data);
-
-  memset (&data, 0, sizeof (struct syscall_parsing_data));
   data.sysinfo = allocate_syscalls_info ();
   result_cleanup = make_cleanup_free_syscalls_info (data.sysinfo);
 
-  if (gdb_xml_parse (parser, document) == 0)
+  if (gdb_xml_parse_quick (_("syscalls info"), NULL,
+			   syselements, document, &data) == 0)
     {
       /* Parsed successfully.  */
       discard_cleanups (result_cleanup);
Index: src/gdb/xml-tdesc.c
===================================================================
--- src.orig/gdb/xml-tdesc.c	2011-01-25 09:31:36.567639998 +0000
+++ src/gdb/xml-tdesc.c	2011-01-25 09:39:16.697639988 +0000
@@ -505,7 +505,6 @@ tdesc_parse_xml (const char *document, x
 		 void *fetcher_baton)
 {
   struct cleanup *back_to, *result_cleanup;
-  struct gdb_xml_parser *parser;
   struct tdesc_parsing_data data;
   struct tdesc_xml_cache *cache;
   char *expanded_text;
@@ -531,16 +530,14 @@ tdesc_parse_xml (const char *document, x
       }
 
   back_to = make_cleanup (null_cleanup, NULL);
-  parser = gdb_xml_create_parser_and_cleanup (_("target description"),
-					      tdesc_elements, &data);
-  gdb_xml_use_dtd (parser, "gdb-target.dtd");
 
   memset (&data, 0, sizeof (struct tdesc_parsing_data));
   data.tdesc = allocate_target_description ();
   result_cleanup = make_cleanup_free_target_description (data.tdesc);
   make_cleanup (xfree, expanded_text);
 
-  if (gdb_xml_parse (parser, expanded_text) == 0)
+  if (gdb_xml_parse_quick (_("target description"), "gdb-target.dtd",
+			   tdesc_elements, expanded_text, &data) == 0)
     {
       /* Parsed successfully.  */
       struct tdesc_xml_cache new_cache;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]