diff --git a/lib/c/Makefile b/lib/c/Makefile
index 83f350fe5042a841322614cf58d9ff91e6f51959..1cc9aa02c04db821424f8a5cab51ff2b0ad46d2c 100644
--- a/lib/c/Makefile
+++ b/lib/c/Makefile
@@ -10,7 +10,8 @@ OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_w
 LABCOMM_JAR=../../compiler/labComm.jar
 LABCOMM=java -jar $(LABCOMM_JAR) 
 
-TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding test_labcomm 
+TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding 
+#test_labcomm 
 #FIXME: test_labcomm_errors
 TEST_DIR=test
 TESTDATA_DIR=$(TEST_DIR)/testdata
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
index 5c443d2b7fe597b884ca25fb2c31f4d83d534266..4ebc4f598c0c685a75503946dffea05b5b03c2fa 100644
--- a/lib/c/labcomm.c
+++ b/lib/c/labcomm.c
@@ -573,7 +573,7 @@ static int do_decode_one(labcomm_decoder_t *d)
   int result;
 
   do {
-    result = d->reader.read(&d->reader, labcomm_reader_start);
+    result = d->reader.action.start(&d->reader);
     if (result > 0) {
       labcomm_decoder_context_t *context = d->context;
 
@@ -642,7 +642,7 @@ static int do_decode_one(labcomm_decoder_t *d)
 	}
       }
     }
-    d->reader.read(&d->reader, labcomm_reader_end);
+    d->reader.action.end(&d->reader);
     /* TODO: should we really loop, or is it OK to
        return after a typedef/sample */
   } while (result > 0 && result < LABCOMM_USER);
@@ -650,7 +650,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, ...),
+  const struct labcomm_reader_action action,
   void *reader_context)
 {
   labcomm_decoder_t *result = malloc(sizeof(labcomm_decoder_t));
@@ -664,14 +664,13 @@ labcomm_decoder_t *labcomm_decoder_new(
     result->reader.data_size = 0;
     result->reader.count = 0;
     result->reader.pos = 0;
-    result->reader.read = reader;
-    result->reader.ioctl = NULL;
+    result->reader.action = action;
     result->reader.on_error = on_error_fprintf;
     result->do_register = do_decoder_register;
     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, LABCOMM_VERSION);
+    result->reader.action.alloc(&result->reader, LABCOMM_VERSION);
   }
   return result;
 }
