Files
lab-rv32i-freertos-c-scheduler/vendor/Hazard3/scripts/listfiles
T

104 lines
3.5 KiB
Python
Executable File

#!/usr/bin/env python3
import shlex
import os
import sys
import argparse
import re
help_str = """
Tool for building file lists, into formats required by various tools.
".f" files contain four types of command:
file (filename)
adds a file to the list
include (dir)
add a directory to include path, if output format supports this
wildcard (.extension) (dir)
add all files with a given extension in a given directory
list (filename)
recurse on another filelist file
The idea is that each component in a project has a
.f file which lists all of the Verilog (e.g.) files
for that component. Higher-level .f files will hierarchically
include the lower-level ones.
In this way, you can build large flat file lists to pass into the
various tools, but never have to *write* large flat file lists.
It also makes it easier to specify parts of your design hierarchy
for a given tool. For example, if you just want to synthesise your
CPU, you can run "listfiles cpu.f -f flat"
"""
def wildcard(dir, extension):
prev_dir = os.getcwd()
os.chdir(dir)
files = [os.path.abspath(f) for f in os.listdir() if os.path.splitext(f)[-1] == extension]
os.chdir(prev_dir)
return files
def read_filelist(fname):
files = []
includes = []
f = open(fname)
prev_dir = os.getcwd()
os.chdir(os.path.dirname(os.path.abspath(fname)))
for l in f.readlines():
l = l.split("#")[0].strip()
if l == "":
continue
words = shlex.split(l)
if words[0] == "file":
assert(len(words) == 2)
files.append(os.path.abspath(os.path.expandvars(words[1])))
elif words[0] == "include":
assert(len(words) == 2)
includes.append(os.path.abspath(os.path.expandvars(words[1])))
elif words[0] == "wildcard":
assert(len(words) == 3)
files.extend(wildcard(os.path.expandvars(words[2]), words[1]))
elif words[0] == "list":
assert(len(words) == 2)
newfiles, newincludes = read_filelist(os.path.expandvars(words[1]))
files.extend(newfiles)
includes.extend(newincludes)
else:
raise Exception("In filelist {}: Invalid command \"{}\"".format(fname, words[0]))
os.chdir(prev_dir)
return (files, includes)
formats = {
"isim": lambda f, i: "verilog work {} {}\n".format(" ".join(f), " ".join("-i " + inc for inc in i)),
"flat": lambda f, i: " ".join(f) + "\n",
"flati": lambda f, i: " ".join(i) + "\n",
"make": lambda f, i: "SRCS={}\nINCDIRS={}\n".format(" ".join(f), " ".join(i))
}
if __name__ == "__main__":
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
parser.epilog = help_str
parser.add_argument("src", help="File list source file")
parser.add_argument("--format", "-f", help="Format to generate output in. Allowed: isim, make, flat (default)")
parser.add_argument("--relative", "-r", action="store_true", help="Use relative paths in output file")
parser.add_argument("--relativeto", help="Use relative paths, relative to some specified path")
parser.add_argument("--output", "-o", help="Output file name")
args = parser.parse_args()
if args.format is None:
args.format = "flat"
files, includes = read_filelist(args.src)
# Uniquify whilst preserving order
func = lambda l: list(dict.fromkeys(l))
if args.relative:
func = lambda l, func=func: [os.path.relpath(f) for f in func(l)]
elif args.relativeto:
func = lambda l, func=func: [os.path.relpath(f, args.relativeto) for f in func(l)]
files, includes = map(func, (files, includes))
if args.format not in formats:
sys.exit("Unknown format: " + args.format)
ofile = sys.stdout if args.output is None else open(args.output, "w")
ofile.write(formats[args.format](files, includes))