From 6a8b4a516689daa34951ccca841c2a4f57412b0e Mon Sep 17 00:00:00 2001 From: "nicolas.zilio@hotmail.fr" <> Date: Tue, 15 Sep 2015 09:34:52 +0200 Subject: first compil ok with addition of generic views --- pcilib/register.h | 1 + pcilib/views.c | 153 ++++++++++++++++-------------------------------------- pcilib/views.h | 7 ++- pcilib/xml.c | 140 +++++++++++++++++++------------------------------ 4 files changed, 106 insertions(+), 195 deletions(-) (limited to 'pcilib') diff --git a/pcilib/register.h b/pcilib/register.h index 5669237..2f6334c 100644 --- a/pcilib/register.h +++ b/pcilib/register.h @@ -50,6 +50,7 @@ typedef struct { pcilib_xml_node_t *xml; /**< Additional XML properties */ pcilib_view_formula_t *formulas; /**< list of views of type formula linked to this register*/ pcilib_view_enum_t *enums; /**< list of views of type enum linked to this register*/ + pcilib_view_t *views; /** list of views linked to this register*/ } pcilib_register_context_t; diff --git a/pcilib/views.c b/pcilib/views.c index 0e3d26d..2a0969c 100644 --- a/pcilib/views.c +++ b/pcilib/views.c @@ -242,7 +242,6 @@ int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const { int i,j,err=0; pcilib_register_value_t temp_value; - char* formula; /* we get the index of the register to find the corresponding register context*/ if((i=pcilib_find_register(ctx,bank,regname))==PCILIB_REGISTER_INVALID){ @@ -256,59 +255,27 @@ int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const pcilib_error("can't read the register %s value before applying views : error %i",regname); return PCILIB_ERROR_INVALID_REQUEST; } - /*in the case we don't ask for a view's name, we know it will be for views of type enum. Especially, it's faster to search directly on the values of those views instead of a given name. - we iterate so through the views of type enum to verify if the value we have corresponds to an enum command*/ - if(!(unit)){ - for(j=0; ctx->register_ctx[i].enums[j].value;j++){ - if((temp_value >= ctx->register_ctx[i].enums[j].min) && (temp_value <= ctx->register_ctx[i].enums[j].max)){ - value_size=strlen(ctx->register_ctx[i].enums[j].name)*sizeof(char); - value=(char*)realloc(value,sizeof(value_size)); - if(!(value)){ - pcilib_error("can't allocate memory for the returning value of the view"); - return PCILIB_ERROR_MEMORY; + + for(j=0;ctx->register_ctx[i].views[j].name;j++){ + if(!(strcasecmp(ctx->register_ctx[i].views[j].base_unit.name,unit))){/*if we asked for the unit "name"*/ + err=ctx->register_ctx[i].views[j].op(ctx,ctx->register_ctx[i].views[j].parameters,value/*the command name*/,0,&temp_value,0,&(ctx->register_ctx[i].views[j])); + if(err){ + pcilib_error("can't write to the register with the enum view"); + return PCILIB_ERROR_FAILED; } - /* in the case the value of register is between min and max, then we return the correponding enum command*/ - strncpy((char*)value,ctx->register_ctx[i].enums[j].name, strlen(ctx->register_ctx[i].enums[j].name)); - /* make sure the string is correctly terminated*/ - ((char*)value)[value_size]='\0'; - return 0; - } - } - pcilib_warning("the value of the register asked do not correspond to any enum views"); - return PCILIB_ERROR_NOTAVAILABLE; - } - - /** in the other case we ask for a view of type formula. Indeed, wa can't directly ask for a formula, so we have to provide a name for those views*/ - j=0; - if(!(strcasecmp(unit, ctx->register_ctx[i].formulas[0].base_unit.name))){ - formula=malloc(sizeof(char)*strlen(ctx->register_ctx[i].formulas[0].read_formula)); - if(!(formula)){ - pcilib_error("can't allocate memory for the formula"); - return PCILIB_ERROR_MEMORY; + break; + }else if(!(strcasecmp(ctx->register_ctx[i].views[j].name,(char*)unit))){/*in this case we asked for the name of the view in unit*/ + err=ctx->register_ctx[i].views[j].op(ctx,ctx->register_ctx[i].views[j].parameters,(char*)unit, 0, &temp_value,0,&(ctx->register_ctx[i].views[j])); + if(err){ + pcilib_error("can't write to the register with the formula view %s", unit); + return PCILIB_ERROR_FAILED; } - strncpy(formula,ctx->register_ctx[i].formulas[0].read_formula,strlen(ctx->register_ctx[i].formulas[0].read_formula)); - pcilib_view_apply_formula(ctx,formula,temp_value,value,0); - value_size=sizeof(int); - return 0; - } - - for(j=0; ctx->register_ctx[i].formulas[0].base_unit.other_units[j].name;j++){ - if(!(strcasecmp(ctx->register_ctx[i].formulas[0].base_unit.other_units[j].name,unit))){ - /* when we have found the correct view of type formula, we apply the formula, that get the good value for return*/ - formula=malloc(sizeof(char)*strlen(ctx->register_ctx[i].formulas[0].read_formula)); - if(!(formula)){ - pcilib_error("can't allocate memory for the formula"); - return PCILIB_ERROR_MEMORY; + *(pcilib_register_value_t*)value=temp_value; + break; } - strncpy(formula,ctx->register_ctx[i].formulas[0].read_formula,strlen(ctx->register_ctx[i].formulas[0].read_formula)); - pcilib_view_apply_formula(ctx,formula,temp_value,value,0); - pcilib_view_apply_unit(ctx->register_ctx[i].formulas[0].base_unit.other_units[j],unit,value); - value_size=sizeof(int); - return 0; + return 0; } - } - - pcilib_warning("the view asked and the register do not correspond"); + pcilib_error("the view asked and the register do not correspond"); return PCILIB_ERROR_NOTAVAILABLE; } @@ -319,7 +286,6 @@ int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, const char *unit, size_t value_size,void* value){ int i,j; pcilib_register_value_t temp_value; - char *formula; int err; /* we get the index of the register to find the corresponding register context*/ @@ -328,17 +294,17 @@ int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, cons return PCILIB_ERROR_INVALID_REQUEST; } - for(j=0;ctx>register_ctx[i].views[j].name;j++){ - if(!(strcasecmp(ctx->register_ctx[i].views[j].base_unit,unit))){ - err=ctx->register_ctx[i].views[j].op(ctx,ctx->register_ctx[i].views[j].parameters,unit,1,&temp_value,value); - temp_value=ctx->register_ctx[i].views[value].value; + for(j=0;ctx->register_ctx[i].views[j].name;j++){ + if(!(strcasecmp(ctx->register_ctx[i].views[j].base_unit.name,unit))){/*if we asked for the unit "name"*/ + err=ctx->register_ctx[i].views[j].op(ctx,ctx->register_ctx[i].views[j].parameters,value/*the command name*/,1,&temp_value,0,&(ctx->register_ctx[i].views[j])); if(err){ pcilib_error("can't write to the register with the enum view"); return PCILIB_ERROR_FAILED; } break; - }else if(!(strcasecmp(ctx->register_ctx[i].views[j].name,unit))){ - err=ctx->register_ctx[i].views[j].op(ctx,ctx->register_ctx[i].views[j].parameters, unit, 1, &temp_value,0,&(ctx->register_ctx[i].views[j])); + }else if(!(strcasecmp(ctx->register_ctx[i].views[j].name,(char*)unit))){/*in this case we asked for then name of the view in unit*/ + temp_value=*(pcilib_register_value_t*)value /*the value to put in the register*/; + err=ctx->register_ctx[i].views[j].op(ctx,ctx->register_ctx[i].views[j].parameters, (char*)unit, 1, &temp_value,0,&(ctx->register_ctx[i].views[j])); if(err){ pcilib_error("can't write to the register with the formula view %s", unit); return PCILIB_ERROR_FAILED; @@ -349,73 +315,46 @@ int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, cons return 0; } - - /*here, in the case of views of type enum, view will correspond to the enum command. - we iterate so through the views of type enum to get the value corresponding to the enum command* - for(j=0; ctx->register_ctx[i].enums[j].name;j++){ - /* we should maybe have another to do it there* - if(!(strcasecmp(ctx->register_ctx[i].enums[j].name,unit))){ - pcilib_write_register(ctx,bank,regname,ctx->register_ctx[i].enums[j].value); - return 0; - } - } - - /** in the other case we ask for a view of type formula. Indeed, wa can't directly ask for a formula, so we have to provide a name for those views in view, and the value we want to write in value*/ - /* j=0; - if(!(strcasecmp(unit, ctx->register_ctx[i].formulas[0].base_unit.name))){ - formula=malloc(sizeof(char)*strlen(ctx->register_ctx[i].formulas[0].write_formula)); - strncpy(formula,ctx->register_ctx[i].formulas[0].write_formula,strlen(ctx->register_ctx[i].formulas[0].write_formula)); - pcilib_view_apply_formula(ctx,formula,*(pcilib_register_value_t*)value,&temp_value,1); - pcilib_write_register(ctx,bank,regname,temp_value); - return 0; - } - - for(j=0; ctx->register_ctx[i].formulas[0].base_unit.other_units[j].name;j++){ - if(!(strcasecmp(ctx->register_ctx[i].formulas[0].base_unit.other_units[j].name,unit))){ - /* when we have found the correct view of type formula, we apply the formula, that get the good value for return* - formula=malloc(sizeof(char)*strlen(ctx->register_ctx[i].formulas[0].write_formula)); - strncpy(formula,ctx->register_ctx[i].formulas[0].write_formula,strlen(ctx->register_ctx[i].formulas[0].write_formula)); - pcilib_view_apply_unit(ctx->register_ctx[i].formulas[0].base_unit.other_units[j],unit,value); - pcilib_view_apply_formula(ctx,formula,*(pcilib_register_value_t*)value,&temp_value,1); - /* we maybe need some error checking there , like temp_value >min and ((pcilib_view_enum_t*)(params))[j].min){ - viewval=(char*)realloc(viewval,strlen(((pcilib_view_enum_t*)(params))[j].name)*sizeof(char)); - strncpy((char*)viewval,((pcilib_view_enum_t*)(params))[j].name, strlen(((pcilib_view_enum_t*)(params))[j].name)); + name=(char*)realloc(name,strlen(((pcilib_view_enum_t*)(params))[j].name)*sizeof(char)); + strncpy(name,((pcilib_view_enum_t*)(params))[j].name, strlen(((pcilib_view_enum_t*)(params))[j].name)); k=strlen(((pcilib_view_enum_t*)(params))[j].name); - ((char*)regval)[k]='\0'; + name[k]='\0'; return 0; } } } - return -1; + return PCILIB_ERROR_INVALID_REQUEST; } -/** viewsval=the current view, params=current view parameters*/ -int operation_formula(pcilib_t *ctx, void *params/*name*/, char* unit, int read_or_write, pcilib_register_value_t *regval, size_t viewval_size, void* viewval){ +/** + * pârams: view params unit=unit wanted regval:value before formula/after formula viewval=view + */ +int operation_formula(pcilib_t *ctx, void *params, char* unit, int view2reg, pcilib_register_value_t *regval, size_t viewval_size, void* viewval){ int j=0; - char* formula; pcilib_register_value_t value=0; + char* formula; - if(read_or_write==0){ + if(view2reg==0){ if(!(strcasecmp(unit, ((pcilib_view_t*)viewval)->base_unit.name))){ formula=malloc(sizeof(char)*strlen(((pcilib_formula_t*)params)->read_formula)); if(!(formula)){ @@ -441,8 +380,7 @@ int operation_formula(pcilib_t *ctx, void *params/*name*/, char* unit, int read_ return value; } } - }else if(read_or_write==1){ - j=0; + }else if(view2reg==1){ if(!(strcasecmp(unit, ((pcilib_view_t*)viewval)->base_unit.name))){ formula=malloc(sizeof(char)*strlen(((pcilib_formula_t*)params)->write_formula)); strncpy(formula,((pcilib_formula_t*)params)->write_formula,strlen(((pcilib_formula_t*)params)->write_formula)); @@ -457,12 +395,13 @@ int operation_formula(pcilib_t *ctx, void *params/*name*/, char* unit, int read_ strncpy(formula,((pcilib_formula_t*)params)->write_formula,strlen((( pcilib_formula_t*)params)->write_formula)); pcilib_view_apply_unit(((pcilib_view_t*)viewval)->base_unit.other_units[j],unit,&value); pcilib_view_apply_formula(ctx,formula,*regval,&value,1); + *regval=value; /* we maybe need some error checking there , like temp_value >min and units[j].name;j++){ - if(!(strcasecmp(base_unit,ctx->units[j].name))){ - myview->base_unit=ctx->units[j]; - break; + if((strcasecmp(base_unit,"name"))){ + for(j=0;ctx->units[j].name;j++){ + if(!(strcasecmp(base_unit,ctx->units[j].name))){ + myview->base_unit=ctx->units[j]; + break; + } + } } - } - } /** @@ -114,44 +114,23 @@ pcilib_get_associated_views(pcilib_t* ctx, const char* reg_name,xmlXPathContextP else sprintf(path,VIEWS_NAME_PATH_BITS,reg_name); nodes = xmlXPathEvalExpression((xmlChar*)path, xpath); nodeset = nodes->nodesetval; + ctx->register_ctx[id].views=malloc(sizeof(pcilib_view_t)); + if(!(ctx->register_ctx[id].views)){ + pcilib_error("error allocating memory for enum views in register context %i",id); + return PCILIB_ERROR_MEMORY; + } + if (!xmlXPathNodeSetIsEmpty(nodeset)) { - int i,k,l; + int i,k; /*if we correctly get a nodeset, then we iterate through the nodeset to get all views, using their names*/ for (i = 0; i < nodeset->nodeNr; i++) { view_name=(char*)nodeset->nodeTab[i]->children->content; /* if the view name obtained is for an enum view, we get all pcilib_view_enum_t corresponding to the register*/ - for(k=0; ctx->enum_views[k].enums_list[0].value; k++){ - if(!(strcasecmp(view_name, ctx->enum_views[k].name))){ - ctx->register_ctx[id].enums=malloc(sizeof(pcilib_view_enum_t)); - - if(!(ctx->register_ctx[id].enums)){ - pcilib_error("error allocating memory for enum views in register context %i",id); - return PCILIB_ERROR_MEMORY; - } - - /*!!!!!!!!!!this loop here is buggy*/ - for(l=0; ctx->enum_views[k].enums_list[l].value;l++){ - ctx->register_ctx[id].enums=realloc(ctx->register_ctx[id].enums,(l+1)*sizeof(pcilib_view_enum_t)); - ctx->register_ctx[id].enums[l]=ctx->enum_views[k].enums_list[l]; - // printf("names %s %s\n",ctx->register_ctx[id].enums[l].name,ctx->enum_views[k].enums_list[l].name); - } - return 0; - } - } - - /*here it is for formula, i assume we have only one formula view per register*/ - for(k=0; ctx->formula_views[k].name;k++){ - if(!(strcasecmp(view_name,ctx->formula_views[k].name))){ - - ctx->register_ctx[id].formulas=malloc(sizeof(pcilib_view_formula_t)); - if(!(ctx->register_ctx[id].formulas)){ - pcilib_error("error allocating memory for formula views in register context %i",id); - return PCILIB_ERROR_MEMORY; - } - pcilib_get_unit_of_view(ctx,&(ctx->formula_views[k]),ctx->formula_views[k].base_unit.name); - ctx->register_ctx[id].formulas[0]=ctx->formula_views[k]; - break; + for(k=0; ctx->views[k].name; k++){ + if(!(strcasecmp(view_name, ctx->views[k].name))){ + ctx->register_ctx[id].views=realloc(ctx->register_ctx[id].views,(k+1)*sizeof(pcilib_view_enum_t)); + ctx->register_ctx[id].views[k]=ctx->views[k]; } } @@ -563,9 +542,7 @@ pcilib_xml_create_unit(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, x static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { int err; - pcilib_view_enum2_t complete_enum_desc={0}; - pcilib_view_enum_t enum_desc = {0}; - pcilib_view_formula_t formula_desc= {0}; + pcilib_view_t desc={0}; xmlNodePtr cur; char *value, *name; char *endptr; @@ -573,32 +550,17 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo int i=0; int ok_min=0, ok_max=0; - /*must i initialize? i think it's only needed if we want to include a description property*/ - enum_desc.name="default"; - enum_desc.value=0; - enum_desc.min=0; - enum_desc.max=0; - - complete_enum_desc.name="default enum"; - complete_enum_desc.description="default description"; - complete_enum_desc.enums_list=malloc(sizeof(pcilib_view_enum_t)); - if(!(complete_enum_desc.enums_list)){ - pcilib_error("can't allocate memory for the complete enum type"); - return PCILIB_ERROR_MEMORY; - } - complete_enum_desc.enums_list[0]=enum_desc; - - formula_desc.name="formula_default"; - formula_desc.read_formula="@reg"; - formula_desc.write_formula="@reg"; - formula_desc.description="default description"; - + desc.description="default description"; + /* we get the attribute type of the view node*/ attr=node->properties; value=(char*)attr->children->content; /* regarding the architecture, i decided to follow what has been done for registers and banks. but without the context*/ /*if the view is of type enum, we get recursively its properties and then populate ctx enum views*/ if(!(strcasecmp(value,"enum"))){ + desc.op=&operation_enum; + desc.parameters=malloc(sizeof(pcilib_view_enum_t)); + desc.base_unit.name="name"; for (cur = node->children; cur != NULL; cur = cur->next) { if (!cur->children) continue; if (!xmlNodeIsText(cur->children)) continue; @@ -608,15 +570,15 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo if (!value) continue; if (!(strcasecmp((char*)name,"name"))) { - complete_enum_desc.name = value; + desc.name = value; }else if (!(strcasecmp((char*)name,"description"))) { - complete_enum_desc.description = value; + desc.description = value; }else if (!(strcasecmp((char*)name,"enum"))) { - complete_enum_desc.enums_list=realloc(complete_enum_desc.enums_list,(i+1)*sizeof(pcilib_view_enum_t)); - complete_enum_desc.enums_list[i].name=value; + desc.parameters=realloc(desc.parameters,(i+1)*sizeof(pcilib_view_enum_t)); + ((pcilib_view_enum_t*)(desc.parameters))[i].name=value; /* we need to iterate through the different attributes of an enum node to get all properties*/ for(attr=cur->properties; attr!=NULL;attr=attr->next){ @@ -632,14 +594,14 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo pcilib_error("Invalid value (%s) is specified in the XML enum node", value); return PCILIB_ERROR_INVALID_DATA; } - complete_enum_desc.enums_list[i].value=dat_value; + ((pcilib_view_enum_t*)(desc.parameters))[i].value=dat_value; }else if(!(strcasecmp(name,"min"))){ pcilib_register_value_t dat_min = strtol(value, &endptr, 0); if ((strlen(endptr) > 0)) { pcilib_error("Invalid min (%s) is specified in the XML enum node", value); return PCILIB_ERROR_INVALID_DATA; } - complete_enum_desc.enums_list[i].min=dat_min; + ((pcilib_view_enum_t*)(desc.parameters))[i].min=dat_min; ok_min=1; }else if(!(strcasecmp(name,"max"))){ pcilib_register_value_t dat_max = strtol(value, &endptr, 0); @@ -647,24 +609,26 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo pcilib_error("Invalid max (%s) is specified in the XML enum node", value); return PCILIB_ERROR_INVALID_DATA; } - complete_enum_desc.enums_list[i].max=dat_max; + ((pcilib_view_enum_t*)(desc.parameters))[i].max=dat_max; ok_max=1; } - if(ok_min==0) complete_enum_desc.enums_list[i].min=complete_enum_desc.enums_list[i].value; - if(ok_max==0) complete_enum_desc.enums_list[i].max=complete_enum_desc.enums_list[i].value; + if(ok_min==0) ((pcilib_view_enum_t*)(desc.parameters))[i].min=((pcilib_view_enum_t*)(desc.parameters))[i].value; + if(ok_max==0) ((pcilib_view_enum_t*)(desc.parameters))[i].max=((pcilib_view_enum_t*)(desc.parameters))[i].value; } i++; } } - err=pcilib_add_views_enum(ctx,1,&complete_enum_desc); + err=pcilib_add_views(ctx,1,&desc); if (err) { - pcilib_error("Error (%i) adding a new enum view (%s) to the pcilib_t", err, complete_enum_desc.name); + pcilib_error("Error (%i) adding a new enum view (%s) to the pcilib_t", err, desc.name); return err; } /* we do the same here but for a iew of type formula if the attribute gives formula*/ }else if(!(strcasecmp(value,"formula"))){ + desc.op=&operation_formula; + desc.parameters=malloc(sizeof(pcilib_formula_t)); for (cur = node->children; cur != NULL; cur = cur->next) { if (!cur->children) continue; if (!xmlNodeIsText(cur->children)) continue; @@ -675,21 +639,21 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo if (!value) continue; if (!(strcasecmp((char*)name,"name"))) { - formula_desc.name = value; + desc.name = value; }else if (!(strcasecmp((char*)name,"read_from_register"))) { - formula_desc.read_formula=value; + ((pcilib_formula_t*)(desc.parameters))->read_formula=value; }else if (!(strcasecmp((char*)name,"write_to_register"))) { - formula_desc.write_formula=value; + ((pcilib_formula_t*)(desc.parameters))->write_formula=value; }else if (!(strcasecmp((char*)name,"description"))) { - formula_desc.description=value; + desc.description=value; }else if (!(strcasecmp((char*)name,"unit"))){ - formula_desc.base_unit.name=value; + desc.base_unit.name=value; } } - err=pcilib_add_views_formula(ctx,1,&formula_desc); + err=pcilib_add_views(ctx,1,&desc); if (err) { - pcilib_error("Error (%i) adding a new formula view (%s) to the pcilib_t", err, formula_desc.name); + pcilib_error("Error (%i) adding a new formula view (%s) to the pcilib_t", err, desc.name); return err; } @@ -868,7 +832,7 @@ int pcilib_process_xml(pcilib_t *ctx, const char *location) { struct dirent *file = NULL; char *model_dir, *model_path; - int i; + int i,j; model_dir = getenv("PCILIB_MODEL_DIR"); if (!model_dir) model_dir = PCILIB_MODEL_DIR; @@ -890,16 +854,18 @@ int pcilib_process_xml(pcilib_t *ctx, const char *location) { if (err) pcilib_error("Error processing XML file %s", file->d_name); } - for(i=0;inum_formula_views;i++){ - pcilib_get_unit_of_view(ctx,&(ctx->formula_views[i]),ctx->formula_views[i].base_unit.name); + for(i=0;inum_views;i++){ + pcilib_get_unit_of_view(ctx,&(ctx->views[i]),ctx->views[i].base_unit.name); } for(i=0;inum_reg;i++){ - if(ctx->register_ctx[i].formulas){ - pcilib_get_unit_of_view(ctx,&(ctx->register_ctx[i].formulas[0]),ctx->register_ctx[i].formulas[0].base_unit.name); + for(j=0;jnum_views;j++){ + if(!(ctx->register_ctx[i].views[j].name)) break; + if(ctx->register_ctx[i].views){ + pcilib_get_unit_of_view(ctx,&(ctx->register_ctx[i].views[j]),ctx->register_ctx[i].views[j].base_unit.name); + } } } - closedir(rep); -- cgit v1.2.3