diff --git a/config/simple.toml b/config/simple.toml new file mode 100644 index 0000000..0f96880 --- /dev/null +++ b/config/simple.toml @@ -0,0 +1,2 @@ +name = "jopa" +port = 6969 diff --git a/src/config/TOMLNode.hpp b/src/config/TOMLNode.hpp index 52e04e7..0273ac7 100644 --- a/src/config/TOMLNode.hpp +++ b/src/config/TOMLNode.hpp @@ -8,6 +8,8 @@ #include #include #include +#include +#include @@ -33,6 +35,12 @@ class toml_node } value; public: + + enum e_type get_type(void) + { + return (type); + } + TOMLMap *getMap(void) { return (value.map); @@ -68,6 +76,26 @@ class toml_node value.map = obj; type = MAP; } + 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); + } + default: + return ( new std::string("Not implemented :)")); + } + } }; #endif diff --git a/src/config/TOMLParser.hpp b/src/config/TOMLParser.hpp index b1f8efa..1c52704 100644 --- a/src/config/TOMLParser.hpp +++ b/src/config/TOMLParser.hpp @@ -19,7 +19,7 @@ namespace config TOMLParser(const std::string filename) : tokenizer(filename) {} toml_node *parse(void); - toml_node *parseObject(void) + toml_node *parseMap(void) { std::cout << "Parsing object" << std::endl; toml_node *node = new toml_node; @@ -29,10 +29,20 @@ namespace config { if (tokenizer.hasMoreTokens()) { - s_token nextToken = tokenizer.getToken(); + s_token nextToken; + try + { + nextToken = tokenizer.getToken(); + } + catch (std::logic_error e) + { + std::cerr << e.what() << std::endl; + break; + } std::string key = nextToken.value; std::cout << key << std::endl; - tokenizer.getToken(); + if (tokenizer.getToken().type != ASSIGN) + throw std::logic_error("EXPECTED assign!"); nextToken = tokenizer.getToken(); switch (nextToken.type) { @@ -49,6 +59,7 @@ namespace config } case NUMBER: { + tokenizer.rollBackToken(); (*mapObject)[key] = parseNumber(); break; } @@ -59,16 +70,28 @@ namespace config } default: { - /* throw std::logic_error("jopa in parseObject"); */ + /* 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"); + } + /* if (tokenizer.getToken().type == NEWLINE) */ + /* completed = true; */ + /* else */ + /* throw std::logic_error("EXPECTED newline"); */ } else { - throw std::logic_error("parseObject: no more tokens"); + throw std::logic_error("parseMap: no more tokens"); } } node->setObject(mapObject); @@ -194,6 +217,9 @@ namespace config std::string key; key = ""; + root = parseMap(); + return (root); + while (tokenizer.hasMoreTokens()) { s_token token; @@ -203,42 +229,49 @@ namespace config /* std::cout << token.to_string() << std::endl; */ switch (token.type) { + case KEY: + { + toml_node *parsedObject = parseString(); + if (!root) + root = parsedObject; + } + case ARR_OPEN: - { - toml_node *parsedObject = parseObject(); - /* parsedObject->printNode(0); */ - if (!root) - root = parsedObject; - } - break; + { + toml_node *parsedObject = parseMap(); + /* parsedObject->printNode(0); */ + if (!root) + root = parsedObject; + } + break; case NUMBER: - { - tokenizer.rollBackToken(); - toml_node *parsedNumber = parseNumber(); - if (!root) - root = parsedNumber; - } - break; + { + tokenizer.rollBackToken(); + toml_node *parsedNumber = parseNumber(); + if (!root) + root = parsedNumber; + } + break; case STRING: - { - tokenizer.rollBackToken(); - toml_node *parsedString = parseString(); - if (!root) - root = parsedString; - } - break; + { + tokenizer.rollBackToken(); + toml_node *parsedString = parseString(); + if (!root) + root = parsedString; + } + break; case BOOL: - { - tokenizer.rollBackToken(); - toml_node *parsedBool = parseBool(); - if (!root) - root = parsedBool; - } - break; + { + tokenizer.rollBackToken(); + toml_node *parsedBool = parseBool(); + if (!root) + root = parsedBool; + } + break; default: - { - throw std::logic_error("JOPA :("); - } + { + throw std::logic_error("JOPA :("); + } } } catch (std::logic_error err) diff --git a/src/config/Tokenizer.hpp b/src/config/Tokenizer.hpp index c2f21c5..76acd5e 100644 --- a/src/config/Tokenizer.hpp +++ b/src/config/Tokenizer.hpp @@ -13,6 +13,8 @@ namespace config { enum e_token { + KEY, + NEWLINE, ASSIGN, STRING, NUMBER, @@ -34,11 +36,20 @@ namespace config /* std::string to_string(void); */ }; + bool istomlkey(char c) + { + if (isalnum(c) || c == '-' || c == '_') + return (true); + else + return (false); + } + class Tokenizer { private: std::fstream file; size_t prev_pos; + e_token last_token; public: Tokenizer(std::string filename) { @@ -51,16 +62,24 @@ namespace config 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 ((c == ' ' || c == '\n')) + while (c == ' ') { file.get(c); - if ((c == ' ' || c == '\n') && !file.good()) + if ((c == ' ') && !file.good()) { throw std::logic_error("No more tokens!"); } @@ -82,6 +101,16 @@ namespace config 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; @@ -94,7 +123,16 @@ namespace config prev_pos = file.tellg(); c = getWithoutWhiteSpace(); - if (c == '"') + if (firstToken() && config::istomlkey(c)) + { + token.type = KEY; + while (config::istomlkey(c)) + { + token.value += c; + file.get(c); + } + } + else if (c == '"') { token.type = STRING; token.value = ""; @@ -112,6 +150,8 @@ namespace config token.type = ARR_CLOSE; else if (c == '=') token.type = ASSIGN; + else if (c == '\n') + token.type = NEWLINE; else if (c == '-' || isdigit(c)) { std::streampos prevCharPos; @@ -154,6 +194,7 @@ namespace config } else if (c == ',') token.type = COMMA; + last_token = token.type; return (token); } } diff --git a/src/config/parse.cpp b/src/config/parse.cpp index 7fece02..bd63071 100644 --- a/src/config/parse.cpp +++ b/src/config/parse.cpp @@ -26,8 +26,8 @@ namespace config void display(TOMLMap *config) { std::cout << "printing config:" << std::endl; - std::cout << (*config)["name"] << std::endl; - std::cout << (*config)["port"] << std::endl; + std::cout << "name: " << *(*config)["name"]->toString() << std::endl; + std::cout << "port: " << *(*config)["port"]->toString() << std::endl; } } diff --git a/src/main.cpp b/src/main.cpp index 2504e23..1e42069 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,9 +7,10 @@ int main(int argc, char **argv) Server server; - server.readConfig(); - server.setupConfig(); - server.start(); + /* server.readConfig(); */ + /* server.setupConfig(); */ + /* server.start(); */ + parse(); return (0); }