Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sven Gestegård Robertz
LabComm
Commits
7ee6a039
Commit
7ee6a039
authored
Apr 22, 2014
by
Tommy Olofsson
Browse files
Merge branch 'vx_c_copy' into vx
parents
05f371e2
695926ba
Changes
8
Hide whitespace changes
Inline
Side-by-side
compiler/C_CodeGen.jrag
View file @
7ee6a039
...
...
@@ -40,9 +40,12 @@ aspect C_CodeGenEnv {
private int indent;
public final int depth;
private C_printer printer;
public final int nestedLevel;
private boolean rootIsPointer;
private int rootLevel;
private C_env(String qualid, String lcName, String rawPrefix,
int indent, int depth, C_printer printer) {
int indent, int depth, C_printer printer
, int nestedLevel
) {
this.qualid = qualid;
this.lcName = lcName;
this.rawPrefix = rawPrefix;
...
...
@@ -54,6 +57,7 @@ aspect C_CodeGenEnv {
this.indent = indent;
this.depth = depth;
this.printer = printer;
this.nestedLevel = nestedLevel;
}
public C_env(String qualid, String lcName, String rawPrefix,
...
...
@@ -69,16 +73,22 @@ aspect C_CodeGenEnv {
this.depth = 0;
this.indent = 0;
this.printer = new C_printer(out);
this.nestedLevel = 0;
}
public C_env(String qualid, String lcName, String rawPrefix,
int indent, int depth, C_printer printer) {
this(qualid, lcName, rawPrefix, indent, depth, printer, 0);
}
public C_env nestArray(String suffix) {
return new C_env(qualid + suffix, lcName, rawPrefix,
indent, depth + 1, printer);
indent, depth + 1, printer
, nestedLevel + 1
);
}
public C_env nestStruct(String suffix) {
return new C_env(qualid + suffix, lcName, rawPrefix,
indent, depth, printer);
indent, depth, printer
, nestedLevel + 1
);
}
public void indent() {
...
...
@@ -101,6 +111,19 @@ aspect C_CodeGenEnv {
printer.println(this, s);
}
public C_env setPointer() {
rootIsPointer = true;
rootLevel = nestedLevel;
return this;
}
public String memberAccessor() {
return (rootIsPointer && (nestedLevel == rootLevel)) ? "->" : ".";
}
public String accessor() {
return (rootIsPointer && (nestedLevel == rootLevel)) ? "*" : "";
}
}
public C_env ArrayType.C_Nest(C_env env) {
...
...
@@ -110,7 +133,7 @@ aspect C_CodeGenEnv {
}
public C_env FixedArrayType.C_Nest(C_env env) {
String index = "
.
a";
String index =
env.memberAccessor() +
"a";
for (int i = 0 ; i < getNumExp() ; i++) {
index += "[i_" + env.depth + "_" + i + "]";
}
...
...
@@ -118,7 +141,7 @@ aspect C_CodeGenEnv {
}
public C_env VariableArrayType.C_Nest(C_env env) {
return env.nestArray("
.
a[i_" + env.depth + "]");
return env.nestArray(
env.memberAccessor() +
"a[i_" + env.depth + "]");
}
...
...
@@ -195,6 +218,8 @@ aspect C_CodeGen {
getDecl(i).C_emitDecoderDeclaration(env);
getDecl(i).C_emitEncoderDeclaration(env);
getDecl(i).C_emitSizeofDeclaration(env);
getDecl(i).C_emitCopyDeclaration(env);
getDecl(i).C_emitCopyDeallocationDeclaration(env);
env.println("");
}
C_emitConstructorDeclaration(env);
...
...
@@ -211,6 +236,8 @@ aspect C_CodeGen {
getDecl(i).C_emitEncoderRegisterHandler(env);
getDecl(i).C_emitEncoderIoctl(env);
getDecl(i).C_emitSizeof(env);
getDecl(i).C_emitCopy(env);
getDecl(i).C_emitCopyDeallocation(env);
}
C_emitConstructor(env);
}
...
...
@@ -405,7 +432,7 @@ aspect C_Limit {
}
public String VariableSize.C_getLimit(C_env env, int i) {
return env.qualid + "
.
n_" + i;
return env.qualid +
env.memberAccessor() +
"n_" + i;
}
}
...
...
@@ -653,6 +680,259 @@ aspect C_Decoder {
}
aspect C_copy {
private void SampleDecl.C_emitCopyFunctionParam(C_env env_src, String src,
String dst)
{
env_src.println("void labcomm_copy_" + env_src.prefix + getName() + "(");
env_src.indent();
env_src.println("struct labcomm_memory *mem,");
env_src.println(env_src.prefix + getName() + " *" + dst + ",");
env_src.println(env_src.prefix + getName() + " *" + src);
env_src.unindent();
env_src.print(")");
}
public void Decl.C_emitCopyDeclaration(C_env env) {
}
public void SampleDecl.C_emitCopyDeclaration(C_env env) {
C_emitCopyFunctionParam(env, "src", "dst");
env.println(";");
}
public void Decl.C_emitCopy(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitCopy(C_env env)" +
" not declared");
}
public void TypeDecl.C_emitCopy(C_env env) {
}
public void SampleDecl.C_emitCopy(C_env env) {
final String dst = "dst";
final String src = "src";
C_env env_src = env.nestStruct(src).setPointer();
C_env env_dst = env.nestStruct(dst).setPointer();
C_emitCopyFunctionParam(env_src, src, dst);
env_src.println("");
env_src.println("{");
env_src.indent();
getType().C_emitCopy(env_src, env_dst);
env_src.unindent();
env_src.println("}");
}
public void Type.C_emitCopy(C_env env_src, C_env env_dst) {
throw new Error(this.getClass().getName() +
".C_emitCopy(C_env env)" +
" not declared");
}
public void VoidType.C_emitCopy(C_env env_src, C_env env_dst) {
}
public void PrimType.C_emitCopy(C_env env_src, C_env env_dst) {
if (C_isDynamic()) {
env_src.println(String.format(
"%s%s = labcomm_memory_alloc(mem, 1, strlen(%s%s)+1);",
env_dst.accessor(), env_dst.qualid,
env_src.accessor(), env_src.qualid));
env_src.println(String.format(
"memcpy(%s%s, %s%s, strlen(%s%s)+1);",
env_dst.accessor(), env_dst.qualid,
env_src.accessor(), env_src.qualid,
env_src.accessor(), env_src.qualid));
} else {
env_src.println(env_dst.accessor() + env_dst.qualid + " = " +
env_src.accessor() + env_src.qualid + ";");
}
}
public void UserType.C_emitCopy(C_env env_src, C_env env_dst) {
lookupType(getName()).getType().C_emitCopy(env_src, env_dst);
}
public void StructType.C_emitCopy(C_env env_src, C_env env_dst) {
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).C_emitCopy(env_src, env_dst);
}
}
public void ArrayType.C_emitCopy(C_env env_src, C_env env_dst) {
C_emitCopyDecodeLimit(env_src, env_dst);
C_emitCopyArrayAllocate(env_src, env_dst);
env_src.println("{");
env_src.indent();
C_emitLoopVariables(env_src);
for (int i = 0 ; i < getNumExp() ; i++) {
String iterator = "i_" + env_src.depth + "_" + i;
env_src.println("for (" + iterator + " = 0" +
" ; " +
iterator + " < " + getExp(i).C_getLimit(env_src, i) +
" ; " +
iterator + "++) {");
env_src.indent();
}
C_emitCalcIndex(env_src);
getType().C_emitCopy(C_Nest(env_src), C_Nest(env_dst));
for (int i = getNumExp() - 1 ; i >= 0 ; i--) {
env_src.unindent();
env_src.println("}");
}
env_src.unindent();
env_src.println("}");
}
public void Field.C_emitCopy(C_env env_src, C_env env_dst) {
String fnam = env_src.memberAccessor() + getName();
getType().C_emitCopy(env_src.nestStruct(fnam), env_dst.nestStruct(fnam));
}
public void Exp.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst, int i) {
// Ordinary array has no length-member.
}
public void VariableSize.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst, int i) {
String src = env_src.qualid + env_src.memberAccessor() + "n_" + i;
String dst = env_dst.qualid + env_dst.memberAccessor() + "n_" + i;
env_src.println(dst + " = " + src + ";");
}
public void ArrayType.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst) {
for (int i = 0 ; i < getNumExp() ; i++) {
getExp(i).C_emitCopyDecodeLimit(env_src, env_dst, i);
}
}
public void ArrayType.C_emitCopyArrayAllocate(C_env env_src, C_env env_dst) {
}
public void VariableArrayType.C_emitCopyArrayAllocate(C_env env_src,
C_env env_dst)
{
env_src.print(env_dst.qualid + env_dst.memberAccessor() +
"a = labcomm_memory_alloc(mem, 1, sizeof(" +
env_src.qualid + env_src.memberAccessor() + "a[0])");
for (int i = 0 ; i < getNumExp() ; i++) {
env_src.print(" * " + getExp(i).C_getLimit(env_src, i));
}
env_dst.println(");");
}
// Code for deallocation of dynamically allocated data in a copy.
private void SampleDecl.C_emitCopyDeallocationFunctionParam(C_env env,
String par)
{
env.println("void labcomm_copy_free_" + env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_memory *mem,");
env.println(env.prefix + getName() + " *" + par);
env.unindent();
env.print(")");
}
public void Decl.C_emitCopyDeallocationDeclaration(C_env env) {
}
public void SampleDecl.C_emitCopyDeallocationDeclaration(C_env env) {
C_emitCopyDeallocationFunctionParam(env, "c");
env.println(";");
}
public void Decl.C_emitCopyDeallocation(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitCopy(C_env env)" +
" not declared");
}
public void TypeDecl.C_emitCopyDeallocation(C_env env) {
}
public void SampleDecl.C_emitCopyDeallocation(C_env env) {
String par = "par";
env = env.nestStruct(par).setPointer();
C_emitCopyDeallocationFunctionParam(env, par);
env.println("");
env.println("{");
env.indent();
getType().C_emitCopyDeallocation(env);
env.unindent();
env.println("}");
}
public void Type.C_emitCopyDeallocation(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitCopyDeallocation(C_env env)" +
" not declared");
}
public void VoidType.C_emitCopyDeallocation(C_env env) {
}
public void PrimType.C_emitCopyDeallocation(C_env env) {
if (C_isDynamic()) {
env.println("labcomm_memory_free(mem, 1, " +
env.accessor() + env.qualid + ");");
}
}
public void UserType.C_emitCopyDeallocation(C_env env) {
if (C_isDynamic()) {
lookupType(getName()).getType().C_emitCopyDeallocation(env);
}
}
public void StructType.C_emitCopyDeallocation(C_env env) {
if (C_isDynamic()) {
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).C_emitCopyDeallocation(env);
}
}
}
public void ArrayType.C_emitCopyDeallocation(C_env env) {
if (getType().C_isDynamic()) {
env.println("{");
env.indent();
C_emitLoopVariables(env);
for (int i = 0 ; i < getNumExp() ; i++) {
String iterator = "i_" + env.depth + "_" + i;
env.println("for (" + iterator + " = 0" +
" ; " +
iterator + " < " + getExp(i).C_getLimit(env, i) +
" ; " +
iterator + "++) {");
env.indent();
}
C_emitCalcIndex(env);
getType().C_emitCopyDeallocation(C_Nest(env));
for (int i = 0 ; i < getNumExp() ; i++) {
env.unindent();
env.println("}");
}
env.unindent();
env.println("}");
}
}
public void VariableArrayType.C_emitCopyDeallocation(C_env env) {
super.C_emitCopyDeallocation(env);
env.println("labcomm_memory_free(mem, 1, " +
env.qualid + env.memberAccessor() + "a);");
}
public void Field.C_emitCopyDeallocation(C_env env) {
getType().C_emitCopyDeallocation(env.nestStruct(env.memberAccessor()
+ getName()));
}
}
aspect C_DecoderIoctl {
public void Decl.C_emitDecoderIoctl(C_env env) {
...
...
examples/Makefile
View file @
7ee6a039
.PHONY
:
all
all
:
echo
To be
done
...
$(MAKE)
-C
twoway all
...
...
examples/simple/compile.sh
View file @
7ee6a039
...
...
@@ -5,10 +5,12 @@ java -jar ../../compiler/labComm.jar --java=gen --c=gen/simple.c --h=gen/simple.
javac
-cp
../../lib/java:. gen/
*
.java Encoder.java Decoder.java
gcc
-Wall
-Werror
-I
.
-I
../../lib/c
-L
../../lib/c
\
gcc
-Wall
-Werror
-Wno-unused-function
\
-I
.
-I
../../lib/c
-L
../../lib/c
\
-o
example_encoder example_encoder.c gen/simple.c
\
-llabcomm
-Tlabcomm
.linkscript
gcc
-Wall
-Werror
-I
.
-I
../../lib/c
-L
../../lib/c
\
gcc
-Wall
-Werror
-Wno-unused-function
\
-I
.
-I
../../lib/c
-L
../../lib/c
\
-o
example_decoder example_decoder.c gen/simple.c
\
-llabcomm
-Tlabcomm
.linkscript
...
...
examples/twoway/Makefile
View file @
7ee6a039
...
...
@@ -2,7 +2,7 @@ TARGETS=client server
LABCOMM_JAR
=
../../compiler/labComm.jar
LABCOMM
=
java
-jar
$(LABCOMM_JAR)
CFLAGS
=
-O3
-g
-Wall
-Werror
-I
../../lib/c
-I
.
CFLAGS
=
-O3
-g
-Wall
-Werror
-I
../../lib/c
-I
.
-Wno-unused-function
all
:
$(TARGETS:%=gen/%)
...
...
lib/c/Makefile
View file @
7ee6a039
...
...
@@ -18,6 +18,13 @@ else ifeq ($(UNAME_S),Darwin)
LDFLAGS
=
-L
.
LDLIBS
=
-llabcomm
MAKESHARED
=
clang
-o
$1
-shared
-Wl
,-install_name,
$2
$3
-lc
else
ifneq
($(findstring CYGWIN,$(UNAME_S)),)
CFLAGS
=
-std
=
c99
-g
-Wall
-Werror
-O3
-I
.
-Itest
CC
=
$(CROSS_COMPILE)
gcc
LD
=
$(CROSS_COMPILE)
ld
LDFLAGS
=
-L
.
LDLIBS
=
-llabcomm
-lrt
ALL_DEPS
:=
$(
filter-out
%.so.1,
$(ALL_DEPS)
)
# No -fPIC supported in windows?
else
$(error
Unknown
system
$(UNAME_S))
endif
...
...
@@ -49,6 +56,7 @@ TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding \
test_signature_numbers
\
test_labcomm
\
test_labcomm_pthread_scheduler
\
test_labcomm_copy
#
#FIXME: test_labcomm test_labcomm_errors
TEST_DIR
=
test
...
...
@@ -133,6 +141,7 @@ clean:
$(RM)
test
/testdata/gen/
*
.[cho]
$(RM)
test
/gen/
*
.[cho]
$(RM)
$(TEST_DIR)
/test_labcomm
$(RM)
$(TEST_DIR)
/test_labcomm_copy
distclean
:
clean
$(RM)
liblabcomm.so.1
...
...
@@ -150,6 +159,7 @@ $(TEST_DIR)/test_signature_numbers.c: $(TEST_DIR)/gen/another_encoding.h
$(TEST_DIR)/test_signature_numbers.c
:
$(TEST_DIR)/gen/generated_encoding.h
$(TEST_DIR)/test_signature_numbers
:
$(TEST_DIR)/gen/another_encoding.o
$(TEST_DIR)/test_signature_numbers
:
$(TEST_DIR)/gen/generated_encoding.o
$(TEST_DIR)/test_labcomm_copy
:
$(TEST_DIR)/gen/generated_encoding.o $(TEST_DIR)/gen/test_sample.o $(TEST_DIR)/gen/more_types.o
labcomm_fd_reader.o
:
labcomm_private.h
labcomm_fd_writer.o
:
labcomm_private.h
labcomm_dynamic_buffer_writer.o
:
labcomm_private.h
lib/c/test/more_types.lc
0 → 100644
View file @
7ee6a039
sample string S;
sample int A[8];
sample struct {
string s1;
string s2;
} NS;
sample string AS[_];
lib/c/test/test_labcomm_copy.c
0 → 100644
View file @
7ee6a039
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <err.h>
#include "labcomm.h"
#include "labcomm_private.h"
#include "labcomm_default_error_handler.h"
#include "labcomm_default_memory.h"
#include "labcomm_default_scheduler.h"
#include "labcomm_fd_writer.h"
#include "labcomm_fd_reader.h"
#include "test/gen/generated_encoding.h"
#include "test/gen/test_sample.h"
#include "test/gen/more_types.h"
#define DATA_FILE "copy_test.dat"
static
void
handle_s1
(
generated_encoding_S1
*
v
,
void
*
context
)
{
labcomm_copy_generated_encoding_S1
(
labcomm_default_memory
,
context
,
v
);
}
static
void
handle_b
(
generated_encoding_B
*
v
,
void
*
context
)
{
labcomm_copy_generated_encoding_B
(
labcomm_default_memory
,
context
,
v
);
}
static
void
handle_i
(
generated_encoding_I
*
v
,
void
*
context
)
{
labcomm_copy_generated_encoding_I
(
labcomm_default_memory
,
context
,
v
);
}
static
void
handle_p
(
generated_encoding_P
*
v
,
void
*
context
)
{
labcomm_copy_generated_encoding_P
(
labcomm_default_memory
,
context
,
v
);
}
static
void
handle_test_var
(
test_sample_test_var
*
v
,
void
*
context
)
{
labcomm_copy_test_sample_test_var
(
labcomm_default_memory
,
context
,
v
);
}
static
void
handle_a
(
more_types_A
*
v
,
void
*
context
)
{
labcomm_copy_more_types_A
(
labcomm_default_memory
,
context
,
v
);
}
static
void
handle_s
(
more_types_S
*
v
,
void
*
context
)
{
labcomm_copy_more_types_S
(
labcomm_default_memory
,
context
,
v
);
}
static
void
handle_ns
(
more_types_NS
*
v
,
void
*
context
)
{
labcomm_copy_more_types_NS
(
labcomm_default_memory
,
context
,
v
);
}
static
void
handle_as
(
more_types_AS
*
v
,
void
*
context
)
{
labcomm_copy_more_types_AS
(
labcomm_default_memory
,
context
,
v
);
}
int
main
(
int
argc
,
char
**
argv
)
{
struct
labcomm_encoder
*
encoder
;
struct
labcomm_decoder
*
decoder
;
int
fd
;
generated_encoding_S1
s1
;
generated_encoding_S1
cache_s1
;
generated_encoding_B
b
;
generated_encoding_B
cache_b
;
generated_encoding_I
I
;
generated_encoding_I
cache_I
;
generated_encoding_P
p
;
generated_encoding_P
cache_p
;
test_sample_test_var
test_var
;
test_sample_test_var
cache_test_var
;
more_types_A
a
;
more_types_A
cache_a
;
more_types_S
s
;
more_types_S
cache_s
=
NULL
;
more_types_NS
ns
;
more_types_NS
cache_ns
;
more_types_AS
as
;
more_types_AS
cache_as
;
fd
=
open
(
DATA_FILE
,
O_RDWR
|
O_CREAT
|
O_TRUNC
,
0644
);
if
(
fd
==
-
1
)
err
(
1
,
"open()"
);
encoder
=
labcomm_encoder_new
(
labcomm_fd_writer_new
(
labcomm_default_memory
,
fd
,
0
),
labcomm_default_error_handler
,
labcomm_default_memory
,
labcomm_default_scheduler
);
labcomm_encoder_register_generated_encoding_S1
(
encoder
);
s1
.
i
=
1
;
labcomm_encode_generated_encoding_S1
(
encoder
,
&
s1
);
labcomm_encoder_register_generated_encoding_B
(
encoder
);
b
=
2
;
labcomm_encode_generated_encoding_B
(
encoder
,
&
b
);
labcomm_encoder_register_generated_encoding_I
(
encoder
);
I
.
n_0
=
3
;
I
.
a
=
calloc
(
I
.
n_0
,
sizeof
(
I
.
a
[
0
]));
I
.
a
[
0
]
=
4
;
I
.
a
[
1
]
=
5
;
I
.
a
[
2
]
=
6
;
labcomm_encode_generated_encoding_I
(
encoder
,
&
I
);
labcomm_encoder_register_generated_encoding_P
(
encoder
);
p
.
n_0
=
7
;
p
.
a
=
calloc
(
p
.
n_0
,
sizeof
(
p
.
a
[
0
]));
for
(
int
i
=
0
;
i
<
p
.
n_0
;
i
++
)
p
.
a
[
i
].
i
=
8
+
i
;
labcomm_encode_generated_encoding_P
(
encoder
,
&
p
);
labcomm_encoder_register_test_sample_test_var
(
encoder
);
test_var
.
n_0
=
2
;
test_var
.
n_1
=
7
;
test_var
.
a
=
calloc
(
test_var
.
n_0
*
test_var
.
n_1
,
sizeof
(
*
test_var
.
a
));
for
(
int
i
=
0
;
i
<
test_var
.
n_0
;
i
++
)
for
(
int
j
=
0
;
j
<
test_var
.
n_1
;
j
++
)
test_var
.
a
[
i
]
=
10
*
i
+
j
;
labcomm_encode_test_sample_test_var
(
encoder
,
&
test_var
);
labcomm_encoder_register_more_types_A
(
encoder
);
for
(
int
i
=
0
;
i
<
sizeof
(
a
.
a
)
/
sizeof
(
a
.
a
[
0
]);
i
++
)
a
.
a
[
i
]
=
i
;
labcomm_encode_more_types_A
(
encoder
,
&
a
);
labcomm_encoder_register_more_types_S
(
encoder
);
s
=
"this is a string"
;
labcomm_encode_more_types_S
(
encoder
,
&
s
);
labcomm_encoder_register_more_types_NS
(
encoder
);
ns
.
s1
=
"this is a string"
;
ns
.
s2
=
"this is a another string"
;
labcomm_encode_more_types_NS
(
encoder
,
&
ns
);
labcomm_encoder_register_more_types_AS
(
encoder
);
as
.
n_0
=
3
;
as
.
a
=
calloc
(
as
.
n_0
,
sizeof
(
as
.
a
[
0
]));
as
.
a
[
0
]
=
"string 0"
;
as
.
a
[
1
]
=
"string 1"
;
as
.
a
[
2
]
=
"string 2"
;
labcomm_encode_more_types_AS
(
encoder
,
&
as
);
labcomm_encoder_free
(
encoder
);
encoder
=
NULL
;
lseek
(
fd
,
0
,
SEEK_SET
);
decoder
=
labcomm_decoder_new
(
labcomm_fd_reader_new
(
labcomm_default_memory
,
fd
,
0
),
labcomm_default_error_handler
,
labcomm_default_memory
,
labcomm_default_scheduler
);
labcomm_decoder_register_generated_encoding_S1
(
decoder
,
handle_s1
,
&
cache_s1
);
labcomm_decoder_register_generated_encoding_B
(
decoder
,
handle_b
,
&
cache_b
);
labcomm_decoder_register_generated_encoding_I
(
decoder
,
handle_i
,
&
cache_I
);
labcomm_decoder_register_generated_encoding_P
(
decoder
,
handle_p
,
&
cache_p
);
labcomm_decoder_register_test_sample_test_var
(
decoder
,
handle_test_var
,
&
cache_test_var
);
labcomm_decoder_register_more_types_A
(
decoder
,
handle_a
,
&
cache_a
);
labcomm_decoder_register_more_types_S
(
decoder
,
handle_s
,
&
cache_s
);
labcomm_decoder_register_more_types_NS
(
decoder
,
handle_ns
,
&
cache_ns
);
labcomm_decoder_register_more_types_AS
(
decoder
,
handle_as
,
&
cache_as
);
while
(
labcomm_decoder_decode_one
(
decoder
)
>
0
)
;
assert
(
cache_s1
.
i
==
s1
.
i
);
puts
(
"S1 copied ok"
);
assert
(
cache_b
==
b
);
puts
(
"B copied ok"
);
assert
(
cache_I
.
n_0
==
I
.
n_0
);
assert
(
cache_I
.
a
[
0
]
==
I
.
a
[
0
]);
assert
(
cache_I
.
a
[
1
]
==
I
.
a
[
1
]);
assert
(
cache_I
.
a
[
2
]
==
I
.
a
[
2
]);
free
(
I
.
a
);
puts
(
"I copied ok"
);
assert
(
cache_p
.
n_0
==
p
.
n_0
);
for
(
int
i
=
0
;
i
<
p
.
n_0
;
i
++
)
assert
(
cache_p
.
a
[
i
].
i
==
p
.
a
[
i
].
i
);
free
(
p
.
a
);
puts
(
"P copied ok"
);