From 53fffa1db7cb04982db8977acd61b808ef60d5a8 Mon Sep 17 00:00:00 2001 From: Ole Troan Date: Tue, 13 Nov 2018 12:36:56 +0100 Subject: API: Add support for type aliases Previously all types are compound. This adds support for aliases, so one can do things like: typedef u32 interface_index; or typedef u8 ip4_address[4]; Change-Id: I0455cad0123fc88acb491d2a3ea2725426bdb246 Signed-off-by: Ole Troan Signed-off-by: Klement Sekera --- src/vpp-api/vapi/vapi_c_gen.py | 43 +++++++++++++++++++++++++++--------- src/vpp-api/vapi/vapi_cpp_gen.py | 9 ++++++-- src/vpp-api/vapi/vapi_json_parser.py | 33 +++++++++++++++++++++------ 3 files changed, 65 insertions(+), 20 deletions(-) (limited to 'src/vpp-api/vapi') diff --git a/src/vpp-api/vapi/vapi_c_gen.py b/src/vpp-api/vapi/vapi_c_gen.py index eb1006d3a7e..9939bc0556c 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 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: @@ -95,12 +98,26 @@ class CField(Field): return result +class CAlias(CField): + def get_c_name(self): + return self.name + + def get_c_def(self): + return "typedef %s" % super(CAlias, self).get_c_def() + # if self.len is not None: + # return "typedef %s %s[%d];" % (self.type.get_c_name(), self.name, self.len) + # else: + # return "typedef %s %s;" % (self.type.get_c_name(), self.name) + + # 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): @@ -156,7 +173,7 @@ class CSimpleType (SimpleType): try: self.get_swap_to_host_func_name() return True - except: + except KeyError: pass return False @@ -335,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__)) {", @@ -609,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) @@ -690,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]: @@ -765,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 diff --git a/src/vpp-api/vapi/vapi_cpp_gen.py b/src/vpp-api/vapi/vapi_cpp_gen.py index 6b62bc4da22..c08993dc918 100755 --- a/src/vpp-api/vapi/vapi_cpp_gen.py +++ b/src/vpp-api/vapi/vapi_cpp_gen.py @@ -5,7 +5,7 @@ import os import sys import logging from vapi_c_gen import CField, CEnum, CStruct, CSimpleType, CStructType,\ - CMessage, json_to_c_header_name + CMessage, json_to_c_header_name, CAlias from vapi_json_parser import JsonParser @@ -21,6 +21,10 @@ class CppEnum(CEnum): pass +class CppAlias(CAlias): + pass + + class CppSimpleType (CSimpleType): pass @@ -251,7 +255,8 @@ if __name__ == '__main__': struct_type_class=CppStructType, field_class=CppField, enum_class=CppEnum, - message_class=CppMessage) + message_class=CppMessage, + alias_class=CppAlias) gen_cpp_headers(jsonparser, logger, args.prefix, args.gen_h_prefix, args.remove_path) diff --git a/src/vpp-api/vapi/vapi_json_parser.py b/src/vpp-api/vapi/vapi_json_parser.py index 39acca0b538..3eb5d3616e1 100644 --- a/src/vpp-api/vapi/vapi_json_parser.py +++ b/src/vpp-api/vapi/vapi_json_parser.py @@ -45,6 +45,10 @@ class Field(object): return self.is_vla() or self.type.has_vla() +class Alias(Field): + pass + + class Type(object): def __init__(self, name): self.name = name @@ -55,12 +59,6 @@ class Type(object): class SimpleType (Type): - def __init__(self, name): - super(SimpleType, self).__init__(name) - - def __str__(self): - return self.name - def has_vla(self): return False @@ -290,11 +288,12 @@ 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): + 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', @@ -310,6 +309,7 @@ class JsonParser(object): self.union_class = union_class self.struct_type_class = struct_type_class self.field_class = field_class + self.alias_class = alias_class self.message_class = message_class self.exceptions = [] @@ -317,6 +317,7 @@ class JsonParser(object): self.types_by_json = {} self.enums_by_json = {} self.unions_by_json = {} + self.aliases_by_json = {} self.messages_by_json = {} self.logger = logger for f in files: @@ -329,6 +330,7 @@ class JsonParser(object): self.types_by_json[path] = [] self.enums_by_json[path] = [] self.unions_by_json[path] = [] + self.aliases_by_json[path] = [] self.messages_by_json[path] = {} with open(path) as f: j = json.load(f) @@ -369,6 +371,19 @@ class JsonParser(object): self.unions[union.name] = union self.logger.debug("Parsed union: %s" % union) self.unions_by_json[path].append(union) + for name, body in j['aliases'].iteritems(): + if name in self.aliases: + progress = progress + 1 + continue + if 'length' in body: + array_len = body['length'] + else: + array_len = None + t = self.types[body['type']] + alias = self.alias_class(name, t, array_len) + self.aliases[name] = alias + self.logger.debug("Parsed alias: %s" % alias) + self.aliases_by_json[path].append(alias) for t in j['types']: if t[0] in self.types: progress = progress + 1 @@ -429,12 +444,16 @@ class JsonParser(object): return self.enums[name] elif name in self.unions: return self.unions[name] + elif name in self.aliases: + return self.aliases[name] elif mundane_name in self.types: return self.types[mundane_name] elif mundane_name in self.enums: return self.enums[mundane_name] elif mundane_name in self.unions: return self.unions[mundane_name] + elif mundane_name in self.aliases: + 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)) -- cgit 1.2.3-korg