diff --git a/README b/README index dcf34b258..f6af2f75c 100644 --- a/README +++ b/README @@ -20,5 +20,5 @@ Additional information about EPICS including mailing list archives and subscription instructions, documentation and training materials, additional components, links to other websites etc. is available on the EPICS home page at - http://www.aps.anl.gov/epics/ + https://epics.anl.gov/ diff --git a/appveyor.yml b/appveyor.yml index e4c5010cb..dbbd7a908 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -40,11 +40,12 @@ configuration: # Environment variables: compiler toolchain environment: matrix: - - TOOLCHAIN: 9.0 - TOOLCHAIN: 10.0 - TOOLCHAIN: 11.0 - TOOLCHAIN: 12.0 - TOOLCHAIN: 14.0 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + TOOLCHAIN: 2017 - TOOLCHAIN: cygwin - TOOLCHAIN: mingw @@ -57,8 +58,6 @@ platform: matrix: exclude: # VS Express installs don't have the 64 bit compiler - - platform: x64 - TOOLCHAIN: 9.0 - platform: x64 TOOLCHAIN: 10.0 diff --git a/ci/appveyor-make.bat b/ci/appveyor-make.bat index 8ecf61dbe..a489d80ee 100644 --- a/ci/appveyor-make.bat +++ b/ci/appveyor-make.bat @@ -1,6 +1,6 @@ :: Universal build script for AppVeyor (https://ci.appveyor.com/) :: Environment: -:: TOOLCHAIN - toolchain version [9.0/10.0/11.0/12.0/14.0/cygwin/mingw] +:: TOOLCHAIN - toolchain version [10.0/11.0/12.0/14.0/2017/cygwin/mingw] :: CONFIGURATION - determines EPICS build [dynamic/static] :: PLATFORM - architecture [x86/x64] :: @@ -57,10 +57,22 @@ if "%TOOLCHAIN%"=="mingw" ( ) set "VSINSTALL=C:\Program Files (x86)\Microsoft Visual Studio %TOOLCHAIN%" +if not exist "%VSINSTALL%\" set "VSINSTALL=C:\Program Files (x86)\Microsoft Visual Studio\%TOOLCHAIN%\Community" +if not exist "%VSINSTALL%\" goto MSMissing + set "MAKE=C:\tools\make" +echo [INFO] APPVEYOR_BUILD_WORKER_IMAGE=%APPVEYOR_BUILD_WORKER_IMAGE% + if "%OS%"=="64BIT" ( set EPICS_HOST_ARCH=windows-x64%ST% + :: VS 2017 + if exist "%VSINSTALL%\VC\Auxiliary\Build\vcvars64.bat" ( + call "%VSINSTALL%\VC\Auxiliary\Build\vcvars64.bat" + where cl + if !ERRORLEVEL! NEQ 0 goto MSMissing + goto MSFound + ) if exist "%VSINSTALL%\VC\vcvarsall.bat" ( call "%VSINSTALL%\VC\vcvarsall.bat" amd64 where cl @@ -79,12 +91,19 @@ if "%OS%"=="64BIT" ( ) ) else ( set EPICS_HOST_ARCH=win32-x86%ST% + :: VS 2017 + if exist "%VSINSTALL%\VC\Auxiliary\Build\vcvars32.bat" ( + call "%VSINSTALL%\VC\Auxiliary\Build\vcvars32.bat" + where cl + if !ERRORLEVEL! NEQ 0 goto MSMissing + goto MSFound + ) if exist "%VSINSTALL%\VC\vcvarsall.bat" ( call "%VSINSTALL%\VC\vcvarsall.bat" x86 where cl if !ERRORLEVEL! NEQ 0 goto MSMissing goto MSFound - ) + ) if exist "%VSINSTALL%\VC\bin\vcvars32.bat" ( call "%VSINSTALL%\VC\bin\vcvars32.bat" where cl diff --git a/ci/appveyor-prepare.bat b/ci/appveyor-prepare.bat index 6edb7b52f..26ca8118a 100644 --- a/ci/appveyor-prepare.bat +++ b/ci/appveyor-prepare.bat @@ -65,6 +65,6 @@ if "%TOOLCHAIN%"=="mingw" ( ) echo [INFO] Installing Make 4.1 -@powershell -Command "(new-object net.webclient).DownloadFile('https://www.aps.anl.gov/epics/download/tools/make-4.1-win64.zip', 'C:\tools\make-4.1.zip')" +curl -fsS --retry 3 -o C:\tools\make-4.1.zip https://epics.anl.gov/download/tools/make-4.1-win64.zip cd \tools "C:\Program Files\7-Zip\7z" e make-4.1.zip diff --git a/configure/os/CONFIG.Common.vxWorksCommon b/configure/os/CONFIG.Common.vxWorksCommon index e7be9fae0..50f626959 100644 --- a/configure/os/CONFIG.Common.vxWorksCommon +++ b/configure/os/CONFIG.Common.vxWorksCommon @@ -170,6 +170,10 @@ COMPILE.ctdt = $(CC) -c $(CPPFLAGS) $(CFLAGS_ctdt) $(INCLUDES) $(SOURCE_FLAG) VXCPPFLAGS = $(filter-out $(OP_SYS_INCLUDE_CPPFLAGS),$(CPPFLAGS)) PREPROCESS.cpp = $(CPP) $(VXCPPFLAGS) $(INCLUDES) $< > $@ +#-------------------------------------------------- +# Use LEDLIB for command-line editing +COMMANDLINE_LIBRARY = LEDLIB + #-------------------------------------------------- # Allow site overrides -include $(CONFIG)/os/CONFIG_SITE.Common.vxWorksCommon diff --git a/documentation/README.html b/documentation/README.html index 8917fa2e7..868043718 100644 --- a/documentation/README.html +++ b/documentation/README.html @@ -98,7 +98,7 @@ base/configure/os/CONFIG_SITE.Common.vxWorksCommon file or in one of its target-specific overrides.

