Commit 2f426104 authored by Sven Gestegård Robertz's avatar Sven Gestegård Robertz
Browse files

handling of typedefs implemented in C

parent 266c6d58
......@@ -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);
......
......@@ -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,
......
......@@ -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
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment