From 29ae04e40d80a6a840daf8926bcd7fe94de319f7 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sat, 12 Feb 2022 00:30:50 +0300 Subject: [PATCH 01/12] feat(parser): get config file from arg --- Makefile | 2 +- src/Server/Server.cpp | 4 ++-- src/Server/Server.hpp | 2 +- src/config/TOMLParser.cpp | 2 +- src/config/TOMLParser.hpp | 2 +- src/config/Tokenizer.cpp | 5 +++-- src/config/Tokenizer.hpp | 2 +- src/config/parse.cpp | 4 ++-- src/config/parse.hpp | 2 +- src/main.cpp | 2 +- 10 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 4864302..093fc02 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,6 @@ re: $(MAKE) all run: $(NAME) - ASAN_OPTIONS=detect_leaks=0 ./$(NAME) + ASAN_OPTIONS=detect_leaks=0 ./$(NAME) $(filter-out $@,$(MAKECMDGOALS)) .PHONY: all clean fclean re diff --git a/src/Server/Server.cpp b/src/Server/Server.cpp index 5c608a7..745f012 100644 --- a/src/Server/Server.cpp +++ b/src/Server/Server.cpp @@ -34,9 +34,9 @@ void Server::print_epoll_events(unsigned int events) //----------------------------------------------Send-------------------------------------------------------------------------------------------- //----------------------------------------------Configuration----------------------------------------------------------------------------------- -void Server::readConfig(void) +void Server::readConfig(char *filename) { - TOMLMap *root = parse(); + TOMLMap *root = parse(filename); /* TOMLMap *map; */ diff --git a/src/Server/Server.hpp b/src/Server/Server.hpp index f0495a9..32acb5a 100644 --- a/src/Server/Server.hpp +++ b/src/Server/Server.hpp @@ -56,7 +56,7 @@ class Server Server(); Server(std::string path); - void readConfig(void); + void readConfig(char *filename); void setupConfig(void); void start(void); void end(void); diff --git a/src/config/TOMLParser.cpp b/src/config/TOMLParser.cpp index bb2316c..42630fe 100644 --- a/src/config/TOMLParser.cpp +++ b/src/config/TOMLParser.cpp @@ -25,7 +25,7 @@ namespace config { - TOMLParser::TOMLParser(const std::string filename) : tokenizer(filename) + TOMLParser::TOMLParser(char *filename) : tokenizer(filename) {}; void TOMLParser::processMap(void) diff --git a/src/config/TOMLParser.hpp b/src/config/TOMLParser.hpp index 114fe4f..98833fb 100644 --- a/src/config/TOMLParser.hpp +++ b/src/config/TOMLParser.hpp @@ -23,7 +23,7 @@ namespace config toml_node *map_node, toml_node::e_type type); public: - TOMLParser(const std::string filename); + TOMLParser(char *filename); TOMLMap *parse(void); toml_node *parseMap(void); diff --git a/src/config/Tokenizer.cpp b/src/config/Tokenizer.cpp index e46d931..c639425 100644 --- a/src/config/Tokenizer.cpp +++ b/src/config/Tokenizer.cpp @@ -38,12 +38,13 @@ namespace config else return (false); } - Tokenizer::Tokenizer(std::string filename) + Tokenizer::Tokenizer(char *filename) { - file.open(filename.c_str(), std::ios::in); + file.open(filename, std::ios::in); if (!file.good()) { std::cerr << "file didn't open" << std::endl; + throw std::logic_error("file didnt open"); } } bool Tokenizer::firstToken() diff --git a/src/config/Tokenizer.hpp b/src/config/Tokenizer.hpp index eec6321..08e7114 100644 --- a/src/config/Tokenizer.hpp +++ b/src/config/Tokenizer.hpp @@ -49,7 +49,7 @@ namespace config e_token last_token; public: - Tokenizer(std::string filename); + Tokenizer(char *filename); char getWithoutWhiteSpace(); struct s_token getToken(); bool hasMoreTokens(); diff --git a/src/config/parse.cpp b/src/config/parse.cpp index 7f9adae..ef86d36 100644 --- a/src/config/parse.cpp +++ b/src/config/parse.cpp @@ -38,9 +38,9 @@ namespace config } } -TOMLMap *parse(void) +TOMLMap *parse(char *filename) { - std::string filename = "config/tester.toml"; + // std::string fiцename = "config/simple.toml"; config::TOMLParser parser(filename); TOMLMap *root = parser.parse(); /* config::display(root); */ diff --git a/src/config/parse.hpp b/src/config/parse.hpp index 72c0067..5b0e1c2 100644 --- a/src/config/parse.hpp +++ b/src/config/parse.hpp @@ -7,7 +7,7 @@ #include "TOMLNode.hpp" #include "TOMLParser.hpp" -TOMLMap *parse(void); +TOMLMap *parse(char *filename); void display(TOMLMap *config); #endif diff --git a/src/main.cpp b/src/main.cpp index 84f3351..be96849 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,7 @@ int main(int argc, char **argv) Server server; - server.readConfig(); + server.readConfig(argv[1]); server.setupConfig(); server.start(); server.end(); From 783b4061c0f473a3124d08d92e02785d863ce976 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sat, 12 Feb 2022 01:43:38 +0300 Subject: [PATCH 02/12] feat: newline stuff --- src/config/Tokenizer.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/config/Tokenizer.cpp b/src/config/Tokenizer.cpp index c639425..0ff9bdb 100644 --- a/src/config/Tokenizer.cpp +++ b/src/config/Tokenizer.cpp @@ -131,7 +131,31 @@ namespace config else if (c == '=') token.type = ASSIGN; else if (c == '\n') + { token.type = NEWLINE; + + std::streampos prev_pos; + file.get(c); + if (c != '\n') + { + file.seekg(-1, std::ios_base::cur); + } + else if (file.eof()) + { + file.clear(); + DBOUT << "cleared" < Date: Sat, 12 Feb 2022 02:13:00 +0300 Subject: [PATCH 03/12] feat: skip newlines --- src/config/Tokenizer.cpp | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/config/Tokenizer.cpp b/src/config/Tokenizer.cpp index 0ff9bdb..903cfc2 100644 --- a/src/config/Tokenizer.cpp +++ b/src/config/Tokenizer.cpp @@ -134,26 +134,16 @@ namespace config { token.type = NEWLINE; - std::streampos prev_pos; - file.get(c); - if (c != '\n') - { - file.seekg(-1, std::ios_base::cur); - } - else if (file.eof()) + do + file.get(c); + while (c == '\n' && !file.eof()); + if (file.eof()) { file.clear(); DBOUT << "cleared" < Date: Sat, 12 Feb 2022 17:53:10 +0300 Subject: [PATCH 04/12] feat: add comment handling --- src/config/Tokenizer.cpp | 32 ++++++++++++++++++++++++++++++-- src/config/Tokenizer.hpp | 4 +++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/config/Tokenizer.cpp b/src/config/Tokenizer.cpp index 903cfc2..ed9455b 100644 --- a/src/config/Tokenizer.cpp +++ b/src/config/Tokenizer.cpp @@ -40,6 +40,7 @@ namespace config } Tokenizer::Tokenizer(char *filename) { + last_token = NO_TOK; file.open(filename, std::ios::in); if (!file.good()) { @@ -50,7 +51,7 @@ namespace config bool Tokenizer::firstToken() { // doesn't account for indent! - if (file.tellg() == 0 || file.tellg() == 1 || (last_token == NEWLINE)) + if (file.tellg() == 0 || file.tellg() == 1 || (last_token == NEWLINE || last_token == NO_TOK)) return (true); else return (false); @@ -198,10 +199,37 @@ namespace config else if (c == ',') token.type = COMMA; else if (c == '#') - token.type = COMMENT; + { + // consume all comments + do + file.get(c); + while (c != '\n' || file.eof()); + DBOUT << "getting comment token" << ENDL; + if (last_token == NO_TOK || last_token == NEWLINE) + { + DBOUT << "getting first token instead of comment" << ENDL; + struct s_token actual; + actual.type = NEWLINE; + while (actual.type == NEWLINE) + actual = getToken(); + DBOUT + << "actual token: '" + << actual.value << "', type: " + << actual.type + << ENDL; + token = actual; + } + else + token.type = NEWLINE; + + } last_token = token.type; + + DBOUT << YELLO << "GOT " << token.value << ", type: " << token.type << ENDL; + return (token); } + char Tokenizer::getWithoutWhiteSpace(void) { char c = ' '; diff --git a/src/config/Tokenizer.hpp b/src/config/Tokenizer.hpp index 08e7114..2de6808 100644 --- a/src/config/Tokenizer.hpp +++ b/src/config/Tokenizer.hpp @@ -27,7 +27,9 @@ namespace config OPEN_BRACKET, CLOSE_BRACKET, MAP_DECL, - MAPARRAY_DECL + MAPARRAY_DECL, + COMMENT, + NO_TOK }; struct s_token From 3a5879eb4d95b0742da7d0d23aa3077997eb9f3d Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sat, 12 Feb 2022 18:54:45 +0300 Subject: [PATCH 05/12] feat(tokenizer): add exceptions --- src/config/TOMLParser.cpp | 8 ++++---- src/config/Tokenizer.cpp | 16 ++++++++++++---- src/config/Tokenizer.hpp | 31 +++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/config/TOMLParser.cpp b/src/config/TOMLParser.cpp index 42630fe..182777e 100644 --- a/src/config/TOMLParser.cpp +++ b/src/config/TOMLParser.cpp @@ -35,7 +35,7 @@ namespace config s_token current; try { current = tokenizer.getToken(); } - catch (std::logic_error e) + catch (std::exception &e) { std::cerr << e.what() << std::endl; return; @@ -71,7 +71,7 @@ namespace config { s_token nextToken; try { nextToken = tokenizer.getToken(); } - catch (std::logic_error e) + catch (std::exception &e) { std::cerr << e.what() << std::endl; break; @@ -158,7 +158,7 @@ namespace config s_token current; try { current = tokenizer.getToken(); } - catch (std::logic_error e) + catch (std::exception &e) { std::cerr << e.what() << std::endl; return; @@ -313,7 +313,7 @@ namespace config { s_token current; try { current = tokenizer.getToken(); } - catch (std::logic_error e) + catch (std::exception &e) { std::cerr << e.what() << std::endl; break; diff --git a/src/config/Tokenizer.cpp b/src/config/Tokenizer.cpp index ed9455b..23c25f3 100644 --- a/src/config/Tokenizer.cpp +++ b/src/config/Tokenizer.cpp @@ -178,6 +178,8 @@ namespace config token.value += c; file.get(c); } + if (token.value != "false") + throw InvalidToken(token.value); file.seekg(-1, std::ios_base::cur); } @@ -189,12 +191,20 @@ namespace config token.value += c; file.get(c); } + if (token.value != "true") + throw InvalidToken(token.value); file.seekg(-1, std::ios_base::cur); } else if (c == 'n') { token.type = NIL; - file.seekg(3, std::ios_base::cur); + while (std::isalpha(c)) + { + token.value += c; + file.get(c); + } + if (token.value != "null") + throw InvalidToken(token.value); } else if (c == ',') token.type = COMMA; @@ -237,9 +247,7 @@ namespace config { file.get(c); if ((c == ' ') && !file.good()) - { - throw std::logic_error("No more tokens!"); - } + throw NoMoreTokens(); else if (!file.good()) return (c); } diff --git a/src/config/Tokenizer.hpp b/src/config/Tokenizer.hpp index 2de6808..dcddc8d 100644 --- a/src/config/Tokenizer.hpp +++ b/src/config/Tokenizer.hpp @@ -59,6 +59,37 @@ namespace config void rollBackToken(); void set_last(e_token type); + class NoMoreTokens: public std::exception + { + public: + virtual const char *what() const throw() + { + return ("No more tokens!"); + } + }; + class InvalidToken: public std::exception + { + protected: + std::string *msg; + + public: + InvalidToken(const std::string &token) + { + + msg = new std::string("Invalid token: '" + token + "'"); + } + + virtual const char *what() const throw() + { + return (msg->c_str()); + } + + virtual ~InvalidToken() throw() + { + delete msg; + } + }; + }; /* struct s_token Tokenizer::getKey(void) */ From 6b244dc57f3a1bf280b00b4ac536dffededb76c7 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sat, 12 Feb 2022 20:19:46 +0300 Subject: [PATCH 06/12] fix: catch only InvalidToken --- src/config/TOMLParser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/config/TOMLParser.cpp b/src/config/TOMLParser.cpp index 182777e..467b477 100644 --- a/src/config/TOMLParser.cpp +++ b/src/config/TOMLParser.cpp @@ -35,7 +35,7 @@ namespace config s_token current; try { current = tokenizer.getToken(); } - catch (std::exception &e) + catch (Tokenizer::NoMoreTokens &e) { std::cerr << e.what() << std::endl; return; @@ -71,7 +71,7 @@ namespace config { s_token nextToken; try { nextToken = tokenizer.getToken(); } - catch (std::exception &e) + catch (Tokenizer::NoMoreTokens &e) { std::cerr << e.what() << std::endl; break; @@ -158,7 +158,7 @@ namespace config s_token current; try { current = tokenizer.getToken(); } - catch (std::exception &e) + catch (Tokenizer::NoMoreTokens &e) { std::cerr << e.what() << std::endl; return; @@ -313,7 +313,7 @@ namespace config { s_token current; try { current = tokenizer.getToken(); } - catch (std::exception &e) + catch (Tokenizer::NoMoreTokens &e) { std::cerr << e.what() << std::endl; break; From 15ae2b131f3fbad27940e8ed6c98a2ddbfe0d325 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sat, 12 Feb 2022 20:20:09 +0300 Subject: [PATCH 07/12] feat: detect invalid tokens --- src/config/Tokenizer.cpp | 26 +++++++++++++++++++++++--- src/config/Tokenizer.hpp | 2 ++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/config/Tokenizer.cpp b/src/config/Tokenizer.cpp index 23c25f3..0bfce2a 100644 --- a/src/config/Tokenizer.cpp +++ b/src/config/Tokenizer.cpp @@ -38,6 +38,15 @@ namespace config else return (false); } + + bool istomlmapdecl(char c) + { + if (isalnum(c) || c == '-' || c == '_' || c == '.') + return (true); + else + return (false); + } + Tokenizer::Tokenizer(char *filename) { last_token = NO_TOK; @@ -99,7 +108,7 @@ namespace config { token.type = MAPARRAY_DECL; file.get(c); - while (c != ']') + while (c != ']' && config::istomlmapdecl(c)) { token.value += c; file.get(c); @@ -107,7 +116,7 @@ namespace config if (c == ']') file.get(c); if (c != ']') - throw std::logic_error("error in MAPARRAY_DECL"); + throw InvalidToken("[[" + token.value); } else { @@ -120,7 +129,8 @@ namespace config file.get(c); } if (c != ']') - throw std::logic_error("malformed MAP_DECL"); + // throw std::logic_error("malformed MAP_DECL"); + throw InvalidToken(token.value); } } else if (c == '[') @@ -233,6 +243,16 @@ namespace config token.type = NEWLINE; } + else + { + while (!config::isspace(c) && (c != '\n')) + { + DBOUT << RED << "[" << c << "]" < Date: Sun, 13 Feb 2022 22:31:14 +0300 Subject: [PATCH 08/12] refactor: change NoMoreTokens message --- src/config/Tokenizer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/Tokenizer.hpp b/src/config/Tokenizer.hpp index 3c7427b..86838ac 100644 --- a/src/config/Tokenizer.hpp +++ b/src/config/Tokenizer.hpp @@ -66,7 +66,7 @@ namespace config public: virtual const char *what() const throw() { - return ("No more tokens!"); + return ("Config may be incomplete, expected more tokens (check EOL)"); } }; class InvalidToken: public std::exception From 4be3ba3f9d40e4b927f815216824ba26b52cad1a Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sun, 13 Feb 2022 22:38:58 +0300 Subject: [PATCH 09/12] feat: change to exception --- src/config/Tokenizer.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/config/Tokenizer.cpp b/src/config/Tokenizer.cpp index 0bfce2a..38e3d96 100644 --- a/src/config/Tokenizer.cpp +++ b/src/config/Tokenizer.cpp @@ -68,16 +68,15 @@ namespace config struct s_token Tokenizer::getToken(void) { - char c; struct s_token token; if (file.eof()) { - std::cout << "Tokens exhausted" << std::endl; - throw std::logic_error("Tokens exhausted"); + DBOUT << RED << "Tokens exhausted" << ENDL; + throw NoMoreTokens(); } prev_pos = file.tellg(); - c = getWithoutWhiteSpace(); + char c = getWithoutWhiteSpace(); if (firstToken() && config::istomlkey(c)) { From 9d5c0f79e89e629dcc0a8f0f135b0947e212d3cf Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sun, 13 Feb 2022 22:39:58 +0300 Subject: [PATCH 10/12] feat(parser): add exceptions --- src/config/TOMLParser.cpp | 32 +++++++++++++++++---------- src/config/TOMLParser.hpp | 46 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/config/TOMLParser.cpp b/src/config/TOMLParser.cpp index 467b477..2bae3fd 100644 --- a/src/config/TOMLParser.cpp +++ b/src/config/TOMLParser.cpp @@ -43,11 +43,13 @@ namespace config if (current.type == MAP_DECL) { if (tokenizer.getToken().type != NEWLINE) - throw std::logic_error("no newline after MAP_DECL"); + throw ExpectedToken("newline", current.value); + // throw std::logic_error("no newline after MAP_DECL"); map_node = parseMap(); } else - throw std::logic_error("unexpected token in processMap"); + // throw std::logic_error("unexpected token in processMap"); + throw UnexpectedToken("", current.value); /* std::cout << current.value << std::endl; */ @@ -90,8 +92,11 @@ namespace config } std::string key = nextToken.value; /* std::cerr << key << std::endl; */ + DBOUT << RED << "key is " << key << ENDL; if (tokenizer.getToken().type != ASSIGN) - throw std::logic_error("EXPECTED assign!"); + throw ExpectedToken("assign", "after " + key); + // throw std::logic_error("EXPECTED assign! 1"); + nextToken = tokenizer.getToken(); switch (nextToken.type) { @@ -126,8 +131,9 @@ namespace config } default: { + throw UnexpectedToken(nextToken.value, key); /* 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; break; } @@ -138,13 +144,14 @@ namespace config break; if (nextToken.type != NEWLINE) { - throw std::logic_error("EXPECTED newline"); + // throw std::logic_error("EXPECTED newline"); + throw ExpectedToken("newline", "parsing Hash Table"); } } - else - { - throw std::logic_error("parseMap: no more tokens"); - } + // else + // { + // throw std::logic_error("parseMap: no more tokens"); + // } } node->setObject(mapObject); return (node); @@ -257,7 +264,9 @@ namespace config } default: { - throw std::logic_error("unkown token in parseArray"); + // throw std::logic_error("unkown token in parseArray"); + throw UnexpectedToken("entry " + current.value, + "in Array"); } } @@ -268,7 +277,8 @@ namespace config else if (current.type == CLOSE_BRACKET) completed = true; else - throw std::invalid_argument("Unexpected token in array!"); + throw UnexpectedToken(current.value, ", when expected COMMA, or CLOSE_BRACKET"); + // throw std::invalid_argument("Unexpected token in array!"); } } result->setArr(array); diff --git a/src/config/TOMLParser.hpp b/src/config/TOMLParser.hpp index 98833fb..26fc9a9 100644 --- a/src/config/TOMLParser.hpp +++ b/src/config/TOMLParser.hpp @@ -41,8 +41,52 @@ namespace config toml_node *parseNil(void); - }; + class ExpectedToken: public std::exception + { + protected: + std::string *msg; + public: + ExpectedToken(const std::string &missing, const std::string context) + { + msg = new std::string("Config file: "); + *msg += ("Expected " + missing + " at " + context); + } + + virtual const char *what() const throw() + { + return (msg->c_str()); + } + + virtual ~ExpectedToken() throw() + { + delete msg; + } + }; + class UnexpectedToken: public std::exception + { + protected: + std::string *msg; + + public: + UnexpectedToken(const std::string &unexpected, const std::string context) + { + msg = new std::string("Config file: "); + *msg += ("Unexpected " + unexpected + " " + context); + } + + virtual const char *what() const throw() + { + return (msg->c_str()); + } + + virtual ~UnexpectedToken() throw() + { + delete msg; + } + + }; + }; /* parse tha root ! */ /* TOMLMap *TOMLParser::parse(void); */ } From a230ca2639ccceb8d48ad744a93e0bd2e7684ef8 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sun, 13 Feb 2022 22:43:19 +0300 Subject: [PATCH 11/12] tmp: don't start server --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index be96849..253eef2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,8 +12,8 @@ int main(int argc, char **argv) server.readConfig(argv[1]); server.setupConfig(); - server.start(); - server.end(); + // server.start(); + server.end(); return (0); From eaaa126e977ae947ef6c3dd81dcb02caa563c0ac Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sun, 13 Feb 2022 22:45:56 +0300 Subject: [PATCH 12/12] feat: catch exceptions in readConfig --- src/Server/Server.cpp | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/Server/Server.cpp b/src/Server/Server.cpp index 745f012..af9b10d 100644 --- a/src/Server/Server.cpp +++ b/src/Server/Server.cpp @@ -36,8 +36,30 @@ void Server::print_epoll_events(unsigned int events) //----------------------------------------------Configuration----------------------------------------------------------------------------------- void Server::readConfig(char *filename) { - TOMLMap *root = parse(filename); + TOMLMap *root = NULL; + try + { + root = parse(filename); + } + catch (config::Tokenizer::NoMoreTokens &e) + { + std::cerr << RED << "FATAL: "; + std::cerr << e.what() << RESET << std::endl; + // root->clear(); + // delete root; + // clean_parsed(root); + return; + } + catch (config::Tokenizer::InvalidToken &e) + { + std::cerr << RED << "FATAL: "; + std::cerr << e.what() << RESET << std::endl; + // clean_parsed(root); + // root->clear(); + delete root; + return; + } /* TOMLMap *map; */ TOMLMap::iterator it1; @@ -408,9 +430,9 @@ void Server::clean_parsed(TOMLMap *root) DBOUT << ">>> cleaning up: <<<" << std::endl; for (it = root->begin(); it != root->end(); ++it) { - /* DBOUT << RED << it->first */ - /* << ": " << GREEN */ - /* << *(it->second->toString()); */ + DBOUT << RED << it->first + << ": " << GREEN + << *(it->second->toString()); clean_generic(it->second); /* delete it->second; */