summaryrefslogtreecommitdiff
path: root/utils/regtools/desc_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/regtools/desc_parser.cpp')
-rw-r--r--utils/regtools/desc_parser.cpp265
1 files changed, 265 insertions, 0 deletions
diff --git a/utils/regtools/desc_parser.cpp b/utils/regtools/desc_parser.cpp
new file mode 100644
index 0000000000..940a619f5c
--- /dev/null
+++ b/utils/regtools/desc_parser.cpp
@@ -0,0 +1,265 @@
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
81bool validate_string_hook(const std::string& str, std::string& s)
82{
83 s = str;
84 return true;
85}
86
87bool 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
94bool 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
101bool 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
112bool 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
125bool 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
135bool 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
145bool 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
159bool 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
174bool 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
192bool 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
209bool 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
226bool 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
241bool 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
249bool 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