aboutsummaryrefslogtreecommitdiff
path: root/gdb/xml-tdesc.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-04-18 21:39:25 +0100
committerPedro Alves <palves@redhat.com>2017-04-18 23:50:55 +0100
commitbd8a901f9e34191e0645a5527556d124ba5c345a (patch)
treeca2c04a1e7ed2387b979584beff7682e8a21c2e1 /gdb/xml-tdesc.c
parentd35d19584cf56a50b4833ff9c003597e01022f27 (diff)
downloadgdb-bd8a901f9e34191e0645a5527556d124ba5c345a.zip
gdb-bd8a901f9e34191e0645a5527556d124ba5c345a.tar.gz
gdb-bd8a901f9e34191e0645a5527556d124ba5c345a.tar.bz2
xml-support.c: Use std::string for growing string buffer
This main idea behind this patch is this change to xml-support.c:scope_level - /* Body text accumulation. This is an owning pointer. */ - struct obstack *body; + /* Body text accumulation. */ + std::string body; ... which allows simplifying other parts of the code. In target_fetch_description_xml, we want to distinguish between returning "success + empty std::string" and "no success", and gdb::optional is a natural fit for that. gdb/ChangeLog: 2017-04-18 Pedro Alves <palves@redhat.com> * tracefile-tfile.c (tfile_write_tdesc): Adjust to use gdb::optional<std::string>. * xml-support.c: Include <string>. (scope_level::scope_level(scope_level &&)) (scope_level::~scope_level): Delete. (scope_level::body): Now a std::string. (gdb_xml_body_text, gdb_xml_end_element): Adjust. (xinclude_parsing_data::xinclude_parsing_data): Add 'output' parameter. (xinclude_parsing_data::~xinclude_parsing_data): Delete. (xinclude_parsing_data::output): Now a std::string reference. (xinclude_start_include): Adjust. (xml_xinclude_default): Adjust. (xml_process_xincludes): Add 'output' parameter, and return bool. * xml-support.h (xml_process_xincludes): Add 'output' parameter, and return bool. * xml-tdesc.c: Include <unordered_map> and <string>. (tdesc_xml_cache): Delete. (tdesc_xml_cache_s): Delete. (xml_cache): Now an std::unordered_map. (tdesc_parse_xml): Adjust to use std::string and unordered_map. (target_fetch_description_xml): Change return type to gdb::optional<std::string>, and adjust. * xml-tdesc.h: Include "common/gdb_optional.h" and <string>. (target_fetch_description_xml): Change return type to gdb::optional<std::string>.
Diffstat (limited to 'gdb/xml-tdesc.c')
-rw-r--r--gdb/xml-tdesc.c81
1 files changed, 29 insertions, 52 deletions
diff --git a/gdb/xml-tdesc.c b/gdb/xml-tdesc.c
index 522a9ba..daa713f 100644
--- a/gdb/xml-tdesc.c
+++ b/gdb/xml-tdesc.c
@@ -26,6 +26,8 @@
#include "xml-tdesc.h"
#include "osabi.h"
#include "filenames.h"
+#include <unordered_map>
+#include <string>
/* Maximum sizes.
This is just to catch obviously wrong values. */
@@ -64,15 +66,7 @@ tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
then we will create unnecessary duplicate gdbarches. See
gdbarch_list_lookup_by_info. */
-struct tdesc_xml_cache
-{
- const char *xml_document;
- struct target_desc *tdesc;
-};
-typedef struct tdesc_xml_cache tdesc_xml_cache_s;
-DEF_VEC_O(tdesc_xml_cache_s);
-
-static VEC(tdesc_xml_cache_s) *xml_cache;
+static std::unordered_map<std::string, target_desc *> xml_cache;
/* Callback data for target description parsing. */
@@ -631,55 +625,42 @@ static struct target_desc *
tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
void *fetcher_baton)
{
- struct cleanup *back_to, *result_cleanup;
struct tdesc_parsing_data data;
- struct tdesc_xml_cache *cache;
- char *expanded_text;
- int ix;
/* Expand all XInclude directives. */
- expanded_text = xml_process_xincludes (_("target description"),
- document, fetcher, fetcher_baton, 0);
- if (expanded_text == NULL)
+ std::string expanded_text;
+
+ if (!xml_process_xincludes (expanded_text,
+ _("target description"),
+ document, fetcher, fetcher_baton, 0))
{
warning (_("Could not load XML target description; ignoring"));
return NULL;
}
/* Check for an exact match in the list of descriptions we have
- previously parsed. strcmp is a slightly inefficient way to
- do this; an SHA-1 checksum would work as well. */
- for (ix = 0; VEC_iterate (tdesc_xml_cache_s, xml_cache, ix, cache); ix++)
- if (strcmp (cache->xml_document, expanded_text) == 0)
- {
- xfree (expanded_text);
- return cache->tdesc;
- }
-
- back_to = make_cleanup (null_cleanup, NULL);
+ previously parsed. */
+ const auto it = xml_cache.find (expanded_text);
+ if (it != xml_cache.end ())
+ return it->second;
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);
+ struct cleanup *result_cleanup
+ = make_cleanup_free_target_description (data.tdesc);
if (gdb_xml_parse_quick (_("target description"), "gdb-target.dtd",
- tdesc_elements, expanded_text, &data) == 0)
+ tdesc_elements, expanded_text.c_str (), &data) == 0)
{
/* Parsed successfully. */
- struct tdesc_xml_cache new_cache;
-
- new_cache.xml_document = expanded_text;
- new_cache.tdesc = data.tdesc;
- VEC_safe_push (tdesc_xml_cache_s, xml_cache, &new_cache);
+ xml_cache.emplace (std::move (expanded_text), data.tdesc);
discard_cleanups (result_cleanup);
- do_cleanups (back_to);
return data.tdesc;
}
else
{
warning (_("Could not load XML target description; ignoring"));
- do_cleanups (back_to);
+ do_cleanups (result_cleanup);
return NULL;
}
}
@@ -759,7 +740,7 @@ target_read_description_xml (struct target_ops *ops)
includes, but not parsing it. Used to dump whole tdesc
as a single XML file. */
-char *
+gdb::optional<std::string>
target_fetch_description_xml (struct target_ops *ops)
{
#if !defined(HAVE_LIBEXPAT)
@@ -772,28 +753,24 @@ target_fetch_description_xml (struct target_ops *ops)
"disabled at compile time"));
}
- return NULL;
+ return {};
#else
struct target_desc *tdesc;
- char *tdesc_str;
- char *expanded_text;
- struct cleanup *back_to;
- tdesc_str = fetch_available_features_from_target ("target.xml", ops);
+ gdb::unique_xmalloc_ptr<char>
+ tdesc_str (fetch_available_features_from_target ("target.xml", ops));
if (tdesc_str == NULL)
- return NULL;
+ return {};
- back_to = make_cleanup (xfree, tdesc_str);
- expanded_text = xml_process_xincludes (_("target description"),
- tdesc_str,
- fetch_available_features_from_target, ops, 0);
- do_cleanups (back_to);
- if (expanded_text == NULL)
+ std::string output;
+ if (!xml_process_xincludes (output,
+ _("target description"),
+ tdesc_str.get (),
+ fetch_available_features_from_target, ops, 0))
{
warning (_("Could not load XML target description; ignoring"));
- return NULL;
+ return {};
}
-
- return expanded_text;
+ return output;
#endif
}