Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • anders.blomdell
  • compiler-refactoring
  • labcomm2006
  • labcomm2013
  • labcomm2014
  • master
  • pragma
  • python_sig_hash
  • typedefs
  • typeref
  • v2006.0
  • v2013.0
  • v2014.0
  • v2014.1
  • v2014.2
  • v2014.3
  • v2014.4
  • v2014.5
  • v2014.6
  • v2015.0
20 results

Target

Select target project
  • anders_blomdell/labcomm
  • klaren/labcomm
  • tommyo/labcomm
  • erikj/labcomm
  • sven/labcomm
5 results
Select Git revision
  • anders.blomdell
  • compiler-refactoring
  • labcomm2006
  • labcomm2013
  • master
  • pragma
  • typedefs
  • typeref
  • v2006.0
  • v2013.0
  • v2014.0
  • v2014.1
  • v2014.2
  • v2014.3
  • v2014.4
15 results
Show changes
Showing
with 1888 additions and 70 deletions
package se.lth.control.labcomm2014;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.EOFException;
import se.lth.control.labcomm2014.Decoder;
import se.lth.control.labcomm2014.DecoderChannel;
import se.lth.control.labcomm2014.TypeDef;
import se.lth.control.labcomm2014.TypeBinding;
public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
static class SelfBinding extends TypeDef {
private int sampleIndex;
private Decoder decoder;
private byte[] dummy = new byte[0];
public String toString() {return "self";}
public String getName() {
if(decoder instanceof DecoderChannel) {
DecoderChannel dc = (DecoderChannel) decoder;
return dc.getSampleName(sampleIndex);
} else {
return "self";
}
}
public int getIndex() {return 0;}
public byte[] getSignature() {
if(decoder instanceof DecoderChannel) {
DecoderChannel dc = (DecoderChannel) decoder;
return dc.getSampleSignature(sampleIndex);
} else {
return dummy;
}
}
public SelfBinding(int sampleIndex, Decoder decoder) {
super();
this.sampleIndex = sampleIndex;
this.decoder = decoder;
}
}
public interface TypeDefListener {
void onTypeDef(SigTypeDef d);
}
private HashMap<Integer,TypeDef> typeDefs;
private HashMap<Integer,Integer> typeBindings;
private HashSet<TypeDefListener> listeners;
private LinkedList<ParsedSampleDef> sampleDefs;
private HashMap<Integer,ParsedTypeDef> pts;
private Decoder decoder;
protected TypeDefParser(Decoder d) {
this.decoder = d;
typeDefs = new HashMap<Integer,TypeDef>();
typeBindings = new HashMap<Integer,Integer>();
listeners = new HashSet<TypeDefListener>();
sampleDefs = new LinkedList<ParsedSampleDef>();
pts = new HashMap<Integer,ParsedTypeDef>();
}
public void addListener(TypeDefListener l) {
listeners.add(l);
}
public Iterator<ParsedSampleDef> sampleDefIterator() {
return sampleDefs.iterator();
}
public void handle_TypeDef(TypeDef d) throws java.io.IOException {
System.out.println("handle_TypeDef: "+d.getIndex());
typeDefs.put(d.getIndex(), d);
ParsedTypeDef td = parseSignatureTD(d);
pts.put(d.getIndex(), td);
}
public void handle_TypeBinding(TypeBinding d) throws java.io.IOException {
TypeDef td;
if(d.isSelfBinding()){
td = new SelfBinding(d.getSampleIndex(), decoder);
} else {
typeBindings.put(d.getSampleIndex(), d.getTypeIndex());
td = getTypeDefForIndex(d.getSampleIndex());
}
System.out.println("handle_TypeBinding: "+d.getSampleIndex());
ParsedSampleDef result = parseSignature(td);
sampleDefs.add(result);
Iterator<TypeDefListener> it = listeners.iterator();
while(it.hasNext()){
notifyListener(it.next(), result);
}
}
private void notifyListener(TypeDefListener l, ParsedTypeDef d) {
l.onTypeDef(d);
if(d instanceof ParsedSampleDef) {
for(SigTypeDef dep : ((ParsedSampleDef)d).getDependencies()) {
//do we want to change ParseTypeDef to have dependencies,
//and do recursion here?
//if so, do notifyListener(l, dep);
l.onTypeDef(dep);
}
}
}
private TypeDef getTypeDefForIndex(int sampleIndex) {
return typeDefs.get(typeBindings.get(sampleIndex));
}
/** Factory method for use by application programs:
* registers a TypeDefParser for handling TypeDef and TypeBinding
* on the Decoder d.
*
* @return a new TypeDefParser registered on d
*/
public static TypeDefParser registerTypeDefParser(Decoder d) throws java.io.IOException {
TypeDefParser res = new TypeDefParser(d);
TypeDef.register(d,res);
TypeBinding.register(d,res);
return res;
}
public LinkedList<SignatureSymbol> symbolify() {
LinkedList<SignatureSymbol> result = new LinkedList<SignatureSymbol>();
Iterator<ParsedSampleDef> sdi = sampleDefIterator();
while(sdi.hasNext()) {
SigTypeDef sd = sdi.next();
result.add(new SampleSymbol());
result.add(sd.getType());
result.add(new NameSymbol(sd.getName()));
Iterator<SigTypeDef> di = sd.getDepIterator();
while(di.hasNext()) {
SigTypeDef d = di.next();
result.add(new TypeSymbol());
result.add(d.getType());
result.add(new NameSymbol(d.getName()));
}
}
return result;
}
public String symbolString() {
Iterator<SignatureSymbol> i = symbolify().iterator();
StringBuilder sb = new StringBuilder();
while(i.hasNext()) {
sb.append(i.next().toString());
}
return sb.toString();
}
// SampleRefType currently not sent, se above
// public class SampleRefType extends DataType {
// public void accept(SignatureSymbolVisitor v) {
// v.visit(this);
// }
//
// public String toString() {
// return "sample";}
// }
private class ParserState {
private ByteArrayInputStream bis;
private DataInputStream in;
private TypeDef current;
private ParsedTypeDef currentParsed;
private LinkedList<TypeDef> typeStack;
ParsedTypeDef newTypeDef() {
currentParsed =new ParsedTypeDef(getCurrentIndex(), getCurrentName());
return currentParsed;
}
private ParserState() {
typeStack = new LinkedList<TypeDef>();
}
ParserState(int typeIdx) {
this();
pushType(typeIdx);
}
ParserState(TypeDef td) {
this();
pushType(td);
}
ParserState(byte sig[]) {
this();
bis= new ByteArrayInputStream(sig);
in = new DataInputStream(bis);
}
void pushType(TypeDef td) {
if(!typeStack.contains(td)) {
typeStack.push(td);
}
}
void pushType(int typeIdx) {
if(typeIdx >= 0x40 && !typeStack.contains(typeIdx)) {
typeStack.push(typeDefs.get(typeIdx));
}
}
void popType() {
TypeDef td2 = typeStack.pop();
current = td2;
bis =new ByteArrayInputStream(td2.getSignature());
in = new DataInputStream(bis);
}
boolean moreTypes() {
return !typeStack.isEmpty();
}
int getCurrentIndex() {
return current.getIndex();
}
String getCurrentName() {
return current.getName();
}
void addTypeUse(int tag) {
SigTypeDef td = pts.get(tag);
if(td != null) {
currentParsed.addDependency(td);
} else {
System.out.println("******* WARNING: TypeDefParser:addTypeUse ("+tag+"): null???");
}
}
/** return name, (if any, or "") for now */
String decodeIntentions() throws IOException {
int n = decodePacked32() & 0xffffffff;
if(n==0) return "";
String name = "";
for(int i=0; i<n;i++) {
int klen = decodePacked32() & 0xffffffff;
byte[] kchars = new byte[klen];
for(int k=0; k<klen; k++) {
kchars[k] = in.readByte();
}
int vlen = decodePacked32() & 0xffffffff;
byte[] vchars = new byte[vlen];
for(int j=0; j<vlen; j++) {
vchars[j] = in.readByte();
}
if(klen==0) {
name = new String(vchars);
}
}
return name;
}
String decodeString() throws IOException {
int len = decodePacked32() & 0xffffffff;
byte[] chars = new byte[len];
for(int i=0; i<len; i++) {
chars[i] = in.readByte();
}
return new String(chars);
}
int decodePacked32() throws IOException {
long res=0;
byte i=0;
boolean cont=true;
do {
byte c = in.readByte();
res = (res << 7) | (c & 0x7f);
cont = (c & 0x80) != 0;
i++;
} while(cont);
return (int) (res & 0xffffffff);
}
void skipBytes(int len) throws IOException {
for(int i=0; i<len; i++) {
in.readByte();
}
}
}
private ParsedTypeDef parseSignatureTD(TypeDef td) throws IOException{
return parseSignatureTD(td, new ParserState(td));
}
private ParsedTypeDef parseSignatureTD(TypeDef td, ParserState s) throws IOException{
ParsedTypeDef result=null;
s.popType();
result = parseTypeDef(s);
return result;
}
public ParsedSampleDef parseSignature(TypeDef td) throws IOException{
ParserState s = new ParserState(td);
ParsedSampleDef result=null;
try {
result = new ParsedSampleDef(parseSignatureTD(td,s));
// while(s.moreTypes()) {
// s.popType();
// result.addDependency(parseTypeDef(s));
// }
} catch(java.io.EOFException ex) {
System.out.println("EOF: self_binding");
}
return result;
}
private SigArrayType parseArray(ParserState in) throws IOException {
int numIdx = in.decodePacked32();
int idx[] = new int[numIdx];
for(int i=0; i<numIdx; i++){
idx[i] = in.decodePacked32();
}
int type = in.decodePacked32();
DataType elementType = lookupType(type, in);
SigArrayType result = new SigArrayType(elementType, idx);
for(int i=0; i<numIdx; i++){
idx[i] = in.decodePacked32();
}
return result;
}
private SigStructType parseStruct(ParserState in) throws IOException {
int numSigFields = in.decodePacked32();
SigStructType result = new SigStructType(numSigFields);
for(int i=0; i<numSigFields; i++) {
result.addField(parseSigField(in));
}
return result;
}
private SigField parseSigField(ParserState in) throws IOException {
String name = in.decodeIntentions();
return new SigField(name, parseType(in, false));
}
private DataType lookupType(int tag, ParserState in) {
DataType result;
if(tag >= Constant.FIRST_USER_INDEX) {
TypeDef td = typeDefs.get(tag);
result = new SigUserType(td.getName());
in.addTypeUse(tag);
in.pushType(tag);
// sampleRefs are sent as primitive types, see above
// } else if(tag == Constant.SAMPLE) {
// result = new SampleRefType();
} else {
result = new SigPrimitiveType(tag);
}
return result;
}
private ParsedSampleDef parseSampleTypeDef(ParserState in) throws IOException {
ParsedTypeDef td = parseTypeDef(in, true);
return new ParsedSampleDef(td);
}
private ParsedTypeDef parseTypeDef(ParserState in) throws IOException {
return parseTypeDef(in, false);
}
private void addParsedTypeDef(ParsedTypeDef td) {
int idx = td.getIndex();
if(idx>=0x40) {
pts.put(idx, td);
}
}
private ParsedTypeDef parseTypeDef(ParserState in, boolean parseIntentions) throws IOException {
ParsedTypeDef result = in.newTypeDef();
result.setType(parseType(in, false));
addParsedTypeDef(result);
return result;
}
private DataType parseType(ParserState in, boolean parseIntentions) throws IOException {
if(parseIntentions) {
String intentions = in.decodeIntentions();
if(intentions.length()>0) {
System.out.println("parseType intentions ("+intentions);
} else {
System.out.println("no intentions");
}
} else {
// System.out.println("not parsing intentions");
}
int tag = in.decodePacked32();
DataType result = null;
switch(tag) {
case 0:
System.out.println("SELF");
break;
case Constant.ARRAY:
result = parseArray(in);
break;
case Constant.STRUCT:
result = parseStruct(in);
break;
default:
result = lookupType(tag, in);
break;
}
return result;
}
}
package se.lth.control.labcomm2014;
public class TypeSymbol implements SignatureSymbol {
public String toString() {
return "typedef ";
}
public void accept(SignatureSymbolVisitor v){
v.visit(this);
}
}
package se.lth.control.labcomm2014;
import java.io.PrintStream;
public class VoidType extends SigStructType{
public VoidType() {
super("void");
}
public void print(PrintStream out, String indent) {
out.print("void");
}
}
package se.lth.control.labcomm; package se.lth.control.labcomm2014;
import java.io.IOException; import java.io.IOException;
public interface LabCommWriter { public interface Writer {
public void write(byte[] data) throws IOException; public void write(byte[] data) throws IOException;
......
package se.lth.control.labcomm; package se.lth.control.labcomm2014;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.IOException; import java.io.IOException;
class WriterWrapper implements LabCommWriter{ class WriterWrapper implements Writer{
private OutputStream os; private OutputStream os;
......
.PHONY: all
all:
.PHONY: test
test:
.PHONY: clean
clean:
find . -name '*.pyc' -exec rm {} \;
.PHONY: distclean
distclean: clean
import labcomm.LabComm
Decoder = labcomm.LabComm.Decoder
Encoder = labcomm.LabComm.Encoder
sample = labcomm.LabComm.sample
typedef = labcomm.LabComm.typedef
array = labcomm.LabComm.array
struct = labcomm.LabComm.struct
primitive = labcomm.LabComm.primitive
BOOLEAN = labcomm.LabComm.BOOLEAN
BYTE = labcomm.LabComm.BYTE
SHORT = labcomm.LabComm.SHORT
INTEGER = labcomm.LabComm.INTEGER
LONG = labcomm.LabComm.LONG
FLOAT = labcomm.LabComm.FLOAT
DOUBLE = labcomm.LabComm.DOUBLE
STRING = labcomm.LabComm.STRING
decl_from_signature = labcomm.LabComm.decl_from_signature
try:
import labcomm.TreeModel
TreeModel = labcomm.TreeModel.TreeModel
except:
pass
#!/usr/bin/python #!/usr/bin/python
# #
# All packets follows the following layout # LabComm2014 packet has the following layout
# #
# +----+----+----+----+ # +----+----+----+----+
# | id | # | id (packed32)
# +----+----+----+----+
# | length (packed32)
# +----+----+----+----+ # +----+----+----+----+
# | data # | data
# | ... # | ...
# +----+-- # +----+--
# #
# Data layouts for packets # LabComm2014 SAMPLE_DEF:
#
# +----+----+----+----+
# | id = 0x02 (packed32)
# +----+----+----+----+
# | length (packed32)
# +----+----+----+----+
# | type number (packed32)
# +----+----+----+----+
# | type name (UTF8)
# | ...
# +----+----+----+----+
# | signature length (packed32)
# +----+----+----+----+
# | type signature
# | ...
# +----+--
# #
# TYPEDEF: # LabComm2014 SAMPLE_REF:
# #
# +----+----+----+----+ # +----+----+----+----+
# | id = 0x00000001 | # | id = 0x03 (packed32)
# +----+----+----+----+ # +----+----+----+----+
# | type number | # | length (packed32)
# +----+----+----+----+
# | type number (packed32)
# +----+----+----+----+ # +----+----+----+----+
# | type name (UTF8) # | type name (UTF8)
# | ... # | ...
# +----+----+----+----+ # +----+----+----+----+
# | type # | signature length (packed32)
# +----+----+----+----+
# | type signature
# | ... # | ...
# +----+-- # +----+--
# #
# LabComm2014 TYPE_DEF: (as SAMPLE_DEF, but signatures are hierarchical,
# i.e., may contain references to other types
# #
# SAMPLE: # +----+----+----+----+
# | id = 0x04 (packed32)
# +----+----+----+----+
# | length (packed32)
# +----+----+----+----+
# | type number (packed32)
# +----+----+----+----+
# | type name (UTF8)
# | ...
# +----+----+----+----+
# | signature length (packed32)
# +----+----+----+----+
# | type signature
# | ...
# +----+--
#
# LabComm2014 TYPE_BINDING
#
# +----+----+----+----+
# | id = 0x05 (packed32)
# +----+----+----+----+
# | length (packed32)
# +----+----+----+----+
# | sample number (packed32)
# +----+----+----+----+
# | type number (packed32)
# +----+----+----+----+
#
# LabComm2014 User data:
#
# +----+----+----+----+
# | id >= 0x00000040 (packed32)
# +----+----+----+----+
# | length (packed32)
# +----+----+----+----+
# | user data
# | ...
# +----+--
#
#
# LabComm2006 packets has the following layout
#
# +----+----+----+----+
# | id |
# +----+----+----+----+
# | data
# | ...
# +----+--
#
# LabComm2006 SAMPLE:
# #
# +----+----+----+----+ # +----+----+----+----+
# | id = 0x00000002 | # | id = 0x00000002 |
...@@ -36,15 +109,15 @@ ...@@ -36,15 +109,15 @@
# | type name (UTF8) # | type name (UTF8)
# | ... # | ...
# +----+----+----+----+ # +----+----+----+----+
# | type # | type signature
# | ... # | ...
# +----+-- # +----+--
# #
# #
# User data: # LabComm2006 User data:
# #
# +----+----+----+----+ # +----+----+----+----+
# | id >= 0x00000060 | # | id >= 0x00000040 |
# +----+----+----+----+ # +----+----+----+----+
# | user data # | user data
# | ... # | ...
...@@ -93,11 +166,21 @@ ...@@ -93,11 +166,21 @@
# sequences of 7 bit chunks, represented in bytes with the high bit meaning # sequences of 7 bit chunks, represented in bytes with the high bit meaning
# that more data is to come. # that more data is to come.
import types
import struct as packer import struct as packer
i_TYPEDEF = 0x01 DEFAULT_VERSION = "LabComm2014"
i_SAMPLE = 0x02
# Allowed packet tags
i_VERSION = 0x01
i_SAMPLE_DEF = 0x02
i_SAMPLE_REF = 0x03
i_TYPE_DEF = 0x04
i_TYPE_BINDING= 0x05
i_PRAGMA = 0x3f
i_USER = 0x40 # ..0xffffffff
# Predefined types
i_ARRAY = 0x10 i_ARRAY = 0x10
i_STRUCT = 0x11 i_STRUCT = 0x11
...@@ -109,19 +192,55 @@ i_LONG = 0x24 ...@@ -109,19 +192,55 @@ i_LONG = 0x24
i_FLOAT = 0x25 i_FLOAT = 0x25
i_DOUBLE = 0x26 i_DOUBLE = 0x26
i_STRING = 0x27 i_STRING = 0x27
i_SAMPLE = 0x28
# Version testing
def usePacketLength(version):
return version in [ None, "LabComm2014" ]
i_USER = 0x40 class length_encoder:
def __init__(self, encoder):
self.encoder = encoder
self.version = encoder.version
self.data = ""
def write(self, data):
self.data += data
def __enter__(self):
return Encoder(writer=self, version=None, codec=self.encoder)
def __exit__(self, type, value, traceback):
if usePacketLength(self.version):
self.encoder.encode_packed32(len(self.data))
self.encoder.pack("%ds" % len(self.data), self.data)
def indent(i, s): def indent(i, s):
return ("\n%s" % (" " * i)).join(s.split("\n")) return ("\n%s" % (" " * i)).join(s.split("\n"))
#
# Base type for all decl's
#
class type_decl(object):
pass
# #
# Primitive types # Primitive types
# #
class primitive(object): class primitive(type_decl):
def decode_decl(self, decoder): def decode_decl(self, decoder):
return self return self
def __eq__(self, other):
return self.__class__ == other.__class__
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self.__class__)
class BOOLEAN(primitive): class BOOLEAN(primitive):
def encode_decl(self, encoder): def encode_decl(self, encoder):
return encoder.encode_type(i_BOOLEAN) return encoder.encode_type(i_BOOLEAN)
...@@ -250,29 +369,66 @@ class STRING(primitive): ...@@ -250,29 +369,66 @@ class STRING(primitive):
def __repr__(self): def __repr__(self):
return "labcomm.STRING()" return "labcomm.STRING()"
class SAMPLE(primitive):
def encode_decl(self, encoder):
return encoder.encode_type(i_SAMPLE)
def encode(self, encoder, value):
if not isinstance(value, type_decl):
# Probably trying to encode a sample class, grab signature
value = value.signature
return encoder.encode_int(encoder.ref_to_index.get(value, 0))
def decode(self, decoder, obj=None):
return decoder.decode_ref()
def new_instance(self):
return ""
def __repr__(self):
return "labcomm.SAMPLE()"
# helper function
def dict_to_sorted_tuple(d):
tmpL = zip(d.keys(), d.values())
tmpL.sort()
return tuple(tmpL)
# #
# Aggregate types # Aggregate types
# #
class sample_or_typedef(object): class sampledef_or_sampleref_or_typedef(type_decl):
def __init__(self, name, decl): def __init__(self, intentions={}, decl=None):
self.name = name self.intentionDict = dict(intentions)
self.name = self.intentionDict.get('', None)
self.intentions = tuple(sorted(self.intentionDict.iteritems()))
self.decl = decl self.decl = decl
def encode_decl_tail(self, encoder): def encode_decl(self, encoder):
encoder.encode_type_number(self) encoder.encode_type(self.type_index)
encoder.encode_string(self.name) with length_encoder(encoder) as e1:
encoder.encode_type_number(self.decl) e1.encode_type(self.get_index(encoder))
# XXX: temporary hack for intentions
e1.encode_intentions(self.intentions)
with length_encoder(e1) as e2:
self.decl.encode_decl(e2)
def encode(self, encoder, object): def encode(self, encoder, value):
self.decl.encode(encoder, object) self.decl.encode(encoder, value)
def decode_decl(self, decoder): def decode_decl(self, decoder):
index = decoder.decode_type_number() index = decoder.decode_type_number()
name = decoder.decode_string() # XXX: temporary hack for intentions
# assume the name is the only intention
ints = decoder.decode_intentions()
if usePacketLength(decoder.version):
length = decoder.decode_packed32()
decl = decoder.decode_decl() decl = decoder.decode_decl()
result = self.__class__.__new__(self.__class__) result = self.__class__.__new__(self.__class__)
result.__init__(name, decl) result.__init__(intentions=ints, decl=decl)
decoder.add_decl(result, index) self.add_index(decoder, index, result)
return result return result
def decode(self, decoder, obj=None): def decode(self, decoder, obj=None):
...@@ -283,30 +439,81 @@ class sample_or_typedef(object): ...@@ -283,30 +439,81 @@ class sample_or_typedef(object):
def new_instance(self): def new_instance(self):
return self.decl.new_instance() return self.decl.new_instance()
def __repr__(self): def __eq__(self, other):
return "'%s', %s" % (self.name, self.decl) return (self.__class__ == other.__class__ and
self.name == other.name and
self.decl == other.decl)
class sample(sample_or_typedef): def __ne__(self, other):
def encode_decl(self, encoder): return not self.__eq__(other)
encoder.encode_type(i_SAMPLE)
self.encode_decl_tail(encoder) def __hash__(self):
return hash(self.__class__) ^ hash(self.name) ^ hash(self.decl)
def __repr__(self): def __repr__(self):
return "labcomm.sample(%s)" % super(sample, self).__repr__() return "%s('%s', %s)" % (self.type_name, self.name, self.decl)
class sample_def(sampledef_or_sampleref_or_typedef):
type_index = i_SAMPLE_DEF
type_name = 'sample'
def get_index(self, encoder):
return encoder.decl_to_index[self]
def add_index(self, decoder, index, decl):
decoder.add_decl(decl, index)
def rename(self, name):
newIntentions = dict(self.intentionDict)
newIntentions['']=name
return sample_def(newIntentions, decl=self.decl)
class sample_ref(sampledef_or_sampleref_or_typedef):
type_index = i_SAMPLE_REF
type_name = 'sample_ref'
def __init__(self, intentions={}, decl=None, sample=None):
self.intentionDict = dict(intentions)
self.name = self.intentionDict.get('', None) # XXX should we allow nameless?
self.decl = decl
self.intentions=tuple(sorted(self.intentionDict.iteritems()))
if sample == None and self.name != None and decl != None:
self.sample = sample_def(intentions, decl)
else:
self.sample = sample
def get_index(self, encoder):
return encoder.ref_to_index[self.sample]
def add_index(self, decoder, index, decl):
decoder.add_ref(decl, index)
class typedef(sampledef_or_sampleref_or_typedef):
type_index = i_TYPE_DEF
type_name = 'typedef'
class typedef(sample_or_typedef):
def encode_decl(self, encoder): def encode_decl(self, encoder):
encoder.encode_type(i_TYPEDEF) self.decl.encode_decl(encoder)
self.encode_decl_tail(encoder)
def __repr__(self): def encode(self, encoder, value):
return "labcomm.typedef(%s)" % super(typedef, self).__repr__() self.decl.encode(encoder, value)
class array(object): class array(type_decl):
def __init__(self, indices, decl): def __init__(self, indices, decl):
self.indices = indices self.indices = tuple(indices)
self.decl = decl self.decl = decl
def __eq__(self, other):
return (self.__class__ == other.__class__ and
self.indices == other.indices and
self.decl == other.decl)
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self.__class__) ^ hash(self.indices) ^ hash(self.decl)
def encode_decl(self, encoder): def encode_decl(self, encoder):
encoder.encode_type(i_ARRAY) encoder.encode_type(i_ARRAY)
encoder.encode_packed32(len(self.indices)) encoder.encode_packed32(len(self.indices))
...@@ -314,18 +521,26 @@ class array(object): ...@@ -314,18 +521,26 @@ class array(object):
encoder.encode_packed32(i) encoder.encode_packed32(i)
encoder.encode_type_number(self.decl) encoder.encode_type_number(self.decl)
def min_max_shape(self, l, depth=0, shape=[]): def min_max_shape(self, l, depth, shape):
if isinstance(l, list): if isinstance(l, types.StringTypes):
return shape
try:
length = len(l) length = len(l)
if len(shape) <= depth: if len(shape) <= depth:
shape.append((length, length)) shape.append((length, length))
pass
else: else:
(low, high) = shape[depth] (low, high) = shape[depth]
low = min(low, length) low = min(low, length)
high = max(high, length) high = max(high, length)
shape[depth] = (low, high) shape[depth] = (low, high)
pass
for e in l: for e in l:
shape = self.min_max_shape(e, depth + 1, shape) shape = self.min_max_shape(e, depth + 1, shape)
pass
pass
except TypeError:
pass
return shape return shape
def shape(self, l): def shape(self, l):
...@@ -341,7 +556,6 @@ class array(object): ...@@ -341,7 +556,6 @@ class array(object):
def encode_indices(self, encoder, value): def encode_indices(self, encoder, value):
depth = len(self.indices) depth = len(self.indices)
shape = self.shape(value) shape = self.shape(value)
#if len(shape) != len(self.indices):
if len(shape) < len(self.indices): if len(shape) < len(self.indices):
raise Exception("Actual dimension %s differs from declared %s" % raise Exception("Actual dimension %s differs from declared %s" %
(shape, self.indices)) (shape, self.indices))
...@@ -354,7 +568,7 @@ class array(object): ...@@ -354,7 +568,7 @@ class array(object):
return depth return depth
def encode_value(self, encoder, value, depth): def encode_value(self, encoder, value, depth):
if depth and isinstance(value, list): if depth:
for e in value: for e in value:
self.encode_value(encoder, e, depth - 1) self.encode_value(encoder, e, depth - 1)
else: else:
...@@ -411,66 +625,91 @@ class array(object): ...@@ -411,66 +625,91 @@ class array(object):
return "labcomm.array(%s,\n %s)" % ( return "labcomm.array(%s,\n %s)" % (
self.indices, indent(4, self.decl.__repr__())) self.indices, indent(4, self.decl.__repr__()))
class struct: class struct(type_decl):
def __init__(self, field): def __init__(self, field):
self.field = field self.field = tuple(field)
def __eq__(self, other):
return (self.__class__ == other.__class__ and
self.field == other.field)
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self.__class__) ^ hash(self.field)
def encode_decl(self, encoder): def encode_decl(self, encoder):
encoder.encode_type(i_STRUCT) encoder.encode_type(i_STRUCT)
encoder.encode_packed32(len(self.field)) encoder.encode_packed32(len(self.field))
for (name, decl) in self.field: for (intentions, decl) in self.field:
encoder.encode_string(name) encoder.encode_intentions(intentions)
encoder.encode_type_number(decl) encoder.encode_type_number(decl)
#type.encode_decl(encoder)
def encode(self, encoder, obj): def encode(self, encoder, obj):
if isinstance(obj, dict): try:
for (name, decl) in self.field: # hack to get names as keys in the obj:
decl.encode(encoder, obj[name]) tmp_foo = zip (map(lambda x:dict(x)[''],obj.keys()), obj.values())
else: tmp_obj = dict(tmp_foo)
for (name, decl) in self.field: for (intentions, decl) in self.field:
decl.encode(encoder, obj.__getattribute__(name)) tmp = dict(intentions)
name = tmp['']
decl.encode(encoder, tmp_obj[name])
except AttributeError:
print "HERE BE DRAGONS! hack to get duck-typing example to work"
for (intentions, decl) in self.field:
tmp = dict(intentions)
name = tmp['']
print "trying to encode [%s] " % (name)
decl.encode(encoder, getattr(obj, name))
def decode_decl(self, decoder): def decode_decl(self, decoder):
n_field = decoder.decode_packed32() n_field = decoder.decode_packed32()
field = [] field = []
for i in range(n_field): for i in range(n_field):
name = decoder.decode_string() ints = decoder.decode_intentions()
decl = decoder.decode_decl() decl = decoder.decode_decl()
field.append((name, decl)) field.append((ints, decl))
return struct(field) return struct(field)
def decode(self, decoder, obj=None): def decode(self, decoder, obj=None):
if obj == None: if obj == None:
obj = decoder.create_object() obj = decoder.create_object()
for (name, decl) in self.field: for (intentions, decl) in self.field:
obj.__setattr__(name, decl.decode(decoder)) #name = dict(intentions)['']
obj.__setattr__(intentions, decl.decode(decoder))
return obj return obj
def new_instance(self): def new_instance(self):
result = anonymous_object() result = anonymous_object()
for (name, decl) in self.field: for (intentions, decl) in self.field:
name = dict(intentions)['']
result.__setattr__(name, decl.new_instance()) result.__setattr__(name, decl.new_instance())
return result return result
def __repr__(self): def __repr__(self):
delim = "" delim = ""
result = "labcomm.struct([" result = "labcomm.struct(["
for (name, decl) in self.field: for (intentions, decl) in self.field:
try:
name = dict(intentions)['']
except:
name = '(no name)'
result += "%s\n ('%s', %s)" % (delim, name, decl) result += "%s\n ('%s', %s)" % (delim, name, decl)
delim = "," delim = ","
result += "\n])" result += "\n])"
return result return result
SAMPLE = sample(None, None) SAMPLE_DEF = sample_def()
TYPEDEF = typedef(None, None) SAMPLE_REF = sample_ref()
ARRAY = array(None, None) ARRAY = array([], None)
STRUCT = struct({}) STRUCT = struct([])
class anonymous_object(dict): class anonymous_object(dict):
def __setattr__(self, name, value): def __setattr__(self, name, value):
if name.startswith("_"): # XXX HERE BE DRAGONS! Is this OK:
if (str(name)).startswith("_"):
super(anonymous_object, self).__setattr__(name, value) super(anonymous_object, self).__setattr__(name, value)
else: else:
self[name] = value self[name] = value
...@@ -482,18 +721,23 @@ class anonymous_object(dict): ...@@ -482,18 +721,23 @@ class anonymous_object(dict):
return self[name] return self[name]
class Codec(object): class Codec(object):
def __init__(self): def __init__(self, codec=None):
self.type_to_name = {} self.type_to_name = codec and codec.type_to_name or {}
self.name_to_type = {} self.name_to_type = codec and codec.name_to_type or {}
self.index_to_decl = {} self.index_to_decl = codec and codec.index_to_decl or {}
self.decl_to_index = {} self.decl_to_index = codec and codec.decl_to_index or {}
self.name_to_decl = {} self.name_to_decl = codec and codec.name_to_decl or {}
self.decl_index = i_USER self.index_to_ref = codec and codec.index_to_ref or {}
self.ref_to_index = codec and codec.ref_to_index or {}
self.name_to_ref = codec and codec.name_to_ref or {}
self.decl_index = codec and codec.decl_index or i_USER
self.ref_index = codec and codec.ref_index or i_USER
if not codec:
self.predefined_types() self.predefined_types()
def predefined_types(self): def predefined_types(self):
self.add_decl(TYPEDEF, i_TYPEDEF) self.add_decl(SAMPLE_DEF, i_SAMPLE_DEF)
self.add_decl(SAMPLE, i_SAMPLE) self.add_decl(SAMPLE_REF, i_SAMPLE_REF)
self.add_decl(ARRAY, i_ARRAY) self.add_decl(ARRAY, i_ARRAY)
self.add_decl(STRUCT, i_STRUCT) self.add_decl(STRUCT, i_STRUCT)
...@@ -506,9 +750,12 @@ class Codec(object): ...@@ -506,9 +750,12 @@ class Codec(object):
self.add_decl(FLOAT(), i_FLOAT) self.add_decl(FLOAT(), i_FLOAT)
self.add_decl(DOUBLE(), i_DOUBLE) self.add_decl(DOUBLE(), i_DOUBLE)
self.add_decl(STRING(), i_STRING) self.add_decl(STRING(), i_STRING)
self.add_decl(SAMPLE(), i_SAMPLE)
def add_decl(self, decl, index=0): def add_decl(self, decl, index=0):
if index == 0: if index == 0:
if decl in self.decl_to_index:
return False
index = self.decl_index index = self.decl_index
self.decl_index += 1 self.decl_index += 1
self.index_to_decl[index] = decl self.index_to_decl[index] = decl
...@@ -517,6 +764,24 @@ class Codec(object): ...@@ -517,6 +764,24 @@ class Codec(object):
self.name_to_decl[decl.name] = decl self.name_to_decl[decl.name] = decl
except: except:
pass pass
return True
def add_ref(self, ref, index=0):
if not isinstance(ref, type_decl):
# Probably trying to register a sample class, grab signature
ref = ref.signature
if index == 0:
if ref.sample in self.ref_to_index:
return False
index = self.ref_index
self.ref_index += 1
self.index_to_ref[index] = ref.sample
self.ref_to_index[ref.sample] = index
try:
self.name_to_ref[ref.sample.name] = ref.sample
except:
pass
return True
def add_binding(self, name, decl): def add_binding(self, name, decl):
self.type_to_name[decl] = name self.type_to_name[decl] = name
...@@ -534,26 +799,53 @@ class Codec(object): ...@@ -534,26 +799,53 @@ class Codec(object):
class Encoder(Codec): class Encoder(Codec):
def __init__(self, writer): def __init__(self, writer, version=DEFAULT_VERSION, codec=None):
super(Encoder, self).__init__() super(Encoder, self).__init__(codec)
self.writer = writer self.writer = writer
self.version = version
if self.version in [ "LabComm2014" ]:
self.encode_type(i_VERSION)
with length_encoder(self) as e:
e.encode_string(version)
elif self.version in [ None, "LabComm2006" ]:
pass
else:
raise Exception("Unsupported labcomm version %s" % self.version)
def pack(self, format, *args): def pack(self, format, *args):
self.writer.write(packer.pack(format, *args)) self.writer.write(packer.pack(format, *args))
def add_decl(self, decl, index=0): def add_decl(self, decl, index=0):
super(Encoder, self).add_decl(decl, index) if not isinstance(decl, type_decl):
decl = decl.signature
if index == 0: if index == 0:
self.writer.mark_begin(decl, None)
if super(Encoder, self).add_decl(decl, index):
decl.encode_decl(self) decl.encode_decl(self)
self.writer.mark() self.writer.mark_end(decl, None)
def add_ref(self, ref, index=0):
if not isinstance(ref, type_decl):
# Trying to register a sample class
ref = ref.signature
decl = sample_ref(intentions=ref.intentions, decl=ref.decl, sample=ref)
if index == 0:
self.writer.mark_begin(ref, None)
if super(Encoder, self).add_ref(decl, index):
decl.encode_decl(self)
self.writer.mark_end(ref, None)
def encode(self, object, decl=None): def encode(self, object, decl=None):
if decl == None: if decl == None:
name = self.type_to_name[object.__class__] name = self.type_to_name[object.__class__]
decl = self.name_to_decl[name] decl = self.name_to_decl[name]
if not isinstance(decl, type_decl):
decl = decl.signature
self.writer.mark_begin(decl, object)
self.encode_type_number(decl) self.encode_type_number(decl)
decl.encode(self, object) with length_encoder(self) as e:
self.writer.mark() decl.encode(e, object)
self.writer.mark_end(decl, object)
def encode_type_number(self, decl): def encode_type_number(self, decl):
try: try:
...@@ -562,6 +854,7 @@ class Encoder(Codec): ...@@ -562,6 +854,7 @@ class Encoder(Codec):
decl.encode_decl(self) decl.encode_decl(self)
def encode_packed32(self, v): def encode_packed32(self, v):
if self.version in [ None, "LabComm2014" ]:
v = v & 0xffffffff v = v & 0xffffffff
tmp = [ v & 0x7f ] tmp = [ v & 0x7f ]
v = v >> 7 v = v >> 7
...@@ -570,10 +863,14 @@ class Encoder(Codec): ...@@ -570,10 +863,14 @@ class Encoder(Codec):
v = v >> 7 v = v >> 7
for c in reversed(tmp): for c in reversed(tmp):
self.encode_byte(c) self.encode_byte(c)
elif self.version == "LabComm2006" :
v = v & 0xffffffff
self.encode_int(v)
else :
raise Exception("Unsupported labcomm version %s" % self.version)
def encode_type(self, index): def encode_type(self, index):
self.encode_packed32(index) self.encode_packed32(index)
# self.pack("!i", index)
def encode_boolean(self, v): def encode_boolean(self, v):
if v: if v:
...@@ -582,7 +879,7 @@ class Encoder(Codec): ...@@ -582,7 +879,7 @@ class Encoder(Codec):
self.pack("!b", 0) self.pack("!b", 0)
def encode_byte(self, v): def encode_byte(self, v):
self.pack("!b", v) self.pack("!B", v)
def encode_short(self, v): def encode_short(self, v):
self.pack("!h", v) self.pack("!h", v)
...@@ -603,12 +900,25 @@ class Encoder(Codec): ...@@ -603,12 +900,25 @@ class Encoder(Codec):
s = v.encode("utf8") s = v.encode("utf8")
self.encode_packed32(len(s)); self.encode_packed32(len(s));
self.pack("%ds" % len(s),s) self.pack("%ds" % len(s),s)
# self.pack("!i%ds" % len(s), len(s), s)
def encode_intentions(self, intentions):
self.encode_packed32(len(intentions))
try:
for (k,v) in intentions:
self.encode_string(k)
self.encode_string(v)
except:
print "WARNING! encode_intentions: don't know what to do with %s" % intentions
class Decoder(Codec): class Decoder(Codec):
def __init__(self, reader): def __init__(self, reader, version=DEFAULT_VERSION):
super(Decoder, self).__init__() super(Decoder, self).__init__()
self.reader = reader self.reader = reader
self.version = version
self.handlers = {}
def register_handler(self, decl, handler):
self.handlers[decl] = handler
def unpack(self, format): def unpack(self, format):
size = packer.calcsize(format) size = packer.calcsize(format)
...@@ -623,15 +933,73 @@ class Decoder(Codec): ...@@ -623,15 +933,73 @@ class Decoder(Codec):
result = self.index_to_decl[index] result = self.index_to_decl[index]
if index < i_USER: if index < i_USER:
result = result.decode_decl(self) result = result.decode_decl(self)
else:
raise Exception('Should not be used')
return result return result
def skip(self, length):
for _ in xrange(length):
self.decode_byte()
# kludge, should really check if the index exists in self.version
def skip_or_raise(self, length, index):
if usePacketLength(self.version):
self.skip(length)
else:
raise Exception("Invalid type index %d" % index)
def runOne(self):
data,decl = self.decode()
# decode any signatures until next sample
while data == None:
data,decl = self.decode()
if decl:
if data != None:
if decl in self.handlers:
handler = self.handlers[decl]
handler(data)
else:
print ("No handler for %s" % decl.name )
for key, value in self.handlers.iteritems():
if key == decl:
print "but value %s == decl %s" % (key,decl)
print "hashes %d : %d" % (hash(key),hash(decl))
raise Exception()
def decode(self): def decode(self):
value = None while True:
index = self.decode_type_number() index = self.decode_type_number()
decl = self.index_to_decl[index] if usePacketLength(self.version):
if index == i_TYPEDEF or index == i_SAMPLE: length = self.decode_packed32()
decl = decl.decode_decl(self) if index != i_VERSION:
break
else: else:
other_version = self.decode_string()
if self.version != other_version:
raise Exception("LabComm version mismatch %s != %s" %
(version, other_version))
if index == i_SAMPLE_DEF:
decl = self.index_to_decl[index].decode_decl(self)
value = None
elif index == i_SAMPLE_REF:
decl = self.index_to_decl[index].decode_decl(self)
value = None
elif index == i_TYPE_DEF:
self.skip_or_raise(length, index)
decl = None
value = None
elif index == i_TYPE_BINDING:
self.skip_or_raise(length, index)
decl = None
value = None
elif index == i_PRAGMA:
self.skip_or_raise(length, index)
decl = None
value = None
elif index < i_USER:
raise Exception("Invalid type index %d" % index)
else:
decl = self.index_to_decl[index]
value = decl.decode(self) value = decl.decode(self)
self.reader.mark(value, decl) self.reader.mark(value, decl)
return (value, decl) return (value, decl)
...@@ -650,6 +1018,7 @@ class Decoder(Codec): ...@@ -650,6 +1018,7 @@ class Decoder(Codec):
return result return result
def decode_packed32(self): def decode_packed32(self):
if self.version in [ "LabComm2013", "LabComm2014" ] :
result = 0 result = 0
while True: while True:
tmp = self.decode_byte() tmp = self.decode_byte()
...@@ -657,6 +1026,10 @@ class Decoder(Codec): ...@@ -657,6 +1026,10 @@ class Decoder(Codec):
if (tmp & 0x80) == 0: if (tmp & 0x80) == 0:
break break
return result return result
elif self.version == "LabComm2006" :
return self.decode_int()
else :
raise Exception("Unsupported labcomm version %s" % self.version)
def decode_type_number(self): def decode_type_number(self):
return self.decode_packed32() return self.decode_packed32()
...@@ -665,7 +1038,7 @@ class Decoder(Codec): ...@@ -665,7 +1038,7 @@ class Decoder(Codec):
return self.unpack("!b") != 0 return self.unpack("!b") != 0
def decode_byte(self): def decode_byte(self):
return self.unpack("!b") return self.unpack("!B")
def decode_short(self): def decode_short(self):
return self.unpack("!h") return self.unpack("!h")
...@@ -686,6 +1059,19 @@ class Decoder(Codec): ...@@ -686,6 +1059,19 @@ class Decoder(Codec):
length = self.decode_packed32() length = self.decode_packed32()
return self.unpack("!%ds" % length).decode("utf8") return self.unpack("!%ds" % length).decode("utf8")
def decode_ref(self):
index = self.decode_int()
return self.index_to_ref.get(index, None)
def decode_intentions(self):
numIntentions = self.decode_packed32()
res = {}
for i in range(numIntentions):
key = self.decode_string()
val = self.decode_string()
res[key] = val
result = dict_to_sorted_tuple(res)
return result
class signature_reader: class signature_reader:
def __init__(self, signature): def __init__(self, signature):
......
class StreamReader:
def __init__(self, stream):
self.stream = stream
pass
def read(self, count):
result = self.stream.read(count)
if len(result) == 0:
raise EOFError()
return result
def mark(self, value, decl):
pass
pass
class StreamWriter:
def __init__(self, stream):
self.stream = stream
pass
def write(self, data):
self.stream.write(data)
pass
def mark_begin(self, decl, value):
pass
def mark_end(self, decl, value):
self.stream.flush()
pass
pass
__all__ = [ 'LabComm' ]
import LabComm
from StreamReader import StreamReader
from StreamWriter import StreamWriter
Decoder = LabComm.Decoder
Encoder = LabComm.Encoder
sample = LabComm.sample_def
sample_def = LabComm.sample_def
sample_ref = LabComm.sample_ref
typedef = LabComm.typedef
array = LabComm.array
struct = LabComm.struct
primitive = LabComm.primitive
BOOLEAN = LabComm.BOOLEAN
BYTE = LabComm.BYTE
SHORT = LabComm.SHORT
INTEGER = LabComm.INTEGER
LONG = LabComm.LONG
FLOAT = LabComm.FLOAT
DOUBLE = LabComm.DOUBLE
STRING = LabComm.STRING
SAMPLE = LabComm.SAMPLE
decl_from_signature = LabComm.decl_from_signature
labcomm2014-*.src.rpm
rpmbuild
.PHONY: all
all:
.PHONY: test
test:
.PHONY: clean
clean:
rm -rf rpmbuild
rm -f *~
.PHONY: distclean
distclean: clean
rm -f labcomm-*.src.rpm
.PHONY: srpm
srpm:
./make_srpm
#!/bin/sh
spec() {
cat << 'EOF'
Name: labcomm__SUFFIX__
Version: __VERSION__
Release: 1
Summary: LabComm communication protocol
License: GPLv3
# https://gitlab.control.lth.se/anders_blomdell/labcomm/repository/archive.tar.gz?__COMMIT__
Source0: labcomm.__DESCRIBE__.tar.gz
BuildRequires: gcc
BuildRequires: ant
BuildRequires: java
BuildRequires: mono-core
%description
LabComm communication protocol
%package devel
Summary: LabComm communication protocol
Requires: %{name} = %{version}-%{release}
%description devel
LabComm communication protocol
%
%prep
%setup -q -c -a 0
%build
pwd
make
%install
#
# C
#
install -d ${RPM_BUILD_ROOT}/%{_libdir}
install lib/c/liblabcomm2014.a ${RPM_BUILD_ROOT}/%{_libdir}/
install lib/c/liblabcomm2014.so.1 ${RPM_BUILD_ROOT}/%{_libdir}/liblabcomm2014.so.__VERSION__
ln -s liblabcomm2014.so.__VERSION__ ${RPM_BUILD_ROOT}/%{_libdir}/liblabcomm2014.so
install -d ${RPM_BUILD_ROOT}/%{_includedir}/labcomm
install lib/c/2014/*h ${RPM_BUILD_ROOT}/%{_includedir}/labcomm
#
# java
#
install -d ${RPM_BUILD_ROOT}/usr/lib
install -m u=r,g=r,o=r compiler/labcomm2014_compiler.jar ${RPM_BUILD_ROOT}/usr/lib
install -m u=r,g=r,o=r lib/java/labcomm2014.jar ${RPM_BUILD_ROOT}/usr/lib
install -d ${RPM_BUILD_ROOT}/%{_bindir}
install -m u=rx,g=rx,o=rx \
compiler/labcomm2014 ${RPM_BUILD_ROOT}/%{_bindir}/labcomm2014
ls -l ${RPM_BUILD_ROOT}/%{_bindir}
#
# C#
#
install -d ${RPM_BUILD_ROOT}/usr/lib
install -m u=r,g=r,o=r lib/csharp/labcomm2014.dll ${RPM_BUILD_ROOT}/usr/lib
#
# Python
#
install -d ${RPM_BUILD_ROOT}/%{python_sitelib}/labcomm2014
install lib/python/labcomm2014/* ${RPM_BUILD_ROOT}/%{python_sitelib}/labcomm2014
%files
%defattr (-, root, root)
%exclude /usr/lib/debug
%exclude /usr/lib/labcomm2014_compiler.jar
/usr/lib/*
%{_libdir}/*
%files devel
%defattr (-, root, root)
/usr/lib/labcomm2014_compiler.jar
%{_includedir}/labcomm/*
%{_bindir}/*
EOF
}
# Create a suitable directory for rpmbuild
rm -rf rpmbuild
mkdir -p rpmbuild/BUILD
mkdir -p rpmbuild/SPECS
mkdir -p rpmbuild/RPMS
mkdir -p rpmbuild/SRPMS
mkdir -p rpmbuild/SOURCES
rm -rf rpmbuild/SOURCES/*
# Create spec and .tar.gz
DESCRIBE=$(git describe | sed -e 's/^v\(.*\)/\1/')
SUFFIX=$(echo ${DESCRIBE} | sed -e 's/^\([^.]*\)[.].*$/\1/g')
VERSION=$(echo ${DESCRIBE} | sed -e 's/^[^.]*[.]\(.*\)/\1/g;s/-/./g')
COMMIT=$(git rev-parse HEAD)
(
spec | \
sed -e "s/__SUFFIX__/${SUFFIX}/g" | \
sed -e "s/__VERSION__/${VERSION}/g" | \
sed -e "s/__DESCRIBE__/${DESCRIBE}/g" | \
sed -e "s/__COMMIT__/${COMMIT}/g" \
) > rpmbuild/SPECS/labcomm.spec
(
cd $(git rev-parse --show-toplevel)
git archive --format tar HEAD
) > rpmbuild/SOURCES/labcomm.${DESCRIBE}.tar.gz
rpmbuild --define "_topdir $(pwd)/rpmbuild" \
-bs rpmbuild/SPECS/labcomm.spec 2>&1 | sed -e 's|rpmbuild/SRPMS/||g'
mv rpmbuild/SRPMS/* .
gen
TESTS=basic simple nested TESTS=basic simple nested ref
LABCOMM_JAR=../compiler/labComm.jar LABCOMM_JAR=../compiler/labcomm2014_compiler.jar
LABCOMM=java -jar $(LABCOMM_JAR) LABCOMM=java -jar $(LABCOMM_JAR)
MONO_PATH=$(shell pwd)/../lib/csharp
PYTHONPATH=$(shell pwd)/../lib/python
all: $(TESTS:%=test_%) include ../lib/c/os_compat.mk
all:
test: $(TESTS:%=test_%) $(TESTS:%=test_renaming_%) compiler_errors
# PYTHONPATH=../lib/python \ # PYTHONPATH=../lib/python \
# ./test_encoder_decoder.py --labcomm="$(LABCOMM)" basic.lc # ./test_encoder_decoder.py --labcomm="$(LABCOMM)" basic.lc
.PHONY: clean .PHONY: clean distclean
clean: clean distclean:
rm -rf gen rm -rf gen
.PHONY: test_% .PHONY: test_%
...@@ -16,28 +22,63 @@ test_%: gen/%/signatures.py \ ...@@ -16,28 +22,63 @@ test_%: gen/%/signatures.py \
gen/%/cs_relay.exe \ gen/%/cs_relay.exe \
gen/%/java_relay.class \ gen/%/java_relay.class \
gen/%/java_code gen/%/java_code
PYTHONPATH=../lib/python ./test_encoder_decoder.py \ PYTHONPATH=$(PYTHONPATH) MONO_PATH=$(MONO_PATH) \
./test_encoder_decoder.py \
--signatures=gen/$*/signatures.py \ --signatures=gen/$*/signatures.py \
--test /bin/tee gen/$*/testdata \ --test tee gen/$*/testdata \
--test gen/$*/c_relay /dev/stdin /dev/stdout \ --test $(shell echo $(VALGRIND) | sed -e 's/[-][-]/\\\\--/g') \
gen/$*/c_relay /dev/stdin /dev/stdout \
--test mono gen/$*/cs_relay.exe /dev/stdin /dev/stdout \ --test mono gen/$*/cs_relay.exe /dev/stdin /dev/stdout \
--test java \\-cp gen/$*:../lib/java/labcomm.jar java_relay \ --test java \\-cp gen/$*:../lib/java/labcomm2014.jar \
java_relay /dev/stdin /dev/stdout
.PHONY: test_renaming_%
test_renaming_%: gen/%/signatures.py \
gen/%/c_renaming_relay \
gen/%/cs_renaming_relay.exe \
gen/%/java_relay.class \
gen/%/java_code
PYTHONPATH=$(PYTHONPATH) MONO_PATH=$(MONO_PATH) \
./test_renaming_encoder_decoder.py \
--signatures=gen/$*/signatures.py \
--test tee gen/$*/testdata.renamed \
--test $(shell echo $(VALGRIND) | sed -e 's/[-][-]/\\\\--/g') \
gen/$*/c_renaming_relay /dev/stdin /dev/stdout \
--test mono gen/$*/cs_renaming_relay.exe \
/dev/stdin /dev/stdout /dev/stdin /dev/stdout
.PRECIOUS: gen/%/ echo \
gen/%/: --test java \\-cp gen/$*:../lib/java/labcomm2014.jar \
mkdir -p $@ java_relay /dev/stdin /dev/stdout
# test cases for compiler error checking
.PHONY: compiler_errors testErrorsOK testErrorsNOK
compiler_errors: testErrorsOK testErrorsNOK
# tests that should succeed
testErrorsOK: $(wildcard errors/correct/*.lc)
./test_errors.py --labcomm="$(LABCOMM)" --testOK $^
# tests that should fail
testErrorsNOK: $(wildcard errors/incorrect/*.lc)
./test_errors.py --labcomm="$(LABCOMM)" --testNOK $^
.PRECIOUS: gen/%/.dir
gen/%/.dir:
mkdir -p gen/$*
touch $@
.PRECIOUS: gen/%/typeinfo .PRECIOUS: gen/%/typeinfo
gen/%/typeinfo: %.lc Makefile | gen/%/ gen/%/typeinfo: %.lc Makefile | gen/%/.dir
$(LABCOMM) --typeinfo=$@ $< $(LABCOMM) --typeinfo=$@ $<
.PRECIOUS: gen/%/signatures.py .PRECIOUS: gen/%/signatures.py
gen/%/signatures.py: %.lc Makefile | gen/%/ gen/%/signatures.py: %.lc Makefile | gen/%/.dir
$(LABCOMM) --python=$@ $< $(LABCOMM) --python=$@ $<
# C relay test rules # C relay test rules
.PRECIOUS: gen/%/c_code.h gen/%/c_code.c .PRECIOUS: gen/%/c_code.h gen/%/c_code.c
gen/%/c_code.h gen/%/c_code.c: %.lc Makefile | gen/%/ gen/%/c_code.h gen/%/c_code.c: %.lc Makefile | gen/%/.dir
$(LABCOMM) --c=gen/$*/c_code.c --h=gen/$*/c_code.h $< $(LABCOMM) --c=gen/$*/c_code.c --h=gen/$*/c_code.h $<
.PRECIOUS: gen/%/c_relay.c .PRECIOUS: gen/%/c_relay.c
...@@ -46,35 +87,43 @@ gen/%/c_relay.c: gen/%/typeinfo relay_gen_c.py Makefile ...@@ -46,35 +87,43 @@ gen/%/c_relay.c: gen/%/typeinfo relay_gen_c.py Makefile
.PRECIOUS: gen/%/c_relay .PRECIOUS: gen/%/c_relay
gen/%/c_relay: gen/%/c_relay.c gen/%/c_code.c Makefile gen/%/c_relay: gen/%/c_relay.c gen/%/c_code.c Makefile
$(CC) $(CFLAGS) -o $@ $< -I../lib/c -I. \ $(CC) $(CFLAGS) -o $@ $< -I../lib/c/2014 -I. -L../lib/c \
-DLABCOMM_FD_OMIT_VERSION \ gen/$*/c_code.c -llabcomm2014
-DLABCOMM_ENCODER_LINEAR_SEARCH \
gen/$*/c_code.c \ .PRECIOUS: gen/%/c_renaming_relay.c
../lib/c/labcomm.c \ gen/%/c_renaming_relay.c: gen/%/typeinfo relay_gen_c.py Makefile
../lib/c/labcomm_fd_*.c \ ./relay_gen_c.py --renaming $< > $@
../lib/c/labcomm_dynamic_buffer_writer.c
.PRECIOUS: gen/%/c_renaming_relay
gen/%/c_renaming_relay: gen/%/c_renaming_relay.c gen/%/c_code.c Makefile
$(CC) $(CFLAGS) -o $@ $< -I../lib/c/2014 -I. -L../lib/c \
gen/$*/c_code.c -llabcomm2014
# C# relay test rules # C# relay test rules
.PRECIOUS: gen/%/cs_code.cs .PRECIOUS: gen/%/cs_code.cs
gen/%/cs_code.cs: %.lc Makefile | gen/%/ gen/%/cs_code.cs: %.lc Makefile | gen/%/.dir
$(LABCOMM) --cs=$@ $< $(LABCOMM) --cs=$@ $<
.PRECIOUS: gen/%/cs_relay.cs .PRECIOUS: gen/%/cs_relay.cs
gen/%/cs_relay.cs: gen/%/typeinfo relay_gen_cs.py Makefile gen/%/cs_relay.cs: gen/%/typeinfo relay_gen_cs.py Makefile
./relay_gen_cs.py $< > $@ ./relay_gen_cs.py $< > $@
.PRECIOUS: gen/%/labcomm.dll
gen/%/labcomm.dll:
ln -s ../../../lib/csharp/labcomm.dll $@
.PRECIOUS: gen/%/cs_relay.exe .PRECIOUS: gen/%/cs_relay.exe
gen/%/cs_relay.exe: gen/%/cs_relay.cs gen/%/cs_code.cs \ gen/%/cs_relay.exe: gen/%/cs_relay.cs gen/%/cs_code.cs Makefile
gen/%/labcomm.dll Makefile mcs -out:$@ $(filter %.cs, $^) -lib:../lib/csharp/ -r:labcomm2014
mcs -out:$@ $(filter %.cs, $^) -lib:../lib/csharp/ -r:labcomm
.PRECIOUS: gen/%/cs_renaming_relay.cs
gen/%/cs_renaming_relay.cs: gen/%/typeinfo relay_gen_cs.py Makefile
./relay_gen_cs.py --renaming $< > $@
.PRECIOUS: gen/%/cs_renaming_relay.exe
gen/%/cs_renaming_relay.exe: gen/%/cs_renaming_relay.cs \
gen/%/cs_code.cs Makefile
mcs -out:$@ $(filter %.cs, $^) -lib:../lib/csharp/ -r:labcomm2014
# Java relay test rules # Java relay test rules
.PRECIOUS: gen/%/java_code .PRECIOUS: gen/%/java_code
gen/%/java_code: %.lc | gen/%/ gen/%/java_code: %.lc | gen/%/.dir
mkdir -p $@ mkdir -p $@
$(LABCOMM) --java=$@ $< $(LABCOMM) --java=$@ $<
...@@ -84,4 +133,4 @@ gen/%/java_relay.java: gen/%/typeinfo relay_gen_java.py Makefile ...@@ -84,4 +133,4 @@ gen/%/java_relay.java: gen/%/typeinfo relay_gen_java.py Makefile
.PRECIOUS: gen/%/java_relay.class .PRECIOUS: gen/%/java_relay.class
gen/%/java_relay.class: gen/%/java_relay.java gen/%/java_code Makefile gen/%/java_relay.class: gen/%/java_relay.java gen/%/java_code Makefile
javac -d gen/$* -cp ../lib/java/labcomm.jar:gen/$*/java_code $< javac -d gen/$* -cp ../lib/java/labcomm2014.jar:gen/$*/java_code $<
typedef struct {
string topic;
} pubsub;
sample pubsub subscribe;
sample pubsub unsubscribe;
sample pubsub publish;
sample pubsub unpublish;
typedef void avoid;
sample avoid doavoid;
// examples of errors: void may not be used
// in structs or arrays
//
// sample struct {
// int a;
// avoid error;
//} foo;
//
//sample void error2[2] ;
//sample avoid error3[_];
typedef void avoid;
// examples of errors: void may not be used
// in structs or arrays
//
sample struct {
int a;
avoid error_1;
} foo;
sample void error_2[2] ;
sample avoid error_3[_];