diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag index d4450880d9034413dc9b16b6f43c9823915bd2ae..f79bbfce3698346a3c38fb50cb50f85b1292b1b2 100644 --- a/compiler/C_CodeGen.jrag +++ b/compiler/C_CodeGen.jrag @@ -803,8 +803,8 @@ aspect C_Signature { } } env.println("};"); - env.println("labcomm_signature_t labcomm_signature_" + - env.prefix + getName() + " = {"); + env.println("LABCOMM_DECLARE_SIGNATURE(labcomm_signature_" + + env.prefix + getName() + ") = {"); env.indent(); env.println("LABCOMM_SAMPLE, \"" + getName() + "\","); env.println("(int (*)(labcomm_signature_t *, void *))labcomm_sizeof_" + diff --git a/lib/c/Makefile b/lib/c/Makefile index dd08db025ec66e0511a55cdc55cd544cc846512f..f201fa66a5421b35325bc66f1c86984d6a71b822 100644 --- a/lib/c/Makefile +++ b/lib/c/Makefile @@ -2,15 +2,15 @@ # Use LLVM clang if it's found. CC = $(shell hash clang 2>/dev/null && echo clang || echo gcc) -CFLAGS = -g -Wall -Werror -O3 -I. -Itest +CFLAGS = -g -Wall -Werror -O3 -I. -Itest -DLABCOMM_ENCODER_LINEAR_SEARCH LDFLAGS = -L. -LDLIBS_TEST = -lcunit -llabcomm +LDLIBS_TEST = -Tlabcomm.linkscript -lcunit -llabcomm -OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader_writer.o labcomm_mem_reader.o labcomm_mem_writer.o +OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o labcomm_mem_reader.o labcomm_mem_writer.o LABCOMMC_PATH=../../compiler LABCOMMC_JAR=$(LABCOMMC_PATH)/labComm.jar -TESTS=test_labcomm_private test_labcomm test_labcomm_errors +TESTS=test_labcomm_basic_type_encoding test_labcomm test_labcomm_errors TEST_DIR=test TESTDATA_DIR=$(TEST_DIR)/testdata TEST_GEN_DIR=$(TESTDATA_DIR)/gen @@ -42,9 +42,9 @@ 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 -$(TEST_DIR)/labcomm_mem_reader.o: labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h +#$(TEST_DIR)/labcomm_mem_reader.o: labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h -$(TEST_DIR)/labcomm_mem_writer.o: labcomm_mem_writer.c labcomm_mem_writer.h cppmacros.h +#$(TEST_DIR)/labcomm_mem_writer.o: labcomm_mem_writer.c labcomm_mem_writer.h cppmacros.h ethaddr.o: ethaddr.c diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c index 5256de8fc4b0012fc4c7e05f4d8fba6fb9843eb4..bdcd204edf7e189ecea889664ce80ef66e1c1d9a 100644 --- a/lib/c/labcomm.c +++ b/lib/c/labcomm.c @@ -7,11 +7,15 @@ #include <errno.h> #include <string.h> +#include <stdarg.h> + #include "labcomm.h" #include "labcomm_private.h" #include "labcomm_ioctl.h" #include "labcomm_dynamic_buffer_writer.h" +#define LABCOMM_VERSION "LabComm2013" + typedef struct labcomm_sample_entry { struct labcomm_sample_entry *next; int index; @@ -146,6 +150,8 @@ static labcomm_sample_entry_t *get_sample_by_index( return p; } +#ifdef LABCOMM_ENCODER_LINEAR_SEARCH + static int get_encoder_index( labcomm_encoder_t *e, labcomm_signature_t *s) @@ -163,6 +169,25 @@ static int get_encoder_index( return result; } +#else + +static int get_encoder_index( + labcomm_encoder_t *e, + labcomm_signature_t *s) +{ + int result = 0; + extern labcomm_signature_t labcomm_first_signature; + extern labcomm_signature_t labcomm_last_signature; + + if (&labcomm_first_signature <= s && s <= &labcomm_last_signature) { + //fprintf(stderr, "%d\n", (int)(s - &labcomm_start)); + result = s - &labcomm_first_signature + LABCOMM_USER; + } + return result; +} + +#endif + void labcomm_encoder_start(struct labcomm_encoder *e, labcomm_signature_t *s) { @@ -301,12 +326,6 @@ void labcomm_internal_encode( } } -void labcomm_internal_encoder_user_action(labcomm_encoder_t *e, - int action) -{ - e->writer.write(&e->writer, action); -} - void labcomm_encoder_free(labcomm_encoder_t* e) { e->writer.write(&e->writer, labcomm_writer_free); @@ -501,7 +520,7 @@ static int do_decode_one(labcomm_decoder_t *d) } labcomm_decoder_t *labcomm_decoder_new( - int (*reader)(labcomm_reader_t *, labcomm_reader_action_t), + int (*reader)(labcomm_reader_t *, labcomm_reader_action_t, ...), void *reader_context) { labcomm_decoder_t *result = malloc(sizeof(labcomm_decoder_t)); @@ -522,7 +541,7 @@ labcomm_decoder_t *labcomm_decoder_new( result->do_decode_one = do_decode_one; result->on_error = on_error_fprintf; result->on_new_datatype = on_new_datatype; - result->reader.read(&result->reader, labcomm_reader_alloc); + result->reader.read(&result->reader, labcomm_reader_alloc, LABCOMM_VERSION); } return result; } diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h index baedb8d0d9b3c56be9bf24c3405876943823dae2..48d4cbe05b42c0981176acfc991b9252b65b6846 100644 --- a/lib/c/labcomm.h +++ b/lib/c/labcomm.h @@ -1,20 +1,8 @@ #ifndef _LABCOMM_H_ #define _LABCOMM_H_ -#ifdef ARM_CORTEXM3_CODESOURCERY - #include <machine/endian.h> -#else - #include <endian.h> -#endif - -// Some projects can not use stdio.h. -#ifndef LABCOMM_NO_STDIO - #include <stdio.h> -#endif - -#include <stdlib.h> -#include <string.h> #include <stdarg.h> +#include <unistd.h> /* Forward declaration */ struct labcomm_encoder; @@ -94,7 +82,8 @@ void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d, */ typedef enum { - labcomm_reader_alloc, + labcomm_reader_alloc, /* (..., char *labcomm_version) + Allocate all neccessary data */ labcomm_reader_free, labcomm_reader_start, labcomm_reader_continue, @@ -108,13 +97,13 @@ typedef struct labcomm_reader { int data_size; int count; int pos; - int (*read)(struct labcomm_reader *, labcomm_reader_action_t); + int (*read)(struct labcomm_reader *, labcomm_reader_action_t, ...); int (*ioctl)(struct labcomm_reader *, int, va_list); labcomm_error_handler_callback on_error; } labcomm_reader_t; struct labcomm_decoder *labcomm_decoder_new( - int (*reader)(labcomm_reader_t *, labcomm_reader_action_t), + int (*reader)(labcomm_reader_t *, labcomm_reader_action_t, ...), void *reader_context); int labcomm_decoder_decode_one( struct labcomm_decoder *decoder); @@ -128,7 +117,8 @@ void labcomm_decoder_free( */ typedef enum { - labcomm_writer_alloc, /* Allocate all neccessary data */ + labcomm_writer_alloc, /* (..., char *labcomm_version) + Allocate all neccessary data */ labcomm_writer_free, /* Free all allocated data */ labcomm_writer_start, /* Start writing an ordinary sample */ labcomm_writer_continue, /* Buffer full during ordinary sample */ diff --git a/lib/c/labcomm.linkscript b/lib/c/labcomm.linkscript new file mode 100644 index 0000000000000000000000000000000000000000..27cf28f393d74530420884701d54ec3971cf4a7a --- /dev/null +++ b/lib/c/labcomm.linkscript @@ -0,0 +1,8 @@ +SECTIONS { + labcomm : { + labcomm_first_signature = ABSOLUTE(.) ; + *(labcomm) + labcomm_last_signature = ABSOLUTE(.) ; + } +} +INSERT AFTER .data; diff --git a/lib/c/labcomm_dynamic_buffer_writer.c b/lib/c/labcomm_dynamic_buffer_writer.c index 5e180ec820203d3d28cb82d54614d938170281de..4c2017119fa385b2167fe4bc497d03ac8c550968 100644 --- a/lib/c/labcomm_dynamic_buffer_writer.c +++ b/lib/c/labcomm_dynamic_buffer_writer.c @@ -1,4 +1,6 @@ #include <errno.h> +#include <stdlib.h> +#include <stdarg.h> #include "labcomm_ioctl.h" #include "labcomm_dynamic_buffer_writer.h" diff --git a/lib/c/labcomm_fd_reader_writer.c b/lib/c/labcomm_fd_reader.c similarity index 52% rename from lib/c/labcomm_fd_reader_writer.c rename to lib/c/labcomm_fd_reader.c index 3ddafc4e08ca3ac9ff63ddca429578850003ed28..62cb6b469265b3670976a3a801681c7a9fc5611a 100644 --- a/lib/c/labcomm_fd_reader_writer.c +++ b/lib/c/labcomm_fd_reader.c @@ -1,18 +1,29 @@ #include <errno.h> #include <unistd.h> -#include "labcomm_fd_reader_writer.h" +#include <stdlib.h> +#include <string.h> +#include "labcomm_fd_reader.h" #define BUFFER_SIZE 2048 int labcomm_fd_reader( labcomm_reader_t *r, - labcomm_reader_action_t action) + labcomm_reader_action_t action, + ...) { int result = -EINVAL; int *fd = r->context; switch (action) { case labcomm_reader_alloc: { + va_list ap; + va_start(ap, action); + char *version = va_arg(ap, char *); + char *tmp = strdup(version); + + read(*fd, tmp, strlen(version)); + free(tmp); + r->data = malloc(BUFFER_SIZE); if (r->data) { r->data_size = BUFFER_SIZE; @@ -23,6 +34,7 @@ int labcomm_fd_reader( } r->count = 0; r->pos = 0; + va_end(ap); } break; case labcomm_reader_start: case labcomm_reader_continue: { @@ -60,48 +72,3 @@ int labcomm_fd_reader( return result; } -int labcomm_fd_writer( - labcomm_writer_t *w, - labcomm_writer_action_t action, ...) -{ - int result = 0; - int *fd = w->context; - - switch (action) { - case labcomm_writer_alloc: { - w->data = malloc(BUFFER_SIZE); - if (! w->data) { - result = -ENOMEM; - w->data_size = 0; - w->count = 0; - w->pos = 0; - } else { - w->data_size = BUFFER_SIZE; - w->count = BUFFER_SIZE; - w->pos = 0; - } - } break; - case labcomm_writer_free: { - free(w->data); - w->data = 0; - w->data_size = 0; - w->count = 0; - w->pos = 0; - } break; - case labcomm_writer_start: - case labcomm_writer_start_signature: { - w->pos = 0; - } break; - case labcomm_writer_continue: - case labcomm_writer_continue_signature: { - result = write(*fd, w->data, w->pos); - w->pos = 0; - } break; - case labcomm_writer_end: - case labcomm_writer_end_signature: { - result = write(*fd, w->data, w->pos); - w->pos = 0; - } break; - } - return result; -} diff --git a/lib/c/labcomm_fd_reader.h b/lib/c/labcomm_fd_reader.h new file mode 100644 index 0000000000000000000000000000000000000000..c06cb3ada399b8a31cf5e9bd9ae914adf3a46f05 --- /dev/null +++ b/lib/c/labcomm_fd_reader.h @@ -0,0 +1,12 @@ +#ifndef _LABCOMM_FD_READER_H_ +#define _LABCOMM_FD_READER_H_ + +#include "labcomm.h" + +extern int labcomm_fd_reader( + labcomm_reader_t *reader, + labcomm_reader_action_t action, + ...); + +#endif + diff --git a/lib/c/labcomm_fd_reader_writer.h b/lib/c/labcomm_fd_reader_writer.h deleted file mode 100644 index e5125d549d4623d1d98fabfe832cd4510e8ff574..0000000000000000000000000000000000000000 --- a/lib/c/labcomm_fd_reader_writer.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _LABCOMM_FD_READER_WRITER_H_ -#define _LABCOMM_FD_READER_WRITER_H_ - -#include "labcomm.h" - -extern int labcomm_fd_reader( - labcomm_reader_t *reader, - labcomm_reader_action_t action); - -extern int labcomm_fd_writer( - labcomm_writer_t *writer, - labcomm_writer_action_t action, - ...); - -#endif - diff --git a/lib/c/labcomm_fd_writer.c b/lib/c/labcomm_fd_writer.c new file mode 100644 index 0000000000000000000000000000000000000000..196e18f3d6a47d8264f9ebfb47118255e7aaca41 --- /dev/null +++ b/lib/c/labcomm_fd_writer.c @@ -0,0 +1,61 @@ +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> +#include "labcomm_fd_writer.h" + +#define BUFFER_SIZE 2048 + +int labcomm_fd_writer( + labcomm_writer_t *w, + labcomm_writer_action_t action, + ...) +{ + int result = 0; + int *fd = w->context; + + switch (action) { + case labcomm_writer_alloc: { + va_list ap; + va_start(ap, action); + char *version = va_arg(ap, char *); + + write(*fd, version, strlen(version)); + w->data = malloc(BUFFER_SIZE); + if (! w->data) { + result = -ENOMEM; + w->data_size = 0; + w->count = 0; + w->pos = 0; + } else { + w->data_size = BUFFER_SIZE; + w->count = BUFFER_SIZE; + w->pos = 0; + } + va_end(ap); + } break; + case labcomm_writer_free: { + free(w->data); + w->data = 0; + w->data_size = 0; + w->count = 0; + w->pos = 0; + } break; + case labcomm_writer_start: + case labcomm_writer_start_signature: { + w->pos = 0; + } break; + case labcomm_writer_continue: + case labcomm_writer_continue_signature: { + result = write(*fd, w->data, w->pos); + w->pos = 0; + } break; + case labcomm_writer_end: + case labcomm_writer_end_signature: { + result = write(*fd, w->data, w->pos); + w->pos = 0; + } break; + } + return result; +} diff --git a/lib/c/labcomm_fd_writer.h b/lib/c/labcomm_fd_writer.h new file mode 100644 index 0000000000000000000000000000000000000000..ea89eb29fe38b0147bbff077c627de72e8bef8bb --- /dev/null +++ b/lib/c/labcomm_fd_writer.h @@ -0,0 +1,12 @@ +#ifndef _LABCOMM_FD_WRITER_H_ +#define _LABCOMM_FD_WRITER_H_ + +#include "labcomm.h" + +extern int labcomm_fd_writer( + labcomm_writer_t *writer, + labcomm_writer_action_t action, + ...); + +#endif + diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h index 2d6777871ed1d377768e837c3418c1100690d685..4271200ed144b5dc0e1841d797cb6685135d54f5 100644 --- a/lib/c/labcomm_private.h +++ b/lib/c/labcomm_private.h @@ -38,6 +38,12 @@ */ #define LABCOMM_USER 0x40 +/* + * + */ +#define LABCOMM_DECLARE_SIGNATURE(name) \ + labcomm_signature_t name __attribute__((section("labcomm"))) + /* * Semi private decoder declarations */ @@ -194,34 +200,6 @@ static inline char *labcomm_decode_string(labcomm_decoder_t *d) return labcomm_read_string(&d->reader); } -static inline int labcomm_buffer_read(struct labcomm_reader *r, - labcomm_reader_action_t action) -{ - // If this gets called, it is an error, - // so note error and let producer proceed - r->context = r; - r->pos = 0; - return 0; -} - -static inline int labcomm_buffer_reader_error(struct labcomm_reader *r) -{ - return r->context != NULL; -} - -static inline void labcomm_buffer_reader_setup( - labcomm_reader_t *r, - void *data, - int length) -{ - r->context = NULL; // Used as error flag - r->data = data; - r->data_size = length; - r->count = length; - r->pos = 0; - r->read = labcomm_buffer_read; -} - /* * Semi private encoder declarations */ diff --git a/lib/c/test/labcomm_mem_reader.c b/lib/c/test/labcomm_mem_reader.c index 0c4e3f1d9c12879ef989c09364bca28133249674..e111433731e746b12df536b98c01eb9a9336fedd 100644 --- a/lib/c/test/labcomm_mem_reader.c +++ b/lib/c/test/labcomm_mem_reader.c @@ -1,6 +1,8 @@ #include "labcomm_mem_reader.h" #include <errno.h> +#include <stdlib.h> +#include <string.h> /* This implementation assumes labcomm will call end exactly once after each start * It is not allowed to save data in mcontext->enc_data, @@ -13,7 +15,9 @@ */ // TODO make labcomm use result! -int labcomm_mem_reader(labcomm_reader_t *r, labcomm_reader_action_t action) +int labcomm_mem_reader(labcomm_reader_t *r, + labcomm_reader_action_t action, + ...) { int result = -EINVAL; labcomm_mem_reader_context_t *mcontext = (labcomm_mem_reader_context_t *) r->context; diff --git a/lib/c/test/labcomm_mem_reader.h b/lib/c/test/labcomm_mem_reader.h index 5cac018ff362c1c9ecfc7984c410b71d01e0016b..55b8ea9784a6eaabffb5801d3a8dd7d2f07254c4 100644 --- a/lib/c/test/labcomm_mem_reader.h +++ b/lib/c/test/labcomm_mem_reader.h @@ -12,6 +12,8 @@ struct labcomm_mem_reader_context_t { unsigned char *enc_data; }; -int labcomm_mem_reader( labcomm_reader_t *r, labcomm_reader_action_t action); +int labcomm_mem_reader(labcomm_reader_t *r, + labcomm_reader_action_t action, + ...); #endif diff --git a/lib/c/test/labcomm_mem_writer.c b/lib/c/test/labcomm_mem_writer.c index 294a471ef380b46aa95d87146c1f725b9b768bcb..4370361e97945f6aec61cbdb2c364bcb13a38fa7 100644 --- a/lib/c/test/labcomm_mem_writer.c +++ b/lib/c/test/labcomm_mem_writer.c @@ -2,6 +2,7 @@ #include <stddef.h> // For size_t. #include <stdarg.h> +#include <stdlib.h> #include <errno.h> #include "labcomm.h" diff --git a/lib/c/test/test_labcomm.c b/lib/c/test/test_labcomm.c index fc4004c109e5583ae2acfbbe00caa33f07f93036..1c5020f7e8f5ee9b622351097fd44e496f330887 100644 --- a/lib/c/test/test_labcomm.c +++ b/lib/c/test/test_labcomm.c @@ -2,6 +2,7 @@ #include "CUnit/Basic.h" #include "CUnit/Console.h" #include <stdbool.h> +#include <stdlib.h> #include <labcomm.h> #include <labcomm_mem_writer.h> diff --git a/lib/c/test/test_labcomm_private.c b/lib/c/test/test_labcomm_basic_type_encoding.c similarity index 97% rename from lib/c/test/test_labcomm_private.c rename to lib/c/test/test_labcomm_basic_type_encoding.c index 33e2a1aaf8e40e263e38f03b543584c9a041809f..c8dfff71d24341d19a4c500a659a1aaff6deec7b 100644 --- a/lib/c/test/test_labcomm_private.c +++ b/lib/c/test/test_labcomm_basic_type_encoding.c @@ -9,7 +9,7 @@ int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...) exit(1); } -int test_read(struct labcomm_reader *r, labcomm_reader_action_t a) +int test_read(struct labcomm_reader *r, labcomm_reader_action_t a, ...) { fprintf(stderr, "test_read should not be called\n"); exit(1); @@ -40,7 +40,7 @@ static labcomm_decoder_t decoder = { .context = NULL, .data = buffer, .data_size = sizeof(buffer), - .count = sizeof(buffer), + .count = 0, .pos = 0, .read = test_read, .ioctl = NULL, @@ -60,7 +60,8 @@ typedef unsigned char byte; encoder.writer.pos = 0; \ labcomm_encode_##type(&encoder, value); \ writer_assert(#type, __LINE__, expect_count, (uint8_t*)expect_bytes); \ - decoder.reader.pos = 0; \ + decoder.reader.count = encoder.writer.pos; \ + decoder.reader.pos = 0; \ decoded = labcomm_decode_##type(&decoder); \ if (decoded != value) { \ fprintf(stderr, "Decode error" format " != " format " @%s:%d \n", value, decoded, \