feature: Add packet trace API
[vpp.git] / src / tools / vppapigen / vppapigen.py
index e571f26..fbb0f27 100755 (executable)
@@ -11,7 +11,7 @@ import os
 import sys
 from subprocess import Popen, PIPE
 
-assert sys.version_info >= (3, 6), \
+assert sys.version_info >= (3, 5), \
     "Not supported Python version: {}".format(sys.version)
 log = logging.getLogger('vppapigen')
 
@@ -130,7 +130,6 @@ class VPPAPILexer(object):
                                                  hex(ord(t.value[0])),
                                                  self.filename,
                                                  t.lexer.lineno))
-        t.lexer.skip(1)
 
     # Define a rule so we can track line numbers
     def t_newline(self, t):
@@ -143,11 +142,6 @@ class VPPAPILexer(object):
     t_ignore = ' \t'
 
 
-def crc_block_combine(block, crc):
-    s = str(block).encode()
-    return binascii.crc32(s, crc) & 0xffffffff
-
-
 def vla_is_last_check(name, block):
     vla = False
     for i, b in enumerate(block):
@@ -228,7 +222,12 @@ class Using():
         else:
             a = {'type': alias.fieldtype}
         self.alias = a
-        self.crc = str(alias).encode()
+        #
+        # Should have been:
+        #  self.crc = str(alias).encode()
+        # but to be backwards compatible use the block ([])
+        #
+        self.crc = str(self.block).encode()
         global_type_add(name, self)
 
     def __repr__(self):
@@ -304,15 +303,27 @@ class Enum():
         self.vla = False
 
         count = 0
-        for i, b in enumerate(block):
-            if type(b) is list:
-                count = b[1]
+        block2 = []
+        block3 = []
+        bc_set = False
+
+        for b in block:
+            if 'value' in b:
+                count = b['value']
             else:
                 count += 1
-                block[i] = [b, count]
-
-        self.block = block
-        self.crc = str(block).encode()
+            block2.append([b['id'], count])
+            try:
+                if b['option']['backwards_compatible']:
+                    pass
+                bc_set = True
+            except KeyError:
+                block3.append([b['id'], count])
+                if bc_set:
+                    raise ValueError("Backward compatible enum must be last {!r} {!r}"
+                                     .format(name, b['id']))
+        self.block = block2
+        self.crc = str(block3).encode()
         global_type_add(name, self)
 
     def __repr__(self):
@@ -622,11 +633,19 @@ class VPPAPIParser(object):
 
     def p_enum_statement(self, p):
         '''enum_statement : ID '=' NUM ','
-                          | ID ',' '''
-        if len(p) == 5:
-            p[0] = [p[1], p[3]]
+                          | ID ','
+                          | ID '[' field_options ']' ','
+                          | ID '=' NUM '[' field_options ']' ',' '''
+        if len(p) == 3:
+            p[0] = {'id': p[1]}
+        elif len(p) == 5:
+            p[0] = {'id': p[1], 'value': p[3]}
+        elif len(p) == 6:
+            p[0] = {'id': p[1], 'option': p[3]}
+        elif len(p) == 8:
+            p[0] = {'id': p[1], 'value': p[3], 'option': p[5]}
         else:
-            p[0] = p[1]
+            self._parse_error('ERROR', self._token_coord(p, 1))
 
     def p_field_options(self, p):
         '''field_options : field_option
@@ -761,12 +780,13 @@ class VPPAPI(object):
 
     def parse_filename(self, filename, debug=0):
         if self.revision:
-            git_show = f'git show  {self.revision}:{filename}'
+            git_show = 'git show {}:{}'.format(self.revision, filename)
             proc = Popen(git_show.split(), stdout=PIPE, encoding='utf-8')
             try:
                 data, errs = proc.communicate()
                 if proc.returncode != 0:
-                    print(f'File not found: {self.revision}:{filename}', file=sys.stderr)
+                    print('File not found: {}:{}'.format(self.revision,
+                      filename), file=sys.stderr)
                     sys.exit(2)
                 return self.parse_string(data, debug=debug)
             except Exception as e:
@@ -776,7 +796,7 @@ class VPPAPI(object):
                 with open(filename, encoding='utf-8') as fd:
                     return self.parse_fd(fd, None)
             except FileNotFoundError:
-                print(f'File not found: {filename}', file=sys.stderr)
+                print('File not found: {}'.format(filename), file=sys.stderr)
                 sys.exit(2)
 
     def autoreply_block(self, name, parent):
@@ -874,10 +894,16 @@ class VPPAPI(object):
                 continue
 
             if d.endswith('_details'):
-                if d[:-8]+'_dump' not in msgs:
-                    raise ValueError('{} missing dump message'
-                                     .format(d))
-                continue
+                if d[:-8]+'_get' in msgs:
+                    if d[:-8]+'_get' in svcs:
+                        continue
+                    else:
+                        raise ValueError('{} should be in a stream service'
+                                         .format(d[:-8]+'_get'))
+                if d[:-8]+'_dump' in msgs:
+                    continue
+                raise ValueError('{} missing dump or get message'
+                                 .format(d))
 
             if d in svcs:
                 continue
@@ -935,7 +961,7 @@ def foldup_blocks(block, crc):
             # Recursively
             t = global_types[b.fieldtype]
             try:
-                crc = crc_block_combine(t.block, crc)
+                crc = binascii.crc32(t.crc, crc) & 0xffffffff
                 crc = foldup_blocks(t.block, crc)
             except AttributeError:
                 pass