読者です 読者をやめる 読者になる 読者になる

ボレロ村上 - ENiyGmaA Code

中3女子です。

boost/property_tree/ini_parser.hpp

 Boost.PropertyTree にはINIパーサがある。

foo
{
    a aaa
    b bbb
}
bar
{
    c ccc
}

 このような木構造を書出すと、

[foo]
a=aaa
b=bbb
[bar]
c=ccc

のように出力される。
 もちろん、読込はこの逆になる。

foo
{
    a aaa
    b bbb
    bar
    {
        c ccc
    }
}

 このような木構造は、パースエラーになる。
INIフォーマットは深い階層構造を想定していない。
これはINIの仕様上からの規定なので、妥当である。


 このような構造をINIに書出すためには、

[foo]
a=aaa
b=bbb
[foo.bar]
c=ccc

 キーをセパレータで結合して一つのセクション名にする、
といった処理が考えられる。
 実際、そのようにしてINIで階層構造を表現している例は多々ある。


 問題は、以下である。

foo
{
    a aaa
    b bbb
    esc "\n escapes"
}

 値に改行を含む木構造を書出すと、

[foo]
a=aaa
b=bbb
esc=
 escapes

エスケープなどの処理は行われない。
boost::property_tree::write_ini は、文字列を直に書出すのみである。


 こうして書出されたINIを再び読み込むと、当然ながらエラーになる。
INIフォーマットは、一行ずつ処理されるからだ。
当然ながらINIパーサは、読込時にエスケープシーケンスを解釈したりもしない。


 この問題はBoost.PropertyTreeのINIパーサの実装の手抜きというよりも、
INIフォーマットの仕様の曖昧さにあるといってよいのではないか。
 だいたい、キー(セクション名)の重複を許すかどうかといった
至極基本的な部分さえ仕様で規定されていないというのはどうしたものか。
(INIパーサの実装ではエラーにしているが)
デファクトスタンダードとはいえ、適当すぎる。


 改行の問題については、エスケープシーケンスの変換/展開処理を
挟めばとりあえず問題はない。
この処理は、boost::property_tree::info_parser::create_escapes と
boost::property_tree::info_parser::expand_escapes に丸投げしてしまってもいい。