From ee3cceeb7a4428f0200959b3036ef26f28a16e91 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Mon, 11 Sep 2023 08:00:51 -0500 Subject: [PATCH] First stab at tsort. --- toys/pending/tsort.c | 95 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 toys/pending/tsort.c diff --git a/toys/pending/tsort.c b/toys/pending/tsort.c new file mode 100644 index 00000000..20dd99b2 --- /dev/null +++ b/toys/pending/tsort.c @@ -0,0 +1,95 @@ +/* tsort.c - topological sort + * + * Copyright 2023 Rob Landley + * + * See http://opengroup.org/onlinepubs/9699919799/utilities/tsort.html + +USE_TSORT(NEWTOY(tsort, ">1", TOYFLAG_USR|TOYFLAG_BIN)) + +config TSORT + bool "tsort" + default n + help + usage: tsort [FILE] + + Topological sort: read pairs of input strings indicating before/after + relationships. Output sorted result if no cycles, or first cycle to stderr. +*/ + +#include "toys.h" + +// sort by second element +static int klatch(char **a, char **b) +{ + return strcmp(a[1], b[1]); +} + +// TODO: this treats NUL in input as EOF +static void do_hersheba(int fd, char *name) +{ + off_t plen; + char *djel = readfd(fd, 0, &plen), *ss, **pair, *keep[2]; + long ii, jj, kk, ll, len = 0, first = 1; + + // Count input entries + if (!djel) return; + for (ss = djel;;) { + while (isspace(*ss)) ss++; + if (!*ss) break; + len++; + while (*ss && !isspace(*ss)) ss++; + } + if (len&1) error_exit("bad input (not pairs)"); + + // collect entries and null terminate strings + pair = xmalloc(len*sizeof(char *)); + for (ss = djel, len = 0;;) { + while (isspace(*ss)) *ss++ = 0; + if (!*ss) break; + pair[len++] = ss; + while (*ss && !isspace(*ss)) ss++; + } + + // sort by second element + len /= 2; + qsort(pair, len, sizeof(keep), (void *)klatch); + + // Pull out depends-on-self nodes, printing non-duplicate orpans + while (len) { + for (ii = 0, kk = ll = 2*len; ii