From 8dbfb433619011b649b1b511ad88969a7f909861 Mon Sep 17 00:00:00 2001 From: Ole Troan Date: Wed, 24 Apr 2019 14:31:18 +0200 Subject: [PATCH] vppapigen: Fold up CRC from dependent types. Change-Id: Id51f26f225cd567ca19efc2301e94fa88840ae8f Signed-off-by: Ole Troan Type: fix Signed-off-by: Ole Troan --- src/tools/vppapigen/vppapigen.py | 67 +++++++++++++++++++++-------------- src/tools/vppapigen/vppapigen_c.py | 4 +-- src/tools/vppapigen/vppapigen_json.py | 10 +++--- src/vpp-api/vapi/vapi_json_parser.py | 5 ++- 4 files changed, 50 insertions(+), 36 deletions(-) diff --git a/src/tools/vppapigen/vppapigen.py b/src/tools/vppapigen/vppapigen.py index ae2b0b1ba40..c60e43e8ed3 100755 --- a/src/tools/vppapigen/vppapigen.py +++ b/src/tools/vppapigen/vppapigen.py @@ -18,15 +18,14 @@ sys.dont_write_bytecode = True # Global dictionary of new types (including enums) global_types = {} -global_crc = 0 -def global_type_add(name): +def global_type_add(name, obj): '''Add new type to the dictionary of types ''' type_name = 'vl_api_' + name + '_t' if type_name in global_types: raise KeyError('Type is already defined: {}'.format(name)) - global_types[type_name] = True + global_types[type_name] = obj # All your trace are belong to us! @@ -122,15 +121,9 @@ class VPPAPILexer(object): t_ignore = ' \t' -# -# Side-effect: Sets global_crc -# -def crc_block(block): - global global_crc +def crc_block_combine(block, crc): s = str(block).encode() - global_crc = binascii.crc32(s, global_crc) - return binascii.crc32(s) & 0xffffffff - + return binascii.crc32(s, crc) & 0xffffffff class Service(): def __init__(self, caller, reply, events=None, stream=False): @@ -145,7 +138,7 @@ class Typedef(): self.name = name self.flags = flags self.block = block - self.crc = crc_block(block) + self.crc = str(block).encode() self.manual_print = False self.manual_endian = False for f in flags: @@ -153,7 +146,7 @@ class Typedef(): self.manual_print = True elif f == 'manual_endian': self.manual_endian = True - global_type_add(name) + global_type_add(name, self) def __repr__(self): return self.name + str(self.flags) + str(self.block) @@ -161,7 +154,6 @@ class Typedef(): class Using(): def __init__(self, name, alias): - global global_crc self.name = name if isinstance(alias, Array): @@ -170,9 +162,8 @@ class Using(): else: a = { 'type': alias.fieldtype } # noqa: E201,E202 self.alias = a - self.crc = binascii.crc32(str(alias).encode()) & 0xffffffff - global_crc = binascii.crc32(str(alias).encode(), global_crc) - global_type_add(name) + self.crc = str(alias).encode() + global_type_add(name, self) def __repr__(self): return self.name + str(self.alias) @@ -183,11 +174,10 @@ class Union(): self.type = 'Union' self.manual_print = False self.manual_endian = False - global global_crc self.name = name self.block = block - self.crc = crc_block(block) - global_type_add(name) + self.crc = str(block).encode() + global_type_add(name, self) def __repr__(self): return str(self.block) @@ -198,7 +188,7 @@ class Define(): self.name = name self.flags = flags self.block = block - self.crc = crc_block(block) + self.crc = str(block).encode() self.dont_trace = False self.manual_print = False self.manual_endian = False @@ -238,8 +228,8 @@ class Enum(): block[i] = [b, count] self.block = block - self.crc = crc_block(block) - global_type_add(name) + self.crc = str(block).encode() + global_type_add(name, self) def __repr__(self): return self.name + str(self.block) @@ -271,7 +261,7 @@ class Import(): class Option(): def __init__(self, option): self.option = option - self.crc = crc_block(option) + self.crc = str(option).encode() def __repr__(self): return str(self.option) @@ -629,8 +619,13 @@ class VPPAPI(object): s['types'] = [] s['Import'] = [] s['Alias'] = {} + crc = 0 for o in objs: tname = o.__class__.__name__ + try: + crc = binascii.crc32(o.crc, crc) + except AttributeError: + pass if isinstance(o, Define): s[tname].append(o) if o.autoreply: @@ -658,6 +653,8 @@ class VPPAPI(object): replies = {s.reply: s for s in s['Service']} seen_services = {} + s['file_crc'] = crc + for service in svcs: if service not in msgs: raise ValueError( @@ -754,6 +751,23 @@ def dirlist_add(dirs): def dirlist_get(): return dirlist +def foldup_blocks(block, crc): + for b in block: + # Look up CRC in user defined types + if b.fieldtype.startswith('vl_api_'): + # Recursively + t = global_types[b.fieldtype] + try: + crc = crc_block_combine(t.block, crc) + return foldup_blocks(t.block, crc) + except: + pass + return crc + +def foldup_crcs(s): + for f in s: + f.crc = foldup_blocks(f.block, + binascii.crc32(f.crc)) # # Main @@ -811,7 +825,8 @@ def main(): # Add msg_id field s['Define'] = add_msg_id(s['Define']) - file_crc = global_crc & 0xffffffff + # Fold up CRCs + foldup_crcs(s['Define']) # # Debug @@ -855,7 +870,7 @@ def main(): raise Exception('Error importing output plugin: {}, {}' .format(module_path, err)) - result = plugin.run(filename, s, file_crc) + result = plugin.run(filename, s) if result: print(result, file=args.output) else: diff --git a/src/tools/vppapigen/vppapigen_c.py b/src/tools/vppapigen/vppapigen_c.py index b34d063c340..93d14f3f617 100644 --- a/src/tools/vppapigen/vppapigen_c.py +++ b/src/tools/vppapigen/vppapigen_c.py @@ -295,7 +295,7 @@ def version_tuple(s, module): # # Plugin entry point # -def run(input_filename, s, file_crc): +def run(input_filename, s): basename = os.path.basename(input_filename) filename, file_extension = os.path.splitext(basename) output = top_boilerplate.format(datestring=datestring, @@ -308,6 +308,6 @@ def run(input_filename, s, file_crc): output += endianfun(s['types'] + s['Define']) output += version_tuple(s, basename) output += bottom_boilerplate.format(input_filename=basename, - file_crc=file_crc) + file_crc=s['file_crc']) return output diff --git a/src/tools/vppapigen/vppapigen_json.py b/src/tools/vppapigen/vppapigen_json.py index 94a9e19577e..124c0d3a0bd 100644 --- a/src/tools/vppapigen/vppapigen_json.py +++ b/src/tools/vppapigen/vppapigen_json.py @@ -26,7 +26,7 @@ def walk_services(s): return r -def walk_defs(s): +def walk_defs(s, is_message = False): r = [] for t in s: d = [] @@ -47,7 +47,7 @@ def walk_defs(s): else: raise ValueError("Error in processing array type %s" % b) - if t.crc: + if is_message and t.crc: c = {} c['crc'] = "{0:#0{1}x}".format(t.crc, 10) d.append(c) @@ -59,15 +59,15 @@ def walk_defs(s): # # Plugin entry point # -def run(filename, s, file_crc): +def run(filename, s): j = {} j['types'] = walk_defs([o for o in s['types'] if o.__class__.__name__ == 'Typedef']) - j['messages'] = walk_defs(s['Define']) + j['messages'] = walk_defs(s['Define'], True) j['unions'] = walk_defs([o for o in s['types'] if o.__class__.__name__ == 'Union']) j['enums'] = walk_enums([o for o in s['types'] if o.__class__.__name__ == 'Enum']) j['services'] = walk_services(s['Service']) j['options'] = s['Option'] j['aliases'] = s['Alias'] - j['vl_api_version'] = hex(file_crc) + j['vl_api_version'] = hex(s['file_crc']) return json.dumps(j, indent=4, separators=(',', ': ')) diff --git a/src/vpp-api/vapi/vapi_json_parser.py b/src/vpp-api/vapi/vapi_json_parser.py index fbeb1887ac2..a9d2c8186bc 100644 --- a/src/vpp-api/vapi/vapi_json_parser.py +++ b/src/vpp-api/vapi/vapi_json_parser.py @@ -365,9 +365,8 @@ class JsonParser(object): continue try: type_pairs = [[self.lookup_type_like_id(t), n] - for t, n in u[1:-1]] - crc = u[-1]["crc"] - union = self.union_class(name, type_pairs, crc) + for t, n in u[1:]] + union = self.union_class(name, type_pairs, 0) progress = progress + 1 except ParseError as e: exceptions.append(e) -- 2.16.6