diff options
Diffstat (limited to 'utils/imxtools/regtools/desc_parser.cpp')
-rw-r--r-- | utils/imxtools/regtools/desc_parser.cpp | 265 |
1 files changed, 0 insertions, 265 deletions
diff --git a/utils/imxtools/regtools/desc_parser.cpp b/utils/imxtools/regtools/desc_parser.cpp deleted file mode 100644 index 940a619f5c..0000000000 --- a/utils/imxtools/regtools/desc_parser.cpp +++ /dev/null | |||
@@ -1,265 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "desc_parser.hpp" | ||
22 | #include <libxml/parser.h> | ||
23 | #include <libxml/tree.h> | ||
24 | #include <stdio.h> | ||
25 | #include <string.h> | ||
26 | |||
27 | #define XML_CHAR_TO_CHAR(s) ((const char *)(s)) | ||
28 | |||
29 | #define BEGIN_ATTR_MATCH(attr) \ | ||
30 | for(xmlAttr *a = attr; a; a = a->next) { | ||
31 | |||
32 | #define MATCH_X_ATTR(attr_name, hook, ...) \ | ||
33 | if(strcmp(XML_CHAR_TO_CHAR(a->name), attr_name) == 0) { \ | ||
34 | std::string s; \ | ||
35 | if(!parse_text_attr(a, s) || !hook(s, __VA_ARGS__)) \ | ||
36 | return false; \ | ||
37 | } | ||
38 | |||
39 | #define SOFT_MATCH_X_ATTR(attr_name, hook, ...) \ | ||
40 | if(strcmp(XML_CHAR_TO_CHAR(a->name), attr_name) == 0) { \ | ||
41 | std::string s; \ | ||
42 | if(parse_text_attr(a, s)) \ | ||
43 | hook(s, __VA_ARGS__); \ | ||
44 | } | ||
45 | |||
46 | #define SOFT_MATCH_SCT_ATTR(attr_name, var) \ | ||
47 | SOFT_MATCH_X_ATTR(attr_name, validate_sct_hook, var) | ||
48 | |||
49 | #define MATCH_TEXT_ATTR(attr_name, var) \ | ||
50 | MATCH_X_ATTR(attr_name, validate_string_hook, var) | ||
51 | |||
52 | #define MATCH_UINT32_ATTR(attr_name, var) \ | ||
53 | MATCH_X_ATTR(attr_name, validate_uint32_hook, var) | ||
54 | |||
55 | #define MATCH_BITRANGE_ATTR(attr_name, first, last) \ | ||
56 | MATCH_X_ATTR(attr_name, validate_bitrange_hook, first, last) | ||
57 | |||
58 | #define END_ATTR_MATCH() \ | ||
59 | } | ||
60 | |||
61 | #define BEGIN_NODE_MATCH(node) \ | ||
62 | for(xmlNode *sub = node; sub; sub = sub->next) { | ||
63 | |||
64 | #define MATCH_ELEM_NODE(node_name, array, parse_fn) \ | ||
65 | if(sub->type == XML_ELEMENT_NODE && strcmp(XML_CHAR_TO_CHAR(sub->name), node_name) == 0) { \ | ||
66 | array.resize(array.size() + 1); \ | ||
67 | if(!parse_fn(sub, array[array.size() - 1])) \ | ||
68 | return false; \ | ||
69 | } | ||
70 | |||
71 | #define SOFT_MATCH_ELEM_NODE(node_name, array, parse_fn) \ | ||
72 | if(sub->type == XML_ELEMENT_NODE && strcmp(XML_CHAR_TO_CHAR(sub->name), node_name) == 0) { \ | ||
73 | array.resize(array.size() + 1); \ | ||
74 | if(!parse_fn(sub, array[array.size() - 1])) \ | ||
75 | array.pop_back(); \ | ||
76 | } | ||
77 | |||
78 | #define END_NODE_MATCH() \ | ||
79 | } | ||
80 | |||
81 | bool validate_string_hook(const std::string& str, std::string& s) | ||
82 | { | ||
83 | s = str; | ||
84 | return true; | ||
85 | } | ||
86 | |||
87 | bool validate_sct_hook(const std::string& str, soc_reg_flags_t& flags) | ||
88 | { | ||
89 | if(str == "yes") flags |= REG_HAS_SCT; | ||
90 | else if(str != "no") return false; | ||
91 | return true; | ||
92 | } | ||
93 | |||
94 | bool validate_unsigned_long_hook(const std::string& str, unsigned long& s) | ||
95 | { | ||
96 | char *end; | ||
97 | s = strtoul(str.c_str(), &end, 0); | ||
98 | return *end == 0; | ||
99 | } | ||
100 | |||
101 | bool validate_uint32_hook(const std::string& str, uint32_t& s) | ||
102 | { | ||
103 | unsigned long u; | ||
104 | if(!validate_unsigned_long_hook(str, u)) return false; | ||
105 | #if ULONG_MAX > UINT32_MAX | ||
106 | if(u > UINT32_MAX) return false; | ||
107 | #endif | ||
108 | s = u; | ||
109 | return true; | ||
110 | } | ||
111 | |||
112 | bool validate_bitrange_hook(const std::string& str, unsigned& first, unsigned& last) | ||
113 | { | ||
114 | unsigned long a, b; | ||
115 | size_t sep = str.find(':'); | ||
116 | if(sep == std::string::npos) return false; | ||
117 | if(!validate_unsigned_long_hook(str.substr(0, sep), a)) return false; | ||
118 | if(!validate_unsigned_long_hook(str.substr(sep + 1), b)) return false; | ||
119 | if(a > 31 || b > 31 || a < b) return false; | ||
120 | first = b; | ||
121 | last = a; | ||
122 | return true; | ||
123 | } | ||
124 | |||
125 | bool parse_text_attr(xmlAttr *attr, std::string& s) | ||
126 | { | ||
127 | if(attr->children != attr->last) | ||
128 | return false; | ||
129 | if(attr->children->type != XML_TEXT_NODE) | ||
130 | return false; | ||
131 | s = XML_CHAR_TO_CHAR(attr->children->content); | ||
132 | return true; | ||
133 | } | ||
134 | |||
135 | bool parse_value_elem(xmlNode *node, soc_reg_field_value_t& value) | ||
136 | { | ||
137 | BEGIN_ATTR_MATCH(node->properties) | ||
138 | MATCH_TEXT_ATTR("name", value.name) | ||
139 | MATCH_UINT32_ATTR("value", value.value) | ||
140 | END_ATTR_MATCH() | ||
141 | |||
142 | return true; | ||
143 | } | ||
144 | |||
145 | bool parse_field_elem(xmlNode *node, soc_reg_field_t& field) | ||
146 | { | ||
147 | BEGIN_ATTR_MATCH(node->properties) | ||
148 | MATCH_TEXT_ATTR("name", field.name) | ||
149 | MATCH_BITRANGE_ATTR("bitrange", field.first_bit, field.last_bit) | ||
150 | END_ATTR_MATCH() | ||
151 | |||
152 | BEGIN_NODE_MATCH(node->children) | ||
153 | SOFT_MATCH_ELEM_NODE("value", field.values, parse_value_elem) | ||
154 | END_NODE_MATCH() | ||
155 | |||
156 | return true; | ||
157 | } | ||
158 | |||
159 | bool parse_reg_elem(xmlNode *node, soc_reg_t& reg) | ||
160 | { | ||
161 | BEGIN_ATTR_MATCH(node->properties) | ||
162 | MATCH_TEXT_ATTR("name", reg.name) | ||
163 | MATCH_UINT32_ATTR("addr", reg.addr) | ||
164 | SOFT_MATCH_SCT_ATTR("sct", reg.flags) | ||
165 | END_ATTR_MATCH() | ||
166 | |||
167 | BEGIN_NODE_MATCH(node->children) | ||
168 | MATCH_ELEM_NODE("field", reg.fields, parse_field_elem) | ||
169 | END_NODE_MATCH() | ||
170 | |||
171 | return true; | ||
172 | } | ||
173 | |||
174 | bool parse_multireg_elem(xmlNode *node, soc_multireg_t& mreg) | ||
175 | { | ||
176 | BEGIN_ATTR_MATCH(node->properties) | ||
177 | MATCH_TEXT_ATTR("name", mreg.name) | ||
178 | MATCH_UINT32_ATTR("base", mreg.base) | ||
179 | MATCH_UINT32_ATTR("count", mreg.count) | ||
180 | MATCH_UINT32_ATTR("offset", mreg.offset) | ||
181 | SOFT_MATCH_SCT_ATTR("sct", mreg.flags) | ||
182 | END_ATTR_MATCH() | ||
183 | |||
184 | BEGIN_NODE_MATCH(node->children) | ||
185 | MATCH_ELEM_NODE("reg", mreg.regs, parse_reg_elem) | ||
186 | MATCH_ELEM_NODE("field", mreg.fields, parse_field_elem) | ||
187 | END_NODE_MATCH() | ||
188 | |||
189 | return true; | ||
190 | } | ||
191 | |||
192 | bool parse_dev_elem(xmlNode *node, soc_dev_t& dev) | ||
193 | { | ||
194 | BEGIN_ATTR_MATCH(node->properties) | ||
195 | MATCH_TEXT_ATTR("name", dev.name) | ||
196 | MATCH_UINT32_ATTR("addr", dev.addr) | ||
197 | MATCH_TEXT_ATTR("long_name", dev.long_name) | ||
198 | MATCH_TEXT_ATTR("desc", dev.desc) | ||
199 | END_ATTR_MATCH() | ||
200 | |||
201 | BEGIN_NODE_MATCH(node->children) | ||
202 | MATCH_ELEM_NODE("multireg", dev.multiregs, parse_multireg_elem) | ||
203 | MATCH_ELEM_NODE("reg", dev.regs, parse_reg_elem) | ||
204 | END_NODE_MATCH() | ||
205 | |||
206 | return true; | ||
207 | } | ||
208 | |||
209 | bool parse_multidev_elem(xmlNode *node, soc_multidev_t& dev) | ||
210 | { | ||
211 | BEGIN_ATTR_MATCH(node->properties) | ||
212 | MATCH_TEXT_ATTR("name", dev.name) | ||
213 | MATCH_TEXT_ATTR("long_name", dev.long_name) | ||
214 | MATCH_TEXT_ATTR("desc", dev.desc) | ||
215 | END_ATTR_MATCH() | ||
216 | |||
217 | BEGIN_NODE_MATCH(node->children) | ||
218 | MATCH_ELEM_NODE("dev", dev.devs, parse_dev_elem) | ||
219 | MATCH_ELEM_NODE("multireg", dev.multiregs, parse_multireg_elem) | ||
220 | MATCH_ELEM_NODE("reg", dev.regs, parse_reg_elem) | ||
221 | END_NODE_MATCH() | ||
222 | |||
223 | return true; | ||
224 | } | ||
225 | |||
226 | bool parse_soc_elem(xmlNode *node, soc_t& soc) | ||
227 | { | ||
228 | BEGIN_ATTR_MATCH(node->properties) | ||
229 | MATCH_TEXT_ATTR("name", soc.name) | ||
230 | MATCH_TEXT_ATTR("desc", soc.desc) | ||
231 | END_ATTR_MATCH() | ||
232 | |||
233 | BEGIN_NODE_MATCH(node->children) | ||
234 | MATCH_ELEM_NODE("dev", soc.devs, parse_dev_elem) | ||
235 | MATCH_ELEM_NODE("multidev", soc.multidevs, parse_multidev_elem) | ||
236 | END_NODE_MATCH() | ||
237 | |||
238 | return true; | ||
239 | } | ||
240 | |||
241 | bool parse_root_elem(xmlNode *node, std::vector< soc_t >& socs) | ||
242 | { | ||
243 | BEGIN_NODE_MATCH(node) | ||
244 | MATCH_ELEM_NODE("soc", socs, parse_soc_elem) | ||
245 | END_NODE_MATCH() | ||
246 | return true; | ||
247 | } | ||
248 | |||
249 | bool parse_soc_desc(const std::string& filename, std::vector< soc_t >& socs) | ||
250 | { | ||
251 | LIBXML_TEST_VERSION | ||
252 | |||
253 | xmlDoc *doc = xmlReadFile(filename.c_str(), NULL, 0); | ||
254 | if(doc == NULL) | ||
255 | return false; | ||
256 | |||
257 | xmlNode *root_element = xmlDocGetRootElement(doc); | ||
258 | |||
259 | bool ret = parse_root_elem(root_element, socs); | ||
260 | |||
261 | xmlFreeDoc(doc); | ||
262 | xmlCleanupParser(); | ||
263 | |||
264 | return ret; | ||
265 | } \ No newline at end of file | ||