|
|
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.