diff --git a/modules/database/src/ioc/db/dbAccess.c b/modules/database/src/ioc/db/dbAccess.c index dfe3e0455..af396c74e 100644 --- a/modules/database/src/ioc/db/dbAccess.c +++ b/modules/database/src/ioc/db/dbAccess.c @@ -601,6 +601,31 @@ all_done: return status; } +long dbEntryToAddr(const DBENTRY *pdbentry, DBADDR *paddr) +{ + dbFldDes *pflddes = pdbentry->pflddes; + short dbfType = pflddes->field_type; + + paddr->precord = pdbentry->precnode->precord; + paddr->pfield = pdbentry->pfield; + paddr->pfldDes = pflddes; + paddr->no_elements = 1; + paddr->field_type = dbfType; + paddr->field_size = pflddes->size; + paddr->special = pflddes->special; + paddr->dbr_field_type = mapDBFToDBR[dbfType]; + + if (paddr->special == SPC_DBADDR) { + const rset *prset = dbGetRset(paddr); + + /* Let record type modify paddr */ + if (prset && prset->cvt_dbaddr) { + return prset->cvt_dbaddr(paddr); + } + } + return 0; +} + /* * Fill out a database structure (*paddr) for * a record given by the name "pname." @@ -611,9 +636,7 @@ all_done: long dbNameToAddr(const char *pname, DBADDR *paddr) { DBENTRY dbEntry; - dbFldDes *pflddes; long status = 0; - short dbfType; if (!pname || !*pname || !pdbbase) return S_db_notFound; @@ -628,46 +651,28 @@ long dbNameToAddr(const char *pname, DBADDR *paddr) status = dbGetAttributePart(&dbEntry, &pname); if (status) goto finish; - pflddes = dbEntry.pflddes; - dbfType = pflddes->field_type; - - paddr->precord = dbEntry.precnode->precord; - paddr->pfield = dbEntry.pfield; - paddr->pfldDes = pflddes; - paddr->no_elements = 1; - paddr->field_type = dbfType; - paddr->field_size = pflddes->size; - paddr->special = pflddes->special; - paddr->dbr_field_type = mapDBFToDBR[dbfType]; - - if (paddr->special == SPC_DBADDR) { - rset *prset = dbGetRset(paddr); - - /* Let record type modify paddr */ - if (prset && prset->cvt_dbaddr) { - status = prset->cvt_dbaddr(paddr); - if (status) - goto finish; - dbfType = paddr->field_type; - } - } + status = dbEntryToAddr(&dbEntry, paddr); + if (status) goto finish; /* Handle field modifiers */ if (*pname++ == '$') { + short dbfType = paddr->field_type; + /* Some field types can be accessed as char arrays */ if (dbfType == DBF_STRING) { paddr->no_elements = paddr->field_size; paddr->field_type = DBF_CHAR; paddr->field_size = 1; paddr->dbr_field_type = DBR_CHAR; - } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { + } + else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { /* Clients see a char array, but keep original dbfType */ paddr->no_elements = PVLINK_STRINGSZ; paddr->field_size = 1; paddr->dbr_field_type = DBR_CHAR; - } else { + } + else { status = S_dbLib_fieldNotFound; - goto finish; } } diff --git a/modules/database/src/ioc/db/dbAccessDefs.h b/modules/database/src/ioc/db/dbAccessDefs.h index 451e3f881..52ac4016d 100644 --- a/modules/database/src/ioc/db/dbAccessDefs.h +++ b/modules/database/src/ioc/db/dbAccessDefs.h @@ -215,7 +215,14 @@ epicsShareFunc int dbGetFieldIndex(const struct dbAddr *paddr); epicsShareFunc long dbScanPassive( struct dbCommon *pfrom,struct dbCommon *pto); epicsShareFunc long dbProcess(struct dbCommon *precord); -epicsShareFunc long dbNameToAddr(const char *pname, struct dbAddr *); +epicsShareFunc long dbNameToAddr(const char *pname, struct dbAddr *paddr); + +/** Initialize DBADDR from a dbEntry + * Also handles SPC_DBADDR processing. This is really an internal + * routine for use by dbNameToAddr() and dbChannelCreate(). + */ +epicsShareFunc long dbEntryToAddr(const struct dbEntry *pdbentry, + struct dbAddr *paddr); /** Initialize DBENTRY from a valid dbAddr* * Constant time equivalent of dbInitEntry() then dbFindRecord(), diff --git a/modules/database/src/ioc/db/dbChannel.c b/modules/database/src/ioc/db/dbChannel.c index 9792708cb..6db2982d8 100644 --- a/modules/database/src/ioc/db/dbChannel.c +++ b/modules/database/src/ioc/db/dbChannel.c @@ -473,9 +473,7 @@ dbChannel * dbChannelCreate(const char *name) dbChannel *chan = NULL; char *cname; dbAddr *paddr; - dbFldDes *pflddes; long status; - short dbfType; if (!name || !*name || !pdbbase) return NULL; @@ -498,32 +496,14 @@ dbChannel * dbChannelCreate(const char *name) ellInit(&chan->post_chain); paddr = &chan->addr; - pflddes = dbEntry.pflddes; - dbfType = pflddes->field_type; - - paddr->precord = dbEntry.precnode->precord; - paddr->pfield = dbEntry.pfield; - paddr->pfldDes = pflddes; - paddr->no_elements = 1; - paddr->field_type = dbfType; - paddr->field_size = pflddes->size; - paddr->special = pflddes->special; - paddr->dbr_field_type = mapDBFToDBR[dbfType]; - - if (paddr->special == SPC_DBADDR) { - rset *prset = dbGetRset(paddr); - - /* Let record type modify paddr */ - if (prset && prset->cvt_dbaddr) { - status = prset->cvt_dbaddr(paddr); - if (status) - goto finish; - dbfType = paddr->field_type; - } - } + status = dbEntryToAddr(&dbEntry, paddr); + if (status) + goto finish; /* Handle field modifiers */ if (*pname) { + short dbfType = paddr->field_type; + if (*pname == '$') { /* Some field types can be accessed as char arrays */ if (dbfType == DBF_STRING) { @@ -531,12 +511,14 @@ dbChannel * dbChannelCreate(const char *name) paddr->field_type = DBF_CHAR; paddr->field_size = 1; paddr->dbr_field_type = DBR_CHAR; - } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { + } + else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { /* Clients see a char array, but keep original dbfType */ paddr->no_elements = PVLINK_STRINGSZ; paddr->field_size = 1; paddr->dbr_field_type = DBR_CHAR; - } else { + } + else { status = S_dbLib_fieldNotFound; goto finish; }