readconf  1.6
設定ファイル読み込みモジュール
 全て データ構造 ファイル 関数 変数 型定義 列挙型 列挙型の値 マクロ定義 グループ
readconf ドキュメント

概要

readconf モジュールは、 Unix 系のプログラムで使用される設定ファイルを読み込むための、 関数 readconf() と構造体 RCConfItem などを提供します。

読み込み中にエラーが発生した場合、途中で停止しません。 発生したエラーの情報を、エラー情報構造体 RCError の配列 RCRaisedErrors に格納します。

設定ファイル

設定ファイルは、次のような定義式の行の集まりです。

項目名1 = 値1 <改行>
項目名2 = 値2 <改行>
...

シャープ記号 (#) で始まるコメントを書くことも出来ます。

値の型は、読み込み時にアプリケーションが指定します。 例えば Item = 3.14 と記述しても、 アプリケーションが文字列型で読み込むように指定した場合は、 文字列として読み込まれます。 また、整数型と指定すれば型違いエラーが発生します。

文字列型を定義する場合は、引用符で囲むことができます。 両端の引用符は読み込み時に取り除かれます。

文字列は引用符で囲む必要はありませんが、 その場合コメント開始文字 # を含めることができません。 コメント開始文字 # を含める場合は、 文字列の両端を引用符で囲んでください。

なお、文字列型の定義中にエスケープ文字を使用することは出来ません。 したがって文字列中に改行文字を入力する方法はありません。

以下は設定ファイルの記述例です。

# sample.conf for readconf module
StringConf = "String Conf Value" # 文字列の項目
NumberConf = 12 # 数値の項目
HexNumberConf = 0xdeadbeef # 16進数の項目
OctalNumberConf = 012 # 8進数の項目
RealNumberConf = -0.345e+2 # 実数型の項目
BoolConf = true # 真偽値型の項目

使い方

readconf() の使い方は、次のような手順になります。

  1. 読み込みたい設定項目名とデフォルト値を設定した、 設定項目構造体配列を用意する。
  2. readconf() に上で用意した設定項目構造体配列と 設定ファイルのパス名を渡す。
  3. グローバル変数 RCNumRaisedErrors が 0 以上の場合は、読み込む際にエラーが発生しているので、 エラー情報構造体配列を解析する。
  4. 設定項目構造体配列の内容を取り出す。

設定項目構造体配列の準備

設定項目構造体配列はグローバル変数として定義するとよいでしょう。

配列を定義する際は初期値として、項目名、型、 デフォルト値を与えます。 デフォルト値は値を読み込めなかった時に使用されます。 配列を定義する際は文字列として与えますが、 readconf() 実行時に指定した型に変換されます。

オプションで、読み込んだ値を検証する関数のアドレスを登録することも出来ます。 この検証関数は値を読み込んだ時に呼び出されます。 値が適正だったら true を、適正でなければ false を返すように定義してください。 false が返ると読み込みエラーが発生し、項目の値はデフォルト値が設定されます。

もう一つのオプションとして、 読み込んだ文字列を数値に変換する関数のアドレスを登録することも出来ます。 この変換関数は、整数または実数型として定義された項目の値を文字列として読み込んだ時に、 検証関数より先に呼び出されます。 引数で渡された文字列を数値に変換して、 変換が成功したら true を、変換できなかったら false を返すように定義してください。 false が返ると読み込みエラーが発生し、項目の値はデフォルト値が設定されます。

以下の配列の定義例では、8つの設定項目を定義しています。 また、配列の各項目に対応するインデックスも列挙型として定義しています。

#include "readconf.h"
bool validateRange(char *name, RCValueType type, RCConfValue value);
RCConfItem SampleConfItems[] =
{
// 項目名, 型, デフォルト値, 検証関数, 変換関数
{ "StringConf", RCValueTypeString, "default string" },
{ "NumberConf", RCValueTypeInteger, "14" },
{ "HexNumberConf", RCValueTypeInteger, "0x0000ffff" },
{ "OctalNumberConf", RCValueTypeInteger, "017" },
{ "RealNumberConf", RCValueTypeReal, "-.987e-1" },
{ "BoolConf", RCValueTypeBool, "false" },
{ "ValidationConf", RCValueTypeInteger, "50000", validateRange },
{ "ConstantConf", RCValueTypeInteger, "Two", NULL, convertNumber },
};
enum SampleConfItemIndex
{
StringConfIndex,
NumberConfIndex,
HexNumberConfIndex,
OctalNumberConfIndex,
RealNumberConfIndex,
BoolConfIndex,
ValidationConfIndex,
ConstantConf,
NumSampleConfItem // 要素数
};
bool validateRange(const char *name, RCValueType type, RCConfValue value)
{
return value.integer >= 40960 && value.integer <= 65535;
}
bool convertNumber(const char *name, RCValueType type,
const char *string, RCConfValue *value)
{
const char *const numbers[] = { "Zero", "One", "Two" };
int i;
for (i = 0; i < ELEMENTSOF(numbers); i++)
{
if (strcmp(string, numbers[i]) == 0)
{
value->integer = i;
return true;
}
}
return false;
}

項目名

項目名は、文字列で指定します。 設定ファイルを読み込む際には、大文字と小文字は無視されるので、 同じ名前を指定しないように注意してください。

項目名に使用可能な文字は、空白文字とコメント開始文字 (#) と 等号記号 (=) を除く文字です。例えば英数字や、 マイナス記号 (-) や、ドット (.) などを使用することができます。

型に指定できるのは、次の 4 つです。

シンボル
文字列 RCValueTypeString
整数(long) RCValueTypeInteger
実数(double) RCValueTypeReal
真偽値(bool) RCValueTypeBool

真偽値は、 true/false もしくは yes/no で表される文字列として 設定ファイル中に記述できます。 (ただし引用符では囲みません。)

デフォルト値

デフォルト値は、設定ファイルに指定した項目名が定義されていない場合や、 設定ファイルを読み込めなかった場合に値に設定されます。

型が整数型や実数型であっても文字列で指定します。

検証関数

読み込んだ値を検証するための関数へのポインタを登録します。

検証関数は、登録した項目の値を読み込んだ時に呼び出されます。 プロトタイプ宣言は次のようになります。

bool validator(const char *name, RCValueType type, RCConfValue value);

引数 nametype に渡されるのは、 検証関数を登録した項目の名前と型ですので、 検証関数の中で名前と型をチェックする必要はないでしょう。 しかし、もし同じ検証関数を別の複数の項目に登録するのであれば、 これらの引数を使って区別することができます。

検証関数は、値が適正だったら true を、 適正でなければ false を返すように定義してください。 false が返ると readconf() は読み込みエラーを発生させ、 項目の値にはデフォルト値を設定します。

変換関数

読み込んだ文字列を変換するための関数へのポインタを登録します。

変換関数は、整数型もしくは実数型の項目の値を読み込んだ時に、 検証関数より前に呼び出されます。 プロトタイプ宣言は次のようになります。

bool convertor(const char *name, RCValueType type, const char *string, RCConfValue *value);

引数 nametype に渡されるのは、 変換関数を登録した項目の名前と型ですので、 変換関数の中でこれらをチェックする必要はないでしょう。 しかし、もし同じ変換関数を複数の項目に登録するのであれば、 これらの引数を使って区別することができます。

変換関数は、値を変換できたら true を、 変換できなかったら false を返すように定義してください。 false が返ると readconf() は読み込みエラーを発生させ、 項目の値にはデフォルト値を設定します。

readconf() の呼び出し

readconf() を呼び出す場合は、設定項目構造体配列のアドレス、 配列の要素数、設定ファイルのパス名を指定します。

配列の要素数は、上の定義例のように、 列挙型としてインデックスを定義した最後に、 要素数も定義すると便利です。 また、配列の要素数を算出する ELEMENTSOF() マクロを定義してありますので、 こちらを使うことも出来ます。

エラー情報構造体

エラー情報構造体配列 RCRaisedErrors には、 設定ファイル読み込み時に発生したエラー情報が格納されます。 発生したエラー情報の数、すなわち配列の要素数は RCNumRaisedErrors に格納されます。

エラー情報構造体配列を解放するには、 RCFreeRaisedErrors() を使用します。

設定項目構造体

設定項目構造体配列には、 readconf() によって読み込まれた値が メンバ RCConfItem.value に設定されます。 RCConfItem.value は共用体 RCConfValue で、 RCConfItem.type で指定された型に対応したメンバに値が設定されます。 型とメンバの対応は次のようになります。

シンボル メンバ
文字列 RCValueTypeString string
整数(long) RCValueTypeInteger integer
実数(double)RCValueTypeReal real
真偽値(bool)RCValueTypeBool boolean