Files
epics-base/modules/database/test/std/rec/mbbioDirectTest.c
Michael Davidsaver 7529577e3b Silence warning in mbbioDirectTest
GCC seems to lose track of possible output lengths
of the first sprintf() when computing possible lengths
of the second.

../mbbioDirectTest.c:44:26: warning: ‘.B’ directive writing 2 bytes into a region of size between 1 and 40 [-Wformat-overflow=]
   44 |         sprintf(field,"%s.B%X", rec, i);
2021-11-13 11:47:15 -08:00

146 lines
3.6 KiB
C

/*************************************************************************\
* Copyright (c) 2017 Dirk Zimoch
* SPDX-License-Identifier: EPICS
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* Theory of Operation
*
* For each of the two soft device supports (soft/raw soft/soft),
* there is a combination of mbboDirect -> val / sim -> mbbiDirect.
*
* The intermediate records are of type double (val) and long (sim) to
* check conversion from/to double.
*
* For each device support, the following is done:
* 1. The mbboDirect record is set to a specific value through the database.
* 2. The initial value is checked on both ends.
* 3. Two single bits (5 & 31) are toggled, values checked on both ends.
* 4. Sim mode is activated, one bit (0) is toggled, values are checked,
* data path (old value in val, new value in sim) is checked.
*/
#include <string.h>
#include "dbAccess.h"
#include "errlog.h"
#include "dbStaticLib.h"
#include "dbTest.h"
#include "dbUnitTest.h"
#include "testMain.h"
#include "epicsThread.h"
#include "epicsExport.h"
static
void testmbbioFields(char dir, unsigned n, unsigned int value)
{
char field[40];
unsigned int i;
sprintf(field,"d%c%d", dir, n);
testdbGetFieldEqual(field, DBF_ULONG, value);
for (i=0; i < 32; i++)
{
sprintf(field,"d%c%d.B%X", dir, n, i);
testdbGetFieldEqual(field, DBF_ULONG, (value>>i)&1);
}
}
static
void testmbbioRecords(unsigned int count, unsigned int value)
{
unsigned int i;
for (i = 1; i <= count; i++)
{
testDiag(" ### do%d ###", i);
testmbbioFields('o', i, value);
testDiag(" ### di%d ###", i);
testmbbioFields('i', i, value);
}
}
static
void putN(const char* pattern, unsigned int count, unsigned int value)
{
char field[40];
unsigned int i;
for (i = 1; i <= count; i++)
{
sprintf(field, pattern, i);
testdbPutFieldOk(field, DBF_ULONG, value);
}
}
static
void testN(const char* pattern, unsigned int count, unsigned int value)
{
char field[40];
unsigned int i;
for (i = 1; i <= count; i++)
{
sprintf(field, pattern, i);
testdbGetFieldEqual(field, DBF_ULONG, value);
}
}
void recTestIoc_registerRecordDeviceDriver(struct dbBase *);
MAIN(mbbioDirectTest)
{
unsigned int value = 0xdeadbeef;
unsigned int simvalue = 0;
char macros [40];
const unsigned int N = 2;
testPlan(N*((32+1)*2*4+4+3));
testdbPrepare();
testdbReadDatabase("recTestIoc.dbd", NULL, NULL);
recTestIoc_registerRecordDeviceDriver(pdbbase);
sprintf(macros, "INIT=%#x", value);
testdbReadDatabase("mbbioDirectTest.db", NULL, macros);
eltc(0);
testIocInitOk();
eltc(1);
testDiag("##### check initial value #####");
testmbbioRecords(N, value);
testDiag("##### set bit 5 #####");
putN("do%u.B5", N, 1);
value |= (1<<5);
testN("val%d", N, value);
testmbbioRecords(N, value);
testDiag("##### clear bit 31 (0x1f) #####");
putN("do%u.B1F", N, 0);
value &= ~(1<<31);
testN("val%d", N, value);
testmbbioRecords(N, value);
testDiag("##### simulation mode #####");
dbpf("sim", "1");
simvalue = value & ~1;
putN("do%u.B0", N, 0);
/* old value in lo* */
testN("val%d", N, value);
/* sim value in sim* */
testN("sim%d", N, simvalue);
testmbbioRecords(N, simvalue);
testIocShutdownOk();
testdbCleanup();
return testDone();
}