Compare commits

...

14 Commits

14 changed files with 196 additions and 88 deletions

View File

@ -534,15 +534,6 @@ lockHandler()
debug("AsynDriverInterface::lockHandler(%s)\n",
clientName());
pasynManager->blockProcessCallback(pasynUser, false);
#ifndef ASYN_VERSION // asyn < 4.14
asynStatus status;
status = pasynManager->lockPort(pasynUser);
if(status!=asynSuccess) {
debug("Failed locking port");
}
#endif
connected = connectToAsynPort();
lockCallback(connected ? StreamIoSuccess : StreamIoFault);
}
@ -553,15 +544,6 @@ unlock()
{
debug("AsynDriverInterface::unlock(%s)\n",
clientName());
#ifndef ASYN_VERSION // asyn < 4.14
asynStatus status;
status = pasynManager->unlockPort(pasynUser);
if (status != asynSuccess) {
debug("Failed unlocking port");
}
#endif
pasynManager->unblockProcessCallback(pasynUser, false);
return true;
}
@ -757,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;

View File

@ -65,7 +65,8 @@ ifdef PCRE
LIB_LIBS += pcre
else
ifneq ($(words $(PCRE_LIB) $(PCRE_INCLUDE)),0)
LIB_SYS_LIBS += pcre
LIB_SYS_LIBS_DEFAULT += pcre
LIB_SYS_LIBS_WIN32 += $(PCRE_LIB)\\pcre
SHRLIB_DEPLIB_DIRS += $(PCRE_LIB)
endif
endif
@ -86,22 +87,11 @@ FORCE:
StreamCore$(OBJ): streamReferences
streamReferences: ../CONFIG_STREAM
@for i in $(BUSSES); \
do echo "extern void* ref_$${i}Interface;"; \
echo "void* p$$i = ref_$${i}Interface;"; \
done > $@
@for i in $(FORMATS); \
do echo "extern void* ref_$${i}Converter;"; \
echo "void* p$$i = ref_$${i}Converter;"; \
done >> $@
$(PERL) ../makeref.pl Interface $(BUSSES) > $@
$(PERL) ../makeref.pl Converter $(FORMATS) >> $@
# create stream.dbd from all RECORDS
$(COMMON_DIR)/$(LIBRARY_DEFAULT).dbd: ../CONFIG_STREAM
@for r in $(RECORDS); \
do echo "device($$r,INST_IO,dev$${r}Stream,\"stream\")"; \
done > $@
@echo "driver(stream)" >> $@
@echo "variable(streamDebug, int)" >> $@
@echo "registrar(streamRegistrar)" >> $@
$(PERL) ../makedbd.pl $(RECORDS) > $@
endif

View File

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

View File

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

6
src/makedbd.pl Normal file
View File

@ -0,0 +1,6 @@
for (@ARGV) {
print "device($_,INST_IO,dev${_}Stream,\"stream\")\n";
}
print "driver(stream)\n";
print "variable(streamDebug, int)\n";
print "registrar(streamRegistrar)\n";

6
src/makeref.pl Normal file
View File

@ -0,0 +1,6 @@
$t=@ARGV[0];
shift;
for (@ARGV) {
print "extern void* ref_${_}$t;\n";
print "void* p$_ = ref_${_}$t;\n";
}

19
stream.dbd Normal file
View 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)

View File

@ -25,21 +25,10 @@ PROD_SRCS_vxWorks = -nil-
PROD_LIBS = stream
ifdef PCRE
# With local PCRE package
PROD_LIBS += pcre
else
ifneq ($(words $(PCRE_LIB) $(PCRE_INCLUDE)),0)
# With system wide PCRE installation
PROD_SYS_LIBS += pcre
PROD_DEPLIB_DIRS += $(PCRE_LIB)
endif
endif
ifdef ASYN
# Which types of asyn busses do you have?
ifneq ($(OS_CLASS), WIN32)
# asynDriver up to version 4-8 does not support serial port for Windows!
# asynDriver up to version 4-16 does not support serial port for Windows!
streamApp_DBD += drvAsynSerialPort.dbd
endif
streamApp_DBD += drvAsynIPPort.dbd
@ -69,7 +58,7 @@ include $(TOP)/configure/RULES
clean:: myclean
myclean:
rm -f core* StreamDebug.log
$(RM) core* StreamDebug.log
endif

