| 6 | | namespace i3 { |
| 7 | | namespace config { |
| 8 | | using namespace std; |
| 9 | | using namespace boost::spirit; |
| 10 | | struct ConfigTemp { |
| 11 | | ////MACRO WILL BE EXPANDED |
| 12 | | //boost::int32_t i; |
| 13 | | //TCHAR* s; |
| 14 | | //std::list<boost::int32_t> ia; |
| 15 | | //std::list<TCHAR*> sa; |
| 16 | | |
| 17 | | #define I3_CONFIG_MACRO_TEMP(r, data, elem) \ |
| 18 | | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), i3_config_integer) , boost::int32_t, \ |
| 19 | | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), i3_config_string) , TCHAR*, \ |
| 20 | | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), i3_config_integer_array) , std::list<boost::int32_t>, std::list<TCHAR*>))) \ |
| | 6 | namespace i3 |
| | 7 | { |
| | 8 | namespace config |
| | 9 | { |
| | 10 | using namespace std; |
| | 11 | using namespace boost::spirit; |
| | 12 | struct ConfigTemp |
| | 13 | { |
| | 14 | ////MACRO WILL BE EXPANDED |
| | 15 | //boost::int32_t i; |
| | 16 | //TCHAR* s; |
| | 17 | //std::list<boost::int32_t> ia; |
| | 18 | //std::list<TCHAR*> sa; |
| | 19 | |
| | 20 | #define I3_CONFIG_MACRO_TEMP(r, data, elem) \ |
| | 21 | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), I3_CONFIG_integer) , boost::int32_t, \ |
| | 22 | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), I3_CONFIG_string) , TCHAR*, \ |
| | 23 | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), I3_CONFIG_integer_array) , std::list<boost::int32_t>, std::list<TCHAR*>))) \ |
| 23 | | BOOST_PP_SEQ_FOR_EACH(I3_CONFIG_MACRO_TEMP, data, CONFIG_MEMBERS) |
| 24 | | }; |
| 25 | | |
| 26 | | struct integer_list { |
| 27 | | boost::int32_t value; |
| 28 | | size_t length; |
| 29 | | integer_list* prev; |
| 30 | | integer_list* tail; |
| 31 | | integer_list() : value(0), length(0), prev(NULL), tail(this) {} |
| 32 | | ~integer_list() { |
| 33 | | for (integer_list* current = tail; current->prev != NULL;) { |
| 34 | | integer_list* prev = current->prev; |
| 35 | | free(current); |
| 36 | | current = prev; |
| 37 | | } |
| 38 | | } |
| 39 | | }; |
| 40 | | struct string_list { |
| 41 | | TCHAR* value; |
| 42 | | size_t length; |
| 43 | | string_list* prev; |
| 44 | | string_list* tail; |
| 45 | | string_list() : value(NULL), length(0), prev(NULL), tail(this) {} |
| 46 | | ~string_list() { |
| 47 | | for (string_list* current = tail; current->prev != NULL;) { |
| 48 | | string_list* prev = current->prev; |
| 49 | | free(current); |
| 50 | | current = prev; |
| 51 | | } |
| 52 | | } |
| 53 | | }; |
| 54 | | struct integer_array { |
| 55 | | boost::int32_t* data; |
| 56 | | size_t length; |
| 57 | | integer_array operator=(integer_list& list) { |
| 58 | | length = list.length; |
| 59 | | if (length == 0) { |
| 60 | | data = NULL; |
| 61 | | return *this; |
| 62 | | } |
| 63 | | data = (boost::int32_t*)malloc(sizeof(*data)*length); |
| 64 | | if (data == NULL) { |
| | 26 | BOOST_PP_SEQ_FOR_EACH(I3_CONFIG_MACRO_TEMP, data, CONFIG_MEMBERS) |
| | 27 | }; |
| | 28 | |
| | 29 | /* |
| | 30 | struct integer_list |
| | 31 | { |
| | 32 | boost::int32_t value; |
| | 33 | size_t length; |
| | 34 | integer_list* prev; |
| | 35 | integer_list* tail; |
| | 36 | integer_list() : value(0), length(0), prev(NULL), tail(this) {} |
| | 37 | ~integer_list() |
| | 38 | { |
| | 39 | for (integer_list* current = tail; current->prev != NULL;) |
| | 40 | { |
| | 41 | integer_list* prev = current->prev; |
| | 42 | free(current); |
| | 43 | current = prev; |
| | 44 | } |
| | 45 | } |
| | 46 | }; |
| | 47 | struct string_list |
| | 48 | { |
| | 49 | TCHAR* value; |
| | 50 | size_t length; |
| | 51 | string_list* prev; |
| | 52 | string_list* tail; |
| | 53 | string_list() : value(NULL), length(0), prev(NULL), tail(this) {} |
| | 54 | ~string_list() |
| | 55 | { |
| | 56 | for (string_list* current = tail; current->prev != NULL;) |
| | 57 | { |
| | 58 | string_list* prev = current->prev; |
| | 59 | free(current); |
| | 60 | current = prev; |
| | 61 | } |
| | 62 | } |
| | 63 | }; |
| | 64 | struct integer_array |
| | 65 | { |
| | 66 | boost::int32_t* data; |
| | 67 | size_t length; |
| | 68 | integer_array operator=(integer_list& list) |
| | 69 | { |
| | 70 | length = list.length; |
| | 71 | if (length == 0) |
| | 72 | { |
| | 73 | data = NULL; |
| | 74 | return *this; |
| | 75 | } |
| | 76 | data = (boost::int32_t*)malloc(sizeof(*data)*length); |
| | 77 | if (data == NULL) |
| | 78 | { |
| | 79 | abort(); |
| | 80 | } |
| | 81 | size_t written = 0; |
| | 82 | for (integer_list* current = list.tail; written < length && current->prev != NULL; current = current->prev, written++) |
| | 83 | { |
| | 84 | data[written] = current->value; |
| | 85 | } |
| | 86 | return *this; |
| | 87 | } |
| | 88 | }; |
| | 89 | struct string_array |
| | 90 | { |
| | 91 | TCHAR** data; |
| | 92 | size_t length; |
| | 93 | string_array& operator=(string_list& list) |
| | 94 | { |
| | 95 | length = list.length; |
| | 96 | if (length == 0) |
| | 97 | { |
| | 98 | data = NULL; |
| | 99 | return *this; |
| | 100 | } |
| | 101 | data = (TCHAR**)malloc(sizeof(*data)*length); |
| | 102 | if (data == NULL) |
| | 103 | { |
| | 104 | abort(); |
| | 105 | } |
| | 106 | size_t written = 0; |
| | 107 | for (string_list* current = list.tail; written < length && current->prev != NULL; current = current->prev, written++) |
| | 108 | { |
| | 109 | data[written] = current->value; |
| | 110 | } |
| | 111 | return *this; |
| | 112 | } |
| | 113 | }; |
| | 114 | */ |
| | 115 | struct MyIniLoader : public grammar<MyIniLoader> |
| | 116 | { |
| | 117 | struct integer_value |
| | 118 | { |
| | 119 | boost::int32_t& data; |
| | 120 | integer_value(boost::int32_t& data) : data(data) {} |
| | 121 | void operator()(int value) const |
| | 122 | { |
| | 123 | data = value; |
| | 124 | } |
| | 125 | }; |
| | 126 | struct integer_array_value |
| | 127 | { |
| | 128 | //integer_list& data; |
| | 129 | //integer_array_value(integer_list& data) : data(data) {} |
| | 130 | //void operator()(boost::int32_t value) const { |
| | 131 | // integer_list* got = (integer_list*)malloc(sizeof(integer_list)); |
| | 132 | // if (!got) { |
| | 133 | // abort(); |
| | 134 | // } |
| | 135 | // got->value = value; |
| | 136 | // got->prev = data.tail; |
| | 137 | // data.tail = got; |
| | 138 | // data.length++; |
| | 139 | //} |
| | 140 | list<boost::int32_t>& data; |
| | 141 | integer_array_value(list<boost::int32_t>& data) : data(data) {} |
| | 142 | void operator()(int value) const |
| | 143 | { |
| | 144 | try |
| | 145 | { |
| | 146 | data.push_back(value); |
| | 147 | } |
| | 148 | catch (exception&) |
| | 149 | { |
| 87 | | size_t written = 0; |
| 88 | | for (string_list* current = list.tail; written < length && current->prev != NULL; current = current->prev, written++) { |
| 89 | | data[written] = current->value; |
| 90 | | } |
| 91 | | return *this; |
| 92 | | } |
| 93 | | }; |
| 94 | | |
| 95 | | struct MyIniLoader : public grammar<MyIniLoader> |
| 96 | | { |
| 97 | | struct integer_value { |
| 98 | | boost::int32_t& data; |
| 99 | | integer_value(boost::int32_t& data) : data(data) {} |
| 100 | | void operator()(int value) const { |
| 101 | | data = value; |
| 102 | | } |
| 103 | | }; |
| 104 | | struct integer_array_value { |
| 105 | | //integer_list& data; |
| 106 | | //integer_array_value(integer_list& data) : data(data) {} |
| 107 | | //void operator()(boost::int32_t value) const { |
| 108 | | // integer_list* got = (integer_list*)malloc(sizeof(integer_list)); |
| 109 | | // if (!got) { |
| 110 | | // abort(); |
| 111 | | // } |
| 112 | | // got->value = value; |
| 113 | | // got->prev = data.tail; |
| 114 | | // data.tail = got; |
| 115 | | // data.length++; |
| 116 | | //} |
| 117 | | list<boost::int32_t>& data; |
| 118 | | integer_array_value(list<boost::int32_t>& data) : data(data) {} |
| 119 | | void operator()(int value) const { |
| 120 | | try { |
| 121 | | data.push_back(value); |
| 122 | | } catch (exception&) { |
| 123 | | abort(); |
| 124 | | } |
| 125 | | } |
| 126 | | }; |
| 127 | | struct string_value { |
| 128 | | TCHAR*& data; |
| 129 | | string_value(TCHAR*& data) : data(data) {} |
| 130 | | void operator()(const TCHAR* first, const TCHAR* last) const { |
| 131 | | ptrdiff_t bytes = (const char*)last - (const char*)first; |
| 132 | | data = (TCHAR*)calloc(bytes + sizeof(TCHAR), 1); |
| 133 | | if (!data) { |
| 134 | | abort(); |
| 135 | | } |
| 136 | | memcpy(data, first, bytes); |
| 137 | | } |
| 138 | | }; |
| 139 | | struct string_array_value { |
| 140 | | //string_list& data; |
| 141 | | //string_array_value(string_list& data) : data(data) {} |
| 142 | | //void operator()(const TCHAR* first, const TCHAR* last) const { |
| 143 | | // ptrdiff_t bytes = (char*)last - (char*)first; |
| 144 | | // string_list* got = (string_list*)malloc(sizeof(string_list)); |
| 145 | | // if (!got) { |
| 146 | | // abort(); |
| 147 | | // } |
| 148 | | // got->value = (TCHAR*)calloc(bytes + sizeof(TCHAR), 1); |
| 149 | | // if (!got->value) { |
| 150 | | // abort(); |
| 151 | | // } |
| 152 | | // memcpy(got->value, first, bytes); |
| 153 | | // got->prev = data.tail; |
| 154 | | // data.tail = got; |
| 155 | | // data.length++; |
| 156 | | //} |
| 157 | | list<TCHAR*>& data; |
| 158 | | string_array_value(list<TCHAR*>& data) : data(data) {} |
| 159 | | void operator()(const TCHAR* first, const TCHAR* last) const { |
| 160 | | ptrdiff_t bytes = (const char*)last - (const char*)first; |
| 161 | | TCHAR* value = (TCHAR*)calloc(bytes + sizeof(TCHAR), 1); |
| 162 | | if (!value) { |
| 163 | | abort(); |
| 164 | | } |
| 165 | | memcpy(value, first, bytes); |
| 166 | | try { |
| 167 | | data.push_back(value); |
| 168 | | } catch (exception&) { |
| 169 | | abort(); |
| 170 | | } |
| 171 | | } |
| 172 | | }; |
| 173 | | |
| 174 | | ////MACRO WILL BE EXPANDED |
| 175 | | //integer_value i; |
| 176 | | //string_value s; |
| 177 | | //integer_array_value ia; |
| 178 | | //string_array_value sa; |
| 179 | | |
| 180 | | #define I3_CONFIG_MACRO_PARSER(r, data, elem) \ |
| 181 | | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), i3_config_integer) , integer_value, \ |
| 182 | | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), i3_config_string) , string_value, \ |
| 183 | | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), i3_config_integer_array) , integer_array_value, string_array_value))) \ |
| | 166 | memcpy(data, first, bytes); |
| | 167 | } |
| | 168 | }; |
| | 169 | struct string_array_value |
| | 170 | { |
| | 171 | //string_list& data; |
| | 172 | //string_array_value(string_list& data) : data(data) {} |
| | 173 | //void operator()(const TCHAR* first, const TCHAR* last) const { |
| | 174 | // ptrdiff_t bytes = (char*)last - (char*)first; |
| | 175 | // string_list* got = (string_list*)malloc(sizeof(string_list)); |
| | 176 | // if (!got) { |
| | 177 | // abort(); |
| | 178 | // } |
| | 179 | // got->value = (TCHAR*)calloc(bytes + sizeof(TCHAR), 1); |
| | 180 | // if (!got->value) { |
| | 181 | // abort(); |
| | 182 | // } |
| | 183 | // memcpy(got->value, first, bytes); |
| | 184 | // got->prev = data.tail; |
| | 185 | // data.tail = got; |
| | 186 | // data.length++; |
| | 187 | //} |
| | 188 | list<TCHAR*>& data; |
| | 189 | string_array_value(list<TCHAR*>& data) : data(data) {} |
| | 190 | void operator()(const TCHAR* first, const TCHAR* last) const |
| | 191 | { |
| | 192 | ptrdiff_t bytes = (const char*)last - (const char*)first; |
| | 193 | TCHAR* value = (TCHAR*)calloc(bytes + sizeof(TCHAR), 1); |
| | 194 | if (!value) |
| | 195 | { |
| | 196 | abort(); |
| | 197 | } |
| | 198 | memcpy(value, first, bytes); |
| | 199 | try |
| | 200 | { |
| | 201 | data.push_back(value); |
| | 202 | } |
| | 203 | catch (exception&) |
| | 204 | { |
| | 205 | abort(); |
| | 206 | } |
| | 207 | } |
| | 208 | }; |
| | 209 | |
| | 210 | ////MACRO WILL BE EXPANDED |
| | 211 | //integer_value i; |
| | 212 | //string_value s; |
| | 213 | //integer_array_value ia; |
| | 214 | //string_array_value sa; |
| | 215 | |
| | 216 | #define I3_CONFIG_MACRO_PARSER(r, data, elem) \ |
| | 217 | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), I3_CONFIG_integer) , integer_value, \ |
| | 218 | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), I3_CONFIG_string) , string_value, \ |
| | 219 | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), I3_CONFIG_integer_array) , integer_array_value, string_array_value))) \ |
| 198 | | BOOST_PP_SEQ_FOR_EACH(I3_CONFIG_MACRO_INITIALIZER, data, CONFIG_MEMBERS) |
| 199 | | |
| 200 | | |
| 201 | | {} |
| 202 | | |
| 203 | | template<typename S> struct definition |
| 204 | | { |
| 205 | | rule<S> expr; |
| 206 | | rule<S> line_ending; |
| 207 | | definition(const MyIniLoader& self) |
| 208 | | { |
| 209 | | using namespace boost; |
| 210 | | |
| 211 | | int_parser<int32_t, 10, integer_traits<int32_t>::const_max, integer_traits<int32_t>::const_min> boost_int32_t_p; |
| 212 | | |
| 213 | | line_ending = str_p(_T("\r\n")) | ch_p(_T('\r')) | ch_p(_T('\n')) | end_p; |
| 214 | | expr = ( |
| 215 | | ////MACRO WILL BE EXPANDED |
| 216 | | //(*blank_p >> str_p(_T("Integer")) >> +blank_p >> str_p(_T("i")) >> *blank_p >> _T("=") >> *blank_p >> int_p[self.i] >> *blank_p) | |
| 217 | | //(*blank_p >> str_p(_T("Integer[]")) >> +blank_p >> str_p(_T("ia")) >> *blank_p >> _T("=") >> *blank_p >> int_p[self.ia] >> *blank_p) | |
| 218 | | //(*blank_p >> str_p(_T("String")) >> +blank_p >> str_p(_T("s")) >> *blank_p >> _T("=") >> *blank_p >> (*(anychar_p - line_ending))[self.s]) | |
| 219 | | //(*blank_p >> str_p(_T("String[]")) >> +blank_p >> str_p(_T("sa")) >> *blank_p >> _T("=") >> *blank_p >> (*(anychar_p - line_ending))[self.sa]) | |
| 220 | | |
| 221 | | |
| 222 | | #define I3_CONFIG_MACRO_SPIRIT(r, data, elem) \ |
| | 234 | BOOST_PP_SEQ_FOR_EACH(I3_CONFIG_MACRO_INITIALIZER, data, CONFIG_MEMBERS) |
| | 235 | |
| | 236 | |
| | 237 | {} |
| | 238 | |
| | 239 | template<typename S> struct definition |
| | 240 | { |
| | 241 | rule<S> expr; |
| | 242 | rule<S> line_ending; |
| | 243 | definition(const MyIniLoader& self) |
| | 244 | { |
| | 245 | using namespace boost; |
| | 246 | |
| | 247 | int_parser<int32_t, 10, integer_traits<int32_t>::const_max, integer_traits<int32_t>::const_min> boost_int32_t_p; |
| | 248 | |
| | 249 | line_ending = str_p(_T("\r\n")) | ch_p(_T('\r')) | ch_p(_T('\n')) | end_p; |
| | 250 | expr = ( |
| | 251 | ////MACRO WILL BE EXPANDED |
| | 252 | //(*blank_p >> str_p(_T("Integer")) >> +blank_p >> str_p(_T("i")) >> *blank_p >> _T("=") >> *blank_p >> int_p[self.i] >> *blank_p) | |
| | 253 | //(*blank_p >> str_p(_T("Integer[]")) >> +blank_p >> str_p(_T("ia")) >> *blank_p >> _T("=") >> *blank_p >> int_p[self.ia] >> *blank_p) | |
| | 254 | //(*blank_p >> str_p(_T("String")) >> +blank_p >> str_p(_T("s")) >> *blank_p >> _T("=") >> *blank_p >> (*(anychar_p - line_ending))[self.s]) | |
| | 255 | //(*blank_p >> str_p(_T("String[]")) >> +blank_p >> str_p(_T("sa")) >> *blank_p >> _T("=") >> *blank_p >> (*(anychar_p - line_ending))[self.sa]) | |
| | 256 | |
| | 257 | |
| | 258 | #define I3_CONFIG_MACRO_SPIRIT(r, data, elem) \ |
| 226 | | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), i3_config_integer) , _T("Integer"), \ |
| 227 | | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), i3_config_string) , _T("String"), \ |
| 228 | | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), i3_config_integer_array) , _T("Integer[]"), _T("String[]")))) \ |
| | 262 | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), I3_CONFIG_integer) , _T("Integer"), \ |
| | 263 | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), I3_CONFIG_string) , _T("String"), \ |
| | 264 | BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_TUPLE_ELEM(3, 0, elem), I3_CONFIG_integer_array) , _T("Integer[]"), _T("String[]")))) \ |