# HG changeset patch # User David Demelier # Date 1506439127 -7200 # Node ID 7e273b7f4f9269be9020abb68021aa5508320f8f # Parent beb6c638b841f878d1b2b634dff56c54139e8206 Irccd: new coding style, closes #576 diff -r beb6c638b841 -r 7e273b7f4f92 irccd/main.cpp --- a/irccd/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/irccd/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -44,18 +44,18 @@ #include "irccd.hpp" #if defined(WITH_JS) -# include "mod-directory.hpp" -# include "mod-elapsed-timer.hpp" -# include "mod-file.hpp" -# include "mod-irccd.hpp" -# include "mod-logger.hpp" -# include "mod-plugin.hpp" -# include "mod-server.hpp" -# include "mod-system.hpp" -# include "mod-timer.hpp" -# include "mod-unicode.hpp" -# include "mod-util.hpp" -# include "plugin-js.hpp" +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include "js_plugin.hpp" #endif using namespace fmt::literals; @@ -64,11 +64,11 @@ namespace { -std::unique_ptr instance; +std::unique_ptr instance; void usage() { - std::cerr << "usage: " << sys::programName() << " [options...]\n\n"; + std::cerr << "usage: " << sys::program_name() << " [options...]\n\n"; std::cerr << "Available options:\n"; std::cerr << " -c, --config file specify the configuration file\n"; std::cerr << " -f, --foreground do not run as a daemon\n"; @@ -78,7 +78,7 @@ std::exit(1); } -void version(const option::Result &options) +void version(const option::Result& options) { std::cout << IRCCD_VERSION << std::endl; @@ -106,13 +106,13 @@ instance->stop(); } -void init(int &argc, char **&argv) +void init(int& argc, char**& argv) { // Needed for some components. - sys::setProgramName("irccd"); + sys::set_program_name("irccd"); // Default logging to console. - log::setVerbose(false); + log::set_verbose(false); // Register some signals. signal(SIGINT, stop); @@ -130,7 +130,7 @@ ++ argv; } -option::Result parse(int &argc, char **&argv) +option::Result parse(int& argc, char**& argv) { // Parse command line options. option::Result result; @@ -150,7 +150,7 @@ result = option::read(argc, argv, options); - for (const auto &pair : result) { + for (const auto& pair : result) { if (pair.first == "-h" || pair.first == "--help") usage(); // NOTREACHED @@ -158,32 +158,32 @@ version(result); // NOTREACHED if (pair.first == "-v" || pair.first == "--verbose") - log::setVerbose(true); + log::set_verbose(true); } - } catch (const std::exception &ex) { - log::warning() << sys::programName() << ": " << ex.what() << std::endl; + } catch (const std::exception& ex) { + log::warning() << sys::program_name() << ": " << ex.what() << std::endl; usage(); } return result; } -Config open(const option::Result &result) +config open(const option::Result& result) { auto it = result.find("-c"); if (it != result.end() || (it = result.find("--config")) != result.end()) { try { - return Config(it->second); + return config(it->second); } catch (const std::exception &ex) { throw std::runtime_error("{}: {}"_format(it->second, ex.what())); } } - return Config::find(); + return config::find(); } -void loadPid(const std::string &path) +void load_pid(const std::string& path) { if (path.empty()) return; @@ -200,12 +200,12 @@ #else throw std::runtime_error("pidfile option not supported on this platform"); #endif - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::warning() << "irccd: " << ex.what() << std::endl; } } -void loadGid(const std::string gid) +void load_gid(const std::string& gid) { try { if (!gid.empty()) @@ -214,12 +214,12 @@ #else throw std::runtime_error(" gid option not supported on this platform"); #endif - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::warning() << "irccd: " << ex.what() << std::endl; } } -void loadUid(const std::string &uid) +void load_uid(const std::string& uid) { try { if (!uid.empty()) @@ -228,12 +228,12 @@ #else throw std::runtime_error("uid option not supported on this platform"); #endif - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::warning() << "irccd: " << ex.what() << std::endl; } } -void loadForeground(bool foreground, const option::Result &options) +void load_foreground(bool foreground, const option::Result& options) { try { #if defined(HAVE_DAEMON) @@ -243,12 +243,12 @@ if (options.count("-f") > 0 || options.count("--foreground") > 0 || foreground) throw std::runtime_error("foreground option not supported on this platform"); #endif - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::warning() << "irccd: " << ex.what() << std::endl; } } -void load(const Config &config, const option::Result &options) +void load(const config& config, const option::Result& options) { /* * Order matters, please be careful when changing this. @@ -258,95 +258,95 @@ */ // [logs] and [format] sections. - config.loadLogs(); - config.loadFormats(); + config.load_logs(); + config.load_formats(); // Show message here to use the formats. log::info() << "irccd: using " << config.path() << std::endl; // [general] section. - loadPid(config.pidfile()); - loadGid(config.gid()); - loadUid(config.uid()); - loadForeground(config.isForeground(), options); + load_pid(config.pidfile()); + load_gid(config.gid()); + load_uid(config.uid()); + load_foreground(config.is_foreground(), options); // [transport] - for (const auto &transport : config.loadTransports()) + for (const auto& transport : config.load_transports()) instance->transports().add(transport); // [server] section. - for (const auto &server : config.loadServers()) + for (const auto& server : config.load_servers()) instance->servers().add(server); // [rule] section. - for (const auto &rule : config.loadRules()) + for (const auto& rule : config.load_rules()) instance->rules().add(rule); // [plugin] section. - config.loadPlugins(*instance); + config.load_plugins(*instance); } } // !namespace -int main(int argc, char **argv) +int main(int argc, char** argv) { init(argc, argv); option::Result options = parse(argc, argv); - instance = std::make_unique(); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); - instance->commands().add(std::make_unique()); + instance = std::make_unique(); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); + instance->commands().add(std::make_unique()); // Load Javascript API and plugin loader. #if defined(WITH_JS) - auto loader = std::make_unique(*instance); + auto loader = std::make_unique(*instance); - loader->addModule(std::make_unique()); - loader->addModule(std::make_unique()); - loader->addModule(std::make_unique()); - loader->addModule(std::make_unique()); - loader->addModule(std::make_unique()); - loader->addModule(std::make_unique()); - loader->addModule(std::make_unique()); - loader->addModule(std::make_unique()); - loader->addModule(std::make_unique()); - loader->addModule(std::make_unique()); - loader->addModule(std::make_unique()); + loader->add_module(std::make_unique()); + loader->add_module(std::make_unique()); + loader->add_module(std::make_unique()); + loader->add_module(std::make_unique()); + loader->add_module(std::make_unique()); + loader->add_module(std::make_unique()); + loader->add_module(std::make_unique()); + loader->add_module(std::make_unique()); + loader->add_module(std::make_unique()); + loader->add_module(std::make_unique()); + loader->add_module(std::make_unique()); instance->plugins().addLoader(std::move(loader)); #endif try { load(open(options), options); - } catch (const std::exception &ex) { + } catch (const std::exception& ex) { log::warning() << "error: " << ex.what() << std::endl; return 1; } diff -r beb6c638b841 -r 7e273b7f4f92 irccdctl/cli.cpp --- a/irccdctl/cli.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/irccdctl/cli.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -40,8 +40,8 @@ void Cli::check(const nlohmann::json &response) { - if (!util::json::getBool(response, "status", false)) { - auto error = util::json::getString(response, "error"); + if (!util::json::get_bool(response, "status", false)) { + auto error = util::json::get_string(response, "error"); if (error.empty()) throw std::runtime_error("command failed with an unknown error"); @@ -78,7 +78,7 @@ if (!msg.is_object()) throw std::runtime_error("no response received"); - if (util::json::getString(msg, "command") != m_name) + if (util::json::get_string(msg, "command") != m_name) throw std::runtime_error("unexpected command result received"); check(msg); @@ -187,10 +187,10 @@ auto result = request(irccdctl, {{ "plugin", args[0] }}); std::cout << std::boolalpha; - std::cout << "Author : " << util::json::getString(result, "author") << std::endl; - std::cout << "License : " << util::json::getString(result, "license") << std::endl; - std::cout << "Summary : " << util::json::getString(result, "summary") << std::endl; - std::cout << "Version : " << util::json::getString(result, "version") << std::endl; + std::cout << "Author : " << util::json::get_string(result, "author") << std::endl; + std::cout << "License : " << util::json::get_string(result, "license") << std::endl; + std::cout << "Summary : " << util::json::get_string(result, "summary") << std::endl; + std::cout << "Version : " << util::json::get_string(result, "version") << std::endl; } /* @@ -407,7 +407,7 @@ }); if (copy.size() == 3) { - if (!util::isNumber(copy[2])) + if (!util::is_int(copy[2])) throw std::invalid_argument("invalid port number"); object["port"] = std::stoi(copy[2]); @@ -909,9 +909,9 @@ // Index. if (result.count("-i") > 0) - json["index"] = util::toNumber(result.find("-i")->second); + json["index"] = util::to_number(result.find("-i")->second); if (result.count("--index") > 0) - json["index"] = util::toNumber(result.find("--index")->second); + json["index"] = util::to_number(result.find("--index")->second); // And action. if (copy[0] != "accept" && copy[0] != "drop") @@ -1013,7 +1013,7 @@ } // Index. - json["index"] = util::toNumber(copy[0]); + json["index"] = util::to_number(copy[0]); check(request(irccdctl, json)); } diff -r beb6c638b841 -r 7e273b7f4f92 irccdctl/main.cpp --- a/irccdctl/main.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/irccdctl/main.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -51,7 +51,7 @@ bool first = true; for (const auto &cmd : commands) { - log::warning() << (first ? "usage: " : " ") << sys::programName() << " " + log::warning() << (first ? "usage: " : " ") << sys::program_name() << " " << cmd->usage() << std::endl; first = false; } @@ -61,7 +61,7 @@ void help() { - log::warning() << "usage: " << sys::programName() << " [options...] [command-options...] [command-args...]\n\n"; + log::warning() << "usage: " << sys::program_name() << " [options...] [command-options...] [command-args...]\n\n"; log::warning() << "General options:\n"; log::warning() << "\t-c, --config file\tspecify the configuration file\n"; log::warning() << "\t --help\t\tshow this help\n"; @@ -78,7 +78,7 @@ log::warning() << "\t" << std::left << std::setw(32) << cmd->name() << cmd->summary() << std::endl; - log::warning() << "\nFor more information on a command, type " << sys::programName() << " help " << std::endl; + log::warning() << "\nFor more information on a command, type " << sys::program_name() << " help " << std::endl; std::exit(1); } @@ -91,7 +91,7 @@ if (it == commands.end()) { log::warning() << "no command named " << command << std::endl; } else { - log::warning() << "usage: " << sys::programName() << " " << (*it)->usage() << "\n" << std::endl; + log::warning() << "usage: " << sys::program_name() << " " << (*it)->usage() << "\n" << std::endl; log::warning() << (*it)->help() << std::endl; } @@ -116,9 +116,9 @@ * domain = "ipv4 or ipv6" (Optional, default: ipv4) * ssl = true | false */ -void readConnectIp(const ini::Section &sc) +void readConnectIp(const ini::section &sc) { - ini::Section::const_iterator it; + ini::section::const_iterator it; std::string host, port; if ((it = sc.find("host")) == sc.end()) @@ -145,7 +145,7 @@ address = net::resolveOne(host, port, domain, SOCK_STREAM); - if ((it = sc.find("ssl")) != sc.end() && util::isBoolean(it->value())) + if ((it = sc.find("ssl")) != sc.end() && util::is_boolean(it->value())) #if defined(WITH_SSL) client = std::make_unique(); #else @@ -165,7 +165,7 @@ * type = "unix" * path = "path to socket file" */ -void readConnectLocal(const ini::Section &sc) +void readConnectLocal(const ini::section &sc) { #if !defined(IRCCD_SYSTEM_WINDOWS) auto it = sc.find("path"); @@ -188,7 +188,7 @@ * * Generic function for reading the [connect] section. */ -void readConnect(const ini::Section &sc) +void readConnect(const ini::section &sc) { auto it = sc.find("type"); @@ -218,12 +218,12 @@ * [general] * verbose = true */ -void readGeneral(const ini::Section &sc) +void readGeneral(const ini::section &sc) { auto verbose = sc.find("verbose"); if (verbose != sc.end()) - log::setVerbose(util::isBoolean(verbose->value())); + log::set_verbose(util::is_boolean(verbose->value())); } /* @@ -236,7 +236,7 @@ * cmd1 = ( "command", "arg1, "...", "argn" ) * cmd2 = ( "command", "arg1, "...", "argn" ) */ -Alias readAlias(const ini::Section &sc, const std::string &name) +Alias readAlias(const ini::section &sc, const std::string &name) { Alias alias(name); @@ -265,8 +265,8 @@ void read(const std::string &path) { try { - ini::Document doc = ini::readFile(path); - ini::Document::const_iterator it; + ini::document doc = ini::read_file(path); + ini::document::const_iterator it; if (!client && (it = doc.find("connect")) != doc.end()) readConnect(*it); @@ -414,10 +414,10 @@ } if (result.count("-v") != 0 || result.count("--verbose") != 0) { - log::setVerbose(true); + log::set_verbose(true); } } catch (const std::exception &ex) { - log::warning("{}: {}"_format(sys::programName(), ex.what())); + log::warning("{}: {}"_format(sys::program_name(), ex.what())); usage(); } @@ -494,7 +494,7 @@ void init(int &argc, char **&argv) { - sys::setProgramName("irccdctl"); + sys::set_program_name("irccdctl"); net::init(); --argc; @@ -569,7 +569,7 @@ } } } catch (const std::exception &ex) { - log::warning() << sys::programName() << ": " << ex.what() << std::endl; + log::warning() << sys::program_name() << ": " << ex.what() << std::endl; std::exit(1); } @@ -586,7 +586,7 @@ } if (!client) { - log::warning("{}: no connection specified"_format(sys::programName())); + log::warning("{}: no connection specified"_format(sys::program_name())); std::exit(1); } @@ -611,6 +611,6 @@ try { exec(args); } catch (const std::exception &ex) { - std::cerr << sys::programName() << ": unrecoverable error: " << ex.what() << std::endl; + std::cerr << sys::program_name() << ": unrecoverable error: " << ex.what() << std::endl; } } diff -r beb6c638b841 -r 7e273b7f4f92 libcommon/irccd/ini.cpp --- a/libcommon/irccd/ini.cpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libcommon/irccd/ini.cpp Tue Sep 26 17:18:47 2017 +0200 @@ -26,25 +26,21 @@ // for PathIsRelative. #if defined(_WIN32) -# if !defined(WIN32_LEAN_AND_MEAN) -# define WIN32_LEAN_AND_MEAN -# endif - -# include +# include #endif #include "ini.hpp" namespace irccd { +namespace ini { + namespace { -using namespace ini; +using stream_iterator = std::istreambuf_iterator; +using token_iterator = std::vector::const_iterator; -using StreamIterator = std::istreambuf_iterator; -using TokenIterator = std::vector::const_iterator; - -inline bool isAbsolute(const std::string &path) noexcept +inline bool is_absolute(const std::string& path) noexcept { #if defined(_WIN32) return !PathIsRelative(path.c_str()); @@ -53,28 +49,28 @@ #endif } -inline bool isQuote(char c) noexcept +inline bool is_quote(char c) noexcept { return c == '\'' || c == '"'; } -inline bool isSpace(char c) noexcept +inline bool is_space(char c) noexcept { // Custom version because std::isspace includes \n as space. return c == ' ' || c == '\t'; } -inline bool isList(char c) noexcept +inline bool is_list(char c) noexcept { return c == '(' || c == ')' || c == ','; } -inline bool isReserved(char c) noexcept +inline bool is_reserved(char c) noexcept { - return isList(c) || isQuote(c) || c == '[' || c == ']' || c == '@' || c == '#' || c == '='; + return is_list(c) || is_quote(c) || c == '[' || c == ']' || c == '@' || c == '#' || c == '='; } -void analyseLine(int &line, int &column, StreamIterator &it) noexcept +void analyse_line(int& line, int& column, stream_iterator& it) noexcept { assert(*it == '\n'); @@ -83,7 +79,7 @@ column = 0; } -void analyseComment(int &column, StreamIterator &it, StreamIterator end) noexcept +void analyse_comment(int& column, stream_iterator& it, stream_iterator end) noexcept { assert(*it == '#'); @@ -93,36 +89,36 @@ } } -void analyseSpaces(int &column, StreamIterator &it, StreamIterator end) noexcept +void analyse_spaces(int& column, stream_iterator& it, stream_iterator end) noexcept { - assert(isSpace(*it)); + assert(is_space(*it)); - while (it != end && isSpace(*it)) { + while (it != end && is_space(*it)) { ++ column; ++ it; } } -void analyseList(Tokens &list, int line, int &column, StreamIterator &it) noexcept +void analyse_list(tokens& list, int line, int& column, stream_iterator& it) noexcept { - assert(isList(*it)); + assert(is_list(*it)); switch (*it++) { case '(': - list.emplace_back(Token::ListBegin, line, column++); + list.emplace_back(token::list_begin, line, column++); break; case ')': - list.emplace_back(Token::ListEnd, line, column++); + list.emplace_back(token::list_end, line, column++); break; case ',': - list.emplace_back(Token::Comma, line, column++); + list.emplace_back(token::comma, line, column++); break; default: break; } } -void analyseSection(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end) +void analyse_section(tokens& list, int& line, int& column, stream_iterator& it, stream_iterator end) { assert(*it == '['); @@ -132,35 +128,39 @@ // Read section name. ++ it; while (it != end && *it != ']') { - if (*it == '\n') - throw Error(line, column, "section not terminated, missing ']'"); - if (isReserved(*it)) - throw Error(line, column, "section name expected after '[', got '" + std::string(1, *it) + "'"); + if (*it == '\n') { + throw exception(line, column, "section not terminated, missing ']'"); + } + if (is_reserved(*it)) { + throw exception(line, column, "section name expected after '[', got '" + std::string(1, *it) + "'"); + } ++ column; value += *it++; } - if (it == end) - throw Error(line, column, "section name expected after '[', got "); - if (value.empty()) - throw Error(line, column, "empty section name"); + if (it == end) { + throw exception(line, column, "section name expected after '[', got "); + } + if (value.empty()) { + throw exception(line, column, "empty section name"); + } // Remove ']'. ++ it; - list.emplace_back(Token::Section, line, save, std::move(value)); + list.emplace_back(token::section, line, save, std::move(value)); } -void analyseAssign(Tokens &list, int &line, int &column, StreamIterator &it) +void analyse_assign(tokens& list, int& line, int& column, stream_iterator& it) { assert(*it == '='); - list.push_back({ Token::Assign, line, column++ }); + list.push_back({ token::assign, line, column++ }); ++ it; } -void analyseQuotedWord(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end) +void analyse_quoted_word(tokens& list, int& line, int& column, stream_iterator& it, stream_iterator end) { std::string value; int save = column; @@ -172,31 +172,32 @@ value += *it++; } - if (it == end) - throw Error(line, column, "undisclosed '" + std::string(1, quote) + "', got "); + if (it == end) { + throw exception(line, column, "undisclosed '" + std::string(1, quote) + "', got "); + } // Remove quote. ++ it; - list.push_back({ Token::QuotedWord, line, save, std::move(value) }); + list.push_back({ token::quoted_word, line, save, std::move(value) }); } -void analyseWord(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end) +void analyse_word(tokens& list, int& line, int& column, stream_iterator& it, stream_iterator end) { - assert(!isReserved(*it)); + assert(!is_reserved(*it)); std::string value; int save = column; - while (it != end && !std::isspace(*it) && !isReserved(*it)) { + while (it != end && !std::isspace(*it) && !is_reserved(*it)) { ++ column; value += *it++; } - list.push_back({ Token::Word, line, save, std::move(value) }); + list.push_back({ token::word, line, save, std::move(value) }); } -void analyseInclude(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end) +void analyse_include(tokens& list, int& line, int& column, stream_iterator& it, stream_iterator end) { assert(*it == '@'); @@ -205,117 +206,127 @@ // Read include. ++ it; - while (it != end && !isSpace(*it)) { + while (it != end && !is_space(*it)) { ++ column; include += *it++; } - if (include != "include") - throw Error(line, column, "expected include after '@' token"); + if (include != "include") { + throw exception(line, column, "expected include after '@' token"); + } - list.push_back({ Token::Include, line, save }); + list.push_back({ token::include, line, save }); } -void parseOptionValueSimple(Option &option, TokenIterator &it) +void parse_option_value_simple(option& option, token_iterator& it) { - assert(it->type() == Token::Word || it->type() == Token::QuotedWord); + assert(it->type() == token::word || it->type() == token::quoted_word); option.push_back((it++)->value()); } -void parseOptionValueList(Option &option, TokenIterator &it, TokenIterator end) +void parse_option_value_list(option& option, token_iterator& it, token_iterator end) { - assert(it->type() == Token::ListBegin); + assert(it->type() == token::list_begin); - TokenIterator save = it++; + token_iterator save = it++; - while (it != end && it->type() != Token::ListEnd) { + while (it != end && it->type() != token::list_end) { switch (it->type()) { - case Token::Comma: + case token::comma: // Previous must be a word. - if (it[-1].type() != Token::Word && it[-1].type() != Token::QuotedWord) - throw Error(it->line(), it->column(), "unexpected comma after '" + it[-1].value() + "'"); + if (it[-1].type() != token::word && it[-1].type() != token::quoted_word) { + throw exception(it->line(), it->column(), "unexpected comma after '" + it[-1].value() + "'"); + } ++ it; break; - case Token::Word: - case Token::QuotedWord: + case token::word: + case token::quoted_word: option.push_back((it++)->value()); break; default: - throw Error(it->line(), it->column(), "unexpected '" + it[-1].value() + "' in list construct"); + throw exception(it->line(), it->column(), "unexpected '" + it[-1].value() + "' in list construct"); break; } } - if (it == end) - throw Error(save->line(), save->column(), "unterminated list construct"); + if (it == end) { + throw exception(save->line(), save->column(), "unterminated list construct"); + } // Remove ). ++ it; } -void parseOption(Section &sc, TokenIterator &it, TokenIterator end) +void parse_option(section& sc, token_iterator& it, token_iterator end) { - Option option(it->value()); - - TokenIterator save = it; + option option(it->value()); + token_iterator save(it); // No '=' or something else? - if (++it == end) - throw Error(save->line(), save->column(), "expected '=' assignment, got "); - if (it->type() != Token::Assign) - throw Error(it->line(), it->column(), "expected '=' assignment, got " + it->value()); + if (++it == end) { + throw exception(save->line(), save->column(), "expected '=' assignment, got "); + } + if (it->type() != token::assign) { + throw exception(it->line(), it->column(), "expected '=' assignment, got " + it->value()); + } // Empty options are allowed so just test for words. if (++it != end) { - if (it->type() == Token::Word || it->type() == Token::QuotedWord) - parseOptionValueSimple(option, it); - else if (it->type() == Token::ListBegin) - parseOptionValueList(option, it, end); + if (it->type() == token::word || it->type() == token::quoted_word) { + parse_option_value_simple(option, it); + } else if (it->type() == token::list_begin) { + parse_option_value_list(option, it, end); + } } sc.push_back(std::move(option)); } -void parseInclude(Document &doc, const std::string &path, TokenIterator &it, TokenIterator end) +void parse_include(document& doc, const std::string& path, token_iterator& it, token_iterator end) { - TokenIterator save = it; + token_iterator save(it); - if (++it == end) - throw Error(save->line(), save->column(), "expected file name after '@include' statement, got "); - if (it->type() != Token::Word && it->type() != Token::QuotedWord) - throw Error(it->line(), it->column(), "expected file name after '@include' statement, got " + it->value()); + if (++it == end) { + throw exception(save->line(), save->column(), "expected file name after '@include' statement, got "); + } + if (it->type() != token::word && it->type() != token::quoted_word) { + throw exception(it->line(), it->column(), "expected file name after '@include' statement, got " + it->value()); + } std::string value = (it++)->value(); std::string file; - if (!isAbsolute(value)) + if (!is_absolute(value)) { #if defined(_WIN32) file = path + "\\" + value; #else file = path + "/" + value; #endif - else + } else { file = value; + } - for (const auto &sc : readFile(file)) + for (const auto& sc : read_file(file)) { doc.push_back(sc); + } } -void parseSection(Document &doc, TokenIterator &it, TokenIterator end) +void parse_section(document& doc, token_iterator& it, token_iterator end) { - Section sc(it->value()); + section sc(it->value()); // Skip [section]. ++ it; // Read until next section. - while (it != end && it->type() != Token::Section) { - if (it->type() != Token::Word) - throw Error(it->line(), it->column(), "unexpected token '" + it->value() + "' in section definition"); + while (it != end && it->type() != token::section) { + if (it->type() != token::word) { + throw exception(it->line(), it->column(), "unexpected token '" + it->value() + "' in section definition"); + } - parseOption(sc, it, end); + parse_option(sc, it, end); } doc.push_back(std::move(sc)); @@ -323,96 +334,98 @@ } // !namespace -namespace ini { - -Tokens analyse(std::istreambuf_iterator it, std::istreambuf_iterator end) +tokens analyse(std::istreambuf_iterator it, std::istreambuf_iterator end) { - Tokens list; + tokens list; int line = 1; int column = 0; while (it != end) { - if (*it == '\n') - analyseLine(line, column, it); - else if (*it == '#') - analyseComment(column, it, end); - else if (*it == '[') - analyseSection(list, line, column, it, end); - else if (*it == '=') - analyseAssign(list, line, column, it); - else if (isSpace(*it)) - analyseSpaces(column, it, end); - else if (*it == '@') - analyseInclude(list, line, column, it, end); - else if (isQuote(*it)) - analyseQuotedWord(list, line, column, it, end); - else if (isList(*it)) - analyseList(list, line, column, it); - else - analyseWord(list, line, column, it, end); + if (*it == '\n') { + analyse_line(line, column, it); + } else if (*it == '#') { + analyse_comment(column, it, end); + } else if (*it == '[') { + analyse_section(list, line, column, it, end); + } else if (*it == '=') { + analyse_assign(list, line, column, it); + } else if (is_space(*it)) { + analyse_spaces(column, it, end); + } else if (*it == '@') { + analyse_include(list, line, column, it, end); + } else if (is_quote(*it)) { + analyse_quoted_word(list, line, column, it, end); + } else if (is_list(*it)) { + analyse_list(list, line, column, it); + } else { + analyse_word(list, line, column, it, end); + } } return list; } -Tokens analyse(std::istream &stream) +tokens analyse(std::istream& stream) { return analyse(std::istreambuf_iterator(stream), {}); } -Document parse(const Tokens &tokens, const std::string &path) +document parse(const tokens& tokens, const std::string& path) { - Document doc; - TokenIterator it = tokens.cbegin(); - TokenIterator end = tokens.cend(); + document doc; + token_iterator it = tokens.cbegin(); + token_iterator end = tokens.cend(); while (it != end) { switch (it->type()) { - case Token::Include: - parseInclude(doc, path, it, end); + case token::include: + parse_include(doc, path, it, end); break; - case Token::Section: - parseSection(doc, it, end); + case token::section: + parse_section(doc, it, end); break; default: - throw Error(it->line(), it->column(), "unexpected '" + it->value() + "' on root document"); + throw exception(it->line(), it->column(), "unexpected '" + it->value() + "' on root document"); } } return doc; } -Document readFile(const std::string &filename) +document read_file(const std::string& filename) { // Get parent path. auto parent = filename; auto pos = parent.find_last_of("/\\"); - if (pos != std::string::npos) + if (pos != std::string::npos) { parent.erase(pos); - else + } else { parent = "."; + } std::ifstream input(filename); - if (!input) - throw Error(0, 0, std::strerror(errno)); + if (!input) { + throw exception(0, 0, std::strerror(errno)); + } return parse(analyse(input), parent); } -Document readString(const std::string &buffer) +document read_string(const std::string& buffer) { std::istringstream iss(buffer); return parse(analyse(iss)); } -void dump(const Tokens &tokens) +void dump(const tokens& tokens) { - for (const Token &token: tokens) + for (const token& token: tokens) { // TODO: add better description std::cout << token.line() << ":" << token.column() << ": " << token.value() << std::endl; + } } } // !ini diff -r beb6c638b841 -r 7e273b7f4f92 libcommon/irccd/ini.hpp --- a/libcommon/irccd/ini.hpp Fri Aug 11 13:45:42 2017 +0200 +++ b/libcommon/irccd/ini.hpp Tue Sep 26 17:18:47 2017 +0200 @@ -16,13 +16,14 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef IRCCD_INI_HPP -#define IRCCD_INI_HPP +#ifndef INI_HPP +#define INI_HPP /** * \file ini.hpp * \brief Extended .ini file parser. * \author David Demelier + * \version 1.0.0 */ /** @@ -42,7 +43,8 @@ * - an option **must** always be defined in a section, * - empty options must be surrounded by quotes, * - lists can not includes trailing commas, - * - include statement must always be at the beginning of files (in no sections), + * - include statement must always be at the beginning of files + * (in no sections), * - comments starts with # until the end of line, * - options with spaces **must** use quotes. * @@ -57,7 +59,8 @@ * * # Redefinition * - * Sections can be redefined multiple times and are kept the order they are seen. + * Sections can be redefined multiple times and are kept the order they are + * seen. * * ````ini * [section] @@ -67,7 +70,7 @@ * value = "2" * ```` * - * The ini::Document object will contains two ini::Section. + * The ini::document object will contains two ini::Section. * * # Lists * @@ -86,8 +89,8 @@ * * # Include statement * - * You can split a file into several pieces, if the include statement contains a relative path, the path will be relative - * to the current file being parsed. + * You can split a file into several pieces, if the include statement contains a + * relative path, the path will be relative to the current file being parsed. * * You **must** use the include statement before any section. * @@ -103,6 +106,32 @@ * ```` */ +/** + * \cond INI_HIDDEN_SYMBOLS + */ + +#if !defined(IRCCD_EXPORT) +# if defined(INI_DLL) +# if defined(_WIN32) +# if defined(INI_BUILDING_DLL) +# define IRCCD_EXPORT __declspec(dllexport) +# else +# define IRCCD_EXPORT __declspec(dllimport) +# endif +# else +# define IRCCD_EXPORT +# endif +# else +# define IRCCD_EXPORT +# endif +#endif + +/** + * \endcond + */ + +#include + #include #include #include @@ -110,8 +139,6 @@ #include #include -#include "sysconfig.hpp" - namespace irccd { /** @@ -119,16 +146,16 @@ */ namespace ini { -class Document; +class document; /** - * \brief Error in a file. + * \brief exception in a file. */ -class Error : public std::exception { +class exception : public std::exception { private: int m_line; //!< line number int m_column; //!< line column - std::string m_message; //!< error message + std::string m_message; //!< exception message public: /** @@ -138,7 +165,7 @@ * \param column the column * \param msg the message */ - inline Error(int line, int column, std::string msg) noexcept + inline exception(int line, int column, std::string msg) noexcept : m_line(line) , m_column(column) , m_message(std::move(msg)) @@ -166,11 +193,11 @@ } /** - * Return the raw error message (no line and column shown). + * Return the raw exception message (no line and column shown). * - * \return the error message + * \return the exception message */ - const char *what() const noexcept override + const char* what() const noexcept override { return m_message.c_str(); } @@ -183,24 +210,24 @@ * * \see analyze */ -class Token { +class token { public: /** - * \brief Token type. + * \brief token type. */ - enum Type { - Include, //!< include statement - Section, //!< [section] - Word, //!< word without quotes - QuotedWord, //!< word with quotes - Assign, //!< = assignment - ListBegin, //!< begin of list ( - ListEnd, //!< end of list ) - Comma //!< list separation + enum type { + include, //!< include statement + section, //!< [section] + word, //!< word without quotes + quoted_word, //!< word with quotes + assign, //!< = assignment + list_begin, //!< begin of list ( + list_end, //!< end of list ) + comma //!< list separation }; private: - Type m_type; + type m_type; int m_line; int m_column; std::string m_value; @@ -214,30 +241,30 @@ * \param column the column * \param value the value */ - Token(Type type, int line, int column, std::string value = "") noexcept + token(type type, int line, int column, std::string value = "") noexcept : m_type(type) , m_line(line) , m_column(column) { switch (type) { - case Include: + case include: m_value = "@include"; break; - case Section: - case Word: - case QuotedWord: + case section: + case word: + case quoted_word: m_value = value; break; - case Assign: + case assign: m_value = "="; break; - case ListBegin: + case list_begin: m_value = "("; break; - case ListEnd: + case list_end: m_value = ")"; break; - case Comma: + case comma: m_value = ","; break; default: @@ -250,7 +277,7 @@ * * \return the type */ - inline Type type() const noexcept + inline type type() const noexcept { return m_type; } @@ -276,12 +303,12 @@ } /** - * Get the value. For words, quoted words and section, the value is the content. Otherwise it's the - * characters parsed. + * Get the value. For words, quoted words and section, the value is the + * content. Otherwise it's the characters parsed. * * \return the value */ - inline const std::string &value() const noexcept + inline const std::string& value() const noexcept { return m_value; } @@ -290,12 +317,12 @@ /** * List of tokens in order they are analyzed. */ -using Tokens = std::vector; +using tokens = std::vector; /** - * \brief Option definition. + * \brief option definition. */ -class Option : public std::vector { +class option : public std::vector { private: std::string m_key; @@ -306,7 +333,7 @@ * \pre key must not be empty * \param key the key */ - inline Option(std::string key) noexcept + inline option(std::string key) noexcept : std::vector() , m_key(std::move(key)) { @@ -320,7 +347,7 @@ * \param key the key * \param value the value */ - inline Option(std::string key, std::string value) noexcept + inline option(std::string key, std::string value) noexcept : m_key(std::move(key)) { assert(!m_key.empty()); @@ -335,7 +362,7 @@ * \param key the key * \param values the values */ - inline Option(std::string key, std::vector values) noexcept + inline option(std::string key, std::vector values) noexcept : std::vector(std::move(values)) , m_key(std::move(key)) { @@ -347,7 +374,7 @@ * * \return the key */ - inline const std::string &key() const noexcept + inline const std::string& key() const noexcept { return m_key; } @@ -357,7 +384,7 @@ * * \return the value */ - inline const std::string &value() const noexcept + inline const std::string& value() const noexcept { static std::string dummy; @@ -368,7 +395,7 @@ /** * \brief Section that contains one or more options. */ -class Section : public std::vector