Commit 469abde1 authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Adedd a test suite that currently seems to work with Python, C and C#

parent 11902762
......@@ -18,3 +18,5 @@ lib/java/se/lth/control/labcomm/LabCommSample.class
lib/java/se/lth/control/labcomm/LabCommType.class
lib/java/se/lth/control/labcomm/LabCommWriter.class
gen
labcomm.dll
labcomm.jar
export LABCOMM_JAR=$(shell pwd)/compiler/labComm.jar
export LABCOMM=java -jar $(LABCOMM_JAR)
all: compiler
$(MAKE) -C lib
$(MAKE) -C lib/c run-test
.PHONY: compiler
compiler:
cd compiler ; ant jar
.PHONY: test
test:
$(MAKE) -C test -e
TESTS=basic simple
LABCOMM_JAR=../compiler/labComm.jar
LABCOMM=java -jar $(LABCOMM_JAR)
all: $(TESTS:%=test_%)
# PYTHONPATH=../lib/python \
# ./test_encoder_decoder.py --labcomm="$(LABCOMM)" basic.lc
.PHONY: clean
clean:
rm -rf gen
.PHONY: test_%
test_%: gen/%/c_relay \
gen/%/cs_code.cs \
gen/%/cs_relay.exe \
gen/%/signatures.py \
gen/%/java_code
PYTHONPATH=../lib/python ./test_encoder_decoder.py \
--signatures=gen/$*/signatures.py \
--test /bin/tee gen/$*/testdata \
--test gen/$*/c_relay /dev/stdin /dev/stdout \
--test mono gen/$*/cs_relay.exe /dev/stdin /dev/stdout
.PRECIOUS: gen/%/
gen/%/:
mkdir -p $@
.PRECIOUS: gen/%/typeinfo
gen/%/typeinfo: %.lc Makefile | gen/%/
$(LABCOMM) --typeinfo=$@ $<
.PRECIOUS: gen/%/signatures.py
gen/%/signatures.py: %.lc Makefile | gen/%/
$(LABCOMM) --python=$@ $<
# C relay test rules
.PRECIOUS: gen/%/c_code.h gen/%/c_code.c
gen/%/c_code.h gen/%/c_code.c: %.lc Makefile | gen/%/
$(LABCOMM) --c=gen/$*/c_code.c --h=gen/$*/c_code.h $<
.PRECIOUS: gen/%/c_relay.c
gen/%/c_relay.c: gen/%/typeinfo relay_gen_c.py Makefile
./relay_gen_c.py $< > $@
.PRECIOUS: gen/%/c_relay
gen/%/c_relay: gen/%/c_relay.c gen/%/c_code.c Makefile
$(CC) $(CFLAGS) -o $@ $< -I../lib/c -I. \
-DLABCOMM_FD_OMIT_VERSION \
-DLABCOMM_ENCODER_LINEAR_SEARCH \
gen/$*/c_code.c \
../lib/c/labcomm.c \
../lib/c/labcomm_fd_*.c \
../lib/c/labcomm_dynamic_buffer_writer.c
# C# relay test rules
.PRECIOUS: gen/%/cs_code.cs
gen/%/cs_code.cs: %.lc Makefile | gen/%/
$(LABCOMM) --cs=$@ $<
.PRECIOUS: gen/%/cs_relay.cs
gen/%/cs_relay.cs: gen/%/typeinfo relay_gen_cs.py Makefile
./relay_gen_cs.py $< > $@
.PRECIOUS: gen/%/labcomm.dll
gen/%/labcomm.dll:
ln -s ../../../lib/csharp/labcomm.dll $@
.PRECIOUS: gen/%/cs_relay.exe
gen/%/cs_relay.exe: gen/%/cs_relay.cs gen/%/cs_code.cs \
gen/%/labcomm.dll Makefile
mcs -out:$@ $(filter %.cs, $^) -lib:../lib/csharp/ -r:labcomm
# Java relay test rules
.PRECIOUS: gen/%/java_code
gen/%/java_code: %.lc | gen/%/
mkdir -p $@
$(LABCOMM) --java=$@ $<
sample void s_void;
sample byte s_byte;
sample short s_short;
sample int s_int;
sample long s_long;
sample float s_float;
sample double s_double;
sample boolean s_boolean;
sample string s_string;
\ No newline at end of file
def gen(f, signatures):
print """
#include <labcomm.h>
#include <labcomm_fd_reader_writer.h>
#include "%(f)s.h"
""" % { 'f': f }
for s in [s.name for s in signatures]:
t = "%s_%s" % (f, s)
print """
void handle_%(t)s(%(t)s *v, void *context)
{
struct labcomm_encoder *e = context;
labcomm_encode_%(t)s(e, v);
}
""" % {'t':t}
print """
int main(int argc, char *argv[]) {
struct labcomm_decoder *d;
struct labcomm_encoder *e;
"""
#!/usr/bin/python
import os
import re
import subprocess
import sys
def gen(classname, namespace, signatures):
yield 'using System;'
yield 'using System.IO;'
yield 'using se.lth.control.labcomm;'
yield ''
yield 'class %s :' % classname
for s in signatures[0:-1]:
yield '%s%s.Handler,' % (namespace, s.name)
yield '%s%s.Handler' % (namespace, signatures[-1].name)
yield '{'
yield ''
yield ' LabCommEncoderChannel encoder;'
for s in signatures:
yield ''
if s.type == 'void':
yield ' void %s%s.Handler.handle() {' % ( namespace, s.name)
else:
yield ' void %s%s.Handler.handle(%s data) {' % (
namespace, s.name, s.type)
yield ' Console.Error.WriteLine("%s%s");' % (namespace, s.name)
if s.type == 'void':
yield ' %s%s.encode(encoder);' % (namespace, s.name)
else:
yield ' %s%s.encode(encoder, data);' % (namespace, s.name)
yield ' }'
yield ''
yield ' public %s(String InName, String OutName) {' % (classname)
yield ' FileStream InFile = new FileStream(InName,'
yield ' FileMode.Open, '
yield ' FileAccess.Read);'
yield ' LabCommDecoderChannel d = new LabCommDecoderChannel(InFile);'
yield ' FileStream OutFile = new FileStream(OutName, '
yield ' FileMode.OpenOrCreate, '
yield ' FileAccess.Write);'
yield ' encoder = new LabCommEncoderChannel(OutFile);'
yield ''
for s in signatures:
yield ' %s%s.register(d, this);' % (namespace, s.name)
yield ''
for s in signatures:
yield ' %s%s.register(encoder);' % (namespace, s.name)
yield ''
yield ' try {'
yield ' d.run();'
yield ' } catch (EndOfStreamException) {'
yield ' }'
yield ''
yield ' }'
yield ''
yield ' static void Main(String[] arg) {'
yield ' new %s(arg[0], arg[1]);' % (classname)
yield ' }'
yield ''
yield '}'
class Signature:
def __init__(self, name, type):
self.name = name
self.type = type
def test_program(target, typeinfo):
f = open(typeinfo)
signature = []
for l in f:
m = re.match('C#,sample,([^,]+),(.*)', l)
if m:
signature.append(Signature(m.group(1), m.group(2)))
f.close()
f = open(target, "w")
for l in gen("x", "", signature):
f.write(l + "\n")
f.close()
if __name__ == "__main__":
#os.system("labcomm --typeinfo=/dev/stdout %s" % sys.argv[1])
typeinfo = subprocess.Popen(["labcomm",
"--typeinfo=/dev/stdout %s" % sys.argv[1]],
stdout=subprocess.PIPE)
signature = []
for l in typeinfo.stdout:
m = re.match('C#,sample,([^,]+),(.*)', l)
if m:
signature.append(Signature(m.group(1), m.group(2)))
for l in gen("x", "", signature):
print l
#!/usr/bin/python
import re
import sys
def split_match(pattern, multiline):
def match(s):
m = re.match(pattern, s)
if m:
return m.group(1)
pass
return filter(lambda s: s != None, map(match, multiline.split('\n')))
if __name__ == '__main__':
f = open(sys.argv[1])
sample = []
for l in map(lambda s: s.strip(), f):
lang,kind,func,arg = l[1:].split(l[0])
if lang == 'C' and kind == 'sample':
sample.append((func, arg))
pass
pass
result = []
result.extend(split_match('^[^|]*\|(.*)$', """
|#include <sys/types.h>
|#include <sys/stat.h>
|#include <fcntl.h>
|#include <labcomm.h>
|#include <labcomm_fd_reader.h>
|#include <labcomm_fd_writer.h>
|#include "c_code.h"
"""))
for func,arg in sample:
result.extend(split_match('^[^|]*\|(.*)$', """
|void handle_%(func)s(%(arg)s *v, void *context)
|{
| struct labcomm_encoder *e = context;
| labcomm_encode_%(func)s(e, v);
|}""" % { 'func': func, 'arg': arg }))
pass
result.extend(split_match('^[^|]*\|(.*)$', """
|int main(int argc, char *argv[]) {
| struct labcomm_encoder *e;
| struct labcomm_decoder *d;
| int in, out;
|
| if (argc < 3) { return 1; }
| in = open(argv[1], O_RDONLY);
| if (in < 0) { return 1; }
| out = open(argv[2], O_WRONLY);
| if (out < 0) { return 1; }
| e = labcomm_encoder_new(labcomm_fd_writer, &out);
| d = labcomm_decoder_new(labcomm_fd_reader, &in);
"""))
for func,arg in sample:
result.extend(split_match('^[^|]*\|(.*)$', """
| labcomm_encoder_register_%(func)s(e);
| labcomm_decoder_register_%(func)s(d, handle_%(func)s, e);
""" % { 'func': func, 'arg': arg }))
result.extend(split_match('^[^|]*\|(.*)$', """
| labcomm_decoder_run(d);
| return 0;
|}
"""))
print "\n".join(result)
pass
#!/usr/bin/python
import re
import sys
def split_match(pattern, multiline):
def match(s):
m = re.match(pattern, s)
if m:
return m.group(1)
pass
return filter(lambda s: s != None, map(match, multiline.split('\n')))
if __name__ == '__main__':
f = open(sys.argv[1])
sample = []
for l in map(lambda s: s.strip(), f):
lang,kind,func,arg = l[1:].split(l[0])
if lang == 'C#' and kind == 'sample':
sample.append((func, arg))
pass
pass
result = []
result.extend(split_match('^[^|]*\|(.*)$', """
|using System;
|using System.IO;
|using se.lth.control.labcomm;
|
|public class cs_relay :
"""))
for func,arg in sample[0:-1]:
result.append(' %s.Handler,' % func)
pass
result.append(' %s.Handler' % sample[-1][0])
result.extend(split_match('^[^|]*\|(.*)$', """
|{
| LabCommEncoderChannel encoder;
"""))
for func,arg in sample:
if arg == 'void':
result.extend(split_match('^[^|]*\|(.*)$', """
| void %(func)s.Handler.handle() {
| %(func)s.encode(encoder);
| }
""" % { 'func': func}))
pass
else:
result.extend(split_match('^[^|]*\|(.*)$', """
| void %(func)s.Handler.handle(%(arg)s data) {
| %(func)s.encode(encoder, data);
| }
""" % { 'func': func, 'arg': arg}))
pass
pass
result.extend(split_match('^[^|]*\|(.*)$', """
| public cs_relay(String InName, String OutName) {
| FileStream InFile = new FileStream(InName,
| FileMode.Open,
| FileAccess.Read);
| LabCommDecoderChannel d = new LabCommDecoderChannel(InFile);
| FileStream OutFile = new FileStream(OutName,
| FileMode.OpenOrCreate,
| FileAccess.Write);
| encoder = new LabCommEncoderChannel(OutFile);
|
"""))
for func,arg in sample:
result.append(' %s.register(d, this);' % func)
pass
for func,arg in sample:
result.append(' %s.register(encoder);' % func)
pass
result.extend(split_match('^[^|]*\|(.*)$', """
| try {
| d.run();
| } catch (EndOfStreamException) {
| }
| }
| static void Main(String[] arg) {
| new cs_relay(arg[0], arg[1]);
| }
|}
"""))
print "\n".join(result)
exit(0)
for func,arg in sample:
result.extend(split_match('^[^|]*\|(.*)$', """
|void handle_%(func)s(%(arg)s *v, void *context)
|{
| struct labcomm_encoder *e = context;
| labcomm_encode_%(func)s(e, v);
|}""" % { 'func': func, 'arg': arg }))
pass
result.extend(split_match('^[^|]*\|(.*)$', """
|int main(int argc, char *argv[]) {
| struct labcomm_encoder *e;
| struct labcomm_decoder *d;
| int in, out;
|
| if (argc < 3) { return 1; }
| in = open(argv[1], O_RDONLY);
| if (in < 0) { return 1; }
| out = open(argv[2], O_WRONLY);
| if (out < 0) { return 1; }
| e = labcomm_encoder_new(labcomm_fd_writer, &out);
| d = labcomm_decoder_new(labcomm_fd_reader, &in);
"""))
for func,arg in sample:
result.extend(split_match('^[^|]*\|(.*)$', """
| labcomm_encoder_register_%(func)s(e);
| labcomm_decoder_register_%(func)s(d, handle_%(func)s, e);
""" % { 'func': func, 'arg': arg }))
result.extend(split_match('^[^|]*\|(.*)$', """
| labcomm_decoder_run(d);
| return 0;
|}
"""))
print "\n".join(result)
pass
#!/usr/bin/python
# -*- coding: iso8859-15 -*-
import math
import os
import sys
import re
import traceback
def run_labcomm(base):
if not os.path.exists("gen/java/%s" % base):
os.makedirs("gen/java/%s" % base)
cmd = " ".join([
"java -jar ../compiler/labComm.jar",
"--c=gen/%s.c" % base,
"--h=gen/%s.h" % base,
"--python=gen/%s.py" % base,
"--java=gen/java/%s" % base,
"%s.lc" % base
])
print cmd
os.system(cmd)
class hexwriter(object):
def __init__(self):
self.pos = 0
self.ascii = ''
def write(self, data):
for c in data:
if ' ' <= c and c <= '}':
self.ascii += c
else:
self.ascii += '.'
sys.stdout.write("%2.2x " % ord(c))
self.pos += 1
if self.pos >= 15:
sys.stdout.write("%s\n" % self.ascii)
self.pos = 0
self.ascii = ""
def mark(self):
pass
def flush(self):
for i in range(self.pos, 15):
sys.stdout.write(" ")
sys.stdout.write("%s\n" % self.ascii)
self.pos = 0
self.ascii = ""
def generate(decl):
if decl.__class__ == labcomm.sample:
result = []
for values in generate(decl.decl):
result.append((decl, values))
return result
elif decl.__class__ == labcomm.struct:
result = []
if len(decl.field) == 0:
result.append({})
else:
values1 = generate(decl.field[0][1])
values2 = generate(labcomm.struct(decl.field[1:]))
for v1 in values1:
for v2 in values2:
v = dict(v2)
v[decl.field[0][0]] = v1
result.append(v)
return result
elif decl.__class__ == labcomm.array:
if len(decl.indices) == 1:
values = generate(decl.decl)
if decl.indices[0] == 0:
lengths = [0, 1, 2]
else:
lengths = [ decl.indices[0] ]
else:
values = generate(labcomm.array(decl.indices[1:],decl.decl))
if decl.indices[0] == 0:
lengths = [1, 2]
else:
lengths = [ decl.indices[0] ]
result = []
for v in values:
for i in lengths:
element = []
for j in range(i):
element.append(v)
result.append(element)
return result
elif decl.__class__ == labcomm.BOOLEAN:
return [False, True]
elif decl.__class__ == labcomm.BYTE:
return [-128, 0, 127]
elif decl.__class__ == labcomm.SHORT:
return [-32768, 0, 32767]
elif decl.__class__ == labcomm.INTEGER:
return [-2147483648, 0, 2147483647]
elif decl.__class__ == labcomm.LONG:
return [-9223372036854775808, 0, 9223372036854775807]
elif decl.__class__ == labcomm.FLOAT:
return [-math.pi, 0.0, math.pi]
elif decl.__class__ == labcomm.DOUBLE:
return [-math.pi, 0.0, math.pi]
elif decl.__class__ == labcomm.STRING:
return ['string',
'teckenstrng'.decode("iso8859-15")]
print decl
raise Exception("unhandled decl %s" % decl.__class__)
if __name__ == "__main__":
sys.path.insert(0, "../lib/python/")
import labcomm
print os.getcwd(), sys.argv
if not os.path.exists("gen"):
os.makedirs("gen")
files = sys.argv[1:]
print sys.argv, files
if len(files) == 0:
files = os.listdir(".")
for f in files:
m = re.match("(.*).lc", f)
if m:
run_labcomm(m.group(1))
sys.path.insert(0, "gen")
for f in files:
m = re.match("(.*).lc", f)
if m:
print f
h = hexwriter()
encoder = labcomm.Encoder(h)
signatures = []
i = __import__(m.group(1))
for k in dir(i):
v = getattr(i, k)
try:
s = v.signature
except:
s = None
if s:
signatures.append(s)
encoder.add_decl(s)
for s in signatures:
for e in generate(s):
encoder.encode(e[1], s)
h.flush()
#!/usr/bin/python
# -*- coding: iso8859-15 -*-
# -*- coding: utf-8 -*-
import argparse
import imp
import labcomm
import math
import os
import sys
import re
import traceback
import ccode
import cscode
def run_labcomm(base):
if not os.path.exists("gen/java/%s" % base):
os.makedirs("gen/java/%s" % base)
if not os.path.exists("gen/csharp"):
os.makedirs("gen/csharp")
if not os.path.exists("gen/c"):
os.makedirs("gen/c")
if not os.path.exists("gen/python"):
os.makedirs("gen/python")
cmd = " ".join([
"java -jar ../compiler/labComm.jar",
"--c=gen/c/%s.c" % base,
"--h=gen/c/%s.h" % base,
"--cs=gen/csharp/%s.cs" % base,
"--python=gen/python/%s.py" % base,
"--java=gen/java/%s" % base,
"--typeinfo=gen/%s.typeinfo" % base,
"%s.lc" % base
])
err = os.system(cmd)
if err != 0:
sys.exit(err / 256)
import struct
import subprocess
import sys
import threading