/*********************************/ /* */ /* o.riabenkyi@gmain.com */ /* */ /*********************************/ #ifndef CONFIGURATIONPARSER_HPP #define CONFIGURATIONPARSER_HPP #include #include #include #include "Config.hpp" #include "LocationConfig.hpp" #include "ServerConfig.hpp" // Reads a webserv configuration file and turns it into a validated Config. // // Syntax (see webserv_design_notes.md): // - one logical line is exactly one syntactic unit: a block opener // ("server {" / "location /path {"), a lone closing "}", or a single // directive followed by its values // - '#' starts a comment that runs to the end of the line, stripped // before tokenizing // - there is no ';' terminator - a directive's values are simply the // remaining tokens on its line // - a closing "}" must appear alone on its own line class ConfigurationParser { public: ConfigurationParser(); ~ConfigurationParser(); // Reads the file at `path`, parses it and returns a validated Config. // Throws std::runtime_error on any syntax or validation error. Config parse(const std::string &path); private: std::vector > _lines; size_t _pos; std::string readFile(const std::string &path) const; void tokenizeLines(const std::string &content); static std::string stripComment(const std::string &line); static std::vector splitTokens(const std::string &line); static std::string joinTokens(const std::vector &tokens); bool hasNext() const; const std::vector &peek() const; std::vector next(); ServerConfig parseServerBlock(); LocationConfig parseLocationBlock(const std::string &path); void applyServerDirective(ServerConfig &server, const std::string &name, const std::vector &values); void applyLocationDirective(LocationConfig &location, const std::string &name, const std::vector &values); static int toInt(const std::string &s); static size_t parseSize(const std::string &s); ConfigurationParser(const ConfigurationParser &other); ConfigurationParser &operator=(const ConfigurationParser &other); }; #endif