summaryrefslogtreecommitdiff
path: root/python_modules
diff options
context:
space:
mode:
authorFrediano Ziglio <fziglio@redhat.com>2019-02-18 16:16:21 +0000
committerFrediano Ziglio <fziglio@redhat.com>2019-03-18 13:01:58 +0000
commit3cd3886b27232028b0dca1346fc9bda2b7cf5ff9 (patch)
tree3effe7f4ec2e76683a83f5fad3d2ad95dc6e0190 /python_modules
parentdac34baaab4500bdd7f73e2a62d9faab4f21c517 (diff)
codegen: Allows to generate C declarations automatically
Allows to specify a @declare attribute for messages and structure that can generate the needed C structures. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Christophe Fergeau <cfergeau@redhat.com>
Diffstat (limited to 'python_modules')
-rw-r--r--python_modules/ptypes.py64
1 files changed, 64 insertions, 0 deletions
diff --git a/python_modules/ptypes.py b/python_modules/ptypes.py
index 05c594e..b08170e 100644
--- a/python_modules/ptypes.py
+++ b/python_modules/ptypes.py
@@ -70,6 +70,8 @@ valid_attributes=set([
'zero',
# this attribute does not exist on the network, fill just structure with the value
'virtual',
+ # generate C structure declarations from protocol definition
+ 'declare',
])
attributes_with_arguments=set([
@@ -483,6 +485,26 @@ class ArrayType(Type):
def c_type(self):
return self.element_type.c_type()
+ def generate_c_declaration(self, writer, member):
+ name = member.name
+ if member.has_attr("chunk"):
+ return writer.writeln('SpiceChunks *%s;' % name)
+ if member.has_attr("as_ptr"):
+ len_var = member.attributes["as_ptr"][0]
+ writer.writeln('uint32_t %s;' % len_var)
+ return writer.writeln('%s *%s;' % (self.c_type(), name))
+ if member.has_attr("to_ptr"):
+ return writer.writeln('%s *%s;' % (self.c_type(), name))
+ if member.has_attr("ptr_array"):
+ return writer.writeln('%s *%s[0];' % (self.c_type(), name))
+ if member.has_end_attr() or self.is_remaining_length():
+ return writer.writeln('%s %s[0];' % (self.c_type(), name))
+ if self.is_constant_length():
+ return writer.writeln('%s %s[%s];' % (self.c_type(), name, self.size))
+ if self.is_identifier_length():
+ return writer.writeln('%s *%s;' % (self.c_type(), name))
+ raise NotImplementedError('unknown array %s' % str(self))
+
class PointerType(Type):
def __init__(self, target_type):
Type.__init__(self)
@@ -517,6 +539,15 @@ class PointerType(Type):
def get_num_pointers(self):
return 1
+ def generate_c_declaration(self, writer, member):
+ target_type = self.target_type
+ is_array = target_type.is_array()
+ if not is_array or target_type.is_identifier_length():
+ writer.writeln("%s *%s;" % (target_type.c_type(), member.name))
+ return
+ raise NotImplementedError('Some pointers to array declarations are not implemented %s' %
+member)
+
class Containee:
def __init__(self):
self.attributes = {}
@@ -612,6 +643,14 @@ class Member(Containee):
names = [prefix + "_" + name for name in names]
return names
+ def generate_c_declaration(self, writer):
+ if self.has_attr("zero"):
+ return
+ if self.is_pointer() or self.is_array():
+ self.member_type.generate_c_declaration(writer, self)
+ return
+ return writer.writeln("%s %s;" % (self.member_type.c_type(), self.name))
+
class SwitchCase:
def __init__(self, values, member):
self.values = values
@@ -735,6 +774,17 @@ class Switch(Containee):
names = names + c.get_pointer_names(marshalled)
return names
+ def generate_c_declaration(self, writer):
+ if self.has_attr("anon") and len(self.cases) == 1:
+ self.cases[0].member.generate_c_declaration(writer)
+ return
+ writer.writeln('union {')
+ writer.indent()
+ for m in self.cases:
+ m.member.generate_c_declaration(writer)
+ writer.unindent()
+ writer.writeln('} %s;' % self.name)
+
class ContainerType(Type):
def is_fixed_sizeof(self):
for m in self.members:
@@ -845,6 +895,20 @@ class ContainerType(Type):
return member
+ def generate_c_declaration(self, writer):
+ if not self.has_attr('declare'):
+ return
+ name = self.c_type()
+ writer.writeln('typedef struct %s {' % name)
+ writer.indent()
+ for m in self.members:
+ m.generate_c_declaration(writer)
+ if len(self.members) == 0:
+ # make sure generated structure are not empty
+ writer.writeln("char dummy[0];")
+ writer.unindent()
+ writer.writeln('} %s;' % name).newline()
+
class StructType(ContainerType):
def __init__(self, name, members, attribute_list):
Type.__init__(self)