diff --git a/.bzrignore b/.bzrignore index d93700e3f04517e9e76477b9b213278cb2ff54d9..a44c36a1b8f4d0fad9ff624d30343bf174ad1c73 100644 --- a/.bzrignore +++ b/.bzrignore @@ -34,3 +34,5 @@ lib/c/test/test_labcomm_generated_encoding lib/java/se/lth/control/labcomm/WriterWrapper.class lib/c/liblabcomm.so.1 lib/c/test/test_labcomm_pthread_scheduler +lib/c/liblabcomm_plain_c.so.1 +lib/c/test/test_signature_plain_c diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag index 551e14d77b0e0c332338d7ec86871756ce1425e7..d6ae8960301ba403718791acc965a55fa512fef9 100644 --- a/compiler/C_CodeGen.jrag +++ b/compiler/C_CodeGen.jrag @@ -201,8 +201,14 @@ aspect C_CodeGen { } public void Program.C_emitC(C_env env) { - C_emitSignature(env); + env.print("#if ! defined(LABCOMM_GEN_CODE) && "); + env.println("! defined(LABCOMM_GEN_SIGNATURE)"); + env.println("#define LABCOMM_GEN_CODE"); + env.println("#define LABCOMM_GEN_SIGNATURE"); + env.println("#endif"); + env.println("#if defined(LABCOMM_GEN_CODE)"); for (int i = 0; i < getNumDecl(); i++) { + getDecl(i).C_emitSignatureBitsAndForward(env); getDecl(i).C_emitDecoder(env); getDecl(i).C_emitDecoderRegisterHandler(env); getDecl(i).C_emitDecoderIoctl(env); @@ -211,6 +217,12 @@ aspect C_CodeGen { getDecl(i).C_emitEncoderIoctl(env); getDecl(i).C_emitSizeof(env); } + env.println("#endif"); + env.println("#if defined(LABCOMM_GEN_SIGNATURE)"); + for (int i = 0; i < getNumDecl(); i++) { + getDecl(i).C_emitSignature(env); + } + env.println("#endif"); } } @@ -441,7 +453,7 @@ aspect C_Decoder { public void SampleDecl.C_emitDecoder(C_env env) { env = env.nestStruct("v"); - env.println("static void decode_" + getName() + "("); + env.println("static void decode_" + env.prefix + getName() + "("); env.indent(); env.println("struct labcomm_reader *r,"); env.println("void (*handle)("); @@ -640,7 +652,7 @@ aspect C_Decoder { env.indent(); env.println("d,"); env.println("&labcomm_signature_" + env.prefix + getName() + ","); - env.println("(labcomm_decoder_function)decode_" + getName() + ","); + env.println("(labcomm_decoder_function)decode_" + env.prefix + getName() + ","); env.println("(labcomm_handler_function)handler,"); env.println("context"); env.unindent(); @@ -701,7 +713,7 @@ aspect C_Encoder { public void SampleDecl.C_emitEncoder(C_env env) { env = env.nestStruct("(*v)"); - env.println("static int encode_" + getName() + "("); + env.println("static int encode_" + env.prefix + getName() + "("); env.indent(); env.println("struct labcomm_writer *w,"); env.println(env.prefix + getName() + " *v"); @@ -725,7 +737,7 @@ aspect C_Encoder { env.indent(); env.println("return labcomm_internal_encode(e, &labcomm_signature_" + env.prefix + getName() + - ", (labcomm_encoder_function)encode_" + getName() + + ", (labcomm_encoder_function)encode_" + env.prefix + getName() + ", v);"); env.unindent(); env.println("}"); @@ -820,7 +832,7 @@ aspect C_Encoder { env.indent(); env.println("e,"); env.println("&labcomm_signature_" + env.prefix + getName() + ","); - env.println("(labcomm_encoder_function)encode_" + getName()); + env.println("(labcomm_encoder_function)encode_" + env.prefix + getName()); env.unindent(); env.println(");"); env.unindent(); @@ -868,25 +880,18 @@ aspect C_EncoderIoctl { aspect C_Signature { - public void ASTNode.C_emitSignature(C_env env) { + public void ASTNode.C_emitSignatureBitsAndForward(C_env env) { throw new Error(this.getClass().getName() + - ".C_emitSignature(C_env env)" + + ".C_emitSignaturBitsAndForwarde(C_env env)" + " not declared"); } - public void Program.C_emitSignature(C_env env) { - for (int i = 0; i < getNumDecl(); i++) { - getDecl(i).C_emitSignature(env); - } + public void Decl.C_emitSignatureBitsAndForward(C_env env) { } - public void Decl.C_emitSignature(C_env env) { - } - - public void SampleDecl.C_emitSignature(C_env env) { + public void SampleDecl.C_emitSignatureBitsAndForward(C_env env) { env.println("static unsigned char signature_bytes_" + - getName() + "[] = {"); -// C_genFlatSignature(env); + env.prefix + getName() + "[] = {"); SignatureList signature = signature(); for (int i = 0 ; i < signature.size() ; i++) { String comment = signature.getComment(i); @@ -904,97 +909,31 @@ aspect C_Signature { } env.println("};"); env.println("LABCOMM_DECLARE_SIGNATURE(labcomm_signature_" + - env.prefix + getName() + ") = {"); - env.indent(); - env.println("LABCOMM_SAMPLE, \"" + getName() + "\","); - env.println("(int (*)(struct labcomm_signature *, void *))labcomm_sizeof_" + - env.prefix + getName() + ","); - env.println("sizeof(signature_bytes_" + getName() + "),"); - env.println("signature_bytes_"+ getName()); - env.unindent(); - env.println(" };"); + env.prefix + getName() + ");"); } - public void ASTNode.C_genFlatSignature(C_env env) { + public void ASTNode.C_emitSignature(C_env env) { throw new Error(this.getClass().getName() + - ".C_genFlatSignature(C_env env)" + + ".C_emitSignature(C_env env)" + " not declared"); } - public void TypeDecl.C_genFlatSignature(C_env env) { - getType().C_genFlatSignature(env); - } - - public void SampleDecl.C_genFlatSignature(C_env env) { - getType().C_genFlatSignature(env); - } - - public void PrimType.C_genFlatSignature(C_env env) { - C_genFlatSignature(env, getToken()); - env.println("// " + getName()); - } - - public void UserType.C_genFlatSignature(C_env env) { - lookupType(getName()).C_genFlatSignature(env); - } - - public void ArrayType.C_genFlatSignature(C_env env) { - C_genFlatSignature(env, LABCOMM_ARRAY); - env.println("// LABCOMM_ARRAY"); - C_genFlatSignature(env, getNumExp()); - env.println("// # of dimensions"); - for (int i = 0 ; i < getNumExp() ; i++) { - getExp(i).C_genFlatSignature(env); - env.println(""); - } - getType().C_genFlatSignature(env); - } - - public void StructType.C_genFlatSignature(C_env env) { - C_genFlatSignature(env, LABCOMM_STRUCT); - env.println("// LABCOMM_STRUCT"); - C_genFlatSignature(env, getNumField()); - env.println("// # of fields"); - for (int i = 0 ; i < getNumField() ; i++) { - getField(i).C_genFlatSignature(env); - } - } - - public void Field.C_genFlatSignature(C_env env) { - C_genFlatSignature(env, getName()); - env.println(""); - getType().C_genFlatSignature(env); - } - - public void IntegerLiteral.C_genFlatSignature(C_env env) { - C_genFlatSignature(env, Integer.parseInt(getValue())); - env.print("// " + getValue()); - } - - public void VariableSize.C_genFlatSignature(C_env env) { - C_genFlatSignature(env, 0); - env.print("// _"); + public void Decl.C_emitSignature(C_env env) { } - public void ASTNode.C_genFlatSignature(C_env env, int value) { - env.print(" "); - for (int i = 24 ; i >= 0 ; i -= 8) { - env.print("0x"); - String hex = Integer.toHexString((value >> i) & 0xff); - if (hex.length() == 1) { env.print("0"); } - env.print(hex); - env.print(", "); - } + public void SampleDecl.C_emitSignature(C_env env) { + env.println("LABCOMM_DECLARE_SIGNATURE(labcomm_signature_" + + env.prefix + getName() + ") = {"); + env.indent(); + env.println("LABCOMM_SAMPLE, \"" + getName() + "\","); + env.println("(int (*)(struct labcomm_signature *, void *))labcomm_sizeof_" + + env.prefix + getName() + ","); + env.println("sizeof(signature_bytes_" + env.prefix + getName() + "),"); + env.println("signature_bytes_" + env.prefix + getName()); + env.unindent(); + env.println(" };"); } - public void ASTNode.C_genFlatSignature(C_env env, String value) { - C_genFlatSignature(env, value.length()); - env.println(""); - env.print(" "); - for (int i = 0 ; i < value.length() ; i++) { - env.print("'" + value.charAt(i) +"', "); - } - } } diff --git a/lib/c/Makefile b/lib/c/Makefile index 979b9899e68c0ca446a39da503394ff395b75a92..811b6e0f677206845b4685ea797a15a6c969b1e7 100644 --- a/lib/c/Makefile +++ b/lib/c/Makefile @@ -5,17 +5,20 @@ CC=gcc CFLAGS=-g -Wall -Werror -O3 -I. -Itest LDFLAGS=-L. #LDLIBS_TEST=-Tlabcomm.linkscript -lcunit -llabcomm -LDLIBS_TEST=-lcunit -llabcomm -Tlabcomm.linkscript -lrt - -OBJS=labcomm_memory.o \ - labcomm_default_error_handler.o \ - labcomm_default_memory.o \ - labcomm_default_scheduler.o \ - labcomm_time.o labcomm_scheduler.o \ - labcomm_encoder.o labcomm_decoder.o \ - labcomm.o \ - labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o \ - labcomm_pthread_scheduler.o \ +LDLIBS_TEST=-llabcomm -Tlabcomm.linkscript -lrt +LDLIBS_TEST_PLAIN_C=-llabcomm_plain_c -lrt + +OBJS_PLAIN_C=labcomm_memory.o \ + labcomm_default_error_handler.o \ + labcomm_default_memory.o \ + labcomm_default_scheduler.o \ + labcomm_time.o labcomm_scheduler.o \ + labcomm_encoder.o labcomm_decoder.o \ + labcomm.o \ + labcomm_dynamic_buffer_writer.o \ + labcomm_fd_reader.o labcomm_fd_writer.o \ + labcomm_pthread_scheduler.o +OBJS=$(OBJS_PLAIN_C) \ labcomm_signature_gnu_ld_tricks.o #FIXME: labcomm_mem_reader.o labcomm_mem_writer.o @@ -23,7 +26,8 @@ LABCOMM_JAR=../../compiler/labComm.jar LABCOMM=java -jar $(LABCOMM_JAR) TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding \ - test_labcomm_pthread_scheduler + test_labcomm_pthread_scheduler \ + test_signature_plain_c # #FIXME: test_labcomm test_labcomm_errors TEST_DIR=test @@ -47,14 +51,21 @@ endif .PHONY: all run-test clean distclean -all: liblabcomm.a liblabcomm.so.1 +all: liblabcomm.a liblabcomm_plain_c.a \ + liblabcomm.so.1 liblabcomm_plain_c.so.1 liblabcomm.a: $(OBJS) - ar -r liblabcomm.a $^ + ar -r $@ $^ + +liblabcomm_plain_c.a: $(OBJS_PLAIN_C) + ar -r $@ $^ liblabcomm.so.1: $(OBJS:%.o=%.pic.o) gcc -shared -Wl,-soname,$@ -o $@ $^ -lc -lrt +liblabcomm_plain_c.so.1: $(OBJS_PLAIN_C:%.o=%.pic.o) + gcc -shared -Wl,-soname,$@ -o $@ $^ -lc -lrt + labcomm.o : labcomm.c labcomm.h labcomm_private.h labcomm_fd_reader_writer.o : labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h labcomm.h labcomm_private.h @@ -81,6 +92,19 @@ $(TEST_DIR)/%.o: $(TEST_DIR)/%.c $(TEST_DIR)/%: $(TEST_DIR)/%.o liblabcomm.a $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(LDLIBS_TEST) +$(TEST_DIR)/test_signature_plain_c_index.o: \ + labcomm_signature_plain_c.c \ + $(TEST_DIR)/gen/generated_encoding.c \ + $(TEST_DIR)/gen/another_encoding.h \ + $(TEST_DIR)/gen/another_encoding.c + $(CC) $(CFLAGS) -o $@ -c $< \ + -DALL_LABCOMM_FILES=\"test/test_signature_plain_c.h\" + +$(TEST_DIR)/test_signature_plain_c: \ + $(TEST_DIR)/test_signature_plain_c.o \ + $(TEST_DIR)/test_signature_plain_c_index.o + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_TEST_PLAIN_C) + $(TEST_DIR)/gen: mkdir -p $@ @@ -118,6 +142,8 @@ clean: distclean: clean $(RM) liblabcomm.so.1 $(RM) liblabcomm.a + $(RM) liblabcomm_plain_c.a + $(RM) liblabcomm_plain_c.so.1 # Extra dependencies $(TEST_DIR)/test_labcomm_basic_type_encoding.o: labcomm_private.h @@ -126,6 +152,8 @@ $(TEST_DIR)/test_labcomm_generated_encoding.o: labcomm_private.h $(TEST_DIR)/test_labcomm_generated_encoding.o: $(TEST_DIR)/gen/generated_encoding.h $(TEST_DIR)/test_labcomm_generated_encoding : $(TEST_DIR)/gen/generated_encoding.o $(TEST_DIR)/test_labcomm: $(TEST_GEN_DIR)/test_sample.o +$(TEST_DIR)/test_signature_plain_c.o: $(TEST_DIR)/gen/another_encoding.h +$(TEST_DIR)/test_signature_plain_c.o: $(TEST_DIR)/gen/generated_encoding.h 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_private.h b/lib/c/labcomm_private.h index 6ea5b4379eab3697708c820531b8b39af3c13265..5735b992798425b8317fa601e8a63b05036383e2 100644 --- a/lib/c/labcomm_private.h +++ b/lib/c/labcomm_private.h @@ -64,8 +64,10 @@ /* * */ +#ifndef LABCOMM_DECLARE_SIGNATURE #define LABCOMM_DECLARE_SIGNATURE(name) \ struct labcomm_signature __attribute__((section("labcomm"),aligned(1))) name +#endif /* * Semi private dynamic memory declarations diff --git a/lib/c/labcomm_signature_gnu_ld_tricks.c b/lib/c/labcomm_signature_gnu_ld_tricks.c index 7ce21ee5f6497c7e60e7a0da468e7724dc60d956..97b0ccbb72d0675749a6ca4e355ebc14c719ec88 100644 --- a/lib/c/labcomm_signature_gnu_ld_tricks.c +++ b/lib/c/labcomm_signature_gnu_ld_tricks.c @@ -1,5 +1,5 @@ /* - labcomm_signature_gnu_ld_tricks.h -- signature handling. + labcomm_signature_gnu_ld_tricks.c -- signature handling. Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se> diff --git a/lib/c/labcomm_signature_plain_c.c b/lib/c/labcomm_signature_plain_c.c new file mode 100644 index 0000000000000000000000000000000000000000..3e500b24b935ac1b1ba98cc09d481e42144333c0 --- /dev/null +++ b/lib/c/labcomm_signature_plain_c.c @@ -0,0 +1,61 @@ +/* + labcomm_signature_plain_c.c -- signature handling. + + Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se> + + This file is part of LabComm. + + LabComm is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LabComm is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#define LABCOMM_DECLARE_SIGNATURE(name) \ + struct labcomm_signature __attribute__((aligned(1))) name + +#include <errno.h> +#include "labcomm.h" +#include "labcomm_signature.h" +#include "labcomm_private.h" + +/* NB: We need to mimic forward declarations done in generated code */ +LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_1); +#define LABCOMM_GEN_CODE +#include ALL_LABCOMM_FILES +#undef LABCOMM_GEN_CODE +LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_2); + +/* NB: We need to force our sentinels out of bss segment, hence -1 */ +LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_1) = { -1, NULL, NULL, 0, NULL}; +#define LABCOMM_GEN_SIGNATURE +#include ALL_LABCOMM_FILES +#undef LABCOMM_GEN_SIGNATURE +LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_2) = { -1, NULL, NULL, 0, NULL}; + +int labcomm_signature_local_index(struct labcomm_signature *s) +{ + int result = -ENOENT; + struct labcomm_signature *labcomm_first_signature; + struct labcomm_signature *labcomm_last_signature; + + if (&labcomm_sentinel_1 < &labcomm_sentinel_2) { + labcomm_first_signature = &labcomm_sentinel_1; + labcomm_last_signature = &labcomm_sentinel_2; + } else { + labcomm_first_signature = &labcomm_sentinel_2; + labcomm_last_signature = &labcomm_sentinel_1; + } + if (labcomm_first_signature <= s && s < labcomm_last_signature) { + result = (int)(s - labcomm_first_signature) + LABCOMM_USER - 1; + } + return result; +} diff --git a/lib/c/test/another_encoding.lc b/lib/c/test/another_encoding.lc new file mode 100644 index 0000000000000000000000000000000000000000..2c545afd19d268a753fcb22753853087cf8f2dc9 --- /dev/null +++ b/lib/c/test/another_encoding.lc @@ -0,0 +1,2 @@ +sample void V; +sample byte B; diff --git a/lib/c/test/test_signature_plain_c.c b/lib/c/test/test_signature_plain_c.c new file mode 100644 index 0000000000000000000000000000000000000000..77fbd704797a3654c7cb5f65330284c8f3a5e7b2 --- /dev/null +++ b/lib/c/test/test_signature_plain_c.c @@ -0,0 +1,26 @@ +#include <stdlib.h> +#include <stdio.h> +#include "test/gen/another_encoding.h" +#include "test/gen/generated_encoding.h" + +extern int labcomm_signature_local_index(struct labcomm_signature *s); + + +static void info(char *name, char *full_name, + struct labcomm_signature *signature) { + printf("%s %s %p -> %d\n", name, full_name, signature, + labcomm_signature_local_index(signature)); + if (labcomm_signature_local_index(signature) < 0x40) { + exit(1); + } +}; + +int main(int argc, char *argv[]) +{ +#define FUNC(name, full_name) \ + extern struct labcomm_signature labcomm_signature_##full_name; \ + info( #name, #full_name, &labcomm_signature_##full_name) + LABCOMM_FORALL_SAMPLES_generated_encoding(FUNC, ;); + LABCOMM_FORALL_SAMPLES_another_encoding(FUNC, ;); + return 0; +} diff --git a/lib/c/test/test_signature_plain_c.h b/lib/c/test/test_signature_plain_c.h new file mode 100644 index 0000000000000000000000000000000000000000..05fcac78b75e5a418e09dd372b0b2b409872c28c --- /dev/null +++ b/lib/c/test/test_signature_plain_c.h @@ -0,0 +1,2 @@ +#include "gen/generated_encoding.c" +#include "gen/another_encoding.c"