|
|
nono 0.0.1
//
// nono
// Copyright (C) 2018 [email protected]
//
#include "configfile.h"
#include <sys/stat.h>
Config *gConfig;
// コンストラクタ
Config::Config(const std::string& dir)
{
assert(!dir.empty());
dirname = dir;
if (dirname.back() != '/') {
dirname.push_back('/');
}
filename = dirname + "config.ini";
}
// デストラクタ
Config::~Config()
{
}
// 設定ファイルをロードする。
// 成功すれば true を返す。
bool
Config::Load()
{
char buf[1024];
FILE *fp;
int line;
bool rv = false;
fp = fopen(filename.c_str(), "r");
if (fp == NULL) {
warn("config file cannot open: %s", filename.c_str());
return false;
}
for (line = 1; fgets(buf, sizeof(buf), fp) != NULL; line++) {
const char *key = buf;
char *val;
// chomp
buf[strcspn(buf, "\r\n")] = '\0';
// 空行は無視
if (buf[0] == '\0') {
continue;
}
// '=' の前後で key, val に分ける
val = strchr(buf, '=');
if (val == NULL) {
warnx("%s: %d: syntax error", filename.c_str(), line);
goto abort;
}
*val++ = '\0';
map[key] = val;
}
rv = true;
abort:
fclose(fp);
return rv;
}
// 変数 key の値を int として読み出します。
// 変数がなければ defaultvalue を返します。
// 変数があって整数として解釈できない場合は 0 になります。
int
Config::ReadInt(const char *key, int defaultvalue)
{
if (map.count(key)) {
const std::string& str = map[key];
return atoi(str.c_str());
} else {
return defaultvalue;
}
}
// 変数 key の値を文字列として読み出します。
// 変数がなければ defaultvalue を返します。
std::string
Config::ReadStr(const char *key, const std::string& defaultvalue)
{
if (map.count(key)) {
return map[key];
} else {
return defaultvalue;
}
}
// 関連するファイルのパスを取得。
std::string
Config::SearchFile(const char *name_c) const
{
std::string name = name_c;
std::string path;
struct stat st;
// ファイルがあるかどうかを調べるだけで、存在したけどそれに何らか
// 不都合があったら次を試すとかはしない。
// 1. 設定ファイルディレクトリ
path = GetConfigDir() + name;
if (stat(path.c_str(), &st) == 0) {
return path;
}
// 2. 共通ディレクトリ(?)
// XXX 共通ディレクトリを返す関数を用意したほうがいいか
path = GetConfigDir() + "../" + name;
if (stat(path.c_str(), &st) == 0) {
return path;
}
return "";
}
// エラー表示を共通化したい
void
Config::Err(const std::string& key, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
Errv(key.c_str(), fmt, ap);
va_end(ap);
}
// エラー表示を共通化したい
void
Config::Err(const char *key, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
Errv(key, fmt, ap);
va_end(ap);
}
// エラー表示本体
void
Config::Errv(const char *key, const char *fmt, va_list ap)
{
char fmtbuf[1024];
vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, ap);
warnx("%s: \"%s\": %s", GetFilename().c_str(), key, fmtbuf);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.