#include #include "pci.h" /** * new type to define an enum view */ pcilib_value_enum_s { const char *name; /**registers[k].bits;k++){ if(!(strcasecmp(reg_name,ctx->registers[k].name))){ return ctx->banks[pcilib_find_register_bank_by_addr(ctx,ctx->registers[k].bank)].name; } } } /** * replace plain registers name in a formula by their value */ static int pcilib_view_compute_plain_registers(pcilib_t* ctx, char* formula){ int j,k; char* substr,substr2; char temp[66]; pcilib_register_value_t value; /*we get recursively all registers of string , and if they are not equel to '@reg', then we get their value and put it in formula*/ for(j=0;j>> import re >>> m = re.search('(?<=@)\w+', formula) >>> m.group(0) */ char reg_value_string[66]; /* to register reg_value as a string, need to check the length*/ sprintf(reg_value_string,"%lu",reg_value); /*computation of plain registers in the formula*/ formula=pcilib_view_formula_compute_plain_registers(formula,ctx); /* computation of @reg with register value*/ formula=pcilib_view_formula_replace(formula,"@reg",reg_value_string); /* evaluation of the formula*/ *out_value=*(pcilib_register_value_t*) pcilib_view_eval_formula(formula); } int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view/*, const char *unit*/, size_t value_size, void *value) { int i,j,err; pcilib_register_value_t temp_value; /* we get the index of the register to find the corresponding register context*/ if((i=pcilib_find_register(ctx,bank,regname))==PCILIB_REGISTER_INVALID){ pcilib_error("can't get the index of the register %s", regname); return PCILIB_ERROR_INVALID_REQUEST; } /* we get the value of the register, as we will apply the view on it*/ if((err==pcilib_read_register_by_id(ctx,i,&temp_value))>0){ pcilib_error("can't read the register %s value before applying views",regname); } /*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(!(view)){ 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=malloc(sizeof(value_size)); if(!(value)){ pcilib_error("can't allocate memory for the returning value of the view %s",view); return PCILIB_ERROR_MEMORY; } /* in the case the value of register is between min and max, then we return the correponding enum command*/ value=*(char*)ctx->register_ctx[i].enums[j].name; 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; while((ctx->register_ctx[i].formulas[j].name)){ if(!(strcasecmp(ctx->register_ctx[i].formulas[j].name))){ /* when we have found the correct view of type formula, we apply the formula, that get the good value for return*/ pcilib_view_apply_formula(ctx, ctx->register_ctx[i].formulas[j].read_formula,temp_value,value); value_size=sizeof(int); return 0; } j++; } pcilib_warning("the view asked and the register do not correspond"); return PCILIB_ERROR_NOTAVAILABLE; } int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view/*, const char *unit*/, size_t value_size, void *value){