diff --git a/Makefile b/Makefile index 07c4765287f6c539daa52e7ab1a424c0f0ee7678..10bc7d42093bdb59a4744b31834600e68df31b08 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ SUBDIRS=compiler lib test examples packaging export LABCOMM_JAR=$(shell pwd)/compiler/labcomm2014_compiler.jar export LABCOMM=java -jar $(LABCOMM_JAR) +export VALGRIND=valgrind --leak-check=full --error-exitcode=1 UNAME_S=$(shell uname -s) diff --git a/lib/c/2014/Makefile b/lib/c/2014/Makefile index 81c0244deaa0578339cb541395c263c012b4a0e2..741f5e33c52de9ba86e09c7ba8b43b56ccd98a4b 100644 --- a/lib/c/2014/Makefile +++ b/lib/c/2014/Makefile @@ -108,7 +108,7 @@ endif # rules invoked by 'test' .PHONY: run-test-% run-test-%: $(TEST_DIR)/gen/% | $(TEST_DIR)/gen - $< + $(VALGRIND) $< .PRECIOUS: $(TEST_DIR)/gen/% diff --git a/lib/c/2014/labcomm2014_decoder.c b/lib/c/2014/labcomm2014_decoder.c index 80422737f75ea44f1e25776c8a2325cafc5f10c6..c9474aa76867db3e944394ab369ce0b091db6bb9 100644 --- a/lib/c/2014/labcomm2014_decoder.c +++ b/lib/c/2014/labcomm2014_decoder.c @@ -186,7 +186,7 @@ static int decode_sample_def_or_ref(struct labcomm2014_decoder *d, int kind) signature.name = TODO_read_intentions(d->reader); if (d->reader->error < 0) { result = d->reader->error; - goto out; + goto free_signature_name; } signature.size = labcomm2014_read_packed32(d->reader); if (d->reader->error < 0) { @@ -224,7 +224,15 @@ static int decode_sample_def_or_ref(struct labcomm2014_decoder *d, int kind) free_signature_signature: labcomm2014_memory_free(d->memory, 1, signature.signature); free_signature_name: - labcomm2014_memory_free(d->memory, 0, signature.name); + if (signature.name) { + if (result == -ENOENT) { + labcomm2014_error_warning(d->error, + LABCOMM2014_ERROR_DEC_NO_REG_SIGNATURE, + "Signature not found: %s\n", + signature.name); + } + labcomm2014_memory_free(d->memory, 0, signature.name); + } out: return result; } @@ -283,23 +291,26 @@ out: } static labcomm2014_decoder_function lookup_h(struct labcomm2014_decoder *d, - struct call_handler_context *wrap, - int remote_index, - int **local_index) + struct call_handler_context *wrap, + int remote_index, + int *r_local_index) { struct decoder *id = d->context; labcomm2014_decoder_function do_decode = NULL; + int *local_index; + labcomm2014_scheduler_data_lock(d->scheduler); - *local_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, - id->remote_to_local, int, - remote_index); - if (**local_index != 0) { + local_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, + id->remote_to_local, int, + remote_index); + *r_local_index = *local_index; + if (*local_index != 0) { struct sample_entry *entry; entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, id->local, struct sample_entry, - **local_index); - wrap->local_index = **local_index; + *local_index); + wrap->local_index = *local_index; wrap->signature = entry->signature; wrap->handler = entry->handler; wrap->context = entry->context; @@ -318,7 +329,7 @@ static int decode_and_handle(struct labcomm2014_decoder *d, int remote_index) { int result; - int *local_index; + int local_index; struct call_handler_context wrap = { .reader = d->reader, .remote_index = remote_index, @@ -327,7 +338,7 @@ static int decode_and_handle(struct labcomm2014_decoder *d, .context = NULL, }; labcomm2014_decoder_function do_decode = lookup_h(registry, &wrap, remote_index, &local_index); - result = *local_index; + result = local_index; if (do_decode) { do_decode(d->reader, call_handler, &wrap); if (d->reader->error < 0) { @@ -363,15 +374,16 @@ static int do_decode_one(struct labcomm2014_decoder *d) char *version = labcomm2014_read_string(d->reader); if (d->reader->error < 0) { result = d->reader->error; - goto out; - } - if (strcmp(version, CURRENT_VERSION) == 0) { + } else if (strcmp(version, CURRENT_VERSION) == 0) { result = LABCOMM_VERSION; d->version_ok = 1; } else { result = -ECONNRESET; } labcomm2014_memory_free(d->memory, 1, version); + if (result < 0) { + goto out; + } } else if (! d->version_ok) { DEBUG_FPRINTF(stderr, "No VERSION %d %d\n", remote_index, length); result = -ECONNRESET; diff --git a/lib/c/2014/labcomm2014_error.c b/lib/c/2014/labcomm2014_error.c index 9a29a76ef02a6e4152354e7b2ae7d6165c37a322..a002026d6df70a558dd2125683a14e1182a8b8ec 100644 --- a/lib/c/2014/labcomm2014_error.c +++ b/lib/c/2014/labcomm2014_error.c @@ -24,15 +24,21 @@ #include <stdarg.h> #include "labcomm2014_error.h" +static char *description[] = { +#define LABCOMM2014_ERROR(name, description) description , +#include "labcomm2014_error.h" +#undef LABCOMM2014_ERROR +}; + void labcomm2014_error_fatal_global(enum labcomm2014_error error, char *format, ...) { va_list args; - fprintf(stderr, "Fatal error %d\n", error); + fprintf(stderr, "Fatal error %d (%s)\n", error, description[error]); va_start(args, format); - vprintf(format, args); + vfprintf(stderr, format, args); va_end(args); exit(1); @@ -45,9 +51,9 @@ void labcomm2014_error_warning(struct labcomm2014_error_handler *e, { va_list args; - fprintf(stderr, "Fatal warning %d\n", error); + fprintf(stderr, "Fatal warning %d (%s)\n", error, description[error]); va_start(args, format); - vprintf(format, args); + vfprintf(stderr, format, args); va_end(args); exit(1); diff --git a/lib/c/2014/labcomm2014_error.h b/lib/c/2014/labcomm2014_error.h index 9162e63acb7795e0b054833ac98d60765dc95e94..ae6ae08203dc38f25aa27730c35cadd9e00b0ea6 100644 --- a/lib/c/2014/labcomm2014_error.h +++ b/lib/c/2014/labcomm2014_error.h @@ -52,6 +52,9 @@ LABCOMM2014_ERROR(LABCOMM2014_ERROR_ENC_NO_REG_SIGNATURE, "Encoder has no registration for this signature") LABCOMM2014_ERROR(LABCOMM2014_ERROR_ENC_BUF_FULL, "The labcomm2014 buffer is full") + +LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_NO_REG_SIGNATURE, + "Decoder has no registration for this signature") LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_UNKNOWN_DATATYPE, "Decoder: Unknown datatype") LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_INDEX_MISMATCH, diff --git a/lib/c/2014/labcomm2014_renaming_decoder.c b/lib/c/2014/labcomm2014_renaming_decoder.c index acd8d35b90a7696e35324ab61b139e6d2922be34..88cdb761242bd7fa6dcdad9a3f5f15ba7cff780a 100644 --- a/lib/c/2014/labcomm2014_renaming_decoder.c +++ b/lib/c/2014/labcomm2014_renaming_decoder.c @@ -147,6 +147,13 @@ static int do_ioctl(struct labcomm2014_decoder *d, ioctl_action, args); } +static int do_decode_one(struct labcomm2014_decoder *d) +{ + struct decoder *id = d->context; + + return id->next->decode_one(id->next); +} + static const struct labcomm2014_sample_ref *do_index_to_sample_ref( struct labcomm2014_decoder *d, int index) { @@ -161,8 +168,8 @@ static const struct labcomm2014_sample_ref *do_ref_get( { const struct labcomm2014_signature *renamed; struct decoder *id = d->context; - - renamed = get_renamed(d, signature); + + renamed = get_renamed(d, signature); if (renamed == NULL) { return id->next->ref_get(id->next, signature); } else { @@ -201,12 +208,12 @@ struct labcomm2014_decoder *labcomm2014_renaming_decoder_new( return NULL; } else { result->decoder.context = result; - result->decoder.reader = NULL; + result->decoder.reader = d->reader; result->decoder.error = d->error; result->decoder.memory = d->memory; result->decoder.scheduler = d->scheduler; result->decoder.free = do_free; - result->decoder.decode_one = d->decode_one; + result->decoder.decode_one = do_decode_one; result->decoder.sample_register = do_sample_register; result->decoder.ref_register = do_ref_register; result->decoder.ioctl = do_ioctl; diff --git a/lib/c/2014/labcomm2014_renaming_encoder.c b/lib/c/2014/labcomm2014_renaming_encoder.c index feaa330147bb2777c188c85f3d5129daf4f7c2ac..b84eaaf11307d4b74f99a7a1acc3c260b141cff1 100644 --- a/lib/c/2014/labcomm2014_renaming_encoder.c +++ b/lib/c/2014/labcomm2014_renaming_encoder.c @@ -263,7 +263,7 @@ struct labcomm2014_encoder *labcomm2014_renaming_encoder_new( return NULL; } else { result->encoder.context = result; - result->encoder.writer = NULL; + result->encoder.writer = e->writer; result->encoder.error = e->error; result->encoder.memory = e->memory; result->encoder.scheduler = e->scheduler; diff --git a/lib/c/2014/test/test_labcomm.c b/lib/c/2014/test/test_labcomm.c index de36a7f4a34905a20360c272bf8f27c0d703593e..0b0fbf36fe0caa3c663654ba9a75bb5509b562f7 100644 --- a/lib/c/2014/test/test_labcomm.c +++ b/lib/c/2014/test/test_labcomm.c @@ -171,7 +171,9 @@ static test_sample_test_var decoder_var = { void handle_test_var(test_sample_test_var *v, void *ctx) { - decoder_var.a[0] = v->a[0]; + if (v->n_0 * v->n_2 > 0) { + decoder_var.a[0] = v->a[0]; + } } int test_decode_one(struct labcomm2014_decoder *decoder) @@ -229,7 +231,7 @@ static void test_encode_decode(struct labcomm2014_encoder *encoder, } } -int main(void) +static int do_test(int argc, char *argv[]) { int i; struct labcomm2014_decoder *decoder = labcomm2014_decoder_new( @@ -273,5 +275,13 @@ int main(void) test_encode_decode(encoder, decoder, 4+i, 0, (1<<(7*i))); } test_encode_decode(encoder, decoder, 8, 0, 4294967295); + + labcomm2014_encoder_free(encoder); + labcomm2014_decoder_free(decoder); return 0; } + +int main(int argc, char *argv[]) +{ + return do_test(argc, argv); +} diff --git a/lib/c/2014/test/test_labcomm_basic_type_encoding.c b/lib/c/2014/test/test_labcomm_basic_type_encoding.c index 29079df684b8f919a2ee15e8ca1992672d3db0f6..b7cf2b1bee28186b996350a92793524d484c34c8 100644 --- a/lib/c/2014/test/test_labcomm_basic_type_encoding.c +++ b/lib/c/2014/test/test_labcomm_basic_type_encoding.c @@ -91,7 +91,7 @@ static void writer_assert(char *type, } } -int main(void) +static int do_test(int argc, char *argv[]) { TEST_WRITE_READ(packed32, packed32, "%d", 0x0, 1, "\x00"); TEST_WRITE_READ(packed32, packed32, "%d", 0x7f, 1, "\x7f"); @@ -141,3 +141,7 @@ int main(void) return 0; } +int main(int argc, char *argv[]) +{ + return do_test(argc, argv); +} diff --git a/lib/c/2014/test/test_labcomm_copy.c b/lib/c/2014/test/test_labcomm_copy.c index 173f152ab52db12b1d24aa417bd9c25f77526d10..fc4bbfe2ac43373305643f0f80ac8d3b1853df99 100644 --- a/lib/c/2014/test/test_labcomm_copy.c +++ b/lib/c/2014/test/test_labcomm_copy.c @@ -70,7 +70,7 @@ static void handle_as(more_types_AS *v, void *context) labcomm2014_copy_more_types_AS(labcomm2014_default_memory, context, v); } -int main(int argc, char **argv) +int do_test(int argc, char **argv) { struct labcomm2014_encoder *encoder; struct labcomm2014_decoder *decoder; @@ -284,4 +284,15 @@ int main(int argc, char **argv) puts("NS deallocated ok"); labcomm2014_copy_free_more_types_AS(labcomm2014_default_memory, &cache_as); puts("AS deallocated ok"); + + labcomm2014_copy_free_generated_encoding_R(labcomm2014_default_memory, + &cache_r); + puts("R deallocated ok"); + + return 0; +} + +int main(int argc, char **argv) +{ + return do_test(argc, argv); } diff --git a/lib/c/2014/test/test_labcomm_pthread_scheduler.c b/lib/c/2014/test/test_labcomm_pthread_scheduler.c index aa7c5f0e08a77ccdf46717418ed06a4d4d64f3bf..c801308c5d8d408f1ece64f3061ef3f9a746b8a7 100644 --- a/lib/c/2014/test/test_labcomm_pthread_scheduler.c +++ b/lib/c/2014/test/test_labcomm_pthread_scheduler.c @@ -40,6 +40,7 @@ static void func(void *arg) if (func_arg->i == 999) { labcomm2014_scheduler_wakeup(func_arg->scheduler); } + free(func_arg); } void enqueue(struct labcomm2014_scheduler *scheduler, @@ -56,7 +57,7 @@ void enqueue(struct labcomm2014_scheduler *scheduler, } } -int main(int argc, char *argv[]) +static int do_test(int argc, char *argv[]) { struct labcomm2014_scheduler *scheduler; struct labcomm2014_time *time; @@ -78,5 +79,12 @@ int main(int argc, char *argv[]) labcomm2014_scheduler_sleep(scheduler, NULL); labcomm2014_scheduler_sleep(scheduler, time); + labcomm2014_time_free(time); + labcomm2014_scheduler_free(scheduler); return 0; } + +int main(int argc, char *argv[]) +{ + return do_test(argc, argv); +} diff --git a/lib/c/2014/test/test_labcomm_renaming_decoder.c b/lib/c/2014/test/test_labcomm_renaming_decoder.c index 9cafa7ca5881d0d8a1d73cb4fb8bc656da83e569..b0c4bd5aaefd8ee517f162bbb8e56150e9a8bf4d 100644 --- a/lib/c/2014/test/test_labcomm_renaming_decoder.c +++ b/lib/c/2014/test/test_labcomm_renaming_decoder.c @@ -169,7 +169,10 @@ int main(int argc, char **argv) labcomm2014_decoder_get_sample_ref( suffix_decoder, labcomm2014_signature_generated_encoding_R)); + labcomm2014_decoder_free(suffix_decoder); + labcomm2014_decoder_free(prefix_decoder); labcomm2014_decoder_free(decoder); + close(fd); unlink(DATA_FILE); } diff --git a/lib/c/2014/test/test_labcomm_renaming_encoder.c b/lib/c/2014/test/test_labcomm_renaming_encoder.c index f1e608fffbd92e0b6896fb24208eb22e7aa1371a..7996b2321158521b2151d263f7f735a741defa08 100644 --- a/lib/c/2014/test/test_labcomm_renaming_encoder.c +++ b/lib/c/2014/test/test_labcomm_renaming_encoder.c @@ -26,7 +26,7 @@ #include "labcomm2014_private.h" #include "labcomm2014_default_error_handler.h" #include "labcomm2014_default_memory.h" -#include "labcomm2014_pthread_scheduler.h" +#include "labcomm2014_default_scheduler.h" #include "labcomm2014_renaming.h" #include "labcomm2014_renaming_encoder.h" #include "test/gen/generated_encoding.h" @@ -193,7 +193,7 @@ void dump_encoder(struct labcomm2014_encoder *encoder) printf("\n"); } -int main(void) +static int do_test(int argc, char *argv[]) { struct labcomm2014_encoder *encoder, *prefix, *suffix; int i; @@ -206,7 +206,7 @@ int main(void) &buffer_writer, labcomm2014_default_error_handler, labcomm2014_default_memory, - labcomm2014_pthread_scheduler_new(labcomm2014_default_memory)); + labcomm2014_default_scheduler); prefix = labcomm2014_renaming_encoder_new(encoder, labcomm2014_renaming_prefix, "p."); @@ -277,6 +277,14 @@ int main(void) labcomm2014_encode_generated_encoding_V(suffix); EXPECT({VARIABLE(5), 0x00 }); + labcomm2014_encoder_free(suffix); + labcomm2014_encoder_free(prefix); + labcomm2014_encoder_free(encoder); + return 0; } +int main(int argc, char *argv[]) +{ + return do_test(argc, argv); +} diff --git a/test/Makefile b/test/Makefile index dc3b8b735b9a24606719e8be46ee2f1960601421..0714905b12228697016e4fd26ce0f2b3d4be32f4 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,4 +1,6 @@ -TESTS=basic simple nested ref +TESTS_RENAME=basic simple nested # sample_ref's does not transfer between + # encoder decoder for now +TESTS=$(TESTS_RENAME) ref LABCOMM_JAR=../compiler/labcomm2014_compiler.jar LABCOMM=java -jar $(LABCOMM_JAR) MONO_PATH=$(shell pwd)/../lib/csharp @@ -8,7 +10,7 @@ include ../lib/c/os_compat.mk all: -test: $(TESTS:%=test_%) compiler_errors +test: $(TESTS:%=test_%) $(TESTS_RENAME:%=test_renaming_%) compiler_errors # PYTHONPATH=../lib/python \ # ./test_encoder_decoder.py --labcomm="$(LABCOMM)" basic.lc @@ -26,10 +28,28 @@ test_%: gen/%/signatures.py \ ./test_encoder_decoder.py \ --signatures=gen/$*/signatures.py \ --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 java \\-cp gen/$*:../lib/java/labcomm2014.jar java_relay \ - /dev/stdin /dev/stdout + --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_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 + echo \ + --test mono gen/$*/cs_relay.exe /dev/stdin /dev/stdout \ + --test java \\-cp gen/$*:../lib/java/labcomm2014.jar \ + java_relay /dev/stdin /dev/stdout # test cases for compiler error checking .PHONY: compiler_errors testErrorsOK testErrorsNOK @@ -71,6 +91,15 @@ gen/%/c_relay: gen/%/c_relay.c gen/%/c_code.c Makefile $(CC) $(CFLAGS) -o $@ $< -I../lib/c/2014 -I. -L../lib/c \ gen/$*/c_code.c -llabcomm2014 +.PRECIOUS: gen/%/c_renaming_relay.c +gen/%/c_renaming_relay.c: gen/%/typeinfo relay_gen_c.py Makefile + ./relay_gen_c.py --renaming $< > $@ + +.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 .PRECIOUS: gen/%/cs_code.cs gen/%/cs_code.cs: %.lc Makefile | gen/%/.dir diff --git a/test/relay_gen_c.py b/test/relay_gen_c.py index 4d050640d0ec5b9091ff0c19d464ffd52361b5ba..e13f66ab01f77a57a740ba8957b992c99ae7c7c0 100755 --- a/test/relay_gen_c.py +++ b/test/relay_gen_c.py @@ -1,5 +1,6 @@ #!/usr/bin/python +import argparse import re import sys @@ -13,7 +14,13 @@ def split_match(pattern, multiline): if __name__ == '__main__': - f = open(sys.argv[1]) + parser = argparse.ArgumentParser(description='Generate C test relay.') + parser.add_argument('--renaming', action='store_true') + parser.add_argument('typeinfo', help='typeinfo file') + + options = parser.parse_args(sys.argv[1:]) + + f = open(options.typeinfo) sample = [] for l in map(lambda s: s.strip(), f): lang,kind,func,arg,stype = l[1:].split(l[0]) @@ -27,12 +34,21 @@ if __name__ == '__main__': |#include <sys/types.h> |#include <sys/stat.h> |#include <fcntl.h> + |#include <stdio.h> |#include <labcomm2014.h> |#include <labcomm2014_default_error_handler.h> |#include <labcomm2014_default_memory.h> |#include <labcomm2014_default_scheduler.h> |#include <labcomm2014_fd_reader.h> |#include <labcomm2014_fd_writer.h> + """)) + if options.renaming: + result.extend(split_match('^[^|]*\|(.*)$', """ + |#include "labcomm2014_renaming.h" + |#include "labcomm2014_renaming_encoder.h" + |#include "labcomm2014_renaming_decoder.h" + """)) + result.extend(split_match('^[^|]*\|(.*)$', """ |#include "c_code.h" """)) for func,arg,stype in sample: @@ -45,26 +61,55 @@ if __name__ == '__main__': pass result.extend(split_match('^[^|]*\|(.*)$', """ |int main(int argc, char *argv[]) { - | struct labcomm2014_encoder *e; - | struct labcomm2014_decoder *d; - | int in, out; + | struct labcomm2014_encoder *e, *e_e; + | struct labcomm2014_decoder *d, *d_d; + """)) + if options.renaming: + result.extend(split_match('^[^|]*\|(.*)$', """ + | struct labcomm2014_encoder *e_p, *e_s; + | struct labcomm2014_decoder *d_p, *d_s; + """)) + result.extend(split_match('^[^|]*\|(.*)$', """ + | int in, out, result; | | 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 = labcomm2014_encoder_new(labcomm2014_fd_writer_new( - | labcomm2014_default_memory, out, 1), - | labcomm2014_default_error_handler, - | labcomm2014_default_memory, - | labcomm2014_default_scheduler); - | d = labcomm2014_decoder_new(labcomm2014_fd_reader_new( - | labcomm2014_default_memory, in, 1), - | labcomm2014_default_error_handler, - | labcomm2014_default_memory, - | labcomm2014_default_scheduler); + | e_e = labcomm2014_encoder_new(labcomm2014_fd_writer_new( + | labcomm2014_default_memory, out, 1), + | labcomm2014_default_error_handler, + | labcomm2014_default_memory, + | labcomm2014_default_scheduler); + | d_d = labcomm2014_decoder_new(labcomm2014_fd_reader_new( + | labcomm2014_default_memory, in, 1), + | labcomm2014_default_error_handler, + | labcomm2014_default_memory, + | labcomm2014_default_scheduler); """)) + if not options.renaming: + result.extend(split_match('^[^|]*\|(.*)$', """ + | e = e_e; + | d = d_d; + """)) + else: + result.extend(split_match('^[^|]*\|(.*)$', """ + | e_p = labcomm2014_renaming_encoder_new(e_e, + | labcomm2014_renaming_prefix, + | "prefix:"); + | e_s = labcomm2014_renaming_encoder_new(e_p, + | labcomm2014_renaming_suffix, + | ":suffix"); + | e = e_s; + | d_p = labcomm2014_renaming_decoder_new(d_d, + | labcomm2014_renaming_prefix, + | "prefix:"); + | d_s = labcomm2014_renaming_decoder_new(d_p, + | labcomm2014_renaming_suffix, + | ":suffix"); + | d = d_s; + """)) for func,arg,stype in sample: result.extend(split_match('^[^|]*\|(.*)$', """ | labcomm2014_encoder_register_%(func)s(e); @@ -73,7 +118,19 @@ if __name__ == '__main__': | labcomm2014_decoder_sample_ref_register(d, labcomm2014_signature_%(func)s); """ % { 'func': func, 'arg': arg })) result.extend(split_match('^[^|]*\|(.*)$', """ - | labcomm2014_decoder_run(d); + | while ((result = labcomm2014_decoder_decode_one(d)) > 0) {}; + """)) + if options.renaming: + result.extend(split_match('^[^|]*\|(.*)$', """ + | labcomm2014_decoder_free(d_s); + | labcomm2014_decoder_free(d_p); + | labcomm2014_encoder_free(e_s); + | labcomm2014_encoder_free(e_p); + """)) + result.extend(split_match('^[^|]*\|(.*)$', """ + | labcomm2014_decoder_free(d_d); + | labcomm2014_encoder_free(e_e); + | fprintf(stderr, "Failed with %d", result); | return 0; |} """)) diff --git a/test/test_renaming_encoder_decoder.py b/test/test_renaming_encoder_decoder.py new file mode 100755 index 0000000000000000000000000000000000000000..8f623f87dcf8833cedd9bcd1d750379b9ede86a3 --- /dev/null +++ b/test/test_renaming_encoder_decoder.py @@ -0,0 +1,253 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import argparse +import imp +import labcomm2014 +import math +import os +import re +import struct +import subprocess +import sys +import threading + + +def labcomm_compile(lc, name, args): + for lang in [ 'c', 'csharp', 'java', 'python']: + destdir = 'gen/%s/%s' % (name, lang) + if not os.path.exists(destdir): + os.makedirs(destdir) + pass + pass + cmd = args.labcomm.split() + [ + "--c=gen/%s/c/%s.c" % (name, name), + "--h=gen/%s/c/%s.h" % (name, name), + "--cs=gen/%s/csharp/%s.cs" % (name, name), + "--python=gen/%s/python/%s.py" % (name, name), + "--java=gen/%s/java/" % name, + "--typeinfo=gen/%s/%s.typeinfo" % (name, name), + lc] + subprocess.check_call(cmd) + pass + +def get_signatures(path): + fp, pathname, description = imp.find_module(os.path.basename(path)[0:-3], + [ os.path.dirname(path) ]) + with fp as fp: + m = imp.load_module('signatures', fp, pathname, description) + pass + return map(lambda s: s.signature, m.sample) + +class Test: + + def __init__(self, program, signatures): + self.program = program + self.signatures = map(lambda s: s.rename('prefix:%s:suffix' % s.name), + signatures) + pass + + def generate(self, decl): + if decl.__class__ == labcomm2014.sample: + result = [] + for values in self.generate(decl.decl): + result.append((decl, values)) + return result + + elif decl.__class__ == labcomm2014.typedef: + result = [] + for values in self.generate(decl.decl): + result.append(values) + return result + + elif decl.__class__ == labcomm2014.struct: + result = [] + if len(decl.field) == 0: + result.append({}) + else: + values1 = self.generate(decl.field[0][1]) + values2 = self.generate(labcomm2014.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__ == labcomm2014.array: + if len(decl.indices) == 1: + values = self.generate(decl.decl) + if decl.indices[0] == 0: + lengths = [0, 1, 2] + else: + lengths = [ decl.indices[0] ] + else: + values = self.generate(labcomm2014.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__ == labcomm2014.BOOLEAN: + return [False, True] + + elif decl.__class__ == labcomm2014.BYTE: + return [0, 127, 128, 255] + + elif decl.__class__ == labcomm2014.SHORT: + return [-32768, 0, 32767] + + elif decl.__class__ == labcomm2014.INTEGER: + return [-2147483648, 0, 2147483647] + + elif decl.__class__ == labcomm2014.LONG: + return [-9223372036854775808, 0, 9223372036854775807] + + elif decl.__class__ == labcomm2014.FLOAT: + def tofloat(v): + return struct.unpack('f', struct.pack('f', v))[0] + return [tofloat(-math.pi), 0.0, tofloat(math.pi)] + + elif decl.__class__ == labcomm2014.DOUBLE: + return [-math.pi, 0.0, math.pi] + + elif decl.__class__ == labcomm2014.STRING: + return ['string', u'sträng' ] + + elif decl.__class__ == labcomm2014.SAMPLE: + return self.signatures + + print>>sys.stderr, decl + raise Exception("unhandled decl %s" % decl.__class__) + + def uses_refs(self, decls): + for decl in decls: + if decl.__class__ == labcomm2014.sample: + if self.uses_refs([ decl.decl ]): + return True + + elif decl.__class__ == labcomm2014.struct: + if self.uses_refs([ d for n,d in decl.field ]): + return True + + elif decl.__class__ == labcomm2014.array: + if self.uses_refs([ decl.decl ]): + return True + + elif decl.__class__ == labcomm2014.SAMPLE: + return True + + return False + + + def run(self): + print>>sys.stderr, 'Testing', self.program + p = subprocess.Popen(self.program, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=sys.stderr) + self.expected = None + self.failed = False + self.next = threading.Condition() + decoder = threading.Thread(target=self.decode, args=(p.stdout,)) + decoder.start() + encoder = labcomm2014.Encoder(labcomm2014.StreamWriter(p.stdin)) + for signature in self.signatures: + encoder.add_decl(signature) + pass + if self.uses_refs(self.signatures): + for signature in self.signatures: + encoder.add_ref(signature) + for signature in self.signatures: + print>>sys.stderr, "Checking", signature.name, + for decl,value in self.generate(signature): + sys.stderr.write('.') + self.next.acquire() + self.received_value = None + self.received_decl = None + encoder.encode(value, decl) + self.next.wait(2) + self.next.release() + if p.poll() != None: + print>>sys.stderr, "Failed with:", p.poll() + self.failed = True + elif value != self.received_value: + print>>sys.stderr, "Coding error" + print>>sys.stderr, value == self.received_value + print>>sys.stderr, "Got: ", self.received_value + print>>sys.stderr, " ", self.received_decl + print>>sys.stderr, "Expected:", value + print>>sys.stderr, " ", decl + self.failed = True + + if self.failed: + if p.poll() == None: + p.terminate() + exit(1) + pass + print>>sys.stderr + pass + p.stdin.close() + if p.wait() != 0: + exit(1) + pass + pass + + def decode(self, f): + decoder = labcomm2014.Decoder(labcomm2014.StreamReader(f)) + try: + while True: + value,decl = decoder.decode() + if value != None: + self.next.acquire() + self.received_value = value + self.received_decl = decl + self.expected = None + self.next.notify_all() + self.next.release() + pass + pass + except EOFError: + pass + pass + + pass + +def run(test, signatures): + t = Test(test, signatures) + t.run() + pass + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Run encoding test.') + class test_action(argparse.Action): + def __call__(self, parser, namespace, values, option_string=None): + old = list(getattr(namespace, self.dest)) + def strip_slash(s): + if s.startswith('\\'): + return s[1:] + return s + old.append(map(strip_slash, values)) + setattr(namespace, self.dest, old) + parser.add_argument('--signatures') + parser.add_argument('--test', nargs='*', action=test_action, default=[]) + + args = parser.parse_args() + signatures = get_signatures(args.signatures) + for test in args.test: + run(test, signatures) + exit(0) + + for lc in args.lc: + run(lc, args) + pass + pass