Compare commits

...

34 Commits
2.8.0 ... 2.8.6

Author SHA1 Message Date
493dc19d8b fix problem with redirects to records that do not start with a letter or underscore 2018-11-14 15:26:33 +01:00
3b64242ffd Merge branch 'master' of github.com:paulscherrerinstitute/StreamDevice 2018-11-14 11:41:47 +01:00
280cb7765a Merge pull request #19 from shadowguy/master
EPICS R3.15.6 dev guide
2018-11-14 11:01:48 +01:00
835e68bd76 fix test: sign extension does not depend on 32 or 64 bit architecture any more 2018-10-10 11:47:42 +02:00
92903361d0 handle state alarms in mbbo update 2018-10-10 11:08:41 +02:00
fb937316aa fix bug in mbbo string readback 2018-10-10 11:06:58 +02:00
ae6ebc4106 mbbo changes: use SHFT and MASK even with VAL (if no xxVL defined or ENUM format) 2018-10-10 11:06:22 +02:00
0f0dd31a0d test build with epics 7 2018-10-10 10:01:18 +02:00
189e61bbe8 Prep for EPICS R3.15.6 release 2018-10-06 15:22:48 +02:00
d8f88c340a remove STREAM_PATCHLEVEL macro because I always forget to update it anyway 2018-09-27 16:21:46 +02:00
2ef5c47f19 fix rule to rebuild StreamVersion.o whenever any other object code changed 2018-09-27 16:05:35 +02:00
cb4d490fb6 added RELEASE variable for SynApps 2018-09-25 14:35:20 +02:00
da281ebf97 Merge branch 'master' of github.com:paulscherrerinstitute/StreamDevice 2018-09-19 16:42:12 +02:00
c832efbcb6 Merge pull request #17 from shadowguy/master
Updated more EPICS web links.  SynApps link was actually broken
2018-09-19 16:41:37 +02:00
b7b3bc0af0 Fix problem with \? at end of input format when no more input is available. Used to work. Works again (but was not really intended) 2018-09-19 16:36:01 +02:00
4a42c3d43a Web link fixes, updated 3.14.8 dev guide link to 3.14.12 2018-09-17 14:13:39 +02:00
624cc0134a Merge branch 'master' of github.com:paulscherrerinstitute/StreamDevice 2018-09-14 16:19:09 +02:00
d9d5d5f55d Merge pull request #16 from shadowguy/master
Typo
2018-09-14 16:18:07 +02:00
53ea75dc80 use macro instead of magic value 2018-09-12 09:48:55 +02:00
b1f4c2a7d9 improve debug message 2018-09-11 18:27:52 +02:00
d87e9cedd2 reset proc to 0 in case it had been 2 to trigger @init 2018-09-11 18:19:58 +02:00
32d93d9028 Merge pull request #15 from darcato/master
Fix typos
2018-09-11 15:10:06 +02:00
3d30827798 Typos on DFB_ULONG 2018-09-11 15:01:33 +02:00
b688f14c22 Merge pull request #14 from icshwi/master
minor modifications related delete and char size
2018-09-10 15:16:10 +02:00
9e972d3f33 Typo 2018-09-05 22:21:12 +02:00
f5da2ea6b3 Do not limit to 80 chars when the link can be 256 by @krisztianloki 2018-08-29 22:27:07 +02:00
4edd2f2eff Fixed new[] / delete mismatch by @krisztianloki 2018-08-29 22:08:23 +02:00
846b884eb5 fix (and simplify) reading strings into waveform, aai, aao, lsi, lso 2018-08-21 16:03:03 +02:00
3f1918ed2d Merge branch 'shadowguy-master' 2018-08-21 10:44:16 +02:00
1d753366d8 fix of the fix 2018-08-21 10:43:13 +02:00
047f18d113 Merge branch 'master' of https://github.com/shadowguy/StreamDevice into shadowguy-master 2018-08-21 09:21:49 +02:00
26c5b012a7 Start search for end parenthesis one character sooner to allow empty parentheses 2018-08-20 20:02:41 +02:00
4f33600a0f Minor typo 2018-08-20 19:07:31 +02:00
2077dfb0a6 Un-breaking EPICS links 2018-08-20 19:01:54 +02:00
22 changed files with 105 additions and 128 deletions

View File

@ -32,9 +32,8 @@ HEADERS += StreamError.h
StreamCore.o StreamCore.d: streamReferences StreamCore.o StreamCore.d: streamReferences
# Update version string (contains __DATE__ and __TIME__) # Update version string (contains __DATE__ and __TIME__)
# each time make runs. # each time anything changes.
StreamVersion.o: FORCE StreamVersion.o: $(filter-out StreamVersion.o stream_exportAddress.o,$(LIBOBJS))
FORCE:
streamReferences: streamReferences:
$(PERL) ../src/makeref.pl Interface $(BUSSES) > $@ $(PERL) ../src/makeref.pl Interface $(BUSSES) > $@

