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
Anders Blomdell
LabComm
Commits
76407049
Commit
76407049
authored
May 21, 2015
by
Anders Blomdell
Browse files
Implementation of renaming encoder. Typedef trees are not correctly encoded!
parent
732bf4bf
Changes
6
Hide whitespace changes
Inline
Side-by-side
lib/c/2014/Makefile
View file @
76407049
...
...
@@ -20,9 +20,11 @@ OBJS=labcomm$(VERSION).o \
labcomm
$(VERSION)
_decoder.o
\
labcomm
$(VERSION)
_dynamic_buffer_writer.o
\
labcomm
$(VERSION)
_fd_reader.o
\
labcomm
$(VERSION)
_type_signature.o
\
labcomm
$(VERSION)
_type_signature.o
\
labcomm
$(VERSION)
_fd_writer.o
\
labcomm
$(VERSION)
_pthread_scheduler.o
labcomm
$(VERSION)
_pthread_scheduler.o
\
labcomm
$(VERSION)
_renaming.o
\
labcomm
$(VERSION)
_renaming_encoder.o
# Enable experimental objects by `make LABCOMM_EXPERIMENTAL=true`
ifeq
($(LABCOMM_EXPERIMENTAL),true)
...
...
@@ -46,7 +48,8 @@ TESTS=test_labcomm_basic_type_encoding \
test_signature_numbers
\
test_labcomm
\
test_labcomm_pthread_scheduler
\
test_labcomm_copy
test_labcomm_copy
\
test_labcomm_renaming
#FIXME: test_labcomm_errors
TEST_DIR
=
test
...
...
@@ -169,3 +172,6 @@ $(TEST_DIR)/gen/test_labcomm_copy: \
$(TEST_DIR)/gen/generated_encoding.o
\
$(TEST_DIR)/gen/test_sample.o
\
$(TEST_DIR)/gen/more_types.o
$(TEST_DIR)/gen/test_labcomm_renaming
:
\
$(TEST_DIR)/gen/generated_encoding.o
lib/c/2014/labcomm2014_renaming.c
0 → 100644
View file @
76407049
/*
labcomm2014_renaming.c -- functions intended for renaming
encoders and decoders
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
"labcomm2014_renaming.h"
#include
<string.h>
#include
<stdio.h>
char
*
labcomm2014_renaming_prefix
(
struct
labcomm2014_memory
*
m
,
char
*
name
,
void
*
context
)
{
char
*
result
,
*
prefix
=
context
;
int
length
;
length
=
strlen
(
name
)
+
strlen
(
prefix
)
+
1
;
result
=
labcomm2014_memory_alloc
(
m
,
0
,
length
);
if
(
result
!=
NULL
)
{
strcpy
(
result
,
prefix
);
strcat
(
result
,
name
);
}
fprintf
(
stderr
,
"%s + %s -> %s
\n
"
,
prefix
,
name
,
result
);
return
result
;
}
char
*
labcomm2014_renaming_suffix
(
struct
labcomm2014_memory
*
m
,
char
*
name
,
void
*
context
)
{
return
labcomm2014_renaming_prefix
(
m
,
context
,
name
);
}
lib/c/2014/labcomm2014_renaming.h
0 → 100644
View file @
76407049
/*
labcomm2014_renaming.h -- functions intended for renaming
encoders and decoders
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/>.
*/
#ifndef __LABCOMM2014_RENAMING_H__
#define __LABCOMM2014_RENAMING_H__
#include
"labcomm2014.h"
char
*
labcomm2014_renaming_prefix
(
struct
labcomm2014_memory
*
m
,
char
*
name
,
void
*
context
);
char
*
labcomm2014_renaming_suffix
(
struct
labcomm2014_memory
*
m
,
char
*
name
,
void
*
context
);
#endif
lib/c/2014/labcomm2014_renaming_encoder.c
0 → 100644
View file @
76407049
/*
labcomm2014_renaming_encoder.c -- a stacked encoder that renames samples
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
<errno.h>
#include
"labcomm2014_renaming_encoder.h"
#include
"labcomm2014.h"
#include
"labcomm2014_private.h"
struct
encoder
{
struct
labcomm2014_encoder
encoder
;
struct
labcomm2014_encoder
*
next
;
char
*
(
*
rename
)(
struct
labcomm2014_memory
*
m
,
char
*
name
,
void
*
context
);
void
*
context
;
LABCOMM_SIGNATURE_ARRAY_DEF
(
renamed
,
struct
labcomm2014_signature
*
);
};
static
struct
labcomm2014_signature
*
get_renamed
(
struct
labcomm2014_encoder
*
e
,
const
struct
labcomm2014_signature
*
signature
)
{
struct
labcomm2014_signature
*
result
;
struct
encoder
*
ie
=
e
->
context
;
int
index
;
index
=
labcomm2014_get_local_index
(
signature
);
labcomm2014_scheduler_writer_lock
(
e
->
scheduler
);
result
=
LABCOMM_SIGNATURE_ARRAY_GET
(
ie
->
renamed
,
struct
labcomm2014_signature
*
,
index
,
NULL
);
labcomm2014_scheduler_writer_unlock
(
e
->
scheduler
);
return
result
;
}
static
struct
labcomm2014_signature
*
set_renamed
(
struct
labcomm2014_encoder
*
e
,
const
struct
labcomm2014_signature
*
signature
)
{
struct
labcomm2014_signature
*
result
;
result
=
get_renamed
(
e
,
signature
);
if
(
result
==
NULL
)
{
/* create a renamed sample */
struct
encoder
*
ie
=
e
->
context
;
int
index
;
struct
labcomm2014_signature
**
renamed
;
index
=
labcomm2014_get_local_index
(
signature
);
if
(
index
<=
0
)
{
goto
out
;
/*result already NULL */
}
labcomm2014_scheduler_writer_lock
(
e
->
scheduler
);
renamed
=
LABCOMM_SIGNATURE_ARRAY_REF
(
e
->
memory
,
ie
->
renamed
,
struct
labcomm2014_signature
*
,
index
);
if
(
renamed
==
NULL
)
{
labcomm2014_error_warning
(
e
->
error
,
LABCOMM2014_ERROR_MEMORY
,
"Could not allocate rename slot: %s
\n
"
,
signature
->
name
);
goto
unlock
;
}
if
(
*
renamed
!=
NULL
)
{
/* Somebody beat as to allocation, this should never happen */
goto
unlock
;
}
result
=
labcomm2014_memory_alloc
(
e
->
memory
,
0
,
sizeof
(
*
result
));
if
(
result
==
NULL
)
{
labcomm2014_error_warning
(
e
->
error
,
LABCOMM2014_ERROR_MEMORY
,
"Could not allocate rename signature: %s
\n
"
,
signature
->
name
);
goto
unlock
;
}
result
->
name
=
ie
->
rename
(
e
->
memory
,
signature
->
name
,
ie
->
context
);
if
(
result
->
name
==
NULL
)
{
labcomm2014_error_warning
(
e
->
error
,
LABCOMM2014_ERROR_MEMORY
,
"Could not allocate rename name: %s
\n
"
,
signature
->
name
);
goto
unlock_free_result
;
}
result
->
encoded_size
=
signature
->
encoded_size
;
result
->
size
=
signature
->
size
;
result
->
signature
=
signature
->
signature
;
result
->
index
=
0
;
#ifndef LABCOMM_NO_TYPEDECL
result
->
tdsize
=
signature
->
tdsize
;
result
->
treedata
=
signature
->
treedata
;
#endif
labcomm2014_set_local_index
(
result
);
*
renamed
=
result
;
goto
unlock
;
unlock_free_result:
labcomm2014_memory_free
(
e
->
memory
,
0
,
result
);
result
=
NULL
;
unlock:
labcomm2014_scheduler_writer_unlock
(
e
->
scheduler
);
out:
;
}
return
result
;
}
static
int
do_type_register
(
struct
labcomm2014_encoder
*
e
,
const
struct
labcomm2014_signature
*
signature
)
{
struct
encoder
*
ie
=
e
->
context
;
return
ie
->
next
->
type_register
(
ie
->
next
,
set_renamed
(
e
,
signature
));
}
static
int
do_type_bind
(
struct
labcomm2014_encoder
*
e
,
const
struct
labcomm2014_signature
*
signature
,
char
has_deps
)
{
struct
encoder
*
ie
=
e
->
context
;
return
ie
->
next
->
type_bind
(
ie
->
next
,
set_renamed
(
e
,
signature
),
has_deps
);
}
static
int
do_sample_register
(
struct
labcomm2014_encoder
*
e
,
const
struct
labcomm2014_signature
*
signature
,
labcomm2014_encoder_function
encode
)
{
struct
encoder
*
ie
=
e
->
context
;
return
ie
->
next
->
sample_register
(
ie
->
next
,
set_renamed
(
e
,
signature
),
encode
);
}
static
int
do_ref_register
(
struct
labcomm2014_encoder
*
e
,
const
struct
labcomm2014_signature
*
signature
)
{
struct
encoder
*
ie
=
e
->
context
;
return
ie
->
next
->
ref_register
(
ie
->
next
,
set_renamed
(
e
,
signature
));
}
static
int
do_encode
(
struct
labcomm2014_encoder
*
e
,
const
struct
labcomm2014_signature
*
signature
,
labcomm2014_encoder_function
encode
,
void
*
value
)
{
struct
encoder
*
ie
=
e
->
context
;
return
ie
->
next
->
encode
(
ie
->
next
,
get_renamed
(
e
,
signature
),
encode
,
value
);
}
static
int
do_ioctl
(
struct
labcomm2014_encoder
*
e
,
const
struct
labcomm2014_signature
*
signature
,
uint32_t
ioctl_action
,
va_list
args
)
{
struct
encoder
*
ie
=
e
->
context
;
return
ie
->
next
->
ioctl
(
ie
->
next
,
get_renamed
(
e
,
signature
),
ioctl_action
,
args
);
}
static
int
do_signature_to_index
(
struct
labcomm2014_encoder
*
e
,
const
struct
labcomm2014_signature
*
signature
)
{
struct
encoder
*
ie
=
e
->
context
;
return
ie
->
next
->
signature_to_index
(
ie
->
next
,
get_renamed
(
e
,
signature
));
}
static
void
do_free
(
struct
labcomm2014_encoder
*
e
)
{
struct
encoder
*
ie
=
e
->
context
;
int
i
;
LABCOMM_SIGNATURE_ARRAY_FOREACH
(
ie
->
renamed
,
struct
labcomm2014_signature
*
,
i
)
{
struct
labcomm2014_signature
*
s
;
s
=
LABCOMM_SIGNATURE_ARRAY_GET
(
ie
->
renamed
,
struct
labcomm2014_signature
*
,
i
,
NULL
);
if
(
s
)
{
labcomm2014_memory_free
(
e
->
memory
,
0
,
s
->
name
);
labcomm2014_memory_free
(
e
->
memory
,
0
,
s
);
}
}
LABCOMM_SIGNATURE_ARRAY_FREE
(
e
->
memory
,
ie
->
renamed
,
struct
labcomm2014_signature
*
);
labcomm2014_memory_free
(
e
->
memory
,
0
,
ie
);
}
struct
labcomm2014_encoder
*
labcomm2014_renaming_encoder_new
(
struct
labcomm2014_encoder
*
e
,
char
*
(
*
rename
)(
struct
labcomm2014_memory
*
m
,
char
*
name
,
void
*
context
),
void
*
context
)
{
struct
encoder
*
result
;
result
=
labcomm2014_memory_alloc
(
e
->
memory
,
0
,
sizeof
(
*
result
));
if
(
!
result
)
{
return
NULL
;
}
else
{
result
->
encoder
.
context
=
result
;
result
->
encoder
.
writer
=
NULL
;
result
->
encoder
.
error
=
e
->
error
;
result
->
encoder
.
memory
=
e
->
memory
;
result
->
encoder
.
scheduler
=
e
->
scheduler
;
result
->
encoder
.
free
=
do_free
;
result
->
encoder
.
type_register
=
do_type_register
;
result
->
encoder
.
type_bind
=
do_type_bind
;
result
->
encoder
.
sample_register
=
do_sample_register
;
result
->
encoder
.
ref_register
=
do_ref_register
;
result
->
encoder
.
encode
=
do_encode
;
result
->
encoder
.
ioctl
=
do_ioctl
;
result
->
encoder
.
signature_to_index
=
do_signature_to_index
;
result
->
next
=
e
;
result
->
rename
=
rename
;
result
->
context
=
context
;
LABCOMM_SIGNATURE_ARRAY_INIT
(
result
->
renamed
,
struct
labcomm2014_signature
*
);
return
&
(
result
->
encoder
);
}
}
lib/c/2014/labcomm2014_renaming_encoder.h
0 → 100644
View file @
76407049
/*
labcomm2014_renaming_encoder.h -- a stacked encoder that renames samples
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/>.
*/
#ifndef __LABCOMM2014_RENAMING_ENCODER_H__
#define __LABCOMM2014_RENAMING_ENCODER_H__
#include
"labcomm2014.h"
struct
labcomm2014_encoder
*
labcomm2014_renaming_encoder_new
(
struct
labcomm2014_encoder
*
e
,
char
*
(
*
rename
)(
struct
labcomm2014_memory
*
m
,
char
*
name
,
void
*
context
),
void
*
context
);
#endif
lib/c/2014/test/test_labcomm_renaming.c
0 → 100644
View file @
76407049
/*
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_pthread_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 (%d: != %d)
\n
"
,
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
++
)
{
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
"
);
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
"
);
}
int
main
(
void
)
{
struct
labcomm2014_encoder
*
encoder
,
*
prefix
,
*
suffix
;
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
seen_variable
)
/
sizeof
(
seen_variable
[
0
])
;
i
++
)
{
seen_variable
[
i
]
=
-
1
;
}
encoder
=
labcomm2014_encoder_new
(
&
buffer_writer
,
labcomm2014_default_error_handler
,
labcomm2014_default_memory
,
labcomm2014_pthread_scheduler_new
(
labcomm2014_default_memory
));
prefix
=
labcomm2014_renaming_encoder_new
(
encoder
,
labcomm2014_renaming_prefix
,
"p."
);
suffix
=
labcomm2014_renaming_encoder_new
(
prefix
,
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
,
0x06
,
VARIABLE
(
0
),
0x01
,
'V'
,
0x02
,
0x11
,
0x00
,
0x04
,
0x08
,
VARIABLE
(
1
),
0x03
,
'v'
,
'_'
,
't'
,
0x02
,
0x11
,
0x00
,
0x04
,
0x05
,
VARIABLE
(
2
),
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
);