| #!/usr/bin/env python3 | 
 | """ | 
 | Generate a Makefile .d fragment for the Verilog includes. | 
 | """ | 
 |  | 
 | import argparse | 
 | import os | 
 | import re | 
 | import sys | 
 |  | 
 | from io import StringIO | 
 |  | 
 | from lib.deps import add_dependency | 
 | from lib.deps import write_deps | 
 |  | 
 | parser = argparse.ArgumentParser() | 
 | parser.add_argument( | 
 |     "inputfile", type=argparse.FileType('r'), help="Input Verilog file" | 
 | ) | 
 | parser.add_argument( | 
 |     "--file_per_line", | 
 |     action='store_true', | 
 |     help="Output dependencies file per line, rather than Make .d format." | 
 | ) | 
 |  | 
 | v_include = re.compile(r'`include[ ]*"([^"]*)"|\$readmem[bh]\("(.*)",(.*)\)') | 
 |  | 
 |  | 
 | def read_dependencies(inputfile): | 
 |     """Read the dependencies out of a verilog file. | 
 |  | 
 |     >>> list(read_dependencies(StringIO(''' | 
 |     ... `include "a.h" | 
 |     ... `include "b.h" /* Cmt | 
 |     ... `include "c.h" | 
 |     ...    */ | 
 |     ... `include "d.h" // Cmt | 
 |     ... // `include "e.h" | 
 |     ...   `include "f.h" | 
 |     ... '''))) | 
 |     ['a.h', 'b.h', 'd.h', 'f.h'] | 
 |  | 
 |     """ | 
 |     data = inputfile.read() | 
 |     # Strip out the /* */ comments | 
 |     data = re.sub('/\\*.*\\*/', '', data, flags=re.DOTALL) | 
 |     # Strip out the // comments | 
 |     data = re.sub(r'//[^\n]*', '', data) | 
 |  | 
 |     matches = v_include.findall(data) | 
 |     for includefile in matches: | 
 |         yield includefile[0] + includefile[1] | 
 |  | 
 |  | 
 | def main(argv): | 
 |     args = parser.parse_args(argv[1:]) | 
 |     inputpath = os.path.abspath(args.inputfile.name) | 
 |     inputdir = os.path.dirname(inputpath) | 
 |  | 
 |     if args.file_per_line: | 
 |         for dep in read_dependencies(args.inputfile): | 
 |             print(os.path.abspath(os.path.join(inputdir, dep))) | 
 |     else: | 
 |         data = StringIO() | 
 |         for includefile in read_dependencies(args.inputfile): | 
 |             add_dependency( | 
 |                 data, inputpath, | 
 |                 os.path.abspath(os.path.join(inputdir, includefile)) | 
 |             ) | 
 |  | 
 |         write_deps(args.inputfile.name, data) | 
 |  | 
 |  | 
 | if __name__ == "__main__": | 
 |     if len(sys.argv) == 1: | 
 |         import doctest | 
 |         failure_count, test_count = doctest.testmod() | 
 |         assert test_count > 0 | 
 |         assert failure_count == 0, "Doctests failed!" | 
 |     sys.exit(main(sys.argv)) |