View File

@ -158,19 +158,22 @@ proc assure {args} {
}
proc escape {string} {
while {![string is print -failindex index $string]} {
set char [string index $string $index]
scan $char "%c" code
switch $char {
"\r" { set escaped "\\r" }
"\n" { set escaped "\\n" }
"\a" { set escaped "\\a" }
"\t" { set escaped "\\t" }
default { set escaped [format "<%02x>" $code] }
set result ""
set length [string length $string]
for {set i 0} {$i < $length} {incr i} {
set c [string index $string $i]
scan $c %c n
if {$n == 13} {
append result "\\r"
} elseif {$n == 10} {
append result "\\n"
} elseif {($n & 127) < 32} {
append result [format "<%02x>" $n]
} else {
append result $c
}
set string [string replace $string $index $index $escaped]
}
return $string
return $result
}
proc finish {} {

View File

@ -45,6 +45,9 @@ set debug 0
startioc
set inf [format %f inf]
set nan [format %f nan]
ioccmd {dbpf DZ:test1.PROC 1}
send "3.14159265359\n"
assure "|3.141593| 3.141593|3.14| 3.14159 | 3.141593|+3.141593|3.1 |3.141593|\n"
@ -56,10 +59,10 @@ send "0\n"
assure "|0.000000| 0.000000|0.00| 0.00000 | 0.000000|+0.000000|0.0 |0.000000|\n"
ioccmd {dbpf DZ:test1.PROC 1}
send "NAN\n"
assure "|nan| nan|nan| nan | nan|+nan|nan |nan|\n"
assure "|$nan| $nan|$nan| $nan | $nan|+$nan|$nan |$nan|\n"
ioccmd {dbpf DZ:test1.PROC 1}
send "-Inf\n"
assure "|-inf| -inf|-inf|-inf |-inf|-inf|-inf |-inf|\n"
assure "|-$inf| -$inf|-$inf|-$inf |-$inf|-$inf|-$inf |-$inf|\n"
ioccmd {dbpf DZ:test1.PROC 1}
send "1e6\n"
assure "|1000000.000000|1000000.000000|1000000.00| 1000000.00000| 1000000.000000|+1000000.000000|1000000.0|1000000.000000|\n"

View File

@ -0,0 +1,41 @@
#!/usr/bin/env tclsh
source streamtestlib.tcl
# Define records, protocol and startup (text goes to files)
# The asynPort "device" is connected to a network TCP socket
# Talk to the socket with send/receive/assure
# Send commands to the ioc shell with ioccmd
set records {
record (ao, "DZ:slow")
{
field (DTYP, "stream")
field (OUT, "@test.proto slow device")
}
record (ao, "DZ:fast")
{
field (DTYP, "stream")
field (OUT, "@test.proto fast device")
}
}
set protocol {
Terminator = LF;
slow { out "slow start"; wait 1000; out "slow finished";}
fast { out "fast"; }
}
set startup {
}
set debug 0
startioc
ioccmd {dbpf DZ:slow 1}
ioccmd {dbpf DZ:fast 1}
assure "slow start\n"
assure "slow finished\n"
assure "fast\n"
finish

View File

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

View File

@ -48,6 +48,7 @@ int main () {
assert (haystack.find(needle) == 0);
haystack.clear();
assert (haystack.find(needle) == 0);
haystack.reserve(10000);
return 0;
}
EOF

View File

@ -1,3 +1,4 @@
rm -f test.* *.out *.ioclog StreamDebug.log
for i in test*
do
if [ $i != testall -a -x $i ]
@ -6,7 +7,7 @@ do
if ! $i "$@"
then
echo -e "\033[31;7mFailed.\033[0m"
(( fail++ ))
(( fail+=1 ))
fi
fi
done