dpdk: DPDK 20.05 iavf flow director backporting to DPDK 20.02
[vpp.git] / src / tools / vppapigen / vppapigen.py
index bb4e2c4..b17ad6d 100755 (executable)
@@ -145,6 +145,33 @@ def crc_block_combine(block, crc):
     return binascii.crc32(s, crc) & 0xffffffff
 
 
+def vla_is_last_check(name, block):
+    vla = False
+    for i, b in enumerate(block):
+        if isinstance(b, Array) and b.vla:
+            vla = True
+            if i + 1 < len(block):
+                raise ValueError(
+                    'VLA field "{}" must be the last field in message "{}"'
+                    .format(b.fieldname, name))
+        elif b.fieldtype.startswith('vl_api_'):
+            if global_types[b.fieldtype].vla:
+                vla = True
+                if i + 1 < len(block):
+                    raise ValueError(
+                        'VLA field "{}" must be the last '
+                        'field in message "{}"'
+                        .format(b.fieldname, name))
+        elif b.fieldtype == 'string' and b.length == 0:
+            vla = True
+            if i + 1 < len(block):
+                raise ValueError(
+                    'VLA field "{}" must be the last '
+                    'field in message "{}"'
+                    .format(b.fieldname, name))
+    return vla
+
+
 class Service():
     def __init__(self, caller, reply, events=None, stream=False):
         self.caller = caller
@@ -166,34 +193,10 @@ class Typedef():
                 self.manual_print = True
             elif f == 'manual_endian':
                 self.manual_endian = True
-        for b in block:
-            # Tag length field of a VLA
-            if isinstance(b, Array):
-                if b.lengthfield:
-                    for b2 in block:
-                        if b2.fieldname == b.lengthfield:
-                            b2.vla_len = True
 
         global_type_add(name, self)
 
-        self.vla = False
-
-        for i, b in enumerate(block):
-            if isinstance(b, Array):
-                if b.length == 0:
-                    self.vla = True
-                    if i + 1 < len(block):
-                        raise ValueError(
-                            'VLA field "{}" must be the last '
-                            'field in message "{}"'
-                            .format(b.fieldname, name))
-            elif b.fieldtype == 'string':
-                self.vla = True
-                if i + 1 < len(block):
-                    raise ValueError(
-                        'VLA field "{}" must be the last '
-                        'field in message "{}"'
-                        .format(b.fieldname, name))
+        self.vla = vla_is_last_check(name, block)
 
     def __repr__(self):
         return self.name + str(self.flags) + str(self.block)
@@ -203,6 +206,9 @@ class Using():
     def __init__(self, name, flags, alias):
         self.name = name
         self.vla = False
+        self.block = []
+        self.manual_print = True
+        self.manual_endian = True
 
         self.manual_print = False
         self.manual_endian = False
@@ -232,8 +238,6 @@ class Union():
         self.manual_endian = False
         self.name = name
 
-        self.manual_print = False
-        self.manual_endian = False
         for f in flags:
             if f == 'manual_print':
                 self.manual_print = True
@@ -242,6 +246,8 @@ class Union():
 
         self.block = block
         self.crc = str(block).encode()
+        self.vla = vla_is_last_check(name, block)
+
         global_type_add(name, self)
 
     def __repr__(self):
@@ -253,12 +259,12 @@ class Define():
         self.name = name
         self.flags = flags
         self.block = block
-        self.crc = str(block).encode()
         self.dont_trace = False
         self.manual_print = False
         self.manual_endian = False
         self.autoreply = False
         self.singular = False
+        self.options = {}
         for f in flags:
             if f == 'dont_trace':
                 self.dont_trace = True
@@ -269,34 +275,16 @@ class Define():
             elif f == 'autoreply':
                 self.autoreply = True
 
-        for i, b in enumerate(block):
+        for b in block:
             if isinstance(b, Option):
                 if b[1] == 'singular' and b[2] == 'true':
                     self.singular = True
+                else:
+                    self.options[b.option] = b.value
                 block.remove(b)
 
-            if isinstance(b, Array) and b.vla and i + 1 < len(block):
-                raise ValueError(
-                    'VLA field "{}" must be the last field in message "{}"'
-                    .format(b.fieldname, name))
-            elif b.fieldtype.startswith('vl_api_'):
-                if (global_types[b.fieldtype].vla and i + 1 < len(block)):
-                    raise ValueError(
-                        'VLA field "{}" must be the last '
-                        'field in message "{}"'
-                        .format(b.fieldname, name))
-            elif b.fieldtype == 'string' and b.length == 0:
-                if i + 1 < len(block):
-                    raise ValueError(
-                        'VLA field "{}" must be the last '
-                        'field in message "{}"'
-                        .format(b.fieldname, name))
-            # Tag length field of a VLA
-            if isinstance(b, Array):
-                if b.lengthfield:
-                    for b2 in block:
-                        if b2.fieldname == b.lengthfield:
-                            b2.vla_len = True
+        self.vla = vla_is_last_check(name, block)
+        self.crc = str(block).encode()
 
     def __repr__(self):
         return self.name + str(self.flags) + str(self.block)
@@ -660,7 +648,7 @@ class VPPAPIParser(object):
         elif len(p) == 4:
             p[0] = Field(p[1], p[2])
         else:
-            self._parse_error('ERROR')
+            self._parse_error('ERROR', self._token_coord(p, 1))
         self.fields.append(p[2])
 
     def p_declaration_array_vla(self, p):
@@ -769,12 +757,11 @@ class VPPAPI(object):
         s['Service'] = []
         s['types'] = []
         s['Import'] = []
-        s['Alias'] = {}
         crc = 0
         for o in objs:
             tname = o.__class__.__name__
             try:
-                crc = binascii.crc32(o.crc, crc)
+                crc = binascii.crc32(o.crc, crc) & 0xffffffff
             except AttributeError:
                 pass
             if isinstance(o, Define):
@@ -782,17 +769,16 @@ class VPPAPI(object):
                 if o.autoreply:
                     s[tname].append(self.autoreply_block(o.name))
             elif isinstance(o, Option):
-                s[tname][o[1]] = o[2]
+                s[tname][o.option] = o.value
             elif type(o) is list:
                 for o2 in o:
                     if isinstance(o2, Service):
                         s['Service'].append(o2)
             elif (isinstance(o, Enum) or
                   isinstance(o, Typedef) or
+                  isinstance(o, Using) or
                   isinstance(o, Union)):
                 s['types'].append(o)
-            elif isinstance(o, Using):
-                s['Alias'][o.name] = o
             else:
                 if tname not in s:
                     raise ValueError('Unknown class type: {} {}'
@@ -922,7 +908,7 @@ def foldup_blocks(block, crc):
 def foldup_crcs(s):
     for f in s:
         f.crc = foldup_blocks(f.block,
-                              binascii.crc32(f.crc))
+                              binascii.crc32(f.crc) & 0xffffffff)
 
 
 #
@@ -938,6 +924,7 @@ def main():
     cliparser = argparse.ArgumentParser(description='VPP API generator')
     cliparser.add_argument('--pluginpath', default=""),
     cliparser.add_argument('--includedir', action='append'),
+    cliparser.add_argument('--outputdir', action='store'),
     cliparser.add_argument('--input',
                            type=argparse.FileType('r', encoding='UTF-8'),
                            default=sys.stdin)
@@ -1029,7 +1016,7 @@ def main():
                       .format(module_path, err))
         return 1
 
-    result = plugin.run(filename, s)
+    result = plugin.run(args, filename, s)
     if result:
         print(result, file=args.output)
     else: