mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
4aa197dbdb
fa4632c41714dfaa699bacc6a947d72668a4deef test: Move boost/stdlib includes last (MarcoFalke) fa488f131fd4f5bab0d01376c5a5013306f1abcd scripted-diff: Bump copyright headers (MarcoFalke) fac5c373006a9e4bcbb56843bb85f1aca4d87599 scripted-diff: Sort test includes (MarcoFalke) Pull request description: When writing tests, often includes need to be added or removed. Currently the list of includes is not sorted, so developers that write tests and have `clang-format` installed will either have an unrelated change (sorting) included in their commit or they will have to manually undo the sort. This pull preempts both issues by just sorting all includes in one commit. Please be aware that this is **NOT** a change to policy to enforce clang-format or any other developer guideline or process. Developers are free to use whatever tool they want, see also #18651. Edit: Also includes a commit to bump the copyright headers, so that the touched files don't need to be touched again for that. ACKs for top commit: practicalswift: ACK fa4632c41714dfaa699bacc6a947d72668a4deef jonatack: ACK fa4632c41714dfaa, light review and sanity checks with gcc build and clang fuzz build Tree-SHA512: 130a8d073a379ba556b1e64104d37c46b671425c0aef0ed725fd60156a95e8dc83fb6f0b5330b2f8152cf5daaf3983b4aca5e75812598f2626c39fd12b88b180
124 lines
3.8 KiB
Python
Executable File
124 lines
3.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright (c) 2018-2019 The Bitcoin Core developers
|
|
# Distributed under the MIT software license, see the accompanying
|
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
import sys
|
|
import re
|
|
from multiprocess import Pool
|
|
|
|
MAPPING = {
|
|
'core_read.cpp': 'core_io.cpp',
|
|
'core_write.cpp': 'core_io.cpp',
|
|
}
|
|
|
|
# Directories with header-based modules, where the assumption that .cpp files
|
|
# define functions and variables declared in corresponding .h files is
|
|
# incorrect.
|
|
HEADER_MODULE_PATHS = [
|
|
'interfaces/'
|
|
]
|
|
|
|
def module_name(path):
|
|
if path in MAPPING:
|
|
path = MAPPING[path]
|
|
if any(path.startswith(dirpath) for dirpath in HEADER_MODULE_PATHS):
|
|
return path
|
|
if path.endswith(".h"):
|
|
return path[:-2]
|
|
if path.endswith(".c"):
|
|
return path[:-2]
|
|
if path.endswith(".cpp"):
|
|
return path[:-4]
|
|
return None
|
|
|
|
if __name__=="__main__":
|
|
files = dict()
|
|
deps = dict()
|
|
|
|
RE = re.compile("^#include <(.*)>")
|
|
|
|
def handle_module(arg):
|
|
module = module_name(arg)
|
|
if module is None:
|
|
print("Ignoring file %s (does not constitute module)\n" % arg)
|
|
else:
|
|
files[arg] = module
|
|
deps[module] = set()
|
|
|
|
def handle_module2(module):
|
|
# Build the transitive closure of dependencies of module
|
|
closure = dict()
|
|
for dep in deps[module]:
|
|
closure[dep] = []
|
|
while True:
|
|
old_size = len(closure)
|
|
old_closure_keys = sorted(closure.keys())
|
|
for src in old_closure_keys:
|
|
for dep in deps[src]:
|
|
if dep not in closure:
|
|
closure[dep] = closure[src] + [src]
|
|
if len(closure) == old_size:
|
|
break
|
|
# If module is in its own transitive closure, it's a circular dependency; check if it is the shortest
|
|
if module in closure:
|
|
return [module] + closure[module]
|
|
|
|
return None
|
|
|
|
|
|
# Iterate over files, and create list of modules
|
|
for arg in sys.argv[1:]:
|
|
handle_module(arg)
|
|
|
|
def build_list_direct(arg):
|
|
module = files[arg]
|
|
with open(arg, 'r', encoding="utf8") as f:
|
|
for line in f:
|
|
match = RE.match(line)
|
|
if match:
|
|
include = match.group(1)
|
|
included_module = module_name(include)
|
|
if included_module is not None and included_module in deps and included_module != module:
|
|
deps[module].add(included_module)
|
|
|
|
|
|
# Iterate again, and build list of direct dependencies for each module
|
|
# TODO: implement support for multiple include directories
|
|
for arg in sorted(files.keys()):
|
|
build_list_direct(arg)
|
|
# Loop to find the shortest (remaining) circular dependency
|
|
|
|
def shortest_c_dep():
|
|
have_cycle = False
|
|
|
|
sorted_keys = None
|
|
|
|
while True:
|
|
|
|
shortest_cycles = None
|
|
if sorted_keys is None:
|
|
sorted_keys = sorted(deps.keys())
|
|
|
|
with Pool(8) as pool:
|
|
cycles = pool.map(handle_module2, sorted_keys)
|
|
|
|
for cycle in cycles:
|
|
if cycle is not None and (shortest_cycles is None or len(cycle) < len(shortest_cycles)):
|
|
shortest_cycles = cycle
|
|
|
|
if shortest_cycles is None:
|
|
break
|
|
# We have the shortest circular dependency; report it
|
|
module = shortest_cycles[0]
|
|
print("Circular dependency: %s" % (" -> ".join(shortest_cycles + [module])))
|
|
# And then break the dependency to avoid repeating in other cycles
|
|
deps[shortest_cycles[-1]] -= {module}
|
|
sorted_keys = None
|
|
have_cycle = True
|
|
|
|
if have_cycle:
|
|
return True
|
|
|
|
sys.exit(1 if shortest_c_dep() else 0)
|