Compare commits
7 Commits
stream_2_5
...
stream_2_5
Author | SHA1 | Date | |
---|---|---|---|
74d950ab2d | |||
9049baf730 | |||
050a165a82 | |||
1428b85a34 | |||
e4f8a6ed40 | |||
5a5b42cb67 | |||
e62553eca6 |
@ -739,38 +739,44 @@ readHandler()
|
||||
streameos = getInTerminator(streameoslen);
|
||||
deveos = streameos;
|
||||
deveoslen = streameoslen;
|
||||
if (streameos) do // streameos == NULL means: don't change eos
|
||||
if (streameos) // streameos == NULL means: don't change eos
|
||||
{
|
||||
asynStatus status;
|
||||
status = pasynOctet->getInputEos(pvtOctet,
|
||||
pasynUser, oldeos, sizeof(oldeos)-1, &oldeoslen);
|
||||
if (status != asynSuccess)
|
||||
{
|
||||
oldeoslen = -1;
|
||||
// No EOS support?
|
||||
}
|
||||
// device (e.g. GPIB) might not accept full eos length
|
||||
if (pasynOctet->setInputEos(pvtOctet, pasynUser,
|
||||
deveos, deveoslen) == asynSuccess)
|
||||
{
|
||||
#ifndef NO_TEMPORARY
|
||||
if (ioAction != AsyncRead)
|
||||
if (streameos[0])
|
||||
{
|
||||
debug("AsynDriverInterface::readHandler(%s) "
|
||||
"input EOS set to %s\n",
|
||||
clientName(),
|
||||
StreamBuffer(deveos, deveoslen).expand()());
|
||||
error("%s: warning: No input EOS support.\n",
|
||||
clientName());
|
||||
}
|
||||
oldeoslen = -1;
|
||||
} else do {
|
||||
// device (e.g. GPIB) might not accept full eos length
|
||||
if (pasynOctet->setInputEos(pvtOctet, pasynUser,
|
||||
deveos, deveoslen) == asynSuccess)
|
||||
{
|
||||
#ifndef NO_TEMPORARY
|
||||
if (ioAction != AsyncRead)
|
||||
{
|
||||
debug("AsynDriverInterface::readHandler(%s) "
|
||||
"input EOS set to %s\n",
|
||||
clientName(),
|
||||
StreamBuffer(deveos, deveoslen).expand()());
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
deveos++; deveoslen--;
|
||||
if (!deveoslen)
|
||||
{
|
||||
error("%s: warning: pasynOctet->setInputEos() failed: %s\n",
|
||||
clientName(), pasynUser->errorMessage);
|
||||
}
|
||||
} while (deveoslen);
|
||||
break;
|
||||
}
|
||||
deveos++; deveoslen--;
|
||||
if (!deveoslen)
|
||||
{
|
||||
error("%s: warning: pasynOctet->setInputEos() failed: %s\n",
|
||||
clientName(), pasynUser->errorMessage);
|
||||
}
|
||||
} while (deveoslen);
|
||||
}
|
||||
|
||||
int bytesToRead = peeksize;
|
||||
long buffersize;
|
||||
|
@ -650,9 +650,12 @@ formatOutput()
|
||||
unsigned short addrlen = extract<unsigned short>(commandIndex);
|
||||
fieldAddress.set(commandIndex, addrlen);
|
||||
commandIndex += addrlen;
|
||||
goto normal_format;
|
||||
}
|
||||
case StreamProtocolParser::format:
|
||||
{
|
||||
fieldAddress.clear();
|
||||
normal_format:
|
||||
// code layout:
|
||||
// formatstring <eos> StreamFormat [info]
|
||||
formatstring = commandIndex;
|
||||
@ -696,7 +699,6 @@ formatOutput()
|
||||
name(), formatstr.expand()());
|
||||
return false;
|
||||
}
|
||||
fieldAddress.clear();
|
||||
continue;
|
||||
}
|
||||
case StreamProtocolParser::whitespace:
|
||||
@ -1169,9 +1171,12 @@ matchInput()
|
||||
unsigned short addrlen = extract<unsigned short>(commandIndex);
|
||||
fieldAddress.set(commandIndex, addrlen);
|
||||
commandIndex += addrlen;
|
||||
goto normal_format;
|
||||
}
|
||||
case StreamProtocolParser::format:
|
||||
{
|
||||
fieldAddress.clear();
|
||||
normal_format:
|
||||
int consumed;
|
||||
// code layout:
|
||||
// formatstring <eos> StreamFormat [info]
|
||||
@ -1310,7 +1315,6 @@ matchInput()
|
||||
return false;
|
||||
}
|
||||
// matchValue() has already removed consumed bytes from inputBuffer
|
||||
fieldAddress.clear();
|
||||
break;
|
||||
}
|
||||
case StreamProtocolParser::skip:
|
||||
@ -1332,12 +1336,12 @@ matchInput()
|
||||
while (commandIndex[i] >= ' ') i++;
|
||||
if (!(flags & AsyncMode) && onMismatch[0] != in_cmd)
|
||||
{
|
||||
error("%s: Input \"%s%s\" too short.",
|
||||
error("%s: Input \"%s%s\" too short.\n",
|
||||
name(),
|
||||
inputLine.length() > 20 ? "..." : "",
|
||||
inputLine.expand(-20)());
|
||||
#ifndef NO_TEMPORARY
|
||||
error(" No match for \"%s\"\n",
|
||||
error("No match for \"%s\"\n",
|
||||
StreamBuffer(commandIndex-1,i+1).expand()());
|
||||
#endif
|
||||
}
|
||||
|
@ -1053,30 +1053,43 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
buffer = fieldBuffer.clear().reserve(size);
|
||||
for (nord = 0; nord < nelem; nord++)
|
||||
{
|
||||
debug("Stream::matchValue(%s): buffer before: %s\n", name(), fieldBuffer.expand()());
|
||||
switch (format.type)
|
||||
{
|
||||
case long_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);
|
||||
break;
|
||||
}
|
||||
case enum_format:
|
||||
{
|
||||
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);
|
||||
break;
|
||||
}
|
||||
case double_format:
|
||||
{
|
||||
consumed = scanValue(format, dval);
|
||||
if (consumed >= 0) ((epicsFloat64*)buffer)[nord] = dval;
|
||||
// Direct assignment to buffer fails fith gcc 3.4.3 for xscale_be
|
||||
// Optimization bug?
|
||||
epicsFloat64 f64=dval;
|
||||
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,
|
||||
((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);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1084,6 +1097,7 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
"Illegal format type\n", name());
|
||||
return false;
|
||||
}
|
||||
debug("Stream::matchValue(%s): buffer after: %s\n", name(), fieldBuffer.expand()());
|
||||
if (consumed < 0) break;
|
||||
consumedInput += consumed;
|
||||
}
|
||||
@ -1127,12 +1141,13 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
{
|
||||
// write into own record, thus don't process it
|
||||
// in @init we must not process other record
|
||||
debug("Stream::matchValue(%s): dbPut(%s.%s,...)\n",
|
||||
debug("Stream::matchValue(%s): dbPut(%s.%s,%s)\n",
|
||||
name(),
|
||||
pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name);
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
fieldBuffer.expand()());
|
||||
putfunc = "dbPut";
|
||||
status = dbPut(pdbaddr, dbfMapping[format.type], fieldBuffer(), nord);
|
||||
status = dbPut(pdbaddr, dbfMapping[format.type], buffer, nord);
|
||||
if (INIT_RUN && pdbaddr->precord != record)
|
||||
{
|
||||
// clean error status of other record in @init
|
||||
@ -1144,12 +1159,13 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
||||
else
|
||||
{
|
||||
// write into other record, thus process it
|
||||
debug("Stream::matchValue(%s): dbPutField(%s.%s,...)\n",
|
||||
debug("Stream::matchValue(%s): dbPutField(%s.%s,%s)\n",
|
||||
name(),
|
||||
pdbaddr->precord->name,
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name);
|
||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||
fieldBuffer.expand()());
|
||||
putfunc = "dbPutField";
|
||||
status = dbPutField(pdbaddr, dbfMapping[format.type], fieldBuffer(), nord);
|
||||
status = dbPutField(pdbaddr, dbfMapping[format.type], buffer, nord);
|
||||
}
|
||||
if (status != 0)
|
||||
{
|
||||
|
@ -227,7 +227,7 @@ getProtocol(const StreamBuffer& protocolAndParams)
|
||||
return new Protocol(*protocol, name, 0);
|
||||
}
|
||||
error("Protocol '%s' not found in protocol file '%s'\n",
|
||||
name(), filename());
|
||||
protocolAndParams(), filename());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
19
stream.dbd
Normal file
19
stream.dbd
Normal file
@ -0,0 +1,19 @@
|
||||
device(aai,INST_IO,devaaiStream,"stream")
|
||||
device(aao,INST_IO,devaaoStream,"stream")
|
||||
device(ao,INST_IO,devaoStream,"stream")
|
||||
device(ai,INST_IO,devaiStream,"stream")
|
||||
device(bo,INST_IO,devboStream,"stream")
|
||||
device(bi,INST_IO,devbiStream,"stream")
|
||||
device(mbbo,INST_IO,devmbboStream,"stream")
|
||||
device(mbbi,INST_IO,devmbbiStream,"stream")
|
||||
device(mbboDirect,INST_IO,devmbboDirectStream,"stream")
|
||||
device(mbbiDirect,INST_IO,devmbbiDirectStream,"stream")
|
||||
device(longout,INST_IO,devlongoutStream,"stream")
|
||||
device(longin,INST_IO,devlonginStream,"stream")
|
||||
device(stringout,INST_IO,devstringoutStream,"stream")
|
||||
device(stringin,INST_IO,devstringinStream,"stream")
|
||||
device(waveform,INST_IO,devwaveformStream,"stream")
|
||||
device(calcout,INST_IO,devcalcoutStream,"stream")
|
||||
driver(stream)
|
||||
variable(streamDebug, int)
|
||||
registrar(streamRegistrar)
|
@ -12,10 +12,26 @@ set records {
|
||||
field (DTYP, "stream")
|
||||
field (OUT, "@test.proto test1 device")
|
||||
}
|
||||
record (longin, "DZ:test2")
|
||||
{
|
||||
field (DTYP, "stream")
|
||||
field (INP, "@test.proto test2 device")
|
||||
}
|
||||
record (longin, "DZ:test3")
|
||||
{
|
||||
field (DTYP, "stream")
|
||||
field (INP, "@test.proto test3 device")
|
||||
}
|
||||
record (longin, "DZ:test4")
|
||||
{
|
||||
field (DTYP, "stream")
|
||||
field (INP, "@test.proto test4 device")
|
||||
}
|
||||
}
|
||||
|
||||
set protocol {
|
||||
Terminator = LF;
|
||||
OutTerminator = LF;
|
||||
MaxInput = 4;
|
||||
test1 {
|
||||
out "%r"; out "%.1r"; out "%.2r"; out "%.3r"; out "%.4r"; out "%.5r";
|
||||
out "%#r"; out "%#.1r"; out "%#.2r"; out "%#.3r"; out "%#.4r"; out "%#.5r";
|
||||
@ -23,6 +39,18 @@ set protocol {
|
||||
out "%0r"; out "%01r"; out "%02r"; out "%03r"; out "%04r"; out "%05r";
|
||||
out "%#0r"; out "%#01r"; out "%#02r"; out "%#03r"; out "%#04r"; out "%#05r";
|
||||
};
|
||||
test2 {
|
||||
in "%04.4r";
|
||||
out "%08x";
|
||||
}
|
||||
test3{
|
||||
in "%#3r\?";
|
||||
out "%08x";
|
||||
}
|
||||
test4{
|
||||
in "%#03r\?";
|
||||
out "%08x";
|
||||
}
|
||||
}
|
||||
|
||||
set startup {
|
||||
@ -192,6 +220,35 @@ assure "\xef\x00\x00\n"
|
||||
assure "\xef\x00\x00\x00\n"
|
||||
assure "\xef\x00\x00\x00\x00\n"
|
||||
|
||||
ioccmd {dbpf DZ:test2.PROC 1}
|
||||
send "\x01\x02\x03\x04"
|
||||
assure "01020304\n"
|
||||
ioccmd {dbpf DZ:test2.PROC 1}
|
||||
send "\xde\xad\xbe\xef"
|
||||
assure "deadbeef\n"
|
||||
ioccmd {dbpf DZ:test2.PROC 1}
|
||||
send "\x00\x00\x00\x00"
|
||||
assure "00000000\n"
|
||||
|
||||
ioccmd {dbpf DZ:test3.PROC 1}
|
||||
send "\x04\x03\x02\x01"
|
||||
assure "00020304\n"
|
||||
ioccmd {dbpf DZ:test3.PROC 1}
|
||||
send "\xde\xad\xbe\xef"
|
||||
assure "ffbeadde\n"
|
||||
ioccmd {dbpf DZ:test3.PROC 1}
|
||||
send "\x00\x00\x00\x00"
|
||||
assure "00000000\n"
|
||||
|
||||
ioccmd {dbpf DZ:test4.PROC 1}
|
||||
send "\x04\x03\x02\x01"
|
||||
assure "00020304\n"
|
||||
ioccmd {dbpf DZ:test4.PROC 1}
|
||||
send "\xde\xad\xbe\xef"
|
||||
assure "00beadde\n"
|
||||
ioccmd {dbpf DZ:test4.PROC 1}
|
||||
send "\x00\x00\x00\x00"
|
||||
assure "00000000\n"
|
||||
|
||||
|
||||
finish
|
||||
|
@ -48,6 +48,7 @@ int main () {
|
||||
assert (haystack.find(needle) == 0);
|
||||
haystack.clear();
|
||||
assert (haystack.find(needle) == 0);
|
||||
haystack.reserve(10000);
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
Reference in New Issue
Block a user