[Toybox] [PATCH] man: support MANPATH.

makepost makepost at firemail.cc
Fri May 10 16:31:01 PDT 2019


On Fri, May 03, 2019 at 03:29:16PM -0500, Rob Landley wrote:
> I've got some colon separated path walking code (lib.c find_in_path()), I should
> probably try to genericize it somehow to cover this case better. Hmmm...
> (Possibly teach _it_ to wordexp()? Or a more generic callback...)

I see the appeal of find_in_path and a wordexp multiplying paths by
sections, suffix presence and zips, reducing man by about 30 lines, but
in the meantime have only extended the existing code like this.
---
>From 739f1fe0e9c68e16a2ede220e42f424b1a8afa43 Mon Sep 17 00:00:00 2001
From: makepost <makepost at firemail.cc>
Date: Fri, 10 May 2019 18:24:26 +0300
Subject: [PATCH] Walk -M /dir:/dir0:/dirN in man.

Iterate over MANPATH and ordered sections using a manpath() helper
equivalent of indenting logic of man x, man 1 x, and man -k each with a
strsep loop.
---
 tests/man.test     | 10 +++++++++-
 toys/pending/man.c | 32 ++++++++++++++++++++++----------
 2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/tests/man.test b/tests/man.test
index 65b8a06f..0f3ad1db 100644
--- a/tests/man.test
+++ b/tests/man.test
@@ -208,7 +208,15 @@ testing "-k -k" "$MAN -k -k" "numbers.1.bz2 - test -k\n" "" ""
 testing "-k d.*h" "$MAN -k 'd.*h'" "numbers.3.gz - No dash.\n" "" ""
 testing "-k ers.1" "$MAN -k ers.1" "numbers.1.bz2 - test -k\nnumbers.5 - See numbers.1\n" "" ""
 
+mkdir -p walrus/man1
+echo Local development override. | bzip2 >walrus/man1/numbers.1.bz2
+testing "-M /dir:/dir0" "man -M walrus:banana numbers" " Local development override.\n\n" "" ""
+testing "-M /dir:/dir0 -k ." "man -M walrus:banana -k ." "numbers.1.bz2 - Local development override.\nnumbers.1.bz2 - test -k\nnumbers.3.gz - No dash.\nnumbers.5 - See numbers.1\n" "" ""
+testing "-M '' x" "man -M '' numbers 2>&1" "man: no numbers\n" "" ""
+testing "-M '' 1 x" "man -M '' 1 numbers 2>&1" "man: section 1 no numbers\n" "" ""
+testing "-M '' -k ." "man -M '' -k ." "" "" ""
+
 # TODO: emerge section header newline
 # TODO: fdm,man-pages man1p/, .nf, rare tags
 
-rm -rf banana
+rm -rf banana walrus
diff --git a/toys/pending/man.c b/toys/pending/man.c
index 82d3c2c9..1d3487d0 100644
--- a/toys/pending/man.c
+++ b/toys/pending/man.c
@@ -32,7 +32,7 @@ config MAN
 GLOBALS(
   char *M, *k;
 
-  char any, cell, ex, *f, k_done, *line, **sufs;
+  char any, cell, ex, *f, k_done, *line, *m, **sct, **scts, **sufs;
   regex_t reg;
 )
 
@@ -137,11 +137,19 @@ static int zopen(char *s)
   return fds[1];
 }
 
+static char manpath()
+{
+  if (*++TT.sct) return 0;
+  if (!(TT.m = strsep(&TT.M, ":"))) return 1;
+  TT.sct = TT.scts;
+  return 0;
+}
+
 // Try opening all the possible file extensions.
-int tryfile(char *section, char *name)
+static int tryfile(char *name)
 {
-  char *s = xmprintf("%s/man%s/%s.%s.bz2", TT.M, section, name, section), **suf;
   int dotnum, fd = -1;
+  char *s = xmprintf("%s/man%s/%s.%s.bz2", TT.m, *TT.sct, name, *TT.sct), **suf;
   size_t len = strlen(s) - 4;
 
   for (dotnum = 0; dotnum <= 2; dotnum += 2) {
@@ -156,7 +164,8 @@ int tryfile(char *section, char *name)
 void man_main(void)
 {
   int fd = -1;
-  char **order = (char *[]) {"1", "8", "3", "2", "5", "4", "6", "7", 0};
+  TT.scts = (char *[]) {"1", "8", "3", "2", "5", "4", "6", "7", 0};
+  TT.sct = TT.scts - 1; // First manpath() read increments.
   TT.sufs = (char *[]) {".bz2", ".gz", ".xz", "", 0};
 
   if (!TT.M) TT.M = getenv("MANPATH");
@@ -167,8 +176,8 @@ void man_main(void)
     DIR *dp;
     struct dirent *entry;
     if (regcomp(&TT.reg, TT.k, REG_ICASE|REG_NOSUB)) error_exit("bad regex");
-    while (*order) {
-      d = xmprintf("%s/man%s", TT.M, *order++);
+    while (!manpath()) {
+      d = xmprintf("%s/man%s", TT.m, *TT.sct);
       if (!(dp = opendir(d))) continue;
       while ((entry = readdir(dp))) {
         if (entry->d_name[0] == '.') continue;
@@ -190,12 +199,15 @@ void man_main(void)
 
   if (toys.optc == 1) {
     if (strchr(*toys.optargs, '/')) fd = zopen(*toys.optargs);
-    else while ((fd == -1) && *order) fd = tryfile(*order++, *toys.optargs);
-    if (!*order) error_exit("no %s", *toys.optargs);
+    else while ((fd == -1) && !manpath()) fd = tryfile(*toys.optargs);
+    if (fd == -1) error_exit("no %s", *toys.optargs);
 
   // If they specified a section, look for file in that section
-  } else if (-1 == (fd = tryfile(toys.optargs[0], toys.optargs[1])))
-    error_exit("section %s no %s", toys.optargs[0], toys.optargs[1]);
+  } else {
+    TT.scts = (char *[]){*toys.optargs, 0}, TT.sct = TT.scts - 1;
+    while ((fd == -1) && !manpath()) fd = tryfile(toys.optargs[1]);
+    if (fd == -1) error_exit("section %s no %s", *--TT.sct, toys.optargs[1]);
+  }
 
   do_lines(fd, '\n', do_man);
 }



More information about the Toybox mailing list