Promote commit-3's tri-color topo bail into a loud dep_cycle error that names the full import cycle, byte-identical both stages (cmd/ww/main.c + selfhost/cmd/ww/main.ww, deps.ha:243 parity). Add a non-vacuous negative gate (989_sepcycle_dup) proving the pre-existing w6l duplicate-symbol reject fires loud + non-zero on a cross-package collision; no new linker code. #58(b)(c) link-arg parity deferred (system()-string vs procrun()-argv is structurally un-unifiable in this scope); #61 filed for the byte-id-blind w6l_ww dup-message divergence.
This commit is contained in:
@@ -740,21 +740,31 @@ sep_scan_pkg(struct sepgraph *g, int pi, const char *searchpath)
|
||||
}
|
||||
|
||||
/* DFS post-order over the dep DAG → reverse-topo (deps before importer),
|
||||
* cite Hare gather (deps.ha:123). Tri-color: a back-edge BAILS rather
|
||||
* than spinning. Commit 3 assumes acyclic; the LOUD cycle reject is
|
||||
* commit 4 (this just must not infinite-loop). */
|
||||
* cite Hare gather (deps.ha:123). Tri-color: a gray back-edge is a loud
|
||||
* dep-cycle reject naming the chain (Hare deps.ha:243); `stack[0..depth)`
|
||||
* is the live DFS path, so the cycle runs from pi's first occurrence on
|
||||
* it to the top, closing back on pi. */
|
||||
static int
|
||||
sep_topo_visit(struct sepgraph *g, int pi, int *order, int *no)
|
||||
sep_topo_visit(struct sepgraph *g, int pi, int *order, int *no,
|
||||
int *stack, int depth)
|
||||
{
|
||||
if (g->pkg[pi].color == 2) return 0;
|
||||
if (g->pkg[pi].color == 1) {
|
||||
fprintf(stderr,
|
||||
"ww --sep: import cycle (loud reject lands commit 4)\n");
|
||||
int j = 0;
|
||||
while (j < depth && stack[j] != pi) j++;
|
||||
fprintf(stderr, "ww --sep: dependency cycle: ");
|
||||
for (int s = j; s < depth; s++)
|
||||
fprintf(stderr, "%s -> ", g->pkg[stack[s]].path[0]
|
||||
? g->pkg[stack[s]].path : "(root)");
|
||||
fprintf(stderr, "%s\n",
|
||||
g->pkg[pi].path[0] ? g->pkg[pi].path : "(root)");
|
||||
return -1;
|
||||
}
|
||||
g->pkg[pi].color = 1;
|
||||
stack[depth] = pi;
|
||||
for (int k = 0; k < g->pkg[pi].ndeps; k++)
|
||||
if (sep_topo_visit(g, g->pkg[pi].deps[k], order, no) < 0)
|
||||
if (sep_topo_visit(g, g->pkg[pi].deps[k], order, no,
|
||||
stack, depth + 1) < 0)
|
||||
return -1;
|
||||
g->pkg[pi].color = 2;
|
||||
order[(*no)++] = pi;
|
||||
@@ -951,10 +961,13 @@ build_one_sep(const char *src, int entry_is_dir, const char *out,
|
||||
if (root < 0 || sep_scan_pkg(g, root, srcdir) < 0) { free(g); return 1; }
|
||||
for (int i = 0; i < g->n; i++) g->pkg[i].color = 0;
|
||||
int *order = calloc((size_t)g->n, sizeof *order);
|
||||
int *stack = calloc((size_t)g->n, sizeof *stack);
|
||||
int norder = 0;
|
||||
if (order == NULL || sep_topo_visit(g, root, order, &norder) < 0) {
|
||||
free(order); free(g); return 1;
|
||||
if (order == NULL || stack == NULL ||
|
||||
sep_topo_visit(g, root, order, &norder, stack, 0) < 0) {
|
||||
free(stack); free(order); free(g); return 1;
|
||||
}
|
||||
free(stack);
|
||||
|
||||
/* producer loop — dep-first, one `w6c -c -I` pass per package. */
|
||||
for (int oi = 0; oi < norder; oi++) {
|
||||
|
||||
Reference in New Issue
Block a user