diff --git a/bin/ptsort.1 b/bin/ptsort.1 index 4f681a9..cd4d336 100644 --- a/bin/ptsort.1 +++ b/bin/ptsort.1 @@ -1,5 +1,5 @@ .\"- -.\" Copyright (c) 2016-2017 Dag-Erling Smørgrav +.\" Copyright (c) 2016-2024 Dag-Erling Smørgrav .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 4, 2017 +.Dd September 13, 2024 .Dt PTSORT 1 .Os .Sh NAME @@ -34,7 +34,7 @@ .Nd Prioritized topological sort .Sh SYNOPSIS .Nm -.Op Fl Ddpqsv +.Op Fl DdPpqsv .Op Fl o Ar output .Op Ar input ... .Sh DESCRIPTION @@ -58,6 +58,17 @@ The following options are available: Sort the output by depth first instead of priority first. .It Fl d Include each node's depth in the output. +.It Fl P +Print all nodes with the same priority (or the same depth if +.Fl D +was specified) on the same line. +Can be combined with +.Fl d +if and only if +.Fl D +is also specified, and with +.Fl p +if and only if it is not. .It Fl p Include each node's priority in the output. .It Fl q diff --git a/bin/ptsort.c b/bin/ptsort.c index 526d740..7250016 100644 --- a/bin/ptsort.c +++ b/bin/ptsort.c @@ -43,6 +43,7 @@ #include "fline.h" static bool bydepth; +static bool parallel; static bool printdepth; static bool printprio; static bool quiet; @@ -372,16 +373,18 @@ output(const char *fn) pnode **all, **p; pnode *n; FILE *f; + bool same = false; /* allocate array of pointers */ - if ((p = all = malloc(tnnodes * sizeof *all)) == NULL) + if ((p = all = malloc((tnnodes + 1) * sizeof *all)) == NULL) err(1, "malloc()"); /* copy nodes into array in lexical order */ for (n = aa_first(&nodes, &nit); n != NULL; n = aa_next(&nit)) *p++ = n; aa_finish(&nit); - /* p now points one past the end of the array */ + /* p now points to the sentinel at the end of the array */ + *p = NULL; /* sort by either priority or depth */ qsort(all, tnnodes, sizeof *all, @@ -395,12 +398,21 @@ output(const char *fn) /* reverse through the array and print each node's name */ while (p-- > all) { - if (printdepth) + if (parallel && p[1] != NULL) { + same = bydepth ? p[0]->depth == p[1]->depth : + p[0]->prio == p[1]->prio; + fputc(same ? ' ' : '\n', f); + } + if (printdepth && !same) fprintf(f, "%7lu ", (*p)->depth); - if (printprio) + if (printprio && !same) fprintf(f, "%7lu ", (*p)->prio); - fprintf(f, "%s\n", (*p)->name); + fprintf(f, "%s", (*p)->name); + if (!parallel) + fputc('\n', f); } + if (parallel) + fputc('\n', f); /* done */ if (f != stdout) @@ -412,7 +424,7 @@ static void usage(void) { - fprintf(stderr, "usage: ptsort [-Ddpqsv] [-o output] [input ...]\n"); + fprintf(stderr, "usage: ptsort [-DdPpqsv] [-o output] [input ...]\n"); exit(1); } @@ -435,6 +447,9 @@ main(int argc, char *argv[]) case 'd': printdepth = true; break; + case 'P': + parallel = true; + break; case 'p': printprio = true; break; @@ -454,12 +469,18 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; + if (parallel && bydepth && printprio) + errx(1, "with -P, -p cannot be combined with -D"); + if (parallel && !bydepth && printdepth) + errx(1, "with -P, -d must be combined with -D"); + if (argc == 0) input(NULL); else while (argc--) input(*argv++); verbose("graph has %lu nodes and %lu edges", tnnodes, tnedges); - output(ofn); + if (tnnodes > 0) + output(ofn); exit(0); }