diff --git a/.github/workflows/ci-scripts-build.yml b/.github/workflows/ci-scripts-build.yml index e8dd9c85b..65384d23b 100644 --- a/.github/workflows/ci-scripts-build.yml +++ b/.github/workflows/ci-scripts-build.yml @@ -29,6 +29,7 @@ on: - '.gitattributes' - '**/*.html' - '**/*.md' + workflow_dispatch: env: SETUP_PATH: .ci-local:.ci diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION index 12120cddb..7972433a1 100644 --- a/configure/CONFIG_BASE_VERSION +++ b/configure/CONFIG_BASE_VERSION @@ -48,7 +48,7 @@ EPICS_VERSION = 7 EPICS_REVISION = 0 # EPICS_MODIFICATION must be a number >=0 and <256 -EPICS_MODIFICATION = 7 +EPICS_MODIFICATION = 8 # EPICS_PATCH_LEVEL must be a number (win32 resource file requirement) # Not included in the official EPICS version number if zero diff --git a/configure/CONFIG_CA_VERSION b/configure/CONFIG_CA_VERSION index 1fe4f1c25..2cff78816 100644 --- a/configure/CONFIG_CA_VERSION +++ b/configure/CONFIG_CA_VERSION @@ -2,7 +2,7 @@ EPICS_CA_MAJOR_VERSION = 4 EPICS_CA_MINOR_VERSION = 14 -EPICS_CA_MAINTENANCE_VERSION = 3 +EPICS_CA_MAINTENANCE_VERSION = 4 # Development flag, set to zero for release versions diff --git a/configure/CONFIG_DATABASE_VERSION b/configure/CONFIG_DATABASE_VERSION index 8b4002ae6..8815d2d1e 100644 --- a/configure/CONFIG_DATABASE_VERSION +++ b/configure/CONFIG_DATABASE_VERSION @@ -1,7 +1,7 @@ # Version number for the database APIs and shared library EPICS_DATABASE_MAJOR_VERSION = 3 -EPICS_DATABASE_MINOR_VERSION = 22 +EPICS_DATABASE_MINOR_VERSION = 23 EPICS_DATABASE_MAINTENANCE_VERSION = 1 # Development flag, set to zero for release versions diff --git a/configure/CONFIG_LIBCOM_VERSION b/configure/CONFIG_LIBCOM_VERSION index 898df2c67..4aab82a17 100644 --- a/configure/CONFIG_LIBCOM_VERSION +++ b/configure/CONFIG_LIBCOM_VERSION @@ -1,7 +1,7 @@ # Version number for the libcom APIs and shared library EPICS_LIBCOM_MAJOR_VERSION = 3 -EPICS_LIBCOM_MINOR_VERSION = 22 +EPICS_LIBCOM_MINOR_VERSION = 23 EPICS_LIBCOM_MAINTENANCE_VERSION = 1 # Development flag, set to zero for release versions diff --git a/configure/RULES_BUILD b/configure/RULES_BUILD index d49ea0e84..f4b2e9229 100644 --- a/configure/RULES_BUILD +++ b/configure/RULES_BUILD @@ -552,11 +552,11 @@ endif # LOADABLE_SHRLIB_SUFFIX ifneq ($(INSTALL_CONFIGS),) $(INSTALL_CONFIG)/%: % $(ECHO) "Installing config file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) + @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $(abspath $< $(@D)) $(INSTALL_CONFIG)/%: ../% $(ECHO) "Installing config file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) + @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $(abspath $< $(@D)) endif $(INSTALL_INCLUDE)/%: $(COMMON_DIR)/% diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 862369125..ae98cae5a 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -20,7 +20,62 @@ should also be read to understand what has changed since earlier releases: **This version of EPICS has not been released yet.** -## Changes made on the 7.0 branch since 7.0.7 +## Changes made on the 7.0 branch since 7.0.8 + + +----- + +## EPICS Release 7.0.8 + +### bi "Raw Soft Channel" use MASK + +If MASK is non-zero, The raw device support will now apply MASK to the +value read into RVAL. +eg. allows extraction of a bit from an input integer. + +``` +record(longin, "integer") { + field(VAL, "0xff") +} +record(bi, "bit1") { + field(DESC, "extract bit 1") + field(DTYP, "Raw Soft Channel") + field(INP , "integer") + field(MASK, "0x2") + field(ZNAM, "Clear") + field(ONAM, "Set") +} +``` + +### ANSI escapes in stderr + +ANSI escape charactor sequences may now be printed to the stderr stream. +These escapes will appear in logs captured from that stream. +Tools which parse and/or render these logs may need to be adjusted to +either strip out the escapes, or to translate them into markup. +(see [ansi2html](https://pypi.org/project/ansi2html/) for example) + +### Allow explicit append with `dbRecordsOnceOnly!=0` + +Previously setting `dbRecordsOnceOnly!=0` prevented any further changes to a record via a .db file. eg. + +``` +record(ai, "myrec") {} +``` + +`dbRecordsOnceOnly!=0` previously disallowed appending fields with either form: + +``` +record("*", "myrec") {} # error +record(ai, "myrec") {} # error +``` + +Beginning with this release, `dbRecordsOnceOnly!=0` allows appending when explicitly intended (when record type is `"*"`). + +``` +record("*", "myrec") {} # allowed +record(ai, "myrec") {} # error +``` ### PROC field changed to ASL0 diff --git a/documentation/ReleaseChecklist.html b/documentation/ReleaseChecklist.html index ac65fef3b..0db98a818 100644 --- a/documentation/ReleaseChecklist.html +++ b/documentation/ReleaseChecklist.html @@ -48,14 +48,14 @@ everything that has to be done since it's so easy to miss steps.

The following roles are used below:

-
Release Manager ()
+
Release Manager
Responsible for managing and tagging the release
-
Platform Developers (informal)
-
Responsible for individual operating system platforms
+
Core Developers
+
Responsible for maintaining the EPICS software
Application Developers
Responsible for support modules that depend on EPICS Base.
-
APS Website Editor (Andrew Johnson)
-
Responsible for the APS EPICS website
+
Website Editors
+
Responsible for the EPICS websites
@@ -72,23 +72,22 @@ everything that has to be done since it's so easy to miss steps.

  Release Manager - Email all developers about the upcoming release and ask for a list - of remaining tasks that must be finished. + Notify core developers about the upcoming release and ask about any + remaining tasks that must be finished.   All developers Check the bug tracker for any outstanding items and handle - appropriately. All bugs that have been fixed should have been marked - as Fix Committed. + appropriately.   Release Manager - Set the Feature Freeze date, by which time all Git commits for - enhancements and new functionality should have been completed. After - this date, commits should only be made to fix problems that show up - during testing. + Set a Feature Freeze date, by which time all Git branches for + enhancements and new functionality should have been merged. After this + date, commits and merges should only be made to fix problems that show + up during testing.   @@ -97,6 +96,7 @@ everything that has to be done since it's so easy to miss steps.

Ensure that documentation will be updated before the release date: @@ -104,13 +104,8 @@ everything that has to be done since it's so easy to miss steps.

  Release Manager - Review and update this checklist for the upcoming release. - - -   - Release Manager - Create a release milestone on Launchpad. If a target release date is - known set "Date Targeted" to the expected release date. + Review and update this checklist for the upcoming release. + Update the release version number in the tags and messages below. Testing @@ -118,7 +113,7 @@ everything that has to be done since it's so easy to miss steps.

  Platform Developers - Run the built-in test programs on all available host platforms using + Run the internal test programs on all available host platforms using
make -s runtests
@@ -156,6 +151,7 @@ everything that has to be done since it's so easy to miss steps.

Check that documentation has been updated: @@ -167,8 +163,8 @@ everything that has to be done since it's so easy to miss steps.

- Release Manager - Obtain a positive Ok to release from developers. + Core Developers + Reach a consensus that the software is ready to release. Creating the final release version @@ -191,27 +187,29 @@ everything that has to be done since it's so easy to miss steps.

