diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag index beb7309c5dd953434700be0d21d63b8a47922778..428657fd47b809f2db7762ddbc30ac708a25bdb5 100644 --- a/compiler/C_CodeGen.jrag +++ b/compiler/C_CodeGen.jrag @@ -673,8 +673,8 @@ aspect C_DecoderIoctl { env.println("va_start(va, ioctl_action);"); env.println("result = labcomm_internal_decoder_ioctl("); env.indent(); - env.println("d, ioctl_action,"); - env.println("&labcomm_signature_" + env.prefix + getName() + ", va);"); + env.println("d, &labcomm_signature_" + env.prefix + getName() + ", "); + env.println("ioctl_action, va);"); env.unindent(); env.println("va_end(va);"); env.println("return result;"); @@ -851,8 +851,8 @@ aspect C_EncoderIoctl { env.println("va_start(va, ioctl_action);"); env.println("result = labcomm_internal_encoder_ioctl("); env.indent(); - env.println("e, ioctl_action,"); - env.println("&labcomm_signature_" + env.prefix + getName() + ", va);"); + env.println("e, &labcomm_signature_" + env.prefix + getName() + ", "); + env.println("ioctl_action, va);"); env.unindent(); env.println("va_end(va);"); env.println("return result;"); diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c index 978640f4eb53d600f335bf619212139dcb6c39e8..9f4f172032b2073e8cb6977c43e8a707922d1220 100644 --- a/lib/c/labcomm.c +++ b/lib/c/labcomm.c @@ -457,7 +457,7 @@ int labcomm_encoder_ioctl(struct labcomm_encoder *encoder, va_start(va, action); result = encoder->writer->action->ioctl(encoder->writer, encoder->writer->context, - action, NULL, va); + 0, NULL, action, va); va_end(va); out: @@ -481,23 +481,23 @@ static int labcomm_writer_ioctl(struct labcomm_writer *writer, } va_start(va, action); - result = writer->action->ioctl(writer, writer->context, action, NULL, va); + result = writer->action->ioctl(writer, writer->context, + 0, NULL, action, va); va_end(va); out: return result; } int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, - int action, struct labcomm_signature *signature, - va_list va) + int action, va_list va) { int result = -ENOTSUP; if (encoder->writer->action->ioctl != NULL) { result = encoder->writer->action->ioctl(encoder->writer, encoder->writer->context, - action, signature, va); + -1, signature, action, va); } return result; } @@ -572,8 +572,6 @@ struct labcomm_decoder *labcomm_decoder_new( result->lock = lock; result->on_error = on_error_fprintf; result->on_new_datatype = on_new_datatype; - result->reader->action->alloc(result->reader, result->reader->context, - result, LABCOMM_VERSION); } return result; } @@ -604,7 +602,14 @@ void labcomm_internal_decoder_register( int labcomm_decoder_decode_one(struct labcomm_decoder *d) { int result; - + + if (d->reader->data == NULL) { + result = d->reader->action->alloc(d->reader, d->reader->context, + d, LABCOMM_VERSION); + if (result <= 0) { + goto out; + } + } result = d->reader->action->start(d->reader, d->reader->context); if (result > 0) { struct labcomm_decoder_context *context = d->context; @@ -681,6 +686,7 @@ int labcomm_decoder_decode_one(struct labcomm_decoder *d) } } d->reader->action->end(d->reader, d->reader->context); +out: return result; } @@ -719,24 +725,56 @@ int labcomm_decoder_ioctl(struct labcomm_decoder *decoder, va_start(va, action); result = decoder->reader->action->ioctl(decoder->reader, decoder->reader->context, - action, NULL, va); + 0, NULL, action, va); va_end(va); } return result; } int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, - int action, struct labcomm_signature *signature, - va_list va) + int action, va_list va) { int result = -ENOTSUP; if (decoder->reader->action->ioctl != NULL) { result = decoder->reader->action->ioctl(decoder->reader, decoder->reader->context, - action, NULL, va); + -1, signature, action, va); } return result; } +void *labcomm_signature_array_ref(int *first, int *last, void **data, + int size, int index) +{ + if (*first == 0 && *last == 0) { + *first = index; + *last = index + 1; + *data = malloc(size); + if (*data) { + memset(*data, 0, size); + } + } else if (index < *first || *last <= index) { + void *old_data = *data; + int old_first = *first; + int old_last = *last; + int n; + *first = (index<old_first)?index:old_first; + *last = (old_last<=index)?index+1:old_last; + n = (*last - *first); + *data = malloc(n * size); + if (*data) { + memset(*data, 0, n * size); + memcpy(*data + (old_first - *first) * size, + old_data, + (old_last - old_first) * size); + } + free(old_data); + } + if (*data) { + return *data + (index - *first) * size; + } else { + return NULL; + } +} diff --git a/lib/c/labcomm_dynamic_buffer_writer.c b/lib/c/labcomm_dynamic_buffer_writer.c index 4a1f3ac16e573d8212b5fdaf978dc7224c92b035..c3ef5cd38bd717a60c8b6d24185241b9960d3f82 100644 --- a/lib/c/labcomm_dynamic_buffer_writer.c +++ b/lib/c/labcomm_dynamic_buffer_writer.c @@ -77,9 +77,9 @@ static int dyn_flush(struct labcomm_writer *w, void *context) } static int dyn_ioctl(struct labcomm_writer *w, void *context, - int action, + int signature_index, struct labcomm_signature *signature, - va_list arg) + int action, va_list arg) { int result = -ENOTSUP; switch (action) { diff --git a/lib/c/labcomm_fd_reader.c b/lib/c/labcomm_fd_reader.c index d67e6f6572a05fd8f3d04bf25593ef98e68794f3..3aa0d63f74811172d7c7b5c598c7f6b42f368903 100644 --- a/lib/c/labcomm_fd_reader.c +++ b/lib/c/labcomm_fd_reader.c @@ -102,13 +102,22 @@ static int fd_end(struct labcomm_reader *r, void *context) return 0; } +static int fd_ioctl(struct labcomm_reader *r, void *context, + int signature_index, + struct labcomm_signature *signature, + int action, va_list args) +{ + return -ENOTSUP; +} + + static const struct labcomm_reader_action action = { .alloc = fd_alloc, .free = fd_free, .start = fd_start, .fill = fd_fill, .end = fd_end, - .ioctl = NULL + .ioctl = fd_ioctl }; struct labcomm_reader *labcomm_fd_reader_new(int fd, int close_fd_on_free) diff --git a/lib/c/labcomm_fd_writer.c b/lib/c/labcomm_fd_writer.c index 6fadb80c831d60f176b4d7646daadfd6b2b14ff7..c2e1b126d46f90c2b0e7801f2447978755aac19f 100644 --- a/lib/c/labcomm_fd_writer.c +++ b/lib/c/labcomm_fd_writer.c @@ -90,13 +90,20 @@ static int fd_flush(struct labcomm_writer *w, void *context) return w->error; } +static int fd_ioctl(struct labcomm_writer *w, void *context, + int signature_index, struct labcomm_signature *signature, + int action, va_list args) +{ + return -ENOTSUP; +} + static const struct labcomm_writer_action action = { .alloc = fd_alloc, .free = fd_free, .start = fd_start, .end = fd_flush, .flush = fd_flush, - .ioctl = NULL + .ioctl = fd_ioctl }; struct labcomm_writer *labcomm_fd_writer_new(int fd, int close_fd_on_free) diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h index 695938dc95dcd389cc050a92bc42d68ea5d8f2a4..9922e1c191b2e12004d289af13f50b55bd81a980 100644 --- a/lib/c/labcomm_private.h +++ b/lib/c/labcomm_private.h @@ -78,7 +78,8 @@ struct labcomm_reader_action { int (*end)(struct labcomm_reader *r, void *context); int (*fill)(struct labcomm_reader *r, void *context); int (*ioctl)(struct labcomm_reader *r, void *context, - int action, struct labcomm_signature *signature, va_list args); + int signature_index, struct labcomm_signature *signature, + int ioctl_action, va_list args); }; struct labcomm_reader { @@ -105,9 +106,8 @@ void labcomm_internal_decoder_register( void *context); int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, - int ioctl_action, struct labcomm_signature *signature, - va_list args); + int ioctl_action, va_list args); #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -211,8 +211,8 @@ struct labcomm_writer_action { int (*end)(struct labcomm_writer *w, void *context); int (*flush)(struct labcomm_writer *w, void *context); int (*ioctl)(struct labcomm_writer *w, void *context, - int index, struct labcomm_signature *, - va_list); + int signature_index, struct labcomm_signature *signature, + int ioctl_action, va_list args); }; struct labcomm_writer { @@ -238,9 +238,8 @@ int labcomm_internal_encode( int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, - int ioctl_action, struct labcomm_signature *signature, - va_list args); + int ioctl_action, va_list args); #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -325,4 +324,36 @@ static inline int labcomm_write_string(struct labcomm_writer *w, char *s) return 0; } +/* + * Macros for handling arrays indexed by signature index + */ + +#define LABCOMM_SIGNATURE_ARRAY_DEF(name, kind) \ + struct { \ + int first; \ + int last; \ + kind *data; \ + } name + +#define LABCOMM_SIGNATURE_ARRAY_DEF_INIT(name, kind) \ + LABCOMM_SIGNATURE_ARRAY_DEF(name, kind) = { 0, 0, NULL } + +#define LABCOMM_SIGNATURE_ARRAY_INIT(name, kind) \ + name.first = 0; name.last = 0; name.data = NULL; \ + name.data = (kind *)name.data; /* typechecking no-op */ + +#define LABCOMM_SIGNATURE_ARRAY_FREE(name, kind) \ + if (name.data) { free(name.data); } \ + name.data = (kind *)NULL; /* typechecking */ + +#define LABCOMM_SIGNATURE_ARRAY_REF(name, kind, index) \ + (name.data = (kind *)name.data, /* typechecking no-op */ \ + (kind *)(labcomm_signature_array_ref(&name.first, &name.last, \ + (void **)&name.data, \ + sizeof(kind), index))) + +void *labcomm_signature_array_ref(int *first, int *last, void **data, + int size, int index); + + #endif diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c index 6cb0d340152718634a2549086af465f7fd91c49f..7de51eb04d2434475385eb025bb5b4646a49c518 100644 --- a/lib/c/test/test_labcomm_generated_encoding.c +++ b/lib/c/test/test_labcomm_generated_encoding.c @@ -53,9 +53,8 @@ static int buf_writer_flush(struct labcomm_writer *w, void *context) static int buf_writer_ioctl( struct labcomm_writer *w, void *context, - int action, - struct labcomm_signature *signature, - va_list arg) + int signature_index, struct labcomm_signature *signature, + int action, va_list arg) { int result = -ENOTSUP; switch (action) {