static long fetch_values(aSubRecord *prec) { long status; int i; if (prec->lflg == aSubLFLG_READ) { /* Get the Subroutine Name and look it up if changed */ status = dbGetLink(&prec->subl, DBR_STRING, prec->snam, 0, 0); if (status) return status; if (prec->snam[0] != 0 && strcmp(prec->snam, prec->onam)) { GENFUNCPTR pfunc = (GENFUNCPTR)registryFunctionFind(prec->snam); if (!pfunc) return S_db_BadSub; prec->sadr = pfunc; strcpy(prec->onam, prec->snam); } } /* Get the input link values */ for (i = 0; i < NUM_ARGS; i++) { long nRequest = (&prec->noa)[i]; status = dbGetLinkValue(&(&prec->inpa)[i], (&prec->fta)[i], (&prec->a)[i], 0, &nRequest); if (nRequest > 0) (&prec->nea)[i] = nRequest; if (status) return status; } return 0; }
/** Constructor for function attribute * \param[in] pName The name of the attribute to be created; case-insensitive. * \param[in] pDescription The description of the attribute. * \param[in] pSource The symbol name for the function to be called to get the value of the parameter. * \param[in] pParam A string that will be passed to the function, typically to specify what/how to get the value. */ functAttribute::functAttribute(const char *pName, const char *pDescription, const char *pSource, const char *pParam) : NDAttribute(pName, pDescription, NDAttrSourceFunct, pSource, NDAttrUndefined, 0), pFunction(0), functionPvt(0) { static const char *functionName = "functAttribute"; /* Create the static pasynUser if not already done */ if (!pasynUserSelf) pasynUserSelf = pasynManager->createAsynUser(0,0); if (pParam) functParam = epicsStrDup(pParam); else functParam = epicsStrDup(""); if (!pSource) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: ERROR, must specify function name\n", driverName, functionName); goto error; } this->pFunction = (NDAttributeFunction)registryFunctionFind(pSource); if (!this->pFunction) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: ERROR, cannot find function %s\n", driverName, functionName, pSource); goto error; } error: return; }
static long init_record(subRecord *prec, int pass) { SUBFUNCPTR psubroutine; long status = 0; struct link *plink; int i; double *pvalue; if (pass==0) return(0); plink = &prec->inpa; pvalue = &prec->a; for (i = 0; i < INP_ARG_MAX; i++, plink++, pvalue++) { if (plink->type == CONSTANT) { recGblInitConstantLink(plink, DBF_DOUBLE, pvalue); } } if (prec->inam[0]) { /* convert the initialization subroutine name */ psubroutine = (SUBFUNCPTR)registryFunctionFind(prec->inam); if (psubroutine == 0) { recGblRecordError(S_db_BadSub, (void *)prec, "recSub(init_record)"); return S_db_BadSub; } /* invoke the initialization subroutine */ status = (*psubroutine)(prec); } if (prec->snam[0] == 0) { epicsPrintf("%s.SNAM is empty\n", prec->name); prec->pact = TRUE; return 0; } prec->sadr = (SUBFUNCPTR)registryFunctionFind(prec->snam); if (prec->sadr == NULL) { recGblRecordError(S_db_BadSub, (void *)prec, "recSub(init_record)"); return S_db_BadSub; } prec->mlst = prec->val; prec->alst = prec->val; prec->lalm = prec->val; return 0; }
static long special(DBADDR *paddr, int after) { aSubRecord *prec = (aSubRecord *)paddr->precord; if (after && prec->lflg == aSubLFLG_IGNORE) { if (prec->snam[0] == 0) return 0; prec->sadr = (GENFUNCPTR)registryFunctionFind(prec->snam); if (!prec->sadr) { recGblRecordError(S_db_BadSub, (void *)prec, prec->snam); return S_db_BadSub; } } return 0; }
static long special(DBADDR *paddr, int after) { subRecord *prec = (subRecord *)paddr->precord; if (!after) { if (prec->snam[0] == 0 && prec->pact) prec->pact = FALSE; prec->rpro = FALSE; return 0; } if (prec->snam[0] == 0) { epicsPrintf("%s.SNAM is empty\n", prec->name); prec->pact = TRUE; return 0; } prec->sadr = (SUBFUNCPTR)registryFunctionFind(prec->snam); if (prec->sadr) return 0; recGblRecordError(S_db_BadSub, (void *)prec, "subRecord(special) registryFunctionFind failed"); return S_db_BadSub; }
static void registryFunctionFindCallFunc(const iocshArgBuf *args) { printf("%p\n", (void*) registryFunctionFind(args[0].sval)); }
static long init_record(aSubRecord *prec, int pass) { GENFUNCPTR pfunc; long status; int i; status = 0; if (pass == 0) { /* Allocate memory for arrays */ initFields(&prec->fta, &prec->noa, &prec->nea, Ifldnames, &prec->a, NULL); initFields(&prec->ftva, &prec->nova, &prec->neva, Ofldnames, &prec->vala, &prec->ovla); return 0; } /* Initialize the Subroutine Name Link */ switch (prec->subl.type) { case CONSTANT: recGblInitConstantLink(&prec->subl, DBF_STRING, prec->snam); break; case PV_LINK: case DB_LINK: case CA_LINK: break; default: recGblRecordError(S_db_badField, (void *)prec, "aSubRecord(init_record) Bad SUBL link type"); return S_db_badField; } /* Initialize Input Links */ for (i = 0; i < NUM_ARGS; i++) { struct link *plink = &(&prec->inpa)[i]; switch (plink->type) { case CONSTANT: if ((&prec->noa)[i] < 2) { if (recGblInitConstantLink(plink, (&prec->fta)[i], (&prec->a)[i])) { prec->udf = FALSE; } else prec->udf = TRUE; } break; case PV_LINK: case CA_LINK: case DB_LINK: break; default: recGblRecordError(S_db_badField, (void *)prec, "aSubRecord(init_record) Illegal INPUT LINK"); status = S_db_badField; break; } } if (status) return status; /* Initialize Output Links */ for (i = 0; i < NUM_ARGS; i++) { switch ((&prec->outa)[i].type) { case CONSTANT: case PV_LINK: case CA_LINK: case DB_LINK: break; default: recGblRecordError(S_db_badField, (void *)prec, "aSubRecord(init_record) Illegal OUTPUT LINK"); status = S_db_badField; } } if (status) return status; /* Call the user initialization routine if there is one */ if (prec->inam[0] != 0) { pfunc = (GENFUNCPTR)registryFunctionFind(prec->inam); if (pfunc) { pfunc(prec); } else { recGblRecordError(S_db_BadSub, (void *)prec, "aSubRecord::init_record - INAM subr not found"); return S_db_BadSub; } } if (prec->lflg == aSubLFLG_IGNORE && prec->snam[0] != 0) { pfunc = (GENFUNCPTR)registryFunctionFind(prec->snam); if (pfunc) prec->sadr = pfunc; else { recGblRecordError(S_db_BadSub, (void *)prec, "aSubRecord::init_record - SNAM subr not found"); return S_db_BadSub; } } strcpy(prec->onam, prec->snam); prec->oval = prec->val; return 0; }
static long initConversion( const char *name, const char *bdir, const char *tdir, menuCvtMethod meth, const char *spec, void **psub) { *psub = 0; switch (meth) { case menuCvtMethodLinear: { break; } case menuCvtMethodSubroutine: { REGISTRYFUNCTION csub; if(spec[0]==0) { nerrmsg(name, "configuration error: SPEC not specified"); return -1; } csub = registryFunctionFind(spec); if (!csub) { nerrmsg(name, "configuration error: " "SPEC is not the name of a registered subroutine"); return -1; } *psub = csub; break; } case menuCvtMethod1DTable: case menuCvtMethod1DTableInverted: { csm_function *csub; char temp[BDIR_SIZE+TDIR_SIZE+SPEC_SIZE+2]; csub = csm_new_function(); if (!csub) { nerrmsg(name, "csm_new_function failed"); return -1; } sprintf(temp, "%s/%s/%s", bdir, tdir, spec); if (!csm_read_1d_table(temp, csub)) { nerrmsg(name, "configuration error: " "File %s is not a valid 1-parameter table", temp); csm_free(csub); return -1; } *psub = csub; break; } case menuCvtMethod2DTable: { csm_function *csub; char temp[BDIR_SIZE+TDIR_SIZE+SPEC_SIZE+2]; csub = csm_new_function(); if (!csub) { nerrmsg(name, "csm_new_function failed"); return -1; } sprintf(temp, "%s/%s/%s", bdir, tdir, spec); if (!csm_read_2d_table(temp, csub)) { nerrmsg(name, "configuration error: " "File %s is not a valid 2-parameter table", temp); csm_free(csub); return -1; } *psub = csub; break; } } return 0; }