View File

@ -1,6 +1,6 @@
# StreamDevice # StreamDevice
_StreamDevice_ is a generic [EPICS](https://www.aps.anl.gov/epics) _StreamDevice_ is a generic [EPICS](https://epics.anl.gov/)
device support for devices with a "byte stream" based device support for devices with a "byte stream" based
communication interface. communication interface.
That means devices that can be controlled by sending and receiving That means devices that can be controlled by sending and receiving

View File

@ -14,14 +14,21 @@ TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
# define INSTALL_LOCATION_APP here # define INSTALL_LOCATION_APP here
#INSTALL_LOCATION_APP=<fullpathname> #INSTALL_LOCATION_APP=<fullpathname>
# For SynApps:
RELEASE=
EPICS_BASE=/usr/local/epics/base-3.16.1 EPICS_BASE=/usr/local/epics/base-7.0.1
ASYN=~/top-3.16/asyn4-30 ASYN=~/top-7/asyn4-33
CALC=~/top-3.16/SynApps/calc-2-8 CALC=~/top-7/SynApps/calc-2-8
PCRE=~/top-3.16/pcre-7-2 PCRE=~/top-7/pcre-7-2
PCRE_INCLUDE_SL6-x86=/usr/include
PCRE_INCLUDE_SL6-x86_64=/usr/include #EPICS_BASE=/usr/local/epics/base-3.16.1
PCRE_INCLUDE_SL6-x86_64-clang=/usr/include #ASYN=~/top-3.16/asyn4-30
#CALC=~/top-3.16/SynApps/calc-2-8
#PCRE=~/top-3.16/pcre-7-2
#PCRE_INCLUDE_SL6-x86=/usr/include
#PCRE_INCLUDE_SL6-x86_64=/usr/include
#PCRE_INCLUDE_SL6-x86_64-clang=/usr/include
#EPICS_BASE=/usr/local/epics/base-3.15.5 #EPICS_BASE=/usr/local/epics/base-3.15.5
#ASYN=~/top-3.15/asyn4-30 #ASYN=~/top-3.15/asyn4-30

View File

@ -53,7 +53,7 @@ RegisterConverter(MyConverter,"Q");
</pre> </pre>
<a name="theory"></a> <a name="theory"></a>
<h2>Theroy of Operation</h2> <h2>Theory of Operation</h2>
<a name="registration"></a> <a name="registration"></a>
<h3>Registration </h3> <h3>Registration </h3>

View File

@ -15,7 +15,7 @@
<h2>What is <em>StreamDevice</em>?</h2> <h2>What is <em>StreamDevice</em>?</h2>
<p> <p>
<em>StreamDevice</em> is a generic <em>StreamDevice</em> is a generic
<a href="https://www.aps.anl.gov/epics" target="ex">EPICS</a> <a href="https://epics.anl.gov/" target="ex">EPICS</a>
device support for devices with a "byte stream" based device support for devices with a "byte stream" based
communication interface. communication interface.
That means devices that can be controlled by sending and That means devices that can be controlled by sending and
@ -96,11 +96,11 @@ come in a predictible order to be parsable by <em>StreamDevice</em>.
<h2>Recommended Readings</h2> <h2>Recommended Readings</h2>
<p> <p>
IOC Application Developer's Guide: IOC Application Developer's Guide:
<a href="https://www.aps.anl.gov/epics/base/R3-14/12-docs/AppDevGuide" <a href="https://epics.anl.gov/base/R3-14/12-docs/AppDevGuide/"
target="ex">R3.14.12</a>, target="ex">R3.14.12</a>,
<a href="https://www.aps.anl.gov/epics/base/R3-16/1-docs/AppDevGuide" <a href="https://epics.anl.gov/base/R3-15/6-docs/AppDevGuide/AppDevGuide.html"
target="ex">R3.15.5</a>, target="ex">R3.15.5</a>,
<a href="https://www.aps.anl.gov/epics/base/R3-15/5-docs/AppDevGuide" <a href="https://epics.anl.gov/base/R3-16/1-docs/AppDevGuide/AppDevGuide.html"
target="ex">R3.16.1</a> target="ex">R3.16.1</a>
</p> </p>
<p> <p>

View File

@ -23,7 +23,7 @@ written or read value.
<dd> <dd>
Not allowed. Not allowed.
</dd> </dd>
<dt>LONG format (e.g. <code>%i</code>):</dt> <dt>LONG <span class=new>or ENUM</span> format (e.g. <code>%i</code>):</dt>
<dd> <dd>
<dl> <dl>
<dt>If any of <code>ZRVL</code> ... <code>FFVL</code> is set <dt>If any of <code>ZRVL</code> ... <code>FFVL</code> is set
@ -41,17 +41,12 @@ written or read value.
</dd> </dd>
<dt>If none of <code>ZRVL</code> ... <code>FFVL</code> is set <dt>If none of <code>ZRVL</code> ... <code>FFVL</code> is set
(all are <code>0</code>):</dt> (all are <code>0</code>):</dt>
<dd> <dd class=new>
<u>Output:</u> <code><i>x</i>=VAL</code><br> <u>Output:</u> <code><i>x</i>=(VAL&lt;&lt;SHFT)&amp;MASK</code><br>
<u>Input:</u> <code>VAL=<i>x</i></code><br> <u>Input:</u> <code>VAL=(RBV=(<i>x</i>&amp;MASK))&gt;&gt;SHFT</code><br>
</dd> </dd>
</dl> </dl>
</dd> </dd>
<dt>ENUM format (e.g. <code>%{</code>):</dt>
<dd>
<u>Output:</u> <code><i>x</i>=VAL</code><br>
<u>Input:</u> <code>VAL=<i>x</i></code><br>
</dd>
<dt>STRING format (e.g. <code>%s</code>):</dt> <dt>STRING format (e.g. <code>%s</code>):</dt>
<dd> <dd>
<u>Output:</u> Depending on <code>VAL</code>, one of <code>ZRST</code> <u>Output:</u> Depending on <code>VAL</code>, one of <code>ZRST</code>

View File

@ -16,7 +16,7 @@
<h2>1. Normal Processing</h2> <h2>1. Normal Processing</h2>
<p> <p>
<em>StreamDevice</em> is an asynchronous device support <em>StreamDevice</em> is an asynchronous device support
(see <a href="http://www.aps.anl.gov/epics/base/R3-14/8-docs/AppDevGuide.pdf" (see <a href="http://www.aps.anl.gov/epics/base/R3-14/12-docs/AppDevGuide.pdf"
target="ex">IOC Application Developer's Guide</a> chapter 12: target="ex">IOC Application Developer's Guide</a> chapter 12:
Device Support). Device Support).
Whenever the record is processed, the <a href="protocol.html">protocol</a> Whenever the record is processed, the <a href="protocol.html">protocol</a>

View File

@ -15,7 +15,7 @@
<p> <p>
<b>Note:</b> The scalcout record is part of the <i>calc</i> module of <b>Note:</b> The scalcout record is part of the <i>calc</i> module of
the <a target="ex" the <a target="ex"
href="http://www.aps.anl.gov/aod/bcda/synApps/index.php" href="https://www.aps.anl.gov/BCDA/synApps"
><em>synApps</em></a> package. ><em>synApps</em></a> package.
Device support for scalcout records is only available for <i>calc</i> Device support for scalcout records is only available for <i>calc</i>
module release 2-4 or higher. module release 2-4 or higher.

View File

@ -388,7 +388,7 @@ The <code>INP</code> or <code>OUT</code> link has the form
<code>"@<var>filename&nbsp;protocol</var>[(<var>arg1</var>,<var>arg2</var>,...)]&nbsp;</var>bus</var>&nbsp;[<var>address</var>&nbsp;[<var>parameters</var>]]"</code>. <code>"@<var>filename&nbsp;protocol</var>[(<var>arg1</var>,<var>arg2</var>,...)]&nbsp;</var>bus</var>&nbsp;[<var>address</var>&nbsp;[<var>parameters</var>]]"</code>.
</p> </p>
<p> <p>
(Elements in <code>[]</code> are optional. To not type the <code>[]</code>). (Elements in <code>[]</code> are optional. Do not type the <code>[]</code>).
</p> </p>
<p> <p>
Here, <code><var>filename</var></code> is the name of the protocol file and Here, <code><var>filename</var></code> is the name of the protocol file and

View File

@ -74,7 +74,7 @@ CPPFLAGS += -DUSE_TYPED_RSET
-include $(TOP)/configure/RULES -include $(TOP)/configure/RULES
# Update version string whenever something changes # Update version string whenever something changes
StreamVersion$(OBJ): ../*.c ../*.h ../*.cc ../CONFIG_STREAM StreamVersion$(OBJ): $(filter-out StreamVersion.o,$(LIBOBJS)$(LIBRARY_OBJS))
# Add references to all registrars to main file to avoid # Add references to all registrars to main file to avoid
# missing initialization. # missing initialization.

View File

@ -73,7 +73,7 @@ public:
{init(NULL, size);} {init(NULL, size);}
~StreamBuffer() ~StreamBuffer()
{if (buffer != local) delete buffer;} {if (buffer != local) delete [] buffer;}
// operator (): get char* pointing to index // operator (): get char* pointing to index
const char* operator()(ssize_t index=0) const const char* operator()(ssize_t index=0) const

View File

@ -1315,12 +1315,12 @@ normal_format:
break; break;
} }
case StreamProtocolParser::skip: case StreamProtocolParser::skip:
// ignore next input byte // ignore next input byte (if exists)
consumedInput++; if (consumedInput < inputLine.length()) consumedInput++;
break; break;
case StreamProtocolParser::whitespace: case StreamProtocolParser::whitespace:
// any number of whitespace (including 0) // any number of whitespace (including 0)
while (isspace(inputLine[consumedInput])) consumedInput++; while (consumedInput < inputLine.length() && isspace(inputLine[consumedInput])) consumedInput++;
break; break;
case esc: case esc:
// escaped literal byte // escaped literal byte

View File

@ -534,11 +534,11 @@ long streamInitRecord(dbCommon* record, const struct link *ioLink,
streamIoFunction readData, streamIoFunction writeData) streamIoFunction readData, streamIoFunction writeData)
{ {
long status; long status;
char filename[80]; char filename[256];
char protocol[80]; char protocol[256];
char busname[80]; char busname[256];
int addr = -1; int addr = -1;
char busparam[80]; char busparam[256];
memset(busparam, 0 ,sizeof(busparam)); memset(busparam, 0 ,sizeof(busparam));
debug("streamInitRecord(%s): SEVR=%d\n", record->name, record->sevr); debug("streamInitRecord(%s): SEVR=%d\n", record->name, record->sevr);
@ -720,7 +720,7 @@ parseLink(const struct link *ioLink, char* filename,
if (0 >= sscanf(ioLink->value.instio.string+n1, " %[^ \t(] %n", protocol, &n2)) if (0 >= sscanf(ioLink->value.instio.string+n1, " %[^ \t(] %n", protocol, &n2))
{ {
error("%s: Missing protocol name\n" error("%s: Missing protocol name\n"
" expect \"@file protocol[(args)] bus [addr] [params]\"\n" " expect \"@file protocol[(arg1,...)] bus [addr] [params]\"\n"
" in \"@%s\"\n", name(), " in \"@%s\"\n", name(),
ioLink->value.instio.string); ioLink->value.instio.string);
return S_dev_badInitRet; return S_dev_badInitRet;
@ -728,15 +728,14 @@ parseLink(const struct link *ioLink, char* filename,
n1+=n2; n1+=n2;
if (ioLink->value.instio.string[n1] == '(') if (ioLink->value.instio.string[n1] == '(')
{ {
strcat(protocol, "("); n2 = 0;
n1++;
sscanf(ioLink->value.instio.string+n1, " %[^)] %n", protocol+strlen(protocol), &n2); sscanf(ioLink->value.instio.string+n1, " %[^)] %n", protocol+strlen(protocol), &n2);
n1+=n2; n1+=n2;
if (ioLink->value.instio.string[n1++] != ')') if (ioLink->value.instio.string[n1++] != ')')
{ {
error("%s: Missing ')' after protocol '%s': '%s'\n" error("%s: Missing ')' after protocol arguments '%s'\n"
" expect \"@file protocol(args) bus [addr] [params]\"\n" " expect \"@file protocol(arg1,...) bus [addr] [params]\"\n"
" in \"@%s\"\n", name(), protocol, ioLink->value.instio.string+n1-1, " in \"@%s\"\n", name(), protocol,
ioLink->value.instio.string); ioLink->value.instio.string);
return S_dev_badInitRet; return S_dev_badInitRet;
} }
@ -745,7 +744,7 @@ parseLink(const struct link *ioLink, char* filename,
if (0 >= sscanf(ioLink->value.instio.string+n1, "%s %i %99c", busname, addr, busparam)) if (0 >= sscanf(ioLink->value.instio.string+n1, "%s %i %99c", busname, addr, busparam))
{ {
error("%s: Missing bus name\n" error("%s: Missing bus name\n"
" expect \"@file protocol[(args)] bus [addr] [params]\"\n" " expect \"@file protocol[(arg1,...)] bus [addr] [params]\"\n"
" in \"@%s\"\n", name(), " in \"@%s\"\n", name(),
ioLink->value.instio.string); ioLink->value.instio.string);
return S_dev_badInitRet; return S_dev_badInitRet;
@ -832,7 +831,7 @@ initRecord(const char* filename, const char* protocol,
return ERROR; return ERROR;
} }
debug("Stream::initRecord %s: initialized. %s\n", debug("Stream::initRecord %s: initialized. %s\n",
name(), convert==2 ? name(), convert == DO_NOT_CONVERT ?
"convert" : "don't convert"); "convert" : "don't convert");
return convert; return convert;
} }
@ -844,6 +843,7 @@ process()
debug("Stream::process(%s)\n", name()); debug("Stream::process(%s)\n", name());
if (record->pact || record->scan == SCAN_IO_EVENT) if (record->pact || record->scan == SCAN_IO_EVENT)
{ {
record->proc = 0;
if (status != NO_ALARM) if (status != NO_ALARM)
{ {
debug("Stream::process(%s) error status=%s (%d)\n", debug("Stream::process(%s) error status=%s (%d)\n",
@ -855,7 +855,7 @@ process()
return false; return false;
} }
debug("Stream::process(%s) ready. %s\n", debug("Stream::process(%s) ready. %s\n",
name(), convert==2 ? name(), convert == DO_NOT_CONVERT ?
"convert" : "don't convert"); "convert" : "don't convert");
return true; return true;
} }
@ -869,11 +869,15 @@ process()
debug("Stream::process(%s) start\n", name()); debug("Stream::process(%s) start\n", name());
status = NO_ALARM; status = NO_ALARM;
convert = OK; convert = OK;
if (!startProtocol(record->proc==2 ? StreamCore::StartInit : StreamCore::StartNormal)) if (!startProtocol(record->proc == 2 ? StreamCore::StartInit : StreamCore::StartNormal))
{ {
debug("Stream::process(%s): could not start %sprotocol, status=%d\n", debug("Stream::process(%s): could not start %sprotocol, status=%s (%d)\n",
name(), record->proc==2 ? "@init " : "", status); name(), record->proc == 2 ? "@init " : "",
status >= 0 && status < ALARM_NSTATUS ?
epicsAlarmConditionStrings[status] : "ERROR",
status);
(void) recGblSetSevr(record, status ? status : UDF_ALARM, INVALID_ALARM); (void) recGblSetSevr(record, status ? status : UDF_ALARM, INVALID_ALARM);
record->proc = 0;
return false; return false;
} }
debug("Stream::process(%s): protocol started\n", name()); debug("Stream::process(%s): protocol started\n", name());
@ -921,7 +925,7 @@ scan(format_t *format, void* value, size_t maxStringSize)
currentValueLength = scanValue(*format->priv, *(double*)value); currentValueLength = scanValue(*format->priv, *(double*)value);
break; break;
case DBF_STRING: case DBF_STRING:
currentValueLength = scanValue(*format->priv, (char*)value, size); currentValueLength = scanValue(*format->priv, (char*)value, size);
break; break;
default: default:
error("INTERNAL ERROR (%s): Illegal format type %d\n", error("INTERNAL ERROR (%s): Illegal format type %d\n",
@ -1084,7 +1088,7 @@ getFieldAddress(const char* fieldname, StreamBuffer& address)
// FIELD in this record or VAL in other record // FIELD in this record or VAL in other record
StreamBuffer fullname; StreamBuffer fullname;
fullname.print("%s.%s", name(), fieldname); fullname.print("%s.%s", name(), fieldname);
if (dbNameToAddr(fullname(), &dbaddr) != OK) if (dbNameToAddr(fullname(), &dbaddr) != OK || strcmp(((dbFldDes*)dbaddr.pfldDes)->name, fieldname) != 0)
{ {
// VAL in other record // VAL in other record
fullname.clear().print("%s.VAL", fieldname); fullname.clear().print("%s.VAL", fieldname);

View File

@ -32,7 +32,6 @@ extern "C" {
#define STREAM_MAJOR 2 #define STREAM_MAJOR 2
#define STREAM_MINOR 8 #define STREAM_MINOR 8
#define STREAM_PATCHLEVEL 0
#ifndef OK #ifndef OK
#define OK 0 #define OK 0

View File

@ -116,17 +116,11 @@ static long readData(dbCommon *record, format_t *format)
if ((length = streamScanfN(record, format, if ((length = streamScanfN(record, format,
(char *)aai->bptr, aai->nelm)) == ERROR) (char *)aai->bptr, aai->nelm)) == ERROR)
{ {
memset(aai->bptr, 0, aai->nelm);
return ERROR; return ERROR;
} }
if (lval < (ssize_t)aai->nelm) if (length < (ssize_t)aai->nelm)
{ {
memset(((char*)aai->bptr)+lval , 0, aai->nelm-lval); ((char*)aai->bptr)[length] = 0;
lval++;
}
else
{
((char*)aai->bptr)[aai->nelm-1] = 0;
} }
aai->nord = (long)length; aai->nord = (long)length;
return OK; return OK;

View File

@ -108,22 +108,16 @@ static long readData(dbCommon *record, format_t *format)
case DBF_CHAR: case DBF_CHAR:
case DBF_UCHAR: case DBF_UCHAR:
{ {
ssize_t length; ssize_t length;
aao->nord = 0; aao->nord = 0;
if ((length = streamScanfN(record, format, if ((length = streamScanfN(record, format,
(char *)aao->bptr, aao->nelm)) == ERROR) (char *)aao->bptr, aao->nelm)) == ERROR)
{ {
memset(aao->bptr, 0, aao->nelm);
return ERROR; return ERROR;
} }
if (length < (ssize_t)aao->nelm) if (length < (ssize_t)aao->nelm)
{ {
memset(((char*)aao->bptr)+lval , 0, aao->nelm-lval); ((char*)aao->bptr)[length] = 0;
lval++;
}
else
{
((char*)aao->bptr)[aao->nelm-1] = 0;
} }
aao->nord = (long)length; aao->nord = (long)length;
goto end_no_check; goto end_no_check;

View File

@ -23,30 +23,27 @@
static long readData(dbCommon *record, format_t *format) static long readData(dbCommon *record, format_t *format)
{ {
lsiRecord *lsi = (lsiRecord *)record; lsiRecord *lsi = (lsiRecord *)record;
ssize_t length;
if (format->type == DBF_STRING) if (format->type != DBF_STRING) return ERROR;
if ((length = streamScanfN(record, format, lsi->val, (long)lsi->sizv)) == ERROR)
{ {
long len; return ERROR;
if ((len = streamScanfN(record, format, lsi->val, lsi->sizv) == ERROR))
{
lsi->len = 0;
return ERROR;
}
lsi->len = len;
return OK;
} }
return ERROR; if (length < (ssize_t)lsi->sizv)
{
lsi->val[length] = 0;
}
lsi->len = length;
return OK;
} }
static long writeData(dbCommon *record, format_t *format) static long writeData(dbCommon *record, format_t *format)
{ {
lsiRecord *lsi = (lsiRecord *)record; lsiRecord *lsi = (lsiRecord *)record;
if (format->type == DBF_STRING) if (format->type != DBF_STRING) return ERROR;
{ return streamPrintf(record, format, lsi->val);
return streamPrintf(record, format, lsi->val);
}
return ERROR;
} }
static long initRecord(dbCommon *record) static long initRecord(dbCommon *record)

View File

@ -24,17 +24,19 @@
static long readData(dbCommon *record, format_t *format) static long readData(dbCommon *record, format_t *format)
{ {
lsoRecord *lso = (lsoRecord *)record; lsoRecord *lso = (lsoRecord *)record;
long len; ssize_t length;
unsigned short monitor_mask; unsigned short monitor_mask;
if (format->type != DBF_STRING) if (format->type != DBF_STRING) return ERROR;
return ERROR; if ((length = streamScanfN(record, format, lso->val, lso->sizv)) == ERROR)
if ((len = streamScanfN(record, format, lso->val, lso->sizv) == ERROR))
{ {
lso->len = 0;
return ERROR; return ERROR;
} }
lso->len = len; if (length < (ssize_t)lso->sizv)
{
lso->val[length] = 0;
}
lso->len = length;
if (record->pact) return OK; if (record->pact) return OK;
/* In @init handler, no processing, enforce monitor updates. */ /* In @init handler, no processing, enforce monitor updates. */
monitor_mask = recGblResetAlarms(record); monitor_mask = recGblResetAlarms(record);
@ -60,11 +62,8 @@ static long writeData(dbCommon *record, format_t *format)
{ {
lsoRecord *lso = (lsoRecord *)record; lsoRecord *lso = (lsoRecord *)record;
if (format->type == DBF_STRING) if (format->type != DBF_STRING) return ERROR;
{ return streamPrintf(record, format, lso->val);
return streamPrintf(record, format, lso->val);
}
return ERROR;
} }
static long initRecord(dbCommon *record) static long initRecord(dbCommon *record)

View File

@ -33,11 +33,12 @@ static long readData(dbCommon *record, format_t *format)
{ {
case DBF_ULONG: case DBF_ULONG:
case DBF_LONG: case DBF_LONG:
case DBF_ENUM:
{ {
if (streamScanf(record, format, &val) == ERROR) return ERROR; if (streamScanf(record, format, &val) == ERROR) return ERROR;
if (mbbo->mask) val &= mbbo->mask;
mbbo->rbv = val; mbbo->rbv = val;
mbbo->rval = val; mbbo->rval = val;
if (mbbo->mask) val &= mbbo->mask;
if (mbbo->shft > 0) val >>= mbbo->shft; if (mbbo->shft > 0) val >>= mbbo->shft;
/* read VAL or RBV? Look if any value is defined */ /* read VAL or RBV? Look if any value is defined */
if (mbbo->sdef) if (mbbo->sdef)
@ -56,17 +57,12 @@ static long readData(dbCommon *record, format_t *format)
mbbo->val = (epicsEnum16)val; mbbo->val = (epicsEnum16)val;
break; break;
} }
case DBF_ENUM:
{
if (streamScanf(record, format, &val) == ERROR) return ERROR;
mbbo->val = (epicsEnum16)val;
break;
}
case DBF_STRING: case DBF_STRING:
{ {
char buffer[sizeof(mbbo->zrst)]; char buffer[sizeof(mbbo->zrst)];
if (streamScanfN(record, format, buffer, sizeof(buffer)) == ERROR) if (streamScanfN(record, format, buffer, sizeof(buffer)) == ERROR)
return ERROR; return ERROR;
mbbo->val = 65535; /* initalize to unknown state*/
for (val = 0; val < 16; val++) for (val = 0; val < 16; val++)
{ {
if (strcmp ((&mbbo->zrst)[val], buffer) == 0) if (strcmp ((&mbbo->zrst)[val], buffer) == 0)
@ -75,6 +71,7 @@ static long readData(dbCommon *record, format_t *format)
break; break;
} }
} }
break;
} }
default: default:
return ERROR; return ERROR;
@ -82,12 +79,21 @@ static long readData(dbCommon *record, format_t *format)
if (record->pact) return DO_NOT_CONVERT; if (record->pact) return DO_NOT_CONVERT;
/* In @init handler, no processing, enforce monitor updates. */ /* In @init handler, no processing, enforce monitor updates. */
monitor_mask = recGblResetAlarms(record); monitor_mask = recGblResetAlarms(record);
if (mbbo->val > 15) {
recGblSetSevr(record, STATE_ALARM, mbbo->unsv);
} else {
recGblSetSevr(record, STATE_ALARM, (&(mbbo->zrsv))[mbbo->val]);
}
mbbo->lalm = mbbo->val;
if (mbbo->val != mbbo->lalm) {
if (!recGblSetSevr(record, COS_ALARM, mbbo->cosv)) mbbo->lalm = mbbo->val;
}
if (mbbo->mlst != mbbo->val) if (mbbo->mlst != mbbo->val)
{ {
monitor_mask |= (DBE_VALUE | DBE_LOG); monitor_mask |= (DBE_VALUE | DBE_LOG);
mbbo->mlst = mbbo->val; mbbo->mlst = mbbo->val;
} }
if (monitor_mask){ if (monitor_mask) {
db_post_events(record, &mbbo->val, monitor_mask); db_post_events(record, &mbbo->val, monitor_mask);
} }
if (mbbo->oraw != mbbo->rval) { if (mbbo->oraw != mbbo->rval) {
@ -110,39 +116,38 @@ static long writeData(dbCommon *record, format_t *format)
switch (format->type) switch (format->type)
{ {
case DBF_ULONG: case DBF_ULONG:
case DBF_ENUM:
/* print VAL or RVAL ? */ /* print VAL or RVAL ? */
val = mbbo->val; val = mbbo->val;
if (mbbo->shft > 0) val <<= mbbo->shft;
if (mbbo->sdef) for (i=0; i<16; i++) if (mbbo->sdef) for (i=0; i<16; i++)
{ {
if ((&mbbo->zrvl)[i]) if ((&mbbo->zrvl)[i])
{ {
/* any values defined ? */ /* any values defined ? */
val = mbbo->rval; val = mbbo->rval;
if (mbbo->mask) val &= mbbo->mask;
break; break;
} }
} }
if (mbbo->mask) val &= mbbo->mask;
return streamPrintf(record, format, val); return streamPrintf(record, format, val);
case DBF_LONG: case DBF_LONG:
{ {
/* print VAL or RVAL ? */ /* print VAL or RVAL ? */
val = (epicsInt16)mbbo->val; val = (epicsInt16)mbbo->val;
if (mbbo->shft > 0) val <<= mbbo->shft;
if (mbbo->sdef) for (i=0; i<16; i++) if (mbbo->sdef) for (i=0; i<16; i++)
{ {
if ((&mbbo->zrvl)[i]) if ((&mbbo->zrvl)[i])
{ {
/* any values defined ? */ /* any values defined ? */
val = (epicsInt32)mbbo->rval; val = (epicsInt32)mbbo->rval;
if (mbbo->mask) val &= mbbo->mask;
break; break;
} }
} }
if (mbbo->mask) val &= mbbo->mask;
return streamPrintf(record, format, val); return streamPrintf(record, format, val);
} }
case DBF_ENUM:
{
return streamPrintf(record, format, mbbo->val);
}
case DBF_STRING: case DBF_STRING:
{ {
if (mbbo->val >= 16) return ERROR; if (mbbo->val >= 16) return ERROR;

View File

@ -42,7 +42,7 @@ static long readData(dbCommon *record, format_t *format)
return OK; return OK;
} }
case DBF_LONG: case DBF_LONG:
case DBF_UONG: case DBF_ULONG:
case DBF_ENUM: case DBF_ENUM:
{ {
long lval; long lval;
@ -72,7 +72,7 @@ static long writeData(dbCommon *record, format_t *format)
return streamPrintf(record, format, sco->oval); return streamPrintf(record, format, sco->oval);
} }
case DBF_LONG: case DBF_LONG:
case DBF_UONG: case DBF_ULONG:
case DBF_ENUM: case DBF_ENUM:
{ {
return streamPrintf(record, format, (long)sco->oval); return streamPrintf(record, format, (long)sco->oval);

View File

@ -117,21 +117,15 @@ static long readData(dbCommon *record, format_t *format)
if ((length = streamScanfN(record, format, if ((length = streamScanfN(record, format,
(char *)wf->bptr, wf->nelm)) == ERROR) (char *)wf->bptr, wf->nelm)) == ERROR)
{ {
memset(wf->bptr, 0, wf->nelm);
return ERROR; return ERROR;
} }
if (length < (ssize_t)wf->nelm) if (length < (ssize_t)wf->nelm)
{ {
memset(((char*)wf->bptr)+lval , 0, wf->nelm-lval); ((char*)wf->bptr)[length] = 0;
lval++;
}
else
{
((char*)wf->bptr)[wf->nelm-1] = 0;
} }
wf->nord = (long)length; wf->nord = (long)length;
return OK; return OK;
} }
default: default:
errlogSevPrintf(errlogFatal, errlogSevPrintf(errlogFatal,
"readData %s: can't convert from string to %s\n", "readData %s: can't convert from string to %s\n",

View File

@ -54,8 +54,6 @@ set debug 0
startioc startioc
# Some formats give different results on 32 bit and 64 bit machines. # Some formats give different results on 32 bit and 64 bit machines.
# This occurs when printing negative numbers with unsigned formats.
# This is normal. E.g. -1 HAS a different number of 1 bits.
# Specify the width field in the format if this is a problem. # Specify the width field in the format if this is a problem.
put DZ:percent 1 put DZ:percent 1
@ -75,17 +73,9 @@ assure "12345 12345 012345 3039 003039 11000000111001 11000000111001 111001 !!..
put DZ:lo 2147483647 put DZ:lo 2147483647
assure "2147483647 2147483647 2147483647 7fffffff FFFFFF 1111111111111111111111111111111 1111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" assure "2147483647 2147483647 2147483647 7fffffff FFFFFF 1111111111111111111111111111111 1111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
put DZ:lo -1 put DZ:lo -1
if {$tcl_platform(machine) == "x86_64"} {
assure "-1 -1 -00001 ffffffffffffffff FFFFFF 1111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
} else {
assure "-1 -1 -00001 ffffffff FFFFFF 11111111111111111111111111111111 11111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" assure "-1 -1 -00001 ffffffff FFFFFF 11111111111111111111111111111111 11111111111111111111111111111111 111111 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
}
put DZ:lo -1234 put DZ:lo -1234
if {$tcl_platform(machine) == "x86_64"} {
assure "-1234 -1234 -01234 fffffffffffffb2e FFFB2E 1111111111111111111111111111111111111111111111111111101100101110 1111111111111111111111111111111111111111111111111111101100101110 101110 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!..!.!!!. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!..!.!!!.\n"
} else {
assure "-1234 -1234 -01234 fffffb2e FFFB2E 11111111111111111111101100101110 11111111111111111111101100101110 101110 !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!. !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!.\n" assure "-1234 -1234 -01234 fffffb2e FFFB2E 11111111111111111111101100101110 11111111111111111111101100101110 101110 !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!. !!!!!!!!!!!!!!!!!!!!!.!!..!.!!!.\n"
}
put DZ:lo 255 put DZ:lo 255
assure "255 255 000255 ff 0000FF 11111111 11111111 111111 !!!!!!!! !!!!!!!!\n" assure "255 255 000255 ff 0000FF 11111111 11111111 111111 !!!!!!!! !!!!!!!!\n"
put DZ:lo 65535 put DZ:lo 65535