vppapigen: require reply/details messages for requests/dumps
[vpp.git] / src / tools / vppapigen / vppapigen.py
index 620b2ef..0779e80 100755 (executable)
@@ -9,6 +9,9 @@ import logging
 import binascii
 import os
 
+# Ensure we don't leave temporary files around
+sys.dont_write_bytecode = True
+
 #
 # VPP API language
 #
@@ -345,6 +348,10 @@ class VPPAPIParser(object):
                              | RPC ID RETURNS ID ';'
                              | RPC ID RETURNS STREAM ID ';'
                              | RPC ID RETURNS ID EVENTS event_list ';' '''
+        if p[2] == p[4]:
+            # Verify that caller and reply differ
+            self._parse_error('Reply ID ({}) should not be equal to Caller ID'.format(p[2]),
+                              self._token_coord(p, 1))
         if len(p) == 8:
             p[0] = Service(p[2], p[4], p[6])
         elif len(p) == 7:
@@ -523,7 +530,7 @@ class VPPAPI(object):
     def __init__(self, debug=False, filename='', logger=None):
         self.lexer = lex.lex(module=VPPAPILexer(filename), debug=debug)
         self.parser = yacc.yacc(module=VPPAPIParser(filename, logger),
-                                tabmodule='vppapigentab', debug=debug)
+                                write_tables=False, debug=debug)
         self.logger = logger
 
     def parse_string(self, code, debug=0, lineno=1):
@@ -570,6 +577,7 @@ class VPPAPI(object):
 
         msgs = {d.name: d for d in s['defines']}
         svcs = {s.caller: s for s in s['services']}
+        replies = {s.reply: s for s in s['services']}
         seen_services = {}
 
         for service in svcs:
@@ -580,6 +588,9 @@ class VPPAPI(object):
                 raise ValueError('Service definition refers to unknown message'
                                  ' definition in reply: {}'
                                  .format(svcs[service].reply))
+            if service in replies:
+                raise ValueError('Service definition refers to message'
+                                 ' marked as reply: {}'.format(service))
             for event in svcs[service].events:
                 if event not in msgs:
                     raise ValueError('Service definition refers to unknown '
@@ -593,16 +604,12 @@ class VPPAPI(object):
                 continue
             if msgs[d].singular is True:
                 continue
-            #if d.endswith('_counters'):
-            #    continue
-            #if d.endswith('_event'):
-            #    continue
             if d.endswith('_reply'):
                 if d[:-6] in svcs:
                     continue
                 if d[:-6] not in msgs:
-                    self.logger.warning('{} missing calling message'
-                                        .format(d))
+                    raise ValueError('{} missing calling message'
+                                     .format(d))
                 continue
             if d.endswith('_dump'):
                 if d in svcs:
@@ -611,14 +618,14 @@ class VPPAPI(object):
                     s['services'].append(Service(d, d[:-5]+'_details',
                                                  stream=True))
                 else:
-                    self.logger.error('{} missing details message'
-                                      .format(d))
+                    raise ValueError('{} missing details message'
+                                     .format(d))
                 continue
 
             if d.endswith('_details'):
                 if d[:-8]+'_dump' not in msgs:
-                    self.logger.error('{} missing dump message'
-                                      .format(d))
+                    raise ValueError('{} missing dump message'
+                                     .format(d))
                 continue
 
             if d in svcs:
@@ -626,9 +633,8 @@ class VPPAPI(object):
             if d+'_reply' in msgs:
                 s['services'].append(Service(d, d+'_reply'))
             else:
-                self.logger.warning('{} missing reply message ({})'
-                                    .format(d, d+'_reply'))
-                s['services'].append(Service(d, None))
+                raise ValueError('{} missing reply message ({}) or service definition'
+                                 .format(d, d+'_reply'))
 
         return s