feat(parser): clean leaks in parseMap, parseArray and rethrow

This commit is contained in:
3lswear
2022-02-19 18:47:05 +03:00
parent 039b7f71a5
commit 281f7f01fe

View File

@@ -31,7 +31,8 @@ namespace config
void TOMLParser::processMap(void) void TOMLParser::processMap(void)
{ {
/* std::cerr << "Processing map" << std::endl; */ /* std::cerr << "Processing map" << std::endl; */
toml_node *map_node; // toml_node *map_node;
std::auto_ptr<toml_node> map_node(new toml_node);
s_token current; s_token current;
try { current = tokenizer.getToken(); } try { current = tokenizer.getToken(); }
@@ -45,7 +46,7 @@ namespace config
if (tokenizer.getToken().type != NEWLINE) if (tokenizer.getToken().type != NEWLINE)
throw ExpectedToken("newline", current.value); throw ExpectedToken("newline", current.value);
// throw std::logic_error("no newline after MAP_DECL"); // throw std::logic_error("no newline after MAP_DECL");
map_node = parseMap().release(); map_node.reset(parseMap());
} }
else else
// throw std::logic_error("unexpected token in processMap"); // throw std::logic_error("unexpected token in processMap");
@@ -57,105 +58,107 @@ namespace config
full_name = split_name(current.value); full_name = split_name(current.value);
put_to_subtable(root.get(), full_name, map_node, toml_node::MAP); put_to_subtable(root, full_name, map_node.release(), toml_node::MAP);;
} }
std::auto_ptr<toml_node> TOMLParser::parseMap(void) toml_node *TOMLParser::parseMap(void)
{ {
/* std::cerr << "Parsing map" << std::endl; */ /* std::cerr << "Parsing map" << std::endl; */
std::auto_ptr<TOMLMap> mapObject(new TOMLMap); // std::auto_ptr<TOMLMap> mapObject(new TOMLMap);
toml_node *node = new toml_node;
TOMLMap *mapObject = new TOMLMap;
bool completed = false; bool completed = false;
while (!completed) try
{ {
if (tokenizer.hasMoreTokens()) while (!completed)
{ {
s_token nextToken; if (tokenizer.hasMoreTokens())
try { nextToken = tokenizer.getToken(); }
catch (Tokenizer::NoMoreTokens &e)
{ {
DBOUT << "got no more tokens" << ENDL; s_token nextToken;
break; try { nextToken = tokenizer.getToken(); }
} catch (Tokenizer::NoMoreTokens &e)
if (nextToken.type == MAPARRAY_DECL) {
{ DBOUT << "got no more tokens" << ENDL;
tokenizer.rollBackToken(); completed = 1;
tokenizer.set_last(NEWLINE); break;
break; }
}
else if (nextToken.type == MAP_DECL) if (nextToken.type == MAPARRAY_DECL)
{ {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
tokenizer.set_last(NEWLINE); tokenizer.set_last(NEWLINE);
break; break;
} }
std::string key = nextToken.value; else if (nextToken.type == MAP_DECL)
/* std::cerr << key << std::endl; */ {
DBOUT << RED << "key is " << key << ENDL; tokenizer.rollBackToken();
if (tokenizer.getToken().type != ASSIGN) tokenizer.set_last(NEWLINE);
throw ExpectedToken("assign", "after " + key); break;
}
std::string key = nextToken.value;
/* std::cerr << key << std::endl; */
if (tokenizer.getToken().type != ASSIGN)
throw ExpectedToken("assign", "after " + key);
// throw std::logic_error("EXPECTED assign! 1"); // throw std::logic_error("EXPECTED assign! 1");
nextToken = tokenizer.getToken(); nextToken = tokenizer.getToken();
switch (nextToken.type) switch (nextToken.type)
{ {
case STRING: case STRING:
{ {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
(*mapObject)[key] = parseString(); (*mapObject)[key] = parseString();
break; break;
} }
case OPEN_BRACKET: case OPEN_BRACKET:
{ {
(*mapObject)[key] = parseArray(); (*mapObject)[key] = parseArray();
break; break;
} }
case NUMBER: case NUMBER:
{ {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
(*mapObject)[key] = parseNumber(); (*mapObject)[key] = parseNumber();
break; break;
} }
case BOOL: case BOOL:
{ {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
(*mapObject)[key] = parseBool(); (*mapObject)[key] = parseBool();
break; break;
} }
case MAPARRAY_DECL: case MAPARRAY_DECL:
{ {
/* std::cerr << "reached MAPARRAY_DECL in parseMap" << std::endl; */ /* std::cerr << "reached MAPARRAY_DECL in parseMap" << std::endl; */
completed = true; completed = true;
break; break;
} }
default: default:
{
throw UnexpectedToken(nextToken.value, key); throw UnexpectedToken(nextToken.value, key);
/* throw std::logic_error("jopa in parseMap"); */ }
// std::cerr << "Unknown token, marking as complete" << std::endl; if (tokenizer.hasMoreTokens())
completed = true; nextToken = tokenizer.getToken();
break; else
} break;
} if (nextToken.type != NEWLINE)
if (tokenizer.hasMoreTokens()) {
nextToken = tokenizer.getToken(); // throw std::logic_error("EXPECTED newline");
else throw ExpectedToken("newline", "parsing Hash Table");
break; }
if (nextToken.type != NEWLINE)
{
// throw std::logic_error("EXPECTED newline");
throw ExpectedToken("newline", "parsing Hash Table");
} }
} }
// else
// {
// throw std::logic_error("parseMap: no more tokens");
// }
} }
catch (std::domain_error &e)
{
DBOUT << "CAUGHT in parse MAP!!!" <<ENDL;
// toml_node *node = new toml_node; node->setObject(mapObject);
std::auto_ptr<toml_node> node(new toml_node); config::clean_generic(node);
node->setObject(mapObject.release()); throw;
}
node->setObject(mapObject);
return (node); return (node);
} }
@@ -164,7 +167,7 @@ namespace config
/* std::cerr << "Parsing MapArray" << std::endl; */ /* std::cerr << "Parsing MapArray" << std::endl; */
// toml_node *map_node; // toml_node *map_node;
std::auto_ptr<toml_node> map_node; std::auto_ptr<toml_node> map_node(new toml_node);
s_token current; s_token current;
try { current = tokenizer.getToken(); } try { current = tokenizer.getToken(); }
@@ -177,10 +180,20 @@ namespace config
{ {
if (tokenizer.getToken().type != NEWLINE) if (tokenizer.getToken().type != NEWLINE)
throw std::logic_error("no newline after map_array declaration"); throw std::logic_error("no newline after map_array declaration");
map_node = parseMap(); try
{
map_node.reset(parseMap());
}
catch (std::exception &e)
{
// DBOUT << "map_node is " << map_node->getMap() << ENDL;
// for (TOMLMap::iterator it = map->begin();)
throw;
}
} }
else else
throw std::logic_error("unexpected token in processMapArray"); throw std::logic_error("unexpected token in process Map Array");
/* std::cout << current.value << std::endl; */ /* std::cout << current.value << std::endl; */
@@ -188,20 +201,20 @@ namespace config
full_name = split_name(current.value); full_name = split_name(current.value);
put_to_subtable(root.get(), full_name, map_node.release(), toml_node::MAPARRAY); put_to_subtable(root, full_name, map_node.release(), toml_node::MAPARRAY);
} }
toml_node *TOMLParser::parseString(void) toml_node *TOMLParser::parseString(void)
{ {
std::string *sValue; std::string *string;
/* std::cerr << "Parsing string" << std::endl; */ /* std::cerr << "Parsing string" << std::endl; */
s_token token = tokenizer.getToken(); s_token token = tokenizer.getToken();
sValue = new std::string(token.value); string = new std::string(token.value);
toml_node *node = new toml_node; toml_node *node = new toml_node;
node->setString(sValue); node->setString(string);
return (node); return (node);
} }
@@ -223,26 +236,29 @@ namespace config
toml_node *TOMLParser::parseArray(void) toml_node *TOMLParser::parseArray(void)
{ {
/* std::cerr << "Parsing array" << std::endl; */ /* std::cerr << "Parsing array" << std::endl; */
toml_node *node;
toml_node *result = new toml_node; toml_node *result = new toml_node;
TOMLArray *array = new TOMLArray; TOMLArray *array = new TOMLArray;
toml_node *node;
bool completed = false; bool completed = false;
s_token current; s_token current;
try
{
while (!completed) while (!completed)
{ {
if (!tokenizer.hasMoreTokens()) // if (!tokenizer.hasMoreTokens())
throw std::logic_error("No more tokens"); // throw std::logic_error("No more tokens");
else // else
{ // {
current = tokenizer.getToken(); current = tokenizer.getToken();
switch (current.type) switch (current.type)
{ {
case OPEN_BRACKET: // case OPEN_BRACKET:
{ // {
node = parseArray(); // node = parseArray();
break; // break;
} // }
case STRING: case STRING:
{ {
tokenizer.rollBackToken(); tokenizer.rollBackToken();
@@ -283,7 +299,15 @@ namespace config
else else
throw UnexpectedToken(current.value, ", when expected COMMA, or CLOSE_BRACKET"); throw UnexpectedToken(current.value, ", when expected COMMA, or CLOSE_BRACKET");
// throw std::invalid_argument("Unexpected token in array!"); // throw std::invalid_argument("Unexpected token in array!");
} // }
}
}
catch (std::domain_error &e)
{
DBOUT << "CAUGHT in parse Array" << ENDL;
result->setArr(array);
config::clean_generic(result);
throw;
} }
result->setArr(array); result->setArr(array);
return (result); return (result);
@@ -317,12 +341,10 @@ namespace config
} }
/* parse tha root ! */ /* parse tha root ! */
TOMLMap *TOMLParser::parse(void) void TOMLParser::parse(void)
{ {
/* std::cerr << "Parsing ROOT" << std::endl; */ /* std::cerr << "Parsing ROOT" << std::endl; */
// root = new TOMLMap; root = new TOMLMap;
// std::auto_ptr<TOMLMap> root(new TOMLMap);
root.reset(new TOMLMap);
bool completed = false; bool completed = false;
while (!completed) while (!completed)
{ {
@@ -337,7 +359,6 @@ namespace config
} }
if (current.type == MAPARRAY_DECL) if (current.type == MAPARRAY_DECL)
{ {
/* processMapArray(); */
tokenizer.set_last(NEWLINE); tokenizer.set_last(NEWLINE);
tokenizer.rollBackToken(); tokenizer.rollBackToken();
processMapArray(); processMapArray();
@@ -347,9 +368,6 @@ namespace config
/* std::cerr << "MAP_DECL value: " << current.value << std::endl; */ /* std::cerr << "MAP_DECL value: " << current.value << std::endl; */
tokenizer.set_last(NEWLINE); tokenizer.set_last(NEWLINE);
tokenizer.rollBackToken(); tokenizer.rollBackToken();
/* if (tokenizer.getToken().type != NEWLINE) */
/* throw std::logic_error("no newline after MAP_DECL"); */
/* (*mapObject)[nextToken.value] = parseMap(); */
processMap(); processMap();
continue; continue;
} }
@@ -387,7 +405,6 @@ namespace config
} }
default: default:
{ {
/* throw std::logic_error("jopa in parseMap"); */
std::cerr << "Unknown token, marking as complete" << std::endl; std::cerr << "Unknown token, marking as complete" << std::endl;
completed = true; completed = true;
break; break;
@@ -409,7 +426,6 @@ namespace config
break; break;
} }
} }
return (root.release());
} }
std::vector<std::string> TOMLParser::split_name(std::string name) std::vector<std::string> TOMLParser::split_name(std::string name)