clang format
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) <2015> <carriez.md@gmail.com>
|
||||
*
|
||||
@@ -9,7 +9,7 @@
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
@@ -19,27 +19,28 @@
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INI_HPP
|
||||
#define INI_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
namespace INI {
|
||||
namespace INI
|
||||
{
|
||||
|
||||
struct Level
|
||||
struct Level
|
||||
{
|
||||
Level() : parent(NULL), depth(0) {}
|
||||
Level(Level* p) : parent(p), depth(0) {}
|
||||
Level(Level *p) : parent(p), depth(0) {}
|
||||
|
||||
typedef std::map<std::string, std::string> value_map_t;
|
||||
typedef std::map<std::string, Level> section_map_t;
|
||||
@@ -49,114 +50,121 @@ struct Level
|
||||
section_map_t sections;
|
||||
values_t ordered_values; // original order in the ini file
|
||||
sections_t ordered_sections;
|
||||
Level* parent;
|
||||
Level *parent;
|
||||
size_t depth;
|
||||
|
||||
const std::string& operator[](const std::string& name) { return values[name]; }
|
||||
Level& operator()(const std::string& name) { return sections[name]; }
|
||||
const std::string &operator[](const std::string &name) { return values[name]; }
|
||||
Level &operator()(const std::string &name) { return sections[name]; }
|
||||
};
|
||||
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
Parser(const char* fn);
|
||||
Parser(std::istream& f) : f_(&f), ln_(0) { parse(top_); }
|
||||
Level& top() { return top_; }
|
||||
void dump(std::ostream& s) { dump(s, top(), ""); }
|
||||
Parser(const char *fn);
|
||||
Parser(std::istream &f) : f_(&f), ln_(0) { parse(top_); }
|
||||
Level &top() { return top_; }
|
||||
void dump(std::ostream &s) { dump(s, top(), ""); }
|
||||
|
||||
private:
|
||||
void dump(std::ostream& s, const Level& l, const std::string& sname);
|
||||
void parse(Level& l);
|
||||
void parseSLine(std::string& sname, size_t& depth);
|
||||
void err(const char* s);
|
||||
void dump(std::ostream &s, const Level &l, const std::string &sname);
|
||||
void parse(Level &l);
|
||||
void parseSLine(std::string &sname, size_t &depth);
|
||||
void err(const char *s);
|
||||
|
||||
private:
|
||||
Level top_;
|
||||
std::ifstream f0_;
|
||||
std::istream* f_;
|
||||
std::istream *f_;
|
||||
std::string line_;
|
||||
size_t ln_;
|
||||
};
|
||||
|
||||
inline void
|
||||
Parser::err(const char* s)
|
||||
inline void Parser::err(const char *s)
|
||||
{
|
||||
char buf[256];
|
||||
sprintf(buf, "%s on line #%ld", s, ln_);
|
||||
throw std::runtime_error(buf);
|
||||
}
|
||||
|
||||
inline std::string trim(const std::string& s)
|
||||
inline std::string trim(const std::string &s)
|
||||
{
|
||||
char p[] = " \t\r\n";
|
||||
long sp = 0;
|
||||
long ep = s.length() - 1;
|
||||
for (; sp <= ep; ++sp)
|
||||
if (!strchr(p, s[sp])) break;
|
||||
if (!strchr(p, s[sp]))
|
||||
break;
|
||||
for (; ep >= 0; --ep)
|
||||
if (!strchr(p, s[ep])) break;
|
||||
return s.substr(sp, ep-sp+1);
|
||||
if (!strchr(p, s[ep]))
|
||||
break;
|
||||
return s.substr(sp, ep - sp + 1);
|
||||
}
|
||||
|
||||
inline
|
||||
Parser::Parser(const char* fn) : f0_(fn), f_(&f0_), ln_(0)
|
||||
{
|
||||
if (!f0_)
|
||||
inline Parser::Parser(const char *fn) : f0_(fn), f_(&f0_), ln_(0)
|
||||
{
|
||||
if (!f0_)
|
||||
throw std::runtime_error(std::string("failed to open file: ") + fn);
|
||||
|
||||
parse(top_);
|
||||
parse(top_);
|
||||
}
|
||||
|
||||
inline void
|
||||
Parser::parseSLine(std::string& sname, size_t& depth)
|
||||
inline void Parser::parseSLine(std::string &sname, size_t &depth)
|
||||
{
|
||||
depth = 0;
|
||||
for (; depth < line_.length(); ++depth)
|
||||
if (line_[depth] != '[') break;
|
||||
if (line_[depth] != '[')
|
||||
break;
|
||||
|
||||
sname = line_.substr(depth, line_.length() - 2*depth);
|
||||
sname = line_.substr(depth, line_.length() - 2 * depth);
|
||||
}
|
||||
|
||||
inline void
|
||||
Parser::parse(Level& l)
|
||||
inline void Parser::parse(Level &l)
|
||||
{
|
||||
while (std::getline(*f_, line_)) {
|
||||
while (std::getline(*f_, line_))
|
||||
{
|
||||
++ln_;
|
||||
if (line_[0] == '#' || line_[0] == ';') continue;
|
||||
if (line_[0] == '#' || line_[0] == ';')
|
||||
continue;
|
||||
line_ = trim(line_);
|
||||
if (line_.empty()) continue;
|
||||
if (line_[0] == '[') {
|
||||
if (line_.empty())
|
||||
continue;
|
||||
if (line_[0] == '[')
|
||||
{
|
||||
size_t depth;
|
||||
std::string sname;
|
||||
parseSLine(sname, depth);
|
||||
Level* lp = NULL;
|
||||
Level* parent = &l;
|
||||
Level *lp = NULL;
|
||||
Level *parent = &l;
|
||||
if (depth > l.depth + 1)
|
||||
err("section with wrong depth");
|
||||
if (l.depth == depth-1)
|
||||
if (l.depth == depth - 1)
|
||||
lp = &l.sections[sname];
|
||||
else {
|
||||
else
|
||||
{
|
||||
lp = l.parent;
|
||||
size_t n = l.depth - depth;
|
||||
for (size_t i = 0; i < n; ++i) lp = lp->parent;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
lp = lp->parent;
|
||||
parent = lp;
|
||||
lp = &lp->sections[sname];
|
||||
}
|
||||
if (lp->depth != 0)
|
||||
err("duplicate section name on the same level");
|
||||
if (!lp->parent) {
|
||||
if (!lp->parent)
|
||||
{
|
||||
lp->depth = depth;
|
||||
lp->parent = parent;
|
||||
}
|
||||
parent->ordered_sections.push_back(parent->sections.find(sname));
|
||||
parse(*lp);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t n = line_.find('=');
|
||||
if (n == std::string::npos)
|
||||
err("no '=' found");
|
||||
std::pair<Level::value_map_t::const_iterator, bool> res =
|
||||
l.values.insert(std::make_pair(trim(line_.substr(0, n)),
|
||||
trim(line_.substr(n+1, line_.length()-n-1))));
|
||||
std::pair<Level::value_map_t::const_iterator, bool> res =
|
||||
l.values.insert(std::make_pair(trim(line_.substr(0, n)), trim(line_.substr(n + 1, line_.length() - n - 1))));
|
||||
if (!res.second)
|
||||
err("duplicated key found");
|
||||
l.ordered_values.push_back(res.first);
|
||||
@@ -164,23 +172,26 @@ Parser::parse(Level& l)
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Parser::dump(std::ostream& s, const Level& l, const std::string& sname)
|
||||
inline void Parser::dump(std::ostream &s, const Level &l, const std::string &sname)
|
||||
{
|
||||
if (!sname.empty()) s << '\n';
|
||||
for (size_t i = 0; i < l.depth; ++i) s << '[';
|
||||
if (!sname.empty()) s << sname;
|
||||
for (size_t i = 0; i < l.depth; ++i) s << ']';
|
||||
if (!sname.empty()) s << std::endl;
|
||||
if (!sname.empty())
|
||||
s << '\n';
|
||||
for (size_t i = 0; i < l.depth; ++i)
|
||||
s << '[';
|
||||
if (!sname.empty())
|
||||
s << sname;
|
||||
for (size_t i = 0; i < l.depth; ++i)
|
||||
s << ']';
|
||||
if (!sname.empty())
|
||||
s << std::endl;
|
||||
for (Level::values_t::const_iterator it = l.ordered_values.begin(); it != l.ordered_values.end(); ++it)
|
||||
s << (*it)->first << '=' << (*it)->second << std::endl;
|
||||
for (Level::sections_t::const_iterator it = l.ordered_sections.begin(); it != l.ordered_sections.end(); ++it) {
|
||||
assert((*it)->second.depth == l.depth+1);
|
||||
for (Level::sections_t::const_iterator it = l.ordered_sections.begin(); it != l.ordered_sections.end(); ++it)
|
||||
{
|
||||
assert((*it)->second.depth == l.depth + 1);
|
||||
dump(s, (*it)->second, (*it)->first);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // INI_HPP
|
||||
|
||||
|
@@ -1,18 +1,19 @@
|
||||
#include "ini.hpp"
|
||||
|
||||
#include <nntpchan/crypto.hpp>
|
||||
#include <nntpchan/storage.hpp>
|
||||
#include <nntpchan/nntp_server.hpp>
|
||||
#include <nntpchan/event.hpp>
|
||||
#include <nntpchan/exec_frontend.hpp>
|
||||
#include <nntpchan/nntp_server.hpp>
|
||||
#include <nntpchan/staticfile_frontend.hpp>
|
||||
#include <nntpchan/storage.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
if (argc != 2) {
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cerr << "usage: " << argv[0] << " config.ini" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
@@ -23,57 +24,63 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
nntpchan::NNTPServer nntp(loop);
|
||||
|
||||
|
||||
std::string fname(argv[1]);
|
||||
|
||||
std::ifstream i(fname);
|
||||
|
||||
if(i.is_open()) {
|
||||
if (i.is_open())
|
||||
{
|
||||
INI::Parser conf(i);
|
||||
|
||||
std::vector<std::string> requiredSections = {"nntp", "articles"};
|
||||
|
||||
auto & level = conf.top();
|
||||
auto &level = conf.top();
|
||||
|
||||
for ( const auto & section : requiredSections ) {
|
||||
if(level.sections.find(section) == level.sections.end()) {
|
||||
for (const auto §ion : requiredSections)
|
||||
{
|
||||
if (level.sections.find(section) == level.sections.end())
|
||||
{
|
||||
std::cerr << "config file " << fname << " does not have required section: ";
|
||||
std::cerr << section << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
auto & storeconf = level.sections["articles"].values;
|
||||
auto &storeconf = level.sections["articles"].values;
|
||||
|
||||
if (storeconf.find("store_path") == storeconf.end()) {
|
||||
if (storeconf.find("store_path") == storeconf.end())
|
||||
{
|
||||
std::cerr << "storage section does not have 'store_path' value" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
nntp.SetStoragePath(storeconf["store_path"]);
|
||||
|
||||
auto & nntpconf = level.sections["nntp"].values;
|
||||
auto &nntpconf = level.sections["nntp"].values;
|
||||
|
||||
if (nntpconf.find("bind") == nntpconf.end()) {
|
||||
if (nntpconf.find("bind") == nntpconf.end())
|
||||
{
|
||||
std::cerr << "nntp section does not have 'bind' value" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(nntpconf.find("instance_name") == nntpconf.end()) {
|
||||
if (nntpconf.find("instance_name") == nntpconf.end())
|
||||
{
|
||||
std::cerr << "nntp section lacks 'instance_name' value" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
nntp.SetInstanceName(nntpconf["instance_name"]);
|
||||
|
||||
if (nntpconf.find("authdb") != nntpconf.end()) {
|
||||
if (nntpconf.find("authdb") != nntpconf.end())
|
||||
{
|
||||
nntp.SetLoginDB(nntpconf["authdb"]);
|
||||
}
|
||||
|
||||
if ( level.sections.find("frontend") != level.sections.end())
|
||||
if (level.sections.find("frontend") != level.sections.end())
|
||||
{
|
||||
// frontend enabled
|
||||
auto & frontconf = level.sections["frontend"].values;
|
||||
auto &frontconf = level.sections["frontend"].values;
|
||||
if (frontconf.find("type") == frontconf.end())
|
||||
{
|
||||
std::cerr << "frontend section provided but 'type' value not provided" << std::endl;
|
||||
@@ -91,38 +98,38 @@ int main(int argc, char * argv[]) {
|
||||
}
|
||||
else if (ftype == "staticfile")
|
||||
{
|
||||
auto required = {
|
||||
"template_dir", "out_dir", "template_dialect", "max_pages"
|
||||
};
|
||||
for (const auto & opt : required)
|
||||
auto required = {"template_dir", "out_dir", "template_dialect", "max_pages"};
|
||||
for (const auto &opt : required)
|
||||
{
|
||||
if(frontconf.find(opt) == frontconf.end())
|
||||
if (frontconf.find(opt) == frontconf.end())
|
||||
{
|
||||
std::cerr << "staticfile frontend specified but no '" << opt << "' value provided" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
auto maxPages = std::stoi(frontconf["max_pages"]);
|
||||
if(maxPages <= 0)
|
||||
if (maxPages <= 0)
|
||||
{
|
||||
std::cerr << "max_pages invalid value '" << frontconf["max_pages"] << "'" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
nntp.SetFrontend(new nntpchan::StaticFileFrontend(nntpchan::CreateTemplateEngine(frontconf["template_dialect"]), frontconf["template_dir"], frontconf["out_dir"], maxPages));
|
||||
nntp.SetFrontend(new nntpchan::StaticFileFrontend(nntpchan::CreateTemplateEngine(frontconf["template_dialect"]),
|
||||
frontconf["template_dir"], frontconf["out_dir"], maxPages));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "unknown frontend type '" << ftype << "'" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
auto & a = nntpconf["bind"];
|
||||
auto &a = nntpconf["bind"];
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
nntp.Bind(a);
|
||||
} catch ( std::exception & ex ) {
|
||||
} catch (std::exception &ex)
|
||||
{
|
||||
std::cerr << "failed to bind: " << ex.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
@@ -130,11 +137,10 @@ int main(int argc, char * argv[]) {
|
||||
std::cerr << "nntpd for " << nntp.InstanceName() << " bound to " << a << std::endl;
|
||||
|
||||
loop.Run();
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "failed to open " << fname << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user