Merge up changes from below
This commit is contained in:
2
README
2
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/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
base/configure/os/CONFIG_SITE.Common.vxWorksCommon file or in one of its
|
||||
target-specific overrides.</P>
|
||||
|
||||
<P>Consult the <a href="http://www.aps.anl.gov/epics/base/vxWorks6.php">vxWorks
|
||||
<P>Consult the <a href="https://epics.anl.gov/base/vxWorks6.php">vxWorks
|
||||
6.x</a> EPICS web pages and the vxWorks documentation for information
|
||||
about configuring your vxWorks operating system for use with EPICS.</P>
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
|
||||
<H3><A NAME="0_0_8"> Documentation</A></H3>
|
||||
<BLOCKQUOTE>EPICS documentation is available through the
|
||||
<a href="http://www.aps.anl.gov/epics/">EPICS website</a> at Argonne.
|
||||
<a href="https://epics.anl.gov/">EPICS website</a> at Argonne.
|
||||
<P>Release specific documentation can also be found in the base/documentation
|
||||
directory of the distribution.</BLOCKQUOTE>
|
||||
|
||||
|
||||
@@ -53,6 +53,61 @@ than one should be ignored).</p>
|
||||
|
||||
<!-- Insert inherited items immediately below here ... -->
|
||||
|
||||
<h3>Restore use of ledlib for VxWorks command editing</h3>
|
||||
|
||||
<p>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
|
||||
<a href="https://bugs.launchpad.net/bugs/1741578">bug #1741578</a>.</p>
|
||||
|
||||
<h3>Constant link types</h3>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<h3>Upgraded the YAJL JSON Library</h3>
|
||||
|
||||
<p>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 <tt>size_t</tt> instead
|
||||
<tt>unsigned int</tt> for string lengths, but it also uses <tt>long long</tt>
|
||||
instead of <tt>long</tt> for JSON integer values, which was the main motivation
|
||||
for the upgrade.</p>
|
||||
|
||||
<p>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
|
||||
<tt>EPICS_YAJL_VERSION</tt> which is defined in the yajl_common.h header file
|
||||
along with a brief description of the API changes.</p>
|
||||
|
||||
<h3>Timestamp support for the calc link type</h3>
|
||||
|
||||
<p>A new optional parameter can be given when specifying a calc JSON link. The
|
||||
<tt>time</tt> parameter is a string containing a single letter <tt>A..L</tt>
|
||||
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).</p>
|
||||
|
||||
<h3>Silence errors from puts to constant link types</h3>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<h3>RSRV expanding large buffer causes crash</h3>
|
||||
|
||||
<p>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
|
||||
<a href="https://bugs.launchpad.net/epics-base/+bug/1706703">bug
|
||||
#1706703</a>.</p>
|
||||
|
||||
|
||||
<h2 align="center">Changes made between 3.16.0.1 and 3.16.1</h2>
|
||||
|
||||
@@ -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<http://www.aps.anl.gov/epics/base/R3-15/2-docs/CAref.html>
|
||||
L<https://epics.anl.gov/base/R3-15/5-docs/CAref.html>
|
||||
|
||||
=back
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user