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:
parent
010151c914
commit
a7fc9b6193
|
@ -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>
|
2017-04-18 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* xml-support.c (gdb_xml_parser): Add ctor/dtor. Make is_xinclude
|
* xml-support.c (gdb_xml_parser): Add ctor/dtor. Make is_xinclude
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "xml-support.h"
|
#include "xml-support.h"
|
||||||
#include "filestuff.h"
|
#include "filestuff.h"
|
||||||
#include "safe-ctype.h"
|
#include "safe-ctype.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
/* Debugging flag. */
|
/* Debugging flag. */
|
||||||
static int debug_xml;
|
static int debug_xml;
|
||||||
|
@ -42,6 +43,32 @@ static int debug_xml;
|
||||||
nesting. */
|
nesting. */
|
||||||
struct scope_level
|
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. */
|
/* Elements we allow at this level. */
|
||||||
const struct gdb_xml_element *elements;
|
const struct gdb_xml_element *elements;
|
||||||
|
|
||||||
|
@ -52,11 +79,9 @@ struct scope_level
|
||||||
optional and repeatable checking). */
|
optional and repeatable checking). */
|
||||||
unsigned int seen;
|
unsigned int seen;
|
||||||
|
|
||||||
/* Body text accumulation. */
|
/* Body text accumulation. This is an owning pointer. */
|
||||||
struct obstack *body;
|
struct obstack *body;
|
||||||
};
|
};
|
||||||
typedef struct scope_level scope_level_s;
|
|
||||||
DEF_VEC_O(scope_level_s);
|
|
||||||
|
|
||||||
/* The parser itself, and our additional state. */
|
/* The parser itself, and our additional state. */
|
||||||
struct gdb_xml_parser
|
struct gdb_xml_parser
|
||||||
|
@ -71,7 +96,8 @@ struct gdb_xml_parser
|
||||||
const char *name; /* Name of this parser. */
|
const char *name; /* Name of this parser. */
|
||||||
void *user_data; /* The user's callback data, for handlers. */
|
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. */
|
struct gdb_exception error; /* A thrown error, if any. */
|
||||||
int last_line; /* The line of the thrown error, or 0. */
|
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)
|
gdb_xml_body_text (void *data, const XML_Char *text, int length)
|
||||||
{
|
{
|
||||||
struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;
|
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)
|
if (parser->error.reason < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (scope->body == NULL)
|
scope_level &scope = parser->scopes.back ();
|
||||||
|
|
||||||
|
if (scope.body == NULL)
|
||||||
{
|
{
|
||||||
scope->body = XCNEW (struct obstack);
|
scope.body = XCNEW (struct obstack);
|
||||||
obstack_init (scope->body);
|
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. */
|
/* 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)
|
const XML_Char **attrs)
|
||||||
{
|
{
|
||||||
struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;
|
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_element *element;
|
||||||
const struct gdb_xml_attribute *attribute;
|
const struct gdb_xml_attribute *attribute;
|
||||||
VEC(gdb_xml_value_s) *attributes = NULL;
|
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
|
/* Push an error scope. If we return or throw an exception before
|
||||||
filling this in, it will tell us to ignore children of this
|
filling this in, it will tell us to ignore children of this
|
||||||
element. */
|
element. Note we don't take a reference to the element yet
|
||||||
VEC_reserve (scope_level_s, parser->scopes, 1);
|
because further below we'll process the element which may recurse
|
||||||
scope = VEC_last (scope_level_s, parser->scopes);
|
back here and push more elements to the vector. When the
|
||||||
memset (&new_scope, 0, sizeof (new_scope));
|
recursion unrolls all such elements will have been popped back
|
||||||
VEC_quick_push (scope_level_s, parser->scopes, &new_scope);
|
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);
|
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. */
|
children. Record that we've seen it. */
|
||||||
|
|
||||||
seen = 1;
|
seen = 1;
|
||||||
for (element = scope->elements; element && element->name;
|
for (element = scope.elements; element && element->name;
|
||||||
element++, seen <<= 1)
|
element++, seen <<= 1)
|
||||||
if (strcmp (element->name, name) == 0)
|
if (strcmp (element->name, name) == 0)
|
||||||
break;
|
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. */
|
list into the new scope even if there was no match. */
|
||||||
if (parser->is_xinclude)
|
if (parser->is_xinclude)
|
||||||
{
|
{
|
||||||
struct scope_level *unknown_scope;
|
|
||||||
|
|
||||||
XML_DefaultCurrent (parser->expat_parser);
|
XML_DefaultCurrent (parser->expat_parser);
|
||||||
|
|
||||||
unknown_scope = VEC_last (scope_level_s, parser->scopes);
|
scope_level &unknown_scope = parser->scopes.back ();
|
||||||
unknown_scope->elements = scope->elements;
|
unknown_scope.elements = scope.elements;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,10 +254,10 @@ gdb_xml_start_element (void *data, const XML_Char *name,
|
||||||
return;
|
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);
|
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);
|
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)
|
if (element->start_handler)
|
||||||
element->start_handler (parser, element, parser->user_data, attributes);
|
element->start_handler (parser, element, parser->user_data, attributes);
|
||||||
|
|
||||||
/* Fill in a new scope level. */
|
/* Fill in a new scope level. Note that we must delay getting a
|
||||||
scope = VEC_last (scope_level_s, parser->scopes);
|
back reference till here because above we might have recursed,
|
||||||
scope->element = element;
|
which may have reallocated the vector which invalidates
|
||||||
scope->elements = element->children;
|
iterators/pointers/references. */
|
||||||
|
scope_level &new_scope = parser->scopes.back ();
|
||||||
|
new_scope.element = element;
|
||||||
|
new_scope.elements = element->children;
|
||||||
|
|
||||||
do_cleanups (back_to);
|
do_cleanups (back_to);
|
||||||
}
|
}
|
||||||
|
@ -342,7 +373,7 @@ gdb_xml_start_element_wrapper (void *data, const XML_Char *name,
|
||||||
static void
|
static void
|
||||||
gdb_xml_end_element (gdb_xml_parser *parser, const XML_Char *name)
|
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;
|
const struct gdb_xml_element *element;
|
||||||
unsigned int seen;
|
unsigned int seen;
|
||||||
|
|
||||||
|
@ -387,12 +418,7 @@ gdb_xml_end_element (gdb_xml_parser *parser, const XML_Char *name)
|
||||||
XML_DefaultCurrent (parser->expat_parser);
|
XML_DefaultCurrent (parser->expat_parser);
|
||||||
|
|
||||||
/* Pop the scope level. */
|
/* Pop the scope level. */
|
||||||
if (scope->body)
|
parser->scopes.pop_back ();
|
||||||
{
|
|
||||||
obstack_free (scope->body, NULL);
|
|
||||||
xfree (scope->body);
|
|
||||||
}
|
|
||||||
VEC_pop (scope_level_s, parser->scopes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
|
/* 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 ()
|
gdb_xml_parser::~gdb_xml_parser ()
|
||||||
{
|
{
|
||||||
struct scope_level *scope;
|
|
||||||
int ix;
|
|
||||||
|
|
||||||
XML_ParserFree (this->expat_parser);
|
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. */
|
/* Initialize a parser. */
|
||||||
|
@ -446,7 +460,6 @@ gdb_xml_parser::gdb_xml_parser (const char *name_,
|
||||||
void *user_data_)
|
void *user_data_)
|
||||||
: name (name_),
|
: name (name_),
|
||||||
user_data (user_data_),
|
user_data (user_data_),
|
||||||
scopes (NULL),
|
|
||||||
error (exception_none),
|
error (exception_none),
|
||||||
last_line (0),
|
last_line (0),
|
||||||
dtd_name (NULL),
|
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);
|
XML_SetCharacterDataHandler (this->expat_parser, gdb_xml_body_text);
|
||||||
|
|
||||||
/* Initialize the outer scope. */
|
/* Initialize the outer scope. */
|
||||||
scope_level start_scope;
|
this->scopes.emplace_back (elements);
|
||||||
memset (&start_scope, 0, sizeof (start_scope));
|
|
||||||
start_scope.elements = elements;
|
|
||||||
VEC_safe_push (scope_level_s, this->scopes, &start_scope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* External entity handler. The only external entities we support
|
/* External entity handler. The only external entities we support
|
||||||
|
|
Loading…
Reference in New Issue