summaryrefslogtreecommitdiffstats
path: root/pcilib/xml.c
diff options
context:
space:
mode:
Diffstat (limited to 'pcilib/xml.c')
-rw-r--r--pcilib/xml.c885
1 files changed, 637 insertions, 248 deletions
diff --git a/pcilib/xml.c b/pcilib/xml.c
index 73a3deb..c431b73 100644
--- a/pcilib/xml.c
+++ b/pcilib/xml.c
@@ -39,14 +39,25 @@
#include "register.h"
#include "xml.h"
#include "error.h"
+#include "view.h"
+#include "views/enum.h"
+#include "views/transform.h"
-#define BANKS_PATH ((xmlChar*)"/model/banks/bank/bank_description") /**< path to complete nodes of banks.*/
-//#define REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register") /**< all standard registers nodes.*/
-//#define BIT_REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits") /**< all bits registers nodes.*/
-#define REGISTERS_PATH ((xmlChar*)"../registers/register") /**< all standard registers nodes.*/
-#define BIT_REGISTERS_PATH ((xmlChar*)"./registers_bits/register_bits") /**< all bits registers nodes.*/
-static char *pcilib_xml_bank_default_format = "0x%lx";
+#define BANKS_PATH ((xmlChar*)"/model/bank") /**< path to complete nodes of banks */
+#define REGISTERS_PATH ((xmlChar*)"./register") /**< all standard registers nodes */
+#define BIT_REGISTERS_PATH ((xmlChar*)"./field") /**< all bits registers nodes */
+#define REGISTER_VIEWS_PATH ((xmlChar*)"./view") /**< supported register & field views */
+#define TRANSFORM_VIEWS_PATH ((xmlChar*)"/model/transform") /**< path to complete nodes of views */
+#define ENUM_VIEWS_PATH ((xmlChar*)"/model/enum") /**< path to complete nodes of views */
+#define ENUM_ELEMENTS_PATH ((xmlChar*)"./name") /**< all elements in the enum */
+#define UNITS_PATH ((xmlChar*)"/model/unit") /**< path to complete nodes of units */
+#define UNIT_TRANSFORMS_PATH ((xmlChar*)"./transform") /**< all transforms of the unit */
+
+
+
+static const char *pcilib_xml_bank_default_format = "0x%lx";
+static const char *pcilib_xml_enum_view_unit = "name";
typedef struct {
pcilib_register_description_t base;
@@ -59,7 +70,7 @@ static xmlNodePtr pcilib_xml_get_parent_bank_node(xmlDocPtr doc, xmlNodePtr node
bank_node = node->parent->parent;
// bank_description is always a first node according to the XSD schema
return xmlFirstElementChild(bank_node);
-
+
}
static xmlNodePtr pcilib_xml_get_parent_register_node(xmlDocPtr doc, xmlNodePtr node) {
@@ -67,76 +78,105 @@ static xmlNodePtr pcilib_xml_get_parent_register_node(xmlDocPtr doc, xmlNodePtr
}
*/
-static int pcilib_xml_parse_register(pcilib_t *ctx, pcilib_xml_register_description_t *xml_desc, xmlDocPtr doc, xmlNodePtr node, pcilib_register_bank_description_t *bdesc) {
+static int pcilib_xml_parse_view_reference(pcilib_t *ctx, xmlDocPtr doc, xmlNodePtr node, pcilib_view_reference_t *desc) {
+ xmlAttr *cur;
+ char *value, *name;
+
+ for (cur = node->properties; cur != NULL; cur = cur->next) {
+ if(!cur->children) continue;
+ if(!xmlNodeIsText(cur->children)) continue;
+
+ name = (char*)cur->name;
+ value = (char*)cur->children->content;
+
+ if (!strcasecmp(name, "name")) {
+ desc->name = value;
+ } else if (!strcasecmp(name, "view")) {
+ desc->view = value;
+ }
+ }
+
+ if (!desc->name)
+ desc->name = desc->view;
+
+ return 0;
+}
+
+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) {
+ int err;
pcilib_register_description_t *desc = (pcilib_register_description_t*)xml_desc;
- xmlNodePtr cur;
+ xmlXPathObjectPtr nodes;
+ xmlNodeSetPtr nodeset;
+
+ xmlAttrPtr cur;
char *value, *name;
char *endptr;
- for (cur = node->children; cur != NULL; cur = cur->next) {
- if (!cur->children) continue;
- if (!xmlNodeIsText(cur->children)) continue;
-
- name = (char*)cur->name;
+
+ for (cur = node->properties; cur != NULL; cur = cur->next) {
+ if (!cur->children) continue;
+ if (!xmlNodeIsText(cur->children)) continue;
+
+ name = (char*)cur->name;
value = (char*)cur->children->content;
if (!value) continue;
-
+
if (!strcasecmp((char*)name, "address")) {
- uintptr_t addr = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)) {
- pcilib_error("Invalid address (%s) is specified in the XML register description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
+ uintptr_t addr = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)) {
+ pcilib_error("Invalid address (%s) is specified in the XML register description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
desc->addr = addr;
} else if(!strcasecmp(name, "offset")) {
- int offset = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)||(offset < 0)||(offset > (8 * sizeof(pcilib_register_value_t)))) {
- pcilib_error("Invalid offset (%s) is specified in the XML register description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
+ int offset = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)||(offset < 0)||(offset > (8 * sizeof(pcilib_register_value_t)))) {
+ pcilib_error("Invalid offset (%s) is specified in the XML register description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
desc->offset = (pcilib_register_size_t)offset;
} else if (!strcasecmp(name,"size")) {
- int size = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)||(size <= 0)||(size > (8 * sizeof(pcilib_register_value_t)))) {
- pcilib_error("Invalid size (%s) is specified in the XML register description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
+ int size = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)||(size <= 0)||(size > (8 * sizeof(pcilib_register_value_t)))) {
+ pcilib_error("Invalid size (%s) is specified in the XML register description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
desc->bits = (pcilib_register_size_t)size;
} else if (!strcasecmp(name, "default")) {
- pcilib_register_value_t val = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)) {
- pcilib_error("Invalid default value (%s) is specified in the XML register description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
+ pcilib_register_value_t val = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)) {
+ pcilib_error("Invalid default value (%s) is specified in the XML register description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
desc->defvalue = val;
} else if (!strcasecmp(name,"min")) {
- pcilib_register_value_t min = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)) {
- pcilib_error("Invalid minimum value (%s) is specified in the XML register description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
- xml_desc->min = min;
+ pcilib_register_value_t min = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)) {
+ pcilib_error("Invalid minimum value (%s) is specified in the XML register description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+ xml_desc->min = min;
} else if (!strcasecmp(name, "max")) {
- pcilib_register_value_t max = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)) {
- pcilib_error("Invalid minimum value (%s) is specified in the XML register description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
- xml_desc->max = max;
+ pcilib_register_value_t max = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)) {
+ pcilib_error("Invalid minimum value (%s) is specified in the XML register description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+ xml_desc->max = max;
} else if (!strcasecmp((char*)name,"rwmask")) {
if (!strcasecmp(value, "all")) {
desc->rwmask = PCILIB_REGISTER_ALL_BITS;
} else if (!strcasecmp(value, "none")) {
desc->rwmask = 0;
} else {
- uintptr_t mask = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)) {
- pcilib_error("Invalid mask (%s) is specified in the XML register description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
- desc->rwmask = mask;
- }
+ uintptr_t mask = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)) {
+ pcilib_error("Invalid mask (%s) is specified in the XML register description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+ desc->rwmask = mask;
+ }
} else if (!strcasecmp(name, "mode")) {
if (!strcasecmp(value, "R")) {
desc->mode = PCILIB_REGISTER_R;
@@ -151,15 +191,15 @@ static int pcilib_xml_parse_register(pcilib_t *ctx, pcilib_xml_register_descript
} else if (!strcasecmp(value, "W1C")) {
desc->mode = PCILIB_REGISTER_W1C;
} else {
- pcilib_error("Invalid access mode (%s) is specified in the XML register description", value);
- return PCILIB_ERROR_INVALID_DATA;
+ pcilib_error("Invalid access mode (%s) is specified in the XML register description", value);
+ return PCILIB_ERROR_INVALID_DATA;
}
} else if (!strcasecmp(name, "type")) {
if (!strcasecmp(value, "fifo")) {
desc->type = PCILIB_REGISTER_FIFO;
} else {
- pcilib_error("Invalid register type (%s) is specified in the XML register description", value);
- return PCILIB_ERROR_INVALID_DATA;
+ pcilib_error("Invalid register type (%s) is specified in the XML register description", value);
+ return PCILIB_ERROR_INVALID_DATA;
}
} else if (!strcasecmp(name,"name")) {
desc->name = value;
@@ -168,82 +208,121 @@ static int pcilib_xml_parse_register(pcilib_t *ctx, pcilib_xml_register_descript
}
}
+ xpath->node = node;
+ nodes = xmlXPathEvalExpression(REGISTER_VIEWS_PATH, xpath);
+ xpath->node = NULL;
+
+ if (!nodes) {
+ xmlErrorPtr xmlerr = xmlGetLastError();
+
+ if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", REGISTER_VIEWS_PATH, xmlerr->code, xmlerr->message);
+ else pcilib_error("Failed to parse XPath expression %s", REGISTER_VIEWS_PATH);
+ return PCILIB_ERROR_FAILED;
+ }
+
+
+ nodeset = nodes->nodesetval;
+ if (!xmlXPathNodeSetIsEmpty(nodeset)) {
+ int i;
+
+ desc->views = (pcilib_view_reference_t*)malloc((nodeset->nodeNr + 1) * sizeof(pcilib_view_reference_t));
+ if (!desc->views) {
+ xmlXPathFreeObject(nodes);
+ pcilib_error("Failed to allocate %zu bytes of memory to store supported register views", (nodeset->nodeNr + 1) * sizeof(char*));
+ return PCILIB_ERROR_MEMORY;
+ }
+
+ memset(desc->views, 0, (nodeset->nodeNr + 1) * sizeof(pcilib_view_reference_t));
+ for (i = 0; i < nodeset->nodeNr; i++) {
+ err = pcilib_xml_parse_view_reference(ctx, doc, nodeset->nodeTab[i], &desc->views[i]);
+ if (err) {
+ xmlXPathFreeObject(nodes);
+ return err;
+ }
+ }
+ }
+ xmlXPathFreeObject(nodes);
+
return 0;
}
static int pcilib_xml_create_register(pcilib_t *ctx, pcilib_register_bank_t bank, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {
int err;
-
xmlXPathObjectPtr nodes;
xmlNodeSetPtr nodeset;
pcilib_xml_register_description_t desc = {{0}};
pcilib_xml_register_description_t fdesc;
-
+
pcilib_register_t reg;
-
+
desc.base.bank = ctx->banks[bank].addr;
desc.base.rwmask = PCILIB_REGISTER_ALL_BITS;
desc.base.mode = PCILIB_REGISTER_R;
desc.base.type = PCILIB_REGISTER_STANDARD;
-
- err = pcilib_xml_parse_register(ctx, &desc, doc, node, &ctx->banks[bank]);
+
+ err = pcilib_xml_parse_register(ctx, &desc, xpath, doc, node, &ctx->banks[bank]);
if (err) {
- pcilib_error("Error (%i) parsing an XML register", err);
- return err;
+ pcilib_error("Error (%i) parsing an XML register", err);
+ return err;
}
-
+
err = pcilib_add_registers(ctx, PCILIB_MODEL_MODIFICATION_FLAG_OVERRIDE, 1, &desc.base, &reg);
if (err) {
- pcilib_error("Error (%i) adding a new XML register (%s) to the model", err, desc.base.name);
- return err;
+ if (desc.base.views) free(desc.base.views);
+ pcilib_error("Error (%i) adding a new XML register (%s) to the model", err, desc.base.name);
+ return err;
}
- ctx->register_ctx[reg].xml = node;
+ ctx->register_ctx[reg].xml = node;
ctx->register_ctx[reg].min = desc.min;
ctx->register_ctx[reg].max = desc.max;
+ ctx->register_ctx[reg].views = desc.base.views;
+
xpath->node = node;
nodes = xmlXPathEvalExpression(BIT_REGISTERS_PATH, xpath);
xpath->node = NULL;
-
+
if (!nodes) {
- xmlErrorPtr xmlerr = xmlGetLastError();
+ xmlErrorPtr xmlerr = xmlGetLastError();
- if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", BIT_REGISTERS_PATH, xmlerr->code, xmlerr->message);
- else pcilib_error("Failed to parse XPath expression %s", BIT_REGISTERS_PATH);
- return PCILIB_ERROR_FAILED;
+ if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", BIT_REGISTERS_PATH, xmlerr->code, xmlerr->message);
+ else pcilib_error("Failed to parse XPath expression %s", BIT_REGISTERS_PATH);
+ return PCILIB_ERROR_FAILED;
}
nodeset = nodes->nodesetval;
if (!xmlXPathNodeSetIsEmpty(nodeset)) {
- int i;
-
- for (i = 0; i < nodeset->nodeNr; i++) {
- memset(&fdesc, 0, sizeof(pcilib_xml_register_description_t));
-
- fdesc.base.bank = desc.base.bank;
- fdesc.base.addr = desc.base.addr;
- fdesc.base.mode = desc.base.mode;
- fdesc.base.rwmask = desc.base.rwmask;
- fdesc.base.type = PCILIB_REGISTER_BITS;
-
- err = pcilib_xml_parse_register(ctx, &fdesc, doc, nodeset->nodeTab[i], &ctx->banks[bank]);
- if (err) {
- pcilib_error("Error parsing field in the XML register %s", desc.base.name);
- continue;
- }
-
- err = pcilib_add_registers(ctx, PCILIB_MODEL_MODIFICATION_FLAG_OVERRIDE, 1, &fdesc.base, &reg);
- if (err) {
- pcilib_error("Error (%i) adding a new XML register (%s) to the model", err, fdesc.base.name);
- continue;
- }
-
- ctx->register_ctx[reg].xml = nodeset->nodeTab[i];
- ctx->register_ctx[reg].min = fdesc.min;
- ctx->register_ctx[reg].max = fdesc.max;
- }
+ int i;
+
+ for (i = 0; i < nodeset->nodeNr; i++) {
+ memset(&fdesc, 0, sizeof(pcilib_xml_register_description_t));
+
+ fdesc.base.bank = desc.base.bank;
+ fdesc.base.addr = desc.base.addr;
+ fdesc.base.mode = desc.base.mode;
+ fdesc.base.rwmask = desc.base.rwmask;
+ fdesc.base.type = PCILIB_REGISTER_BITS;
+
+ err = pcilib_xml_parse_register(ctx, &fdesc, xpath, doc, nodeset->nodeTab[i], &ctx->banks[bank]);
+ if (err) {
+ pcilib_error("Error parsing field in the XML register %s", desc.base.name);
+ continue;
+ }
+
+ err = pcilib_add_registers(ctx, PCILIB_MODEL_MODIFICATION_FLAG_OVERRIDE, 1, &fdesc.base, &reg);
+ if (err) {
+ if (fdesc.base.views) free(fdesc.base.views);
+ pcilib_error("Error (%i) adding a new XML register (%s) to the model", err, fdesc.base.name);
+ continue;
+ }
+
+ ctx->register_ctx[reg].xml = nodeset->nodeTab[i];
+ ctx->register_ctx[reg].min = fdesc.min;
+ ctx->register_ctx[reg].max = fdesc.max;
+ ctx->register_ctx[reg].views = fdesc.base.views;
+ }
}
xmlXPathFreeObject(nodes);
@@ -252,11 +331,11 @@ static int pcilib_xml_create_register(pcilib_t *ctx, pcilib_register_bank_t bank
static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {
int err;
-
+
int override = 0;
pcilib_register_bank_description_t desc = {0};
pcilib_register_bank_t bank;
- xmlNodePtr cur;
+ xmlAttrPtr cur;
char *value, *name;
char *endptr;
@@ -273,70 +352,70 @@ static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
desc.endianess = PCILIB_HOST_ENDIAN;
desc.raw_endianess = PCILIB_HOST_ENDIAN;
- // iterate through all children, representing bank properties, to fill the structure
- for (cur = node->children; cur != NULL; cur = cur->next) {
- if (!cur->children) continue;
- if (!xmlNodeIsText(cur->children)) continue;
-
- name = (char*)cur->name;
+ // iterate through all children, representing bank properties, to fill the structure
+ for (cur = node->properties; cur != NULL; cur = cur->next) {
+ if (!cur->children) continue;
+ if (!xmlNodeIsText(cur->children)) continue;
+
+ name = (char*)cur->name;
value = (char*)cur->children->content;
if (!value) continue;
-
+
if (!strcasecmp(name, "bar")) {
- char bar = value[0]-'0';
- if ((strlen(value) != 1)||(bar < 0)||(bar > 5)) {
- pcilib_error("Invalid BAR (%s) is specified in the XML bank description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
+ char bar = value[0]-'0';
+ if ((strlen(value) != 1)||(bar < 0)||(bar > 5)) {
+ pcilib_error("Invalid BAR (%s) is specified in the XML bank description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
desc.bar = (pcilib_bar_t)bar;
override = 1;
} else if (!strcasecmp(name,"size")) {
- long size = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)||(size<=0)) {
- pcilib_error("Invalid bank size (%s) is specified in the XML bank description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
+ long size = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)||(size<=0)) {
+ pcilib_error("Invalid bank size (%s) is specified in the XML bank description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
desc.size = (size_t)size;
override = 1;
} else if (!strcasecmp(name,"protocol")) {
- pcilib_register_protocol_t protocol = pcilib_find_register_protocol_by_name(ctx, value);
- if (protocol == PCILIB_REGISTER_PROTOCOL_INVALID) {
- pcilib_error("Unsupported protocol (%s) is specified in the XML bank description", value);
- return PCILIB_ERROR_NOTSUPPORTED;
- }
- desc.protocol = ctx->protocols[protocol].addr;
+ pcilib_register_protocol_t protocol = pcilib_find_register_protocol_by_name(ctx, value);
+ if (protocol == PCILIB_REGISTER_PROTOCOL_INVALID) {
+ pcilib_error("Unsupported protocol (%s) is specified in the XML bank description", value);
+ return PCILIB_ERROR_NOTSUPPORTED;
+ }
+ desc.protocol = ctx->protocols[protocol].addr;
override = 1;
} else if (!strcasecmp(name,"address")) {
- uintptr_t addr = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)) {
- pcilib_error("Invalid address (%s) is specified in the XML bank description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
+ uintptr_t addr = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)) {
+ pcilib_error("Invalid address (%s) is specified in the XML bank description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
desc.read_addr = addr;
desc.write_addr = addr;
override = 1;
} else if (!strcasecmp(name,"read_address")) {
- uintptr_t addr = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)) {
- pcilib_error("Invalid address (%s) is specified in the XML bank description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
+ uintptr_t addr = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)) {
+ pcilib_error("Invalid address (%s) is specified in the XML bank description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
desc.read_addr = addr;
override = 1;
} else if (!strcasecmp(name,"write_address")) {
- uintptr_t addr = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)) {
- pcilib_error("Invalid address (%s) is specified in the XML bank description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
+ uintptr_t addr = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)) {
+ pcilib_error("Invalid address (%s) is specified in the XML bank description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
desc.write_addr = addr;
override = 1;
} else if(strcasecmp((char*)name,"word_size")==0) {
- int access = strtol(value, &endptr, 0);
- if ((strlen(endptr) > 0)||(access%8)||(access<=0)||(access>(8 * sizeof(pcilib_register_value_t)))) {
- pcilib_error("Invalid word size (%s) is specified in the XML bank description", value);
- return PCILIB_ERROR_INVALID_DATA;
- }
+ int access = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)||(access%8)||(access<=0)||(access>(8 * sizeof(pcilib_register_value_t)))) {
+ pcilib_error("Invalid word size (%s) is specified in the XML bank description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
desc.access = access;
override = 1;
} else if (!strcasecmp(name,"endianess")) {
@@ -344,8 +423,8 @@ static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
else if (!strcasecmp(value,"big")) desc.endianess = PCILIB_BIG_ENDIAN;
else if (!strcasecmp(value,"host")) desc.endianess = PCILIB_HOST_ENDIAN;
else {
- pcilib_error("Invalid endianess (%s) is specified in the XML bank description", value);
- return PCILIB_ERROR_INVALID_DATA;
+ pcilib_error("Invalid endianess (%s) is specified in the XML bank description", value);
+ return PCILIB_ERROR_INVALID_DATA;
}
override = 1;
} else if (!strcasecmp(name,"format")) {
@@ -357,7 +436,7 @@ static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
desc.description = value;
override = 1;
} else if (!strcasecmp((char*)name,"override")) {
- override = 1;
+ override = 1;
}
}
@@ -369,31 +448,302 @@ static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
ctx->xml.bank_nodes[bank] = node;
if (ctx->bank_ctx[bank]) {
- ctx->bank_ctx[bank]->xml = node;
+ ctx->bank_ctx[bank]->xml = node;
}
xpath->node = node;
nodes = xmlXPathEvalExpression(REGISTERS_PATH, xpath);
xpath->node = NULL;
+
+ if (!nodes) {
+ xmlErrorPtr xmlerr = xmlGetLastError();
+ if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", REGISTERS_PATH, xmlerr->code, xmlerr->message);
+ else pcilib_error("Failed to parse XPath expression %s", REGISTERS_PATH);
+ return PCILIB_ERROR_FAILED;
+ }
+
+ nodeset = nodes->nodesetval;
+ if (!xmlXPathNodeSetIsEmpty(nodeset)) {
+ int i;
+ for (i = 0; i < nodeset->nodeNr; i++) {
+ err = pcilib_xml_create_register(ctx, bank, xpath, doc, nodeset->nodeTab[i]);
+ if (err) pcilib_error("Error creating XML registers for bank %s", desc.name);
+ }
+ }
+ xmlXPathFreeObject(nodes);
+
+ return 0;
+}
+
+static int pcilib_xml_parse_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_view_description_t *desc) {
+ xmlAttrPtr cur;
+ const char *value, *name;
+
+ desc->type = PCILIB_TYPE_STRING;
+
+ for (cur = node->properties; cur != NULL; cur = cur->next) {
+ if (!cur->children) continue;
+ if (!xmlNodeIsText(cur->children)) continue;
+
+ name = (char*)cur->name;
+ value = (char*)cur->children->content;
+ if (!value) continue;
+
+ if (!strcasecmp(name, "name")) {
+ desc->name = value;
+ } else if (!strcasecmp((char*)name, "description")) {
+ desc->description = value;
+ } else if (!strcasecmp((char*)name, "unit")) {
+ desc->unit = value;
+ } else if (!strcasecmp((char*)name, "type")) {
+ if (!strcasecmp(value, "string")) desc->type = PCILIB_TYPE_STRING;
+ else if (!strcasecmp(value, "float")) desc->type = PCILIB_TYPE_DOUBLE;
+ else if (!strcasecmp(value, "int")) desc->type = PCILIB_TYPE_LONG;
+ else {
+ pcilib_error("Invalid type (%s) of register view is specified in the XML bank description", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {
+ int err;
+ xmlAttrPtr cur;
+ const char *value, *name;
+
+ pcilib_transform_view_description_t desc = {0};
+
+ desc.base.api = &pcilib_enum_view_xml_api;
+
+ err = pcilib_xml_parse_view(ctx, xpath, doc, node, (pcilib_view_description_t*)&desc);
+ if (err) return err;
+
+ for (cur = node->properties; cur != NULL; cur = cur->next) {
+ if (!cur->children) continue;
+ if (!xmlNodeIsText(cur->children)) continue;
+
+ name = (char*)cur->name;
+ value = (char*)cur->children->content;
+ if (!value) continue;
+
+ if (!strcasecmp(name, "read_from_register")) {
+ desc.read_from_reg = value;
+ } else if (!strcasecmp(name, "write_to_register")) {
+ desc.write_to_reg = value;
+ }
+ }
+
+
+ return pcilib_add_views(ctx, 1, (pcilib_view_description_t*)&desc);
+}
+
+
+static int pcilib_xml_parse_value_name(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_value_name_t *desc) {
+ xmlAttr *cur;
+ char *value, *name;
+ char *endptr;
+
+ int min_set = 0, max_set = 0;
+ pcilib_register_value_t val;
+ for (cur = node->properties; cur != NULL; cur = cur->next) {
+ if(!cur->children) continue;
+ if(!xmlNodeIsText(cur->children)) continue;
+
+ name = (char*)cur->name;
+ value = (char*)cur->children->content;
+
+ if (!strcasecmp(name, "name")) {
+ desc->name = value;
+ } else if (!strcasecmp(name, "value")) {
+ val = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)) {
+ pcilib_error("Invalid enum value (%s) is specified in the XML enum node", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+ desc->value = val;
+ } else if (!strcasecmp(name, "min")) {
+ val = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)) {
+ pcilib_error("Invalid enum min-value (%s) is specified in the XML enum node", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+ desc->min = val;
+ min_set = 1;
+ } else if (!strcasecmp(name, "max")) {
+ val = strtol(value, &endptr, 0);
+ if ((strlen(endptr) > 0)) {
+ pcilib_error("Invalid enum max-value (%s) is specified in the XML enum node", value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+ desc->max = val;
+ max_set = 1;
+ }
+ }
+
+ if ((!min_set)&&(!max_set)) {
+ desc->min = desc->value;
+ desc->max = desc->value;
+ } else if (max_set) {
+ desc->min = 0;
+ } else if (min_set) {
+ desc->max = (pcilib_register_value_t)-1;
+ }
+
+ if ((desc->min > desc->max)||(desc->value < desc->min)||(desc->value > desc->max)) {
+ pcilib_error("Invalid enum configuration (min: %lu, max: %lu, value: %lu)", desc->min, desc->max, desc->value);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+
+ return 0;
+}
+
+static int pcilib_xml_create_enum_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {
+ int i;
+ int err;
+
+ xmlXPathObjectPtr nodes;
+ xmlNodeSetPtr nodeset;
+
+ pcilib_enum_view_description_t desc = {0};
+
+ desc.base.unit = pcilib_xml_enum_view_unit;
+ desc.base.api = &pcilib_enum_view_xml_api;
+
+ err = pcilib_xml_parse_view(ctx, xpath, doc, node, (pcilib_view_description_t*)&desc);
+ if (err) return err;
+
+
+ xpath->node = node;
+ nodes = xmlXPathEvalExpression(ENUM_ELEMENTS_PATH, xpath);
+ xpath->node = NULL;
+
+ if (!nodes) {
+ xmlErrorPtr xmlerr = xmlGetLastError();
+ if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", ENUM_ELEMENTS_PATH, xmlerr->code, xmlerr->message);
+ else pcilib_error("Failed to parse XPath expression %s", ENUM_ELEMENTS_PATH);
+ return PCILIB_ERROR_FAILED;
+ }
+
+ nodeset = nodes->nodesetval;
+ if (xmlXPathNodeSetIsEmpty(nodeset)) {
+ xmlXPathFreeObject(nodes);
+ pcilib_error("No names is defined for enum view (%s)", desc.base.name);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+
+ desc.names = (pcilib_value_name_t*)malloc((nodeset->nodeNr + 1) * sizeof(pcilib_value_name_t));
+ if (!desc.names) {
+ xmlXPathFreeObject(nodes);
+ pcilib_error("No names is defined for enum view (%s)", desc.base.name);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+
+
+ for (i = 0; i < nodeset->nodeNr; i++) {
+ err = pcilib_xml_parse_value_name(ctx, xpath, doc, nodeset->nodeTab[i], &desc.names[i]);
+ if (err) {
+ xmlXPathFreeObject(nodes);
+ free(desc.names);
+ return err;
+ }
+ }
+ memset(&desc.names[nodeset->nodeNr], 0, sizeof(pcilib_value_name_t));
+
+ xmlXPathFreeObject(nodes);
+
+
+ err = pcilib_add_views(ctx, 1, (pcilib_view_description_t*)&desc);
+ if (err) free(desc.names);
+ return err;
+}
+
+static int pcilib_xml_parse_unit_transform(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_unit_transform_t *desc) {
+ xmlAttrPtr cur;
+ char *value, *name;
+
+ for (cur = node->properties; cur != NULL; cur = cur->next) {
+ if (!cur->children) continue;
+ if (!xmlNodeIsText(cur->children)) continue;
+
+ name = (char*)cur->name;
+ value = (char*)cur->children->content;
+
+ if (!strcasecmp(name, "unit")) {
+ desc->unit = value;
+ } else if (!strcasecmp(name, "transform")) {
+ desc->transform = value;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * function to create a unit from a unit xml node, then populating ctx with it
+ *@param[in,out] ctx - the pcilib_t running
+ *@param[in] xpath - the xpath context of the unis xml file
+ *@param[in] doc - the AST of the unit xml file
+ *@param[in] node - the node representing the unit
+ *@return an error code: 0 if evrythinh is ok
+ */
+static int pcilib_xml_create_unit(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {
+ int err;
+
+ pcilib_unit_description_t desc = {0};
+
+ xmlXPathObjectPtr nodes;
+ xmlNodeSetPtr nodeset;
+
+ xmlAttrPtr cur;
+ char *value, *name;
+
+ for (cur = node->properties; cur != NULL; cur = cur->next) {
+ if (!cur->children) continue;
+ if (!xmlNodeIsText(cur->children)) continue;
+
+ name = (char*)cur->name;
+ value = (char*)cur->children->content;
+ if (!strcasecmp(name, "name")) {
+ desc.name = value;
+ }
+ }
+
+ xpath->node = node;
+ nodes = xmlXPathEvalExpression(UNIT_TRANSFORMS_PATH, xpath);
+ xpath->node = NULL;
+
if (!nodes) {
- xmlErrorPtr xmlerr = xmlGetLastError();
- if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", REGISTERS_PATH, xmlerr->code, xmlerr->message);
- else pcilib_error("Failed to parse XPath expression %s", REGISTERS_PATH);
- return PCILIB_ERROR_FAILED;
+ xmlErrorPtr xmlerr = xmlGetLastError();
+ if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", UNIT_TRANSFORMS_PATH, xmlerr->code, xmlerr->message);
+ else pcilib_error("Failed to parse XPath expression %s", UNIT_TRANSFORMS_PATH);
+ return PCILIB_ERROR_FAILED;
}
nodeset = nodes->nodesetval;
if (!xmlXPathNodeSetIsEmpty(nodeset)) {
int i;
+
+ if (nodeset->nodeNr > PCILIB_MAX_TRANSFORMS_PER_UNIT) {
+ xmlXPathFreeObject(nodes);
+ pcilib_error("Too many transforms for unit %s are defined, only %lu are supported", desc.name, PCILIB_MAX_TRANSFORMS_PER_UNIT);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+
for (i = 0; i < nodeset->nodeNr; i++) {
- err = pcilib_xml_create_register(ctx, bank, xpath, doc, nodeset->nodeTab[i]);
- if (err) pcilib_error("Error creating XML registers for bank %s", desc.name);
+ err = pcilib_xml_parse_unit_transform(ctx, xpath, doc, nodeset->nodeTab[i], &desc.transforms[i]);
+ if (err) {
+ xmlXPathFreeObject(nodes);
+ return err;
+ }
}
}
xmlXPathFreeObject(nodes);
- return 0;
+ return pcilib_add_units(ctx, 1, &desc);
}
@@ -405,69 +755,108 @@ static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
* @param[in] pci the pcilib_t running, which will be filled
*/
static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathContextPtr xpath) {
- xmlXPathObjectPtr bank_nodes;
+ int err;
+ xmlXPathObjectPtr bank_nodes = NULL, transform_nodes = NULL, enum_nodes = NULL, unit_nodes = NULL;
xmlNodeSetPtr nodeset;
+ int i;
- bank_nodes = xmlXPathEvalExpression(BANKS_PATH, xpath);
- if (!bank_nodes) {
- xmlErrorPtr xmlerr = xmlGetLastError();
- if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", BANKS_PATH, xmlerr->code, xmlerr->message);
- else pcilib_error("Failed to parse XPath expression %s", BANKS_PATH);
- return PCILIB_ERROR_FAILED;
+ bank_nodes = xmlXPathEvalExpression(BANKS_PATH, xpath);
+ if (bank_nodes) transform_nodes = xmlXPathEvalExpression(TRANSFORM_VIEWS_PATH, xpath);
+ if (transform_nodes) enum_nodes = xmlXPathEvalExpression(ENUM_VIEWS_PATH, xpath);
+ if (enum_nodes) unit_nodes = xmlXPathEvalExpression(UNITS_PATH, xpath);
+
+ if (!unit_nodes) {
+ const unsigned char *expr = (enum_nodes?UNITS_PATH:(transform_nodes?ENUM_VIEWS_PATH:(bank_nodes?TRANSFORM_VIEWS_PATH:BANKS_PATH)));
+
+ if (enum_nodes) xmlXPathFreeObject(enum_nodes);
+ if (transform_nodes) xmlXPathFreeObject(transform_nodes);
+ if (bank_nodes) xmlXPathFreeObject(bank_nodes);
+ xmlErrorPtr xmlerr = xmlGetLastError();
+ if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", expr, xmlerr->code, xmlerr->message);
+ else pcilib_error("Failed to parse XPath expression %s", expr);
+ return PCILIB_ERROR_FAILED;
}
+ nodeset = unit_nodes->nodesetval;
+ if(!xmlXPathNodeSetIsEmpty(nodeset)) {
+ for(i=0; i < nodeset->nodeNr; i++) {
+ err = pcilib_xml_create_unit(ctx, xpath, doc, nodeset->nodeTab[i]);
+ if (err) pcilib_error("Error (%i) creating unit", err);
+ }
+ }
+
+ nodeset = transform_nodes->nodesetval;
+ if (!xmlXPathNodeSetIsEmpty(nodeset)) {
+ for(i=0; i < nodeset->nodeNr; i++) {
+ err = pcilib_xml_create_transform_view(ctx, xpath, doc, nodeset->nodeTab[i]);
+ if (err) pcilib_error("Error (%i) creating register transform", err);
+ }
+ }
+
+ nodeset = enum_nodes->nodesetval;
+ if (!xmlXPathNodeSetIsEmpty(nodeset)) {
+ for(i=0; i < nodeset->nodeNr; i++) {
+ err = pcilib_xml_create_enum_view(ctx, xpath, doc, nodeset->nodeTab[i]);
+ if (err) pcilib_error("Error (%i) creating register enum", err);
+ }
+ }
nodeset = bank_nodes->nodesetval;
if (!xmlXPathNodeSetIsEmpty(nodeset)) {
- int i;
- for (i = 0; i < nodeset->nodeNr; i++) {
- pcilib_xml_create_bank(ctx, xpath, doc, nodeset->nodeTab[i]);
- }
+ for (i = 0; i < nodeset->nodeNr; i++) {
+ err = pcilib_xml_create_bank(ctx, xpath, doc, nodeset->nodeTab[i]);
+ if (err) pcilib_error("Error (%i) creating bank", err);
+ }
}
+
+
+ xmlXPathFreeObject(unit_nodes);
+ xmlXPathFreeObject(enum_nodes);
+ xmlXPathFreeObject(transform_nodes);
xmlXPathFreeObject(bank_nodes);
-
+
return 0;
}
static int pcilib_xml_load_xsd(pcilib_t *ctx, char *xsd_filename) {
int err;
-
+
xmlSchemaParserCtxtPtr ctxt;
/** we first parse the xsd file for AST with validation*/
ctxt = xmlSchemaNewParserCtxt(xsd_filename);
if (!ctxt) {
- xmlErrorPtr xmlerr = xmlGetLastError();
- if (xmlerr) pcilib_error("xmlSchemaNewParserCtxt reported error %d - %s", xmlerr->code, xmlerr->message);
- else pcilib_error("Failed to create a parser for XML schemas");
- return PCILIB_ERROR_FAILED;
+ xmlErrorPtr xmlerr = xmlGetLastError();
+ if (xmlerr) pcilib_error("xmlSchemaNewParserCtxt reported error %d - %s", xmlerr->code, xmlerr->message);
+ else pcilib_error("Failed to create a parser for XML schemas");
+ return PCILIB_ERROR_FAILED;
}
-
+
ctx->xml.schema = xmlSchemaParse(ctxt);
if (!ctx->xml.schema) {
- xmlErrorPtr xmlerr = xmlGetLastError();
- xmlSchemaFreeParserCtxt(ctxt);
- if (xmlerr) pcilib_error("Failed to parse XML schema, xmlSchemaParse reported error %d - %s", xmlerr->code, xmlerr->message);
- else pcilib_error("Failed to parse XML schema");
- return PCILIB_ERROR_INVALID_DATA;
+ xmlErrorPtr xmlerr = xmlGetLastError();
+ xmlSchemaFreeParserCtxt(ctxt);
+ if (xmlerr) pcilib_error("Failed to parse XML schema, xmlSchemaParse reported error %d - %s", xmlerr->code, xmlerr->message);
+ else pcilib_error("Failed to parse XML schema");
+ return PCILIB_ERROR_INVALID_DATA;
}
-
+
xmlSchemaFreeParserCtxt(ctxt);
ctx->xml.validator = xmlSchemaNewValidCtxt(ctx->xml.schema);
if (!ctx->xml.validator) {
- xmlErrorPtr xmlerr = xmlGetLastError();
- if (xmlerr) pcilib_error("xmlSchemaNewValidCtxt reported error %d - %s", xmlerr->code, xmlerr->message);
- else pcilib_error("Failed to create a validation context");
- return PCILIB_ERROR_FAILED;
+ xmlErrorPtr xmlerr = xmlGetLastError();
+ if (xmlerr) pcilib_error("xmlSchemaNewValidCtxt reported error %d - %s", xmlerr->code, xmlerr->message);
+ else pcilib_error("Failed to create a validation context");
+ return PCILIB_ERROR_FAILED;
}
-
+
err = xmlSchemaSetValidOptions(ctx->xml.validator, XML_SCHEMA_VAL_VC_I_CREATE);
if (err) {
- xmlErrorPtr xmlerr = xmlGetLastError();
- if (xmlerr) pcilib_error("xmlSchemaSetValidOptions reported error %d - %s", xmlerr->code, xmlerr->message);
- else pcilib_error("Failed to configure the validation context to populate default attributes");
- return PCILIB_ERROR_FAILED;
+ xmlErrorPtr xmlerr = xmlGetLastError();
+ if (xmlerr) pcilib_error("xmlSchemaSetValidOptions reported error %d - %s", xmlerr->code, xmlerr->message);
+ else pcilib_error("Failed to configure the validation context to populate default attributes");
+ return PCILIB_ERROR_FAILED;
}
return 0;
@@ -481,46 +870,46 @@ static int pcilib_xml_load_file(pcilib_t *ctx, const char *path, const char *nam
full_name = (char*)alloca(strlen(path) + strlen(name) + 2);
if (!name) {
- pcilib_error("Error allocating %zu bytes of memory in stack to create a file name", strlen(path) + strlen(name) + 2);
- return PCILIB_ERROR_MEMORY;
+ pcilib_error("Error allocating %zu bytes of memory in stack to create a file name", strlen(path) + strlen(name) + 2);
+ return PCILIB_ERROR_MEMORY;
}
sprintf(full_name, "%s/%s", path, name);
doc = xmlCtxtReadFile(ctx->xml.parser, full_name, NULL, 0);
if (!doc) {
- xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser);
- if (xmlerr) pcilib_error("Error parsing %s, xmlCtxtReadFile reported error %d - %s", full_name, xmlerr->code, xmlerr->message);
- else pcilib_error("Error parsing %s", full_name);
- return PCILIB_ERROR_INVALID_DATA;
+ xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser);
+ if (xmlerr) pcilib_error("Error parsing %s, xmlCtxtReadFile reported error %d - %s", full_name, xmlerr->code, xmlerr->message);
+ else pcilib_error("Error parsing %s", full_name);
+ return PCILIB_ERROR_INVALID_DATA;
}
err = xmlSchemaValidateDoc(ctx->xml.validator, doc);
if (err) {
- xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser);
- xmlFreeDoc(doc);
- if (xmlerr) pcilib_error("Error validating %s, xmlSchemaValidateDoc reported error %d - %s", full_name, xmlerr->code, xmlerr->message);
- else pcilib_error("Error validating %s", full_name);
- return PCILIB_ERROR_VERIFY;
+ xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser);
+ xmlFreeDoc(doc);
+ if (xmlerr) pcilib_error("Error validating %s, xmlSchemaValidateDoc reported error %d - %s", full_name, xmlerr->code, xmlerr->message);
+ else pcilib_error("Error validating %s", full_name);
+ return PCILIB_ERROR_VERIFY;
}
xpath = xmlXPathNewContext(doc);
if (!xpath) {
- xmlErrorPtr xmlerr = xmlGetLastError();
- xmlFreeDoc(doc);
- if (xmlerr) pcilib_error("Document %s: xmlXpathNewContext reported error %d - %s for document %s", full_name, xmlerr->code, xmlerr->message);
- else pcilib_error("Error creating XPath context for %s", full_name);
- return PCILIB_ERROR_FAILED;
+ xmlErrorPtr xmlerr = xmlGetLastError();
+ xmlFreeDoc(doc);
+ if (xmlerr) pcilib_error("Document %s: xmlXpathNewContext reported error %d - %s for document %s", full_name, xmlerr->code, xmlerr->message);
+ else pcilib_error("Error creating XPath context for %s", full_name);
+ return PCILIB_ERROR_FAILED;
}
- // This can only partially fail... Therefore we need to keep XML and just return the error...
+ // This can only partially fail... Therefore we need to keep XML and just return the error...
err = pcilib_xml_process_document(ctx, doc, xpath);
if (ctx->xml.num_files == PCILIB_MAX_MODEL_FILES) {
- xmlFreeDoc(doc);
+ xmlFreeDoc(doc);
xmlXPathFreeContext(xpath);
- pcilib_error("Too many XML files for a model, only up to %zu are supported", PCILIB_MAX_MODEL_FILES);
- return PCILIB_ERROR_TOOBIG;
+ pcilib_error("Too many XML files for a model, only up to %zu are supported", PCILIB_MAX_MODEL_FILES);
+ return PCILIB_ERROR_TOOBIG;
}
ctx->xml.docs[ctx->xml.num_files] = doc;
@@ -550,12 +939,12 @@ int pcilib_process_xml(pcilib_t *ctx, const char *location) {
if (!rep) return PCILIB_ERROR_NOTFOUND;
while ((file = readdir(rep)) != NULL) {
- size_t len = strlen(file->d_name);
- if ((len < 4)||(strcasecmp(file->d_name + len - 4, ".xml"))) continue;
- if (file->d_type != DT_REG) continue;
-
- err = pcilib_xml_load_file(ctx, model_path, file->d_name);
- if (err) pcilib_error("Error processing XML file %s", file->d_name);
+ size_t len = strlen(file->d_name);
+ if ((len < 4)||(strcasecmp(file->d_name + len - 4, ".xml"))) continue;
+ if (file->d_type != DT_REG) continue;
+
+ err = pcilib_xml_load_file(ctx, model_path, file->d_name);
+ if (err) pcilib_error("Error processing XML file %s", file->d_name);
}
closedir(rep);
@@ -586,16 +975,16 @@ int pcilib_init_xml(pcilib_t *ctx, const char *model) {
sprintf(xsd_path, "%s/model.xsd", model_dir);
if (stat(xsd_path, &st)) {
- pcilib_info("XML models are not present");
- return PCILIB_ERROR_NOTFOUND;
+ pcilib_info("XML models are not present");
+ return PCILIB_ERROR_NOTFOUND;
}
ctx->xml.parser = xmlNewParserCtxt();
if (!ctx->xml.parser) {
- xmlErrorPtr xmlerr = xmlGetLastError();
- if (xmlerr) pcilib_error("xmlNewParserCtxt reported error %d (%s)", xmlerr->code, xmlerr->message);
- else pcilib_error("Failed to create an XML parser context");
- return PCILIB_ERROR_FAILED;
+ xmlErrorPtr xmlerr = xmlGetLastError();
+ if (xmlerr) pcilib_error("xmlNewParserCtxt reported error %d (%s)", xmlerr->code, xmlerr->message);
+ else pcilib_error("Failed to create an XML parser context");
+ return PCILIB_ERROR_FAILED;
}
err = pcilib_xml_load_xsd(ctx, xsd_path);
@@ -613,44 +1002,44 @@ void pcilib_free_xml(pcilib_t *ctx) {
memset(ctx->xml.bank_nodes, 0, sizeof(ctx->xml.bank_nodes));
for (i = 0; i < ctx->num_banks; i++) {
- if (ctx->bank_ctx[i])
- ctx->bank_ctx[i]->xml = NULL;
+ if (ctx->bank_ctx[i])
+ ctx->bank_ctx[i]->xml = NULL;
}
-
+
for (i = 0; i < ctx->num_reg; i++) {
- ctx->register_ctx[i].xml = NULL;
+ ctx->register_ctx[i].xml = NULL;
}
-
+
for (i = 0; i < ctx->xml.num_files; i++) {
- if (ctx->xml.docs[i]) {
- xmlFreeDoc(ctx->xml.docs[i]);
- ctx->xml.docs[i] = NULL;
- }
- if (ctx->xml.xpath[i]) {
- xmlXPathFreeContext(ctx->xml.xpath[i]);
- ctx->xml.xpath[i] = NULL;
- }
+ if (ctx->xml.docs[i]) {
+ xmlFreeDoc(ctx->xml.docs[i]);
+ ctx->xml.docs[i] = NULL;
+ }
+ if (ctx->xml.xpath[i]) {
+ xmlXPathFreeContext(ctx->xml.xpath[i]);
+ ctx->xml.xpath[i] = NULL;
+ }
}
ctx->xml.num_files = 0;
if (ctx->xml.validator) {
- xmlSchemaFreeValidCtxt(ctx->xml.validator);
- ctx->xml.validator = NULL;
+ xmlSchemaFreeValidCtxt(ctx->xml.validator);
+ ctx->xml.validator = NULL;
}
-
+
if (ctx->xml.schema) {
- xmlSchemaFree(ctx->xml.schema);
- ctx->xml.schema = NULL;
-
+ xmlSchemaFree(ctx->xml.schema);
+ ctx->xml.schema = NULL;
+
}
if (ctx->xml.parser) {
- xmlFreeParserCtxt(ctx->xml.parser);
- ctx->xml.parser = NULL;
+ xmlFreeParserCtxt(ctx->xml.parser);
+ ctx->xml.parser = NULL;
}
-/*
- xmlSchemaCleanupTypes();
- xmlCleanupParser();
- xmlMemoryDump();
-*/
+ /*
+ xmlSchemaCleanupTypes();
+ xmlCleanupParser();
+ xmlMemoryDump();
+ */
}