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: