From c217a936c77035b2b604af2408ce4744d777ee00 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Thu, 20 Jan 2022 20:23:50 +0300 Subject: [PATCH 01/10] refactor --- src/config/TOMLParser.hpp | 180 ++++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 87 deletions(-) diff --git a/src/config/TOMLParser.hpp b/src/config/TOMLParser.hpp index 556e898..aaf9f6a 100644 --- a/src/config/TOMLParser.hpp +++ b/src/config/TOMLParser.hpp @@ -103,6 +103,98 @@ namespace config return (node); } + void parseMapArray(void) + { + + std::cerr << "Parsing MapArray" << std::endl; + toml_node *map_node; + toml_node *maparr_node; + s_token current; + + try { current = tokenizer.getToken(); } + catch (std::logic_error e) + { + std::cerr << e.what() << std::endl; + return; + } + if (current.type == MAPARRAY_DECL) + { + if (tokenizer.getToken().type != NEWLINE) + throw std::logic_error("no newline after map_array declaration"); + map_node = parseMap(); + } + else + throw std::logic_error("unexpected token in parseMapArray"); + + TOMLMap::iterator it; + std::cout << current.value << std::endl; + std::string name = current.value; + std::vector full_name; + size_t dot; + + while (1) + { + dot = name.find('.'); + if (dot == std::string::npos) + break; + /* std::cout << dot << std::endl; */ + full_name.push_back(name.substr(0, dot)); + name.erase(0, dot + 1); + } + full_name.push_back(name); + + for (size_t i = 0; i < full_name.size(); i++) + std::cout << full_name[i] << ", "; + std::cout << std::endl; + + /* throw std::logic_error("tha end"); */ + TOMLMap *local_root; + + std::vector::iterator subname = full_name.begin(); + local_root = root; + while (1) + { + if (subname + 1 == full_name.end()) + { + it = local_root->find(*subname); + if (it == local_root->end()) + { + maparr_node = new toml_node; + TOMLMapArray *map_array = new TOMLMapArray; + map_array->push_back(map_node->getMap()); + maparr_node->setMapArray(map_array); + (*local_root)[*subname] = maparr_node; + } + else + (it->second)->getMapArray()->push_back(map_node->getMap()); + break; + } + else + { + it = local_root->find(*subname); + + toml_node *map_node2; + map_node2 = new toml_node; + TOMLMap *map = new TOMLMap; + map_node2->setObject(map); + /* subname not found in local_root */ + if (it == local_root->end()) + { + (*local_root)[*subname] = map_node2; + local_root = map; + } + /* subname found in local_root */ + else + { + local_root = *((it->second)->getMapArray()->end() - 1); + } + + } + ++subname; + } + + } + toml_node *parseString(void) { /* toml_node *node; */ @@ -244,93 +336,7 @@ namespace config { /* parseMapArray(); */ tokenizer.rollBackToken(); - std::cerr << "Parsing MapArray" << std::endl; - toml_node *map_node; - toml_node *maparr_node; - s_token current; - - try { current = tokenizer.getToken(); } - catch (std::logic_error e) - { - std::cerr << e.what() << std::endl; - break; - } - if (current.type == MAPARRAY_DECL) - { - if (tokenizer.getToken().type != NEWLINE) - throw std::logic_error("no newline after map_array declaration"); - map_node = parseMap(); - } - else - throw std::logic_error("unexpected token in parseMapArray"); - - TOMLMap::iterator it; - std::cout << current.value << std::endl; - std::string name = current.value; - std::vector full_name; - size_t dot; - - while (1) - { - dot = name.find('.'); - if (dot == std::string::npos) - break; - /* std::cout << dot << std::endl; */ - full_name.push_back(name.substr(0, dot)); - name.erase(0, dot + 1); - } - full_name.push_back(name); - - for (size_t i = 0; i < full_name.size(); i++) - std::cout << full_name[i] << ", "; - std::cout << std::endl; - - /* throw std::logic_error("tha end"); */ - TOMLMap *local_root; - - std::vector::iterator subname = full_name.begin(); - local_root = root; - while (1) - { - if (subname + 1 == full_name.end()) - { - it = local_root->find(*subname); - if (it == local_root->end()) - { - maparr_node = new toml_node; - TOMLMapArray *map_array = new TOMLMapArray; - map_array->push_back(map_node->getMap()); - maparr_node->setMapArray(map_array); - (*local_root)[*subname] = maparr_node; - } - else - (it->second)->getMapArray()->push_back(map_node->getMap()); - break; - } - else - { - it = local_root->find(*subname); - - toml_node *map_node2; - map_node2 = new toml_node; - TOMLMap *map = new TOMLMap; - map_node2->setObject(map); - /* subname not found in local_root */ - if (it == local_root->end()) - { - (*local_root)[*subname] = map_node2; - local_root = map; - } - /* subname found in local_root */ - else - { - local_root = *((it->second)->getMapArray()->end() - 1); - } - - } - ++subname; - } - + parseMapArray(); } else { From 96d7db19bb0a0102524d251f8838079fd7e65c0b Mon Sep 17 00:00:00 2001 From: 3lswear Date: Thu, 20 Jan 2022 21:28:38 +0300 Subject: [PATCH 02/10] add error_page --- config/example.toml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/config/example.toml b/config/example.toml index b2418f2..80d7ab9 100644 --- a/config/example.toml +++ b/config/example.toml @@ -1,9 +1,12 @@ [[server]] name = "serv1" - host = "127.0.0.1" + ip = "127.0.0.1" port = 8080 - error_page = "error.html" body_size_limit = 10 + # error_404 = "error_404.html" + [server.error_page] + 400 = "error_400.html" + 401 = "error_401.html" [[server.location]] location = "/" # redirection ??? @@ -23,7 +26,7 @@ [[server]] name = "2222" - host = "10.0.0.1" + ip = "10.0.0.1" port = 8081 error_page = "error2.html" body_size_limit = 10 From 22cda8daf047594e7653b16be9d7222a0e36dabb Mon Sep 17 00:00:00 2001 From: 3lswear Date: Fri, 21 Jan 2022 18:12:10 +0300 Subject: [PATCH 03/10] split class intermediate --- src/config/TOMLNode.cpp | 166 ++++++++++++++++++++++++++++++++++++++++ src/config/TOMLNode.hpp | 150 +++--------------------------------- 2 files changed, 178 insertions(+), 138 deletions(-) create mode 100644 src/config/TOMLNode.cpp diff --git a/src/config/TOMLNode.cpp b/src/config/TOMLNode.cpp new file mode 100644 index 0000000..0afc7fb --- /dev/null +++ b/src/config/TOMLNode.cpp @@ -0,0 +1,166 @@ +#include "webserv.hpp" +#include "TOMLNode.hpp" + +/* toml_node::toml_node(void) */ +/* { */ +/* return; */ +/* } */ + +/* toml_node::toml_node(const toml_node &src) */ +/* { */ +/* *this = src; */ +/* return; */ +/* } */ + +/* toml_node::~toml_node(void) */ +/* { */ +/* return; */ +/* } */ + +/* toml_node &toml_node::operator=(const toml_node &rhs) */ +/* { */ +/* //code */ +/* return (*this); */ +/* } */ + +toml_node::e_type toml_node::get_type(void) +{ + return (type); +} + +TOMLMap *toml_node::getMap(void) +{ + return (value.map); +} + +TOMLMapArray *toml_node::getMapArray(void) +{ + return (value.map_array); +} + +void toml_node::setString(std::string *str) +{ + value.str = str; + type = STRING; +} + +void toml_node::setNumber(int num) +{ + value.integer = num; + type = NUM; +} + +void toml_node::setArr(TOMLArray *toml_array) +{ + value.array = toml_array; + type = ARRAY; +} +void toml_node::setBool(bool b) +{ + value.boolean = b; + type = BOOL; +} +void toml_node::setNil(void) +{ + type = NIL; +} + +void toml_node::setObject(TOMLMap *obj) +{ + value.map = obj; + type = MAP; +} + +void toml_node::setMapArray(TOMLMapArray *map_array) +{ + value.map_array = map_array; + type = MAPARRAY; +} + +std::string *toml_node::toString(void) const +{ + switch (type) + { + case STRING: + { + return (value.str); + } + case NUM: + { + std::stringstream ss; + ss << value.integer; + std::string *result = new std::string(); + ss >> *result; + return (result); + } + case ARRAY: + { + TOMLArray::iterator it; + std::string *result = new std::string("[ "); + for (it = value.array->begin(); it != value.array->end(); ++it) + { + *result += *((*it)->toString()); + *result += ", "; + } + *result += " ]"; + return (result); + } + case MAP: + { + return (TOMLMap_to_string(value.map)); + } + case MAPARRAY: + { + std::stringstream ss; + std::string *result = new std::string(); + TOMLMapArray::iterator it; + TOMLMapArray *map_array = value.map_array; + + ss << "[\n"; + for (it = map_array->begin(); it != map_array->end(); ++it) + { + ss << (*TOMLMap_to_string(*it)); + ss << ", " << std::endl; + } + ss << "]\n"; + + + /* ss >> *result; */ + *result = ss.str(); + return (result); + } + case BOOL: + { + std::string *result; + if (value.boolean) + result = new std::string("true"); + else + result = new std::string("false"); + return (result); + } + default: + return ( new std::string("Not implemented :)")); + } +} + +std::string *TOMLMap_to_string(TOMLMap *map) +{ + std::stringstream ss; + std::string *result = new std::string(); + TOMLMap::iterator it; + + ss << "{\n"; + for (it = map->begin(); it != map->end(); ++it) + { + ss << it->first + << ": " + << *(it->second->toString()) + << std::endl; + } + + ss << "}" << std::endl; + + /* ss >> *result; */ + *result = ss.str(); + return (result); +} diff --git a/src/config/TOMLNode.hpp b/src/config/TOMLNode.hpp index 2cf2c64..8f0fd45 100644 --- a/src/config/TOMLNode.hpp +++ b/src/config/TOMLNode.hpp @@ -11,9 +11,6 @@ #include #include - - - class toml_node { @@ -37,145 +34,22 @@ class toml_node STRING, NUM, BOOL, ARRAY, MAP, MAPARRAY, NIL } type; - enum e_type get_type(void) - { - return (type); - } + enum e_type get_type(void); - TOMLMap *getMap(void) - { - return (value.map); - } + TOMLMap *getMap(void); + TOMLMapArray *getMapArray(void); - TOMLMapArray *getMapArray(void) - { - return (value.map_array); - } + void setString(std::string *str); + void setNumber(int num); - void setString(std::string *str) - { - value.str = str; - type = STRING; - } + void setArr(TOMLArray *toml_array); + void setBool(bool b); + void setNil(void); + void setObject(TOMLMap *obj); + void setMapArray(TOMLMapArray *map_array); - void setNumber(int num) - { - value.integer = num; - type = NUM; - } - - void setArr(TOMLArray *toml_array) - { - value.array = toml_array; - type = ARRAY; - } - void setBool(bool b) - { - value.boolean = b; - type = BOOL; - } - void setNil(void) - { - type = NIL; - } - void setObject(TOMLMap *obj) - { - value.map = obj; - type = MAP; - } - void setMapArray(TOMLMapArray *map_array) - { - value.map_array = map_array; - type = MAPARRAY; - } - - static std::string *TOMLMap_to_string(TOMLMap *map) - { - std::stringstream ss; - std::string *result = new std::string(); - TOMLMap::iterator it; - - ss << "{\n"; - for (it = map->begin(); it != map->end(); ++it) - { - ss << it->first - << ": " - << *(it->second->toString()) - << std::endl; - } - - ss << "}" << std::endl; - - /* ss >> *result; */ - *result = ss.str(); - return (result); - } - - std::string *toString(void) const - { - switch (type) - { - case STRING: - { - return (value.str); - } - case NUM: - { - std::stringstream ss; - ss << value.integer; - std::string *result = new std::string(); - ss >> *result; - return (result); - } - case ARRAY: - { - TOMLArray::iterator it; - std::string *result = new std::string("[ "); - for (it = value.array->begin(); it != value.array->end(); ++it) - { - *result += *((*it)->toString()); - *result += ", "; - } - *result += " ]"; - return (result); - } - case MAP: - { - return (TOMLMap_to_string(value.map)); - } - case MAPARRAY: - { - std::stringstream ss; - std::string *result = new std::string(); - TOMLMapArray::iterator it; - TOMLMapArray *map_array = value.map_array; - - ss << "[\n"; - for (it = map_array->begin(); it != map_array->end(); ++it) - { - ss << (*TOMLMap_to_string(*it)); - ss << ", " << std::endl; - } - ss << "]\n"; - - - /* ss >> *result; */ - *result = ss.str(); - return (result); - } - case BOOL: - { - std::string *result; - if (value.boolean) - result = new std::string("true"); - else - result = new std::string("false"); - return (result); - } - default: - return ( new std::string("Not implemented :)")); - } - } + std::string *TOMLMap_to_string(TOMLMap *map) const; + std::string *toString(void) const; }; #endif From 51a3050bebbe67eea213d9b639f59b8a8d34309b Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sat, 22 Jan 2022 13:58:44 +0300 Subject: [PATCH 04/10] refactor: separate parsing classes --- {src/config => includes}/TOMLNode.hpp | 5 +- includes/TOMLParser.hpp | 43 +++ includes/Tokenizer.hpp | 74 ++++ includes/parse.hpp | 13 + includes/tomlstuff.hpp | 11 + includes/webserv.hpp | 12 - src/config/TOMLNode.cpp | 3 +- src/config/TOMLParser.cpp | 403 ++++++++++++++++++++ src/config/TOMLParser.hpp | 400 ------------------- src/config/{Tokenizer.hpp => Tokenizer.cpp} | 154 +++----- src/config/parse.cpp | 5 +- src/main.cpp | 1 + 12 files changed, 609 insertions(+), 515 deletions(-) rename {src/config => includes}/TOMLNode.hpp (92%) create mode 100644 includes/TOMLParser.hpp create mode 100644 includes/Tokenizer.hpp create mode 100644 includes/parse.hpp create mode 100644 includes/tomlstuff.hpp create mode 100644 src/config/TOMLParser.cpp delete mode 100644 src/config/TOMLParser.hpp rename src/config/{Tokenizer.hpp => Tokenizer.cpp} (70%) diff --git a/src/config/TOMLNode.hpp b/includes/TOMLNode.hpp similarity index 92% rename from src/config/TOMLNode.hpp rename to includes/TOMLNode.hpp index 8f0fd45..6c7716a 100644 --- a/src/config/TOMLNode.hpp +++ b/includes/TOMLNode.hpp @@ -2,6 +2,8 @@ #define TOMLNODE_HPP #include "webserv.hpp" +#include "tomlstuff.hpp" + #include #include #include @@ -48,8 +50,9 @@ class toml_node void setObject(TOMLMap *obj); void setMapArray(TOMLMapArray *map_array); - std::string *TOMLMap_to_string(TOMLMap *map) const; std::string *toString(void) const; + static std::string *TOMLMap_to_string(TOMLMap *map); }; + #endif diff --git a/includes/TOMLParser.hpp b/includes/TOMLParser.hpp new file mode 100644 index 0000000..e06e41a --- /dev/null +++ b/includes/TOMLParser.hpp @@ -0,0 +1,43 @@ +#ifndef TOMLPARSER_HPP +#define TOMLPARSER_HPP + +#include "webserv.hpp" +#include "tomlstuff.hpp" +#include "Tokenizer.hpp" +#include "TOMLNode.hpp" +#include + +namespace config +{ + class TOMLParser + { + private: + std::fstream file; + TOMLMap *root; //root of TOML tree + /* toml_node *current; //node currently being parsed */ + Tokenizer tokenizer; + + public: + TOMLParser(const std::string filename); + TOMLMap *parse(void); + + toml_node *parseMap(void); + + void parseMapArray(void); + + toml_node *parseString(void); + + toml_node *parseNumber(void); + + toml_node *parseArray(void); + + toml_node *parseBool(void); + + toml_node *parseNil(void); + + }; + + /* parse tha root ! */ + /* TOMLMap *TOMLParser::parse(void); */ +} +#endif diff --git a/includes/Tokenizer.hpp b/includes/Tokenizer.hpp new file mode 100644 index 0000000..86de8f9 --- /dev/null +++ b/includes/Tokenizer.hpp @@ -0,0 +1,74 @@ +#ifndef TOKENIZER_HPP +#define TOKENIZER_HPP + +#include "webserv.hpp" +#include "tomlstuff.hpp" + +#include +#include +#include +#include +#include +#include + + +namespace config +{ + enum e_token + { + KEY, + NEWLINE, + ASSIGN, + STRING, + NUMBER, + COMMA, + BOOL, + NIL, + ARR_OPEN, + ARR_CLOSE, + MAP_OPEN, + MAP_CLOSE, + MAPARRAY_DECL + }; + + struct s_token + { + std::string value; + e_token type; + /* std::string to_string(void); */ + }; + + bool isspace(char c); + + bool istomlkey(char c); + + class Tokenizer + { + private: + std::fstream file; + size_t prev_pos; + e_token last_token; + + public: + Tokenizer(std::string filename); + char getWithoutWhiteSpace(); + struct s_token getToken(); + bool hasMoreTokens(); + bool firstToken(); + void rollBackToken(); + + }; + + /* struct s_token Tokenizer::getKey(void) */ + /* { */ + /* char c; */ + /* struct s_token token; */ + /* if (file.eof()) */ + /* { */ + /* std::cout << "Tokens exhausted" << std::endl; */ + /* } */ + /* } */ + +} + +#endif diff --git a/includes/parse.hpp b/includes/parse.hpp new file mode 100644 index 0000000..9f73f31 --- /dev/null +++ b/includes/parse.hpp @@ -0,0 +1,13 @@ +#ifndef PARSE_HPP +#define PARSE_HPP + +#include "tomlstuff.hpp" + +#include "Tokenizer.hpp" +#include "TOMLNode.hpp" +#include "TOMLParser.hpp" + +void parse(void); +void display(TOMLMap *config); + +#endif diff --git a/includes/tomlstuff.hpp b/includes/tomlstuff.hpp new file mode 100644 index 0000000..d7c7d11 --- /dev/null +++ b/includes/tomlstuff.hpp @@ -0,0 +1,11 @@ +#ifndef TOMLSTUFF_HPP +#define TOMLSTUFF_HPP + +class toml_node; + +typedef std::map TOMLMap; // = JSONObject +typedef std::vector TOMLMapArray; +typedef std::vector TOMLArray; + +#endif + diff --git a/includes/webserv.hpp b/includes/webserv.hpp index 926a93e..72df111 100644 --- a/includes/webserv.hpp +++ b/includes/webserv.hpp @@ -19,16 +19,4 @@ #include #include -void parse(void); - -class toml_node; - -/* typedef std::vector TOMLArray; */ -/* typedef std::vector TOMLArrayOfMap; */ -typedef std::map TOMLMap; // = JSONObject -typedef std::vector TOMLMapArray; -typedef std::vector TOMLArray; - -void display(TOMLMap *config); - #endif diff --git a/src/config/TOMLNode.cpp b/src/config/TOMLNode.cpp index 0afc7fb..3a32ec2 100644 --- a/src/config/TOMLNode.cpp +++ b/src/config/TOMLNode.cpp @@ -1,4 +1,3 @@ -#include "webserv.hpp" #include "TOMLNode.hpp" /* toml_node::toml_node(void) */ @@ -143,7 +142,7 @@ std::string *toml_node::toString(void) const } } -std::string *TOMLMap_to_string(TOMLMap *map) +std::string *toml_node::TOMLMap_to_string(TOMLMap *map) { std::stringstream ss; std::string *result = new std::string(); diff --git a/src/config/TOMLParser.cpp b/src/config/TOMLParser.cpp new file mode 100644 index 0000000..f553e9b --- /dev/null +++ b/src/config/TOMLParser.cpp @@ -0,0 +1,403 @@ +#include "TOMLParser.hpp" + +/* -Template::-Template(void) */ +/* { */ +/* return; */ +/* } */ + +/* -Template::-Template(const -Template &src) */ +/* { */ +/* *this = src; */ +/* return; */ +/* } */ + +/* -Template::~-Template(void) */ +/* { */ +/* return; */ +/* } */ + +/* -Template &-Template::operator=(const -Template &rhs) */ +/* { */ +/* //code */ +/* return (*this); */ +/* } */ + +config::TOMLParser::TOMLParser(const std::string filename) : tokenizer(filename) +{}; + +toml_node *config::TOMLParser::parseMap(void) +{ + std::cerr << "Parsing map" << std::endl; + toml_node *node = new toml_node; + TOMLMap *mapObject = new TOMLMap; + bool completed = false; + while (!completed) + { + if (tokenizer.hasMoreTokens()) + { + s_token nextToken; + try { nextToken = tokenizer.getToken(); } + catch (std::logic_error e) + { + std::cerr << e.what() << std::endl; + break; + } + if (nextToken.type == MAPARRAY_DECL) + { + tokenizer.rollBackToken(); + break; + } + std::string key = nextToken.value; + std::cerr << key << std::endl; + if (tokenizer.getToken().type != ASSIGN) + throw std::logic_error("EXPECTED assign!"); + nextToken = tokenizer.getToken(); + switch (nextToken.type) + { + case STRING: + { + tokenizer.rollBackToken(); + (*mapObject)[key] = parseString(); + break; + } + case ARR_OPEN: + { + (*mapObject)[key] = parseArray(); + break; + } + case NUMBER: + { + tokenizer.rollBackToken(); + (*mapObject)[key] = parseNumber(); + break; + } + case BOOL: + { + tokenizer.rollBackToken(); + (*mapObject)[key] = parseBool(); + break; + } + case MAPARRAY_DECL: + { + std::cerr << "reached MAPARRAY_DECL in parseMap" << std::endl; + completed = true; + break; + } + default: + { + /* throw std::logic_error("jopa in parseMap"); */ + std::cerr << "Unknown token, marking as complete" << std::endl; + completed = true; + break; + } + } + if (tokenizer.hasMoreTokens()) + nextToken = tokenizer.getToken(); + else + break; + if (nextToken.type != NEWLINE) + { + throw std::logic_error("EXPECTED newline"); + } + } + else + { + throw std::logic_error("parseMap: no more tokens"); + } + } + node->setObject(mapObject); + return (node); +} + +void config::TOMLParser::parseMapArray(void) +{ + + std::cerr << "Parsing MapArray" << std::endl; + toml_node *map_node; + toml_node *maparr_node; + s_token current; + + try { current = tokenizer.getToken(); } + catch (std::logic_error e) + { + std::cerr << e.what() << std::endl; + return; + } + if (current.type == MAPARRAY_DECL) + { + if (tokenizer.getToken().type != NEWLINE) + throw std::logic_error("no newline after map_array declaration"); + map_node = parseMap(); + } + else + throw std::logic_error("unexpected token in parseMapArray"); + + TOMLMap::iterator it; + std::cout << current.value << std::endl; + std::string name = current.value; + std::vector full_name; + size_t dot; + + while (1) + { + dot = name.find('.'); + if (dot == std::string::npos) + break; + /* std::cout << dot << std::endl; */ + full_name.push_back(name.substr(0, dot)); + name.erase(0, dot + 1); + } + full_name.push_back(name); + + for (size_t i = 0; i < full_name.size(); i++) + std::cout << full_name[i] << ", "; + std::cout << std::endl; + + /* throw std::logic_error("tha end"); */ + TOMLMap *local_root; + + std::vector::iterator subname = full_name.begin(); + local_root = root; + while (1) + { + if (subname + 1 == full_name.end()) + { + it = local_root->find(*subname); + if (it == local_root->end()) + { + maparr_node = new toml_node; + TOMLMapArray *map_array = new TOMLMapArray; + map_array->push_back(map_node->getMap()); + maparr_node->setMapArray(map_array); + (*local_root)[*subname] = maparr_node; + } + else + (it->second)->getMapArray()->push_back(map_node->getMap()); + break; + } + else + { + it = local_root->find(*subname); + + toml_node *map_node2; + map_node2 = new toml_node; + TOMLMap *map = new TOMLMap; + map_node2->setObject(map); + /* subname not found in local_root */ + if (it == local_root->end()) + { + (*local_root)[*subname] = map_node2; + local_root = map; + } + /* subname found in local_root */ + else + { + local_root = *((it->second)->getMapArray()->end() - 1); + } + + } + ++subname; + } + +} + +toml_node *config::TOMLParser::parseString(void) +{ + /* toml_node *node; */ + toml_node *node = new toml_node; + std::string *sValue; + + std::cerr << "Parsing string" << std::endl; + s_token token = tokenizer.getToken(); + sValue = new std::string(token.value); + node->setString(sValue); + + return (node); +} + +toml_node *config::TOMLParser::parseNumber(void) +{ + toml_node *node = new toml_node; + int value; + + std::cerr << "Parsing number" << std::endl; + s_token token = tokenizer.getToken(); + value = std::atoi(token.value.c_str()); + node->setNumber(value); + + return (node); +} + +toml_node *config::TOMLParser::parseArray(void) +{ + std::cerr << "Parsing array" << std::endl; + toml_node *node; + toml_node *result = new toml_node; + TOMLArray *array = new TOMLArray; + bool completed = false; + s_token current; + + while (!completed) + { + if (!tokenizer.hasMoreTokens()) + throw std::logic_error("No more tokens"); + else + { + current = tokenizer.getToken(); + switch (current.type) + { + case ARR_OPEN: + { + node = parseArray(); + break; + } + case STRING: + { + tokenizer.rollBackToken(); + node = parseString(); + break; + } + case NUMBER: + { + tokenizer.rollBackToken(); + node = parseNumber(); + break; + } + case BOOL: + { + tokenizer.rollBackToken(); + node = parseBool(); + break; + } + case NIL: + { + node = parseNil(); + break; + } + default: + { + throw std::logic_error("unkown token in parseArray"); + } + + } + array->push_back(node); + current = tokenizer.getToken(); + if (current.type == COMMA) + continue; + else if (current.type == ARR_CLOSE) + completed = true; + else + throw std::invalid_argument("Unexpected token in array!"); + } + } + result->setArr(array); + return (result); +} + +toml_node *config::TOMLParser::parseBool(void) +{ + toml_node *node = new toml_node; + bool value; + + std::cerr << "Parsing bool" << std::endl; + s_token token = tokenizer.getToken(); + if (token.value == "true") + value = true; + else if (token.value == "false") + value = false; + else + throw std::invalid_argument("Unexpected bool value"); + node->setBool(value); + + return (node); +} + +toml_node *config::TOMLParser::parseNil(void) +{ + toml_node *node = new toml_node; + std::cerr << "Parsing NIL" << std::endl; + node->setNil(); + return (node); +} + +/* parse tha root ! */ +TOMLMap *config::TOMLParser::parse(void) +{ + std::cerr << "Parsing ROOT" << std::endl; + root = new TOMLMap; + bool completed = false; + while (!completed) + { + if (tokenizer.hasMoreTokens()) + { + s_token current; + try { current = tokenizer.getToken(); } + catch (std::logic_error e) + { + std::cerr << e.what() << std::endl; + break; + } + if (current.type == MAPARRAY_DECL) + { + /* parseMapArray(); */ + tokenizer.rollBackToken(); + parseMapArray(); + } + else + { + std::string key = current.value; + std::cerr << key << std::endl; + if (tokenizer.getToken().type != ASSIGN) + throw std::logic_error("EXPECTED assign!"); + current = tokenizer.getToken(); + switch (current.type) + { + case STRING: + { + tokenizer.rollBackToken(); + (*root)[key] = parseString(); + break; + } + case ARR_OPEN: + { + (*root)[key] = parseArray(); + break; + } + case NUMBER: + { + tokenizer.rollBackToken(); + (*root)[key] = parseNumber(); + break; + } + case BOOL: + { + tokenizer.rollBackToken(); + (*root)[key] = parseBool(); + break; + } + default: + { + /* throw std::logic_error("jopa in parseMap"); */ + std::cerr << "Unknown token, marking as complete" << std::endl; + completed = true; + break; + } + } + if (tokenizer.hasMoreTokens()) + current = tokenizer.getToken(); + else + break; + if (current.type != NEWLINE) + { + throw std::logic_error("EXPECTED newline"); + } + } + } + else + { + completed = true; + break; + } + } + return (root); +} diff --git a/src/config/TOMLParser.hpp b/src/config/TOMLParser.hpp deleted file mode 100644 index aaf9f6a..0000000 --- a/src/config/TOMLParser.hpp +++ /dev/null @@ -1,400 +0,0 @@ -#ifndef TOMLPARSER_HPP -#define TOMLPARSER_HPP - -#include "TOMLNode.hpp" -#include "Tokenizer.hpp" -#include - -namespace config -{ - class TOMLParser - { - private: - std::fstream file; - TOMLMap *root; //root of TOML tree - /* toml_node *current; //node currently being parsed */ - Tokenizer tokenizer; - - public: - TOMLParser(const std::string filename) : tokenizer(filename) {} - TOMLMap *parse(void); - - toml_node *parseMap(void) - { - std::cerr << "Parsing object" << std::endl; - toml_node *node = new toml_node; - TOMLMap *mapObject = new TOMLMap; - bool completed = false; - while (!completed) - { - if (tokenizer.hasMoreTokens()) - { - s_token nextToken; - try { nextToken = tokenizer.getToken(); } - catch (std::logic_error e) - { - std::cerr << e.what() << std::endl; - break; - } - if (nextToken.type == MAPARRAY_DECL) - { - tokenizer.rollBackToken(); - break; - } - std::string key = nextToken.value; - std::cerr << key << std::endl; - if (tokenizer.getToken().type != ASSIGN) - throw std::logic_error("EXPECTED assign!"); - nextToken = tokenizer.getToken(); - switch (nextToken.type) - { - case STRING: - { - tokenizer.rollBackToken(); - (*mapObject)[key] = parseString(); - break; - } - case ARR_OPEN: - { - (*mapObject)[key] = parseArray(); - break; - } - case NUMBER: - { - tokenizer.rollBackToken(); - (*mapObject)[key] = parseNumber(); - break; - } - case BOOL: - { - tokenizer.rollBackToken(); - (*mapObject)[key] = parseBool(); - break; - } - case MAPARRAY_DECL: - { - std::cerr << "reached MAPARRAY_DECL in parseMap" << std::endl; - completed = true; - break; - } - default: - { - /* throw std::logic_error("jopa in parseMap"); */ - std::cerr << "Unknown token, marking as complete" << std::endl; - completed = true; - break; - } - } - if (tokenizer.hasMoreTokens()) - nextToken = tokenizer.getToken(); - else - break; - if (nextToken.type != NEWLINE) - { - throw std::logic_error("EXPECTED newline"); - } - } - else - { - throw std::logic_error("parseMap: no more tokens"); - } - } - node->setObject(mapObject); - return (node); - } - - void parseMapArray(void) - { - - std::cerr << "Parsing MapArray" << std::endl; - toml_node *map_node; - toml_node *maparr_node; - s_token current; - - try { current = tokenizer.getToken(); } - catch (std::logic_error e) - { - std::cerr << e.what() << std::endl; - return; - } - if (current.type == MAPARRAY_DECL) - { - if (tokenizer.getToken().type != NEWLINE) - throw std::logic_error("no newline after map_array declaration"); - map_node = parseMap(); - } - else - throw std::logic_error("unexpected token in parseMapArray"); - - TOMLMap::iterator it; - std::cout << current.value << std::endl; - std::string name = current.value; - std::vector full_name; - size_t dot; - - while (1) - { - dot = name.find('.'); - if (dot == std::string::npos) - break; - /* std::cout << dot << std::endl; */ - full_name.push_back(name.substr(0, dot)); - name.erase(0, dot + 1); - } - full_name.push_back(name); - - for (size_t i = 0; i < full_name.size(); i++) - std::cout << full_name[i] << ", "; - std::cout << std::endl; - - /* throw std::logic_error("tha end"); */ - TOMLMap *local_root; - - std::vector::iterator subname = full_name.begin(); - local_root = root; - while (1) - { - if (subname + 1 == full_name.end()) - { - it = local_root->find(*subname); - if (it == local_root->end()) - { - maparr_node = new toml_node; - TOMLMapArray *map_array = new TOMLMapArray; - map_array->push_back(map_node->getMap()); - maparr_node->setMapArray(map_array); - (*local_root)[*subname] = maparr_node; - } - else - (it->second)->getMapArray()->push_back(map_node->getMap()); - break; - } - else - { - it = local_root->find(*subname); - - toml_node *map_node2; - map_node2 = new toml_node; - TOMLMap *map = new TOMLMap; - map_node2->setObject(map); - /* subname not found in local_root */ - if (it == local_root->end()) - { - (*local_root)[*subname] = map_node2; - local_root = map; - } - /* subname found in local_root */ - else - { - local_root = *((it->second)->getMapArray()->end() - 1); - } - - } - ++subname; - } - - } - - toml_node *parseString(void) - { - /* toml_node *node; */ - toml_node *node = new toml_node; - std::string *sValue; - - std::cerr << "Parsing string" << std::endl; - s_token token = tokenizer.getToken(); - sValue = new std::string(token.value); - node->setString(sValue); - - return (node); - } - - toml_node *parseNumber(void) - { - toml_node *node = new toml_node; - int value; - - std::cerr << "Parsing number" << std::endl; - s_token token = tokenizer.getToken(); - value = std::atoi(token.value.c_str()); - node->setNumber(value); - - return (node); - } - - toml_node *parseArray(void) - { - std::cerr << "Parsing array" << std::endl; - toml_node *node; - toml_node *result = new toml_node; - TOMLArray *array = new TOMLArray; - bool completed = false; - s_token current; - - while (!completed) - { - if (!tokenizer.hasMoreTokens()) - throw std::logic_error("No more tokens"); - else - { - current = tokenizer.getToken(); - switch (current.type) - { - case ARR_OPEN: - { - node = parseArray(); - break; - } - case STRING: - { - tokenizer.rollBackToken(); - node = parseString(); - break; - } - case NUMBER: - { - tokenizer.rollBackToken(); - node = parseNumber(); - break; - } - case BOOL: - { - tokenizer.rollBackToken(); - node = parseBool(); - break; - } - case NIL: - { - node = parseNil(); - break; - } - default: - { - throw std::logic_error("unkown token in parseArray"); - } - - } - array->push_back(node); - current = tokenizer.getToken(); - if (current.type == COMMA) - continue; - else if (current.type == ARR_CLOSE) - completed = true; - else - throw std::invalid_argument("Unexpected token in array!"); - } - } - result->setArr(array); - return (result); - } - - toml_node *parseBool(void) - { - toml_node *node = new toml_node; - bool value; - - std::cerr << "Parsing bool" << std::endl; - s_token token = tokenizer.getToken(); - if (token.value == "true") - value = true; - else if (token.value == "false") - value = false; - else - throw std::invalid_argument("Unexpected bool value"); - node->setBool(value); - - return (node); - } - - toml_node *parseNil(void) - { - toml_node *node = new toml_node; - std::cerr << "Parsing NIL" << std::endl; - node->setNil(); - return (node); - } - }; - - /* parse tha root ! */ - TOMLMap *TOMLParser::parse(void) - { - std::cerr << "Parsing ROOT" << std::endl; - root = new TOMLMap; - bool completed = false; - while (!completed) - { - if (tokenizer.hasMoreTokens()) - { - s_token current; - try { current = tokenizer.getToken(); } - catch (std::logic_error e) - { - std::cerr << e.what() << std::endl; - break; - } - if (current.type == MAPARRAY_DECL) - { - /* parseMapArray(); */ - tokenizer.rollBackToken(); - parseMapArray(); - } - else - { - std::string key = current.value; - std::cerr << key << std::endl; - if (tokenizer.getToken().type != ASSIGN) - throw std::logic_error("EXPECTED assign!"); - current = tokenizer.getToken(); - switch (current.type) - { - case STRING: - { - tokenizer.rollBackToken(); - (*root)[key] = parseString(); - break; - } - case ARR_OPEN: - { - (*root)[key] = parseArray(); - break; - } - case NUMBER: - { - tokenizer.rollBackToken(); - (*root)[key] = parseNumber(); - break; - } - case BOOL: - { - tokenizer.rollBackToken(); - (*root)[key] = parseBool(); - break; - } - default: - { - /* throw std::logic_error("jopa in parseMap"); */ - std::cerr << "Unknown token, marking as complete" << std::endl; - completed = true; - break; - } - } - if (tokenizer.hasMoreTokens()) - current = tokenizer.getToken(); - else - break; - if (current.type != NEWLINE) - { - throw std::logic_error("EXPECTED newline"); - } - } - } - else - { - completed = true; - break; - } - } - return (root); - } -} -#endif diff --git a/src/config/Tokenizer.hpp b/src/config/Tokenizer.cpp similarity index 70% rename from src/config/Tokenizer.hpp rename to src/config/Tokenizer.cpp index 791f8a8..c52fd1d 100644 --- a/src/config/Tokenizer.hpp +++ b/src/config/Tokenizer.cpp @@ -1,40 +1,28 @@ -#ifndef TOKENIZER_HPP -#define TOKENIZER_HPP +#include "Tokenizer.hpp" -#include "webserv.hpp" -#include -#include -#include -#include -#include -#include +/* -Template::-Template(void) */ +/* { */ +/* return; */ +/* } */ +/* -Template::-Template(const -Template &src) */ +/* { */ +/* *this = src; */ +/* return; */ +/* } */ + +/* -Template::~-Template(void) */ +/* { */ +/* return; */ +/* } */ + +/* -Template &-Template::operator=(const -Template &rhs) */ +/* { */ +/* //code */ +/* return (*this); */ +/* } */ namespace config { - enum e_token - { - KEY, - NEWLINE, - ASSIGN, - STRING, - NUMBER, - COMMA, - BOOL, - NIL, - ARR_OPEN, - ARR_CLOSE, - MAP_OPEN, - MAP_CLOSE, - MAPARRAY_DECL - }; - - struct s_token - { - std::string value; - e_token type; - /* std::string to_string(void); */ - }; - bool isspace(char c) { if (c == ' ' || c == '\t') @@ -50,74 +38,23 @@ namespace config else return (false); } - - class Tokenizer + Tokenizer::Tokenizer(std::string filename) { - private: - std::fstream file; - size_t prev_pos; - e_token last_token; - public: - Tokenizer(std::string filename) - { - file.open(filename.c_str(), std::ios::in); - if (!file.good()) - { - std::cerr << "file didn't open" << std::endl; - } - } - char getWithoutWhiteSpace(); - struct s_token getToken(); - bool hasMoreTokens(); - bool firstToken() - { - // doesn't account for indent! - if (file.tellg() == 0 || file.tellg() == 1 || (last_token == NEWLINE)) - return (true); - else - return (false); - } - void rollBackToken(); - }; - - char Tokenizer::getWithoutWhiteSpace(void) - { - char c = ' '; - while (config::isspace(c)) + file.open(filename.c_str(), std::ios::in); + if (!file.good()) { - file.get(c); - if ((c == ' ') && !file.good()) - { - throw std::logic_error("No more tokens!"); - } - else if (!file.good()) - return (c); + std::cerr << "file didn't open" << std::endl; } - return (c); } - - bool Tokenizer::hasMoreTokens(void) + bool Tokenizer::firstToken() { - return (!file.eof()); + // doesn't account for indent! + if (file.tellg() == 0 || file.tellg() == 1 || (last_token == NEWLINE)) + return (true); + else + return (false); } - void Tokenizer::rollBackToken(void) - { - if (file.eof()) - file.clear(); - file.seekg(prev_pos); - } - - /* struct s_token Tokenizer::getKey(void) */ - /* { */ - /* char c; */ - /* struct s_token token; */ - /* if (file.eof()) */ - /* { */ - /* std::cout << "Tokens exhausted" << std::endl; */ - /* } */ - /* } */ - struct s_token Tokenizer::getToken(void) { char c; @@ -240,6 +177,31 @@ namespace config last_token = token.type; return (token); } -} + char Tokenizer::getWithoutWhiteSpace(void) + { + char c = ' '; + while (config::isspace(c)) + { + file.get(c); + if ((c == ' ') && !file.good()) + { + throw std::logic_error("No more tokens!"); + } + else if (!file.good()) + return (c); + } + return (c); + } -#endif + bool Tokenizer::hasMoreTokens(void) + { + return (!file.eof()); + } + + void Tokenizer::rollBackToken(void) + { + if (file.eof()) + file.clear(); + file.seekg(prev_pos); + } +} diff --git a/src/config/parse.cpp b/src/config/parse.cpp index 90e806d..cc23801 100644 --- a/src/config/parse.cpp +++ b/src/config/parse.cpp @@ -6,10 +6,7 @@ #include #include -#include "TOMLNode.hpp" -#include "TOMLParser.hpp" -#include "Tokenizer.hpp" - +#include "parse.hpp" /* struct location */ /* { */ /* std::string location; */ diff --git a/src/main.cpp b/src/main.cpp index 1e42069..61388cc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include "webserv.hpp" +#include "parse.hpp" int main(int argc, char **argv) { From d9f3330440a809a79c3f7fff576136ee8e2e8dc5 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sat, 22 Jan 2022 14:07:54 +0300 Subject: [PATCH 05/10] refactor: token names and misc --- includes/Tokenizer.hpp | 4 +- src/config/TOMLParser.cpp | 668 +++++++++++++++++++------------------- src/config/Tokenizer.cpp | 4 +- 3 files changed, 342 insertions(+), 334 deletions(-) diff --git a/includes/Tokenizer.hpp b/includes/Tokenizer.hpp index 86de8f9..183332b 100644 --- a/includes/Tokenizer.hpp +++ b/includes/Tokenizer.hpp @@ -24,8 +24,8 @@ namespace config COMMA, BOOL, NIL, - ARR_OPEN, - ARR_CLOSE, + OPEN_BRACKET, + CLOSE_BRACKET, MAP_OPEN, MAP_CLOSE, MAPARRAY_DECL diff --git a/src/config/TOMLParser.cpp b/src/config/TOMLParser.cpp index f553e9b..ac61b05 100644 --- a/src/config/TOMLParser.cpp +++ b/src/config/TOMLParser.cpp @@ -22,357 +22,72 @@ /* return (*this); */ /* } */ -config::TOMLParser::TOMLParser(const std::string filename) : tokenizer(filename) -{}; - -toml_node *config::TOMLParser::parseMap(void) +namespace config { - std::cerr << "Parsing map" << std::endl; - toml_node *node = new toml_node; - TOMLMap *mapObject = new TOMLMap; - bool completed = false; - while (!completed) + + TOMLParser::TOMLParser(const std::string filename) : tokenizer(filename) + {}; + + toml_node *TOMLParser::parseMap(void) { - if (tokenizer.hasMoreTokens()) + std::cerr << "Parsing map" << std::endl; + toml_node *node = new toml_node; + TOMLMap *mapObject = new TOMLMap; + bool completed = false; + while (!completed) { - s_token nextToken; - try { nextToken = tokenizer.getToken(); } - catch (std::logic_error e) - { - std::cerr << e.what() << std::endl; - break; - } - if (nextToken.type == MAPARRAY_DECL) - { - tokenizer.rollBackToken(); - break; - } - std::string key = nextToken.value; - std::cerr << key << std::endl; - if (tokenizer.getToken().type != ASSIGN) - throw std::logic_error("EXPECTED assign!"); - nextToken = tokenizer.getToken(); - switch (nextToken.type) - { - case STRING: - { - tokenizer.rollBackToken(); - (*mapObject)[key] = parseString(); - break; - } - case ARR_OPEN: - { - (*mapObject)[key] = parseArray(); - break; - } - case NUMBER: - { - tokenizer.rollBackToken(); - (*mapObject)[key] = parseNumber(); - break; - } - case BOOL: - { - tokenizer.rollBackToken(); - (*mapObject)[key] = parseBool(); - break; - } - case MAPARRAY_DECL: - { - std::cerr << "reached MAPARRAY_DECL in parseMap" << std::endl; - completed = true; - break; - } - default: - { - /* throw std::logic_error("jopa in parseMap"); */ - std::cerr << "Unknown token, marking as complete" << std::endl; - completed = true; - break; - } - } if (tokenizer.hasMoreTokens()) - nextToken = tokenizer.getToken(); - else - break; - if (nextToken.type != NEWLINE) { - throw std::logic_error("EXPECTED newline"); - } - } - else - { - throw std::logic_error("parseMap: no more tokens"); - } - } - node->setObject(mapObject); - return (node); -} + s_token nextToken; + try { nextToken = tokenizer.getToken(); } + catch (std::logic_error e) + { + std::cerr << e.what() << std::endl; + break; + } + if (nextToken.type == MAPARRAY_DECL) + { + tokenizer.rollBackToken(); + break; + } + else if (nextToken.type == OPEN_BRACKET) + { -void config::TOMLParser::parseMapArray(void) -{ - - std::cerr << "Parsing MapArray" << std::endl; - toml_node *map_node; - toml_node *maparr_node; - s_token current; - - try { current = tokenizer.getToken(); } - catch (std::logic_error e) - { - std::cerr << e.what() << std::endl; - return; - } - if (current.type == MAPARRAY_DECL) - { - if (tokenizer.getToken().type != NEWLINE) - throw std::logic_error("no newline after map_array declaration"); - map_node = parseMap(); - } - else - throw std::logic_error("unexpected token in parseMapArray"); - - TOMLMap::iterator it; - std::cout << current.value << std::endl; - std::string name = current.value; - std::vector full_name; - size_t dot; - - while (1) - { - dot = name.find('.'); - if (dot == std::string::npos) - break; - /* std::cout << dot << std::endl; */ - full_name.push_back(name.substr(0, dot)); - name.erase(0, dot + 1); - } - full_name.push_back(name); - - for (size_t i = 0; i < full_name.size(); i++) - std::cout << full_name[i] << ", "; - std::cout << std::endl; - - /* throw std::logic_error("tha end"); */ - TOMLMap *local_root; - - std::vector::iterator subname = full_name.begin(); - local_root = root; - while (1) - { - if (subname + 1 == full_name.end()) - { - it = local_root->find(*subname); - if (it == local_root->end()) - { - maparr_node = new toml_node; - TOMLMapArray *map_array = new TOMLMapArray; - map_array->push_back(map_node->getMap()); - maparr_node->setMapArray(map_array); - (*local_root)[*subname] = maparr_node; - } - else - (it->second)->getMapArray()->push_back(map_node->getMap()); - break; - } - else - { - it = local_root->find(*subname); - - toml_node *map_node2; - map_node2 = new toml_node; - TOMLMap *map = new TOMLMap; - map_node2->setObject(map); - /* subname not found in local_root */ - if (it == local_root->end()) - { - (*local_root)[*subname] = map_node2; - local_root = map; - } - /* subname found in local_root */ - else - { - local_root = *((it->second)->getMapArray()->end() - 1); - } - - } - ++subname; - } - -} - -toml_node *config::TOMLParser::parseString(void) -{ - /* toml_node *node; */ - toml_node *node = new toml_node; - std::string *sValue; - - std::cerr << "Parsing string" << std::endl; - s_token token = tokenizer.getToken(); - sValue = new std::string(token.value); - node->setString(sValue); - - return (node); -} - -toml_node *config::TOMLParser::parseNumber(void) -{ - toml_node *node = new toml_node; - int value; - - std::cerr << "Parsing number" << std::endl; - s_token token = tokenizer.getToken(); - value = std::atoi(token.value.c_str()); - node->setNumber(value); - - return (node); -} - -toml_node *config::TOMLParser::parseArray(void) -{ - std::cerr << "Parsing array" << std::endl; - toml_node *node; - toml_node *result = new toml_node; - TOMLArray *array = new TOMLArray; - bool completed = false; - s_token current; - - while (!completed) - { - if (!tokenizer.hasMoreTokens()) - throw std::logic_error("No more tokens"); - else - { - current = tokenizer.getToken(); - switch (current.type) - { - case ARR_OPEN: - { - node = parseArray(); - break; - } - case STRING: - { - tokenizer.rollBackToken(); - node = parseString(); - break; - } - case NUMBER: - { - tokenizer.rollBackToken(); - node = parseNumber(); - break; - } - case BOOL: - { - tokenizer.rollBackToken(); - node = parseBool(); - break; - } - case NIL: - { - node = parseNil(); - break; - } - default: - { - throw std::logic_error("unkown token in parseArray"); - } - - } - array->push_back(node); - current = tokenizer.getToken(); - if (current.type == COMMA) - continue; - else if (current.type == ARR_CLOSE) - completed = true; - else - throw std::invalid_argument("Unexpected token in array!"); - } - } - result->setArr(array); - return (result); -} - -toml_node *config::TOMLParser::parseBool(void) -{ - toml_node *node = new toml_node; - bool value; - - std::cerr << "Parsing bool" << std::endl; - s_token token = tokenizer.getToken(); - if (token.value == "true") - value = true; - else if (token.value == "false") - value = false; - else - throw std::invalid_argument("Unexpected bool value"); - node->setBool(value); - - return (node); -} - -toml_node *config::TOMLParser::parseNil(void) -{ - toml_node *node = new toml_node; - std::cerr << "Parsing NIL" << std::endl; - node->setNil(); - return (node); -} - -/* parse tha root ! */ -TOMLMap *config::TOMLParser::parse(void) -{ - std::cerr << "Parsing ROOT" << std::endl; - root = new TOMLMap; - bool completed = false; - while (!completed) - { - if (tokenizer.hasMoreTokens()) - { - s_token current; - try { current = tokenizer.getToken(); } - catch (std::logic_error e) - { - std::cerr << e.what() << std::endl; - break; - } - if (current.type == MAPARRAY_DECL) - { - /* parseMapArray(); */ - tokenizer.rollBackToken(); - parseMapArray(); - } - else - { - std::string key = current.value; + } + std::string key = nextToken.value; std::cerr << key << std::endl; if (tokenizer.getToken().type != ASSIGN) throw std::logic_error("EXPECTED assign!"); - current = tokenizer.getToken(); - switch (current.type) + nextToken = tokenizer.getToken(); + switch (nextToken.type) { case STRING: { tokenizer.rollBackToken(); - (*root)[key] = parseString(); + (*mapObject)[key] = parseString(); break; } - case ARR_OPEN: + case OPEN_BRACKET: { - (*root)[key] = parseArray(); + (*mapObject)[key] = parseArray(); break; } case NUMBER: { tokenizer.rollBackToken(); - (*root)[key] = parseNumber(); + (*mapObject)[key] = parseNumber(); break; } case BOOL: { tokenizer.rollBackToken(); - (*root)[key] = parseBool(); + (*mapObject)[key] = parseBool(); + break; + } + case MAPARRAY_DECL: + { + std::cerr << "reached MAPARRAY_DECL in parseMap" << std::endl; + completed = true; break; } default: @@ -384,20 +99,313 @@ TOMLMap *config::TOMLParser::parse(void) } } if (tokenizer.hasMoreTokens()) - current = tokenizer.getToken(); + nextToken = tokenizer.getToken(); else break; - if (current.type != NEWLINE) + if (nextToken.type != NEWLINE) { throw std::logic_error("EXPECTED newline"); } } + else + { + throw std::logic_error("parseMap: no more tokens"); + } + } + node->setObject(mapObject); + return (node); + } + + void TOMLParser::parseMapArray(void) + { + + std::cerr << "Parsing MapArray" << std::endl; + toml_node *map_node; + toml_node *maparr_node; + s_token current; + + try { current = tokenizer.getToken(); } + catch (std::logic_error e) + { + std::cerr << e.what() << std::endl; + return; + } + if (current.type == MAPARRAY_DECL) + { + if (tokenizer.getToken().type != NEWLINE) + throw std::logic_error("no newline after map_array declaration"); + map_node = parseMap(); } else + throw std::logic_error("unexpected token in parseMapArray"); + + TOMLMap::iterator it; + std::cout << current.value << std::endl; + std::string name = current.value; + std::vector full_name; + size_t dot; + + while (1) { - completed = true; - break; + dot = name.find('.'); + if (dot == std::string::npos) + break; + /* std::cout << dot << std::endl; */ + full_name.push_back(name.substr(0, dot)); + name.erase(0, dot + 1); } + full_name.push_back(name); + + for (size_t i = 0; i < full_name.size(); i++) + std::cout << full_name[i] << ", "; + std::cout << std::endl; + + /* throw std::logic_error("tha end"); */ + TOMLMap *local_root; + + std::vector::iterator subname = full_name.begin(); + local_root = root; + while (1) + { + if (subname + 1 == full_name.end()) + { + it = local_root->find(*subname); + if (it == local_root->end()) + { + maparr_node = new toml_node; + TOMLMapArray *map_array = new TOMLMapArray; + map_array->push_back(map_node->getMap()); + maparr_node->setMapArray(map_array); + (*local_root)[*subname] = maparr_node; + } + else + (it->second)->getMapArray()->push_back(map_node->getMap()); + break; + } + else + { + it = local_root->find(*subname); + + toml_node *map_node2; + map_node2 = new toml_node; + TOMLMap *map = new TOMLMap; + map_node2->setObject(map); + /* subname not found in local_root */ + if (it == local_root->end()) + { + (*local_root)[*subname] = map_node2; + local_root = map; + } + /* subname found in local_root */ + else + { + local_root = *((it->second)->getMapArray()->end() - 1); + } + + } + ++subname; + } + + } + + toml_node *TOMLParser::parseString(void) + { + /* toml_node *node; */ + toml_node *node = new toml_node; + std::string *sValue; + + std::cerr << "Parsing string" << std::endl; + s_token token = tokenizer.getToken(); + sValue = new std::string(token.value); + node->setString(sValue); + + return (node); + } + + toml_node *TOMLParser::parseNumber(void) + { + toml_node *node = new toml_node; + int value; + + std::cerr << "Parsing number" << std::endl; + s_token token = tokenizer.getToken(); + value = std::atoi(token.value.c_str()); + node->setNumber(value); + + return (node); + } + + toml_node *TOMLParser::parseArray(void) + { + std::cerr << "Parsing array" << std::endl; + toml_node *node; + toml_node *result = new toml_node; + TOMLArray *array = new TOMLArray; + bool completed = false; + s_token current; + + while (!completed) + { + if (!tokenizer.hasMoreTokens()) + throw std::logic_error("No more tokens"); + else + { + current = tokenizer.getToken(); + switch (current.type) + { + case OPEN_BRACKET: + { + node = parseArray(); + break; + } + case STRING: + { + tokenizer.rollBackToken(); + node = parseString(); + break; + } + case NUMBER: + { + tokenizer.rollBackToken(); + node = parseNumber(); + break; + } + case BOOL: + { + tokenizer.rollBackToken(); + node = parseBool(); + break; + } + case NIL: + { + node = parseNil(); + break; + } + default: + { + throw std::logic_error("unkown token in parseArray"); + } + + } + array->push_back(node); + current = tokenizer.getToken(); + if (current.type == COMMA) + continue; + else if (current.type == CLOSE_BRACKET) + completed = true; + else + throw std::invalid_argument("Unexpected token in array!"); + } + } + result->setArr(array); + return (result); + } + + toml_node *TOMLParser::parseBool(void) + { + toml_node *node = new toml_node; + bool value; + + std::cerr << "Parsing bool" << std::endl; + s_token token = tokenizer.getToken(); + if (token.value == "true") + value = true; + else if (token.value == "false") + value = false; + else + throw std::invalid_argument("Unexpected bool value"); + node->setBool(value); + + return (node); + } + + toml_node *TOMLParser::parseNil(void) + { + toml_node *node = new toml_node; + std::cerr << "Parsing NIL" << std::endl; + node->setNil(); + return (node); + } + + /* parse tha root ! */ + TOMLMap *TOMLParser::parse(void) + { + std::cerr << "Parsing ROOT" << std::endl; + root = new TOMLMap; + bool completed = false; + while (!completed) + { + if (tokenizer.hasMoreTokens()) + { + s_token current; + try { current = tokenizer.getToken(); } + catch (std::logic_error e) + { + std::cerr << e.what() << std::endl; + break; + } + if (current.type == MAPARRAY_DECL) + { + /* parseMapArray(); */ + tokenizer.rollBackToken(); + parseMapArray(); + } + else + { + std::string key = current.value; + std::cerr << key << std::endl; + if (tokenizer.getToken().type != ASSIGN) + throw std::logic_error("EXPECTED assign!"); + current = tokenizer.getToken(); + switch (current.type) + { + case STRING: + { + tokenizer.rollBackToken(); + (*root)[key] = parseString(); + break; + } + case OPEN_BRACKET: + { + (*root)[key] = parseArray(); + break; + } + case NUMBER: + { + tokenizer.rollBackToken(); + (*root)[key] = parseNumber(); + break; + } + case BOOL: + { + tokenizer.rollBackToken(); + (*root)[key] = parseBool(); + break; + } + default: + { + /* throw std::logic_error("jopa in parseMap"); */ + std::cerr << "Unknown token, marking as complete" << std::endl; + completed = true; + break; + } + } + if (tokenizer.hasMoreTokens()) + current = tokenizer.getToken(); + else + break; + if (current.type != NEWLINE) + { + throw std::logic_error("EXPECTED newline"); + } + } + } + else + { + completed = true; + break; + } + } + return (root); } - return (root); } diff --git a/src/config/Tokenizer.cpp b/src/config/Tokenizer.cpp index c52fd1d..9b75ec5 100644 --- a/src/config/Tokenizer.cpp +++ b/src/config/Tokenizer.cpp @@ -108,13 +108,13 @@ namespace config } else { - token.type = ARR_OPEN; + token.type = OPEN_BRACKET; file.seekg(prev_pos); } } else if (c == ']') - token.type = ARR_CLOSE; + token.type = CLOSE_BRACKET; else if (c == '=') token.type = ASSIGN; else if (c == '\n') From 24e49f63e82701fe05b98e55dff0120ca0c7cc07 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sat, 22 Jan 2022 18:10:02 +0300 Subject: [PATCH 06/10] refactor: add helper parser funcs --- includes/TOMLParser.hpp | 4 ++ src/config/TOMLParser.cpp | 137 +++++++++++++++++++++----------------- 2 files changed, 81 insertions(+), 60 deletions(-) diff --git a/includes/TOMLParser.hpp b/includes/TOMLParser.hpp index e06e41a..6cc5c8a 100644 --- a/includes/TOMLParser.hpp +++ b/includes/TOMLParser.hpp @@ -16,6 +16,10 @@ namespace config TOMLMap *root; //root of TOML tree /* toml_node *current; //node currently being parsed */ Tokenizer tokenizer; + static std::vector split_name(std::string name); + static void put_to_subtable(TOMLMap *root, + std::vector full_name, + toml_node *map_node); public: TOMLParser(const std::string filename); diff --git a/src/config/TOMLParser.cpp b/src/config/TOMLParser.cpp index ac61b05..b07d220 100644 --- a/src/config/TOMLParser.cpp +++ b/src/config/TOMLParser.cpp @@ -121,7 +121,6 @@ namespace config std::cerr << "Parsing MapArray" << std::endl; toml_node *map_node; - toml_node *maparr_node; s_token current; try { current = tokenizer.getToken(); } @@ -143,68 +142,11 @@ namespace config std::cout << current.value << std::endl; std::string name = current.value; std::vector full_name; - size_t dot; - while (1) - { - dot = name.find('.'); - if (dot == std::string::npos) - break; - /* std::cout << dot << std::endl; */ - full_name.push_back(name.substr(0, dot)); - name.erase(0, dot + 1); - } - full_name.push_back(name); - - for (size_t i = 0; i < full_name.size(); i++) - std::cout << full_name[i] << ", "; - std::cout << std::endl; + full_name = split_name(name); /* throw std::logic_error("tha end"); */ - TOMLMap *local_root; - - std::vector::iterator subname = full_name.begin(); - local_root = root; - while (1) - { - if (subname + 1 == full_name.end()) - { - it = local_root->find(*subname); - if (it == local_root->end()) - { - maparr_node = new toml_node; - TOMLMapArray *map_array = new TOMLMapArray; - map_array->push_back(map_node->getMap()); - maparr_node->setMapArray(map_array); - (*local_root)[*subname] = maparr_node; - } - else - (it->second)->getMapArray()->push_back(map_node->getMap()); - break; - } - else - { - it = local_root->find(*subname); - - toml_node *map_node2; - map_node2 = new toml_node; - TOMLMap *map = new TOMLMap; - map_node2->setObject(map); - /* subname not found in local_root */ - if (it == local_root->end()) - { - (*local_root)[*subname] = map_node2; - local_root = map; - } - /* subname found in local_root */ - else - { - local_root = *((it->second)->getMapArray()->end() - 1); - } - - } - ++subname; - } + put_to_subtable(root, full_name, map_node); } @@ -408,4 +350,79 @@ namespace config } return (root); } + + std::vector TOMLParser::split_name(std::string name) + { + std::vector full_name; + size_t dot; + + while (1) + { + dot = name.find('.'); + if (dot == std::string::npos) + break; + /* std::cout << dot << std::endl; */ + full_name.push_back(name.substr(0, dot)); + name.erase(0, dot + 1); + } + full_name.push_back(name); + + for (size_t i = 0; i < full_name.size(); i++) + std::cout << full_name[i] << ", "; + std::cout << std::endl; + + return (full_name); + } + + void TOMLParser::put_to_subtable(TOMLMap *root, + std::vector full_name, + toml_node *map_node) + { + std::vector::iterator subname = full_name.begin(); + toml_node *maparr_node; + TOMLMap::iterator it; + + TOMLMap *local_root = root; + + while (1) + { + if (subname + 1 == full_name.end()) + { + it = local_root->find(*subname); + if (it == local_root->end()) + { + maparr_node = new toml_node; + TOMLMapArray *map_array = new TOMLMapArray; + map_array->push_back(map_node->getMap()); + maparr_node->setMapArray(map_array); + (*local_root)[*subname] = maparr_node; + } + else + (it->second)->getMapArray()->push_back(map_node->getMap()); + break; + } + else + { + it = local_root->find(*subname); + + toml_node *map_node2; + map_node2 = new toml_node; + TOMLMap *map = new TOMLMap; + map_node2->setObject(map); + /* subname not found in local_root */ + if (it == local_root->end()) + { + (*local_root)[*subname] = map_node2; + local_root = map; + } + /* subname found in local_root */ + else + { + local_root = *((it->second)->getMapArray()->end() - 1); + } + + } + ++subname; + } + } } From 3b2469b130eedc6c7df8fa84511fec51cfeff189 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sat, 22 Jan 2022 18:11:29 +0300 Subject: [PATCH 07/10] fix: reset last token when needed --- includes/Tokenizer.hpp | 1 + src/config/TOMLParser.cpp | 2 ++ src/config/Tokenizer.cpp | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/includes/Tokenizer.hpp b/includes/Tokenizer.hpp index 183332b..2adb4ca 100644 --- a/includes/Tokenizer.hpp +++ b/includes/Tokenizer.hpp @@ -56,6 +56,7 @@ namespace config bool hasMoreTokens(); bool firstToken(); void rollBackToken(); + void set_last(e_token type); }; diff --git a/src/config/TOMLParser.cpp b/src/config/TOMLParser.cpp index b07d220..cdb7449 100644 --- a/src/config/TOMLParser.cpp +++ b/src/config/TOMLParser.cpp @@ -48,6 +48,7 @@ namespace config if (nextToken.type == MAPARRAY_DECL) { tokenizer.rollBackToken(); + tokenizer.set_last(NEWLINE); break; } else if (nextToken.type == OPEN_BRACKET) @@ -289,6 +290,7 @@ namespace config if (current.type == MAPARRAY_DECL) { /* parseMapArray(); */ + tokenizer.set_last(NEWLINE); tokenizer.rollBackToken(); parseMapArray(); } diff --git a/src/config/Tokenizer.cpp b/src/config/Tokenizer.cpp index 9b75ec5..5ad54ba 100644 --- a/src/config/Tokenizer.cpp +++ b/src/config/Tokenizer.cpp @@ -204,4 +204,9 @@ namespace config file.clear(); file.seekg(prev_pos); } + + void Tokenizer::set_last(e_token type) + { + last_token = type; + } } From d9b66c8795c4470138be6d000e108779537d05d0 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sun, 23 Jan 2022 13:50:12 +0300 Subject: [PATCH 08/10] feat: working subtables --- includes/TOMLParser.hpp | 4 +- includes/Tokenizer.hpp | 3 +- src/config/TOMLParser.cpp | 88 +++++++++++++++++++++++++++++++-------- src/config/Tokenizer.cpp | 21 +++++++--- 4 files changed, 90 insertions(+), 26 deletions(-) diff --git a/includes/TOMLParser.hpp b/includes/TOMLParser.hpp index 6cc5c8a..1be4c2a 100644 --- a/includes/TOMLParser.hpp +++ b/includes/TOMLParser.hpp @@ -16,16 +16,18 @@ namespace config TOMLMap *root; //root of TOML tree /* toml_node *current; //node currently being parsed */ Tokenizer tokenizer; + static std::vector split_name(std::string name); static void put_to_subtable(TOMLMap *root, std::vector full_name, - toml_node *map_node); + toml_node *map_node, toml_node::e_type type); public: TOMLParser(const std::string filename); TOMLMap *parse(void); toml_node *parseMap(void); + void processMap(void); void parseMapArray(void); diff --git a/includes/Tokenizer.hpp b/includes/Tokenizer.hpp index 2adb4ca..eec6321 100644 --- a/includes/Tokenizer.hpp +++ b/includes/Tokenizer.hpp @@ -26,8 +26,7 @@ namespace config NIL, OPEN_BRACKET, CLOSE_BRACKET, - MAP_OPEN, - MAP_CLOSE, + MAP_DECL, MAPARRAY_DECL }; diff --git a/src/config/TOMLParser.cpp b/src/config/TOMLParser.cpp index cdb7449..f77924b 100644 --- a/src/config/TOMLParser.cpp +++ b/src/config/TOMLParser.cpp @@ -28,6 +28,37 @@ namespace config TOMLParser::TOMLParser(const std::string filename) : tokenizer(filename) {}; + void TOMLParser::processMap(void) + { + std::cerr << "Processing map" << std::endl; + toml_node *map_node; + s_token current; + + try { current = tokenizer.getToken(); } + catch (std::logic_error e) + { + std::cerr << e.what() << std::endl; + return; + } + if (current.type == MAP_DECL) + { + if (tokenizer.getToken().type != NEWLINE) + throw std::logic_error("no newline after MAP_DECL"); + map_node = parseMap(); + } + else + throw std::logic_error("unexpected token in processMap"); + + std::cout << current.value << std::endl; + + std::vector full_name; + + full_name = split_name(current.value); + + put_to_subtable(root, full_name, map_node, toml_node::MAP); + + } + toml_node *TOMLParser::parseMap(void) { std::cerr << "Parsing map" << std::endl; @@ -51,9 +82,11 @@ namespace config tokenizer.set_last(NEWLINE); break; } - else if (nextToken.type == OPEN_BRACKET) + else if (nextToken.type == MAP_DECL) { - + tokenizer.rollBackToken(); + tokenizer.set_last(NEWLINE); + break; } std::string key = nextToken.value; std::cerr << key << std::endl; @@ -139,15 +172,13 @@ namespace config else throw std::logic_error("unexpected token in parseMapArray"); - TOMLMap::iterator it; std::cout << current.value << std::endl; - std::string name = current.value; + std::vector full_name; - full_name = split_name(name); + full_name = split_name(current.value); - /* throw std::logic_error("tha end"); */ - put_to_subtable(root, full_name, map_node); + put_to_subtable(root, full_name, map_node, toml_node::MAPARRAY); } @@ -294,6 +325,17 @@ namespace config tokenizer.rollBackToken(); parseMapArray(); } + else if (current.type == MAP_DECL) + { + std::cerr << "MAP_DECL value: " << current.value << std::endl; + tokenizer.set_last(NEWLINE); + tokenizer.rollBackToken(); + /* if (tokenizer.getToken().type != NEWLINE) */ + /* throw std::logic_error("no newline after MAP_DECL"); */ + /* (*mapObject)[nextToken.value] = parseMap(); */ + processMap(); + continue; + } else { std::string key = current.value; @@ -378,7 +420,7 @@ namespace config void TOMLParser::put_to_subtable(TOMLMap *root, std::vector full_name, - toml_node *map_node) + toml_node *map_node, toml_node::e_type type) { std::vector::iterator subname = full_name.begin(); toml_node *maparr_node; @@ -391,16 +433,28 @@ namespace config if (subname + 1 == full_name.end()) { it = local_root->find(*subname); - if (it == local_root->end()) + if (type == toml_node::MAPARRAY) { - maparr_node = new toml_node; - TOMLMapArray *map_array = new TOMLMapArray; - map_array->push_back(map_node->getMap()); - maparr_node->setMapArray(map_array); - (*local_root)[*subname] = maparr_node; + if (it == local_root->end()) + { + maparr_node = new toml_node; + TOMLMapArray *map_array = new TOMLMapArray; + map_array->push_back(map_node->getMap()); + maparr_node->setMapArray(map_array); + (*local_root)[*subname] = maparr_node; + } + else + (it->second)->getMapArray()->push_back(map_node->getMap()); + } + else if (type == toml_node::MAP) + { + if (it == local_root->end()) + { + (*local_root)[*subname] = map_node; + } + else + throw std::logic_error("map already in subtable!"); } - else - (it->second)->getMapArray()->push_back(map_node->getMap()); break; } else @@ -419,9 +473,7 @@ namespace config } /* subname found in local_root */ else - { local_root = *((it->second)->getMapArray()->end() - 1); - } } ++subname; diff --git a/src/config/Tokenizer.cpp b/src/config/Tokenizer.cpp index 5ad54ba..4d6f9c8 100644 --- a/src/config/Tokenizer.cpp +++ b/src/config/Tokenizer.cpp @@ -88,9 +88,9 @@ namespace config file.get(c); } } - else if (c == '[') + else if (c == '[' && firstToken()) { - std::streampos prev_pos = file.tellg(); + /* std::streampos prev_pos = file.tellg(); */ file.get(c); if (c == '[') { @@ -108,10 +108,21 @@ namespace config } else { - token.type = OPEN_BRACKET; - file.seekg(prev_pos); + token.type = MAP_DECL; + token.value += c; + file.get(c); + while (c != ']') + { + token.value += c; + file.get(c); + } + if (c != ']') + throw std::logic_error("malformed MAP_DECL"); } - + } + else if (c == '[') + { + token.type = OPEN_BRACKET; } else if (c == ']') token.type = CLOSE_BRACKET; From 2e51c43967dc10954fbde035f9b938008140bf53 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sun, 23 Jan 2022 13:50:32 +0300 Subject: [PATCH 09/10] feat: error_page as subtable --- config/simple.toml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/config/simple.toml b/config/simple.toml index 4abbf7d..31d9ecb 100644 --- a/config/simple.toml +++ b/config/simple.toml @@ -2,8 +2,9 @@ name = "serv1" host = "127.0.0.1" port = 8080 - error_page = "error.html" body_size_limit = 10 + [server.error_page] + 404 = "error_404.html" [[server.location]] location = "/" root = "/var/www/html/jopa.html" @@ -22,8 +23,12 @@ name = "2222" host = "10.0.0.1" port = 8081 - error_page = "error2.html" body_size_limit = 10 + [server.error_page] + 404 = "error_404.html" + 405 = "error_405.html" + 406 = "error_406.html" + 407 = "error_407.html" [[server.location]] location = "/root2/" root = "/var/www/html/jopa.html" From 1dcd3f6d366ebc887accda8a667ba1adee39e6fc Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sun, 23 Jan 2022 13:54:08 +0300 Subject: [PATCH 10/10] refactor: parseMapArray -> processMapArray --- includes/TOMLParser.hpp | 2 +- src/config/TOMLParser.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/includes/TOMLParser.hpp b/includes/TOMLParser.hpp index 1be4c2a..114fe4f 100644 --- a/includes/TOMLParser.hpp +++ b/includes/TOMLParser.hpp @@ -29,7 +29,7 @@ namespace config toml_node *parseMap(void); void processMap(void); - void parseMapArray(void); + void processMapArray(void); toml_node *parseString(void); diff --git a/src/config/TOMLParser.cpp b/src/config/TOMLParser.cpp index f77924b..e8b0b1b 100644 --- a/src/config/TOMLParser.cpp +++ b/src/config/TOMLParser.cpp @@ -150,7 +150,7 @@ namespace config return (node); } - void TOMLParser::parseMapArray(void) + void TOMLParser::processMapArray(void) { std::cerr << "Parsing MapArray" << std::endl; @@ -170,7 +170,7 @@ namespace config map_node = parseMap(); } else - throw std::logic_error("unexpected token in parseMapArray"); + throw std::logic_error("unexpected token in processMapArray"); std::cout << current.value << std::endl; @@ -320,10 +320,10 @@ namespace config } if (current.type == MAPARRAY_DECL) { - /* parseMapArray(); */ + /* processMapArray(); */ tokenizer.set_last(NEWLINE); tokenizer.rollBackToken(); - parseMapArray(); + processMapArray(); } else if (current.type == MAP_DECL) {