diff options
| author | zilio nicolas <nicolas.zilio@kit.edu> | 2015-09-10 12:52:27 +0200 | 
|---|---|---|
| committer | zilio nicolas <nicolas.zilio@kit.edu> | 2015-09-10 12:52:27 +0200 | 
| commit | fd215e3fd7d29c2c8605d8571091dae1c4f133bc (patch) | |
| tree | 0f725ce36150ae2408b07a7a7b158d807b0facce | |
| parent | 4763e65fcf6288e94adc76a44c762a904f698e72 (diff) | |
| download | pcitool-fd215e3fd7d29c2c8605d8571091dae1c4f133bc.tar.gz pcitool-fd215e3fd7d29c2c8605d8571091dae1c4f133bc.tar.bz2 pcitool-fd215e3fd7d29c2c8605d8571091dae1c4f133bc.tar.xz pcitool-fd215e3fd7d29c2c8605d8571091dae1c4f133bc.zip  | |
towards better views i hope
| -rw-r--r-- | pcilib/register.h | 2 | ||||
| -rw-r--r-- | views.c | 263 | ||||
| -rw-r--r-- | views.h | 15 | 
3 files changed, 280 insertions, 0 deletions
diff --git a/pcilib/register.h b/pcilib/register.h index e7cbae9..9126e9f 100644 --- a/pcilib/register.h +++ b/pcilib/register.h @@ -47,6 +47,8 @@ typedef struct {      pcilib_register_bank_t bank;		/**< Reference to bank containing the register */      pcilib_register_value_t min, max;		/**< Minimum & maximum allowed values */      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_register_context_t; @@ -0,0 +1,263 @@ +/** + * new type to define an enum view + */ +pcilib_value_enum_s { +  const char *name; /**<corresponding string to value*/ +  pcilib_register_value_t value, min, max;  +}; + + +/** + * new type to define a formula view + */ +pcilib_view_formula_s { +  const char *name; /**<name of the view*/ +  const char *read_formula; /**< formula to parse to read from a register*/ +  const char *write_formula; /**<formula to parse to write to a register*/ +	// **see it later**        const char *unit; (?) +} + + +/** + * + * replace a substring within a string by another + * @param[in] txt - the string to be modified + *@param[in] before - the substring in the string that will be replaced + *@param[in] after - the new value of before substring + *@return the modified txt string + */ +char *formula_replace (const char *txt, const char *before, const char *after) +{ +	const char *pos;  +	char *return_txt;  +	size_t pos_return_txt;  +	size_t len;  +	size_t allocated_size;  +	 +	/*get the first occurence of before. then we need one time to be out of the loop to correctly set the diverses varaibles (malloc instead of realloc notably)*/ +	pos = strstr (txt, before); +	  +	if (pos == NULL) +	{ +		pcilib_warning("problem with a formula"); +	} +  +	/* get the position of this occurence*/ +	len = (size_t)pos - (size_t)txt; +	allocated_size = len + strlen (after) + 1; +	return_txt = malloc (allocated_size); +	pos_return_txt = 0; +	 +	/* we copy there the in a newly allocated string the start of txt before the "before" occurence, and then we copy after instead*/ +	strncpy (return_txt + pos_return_txt, txt, len); +	pos_return_txt += len; +	txt = pos + strlen (before); +	  +	len = strlen (after); +	strncpy (return_txt + pos_return_txt, after, len); +	pos_return_txt += len; +	 +	/* we then iterate with the same principle to all occurences of before*/ +	pos = strstr (txt, before); +	while (pos != NULL) +	{ +		len = (size_t)pos - (size_t)txt; +		allocated_size += len + strlen (after); +		return_txt = (char *)realloc (return_txt, allocated_size); +		  +		strncpy (return_txt + pos_return_txt, txt, len); +		pos_return_txt += len; +		  +		txt = pos + strlen (before); +		  +		len = strlen (after); +		strncpy (return_txt + pos_return_txt, after, len); +		pos_return_txt += len; +		pos = strstr (txt, before); +	} +	/* put the rest of txt string at the end*/ +	len = strlen (txt) + 1; +	allocated_size += len; +	return_txt = realloc (return_txt, allocated_size); +	strncpy (return_txt + pos_return_txt, txt, len); +	 +	return return_txt; +} + +/* + * function used to get the substring of a string s, from the starting and ending indexes +  * @param[in] s string containing the substring we want to extract. + * @param[in] start the start index of the substring. + * @param[in] end the ending index of the substring. + * @return the extracted substring. + */ +char *str_sub (const char *s, unsigned int start, unsigned int end) +{ +   char *new_s = NULL; + +   if (s != NULL && start < end) +   { +      new_s = malloc (sizeof (*new_s) * (end - start + 2)); +      if (new_s != NULL) +      { +         int i; + +         for (i = start; i <= end; i++) +         { +            new_s[i-start] = s[i]; +         } +         new_s[i-start] = '\0'; +      } +      else +      { +         pcilib_error("insufficient memory for string manipulation\n"); +         return NULL; +      } +   } +   return new_s; +} + +static int +pcilib_view_compute_plain_registers{ +  /* hsould i used regexp.h??? or compile everythin myself? */ +} + + + + + +/* + * this function calls the python script and the function "evaluate" in it to evaluate the given formula + *@param[in] the formula to be evaluated + *@return the integer value of the evaluated formula (maybe go to float instead) + */ +static int +pcilib_view_eval_formula(char* formula){ +/* !!!! cf !!!!*/ +  // setenv("PYTHONPATH",".",1); +   PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *presult=NULL; +   char* pythonfile; + +   /* path to the python file, we may need a way to set it, maybe with a variable like PCILIB_PYTHON_PATH*/ +   pythonfile="pythonscripts.py"; +    +   /* initialization of python interpreter*/ +   Py_Initialize(); + +   pName = PyUnicode_FromString(pythonfile); +   pModule = PyImport_Import(pName); /* get the python file*/ +	if(!pModule) { +		pcilib_error("no python file found for python evaluation of formulas\n"); +		PyErr_Print(); +		return -1; +	} +   pDict = PyModule_GetDict(pModule); /*useless but needed*/ + +   pFunc = PyDict_GetItemString(pDict, (char*)"evaluate"); /*getting of the function "evaluate" in the script*/ +   /* if the function is ok, then call it*/ +   if (PyCallable_Check(pFunc)) +   { +        /* execution of the function*/ +       pValue=Py_BuildValue("(z)",formula); +       PyErr_Print(); +       presult=PyObject_CallObject(pFunc,pValue); +       PyErr_Print(); +   } else  +   { +       PyErr_Print(); +   } +   /* remove memory*/ +   Py_DECREF(pModule); +   Py_DECREF(pName); +    +   /* close interpreter*/ +   Py_Finalize(); +    +   return PyLong_AsLong(presult); /*this function is due to python 3.3, as PyLong_AsInt was there in python 2.7 and is no more there, resulting in using cast futhermore*/ +} + + +static int +pcilib_view_apply_read_formula(pcilib_t* ctx, char* formula, pcilib_register_value_t reg_value, pcilib_register_value_t* out_value) +{ +  /* when applying a formula, we need to: +     1) compute the values of all registers present in plain name in the formulas and replace their name with their value : for example, if we have the formula" ((1./4)*(@reg - 1200)) if @freq==0 else ((3./10)*(@reg - 1000)) " we need to get the value of the register "freq" +     2) compute the "@reg" component, corresponding to the raw value of the register +     3) pass the formula to python interpreter for evaluation +     4) return the final evaluation +      +     remark: it might be worth to use python regular expression interpreter (the following return all words following @ in formula :  +         >>> 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); +  /* 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); + +} + +static int +pcilib_view_apply_write_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_read_formula(ctx->register_ctx[i].formulas[j].read_formula,temp_value, value,....); +      return 0; +    } +    j++; +   } + +  pcilib_warning("the view asked and the register do not correspond"); +  return PCILIB_ERROR_NOTAVAILABLE; +} +  +       @@ -0,0 +1,15 @@ +typedef struct pcilib_view_enum_s pcilib_view_enum_t; + +typedef struct pcilib_view_formula_s pcilib_view_formula_t; + + +/** + * function to read a register using a view + */ +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); + +/** + * function to write to a register using a view + */ +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); +  | 
