From 50233da38d16eecac393403a9993a9488b2b4383 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sat, 11 Jul 2015 10:46:15 +0300 Subject: [PATCH] Support for void fields --- .../libuavcan_dsdl_compiler/__init__.py | 19 ++++++++++ .../data_type_template.tmpl | 35 ++++++++++--------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/__init__.py b/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/__init__.py index a7a18bab9f..04c2f3bf91 100644 --- a/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/__init__.py +++ b/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/__init__.py @@ -158,6 +158,8 @@ def type_to_cpp_type(t): return '::uavcan::Array< %s, %s, %d >' % (value_type, mode, t.max_size) elif t.category == t.CATEGORY_COMPOUND: return '::' + t.full_name.replace('.', '::') + elif t.category == t.CATEGORY_VOID: + return '::uavcan::IntegerSpec< %d, ::uavcan::SignednessUnsigned, ::uavcan::CastModeSaturate >' % t.bitlen else: raise DsdlCompilerException('Unknown type category: %s' % t.category) @@ -186,8 +188,14 @@ def generate_one_type(template_expander, t): # Attribute types def inject_cpp_types(attributes): + void_index = 0 for a in attributes: a.cpp_type = type_to_cpp_type(a.type) + a.void = a.type.category == a.type.CATEGORY_VOID + if a.void: + assert not a.name + a.name = '_void_%d' % void_index + void_index += 1 if t.kind == t.KIND_MESSAGE: inject_cpp_types(t.fields) @@ -285,6 +293,17 @@ def make_template_expander(filename): def expand(**args): # This function adds one indentation level (4 spaces); it will be used from the template args['indent'] = lambda text, idnt = ' ': idnt + text.replace('\n', '\n' + idnt) + # This function works like enumerate(), telling you whether the current item is the last one + def enum_last_value(iterable, start=0): + it = iter(iterable) + count = start + last = next(it) + for val in it: + yield count, False, last + last = val + count += 1 + yield count, True, last + args['enum_last_value'] = enum_last_value return template(**args) return expand diff --git a/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/data_type_template.tmpl b/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/data_type_template.tmpl index f59577ca34..e7015d5ccb 100644 --- a/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/data_type_template.tmpl +++ b/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/data_type_template.tmpl @@ -64,8 +64,8 @@ struct UAVCAN_EXPORT ${t.cpp_type_name} { enum Type { - % for idx,a in enumerate(fields): - ${a.name}${',' if idx < (len(fields) - 1) else ''} + % for idx,last,a in enum_last_value(fields): + ${a.name}${',' if not last else ''} % endfor }; }; @@ -77,8 +77,8 @@ struct UAVCAN_EXPORT ${t.cpp_type_name} enum { ${enum_name} = TagType::BitLen + - % for idx,a in enumerate(fields): - % if idx < (len(fields) - 1): + % for idx,last,a in enum_last_value(fields): + % if not last: ::uavcan::${enum_comparator}::Result' * (len(fields) - 1)} @@ -113,7 +113,7 @@ struct UAVCAN_EXPORT ${t.cpp_type_name} % endfor // Fields - % for a in fields: + % for a in [x for x in fields if not x.void]: typename ::uavcan::StorageType< typename FieldTypes::${a.name} >::Type ${a.name}; % endfor @@ -125,7 +125,7 @@ public: % endif ${type_name}() - % for idx,a in enumerate(fields): + % for idx,a in enumerate([x for x in fields if not x.void]): ${':' if idx == 0 else ','} ${a.name}() % endfor % if union: @@ -166,7 +166,7 @@ public: */ template ${type_name}(const T& x) - % for idx,a in enumerate(fields): + % for idx,a in enumerate([x for x in fields if not x.void]): ${':' if idx == 0 else ','} ${a.name}() % endfor % if union: @@ -295,8 +295,8 @@ bool ${scope_prefix}<_tmpl>::operator==(ParameterType rhs) const % else: % if fields: return - % for idx,a in enumerate(fields): - ${a.name} == rhs.${a.name}${' &&' if (idx + 1) < len(fields) else ';'} + % for idx,last,a in enum_last_value([x for x in fields if not x.void]): + ${a.name} == rhs.${a.name}${' &&' if not last else ';'} % endfor % else: (void)rhs; @@ -324,8 +324,8 @@ bool ${scope_prefix}<_tmpl>::isClose(ParameterType rhs) const % else: % if fields: return - % for idx,a in enumerate(fields): - ::uavcan::areClose(${a.name}, rhs.${a.name})${' &&' if (idx + 1) < len(fields) else ';'} + % for idx,last,a in enum_last_value([x for x in fields if not x.void]): + ::uavcan::areClose(${a.name}, rhs.${a.name})${' &&' if not last else ';'} % endfor % else: (void)rhs; @@ -356,11 +356,14 @@ int ${scope_prefix}<_tmpl>::${call_name}(${self_parameter_type} self, ::uavcan:: % endfor return -1; // Invalid tag value % else: + % for a in [x for x in fields if x.void]: + typename ::uavcan::StorageType< typename FieldTypes::${a.name} >::Type ${a.name} = 0; + % endfor int res = 1; - % for idx,a in enumerate(fields): - res = FieldTypes::${a.name}::${call_name}(self.${a.name}, codec, \ -${'::uavcan::TailArrayOptDisabled' if (idx + 1) < len(fields) else 'tao_mode'}); - % if (idx + 1) < len(fields): + % for idx,last,a in enum_last_value(fields): + res = FieldTypes::${a.name}::${call_name}(${'self.' * (not a.void)}${a.name}, codec, \ +${'::uavcan::TailArrayOptDisabled' if not last else 'tao_mode'}); + % if not last: if (res <= 0) { return res; @@ -545,7 +548,7 @@ void YamlStreamer< ${type_name} >::stream(Stream& s, ${type_name}::ParameterType } % endfor % else: - % for idx,a in enumerate(fields): + % for idx,a in enumerate([x for x in fields if not x.void]): % if idx == 0: if (level > 0) {