diff --git a/configure/CONFIG_SITE_ENV b/configure/CONFIG_SITE_ENV index 660c3d374..3bdb94b15 100644 --- a/configure/CONFIG_SITE_ENV +++ b/configure/CONFIG_SITE_ENV @@ -34,35 +34,30 @@ # The future dates below assume the rules don't get changed; # see http://www.timeanddate.com/time/dst/2018.html to check. # -# DST for 2017 US: Mar 12 - Nov 05 -# EU: Mar 26 - Oct 29 -EPICS_TIMEZONE = CUS::360:031202:110502 -#EPICS_TIMEZONE = MET::-60:032602:102902 -# # DST for 2018 US: Mar 11 - Nov 04 # EU: Mar 25 - Oct 28 -#EPICS_TIMEZONE = CUS::360:031102:110402 -#EPICS_TIMEZONE = MET::-60:032502:102802 +EPICS_TIMEZONE = CUS::360:031102:110402 +#EPICS_TIMEZONE = MET::-60:032502:102803 # # DST for 2019 US: Mar 10 - Nov 03 # EU: Mar 31 - Oct 27 #EPICS_TIMEZONE = CUS::360:031002:110302 -#EPICS_TIMEZONE = MET::-60:033102:102702 +#EPICS_TIMEZONE = MET::-60:033102:102703 # # DST for 2020 US: Mar 08 - Nov 01 # EU: Mar 29 - Oct 25 #EPICS_TIMEZONE = CUS::360:030802:110102 -#EPICS_TIMEZONE = MET::-60:032902:102502 +#EPICS_TIMEZONE = MET::-60:032902:102503 # # DST for 2021 US: Mar 14 - Nov 07 # EU: Mar 28 - Oct 31 #EPICS_TIMEZONE = CUS::360:031402:110702 -#EPICS_TIMEZONE = MET::-60:032802:103102 +#EPICS_TIMEZONE = MET::-60:032802:103103 # # DST for 2022 US: Mar 13 - Nov 06 # EU: Mar 27 - Oct 30 #EPICS_TIMEZONE = CUS::360:031302:110602 -#EPICS_TIMEZONE = MET::-60:032702:103002 +#EPICS_TIMEZONE = MET::-60:032702:103003 # EPICS_TS_NTP_INET # NTP time server ip address for VxWorks and RTEMS. diff --git a/configure/RULES_BUILD b/configure/RULES_BUILD index ea84db8be..14e7a32ea 100644 --- a/configure/RULES_BUILD +++ b/configure/RULES_BUILD @@ -102,6 +102,7 @@ endif # Products and Object libraries # PRODTARGETS += $(PRODNAME) $(MUNCHNAME) $(CTDT_SRCS) $(CTDT_OBJS) $(NMS) +TESTPRODTARGETS += $(TESTPRODNAME) $(TESTMUNCHNAME) #--------------------------------------------------------------- # Test specifications and test result files @@ -140,7 +141,7 @@ rebuild: clean install build: inc -build: $(OBJSNAME) $(LIBTARGETS) $(PRODTARGETS) $(TESTPRODNAME) \ +build: $(OBJSNAME) $(LIBTARGETS) $(PRODTARGETS) $(TESTPRODTARGETS) \ $(TARGETS) $(TESTSCRIPTS) $(INSTALL_LIB_INSTALLS) inc : $(COMMON_INC) $(INSTALL_INC) $(INSTALL_CONFIGS) @@ -158,20 +159,21 @@ clean: build_clean build_clean: $(ECHO) "Cleaning" - @$(RM) *.i *$(OBJ) *.a $(TESTPRODNAME) \ + @$(RM) *.i *$(OBJ) *.a \ $(LIBNAME) $(TESTLIBNAME) $(SHRLIBNAME) $(TESTSHRLIBNAME) \ $(DLLSTUB_LIBNAME) $(TESTDLLSTUB_LIBNAME) \ $(LOADABLE_SHRLIBNAME) \ $(INC) $(TARGETS) $(TDS) $(CLEANS) \ *.out MakefileInclude *.manifest *.exp \ - $(COMMON_INC) $(HDEPENDS_FILES) $(PRODTARGETS) \ + $(COMMON_INC) $(HDEPENDS_FILES) $(PRODTARGETS) $(TESTPRODTARGETS) \ $(TESTSCRIPTS) $(TAPFILES) $(JUNITFILES) ifdef RES @$(RM) *$(RES) endif -$(DIRECTORY_TARGETS) : - $(MKDIR) $@ +# Sort mkdir targets to remove duplicates & make parents first +$(DIRECTORY_TARGETS): + $(MKDIR) $(sort $@) # Install LIB_INSTALLS libraries before linking executables $(TESTPRODNAME) $(PRODNAME): | $(INSTALL_LIB_INSTALLS) @@ -321,6 +323,10 @@ $(MUNCHNAME): %$(MUNCH_SUFFIX): $(MUNCH_DEPENDS) %$(EXE) @$(RM) $@ $(MUNCH_CMD) +$(TESTMUNCHNAME): %$(MUNCH_SUFFIX): $(MUNCH_DEPENDS) %$(EXE) + @$(RM) $@ + $(MUNCH_CMD) + #--------------------------------------------------------------- # GeSys modules for RTEMS $(MODNAME): %$(MODEXT): %$(EXE) diff --git a/configure/os/CONFIG.Common.RTEMS b/configure/os/CONFIG.Common.RTEMS index 9650ae255..c22e37a66 100644 --- a/configure/os/CONFIG.Common.RTEMS +++ b/configure/os/CONFIG.Common.RTEMS @@ -136,6 +136,13 @@ MOD_LDFLAGS = $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) $(POSIX_LDFLAGS) \ LINK.mod = $(CCC) -o $@ $(PRODDIR_LDFLAGS) $(MOD_LDFLAGS) LINK.mod += $(PROD_LDFLAGS) $(PROD_LD_OBJS) $(PROD_LD_RESS) $(MOD_LDLIBS) +#-------------------------------------------------- +# Here munching means creating a bootable object binary +ifdef MUNCH_SUFFIX + MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) + TESTMUNCHNAME = $(TESTPRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) +endif + #-------------------------------------------------- # RTEMS has neither shared libraries nor dynamic loading STATIC_BUILD=YES diff --git a/configure/os/CONFIG.Common.RTEMS-beatnik b/configure/os/CONFIG.Common.RTEMS-beatnik index 00080e7fd..aaf611638 100644 --- a/configure/os/CONFIG.Common.RTEMS-beatnik +++ b/configure/os/CONFIG.Common.RTEMS-beatnik @@ -15,7 +15,6 @@ ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120 OP_SYS_LDLIBS += -lbspExt MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@ endef diff --git a/configure/os/CONFIG.Common.RTEMS-mvme2100 b/configure/os/CONFIG.Common.RTEMS-mvme2100 index 687af2374..0ae64c791 100644 --- a/configure/os/CONFIG.Common.RTEMS-mvme2100 +++ b/configure/os/CONFIG.Common.RTEMS-mvme2100 @@ -13,7 +13,6 @@ ARCH_DEP_CFLAGS += -DHAVE_PPCBUG OP_SYS_LDLIBS += -lbspExt MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< rtems gzip -f9 rtems diff --git a/configure/os/CONFIG.Common.RTEMS-mvme2700 b/configure/os/CONFIG.Common.RTEMS-mvme2700 index f45e321c4..899fab17f 100644 --- a/configure/os/CONFIG.Common.RTEMS-mvme2700 +++ b/configure/os/CONFIG.Common.RTEMS-mvme2700 @@ -7,7 +7,6 @@ ARCH_DEP_CFLAGS += -DHAVE_PPCBUG ARCH_DEP_CFLAGS += -DNVRAM_INDIRECT MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< rtems gzip -f9 rtems diff --git a/configure/os/CONFIG.Common.RTEMS-mvme3100 b/configure/os/CONFIG.Common.RTEMS-mvme3100 index cd9416ce7..e94d46211 100644 --- a/configure/os/CONFIG.Common.RTEMS-mvme3100 +++ b/configure/os/CONFIG.Common.RTEMS-mvme3100 @@ -15,7 +15,6 @@ ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120 OP_SYS_LDLIBS += -lbspExt MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@ endef diff --git a/configure/os/CONFIG.Common.RTEMS-mvme5500 b/configure/os/CONFIG.Common.RTEMS-mvme5500 index 0c05b76a8..44ef7ea3e 100644 --- a/configure/os/CONFIG.Common.RTEMS-mvme5500 +++ b/configure/os/CONFIG.Common.RTEMS-mvme5500 @@ -16,7 +16,6 @@ ARCH_DEP_CFLAGS += -DBSP_NVRAM_BASE_ADDR=0xf1110000 OP_SYS_LDLIBS += -lbspExt MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@ endef diff --git a/configure/os/CONFIG.Common.RTEMS-pc386 b/configure/os/CONFIG.Common.RTEMS-pc386 index b3150cc66..92ef4ac22 100644 --- a/configure/os/CONFIG.Common.RTEMS-pc386 +++ b/configure/os/CONFIG.Common.RTEMS-pc386 @@ -8,7 +8,6 @@ RTEMS_TARGET_CPU=i386 MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< temp.bin $(BIN2BOOT) $@ 0x00097E00 \ diff --git a/configure/os/CONFIG.Common.RTEMS-uC5282 b/configure/os/CONFIG.Common.RTEMS-uC5282 index 9c6a58d33..6b0903e07 100644 --- a/configure/os/CONFIG.Common.RTEMS-uC5282 +++ b/configure/os/CONFIG.Common.RTEMS-uC5282 @@ -9,7 +9,6 @@ RTEMS_TARGET_CPU = m68k ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) define MUNCH_CMD $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< $@ endef diff --git a/src/ca/client/oldChannelNotify.cpp b/src/ca/client/oldChannelNotify.cpp index 5775bcc6b..701f51fc1 100644 --- a/src/ca/client/oldChannelNotify.cpp +++ b/src/ca/client/oldChannelNotify.cpp @@ -390,7 +390,7 @@ int epicsShareAPI ca_array_get_callback ( chtype type, { caStatus = ECA_ALLOCMEM; } - catch ( cacChannel::msgBodyCacheTooSmall ) { + catch ( cacChannel::msgBodyCacheTooSmall & ) { caStatus = ECA_TOLARGE; } catch ( ... ) diff --git a/src/ca/client/perl/Makefile b/src/ca/client/perl/Makefile index fb0fc96ff..9b61b3b32 100644 --- a/src/ca/client/perl/Makefile +++ b/src/ca/client/perl/Makefile @@ -58,7 +58,7 @@ Cap5_LIBS = ca Com Cap5_INCLUDES = -I$(shell $(PERL) ../perlConfig.pl archlib)/CORE Cap5_CFLAGS = $(shell $(PERL) ../perlConfig.pl ccflags) -CLEANS += Cap5.c pod2htmd.tmp pod2htmi.tmp +CLEANS += Cap5.c include $(TOP)/configure/RULES diff --git a/src/ca/client/tools/caput.c b/src/ca/client/tools/caput.c index 9c50cd9df..5e4d10e23 100644 --- a/src/ca/client/tools/caput.c +++ b/src/ca/client/tools/caput.c @@ -8,7 +8,7 @@ * Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer * Synchrotronstrahlung. * EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. +* in file LICENSE that is included with this distribution. \*************************************************************************/ /* @@ -419,7 +419,7 @@ int main (int argc, char *argv[]) if (argc > optind+1) { for (i = optind + 1; i < argc; i++) { strcat(cbuf, " "); - strcat(cbuf, argv[i]); + strcat(cbuf, argv[i]); } } @@ -530,6 +530,11 @@ int main (int argc, char *argv[]) /* Use standard put with defined timeout */ result = ca_array_put (dbrType, count, pvs[0].chid, pbuf); } + if (result != ECA_NORMAL) { + fprintf(stderr, "Error from put operation: %s\n", ca_message(result)); + return 1; + } + result = ca_pend_io(caTimeout); if (result == ECA_TIMEOUT) { fprintf(stderr, "Write operation timed out: Data was not written.\n"); @@ -545,7 +550,7 @@ int main (int argc, char *argv[]) } if (result != ECA_NORMAL) { - fprintf(stderr, "Error occured writing data.\n"); + fprintf(stderr, "Error occured writing data: %s\n", ca_message(result)); return 1; } diff --git a/src/ca/client/tools/tool_lib.c b/src/ca/client/tools/tool_lib.c index 72044bd49..29b252e37 100644 --- a/src/ca/client/tools/tool_lib.c +++ b/src/ca/client/tools/tool_lib.c @@ -414,6 +414,12 @@ char *dbr2str (const void *value, unsigned type) ptsNewS = &((struct TYPE *)value)->stamp; \ ptsNewC = &tsNow; \ \ + if (!tsInitS) \ + { \ + tsFirst = *ptsNewS; \ + tsInitS = 1; \ + } \ + \ switch (tsType) { \ case relative: \ ptsRefC = &tsStart; \ @@ -506,12 +512,6 @@ void print_time_val_sts (pv* pv, unsigned long reqElems) epicsTimeGetCurrent(&tsNow); epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, &tsNow); - if (!tsInitS) - { - tsFirst = tsNow; - tsInitS = 1; - } - if (pv->nElems <= 1 && fieldSeparator == ' ') printf("%-30s", pv->name); else printf("%s", pv->name); printf("%c", fieldSeparator); diff --git a/src/ioc/db/test/testdbConvert.c b/src/ioc/db/test/testdbConvert.c index cd0ed0ed2..cc175c0a0 100644 --- a/src/ioc/db/test/testdbConvert.c +++ b/src/ioc/db/test/testdbConvert.c @@ -38,7 +38,7 @@ static void testBasicGet(void) getter(&addr, scratch, 1, s_input_len, 0); - testOk1(scratch[0]==s_input[0]); + testOk1(scratch[0]==s_input[0] && scratch[1]==0); memset(scratch, 0x42, sizeof(s_input)); } @@ -128,7 +128,7 @@ static void testBasicPut(void) putter(&addr, s_input, 1, s_input_len, 0); - testOk1(scratch[0]==s_input[0]); + testOk1(scratch[0]==s_input[0] && scratch[1]==0); memset(scratch, 0x42, sizeof(s_input)); } diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c index c2b1afa49..4e0755db7 100644 --- a/src/ioc/dbStatic/dbStaticLib.c +++ b/src/ioc/dbStatic/dbStaticLib.c @@ -51,8 +51,11 @@ static char *pNullString = ""; #define messagesize 276 #define RPCL_LEN INFIX_TO_POSTFIX_SIZE(80) -/* must be long enough to hold 32-bit signed integer in base 10 */ -STATIC_ASSERT(messagesize>=11); +/* Must be big enough to hold a 64-bit integer in base 10, but in + * the future when fields hold large JSON objects this fixed size + * allocation will probably have to become variable sized. + */ +STATIC_ASSERT(messagesize >= 21); static char *ppstring[5]={" NPP"," PP"," CA"," CP"," CPP"}; static char *msstring[4]={" NMS"," MS"," MSI"," MSS"}; @@ -208,11 +211,13 @@ static void zeroDbentry(DBENTRY *pdbentry) static char *getpMessage(DBENTRY *pdbentry) { char *msg = pdbentry->message; + if (!msg) { msg = dbCalloc(1, messagesize); pdbentry->message = msg; } - *msg = '\0'; + else + *msg = '\0'; return msg; } @@ -224,6 +229,17 @@ void dbMsgCpy(DBENTRY *pdbentry, const char *msg) pdbentry->message[messagesize-1] = '\0'; } +static +void dbMsgNCpy(DBENTRY *pdbentry, const char *msg, size_t len) +{ + getpMessage(pdbentry); + if (len >= messagesize) + len = messagesize-1; /* FIXME: Quietly truncates */ + + strncpy(pdbentry->message, msg, len); + pdbentry->message[len] = '\0'; +} + static void dbMsgPrint(DBENTRY *pdbentry, const char *fmt, ...) { @@ -1678,21 +1694,27 @@ int dbIsVisibleRecord(DBENTRY *pdbentry) long dbCreateAlias(DBENTRY *pdbentry, const char *alias) { - dbRecordType *precordType = pdbentry->precordType; - dbRecordNode *precnode = pdbentry->precnode; - dbRecordNode *pnewnode; - PVDENTRY *ppvd; - ELLLIST *preclist = NULL; - if (!precordType) return S_dbLib_recordTypeNotFound; + dbRecordType *precordType = pdbentry->precordType; + dbRecordNode *precnode = pdbentry->precnode; + dbRecordNode *pnewnode; + DBENTRY tempEntry; + PVDENTRY *ppvd; + + if (!precordType) + return S_dbLib_recordTypeNotFound; + /* alias of alias still references actual record */ - while(precnode && (precnode->flags&DBRN_FLAGS_ISALIAS)) + while (precnode && (precnode->flags & DBRN_FLAGS_ISALIAS)) precnode = precnode->aliasedRecnode; - if (!precnode) return S_dbLib_recNotFound; - zeroDbentry(pdbentry); - if (!dbFindRecord(pdbentry, alias)) return S_dbLib_recExists; - zeroDbentry(pdbentry); - pdbentry->precordType = precordType; - preclist = &precordType->recList; + + if (!precnode) + return S_dbLib_recNotFound; + + dbInitEntry(pdbentry->pdbbase, &tempEntry); + if (!dbFindRecord(&tempEntry, alias)) + return S_dbLib_recExists; + dbFinishEntry(&tempEntry); + pnewnode = dbCalloc(1, sizeof(dbRecordNode)); pnewnode->recordname = epicsStrDup(alias); pnewnode->precord = precnode->precord; @@ -1700,11 +1722,16 @@ long dbCreateAlias(DBENTRY *pdbentry, const char *alias) pnewnode->flags = DBRN_FLAGS_ISALIAS; precnode->flags |= DBRN_FLAGS_HASALIAS; ellInit(&pnewnode->infoList); - ellAdd(preclist, &pnewnode->node); + + ellAdd(&precordType->recList, &pnewnode->node); precordType->no_aliases++; - pdbentry->precnode = pnewnode; + ppvd = dbPvdAdd(pdbentry->pdbbase, precordType, pnewnode); - if (!ppvd) {errMessage(-1,"Logic Err: Could not add to PVD");return(-1);} + if (!ppvd) { + errMessage(-1, "dbCreateAlias: Add to PVD failed"); + return -1; + } + return 0; } @@ -1888,7 +1915,8 @@ char * dbGetString(DBENTRY *pdbentry) switch (pflddes->field_type) { case DBF_STRING: - dbMsgCpy(pdbentry, (char *)pfield); + /* Protect against a missing nil-terminator */ + dbMsgNCpy(pdbentry, (char *)pfield, pflddes->size); break; case DBF_CHAR: case DBF_UCHAR: @@ -1911,6 +1939,8 @@ char * dbGetString(DBENTRY *pdbentry) case CONSTANT: if (plink->value.constantStr) { dbMsgCpy(pdbentry, plink->value.constantStr); + } else if (plink->text) { + dbMsgCpy(pdbentry, plink->text); } else { dbMsgCpy(pdbentry, ""); } @@ -2011,7 +2041,13 @@ char * dbGetString(DBENTRY *pdbentry) switch(plink->type) { case CONSTANT: - dbMsgCpy(pdbentry, "0"); + if (plink->value.constantStr) { + dbMsgCpy(pdbentry, plink->value.constantStr); + } else if (plink->text) { + dbMsgCpy(pdbentry, plink->text); + } else { + dbMsgCpy(pdbentry, ""); + } break; case MACRO_LINK: if (plink->value.macro_link.macroStr) { diff --git a/src/std/rec/stringinRecord.c b/src/std/rec/stringinRecord.c index 212e79378..ee84f0dc9 100644 --- a/src/std/rec/stringinRecord.c +++ b/src/std/rec/stringinRecord.c @@ -96,6 +96,7 @@ static long init_record(struct dbCommon *pcommon, int pass) { struct stringinRecord *prec = (struct stringinRecord *)pcommon; STATIC_ASSERT(sizeof(prec->oval)==sizeof(prec->val)); + STATIC_ASSERT(sizeof(prec->sval)==sizeof(prec->val)); struct stringindset *pdset = (struct stringindset *) prec->dset; if (pass == 0) return 0; @@ -120,7 +121,8 @@ static long init_record(struct dbCommon *pcommon, int pass) if (status) return status; } - strcpy(prec->oval, prec->val); + + strncpy(prec->oval, prec->val, sizeof(prec->val)); return 0; } @@ -213,7 +215,7 @@ static long readValue(stringinRecord *prec) if (prec->pact || (prec->sdly < 0.)) { status = dbGetLink(&prec->siol, DBR_STRING, prec->sval, 0, 0); if (status == 0) { - strcpy(prec->val, prec->sval); + strncpy(prec->val, prec->sval, sizeof(prec->val)); prec->udf = FALSE; } prec->pact = FALSE; diff --git a/src/std/rec/stringoutRecord.c b/src/std/rec/stringoutRecord.c index fedc9fc68..0c871fc4d 100644 --- a/src/std/rec/stringoutRecord.c +++ b/src/std/rec/stringoutRecord.c @@ -98,6 +98,7 @@ static long init_record(struct dbCommon *pcommon, int pass) { struct stringoutRecord *prec = (struct stringoutRecord *)pcommon; STATIC_ASSERT(sizeof(prec->oval)==sizeof(prec->val)); + STATIC_ASSERT(sizeof(prec->ivov)==sizeof(prec->val)); struct stringoutdset *pdset = (struct stringoutdset *) prec->dset; if (pass == 0) return 0; @@ -126,7 +127,7 @@ static long init_record(struct dbCommon *pcommon, int pass) return status; } - strcpy(prec->oval, prec->val); + strncpy(prec->oval, prec->val, sizeof(prec->val)); return 0; } @@ -165,7 +166,7 @@ static long process(struct dbCommon *pcommon) break; case (menuIvoaSet_output_to_IVOV) : if(prec->pact == FALSE){ - strcpy(prec->val,prec->ivov); + strncpy(prec->val, prec->ivov, sizeof(prec->val)); } status=writeValue(prec); /* write the new value */ break; diff --git a/src/std/rec/test/asTestLib.c b/src/std/rec/test/asTestLib.c index 18139233f..2043ed770 100644 --- a/src/std/rec/test/asTestLib.c +++ b/src/std/rec/test/asTestLib.c @@ -109,11 +109,7 @@ static void hookPass0(initHookState state) 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, ""); + checkGetString(&entry, "rec0.DISV"); testOk1(dbPutString(&entry, "rec0.SEVR")==0); } else{ diff --git a/src/std/rec/test/softTest.c b/src/std/rec/test/softTest.c index b29c955f9..e9cb319a0 100644 --- a/src/std/rec/test/softTest.c +++ b/src/std/rec/test/softTest.c @@ -12,6 +12,7 @@ #include "dbTest.h" #include "dbUnitTest.h" #include "epicsThread.h" +#include "epicsEvent.h" #include "errlog.h" #include "registryFunction.h" #include "subRecord.h" @@ -134,24 +135,25 @@ void testGroup2(void) int dest; +epicsEventId destEvent; static long destSubr(subRecord *prec) { dest = prec->val; prec->val = -1; + epicsEventMustTrigger(destEvent); return 0; } static -void checkOutput(const char *rec, int value) +void checkOutput3(const char *rec, int value) { testDiag("Checking record '%s'", rec); testdbPutFieldOk(rec, DBR_LONG, value); - /* Even with a local CA link, the dest record gets processed in - * the context of this thread (i.e. immediately). TPRO confirms. - */ + + epicsEventMustWait(destEvent); testOk(dest == value, "value %d output -> %d", value, dest); } @@ -170,22 +172,33 @@ void testGroup3(void) NULL, }; + destEvent = epicsEventMustCreate(epicsEventEmpty); + testDiag("============ Starting %s ============", EPICS_FUNCTION); for (rec = records; *rec; rec++) { - checkOutput(*rec, 1); + checkOutput3(*rec, 1); checkDtyp(*rec); } - checkOutput("do3.B0", 1); + checkOutput3("do3.B0", 1); checkDtyp("do3"); - checkOutput("do3c.B0", 1); + checkOutput3("do3c.B0", 1); checkDtyp("do3c"); for (rec = records; *rec; rec++) { - checkOutput(*rec, 0); + checkOutput3(*rec, 0); } - checkOutput("do3.B0", 0); - checkOutput("do3c.B0", 0); + checkOutput3("do3.B0", 0); + checkOutput3("do3c.B0", 0); +} + + +static +void checkOutput4(const char *rec, int value) +{ + testDiag("Checking record '%s'", rec); + + testdbPutFieldOk(rec, DBR_LONG, value); } /* Group 4 are all soft-channel output records with OUT being empty @@ -202,7 +215,7 @@ void testGroup4(void) testDiag("============ Starting %s ============", EPICS_FUNCTION); for (rec = records; *rec; rec++) { - checkOutput(*rec, 0); + checkOutput4(*rec, 0); } } @@ -211,7 +224,7 @@ void recTestIoc_registerRecordDeviceDriver(struct dbBase *); MAIN(softTest) { - testPlan(266); + testPlan(258); testdbPrepare(); testdbReadDatabase("recTestIoc.dbd", NULL, NULL); diff --git a/src/tools/convertRelease.pl b/src/tools/convertRelease.pl index 5900612f3..0da10bb72 100644 --- a/src/tools/convertRelease.pl +++ b/src/tools/convertRelease.pl @@ -231,10 +231,10 @@ sub checkRelease { AbsPath($macros{$parent}) ne AbsPath($ppath)) { print "\n" unless ($status); print "Definition of $parent conflicts with $app support.\n"; - print "In this application a RELEASE file defines\n"; - print "\t$parent = $macros{$parent}\n"; - print "but $app at $path defines\n"; - print "\t$parent = $ppath\n"; + print "In this application or module, a RELEASE file\n"; + print "conflicts with $app at $path\n"; + print " Here: $parent = $macros{$parent}\n"; + print " $app: $parent = $ppath\n"; $status = 1; } }