diff --git a/.bzrignore b/.bzrignore index 7c11f80132a34152f829ad561b9d32eb49dd872e..4604e2fe800c8bd5d2fb09a69714389895582bb0 100644 --- a/.bzrignore +++ b/.bzrignore @@ -38,3 +38,4 @@ lib/c/liblabcomm_plain_c.so.1 lib/c/test/test_signature_plain_c test/test_signature_numbers lib/c/test/test_signature_numbers +lib/c/test/test_labcomm diff --git a/lib/c/Makefile b/lib/c/Makefile index 5ca4d0cb955921274998b40678c09d89a5d7edcc..113e4acb0b4afafb516114456d6e85a881d4df3e 100644 --- a/lib/c/Makefile +++ b/lib/c/Makefile @@ -1,7 +1,6 @@ ## Macros CC=gcc -#CFLAGS=-g -Wall -Werror -O3 -I. -Itest -DLABCOMM_ENCODER_LINEAR_SEARCH CFLAGS=-g -Wall -Werror -O3 -I. -Itest LDFLAGS=-L. LDLIBS_TEST=-llabcomm -lrt @@ -23,18 +22,15 @@ LABCOMM_JAR=../../compiler/labComm.jar LABCOMM=java -jar $(LABCOMM_JAR) TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding \ + test_signature_numbers \ + test_labcomm \ test_labcomm_pthread_scheduler \ - test_signature_numbers # #FIXME: test_labcomm test_labcomm_errors TEST_DIR=test -TESTDATA_DIR=$(TEST_DIR)/testdata -TEST_GEN_DIR=$(TESTDATA_DIR)/gen VPATH=$(TEST_DIR) -CREATED_DIRS=$(TEST_DIR) $(TESTDATA_DIR) $(TEST_GEN_DIR) - # Enable experimental objects by invoking make like `make LABCOMM_EXPERIMENTAL=true` ifeq ($(LABCOMM_EXPERIMENTAL),true) OBJS += experimental/udp_hack.o experimental/ethaddr.o \ @@ -66,10 +62,6 @@ labcomm_fd_reader_writer.o : labcomm_fd_reader_writer.c labcomm_fd_reader_write ethaddr.o: ethaddr.c -$(CREATED_DIRS): - mkdir -p $@ - -## NB! the tests need CUnit to be installed run-test: $(TESTS:%=run-test-%) run-test-%: $(TEST_DIR)/% | $(TEST_DIR) @@ -85,6 +77,8 @@ $(TEST_DIR)/%: $(TEST_DIR)/%.o $(TEST_DIR)/gen: mkdir -p $@ +.PRECIOUS: $(TEST_DIR)/gen/%.c +.PRECIOUS: $(TEST_DIR)/gen/%.h $(TEST_DIR)/gen/%.c $(TEST_DIR)/gen/%.h: $(TEST_DIR)/%.lc | $(TEST_DIR)/gen $(LABCOMM) \ --c=$(TEST_DIR)/gen/$*.c \ @@ -127,7 +121,7 @@ $(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_labcomm: $(TEST_DIR)/gen/test_sample.o $(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 diff --git a/lib/c/labcomm_decoder.c b/lib/c/labcomm_decoder.c index 0641e405caf00d6b345bf9deec54cb183521d350..3bbc8e136f61f405bd7e5edeec84bd00cc257bcf 100644 --- a/lib/c/labcomm_decoder.c +++ b/lib/c/labcomm_decoder.c @@ -83,11 +83,15 @@ void labcomm_decoder_free(struct labcomm_decoder* d) labcomm_memory_free(memory, 0, d); } -static void collect_flat_signature( +static int collect_flat_signature( struct labcomm_decoder *decoder, struct labcomm_writer *writer) { - int type = labcomm_read_packed32(decoder->reader); + int result, type; + + type = labcomm_read_packed32(decoder->reader); + result = decoder->reader->error; + 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); @@ -103,7 +107,8 @@ static void collect_flat_signature( int n = labcomm_read_packed32(decoder->reader); labcomm_write_packed32(writer, n); } - collect_flat_signature(decoder, writer); + result = collect_flat_signature(decoder, writer); + if (result < 0) { goto out; } } break; case LABCOMM_STRUCT: { int fields, i; @@ -114,7 +119,8 @@ static void collect_flat_signature( char *name = labcomm_read_string(decoder->reader); labcomm_write_string(writer, name); labcomm_memory_free(decoder->memory, 1, name); - collect_flat_signature(decoder, writer); + result = collect_flat_signature(decoder, writer); + if (result < 0) { goto out; } } } break; case LABCOMM_BOOLEAN: @@ -127,11 +133,14 @@ static void collect_flat_signature( case LABCOMM_STRING: { } break; default: { + result = -ENOSYS; decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3, "Implement %s (2) for type 0x%x...\n", __FUNCTION__, type); } break; } } +out: + return result; } static int writer_ioctl(struct labcomm_writer *writer, @@ -181,7 +190,7 @@ static int decode_typedef_or_sample(struct labcomm_decoder *d, int kind) local_index = 0; labcomm_writer_alloc(&writer, writer.action_context, ""); labcomm_writer_start(&writer, writer.action_context, 0, NULL, NULL); - remote_index = labcomm_read_packed32(d->reader); //int + remote_index = labcomm_read_packed32(d->reader); signature.name = labcomm_read_string(d->reader); signature.type = kind; collect_flat_signature(d, &writer); diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h index 8e2f0595c23910cc60689022999dfb3aa989cc3d..455e88d3a6fe3796f15608c1ca671500c9e9f999 100644 --- a/lib/c/labcomm_private.h +++ b/lib/c/labcomm_private.h @@ -201,6 +201,9 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, for (i = sizeof(type) - 1 ; i >= 0 ; i--) { \ if (r->pos >= r->count) { \ labcomm_reader_fill(r, r->action_context); \ + if (r->error < 0) { \ + return 0; \ + } \ } \ ((unsigned char*)(&result))[i] = r->data[r->pos]; \ r->pos++; \ @@ -216,6 +219,9 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, for (i = 0 ; i < sizeof(type) ; i++) { \ if (r->pos >= r->count) { \ labcomm_reader_fille(r, r->action_context); \ + if (r->error < 0) { \ + return 0; \ + } \ } \ ((unsigned char*)(&result))[i] = r->data[r->pos]; \ r->pos++; \ @@ -259,19 +265,23 @@ out: static inline char *labcomm_read_string(struct labcomm_reader *r) { - char *result; - int length, i; + char *result = NULL; + int length, pos; length = labcomm_read_packed32(r); result = labcomm_memory_alloc(r->memory, 1, length + 1); - for (i = 0 ; i < length ; i++) { + for (pos = 0 ; pos < length ; pos++) { if (r->pos >= r->count) { labcomm_reader_fill(r, r->action_context); + if (r->error < 0) { + goto out; + } } - result[i] = r->data[r->pos]; + result[pos] = r->data[r->pos]; r->pos++; } - result[length] = 0; +out: + result[pos] = 0; return result; } diff --git a/lib/c/test/test_labcomm.c b/lib/c/test/test_labcomm.c index 1c5020f7e8f5ee9b622351097fd44e496f330887..3addcf2297484923f77266f9557cc8c72b66abd3 100644 --- a/lib/c/test/test_labcomm.c +++ b/lib/c/test/test_labcomm.c @@ -1,6 +1,173 @@ +/* + test_labcomm.c -- Various labcomm tests -#include "CUnit/Basic.h" -#include "CUnit/Console.h" + 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/>. +*/ + +#include <stdint.h> +#include <inttypes.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include "labcomm_private.h" +#include "labcomm_default_error_handler.h" +#include "labcomm_default_memory.h" +#include "labcomm_default_scheduler.h" +#include "test/gen/test_sample.h" + +static unsigned char buffer[512]; + +static int writer_alloc(struct labcomm_writer *w, + struct labcomm_writer_action_context *action_context, + char *labcomm_version) +{ + w->data = buffer; + w->data_size = sizeof(buffer); + w->count = sizeof(buffer); + + return 0; +} +static int writer_start(struct labcomm_writer *w, + struct labcomm_writer_action_context *action_context, + int index, struct labcomm_signature *signature, + void *value) +{ + return 0; +} +const struct labcomm_writer_action writer_action = { + .alloc = writer_alloc, + .start = writer_start, +}; +static struct labcomm_writer_action_context writer_action_context = { + .next = NULL, + .action = &writer_action, + .context = NULL +}; +static struct labcomm_writer writer = { + .action_context = &writer_action_context, + .data = buffer, + .data_size = sizeof(buffer), + .count = sizeof(buffer), + .pos = 0, + .error = 0, +}; + +static int reader_alloc(struct labcomm_reader *r, + struct labcomm_reader_action_context *action_context, + char *labcomm_version) +{ + r->data = buffer; + r->data_size = sizeof(buffer); + r->count = 0; + r->memory = labcomm_default_memory; + + return 0; +} +static int reader_fill(struct labcomm_reader *r, + struct labcomm_reader_action_context *action_context) +{ + r->error = -ENOMEM; + return r->error; +} +const struct labcomm_reader_action reader_action = { + .alloc = reader_alloc, + .fill = reader_fill, +}; +static struct labcomm_reader_action_context reader_action_context = { + .next = NULL, + .action = &reader_action, + .context = NULL +}; +static struct labcomm_reader reader = { + .action_context = &reader_action_context, + .data = buffer, + .data_size = sizeof(buffer), + .count = 0, + .pos = 0, + .error = 0, +}; + +test_sample_test_var encoder_var, decoder_var; + +void handle_test_var(test_sample_test_var *v, void *ctx) +{ + decoder_var = *v; +} + +int test_decode_one(struct labcomm_decoder *decoder) +{ + int result; + + for (reader.count = 0 ; reader.count < writer.pos ; reader.count++) { + reader.error = 0; + reader.pos = 0; + result = labcomm_decoder_decode_one(decoder); + if (result >= 0) { + fprintf(stderr, "Got result from buffer with bogus length (%d)\n", + result); + exit(1); + } + } + reader.error = 0; + reader.pos = 0; + reader.count = writer.pos; + result = labcomm_decoder_decode_one(decoder); + if (result < 0) { + fprintf(stderr, "Got result from buffer with correct length (%d)\n", + result); + exit(1); + } + return result; +} + +int main(void) +{ + int err; + struct labcomm_encoder *encoder = labcomm_encoder_new( + &writer, + labcomm_default_error_handler, + labcomm_default_memory, + labcomm_default_scheduler); + struct labcomm_decoder *decoder = labcomm_decoder_new( + &reader, + labcomm_default_error_handler, + labcomm_default_memory, + labcomm_default_scheduler); + labcomm_decoder_register_test_sample_test_var(decoder, + handle_test_var, + NULL); + labcomm_encoder_register_test_sample_test_var(encoder); + err = test_decode_one(decoder); + fprintf(stderr, "decode of register %d\n", err); + writer.pos = 0; + encoder_var = 314; + labcomm_encode_test_sample_test_var(encoder, &encoder_var); + err = test_decode_one(decoder); + fprintf(stderr, "decode of sample %d -> %d\n", err, decoder_var); + if (decoder_var != encoder_var) { + fprintf(stderr, "Failed to decode correct value %d != %d\n", + encoder_var, decoder_var); + exit(1); + } + return 0; +} + +#if 0 #include <stdbool.h> #include <stdlib.h> @@ -186,3 +353,4 @@ int main() return CU_get_error(); } +#endif diff --git a/lib/c/test/testdata/test_sample.lc b/lib/c/test/test_sample.lc similarity index 100% rename from lib/c/test/testdata/test_sample.lc rename to lib/c/test/test_sample.lc