xml-support.c: Use std::vector

scope_level::scope_level needed both a move ctor and a dtor explicitly
coded, but those will be eliminated in a following patch.

gdb/ChangeLog:
2017-04-18  Pedro Alves  <palves@redhat.com>

	* xml-support.c: Include <vector>.
	(scope_level::scope_level(const gdb_xml_element *))
	(scope_level::scope_level(scope_level&&)): New.
	(scope_level::~scope_level): New.
	(scope_level_s): Delete.
	(gdb_xml_parser::scopes): Now a std::vector.
	(gdb_xml_body_text, gdb_xml_start_element, gdb_xml_end_element):
	Use std::vector.
	(gdb_xml_parser::~gdb_xml_parser): Remove now unnecessary
	scope cleanup code.
	(gdb_xml_parser::gdb_xml_parser): Remove explicit initialization
	of the scopes member.  Use std::vector::emplace_back.
This commit is contained in:
Pedro Alves 2017-04-18 21:39:24 +01:00
parent 010151c914
commit a7fc9b6193
2 changed files with 76 additions and 51 deletions

View File

@ -1,3 +1,18 @@
2017-04-18 Pedro Alves <palves@redhat.com>
* xml-support.c: Include <vector>.
(scope_level::scope_level(const gdb_xml_element *))
(scope_level::scope_level(scope_level&&)): New.
(scope_level::~scope_level): New.
(scope_level_s): Delete.
(gdb_xml_parser::scopes): Now a std::vector.
(gdb_xml_body_text, gdb_xml_start_element, gdb_xml_end_element):
Use std::vector.
(gdb_xml_parser::~gdb_xml_parser): Remove now unnecessary
scope cleanup code.
(gdb_xml_parser::gdb_xml_parser): Remove explicit initialization
of the scopes member. Use std::vector::emplace_back.
2017-04-18 Pedro Alves <palves@redhat.com>
* xml-support.c (gdb_xml_parser): Add ctor/dtor. Make is_xinclude

View File

