#!/bin/sh
# makewhatis: create the whatis database
# Created: Sun Jun 14 10:49:37 1992
# Revised: Sat Jan  8 14:12:37 1994 by faith@cs.unc.edu
# Copyright 1992, 1993, 1994 Rickard E. Faith (faith@cs.unc.edu)
# May be freely distributed and modified as long as copyright is retained.
#
# Wed Dec 23 13:27:50 1992: Rik Faith (faith@cs.unc.edu) applied changes
# based on Mitchum DSouza (mitchum.dsouza@mrc-apu.cam.ac.uk) cat patches.
# Also, cleaned up code and make it work with NET-2 doc pages.
#
# makewhatis-1.4: aeb 940802, 941007, 950417
# Fixed so that the -c option works correctly for the cat pages
# on my machine. Fix for -u by Nan Zou (nan@ksu.ksu.edu).
# Many minor changes.
# The -s option is undocumented, and may well disappear again.
#
# Note for Slackware users: "makewhatis -v -w -c" will work.

PATH=/usr/bin:/bin

DEFMANPATH=/usr/man
DEFCATPATH=/usr/man/preformat:/usr/man
manfilter="cat"
catfilter="col -bx"

topath=manpath

defmanpath=$DEFMANPATH
defcatpath=

sections="1 2 3 4 5 6 7 8 9 n l"

for name in $*
do
if [ -n "$setsections" ]; then
	setsections=
	sections=$name
	continue
fi
case $name in
    -c) topath=catpath
	defmanpath=
	defcatpath=$DEFCATPATH
        continue;;
    -s) setsections=1
        continue;;
    -u) findarg="-ctime 0"
        update=1
        continue;;
    -v) verbose=1
	continue;;
    -w) manpath=`man --path`
	continue;;
    -*) echo "Usage: makewhatis [-u] [-v] [-w] [manpath] [-c [catpath]]"
	echo "       This will build the whatis database for the man pages"
	echo "       found in manpath and the cat pages found in catpath."
        echo "       -u: update database with new pages"
	echo "       -v: verbose"
	echo "       -w: use manpath obtained from \`man --path\`"
        echo "       [manpath]: man directories (default: $DEFMANPATH)"
	echo "       [catpath]: cat directories (default: the first existing"
	echo "           directory in $DEFCATPATH)"
        exit;;
     *) if [ -d $name ]
        then
            eval $topath=$"$topath":$name
        else
            echo "No such directory $name"
            exit
        fi;;
esac
done

manpath=`echo ${manpath-$defmanpath} | tr : ' '`
if [ -z "$catpath" ]; then
   for d in `echo $defcatpath | tr : ' '`
   do
      if [ -d $d ]; then catpath=$d; break; fi
   done
fi
catpath=`echo ${catpath} | tr : ' '`

# first remove all the whatis files that will be created new,
# then only update - we might visit the same directory twice
if [ -z $update ]; then
   for pages in man cat
   do
      eval path=$"$pages"path
      for mandir in $path
      do
         rm -f $mandir/whatis
      done
   done
fi

