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

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

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