From 1112f3baeabb07be1dbb73f200b40612e0587e13 Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Tue, 11 Jun 2013 18:13:56 +0200
Subject: [PATCH] Changed interface for readers/writers to simplify stacked
 operation. Start of adding GPLv3 licensensing.

---
 examples/twoway/decimating.c                  | 200 +++++++----------
 lib/c/Makefile                                |   4 +-
 lib/c/labcomm.c                               | 206 +++++++++++++-----
 lib/c/labcomm.h                               |  22 ++
 lib/c/labcomm_dynamic_buffer_writer.c         |  57 ++++-
 lib/c/labcomm_fd_reader.c                     |  52 ++++-
 lib/c/labcomm_fd_writer.c                     |  52 ++++-
 lib/c/labcomm_private.h                       | 136 +++++++++---
 lib/c/test/test_labcomm_basic_type_encoding.c |  27 ++-
 lib/c/test/test_labcomm_generated_encoding.c  |  64 ++++--
 10 files changed, 563 insertions(+), 257 deletions(-)

diff --git a/examples/twoway/decimating.c b/examples/twoway/decimating.c
index 769dd30..e80e7ad 100644
--- a/examples/twoway/decimating.c
+++ b/examples/twoway/decimating.c
@@ -1,3 +1,25 @@
+/*
+  decimating.c -- LabComm example of a twoway stacked decimation 
+                  reader/writer.
+
+  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 <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -11,14 +33,8 @@ struct decimating_private {
   int encoder_initialized;
   struct labcomm_decoder *decoder;
   int decoder_initialized;
-  struct orig_reader {
-    void *context;
-    const struct labcomm_reader_action *action;
-  } orig_reader;
-  struct orig_writer {
-    void *context;
-    const struct labcomm_writer_action *action;
-  } orig_writer;
+  struct labcomm_reader_action_context reader_action_context;
+  struct labcomm_writer_action_context writer_action_context;
   LABCOMM_SIGNATURE_ARRAY_DEF(decimation, 
 			      struct decimation {
 				int n;
@@ -40,67 +56,42 @@ static void set_decimation(
   decimation->current = 0;
 }
 
-static int wrap_reader_alloc(struct labcomm_reader *r, void *context, 
-			     struct labcomm_decoder *decoder,
-			     char *labcomm_version)
+static int wrap_reader_alloc(
+  struct labcomm_reader *r, 
+  struct labcomm_reader_action_context *action_context, 
+  struct labcomm_decoder *decoder,
+  char *labcomm_version)
 {
-  int result;
-  struct decimating_private *decimating = context;
-  struct orig_reader *orig_reader = &decimating->orig_reader;
+  struct decimating_private *decimating = action_context->context;
 
   /* Stash away decoder for later use */
   decimating->decoder = decoder;
-  result = orig_reader->action->alloc(r, orig_reader->context, 
-				      decoder, labcomm_version);
-  return result;
+  return labcomm_reader_alloc(r, action_context->next, 
+			      decoder, labcomm_version);
 }
 
-static int wrap_reader_free(struct labcomm_reader *r, void *context)
+static int wrap_reader_start(
+  struct labcomm_reader *r, 
+  struct labcomm_reader_action_context *action_context)
 {
-  struct decimating_private *decimating = context;
-  struct orig_reader *orig_reader = &decimating->orig_reader;
-
-  return orig_reader->action->free(r, orig_reader->context);
-}
-
-static int wrap_reader_start(struct labcomm_reader *r, void *context)
-{
-  struct decimating_private *decimating = context;
-  struct orig_reader *orig_reader = &decimating->orig_reader;
+  struct decimating_private *decimating = action_context->context;
 
   if (! decimating->decoder_initialized) {
     decimating->decoder_initialized = 1;
     labcomm_decoder_register_decimating_messages_set_decimation(
       decimating->decoder, set_decimation, decimating);
   }
-  return orig_reader->action->start(r, orig_reader->context);
-}
-
-static int wrap_reader_end(struct labcomm_reader *r, void *context)
-{
-  struct decimating_private *decimating = context;
-  struct orig_reader *orig_reader = &decimating->orig_reader;
-
-  return orig_reader->action->end(r, orig_reader->context);
+  return labcomm_reader_start(r, action_context->next);
 }
 
