mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-12 22:23:49 +01:00
Extend includes.py to compare topology with subsystem init order.
This commit is contained in:
parent
c323cc0913
commit
a40d539f7c
@ -173,6 +173,27 @@ def remove_self_edges(graph):
|
|||||||
for k in list(graph):
|
for k in list(graph):
|
||||||
graph[k] = [ d for d in graph[k] if d != k ]
|
graph[k] = [ d for d in graph[k] if d != k ]
|
||||||
|
|
||||||
|
def closure(graph):
|
||||||
|
"""Takes a directed graph in as an adjacency mapping (a mapping from
|
||||||
|
node to a list of the nodes to which it connects), and completes
|
||||||
|
its closure.
|
||||||
|
"""
|
||||||
|
graph = graph.copy()
|
||||||
|
changed = False
|
||||||
|
for k in graph.keys():
|
||||||
|
graph[k] = set(graph[k])
|
||||||
|
while True:
|
||||||
|
for k in graph.keys():
|
||||||
|
sz = len(graph[k])
|
||||||
|
for v in list(graph[k]):
|
||||||
|
graph[k].update(graph.get(v, []))
|
||||||
|
if sz != len(graph[k]):
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
if not changed:
|
||||||
|
return graph
|
||||||
|
changed = False
|
||||||
|
|
||||||
def toposort(graph, limit=100):
|
def toposort(graph, limit=100):
|
||||||
"""Takes a directed graph in as an adjacency mapping (a mapping from
|
"""Takes a directed graph in as an adjacency mapping (a mapping from
|
||||||
node to a list of the nodes to which it connects). Tries to
|
node to a list of the nodes to which it connects). Tries to
|
||||||
@ -233,8 +254,25 @@ def walk_c_files(topdir="src"):
|
|||||||
for err in consider_include_rules(fullpath, f):
|
for err in consider_include_rules(fullpath, f):
|
||||||
yield err
|
yield err
|
||||||
|
|
||||||
|
def check_subsys_file(fname, uses_dirs):
|
||||||
|
uses_closure = closure(uses_dirs)
|
||||||
|
ok = True
|
||||||
|
previous_subsystems = []
|
||||||
|
with open(fname) as f:
|
||||||
|
for line in f:
|
||||||
|
_, name, fname = line.split()
|
||||||
|
fname = re.sub(r'^.*/src/', "", fname)
|
||||||
|
fname = re.sub(r'^src/', "", fname)
|
||||||
|
fname = re.sub(r'/[^/]*\.c', "", fname)
|
||||||
|
for prev in previous_subsystems:
|
||||||
|
if fname in uses_closure[prev]:
|
||||||
|
print("INVERSION: {} uses {}".format(prev,fname))
|
||||||
|
ok = False
|
||||||
|
previous_subsystems.append(fname)
|
||||||
|
return not ok
|
||||||
|
|
||||||
def run_check_includes(topdir, list_unused=False, log_sorted_levels=False,
|
def run_check_includes(topdir, list_unused=False, log_sorted_levels=False,
|
||||||
list_advisories=False):
|
list_advisories=False, check_subsystem_order=None):
|
||||||
trouble = False
|
trouble = False
|
||||||
|
|
||||||
for err in walk_c_files(topdir):
|
for err in walk_c_files(topdir):
|
||||||
@ -259,6 +297,11 @@ def run_check_includes(topdir, list_unused=False, log_sorted_levels=False,
|
|||||||
uses_dirs[rules.incpath] = rules.getAllowedDirectories()
|
uses_dirs[rules.incpath] = rules.getAllowedDirectories()
|
||||||
|
|
||||||
remove_self_edges(uses_dirs)
|
remove_self_edges(uses_dirs)
|
||||||
|
|
||||||
|
if check_subsystem_order:
|
||||||
|
if check_subsys_file(check_subsystem_order, uses_dirs):
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
all_levels = toposort(uses_dirs)
|
all_levels = toposort(uses_dirs)
|
||||||
|
|
||||||
if log_sorted_levels:
|
if log_sorted_levels:
|
||||||
@ -282,6 +325,8 @@ def main(argv):
|
|||||||
help="List unused lines in .may_include files.")
|
help="List unused lines in .may_include files.")
|
||||||
parser.add_argument("--list-advisories", action="store_true",
|
parser.add_argument("--list-advisories", action="store_true",
|
||||||
help="List advisories as well as forbidden includes")
|
help="List advisories as well as forbidden includes")
|
||||||
|
parser.add_argument("--check-subsystem-order", action="store",
|
||||||
|
help="Check a list of subsystems for ordering")
|
||||||
parser.add_argument("topdir", default="src", nargs="?",
|
parser.add_argument("topdir", default="src", nargs="?",
|
||||||
help="Top-level directory for the tor source")
|
help="Top-level directory for the tor source")
|
||||||
args = parser.parse_args(argv[1:])
|
args = parser.parse_args(argv[1:])
|
||||||
@ -289,7 +334,8 @@ def main(argv):
|
|||||||
run_check_includes(topdir=args.topdir,
|
run_check_includes(topdir=args.topdir,
|
||||||
log_sorted_levels=args.toposort,
|
log_sorted_levels=args.toposort,
|
||||||
list_unused=args.list_unused,
|
list_unused=args.list_unused,
|
||||||
list_advisories=args.list_advisories)
|
list_advisories=args.list_advisories,
|
||||||
|
check_subsystem_order=args.check_subsystem_order)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main(sys.argv)
|
main(sys.argv)
|
||||||
|
Loading…
Reference in New Issue
Block a user