From fe7840b4073bc0703e22b868670dc8cecc6f4de1 Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Mon, 26 Aug 2013 21:10:06 +0200
Subject: [PATCH] Fixed sizeof function.

---
 compiler/C_CodeGen.jrag   | 15 ++++++---
 lib/c/labcomm.h           |  2 ++
 lib/c/labcomm_private.h   | 13 ++++++++
 lib/c/test/test_labcomm.c | 68 ++++++++++++++++++++++++++++++---------
 lib/c/test/test_sample.lc |  2 +-
 5 files changed, 79 insertions(+), 21 deletions(-)

diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag
index 240ee7f..008bf70 100644
--- a/compiler/C_CodeGen.jrag
+++ b/compiler/C_CodeGen.jrag
@@ -963,7 +963,7 @@ aspect C_Sizeof {
 
   public void SampleDecl.C_emitSizeofDeclaration(C_env env) {
     env.println("extern int labcomm_sizeof_" + env.prefix + getName() +
-		"(struct labcomm_signature *sig, " + env.prefix + getName() + " *v);");
+		"(" + env.prefix + getName() + " *v);");
   }
 
   public int Decl.C_fixedSizeof() {
@@ -1024,16 +1024,17 @@ aspect C_Sizeof {
   public void SampleDecl.C_emitSizeof(C_env env) {
     env = env.nestStruct("(*v)");
     env.println("int labcomm_sizeof_" + env.prefix + getName() +
-		"(struct labcomm_signature *sig, " + env.prefix + getName() + " *v)");
+		"(" + env.prefix + getName() + " *v)");
     env.println("{");
     env.indent();
+    env.println("int result = labcomm_size_packed32(labcomm_signature_" + 
+                env.prefix + getName() +".index);");
     if (C_isDynamic()) {
-      env.println("int result = 0;");
       getType().C_emitSizeof(env);
-      env.println("return result;");
     } else {
-      env.println("return " + (0 + C_fixedSizeof()) + ";");
+      env.println("result += " + C_fixedSizeof() + ";");
     }    
+    env.println("return result;");
     env.unindent();
     env.println("}");
   }
@@ -1099,6 +1100,10 @@ aspect C_Sizeof {
       env.unindent();
       env.println("}");
     } else {
+      for (int i = 0 ; i < getNumExp() ; i++) {
+      	env.println("result += labcomm_size_packed32(" + 
+	            getExp(i).C_getLimit(env, i) + ");");
+      }
       env.print("result += " + getType().C_fixedSizeof());
       for (int i = 0 ; i < getNumExp() ; i++) {
 	env.print(" * " + getExp(i).C_getLimit(env, i));
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
index 35977e2..b83cdf8 100644
--- a/lib/c/labcomm.h
+++ b/lib/c/labcomm.h
@@ -43,7 +43,9 @@ struct labcomm_signature {
   int size;
   unsigned char *signature; 
   int index;
+#ifdef LABCOMM_EXPERIMENTAL_CACHED_ENCODED_SIZE
   int cached_encoded_size; // -1 if not initialized or type is variable size
+#endif
 };
 
 /*
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index 455e88d..ab4e315 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -455,6 +455,19 @@ static inline int labcomm_write_string(struct labcomm_writer *w, char *s)
   return 0;
 }
 
+/* Size of packed32 variable */
+static inline int labcomm_size_packed32(unsigned int data)
+{
+  int result = 0;
+  int i;
+
+  for (i = 0 ; i == 0 || data ; i++, data = (data >> 7)) {
+    result++;
+  }
+  return result;
+
+}
+
 /*
  * Macros for handling arrays indexed by signature index
  */
diff --git a/lib/c/test/test_labcomm.c b/lib/c/test/test_labcomm.c
index dbb3c21..b14f814 100644
--- a/lib/c/test/test_labcomm.c
+++ b/lib/c/test/test_labcomm.c
@@ -102,11 +102,22 @@ static struct labcomm_reader reader =  {
   .error = 0,
 };
 
-test_sample_test_var encoder_var, decoder_var;
+static int32_t encoder_data[256];
+static test_sample_test_var encoder_var = {
+  .n_0 = 1,
+  .n_1 = 1,
+  .a = encoder_data,
+};
+static int32_t decoder_data[256];
+static test_sample_test_var decoder_var = {
+  .n_0 = 1,
+  .n_1 = 1,
+  .a = decoder_data,
+};;
 
 void handle_test_var(test_sample_test_var *v, void *ctx)
 {
-  decoder_var = *v;  
+  decoder_var.a[0] = v->a[0];  
 }
 
 int test_decode_one(struct labcomm_decoder *decoder)
@@ -135,9 +146,37 @@ int test_decode_one(struct labcomm_decoder *decoder)
   return result;
 }
 
-int main(void)
+static void test_encode_decode(struct labcomm_encoder *encoder,
+			       struct labcomm_decoder *decoder,
+			       int expected, uint32_t n_0, uint32_t n_1)
 {
   int err;
+
+  writer.pos = 0;
+  encoder_var.n_0 = n_0;
+  encoder_var.n_1 = n_1;
+  encoder_var.a[0] = 314;
+  labcomm_encode_test_sample_test_var(encoder, &encoder_var);
+  err = test_decode_one(decoder);
+  fprintf(stderr, "decode of sample %u * %u -> size=%d err=%d\n", 
+	  n_0, n_1, writer.pos, err);
+  if (writer.pos != labcomm_sizeof_test_sample_test_var(&encoder_var)) {
+    fprintf(stderr, "Incorrect sizeof %u * %u (%d != %d)\n",
+	    n_0, n_1, 
+	    writer.pos, labcomm_sizeof_test_sample_test_var(&encoder_var));
+    exit(1);
+  }
+  if (writer.pos != expected) {
+    fprintf(stderr, "Unexpected size %u * %u (%d != %d)\n",
+	    n_0, n_1, 
+	    writer.pos, expected);
+    exit(1);
+  }
+}
+
+int main(void)
+{
+  int err, i;
   struct labcomm_encoder *encoder = labcomm_encoder_new(
     &writer, 
     labcomm_default_error_handler,
@@ -153,21 +192,20 @@ int main(void)
 						NULL);
   labcomm_encoder_register_test_sample_test_var(encoder);
   err = test_decode_one(decoder);
-  fprintf(stderr, "decode of register %d\n", err);
-  writer.pos = 0;
-  encoder_var = 314;
-  labcomm_encode_test_sample_test_var(encoder, &encoder_var);
-  err = test_decode_one(decoder);
-  fprintf(stderr, "decode of sample %d -> %d\n", err, decoder_var);
-  if (decoder_var != encoder_var) {
+  fprintf(stderr, "decode of register -> index %d\n", err);
+  test_encode_decode(encoder, decoder, 7, 1, 1);
+  if (decoder_var.a[0] != encoder_var.a[0]) {
     fprintf(stderr, "Failed to decode correct value %d != %d\n", 
-	    encoder_var, decoder_var);
+	    encoder_var.a[0], decoder_var.a[0]);
     exit(1);
   }
-  fprintf(stderr, "Size: %d %d\n", 
-	  labcomm_sizeof_test_sample_test_var(NULL, NULL),
-	  writer.pos);
-//  exit(1);
+  test_encode_decode(encoder, decoder, 19, 2, 2);
+  test_encode_decode(encoder, decoder, 3, 0, 0);
+  for (i = 1 ; i <= 4 ; i++) {
+    test_encode_decode(encoder, decoder, 2+i, 0, (1<<(7*i))-1);
+    test_encode_decode(encoder, decoder, 3+i, 0, (1<<(7*i)));
+  }
+  test_encode_decode(encoder, decoder, 7, 0, 4294967295);
   return 0;
 }
 
diff --git a/lib/c/test/test_sample.lc b/lib/c/test/test_sample.lc
index bf686a7..bac6bb6 100644
--- a/lib/c/test/test_sample.lc
+++ b/lib/c/test/test_sample.lc
@@ -1 +1 @@
-sample int test_var;
+sample int test_var[_,_];
-- 
GitLab