Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • anders.blomdell
  • compiler-refactoring
  • labcomm2006
  • labcomm2013
  • labcomm2014
  • master
  • pragma
  • python_sig_hash
  • typedefs
  • typeref
  • v2006.0
  • v2013.0
  • v2014.0
  • v2014.1
  • v2014.2
  • v2014.3
  • v2014.4
  • v2014.5
  • v2014.6
  • v2015.0
20 results

Target

Select target project
  • anders_blomdell/labcomm
  • klaren/labcomm
  • tommyo/labcomm
  • erikj/labcomm
  • sven/labcomm
5 results
Select Git revision
  • anders.blomdell
  • compiler-refactoring
  • labcomm2006
  • labcomm2013
  • master
  • pragma
  • typedefs
  • typeref
  • v2006.0
  • v2013.0
  • v2014.0
  • v2014.1
  • v2014.2
  • v2014.3
  • v2014.4
15 results
Show changes
Showing
with 1539 additions and 826 deletions
/*
test_labcomm2014.c -- Various labcomm2014 tests
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>
#include <stdlib.h>
#include <errno.h>
#include "labcomm2014_private.h"
#include "labcomm2014_default_error_handler.h"
#include "labcomm2014_default_memory.h"
#include "labcomm2014_default_scheduler.h"
#include "test/gen/test_sample.h"
static struct labcomm2014_writer writer;
static struct expect {
char *description;
int result;
int (*trampoline)(struct labcomm2014_decoder *context);
struct labcomm2014_decoder *context;
} *expect;
static void check_expect()
{
struct expect *p = expect;
{
int i;
for (i = 0 ; i < writer.pos ; i++) {
fprintf(stderr, "%02x ", writer.data[i]);
}
fprintf(stderr, "\n");
}
if (p && p->trampoline) {
int err;
expect = p + 1;
fprintf(stderr, "Checking '%s' expected=%d ", p->description, p->result);
err = p->trampoline(p->context);
fprintf(stderr, "actual=%d\n", err);
if (p->result >= 0 && p->result != err) {
fprintf(stderr, "FAILED\n");
exit(1);
} else if (err == 0) {
fprintf(stderr, "FAILED (unexpected 0)\n");
exit(1);
}
writer.pos = 0;
}
}
static unsigned char buffer[512];
static int writer_alloc(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
w->data = buffer;
w->data_size = sizeof(buffer);
w->count = sizeof(buffer);
return 0;
}
static int writer_start(struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index, const struct labcomm2014_signature *signature,
void *value)
{
return 0;
}
static int buf_writer_end(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
check_expect();
return 0;
}
const struct labcomm2014_writer_action writer_action = {
.alloc = writer_alloc,
.start = writer_start,
.end = buf_writer_end,
};
static struct labcomm2014_writer_action_context writer_action_context = {
.next = NULL,
.action = &writer_action,
.context = NULL
};
static struct labcomm2014_writer writer = {
.action_context = &writer_action_context,
.data = buffer,
.data_size = sizeof(buffer),
.count = sizeof(buffer),
.pos = 0,
.error = 0,
};
static int reader_alloc(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context)
{
r->data = buffer;
r->data_size = sizeof(buffer);
r->count = 0;
r->memory = labcomm2014_default_memory;
return 0;
}
static int reader_fill(struct labcomm2014_reader *r,
struct labcomm2014_reader_action_context *action_context)
{
r->error = -ENOMEM;
return r->error;
}
const struct labcomm2014_reader_action reader_action = {
.alloc = reader_alloc,
.fill = reader_fill,
};
static struct labcomm2014_reader_action_context reader_action_context = {
.next = NULL,
.action = &reader_action,
.context = NULL
};
static struct labcomm2014_reader reader = {
.action_context = &reader_action_context,
.data = buffer,
.data_size = sizeof(buffer),
.count = 0,
.pos = 0,
.error = 0,
};
static int32_t encoder_data[256];
static test_sample_test_var encoder_var = {
.n_0 = 1,
.n_2 = 1,
.a = encoder_data,
};
static int32_t decoder_data[256];
static test_sample_test_var decoder_var = {
.n_0 = 1,
.n_2 = 1,
.a = decoder_data,
};;
void handle_test_var(test_sample_test_var *v, void *ctx)
{
if (v->n_0 * v->n_2 > 0) {
decoder_var.a[0] = v->a[0];
}
}
int test_decode_one(struct labcomm2014_decoder *decoder)
{
int result;
for (reader.count = 0 ; reader.count < writer.pos ; reader.count++) {
reader.error = 0;
reader.pos = 0;
result = labcomm2014_decoder_decode_one(decoder);
if (result >= 0 ) {
fprintf(stderr,
"Got result from buffer with bogus length (%d, %d != %d)\n",
result, reader.count, writer.pos);
exit(1);
}
}
reader.error = 0;
reader.pos = 0;
reader.count = writer.pos;
result = labcomm2014_decoder_decode_one(decoder);
if (result < 0) {
fprintf(stderr, "Got no result from buffer with correct length (%d)\n",
result);
exit(1);
}
return result;
}
static void test_encode_decode(struct labcomm2014_encoder *encoder,
struct labcomm2014_decoder *decoder,
int expected, uint32_t n_0, uint32_t n_2)
{
int err;
writer.pos = 0;
encoder_var.n_0 = n_0;
encoder_var.n_2 = n_2;
encoder_var.a[0] = 314;
labcomm2014_encode_test_sample_test_var(encoder, &encoder_var);
err = test_decode_one(decoder);
fprintf(stderr, "decode of sample %u * 2 * %u -> size=%d err=%d\n",
n_0, n_2, writer.pos, err);
if (writer.pos != labcomm2014_sizeof_test_sample_test_var(NULL, &encoder_var)) {
fprintf(stderr, "Incorrect sizeof %u * 2 * %u (%d != %d)\n",
n_0, n_2,
writer.pos, labcomm2014_sizeof_test_sample_test_var(NULL, &encoder_var));
exit(1);
}
if (writer.pos != expected) {
fprintf(stderr, "Unexpected size %u * 2 * %u (%d != %d)\n",
n_0, n_2,
writer.pos, expected);
exit(1);
}
}
static int do_test(int argc, char *argv[])
{
int i;
struct labcomm2014_decoder *decoder = labcomm2014_decoder_new(
&reader,
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
struct expect expect_version[] = {
{ "Version", 1, test_decode_one, decoder },
{ 0, 0, 0 }
};
expect = expect_version;
struct labcomm2014_encoder *encoder = labcomm2014_encoder_new(
&writer,
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
labcomm2014_decoder_register_test_sample_test_var(decoder,
handle_test_var,
NULL);
struct expect expect_registration[] = {
{ "Sampledef", -1, test_decode_one, decoder },
#ifdef SHOULD_THIS_BE_REMOVED
{ "Typedef", -1, test_decode_one, decoder },
#endif
{ "Binding", -1, test_decode_one, decoder },
{ 0, 0, 0 }
};
expect = expect_registration;
labcomm2014_encoder_register_test_sample_test_var(encoder);
test_encode_decode(encoder, decoder, 12, 1, 1);
if (decoder_var.a[0] != encoder_var.a[0]) {
fprintf(stderr, "Failed to decode correct value %d != %d\n",
encoder_var.a[0], decoder_var.a[0]);
exit(1);
}
test_encode_decode(encoder, decoder, 36, 2, 2);
test_encode_decode(encoder, decoder, 4, 0, 0);
for (i = 1 ; i <= 4 ; i++) {
test_encode_decode(encoder, decoder, 3+i, 0, (1<<(7*i))-1);
test_encode_decode(encoder, decoder, 4+i, 0, (1<<(7*i)));
}
test_encode_decode(encoder, decoder, 8, 0, 4294967295);
labcomm2014_encoder_free(encoder);
labcomm2014_decoder_free(decoder);
return 0;
}
int main(int argc, char *argv[])
{
return do_test(argc, argv);
}
/*
test_labcomm_basic_type_encoding.c -- LabComm tests of basic encoding
test_labcomm2014_basic_type_encoding.c -- LabComm tests of basic encoding
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -23,13 +23,13 @@
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include "labcomm_private.h"
#include "labcomm2014_private.h"
static int line;
static unsigned char buffer[128];
static struct labcomm_writer writer = {
static struct labcomm2014_writer writer = {
.action_context = NULL,
.data = buffer,
.data_size = sizeof(buffer),
......@@ -38,7 +38,7 @@ static struct labcomm_writer writer = {
.error = 0,
};
static struct labcomm_reader reader = {
static struct labcomm2014_reader reader = {
.action_context = NULL,
.data = buffer,
.data_size = sizeof(buffer),
......@@ -53,11 +53,11 @@ typedef uint32_t packed32;
type decoded; \
line = __LINE__; \
writer.pos = 0; \
labcomm_write_##ltype(&writer, value); \
labcomm2014_write_##ltype(&writer, value); \
writer_assert(#ltype, expect_count, (uint8_t*)expect_bytes); \
reader.count = writer.pos; \
reader.pos = 0; \
decoded = labcomm_read_##ltype(&reader); \
decoded = labcomm2014_read_##ltype(&reader); \
if (decoded != value) { \
fprintf(stderr, "Decode error" format " != " format " @%s:%d \n", \
value, decoded, __FILE__, __LINE__); \
......@@ -91,7 +91,7 @@ static void writer_assert(char *type,
}
}
int main(void)
static int do_test(int argc, char *argv[])
{
TEST_WRITE_READ(packed32, packed32, "%d", 0x0, 1, "\x00");
TEST_WRITE_READ(packed32, packed32, "%d", 0x7f, 1, "\x7f");
......@@ -141,3 +141,7 @@ int main(void)
return 0;
}
int main(int argc, char *argv[])
{
return do_test(argc, argv);
}
#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 "labcomm2014.h"
#include "labcomm2014_private.h"
#include "labcomm2014_default_error_handler.h"
#include "labcomm2014_default_memory.h"
#include "labcomm2014_default_scheduler.h"
#include "labcomm2014_fd_writer.h"
#include "labcomm2014_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)
{
labcomm2014_copy_generated_encoding_S1(labcomm2014_default_memory, context, v);
}
static void handle_b(generated_encoding_B *v, void *context)
{
labcomm2014_copy_generated_encoding_B(labcomm2014_default_memory, context, v);
}
static void handle_i(generated_encoding_I *v, void *context)
{
labcomm2014_copy_generated_encoding_I(labcomm2014_default_memory, context, v);
}
static void handle_p(generated_encoding_P *v, void *context)
{
labcomm2014_copy_generated_encoding_P(labcomm2014_default_memory, context, v);
}
static void handle_r(generated_encoding_R *v, void *context)
{
labcomm2014_copy_generated_encoding_R(labcomm2014_default_memory, context, v);
}
static void handle_test_var(test_sample_test_var *v, void *context)
{
labcomm2014_copy_test_sample_test_var(labcomm2014_default_memory, context, v);
}
static void handle_a(more_types_A *v, void *context)
{
labcomm2014_copy_more_types_A(labcomm2014_default_memory, context, v);
}
static void handle_s(more_types_S *v, void *context)
{
labcomm2014_copy_more_types_S(labcomm2014_default_memory, context, v);
}
static void handle_ns(more_types_NS *v, void *context)
{
labcomm2014_copy_more_types_NS(labcomm2014_default_memory, context, v);
}
static void handle_as(more_types_AS *v, void *context)
{
labcomm2014_copy_more_types_AS(labcomm2014_default_memory, context, v);
}
int do_test(int argc, char **argv)
{
struct labcomm2014_encoder *encoder;
struct labcomm2014_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;
generated_encoding_R r;
generated_encoding_R cache_r;
fd = open(DATA_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
err(1, "open()");
encoder =
labcomm2014_encoder_new(labcomm2014_fd_writer_new(labcomm2014_default_memory, fd, 0),
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
labcomm2014_encoder_register_generated_encoding_S1(encoder);
s1.i = 1;
labcomm2014_encode_generated_encoding_S1(encoder, &s1);
labcomm2014_encoder_register_generated_encoding_B(encoder);
b = 2;
labcomm2014_encode_generated_encoding_B(encoder, &b);
labcomm2014_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;
labcomm2014_encode_generated_encoding_I(encoder, &I);
labcomm2014_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;
labcomm2014_encode_generated_encoding_P(encoder, &p);
labcomm2014_encoder_register_test_sample_test_var(encoder);
test_var.n_0 = 2;
test_var.n_2 = 7;
test_var.a = calloc(test_var.n_0 * 2 * test_var.n_2, sizeof(*test_var.a));
for (int i = 0; i < test_var.n_0; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < test_var.n_2; k++) {
test_var.a[(((i) * 2 + j) * test_var.n_2) + k] = 100 * i + 10 * j + k;
}
labcomm2014_encode_test_sample_test_var(encoder, &test_var);
labcomm2014_encoder_register_more_types_A(encoder);
for (int i = 0; i < sizeof(a.a) / sizeof(a.a[0]); i++)
a.a[i] = i;
labcomm2014_encode_more_types_A(encoder, &a);
labcomm2014_encoder_register_more_types_S(encoder);
s = "this is a string";
labcomm2014_encode_more_types_S(encoder, &s);
labcomm2014_encoder_register_more_types_NS(encoder);
ns.s1 = "this is a string";
ns.s2 = "this is a another string";
labcomm2014_encode_more_types_NS(encoder, &ns);
labcomm2014_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";
labcomm2014_encode_more_types_AS(encoder, &as);
labcomm2014_encoder_register_generated_encoding_R(encoder);
labcomm2014_encoder_sample_ref_register(encoder, labcomm2014_signature_generated_encoding_V);
labcomm2014_encoder_sample_ref_register(encoder,
labcomm2014_signature_generated_encoding_UnusedD);
labcomm2014_encoder_sample_ref_register(encoder, labcomm2014_signature_generated_encoding_R);
r.a[0] = labcomm2014_encoder_get_sample_ref(
encoder, labcomm2014_signature_generated_encoding_V);
r.a[1] = labcomm2014_encoder_get_sample_ref(
encoder, labcomm2014_signature_generated_encoding_UnusedE);
r.a[2] = labcomm2014_encoder_get_sample_ref(
encoder, labcomm2014_signature_generated_encoding_UnusedD);
r.a[3] = labcomm2014_encoder_get_sample_ref(
encoder, labcomm2014_signature_generated_encoding_R);
labcomm2014_encode_generated_encoding_R(encoder, &r);
labcomm2014_encoder_free(encoder);
encoder = NULL;
lseek(fd, 0, SEEK_SET);
decoder =
labcomm2014_decoder_new(labcomm2014_fd_reader_new(labcomm2014_default_memory, fd, 0),
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
labcomm2014_decoder_register_generated_encoding_S1(decoder, handle_s1, &cache_s1);
labcomm2014_decoder_register_generated_encoding_B(decoder, handle_b, &cache_b);
labcomm2014_decoder_register_generated_encoding_I(decoder, handle_i, &cache_I);
labcomm2014_decoder_register_generated_encoding_P(decoder, handle_p, &cache_p);
labcomm2014_decoder_register_test_sample_test_var(decoder, handle_test_var,
&cache_test_var);
labcomm2014_decoder_register_more_types_A(decoder, handle_a, &cache_a);
labcomm2014_decoder_register_more_types_S(decoder, handle_s, &cache_s);
labcomm2014_decoder_register_more_types_NS(decoder, handle_ns, &cache_ns);
labcomm2014_decoder_register_more_types_AS(decoder, handle_as, &cache_as);
labcomm2014_decoder_register_generated_encoding_R(decoder, handle_r, &cache_r);
labcomm2014_decoder_sample_ref_register(decoder, labcomm2014_signature_generated_encoding_V);
labcomm2014_decoder_sample_ref_register(decoder,
labcomm2014_signature_generated_encoding_UnusedE);
labcomm2014_decoder_sample_ref_register(decoder, labcomm2014_signature_generated_encoding_R);
while (labcomm2014_decoder_decode_one(decoder) > 0) ;
printf("cache_s1.i = %d, s1.i = %d\n", cache_s1.i, s1.i);
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");
assert(cache_test_var.n_0 == test_var.n_0);
assert(cache_test_var.n_2 == test_var.n_2);
for (int i = 0; i < test_var.n_0; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < test_var.n_2; k++) {
assert(cache_test_var.a[(((i) * 2 + j) * test_var.n_2) + k] ==
test_var.a[(((i) * 2 + j) * test_var.n_2) + k]);
assert(cache_test_var.a[(((i) * 2 + j) * test_var.n_2) + k] ==
100 * i + 10 * j + k);
}
free(test_var.a);
puts("test_var copied ok");
for (int i = 0; i < sizeof(a.a) / sizeof(a.a[0]); i++)
assert(cache_a.a[i] == a.a[i]);
puts("A copied ok");
assert(!strcmp(cache_s, s));
puts("S copied ok");
assert(!strcmp(cache_ns.s1, ns.s1));
assert(!strcmp(cache_ns.s2, ns.s2));
puts("NS copied ok");
for (int i = 0; i < as.n_0; i++)
assert(!strcmp(cache_as.a[i], as.a[i]));
free(as.a);
puts("AS copied ok");
fprintf(stderr, "%p %p\n", r.a[0], cache_r.a[0]);
fprintf(stderr, "%p %p\n", r.a[1], cache_r.a[1]);
fprintf(stderr, "%p %p\n", r.a[2], cache_r.a[2]);
fprintf(stderr, "%p %p\n", r.a[3], cache_r.a[3]);
assert(cache_r.a[0] == r.a[0]);
assert(cache_r.a[1] == NULL); /* UnusedE */
assert(cache_r.a[2] == NULL); /* UnusedD */
assert(cache_r.a[3] == r.a[3]);
puts("R copied ok");
labcomm2014_decoder_free(decoder);
close(fd);
unlink(DATA_FILE);
labcomm2014_copy_free_generated_encoding_S1(labcomm2014_default_memory, &cache_s1);
puts("S1 deallocated ok");
labcomm2014_copy_free_generated_encoding_B(labcomm2014_default_memory, &cache_b);
puts("B deallocated ok");
labcomm2014_copy_free_generated_encoding_I(labcomm2014_default_memory, &cache_I);
puts("I deallocated ok");
labcomm2014_copy_free_generated_encoding_P(labcomm2014_default_memory, &cache_p);
puts("P deallocated ok");
labcomm2014_copy_free_test_sample_test_var(labcomm2014_default_memory, &cache_test_var);
puts("test_var deallocated ok");
labcomm2014_copy_free_more_types_A(labcomm2014_default_memory, &cache_a);
puts("A deallocated ok");
labcomm2014_copy_free_more_types_S(labcomm2014_default_memory, &cache_s);
puts("S deallocated ok");
labcomm2014_copy_free_more_types_NS(labcomm2014_default_memory, &cache_ns);
puts("NS deallocated ok");
labcomm2014_copy_free_more_types_AS(labcomm2014_default_memory, &cache_as);
puts("AS deallocated ok");
labcomm2014_copy_free_generated_encoding_R(labcomm2014_default_memory,
&cache_r);
puts("R deallocated ok");
return 0;
}
int main(int argc, char **argv)
{
return do_test(argc, argv);
}
/*
test_labcomm_generated_encoding.c -- LabComm tests of generated encoding
test_labcomm2014_generated_encoding.c -- LabComm tests of generated encoding
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -23,22 +23,34 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "labcomm_private.h"
#include "labcomm_default_error_handler.h"
#include "labcomm_default_memory.h"
#include "labcomm_pthread_scheduler.h"
#include "labcomm2014_private.h"
#include "labcomm2014_default_error_handler.h"
#include "labcomm2014_default_memory.h"
#include "labcomm2014_pthread_scheduler.h"
#include "test/gen/generated_encoding.h"
#define IOCTL_WRITER_ASSERT_BYTES 4096
#define IOCTL_WRITER_RESET 4097
#define EXPECT(...) \
{ \
int expected[] = __VA_ARGS__; \
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_ASSERT_BYTES, \
__LINE__, \
sizeof(expected)/sizeof(expected[0]), \
expected); \
}
#define VARIABLE(i) -(i + 1)
#define IS_VARIABLE(i) (i < 0)
static unsigned char buffer[128];
struct labcomm_writer *writer;
struct labcomm2014_writer *writer;
static int seen_variable[1024];
static int buf_writer_alloc(
struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
char *labcomm_version)
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
writer = w; /* Hack */
w->data_size = sizeof(buffer);
......@@ -50,32 +62,32 @@ static int buf_writer_alloc(
}
static int buf_writer_free(
struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context)
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
return 0;
}
static int buf_writer_start(
struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index,
struct labcomm_signature *signature,
const struct labcomm2014_signature *signature,
void *value)
{
return 0;
}
static int buf_writer_end(
struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context)
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
return 0;
}
static int buf_writer_flush(
struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context)
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
fprintf(stderr, "Should not come here %s:%d\n", __FILE__, __LINE__);
exit(1);
......@@ -84,9 +96,9 @@ static int buf_writer_flush(
}
static int buf_writer_ioctl(
struct labcomm_writer *w,
struct labcomm_writer_action_context *action_context,
int signature_index, struct labcomm_signature *signature,
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int signature_index, const struct labcomm2014_signature *signature,
uint32_t action, va_list arg)
{
int result = -ENOTSUP;
......@@ -97,13 +109,23 @@ static int buf_writer_ioctl(
int *expected = va_arg(arg, int *);
int i, mismatch;
mismatch = 0;
if (w->pos != count) {
fprintf(stderr, "Invalid length encoded %d != %d (%s:%d)\n",
fprintf(stderr, "Invalid length detected %d != %d (%s:%d)\n",
w->pos, count, __FILE__, line);
mismatch = 1;
}
for (mismatch = 0, i = 0 ; i < count ; i++) {
if (expected[i] >= 0 && expected[i] != buffer[i]) {
for (i = 0 ; i < count ; i++) {
if (IS_VARIABLE(expected[i])) {
if (seen_variable[VARIABLE(expected[i])] == -1) {
seen_variable[VARIABLE(expected[i])] = buffer[i];
}
if (seen_variable[VARIABLE(expected[i])] != buffer[i]) {
fprintf(stderr, "Unexpected variable (%d: != %d)\n",
seen_variable[VARIABLE(expected[i])], buffer[i]);
mismatch = 1;
}
} else if (expected[i] != buffer[i]) {
mismatch = 1;
}
}
......@@ -117,7 +139,7 @@ static int buf_writer_ioctl(
printf("\n");
for (i = 0 ; i < count ; i++) {
if (expected[i] < 0) {
printf(".. ");
printf("v%d ", VARIABLE(expected[i]));
} else {
printf("%2.2x ", expected[i] );
}
......@@ -135,7 +157,7 @@ static int buf_writer_ioctl(
return result;
}
const struct labcomm_writer_action writer_action = {
const struct labcomm2014_writer_action writer_action = {
.alloc = buf_writer_alloc,
.free = buf_writer_free,
.start = buf_writer_start,
......@@ -144,12 +166,12 @@ const struct labcomm_writer_action writer_action = {
.ioctl = buf_writer_ioctl
};
static struct labcomm_writer_action_context action_context = {
static struct labcomm2014_writer_action_context action_context = {
.next = NULL,
.action = &writer_action,
.context = NULL
};
static struct labcomm_writer buffer_writer = {
static struct labcomm2014_writer buffer_writer = {
.action_context = &action_context,
.data = buffer,
.data_size = sizeof(buffer),
......@@ -158,7 +180,7 @@ static struct labcomm_writer buffer_writer = {
.error = 0,
};
void dump_encoder(struct labcomm_encoder *encoder)
void dump_encoder(struct labcomm2014_encoder *encoder)
{
int i;
......@@ -168,44 +190,95 @@ void dump_encoder(struct labcomm_encoder *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;
generated_encoding_B B = 1;
generated_encoding_R R;
struct labcomm2014_encoder *encoder;
int i;
struct labcomm_encoder *encoder = labcomm_encoder_new(
for (i = 0 ; i < sizeof(seen_variable)/sizeof(seen_variable[0]) ; i++) {
seen_variable[i] = -1;
}
encoder = labcomm2014_encoder_new(
&buffer_writer,
labcomm_default_error_handler,
labcomm_default_memory,
labcomm_pthread_scheduler_new(labcomm_default_memory));
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_pthread_scheduler_new(labcomm2014_default_memory));
EXPECT({ 0x01, 0x0c, 0x0b,
'L', 'a', 'b', 'C', 'o', 'm', 'm', '2','0', '1', '4' });
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_register_generated_encoding_V(encoder);
labcomm2014_encoder_register_generated_encoding_V(encoder);
EXPECT({ 0x02, 0x08, VARIABLE(0), 0x01, 0x00, 0x01, 'V', 0x02, 0x11, 0x00,
0x04, 0x0a, VARIABLE(1), 0x01, 0x00, 0x03, 'v', '_', 't', 0x02, 0x11, 0x00,
0x04, 0x07, VARIABLE(2), 0x01, 0x00, 0x01, 'V', 0x01, VARIABLE(1),
0x05, 0x02, VARIABLE(0), VARIABLE(2) });
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_register_generated_encoding_B(encoder);
labcomm2014_encoder_register_generated_encoding_B(encoder);
EXPECT({ 0x02, 0x07, VARIABLE(3),0x01, 0x00, 0x01, 'B', 0x01, 0x21,
0x05, 0x02, VARIABLE(3), LABCOMM_BIND_SELF });
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_register_generated_encoding_R(encoder);
labcomm2014_encoder_register_generated_encoding_R(encoder);
EXPECT({ 0x02, 0x0a, VARIABLE(4), 0x01, 0x00, 0x01, 'R', 0x04, 0x10, 0x01, 0x04, 0x28,
0x05, 0x02, VARIABLE(4), LABCOMM_BIND_SELF });
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_sample_ref_register(encoder,
labcomm2014_signature_generated_encoding_V);
labcomm2014_encoder_sample_ref_register(encoder,
labcomm2014_signature_generated_encoding_V);
EXPECT({0x03, 0x08, VARIABLE(5), 0x01, 0x00, 0x01, 'V', 0x02, 0x11, 0x00});
labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
labcomm_encoder_register_generated_encoding_V(encoder);
labcomm_encoder_register_generated_encoding_V(encoder);
EXPECT({ 0x02, -1, 0x01, 'V', 0x11, 0x00 });
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_sample_ref_register(encoder,
labcomm2014_signature_generated_encoding_B);
labcomm2014_encoder_sample_ref_register(encoder,
labcomm2014_signature_generated_encoding_B);
EXPECT({0x03, 0x07, VARIABLE(6), 0x01, 0x00, 0x01, 'B', 0x01, 0x21});
labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
labcomm_encoder_register_generated_encoding_B(encoder);
labcomm_encoder_register_generated_encoding_B(encoder);
EXPECT({0x02, -1, 0x01, 'B', 0x21});
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_sample_ref_register(encoder,
labcomm2014_signature_generated_encoding_R);
labcomm2014_encoder_sample_ref_register(encoder,
labcomm2014_signature_generated_encoding_R);
EXPECT({0x03, 0x0a, VARIABLE(7), 0x01, 0x00, 0x01, 'R', 0x04, 0x10, 0x01, 0x04, 0x28});
labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
labcomm_encode_generated_encoding_V(encoder, &V);
EXPECT({-1});
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
// was: labcomm2014_encode_generated_encoding_V(encoder, &V);
labcomm2014_encode_generated_encoding_V(encoder);
EXPECT({VARIABLE(10), 0x00 });
labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
labcomm_encode_generated_encoding_B(encoder, &B);
EXPECT({-1, 1});
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
labcomm2014_encode_generated_encoding_B(encoder, &B);
EXPECT({VARIABLE(20), 0x01, 1});
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
R.a[0] = labcomm2014_encoder_get_sample_ref(
encoder, labcomm2014_signature_generated_encoding_V);
R.a[1] = labcomm2014_encoder_get_sample_ref(
encoder, labcomm2014_signature_generated_encoding_B);
R.a[2] = labcomm2014_encoder_get_sample_ref(
encoder, labcomm2014_signature_generated_encoding_UnusedE);
R.a[3] = labcomm2014_encoder_get_sample_ref(
encoder, labcomm2014_signature_generated_encoding_R);
labcomm2014_encode_generated_encoding_R(encoder, &R);
EXPECT({VARIABLE(4), 0x10, 0x00, 0x00, 0x00, VARIABLE(5),
0x00, 0x00, 0x00, VARIABLE(6),
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, VARIABLE(7)});
return 0;
}
/*
test_labcomm_pthread_scheduler.c -- test labcomm pthread based task
test_labcomm2014_pthread_scheduler.c -- test labcomm2014 pthread based task
coordination
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -22,13 +22,13 @@
#include <stdio.h>
#include <stdlib.h>
#include "labcomm_default_memory.h"
#include "labcomm_scheduler.h"
#include "labcomm_pthread_scheduler.h"
#include "labcomm2014_default_memory.h"
#include "labcomm2014_scheduler.h"
#include "labcomm2014_pthread_scheduler.h"
#define TICK 100000
struct func_arg {
struct labcomm_scheduler *scheduler;
struct labcomm2014_scheduler *scheduler;
int i;
};
......@@ -38,11 +38,12 @@ static void func(void *arg)
printf("%p %d\n", arg, func_arg->i);
if (func_arg->i == 999) {
labcomm_scheduler_wakeup(func_arg->scheduler);
labcomm2014_scheduler_wakeup(func_arg->scheduler);
}
free(func_arg);
}
void enqueue(struct labcomm_scheduler *scheduler,
void enqueue(struct labcomm2014_scheduler *scheduler,
int first, int last)
{
int i;
......@@ -52,16 +53,16 @@ void enqueue(struct labcomm_scheduler *scheduler,
tmp->scheduler = scheduler;
tmp->i = i;
labcomm_scheduler_enqueue(scheduler, i*TICK, func, tmp);
labcomm2014_scheduler_enqueue(scheduler, i*TICK, func, tmp);
}
}
int main(int argc, char *argv[])
static int do_test(int argc, char *argv[])
{
struct labcomm_scheduler *scheduler;
struct labcomm_time *time;
struct labcomm2014_scheduler *scheduler;
struct labcomm2014_time *time;
scheduler = labcomm_pthread_scheduler_new(labcomm_default_memory);
scheduler = labcomm2014_pthread_scheduler_new(labcomm2014_default_memory);
enqueue(scheduler, 0, 5);
enqueue(scheduler, 0, 1);
enqueue(scheduler, 1, 3);
......@@ -71,12 +72,19 @@ int main(int argc, char *argv[])
tmp->scheduler = scheduler;
tmp->i = 999;
labcomm_scheduler_enqueue(scheduler, 6*TICK, func, tmp);
labcomm2014_scheduler_enqueue(scheduler, 6*TICK, func, tmp);
}
time = labcomm_scheduler_now(scheduler);
labcomm_time_add_usec(time, 12*TICK);
labcomm_scheduler_sleep(scheduler, NULL);
labcomm_scheduler_sleep(scheduler, time);
time = labcomm2014_scheduler_now(scheduler);
labcomm2014_time_add_usec(time, 12*TICK);
labcomm2014_scheduler_sleep(scheduler, NULL);
labcomm2014_scheduler_sleep(scheduler, time);
labcomm2014_time_free(time);
labcomm2014_scheduler_free(scheduler);
return 0;
}
int main(int argc, char *argv[])
{
return do_test(argc, argv);
}
#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 "labcomm2014.h"
#include "labcomm2014_private.h"
#include "labcomm2014_default_error_handler.h"
#include "labcomm2014_default_memory.h"
#include "labcomm2014_default_scheduler.h"
#include "labcomm2014_fd_writer.h"
#include "labcomm2014_fd_reader.h"
#include "labcomm2014_renaming.h"
#include "labcomm2014_renaming_encoder.h"
#include "labcomm2014_renaming_decoder.h"
#include "test/gen/generated_encoding.h"
#define DATA_FILE "renaming_test.dat"
static void handle_r(generated_encoding_R *v, void *context)
{
labcomm2014_copy_generated_encoding_R(labcomm2014_default_memory, context, v);
}
int main(int argc, char **argv)
{
struct labcomm2014_renaming_registry *registry;
struct labcomm2014_encoder *encoder, *prefix_encoder, *suffix_encoder;
struct labcomm2014_decoder *decoder, *prefix_decoder, *suffix_decoder;
int fd;
generated_encoding_R r;
generated_encoding_R cache_r, prefix_cache_r, suffix_cache_r;
fd = open(DATA_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
err(1, "open()");
}
registry = labcomm2014_renaming_registry_new(
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
encoder = labcomm2014_encoder_new(
labcomm2014_fd_writer_new(labcomm2014_default_memory, fd, 0),
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
prefix_encoder = labcomm2014_renaming_encoder_new(
encoder, registry, labcomm2014_renaming_prefix, "p.");
suffix_encoder = labcomm2014_renaming_encoder_new(
prefix_encoder, registry, labcomm2014_renaming_suffix, ".s");
labcomm2014_encoder_register_generated_encoding_R(encoder);
labcomm2014_encoder_register_generated_encoding_R(prefix_encoder);
labcomm2014_encoder_register_generated_encoding_R(suffix_encoder);
labcomm2014_encoder_sample_ref_register(
encoder, labcomm2014_signature_generated_encoding_R);
labcomm2014_encoder_sample_ref_register(
prefix_encoder, labcomm2014_signature_generated_encoding_R);
labcomm2014_encoder_sample_ref_register(
suffix_encoder, labcomm2014_signature_generated_encoding_R);
r.a[0] = labcomm2014_encoder_get_sample_ref(
encoder, labcomm2014_signature_generated_encoding_R);
r.a[1] = labcomm2014_encoder_get_sample_ref(
prefix_encoder, labcomm2014_signature_generated_encoding_R);
r.a[2] = labcomm2014_encoder_get_sample_ref(
suffix_encoder, labcomm2014_signature_generated_encoding_R);
r.a[3] = labcomm2014_encoder_get_sample_ref(
encoder, labcomm2014_signature_generated_encoding_R);
labcomm2014_encode_generated_encoding_R(encoder, &r);
r.a[3] = labcomm2014_encoder_get_sample_ref(
prefix_encoder, labcomm2014_signature_generated_encoding_R);
labcomm2014_encode_generated_encoding_R(prefix_encoder, &r);
r.a[3] = labcomm2014_encoder_get_sample_ref(
suffix_encoder, labcomm2014_signature_generated_encoding_R);
labcomm2014_encode_generated_encoding_R(suffix_encoder, &r);
labcomm2014_encoder_free(suffix_encoder);
labcomm2014_encoder_free(prefix_encoder);
labcomm2014_encoder_free(encoder);
encoder = NULL;
lseek(fd, 0, SEEK_SET);
decoder =
labcomm2014_decoder_new(
labcomm2014_fd_reader_new(labcomm2014_default_memory, fd, 0),
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
prefix_decoder = labcomm2014_renaming_decoder_new(
decoder, registry, labcomm2014_renaming_prefix, "p.");
suffix_decoder = labcomm2014_renaming_decoder_new(
prefix_decoder, registry, labcomm2014_renaming_suffix, ".s");
labcomm2014_decoder_register_generated_encoding_R(
decoder, handle_r, &cache_r);
labcomm2014_decoder_register_generated_encoding_R(
prefix_decoder, handle_r, &prefix_cache_r);
labcomm2014_decoder_register_generated_encoding_R(
suffix_decoder, handle_r, &suffix_cache_r);
labcomm2014_decoder_sample_ref_register(
decoder, labcomm2014_signature_generated_encoding_R);
labcomm2014_decoder_sample_ref_register(
prefix_decoder, labcomm2014_signature_generated_encoding_R);
labcomm2014_decoder_sample_ref_register(
suffix_decoder, labcomm2014_signature_generated_encoding_R);
while (labcomm2014_decoder_decode_one(decoder) > 0) ;
fprintf(stderr, "cache_r:\n");
fprintf(stderr, "%p %p %p %p\n",
cache_r.a[0],
cache_r.a[1],
cache_r.a[2],
cache_r.a[3]);
fprintf(stderr, "prefix_cache_r:\n");
fprintf(stderr, "%p %p %p %p\n",
prefix_cache_r.a[0],
prefix_cache_r.a[1],
prefix_cache_r.a[2],
prefix_cache_r.a[3]);
fprintf(stderr, "suffix_cache_r:\n");
fprintf(stderr, "%p %p %p %p\n",
suffix_cache_r.a[0],
suffix_cache_r.a[1],
suffix_cache_r.a[2],
suffix_cache_r.a[3]);
assert(cache_r.a[0] ==
labcomm2014_decoder_get_sample_ref(
decoder, labcomm2014_signature_generated_encoding_R));
assert(cache_r.a[1] ==
labcomm2014_decoder_get_sample_ref(
prefix_decoder, labcomm2014_signature_generated_encoding_R));
assert(cache_r.a[2] ==
labcomm2014_decoder_get_sample_ref(
suffix_decoder, labcomm2014_signature_generated_encoding_R));
assert(cache_r.a[3] ==
labcomm2014_decoder_get_sample_ref(
decoder, labcomm2014_signature_generated_encoding_R));
assert(prefix_cache_r.a[0] ==
labcomm2014_decoder_get_sample_ref(
decoder, labcomm2014_signature_generated_encoding_R));
assert(prefix_cache_r.a[1] ==
labcomm2014_decoder_get_sample_ref(
prefix_decoder, labcomm2014_signature_generated_encoding_R));
assert(prefix_cache_r.a[2] ==
labcomm2014_decoder_get_sample_ref(
suffix_decoder, labcomm2014_signature_generated_encoding_R));
assert(prefix_cache_r.a[3] ==
labcomm2014_decoder_get_sample_ref(
prefix_decoder, labcomm2014_signature_generated_encoding_R));
assert(suffix_cache_r.a[0] ==
labcomm2014_decoder_get_sample_ref(
decoder, labcomm2014_signature_generated_encoding_R));
assert(suffix_cache_r.a[1] ==
labcomm2014_decoder_get_sample_ref(
prefix_decoder, labcomm2014_signature_generated_encoding_R));
assert(suffix_cache_r.a[2] ==
labcomm2014_decoder_get_sample_ref(
suffix_decoder, labcomm2014_signature_generated_encoding_R));
assert(suffix_cache_r.a[3] ==
labcomm2014_decoder_get_sample_ref(
suffix_decoder, labcomm2014_signature_generated_encoding_R));
labcomm2014_decoder_free(suffix_decoder);
labcomm2014_decoder_free(prefix_decoder);
labcomm2014_decoder_free(decoder);
labcomm2014_renaming_registry_free(registry);
close(fd);
unlink(DATA_FILE);
}
/*
test_labcomm2014_renaming.c -- LabComm tests of renaming
Copyright 2015 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 <stdlib.h>
#include <string.h>
#include <errno.h>
#include "labcomm2014_private.h"
#include "labcomm2014_default_error_handler.h"
#include "labcomm2014_default_memory.h"
#include "labcomm2014_default_scheduler.h"
#include "labcomm2014_renaming.h"
#include "labcomm2014_renaming_encoder.h"
#include "test/gen/generated_encoding.h"
#define IOCTL_WRITER_ASSERT_BYTES 4096
#define IOCTL_WRITER_RESET 4097
#define EXPECT(...) \
{ \
int expected[] = __VA_ARGS__; \
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_ASSERT_BYTES, \
__LINE__, \
sizeof(expected)/sizeof(expected[0]), \
expected); \
}
#define VARIABLE(i) -(i + 1)
#define IS_VARIABLE(i) (i < 0)
static unsigned char buffer[128];
struct labcomm2014_writer *writer;
static int seen_variable[1024];
static int buf_writer_alloc(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
writer = w; /* Hack */
w->data_size = sizeof(buffer);
w->count = w->data_size;
w->data = buffer;
w->pos = 0;
return 0;
}
static int buf_writer_free(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
return 0;
}
static int buf_writer_start(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int index,
const struct labcomm2014_signature *signature,
void *value)
{
return 0;
}
static int buf_writer_end(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
return 0;
}
static int buf_writer_flush(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context)
{
fprintf(stderr, "Should not come here %s:%d\n", __FILE__, __LINE__);
exit(1);
return 0;
}
static int buf_writer_ioctl(
struct labcomm2014_writer *w,
struct labcomm2014_writer_action_context *action_context,
int signature_index, const struct labcomm2014_signature *signature,
uint32_t action, va_list arg)
{
int result = -ENOTSUP;
switch (action) {
case IOCTL_WRITER_ASSERT_BYTES: {
int line = va_arg(arg, int);
int count = va_arg(arg, int);
int *expected = va_arg(arg, int *);
int i, mismatch;
mismatch = 0;
if (w->pos != count) {
fprintf(stderr, "Invalid length detected %d != %d (%s:%d)\n",
w->pos, count, __FILE__, line);
mismatch = 1;
}
for (i = 0 ; i < count ; i++) {
if (IS_VARIABLE(expected[i])) {
if (seen_variable[VARIABLE(expected[i])] == -1) {
seen_variable[VARIABLE(expected[i])] = buffer[i];
}
if (seen_variable[VARIABLE(expected[i])] != buffer[i]) {
fprintf(stderr, "Unexpected variable v%d (%02x: != %02x)\n",
VARIABLE(expected[i]),
seen_variable[VARIABLE(expected[i])], buffer[i]);
mismatch = 1;
}
} else if (expected[i] != buffer[i]) {
mismatch = 1;
}
}
if (mismatch) {
fprintf(stderr, "Encoder mismatch (%s:%d)\n",
__FILE__, line);
for (i = 0 ; i < w->pos ; i++) {
if (32 <= w->data[i] && w->data[i] < 127) {
printf("%2c ", w->data[i]);
} else {
printf("%2.2x ", w->data[i]);
}
}
printf("\n");
for (i = 0 ; i < w->pos ; i++) {
printf("%2.2x ", w->data[i]);
}
printf("\n");
for (i = 0 ; i < count ; i++) {
if (expected[i] < 0) {
printf("v%d ", VARIABLE(expected[i]));
} else {
printf("%2.2x ", expected[i] );
}
}
printf("\n");
if (mismatch) { exit(1); }
}
result = 0;
} break;
case IOCTL_WRITER_RESET: {
w->pos = 0;
result = 0;
}
}
return result;
}
const struct labcomm2014_writer_action writer_action = {
.alloc = buf_writer_alloc,
.free = buf_writer_free,
.start = buf_writer_start,
.end = buf_writer_end,
.flush = buf_writer_flush,
.ioctl = buf_writer_ioctl
};
static struct labcomm2014_writer_action_context action_context = {
.next = NULL,
.action = &writer_action,
.context = NULL
};
static struct labcomm2014_writer buffer_writer = {
.action_context = &action_context,
.data = buffer,
.data_size = sizeof(buffer),
.count = sizeof(buffer),
.pos = 0,
.error = 0,
};
void dump_encoder(struct labcomm2014_encoder *encoder)
{
int i;
for (i = 0 ; i < writer->pos ; i++) {
printf("%2.2x ", writer->data[i]);
}
printf("\n");
}
static int do_test(int argc, char *argv[])
{
struct labcomm2014_renaming_registry *registry;
struct labcomm2014_encoder *encoder, *prefix, *suffix;
int i;
for (i = 0 ; i < sizeof(seen_variable)/sizeof(seen_variable[0]) ; i++) {
seen_variable[i] = -1;
}
registry = labcomm2014_renaming_registry_new(
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
encoder = labcomm2014_encoder_new(
&buffer_writer,
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
prefix = labcomm2014_renaming_encoder_new(encoder,
registry,
labcomm2014_renaming_prefix,
"p.");
suffix = labcomm2014_renaming_encoder_new(prefix,
registry,
labcomm2014_renaming_suffix,
".s");
EXPECT({ 0x01, 0x0c, 0x0b,
'L', 'a', 'b', 'C', 'o', 'm', 'm', '2','0', '1', '4' });
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_register_generated_encoding_V(encoder);
labcomm2014_encoder_register_generated_encoding_V(encoder);
EXPECT({ 0x02, 0x08, VARIABLE(0), 0x01, 0x00, 0x01, 'V', 0x02, 0x11, 0x00,
0x04, 0x0a, VARIABLE(1), 0x01, 0x00, 0x03, 'v', '_', 't', 0x02, 0x11, 0x00,
0x04, 0x07, VARIABLE(2), 0x01, 0x00, 0x01, 'V', 0x01, VARIABLE(1),
0x05, 0x02, VARIABLE(0), VARIABLE(2) });
labcomm2014_encoder_ioctl(prefix, IOCTL_WRITER_RESET);
labcomm2014_encoder_register_generated_encoding_V(prefix);
labcomm2014_encoder_register_generated_encoding_V(prefix);
EXPECT({ 0x02, 0x0a, VARIABLE(3), 0x01, 0x00, 0x03, 'p', '.', 'V', 0x02, 0x11, 0x00,
0x04, 0x09, VARIABLE(4), 0x01, 0x00, 0x03, 'p', '.', 'V', 0x01, VARIABLE(2),
0x05, 0x02, VARIABLE(3), VARIABLE(4) });
labcomm2014_encoder_ioctl(suffix, IOCTL_WRITER_RESET);
labcomm2014_encoder_register_generated_encoding_V(suffix);
labcomm2014_encoder_register_generated_encoding_V(suffix);
// XXX HERE BE DRAGONS! What does "BOGUS" man in the below renaming test?
// previous version (from merge conflict): VARIABLE(6) vs VARIABLE(2)
// <<<<<<< ours
// EXPECT({ 0x02, 0x0c, VARIABLE(5), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x02, 0x11, 0x00,
// 0x04, 0x09, VARIABLE(6), 0x01, 0x00, 0x03, 'V', '.', 's', 0x01, VARIABLE(2),
// 0x04, 0x0b, VARIABLE(7), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x01, VARIABLE(6),
// =======
EXPECT({ 0x02, 0x0c, VARIABLE(5), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x02, 0x11, 0x00,
0x04, 0x09, VARIABLE(6), 0x01, 0x00, 0x03, 'V', '.', 's', 0x01, VARIABLE(2), /* BOGUS */
0x04, 0x0b, VARIABLE(7), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x01, VARIABLE(2),
0x05, 0x02, VARIABLE(5), VARIABLE(7) });
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_sample_ref_register(encoder,
labcomm2014_signature_generated_encoding_V);
labcomm2014_encoder_sample_ref_register(encoder,
labcomm2014_signature_generated_encoding_V);
EXPECT({0x03, 0x08, VARIABLE(8), 0x01, 0x00, 0x01, 'V', 0x02, 0x11, 0x00});
labcomm2014_encoder_ioctl(prefix, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_sample_ref_register(prefix,
labcomm2014_signature_generated_encoding_V);
labcomm2014_encoder_sample_ref_register(prefix,
labcomm2014_signature_generated_encoding_V);
EXPECT({0x03, 0x0a, VARIABLE(9), 0x01, 0x00, 0x03, 'p', '.', 'V', 0x02, 0x11, 0x00});
labcomm2014_encoder_ioctl(suffix, IOCTL_WRITER_RESET);
/* Register twice to make sure that only one registration gets encoded */
labcomm2014_encoder_sample_ref_register(suffix,
labcomm2014_signature_generated_encoding_V);
labcomm2014_encoder_sample_ref_register(suffix,
labcomm2014_signature_generated_encoding_V);
EXPECT({0x03, 0x0c, VARIABLE(10), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x02, 0x11, 0x00});
labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
labcomm2014_encode_generated_encoding_V(encoder);
EXPECT({VARIABLE(0), 0x00 });
labcomm2014_encoder_ioctl(prefix, IOCTL_WRITER_RESET);
labcomm2014_encode_generated_encoding_V(prefix);
EXPECT({VARIABLE(3), 0x00 });
labcomm2014_encoder_ioctl(suffix, IOCTL_WRITER_RESET);
labcomm2014_encode_generated_encoding_V(suffix);
EXPECT({VARIABLE(5), 0x00 });
labcomm2014_encoder_free(suffix);
labcomm2014_encoder_free(prefix);
labcomm2014_encoder_free(encoder);
labcomm2014_renaming_registry_free(registry);
return 0;
}
int main(int argc, char *argv[])
{
return do_test(argc, argv);
}
#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 "labcomm2014.h"
#include "labcomm2014_private.h"
#include "labcomm2014_default_error_handler.h"
#include "labcomm2014_default_memory.h"
#include "labcomm2014_default_scheduler.h"
#include "labcomm2014_renaming.h"
#include "labcomm2014_renaming_private.h"
#include "test/gen/generated_encoding.h"
static int do_test(int argc, char **argv)
{
struct labcomm2014_renaming_registry *registry;
struct labcomm2014_renaming_rename *r1, *r2, *r3, *r4;
registry = labcomm2014_renaming_registry_new(
labcomm2014_default_error_handler,
labcomm2014_default_memory,
labcomm2014_default_scheduler);
r1 = labcomm2014_renaming_rename_new(
registry,
labcomm2014_signature_generated_encoding_R,
labcomm2014_renaming_prefix, "p:");
r2 = labcomm2014_renaming_rename_new(
registry,
labcomm2014_renaming_rename_signature(r1),
labcomm2014_renaming_suffix, ":s");
r3 = labcomm2014_renaming_rename_new(
registry,
labcomm2014_signature_generated_encoding_R,
labcomm2014_renaming_suffix, ":s");
r4 = labcomm2014_renaming_rename_new(
registry,
labcomm2014_renaming_rename_signature(r3),
labcomm2014_renaming_prefix, "p:");
assert(r2 == r4);
labcomm2014_renaming_rename_free(registry, r1);
labcomm2014_renaming_rename_free(registry, r2);
labcomm2014_renaming_rename_free(registry, r3);
labcomm2014_renaming_rename_free(registry, r4);
labcomm2014_renaming_registry_free(registry);
return 0;
}
int main(int argc, char **argv)
{
return do_test(argc, argv);
}
sample int test_var[_,2,_];
#include <stdlib.h>
#include <stdio.h>
#include "labcomm2014_private.h"
#include "test/gen/another_encoding.h"
#include "test/gen/generated_encoding.h"
static void info(char *name, char *full_name,
const struct labcomm2014_signature *signature) {
printf("%s %s %p -> %d\n", name, full_name, signature,
labcomm2014_get_local_index(signature));
if (labcomm2014_get_local_index(signature) < 0x40) {
exit(1);
}
};
int main(int argc, char *argv[])
{
#define FUNC(name, full_name) \
info( #name, #full_name, labcomm2014_signature_##full_name)
LABCOMM_FORALL_SAMPLES_generated_encoding(FUNC, ;);
LABCOMM_FORALL_SAMPLES_another_encoding(FUNC, ;);
return 0;
}
## Macros
VERSIONS=2014
CC=gcc
#CFLAGS=-g -Wall -Werror -O3 -I. -Itest -DLABCOMM_ENCODER_LINEAR_SEARCH
CFLAGS=-g -Wall -Werror -O3 -I. -Itest
LDFLAGS=-L.
#LDLIBS_TEST=-Tlabcomm.linkscript -lcunit -llabcomm
LDLIBS_TEST=-lcunit -llabcomm -Tlabcomm.linkscript -lrt
all:
OBJS=labcomm_memory.o \
labcomm_default_error_handler.o \
labcomm_default_memory.o \
labcomm_default_scheduler.o \
labcomm_time.o labcomm_scheduler.o \
labcomm_encoder.o labcomm_decoder.o \
labcomm.o \
labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o \
labcomm_pthread_scheduler.o \
labcomm_signature_gnu_ld_tricks.o
%:
for v in $(VERSIONS) ; do $(MAKE) -C $${v} $@ || exit 1 ; done
#FIXME: labcomm_mem_reader.o labcomm_mem_writer.o
LABCOMM_JAR=../../compiler/labComm.jar
LABCOMM=java -jar $(LABCOMM_JAR)
TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding \
test_labcomm_pthread_scheduler
#
#FIXME: test_labcomm test_labcomm_errors
TEST_DIR=test
TESTDATA_DIR=$(TEST_DIR)/testdata
TEST_GEN_DIR=$(TESTDATA_DIR)/gen
.PHONY: clean
clean:
for v in $(VERSIONS) ; do $(MAKE) -C $${v} $@ || exit 1 ; done
VPATH=$(TEST_DIR)
.PHONY: distclean
distclean:
for v in $(VERSIONS) ; do $(MAKE) -C $${v} $@ || exit 1 ; done
rm -f *.o *.so *.so.1 *.a
CREATED_DIRS=$(TEST_DIR) $(TESTDATA_DIR) $(TEST_GEN_DIR)
# Enable experimental objects by invoking make like `make LABCOMM_EXPERIMENTAL=true`
ifeq ($(LABCOMM_EXPERIMENTAL),true)
OBJS += experimental/udp_hack.o experimental/ethaddr.o \
experimental/labcomm_thr_reader_writer.o \
experimental/ThrottleDrv/ethernet_drv.o \
experimental/ThrottleDrv/throttle_drv.o \
experimental/labcomm_udp_reader_writer.o
endif
## Targets
.PHONY: all run-test clean distclean
all: liblabcomm.a liblabcomm.so.1
liblabcomm.a: $(OBJS)
ar -r liblabcomm.a $^
liblabcomm.so.1: $(OBJS:%.o=%.pic.o)
gcc -shared -Wl,-soname,$@ -o $@ $^ -lc -lrt
labcomm.o : labcomm.c labcomm.h labcomm_private.h
labcomm_fd_reader_writer.o : labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h labcomm.h labcomm_private.h
#$(TEST_DIR)/labcomm_mem_reader.o: labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h
#$(TEST_DIR)/labcomm_mem_writer.o: labcomm_mem_writer.c labcomm_mem_writer.h cppmacros.h
ethaddr.o: ethaddr.c
$(CREATED_DIRS):
mkdir -p $@
## NB! the tests need CUnit to be installed
run-test: $(TESTS:%=run-test-%)
run-test-%: $(TEST_DIR)/% | $(TEST_DIR)
$<
$(TEST_DIR)/%.o: $(TEST_DIR)/%.c
$(CC) $(CFLAGS) -o $@ -c $<
.PRECIOUS: $(TEST_DIR)/%
$(TEST_DIR)/%: $(TEST_DIR)/%.o liblabcomm.a
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(LDLIBS_TEST)
$(TEST_DIR)/gen:
mkdir -p $@
$(TEST_DIR)/gen/%.c $(TEST_DIR)/gen/%.h: $(TEST_DIR)/%.lc | $(TEST_DIR)/gen
$(LABCOMM) \
--c=$(TEST_DIR)/gen/$*.c \
--h=$(TEST_DIR)/gen/$*.h \
$<
$(TEST_GEN_DIR)/%.c $(TEST_GEN_DIR)/%.h: $(TESTDATA_DIR)/%.lc \
$(LABCOMM_JAR) | $(TEST_GEN_DIR)
$(LABCOMM) \
--c=$(patsubst %.h,%.c,$@) --h=$(patsubst %.c,%.h,$@) $<
$(LABCOMM_JAR):
@echo "======Building LabComm compiler======"
cd $(shell dirname $(LABCOMM_JAR)); ant jar
@echo "======End building LabComm compiler======"
%.pic.o: %.c
$(CC) -fPIC $(CFLAGS) -c -o $@ $<
%.o: %.c %.h
clean:
$(RM) *.o
$(RM) experimental/*.o experimental/ThrottleDrv/*.o
$(RM) test/*.o
$(RM) test/*.gch
$(RM) test/test_labcomm_errors
$(RM) test/testdata/gen/*.[cho]
$(RM) test/gen/*.[cho]
$(RM) $(TEST_DIR)/test_labcomm
distclean: clean
$(RM) liblabcomm.so.1
$(RM) liblabcomm.a
# Extra dependencies
$(TEST_DIR)/test_labcomm_basic_type_encoding.o: labcomm_private.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
labcomm_fd_writer.o: labcomm_private.h
labcomm_dynamic_buffer_writer.o: labcomm_private.h
/* Hack to get a link error with (hopefully) useful information if not linked
with -Tlabcomm.linkscript */
"You need to link with '-Tlabcomm.linkscript'"=0;
SECTIONS {
labcomm : {
labcomm_first_signature = ABSOLUTE(.) ;
*(labcomm)
labcomm_last_signature = ABSOLUTE(.) ;
}
}
INSERT AFTER .data;
/*
labcomm_decoder.c -- runtime for handling 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/>.
*/
#define LABCOMM_VERSION "LabComm2013"
#include <errno.h>
#include "labcomm.h"
#include "labcomm_private.h"
#include "labcomm_signature.h"
#include "labcomm_ioctl.h"
#include "labcomm_dynamic_buffer_writer.h"
struct sample_entry {
int remote_index;
struct labcomm_signature *signature;
labcomm_decoder_function decode;
labcomm_handler_function handler;
void *context;
};
struct labcomm_decoder {
struct labcomm_reader *reader;
int reader_allocated;
struct labcomm_error_handler *error;
struct labcomm_memory *memory;
struct labcomm_scheduler *scheduler;
labcomm_error_handler_callback on_error;
labcomm_handle_new_datatype_callback on_new_datatype;
LABCOMM_SIGNATURE_ARRAY_DEF(local, struct sample_entry);
LABCOMM_SIGNATURE_ARRAY_DEF(remote_to_local, int);
};
struct labcomm_decoder *labcomm_decoder_new(
struct labcomm_reader *reader,
struct labcomm_error_handler *error,
struct labcomm_memory *memory,
struct labcomm_scheduler *scheduler)
{
struct labcomm_decoder *result;
result = labcomm_memory_alloc(memory, 0, sizeof(*result));
if (result) {
result->reader = reader;
result->reader->decoder = result;
result->reader->data = 0;
result->reader->data_size = 0;
result->reader->count = 0;
result->reader->pos = 0;
result->reader->error = 0;
result->reader_allocated = 0;
result->error = error;
result->memory = memory;
result->scheduler = scheduler;
LABCOMM_SIGNATURE_ARRAY_INIT(result->local, struct sample_entry);
LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local, int);
}
return result;
}
void labcomm_decoder_free(struct labcomm_decoder* d)
{
struct labcomm_memory *memory = d->memory;
labcomm_reader_free(d->reader, d->reader->action_context);
LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->local, struct sample_entry);
LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->remote_to_local, int);
labcomm_memory_free(memory, 0, d);
}
static void collect_flat_signature(
struct labcomm_decoder *decoder,
struct labcomm_writer *writer)
{
int type = labcomm_read_packed32(decoder->reader);
if (type >= LABCOMM_USER) {
decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
"Implement %s ... (1) for type 0x%x\n", __FUNCTION__, type);
} else {
labcomm_write_packed32(writer, type);
switch (type) {
case LABCOMM_ARRAY: {
int dimensions, i;
dimensions = labcomm_read_packed32(decoder->reader);
labcomm_write_packed32(writer, dimensions);
for (i = 0 ; i < dimensions ; i++) {
int n = labcomm_read_packed32(decoder->reader);
labcomm_write_packed32(writer, n);
}
collect_flat_signature(decoder, writer);
} break;
case LABCOMM_STRUCT: {
int fields, i;
fields = labcomm_read_packed32(decoder->reader);
labcomm_write_packed32(writer, fields);
for (i = 0 ; i < fields ; i++) {
char *name = labcomm_read_string(decoder->reader);
labcomm_write_string(writer, name);
labcomm_memory_free(decoder->memory, 1, name);
collect_flat_signature(decoder, writer);
}
} break;
case LABCOMM_BOOLEAN:
case LABCOMM_BYTE:
case LABCOMM_SHORT:
case LABCOMM_INT:
case LABCOMM_LONG:
case LABCOMM_FLOAT:
case LABCOMM_DOUBLE:
case LABCOMM_STRING: {
} break;
default: {
decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
"Implement %s (2) for type 0x%x...\n", __FUNCTION__, type);
} break;
}
}
}
static int writer_ioctl(struct labcomm_writer *writer,
uint32_t action,
...)
{
int result;
va_list va;
if (LABCOMM_IOC_SIG(action) != LABCOMM_IOC_NOSIG) {
result = -EINVAL;
goto out;
}
va_start(va, action);
result = labcomm_writer_ioctl(writer, writer->action_context,
0, NULL, action, va);
va_end(va);
out:
return result;
}
static int decode_typedef_or_sample(struct labcomm_decoder *d, int kind)
{
int result;
/* 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 = {
.action_context = &action_context,
.memory = d->memory,
.data = NULL,
.data_size = 0,
.count = 0,
.pos = 0,
.error = 0,
};
struct labcomm_signature signature, *local_signature;
int remote_index, local_index, err;
local_signature = NULL;
local_index = 0;
labcomm_writer_alloc(&writer, writer.action_context, "");
labcomm_writer_start(&writer, writer.action_context, 0, NULL, NULL);
remote_index = labcomm_read_packed32(d->reader); //int
signature.name = labcomm_read_string(d->reader);
signature.type = kind;
collect_flat_signature(d, &writer);
labcomm_writer_end(&writer, writer.action_context);
err = writer_ioctl(&writer,
LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN,
&signature.size);
if (err < 0) {
fprintf(stderr, "Failed to get size: %s\n", strerror(-err));
result = -ENOENT;
goto free_signature_name;
}
err = writer_ioctl(&writer,
LABCOMM_IOCTL_WRITER_GET_BYTE_POINTER,
&signature.signature);
if (err < 0) {
fprintf(stderr, "Failed to get pointer: %s\n", strerror(-err));
result = -ENOENT;
goto free_signature_name;
}
{
int i;
labcomm_scheduler_data_lock(d->scheduler);
LABCOMM_SIGNATURE_ARRAY_FOREACH(d->local, struct sample_entry, i) {
struct sample_entry *s;
int *remote_to_local;
result = -ENOENT;
s = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
d->local, struct sample_entry, i);
if (s->signature &&
s->signature->type == signature.type &&
s->signature->size == signature.size &&
strcmp(s->signature->name, signature.name) == 0 &&
bcmp((void*)s->signature->signature, (void*)signature.signature,
signature.size) == 0) {
s->remote_index = remote_index;
local_signature = s->signature;
local_index = i;
remote_to_local = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
d->remote_to_local, int,
remote_index);
*remote_to_local = i;
result = remote_index;
break;
}
}
labcomm_scheduler_data_unlock(d->scheduler);
if (local_signature) {
labcomm_reader_start(d->reader, d->reader->action_context,
local_index, remote_index, local_signature,
NULL);
labcomm_reader_end(d->reader, d->reader->action_context);
}
}
#if 0
if (! entry) {
/* Unknown datatype, bail out */
d->on_new_datatype(d, &signature);
result = -ENOENT;
} else if (entry->index && entry->index != remote_index) {
d->on_error(LABCOMM_ERROR_DEC_INDEX_MISMATCH, 5,
"%s(): index mismatch '%s' (id=0x%x != 0x%x)\n",
__FUNCTION__, signature.name, entry->index, remote_index);
result = -ENOENT;
#endif
free_signature_name:
labcomm_memory_free(d->memory, 0, signature.name);
labcomm_writer_free(&writer, writer.action_context);
return result;
}
struct call_handler_context {
struct labcomm_reader *reader;
int local_index;
int remote_index;
struct labcomm_signature *signature;
labcomm_handler_function handler;
void *context;
};
static void call_handler(void *value, void *context)
{
struct call_handler_context *wrap = context;
if (wrap->reader->error >= 0) {
labcomm_reader_start(wrap->reader, wrap->reader->action_context,
wrap->local_index, wrap->remote_index, wrap->signature,
value);
wrap->handler(value, wrap->context);
labcomm_reader_end(wrap->reader, wrap->reader->action_context);
}
}
static void reader_alloc(struct labcomm_decoder *d)
{
if (!d->reader_allocated) {
d->reader_allocated = 1;
labcomm_reader_alloc(d->reader, d->reader->action_context,
LABCOMM_VERSION);
}
}
int labcomm_decoder_decode_one(struct labcomm_decoder *d)
{
int result, remote_index;
reader_alloc(d);
remote_index = labcomm_read_packed32(d->reader);
if (d->reader->error < 0) {
result = d->reader->error;
goto out;
}
if (remote_index == LABCOMM_TYPEDEF || remote_index == LABCOMM_SAMPLE) {
result = decode_typedef_or_sample(d, remote_index);
} else {
int *local_index;
struct call_handler_context wrap = {
.reader = d->reader,
.remote_index = remote_index,
.signature = NULL,
.handler = NULL,
.context = NULL,
};
labcomm_decoder_function do_decode = NULL;
labcomm_scheduler_data_lock(d->scheduler);
local_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
d->remote_to_local, int,
remote_index);
if (*local_index != 0) {
struct sample_entry *entry;
entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
d->local, struct sample_entry,
*local_index);
wrap.local_index = *local_index;
wrap.signature = entry->signature;
wrap.handler = entry->handler;
wrap.context = entry->context;
do_decode = entry->decode;
result = *local_index;
}
labcomm_scheduler_data_unlock(d->scheduler);
if (do_decode) {
do_decode(d->reader, call_handler, &wrap);
} else {
result = -ENOENT;
}
}
out:
return result;
}
void labcomm_decoder_run(struct labcomm_decoder *d)
{
while (labcomm_decoder_decode_one(d) > 0) {
}
}
int labcomm_decoder_ioctl(struct labcomm_decoder *d,
uint32_t action,
...)
{
int result;
va_list va;
va_start(va, action);
result = labcomm_reader_ioctl(d->reader,
d->reader->action_context,
0, 0, NULL, action, va);
va_end(va);
return result;
}
int labcomm_internal_decoder_ioctl(struct labcomm_decoder *d,
struct labcomm_signature *signature,
uint32_t action, va_list va)
{
int result;
int local_index, remote_index;
local_index = labcomm_signature_local_index(signature);
labcomm_scheduler_data_lock(d->scheduler);
remote_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
d->local,
struct sample_entry,
local_index)->remote_index;
labcomm_scheduler_data_unlock(d->scheduler);
result = labcomm_reader_ioctl(d->reader, d->reader->action_context,
local_index, remote_index,
signature, action, va);
return result;
}
int labcomm_internal_decoder_register(
struct labcomm_decoder *d,
struct labcomm_signature *signature,
labcomm_decoder_function decode,
labcomm_handler_function handler,
void *context)
{
int local_index;
struct sample_entry *entry;
reader_alloc(d);
local_index = labcomm_signature_local_index(signature);
if (local_index <= 0) { goto out; }
labcomm_reader_start(d->reader, d->reader->action_context,
local_index, 0, signature,
NULL);
labcomm_reader_end(d->reader, d->reader->action_context);
labcomm_scheduler_data_lock(d->scheduler);
entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
d->local, struct sample_entry,
local_index);
if (entry == NULL) { local_index = -ENOMEM; goto unlock; }
entry->remote_index = 0;
entry->signature = signature;
entry->decode = decode;
entry->handler = handler;
entry->context = context;
unlock:
labcomm_scheduler_data_unlock(d->scheduler);
out:
return local_index;
}
/*
labcomm_encoder.c -- handling encoding 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/>.
*/
#define LABCOMM_VERSION "LabComm2013"
#include <errno.h>
#include "labcomm.h"
#include "labcomm_signature.h"
#include "labcomm_private.h"
#include "labcomm_ioctl.h"
struct labcomm_encoder {
struct labcomm_writer *writer;
struct labcomm_error_handler *error;
struct labcomm_memory *memory;
struct labcomm_scheduler *scheduler;
LABCOMM_SIGNATURE_ARRAY_DEF(registered, int);
};
struct labcomm_encoder *labcomm_encoder_new(
struct labcomm_writer *writer,
struct labcomm_error_handler *error,
struct labcomm_memory *memory,
struct labcomm_scheduler *scheduler)
{
struct labcomm_encoder *result;
result = labcomm_memory_alloc(memory, 0, sizeof(*result));
if (result) {
result->writer = writer;
result->writer->encoder = result;
result->writer->data = NULL;
result->writer->data_size = 0;
result->writer->count = 0;
result->writer->pos = 0;
result->writer->error = 0;
result->error = error;
result->memory = memory;
result->scheduler = scheduler;
LABCOMM_SIGNATURE_ARRAY_INIT(result->registered, int);
labcomm_writer_alloc(result->writer,
result->writer->action_context, LABCOMM_VERSION);
}
return result;
}
void labcomm_encoder_free(struct labcomm_encoder* e)
{
struct labcomm_memory *memory = e->memory;
labcomm_writer_free(e->writer, e->writer->action_context);
LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, e->registered, int);
labcomm_memory_free(memory, 0, e);
}
int labcomm_internal_encoder_register(
struct labcomm_encoder *e,
struct labcomm_signature *signature,
labcomm_encoder_function encode)
{
int result = -EINVAL;
int index, *done, err, i;
index = labcomm_signature_local_index(signature);
labcomm_scheduler_writer_lock(e->scheduler);
if (signature->type != LABCOMM_SAMPLE) { goto out; }
if (index <= 0) { goto out; }
done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->registered, int, index);
if (*done) { goto out; }
*done = 1;
err = labcomm_writer_start(e->writer, e->writer->action_context,
index, signature, NULL);
if (err == -EALREADY) { result = 0; goto out; }
if (err != 0) { result = err; goto out; }
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) {
labcomm_writer_flush(e->writer, e->writer->action_context);
}
e->writer->data[e->writer->pos] = signature->signature[i];
e->writer->pos++;
}
labcomm_writer_end(e->writer, e->writer->action_context);
result = e->writer->error;
out:
labcomm_scheduler_writer_unlock(e->scheduler);
return result;
}
int labcomm_internal_encode(
struct labcomm_encoder *e,
struct labcomm_signature *signature,
labcomm_encoder_function encode,
void *value)
{
int result;
int index;
index = labcomm_signature_local_index(signature);
labcomm_scheduler_writer_lock(e->scheduler);
result = labcomm_writer_start(e->writer, e->writer->action_context,
index, signature, value);
if (result == -EALREADY) { result = 0; goto no_end; }
if (result != 0) { goto out; }
result = labcomm_write_packed32(e->writer, index);
if (result != 0) { goto out; }
result = encode(e->writer, value);
out:
labcomm_writer_end(e->writer, e->writer->action_context);
no_end:
labcomm_scheduler_writer_unlock(e->scheduler);
return result;
}
int labcomm_encoder_ioctl(struct labcomm_encoder *encoder,
uint32_t action,
...)
{
int result;
va_list va;
if (LABCOMM_IOC_SIG(action) != LABCOMM_IOC_NOSIG) {
result = -EINVAL;
goto out;
}
va_start(va, action);
result = labcomm_writer_ioctl(encoder->writer,
encoder->writer->action_context,
0, NULL, action, va);
va_end(va);
out:
return result;
}
int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
struct labcomm_signature *signature,
uint32_t action, va_list va)
{
int result = -ENOTSUP;
int index;
index = labcomm_signature_local_index(signature);
result = labcomm_writer_ioctl(encoder->writer,
encoder->writer->action_context,
index, signature, action, va);
return result;
}
/*
labcomm_error.h -- labcomm error declarations
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/>.
*/
#ifndef __LABCOMM_ERROR_H__
#define __LABCOMM_ERROR_H__
enum labcomm_error {
#define LABCOMM_ERROR(name, description) name ,
#include "labcomm_error.h"
#undef LABCOMM_ERROR
};
struct labcomm_error_handler;
#endif
#ifdef LABCOMM_ERROR
LABCOMM_ERROR(LABCOMM_ERROR_ENC_NO_REG_SIGNATURE,
"Encoder has no registration for this signature")
LABCOMM_ERROR(LABCOMM_ERROR_ENC_BUF_FULL,
"The labcomm buffer is full")
LABCOMM_ERROR(LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE,
"Decoder: Unknown datatype")
LABCOMM_ERROR(LABCOMM_ERROR_DEC_INDEX_MISMATCH,
"Decoder: index mismatch")
LABCOMM_ERROR(LABCOMM_ERROR_DEC_TYPE_NOT_FOUND,
"Decoder: type not found")
LABCOMM_ERROR(LABCOMM_ERROR_UNIMPLEMENTED_FUNC,
"This function is not yet implemented")
LABCOMM_ERROR(LABCOMM_ERROR_MEMORY,
"Could not allocate memory")
LABCOMM_ERROR(LABCOMM_ERROR_USER_DEF,
"User defined error")
#endif
/*
labcomm_signature.h -- signature handling.
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 "labcomm.h"
int labcomm_signature_local_index(struct labcomm_signature *s);
INPUT(liblabcomm.so.1)
/* Hack to get a link error with (hopefully) useful information if not linked
with -Tlabcomm.linkscript */
"You need to link with '-Tlabcomm.linkscript'"+=1;
/*INPUT(liblabcomm.a)*/
## Macros
UNAME_S=$(shell uname -s)
VERSION=2014
LIBVERSION=2014
ifeq ($(UNAME_S),Linux)
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)gcc
CFLAGS=-std=c99 -g -Wall -Werror -O3 -I.
CFLAGS_TEST=$(CFLAGS) -Itest
LDFLAGS=-L..
LDLIBS=-llabcomm$(LIBVERSION) -lrt
LD_LIBRARY_PATH_NAME=LD_LIBRARY_PATH
MAKESHARED=gcc -o $1 -shared -Wl,-soname,$2 $3 -lc -lrt
else ifeq ($(UNAME_S),Darwin)
#CC=$(CROSS_COMPILE)clang
#LD=$(CROSS_COMPILE)ld
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)gcc
CFLAGS=-g -Wall -Werror -O3 -I. -Itest \
-DLABCOMM_COMPAT=\"labcomm$(VERSION)_compat_osx.h\" \
-DLABCOMM_OS_DARWIN=1 \
-Wno-unused-function
# -Wno-tautological-compare
CFLAGS+=-std=c99
LDFLAGS=-L..
LDLIBS=-llabcomm$(LIBVERSION)
LD_LIBRARY_PATH_NAME=DYLD_LIBRARY_PATH
MAKESHARED=clang -o $1 -shared -Wl,-install_name,$2 $3 -lc
else ifneq ($(findstring CYGWIN,$(UNAME_S)),)
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
CFLAGS=-std=c99 -g -Wall -Werror -O3 -I.
LDFLAGS=-L..
LDLIBS=-llabcomm$(LIBVERSION) -lrt
ALL_DEPS:=$(filter-out %.so.1, $(ALL_DEPS)) # No -fPIC supported in windows?
else
$(error Unknown system $(UNAME_S))
endif
CFLAGS_TEST=$(CFLAGS) -Itest -DVERSION=$(VERSION)
ifeq ($(CROSS_COMPILE),i586-wrs-vxworks-)
ALL_DEPS:=$(filter-out %.so.1, $(ALL_DEPS)) # PIC is only supported for RTPs
CFLAGS:=$(CFLAGS) -DLABCOMM_COMPAT=\"labcomm_compat_vxworks.h\"
endif