summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pcilib/xml.c361
-rw-r--r--pcilib/xml.h14
-rw-r--r--pcitool/cli.c6
3 files changed, 372 insertions, 9 deletions
diff --git a/pcilib/xml.c b/pcilib/xml.c
index b93f2aa..a9be502 100644
--- a/pcilib/xml.c
+++ b/pcilib/xml.c
@@ -19,6 +19,8 @@
#include <assert.h>
#include <Python.h>
+//#define VIEW_OK
+//#define UNIT_OK
/**
* pcilib_xml_getdoc
@@ -670,3 +672,362 @@ void pcilib_xml_init_nodeset_bank_ctx(pcilib_register_bank_context_t *ctx){
}
*/
+
+#ifdef VIEW_OK
+/* pcilib_xml_getnumberformulaviews
+ *
+ * function to get the number of views of type formula, for further malloc
+ */
+int pcilib_xml_getnumberformulaviews(xmlXPathContextPtr doc){
+ int j;
+ xmlNodeSetPtr nodeviewsset=NULL;
+ nodeviewsset=pcilib_xml_getsetproperty(doc,VIEW_FORMULA_PATH)->nodesetval;
+ j=nodeviewsset->nodeNr;
+ return j;
+
+}
+
+/* pcilib_xml_getnumberenumviews
+ *
+ * function to get the number of views of type enum, for further malloc
+ */
+int pcilib_xml_getnumberenumviews(xmlXPathContextPtr doc){
+ int j;
+ xmlNodeSetPtr nodeviewsset=NULL;
+ nodeviewsset=pcilib_xml_getsetproperty(doc,VIEW_ENUM_PATH)->nodesetval;
+ j=nodeviewsset->nodeNr;
+ return j;
+
+
+}
+
+/* pcilib_xml_initialize_viewsformula
+ *
+ * function to create the structures to store the views of type formula from the xml
+ *
+ * values that need to be changed when xml file change: name, formula,
+ */
+void pcilib_xml_initialize_viewsformula(xmlDocPtr doc, pcilib_view_formula_ptr_t* myviewsformula){
+ xmlNodeSetPtr viewsetformula, viewformula, viewreverseformula, viewunit, viewformulaname, nodesetviewregister,nodesetviewregisterbit,nodesetregister,nodesetsubregister;
+ xmlChar *formula, *name,*reverseformula,*registername,*bankname,*unit;
+ int i,j,registernumber,viewnumber,k,l,externregisternumber,enregistrement,u;
+
+ char *substr;
+
+ xmlXPathContextPtr context;
+ context=pcilib_xml_getcontext(doc);
+
+ viewsetformula=pcilib_xml_getsetproperty(context,VIEW_FORMULA_PATH)->nodesetval;
+ viewformula=pcilib_xml_getsetproperty(context,VIEW_FORMULA_FORMULA_PATH)->nodesetval;
+ viewreverseformula=pcilib_xml_getsetproperty(context,VIEW_FORMULA_REVERSE_FORMULA_PATH)->nodesetval;
+ viewunit=pcilib_xml_getsetproperty(context,VIEW_FORMULA_UNIT_PATH)->nodesetval;
+ viewformulaname=pcilib_xml_getsetproperty(context,VIEW_FORMULA_NAME_PATH)->nodesetval;
+
+
+
+viewnumber=0;
+
+
+ nodesetviewregisterbit=pcilib_xml_getsetproperty(context,VIEW_BITS_REGISTER)->nodesetval;
+ nodesetviewregister=pcilib_xml_getsetproperty(context,VIEW_STANDARD_REGISTER)->nodesetval;
+ nodesetregister=pcilib_xml_getsetproperty(context,NAME_PATH)->nodesetval;
+ nodesetsubregister=pcilib_xml_getsetproperty(context,SUB_NAME_PATH)->nodesetval;
+
+ myviewsformula->viewsformula=calloc(myviewsformula->size,sizeof(pcilib_view_formula_t));
+ for(i=0;i<viewsetformula->nodeNr;i++){
+ registernumber=0;
+ name=xmlNodeListGetString(doc,viewformulaname->nodeTab[i]->xmlChildrenNode,1);
+ formula=xmlNodeListGetString(doc,viewformula->nodeTab[i]->xmlChildrenNode,1);
+ reverseformula=xmlNodeListGetString(doc,viewreverseformula->nodeTab[i]->xmlChildrenNode,1);
+ unit=xmlNodeListGetString(doc,viewunit->nodeTab[i]->xmlChildrenNode,1);
+
+ xmlXPathObjectPtr temp,temp2;
+
+ char* path;
+ path=malloc((strlen((char*)name)+51)*sizeof(char));
+ sprintf(path, VIEW_STANDARD_REGISTER_PLUS,(char*)name);
+ temp=pcilib_xml_getsetproperty(context,(xmlChar*)path);
+ if(temp!=NULL) nodesetviewregister= temp->nodesetval;
+
+ char* path2;
+ path2=malloc((strlen((char*)name)+strlen(VIEW_BITS_REGISTER_PLUS))*sizeof(char));
+ sprintf(path2, VIEW_BITS_REGISTER_PLUS,(char*)name);
+ temp2= pcilib_xml_getsetproperty(context,(xmlChar*)path2);
+ if(temp2!=NULL) nodesetviewregisterbit= temp2->nodesetval;
+
+ j=0;
+ if(temp!=NULL) j+=nodesetviewregister->nodeNr;
+ if(temp2!=NULL) j+=nodesetviewregisterbit->nodeNr;
+
+ myviewsformula->viewsformula[viewnumber].depending_registers=calloc((j),sizeof(pcilib_register_for_read_t));
+ myviewsformula->viewsformula[viewnumber].number_depending_registers=j;
+ registernumber=0;
+ if (temp!=NULL){
+ for(j=0; j<nodesetviewregister->nodeNr;j++){
+ myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].name=(char*)xmlNodeListGetString(doc,nodesetviewregister->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1);
+ bankname=xmlNodeListGetString(doc,xmlFirstElementChild(nodesetviewregister->nodeTab[j]->parent->parent->parent->parent)->last->prev->prev->prev->xmlChildrenNode,1);
+ myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].bank_name=(char*)bankname;
+ registernumber++;
+ }
+ }
+
+ if(temp2!=NULL){
+ for(j=0; j<nodesetviewregisterbit->nodeNr;j++){
+ myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].name=(char*)xmlNodeListGetString(doc,nodesetviewregisterbit->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1);
+ bankname=xmlNodeListGetString(doc,(xmlFirstElementChild(nodesetviewregisterbit->nodeTab[j]->parent->parent->parent->parent->parent->parent))->last->prev->prev->prev->xmlChildrenNode,1);
+ myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].bank_name=(char*)bankname;
+ registernumber++;
+ }
+ }
+
+ myviewsformula->viewsformula[viewnumber].name=(char*) name;
+ myviewsformula->viewsformula[viewnumber].formula=(char*) formula;
+ myviewsformula->viewsformula[viewnumber].reverseformula=(char*) reverseformula;
+ myviewsformula->viewsformula[viewnumber].unit=(char*) unit;
+
+ /* we then get the extern registers for the formula, which names are directly put in the formula*/
+ externregisternumber=0;
+ k=0;
+ u=0;
+ myviewsformula->viewsformula[viewnumber].extern_registers=calloc(1,sizeof(pcilib_register_for_read_t));
+ myviewsformula->viewsformula[viewnumber].number_extern_registers=0;
+
+ /* we first get the name of a register put in the formula, by getting indexes of start and end for this name*/
+ for(j=0;j<strlen((char*)formula);j++){
+ if(formula[j]=='@'){
+ k=j+1;
+ while((formula[k]!=' ' && formula[k]!=')' && formula[k]!='/' && formula[k]!='+' && formula[k]!='-' && formula[k]!='*' && formula[k]!='=') && (k<strlen((char*)formula))){
+ k++;
+ }
+ enregistrement=1;
+ substr=str_sub((char*)formula,j+1,k-1);
+ /* we verify the register is not the depending register*/
+ if(strcmp("reg",substr)!=0){
+
+ /* we then get recursively each standard register and test if it's the extern register or not*/
+ for(l=0;l<nodesetregister->nodeNr;l++){
+ registername=xmlNodeListGetString(doc,nodesetregister->nodeTab[l]->xmlChildrenNode,1);
+ if(strcmp((char*)registername,substr)==0){
+ bankname=xmlNodeListGetString(doc,(xmlFirstElementChild(nodesetregister->nodeTab[l]->parent->parent->parent))->last->prev->prev->prev->xmlChildrenNode,1);
+ /*before registering the extern register, as it matches, we tast if the said register was already registered or not*/
+ for(u=0;u<externregisternumber;u++){
+ if(strcmp(myviewsformula->viewsformula[viewnumber].extern_registers[u].name,(char*)registername)==0){
+ enregistrement=0;
+ }
+ }
+ if(enregistrement==1){
+ myviewsformula->viewsformula[viewnumber].number_extern_registers++;
+ myviewsformula->viewsformula[viewnumber].extern_registers=realloc(myviewsformula->viewsformula[viewnumber].extern_registers,myviewsformula->viewsformula[viewnumber].number_extern_registers*sizeof(pcilib_register_for_read_t));
+ myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].name=(char*)registername;
+ myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].bank_name=(char*)bankname;
+ enregistrement=0;
+ externregisternumber++;
+ }
+ break;
+ }
+ }
+ if(enregistrement==1){
+ /* we get recursively each bits register and test if it's the extern register of the formula or not*/
+ for(l=0;l<nodesetsubregister->nodeNr;l++){
+ registername=xmlNodeListGetString(doc,nodesetsubregister->nodeTab[l]->xmlChildrenNode, 1);
+ if(strcmp((char*)registername,substr)==0){
+ bankname=xmlNodeListGetString(doc,(xmlFirstElementChild(nodesetsubregister->nodeTab[l]->parent->parent->parent->parent->parent))->last->prev->prev->prev->xmlChildrenNode,1);
+ /* check to test if the register has already been registered or not*/
+ for(u=0;u<externregisternumber;u++){
+ if(strcmp(myviewsformula->viewsformula[viewnumber].extern_registers[u].name,(char*)registername)==0){
+ enregistrement=0;
+ break;
+ }
+ }
+ if(enregistrement==1){
+ myviewsformula->viewsformula[viewnumber].number_extern_registers++;
+ myviewsformula->viewsformula[viewnumber].extern_registers=realloc(myviewsformula->viewsformula[viewnumber].extern_registers,myviewsformula->viewsformula[viewnumber].number_extern_registers*sizeof(pcilib_register_for_read_t));
+ myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].name=(char*)registername;
+ myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].bank_name=(char*)bankname;
+ externregisternumber++;
+ enregistrement=0;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ viewnumber++;
+ }
+}
+
+/* pcilib_xml_initialize_viewsenum
+ *
+ * function to create the structures to store the views of type enum from the xml
+ *
+ * values that need to be changed when xml file change: current,
+*
+ */
+void pcilib_xml_initialize_viewsenum(xmlDocPtr doc, pcilib_view_enum_ptr_t* myviewsenum){
+ xmlNodeSetPtr viewsetenum,viewsetregister3, viewsetregister4;
+ xmlChar *name;
+ int i,k,viewnumber,j,registernumber;
+
+ xmlXPathContextPtr context;
+ context=pcilib_xml_getcontext(doc);
+
+ xmlXPathObjectPtr temp,temp2;
+
+ xmlNodePtr current;
+ viewsetenum=pcilib_xml_getsetproperty(context,VIEW_ENUM_PATH)->nodesetval;
+ xmlAttr *attr2,*attr3;
+ viewnumber=0;
+ int enumnumber=0;
+
+ myviewsenum->viewsenum=calloc(myviewsenum->size,sizeof(pcilib_view_enum_t));
+ for(i=0;i<viewsetenum->nodeNr;i++){
+ enumnumber=0;
+ k=0;
+ registernumber=0;
+ name=xmlNodeListGetString(doc,xmlFirstElementChild(viewsetenum->nodeTab[i])->xmlChildrenNode,1);
+ myviewsenum->viewsenum[viewnumber].name=(char*)name;
+ myviewsenum->viewsenum[viewnumber].registerenum=calloc(1,sizeof(char*));
+ myviewsenum->viewsenum[viewnumber].number_registerenum=0;
+ registernumber=0;
+
+ char* path;
+ path=malloc((strlen((char*)name)+51)*sizeof(char));
+ sprintf(path, VIEW_STANDARD_REGISTER_PLUS,(char*)name);
+ temp=pcilib_xml_getsetproperty(context,(xmlChar*)path);
+ if(temp!=NULL) viewsetregister3= temp->nodesetval;
+
+ char* path2;
+ path2=malloc((strlen((char*)name)+strlen(VIEW_BITS_REGISTER_PLUS))*sizeof(char));
+ sprintf(path2, VIEW_BITS_REGISTER_PLUS,(char*)name);
+ temp2= pcilib_xml_getsetproperty(context,(xmlChar*)path2);
+ if(temp2!=NULL) viewsetregister4= temp2->nodesetval;
+
+ j=0;
+ if(temp!=NULL) j+=viewsetregister3->nodeNr;
+ if(temp2!=NULL) j+=viewsetregister4->nodeNr;
+ myviewsenum->viewsenum[viewnumber].registerenum=malloc(j*sizeof(char*));
+ myviewsenum->viewsenum[viewnumber].number_registerenum=j;
+ if(temp!=NULL){
+ for(j=0; j<viewsetregister3->nodeNr;j++){
+ myviewsenum->viewsenum[viewnumber].registerenum[registernumber]=(char*)xmlNodeListGetString(doc,viewsetregister3->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1);
+ registernumber++;
+ }
+ }
+ if(temp2!=NULL){
+ for(j=0; j<viewsetregister4->nodeNr;j++){
+ myviewsenum->viewsenum[viewnumber].registerenum[registernumber]=(char*)xmlNodeListGetString(doc,viewsetregister4->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1);
+ registernumber++;
+ }
+ }
+
+
+ current=xmlFirstElementChild(viewsetenum->nodeTab[i])->next->next->next->next;
+ while(current!=viewsetenum->nodeTab[i]->last->prev){
+ k++;
+ current=current->next->next;
+ }
+
+ myviewsenum->viewsenum[viewnumber].myenums=calloc((k+1),sizeof(pcilib_enum_t));
+ myviewsenum->viewsenum[viewnumber].number_enums=k+1;
+
+ /* we get here each enum for a said view except the last one*/
+ current=xmlFirstElementChild(viewsetenum->nodeTab[i])->next->next;
+ while(current!=viewsetenum->nodeTab[i]->last->prev->prev->prev){
+ attr2 = current->properties;
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].command=(char*)xmlNodeListGetString(doc,current->xmlChildrenNode,1);
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value=(char*)attr2->children->content;
+ attr2=attr2->next;
+ /* and we take the properties that are given about range*/
+ if(attr2!=NULL){
+ if(strcmp((char*)attr2->name,"min")==0){
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=(char*)attr2->children->content;
+ attr3=attr2->next;
+ if(attr3 !=NULL){
+ if(strcmp((char*)attr3->name,"max")==0){
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr3->children->content;
+ }else pcilib_error("problem in xml file at enum");
+
+ }else{
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
+ }
+
+ }else if(strcmp((char*)attr2->name,"max")==0){
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr2->children->content;
+ }else pcilib_error("problem in xml file at enum");
+ }else{
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
+ }
+ enumnumber++;
+ current=current->next->next;
+ }
+ /* get the last enum and the given properties */
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].command=(char*)xmlNodeListGetString(doc,current->xmlChildrenNode,1);
+ attr2 = current->properties;
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value=(char*)attr2->children->content;
+ attr2=attr2->next;
+ if(attr2!=NULL){
+ if(strcmp((char*)attr2->name,"min")==0){
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=(char*)attr2->children->content;
+ attr3=attr2->next;
+ if(attr3 !=NULL){
+ if(strcmp((char*)attr3->name,"max")==0){
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr3->children->content;
+ }else pcilib_error("problem in xml file at enum");
+ }else{
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
+ }
+
+ }else if(strcmp((char*)attr2->name,"max")==0){
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr2->children->content;
+ }else pcilib_error("problem in xml file at enum");
+ }else{
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
+ myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
+ }
+
+ viewnumber++;
+
+ }
+}
+#endif
+
+#ifdef UNIT_OK
+
+void pclib_xml_initialize_units(xmlDocPtr doc, pcilib_units_ptr_t* unitsptr){
+
+ xmlNodeSetPtr nodesetbaseunit=NULL, nodesettransformunit=NULL;
+ xmlXPathContextptr context;
+ context=pcilib_xml_getcontext(doc);
+ xmlXPathObjectPtr temp;
+ int i,j;
+ char *path;
+
+ temp=pcilib_xml_getsetproperty(context, BASE_UNIT_PATH);
+ if(temp!=NULL) nodesetbaseunit=temp->nodesetval;
+ else pcilib_error("the unit xml file is wrong");
+
+ unitsptr->list_unit=malloc(nodesetbaseunit->nodeNr*sizeof(pcilib_unit_t));
+ unitsptr->size=nodesetbaseunit->nodeNr;
+
+ for(i=0; i< nodesetbaseunit->NodeNr; i++){
+ unitsptr->list_unit[i].name=nodesetbaseunit->nodeTab[i]->properties->children->content;
+ path=malloc((strlen(unitsptr->list_unit[i].name)+35)*sizeof(char));
+ sprintf(path, TRANSFORM_UNIT_PATH, unitsptr->list_unit[i].name);
+ temp=pcilib_xml_getsetproperty(context, path);
+ if(temp!=NULL){
+ unitsptr->list_unit[i].size_trans_units=temp->nodeNr;
+ unitsptr->list_unit[i].other_units=malloc(temp->nodeNr*sizeof(pcilib_transform_unit_t));
+ for(j=0;j<temp->nodeNr;j++){
+ unitsptr->list_unit[i].other_units[j].name=temp->nodeTab[j]->properties->children->content;
+ unitsptr->list_unit[i].other_units[j].transform_formula=(char*)xmlNodeListGetString(doc,temp->nodeTab[j]->xmlChildrenNode,1);
+ }
+ }
+ }
+
+}
+#endif
diff --git a/pcilib/xml.h b/pcilib/xml.h
index da540b5..f5833aa 100644
--- a/pcilib/xml.h
+++ b/pcilib/xml.h
@@ -74,15 +74,17 @@
#define BANK_NAME_PATH ((xmlChar*)"/model/banks/bank/bank_description/name") /**< path to name of banks.*/
#define BANK_DESCRIPTION_PATH ((xmlChar*)"/model/banks/bank/bank_description/description") /**<path to description of banks.*/
-#define UNIT_PATH ((char*)"/units/unit[@name=\"%s\"]/convert_unit[@value=\"%s\"]") /**< path to get possible units for a view in units xml file.*/
/**
- * this type is used to save enough information in the pcilib_watch_to_read_with_enum function to get a good output in human readable form.
+ * this path get the units in the units xml file
*/
-typedef struct{
- int val; /**< value of a register corresponding to an enum value.*/
- char* name; /**< name of the corresponding command to val.*/
-}info_enum;
+#define BASE_UNIT_PATH ((char*)"/units/unit")
+
+/**
+ * this path permits to get the possible units one given unit can be converted into in the xml.
+ */
+#define TRANSFORM_UNIT_PATH ((char*)"/units/unit[@name=\"%s\"]/convert_unit")
+
/**
* this function takes a string and will create an abtract syntax tree from the xml file represented by the string.
diff --git a/pcitool/cli.c b/pcitool/cli.c
index f105349..49d13ee 100644
--- a/pcitool/cli.c
+++ b/pcitool/cli.c
@@ -3128,9 +3128,6 @@ int main(int argc, char **argv) {
// Requesting real-time priority when needed
switch (mode) {
- case MODE_VALIDATE_XML:
- validation();
- break;
case MODE_READ:
case MODE_WRITE:
if (amode != ACCESS_DMA)
@@ -3146,6 +3143,9 @@ int main(int argc, char **argv) {
}
switch (mode) {
+ case MODE_VALIDATE_XML:
+ validation();
+ break;
case MODE_INFO:
Info(handle, model_info);
break;