| | 67 | } |
| | 68 | |
| | 69 | #include <boost/spirit.hpp> |
| | 70 | using namespace std; |
| | 71 | |
| | 72 | namespace i3_myini { |
| | 73 | using namespace boost::spirit; |
| | 74 | |
| | 75 | struct integer_list { |
| | 76 | int i; |
| | 77 | integer_list* next; |
| | 78 | }; |
| | 79 | struct string_list { |
| | 80 | char* s; |
| | 81 | string_list* next; |
| | 82 | }; |
| | 83 | struct Config { |
| | 84 | int i; |
| | 85 | char* s; |
| | 86 | integer_list ia; |
| | 87 | string_list sa; |
| | 88 | }; |
| | 89 | |
| | 90 | struct MyIniLoader : public grammar<MyIniLoader> |
| | 91 | { |
| | 92 | struct integer_value { |
| | 93 | int& data; |
| | 94 | integer_value(int& data) : data(data) {} |
| | 95 | void operator()(int value) const { |
| | 96 | data = value; |
| | 97 | } |
| | 98 | }; |
| | 99 | struct integer_array_value { |
| | 100 | integer_list& data; |
| | 101 | integer_array_value(integer_list& data) : data(data) {} |
| | 102 | void operator()(int value) const { |
| | 103 | data.i = value; |
| | 104 | data.next = (integer_list*)malloc(sizeof(data)); |
| | 105 | if (!data.next) { |
| | 106 | abort(); |
| | 107 | } |
| | 108 | data.next->next = NULL; |
| | 109 | } |
| | 110 | }; |
| | 111 | struct string_value { |
| | 112 | char*& data; |
| | 113 | string_value(char*& data) : data(data) {} |
| | 114 | void operator()(const char* first, const char* last) const { |
| | 115 | if (data) { |
| | 116 | free(data); |
| | 117 | } |
| | 118 | data = (char*)calloc(last - first + 1, 1); |
| | 119 | if (!data) { |
| | 120 | abort(); |
| | 121 | } |
| | 122 | memcpy(data, first, last - first); |
| | 123 | } |
| | 124 | }; |
| | 125 | struct string_array_value { |
| | 126 | string_list& data; |
| | 127 | string_array_value(string_list& data) : data(data) {} |
| | 128 | void operator()(const char* first, const char* last) const { |
| | 129 | data.s = (char*)calloc(last - first + 1, 1); |
| | 130 | if (!data.s) { |
| | 131 | abort(); |
| | 132 | } |
| | 133 | memcpy(data.s, first, last - first); |
| | 134 | data.next = (string_list*)malloc(sizeof(data)); |
| | 135 | if (!data.next) { |
| | 136 | abort(); |
| | 137 | } |
| | 138 | data.next->next = NULL; |
| | 139 | } |
| | 140 | }; |
| | 141 | |
| | 142 | integer_value i; |
| | 143 | string_value s; |
| | 144 | integer_array_value ia; |
| | 145 | string_array_value sa; |
| | 146 | |
| | 147 | Config& config; |
| | 148 | MyIniLoader(Config& config) : config(config) |
| | 149 | , i(config.i) |
| | 150 | , ia(config.ia) |
| | 151 | , s(config.s) |
| | 152 | , sa(config.sa) |
| | 153 | {} |
| | 154 | |
| | 155 | template<typename S> struct definition |
| | 156 | { |
| | 157 | // ���@�� |
| | 158 | // expr ::= term ('+' term | '-' term)* |
| | 159 | // term ::= fctr ('*' fctr | '/' fctr)* |
| | 160 | // fctr ::= int | '(' expr ')' |
| | 161 | // |
| | 162 | // �J�n�L�� |
| | 163 | // expr |
| | 164 | |
| | 165 | rule<S> expr; |
| | 166 | |
| | 167 | definition(const MyIniLoader& self) |
| | 168 | { |
| | 169 | expr = *space_p << str_p("FOO=") << int_p[ia] << *space_p; |
| | 170 | } |
| | 171 | |
| | 172 | const rule<S>& start() const { return expr; } |
| | 173 | }; |
| | 174 | }; |
| | 175 | } |
| | 176 | |
| | 177 | BOOST_AUTO_TEST_CASE(test_configboostasiodfj) |
| | 178 | { |
| | 179 | using namespace i3_myini; |
| | 180 | using namespace boost::spirit; |
| | 181 | Config c; |
| | 182 | MyIniLoader i; |
| | 183 | std::string str = "FOO=1 "; |
| | 184 | parse_info<> r = parse(str.c_str(), i); |
| | 185 | if( r.full ) { |
| | 186 | cout << "c.i: " << c.i << endl; |
| | 187 | } else { |
| | 188 | cout << "error" << endl; |
| | 189 | } |