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 に丸投げしてしまってもいい。