for pages in man cat
do
   export pages
   eval filter=$"$pages"filter
   eval path=$"$pages"path
   for mandir in $path
   do
     if [ x$verbose != x ]; then
        echo "about to enter $mandir" > /dev/tty
     fi
     cd $mandir
     if [ -f ./whatis -a $pages = man ]; then
        if [ x$verbose != x ]; then
           echo skipping $mandir - we did it already > /dev/tty
        fi
     else      
      for i in $sections
      do
         if [ -d ${pages}$i ]
         then
            cd ${pages}$i
            section=$i
            export section
            for j in `find . -name '*' ${findarg} -print`
            do
               case $j in
               *.Z|*.z|*.gz)
                  Cat=zcat
                  ;;
               *)
                  Cat=cat
                  ;;
               esac
               if [ x$verbose != x ]; then
                  echo "adding $j" > /dev/tty
               fi
               progname=`basename $j | sed 's/\..*//'`
               export progname
               ${Cat} ${j} | ${filter} |\
               gawk 'BEGIN {after = 0; insh = 0; thisjoin = 1; charct = 0;
                        pages = ENVIRON["pages"];
                        section = ENVIRON["section"]
                        progname = ENVIRON["progname"]} {
                  if (($1 ~ /^\.[Ss][Hh]/ && $2 ~ /[Nn][Aa][Mm][Ee]/) ||
                     (pages == "cat" && $1 ~ /^NAME/)) {
                     if (!insh)
                        insh = 1
                     else {
                        printf "\n"
                        exit
                     }
                  } else if (insh) {
                     if ($1 ~ /^\.[Ss][HhYS]/ ||
                        (pages == "cat" &&
                           ($1 ~ /^S[yYeE]/ || $1 ~ /^DESCRIPTION/ ||
                            $1 ~ /^COMMAND/ || $1 ~ /^OVERVIEW/ ||
                            $1 ~ /^STRUCTURES/ || $1 ~ /^INTRODUCTION/))) {
                           # end insh for Synopsis, Syntax, but also for
                           # DESCRIPTION (e.g., XFree86.1x),
                           # COMMAND (e.g., xspread.1)
                           # OVERVIEW (e.g., TclCommandWriting.3)
                           # STRUCTURES (e.g., XEvent.3x)
                           # INTRODUCTION (e.g., TclX.n)
                        printf "\n"
                        exit
                     } else { # derived from Tom Christiansen perl script
                        if (!after && $0 ~ progname"-") {  # Fix old cat pages
                           sub(progname"-", progname" - ")
                        }
                        gsub(/	/, " ")          # Translate tabs to spaces
                        gsub(/  +/, " ")         # Collapse spaces
                        gsub(/ *, */, ", ")      # Fix comma spacings
                        sub(/^ /, "")            # Kill initial spaces
                        sub(/ $/, "")            # Kill trailing spaces
                        sub(/__+/, "_")          # Collapse underscores
                        if ($0 ~ /[^ ]-$/) {
                           sub(/-$/, "")         # Handle Hyphenations
                           nextjoin = 1
                        } else
                           nextjoin = 0
                        sub(/^.[IB] /, "")       # Kill bold and italics
                        sub(/^.Nm /, "")         # Kill bold
                        sub(/^.Tn /, "")         # Kill normal
                        sub(/^.Li /, "")         # Kill .Li
                        sub(/^.Dq /, "")         # Kill .Dq
                        sub(/^.Nd */, "- ")      # Convert .Nd to dash
                        gsub(/\\f[PRIB0123]/, "")   # Kill font changes
                        gsub(/\\s[-+0-9]*/, "")     # Kill size changes
                        gsub(/\\&/, "")             # Kill \&
                        gsub(/\\\((ru|ul)/, "_")    # Translate
                        gsub(/\\\((mi|hy|em)/, "-") # Translate
                        gsub(/\\\*\(../, "")        # Kill troff strings
                        sub(/^\.\\\".*/, "")        # Kill comments
                        gsub(/\\/, "")              # Kill all backslashes
                        if ($1 ~ /^\.../ || $1 == "") {
                           if (after && !needmore) {
                              printf "\n"
                              thisjoin = 1
                              charct = 0
                              after = 0
                           }
                        } else {
                           if ($0 ~ /^- /) {
                              sub("- ", " - ");
                           } else if (!thisjoin && $0 !~ /^- /) {
			      printf " "
                              charct += 1
                           }
                           thisjoin = nextjoin
                           if ($0 !~ / - / && $0 !~ / -$/ && $0 !~ /^- /) {
                              printf "%s", $0
			      charct += length
                              needmore = 0
                           } else {
                              after = 1
                              if ($0 ~ / - /) {
                                 where = match( $0 , / - /)
                              } else if ($0 ~ / -$/) {
                                 where = match( $0, / -$/)
                              } else {
                                 where = 0
                              }
                              printf "%-*s", 20-charct, sprintf( "%s (%s)",
                                    substr( $0, 0, where-1 ), section )
                              printf "%s", substr( $0, where )
                              if ($0 ~ /- *$/) {
                                 needmore = 1
                              } else {
                                 needmore = 0
                              }
                           }
                        }
                     }
                  }
               }'
               done
            cd ..
         fi
      done > /tmp/whatis$$

      # kludge for Slackware's /usr/man/preformat
      if [ $mandir = /usr/man/preformat ]
      then
         mandir1=/usr/man
      else
         mandir1=$mandir
      fi

      if [ -f ${mandir1}/whatis ]
      then
         cat ${mandir1}/whatis >> /tmp/whatis$$
      fi
      sed '/^$/d' < /tmp/whatis$$ | sort | uniq > ${mandir1}/whatis
      chmod 644 ${mandir1}/whatis
      rm /tmp/whatis$$
     fi
   done
done
