Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rosidl_generator_c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ if(BUILD_TESTING)

rosidl_generate_interfaces(${PROJECT_NAME}_interfaces
${test_interface_files_MSG_FILES}
${test_interface_files_IDL_FILES}
ADD_LINTER_TESTS
SKIP_INSTALL
)
Expand Down
103 changes: 101 additions & 2 deletions rosidl_generator_c/resource/msg__functions.c.em
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ from rosidl_parser.definition import AbstractWString
from rosidl_parser.definition import Array
from rosidl_parser.definition import BasicType
from rosidl_parser.definition import AbstractGenericString
from rosidl_parser.definition import EnumerationType
from rosidl_parser.definition import NamespacedType
from rosidl_generator_c import basetype_to_c
from rosidl_generator_c import idl_enumeration_type_to_c_typename
from rosidl_generator_c import idl_enumeration_type_sequence_to_c_typename
from rosidl_generator_c import idl_structure_type_sequence_to_c_typename
from rosidl_generator_c import idl_structure_type_to_c_include_prefix
from rosidl_generator_c import idl_structure_type_to_c_typename
Expand Down Expand Up @@ -69,6 +72,102 @@ for member in message.structure.members:
@[ end for]@
@[end if]@
@#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@#######################################################################
@# message enums functions
@#######################################################################
@[for enum in message.enumerations]@
@{
__enum_typename = idl_enumeration_type_to_c_typename(enum.enumeration_type)
__enum_sequence_typename = idl_enumeration_type_sequence_to_c_typename(enum.enumeration_type)
}@
bool
@(__enum_sequence_typename)__init(@(__enum_sequence_typename) * sequence, size_t size)
{
if (!sequence) {
return false;
}

rcutils_allocator_t allocator = rcutils_get_default_allocator();
@(__enum_typename) * data = NULL;

if (size) {
data = (@(__enum_typename) *)allocator.zero_allocate(size, sizeof(@(__enum_typename)), allocator.state);
if (!data) {
return false;
}
}

sequence->data = data;
sequence->size = size;
sequence->capacity = size;
return true;
}

void
@(__enum_sequence_typename)__fini(@(__enum_sequence_typename) * sequence)
{
if (!sequence) {
return;
}
if (sequence->data) {
/* ensure that data and capacity values are consistent */
assert(sequence->capacity > 0);
free(sequence->data);
sequence->data = NULL;
sequence->size = 0;
sequence->capacity = 0;
} else {
/* ensure that data, size, and capacity values are consistent */
assert(0 == sequence->size);
assert(0 == sequence->capacity);
}
}

bool
@(__enum_sequence_typename)__are_equal(const @(__enum_sequence_typename) * lhs, const @(__enum_sequence_typename) * rhs)
{
if (!lhs || !rhs) {
return false;
}
if (lhs->size != rhs->size) {
return false;
}
for (size_t i = 0; i < lhs->size; ++i) {
if (lhs->data[i] != rhs->data[i]) {
return false;
}
}
return true;
}

bool
@(__enum_sequence_typename)__copy(
const @(__enum_sequence_typename) * input,
@(__enum_sequence_typename) * output)
{
if (!input || !output) {
return false;
}
if (output->capacity < input->size) {
const size_t allocation_size =
input->size * sizeof(@(__enum_typename));
rcutils_allocator_t allocator = rcutils_get_default_allocator();
@(__enum_typename) * data =
(@(__enum_typename) *)allocator.reallocate(
output->data, allocation_size, allocator.state);
if (!data) {
return false;
}
output->data = data;
output->size = input->size;
output->capacity = input->size;
}
for (size_t i = 0; i < input->size; ++i) {
output->data[i] = input->data[i];
}
return true;
}
@[ end for]@

@#######################################################################
@# message functions
Expand Down Expand Up @@ -185,7 +284,7 @@ for member in message.structure.members:
last_label_index += 1
lines.append(' }')
lines.append('}')
elif isinstance(member.type, BasicType):
elif isinstance(member.type, (BasicType, EnumerationType)):
if member.has_annotation('default'):
# set default value of primitive type
lines.append('msg->%s = %s;' % (member.name, value_to_c(member.type, member.get_annotation_value('default')['value'])))
Expand Down Expand Up @@ -224,7 +323,7 @@ for member in message.structure.members:
elif isinstance(member.type, AbstractSequence):
# finalize the dynamic array
lines.append('%s__fini(&msg->%s);' % (idl_type_to_c(member.type), member.name))
elif not isinstance(member.type, BasicType):
elif not isinstance(member.type, (BasicType, EnumerationType)):
# finalize non-array sub messages and strings
lines.append('%s__fini(&msg->%s);' % (basetype_to_c(member.type), member.name))
for line in lines:
Expand Down
59 changes: 59 additions & 0 deletions rosidl_generator_c/resource/msg__functions.h.em
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@# Included from rosidl_generator_c/resource/idl__functions.h.em
@{
from rosidl_generator_c import idl_enumeration_type_sequence_to_c_typename
from rosidl_generator_c import idl_enumeration_type_to_c_typename
from rosidl_generator_c import idl_structure_type_sequence_to_c_typename
from rosidl_generator_c import idl_structure_type_to_c_typename
from rosidl_generator_c import interface_path_to_string
Expand Down Expand Up @@ -165,3 +167,60 @@ bool
@(array_typename)__copy(
const @(array_typename) * input,
@(array_typename) * output);

@#######################################################################
@# message enums functions
@#######################################################################
@[for enum in message.enumerations]@
@{
__enum_typename = idl_enumeration_type_to_c_typename(enum.enumeration_type)
__enum_sequence_typename = idl_enumeration_type_sequence_to_c_typename(enum.enumeration_type)
}@
/// Initialize sequence of @(__enum_typename).
/**
* It allocates the memory for the number of elements.
* \param[in,out] sequence The allocated sequence pointer.
* \param[in] size The size / capacity of the sequence.
* \return true if initialization was successful, otherwise false
* If the sequence pointer is valid and the size is zero it is guaranteed
# to return true.
*/
ROSIDL_GENERATOR_C_PUBLIC_@(package_name)
bool
@(__enum_sequence_typename)__init(@(__enum_sequence_typename) * sequence, size_t size);

/// Finalize sequence of @(__enum_typename).
/**
* \param[in,out] sequence The allocated sequence pointer.
*/
ROSIDL_GENERATOR_C_PUBLIC_@(package_name)
void
@(__enum_sequence_typename)__fini(@(__enum_sequence_typename) * sequence);

/// Check for @(__enum_typename) array equality.
/**
* \param[in] lhs The array on the left hand side of the equality operator.
* \param[in] rhs The array on the right hand side of the equality operator.
* \return true if message arrays are equal in size and content, otherwise false.
*/
ROSIDL_GENERATOR_C_PUBLIC_@(package_name)
bool
@(__enum_sequence_typename)__are_equal(const @(__enum_sequence_typename) * lhs, const @(__enum_sequence_typename) * rhs);

/// Copy an array of @(__enum_typename).
/**
* This function performs a deep copy, as opposed to the shallow copy that
* plain assignment yields.
*
* \param[in] input The source array pointer.
* \param[out] output The target array pointer, which must
* have been initialized before calling this function.
* \return true if successful, or false if either pointer
* is null or memory allocation fails.
*/
ROSIDL_GENERATOR_C_PUBLIC_@(package_name)
bool
@(__enum_sequence_typename)__copy(
const @(__enum_sequence_typename) * input,
@(__enum_sequence_typename) * output);
@[ end for]@
27 changes: 27 additions & 0 deletions rosidl_generator_c/resource/msg__struct.h.em
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ from rosidl_parser.definition import BasicType
from rosidl_parser.definition import BOOLEAN_TYPE
from rosidl_parser.definition import BoundedSequence
from rosidl_parser.definition import CHARACTER_TYPES
from rosidl_parser.definition import EnumerationType
from rosidl_parser.definition import FLOATING_POINT_TYPES
from rosidl_parser.definition import INTEGER_TYPES
from rosidl_parser.definition import NamespacedType
from rosidl_parser.definition import OCTET_TYPE
from rosidl_generator_c import basetype_to_c
from rosidl_generator_c import idl_declaration_to_c
from rosidl_generator_c import idl_enumeration_type_to_c_typename
from rosidl_generator_c import idl_enumeration_type_sequence_to_c_typename
from rosidl_generator_c import idl_structure_type_sequence_to_c_typename
from rosidl_generator_c import idl_structure_type_to_c_include_prefix
from rosidl_generator_c import idl_structure_type_to_c_typename
Expand Down Expand Up @@ -140,6 +143,30 @@ enum
@[end if]@
@#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


@#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// Enums defined in the message
@[for enum in message.enumerations]@
// Enum defined in @(interface_path_to_string(interface_path)) in the package @(package_name).
typedef enum @(idl_enumeration_type_to_c_typename(enum.enumeration_type))
{
@[for enumerator in enum.enumerators]@
@(enumerator),
@[end for]@
} @(idl_enumeration_type_to_c_typename(enum.enumeration_type));

// Struct for a sequence of @(idl_enumeration_type_to_c_typename(enum.enumeration_type)).
typedef struct @(idl_enumeration_type_sequence_to_c_typename(enum.enumeration_type))
{
@(idl_enumeration_type_to_c_typename(enum.enumeration_type)) * data;
/// The number of valid items in data
size_t size;
/// The number of allocated items in data
size_t capacity;
} @(idl_enumeration_type_sequence_to_c_typename(enum.enumeration_type));
@[ end for]@
@#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

@#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/// Struct defined in @(interface_path_to_string(interface_path)) in the package @(package_name).
@{comments = message.structure.get_comment_lines()}@
Expand Down
14 changes: 14 additions & 0 deletions rosidl_generator_c/rosidl_generator_c/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from rosidl_parser.definition import Array
from rosidl_parser.definition import BasicType
from rosidl_parser.definition import CHARACTER_TYPES
from rosidl_parser.definition import EnumerationType
from rosidl_parser.definition import NamespacedType
from rosidl_parser.definition import OCTET_TYPE

Expand Down Expand Up @@ -69,6 +70,14 @@ def prefix_with_bom_if_necessary(content):
}


def idl_enumeration_type_to_c_typename(enumeration_type):
return '__'.join(enumeration_type.namespaced_name())


def idl_enumeration_type_sequence_to_c_typename(enumeration_type):
return idl_enumeration_type_to_c_typename(enumeration_type) + '__Sequence'


def idl_structure_type_to_c_include_prefix(namespaced_type, subdirectory=None):
parts = [
convert_camel_case_to_lower_case_underscore(x)
Expand Down Expand Up @@ -148,6 +157,8 @@ def basetype_to_c(basetype):
return 'rosidl_runtime_c__U16String'
if isinstance(basetype, NamespacedType):
return idl_structure_type_to_c_typename(basetype)
if isinstance(basetype, EnumerationType):
return idl_enumeration_type_to_c_typename(basetype)
assert False, str(basetype)


Expand All @@ -161,6 +172,9 @@ def value_to_c(type_, value):
if isinstance(type_, AbstractWString):
return 'u"%s"' % escape_wstring(value)

if isinstance(type_, EnumerationType):
return '%s' % value

return basic_value_to_c(type_, value)


Expand Down
Loading