Compare commits
12 Commits
stream_2_6
...
stream_2_7
Author | SHA1 | Date | |
---|---|---|---|
e2af7e3149 | |||
950d75ba43 | |||
e651c99697 | |||
9694628d3f | |||
046582d1a0 | |||
f6f0ea9ae5 | |||
018547cdf3 | |||
d763a64f03 | |||
cefa460a0d | |||
cc5948ad0b | |||
be1943a66d | |||
d9acb47afe |
@ -41,6 +41,12 @@ written or read value.
|
||||
(=20.0/0xFFFF) maps 0x0000 to -10.0, 0x7FFF to 0.0 and 0xFFFF to 10.0.
|
||||
Using unsigned formats with values ≥ 0x800000 gives different results
|
||||
on 64 bit machines.
|
||||
<p class="new">
|
||||
If <code>LINR=="NO CONVERSION"</code> (the default), <code>VAL</code>
|
||||
is directly converted from and to <code>long</code> without going through
|
||||
<code>RVAL</code>. This allows for more bits on 64 bit machines.
|
||||
To get the old behavior, use <code>LINR=="LINEAR"</code>.
|
||||
</p>
|
||||
</dd>
|
||||
<dt>ENUM format (e.g. <code>%{</code>):</dt>
|
||||
<dd>
|
||||
|
@ -40,6 +40,12 @@ written or read value.
|
||||
(=20.0/0xFFFF) maps -10.0 to 0x0000, 0.0 to 0x7FFF and 10.0 to 0xFFFF.
|
||||
Using unsigned formats with values ≥ 0x800000 gives different results
|
||||
on 64 bit machines.
|
||||
<p class="new">
|
||||
If <code>LINR=="NO CONVERSION"</code> (the default), <code>OVAL</code>
|
||||
is directly converted to <code>long</code> without going through
|
||||
<code>RVAL</code>. This allows for more bits on 64 bit machines.
|
||||
To get the old behavior, use <code>LINR=="LINEAR"</code>.
|
||||
</p>
|
||||
</dd>
|
||||
<dt>ENUM format (e.g. <code>%{</code>):</dt>
|
||||
<dd>
|
||||
|
@ -158,6 +158,9 @@ attribute (see
|
||||
target="ex">Record Reference Manual</a>), the record will be processed.
|
||||
It is your responsibility that the data type of the record field is
|
||||
compatible to the the data type of the converter.
|
||||
<span class="new">STRING formats are compatible with arrays of CHAR or UCHAR.<span>
|
||||
</p>
|
||||
<p>
|
||||
Note that using this syntax is by far not as efficient as using the
|
||||
default field.
|
||||
At the moment it is not possible to set <code>otherrecord</code> to an alarm
|
||||
@ -195,7 +198,7 @@ is accepted.
|
||||
</p>
|
||||
<p class="new">
|
||||
When a maximum field width is given, leading whitespace only counts to the
|
||||
field witdth when the space flag is given.
|
||||
field witdth when the space flag is used.
|
||||
</p>
|
||||
|
||||
<a name="stdl"></a>
|
||||
@ -210,6 +213,10 @@ field witdth when the space flag is given.
|
||||
<p>
|
||||
With the <code>#</code> flag, octal values are prefixed with <code>0</code>
|
||||
and hexadecimal values with <code>0x</code> or <code>0X</code>.
|
||||
<p class="new">
|
||||
Unlike printf, <code>%x</code> and <code>%X</code> truncate the
|
||||
output to the the given width (number of least significant half bytes).
|
||||
</p>
|
||||
</p>
|
||||
<p>
|
||||
<b>Input:</b> <code>%d</code> matches signed decimal, <code>%u</code> matches
|
||||
@ -230,7 +237,7 @@ is accepted.
|
||||
</p>
|
||||
<p class="new">
|
||||
When a maximum field width is given, leading whitespace only counts to the
|
||||
field witdth when the space flag is given.
|
||||
field witdth when the space flag is used.
|
||||
</p>
|
||||
|
||||
<a name="stds"></a>
|
||||
@ -248,7 +255,7 @@ The default <em>width</em> is infinite for <code>%s</code> and
|
||||
1 for <code>%c</code>.
|
||||
Leading whitespaces are skipped with <code>%s</code>
|
||||
<span class="new">
|
||||
except when the space flag is given</span>
|
||||
except when the space flag is used</span>
|
||||
but not with <code>%c</code>.
|
||||
The empty string matches.
|
||||
</p>
|
||||
@ -283,23 +290,35 @@ The strings are separated by <code>|</code>.
|
||||
Example: <code>%{OFF|STANDBY|ON}</code> mapps the string <code>OFF</code>
|
||||
to the value 0, <code>STANDBY</code> to 1 and <code>ON</code> to 2.
|
||||
</p>
|
||||
<p>
|
||||
<p class="new">
|
||||
When using the <code>#</code> flag it is allowed to assign integer values
|
||||
to the strings using <code>=</code>.
|
||||
Unassigned strings increment their values by 1 as usual.
|
||||
</p>
|
||||
<p class="new">
|
||||
If one string is the initial substing of another, the substing must come
|
||||
later to ensure correct matching.
|
||||
In particular if one string is the emptry string, it must be the last one.
|
||||
Use <code>#</code> and <code>=</code> to renumber if necessary.
|
||||
</p>
|
||||
<p class="new">
|
||||
Use the assignment <code>=?</code> for the last string to make it the
|
||||
default value for output formats.
|
||||
</p>
|
||||
<p>
|
||||
Example: <code>%#{neg=-1|stop=0|pos=1|fast=10}</code>.
|
||||
Example: <code>%#{neg=-1|stop|pos|fast=10|rewind=-10}</code>.
|
||||
</p>
|
||||
<p>
|
||||
If one of the strings contains <code>|</code> or <code>}</code>
|
||||
(or <code>=</code> if the <code>#</code> flag is used)
|
||||
<span class="new">(or <code>=</code> if the <code>#</code> flag is used)</span>
|
||||
a <code>\</code> must be used to escape the character.
|
||||
</p>
|
||||
<p>
|
||||
In output, depending on the value, one of the strings is printed.
|
||||
<b>Output:</b> Depending on the value, one of the strings is printed,
|
||||
<span class="new">or the default if no value matches</span>.
|
||||
</p>
|
||||
<p>
|
||||
In input, if any of the strings matches the value is set accordingly.
|
||||
<b>Input:</b> If any of the strings matches, the value is set accordingly.
|
||||
</p>
|
||||
|
||||
<a name="bin"></a>
|
||||
|
@ -281,7 +281,7 @@ With some more records, you can clean the message record if SEVR is not INVALID.
|
||||
<code>
|
||||
record (calcout, "$(DEVICE):clean_1") {<br>
|
||||
field (INPA, "$(DEVICE):readcurrent.SEVR CP")<br>
|
||||
field (CALC, "A!=2")<br>
|
||||
field (CALC, "A#3")<br>
|
||||
field (OOPT, "When Non-zero")<br>
|
||||
field (OUT, "$(DEVICE):clean_2.PROC")<br>
|
||||
}<br>
|
||||
|
14
makefile
14
makefile
@ -1,12 +1,10 @@
|
||||
include /ioc/tools/driver.makefile
|
||||
EXCLUDE_VERSIONS = 3.13.2
|
||||
PROJECT=stream2
|
||||
PROJECT=stream
|
||||
BUILDCLASSES += Linux
|
||||
|
||||
#DOCUDIR = doc
|
||||
|
||||
DBDS = stream.dbd
|
||||
|
||||
BUSSES += AsynDriver
|
||||
BUSSES += Dummy
|
||||
|
||||
@ -42,9 +40,9 @@ HEADERS += StreamBuffer.h
|
||||
HEADERS += StreamError.h
|
||||
|
||||
ifeq (${EPICS_BASETYPE},3.13)
|
||||
USR_INCLUDES += -include $(INSTALL_INCLUDE)/compat3_13.h
|
||||
endif
|
||||
ifeq (${EPICS_BASETYPE},3.14)
|
||||
# old gcc needs full path for -include
|
||||
CXXFLAGS += -include $(foreach d,${INCLUDES:-I%=%},$(wildcard $d/compat3_13.h))
|
||||
else
|
||||
RECORDTYPES += calcout
|
||||
endif
|
||||
|
||||
@ -54,5 +52,7 @@ streamReferences:
|
||||
perl ../src/makeref.pl Interface $(BUSSES) > $@
|
||||
perl ../src/makeref.pl Converter $(FORMATS) >> $@
|
||||
|
||||
stream.dbd:
|
||||
# have to hack a bit to work with both versions of driver.makefile
|
||||
DBDFILES = O.$${EPICSVERSION}_$${T_A}/streamSup.dbd
|
||||
../O.${EPICSVERSION}_${T_A}/streamSup.dbd:
|
||||
perl ../src/makedbd.pl $(RECORDTYPES) > $@
|
||||
|
@ -31,9 +31,9 @@ class BCDConverter : public StreamFormatConverter
|
||||
};
|
||||
|
||||
int BCDConverter::
|
||||
parse(const StreamFormat&, StreamBuffer&, const char*&, bool)
|
||||
parse(const StreamFormat& fmt, StreamBuffer&, const char*&, bool)
|
||||
{
|
||||
return long_format;
|
||||
return (fmt.flags & sign_flag) ? signed_format : unsigned_format;
|
||||
}
|
||||
|
||||
bool BCDConverter::
|
||||
|
@ -19,6 +19,7 @@
|
||||
***************************************************************/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include "StreamFormatConverter.h"
|
||||
#include "StreamError.h"
|
||||
|
||||
@ -32,51 +33,59 @@ class BinaryConverter : public StreamFormatConverter
|
||||
};
|
||||
|
||||
int BinaryConverter::
|
||||
parse(const StreamFormat& format, StreamBuffer& info,
|
||||
parse(const StreamFormat& fmt, StreamBuffer& info,
|
||||
const char*& source, bool)
|
||||
{
|
||||
if (format.conv == 'B')
|
||||
if (fmt.conv == 'b')
|
||||
{
|
||||
// user defined characters for %B (next 2 in source)
|
||||
// default characters 0 and 1 for %b
|
||||
info.append("01");
|
||||
return unsigned_format;
|
||||
}
|
||||
|
||||
// user defined characters for %B (next 2 in source)
|
||||
if (*source)
|
||||
{
|
||||
if (*source == esc) source++;
|
||||
info.append(*source++);
|
||||
if (*source)
|
||||
{
|
||||
if (*source == esc) source++;
|
||||
info.append(*source++);
|
||||
if (*source)
|
||||
{
|
||||
if (*source == esc) source++;
|
||||
info.append(*source++);
|
||||
return long_format;
|
||||
}
|
||||
return unsigned_format;
|
||||
}
|
||||
error("Missing characters after %%B format conversion\n");
|
||||
return false;
|
||||
}
|
||||
// default characters for %b
|
||||
info.append("01");
|
||||
return long_format;
|
||||
error("Missing characters after %%B format conversion\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BinaryConverter::
|
||||
printLong(const StreamFormat& format, StreamBuffer& output, long value)
|
||||
printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
||||
{
|
||||
int prec = format.prec;
|
||||
int prec = fmt.prec;
|
||||
if (prec == -1)
|
||||
{
|
||||
// find number of significant bits
|
||||
prec = sizeof (value) * 8;
|
||||
while (prec && (value & (1L << (prec - 1))) == 0) prec--;
|
||||
// Find number of significant bits is nothing is specified.
|
||||
unsigned long x = (unsigned long) value;
|
||||
prec = 32;
|
||||
#if (LONG_BIT > 32)
|
||||
if (x > 0xFFFFFFFF) { prec = 64; x >>=32; }
|
||||
#endif
|
||||
if (x <= 0x0000FFFF) { prec -= 16; x <<=16; }
|
||||
if (x <= 0x00FFFFFF) { prec -= 8; x <<=8; }
|
||||
if (x <= 0x0FFFFFFF) { prec -= 4; x <<=4; }
|
||||
if (x <= 0x3FFFFFFF) { prec -= 2; x <<=2; }
|
||||
if (x <= 0x7FFFFFFF) { prec -= 1; }
|
||||
}
|
||||
if (prec == 0) prec++; // print at least one bit
|
||||
int width = prec;
|
||||
if (format.width > width) width = format.width;
|
||||
char zero = format.info[0];
|
||||
char one = format.info[1];
|
||||
char fill = (format.flags & zero_flag) ? zero : ' ';
|
||||
if (format.flags & alt_flag)
|
||||
if (fmt.width > width) width = fmt.width;
|
||||
char zero = fmt.info[0];
|
||||
char one = fmt.info[1];
|
||||
char fill = (fmt.flags & zero_flag) ? zero : ' ';
|
||||
if (fmt.flags & alt_flag)
|
||||
{
|
||||
// little endian (least significant bit first)
|
||||
if (!(format.flags & left_flag))
|
||||
if (!(fmt.flags & left_flag))
|
||||
{
|
||||
// pad left
|
||||
while (width > prec)
|
||||
@ -100,7 +109,7 @@ printLong(const StreamFormat& format, StreamBuffer& output, long value)
|
||||
else
|
||||
{
|
||||
// big endian (most significant bit first)
|
||||
if (!(format.flags & left_flag))
|
||||
if (!(fmt.flags & left_flag))
|
||||
{
|
||||
// pad left
|
||||
while (width > prec)
|
||||
@ -124,18 +133,18 @@ printLong(const StreamFormat& format, StreamBuffer& output, long value)
|
||||
}
|
||||
|
||||
int BinaryConverter::
|
||||
scanLong(const StreamFormat& format, const char* input, long& value)
|
||||
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
||||
{
|
||||
long val = 0;
|
||||
int width = format.width;
|
||||
int width = fmt.width;
|
||||
if (width == 0) width = -1;
|
||||
int length = 0;
|
||||
char zero = format.info[0];
|
||||
char one = format.info[1];
|
||||
char zero = fmt.info[0];
|
||||
char one = fmt.info[1];
|
||||
if (!isspace(zero) && !isspace(one))
|
||||
while (isspace(input[length])) length++; // skip whitespaces
|
||||
if (input[length] != zero && input[length] != one) return -1;
|
||||
if (format.flags & alt_flag)
|
||||
if (fmt.flags & alt_flag)
|
||||
{
|
||||
// little endian (least significan bit first)
|
||||
long mask = 1;
|
||||
|
@ -36,7 +36,7 @@ class EnumConverter : public StreamFormatConverter
|
||||
|
||||
int EnumConverter::
|
||||
parse(const StreamFormat& fmt, StreamBuffer& info,
|
||||
const char*& source, bool)
|
||||
const char*& source, bool scanFormat)
|
||||
{
|
||||
if (fmt.flags & (left_flag|sign_flag|space_flag|zero_flag))
|
||||
{
|
||||
@ -56,7 +56,30 @@ parse(const StreamFormat& fmt, StreamBuffer& info,
|
||||
if (*source == '=' && (fmt.flags & alt_flag))
|
||||
{
|
||||
char* p;
|
||||
index = strtol(++source, &p, 0);
|
||||
|
||||
if (*++source == '?')
|
||||
{
|
||||
// default choice
|
||||
if (scanFormat)
|
||||
{
|
||||
error("Default value only allowed in output formats\n");
|
||||
return false;
|
||||
}
|
||||
if (*++source != '}')
|
||||
{
|
||||
error("Default value must be last\n");
|
||||
return false;
|
||||
}
|
||||
source++;
|
||||
numEnums = -(numEnums+1);
|
||||
info.append('\0');
|
||||
memcpy(info(n), &numEnums, sizeof(numEnums));
|
||||
debug("EnumConverter::parse %ld choices with default: %s\n",
|
||||
-numEnums, info.expand()());
|
||||
return enum_format;
|
||||
}
|
||||
|
||||
index = strtol(source, &p, 0);
|
||||
if (p == source || (*p != '|' && *p != '}'))
|
||||
{
|
||||
error("Integer expected after '=' "
|
||||
@ -99,6 +122,9 @@ printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
||||
const char* s = fmt.info;
|
||||
long numEnums = extract<long>(s);
|
||||
long index = extract<long>(s);
|
||||
bool noDefault = numEnums >= 0;
|
||||
|
||||
if (numEnums < 0) numEnums=-numEnums-1;
|
||||
while (numEnums-- && (value != index))
|
||||
{
|
||||
while(*s)
|
||||
@ -109,7 +135,7 @@ printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
||||
s++;
|
||||
index = extract<long>(s);
|
||||
}
|
||||
if (numEnums == -1)
|
||||
if (numEnums == -1 && noDefault)
|
||||
{
|
||||
error("Value %li not found in enum set\n", value);
|
||||
return false;
|
||||
|
@ -31,23 +31,23 @@ class RawConverter : public StreamFormatConverter
|
||||
};
|
||||
|
||||
int RawConverter::
|
||||
parse(const StreamFormat&, StreamBuffer&,
|
||||
parse(const StreamFormat& fmt, StreamBuffer&,
|
||||
const char*&, bool)
|
||||
{
|
||||
return long_format;
|
||||
return (fmt.flags & (sign_flag|zero_flag)) ? signed_format : unsigned_format;
|
||||
}
|
||||
|
||||
bool RawConverter::
|
||||
printLong(const StreamFormat& format, StreamBuffer& output, long value)
|
||||
printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
||||
{
|
||||
int prec = format.prec; // number of bytes from value
|
||||
int prec = fmt.prec; // number of bytes from value
|
||||
if (prec == -1) prec = 1; // default: 1 byte
|
||||
int width = prec; // number of bytes in output
|
||||
if (prec > (int)sizeof(long)) prec=sizeof(long);
|
||||
if (format.width > width) width = format.width;
|
||||
if (fmt.width > width) width = fmt.width;
|
||||
|
||||
char byte = 0;
|
||||
if (format.flags & alt_flag) // little endian (lsb first)
|
||||
if (fmt.flags & alt_flag) // little endian (lsb first)
|
||||
{
|
||||
while (prec--)
|
||||
{
|
||||
@ -56,7 +56,7 @@ printLong(const StreamFormat& format, StreamBuffer& output, long value)
|
||||
value >>= 8;
|
||||
width--;
|
||||
}
|
||||
if (format.flags & zero_flag)
|
||||
if (fmt.flags & zero_flag)
|
||||
{
|
||||
// fill with zero
|
||||
byte = 0;
|
||||
@ -73,7 +73,7 @@ printLong(const StreamFormat& format, StreamBuffer& output, long value)
|
||||
}
|
||||
else // big endian (msb first)
|
||||
{
|
||||
if (format.flags & zero_flag)
|
||||
if (fmt.flags & zero_flag)
|
||||
{
|
||||
// fill with zero
|
||||
byte = 0;
|
||||
@ -97,17 +97,17 @@ printLong(const StreamFormat& format, StreamBuffer& output, long value)
|
||||
}
|
||||
|
||||
int RawConverter::
|
||||
scanLong(const StreamFormat& format, const char* input, long& value)
|
||||
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
||||
{
|
||||
long length = 0;
|
||||
long val = 0;
|
||||
int width = format.width;
|
||||
int width = fmt.width;
|
||||
if (width == 0) width = 1; // default: 1 byte
|
||||
if (format.flags & skip_flag)
|
||||
if (fmt.flags & skip_flag)
|
||||
{
|
||||
return width; // just skip input
|
||||
}
|
||||
if (format.flags & alt_flag)
|
||||
if (fmt.flags & alt_flag)
|
||||
{
|
||||
// little endian (lsb first)
|
||||
unsigned int shift = 0;
|
||||
@ -118,7 +118,7 @@ scanLong(const StreamFormat& format, const char* input, long& value)
|
||||
}
|
||||
if (width == 0)
|
||||
{
|
||||
if (format.flags & zero_flag)
|
||||
if (fmt.flags & zero_flag)
|
||||
{
|
||||
// fill with zero
|
||||
val |= ((unsigned char) input[length++]) << shift;
|
||||
@ -134,7 +134,7 @@ scanLong(const StreamFormat& format, const char* input, long& value)
|
||||
else
|
||||
{
|
||||
// big endian (msb first)
|
||||
if (format.flags & zero_flag)
|
||||
if (fmt.flags & zero_flag)
|
||||
{
|
||||
// fill with zero
|
||||
val = (unsigned char) input[length++];
|
||||
|
@ -749,7 +749,7 @@ printSeparator()
|
||||
bool StreamCore::
|
||||
printValue(const StreamFormat& fmt, long value)
|
||||
{
|
||||
if (fmt.type != long_format && fmt.type != enum_format)
|
||||
if (fmt.type != unsigned_format && fmt.type != signed_format && fmt.type != enum_format)
|
||||
{
|
||||
error("%s: printValue(long) called with %%%c format\n",
|
||||
name(), fmt.conv);
|
||||
@ -1216,7 +1216,8 @@ normal_format:
|
||||
double ddummy;
|
||||
switch (fmt.type)
|
||||
{
|
||||
case long_format:
|
||||
case unsigned_format:
|
||||
case signed_format:
|
||||
case enum_format:
|
||||
consumed = StreamFormatConverter::find(fmt.conv)->
|
||||
scanLong(fmt, inputLine(consumedInput), ldummy);
|
||||
@ -1457,7 +1458,7 @@ matchSeparator()
|
||||
long StreamCore::
|
||||
scanValue(const StreamFormat& fmt, long& value)
|
||||
{
|
||||
if (fmt.type != long_format && fmt.type != enum_format)
|
||||
if (fmt.type != unsigned_format && fmt.type != signed_format && fmt.type != enum_format)
|
||||
{
|
||||
error("%s: scanValue(long&) called with %%%c format\n",
|
||||
name(), fmt.conv);
|
||||
|
@ -751,21 +751,16 @@ process()
|
||||
bool Stream::
|
||||
print(format_t *format, va_list ap)
|
||||
{
|
||||
long lval;
|
||||
double dval;
|
||||
char* sval;
|
||||
switch (format->type)
|
||||
{
|
||||
case DBF_ENUM:
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
lval = va_arg(ap, long);
|
||||
return printValue(*format->priv, lval);
|
||||
case DBF_ENUM:
|
||||
return printValue(*format->priv, va_arg(ap, long));
|
||||
case DBF_DOUBLE:
|
||||
dval = va_arg(ap, double);
|
||||
return printValue(*format->priv, dval);
|
||||
return printValue(*format->priv, va_arg(ap, double));
|
||||
case DBF_STRING:
|
||||
sval = va_arg(ap, char*);
|
||||
return printValue(*format->priv, sval);
|
||||
return printValue(*format->priv, va_arg(ap, char*));
|
||||
}
|
||||
error("INTERNAL ERROR (%s): Illegal format type\n", name());
|
||||
return false;
|
||||
@ -775,27 +770,22 @@ bool Stream::
|
||||
scan(format_t *format, void* value, size_t maxStringSize)
|
||||
{
|
||||
// called by streamScanfN
|
||||
long* lptr;
|
||||
double* dptr;
|
||||
char* sptr;
|
||||
|
||||
// first remove old value from inputLine (if we are scanning arrays)
|
||||
consumedInput += currentValueLength;
|
||||
currentValueLength = 0;
|
||||
switch (format->type)
|
||||
{
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
case DBF_ENUM:
|
||||
lptr = (long*)value;
|
||||
currentValueLength = scanValue(*format->priv, *lptr);
|
||||
currentValueLength = scanValue(*format->priv, *(long*)value);
|
||||
break;
|
||||
case DBF_DOUBLE:
|
||||
dptr = (double*)value;
|
||||
currentValueLength = scanValue(*format->priv, *dptr);
|
||||
currentValueLength = scanValue(*format->priv, *(double*)value);
|
||||
break;
|
||||
case DBF_STRING:
|
||||
sptr = (char*)value;
|
||||
currentValueLength = scanValue(*format->priv, sptr,
|
||||
currentValueLength = scanValue(*format->priv, (char*)value,
|
||||
maxStringSize);
|
||||
break;
|
||||
default:
|
||||
@ -979,9 +969,9 @@ getFieldAddress(const char* fieldname, StreamBuffer& address)
|
||||
}
|
||||
|
||||
static const unsigned char dbfMapping[] =
|
||||
{0, DBF_LONG, DBF_ENUM, DBF_DOUBLE, DBF_STRING};
|
||||
{0, DBF_ULONG, DBF_LONG, DBF_ENUM, DBF_DOUBLE, DBF_STRING};
|
||||
static const short typeSize[] =
|
||||
{0, sizeof(epicsInt32), sizeof(epicsUInt16),
|
||||
{0, sizeof(epicsUInt32), sizeof(epicsInt32), sizeof(epicsUInt16),
|
||||
sizeof(epicsFloat64), MAX_STRING_SIZE};
|
||||
|
||||
bool Stream::
|
||||
@ -993,6 +983,9 @@ formatValue(const StreamFormat& format, const void* fieldaddress)
|
||||
// -- TO DO: If SCAN is "I/O Intr" and record has not been processed, --
|
||||
// -- do it now to get the latest value (only for output records?) --
|
||||
|
||||
format_s fmt;
|
||||
fmt.type = dbfMapping[format.type];
|
||||
fmt.priv = &format;
|
||||
if (fieldaddress)
|
||||
{
|
||||
// Format like "%([record.]field)..." has requested to get value
|
||||
@ -1025,7 +1018,6 @@ formatValue(const StreamFormat& format, const void* fieldaddress)
|
||||
}
|
||||
|
||||
/* convert type to LONG, ENUM, DOUBLE, or STRING */
|
||||
int type = dbfMapping[format.type];
|
||||
long nelem = pdbaddr->no_elements;
|
||||
size_t size = nelem * typeSize[format.type];
|
||||
|
||||
@ -1040,13 +1032,13 @@ formatValue(const StreamFormat& format, const void* fieldaddress)
|
||||
nelem,
|
||||
pdbaddr->field_size,
|
||||
pamapdbfType[pdbaddr->field_type].strvalue);
|
||||
type = DBF_CHAR;
|
||||
fmt.type = DBF_CHAR;
|
||||
size = nelem;
|
||||
}
|
||||
|
||||
char* buffer = fieldBuffer.clear().reserve(size);
|
||||
|
||||
if (dbGet(pdbaddr, type, buffer,
|
||||
if (dbGet(pdbaddr, fmt.type, buffer,
|
||||
NULL, &nelem, NULL) != 0)
|
||||
{
|
||||
error("%s: dbGet(%s.%s, %s) failed\n",
|
||||
@ -1060,7 +1052,7 @@ formatValue(const StreamFormat& format, const void* fieldaddress)
|
||||
name(),nelem);
|
||||
|
||||
/* terminate CHAR array as string */
|
||||
if (type == DBF_CHAR)
|
||||
if (fmt.type == DBF_CHAR)
|
||||
{
|
||||
if (nelem >= pdbaddr->no_elements) nelem = pdbaddr->no_elements-1;
|
||||
buffer[nelem] = 0;
|
||||
@ -1077,7 +1069,12 @@ formatValue(const StreamFormat& format, const void* fieldaddress)
|
||||
(long)((epicsUInt16*)buffer)[i]))
|
||||
return false;
|
||||
break;
|
||||
case long_format:
|
||||
case unsigned_format:
|
||||
if (!printValue(format,
|
||||
(long)((epicsUInt32*)buffer)[i]))
|
||||
return false;
|
||||
break;
|
||||
case signed_format:
|
||||
if (!printValue(format,
|
||||
(long)((epicsInt32*)buffer)[i]))
|
||||
return false;
|
||||
@ -1104,9 +1101,6 @@ formatValue(const StreamFormat& format, const void* fieldaddress)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
format_s fmt;
|
||||
fmt.type = dbfMapping[format.type];
|
||||
fmt.priv = &format;
|
||||
debug("Stream::formatValue(%s) format=%%%c type=%s\n",
|
||||
name(), format.conv, pamapdbfType[fmt.type].strvalue);
|
||||
if (!writeData)
|
||||
@ -1132,7 +1126,10 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
char* buffer;
|
||||
int status;
|
||||
const char* putfunc;
|
||||
format_s fmt;
|
||||
|
||||
fmt.type = dbfMapping[format.type];
|
||||
fmt.priv = &format;
|
||||
if (fieldaddress)
|
||||
{
|
||||
// Format like "%([record.]field)..." has requested to put value
|
||||
@ -1148,12 +1145,24 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
name(), fieldBuffer.expand()());
|
||||
switch (format.type)
|
||||
{
|
||||
case long_format:
|
||||
case unsigned_format:
|
||||
{
|
||||
consumed = scanValue(format, lval);
|
||||
if (consumed >= 0) ((epicsUInt32*)buffer)[nord] = lval;
|
||||
debug("Stream::matchValue(%s): %s.%s[%li] = %lu\n",
|
||||
name(), pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
nord, lval);
|
||||
break;
|
||||
}
|
||||
case signed_format:
|
||||
{
|
||||
consumed = scanValue(format, lval);
|
||||
if (consumed >= 0) ((epicsInt32*)buffer)[nord] = lval;
|
||||
debug("Stream::matchValue(%s): %s[%li] = %li\n",
|
||||
name(), pdbaddr->precord->name, nord, lval);
|
||||
debug("Stream::matchValue(%s): %s.%s[%li] = %li\n",
|
||||
name(), pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
nord, lval);
|
||||
break;
|
||||
}
|
||||
case enum_format:
|
||||
@ -1161,8 +1170,10 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
consumed = scanValue(format, lval);
|
||||
if (consumed >= 0)
|
||||
((epicsUInt16*)buffer)[nord] = (epicsUInt16)lval;
|
||||
debug("Stream::matchValue(%s): %s[%li] = %li\n",
|
||||
name(), pdbaddr->precord->name, nord, lval);
|
||||
debug("Stream::matchValue(%s): %s.%s[%li] = %li\n",
|
||||
name(), pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
nord, lval);
|
||||
break;
|
||||
}
|
||||
case double_format:
|
||||
@ -1175,18 +1186,34 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
if (consumed >= 0)
|
||||
memcpy(((epicsFloat64*)buffer)+nord,
|
||||
&f64, sizeof(f64));
|
||||
debug("Stream::matchValue(%s): %s[%li] = %#g %#g\n",
|
||||
name(), pdbaddr->precord->name, nord, dval,
|
||||
debug("Stream::matchValue(%s): %s.%s[%li] = %#g %#g\n",
|
||||
name(), pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
nord, dval,
|
||||
((epicsFloat64*)buffer)[nord]);
|
||||
break;
|
||||
}
|
||||
case string_format:
|
||||
{
|
||||
consumed = scanValue(format,
|
||||
buffer+MAX_STRING_SIZE*nord, MAX_STRING_SIZE);
|
||||
debug("Stream::matchValue(%s): %s[%li] = \"%.*s\"\n",
|
||||
name(), pdbaddr->precord->name, nord,
|
||||
MAX_STRING_SIZE, buffer+MAX_STRING_SIZE*nord);
|
||||
if (pdbaddr->field_type == DBF_CHAR)
|
||||
{
|
||||
// string to char array
|
||||
consumed = scanValue(format, buffer, nelem);
|
||||
debug("Stream::matchValue(%s): %s.%s = \"%.*s\"\n",
|
||||
name(), pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
(int)consumed, buffer);
|
||||
nord = nelem;
|
||||
}
|
||||
else
|
||||
{
|
||||
consumed = scanValue(format,
|
||||
buffer+MAX_STRING_SIZE*nord, MAX_STRING_SIZE);
|
||||
debug("Stream::matchValue(%s): %s.%s[%li] = \"%.*s\"\n",
|
||||
name(), pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
nord, MAX_STRING_SIZE, buffer+MAX_STRING_SIZE*nord);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1223,15 +1250,17 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
name());
|
||||
return false;
|
||||
}
|
||||
/* convert from Unix epoch (1 Jan 1970) to EPICS epoch (1 Jan 1990) */
|
||||
dval = dval-631152000u;
|
||||
pdbaddr->precord->time.secPastEpoch = (long)dval;
|
||||
// rouding: we don't have 9 digits precision
|
||||
// in a double of today's number of seconds
|
||||
pdbaddr->precord->time.nsec = (long)((dval-(long)dval)*1e6)*1000;
|
||||
debug("Stream::matchValue(%s): writing %i.%i to TIME field\n",
|
||||
debug("Stream::matchValue(%s): writing %i.%i to %s.TIME field\n",
|
||||
name(),
|
||||
pdbaddr->precord->time.secPastEpoch,
|
||||
pdbaddr->precord->time.nsec);
|
||||
pdbaddr->precord->time.nsec,
|
||||
pdbaddr->precord->name);
|
||||
pdbaddr->precord->tse = epicsTimeEventDeviceTime;
|
||||
return true;
|
||||
#else
|
||||
@ -1240,18 +1269,19 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (format.type == string_format &&
|
||||
(pdbaddr->field_type == DBF_CHAR || pdbaddr->field_type == DBF_UCHAR))
|
||||
{
|
||||
/* write strings to [U]CHAR arrays */
|
||||
nord = consumed;
|
||||
fmt.type = DBF_CHAR;
|
||||
}
|
||||
if (pdbaddr->precord == record || INIT_RUN)
|
||||
{
|
||||
// write into own record, thus don't process it
|
||||
// in @init we must not process other record
|
||||
debug("Stream::matchValue(%s): dbPut(%s.%s,%s)\n",
|
||||
name(),
|
||||
pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
fieldBuffer.expand()());
|
||||
putfunc = "dbPut";
|
||||
status = dbPut(pdbaddr, dbfMapping[format.type], buffer, nord);
|
||||
status = dbPut(pdbaddr, fmt.type, buffer, nord);
|
||||
if (INIT_RUN && pdbaddr->precord != record)
|
||||
{
|
||||
// clean error status of other record in @init
|
||||
@ -1263,41 +1293,44 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
else
|
||||
{
|
||||
// write into other record, thus process it
|
||||
debug("Stream::matchValue(%s): dbPutField(%s.%s,%s)\n",
|
||||
name(),
|
||||
pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
fieldBuffer.expand()());
|
||||
putfunc = "dbPutField";
|
||||
status = dbPutField(pdbaddr, dbfMapping[format.type],
|
||||
status = dbPutField(pdbaddr, fmt.type,
|
||||
buffer, nord);
|
||||
}
|
||||
debug("Stream::matchValue(%s): %s(%s.%s, %s, %s) status=0x%x\n",
|
||||
name(), putfunc,
|
||||
pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
pamapdbfType[fmt.type].strvalue,
|
||||
fieldBuffer.expand()(),
|
||||
status);
|
||||
if (status != 0)
|
||||
{
|
||||
flags &= ~ScanTried;
|
||||
switch (format.type)
|
||||
switch (fmt.type)
|
||||
{
|
||||
case long_format:
|
||||
case enum_format:
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
case DBF_ENUM:
|
||||
error("%s: %s(%s.%s, %s, %li) failed\n",
|
||||
putfunc, name(), pdbaddr->precord->name,
|
||||
name(), putfunc, pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
pamapdbfType[dbfMapping[format.type]].strvalue,
|
||||
pamapdbfType[fmt.type].strvalue,
|
||||
lval);
|
||||
return false;
|
||||
case double_format:
|
||||
case DBF_DOUBLE:
|
||||
error("%s: %s(%s.%s, %s, %#g) failed\n",
|
||||
putfunc, name(), pdbaddr->precord->name,
|
||||
name(), putfunc, pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
pamapdbfType[dbfMapping[format.type]].strvalue,
|
||||
pamapdbfType[fmt.type].strvalue,
|
||||
dval);
|
||||
return false;
|
||||
case string_format:
|
||||
error("%s: %s(%s.%s, %s, \"%s\") failed\n",
|
||||
putfunc, name(), pdbaddr->precord->name,
|
||||
case DBF_STRING:
|
||||
error("%s: %s(%s.%s, %s, \"%.*s\") failed\n",
|
||||
name(), putfunc, pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
pamapdbfType[dbfMapping[format.type]].strvalue,
|
||||
buffer);
|
||||
pamapdbfType[fmt.type].strvalue,
|
||||
(int)consumed, buffer);
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
@ -1306,9 +1339,6 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
return true;
|
||||
}
|
||||
// no fieldaddress (the "normal" case)
|
||||
format_s fmt;
|
||||
fmt.type = dbfMapping[format.type];
|
||||
fmt.priv = &format;
|
||||
if (!readData)
|
||||
{
|
||||
error("%s: No readData() function provided\n", name());
|
||||
|
@ -34,11 +34,12 @@ typedef enum {
|
||||
} StreamFormatFlag;
|
||||
|
||||
typedef enum {
|
||||
long_format = 1,
|
||||
enum_format = 2,
|
||||
double_format = 3,
|
||||
string_format = 4,
|
||||
pseudo_format = 5
|
||||
unsigned_format = 1,
|
||||
signed_format,
|
||||
enum_format,
|
||||
double_format,
|
||||
string_format,
|
||||
pseudo_format
|
||||
} StreamFormatType;
|
||||
|
||||
extern const char* StreamFormatTypeStr[];
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include "StreamFormatConverter.h"
|
||||
#include "StreamError.h"
|
||||
|
||||
@ -310,12 +311,16 @@ parse(const StreamFormat& fmt, StreamBuffer& info,
|
||||
info.append('l');
|
||||
info.append(fmt.conv);
|
||||
}
|
||||
return long_format;
|
||||
if (fmt.conv == 'd' || fmt.conv == 'i') return signed_format;
|
||||
return unsigned_format;
|
||||
}
|
||||
|
||||
bool StdLongConverter::
|
||||
printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
||||
{
|
||||
// limits %x/%X formats to number of half bytes in width.
|
||||
if (fmt.width && (fmt.conv == 'x' || fmt.conv == 'X') && fmt.width < 2*sizeof(long))
|
||||
value &= ~(-1L << (fmt.width*4));
|
||||
output.print(fmt.info, value);
|
||||
return true;
|
||||
}
|
||||
@ -327,6 +332,7 @@ scanLong(const StreamFormat& fmt, const char* input, long& value)
|
||||
int length;
|
||||
bool neg;
|
||||
int base;
|
||||
long v;
|
||||
|
||||
length = prepareval(fmt, input, neg);
|
||||
if (length < 0) return -1;
|
||||
@ -336,14 +342,11 @@ scanLong(const StreamFormat& fmt, const char* input, long& value)
|
||||
base = 10;
|
||||
break;
|
||||
case 'o':
|
||||
base = 8;
|
||||
goto signcheck;
|
||||
case 'x':
|
||||
case 'X':
|
||||
base = 16;
|
||||
signcheck:
|
||||
// allow negative hex and oct numbers with - flag
|
||||
// allow negative hex and oct numbers with - flag
|
||||
if (neg && !(fmt.flags & left_flag)) return -1;
|
||||
base = (fmt.conv == 'o') ? 8 : 16;
|
||||
break;
|
||||
case 'u':
|
||||
if (neg) return -1;
|
||||
@ -352,10 +355,10 @@ signcheck:
|
||||
default:
|
||||
base = 0;
|
||||
}
|
||||
value = strtoul(input, &end, base);
|
||||
if (neg) value = -value;
|
||||
v = strtoul(input, &end, base);
|
||||
if (end == input) return -1;
|
||||
length += end-input;
|
||||
value = neg ? -v : v;
|
||||
return length;
|
||||
}
|
||||
|
||||
@ -543,7 +546,7 @@ parse(const StreamFormat& fmt, StreamBuffer& info,
|
||||
info.append("%n");
|
||||
return string_format;
|
||||
}
|
||||
return long_format;
|
||||
return unsigned_format;
|
||||
}
|
||||
|
||||
bool StdCharsConverter::
|
||||
|
@ -26,7 +26,8 @@
|
||||
#include "StreamError.h"
|
||||
|
||||
const char* StreamFormatTypeStr[] = {
|
||||
"none", "long", "enum", "double", "string", "pseudo"
|
||||
// must match the order in StreamFormat.h
|
||||
"none", "unsigned", "signed", "enum", "double", "string", "pseudo"
|
||||
};
|
||||
|
||||
class StreamProtocolParser::Protocol::Variable
|
||||
@ -1438,7 +1439,7 @@ compileFormat(StreamBuffer& buffer, const char*& formatstr,
|
||||
// parsing failed
|
||||
return false;
|
||||
}
|
||||
if (type < long_format && type > pseudo_format)
|
||||
if (type < 1 && type > pseudo_format)
|
||||
{
|
||||
error(line, filename(),
|
||||
"Illegal format type %d returned from '%%%c' converter\n",
|
||||
|
@ -20,9 +20,9 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "devStream.h"
|
||||
#include <aaiRecord.h>
|
||||
#include <errlog.h>
|
||||
#include <aaiRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
@ -57,6 +57,7 @@ static long readData (dbCommon *record, format_t *format)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
case DBF_ENUM:
|
||||
{
|
||||
@ -191,6 +192,7 @@ static long writeData (dbCommon *record, format_t *format)
|
||||
return ERROR;
|
||||
break;
|
||||
}
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
case DBF_ENUM:
|
||||
{
|
||||
|
@ -20,9 +20,9 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "devStream.h"
|
||||
#include <aaoRecord.h>
|
||||
#include <errlog.h>
|
||||
#include <aaoRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
@ -57,6 +57,7 @@ static long readData (dbCommon *record, format_t *format)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
case DBF_ENUM:
|
||||
{
|
||||
@ -191,6 +192,7 @@ static long writeData (dbCommon *record, format_t *format)
|
||||
return ERROR;
|
||||
break;
|
||||
}
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
case DBF_ENUM:
|
||||
{
|
||||
|
@ -18,10 +18,18 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <math.h>
|
||||
#include <menuConvert.h>
|
||||
#include <aiRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <private/mathP.h>
|
||||
#define isinf(x) isInf(x)
|
||||
#define isnan(x) isNan(x)
|
||||
#endif
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
{
|
||||
aiRecord *ai = (aiRecord *) record;
|
||||
@ -32,20 +40,28 @@ static long readData (dbCommon *record, format_t *format)
|
||||
{
|
||||
double val;
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
if (ai->aslo != 0.0) val *= ai->aslo;
|
||||
if (ai->aslo != 0.0 && ai->aslo != 1.0) val *= ai->aslo;
|
||||
val += ai->aoff;
|
||||
if (!INIT_RUN && ai->smoo != 0.0)
|
||||
{
|
||||
if (!(ai->smoo == 0.0 || ai->init || ai->udf || isinf(ai->val) || isnan(ai->val)))
|
||||
val = ai->val * ai->smoo + val * (1.0 - ai->smoo);
|
||||
}
|
||||
ai->val = val;
|
||||
return DO_NOT_CONVERT;
|
||||
}
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
{
|
||||
long rval;
|
||||
if (streamScanf (record, format, &rval)) return ERROR;
|
||||
ai->rval = rval;
|
||||
if (ai->linr == menuConvertNO_CONVERSION)
|
||||
{
|
||||
/* allow more bits than 32 */
|
||||
if (format->type == DBF_ULONG)
|
||||
ai->val = (unsigned long)rval;
|
||||
else
|
||||
ai->val = rval;
|
||||
return DO_NOT_CONVERT;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
@ -55,19 +71,32 @@ static long readData (dbCommon *record, format_t *format)
|
||||
static long writeData (dbCommon *record, format_t *format)
|
||||
{
|
||||
aiRecord *ai = (aiRecord *) record;
|
||||
double val;
|
||||
|
||||
switch (format->type)
|
||||
{
|
||||
case DBF_DOUBLE:
|
||||
{
|
||||
val = ai->val - ai->aoff;
|
||||
if (ai->aslo != 0) val /= ai->aslo;
|
||||
double val = ai->val - ai->aoff;
|
||||
if (ai->aslo != 0.0 && ai->aslo != 1.0) val /= ai->aslo;
|
||||
return streamPrintf (record, format, val);
|
||||
}
|
||||
case DBF_ULONG:
|
||||
{
|
||||
if (ai->linr == menuConvertNO_CONVERSION)
|
||||
{
|
||||
/* allow more bits than 32 */
|
||||
return streamPrintf (record, format, (unsigned long)ai->val);
|
||||
}
|
||||
return streamPrintf (record, format, (unsigned long)ai->rval);
|
||||
}
|
||||
case DBF_LONG:
|
||||
{
|
||||
return streamPrintf (record, format, (long) ai->rval);
|
||||
if (ai->linr == menuConvertNO_CONVERSION)
|
||||
{
|
||||
/* allow more bits than 32 */
|
||||
return streamPrintf (record, format, (long)ai->val);
|
||||
}
|
||||
return streamPrintf (record, format, (long)ai->rval);
|
||||
}
|
||||
}
|
||||
return ERROR;
|
||||
|
@ -18,8 +18,9 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <menuConvert.h>
|
||||
#include <aoRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
@ -32,16 +33,26 @@ static long readData (dbCommon *record, format_t *format)
|
||||
{
|
||||
double val;
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
if (ao->aslo != 0) val *= ao->aslo;
|
||||
if (ao->aslo != 0.0 && ao->aslo != 1.0) val *= ao->aslo;
|
||||
ao->val = val + ao->aoff;
|
||||
return DO_NOT_CONVERT;
|
||||
}
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
{
|
||||
long rval;
|
||||
if (streamScanf (record, format, &rval)) return ERROR;
|
||||
ao->rbv = rval;
|
||||
if (INIT_RUN) ao->rval = rval;
|
||||
ao->rval = rval;
|
||||
if (ao->linr == menuConvertNO_CONVERSION)
|
||||
{
|
||||
/* allow more bits than 32 */
|
||||
if (format->type == DBF_ULONG)
|
||||
ao->val = (unsigned long)rval;
|
||||
else
|
||||
ao->val = rval;
|
||||
return DO_NOT_CONVERT;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
@ -56,16 +67,27 @@ static long writeData (dbCommon *record, format_t *format)
|
||||
{
|
||||
case DBF_DOUBLE:
|
||||
{
|
||||
double val;
|
||||
if (INIT_RUN) val = ao->val;
|
||||
else val = ao->oval;
|
||||
val -= ao->aoff;
|
||||
if (ao->aslo != 0) val /= ao->aslo;
|
||||
double val = (INIT_RUN ? ao->val : ao->oval) - ao->aoff;
|
||||
if (ao->aslo != 0.0 && ao->aslo != 1.0) val /= ao->aslo;
|
||||
return streamPrintf (record, format, val);
|
||||
}
|
||||
case DBF_ULONG:
|
||||
{
|
||||
if (ao->linr == menuConvertNO_CONVERSION)
|
||||
{
|
||||
/* allow more bits than 32 */
|
||||
return streamPrintf (record, format, (unsigned long)(INIT_RUN ? ao->val : ao->oval));
|
||||
}
|
||||
return streamPrintf (record, format, (unsigned long)ao->rval);
|
||||
}
|
||||
case DBF_LONG:
|
||||
{
|
||||
return streamPrintf (record, format, (long) ao->rval);
|
||||
if (ao->linr == menuConvertNO_CONVERSION)
|
||||
{
|
||||
/* allow more bits than 32 */
|
||||
return streamPrintf (record, format, (long)(INIT_RUN ? ao->val : ao->oval));
|
||||
}
|
||||
return streamPrintf (record, format, (long)ao->rval);
|
||||
}
|
||||
}
|
||||
return ERROR;
|
||||
|
@ -18,9 +18,9 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <biRecord.h>
|
||||
#include <string.h>
|
||||
#include <biRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
@ -30,6 +30,7 @@ static long readData (dbCommon *record, format_t *format)
|
||||
|
||||
switch (format->type)
|
||||
{
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
{
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
@ -69,13 +70,14 @@ static long writeData (dbCommon *record, format_t *format)
|
||||
|
||||
switch (format->type)
|
||||
{
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
{
|
||||
return streamPrintf (record, format, bi->rval);
|
||||
}
|
||||
case DBF_ENUM:
|
||||
{
|
||||
return streamPrintf (record, format, (long) bi->val);
|
||||
return streamPrintf (record, format, (long)bi->val);
|
||||
}
|
||||
case DBF_STRING:
|
||||
{
|
||||
|
@ -18,9 +18,9 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <boRecord.h>
|
||||
#include <string.h>
|
||||
#include <boRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
@ -30,6 +30,7 @@ static long readData (dbCommon *record, format_t *format)
|
||||
|
||||
switch (format->type)
|
||||
{
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
{
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
@ -70,13 +71,14 @@ static long writeData (dbCommon *record, format_t *format)
|
||||
|
||||
switch (format->type)
|
||||
{
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
{
|
||||
return streamPrintf (record, format, bo->rval);
|
||||
}
|
||||
case DBF_ENUM:
|
||||
{
|
||||
return streamPrintf (record, format, (long) bo->val);
|
||||
return streamPrintf (record, format, (long)bo->val);
|
||||
}
|
||||
case DBF_STRING:
|
||||
{
|
||||
|
@ -17,9 +17,9 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <postfix.h>
|
||||
#include <calcoutRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
@ -32,13 +32,17 @@ static long readData (dbCommon *record, format_t *format)
|
||||
{
|
||||
return streamScanf (record, format, &co->val);
|
||||
}
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
case DBF_ENUM:
|
||||
{
|
||||
long lval;
|
||||
|
||||
if (streamScanf (record, format, &lval)) return ERROR;
|
||||
co->val = lval;
|
||||
if (format->type == DBF_LONG)
|
||||
co->val = lval;
|
||||
else
|
||||
co->val = (unsigned long)lval;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
@ -55,8 +59,12 @@ static long writeData (dbCommon *record, format_t *format)
|
||||
{
|
||||
return streamPrintf (record, format, co->oval);
|
||||
}
|
||||
case DBF_LONG:
|
||||
case DBF_ULONG:
|
||||
case DBF_ENUM:
|
||||
{
|
||||
return streamPrintf (record, format, (unsigned long)co->oval);
|
||||
}
|
||||
case DBF_LONG:
|
||||
{
|
||||
return streamPrintf (record, format, (long)co->oval);
|
||||
}
|
||||
|
@ -18,20 +18,25 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <longinRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
{
|
||||
longinRecord *li = (longinRecord *) record;
|
||||
|
||||
if (format->type == DBF_LONG || format->type == DBF_ENUM)
|
||||
switch (format->type)
|
||||
{
|
||||
long val;
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
li->val = val;
|
||||
return OK;
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
case DBF_ENUM:
|
||||
{
|
||||
long val;
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
li->val = val;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
return ERROR;
|
||||
}
|
||||
@ -40,9 +45,13 @@ static long writeData (dbCommon *record, format_t *format)
|
||||
{
|
||||
longinRecord *li = (longinRecord *) record;
|
||||
|
||||
if (format->type == DBF_LONG || format->type == DBF_ENUM)
|
||||
switch (format->type)
|
||||
{
|
||||
return streamPrintf (record, format, (long) li->val);
|
||||
case DBF_ULONG:
|
||||
case DBF_ENUM:
|
||||
return streamPrintf (record, format, (unsigned long)li->val);
|
||||
case DBF_LONG:
|
||||
return streamPrintf (record, format, (long)li->val);
|
||||
}
|
||||
return ERROR;
|
||||
}
|
||||
|
@ -19,20 +19,25 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <longoutRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
{
|
||||
longoutRecord *lo = (longoutRecord *) record;
|
||||
|
||||
if (format->type == DBF_LONG || format->type == DBF_ENUM)
|
||||
switch (format->type)
|
||||
{
|
||||
long val;
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
lo->val = val;
|
||||
return OK;
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
case DBF_ENUM:
|
||||
{
|
||||
long val;
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
lo->val = val;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
return ERROR;
|
||||
}
|
||||
@ -41,9 +46,13 @@ static long writeData (dbCommon *record, format_t *format)
|
||||
{
|
||||
longoutRecord *lo = (longoutRecord *) record;
|
||||
|
||||
if (format->type == DBF_LONG || format->type == DBF_ENUM)
|
||||
switch (format->type)
|
||||
{
|
||||
return streamPrintf (record, format, (long) lo->val);
|
||||
case DBF_ULONG:
|
||||
case DBF_ENUM:
|
||||
return streamPrintf (record, format, (unsigned long)lo->val);
|
||||
case DBF_LONG:
|
||||
return streamPrintf (record, format, (long)lo->val);
|
||||
}
|
||||
return ERROR;
|
||||
}
|
||||
|
@ -19,16 +19,16 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <mbbiDirectRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
{
|
||||
mbbiDirectRecord *mbbiD = (mbbiDirectRecord *) record;
|
||||
long val;
|
||||
unsigned long val;
|
||||
|
||||
if (format->type == DBF_LONG)
|
||||
if (format->type == DBF_ULONG || format->type == DBF_LONG)
|
||||
{
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
if (mbbiD->mask)
|
||||
@ -40,7 +40,7 @@ static long readData (dbCommon *record, format_t *format)
|
||||
else
|
||||
{
|
||||
/* No MASK, (NOBT = 0): use VAL field */
|
||||
mbbiD->val = (short)val;
|
||||
mbbiD->val = (unsigned short)val;
|
||||
return DO_NOT_CONVERT;
|
||||
}
|
||||
}
|
||||
@ -50,9 +50,9 @@ static long readData (dbCommon *record, format_t *format)
|
||||
static long writeData (dbCommon *record, format_t *format)
|
||||
{
|
||||
mbbiDirectRecord *mbbiD = (mbbiDirectRecord *) record;
|
||||
long val;
|
||||
unsigned long val;
|
||||
|
||||
if (format->type == DBF_LONG)
|
||||
if (format->type == DBF_ULONG || format->type == DBF_LONG)
|
||||
{
|
||||
if (mbbiD->mask) val = mbbiD->rval & mbbiD->mask;
|
||||
else val = mbbiD->val;
|
||||
|
@ -19,19 +19,20 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <mbbiRecord.h>
|
||||
#include <string.h>
|
||||
#include <mbbiRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
{
|
||||
mbbiRecord *mbbi = (mbbiRecord *) record;
|
||||
long val;
|
||||
unsigned long val;
|
||||
int i;
|
||||
|
||||
switch (format->type)
|
||||
{
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
{
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
|
@ -19,16 +19,16 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <mbboDirectRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
{
|
||||
mbboDirectRecord *mbboD = (mbboDirectRecord *) record;
|
||||
long val;
|
||||
unsigned long val;
|
||||
|
||||
if (format->type == DBF_LONG)
|
||||
if (format->type == DBF_ULONG || format->type == DBF_LONG)
|
||||
{
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
if (mbboD->mask)
|
||||
@ -53,7 +53,7 @@ static long writeData (dbCommon *record, format_t *format)
|
||||
mbboDirectRecord *mbboD = (mbboDirectRecord *) record;
|
||||
long val;
|
||||
|
||||
if (format->type == DBF_LONG)
|
||||
if (format->type == DBF_ULONG || format->type == DBF_LONG)
|
||||
{
|
||||
if (mbboD->mask) val = mbboD->rval & mbboD->mask;
|
||||
else val = mbboD->val;
|
||||
|
@ -19,19 +19,20 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <mbboRecord.h>
|
||||
#include <string.h>
|
||||
#include <mbboRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
{
|
||||
mbboRecord *mbbo = (mbboRecord *) record;
|
||||
long val;
|
||||
unsigned long val;
|
||||
int i;
|
||||
|
||||
switch (format->type)
|
||||
{
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
{
|
||||
if (streamScanf (record, format, &val)) return ERROR;
|
||||
@ -76,11 +77,12 @@ static long readData (dbCommon *record, format_t *format)
|
||||
static long writeData (dbCommon *record, format_t *format)
|
||||
{
|
||||
mbboRecord *mbbo = (mbboRecord *) record;
|
||||
long val;
|
||||
unsigned long val;
|
||||
int i;
|
||||
|
||||
switch (format->type)
|
||||
{
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
{
|
||||
/* print VAL or RVAL ? */
|
||||
|
@ -18,8 +18,8 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <stringinRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
|
@ -18,8 +18,8 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <stringoutRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
|
@ -18,10 +18,10 @@
|
||||
* *
|
||||
***************************************************************/
|
||||
|
||||
#include "devStream.h"
|
||||
#include <waveformRecord.h>
|
||||
#include <string.h>
|
||||
#include <errlog.h>
|
||||
#include <waveformRecord.h>
|
||||
#include "devStream.h"
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long readData (dbCommon *record, format_t *format)
|
||||
@ -57,6 +57,7 @@ static long readData (dbCommon *record, format_t *format)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DBF_ULONG:
|
||||
case DBF_LONG:
|
||||
case DBF_ENUM:
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ proc startioc {} {
|
||||
if [info exists asynversion] {
|
||||
puts $fd "require asyn,$asynversion"
|
||||
}
|
||||
puts $fd "require stream2,$streamversion"
|
||||
puts $fd "require stream,$streamversion"
|
||||
} else {
|
||||
puts $fd "#!../O.$env(EPICS_HOST_ARCH)/streamApp"
|
||||
puts $fd "dbLoadDatabase ../O.Common/streamApp.dbd"
|
||||
@ -77,7 +77,9 @@ proc startioc {} {
|
||||
}
|
||||
fconfigure $ioc -blocking yes -buffering none
|
||||
debugmsg "waiting to connect"
|
||||
set timer [after 1000 {puts stderr "\033\[31;7mCannot start IOC.\033\[0m"; exit 1}]
|
||||
vwait sock
|
||||
after cancel $timer
|
||||
}
|
||||
|
||||
set lastcommand ""
|
||||
|
@ -41,12 +41,10 @@ set protocol {
|
||||
set startup {
|
||||
}
|
||||
|
||||
set debug 0
|
||||
|
||||
startioc
|
||||
|
||||
set inf [format %f inf]
|
||||
set nan [format %f nan]
|
||||
if [catch {set nan [format %f nan]}] {set nan nan}
|
||||
|
||||
ioccmd {dbpf DZ:test1.PROC 1}
|
||||
send "3.14159265359\n"
|
||||
|
@ -50,7 +50,7 @@ set protocol {
|
||||
in {in "%{zero|one|two}bla"; out "%d";}
|
||||
out1 {out "%#{zero|one|two}bla";}
|
||||
in1 {in "%#{zero|one|two}bla"; out "%d";}
|
||||
out2 {out "%#{zero=-1|one|two=5}bla";}
|
||||
out2 {out "%#{zero=-1|one|two=5|default=?}bla";}
|
||||
in2 {in "%#{zero=-1|one|two=5}bla"; out "%d";}
|
||||
in3 {in "%{\x00|\r|}bla"; out "%d";}
|
||||
}
|
||||
@ -81,6 +81,8 @@ ioccmd {dbpf DZ:testout2 0}
|
||||
assure "onebla\n"
|
||||
ioccmd {dbpf DZ:testout2 5}
|
||||
assure "twobla\n"
|
||||
ioccmd {dbpf DZ:testout2 17}
|
||||
assure "defaultbla\n"
|
||||
|
||||
ioccmd {dbpf DZ:testin.PROC 1}
|
||||
send "zerobla\n"
|
||||
|
@ -68,15 +68,15 @@ ioccmd {dbpf DZ:lo 12345}
|
||||
assure "12345 12345 012345 3039 003039 11000000111001 11000000111001 111001 !!......!!!..! !!......!!!..!\n"
|
||||
ioccmd {dbpf DZ:lo -1}
|
||||
if {$tcl_platform(machine) == "x86_64"} {
|
||||
assure "-1 -1 -00001 ffffffffffffffff FFFFFFFFFFFFFFFF 1111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
||||
assure "-1 -1 -00001 ffffffffffffffff FFFFFF 11111111111111111111111111111111 11111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
||||
} else {
|
||||
assure "-1 -1 -00001 ffffffff FFFFFFFF 11111111111111111111111111111111 11111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
||||
assure "-1 -1 -00001 ffffffff FFFFFF 11111111111111111111111111111111 11111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
|
||||
}
|
||||
ioccmd {dbpf DZ:lo -1234}
|
||||
if {$tcl_platform(machine) == "x86_64"} {
|
||||
assure "-1234 -1234 -01234 fffffffffffffb2e FFFFFFFFFFFFFB2E 1111111111111111111111111111111111111111111111111111101100101110 1111111111111111111111111111111111111111111111111111101100101110 101110 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!..!.!!!. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!..!.!!!.\n"
|
||||
assure "-1234 -1234 -01234 fffffffffffffb2e FFFB2E 11111111111111111111101100101110 11111111111111111111101100101110 101110 !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!. !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!.\n"
|
||||
} else {
|
||||
assure "-1234 -1234 -01234 fffffb2e FFFFFB2E 11111111111111111111101100101110 11111111111111111111101100101110 101110 !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!. !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!.\n"
|
||||
assure "-1234 -1234 -01234 fffffb2e FFFB2E 11111111111111111111101100101110 11111111111111111111101100101110 101110 !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!. !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!.\n"
|
||||
}
|
||||
ioccmd {dbpf DZ:lo 255}
|
||||
assure "255 255 000255 ff 0000FF 11111111 11111111 111111 !!!!!!!! !!!!!!!!\n"
|
||||
|
@ -10,16 +10,19 @@ set records {
|
||||
record (ai, "DZ:test1")
|
||||
{
|
||||
field (DTYP, "stream")
|
||||
field (LINR, "LINEAR")
|
||||
field (INP, "@test.proto test1 device")
|
||||
}
|
||||
record (ai, "DZ:test2")
|
||||
{
|
||||
field (DTYP, "stream")
|
||||
field (LINR, "LINEAR")
|
||||
field (INP, "@test.proto test2 device")
|
||||
}
|
||||
record (ai, "DZ:test3")
|
||||
{
|
||||
field (DTYP, "stream")
|
||||
field (LINR, "LINEAR")
|
||||
field (INP, "@test.proto test3 device")
|
||||
}
|
||||
record (ai, "DZ:test4")
|
||||
@ -30,26 +33,31 @@ set records {
|
||||
record (ai, "DZ:test5")
|
||||
{
|
||||
field (DTYP, "stream")
|
||||
field (LINR, "LINEAR")
|
||||
field (INP, "@test.proto test5 device")
|
||||
}
|
||||
record (ai, "DZ:test6")
|
||||
{
|
||||
field (DTYP, "stream")
|
||||
field (LINR, "LINEAR")
|
||||
field (INP, "@test.proto test6 device")
|
||||
}
|
||||
record (ai, "DZ:test7")
|
||||
{
|
||||
field (DTYP, "stream")
|
||||
field (LINR, "LINEAR")
|
||||
field (INP, "@test.proto test7 device")
|
||||
}
|
||||
record (ai, "DZ:test8")
|
||||
{
|
||||
field (DTYP, "stream")
|
||||
field (LINR, "LINEAR")
|
||||
field (INP, "@test.proto test8 device")
|
||||
}
|
||||
record (ai, "DZ:test9")
|
||||
{
|
||||
field (DTYP, "stream")
|
||||
field (LINR, "LINEAR")
|
||||
field (INP, "@test.proto test9 device")
|
||||
}
|
||||
record (ai, "DZ:test10")
|
||||
|
@ -53,13 +53,22 @@ int main () {
|
||||
}
|
||||
EOF
|
||||
|
||||
g++ -I ../../src ../../src/O.$EPICS_HOST_ARCH/StreamBuffer.o test.cc -o test.exe
|
||||
|
||||
test.exe
|
||||
if [ $? != 0 ]
|
||||
if [ "$1" = "-sls" ]
|
||||
then
|
||||
echo -e "\033[31;7mTest failed.\033[0m"
|
||||
exit 1
|
||||
O=../../O.*_$EPICS_HOST_ARCH/StreamBuffer.o
|
||||
else
|
||||
O=../../src/O.$EPICS_HOST_ARCH/StreamBuffer.o
|
||||
fi
|
||||
|
||||
for o in $O
|
||||
do
|
||||
g++ -I ../../src $o test.cc -o test.exe
|
||||
test.exe
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo -e "\033[31;7mTest failed.\033[0m"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
rm test.*
|
||||
echo -e "\033[32mTest passed.\033[0m"
|
||||
|
Reference in New Issue
Block a user