Comment detail

設定ファイルから値を取得 (Nested Flatten)
Boost.Spirit を使って。
Javaのpropertiesファイルみたいな
KEY = VALUE
KEY2 = VALUE2
:
形式のファイルを読み込みます。

#で始まる行はコメントとして読み飛ばします。
また、KEYに使えるのがアルファベット、数字、
アンダーバー、ハイフンのみという制約が
あります。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <map>
#include <string>
#include <stdexcept>
#include <fstream>

#include <boost/spirit.hpp>
#include <boost/spirit/actor/assign_actor.hpp>
#include <boost/spirit/actor/insert_at_actor.hpp>
#include <boost/algorithm/string/trim.hpp>

class PropertyFileReader
{
    public:
        //! key-value paired map type
        typedef std::map<std::string, std::string> property_map_type;

    public:
        static property_map_type
            read(
                    std::istream& is
                );

};


PropertyFileReader::property_map_type
PropertyFileReader::read(
        std::istream& is
        )
{
    using namespace boost::spirit;

    property_map_type prop;
    property_map_type::key_type prop_key;

    rule<> comment_r = comment_p("#");
    rule<> name_r = (alpha_p | ch_p('_')) >> *( alnum_p | ch_p('_') | ch_p('-'));
    rule<> key_r = name_r[assign_a(prop_key)];
    rule<> value_r = (*(anychar_p - eol_p))[insert_at_a(prop, prop_key)];

    rule<> kvpair_r = (key_r >> *blank_p >> ch_p('=') >> *blank_p >> value_r);

    rule<> commentline_r = *blank_p >> comment_r;
    rule<> emptyline_r = *blank_p >> eol_p;
    rule<> kvpairline_r = *blank_p >> kvpair_r >> eol_p;

    rule<> prop_r = *( commentline_r || emptyline_r || kvpairline_r ) >> end_p;

    // slurp stream
    std::string content;
    while ( !is.eof() ) {
        std::string line;
        std::getline(is,line);
        content += line + "\n";
    }

    parse_info<> result = parse(content.c_str(), prop_r);

    if ( !result.full ) {
        throw std::runtime_error("couldn't parse properties");
    }

    // trim following white spaces in value
    for ( property_map_type::iterator it = prop.begin(); it != prop.end(); ++it )
        boost::algorithm::trim(it->second);

    return prop;
}

int main(int c, char** v)
{
  if ( c != 3 ) {
    std::cout << "usage " << v[0] << " <property file> <key name>\n";
    return 0;
  }

  try {
    PropertyFileReader::property_map_type map(
        PropertyFileReader().read(std::ifstream(v[1])) );

    std::cout << v[2] << " = " << map[std::string(v[2])] << "\n";
  }
  catch ( const std::exception& e ) {
    std::cerr << "ERROR: " << e.what() << "\n";
    return 1;
  }
  return 0;
}

Index

Feed

Other

Link

Pathtraq

loading...