-

Consult the vxWorks +

Consult the vxWorks 6.x EPICS web pages and the vxWorks documentation for information about configuring your vxWorks operating system for use with EPICS.

@@ -128,7 +128,7 @@

Documentation

EPICS documentation is available through the - EPICS website at Argonne. + EPICS website at Argonne.

Release specific documentation can also be found in the base/documentation directory of the distribution.

diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 3256e72a3..54968e7bd 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -53,6 +53,61 @@ than one should be ignored).

+

Restore use of ledlib for VxWorks command editing

+ +

The epicsReadline refactoring work described below unfortunately disabled the +VxWorks implementation of the osdReadline.c API that uses ledlib for command +editing and history. This functionality has now been restored, see Launchpad +bug #1741578.

+ +

Constant link types

+ +

Constant links can now hold 64-bit integer values, either as scalars or +arrays. Only base 10 is supported by the JSON parser though, the JSON standard +doesn't allow for hexadecimal numbers.

+ +

Upgraded the YAJL JSON Library

+ +

The third-party YAJL library that has been included in libCom for several +years has been upgraded to version 2.1.0 and several bugs fixed. This has an +updated API, requiring any code that uses it to parse its own JSON files to be +modified to match. The changes are mainly that it uses size_t instead +unsigned int for string lengths, but it also uses long long +instead of long for JSON integer values, which was the main motivation +for the upgrade.

+ +

The self-tests that YAJL comes with have been imported and are now run as an +EPICS Unit Test program, and the JSON syntax accepted by the parser was extended +to permit trailing commas in both arrays and maps. The difference between the +old and new YAJL APIs can be detected at compile time by looking for the macro +EPICS_YAJL_VERSION which is defined in the yajl_common.h header file +along with a brief description of the API changes.

+ +

Timestamp support for the calc link type

+ +

A new optional parameter can be given when specifying a calc JSON link. The +time parameter is a string containing a single letter A..L +that selects one of the input links to be used for the timestamp of calculation +if requested. The timestamp will be fetched atomically with the value from the +chosen input link (providing that input link type supports the readLocked() +method).

+ +

Silence errors from puts to constant link types

+ +

A soft channel output record with the OUT link unset uses the CONSTANT link +type. The new link type code was causing some soft channel device supports to +return an error status from the write method of that link type, which would +cause a ca_put() operation to such a record to generate an exception. This has +been silenced by giving the constant link types a dummy putValue method. A new +test program has been added to prevent regressions of this behaviour.

