static long read_event(eventRecord *prec) { long status; char newEvent[MAX_STRING_SIZE]; if (prec->inp.type != CONSTANT) { status = dbGetLink(&prec->inp, DBR_STRING, newEvent, 0, 0); if (status) return status; if (strcmp(newEvent, prec->val) != 0) { strcpy(prec->val, newEvent); prec->epvt = eventNameToHandle(prec->val); } } prec->udf = FALSE; if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) dbGetTimeStamp(&prec->inp, &prec->time); return 0; }
static long init_record(calcoutRecord *prec, int pass) { DBLINK *plink; int i; double *pvalue; epicsEnum16 *plinkValid; short error_number; calcoutDSET *pcalcoutDSET; DBADDR dbaddr; DBADDR *pAddr = &dbaddr; rpvtStruct *prpvt; if (pass == 0) { prec->rpvt = (rpvtStruct *) callocMustSucceed(1, sizeof(rpvtStruct), "calcoutRecord"); return 0; } if (!(pcalcoutDSET = (calcoutDSET *)prec->dset)) { recGblRecordError(S_dev_noDSET, (void *)prec, "calcout:init_record"); return S_dev_noDSET; } /* must have write defined */ if ((pcalcoutDSET->number < 5) || (pcalcoutDSET->write ==NULL)) { recGblRecordError(S_dev_missingSup, (void *)prec, "calcout:init_record"); return S_dev_missingSup; } prpvt = prec->rpvt; plink = &prec->inpa; pvalue = &prec->a; plinkValid = &prec->inav; for (i = 0; i <= CALCPERFORM_NARGS; i++, plink++, pvalue++, plinkValid++) { if (plink->type == CONSTANT) { /* Don't InitConstantLink the .OUT link */ if (i < CALCPERFORM_NARGS) { recGblInitConstantLink(plink, DBF_DOUBLE, pvalue); } *plinkValid = calcoutINAV_CON; } else if (!dbNameToAddr(plink->value.pv_link.pvname, pAddr)) { /* PV resides on this ioc */ *plinkValid = calcoutINAV_LOC; } else { /* pv is not on this ioc. Callback later for connection stat */ *plinkValid = calcoutINAV_EXT_NC; prpvt->caLinkStat = CA_LINKS_NOT_OK; } } prec->clcv = postfix(prec->calc, prec->rpcl, &error_number); if (prec->clcv){ recGblRecordError(S_db_badField, (void *)prec, "calcout: init_record: Illegal CALC field"); errlogPrintf("%s.CALC: %s in expression \"%s\"\n", prec->name, calcErrorStr(error_number), prec->calc); } prec->oclv = postfix(prec->ocal, prec->orpc, &error_number); if (prec->dopt == calcoutDOPT_Use_OVAL && prec->oclv){ recGblRecordError(S_db_badField, (void *)prec, "calcout: init_record: Illegal OCAL field"); errlogPrintf("%s.OCAL: %s in expression \"%s\"\n", prec->name, calcErrorStr(error_number), prec->ocal); } prpvt = prec->rpvt; callbackSetCallback(checkLinksCallback, &prpvt->checkLinkCb); callbackSetPriority(0, &prpvt->checkLinkCb); callbackSetUser(prec, &prpvt->checkLinkCb); prpvt->cbScheduled = 0; prec->epvt = eventNameToHandle(prec->oevt); if (pcalcoutDSET->init_record) pcalcoutDSET->init_record(prec); prec->pval = prec->val; prec->mlst = prec->val; prec->alst = prec->val; prec->lalm = prec->val; prec->povl = prec->oval; return 0; }
static long special(DBADDR *paddr, int after) { calcoutRecord *prec = (calcoutRecord *)paddr->precord; rpvtStruct *prpvt = prec->rpvt; DBADDR dbaddr; DBADDR *pAddr = &dbaddr; short error_number; int fieldIndex = dbGetFieldIndex(paddr); int lnkIndex; DBLINK *plink; double *pvalue; epicsEnum16 *plinkValid; if (!after) return 0; switch(fieldIndex) { case(calcoutRecordCALC): prec->clcv = postfix(prec->calc, prec->rpcl, &error_number); if (prec->clcv){ recGblRecordError(S_db_badField, (void *)prec, "calcout: special(): Illegal CALC field"); errlogPrintf("%s.CALC: %s in expression \"%s\"\n", prec->name, calcErrorStr(error_number), prec->calc); } db_post_events(prec, &prec->clcv, DBE_VALUE); return 0; case(calcoutRecordOCAL): prec->oclv = postfix(prec->ocal, prec->orpc, &error_number); if (prec->dopt == calcoutDOPT_Use_OVAL && prec->oclv){ recGblRecordError(S_db_badField, (void *)prec, "calcout: special(): Illegal OCAL field"); errlogPrintf("%s.OCAL: %s in expression \"%s\"\n", prec->name, calcErrorStr(error_number), prec->ocal); } db_post_events(prec, &prec->oclv, DBE_VALUE); return 0; case(calcoutRecordINPA): case(calcoutRecordINPB): case(calcoutRecordINPC): case(calcoutRecordINPD): case(calcoutRecordINPE): case(calcoutRecordINPF): case(calcoutRecordINPG): case(calcoutRecordINPH): case(calcoutRecordINPI): case(calcoutRecordINPJ): case(calcoutRecordINPK): case(calcoutRecordINPL): case(calcoutRecordOUT): lnkIndex = fieldIndex - calcoutRecordINPA; plink = &prec->inpa + lnkIndex; pvalue = &prec->a + lnkIndex; plinkValid = &prec->inav + lnkIndex; if (plink->type == CONSTANT) { if (fieldIndex != calcoutRecordOUT) { recGblInitConstantLink(plink, DBF_DOUBLE, pvalue); db_post_events(prec, pvalue, DBE_VALUE); } *plinkValid = calcoutINAV_CON; } else if (!dbNameToAddr(plink->value.pv_link.pvname, pAddr)) { /* if the PV resides on this ioc */ *plinkValid = calcoutINAV_LOC; } else { /* pv is not on this ioc. Callback later for connection stat */ *plinkValid = calcoutINAV_EXT_NC; /* DO_CALLBACK, if not already scheduled */ if (!prpvt->cbScheduled) { callbackRequestDelayed(&prpvt->checkLinkCb, .5); prpvt->cbScheduled = 1; prpvt->caLinkStat = CA_LINKS_NOT_OK; } } db_post_events(prec, plinkValid, DBE_VALUE); return 0; case(calcoutRecordOEVT): prec->epvt = eventNameToHandle(prec->oevt); return 0; default: recGblDbaddrError(S_db_badChoice, paddr, "calc: special"); return(S_db_badChoice); } }
void scanAdd(struct dbCommon *precord) { int scan; /* get the list on which this record belongs */ scan = precord->scan; if (scan == menuScanPassive) return; if (scan < 0 || scan >= nPeriodic + SCAN_1ST_PERIODIC) { recGblRecordError(-1, (void *)precord, "scanAdd detected illegal SCAN value"); } else if (scan == menuScanEvent) { char* eventname; int prio; event_list *pel; eventname = precord->evnt; if (strlen(eventname) >= MAX_STRING_SIZE) { recGblRecordError(S_db_badField, (void *)precord, "scanAdd: too long EVNT value"); return; } prio = precord->prio; if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) { recGblRecordError(-1, (void *)precord, "scanAdd: illegal prio field"); return; } pel = eventNameToHandle(eventname); if (pel) addToList(precord, &pel->scan_list[prio]); } else if (scan == menuScanI_O_Intr) { ioscan_head *piosh = NULL; int prio; DEVSUPFUN get_ioint_info; if (precord->dset == NULL){ recGblRecordError(-1, (void *)precord, "scanAdd: I/O Intr not valid (no DSET) "); precord->scan = menuScanPassive; return; } get_ioint_info = precord->dset->get_ioint_info; if (get_ioint_info == NULL) { recGblRecordError(-1, (void *)precord, "scanAdd: I/O Intr not valid (no get_ioint_info)"); precord->scan = menuScanPassive; return; } if (get_ioint_info(0, precord, &piosh)) { precord->scan = menuScanPassive; return; } if (piosh == NULL) { recGblRecordError(-1, (void *)precord, "scanAdd: I/O Intr not valid"); precord->scan = menuScanPassive; return; } prio = precord->prio; if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) { recGblRecordError(-1, (void *)precord, "scanAdd: illegal prio field"); precord->scan = menuScanPassive; return; } addToList(precord, &piosh->iosl[prio].scan_list); } else if (scan >= SCAN_1ST_PERIODIC) { addToList(precord, &papPeriodic[scan - SCAN_1ST_PERIODIC]->scan_list); } return; }