-static int wrap_reader_fill(struct labcomm_reader *r, void *context)
+static int wrap_reader_ioctl(
+  struct labcomm_reader *r,   
+  struct labcomm_reader_action_context *action_context,
+  int signature_index,
+  struct labcomm_signature *signature, 
+  uint32_t action, va_list args)
 {
-  struct decimating_private *decimating = context;
-  struct orig_reader *orig_reader = &decimating->orig_reader;
-  int result;
-
-  result = orig_reader->action->fill(r, orig_reader->context);
-  return result;
-} 
-
-static int wrap_reader_ioctl(struct labcomm_reader *r, void *context,
-			     int signature_index,
-			     struct labcomm_signature *signature, 
-			     uint32_t action, va_list args)
-{
-  struct decimating_private *decimating = context;
-  struct orig_reader *orig_reader = &decimating->orig_reader;
+  struct decimating_private *decimating = action_context->context;
 
   if (action == SET_DECIMATION) {
     decimating_messages_set_decimation decimation;
@@ -113,48 +104,42 @@ static int wrap_reader_ioctl(struct labcomm_reader *r, void *context,
     return labcomm_encode_decimating_messages_set_decimation(
       decimating->encoder, &decimation);
   } else {
-    return orig_reader->action->ioctl(r, orig_reader->context,
-				      signature_index, signature, action, args);
+    return labcomm_reader_ioctl(r, action_context->next,
+				signature_index, signature, action, args);
   }
   
 }
 
 struct labcomm_reader_action decimating_reader_action = {
   .alloc = wrap_reader_alloc,
-  .free = wrap_reader_free, 
+  .free = NULL,
   .start = wrap_reader_start,
-  .end = wrap_reader_end,
-  .fill = wrap_reader_fill,
+  .end = NULL,
+  .fill = NULL,
   .ioctl = wrap_reader_ioctl
 };
 
-int wrap_writer_alloc(struct labcomm_writer *w, void *context, 
-		      struct labcomm_encoder *encoder, char *labcomm_version)
+static int wrap_writer_alloc(
+  struct labcomm_writer *w, 
+  struct labcomm_writer_action_context *action_context, 
+  struct labcomm_encoder *encoder, char *labcomm_version)
 {
-  struct decimating_private *decimating = context;
-  struct orig_writer *orig_writer = &decimating->orig_writer;
+  struct decimating_private *decimating = action_context->context;
 
   /* Stash away encoder for later use */
   decimating->encoder = encoder;
-  return orig_writer->action->alloc(w, orig_writer->context,
-				    encoder, labcomm_version);
-}
-
-int wrap_writer_free(struct labcomm_writer *w, void *context)
-{  
-  struct decimating_private *decimating = context;
-  struct orig_writer *orig_writer = &decimating->orig_writer;
-
-  return orig_writer->action->free(w, orig_writer->context);
+  return labcomm_writer_alloc(w, action_context->next,
+			      encoder, labcomm_version);
 }
 
-int wrap_writer_start(struct labcomm_writer *w, void *context,
-		      struct labcomm_encoder *encoder,
-		      int index, struct labcomm_signature *signature,
-		      void *value)
+static int wrap_writer_start(
+  struct labcomm_writer *w, 
+  struct labcomm_writer_action_context *action_context, 
+  struct labcomm_encoder *encoder,
+  int index, struct labcomm_signature *signature,
+  void *value)
 {
-  struct decimating_private *decimating = context;
-  struct orig_writer *orig_writer = &decimating->orig_writer;
+  struct decimating_private *decimating = action_context->context;
   struct decimation *decimation;
 
   if (! decimating->encoder_initialized) {
@@ -169,47 +154,18 @@ int wrap_writer_start(struct labcomm_writer *w, void *context,
     return -EALREADY;
   } else {
     decimation->current = 0;
-    return orig_writer->action->start(w, orig_writer->context,
-				      encoder, index, signature, value);
+    return labcomm_writer_start(w, action_context->next,
+				encoder, index, signature, value);
   }
 }
 
-int wrap_writer_end(struct labcomm_writer *w, void *context)
-{
-  struct decimating_private *decimating = context;
-  struct orig_writer *orig_writer = &decimating->orig_writer;
-
-  return orig_writer->action->end(w, orig_writer->context);
-}
-
-int wrap_writer_flush(struct labcomm_writer *w, void *context)
-{
-  struct decimating_private *decimating = context;
-  struct orig_writer *orig_writer = &decimating->orig_writer;
-
-  return orig_writer->action->flush(w, orig_writer->context);
-}
-
-int wrap_writer_ioctl(struct labcomm_writer *w, void *context, 
-		      int signature_index,
-		      struct labcomm_signature *signature, 
-		      uint32_t action, va_list args)
-{
-  struct decimating_private *decimating = context;
-  struct orig_writer *orig_writer = &decimating->orig_writer;
-
-  return orig_writer->action->ioctl(w, orig_writer->context,
-				    signature_index, signature, action, args);
-}
-
-
 struct labcomm_writer_action decimating_writer_action = {
   .alloc = wrap_writer_alloc,
-  .free = wrap_writer_free, 
+  .free = NULL, 
   .start = wrap_writer_start,
-  .end = wrap_writer_end,
-  .flush = wrap_writer_flush,
-  .ioctl = wrap_writer_ioctl
+  .end = NULL,
+  .flush = NULL,
+  .ioctl = NULL
 };
 
 extern struct decimating *decimating_new(
@@ -225,15 +181,15 @@ extern struct decimating *decimating_new(
   }
 
   /* Wrap reader and writer */
-  result->orig_reader.context = reader->context;
-  result->orig_reader.action = reader->action;
-  reader->context = result;
-  reader->action = &decimating_reader_action;
-
-  result->orig_writer.context = writer->context;
-  result->orig_writer.action = writer->action;
-  writer->context = result;
-  writer->action = &decimating_writer_action;
+  result->reader_action_context.next = reader->action_context;
+  result->reader_action_context.action = &decimating_reader_action;
+  result->reader_action_context.context = result;
+  reader->action_context = &result->reader_action_context;
+
+  result->writer_action_context.next = writer->action_context;
+  result->writer_action_context.action = &decimating_writer_action;
+  result->writer_action_context.context = result;
+  writer->action_context = &result->writer_action_context;
 
   /* Init visible result struct */
   result->decimating.reader = reader;
diff --git a/lib/c/Makefile b/lib/c/Makefile
index a22d14c..50325b6 100644
--- a/lib/c/Makefile
+++ b/lib/c/Makefile
@@ -112,7 +112,9 @@ distclean: clean
 
 # Extra dependencies
 $(TEST_DIR)/test_labcomm_basic_type_encoding.o: labcomm_private.h
-$(TEST_DIR)/test_labcomm_generated_encoding.o : $(TEST_DIR)/gen/generated_encoding.h
+
+$(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
 labcomm_fd_reader.o: labcomm_private.h
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
index 801c5f7..7aec84c 100644
--- a/lib/c/labcomm.c
+++ b/lib/c/labcomm.c
@@ -4,12 +4,14 @@
 
   Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
-  This program is free software: you can redistribute it and/or modify
+  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.
 
-  This program is distributed in the hope that it will be useful,
+  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.
@@ -83,6 +85,104 @@ struct labcomm_decoder_context {
   struct labcomm_sample_entry *sample;
 };
 
+/* Unwrapping reader/writer functions */
+#define UNWRAP_ac(func, rw, ac, ...) ac
+#define UNWRAP(func, ...)	     \
+  while (1) {								\
+    if (UNWRAP_ac(func, __VA_ARGS__)->action->func) {			\
+      return UNWRAP_ac(func, __VA_ARGS__)->action->func(__VA_ARGS__); }	\
+    if (UNWRAP_ac(func, __VA_ARGS__)->next == NULL) { return -ENOSYS; }	\
+    UNWRAP_ac(func, __VA_ARGS__) = UNWRAP_ac(func, __VA_ARGS__)->next;	\
+  }
+
+int labcomm_reader_alloc(struct labcomm_reader *r, 
+                         struct labcomm_reader_action_context *action_context, 
+                         struct labcomm_decoder *decoder, 
+                         char *labcomm_version)
+{
+  UNWRAP(alloc, r, action_context, decoder, labcomm_version);
+}
+
+int labcomm_reader_free(struct labcomm_reader *r, 
+                        struct labcomm_reader_action_context *action_context)
+{
+  UNWRAP(free, r, action_context);
+}
+
+int labcomm_reader_start(struct labcomm_reader *r, 
+                         struct labcomm_reader_action_context *action_context)
+{
+  UNWRAP(start, r, action_context);
+}
+
+int labcomm_reader_end(struct labcomm_reader *r, 
+                       struct labcomm_reader_action_context *action_context)
+{
+  UNWRAP(end, r, action_context);
+}
+
+int labcomm_reader_fill(struct labcomm_reader *r, 
+                        struct labcomm_reader_action_context *action_context)
+{
+  UNWRAP(fill, r, action_context);
+}
+
+int labcomm_reader_ioctl(struct labcomm_reader *r, 
+                         struct labcomm_reader_action_context *action_context,
+                         int index, 
+                         struct labcomm_signature *signature, 
+                         uint32_t ioctl_action, va_list args)
+{
+  UNWRAP(ioctl, r, action_context, index, signature, ioctl_action, args);
+}
+
+int labcomm_writer_alloc(struct labcomm_writer *w, 
+                         struct labcomm_writer_action_context *action_context, 
+                         struct labcomm_encoder *encoder, 
+                         char *labcomm_version)
+{
+  UNWRAP(alloc, w, action_context, encoder, labcomm_version);
+}
+
+int labcomm_writer_free(struct labcomm_writer *w, 
+                        struct labcomm_writer_action_context *action_context)
+{
+  UNWRAP(free, w, action_context);
+}
+
+int labcomm_writer_start(struct labcomm_writer *w, 
+                         struct labcomm_writer_action_context *action_context,
+                         struct labcomm_encoder *encoder,
+                         int index, struct labcomm_signature *signature,
+                         void *value)
+{
+  UNWRAP(start, w, action_context, encoder, index, signature, value);
+}
+
+int labcomm_writer_end(struct labcomm_writer *w, 
+                       struct labcomm_writer_action_context *action_context)
+{
+  UNWRAP(end, w, action_context);
+} 
+
+int labcomm_writer_flush(struct labcomm_writer *w, 
+                         struct labcomm_writer_action_context *action_context)
+{
+  UNWRAP(flush, w, action_context);
+} 
+
+int labcomm_writer_ioctl(struct labcomm_writer *w, 
+                         struct labcomm_writer_action_context *action_context, 
+                         int index, 
+                         struct labcomm_signature *signature, 
+                         uint32_t ioctl_action, va_list args)
+{
+  UNWRAP(ioctl, w, action_context, index, signature, ioctl_action, args);
+} 
+
+
+
+
 void labcomm_register_error_handler_encoder(struct labcomm_encoder *encoder, labcomm_error_handler_callback callback)
 {
  encoder->on_error = callback; 
@@ -237,20 +337,20 @@ static void labcomm_encode_signature(struct labcomm_encoder *e,
   int i, index;
 
   index = get_encoder_index(e, signature);
-  e->writer->action->start(e->writer, e->writer->context, 
-			   e, index, signature, NULL);
+  labcomm_writer_start(e->writer, e->writer->action_context, 
+		       e, index, signature, NULL);
   labcomm_write_packed32(e->writer, signature->type);
   labcomm_write_packed32(e->writer, index);
 
   labcomm_write_string(e->writer, signature->name);
   for (i = 0 ; i < signature->size ; i++) {
     if (e->writer->pos >= e->writer->count) {
-      e->writer->action->flush(e->writer, e->writer->context);
+      labcomm_writer_flush(e->writer, e->writer->action_context);
     }
     e->writer->data[e->writer->pos] = signature->signature[i];
     e->writer->pos++;
   }
-  e->writer->action->end(e->writer, e->writer->context);
+  labcomm_writer_end(e->writer, e->writer->action_context);
 }
 
 #ifdef LABCOMM_ENCODER_LINEAR_SEARCH
@@ -322,8 +422,8 @@ struct labcomm_encoder *labcomm_encoder_new(
     result->lock = lock;
     result->on_error = on_error_fprintf;
     LABCOMM_SIGNATURE_ARRAY_INIT(result->registered, int);
-    result->writer->action->alloc(result->writer,result->writer->context,
-				  result, LABCOMM_VERSION);
+    labcomm_writer_alloc(result->writer,result->writer->action_context,
+			 result, LABCOMM_VERSION);
   }
   return result;
 }
@@ -364,7 +464,7 @@ int labcomm_internal_encode(
   int index;
 
   index = get_encoder_index(e, signature);
-  result = e->writer->action->start(e->writer, e->writer->context, 
+  result = labcomm_writer_start(e->writer, e->writer->action_context, 
 				    e, index, signature, value);
   if (result == -EALREADY) { result = 0; goto no_end; }
   if (result != 0) { goto out; }
@@ -372,7 +472,7 @@ int labcomm_internal_encode(
   if (result != 0) { goto out; }
   result = encode(e->writer, value);
 out:
-  e->writer->action->end(e->writer, e->writer->context);
+  labcomm_writer_end(e->writer, e->writer->action_context);
 no_end:
   return result;
 }
@@ -382,7 +482,7 @@ void labcomm_encoder_free(struct labcomm_encoder* e)
   struct labcomm_encoder_context *context;
 
   context = (struct labcomm_encoder_context *) e->context;
-  e->writer->action->free(e->writer, e->writer->context);
+  labcomm_writer_free(e->writer, e->writer->action_context);
   LABCOMM_SIGNATURE_ARRAY_FREE(e->registered, int);
 
 #ifdef LABCOMM_ENCODER_LINEAR_SEARCH
@@ -407,44 +507,36 @@ int labcomm_encoder_ioctl(struct labcomm_encoder *encoder,
   int result;
   va_list va;
     
-  if (encoder->writer->action->ioctl == NULL) {
-    result = -ENOTSUP;
-    goto out;
-  }
   if (LABCOMM_IOC_SIG(action) != LABCOMM_IOC_NOSIG) {
     result = -EINVAL;
     goto out;
   }
     
   va_start(va, action);
-  result = encoder->writer->action->ioctl(encoder->writer, 
-					  encoder->writer->context,
-					  0, NULL, action, va);
+  result = labcomm_writer_ioctl(encoder->writer, 
+			       encoder->writer->action_context,
+			       0, NULL, action, va);
   va_end(va);
 
 out:
   return result;
 }
 
-static int labcomm_writer_ioctl(struct labcomm_writer *writer,
-				uint32_t action,
-				...)
+static int writer_ioctl(struct labcomm_writer *writer,
+			uint32_t action,
+			...)
 {
   int result;
   va_list va;
 
-  if (writer->action->ioctl == NULL) {
-    result = -ENOTSUP;
-    goto out;
-  }
   if (LABCOMM_IOC_SIG(action) != LABCOMM_IOC_NOSIG) {
     result = -EINVAL;
     goto out;
   }
   
   va_start(va, action);
-  result = writer->action->ioctl(writer, writer->context, 
-				 0, NULL, action, va);
+  result = labcomm_writer_ioctl(writer, writer->action_context, 
+				0, NULL, action, va);
   va_end(va);
 out:
   return result;
@@ -456,11 +548,9 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
 {
   int result = -ENOTSUP;
   
-  if (encoder->writer->action->ioctl != NULL) {
-    result = encoder->writer->action->ioctl(encoder->writer, 
-					    encoder->writer->context, 
-					    -1, signature, action, va);
-  }
+  result = labcomm_writer_ioctl(encoder->writer, 
+				encoder->writer->action_context, 
+				-1, signature, action, va);
   return result;
 }
 
@@ -568,13 +658,13 @@ 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);
+    result = labcomm_reader_alloc(d->reader, d->reader->action_context,
+				  d, LABCOMM_VERSION);
     if (result <= 0) {
       goto out;
     }
   }
-  result = d->reader->action->start(d->reader, d->reader->context);
+  result = labcomm_reader_start(d->reader, d->reader->action_context);
   if (result > 0) {
     struct labcomm_decoder_context *context = d->context;
     
@@ -582,36 +672,40 @@ int labcomm_decoder_decode_one(struct labcomm_decoder *d)
     if (result == LABCOMM_TYPEDEF || result == LABCOMM_SAMPLE) {
       /* TODO: should the labcomm_dynamic_buffer_writer be 
 	 a permanent part of labcomm_decoder? */
+      struct labcomm_writer_action_context action_context = {
+	.next = NULL,
+	.action = labcomm_dynamic_buffer_writer_action,
+	.context = NULL
+      };
       struct labcomm_writer writer = {
-	.context = NULL,
+	.action_context = &action_context,
 	.data = NULL,
 	.data_size = 0,
 	.count = 0,
 	.pos = 0,
 	.error = 0,
-	.action = labcomm_dynamic_buffer_writer_action,
       };
       struct labcomm_signature signature;
       struct labcomm_sample_entry *entry = NULL;
       int index, err;
       
-      writer.action->alloc(&writer, writer.context, NULL, "");
-      writer.action->start(&writer, writer.context, NULL, 0, NULL, NULL);
+      labcomm_writer_alloc(&writer, writer.action_context, NULL, "");
+      labcomm_writer_start(&writer, writer.action_context, NULL, 0, NULL, NULL);
       index = labcomm_read_packed32(d->reader); //int
       signature.name = labcomm_read_string(d->reader);
       signature.type = result;
       collect_flat_signature(d, &writer);
-      writer.action->end(&writer, writer.context);
-      err = labcomm_writer_ioctl(&writer, 
-				 LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN,
-				 &signature.size);
+      labcomm_writer_end(&writer, writer.action_context);
+      err = writer_ioctl(&writer, 
+			 LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN,
+			 &signature.size);
       if (err < 0) {
 	printf("Failed to get size: %s\n", strerror(-err));
 	goto free_signature_name;
       }
-      err = labcomm_writer_ioctl(&writer, 
-				 LABCOMM_IOCTL_WRITER_GET_BYTE_POINTER,
-				 &signature.signature);
+      err = writer_ioctl(&writer, 
+			 LABCOMM_IOCTL_WRITER_GET_BYTE_POINTER,
+			 &signature.signature);
       if (err < 0) {
 	printf("Failed to get pointer: %s\n", strerror(-err));
 	goto free_signature_name;
@@ -639,7 +733,7 @@ int labcomm_decoder_decode_one(struct labcomm_decoder *d)
       }
     free_signature_name:
       free(signature.name);
-      writer.action->free(&writer, writer.context);
+      labcomm_writer_free(&writer, writer.action_context);
       if (!entry) {
 	// No handler for found type, bail out (after cleanup)
 	result = -ENOENT;
@@ -659,7 +753,7 @@ int labcomm_decoder_decode_one(struct labcomm_decoder *d)
       }
     }
   }
-  d->reader->action->end(d->reader, d->reader->context);
+  labcomm_reader_end(d->reader, d->reader->action_context);
 out:
   return result;
 }
@@ -676,7 +770,7 @@ void labcomm_decoder_free(struct labcomm_decoder* d)
   struct labcomm_sample_entry *entry = context->sample;
   struct labcomm_sample_entry *entry_next;
 
-  d->reader->action->free(d->reader, d->reader->context);
+  labcomm_reader_free(d->reader, d->reader->action_context);
   LABCOMM_SIGNATURE_ARRAY_FREE(d->local_to_remote, int);
   LABCOMM_SIGNATURE_ARRAY_FREE(d->remote_to_local, int);
   while (entry != NULL) {
@@ -697,9 +791,9 @@ int labcomm_decoder_ioctl(struct labcomm_decoder *decoder,
   va_list va;
     
   va_start(va, action);
-  result = decoder->reader->action->ioctl(decoder->reader, 
-					  decoder->reader->context,
-					  0, NULL, action, va);
+  result = labcomm_reader_ioctl(decoder->reader, 
+				decoder->reader->action_context,
+				0, NULL, action, va);
   va_end(va);
   return result;
 }
@@ -717,10 +811,10 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder,
   if (*remote_index == 0) {
     result = -EAGAIN;
   } else {
-    result = decoder->reader->action->ioctl(decoder->reader, 
-					    decoder->reader->context,
-					    *remote_index, signature, 
-					    action, va);
+    result = labcomm_reader_ioctl(decoder->reader, 
+				  decoder->reader->action_context,
+				  *remote_index, signature, 
+				  action, va);
   }
   return result;
 }
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
index 5592b2c..f7b273c 100644
--- a/lib/c/labcomm.h
+++ b/lib/c/labcomm.h
@@ -1,3 +1,25 @@
+/*
+  labcomm.h -- user interface for handling encoding and decoding of
+               labcomm samples.
+
+  Copyright 2006-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/>.
+*/
+
 #ifndef _LABCOMM_H_
 #define _LABCOMM_H_
 
diff --git a/lib/c/labcomm_dynamic_buffer_writer.c b/lib/c/labcomm_dynamic_buffer_writer.c
index 9588807..cca4df2 100644
--- a/lib/c/labcomm_dynamic_buffer_writer.c
+++ b/lib/c/labcomm_dynamic_buffer_writer.c
@@ -1,3 +1,24 @@
+/*
+  labcomm_dynamic_buffer_writer.c -- LabComm dynamic memory writer.
+
+  Copyright 2006-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 <errno.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -6,7 +27,8 @@
 #include "labcomm_ioctl.h"
 #include "labcomm_dynamic_buffer_writer.h"
 
-static int dyn_alloc(struct labcomm_writer *w, void *context,
+static int dyn_alloc(struct labcomm_writer *w, 
+		     struct labcomm_writer_action_context *action_context,
 		     struct labcomm_encoder *encoder,
 		     char *labcomm_version)
 {
@@ -21,18 +43,22 @@ static int dyn_alloc(struct labcomm_writer *w, void *context,
   return w->error;
 }
 
-static int dyn_free(struct labcomm_writer *w, void *context)
+static int dyn_free(struct labcomm_writer *w, 
+		    struct labcomm_writer_action_context *action_context)
 {
   free(w->data);
   w->data = 0;
   w->data_size = 0;
   w->count = 0;
   w->pos = 0;
-
+  if (action_context->context) {
+    free(action_context->context);
+  }
   return 0;
 }
 
-static int dyn_start(struct labcomm_writer *w, void *context,
+static int dyn_start(struct labcomm_writer *w, 
+		     struct labcomm_writer_action_context *action_context,
 		     struct labcomm_encoder *encoder,
 		     int index,
 		     struct labcomm_signature *signature,
@@ -54,12 +80,14 @@ static int dyn_start(struct labcomm_writer *w, void *context,
   return w->error;
 }
 
-static int dyn_end(struct labcomm_writer *w, void *context)
+static int dyn_end(struct labcomm_writer *w, 
+		   struct labcomm_writer_action_context *action_context)
 {
   return 0;
 }
 
-static int dyn_flush(struct labcomm_writer *w, void *context)
+static int dyn_flush(struct labcomm_writer *w, 
+		     struct labcomm_writer_action_context *action_context)
 {
   void *tmp;
 
@@ -76,7 +104,8 @@ static int dyn_flush(struct labcomm_writer *w, void *context)
   return w->error; 
 }
 
-static int dyn_ioctl(struct labcomm_writer *w, void *context, 
+static int dyn_ioctl(struct labcomm_writer *w, 
+		     struct labcomm_writer_action_context *action_context, 
 		     int signature_index,
 		     struct labcomm_signature *signature,
 		     uint32_t action, va_list arg)
@@ -110,13 +139,19 @@ const struct labcomm_writer_action *labcomm_dynamic_buffer_writer_action =
 
 struct labcomm_writer *labcomm_dynamic_buffer_writer_new()
 {
-  struct labcomm_writer *result;
+  struct result {
+    struct labcomm_writer writer;
+    struct labcomm_writer_action_context action_context;
+  } *result;
 
   result = malloc(sizeof(*result));
   if (result != NULL) {
-    result->context = NULL;
-    result->action = &action;
+    result->action_context.next = NULL;
+    result->action_context.context = result;
+    result->action_context.action = &action;
+    result->writer.action_context = &result->action_context;
+    return &result->writer;
   }
-  return result;
+  return NULL;
 }
 
diff --git a/lib/c/labcomm_fd_reader.c b/lib/c/labcomm_fd_reader.c
index 8edbdcd..154b0a8 100644
--- a/lib/c/labcomm_fd_reader.c
+++ b/lib/c/labcomm_fd_reader.c
@@ -1,3 +1,24 @@
+/*
+  labcomm_fd_reader.c -- LabComm reader for Unix file descriptors.
+
+  Copyright 2006-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 <errno.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -9,11 +30,13 @@
 
 struct labcomm_fd_reader {
   struct labcomm_reader reader;
+  struct labcomm_reader_action_context action_context;
   int fd;
   int close_fd_on_free;
 };
 
-static int fd_alloc(struct labcomm_reader *r, void *context, 
+static int fd_alloc(struct labcomm_reader *r,
+		    struct labcomm_reader_action_context *action_context, 
 		    struct labcomm_decoder *decoder,
 		    char *version)
 {
@@ -44,9 +67,10 @@ static int fd_alloc(struct labcomm_reader *r, void *context,
   return result;
 }
 
-static int fd_free(struct labcomm_reader *r, void *context)
+static int fd_free(struct labcomm_reader *r, 
+		   struct labcomm_reader_action_context *action_context)
 {
-  struct labcomm_fd_reader *fd_context = context;
+  struct labcomm_fd_reader *fd_context = action_context->context;
 
   free(r->data);
   r->data = 0;
@@ -62,10 +86,11 @@ static int fd_free(struct labcomm_reader *r, void *context)
   return 0;
 }
 
-static int fd_fill(struct labcomm_reader *r, void *context)
+static int fd_fill(struct labcomm_reader *r, 
+		   struct labcomm_reader_action_context *action_context)
 {
   int result = 0;
-  struct labcomm_fd_reader *fd_context = context;
+  struct labcomm_fd_reader *fd_context = action_context->context;
 
   if (r->pos < r->count) {
     result = r->count - r->pos;
@@ -86,23 +111,26 @@ static int fd_fill(struct labcomm_reader *r, void *context)
   return result;
 }
 
-static int fd_start(struct labcomm_reader *r, void *context)
+static int fd_start(struct labcomm_reader *r,
+		    struct labcomm_reader_action_context *action_context)
 {
   int available;
 
   available = r->count - r->pos;
   if (available == 0) {
-    available = fd_fill(r, context);
+    available = fd_fill(r, action_context);
   }
   return available;
 }
 
-static int fd_end(struct labcomm_reader *r, void *context)
+static int fd_end(struct labcomm_reader *r, 
+		  struct labcomm_reader_action_context *action_context)
 {
   return 0;
 }
 
-static int fd_ioctl(struct labcomm_reader *r, void *context,
+static int fd_ioctl(struct labcomm_reader *r, 
+		    struct labcomm_reader_action_context *action_context,
 		    int signature_index, 
 		    struct labcomm_signature *signature, 
 		    uint32_t action, va_list args)
@@ -128,10 +156,12 @@ struct labcomm_reader *labcomm_fd_reader_new(int fd, int close_fd_on_free)
   if (result == NULL) {
     return NULL;
   } else {
+    result->reader.action_context = &result->action_context;
+    result->action_context.next = NULL;
+    result->action_context.action = &action;
+    result->action_context.context = result;
     result->fd = fd;
     result->close_fd_on_free = close_fd_on_free;
-    result->reader.context = result;
-    result->reader.action = &action;
     return &result->reader;
   }
 }
diff --git a/lib/c/labcomm_fd_writer.c b/lib/c/labcomm_fd_writer.c
index b712ffb..1ff8b22 100644
--- a/lib/c/labcomm_fd_writer.c
+++ b/lib/c/labcomm_fd_writer.c
@@ -1,3 +1,24 @@
+/*
+  labcomm_fd_writer.c -- LabComm writer for Unix file descriptors.
+
+  Copyright 2006-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 <errno.h>
 #include <unistd.h>
 #include <string.h>
@@ -10,13 +31,16 @@
 
 struct labcomm_fd_writer {
   struct labcomm_writer writer;
+  struct labcomm_writer_action_context action_context;
   int fd;
   int close_fd_on_free;
 };
 
-static int fd_flush(struct labcomm_writer *w, void *context);
+static int fd_flush(struct labcomm_writer *w, 
+		    struct labcomm_writer_action_context *action_context);
 
-static int fd_alloc(struct labcomm_writer *w, void *context, 
+static int fd_alloc(struct labcomm_writer *w, 
+		    struct labcomm_writer_action_context *action_context, 
 		    struct labcomm_encoder *encoder,
 		    char *version)
 {
@@ -32,16 +56,17 @@ static int fd_alloc(struct labcomm_writer *w, void *context,
     w->pos = 0;
     if (version && version[0]) {
       labcomm_write_string(w, version);
-      fd_flush(w, context);
+      fd_flush(w, action_context);
     }
   }
 
   return w->error;
 }
 
-static int fd_free(struct labcomm_writer *w, void *context)
+static int fd_free(struct labcomm_writer *w, 
+		   struct labcomm_writer_action_context *action_context)
 {
-  struct labcomm_fd_writer *fd_context = context;
+  struct labcomm_fd_writer *fd_context = action_context->context;
 
   free(w->data);
   w->data = 0;
@@ -55,7 +80,8 @@ static int fd_free(struct labcomm_writer *w, void *context)
   return 0;
 }
 
-static int fd_start(struct labcomm_writer *w, void *context,
+static int fd_start(struct labcomm_writer *w, 
+		    struct labcomm_writer_action_context *action_context,
 		    struct labcomm_encoder *encoder,
 		    int index,
 		    struct labcomm_signature *signature,
@@ -66,9 +92,10 @@ static int fd_start(struct labcomm_writer *w, void *context,
   return w->error;
 }
 
-static int fd_flush(struct labcomm_writer *w, void *context)
+static int fd_flush(struct labcomm_writer *w, 
+		    struct labcomm_writer_action_context *action_context)
 {
-  struct labcomm_fd_writer *fd_context = context;
+  struct labcomm_fd_writer *fd_context = action_context->context;
   int start, err;
   
   start = 0;
@@ -90,7 +117,8 @@ static int fd_flush(struct labcomm_writer *w, void *context)
   return w->error;
 }
 
-static int fd_ioctl(struct labcomm_writer *w, void *context, 
+static int fd_ioctl(struct labcomm_writer *w, 
+		    struct labcomm_writer_action_context *action_context, 
 		    int signature_index, struct labcomm_signature *signature, 
 		    uint32_t action, va_list args)
 {
@@ -114,10 +142,12 @@ struct labcomm_writer *labcomm_fd_writer_new(int fd, int close_fd_on_free)
   if (result == NULL) {
     return NULL;
   } else {
+    result->writer.action_context = &result->action_context;
+    result->action_context.next = NULL;
+    result->action_context.action = &action;
+    result->action_context.context = result;
     result->fd = fd;
     result->close_fd_on_free = close_fd_on_free;
-    result->writer.context = result;
-    result->writer.action = &action;
     return &result->writer;
   }
 }
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index 0bd9781..3755cc4 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -1,3 +1,25 @@
+/*
+  labcomm_private.h -- semi private declarations for handling encoding and 
+                       decoding of labcomm samples.
+
+  Copyright 2006-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/>.
+*/
+
 #ifndef _LABCOMM_PRIVATE_H_
 #define _LABCOMM_PRIVATE_H_
 
@@ -70,21 +92,34 @@ typedef void (*labcomm_decoder_function)(
   labcomm_handler_function handler,
   void *context);
 
+struct labcomm_reader_action_context;
+
 struct labcomm_reader_action {
-  int (*alloc)(struct labcomm_reader *r, void *context, 
+  int (*alloc)(struct labcomm_reader *r, 
+	       struct labcomm_reader_action_context *action_context, 
 	       struct labcomm_decoder *decoder, char *labcomm_version);
-  int (*free)(struct labcomm_reader *r, void *context);
-  int (*start)(struct labcomm_reader *r, void *context);
-  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 (*free)(struct labcomm_reader *r, 
+	      struct labcomm_reader_action_context *action_context);
+  int (*start)(struct labcomm_reader *r, 
+	       struct labcomm_reader_action_context *action_context);
+  int (*end)(struct labcomm_reader *r, 
+	     struct labcomm_reader_action_context *action_context);
+  int (*fill)(struct labcomm_reader *r, 
+	      struct labcomm_reader_action_context *action_context);
+  int (*ioctl)(struct labcomm_reader *r, 
+	       struct labcomm_reader_action_context *action_context,
 	       int signature_index, struct labcomm_signature *signature, 
 	       uint32_t ioctl_action, va_list args);
 };
 
-struct labcomm_reader {
+struct labcomm_reader_action_context {
+  struct labcomm_reader_action_context *next;
   const struct labcomm_reader_action *action;
-  void *context;
+  void *context;  
+};
+
+struct labcomm_reader {
+  struct labcomm_reader_action_context *action_context;
   unsigned char *data;
   int data_size;
   int count;
@@ -92,7 +127,23 @@ struct labcomm_reader {
   int error;
 };
 
-
+int labcomm_reader_alloc(struct labcomm_reader *r, 
+			 struct labcomm_reader_action_context *action_context, 
+			 struct labcomm_decoder *decoder, 
+			 char *labcomm_version);
+int labcomm_reader_free(struct labcomm_reader *r, 
+			struct labcomm_reader_action_context *action_context);
+int labcomm_reader_start(struct labcomm_reader *r, 
+			 struct labcomm_reader_action_context *action_context);
+int labcomm_reader_end(struct labcomm_reader *r, 
+		       struct labcomm_reader_action_context *action_context);
+int labcomm_reader_fill(struct labcomm_reader *r, 
+			struct labcomm_reader_action_context *action_context);
+int labcomm_reader_ioctl(struct labcomm_reader *r, 
+			 struct labcomm_reader_action_context *action_context,
+			 int signature_index, 
+			 struct labcomm_signature *signature, 
+			 uint32_t ioctl_action, va_list args);
 
 /*
  * Non typesafe registration function to be called from
@@ -116,7 +167,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->action->fill(r, r->context);					\
+	labcomm_reader_fill(r, r->action_context);			\
       }									\
       ((unsigned char*)(&result))[i] = r->data[r->pos];			\
       r->pos++;								\
@@ -131,7 +182,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->action->fill(r, r->context);					\
+	labcomm_reader_fille(r, r->action_context);			\
       }									\
       ((unsigned char*)(&result))[i] = r->data[r->pos];			\
       r->pos++;								\
@@ -157,7 +208,7 @@ static inline unsigned int labcomm_read_packed32(struct labcomm_reader *r)
     unsigned char tmp;
 
     if (r->pos >= r->count) {	
-      r->action->fill(r, r->context);
+      labcomm_reader_fill(r, r->action_context);
       if (r->error != 0) {
 	goto out;
       }
@@ -182,7 +233,7 @@ static inline char *labcomm_read_string(struct labcomm_reader *r)
   result = malloc(length + 1);
   for (i = 0 ; i < length ; i++) {
     if (r->pos >= r->count) {	
-      r->action->fill(r, r->context);
+      labcomm_reader_fill(r, r->action_context);
     }
     result[i] = r->data[r->pos];
     r->pos++;
@@ -197,27 +248,37 @@ static inline char *labcomm_read_string(struct labcomm_reader *r)
 typedef int (*labcomm_encoder_function)(
   struct labcomm_writer *,
   void *value);
-
-struct labcomm_writer;
+struct labcomm_writer_action_context;
 
 struct labcomm_writer_action {
-  int (*alloc)(struct labcomm_writer *w, void *context, 
+  int (*alloc)(struct labcomm_writer *w, 
+	       struct labcomm_writer_action_context *action_context, 
 	       struct labcomm_encoder *encoder, char *labcomm_version);
-  int (*free)(struct labcomm_writer *w, void *context);
-  int (*start)(struct labcomm_writer *w, void *context,
+  int (*free)(struct labcomm_writer *w, 
+	      struct labcomm_writer_action_context *action_context);
+  int (*start)(struct labcomm_writer *w, 
+	       struct labcomm_writer_action_context *action_context,
 	       struct labcomm_encoder *encoder,
 	       int index, struct labcomm_signature *signature,
 	       void *value);
-  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 (*end)(struct labcomm_writer *w, 
+	     struct labcomm_writer_action_context *action_context);
+  int (*flush)(struct labcomm_writer *w, 
+	       struct labcomm_writer_action_context *action_context); 
+  int (*ioctl)(struct labcomm_writer *w, 
+	       struct labcomm_writer_action_context *action_context, 
 	       int signature_index, struct labcomm_signature *signature, 
 	       uint32_t ioctl_action, va_list args);
 };
 
-struct labcomm_writer {
+struct labcomm_writer_action_context {
+  struct labcomm_writer_action_context *next;
   const struct labcomm_writer_action *action;
-  void *context;
+  void *context;  
+};
+
+struct labcomm_writer {
+  struct labcomm_writer_action_context *action_context;
   unsigned char *data;
   int data_size;
   int count;
@@ -225,6 +286,27 @@ struct labcomm_writer {
   int error;
 };
 
+int labcomm_writer_alloc(struct labcomm_writer *w, 
+			 struct labcomm_writer_action_context *action_context, 
+			 struct labcomm_encoder *encoder, 
+			 char *labcomm_version);
+int labcomm_writer_free(struct labcomm_writer *w, 
+			struct labcomm_writer_action_context *action_context);
+int labcomm_writer_start(struct labcomm_writer *w, 
+			 struct labcomm_writer_action_context *action_context,
+			 struct labcomm_encoder *encoder,
+			 int index, struct labcomm_signature *signature,
+			 void *value);
+int labcomm_writer_end(struct labcomm_writer *w, 
+		       struct labcomm_writer_action_context *action_context);
+int labcomm_writer_flush(struct labcomm_writer *w, 
+			 struct labcomm_writer_action_context *action_context); 
+int labcomm_writer_ioctl(struct labcomm_writer *w, 
+			 struct labcomm_writer_action_context *action_context, 
+			 int signature_index, 
+			 struct labcomm_signature *signature, 
+			 uint32_t ioctl_action, va_list args);
+
 void labcomm_internal_encoder_register(
   struct labcomm_encoder *encoder, 
   struct labcomm_signature *signature, 
@@ -249,7 +331,7 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
     for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
       if (w->pos >= w->count) { /*buffer is full*/			\
         int err;							\
-	err = w->action->flush(w, w->context);				\
+	err = labcomm_writer_flush(w, w->action_context);		\
 	if (err != 0) { return err; }					\
       }									\
       w->data[w->pos] = ((unsigned char*)(&data))[i];			\
@@ -266,7 +348,7 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
     for (i = 0 ; i < sizeof(type) ; i++) {				\
       if (w->pos >= w->count) {						\
         int err;							\
-	err = w->action->flush(w, w->context);					\
+	err = labcomm_writer_flush(w, w->action_context);		\
 	if (err != 0) { return err; }					\
       }									\
       w->data[w->pos] = ((unsigned char*)(&data))[i];			\
@@ -297,7 +379,7 @@ static inline int labcomm_write_packed32(struct labcomm_writer *w,
   for (i = i - 1 ; i >= 0 ; i--) {
     if (w->pos >= w->count) {					
       int err;
-      err = w->action->flush(w, w->context);
+      err = labcomm_writer_flush(w, w->action_context);	
       if (err != 0) { return err; }
     }
     w->data[w->pos++] = tmp[i] | (i?0x80:0x00);
@@ -315,7 +397,7 @@ static inline int labcomm_write_string(struct labcomm_writer *w, char *s)
   for (i = 0 ; i < length ; i++) {
     if (w->pos >= w->count) {	
       int err;
-      err = w->action->flush(w, w->context);
+      err = labcomm_writer_flush(w, w->action_context);	
       if (err != 0) { return err; }
     }
     w->data[w->pos] = s[i];
diff --git a/lib/c/test/test_labcomm_basic_type_encoding.c b/lib/c/test/test_labcomm_basic_type_encoding.c
index 7a12c3f..9151b9b 100644
--- a/lib/c/test/test_labcomm_basic_type_encoding.c
+++ b/lib/c/test/test_labcomm_basic_type_encoding.c
@@ -1,3 +1,24 @@
+/*
+  test_labcomm_basic_type_encoding.c -- LabComm tests of basic encoding
+
+  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>
@@ -8,22 +29,20 @@ static int line;
 static unsigned char buffer[128];
 
 static struct labcomm_writer writer =  {
-  .context = NULL,
+  .action_context = NULL,
   .data = buffer,
   .data_size = sizeof(buffer),
   .count = sizeof(buffer),
   .pos = 0,
   .error = 0,
-  .action = NULL,
 };
 
 static struct labcomm_reader reader =  {
-  .context = NULL,
+  .action_context = NULL,
   .data = buffer,
   .data_size = sizeof(buffer),
   .count = 0,
   .pos = 0,
-  .action = NULL,
 };
 
 typedef uint32_t packed32;
diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c
index 6185ff5..773268e 100644
--- a/lib/c/test/test_labcomm_generated_encoding.c
+++ b/lib/c/test/test_labcomm_generated_encoding.c
@@ -1,3 +1,24 @@
+/*
+  test_labcomm_generated_encoding.c -- LabComm tests of generated encoding
+
+  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 <string.h>
 #include <errno.h>
@@ -11,9 +32,11 @@
 static unsigned char buffer[128];
 struct labcomm_writer *writer;
 
-static int buf_writer_alloc(struct labcomm_writer *w, void *context,
-			    struct labcomm_encoder *encoder,
-			    char *labcomm_version)
+static int buf_writer_alloc(
+  struct labcomm_writer *w, 
+  struct labcomm_writer_action_context *action_context,
+  struct labcomm_encoder *encoder,
+  char *labcomm_version)
 {
   writer = w; /* Hack */
   w->data_size = sizeof(buffer);
@@ -24,26 +47,34 @@ static int buf_writer_alloc(struct labcomm_writer *w, void *context,
   return 0;
 }
 
-static int buf_writer_free(struct labcomm_writer *w, void *context)
+static int buf_writer_free(
+  struct labcomm_writer *w, 
+  struct labcomm_writer_action_context *action_context)
 {
   return 0;
 }
 
-static int buf_writer_start(struct labcomm_writer *w, void *context,
-			    struct labcomm_encoder *encoder,
-			    int index,
-			    struct labcomm_signature *signature,
-			    void *value)
+static int buf_writer_start(
+  struct labcomm_writer *w,
+  struct labcomm_writer_action_context *action_context,
+  struct labcomm_encoder *encoder,
+  int index,
+  struct labcomm_signature *signature,
+  void *value)
 {
   return 0;
 }
 
-static int buf_writer_end(struct labcomm_writer *w, void *context)
+static int buf_writer_end(
+  struct labcomm_writer *w, 
+  struct labcomm_writer_action_context *action_context)
 {
   return 0;
 }
 
-static int buf_writer_flush(struct labcomm_writer *w, void *context)
+static int buf_writer_flush(
+  struct labcomm_writer *w, 
+  struct labcomm_writer_action_context *action_context)
 {
   fprintf(stderr, "Should not come here %s:%d\n", __FILE__, __LINE__);
   exit(1);
@@ -52,7 +83,8 @@ static int buf_writer_flush(struct labcomm_writer *w, void *context)
 }
 
 static int buf_writer_ioctl(
-  struct labcomm_writer *w, void *context,
+  struct labcomm_writer *w, 
+  struct labcomm_writer_action_context *action_context,
   int signature_index, struct labcomm_signature *signature,
   uint32_t action, va_list arg)
 {
@@ -111,14 +143,18 @@ const struct labcomm_writer_action writer_action = {
   .ioctl = buf_writer_ioctl
 };
 
+static struct labcomm_writer_action_context action_context = {
+  .next = NULL,
+  .action = &writer_action,
+  .context = NULL
+}; 
 static struct labcomm_writer buffer_writer = {
-  .context = NULL,
+  .action_context = &action_context,
   .data = buffer,
   .data_size = sizeof(buffer),
   .count = sizeof(buffer),
   .pos = 0,
   .error = 0,
-  .action = &writer_action,
 };
 
 void dump_encoder(struct labcomm_encoder *encoder)
-- 
GitLab