Skip to content
GitLab
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
274eddf0
Commit
274eddf0
authored
Apr 29, 2013
by
Anders Blomdell
Browse files
First stab at propagating writer errors to caller.
parent
45c7b977
Changes
5
Hide whitespace changes
Inline
Side-by-side
compiler/C_CodeGen.jrag
View file @
274eddf0
...
...
@@ -351,7 +351,7 @@ aspect C_Declarations {
env.println("struct labcomm_encoder *e);");
env.unindent();
env.println("
void
labcomm_encode_" + env.prefix + getName() + "(");
env.println("
int
labcomm_encode_" + env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_encoder *e,");
env.println(env.prefix + getName() + " *v");
...
...
@@ -633,7 +633,7 @@ aspect C_Encoder {
public void SampleDecl.C_emitEncoder(C_env env) {
env = env.nestStruct("(*v)");
env.println("static
void
encode_" + getName() + "(");
env.println("static
int
encode_" + getName() + "(");
env.indent();
env.println("labcomm_encoder_t *e,");
env.println(env.prefix + getName() + " *v");
...
...
@@ -641,21 +641,23 @@ aspect C_Encoder {
env.println(")");
env.println("{");
env.indent();
env.println("int result;");
getType().C_emitEncoder(env);
env.println("return result;");
env.unindent();
env.println("}");
// Typesafe encode wrapper
env.println("
void
labcomm_encode_" + env.prefix + getName() + "(");
env.println("
int
labcomm_encode_" + env.prefix + getName() + "(");
env.println("labcomm_encoder_t *e,");
env.println(env.prefix + getName() + " *v");
env.unindent();
env.println(")");
env.println("{");
env.indent();
env.println("labcomm_internal_encode(e, &labcomm_signature_" +
env.println("
return
labcomm_internal_encode(e, &labcomm_signature_" +
env.prefix + getName() +
", (labcomm_encode
_typecast_t
)encode_" + getName() +
", (labcomm_encode
r_function
)encode_" + getName() +
", v);");
env.unindent();
env.println("}");
...
...
@@ -668,10 +670,13 @@ aspect C_Encoder {
}
public void VoidType.C_emitEncoder(C_env env) {
env.println("result = 0;");
}
public void PrimType.C_emitEncoder(C_env env) {
env.println("labcomm_encode_" + getName() + "(e, " + env.qualid + ");");
env.println("result = labcomm_encode_" + getName() +
"(e, " + env.qualid + ");");
env.println("if (result != 0) { return result; }");
}
public void UserType.C_emitEncoder(C_env env) {
...
...
@@ -748,7 +753,7 @@ aspect C_Encoder {
env.indent();
env.println("e,");
env.println("&labcomm_signature_" + env.prefix + getName() + ",");
env.println("(labcomm_encode
_typecast_t
)encode_" + getName());
env.println("(labcomm_encode
r_function
)encode_" + getName());
env.unindent();
env.println(");");
env.unindent();
...
...
lib/c/labcomm.c
View file @
274eddf0
...
...
@@ -42,7 +42,7 @@ typedef struct labcomm_sample_entry {
labcomm_signature_t
*
signature
;
labcomm_decoder_typecast_t
decoder
;
labcomm_handler_typecast_t
handler
;
labcomm_encode
_typecast_t
encode
;
labcomm_encode
r_function
encode
;
void
*
context
;
}
labcomm_sample_entry_t
;
...
...
@@ -224,32 +224,14 @@ static int get_encoder_index(
#endif
}
void
labcomm_encoder_start
(
struct
labcomm_encoder
*
e
,
labcomm_signature_t
*
s
)
{
int
index
=
get_encoder_index
(
e
,
s
);
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_start
,
index
);
}
void
labcomm_encoder_end
(
struct
labcomm_encoder
*
e
,
labcomm_signature_t
*
s
)
{
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_end
);
}
void
labcomm_encode_type_index
(
labcomm_encoder_t
*
e
,
labcomm_signature_t
*
s
)
{
int
index
=
get_encoder_index
(
e
,
s
);
labcomm_encode_packed32
(
e
,
index
);
}
void
labcomm_encode_signature
(
struct
labcomm_encoder
*
e
,
labcomm_signature_t
*
signature
)
{
int
i
;
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_start_signature
);
labcomm_encode_packed32
(
e
,
signature
->
type
);
labcomm_encode_type_index
(
e
,
signature
);
labcomm_encode_packed32
(
e
,
get_encoder_index
(
e
,
signature
));
labcomm_encode_string
(
e
,
signature
->
name
);
for
(
i
=
0
;
i
<
signature
->
size
;
i
++
)
{
if
(
e
->
writer
.
pos
>=
e
->
writer
.
count
)
{
...
...
@@ -264,7 +246,7 @@ void labcomm_encode_signature(struct labcomm_encoder *e,
#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
static
int
encoder_add_signature_by_search
(
struct
labcomm_encoder
*
e
,
labcomm_signature_t
*
signature
,
labcomm_encode
_typecast_t
encode
)
labcomm_encode
r_function
encode
)
{
int
result
;
labcomm_encoder_context_t
*
context
=
e
->
context
;
...
...
@@ -289,7 +271,7 @@ static int encoder_add_signature_by_search(struct labcomm_encoder *e,
#ifndef LABCOMM_ENCODER_LINEAR_SEARCH
static
int
encoder_add_signature_by_section
(
struct
labcomm_encoder
*
e
,
labcomm_signature_t
*
s
,
labcomm_encode
_typecast_t
encode
)
labcomm_encode
r_function
encode
)
{
int
result
=
-
ENOENT
;
...
...
@@ -319,7 +301,7 @@ out:
static
int
encoder_add_signature
(
struct
labcomm_encoder
*
e
,
labcomm_signature_t
*
signature
,
labcomm_encode
_typecast_t
encode
)
labcomm_encode
r_function
encode
)
{
int
index
=
-
ENOENT
;
...
...
@@ -333,7 +315,7 @@ static int encoder_add_signature(struct labcomm_encoder *e,
static
void
do_encoder_register
(
struct
labcomm_encoder
*
e
,
labcomm_signature_t
*
signature
,
labcomm_encode
_typecast_t
encode
)
labcomm_encode
r_function
encode
)
{
if
(
signature
->
type
==
LABCOMM_SAMPLE
)
{
if
(
get_encoder_index
(
e
,
signature
)
==
0
)
{
...
...
@@ -355,6 +337,7 @@ static void do_encoder_register(struct labcomm_encoder *e,
}
}
/*
static labcomm_sample_entry_t *encoder_get_sample_by_signature_address(
labcomm_encoder_t *encoder,
labcomm_signature_t *s)
...
...
@@ -371,32 +354,30 @@ static labcomm_sample_entry_t *encoder_get_sample_by_signature_address(
#endif
return result;
}
*/
static
void
do_encode
(
labcomm_encoder_t
*
e
ncoder
,
static
int
do_encode
(
labcomm_encoder_t
*
e
,
labcomm_signature_t
*
signature
,
labcomm_encode
_typecast_t
encode
,
labcomm_encode
r_function
encode
,
void
*
value
)
{
labcomm_sample_entry_t
*
sample
;
sample
=
encoder_get_sample_by_signature_address
(
encoder
,
signature
);
(
void
)
sample
;
labcomm_encoder_start
(
encoder
,
signature
);
labcomm_encode_type_index
(
encoder
,
signature
);
encode
(
encoder
,
value
);
labcomm_encoder_end
(
encoder
,
signature
);
/*
labcomm_sample_entry_t *sample;
int
result
;
labcomm_writer_start_t
lws
;
sample = encoder_get_sample_by_signature_address(encoder, signature);
if (sample && sample->encode) {
sample->encode(encoder, value);
} else {
encoder->on_error(LABCOMM_ERROR_ENC_NO_REG_SIGNATURE, 2, "No registration for %s.\n", signature->name);
}
*/
lws
.
encoder
=
e
;
lws
.
index
=
get_encoder_index
(
e
,
signature
);
lws
.
signature
=
signature
;
lws
.
value
=
value
;
result
=
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_start
,
&
lws
);
if
(
result
==
-
EALREADY
)
{
result
=
0
;
goto
out
;
}
if
(
result
!=
0
)
{
goto
out
;
}
result
=
labcomm_encode_packed32
(
e
,
lws
.
index
);
if
(
result
!=
0
)
{
goto
out
;
}
result
=
encode
(
e
,
value
);
out:
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_end
,
&
lws
);
return
result
;
}
labcomm_encoder_t
*
labcomm_encoder_new
(
...
...
@@ -435,7 +416,7 @@ labcomm_encoder_t *labcomm_encoder_new(
void
labcomm_internal_encoder_register
(
labcomm_encoder_t
*
e
,
labcomm_signature_t
*
signature
,
labcomm_encode
_typecast_t
encode
)
labcomm_encode
r_function
encode
)
{
// Will segfault if e == NULL.
if
(
e
->
do_register
)
{
...
...
@@ -445,17 +426,18 @@ void labcomm_internal_encoder_register(
}
}
void
labcomm_internal_encode
(
int
labcomm_internal_encode
(
labcomm_encoder_t
*
e
,
labcomm_signature_t
*
signature
,
labcomm_encode
_typecast_t
encode
,
labcomm_encode
r_function
encode
,
void
*
value
)
{
if
(
e
->
do_encode
)
{
e
->
do_encode
(
e
,
signature
,
encode
,
value
);
return
e
->
do_encode
(
e
,
signature
,
encode
,
value
);
}
else
{
e
->
on_error
(
LABCOMM_ERROR_ENC_MISSING_DO_ENCODE
,
0
);
}
return
0
;
}
void
labcomm_encoder_free
(
labcomm_encoder_t
*
e
)
...
...
lib/c/labcomm.h
View file @
274eddf0
...
...
@@ -11,7 +11,7 @@ struct labcomm_decoder;
/*
* Signature entry
*/
typedef
struct
labcomm_signature
{
typedef
struct
labcomm_signature
{
int
type
;
char
*
name
;
int
(
*
encoded_size
)(
struct
labcomm_signature
*
,
void
*
);
// void * == encoded_sample *
...
...
@@ -115,12 +115,20 @@ void labcomm_decoder_free(
/*
* Encoder
*/
typedef
struct
{
struct
labcomm_encoder
*
encoder
;
int
index
;
labcomm_signature_t
*
signature
;
void
*
value
;
}
labcomm_writer_start_t
;
typedef
enum
{
labcomm_writer_alloc
,
/* (..., char *labcomm_version)
Allocate all neccessary data */
labcomm_writer_free
,
/* Free all allocated data */
labcomm_writer_start
,
/* Start writing an ordinary sample */
labcomm_writer_start
,
/* (..., labcomm_writer_start_t *s)
-EALREADY skips further encoding
Start writing an ordinary sample */
labcomm_writer_continue
,
/* Buffer full during ordinary sample */
labcomm_writer_end
,
/* End writing ordinary sample */
labcomm_writer_start_signature
,
/* Start writing signature */
...
...
lib/c/labcomm_private.h
View file @
274eddf0
...
...
@@ -203,7 +203,7 @@ static inline char *labcomm_decode_string(labcomm_decoder_t *d)
/*
* Semi private encoder declarations
*/
typedef
void
(
*
labcomm_encode
_typecast_t
)(
typedef
int
(
*
labcomm_encode
r_function
)(
struct
labcomm_encoder
*
,
void
*
value
);
...
...
@@ -212,10 +212,10 @@ typedef struct labcomm_encoder {
labcomm_writer_t
writer
;
void
(
*
do_register
)(
struct
labcomm_encoder
*
encoder
,
labcomm_signature_t
*
signature
,
labcomm_encode
_typecast_t
);
void
(
*
do_encode
)(
struct
labcomm_encoder
*
encoder
,
labcomm_encode
r_function
encode
);
int
(
*
do_encode
)(
struct
labcomm_encoder
*
encoder
,
labcomm_signature_t
*
signature
,
labcomm_encode
_typecast_t
encode
,
labcomm_encode
r_function
encode
,
void
*
value
);
labcomm_error_handler_callback
on_error
;
}
labcomm_encoder_t
;
...
...
@@ -223,46 +223,52 @@ typedef struct labcomm_encoder {
void
labcomm_internal_encoder_register
(
labcomm_encoder_t
*
encoder
,
labcomm_signature_t
*
signature
,
labcomm_encode
_typecast_t
encode
);
labcomm_encode
r_function
encode
);
void
labcomm_internal_encode
(
int
labcomm_internal_encode
(
labcomm_encoder_t
*
encoder
,
labcomm_signature_t
*
signature
,
labcomm_encode
_typecast_t
encode
,
labcomm_encode
r_function
encode
,
void
*
value
);
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define LABCOMM_ENCODE(name, type) \
static inline
void
labcomm_write_##name(labcomm_writer_t *w, type data) { \
static inline
int
labcomm_write_##name(labcomm_writer_t *w, type data) { \
int i; \
for (i = sizeof(type) - 1 ; i >= 0 ; i--) { \
if (w->pos >= w->count) {
/*buffer is full*/
\
w->write(w, labcomm_writer_continue); \
int err; \
err = w->write(w, labcomm_writer_continue); \
if (err != 0) { return err; } \
} \
w->data[w->pos] = ((unsigned char*)(&data))[i]; \
w->pos++; \
} \
return 0; \
} \
static inline
void
labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
labcomm_write_##name(&e->writer, data); \
static inline
int
labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
return
labcomm_write_##name(&e->writer, data); \
}
#else
#define LABCOMM_ENCODE(name, type) \
static inline
void
labcomm_write_##name(labcomm_writer_t *w, type data) { \
static inline
int
labcomm_write_##name(labcomm_writer_t *w, type data) { \
int i; \
for (i = 0 ; i < sizeof(type) ; i++) { \
if (w->pos >= w->count) { \
w->write(w, labcomm_writer_continue); \
int err; \
err = w->write(w, labcomm_writer_continue); \
if (err != 0) { return err; } \
} \
w->data[w->pos] = ((unsigned char*)(&data))[i]; \
w->pos++; \
} \
return 0; \
} \
static inline
void
labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
labcomm_write_##name(&e->writer, data); \
static inline
int
labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
return
labcomm_write_##name(&e->writer, data); \
}
#endif
...
...
@@ -287,7 +293,8 @@ LABCOMM_ENCODE(double, double)
* 0b1110 - 4 bytes (0x00200000 - 0x0fffffff)
* 0b11110 - 5 bytes (0x10000000 - 0xffffffff) [4 bits unused]
*/
static
inline
void
labcomm_pack32
(
labcomm_writer_t
*
w
,
unsigned
int
data
)
static
inline
int
labcomm_write_packed32
(
labcomm_writer_t
*
w
,
unsigned
int
data
)
{
int
n
;
unsigned
char
tag
;
...
...
@@ -311,68 +318,86 @@ static inline void labcomm_pack32(labcomm_writer_t *w, unsigned int data)
n
=
5
;
tag
=
0xf0
;
}
if
(
w
->
pos
+
n
-
1
>=
w
->
count
)
{
/* TODO: maybe?
if (w->pos + n - 1 >= w->count) {
w->write(w, labcomm_writer_continue, n);
}
}
*/
switch
(
n
)
{
case
5
:
{
if
(
w
->
pos
>=
w
->
count
)
{
w
->
write
(
w
,
labcomm_writer_continue
);
if
(
w
->
pos
>=
w
->
count
)
{
int
err
;
err
=
w
->
write
(
w
,
labcomm_writer_continue
);
if
(
err
!=
0
)
{
return
err
;
}
}
w
->
data
[
w
->
pos
++
]
=
tag
;
tag
=
0
;
}
case
4
:
{
if
(
w
->
pos
>=
w
->
count
)
{
w
->
write
(
w
,
labcomm_writer_continue
);
int
err
;
err
=
w
->
write
(
w
,
labcomm_writer_continue
);
if
(
err
!=
0
)
{
return
err
;
}
}
w
->
data
[
w
->
pos
++
]
=
tmp
[
0
]
|
tag
;
tag
=
0
;
}
case
3
:
{
if
(
w
->
pos
>=
w
->
count
)
{
w
->
write
(
w
,
labcomm_writer_continue
);
int
err
;
err
=
w
->
write
(
w
,
labcomm_writer_continue
);
if
(
err
!=
0
)
{
return
err
;
}
}
w
->
data
[
w
->
pos
++
]
=
tmp
[
1
]
|
tag
;
tag
=
0
;
}
case
2
:
{
if
(
w
->
pos
>=
w
->
count
)
{
w
->
write
(
w
,
labcomm_writer_continue
);
int
err
;
err
=
w
->
write
(
w
,
labcomm_writer_continue
);
if
(
err
!=
0
)
{
return
err
;
}
}
w
->
data
[
w
->
pos
++
]
=
tmp
[
2
]
|
tag
;
tag
=
0
;
}
case
1
:
{
if
(
w
->
pos
>=
w
->
count
)
{
w
->
write
(
w
,
labcomm_writer_continue
);
int
err
;
err
=
w
->
write
(
w
,
labcomm_writer_continue
);
if
(
err
!=
0
)
{
return
err
;
}
}
w
->
data
[
w
->
pos
++
]
=
tmp
[
3
]
|
tag
;
}
}
return
0
;
}
static
inline
void
labcomm_encode_packed32
(
labcomm_encoder_t
*
e
,
unsigned
int
data
)
static
inline
int
labcomm_encode_packed32
(
labcomm_encoder_t
*
e
,
unsigned
int
data
)
{
labcomm_pack32
(
&
e
->
writer
,
data
);
return
labcomm_
write_
pack
ed
32
(
&
e
->
writer
,
data
);
}
static
inline
void
labcomm_write_string
(
labcomm_writer_t
*
w
,
char
*
s
)
static
inline
int
labcomm_write_string
(
labcomm_writer_t
*
w
,
char
*
s
)
{
int
length
,
i
;
int
length
,
i
,
err
;
length
=
strlen
((
char
*
)
s
);
labcomm_pack32
(
w
,
length
);
err
=
labcomm_write_packed32
(
w
,
length
);
if
(
err
!=
0
)
{
return
err
;
}
for
(
i
=
0
;
i
<
length
;
i
++
)
{
if
(
w
->
pos
>=
w
->
count
)
{
w
->
write
(
w
,
labcomm_writer_continue
);
int
err
;
err
=
w
->
write
(
w
,
labcomm_writer_continue
);
if
(
err
!=
0
)
{
return
err
;
}
}
w
->
data
[
w
->
pos
]
=
s
[
i
];
w
->
pos
++
;
}
return
0
;
}
static
inline
void
labcomm_encode_string
(
labcomm_encoder_t
*
e
,
static
inline
int
labcomm_encode_string
(
labcomm_encoder_t
*
e
,
char
*
s
)
{
labcomm_write_string
(
&
e
->
writer
,
s
);
return
labcomm_write_string
(
&
e
->
writer
,
s
);
}
#endif
lib/c/test/test_labcomm_generated_encoding.c
View file @
274eddf0
...
...
@@ -115,6 +115,15 @@ void dump_encoder(labcomm_encoder_t *encoder)
printf
(
"
\n
"
);
}
#define EXPECT(...) \
{ \
int expected[] = __VA_ARGS__; \
labcomm_encoder_ioctl(encoder, IOCTL_WRITER_ASSERT_BYTES, \
__LINE__, \
sizeof(expected)/sizeof(expected[0]), \
expected); \
}
int
main
(
void
)
{
generated_encoding_V
V
;
...
...
@@ -124,39 +133,19 @@ int main(void)
labcomm_encoder_ioctl
(
encoder
,
IOCTL_WRITER_RESET
);
labcomm_encoder_register_generated_encoding_V
(
encoder
);
{
int
expected
[]
=
{
0x02
,
-
1
,
0x01
,
'V'
,
0x11
,
0x00
};
labcomm_encoder_ioctl
(
encoder
,
IOCTL_WRITER_ASSERT_BYTES
,
__LINE__
,
6
,
expected
);
}
EXPECT
({
0x02
,
-
1
,
0x01
,
'V'
,
0x11
,
0x00
});
labcomm_encoder_ioctl
(
encoder
,
IOCTL_WRITER_RESET
);
labcomm_encoder_register_generated_encoding_B
(
encoder
);
{
int
expected
[]
=
{
0x02
,
-
1
,
0x01
,
'B'
,
0x21
};
labcomm_encoder_ioctl
(
encoder
,
IOCTL_WRITER_ASSERT_BYTES
,
__LINE__
,
5
,
expected
);
}
EXPECT
({
0x02
,
-
1
,
0x01
,
'B'
,
0x21
});
labcomm_encoder_ioctl
(
encoder
,
IOCTL_WRITER_RESET
);
labcomm_encode_generated_encoding_V
(
encoder
,
&
V
);
{
int
expected
[]
=
{
-
1
};
labcomm_encoder_ioctl
(
encoder
,
IOCTL_WRITER_ASSERT_BYTES
,
__LINE__
,
1
,
expected
);
}
EXPECT
({
-
1
});
labcomm_encoder_ioctl
(
encoder
,
IOCTL_WRITER_RESET
);
labcomm_encode_generated_encoding_B
(
encoder
,
&
B
);
{
int
expected
[]
=
{
-
1
,
1
};
labcomm_encoder_ioctl
(
encoder
,
IOCTL_WRITER_ASSERT_BYTES
,
__LINE__
,
2
,
expected
);
}
EXPECT
({
-
1
,
1
});
return
0
;
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment