about summary refs log tree commit diff stats
path: root/adapter
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-03-15 11:08:21 +0100
committerbptato <nincsnevem662@gmail.com>2024-03-15 11:28:35 +0100
commit39ae15c1049f41f0ab3b60e420fa6d79f5ed48cd (patch)
treec022f4ca70fbeeb550641321798b464cefa6a033 /adapter
parent5d95938a2fbf1bbc1f4ce05993da3e8dc9da6261 (diff)
downloadchawan-39ae15c1049f41f0ab3b60e420fa6d79f5ed48cd.tar.gz
man: work around parameter insanity
This is horrible.

-s means completely different things on various systems. -l does not
exist on various systems. Nothing is standardized, except that man
should take at least one parameter and that -k should perform a search.
(Seriously, that's all.)

So what we do is:
* add a separate env var for overriding apropos
* for man:, never use -s to specify sections
* for man-k:, fall back to man, EXCEPT on FreeBSD which does not have a
  working section specifier on man -k (neither -S nor MANSECT does
  anything)
* for man-l:, just pass the path wholesale to man and hope it does
  something useful.

Also, we now set MANCOLOR to 1 so FreeBSD man gives us formatting as
well.
Diffstat (limited to 'adapter')
-rw-r--r--adapter/protocol/man.nim24
1 files changed, 18 insertions, 6 deletions
diff --git a/adapter/protocol/man.nim b/adapter/protocol/man.nim
index e35abde7..17f44dea 100644
--- a/adapter/protocol/man.nim
+++ b/adapter/protocol/man.nim
@@ -220,9 +220,9 @@ proc processManpage(file: File; header: string) =
   discard file.pclose()
 
 proc doMan(man, keyword, section: string) =
-  let sectionOpt = if section == "": "" else: " -s " & section
-  let cmd = "GROFF_NO_SGR=1 MAN_KEEP_FORMATTING=1 " &
-    man & sectionOpt & " " & keyword & " 2>&1"
+  let sectionOpt = if section == "": "" else: ' ' & section
+  let cmd = "MANCOLOR=1 GROFF_NO_SGR=1 MAN_KEEP_FORMATTING=1 " &
+    man & sectionOpt & ' ' & keyword & " 2>&1"
   let file = popen(cstring(cmd), "r")
   if file == nil:
     stdout.write("Cha-Control: ConnectionError 1 failed to run " & cmd)
@@ -236,8 +236,10 @@ proc doMan(man, keyword, section: string) =
 <pre>""")
 
 proc doLocal(man, path: string) =
-  let cmd = "GROFF_NO_SGR=1 MAN_KEEP_FORMATTING=1 " &
-    man & " -l " & path & " 2>&1"
+  # Note: we intentionally do not use -l, because it is not supported on
+  # various systems (at the very least FreeBSD, NetBSD).
+  let cmd = "MANCOLOR=1 GROFF_NO_SGR=1 MAN_KEEP_FORMATTING=1 " &
+    man & ' ' & path & " 2>&1"
   let file = popen(cstring(cmd), "r")
   if file == nil:
     stdout.write("Cha-Control: ConnectionError 1 failed to run " & cmd)
@@ -304,6 +306,16 @@ proc main() =
           man = s
           break notfound
       man = "/usr/bin/env man"
+  var apropos = getEnv("MANCHA_APROPOS")
+  if apropos == "":
+    # on most systems, man is compatible with apropos (using -s syntax for
+    # specifying sections).
+    # ...not on FreeBSD :( here we have -S and MANSECT for specifying man
+    # sections, and both are silently ignored when searching with -k. hooray.
+    when not defined(freebsd):
+      apropos = man
+    else:
+      apropos = "/usr/bin/apropos" # this is where it should be.
   let path = getEnv("MAPPED_URI_PATH")
   let scheme = getEnv("MAPPED_URI_SCHEME")
   if scheme == "man":
@@ -311,7 +323,7 @@ proc main() =
     doMan(man, keyword, section)
   elif scheme == "man-k":
     let (keyword, section) = parseSection(path)
-    doKeyword(man, keyword, section)
+    doKeyword(apropos, keyword, section)
   elif scheme == "man-l":
     doLocal(man, path)
   else: