예제 #1
0
static void dbRecordField(char *name,char *value)
{
    DBENTRY		*pdbentry;
    tempListNode	*ptempListNode;
    long		status;

    if(duplicate) return;
    ptempListNode = (tempListNode *)ellFirst(&tempList);
    pdbentry = ptempListNode->item;
    status = dbFindField(pdbentry,name);
    if(status) {
	epicsPrintf("Record \"%s\" does not have a field \"%s\"\n", 
                    dbGetRecordName(pdbentry), name);
	yyerror(NULL);
	return;
    }
    dbTranslateEscape(value, value);    /* yuck: in-place, but safe */
    status = dbPutString(pdbentry,value);
    if(status) {
	epicsPrintf("Can't set \"%s.%s\" to \"%s\"\n",
                    dbGetRecordName(pdbentry), name, value);
	yyerror(NULL);
	return;
    }
}
예제 #2
0
파일: asTestLib.c 프로젝트: ukaea/epics
static void hookPass1(initHookState state)
{
    DBENTRY entry;
    DBADDR  addr;
    if(state!=initHookAfterInitDatabase)
        return;
    testDiag("initHookAfterInitDatabase");

    dbInitEntry(pdbbase, &entry);

    if(dbFindRecord(&entry, "rec0.VAL")==0) {
        aoRecord *prec = entry.precnode->precord;
        testOk(prec->val==3, "VAL %d==3 (init_record value)", (int)prec->val);
        testOk1(dbPutString(&entry, "4")==0);
        testOk(prec->val==4, "VAL %d==4", (int)prec->val);
    } else{
        testFail("Missing rec0");
        testSkip(1, "missing record");
    }

    /* Can't restore links in pass 1 */

    if(dbNameToAddr("rec1.VAL", &addr)) {
        testFail("missing rec1");
        testSkip(3, "missing record");
    } else {
        struct rset *prset = dbGetRset(&addr);
        dbfType ftype = addr.field_type;
        long count=-1, offset=-1, maxcount = addr.no_elements;
        testOk1(prset && prset->get_array_info && prset->put_array_info);
        testOk1((*prset->get_array_info)(&addr, &count, &offset)==0);
        /* count is ignored */
        testOk1((*dbPutConvertRoutine[DBF_DOUBLE][ftype])(&addr, values, NELEMENTS(values), maxcount,offset)==0);
        testOk1((*prset->put_array_info)(&addr, NELEMENTS(values))==0);
    }

    dbFinishEntry(&entry);
}
예제 #3
0
파일: asTestLib.c 프로젝트: ukaea/epics
static void hookPass0(initHookState state)
{
    DBENTRY entry;
    if(state!=initHookAfterInitDevSup)
        return;
    testDiag("initHookAfterInitDevSup");

    dbInitEntry(pdbbase, &entry);

    testDiag("restore integer pass0");
    /* rec0.VAL is initially 1, set it to 2 */
    if(dbFindRecord(&entry, "rec0.VAL")==0) {
        aoRecord *prec = entry.precnode->precord;
        testOk(prec->val==1, "VAL %d==1 (initial value from .db)", (int)prec->val);
        checkGetString(&entry, "1");
        testOk1(dbPutString(&entry, "2")==0);
        testOk(prec->val==2, "VAL %d==2", (int)prec->val);
        checkGetString(&entry, "2");
    } else {
        testFail("Missing rec0");
        testSkip(4, "missing record");
    }

    testDiag("restore string pass0");
    if(dbFindRecord(&entry, "rec0.DESC")==0) {
        aoRecord *prec = entry.precnode->precord;
        testOk1(strcmp(prec->desc, "foobar")==0);
        checkGetString(&entry, "foobar");
        testOk1(dbPutString(&entry, "hello")==0);
        testOk1(strcmp(prec->desc, "hello")==0);
        checkGetString(&entry, "hello");
    } else {
        testFail("Missing rec0");
        testSkip(4, "missing record");
    }

    if(dbFindRecord(&entry, "rec1.DESC")==0) {
        aoRecord *prec = entry.precnode->precord;
        testOk1(strcmp(prec->desc, "")==0);
        checkGetString(&entry, "");
        testOk1(dbPutString(&entry, "world")==0);
        testOk1(strcmp(prec->desc, "world")==0);
        checkGetString(&entry, "world");
    } else {
        testFail("Missing rec1");
        testSkip(4, "missing record");
    }

    testDiag("restore link pass0");
    /* rec0.OUT is initially "rec0.DISV", set it to "rec0.SEVR" */
    if(dbFindRecord(&entry, "rec0.OUT")==0) {
        aoRecord *prec = entry.precnode->precord;
        if(prec->out.type==CONSTANT)
            testOk(strcmp(prec->out.text,"rec0.DISV")==0,
                   "%s==rec0.DISV (initial value from .db)",
                   prec->out.text);
        else
            testFail("Wrong link type: %d", (int)prec->out.type);

        /* note that dbGetString() reads an empty string before links are initialized
         * should probably be considered a bug, but has been the case for so long
         * we call it a 'feature'.
         */
        checkGetString(&entry, "");

        testOk1(dbPutString(&entry, "rec0.SEVR")==0);
    } else{
        testFail("Missing rec0");
        testSkip(1, "missing record");
    }

    /* rec0.SDIS is initially NULL, set it to "rec0.STAT" */
    if(dbFindRecord(&entry, "rec0.SDIS")==0) {
        aoRecord *prec = entry.precnode->precord;
        if(prec->sdis.type==CONSTANT)
            testOk1(prec->sdis.value.constantStr==NULL);
        else
            testFail("Wrong link type: %d", (int)prec->sdis.type);

        testOk1(dbPutString(&entry, "rec0.STAT")==0);
    } else{
        testFail("Missing rec0");
        testSkip(1, "missing record");
    }

    /* can't restore array field in pass0 */

    dbFinishEntry(&entry);
}
예제 #4
0
static long dbPutFieldLink(DBADDR *paddr,
    short dbrType, const void *pbuffer, long nRequest)
{
    dbCommon    *precord = paddr->precord;
    dbFldDes    *pfldDes = paddr->pfldDes;
    long        special = paddr->special;
    DBLINK      *plink = (DBLINK *)paddr->pfield;
    const char  *pstring = (const char *)pbuffer;
    DBENTRY     dbEntry;
    DBADDR      dbaddr;
    struct dsxt *old_dsxt = NULL;
    struct dset *new_dset = NULL;
    struct dsxt *new_dsxt = NULL;
    long        status;
    int         isDevLink;
    short       scan;

    switch (dbrType) {
    case DBR_CHAR:
    case DBR_UCHAR:
        if (pstring[nRequest - 1] != '\0')
            return S_db_badDbrtype;
        break;

    case DBR_STRING:
        break;

    default:
        return S_db_badDbrtype;
    }

    dbInitEntry(pdbbase, &dbEntry);
    status = dbFindRecord(&dbEntry, precord->name);
    if (!status) status = dbFindField(&dbEntry, pfldDes->name);
    if (status) goto finish;

    isDevLink = ellCount(&precord->rdes->devList) > 0 &&
                (strcmp(pfldDes->name, "INP") == 0 ||
                 strcmp(pfldDes->name, "OUT") == 0);

    dbLockSetGblLock();
    dbLockSetRecordLock(precord);

    scan = precord->scan;

    if (isDevLink) {
        devSup *pdevSup = dbDTYPtoDevSup(precord->rdes, precord->dtyp);
        if (pdevSup) {
            new_dset = pdevSup->pdset;
            new_dsxt = pdevSup->pdsxt;
        }

        if (precord->dset) {
            pdevSup = dbDSETtoDevSup(precord->rdes, precord->dset);
            if (pdevSup)
                old_dsxt = pdevSup->pdsxt;
        }

        if (new_dsxt == NULL ||
            new_dsxt->add_record == NULL ||
            (precord->dset && old_dsxt == NULL) ||
            (old_dsxt && old_dsxt->del_record == NULL)) {
            status = S_db_noSupport;
            goto unlock;
        }

        if (scan == menuScanI_O_Intr) {
            scanDelete(precord);
            precord->scan = menuScanPassive;
        }

        if (old_dsxt) {
            status = old_dsxt->del_record(precord);
            if (status)
                goto restoreScan;
        }
    }

    switch (plink->type) { /* Old link type */
    case DB_LINK:
        free(plink->value.pv_link.pvt);
        plink->value.pv_link.pvt = 0;
        plink->type = PV_LINK;
        plink->value.pv_link.getCvt = 0;
        plink->value.pv_link.pvlMask = 0;
        plink->value.pv_link.lastGetdbrType = 0;
        dbLockSetSplit(precord);
        break;

    case CA_LINK:
        dbCaRemoveLink(plink);
        plink->type = PV_LINK;
        plink->value.pv_link.getCvt = 0;
        plink->value.pv_link.pvlMask = 0;
        plink->value.pv_link.lastGetdbrType = 0;
        break;

    case CONSTANT:
        break;  /* do nothing */

    case PV_LINK:
    case MACRO_LINK:
        break;  /* should never get here */

    default: /* Hardware address */
        if (!isDevLink) {
            status = S_db_badHWaddr;
            goto restoreScan;
        }
        break;
    }

    if (special) status = dbPutSpecial(paddr, 0);

    if (!status) status = dbPutString(&dbEntry, pstring);

    if (!status && special) status = dbPutSpecial(paddr, 1);

    if (status) {
        if (isDevLink) {
            precord->dset = NULL;
            precord->pact = TRUE;
        }
        goto postScanEvent;
    }

    if (isDevLink) {
        precord->dpvt = NULL;
        precord->dset = new_dset;
        precord->pact = FALSE;

        status = new_dsxt->add_record(precord);
        if (status) {
            precord->dset = NULL;
            precord->pact = TRUE;
            goto postScanEvent;
        }
    }

    switch (plink->type) { /* New link type */
    case PV_LINK:
        if (plink == &precord->tsel)
            recGblTSELwasModified(plink);
        plink->value.pv_link.precord = precord;

        if (!(plink->value.pv_link.pvlMask & (pvlOptCA|pvlOptCP|pvlOptCPP)) &&
            (dbNameToAddr(plink->value.pv_link.pvname, &dbaddr) == 0)) {
            /* It's a DB link */
            DBADDR      *pdbAddr;

            plink->type = DB_LINK;
            pdbAddr = dbMalloc(sizeof(struct dbAddr));
            *pdbAddr = dbaddr; /* NB: structure copy */;
            plink->value.pv_link.pvt = pdbAddr;
            dbLockSetRecordLock(pdbAddr->precord);
            dbLockSetMerge(precord, pdbAddr->precord);
        } else { /* Make it a CA link */
            char        *pperiod;

            plink->type = CA_LINK;
            if (pfldDes->field_type == DBF_INLINK) {
                plink->value.pv_link.pvlMask |= pvlOptInpNative;
            }
            dbCaAddLink(plink);
            if (pfldDes->field_type == DBF_FWDLINK) {
                pperiod = strrchr(plink->value.pv_link.pvname, '.');
                if (pperiod && strstr(pperiod, "PROC"))
                    plink->value.pv_link.pvlMask |= pvlOptFWD;
            }
        }
        break;

    case CONSTANT:
        break;

    case DB_LINK:
    case CA_LINK:
    case MACRO_LINK:
        break;  /* should never get here */

    default: /* Hardware address */
        if (!isDevLink) {
            status = S_db_badHWaddr;
            goto postScanEvent;
        }
        break;
    }
    db_post_events(precord, plink, DBE_VALUE | DBE_LOG);

restoreScan:
    if (isDevLink &&
        scan == menuScanI_O_Intr) { /* undo scanDelete() */
        precord->scan = scan;
        scanAdd(precord);
    }
postScanEvent:
    if (scan != precord->scan)
        db_post_events(precord, &precord->scan, DBE_VALUE|DBE_LOG);
unlock:
    dbLockSetGblUnlock();
finish:
    dbFinishEntry(&dbEntry);
    return status;
}