home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / perl / scripts-convex / man.shar / man / catman < prev    next >
Encoding:
Text File  |  1991-03-04  |  4.9 KB  |  231 lines

  1. #!/usr/local/bin/perl
  2. #
  3. # perl rewrite of catman 
  4. # author: tom christiansen <tchrist@convex.com>
  5. #
  6. # Copyright 1990 Convex Computer Corporation.
  7. # All rights reserved.
  8.  
  9. $| = 1;
  10.  
  11. $TBL        = "tbl -D";
  12. $EQN        = "neqn";
  13. # $MAKEWHATIS = "/usr/lib/makewhatis";
  14. $MAKEWHATIS = "/usr/local/lib/makewhatis";
  15. $COMPRESS   = "compress";
  16. $NROFF        = "nroff";
  17. $COL         = "col";
  18. $CAT        = "cat";
  19. $ZCAT        = "zcat";
  20.  
  21. # Command to format man pages to be viewed on a tty or printed on a line printer
  22. $CATSET      = "$NROFF -h -man -";
  23. $CATSET  .= " | $COL" if $COL;
  24.  
  25. umask 022;
  26.  
  27. do 'getopts.pl' || die("can't do getopts.pl", $@?$@:$!, "\n");
  28.  
  29. # -Z flag is planning for the future
  30. unless (&Getopts('dpnwZP:M:') && $ARGV <= 1) {
  31.     die "usage: $0 [-pnwZ] [[-M] manpath] [sections]\n";
  32. }
  33.  
  34. $debug      =  $opt_d;
  35. $makewhatis = !$opt_n;
  36. $catman     = !$opt_w;
  37. $fakeout    =  $opt_p;
  38. $compress   =  $opt_Z;
  39.  
  40.  
  41. $manpath = shift if $ARGV[0] =~ m#^/#;
  42.  
  43. if ($sections = shift) {
  44.      $delim = ($sections =~ /:/) ? ':' : '';
  45.      $sections =~ s/(.)-(.)/join("","$1".."$2")/ge; # expand 1-3 and l-p ranges
  46.      grep($sections{$_}++, split(/$delim/,$sections));
  47.      print STDERR "sections are: ", 
  48.      join(':',keys %sections), "\n" if $debug;
  49. }
  50.  
  51.  
  52. $manpath = $manpath || $opt_P || $opt_M || "/usr/man";
  53.  
  54.  
  55. path: foreach $path (split(/:/,$manpath)) {
  56.     unless (chdir $path) {
  57.     warn "can't chdir to $path: $!";
  58.     $status = 1;
  59.     next path;
  60.     }
  61.     if ($makewhatis) {
  62.     &run ("$MAKEWHATIS " . ($debug ? "-d" : "") . " $path") ||
  63.         warn "$0: $MAKEWHATIS returned " . ($? >> 8) . " ($!)\n";
  64.     }
  65.     next unless $catman;
  66.  
  67.     print "chdir $path\n" if $debug;
  68.  
  69.     unless (dbmopen(%whatis, "whatis", undef)) {
  70.     warn "can't dbmopen $path/whatis: $!\n";
  71.     warn "$0: please run makewhatis first\n";
  72.     $status++;
  73.     next;
  74.     } 
  75.  
  76.     $SIG{'PIPE'} = 'PLUMBER';
  77.  
  78.     while (($key,$value) = each %whatis) {
  79.  
  80. manpage: for (split(/\002/, $value)) {
  81.         next unless /\001/; # otherwise indirect reference
  82.  
  83.         ($cmd, $page, $section, $desc) = split(/\001/);
  84.         $manpage = "$path/man$section/$page";
  85.         next if $sections && !$sections{$section};
  86.         print STDERR "considering $manpage\n" if $debug;
  87.  
  88.         local(@st_man, @st_cat);
  89.  
  90.         if ($manpage !~ /\S\.\S/) {
  91.         print "skipping non man file: $manpage\n" if $debug;
  92.         next manpage;
  93.         } 
  94.  
  95.         if (!-e $manpage) {
  96.         $manpage .= '.Z';
  97.         next unless -e $manpage;
  98.         } 
  99.  
  100.         ($catpage = $manpage) 
  101.         =~ s,^(.*)/man([^\.]*)(\.Z)?/([^/]*)$,$1/cat$2$3/$4,;
  102.  
  103.         ($catdir = $catpage) =~ s#/[^/]*$##;
  104.         next manpage unless -d $catdir && -w _;
  105.  
  106.         if ((stat(_))[9] > (stat($catpage))[9]) {
  107.         $command = (($manpage =~ m:\.Z:) ? $ZCAT : $CAT)
  108.                 . " < $manpage | $CATSET";
  109.  
  110.         $command = &insert_filters($command, $manpage);
  111.         $command =~ s,-man,$path/tmac.an, if -e "$path/tmac.an";
  112.  
  113.         $command .= "| $COMPRESS " if $catpage =~ /\.Z/;
  114.  
  115.         $command .= "> $catpage";
  116.  
  117.         eval '&reformat($command)'; # setjmp for SIGPIPE
  118.  
  119.         if ($@) {
  120.             next if $@ =~ /broken pipe/i;
  121.             die $@;
  122.         }
  123.         }
  124.     }
  125.     } 
  126.     dbmclose(whatis);
  127. }
  128.  
  129. exit $status;
  130.  
  131. sub PLUMBER { die "Broken pipe writing to kid proc!\n"; }  # longjmp
  132.  
  133. sub insert_filters {
  134.     local($filters,$eqn, $tbl, $_);
  135.     local(*PAGE);
  136.     local($command, $PAGE) = @_;
  137.  
  138.  
  139.     $PAGE = "$ZCAT < $PAGE|" if $PAGE =~ /\.Z/;
  140.  
  141.     (open PAGE) || die ("can't open $page to check filters: $!\n");
  142.  
  143.     while (<PAGE>) {
  144.     if (/^\.EQ/) {
  145.         $_ = <PAGE>;
  146.         $eqn = 1 unless /\.(if|nr)/;  # has eqn output not input
  147.     } 
  148.     if (/^\.TS/) {
  149.         $_ = <PAGE>;
  150.         $tbl = 1 unless /\.(if|nr)/;  # has tbl output not input
  151.     } 
  152.     last if $eqn && $tbl;
  153.     } 
  154.     close PAGE;
  155.  
  156.     $eqn && $_[0] =~ s/(\S+roff)/$EQN | $1/;
  157.     $tbl && $_[0] =~ s/(\S+roff)/$TBL | $1/;
  158.  
  159.     $_[0];
  160.  
  161.  
  162. sub run {
  163.     local($command) = $_[0];
  164.     $command =~ s/^\s*cat\s*<?\s*([^\s|]+)\s*\|\s*([^|]+)/$2 < $1/;
  165.     $command =~ s/^([^|<]+)<([^Z|<]+)$/$1 $2/;
  166.     print STDERR "$command\n" if $debug || $fakeout;
  167.     if ((!$fakeout) && system($command)) {
  168.     $status++;
  169.     printf STDERR "\"%s\" exited %d, sig %d: $!\n", $command, 
  170.         ($? >> 8), ($? & 255) if $debug;
  171.     } 
  172.     $? == 0;
  173. }
  174.  
  175. sub print {
  176.     local($_) = @_;
  177.  
  178.     if (!$inbold) {
  179.     print;
  180.     } else {
  181.     for (split(//)) {
  182.         print /[!-~]/ ? $_."\b".$_ : $_;
  183.     } 
  184.     } 
  185. }
  186.  
  187. sub reformat {
  188.     local($_) = @_;
  189.     local($nroff, $col);
  190.     local($inbold) = 0;
  191.  
  192.     s/^\s*cat\s*<?\s*([^\s|]+)\s*\|\s*([^|]+)/$2 < $1/;
  193.     s/^([^|<]+)<([^Z|<]+)$/$1 $2/;
  194.     ($nroff, $col) = m!(.*)\|\s*($COL.*)!;
  195.  
  196.     print STDERR "$nroff | (this proc) | $col\n" if $debug || $fakeout;
  197.  
  198.     return 0 if $fakeout;
  199.  
  200.     open (NROFF, "$nroff |");
  201.     open (COL, "| $col");
  202.  
  203.     select(COL);
  204.  
  205.     while (<NROFF>) {
  206.     s/\033\+/\001/;
  207.     s/\033\,/\002/;
  208.     if ( /^([^\001]*)\002/ || /^([^\002]*)\001/ )  {
  209.         &print($1);
  210.         $inbold = !$inbold;
  211.         $_ = $';
  212.         redo;
  213.     }   
  214.     &print($_);
  215.     }
  216.  
  217.     close NROFF;
  218.     if ($?) {
  219.     warn "$program: \"$nroff\" failed!\n";
  220.     $status++;
  221.     } 
  222.     close COL;
  223.     if ($?) {
  224.     warn "$program: \"$col\" failed!\n";
  225.     $status++;
  226.     }
  227.     select(STDOUT);
  228.     1;
  229. }
  230.