aboutsummaryrefslogtreecommitdiffstats
path: root/src/tools/vppapigen
diff options
context:
space:
mode:
authorOle Troan <ot@cisco.com>2019-04-24 14:31:18 +0200
committerPaul Vinciguerra <pvinci@vinciconsulting.com>2019-06-07 10:13:59 +0000
commit8dbfb433619011b649b1b511ad88969a7f909861 (patch)
tree40e9b9b19a3a0910c809a6053b61f4143f3fe0c9 /src/tools/vppapigen
parent8edca1361674ce116a3a02d3adbfe0a78a28a2ca (diff)
vppapigen: Fold up CRC from dependent types.
Change-Id: Id51f26f225cd567ca19efc2301e94fa88840ae8f Signed-off-by: Ole Troan <ot@cisco.com> Type: fix Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'src/tools/vppapigen')
-rwxr-xr-xsrc/tools/vppapigen/vppapigen.py67
-rw-r--r--src/tools/vppapigen/vppapigen_c.py4
-rw-r--r--src/tools/vppapigen/vppapigen_json.py10
3 files changed, 48 insertions, 33 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=(',', ': '))