55 lines
2.0 KiB
Python
55 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Busca dependencias circulares entre cabeceras públicas y entre módulos internos (por #include "...")."""
|
|
import os, re, sys
|
|
root = os.path.join(os.path.dirname(__file__), "..")
|
|
|
|
def includes(path):
|
|
out = []
|
|
for line in open(path, encoding="utf-8"):
|
|
m = re.match(r'\s*#\s*include\s+"([^"]+)"', line)
|
|
if m: out.append(m.group(1))
|
|
return out
|
|
|
|
def find_cycle(graph):
|
|
state, stack = {}, []
|
|
def dfs(n):
|
|
state[n] = 1; stack.append(n)
|
|
for m in graph.get(n, []):
|
|
if state.get(m) == 1: return stack[stack.index(m):] + [m]
|
|
if state.get(m) is None:
|
|
c = dfs(m)
|
|
if c: return c
|
|
stack.pop(); state[n] = 2
|
|
return None
|
|
for n in list(graph):
|
|
if state.get(n) is None:
|
|
c = dfs(n)
|
|
if c: return c
|
|
return None
|
|
|
|
# 1) cabeceras públicas
|
|
pub = os.path.join(root, "include", "tahgibu")
|
|
g = {}
|
|
for f in sorted(os.listdir(pub)):
|
|
g[f] = [i.split("/")[-1] for i in includes(os.path.join(pub, f)) if i.startswith("tahgibu/")]
|
|
c = find_cycle(g)
|
|
print("Cabeceras públicas:", "CICLO " + " -> ".join(c) if c else "sin ciclos (%d cabeceras)" % len(g))
|
|
|
|
# 2) módulos internos (carpetas de src/, sin ui/ ni platform/) por dependencias de archivos .c/.h
|
|
src = os.path.join(root, "src")
|
|
mods = {}
|
|
for d, _, files in os.walk(src):
|
|
for f in files:
|
|
if not f.endswith((".c", ".h")): continue
|
|
p = os.path.join(d, f)
|
|
mod = os.path.relpath(d, src).split(os.sep)[0]
|
|
for inc in includes(p):
|
|
tgt = os.path.normpath(os.path.join(d, inc))
|
|
if tgt.startswith(src) and os.path.exists(tgt):
|
|
tmod = os.path.relpath(os.path.dirname(tgt), src).split(os.sep)[0]
|
|
if tmod != mod: mods.setdefault(mod, set()).add(tmod)
|
|
for m, deps in sorted(mods.items()): print(" %-12s -> %s" % (m, ", ".join(sorted(deps))))
|
|
c = find_cycle({k: sorted(v) for k, v in mods.items()})
|
|
print("Módulos internos:", "CICLO " + " -> ".join(c) if c else "sin ciclos")
|
|
sys.exit(0)
|