diff --git a/compiler/CS_CodeGen.jrag b/compiler/CS_CodeGen.jrag index 9c6278a23f55af2e8c06c28f6ef874e5f127b3dd..c147dc6da26ea3a57bab97c551c31a64aad1a78e 100644 --- a/compiler/CS_CodeGen.jrag +++ b/compiler/CS_CodeGen.jrag @@ -645,6 +645,10 @@ aspect CS_Class { " not declared"); } + public boolean VoidType.CS_needInstance() { + return false; + } + public boolean PrimType.CS_needInstance() { return false; } @@ -772,13 +776,15 @@ aspect CS_Info { public void TypeDecl.CS_info(CS_env env, String namespace) { env.print(";C#;typedef;" + namespace + getName() + ";"); - getType().CS_emitType(env); + getType().CS_emitType(env) ; + env.print(";not_applicable_for_C#"); env.println(); } public void SampleDecl.CS_info(CS_env env, String namespace) { env.print(";C#;sample;" + namespace + getName() + ";"); getType().CS_emitType(env); + env.print(";not_applicable_for_C#"); env.println(); } diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag index 4d4c76b4c7b9f1c754aa5b7119cfe849318ae5f2..e2e04baac6435830a280165aa77d055d512aa071 100644 --- a/compiler/C_CodeGen.jrag +++ b/compiler/C_CodeGen.jrag @@ -371,8 +371,10 @@ aspect C_Declarations { env.println("int labcomm"+env.verStr+"_encode_" + env.prefix + getName() + "("); env.indent(); - env.println("struct labcomm"+env.verStr+"_encoder *e,"); - env.println(env.prefix + getName() + " *v"); + env.println("struct labcomm"+env.verStr+"_encoder *e"); + if(!isVoid() ) { + env.println(", "+env.prefix + getName() + " *v"); + } env.unindent(); env.println(");"); @@ -700,8 +702,10 @@ aspect C_Encoder { env = env.nestStruct("(*v)"); env.println("static int encode_" + env.prefix + getName() + "("); env.indent(); - env.println("struct labcomm"+env.verStr+"_writer *w,"); - env.println(env.prefix + getName() + " *v"); + env.println("struct labcomm"+env.verStr+"_writer *w"); + if(!isVoid() ) { + env.println(", "+env.prefix + getName() + " *v"); + } env.unindent(); env.println(")"); env.println("{"); @@ -714,16 +718,19 @@ aspect C_Encoder { // Typesafe encode wrapper env.println("int labcomm"+env.verStr+"_encode_" + env.prefix + getName() + "("); - env.println("struct labcomm"+env.verStr+"_encoder *e,"); - env.println(env.prefix + getName() + " *v"); + env.println("struct labcomm"+env.verStr+"_encoder *e"); + if(!isVoid() ) { + env.println(", "+env.prefix + getName() + " *v"); + } env.unindent(); env.println(")"); env.println("{"); env.indent(); env.println("return labcomm"+env.verStr+"_internal_encode(e, &labcomm"+env.verStr+"_signature_" + env.prefix + getName() + - ", (labcomm"+env.verStr+"_encoder_function)encode_" + env.prefix + getName() + - ", v);"); + ", (labcomm"+env.verStr+"_encoder_function)encode_" + + env.prefix + getName() + + (!isVoid()?", v":", NULL")+");"); env.unindent(); env.println("}"); } @@ -745,7 +752,7 @@ aspect C_Encoder { } public void UserType.C_emitEncoder(C_env env) { - lookupType(getName()).getType().C_emitEncoder(env); + decl().getType().C_emitEncoder(env); } public void StructType.C_emitEncoder(C_env env) { @@ -1156,12 +1163,23 @@ aspect C_Info { public void TypeDecl.C_info(C_env env) { env.println(",C,typedef," + env.prefix + getName() + "," + - env.prefix + getName()); + env.prefix + getName() + "," + + C_info_type_or_void(env.prefix)); } public void SampleDecl.C_info(C_env env) { env.println(",C,sample," + env.prefix + getName() + "," + - env.prefix + getName()); + env.prefix + getName() + "," + + C_info_type_or_void(env.prefix)); } + // make void types explicitly as they require special treatment + // in encoder/decoder calls + protected String Decl.C_info_type_or_void(String prefix) { + if(isVoid() ) { + return "void"; + } else { + return prefix + getName() ; + } + } } diff --git a/compiler/DeclNames.jrag b/compiler/DeclNames.jrag new file mode 100644 index 0000000000000000000000000000000000000000..4e58087cd269406ec4db3970c7cf90a8f2242051 --- /dev/null +++ b/compiler/DeclNames.jrag @@ -0,0 +1,7 @@ +aspect DeclNames { + inh String Type.declName(); + eq Decl.getType().declName() = getName(); + + inh String Field.declName(); + eq StructType.getField(int i).declName() = declName(); +} diff --git a/compiler/ErrorCheck.jrag b/compiler/ErrorCheck.jrag index b1e255ecdcbc33685fd91e40f7ee2639b9a80587..caa80815456d4c1a390f2f80f7a5a7e5f74c0b8d 100644 --- a/compiler/ErrorCheck.jrag +++ b/compiler/ErrorCheck.jrag @@ -20,6 +20,7 @@ aspect ErrorCheck { } public void ASTNode.errorCheck(Collection collection) { nameCheck(); + typeCheck(); if(hasErrors()) collection.add(errors); for(int i = 0; i < getNumChild(); i++) { diff --git a/compiler/Java_CodeGen.jrag b/compiler/Java_CodeGen.jrag index 7b7aab4844f754cebdeac65f7ec8a9777b304ac8..b01ff8f02e5052fd9979c69ed60bee9e32768586 100644 --- a/compiler/Java_CodeGen.jrag +++ b/compiler/Java_CodeGen.jrag @@ -196,6 +196,7 @@ aspect Java_StructName { aspect Java_Void { syn boolean Decl.isVoid() = getType().isVoid(); + syn boolean UserType.isVoid() = decl().isVoid(); syn boolean Type.isVoid() = false; syn boolean VoidType.isVoid() = true; @@ -746,6 +747,10 @@ aspect Java_Class { " not declared"); } + public boolean VoidType.Java_needInstance() { + return false; + } + public boolean PrimType.Java_needInstance() { return false; } @@ -864,13 +869,15 @@ aspect Java_Info { public void TypeDecl.Java_info(Java_env env) { env.print(",Java,typedef," + getName() + ","); - getType().Java_emitType(env); + getType().Java_emitType(env); + env.print(",not_applicable_for_Java"); env.println(); } public void SampleDecl.Java_info(Java_env env) { env.print(",Java,sample," + getName() + ","); getType().Java_emitType(env); + env.print(",not_applicable_for_Java"); env.println(); } diff --git a/compiler/LabComm.ast b/compiler/LabComm.ast index 7b11255bac395e1b6d0989d1d45f5231c1850a5c..6f290e58d497c19dc4f78ffb443fe6dd3278944a 100644 --- a/compiler/LabComm.ast +++ b/compiler/LabComm.ast @@ -12,7 +12,7 @@ PrimType : Type ::= <Name:String> <Token:int>; UserType : Type ::= <Name:String>; StructType : Type ::= Field*; ParseArrayType : Type ::= Type Dim*; -abstract ArrayType : Type ::= Type Exp*; +abstract ArrayType :Type ::= Type Exp*; VariableArrayType : ArrayType; FixedArrayType : ArrayType; diff --git a/compiler/LabComm.java b/compiler/LabComm.java index c1c7251f9bb622b617d6acf5a1005c6d05eb581d..c86125a5c17df193402c526d6f2d688602632c35 100644 --- a/compiler/LabComm.java +++ b/compiler/LabComm.java @@ -249,6 +249,10 @@ public class LabComm { if (prettyOnStdout) { ast.pp(System.out); } + } else { + // Catch-all for compilation errors + System.err.println("Error in specification"); + System.exit(3); } } } diff --git a/compiler/LabCommParser.parser b/compiler/LabCommParser.parser index 8bef9036102cb7cc6e5c7bd2a9742cc80b225dd9..dea1194a0c06dc7ce19a9813000d9591c4dc40b3 100644 --- a/compiler/LabCommParser.parser +++ b/compiler/LabCommParser.parser @@ -14,7 +14,7 @@ s.append(" *** Syntactic error: unexpected token " + Terminals.NAMES[token.getId()]); throw new SourceError(s.toString()); //super.syntaxError(token); - //throw new RuntimeException(token.getLine(token.getStart()) + ", " + + //throw new RuntimeException(token.getLine(token.getStart()) + ", " + // token.getColumn(token.getStart()) + ": Syntax Error"); } public void scannerError(Scanner.Exception e) { @@ -55,51 +55,50 @@ List var_decl_list = Field var_decl = type.t IDENTIFIER SEMICOLON {: return new Field(t, IDENTIFIER); :} - | type.t IDENTIFIER dim_list.d SEMICOLON + | type.t IDENTIFIER dim_list.d SEMICOLON {: return new Field(new ParseArrayType(t, d), IDENTIFIER); :} ; -TypeDecl type_decl = +TypeDecl type_decl = TYPEDEF type.t IDENTIFIER SEMICOLON {: return new TypeDecl(t, IDENTIFIER); :} - | TYPEDEF type.t IDENTIFIER dim_list.d SEMICOLON + | TYPEDEF type.t IDENTIFIER dim_list.d SEMICOLON {: return new TypeDecl(new ParseArrayType(t, d), IDENTIFIER); :} ; -SampleDecl sample_decl = - SAMPLE type.t IDENTIFIER SEMICOLON +SampleDecl sample_decl = + SAMPLE type.t IDENTIFIER SEMICOLON {: return new SampleDecl(t, IDENTIFIER); :} - | SAMPLE type.t IDENTIFIER dim_list.d SEMICOLON + | SAMPLE type.t IDENTIFIER dim_list.d SEMICOLON {: return new SampleDecl(new ParseArrayType(t, d), IDENTIFIER); :} - | SAMPLE VOID IDENTIFIER SEMICOLON - {: return new SampleDecl(new VoidType(), IDENTIFIER); :} ; Type type = prim_type.p {: return p; :} | user_type.u {: return u; :} | struct_type.s {: return s; :} + | void_type.v {: return v; :} ; -PrimType prim_type = - BOOLEAN +PrimType prim_type = + BOOLEAN {: return new PrimType(BOOLEAN, ASTNode.LABCOMM_BOOLEAN); :} - | BYTE + | BYTE {: return new PrimType(BYTE, ASTNode.LABCOMM_BYTE); :} - | SHORT + | SHORT {: return new PrimType(SHORT, ASTNode.LABCOMM_SHORT); :} - | INT + | INT {: return new PrimType(INT, ASTNode.LABCOMM_INT); :} - | LONG + | LONG {: return new PrimType(LONG, ASTNode.LABCOMM_LONG); :} - | FLOAT + | FLOAT {: return new PrimType(FLOAT, ASTNode.LABCOMM_FLOAT); :} - | DOUBLE + | DOUBLE {: return new PrimType(DOUBLE, ASTNode.LABCOMM_DOUBLE); :} - | STRING + | STRING {: return new PrimType(STRING, ASTNode.LABCOMM_STRING); :} ; -UserType user_type = +UserType user_type = IDENTIFIER {: return new UserType(IDENTIFIER); :} ; @@ -107,6 +106,10 @@ StructType struct_type = STRUCT LBRACE var_decl_list.l RBRACE {: return new StructType(l); :} ; +VoidType void_type = + VOID {: return new VoidType(); :} +; + List dim_list = dim.d {: return new List().add(d); :} | dim_list.l dim.d {: return l.add(d); :} @@ -121,7 +124,7 @@ List exp_list = | exp_list.l COMMA exp.e {: return l.add(e); :} ; -Exp exp = +Exp exp = INTEGER_LITERAL {: return new IntegerLiteral(INTEGER_LITERAL); :} | UNDERSCORE {: return new VariableSize(); :} ; diff --git a/compiler/TypeCheck.jrag b/compiler/TypeCheck.jrag new file mode 100644 index 0000000000000000000000000000000000000000..a640ace5098013bef6cad31767a96220aa66b8a7 --- /dev/null +++ b/compiler/TypeCheck.jrag @@ -0,0 +1,36 @@ +aspect TypeCheck { + public void ASTNode.typeCheck() { + // calls to the different type checks to be performed + nullTypeCheck(); + } + +// void is not allowed as a field in a struct or an array element + + syn boolean Type.isNull(); + eq Type.isNull() = false; + eq VoidType.isNull() = true; + eq UserType.isNull() = decl().isNull(); + + syn boolean TypeDecl.isNull(); + eq TypeDecl.isNull() = getType().isNull(); + + public void ASTNode.nullTypeCheck() {} + + public void Field.nullTypeCheck() { + if(getType().isNull()) { + error("field " + getName() + " of struct "+ declName()+ " may not be of type void"); + } + } + + public void ParseArrayType.nullTypeCheck() { + if(getType().isNull()) { + error("elements of array "+declName()+" may not be of type void"); + } + } + + public void ArrayType.nullTypeCheck() { + if(getType().isNull()) { + error("elements of array "+declName()+" may not be of type void"); + } + } +} diff --git a/examples/simple/Decoder.java b/examples/simple/Decoder.java index 266b895251b6237ee53777dbc05fb8636e13dfff..4ab97e48fccda695f051157b6eb86d293b700d3f 100644 --- a/examples/simple/Decoder.java +++ b/examples/simple/Decoder.java @@ -5,7 +5,7 @@ import java.io.InputStream; import se.lth.control.labcomm.LabCommDecoderChannel; public class Decoder - implements theTwoInts.Handler, anotherTwoInts.Handler, IntString.Handler, TwoArrays.Handler, TwoFixedArrays.Handler + implements theTwoInts.Handler, anotherTwoInts.Handler, IntString.Handler, TwoArrays.Handler, TwoFixedArrays.Handler, doavoid.Handler { @@ -20,6 +20,7 @@ public class Decoder IntString.register(decoder, this); TwoArrays.register(decoder, this); TwoFixedArrays.register(decoder, this); + doavoid.register(decoder, this); try { System.out.println("Running decoder."); @@ -72,6 +73,10 @@ public class Decoder } System.out.println(); } + public void handle_doavoid() throws java.io.IOException { + System.out.println("Got doavoid"); + } + public static void main(String[] arg) throws Exception { diff --git a/examples/simple/example_encoder.c b/examples/simple/example_encoder.c index 174694237cfeb83c05093a73bbdf56e8f513a4ad..ea77e11ca026daa100b5b19d6c8449d72c1ba6cf 100644 --- a/examples/simple/example_encoder.c +++ b/examples/simple/example_encoder.c @@ -20,9 +20,13 @@ int main(int argc, char *argv[]) { labcomm_default_error_handler, labcomm_default_memory, labcomm_default_scheduler); + labcomm_encoder_register_simple_doavoid(encoder); labcomm_encoder_register_simple_theTwoInts(encoder); labcomm_encoder_register_simple_anotherTwoInts(encoder); labcomm_encoder_register_simple_IntString(encoder); + + labcomm_encode_simple_doavoid(encoder); + simple_IntString is; is.x = 24; is.s = "Hello, LabComm!"; diff --git a/examples/simple/simple.lc b/examples/simple/simple.lc index 518395755eda152f137213ae8ab86fed14434f16..f25295d4d5e45c6fd9cb703fea483ab949281405 100644 --- a/examples/simple/simple.lc +++ b/examples/simple/simple.lc @@ -25,3 +25,18 @@ sample struct { int a[2]; int b[2,3]; } TwoFixedArrays; + +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[_]; diff --git a/examples/twoway/client.c b/examples/twoway/client.c index 484b20edcabd2f7a2daef7b786d26846de61e9e9..be82e9a8834e45e43eca6964b567d0ac1ef7cb61 100644 --- a/examples/twoway/client.c +++ b/examples/twoway/client.c @@ -175,7 +175,7 @@ int main(int argc, char *argv[]) } } printf("\n"); - labcomm_encode_types_Terminate(encoder, LABCOMM_VOID); + labcomm_encode_types_Terminate(encoder); out: return 0; diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c index 79aeb4307575f6d6d98f6c9a2215e80eb340e05d..670b8247472c127839eaabf6340e438d538d6c81 100644 --- a/lib/c/test/test_labcomm_generated_encoding.c +++ b/lib/c/test/test_labcomm_generated_encoding.c @@ -179,7 +179,8 @@ void dump_encoder(struct labcomm_encoder *encoder) int main(void) { - generated_encoding_V V; + //no longer used + //generated_encoding_V V; generated_encoding_B B = 1; struct labcomm_encoder *encoder = labcomm_encoder_new( @@ -199,7 +200,8 @@ int main(void) EXPECT({0x02, -1, 0x01, 'B', 0x21}); labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET); - labcomm_encode_generated_encoding_V(encoder, &V); + // was: labcomm_encode_generated_encoding_V(encoder, &V); + labcomm_encode_generated_encoding_V(encoder); EXPECT({-1}); labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET); diff --git a/test/Makefile b/test/Makefile index 7401102eba4792c16788f41379678faca4fae516..376949f2cec1c70850223cc952f2b87692aeda2d 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,12 +1,12 @@ TESTS=basic simple nested LABCOMM_JAR=../compiler/labComm.jar -LABCOMM=java -jar $(LABCOMM_JAR) +LABCOMM=java -jar $(LABCOMM_JAR) CFLAGS=-O3 -g -Wall -Werror -all: +all: -test: $(TESTS:%=test_%) +test: $(TESTS:%=test_%) compiler_errors # PYTHONPATH=../lib/python \ # ./test_encoder_decoder.py --labcomm="$(LABCOMM)" basic.lc @@ -14,12 +14,12 @@ test: $(TESTS:%=test_%) clean distclean: rm -rf gen -.PHONY: test_% +.PHONY: test_% test_%: gen/%/signatures.py \ gen/%/c_relay \ gen/%/cs_relay.exe \ gen/%/java_relay.class \ - gen/%/java_code + gen/%/java_code PYTHONPATH=../lib/python ./test_encoder_decoder.py \ --signatures=gen/$*/signatures.py \ --test tee gen/$*/testdata \ @@ -27,6 +27,20 @@ test_%: gen/%/signatures.py \ --test mono gen/$*/cs_relay.exe /dev/stdin /dev/stdout \ --test java \\-cp gen/$*:../lib/java/labcomm.jar 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/$* @@ -52,7 +66,7 @@ gen/%/c_relay.c: gen/%/typeinfo relay_gen_c.py Makefile .PRECIOUS: gen/%/c_relay gen/%/c_relay: gen/%/c_relay.c gen/%/c_code.c Makefile $(CC) $(CFLAGS) -o $@ $< -I../lib/c -I. -L..//lib/c \ - gen/$*/c_code.c -llabcomm + gen/$*/c_code.c -llabcomm # C# relay test rules .PRECIOUS: gen/%/cs_code.cs diff --git a/test/errors/correct/structtype.lc b/test/errors/correct/structtype.lc new file mode 100644 index 0000000000000000000000000000000000000000..9eef504d7e0421baa6dad5bf83cfe6ad22f7d04c --- /dev/null +++ b/test/errors/correct/structtype.lc @@ -0,0 +1,9 @@ +typedef struct { + string topic; +} pubsub; + +sample pubsub subscribe; +sample pubsub unsubscribe; + +sample pubsub publish; +sample pubsub unpublish; diff --git a/test/errors/correct/void.lc b/test/errors/correct/void.lc new file mode 100644 index 0000000000000000000000000000000000000000..a2d8a8470b94de9ebb1b047d9845ddd907a9f754 --- /dev/null +++ b/test/errors/correct/void.lc @@ -0,0 +1,14 @@ +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[_]; diff --git a/test/errors/incorrect/void.lc b/test/errors/incorrect/void.lc new file mode 100644 index 0000000000000000000000000000000000000000..743c4d05836e41ae049c54dbd1051818e90dfc51 --- /dev/null +++ b/test/errors/incorrect/void.lc @@ -0,0 +1,12 @@ +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[_]; diff --git a/test/relay_gen_c.py b/test/relay_gen_c.py index 6f4da2ca1b7e1d621a5e52d0e7e1052c33edbb3b..837cf7243b0c4ac383b43b6ad93cf5f1cdd15757 100755 --- a/test/relay_gen_c.py +++ b/test/relay_gen_c.py @@ -16,13 +16,14 @@ 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]) + lang,kind,func,arg,stype = l[1:].split(l[0]) if lang == 'C' and kind == 'sample': - sample.append((func, arg)) + sample.append((func, arg, stype)) pass pass result = [] result.extend(split_match('^[^|]*\|(.*)$', """ + |// generated by relay_gen_c.py |#include <sys/types.h> |#include <sys/stat.h> |#include <fcntl.h> @@ -34,13 +35,19 @@ if __name__ == '__main__': |#include <labcomm_fd_writer.h> |#include "c_code.h" """)) - for func,arg in sample: + for func,arg,stype 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 })) + | labcomm_encode_%(func)s(e%(valargstr)s); + |}""" % { 'func': func, 'arg': arg, 'valargstr': '' if stype == "void" else', v' })) +# 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[]) { @@ -64,7 +71,7 @@ if __name__ == '__main__': | labcomm_default_memory, | labcomm_default_scheduler); """)) - for func,arg in sample: + for func,arg,stype in sample: result.extend(split_match('^[^|]*\|(.*)$', """ | labcomm_encoder_register_%(func)s(e); | labcomm_decoder_register_%(func)s(d, handle_%(func)s, e); diff --git a/test/relay_gen_cs.py b/test/relay_gen_cs.py index 06a4e659507c21cf82071af63c1aad66abffb435..68fdc4de6db96a45ae1d75fc263fd3ebc498aafe 100755 --- a/test/relay_gen_cs.py +++ b/test/relay_gen_cs.py @@ -16,7 +16,7 @@ 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]) + lang,kind,func,arg,dummy = l[1:].split(l[0]) if lang == 'C#' and kind == 'sample': sample.append((func, arg)) pass diff --git a/test/relay_gen_java.py b/test/relay_gen_java.py index 9c0869bbac9fcb143051897784603655be27c27f..93644bc2ed679087264766594acece7467f04eaf 100755 --- a/test/relay_gen_java.py +++ b/test/relay_gen_java.py @@ -16,7 +16,7 @@ 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]) + lang,kind,func,arg,dummy = l[1:].split(l[0]) if lang == 'Java' and kind == 'sample': sample.append((func, arg)) pass diff --git a/test/test_errors.py b/test/test_errors.py new file mode 100755 index 0000000000000000000000000000000000000000..24b9627cd07b6aa0abacf7d131609dfa7ef16fe2 --- /dev/null +++ b/test/test_errors.py @@ -0,0 +1,49 @@ +#!/usr/bin/python + +import sys +import argparse +import subprocess + +# returns true if test fails +def test_labcomm_compile_OK(lc, args): + cmd = args.labcomm.split() + [lc] + try: + res = subprocess.check_call(cmd) + print "sucess!" + return False + except subprocess.CalledProcessError as ex: + print ex.output + print ex.returncode + return True + +def test_labcomm_compile_fail(lc, args): + cmd = args.labcomm.split() + [lc] + try: + res = subprocess.check_call(cmd) + print "failed! (should have produced an error)" + return True + except subprocess.CalledProcessError as ex: + print "sucess!" + print ex.output + print ex.returncode + return False; + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Run test of error messages.') + + parser.add_argument('--labcomm'); + parser.add_argument('--testOK', nargs='*', default=[]) + parser.add_argument('--testNOK', nargs='*', default=[]) + args = parser.parse_args() + + fail = False; + for test in args.testOK: + fail = fail or test_labcomm_compile_OK(test, args) + pass + for test in args.testNOK: + fail = fail or test_labcomm_compile_fail(test, args) + pass + if fail: + print "*** fail ***" + else: + print "*** success ***"