cd base-7.0/modules/<module>/documentation
pandoc -f gfm -t html -o RELEASE_NOTES.html RELEASE_NOTES.md - Commit changes (don't push). + Commit these changes (don't push).
  • Edit the module's release version file - configure/CONFIG_module_VERSION and its top-level - Doxyfile; set the DEVELOPMENT_FLAG value to 0 and - remove -dev from the PROJECT_NUMBER string. - Commit changes (don't push).
  • + configure/CONFIG_module_VERSION and the + Doxyfiles in the top-level and/or documentation + directories. In these, set DEVELOPMENT_FLAG to 0 and remove + -dev from the PROJECT_NUMBER string. Commit these + changes (don't push).
  • Tag the module:
    - git tag -m 'ANJ: Tag for EPICS 7.0.7' <module-version> + git tag -m 'ANJ: Tag for EPICS 7.0.8' <module-version>
  • Update the git submodule on the Base-7.0 branch to the - newly-tagged version, but don't commit yet: + newly-tagged version, check the module's status matches the tag:
    cd base-7.0/modules
    git add <module>
    git submodule status --cached
    + Don't commit the submodule updates yet.
  • Edit the module's release version file @@ -221,7 +219,8 @@ everything that has to be done since it's so easy to miss steps.

    PROJECT_NUMBER string, appending -dev to the new module version number. Commit changes.
  • -
  • Push commits and the new tag to the submodule's GitHub repository: +
  • Push commits and the new tag to the submodule's GitHub repository + (assumed to be the upstream remote):
    cd base-7.0/modules/<module>
    git push --follow-tags upstream master @@ -270,10 +269,9 @@ everything that has to be done since it's so easy to miss steps.

    Tag the epics-base module in Git:
    cd base-7.0
    - git tag -m 'ANJ: Tagged for release' R7.0.7 + git tag -m 'ANJ: Tagged for release' R7.0.8
    -

    Don't push anything to the Launchpad repository - yet.

    +

    Don't push to GitHub yet.

    @@ -305,12 +303,12 @@ everything that has to be done since it's so easy to miss steps.

    files and directories that are only used for continuous integration:
    cd base-7.0
    - ./.tools/make-tar.sh R7.0.7 ../base-7.0.7.tar.gz base-7.0.7/ + ./.tools/make-tar.sh R7.0.8 ../base-7.0.8.tar.gz base-7.0.8/
    Create a GPG signature file of the tarfile as follows:
    cd ..
    - gpg --armor --sign --detach-sig base-7.0.7.tar.gz + gpg --armor --sign --detach-sig base-7.0.8.tar.gz
    @@ -318,8 +316,9 @@ everything that has to be done since it's so easy to miss steps.

    Release Manager Test the tar file by extracting its contents and building it on at - least one supported platform. When this succeeds the commits and new git - tag can be pushed to the Launchpad repository: + least one supported platform. If this succeeds the commits and new git + tag can be pushed to the GitHub repository's 7.0 branch (assumed to be + the upstream remote):
    git push --follow-tags upstream 7.0
    @@ -367,7 +366,7 @@ everything that has to be done since it's so easy to miss steps.

    - Publish to epics-controls + Publish to epics-controls.org @@ -375,7 +374,7 @@ everything that has to be done since it's so easy to miss steps.

    Upload the tar file and its .asc signature file to the epics-controls web-server.
    - scp base-7.0.7.tar.gz base-7.0.7.tar.gz.asc epics-controls:download/base
    + scp base-7.0.8.tar.gz base-7.0.8.tar.gz.asc epics-controls:download/base
    @@ -392,22 +391,22 @@ everything that has to be done since it's so easy to miss steps.

    - Publish to Launchpad + Publish to GitHub Release Manager - Go to the Launchpad milestone for this release. Click the Create - release button and add the release date. Put a URL for the release page - in the Release notes box, and click the Create release button. Upload - the tar file and its .asc signature file to the new Launchpad - release page. + Go to the GitHub + + Create release from tag R7.0.8 page. + Upload the tar file and its .asc signature file to the new + GitHub release page. Release Manager - Find all Launchpad bug reports with the status Fix Committed which - have been fixed in this release and mark them Fix Released. + We used to close out bug reports in Launchpad at release-time, this + would be the time to do that if we have an equivalent on GitHub. diff --git a/modules/Makefile b/modules/Makefile index 11a1671fb..575824e34 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -34,9 +34,6 @@ pvDatabase_DEPEND_DIRS = pvAccess SUBMODULES += pva2pva pva2pva_DEPEND_DIRS = pvAccess -SUBMODULES += example -example_DEPEND_DIRS = pva2pva pvaClient - SUBMODULES += pcas pcas_DEPEND_DIRS = ca diff --git a/modules/ca/src/client/acctst.c b/modules/ca/src/client/acctst.c index 34298680c..44cc0673a 100644 --- a/modules/ca/src/client/acctst.c +++ b/modules/ca/src/client/acctst.c @@ -2575,7 +2575,8 @@ void monitorUpdateTest ( chid chan, unsigned interestLevel ) SEVCHK ( ca_get ( DBR_FLOAT, chan, &temp ), NULL ); SEVCHK ( ca_pend_io ( timeoutToPendIO ), NULL ); - /* printf ( "flow control bypassed %u events\n", flowCtrlCount ); */ + if (0) + printf ( "flow control bypassed %u events\n", flowCtrlCount ); showProgressEnd ( interestLevel ); } diff --git a/modules/ca/src/client/cac.cpp b/modules/ca/src/client/cac.cpp index f8d1d0800..fd641ad21 100644 --- a/modules/ca/src/client/cac.cpp +++ b/modules/ca/src/client/cac.cpp @@ -25,6 +25,7 @@ #include #include // vxWorks 6.0 requires this include +#include "epicsStdio.h" #include "dbDefs.h" #include "epicsGuard.h" #include "epicsVersion.h" @@ -1008,7 +1009,7 @@ bool cac::defaultExcep ( char buf[512]; char hostName[64]; iiu.getHostName ( guard, hostName, sizeof ( hostName ) ); - sprintf ( buf, "host=%s ctx=%.400s", hostName, pCtx ); + epicsSnprintf( buf, sizeof(buf), "host=%s ctx=%.400s", hostName, pCtx ); this->notify.exception ( guard, status, buf, 0, 0u ); return true; } @@ -1312,7 +1313,7 @@ void cac::pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv, const char * pChannelName, const char * pAcc, const char * pRej ) { char buf[256]; - sprintf ( buf, "Channel: \"%.64s\", Connecting to: %.64s, Ignored: %.64s", + epicsSnprintf( buf, sizeof(buf), "Channel: \"%.64s\", Connecting to: %.64s, Ignored: %.64s", pChannelName, pAcc, pRej ); { callbackManager mgr ( this->notify, this->cbMutex ); diff --git a/modules/ca/src/client/iocinf.cpp b/modules/ca/src/client/iocinf.cpp index c760a0d34..8bd42f108 100644 --- a/modules/ca/src/client/iocinf.cpp +++ b/modules/ca/src/client/iocinf.cpp @@ -21,6 +21,9 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#include +#include + #include #include #include @@ -28,6 +31,7 @@ #include "envDefs.h" #include "epicsAssert.h" +#include "epicsString.h" #include "epicsStdioRedirect.h" #include "errlog.h" #include "osiWireFormat.h" @@ -35,39 +39,6 @@ #include "addrList.h" #include "iocinf.h" -/* - * getToken() - */ -static char *getToken ( const char **ppString, char *pBuf, unsigned bufSIze ) -{ - bool tokenFound = false; - const char *pToken; - unsigned i; - - pToken = *ppString; - while ( isspace (*pToken) && *pToken ){ - pToken++; - } - - for ( i=0u; iname); - fprintf ( stderr, "\tBad internet address or host name: '%s'\n", pToken); - continue; + try { + std::vector scratch(pStr, pStr+strlen(pStr)+1); // copy chars and trailing nil + + char *save = NULL; + for(const char *pToken = epicsStrtok_r(&scratch[0], " \t\n\r", &save); + pToken; + pToken = epicsStrtok_r(NULL, " \t\n\r", &save)) + { + if(!pToken[0]) { + continue; + } + + status = aToIPAddr ( pToken, port, &addr ); + if (status<0) { + fprintf ( stderr, "%s: Parsing '%s'\n", __FILE__, pEnv->name); + fprintf ( stderr, "\tBad internet address or host name: '%s'\n", pToken); + continue; + } + + if ( ignoreNonDefaultPort && ntohs ( addr.sin_port ) != port ) { + continue; + } + + pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode)); + if (pNewNode==NULL) { + fprintf ( stderr, "addAddrToChannelAccessAddressList(): no memory available for configuration\n"); + break; + } + + pNewNode->addr.ia = addr; + + /* + * LOCK applied externally + */ + ellAdd (pList, &pNewNode->node); + ret = 0; /* success if anything is added to the list */ } - - if ( ignoreNonDefaultPort && ntohs ( addr.sin_port ) != port ) { - continue; - } - - pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode)); - if (pNewNode==NULL) { - fprintf ( stderr, "addAddrToChannelAccessAddressList(): no memory available for configuration\n"); - break; - } - - pNewNode->addr.ia = addr; - - /* - * LOCK applied externally - */ - ellAdd (pList, &pNewNode->node); - ret = 0; /* success if anything is added to the list */ + } catch(std::exception&) { // only bad_alloc currently possible + ret = -1; } return ret; diff --git a/modules/database/src/ioc/as/asIocRegister.c b/modules/database/src/ioc/as/asIocRegister.c index dcc2a6bdd..b0451bc17 100644 --- a/modules/database/src/ioc/as/asIocRegister.c +++ b/modules/database/src/ioc/as/asIocRegister.c @@ -90,7 +90,7 @@ static const iocshFuncDef asprulesFuncDef = { "asprules",1,asprulesArgs, "List rules of an Access Security Group.\n" "If no Group is specified then list the rules for all groups\n" - "Example: asprules mygroup" + "Example: asprules mygroup\n" }; static void asprulesCallFunc(const iocshArgBuf *args) { diff --git a/modules/database/src/ioc/db/dbUnitTest.c b/modules/database/src/ioc/db/dbUnitTest.c index 2c7efd8a9..bf4ec205b 100644 --- a/modules/database/src/ioc/db/dbUnitTest.c +++ b/modules/database/src/ioc/db/dbUnitTest.c @@ -50,6 +50,7 @@ void testdbPrepare(void) { if(!testEvtLock) testEvtLock = epicsMutexMustCreate(); + initHookAnnounce(initHookAfterPrepareDatabase); } void testdbReadDatabase(const char* file, @@ -94,6 +95,7 @@ void testIocShutdownOk(void) void testdbCleanup(void) { + initHookAnnounce(initHookBeforeCleanupDatabase); dbFreeBase(pdbbase); db_cleanup_events(); initHookFree(); diff --git a/modules/database/src/ioc/dbStatic/dbBase.h b/modules/database/src/ioc/dbStatic/dbBase.h index 35ca0a638..f0a954b50 100644 --- a/modules/database/src/ioc/dbStatic/dbBase.h +++ b/modules/database/src/ioc/dbStatic/dbBase.h @@ -118,6 +118,10 @@ typedef struct dbRecordNode { char *recordname; ELLLIST infoList; /*LIST head of info nodes*/ int flags; + /** Parse order of this record() + * @since UNRELEASED + */ + unsigned order; struct dbRecordNode *aliasedRecnode; /* NULL unless flags|DBRN_FLAGS_ISALIAS */ }dbRecordNode; @@ -184,5 +188,9 @@ typedef struct dbBase { struct gphPvt *pgpHash; short ignoreMissingMenus; short loadCdefs; + /** Total number of records. + * @since UNRELEASED + */ + unsigned no_records; }dbBase; #endif diff --git a/modules/database/src/ioc/dbStatic/dbLexRoutines.c b/modules/database/src/ioc/dbStatic/dbLexRoutines.c index 7acaaa292..cd3c6ff0d 100644 --- a/modules/database/src/ioc/dbStatic/dbLexRoutines.c +++ b/modules/database/src/ioc/dbStatic/dbLexRoutines.c @@ -247,23 +247,23 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp, } my_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char)); freeListInitPvt(&freeListPvt,sizeof(tempListNode),100); - if(substitutions) { - if(macCreateHandle(&macHandle,NULL)) { - epicsPrintf("macCreateHandle error\n"); - status = -1; - goto cleanup; - } - macParseDefns(macHandle,(char *)substitutions,&macPairs); - if(macPairs ==NULL) { - macDeleteHandle(macHandle); - macHandle = NULL; - } else { - macInstallMacros(macHandle,macPairs); - free((void *)macPairs); - mac_input_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char)); - } - macSuppressWarning(macHandle,dbQuietMacroWarnings); + if (substitutions == NULL) + substitutions = ""; + if(macCreateHandle(&macHandle,NULL)) { + epicsPrintf("macCreateHandle error\n"); + status = -1; + goto cleanup; } + macParseDefns(macHandle,substitutions,&macPairs); + if(macPairs == NULL) { + macDeleteHandle(macHandle); + macHandle = NULL; + } else { + macInstallMacros(macHandle,macPairs); + free(macPairs); + mac_input_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char)); + } + macSuppressWarning(macHandle,dbQuietMacroWarnings); pinputFile = dbCalloc(1,sizeof(inputFile)); if (filename) { pinputFile->filename = macEnvExpand(filename); diff --git a/modules/database/src/ioc/dbStatic/link.h b/modules/database/src/ioc/dbStatic/link.h index a7edebf57..6488e8caa 100644 --- a/modules/database/src/ioc/dbStatic/link.h +++ b/modules/database/src/ioc/dbStatic/link.h @@ -193,7 +193,7 @@ struct lset; struct link { struct dbCommon *precord; /* Pointer to record owning link */ short type; - short flags; + unsigned short flags; struct lset *lset; char *text; /* Raw link text */ union value value; diff --git a/modules/database/src/std/rec/biRecord.dbd.pod b/modules/database/src/std/rec/biRecord.dbd.pod index 157c33fe6..c62b291ad 100644 --- a/modules/database/src/std/rec/biRecord.dbd.pod +++ b/modules/database/src/std/rec/biRecord.dbd.pod @@ -61,8 +61,8 @@ this chapter for information on soft device support. If the record gets its values from hardware or uses the C device support, the device support routines place the value in the RVAL field. -(Since UNRELEASED) If the MASK field is non-zero, then this MASK is applied to RVAL. -The value of RVAL is then converted using the process described in the +(Since 7.0.8) If the MASK field is non-zero, then this MASK is applied to RVAL. +The value from RVAL is then converted using the process described in the next section. =fields INP, DTYP, ZNAM, ONAM, RVAL, VAL diff --git a/modules/database/src/std/rec/calcRecord.dbd.pod b/modules/database/src/std/rec/calcRecord.dbd.pod index 23893feeb..4619dd4e3 100644 --- a/modules/database/src/std/rec/calcRecord.dbd.pod +++ b/modules/database/src/std/rec/calcRecord.dbd.pod @@ -158,7 +158,7 @@ CEIL: Ceiling (unary) FLOOR: Floor (unary) =item * -FMOD: Floating point modulo (binary) Added in UNRELEASED +FMOD: Floating point modulo (binary) Added in 7.0.8 =item * LOG: Log base 10 (unary) diff --git a/modules/database/src/std/rec/calcoutRecord.dbd.pod b/modules/database/src/std/rec/calcoutRecord.dbd.pod index b62f57520..490aec9c9 100644 --- a/modules/database/src/std/rec/calcoutRecord.dbd.pod +++ b/modules/database/src/std/rec/calcoutRecord.dbd.pod @@ -184,7 +184,7 @@ CEIL: Ceiling (unary) FLOOR: Floor (unary) =item * -FMOD: Floating point modulo (binary) Added in UNRELEASED +FMOD: Floating point modulo (binary) Added in 7.0.8 =item * LOG: Log base 10 (unary) diff --git a/modules/database/src/std/rec/longoutRecord.dbd.pod b/modules/database/src/std/rec/longoutRecord.dbd.pod index 912573749..9fead68d4 100644 --- a/modules/database/src/std/rec/longoutRecord.dbd.pod +++ b/modules/database/src/std/rec/longoutRecord.dbd.pod @@ -85,7 +85,7 @@ for information on the format of hardware addresses and database links. =head4 Menu longoutOOPT -The OOPT field was added in EPICS UNRELEASED. +The OOPT field was added in EPICS 7.0.8. It determines the condition that causes the output link to be written to. It's a menu field that has six choices: @@ -119,7 +119,7 @@ VAL is non-zero and last value was zero. =head4 Changes in OUT field when OOPT = On Change -The OOCH field was added in EPICS UNRELEASED. +The OOCH field was added in EPICS 7.0.8. If OOCH is C (its default value) and the OOPT field is C, the record will write to the device support the first time the record gets diff --git a/modules/database/src/tools/dbdExpand.pl b/modules/database/src/tools/dbdExpand.pl index 5cd26728b..acd292a45 100644 --- a/modules/database/src/tools/dbdExpand.pl +++ b/modules/database/src/tools/dbdExpand.pl @@ -20,10 +20,14 @@ use EPICS::Getopts; use EPICS::Readfile; use EPICS::macLib; -our ($opt_D, @opt_I, @opt_S, $opt_o); +our ($opt_D, $opt_A, @opt_I, @opt_S, $opt_o); -getopts('DI@S@o:') or - die "Usage: dbdExpand [-D] [-I dir] [-S macro=val] [-o out.dbd] in.dbd ..."; +getopts('DAI@S@o:') or + die "Usage: dbdExpand [-D] [-A] [-I dir] [-S macro=val] [-o out.dbd] in.dbd ..."; + +if ($opt_A) { + $DBD::Parser::allowAutoDeclarations = 1; +} my @path = map { split /[:;]/ } @opt_I; # FIXME: Broken on Win32? my $macros = EPICS::macLib->new(@opt_S); diff --git a/modules/libcom/src/as/asLibRoutines.c b/modules/libcom/src/as/asLibRoutines.c index 59dd80bda..571471e2a 100644 --- a/modules/libcom/src/as/asLibRoutines.c +++ b/modules/libcom/src/as/asLibRoutines.c @@ -366,7 +366,7 @@ long epicsStdCall asAddClient(ASCLIENTPVT *pasClientPvt,ASMEMBERPVT asMemberPvt, { ASGMEMBER *pasgmember = asMemberPvt; ASGCLIENT *pasgclient; - int len, i; + size_t len, i; long status; if(!asActive) return(S_asLib_asNotActive); @@ -394,7 +394,7 @@ long epicsStdCall asChangeClient( { ASGCLIENT *pasgclient = asClientPvt; long status; - int len, i; + size_t len, i; if(!asActive) return(S_asLib_asNotActive); if(!pasgclient) return(S_asLib_badClient); diff --git a/modules/libcom/src/calc/postfix.h b/modules/libcom/src/calc/postfix.h index c9fdc1ee7..5d75a7ddf 100644 --- a/modules/libcom/src/calc/postfix.h +++ b/modules/libcom/src/calc/postfix.h @@ -222,7 +222,7 @@ extern "C" { * - n parameter minimum value: min(a, b, ...) * - Square root: sqr(a) or sqrt(a) * - Floating point modulo: fmod(num, den) - * \since The fmod() function was added in UNRELEASED + * \since The fmod() function was added in 7.0.8 * * -# ***Trigonometric Functions*** * Standard circular trigonometric functions, with angles expressed in radians: diff --git a/modules/libcom/src/error/errlog.h b/modules/libcom/src/error/errlog.h index 4aaf054ac..44a504812 100644 --- a/modules/libcom/src/error/errlog.h +++ b/modules/libcom/src/error/errlog.h @@ -180,8 +180,8 @@ LIBCOM_API void errlogAddListener(errlogListener listener, void *pPrivate); * \param listener Function pointer of type ::errlogListener * \param pPrivate This will be passed as the first argument of listener() * - * \since UNRELEASED Safe to call from a listener callback. - * \until UNRELEASED Self-removal from a listener callback caused corruption. + * \since 7.0.8 Safe to call from a listener callback. + * \until 7.0.8 Self-removal from a listener callback caused corruption. */ LIBCOM_API int errlogRemoveListeners(errlogListener listener, void *pPrivate); diff --git a/modules/libcom/src/flex/Makefile b/modules/libcom/src/flex/Makefile index 5c6f41bfe..9b98e33d5 100644 --- a/modules/libcom/src/flex/Makefile +++ b/modules/libcom/src/flex/Makefile @@ -19,7 +19,7 @@ parse_CPPFLAGS = -DDEFAULT_SKELETON_FILE=$(SKELETON_FILE) INC += flex.skel.static -# flex.c is included in parse.c +# flex.c, scan.c and yylex.c are #included by parse.c e_flex_SRCS += ccl.c e_flex_SRCS += dfa.c e_flex_SRCS += ecs.c diff --git a/modules/libcom/src/flex/ccl.c b/modules/libcom/src/flex/ccl.c index 4d278ba2a..48a2ccc57 100644 --- a/modules/libcom/src/flex/ccl.c +++ b/modules/libcom/src/flex/ccl.c @@ -132,7 +132,6 @@ void cclnegate(int cclp) void list_character_set(FILE *file, int cset[]) { int i; - char *readable_form(); putc( '[', file ); diff --git a/modules/libcom/src/flex/flex.c b/modules/libcom/src/flex/flex.c index 79ea51dda..349d8aff3 100644 --- a/modules/libcom/src/flex/flex.c +++ b/modules/libcom/src/flex/flex.c @@ -188,7 +188,6 @@ int main(int argc, char *argv[]) void flexend(int status) { int tblsiz; - char *flex_gettime(); if ( skelfile != NULL ) { @@ -382,7 +381,7 @@ void flexend(int status) void flexinit(int argc, char **argv) { int i, sawcmpflag; - char *arg, *flex_gettime(), *mktemp(); + char *arg; printstats = syntaxerror = trace = spprdflt = interactive = caseins = false; backtrack_report = performance_report = ddebug = fulltbl = fullspd = false; diff --git a/modules/libcom/src/flex/flexdef.h b/modules/libcom/src/flex/flexdef.h index 0a9736e6c..dd6123da2 100644 --- a/modules/libcom/src/flex/flexdef.h +++ b/modules/libcom/src/flex/flexdef.h @@ -567,8 +567,8 @@ extern int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; extern int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; extern int num_backtracking, bol_needed; -void *allocate_array(int size, int element_size); -void *reallocate_array(void *array, int size, int element_size); +extern void *allocate_array(int size, int element_size); +extern void *reallocate_array(void *array, int size, int element_size); #define allocate_integer_array(size) \ (int *) allocate_array( size, sizeof( int ) ) @@ -677,10 +677,20 @@ extern int all_upper (Char *); /* bubble sort an integer array */ extern void bubble (int [], int); +/* replace upper-case letter to lower-case */ +extern Char clower(int c); + +/* returns copy of a string */ +extern char *copy_string(char *str); + +/* returns copy of a (potentially) unsigned string */ +extern Char *copy_unsigned_string(Char *str); + /* shell sort a character array */ extern void cshell (Char [], int, int); -extern void dataend (void); /* finish up a block of data declarations */ +/* finish up a block of data declarations */ +extern void dataend (void); /* report an error message and terminate */ extern void flexerror (char[]) NORETURN; @@ -688,6 +698,9 @@ extern void flexerror (char[]) NORETURN; /* report a fatal error message and terminate */ extern void flexfatal (char[]); +/* return current time */ +extern char *flex_gettime(); + /* report an error message formatted with one integer argument */ extern void lerrif (char[], int); @@ -700,11 +713,18 @@ extern void line_directive_out (FILE*); /* generate a data statment for a two-dimensional array */ extern void mk2data (int); -extern void mkdata (int); /* generate a data statement */ +/* generate a data statement */ +extern void mkdata (int); /* return the integer represented by a string of digits */ extern int myctoi (Char []); +/* return character corresponding to escape sequence */ +extern Char myesc(Char *array); + +/* return the the human-readable form of a character */ +extern char *readable_form(int c); + /* write out one section of the skeleton file */ extern void skelout (void); @@ -784,8 +804,14 @@ extern void cclinstal (Char [], int); /* lookup the number associated with character class */ extern int ccllookup (Char []); -extern void ndinstal (char[], Char[]); /* install a name definition */ -extern void scinstal (char[], int); /* make a start condition */ +/* install a name definition */ +extern void ndinstal (char[], Char[]); + +/* lookup a name definition */ +extern Char *ndlookup(char *nd); + +/* make a start condition */ +extern void scinstal (char[], int); /* lookup the number associated with a start condition */ extern int sclookup (char[]); diff --git a/modules/libcom/src/flex/gen.c b/modules/libcom/src/flex/gen.c index a10fbb537..f683d136c 100644 --- a/modules/libcom/src/flex/gen.c +++ b/modules/libcom/src/flex/gen.c @@ -217,7 +217,6 @@ void genecs(void) int i, j; static char C_char_decl[] = "static const %s %s[%d] =\n { 0,\n"; int numrows; - Char clower(); if ( numecs < csize ) printf( C_char_decl, "YY_CHAR", "yy_ec", csize ); @@ -237,8 +236,6 @@ void genecs(void) if ( trace ) { - char *readable_form(); - fputs( "\n\nEquivalence Classes:\n\n", stderr ); numrows = csize / 8; diff --git a/modules/libcom/src/flex/parse.y b/modules/libcom/src/flex/parse.y index 21ac91730..09aebc5b3 100644 --- a/modules/libcom/src/flex/parse.y +++ b/modules/libcom/src/flex/parse.y @@ -34,11 +34,18 @@ int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen; int trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule; -Char clower(); static int madeany = false; /* whether we've made the '.' character class */ int previous_continued_action; /* whether the previous rule's action was '|' */ +/* forward declarations */ + +void build_eof_action( void ); +void synerr( char str[] ); +void format_pinpoint_message( char msg[], char arg[] ); +void pinpoint_message( char str[] ); +void yyerror( char msg[] ); + %} %% @@ -626,7 +633,7 @@ string : string CHAR * conditions */ -void build_eof_action() +void build_eof_action( void ) { int i; @@ -652,8 +659,7 @@ void build_eof_action() /* synerr - report a syntax error */ -void synerr( str ) -char str[]; +void synerr( char str[] ) { syntaxerror = true; @@ -665,8 +671,7 @@ char str[]; * pinpointing its location */ -void format_pinpoint_message( msg, arg ) -char msg[], arg[]; +void format_pinpoint_message( char msg[], char arg[] ) { char errmsg[MAXLINE]; @@ -678,8 +683,7 @@ char msg[], arg[]; /* pinpoint_message - write out a message, pinpointing its location */ -void pinpoint_message( str ) -char str[]; +void pinpoint_message( char str[] ) { fprintf( stderr, "\"%s\", line %d: %s\n", infilename, linenum, str ); @@ -690,8 +694,7 @@ char str[]; * currently, messages are ignore */ -void yyerror( msg ) -char msg[]; +void yyerror( char msg[] ) { } diff --git a/modules/libcom/src/flex/scan.c b/modules/libcom/src/flex/scan.c index 67c6be38c..e1fd68eb3 100644 --- a/modules/libcom/src/flex/scan.c +++ b/modules/libcom/src/flex/scan.c @@ -953,6 +953,7 @@ void yy_load_buffer_state ( void ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); void yy_delete_buffer ( YY_BUFFER_STATE b ); void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +void set_input_file( char *file ); #define yy_new_buffer yy_create_buffer @@ -966,7 +967,7 @@ YY_DECL static int bracelevel, didadef; int i, indented_code = false, checking_used = false, new_xlation = false; int doing_codeblock = false; - Char nmdef[MAXLINE], myesc(); + Char nmdef[MAXLINE]; if ( yy_init ) @@ -1488,7 +1489,6 @@ case 65: # line 333 "scan.l" { Char *nmdefptr; - Char *ndlookup(); (void) strcpy( nmstr, (char *) yytext ); nmstr[yyleng - 1] = '\0'; /* chop trailing brace */ @@ -2230,8 +2230,7 @@ int yywrap() /* set_input_file - open the given file (if NULL, stdin) for scanning */ -void set_input_file( file ) -char *file; +void set_input_file( char *file ) { if ( file ) diff --git a/modules/libcom/src/flex/sym.c b/modules/libcom/src/flex/sym.c index e17d59427..59dac35d8 100644 --- a/modules/libcom/src/flex/sym.c +++ b/modules/libcom/src/flex/sym.c @@ -108,8 +108,6 @@ void cclinstal(Char *ccltxt, int cclnum) /* we don't bother checking the return status because we are not called * unless the symbol is new */ - Char *copy_unsigned_string(); - (void) addsym( (char *) copy_unsigned_string( ccltxt ), (char *) 0, cclnum, ccltab, CCL_HASH_SIZE ); } @@ -191,9 +189,6 @@ int hashfunct(char *str, int hash_size) void ndinstal(char *nd, Char *def) { - char *copy_string(); - Char *copy_unsigned_string(); - if ( addsym( copy_string( nd ), (char *) copy_unsigned_string( def ), 0, ndtbl, NAME_TABLE_HASH_SIZE ) ) synerr( "name defined twice" ); @@ -227,8 +222,6 @@ Char *ndlookup(char *nd) void scinstal(char *str, int xcluflg) { - char *copy_string(); - /* bit of a hack. We know how the default start-condition is * declared, and don't put out a define for it, because it * would come out as "#define 0 1" diff --git a/modules/libcom/src/gpHash/gpHashLib.c b/modules/libcom/src/gpHash/gpHashLib.c index 3ed7de4f1..c4991a873 100644 --- a/modules/libcom/src/gpHash/gpHashLib.c +++ b/modules/libcom/src/gpHash/gpHashLib.c @@ -63,7 +63,7 @@ GPHENTRY * epicsStdCall gphFindParse(gphPvt *pgphPvt, const char *name, size_t l ELLLIST **paplist; ELLLIST *gphlist; GPHENTRY *pgphNode; - int hash; + unsigned hash; if (pgphPvt == NULL) return NULL; paplist = pgphPvt->paplist; @@ -99,7 +99,7 @@ GPHENTRY * epicsStdCall gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid) ELLLIST **paplist; ELLLIST *plist; GPHENTRY *pgphNode; - int hash; + unsigned hash; if (pgphPvt == NULL) return NULL; paplist = pgphPvt->paplist; @@ -144,7 +144,7 @@ void epicsStdCall gphDelete(gphPvt *pgphPvt, const char *name, void *pvtid) ELLLIST **paplist; ELLLIST *plist = NULL; GPHENTRY *pgphNode; - int hash; + unsigned hash; if (pgphPvt == NULL) return; paplist = pgphPvt->paplist; diff --git a/modules/libcom/src/iocsh/initHooks.c b/modules/libcom/src/iocsh/initHooks.c index 750a76d42..90b1de2c5 100644 --- a/modules/libcom/src/iocsh/initHooks.c +++ b/modules/libcom/src/iocsh/initHooks.c @@ -139,6 +139,9 @@ const char *initHookName(int state) "initHookBeforeFree", "initHookAfterShutdown", + "initHookAfterPrepareDatabase", + "initHookBeforeCleanupDatabase", + "initHookAfterInterruptAccept", "initHookAtEnd" }; diff --git a/modules/libcom/src/iocsh/initHooks.h b/modules/libcom/src/iocsh/initHooks.h index de4a72a32..573817f6b 100644 --- a/modules/libcom/src/iocsh/initHooks.h +++ b/modules/libcom/src/iocsh/initHooks.h @@ -71,6 +71,7 @@ extern "C" { * if the IOC is later paused and restarted. */ typedef enum { + // iocInit() begins initHookAtIocBuild = 0, /**< Start of iocBuild() / iocInit() */ initHookAtBeginning, /**< Database sanity checks passed */ @@ -110,7 +111,7 @@ typedef enum { */ initHookAfterCloseLinks, /** \brief Scan tasks stopped. - * \since UNRELEASED Triggered during normal IOC shutdown + * \since 7.0.8 Triggered during normal IOC shutdown * \since 7.0.3.1 Added, triggered only by unittest code. */ initHookAfterStopScan, @@ -119,7 +120,7 @@ typedef enum { */ initHookAfterStopCallback, /** \brief CA links stopped. - * \since UNRELEASED Triggered during normal IOC shutdown + * \since 7.0.8 Triggered during normal IOC shutdown * \since 7.0.3.1 Added, triggered only by unittest code. */ initHookAfterStopLinks, @@ -133,6 +134,17 @@ typedef enum { initHookAfterShutdown, // iocShutdown() ends + /** \brief Called during testdbPrepare() + * Use this hook to repeat actions each time an empty test database is initialized. + * \since 7.0.8 Added, triggered only by unittest code. + */ + initHookAfterPrepareDatabase, + /** \brief Called during testdbCleanup() + * Use this hook to perform cleanup each time before a test database is free()'d. + * \since 7.0.8 Added, triggered only by unittest code. + */ + initHookBeforeCleanupDatabase, + /* Deprecated states: */ /** Only announced once. Deprecated in favor of initHookAfterDatabaseRunning */ initHookAfterInterruptAccept, diff --git a/modules/libcom/src/iocsh/iocsh.h b/modules/libcom/src/iocsh/iocsh.h index 2c8da0998..90a534581 100644 --- a/modules/libcom/src/iocsh/iocsh.h +++ b/modules/libcom/src/iocsh/iocsh.h @@ -66,12 +66,16 @@ typedef enum { iocshArgPdbbase, iocshArgArgv, iocshArgPersistentString, - /** Equivalent to iocshArgString with a hint for tab completion as a record name. - * @since UNRELEASED + /** + * Equivalent to iocshArgString with a hint for tab completion that the + * argument is a record name. + * @since 7.0.8 */ iocshArgStringRecord, - /** Equivalent to iocshArgString with a hint for tab completion as a file system path. - * @since UNRELEASED + /** + * Equivalent to iocshArgString with a hint for tab completion that the + * argument is a file system path. + * @since 7.0.8 */ iocshArgStringPath, }iocshArgType; diff --git a/modules/libcom/src/iocsh/libComRegister.c b/modules/libcom/src/iocsh/libComRegister.c index f5469396c..5751ad070 100644 --- a/modules/libcom/src/iocsh/libComRegister.c +++ b/modules/libcom/src/iocsh/libComRegister.c @@ -193,7 +193,7 @@ static const iocshFuncDef epicsEnvShowFuncDef = {"epicsEnvShow",1,epicsEnvShowAr " (default) - show all environment variables\n" " name - show value of specific environment variable\n" "Example: epicsEnvShow\n" - "Example: epicsEnvShow PATH"}; + "Example: epicsEnvShow PATH\n"}; static void epicsEnvShowCallFunc(const iocshArgBuf *args) { epicsEnvShow (args[0].sval); diff --git a/modules/libcom/src/log/iocLogServer.c b/modules/libcom/src/log/iocLogServer.c index 81288d481..890176fb0 100644 --- a/modules/libcom/src/log/iocLogServer.c +++ b/modules/libcom/src/log/iocLogServer.c @@ -43,7 +43,7 @@ static char ioc_log_file_command[256]; struct iocLogClient { - int insock; + SOCKET insock; struct ioc_log_server *pserver; size_t nChar; char recvbuf[1024]; diff --git a/modules/libcom/src/misc/adjustment.c b/modules/libcom/src/misc/adjustment.c index a5803c4e2..525394277 100644 --- a/modules/libcom/src/misc/adjustment.c +++ b/modules/libcom/src/misc/adjustment.c @@ -15,40 +15,25 @@ #include #include -/* Up to now epicsShareThings have been declared as imports - * (Appropriate for other stuff) - * After setting the following they will be declared as exports - * (Appropriate for what we implement) - */ +#include #include "adjustment.h" -LIBCOM_API size_t adjustToWorstCaseAlignment(size_t size) +size_t adjustToWorstCaseAlignment(size_t size) { - int align_size, adjust; - struct test_long_word { char c; long lw; }; - struct test_double { char c; double d; }; - struct test_ptr { char c; void *p; }; - int test_long_size = sizeof(struct test_long_word) - sizeof(long); - int test_double_size = sizeof(struct test_double) - sizeof(double); - int test_ptr_size = sizeof(struct test_ptr) - sizeof(void *); - size_t adjusted_size = size; + union aline { + /* largest primative types (so far...) */ + double dval; + size_t uval; + char *ptr; + }; - /* - * Use Jeff's alignment tests to determine worst case of long, - * double or pointer alignment requirements. - */ - align_size = test_long_size > test_ptr_size ? - test_long_size : test_ptr_size; + /* assert that alignment size is a power of 2 */ + STATIC_ASSERT((sizeof(union aline) & (sizeof(union aline)-1))==0); - align_size = align_size > test_double_size ? - align_size : test_double_size; + /* round up to aligment size */ + size--; + size |= sizeof(union aline)-1; + size++; - /* - * Increase the size to fit worst case alignment if not already - * properly aligned. - */ - adjust = align_size - size%align_size; - if (adjust != align_size) adjusted_size += adjust; - - return (adjusted_size); + return size; } diff --git a/modules/libcom/src/misc/ipAddrToAsciiAsynchronous.cpp b/modules/libcom/src/misc/ipAddrToAsciiAsynchronous.cpp index b5e863d59..43a7537b9 100644 --- a/modules/libcom/src/misc/ipAddrToAsciiAsynchronous.cpp +++ b/modules/libcom/src/misc/ipAddrToAsciiAsynchronous.cpp @@ -17,6 +17,7 @@ #include #include #include +#include //#define EPICS_FREELIST_DEBUG #define EPICS_PRIVATE_API @@ -82,7 +83,6 @@ struct ipAddrToAsciiGlobal : public epicsThreadRunable { virtual void run (); - char nameTmp [1024]; tsFreeList < ipAddrToAsciiTransactionPrivate, 0x80 > transactionFreeList; @@ -297,6 +297,8 @@ ipAddrToAsciiTransaction & ipAddrToAsciiEnginePrivate::createTransaction () void ipAddrToAsciiGlobal::run () { + std::vector nameTmp(1024); + epicsGuard < epicsMutex > guard ( this->mutex ); while ( ! this->exitFlag ) { { @@ -313,14 +315,13 @@ void ipAddrToAsciiGlobal::run () if ( this->exitFlag ) { - sockAddrToDottedIP ( & addr.sa, this->nameTmp, - sizeof ( this->nameTmp ) ); + sockAddrToDottedIP ( & addr.sa, &nameTmp[0], nameTmp.size() ); } else { epicsGuardRelease < epicsMutex > unguard ( guard ); // depending on DNS configuration, this could take a very long time // so we release the lock - sockAddrToA ( &addr.sa, this->nameTmp, sizeof ( this->nameTmp ) ); + sockAddrToA ( &addr.sa, &nameTmp[0], nameTmp.size() ); } // the ipAddrToAsciiTransactionPrivate destructor is allowed to @@ -339,7 +340,7 @@ void ipAddrToAsciiGlobal::run () { epicsGuardRelease < epicsMutex > unguard ( guard ); // don't call callback with lock applied - pCur->pCB->transactionComplete ( this->nameTmp ); + pCur->pCB->transactionComplete ( &nameTmp[0] ); } this->callbackInProgress = false; diff --git a/modules/libcom/src/osi/epicsTime.cpp b/modules/libcom/src/osi/epicsTime.cpp index 43442225e..b78191f69 100644 --- a/modules/libcom/src/osi/epicsTime.cpp +++ b/modules/libcom/src/osi/epicsTime.cpp @@ -238,7 +238,7 @@ size_t epicsStdCall epicsTimeToStrftime (char *pBuff, size_t bufLength, const ch // convert nanosecs to integer of correct range frac /= div[fracWid]; char fracFormat[32]; - sprintf ( fracFormat, "%%0%lulu", fracWid ); + epicsSnprintf ( fracFormat, sizeof ( fracFormat ), "%%0%lulu", fracWid ); int status = epicsSnprintf ( pBufCur, bufLenLeft, fracFormat, frac ); if ( status > 0 ) { unsigned long nChar = static_cast < unsigned long > ( status ); diff --git a/modules/libcom/src/osi/os/WIN32/osdSock.c b/modules/libcom/src/osi/os/WIN32/osdSock.c index 8ca80ffb9..3c8dc6ebf 100644 --- a/modules/libcom/src/osi/os/WIN32/osdSock.c +++ b/modules/libcom/src/osi/os/WIN32/osdSock.c @@ -119,8 +119,8 @@ LIBCOM_API SOCKET epicsStdCall epicsSocketCreate ( return socket ( domain, type, protocol ); } -LIBCOM_API int epicsStdCall epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) +LIBCOM_API SOCKET epicsStdCall epicsSocketAccept ( + SOCKET sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) { return accept ( sock, pAddr, addrlen ); } diff --git a/modules/libcom/src/osi/os/WIN32/osdThread.c b/modules/libcom/src/osi/os/WIN32/osdThread.c index 5e9eeb435..d055b9bd9 100644 --- a/modules/libcom/src/osi/os/WIN32/osdThread.c +++ b/modules/libcom/src/osi/os/WIN32/osdThread.c @@ -500,8 +500,6 @@ static unsigned WINAPI epicsWin32ThreadEntry ( LPVOID lpParameter ) BOOL success; if ( pGbl ) { - setThreadName ( pParm->id, pParm->pName ); - success = FlsSetValue ( pGbl->flsIndexThreadLibraryEPICS, pParm ); if ( success ) { osdThreadHooksRun ( ( epicsThreadId ) pParm ); @@ -659,6 +657,7 @@ epicsThreadId epicsThreadCreateOpt ( pParmWIN32->id = ( DWORD ) threadId ; } + setThreadName ( pParmWIN32->id, pParmWIN32->pName ); osdPriority = epicsThreadGetOsdPriorityValue (opts->priority); bstat = SetThreadPriority ( pParmWIN32->handle, osdPriority ); if (!bstat) { diff --git a/modules/libcom/src/osi/os/WIN32/osdTime.cpp b/modules/libcom/src/osi/os/WIN32/osdTime.cpp index e2c3efbfe..0916b6c9f 100644 --- a/modules/libcom/src/osi/os/WIN32/osdTime.cpp +++ b/modules/libcom/src/osi/os/WIN32/osdTime.cpp @@ -215,6 +215,7 @@ void currentTime :: startPLL () CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, & this->threadId ); assert ( this->threadHandle ); + setThreadName ( this->threadId, "EPICS Time PLL" ); BOOL bstat = SetThreadPriority ( this->threadHandle, THREAD_PRIORITY_HIGHEST ); assert ( bstat ); @@ -496,7 +497,6 @@ static unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ) { currentTime * pCT = reinterpret_cast < currentTime * > ( pCurrentTimeIn ); - setThreadName ( pCT->threadId, "EPICS Time PLL" ); while ( ! pCT->threadShutdownCmd ) { Sleep ( currentTime :: pllDelay * 1000 /* mS */ ); pCT->updatePLL (); diff --git a/modules/libcom/src/osi/os/default/osdMessageQueue.cpp b/modules/libcom/src/osi/os/default/osdMessageQueue.cpp index dfbe9886c..89bc35562 100644 --- a/modules/libcom/src/osi/os/default/osdMessageQueue.cpp +++ b/modules/libcom/src/osi/os/default/osdMessageQueue.cpp @@ -40,7 +40,16 @@ struct threadNode { struct eventNode *evp; void *buf; unsigned int size; - volatile bool eventSent; + bool eventSent; + inline + threadNode() + :evp(NULL) + ,buf(NULL) + ,size(0u) + ,eventSent(false) + { + memset(&link, 0, sizeof(link)); + } }; /* @@ -366,9 +375,10 @@ myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, freeEventNode(pmsg, threadNode.evp, status); + bool wasSent = threadNode.eventSent; epicsMutexUnlock(pmsg->mutex); - if (threadNode.eventSent && (threadNode.size <= size)) + if (wasSent && (threadNode.size <= size)) return threadNode.size; return -1; } diff --git a/modules/libcom/src/osi/os/posix/osdSock.c b/modules/libcom/src/osi/os/posix/osdSock.c index f773b3357..0d873e628 100644 --- a/modules/libcom/src/osi/os/posix/osdSock.c +++ b/modules/libcom/src/osi/os/posix/osdSock.c @@ -27,6 +27,7 @@ #include "osiSock.h" #include "epicsAssert.h" #include "errlog.h" +#include "epicsAtomic.h" /* Linux and *BSD (at least) specific way to atomically set O_CLOEXEC. * RTEMS 5.1 provides SOCK_CLOEXEC, but doesn't implement accept4() @@ -60,19 +61,18 @@ static void unlockInfo (void) epicsMutexUnlock (infoMutex); } -/* - * NOOP - */ + +static size_t nAttached; + int osiSockAttach() { + epicsAtomicIncrSizeT(&nAttached); return 1; } -/* - * NOOP - */ void osiSockRelease() { + epicsAtomicDecrSizeT(&nAttached); } /* @@ -83,6 +83,11 @@ void osiSockRelease() LIBCOM_API SOCKET epicsStdCall epicsSocketCreate ( int domain, int type, int protocol ) { + static unsigned char warnAttached; + if(!epicsAtomicGetSizeT(&nAttached) && !warnAttached) { + warnAttached = 1; + errlogPrintf(ERL_WARNING ": epicsSocketCreate() without osiSockAttach() is not portable\n"); + } SOCKET sock = socket ( domain, type | SOCK_CLOEXEC, protocol ); if ( sock < 0 ) { sock = INVALID_SOCKET; @@ -119,8 +124,8 @@ LIBCOM_API SOCKET epicsStdCall epicsSocketCreate ( return sock; } -LIBCOM_API int epicsStdCall epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) +LIBCOM_API SOCKET epicsStdCall epicsSocketAccept ( + SOCKET sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) { #ifndef HAVE_SOCK_CLOEXEC int newSock = accept ( sock, pAddr, addrlen ); diff --git a/modules/libcom/src/osi/os/vxWorks/osdSock.c b/modules/libcom/src/osi/os/vxWorks/osdSock.c index 962612ca9..3f272c359 100644 --- a/modules/libcom/src/osi/os/vxWorks/osdSock.c +++ b/modules/libcom/src/osi/os/vxWorks/osdSock.c @@ -44,8 +44,8 @@ LIBCOM_API SOCKET epicsStdCall epicsSocketCreate ( return sock; } -LIBCOM_API int epicsStdCall epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) +LIBCOM_API SOCKET epicsStdCall epicsSocketAccept ( + SOCKET sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) { int newSock = accept ( sock, pAddr, addrlen ); if ( newSock < 0 ) { diff --git a/modules/libcom/src/osi/osiSock.h b/modules/libcom/src/osi/osiSock.h index 59332a04b..e1abb23db 100644 --- a/modules/libcom/src/osi/osiSock.h +++ b/modules/libcom/src/osi/osiSock.h @@ -63,8 +63,8 @@ LIBCOM_API SOCKET epicsStdCall epicsSocketCreate ( * peer address. * \return A new socket used for communicating with the peer just accepted, or -1 on error. */ -LIBCOM_API int epicsStdCall epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ); +LIBCOM_API SOCKET epicsStdCall epicsSocketAccept ( + SOCKET sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ); /*! * \brief Close and free resources held by a SOCKET object. * diff --git a/modules/libcom/test/epicsEventTest.cpp b/modules/libcom/test/epicsEventTest.cpp index cc73f8398..f9fa87198 100644 --- a/modules/libcom/test/epicsEventTest.cpp +++ b/modules/libcom/test/epicsEventTest.cpp @@ -16,12 +16,12 @@ #include #include #include -#include #include #include #include #include +#include "epicsStdio.h" #include "epicsThread.h" #include "epicsEvent.h" #include "epicsMutex.h" @@ -244,7 +244,7 @@ MAIN(epicsEventTest) name = (char **)calloc(nthreads, sizeof(char *)); for(int i = 0; i < nthreads; i++) { name[i] = (char *)calloc(16, sizeof(char)); - sprintf(name[i],"producer %d",i); + epicsSnprintf(name[i], 16, "producer %d",i); id[i] = epicsThreadCreate(name[i], 40, stackSize, producer, pinfo); epicsThreadSleep(0.1); } diff --git a/modules/libcom/test/epicsMessageQueueTest.cpp b/modules/libcom/test/epicsMessageQueueTest.cpp index d245cde89..fc5a903b9 100644 --- a/modules/libcom/test/epicsMessageQueueTest.cpp +++ b/modules/libcom/test/epicsMessageQueueTest.cpp @@ -10,11 +10,11 @@ /* * Author W. Eric Norum */ -#include #include #include #include +#include "epicsStdio.h" #include "epicsMessageQueue.h" #include "epicsThread.h" #include "epicsExit.h" @@ -232,7 +232,7 @@ sender(void *arg) int i = 0; while (!sendExit) { - len = sprintf(cbuf, "%s -- %d.", epicsThreadGetNameSelf(), ++i); + len = epicsSnprintf(cbuf, sizeof(cbuf), "%s -- %d.", epicsThreadGetNameSelf(), ++i); while (q->trySend((void *)cbuf, len) < 0) epicsThreadSleep(0.005 * (randBelow(5))); epicsThreadSleep(0.005 * (randBelow(20))); @@ -421,7 +421,7 @@ extern "C" void messageQueueTest(void *parm) epicsThreadPriorityHigh, epicsThreadPriorityHigh }; - sprintf(name, "Sender %d", i+1); + epicsSnprintf(name, sizeof(name), "Sender %d", i+1); opts.priority = pri[i]; senderId[i] = epicsThreadCreateOpt(name, sender, &q1, &opts); if (!senderId[i]) diff --git a/modules/libcom/test/epicsMutexTest.cpp b/modules/libcom/test/epicsMutexTest.cpp index 3086f679a..1342b903e 100644 --- a/modules/libcom/test/epicsMutexTest.cpp +++ b/modules/libcom/test/epicsMutexTest.cpp @@ -18,10 +18,10 @@ #include #include #include -#include #include #include +#include "epicsStdio.h" #include "epicsTime.h" #include "epicsThread.h" #include "epicsMutex.h" @@ -266,7 +266,7 @@ MAIN(epicsMutexTest) stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); for(i=0; ithreadnum = i; pinfo[i]->mutex = mutex; diff --git a/modules/libcom/test/epicsThreadTest.cpp b/modules/libcom/test/epicsThreadTest.cpp index 24ca294cc..6d43e71dc 100644 --- a/modules/libcom/test/epicsThreadTest.cpp +++ b/modules/libcom/test/epicsThreadTest.cpp @@ -13,11 +13,11 @@ #include #include #include -#include #include #include #include +#include "epicsStdio.h" #include "epicsThread.h" #include "epicsEvent.h" #include "epicsTime.h" @@ -73,7 +73,7 @@ void testMyThread() int startPriority = 0; for (int i = 0; i < ntasks; i++) { char name[10]; - sprintf(name, "t%d", i); + epicsSnprintf(name, sizeof(name), "t%d", i); myThreads[i] = new myThread(i, name); if (i == 0) startPriority = myThreads[i]->thread.getPriority(); diff --git a/modules/libcom/test/epicsTimeZoneTest.c b/modules/libcom/test/epicsTimeZoneTest.c index 4067c3f7d..f10688765 100644 --- a/modules/libcom/test/epicsTimeZoneTest.c +++ b/modules/libcom/test/epicsTimeZoneTest.c @@ -60,11 +60,11 @@ void test_gmtime(time_t T, int sec, int min, int hour, struct tm B; testDiag("test_gmtime(%ld, ...)", (long)T); if(epicsTime_gmtime(&T, &B)!=epicsTimeOK) { - testFail("epicsTime_localtime() error"); - testSkip(9, "epicsTime_localtime() failed"); + testFail("epicsTime_gmtime() error"); + testSkip(9, "epicsTime_gmtime() failed"); } else { B.tm_year += 1900; /* for readability */ - testPass("epicsTime_localtime() success"); + testPass("epicsTime_gmtime() success"); #define TEST(FLD) testOk(B.tm_##FLD==FLD, "%s %d==%d", #FLD, B.tm_##FLD, FLD) TEST(sec); TEST(min); diff --git a/modules/pvAccess b/modules/pvAccess index cf483d664..7746ea3c6 160000 --- a/modules/pvAccess +++ b/modules/pvAccess @@ -1 +1 @@ -Subproject commit cf483d664df92440443526acc276bc823c34ff31 +Subproject commit 7746ea3c6c366f7bf3a949613a77c9e4c7f7f2dd diff --git a/modules/pvData b/modules/pvData index 4c9b294e2..7c10c29c3 160000 --- a/modules/pvData +++ b/modules/pvData @@ -1 +1 @@ -Subproject commit 4c9b294e2bd50741437772aa11f47f8ba3c6fac8 +Subproject commit 7c10c29c331b8d115e58067629f73edfb30effc6 diff --git a/modules/pvDatabase b/modules/pvDatabase index 1b787c514..d18e0c913 160000 --- a/modules/pvDatabase +++ b/modules/pvDatabase @@ -1 +1 @@ -Subproject commit 1b787c514961f860a246cb4dc849dfbb1a10eb5e +Subproject commit d18e0c913a8d5a8d42cbf2d5ec28ffd362897809 diff --git a/modules/pva2pva b/modules/pva2pva index 3b9990e36..949b3f63c 160000 --- a/modules/pva2pva +++ b/modules/pva2pva @@ -1 +1 @@ -Subproject commit 3b9990e3650fca2673eebfb83645193ac0e5297d +Subproject commit 949b3f63c2387bb92c1c22ca2f80f8d320805117 diff --git a/src/tools/installEpics.pl b/src/tools/installEpics.pl index 6cd06e801..c41cc6f91 100644 --- a/src/tools/installEpics.pl +++ b/src/tools/installEpics.pl @@ -57,6 +57,9 @@ foreach my $source (@ARGV) { my $temp = "$install_dir/TEMP.$name.$$"; my $target = "$install_dir/$name"; + # Don't try to install the file if it already exists + next if $source eq $target; + if (-f $target) { next if -M $target < -M $source and -C $target < -C $source; # Remove old target, making sure it is deletable first