@ -22,6 +22,7 @@
#include "xml-support.h"
#include "filestuff.h"
#include "safe-ctype.h"
#include <vector>
/* Debugging flag. */
static int debug_xml;
@ -42,6 +43,32 @@ static int debug_xml;
nesting. */
struct scope_level
{
explicit scope_level (const gdb_xml_element *elements_ = NULL)
: elements (elements_),
element (NULL),
seen (0),
body (NULL)
{}
scope_level (scope_level &&other) noexcept
: elements (other.elements),
element (other.element),
seen (other.seen),
body (other.body)
{
if (this != &other)
other.body = NULL;
}
~scope_level ()
{
if (this->body)
{
obstack_free (this->body, NULL);
xfree (this->body);
}
}
/* Elements we allow at this level. */
const struct gdb_xml_element *elements;
@ -52,11 +79,9 @@ struct scope_level
optional and repeatable checking). */
unsigned int seen;
/* Body text accumulation. */
/* Body text accumulation. This is an owning pointer. */
struct obstack *body;
};
typedef struct scope_level scope_level_s;
DEF_VEC_O(scope_level_s);
/* The parser itself, and our additional state. */
struct gdb_xml_parser
@ -71,7 +96,8 @@ struct gdb_xml_parser
const char *name; /* Name of this parser. */
void *user_data; /* The user's callback data, for handlers. */
VEC(scope_level_s) *scopes; /* Scoping stack. */
/* Scoping stack. */
std::vector<scope_level> scopes;
struct gdb_exception error; /* A thrown error, if any. */
int last_line; /* The line of the thrown error, or 0. */
@ -89,18 +115,19 @@ static void
gdb_xml_body_text (void *data, const XML_Char *text, int length)
{
struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;
struct scope_level *scope = VEC_last (scope_level_s, parser->scopes);
if (parser->error.reason < 0)
return;
if (scope->body == NULL)
scope_level &scope = parser->scopes.back ();
if (scope.body == NULL)
{
scope->body = XCNEW (struct obstack);
obstack_init (scope->body);
scope.body = XCNEW (struct obstack);
obstack_init (scope.body);
}
obstack_grow (scope->body, text, length);
obstack_grow (scope.body, text, length);
}
/* Issue a debugging message from one of PARSER's handlers. */
@ -179,8 +206,6 @@ gdb_xml_start_element (void *data, const XML_Char *name,
const XML_Char **attrs)
{
struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;
struct scope_level *scope;
struct scope_level new_scope;
const struct gdb_xml_element *element;
const struct gdb_xml_attribute *attribute;
VEC(gdb_xml_value_s) *attributes = NULL;
@ -189,11 +214,16 @@ gdb_xml_start_element (void *data, const XML_Char *name,
/* 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. */
VEC_reserve (scope_level_s, parser->scopes, 1);
scope = VEC_last (scope_level_s, parser->scopes);
memset (&new_scope, 0, sizeof (new_scope));
VEC_quick_push (scope_level_s, parser->scopes, &new_scope);
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. */
parser->scopes.emplace_back ();
/* Get a reference to the current scope. */
scope_level &scope = parser->scopes[parser->scopes.size () - 2];
gdb_xml_debug (parser, _("Entering element <%s>"), name);
@ -201,7 +231,7 @@ gdb_xml_start_element (void *data, const XML_Char *name,
children. Record that we've seen it. */
seen = 1;
for (element = scope->elements; element && element->name;
for (element = scope.elements; element && element->name;
element++, seen <<= 1)
if (strcmp (element->name, name) == 0)
break;
@ -213,12 +243,10 @@ gdb_xml_start_element (void *data, const XML_Char *name,
list into the new scope even if there was no match. */
if (parser->is_xinclude)
{
struct scope_level *unknown_scope;
XML_DefaultCurrent (parser->expat_parser);
unknown_scope = VEC_last (scope_level_s, parser->scopes);
unknown_scope->elements = scope->elements;
scope_level &unknown_scope = parser->scopes.back ();
unknown_scope.elements = scope.elements;
return;
}
@ -226,10 +254,10 @@ gdb_xml_start_element (void *data, const XML_Char *name,
return;
}
if (!(element->flags & GDB_XML_EF_REPEATABLE) && (seen & scope->seen))
if (!(element->flags & GDB_XML_EF_REPEATABLE) && (seen & scope.seen))
gdb_xml_error (parser, _("Element <%s> only expected once"), name);
scope->seen |= seen;
scope.seen |= seen;
back_to = make_cleanup (gdb_xml_values_cleanup, &attributes);
@ -302,10 +330,13 @@ gdb_xml_start_element (void *data, const XML_Char *name,
if (element->start_handler)
element->start_handler (parser, element, parser->user_data, attributes);
/* Fill in a new scope level. */
scope = VEC_last (scope_level_s, parser->scopes);
scope->element = element;
scope->elements = element->children;
/* 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 = parser->scopes.back ();
new_scope.element = element;
new_scope.elements = element->children;
do_cleanups (back_to);
}
@ -342,7 +373,7 @@ gdb_xml_start_element_wrapper (void *data, const XML_Char *name,
static void
gdb_xml_end_element (gdb_xml_parser *parser, const XML_Char *name)
{
struct scope_level *scope = VEC_last (scope_level_s, parser->scopes);
struct scope_level *scope = &parser->scopes.back ();
const struct gdb_xml_element *element;
unsigned int seen;
@ -387,12 +418,7 @@ gdb_xml_end_element (gdb_xml_parser *parser, const XML_Char *name)
XML_DefaultCurrent (parser->expat_parser);
/* Pop the scope level. */
if (scope->body)
{
obstack_free (scope->body, NULL);
xfree (scope->body);
}
VEC_pop (scope_level_s, parser->scopes);
parser->scopes.pop_back ();
}
/* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
@ -424,19 +450,7 @@ gdb_xml_end_element_wrapper (void *data, const XML_Char *name)
gdb_xml_parser::~gdb_xml_parser ()
{
struct scope_level *scope;
int ix;
XML_ParserFree (this->expat_parser);
/* Clean up the scopes. */
for (ix = 0; VEC_iterate (scope_level_s, this->scopes, ix, scope); ix++)
if (scope->body)
{
obstack_free (scope->body, NULL);
xfree (scope->body);
}
VEC_free (scope_level_s, this->scopes);
}
/* Initialize a parser. */
@ -446,7 +460,6 @@ gdb_xml_parser::gdb_xml_parser (const char *name_,
void *user_data_)
: name (name_),
user_data (user_data_),
scopes (NULL),
error (exception_none),
last_line (0),
dtd_name (NULL),
@ -464,10 +477,7 @@ gdb_xml_parser::gdb_xml_parser (const char *name_,
XML_SetCharacterDataHandler (this->expat_parser, gdb_xml_body_text);
/* Initialize the outer scope. */
scope_level start_scope;
memset (&start_scope, 0, sizeof (start_scope));
start_scope.elements = elements;
VEC_safe_push (scope_level_s, this->scopes, &start_scope);
this->scopes.emplace_back (elements);
}
/* External entity handler. The only external entities we support