+ +

RSRV expanding large buffer causes crash

+ +

In the 3.16.1 release a crash can occur in the IOC's RSRV server when a large +array is made even larger; the previous array buffer was not being released +correctly. See Launchpad +bug +#1706703.

Changes made between 3.16.0.1 and 3.16.1

diff --git a/src/ca/client/perl/CA.pm b/src/ca/client/perl/CA.pm index 22944172a..d79cdd33e 100644 --- a/src/ca/client/perl/CA.pm +++ b/src/ca/client/perl/CA.pm @@ -652,7 +652,7 @@ not follow this pattern, but are still printable strings. =item [1] R3.15 Channel Access Reference Manual by Jeffrey O. Hill -L +L =back diff --git a/src/ioc/db/test/callbackParallelTest.c b/src/ioc/db/test/callbackParallelTest.c index 2ccc44375..f8d0c3981 100644 --- a/src/ioc/db/test/callbackParallelTest.c +++ b/src/ioc/db/test/callbackParallelTest.c @@ -34,6 +34,8 @@ * * Two time intervals are measured. The time to queue and run each of * the immediate callbacks, and the actual delay of the delayed callback. + * + * Slow callbacks no longer fail the test, they just emit a diagnostic. */ #define NCALLBACKS 169 @@ -108,7 +110,7 @@ MAIN(callbackParallelTest) for (j = 0; j < 5; j++) setupError[i][j] = timeError[i][j] = defaultError[j]; - testPlan(4); + testPlan(2); testDiag("Starting %d parallel callback threads", noCpus); @@ -165,7 +167,8 @@ MAIN(callbackParallelTest) } } testOk(faults == 0, "%d faults during callback setup", faults); - testOk(slowups <= 1, "%d slowups during callback setup", slowups); + if (slowups) + testDiag("%d slowups during callback setup", slowups); slowups = 0; for (i = 0; i < NCALLBACKS ; i++) { @@ -182,7 +185,8 @@ MAIN(callbackParallelTest) } updateStats(timeError[i%NUM_CALLBACK_PRIORITIES], error); } - testOk(slowups < 5, "%d slowups during callbacks", slowups); + if (slowups) + testDiag("%d slowups during callback setup", slowups); testDiag("Setup time statistics"); printStats(setupError[0], "LOW"); diff --git a/src/ioc/db/test/callbackTest.c b/src/ioc/db/test/callbackTest.c index 7032a7cd1..3ccc2c2f3 100644 --- a/src/ioc/db/test/callbackTest.c +++ b/src/ioc/db/test/callbackTest.c @@ -34,6 +34,8 @@ * * Two time intervals are measured. The time to queue and run each of * the immediate callbacks, and the actual delay of the delayed callback. + * + * Slow callbacks no longer fail the test, they just emit a diagnostic. */ #define NCALLBACKS 169 @@ -108,7 +110,7 @@ MAIN(callbackTest) for (j = 0; j < 5; j++) setupError[i][j] = timeError[i][j] = defaultError[j]; - testPlan(4); + testPlan(2); callbackInit(); epicsThreadSleep(1.0); @@ -162,7 +164,8 @@ MAIN(callbackTest) } } testOk(faults == 0, "%d faults during callback setup", faults); - testOk(slowups <= 1, "%d slowups during callback setup", slowups); + if (slowups) + testDiag("%d slowups during callback setup", slowups); slowups = 0; for (i = 0; i < NCALLBACKS ; i++) { @@ -179,7 +182,8 @@ MAIN(callbackTest) } updateStats(timeError[i%NUM_CALLBACK_PRIORITIES], error); } - testOk(slowups < 5, "%d slowups during callbacks", slowups); + if (slowups) + testDiag("%d slowups during callback setup", slowups); testDiag("Setup time statistics"); printStats(setupError[0], "LOW"); diff --git a/src/libCom/osi/epicsReadline.c b/src/libCom/osi/epicsReadline.c index 936cbce99..0caa50fc2 100644 --- a/src/libCom/osi/epicsReadline.c +++ b/src/libCom/osi/epicsReadline.c @@ -1,11 +1,11 @@ /*************************************************************************\ * Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne +* Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ -/* Author: Eric Norum Date: 12DEC2001 */ +/* Author: Eric Norum */ #include #include @@ -15,8 +15,15 @@ #include "envDefs.h" #include "epicsReadline.h" +/* Basic command-line input, no editing or history: */ #define EPICS_COMMANDLINE_LIBRARY_EPICS 0 + +/* OS-specific command-line editing and/or history: */ #define EPICS_COMMANDLINE_LIBRARY_LIBTECLA 1 +#define EPICS_COMMANDLINE_LIBRARY_LEDLIB 1 +#define EPICS_COMMANDLINE_LIBRARY_OTHER 1 + +/* GNU readline, or Apple's libedit wrapper: */ #define EPICS_COMMANDLINE_LIBRARY_READLINE 2 #define EPICS_COMMANDLINE_LIBRARY_READLINE_CURSES 2 #define EPICS_COMMANDLINE_LIBRARY_READLINE_NCURSES 2 @@ -38,18 +45,17 @@ static void osdReadlineEnd(struct readlineContext *); #if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_EPICS -static void osdReadlineBegin(struct readlineContext * c) {} -static char * osdReadline(const char *prompt, struct readlineContext * c) { return NULL; } -static void osdReadlineEnd(struct readlineContext * c) {} +static void osdReadlineBegin(struct readlineContext *rc) {} +static char * osdReadline(const char *prompt, struct readlineContext *rc) +{ + return NULL; +} +static void osdReadlineEnd(struct readlineContext *rc) {} +#elif EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_READLINE +# include "gnuReadline.c" #else - -# if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_READLINE -# include "gnuReadline.c" -# else -# include "osdReadline.c" -# endif - +# include "osdReadline.c" #endif /* @@ -58,15 +64,15 @@ static void osdReadlineEnd(struct readlineContext * c) {} void * epicsShareAPI epicsReadlineBegin(FILE *in) { - struct readlineContext *readlineContext = calloc(1, sizeof(*readlineContext)); + struct readlineContext *rc = calloc(1, sizeof(*rc)); - if (readlineContext) { - readlineContext->in = in; - readlineContext->line = NULL; + if (rc) { + rc->in = in; + rc->line = NULL; if (!envGetConfigParamPtr(&IOCSH_HISTEDIT_DISABLE)) - osdReadlineBegin(readlineContext); + osdReadlineBegin(rc); } - return readlineContext; + return rc; } /* @@ -75,19 +81,19 @@ epicsReadlineBegin(FILE *in) char * epicsShareAPI epicsReadline (const char *prompt, void *context) { - struct readlineContext *readlineContext = context; + struct readlineContext *rc = context; FILE *in; char *line; int c; /* char is unsigned on some archs, EOF is -ve */ int linelen = 0; int linesize = 50; - if (readlineContext->osd) - return osdReadline(prompt, readlineContext); + if (rc->osd) + return osdReadline(prompt, rc); - free(readlineContext->line); - readlineContext->line = NULL; - if ((in = readlineContext->in) == NULL) { + free(rc->line); + rc->line = NULL; + if ((in = rc->in) == NULL) { in = stdin; if (prompt) { fputs(prompt, stdout); @@ -125,7 +131,7 @@ epicsReadline (const char *prompt, void *context) line[linelen++] = c; } line[linelen] = '\0'; - readlineContext->line = line; + rc->line = line; return line; } @@ -136,13 +142,13 @@ void epicsShareAPI epicsReadlineEnd (void *context) { if (context) { - struct readlineContext *readlineContext = context; + struct readlineContext *rc = context; - if (readlineContext->osd) - osdReadlineEnd(readlineContext); - else - free(readlineContext->line); - free(readlineContext); + if (rc->osd) + osdReadlineEnd(rc); + else + free(rc->line); + free(rc); } } diff --git a/src/libCom/osi/os/vxWorks/osdReadline.c b/src/libCom/osi/os/vxWorks/osdReadline.c index 9195b6b72..dee24fd64 100644 --- a/src/libCom/osi/os/vxWorks/osdReadline.c +++ b/src/libCom/osi/os/vxWorks/osdReadline.c @@ -33,7 +33,7 @@ struct osdContext { static void osdReadlineBegin(struct readlineContext *context) { - struct osdContext osd = malloc(sizeof *osd); + struct osdContext *osd = malloc(sizeof *osd); if (osd != NULL) { osd->ledId = (LED_ID) ERROR; diff --git a/src/std/rec/test/softTest.c b/src/std/rec/test/softTest.c index b81e6bfda..b29c955f9 100644 --- a/src/std/rec/test/softTest.c +++ b/src/std/rec/test/softTest.c @@ -11,6 +11,7 @@ #include "dbStaticLib.h" #include "dbTest.h" #include "dbUnitTest.h" +#include "epicsThread.h" #include "errlog.h" #include "registryFunction.h" #include "subRecord.h" @@ -39,10 +40,10 @@ void doProcess(const char *rec) testdbPutFieldOk(proc, DBR_CHAR, 1); } -/* Group 0 are all soft-channel input records with INP being a DB link +/* Group 0 are soft-channel input records with INP being a DB or CA link * to the PV 'source'. Their VAL fields all start out with the default * value for the type, i.e. 0 or an empty string. Triggering record - * processing should read the integer value from the 'source' PV. + * processing reads the value from the 'source' PV. */ static @@ -50,14 +51,22 @@ void testGroup0(void) { const char ** rec; const char * records[] = { - "ai0", "bi0", "di0", "ii0", "li0", "lsi0", "mi0", "si0", NULL + "ai0", "bi0", "di0", "ii0", "li0", "lsi0", "mi0", "si0", + "ai0c", "bi0c", "di0c", "ii0c", "li0c", "lsi0c", "mi0c", "si0c", + NULL }; testDiag("============ Starting %s ============", EPICS_FUNCTION); testdbPutFieldOk("source", DBR_LONG, 1); + /* The above put sends CA monitors to all of the CA links, but + * doesn't trigger record processing (the links are not CP/CPP). + * How could we wait until all of those monitors have arrived, + * instead of just waiting for an arbitrary time period? + */ + epicsThreadSleep(1.0); /* FIXME: Wait here? */ for (rec = records; *rec; rec++) { - if (strcmp(*rec, "lsi0") != 0) + if (strncmp(*rec, "lsi0", 4) != 0) testdbGetFieldEqual(*rec, DBR_LONG, 0); checkDtyp(*rec); doProcess(*rec); @@ -65,6 +74,7 @@ void testGroup0(void) } testdbPutFieldOk("source", DBR_LONG, 0); + epicsThreadSleep(1.0); /* FIXME: Wait here as above */ for (rec = records; *rec; rec++) { doProcess(*rec); testdbGetFieldEqual(*rec, DBR_LONG, 0); @@ -129,6 +139,7 @@ static long destSubr(subRecord *prec) { dest = prec->val; + prec->val = -1; return 0; } @@ -138,20 +149,25 @@ void checkOutput(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. + */ testOk(dest == value, "value %d output -> %d", value, dest); } -/* Group 3 are all soft-channel output records with OUT being a DB link - * to the PV 'dest' with PP. Putting a value to the record writes that - * value to 'dest' and processes it. +/* Group 3 are all soft-channel output records with OUT being a DB or + * local CA link to the subRecord 'dest'; DB links have the PP flag, + * for CA links the VAL field is marked PP. Putting a value to the + * output record writes that value to 'dest'. */ static void testGroup3(void) { const char ** rec; const char * records[] = { - "ao0", "bo0", "io0", "lo0", "lso0", "mo0", "so0", NULL, + "ao3", "bo3", "io3", "lo3", "lso3", "mo3", "so3", + "ao3c", "bo3c", "io3c", "lo3c", "lso3c", "mo3c", "so3c", + NULL, }; testDiag("============ Starting %s ============", EPICS_FUNCTION); @@ -160,13 +176,16 @@ void testGroup3(void) checkOutput(*rec, 1); checkDtyp(*rec); } - checkOutput("do0.B0", 1); - checkDtyp("do0"); + checkOutput("do3.B0", 1); + checkDtyp("do3"); + checkOutput("do3c.B0", 1); + checkDtyp("do3c"); for (rec = records; *rec; rec++) { checkOutput(*rec, 0); } - checkOutput("do0.B0", 0); + checkOutput("do3.B0", 0); + checkOutput("do3c.B0", 0); } /* Group 4 are all soft-channel output records with OUT being empty @@ -177,7 +196,7 @@ void testGroup4(void) { const char ** rec; const char * records[] = { - "ao1", "bo1", "do1.B0", "io1", "lo1", "lso1", "mo1", "so1", NULL, + "ao4", "bo4", "do4.B0", "io4", "lo4", "lso4", "mo4", "so4", NULL, }; testDiag("============ Starting %s ============", EPICS_FUNCTION); @@ -189,9 +208,10 @@ void testGroup4(void) void recTestIoc_registerRecordDeviceDriver(struct dbBase *); + MAIN(softTest) { - testPlan(163); + testPlan(266); testdbPrepare(); testdbReadDatabase("recTestIoc.dbd", NULL, NULL); diff --git a/src/std/rec/test/softTest.db b/src/std/rec/test/softTest.db index 8384fe946..06dbf2b7e 100644 --- a/src/std/rec/test/softTest.db +++ b/src/std/rec/test/softTest.db @@ -59,6 +59,60 @@ record(stringin, "si0") { field(INP, "source") } +record(ai, "ai0c") { + field(DTYP, "Soft Channel") + field(INP, "source CA") +} +record(bi, "bi0c") { + field(DTYP, "Soft Channel") + field(INP, "source CA") + field(ZNAM, "Zero") + field(ONAM, "One") +} +record(int64in, "ii0c") { + field(DTYP, "Soft Channel") + field(INP, "source CA") +} +record(longin, "li0c") { + field(DTYP, "Soft Channel") + field(INP, "source CA") +} +record(mbbiDirect, "di0c") { + field(DTYP, "Soft Channel") + field(NOBT, 4) + field(INP, "source CA") +} +record(mbbi, "mi0c") { + field(DTYP, "Soft Channel") + field(NOBT, 4) + field(INP, "source CA") + field(ZRST, "Zero") + field(ONST, "One") + field(TWST, "Two") + field(THST, "Three") + field(FRST, "Four") + field(FVST, "Five") + field(SXST, "Six") + field(SVST, "Seven") + field(EIST, "Eight") + field(NIST, "Nine") + field(TEST, "Ten") + field(ELST, "Eleven") + field(TWST, "Twelve") + field(TTST, "Thirteen") + field(FTST, "Fourteen") + field(FFST, "Fifteen") +} +record(lsi, "lsi0c") { + field(DTYP, "Soft Channel") + field(SIZV, 40) + field(INP, "source CA") +} +record(stringin, "si0c") { + field(DTYP, "Soft Channel") + field(INP, "source CA") +} + # Group 1 are all soft-channel input records with INP being a non-zero # "const" JSON-link, 9 for most records, 1 for the binary. Their VAL @@ -171,38 +225,39 @@ record(mbbi, "mi2") { } -# Group 3 are all soft-channel output records with OUT being a DB link -# to the PV 'dest' with PP. Putting a value to the record writes that -# value to 'dest' and processes it. +# Group 3 are all soft-channel output records with OUT being a DB or +# CA link to the PV 'dest' with PP. Putting a value to the record +# under test writes the value to 'dest' and processes it. record(sub, "dest") { field(SNAM, "destSubr") + field(VAL, -1) } -record(ao, "ao0") { +record(ao, "ao3") { field(DTYP, "Soft Channel") field(OUT, "dest PP") } -record(bo, "bo0") { +record(bo, "bo3") { field(DTYP, "Soft Channel") field(OUT, "dest PP") field(ZNAM, "Zero") field(ONAM, "One") } -record(int64out, "io0") { +record(int64out, "io3") { field(DTYP, "Soft Channel") field(OUT, "dest PP") } -record(longout, "lo0") { +record(longout, "lo3") { field(DTYP, "Soft Channel") field(OUT, "dest PP") } -record(mbboDirect, "do0") { +record(mbboDirect, "do3") { field(DTYP, "Soft Channel") field(NOBT, 4) field(OUT, "dest PP") } -record(mbbo, "mo0") { +record(mbbo, "mo3") { field(DTYP, "Soft Channel") field(NOBT, 4) field(OUT, "dest PP") @@ -223,39 +278,93 @@ record(mbbo, "mo0") { field(FTST, "Fourteen") field(FFST, "Fifteen") } -record(lso, "lso0") { +record(lso, "lso3") { field(DTYP, "Soft Channel") field(OUT, "dest PP") field(SIZV, 40) } -record(stringout, "so0") { +record(stringout, "so3") { field(DTYP, "Soft Channel") field(OUT, "dest PP") } +record(ao, "ao3c") { + field(DTYP, "Soft Channel") + field(OUT, "dest CA") +} +record(bo, "bo3c") { + field(DTYP, "Soft Channel") + field(OUT, "dest CA") + field(ZNAM, "Zero") + field(ONAM, "One") +} +record(int64out, "io3c") { + field(DTYP, "Soft Channel") + field(OUT, "dest CA") +} +record(longout, "lo3c") { + field(DTYP, "Soft Channel") + field(OUT, "dest CA") +} +record(mbboDirect, "do3c") { + field(DTYP, "Soft Channel") + field(NOBT, 4) + field(OUT, "dest CA") +} +record(mbbo, "mo3c") { + field(DTYP, "Soft Channel") + field(NOBT, 4) + field(OUT, "dest CA") + field(ZRST, "Zero") + field(ONST, "One") + field(TWST, "Two") + field(THST, "Three") + field(FRST, "Four") + field(FVST, "Five") + field(SXST, "Six") + field(SVST, "Seven") + field(EIST, "Eight") + field(NIST, "Nine") + field(TEST, "Ten") + field(ELST, "Eleven") + field(TWST, "Twelve") + field(TTST, "Thirteen") + field(FTST, "Fourteen") + field(FFST, "Fifteen") +} +record(lso, "lso3c") { + field(DTYP, "Soft Channel") + field(OUT, "dest CA") + field(SIZV, 40) +} +record(stringout, "so3c") { + field(DTYP, "Soft Channel") + field(OUT, "dest CA") +} + # Group 4 are all soft-channel output records with OUT being empty # (i.e. a CONSTANT link). Putting a value to the record must succeed. -record(ao, "ao1") { +record(ao, "ao4") { field(DTYP, "Soft Channel") } -record(bo, "bo1") { +record(bo, "bo4") { field(DTYP, "Soft Channel") field(ZNAM, "Zero") field(ONAM, "One") } -record(int64out, "io1") { +record(int64out, "io4") { field(DTYP, "Soft Channel") } -record(longout, "lo1") { +record(longout, "lo4") { field(DTYP, "Soft Channel") } -record(mbboDirect, "do1") { +record(mbboDirect, "do4") { field(DTYP, "Soft Channel") field(NOBT, 4) } -record(mbbo, "mo1") { +record(mbbo, "mo4") { field(DTYP, "Soft Channel") field(NOBT, 4) field(ZRST, "Zero") @@ -275,10 +384,10 @@ record(mbbo, "mo1") { field(FTST, "Fourteen") field(FFST, "Fifteen") } -record(lso, "lso1") { +record(lso, "lso4") { field(DTYP, "Soft Channel") field(SIZV, 40) } -record(stringout, "so1") { +record(stringout, "so4") { field(DTYP, "Soft Channel") } diff --git a/src/tools/genVersionHeader.pl b/src/tools/genVersionHeader.pl index 5851ea831..c61f14c98 100644 --- a/src/tools/genVersionHeader.pl +++ b/src/tools/genVersionHeader.pl @@ -18,8 +18,8 @@ use POSIX qw(strftime); use strict; -# RFC 8601 date+time w/ zone (eg "2014-08-29T09:42:47-0700") -my $tfmt = '%Y-%m-%dT%H:%M:%S'; +# RFC 8601 date+time w/ zone (eg "2014-08-29T09:42-0700") +my $tfmt = '%Y-%m-%dT%H:%M'; $tfmt .= '%z' unless $^O eq 'MSWin32'; # %z returns zone name on Windows my $now = strftime($tfmt, localtime);