@@ -714,7 +713,7 @@ void labcomm_decoder_run(labcomm_decoder_t *d)
 
 void labcomm_decoder_free(labcomm_decoder_t* d)
 {
-  d->reader.read(&d->reader, labcomm_reader_free);
+  d->reader.action.free(&d->reader);
   labcomm_decoder_context_t *context = (labcomm_decoder_context_t *) d->context;
   labcomm_sample_entry_t *entry = context->sample;
   labcomm_sample_entry_t *entry_next;
@@ -735,11 +734,11 @@ int labcomm_decoder_ioctl(struct labcomm_decoder *decoder,
 {
   int result = -ENOTSUP;
   
-  if (decoder->reader.ioctl != NULL) {
+  if (decoder->reader.action.ioctl != NULL) {
     va_list va;
     
     va_start(va, action);
-    result = decoder->reader.ioctl(&decoder->reader, action, NULL, va);
+    result = decoder->reader.action.ioctl(&decoder->reader, action, NULL, va);
     va_end(va);
   }
   return result;
@@ -752,8 +751,8 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder,
 {
   int result = -ENOTSUP;
   
-  if (decoder->reader.ioctl != NULL) {
-    result = decoder->reader.ioctl(&decoder->reader, action, NULL, va);
+  if (decoder->reader.action.ioctl != NULL) {
+    result = decoder->reader.action.ioctl(&decoder->reader, action, NULL, va);
   }
   return result;
 }
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
index 8bc80cf56d591ac93fd6c60507ea951a0297148b..7d38828393389459bffa60cc49874cf9063d5a61 100644
--- a/lib/c/labcomm.h
+++ b/lib/c/labcomm.h
@@ -91,19 +91,29 @@ typedef enum {
   labcomm_reader_ioctl
 } labcomm_reader_action_t;
 
+struct labcomm_reader;
+
+struct labcomm_reader_action {
+  int (*alloc)(struct labcomm_reader *, char *labcomm_version);
+  int (*free)(struct labcomm_reader *);
+  int (*start)(struct labcomm_reader *);
+  int (*fill)(struct labcomm_reader *); 
+  int (*end)(struct labcomm_reader *);
+  int (*ioctl)(struct labcomm_reader *, int, labcomm_signature_t *, va_list);
+};
+
 typedef struct labcomm_reader {
   void *context;
   unsigned char *data;
   int data_size;
   int count;
   int pos;
-  int (*read)(struct labcomm_reader *, labcomm_reader_action_t, ...);
-  int (*ioctl)(struct labcomm_reader *, int, labcomm_signature_t *, va_list);
+  struct labcomm_reader_action action;
   labcomm_error_handler_callback on_error;
 }  labcomm_reader_t;
 
 struct labcomm_decoder *labcomm_decoder_new(
-  int (*reader)(labcomm_reader_t *, labcomm_reader_action_t, ...),
+  const struct labcomm_reader_action action,
   void *reader_context);
 int labcomm_decoder_decode_one(
   struct labcomm_decoder *decoder);
diff --git a/lib/c/labcomm_fd_reader.c b/lib/c/labcomm_fd_reader.c
index 6940e1ce993c6957e9615cc1b0c3f245ef999d66..09bfc3c359a187898afd7269c9179aa2fa002922 100644
--- a/lib/c/labcomm_fd_reader.c
+++ b/lib/c/labcomm_fd_reader.c
@@ -6,72 +6,79 @@
 
 #define BUFFER_SIZE 2048
 
-int labcomm_fd_reader(
-  labcomm_reader_t *r, 
-  labcomm_reader_action_t action,
-  ...)
+static int fd_alloc(struct labcomm_reader *r, char *version)
 {
-  int result = -EINVAL;
+  int result;
+#ifndef LABCOMM_FD_OMIT_VERSION
   int *fd = r->context;
+  char *tmp = strdup(version);
   
-  switch (action) {
-    case labcomm_reader_alloc: {
-#ifndef LABCOMM_FD_OMIT_VERSION
-      va_list ap;
-      va_start(ap, action);
-      char *version = va_arg(ap, char *);
-      char *tmp = strdup(version);
-
-      read(*fd, tmp, strlen(version));
-      free(tmp);
-#endif
-      r->data = malloc(BUFFER_SIZE);
-      if (r->data) {
-        r->data_size = BUFFER_SIZE;
-        result = r->data_size;
-      } else {
-        r->data_size = 0;
-        result = -ENOMEM;
-      }
-      r->count = 0;
-      r->pos = 0;
-#ifndef LABCOMM_FD_OMIT_VERSION
-	va_end(ap);
+  read(*fd, tmp, strlen(version));
+  free(tmp);
 #endif
-    } break;
-    case labcomm_reader_start: 
-    case labcomm_reader_continue: {
-      if (r->pos < r->count) {
-        result = r->count - r->pos;
-      } else {
-        int err;
+  r->data = malloc(BUFFER_SIZE);
+  if (r->data) {
+    r->data_size = BUFFER_SIZE;
+    result = r->data_size;
+  } else {
+    r->data_size = 0;
+    result = -ENOMEM;
+  }
+  r->count = 0;
+  r->pos = 0;
+
+  return result;
+}
+
+static int fd_free(struct labcomm_reader *r)
+{
+  free(r->data);
+  r->data = 0;
+  r->data_size = 0;
+  r->count = 0;
+  r->pos = 0;
 
-        r->pos = 0;
-        err = read(*fd, r->data, r->data_size);
-        if (err <= 0) {
-          r->count = 0;
-          result = -1;
-        } else {
-          r->count = err;
-          result = r->count - r->pos;
-        }
-      }
-    } break;
-    case labcomm_reader_end: {
-      result = 0;
-    } break;
-    case labcomm_reader_free: {
-      free(r->data);
-      r->data = 0;
-      r->data_size = 0;
+  return 0;
+}
+
+static int fd_fill(struct labcomm_reader *r)
+{
+  int result;
+  int *fd = r->context;
+
+  if (r->pos < r->count) {
+    result = r->count - r->pos;
+  } else {
+    int err;
+    
+    r->pos = 0;
+    err = read(*fd, r->data, r->data_size);
+    if (err <= 0) {
       r->count = 0;
-      r->pos = 0;
-      result = 0;
-    } break;
-    case labcomm_reader_ioctl: {
-      result = -ENOTSUP;
+      result = -EPIPE;
+    } else {
+      r->count = err;
+      result = r->count - r->pos;
     }
   }
   return result;
 }
 
+static int fd_start(struct labcomm_reader *r)
+{
+  return fd_fill(r);
+}
+
+static int fd_end(struct labcomm_reader *r)
+{
+  return 0;
+}
+
+const struct labcomm_reader_action labcomm_fd_reader = {
+  .alloc = fd_alloc,
+  .free = fd_free,
+  .start = fd_start,
+  .fill = fd_fill,
+  .end = fd_end,
+  .ioctl = NULL
+};
diff --git a/lib/c/labcomm_fd_reader.h b/lib/c/labcomm_fd_reader.h
index c06cb3ada399b8a31cf5e9bd9ae914adf3a46f05..55882cf0e049fe6908677eecade680e5345d7c2a 100644
--- a/lib/c/labcomm_fd_reader.h
+++ b/lib/c/labcomm_fd_reader.h
@@ -3,10 +3,7 @@
 
 #include "labcomm.h"
 
-extern int labcomm_fd_reader(
-  labcomm_reader_t *reader, 
-  labcomm_reader_action_t action,
-  ...);
+extern const struct labcomm_reader_action labcomm_fd_reader;
 
 #endif
 
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index 36c122e565e3b9d3442ad7f17feb0755ad58f56b..fd1068c1481b699447b7fb5b74e600747419284e 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -90,7 +90,7 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder,
     type result; int i;							\
     for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
       if (r->pos >= r->count) {						\
-	r->read(r, labcomm_reader_continue);				\
+	r->action.fill(r);						\
       }									\
       ((unsigned char*)(&result))[i] = r->data[r->pos];			\
       r->pos++;								\
@@ -108,7 +108,7 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder,
     type result; int i;							\
     for (i = 0 ; i < sizeof(type) ; i++) {				\
       if (r->pos >= r->count) {						\
-	r->read(r, labcomm_reader_continue);				\
+	r->action.fill(r);						\
       }									\
       ((unsigned char*)(&result))[i] = r->data[r->pos];			\
       r->pos++;								\
@@ -129,56 +129,6 @@ LABCOMM_DECODE(long, long long)
 LABCOMM_DECODE(float, float)
 LABCOMM_DECODE(double, double)
 
-#if 0
-/* 
- * Unpack a 32 bit unsigned number from a sequence bytes, where the 
- * first byte is prefixed with a variable length bit pattern that
- * indicates the number of bytes used for encoding. The encoding
- * is inspired by the UTF-8 encoding.
- *
- * 0b0     - 1 byte  (0x00000000 - 0x0000007f)
- * 0b10    - 2 bytes (0x00000080 - 0x00003fff)
- * 0b110   - 3 bytes (0x00004000 - 0x001fffff)
- * 0b1110  - 4 bytes (0x00200000 - 0x0fffffff)
- * 0b11110 - 5 bytes (0x10000000 - 0xffffffff) [4 bits unused]
- */
-static inline unsigned int labcomm_read_unpacked32(labcomm_reader_t *r)
-{
-  unsigned int result = 0;
-  int n, i;
-  unsigned char tag;
-
-  if (r->pos >= r->count) {	
-    r->read(r, labcomm_reader_continue);
-  }
-  tag = r->data[r->pos];
-  r->pos++;
-  if (tag < 0x80) {
-    n = 1;
-    result = tag;
-  } else if (tag < 0xc0) {
-    n = 2;
-    result = tag & 0x3f;
-  } else if (tag < 0xe0) {
-    n = 3;
-    result = tag & 0x1f;
-  } else if (tag < 0xf0) {
-    n = 4;
-    result = tag & 0x0f;
-  } else {
-    n = 5;
-  }
-  for (i = 1 ; i < n ; i++) {
-    if (r->pos >= r->count) {	
-      r->read(r, labcomm_reader_continue);
-    }
-    result = (result << 8) | r->data[r->pos];
-    r->pos++;
-  }
-  return result;
-}
-#endif
-
 static inline unsigned int labcomm_read_unpacked32(labcomm_reader_t *r)
 {
   unsigned int result = 0;
@@ -187,7 +137,7 @@ static inline unsigned int labcomm_read_unpacked32(labcomm_reader_t *r)
     unsigned char tmp;
 
     if (r->pos >= r->count) {	
-      r->read(r, labcomm_reader_continue);
+      r->action.fill(r);
     }
     tmp = r->data[r->pos];
     r->pos++;
@@ -213,7 +163,7 @@ static inline char *labcomm_read_string(labcomm_reader_t *r)
   result = malloc(length + 1);
   for (i = 0 ; i < length ; i++) {
     if (r->pos >= r->count) {	
-      r->read(r, labcomm_reader_continue);
+      r->action.fill(r);
     }
     result[i] = r->data[r->pos];
     r->pos++;
diff --git a/lib/c/test/test_labcomm_basic_type_encoding.c b/lib/c/test/test_labcomm_basic_type_encoding.c
index 270796e9f45b1659f2c8877b04b10f0c38f00a89..2efad6fd841144735e67633866b458dc2c86af22 100644
--- a/lib/c/test/test_labcomm_basic_type_encoding.c
+++ b/lib/c/test/test_labcomm_basic_type_encoding.c
@@ -43,8 +43,7 @@ static labcomm_decoder_t decoder = {
     .data_size = sizeof(buffer),
     .count = 0,
     .pos = 0,
-    .read = test_read,
-    .ioctl = NULL,
+    .action = { NULL, NULL, NULL, NULL, NULL, NULL },
     .on_error = NULL,
   },
   .do_register = NULL,
diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c
index 6548978f9028b85295ac9887612d445e3c7fd9fa..f539111ce4d5c3f57a4c905a3bfc4c29f776fc5c 100644
--- a/lib/c/test/test_labcomm_generated_encoding.c
+++ b/lib/c/test/test_labcomm_generated_encoding.c
@@ -11,12 +11,6 @@ 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, ...)
-{
-  fprintf(stderr, "test_read should not be called\n");
-  exit(1);
-}
-
 #define IOCTL_WRITER_ASSERT_BYTES 4096
 #define IOCTL_WRITER_RESET 4097
 
diff --git a/test/Makefile b/test/Makefile
index de2dd411541dc90baeca1533999b9694b9c44e00..0bce5a95de0f84985497daa1fb6abf243753db86 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -2,6 +2,8 @@ TESTS=basic simple nested
 LABCOMM_JAR=../compiler/labComm.jar
 LABCOMM=java -jar $(LABCOMM_JAR) 
 
+CFLAGS=-O3 -Wall -Werror
+
 all:	
 
 test: $(TESTS:%=test_%)