|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2018 [email protected] ! 4: // ! 5: ! 6: // 設定ファイルは、テキスト形式、行志向で順序を持たない key=value ペアの羅列、 ! 7: // アプリケーションが書き戻しを行わないためユーザが任意にコメント行を入れる ! 8: // ことが出来る、タイプのもの。 ! 9: // ! 10: // 設定(Config)は次の3段階によって確定する。 ! 11: // c1. 初期値 ! 12: // 項目はそれぞれ固有の初期値を持っている。ここでいう初期値は単なるゼロ ! 13: // クリアではなく、その項目に最も自然な、あるいは極力問題なく動作するよう ! 14: // 選択した値のこと。 ! 15: // c2. 設定ファイル ! 16: // 設定ファイルで指定された値はそれを上書きする。 ! 17: // c3. コマンドライン引数 ! 18: // コマンドライン引数で指定された値はそれを上書きする。 ! 19: // ! 20: // おそらくたぶんすべての項目が例外なくこのように動作するようにしたい。 ! 21: ! 22: #pragma once ! 23: ! 24: #include "header.h" ! 25: #include <vector> ! 26: ! 27: // 設定の1項目 ! 28: class ConfigItem ! 29: { ! 30: friend class Config; ! 31: ! 32: public: ! 33: enum from_t { ! 34: FromInitial = 0, // 初期値 ! 35: FromConfig, // 設定ファイルで更新 ! 36: FromOption, // コマンドライン引数で更新 ! 37: }; ! 38: ! 39: public: ! 40: ConfigItem() { }; ! 41: ConfigItem(const std::string& key_, const std::string& val_, ! 42: from_t from_, const std::string& where_) { ! 43: key = key_; ! 44: value = val_; ! 45: from = from_; ! 46: where = where_; ! 47: } ! 48: virtual ~ConfigItem() { }; ! 49: ! 50: // 値を文字列のまま取得する。 ! 51: const std::string& AsString() const { return value; } ! 52: ! 53: // 値を整数値として取得する。 ! 54: // この関数はよく似たことをたびたびやるのを避けるために提供してある ! 55: // ただのユーティリティ関数。変換できない場合や空文字列の場合 0 に ! 56: // なるので、それでもよければ使ってよい。 ! 57: int AsInt() const { return atoi(value.c_str()); } ! 58: ! 59: // デフォルト値を差し替える。 ! 60: // この変数が FromInitial なら値(初期値)を val に差し替える。この時 ! 61: // from は FromInitial のまま。 ! 62: // FromInitial でなければ (ユーザが値を上書きしていれば) 何もしない。 ! 63: // 本来は初期値設定 -> 設定ファイルやオプションで上書きの順に動作する ! 64: // のが理想だが、設定ファイルを読まないと VM 種別が確定しないにわたま ! 65: // 問題のため、VM 種別によって初期値が決定する場合などはデバイスの ! 66: // コンストラクタでこれを呼び出すこと。例えば mpu-clock など。 ! 67: void SetDefault(const std::string& val); ! 68: void SetDefault(int val); ! 69: ! 70: // from を取得する ! 71: from_t GetFrom() const { return from; } ! 72: ! 73: // この項目で "invalid argument" を warnx() で出力する ! 74: void Err() const; ! 75: ! 76: // この項目での指定のエラーメッセージを warnx() で出力する ! 77: void Err(const std::string& msg) const; ! 78: void Err(const char *fmt, ...) const; ! 79: ! 80: private: ! 81: // key が変数名、value が値。 ! 82: // value はここでは文字列でありそれ以上の構造は持たないが、 ! 83: // 整数値として解釈する或いはカンマ区切りにするなどは使う側の裁量。 ! 84: // value からは前後の空白は削除する。 ! 85: // またエスケープの類も今の所ない。 ! 86: std::string key {}; ! 87: std::string value {}; ! 88: ! 89: // from (と where) はこの変数の由来を示す。 ! 90: // o FromOption なら値は -V オプションで指定されたことを示す。 ! 91: // o FromConfig なら値は設定ファイルで指定されたことを示す。 ! 92: // この場合 where に "ファイルパス:行番号" が入っている。 ! 93: // o FromInitial なら値は初期値のままであることを示す。引数や ! 94: // 設定ファイルで値を指定した場合は例え初期値と同じ値を指定したと ! 95: // しても初期値扱いとはしない。 ! 96: from_t from {}; ! 97: std::string where {}; ! 98: }; ! 99: ! 100: // 設定ファイル ! 101: class ConfigFile ! 102: { ! 103: public: ! 104: ConfigFile(const std::string& filepath_); ! 105: virtual ~ConfigFile(); ! 106: ! 107: // ファイルの読み込み。 ! 108: // 成功すれば true を返す。失敗すればエラーを表示して false を返す。 ! 109: bool Load(); ! 110: ! 111: // パス ! 112: std::string filepath {}; ! 113: ! 114: // 読み込んだ行一覧 ! 115: // 行(改行と前後の空白を除く) と行番号(1から始まる)の pair。 ! 116: // コメント行や空行は取り除いてあるが、文法チェックはしていないので ! 117: // 何か書いてある行の集合。 ! 118: std::vector<std::pair<std::string, int>> lines {}; ! 119: }; ! 120: ! 121: // 設定 ! 122: class Config ! 123: { ! 124: public: ! 125: Config(); ! 126: virtual ~Config(); ! 127: ! 128: // 設定ファイルの内容で上書きする ! 129: bool Update(const ConfigFile& file); ! 130: ! 131: // コマンドライン引数の内容で上書きする ! 132: bool Update(const std::vector<std::string>& options); ! 133: ! 134: // 内容を表示する ! 135: void Show() const; ! 136: ! 137: // key から ConfigItem を取得する。 ! 138: // key は必ず存在するので参照を返す。 ! 139: // 見付からなければ assert する。それはプログラムミスなので。 ! 140: const ConfigItem& Get(const std::string& key) const; ! 141: ConfigItem& Get(const std::string& key); ! 142: ! 143: private: ! 144: // 項目を追加 (初期状態用) ! 145: bool Add(const std::string& key); ! 146: bool Add(const std::string& key, int value); ! 147: bool Add(const std::string& key, const std::string& value); ! 148: ! 149: // key から ConfigItem を返す。見付からなければ NULL を返す。 ! 150: // (こっちは内部で変更するために使う) ! 151: ConfigItem *FindItem(const std::string& key); ! 152: ! 153: // 更新1行分の共通処理 ! 154: bool UpdateLine(const std::string& line, ConfigItem::from_t, ! 155: const std::string& from); ! 156: ! 157: // "key=val" 形式の行から key, val を取り出す。 ! 158: static bool SplitKeyVal(std::string *keyp, std::string *valp, ! 159: const std::string& line); ! 160: ! 161: // 設定項目の集合 ! 162: std::vector<ConfigItem> list {}; ! 163: }; ! 164: ! 165: extern std::unique_ptr<Config> gConfig;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.