diff options
Diffstat (limited to 'src/vpp-api/vapi')
-rwxr-xr-x | src/vpp-api/vapi/vapi_c_gen.py | 827 | ||||
-rwxr-xr-x | src/vpp-api/vapi/vapi_cpp_gen.py | 221 | ||||
-rw-r--r-- | src/vpp-api/vapi/vapi_json_parser.py | 269 |
3 files changed, 767 insertions, 550 deletions
diff --git a/src/vpp-api/vapi/vapi_c_gen.py b/src/vpp-api/vapi/vapi_c_gen.py index debd7345f60..2978ebd2077 100755 --- a/src/vpp-api/vapi/vapi_c_gen.py +++ b/src/vpp-api/vapi/vapi_c_gen.py @@ -5,8 +5,17 @@ import inspect import os import sys import logging -from vapi_json_parser import Field, Struct, Enum, Union, Message, JsonParser,\ - SimpleType, StructType, Alias +from vapi_json_parser import ( + Field, + Struct, + Enum, + Union, + Message, + JsonParser, + SimpleType, + StructType, + Alias, +) class CField(Field): @@ -14,54 +23,63 @@ class CField(Field): return "vapi_type_%s" % self.name def get_c_def(self): - if self.type.get_c_name() == 'vl_api_string_t': + 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: if self.len is not None and type(self.len) != dict: - 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) def get_swap_to_be_code(self, struct, var): if self.len is not None and type(self.len) != dict: if self.len > 0: - return "do { unsigned i; for (i = 0; i < %d; ++i) { %s } }"\ - " while(0);" % ( - self.len, - self.type.get_swap_to_be_code(struct, "%s[i]" % var)) + return ( + "do { unsigned i; for (i = 0; i < %d; ++i) { %s } }" + " while(0);" + % (self.len, self.type.get_swap_to_be_code(struct, "%s[i]" % var)) + ) else: if self.nelem_field.needs_byte_swap(): nelem_field = "%s(%s%s)" % ( self.nelem_field.type.get_swap_to_host_func_name(), - struct, self.nelem_field.name) + struct, + self.nelem_field.name, + ) else: nelem_field = "%s%s" % (struct, self.nelem_field.name) return ( "do { unsigned i; for (i = 0; i < %s; ++i) { %s } }" - " while(0);" % - (nelem_field, self.type.get_swap_to_be_code( - struct, "%s[i]" % var))) + " while(0);" + % ( + nelem_field, + self.type.get_swap_to_be_code(struct, "%s[i]" % var), + ) + ) return self.type.get_swap_to_be_code(struct, "%s" % var) def get_swap_to_host_code(self, struct, var): if self.len is not None and type(self.len) != dict: if self.len > 0: - return "do { unsigned i; for (i = 0; i < %d; ++i) { %s } }"\ - " while(0);" % ( - self.len, - self.type.get_swap_to_host_code(struct, "%s[i]" % var)) + return ( + "do { unsigned i; for (i = 0; i < %d; ++i) { %s } }" + " while(0);" + % (self.len, self.type.get_swap_to_host_code(struct, "%s[i]" % var)) + ) else: # nelem_field already swapped to host here... return ( "do { unsigned i; for (i = 0; i < %s%s; ++i) { %s } }" - " while(0);" % - (struct, self.nelem_field.name, - self.type.get_swap_to_host_code( - struct, "%s[i]" % var))) + " while(0);" + % ( + struct, + self.nelem_field.name, + self.type.get_swap_to_host_code(struct, "%s[i]" % var), + ) + ) return self.type.get_swap_to_host_code(struct, "%s" % var) def needs_byte_swap(self): @@ -82,10 +100,14 @@ class CField(Field): 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))] + 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(): @@ -96,10 +118,14 @@ class CField(Field): 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))) + 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) @@ -113,52 +139,75 @@ class CAlias(CField): 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) + 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 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])), - "} %s;" % self.get_c_name()]) + return "\n".join( + [ + "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)] + 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)] + 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)] + 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): +class CSimpleType(SimpleType): swap_to_be_dict = { - 'i16': 'htobe16', 'u16': 'htobe16', - 'i32': 'htobe32', 'u32': 'htobe32', - 'i64': 'htobe64', 'u64': 'htobe64', + "i16": "htobe16", + "u16": "htobe16", + "i32": "htobe32", + "u32": "htobe32", + "i64": "htobe64", + "u64": "htobe64", } swap_to_host_dict = { - 'i16': 'be16toh', 'u16': 'be16toh', - 'i32': 'be32toh', 'u32': 'be32toh', - 'i64': 'be64toh', 'u64': 'be64toh', + "i16": "be16toh", + "u16": "be16toh", + "i32": "be32toh", + "u32": "be32toh", + "i64": "be64toh", + "u64": "be64toh", } __packed = "__attribute__((packed))" pack_dict = { - 'i8': __packed, 'u8': __packed, - 'i16': __packed, 'u16': __packed, + "i8": __packed, + "u8": __packed, + "i16": __packed, + "u16": __packed, } def get_c_name(self): @@ -175,15 +224,21 @@ class CSimpleType (SimpleType): def get_swap_to_be_code(self, struct, var, cast=None): x = "%s%s" % (struct, var) - return "%s = %s%s(%s);" % (x, - "(%s)" % cast if cast else "", - self.get_swap_to_be_func_name(), x) + return "%s = %s%s(%s);" % ( + x, + "(%s)" % cast if cast else "", + self.get_swap_to_be_func_name(), + x, + ) def get_swap_to_host_code(self, struct, var, cast=None): x = "%s%s" % (struct, var) - return "%s = %s%s(%s);" % (x, - "(%s)" % cast if cast else "", - self.get_swap_to_host_func_name(), x) + return "%s = %s%s(%s);" % ( + x, + "(%s)" % cast if cast else "", + self.get_swap_to_host_func_name(), + x, + ) def needs_byte_swap(self): try: @@ -205,7 +260,7 @@ class CEnum(Enum): return "typedef enum {\n%s\n} %s %s;" % ( "\n".join([" %s = %s," % (i, j) for i, j in self.value_pairs]), self.type.get_packed(), - self.get_c_name() + self.get_c_name(), ) def needs_byte_swap(self): @@ -224,16 +279,15 @@ class CUnion(Union): def get_c_def(self): return "typedef union {\n%s\n} %s;" % ( - "\n".join([" %s %s;" % (i.get_c_name(), j) - for i, j in self.type_pairs]), - self.get_c_name() + "\n".join([" %s %s;" % (i.get_c_name(), j) for i, j in self.type_pairs]), + self.get_c_name(), ) def needs_byte_swap(self): return False -class CStructType (StructType, CStruct): +class CStructType(StructType, CStruct): def get_c_name(self): return "vapi_type_%s" % self.name @@ -244,27 +298,36 @@ class CStructType (StructType, CStruct): return "%s_ntoh" % self.get_c_name() def get_swap_to_be_func_decl(self): - return "void %s(%s *msg)" % ( - self.get_swap_to_be_func_name(), self.get_c_name()) + return "void %s(%s *msg)" % (self.get_swap_to_be_func_name(), self.get_c_name()) def get_swap_to_be_func_def(self): return "%s\n{\n%s\n}" % ( self.get_swap_to_be_func_decl(), - "\n".join([ - " %s" % p.get_swap_to_be_code("msg->", "%s" % p.name) - for p in self.fields if p.needs_byte_swap()]), + "\n".join( + [ + " %s" % p.get_swap_to_be_code("msg->", "%s" % p.name) + for p in self.fields + if p.needs_byte_swap() + ] + ), ) def get_swap_to_host_func_decl(self): return "void %s(%s *msg)" % ( - self.get_swap_to_host_func_name(), self.get_c_name()) + self.get_swap_to_host_func_name(), + self.get_c_name(), + ) def get_swap_to_host_func_def(self): return "%s\n{\n%s\n}" % ( self.get_swap_to_host_func_decl(), - "\n".join([ - " %s" % p.get_swap_to_host_code("msg->", "%s" % p.name) - for p in self.fields if p.needs_byte_swap()]), + "\n".join( + [ + " %s" % p.get_swap_to_host_code("msg->", "%s" % p.name) + for p in self.fields + if p.needs_byte_swap() + ] + ), ) def get_swap_to_be_code(self, struct, var): @@ -280,13 +343,11 @@ class CStructType (StructType, CStruct): return False -class CMessage (Message): +class CMessage(Message): def __init__(self, logger, definition, json_parser): super(CMessage, self).__init__(logger, definition, json_parser) self.payload_members = [ - " %s" % p.get_c_def() - for p in self.fields - if p.type != self.header + " %s" % p.get_c_def() for p in self.fields if p.type != self.header ] def has_payload(self): @@ -305,46 +366,65 @@ class CMessage (Message): return "vapi_alloc_%s" % self.name def get_alloc_vla_param_names(self): - return [x for f in self.fields - if f.has_vla() - for x in f.get_alloc_vla_param_names([])] + 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)" % ( self.get_c_name(), self.get_alloc_func_name(), - "".join([", size_t %s" % n for n in - self.get_alloc_vla_param_names()])) + "".join([", size_t %s" % n for n in self.get_alloc_vla_param_names()]), + ) def get_alloc_func_def(self): extra = [] - if self.header.has_field('client_index'): - extra.append( - " msg->header.client_index = vapi_get_client_index(ctx);") - if self.header.has_field('context'): + if self.header.has_field("client_index"): + extra.append(" msg->header.client_index = vapi_get_client_index(ctx);") + if self.header.has_field("context"): extra.append(" msg->header.context = 0;") - return "\n".join([ - "%s" % self.get_alloc_func_decl(), - "{", - " %s *msg = NULL;" % self.get_c_name(), - " const size_t size = sizeof(%s)%s;" % ( - self.get_c_name(), - "".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) {", - " return NULL;", - " }", - ] + extra + [ - " msg->header._vl_msg_id = vapi_lookup_vl_msg_id(ctx, %s);" % - self.get_msg_id_name(), - "".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;", - "}"]) + return "\n".join( + [ + "%s" % self.get_alloc_func_decl(), + "{", + " %s *msg = NULL;" % self.get_c_name(), + " const size_t size = sizeof(%s)%s;" + % ( + self.get_c_name(), + "".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) {", + " return NULL;", + " }", + ] + + extra + + [ + " msg->header._vl_msg_id = vapi_lookup_vl_msg_id(ctx, %s);" + % self.get_msg_id_name(), + "".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;", + "}", + ] + ) def get_calc_msg_size_func_name(self): return "vapi_calc_%s_msg_size" % self.name @@ -352,21 +432,26 @@ class CMessage (Message): def get_calc_msg_size_func_decl(self): return "uword %s(%s *msg)" % ( self.get_calc_msg_size_func_name(), - self.get_c_name()) + self.get_c_name(), + ) def get_calc_msg_size_func_def(self): - return "\n".join([ - "%s" % self.get_calc_msg_size_func_decl(), - "{", - " return sizeof(*msg)%s;" % - "".join(["+ msg->payload.%s * sizeof(msg->payload.%s[0])" % ( - f.nelem_field.name, - f.name) - for f in self.fields - if f.nelem_field is not None - ]), - "}", - ]) + return "\n".join( + [ + "%s" % self.get_calc_msg_size_func_decl(), + "{", + " return sizeof(*msg)%s;" + % "".join( + [ + "+ msg->payload.%s * sizeof(msg->payload.%s[0])" + % (f.nelem_field.name, f.name) + for f in self.fields + if f.nelem_field is not None + ] + ), + "}", + ] + ) def get_verify_msg_size_func_name(self): return f"vapi_verify_{self.name}_msg_size" @@ -374,7 +459,8 @@ class CMessage (Message): def get_verify_msg_size_func_decl(self): return "int %s(%s *msg, uword buf_size)" % ( self.get_verify_msg_size_func_name(), - self.get_c_name()) + self.get_c_name(), + ) def get_verify_msg_size_func_def(self): return inspect.cleandoc( @@ -397,29 +483,39 @@ class CMessage (Message): }} return 0; }} - """) + """ + ) def get_c_def(self): if self.has_payload(): - return "\n".join([ - "typedef struct __attribute__ ((__packed__)) {", - "%s " % - "\n".join(self.payload_members), - "} %s;" % self.get_payload_struct_name(), - "", - "typedef struct __attribute__ ((__packed__)) {", - (" %s %s;" % (self.header.get_c_name(), - self.fields[0].name) - if self.header is not None else ""), - " %s payload;" % self.get_payload_struct_name(), - "} %s;" % self.get_c_name(), ]) + return "\n".join( + [ + "typedef struct __attribute__ ((__packed__)) {", + "%s " % "\n".join(self.payload_members), + "} %s;" % self.get_payload_struct_name(), + "", + "typedef struct __attribute__ ((__packed__)) {", + ( + " %s %s;" % (self.header.get_c_name(), self.fields[0].name) + if self.header is not None + else "" + ), + " %s payload;" % self.get_payload_struct_name(), + "} %s;" % self.get_c_name(), + ] + ) else: - return "\n".join([ - "typedef struct __attribute__ ((__packed__)) {", - (" %s %s;" % (self.header.get_c_name(), - self.fields[0].name) - if self.header is not None else ""), - "} %s;" % self.get_c_name(), ]) + return "\n".join( + [ + "typedef struct __attribute__ ((__packed__)) {", + ( + " %s %s;" % (self.header.get_c_name(), self.fields[0].name) + if self.header is not None + else "" + ), + "} %s;" % self.get_c_name(), + ] + ) def get_swap_payload_to_host_func_name(self): return "%s_payload_ntoh" % self.get_c_name() @@ -430,29 +526,37 @@ class CMessage (Message): def get_swap_payload_to_host_func_decl(self): return "void %s(%s *payload)" % ( self.get_swap_payload_to_host_func_name(), - self.get_payload_struct_name()) + self.get_payload_struct_name(), + ) def get_swap_payload_to_be_func_decl(self): return "void %s(%s *payload)" % ( self.get_swap_payload_to_be_func_name(), - self.get_payload_struct_name()) + self.get_payload_struct_name(), + ) def get_swap_payload_to_be_func_def(self): return "%s\n{\n%s\n}" % ( self.get_swap_payload_to_be_func_decl(), - "\n".join([ - " %s" % p.get_swap_to_be_code("payload->", "%s" % p.name) - for p in self.fields - if p.needs_byte_swap() and p.type != self.header]), + "\n".join( + [ + " %s" % p.get_swap_to_be_code("payload->", "%s" % p.name) + for p in self.fields + if p.needs_byte_swap() and p.type != self.header + ] + ), ) def get_swap_payload_to_host_func_def(self): return "%s\n{\n%s\n}" % ( self.get_swap_payload_to_host_func_decl(), - "\n".join([ - " %s" % p.get_swap_to_host_code("payload->", "%s" % p.name) - for p in self.fields - if p.needs_byte_swap() and p.type != self.header]), + "\n".join( + [ + " %s" % p.get_swap_to_host_code("payload->", "%s" % p.name) + for p in self.fields + if p.needs_byte_swap() and p.type != self.header + ] + ), ) def get_swap_to_host_func_name(self): @@ -463,37 +567,50 @@ class CMessage (Message): def get_swap_to_host_func_decl(self): return "void %s(%s *msg)" % ( - self.get_swap_to_host_func_name(), self.get_c_name()) + self.get_swap_to_host_func_name(), + self.get_c_name(), + ) def get_swap_to_be_func_decl(self): - return "void %s(%s *msg)" % ( - self.get_swap_to_be_func_name(), self.get_c_name()) + return "void %s(%s *msg)" % (self.get_swap_to_be_func_name(), self.get_c_name()) def get_swap_to_be_func_def(self): - return "\n".join([ - "%s" % self.get_swap_to_be_func_decl(), - "{", - (" VAPI_DBG(\"Swapping `%s'@%%p to big endian\", msg);" % - self.get_c_name()), - " %s(&msg->header);" % self.header.get_swap_to_be_func_name() - if self.header is not None else "", - " %s(&msg->payload);" % self.get_swap_payload_to_be_func_name() - if self.has_payload() else "", - "}", - ]) + return "\n".join( + [ + "%s" % self.get_swap_to_be_func_decl(), + "{", + ( + ' VAPI_DBG("Swapping `%s\'@%%p to big endian", msg);' + % self.get_c_name() + ), + " %s(&msg->header);" % self.header.get_swap_to_be_func_name() + if self.header is not None + else "", + " %s(&msg->payload);" % self.get_swap_payload_to_be_func_name() + if self.has_payload() + else "", + "}", + ] + ) def get_swap_to_host_func_def(self): - return "\n".join([ - "%s" % self.get_swap_to_host_func_decl(), - "{", - (" VAPI_DBG(\"Swapping `%s'@%%p to host byte order\", msg);" % - self.get_c_name()), - " %s(&msg->header);" % self.header.get_swap_to_host_func_name() - if self.header is not None else "", - " %s(&msg->payload);" % self.get_swap_payload_to_host_func_name() - if self.has_payload() else "", - "}", - ]) + return "\n".join( + [ + "%s" % self.get_swap_to_host_func_decl(), + "{", + ( + ' VAPI_DBG("Swapping `%s\'@%%p to host byte order", msg);' + % self.get_c_name() + ), + " %s(&msg->header);" % self.header.get_swap_to_host_func_name() + if self.header is not None + else "", + " %s(&msg->payload);" % self.get_swap_payload_to_host_func_name() + if self.has_payload() + else "", + "}", + ] + ) def get_op_func_name(self): return "vapi_%s" % self.name @@ -502,111 +619,126 @@ class CMessage (Message): if self.reply.has_payload(): return "vapi_error_e %s(%s)" % ( self.get_op_func_name(), - ",\n ".join([ - 'struct vapi_ctx_s *ctx', - '%s *msg' % self.get_c_name(), - 'vapi_error_e (*callback)(struct vapi_ctx_s *ctx', - ' void *callback_ctx', - ' vapi_error_e rv', - ' bool is_last', - ' %s *reply)' % - self.reply.get_payload_struct_name(), - 'void *callback_ctx', - ]) + ",\n ".join( + [ + "struct vapi_ctx_s *ctx", + "%s *msg" % self.get_c_name(), + "vapi_error_e (*callback)(struct vapi_ctx_s *ctx", + " void *callback_ctx", + " vapi_error_e rv", + " bool is_last", + " %s *reply)" + % self.reply.get_payload_struct_name(), + "void *callback_ctx", + ] + ), ) else: return "vapi_error_e %s(%s)" % ( self.get_op_func_name(), - ",\n ".join([ - 'struct vapi_ctx_s *ctx', - '%s *msg' % self.get_c_name(), - 'vapi_error_e (*callback)(struct vapi_ctx_s *ctx', - ' void *callback_ctx', - ' vapi_error_e rv', - ' bool is_last)', - 'void *callback_ctx', - ]) + ",\n ".join( + [ + "struct vapi_ctx_s *ctx", + "%s *msg" % self.get_c_name(), + "vapi_error_e (*callback)(struct vapi_ctx_s *ctx", + " void *callback_ctx", + " vapi_error_e rv", + " bool is_last)", + "void *callback_ctx", + ] + ), ) def get_op_func_def(self): - return "\n".join([ - "%s" % self.get_op_func_decl(), - "{", - " if (!msg || !callback) {", - " return VAPI_EINVAL;", - " }", - " if (vapi_is_nonblocking(ctx) && vapi_requests_full(ctx)) {", - " return VAPI_EAGAIN;", - " }", - " vapi_error_e rv;", - " if (VAPI_OK != (rv = vapi_producer_lock (ctx))) {", - " return rv;", - " }", - " u32 req_context = vapi_gen_req_context(ctx);", - " msg->header.context = req_context;", - " %s(msg);" % self.get_swap_to_be_func_name(), - (" if (VAPI_OK == (rv = vapi_send_with_control_ping " - "(ctx, msg, req_context))) {" - if self.reply_is_stream else - " if (VAPI_OK == (rv = vapi_send (ctx, msg))) {" - ), - (" vapi_store_request(ctx, req_context, %s, " - "(vapi_cb_t)callback, callback_ctx);" % - ("true" if self.reply_is_stream else "false")), - " if (VAPI_OK != vapi_producer_unlock (ctx)) {", - " abort (); /* this really shouldn't happen */", - " }", - " if (vapi_is_nonblocking(ctx)) {", - " rv = VAPI_OK;", - " } else {", - " rv = vapi_dispatch(ctx);", - " }", - " } else {", - " %s(msg);" % self.get_swap_to_host_func_name(), - " if (VAPI_OK != vapi_producer_unlock (ctx)) {", - " abort (); /* this really shouldn't happen */", - " }", - " }", - " return rv;", - "}", - "", - ]) + return "\n".join( + [ + "%s" % self.get_op_func_decl(), + "{", + " if (!msg || !callback) {", + " return VAPI_EINVAL;", + " }", + " if (vapi_is_nonblocking(ctx) && vapi_requests_full(ctx)) {", + " return VAPI_EAGAIN;", + " }", + " vapi_error_e rv;", + " if (VAPI_OK != (rv = vapi_producer_lock (ctx))) {", + " return rv;", + " }", + " u32 req_context = vapi_gen_req_context(ctx);", + " msg->header.context = req_context;", + " %s(msg);" % self.get_swap_to_be_func_name(), + ( + " if (VAPI_OK == (rv = vapi_send_with_control_ping " + "(ctx, msg, req_context))) {" + if self.reply_is_stream + else " if (VAPI_OK == (rv = vapi_send (ctx, msg))) {" + ), + ( + " vapi_store_request(ctx, req_context, %s, " + "(vapi_cb_t)callback, callback_ctx);" + % ("true" if self.reply_is_stream else "false") + ), + " if (VAPI_OK != vapi_producer_unlock (ctx)) {", + " abort (); /* this really shouldn't happen */", + " }", + " if (vapi_is_nonblocking(ctx)) {", + " rv = VAPI_OK;", + " } else {", + " rv = vapi_dispatch(ctx);", + " }", + " } else {", + " %s(msg);" % self.get_swap_to_host_func_name(), + " if (VAPI_OK != vapi_producer_unlock (ctx)) {", + " abort (); /* this really shouldn't happen */", + " }", + " }", + " return rv;", + "}", + "", + ] + ) def get_event_cb_func_decl(self): if not self.is_reply and not self.is_event: - raise Exception( - "Cannot register event callback for non-reply message") + raise Exception("Cannot register event callback for non-reply message") if self.has_payload(): - return "\n".join([ - "void vapi_set_%s_event_cb (" % - self.get_c_name(), - " struct vapi_ctx_s *ctx, ", - (" vapi_error_e (*callback)(struct vapi_ctx_s *ctx, " - "void *callback_ctx, %s *payload)," % - self.get_payload_struct_name()), - " void *callback_ctx)", - ]) + return "\n".join( + [ + "void vapi_set_%s_event_cb (" % self.get_c_name(), + " struct vapi_ctx_s *ctx, ", + ( + " vapi_error_e (*callback)(struct vapi_ctx_s *ctx, " + "void *callback_ctx, %s *payload)," + % self.get_payload_struct_name() + ), + " void *callback_ctx)", + ] + ) else: - return "\n".join([ - "void vapi_set_%s_event_cb (" % - self.get_c_name(), - " struct vapi_ctx_s *ctx, ", - " vapi_error_e (*callback)(struct vapi_ctx_s *ctx, " - "void *callback_ctx),", - " void *callback_ctx)", - ]) + return "\n".join( + [ + "void vapi_set_%s_event_cb (" % self.get_c_name(), + " struct vapi_ctx_s *ctx, ", + " vapi_error_e (*callback)(struct vapi_ctx_s *ctx, " + "void *callback_ctx),", + " void *callback_ctx)", + ] + ) def get_event_cb_func_def(self): if not self.is_reply and not self.is_event: - raise Exception( - "Cannot register event callback for non-reply function") - return "\n".join([ - "%s" % self.get_event_cb_func_decl(), - "{", - (" vapi_set_event_cb(ctx, %s, (vapi_event_cb)callback, " - "callback_ctx);" % - self.get_msg_id_name()), - "}"]) + raise Exception("Cannot register event callback for non-reply function") + return "\n".join( + [ + "%s" % self.get_event_cb_func_decl(), + "{", + ( + " vapi_set_event_cb(ctx, %s, (vapi_event_cb)callback, " + "callback_ctx);" % self.get_msg_id_name() + ), + "}", + ] + ) def get_c_metadata_struct_name(self): return "__vapi_metadata_%s" % self.name @@ -614,38 +746,41 @@ class CMessage (Message): def get_c_constructor(self): has_context = False if self.header is not None: - has_context = self.header.has_field('context') - return '\n'.join([ - 'static void __attribute__((constructor)) __vapi_constructor_%s()' - % self.name, - '{', - ' static const char name[] = "%s";' % self.name, - ' static const char name_with_crc[] = "%s_%s";' - % (self.name, self.crc[2:]), - ' static vapi_message_desc_t %s = {' % - self.get_c_metadata_struct_name(), - ' name,', - ' sizeof(name) - 1,', - ' name_with_crc,', - ' sizeof(name_with_crc) - 1,', - ' true,' if has_context else ' false,', - ' offsetof(%s, context),' % self.header.get_c_name() - if has_context else ' 0,', - (' offsetof(%s, payload),' % self.get_c_name()) - if self.has_payload() else ' VAPI_INVALID_MSG_ID,', - ' (verify_msg_size_fn_t)%s,' % - self.get_verify_msg_size_func_name(), - ' (generic_swap_fn_t)%s,' % self.get_swap_to_be_func_name(), - ' (generic_swap_fn_t)%s,' % self.get_swap_to_host_func_name(), - ' VAPI_INVALID_MSG_ID,', - ' };', - '', - ' %s = vapi_register_msg(&%s);' % - (self.get_msg_id_name(), self.get_c_metadata_struct_name()), - ' VAPI_DBG("Assigned msg id %%d to %s", %s);' % - (self.name, self.get_msg_id_name()), - '}', - ]) + has_context = self.header.has_field("context") + return "\n".join( + [ + "static void __attribute__((constructor)) __vapi_constructor_%s()" + % self.name, + "{", + ' static const char name[] = "%s";' % self.name, + ' static const char name_with_crc[] = "%s_%s";' + % (self.name, self.crc[2:]), + " static vapi_message_desc_t %s = {" + % self.get_c_metadata_struct_name(), + " name,", + " sizeof(name) - 1,", + " name_with_crc,", + " sizeof(name_with_crc) - 1,", + " true," if has_context else " false,", + " offsetof(%s, context)," % self.header.get_c_name() + if has_context + else " 0,", + (" offsetof(%s, payload)," % self.get_c_name()) + if self.has_payload() + else " VAPI_INVALID_MSG_ID,", + " (verify_msg_size_fn_t)%s," % self.get_verify_msg_size_func_name(), + " (generic_swap_fn_t)%s," % self.get_swap_to_be_func_name(), + " (generic_swap_fn_t)%s," % self.get_swap_to_host_func_name(), + " VAPI_INVALID_MSG_ID,", + " };", + "", + " %s = vapi_register_msg(&%s);" + % (self.get_msg_id_name(), self.get_c_metadata_struct_name()), + ' VAPI_DBG("Assigned msg id %%d to %s", %s);' + % (self.name, self.get_msg_id_name()), + "}", + ] + ) def emit_definition(parser, json_file, emitted, o): @@ -659,11 +794,13 @@ def emit_definition(parser, json_file, emitted, o): if hasattr(o, "reply"): emit_definition(parser, json_file, emitted, o.reply) if hasattr(o, "get_c_def"): - 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] and - o not in parser.aliases_by_json[json_file]): + 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] + and o not in parser.aliases_by_json[json_file] + ): return guard = "defined_%s" % o.get_c_name() print("#ifndef %s" % guard) @@ -673,11 +810,9 @@ def emit_definition(parser, json_file, emitted, o): function_attrs = "static inline " if o.name in parser.messages_by_json[json_file]: if o.has_payload(): - print("%s%s" % (function_attrs, - o.get_swap_payload_to_be_func_def())) + print("%s%s" % (function_attrs, o.get_swap_payload_to_be_func_def())) print("") - print("%s%s" % (function_attrs, - o.get_swap_payload_to_host_func_def())) + print("%s%s" % (function_attrs, o.get_swap_payload_to_host_func_def())) print("") print("%s%s" % (function_attrs, o.get_swap_to_be_func_def())) print("") @@ -711,8 +846,12 @@ def gen_json_unified_header(parser, logger, j, io, name): orig_stdout = sys.stdout sys.stdout = io include_guard = "__included_%s" % ( - j.replace(".", "_").replace("/", "_").replace("-", "_").replace( - "+", "_").replace("@", "_")) + j.replace(".", "_") + .replace("/", "_") + .replace("-", "_") + .replace("+", "_") + .replace("@", "_") + ) print("#ifndef %s" % include_guard) print("#define %s" % include_guard) print("") @@ -724,12 +863,14 @@ def gen_json_unified_header(parser, logger, j, io, name): print("#include <vapi/vapi_dbg.h>") print("") print("#ifdef __cplusplus") - print("extern \"C\" {") + print('extern "C" {') print("#endif") if name == "memclnt.api.vapi.h": print("") - print("static inline vapi_error_e vapi_send_with_control_ping " - "(vapi_ctx_t ctx, void * msg, u32 context);") + print( + "static inline vapi_error_e vapi_send_with_control_ping " + "(vapi_ctx_t ctx, void * msg, u32 context);" + ) elif name == "vlib.api.vapi.h": print("#include <vapi/memclnt.api.vapi.h>") else: @@ -738,12 +879,18 @@ def gen_json_unified_header(parser, logger, j, io, name): for m in parser.messages_by_json[j].values(): print("extern vapi_msg_id_t %s;" % m.get_msg_id_name()) print("") - print("#define DEFINE_VAPI_MSG_IDS_%s\\" % - f.replace(".", "_").replace("/", "_").replace("-", "_").upper()) - print("\\\n".join([ - " vapi_msg_id_t %s;" % m.get_msg_id_name() - for m in parser.messages_by_json[j].values() - ])) + print( + "#define DEFINE_VAPI_MSG_IDS_%s\\" + % f.replace(".", "_").replace("/", "_").replace("-", "_").upper() + ) + print( + "\\\n".join( + [ + " vapi_msg_id_t %s;" % m.get_msg_id_name() + for m in parser.messages_by_json[j].values() + ] + ) + ) print("") print("") emitted = [] @@ -802,12 +949,11 @@ def gen_c_unified_headers(parser, logger, prefix, remove_path): d, f = os.path.split(j) else: f = j - with open('%s%s' % (prefix, json_to_c_header_name(f)), "w") as io: - gen_json_unified_header( - parser, logger, j, io, json_to_c_header_name(f)) + with open("%s%s" % (prefix, json_to_c_header_name(f)), "w") as io: + gen_json_unified_header(parser, logger, j, io, json_to_c_header_name(f)) -if __name__ == '__main__': +if __name__ == "__main__": try: verbose = int(os.getenv("V", 0)) except: @@ -825,23 +971,30 @@ if __name__ == '__main__': logger.setLevel(log_level) argparser = argparse.ArgumentParser(description="VPP C API generator") - argparser.add_argument('files', metavar='api-file', action='append', - type=str, help='json api file' - '(may be specified multiple times)') - argparser.add_argument('--prefix', action='store', default=None, - help='path prefix') - argparser.add_argument('--remove-path', action='store_true', - help='remove path from filename') + argparser.add_argument( + "files", + metavar="api-file", + action="append", + type=str, + help="json api file" "(may be specified multiple times)", + ) + argparser.add_argument("--prefix", action="store", default=None, help="path prefix") + argparser.add_argument( + "--remove-path", action="store_true", help="remove path from filename" + ) args = argparser.parse_args() - jsonparser = JsonParser(logger, args.files, - simple_type_class=CSimpleType, - enum_class=CEnum, - union_class=CUnion, - struct_type_class=CStructType, - field_class=CField, - message_class=CMessage, - alias_class=CAlias) + jsonparser = JsonParser( + logger, + args.files, + simple_type_class=CSimpleType, + enum_class=CEnum, + union_class=CUnion, + struct_type_class=CStructType, + field_class=CField, + 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 diff --git a/src/vpp-api/vapi/vapi_cpp_gen.py b/src/vpp-api/vapi/vapi_cpp_gen.py index 7bc2e7fecf0..33744a3d58c 100755 --- a/src/vpp-api/vapi/vapi_cpp_gen.py +++ b/src/vpp-api/vapi/vapi_cpp_gen.py @@ -4,8 +4,16 @@ import argparse import os import sys import logging -from vapi_c_gen import CField, CEnum, CStruct, CSimpleType, CStructType,\ - CMessage, json_to_c_header_name, CAlias +from vapi_c_gen import ( + CField, + CEnum, + CStruct, + CSimpleType, + CStructType, + CMessage, + json_to_c_header_name, + CAlias, +) from vapi_json_parser import JsonParser @@ -25,53 +33,64 @@ class CppAlias(CAlias): pass -class CppSimpleType (CSimpleType): +class CppSimpleType(CSimpleType): pass -class CppStructType (CStructType, CppStruct): +class CppStructType(CStructType, CppStruct): pass -class CppMessage (CMessage): +class CppMessage(CMessage): def get_swap_to_be_template_instantiation(self): - return "\n".join([ - "template <> inline void vapi_swap_to_be<%s>(%s *msg)" % - (self.get_c_name(), self.get_c_name()), - "{", - " %s(msg);" % self.get_swap_to_be_func_name(), - "}", - ]) + return "\n".join( + [ + "template <> inline void vapi_swap_to_be<%s>(%s *msg)" + % (self.get_c_name(), self.get_c_name()), + "{", + " %s(msg);" % self.get_swap_to_be_func_name(), + "}", + ] + ) def get_swap_to_host_template_instantiation(self): - return "\n".join([ - "template <> inline void vapi_swap_to_host<%s>(%s *msg)" % - (self.get_c_name(), self.get_c_name()), - "{", - " %s(msg);" % self.get_swap_to_host_func_name(), - "}", - ]) + return "\n".join( + [ + "template <> inline void vapi_swap_to_host<%s>(%s *msg)" + % (self.get_c_name(), self.get_c_name()), + "{", + " %s(msg);" % self.get_swap_to_host_func_name(), + "}", + ] + ) def get_alloc_template_instantiation(self): - return "\n".join([ - "template <> inline %s* vapi_alloc<%s%s>" - "(Connection &con%s)" % - (self.get_c_name(), self.get_c_name(), - ", size_t" * len(self.get_alloc_vla_param_names()), - "".join([", size_t %s" % n for n in - self.get_alloc_vla_param_names()]) - ), - "{", - " %s* result = %s(con.vapi_ctx%s);" % - (self.get_c_name(), self.get_alloc_func_name(), - "".join([", %s" % n - for n in self.get_alloc_vla_param_names()])), - "#if VAPI_CPP_DEBUG_LEAKS", - " con.on_shm_data_alloc(result);", - "#endif", - " return result;", - "}", - ]) + return "\n".join( + [ + "template <> inline %s* vapi_alloc<%s%s>" + "(Connection &con%s)" + % ( + self.get_c_name(), + self.get_c_name(), + ", size_t" * len(self.get_alloc_vla_param_names()), + "".join( + [", size_t %s" % n for n in self.get_alloc_vla_param_names()] + ), + ), + "{", + " %s* result = %s(con.vapi_ctx%s);" + % ( + self.get_c_name(), + self.get_alloc_func_name(), + "".join([", %s" % n for n in self.get_alloc_vla_param_names()]), + ), + "#if VAPI_CPP_DEBUG_LEAKS", + " con.on_shm_data_alloc(result);", + "#endif", + " return result;", + "}", + ] + ) def get_cpp_name(self): return "%s%s" % (self.name[0].upper(), self.name[1:]) @@ -86,51 +105,60 @@ class CppMessage (CMessage): template, self.get_c_name(), self.reply.get_c_name(), - "".join([", size_t"] * len(self.get_alloc_vla_param_names())) + "".join([", size_t"] * len(self.get_alloc_vla_param_names())), ) def get_req_template_instantiation(self): return "template class %s;" % self.get_req_template_name() def get_type_alias(self): - return "using %s = %s;" % ( - self.get_cpp_name(), self.get_req_template_name()) + return "using %s = %s;" % (self.get_cpp_name(), self.get_req_template_name()) def get_reply_template_name(self): return "Msg<%s>" % (self.get_c_name()) def get_reply_type_alias(self): - return "using %s = %s;" % ( - self.get_cpp_name(), self.get_reply_template_name()) + return "using %s = %s;" % (self.get_cpp_name(), self.get_reply_template_name()) def get_msg_class_instantiation(self): return "template class Msg<%s>;" % self.get_c_name() def get_get_msg_id_t_instantiation(self): - return "\n".join([ - ("template <> inline vapi_msg_id_t vapi_get_msg_id_t<%s>()" - % self.get_c_name()), - "{", - " return ::%s; " % self.get_msg_id_name(), - "}", - "", - ("template <> inline vapi_msg_id_t " - "vapi_get_msg_id_t<Msg<%s>>()" % self.get_c_name()), - "{", - " return ::%s; " % self.get_msg_id_name(), - "}", - ]) + return "\n".join( + [ + ( + "template <> inline vapi_msg_id_t vapi_get_msg_id_t<%s>()" + % self.get_c_name() + ), + "{", + " return ::%s; " % self.get_msg_id_name(), + "}", + "", + ( + "template <> inline vapi_msg_id_t " + "vapi_get_msg_id_t<Msg<%s>>()" % self.get_c_name() + ), + "{", + " return ::%s; " % self.get_msg_id_name(), + "}", + ] + ) def get_cpp_constructor(self): - return '\n'.join([ - ('static void __attribute__((constructor)) ' - '__vapi_cpp_constructor_%s()' - % self.name), - '{', - (' vapi::vapi_msg_set_msg_id<%s>(%s);' % ( - self.get_c_name(), self.get_msg_id_name())), - '}', - ]) + return "\n".join( + [ + ( + "static void __attribute__((constructor)) " + "__vapi_cpp_constructor_%s()" % self.name + ), + "{", + ( + " vapi::vapi_msg_set_msg_id<%s>(%s);" + % (self.get_c_name(), self.get_msg_id_name()) + ), + "}", + ] + ) def gen_json_header(parser, logger, j, io, gen_h_prefix, add_debug_comments): @@ -139,8 +167,8 @@ def gen_json_header(parser, logger, j, io, gen_h_prefix, add_debug_comments): sys.stdout = io d, f = os.path.split(j) include_guard = "__included_hpp_%s" % ( - f.replace(".", "_").replace("/", "_").replace("-", "_").replace( - "@", "_")) + f.replace(".", "_").replace("/", "_").replace("-", "_").replace("@", "_") + ) print("#ifndef %s" % include_guard) print("#define %s" % include_guard) print("") @@ -202,8 +230,9 @@ def json_to_cpp_header_name(json_name): raise Exception("Unexpected json name `%s'!" % json_name) -def gen_cpp_headers(parser, logger, prefix, gen_h_prefix, remove_path, - add_debug_comments=False): +def gen_cpp_headers( + parser, logger, prefix, gen_h_prefix, remove_path, add_debug_comments=False +): if prefix == "" or prefix is None: prefix = "" else: @@ -217,12 +246,11 @@ def gen_cpp_headers(parser, logger, prefix, gen_h_prefix, remove_path, d, f = os.path.split(j) else: f = j - with open('%s%s' % (prefix, json_to_cpp_header_name(f)), "w") as io: - gen_json_header(parser, logger, j, io, - gen_h_prefix, add_debug_comments) + with open("%s%s" % (prefix, json_to_cpp_header_name(f)), "w") as io: + gen_json_header(parser, logger, j, io, gen_h_prefix, add_debug_comments) -if __name__ == '__main__': +if __name__ == "__main__": try: verbose = int(os.getenv("V", 0)) except: @@ -240,27 +268,36 @@ if __name__ == '__main__': logger.setLevel(log_level) argparser = argparse.ArgumentParser(description="VPP C++ API generator") - argparser.add_argument('files', metavar='api-file', action='append', - type=str, help='json api file' - '(may be specified multiple times)') - argparser.add_argument('--prefix', action='store', default=None, - help='path prefix') - argparser.add_argument('--gen-h-prefix', action='store', default=None, - help='generated C header prefix') - argparser.add_argument('--remove-path', action='store_true', - help='remove path from filename') + argparser.add_argument( + "files", + metavar="api-file", + action="append", + type=str, + help="json api file" "(may be specified multiple times)", + ) + argparser.add_argument("--prefix", action="store", default=None, help="path prefix") + argparser.add_argument( + "--gen-h-prefix", action="store", default=None, help="generated C header prefix" + ) + argparser.add_argument( + "--remove-path", action="store_true", help="remove path from filename" + ) args = argparser.parse_args() - jsonparser = JsonParser(logger, args.files, - simple_type_class=CppSimpleType, - struct_type_class=CppStructType, - field_class=CppField, - enum_class=CppEnum, - message_class=CppMessage, - alias_class=CppAlias) - - gen_cpp_headers(jsonparser, logger, args.prefix, args.gen_h_prefix, - args.remove_path) + jsonparser = JsonParser( + logger, + args.files, + simple_type_class=CppSimpleType, + struct_type_class=CppStructType, + field_class=CppField, + enum_class=CppEnum, + message_class=CppMessage, + alias_class=CppAlias, + ) + + gen_cpp_headers( + jsonparser, logger, args.prefix, args.gen_h_prefix, args.remove_path + ) for e in jsonparser.exceptions: logger.warning(e) diff --git a/src/vpp-api/vapi/vapi_json_parser.py b/src/vpp-api/vapi/vapi_json_parser.py index 1383d456bf1..a323f15e7b6 100644 --- a/src/vpp-api/vapi/vapi_json_parser.py +++ b/src/vpp-api/vapi/vapi_json_parser.py @@ -3,7 +3,7 @@ import json -class ParseError (Exception): +class ParseError(Exception): pass @@ -13,14 +13,12 @@ magic_suffix = "_t" def remove_magic(what): if what.startswith(magic_prefix) and what.endswith(magic_suffix): - return what[len(magic_prefix): - len(magic_suffix)] + return what[len(magic_prefix) : -len(magic_suffix)] return what class Field(object): - - def __init__(self, field_name, field_type, array_len=None, - nelem_field=None): + def __init__(self, field_name, field_type, array_len=None, nelem_field=None): self.name = field_name self.type = field_type self.len = array_len @@ -30,17 +28,23 @@ class Field(object): if self.len is None: return "Field(name: %s, type: %s)" % (self.name, self.type) elif type(self.len) == dict: - return "Field(name: %s, type: %s, length: %s)" % (self.name, - self.type, - self.len) + return "Field(name: %s, type: %s, length: %s)" % ( + self.name, + self.type, + self.len, + ) elif self.len > 0: - return "Field(name: %s, type: %s, length: %s)" % (self.name, - self.type, - self.len) + return "Field(name: %s, type: %s, length: %s)" % ( + self.name, + self.type, + self.len, + ) else: - return ( - "Field(name: %s, type: %s, variable length stored in: %s)" % - (self.name, self.type, self.nelem_field)) + return "Field(name: %s, type: %s, variable length stored in: %s)" % ( + self.name, + self.type, + self.nelem_field, + ) def is_vla(self): return self.nelem_field is not None @@ -61,32 +65,38 @@ class Type(object): return self.name -class SimpleType (Type): - +class SimpleType(Type): def has_vla(self): return False def get_msg_header_defs(struct_type_class, field_class, json_parser, logger): return [ - struct_type_class(['msg_header1_t', - ['u16', '_vl_msg_id'], - ['u32', 'context'], - ], - json_parser, field_class, logger - ), - struct_type_class(['msg_header2_t', - ['u16', '_vl_msg_id'], - ['u32', 'client_index'], - ['u32', 'context'], - ], - json_parser, field_class, logger - ), + struct_type_class( + [ + "msg_header1_t", + ["u16", "_vl_msg_id"], + ["u32", "context"], + ], + json_parser, + field_class, + logger, + ), + struct_type_class( + [ + "msg_header2_t", + ["u16", "_vl_msg_id"], + ["u32", "client_index"], + ["u32", "context"], + ], + json_parser, + field_class, + logger, + ), ] class Struct(object): - def __init__(self, name, fields): self.name = name self.fields = fields @@ -112,7 +122,7 @@ class Enum(SimpleType): def __str__(self): return "Enum(%s, [%s])" % ( self.name, - "], [" .join(["%s => %s" % (i, j) for i, j in self.value_pairs]) + "], [".join(["%s => %s" % (i, j) for i, j in self.value_pairs]), ) @@ -126,7 +136,7 @@ class Union(Type): def __str__(self): return "Union(%s, [%s])" % ( self.name, - "], [" .join(["%s %s" % (i, j) for i, j in self.type_pairs]) + "], [".join(["%s %s" % (i, j) for i, j in self.type_pairs]), ) def has_vla(self): @@ -134,7 +144,6 @@ class Union(Type): class Message(object): - def __init__(self, logger, definition, json_parser): struct_type_class = json_parser.struct_type_class field_class = json_parser.field_class @@ -150,22 +159,24 @@ class Message(object): self.is_reply = json_parser.is_reply(self.name) self.is_event = json_parser.is_event(self.name) fields = [] - for header in get_msg_header_defs(struct_type_class, field_class, - json_parser, logger): + for header in get_msg_header_defs( + struct_type_class, field_class, json_parser, logger + ): logger.debug("Probing header `%s'" % header.name) if header.is_part_of_def(m[1:]): self.header = header logger.debug("Found header `%s'" % header.name) - fields.append(field_class(field_name='header', - field_type=self.header)) + fields.append(field_class(field_name="header", field_type=self.header)) ignore = False break if ignore and not self.is_event and not self.is_reply: - raise ParseError("While parsing message `%s': could not find all " - "common header fields" % name) + raise ParseError( + "While parsing message `%s': could not find all " + "common header fields" % name + ) for field in m[1:]: - if isinstance(field, dict) and 'crc' in field: - self.crc = field['crc'] + if isinstance(field, dict) and "crc" in field: + self.crc = field["crc"] logger.debug("Found CRC `%s'" % self.crc) continue else: @@ -175,25 +186,22 @@ class Message(object): if any(type(n) is dict for n in field): l -= 1 if l == 2: - if self.header is not None and\ - self.header.has_field(field[1]): + if self.header is not None and self.header.has_field(field[1]): continue - p = field_class(field_name=field[1], - field_type=field_type) + p = field_class(field_name=field[1], field_type=field_type) elif l == 3: - if field[2] == 0 and field[0] != 'string': + if field[2] == 0 and field[0] != "string": raise ParseError( "While parsing message `%s': variable length " "array `%s' doesn't have reference to member " - "containing the actual length" % ( - name, field[1])) - if field[0] == 'string' and field[2] > 0: - field_type = json_parser.lookup_type_like_id('u8') + "containing the actual length" % (name, field[1]) + ) + if field[0] == "string" and field[2] > 0: + field_type = json_parser.lookup_type_like_id("u8") p = field_class( - field_name=field[1], - field_type=field_type, - array_len=field[2]) + field_name=field[1], field_type=field_type, array_len=field[2] + ) elif l == 4: nelem_field = None for f in fields: @@ -203,17 +211,19 @@ class Message(object): raise ParseError( "While parsing message `%s': couldn't find " "variable length array `%s' member containing " - "the actual length `%s'" % ( - name, field[1], field[3])) + "the actual length `%s'" % (name, field[1], field[3]) + ) p = field_class( field_name=field[1], field_type=field_type, array_len=field[2], - nelem_field=nelem_field) + nelem_field=nelem_field, + ) else: - raise Exception("Don't know how to parse message " - "definition for message `%s': `%s'" % - (m, m[1:])) + raise Exception( + "Don't know how to parse message " + "definition for message `%s': `%s'" % (m, m[1:]) + ) logger.debug("Parsed field `%s'" % p) fields.append(p) self.fields = fields @@ -221,35 +231,36 @@ class Message(object): logger.debug("Parsed message: %s" % self) def __str__(self): - return "Message(%s, [%s], {crc: %s}" % \ - (self.name, - "], [".join([str(f) for f in self.fields]), - self.crc) - + return "Message(%s, [%s], {crc: %s}" % ( + self.name, + "], [".join([str(f) for f in self.fields]), + self.crc, + ) -class StructType (Type, Struct): +class StructType(Type, Struct): def __init__(self, definition, json_parser, field_class, logger): t = definition logger.debug("Parsing struct definition `%s'" % t) name = t[0] fields = [] for field in t[1:]: - if len(field) == 1 and 'crc' in field: - self.crc = field['crc'] + if len(field) == 1 and "crc" in field: + self.crc = field["crc"] continue field_type = json_parser.lookup_type_like_id(field[0]) logger.debug("Parsing type field `%s'" % field) if len(field) == 2: - p = field_class(field_name=field[1], - field_type=field_type) + p = field_class(field_name=field[1], field_type=field_type) elif len(field) == 3: if field[2] == 0: - raise ParseError("While parsing type `%s': array `%s' has " - "variable length" % (name, field[1])) - p = field_class(field_name=field[1], - field_type=field_type, - array_len=field[2]) + raise ParseError( + "While parsing type `%s': array `%s' has " + "variable length" % (name, field[1]) + ) + p = field_class( + field_name=field[1], field_type=field_type, array_len=field[2] + ) elif len(field) == 4: nelem_field = None for f in fields: @@ -259,23 +270,25 @@ class StructType (Type, Struct): raise ParseError( "While parsing message `%s': couldn't find " "variable length array `%s' member containing " - "the actual length `%s'" % ( - name, field[1], field[3])) - p = field_class(field_name=field[1], - field_type=field_type, - array_len=field[2], - nelem_field=nelem_field) + "the actual length `%s'" % (name, field[1], field[3]) + ) + p = field_class( + field_name=field[1], + field_type=field_type, + array_len=field[2], + nelem_field=nelem_field, + ) else: raise ParseError( "Don't know how to parse field `%s' of type definition " - "for type `%s'" % (field, t)) + "for type `%s'" % (field, t) + ) fields.append(p) Type.__init__(self, name) Struct.__init__(self, name, fields) def __str__(self): - return "StructType(%s, %s)" % (Type.__str__(self), - Struct.__str__(self)) + return "StructType(%s, %s)" % (Type.__str__(self), Struct.__str__(self)) def has_field(self, name): return name in self.field_names @@ -289,30 +302,47 @@ class StructType (Type, Struct): if field[0] != p.type.name: raise ParseError( "Unexpected field type `%s' (should be `%s'), " - "while parsing msg/def/field `%s/%s/%s'" % - (field[0], p.type, p.name, definition, field)) + "while parsing msg/def/field `%s/%s/%s'" + % (field[0], p.type, p.name, definition, field) + ) return True class JsonParser(object): - def __init__(self, logger, files, simple_type_class=SimpleType, - enum_class=Enum, union_class=Union, - struct_type_class=StructType, field_class=Field, - message_class=Message, alias_class=Alias): + def __init__( + self, + logger, + files, + simple_type_class=SimpleType, + enum_class=Enum, + union_class=Union, + struct_type_class=StructType, + field_class=Field, + message_class=Message, + alias_class=Alias, + ): self.services = {} self.messages = {} self.enums = {} self.unions = {} self.aliases = {} self.types = { - x: simple_type_class(x) for x in [ - 'i8', 'i16', 'i32', 'i64', - 'u8', 'u16', 'u32', 'u64', - 'f64', 'bool' + x: simple_type_class(x) + for x in [ + "i8", + "i16", + "i32", + "i64", + "u8", + "u16", + "u32", + "u64", + "f64", + "bool", ] } - self.types['string'] = simple_type_class('vl_api_string_t') + self.types["string"] = simple_type_class("vl_api_string_t") self.replies = set() self.events = set() self.simple_type_class = simple_type_class @@ -345,15 +375,15 @@ class JsonParser(object): self.messages_by_json[path] = {} with open(path) as f: j = json.load(f) - for k in j['services']: + for k in j["services"]: if k in self.services: raise ParseError("Duplicate service `%s'" % k) - self.services[k] = j['services'][k] + self.services[k] = j["services"][k] self.replies.add(self.services[k]["reply"]) if "events" in self.services[k]: for x in self.services[k]["events"]: self.events.add(x) - for e in j['enums']: + for e in j["enums"]: name = e[0] value_pairs = e[1:-1] enumtype = self.types[e[-1]["enumtype"]] @@ -365,14 +395,15 @@ class JsonParser(object): progress = 0 last_progress = 0 while True: - for u in j['unions']: + for u in j["unions"]: name = u[0] if name in self.unions: progress = progress + 1 continue try: - type_pairs = [[self.lookup_type_like_id(t), n] - for t, n in u[1:]] + type_pairs = [ + [self.lookup_type_like_id(t), n] for t, n in u[1:] + ] union = self.union_class(name, type_pairs, 0) progress = progress + 1 except ParseError as e: @@ -381,17 +412,16 @@ class JsonParser(object): self.unions[union.name] = union self.logger.debug("Parsed union: %s" % union) self.unions_by_json[path].append(union) - for t in j['types']: + for t in j["types"]: if t[0] in self.types: progress = progress + 1 continue try: - type_ = self.struct_type_class(t, self, - self.field_class, - self.logger) + type_ = self.struct_type_class( + t, self, self.field_class, self.logger + ) if type_.name in self.types: - raise ParseError( - "Duplicate type `%s'" % type_.name) + raise ParseError("Duplicate type `%s'" % type_.name) progress = progress + 1 except ParseError as e: exceptions.append(e) @@ -399,16 +429,16 @@ class JsonParser(object): self.types[type_.name] = type_ self.types_by_json[path].append(type_) self.logger.debug("Parsed type: %s" % type_) - for name, body in j['aliases'].items(): + for name, body in j["aliases"].items(): if name in self.aliases: progress = progress + 1 continue - if 'length' in body: - array_len = body['length'] + if "length" in body: + array_len = body["length"] else: array_len = None try: - t = self.lookup_type_like_id(body['type']) + t = self.lookup_type_like_id(body["type"]) except ParseError as e: exceptions.append(e) continue @@ -430,14 +460,13 @@ class JsonParser(object): processed = [] while True: exceptions = [] - for m in j['messages']: + for m in j["messages"]: if m in processed: continue try: msg = self.message_class(self.logger, m, self) if msg.name in self.messages: - raise ParseError( - "Duplicate message `%s'" % msg.name) + raise ParseError("Duplicate message `%s'" % msg.name) except ParseError as e: exceptions.append(e) continue @@ -470,7 +499,8 @@ class JsonParser(object): return self.aliases[mundane_name] raise ParseError( "Could not find type, enum or union by magic name `%s' nor by " - "mundane name `%s'" % (name, mundane_name)) + "mundane name `%s'" % (name, mundane_name) + ) def is_reply(self, message): return message in self.replies @@ -479,7 +509,7 @@ class JsonParser(object): return message in self.events def get_reply(self, message): - return self.messages[self.services[message]['reply']] + return self.messages[self.services[message]["reply"]] def finalize_parsing(self): if len(self.messages) == 0: @@ -493,17 +523,14 @@ class JsonParser(object): try: m.reply = self.get_reply(n) if "stream" in self.services[m.name]: - m.reply_is_stream = \ - self.services[m.name]["stream"] + m.reply_is_stream = self.services[m.name]["stream"] else: m.reply_is_stream = False m.reply.request = m except: - raise ParseError( - "Cannot find reply to message `%s'" % n) + raise ParseError("Cannot find reply to message `%s'" % n) except ParseError as e: self.exceptions.append(e) remove.append(n) - self.messages_by_json[jn] = { - k: v for k, v in j.items() if k not in remove} + self.messages_by_json[jn] = {k: v for k, v in j.items() if k not in remove} |