From acd1aef2a02f9934ca091ffb7e54ebfe9388a36a Mon Sep 17 00:00:00 2001 From: Evan Daykin Date: Wed, 8 Oct 2025 10:44:27 -0400 Subject: [PATCH] Warn to stderr when discarding CPP modifier for outlink (#608) * warn to stderr when un-setting inapplicable CPP flag on output links * Warn and unset CP flag for output links * use errlogprintf instead of fprintf for dbParseLink CP/CPP warning * Pass source record name to dbParseLink for debug information when modifier is discarded * make CP/CPP discard warning less verbose * Include field name of affected record when warning of CP/CPP discard --- modules/database/src/ioc/db/dbAccess.c | 2 +- modules/database/src/ioc/dbStatic/dbStaticLib.c | 16 +++++++++++----- modules/database/src/ioc/dbStatic/dbStaticPvt.h | 2 +- modules/database/test/ioc/db/dbPutLinkTest.c | 16 +++++++++++++--- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/modules/database/src/ioc/db/dbAccess.c b/modules/database/src/ioc/db/dbAccess.c index a6c040d45..ca6627287 100644 --- a/modules/database/src/ioc/db/dbAccess.c +++ b/modules/database/src/ioc/db/dbAccess.c @@ -1095,7 +1095,7 @@ static long dbPutFieldLink(DBADDR *paddr, return S_db_badDbrtype; } - status = dbParseLink(pstring, pfldDes->field_type, &link_info); + status = dbParseLink(pstring, pfldDes->field_type, &link_info, precord->name, pfldDes->name); if (status) return status; diff --git a/modules/database/src/ioc/dbStatic/dbStaticLib.c b/modules/database/src/ioc/dbStatic/dbStaticLib.c index 3e892b11f..08225c5c8 100644 --- a/modules/database/src/ioc/dbStatic/dbStaticLib.c +++ b/modules/database/src/ioc/dbStatic/dbStaticLib.c @@ -2214,7 +2214,7 @@ long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec) if(!plink->text) continue; - if(dbParseLink(plink->text, pflddes->field_type, &link_info)!=0) { + if(dbParseLink(plink->text, pflddes->field_type, &link_info, prec->name, pflddes->name)!=0) { /* This was already parsed once when ->text was set. * Any syntax error messages were printed at that time. */ @@ -2243,7 +2243,7 @@ void dbFreeLinkInfo(dbLinkInfo *pinfo) pinfo->target = NULL; } -long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo) +long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, const char *recname, const char *fieldname) { char *pstr; size_t len; @@ -2380,7 +2380,13 @@ long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo) /* filter modifiers based on link type */ switch(ftype) { case DBF_INLINK: /* accept all */ break; - case DBF_OUTLINK: pinfo->modifiers &= ~pvlOptCPP; break; + case DBF_OUTLINK: + if(pinfo->modifiers & (pvlOptCPP|pvlOptCP)){ + errlogPrintf(ERL_WARNING ": Discarding CP/CPP modifier in CA output link from %s.%s to %s.\n", + recname, fieldname, pinfo->target); + } + pinfo->modifiers &= ~(pvlOptCPP|pvlOptCP); + break; case DBF_FWDLINK: pinfo->modifiers &= pvlOptCA; break; } } @@ -2618,7 +2624,7 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring) dbLinkInfo link_info; DBLINK *plink = (DBLINK *)pfield; - status = dbParseLink(pstring, pflddes->field_type, &link_info); + status = dbParseLink(pstring, pflddes->field_type, &link_info, dbGetRecordName(pdbentry), dbGetFieldName(pdbentry)); if (status) break; if (plink->type==CONSTANT && plink->value.constantStr==NULL) { @@ -3602,7 +3608,7 @@ void dbReportDeviceConfig(dbBase *pdbbase, FILE *report) if (plink->text) { /* Not yet parsed */ dbLinkInfo linfo; - if (dbParseLink(plink->text, pdbentry->pflddes->field_type, &linfo)) + if (dbParseLink(plink->text, pdbentry->pflddes->field_type, &linfo, dbGetRecordName(pdbentry), dbGetFieldName(pdbentry))) continue; linkType = linfo.ltype; diff --git a/modules/database/src/ioc/dbStatic/dbStaticPvt.h b/modules/database/src/ioc/dbStatic/dbStaticPvt.h index 033fde40c..32287a149 100644 --- a/modules/database/src/ioc/dbStatic/dbStaticPvt.h +++ b/modules/database/src/ioc/dbStatic/dbStaticPvt.h @@ -74,7 +74,7 @@ long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec); /* Parse link string. no record locks needed. * on success caller must free pinfo->target */ -DBCORE_API long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo); +DBCORE_API long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, const char *recordname, const char *fieldname); /* Check if link type allow the parsed link value pinfo * to be assigned to the given link. * Record containing plink must be locked. diff --git a/modules/database/test/ioc/db/dbPutLinkTest.c b/modules/database/test/ioc/db/dbPutLinkTest.c index 2b7d3a518..a53214f6d 100644 --- a/modules/database/test/ioc/db/dbPutLinkTest.c +++ b/modules/database/test/ioc/db/dbPutLinkTest.c @@ -92,7 +92,7 @@ static void testLinkParse(void) for (;td->str; td++) { int i, N; testDiag("Parsing \"%s\"", td->str); - testOk(dbParseLink(td->str, DBF_INLINK, &info) == 0, "Parser returned OK"); + testOk(dbParseLink(td->str, DBF_INLINK, &info, "dummy","INP") == 0, "Parser returned OK"); if (!testOk(info.ltype == td->info.ltype, "Link type value")) testDiag("Expected %d, got %d", td->info.ltype, info.ltype); if (td->info.target && info.target) @@ -121,6 +121,16 @@ static void testLinkParse(void) dbFreeLinkInfo(&info); } + info.modifiers |= pvlOptCPP; + dbParseLink("something CPP", DBF_OUTLINK, &info, "dummy","OUT"); + testOk(info.modifiers == 0, "CPP modifier was discarded"); + dbFreeLinkInfo(&info); + + info.modifiers |= pvlOptCP; + dbParseLink("something CP", DBF_OUTLINK, &info, "dummy","OUT"); + testOk(info.modifiers == 0, "CP modifier was discarded"); + dbFreeLinkInfo(&info); + testIocShutdownOk(); testdbCleanup(); @@ -155,7 +165,7 @@ static void testLinkFailParse(void) eltc(1); for(;*td; td++) { - testOk(dbParseLink(*td, DBF_INLINK, &info) == S_dbLib_badField, + testOk(dbParseLink(*td, DBF_INLINK, &info, "dummy","INP") == S_dbLib_badField, "dbParseLink correctly rejected \"%s\"", *td); } @@ -705,7 +715,7 @@ void testTSEL(void) MAIN(dbPutLinkTest) { - testPlan(352); + testPlan(354); testLinkParse(); testLinkFailParse(); testCADBSet();