Commit 58bb8f34 authored by Francis Dupont's avatar Francis Dupont Committed by Tomek Mrugalski

[5014_phase2] Fixed lexer cleanup on any exit (note parser uses try-catch)

parent b4264859
......@@ -882,6 +882,14 @@ null {
driver.locs_.pop_back();
driver.file_ = driver.files_.back();
driver.files_.pop_back();
if (driver.sfile_) {
fclose(driver.sfile_);
driver.sfile_ = 0;
}
if (!driver.sfiles_.empty()) {
driver.sfile_ = driver.sfiles_.back();
driver.sfiles_.pop_back();
}
parser6__delete_buffer(YY_CURRENT_BUFFER);
parser6__switch_to_buffer(driver.states_.back());
driver.states_.pop_back();
......@@ -896,11 +904,11 @@ using namespace isc::dhcp;
void
Parser6Context::scanStringBegin(const std::string& str, ParserType parser_type)
{
static_cast<void>(parser6_lex_destroy());
start_token_flag = true;
start_token_value = parser_type;
file_ = "<string>";
sfile_ = 0;
loc_.initialize(&file_);
yy_flex_debug = trace_scanning_;
YY_BUFFER_STATE buffer;
......@@ -911,22 +919,16 @@ Parser6Context::scanStringBegin(const std::string& str, ParserType parser_type)
}
}
void
Parser6Context::scanStringEnd()
{
yy_delete_buffer(YY_CURRENT_BUFFER);
}
void
Parser6Context::scanFileBegin(FILE * f,
const std::string& filename,
ParserType parser_type)
{
static_cast<void>(parser6_lex_destroy());
start_token_flag = true;
start_token_value = parser_type;
file_ = filename;
sfile_ = f;
loc_.initialize(&file_);
yy_flex_debug = trace_scanning_;
YY_BUFFER_STATE buffer;
......@@ -940,9 +942,24 @@ Parser6Context::scanFileBegin(FILE * f,
}
void
Parser6Context::scanFileEnd(FILE * f) {
fclose(f);
yy_delete_buffer(YY_CURRENT_BUFFER);
Parser6Context::scanEnd() {
if (sfile_)
fclose(sfile_);
sfile_ = 0;
static_cast<void>(parser6_lex_destroy());
// Close files
while (!sfiles_.empty()) {
FILE* f = sfiles_.back();
if (f) {
fclose(f);
}
sfiles_.pop_back();
}
// Delete states
while (!states_.empty()) {
parser6__delete_buffer(states_.back());
states_.pop_back();
}
}
void
......@@ -955,6 +972,10 @@ Parser6Context::includeFile(const std::string& filename) {
if (!f) {
fatal("Can't open include file " + filename);
}
if (sfile_) {
sfiles_.push_back(sfile_);
}
sfile_ = f;
states_.push_back(YY_CURRENT_BUFFER);
YY_BUFFER_STATE buffer;
buffer = parser6__create_buffer(f, 65536 /*buffer size*/);
......
......@@ -259,9 +259,9 @@ global_objects: global_object
// This represents a single top level entry, e.g. Dhcp6 or DhcpDdns.
global_object: dhcp6_object
| logging_object
| dhcp4_json_object
| dhcpddns_json_object
| unknown_map_entry
| dhcp4_json_object
| dhcpddns_json_object
| unknown_map_entry
;
dhcp6_object: DHCP6 {
......
......@@ -28,21 +28,7 @@ isc::data::ConstElementPtr
Parser6Context::parseString(const std::string& str, ParserType parser_type)
{
scanStringBegin(str, parser_type);
isc::dhcp::Dhcp6Parser parser(*this);
// Uncomment this to get detailed parser logs.
// trace_parsing_ = true;
parser.set_debug_level(trace_parsing_);
int res = parser.parse();
if (res != 0) {
// @todo: handle exception here
}
scanStringEnd();
if (stack_.size() == 1) {
return (stack_[0]);
} else {
isc_throw(Dhcp6ParseError, "Expected exactly one terminal Element expected, found "
<< stack_.size());
}
return (parseCommon());
}
isc::data::ConstElementPtr
......@@ -52,16 +38,26 @@ Parser6Context::parseFile(const std::string& filename, ParserType parser_type) {
isc_throw(Dhcp6ParseError, "Unable to open file " << filename);
}
scanFileBegin(f, filename, parser_type);
return (parseCommon());
}
isc::data::ConstElementPtr
Parser6Context::parseCommon() {
isc::dhcp::Dhcp6Parser parser(*this);
// Uncomment this to get detailed parser logs.
// trace_parsing_ = true;
parser.set_debug_level(trace_parsing_);
int res = parser.parse();
if (res != 0) {
// @todo: handle exception here
try {
int res = parser.parse();
if (res != 0) {
isc_throw(Dhcp6ParseError, "Parser abort");
}
scanEnd();
}
catch (...) {
scanEnd();
throw;
}
scanFileEnd(f);
if (stack_.size() == 1) {
return (stack_[0]);
} else {
......
......@@ -53,14 +53,11 @@ public:
/// @brief Method called before scanning starts on a string.
void scanStringBegin(const std::string& str, ParserType type);
/// @brief Method called after the last tokens are scanned from a string.
void scanStringEnd();
/// @brief Method called before scanning starts on a file.
void scanFileBegin(FILE * f, const std::string& filename, ParserType type);
/// @brief Method called after the last tokens are scanned from a file.
void scanFileEnd(FILE * f);
/// @brief Method called after the last tokens are scanned.
void scanEnd();
/// @brief Divert input to an include file.
void includeFile(const std::string& filename);
......@@ -144,9 +141,15 @@ public:
/// @brief Location stack
std::vector<isc::dhcp::location> locs_;
/// @brief State stack
/// @brief Lexer state stack
std::vector<struct yy_buffer_state*> states_;;
/// @brief sFile (aka FILE)
FILE* sfile_;
/// @brief sFile (aka FILE) stack
std::vector<FILE*> sfiles_;
/// @brief Current syntactic context
ParserContext ctx_;
......@@ -169,6 +172,9 @@ public:
/// @brief Syntactic context stack
std::vector<ParserContext> cstack_;
/// @brief Common part of parseXXX
isc::data::ConstElementPtr parseCommon();
};
}; // end of isc::eval namespace
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment