X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvpp-api%2Fvapi%2Fvapi_c_gen.py;h=330bd92ef8f36e1c97f4c462994b5522fef4b87a;hb=e2ccdf0316243a1486109743e3de532cae5f3254;hp=c4c53662a825cadd7090434d54ce45d6e6b007b9;hpb=1732e476cde7cd74aa107c91eb93754a274612d3;p=vpp.git diff --git a/src/vpp-api/vapi/vapi_c_gen.py b/src/vpp-api/vapi/vapi_c_gen.py index c4c53662a82..330bd92ef8f 100755 --- a/src/vpp-api/vapi/vapi_c_gen.py +++ b/src/vpp-api/vapi/vapi_c_gen.py @@ -1,19 +1,28 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 import argparse 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) + if self.type.get_c_name() == 'vl_api_string_t': + if self.len: + return "u8 %s[%d];" % (self.name, self.len) + else: + return "vl_api_string_t %s;" % (self.name) else: - return "%s %s" % (self.type.get_c_name(), self.name) + if self.len is not None: + return "%s %s[%d];" % (self.type.get_c_name(), self.name, self.len) + else: + 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 +65,79 @@ 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) + 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 +178,7 @@ class CSimpleType (SimpleType): try: self.get_swap_to_host_func_name() return True - except: + except KeyError: pass return False @@ -213,16 +286,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 +314,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 +325,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 +357,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 +631,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 +653,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) @@ -653,6 +717,8 @@ def gen_json_unified_header(parser, logger, j, io, name): emit_definition(parser, j, emitted, u) for t in parser.types_by_json[j]: emit_definition(parser, j, emitted, t) + for a in parser.aliases_by_json[j]: + emit_definition(parser, j, emitted, a) for m in parser.messages_by_json[j].values(): emit_definition(parser, j, emitted, m) @@ -724,7 +790,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