X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=blobdiff_plain;f=src%2Fvpp-api%2Fvapi%2Fvapi_c_gen.py;h=490b83028da91a134d787b97756e80d56f530a04;hp=c4c53662a825cadd7090434d54ce45d6e6b007b9;hb=8c8acc0;hpb=1732e476cde7cd74aa107c91eb93754a274612d3 diff --git a/src/vpp-api/vapi/vapi_c_gen.py b/src/vpp-api/vapi/vapi_c_gen.py index c4c53662a82..490b83028da 100755 --- a/src/vpp-api/vapi/vapi_c_gen.py +++ b/src/vpp-api/vapi/vapi_c_gen.py @@ -5,15 +5,18 @@ import os import sys import logging from vapi_json_parser import Field, Struct, Enum, Union, Message, JsonParser,\ - SimpleType, StructType + SimpleType, StructType, Alias class CField(Field): + def get_c_name(self): + return "vapi_type_%s" % self.name + def get_c_def(self): if self.len is not None: - return "%s %s[%d]" % (self.type.get_c_name(), self.name, self.len) + return "%s %s[%d];" % (self.type.get_c_name(), self.name, self.len) else: - return "%s %s" % (self.type.get_c_name(), self.name) + return "%s %s;" % (self.type.get_c_name(), self.name) def get_swap_to_be_code(self, struct, var): if self.len is not None: @@ -56,15 +59,80 @@ class CField(Field): def needs_byte_swap(self): return self.type.needs_byte_swap() + def get_vla_field_length_name(self, path): + return "%s_%s_array_size" % ("_".join(path), self.name) + + def get_alloc_vla_param_names(self, path): + if self.is_vla(): + result = [self.get_vla_field_length_name(path)] + else: + result = [] + if self.type.has_vla(): + t = self.type.get_alloc_vla_param_names(path + [self.name]) + result.extend(t) + return result + + def get_vla_calc_size_code(self, prefix, path): + if self.is_vla(): + result = ["sizeof(%s.%s[0]) * %s" % ( + ".".join([prefix] + path), + self.name, + self.get_vla_field_length_name(path))] + else: + result = [] + if self.type.has_vla(): + t = self.type.get_vla_calc_size_code(prefix, path + [self.name]) + result.extend(t) + return result + + def get_vla_assign_code(self, prefix, path): + result = [] + if self.is_vla(): + result.append("%s.%s = %s" % ( + ".".join([prefix] + path), + self.nelem_field.name, + self.get_vla_field_length_name(path))) + if self.type.has_vla(): + t = self.type.get_vla_assign_code(prefix, path + [self.name]) + result.extend(t) + return result + + +class CAlias(CField): + def get_c_name(self): + return "vapi_type_%s" % self.name + + def get_c_def(self): + if self.len is not None: + return "typedef %s vapi_type_%s[%d];" % (self.type.get_c_name(), self.name, self.len) + else: + return "typedef %s vapi_type_%s;" % (self.type.get_c_name(), self.name) + #return "typedef %s" % super(CAlias, self).get_c_def() + + # def needs_byte_swap + class CStruct(Struct): def get_c_def(self): return "\n".join([ - "typedef struct __attribute__((__packed__)) {\n%s;" % ( - ";\n".join([" %s" % x.get_c_def() - for x in self.fields])), + "typedef struct __attribute__((__packed__)) {\n%s" % ( + "\n".join([" %s" % x.get_c_def() + for x in self.fields])), "} %s;" % self.get_c_name()]) + def get_vla_assign_code(self, prefix, path): + return [x for f in self.fields if f.has_vla() + for x in f.get_vla_assign_code(prefix, path)] + + def get_alloc_vla_param_names(self, path): + return [x for f in self.fields + if f.has_vla() + for x in f.get_alloc_vla_param_names(path)] + + def get_vla_calc_size_code(self, prefix, path): + return [x for f in self.fields if f.has_vla() + for x in f.get_vla_calc_size_code(prefix, path)] + class CSimpleType (SimpleType): @@ -105,7 +173,7 @@ class CSimpleType (SimpleType): try: self.get_swap_to_host_func_name() return True - except: + except KeyError: pass return False @@ -213,16 +281,13 @@ class CMessage (Message): def get_payload_struct_name(self): return "vapi_payload_%s" % self.name - def get_alloc_func_vla_field_length_name(self, field): - return "%s_array_size" % field.name - def get_alloc_func_name(self): return "vapi_alloc_%s" % self.name def get_alloc_vla_param_names(self): - return [self.get_alloc_func_vla_field_length_name(f) - for f in self.fields - if f.nelem_field is not None] + return [x for f in self.fields + if f.has_vla() + for x in f.get_alloc_vla_param_names([])] def get_alloc_func_decl(self): return "%s* %s(struct vapi_ctx_s *ctx%s)" % ( @@ -244,13 +309,9 @@ class CMessage (Message): " %s *msg = NULL;" % self.get_c_name(), " const size_t size = sizeof(%s)%s;" % ( self.get_c_name(), - "".join([ - " + sizeof(msg->payload.%s[0]) * %s" % ( - f.name, - self.get_alloc_func_vla_field_length_name(f)) - for f in self.fields - if f.nelem_field is not None - ])), + "".join([" + %s" % x for f in self.fields if f.has_vla() + for x in f.get_vla_calc_size_code("msg->payload", + [])])), " /* cast here required to play nicely with C++ world ... */", " msg = (%s*)vapi_msg_alloc(ctx, size);" % self.get_c_name(), " if (!msg) {", @@ -259,11 +320,9 @@ class CMessage (Message): ] + extra + [ " msg->header._vl_msg_id = vapi_lookup_vl_msg_id(ctx, %s);" % self.get_msg_id_name(), - "\n".join([" msg->payload.%s = %s;" % ( - f.nelem_field.name, - self.get_alloc_func_vla_field_length_name(f)) - for f in self.fields - if f.nelem_field is not None]), + "".join([" %s;\n" % line + for f in self.fields if f.has_vla() + for line in f.get_vla_assign_code("msg->payload", [])]), " return msg;", "}"]) @@ -293,8 +352,8 @@ class CMessage (Message): if self.has_payload(): return "\n".join([ "typedef struct __attribute__ ((__packed__)) {", - "%s; " % - ";\n".join(self.payload_members), + "%s " % + "\n".join(self.payload_members), "} %s;" % self.get_payload_struct_name(), "", "typedef struct __attribute__ ((__packed__)) {", @@ -567,7 +626,8 @@ def emit_definition(parser, json_file, emitted, o): if (o not in parser.enums_by_json[json_file] and o not in parser.types_by_json[json_file] and o not in parser.unions_by_json[json_file] and - o.name not in parser.messages_by_json[json_file]): + o.name not in parser.messages_by_json[json_file] and + o not in parser.aliases_by_json[json_file]): return guard = "defined_%s" % o.get_c_name() print("#ifndef %s" % guard) @@ -588,23 +648,22 @@ def emit_definition(parser, json_file, emitted, o): print("%s%s" % (function_attrs, o.get_swap_to_host_func_def())) print("") print("%s%s" % (function_attrs, o.get_calc_msg_size_func_def())) - print("") if not o.is_reply and not o.is_event: + print("") print("%s%s" % (function_attrs, o.get_alloc_func_def())) print("") print("%s%s" % (function_attrs, o.get_op_func_def())) - print("") - print("%s" % o.get_c_constructor()) print("") + print("%s" % o.get_c_constructor()) if o.is_reply or o.is_event: - print("%s%s;" % (function_attrs, o.get_event_cb_func_def())) print("") + print("%s%s;" % (function_attrs, o.get_event_cb_func_def())) elif hasattr(o, "get_swap_to_be_func_def"): print("%s%s" % (function_attrs, o.get_swap_to_be_func_def())) print("") print("%s%s" % (function_attrs, o.get_swap_to_host_func_def())) - print("") print("#endif") + print("") emitted.append(o) @@ -649,6 +708,8 @@ def gen_json_unified_header(parser, logger, j, io, name): emitted = [] for e in parser.enums_by_json[j]: emit_definition(parser, j, emitted, e) + for a in parser.aliases_by_json[j]: + emit_definition(parser, j, emitted, a) for u in parser.unions_by_json[j]: emit_definition(parser, j, emitted, u) for t in parser.types_by_json[j]: @@ -724,7 +785,8 @@ if __name__ == '__main__': union_class=CUnion, struct_type_class=CStructType, field_class=CField, - message_class=CMessage) + message_class=CMessage, + alias_class=CAlias) # not using the model of having separate generated header and code files # with generated symbols present in shared library (per discussion with