From 4fef972c2a317ab1e8da6c0629ba5cb028142799 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 7 Mar 2014 01:08:03 +0400 Subject: [PATCH] DSDL compiler fix: detecting DTID collisions from all namespaces --- libuavcan/dsdl_compiler/dsdlc.py | 12 ++++-------- pyuavcan/pyuavcan/dsdl/__init__.py | 2 +- pyuavcan/pyuavcan/dsdl/parser.py | 15 ++++++++------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/libuavcan/dsdl_compiler/dsdlc.py b/libuavcan/dsdl_compiler/dsdlc.py index 773648a685..fa93f1eaaa 100755 --- a/libuavcan/dsdl_compiler/dsdlc.py +++ b/libuavcan/dsdl_compiler/dsdlc.py @@ -44,9 +44,9 @@ def configure_logging(verbosity): level = { 0: logging.WARNING, 1: logging.INFO, 2: logging.DEBUG }.get(verbosity or 0, logging.DEBUG) logging.basicConfig(stream=sys.stderr, level=level, format=fmt) -def run_parser(source_dir, search_dirs): +def run_parser(source_dirs, search_dirs): try: - types = dsdl.parse_namespace(source_dir, search_dirs) + types = dsdl.parse_namespaces(source_dirs, search_dirs) except dsdl.DsdlException as ex: logging.info('Parser failure', exc_info=True) die(str(ex)) @@ -202,13 +202,9 @@ args = argparser.parse_args() configure_logging(args.verbose) -types = [] -for srcdir in args.source_dir: - new_types = run_parser(srcdir, args.incdir + args.source_dir) - types += new_types - logging.info('%d types from [%s]', len(new_types), srcdir) - +types = run_parser(args.source_dir, args.incdir + args.source_dir) if not types: die('No type definitions were found') +logging.info('%d types total', len(types)) run_generator(types, args.outdir) diff --git a/pyuavcan/pyuavcan/dsdl/__init__.py b/pyuavcan/pyuavcan/dsdl/__init__.py index c9399f6af4..f364dd0624 100644 --- a/pyuavcan/pyuavcan/dsdl/__init__.py +++ b/pyuavcan/pyuavcan/dsdl/__init__.py @@ -2,7 +2,7 @@ # Copyright (C) 2014 Pavel Kirienko # -from .parser import Parser, parse_namespace, \ +from .parser import Parser, parse_namespaces, \ Type, PrimitiveType, ArrayType, CompoundType, \ Attribute, Field, Constant diff --git a/pyuavcan/pyuavcan/dsdl/parser.py b/pyuavcan/pyuavcan/dsdl/parser.py index f03d198254..01d1b7cb9f 100644 --- a/pyuavcan/pyuavcan/dsdl/parser.py +++ b/pyuavcan/pyuavcan/dsdl/parser.py @@ -478,17 +478,18 @@ def validate_data_struct_len(t): 'Max data structure length is invalid: %d bits, %d bytes', bitlen, bytelen) -def parse_namespace(source_dir, search_dirs): +def parse_namespaces(source_dirs, search_dirs): def walk(): import fnmatch from functools import partial def on_walk_error(directory, ex): raise DsdlException('OS error in [%s]: %s' % (directory, str(ex))) from ex - walker = os.walk(source_dir, onerror=partial(on_walk_error, source_dir), followlinks=True) - for root, _dirnames, filenames in walker: - for filename in fnmatch.filter(filenames, '*.uavcan'): - filename = os.path.join(root, filename) - yield filename + for source_dir in source_dirs: + walker = os.walk(source_dir, onerror=partial(on_walk_error, source_dir), followlinks=True) + for root, _dirnames, filenames in walker: + for filename in fnmatch.filter(filenames, '*.uavcan'): + filename = os.path.join(root, filename) + yield filename all_default_dtid = {} # (kind, dtid) : filename def ensure_unique_dtid(t, filename): @@ -501,7 +502,7 @@ def parse_namespace(source_dir, search_dirs): error('Default data type ID collision: [%s] [%s]', first, second) all_default_dtid[key] = filename - parser = Parser([source_dir] + search_dirs) + parser = Parser(source_dirs + search_dirs) output_types = [] for filename in walk(): t = parser.parse(filename)