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;
}
Beispiel #2
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;
}
Beispiel #5
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;
}