diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c index e7807bc7a..ca7dfff83 100644 --- a/src/ioc/dbStatic/dbStaticLib.c +++ b/src/ioc/dbStatic/dbStaticLib.c @@ -1888,6 +1888,65 @@ char * dbGetString(DBENTRY *pdbentry) return (message); } +long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec) +{ + short i; + + for (i=0; ino_links; i++) { + dbLinkInfo link_info; + dbFldDes *pflddes = rtyp->papFldDes[rtyp->link_ind[i]]; + DBLINK *plink = (DBLINK *)(((char *)prec) + pflddes->offset); + devSup *devsup = NULL; + + /* link fields are zero'd on allocation. + * so are effectively CONSTANT, but with constantStr==NULL. + * Here we initialize them to have the correct link type, + * with zero values and empty (but non-NULL) strings. + */ + + if(pflddes->isDevLink) { + devsup = (devSup *)ellNth(&rtyp->devList, prec->dtyp+1); + } + if(devsup) + plink->type = devsup->link_type; + else + plink->type = CONSTANT; + + switch (plink->type) { + case CONSTANT: plink->value.constantStr = callocMustSucceed(1, 1, "init CONSTANT link"); break; + case PV_LINK: plink->value.pv_link.pvname = callocMustSucceed(1, 1, "init PV_LINK"); break; + case VME_IO: plink->value.vmeio.parm = pNullString; break; + case CAMAC_IO: plink->value.camacio.parm = pNullString; break; + case AB_IO: plink->value.abio.parm = pNullString; break; + case GPIB_IO: plink->value.gpibio.parm = pNullString; break; + case BITBUS_IO: plink->value.bitbusio.parm = pNullString; break; + case INST_IO: plink->value.instio.string = pNullString; break; + case BBGPIB_IO: plink->value.bbgpibio.parm = pNullString; break; + case VXI_IO: plink->value.vxiio.parm = pNullString; break; + } + + if(!plink->text) + continue; + + if(dbParseLink(plink->text, pflddes->field_type, &link_info)!=0) { + /* This was already parsed once when ->text was set. + * Any syntax error messages were printed at that time. + */ + + } else if(dbCanSetLink(plink, &link_info, devsup)!=0) { + errlogPrintf("Error: %s.%s: can't initialize link type %d with \"%s\" (type %d)\n", + prec->name, pflddes->name, plink->type, plink->text, link_info.ltype); + + } else if(dbSetLink(plink, &link_info, devsup)) { + errlogPrintf("Error: %s.%s: failed to initialize link type %d with \"%s\" (type %d)\n", + prec->name, pflddes->name, plink->type, plink->text, link_info.ltype); + } + free(plink->text); + plink->text = NULL; + } + return 0; +} + long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo) { char *pstr, *pend; diff --git a/src/ioc/dbStatic/dbStaticPvt.h b/src/ioc/dbStatic/dbStaticPvt.h index f3e6a932e..c249e73bb 100644 --- a/src/ioc/dbStatic/dbStaticPvt.h +++ b/src/ioc/dbStatic/dbStaticPvt.h @@ -51,6 +51,8 @@ typedef struct dbLinkInfo { int hwnums[5]; } dbLinkInfo; +long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec); + /* Parse link string. no record locks needed. * on success caller must free pinfo->target */ diff --git a/src/ioc/misc/iocInit.c b/src/ioc/misc/iocInit.c index 1e224d2f5..32b7fc524 100644 --- a/src/ioc/misc/iocInit.c +++ b/src/ioc/misc/iocInit.c @@ -56,6 +56,8 @@ #include "dbCommon.h" #include "dbLock.h" #include "dbAccess.h" +#include "dbStaticLib.h" +#include "dbStaticPvt.h" #include "recGbl.h" #include "dbNotify.h" #include "dbCa.h" @@ -82,7 +84,14 @@ static void initDatabase(void); static void initialProcess(void); static void exitDatabase(void *dummy); - +/* + * Iterate through all record instances (but not aliases), + * calling a function for each one. + */ +typedef void (*recIterFunc)(dbRecordType *rtyp, dbCommon *prec, void *user); + +static void iterateRecords(recIterFunc func, void *user); + /* * Initialize EPICS on the IOC. */ @@ -122,8 +131,14 @@ static int iocBuild_1(void) return 0; } +static void prepareLinks(dbRecordType *rtyp, dbCommon *prec, void *junk) +{ + dbInitRecordLinks(rtyp, prec); +} + static int iocBuild_2(void) { + iterateRecords(prepareLinks, NULL); initHookAnnounce(initHookAfterCaLinkInit); initDrvSup(); @@ -413,12 +428,6 @@ static void finishDevSup(void) } } } - -/* - * Iterate through all record instances (but not aliases), - * calling a function for each one. - */ -typedef void (*recIterFunc)(dbRecordType *rtyp, dbCommon *prec, void *user); static void iterateRecords(recIterFunc func, void *user) {