diff --git a/.gitignore b/.gitignore index 7bf5adef57c4ce66f735a530e9dc1121071e4146..2eee7623d98382adf1fb85423229d774866f1079 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,7 @@ encoded_data06 gen gen06 *.pyc +examples/twoway/gen/ +lib/csharp/labcomm.dll +lib/java/gen/ +lib/java/labcomm*.jar diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag index e2e04baac6435830a280165aa77d055d512aa071..eea099bb1a41eddc589b49d986484fdd672f0663 100644 --- a/compiler/C_CodeGen.jrag +++ b/compiler/C_CodeGen.jrag @@ -43,11 +43,16 @@ aspect C_CodeGenEnv { private int indent; public final int depth; private C_printer printer; + public final int nestedLevel; + private boolean rootIsPointer; + private int rootLevel; private C_env(String qualid, String lcName, String rawPrefix, - int indent, int depth, C_printer printer, int version) { + int indent, int depth, C_printer printer, + int nestedLevel, int version) + { this.version = version; - this.verStr = (version == 2006 ? "2006" : ""); + this.verStr = (version == 2006 ? "2006" : ""); this.qualid = qualid; this.lcName = lcName; this.rawPrefix = rawPrefix; @@ -59,21 +64,28 @@ aspect C_CodeGenEnv { this.indent = indent; this.depth = depth; this.printer = printer; + this.nestedLevel = nestedLevel; } - public C_env(String qualid, String lcName, String rawPrefix, - PrintStream out, int version) { - this(qualid, lcName, rawPrefix, 0, 0, new C_printer(out), version); + public C_env(String qualid, String lcName, String rawPrefix, + PrintStream out, int version) + { + this(qualid, lcName, rawPrefix, 0, 0, new C_printer(out), 0, version); + } + + public C_env(String qualid, String lcName, String rawPrefix, + int indent, int depth, C_printer printer, int version) { + this(qualid, lcName, rawPrefix, indent, depth, printer, 0, version); } public C_env nestArray(String suffix) { - return new C_env(qualid + suffix, lcName, rawPrefix, - indent, depth + 1, printer, version); + return new C_env(qualid + suffix, lcName, rawPrefix, + indent, depth + 1, printer, nestedLevel + 1, version); } public C_env nestStruct(String suffix) { return new C_env(qualid + suffix, lcName, rawPrefix, - indent, depth, printer, version); + indent, depth, printer, nestedLevel + 1, version); } public void indent() { @@ -96,6 +108,19 @@ aspect C_CodeGenEnv { printer.println(this, s); } + public C_env setPointer() { + rootIsPointer = true; + rootLevel = nestedLevel; + return this; + } + + public String memberAccessor() { + return (rootIsPointer && (nestedLevel == rootLevel)) ? "->" : "."; + } + + public String accessor() { + return (rootIsPointer && (nestedLevel == rootLevel)) ? "*" : ""; + } } public C_env ArrayType.C_Nest(C_env env) { @@ -105,7 +130,7 @@ aspect C_CodeGenEnv { } public C_env FixedArrayType.C_Nest(C_env env) { - String index = ".a"; + String index = env.memberAccessor() + "a"; for (int i = 0 ; i < getNumExp() ; i++) { index += "[i_" + env.depth + "_" + i + "]"; } @@ -113,7 +138,7 @@ aspect C_CodeGenEnv { } public C_env VariableArrayType.C_Nest(C_env env) { - return env.nestArray(".a[i_" + env.depth + "]"); + return env.nestArray(env.memberAccessor() + "a[i_" + env.depth + "]"); } @@ -156,7 +181,6 @@ aspect C_CodeGen { env.println(""); // Include - env.println("#include <stdint.h>"); env.println("#include \"labcomm"+env.verStr+".h\""); for (int i = 0 ; i < includes.size() ; i++) { env.println("#include \"" + includes.get(i) + "\""); @@ -190,6 +214,8 @@ aspect C_CodeGen { getDecl(i).C_emitDecoderDeclaration(env); getDecl(i).C_emitEncoderDeclaration(env); getDecl(i).C_emitSizeofDeclaration(env); + getDecl(i).C_emitCopyDeclaration(env); + getDecl(i).C_emitCopyDeallocationDeclaration(env); env.println(""); } C_emitConstructorDeclaration(env); @@ -206,6 +232,8 @@ aspect C_CodeGen { getDecl(i).C_emitEncoderRegisterHandler(env); getDecl(i).C_emitEncoderIoctl(env); getDecl(i).C_emitSizeof(env); + getDecl(i).C_emitCopy(env); + getDecl(i).C_emitCopyDeallocation(env); } C_emitConstructor(env); } @@ -402,7 +430,7 @@ aspect C_Limit { } public String VariableSize.C_getLimit(C_env env, int i) { - return env.qualid + ".n_" + i; + return env.qualid + env.memberAccessor() + "n_" + i; } } @@ -650,6 +678,263 @@ aspect C_Decoder { } +aspect C_copy { + + private void SampleDecl.C_emitCopyFunctionParam(C_env env, String src, + String dst) + { + env.println("void labcomm" + env.verStr + "_copy_" + + env.prefix + getName() + "("); + env.indent(); + env.println("struct labcomm" + env.verStr + "_memory *mem,"); + env.println(env.prefix + getName() + " *" + dst + ","); + env.println(env.prefix + getName() + " *" + src); + env.unindent(); + env.print(")"); + } + + public void Decl.C_emitCopyDeclaration(C_env env) { + } + + public void SampleDecl.C_emitCopyDeclaration(C_env env) { + C_emitCopyFunctionParam(env, "src", "dst"); + env.println(";"); + } + + public void Decl.C_emitCopy(C_env env) { + throw new Error(this.getClass().getName() + + ".C_emitCopy(C_env env)" + + " not declared"); + } + + public void TypeDecl.C_emitCopy(C_env env) { + } + + public void SampleDecl.C_emitCopy(C_env env) { + final String dst = "dst"; + final String src = "src"; + C_env env_src = env.nestStruct(src).setPointer(); + C_env env_dst = env.nestStruct(dst).setPointer(); + + C_emitCopyFunctionParam(env_src, src, dst); + env_src.println(""); + env_src.println("{"); + env_src.indent(); + getType().C_emitCopy(env_src, env_dst); + env_src.unindent(); + env_src.println("}"); + } + + public void Type.C_emitCopy(C_env env_src, C_env env_dst) { + throw new Error(this.getClass().getName() + + ".C_emitCopy(C_env env)" + + " not declared"); + } + + public void VoidType.C_emitCopy(C_env env_src, C_env env_dst) { + } + + public void PrimType.C_emitCopy(C_env env_src, C_env env_dst) { + if (C_isDynamic()) { + env_src.println(String.format( + "%s%s = labcomm%s_memory_alloc(mem, 1, strlen(%s%s)+1);", + env_dst.accessor(), env_dst.qualid, + env_src.verStr, + env_src.accessor(), env_src.qualid)); + env_src.println(String.format( + "memcpy(%s%s, %s%s, strlen(%s%s)+1);", + env_dst.accessor(), env_dst.qualid, + env_src.accessor(), env_src.qualid, + env_src.accessor(), env_src.qualid)); + } else { + env_src.println(env_dst.accessor() + env_dst.qualid + " = " + + env_src.accessor() + env_src.qualid + ";"); + } + } + + public void UserType.C_emitCopy(C_env env_src, C_env env_dst) { + lookupType(getName()).getType().C_emitCopy(env_src, env_dst); + } + + public void StructType.C_emitCopy(C_env env_src, C_env env_dst) { + for (int i = 0 ; i < getNumField() ; i++) { + getField(i).C_emitCopy(env_src, env_dst); + } + } + + public void ArrayType.C_emitCopy(C_env env_src, C_env env_dst) { + C_emitCopyDecodeLimit(env_src, env_dst); + C_emitCopyArrayAllocate(env_src, env_dst); + env_src.println("{"); + env_src.indent(); + C_emitLoopVariables(env_src); + for (int i = 0 ; i < getNumExp() ; i++) { + String iterator = "i_" + env_src.depth + "_" + i; + env_src.println("for (" + iterator + " = 0" + + " ; " + + iterator + " < " + getExp(i).C_getLimit(env_src, i) + + " ; " + + iterator + "++) {"); + env_src.indent(); + } + C_emitCalcIndex(env_src); + getType().C_emitCopy(C_Nest(env_src), C_Nest(env_dst)); + for (int i = getNumExp() - 1 ; i >= 0 ; i--) { + env_src.unindent(); + env_src.println("}"); + } + env_src.unindent(); + env_src.println("}"); + } + + public void Field.C_emitCopy(C_env env_src, C_env env_dst) { + String fnam = env_src.memberAccessor() + getName(); + getType().C_emitCopy(env_src.nestStruct(fnam), env_dst.nestStruct(fnam)); + } + + public void Exp.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst, int i) { + // Ordinary array has no length-member. + } + + public void VariableSize.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst, int i) { + String src = env_src.qualid + env_src.memberAccessor() + "n_" + i; + String dst = env_dst.qualid + env_dst.memberAccessor() + "n_" + i; + env_src.println(dst + " = " + src + ";"); + } + + public void ArrayType.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst) { + for (int i = 0 ; i < getNumExp() ; i++) { + getExp(i).C_emitCopyDecodeLimit(env_src, env_dst, i); + } + } + + public void ArrayType.C_emitCopyArrayAllocate(C_env env_src, C_env env_dst) { + } + + public void VariableArrayType.C_emitCopyArrayAllocate(C_env env_src, + C_env env_dst) + { + env_src.print(env_dst.qualid + env_dst.memberAccessor() + + "a = labcomm" + env_src.verStr + + "_memory_alloc(mem, 1, sizeof(" + + env_src.qualid + env_src.memberAccessor() + "a[0])"); + for (int i = 0 ; i < getNumExp() ; i++) { + env_src.print(" * " + getExp(i).C_getLimit(env_src, i)); + } + env_dst.println(");"); + } + + // Code for deallocation of dynamically allocated data in a copy. + + private void SampleDecl.C_emitCopyDeallocationFunctionParam(C_env env, + String par) + { + env.println("void labcomm" + env.verStr + "_copy_free_" + + env.prefix + getName() + "("); + env.indent(); + env.println("struct labcomm" + env.verStr + "_memory *mem,"); + env.println(env.prefix + getName() + " *" + par); + env.unindent(); + env.print(")"); + } + + public void Decl.C_emitCopyDeallocationDeclaration(C_env env) { + } + + public void SampleDecl.C_emitCopyDeallocationDeclaration(C_env env) { + C_emitCopyDeallocationFunctionParam(env, "c"); + env.println(";"); + } + + public void Decl.C_emitCopyDeallocation(C_env env) { + throw new Error(this.getClass().getName() + + ".C_emitCopy(C_env env)" + + " not declared"); + } + + public void TypeDecl.C_emitCopyDeallocation(C_env env) { + } + + public void SampleDecl.C_emitCopyDeallocation(C_env env) { + String par = "par"; + env = env.nestStruct(par).setPointer(); + + C_emitCopyDeallocationFunctionParam(env, par); + env.println(""); + env.println("{"); + env.indent(); + getType().C_emitCopyDeallocation(env); + env.unindent(); + env.println("}"); + } + + public void Type.C_emitCopyDeallocation(C_env env) { + throw new Error(this.getClass().getName() + + ".C_emitCopyDeallocation(C_env env)" + + " not declared"); + } + + public void VoidType.C_emitCopyDeallocation(C_env env) { + } + + public void PrimType.C_emitCopyDeallocation(C_env env) { + if (C_isDynamic()) { + env.println("labcomm" + env.verStr + "_memory_free(mem, 1, " + + env.accessor() + env.qualid + ");"); + } + } + + public void UserType.C_emitCopyDeallocation(C_env env) { + if (C_isDynamic()) { + lookupType(getName()).getType().C_emitCopyDeallocation(env); + } + } + + public void StructType.C_emitCopyDeallocation(C_env env) { + if (C_isDynamic()) { + for (int i = 0 ; i < getNumField() ; i++) { + getField(i).C_emitCopyDeallocation(env); + } + } + } + + public void ArrayType.C_emitCopyDeallocation(C_env env) { + if (getType().C_isDynamic()) { + env.println("{"); + env.indent(); + C_emitLoopVariables(env); + for (int i = 0 ; i < getNumExp() ; i++) { + String iterator = "i_" + env.depth + "_" + i; + env.println("for (" + iterator + " = 0" + + " ; " + + iterator + " < " + getExp(i).C_getLimit(env, i) + + " ; " + + iterator + "++) {"); + env.indent(); + } + C_emitCalcIndex(env); + getType().C_emitCopyDeallocation(C_Nest(env)); + for (int i = 0 ; i < getNumExp() ; i++) { + env.unindent(); + env.println("}"); + } + env.unindent(); + env.println("}"); + } + } + + public void VariableArrayType.C_emitCopyDeallocation(C_env env) { + super.C_emitCopyDeallocation(env); + env.println("labcomm" + env.verStr + "_memory_free(mem, 1, " + + env.qualid + env.memberAccessor() + "a);"); + } + + public void Field.C_emitCopyDeallocation(C_env env) { + getType().C_emitCopyDeallocation(env.nestStruct(env.memberAccessor() + + getName())); + } +} + aspect C_DecoderIoctl { public void Decl.C_emitDecoderIoctl(C_env env) { diff --git a/examples/Makefile b/examples/Makefile index cdbef3d2ac044cc003c28a599cd3e1df93fe318a..072b2d80a1c7367490cc3c37daaf42ab0d492861 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,4 +1,5 @@ .PHONY: all + all: echo To be done... $(MAKE) -C twoway all diff --git a/examples/simple/compile.sh b/examples/simple/compile.sh index f0a885a871c7e648bd2bb7b11589fb04b367d038..a33018d15b35cc51914ca94e969d03ae59b20596 100644 --- a/examples/simple/compile.sh +++ b/examples/simple/compile.sh @@ -9,7 +9,8 @@ java -jar ../../compiler/labComm.jar --java=gen --c=gen/simple.c --h=gen/simple. javac -cp ../../lib/java:. gen/*.java Encoder.java Decoder.java -gcc -Wall -Werror -I. -I../../lib/c -L../../lib/c \ +gcc -Wall -Werror -Wno-unused-function \ + -I. -I../../lib/c -L../../lib/c \ -o example_encoder example_encoder.c gen/simple.c \ -llabcomm2013 -Tlabcomm.linkscript gcc -Wall -Werror -I . -I ../../lib/c -L../../lib/c \ diff --git a/examples/twoway/Makefile b/examples/twoway/Makefile index b14550b48aff392429a8aaec85f2fb00e8077d12..60b5708efd2d48df21b41e87b19e9d2eb1534161 100644 --- a/examples/twoway/Makefile +++ b/examples/twoway/Makefile @@ -2,7 +2,7 @@ TARGETS=client server LABCOMM_JAR=../../compiler/labComm.jar LABCOMM=java -jar $(LABCOMM_JAR) -CFLAGS=-O3 -g -Wall -Werror -I../../lib/c -I. +CFLAGS=-O3 -g -Wall -Werror -I../../lib/c -I. -Wno-unused-function all: $(TARGETS:%=gen/%) diff --git a/lib/c/2006/labcomm2006.h b/lib/c/2006/labcomm2006.h index 20db98efe70e1f379b4f36975940276216e4715e..938aa2d7e7612dfc9554e41600ec8cad930ccee0 100644 --- a/lib/c/2006/labcomm2006.h +++ b/lib/c/2006/labcomm2006.h @@ -26,8 +26,13 @@ #define LABCOMM_VERSION "LabComm2006" #include <stdarg.h> -#include <stdint.h> -#include <unistd.h> + +#ifdef LABCOMM_COMPAT + #include LABCOMM_COMPAT +#else + #include <stdint.h> + #include <unistd.h> +#endif #include "labcomm2006_error.h" #include "labcomm2006_scheduler.h" diff --git a/lib/c/2006/labcomm2006_fd_reader.c b/lib/c/2006/labcomm2006_fd_reader.c index 7c0596094eba5dbd067f4debd05e049ea5ac98f5..485be6bc9eee84f1ba4bd546c12bb7a8369a8e80 100644 --- a/lib/c/2006/labcomm2006_fd_reader.c +++ b/lib/c/2006/labcomm2006_fd_reader.c @@ -96,7 +96,7 @@ static int fd_fill(struct labcomm2006_reader *r, int err; r->pos = 0; - err = read(fd_reader->fd, r->data, r->data_size); + err = read(fd_reader->fd, (char *) r->data, r->data_size); if (err <= 0) { r->count = 0; r->error = -EPIPE; diff --git a/lib/c/2006/labcomm2006_fd_writer.c b/lib/c/2006/labcomm2006_fd_writer.c index d93c63b6c9821e1f92c95193b0a9b51c00cda518..af058b98465f24f2f01ed8d935ec3906960d61bd 100644 --- a/lib/c/2006/labcomm2006_fd_writer.c +++ b/lib/c/2006/labcomm2006_fd_writer.c @@ -107,7 +107,7 @@ static int fd_flush(struct labcomm2006_writer *w, start = 0; err = 0; while (start < w->pos) { - err = write(fd_context->fd, &w->data[start], w->pos - start); + err = write(fd_context->fd, (char *) &w->data[start], w->pos - start); if (err <= 0) { break; } diff --git a/lib/c/2006/labcomm2006_private.h b/lib/c/2006/labcomm2006_private.h index 1efd360495033ca1d834e5aa1cc4730d9d948e3b..1be45d2e0a3d98c3744373895389f78f9b6cf1ab 100644 --- a/lib/c/2006/labcomm2006_private.h +++ b/lib/c/2006/labcomm2006_private.h @@ -28,12 +28,12 @@ #else #include <endian.h> #include <stdio.h> + #include <stdint.h> + #include <unistd.h> #endif -#include <stdint.h> //#include <stdlib.h> #include <string.h> -#include <unistd.h> #include "labcomm2006.h" /* diff --git a/lib/c/2006/labcomm2006_scheduler.h b/lib/c/2006/labcomm2006_scheduler.h index d4a6c6dd2d67ae200a61807e9e3ddeffc1539456..d4ea80d78707c0c171a43bf7014db6ad4387718a 100644 --- a/lib/c/2006/labcomm2006_scheduler.h +++ b/lib/c/2006/labcomm2006_scheduler.h @@ -22,8 +22,12 @@ #ifndef _LABCOMM_SCHEDULER_H_ #define _LABCOMM_SCHEDULER_H_ -#include <unistd.h> -#include <stdint.h> +#ifdef LABCOMM_COMPAT + #include LABCOMM_COMPAT +#else + #include <unistd.h> + #include <stdint.h> +#endif struct labcomm2006_time; diff --git a/lib/c/Makefile b/lib/c/Makefile index 21aa3402be7d797b914f0957af33eec8f96f2f09..4929b78d238e622c066f794f869f6f8bd0ae7edd 100644 --- a/lib/c/Makefile +++ b/lib/c/Makefile @@ -1,23 +1,40 @@ ## Macros UNAME_S=$(shell uname -s) +ALL_DEPS=liblabcomm.a liblabcomm.so.1 liblabcomm2006.a liblabcomm2006.so.1 liblabcomm2013.a liblabcomm2013.so.1 + ifeq ($(UNAME_S),Linux) - CC=gcc CFLAGS=-std=c99 -g -Wall -Werror -O3 -I. -Itest -I2006 + CC=$(CROSS_COMPILE)gcc + LD=$(CROSS_COMPILE)ld LDFLAGS=-L. LDLIBS=-llabcomm -llabcomm2006 -lrt MAKESHARED=gcc -o $1 -shared -Wl,-soname,$2 $3 -lc -lrt else ifeq ($(UNAME_S),Darwin) - CC=clang + CC=$(CROSS_COMPILE)clang + LD=$(CROSS_COMPILE)ld CFLAGS=-g -Wall -Werror -O3 -I. -Itest \ -DLABCOMM_COMPAT=\"labcomm_compat_osx.h\" \ -Wno-tautological-compare -Wno-unused-function LDFLAGS=-L. LDLIBS=-llabcomm -llabcomm2006 MAKESHARED=clang -o $1 -shared -Wl,-install_name,$2 $3 -lc +else ifneq ($(findstring CYGWIN,$(UNAME_S)),) + CFLAGS=-std=c99 -g -Wall -Werror -O3 -I. -Itest + CC=$(CROSS_COMPILE)gcc + LD=$(CROSS_COMPILE)ld + LDFLAGS=-L. + LDLIBS=-llabcomm -lrt + ALL_DEPS:=$(filter-out %.so.1, $(ALL_DEPS)) # No -fPIC supported in windows? else $(error Unknown system $(UNAME_S)) endif +ifeq ($(CROSS_COMPILE),i586-wrs-vxworks-) + ALL_DEPS:=$(filter-out %.so.1, $(ALL_DEPS)) # PIC is only supported for RTPs + CFLAGS:=$(CFLAGS) -DLABCOMM_COMPAT=\"labcomm_compat_vxworks.h\" +endif +# TODO: Support for Codesourcery ARM toolchain. + OBJS2006=2006/labcomm2006_memory.o \ 2006/labcomm2006_error.o \ 2006/labcomm2006_default_error_handler.o \ @@ -50,6 +67,7 @@ TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding \ test_signature_numbers \ test_labcomm \ test_labcomm_pthread_scheduler \ + test_labcomm_copy # #FIXME: test_labcomm test_labcomm_errors TEST_DIR=test @@ -69,7 +87,7 @@ endif .PHONY: all run-test clean distclean -all: liblabcomm.a liblabcomm.so.1 liblabcomm2006.a liblabcomm2006.so.1 liblabcomm2013.a liblabcomm2013.so.1 +all: $(ALL_DEPS) liblabcomm.a: $(OBJS) $(OBJS2006) ar -r $@ $^ @@ -150,6 +168,7 @@ clean: $(RM) test/testdata/gen/*.[cho] $(RM) test/gen/*.[cho] $(RM) $(TEST_DIR)/test_labcomm + $(RM) $(TEST_DIR)/test_labcomm_copy distclean: clean $(RM) liblabcomm.so.1 @@ -169,6 +188,7 @@ $(TEST_DIR)/test_signature_numbers.c: $(TEST_DIR)/gen/another_encoding.h $(TEST_DIR)/test_signature_numbers.c: $(TEST_DIR)/gen/generated_encoding.h $(TEST_DIR)/test_signature_numbers: $(TEST_DIR)/gen/another_encoding.o $(TEST_DIR)/test_signature_numbers: $(TEST_DIR)/gen/generated_encoding.o +$(TEST_DIR)/test_labcomm_copy: $(TEST_DIR)/gen/generated_encoding.o $(TEST_DIR)/gen/test_sample.o $(TEST_DIR)/gen/more_types.o labcomm_fd_reader.o: labcomm_private.h labcomm_fd_writer.o: labcomm_private.h labcomm_dynamic_buffer_writer.o: labcomm_private.h diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c index cb48e47df9c4798768bdb0b8a42e40067ad0aa2c..ed4e61779d2d21eb2025fd7f16ca6430e26ec0de 100644 --- a/lib/c/labcomm.c +++ b/lib/c/labcomm.c @@ -246,7 +246,7 @@ void labcomm_set_local_index(struct labcomm_signature *signature) { if (signature->index != 0) { labcomm_error_fatal_global(LABCOMM_ERROR_SIGNATURE_ALREADY_SET, - "%s", signature->name); + "Signature already set: %s\n", signature->name); } signature->index = local_index; local_index++; @@ -256,7 +256,7 @@ int labcomm_get_local_index(struct labcomm_signature *signature) { if (signature->index == 0) { labcomm_error_fatal_global(LABCOMM_ERROR_SIGNATURE_NOT_SET, - "%s", signature->name); + "Signature not set: %s\n", signature->name); } return signature->index; } diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h index b83cdf85faa6dc4890d489ec915b5329090993a9..0c264bcb956ceb73bcddcd6027318c6763340838 100644 --- a/lib/c/labcomm.h +++ b/lib/c/labcomm.h @@ -24,8 +24,14 @@ #define _LABCOMM_H_ #include <stdarg.h> -#include <stdint.h> -#include <unistd.h> + +#ifdef LABCOMM_COMPAT + #include LABCOMM_COMPAT +#else + #include <stdint.h> + #include <unistd.h> +#endif + #include "labcomm_error.h" #include "labcomm_scheduler.h" diff --git a/lib/c/labcomm_compat_vxworks.h b/lib/c/labcomm_compat_vxworks.h index f05ee787d334e27dd32ef03bd0ff84b3c2cea086..ab32a5025c28d3a51c551f234291441ee9ebf7df 100644 --- a/lib/c/labcomm_compat_vxworks.h +++ b/lib/c/labcomm_compat_vxworks.h @@ -1,7 +1,22 @@ +#ifndef _LABCOMM_COMPAT_VXWORKS_H_ +#define _LABCOMM_COMPAT_VXWORKS_H_ + #ifndef __VXWORKS__ #error "__VXWORKS__" not defined #endif +#include <types/vxTypes.h> +#include <selectLib.h> +#include <types.h> +#include <timers.h> +#include <stdio.h> +#include <private/stdioP.h> + +#ifdef __INT64_MAX__ +#undef INT64_MAX +#define INT64_MAX __INT64_MAX__ +#endif + #if (CPU == PPC603) #undef _LITTLE_ENDIAN #endif @@ -10,3 +25,6 @@ #undef _BIG_ENDIAN #endif +extern unsigned int cpuFrequency; + +#endif diff --git a/lib/c/labcomm_decoder.c b/lib/c/labcomm_decoder.c index d6ecd5e5103e82faf39d8edf8c7f24228736bb5c..0de42d3d1be477be7ee46bd60788c853a2b2c512 100644 --- a/lib/c/labcomm_decoder.c +++ b/lib/c/labcomm_decoder.c @@ -67,6 +67,7 @@ struct labcomm_decoder *labcomm_decoder_new( result->error = error; result->memory = memory; result->scheduler = scheduler; + result->on_error = on_error_fprintf; LABCOMM_SIGNATURE_ARRAY_INIT(result->local, struct sample_entry); LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local, int); } @@ -94,7 +95,8 @@ static int collect_flat_signature( if (result < 0) { goto out; } if (type >= LABCOMM_USER) { decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3, - "Implement %s ... (1) for type 0x%x\n", __FUNCTION__, type); + "Implement %s ... (1) for type 0x%x\n", + __FUNCTION__, type); } else { labcomm_write_packed32(writer, type); switch (type) { @@ -134,8 +136,9 @@ static int collect_flat_signature( } break; default: { result = -ENOSYS; - decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3, - "Implement %s (2) for type 0x%x...\n", __FUNCTION__, type); + decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3, + "Implement %s (2) for type 0x%x...\n", + __FUNCTION__, type); } break; } } @@ -199,7 +202,8 @@ static int decode_typedef_or_sample(struct labcomm_decoder *d, int kind) LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN, &signature.size); if (err < 0) { - fprintf(stderr, "Failed to get size: %s\n", strerror(-err)); + d->on_error(LABCOMM_ERROR_BAD_WRITER, 2, + "Failed to get size: %s\n", strerror(-err)); result = -ENOENT; goto free_signature_name; } @@ -207,7 +211,8 @@ static int decode_typedef_or_sample(struct labcomm_decoder *d, int kind) LABCOMM_IOCTL_WRITER_GET_BYTE_POINTER, &signature.signature); if (err < 0) { - fprintf(stderr, "Failed to get pointer: %s\n", strerror(-err)); + d->on_error(LABCOMM_ERROR_BAD_WRITER, 2, + "Failed to get pointer: %s\n", strerror(-err)); result = -ENOENT; goto free_signature_name; } @@ -253,8 +258,8 @@ static int decode_typedef_or_sample(struct labcomm_decoder *d, int kind) d->on_new_datatype(d, &signature); result = -ENOENT; } else if (entry->index && entry->index != remote_index) { - d->on_error(LABCOMM_ERROR_DEC_INDEX_MISMATCH, 5, - "%s(): index mismatch '%s' (id=0x%x != 0x%x)\n", + d->on_error(LABCOMM_ERROR_DEC_INDEX_MISMATCH, 5, + "%s(): index mismatch '%s' (id=0x%x != 0x%x)\n", __FUNCTION__, signature.name, entry->index, remote_index); result = -ENOENT; #endif diff --git a/lib/c/labcomm_default_memory.h b/lib/c/labcomm_default_memory.h index 09112099de57360fccb9897ab1a7926830df60b8..8b22301ed7c9e9bdaf8bf13f98661af264b864d3 100644 --- a/lib/c/labcomm_default_memory.h +++ b/lib/c/labcomm_default_memory.h @@ -21,7 +21,6 @@ #include <stdlib.h> #include "labcomm.h" -#include "labcomm_private.h" extern struct labcomm_memory *labcomm_default_memory; diff --git a/lib/c/labcomm_error.c b/lib/c/labcomm_error.c index 278c5f3549f4df229bba97cde7fa08bd89e12ea3..5bfea6ed319e2a8457fcbd57cb6e747e0e5af7e8 100644 --- a/lib/c/labcomm_error.c +++ b/lib/c/labcomm_error.c @@ -21,12 +21,19 @@ #include <stdlib.h> #include <stdio.h> +#include <stdarg.h> #include "labcomm_error.h" - + void labcomm_error_fatal_global(enum labcomm_error error, char *format, ...) { + va_list args; + fprintf(stderr, "Fatal error %d\n", error); + va_start(args, format); + vprintf(format, args); + va_end(args); + exit(1); } diff --git a/lib/c/labcomm_error.h b/lib/c/labcomm_error.h index dd124c96fe80b4bec7c95d8e087fa89d052424be..80e4805d96c071967d3be7b964c2d549e304f6ef 100644 --- a/lib/c/labcomm_error.h +++ b/lib/c/labcomm_error.h @@ -64,5 +64,7 @@ LABCOMM_ERROR(LABCOMM_ERROR_MEMORY, "Could not allocate memory") LABCOMM_ERROR(LABCOMM_ERROR_USER_DEF, "User defined error") +LABCOMM_ERROR(LABCOMM_ERROR_BAD_WRITER, + "Decoder: writer_ioctl() failed") #endif diff --git a/lib/c/labcomm_fd_reader.c b/lib/c/labcomm_fd_reader.c index e397c84401a27a59aec74da39e37cedbf111e7f5..65a9fbbc20f3ed7526677fa3feeb6ef13465bf74 100644 --- a/lib/c/labcomm_fd_reader.c +++ b/lib/c/labcomm_fd_reader.c @@ -98,7 +98,7 @@ static int fd_fill(struct labcomm_reader *r, int err; r->pos = 0; - err = read(fd_reader->fd, r->data, r->data_size); + err = read(fd_reader->fd, (char *)r->data, r->data_size); if (err <= 0) { r->count = 0; r->error = -EPIPE; diff --git a/lib/c/labcomm_fd_writer.c b/lib/c/labcomm_fd_writer.c index acf6934ad7c50eec43dba087b8d863e045ac4703..9ea707fdae04c8e4dece32fa63a342d7b86687eb 100644 --- a/lib/c/labcomm_fd_writer.c +++ b/lib/c/labcomm_fd_writer.c @@ -101,7 +101,7 @@ static int fd_flush(struct labcomm_writer *w, start = 0; err = 0; while (start < w->pos) { - err = write(fd_context->fd, &w->data[start], w->pos - start); + err = write(fd_context->fd, (char *)&w->data[start], w->pos - start); if (err <= 0) { break; } diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h index ab4e315d0b28f89fb5e8bbaa607e0848dbe37084..e615799bb1b92225d4f6604aa36e8a33953fa06c 100644 --- a/lib/c/labcomm_private.h +++ b/lib/c/labcomm_private.h @@ -28,12 +28,12 @@ #else #include <endian.h> #include <stdio.h> + #include <stdint.h> + #include <unistd.h> #endif -#include <stdint.h> //#include <stdlib.h> #include <string.h> -#include <unistd.h> #include "labcomm.h" /* @@ -270,6 +270,11 @@ static inline char *labcomm_read_string(struct labcomm_reader *r) length = labcomm_read_packed32(r); result = labcomm_memory_alloc(r->memory, 1, length + 1); + if (!result) { + on_error_fprintf(LABCOMM_ERROR_MEMORY, 4, "%d byte at %s:%d", + length+1, __FUNCTION__, __LINE__); + return NULL; + } for (pos = 0 ; pos < length ; pos++) { if (r->pos >= r->count) { labcomm_reader_fill(r, r->action_context); diff --git a/lib/c/labcomm_scheduler.h b/lib/c/labcomm_scheduler.h index 4aef48daf6c734cafdb25780a43954d0340beb71..07f74c281ab7fff57ec8edf86e6f04219f2e3427 100644 --- a/lib/c/labcomm_scheduler.h +++ b/lib/c/labcomm_scheduler.h @@ -22,8 +22,12 @@ #ifndef _LABCOMM_SCHEDULER_H_ #define _LABCOMM_SCHEDULER_H_ -#include <unistd.h> -#include <stdint.h> +#ifdef LABCOMM_COMPAT + #include LABCOMM_COMPAT +#else + #include <unistd.h> + #include <stdint.h> +#endif struct labcomm_time; diff --git a/lib/c/labcomm_scheduler_private.h b/lib/c/labcomm_scheduler_private.h index cc4d50e40c518eb7c43b928918e1f568a8301065..398552e0e434f17b4f332364ce09256dcb4d682c 100644 --- a/lib/c/labcomm_scheduler_private.h +++ b/lib/c/labcomm_scheduler_private.h @@ -22,7 +22,12 @@ #ifndef _LABCOMM_SCHEDULER_PRIVATE_H_ #define _LABCOMM_SCHEDULER_PRIVATE_H_ -#include <unistd.h> +#ifdef LABCOMM_COMPAT + #include LABCOMM_COMPAT +#else + #include <unistd.h> +#endif + #include "labcomm_scheduler.h" struct labcomm_time { diff --git a/lib/c/test/more_types.lc b/lib/c/test/more_types.lc new file mode 100644 index 0000000000000000000000000000000000000000..91fb9358134fccf3149507e96d27680465c50411 --- /dev/null +++ b/lib/c/test/more_types.lc @@ -0,0 +1,7 @@ +sample string S; +sample int A[8]; +sample struct { + string s1; + string s2; +} NS; +sample string AS[_]; diff --git a/lib/c/test/test_labcomm_copy.c b/lib/c/test/test_labcomm_copy.c new file mode 100644 index 0000000000000000000000000000000000000000..b7b5e0829b01a6ad98306fbf56263bbdca61d6e5 --- /dev/null +++ b/lib/c/test/test_labcomm_copy.c @@ -0,0 +1,242 @@ +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <assert.h> +#include <err.h> + +#include "labcomm.h" +#include "labcomm_private.h" +#include "labcomm_default_error_handler.h" +#include "labcomm_default_memory.h" +#include "labcomm_default_scheduler.h" +#include "labcomm_fd_writer.h" +#include "labcomm_fd_reader.h" +#include "test/gen/generated_encoding.h" +#include "test/gen/test_sample.h" +#include "test/gen/more_types.h" + +#define DATA_FILE "copy_test.dat" + +static void handle_s1(generated_encoding_S1 *v, void *context) +{ + labcomm_copy_generated_encoding_S1(labcomm_default_memory, context, v); +} + +static void handle_b(generated_encoding_B *v, void *context) +{ + labcomm_copy_generated_encoding_B(labcomm_default_memory, context, v); +} + +static void handle_i(generated_encoding_I *v, void *context) +{ + labcomm_copy_generated_encoding_I(labcomm_default_memory, context, v); +} + +static void handle_p(generated_encoding_P *v, void *context) +{ + labcomm_copy_generated_encoding_P(labcomm_default_memory, context, v); +} + +static void handle_test_var(test_sample_test_var *v, void *context) +{ + labcomm_copy_test_sample_test_var(labcomm_default_memory, context, v); +} + +static void handle_a(more_types_A *v, void *context) +{ + labcomm_copy_more_types_A(labcomm_default_memory, context, v); +} + +static void handle_s(more_types_S *v, void *context) +{ + labcomm_copy_more_types_S(labcomm_default_memory, context, v); +} + +static void handle_ns(more_types_NS *v, void *context) +{ + labcomm_copy_more_types_NS(labcomm_default_memory, context, v); +} + +static void handle_as(more_types_AS *v, void *context) +{ + labcomm_copy_more_types_AS(labcomm_default_memory, context, v); +} + +int main(int argc, char **argv) +{ + struct labcomm_encoder *encoder; + struct labcomm_decoder *decoder; + int fd; + generated_encoding_S1 s1; + generated_encoding_S1 cache_s1; + generated_encoding_B b; + generated_encoding_B cache_b; + generated_encoding_I I; + generated_encoding_I cache_I; + generated_encoding_P p; + generated_encoding_P cache_p; + test_sample_test_var test_var; + test_sample_test_var cache_test_var; + more_types_A a; + more_types_A cache_a; + more_types_S s; + more_types_S cache_s = NULL; + more_types_NS ns; + more_types_NS cache_ns; + more_types_AS as; + more_types_AS cache_as; + + fd = open(DATA_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644); + if (fd == -1) + err(1, "open()"); + encoder = + labcomm_encoder_new(labcomm_fd_writer_new(labcomm_default_memory, fd, 0), + labcomm_default_error_handler, + labcomm_default_memory, + labcomm_default_scheduler); + + labcomm_encoder_register_generated_encoding_S1(encoder); + s1.i = 1; + labcomm_encode_generated_encoding_S1(encoder, &s1); + + labcomm_encoder_register_generated_encoding_B(encoder); + b = 2; + labcomm_encode_generated_encoding_B(encoder, &b); + + labcomm_encoder_register_generated_encoding_I(encoder); + I.n_0 = 3; + I.a = calloc(I.n_0, sizeof(I.a[0])); + I.a[0] = 4; + I.a[1] = 5; + I.a[2] = 6; + labcomm_encode_generated_encoding_I(encoder, &I); + + labcomm_encoder_register_generated_encoding_P(encoder); + p.n_0 = 7; + p.a = calloc(p.n_0, sizeof(p.a[0])); + for (int i = 0; i < p.n_0; i++) + p.a[i].i = 8 + i; + labcomm_encode_generated_encoding_P(encoder, &p); + + labcomm_encoder_register_test_sample_test_var(encoder); + test_var.n_0 = 2; + test_var.n_1 = 7; + test_var.a = calloc(test_var.n_0 * test_var.n_1, sizeof(*test_var.a)); + for (int i = 0; i < test_var.n_0; i++) + for (int j = 0; j < test_var.n_1; j++) + test_var.a[i] = 10 * i + j; + labcomm_encode_test_sample_test_var(encoder, &test_var); + + labcomm_encoder_register_more_types_A(encoder); + for (int i = 0; i < sizeof(a.a) / sizeof(a.a[0]); i++) + a.a[i] = i; + labcomm_encode_more_types_A(encoder, &a); + + labcomm_encoder_register_more_types_S(encoder); + s = "this is a string"; + labcomm_encode_more_types_S(encoder, &s); + + labcomm_encoder_register_more_types_NS(encoder); + ns.s1 = "this is a string"; + ns.s2 = "this is a another string"; + labcomm_encode_more_types_NS(encoder, &ns); + + labcomm_encoder_register_more_types_AS(encoder); + as.n_0 = 3; + as.a = calloc(as.n_0, sizeof(as.a[0])); + as.a[0] = "string 0"; + as.a[1] = "string 1"; + as.a[2] = "string 2"; + labcomm_encode_more_types_AS(encoder, &as); + + labcomm_encoder_free(encoder); + encoder = NULL; + lseek(fd, 0, SEEK_SET); + decoder = + labcomm_decoder_new(labcomm_fd_reader_new(labcomm_default_memory, fd, 0), + labcomm_default_error_handler, + labcomm_default_memory, + labcomm_default_scheduler); + + labcomm_decoder_register_generated_encoding_S1(decoder, handle_s1, &cache_s1); + labcomm_decoder_register_generated_encoding_B(decoder, handle_b, &cache_b); + labcomm_decoder_register_generated_encoding_I(decoder, handle_i, &cache_I); + labcomm_decoder_register_generated_encoding_P(decoder, handle_p, &cache_p); + labcomm_decoder_register_test_sample_test_var(decoder, handle_test_var, + &cache_test_var); + labcomm_decoder_register_more_types_A(decoder, handle_a, &cache_a); + labcomm_decoder_register_more_types_S(decoder, handle_s, &cache_s); + labcomm_decoder_register_more_types_NS(decoder, handle_ns, &cache_ns); + labcomm_decoder_register_more_types_AS(decoder, handle_as, &cache_as); + + while (labcomm_decoder_decode_one(decoder) > 0) ; + + assert(cache_s1.i == s1.i); + puts("S1 copied ok"); + + assert(cache_b == b); + puts("B copied ok"); + + assert(cache_I.n_0 == I.n_0); + assert(cache_I.a[0] == I.a[0]); + assert(cache_I.a[1] == I.a[1]); + assert(cache_I.a[2] == I.a[2]); + free(I.a); + puts("I copied ok"); + + assert(cache_p.n_0 == p.n_0); + for (int i = 0; i < p.n_0; i++) + assert(cache_p.a[i].i == p.a[i].i); + free(p.a); + puts("P copied ok"); + + assert(cache_test_var.n_0 == test_var.n_0); + assert(cache_test_var.n_1 == test_var.n_1); + for (int i = 0; i < test_var.n_0; i++) + for (int j = 0; j < test_var.n_1; j++) + assert(cache_test_var.a[p.n_0 * i + j] == test_var.a[p.n_0 * i + j]); + free(test_var.a); + puts("test_var copied ok"); + + for (int i = 0; i < sizeof(a.a) / sizeof(a.a[0]); i++) + assert(cache_a.a[i] == a.a[i]); + puts("A copied ok"); + + assert(!strcmp(cache_s, s)); + puts("S copied ok"); + + assert(!strcmp(cache_ns.s1, ns.s1)); + assert(!strcmp(cache_ns.s2, ns.s2)); + puts("NS copied ok"); + + for (int i = 0; i < as.n_0; i++) + assert(!strcmp(cache_as.a[i], as.a[i])); + free(as.a); + puts("AS copied ok"); + + labcomm_decoder_free(decoder); + close(fd); + unlink(DATA_FILE); + + labcomm_copy_free_generated_encoding_S1(labcomm_default_memory, &cache_s1); + puts("S1 deallocated ok"); + labcomm_copy_free_generated_encoding_B(labcomm_default_memory, &cache_b); + puts("B deallocated ok"); + labcomm_copy_free_generated_encoding_I(labcomm_default_memory, &cache_I); + puts("I deallocated ok"); + labcomm_copy_free_generated_encoding_P(labcomm_default_memory, &cache_p); + puts("P deallocated ok"); + labcomm_copy_free_test_sample_test_var(labcomm_default_memory, &cache_test_var); + puts("test_var deallocated ok"); + labcomm_copy_free_more_types_A(labcomm_default_memory, &cache_a); + puts("A deallocated ok"); + labcomm_copy_free_more_types_S(labcomm_default_memory, &cache_s); + puts("S deallocated ok"); + labcomm_copy_free_more_types_NS(labcomm_default_memory, &cache_ns); + puts("NS deallocated ok"); + labcomm_copy_free_more_types_AS(labcomm_default_memory, &cache_as); + puts("AS deallocated ok"); +} diff --git a/test/Makefile b/test/Makefile index 376949f2cec1c70850223cc952f2b87692aeda2d..0fe91b486994f62b4254a2d66ef35ece03947f33 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,7 +2,7 @@ TESTS=basic simple nested LABCOMM_JAR=../compiler/labComm.jar LABCOMM=java -jar $(LABCOMM_JAR) -CFLAGS=-O3 -g -Wall -Werror +CFLAGS=-O3 -g -Wall -Werror -Wno-unused-function all: