bzr branch
http://suren.me/webbzr/alps/pcitool
277.2.1
by zilio nicolas
registers and banks support in xml v1. pci -ll works fine, but got segfault on pci -r name and pci -r name gives 0 always. might be due to the order in pci.c ------> ask suren |
1 |
/**
|
324
by Suren A. Chilingaryan
Documentation update |
2 |
* @file xml.c
|
277.2.1
by zilio nicolas
registers and banks support in xml v1. pci -ll works fine, but got segfault on pci -r name and pci -r name gives 0 always. might be due to the order in pci.c ------> ask suren |
3 |
* @version 1.0
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
4 |
*
|
277.2.1
by zilio nicolas
registers and banks support in xml v1. pci -ll works fine, but got segfault on pci -r name and pci -r name gives 0 always. might be due to the order in pci.c ------> ask suren |
5 |
* @brief this file is the main source file for the implementation of dynamic registers using xml and several funtionalities for the "pci-tool" line command tool from XML files. the xml part has been implemented using libxml2
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
6 |
*
|
277.2.17
by zilio nicolas
further modifications |
7 |
* @details registers and banks nodes are parsed using xpath expression, but their properties is get by recursively getting all properties nodes. In this sense, if a property changes, the algorithm has to be changed, but if it's registers or banks nodes, just the xpath expression modification should be enough.
|
8 |
||
277.2.1
by zilio nicolas
registers and banks support in xml v1. pci -ll works fine, but got segfault on pci -r name and pci -r name gives 0 always. might be due to the order in pci.c ------> ask suren |
9 |
Libxml2 considers blank spaces within the XML as node natively and this code as been produced considering blank spaces in the XML files. In case XML files would not contain blank spaces anymore, please change the code.
|
10 |
||
277.2.17
by zilio nicolas
further modifications |
11 |
In case the performance is not good enough, please consider the following : hard code of formulas
|
277.2.1
by zilio nicolas
registers and banks support in xml v1. pci -ll works fine, but got segfault on pci -r name and pci -r name gives 0 always. might be due to the order in pci.c ------> ask suren |
12 |
*/
|
277.2.9
by zilio nicolas
xml files get by model and remove of validation mode |
13 |
#define _XOPEN_SOURCE 700
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
14 |
#define _BSD_SOURCE
|
15 |
#define _DEFAULT_SOURCE
|
|
16 |
||
277.2.1
by zilio nicolas
registers and banks support in xml v1. pci -ll works fine, but got segfault on pci -r name and pci -r name gives 0 always. might be due to the order in pci.c ------> ask suren |
17 |
#include <stdlib.h> |
18 |
#include <stdio.h> |
|
19 |
#include <string.h> |
|
277.2.16
by zilio nicolas
end of modifications |
20 |
#include <strings.h> |
303
by Suren A. Chilingaryan
Initial integration of XML support |
21 |
#include <dirent.h> |
22 |
#include <errno.h> |
|
23 |
#include <alloca.h> |
|
24 |
#include <unistd.h> |
|
25 |
#include <sys/types.h> |
|
26 |
#include <sys/stat.h> |
|
27 |
||
28 |
||
277.2.9
by zilio nicolas
xml files get by model and remove of validation mode |
29 |
#include <libxml/xmlschemastypes.h> |
277.2.13
by zilio nicolas
almost finished regarding suren remarks |
30 |
#include <libxml/tree.h> |
31 |
#include <libxml/parser.h> |
|
32 |
#include <libxml/xpath.h> |
|
33 |
#include <libxml/xpathInternals.h> |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
34 |
|
277.2.17
by zilio nicolas
further modifications |
35 |
#include "config.h" |
36 |
||
303
by Suren A. Chilingaryan
Initial integration of XML support |
37 |
#include "pci.h" |
38 |
#include "bank.h" |
|
39 |
#include "register.h" |
|
40 |
#include "xml.h" |
|
41 |
#include "error.h" |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
42 |
#include "view.h" |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
43 |
#include "py.h" |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
44 |
#include "views/enum.h" |
45 |
#include "views/transform.h" |
|
46 |
||
47 |
||
48 |
#define BANKS_PATH ((xmlChar*)"/model/bank") /**< path to complete nodes of banks */ |
|
49 |
#define REGISTERS_PATH ((xmlChar*)"./register") /**< all standard registers nodes */ |
|
50 |
#define BIT_REGISTERS_PATH ((xmlChar*)"./field") /**< all bits registers nodes */ |
|
51 |
#define REGISTER_VIEWS_PATH ((xmlChar*)"./view") /**< supported register & field views */ |
|
379
by Suren A. Chilingaryan
Support XML configuration of device models |
52 |
#define TRANSFORM_VIEWS_PATH ((xmlChar*)"/model/transform") /**< path to complete nodes of views */ |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
53 |
#define ENUM_VIEWS_PATH ((xmlChar*)"/model/enum") /**< path to complete nodes of views */ |
54 |
#define ENUM_ELEMENTS_PATH ((xmlChar*)"./name") /**< all elements in the enum */ |
|
55 |
#define UNITS_PATH ((xmlChar*)"/model/unit") /**< path to complete nodes of units */ |
|
379
by Suren A. Chilingaryan
Support XML configuration of device models |
56 |
#define UNIT_TRANSFORMS_PATH ((xmlChar*)"./transform") /**< all transforms of the unit */ |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
57 |
|
58 |
||
59 |
static const char *pcilib_xml_bank_default_format = "0x%lx"; |
|
60 |
static const char *pcilib_xml_enum_view_unit = "name"; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
61 |
|
62 |
typedef struct { |
|
63 |
pcilib_register_description_t base; |
|
319
by Suren A. Chilingaryan
Provide register listings in public API |
64 |
pcilib_register_value_range_t range; |
303
by Suren A. Chilingaryan
Initial integration of XML support |
65 |
} pcilib_xml_register_description_t; |
66 |
||
67 |
/*
|
|
68 |
static xmlNodePtr pcilib_xml_get_parent_bank_node(xmlDocPtr doc, xmlNodePtr node) {
|
|
69 |
xmlNodePtr bank_node;
|
|
70 |
bank_node = node->parent->parent;
|
|
71 |
// bank_description is always a first node according to the XSD schema
|
|
72 |
return xmlFirstElementChild(bank_node);
|
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
73 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
74 |
}
|
75 |
||
76 |
static xmlNodePtr pcilib_xml_get_parent_register_node(xmlDocPtr doc, xmlNodePtr node) {
|
|
77 |
return node->parent->parent;
|
|
78 |
}
|
|
79 |
*/
|
|
80 |
||
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
81 |
int pcilib_get_xml_attr(pcilib_t *ctx, pcilib_xml_node_t *node, const char *attr, pcilib_value_t *val) { |
82 |
xmlAttr *prop; |
|
83 |
xmlChar *str; |
|
84 |
||
85 |
prop = xmlHasProp(node, BAD_CAST attr); |
|
86 |
if ((!prop)||(!prop->children)) return PCILIB_ERROR_NOTFOUND; |
|
87 |
||
88 |
str = prop->children->content; |
|
89 |
return pcilib_set_value_from_static_string(ctx, val, (const char*)str); |
|
90 |
}
|
|
91 |
||
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
92 |
static int pcilib_xml_parse_view_reference(pcilib_t *ctx, xmlDocPtr doc, xmlNodePtr node, pcilib_view_reference_t *desc) { |
93 |
xmlAttr *cur; |
|
94 |
char *value, *name; |
|
95 |
||
96 |
for (cur = node->properties; cur != NULL; cur = cur->next) { |
|
97 |
if(!cur->children) continue; |
|
98 |
if(!xmlNodeIsText(cur->children)) continue; |
|
99 |
||
100 |
name = (char*)cur->name; |
|
101 |
value = (char*)cur->children->content; |
|
102 |
||
103 |
if (!strcasecmp(name, "name")) { |
|
104 |
desc->name = value; |
|
105 |
} else if (!strcasecmp(name, "view")) { |
|
106 |
desc->view = value; |
|
107 |
}
|
|
108 |
}
|
|
109 |
||
110 |
if (!desc->name) |
|
111 |
desc->name = desc->view; |
|
112 |
||
305.1.4
by zilio nicolas
more towards views |
113 |
return 0; |
114 |
}
|
|
115 |
||
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
116 |
static int pcilib_xml_parse_register(pcilib_t *ctx, pcilib_xml_register_description_t *xml_desc, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_register_bank_description_t *bdesc) { |
117 |
int err; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
118 |
pcilib_register_description_t *desc = (pcilib_register_description_t*)xml_desc; |
119 |
||
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
120 |
xmlXPathObjectPtr nodes; |
121 |
xmlNodeSetPtr nodeset; |
|
122 |
||
123 |
xmlAttrPtr cur; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
124 |
char *value, *name; |
125 |
char *endptr; |
|
126 |
||
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
127 |
|
128 |
for (cur = node->properties; cur != NULL; cur = cur->next) { |
|
129 |
if (!cur->children) continue; |
|
130 |
if (!xmlNodeIsText(cur->children)) continue; |
|
131 |
||
132 |
name = (char*)cur->name; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
133 |
value = (char*)cur->children->content; |
134 |
if (!value) continue; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
135 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
136 |
if (!strcasecmp((char*)name, "address")) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
137 |
uintptr_t addr = strtol(value, &endptr, 0); |
138 |
if ((strlen(endptr) > 0)) { |
|
139 |
pcilib_error("Invalid address (%s) is specified in the XML register description", value); |
|
140 |
return PCILIB_ERROR_INVALID_DATA; |
|
141 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
142 |
desc->addr = addr; |
143 |
} else if(!strcasecmp(name, "offset")) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
144 |
int offset = strtol(value, &endptr, 0); |
145 |
if ((strlen(endptr) > 0)||(offset < 0)||(offset > (8 * sizeof(pcilib_register_value_t)))) { |
|
146 |
pcilib_error("Invalid offset (%s) is specified in the XML register description", value); |
|
147 |
return PCILIB_ERROR_INVALID_DATA; |
|
148 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
149 |
desc->offset = (pcilib_register_size_t)offset; |
150 |
} else if (!strcasecmp(name,"size")) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
151 |
int size = strtol(value, &endptr, 0); |
152 |
if ((strlen(endptr) > 0)||(size <= 0)||(size > (8 * sizeof(pcilib_register_value_t)))) { |
|
153 |
pcilib_error("Invalid size (%s) is specified in the XML register description", value); |
|
154 |
return PCILIB_ERROR_INVALID_DATA; |
|
155 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
156 |
desc->bits = (pcilib_register_size_t)size; |
157 |
} else if (!strcasecmp(name, "default")) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
158 |
pcilib_register_value_t val = strtol(value, &endptr, 0); |
159 |
if ((strlen(endptr) > 0)) { |
|
160 |
pcilib_error("Invalid default value (%s) is specified in the XML register description", value); |
|
161 |
return PCILIB_ERROR_INVALID_DATA; |
|
162 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
163 |
desc->defvalue = val; |
164 |
} else if (!strcasecmp(name,"min")) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
165 |
pcilib_register_value_t min = strtol(value, &endptr, 0); |
166 |
if ((strlen(endptr) > 0)) { |
|
167 |
pcilib_error("Invalid minimum value (%s) is specified in the XML register description", value); |
|
168 |
return PCILIB_ERROR_INVALID_DATA; |
|
169 |
}
|
|
319
by Suren A. Chilingaryan
Provide register listings in public API |
170 |
xml_desc->range.min = min; |
303
by Suren A. Chilingaryan
Initial integration of XML support |
171 |
} else if (!strcasecmp(name, "max")) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
172 |
pcilib_register_value_t max = strtol(value, &endptr, 0); |
173 |
if ((strlen(endptr) > 0)) { |
|
174 |
pcilib_error("Invalid minimum value (%s) is specified in the XML register description", value); |
|
175 |
return PCILIB_ERROR_INVALID_DATA; |
|
176 |
}
|
|
319
by Suren A. Chilingaryan
Provide register listings in public API |
177 |
xml_desc->range.max = max; |
303
by Suren A. Chilingaryan
Initial integration of XML support |
178 |
} else if (!strcasecmp((char*)name,"rwmask")) { |
179 |
if (!strcasecmp(value, "all")) { |
|
180 |
desc->rwmask = PCILIB_REGISTER_ALL_BITS; |
|
181 |
} else if (!strcasecmp(value, "none")) { |
|
182 |
desc->rwmask = 0; |
|
183 |
} else { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
184 |
uintptr_t mask = strtol(value, &endptr, 0); |
185 |
if ((strlen(endptr) > 0)) { |
|
186 |
pcilib_error("Invalid mask (%s) is specified in the XML register description", value); |
|
187 |
return PCILIB_ERROR_INVALID_DATA; |
|
188 |
}
|
|
189 |
desc->rwmask = mask; |
|
190 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
191 |
} else if (!strcasecmp(name, "mode")) { |
192 |
if (!strcasecmp(value, "R")) { |
|
193 |
desc->mode = PCILIB_REGISTER_R; |
|
194 |
} else if (!strcasecmp(value, "W")) { |
|
195 |
desc->mode = PCILIB_REGISTER_W; |
|
196 |
} else if (!strcasecmp(value, "RW")) { |
|
197 |
desc->mode = PCILIB_REGISTER_RW; |
|
198 |
} else if (!strcasecmp(value, "RW1C")) { |
|
199 |
desc->mode = PCILIB_REGISTER_RW1C; |
|
200 |
} else if (!strcasecmp(value, "W1C")) { |
|
201 |
desc->mode = PCILIB_REGISTER_W1C; |
|
321
by Suren A. Chilingaryan
Support computed (property-based) registers |
202 |
} else if (!strcasecmp(value, "RW1I")) { |
203 |
desc->mode = PCILIB_REGISTER_RW1I; |
|
204 |
} else if (!strcasecmp(value, "W1I")) { |
|
205 |
desc->mode = PCILIB_REGISTER_W1I; |
|
206 |
} else if (!strcasecmp(value, "-")) { |
|
207 |
desc->mode = 0; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
208 |
} else { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
209 |
pcilib_error("Invalid access mode (%s) is specified in the XML register description", value); |
210 |
return PCILIB_ERROR_INVALID_DATA; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
211 |
}
|
212 |
} else if (!strcasecmp(name, "type")) { |
|
213 |
if (!strcasecmp(value, "fifo")) { |
|
214 |
desc->type = PCILIB_REGISTER_FIFO; |
|
215 |
} else { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
216 |
pcilib_error("Invalid register type (%s) is specified in the XML register description", value); |
217 |
return PCILIB_ERROR_INVALID_DATA; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
218 |
}
|
219 |
} else if (!strcasecmp(name,"name")) { |
|
220 |
desc->name = value; |
|
221 |
} else if (!strcasecmp(name,"description")) { |
|
222 |
desc->description = value; |
|
223 |
}
|
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
224 |
}
|
225 |
||
226 |
xpath->node = node; |
|
227 |
nodes = xmlXPathEvalExpression(REGISTER_VIEWS_PATH, xpath); |
|
228 |
xpath->node = NULL; |
|
229 |
||
230 |
if (!nodes) { |
|
231 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
|
232 |
||
233 |
if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", REGISTER_VIEWS_PATH, xmlerr->code, xmlerr->message); |
|
234 |
else pcilib_error("Failed to parse XPath expression %s", REGISTER_VIEWS_PATH); |
|
235 |
return PCILIB_ERROR_FAILED; |
|
236 |
}
|
|
237 |
||
238 |
||
239 |
nodeset = nodes->nodesetval; |
|
240 |
if (!xmlXPathNodeSetIsEmpty(nodeset)) { |
|
241 |
int i; |
|
242 |
||
243 |
desc->views = (pcilib_view_reference_t*)malloc((nodeset->nodeNr + 1) * sizeof(pcilib_view_reference_t)); |
|
244 |
if (!desc->views) { |
|
245 |
xmlXPathFreeObject(nodes); |
|
246 |
pcilib_error("Failed to allocate %zu bytes of memory to store supported register views", (nodeset->nodeNr + 1) * sizeof(char*)); |
|
247 |
return PCILIB_ERROR_MEMORY; |
|
305.1.4
by zilio nicolas
more towards views |
248 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
249 |
|
250 |
memset(desc->views, 0, (nodeset->nodeNr + 1) * sizeof(pcilib_view_reference_t)); |
|
251 |
for (i = 0; i < nodeset->nodeNr; i++) { |
|
252 |
err = pcilib_xml_parse_view_reference(ctx, doc, nodeset->nodeTab[i], &desc->views[i]); |
|
253 |
if (err) { |
|
254 |
xmlXPathFreeObject(nodes); |
|
255 |
return err; |
|
256 |
}
|
|
257 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
258 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
259 |
xmlXPathFreeObject(nodes); |
303
by Suren A. Chilingaryan
Initial integration of XML support |
260 |
|
261 |
return 0; |
|
262 |
}
|
|
263 |
||
264 |
static int pcilib_xml_create_register(pcilib_t *ctx, pcilib_register_bank_t bank, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { |
|
265 |
int err; |
|
266 |
xmlXPathObjectPtr nodes; |
|
267 |
xmlNodeSetPtr nodeset; |
|
268 |
||
269 |
pcilib_xml_register_description_t desc = {{0}}; |
|
270 |
pcilib_xml_register_description_t fdesc; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
271 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
272 |
pcilib_register_t reg; |
305.1.6
by nicolas.zilio at hotmail
more towards views |
273 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
274 |
desc.base.bank = ctx->banks[bank].addr; |
275 |
desc.base.rwmask = PCILIB_REGISTER_ALL_BITS; |
|
276 |
desc.base.mode = PCILIB_REGISTER_R; |
|
277 |
desc.base.type = PCILIB_REGISTER_STANDARD; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
278 |
|
279 |
err = pcilib_xml_parse_register(ctx, &desc, xpath, doc, node, &ctx->banks[bank]); |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
280 |
if (err) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
281 |
pcilib_error("Error (%i) parsing an XML register", err); |
282 |
return err; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
283 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
284 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
285 |
err = pcilib_add_registers(ctx, PCILIB_MODEL_MODIFICATION_FLAG_OVERRIDE, 1, &desc.base, ®); |
286 |
if (err) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
287 |
if (desc.base.views) free(desc.base.views); |
288 |
pcilib_error("Error (%i) adding a new XML register (%s) to the model", err, desc.base.name); |
|
289 |
return err; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
290 |
}
|
291 |
||
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
292 |
ctx->register_ctx[reg].xml = node; |
319
by Suren A. Chilingaryan
Provide register listings in public API |
293 |
memcpy(&ctx->register_ctx[reg].range, &desc.range, sizeof(pcilib_register_value_range_t)); |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
294 |
ctx->register_ctx[reg].views = desc.base.views; |
295 |
||
303
by Suren A. Chilingaryan
Initial integration of XML support |
296 |
|
297 |
xpath->node = node; |
|
298 |
nodes = xmlXPathEvalExpression(BIT_REGISTERS_PATH, xpath); |
|
299 |
xpath->node = NULL; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
300 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
301 |
if (!nodes) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
302 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
303
by Suren A. Chilingaryan
Initial integration of XML support |
303 |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
304 |
if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", BIT_REGISTERS_PATH, xmlerr->code, xmlerr->message); |
305 |
else pcilib_error("Failed to parse XPath expression %s", BIT_REGISTERS_PATH); |
|
306 |
return PCILIB_ERROR_FAILED; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
307 |
}
|
308 |
||
309 |
nodeset = nodes->nodesetval; |
|
310 |
if (!xmlXPathNodeSetIsEmpty(nodeset)) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
311 |
int i; |
312 |
||
313 |
for (i = 0; i < nodeset->nodeNr; i++) { |
|
314 |
memset(&fdesc, 0, sizeof(pcilib_xml_register_description_t)); |
|
315 |
||
316 |
fdesc.base.bank = desc.base.bank; |
|
317 |
fdesc.base.addr = desc.base.addr; |
|
318 |
fdesc.base.mode = desc.base.mode; |
|
319 |
fdesc.base.rwmask = desc.base.rwmask; |
|
320 |
fdesc.base.type = PCILIB_REGISTER_BITS; |
|
321 |
||
322 |
err = pcilib_xml_parse_register(ctx, &fdesc, xpath, doc, nodeset->nodeTab[i], &ctx->banks[bank]); |
|
323 |
if (err) { |
|
324 |
pcilib_error("Error parsing field in the XML register %s", desc.base.name); |
|
325 |
continue; |
|
326 |
}
|
|
327 |
||
328 |
err = pcilib_add_registers(ctx, PCILIB_MODEL_MODIFICATION_FLAG_OVERRIDE, 1, &fdesc.base, ®); |
|
329 |
if (err) { |
|
330 |
if (fdesc.base.views) free(fdesc.base.views); |
|
331 |
pcilib_error("Error (%i) adding a new XML register (%s) to the model", err, fdesc.base.name); |
|
332 |
continue; |
|
333 |
}
|
|
334 |
||
335 |
ctx->register_ctx[reg].xml = nodeset->nodeTab[i]; |
|
319
by Suren A. Chilingaryan
Provide register listings in public API |
336 |
memcpy(&ctx->register_ctx[reg].range, &fdesc.range, sizeof(pcilib_register_value_range_t)); |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
337 |
ctx->register_ctx[reg].views = fdesc.base.views; |
338 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
339 |
}
|
340 |
xmlXPathFreeObject(nodes); |
|
341 |
||
342 |
return 0; |
|
343 |
}
|
|
344 |
||
345 |
static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { |
|
346 |
int err; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
347 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
348 |
int override = 0; |
349 |
pcilib_register_bank_description_t desc = {0}; |
|
350 |
pcilib_register_bank_t bank; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
351 |
xmlAttrPtr cur; |
303
by Suren A. Chilingaryan
Initial integration of XML support |
352 |
char *value, *name; |
353 |
char *endptr; |
|
354 |
||
355 |
xmlXPathObjectPtr nodes; |
|
356 |
xmlNodeSetPtr nodeset; |
|
357 |
||
358 |
||
359 |
desc.format = pcilib_xml_bank_default_format; |
|
360 |
desc.addr = PCILIB_REGISTER_BANK_DYNAMIC; |
|
361 |
desc.bar = PCILIB_BAR_NOBAR; |
|
362 |
desc.size = 0x1000; |
|
363 |
desc.protocol = PCILIB_REGISTER_PROTOCOL_DEFAULT; |
|
364 |
desc.access = 32; |
|
365 |
desc.endianess = PCILIB_HOST_ENDIAN; |
|
366 |
desc.raw_endianess = PCILIB_HOST_ENDIAN; |
|
367 |
||
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
368 |
// iterate through all children, representing bank properties, to fill the structure
|
369 |
for (cur = node->properties; cur != NULL; cur = cur->next) { |
|
370 |
if (!cur->children) continue; |
|
371 |
if (!xmlNodeIsText(cur->children)) continue; |
|
372 |
||
373 |
name = (char*)cur->name; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
374 |
value = (char*)cur->children->content; |
375 |
if (!value) continue; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
376 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
377 |
if (!strcasecmp(name, "bar")) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
378 |
char bar = value[0]-'0'; |
379 |
if ((strlen(value) != 1)||(bar < 0)||(bar > 5)) { |
|
380 |
pcilib_error("Invalid BAR (%s) is specified in the XML bank description", value); |
|
381 |
return PCILIB_ERROR_INVALID_DATA; |
|
382 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
383 |
desc.bar = (pcilib_bar_t)bar; |
384 |
override = 1; |
|
385 |
} else if (!strcasecmp(name,"size")) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
386 |
long size = strtol(value, &endptr, 0); |
387 |
if ((strlen(endptr) > 0)||(size<=0)) { |
|
388 |
pcilib_error("Invalid bank size (%s) is specified in the XML bank description", value); |
|
389 |
return PCILIB_ERROR_INVALID_DATA; |
|
390 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
391 |
desc.size = (size_t)size; |
392 |
override = 1; |
|
393 |
} else if (!strcasecmp(name,"protocol")) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
394 |
pcilib_register_protocol_t protocol = pcilib_find_register_protocol_by_name(ctx, value); |
395 |
if (protocol == PCILIB_REGISTER_PROTOCOL_INVALID) { |
|
396 |
pcilib_error("Unsupported protocol (%s) is specified in the XML bank description", value); |
|
397 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
398 |
}
|
|
399 |
desc.protocol = ctx->protocols[protocol].addr; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
400 |
override = 1; |
401 |
} else if (!strcasecmp(name,"address")) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
402 |
uintptr_t addr = strtol(value, &endptr, 0); |
403 |
if ((strlen(endptr) > 0)) { |
|
404 |
pcilib_error("Invalid address (%s) is specified in the XML bank description", value); |
|
405 |
return PCILIB_ERROR_INVALID_DATA; |
|
406 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
407 |
desc.read_addr = addr; |
408 |
desc.write_addr = addr; |
|
409 |
override = 1; |
|
410 |
} else if (!strcasecmp(name,"read_address")) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
411 |
uintptr_t addr = strtol(value, &endptr, 0); |
412 |
if ((strlen(endptr) > 0)) { |
|
413 |
pcilib_error("Invalid address (%s) is specified in the XML bank description", value); |
|
414 |
return PCILIB_ERROR_INVALID_DATA; |
|
415 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
416 |
desc.read_addr = addr; |
417 |
override = 1; |
|
418 |
} else if (!strcasecmp(name,"write_address")) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
419 |
uintptr_t addr = strtol(value, &endptr, 0); |
420 |
if ((strlen(endptr) > 0)) { |
|
421 |
pcilib_error("Invalid address (%s) is specified in the XML bank description", value); |
|
422 |
return PCILIB_ERROR_INVALID_DATA; |
|
423 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
424 |
desc.write_addr = addr; |
425 |
override = 1; |
|
426 |
} else if(strcasecmp((char*)name,"word_size")==0) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
427 |
int access = strtol(value, &endptr, 0); |
428 |
if ((strlen(endptr) > 0)||(access%8)||(access<=0)||(access>(8 * sizeof(pcilib_register_value_t)))) { |
|
429 |
pcilib_error("Invalid word size (%s) is specified in the XML bank description", value); |
|
430 |
return PCILIB_ERROR_INVALID_DATA; |
|
431 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
432 |
desc.access = access; |
433 |
override = 1; |
|
434 |
} else if (!strcasecmp(name,"endianess")) { |
|
435 |
if (!strcasecmp(value,"little")) desc.endianess = PCILIB_LITTLE_ENDIAN; |
|
436 |
else if (!strcasecmp(value,"big")) desc.endianess = PCILIB_BIG_ENDIAN; |
|
437 |
else if (!strcasecmp(value,"host")) desc.endianess = PCILIB_HOST_ENDIAN; |
|
438 |
else { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
439 |
pcilib_error("Invalid endianess (%s) is specified in the XML bank description", value); |
440 |
return PCILIB_ERROR_INVALID_DATA; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
441 |
}
|
442 |
override = 1; |
|
443 |
} else if (!strcasecmp(name,"format")) { |
|
444 |
desc.format = value; |
|
445 |
override = 1; |
|
446 |
} else if (!strcasecmp((char*)name,"name")) { |
|
447 |
desc.name = value; |
|
448 |
} else if (!strcasecmp((char*)name,"description")) { |
|
449 |
desc.description = value; |
|
450 |
override = 1; |
|
451 |
} else if (!strcasecmp((char*)name,"override")) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
452 |
override = 1; |
303
by Suren A. Chilingaryan
Initial integration of XML support |
453 |
}
|
454 |
}
|
|
455 |
||
456 |
err = pcilib_add_register_banks(ctx, override?PCILIB_MODEL_MODIFICATION_FLAG_OVERRIDE:PCILIB_MODEL_MODIFICATION_FLAG_SKIP_EXISTING, 1, &desc, &bank); |
|
457 |
if (err) { |
|
458 |
pcilib_error("Error adding register bank (%s) specified in the XML bank description", desc.name); |
|
459 |
return err; |
|
460 |
}
|
|
461 |
||
462 |
ctx->xml.bank_nodes[bank] = node; |
|
463 |
if (ctx->bank_ctx[bank]) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
464 |
ctx->bank_ctx[bank]->xml = node; |
303
by Suren A. Chilingaryan
Initial integration of XML support |
465 |
}
|
466 |
||
467 |
xpath->node = node; |
|
468 |
nodes = xmlXPathEvalExpression(REGISTERS_PATH, xpath); |
|
469 |
xpath->node = NULL; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
470 |
|
471 |
if (!nodes) { |
|
472 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
|
473 |
if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", REGISTERS_PATH, xmlerr->code, xmlerr->message); |
|
474 |
else pcilib_error("Failed to parse XPath expression %s", REGISTERS_PATH); |
|
475 |
return PCILIB_ERROR_FAILED; |
|
476 |
}
|
|
477 |
||
478 |
nodeset = nodes->nodesetval; |
|
479 |
if (!xmlXPathNodeSetIsEmpty(nodeset)) { |
|
480 |
int i; |
|
481 |
for (i = 0; i < nodeset->nodeNr; i++) { |
|
482 |
err = pcilib_xml_create_register(ctx, bank, xpath, doc, nodeset->nodeTab[i]); |
|
483 |
if (err) pcilib_error("Error creating XML registers for bank %s", desc.name); |
|
484 |
}
|
|
485 |
}
|
|
486 |
xmlXPathFreeObject(nodes); |
|
487 |
||
488 |
return 0; |
|
489 |
}
|
|
490 |
||
491 |
static int pcilib_xml_parse_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_view_description_t *desc) { |
|
492 |
xmlAttrPtr cur; |
|
493 |
const char *value, *name; |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
494 |
|
495 |
int inconsistent = (desc->mode & PCILIB_ACCESS_INCONSISTENT); |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
496 |
|
497 |
for (cur = node->properties; cur != NULL; cur = cur->next) { |
|
498 |
if (!cur->children) continue; |
|
499 |
if (!xmlNodeIsText(cur->children)) continue; |
|
500 |
||
501 |
name = (char*)cur->name; |
|
502 |
value = (char*)cur->children->content; |
|
503 |
if (!value) continue; |
|
504 |
||
505 |
if (!strcasecmp(name, "name")) { |
|
316
by Suren A. Chilingaryan
Support XML properties |
506 |
// Overriden by path
|
321
by Suren A. Chilingaryan
Support computed (property-based) registers |
507 |
if (desc->name) continue; |
508 |
if (*value == '/') |
|
509 |
desc->flags |= PCILIB_VIEW_FLAG_PROPERTY; |
|
510 |
desc->name = value; |
|
316
by Suren A. Chilingaryan
Support XML properties |
511 |
} else if (!strcasecmp(name, "path")) { |
512 |
desc->name = value; |
|
513 |
desc->flags |= PCILIB_VIEW_FLAG_PROPERTY; |
|
321
by Suren A. Chilingaryan
Support computed (property-based) registers |
514 |
} else if (!strcasecmp(name, "register")) { |
515 |
desc->regname = value; |
|
516 |
desc->flags |= PCILIB_VIEW_FLAG_REGISTER; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
517 |
} else if (!strcasecmp((char*)name, "description")) { |
518 |
desc->description = value; |
|
519 |
} else if (!strcasecmp((char*)name, "unit")) { |
|
520 |
desc->unit = value; |
|
521 |
} else if (!strcasecmp((char*)name, "type")) { |
|
522 |
if (!strcasecmp(value, "string")) desc->type = PCILIB_TYPE_STRING; |
|
523 |
else if (!strcasecmp(value, "float")) desc->type = PCILIB_TYPE_DOUBLE; |
|
524 |
else if (!strcasecmp(value, "int")) desc->type = PCILIB_TYPE_LONG; |
|
525 |
else { |
|
526 |
pcilib_error("Invalid type (%s) of register view is specified in the XML bank description", value); |
|
527 |
return PCILIB_ERROR_INVALID_DATA; |
|
528 |
}
|
|
321
by Suren A. Chilingaryan
Support computed (property-based) registers |
529 |
} else if (!strcasecmp(name, "mode")) { |
530 |
if (!strcasecmp(value, "R")) { |
|
531 |
desc->mode = PCILIB_REGISTER_R; |
|
532 |
} else if (!strcasecmp(value, "W")) { |
|
533 |
desc->mode = PCILIB_REGISTER_W; |
|
534 |
} else if (!strcasecmp(value, "RW")) { |
|
535 |
desc->mode = PCILIB_REGISTER_RW; |
|
536 |
} else if (!strcasecmp(value, "-")) { |
|
537 |
desc->mode = 0; |
|
538 |
} else { |
|
539 |
pcilib_error("Invalid access mode (%s) is specified in the XML register description", value); |
|
540 |
return PCILIB_ERROR_INVALID_DATA; |
|
541 |
}
|
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
542 |
} else if (!strcasecmp(name, "write_verification")) { |
543 |
if (strcmp(value, "0")) inconsistent = 0; |
|
544 |
else inconsistent = 1; |
|
346.1.5
by Vasilii Chernov
Add write_register python wrap. Add no_set_check attribute to pcilib_view_t type |
545 |
}
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
546 |
}
|
346.1.9
by Vasilii Chernov
Change no_set_check parameter name. Move Python wrap to separate directory. |
547 |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
548 |
if (inconsistent) desc->mode |= PCILIB_ACCESS_INCONSISTENT; |
549 |
else desc->mode &= ~PCILIB_ACCESS_INCONSISTENT; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
550 |
|
551 |
return 0; |
|
552 |
}
|
|
553 |
||
554 |
static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { |
|
555 |
int err; |
|
556 |
xmlAttrPtr cur; |
|
557 |
const char *value, *name; |
|
318
by Suren A. Chilingaryan
Support reading/writting register views by id |
558 |
pcilib_view_context_t *view_ctx; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
559 |
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
560 |
pcilib_access_mode_t mode = 0; |
324
by Suren A. Chilingaryan
Documentation update |
561 |
pcilib_transform_view_description_t desc = {{0}}; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
562 |
|
311
by Suren A. Chilingaryan
Implement enum view |
563 |
desc.base.api = &pcilib_transform_view_api; |
315
by Suren A. Chilingaryan
Support properties of arbitrary type |
564 |
desc.base.type = PCILIB_TYPE_DOUBLE; |
321
by Suren A. Chilingaryan
Support computed (property-based) registers |
565 |
desc.base.mode = PCILIB_ACCESS_RW; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
566 |
|
567 |
err = pcilib_xml_parse_view(ctx, xpath, doc, node, (pcilib_view_description_t*)&desc); |
|
568 |
if (err) return err; |
|
569 |
||
570 |
for (cur = node->properties; cur != NULL; cur = cur->next) { |
|
571 |
if (!cur->children) continue; |
|
572 |
if (!xmlNodeIsText(cur->children)) continue; |
|
573 |
||
574 |
name = (char*)cur->name; |
|
575 |
value = (char*)cur->children->content; |
|
576 |
if (!value) continue; |
|
577 |
||
578 |
if (!strcasecmp(name, "read_from_register")) { |
|
316
by Suren A. Chilingaryan
Support XML properties |
579 |
if (desc.base.flags&PCILIB_VIEW_FLAG_PROPERTY) { |
580 |
if (strstr(value, "$value")) { |
|
581 |
pcilib_error("Invalid transform specified in XML property (%s). The properties can't reference $value (%s)", desc.base.name, value); |
|
582 |
return PCILIB_ERROR_INVALID_DATA; |
|
583 |
}
|
|
584 |
}
|
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
585 |
desc.read_from_reg = value; |
321
by Suren A. Chilingaryan
Support computed (property-based) registers |
586 |
if ((value)&&(*value)) mode |= PCILIB_ACCESS_R; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
587 |
} else if (!strcasecmp(name, "write_to_register")) { |
316
by Suren A. Chilingaryan
Support XML properties |
588 |
if (desc.base.flags&PCILIB_VIEW_FLAG_PROPERTY) { |
589 |
if (strstr(value, "$value")) { |
|
590 |
pcilib_error("Invalid transform specified in XML property (%s). The properties can't reference $value (%s)", desc.base.name, value); |
|
591 |
return PCILIB_ERROR_INVALID_DATA; |
|
592 |
}
|
|
593 |
}
|
|
594 |
desc.write_to_reg = value; |
|
321
by Suren A. Chilingaryan
Support computed (property-based) registers |
595 |
if ((value)&&(*value)) mode |= PCILIB_ACCESS_W; |
346.1.6
by Vasilii Chernov
Merge script and transform view. Add get register and properties info to python wrap. |
596 |
} else if (!strcasecmp(name, "script")) { |
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
597 |
desc.script = value; |
598 |
break; |
|
346.1.6
by Vasilii Chernov
Merge script and transform view. Add get register and properties info to python wrap. |
599 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
600 |
}
|
353
by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov |
601 |
desc.base.mode &= (~PCILIB_ACCESS_RW)|mode; |
321
by Suren A. Chilingaryan
Support computed (property-based) registers |
602 |
|
318
by Suren A. Chilingaryan
Support reading/writting register views by id |
603 |
err = pcilib_add_views_custom(ctx, 1, (pcilib_view_description_t*)&desc, &view_ctx); |
604 |
if (err) return err; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
605 |
|
318
by Suren A. Chilingaryan
Support reading/writting register views by id |
606 |
view_ctx->xml = node; |
607 |
return 0; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
608 |
}
|
609 |
||
319
by Suren A. Chilingaryan
Provide register listings in public API |
610 |
static int pcilib_xml_parse_value_name(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_register_value_name_t *desc) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
611 |
xmlAttr *cur; |
612 |
char *value, *name; |
|
613 |
char *endptr; |
|
614 |
||
615 |
int min_set = 0, max_set = 0; |
|
616 |
pcilib_register_value_t val; |
|
346.1.25
by Vasilii Chernov
Set value description content to NULL in pcilib_xml_parse_value_name |
617 |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
618 |
for (cur = node->properties; cur != NULL; cur = cur->next) { |
619 |
if(!cur->children) continue; |
|
620 |
if(!xmlNodeIsText(cur->children)) continue; |
|
621 |
||
622 |
name = (char*)cur->name; |
|
623 |
value = (char*)cur->children->content; |
|
624 |
||
625 |
if (!strcasecmp(name, "name")) { |
|
626 |
desc->name = value; |
|
320
by Suren A. Chilingaryan
Add optional description in the value name-aliases |
627 |
} else if (!strcasecmp(name, "description")) { |
628 |
desc->description = value; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
629 |
} else if (!strcasecmp(name, "value")) { |
630 |
val = strtol(value, &endptr, 0); |
|
631 |
if ((strlen(endptr) > 0)) { |
|
632 |
pcilib_error("Invalid enum value (%s) is specified in the XML enum node", value); |
|
633 |
return PCILIB_ERROR_INVALID_DATA; |
|
634 |
}
|
|
635 |
desc->value = val; |
|
636 |
} else if (!strcasecmp(name, "min")) { |
|
637 |
val = strtol(value, &endptr, 0); |
|
638 |
if ((strlen(endptr) > 0)) { |
|
639 |
pcilib_error("Invalid enum min-value (%s) is specified in the XML enum node", value); |
|
640 |
return PCILIB_ERROR_INVALID_DATA; |
|
641 |
}
|
|
642 |
desc->min = val; |
|
643 |
min_set = 1; |
|
644 |
} else if (!strcasecmp(name, "max")) { |
|
645 |
val = strtol(value, &endptr, 0); |
|
646 |
if ((strlen(endptr) > 0)) { |
|
647 |
pcilib_error("Invalid enum max-value (%s) is specified in the XML enum node", value); |
|
648 |
return PCILIB_ERROR_INVALID_DATA; |
|
649 |
}
|
|
650 |
desc->max = val; |
|
651 |
max_set = 1; |
|
652 |
}
|
|
653 |
}
|
|
654 |
||
655 |
if ((!min_set)&&(!max_set)) { |
|
656 |
desc->min = desc->value; |
|
657 |
desc->max = desc->value; |
|
658 |
} else if (max_set) { |
|
659 |
desc->min = 0; |
|
660 |
} else if (min_set) { |
|
661 |
desc->max = (pcilib_register_value_t)-1; |
|
662 |
}
|
|
663 |
||
664 |
if ((desc->min > desc->max)||(desc->value < desc->min)||(desc->value > desc->max)) { |
|
665 |
pcilib_error("Invalid enum configuration (min: %lu, max: %lu, value: %lu)", desc->min, desc->max, desc->value); |
|
666 |
return PCILIB_ERROR_INVALID_DATA; |
|
667 |
}
|
|
668 |
||
669 |
return 0; |
|
670 |
}
|
|
671 |
||
672 |
static int pcilib_xml_create_enum_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { |
|
673 |
int i; |
|
674 |
int err; |
|
675 |
||
676 |
xmlXPathObjectPtr nodes; |
|
677 |
xmlNodeSetPtr nodeset; |
|
678 |
||
318
by Suren A. Chilingaryan
Support reading/writting register views by id |
679 |
pcilib_view_context_t *view_ctx; |
324
by Suren A. Chilingaryan
Documentation update |
680 |
pcilib_enum_view_description_t desc = {{0}}; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
681 |
|
315
by Suren A. Chilingaryan
Support properties of arbitrary type |
682 |
desc.base.type = PCILIB_TYPE_STRING; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
683 |
desc.base.unit = pcilib_xml_enum_view_unit; |
684 |
desc.base.api = &pcilib_enum_view_xml_api; |
|
315
by Suren A. Chilingaryan
Support properties of arbitrary type |
685 |
desc.base.mode = PCILIB_ACCESS_RW; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
686 |
|
687 |
err = pcilib_xml_parse_view(ctx, xpath, doc, node, (pcilib_view_description_t*)&desc); |
|
688 |
if (err) return err; |
|
689 |
||
690 |
||
691 |
xpath->node = node; |
|
692 |
nodes = xmlXPathEvalExpression(ENUM_ELEMENTS_PATH, xpath); |
|
693 |
xpath->node = NULL; |
|
694 |
||
303
by Suren A. Chilingaryan
Initial integration of XML support |
695 |
if (!nodes) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
696 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
697 |
if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", ENUM_ELEMENTS_PATH, xmlerr->code, xmlerr->message); |
|
698 |
else pcilib_error("Failed to parse XPath expression %s", ENUM_ELEMENTS_PATH); |
|
699 |
return PCILIB_ERROR_FAILED; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
700 |
}
|
701 |
||
702 |
nodeset = nodes->nodesetval; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
703 |
if (xmlXPathNodeSetIsEmpty(nodeset)) { |
704 |
xmlXPathFreeObject(nodes); |
|
705 |
pcilib_error("No names is defined for enum view (%s)", desc.base.name); |
|
706 |
return PCILIB_ERROR_INVALID_DATA; |
|
707 |
}
|
|
708 |
||
319
by Suren A. Chilingaryan
Provide register listings in public API |
709 |
desc.names = (pcilib_register_value_name_t*)malloc((nodeset->nodeNr + 1) * sizeof(pcilib_register_value_name_t)); |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
710 |
if (!desc.names) { |
711 |
xmlXPathFreeObject(nodes); |
|
712 |
pcilib_error("No names is defined for enum view (%s)", desc.base.name); |
|
713 |
return PCILIB_ERROR_INVALID_DATA; |
|
714 |
}
|
|
357
by Suren A. Chilingaryan
Merge of further work on Python scripting from Vasiliy Chernov |
715 |
memset(desc.names, 0, (nodeset->nodeNr + 1) * sizeof(pcilib_register_value_name_t)); |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
716 |
|
717 |
for (i = 0; i < nodeset->nodeNr; i++) { |
|
718 |
err = pcilib_xml_parse_value_name(ctx, xpath, doc, nodeset->nodeTab[i], &desc.names[i]); |
|
719 |
if (err) { |
|
720 |
xmlXPathFreeObject(nodes); |
|
721 |
free(desc.names); |
|
722 |
return err; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
723 |
}
|
724 |
}
|
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
725 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
726 |
xmlXPathFreeObject(nodes); |
727 |
||
318
by Suren A. Chilingaryan
Support reading/writting register views by id |
728 |
err = pcilib_add_views_custom(ctx, 1, (pcilib_view_description_t*)&desc, &view_ctx); |
729 |
if (err) { |
|
730 |
free(desc.names); |
|
731 |
return err; |
|
732 |
}
|
|
733 |
view_ctx->xml = node; |
|
734 |
return 0; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
735 |
}
|
736 |
||
737 |
static int pcilib_xml_parse_unit_transform(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_unit_transform_t *desc) { |
|
738 |
xmlAttrPtr cur; |
|
739 |
char *value, *name; |
|
740 |
||
741 |
for (cur = node->properties; cur != NULL; cur = cur->next) { |
|
742 |
if (!cur->children) continue; |
|
743 |
if (!xmlNodeIsText(cur->children)) continue; |
|
744 |
||
745 |
name = (char*)cur->name; |
|
746 |
value = (char*)cur->children->content; |
|
747 |
||
748 |
if (!strcasecmp(name, "unit")) { |
|
749 |
desc->unit = value; |
|
750 |
} else if (!strcasecmp(name, "transform")) { |
|
751 |
desc->transform = value; |
|
752 |
}
|
|
753 |
}
|
|
754 |
||
303
by Suren A. Chilingaryan
Initial integration of XML support |
755 |
return 0; |
756 |
}
|
|
757 |
||
305.1.8
by nicolas.zilio at hotmail
views with units functionnal (beware, as formulas are completely crap now, we could get segfault, for example if we want to write a negative value in register) |
758 |
/**
|
759 |
* function to create a unit from a unit xml node, then populating ctx with it
|
|
760 |
*@param[in,out] ctx - the pcilib_t running
|
|
761 |
*@param[in] xpath - the xpath context of the unis xml file
|
|
762 |
*@param[in] doc - the AST of the unit xml file
|
|
763 |
*@param[in] node - the node representing the unit
|
|
764 |
*@return an error code: 0 if evrythinh is ok
|
|
765 |
*/
|
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
766 |
static int pcilib_xml_create_unit(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { |
305.1.7
by nicolas.zilio at hotmail
views working fine, units in progress |
767 |
int err; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
768 |
|
769 |
pcilib_unit_description_t desc = {0}; |
|
770 |
||
771 |
xmlXPathObjectPtr nodes; |
|
772 |
xmlNodeSetPtr nodeset; |
|
773 |
||
774 |
xmlAttrPtr cur; |
|
775 |
char *value, *name; |
|
776 |
||
777 |
for (cur = node->properties; cur != NULL; cur = cur->next) { |
|
778 |
if (!cur->children) continue; |
|
779 |
if (!xmlNodeIsText(cur->children)) continue; |
|
780 |
||
781 |
name = (char*)cur->name; |
|
305.1.7
by nicolas.zilio at hotmail
views working fine, units in progress |
782 |
value = (char*)cur->children->content; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
783 |
if (!strcasecmp(name, "name")) { |
784 |
desc.name = value; |
|
305.1.7
by nicolas.zilio at hotmail
views working fine, units in progress |
785 |
}
|
786 |
}
|
|
787 |
||
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
788 |
xpath->node = node; |
789 |
nodes = xmlXPathEvalExpression(UNIT_TRANSFORMS_PATH, xpath); |
|
790 |
xpath->node = NULL; |
|
791 |
||
792 |
if (!nodes) { |
|
793 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
|
794 |
if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", UNIT_TRANSFORMS_PATH, xmlerr->code, xmlerr->message); |
|
795 |
else pcilib_error("Failed to parse XPath expression %s", UNIT_TRANSFORMS_PATH); |
|
796 |
return PCILIB_ERROR_FAILED; |
|
305.1.7
by nicolas.zilio at hotmail
views working fine, units in progress |
797 |
}
|
798 |
||
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
799 |
nodeset = nodes->nodesetval; |
800 |
if (!xmlXPathNodeSetIsEmpty(nodeset)) { |
|
801 |
int i; |
|
802 |
||
803 |
if (nodeset->nodeNr > PCILIB_MAX_TRANSFORMS_PER_UNIT) { |
|
804 |
xmlXPathFreeObject(nodes); |
|
805 |
pcilib_error("Too many transforms for unit %s are defined, only %lu are supported", desc.name, PCILIB_MAX_TRANSFORMS_PER_UNIT); |
|
806 |
return PCILIB_ERROR_INVALID_DATA; |
|
807 |
}
|
|
305.1.4
by zilio nicolas
more towards views |
808 |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
809 |
for (i = 0; i < nodeset->nodeNr; i++) { |
810 |
err = pcilib_xml_parse_unit_transform(ctx, xpath, doc, nodeset->nodeTab[i], &desc.transforms[i]); |
|
811 |
if (err) { |
|
812 |
xmlXPathFreeObject(nodes); |
|
813 |
return err; |
|
305.1.4
by zilio nicolas
more towards views |
814 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
815 |
}
|
305.1.4
by zilio nicolas
more towards views |
816 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
817 |
xmlXPathFreeObject(nodes); |
818 |
||
819 |
return pcilib_add_units(ctx, 1, &desc); |
|
305.1.4
by zilio nicolas
more towards views |
820 |
}
|
821 |
||
822 |
||
277.2.7
by zilio nicolas
put xml nodes pointers for banks and registers in pcilib_t, compil ok |
823 |
/** pcilib_xml_initialize_banks
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
824 |
*
|
825 |
* function to create the structures to store the banks from the AST
|
|
826 |
* @see pcilib_xml_create_bank
|
|
277.2.7
by zilio nicolas
put xml nodes pointers for banks and registers in pcilib_t, compil ok |
827 |
* @param[in] doc the AST of the xml file.
|
277.2.12
by zilio nicolas
almost finished regarding suren remarks |
828 |
* @param[in] pci the pcilib_t running, which will be filled
|
277.2.7
by zilio nicolas
put xml nodes pointers for banks and registers in pcilib_t, compil ok |
829 |
*/
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
830 |
static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathContextPtr xpath) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
831 |
int err; |
346.1.3
by Vasilii Chernov
Add support for setting register value to script transfrom. Add set_property and get_property functions to pcipywrap. Cleaning cmakelists from unused dependencies |
832 |
xmlXPathObjectPtr bank_nodes = NULL, transform_nodes = NULL, enum_nodes = NULL, unit_nodes = NULL; |
303
by Suren A. Chilingaryan
Initial integration of XML support |
833 |
xmlNodeSetPtr nodeset; |
305.1.4
by zilio nicolas
more towards views |
834 |
int i; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
835 |
|
836 |
bank_nodes = xmlXPathEvalExpression(BANKS_PATH, xpath); |
|
837 |
if (bank_nodes) transform_nodes = xmlXPathEvalExpression(TRANSFORM_VIEWS_PATH, xpath); |
|
346.1.3
by Vasilii Chernov
Add support for setting register value to script transfrom. Add set_property and get_property functions to pcipywrap. Cleaning cmakelists from unused dependencies |
838 |
if (transform_nodes) enum_nodes = xmlXPathEvalExpression(ENUM_VIEWS_PATH, xpath); |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
839 |
if (enum_nodes) unit_nodes = xmlXPathEvalExpression(UNITS_PATH, xpath); |
840 |
||
841 |
if (!unit_nodes) { |
|
842 |
const unsigned char *expr = (enum_nodes?UNITS_PATH:(transform_nodes?ENUM_VIEWS_PATH:(bank_nodes?TRANSFORM_VIEWS_PATH:BANKS_PATH))); |
|
843 |
||
844 |
if (enum_nodes) xmlXPathFreeObject(enum_nodes); |
|
845 |
if (transform_nodes) xmlXPathFreeObject(transform_nodes); |
|
846 |
if (bank_nodes) xmlXPathFreeObject(bank_nodes); |
|
847 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
|
848 |
if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", expr, xmlerr->code, xmlerr->message); |
|
849 |
else pcilib_error("Failed to parse XPath expression %s", expr); |
|
850 |
return PCILIB_ERROR_FAILED; |
|
851 |
}
|
|
852 |
||
853 |
nodeset = unit_nodes->nodesetval; |
|
854 |
if(!xmlXPathNodeSetIsEmpty(nodeset)) { |
|
855 |
for(i=0; i < nodeset->nodeNr; i++) { |
|
856 |
err = pcilib_xml_create_unit(ctx, xpath, doc, nodeset->nodeTab[i]); |
|
857 |
if (err) pcilib_error("Error (%i) creating unit", err); |
|
858 |
}
|
|
859 |
}
|
|
860 |
||
861 |
nodeset = transform_nodes->nodesetval; |
|
862 |
if (!xmlXPathNodeSetIsEmpty(nodeset)) { |
|
863 |
for(i=0; i < nodeset->nodeNr; i++) { |
|
346.1.10
by Vasilii Chernov
1. Cmakelists - move copy xml folder command to root file |
864 |
err = pcilib_xml_create_transform_view(ctx, xpath, doc, nodeset->nodeTab[i]); |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
865 |
if (err) pcilib_error("Error (%i) creating register transform", err); |
866 |
}
|
|
867 |
}
|
|
868 |
||
869 |
nodeset = enum_nodes->nodesetval; |
|
870 |
if (!xmlXPathNodeSetIsEmpty(nodeset)) { |
|
871 |
for(i=0; i < nodeset->nodeNr; i++) { |
|
872 |
err = pcilib_xml_create_enum_view(ctx, xpath, doc, nodeset->nodeTab[i]); |
|
873 |
if (err) pcilib_error("Error (%i) creating register enum", err); |
|
874 |
}
|
|
875 |
}
|
|
305.1.6
by nicolas.zilio at hotmail
more towards views |
876 |
|
877 |
nodeset = bank_nodes->nodesetval; |
|
878 |
if (!xmlXPathNodeSetIsEmpty(nodeset)) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
879 |
for (i = 0; i < nodeset->nodeNr; i++) { |
880 |
err = pcilib_xml_create_bank(ctx, xpath, doc, nodeset->nodeTab[i]); |
|
881 |
if (err) pcilib_error("Error (%i) creating bank", err); |
|
882 |
}
|
|
305.1.6
by nicolas.zilio at hotmail
more towards views |
883 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
884 |
|
885 |
||
886 |
xmlXPathFreeObject(unit_nodes); |
|
887 |
xmlXPathFreeObject(enum_nodes); |
|
888 |
xmlXPathFreeObject(transform_nodes); |
|
305.1.6
by nicolas.zilio at hotmail
more towards views |
889 |
xmlXPathFreeObject(bank_nodes); |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
890 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
891 |
return 0; |
892 |
}
|
|
893 |
||
379
by Suren A. Chilingaryan
Support XML configuration of device models |
894 |
static int pcilib_xml_load_xsd_file(pcilib_t *ctx, const char *xsd_filename, xmlSchemaPtr *schema, xmlSchemaValidCtxtPtr *validator) { |
303
by Suren A. Chilingaryan
Initial integration of XML support |
895 |
int err; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
896 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
897 |
xmlSchemaParserCtxtPtr ctxt; |
898 |
||
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
899 |
*schema = NULL; |
900 |
*validator = NULL; |
|
901 |
||
303
by Suren A. Chilingaryan
Initial integration of XML support |
902 |
/** we first parse the xsd file for AST with validation*/
|
903 |
ctxt = xmlSchemaNewParserCtxt(xsd_filename); |
|
904 |
if (!ctxt) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
905 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
906 |
if (xmlerr) pcilib_error("xmlSchemaNewParserCtxt reported error %d - %s", xmlerr->code, xmlerr->message); |
|
907 |
else pcilib_error("Failed to create a parser for XML schemas"); |
|
908 |
return PCILIB_ERROR_FAILED; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
909 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
910 |
|
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
911 |
*schema = xmlSchemaParse(ctxt); |
912 |
if (!*schema) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
913 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
914 |
xmlSchemaFreeParserCtxt(ctxt); |
|
915 |
if (xmlerr) pcilib_error("Failed to parse XML schema, xmlSchemaParse reported error %d - %s", xmlerr->code, xmlerr->message); |
|
916 |
else pcilib_error("Failed to parse XML schema"); |
|
917 |
return PCILIB_ERROR_INVALID_DATA; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
918 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
919 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
920 |
xmlSchemaFreeParserCtxt(ctxt); |
921 |
||
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
922 |
*validator = xmlSchemaNewValidCtxt(*schema); |
923 |
if (!*validator) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
924 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
379
by Suren A. Chilingaryan
Support XML configuration of device models |
925 |
xmlSchemaFree(*schema); *schema = NULL; |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
926 |
if (xmlerr) pcilib_error("xmlSchemaNewValidCtxt reported error %d - %s", xmlerr->code, xmlerr->message); |
927 |
else pcilib_error("Failed to create a validation context"); |
|
928 |
return PCILIB_ERROR_FAILED; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
929 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
930 |
|
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
931 |
err = xmlSchemaSetValidOptions(*validator, XML_SCHEMA_VAL_VC_I_CREATE); |
303
by Suren A. Chilingaryan
Initial integration of XML support |
932 |
if (err) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
933 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
379
by Suren A. Chilingaryan
Support XML configuration of device models |
934 |
xmlSchemaFreeValidCtxt(*validator); *validator = NULL; |
935 |
xmlSchemaFree(*schema); *schema = NULL; |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
936 |
if (xmlerr) pcilib_error("xmlSchemaSetValidOptions reported error %d - %s", xmlerr->code, xmlerr->message); |
937 |
else pcilib_error("Failed to configure the validation context to populate default attributes"); |
|
938 |
return PCILIB_ERROR_FAILED; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
939 |
}
|
940 |
||
941 |
return 0; |
|
942 |
}
|
|
943 |
||
379
by Suren A. Chilingaryan
Support XML configuration of device models |
944 |
/*
|
945 |
static xmlDocPtr pcilib_xml_load_xml_file(pcilib_t *ctx, const char *xsd_filename, const char *xml_filename) {
|
|
946 |
int err;
|
|
947 |
xmlDocPtr doc;
|
|
948 |
xmlSchemaPtr schema;
|
|
949 |
xmlSchemaValidCtxtPtr validator;
|
|
950 |
xmlParserCtxtPtr parser;
|
|
951 |
||
952 |
err = pcilib_xml_load_xsd_file(ctx, xsd_filename, &schema, &validator);
|
|
953 |
if (err) {
|
|
954 |
pcilib_error("Error (%i) parsing the devices schema (%s)", err, xsd_filename);
|
|
955 |
return NULL;
|
|
956 |
}
|
|
957 |
||
958 |
parser = xmlNewParserCtxt();
|
|
959 |
if (!parser) {
|
|
960 |
xmlErrorPtr xmlerr = xmlGetLastError();
|
|
961 |
xmlSchemaFree(schema);
|
|
962 |
xmlSchemaFreeValidCtxt(validator);
|
|
963 |
if (xmlerr) pcilib_error("xmlNewParserCtxt reported error %d (%s)", xmlerr->code, xmlerr->message);
|
|
964 |
else pcilib_error("Failed to create an XML parser context");
|
|
965 |
return NULL;
|
|
966 |
}
|
|
967 |
||
968 |
doc = xmlCtxtReadFile(parser, xml_filename, NULL, 0);
|
|
969 |
if (!doc) {
|
|
970 |
xmlErrorPtr xmlerr = xmlGetLastError();
|
|
971 |
xmlFreeParserCtxt(parser);
|
|
972 |
xmlSchemaFree(schema);
|
|
973 |
xmlSchemaFreeValidCtxt(validator);
|
|
974 |
if (xmlerr) pcilib_error("Error parsing %s, xmlCtxtReadFile reported error %d - %s", xml_filename, xmlerr->code, xmlerr->message);
|
|
975 |
else pcilib_error("Error parsing %s", xml_filename);
|
|
976 |
return NULL;
|
|
977 |
}
|
|
978 |
|
|
979 |
err = xmlSchemaValidateDoc(validator, doc);
|
|
980 |
if (err) {
|
|
981 |
xmlErrorPtr xmlerr = xmlCtxtGetLastError(parser);
|
|
982 |
xmlFreeDoc(doc);
|
|
983 |
xmlFreeParserCtxt(parser);
|
|
984 |
xmlSchemaFree(schema);
|
|
985 |
xmlSchemaFreeValidCtxt(validator);
|
|
986 |
if (xmlerr) pcilib_error("Error validating %s, xmlSchemaValidateDoc reported error %d - %s", xml_filename, xmlerr->code, xmlerr->message);
|
|
987 |
else pcilib_error("Error validating %s", xml_filename);
|
|
988 |
return NULL;
|
|
989 |
}
|
|
990 |
||
991 |
xmlFreeParserCtxt(parser);
|
|
992 |
xmlSchemaFree(schema);
|
|
993 |
xmlSchemaFreeValidCtxt(validator);
|
|
994 |
||
995 |
return doc;
|
|
996 |
}
|
|
997 |
*/
|
|
998 |
||
999 |
static xmlXPathObjectPtr pcilib_xml_eval_xpath_expression(pcilib_t *ctx, xmlDocPtr doc, const xmlChar *query) { |
|
1000 |
xmlXPathContextPtr xpath; |
|
1001 |
xmlXPathObjectPtr nodes; |
|
1002 |
||
1003 |
xpath = xmlXPathNewContext(doc); |
|
1004 |
if (!xpath) { |
|
1005 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
|
1006 |
if (xmlerr) pcilib_error("xmlXpathNewContext reported error %d - %s", xmlerr->code, xmlerr->message); |
|
1007 |
else pcilib_error("Error creating XPath context"); |
|
1008 |
return NULL; |
|
1009 |
}
|
|
1010 |
||
1011 |
nodes = xmlXPathEvalExpression(query, xpath); |
|
1012 |
if (!nodes) { |
|
1013 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
|
1014 |
xmlXPathFreeContext(xpath); |
|
1015 |
if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", query, xmlerr->code, xmlerr->message); |
|
1016 |
else pcilib_error("Failed to parse XPath expression %s", query); |
|
1017 |
return NULL; |
|
1018 |
}
|
|
1019 |
||
1020 |
xmlXPathFreeContext(xpath); |
|
1021 |
return nodes; |
|
1022 |
}
|
|
1023 |
||
1024 |
static int pcilib_xml_load_xsd(pcilib_t *ctx, const char *model_dir) { |
|
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1025 |
int err; |
1026 |
||
1027 |
struct stat st; |
|
1028 |
char *xsd_path; |
|
1029 |
||
1030 |
xsd_path = (char*)alloca(strlen(model_dir) + 32); |
|
1031 |
if (!xsd_path) return PCILIB_ERROR_MEMORY; |
|
1032 |
||
1033 |
sprintf(xsd_path, "%s/model.xsd", model_dir); |
|
1034 |
if (stat(xsd_path, &st)) { |
|
1035 |
pcilib_info("XML models are not present, missing parts schema"); |
|
1036 |
return PCILIB_ERROR_NOTFOUND; |
|
1037 |
}
|
|
1038 |
||
1039 |
err = pcilib_xml_load_xsd_file(ctx, xsd_path, &ctx->xml.parts_schema, &ctx->xml.parts_validator); |
|
1040 |
if (err) return err; |
|
1041 |
||
1042 |
sprintf(xsd_path, "%s/references.xsd", model_dir); |
|
1043 |
if (stat(xsd_path, &st)) { |
|
1044 |
pcilib_info("XML models are not present, missing schema"); |
|
1045 |
return PCILIB_ERROR_NOTFOUND; |
|
1046 |
}
|
|
1047 |
||
1048 |
return pcilib_xml_load_xsd_file(ctx, xsd_path, &ctx->xml.schema, &ctx->xml.validator); |
|
1049 |
}
|
|
1050 |
||
1051 |
||
1052 |
||
379
by Suren A. Chilingaryan
Support XML configuration of device models |
1053 |
static xmlDocPtr pcilib_xml_load_file(pcilib_t *ctx, xmlParserCtxtPtr parser, xmlSchemaValidCtxtPtr validator, const char *path, const char *name) { |
303
by Suren A. Chilingaryan
Initial integration of XML support |
1054 |
int err; |
1055 |
char *full_name; |
|
1056 |
xmlDocPtr doc; |
|
1057 |
||
1058 |
full_name = (char*)alloca(strlen(path) + strlen(name) + 2); |
|
1059 |
if (!name) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1060 |
pcilib_error("Error allocating %zu bytes of memory in stack to create a file name", strlen(path) + strlen(name) + 2); |
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1061 |
return NULL; |
303
by Suren A. Chilingaryan
Initial integration of XML support |
1062 |
}
|
1063 |
||
1064 |
sprintf(full_name, "%s/%s", path, name); |
|
1065 |
||
379
by Suren A. Chilingaryan
Support XML configuration of device models |
1066 |
doc = xmlCtxtReadFile(parser, full_name, NULL, 0); |
303
by Suren A. Chilingaryan
Initial integration of XML support |
1067 |
if (!doc) { |
379
by Suren A. Chilingaryan
Support XML configuration of device models |
1068 |
xmlErrorPtr xmlerr = xmlCtxtGetLastError(parser); |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1069 |
if (xmlerr) pcilib_error("Error parsing %s, xmlCtxtReadFile reported error %d - %s", full_name, xmlerr->code, xmlerr->message); |
1070 |
else pcilib_error("Error parsing %s", full_name); |
|
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1071 |
return NULL; |
303
by Suren A. Chilingaryan
Initial integration of XML support |
1072 |
}
|
1073 |
||
379
by Suren A. Chilingaryan
Support XML configuration of device models |
1074 |
err = xmlSchemaValidateDoc(validator, doc); |
303
by Suren A. Chilingaryan
Initial integration of XML support |
1075 |
if (err) { |
379
by Suren A. Chilingaryan
Support XML configuration of device models |
1076 |
xmlErrorPtr xmlerr = xmlCtxtGetLastError(parser); |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1077 |
xmlFreeDoc(doc); |
1078 |
if (xmlerr) pcilib_error("Error validating %s, xmlSchemaValidateDoc reported error %d - %s", full_name, xmlerr->code, xmlerr->message); |
|
1079 |
else pcilib_error("Error validating %s", full_name); |
|
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1080 |
return NULL; |
1081 |
}
|
|
1082 |
||
1083 |
return doc; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1084 |
}
|
1085 |
||
379
by Suren A. Chilingaryan
Support XML configuration of device models |
1086 |
static xmlDocPtr pcilib_xml_load_model_file(pcilib_t *ctx, const char *path, const char *name) { |
1087 |
return pcilib_xml_load_file(ctx, ctx->xml.parser, ctx->xml.parts_validator, path, name); |
|
1088 |
}
|
|
1089 |
||
1090 |
||
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1091 |
static int pcilib_process_xml_internal(pcilib_t *ctx, const char *model, const char *location) { |
303
by Suren A. Chilingaryan
Initial integration of XML support |
1092 |
int err; |
1093 |
||
1094 |
DIR *rep; |
|
1095 |
struct dirent *file = NULL; |
|
1096 |
char *model_dir, *model_path; |
|
1097 |
||
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1098 |
xmlDocPtr doc = NULL; |
1099 |
xmlNodePtr root = NULL; |
|
1100 |
xmlXPathContextPtr xpath; |
|
1101 |
||
1102 |
if (ctx->xml.num_files == PCILIB_MAX_MODEL_FILES) { |
|
1103 |
pcilib_error("Too many XML locations for a model, only up to %zu are supported", PCILIB_MAX_MODEL_FILES); |
|
1104 |
return PCILIB_ERROR_TOOBIG; |
|
1105 |
}
|
|
1106 |
||
303
by Suren A. Chilingaryan
Initial integration of XML support |
1107 |
model_dir = getenv("PCILIB_MODEL_DIR"); |
1108 |
if (!model_dir) model_dir = PCILIB_MODEL_DIR; |
|
1109 |
||
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1110 |
if (!model) model = ctx->model; |
1111 |
if (!location) location = ""; |
|
1112 |
||
1113 |
model_path = (char*)alloca(strlen(model_dir) + strlen(model) + strlen(location) + 3); |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1114 |
if (!model_path) return PCILIB_ERROR_MEMORY; |
1115 |
||
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1116 |
sprintf(model_path, "%s/%s/%s", model_dir, model, location); |
303
by Suren A. Chilingaryan
Initial integration of XML support |
1117 |
|
1118 |
rep = opendir(model_path); |
|
1119 |
if (!rep) return PCILIB_ERROR_NOTFOUND; |
|
1120 |
||
1121 |
while ((file = readdir(rep)) != NULL) { |
|
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1122 |
xmlDocPtr newdoc; |
1123 |
||
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1124 |
size_t len = strlen(file->d_name); |
1125 |
if ((len < 4)||(strcasecmp(file->d_name + len - 4, ".xml"))) continue; |
|
1126 |
if (file->d_type != DT_REG) continue; |
|
1127 |
||
379
by Suren A. Chilingaryan
Support XML configuration of device models |
1128 |
newdoc = pcilib_xml_load_model_file(ctx, model_path, file->d_name); |
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1129 |
if (!newdoc) { |
1130 |
pcilib_error("Error processing XML file %s", file->d_name); |
|
1131 |
continue; |
|
1132 |
}
|
|
1133 |
||
1134 |
if (doc) { |
|
1135 |
xmlNodePtr node; |
|
1136 |
||
1137 |
node = xmlDocGetRootElement(newdoc); |
|
1138 |
if (node) node = xmlFirstElementChild(node); |
|
1139 |
if (node) node = xmlDocCopyNodeList(doc, node); |
|
1140 |
xmlFreeDoc(newdoc); |
|
1141 |
||
1142 |
if ((!node)||(!xmlAddChildList(root, node))) { |
|
1143 |
xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser); |
|
1144 |
if (node) xmlFreeNode(node); |
|
1145 |
if (xmlerr) pcilib_error("Error manipulating XML tree of %s, libXML2 reported error %d - %s", file->d_name, xmlerr->code, xmlerr->message); |
|
1146 |
else pcilib_error("Error manipulating XML tree of %s", file->d_name); |
|
1147 |
continue; |
|
1148 |
}
|
|
1149 |
} else { |
|
1150 |
root = xmlDocGetRootElement(newdoc); |
|
1151 |
if (!root) { |
|
1152 |
xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser); |
|
1153 |
xmlFreeDoc(newdoc); |
|
1154 |
if (xmlerr) pcilib_error("Error manipulating XML tree of %s, libXML2 reported error %d - %s", file->d_name, xmlerr->code, xmlerr->message); |
|
1155 |
else pcilib_error("Error manipulating XML tree of %s", file->d_name); |
|
1156 |
continue; |
|
1157 |
}
|
|
1158 |
doc = newdoc; |
|
1159 |
// This is undocumented, but should be fine...
|
|
1160 |
if (doc->URL) xmlFree((xmlChar*)doc->URL); |
|
1161 |
doc->URL = xmlStrdup(BAD_CAST model_path); |
|
1162 |
}
|
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1163 |
}
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1164 |
closedir(rep); |
1165 |
||
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1166 |
if (!doc) |
1167 |
return 0; |
|
1168 |
||
1169 |
err = xmlSchemaValidateDoc(ctx->xml.validator, doc); |
|
1170 |
if (err) { |
|
1171 |
xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser); |
|
1172 |
xmlFreeDoc(doc); |
|
1173 |
if (xmlerr) pcilib_error("Error validating %s, xmlSchemaValidateDoc reported error %d - %s", model_path, xmlerr->code, xmlerr->message); |
|
1174 |
else pcilib_error("Error validating %s", model_path); |
|
1175 |
return PCILIB_ERROR_VERIFY; |
|
1176 |
}
|
|
1177 |
||
1178 |
xpath = xmlXPathNewContext(doc); |
|
1179 |
if (!xpath) { |
|
1180 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
|
1181 |
xmlFreeDoc(doc); |
|
1182 |
if (xmlerr) pcilib_error("Document %s: xmlXpathNewContext reported error %d - %s for document %s", model_path, xmlerr->code, xmlerr->message); |
|
1183 |
else pcilib_error("Error creating XPath context for %s", model_path); |
|
1184 |
return PCILIB_ERROR_FAILED; |
|
1185 |
}
|
|
1186 |
||
1187 |
// This can only partially fail... Therefore we need to keep XML and just return the error...
|
|
1188 |
err = pcilib_xml_process_document(ctx, doc, xpath); |
|
1189 |
||
1190 |
ctx->xml.docs[ctx->xml.num_files] = doc; |
|
1191 |
ctx->xml.xpath[ctx->xml.num_files] = xpath; |
|
1192 |
ctx->xml.num_files++; |
|
1193 |
||
1194 |
return err; |
|
1195 |
}
|
|
1196 |
||
1197 |
int pcilib_process_xml(pcilib_t *ctx, const char *location) { |
|
1198 |
return pcilib_process_xml_internal(ctx, NULL, location); |
|
1199 |
}
|
|
1200 |
||
303
by Suren A. Chilingaryan
Initial integration of XML support |
1201 |
int pcilib_init_xml(pcilib_t *ctx, const char *model) { |
1202 |
int err; |
|
1203 |
||
1204 |
char *model_dir; |
|
1205 |
||
1206 |
model_dir = getenv("PCILIB_MODEL_DIR"); |
|
1207 |
if (!model_dir) model_dir = PCILIB_MODEL_DIR; |
|
1208 |
||
1209 |
ctx->xml.parser = xmlNewParserCtxt(); |
|
1210 |
if (!ctx->xml.parser) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1211 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
1212 |
if (xmlerr) pcilib_error("xmlNewParserCtxt reported error %d (%s)", xmlerr->code, xmlerr->message); |
|
1213 |
else pcilib_error("Failed to create an XML parser context"); |
|
1214 |
return PCILIB_ERROR_FAILED; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1215 |
}
|
1216 |
||
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1217 |
err = pcilib_xml_load_xsd(ctx, model_dir); |
303
by Suren A. Chilingaryan
Initial integration of XML support |
1218 |
if (err) return err; |
1219 |
||
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1220 |
return pcilib_process_xml_internal(ctx, model, NULL); |
303
by Suren A. Chilingaryan
Initial integration of XML support |
1221 |
}
|
1222 |
||
1223 |
void pcilib_free_xml(pcilib_t *ctx) { |
|
1224 |
int i; |
|
1225 |
||
1226 |
memset(ctx->xml.bank_nodes, 0, sizeof(ctx->xml.bank_nodes)); |
|
1227 |
for (i = 0; i < ctx->num_banks; i++) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1228 |
if (ctx->bank_ctx[i]) |
1229 |
ctx->bank_ctx[i]->xml = NULL; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1230 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1231 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1232 |
for (i = 0; i < ctx->num_reg; i++) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1233 |
ctx->register_ctx[i].xml = NULL; |
303
by Suren A. Chilingaryan
Initial integration of XML support |
1234 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1235 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1236 |
for (i = 0; i < ctx->xml.num_files; i++) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1237 |
if (ctx->xml.docs[i]) { |
1238 |
xmlFreeDoc(ctx->xml.docs[i]); |
|
1239 |
ctx->xml.docs[i] = NULL; |
|
1240 |
}
|
|
1241 |
if (ctx->xml.xpath[i]) { |
|
1242 |
xmlXPathFreeContext(ctx->xml.xpath[i]); |
|
1243 |
ctx->xml.xpath[i] = NULL; |
|
1244 |
}
|
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1245 |
}
|
1246 |
ctx->xml.num_files = 0; |
|
1247 |
||
1248 |
if (ctx->xml.validator) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1249 |
xmlSchemaFreeValidCtxt(ctx->xml.validator); |
1250 |
ctx->xml.validator = NULL; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1251 |
}
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1252 |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1253 |
if (ctx->xml.schema) { |
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1254 |
xmlSchemaFree(ctx->xml.schema); |
1255 |
ctx->xml.schema = NULL; |
|
322
by Suren A. Chilingaryan
Support multiple XML files per folder |
1256 |
}
|
1257 |
||
1258 |
if (ctx->xml.parts_validator) { |
|
1259 |
xmlSchemaFreeValidCtxt(ctx->xml.parts_validator); |
|
1260 |
ctx->xml.parts_validator = NULL; |
|
1261 |
}
|
|
1262 |
||
1263 |
if (ctx->xml.parts_schema) { |
|
1264 |
xmlSchemaFree(ctx->xml.parts_schema); |
|
1265 |
ctx->xml.parts_schema = NULL; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1266 |
}
|
1267 |
||
1268 |
if (ctx->xml.parser) { |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1269 |
xmlFreeParserCtxt(ctx->xml.parser); |
1270 |
ctx->xml.parser = NULL; |
|
303
by Suren A. Chilingaryan
Initial integration of XML support |
1271 |
}
|
311
by Suren A. Chilingaryan
Implement enum view |
1272 |
|
307
by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far) |
1273 |
/*
|
1274 |
xmlSchemaCleanupTypes();
|
|
1275 |
xmlCleanupParser();
|
|
1276 |
xmlMemoryDump();
|
|
1277 |
*/
|
|
277.2.16
by zilio nicolas
end of modifications |
1278 |
}
|
379
by Suren A. Chilingaryan
Support XML configuration of device models |
1279 |
|
1280 |
||
1281 |
char *pcilib_detect_xml_model(pcilib_t *ctx, unsigned int vendor_id, unsigned int device_id) { |
|
1282 |
int err; |
|
1283 |
char *model = NULL; |
|
1284 |
xmlSchemaPtr schema; /**< Pointer to the parsed xsd schema */ |
|
1285 |
xmlSchemaValidCtxtPtr validator; /**< Pointer to the XML validation context */ |
|
1286 |
xmlParserCtxtPtr parser; /**< Pointer to the XML parser context */ |
|
1287 |
||
1288 |
DIR *rep; |
|
1289 |
struct dirent *file = NULL; |
|
1290 |
struct stat st; |
|
1291 |
const char *data_dir; |
|
1292 |
char *xsd_path, *xml_path; |
|
1293 |
||
1294 |
xmlXPathObjectPtr nodes; |
|
1295 |
xmlChar xpath_query[64]; |
|
1296 |
||
384
by Suren A. Chilingaryan
Fix device detection code |
1297 |
xmlStrPrintf(xpath_query, sizeof(xpath_query), (xmlChar*)"/devices/device[@vendor=\"%04x\" and @device=\"%04x\"]/@model", vendor_id, device_id); |
379
by Suren A. Chilingaryan
Support XML configuration of device models |
1298 |
|
1299 |
data_dir = getenv("PCILIB_DATA_DIR"); |
|
1300 |
if (!data_dir) data_dir = PCILIB_DATA_DIR; |
|
1301 |
||
1302 |
xsd_path = (char*)alloca(strlen(data_dir) + 32); |
|
1303 |
xml_path = (char*)alloca(strlen(data_dir) + 32); |
|
1304 |
if ((!xsd_path)||(!xml_path)) { |
|
1305 |
pcilib_error("Error allocating stack memory"); |
|
1306 |
return NULL; |
|
1307 |
}
|
|
1308 |
||
1309 |
sprintf(xsd_path, "%s/devices.xsd", data_dir); |
|
1310 |
sprintf(xml_path, "%s/devices", data_dir); |
|
1311 |
if (stat(xsd_path, &st)||stat(xml_path, &st)) { |
|
1312 |
pcilib_info("No XML devices are defined, missing devices schema or list"); |
|
1313 |
return NULL; |
|
1314 |
}
|
|
1315 |
||
1316 |
parser = xmlNewParserCtxt(); |
|
1317 |
if (!parser) { |
|
1318 |
xmlErrorPtr xmlerr = xmlGetLastError(); |
|
1319 |
if (xmlerr) pcilib_error("xmlNewParserCtxt reported error %d (%s)", xmlerr->code, xmlerr->message); |
|
1320 |
else pcilib_error("Failed to create an XML parser context"); |
|
1321 |
return NULL; |
|
1322 |
}
|
|
1323 |
||
1324 |
err = pcilib_xml_load_xsd_file(ctx, xsd_path, &schema, &validator); |
|
1325 |
if (err) { |
|
1326 |
xmlFreeParserCtxt(parser); |
|
1327 |
pcilib_error("Error (%i) parsing the device schema (%s)", err, xsd_path); |
|
1328 |
return NULL; |
|
1329 |
}
|
|
1330 |
||
1331 |
rep = opendir(xml_path); |
|
1332 |
if (!rep) goto cleanup; |
|
1333 |
||
1334 |
while ((model == NULL)&&((file = readdir(rep)) != NULL)) { |
|
1335 |
xmlDocPtr doc; |
|
1336 |
||
1337 |
size_t len = strlen(file->d_name); |
|
1338 |
if ((len < 4)||(strcasecmp(file->d_name + len - 4, ".xml"))) continue; |
|
1339 |
if (file->d_type != DT_REG) continue; |
|
1340 |
||
1341 |
doc = pcilib_xml_load_file(ctx, parser, validator, xml_path, file->d_name); |
|
1342 |
if (!doc) continue; |
|
1343 |
||
1344 |
nodes = pcilib_xml_eval_xpath_expression(ctx, doc, xpath_query); |
|
1345 |
if (!nodes) { |
|
1346 |
xmlFreeDoc(doc); |
|
1347 |
continue; |
|
1348 |
}
|
|
1349 |
||
1350 |
if (!xmlXPathNodeSetIsEmpty(nodes->nodesetval)) { |
|
1351 |
xmlNodePtr node = nodes->nodesetval->nodeTab[0]; |
|
1352 |
model = strdup((char*)node->children->content); |
|
1353 |
}
|
|
1354 |
||
1355 |
xmlXPathFreeObject(nodes); |
|
1356 |
xmlFreeDoc(doc); |
|
1357 |
}
|
|
1358 |
closedir(rep); |
|
1359 |
||
1360 |
cleanup: |
|
1361 |
xmlSchemaFree(schema); |
|
1362 |
xmlSchemaFreeValidCtxt(validator); |
|
1363 |
xmlFreeParserCtxt(parser); |
|
1364 |
||
1365 |
return model; |
|
1366 |
}
|