/* * asbots * Copyright (C) 2021 niansa * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "config.hpp" #include "uid.hpp" #include "utility.hpp" #include #include #include #include #include inline void noop() {} Config parseConfig(const std::filesystem::path& path) { Config fres; auto file = std::ifstream(path); // Read through all sections while (!file.eof()) { std::string head; std::string_view section; file >> head; // Skip some emptynes if (head.empty()) { continue; } // Check section head syntax if (head.size() < 3 || !head.starts_with('[') || !head.ends_with(']')) { throw Config::ParseError("Invalid head (section identifier) syntax"); } // Extract actual section name section = {head.data()+1, head.size()-2}; while (!file.eof()) { // Get key and value std::string line; std::getline(file, line); // Check for empty line if (line.empty()) { continue; } // Split into key and value auto [key, value] = Utility::splitOnce(line, ": "); // Check for "end" if (key == "end") { break; } // Do stuff depending on current section using macro magic # define SECTION(name, ...) if (section == #name) {auto &d = fres.name; __VA_ARGS__; continue;;} noop() # define ASSIGN(e_key, val) if (key == #e_key) {d.e_key = val; continue;} noop() SECTION(connection, { ASSIGN(addr, value); ASSIGN(port, std::stoi(std::string(value))); }); SECTION(auth, { ASSIGN(send_password, value); ASSIGN(accept_password, value); }); SECTION(server, { ASSIGN(name, value); ASSIGN(description, value); ASSIGN(uid, SUID(value)); ASSIGN(hidden, value=="true"); }); // Misc keys auto s_res = fres.misc.find(std::string(section)); if (s_res == fres.misc.end()) { fres.misc[std::string(section)] = {{std::string(key), std::string(value)}}; } else { s_res->second[std::string(key)] = value; } } } // Return resulting Config object return fres; }