X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Ftools%2Fvppapigen%2Fvppapigen.py;h=57e5e3a411ee95321a9cf4749d67fc14fe1c4f24;hb=b533f3fadeab73aef04b6fd65ab997ed7fce50df;hp=81f26fe44328de75bb4fb59989f3c13467ac5a1d;hpb=9d42087149a6870965896be74dc6260f72d2cac9;p=vpp.git diff --git a/src/tools/vppapigen/vppapigen.py b/src/tools/vppapigen/vppapigen.py index 81f26fe4432..57e5e3a411e 100755 --- a/src/tools/vppapigen/vppapigen.py +++ b/src/tools/vppapigen/vppapigen.py @@ -41,6 +41,7 @@ class VPPAPILexer(object): 'service': 'SERVICE', 'rpc': 'RPC', 'returns': 'RETURNS', + 'null': 'NULL', 'stream': 'STREAM', 'events': 'EVENTS', 'define': 'DEFINE', @@ -115,12 +116,6 @@ class VPPAPILexer(object): # A string containing ignored characters (spaces and tabs) t_ignore = ' \t' - -class Iterator(type): - def __iter__(self): - return self.iter() - - class Service(): def __init__(self, caller, reply, events=[], stream=False): self.caller = caller @@ -346,9 +341,14 @@ class VPPAPIParser(object): p[0] = p[1] + [p[2]] def p_service_statement(self, p): - '''service_statement : RPC ID RETURNS ID ';' + '''service_statement : RPC ID RETURNS NULL ';' + | 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: @@ -571,29 +571,40 @@ class VPPAPI(object): if isinstance(o2, Service): s['services'].append(o2) - # Create services implicitly + 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: if service not in msgs: raise ValueError('Service definition refers to unknown message' ' definition: {}'.format(service)) - if svcs[service].reply not in msgs: + if svcs[service].reply != 'null' and svcs[service].reply not in msgs: 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 ' 'event: {} in message: {}' .format(event, service)) + seen_services[event] = True + # Create services implicitly for d in msgs: - if msgs[d].singular is True: + if d in seen_services: continue - if d.endswith('_counters'): + 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 @@ -629,10 +640,16 @@ class VPPAPI(object): return s - def process_imports(self, objs): + def process_imports(self, objs, in_import): + imported_objs = [] for o in objs: if isinstance(o, Import): - return objs + self.process_imports(o.result) + return objs + self.process_imports(o.result, True) + if in_import: + if isinstance(o, Define) and o.typeonly: + imported_objs.append(o) + if in_import: + return imported_objs return objs @@ -664,9 +681,6 @@ def dirlist_get(): # Main # def main(): - logging.basicConfig() - log = logging.getLogger('vppapigen') - cliparser = argparse.ArgumentParser(description='VPP API generator') cliparser.add_argument('--pluginpath', default=""), cliparser.add_argument('--includedir', action='append'), @@ -692,11 +706,18 @@ def main(): else: filename = '' + if args.debug: + logging.basicConfig(stream=sys.stdout, level=logging.WARNING) + else: + logging.basicConfig() + log = logging.getLogger('vppapigen') + + parser = VPPAPI(debug=args.debug, filename=filename, logger=log) result = parser.parse_file(args.input, log) # Build a list of objects. Hash of lists. - result = parser.process_imports(result) + result = parser.process_imports(result, False) s = parser.process(result) # Add msg_id field @@ -720,11 +741,21 @@ def main(): import imp # Default path + pluginpath = '' if not args.pluginpath: - pluginpath = os.path.dirname(os.path.realpath(__file__)) + \ - '/../share/vpp/' + cand = [] + cand.append(os.path.dirname(os.path.realpath(__file__))) + cand.append(os.path.dirname(os.path.realpath(__file__)) + \ + '/../share/vpp/') + for c in cand: + c += '/' + if os.path.isfile(c + args.output_module + '.py'): + pluginpath = c + break else: pluginpath = args.pluginpath + '/' + if pluginpath == '': + raise Exception('Output plugin not found') module_path = pluginpath + args.output_module + '.py' try: