diff --git a/src/ioc/db/dbAccess.c b/src/ioc/db/dbAccess.c index 280077149..da52ccb57 100644 --- a/src/ioc/db/dbAccess.c +++ b/src/ioc/db/dbAccess.c @@ -325,7 +325,8 @@ static void get_alarm(DBADDR *paddr, char **ppbuffer, return; } -static void getOptions(DBADDR *paddr,char **poriginal,long *options,void *pflin) +static void getOptions(DBADDR *paddr, char **poriginal, long *options, + void *pflin) { db_field_log *pfl= (db_field_log *)pflin; struct rset *prset; @@ -890,6 +891,51 @@ long epicsShareAPI dbPutLinkValue(struct link *plink, short dbrType, return status; } +static long dbGetFieldLink(DBADDR *paddr,short dbrType, + void *pbuffer, long *options, long *nRequest, void *pflin) +{ + dbCommon *precord = paddr->precord; + dbFldDes *pfldDes = paddr->pfldDes; + char *pbuf = (char *)pbuffer; + int maxlen; + DBENTRY dbEntry; + long status; + + if (options && (*options)) + getOptions(paddr, &pbuf, options, pflin); + if (nRequest && *nRequest == 0) + return 0; + + switch (dbrType) { + case DBR_STRING: + maxlen = MAX_STRING_SIZE - 1; + if (nRequest && *nRequest > 1) *nRequest = 1; + break; + + case DBR_CHAR: + case DBR_UCHAR: + if (nRequest && *nRequest > 0) { + maxlen = *nRequest - 1; + break; + } + /* else fall through ... */ + default: + return S_db_badDbrtype; + } + + dbInitEntry(pdbbase, &dbEntry); + status = dbFindRecord(&dbEntry, precord->name); + if (!status) status = dbFindField(&dbEntry, pfldDes->name); + if (!status) { + char *rtnString = dbGetString(&dbEntry); + + strncpy(pbuf, rtnString, --maxlen); + pbuf[maxlen] = 0; + } + dbFinishEntry(&dbEntry); + return status; +} + long epicsShareAPI dbGetField(DBADDR *paddr,short dbrType, void *pbuffer, long *options, long *nRequest, void *pflin) { @@ -899,47 +945,11 @@ long epicsShareAPI dbGetField(DBADDR *paddr,short dbrType, dbScanLock(precord); if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { - DBENTRY dbEntry; - dbFldDes *pfldDes = paddr->pfldDes; - char *rtnString; - char *pbuf = (char *)pbuffer; - int maxlen; - - if (options && (*options)) - getOptions(paddr, &pbuf, options, pflin); - if (nRequest && *nRequest == 0) goto done; - - switch (dbrType) { - case DBR_STRING: - maxlen = MAX_STRING_SIZE - 1; - if (nRequest && *nRequest > 1) *nRequest = 1; - break; - - case DBR_CHAR: - case DBR_UCHAR: - if (nRequest && *nRequest > 0) { - maxlen = *nRequest - 1; - break; - } - /* else fall through ... */ - default: - status = S_db_badDbrtype; - goto done; - } - - dbInitEntry(pdbbase, &dbEntry); - status = dbFindRecord(&dbEntry, precord->name); - if (!status) status = dbFindField(&dbEntry, pfldDes->name); - if (!status) { - rtnString = dbGetString(&dbEntry); - strncpy(pbuf, rtnString, maxlen); - pbuf[maxlen] = 0; - } - dbFinishEntry(&dbEntry); + status = dbGetFieldLink(paddr, dbrType, pbuffer, options, nRequest, + pflin); } else { status = dbGet(paddr, dbrType, pbuffer, options, nRequest, pflin); } -done: dbScanUnlock(precord); return status; } @@ -985,7 +995,7 @@ long epicsShareAPI dbGet(DBADDR *paddr, short dbrType, return S_db_badDbrtype; } - strncpy(pbuf, (char *)paddr->pfield, maxlen); + strncpy(pbuf, paddr->pfield, --maxlen); pbuf[maxlen] = 0; return 0; } @@ -1351,7 +1361,6 @@ long epicsShareAPI dbPut(DBADDR *paddr, short dbrType, short field_type = paddr->field_type; long no_elements = paddr->no_elements; long special = paddr->special; - long offset; long status = 0; dbFldDes *pfldDes; int isValueField; @@ -1380,6 +1389,7 @@ long epicsShareAPI dbPut(DBADDR *paddr, short dbrType, paddr->pfield, paddr); } else { struct rset *prset = dbGetRset(paddr); + long offset = 0; if (paddr->special == SPC_DBADDR && prset && prset->get_array_info) { @@ -1387,8 +1397,6 @@ long epicsShareAPI dbPut(DBADDR *paddr, short dbrType, status = prset->get_array_info(paddr, &dummy, &offset); } - else - offset = 0; if (no_elements < nRequest) nRequest = no_elements; status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer, nRequest, no_elements, offset); diff --git a/src/ioc/db/dbChannel.c b/src/ioc/db/dbChannel.c index 4010b7a9d..6a0b0468c 100644 --- a/src/ioc/db/dbChannel.c +++ b/src/ioc/db/dbChannel.c @@ -331,7 +331,7 @@ dbChannel * dbChannelCreate(const char *name) const char *pname = name; DBENTRY dbEntry; dbChannel *chan = NULL; - DBADDR *paddr; + dbAddr *paddr; dbFldDes *pflddes; long status; short dbfType; @@ -429,6 +429,9 @@ long dbChannelOpen(dbChannel *chan) return status; } +/* FIXME: For performance we should make these one-liners into macros, + * or try to make them inline if all our compilers can do that. + */ const char * dbChannelName(dbChannel *chan) { return chan->name; @@ -472,7 +475,11 @@ short dbChannelSpecial(dbChannel *chan) void * dbChannelField(dbChannel *chan) { void * pdata = chan->addr.pfield; - /* FIXME: offer to filters? */ + /* FIXME: offer to filters? + * This is probably *not* a good idea, since there are several places + * (e.g. db_post_events()) where this pointer is compared with the + * address of a specific record field. + */ return pdata; } @@ -483,6 +490,7 @@ long dbChannelGetField(dbChannel *chan, short type, void *pbuffer, return dbGetField(&chan->addr, type, pbuffer, options, nRequest, pfl); } +/* Only use this when the record is already scan-locked */ long dbChannelPut(dbChannel *chan, short type, const void *pbuffer, long nRequest) { @@ -501,7 +509,7 @@ void dbChannelShow(dbChannel *chan, int level) { printf(" dbChannel name: %s\n", chan->name); /* FIXME: show field_type name */ - printf(" field_type %d, %ld element(s), %d filter(s)", + printf(" field_type %d, %ld element(s), %d filter(s)\n", chan->addr.field_type, chan->addr.no_elements, ellCount(&chan->filters)); if (level > 0) @@ -512,7 +520,7 @@ void dbChannelFilterShow(dbChannel *chan, int level) { chFilter *filter = (chFilter *) ellFirst(&chan->filters); while (filter) { - filter->fif->channel_report(filter, level - 1); + filter->fif->channel_report(filter, level); filter = (chFilter *) ellNext(&filter->node); } } @@ -527,8 +535,6 @@ void dbChannelDelete(dbChannel *chan) } free((char *) chan->name); // FIXME: Use free-list free(chan); // FIXME: Use free-list - - return 0; } diff --git a/src/ioc/db/test/dbChannelTest.c b/src/ioc/db/test/dbChannelTest.c index 50543c038..1f45b5253 100644 --- a/src/ioc/db/test/dbChannelTest.c +++ b/src/ioc/db/test/dbChannelTest.c @@ -132,7 +132,7 @@ MAIN(dbChannelTest) { dbChannel *pch; - testPlan(67); + testPlan(68); testOk1(!dbReadDatabase(&pdbbase, "dbChannelTest.dbx", ".:..", NULL)); testOk(!!pdbbase, "pdbbase was set"); @@ -196,7 +196,7 @@ MAIN(dbChannelTest) testOk1(!!(pch = dbChannelCreate("x.{\"scalar\":null}"))); e = e_report; - dbChannelShow(pch, 0); + dbChannelShow(pch, 1); e = e_close; if (pch) dbChannelDelete(pch);