From 2f426104c6b7cf0a7bf8a8e401a71525b0a6752b Mon Sep 17 00:00:00 2001 From: Sven Gestegard Robertz <sven.robertz@cs.lth.se> Date: Sat, 31 Jan 2015 14:33:34 +0100 Subject: [PATCH] handling of typedefs implemented in C --- examples/user_types/example_decoder.c | 5 ++ lib/c/2014/labcomm_decoder.c | 88 ++++++++++++++++++++++++++- lib/c/2014/labcomm_type_signature.h | 70 ++++++--------------- 3 files changed, 110 insertions(+), 53 deletions(-) diff --git a/examples/user_types/example_decoder.c b/examples/user_types/example_decoder.c index 830a4c5..56a7fb4 100644 --- a/examples/user_types/example_decoder.c +++ b/examples/user_types/example_decoder.c @@ -20,6 +20,10 @@ static void handle_test_theSecondInt(int *v,void *context) { printf("Got theSecondInt. (%d) \n", *v); } +static void handle_typedef(struct labcomm_raw_typedef *v,void *context) { + printf("Got typedef. (%d) %s\n", v->index, v->name); +} + static void handle_test_twoLines(test_twoLines *v,void *context) { printf("Got twoLines. (%d,%d) -> (%d,%d), (%d,%d) -> (%d,%d)\n", v->l1.start.x.val, v->l1.start.y.val, v->l1.end.x.val, v->l1.end.y.val, @@ -49,6 +53,7 @@ int main(int argc, char *argv[]) { labcomm_decoder_register_test_theFirstInt(decoder, handle_test_theFirstInt, context); labcomm_decoder_register_test_theSecondInt(decoder, handle_test_theSecondInt, context); labcomm_decoder_register_test_twoLines(decoder, handle_test_twoLines, context); + labcomm_decoder_register_labcomm_typedef(decoder, handle_typedef, context); printf("Decoding:\n"); labcomm_decoder_run(decoder); diff --git a/lib/c/2014/labcomm_decoder.c b/lib/c/2014/labcomm_decoder.c index 2c3e567..8c240c9 100644 --- a/lib/c/2014/labcomm_decoder.c +++ b/lib/c/2014/labcomm_decoder.c @@ -443,7 +443,11 @@ int labcomm_decoder_decode_one(struct labcomm_decoder *d) } else if (remote_index == LABCOMM_SAMPLE_REF) { result = decode_sample_def_or_ref(d, LABCOMM_SAMPLE_REF); } else if (remote_index == LABCOMM_TYPE_DEF) { - result = decode_type_def(d, LABCOMM_TYPE_DEF); + result = decode_and_handle(d, d, remote_index); + if(result == -ENOENT) { + printf("*** no handler for typedef..."); + result = decode_type_def(d, LABCOMM_TYPE_DEF); + } } else if (remote_index == LABCOMM_TYPE_BINDING) { result = decode_type_binding(d, LABCOMM_TYPE_BINDING); } else if (remote_index == LABCOMM_PRAGMA) { @@ -525,6 +529,88 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *d, return result; } +#ifndef LABCOMM_NO_TYPEDECL +//// Code for allowing user code to handle typedefs +//// (should perhaps be moved to another file) + +static void decode_raw_typedef( + struct labcomm_reader *r, + void (*handle)( + struct labcomm_raw_typedef *v, + void *context + ), + void *context +) +{ + struct labcomm_raw_typedef v; + v.index = labcomm_read_packed32(r); + if (r->error < 0) { + goto out; + } + v.name = labcomm_read_string(r); + if (r->error < 0) { + goto free_name; + } + v.length = labcomm_read_packed32(r); + if (r->error < 0) { + goto free_name; + } + int i; + v.signature_data = labcomm_memory_alloc(r->memory, 1, v.length); + if(v.signature_data) { + for(i=0; i<v.length; i++) { + v.signature_data[i] = labcomm_read_byte(r); + if (r->error < 0) { + goto free_sig; + } + } + handle(&v, context); + } +free_sig: + labcomm_memory_free(r->memory, 1, v.signature_data); +free_name: + labcomm_memory_free(r->memory, 1, v.name); +out: + return; +} + +int labcomm_decoder_register_labcomm_typedef( + struct labcomm_decoder *d, + void (*handler)( + struct labcomm_raw_typedef *v, + void *context + ), + void *context +) +{ + int tag = LABCOMM_TYPE_DEF; + struct sample_entry *entry; + int *remote_to_local; + + labcomm_scheduler_data_lock(d->scheduler); + entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, + d->local, struct sample_entry, + tag); + if (entry == NULL) { tag = -ENOMEM; goto unlock; } + entry->remote_index = LABCOMM_TYPE_DEF; + entry->signature = NULL; + entry->decode = (labcomm_decoder_function) decode_raw_typedef; + entry->handler =(labcomm_handler_function) handler; + entry->context = context; + + remote_to_local = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, + d->remote_to_local, int, + tag); + *remote_to_local = tag; +unlock: + labcomm_scheduler_data_unlock(d->scheduler); + + return tag; +} + +//// End typedef handling +#endif + int labcomm_internal_decoder_register( struct labcomm_decoder *d, const struct labcomm_signature *signature, diff --git a/lib/c/2014/labcomm_type_signature.h b/lib/c/2014/labcomm_type_signature.h index 44549aa..3f2ecfe 100644 --- a/lib/c/2014/labcomm_type_signature.h +++ b/lib/c/2014/labcomm_type_signature.h @@ -61,67 +61,33 @@ struct labcomm_signature { #endif }; -#if 0 -/* - * Signature entry +/* a struct for "raw" typedefs, to be used as an intermediate representation + * between decoder and signature parser */ -#ifdef USE_UNIONS - -/* Useful for C99 and up (or GCC without -pedantic) */ - -#define LABCOMM_SIGDEF_BYTES_OR_SIGNATURE \ - union { \ - char *bytes; \ - struct labcomm_signature* signature; \ - } u; - -#define LABCOMM_SIGDEF_BYTES(l, b) { l, .u.bytes=b } -#define LABCOMM_SIGDEF_SIGNATURE(s) { 0, .u.signature=&s } // addressof, as s is pointing at the sig struct, not directly the the sig_bytes[] -#define LABCOMM_SIGDEF_END { -1, .u.bytes=0 } - -#else - -#define LABCOMM_SIGDEF_BYTES_OR_SIGNATURE \ - struct { \ - char *bytes; \ - struct labcomm_signature *signature; \ - } u; - -#define LABCOMM_SIGDEF_BYTES(l, b) { l, { b, 0 } } -#define LABCOMM_SIGDEF_SIGNATURE(s) { 0, { 0, &s } } -#define LABCOMM_SIGDEF_END { -1, { 0, 0 } } - -#endif - -struct labcomm_signature_data { - int length; - LABCOMM_SIGDEF_BYTES_OR_SIGNATURE +struct labcomm_raw_typedef { + char *name; + int index; + int length; + char *signature_data; }; -struct labcomm_signature { - int type; - char *name; - int (*encoded_size)(struct labcomm_signature *, void *); // void * == encoded_sample * - struct { - int size; - unsigned char *data; - } flat; - struct { - int size; - struct labcomm_signature_data *data; - } tree; - int index; -#ifdef LABCOMM_EXPERIMENTAL_CACHED_ENCODED_SIZE - int cached_encoded_size; // -1 if not initialized or type is variable size -#endif -}; -#endif /* * functions */ +/* register a handler for typedefs + */ + +int labcomm_decoder_register_labcomm_typedef( + struct labcomm_decoder *d, + void (*handler)( + struct labcomm_raw_typedef *v, + void *context + ), + void *context +); /* Dump signature bytes on stdout */ -- GitLab