-
Notifications
You must be signed in to change notification settings - Fork 262
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
xml_parsert: construct with message handler
This both avoids an object of static lifetime as well as it fixes the (transitive) use of the deprecated messaget() constructor. Avoid global objects in the lexer (as side-effect making it reentrant) as initialisation is required. The parser continues to have global state, so guard against reentrant use.
- Loading branch information
1 parent
7232457
commit 9f01d3e
Showing
4 changed files
with
55 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,20 @@ Author: Daniel Kroening, [email protected] | |
|
||
#include <fstream> | ||
|
||
xml_parsert xml_parser; | ||
int xml_parsert::instance_count = 0; | ||
|
||
int yyxmllex_init_extra(xml_parsert *, void **); | ||
int yyxmllex_destroy(void *); | ||
int yyxmlparse(xml_parsert &, void *); | ||
|
||
bool xml_parsert::parse() | ||
{ | ||
void *scanner; | ||
yyxmllex_init_extra(this, &scanner); | ||
bool parse_fail = yyxmlparse(*this, scanner) != 0; | ||
yyxmllex_destroy(scanner); | ||
return parse_fail; | ||
} | ||
|
||
// 'do it all' function | ||
bool parse_xml( | ||
|
@@ -19,19 +32,16 @@ bool parse_xml( | |
message_handlert &message_handler, | ||
xmlt &dest) | ||
{ | ||
xml_parser.clear(); | ||
xml_parsert xml_parser{message_handler}; | ||
|
||
xml_parser.set_file(filename); | ||
xml_parser.in=∈ | ||
xml_parser.log.set_message_handler(message_handler); | ||
|
||
bool result=yyxmlparse()!=0; | ||
bool result = xml_parser.parse(); | ||
|
||
// save result | ||
xml_parser.parse_tree.element.swap(dest); | ||
|
||
// save some memory | ||
xml_parser.clear(); | ||
|
||
return result; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,11 +14,25 @@ Author: Daniel Kroening, [email protected] | |
|
||
#include "xml_parse_tree.h" | ||
|
||
int yyxmlparse(); | ||
|
||
class xml_parsert:public parsert | ||
{ | ||
public: | ||
explicit xml_parsert(message_handlert &message_handler) | ||
: parsert(message_handler) | ||
{ | ||
// Simplistic check that we don't attempt to do reentrant parsing as the | ||
// Bison-generated parser has global state. | ||
PRECONDITION(++instance_count == 1); | ||
stack.push_back(&parse_tree.element); | ||
} | ||
|
||
xml_parsert(const xml_parsert &) = delete; | ||
|
||
~xml_parsert() override | ||
{ | ||
--instance_count; | ||
} | ||
|
||
xml_parse_treet parse_tree; | ||
|
||
std::list<xmlt *> stack; | ||
|
@@ -28,29 +42,30 @@ class xml_parsert:public parsert | |
return *stack.back(); | ||
} | ||
|
||
virtual bool parse() | ||
{ | ||
return yyxmlparse()!=0; | ||
} | ||
bool parse() override; | ||
|
||
void new_level() | ||
{ | ||
current().elements.push_back(xmlt()); | ||
stack.push_back(¤t().elements.back()); | ||
} | ||
|
||
virtual void clear() | ||
/// Clears the parser state. May be removed in future as there should not be a | ||
/// need to re-use an existing parser object. | ||
void clear() override | ||
{ | ||
parse_tree.clear(); | ||
// set up stack | ||
stack.clear(); | ||
stack.push_back(&parse_tree.element); | ||
parsert::clear(); | ||
} | ||
}; | ||
|
||
extern xml_parsert xml_parser; | ||
protected: | ||
static int instance_count; | ||
}; | ||
|
||
int yyxmlerror(const std::string &error); | ||
int yyxmlerror(xml_parsert &, void *, const std::string &); | ||
|
||
// 'do it all' functions | ||
bool parse_xml( | ||
|