Compare commits

..

12 Commits

36 changed files with 451 additions and 241 deletions

View File

@ -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>

View File

@ -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 &ge; 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>

View File

@ -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>

View File

@ -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>
&nbsp;&nbsp;field (INPA, "$(DEVICE):readcurrent.SEVR CP")<br>
&nbsp;&nbsp;field (CALC, "A!=2")<br>
&nbsp;&nbsp;field (CALC, "A#3")<br>
&nbsp;&nbsp;field (OOPT, "When Non-zero")<br>
&nbsp;&nbsp;field (OUT, "$(DEVICE):clean_2.PROC")<br>
}<br>

View File

@ -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) > $@

View File

@ -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::

View File

@ -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;

View File

@ -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;

View File

@ -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++];

View File

@ -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);

View File

@ -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());

View File

@ -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[];

View File

@ -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::

View File

@ -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",

View File

@ -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:
{

View File

@ -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:
{

View File

@ -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;

View File

@ -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;

View File

@ -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:
{

View File

@ -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:
{

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 ? */

View File

@ -18,8 +18,8 @@
* *
***************************************************************/
#include "devStream.h"
#include <stringinRecord.h>
#include "devStream.h"
#include <epicsExport.h>
static long readData (dbCommon *record, format_t *format)

View File

@ -18,8 +18,8 @@
* *
***************************************************************/
#include "devStream.h"
#include <stringoutRecord.h>
#include "devStream.h"
#include <epicsExport.h>
static long readData (dbCommon *record, format_t *format)

View File

@ -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:
{

View File

@ -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 ""

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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")

View File

@ -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"