1#!/usr/bin/env python 2# 3# Copyright 2017, Data61 4# Commonwealth Scientific and Industrial Research Organisation (CSIRO) 5# ABN 41 687 119 230. 6# 7# This software may be distributed and modified according to the terms of 8# the BSD 2-Clause license. Note that NO WARRANTY is provided. 9# See "LICENSE_BSD2.txt" for details. 10# 11# @TAG(DATA61_BSD) 12# 13""" 14Script for reporting circular #includes in pre-processed sel4 source. 15Exits with a status of 0 if no circular dependencies are found, otherwise 16prints circular dependency and exits with a status of -1. 17""" 18 19import sys 20import re 21import argparse 22 23def main(parse_args): 24 """ 25 Reads pre-processed sel4 source from standard input. 26 If a circular dependency is found, the chain of includes 27 resulting in the loop is printed out. 28 """ 29 30 ignore_re = None 31 ignore_args = parse_args.ignore 32 if ignore_args and len(ignore_args): 33 ignore_args = [re.escape(ignore) for ignore in ignore_args] 34 ignore_re_string = '(' + '|'.join(ignore_args) + ')' 35 ignore_re = re.compile(r'^# 1 ".*' + ignore_re_string + '"') 36 37 header_re = re.compile(r'^# (\d+) "(.*\..)"') 38 39 file_stack = [] 40 41 for line in sys.stdin: 42 43 if ignore_re and ignore_re.match(line): 44 continue 45 46 match = header_re.match(line) 47 48 if match is None: 49 continue 50 51 depth = int(match.group(1)) 52 header = match.group(2) 53 54 if depth == 1: 55 # found a new header 56 if header in file_stack: 57 print("Circular includes found:") 58 print("\n".join(file_stack)) 59 print(header) 60 return -1 61 else: 62 file_stack.append(header) 63 else: 64 # popped back up to an earlier header 65 while file_stack[-1] != header: 66 file_stack.pop() 67 68 return 0 69 70if __name__ == "__main__": 71 72 parser = argparse.ArgumentParser() 73 parser.add_argument('--ignore', nargs='+', 74 help="Files to ignore when parsing the sel4 source") 75 args = parser.parse_args() 76 77 sys.exit(main(args)) 78