|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2018 [email protected]
4: //
5:
6: #include "configfile.h"
7: #include <sys/stat.h>
8:
9: Config *gConfig;
10:
11: // コンストラクタ
12: Config::Config(const std::string& dir)
13: {
14: assert(!dir.empty());
15: dirname = dir;
16: if (dirname.back() != '/') {
17: dirname.push_back('/');
18: }
19:
20: filename = dirname + "config.ini";
21: }
22:
23: // デストラクタ
24: Config::~Config()
25: {
26: }
27:
28: // 設定ファイルをロードする。
29: // 成功すれば true を返す。
30: bool
31: Config::Load()
32: {
33: char buf[1024];
34: FILE *fp;
35: int line;
36: bool rv = false;
37:
38: fp = fopen(filename.c_str(), "r");
39: if (fp == NULL) {
40: warn("config file cannot open: %s", filename.c_str());
41: return false;
42: }
43:
44: for (line = 1; fgets(buf, sizeof(buf), fp) != NULL; line++) {
45: const char *key = buf;
46: char *val;
47:
48: // chomp
49: buf[strcspn(buf, "\r\n")] = '\0';
50:
51: // 空行は無視
52: if (buf[0] == '\0') {
53: continue;
54: }
55:
56: // '=' の前後で key, val に分ける
57: val = strchr(buf, '=');
58: if (val == NULL) {
59: warnx("%s: %d: syntax error", filename.c_str(), line);
60: goto abort;
61: }
62:
63: *val++ = '\0';
64:
65: map[key] = val;
66: }
67:
68: rv = true;
69: abort:
70: fclose(fp);
71: return rv;
72: }
73:
74: // 変数 key の値を int として読み出します。
75: // 変数がなければ defaultvalue を返します。
76: // 変数があって整数として解釈できない場合は 0 になります。
77: int
78: Config::ReadInt(const char *key, int defaultvalue)
79: {
80: if (map.count(key)) {
81: const std::string& str = map[key];
82: return atoi(str.c_str());
83: } else {
84: return defaultvalue;
85: }
86: }
87:
88: // 変数 key の値を文字列として読み出します。
89: // 変数がなければ defaultvalue を返します。
90: std::string
91: Config::ReadStr(const char *key, const std::string& defaultvalue)
92: {
93: if (map.count(key)) {
94: return map[key];
95: } else {
96: return defaultvalue;
97: }
98: }
99:
100: // 関連するファイルのパスを取得。
101: std::string
102: Config::SearchFile(const char *name_c) const
103: {
104: std::string name = name_c;
105: std::string path;
106: struct stat st;
107:
108: // ファイルがあるかどうかを調べるだけで、存在したけどそれに何らか
109: // 不都合があったら次を試すとかはしない。
110:
111: // 1. 設定ファイルディレクトリ
112: path = GetConfigDir() + name;
113: if (stat(path.c_str(), &st) == 0) {
114: return path;
115: }
116:
117: // 2. 共通ディレクトリ(?)
118: // XXX 共通ディレクトリを返す関数を用意したほうがいいか
119: path = GetConfigDir() + "../" + name;
120: if (stat(path.c_str(), &st) == 0) {
121: return path;
122: }
123:
124: return "";
125: }
126:
127: // エラー表示を共通化したい
128: void
129: Config::Err(const std::string& key, const char *fmt, ...)
130: {
131: va_list ap;
132:
133: va_start(ap, fmt);
134: Errv(key.c_str(), fmt, ap);
135: va_end(ap);
136: }
137:
138: // エラー表示を共通化したい
139: void
140: Config::Err(const char *key, const char *fmt, ...)
141: {
142: va_list ap;
143:
144: va_start(ap, fmt);
145: Errv(key, fmt, ap);
146: va_end(ap);
147: }
148:
149: // エラー表示本体
150: void
151: Config::Errv(const char *key, const char *fmt, va_list ap)
152: {
153: char fmtbuf[1024];
154:
155: vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, ap);
156: warnx("%s: \"%s\": %s", GetFilename().c_str(), key, fmtbuf);
157: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.