summaryrefslogtreecommitdiff
path: root/usr.bin/tsort/tsort.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/tsort/tsort.c')
-rw-r--r--usr.bin/tsort/tsort.c162
1 files changed, 89 insertions, 73 deletions
diff --git a/usr.bin/tsort/tsort.c b/usr.bin/tsort/tsort.c
index 7de82a8a59a..da5782ebc62 100644
--- a/usr.bin/tsort/tsort.c
+++ b/usr.bin/tsort/tsort.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tsort.c,v 1.28 2015/08/31 09:36:02 espie Exp $ */
+/* $OpenBSD: tsort.c,v 1.29 2015/09/03 11:16:50 espie Exp $ */
/* ex:ts=8 sw=4:
*
* Copyright (c) 1999-2004 Marc Espie <espie@openbsd.org>
@@ -137,6 +137,7 @@ static struct node *find_cycle_from(struct node *, struct array *);
static struct node *find_predecessor(struct array *, struct node *);
static unsigned int traverse_node(struct node *, unsigned int, struct array *);
static struct node *find_longest_cycle(struct array *, struct array *);
+static struct node *find_normal_cycle(struct array *, struct array *);
static void heap_down(struct array *, unsigned int);
static void heapify(struct array *, int);
@@ -153,6 +154,11 @@ static void *emem(void *);
#define DEBUG_TRAVERSE 0
static struct ohash_info node_info = {
offsetof(struct node, k), NULL, hash_calloc, hash_free, entry_alloc };
+static void parse_args(int, char *[], struct ohash *);
+static int tsort(struct ohash *);
+
+static int quiet_flag, long_flag,
+ warn_flag, hints_flag, verbose_flag;
int main(int, char *[]);
@@ -795,69 +801,77 @@ find_longest_cycle(struct array *h, struct array *c)
return n;
}
+static struct node *
+find_normal_cycle(struct array *h, struct array *c)
+{
+ struct node *b, *n;
+
+ if (hints_flag)
+ n = find_smallest_node(h);
+ else
+ n = find_good_cycle_break(h);
+ while ((b = find_cycle_from(n, c)) == NULL)
+ n = find_predecessor(h, n);
+ return b;
+}
+
#define plural(n) ((n) > 1 ? "s" : "")
-int
-main(int argc, char *argv[])
+static void
+parse_args(int argc, char *argv[], struct ohash *pairs)
{
- struct ohash pairs;
- int reverse_flag, quiet_flag, long_flag,
- warn_flag, hints_flag, verbose_flag;
+ int c;
unsigned int order;
+ int reverse_flag;
order = 0;
reverse_flag = quiet_flag = long_flag =
warn_flag = hints_flag = verbose_flag = 0;
- nodes_init(&pairs);
-
- {
- int c;
-
- while ((c = getopt(argc, argv, "h:flqrvw")) != -1) {
- switch(c) {
- case 'h': {
- FILE *f;
-
- f = fopen(optarg, "r");
- if (f == NULL)
- err(EX_NOINPUT, "Can't open hint file %s",
- optarg);
- order = read_hints(f, &pairs, quiet_flag,
- optarg, order);
- fclose(f);
- }
- hints_flag = 1;
- break;
- /*FALLTHRU*/
- case 'f':
- hints_flag = 2;
- break;
- case 'l':
- long_flag = 1;
- break;
- case 'q':
- quiet_flag = 1;
- break;
- case 'r':
- reverse_flag = 1;
- break;
- case 'v':
- verbose_flag = 1;
- break;
- case 'w':
- warn_flag = 1;
- break;
- default:
- usage();
- }
- }
-
- argc -= optind;
- argv += optind;
+ nodes_init(pairs);
+ while ((c = getopt(argc, argv, "h:flqrvw")) != -1) {
+ switch(c) {
+ case 'h': {
+ FILE *f;
+
+ f = fopen(optarg, "r");
+ if (f == NULL)
+ err(EX_NOINPUT, "Can't open hint file %s",
+ optarg);
+ order = read_hints(f, pairs, quiet_flag,
+ optarg, order);
+ fclose(f);
+ }
+ hints_flag = 1;
+ break;
+ /*FALLTHRU*/
+ case 'f':
+ hints_flag = 2;
+ break;
+ case 'l':
+ long_flag = 1;
+ break;
+ case 'q':
+ quiet_flag = 1;
+ break;
+ case 'r':
+ reverse_flag = 1;
+ break;
+ case 'v':
+ verbose_flag = 1;
+ break;
+ case 'w':
+ warn_flag = 1;
+ break;
+ default:
+ usage();
+ }
}
+ argc -= optind;
+ argv += optind;
+
switch(argc) {
case 1: {
FILE *f;
@@ -865,20 +879,23 @@ main(int argc, char *argv[])
f = fopen(argv[0], "r");
if (f == NULL)
err(EX_NOINPUT, "Can't open file %s", argv[0]);
- order = read_pairs(f, &pairs, reverse_flag, argv[0], order,
+ order = read_pairs(f, pairs, reverse_flag, argv[0], order,
hints_flag == 2);
fclose(f);
break;
}
case 0:
- order = read_pairs(stdin, &pairs, reverse_flag, "stdin",
+ order = read_pairs(stdin, pairs, reverse_flag, "stdin",
order, hints_flag == 2);
break;
default:
usage();
}
+}
- {
+static int
+tsort(struct ohash *pairs)
+{
struct array aux; /* Unrefed nodes/cycle reporting. */
struct array remaining;
unsigned int broken_arcs, broken_cycles;
@@ -888,9 +905,9 @@ main(int argc, char *argv[])
broken_cycles = 0;
if (hints_flag)
- make_transparent(&pairs);
- split_nodes(&pairs, &aux, &remaining);
- ohash_delete(&pairs);
+ make_transparent(pairs);
+ split_nodes(pairs, &aux, &remaining);
+ ohash_delete(pairs);
if (hints_flag)
heapify(&aux, verbose_flag);
@@ -925,19 +942,10 @@ main(int argc, char *argv[])
/* XXX Simple cycle detection and long cycle
* detection are mutually exclusive. */
- if (long_flag) {
+ if (long_flag)
n = find_longest_cycle(&remaining, &aux);
- } else {
- struct node *b;
-
- if (hints_flag)
- n = find_smallest_node(&remaining);
- else
- n = find_good_cycle_break(&remaining);
- while ((b = find_cycle_from(n, &aux)) == NULL)
- n = find_predecessor(&remaining, n);
- n = b;
- }
+ else
+ n = find_normal_cycle(&remaining, &aux);
if (!quiet_flag) {
warnx("cycle in data");
@@ -959,10 +967,18 @@ main(int argc, char *argv[])
broken_cycles, plural(broken_cycles),
broken_arcs, plural(broken_arcs));
if (warn_flag)
- exit(broken_cycles < 256 ? broken_cycles : 255);
+ return (broken_cycles < 256 ? broken_cycles : 255);
else
- exit(EX_OK);
- }
+ return (EX_OK);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct ohash pairs;
+
+ parse_args(argc, argv, &pairs);
+ return tsort(&pairs);
}