1 /* $OpenBSD: tsort.c,v 1.19 2004/08/05 10:59:42 espie Exp $ */
2 /* ex:ts=8 sw=4:
3  *
4  * Copyright © 2013
5  *	Thorsten “mirabilos” Glaser <tg@mirbsd.org>
6  * Copyright (c) 1999-2004 Marc Espie <espie@openbsd.org>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include <sys/types.h>
22 #include <assert.h>
23 #include <ctype.h>
24 #include <err.h>
25 #include <limits.h>
26 #include <stddef.h>
27 #include <ohash.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sysexits.h>
32 #include <unistd.h>
33 
34 __RCSID("$MirOS: src/usr.bin/tsort/tsort.c,v 1.2 2013/10/31 20:07:17 tg Exp $");
35 
36 /* The complexity of topological sorting is O(e), where e is the
37  * size of input.  While reading input, vertices have to be identified,
38  * thus add the complexity of e keys retrieval among v keys using
39  * an appropriate data structure.  This program uses open double hashing
40  * for that purpose.  See Knuth for the expected complexity of double
41  * hashing (Brent variation should probably be used if v << e, as a user
42  * option).
43  *
44  * The algorithm used for longest cycle reporting is accurate, but somewhat
45  * expensive.  It may need to build all free paths of the graph (a free
46  * path is a path that never goes twice through the same node), whose
47  * number can be as high as O(2^e).  Usually, the number of free paths is
48  * much smaller though.  This program's author does not believe that a
49  * significantly better worst-case complexity algorithm exists.
50  *
51  * In case of a hints file, the set of minimal nodes is maintained as a
52  * heap.  The resulting complexity is O(e+v log v) for the worst case.
53  * The average should actually be near O(e).
54  *
55  * If the hints file is incomplete, there is some extra complexity incurred
56  * by make_transparent, which does propagate order values to unmarked
57  * nodes. In the worst case, make_transparent is  O(e u),
58  * where u is the number of originally unmarked nodes.
59  * In practice, it is much faster.
60  *
61  * The simple topological sort algorithm detects cycles.  This program
62  * goes further, breaking cycles through the use of simple heuristics.
63  * Each cycle break checks the whole set of nodes, hence if c cycles break
64  * are needed, this is an extra cost of O(c v).
65  *
66  * Possible heuristics are as follows:
67  * - break cycle at node with lowest number of predecessors (default case),
68  * - break longest cycle at node with lowest number of predecessors,
69  * - break cycle at next node from the hints file.
70  *
71  * Except for the hints file case, which sets an explicit constraint on
72  * which cycle to break, those heuristics locally result in the smallest
73  * number of broken edges.
74  *
75  * Those are admittedly greedy strategies, as is the selection of the next
76  * node from the hints file amongst equivalent candidates that is used for
77  * `stable' topological sorting.
78  */
79 
80 #ifdef __GNUC__
81 #define UNUSED	__attribute__((__unused__))
82 #else
83 #define UNUSED
84 #endif
85 
86 struct node;
87 
88 /* The set of arcs from a given node is stored as a linked list.  */
89 struct link {
90 	struct link *next;
91 	struct node *node;
92 };
93 
94 #define NO_ORDER	UINT_MAX
95 
96 struct node {
97 	unsigned int refs;	/* Number of arcs left, coming into this node.
98 				 * Note that nodes with a null count can't
99 				 * be part of cycles.  */
100 	struct link  *arcs;	/* List of forward arcs.  */
101 
102 	unsigned int order; 	/* Order of nodes according to a hint file.  */
103 
104 	/* Cycle detection algorithms build a free path of nodes.  */
105 	struct node  *from; 	/* Previous node in the current path.  */
106 
107 	unsigned int mark;	/* Mark processed nodes in cycle discovery.  */
108 	struct link  *traverse;	/* Next link to traverse when backtracking.  */
109 	char         k[1];	/* Name of this node.  */
110 };
111 
112 #define HASH_START 9
113 
114 struct array {
115 	unsigned int entries;
116 	struct node  **t;
117 };
118 
119 static void nodes_init(struct ohash *);
120 static struct node *node_lookup(struct ohash *, const char *, const char *);
121 static void usage(void);
122 static struct node *new_node(const char *, const char *);
123 
124 static unsigned int read_pairs(FILE *, struct ohash *, int,
125     const char *, unsigned int, int);
126 static void split_nodes(struct ohash *, struct array *, struct array *);
127 static void make_transparent(struct ohash *);
128 static void insert_arc(struct node *, struct node *);
129 
130 #ifdef DEBUG
131 static void dump_node(struct node *);
132 static void dump_array(struct array *);
133 static void dump_hash(struct ohash *);
134 #endif
135 static unsigned int read_hints(FILE *, struct ohash *, int,
136     const char *, unsigned int);
137 static struct node *find_smallest_node(struct array *);
138 static struct node *find_good_cycle_break(struct array *);
139 static void print_cycle(struct array *);
140 static struct node *find_cycle_from(struct node *, struct array *);
141 static struct node *find_predecessor(struct array *, struct node *);
142 static unsigned int traverse_node(struct node *, unsigned int, struct array *);
143 static struct node *find_longest_cycle(struct array *, struct array *);
144 
145 static void heap_down(struct array *, unsigned int);
146 static void heapify(struct array *, int);
147 static struct node *dequeue(struct array *);
148 static void enqueue(struct array *, struct node *);
149 
150 
151 
152 #define erealloc(n, s)	emem(realloc(n, s))
153 static void *hash_alloc(size_t, void *);
154 static void hash_free(void *, size_t, void *);
155 static void* entry_alloc(size_t, void *);
156 static void *emalloc(size_t);
157 static void *emem(void *);
158 #define DEBUG_TRAVERSE 0
159 static struct ohash_info node_info = {
160 	offsetof(struct node, k), NULL, hash_alloc, hash_free, entry_alloc };
161 
162 
163 int main(int, char *[]);
164 
165 
166 /***
167  *** Memory handling.
168  ***/
169 
170 static void *
emem(void * p)171 emem(void *p)
172 {
173 	if (p)
174 		return p;
175 	else
176 		errx(EX_SOFTWARE, "Memory exhausted");
177 }
178 
179 static void *
hash_alloc(size_t s,void * u UNUSED)180 hash_alloc(size_t s, void *u UNUSED)
181 {
182 	return emem(calloc(s, 1));
183 }
184 
185 static void
hash_free(void * p,size_t s UNUSED,void * u UNUSED)186 hash_free(void *p, size_t s UNUSED, void *u UNUSED)
187 {
188 	free(p);
189 }
190 
191 static void *
entry_alloc(size_t s,void * u UNUSED)192 entry_alloc(size_t s, void *u UNUSED)
193 {
194 	return emalloc(s);
195 }
196 
197 static void *
emalloc(size_t s)198 emalloc(size_t s)
199 {
200 	return emem(malloc(s));
201 }
202 
203 
204 /***
205  *** Hash table.
206  ***/
207 
208 /* Inserting and finding nodes in the hash structure.
209  * We handle interval strings for efficiency wrt fgetln.  */
210 static struct node *
new_node(const char * start,const char * end)211 new_node(const char *start, const char *end)
212 {
213 	struct node 	*n;
214 
215 	n = ohash_create_entry(&node_info, start, &end);
216 	n->from = NULL;
217 	n->arcs = NULL;
218 	n->refs = 0;
219 	n->mark = 0;
220 	n->order = NO_ORDER;
221 	n->traverse = NULL;
222 	return n;
223 }
224 
225 
226 static void
nodes_init(struct ohash * h)227 nodes_init(struct ohash *h)
228 {
229 	ohash_init(h, HASH_START, &node_info);
230 }
231 
232 static struct node *
node_lookup(struct ohash * h,const char * start,const char * end)233 node_lookup(struct ohash *h, const char *start, const char *end)
234 {
235 	unsigned int	i;
236 	struct node *	n;
237 
238 	i = ohash_qlookupi(h, start, &end);
239 
240 	n = ohash_find(h, i);
241 	if (n == NULL)
242 		n = ohash_insert(h, i, new_node(start, end));
243 	return n;
244 }
245 
246 #ifdef DEBUG
247 static void
dump_node(struct node * n)248 dump_node(struct node *n)
249 {
250 	struct link 	*l;
251 
252 	if (n->refs == 0)
253 		return;
254 	printf("%s (%u/%u): ", n->k, n->order, n->refs);
255 	for (l = n->arcs; l != NULL; l = l->next)
256 		if (n->refs != 0)
257 		printf("%s(%u/%u) ", l->node->k, l->node->order, l->node->refs);
258     	putchar('\n');
259 }
260 
261 static void
dump_array(struct array * a)262 dump_array(struct array *a)
263 {
264 	unsigned int 	i;
265 
266 	for (i = 0; i < a->entries; i++)
267 		dump_node(a->t[i]);
268 }
269 
270 static void
dump_hash(struct ohash * h)271 dump_hash(struct ohash *h)
272 {
273 	unsigned int 	i;
274 	struct node 	*n;
275 
276 	for (n = ohash_first(h, &i); n != NULL; n = ohash_next(h, &i))
277 		dump_node(n);
278 }
279 #endif
280 
281 
282 /***
283  *** Reading data.
284  ***/
285 
286 static void
insert_arc(struct node * a,struct node * b)287 insert_arc(struct node *a, struct node *b)
288 {
289 	struct link 	*l;
290 
291 	/* Check that this arc is not already present.  */
292 	for (l = a->arcs; l != NULL; l = l->next) {
293 		if (l->node == b)
294 			return;
295 	}
296 	b->refs++;
297 	l = emalloc(sizeof(struct link));
298 	l->node = b;
299 	l->next = a->arcs;
300 	a->arcs = l;
301 }
302 
303 static unsigned int
read_pairs(FILE * f,struct ohash * h,int reverse,const char * name,unsigned int order,int hint)304 read_pairs(FILE *f, struct ohash *h, int reverse, const char *name,
305     unsigned int order, int hint)
306 {
307 	int 		toggle;
308 	struct node 	*a;
309 	size_t 		size;
310 	char 		*str;
311 
312 	toggle = 1;
313 	a = NULL;
314 
315 	while ((str = fgetln(f, &size)) != NULL) {
316 		char *sentinel;
317 
318 		sentinel = str + size;
319 		for (;;) {
320 			char *e;
321 
322 			while (str < sentinel && isspace(*str))
323 				str++;
324 			if (str == sentinel)
325 				break;
326 			for (e = str; e < sentinel && !isspace(*e); e++)
327 				continue;
328 			if (toggle) {
329 				a = node_lookup(h, str, e);
330 				if (a->order == NO_ORDER && hint)
331 					a->order = order++;
332 			} else {
333 				struct node *b;
334 
335 				b = node_lookup(h, str, e);
336 				assert(a != NULL);
337 				if (b != a) {
338 					if (reverse)
339 						insert_arc(b, a);
340 					else
341 						insert_arc(a, b);
342 				}
343 			}
344 			toggle = !toggle;
345 			str = e;
346 		}
347 	}
348 	if (toggle == 0)
349 		errx(EX_DATAERR, "odd number of pairs in %s", name);
350     	if (!feof(f))
351 		err(EX_IOERR, "error reading %s", name);
352 	return order;
353 }
354 
355 static unsigned int
read_hints(FILE * f,struct ohash * h,int quiet,const char * name,unsigned int order)356 read_hints(FILE *f, struct ohash *h, int quiet, const char *name,
357     unsigned int order)
358 {
359 	char 		*str;
360 	size_t 		size;
361 
362 	while ((str = fgetln(f, &size)) != NULL) {
363 		char *sentinel;
364 
365 		sentinel = str + size;
366 		for (;;) {
367 			char *e;
368 			struct node *a;
369 
370 			while (str < sentinel && isspace(*str))
371 				str++;
372 			if (str == sentinel)
373 				break;
374 			for (e = str; e < sentinel && !isspace(*e); e++)
375 				continue;
376 			a = node_lookup(h, str, e);
377 			if (a->order != NO_ORDER) {
378 				if (!quiet)
379 				    warnx(
380 					"duplicate node %s in hints file %s",
381 					a->k, name);
382 			} else
383 				a->order = order++;
384 			str = e;
385 		}
386 	}
387 	return order;
388 }
389 
390 
391 /***
392  *** Standard heap handling routines.
393  ***/
394 
395 static void
heap_down(struct array * h,unsigned int i)396 heap_down(struct array *h, unsigned int i)
397 {
398 	unsigned int 	j;
399 	struct node 	*swap;
400 
401 	for (; (j=2*i+1) < h->entries; i = j) {
402 		if (j+1 < h->entries && h->t[j+1]->order < h->t[j]->order)
403 		    	j++;
404 		if (h->t[i]->order <= h->t[j]->order)
405 			break;
406 		swap = h->t[i];
407 		h->t[i] = h->t[j];
408 		h->t[j] = swap;
409 	}
410 }
411 
412 static void
heapify(struct array * h,int verbose)413 heapify(struct array *h, int verbose)
414 {
415 	unsigned int 	i;
416 
417 	for (i = h->entries; i != 0;) {
418 		if (h->t[--i]->order == NO_ORDER && verbose)
419 			warnx("node %s absent from hints file", h->t[i]->k);
420 		heap_down(h, i);
421 	}
422 }
423 
424 #define DEQUEUE(h) ( hints_flag ? dequeue(h) : (h)->t[--(h)->entries] )
425 
426 static struct node *
dequeue(struct array * h)427 dequeue(struct array *h)
428 {
429 	struct node 	*n;
430 
431 	if (h->entries == 0)
432 		n = NULL;
433 	else {
434 		n = h->t[0];
435 		if (--h->entries != 0) {
436 		    h->t[0] = h->t[h->entries];
437 		    heap_down(h, 0);
438 		}
439 	}
440 	return n;
441 }
442 
443 #define ENQUEUE(h, n) do {			\
444 	if (hints_flag)				\
445 		enqueue((h), (n));		\
446 	else					\
447 		(h)->t[(h)->entries++] = (n);	\
448 	} while(0);
449 
450 static void
enqueue(struct array * h,struct node * n)451 enqueue(struct array *h, struct node *n)
452 {
453 	unsigned int 	i, j;
454 	struct node 	*swap;
455 
456 	h->t[h->entries++] = n;
457 	for (i = h->entries-1; i > 0; i = j) {
458 		j = (i-1)/2;
459 		if (h->t[j]->order < h->t[i]->order)
460 			break;
461 		swap = h->t[j];
462 		h->t[j] = h->t[i];
463 		h->t[i] = swap;
464 	}
465 }
466 
467 /* Nodes without order should not hinder direct dependencies.
468  * Iterate until no nodes are left.
469  */
470 static void
make_transparent(struct ohash * hash)471 make_transparent(struct ohash *hash)
472 {
473 	struct node 	*n;
474 	unsigned int 	i;
475 	struct link 	*l;
476 	int		adjusted;
477 	int		bad;
478 	unsigned int	min;
479 
480 	/* first try to solve complete nodes */
481 	do {
482 		adjusted = 0;
483 		bad = 0;
484 		for (n = ohash_first(hash, &i); n != NULL;
485 		    n = ohash_next(hash, &i)) {
486 			if (n->order == NO_ORDER) {
487 				min = NO_ORDER;
488 
489 				for (l = n->arcs; l != NULL; l = l->next) {
490 					/* unsolved node -> delay resolution */
491 					if (l->node->order == NO_ORDER) {
492 						bad = 1;
493 						break;
494 					} else if (l->node->order < min)
495 						min = l->node->order;
496 				}
497 				if (min < NO_ORDER && l == NULL) {
498 					n->order = min;
499 					adjusted = 1;
500 				}
501 			}
502 		}
503 
504 	} while (adjusted);
505 
506 	/* then, if incomplete nodes are left, do them */
507 	if (bad) do {
508 		adjusted = 0;
509 		for (n = ohash_first(hash, &i); n != NULL;
510 		    n = ohash_next(hash, &i))
511 			if (n->order == NO_ORDER)
512 				for (l = n->arcs; l != NULL; l = l->next)
513 					if (l->node->order < n->order) {
514 						n->order = l->node->order;
515 						adjusted = 1;
516 					}
517 	} while (adjusted);
518 }
519 
520 
521 /***
522  *** Search through hash array for nodes.
523  ***/
524 
525 /* Split nodes into unrefed nodes/live nodes.  */
526 static void
split_nodes(struct ohash * hash,struct array * heap,struct array * remaining)527 split_nodes(struct ohash *hash, struct array *heap, struct array *remaining)
528 {
529 
530 	struct node *n;
531 	unsigned int i;
532 
533 	heap->t = emalloc(sizeof(struct node *) * ohash_entries(hash));
534 	remaining->t = emalloc(sizeof(struct node *) * ohash_entries(hash));
535 	heap->entries = 0;
536 	remaining->entries = 0;
537 
538 	for (n = ohash_first(hash, &i); n != NULL; n = ohash_next(hash, &i)) {
539 		if (n->refs == 0)
540 			heap->t[heap->entries++] = n;
541 		else
542 			remaining->t[remaining->entries++] = n;
543 	}
544 }
545 
546 /* Good point to break a cycle: live node with as few refs as possible. */
547 static struct node *
find_good_cycle_break(struct array * h)548 find_good_cycle_break(struct array *h)
549 {
550 	unsigned int 	i;
551 	unsigned int 	best;
552 	struct node 	*u;
553 
554 	best = UINT_MAX;
555 	u = NULL;
556 
557 	assert(h->entries != 0);
558 	for (i = 0; i < h->entries; i++) {
559 		struct node *n = h->t[i];
560 		/* No need to look further. */
561 		if (n->refs == 1)
562 			return n;
563 		if (n->refs != 0 && n->refs < best) {
564 			best = n->refs;
565 			u = n;
566 		}
567 	}
568 	assert(u != NULL);
569 	return u;
570 }
571 
572 /*  Retrieve the node with the smallest order.  */
573 static struct node *
find_smallest_node(struct array * h)574 find_smallest_node(struct array *h)
575 {
576 	unsigned int 	i;
577 	unsigned int 	best;
578 	struct node 	*u;
579 
580 	best = UINT_MAX;
581 	u = NULL;
582 
583 	assert(h->entries != 0);
584 	for (i = 0; i < h->entries; i++) {
585 		struct node *n = h->t[i];
586 		if (n->refs != 0 && n->order < best) {
587 			best = n->order;
588 			u = n;
589 		}
590 	}
591 	assert(u != NULL);
592 	return u;
593 }
594 
595 
596 /***
597  *** Graph algorithms.
598  ***/
599 
600 /* Explore the nodes reachable from i to find a cycle, store it in c.
601  * This may fail.  */
602 static struct node *
find_cycle_from(struct node * i,struct array * c)603 find_cycle_from(struct node *i, struct array *c)
604 {
605 	struct node 	*n;
606 
607 	n = i;
608 	/* XXX Previous cycle findings may have left this pointer non-null.  */
609 	i->from = NULL;
610 
611 	for (;;) {
612 		/* Note that all marks are reversed before this code exits.  */
613 		n->mark = 1;
614 		if (n->traverse)
615 			n->traverse = n->traverse->next;
616 		else
617 			n->traverse = n->arcs;
618 		/* Skip over dead nodes.  */
619 		while (n->traverse && n->traverse->node->refs == 0)
620 			n->traverse = n->traverse->next;
621 		if (n->traverse) {
622 			struct node *go = n->traverse->node;
623 
624 			if (go->mark) {
625 				c->entries = 0;
626 				for (; n != NULL && n != go; n = n->from) {
627 					c->t[c->entries++] = n;
628 					n->mark = 0;
629 				}
630 				for (; n != NULL; n = n->from)
631 					n->mark = 0;
632 				c->t[c->entries++] = go;
633 				return go;
634 			} else {
635 			    go->from = n;
636 			    n = go;
637 			}
638 		} else {
639 			n->mark = 0;
640 			n = n->from;
641 			if (n == NULL)
642 				return NULL;
643 		}
644 	}
645 }
646 
647 /* Find a live predecessor of node n.  This is a slow routine, as it needs
648  * to go through the whole array, but it is not needed often.
649  */
650 static struct node *
find_predecessor(struct array * a,struct node * n)651 find_predecessor(struct array *a, struct node *n)
652 {
653 	unsigned int i;
654 
655 	for (i = 0; i < a->entries; i++) {
656 		struct node *m;
657 
658 		m = a->t[i];
659 		if (m->refs != 0) {
660 			struct link *l;
661 
662 			for (l = m->arcs; l != NULL; l = l->next)
663 				if (l->node == n)
664 					return m;
665 		}
666 	}
667 	assert(1 == 0);
668 	return NULL;
669 }
670 
671 /* Traverse all strongly connected components reachable from node n.
672    Start numbering them at o. Return the maximum order reached.
673    Update the largest cycle found so far.
674  */
675 static unsigned int
traverse_node(struct node * n,unsigned int o,struct array * c)676 traverse_node(struct node *n, unsigned int o, struct array *c)
677 {
678 	unsigned int 	min, max;
679 
680 	n->from = NULL;
681 	min = o;
682 	max = ++o;
683 
684 	for (;;) {
685 		n->mark = o;
686 		if (DEBUG_TRAVERSE)
687 			printf("%s(%u) ", n->k, n->mark);
688 		/* Find next arc to explore.  */
689 		if (n->traverse)
690 			n->traverse = n->traverse->next;
691 		else
692 			n->traverse = n->arcs;
693 		/* Skip over dead nodes.  */
694 		while (n->traverse && n->traverse->node->refs == 0)
695 			n->traverse = n->traverse->next;
696 		/* If arc left.  */
697 		if (n->traverse) {
698 			struct node 	*go;
699 
700 			go = n->traverse->node;
701 			/* Optimisation: if go->mark < min, we already
702 			 * visited this strongly-connected component in
703 			 * a previous pass.  Hence, this can yield no new
704 			 * cycle.  */
705 
706 			/* Not part of the current path: go for it.  */
707 			if (go->mark == 0 || go->mark == min) {
708 				go->from = n;
709 				n = go;
710 				o++;
711 				if (o > max)
712 					max = o;
713 			/* Part of the current path: check cycle length.  */
714 			} else if (go->mark > min) {
715 				if (DEBUG_TRAVERSE)
716 					printf("%d\n", o - go->mark + 1);
717 				if (o - go->mark + 1 > c->entries) {
718 					struct node *t;
719 					unsigned int i;
720 
721 					c->entries = o - go->mark + 1;
722 					i = 0;
723 					c->t[i++] = go;
724 					for (t = n; t != go; t = t->from)
725 						c->t[i++] = t;
726 				}
727 			}
728 
729 		/* No arc left: backtrack.  */
730 		} else {
731 			n->mark = min;
732 			n = n->from;
733 			if (!n)
734 				return max;
735 			o--;
736 		}
737 	}
738 }
739 
740 static void
print_cycle(struct array * c)741 print_cycle(struct array *c)
742 {
743 	unsigned int 	i;
744 
745 	/* Printing in reverse order, since cycle discoveries finds reverse
746 	 * edges.  */
747 	for (i = c->entries; i != 0;) {
748 		i--;
749 		warnx("%s", c->t[i]->k);
750 	}
751 }
752 
753 static struct node *
find_longest_cycle(struct array * h,struct array * c)754 find_longest_cycle(struct array *h, struct array *c)
755 {
756 	unsigned int 	i;
757 	unsigned int 	o;
758 	unsigned int 	best;
759 	struct node 	*n;
760 	static int 	notfirst = 0;
761 
762 	assert(h->entries != 0);
763 
764 	/* No cycle found yet.  */
765 	c->entries = 0;
766 
767 	/* Reset the set of marks, except the first time around.  */
768 	if (notfirst) {
769 		for (i = 0; i < h->entries; i++)
770 			h->t[i]->mark = 0;
771 	} else
772 		notfirst = 1;
773 
774 	o = 0;
775 
776 	/* Traverse the array.  Each unmarked, live node heralds a
777 	 * new set of strongly connected components.  */
778 	for (i = 0; i < h->entries; i++) {
779 		n = h->t[i];
780 		if (n->refs != 0 && n->mark == 0) {
781 			/* Each call to traverse_node uses a separate
782 			 * interval of numbers to mark nodes.  */
783 			o++;
784 			o = traverse_node(n, o, c);
785 		}
786 	}
787 
788 	assert(c->entries != 0);
789 	n = c->t[0];
790 	best = n->refs;
791 	for (i = 0; i < c->entries; i++) {
792 		if (c->t[i]->refs < best) {
793 			n = c->t[i];
794 			best = n->refs;
795 		}
796 	}
797 	return n;
798 }
799 
800 
801 #define plural(n) ((n) > 1 ? "s" : "")
802 
803 int
main(int argc,char * argv[])804 main(int argc, char *argv[])
805 {
806 	struct ohash 	pairs;
807 	int 		reverse_flag, quiet_flag, long_flag,
808 			    warn_flag, hints_flag, verbose_flag;
809 	unsigned int	order;
810 
811 	order = 0;
812 
813 	reverse_flag = quiet_flag = long_flag =
814 		warn_flag = hints_flag = verbose_flag = 0;
815 	nodes_init(&pairs);
816 
817 	{
818 	    int c;
819 
820 	    while ((c = getopt(argc, argv, "h:flqrvw")) != -1) {
821 		    switch(c) {
822 		    case 'h': {
823 			    FILE *f;
824 
825 			    f = fopen(optarg, "r");
826 			    if (f == NULL)
827 				    err(EX_NOINPUT, "Can't open hint file %s",
828 					optarg);
829 			    order = read_hints(f, &pairs, quiet_flag,
830 				optarg, order);
831 			    fclose(f);
832 		    }
833 			    hints_flag = 1;
834 			    break;
835 			    /*FALLTHRU*/
836 		    case 'f':
837 			    hints_flag = 2;
838 			    break;
839 		    case 'l':
840 			    long_flag = 1;
841 			    break;
842 		    case 'q':
843 			    quiet_flag = 1;
844 			    break;
845 		    case 'r':
846 			    reverse_flag = 1;
847 			    break;
848 		    case 'v':
849 			    verbose_flag = 1;
850 			    break;
851 		    case 'w':
852 			    warn_flag = 1;
853 			    break;
854 		    default:
855 			    usage();
856 		    }
857 	    }
858 
859 	    argc -= optind;
860 	    argv += optind;
861 	}
862 
863 	switch(argc) {
864 	case 1: {
865 		FILE *f;
866 
867 		f = fopen(argv[0], "r");
868 		if (f == NULL)
869 			err(EX_NOINPUT, "Can't open file %s", argv[1]);
870 		order = read_pairs(f, &pairs, reverse_flag, argv[1], order,
871 		    hints_flag == 2);
872 		fclose(f);
873 		break;
874 	}
875 	case 0:
876 		order = read_pairs(stdin, &pairs, reverse_flag, "stdin",
877 		    order, hints_flag == 2);
878 		break;
879 	default:
880 		usage();
881 	}
882 
883 	{
884 	    struct array 	aux;	/* Unrefed nodes/cycle reporting.  */
885 	    struct array	remaining;
886 	    unsigned int	broken_arcs, broken_cycles;
887 	    unsigned int	left;
888 
889 	    broken_arcs = 0;
890 	    broken_cycles = 0;
891 
892 	    if (hints_flag)
893 	    	make_transparent(&pairs);
894 	    split_nodes(&pairs, &aux, &remaining);
895 	    ohash_delete(&pairs);
896 
897 	    if (hints_flag)
898 		    heapify(&aux, verbose_flag);
899 
900 	    left = remaining.entries + aux.entries;
901 	    while (left != 0) {
902 
903 		    /* Standard topological sort.  */
904 		    while (aux.entries) {
905 			    struct link *l;
906 			    struct node *n;
907 
908 			    n = DEQUEUE(&aux);
909 			    printf("%s\n", n->k);
910 			    left--;
911 			    /* We can't free nodes, as we don't know which
912 			     * entry we can remove in the hash table.  We
913 			     * rely on refs == 0 to recognize live nodes.
914 			     * Decrease ref count of live nodes, enter new
915 			     * candidates into the unrefed list.  */
916 			    for (l = n->arcs; l != NULL; l = l->next)
917 				    if (l->node->refs != 0 &&
918 					--l->node->refs == 0) {
919 					    ENQUEUE(&aux, l->node);
920 				    }
921 		    }
922 		    /* There are still cycles to break.  */
923 		    if (left != 0) {
924 			    struct node *n;
925 
926 			    broken_cycles++;
927 			    /* XXX Simple cycle detection and long cycle
928 			     * detection are mutually exclusive.  */
929 
930 			    if (long_flag) {
931 				    n = find_longest_cycle(&remaining, &aux);
932 			    } else {
933 				    struct node *b;
934 
935 				    if (hints_flag)
936 					    n = find_smallest_node(&remaining);
937 				    else
938 					    n = find_good_cycle_break(&remaining);
939 				    while ((b = find_cycle_from(n, &aux)) == NULL)
940 					    n = find_predecessor(&remaining, n);
941 				    n = b;
942 			    }
943 
944 			    if (!quiet_flag) {
945 				    warnx("cycle in data");
946 				    print_cycle(&aux);
947 			    }
948 
949 			    if (verbose_flag)
950 				    warnx("%u edge%s broken", n->refs,
951 					plural(n->refs));
952 			    broken_arcs += n->refs;
953 			    n->refs = 0;
954 			    /* Reinitialization, cycle reporting uses aux.  */
955 			    aux.t[0] = n;
956 			    aux.entries = 1;
957 		    }
958 	    }
959 	    if (verbose_flag && broken_cycles != 0)
960 		    warnx("%u cycle%s broken, for a total of %u edge%s",
961 			broken_cycles, plural(broken_cycles),
962 			broken_arcs, plural(broken_arcs));
963 	    if (warn_flag)
964 		    exit(broken_cycles < 256 ? broken_cycles : 255);
965 	    else
966 		    exit(EX_OK);
967 	}
968 }
969 
970 
971 extern char *__progname;
972 
973 static void
usage(void)974 usage(void)
975 {
976 	fprintf(stderr, "Usage: %s [-flqrvw] [-h file] [file]\n", __progname);
977 	exit(EX_USAGE);
978 }
979