change display.format, add display.form and .precision
Replace printf-style format string with enum + integer. ScalarBuilder explode scalar()/scalarArray()
This commit is contained in:
172
pdbApp/pvif.cpp
172
pdbApp/pvif.cpp
@ -11,6 +11,7 @@
|
||||
#include <alarm.h>
|
||||
#include <errSymTbl.h>
|
||||
#include <epicsVersion.h>
|
||||
#include <errlog.h>
|
||||
|
||||
#include <pv/status.h>
|
||||
#include <pv/bitSet.h>
|
||||
@ -32,10 +33,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
int qsrvDisableFormat = 1;
|
||||
}
|
||||
|
||||
namespace pvd = epics::pvData;
|
||||
|
||||
DBCH::DBCH(dbChannel *ch) :chan(ch)
|
||||
@ -94,7 +91,8 @@ struct pvCommon : public pvTimeAlarm {
|
||||
pvd::BitSet maskVALUE, maskPROPERTY, maskVALUEPut;
|
||||
|
||||
pvd::PVDoublePtr displayLow, displayHigh, controlLow, controlHigh;
|
||||
pvd::PVStringPtr egu, desc, prec;
|
||||
pvd::PVStringPtr egu, desc;
|
||||
pvd::PVIntPtr fmt, prec;
|
||||
|
||||
pvd::PVScalarPtr warnLow, warnHigh, alarmLow, alarmHigh;
|
||||
|
||||
@ -175,9 +173,32 @@ void attachTime(pvTimeAlarm& pvm, const pvd::PVStructurePtr& pv)
|
||||
#undef FMAP
|
||||
}
|
||||
|
||||
static
|
||||
pvd::shared_vector<const std::string> buildFormats()
|
||||
{
|
||||
pvd::shared_vector<std::string> fmt;
|
||||
fmt.push_back("Default");
|
||||
fmt.push_back("String");
|
||||
fmt.push_back("Binary");
|
||||
fmt.push_back("Decimal");
|
||||
fmt.push_back("Hex");
|
||||
fmt.push_back("Exponential");
|
||||
fmt.push_back("Engineering");
|
||||
return pvd::freeze(fmt);
|
||||
}
|
||||
|
||||
static const
|
||||
pvd::shared_vector<const std::string> displayForms(buildFormats());
|
||||
|
||||
// lookup fields and populate pvCommon. Non-existant fields will be NULL.
|
||||
void attachMeta(pvCommon& pvm, const pvd::PVStructurePtr& pv)
|
||||
{
|
||||
{
|
||||
pvd::PVStructurePtr fmt(pv->getSubField<pvd::PVStructure>("display.form"));
|
||||
if(fmt) {
|
||||
fmt->getSubFieldT<pvd::PVStringArray>("choices")->replace(displayForms);
|
||||
}
|
||||
}
|
||||
attachTime(pvm, pv);
|
||||
#define FMAP(MNAME, PVT, FNAME, DBE) pvm.MNAME = pv->getSubField<pvd::PVT>(FNAME); \
|
||||
if(pvm.MNAME) pvm.mask ## DBE.set(pvm.MNAME->getFieldOffset())
|
||||
@ -187,7 +208,8 @@ void attachMeta(pvCommon& pvm, const pvd::PVStructurePtr& pv)
|
||||
FMAP(controlLow, PVDouble, "control.limitLow", PROPERTY);
|
||||
FMAP(egu, PVString, "display.units", PROPERTY);
|
||||
FMAP(desc, PVString, "display.description", PROPERTY);
|
||||
FMAP(prec, PVString, "display.format", PROPERTY);
|
||||
FMAP(prec, PVInt, "display.precision", PROPERTY);
|
||||
FMAP(fmt, PVInt, "display.form.index", PROPERTY);
|
||||
FMAP(warnHigh, PVScalar, "valueAlarm.highWarningLimit", PROPERTY);
|
||||
FMAP(warnLow, PVScalar, "valueAlarm.lowWarningLimit", PROPERTY);
|
||||
FMAP(alarmHigh, PVScalar, "valueAlarm.highAlarmLimit", PROPERTY);
|
||||
@ -443,61 +465,12 @@ void putMeta(const pvCommon& pv, unsigned dbe, db_field_log *pfl)
|
||||
FMAP(DBR_CTRL_DOUBLE, controlLow, lower_ctrl_limit);
|
||||
FMAP(DBR_GR_DOUBLE, egu, units);
|
||||
#undef FMAP
|
||||
if(META::mask&DBR_PRECISION && pv.prec && !qsrvDisableFormat) {
|
||||
// construct printf() style format.
|
||||
// Widths based on epicsTypes.h
|
||||
char buf[8];
|
||||
char *pos = &buf[8]; // build string in reverse order
|
||||
bool ok = true;
|
||||
|
||||
*--pos = '\0'; // buf[7] = '\0'
|
||||
|
||||
switch(dbChannelFinalFieldType(pv.chan)) {
|
||||
#ifdef USE_INT64
|
||||
case DBF_UINT64:
|
||||
*--pos = 'l';
|
||||
*--pos = 'l';
|
||||
#endif
|
||||
case DBF_UCHAR:
|
||||
case DBF_USHORT:
|
||||
case DBF_ULONG:
|
||||
*--pos = 'u';
|
||||
break;
|
||||
#ifdef USE_INT64
|
||||
case DBF_INT64:
|
||||
*--pos = 'l';
|
||||
*--pos = 'l';
|
||||
#endif
|
||||
case DBF_CHAR:
|
||||
case DBF_SHORT:
|
||||
case DBF_LONG:
|
||||
*--pos = 'd';
|
||||
break;
|
||||
case DBF_DOUBLE:
|
||||
case DBF_FLOAT:
|
||||
*--pos = 'g'; // either decimal or scientific
|
||||
break;
|
||||
case DBF_STRING:
|
||||
*--pos = 's';
|
||||
break;
|
||||
default:
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if(ok) {
|
||||
long dp = meta.precision.dp;
|
||||
if(dp<0) dp = 0;
|
||||
else if(dp>=99) dp = 99;
|
||||
for(;dp;dp = dp/10u) {
|
||||
*--pos = '0'+(dp%10u);
|
||||
}
|
||||
*--pos = '%';
|
||||
}
|
||||
pv.prec->put(pos);
|
||||
if(META::mask&DBR_PRECISION && pv.prec) {
|
||||
pv.prec->put(pvd::int32(meta.precision.dp));
|
||||
}
|
||||
#define FMAP(MASK, MNAME, FNAME) if(META::mask&(MASK) && pv.MNAME) pv.MNAME->putFrom(meta.FNAME)
|
||||
// not handling precision until I get a better idea of what 'format' is supposed to be...
|
||||
//FMAP(prec, PVScalar, "display.format", PROPERTY);
|
||||
//FMAP(prec, PVScalar, "display.form", PROPERTY);
|
||||
FMAP(DBR_AL_DOUBLE, warnHigh, upper_warning_limit);
|
||||
FMAP(DBR_AL_DOUBLE, warnLow, lower_warning_limit);
|
||||
FMAP(DBR_AL_DOUBLE, alarmHigh, upper_alarm_limit);
|
||||
@ -528,16 +501,15 @@ void putAll(const PVC &pv, unsigned dbe, db_field_log *pfl)
|
||||
}
|
||||
}
|
||||
|
||||
void findNSMask(pvTimeAlarm& pvmeta, dbChannel *chan, const epics::pvData::PVStructurePtr& pvalue)
|
||||
void findNSMask(pvTimeAlarm& pvmeta, pdbRecordIterator& info, const epics::pvData::PVStructurePtr& pvalue)
|
||||
{
|
||||
pdbRecordIterator info(chan);
|
||||
const char *UT = info.info("Q:time:tag");
|
||||
if(UT && strncmp(UT, "nsec:lsb:", 9)==0) {
|
||||
try{
|
||||
pvmeta.nsecMask = epics::pvData::castUnsafe<pvd::uint32>(std::string(&UT[9]));
|
||||
}catch(std::exception& e){
|
||||
pvmeta.nsecMask = 0;
|
||||
std::cerr<<dbChannelRecord(chan)->name<<" : Q:time:tag nsec:lsb: requires a number not '"<<UT[9]<<"'\n";
|
||||
std::cerr<<info.name()<<" : Q:time:tag nsec:lsb: requires a number not '"<<UT[9]<<"'\n";
|
||||
}
|
||||
}
|
||||
if(pvmeta.nsecMask>0 && pvmeta.nsecMask<=32) {
|
||||
@ -553,6 +525,25 @@ void findNSMask(pvTimeAlarm& pvmeta, dbChannel *chan, const epics::pvData::PVStr
|
||||
pvmeta.nsecMask = 0;
|
||||
}
|
||||
|
||||
void findFormat(pvTimeAlarm& pvmeta, pdbRecordIterator& info, const epics::pvData::PVStructurePtr& pvalue)
|
||||
{
|
||||
const char *FMT = info.info("Q:form");
|
||||
if(FMT) {
|
||||
pvd::PVScalarPtr fmt(pvalue->getSubField<pvd::PVScalar>("display.form.index"));
|
||||
if(fmt) {
|
||||
bool found = false;
|
||||
for(size_t i=0; !found && i<displayForms.size(); i++) {
|
||||
if((found=(displayForms[i]==FMT)))
|
||||
fmt->putFrom<pvd::uint32>(i);
|
||||
}
|
||||
if(!found) {
|
||||
fmt->putFrom<pvd::uint32>(0); // Default
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename PVX, typename META>
|
||||
struct PVIFScalarNumeric : public PVIF
|
||||
{
|
||||
@ -583,7 +574,9 @@ struct PVIFScalarNumeric : public PVIF
|
||||
pvmeta.maskVALUEPut.set(0);
|
||||
pvmeta.maskVALUEPut.set(bit);
|
||||
}
|
||||
findNSMask(pvmeta, chan, pvalue);
|
||||
pdbRecordIterator info(chan);
|
||||
findNSMask(pvmeta, info, pvalue);
|
||||
findFormat(pvmeta, info, pvalue);
|
||||
}
|
||||
virtual ~PVIFScalarNumeric() {}
|
||||
|
||||
@ -679,19 +672,45 @@ ScalarBuilder::dtype(dbChannel *channel)
|
||||
if(maxelem!=1 && dbr==DBR_ENUM)
|
||||
dbr = DBF_SHORT;
|
||||
|
||||
pvd::FieldBuilderPtr builder(pvd::getFieldCreate()->createFieldBuilder());
|
||||
pvd::StandardFieldPtr standard(pvd::getStandardField());
|
||||
|
||||
if(dbr==DBR_ENUM)
|
||||
return pvd::getStandardField()->enumerated("alarm,timeStamp");
|
||||
|
||||
std::string options;
|
||||
if(dbr!=DBR_STRING)
|
||||
options = "alarm,timeStamp,display,control,valueAlarm";
|
||||
builder = builder->setId("epics:nt/NTEnum:1.0")
|
||||
->addNestedStructure("value")
|
||||
->add("index", pvd::pvInt)
|
||||
->addArray("choices", pvd::pvString)
|
||||
->endNested();
|
||||
else if(maxelem==1)
|
||||
builder = builder->setId("epics:nt/NTScalar:1.0")
|
||||
->add("value", pvt);
|
||||
else
|
||||
options = "alarm,timeStamp,display,control";
|
||||
builder = builder->setId("epics:nt/NTScalarArray:1.0")
|
||||
->addArray("value", pvt);
|
||||
|
||||
if(maxelem==1)
|
||||
return pvd::getStandardField()->scalar(pvt, options);
|
||||
else
|
||||
return pvd::getStandardField()->scalarArray(pvt, options);
|
||||
builder = builder->add("alarm", standard->alarm())
|
||||
->add("timeStamp", standard->timeStamp());
|
||||
|
||||
if(dbr!=DBR_ENUM) {
|
||||
builder = builder->addNestedStructure("display")
|
||||
->add("limitLow", pvd::pvDouble)
|
||||
->add("limitHigh", pvd::pvDouble)
|
||||
->add("description", pvd::pvString)
|
||||
->add("units", pvd::pvString)
|
||||
->add("precision", pvd::pvInt)
|
||||
->addNestedStructure("form")
|
||||
->setId("enum_t")
|
||||
->add("index", pvd::pvInt)
|
||||
->addArray("choices", pvd::pvString)
|
||||
->endNested()
|
||||
->endNested()
|
||||
->add("control", standard->control());
|
||||
|
||||
if(dbr!=DBR_STRING)
|
||||
builder = builder->add("valueAlarm", standard->doubleAlarm());
|
||||
}
|
||||
|
||||
return builder->createStructure();
|
||||
}
|
||||
|
||||
PVIF*
|
||||
@ -704,7 +723,6 @@ ScalarBuilder::attach(dbChannel *channel, const epics::pvData::PVStructurePtr& r
|
||||
|
||||
const short dbr = dbChannelFinalFieldType(channel);
|
||||
const long maxelem = dbChannelFinalElements(channel);
|
||||
//const pvd::ScalarType pvt = DBR2PVD(dbr);
|
||||
|
||||
if(maxelem==1) {
|
||||
switch(dbr) {
|
||||
@ -904,8 +922,10 @@ struct PVIFMeta : public PVIF
|
||||
if(!field)
|
||||
throw std::logic_error("PVIFMeta attached type mis-match");
|
||||
meta.chan = channel;
|
||||
pdbRecordIterator info(chan);
|
||||
attachTime(meta, field);
|
||||
findNSMask(meta, channel, field);
|
||||
findNSMask(meta, info, field);
|
||||
findFormat(meta, info, field);
|
||||
if(enclosing) {
|
||||
meta.maskALWAYS.clear();
|
||||
meta.maskALWAYS.set(enclosing->getFieldOffset());
|
||||
@ -1094,7 +1114,3 @@ PVIFBuilder* PVIFBuilder::create(const std::string& type)
|
||||
else
|
||||
throw std::runtime_error(std::string("Unknown +type=")+type);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
epicsExportAddress(int, qsrvDisableFormat);
|
||||
}
|
||||
|
@ -9,9 +9,6 @@ link("pva", "lsetPVA")
|
||||
device(waveform, CONSTANT, devWfPDBDemo, "QSRV Demo")
|
||||
# from imagedemo.c
|
||||
function(QSRV_image_demo)
|
||||
# from pvif.cpp
|
||||
# Disable mapping of display.format
|
||||
variable(qsrvDisableFormat, int)
|
||||
# from pdb.cpp
|
||||
# Extra debug info when parsing group definitions
|
||||
variable(PDBProviderDebug, int)
|
||||
|
@ -8,9 +8,6 @@ registrar(installPVAAddLinkHook)
|
||||
device(waveform, CONSTANT, devWfPDBDemo, "QSRV Demo")
|
||||
# from imagedemo.c
|
||||
function(QSRV_image_demo)
|
||||
# from pvif.cpp
|
||||
# Disable mapping of display.format
|
||||
variable(qsrvDisableFormat, int)
|
||||
# from pdb.cpp
|
||||
# Extra debug info when parsing group definitions
|
||||
variable(PDBProviderDebug, int)
|
||||
|
@ -107,6 +107,8 @@ void testScalar()
|
||||
p2p::auto_ptr<PVIF> pvif_ai_rval(builder.attach(chan_ai_rval, root, FieldName("ai_rval")));
|
||||
p2p::auto_ptr<PVIF> pvif_mbbi(builder.attach(chan_mbbi, root, FieldName("mbbi")));
|
||||
|
||||
testShow()<<"Entire structure\n"<<root;
|
||||
|
||||
pvd::BitSet mask;
|
||||
|
||||
dbScanLock((dbCommon*)prec_li);
|
||||
@ -123,18 +125,19 @@ void testScalar()
|
||||
.set(OFF("li.alarm.message"))
|
||||
.set(OFF("li.timeStamp.secondsPastEpoch"))
|
||||
.set(OFF("li.timeStamp.nanoseconds"))
|
||||
//.set(OFF("li.timeStamp.userTag"))
|
||||
.set(OFF("li.display.limitHigh"))
|
||||
.set(OFF("li.display.limitLow"))
|
||||
.set(OFF("li.display.description"))
|
||||
.set(OFF("li.display.format"))
|
||||
.set(OFF("li.display.units"))
|
||||
.set(OFF("li.display.precision"))
|
||||
.set(OFF("li.display.form.index"))
|
||||
.set(OFF("li.control.limitHigh"))
|
||||
.set(OFF("li.control.limitLow"))
|
||||
.set(OFF("li.valueAlarm.highWarningLimit"))
|
||||
.set(OFF("li.valueAlarm.lowWarningLimit"))
|
||||
.set(OFF("li.valueAlarm.highAlarmLimit"))
|
||||
.set(OFF("li.valueAlarm.lowAlarmLimit")));
|
||||
.set(OFF("li.valueAlarm.lowAlarmLimit")))
|
||||
<<" li changes\n"<<root->stream().show(mask);
|
||||
#undef OFF
|
||||
mask.clear();
|
||||
|
||||
@ -158,7 +161,8 @@ void testScalar()
|
||||
.set(OFF("i64.display.limitLow"))
|
||||
.set(OFF("i64.display.description"))
|
||||
.set(OFF("i64.display.units"))
|
||||
.set(OFF("i64.display.format"))
|
||||
.set(OFF("i64.display.precision"))
|
||||
.set(OFF("i64.display.form.index"))
|
||||
.set(OFF("i64.control.limitHigh"))
|
||||
.set(OFF("i64.control.limitLow"))
|
||||
.set(OFF("i64.valueAlarm.highWarningLimit"))
|
||||
@ -189,10 +193,12 @@ void testScalar()
|
||||
.set(OFF("si.display.limitHigh"))
|
||||
.set(OFF("si.display.limitLow"))
|
||||
.set(OFF("si.display.description"))
|
||||
.set(OFF("si.display.format"))
|
||||
.set(OFF("si.display.units"))
|
||||
.set(OFF("si.display.precision"))
|
||||
.set(OFF("si.display.form.index"))
|
||||
.set(OFF("si.control.limitHigh"))
|
||||
.set(OFF("si.control.limitLow")));
|
||||
.set(OFF("si.control.limitLow")))
|
||||
<<" si changes\n"<<root->stream().show(mask);
|
||||
#undef OFF
|
||||
mask.clear();
|
||||
|
||||
@ -215,7 +221,8 @@ void testScalar()
|
||||
.set(OFF("ai.display.limitHigh"))
|
||||
.set(OFF("ai.display.limitLow"))
|
||||
.set(OFF("ai.display.description"))
|
||||
.set(OFF("ai.display.format"))
|
||||
.set(OFF("ai.display.precision"))
|
||||
.set(OFF("ai.display.form.index"))
|
||||
.set(OFF("ai.display.units"))
|
||||
.set(OFF("ai.control.limitHigh"))
|
||||
.set(OFF("ai.control.limitLow"))
|
||||
@ -233,15 +240,17 @@ void testScalar()
|
||||
.set(OFF("ai_rval.display.limitHigh"))
|
||||
.set(OFF("ai_rval.display.limitLow"))
|
||||
.set(OFF("ai_rval.display.description"))
|
||||
.set(OFF("ai_rval.display.format"))
|
||||
.set(OFF("ai_rval.display.units"))
|
||||
.set(OFF("ai_rval.display.precision"))
|
||||
.set(OFF("ai_rval.display.form.index"))
|
||||
.set(OFF("ai_rval.control.limitHigh"))
|
||||
.set(OFF("ai_rval.control.limitLow"))
|
||||
.set(OFF("ai_rval.valueAlarm.highWarningLimit"))
|
||||
.set(OFF("ai_rval.valueAlarm.lowWarningLimit"))
|
||||
.set(OFF("ai_rval.valueAlarm.highAlarmLimit"))
|
||||
.set(OFF("ai_rval.valueAlarm.lowAlarmLimit"))
|
||||
);
|
||||
)
|
||||
<<" ai changes\n"<<root->stream().show(mask);
|
||||
#undef OFF
|
||||
mask.clear();
|
||||
|
||||
@ -260,7 +269,8 @@ void testScalar()
|
||||
.set(OFF("mbbi.alarm.message"))
|
||||
.set(OFF("mbbi.timeStamp.secondsPastEpoch"))
|
||||
.set(OFF("mbbi.timeStamp.nanoseconds"))
|
||||
.set(OFF("mbbi.timeStamp.userTag")));
|
||||
.set(OFF("mbbi.timeStamp.userTag")))
|
||||
<<" mbbi changes\n"<<root->stream().show(mask);
|
||||
#undef OFF
|
||||
mask.clear();
|
||||
|
||||
@ -272,6 +282,8 @@ void testScalar()
|
||||
testFieldEqual<pvd::PVDouble>(root, "li.display.limitHigh", 100.0);
|
||||
testFieldEqual<pvd::PVDouble>(root, "li.display.limitLow", 10.0);
|
||||
testFieldEqual<pvd::PVString>(root, "li.display.units", "arb");
|
||||
testFieldEqual<pvd::PVInt>(root, "li.display.precision", 0);
|
||||
testFieldEqual<pvd::PVInt>(root, "li.display.form.index", 4); // "Hex"
|
||||
|
||||
#ifdef USE_INT64
|
||||
testFieldEqual<pvd::PVLong>(root, "i64.value", 0x7fffffffffffffffLL);
|
||||
@ -284,6 +296,7 @@ void testScalar()
|
||||
testTodoBegin("Bug in int64inRecord get_units()");
|
||||
testFieldEqual<pvd::PVString>(root, "i64.display.units", "arb");
|
||||
testTodoEnd();
|
||||
testFieldEqual<pvd::PVInt>(root, "i64.display.precision", 0);
|
||||
#endif
|
||||
|
||||
testFieldEqual<pvd::PVString>(root, "si.value", "hello");
|
||||
@ -298,8 +311,9 @@ void testScalar()
|
||||
testFieldEqual<pvd::PVInt>(root, "ai.timeStamp.nanoseconds", 12345678);
|
||||
testFieldEqual<pvd::PVDouble>(root, "ai.display.limitHigh", 200.0);
|
||||
testFieldEqual<pvd::PVDouble>(root, "ai.display.limitLow", 20.0);
|
||||
testFieldEqual<pvd::PVString>(root, "ai.display.format", "");
|
||||
testFieldEqual<pvd::PVInt>(root, "ai.display.precision", 2);
|
||||
testFieldEqual<pvd::PVString>(root, "ai.display.units", "foo");
|
||||
testFieldEqual<pvd::PVInt>(root, "ai.display.form.index", 0);
|
||||
|
||||
testFieldEqual<pvd::PVInt>(root, "ai_rval.value", 1234);
|
||||
testFieldEqual<pvd::PVInt>(root, "ai_rval.alarm.severity", 2);
|
||||
@ -308,8 +322,9 @@ void testScalar()
|
||||
testFieldEqual<pvd::PVInt>(root, "ai_rval.timeStamp.userTag", 0);
|
||||
testFieldEqual<pvd::PVDouble>(root, "ai_rval.display.limitHigh", 2147483647.0);
|
||||
testFieldEqual<pvd::PVDouble>(root, "ai_rval.display.limitLow", -2147483648.0);
|
||||
testFieldEqual<pvd::PVString>(root, "ai_rval.display.format", "");
|
||||
testFieldEqual<pvd::PVInt>(root, "ai_rval.display.precision", 0);
|
||||
testFieldEqual<pvd::PVString>(root, "ai_rval.display.units", "");
|
||||
testFieldEqual<pvd::PVInt>(root, "ai_rval.display.form.index", 0);
|
||||
|
||||
testFieldEqual<pvd::PVInt>(root, "mbbi.value.index", 1);
|
||||
testFieldEqual<pvd::PVInt>(root, "mbbi.alarm.severity", 0);
|
||||
@ -340,6 +355,15 @@ void testScalar()
|
||||
testEqual(prec_li->val, 102043);
|
||||
dbScanUnlock((dbCommon*)prec_li);
|
||||
|
||||
#ifdef USE_INT64
|
||||
dbScanLock((dbCommon*)prec_i64);
|
||||
mask.clear();
|
||||
mask.set(root->getSubFieldT("i64.value")->getFieldOffset());
|
||||
pvif_i64->get(mask);
|
||||
testEqual(prec_i64->val, epicsInt64(-0x8000000000000000LL));
|
||||
dbScanUnlock((dbCommon*)prec_i64);
|
||||
#endif
|
||||
|
||||
#ifdef USE_INT64
|
||||
dbScanLock((dbCommon*)prec_i64);
|
||||
mask.clear();
|
||||
@ -501,9 +525,9 @@ void testPlain()
|
||||
|
||||
MAIN(testpvif)
|
||||
{
|
||||
testPlan(71
|
||||
testPlan(75
|
||||
#ifdef USE_INT64
|
||||
+11
|
||||
+13
|
||||
#endif
|
||||
);
|
||||
#ifdef USE_INT64
|
||||
|
@ -5,6 +5,7 @@ record(longin, "test:li") {
|
||||
field(EGU, "arb")
|
||||
field(HOPR, "100")
|
||||
field(LOPR, "10")
|
||||
info(Q:form, "Hex")
|
||||
}
|
||||
record(ai, "test:ai") {
|
||||
field(VAL, "42.2")
|
||||
|
Reference in New Issue
Block a user