From f82813bfa40193aec07e013b029eec6dc092ecdd Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Wed, 1 Jul 2015 16:18:45 +0200 Subject: 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 --- pcilib/xml.c | 672 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 672 insertions(+) create mode 100644 pcilib/xml.c (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c new file mode 100644 index 0000000..b93f2aa --- /dev/null +++ b/pcilib/xml.c @@ -0,0 +1,672 @@ +/** + * @file pcilib_xml.c + * @version 1.0 + * + * @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 + * + * @details this code was meant to be evolutive as the XML files evolute. In this meaning, most of the xml parsing is realized with XPath expressions(when it was possible), so that changing the xml xould result mainly in changing the XPAth pathes present in the header file. In a case of a change in xml file, variables that need to be changed other than xpathes, will be indicated in the description of the function. + + 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. + + In case the performance is not good enough, please consider the following : no more configuration file indicating where the files required are, hard code of formulas, and go to complete non evolutive code : get 1 access to xml file and context, and then make recursive descent to get all you need(investigation of libxml2 source code would be so needed to prove it's better to go recursive than just xpath). + */ + +#include "xml.h" +#include "error.h" +#include +#include +#include +#include +#include + + +/** + * pcilib_xml_getdoc + * this function takes a string and will create an abtract syntax tree from the xml file represented by the string + * @param[in] filename the the name of the xml file containing registers and banks + */ +xmlDocPtr pcilib_xml_getdoc(char* filename){ + xmlDocPtr doc; + doc=xmlParseFile(filename); /**nodesetval)){ + xmlXPathFreeObject(result); +// pcilib_warning("warning : no results found for: %s",xpath); + return NULL; + } + + return result; +} + +/** pcilib_xml_getcontext. + * this function create a context in an AST (ie initialize XPAth for the AST). + * @param[in] doc the AST of the xml file. + */ +xmlXPathContextPtr pcilib_xml_getcontext(xmlDocPtr doc){ + xmlXPathContextPtr context; + context= xmlXPathNewContext(doc); /**addr=(pcilib_register_addr_t)strtol((char*)adress,&ptr,0); + myregister->offset=(pcilib_register_size_t)strtol((char*)offset,&ptr,0); + myregister->bits=(pcilib_register_size_t)strtol((char*)size,&ptr,0); + myregister->defvalue=(pcilib_register_value_t)strtol((char*)defvalue,&ptr,0); + + if(strcmp((char*)rwmask,"all bits")==0){ + myregister->rwmask=PCILIB_REGISTER_ALL_BITS; + }else if(strcmp((char*)rwmask,"0")==0){ + myregister->rwmask=0; + }else{ + myregister->rwmask=(pcilib_register_value_t)strtol((char*)rwmask,&ptr,0); + } + + if(strcmp((char*)mode,"R")==0){ + myregister->mode=PCILIB_REGISTER_R; + }else if(strcmp((char*)mode,"W")==0){ + myregister->mode=PCILIB_REGISTER_W; + }else if(strcmp((char*)mode,"RW")==0){ + myregister->mode=PCILIB_REGISTER_RW; + }else if(strcmp((char*)mode,"W")==0){ + myregister->mode=PCILIB_REGISTER_W; + }else if(strcmp((char*)mode,"RW1C")==0){ + myregister->mode=PCILIB_REGISTER_RW1C; + }else if(strcmp((char*)mode,"W1C")==0){ + myregister->mode=PCILIB_REGISTER_W1C; + } + + if(strcmp((char*)type,"standard")==0){ + myregister->type=PCILIB_REGISTER_STANDARD; + }else if(strcmp((char*)type,"bits")==0){ + myregister->type=PCILIB_REGISTER_BITS; + }else if(strcmp((char*)type,"fifo")==0){ + myregister->type=PCILIB_REGISTER_FIFO; + } + + if(strcmp((char*)bank,"bank 0")==0){ + myregister->bank=PCILIB_REGISTER_BANK0; + }else if(strcmp((char*)bank,"bank 1")==0){ + myregister->bank=PCILIB_REGISTER_BANK1; + }else if(strcmp((char*)bank,"bank 2")==0){ + myregister->bank=PCILIB_REGISTER_BANK2; + }else if(strcmp((char*)bank,"bank 3")==0){ + myregister->bank=PCILIB_REGISTER_BANK3; + }else if(strcmp((char*)bank,"DMA bank")==0){ + myregister->bank=PCILIB_REGISTER_BANK_DMA; + }else if (strcmp((char*)bank,"dynamic bank")==0){ + myregister->addr=PCILIB_REGISTER_BANK_DYNAMIC; + }else{ + myregister->bank=PCILIB_REGISTER_BANK_INVALID; + } + + myregister->name=(char*)name; + myregister->description=(char*)description; + /*should we include those xmlnodes?*/ + //myregister->xmlNode=node; +} + +/** pcilib_xml_getnumberbanks + * + * get the number of banks nodes in the AST, used to have some malloc in pci + * @param[in] doc the Xpath context of the xml file. + * @return the number of banks. + */ +int pcilib_xml_getnumberbanks(xmlXPathContextPtr doc){ + xmlNodeSetPtr nodesetadress=NULL; + xmlXPathObjectPtr temp; + temp=pcilib_xml_getsetproperty(doc,BANK_ADDR_PATH); /**< we first get a structure containing all the banks nodes*/ + if(temp!=NULL) nodesetadress=temp->nodesetval; + else pcilib_error("no bank in the xml file"); + return nodesetadress->nodeNr; /**< we then return the number of said nodes */ +} + +/** pcilib_xml_initialize_banks + * + * function to create the structures to store the banks from the AST + * @see pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol,xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description, xmlNodePtr node). + * @param[in] doc the AST of the xml file. + * @param[in,out] mybanks the structure containing the banks. + */ +void pcilib_xml_initialize_banks(xmlDocPtr doc, pcilib_register_bank_description_t* mybanks){ + pcilib_register_bank_description_t mybank; + + xmlNodeSetPtr nodesetadress=NULL,nodesetbar=NULL,nodesetsize=NULL,nodesetprotocol=NULL,nodesetread_addr=NULL,nodesetwrite_addr=NULL,nodesetaccess=NULL,nodesetendianess=NULL,nodesetformat=NULL,nodesetname=NULL,nodesetdescription=NULL; + xmlChar *adress=NULL,*bar=NULL,*size=NULL,*protocol=NULL,*read_addr=NULL,*write_addr=NULL,*access=NULL,*endianess=NULL,*format=NULL,*name=NULL,*description=NULL; + xmlNodePtr mynode; + + xmlXPathContextPtr context; + context=pcilib_xml_getcontext(doc); + + int i; + + mynode=malloc(sizeof(xmlNode)); + + xmlXPathObjectPtr temp; + + /** we first get the nodes corresponding to the properties we want + * note: here a recursive algorithm may be more efficient but less evolutive*/ + temp=pcilib_xml_getsetproperty(context,BANK_ADDR_PATH); + if(temp!=NULL) nodesetadress=temp->nodesetval; + else pcilib_error("there is no adress for banks in the xml"); + + temp=pcilib_xml_getsetproperty(context,BANK_BAR_PATH); + if(temp!=NULL) nodesetbar=temp->nodesetval; + else pcilib_error("there is no bar for banks in the xml"); + + temp=pcilib_xml_getsetproperty(context,BANK_SIZE_PATH); + if(temp!=NULL) nodesetsize=temp->nodesetval; + else pcilib_error("there is no size for banks in the xml"); + + temp=pcilib_xml_getsetproperty(context,BANK_PROTOCOL_PATH); + if(temp!=NULL) nodesetprotocol= temp->nodesetval; + else pcilib_error("there is no protocol for banks in the xml"); + + temp=pcilib_xml_getsetproperty(context,BANK_READ_ADDR_PATH); + if(temp!=NULL) nodesetread_addr=temp->nodesetval; + else pcilib_error("there is no read_adress for banks in the xml"); + + temp=pcilib_xml_getsetproperty(context,BANK_WRITE_ADDR_PATH); + if(temp!=NULL)nodesetwrite_addr=temp->nodesetval; + else pcilib_error("there is no write_adress for banks in the xml"); + + temp=pcilib_xml_getsetproperty(context,BANK_ACCESS_PATH); + if(temp!=NULL)nodesetaccess=temp->nodesetval; + else pcilib_error("there is no access for banks in the xml"); + + temp=pcilib_xml_getsetproperty(context,BANK_ENDIANESS_PATH); + if(temp!=NULL) nodesetendianess=temp->nodesetval; + else pcilib_error("there is no endianess for banks in the xml"); + + temp=pcilib_xml_getsetproperty(context,BANK_FORMAT_PATH); + if(temp!=NULL) nodesetformat=temp->nodesetval; + else pcilib_error("there is no format for banks in the xml"); + + temp=pcilib_xml_getsetproperty(context,BANK_NAME_PATH); + if(temp!=NULL)nodesetname=temp->nodesetval; + else pcilib_error("there is no name for banks in the xml"); + + temp=pcilib_xml_getsetproperty(context,BANK_DESCRIPTION_PATH); + if(temp!=NULL)nodesetdescription=temp->nodesetval; + + for(i=0;inodeNr;i++){ + /** we then get each node from the structures above*/ + adress=xmlNodeListGetString(doc,nodesetadress->nodeTab[i]->xmlChildrenNode, 1); + bar=xmlNodeListGetString(doc,nodesetbar->nodeTab[i]->xmlChildrenNode, 1); + size=xmlNodeListGetString(doc,nodesetsize->nodeTab[i]->xmlChildrenNode, 1); + protocol=xmlNodeListGetString(doc,nodesetprotocol->nodeTab[i]->xmlChildrenNode, 1); + read_addr=xmlNodeListGetString(doc,nodesetread_addr->nodeTab[i]->xmlChildrenNode, 1); + write_addr=xmlNodeListGetString(doc,nodesetwrite_addr->nodeTab[i]->xmlChildrenNode, 1); + access=xmlNodeListGetString(doc,nodesetaccess->nodeTab[i]->xmlChildrenNode, 1); + endianess=xmlNodeListGetString(doc,nodesetendianess->nodeTab[i]->xmlChildrenNode, 1); + format=xmlNodeListGetString(doc,nodesetformat->nodeTab[i]->xmlChildrenNode, 1); + name=xmlNodeListGetString(doc,nodesetname->nodeTab[i]->xmlChildrenNode, 1); + description=xmlNodeListGetString(doc,nodesetdescription->nodeTab[i]->xmlChildrenNode, 1); + + mynode=nodesetadress->nodeTab[i]->parent; + /** the following function will create the given structure for banks*/ + pcilib_xml_create_bank(&mybank,adress,bar,size,protocol,read_addr,write_addr,access,endianess,format, name, description,mynode); + mybanks[i]=mybank; + } + +} + +/** pcilib_xml_create_bank + * + * this function create a bank structure from the results of xml parsing + * @param[out] mybank the created bank. + * @param[in] adress the adress of the bank that will be created. + * @param[in] bar the bar of the bank that will be created. + * @param[in] size the size of the bank that will be created. + * @param[in] protocol the protocol of the bank that will be created. + * @param[in] read_addr the read adress for protocol of the bank that will be created. + * @param[in] write_addr the write adress for the protocol of the bank that will be created. + * @param[in] access the word size of the bank that will be created. + * @param[in] endianess the endianess of the bank that will be created. + * @param[in] format the format of the bank that will be created. + * @param[in] name the name of the bank that will be created. + * @param[in] description the description of the bank that will be created. + * @param[in] node the xmlNodeptr referring to the bank_description node of the bank that will be created. + */ +void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol, xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description, xmlNodePtr node){ + + char* ptr; + + /** we recreate each sub property of banks' structure given the results of xml parsing + note : strtol is used here to get hexadecimal and decimal values from the xml file as well*/ + + if (strcmp((char*)adress,"bank 0")==0){ + mybank->addr=PCILIB_REGISTER_BANK0; + }else if (strcmp((char*)adress,"bank 1")==0){ + mybank->addr=PCILIB_REGISTER_BANK1; + }else if (strcmp((char*)adress,"bank 2")==0){ + mybank->addr=PCILIB_REGISTER_BANK2; + }else if (strcmp((char*)adress,"bank 3")==0){ + mybank->addr=PCILIB_REGISTER_BANK3; + }else if (strcmp((char*)adress,"DMA bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DMA; + }else if (strcmp((char*)adress,"DMAconf bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DMACONF; + }else if (strcmp((char*)adress,"dynamic bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC; + }else{ + mybank->addr=PCILIB_REGISTER_BANK_INVALID; + } + + if(strcmp((char*)bar,"0")==0){ + mybank->bar=PCILIB_BAR0; + }else if(strcmp((char*)bar,"ipecamera_register")==0){ + mybank->bar=PCILIB_BAR1; + } + + mybank->bar=(pcilib_bar_t)strtol((char*)bar,&ptr,0); + mybank->size=(size_t)strtol((char*)size,&ptr,0); + + if(strcmp((char*)protocol,"default")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT; + }else if(strcmp((char*)protocol,"0")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL0; + }else if(strcmp((char*)protocol,"dma")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DMA; + }else if(strcmp((char*)protocol,"dynamic")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DYNAMIC; + }else if (strcmp((char*)protocol,"software")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_SOFTWARE; + }else mybank->protocol=PCILIB_REGISTER_PROTOCOL_INVALID; + + mybank->read_addr=(uintptr_t)strtol((char*)read_addr,&ptr,0); + mybank->write_addr=(uintptr_t)strtol((char*)write_addr,&ptr,0); + mybank->access=(uint8_t)strtol((char*)access,&ptr,0); + + if(strcmp((char*)endianess,"little")==0){ + mybank->endianess=PCILIB_LITTLE_ENDIAN; + }else if(strcmp((char*)endianess,"big")==0){ + mybank->endianess=PCILIB_BIG_ENDIAN; + }else if(strcmp((char*)endianess,"host")==0){ + mybank->endianess=PCILIB_HOST_ENDIAN; + } + + mybank->raw_endianess=mybank->endianess; + + mybank->name=(char*)name; + mybank->description=(char*)description; + /* to include or not?*/ + //mybank->xmlNode=node; +} + + +/** pcilib_xml_getnumberregisters + * + * get the number of registers in the xml document, for further mallocs + * @param[in] doc the xpath context of the xml file. + * @return the numbers of registers in xml file. + */ +int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc){ + xmlNodeSetPtr nodesetadress=NULL,nodesetsuboffset=NULL; + xmlXPathObjectPtr temp,temp2; + temp=pcilib_xml_getsetproperty(doc,ADRESS_PATH); /**nodesetval; /**nodesetval;/**< we get the structure with all bits registers here */ + else nodesetsuboffset->nodeNr=0; + return nodesetadress->nodeNr + nodesetsuboffset->nodeNr; /**nodesetval; + else pcilib_error("no adress for registers found in xml"); + + temp=pcilib_xml_getsetproperty(context,OFFSET_PATH); + if(temp!=NULL)nodesetoffset=temp->nodesetval; + else pcilib_error("no offset for registers found in xml"); + + temp=pcilib_xml_getsetproperty(context,DEFVALUE_PATH); + if(temp!=NULL)nodesetdefvalue=temp->nodesetval; + else pcilib_error("no defvalue for registers found in xml"); + + temp=pcilib_xml_getsetproperty(context,RWMASK_PATH); + if(temp!=NULL)nodesetrwmask=temp->nodesetval; + else pcilib_error("no rwmask for registers found in xml"); + + temp=pcilib_xml_getsetproperty(context,SIZE_PATH); + if(temp!=NULL)nodesetsize=temp->nodesetval; + else pcilib_error("no size for registers found in xml"); + + temp=pcilib_xml_getsetproperty(context,MODE_PATH); + if(temp!=NULL)nodesetmode=temp->nodesetval; + else pcilib_error("no mode for registers found in xml"); + + temp=pcilib_xml_getsetproperty(context,NAME_PATH); + if(temp!=NULL)nodesetname=temp->nodesetval; + else pcilib_error("no name for registers found in xml"); + + xmlNodeSetPtr nodesetsuboffset=NULL,nodesetsubsize=NULL,nodesetsubmode=NULL,nodesetsubname=NULL; + xmlChar *subadress=NULL,*suboffset=NULL,*subdefvalue=NULL,*subrwmask=NULL,*subsize=NULL,*submode=NULL,*subname=NULL,*subbank=NULL,*subtype=NULL,*subdescription=NULL; + + /**get the structures containing each property of bits registers */ + temp=pcilib_xml_getsetproperty(context,SUB_OFFSET_PATH); + if(temp!=NULL)nodesetsuboffset=temp->nodesetval; + else pcilib_error("no offset for registers bits found in xml"); + + temp=pcilib_xml_getsetproperty(context,SUB_SIZE_PATH); + if(temp!=NULL)nodesetsubsize=temp->nodesetval; + else pcilib_error("no size for registers bits found in xml"); + + temp=pcilib_xml_getsetproperty(context,SUB_MODE_PATH); + if(temp!=NULL)nodesetsubmode=temp->nodesetval; + else pcilib_error("no mode for registers bits found in xml"); + + temp=pcilib_xml_getsetproperty(context,SUB_NAME_PATH); + if(temp!=NULL)nodesetsubname=temp->nodesetval; + else pcilib_error("no name for registers bits found in xml"); + + + pcilib_register_description_t myregister; + + int i,j; + + for(i=0;inodeNr;i++){ + /** get each sub property of each standard registers*/ + adress=xmlNodeListGetString(doc,nodesetadress->nodeTab[i]->xmlChildrenNode, 1); + tempnode=xmlFirstElementChild(xmlFirstElementChild(nodesetadress->nodeTab[i]->parent->parent->parent)); + if(strcmp("adress",(char*)tempnode->name)==0) bank=xmlNodeListGetString(doc,tempnode->xmlChildrenNode,1); + else pcilib_error("the xml file is malformed"); + offset=xmlNodeListGetString(doc,nodesetoffset->nodeTab[i]->xmlChildrenNode, 1); + size=xmlNodeListGetString(doc,nodesetsize->nodeTab[i]->xmlChildrenNode, 1); + defvalue=xmlNodeListGetString(doc,nodesetdefvalue->nodeTab[i]->xmlChildrenNode, 1); + rwmask=xmlNodeListGetString(doc,nodesetrwmask->nodeTab[i]->xmlChildrenNode, 1); + mode=xmlNodeListGetString(doc,nodesetmode->nodeTab[i]->xmlChildrenNode, 1); + name=xmlNodeListGetString(doc,nodesetname->nodeTab[i]->xmlChildrenNode, 1); + type=(xmlChar*)"standard"; + if(nodesetname->nodeTab[i]->next->next!= NULL && strcmp((char*)nodesetname->nodeTab[i]->next->next->name,"description")==0){ + description=xmlNodeListGetString(doc,nodesetname->nodeTab[i]->next->next->xmlChildrenNode,1); + }else{ + description=(xmlChar*)""; + } + mynode=nodesetadress->nodeTab[i]->parent; + /**creation of a register with the given previous properties*/ + pcilib_xml_create_register(&myregister,adress,offset,size,defvalue,rwmask,mode, type, bank, name, description,mynode); + registers[i]=myregister; + } + + j=i; + + for(i=0;inodeNr;i++){ + /** we get there each subproperty of each bits register*/ + tempnode=xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent); + if(strcmp((char*)tempnode->name,"adress")==0)subadress=xmlNodeListGetString(doc,tempnode->xmlChildrenNode, 1); + else pcilib_error("xml file is malformed"); + tempnode= xmlFirstElementChild(xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent->parent->parent)); + if(strcmp((char*)tempnode->name,"adress")==0) subbank=xmlNodeListGetString(doc,tempnode->xmlChildrenNode,1); + else pcilib_error("xml file is malformed"); + suboffset=xmlNodeListGetString(doc,nodesetsuboffset->nodeTab[i]->xmlChildrenNode, 1); + subsize=xmlNodeListGetString(doc,nodesetsubsize->nodeTab[i]->xmlChildrenNode, 1); + tempnode=xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent)->next->next->next->next->next->next; + if(strcmp((char*)tempnode->name,"default")==0)subdefvalue=xmlNodeListGetString(doc,tempnode->xmlChildrenNode, 1); + else pcilib_error("xml file is malformed"); + subrwmask=xmlNodeListGetString(doc,nodesetsuboffset->nodeTab[i]->parent->parent->prev->prev->prev->prev->prev->prev->xmlChildrenNode, 1); + submode=xmlNodeListGetString(doc,nodesetsubmode->nodeTab[i]->xmlChildrenNode, 1); + subname=xmlNodeListGetString(doc,nodesetsubname->nodeTab[i]->xmlChildrenNode, 1); + subtype=(xmlChar*)"bits"; + if(nodesetsubname->nodeTab[i]->next->next!= NULL && strcmp((char*)nodesetsubname->nodeTab[i]->next->next->name,"sub_description")==0){ + subdescription=xmlNodeListGetString(doc,nodesetsubname->nodeTab[i]->next->next->xmlChildrenNode,1); + }else{ + subdescription=(xmlChar*)""; + } + mynode=nodesetsuboffset->nodeTab[i]->parent; + /** creation of a bits register given the previous properties*/ + pcilib_xml_create_register(&myregister,subadress,suboffset,subsize,subdefvalue,subrwmask,submode, subtype, subbank, subname, subdescription,mynode); + registers[i+j]=myregister; + } +} + + +/* + * next 3 functions are for the implementation of a merge sort algorithm + */ +void topdownmerge(pcilib_register_description_t *A, int start, int middle, int end, pcilib_register_description_t *B){ + int i0,i1,j; + i0= start; + i1=middle; + + for(j=start;j=end || A[i0].addr<=A[i1].addr)){ + B[j]=A[i0]; + i0++; + } + else{ + B[j]=A[i1]; + i1++; + } + } +} + +void copyarray(pcilib_register_description_t *B, int start,int end, pcilib_register_description_t *A){ + int k; + for (k=start; k +/** validation + * + * function to validate the xml file against the xsd, so that it does not require extern software + */ +void validation() +{ +xmlDocPtr doc; +xmlSchemaPtr schema = NULL; +xmlSchemaParserCtxtPtr ctxt; + +char *XMLFileName; + pcilib_xml_read_config(&XMLFileName,3); +char *XSDFileName; + pcilib_xml_read_config(&XSDFileName,12); +int ret=1; + +ctxt = xmlSchemaNewParserCtxt(XSDFileName); + +schema = xmlSchemaParse(ctxt); +xmlSchemaFreeParserCtxt(ctxt); + +doc = xmlReadFile(XMLFileName, NULL, 0); + +if (doc == NULL) +{ + pcilib_error("Could not parse xml document "); +} +else +{ +xmlSchemaValidCtxtPtr ctxt; +/** validation here*/ +ctxt = xmlSchemaNewValidCtxt(schema); +ret = xmlSchemaValidateDoc(ctxt, doc); +xmlSchemaFreeValidCtxt(ctxt); +xmlFreeDoc(doc); +} + +//! free the resource +if(schema != NULL) +xmlSchemaFree(schema); + +xmlSchemaCleanupTypes(); +/** print results */ +if (ret == 0) +{ + printf("xml file validates\n"); +} +else +{ + printf("xml file does not validate against the schema\n"); +} + +} + +/** pcilib_xml_read_config + * + * function to get the config we want at line j, in order to be able to have a configuration file with pwd to files we want +* @param[in,out] xmlfile the string representating a pwd to a file we want to access in:uninitilized out: the pwd. +* @param[in] i the line at which the function should read the file to get the pwd. + */ +void pcilib_xml_read_config(char** xmlfile, int j){ + FILE *fp; + + fp=fopen("config.txt","r"); + char line[60]; + memset(line,'\0',60); + int i=0,k; + char *temp1; + if(fp==NULL) pcilib_error("can't find the configuration file: it must be near the executable"); + + while(fgets(line,60,fp)!=NULL){ + if(i==j) { + k=0; + temp1=calloc((strlen(line)),sizeof(char)); + while(line[k]!='\n'){ + temp1[k]=line[k]; + k++; + } + temp1[k]='\0'; + *xmlfile=temp1; + } + i++; + memset(line,'\0',60); + } +} +/* to include or not?*/ +/** pcilib_xml_init_nodeset_register_ctx + * + * function to get all registers nodes in a structure and put it in registers context +* @param[in] ctx the register context running. + * +void pcilib_xml_init_nodeset_register_ctx(pcilib_register_context_t *ctx){ + char* xmlfile; + pcilib_xml_read_config(&xmlfile,3); + xmlDocPtr doc; + doc=pcilib_xml_getdoc(xmlfile); + xmlXPathContextPtr context; + context=pcilib_xml_getcontext(doc); + + xmlNodeSetPtr registers; + registers = pcilib_xml_getsetproperty(context, REGISTERS_PATH)->nodesetval; + ctx->registers_nodes=registers; +} + +** pcilib_xml_init_nodeset_bank_ctx + * + *function to get all banks nodes in a structure and put it in banks context +* @param[in] ctx the bank context running. + * +void pcilib_xml_init_nodeset_bank_ctx(pcilib_register_bank_context_t *ctx){ + char* xmlfile; + pcilib_xml_read_config(&xmlfile,3); + xmlDocPtr doc; + doc=pcilib_xml_getdoc(xmlfile); + xmlXPathContextPtr context; + context=pcilib_xml_getcontext(doc); + + xmlNodeSetPtr banks; + banks = pcilib_xml_getsetproperty(context, BANKS_PATH)->nodesetval; + ctx->banks_nodes=banks; + +} +*/ -- cgit v1.2.3 From 01e63939789b7b6f195bf985dc06151cf5ee780b Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Fri, 3 Jul 2015 12:32:07 +0200 Subject: modified version to include future functions --- pcilib/xml.c | 361 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) (limited to 'pcilib/xml.c') 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 #include +//#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;inodeNr;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; jnodeNr;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; jnodeNr;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;jnodeNr;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;uviewsformula[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;lnodeNr;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;uviewsformula[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;inodeNr;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; jnodeNr;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; jnodeNr;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;jnodeNr;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 -- cgit v1.2.3 From 5a7bcf11b8e3168900a75e7cbf3b1e18f424d271 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Tue, 7 Jul 2015 14:03:39 +0200 Subject: some modif --- pcilib/xml.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c index a9be502..205b563 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -306,8 +306,12 @@ void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* if(strcmp((char*)bar,"0")==0){ mybank->bar=PCILIB_BAR0; - }else if(strcmp((char*)bar,"ipecamera_register")==0){ + }else if(strcmp((char*)bar,"1")==0){ mybank->bar=PCILIB_BAR1; + }else if(strcmp((char*)bar,"no_bar")==0){ + mybank->bar=PCILIB_BAR_NOBAR; + }else{ + mybank->bar=PCILIB_BAR_INVALID; } mybank->bar=(pcilib_bar_t)strtol((char*)bar,&ptr,0); @@ -336,7 +340,7 @@ void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* }else if(strcmp((char*)endianess,"host")==0){ mybank->endianess=PCILIB_HOST_ENDIAN; } - + mybank->format=(char*)format; mybank->raw_endianess=mybank->endianess; mybank->name=(char*)name; -- cgit v1.2.3 From d3678e0fcb489eba625347d1209bd8a179153ae0 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Thu, 27 Aug 2015 11:09:21 +0200 Subject: put xml nodes pointers for banks and registers in pcilib_t, compil ok --- pcilib/xml.c | 200 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 103 insertions(+), 97 deletions(-) (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c index 205b563..762f805 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -18,7 +18,7 @@ #include #include #include - +#include "pci.h" //#define VIEW_OK //#define UNIT_OK @@ -90,9 +90,8 @@ xmlXPathContextPtr pcilib_xml_getcontext(xmlDocPtr doc){ * @param[in] bank the bank of the future register * @param[in] name the name of the future register * @param[in] description the description of the future register - * @param[in] node the current xmlNode in the xml of the future register */ -void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlChar* adress, xmlChar *offset, xmlChar *size, xmlChar *defvalue, xmlChar *rwmask, xmlChar *mode, xmlChar *type, xmlChar *bank, xmlChar *name, xmlChar *description, xmlNodePtr node){ +void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlChar* adress, xmlChar *offset, xmlChar *size, xmlChar *defvalue, xmlChar *rwmask, xmlChar *mode, xmlChar *type, xmlChar *bank, xmlChar *name, xmlChar *description){ char* ptr; @@ -153,8 +152,6 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlCha myregister->name=(char*)name; myregister->description=(char*)description; - /*should we include those xmlnodes?*/ - //myregister->xmlNode=node; } /** pcilib_xml_getnumberbanks @@ -172,6 +169,90 @@ int pcilib_xml_getnumberbanks(xmlXPathContextPtr doc){ return nodesetadress->nodeNr; /**< we then return the number of said nodes */ } +/** pcilib_xml_create_bank + * + * this function create a bank structure from the results of xml parsing + * @param[out] mybank the created bank. + * @param[in] adress the adress of the bank that will be created. + * @param[in] bar the bar of the bank that will be created. + * @param[in] size the size of the bank that will be created. + * @param[in] protocol the protocol of the bank that will be created. + * @param[in] read_addr the read adress for protocol of the bank that will be created. + * @param[in] write_addr the write adress for the protocol of the bank that will be created. + * @param[in] access the word size of the bank that will be created. + * @param[in] endianess the endianess of the bank that will be created. + * @param[in] format the format of the bank that will be created. + * @param[in] name the name of the bank that will be created. + * @param[in] description the description of the bank that will be created. + */ +void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol, xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description){ + + char* ptr; + + /** we recreate each sub property of banks' structure given the results of xml parsing + note : strtol is used here to get hexadecimal and decimal values from the xml file as well*/ + + if (strcmp((char*)adress,"bank 0")==0){ + mybank->addr=PCILIB_REGISTER_BANK0; + }else if (strcmp((char*)adress,"bank 1")==0){ + mybank->addr=PCILIB_REGISTER_BANK1; + }else if (strcmp((char*)adress,"bank 2")==0){ + mybank->addr=PCILIB_REGISTER_BANK2; + }else if (strcmp((char*)adress,"bank 3")==0){ + mybank->addr=PCILIB_REGISTER_BANK3; + }else if (strcmp((char*)adress,"DMA bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DMA; + }else if (strcmp((char*)adress,"DMAconf bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DMACONF; + }else if (strcmp((char*)adress,"dynamic bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC; + }else{ + mybank->addr=PCILIB_REGISTER_BANK_INVALID; + } + + if(strcmp((char*)bar,"0")==0){ + mybank->bar=PCILIB_BAR0; + }else if(strcmp((char*)bar,"1")==0){ + mybank->bar=PCILIB_BAR1; + }else if(strcmp((char*)bar,"no_bar")==0){ + mybank->bar=PCILIB_BAR_NOBAR; + }else{ + mybank->bar=PCILIB_BAR_INVALID; + } + + mybank->bar=(pcilib_bar_t)strtol((char*)bar,&ptr,0); + mybank->size=(size_t)strtol((char*)size,&ptr,0); + + if(strcmp((char*)protocol,"default")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT; + }else if(strcmp((char*)protocol,"0")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL0; + }else if(strcmp((char*)protocol,"dma")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DMA; + }else if(strcmp((char*)protocol,"dynamic")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DYNAMIC; + }else if (strcmp((char*)protocol,"software")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_SOFTWARE; + }else mybank->protocol=PCILIB_REGISTER_PROTOCOL_INVALID; + + mybank->read_addr=(uintptr_t)strtol((char*)read_addr,&ptr,0); + mybank->write_addr=(uintptr_t)strtol((char*)write_addr,&ptr,0); + mybank->access=(uint8_t)strtol((char*)access,&ptr,0); + + if(strcmp((char*)endianess,"little")==0){ + mybank->endianess=PCILIB_LITTLE_ENDIAN; + }else if(strcmp((char*)endianess,"big")==0){ + mybank->endianess=PCILIB_BIG_ENDIAN; + }else if(strcmp((char*)endianess,"host")==0){ + mybank->endianess=PCILIB_HOST_ENDIAN; + } + mybank->format=(char*)format; + mybank->raw_endianess=mybank->endianess; + + mybank->name=(char*)name; + mybank->description=(char*)description; +} + /** pcilib_xml_initialize_banks * * function to create the structures to store the banks from the AST @@ -179,7 +260,7 @@ int pcilib_xml_getnumberbanks(xmlXPathContextPtr doc){ * @param[in] doc the AST of the xml file. * @param[in,out] mybanks the structure containing the banks. */ -void pcilib_xml_initialize_banks(xmlDocPtr doc, pcilib_register_bank_description_t* mybanks){ +void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc, pcilib_register_bank_description_t* mybanks){ pcilib_register_bank_description_t mybank; xmlNodeSetPtr nodesetadress=NULL,nodesetbar=NULL,nodesetsize=NULL,nodesetprotocol=NULL,nodesetread_addr=NULL,nodesetwrite_addr=NULL,nodesetaccess=NULL,nodesetendianess=NULL,nodesetformat=NULL,nodesetname=NULL,nodesetdescription=NULL; @@ -239,7 +320,10 @@ void pcilib_xml_initialize_banks(xmlDocPtr doc, pcilib_register_bank_description temp=pcilib_xml_getsetproperty(context,BANK_DESCRIPTION_PATH); if(temp!=NULL)nodesetdescription=temp->nodesetval; - + + pci->banks_xml_nodes=calloc(nodesetadress->nodeNr,sizeof(xmlNodePtr)); + if(!(pci->banks_xml_nodes)) pcilib_warning("can't create bank xml nodes for pcilib_t struct"); + for(i=0;inodeNr;i++){ /** we then get each node from the structures above*/ adress=xmlNodeListGetString(doc,nodesetadress->nodeTab[i]->xmlChildrenNode, 1); @@ -255,99 +339,16 @@ void pcilib_xml_initialize_banks(xmlDocPtr doc, pcilib_register_bank_description description=xmlNodeListGetString(doc,nodesetdescription->nodeTab[i]->xmlChildrenNode, 1); mynode=nodesetadress->nodeTab[i]->parent; + /** the following function will create the given structure for banks*/ - pcilib_xml_create_bank(&mybank,adress,bar,size,protocol,read_addr,write_addr,access,endianess,format, name, description,mynode); + pcilib_xml_create_bank(&mybank,adress,bar,size,protocol,read_addr,write_addr,access,endianess,format, name, description); mybanks[i]=mybank; + pci->banks_xml_nodes[i]=mynode; + } } -/** pcilib_xml_create_bank - * - * this function create a bank structure from the results of xml parsing - * @param[out] mybank the created bank. - * @param[in] adress the adress of the bank that will be created. - * @param[in] bar the bar of the bank that will be created. - * @param[in] size the size of the bank that will be created. - * @param[in] protocol the protocol of the bank that will be created. - * @param[in] read_addr the read adress for protocol of the bank that will be created. - * @param[in] write_addr the write adress for the protocol of the bank that will be created. - * @param[in] access the word size of the bank that will be created. - * @param[in] endianess the endianess of the bank that will be created. - * @param[in] format the format of the bank that will be created. - * @param[in] name the name of the bank that will be created. - * @param[in] description the description of the bank that will be created. - * @param[in] node the xmlNodeptr referring to the bank_description node of the bank that will be created. - */ -void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol, xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description, xmlNodePtr node){ - - char* ptr; - - /** we recreate each sub property of banks' structure given the results of xml parsing - note : strtol is used here to get hexadecimal and decimal values from the xml file as well*/ - - if (strcmp((char*)adress,"bank 0")==0){ - mybank->addr=PCILIB_REGISTER_BANK0; - }else if (strcmp((char*)adress,"bank 1")==0){ - mybank->addr=PCILIB_REGISTER_BANK1; - }else if (strcmp((char*)adress,"bank 2")==0){ - mybank->addr=PCILIB_REGISTER_BANK2; - }else if (strcmp((char*)adress,"bank 3")==0){ - mybank->addr=PCILIB_REGISTER_BANK3; - }else if (strcmp((char*)adress,"DMA bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DMA; - }else if (strcmp((char*)adress,"DMAconf bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DMACONF; - }else if (strcmp((char*)adress,"dynamic bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC; - }else{ - mybank->addr=PCILIB_REGISTER_BANK_INVALID; - } - - if(strcmp((char*)bar,"0")==0){ - mybank->bar=PCILIB_BAR0; - }else if(strcmp((char*)bar,"1")==0){ - mybank->bar=PCILIB_BAR1; - }else if(strcmp((char*)bar,"no_bar")==0){ - mybank->bar=PCILIB_BAR_NOBAR; - }else{ - mybank->bar=PCILIB_BAR_INVALID; - } - - mybank->bar=(pcilib_bar_t)strtol((char*)bar,&ptr,0); - mybank->size=(size_t)strtol((char*)size,&ptr,0); - - if(strcmp((char*)protocol,"default")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT; - }else if(strcmp((char*)protocol,"0")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL0; - }else if(strcmp((char*)protocol,"dma")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DMA; - }else if(strcmp((char*)protocol,"dynamic")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DYNAMIC; - }else if (strcmp((char*)protocol,"software")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_SOFTWARE; - }else mybank->protocol=PCILIB_REGISTER_PROTOCOL_INVALID; - - mybank->read_addr=(uintptr_t)strtol((char*)read_addr,&ptr,0); - mybank->write_addr=(uintptr_t)strtol((char*)write_addr,&ptr,0); - mybank->access=(uint8_t)strtol((char*)access,&ptr,0); - - if(strcmp((char*)endianess,"little")==0){ - mybank->endianess=PCILIB_LITTLE_ENDIAN; - }else if(strcmp((char*)endianess,"big")==0){ - mybank->endianess=PCILIB_BIG_ENDIAN; - }else if(strcmp((char*)endianess,"host")==0){ - mybank->endianess=PCILIB_HOST_ENDIAN; - } - mybank->format=(char*)format; - mybank->raw_endianess=mybank->endianess; - - mybank->name=(char*)name; - mybank->description=(char*)description; - /* to include or not?*/ - //mybank->xmlNode=node; -} /** pcilib_xml_getnumberregisters @@ -380,7 +381,7 @@ int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc){ * @param[in] doc the xpath context of the xml file. * @param[in,out] registers in: initialized list out: the list of the created registers. */ -void pcilib_xml_initialize_registers(xmlDocPtr doc,pcilib_register_description_t *registers){ +void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc,pcilib_register_description_t *registers){ xmlNodeSetPtr nodesetadress=NULL,nodesetoffset=NULL,nodesetdefvalue=NULL,nodesetrwmask=NULL,nodesetsize=NULL,nodesetmode=NULL,nodesetname=NULL; xmlChar *adress=NULL,*offset=NULL,*defvalue=NULL,*rwmask=NULL,*size=NULL,*mode=NULL,*name=NULL,*bank=NULL,*type=NULL,*description=NULL; @@ -446,6 +447,9 @@ void pcilib_xml_initialize_registers(xmlDocPtr doc,pcilib_register_description_t pcilib_register_description_t myregister; int i,j; + + pci->registers_xml_nodes=calloc(nodesetadress->nodeNr+nodesetsuboffset->nodeNr,sizeof(xmlNodePtr)); + if(!(pci->registers_xml_nodes)) pcilib_warning("can't create registers xml nodes in pcilib_t struct"); for(i=0;inodeNr;i++){ /** get each sub property of each standard registers*/ @@ -467,8 +471,9 @@ void pcilib_xml_initialize_registers(xmlDocPtr doc,pcilib_register_description_t } mynode=nodesetadress->nodeTab[i]->parent; /**creation of a register with the given previous properties*/ - pcilib_xml_create_register(&myregister,adress,offset,size,defvalue,rwmask,mode, type, bank, name, description,mynode); + pcilib_xml_create_register(&myregister,adress,offset,size,defvalue,rwmask,mode, type, bank, name, description); registers[i]=myregister; + pci->registers_xml_nodes[i]=mynode; } j=i; @@ -497,8 +502,9 @@ void pcilib_xml_initialize_registers(xmlDocPtr doc,pcilib_register_description_t } mynode=nodesetsuboffset->nodeTab[i]->parent; /** creation of a bits register given the previous properties*/ - pcilib_xml_create_register(&myregister,subadress,suboffset,subsize,subdefvalue,subrwmask,submode, subtype, subbank, subname, subdescription,mynode); + pcilib_xml_create_register(&myregister,subadress,suboffset,subsize,subdefvalue,subrwmask,submode, subtype, subbank, subname, subdescription); registers[i+j]=myregister; + pci->registers_xml_nodes[i+j]=mynode; } } -- cgit v1.2.3 From 1d3cffac722081aa8b74821a832d8cc9c58715e6 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Thu, 27 Aug 2015 12:13:38 +0200 Subject: better public API and no more use of locals within pcilib_open --- pcilib/xml.c | 164 ++++++++++++++++++++++++++--------------------------------- 1 file changed, 73 insertions(+), 91 deletions(-) (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c index 762f805..68ac42a 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -19,6 +19,8 @@ #include #include #include "pci.h" +#include "bank.h" +#include "register.h" //#define VIEW_OK //#define UNIT_OK @@ -260,12 +262,14 @@ void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* * @param[in] doc the AST of the xml file. * @param[in,out] mybanks the structure containing the banks. */ -void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc, pcilib_register_bank_description_t* mybanks){ +void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc/*, pcilib_register_bank_description_t* mybanks*/){ pcilib_register_bank_description_t mybank; xmlNodeSetPtr nodesetadress=NULL,nodesetbar=NULL,nodesetsize=NULL,nodesetprotocol=NULL,nodesetread_addr=NULL,nodesetwrite_addr=NULL,nodesetaccess=NULL,nodesetendianess=NULL,nodesetformat=NULL,nodesetname=NULL,nodesetdescription=NULL; xmlChar *adress=NULL,*bar=NULL,*size=NULL,*protocol=NULL,*read_addr=NULL,*write_addr=NULL,*access=NULL,*endianess=NULL,*format=NULL,*name=NULL,*description=NULL; xmlNodePtr mynode; + int number_banks; + pcilib_register_bank_description_t* banks; xmlXPathContextPtr context; context=pcilib_xml_getcontext(doc); @@ -274,10 +278,14 @@ void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc, pcilib_register_b mynode=malloc(sizeof(xmlNode)); + number_banks=pcilib_xml_getnumberbanks(context); + if(number_banks) banks=calloc((number_banks),sizeof(pcilib_register_bank_description_t)); + else return; + xmlXPathObjectPtr temp; - /** we first get the nodes corresponding to the properties we want - * note: here a recursive algorithm may be more efficient but less evolutive*/ + /** we first get the nodes corresponding to the properties we want*/ +/* -----> certainly not necessary if we validate xml each time*/ temp=pcilib_xml_getsetproperty(context,BANK_ADDR_PATH); if(temp!=NULL) nodesetadress=temp->nodesetval; else pcilib_error("there is no adress for banks in the xml"); @@ -342,14 +350,62 @@ void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc, pcilib_register_b /** the following function will create the given structure for banks*/ pcilib_xml_create_bank(&mybank,adress,bar,size,protocol,read_addr,write_addr,access,endianess,format, name, description); - mybanks[i]=mybank; + banks[i]=mybank; pci->banks_xml_nodes[i]=mynode; } + + pcilib_add_register_banks(pci,number_banks,banks); +} + +/* + * next 3 functions are for the implementation of a merge sort algorithm + */ +void topdownmerge(pcilib_register_description_t *A, int start, int middle, int end, pcilib_register_description_t *B){ + int i0,i1,j; + i0= start; + i1=middle; + for(j=start;j=end || A[i0].addr<=A[i1].addr)){ + B[j]=A[i0]; + i0++; + } + else{ + B[j]=A[i1]; + i1++; + } + } } +void copyarray(pcilib_register_description_t *B, int start,int end, pcilib_register_description_t *A){ + int k; + for (k=start; knodeNr + nodesetsuboffset->nodeNr; /** certainly not necessary if we validate xml each time*/ + temp=pcilib_xml_getsetproperty(context,ADRESS_PATH); if(temp!=NULL)nodesetadress=temp->nodesetval; else pcilib_error("no adress for registers found in xml"); @@ -506,57 +571,12 @@ void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc,pcilib_registe registers[i+j]=myregister; pci->registers_xml_nodes[i+j]=mynode; } -} - - -/* - * next 3 functions are for the implementation of a merge sort algorithm - */ -void topdownmerge(pcilib_register_description_t *A, int start, int middle, int end, pcilib_register_description_t *B){ - int i0,i1,j; - i0= start; - i1=middle; - - for(j=start;j=end || A[i0].addr<=A[i1].addr)){ - B[j]=A[i0]; - i0++; - } - else{ - B[j]=A[i1]; - i1++; - } - } -} -void copyarray(pcilib_register_description_t *B, int start,int end, pcilib_register_description_t *A){ - int k; - for (k=start; k /** validation @@ -644,44 +664,6 @@ void pcilib_xml_read_config(char** xmlfile, int j){ memset(line,'\0',60); } } -/* to include or not?*/ -/** pcilib_xml_init_nodeset_register_ctx - * - * function to get all registers nodes in a structure and put it in registers context -* @param[in] ctx the register context running. - * -void pcilib_xml_init_nodeset_register_ctx(pcilib_register_context_t *ctx){ - char* xmlfile; - pcilib_xml_read_config(&xmlfile,3); - xmlDocPtr doc; - doc=pcilib_xml_getdoc(xmlfile); - xmlXPathContextPtr context; - context=pcilib_xml_getcontext(doc); - - xmlNodeSetPtr registers; - registers = pcilib_xml_getsetproperty(context, REGISTERS_PATH)->nodesetval; - ctx->registers_nodes=registers; -} - -** pcilib_xml_init_nodeset_bank_ctx - * - *function to get all banks nodes in a structure and put it in banks context -* @param[in] ctx the bank context running. - * -void pcilib_xml_init_nodeset_bank_ctx(pcilib_register_bank_context_t *ctx){ - char* xmlfile; - pcilib_xml_read_config(&xmlfile,3); - xmlDocPtr doc; - doc=pcilib_xml_getdoc(xmlfile); - xmlXPathContextPtr context; - context=pcilib_xml_getcontext(doc); - - xmlNodeSetPtr banks; - banks = pcilib_xml_getsetproperty(context, BANKS_PATH)->nodesetval; - ctx->banks_nodes=banks; - -} -*/ #ifdef VIEW_OK /* pcilib_xml_getnumberformulaviews -- cgit v1.2.3 From d2ec5ac52105c526390d8a31e52a7a2c260dde80 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Thu, 27 Aug 2015 16:19:53 +0200 Subject: xml files get by model and remove of validation mode --- pcilib/xml.c | 224 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 124 insertions(+), 100 deletions(-) (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c index 68ac42a..203b147 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -10,17 +10,18 @@ In case the performance is not good enough, please consider the following : no more configuration file indicating where the files required are, hard code of formulas, and go to complete non evolutive code : get 1 access to xml file and context, and then make recursive descent to get all you need(investigation of libxml2 source code would be so needed to prove it's better to go recursive than just xpath). */ - +#define _XOPEN_SOURCE 700 #include "xml.h" #include "error.h" #include #include #include #include -#include +//#include #include "pci.h" #include "bank.h" #include "register.h" +#include //#define VIEW_OK //#define UNIT_OK @@ -79,6 +80,83 @@ xmlXPathContextPtr pcilib_xml_getcontext(xmlDocPtr doc){ } +/** validation + * + * function to validate the xml file against the xsd, so that it does not require extern software + */ +void validation(char* xml_filename, char* xsd_filename) +{ +xmlDocPtr doc; +xmlSchemaPtr schema = NULL; +xmlSchemaParserCtxtPtr ctxt; +int ret=1; + +ctxt = xmlSchemaNewParserCtxt(xsd_filename); +schema = xmlSchemaParse(ctxt); +xmlSchemaFreeParserCtxt(ctxt); + +doc = xmlReadFile(xml_filename, NULL, 0); + +if (doc == NULL) +{ + pcilib_error("Could not parse xml document "); +} +else +{ +xmlSchemaValidCtxtPtr ctxt; +/** validation here*/ +ctxt = xmlSchemaNewValidCtxt(schema); +ret = xmlSchemaValidateDoc(ctxt, doc); +xmlSchemaFreeValidCtxt(ctxt); +xmlFreeDoc(doc); +} + +//! free the resource +if(schema != NULL) +xmlSchemaFree(schema); +xmlSchemaCleanupTypes(); + +if(ret!=0) pcilib_error("xml file \"%s\" does not validate against the schema",xml_filename); + +} + +void pcilib_init_xml(xmlDocPtr* docs){ + char *path,*command,*command_xsd, *line, *line_xsd; + FILE *in, *in2; + int i=1; + + path=malloc(sizeof(char*)); + command=malloc(sizeof(char*)); + command_xsd=malloc(sizeof(char*)); + line=malloc(sizeof(char*)); + line_xsd=malloc(sizeof(char*)); + docs=malloc(sizeof(xmlDocPtr)); + + path=getenv("PCILIB_MODEL_DIR"); + if((strcmp(path,"(null)"))==0) pcilib_error("can't find environment variable for xml files"); + + sprintf(command,"find %s -name *.xml -print",path); + sprintf(command_xsd,"find %s -name *.xsd -print",path); + + if(!(in=popen(command,"r"))) pcilib_error("fail popen xml"); + if(!((in2=popen(command_xsd,"r")))) pcilib_error("fail popen xsd"); + + while(fgets(line_xsd,sizeof(line_xsd),in2)!=NULL) { + if((strstr(line_xsd,"units"))!=NULL) break; + } + if(line_xsd==NULL) pcilib_error("no xsd file found"); + +while((fgets(line,sizeof(line),in))!=NULL) { + validation(line,line_xsd); + docs=(xmlDocPtr*) realloc(docs,i*sizeof(xmlDocPtr)); + docs[i-1]=pcilib_xml_getdoc(line); + i++; + } + + docs=(xmlDocPtr*) realloc(docs,i*sizeof(xmlDocPtr)); + docs[i]=NULL; +} + /** pcilib_xml_create_register. * this function create a register structure from the results of xml parsing. * @param[out] myregister the register we want to create @@ -262,7 +340,7 @@ void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* * @param[in] doc the AST of the xml file. * @param[in,out] mybanks the structure containing the banks. */ -void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc/*, pcilib_register_bank_description_t* mybanks*/){ +void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr* docs){ pcilib_register_bank_description_t mybank; xmlNodeSetPtr nodesetadress=NULL,nodesetbar=NULL,nodesetsize=NULL,nodesetprotocol=NULL,nodesetread_addr=NULL,nodesetwrite_addr=NULL,nodesetaccess=NULL,nodesetendianess=NULL,nodesetformat=NULL,nodesetname=NULL,nodesetdescription=NULL; @@ -270,20 +348,17 @@ void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc/*, pcilib_register xmlNodePtr mynode; int number_banks; pcilib_register_bank_description_t* banks; - xmlXPathContextPtr context; - context=pcilib_xml_getcontext(doc); - - int i; - + int i,p; + xmlXPathObjectPtr temp; mynode=malloc(sizeof(xmlNode)); - - number_banks=pcilib_xml_getnumberbanks(context); + p=0; + while(docs[p]!=NULL){ + context=pcilib_xml_getcontext(docs[p]); + number_banks=pcilib_xml_getnumberbanks(context); if(number_banks) banks=calloc((number_banks),sizeof(pcilib_register_bank_description_t)); else return; - xmlXPathObjectPtr temp; - /** we first get the nodes corresponding to the properties we want*/ /* -----> certainly not necessary if we validate xml each time*/ temp=pcilib_xml_getsetproperty(context,BANK_ADDR_PATH); @@ -334,17 +409,17 @@ void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc/*, pcilib_register for(i=0;inodeNr;i++){ /** we then get each node from the structures above*/ - adress=xmlNodeListGetString(doc,nodesetadress->nodeTab[i]->xmlChildrenNode, 1); - bar=xmlNodeListGetString(doc,nodesetbar->nodeTab[i]->xmlChildrenNode, 1); - size=xmlNodeListGetString(doc,nodesetsize->nodeTab[i]->xmlChildrenNode, 1); - protocol=xmlNodeListGetString(doc,nodesetprotocol->nodeTab[i]->xmlChildrenNode, 1); - read_addr=xmlNodeListGetString(doc,nodesetread_addr->nodeTab[i]->xmlChildrenNode, 1); - write_addr=xmlNodeListGetString(doc,nodesetwrite_addr->nodeTab[i]->xmlChildrenNode, 1); - access=xmlNodeListGetString(doc,nodesetaccess->nodeTab[i]->xmlChildrenNode, 1); - endianess=xmlNodeListGetString(doc,nodesetendianess->nodeTab[i]->xmlChildrenNode, 1); - format=xmlNodeListGetString(doc,nodesetformat->nodeTab[i]->xmlChildrenNode, 1); - name=xmlNodeListGetString(doc,nodesetname->nodeTab[i]->xmlChildrenNode, 1); - description=xmlNodeListGetString(doc,nodesetdescription->nodeTab[i]->xmlChildrenNode, 1); + adress=xmlNodeListGetString(docs[p],nodesetadress->nodeTab[i]->xmlChildrenNode, 1); + bar=xmlNodeListGetString(docs[p],nodesetbar->nodeTab[i]->xmlChildrenNode, 1); + size=xmlNodeListGetString(docs[p],nodesetsize->nodeTab[i]->xmlChildrenNode, 1); + protocol=xmlNodeListGetString(docs[p],nodesetprotocol->nodeTab[i]->xmlChildrenNode, 1); + read_addr=xmlNodeListGetString(docs[p],nodesetread_addr->nodeTab[i]->xmlChildrenNode, 1); + write_addr=xmlNodeListGetString(docs[p],nodesetwrite_addr->nodeTab[i]->xmlChildrenNode, 1); + access=xmlNodeListGetString(docs[p],nodesetaccess->nodeTab[i]->xmlChildrenNode, 1); + endianess=xmlNodeListGetString(docs[p],nodesetendianess->nodeTab[i]->xmlChildrenNode, 1); + format=xmlNodeListGetString(docs[p],nodesetformat->nodeTab[i]->xmlChildrenNode, 1); + name=xmlNodeListGetString(docs[p],nodesetname->nodeTab[i]->xmlChildrenNode, 1); + description=xmlNodeListGetString(docs[p],nodesetdescription->nodeTab[i]->xmlChildrenNode, 1); mynode=nodesetadress->nodeTab[i]->parent; @@ -356,6 +431,8 @@ void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc/*, pcilib_register } pcilib_add_register_banks(pci,number_banks,banks); + p++; + } } /* @@ -438,19 +515,18 @@ int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc){ * @param[in] doc the xpath context of the xml file. * @param[in,out] registers in: initialized list out: the list of the created registers. */ -void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc/*,pcilib_register_description_t *registers*/){ +void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr* docs){ xmlNodeSetPtr nodesetadress=NULL,nodesetoffset=NULL,nodesetdefvalue=NULL,nodesetrwmask=NULL,nodesetsize=NULL,nodesetmode=NULL,nodesetname=NULL; xmlChar *adress=NULL,*offset=NULL,*defvalue=NULL,*rwmask=NULL,*size=NULL,*mode=NULL,*name=NULL,*bank=NULL,*type=NULL,*description=NULL; xmlNodePtr mynode; xmlNodePtr tempnode; xmlXPathContextPtr context; - int number_registers; +int number_registers, count=0; pcilib_register_description_t *registers=NULL; - context=pcilib_xml_getcontext(doc); - mynode=malloc(sizeof(xmlNode)); - +while(docs[count]!=NULL){ + context=pcilib_xml_getcontext(docs[count]); number_registers=pcilib_xml_getnumberregisters(context); if(number_registers) registers=calloc(number_registers,sizeof(pcilib_register_description_t)); else return; @@ -518,19 +594,19 @@ void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc/*,pcilib_regis for(i=0;inodeNr;i++){ /** get each sub property of each standard registers*/ - adress=xmlNodeListGetString(doc,nodesetadress->nodeTab[i]->xmlChildrenNode, 1); + adress=xmlNodeListGetString(docs[count],nodesetadress->nodeTab[i]->xmlChildrenNode, 1); tempnode=xmlFirstElementChild(xmlFirstElementChild(nodesetadress->nodeTab[i]->parent->parent->parent)); - if(strcmp("adress",(char*)tempnode->name)==0) bank=xmlNodeListGetString(doc,tempnode->xmlChildrenNode,1); + if(strcmp("adress",(char*)tempnode->name)==0) bank=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode,1); else pcilib_error("the xml file is malformed"); - offset=xmlNodeListGetString(doc,nodesetoffset->nodeTab[i]->xmlChildrenNode, 1); - size=xmlNodeListGetString(doc,nodesetsize->nodeTab[i]->xmlChildrenNode, 1); - defvalue=xmlNodeListGetString(doc,nodesetdefvalue->nodeTab[i]->xmlChildrenNode, 1); - rwmask=xmlNodeListGetString(doc,nodesetrwmask->nodeTab[i]->xmlChildrenNode, 1); - mode=xmlNodeListGetString(doc,nodesetmode->nodeTab[i]->xmlChildrenNode, 1); - name=xmlNodeListGetString(doc,nodesetname->nodeTab[i]->xmlChildrenNode, 1); + offset=xmlNodeListGetString(docs[count],nodesetoffset->nodeTab[i]->xmlChildrenNode, 1); + size=xmlNodeListGetString(docs[count],nodesetsize->nodeTab[i]->xmlChildrenNode, 1); + defvalue=xmlNodeListGetString(docs[count],nodesetdefvalue->nodeTab[i]->xmlChildrenNode, 1); + rwmask=xmlNodeListGetString(docs[count],nodesetrwmask->nodeTab[i]->xmlChildrenNode, 1); + mode=xmlNodeListGetString(docs[count],nodesetmode->nodeTab[i]->xmlChildrenNode, 1); + name=xmlNodeListGetString(docs[count],nodesetname->nodeTab[i]->xmlChildrenNode, 1); type=(xmlChar*)"standard"; if(nodesetname->nodeTab[i]->next->next!= NULL && strcmp((char*)nodesetname->nodeTab[i]->next->next->name,"description")==0){ - description=xmlNodeListGetString(doc,nodesetname->nodeTab[i]->next->next->xmlChildrenNode,1); + description=xmlNodeListGetString(docs[count],nodesetname->nodeTab[i]->next->next->xmlChildrenNode,1); }else{ description=(xmlChar*)""; } @@ -546,22 +622,22 @@ void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc/*,pcilib_regis for(i=0;inodeNr;i++){ /** we get there each subproperty of each bits register*/ tempnode=xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent); - if(strcmp((char*)tempnode->name,"adress")==0)subadress=xmlNodeListGetString(doc,tempnode->xmlChildrenNode, 1); + if(strcmp((char*)tempnode->name,"adress")==0)subadress=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode, 1); else pcilib_error("xml file is malformed"); tempnode= xmlFirstElementChild(xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent->parent->parent)); - if(strcmp((char*)tempnode->name,"adress")==0) subbank=xmlNodeListGetString(doc,tempnode->xmlChildrenNode,1); + if(strcmp((char*)tempnode->name,"adress")==0) subbank=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode,1); else pcilib_error("xml file is malformed"); - suboffset=xmlNodeListGetString(doc,nodesetsuboffset->nodeTab[i]->xmlChildrenNode, 1); - subsize=xmlNodeListGetString(doc,nodesetsubsize->nodeTab[i]->xmlChildrenNode, 1); + suboffset=xmlNodeListGetString(docs[count],nodesetsuboffset->nodeTab[i]->xmlChildrenNode, 1); + subsize=xmlNodeListGetString(docs[count],nodesetsubsize->nodeTab[i]->xmlChildrenNode, 1); tempnode=xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent)->next->next->next->next->next->next; - if(strcmp((char*)tempnode->name,"default")==0)subdefvalue=xmlNodeListGetString(doc,tempnode->xmlChildrenNode, 1); + if(strcmp((char*)tempnode->name,"default")==0)subdefvalue=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode, 1); else pcilib_error("xml file is malformed"); - subrwmask=xmlNodeListGetString(doc,nodesetsuboffset->nodeTab[i]->parent->parent->prev->prev->prev->prev->prev->prev->xmlChildrenNode, 1); - submode=xmlNodeListGetString(doc,nodesetsubmode->nodeTab[i]->xmlChildrenNode, 1); - subname=xmlNodeListGetString(doc,nodesetsubname->nodeTab[i]->xmlChildrenNode, 1); + subrwmask=xmlNodeListGetString(docs[count],nodesetsuboffset->nodeTab[i]->parent->parent->prev->prev->prev->prev->prev->prev->xmlChildrenNode, 1); + submode=xmlNodeListGetString(docs[count],nodesetsubmode->nodeTab[i]->xmlChildrenNode, 1); + subname=xmlNodeListGetString(docs[count],nodesetsubname->nodeTab[i]->xmlChildrenNode, 1); subtype=(xmlChar*)"bits"; if(nodesetsubname->nodeTab[i]->next->next!= NULL && strcmp((char*)nodesetsubname->nodeTab[i]->next->next->name,"sub_description")==0){ - subdescription=xmlNodeListGetString(doc,nodesetsubname->nodeTab[i]->next->next->xmlChildrenNode,1); + subdescription=xmlNodeListGetString(docs[count],nodesetsubname->nodeTab[i]->next->next->xmlChildrenNode,1); }else{ subdescription=(xmlChar*)""; } @@ -574,64 +650,12 @@ void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc/*,pcilib_regis pcilib_xml_arrange_registers(registers,number_registers); pcilib_add_registers(pci,number_registers,registers); + count++; + } } -#include -/** validation - * - * function to validate the xml file against the xsd, so that it does not require extern software - */ -void validation() -{ -xmlDocPtr doc; -xmlSchemaPtr schema = NULL; -xmlSchemaParserCtxtPtr ctxt; - -char *XMLFileName; - pcilib_xml_read_config(&XMLFileName,3); -char *XSDFileName; - pcilib_xml_read_config(&XSDFileName,12); -int ret=1; - -ctxt = xmlSchemaNewParserCtxt(XSDFileName); - -schema = xmlSchemaParse(ctxt); -xmlSchemaFreeParserCtxt(ctxt); - -doc = xmlReadFile(XMLFileName, NULL, 0); - -if (doc == NULL) -{ - pcilib_error("Could not parse xml document "); -} -else -{ -xmlSchemaValidCtxtPtr ctxt; -/** validation here*/ -ctxt = xmlSchemaNewValidCtxt(schema); -ret = xmlSchemaValidateDoc(ctxt, doc); -xmlSchemaFreeValidCtxt(ctxt); -xmlFreeDoc(doc); -} - -//! free the resource -if(schema != NULL) -xmlSchemaFree(schema); - -xmlSchemaCleanupTypes(); -/** print results */ -if (ret == 0) -{ - printf("xml file validates\n"); -} -else -{ - printf("xml file does not validate against the schema\n"); -} - -} /** pcilib_xml_read_config * -- cgit v1.2.3 From 04b33df0407e03175a56096cb7ff79a56bea9e88 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Thu, 27 Aug 2015 16:26:48 +0200 Subject: some cleaning --- pcilib/xml.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c index 203b147..482ab25 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -111,7 +111,6 @@ xmlSchemaFreeValidCtxt(ctxt); xmlFreeDoc(doc); } -//! free the resource if(schema != NULL) xmlSchemaFree(schema); xmlSchemaCleanupTypes(); @@ -654,41 +653,6 @@ while(docs[count]!=NULL){ } } - - - -/** pcilib_xml_read_config - * - * function to get the config we want at line j, in order to be able to have a configuration file with pwd to files we want -* @param[in,out] xmlfile the string representating a pwd to a file we want to access in:uninitilized out: the pwd. -* @param[in] i the line at which the function should read the file to get the pwd. - */ -void pcilib_xml_read_config(char** xmlfile, int j){ - FILE *fp; - - fp=fopen("config.txt","r"); - char line[60]; - memset(line,'\0',60); - int i=0,k; - char *temp1; - if(fp==NULL) pcilib_error("can't find the configuration file: it must be near the executable"); - - while(fgets(line,60,fp)!=NULL){ - if(i==j) { - k=0; - temp1=calloc((strlen(line)),sizeof(char)); - while(line[k]!='\n'){ - temp1[k]=line[k]; - k++; - } - temp1[k]='\0'; - *xmlfile=temp1; - } - i++; - memset(line,'\0',60); - } -} - #ifdef VIEW_OK /* pcilib_xml_getnumberformulaviews * -- cgit v1.2.3 From a1e8741ac0d77ab721a413a283127352d80fb944 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Thu, 27 Aug 2015 16:42:27 +0200 Subject: some adressing regarding possible memory leaks --- pcilib/xml.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c index 482ab25..ad76dcc 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -154,6 +154,15 @@ while((fgets(line,sizeof(line),in))!=NULL) { docs=(xmlDocPtr*) realloc(docs,i*sizeof(xmlDocPtr)); docs[i]=NULL; + free(path); + free(command); + free(command_xsd); + free(line); + free(line_xsd); + free(in); + free(in2); + fclose(in); + fclose(in2); } /** pcilib_xml_create_register. @@ -481,6 +490,7 @@ void pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int s pcilib_register_description_t* temp; temp=malloc(size*sizeof(pcilib_register_description_t)); topdownsplitmerge(registers,0,size,temp); + free(temp); } /** pcilib_xml_getnumberregisters @@ -724,13 +734,13 @@ viewnumber=0; xmlXPathObjectPtr temp,temp2; char* path; - path=malloc((strlen((char*)name)+51)*sizeof(char)); + path=malloc(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)); + path2=malloc(sizeof(char*)); sprintf(path2, VIEW_BITS_REGISTER_PLUS,(char*)name); temp2= pcilib_xml_getsetproperty(context,(xmlChar*)path2); if(temp2!=NULL) nodesetviewregisterbit= temp2->nodesetval; @@ -836,6 +846,9 @@ viewnumber=0; } viewnumber++; } + + free(path); + free(path2); } /* pcilib_xml_initialize_viewsenum @@ -873,13 +886,13 @@ void pcilib_xml_initialize_viewsenum(xmlDocPtr doc, pcilib_view_enum_ptr_t* myvi registernumber=0; char* path; - path=malloc((strlen((char*)name)+51)*sizeof(char)); + path=malloc(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)); + path2=malloc(sizeof(char*)); sprintf(path2, VIEW_BITS_REGISTER_PLUS,(char*)name); temp2= pcilib_xml_getsetproperty(context,(xmlChar*)path2); if(temp2!=NULL) viewsetregister4= temp2->nodesetval; @@ -973,6 +986,9 @@ void pcilib_xml_initialize_viewsenum(xmlDocPtr doc, pcilib_view_enum_ptr_t* myvi viewnumber++; } + + free(path); + free(path2); } #endif @@ -996,7 +1012,7 @@ void pclib_xml_initialize_units(xmlDocPtr doc, pcilib_units_ptr_t* unitsptr){ 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)); + path=malloc(sizeof(char*)); sprintf(path, TRANSFORM_UNIT_PATH, unitsptr->list_unit[i].name); temp=pcilib_xml_getsetproperty(context, path); if(temp!=NULL){ @@ -1008,6 +1024,6 @@ void pclib_xml_initialize_units(xmlDocPtr doc, pcilib_units_ptr_t* unitsptr){ } } } - + free(path); } #endif -- cgit v1.2.3 From 57149189cb4e15ed38ee34d44450390955e56697 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Fri, 4 Sep 2015 12:52:07 +0200 Subject: almost finished regarding suren remarks --- pcilib/xml.c | 1172 ++++++++++++++++++---------------------------------------- 1 file changed, 356 insertions(+), 816 deletions(-) (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c index ad76dcc..d4c84be 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -17,20 +17,20 @@ #include #include #include -//#include #include "pci.h" #include "bank.h" #include "register.h" #include -//#define VIEW_OK -//#define UNIT_OK -/** - * pcilib_xml_getdoc +#include +#include + +/** pcilib_xml_getdoc * this function takes a string and will create an abtract syntax tree from the xml file represented by the string * @param[in] filename the the name of the xml file containing registers and banks */ -xmlDocPtr pcilib_xml_getdoc(char* filename){ +static xmlDocPtr +pcilib_xml_getdoc(char* filename){ xmlDocPtr doc; doc=xmlParseFile(filename); /**nodesetval)){ xmlXPathFreeObject(result); -// pcilib_warning("warning : no results found for: %s",xpath); return NULL; } @@ -69,7 +67,8 @@ xmlXPathObjectPtr pcilib_xml_getsetproperty(xmlXPathContextPtr doc, xmlChar *xpa * this function create a context in an AST (ie initialize XPAth for the AST). * @param[in] doc the AST of the xml file. */ -xmlXPathContextPtr pcilib_xml_getcontext(xmlDocPtr doc){ +static xmlXPathContextPtr +pcilib_xml_getcontext(xmlDocPtr doc){ xmlXPathContextPtr context; context= xmlXPathNewContext(doc); /**addr=(pcilib_register_addr_t)strtol((char*)adress,&ptr,0); - myregister->offset=(pcilib_register_size_t)strtol((char*)offset,&ptr,0); - myregister->bits=(pcilib_register_size_t)strtol((char*)size,&ptr,0); - myregister->defvalue=(pcilib_register_value_t)strtol((char*)defvalue,&ptr,0); - - if(strcmp((char*)rwmask,"all bits")==0){ - myregister->rwmask=PCILIB_REGISTER_ALL_BITS; - }else if(strcmp((char*)rwmask,"0")==0){ - myregister->rwmask=0; - }else{ - myregister->rwmask=(pcilib_register_value_t)strtol((char*)rwmask,&ptr,0); - } - - if(strcmp((char*)mode,"R")==0){ - myregister->mode=PCILIB_REGISTER_R; - }else if(strcmp((char*)mode,"W")==0){ - myregister->mode=PCILIB_REGISTER_W; - }else if(strcmp((char*)mode,"RW")==0){ - myregister->mode=PCILIB_REGISTER_RW; - }else if(strcmp((char*)mode,"W")==0){ - myregister->mode=PCILIB_REGISTER_W; - }else if(strcmp((char*)mode,"RW1C")==0){ - myregister->mode=PCILIB_REGISTER_RW1C; - }else if(strcmp((char*)mode,"W1C")==0){ - myregister->mode=PCILIB_REGISTER_W1C; - } - - if(strcmp((char*)type,"standard")==0){ - myregister->type=PCILIB_REGISTER_STANDARD; - }else if(strcmp((char*)type,"bits")==0){ - myregister->type=PCILIB_REGISTER_BITS; - }else if(strcmp((char*)type,"fifo")==0){ - myregister->type=PCILIB_REGISTER_FIFO; - } - - if(strcmp((char*)bank,"bank 0")==0){ - myregister->bank=PCILIB_REGISTER_BANK0; - }else if(strcmp((char*)bank,"bank 1")==0){ - myregister->bank=PCILIB_REGISTER_BANK1; - }else if(strcmp((char*)bank,"bank 2")==0){ - myregister->bank=PCILIB_REGISTER_BANK2; - }else if(strcmp((char*)bank,"bank 3")==0){ - myregister->bank=PCILIB_REGISTER_BANK3; - }else if(strcmp((char*)bank,"DMA bank")==0){ - myregister->bank=PCILIB_REGISTER_BANK_DMA; - }else if (strcmp((char*)bank,"dynamic bank")==0){ - myregister->addr=PCILIB_REGISTER_BANK_DYNAMIC; - }else{ - myregister->bank=PCILIB_REGISTER_BANK_INVALID; - } - - myregister->name=(char*)name; - myregister->description=(char*)description; -} - -/** pcilib_xml_getnumberbanks - * - * get the number of banks nodes in the AST, used to have some malloc in pci - * @param[in] doc the Xpath context of the xml file. - * @return the number of banks. - */ -int pcilib_xml_getnumberbanks(xmlXPathContextPtr doc){ - xmlNodeSetPtr nodesetadress=NULL; - xmlXPathObjectPtr temp; - temp=pcilib_xml_getsetproperty(doc,BANK_ADDR_PATH); /**< we first get a structure containing all the banks nodes*/ - if(temp!=NULL) nodesetadress=temp->nodesetval; - else pcilib_error("no bank in the xml file"); - return nodesetadress->nodeNr; /**< we then return the number of said nodes */ -} /** pcilib_xml_create_bank * - * this function create a bank structure from the results of xml parsing + * this function create a bank structure from a xml bank node * @param[out] mybank the created bank. - * @param[in] adress the adress of the bank that will be created. - * @param[in] bar the bar of the bank that will be created. - * @param[in] size the size of the bank that will be created. - * @param[in] protocol the protocol of the bank that will be created. - * @param[in] read_addr the read adress for protocol of the bank that will be created. - * @param[in] write_addr the write adress for the protocol of the bank that will be created. - * @param[in] access the word size of the bank that will be created. - * @param[in] endianess the endianess of the bank that will be created. - * @param[in] format the format of the bank that will be created. - * @param[in] name the name of the bank that will be created. - * @param[in] description the description of the bank that will be created. + * @param[in] my node the xml node used to create the bank + * @param[in] doc the AST of the xml file, used for used lixbml functions */ -void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol, xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description){ +static void +pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc){ - char* ptr; + char* ptr; + xmlNodePtr cur; + xmlChar *value; - /** we recreate each sub property of banks' structure given the results of xml parsing - note : strtol is used here to get hexadecimal and decimal values from the xml file as well*/ + cur=mynode->children; /** we place ourselves in the childrens of the bank node*/ - if (strcmp((char*)adress,"bank 0")==0){ - mybank->addr=PCILIB_REGISTER_BANK0; - }else if (strcmp((char*)adress,"bank 1")==0){ - mybank->addr=PCILIB_REGISTER_BANK1; - }else if (strcmp((char*)adress,"bank 2")==0){ - mybank->addr=PCILIB_REGISTER_BANK2; - }else if (strcmp((char*)adress,"bank 3")==0){ - mybank->addr=PCILIB_REGISTER_BANK3; - }else if (strcmp((char*)adress,"DMA bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DMA; - }else if (strcmp((char*)adress,"DMAconf bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DMACONF; - }else if (strcmp((char*)adress,"dynamic bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC; - }else{ - mybank->addr=PCILIB_REGISTER_BANK_INVALID; - } - - if(strcmp((char*)bar,"0")==0){ - mybank->bar=PCILIB_BAR0; - }else if(strcmp((char*)bar,"1")==0){ - mybank->bar=PCILIB_BAR1; - }else if(strcmp((char*)bar,"no_bar")==0){ - mybank->bar=PCILIB_BAR_NOBAR; - }else{ - mybank->bar=PCILIB_BAR_INVALID; - } - - mybank->bar=(pcilib_bar_t)strtol((char*)bar,&ptr,0); - mybank->size=(size_t)strtol((char*)size,&ptr,0); - - if(strcmp((char*)protocol,"default")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT; - }else if(strcmp((char*)protocol,"0")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL0; - }else if(strcmp((char*)protocol,"dma")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DMA; - }else if(strcmp((char*)protocol,"dynamic")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DYNAMIC; - }else if (strcmp((char*)protocol,"software")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_SOFTWARE; - }else mybank->protocol=PCILIB_REGISTER_PROTOCOL_INVALID; - - mybank->read_addr=(uintptr_t)strtol((char*)read_addr,&ptr,0); - mybank->write_addr=(uintptr_t)strtol((char*)write_addr,&ptr,0); - mybank->access=(uint8_t)strtol((char*)access,&ptr,0); - - if(strcmp((char*)endianess,"little")==0){ - mybank->endianess=PCILIB_LITTLE_ENDIAN; - }else if(strcmp((char*)endianess,"big")==0){ - mybank->endianess=PCILIB_BIG_ENDIAN; - }else if(strcmp((char*)endianess,"host")==0){ - mybank->endianess=PCILIB_HOST_ENDIAN; - } - mybank->format=(char*)format; - mybank->raw_endianess=mybank->endianess; + /** we iterate through all children, representing bank properties, to fill the structure*/ + while(cur!=NULL){ + /** we get each time the name of the node, corresponding to one property, and the value of the node*/ + value=xmlNodeListGetString(doc,cur->children,1); + + if(strcmp((char*)cur->name,"adress")==0){ + if (strcmp((char*)value,"bank 0")==0){ + mybank->addr=PCILIB_REGISTER_BANK0; + }else if (strcmp((char*)value,"bank 1")==0){ + mybank->addr=PCILIB_REGISTER_BANK1; + }else if (strcmp((char*)value,"bank 2")==0){ + mybank->addr=PCILIB_REGISTER_BANK2; + }else if (strcmp((char*)value,"bank 3")==0){ + mybank->addr=PCILIB_REGISTER_BANK3; + }else if (strcmp((char*)value,"DMA bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DMA; + }else if (strcmp((char*)value,"DMAconf bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DMACONF; + }else if (strcmp((char*)value,"dynamic bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC; + }else{ + mybank->addr=PCILIB_REGISTER_BANK_INVALID; + } + + }else if(strcmp((char*)cur->name,"bar")==0){ + if(strcmp((char*)value,"0")==0){ + mybank->bar=PCILIB_BAR0; + }else if(strcmp((char*)value,"1")==0){ + mybank->bar=PCILIB_BAR1; + }else if(strcmp((char*)value,"no_bar")==0){ + mybank->bar=PCILIB_BAR_NOBAR; + }else{ + mybank->bar=PCILIB_BAR_INVALID; + } + mybank->bar=(pcilib_bar_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"size")==0){ + mybank->size=(size_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"protocol")==0){ + if(strcmp((char*)value,"default")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT; + }else if(strcmp((char*)value,"0")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL0; + }else if(strcmp((char*)value,"dma")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DMA; + }else if(strcmp((char*)value,"dynamic")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DYNAMIC; + }else if (strcmp((char*)value,"software")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_SOFTWARE; + }else mybank->protocol=PCILIB_REGISTER_PROTOCOL_INVALID; + + }else if(strcmp((char*)cur->name,"read_adress")==0){ + mybank->read_addr=(uintptr_t)strtol((char*)value,&ptr,0); - mybank->name=(char*)name; - mybank->description=(char*)description; -} + }else if(strcmp((char*)cur->name,"write_adress")==0){ + mybank->write_addr=(uintptr_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"word_size")==0){ + mybank->access=(uint8_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"endianess")==0){ + if(strcmp((char*)value,"little")==0){ + mybank->endianess=PCILIB_LITTLE_ENDIAN; + }else if(strcmp((char*)value,"big")==0){ + mybank->endianess=PCILIB_BIG_ENDIAN; + }else if(strcmp((char*)value,"host")==0){ + mybank->endianess=PCILIB_HOST_ENDIAN; + } + mybank->raw_endianess=mybank->endianess; + + }else if(strcmp((char*)cur->name,"format")==0){ + mybank->format=(char*)value; + + }else if(strcmp((char*)cur->name,"name")==0){ + mybank->name=(char*)value; + + }else if(strcmp((char*)cur->name,"description")==0){ + mybank->description=(char*)value; + } + + cur=cur->next; + } +} + + /** pcilib_xml_initialize_banks * * function to create the structures to store the banks from the AST - * @see pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol,xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description, xmlNodePtr node). + * @see pcilib_xml_create_bank( * @param[in] doc the AST of the xml file. - * @param[in,out] mybanks the structure containing the banks. + * @param[in] pci the pcilib_t running, which will be filled */ -void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr* docs){ +static void +pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ pcilib_register_bank_description_t mybank; - xmlNodeSetPtr nodesetadress=NULL,nodesetbar=NULL,nodesetsize=NULL,nodesetprotocol=NULL,nodesetread_addr=NULL,nodesetwrite_addr=NULL,nodesetaccess=NULL,nodesetendianess=NULL,nodesetformat=NULL,nodesetname=NULL,nodesetdescription=NULL; - xmlChar *adress=NULL,*bar=NULL,*size=NULL,*protocol=NULL,*read_addr=NULL,*write_addr=NULL,*access=NULL,*endianess=NULL,*format=NULL,*name=NULL,*description=NULL; + xmlNodeSetPtr nodesetadress=NULL; xmlNodePtr mynode; - int number_banks; pcilib_register_bank_description_t* banks; xmlXPathContextPtr context; - int i,p; - xmlXPathObjectPtr temp; - mynode=malloc(sizeof(xmlNode)); - p=0; - while(docs[p]!=NULL){ - context=pcilib_xml_getcontext(docs[p]); - number_banks=pcilib_xml_getnumberbanks(context); - if(number_banks) banks=calloc((number_banks),sizeof(pcilib_register_bank_description_t)); - else return; + int i; - /** we first get the nodes corresponding to the properties we want*/ -/* -----> certainly not necessary if we validate xml each time*/ - temp=pcilib_xml_getsetproperty(context,BANK_ADDR_PATH); - if(temp!=NULL) nodesetadress=temp->nodesetval; - else pcilib_error("there is no adress for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_BAR_PATH); - if(temp!=NULL) nodesetbar=temp->nodesetval; - else pcilib_error("there is no bar for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_SIZE_PATH); - if(temp!=NULL) nodesetsize=temp->nodesetval; - else pcilib_error("there is no size for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_PROTOCOL_PATH); - if(temp!=NULL) nodesetprotocol= temp->nodesetval; - else pcilib_error("there is no protocol for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_READ_ADDR_PATH); - if(temp!=NULL) nodesetread_addr=temp->nodesetval; - else pcilib_error("there is no read_adress for banks in the xml"); + mynode=malloc(sizeof(xmlNode)); + context=pcilib_xml_getcontext(doc); - temp=pcilib_xml_getsetproperty(context,BANK_WRITE_ADDR_PATH); - if(temp!=NULL)nodesetwrite_addr=temp->nodesetval; - else pcilib_error("there is no write_adress for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_ACCESS_PATH); - if(temp!=NULL)nodesetaccess=temp->nodesetval; - else pcilib_error("there is no access for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_ENDIANESS_PATH); - if(temp!=NULL) nodesetendianess=temp->nodesetval; - else pcilib_error("there is no endianess for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_FORMAT_PATH); - if(temp!=NULL) nodesetformat=temp->nodesetval; - else pcilib_error("there is no format for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_NAME_PATH); - if(temp!=NULL)nodesetname=temp->nodesetval; - else pcilib_error("there is no name for banks in the xml"); + /** we get the bank nodes using xpath expression*/ + nodesetadress=pcilib_xml_getsetproperty(context,BANKS_PATH)->nodesetval; + if(nodesetadress->nodeNr>0) banks=calloc((nodesetadress->nodeNr),sizeof(pcilib_register_bank_description_t)); + else return; - temp=pcilib_xml_getsetproperty(context,BANK_DESCRIPTION_PATH); - if(temp!=NULL)nodesetdescription=temp->nodesetval; - pci->banks_xml_nodes=calloc(nodesetadress->nodeNr,sizeof(xmlNodePtr)); - if(!(pci->banks_xml_nodes)) pcilib_warning("can't create bank xml nodes for pcilib_t struct"); - - for(i=0;inodeNr;i++){ - /** we then get each node from the structures above*/ - adress=xmlNodeListGetString(docs[p],nodesetadress->nodeTab[i]->xmlChildrenNode, 1); - bar=xmlNodeListGetString(docs[p],nodesetbar->nodeTab[i]->xmlChildrenNode, 1); - size=xmlNodeListGetString(docs[p],nodesetsize->nodeTab[i]->xmlChildrenNode, 1); - protocol=xmlNodeListGetString(docs[p],nodesetprotocol->nodeTab[i]->xmlChildrenNode, 1); - read_addr=xmlNodeListGetString(docs[p],nodesetread_addr->nodeTab[i]->xmlChildrenNode, 1); - write_addr=xmlNodeListGetString(docs[p],nodesetwrite_addr->nodeTab[i]->xmlChildrenNode, 1); - access=xmlNodeListGetString(docs[p],nodesetaccess->nodeTab[i]->xmlChildrenNode, 1); - endianess=xmlNodeListGetString(docs[p],nodesetendianess->nodeTab[i]->xmlChildrenNode, 1); - format=xmlNodeListGetString(docs[p],nodesetformat->nodeTab[i]->xmlChildrenNode, 1); - name=xmlNodeListGetString(docs[p],nodesetname->nodeTab[i]->xmlChildrenNode, 1); - description=xmlNodeListGetString(docs[p],nodesetdescription->nodeTab[i]->xmlChildrenNode, 1); - - mynode=nodesetadress->nodeTab[i]->parent; - - /** the following function will create the given structure for banks*/ - pcilib_xml_create_bank(&mybank,adress,bar,size,protocol,read_addr,write_addr,access,endianess,format, name, description); - banks[i]=mybank; - pci->banks_xml_nodes[i]=mynode; + if(!(pci->banks_xml_nodes)) pcilib_warning("can't create bank xml nodes for pcilib_t struct"); + /** for each of the bank nodes, we create the associated structure*/ + for(i=0;inodeNr;i++){ + mynode=nodesetadress->nodeTab[i]; + pcilib_xml_create_bank(&mybank,mynode,doc); + banks[i]=mybank; + pci->banks_xml_nodes[i]=mynode; } - - pcilib_add_register_banks(pci,number_banks,banks); - p++; - } + /** we push our banks structures in the pcilib environnement*/ + pcilib_add_register_banks(pci,nodesetadress->nodeNr,banks); } /* - * next 3 functions are for the implementation of a merge sort algorithm + * next 2 functions are for the implementation of a merge sort algorithm, because we need a stable algorithm */ -void topdownmerge(pcilib_register_description_t *A, int start, int middle, int end, pcilib_register_description_t *B){ +static void +pcilib_xml_topdownmerge(pcilib_register_description_t *A, int start, int middle, int end, pcilib_register_description_t *B){ int i0,i1,j; i0= start; i1=middle; @@ -463,58 +287,154 @@ void topdownmerge(pcilib_register_description_t *A, int start, int middle, int e } } -void copyarray(pcilib_register_description_t *B, int start,int end, pcilib_register_description_t *A){ - int k; - for (k=start; knodesetval; /**children; + + while(cur!=NULL){ + value=xmlNodeListGetString(doc,cur->children,1); + /* we iterate throug each children to get the associated property + note :the use of strtol permits to get as well hexadecimal and decimal values + */ + if(strcmp((char*)cur->name,"adress")==0){ + myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"offset")==0){ + myregister->offset=(pcilib_register_size_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"size")==0){ + myregister->bits=(pcilib_register_size_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"default")==0){ + myregister->defvalue=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"rwmask")==0){ + if(strcmp((char*)value,"all bits")==0){ + myregister->rwmask=PCILIB_REGISTER_ALL_BITS; + }else if(strcmp((char*)value,"0")==0){ + myregister->rwmask=0; + }else{ + myregister->rwmask=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + } + + }else if(strcmp((char*)cur->name,"mode")==0){ + if(strcmp((char*)value,"R")==0){ + myregister->mode=PCILIB_REGISTER_R; + }else if(strcmp((char*)value,"W")==0){ + myregister->mode=PCILIB_REGISTER_W; + }else if(strcmp((char*)value,"RW")==0){ + myregister->mode=PCILIB_REGISTER_RW; + }else if(strcmp((char*)value,"W")==0){ + myregister->mode=PCILIB_REGISTER_W; + }else if(strcmp((char*)value,"RW1C")==0){ + myregister->mode=PCILIB_REGISTER_RW1C; + }else if(strcmp((char*)value,"W1C")==0){ + myregister->mode=PCILIB_REGISTER_W1C; + } + + }else if(strcmp((char*)cur->name,"name")==0){ + myregister->name=(char*)value; + + }else if(strcmp((char*)cur->name,"value_min")==0){ + /* not implemented yet*/ // myregister->value_min=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"value_max")==0){ + /* not implemented yet*/ // myregister->value_max=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"description")==0){ + myregister->description=(char*)value; } + + cur=cur->next; + } - temp2=pcilib_xml_getsetproperty(doc,SUB_OFFSET_PATH);/**< we get the structure with all bits registers here */ - if(temp2!=NULL) nodesetsuboffset=temp2->nodesetval;/**< we get the structure with all bits registers here */ - else nodesetsuboffset->nodeNr=0; - return nodesetadress->nodeNr + nodesetsuboffset->nodeNr; /**type=PCILIB_REGISTER_STANDARD; + bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent))->xmlChildrenNode,1); /**type=PCILIB_REGISTER_BITS; + bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent->parent->parent))->xmlChildrenNode,1);/**parent->parent->children; /**children,1); + if(strcmp((char*)cur->name,"adress")==0){ + myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0); + }else if(strcmp((char*)cur->name,"default")==0){ + myregister->defvalue=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + }else if(strcmp((char*)cur->name,"rwmask")==0){ + if(strcmp((char*)value,"all bits")==0){ + myregister->rwmask=PCILIB_REGISTER_ALL_BITS; + }else if(strcmp((char*)value,"0")==0){ + myregister->rwmask=0; + }else{ + myregister->rwmask=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + } + } + cur=cur->next; + } + + }else if(strcmp((char*)type,"fifo")==0){ + /* not implemented yet*/ myregister->type=PCILIB_REGISTER_FIFO; + } + if(strcmp((char*)bank,"bank 0")==0){ + myregister->bank=PCILIB_REGISTER_BANK0; + }else if(strcmp((char*)bank,"bank 1")==0){ + myregister->bank=PCILIB_REGISTER_BANK1; + }else if(strcmp((char*)bank,"bank 2")==0){ + myregister->bank=PCILIB_REGISTER_BANK2; + }else if(strcmp((char*)bank,"bank 3")==0){ + myregister->bank=PCILIB_REGISTER_BANK3; + }else if(strcmp((char*)bank,"DMA bank")==0){ + myregister->bank=PCILIB_REGISTER_BANK_DMA; + }else if (strcmp((char*)bank,"dynamic bank")==0){ + myregister->addr=PCILIB_REGISTER_BANK_DYNAMIC; + }else{ + myregister->bank=PCILIB_REGISTER_BANK_INVALID; + } +} /** pcilib_xml_initialize_registers * @@ -522,508 +442,128 @@ int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc){ * * variables who need change if xml structure change : bank,description, sub_description, sub_adress, sub_bank, sub_rwmask (we consider it to be equal to the standard register), sub_defvalue(same to standard register normally) * @param[in] doc the xpath context of the xml file. - * @param[in,out] registers in: initialized list out: the list of the created registers. + * @param[in] pci the pcilib_t struct running, that will get filled */ -void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr* docs){ +void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){ - xmlNodeSetPtr nodesetadress=NULL,nodesetoffset=NULL,nodesetdefvalue=NULL,nodesetrwmask=NULL,nodesetsize=NULL,nodesetmode=NULL,nodesetname=NULL; - xmlChar *adress=NULL,*offset=NULL,*defvalue=NULL,*rwmask=NULL,*size=NULL,*mode=NULL,*name=NULL,*bank=NULL,*type=NULL,*description=NULL; + xmlNodeSetPtr nodesetadress=NULL, nodesetsubadress=NULL; + xmlChar *type=NULL; xmlNodePtr mynode; - xmlNodePtr tempnode; xmlXPathContextPtr context; -int number_registers, count=0; + int number_registers; pcilib_register_description_t *registers=NULL; - -while(docs[count]!=NULL){ - context=pcilib_xml_getcontext(docs[count]); - number_registers=pcilib_xml_getnumberregisters(context); - if(number_registers) registers=calloc(number_registers,sizeof(pcilib_register_description_t)); - else return; - - xmlXPathObjectPtr temp; - - /** get the sructures containing each property of standard regsiter */ -/* -----> certainly not necessary if we validate xml each time*/ - - temp=pcilib_xml_getsetproperty(context,ADRESS_PATH); - if(temp!=NULL)nodesetadress=temp->nodesetval; - else pcilib_error("no adress for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,OFFSET_PATH); - if(temp!=NULL)nodesetoffset=temp->nodesetval; - else pcilib_error("no offset for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,DEFVALUE_PATH); - if(temp!=NULL)nodesetdefvalue=temp->nodesetval; - else pcilib_error("no defvalue for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,RWMASK_PATH); - if(temp!=NULL)nodesetrwmask=temp->nodesetval; - else pcilib_error("no rwmask for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,SIZE_PATH); - if(temp!=NULL)nodesetsize=temp->nodesetval; - else pcilib_error("no size for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,MODE_PATH); - if(temp!=NULL)nodesetmode=temp->nodesetval; - else pcilib_error("no mode for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,NAME_PATH); - if(temp!=NULL)nodesetname=temp->nodesetval; - else pcilib_error("no name for registers found in xml"); - - xmlNodeSetPtr nodesetsuboffset=NULL,nodesetsubsize=NULL,nodesetsubmode=NULL,nodesetsubname=NULL; - xmlChar *subadress=NULL,*suboffset=NULL,*subdefvalue=NULL,*subrwmask=NULL,*subsize=NULL,*submode=NULL,*subname=NULL,*subbank=NULL,*subtype=NULL,*subdescription=NULL; - - /**get the structures containing each property of bits registers */ - temp=pcilib_xml_getsetproperty(context,SUB_OFFSET_PATH); - if(temp!=NULL)nodesetsuboffset=temp->nodesetval; - else pcilib_error("no offset for registers bits found in xml"); - - temp=pcilib_xml_getsetproperty(context,SUB_SIZE_PATH); - if(temp!=NULL)nodesetsubsize=temp->nodesetval; - else pcilib_error("no size for registers bits found in xml"); - - temp=pcilib_xml_getsetproperty(context,SUB_MODE_PATH); - if(temp!=NULL)nodesetsubmode=temp->nodesetval; - else pcilib_error("no mode for registers bits found in xml"); - - temp=pcilib_xml_getsetproperty(context,SUB_NAME_PATH); - if(temp!=NULL)nodesetsubname=temp->nodesetval; - else pcilib_error("no name for registers bits found in xml"); - - pcilib_register_description_t myregister; - int i,j; + + context=pcilib_xml_getcontext(doc); + + /** we first get the nodes of standard and bits registers*/ + nodesetadress=pcilib_xml_getsetproperty(context,REGISTERS_PATH)->nodesetval; + nodesetsubadress=pcilib_xml_getsetproperty(context,BITS_REGISTERS_PATH)->nodesetval; + if(nodesetadress->nodeNr>0)registers=calloc(nodesetadress->nodeNr+nodesetsubadress->nodeNr,sizeof(pcilib_register_description_t)); + else return; - pci->registers_xml_nodes=calloc(nodesetadress->nodeNr+nodesetsuboffset->nodeNr,sizeof(xmlNodePtr)); + pci->registers_xml_nodes=calloc(nodesetadress->nodeNr+nodesetsubadress->nodeNr,sizeof(xmlNodePtr)); if(!(pci->registers_xml_nodes)) pcilib_warning("can't create registers xml nodes in pcilib_t struct"); + /** we then iterate through standard registers nodes to create registers structures*/ for(i=0;inodeNr;i++){ - /** get each sub property of each standard registers*/ - adress=xmlNodeListGetString(docs[count],nodesetadress->nodeTab[i]->xmlChildrenNode, 1); - tempnode=xmlFirstElementChild(xmlFirstElementChild(nodesetadress->nodeTab[i]->parent->parent->parent)); - if(strcmp("adress",(char*)tempnode->name)==0) bank=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode,1); - else pcilib_error("the xml file is malformed"); - offset=xmlNodeListGetString(docs[count],nodesetoffset->nodeTab[i]->xmlChildrenNode, 1); - size=xmlNodeListGetString(docs[count],nodesetsize->nodeTab[i]->xmlChildrenNode, 1); - defvalue=xmlNodeListGetString(docs[count],nodesetdefvalue->nodeTab[i]->xmlChildrenNode, 1); - rwmask=xmlNodeListGetString(docs[count],nodesetrwmask->nodeTab[i]->xmlChildrenNode, 1); - mode=xmlNodeListGetString(docs[count],nodesetmode->nodeTab[i]->xmlChildrenNode, 1); - name=xmlNodeListGetString(docs[count],nodesetname->nodeTab[i]->xmlChildrenNode, 1); type=(xmlChar*)"standard"; - if(nodesetname->nodeTab[i]->next->next!= NULL && strcmp((char*)nodesetname->nodeTab[i]->next->next->name,"description")==0){ - description=xmlNodeListGetString(docs[count],nodesetname->nodeTab[i]->next->next->xmlChildrenNode,1); - }else{ - description=(xmlChar*)""; - } - mynode=nodesetadress->nodeTab[i]->parent; - /**creation of a register with the given previous properties*/ - pcilib_xml_create_register(&myregister,adress,offset,size,defvalue,rwmask,mode, type, bank, name, description); + mynode=nodesetadress->nodeTab[i]; + pcilib_xml_create_register(&myregister,mynode,doc,type); registers[i]=myregister; pci->registers_xml_nodes[i]=mynode; } j=i; - - for(i=0;inodeNr;i++){ - /** we get there each subproperty of each bits register*/ - tempnode=xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent); - if(strcmp((char*)tempnode->name,"adress")==0)subadress=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode, 1); - else pcilib_error("xml file is malformed"); - tempnode= xmlFirstElementChild(xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent->parent->parent)); - if(strcmp((char*)tempnode->name,"adress")==0) subbank=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode,1); - else pcilib_error("xml file is malformed"); - suboffset=xmlNodeListGetString(docs[count],nodesetsuboffset->nodeTab[i]->xmlChildrenNode, 1); - subsize=xmlNodeListGetString(docs[count],nodesetsubsize->nodeTab[i]->xmlChildrenNode, 1); - tempnode=xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent)->next->next->next->next->next->next; - if(strcmp((char*)tempnode->name,"default")==0)subdefvalue=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode, 1); - else pcilib_error("xml file is malformed"); - subrwmask=xmlNodeListGetString(docs[count],nodesetsuboffset->nodeTab[i]->parent->parent->prev->prev->prev->prev->prev->prev->xmlChildrenNode, 1); - submode=xmlNodeListGetString(docs[count],nodesetsubmode->nodeTab[i]->xmlChildrenNode, 1); - subname=xmlNodeListGetString(docs[count],nodesetsubname->nodeTab[i]->xmlChildrenNode, 1); - subtype=(xmlChar*)"bits"; - if(nodesetsubname->nodeTab[i]->next->next!= NULL && strcmp((char*)nodesetsubname->nodeTab[i]->next->next->name,"sub_description")==0){ - subdescription=xmlNodeListGetString(docs[count],nodesetsubname->nodeTab[i]->next->next->xmlChildrenNode,1); - }else{ - subdescription=(xmlChar*)""; - } - mynode=nodesetsuboffset->nodeTab[i]->parent; - /** creation of a bits register given the previous properties*/ - pcilib_xml_create_register(&myregister,subadress,suboffset,subsize,subdefvalue,subrwmask,submode, subtype, subbank, subname, subdescription); + /** we then iterate through bits registers nodes to create registers structures*/ + for(i=0;inodeNr;i++){ + type=(xmlChar*)"bits"; + mynode=nodesetsubadress->nodeTab[i]; + pcilib_xml_create_register(&myregister,mynode,doc,type); registers[i+j]=myregister; pci->registers_xml_nodes[i+j]=mynode; } - - pcilib_xml_arrange_registers(registers,number_registers); - pcilib_add_registers(pci,number_registers,registers); - count++; - } -} - -#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; + /**we arrange the register for them to be well placed for pci-l*/ + pcilib_xml_arrange_registers(registers,nodesetadress->nodeNr+nodesetsubadress->nodeNr); + /**we fille the pcilib_t struct*/ + pcilib_add_registers(pci,number_registers,registers); } -/* 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, +/** pcilib_init_xml + * this function will initialize the registers and banks from the xml files + * @param[in,out] ctx the pciilib_t running that gets filled with structures */ -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; - +int pcilib_init_xml(pcilib_t* ctx){ + char *path,*pwd, **line, *line_xsd=NULL; + int i=1,k; + xmlDocPtr* docs; + DIR* rep=NULL; + struct dirent* file=NULL; + int err; -viewnumber=0; - + path=malloc(sizeof(char*)); + line=malloc(sizeof(char*)); + line[0]=NULL; + + /** we first get the env variable corresponding to the place of the xml files*/ + path=getenv("PCILIB_MODEL_DIR"); + if(path==NULL){ + pcilib_warning("can't find environment variable for xml files"); + return 1; + } - 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;inodeNr;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(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(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; jnodeNr;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; jnodeNr;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;jnodeNr;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;uviewsformula[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;lnodeNr;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;uviewsformula[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++; - } - - free(path); - free(path2); -} - -/* 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;inodeNr;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(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(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; jnodeNr;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; jnodeNr;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++; - - } - - free(path); - free(path2); -} -#endif + /** we then open the directory corresponding to the ctx model*/ + pwd=malloc((strlen(path)+strlen(ctx->model))*sizeof(char)); + sprintf(pwd,"%s%s/",path,ctx->model); + if((rep=opendir(pwd))==NULL){ + pcilib_warning("could not open the directory for xml files: error %i\n",errno); + return 1; + } -#ifdef UNIT_OK + /** we iterate through the files of the directory, to get the xml files and the xsd file*/ + while((file=readdir(rep))!=NULL){ + if(strstr(file->d_name,".xml")!=NULL){ + line=realloc(line,i*sizeof(char*)); + line[i-1]=malloc((strlen(file->d_name)+strlen(pwd)+1)*sizeof(char)); + sprintf(line[i-1],"%s%s",pwd,file->d_name); /**< here i wanted to use realpath() function, but it was not working correctly*/ + i++; + } + if(strstr(file->d_name,".xsd")!=NULL){ + line_xsd=malloc((strlen(file->d_name)+strlen(pwd))*sizeof(char)); + sprintf(line_xsd,"%s%s",pwd,file->d_name); + } + } -void pclib_xml_initialize_units(xmlDocPtr doc, pcilib_units_ptr_t* unitsptr){ + if(line_xsd==NULL){ + pcilib_warning("no xsd file found"); + return 1; + } - xmlNodeSetPtr nodesetbaseunit=NULL, nodesettransformunit=NULL; - xmlXPathContextptr context; - context=pcilib_xml_getcontext(doc); - xmlXPathObjectPtr temp; - int i,j; - char *path; + if(line[0]==NULL){ + pcilib_warning("no xml file found"); + return 1; + } + + /** for each xml file, we validate it, and get the registers and the banks*/ + docs=malloc((i-1)*sizeof(xmlDocPtr)); + for(k=0;knodesetval; - 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(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;jnodeNr;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); - } - } - } - free(path); -} -#endif -- cgit v1.2.3 From a13f2fe66f4599e2828e6cf752d1a34dc37c0791 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Fri, 4 Sep 2015 14:03:48 +0200 Subject: added cleanup --- pcilib/xml.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c index 55cdf11..257b503 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -244,7 +244,6 @@ pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ xmlNodeSetPtr nodesetadress=NULL; xmlNodePtr mynode; - pcilib_register_bank_description_t* banks; xmlXPathContextPtr context; int i; @@ -253,21 +252,20 @@ pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ /** we get the bank nodes using xpath expression*/ nodesetadress=pcilib_xml_getsetproperty(context,BANKS_PATH)->nodesetval; - if(nodesetadress->nodeNr>0) banks=calloc((nodesetadress->nodeNr),sizeof(pcilib_register_bank_description_t)); - else return; + if(nodesetadress->nodeNr==0) return; pci->banks_xml_nodes=calloc(nodesetadress->nodeNr,sizeof(xmlNodePtr)); - if(!(pci->banks_xml_nodes)) pcilib_warning("can't create bank xml nodes for pcilib_t struct"); + if(!(pci->banks_xml_nodes)) pcilib_error("can't create bank xml nodes for pcilib_t struct"); - /** for each of the bank nodes, we create the associated structure*/ + /** for each of the bank nodes, we create the associated structure, and push it in the pcilib environnement*/ for(i=0;inodeNr;i++){ mynode=nodesetadress->nodeTab[i]; pcilib_xml_create_bank(&mybank,mynode,doc); - banks[i]=mybank; + pcilib_add_register_banks(pci,1,&mybank); pci->banks_xml_nodes[i]=mynode; } - /** we push our banks structures in the pcilib environnement*/ - pcilib_add_register_banks(pci,nodesetadress->nodeNr,banks); + + } /* @@ -567,6 +565,10 @@ int pcilib_init_xml(pcilib_t* ctx){ free(line); free(line_xsd); free(docs); + + xmlCleanupParser(); + xmlMemoryDump(); + return 0; } -- cgit v1.2.3 From 86cca494757d4911041367c5d1d3a86395a541f5 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Fri, 4 Sep 2015 15:45:20 +0200 Subject: qsort enough implementation, and corrected a little unwanted propagating description --- pcilib/xml.c | 48 +++++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c index 257b503..dfda3cc 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -268,40 +268,20 @@ pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ } -/* - * next 2 functions are for the implementation of a merge sort algorithm, because we need a stable algorithm +/** pcilib_xml_registers_compare + * function to compare registers by adress for sorting registers + * @param a one hypothetic register + * @param b one other hypothetic register */ -static void -pcilib_xml_topdownmerge(pcilib_register_description_t *A, int start, int middle, int end, pcilib_register_description_t *B){ - int i0,i1,j; - i0= start; - i1=middle; - - for(j=start;j=end || A[i0].addr<=A[i1].addr)){ - B[j]=A[i0]; - i0++; - } - else{ - B[j]=A[i1]; - i1++; - } - } -} +static int +pcilib_xml_compare_registers(void const *a, void const *b){ + const pcilib_register_description_t *pa=a; + const pcilib_register_description_t *pb=b; -static void -pcilib_xml_topdownsplitmerge(pcilib_register_description_t *A, int start, int end, pcilib_register_description_t *B){ - int middle; - if(end-start <2) - return; - - middle =(end+start)/2; - pcilib_xml_topdownsplitmerge(A,start, middle,B); - pcilib_xml_topdownsplitmerge(A,middle,end,B); - pcilib_xml_topdownmerge(A,start,middle,end,B); - memcpy(&A[start],&B[start],(end-start)*sizeof(pcilib_register_description_t)); + return pa->addr - pb->addr; } + /** pcilib_xml_arrange_registers * after the complete structure containing the registers has been created from the xml, this function rearrange them by address in order to add them in pcilib_open, which don't consider the adding of registers in order of adress * @param[in,out] registers the list of registers in : not ranged out: ranged. @@ -310,7 +290,7 @@ pcilib_xml_topdownsplitmerge(pcilib_register_description_t *A, int start, int en void pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int size){ pcilib_register_description_t* temp; temp=malloc(size*sizeof(pcilib_register_description_t)); - pcilib_xml_topdownsplitmerge(registers,0,size,temp); + qsort(registers,size,sizeof(pcilib_register_description_t),pcilib_xml_compare_registers); free(temp); } @@ -327,6 +307,7 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod xmlNodePtr cur; xmlChar *value; xmlChar *bank; + int i=0; /**we get the children of the register xml nodes, that contains the properties for it*/ cur=mynode->children; @@ -382,12 +363,17 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod /* not implemented yet*/ // myregister->value_max=(pcilib_register_value_t)strtol((char*)value,&ptr,0); }else if(strcmp((char*)cur->name,"description")==0){ + i++; myregister->description=(char*)value; } cur=cur->next; } + /** make sure we don't get the description from previous registers*/ + if(i==0) myregister->description=NULL; + + /** we then get properties that can not be parsed as the previous ones*/ if(strcmp((char*)type,"standard")==0){ myregister->type=PCILIB_REGISTER_STANDARD; -- cgit v1.2.3 From ea28e2990ae59e21856d9ae0311cec5b5415237b Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Fri, 4 Sep 2015 20:31:14 +0200 Subject: end of modifications --- pcilib/xml.c | 386 ++++++++++++++++++++++++++++------------------------------- 1 file changed, 184 insertions(+), 202 deletions(-) (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c index dfda3cc..f581b96 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -11,12 +11,18 @@ In case the performance is not good enough, please consider the following : no more configuration file indicating where the files required are, hard code of formulas, and go to complete non evolutive code : get 1 access to xml file and context, and then make recursive descent to get all you need(investigation of libxml2 source code would be so needed to prove it's better to go recursive than just xpath). */ #define _XOPEN_SOURCE 700 + + +#define REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register") /** #include #include -#include +#include #include "pci.h" #include "bank.h" #include "register.h" @@ -25,71 +31,54 @@ #include #include #include - #include #include -/** pcilib_xml_getdoc - * this function takes a string and will create an abtract syntax tree from the xml file represented by the string - * @param[in] filename the the name of the xml file containing registers and banks - */ -static xmlDocPtr -pcilib_xml_getdoc(char* filename){ - xmlDocPtr doc; - doc=xmlParseFile(filename); /**nodesetval)){ - xmlXPathFreeObject(result); - return NULL; + pcilib_warning("the parsing of %s xpath expression resulted in an empty nodeset",(char*)xpath); + xmlXPathFreeObject(result); + return NULL; } return result; } -/** pcilib_xml_getcontext. - * this function create a context in an AST (ie initialize XPAth for the AST). - * @param[in] doc the AST of the xml file. + +/**pcilib_xml_get_bank_node_from_register_node + * this function get the bank xml node from a standards register xml node in the xml file + *@param[in] mynode the register node we want to know the bank + *@return the bank node */ -static xmlXPathContextPtr -pcilib_xml_getcontext(xmlDocPtr doc){ - xmlXPathContextPtr context; - context= xmlXPathNewContext(doc); /**parent->parent)); } -/** validation + +/** pcilib_xml_validate * function to validate the xml file against the xsd * @param[in] xml_filename path to the xml file * @param[in] xsd_filename path to the xsd file + *@return an error code */ static int -validation(char* xml_filename, char* xsd_filename) +pcilib_xml_validate(char* xml_filename, char* xsd_filename) { xmlDocPtr doc; xmlSchemaPtr schema = NULL; @@ -136,11 +125,14 @@ if(ret!=0) pcilib_warning("\nxml file \"%s\" does not validate against the schem * @param[in] doc the AST of the xml file, used for used lixbml functions */ static void -pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc){ +pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc, pcilib_t* pci){ char* ptr; xmlNodePtr cur; xmlChar *value; + static int i=0; + int bar_ok=0; + int k=0, name_found=0; cur=mynode->children; /** we place ourselves in the childrens of the bank node*/ @@ -149,84 +141,69 @@ pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr my /** we get each time the name of the node, corresponding to one property, and the value of the node*/ value=xmlNodeListGetString(doc,cur->children,1); - if(strcmp((char*)cur->name,"adress")==0){ - if (strcmp((char*)value,"bank 0")==0){ - mybank->addr=PCILIB_REGISTER_BANK0; - }else if (strcmp((char*)value,"bank 1")==0){ - mybank->addr=PCILIB_REGISTER_BANK1; - }else if (strcmp((char*)value,"bank 2")==0){ - mybank->addr=PCILIB_REGISTER_BANK2; - }else if (strcmp((char*)value,"bank 3")==0){ - mybank->addr=PCILIB_REGISTER_BANK3; - }else if (strcmp((char*)value,"DMA bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DMA; - }else if (strcmp((char*)value,"DMAconf bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DMACONF; - }else if (strcmp((char*)value,"dynamic bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC; - }else{ - mybank->addr=PCILIB_REGISTER_BANK_INVALID; - } + if(strcasecmp((char*)cur->name,"bar")==0){ + mybank->bar=(pcilib_bar_t)(value[0]-'0'); + bar_ok++; - }else if(strcmp((char*)cur->name,"bar")==0){ - if(strcmp((char*)value,"0")==0){ - mybank->bar=PCILIB_BAR0; - }else if(strcmp((char*)value,"1")==0){ - mybank->bar=PCILIB_BAR1; - }else if(strcmp((char*)value,"no_bar")==0){ - mybank->bar=PCILIB_BAR_NOBAR; - }else{ - mybank->bar=PCILIB_BAR_INVALID; - } - mybank->bar=(pcilib_bar_t)strtol((char*)value,&ptr,0); - - }else if(strcmp((char*)cur->name,"size")==0){ + }else if(strcasecmp((char*)cur->name,"size")==0){ mybank->size=(size_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"protocol")==0){ - if(strcmp((char*)value,"default")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT; - }else if(strcmp((char*)value,"0")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL0; - }else if(strcmp((char*)value,"dma")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DMA; - }else if(strcmp((char*)value,"dynamic")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DYNAMIC; - }else if (strcmp((char*)value,"software")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_SOFTWARE; - }else mybank->protocol=PCILIB_REGISTER_PROTOCOL_INVALID; - - }else if(strcmp((char*)cur->name,"read_adress")==0){ + }else if(strcasecmp((char*)cur->name,"protocol")==0){ + while(pci->protocols[k].name!=NULL){ + if(strcasecmp(pci->protocols[k].name,(char*)value)==0){ + mybank->protocol=pci->protocols[k].addr; + break; + k++; + } + } + + }else if(strcasecmp((char*)cur->name,"read_address")==0){ mybank->read_addr=(uintptr_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"write_adress")==0){ + }else if(strcasecmp((char*)cur->name,"write_address")==0){ mybank->write_addr=(uintptr_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"word_size")==0){ + }else if(strcasecmp((char*)cur->name,"word_size")==0){ mybank->access=(uint8_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"endianess")==0){ - if(strcmp((char*)value,"little")==0){ + }else if(strcasecmp((char*)cur->name,"endianess")==0){ + if(strcasecmp((char*)value,"little")==0){ mybank->endianess=PCILIB_LITTLE_ENDIAN; - }else if(strcmp((char*)value,"big")==0){ + }else if(strcasecmp((char*)value,"big")==0){ mybank->endianess=PCILIB_BIG_ENDIAN; - }else if(strcmp((char*)value,"host")==0){ + }else if(strcasecmp((char*)value,"host")==0){ mybank->endianess=PCILIB_HOST_ENDIAN; } mybank->raw_endianess=mybank->endianess; - }else if(strcmp((char*)cur->name,"format")==0){ + }else if(strcasecmp((char*)cur->name,"format")==0){ mybank->format=(char*)value; - }else if(strcmp((char*)cur->name,"name")==0){ + }else if(strcasecmp((char*)cur->name,"name")==0){ mybank->name=(char*)value; - }else if(strcmp((char*)cur->name,"description")==0){ + }else if(strcasecmp((char*)cur->name,"description")==0){ mybank->description=(char*)value; } cur=cur->next; } + + if(bar_ok==0) mybank->bar=PCILIB_BAR_NOBAR; + + while(pci->banks[k].name!=NULL){ + if(strcasecmp(pci->banks[k].name,mybank->name)==0){ + mybank->addr=pci->banks[k].addr; + name_found++; + break; + } + k++; + } + if(name_found==0) { + mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC + i; + i++; + } + pci->xml_banks[k]=mynode; } @@ -242,36 +219,39 @@ static void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ pcilib_register_bank_description_t mybank; - xmlNodeSetPtr nodesetadress=NULL; + xmlNodeSetPtr nodesetaddress=NULL; xmlNodePtr mynode; xmlXPathContextPtr context; int i; mynode=malloc(sizeof(xmlNode)); - context=pcilib_xml_getcontext(doc); - + if(!(context= xmlXPathNewContext(doc))){ + pcilib_error("can't get an AST from an xml file"); + return; + } /** we get the bank nodes using xpath expression*/ - nodesetadress=pcilib_xml_getsetproperty(context,BANKS_PATH)->nodesetval; - if(nodesetadress->nodeNr==0) return; + nodesetaddress=pcilib_xml_get_nodeset_from_xpath(context,BANKS_PATH)->nodesetval; + if(!(nodesetaddress)) return; + if(nodesetaddress->nodeNr==0) return; - pci->banks_xml_nodes=calloc(nodesetadress->nodeNr,sizeof(xmlNodePtr)); - if(!(pci->banks_xml_nodes)) pcilib_error("can't create bank xml nodes for pcilib_t struct"); + pci->xml_banks=calloc(PCILIB_MAX_REGISTER_BANKS+1,sizeof(xmlNodePtr)); + if(!(pci->xml_banks)) pcilib_error("can't create bank xml nodes for pcilib_t struct"); /** for each of the bank nodes, we create the associated structure, and push it in the pcilib environnement*/ - for(i=0;inodeNr;i++){ - mynode=nodesetadress->nodeTab[i]; - pcilib_xml_create_bank(&mybank,mynode,doc); + for(i=0;inodeNr;i++){ + mynode=nodesetaddress->nodeTab[i]; + pcilib_xml_create_bank(&mybank,mynode,doc, pci); pcilib_add_register_banks(pci,1,&mybank); - pci->banks_xml_nodes[i]=mynode; } } /** pcilib_xml_registers_compare - * function to compare registers by adress for sorting registers + * function to compare registers by address for sorting registers * @param a one hypothetic register * @param b one other hypothetic register + *@return the result of the comparison */ static int pcilib_xml_compare_registers(void const *a, void const *b){ @@ -283,7 +263,7 @@ pcilib_xml_compare_registers(void const *a, void const *b){ /** pcilib_xml_arrange_registers - * after the complete structure containing the registers has been created from the xml, this function rearrange them by address in order to add them in pcilib_open, which don't consider the adding of registers in order of adress + * after the complete structure containing the registers has been created from the xml, this function rearrange them by address in order to add them in pcilib_open, which don't consider the adding of registers in order of address * @param[in,out] registers the list of registers in : not ranged out: ranged. * @param[in] size the number of registers. */ @@ -301,12 +281,12 @@ void pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int s * @param[in] doc the AST of the xml file, required for some ibxml2 sub-fonctions * @param[in] mynode the xml node to create register from */ -void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNodePtr mynode, xmlDocPtr doc, xmlChar* type){ +void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNodePtr mynode, xmlDocPtr doc, xmlChar* type, pcilib_t* pci){ char* ptr; xmlNodePtr cur; - xmlChar *value; - xmlChar *bank; + xmlChar *value=NULL; + xmlNodePtr bank=NULL; int i=0; /**we get the children of the register xml nodes, that contains the properties for it*/ @@ -317,52 +297,52 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod /* we iterate throug each children to get the associated property note :the use of strtol permits to get as well hexadecimal and decimal values */ - if(strcmp((char*)cur->name,"adress")==0){ + if(strcasecmp((char*)cur->name,"address")==0){ myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"offset")==0){ + }else if(strcasecmp((char*)cur->name,"offset")==0){ myregister->offset=(pcilib_register_size_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"size")==0){ + }else if(strcasecmp((char*)cur->name,"size")==0){ myregister->bits=(pcilib_register_size_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"default")==0){ + }else if(strcasecmp((char*)cur->name,"default")==0){ myregister->defvalue=(pcilib_register_value_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"rwmask")==0){ - if(strcmp((char*)value,"all bits")==0){ + }else if(strcasecmp((char*)cur->name,"rwmask")==0){ + if(strcasecmp((char*)value,"all bits")==0){ myregister->rwmask=PCILIB_REGISTER_ALL_BITS; - }else if(strcmp((char*)value,"0")==0){ + }else if(strcasecmp((char*)value,"0")==0){ myregister->rwmask=0; }else{ myregister->rwmask=(pcilib_register_value_t)strtol((char*)value,&ptr,0); } - }else if(strcmp((char*)cur->name,"mode")==0){ - if(strcmp((char*)value,"R")==0){ + }else if(strcasecmp((char*)cur->name,"mode")==0){ + if(strcasecmp((char*)value,"R")==0){ myregister->mode=PCILIB_REGISTER_R; - }else if(strcmp((char*)value,"W")==0){ + }else if(strcasecmp((char*)value,"W")==0){ myregister->mode=PCILIB_REGISTER_W; - }else if(strcmp((char*)value,"RW")==0){ + }else if(strcasecmp((char*)value,"RW")==0){ myregister->mode=PCILIB_REGISTER_RW; - }else if(strcmp((char*)value,"W")==0){ + }else if(strcasecmp((char*)value,"W")==0){ myregister->mode=PCILIB_REGISTER_W; - }else if(strcmp((char*)value,"RW1C")==0){ + }else if(strcasecmp((char*)value,"RW1C")==0){ myregister->mode=PCILIB_REGISTER_RW1C; - }else if(strcmp((char*)value,"W1C")==0){ + }else if(strcasecmp((char*)value,"W1C")==0){ myregister->mode=PCILIB_REGISTER_W1C; } - }else if(strcmp((char*)cur->name,"name")==0){ + }else if(strcasecmp((char*)cur->name,"name")==0){ myregister->name=(char*)value; - }else if(strcmp((char*)cur->name,"value_min")==0){ + }else if(strcasecmp((char*)cur->name,"value_min")==0){ /* not implemented yet*/ // myregister->value_min=(pcilib_register_value_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"value_max")==0){ + }else if(strcasecmp((char*)cur->name,"value_max")==0){ /* not implemented yet*/ // myregister->value_max=(pcilib_register_value_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"description")==0){ + }else if(strcasecmp((char*)cur->name,"description")==0){ i++; myregister->description=(char*)value; } @@ -375,116 +355,106 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod /** we then get properties that can not be parsed as the previous ones*/ - if(strcmp((char*)type,"standard")==0){ + if(strcasecmp((char*)type,"standard")==0){ myregister->type=PCILIB_REGISTER_STANDARD; - bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent))->xmlChildrenNode,1); /**children,1); + if(strcasecmp((char*)bank->name,"name")==0){ + break; + } + bank=bank->next; + } - }else if(strcmp((char*)type,"bits")==0){ - myregister->type=PCILIB_REGISTER_BITS; - bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent->parent->parent))->xmlChildrenNode,1);/**parent->parent->children; /**children,1); - if(strcmp((char*)cur->name,"adress")==0){ - myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"default")==0){ - myregister->defvalue=(pcilib_register_value_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"rwmask")==0){ - if(strcmp((char*)value,"all bits")==0){ - myregister->rwmask=PCILIB_REGISTER_ALL_BITS; - }else if(strcmp((char*)value,"0")==0){ - myregister->rwmask=0; - }else{ - myregister->rwmask=(pcilib_register_value_t)strtol((char*)value,&ptr,0); - } + int k=0; + + while(pci->banks[k].name!=NULL){ + printf("name %s\n",pci->banks[k].name); + if(strcasecmp(pci->banks[k].name,(char*)value)==0){ + myregister->bank=pci->banks[k].addr; + printf("ok\n"); + break; } - cur=cur->next; + k++; } - }else if(strcmp((char*)type,"fifo")==0){ - /* not implemented yet*/ myregister->type=PCILIB_REGISTER_FIFO; - } + }else if(strcasecmp((char*)type,"bits")==0){ + myregister->type=PCILIB_REGISTER_BITS; - if(strcmp((char*)bank,"bank 0")==0){ - myregister->bank=PCILIB_REGISTER_BANK0; - }else if(strcmp((char*)bank,"bank 1")==0){ - myregister->bank=PCILIB_REGISTER_BANK1; - }else if(strcmp((char*)bank,"bank 2")==0){ - myregister->bank=PCILIB_REGISTER_BANK2; - }else if(strcmp((char*)bank,"bank 3")==0){ - myregister->bank=PCILIB_REGISTER_BANK3; - }else if(strcmp((char*)bank,"DMA bank")==0){ - myregister->bank=PCILIB_REGISTER_BANK_DMA; - }else if (strcmp((char*)bank,"dynamic bank")==0){ - myregister->addr=PCILIB_REGISTER_BANK_DYNAMIC; - }else{ - myregister->bank=PCILIB_REGISTER_BANK_INVALID; + }else if(strcasecmp((char*)type,"fifo")==0){ + /* not implemented yet*/ myregister->type=PCILIB_REGISTER_FIFO; } + + } /** pcilib_xml_initialize_registers * * this function create a list of registers from an abstract syntax tree * - * variables who need change if xml structure change : bank,description, sub_description, sub_adress, sub_bank, sub_rwmask (we consider it to be equal to the standard register), sub_defvalue(same to standard register normally) + * variables who need change if xml structure change : bank,description, sub_description, sub_address, sub_bank, sub_rwmask (we consider it to be equal to the standard register), sub_defvalue(same to standard register normally) * @param[in] doc the xpath context of the xml file. * @param[in] pci the pcilib_t struct running, that will get filled */ void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){ - xmlNodeSetPtr nodesetadress=NULL, nodesetsubadress=NULL; - xmlChar *type=NULL; + xmlNodeSetPtr nodesetaddress=NULL, nodesetsubaddress=NULL; xmlNodePtr mynode; xmlXPathContextPtr context; pcilib_register_description_t *registers=NULL; pcilib_register_description_t myregister; int i,j; - context=pcilib_xml_getcontext(doc); + context= xmlXPathNewContext(doc); + if(!(context= xmlXPathNewContext(doc))){ + pcilib_error("can't get an AST from an xml file"); + return; + } /** we first get the nodes of standard and bits registers*/ - nodesetadress=pcilib_xml_getsetproperty(context,REGISTERS_PATH)->nodesetval; - nodesetsubadress=pcilib_xml_getsetproperty(context,BITS_REGISTERS_PATH)->nodesetval; - if(nodesetadress->nodeNr>0)registers=calloc(nodesetadress->nodeNr+nodesetsubadress->nodeNr,sizeof(pcilib_register_description_t)); + nodesetaddress=pcilib_xml_get_nodeset_from_xpath(context,REGISTERS_PATH)->nodesetval; + nodesetsubaddress=pcilib_xml_get_nodeset_from_xpath(context,BITS_REGISTERS_PATH)->nodesetval; + if(!(nodesetaddress)) return; + if(nodesetaddress->nodeNr>0)registers=calloc(nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,sizeof(pcilib_register_description_t)); else return; - pci->registers_xml_nodes=calloc(nodesetadress->nodeNr+nodesetsubadress->nodeNr,sizeof(xmlNodePtr)); - if(!(pci->registers_xml_nodes)) pcilib_warning("can't create registers xml nodes in pcilib_t struct"); + pci->xml_registers=calloc(nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,sizeof(xmlNodePtr)); + if(!(pci->xml_registers)) pcilib_warning("can't create registers xml nodes in pcilib_t struct"); /** we then iterate through standard registers nodes to create registers structures*/ - for(i=0;inodeNr;i++){ - type=(xmlChar*)"standard"; - mynode=nodesetadress->nodeTab[i]; - pcilib_xml_create_register(&myregister,mynode,doc,type); + for(i=0;inodeNr;i++){ + mynode=nodesetaddress->nodeTab[i]; + pcilib_xml_create_register(&myregister,mynode,doc,(xmlChar*)"standard",pci); registers[i]=myregister; - pci->registers_xml_nodes[i]=mynode; + pci->xml_registers[i]=mynode; } j=i; + if(!(nodesetsubaddress)) return; /** we then iterate through bits registers nodes to create registers structures*/ - for(i=0;inodeNr;i++){ - type=(xmlChar*)"bits"; - mynode=nodesetsubadress->nodeTab[i]; - pcilib_xml_create_register(&myregister,mynode,doc,type); + for(i=0;inodeNr;i++){ + mynode=nodesetsubaddress->nodeTab[i]; + pcilib_xml_create_register(&myregister,mynode->parent->parent,doc,(xmlChar*)"standard",pci); + pcilib_xml_create_register(&myregister,mynode,doc,(xmlChar*)"bits",pci); registers[i+j]=myregister; - pci->registers_xml_nodes[i+j]=mynode; + pci->xml_registers[i+j]=mynode; } /**we arrange the register for them to be well placed for pci-l*/ - pcilib_xml_arrange_registers(registers,nodesetadress->nodeNr+nodesetsubadress->nodeNr); + pcilib_xml_arrange_registers(registers,nodesetaddress->nodeNr+nodesetsubaddress->nodeNr); /**we fille the pcilib_t struct*/ - pcilib_add_registers(pci,nodesetadress->nodeNr+nodesetsubadress->nodeNr,registers); + pcilib_add_registers(pci,nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,registers); } /** pcilib_init_xml * this function will initialize the registers and banks from the xml files * @param[in,out] ctx the pciilib_t running that gets filled with structures + * @param[in] model the current model of ctx + * @return an error code */ -int pcilib_init_xml(pcilib_t* ctx){ +int pcilib_init_xml(pcilib_t* ctx, char* model){ char *path,*pwd, **line, *line_xsd=NULL; int i=1,k; xmlDocPtr* docs; @@ -504,8 +474,8 @@ int pcilib_init_xml(pcilib_t* ctx){ } /** we then open the directory corresponding to the ctx model*/ - pwd=malloc((strlen(path)+strlen(ctx->model))*sizeof(char)); - sprintf(pwd,"%s%s/",path,ctx->model); + pwd=malloc((strlen(path)+strlen(model))*sizeof(char)); + sprintf(pwd,"%s%s/",path,model); if((rep=opendir(pwd))==NULL){ pcilib_warning("could not open the directory for xml files: error %i\n",errno); return 1; @@ -538,23 +508,35 @@ int pcilib_init_xml(pcilib_t* ctx){ /** for each xml file, we validate it, and get the registers and the banks*/ docs=malloc((i-1)*sizeof(xmlDocPtr)); for(k=0;kxml_context=malloc(sizeof(pcilib_xml_context_t)); + ctx->xml_context->docs=malloc(sizeof(xmlDocPtr)*(i-1)); + ctx->xml_context->docs=docs; + free(pwd); free(line); free(line_xsd); - free(docs); - - xmlCleanupParser(); - xmlMemoryDump(); return 0; } +/** pcilib_clean_xml + * this function free the xml parts of the pcilib_t running, and some libxml ashes + * @param[in] pci the pcilib_t running +*/ +void pcilib_clean_xml(pcilib_t* pci){ + + free(pci->xml_banks); + free(pci->xml_registers); + free(pci->xml_context); + xmlCleanupParser(); + xmlMemoryDump(); + +} -- cgit v1.2.3 From d996fab54c59ca0b34d4ff7c4ab5ab8247559db0 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Mon, 7 Sep 2015 10:35:48 +0200 Subject: further modifications --- pcilib/xml.c | 200 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 105 insertions(+), 95 deletions(-) (limited to 'pcilib/xml.c') diff --git a/pcilib/xml.c b/pcilib/xml.c index f581b96..8457927 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -4,11 +4,11 @@ * * @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 * - * @details this code was meant to be evolutive as the XML files evolute. In this meaning, most of the xml parsing is realized with XPath expressions(when it was possible), so that changing the xml xould result mainly in changing the XPAth pathes present in the header file. In a case of a change in xml file, variables that need to be changed other than xpathes, will be indicated in the description of the function. - + * @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. + 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. - In case the performance is not good enough, please consider the following : no more configuration file indicating where the files required are, hard code of formulas, and go to complete non evolutive code : get 1 access to xml file and context, and then make recursive descent to get all you need(investigation of libxml2 source code would be so needed to prove it's better to go recursive than just xpath). + In case the performance is not good enough, please consider the following : hard code of formulas */ #define _XOPEN_SOURCE 700 @@ -33,6 +33,14 @@ #include #include #include +#include "config.h" + +typedef enum{ + type_standard, + type_bits, + type_fifo +}pcilib_type_register_t; + /** pcilib_xml_get_nodeset_from_xpath * this function takes a context from an AST and an XPath expression, to produce an object containing the nodes corresponding to the xpath expression @@ -59,18 +67,6 @@ pcilib_xml_get_nodeset_from_xpath(xmlXPathContextPtr doc, xmlChar *xpath){ } -/**pcilib_xml_get_bank_node_from_register_node - * this function get the bank xml node from a standards register xml node in the xml file - *@param[in] mynode the register node we want to know the bank - *@return the bank node - */ -static xmlNodePtr -pcilib_xml_get_bank_node_from_register_node(xmlNodePtr mynode){ - return xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent)); -} - - - /** pcilib_xml_validate * function to validate the xml file against the xsd * @param[in] xml_filename path to the xml file @@ -125,14 +121,13 @@ if(ret!=0) pcilib_warning("\nxml file \"%s\" does not validate against the schem * @param[in] doc the AST of the xml file, used for used lixbml functions */ static void -pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc, pcilib_t* pci){ +pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc, pcilib_t* pci, int err){ char* ptr; xmlNodePtr cur; xmlChar *value; - static int i=0; int bar_ok=0; - int k=0, name_found=0; + int k=0; cur=mynode->children; /** we place ourselves in the childrens of the bank node*/ @@ -149,12 +144,8 @@ pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr my mybank->size=(size_t)strtol((char*)value,&ptr,0); }else if(strcasecmp((char*)cur->name,"protocol")==0){ - while(pci->protocols[k].name!=NULL){ - if(strcasecmp(pci->protocols[k].name,(char*)value)==0){ - mybank->protocol=pci->protocols[k].addr; - break; - k++; - } + if((mybank->protocol=pcilib_find_register_protocol_by_name(pci,(char*)value))==PCILIB_REGISTER_PROTOCOL_INVALID){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT; } }else if(strcasecmp((char*)cur->name,"read_address")==0){ @@ -190,20 +181,23 @@ pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr my } if(bar_ok==0) mybank->bar=PCILIB_BAR_NOBAR; - - while(pci->banks[k].name!=NULL){ - if(strcasecmp(pci->banks[k].name,mybank->name)==0){ - mybank->addr=pci->banks[k].addr; - name_found++; - break; + + k=(int)pcilib_find_register_bank_by_name(pci,mybank->name); + if(k==PCILIB_REGISTER_BANK_INVALID){ + mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC + pci->xml_ctx->nb_new_banks; + pci->xml_ctx->nb_new_banks++; + k=pci->num_banks+1; } - k++; - } - if(name_found==0) { - mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC + i; - i++; + else mybank->addr=pci->banks[k].addr; + + if(err==0){ + pci->xml_ctx->xml_banks[k]=mynode; } - pci->xml_banks[k]=mynode; + + char buffer[66]; + sprintf(buffer,"%i",mybank->addr); + printf("buffer %s \n",buffer); + xmlNewChild(mynode,NULL, BAD_CAST "address", BAD_CAST buffer); } @@ -222,7 +216,7 @@ pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ xmlNodeSetPtr nodesetaddress=NULL; xmlNodePtr mynode; xmlXPathContextPtr context; - int i; + int i,err=0; mynode=malloc(sizeof(xmlNode)); if(!(context= xmlXPathNewContext(doc))){ @@ -234,13 +228,16 @@ pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ if(!(nodesetaddress)) return; if(nodesetaddress->nodeNr==0) return; - pci->xml_banks=calloc(PCILIB_MAX_REGISTER_BANKS+1,sizeof(xmlNodePtr)); - if(!(pci->xml_banks)) pcilib_error("can't create bank xml nodes for pcilib_t struct"); + pci->xml_ctx->xml_banks=calloc(PCILIB_MAX_REGISTER_BANKS+1,sizeof(xmlNodePtr)); + if(!(pci->xml_ctx->xml_banks)){ + pcilib_error("can't create bank xml nodes for pcilib_t struct"); + err++; + } /** for each of the bank nodes, we create the associated structure, and push it in the pcilib environnement*/ for(i=0;inodeNr;i++){ mynode=nodesetaddress->nodeTab[i]; - pcilib_xml_create_bank(&mybank,mynode,doc, pci); + pcilib_xml_create_bank(&mybank,mynode,doc, pci, err); pcilib_add_register_banks(pci,1,&mybank); } @@ -267,13 +264,24 @@ pcilib_xml_compare_registers(void const *a, void const *b){ * @param[in,out] registers the list of registers in : not ranged out: ranged. * @param[in] size the number of registers. */ -void pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int size){ +static void +pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int size){ pcilib_register_description_t* temp; temp=malloc(size*sizeof(pcilib_register_description_t)); qsort(registers,size,sizeof(pcilib_register_description_t),pcilib_xml_compare_registers); free(temp); } +/**pcilib_get_bank_address_from_register_node + *@param[in] node the current register node + */ +static xmlChar* +pcilib_get_bank_address_from_register_node(xmlDocPtr doc, xmlNodePtr node){ + xmlChar* temp= xmlNodeListGetString(doc,xmlGetLastChild(xmlFirstElementChild(node->parent->parent))->children,1); + return temp; +} + + /** pcilib_xml_create_register. * this function create a register structure from a xml register node. * @param[out] myregister the register we want to create @@ -281,12 +289,11 @@ void pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int s * @param[in] doc the AST of the xml file, required for some ibxml2 sub-fonctions * @param[in] mynode the xml node to create register from */ -void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNodePtr mynode, xmlDocPtr doc, xmlChar* type, pcilib_t* pci){ +void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNodePtr mynode, xmlDocPtr doc,pcilib_register_type_t type, pcilib_t* pci){ char* ptr; xmlNodePtr cur; xmlChar *value=NULL; - xmlNodePtr bank=NULL; int i=0; /**we get the children of the register xml nodes, that contains the properties for it*/ @@ -299,7 +306,7 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod */ if(strcasecmp((char*)cur->name,"address")==0){ myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0); - + }else if(strcasecmp((char*)cur->name,"offset")==0){ myregister->offset=(pcilib_register_size_t)strtol((char*)value,&ptr,0); @@ -352,39 +359,19 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod /** make sure we don't get the description from previous registers*/ if(i==0) myregister->description=NULL; - /** we then get properties that can not be parsed as the previous ones*/ - if(strcasecmp((char*)type,"standard")==0){ + if((int)type==(int)type_standard){ myregister->type=PCILIB_REGISTER_STANDARD; - bank=pcilib_xml_get_bank_node_from_register_node(mynode); - while(bank!=NULL){ - value=xmlNodeListGetString(doc,bank->children,1); - if(strcasecmp((char*)bank->name,"name")==0){ - break; - } - bank=bank->next; - } - - int k=0; - - while(pci->banks[k].name!=NULL){ - printf("name %s\n",pci->banks[k].name); - if(strcasecmp(pci->banks[k].name,(char*)value)==0){ - myregister->bank=pci->banks[k].addr; - printf("ok\n"); - break; - } - k++; - } - - }else if(strcasecmp((char*)type,"bits")==0){ + myregister->bank=(pcilib_register_bank_addr_t)strtol((char*)pcilib_get_bank_address_from_register_node(doc,mynode),&ptr,0); + + }else if((int)type==(int)type_bits){ myregister->type=PCILIB_REGISTER_BITS; - - }else if(strcasecmp((char*)type,"fifo")==0){ + + }else if((int)type==(int)type_fifo){ /* not implemented yet*/ myregister->type=PCILIB_REGISTER_FIFO; } - + } @@ -403,7 +390,7 @@ void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){ xmlXPathContextPtr context; pcilib_register_description_t *registers=NULL; pcilib_register_description_t myregister; - int i,j; + int i,j,err=0; context= xmlXPathNewContext(doc); if(!(context= xmlXPathNewContext(doc))){ @@ -418,15 +405,22 @@ void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){ if(nodesetaddress->nodeNr>0)registers=calloc(nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,sizeof(pcilib_register_description_t)); else return; - pci->xml_registers=calloc(nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,sizeof(xmlNodePtr)); - if(!(pci->xml_registers)) pcilib_warning("can't create registers xml nodes in pcilib_t struct"); + if(pci->xml_ctx->nb_registers==0) + pci->xml_ctx->xml_registers=calloc(nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,sizeof(xmlNodePtr)); + else + pci->xml_ctx->xml_registers=realloc(pci->xml_ctx->xml_registers,(pci->xml_ctx->nb_registers+nodesetaddress->nodeNr+nodesetsubaddress->nodeNr)*sizeof(xmlNodePtr)); + + if(!(pci->xml_ctx->xml_registers)){ + pcilib_warning("can't create registers xml nodes in pcilib_t struct: memory allocation failed"); + err++; + } /** we then iterate through standard registers nodes to create registers structures*/ for(i=0;inodeNr;i++){ mynode=nodesetaddress->nodeTab[i]; - pcilib_xml_create_register(&myregister,mynode,doc,(xmlChar*)"standard",pci); + pcilib_xml_create_register(&myregister,mynode,doc,type_standard,pci); registers[i]=myregister; - pci->xml_registers[i]=mynode; + if(err==0) pci->xml_ctx->xml_registers[pci->xml_ctx->nb_registers+i]=mynode; } j=i; @@ -434,16 +428,17 @@ void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){ /** we then iterate through bits registers nodes to create registers structures*/ for(i=0;inodeNr;i++){ mynode=nodesetsubaddress->nodeTab[i]; - pcilib_xml_create_register(&myregister,mynode->parent->parent,doc,(xmlChar*)"standard",pci); - pcilib_xml_create_register(&myregister,mynode,doc,(xmlChar*)"bits",pci); + pcilib_xml_create_register(&myregister,mynode->parent->parent,doc,type_standard,pci); + pcilib_xml_create_register(&myregister,mynode,doc,type_bits,pci); registers[i+j]=myregister; - pci->xml_registers[i+j]=mynode; + if(err==0) pci->xml_ctx->xml_registers[pci->xml_ctx->nb_registers+i+j]=mynode; } /**we arrange the register for them to be well placed for pci-l*/ pcilib_xml_arrange_registers(registers,nodesetaddress->nodeNr+nodesetsubaddress->nodeNr); /**we fille the pcilib_t struct*/ pcilib_add_registers(pci,nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,registers); + pci->xml_ctx->nb_registers+=nodesetaddress->nodeNr+nodesetsubaddress->nodeNr; } @@ -460,7 +455,7 @@ int pcilib_init_xml(pcilib_t* ctx, char* model){ xmlDocPtr* docs; DIR* rep=NULL; struct dirent* file=NULL; - int err; + int err, err_count=0; path=malloc(sizeof(char*)); line=malloc(sizeof(char*)); @@ -469,8 +464,7 @@ int pcilib_init_xml(pcilib_t* ctx, char* model){ /** we first get the env variable corresponding to the place of the xml files*/ path=getenv("PCILIB_MODEL_DIR"); if(path==NULL){ - pcilib_warning("can't find environment variable for xml files"); - return 1; + path=PCILIB_MODEL_DIR; } /** we then open the directory corresponding to the ctx model*/ @@ -478,7 +472,7 @@ int pcilib_init_xml(pcilib_t* ctx, char* model){ sprintf(pwd,"%s%s/",path,model); if((rep=opendir(pwd))==NULL){ pcilib_warning("could not open the directory for xml files: error %i\n",errno); - return 1; + return PCILIB_ERROR_NOTINITIALIZED; } /** we iterate through the files of the directory, to get the xml files and the xsd file*/ @@ -497,33 +491,45 @@ int pcilib_init_xml(pcilib_t* ctx, char* model){ if(line_xsd==NULL){ pcilib_warning("no xsd file found"); - return 1; + return PCILIB_ERROR_NOTINITIALIZED; } if(line[0]==NULL){ pcilib_warning("no xml file found"); - return 1; + return PCILIB_ERROR_NOTINITIALIZED; } /** for each xml file, we validate it, and get the registers and the banks*/ docs=malloc((i-1)*sizeof(xmlDocPtr)); + ctx->xml_ctx=malloc(sizeof(pcilib_xml_context_t)); + ctx->xml_ctx->docs=malloc(sizeof(xmlDocPtr)*(i-1)); + ctx->xml_ctx->nb_registers=0; + ctx->xml_ctx->nb_new_banks=0; + + if(!(ctx->xml_ctx) || !(ctx->xml_ctx->docs)) + return PCILIB_ERROR_MEMORY; + + for(k=0;kxml_context=malloc(sizeof(pcilib_xml_context_t)); - ctx->xml_context->docs=malloc(sizeof(xmlDocPtr)*(i-1)); - ctx->xml_context->docs=docs; + + ctx->xml_ctx->docs=docs; free(pwd); free(line); free(line_xsd); + if(err_count>0) return PCILIB_ERROR_NOTINITIALIZED; return 0; } @@ -531,11 +537,15 @@ int pcilib_init_xml(pcilib_t* ctx, char* model){ * this function free the xml parts of the pcilib_t running, and some libxml ashes * @param[in] pci the pcilib_t running */ -void pcilib_clean_xml(pcilib_t* pci){ - - free(pci->xml_banks); - free(pci->xml_registers); - free(pci->xml_context); +void pcilib_free_xml(pcilib_t* pci){ + + free(pci->xml_ctx->xml_banks); + free(pci->xml_ctx->xml_registers); + pci->xml_ctx->xml_banks=NULL; + pci->xml_ctx->xml_registers=NULL; + free(pci->xml_ctx); + pci->xml_ctx=NULL; + xmlCleanupParser(); xmlMemoryDump(); -- cgit v1.2.3