Home | History | Annotate | Line # | Download | only in groffer
      1  1.1  christos #! /bin/sh
      2  1.1  christos 
      3  1.1  christos # groffer - display groff files
      4  1.1  christos 
      5  1.1  christos # Source file position: <groff-source>/contrib/groffer/groffer2.sh
      6  1.1  christos # Installed position: <prefix>/lib/groff/groffer/groffer2.sh
      7  1.1  christos 
      8  1.1  christos # This file should not be run independently.  It is called by
      9  1.1  christos # `groffer.sh' in the source or by the installed `groffer' program.
     10  1.1  christos 
     11  1.1  christos # Copyright (C) 2001,2002,2003,2004,2005
     12  1.1  christos # Free Software Foundation, Inc.
     13  1.1  christos # Written by Bernd Warken
     14  1.1  christos 
     15  1.1  christos # Last update: 22 August 2005
     16  1.1  christos 
     17  1.1  christos # This file is part of `groffer', which is part of `groff'.
     18  1.1  christos 
     19  1.1  christos # `groff' is free software; you can redistribute it and/or modify it
     20  1.1  christos # under the terms of the GNU General Public License as published by
     21  1.1  christos # the Free Software Foundation; either version 2, or (at your option)
     22  1.1  christos # any later version.
     23  1.1  christos 
     24  1.1  christos # `groff' is distributed in the hope that it will be useful, but
     25  1.1  christos # WITHOUT ANY WARRANTY; without even the implied warranty of
     26  1.1  christos # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     27  1.1  christos # General Public License for more details.
     28  1.1  christos 
     29  1.1  christos # You should have received a copy of the GNU General Public License
     30  1.1  christos # along with `groff'; see the files COPYING and LICENSE in the top
     31  1.1  christos # directory of the `groff' source.  If not, write to the Free Software
     32  1.1  christos # Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301,
     33  1.1  christos # USA.
     34  1.1  christos 
     35  1.1  christos 
     36  1.1  christos ########################################################################
     37  1.1  christos #             Test of rudimentary shell functionality
     38  1.1  christos ########################################################################
     39  1.1  christos 
     40  1.1  christos 
     41  1.1  christos ########################################################################
     42  1.1  christos # Test of `unset'
     43  1.1  christos #
     44  1.1  christos export _UNSET;
     45  1.1  christos export _foo;
     46  1.1  christos _foo=bar;
     47  1.1  christos _res="$(unset _foo 2>&1)";
     48  1.1  christos if unset _foo >${_NULL_DEV} 2>&1 && \
     49  1.1  christos    test _"${_res}"_ = __ && test _"${_foo}"_ = __
     50  1.1  christos then
     51  1.1  christos   _UNSET='unset';
     52  1.1  christos   eval "${_UNSET}" _foo;
     53  1.1  christos   eval "${_UNSET}" _res;
     54  1.1  christos else
     55  1.1  christos   _UNSET=':';
     56  1.1  christos fi;
     57  1.1  christos 
     58  1.1  christos 
     59  1.1  christos ########################################################################
     60  1.1  christos # Test of `test'.
     61  1.1  christos #
     62  1.1  christos if test a = a && test a != b && test -f "${_GROFFER_SH}"
     63  1.1  christos then
     64  1.1  christos   :;
     65  1.1  christos else
     66  1.1  christos   echo '"test" did not work.' >&2;
     67  1.1  christos   exit "${_ERROR}";
     68  1.1  christos fi;
     69  1.1  christos 
     70  1.1  christos 
     71  1.1  christos ########################################################################
     72  1.1  christos # Test of `echo' and the `$()' construct.
     73  1.1  christos #
     74  1.1  christos if echo '' >${_NULL_DEV}
     75  1.1  christos then
     76  1.1  christos   :;
     77  1.1  christos else
     78  1.1  christos   echo '"echo" did not work.' >&2;
     79  1.1  christos   exit "${_ERROR}";
     80  1.1  christos fi;
     81  1.1  christos if test _"$(t1="$(echo te)" &&
     82  1.1  christos             t2="$(echo '')" &&
     83  1.1  christos             t3="$(echo 'st')" &&
     84  1.1  christos             echo "${t1}${t2}${t3}")"_ \
     85  1.1  christos      != _test_
     86  1.1  christos then
     87  1.1  christos   echo 'The "$()" construct did not work' >&2;
     88  1.1  christos   exit "${_ERROR}";
     89  1.1  christos fi;
     90  1.1  christos 
     91  1.1  christos 
     92  1.1  christos ########################################################################
     93  1.1  christos # Test of sed program; test in groffer.sh is not valid here.
     94  1.1  christos #
     95  1.1  christos if test _"$(echo red | sed -e 's/r/s/')"_ != _sed_
     96  1.1  christos then
     97  1.1  christos   echo 'The sed program did not work.' >&2;
     98  1.1  christos   exit "${_ERROR}";
     99  1.1  christos fi;
    100  1.1  christos 
    101  1.1  christos 
    102  1.1  christos ########################################################################
    103  1.1  christos # Test of function definitions.
    104  1.1  christos #
    105  1.1  christos _t_e_s_t_f_u_n_c_()
    106  1.1  christos {
    107  1.1  christos   return 0;
    108  1.1  christos }
    109  1.1  christos 
    110  1.1  christos if _t_e_s_t_f_u_n_c_ 2>${_NULL_DEV}
    111  1.1  christos then
    112  1.1  christos   :;
    113  1.1  christos else
    114  1.1  christos   echo 'Shell '"${_SHELL}"' does not support function definitions.' >&2;
    115  1.1  christos   exit "${_ERROR}";
    116  1.1  christos fi;
    117  1.1  christos 
    118  1.1  christos 
    119  1.1  christos ########################################################################
    120  1.1  christos #                    debug - diagnostic messages
    121  1.1  christos ########################################################################
    122  1.1  christos 
    123  1.1  christos export _DEBUG_STACKS;
    124  1.1  christos _DEBUG_STACKS='no';		# disable stack output in each function
    125  1.1  christos #_DEBUG_STACKS='yes';		# enable stack output in each function
    126  1.1  christos 
    127  1.1  christos export _DEBUG_LM;
    128  1.1  christos _DEBUG_LM='no';			# disable landmark messages
    129  1.1  christos #_DEBUG_LM='yes';		# enable landmark messages
    130  1.1  christos 
    131  1.1  christos export _DEBUG_KEEP_FILES;
    132  1.1  christos _DEBUG_KEEP_FILES='no'		# disable file keeping in temporary dir
    133  1.1  christos #_DEBUG_KEEP_FILES='yes'	# enable file keeping in temporary dir
    134  1.1  christos 
    135  1.1  christos export _DEBUG_PRINT_PARAMS;
    136  1.1  christos _DEBUG_PRINT_PARAMS='no';	# disable printing of all parameters
    137  1.1  christos #_DEBUG_PRINT_PARAMS='yes';	# enable printing of all parameters
    138  1.1  christos 
    139  1.1  christos export _DEBUG_PRINT_SHELL;
    140  1.1  christos _DEBUG_PRINT_SHELL='no';	# disable printing of the shell name
    141  1.1  christos #_DEBUG_PRINT_SHELL='yes';	# enable printing of the shell name
    142  1.1  christos 
    143  1.1  christos export _DEBUG_PRINT_TMPDIR;
    144  1.1  christos _DEBUG_PRINT_TMPDIR='no';	# disable printing of the temporary dir
    145  1.1  christos #_DEBUG_PRINT_TMPDIR='yes';	# enable printing of the temporary dir
    146  1.1  christos 
    147  1.1  christos export _DEBUG_USER_WITH_STACK;
    148  1.1  christos _DEBUG_USER_WITH_STACK='no';	# disable stack dump in error_user()
    149  1.1  christos #_DEBUG_USER_WITH_STACK='yes';	# enable stack dump in error_user()
    150  1.1  christos 
    151  1.1  christos # determine all --debug* options
    152  1.1  christos case " $*" in
    153  1.1  christos *\ --debug*)
    154  1.1  christos   case " $* " in
    155  1.1  christos   *' --debug '*)
    156  1.1  christos     # _DEBUG_STACKS='yes';
    157  1.1  christos     # _DEBUG_LM='yes';
    158  1.1  christos     _DEBUG_KEEP_FILES='yes';
    159  1.1  christos     _DEBUG_PRINT_PARAMS='yes';
    160  1.1  christos     _DEBUG_PRINT_SHELL='yes';
    161  1.1  christos     _DEBUG_PRINT_TMPDIR='yes';
    162  1.1  christos     _DEBUG_USER_WITH_STACK='yes';
    163  1.1  christos     ;;
    164  1.1  christos   esac;
    165  1.1  christos   d=' --debug-all --debug-keep --debug-lm --debug-params --debug-shell '\
    166  1.1  christos '--debug-stacks --debug-tmpdir --debug-user ';
    167  1.1  christos   for i
    168  1.1  christos   do
    169  1.1  christos     case "$i" in
    170  1.1  christos     --debug-s)
    171  1.1  christos       echo 'The abbreviation --debug-s has multiple options: '\
    172  1.1  christos '--debug-shell and --debug-stacks.' >&2
    173  1.1  christos       exit "${_ERROR}";
    174  1.1  christos       ;;
    175  1.1  christos     esac;
    176  1.1  christos     case "$d" in
    177  1.1  christos     *\ ${i}*)
    178  1.1  christos       # extract whole word of abbreviation $i
    179  1.1  christos       s="$(cat <<EOF | sed -n -e 's/^.* \('"$i"'[^ ]*\) .*/\1/p'
    180  1.1  christos $d
    181  1.1  christos EOF
    182  1.1  christos )"
    183  1.1  christos       case "$s" in
    184  1.1  christos       '') continue; ;;
    185  1.1  christos       --debug-all)
    186  1.1  christos         _DEBUG_STACKS='yes';
    187  1.1  christos         _DEBUG_LM='yes';
    188  1.1  christos         _DEBUG_KEEP_FILES='yes';
    189  1.1  christos         _DEBUG_PRINT_PARAMS='yes';
    190  1.1  christos         _DEBUG_PRINT_SHELL='yes';
    191  1.1  christos         _DEBUG_PRINT_TMPDIR='yes';
    192  1.1  christos         _DEBUG_USER_WITH_STACK='yes';
    193  1.1  christos         ;;
    194  1.1  christos       --debug-keep)
    195  1.1  christos         _DEBUG_PRINT_TMPDIR='yes';
    196  1.1  christos         _DEBUG_KEEP_FILES='yes';
    197  1.1  christos         ;;
    198  1.1  christos       --debug-lm)
    199  1.1  christos         _DEBUG_LM='yes';
    200  1.1  christos         ;;
    201  1.1  christos       --debug-params)
    202  1.1  christos         _DEBUG_PRINT_PARAMS='yes';
    203  1.1  christos         ;;
    204  1.1  christos       --debug-shell)
    205  1.1  christos         _DEBUG_PRINT_SHELL='yes';
    206  1.1  christos         ;;
    207  1.1  christos       --debug-stacks)
    208  1.1  christos         _DEBUG_STACKS='yes';
    209  1.1  christos         ;;
    210  1.1  christos       --debug-tmpdir)
    211  1.1  christos         _DEBUG_PRINT_TMPDIR='yes';
    212  1.1  christos         ;;
    213  1.1  christos       --debug-user)
    214  1.1  christos         _DEBUG_USER_WITH_STACK='yes';
    215  1.1  christos         ;;
    216  1.1  christos       esac;
    217  1.1  christos       ;;
    218  1.1  christos     esac;
    219  1.1  christos   done
    220  1.1  christos   ;;
    221  1.1  christos esac;
    222  1.1  christos 
    223  1.1  christos if test _"${_DEBUG_PRINT_PARAMS}"_ = _yes_
    224  1.1  christos then
    225  1.1  christos   echo "parameters: $@" >&2;
    226  1.1  christos fi;
    227  1.1  christos 
    228  1.1  christos if test _"${_DEBUG_PRINT_SHELL}"_ = _yes_
    229  1.1  christos then
    230  1.1  christos   if test _"${_SHELL}"_ = __
    231  1.1  christos   then
    232  1.1  christos     if test _"${POSIXLY_CORRECT}"_ = _y_
    233  1.1  christos     then
    234  1.1  christos       echo 'shell: bash as /bin/sh (none specified)' >&2;
    235  1.1  christos     else
    236  1.1  christos       echo 'shell: /bin/sh (none specified)' >&2;
    237  1.1  christos     fi;
    238  1.1  christos   else
    239  1.1  christos     echo "shell: ${_SHELL}" >&2;
    240  1.1  christos   fi;
    241  1.1  christos fi;
    242  1.1  christos 
    243  1.1  christos 
    244  1.1  christos ########################################################################
    245  1.1  christos #                       Environment Variables
    246  1.1  christos ########################################################################
    247  1.1  christos 
    248  1.1  christos # Environment variables that exist only for this file start with an
    249  1.1  christos # underscore letter.  Global variables to this file are written in
    250  1.1  christos # upper case letters, e.g. $_GLOBAL_VARIABLE; temporary variables
    251  1.1  christos # start with an underline and use only lower case letters and
    252  1.1  christos # underlines, e.g.  $_local_variable .
    253  1.1  christos 
    254  1.1  christos #   [A-Z]*     system variables,      e.g. $MANPATH
    255  1.1  christos #   _[A-Z_]*   global file variables, e.g. $_MAN_PATH
    256  1.1  christos #   _[a-z_]*   temporary variables,   e.g. $_manpath
    257  1.1  christos 
    258  1.1  christos # Due to incompatibilities of the `ash' shell, the name of loop
    259  1.1  christos # variables in `for' must be single character
    260  1.1  christos #   [a-z]      local loop variables,   e.g. $i
    261  1.1  christos 
    262  1.1  christos 
    263  1.1  christos ########################################################################
    264  1.1  christos # read-only variables (global to this file)
    265  1.1  christos ########################################################################
    266  1.1  christos 
    267  1.1  christos # function return values; `0' means ok; other values are error codes
    268  1.1  christos export _ALL_EXIT;
    269  1.1  christos export _BAD;
    270  1.1  christos export _GOOD;
    271  1.1  christos export _NO;
    272  1.1  christos export _OK;
    273  1.1  christos export _YES;
    274  1.1  christos 
    275  1.1  christos _GOOD='0';			# return ok
    276  1.1  christos _BAD='1';			# return negatively, error code `1'
    277  1.1  christos # $_ERROR was already defined as `7' in groffer.sh.
    278  1.1  christos 
    279  1.1  christos _NO="${_BAD}";
    280  1.1  christos _YES="${_GOOD}";
    281  1.1  christos _OK="${_GOOD}";
    282  1.1  christos 
    283  1.1  christos # quasi-functions, call with `eval', e.g `eval "${return_ok}"'
    284  1.1  christos export return_ok;
    285  1.1  christos export return_good;
    286  1.1  christos export return_bad;
    287  1.1  christos export return_yes;
    288  1.1  christos export return_no;
    289  1.1  christos export return_error;
    290  1.1  christos export return_var;
    291  1.1  christos return_ok="func_pop; return ${_OK}";
    292  1.1  christos return_good="func_pop; return ${_GOOD}";
    293  1.1  christos return_bad="func_pop; return ${_BAD}";
    294  1.1  christos return_yes="func_pop; return ${_YES}";
    295  1.1  christos return_no="func_pop; return ${_NO}";
    296  1.1  christos return_error="func_pop; return ${_ERROR}";
    297  1.1  christos return_var="func_pop; return";	# add number, e.g. `eval "${return_var} $n'
    298  1.1  christos 
    299  1.1  christos 
    300  1.1  christos export _DEFAULT_MODES;
    301  1.1  christos _DEFAULT_MODES='x,ps,tty';
    302  1.1  christos export _DEFAULT_RESOLUTION;
    303  1.1  christos _DEFAULT_RESOLUTION='75';
    304  1.1  christos 
    305  1.1  christos export _DEFAULT_TTY_DEVICE;
    306  1.1  christos _DEFAULT_TTY_DEVICE='latin1';
    307  1.1  christos 
    308  1.1  christos # _VIEWER_* viewer programs for different modes (only X is necessary)
    309  1.1  christos # _VIEWER_* a comma-separated list of viewer programs (with options)
    310  1.1  christos export _VIEWER_DVI;		# viewer program for dvi mode
    311  1.1  christos export _VIEWER_HTML_TTY;	# viewer program for html mode in tty
    312  1.1  christos export _VIEWER_HTML_X;		# viewer program for html mode in X
    313  1.1  christos export _VIEWER_PDF;		# viewer program for pdf mode
    314  1.1  christos export _VIEWER_PS;		# viewer program for ps mode
    315  1.1  christos export _VIEWER_X;		# viewer program for X mode
    316  1.1  christos _VIEWER_DVI='kdvi,xdvi,dvilx';
    317  1.1  christos _VIEWER_HTML_TTY='lynx';
    318  1.1  christos _VIEWER_HTML_X='konqueror,mozilla,netscape,galeon,opera,amaya,arena';
    319  1.1  christos _VIEWER_PDF='kghostview --scale 1.45,ggv,xpdf,acroread,kpdf';
    320  1.1  christos _VIEWER_PS='kghostview --scale 1.45,ggv,gv,ghostview,gs_x11,gs';
    321  1.1  christos _VIEWER_X='gxditview,xditview';
    322  1.1  christos 
    323  1.1  christos # Search automatically in standard sections `1' to `8', and in the
    324  1.1  christos # traditional sections `9', `n', and `o'.  On many systems, there
    325  1.1  christos # exist even more sections, mostly containing a set of man pages
    326  1.1  christos # special to a specific program package.  These aren't searched for
    327  1.1  christos # automatically, but must be specified on the command line.
    328  1.1  christos export _MAN_AUTO_SEC_LIST;
    329  1.1  christos _MAN_AUTO_SEC_LIST="'1' '2' '3' '4' '5' '6' '7' '8' '9' 'n' 'o'";
    330  1.1  christos export _MAN_AUTO_SEC_CHARS;
    331  1.1  christos _MAN_AUTO_SEC_CHARS='[123456789no]';
    332  1.1  christos 
    333  1.1  christos export _SPACE_SED;
    334  1.1  christos _SPACE_SED='['"${_SP}${_TAB}"']';
    335  1.1  christos 
    336  1.1  christos export _SPACE_CASE;
    337  1.1  christos _SPACE_CASE='[\'"${_SP}"'\'"${_TAB}"']';
    338  1.1  christos 
    339  1.1  christos export _PROCESS_ID;		# for shutting down the program
    340  1.1  christos _PROCESS_ID="$$";
    341  1.1  christos 
    342  1.1  christos 
    343  1.1  christos ############ the command line options of the involved programs
    344  1.1  christos #
    345  1.1  christos # The naming scheme for the options environment names is
    346  1.1  christos # $_OPTS_<prog>_<length>[_<argspec>]
    347  1.1  christos #
    348  1.1  christos # <prog>:    program name GROFFER, GROFF, or CMDLINE (for all
    349  1.1  christos #            command line options)
    350  1.1  christos # <length>:  LONG (long options) or SHORT (single character options)
    351  1.1  christos # <argspec>: ARG for options with argument, NA for no argument;
    352  1.1  christos #            without _<argspec> both the ones with and without arg.
    353  1.1  christos #
    354  1.1  christos # Each option that takes an argument must be specified with a
    355  1.1  christos # trailing : (colon).
    356  1.1  christos 
    357  1.1  christos # exports
    358  1.1  christos export _OPTS_GROFFER_SHORT_NA;
    359  1.1  christos export _OPTS_GROFFER_SHORT_ARG;
    360  1.1  christos export _OPTS_GROFFER_LONG_NA;
    361  1.1  christos export _OPTS_GROFFER_LONG_ARG;
    362  1.1  christos export _OPTS_GROFF_SHORT_NA;
    363  1.1  christos export _OPTS_GROFF_SHORT_ARG;
    364  1.1  christos export _OPTS_GROFF_LONG_NA;
    365  1.1  christos export _OPTS_GROFF_LONG_ARG;
    366  1.1  christos export _OPTS_X_SHORT_ARG;
    367  1.1  christos export _OPTS_X_SHORT_NA;
    368  1.1  christos export _OPTS_X_LONG_ARG;
    369  1.1  christos export _OPTS_X_LONG_NA;
    370  1.1  christos export _OPTS_MAN_SHORT_ARG;
    371  1.1  christos export _OPTS_MAN_SHORT_NA;
    372  1.1  christos export _OPTS_MAN_LONG_ARG;
    373  1.1  christos export _OPTS_MAN_LONG_NA;
    374  1.1  christos export _OPTS_MANOPT_SHORT_ARG;
    375  1.1  christos export _OPTS_MANOPT_SHORT_NA;
    376  1.1  christos export _OPTS_MANOPT_LONG_ARG;
    377  1.1  christos export _OPTS_MANOPT_LONG_NA;
    378  1.1  christos export _OPTS_CMDLINE_SHORT_NA;
    379  1.1  christos export _OPTS_CMDLINE_SHORT_ARG;
    380  1.1  christos export _OPTS_CMDLINE_LONG_NA;
    381  1.1  christos export _OPTS_CMDLINE_LONG_ARG;
    382  1.1  christos 
    383  1.1  christos ###### groffer native options
    384  1.1  christos 
    385  1.1  christos _OPTS_GROFFER_SHORT_NA="'h' 'Q' 'v' 'V' 'X' 'Z'";
    386  1.1  christos _OPTS_GROFFER_SHORT_ARG="'T'";
    387  1.1  christos 
    388  1.1  christos _OPTS_GROFFER_LONG_NA="'auto' \
    389  1.1  christos 'apropos' 'apropos-data' 'apropos-devel' 'apropos-progs' \
    390  1.1  christos 'debug' 'debug-all' 'debug-keep' 'debug-lm' 'debug-params' 'debug-shell' \
    391  1.1  christos 'debug-stacks' 'debug-tmpdir' 'debug-user' 'default' 'do-nothing' 'dvi' \
    392  1.1  christos 'groff' 'help' 'intermediate-output' 'html' 'man' \
    393  1.1  christos 'no-location' 'no-man' 'no-special' 'pdf' 'ps' 'rv' 'source' \
    394  1.1  christos 'text' 'text-device' \
    395  1.1  christos 'tty' 'tty-device' 'version' 'whatis' 'where' 'www' 'x' 'X'";
    396  1.1  christos 
    397  1.1  christos _OPTS_GROFFER_LONG_ARG="\
    398  1.1  christos 'default-modes' 'device' 'dvi-viewer' 'dvi-viewer-tty' 'extension' 'fg' \
    399  1.1  christos 'fn' 'font' 'foreground' 'html-viewer' 'html-viewer-tty' 'mode' \
    400  1.1  christos 'pdf-viewer' 'pdf-viewer-tty' 'print' 'ps-viewer' 'ps-viewer-tty' 'shell' \
    401  1.1  christos 'title' 'tty-viewer' 'tty-viewer-tty' 'www-viewer' 'www-viewer-tty' \
    402  1.1  christos 'x-viewer' 'x-viewer-tty' 'X-viewer' 'X-viewer-tty'";
    403  1.1  christos 
    404  1.1  christos ##### groffer options inhereted from groff
    405  1.1  christos 
    406  1.1  christos _OPTS_GROFF_SHORT_NA="'a' 'b' 'c' 'C' 'e' 'E' 'g' 'G' 'i' 'l' 'N' 'p' \
    407  1.1  christos 'R' 's' 'S' 't' 'U' 'z'";
    408  1.1  christos _OPTS_GROFF_SHORT_ARG="'d' 'f' 'F' 'I' 'L' 'm' 'M' 'n' 'o' 'P' 'r' \
    409  1.1  christos 'w' 'W'";
    410  1.1  christos _OPTS_GROFF_LONG_NA="";
    411  1.1  christos _OPTS_GROFF_LONG_ARG="";
    412  1.1  christos 
    413  1.1  christos ##### groffer options inhereted from the X Window toolkit
    414  1.1  christos 
    415  1.1  christos _OPTS_X_SHORT_NA="";
    416  1.1  christos _OPTS_X_SHORT_ARG="";
    417  1.1  christos 
    418  1.1  christos _OPTS_X_LONG_NA="'iconic' 'rv'";
    419  1.1  christos 
    420  1.1  christos _OPTS_X_LONG_ARG="'background' 'bd' 'bg' 'bordercolor' 'borderwidth' \
    421  1.1  christos 'bw' 'display' 'fg' 'fn' 'font' 'foreground' 'ft' 'geometry' \
    422  1.1  christos 'resolution' 'title' 'xrm'";
    423  1.1  christos 
    424  1.1  christos ###### groffer options inherited from man
    425  1.1  christos 
    426  1.1  christos _OPTS_MAN_SHORT_NA="";
    427  1.1  christos _OPTS_MAN_SHORT_ARG="";
    428  1.1  christos 
    429  1.1  christos _OPTS_MAN_LONG_NA="'all' 'ascii' 'catman' 'ditroff' \
    430  1.1  christos 'local-file' 'location' 'troff' 'update'";
    431  1.1  christos 
    432  1.1  christos _OPTS_MAN_LONG_ARG="'locale' 'manpath' \
    433  1.1  christos 'pager' 'preprocessor' 'prompt' 'sections' 'systems' 'troff-device'";
    434  1.1  christos 
    435  1.1  christos ###### additional options for parsing $MANOPT only
    436  1.1  christos 
    437  1.1  christos _OPTS_MANOPT_SHORT_NA="'7' 'a' 'c' 'd' 'D' 'f' 'h' 'k' 'l' 't' 'u' \
    438  1.1  christos 'V' 'w' 'Z'";
    439  1.1  christos _OPTS_MANOPT_SHORT_ARG="'e' 'L' 'm' 'M' 'p' 'P' 'r' 'S' 'T'";
    440  1.1  christos 
    441  1.1  christos _OPTS_MANOPT_LONG_NA="${_OPTS_MAN_LONG_NA} \
    442  1.1  christos 'apropos' 'debug' 'default' 'help' 'html' 'ignore-case' 'location-cat' \
    443  1.1  christos 'match-case' 'troff' 'update' 'version' 'whatis' 'where' 'where-cat'";
    444  1.1  christos 
    445  1.1  christos _OPTS_MANOPT_LONG_ARG="${_OPTS_MAN_LONG_NA} \
    446  1.1  christos 'config_file' 'encoding' 'extension' 'locale'";
    447  1.1  christos 
    448  1.1  christos ###### collections of command line options
    449  1.1  christos 
    450  1.1  christos _OPTS_CMDLINE_SHORT_NA="${_OPTS_GROFFER_SHORT_NA} \
    451  1.1  christos ${_OPTS_GROFF_SHORT_NA} ${_OPTS_X_SHORT_NA} ${_OPTS_MAN_SHORT_NA}";
    452  1.1  christos _OPTS_CMDLINE_SHORT_ARG="${_OPTS_GROFFER_SHORT_ARG} \
    453  1.1  christos ${_OPTS_GROFF_SHORT_ARG} ${_OPTS_X_SHORT_ARG} ${_OPTS_MAN_SHORT_ARG}";
    454  1.1  christos 
    455  1.1  christos _OPTS_CMDLINE_LONG_NA="${_OPTS_GROFFER_LONG_NA} \
    456  1.1  christos ${_OPTS_GROFF_LONG_NA} ${_OPTS_X_LONG_NA} ${_OPTS_MAN_LONG_NA}";
    457  1.1  christos _OPTS_CMDLINE_LONG_ARG="${_OPTS_GROFFER_LONG_ARG} \
    458  1.1  christos ${_OPTS_GROFF_LONG_ARG} ${_OPTS_MAN_LONG_ARG} ${_OPTS_X_LONG_ARG}";
    459  1.1  christos 
    460  1.1  christos 
    461  1.1  christos ########################################################################
    462  1.1  christos # read-write variables (global to this file)
    463  1.1  christos ########################################################################
    464  1.1  christos 
    465  1.1  christos export _ALL_PARAMS;		# All options and file name parameters
    466  1.1  christos export _ADDOPTS_GROFF;		# Transp. options for groff (`eval').
    467  1.1  christos export _ADDOPTS_POST;		# Transp. options postproc (`eval').
    468  1.1  christos export _ADDOPTS_X;		# Transp. options X postproc (`eval').
    469  1.1  christos export _APROPOS_PROG;		# Program to run apropos.
    470  1.1  christos export _APROPOS_SECTIONS;	# Sections for different --apropos-*.
    471  1.1  christos export _DEFAULT_MODES;		# Set default modes.
    472  1.1  christos export _DISPLAY_MODE;		# Display mode.
    473  1.1  christos export _DISPLAY_PROG;		# Viewer program to be used for display.
    474  1.1  christos export _DISPLAY_ARGS;		# X resources for the viewer program.
    475  1.1  christos export _FILEARGS;		# Stores filespec parameters.
    476  1.1  christos export _FILESPEC_ARG;		# Stores the actual filespec parameter.
    477  1.1  christos export _FUNC_STACK;		# Store debugging information.
    478  1.1  christos export _REGISTERED_TITLE;	# Processed file names.
    479  1.1  christos # _HAS_* from availability tests
    480  1.1  christos export _HAS_COMPRESSION;	# `yes' if gzip compression is available
    481  1.1  christos export _HAS_BZIP;		# `yes' if bzip2 compression is available
    482  1.1  christos # _MAN_* finally used configuration of man searching
    483  1.1  christos export _MAN_ALL;		# search all man pages per filespec
    484  1.1  christos export _MAN_ENABLE;		# enable search for man pages
    485  1.1  christos export _MAN_EXT;		# extension for man pages
    486  1.1  christos export _MAN_FORCE;		# force file parameter to be man pages
    487  1.1  christos export _MAN_IS_SETUP;		# setup man variables only once
    488  1.1  christos export _MAN_LANG;		# language for man pages
    489  1.1  christos export _MAN_LANG2;		# language for man pages
    490  1.1  christos export _MAN_LANG_DONE;		# language dirs added to man path
    491  1.1  christos export _MAN_PATH;		# search path for man pages
    492  1.1  christos export _MAN_SEC;		# sections for man pages; sep. `:'
    493  1.1  christos export _MAN_SEC_DONE;		# sections added to man path
    494  1.1  christos export _MAN_SYS;		# system names for man pages; sep. `,'
    495  1.1  christos export _MAN_SYS;		# system names added to man path
    496  1.1  christos # _MANOPT_* as parsed from $MANOPT
    497  1.1  christos export _MANOPT_ALL;		# $MANOPT --all
    498  1.1  christos export _MANOPT_EXTENSION;	# $MANOPT --extension
    499  1.1  christos export _MANOPT_LANG;		# $MANOPT --locale
    500  1.1  christos export _MANOPT_PATH;		# $MANOPT --manpath
    501  1.1  christos export _MANOPT_PAGER;		# $MANOPT --pager
    502  1.1  christos export _MANOPT_SEC;		# $MANOPT --sections
    503  1.1  christos export _MANOPT_SYS;		# $MANOPT --systems
    504  1.1  christos # _OPT_* as parsed from groffer command line
    505  1.1  christos export _OPT_ALL;		# display all suitable man pages.
    506  1.1  christos export _OPT_APROPOS;		# call `apropos' program.
    507  1.1  christos export _OPT_BD;			# set border color in some modes.
    508  1.1  christos export _OPT_BG;			# set background color in some modes.
    509  1.1  christos export _OPT_BW;			# set border width in some modes.
    510  1.1  christos export _OPT_DEFAULT_MODES;	# `,'-list of modes when no mode given.
    511  1.1  christos export _OPT_DEVICE;		# device option.
    512  1.1  christos export _OPT_DO_NOTHING;		# do nothing in main_display().
    513  1.1  christos export _OPT_DISPLAY;		# set X display.
    514  1.1  christos export _OPT_FG;			# set foreground color in some modes.
    515  1.1  christos export _OPT_FN;			# set font in some modes.
    516  1.1  christos export _OPT_GEOMETRY;		# set size and position of viewer in X.
    517  1.1  christos export _OPT_ICONIC;		# -iconic option for X viewers.
    518  1.1  christos export _OPT_LANG;		# set language for man pages
    519  1.1  christos export _OPT_LOCATION;		# print processed file names to stderr
    520  1.1  christos export _OPT_MODE;		# values: X, tty, Q, Z, ""
    521  1.1  christos export _OPT_MANPATH;		# manual setting of path for man-pages
    522  1.1  christos export _OPT_PAGER;		# specify paging program for tty mode
    523  1.1  christos export _OPT_RESOLUTION;		# set X resolution in dpi
    524  1.1  christos export _OPT_RV;			# reverse fore- and background colors.
    525  1.1  christos export _OPT_SECTIONS;		# sections for man page search
    526  1.1  christos export _OPT_SYSTEMS;		# man pages of different OS's
    527  1.1  christos export _OPT_TITLE;		# title for gxditview window
    528  1.1  christos export _OPT_TEXT_DEVICE;	# set device for tty mode.
    529  1.1  christos export _OPT_V;			# groff option -V.
    530  1.1  christos export _OPT_VIEWER_DVI;		# viewer program for dvi mode
    531  1.1  christos export _OPT_VIEWER_PDF;		# viewer program for pdf mode
    532  1.1  christos export _OPT_VIEWER_PS;		# viewer program for ps mode
    533  1.1  christos export _OPT_VIEWER_HTML;	# viewer program for html mode
    534  1.1  christos export _OPT_VIEWER_X;		# viewer program for x mode
    535  1.1  christos export _OPT_WHATIS;		# print the man description
    536  1.1  christos export _OPT_XRM;		# specify X resource.
    537  1.1  christos export _OPT_Z;			# groff option -Z.
    538  1.1  christos export _OUTPUT_FILE_NAME;	# output generated, see main_set_res..()
    539  1.1  christos export _VIEWER_TERMINAL;	# viewer options for terminal (--*-viewer-tty)
    540  1.1  christos # _TMP_* temporary directory and files
    541  1.1  christos export _TMP_DIR;		# groffer directory for temporary files
    542  1.1  christos export _TMP_CAT;		# stores concatenation of everything
    543  1.1  christos export _TMP_STDIN;		# stores stdin, if any
    544  1.1  christos 
    545  1.1  christos # these variables are preset in section `Preset' after the rudim. test
    546  1.1  christos 
    547  1.1  christos 
    548  1.1  christos ########################################################################
    549  1.1  christos # Preset and reset of read-write global variables
    550  1.1  christos ########################################################################
    551  1.1  christos 
    552  1.1  christos 
    553  1.1  christos export _START_DIR;		# directory at start time of the script
    554  1.1  christos _START_DIR="$(pwd)";
    555  1.1  christos 
    556  1.1  christos # For variables that can be reset by option `--default', see reset().
    557  1.1  christos 
    558  1.1  christos _FILEARGS='';
    559  1.1  christos 
    560  1.1  christos # _HAS_* from availability tests
    561  1.1  christos _HAS_COMPRESSION='';
    562  1.1  christos _HAS_BZIP='';
    563  1.1  christos 
    564  1.1  christos # _TMP_* temporary files
    565  1.1  christos _TMP_DIR='';
    566  1.1  christos _TMP_CAT='';
    567  1.1  christos _TMP_CONF='';
    568  1.1  christos _TMP_STDIN='';
    569  1.1  christos 
    570  1.1  christos 
    571  1.1  christos ########################################################################
    572  1.1  christos # reset ()
    573  1.1  christos #
    574  1.1  christos # Reset the variables that can be affected by options to their default.
    575  1.1  christos #
    576  1.1  christos reset()
    577  1.1  christos {
    578  1.1  christos   if test "$#" -ne 0
    579  1.1  christos   then
    580  1.1  christos     error "reset() does not have arguments.";
    581  1.1  christos   fi;
    582  1.1  christos 
    583  1.1  christos   _ADDOPTS_GROFF='';
    584  1.1  christos   _ADDOPTS_POST='';
    585  1.1  christos   _ADDOPTS_X='';
    586  1.1  christos   _APROPOS_PROG='';
    587  1.1  christos   _APROPOS_SECTIONS='';
    588  1.1  christos   _DISPLAY_ARGS='';
    589  1.1  christos   _DISPLAY_MODE='';
    590  1.1  christos   _DISPLAY_PROG='';
    591  1.1  christos   _REGISTERED_TITLE='';
    592  1.1  christos 
    593  1.1  christos   # _MAN_* finally used configuration of man searching
    594  1.1  christos   _MAN_ALL='no';
    595  1.1  christos   _MAN_ENABLE='yes';		# do search for man-pages
    596  1.1  christos   _MAN_EXT='';
    597  1.1  christos   _MAN_FORCE='no';		# first local file, then search man page
    598  1.1  christos   _MAN_IS_SETUP='no';
    599  1.1  christos   _MAN_LANG='';
    600  1.1  christos   _MAN_LANG2='';
    601  1.1  christos   _MAN_PATH='';
    602  1.1  christos   _MAN_SEC='';
    603  1.1  christos   _MAN_SEC_DONE='no';
    604  1.1  christos   _MAN_SYS='';
    605  1.1  christos   _MAN_SYS_DONE='no';
    606  1.1  christos 
    607  1.1  christos   # _MANOPT_* as parsed from $MANOPT
    608  1.1  christos   _MANOPT_ALL='no';
    609  1.1  christos   _MANOPT_EXTENSION='';
    610  1.1  christos   _MANOPT_LANG='';
    611  1.1  christos   _MANOPT_PATH='';
    612  1.1  christos   _MANOPT_PAGER='';
    613  1.1  christos   _MANOPT_SEC='';
    614  1.1  christos   _MANOPT_SYS='';
    615  1.1  christos 
    616  1.1  christos   # _OPT_* as parsed from groffer command line
    617  1.1  christos   _OPT_ALL='no';
    618  1.1  christos   _OPT_APROPOS='no';
    619  1.1  christos   _OPT_BD='';
    620  1.1  christos   _OPT_BG='';
    621  1.1  christos   _OPT_BW='';
    622  1.1  christos   _OPT_DEFAULT_MODES='';
    623  1.1  christos   _OPT_DEVICE='';
    624  1.1  christos   _OPT_DISPLAY='';
    625  1.1  christos   _OPT_DO_NOTHING='no';
    626  1.1  christos   _OPT_FG='';
    627  1.1  christos   _OPT_FN='';
    628  1.1  christos   _OPT_GEOMETRY='';
    629  1.1  christos   _OPT_ICONIC='no';
    630  1.1  christos   _OPT_LANG='';
    631  1.1  christos   _OPT_LOCATION='no';
    632  1.1  christos   _OPT_MODE='';
    633  1.1  christos   _OPT_MANPATH='';
    634  1.1  christos   _OPT_PAGER='';
    635  1.1  christos   _OPT_RESOLUTION='';
    636  1.1  christos   _OPT_RV='no';
    637  1.1  christos   _OPT_SECTIONS='';
    638  1.1  christos   _OPT_SYSTEMS='';
    639  1.1  christos   _OPT_TITLE='';
    640  1.1  christos   _OPT_TEXT_DEVICE='';
    641  1.1  christos   _OPT_V='no';
    642  1.1  christos   _OPT_VIEWER_DVI='';
    643  1.1  christos   _OPT_VIEWER_PDF='';
    644  1.1  christos   _OPT_VIEWER_PS='';
    645  1.1  christos   _OPT_VIEWER_HTML='';
    646  1.1  christos   _OPT_VIEWER_X='';
    647  1.1  christos   _OPT_WHATIS='no';
    648  1.1  christos   _OPT_XRM='';
    649  1.1  christos   _OPT_Z='no';
    650  1.1  christos   _VIEWER_TERMINAL='no';
    651  1.1  christos }
    652  1.1  christos 
    653  1.1  christos reset;
    654  1.1  christos 
    655  1.1  christos 
    656  1.1  christos ########################################################################
    657  1.1  christos #          Functions for error handling and debugging
    658  1.1  christos ########################################################################
    659  1.1  christos 
    660  1.1  christos 
    661  1.1  christos ##############
    662  1.1  christos # echo1 (<text>*)
    663  1.1  christos #
    664  1.1  christos # Output to stdout.
    665  1.1  christos #
    666  1.1  christos # Arguments : arbitrary text including `-'.
    667  1.1  christos #
    668  1.1  christos echo1()
    669  1.1  christos {
    670  1.1  christos   cat <<EOF
    671  1.1  christos $@
    672  1.1  christos EOF
    673  1.1  christos }
    674  1.1  christos 
    675  1.1  christos 
    676  1.1  christos ##############
    677  1.1  christos # echo2 (<text>*)
    678  1.1  christos #
    679  1.1  christos # Output to stderr.
    680  1.1  christos #
    681  1.1  christos # Arguments : arbitrary text.
    682  1.1  christos #
    683  1.1  christos echo2()
    684  1.1  christos {
    685  1.1  christos   cat >&2 <<EOF
    686  1.1  christos $@
    687  1.1  christos EOF
    688  1.1  christos }
    689  1.1  christos 
    690  1.1  christos 
    691  1.1  christos ##############
    692  1.1  christos # landmark (<text>)
    693  1.1  christos #
    694  1.1  christos # Print <text> to standard error as a debugging aid.
    695  1.1  christos #
    696  1.1  christos # Globals: $_DEBUG_LM
    697  1.1  christos #
    698  1.1  christos landmark()
    699  1.1  christos {
    700  1.1  christos   if test _"${_DEBUG_LM}"_ = _yes_
    701  1.1  christos   then
    702  1.1  christos     echo2 "LM: $*";
    703  1.1  christos   fi;
    704  1.1  christos }
    705  1.1  christos 
    706  1.1  christos landmark "1: debugging functions";
    707  1.1  christos 
    708  1.1  christos 
    709  1.1  christos ##############
    710  1.1  christos # clean_up ()
    711  1.1  christos #
    712  1.1  christos # Clean up at exit.
    713  1.1  christos #
    714  1.1  christos clean_up()
    715  1.1  christos {
    716  1.1  christos   cd "${_START_DIR}" >"${_NULL_DEV}" 2>&1;
    717  1.1  christos   if test _${_DEBUG_KEEP_FILES}_ = _yes_
    718  1.1  christos   then
    719  1.1  christos     echo2 "Kept temporary directory ${_TMP_DIR}."
    720  1.1  christos   else
    721  1.1  christos     if test _"${_TMP_DIR}"_ != __
    722  1.1  christos     then
    723  1.1  christos       if test -d "${_TMP_DIR}" || test -f "${_TMP_DIR}"
    724  1.1  christos       then
    725  1.1  christos         rm -f -r "${_TMP_DIR}" >${_NULL_DEV} 2>&1;
    726  1.1  christos       fi; 
    727  1.1  christos     fi;
    728  1.1  christos   fi;
    729  1.1  christos }
    730  1.1  christos 
    731  1.1  christos 
    732  1.1  christos #############
    733  1.1  christos # diag (text>*)
    734  1.1  christos #
    735  1.1  christos # Output a diagnostic message to stderr
    736  1.1  christos #
    737  1.1  christos diag()
    738  1.1  christos {
    739  1.1  christos   echo2 '>>>>>'"$*";
    740  1.1  christos }
    741  1.1  christos 
    742  1.1  christos 
    743  1.1  christos #############
    744  1.1  christos # error (<text>*)
    745  1.1  christos #
    746  1.1  christos # Print an error message to standard error, print the function stack,
    747  1.1  christos # exit with an error condition.  The argument should contain the name
    748  1.1  christos # of the function from which it was called.  This is for system errors.
    749  1.1  christos #
    750  1.1  christos error()
    751  1.1  christos {
    752  1.1  christos   case "$#" in
    753  1.1  christos     1) echo2 'groffer error: '"$1"; ;;
    754  1.1  christos     *) echo2 'groffer error: wrong number of arguments in error().'; ;;
    755  1.1  christos   esac;
    756  1.1  christos   func_stack_dump;
    757  1.1  christos   if test _"${_TMP_DIR}"_ != __ && test -d "${_TMP_DIR}"
    758  1.1  christos   then
    759  1.1  christos     : >"${_TMP_DIR}"/,error;
    760  1.1  christos   fi;
    761  1.1  christos   exit "${_ERROR}";
    762  1.1  christos }
    763  1.1  christos 
    764  1.1  christos 
    765  1.1  christos #############
    766  1.1  christos # error_user (<text>*)
    767  1.1  christos #
    768  1.1  christos # Print an error message to standard error; exit with an error condition.
    769  1.1  christos # The error is supposed to be produce by the user.  So the funtion stack
    770  1.1  christos # is omitted.
    771  1.1  christos #
    772  1.1  christos error_user()
    773  1.1  christos {
    774  1.1  christos   case "$#" in
    775  1.1  christos     1)
    776  1.1  christos       echo2 'groffer error: '"$1";
    777  1.1  christos        ;;
    778  1.1  christos     *)
    779  1.1  christos       echo2 'groffer error: wrong number of arguments in error_user().';
    780  1.1  christos       ;;
    781  1.1  christos   esac;
    782  1.1  christos   if test _"${_DEBUG_USER_WITH_STACK}"_ = _yes_
    783  1.1  christos   then
    784  1.1  christos     func_stack_dump;
    785  1.1  christos   fi;
    786  1.1  christos   if test _"${_TMP_DIR}"_ != __ && test -d "${_TMP_DIR}"
    787  1.1  christos   then
    788  1.1  christos     : >"${_TMP_DIR}"/,error;
    789  1.1  christos   fi;
    790  1.1  christos   exit "${_ERROR}";
    791  1.1  christos }
    792  1.1  christos 
    793  1.1  christos 
    794  1.1  christos #############
    795  1.1  christos # exit_test ()
    796  1.1  christos #
    797  1.1  christos # Test whether the former command ended with error().  Exit again.
    798  1.1  christos #
    799  1.1  christos # Globals: $_ERROR
    800  1.1  christos #
    801  1.1  christos exit_test()
    802  1.1  christos {
    803  1.1  christos   if test "$?" = "${_ERROR}"
    804  1.1  christos   then
    805  1.1  christos     exit ${_ERROR};
    806  1.1  christos   fi;
    807  1.1  christos   if test _"${_TMP_DIR}"_ != __ && test -f "${_TMP_DIR}"/,error
    808  1.1  christos   then
    809  1.1  christos     exit ${_ERROR};
    810  1.1  christos   fi;
    811  1.1  christos }
    812  1.1  christos 
    813  1.1  christos 
    814  1.1  christos #############
    815  1.1  christos # func_check (<func_name> <rel_op> <nr_args> "$@")
    816  1.1  christos #
    817  1.1  christos # Check number of arguments and register to _FUNC_STACK.
    818  1.1  christos #
    819  1.1  christos # Arguments: >=3
    820  1.1  christos #   <func_name>: name of the calling function.
    821  1.1  christos #   <rel_op>:    a relational operator: = != < > <= >=
    822  1.1  christos #   <nr_args>:   number of arguments to be checked against <operator>
    823  1.1  christos #   "$@":        the arguments of the calling function.
    824  1.1  christos #
    825  1.1  christos # Variable prefix: fc
    826  1.1  christos #
    827  1.1  christos func_check()
    828  1.1  christos {
    829  1.1  christos   if test "$#" -lt 3
    830  1.1  christos   then
    831  1.1  christos     error 'func_check() needs at least 3 arguments.';
    832  1.1  christos   fi;
    833  1.1  christos   fc_fname="$1";
    834  1.1  christos   case "$3" in
    835  1.1  christos     1)
    836  1.1  christos       fc_nargs="$3";
    837  1.1  christos       fc_s='';
    838  1.1  christos       ;;
    839  1.1  christos     0|[2-9])
    840  1.1  christos       fc_nargs="$3";
    841  1.1  christos       fc_s='s';
    842  1.1  christos       ;;
    843  1.1  christos     *)
    844  1.1  christos       error "func_check(): third argument must be a digit.";
    845  1.1  christos       ;;
    846  1.1  christos   esac;
    847  1.1  christos   case "$2" in
    848  1.1  christos     '='|'-eq')
    849  1.1  christos       fc_op='-eq';
    850  1.1  christos       fc_comp='exactly';
    851  1.1  christos       ;;
    852  1.1  christos     '>='|'-ge')
    853  1.1  christos       fc_op='-ge';
    854  1.1  christos       fc_comp='at least';
    855  1.1  christos       ;;
    856  1.1  christos     '<='|'-le')
    857  1.1  christos       fc_op='-le';
    858  1.1  christos       fc_comp='at most';
    859  1.1  christos       ;;
    860  1.1  christos     '<'|'-lt')
    861  1.1  christos       fc_op='-lt';
    862  1.1  christos       fc_comp='less than';
    863  1.1  christos       ;;
    864  1.1  christos     '>'|'-gt')
    865  1.1  christos       fc_op='-gt';
    866  1.1  christos       fc_comp='more than';
    867  1.1  christos       ;;
    868  1.1  christos     '!='|'-ne')
    869  1.1  christos       fc_op='-ne';
    870  1.1  christos       fc_comp='not';
    871  1.1  christos       ;;
    872  1.1  christos     *)
    873  1.1  christos       error \
    874  1.1  christos         'func_check(): second argument is not a relational operator.';
    875  1.1  christos       ;;
    876  1.1  christos   esac;
    877  1.1  christos   shift;
    878  1.1  christos   shift;
    879  1.1  christos   shift;
    880  1.1  christos   if test "$#" "${fc_op}" "${fc_nargs}"
    881  1.1  christos   then
    882  1.1  christos     do_nothing;
    883  1.1  christos   else
    884  1.1  christos     error "func_check(): \
    885  1.1  christos ${fc_fname}"'() needs '"${fc_comp} ${fc_nargs}"' argument'"${fc_s}"'.';
    886  1.1  christos   fi;
    887  1.1  christos   func_push "${fc_fname}";
    888  1.1  christos   if test _"${_DEBUG_STACKS}"_ = _yes_
    889  1.1  christos   then
    890  1.1  christos     echo2 '+++ '"${fc_fname} $@";
    891  1.1  christos     echo2 '>>> '"${_FUNC_STACK}";
    892  1.1  christos   fi;
    893  1.1  christos   eval ${_UNSET} fc_comp;
    894  1.1  christos   eval ${_UNSET} fc_fname;
    895  1.1  christos   eval ${_UNSET} fc_nargs;
    896  1.1  christos   eval ${_UNSET} fc_op;
    897  1.1  christos   eval ${_UNSET} fc_s;
    898  1.1  christos }
    899  1.1  christos 
    900  1.1  christos 
    901  1.1  christos #############
    902  1.1  christos # func_pop ()
    903  1.1  christos #
    904  1.1  christos # Retrieve the top element from the stack.
    905  1.1  christos #
    906  1.1  christos # The stack elements are separated by `!'; the popped element is
    907  1.1  christos # identical to the original element, except that all `!' characters
    908  1.1  christos # were removed.
    909  1.1  christos #
    910  1.1  christos # Arguments: 1
    911  1.1  christos #
    912  1.1  christos func_pop()
    913  1.1  christos {
    914  1.1  christos   if test "$#" -ne 0
    915  1.1  christos   then
    916  1.1  christos     error 'func_pop() does not have arguments.';
    917  1.1  christos   fi;
    918  1.1  christos   case "${_FUNC_STACK}" in
    919  1.1  christos   '')
    920  1.1  christos     if test _"${_DEBUG_STACKS}"_ = _yes_
    921  1.1  christos     then
    922  1.1  christos       error 'func_pop(): stack is empty.';
    923  1.1  christos     fi;
    924  1.1  christos     ;;
    925  1.1  christos   *!*)
    926  1.1  christos     # split at first bang `!'.
    927  1.1  christos     _FUNC_STACK="$(echo1 "${_FUNC_STACK}" | sed -e 's/^[^!]*!//')";
    928  1.1  christos     exit_test;
    929  1.1  christos     ;;
    930  1.1  christos   *)
    931  1.1  christos     _FUNC_STACK='';
    932  1.1  christos     ;;
    933  1.1  christos   esac;
    934  1.1  christos   if test _"${_DEBUG_STACKS}"_ = _yes_
    935  1.1  christos   then
    936  1.1  christos     echo2 '<<< '"${_FUNC_STACK}";
    937  1.1  christos   fi;
    938  1.1  christos }
    939  1.1  christos 
    940  1.1  christos 
    941  1.1  christos #############
    942  1.1  christos # func_push (<element>)
    943  1.1  christos #
    944  1.1  christos # Store another element to stack.
    945  1.1  christos #
    946  1.1  christos # The stack elements are separated by `!'; if <element> contains a `!'
    947  1.1  christos # it is removed first.
    948  1.1  christos #
    949  1.1  christos # Arguments: 1
    950  1.1  christos #
    951  1.1  christos # Variable prefix: fp
    952  1.1  christos #
    953  1.1  christos func_push()
    954  1.1  christos {
    955  1.1  christos   if test "$#" -ne 1
    956  1.1  christos   then
    957  1.1  christos     error 'func_push() needs 1 argument.';
    958  1.1  christos   fi;
    959  1.1  christos   case "$1" in
    960  1.1  christos   *'!'*)
    961  1.1  christos     # remove all bangs `!'.
    962  1.1  christos     fp_element="$(echo1 "$1" | sed -e 's/!//g')";
    963  1.1  christos     exit_test;
    964  1.1  christos     ;;
    965  1.1  christos   *)
    966  1.1  christos     fp_element="$1";
    967  1.1  christos     ;;
    968  1.1  christos   esac;
    969  1.1  christos   if test _"${_FUNC_STACK}"_ = __
    970  1.1  christos   then
    971  1.1  christos     _FUNC_STACK="${fp_element}";
    972  1.1  christos   else
    973  1.1  christos     _FUNC_STACK="${fp_element}!${_FUNC_STACK}";
    974  1.1  christos   fi;
    975  1.1  christos   eval ${_UNSET} fp_element;
    976  1.1  christos }
    977  1.1  christos 
    978  1.1  christos 
    979  1.1  christos #############
    980  1.1  christos # func_stack_dump ()
    981  1.1  christos #
    982  1.1  christos # Print the content of the stack.  Ignore the arguments.
    983  1.1  christos #
    984  1.1  christos func_stack_dump()
    985  1.1  christos {
    986  1.1  christos   diag 'call stack: '"${_FUNC_STACK}";
    987  1.1  christos }
    988  1.1  christos 
    989  1.1  christos 
    990  1.1  christos ########################################################################
    991  1.1  christos #                        System Test
    992  1.1  christos ########################################################################
    993  1.1  christos 
    994  1.1  christos landmark "2: system test";
    995  1.1  christos 
    996  1.1  christos # Test the availability of the system utilities used in this script.
    997  1.1  christos 
    998  1.1  christos 
    999  1.1  christos ########################################################################
   1000  1.1  christos # Test of function `sed'.
   1001  1.1  christos #
   1002  1.1  christos 
   1003  1.1  christos if test _"$(echo xTesTx \
   1004  1.1  christos            | sed -e 's/^.\([Tt]e*x*sTT*\).*$/\1/' \
   1005  1.1  christos            | sed -e 's|T|t|g')"_ != _test_
   1006  1.1  christos then
   1007  1.1  christos   error 'Test of "sed" command failed.';
   1008  1.1  christos fi;
   1009  1.1  christos 
   1010  1.1  christos 
   1011  1.1  christos ########################################################################
   1012  1.1  christos # Test of function `cat'.
   1013  1.1  christos #
   1014  1.1  christos if test _"$(echo test | cat)"_ != _test_
   1015  1.1  christos then
   1016  1.1  christos   error 'Test of "cat" command failed.';
   1017  1.1  christos fi;
   1018  1.1  christos 
   1019  1.1  christos 
   1020  1.1  christos ########################################################################
   1021  1.1  christos # Test for compression.
   1022  1.1  christos #
   1023  1.1  christos if test _"$(echo 'test' | gzip -c -d -f - 2>${_NULL_DEV})"_ = _test_
   1024  1.1  christos then
   1025  1.1  christos   _HAS_COMPRESSION='yes';
   1026  1.1  christos   if echo1 'test' | bzip2 -c 2>${_NULL_DEV} | bzip2 -t 2>${_NULL_DEV} \
   1027  1.1  christos      && test _"$(echo 'test' | bzip2 -c 2>${_NULL_DEV} \
   1028  1.1  christos                              | bzip2 -d -c 2>${_NULL_DEV})"_ \
   1029  1.1  christos              = _test_
   1030  1.1  christos   then
   1031  1.1  christos     _HAS_BZIP='yes';
   1032  1.1  christos   else
   1033  1.1  christos     _HAS_BZIP='no';
   1034  1.1  christos   fi;
   1035  1.1  christos else
   1036  1.1  christos   _HAS_COMPRESSION='no';
   1037  1.1  christos   _HAS_BZIP='no';
   1038  1.1  christos fi;
   1039  1.1  christos 
   1040  1.1  christos 
   1041  1.1  christos ########################################################################
   1042  1.1  christos #       Definition of normal Functions in alphabetical order
   1043  1.1  christos ########################################################################
   1044  1.1  christos landmark "3: functions";
   1045  1.1  christos 
   1046  1.1  christos ########################################################################
   1047  1.1  christos # apropos_filespec ()
   1048  1.1  christos #
   1049  1.1  christos # Setup for the --apropos* options
   1050  1.1  christos #
   1051  1.1  christos apropos_filespec()
   1052  1.1  christos {
   1053  1.1  christos 
   1054  1.1  christos   func_check apropos_filespec '=' 0 "$@";
   1055  1.1  christos   if obj _OPT_APROPOS is_yes
   1056  1.1  christos   then
   1057  1.1  christos     eval to_tmp_line \
   1058  1.1  christos       "'.SH $(echo1 "${_FILESPEC_ARG}" | sed 's/[^\\]-/\\-/g')'";
   1059  1.1  christos     exit_test;
   1060  1.1  christos     if obj _APROPOS_PROG is_empty
   1061  1.1  christos     then
   1062  1.1  christos       error 'apropos_filespec: apropos_setup() must be run first.';
   1063  1.1  christos     fi;
   1064  1.1  christos     if obj _APROPOS_SECTIONS is_empty
   1065  1.1  christos     then
   1066  1.1  christos       if obj _OPT_SECTIONS is_empty
   1067  1.1  christos       then
   1068  1.1  christos         s='^.*(.*).*$';
   1069  1.1  christos       else
   1070  1.1  christos         s='^.*(['"$(echo1 "${_OPT_SECTIONS}" | sed -e 's/://g')"']';
   1071  1.1  christos       fi;
   1072  1.1  christos     else
   1073  1.1  christos       s='^.*(['"${_APROPOS_SECTIONS}"']';
   1074  1.1  christos     fi;
   1075  1.1  christos     eval "${_APROPOS_PROG}" "'${_FILESPEC_ARG}'" | \
   1076  1.1  christos       sed -n -e '
   1077  1.1  christos /^'"${_FILESPEC_ARG}"': /p
   1078  1.1  christos /'"$s"'/p
   1079  1.1  christos ' | \
   1080  1.1  christos       sort |\
   1081  1.1  christos       sed -e '
   1082  1.1  christos s/^\(.* (..*)\)  *-  *\(.*\)$/\.br\n\.TP 15\n\.BR \1\n\2/
   1083  1.1  christos ' >>"${_TMP_CAT}";
   1084  1.1  christos   fi;
   1085  1.1  christos   eval "${return_ok}";
   1086  1.1  christos }
   1087  1.1  christos 
   1088  1.1  christos 
   1089  1.1  christos ########################################################################
   1090  1.1  christos # apropos_setup ()
   1091  1.1  christos #
   1092  1.1  christos # Setup for the --apropos* options
   1093  1.1  christos #
   1094  1.1  christos apropos_setup()
   1095  1.1  christos {
   1096  1.1  christos   func_check apropos_setup '=' 0 "$@";
   1097  1.1  christos   if obj _OPT_APROPOS is_yes
   1098  1.1  christos   then
   1099  1.1  christos     if is_prog apropos
   1100  1.1  christos     then
   1101  1.1  christos       _APROPOS_PROG='apropos';
   1102  1.1  christos     elif is_prog man
   1103  1.1  christos     then
   1104  1.1  christos       if man --apropos man >${_NULL_DEV} 2>${_NULL_DEV}
   1105  1.1  christos       then
   1106  1.1  christos         _APROPOS_PROG='man --apropos';
   1107  1.1  christos       elif man -k man >${_NULL_DEV} 2>${_NULL_DEV}
   1108  1.1  christos       then
   1109  1.1  christos         _APROPOS_PROG='man -k';
   1110  1.1  christos       fi;
   1111  1.1  christos     fi;
   1112  1.1  christos     if obj _APROPOS_PROG is_empty
   1113  1.1  christos     then
   1114  1.1  christos       error 'apropos_setup: no apropos program available.';
   1115  1.1  christos     fi;
   1116  1.1  christos     to_tmp_line '.TH GROFFER APROPOS';
   1117  1.1  christos   fi;
   1118  1.1  christos   eval "${return_ok}";
   1119  1.1  christos }
   1120  1.1  christos 
   1121  1.1  christos 
   1122  1.1  christos ########################################################################
   1123  1.1  christos # base_name (<path>)
   1124  1.1  christos #
   1125  1.1  christos # Get the file name part of <path>, i.e. delete everything up to last
   1126  1.1  christos # `/' from the beginning of <path>.  Remove final slashes, too, to get a
   1127  1.1  christos # non-empty output.
   1128  1.1  christos #
   1129  1.1  christos # Arguments : 1
   1130  1.1  christos # Output    : the file name part (without slashes)
   1131  1.1  christos #
   1132  1.1  christos # Variable prefix: bn
   1133  1.1  christos #
   1134  1.1  christos base_name()
   1135  1.1  christos {
   1136  1.1  christos   func_check base_name = 1 "$@";
   1137  1.1  christos   bn_name="$1";
   1138  1.1  christos   case "${bn_name}" in
   1139  1.1  christos     */)
   1140  1.1  christos       # delete all final slashes
   1141  1.1  christos       bn_name="$(echo1 "${bn_name}" | sed -e 's|//*$||')";
   1142  1.1  christos       exit_test;
   1143  1.1  christos       ;;
   1144  1.1  christos   esac;
   1145  1.1  christos   case "${bn_name}" in
   1146  1.1  christos     /|'')
   1147  1.1  christos       eval ${_UNSET} bn_name;
   1148  1.1  christos       eval "${return_bad}";
   1149  1.1  christos       ;;
   1150  1.1  christos     */*)
   1151  1.1  christos       # delete everything before and including the last slash `/'.
   1152  1.1  christos       echo1 "${bn_name}" | sed -e 's|^.*//*\([^/]*\)$|\1|';
   1153  1.1  christos       ;;
   1154  1.1  christos     *)
   1155  1.1  christos       obj bn_name echo1;
   1156  1.1  christos       ;;
   1157  1.1  christos   esac;
   1158  1.1  christos   eval ${_UNSET} bn_name;
   1159  1.1  christos   eval "${return_ok}";
   1160  1.1  christos }
   1161  1.1  christos 
   1162  1.1  christos 
   1163  1.1  christos ########################################################################
   1164  1.1  christos # cat_z (<file>)
   1165  1.1  christos #
   1166  1.1  christos # Decompress if possible or just print <file> to standard output.
   1167  1.1  christos #
   1168  1.1  christos # gzip, bzip2, and .Z decompression is supported.
   1169  1.1  christos #
   1170  1.1  christos # Arguments: 1, a file name.
   1171  1.1  christos # Output: the content of <file>, possibly decompressed.
   1172  1.1  christos #
   1173  1.1  christos if test _"${_HAS_COMPRESSION}"_ = _yes_
   1174  1.1  christos then
   1175  1.1  christos   cat_z()
   1176  1.1  christos   {
   1177  1.1  christos     func_check cat_z = 1 "$@";
   1178  1.1  christos     case "$1" in
   1179  1.1  christos       '')
   1180  1.1  christos         error 'cat_z(): empty file name';
   1181  1.1  christos         ;;
   1182  1.1  christos       '-')
   1183  1.1  christos         error 'cat_z(): for standard input use save_stdin()';
   1184  1.1  christos         ;;
   1185  1.1  christos     esac;
   1186  1.1  christos     if obj _HAS_BZIP is_yes
   1187  1.1  christos     then
   1188  1.1  christos       if bzip2 -t "$1" 2>${_NULL_DEV}
   1189  1.1  christos       then
   1190  1.1  christos         bzip2 -c -d "$1" 2>${_NULL_DEV};
   1191  1.1  christos         eval "${return_ok}";
   1192  1.1  christos       fi;
   1193  1.1  christos     fi;
   1194  1.1  christos     gzip -c -d -f "$1" 2>${_NULL_DEV};
   1195  1.1  christos     eval "${return_ok}";
   1196  1.1  christos   }
   1197  1.1  christos else
   1198  1.1  christos   cat_z()
   1199  1.1  christos   {
   1200  1.1  christos     func_check cat_z = 1 "$@";
   1201  1.1  christos     cat "$1";
   1202  1.1  christos     eval "${return_ok}";
   1203  1.1  christos   }
   1204  1.1  christos fi;
   1205  1.1  christos 
   1206  1.1  christos 
   1207  1.1  christos ########################################################################
   1208  1.1  christos # clean_up ()
   1209  1.1  christos #
   1210  1.1  christos # Do the final cleaning up before exiting; used by the trap calls.
   1211  1.1  christos #
   1212  1.1  christos # defined above
   1213  1.1  christos 
   1214  1.1  christos 
   1215  1.1  christos ########################################################################
   1216  1.1  christos # diag (<text>*)
   1217  1.1  christos #
   1218  1.1  christos # Print marked message to standard error; useful for debugging.
   1219  1.1  christos #
   1220  1.1  christos # defined above
   1221  1.1  christos 
   1222  1.1  christos 
   1223  1.1  christos ########################################################################
   1224  1.1  christos landmark '4: dirname()*';
   1225  1.1  christos ########################################################################
   1226  1.1  christos 
   1227  1.1  christos #######################################################################
   1228  1.1  christos # dirname_append (<dir> <name>)
   1229  1.1  christos #
   1230  1.1  christos # Append `name' to `dir' with clean handling of `/'.
   1231  1.1  christos #
   1232  1.1  christos # Arguments : 2
   1233  1.1  christos # Output    : the generated new directory name <dir>/<name>
   1234  1.1  christos #
   1235  1.1  christos dirname_append()
   1236  1.1  christos {
   1237  1.1  christos   func_check dirname_append = 2 "$@";
   1238  1.1  christos   if is_empty "$1"
   1239  1.1  christos   then
   1240  1.1  christos     error "dir_append(): first argument is empty.";
   1241  1.1  christos   fi;
   1242  1.1  christos   if is_empty "$2"
   1243  1.1  christos   then
   1244  1.1  christos     echo1 "$1";
   1245  1.1  christos   else
   1246  1.1  christos     dirname_chop "$1"/"$2";
   1247  1.1  christos   fi;
   1248  1.1  christos   eval "${return_ok}";
   1249  1.1  christos }
   1250  1.1  christos 
   1251  1.1  christos 
   1252  1.1  christos ########################################################################
   1253  1.1  christos # dirname_chop (<name>)
   1254  1.1  christos #
   1255  1.1  christos # Remove unnecessary slashes from directory name.
   1256  1.1  christos #
   1257  1.1  christos # Argument: 1, a directory name.
   1258  1.1  christos # Output:   path without double, or trailing slashes.
   1259  1.1  christos #
   1260  1.1  christos # Variable prefix: dc
   1261  1.1  christos #
   1262  1.1  christos dirname_chop()
   1263  1.1  christos {
   1264  1.1  christos   func_check dirname_chop = 1 "$@";
   1265  1.1  christos   # replace all multiple slashes by a single slash `/'.
   1266  1.1  christos   dc_res="$(echo1 "$1" | sed -e 's|///*|/|g')";
   1267  1.1  christos   exit_test;
   1268  1.1  christos   case "${dc_res}" in
   1269  1.1  christos   ?*/)
   1270  1.1  christos     # remove trailing slash '/';
   1271  1.1  christos     echo1 "${dc_res}" | sed -e 's|/$||';
   1272  1.1  christos     ;;
   1273  1.1  christos   *)
   1274  1.1  christos     obj dc_res echo1
   1275  1.1  christos     ;;
   1276  1.1  christos   esac;
   1277  1.1  christos   eval ${_UNSET} dc_res;
   1278  1.1  christos   eval "${return_ok}";
   1279  1.1  christos }
   1280  1.1  christos 
   1281  1.1  christos 
   1282  1.1  christos ########################################################################
   1283  1.1  christos # do_filearg (<filearg>)
   1284  1.1  christos #
   1285  1.1  christos # Append the file, man-page, or standard input corresponding to the
   1286  1.1  christos # argument to the temporary file.  If this is compressed in the gzip
   1287  1.1  christos # or Z format it is decompressed.  A title element is generated.
   1288  1.1  christos #
   1289  1.1  christos # Argument either:
   1290  1.1  christos #   - name of an existing file.
   1291  1.1  christos #   - `-' to represent standard input (several times allowed).
   1292  1.1  christos #   - `man:name.(section)' the man-page for `name' in `section'.
   1293  1.1  christos #   - `man:name.section' the man-page for `name' in `section'.
   1294  1.1  christos #   - `man:name' the man-page for `name' in the lowest `section'.
   1295  1.1  christos #   - `name.section' the man-page for `name' in `section'.
   1296  1.1  christos #   - `name' the man-page for `name' in the lowest `section'.
   1297  1.1  christos # Globals :
   1298  1.1  christos #   $_TMP_STDIN, $_MAN_ENABLE, $_MAN_IS_SETUP, $_OPT_MAN
   1299  1.1  christos #
   1300  1.1  christos # Output  : none
   1301  1.1  christos # Return  : $_GOOD if found, ${_BAD} otherwise.
   1302  1.1  christos #
   1303  1.1  christos # Variable prefix: df
   1304  1.1  christos #
   1305  1.1  christos do_filearg()
   1306  1.1  christos {
   1307  1.1  christos   func_check do_filearg = 1 "$@";
   1308  1.1  christos   df_filespec="$1";
   1309  1.1  christos   # store sequence into positional parameters
   1310  1.1  christos   case "${df_filespec}" in
   1311  1.1  christos   '')
   1312  1.1  christos     eval ${_UNSET} df_filespec;
   1313  1.1  christos     eval "${return_good}";
   1314  1.1  christos     ;;
   1315  1.1  christos   '-')
   1316  1.1  christos     register_file '-';
   1317  1.1  christos     eval ${_UNSET} df_filespec;
   1318  1.1  christos     eval "${return_good}";
   1319  1.1  christos     ;;
   1320  1.1  christos   */*)			       # with directory part; so no man search
   1321  1.1  christos     set 'File';
   1322  1.1  christos     ;;
   1323  1.1  christos   *)
   1324  1.1  christos     if obj _MAN_ENABLE is_yes
   1325  1.1  christos     then
   1326  1.1  christos       if obj _MAN_FORCE is_yes
   1327  1.1  christos       then
   1328  1.1  christos         set 'Manpage' 'File';
   1329  1.1  christos       else
   1330  1.1  christos         set 'File' 'Manpage';
   1331  1.1  christos       fi;
   1332  1.1  christos       else
   1333  1.1  christos       set 'File';
   1334  1.1  christos     fi;
   1335  1.1  christos     ;;
   1336  1.1  christos   esac;
   1337  1.1  christos   for i
   1338  1.1  christos   do
   1339  1.1  christos     case "$i" in
   1340  1.1  christos     File)
   1341  1.1  christos       if test -f "${df_filespec}"
   1342  1.1  christos       then
   1343  1.1  christos         if test -r "${df_filespec}"
   1344  1.1  christos         then
   1345  1.1  christos           register_file "${df_filespec}";
   1346  1.1  christos           eval ${_UNSET} df_filespec;
   1347  1.1  christos           eval ${_UNSET} df_no_man;
   1348  1.1  christos           eval "${return_good}";
   1349  1.1  christos         else
   1350  1.1  christos           echo2 "could not read \`${df_filespec}'";
   1351  1.1  christos           eval ${_UNSET} df_filespec;
   1352  1.1  christos           eval ${_UNSET} df_no_man;
   1353  1.1  christos           eval "${return_bad}";
   1354  1.1  christos         fi;
   1355  1.1  christos       else
   1356  1.1  christos         if obj df_no_man is_not_empty
   1357  1.1  christos         then
   1358  1.1  christos           if obj _OPT_WHATIS is_yes
   1359  1.1  christos           then
   1360  1.1  christos             to_tmp_line "This is neither a file nor a man page."
   1361  1.1  christos           else
   1362  1.1  christos             echo2 "\`${df_filespec}' is neither a file nor a man page."
   1363  1.1  christos           fi;
   1364  1.1  christos         fi;
   1365  1.1  christos         df_no_file=yes;
   1366  1.1  christos         continue;
   1367  1.1  christos       fi;
   1368  1.1  christos       ;;
   1369  1.1  christos     Manpage)			# parse filespec as man page
   1370  1.1  christos       if obj _MAN_IS_SETUP is_not_yes
   1371  1.1  christos       then
   1372  1.1  christos         man_setup;
   1373  1.1  christos       fi;
   1374  1.1  christos       if man_do_filespec "${df_filespec}"
   1375  1.1  christos       then
   1376  1.1  christos         eval ${_UNSET} df_filespec;
   1377  1.1  christos         eval ${_UNSET} df_no_file;
   1378  1.1  christos         eval "${return_good}";
   1379  1.1  christos       else
   1380  1.1  christos         if obj df_no_file is_not_empty
   1381  1.1  christos         then
   1382  1.1  christos           if obj _OPT_WHATIS is_yes
   1383  1.1  christos           then
   1384  1.1  christos             to_tmp_line "This is neither a file nor a man page."
   1385  1.1  christos           else
   1386  1.1  christos             echo2 "\`${df_filespec}' is neither a file nor a man page."
   1387  1.1  christos           fi;
   1388  1.1  christos         fi;
   1389  1.1  christos         df_no_man=yes;
   1390  1.1  christos         continue;
   1391  1.1  christos       fi;
   1392  1.1  christos       ;;
   1393  1.1  christos     esac;
   1394  1.1  christos   done;
   1395  1.1  christos   eval ${_UNSET} df_filespec;
   1396  1.1  christos   eval ${_UNSET} df_no_file;
   1397  1.1  christos   eval ${_UNSET} df_no_man;
   1398  1.1  christos   eval "${return_bad}";
   1399  1.1  christos } # do_filearg()
   1400  1.1  christos 
   1401  1.1  christos 
   1402  1.1  christos ########################################################################
   1403  1.1  christos # do_nothing ()
   1404  1.1  christos #
   1405  1.1  christos # Dummy function.
   1406  1.1  christos #
   1407  1.1  christos do_nothing()
   1408  1.1  christos {
   1409  1.1  christos   eval return "${_OK}";
   1410  1.1  christos }
   1411  1.1  christos 
   1412  1.1  christos 
   1413  1.1  christos ########################################################################
   1414  1.1  christos # echo2 (<text>*)
   1415  1.1  christos #
   1416  1.1  christos # Print to standard error with final line break.
   1417  1.1  christos #
   1418  1.1  christos # defined above
   1419  1.1  christos 
   1420  1.1  christos 
   1421  1.1  christos ########################################################################
   1422  1.1  christos # error (<text>*)
   1423  1.1  christos #
   1424  1.1  christos # Print error message and exit with error code.
   1425  1.1  christos #
   1426  1.1  christos # defined above
   1427  1.1  christos 
   1428  1.1  christos 
   1429  1.1  christos ########################################################################
   1430  1.1  christos # exit_test ()
   1431  1.1  christos #
   1432  1.1  christos # Test whether the former command ended with error().  Exit again.
   1433  1.1  christos #
   1434  1.1  christos # defined above
   1435  1.1  christos 
   1436  1.1  christos 
   1437  1.1  christos ########################################################################
   1438  1.1  christos # func_check (<func_name> <rel_op> <nr_args> "$@")
   1439  1.1  christos #
   1440  1.1  christos # Check number of arguments and register to _FUNC_STACK.
   1441  1.1  christos #
   1442  1.1  christos # Arguments: >=3
   1443  1.1  christos #   <func_name>: name of the calling function.
   1444  1.1  christos #   <rel_op>:    a relational operator: = != < > <= >=
   1445  1.1  christos #   <nr_args>:   number of arguments to be checked against <operator>
   1446  1.1  christos #   "$@":        the arguments of the calling function.
   1447  1.1  christos #
   1448  1.1  christos # defined above
   1449  1.1  christos 
   1450  1.1  christos #########################################################################
   1451  1.1  christos # func_pop ()
   1452  1.1  christos #
   1453  1.1  christos # Delete the top element from the function call stack.
   1454  1.1  christos #
   1455  1.1  christos # defined above
   1456  1.1  christos 
   1457  1.1  christos 
   1458  1.1  christos ########################################################################
   1459  1.1  christos # func_push (<element>)
   1460  1.1  christos #
   1461  1.1  christos # Store another element to function call stack.
   1462  1.1  christos #
   1463  1.1  christos # defined above
   1464  1.1  christos 
   1465  1.1  christos 
   1466  1.1  christos ########################################################################
   1467  1.1  christos # func_stack_dump ()
   1468  1.1  christos #
   1469  1.1  christos # Print the content of the stack.
   1470  1.1  christos #
   1471  1.1  christos # defined above
   1472  1.1  christos 
   1473  1.1  christos 
   1474  1.1  christos ########################################################################
   1475  1.1  christos # get_first_essential (<arg>*)
   1476  1.1  christos #
   1477  1.1  christos # Retrieve first non-empty argument.
   1478  1.1  christos #
   1479  1.1  christos # Return  : `1' if all arguments are empty, `0' if found.
   1480  1.1  christos # Output  : the retrieved non-empty argument.
   1481  1.1  christos #
   1482  1.1  christos # Variable prefix: gfe
   1483  1.1  christos #
   1484  1.1  christos get_first_essential()
   1485  1.1  christos {
   1486  1.1  christos   func_check get_first_essential '>=' 0 "$@";
   1487  1.1  christos   if is_equal "$#" 0
   1488  1.1  christos   then
   1489  1.1  christos     eval "${return_ok}";
   1490  1.1  christos   fi;
   1491  1.1  christos   for i
   1492  1.1  christos   do
   1493  1.1  christos     gfe_var="$i";
   1494  1.1  christos     if obj gfe_var is_not_empty
   1495  1.1  christos     then
   1496  1.1  christos       obj gfe_var echo1;
   1497  1.1  christos       eval ${_UNSET} gfe_var;
   1498  1.1  christos       eval "${return_ok}";
   1499  1.1  christos     fi;
   1500  1.1  christos   done;
   1501  1.1  christos   eval ${_UNSET} gfe_var;
   1502  1.1  christos   eval "${return_bad}";
   1503  1.1  christos }
   1504  1.1  christos 
   1505  1.1  christos 
   1506  1.1  christos ########################################################################
   1507  1.1  christos landmark '5: is_*()';
   1508  1.1  christos ########################################################################
   1509  1.1  christos 
   1510  1.1  christos ########################################################################
   1511  1.1  christos # is_dir (<name>)
   1512  1.1  christos #
   1513  1.1  christos # Test whether `name' is a directory.
   1514  1.1  christos #
   1515  1.1  christos # Arguments : 1
   1516  1.1  christos # Return    : `0' if arg1 is a directory, `1' otherwise.
   1517  1.1  christos #
   1518  1.1  christos is_dir()
   1519  1.1  christos {
   1520  1.1  christos   func_check is_dir '=' 1 "$@";
   1521  1.1  christos   if test _"$1"_ != __ && test -d "$1" && test -r "$1"
   1522  1.1  christos   then
   1523  1.1  christos     eval "${return_yes}";
   1524  1.1  christos   fi;
   1525  1.1  christos   eval "${return_no}";
   1526  1.1  christos }
   1527  1.1  christos 
   1528  1.1  christos 
   1529  1.1  christos ########################################################################
   1530  1.1  christos # is_empty (<string>)
   1531  1.1  christos #
   1532  1.1  christos # Test whether `string' is empty.
   1533  1.1  christos #
   1534  1.1  christos # Arguments : <=1
   1535  1.1  christos # Return    : `0' if arg1 is empty or does not exist, `1' otherwise.
   1536  1.1  christos #
   1537  1.1  christos is_empty()
   1538  1.1  christos {
   1539  1.1  christos   func_check is_empty '=' 1 "$@";
   1540  1.1  christos   if test _"$1"_ = __
   1541  1.1  christos   then
   1542  1.1  christos     eval "${return_yes}";
   1543  1.1  christos   fi;
   1544  1.1  christos   eval "${return_no}";
   1545  1.1  christos }
   1546  1.1  christos 
   1547  1.1  christos 
   1548  1.1  christos ########################################################################
   1549  1.1  christos # is_equal (<string1> <string2>)
   1550  1.1  christos #
   1551  1.1  christos # Test whether `string1' is equal to <string2>.
   1552  1.1  christos #
   1553  1.1  christos # Arguments : 2
   1554  1.1  christos # Return    : `0' both arguments are equal strings, `1' otherwise.
   1555  1.1  christos #
   1556  1.1  christos is_equal()
   1557  1.1  christos {
   1558  1.1  christos   func_check is_equal '=' 2 "$@";
   1559  1.1  christos   if test _"$1"_ = _"$2"_
   1560  1.1  christos   then
   1561  1.1  christos     eval "${return_yes}";
   1562  1.1  christos   fi;
   1563  1.1  christos   eval "${return_no}";
   1564  1.1  christos }
   1565  1.1  christos 
   1566  1.1  christos 
   1567  1.1  christos ########################################################################
   1568  1.1  christos # is_existing (<name>)
   1569  1.1  christos #
   1570  1.1  christos # Test whether `name' is an existing file or directory.  Solaris 2.5 does
   1571  1.1  christos # not have `test -e'.
   1572  1.1  christos #
   1573  1.1  christos # Arguments : 1
   1574  1.1  christos # Return    : `0' if arg1 exists, `1' otherwise.
   1575  1.1  christos #
   1576  1.1  christos is_existing()
   1577  1.1  christos {
   1578  1.1  christos   func_check is_existing '=' 1 "$@";
   1579  1.1  christos   if test _"$1"_ = __
   1580  1.1  christos   then
   1581  1.1  christos     eval "${return_no}";
   1582  1.1  christos   fi;
   1583  1.1  christos   if test -f "$1" || test -d "$1" || test -c "$1"
   1584  1.1  christos   then
   1585  1.1  christos     eval "${return_yes}";
   1586  1.1  christos   fi;
   1587  1.1  christos   eval "${return_no}";
   1588  1.1  christos }
   1589  1.1  christos 
   1590  1.1  christos 
   1591  1.1  christos ########################################################################
   1592  1.1  christos # is_file (<name>)
   1593  1.1  christos #
   1594  1.1  christos # Test whether `name' is a readable file.
   1595  1.1  christos #
   1596  1.1  christos # Arguments : 1
   1597  1.1  christos # Return    : `0' if arg1 is a readable file, `1' otherwise.
   1598  1.1  christos #
   1599  1.1  christos is_file()
   1600  1.1  christos {
   1601  1.1  christos   func_check is_file '=' 1 "$@";
   1602  1.1  christos   if is_not_empty "$1" && test -f "$1" && test -r "$1"
   1603  1.1  christos   then
   1604  1.1  christos     eval "${return_yes}";
   1605  1.1  christos   fi;
   1606  1.1  christos   eval "${return_no}";
   1607  1.1  christos }
   1608  1.1  christos 
   1609  1.1  christos 
   1610  1.1  christos ########################################################################
   1611  1.1  christos # is_non_empty_file (<file_name>)
   1612  1.1  christos #
   1613  1.1  christos # Test whether `file_name' is a non-empty existing file.
   1614  1.1  christos #
   1615  1.1  christos # Arguments : <=1
   1616  1.1  christos # Return    :
   1617  1.1  christos #   `0' if arg1 is a non-empty existing file
   1618  1.1  christos #   `1' otherwise
   1619  1.1  christos #
   1620  1.1  christos is_non_empty_file()
   1621  1.1  christos {
   1622  1.1  christos   func_check is_non_empty_file '=' 1 "$@";
   1623  1.1  christos   if is_file "$1" && test -s "$1"
   1624  1.1  christos   then
   1625  1.1  christos     eval "${return_yes}";
   1626  1.1  christos   fi;
   1627  1.1  christos   eval "${return_no}";
   1628  1.1  christos }
   1629  1.1  christos 
   1630  1.1  christos 
   1631  1.1  christos ########################################################################
   1632  1.1  christos # is_not_dir (<name>)
   1633  1.1  christos #
   1634  1.1  christos # Test whether `name' is not a readable directory.
   1635  1.1  christos #
   1636  1.1  christos # Arguments : 1
   1637  1.1  christos # Return    : `0' if arg1 is a directory, `1' otherwise.
   1638  1.1  christos #
   1639  1.1  christos is_not_dir()
   1640  1.1  christos {
   1641  1.1  christos   func_check is_not_dir '=' 1 "$@";
   1642  1.1  christos   if is_dir "$1"
   1643  1.1  christos   then
   1644  1.1  christos     eval "${return_no}";
   1645  1.1  christos   fi;
   1646  1.1  christos   eval "${return_yes}";
   1647  1.1  christos }
   1648  1.1  christos 
   1649  1.1  christos 
   1650  1.1  christos ########################################################################
   1651  1.1  christos # is_not_empty (<string>)
   1652  1.1  christos #
   1653  1.1  christos # Test whether `string' is not empty.
   1654  1.1  christos #
   1655  1.1  christos # Arguments : <=1
   1656  1.1  christos # Return    : `0' if arg1 exists and is not empty, `1' otherwise.
   1657  1.1  christos #
   1658  1.1  christos is_not_empty()
   1659  1.1  christos {
   1660  1.1  christos   func_check is_not_empty '=' 1 "$@";
   1661  1.1  christos   if is_empty "$1"
   1662  1.1  christos   then
   1663  1.1  christos     eval "${return_no}";
   1664  1.1  christos   fi;
   1665  1.1  christos   eval "${return_yes}";
   1666  1.1  christos }
   1667  1.1  christos 
   1668  1.1  christos 
   1669  1.1  christos ########################################################################
   1670  1.1  christos # is_not_equal (<string1> <string2>)
   1671  1.1  christos #
   1672  1.1  christos # Test whether `string1' differs from `string2'.
   1673  1.1  christos #
   1674  1.1  christos # Arguments : 2
   1675  1.1  christos #
   1676  1.1  christos is_not_equal()
   1677  1.1  christos {
   1678  1.1  christos   func_check is_not_equal '=' 2 "$@";
   1679  1.1  christos   if is_equal "$1" "$2"
   1680  1.1  christos   then
   1681  1.1  christos     eval "${return_no}";
   1682  1.1  christos   fi
   1683  1.1  christos   eval "${return_yes}";
   1684  1.1  christos }
   1685  1.1  christos 
   1686  1.1  christos 
   1687  1.1  christos ########################################################################
   1688  1.1  christos # is_not_file (<filename>)
   1689  1.1  christos #
   1690  1.1  christos # Test whether `name' is a not readable file.
   1691  1.1  christos #
   1692  1.1  christos # Arguments : 1 (empty allowed)
   1693  1.1  christos #
   1694  1.1  christos is_not_file()
   1695  1.1  christos {
   1696  1.1  christos   func_check is_not_file '=' 1 "$@";
   1697  1.1  christos   if is_file "$1"
   1698  1.1  christos   then
   1699  1.1  christos     eval "${return_no}";
   1700  1.1  christos   fi;
   1701  1.1  christos   eval "${return_yes}";
   1702  1.1  christos }
   1703  1.1  christos 
   1704  1.1  christos 
   1705  1.1  christos ########################################################################
   1706  1.1  christos # is_not_prog ([<name> [<arg>*]])
   1707  1.1  christos #
   1708  1.1  christos # Verify that arg is a not program in $PATH.
   1709  1.1  christos #
   1710  1.1  christos # Arguments : >=0 (empty allowed)
   1711  1.1  christos #   more args are ignored, this allows to specify progs with arguments
   1712  1.1  christos #
   1713  1.1  christos is_not_prog()
   1714  1.1  christos {
   1715  1.1  christos   func_check is_not_prog '>=' 0 "$@";
   1716  1.1  christos   case "$#" in
   1717  1.1  christos   0)
   1718  1.1  christos     eval "${return_yes}";
   1719  1.1  christos     ;;
   1720  1.1  christos   *)
   1721  1.1  christos     if where_is "$1" >${_NULL_DEV}
   1722  1.1  christos     then
   1723  1.1  christos       eval "${return_no}";
   1724  1.1  christos     fi;
   1725  1.1  christos     ;;
   1726  1.1  christos   esac
   1727  1.1  christos   eval "${return_yes}";
   1728  1.1  christos }
   1729  1.1  christos 
   1730  1.1  christos 
   1731  1.1  christos ########################################################################
   1732  1.1  christos # is_not_writable (<name>)
   1733  1.1  christos #
   1734  1.1  christos # Test whether `name' is a not a writable file or directory.
   1735  1.1  christos #
   1736  1.1  christos # Arguments : >=1 (empty allowed), more args are ignored
   1737  1.1  christos #
   1738  1.1  christos is_not_writable()
   1739  1.1  christos {
   1740  1.1  christos   func_check is_not_writable '>=' 1 "$@";
   1741  1.1  christos   if is_writable "$1"
   1742  1.1  christos   then
   1743  1.1  christos     eval "${return_no}";
   1744  1.1  christos   fi;
   1745  1.1  christos   eval "${return_yes}";
   1746  1.1  christos }
   1747  1.1  christos 
   1748  1.1  christos 
   1749  1.1  christos ########################################################################
   1750  1.1  christos # is_not_X ()
   1751  1.1  christos #
   1752  1.1  christos # Test whether not running in X Window by checking $DISPLAY
   1753  1.1  christos #
   1754  1.1  christos is_not_X()
   1755  1.1  christos {
   1756  1.1  christos   func_check is_X '=' 0 "$@";
   1757  1.1  christos   if obj DISPLAY is_empty
   1758  1.1  christos   then
   1759  1.1  christos     eval "${return_yes}";
   1760  1.1  christos   fi;
   1761  1.1  christos   eval "${return_no}";
   1762  1.1  christos }
   1763  1.1  christos 
   1764  1.1  christos 
   1765  1.1  christos ########################################################################
   1766  1.1  christos # is_not_yes (<string>)
   1767  1.1  christos #
   1768  1.1  christos # Test whether `string' is not "yes".
   1769  1.1  christos #
   1770  1.1  christos # Arguments : 1
   1771  1.1  christos #
   1772  1.1  christos is_not_yes()
   1773  1.1  christos {
   1774  1.1  christos   func_check is_not_yes = 1 "$@";
   1775  1.1  christos   if is_yes "$1"
   1776  1.1  christos   then
   1777  1.1  christos     eval "${return_no}";
   1778  1.1  christos   fi;
   1779  1.1  christos   eval "${return_yes}";
   1780  1.1  christos }
   1781  1.1  christos 
   1782  1.1  christos 
   1783  1.1  christos ########################################################################
   1784  1.1  christos # is_prog ([<name> [<arg>*]])
   1785  1.1  christos #
   1786  1.1  christos # Determine whether <name> is a program in $PATH
   1787  1.1  christos #
   1788  1.1  christos # Arguments : >=0 (empty allowed)
   1789  1.1  christos #   <arg>* are ignored, this allows to specify progs with arguments.
   1790  1.1  christos #
   1791  1.1  christos is_prog()
   1792  1.1  christos {
   1793  1.1  christos   func_check is_prog '>=' 0 "$@";
   1794  1.1  christos   case "$#" in
   1795  1.1  christos   0)
   1796  1.1  christos     eval "${return_no}";
   1797  1.1  christos     ;;
   1798  1.1  christos   *)
   1799  1.1  christos     if where_is "$1" >${_NULL_DEV}
   1800  1.1  christos     then
   1801  1.1  christos       eval "${return_yes}";
   1802  1.1  christos     fi;
   1803  1.1  christos     ;;
   1804  1.1  christos   esac
   1805  1.1  christos   eval "${return_no}";
   1806  1.1  christos }
   1807  1.1  christos 
   1808  1.1  christos 
   1809  1.1  christos ########################################################################
   1810  1.1  christos # is_writable (<name>)
   1811  1.1  christos #
   1812  1.1  christos # Test whether `name' is a writable file or directory.
   1813  1.1  christos #
   1814  1.1  christos # Arguments : >=1 (empty allowed), more args are ignored
   1815  1.1  christos #
   1816  1.1  christos is_writable()
   1817  1.1  christos {
   1818  1.1  christos   func_check is_writable '>=' 1 "$@";
   1819  1.1  christos   if test _"$1"_ = __
   1820  1.1  christos   then
   1821  1.1  christos     eval "${return_no}";
   1822  1.1  christos   fi;
   1823  1.1  christos   if test -r "$1"
   1824  1.1  christos   then
   1825  1.1  christos     if test -w "$1"
   1826  1.1  christos     then
   1827  1.1  christos       eval "${return_yes}";
   1828  1.1  christos     fi;
   1829  1.1  christos   fi;
   1830  1.1  christos   eval "${return_no}";
   1831  1.1  christos }
   1832  1.1  christos 
   1833  1.1  christos 
   1834  1.1  christos ########################################################################
   1835  1.1  christos # is_X ()
   1836  1.1  christos #
   1837  1.1  christos # Test whether running in X Window by checking $DISPLAY
   1838  1.1  christos #
   1839  1.1  christos is_X()
   1840  1.1  christos {
   1841  1.1  christos   func_check is_X '=' 0 "$@";
   1842  1.1  christos   if obj DISPLAY is_not_empty
   1843  1.1  christos   then
   1844  1.1  christos     eval "${return_yes}";
   1845  1.1  christos   fi;
   1846  1.1  christos   eval "${return_no}";
   1847  1.1  christos }
   1848  1.1  christos 
   1849  1.1  christos 
   1850  1.1  christos ########################################################################
   1851  1.1  christos # is_yes (<string>)
   1852  1.1  christos #
   1853  1.1  christos # Test whether `string' has value "yes".
   1854  1.1  christos #
   1855  1.1  christos # Return    : `0' if arg1 is `yes', `1' otherwise.
   1856  1.1  christos #
   1857  1.1  christos is_yes()
   1858  1.1  christos {
   1859  1.1  christos   func_check is_yes '=' 1 "$@";
   1860  1.1  christos   if is_equal "$1" 'yes'
   1861  1.1  christos   then
   1862  1.1  christos     eval "${return_yes}";
   1863  1.1  christos   fi;
   1864  1.1  christos   eval "${return_no}";
   1865  1.1  christos }
   1866  1.1  christos 
   1867  1.1  christos 
   1868  1.1  christos ########################################################################
   1869  1.1  christos # landmark ()
   1870  1.1  christos #
   1871  1.1  christos # Print debugging information on standard error if $_DEBUG_LM is `yes'.
   1872  1.1  christos #
   1873  1.1  christos # Globals: $_DEBUG_LM
   1874  1.1  christos #
   1875  1.1  christos # Defined in section `Debugging functions'.
   1876  1.1  christos 
   1877  1.1  christos 
   1878  1.1  christos ########################################################################
   1879  1.1  christos # leave ([<code>])
   1880  1.1  christos #
   1881  1.1  christos # Clean exit without an error or with <code>.
   1882  1.1  christos #
   1883  1.1  christos leave()
   1884  1.1  christos {
   1885  1.1  christos   clean_up;
   1886  1.1  christos   if test $# = 0
   1887  1.1  christos   then
   1888  1.1  christos     exit "${_OK}";
   1889  1.1  christos   else
   1890  1.1  christos     exit "$1";
   1891  1.1  christos   fi;
   1892  1.1  christos }
   1893  1.1  christos 
   1894  1.1  christos 
   1895  1.1  christos ########################################################################
   1896  1.1  christos landmark '6: list_*()';
   1897  1.1  christos ########################################################################
   1898  1.1  christos #
   1899  1.1  christos # `list' is an object class that represents an array or list.  Its
   1900  1.1  christos # data consists of space-separated single-quoted elements.  So a list
   1901  1.1  christos # has the form "'first' 'second' '...' 'last'".  See list_append() for
   1902  1.1  christos # more details on the list structure.  The array elements of `list'
   1903  1.1  christos # can be get by `eval set x "$list"; shift`.
   1904  1.1  christos 
   1905  1.1  christos 
   1906  1.1  christos ########################################################################
   1907  1.1  christos # list_append (<list> <element>...)
   1908  1.1  christos #
   1909  1.1  christos # Arguments: >=2
   1910  1.1  christos #   <list>: a variable name for a list of single-quoted elements
   1911  1.1  christos #   <element>:  some sequence of characters.
   1912  1.1  christos # Output: none, but $<list> is set to
   1913  1.1  christos #   if <list> is empty:  "'<element>' '...'"
   1914  1.1  christos #   otherwise:           "$list '<element>' ..."
   1915  1.1  christos #
   1916  1.1  christos # Variable prefix: la
   1917  1.1  christos #
   1918  1.1  christos list_append()
   1919  1.1  christos {
   1920  1.1  christos   func_check list_append '>=' 2 "$@";
   1921  1.1  christos   la_name="$1";
   1922  1.1  christos   eval la_list='"${'$1'}"';
   1923  1.1  christos   shift;
   1924  1.1  christos   for s
   1925  1.1  christos   do
   1926  1.1  christos     la_s="$s";
   1927  1.1  christos     case "${la_s}" in
   1928  1.1  christos     *\'*)
   1929  1.1  christos       # escape each single quote by replacing each
   1930  1.1  christos       # "'" (squote) by "'\''" (squote bslash squote squote);
   1931  1.1  christos       # note that the backslash must be doubled in the following `sed'
   1932  1.1  christos       la_element="$(echo1 "${la_s}" | sed -e 's/'"${_SQ}"'/&\\&&/g')";
   1933  1.1  christos       exit_test;
   1934  1.1  christos       ;;
   1935  1.1  christos     '')
   1936  1.1  christos       la_element="";
   1937  1.1  christos       ;;
   1938  1.1  christos     *)
   1939  1.1  christos       la_element="${la_s}";
   1940  1.1  christos       ;;
   1941  1.1  christos     esac;
   1942  1.1  christos     if obj la_list is_empty
   1943  1.1  christos     then
   1944  1.1  christos       la_list="'${la_element}'";
   1945  1.1  christos     else
   1946  1.1  christos       la_list="${la_list} '${la_element}'";
   1947  1.1  christos     fi;
   1948  1.1  christos   done;
   1949  1.1  christos   eval "${la_name}"='"${la_list}"';
   1950  1.1  christos   eval ${_UNSET} la_element;
   1951  1.1  christos   eval ${_UNSET} la_list;
   1952  1.1  christos   eval ${_UNSET} la_name;
   1953  1.1  christos   eval ${_UNSET} la_s;
   1954  1.1  christos   eval "${return_ok}";
   1955  1.1  christos }
   1956  1.1  christos 
   1957  1.1  christos 
   1958  1.1  christos ########################################################################
   1959  1.1  christos # list_from_cmdline (<pre_name_of_opt_lists> [<cmdline_arg>...])
   1960  1.1  christos #
   1961  1.1  christos # Transform command line arguments into a normalized form.
   1962  1.1  christos #
   1963  1.1  christos # Options, option arguments, and file parameters are identified and
   1964  1.1  christos # output each as a single-quoted argument of its own.  Options and
   1965  1.1  christos # file parameters are separated by a '--' argument.
   1966  1.1  christos #
   1967  1.1  christos # Arguments: >=1
   1968  1.1  christos #   <pre_name>: common part of a set of 4 environment variable names:
   1969  1.1  christos #     $<pre_name>_SHORT_NA:  list of short options without an arg.
   1970  1.1  christos #     $<pre_name>_SHORT_ARG: list of short options that have an arg.
   1971  1.1  christos #     $<pre_name>_LONG_NA:   list of long options without an arg.
   1972  1.1  christos #     $<pre_name>_LONG_ARG:  list of long options that have an arg.
   1973  1.1  christos #   <cmdline_arg>...: the arguments from a command line, such as "$@",
   1974  1.1  christos #                     the content of a variable, or direct arguments.
   1975  1.1  christos #
   1976  1.1  christos # Output: ['-[-]opt' ['optarg']]... '--' ['filename']...
   1977  1.1  christos #
   1978  1.1  christos # Example:
   1979  1.1  christos #   list_from_cmdline PRE 'a b' 'c' '' 'long' -a f1 -bcarg --long=larg f2
   1980  1.1  christos # If $PRE_SHORT_NA, $PRE_SHORT_ARG, $PRE_LONG_NA, and $PRE_LONG_ARG are
   1981  1.1  christos # none-empty option lists, this will result in printing:
   1982  1.1  christos #     '-a' '-b' '-c' 'arg' '--long' 'larg' '--' 'f1' 'f2'
   1983  1.1  christos #
   1984  1.1  christos #   Use this function in the following way:
   1985  1.1  christos #     eval set x "$(args_norm PRE_NAME "$@")";
   1986  1.1  christos #     shift;
   1987  1.1  christos #     while test "$1" != '--'; do
   1988  1.1  christos #       case "$1" in
   1989  1.1  christos #       ...
   1990  1.1  christos #       esac;
   1991  1.1  christos #       shift;
   1992  1.1  christos #     done;
   1993  1.1  christos #     shift;         #skip '--'
   1994  1.1  christos #     # all positional parameters ("$@") left are file name parameters.
   1995  1.1  christos #
   1996  1.1  christos # Variable prefix: lfc
   1997  1.1  christos #
   1998  1.1  christos list_from_cmdline()
   1999  1.1  christos {
   2000  1.1  christos   func_check list_from_cmdline '>=' 1 "$@";
   2001  1.1  christos   lfc_short_n="$(obj_data "$1"_SHORT_NA)";  # short options, no argument
   2002  1.1  christos   lfc_short_a="$(obj_data "$1"_SHORT_ARG)"; # short options, with argument
   2003  1.1  christos   lfc_long_n="$(obj_data "$1"_LONG_NA)";    # long options, no argument
   2004  1.1  christos   lfc_long_a="$(obj_data "$1"_LONG_ARG)";   # long options, with argument
   2005  1.1  christos   exit_test;
   2006  1.1  christos   if obj lfc_short_n is_empty
   2007  1.1  christos   then
   2008  1.1  christos     error 'list_from_cmdline(): no $'"$1"'_SHORT_NA options.';
   2009  1.1  christos   fi;
   2010  1.1  christos   if obj lfc_short_a is_empty
   2011  1.1  christos   then
   2012  1.1  christos     error 'list_from_cmdline(): no $'"$1"'_SHORT_ARG options.';
   2013  1.1  christos   fi;
   2014  1.1  christos   if obj lfc_long_n is_empty
   2015  1.1  christos   then
   2016  1.1  christos     error 'list_from_cmdline(): no $'"$1"'_LONG_NA options.';
   2017  1.1  christos   fi;
   2018  1.1  christos   if obj lfc_long_a is_empty
   2019  1.1  christos   then
   2020  1.1  christos     error 'list_from_cmdline(): no $'"$1"'_LONG_ARG options.';
   2021  1.1  christos   fi;
   2022  1.1  christos 
   2023  1.1  christos   shift;
   2024  1.1  christos   if is_equal "$#" 0
   2025  1.1  christos   then
   2026  1.1  christos     echo1 --
   2027  1.1  christos     eval ${_UNSET} lfc_fparams;
   2028  1.1  christos     eval ${_UNSET} lfc_short_a;
   2029  1.1  christos     eval ${_UNSET} lfc_short_n;
   2030  1.1  christos     eval ${_UNSET} lfc_long_a;
   2031  1.1  christos     eval ${_UNSET} lfc_long_n;
   2032  1.1  christos     eval ${_UNSET} lfc_result;
   2033  1.1  christos     eval "${return_ok}";
   2034  1.1  christos   fi;
   2035  1.1  christos 
   2036  1.1  christos   lfc_fparams='';
   2037  1.1  christos   lfc_result='';
   2038  1.1  christos   while test "$#" -ge 1
   2039  1.1  christos   do
   2040  1.1  christos     lfc_arg="$1";
   2041  1.1  christos     shift;
   2042  1.1  christos     case "${lfc_arg}" in
   2043  1.1  christos     --) break; ;;
   2044  1.1  christos     --*=*)
   2045  1.1  christos       # delete leading '--';
   2046  1.1  christos       lfc_abbrev="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
   2047  1.1  christos       lfc_with_equal="${lfc_abbrev}";
   2048  1.1  christos       # extract option by deleting from the first '=' to the end
   2049  1.1  christos       lfc_abbrev="$(echo1 "${lfc_with_equal}" | \
   2050  1.1  christos                     sed -e 's/^\([^=]*\)=.*$/\1/')";
   2051  1.1  christos       lfc_opt="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
   2052  1.1  christos       exit_test;
   2053  1.1  christos       if obj lfc_opt is_empty
   2054  1.1  christos       then
   2055  1.1  christos         error_user "--${lfc_abbrev} is not an option.";
   2056  1.1  christos       else
   2057  1.1  christos         # get the option argument by deleting up to first `='
   2058  1.1  christos         lfc_optarg="$(echo1 "${lfc_with_equal}" | sed -e 's/^[^=]*=//')";
   2059  1.1  christos         exit_test;
   2060  1.1  christos         list_append lfc_result "--${lfc_opt}" "${lfc_optarg}";
   2061  1.1  christos         continue;
   2062  1.1  christos       fi;
   2063  1.1  christos       ;;
   2064  1.1  christos     --*)
   2065  1.1  christos       # delete leading '--';
   2066  1.1  christos       lfc_abbrev="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
   2067  1.1  christos       if list_has lfc_long_n "${lfc_abbrev}"
   2068  1.1  christos       then
   2069  1.1  christos         lfc_opt="${lfc_abbrev}";
   2070  1.1  christos       else
   2071  1.1  christos         exit_test;
   2072  1.1  christos         lfc_opt="$(list_single_from_abbrev lfc_long_n "${lfc_abbrev}")";
   2073  1.1  christos         exit_test;
   2074  1.1  christos         if obj lfc_opt is_not_empty && is_not_equal "$#" 0
   2075  1.1  christos         then
   2076  1.1  christos           a="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
   2077  1.1  christos           exit_test;
   2078  1.1  christos           if obj a is_not_empty
   2079  1.1  christos           then
   2080  1.1  christos             error_user "The abbreviation ${lfc_arg} \
   2081  1.1  christos has multiple options: --${lfc_opt} and --${a}.";
   2082  1.1  christos           fi;
   2083  1.1  christos         fi;
   2084  1.1  christos       fi;
   2085  1.1  christos       if obj lfc_opt is_not_empty
   2086  1.1  christos       then
   2087  1.1  christos         # long option, no argument
   2088  1.1  christos         list_append lfc_result "--${lfc_opt}";
   2089  1.1  christos         continue;
   2090  1.1  christos       fi;
   2091  1.1  christos       lfc_opt="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
   2092  1.1  christos       exit_test;
   2093  1.1  christos       if obj lfc_opt is_not_empty
   2094  1.1  christos       then
   2095  1.1  christos         # long option with argument
   2096  1.1  christos         if test "$#" -le 0
   2097  1.1  christos         then
   2098  1.1  christos           error_user "no argument for option --${lfc_opt}."
   2099  1.1  christos         fi;
   2100  1.1  christos         list_append lfc_result "--${lfc_opt}" "$1";
   2101  1.1  christos         shift;
   2102  1.1  christos         continue;
   2103  1.1  christos       fi;
   2104  1.1  christos       error_user "${lfc_arg} is not an option.";
   2105  1.1  christos       ;;
   2106  1.1  christos     -?*)			# short option (cluster)
   2107  1.1  christos       # delete leading `-';
   2108  1.1  christos       lfc_rest="$(echo1 "${lfc_arg}" | sed -e 's/^-//')";
   2109  1.1  christos       exit_test;
   2110  1.1  christos       while obj lfc_rest is_not_empty
   2111  1.1  christos       do
   2112  1.1  christos         # get next short option from cluster (first char of $lfc_rest)
   2113  1.1  christos         lfc_optchar="$(echo1 "${lfc_rest}" | sed -e 's/^\(.\).*$/\1/')";
   2114  1.1  christos         # remove first character from ${lfc_rest};
   2115  1.1  christos         lfc_rest="$(echo1 "${lfc_rest}" | sed -e 's/^.//')";
   2116  1.1  christos         exit_test;
   2117  1.1  christos         if list_has lfc_short_n "${lfc_optchar}"
   2118  1.1  christos         then
   2119  1.1  christos           list_append lfc_result "-${lfc_optchar}";
   2120  1.1  christos           continue;
   2121  1.1  christos         elif list_has lfc_short_a "${lfc_optchar}"
   2122  1.1  christos         then
   2123  1.1  christos           if obj lfc_rest is_empty
   2124  1.1  christos           then
   2125  1.1  christos             if test "$#" -ge 1
   2126  1.1  christos             then
   2127  1.1  christos               list_append lfc_result "-${lfc_optchar}" "$1";
   2128  1.1  christos               shift;
   2129  1.1  christos               continue;
   2130  1.1  christos             else
   2131  1.1  christos               error_user "no argument for option -${lfc_optchar}.";
   2132  1.1  christos             fi;
   2133  1.1  christos           else			# rest is the argument
   2134  1.1  christos             list_append lfc_result "-${lfc_optchar}" "${lfc_rest}";
   2135  1.1  christos             lfc_rest='';
   2136  1.1  christos             continue;
   2137  1.1  christos           fi;
   2138  1.1  christos         else
   2139  1.1  christos           error_user "unknown option -${lfc_optchar}.";
   2140  1.1  christos         fi;
   2141  1.1  christos       done;
   2142  1.1  christos       ;;
   2143  1.1  christos     *)
   2144  1.1  christos       # Here, $lfc_arg is not an option, so a file parameter.
   2145  1.1  christos       list_append lfc_fparams "${lfc_arg}";
   2146  1.1  christos 
   2147  1.1  christos       # Ignore the strange POSIX option handling to end option
   2148  1.1  christos       # parsing after the first file name argument.  To reuse it, do
   2149  1.1  christos       # a `break' here if $POSIXLY_CORRECT of `bash' is not empty.
   2150  1.1  christos       # When `bash' is called as `sh' $POSIXLY_CORRECT is set
   2151  1.1  christos       # automatically to `y'.
   2152  1.1  christos       ;;
   2153  1.1  christos     esac;
   2154  1.1  christos   done;
   2155  1.1  christos   list_append lfc_result '--';
   2156  1.1  christos   if obj lfc_fparams is_not_empty
   2157  1.1  christos   then
   2158  1.1  christos     lfc_result="${lfc_result} ${lfc_fparams}";
   2159  1.1  christos   fi;
   2160  1.1  christos   if test "$#" -gt 0
   2161  1.1  christos   then
   2162  1.1  christos     list_append lfc_result "$@";
   2163  1.1  christos   fi;
   2164  1.1  christos   obj lfc_result echo1;
   2165  1.1  christos   eval ${_UNSET} lfc_abbrev;
   2166  1.1  christos   eval ${_UNSET} lfc_fparams;
   2167  1.1  christos   eval ${_UNSET} lfc_short_a;
   2168  1.1  christos   eval ${_UNSET} lfc_short_n;
   2169  1.1  christos   eval ${_UNSET} lfc_long_a;
   2170  1.1  christos   eval ${_UNSET} lfc_long_n;
   2171  1.1  christos   eval ${_UNSET} lfc_result;
   2172  1.1  christos   eval ${_UNSET} lfc_arg;
   2173  1.1  christos   eval ${_UNSET} lfc_opt;
   2174  1.1  christos   eval ${_UNSET} lfc_opt_arg;
   2175  1.1  christos   eval ${_UNSET} lfc_opt_char;
   2176  1.1  christos   eval ${_UNSET} lfc_with_equal;
   2177  1.1  christos   eval ${_UNSET} lfc_rest;
   2178  1.1  christos   eval "${return_ok}";
   2179  1.1  christos } # list_from_cmdline()
   2180  1.1  christos 
   2181  1.1  christos 
   2182  1.1  christos ########################################################################
   2183  1.1  christos # list_from_split (<string> <separator>)
   2184  1.1  christos #
   2185  1.1  christos # In <string>, escape all white space characters and replace each
   2186  1.1  christos # <separator> by space.
   2187  1.1  christos #
   2188  1.1  christos # Arguments: 2: a <string> that is to be split into parts divided by
   2189  1.1  christos #               <separator>
   2190  1.1  christos # Output:    the resulting list string
   2191  1.1  christos #
   2192  1.1  christos # Variable prefix: lfs
   2193  1.1  christos #
   2194  1.1  christos list_from_split()
   2195  1.1  christos {
   2196  1.1  christos   func_check list_from_split = 2 "$@";
   2197  1.1  christos 
   2198  1.1  christos   # precede each space or tab by a backslash `\' (doubled for `sed')
   2199  1.1  christos   lfs_s="$(echo1 "$1" | sed -e 's/\('"${_SPACE_SED}"'\)/\\\1/g')";
   2200  1.1  christos   exit_test;
   2201  1.1  christos 
   2202  1.1  christos   # replace split character of string by the list separator ` ' (space).
   2203  1.1  christos   case "$2" in
   2204  1.1  christos     /)				# cannot use normal `sed' separator
   2205  1.1  christos       echo1 "${lfs_s}" | sed -e 's|'"$2"'| |g';
   2206  1.1  christos       ;;
   2207  1.1  christos     ?)				# use normal `sed' separator
   2208  1.1  christos       echo1 "${lfs_s}" | sed -e 's/'"$2"'/ /g';
   2209  1.1  christos       ;;
   2210  1.1  christos     ??*)
   2211  1.1  christos       error 'list_from_split(): separator must be a single character.';
   2212  1.1  christos       ;;
   2213  1.1  christos   esac;
   2214  1.1  christos   eval ${_UNSET} lfs_s;
   2215  1.1  christos   eval "${return_ok}";
   2216  1.1  christos }
   2217  1.1  christos 
   2218  1.1  christos 
   2219  1.1  christos ########################################################################
   2220  1.1  christos # list_get (<list>)
   2221  1.1  christos #
   2222  1.1  christos # Check whether <list> is a space-separated list of '-quoted elements.
   2223  1.1  christos #
   2224  1.1  christos # If the test fails an error is raised.
   2225  1.1  christos # If the test succeeds the argument is echoed.
   2226  1.1  christos #
   2227  1.1  christos # Testing criteria:
   2228  1.1  christos #   A list has the form "'first' 'second' '...' 'last'".  So it has a
   2229  1.1  christos #   leading and a final quote and the elements are separated by "' '"
   2230  1.1  christos #   constructs.  If these are all removed there should not be any
   2231  1.1  christos #   unescaped single-quotes left.  Watch out for escaped single
   2232  1.1  christos #   quotes; they have the form '\'' (sq bs sq sq).
   2233  1.1  christos 
   2234  1.1  christos # Arguments: 1
   2235  1.1  christos # Output: the argument <list> unchanged, if the check succeeded.
   2236  1.1  christos #
   2237  1.1  christos # Variable prefix: lg
   2238  1.1  christos #
   2239  1.1  christos list_get()
   2240  1.1  christos {
   2241  1.1  christos   func_check list_get = 1 "$@";
   2242  1.1  christos   eval lg_list='"${'$1'}"';
   2243  1.1  christos   # remove leading and final space characters
   2244  1.1  christos   lg_list="$(echo1 "${lg_list}" | sed -e '
   2245  1.1  christos s/^'"${_SPACE_SED}"'*//
   2246  1.1  christos s/'"${_SPACE_SED}"'*$//
   2247  1.1  christos ')";
   2248  1.1  christos   exit_test;
   2249  1.1  christos   case "${lg_list}" in
   2250  1.1  christos   '')
   2251  1.1  christos     eval ${_UNSET} lg_list;
   2252  1.1  christos     eval "${return_ok}";
   2253  1.1  christos     ;;
   2254  1.1  christos   \'*\')
   2255  1.1  christos     obj lg_list echo1;
   2256  1.1  christos     eval ${_UNSET} lg_list;
   2257  1.1  christos     eval "${return_ok}";
   2258  1.1  christos     ;;
   2259  1.1  christos   *)
   2260  1.1  christos     error "list_get(): bad list: $1"
   2261  1.1  christos     ;;
   2262  1.1  christos   esac;
   2263  1.1  christos   eval ${_UNSET} lg_list;
   2264  1.1  christos   eval "${return_ok}";
   2265  1.1  christos }
   2266  1.1  christos 
   2267  1.1  christos 
   2268  1.1  christos ########################################################################
   2269  1.1  christos # list_has (<var_name> <element>)
   2270  1.1  christos #
   2271  1.1  christos # Test whether the list <var_name> has the element <element>.
   2272  1.1  christos #
   2273  1.1  christos # Arguments: 2
   2274  1.1  christos #   <var_name>: a variable name for a list of single-quoted elements
   2275  1.1  christos #   <element>:  some sequence of characters.
   2276  1.1  christos #
   2277  1.1  christos # Variable prefix: lh
   2278  1.1  christos #
   2279  1.1  christos list_has()
   2280  1.1  christos {
   2281  1.1  christos   func_check list_has = 2 "$@";
   2282  1.1  christos   eval lh_list='"${'$1'}"';
   2283  1.1  christos   if obj lh_list is_empty
   2284  1.1  christos   then
   2285  1.1  christos     eval "${_UNSET}" lh_list;
   2286  1.1  christos     eval "${return_no}";
   2287  1.1  christos   fi;
   2288  1.1  christos   case "$2" in
   2289  1.1  christos     \'*\')  lh_element=" $2 "; ;;
   2290  1.1  christos     *)      lh_element=" '$2' "; ;;
   2291  1.1  christos   esac;
   2292  1.1  christos   if string_contains " ${lh_list} " "${lh_element}"
   2293  1.1  christos   then
   2294  1.1  christos     eval "${_UNSET}" lh_list;
   2295  1.1  christos     eval "${_UNSET}" lh_element;
   2296  1.1  christos     eval "${return_yes}";
   2297  1.1  christos   else
   2298  1.1  christos     eval "${_UNSET}" lh_list;
   2299  1.1  christos     eval "${_UNSET}" lh_element;
   2300  1.1  christos     eval "${return_no}";
   2301  1.1  christos   fi;
   2302  1.1  christos }
   2303  1.1  christos 
   2304  1.1  christos 
   2305  1.1  christos ########################################################################
   2306  1.1  christos # list_has_abbrev (<var_name> <abbrev>)
   2307  1.1  christos #
   2308  1.1  christos # Test whether the list <var_name> has an element starting with <abbrev>.
   2309  1.1  christos #
   2310  1.1  christos # Arguments: 2
   2311  1.1  christos #   <var_name>: a variable name for a list of single-quoted elements
   2312  1.1  christos #   <abbrev>:   some sequence of characters.
   2313  1.1  christos #
   2314  1.1  christos # Variable prefix: lha
   2315  1.1  christos #
   2316  1.1  christos list_has_abbrev()
   2317  1.1  christos {
   2318  1.1  christos   func_check list_has_abbrev = 2 "$@";
   2319  1.1  christos   eval lha_list='"${'$1'}"';
   2320  1.1  christos   if obj lha_list is_empty
   2321  1.1  christos   then
   2322  1.1  christos     eval "${_UNSET}" lha_list;
   2323  1.1  christos     eval "${return_no}";
   2324  1.1  christos   fi;
   2325  1.1  christos   case "$2" in
   2326  1.1  christos     \'*)
   2327  1.1  christos       lha_element="$(echo1 "$2" | sed -e 's/'"${_SQ}"'$//')";
   2328  1.1  christos       exit_test;
   2329  1.1  christos       ;;
   2330  1.1  christos     *) lha_element="'$2"; ;;
   2331  1.1  christos   esac;
   2332  1.1  christos   if string_contains " ${lha_list}" " ${lha_element}"
   2333  1.1  christos   then
   2334  1.1  christos     eval "${_UNSET}" lha_list;
   2335  1.1  christos     eval "${_UNSET}" lha_element;
   2336  1.1  christos     eval "${return_yes}";
   2337  1.1  christos   else
   2338  1.1  christos     eval "${_UNSET}" lha_list;
   2339  1.1  christos     eval "${_UNSET}" lha_element;
   2340  1.1  christos     eval "${return_no}";
   2341  1.1  christos   fi;
   2342  1.1  christos   eval "${return_ok}";
   2343  1.1  christos }
   2344  1.1  christos 
   2345  1.1  christos 
   2346  1.1  christos ########################################################################
   2347  1.1  christos # list_has_not (<list> <element>)
   2348  1.1  christos #
   2349  1.1  christos # Test whether <list> has no <element>.
   2350  1.1  christos #
   2351  1.1  christos # Arguments: 2
   2352  1.1  christos #   <list>:    a space-separated list of single-quoted elements.
   2353  1.1  christos #   <element>: some sequence of characters.
   2354  1.1  christos #
   2355  1.1  christos # Variable prefix: lhn
   2356  1.1  christos #
   2357  1.1  christos list_has_not()
   2358  1.1  christos {
   2359  1.1  christos   func_check list_has_not = 2 "$@";
   2360  1.1  christos   eval lhn_list='"${'$1'}"';
   2361  1.1  christos   if obj lhn_list is_empty
   2362  1.1  christos   then
   2363  1.1  christos     eval "${_UNSET}" lhn_list;
   2364  1.1  christos     eval "${return_yes}";
   2365  1.1  christos   fi;
   2366  1.1  christos   case "$2" in
   2367  1.1  christos     \'*\') lhn_element=" $2 "; ;;
   2368  1.1  christos     *)     lhn_element=" '$2' "; ;;
   2369  1.1  christos   esac;
   2370  1.1  christos   if string_contains " ${lhn_list} " "${lhn_element}"
   2371  1.1  christos   then
   2372  1.1  christos     eval "${_UNSET}" lhn_list;
   2373  1.1  christos     eval "${_UNSET}" lhn_element;
   2374  1.1  christos     eval "${return_no}";
   2375  1.1  christos   else
   2376  1.1  christos     eval "${_UNSET}" lhn_list;
   2377  1.1  christos     eval "${_UNSET}" lhn_element;
   2378  1.1  christos     eval "${return_yes}";
   2379  1.1  christos   fi;
   2380  1.1  christos }
   2381  1.1  christos 
   2382  1.1  christos 
   2383  1.1  christos ########################################################################
   2384  1.1  christos # list_single_from_abbrev (<list> <abbrev>)
   2385  1.1  christos #
   2386  1.1  christos # Check whether the list has an element starting with <abbrev>.  If
   2387  1.1  christos # there are more than a single element an error is created.
   2388  1.1  christos #
   2389  1.1  christos # Arguments: 2
   2390  1.1  christos #   <list>:   a variable name for a list of single-quoted elements
   2391  1.1  christos #   <abbrev>: some sequence of characters.
   2392  1.1  christos #
   2393  1.1  christos # Output: the found element.
   2394  1.1  christos #
   2395  1.1  christos # Variable prefix: lsfa
   2396  1.1  christos #
   2397  1.1  christos list_single_from_abbrev()
   2398  1.1  christos {
   2399  1.1  christos   func_check list_single_from_abbrev = 2 "$@";
   2400  1.1  christos   eval lsfa_list='"${'$1'}"';
   2401  1.1  christos   if obj lsfa_list is_empty
   2402  1.1  christos   then
   2403  1.1  christos     eval "${_UNSET}" lsfa_list;
   2404  1.1  christos     eval "${return_no}";
   2405  1.1  christos   fi;
   2406  1.1  christos   lsfa_abbrev="$2";
   2407  1.1  christos   if list_has lsfa_list "${lsfa_abbrev}"
   2408  1.1  christos   then
   2409  1.1  christos     obj lsfa_abbrev echo1;
   2410  1.1  christos     eval "${_UNSET}" lsfa_abbrev;
   2411  1.1  christos     eval "${_UNSET}" lsfa_list;
   2412  1.1  christos     eval "${return_yes}";
   2413  1.1  christos   fi;
   2414  1.1  christos   if list_has_abbrev lsfa_list "${lsfa_abbrev}"
   2415  1.1  christos   then
   2416  1.1  christos     lsfa_element='';
   2417  1.1  christos     eval set x "${lsfa_list}";
   2418  1.1  christos     shift;
   2419  1.1  christos     for i
   2420  1.1  christos     do
   2421  1.1  christos       case "$i" in
   2422  1.1  christos       ${lsfa_abbrev}*)
   2423  1.1  christos         if obj lsfa_element is_not_empty
   2424  1.1  christos         then
   2425  1.1  christos           error_user "The abbreviation --${lsfa_abbrev} \
   2426  1.1  christos has multiple options: --${lsfa_element} and --${i}.";
   2427  1.1  christos         fi;
   2428  1.1  christos         lsfa_element="$i";
   2429  1.1  christos         ;;
   2430  1.1  christos       esac;
   2431  1.1  christos     done;
   2432  1.1  christos     obj lsfa_element echo1;
   2433  1.1  christos     eval "${_UNSET}" lsfa_abbrev;
   2434  1.1  christos     eval "${_UNSET}" lsfa_element;
   2435  1.1  christos     eval "${_UNSET}" lsfa_list;
   2436  1.1  christos     eval "${return_yes}";
   2437  1.1  christos   else
   2438  1.1  christos     eval "${_UNSET}" lsfa_abbrev;
   2439  1.1  christos     eval "${_UNSET}" lsfa_element;
   2440  1.1  christos     eval "${_UNSET}" lsfa_list;
   2441  1.1  christos     eval "${return_no}";
   2442  1.1  christos   fi;
   2443  1.1  christos }
   2444  1.1  christos 
   2445  1.1  christos 
   2446  1.1  christos ########################################################################
   2447  1.1  christos landmark '7: man_*()';
   2448  1.1  christos ########################################################################
   2449  1.1  christos 
   2450  1.1  christos ########################################################################
   2451  1.1  christos # man_do_filespec (<filespec>)
   2452  1.1  christos #
   2453  1.1  christos # Print suitable man page(s) for filespec to $_TMP_CAT.
   2454  1.1  christos #
   2455  1.1  christos # Arguments : 2
   2456  1.1  christos #   <filespec>: argument of the form `man:name.section', `man:name',
   2457  1.1  christos #               `man:name(section)', `name.section', `name'.
   2458  1.1  christos #
   2459  1.1  christos # Globals   : $_OPT_ALL
   2460  1.1  christos #
   2461  1.1  christos # Output    : none.
   2462  1.1  christos # Return    : `0' if man page was found, `1' else.
   2463  1.1  christos #
   2464  1.1  christos # Only called from do_fileargs(), checks on $MANPATH and $_MAN_ENABLE
   2465  1.1  christos # are assumed (see man_setup()).
   2466  1.1  christos #
   2467  1.1  christos # Variable prefix: mdf
   2468  1.1  christos #
   2469  1.1  christos man_do_filespec()
   2470  1.1  christos {
   2471  1.1  christos   func_check man_do_filespec = 1 "$@";
   2472  1.1  christos   if obj _MAN_PATH is_empty
   2473  1.1  christos   then
   2474  1.1  christos     eval "${return_bad}";
   2475  1.1  christos   fi;
   2476  1.1  christos   if is_empty "$1"
   2477  1.1  christos   then
   2478  1.1  christos     eval "${return_bad}";
   2479  1.1  christos   fi;
   2480  1.1  christos   mdf_spec="$1";
   2481  1.1  christos   mdf_name='';
   2482  1.1  christos   mdf_section='';
   2483  1.1  christos   case "${mdf_spec}" in
   2484  1.1  christos   */*)				# not a man spec with containing '/'
   2485  1.1  christos     eval ${_UNSET} mdf_got_one;
   2486  1.1  christos     eval ${_UNSET} mdf_name;
   2487  1.1  christos     eval ${_UNSET} mdf_section;
   2488  1.1  christos     eval ${_UNSET} mdf_spec;
   2489  1.1  christos     eval "${return_bad}";
   2490  1.1  christos     ;;
   2491  1.1  christos   man:?*\(?*\))			# man:name(section)
   2492  1.1  christos     mdf_name="$(echo1 "${mdf_spec}" \
   2493  1.1  christos                 | sed -e 's/^man:\(..*\)(\(..*\))$/\1/')";
   2494  1.1  christos     mdf_section="$(echo1 "${mdf_spec}" \
   2495  1.1  christos                    | sed -e 's/^man:\(..*\)(\(..*\))$/\2/')";
   2496  1.1  christos     exit_test;
   2497  1.1  christos     ;;
   2498  1.1  christos   man:?*.${_MAN_AUTO_SEC_CHARS}) # man:name.section
   2499  1.1  christos     mdf_name="$(echo1 "${mdf_spec}" \
   2500  1.1  christos                 | sed -e 's/^man:\(..*\)\..$/\1/')";
   2501  1.1  christos     mdf_section="$(echo1 "${mdf_spec}" \
   2502  1.1  christos                    | sed -e 's/^.*\(.\)$/\1/')";
   2503  1.1  christos     exit_test;
   2504  1.1  christos     ;;
   2505  1.1  christos   man:?*)			# man:name
   2506  1.1  christos     mdf_name="$(echo1 "${mdf_spec}" | sed -e 's/^man://')";
   2507  1.1  christos     exit_test;
   2508  1.1  christos     ;;
   2509  1.1  christos   ?*\(?*\))			# name(section)
   2510  1.1  christos     mdf_name="$(echo1 "${mdf_spec}" \
   2511  1.1  christos                 | sed -e 's/^\(..*\)(\(..*\))$/\1/')";
   2512  1.1  christos     mdf_section="$(echo1 "${mdf_spec}" \
   2513  1.1  christos                    | sed -e 's/^\(..*\)(\(..*\))$/\2/')";
   2514  1.1  christos     exit_test;
   2515  1.1  christos     ;;
   2516  1.1  christos   ?*.${_MAN_AUTO_SEC_CHARS})	# name.section
   2517  1.1  christos     mdf_name="$(echo1 "${mdf_spec}" \
   2518  1.1  christos                 | sed -e 's/^\(..*\)\..$/\1/')";
   2519  1.1  christos     mdf_section="$(echo1 "${mdf_spec}" \
   2520  1.1  christos                    | sed -e 's/^.*\(.\)$/\1/')";
   2521  1.1  christos     exit_test;
   2522  1.1  christos     ;;
   2523  1.1  christos   ?*)
   2524  1.1  christos     mdf_name="${mdf_spec}";
   2525  1.1  christos     ;;
   2526  1.1  christos   esac;
   2527  1.1  christos   if obj mdf_name is_empty
   2528  1.1  christos   then
   2529  1.1  christos     eval ${_UNSET} mdf_got_one;
   2530  1.1  christos     eval ${_UNSET} mdf_name;
   2531  1.1  christos     eval ${_UNSET} mdf_section;
   2532  1.1  christos     eval ${_UNSET} mdf_spec;
   2533  1.1  christos     eval "${return_bad}";
   2534  1.1  christos   fi;
   2535  1.1  christos   mdf_got_one='no';
   2536  1.1  christos   if obj mdf_section is_empty
   2537  1.1  christos   then
   2538  1.1  christos     if obj _OPT_SECTIONS is_empty
   2539  1.1  christos     then
   2540  1.1  christos       eval set x "${_MAN_AUTO_SEC_LIST}";
   2541  1.1  christos     else
   2542  1.1  christos       # use --sections when no section is given to filespec
   2543  1.1  christos       eval set x "$(echo1 "${_OPT_SECTIONS}" | sed -e 's/:/ /g')";
   2544  1.1  christos     fi;
   2545  1.1  christos     shift;
   2546  1.1  christos     for s
   2547  1.1  christos     do
   2548  1.1  christos       mdf_s="$s";
   2549  1.1  christos       if man_search_section "${mdf_name}" "${mdf_s}"
   2550  1.1  christos       then			# found
   2551  1.1  christos         if obj _MAN_ALL is_yes
   2552  1.1  christos         then
   2553  1.1  christos           mdf_got_one='yes';
   2554  1.1  christos         else
   2555  1.1  christos           eval ${_UNSET} mdf_got_one;
   2556  1.1  christos           eval ${_UNSET} mdf_name;
   2557  1.1  christos           eval ${_UNSET} mdf_s;
   2558  1.1  christos           eval ${_UNSET} mdf_section;
   2559  1.1  christos           eval ${_UNSET} mdf_spec;
   2560  1.1  christos           eval "${return_good}";
   2561  1.1  christos         fi;
   2562  1.1  christos       fi;
   2563  1.1  christos     done;
   2564  1.1  christos   else
   2565  1.1  christos     if man_search_section "${mdf_name}" "${mdf_section}"
   2566  1.1  christos     then
   2567  1.1  christos       eval ${_UNSET} mdf_got_one;
   2568  1.1  christos       eval ${_UNSET} mdf_name;
   2569  1.1  christos       eval ${_UNSET} mdf_s;
   2570  1.1  christos       eval ${_UNSET} mdf_section;
   2571  1.1  christos       eval ${_UNSET} mdf_spec;
   2572  1.1  christos       eval "${return_good}";
   2573  1.1  christos     else
   2574  1.1  christos       eval ${_UNSET} mdf_got_one;
   2575  1.1  christos       eval ${_UNSET} mdf_name;
   2576  1.1  christos       eval ${_UNSET} mdf_section;
   2577  1.1  christos       eval ${_UNSET} mdf_spec;
   2578  1.1  christos       eval "${return_bad}";
   2579  1.1  christos     fi;
   2580  1.1  christos   fi;
   2581  1.1  christos   if obj _MAN_ALL is_yes && obj mdf_got_one is_yes
   2582  1.1  christos   then
   2583  1.1  christos     eval ${_UNSET} mdf_got_one;
   2584  1.1  christos     eval ${_UNSET} mdf_name;
   2585  1.1  christos     eval ${_UNSET} mdf_s;
   2586  1.1  christos     eval ${_UNSET} mdf_section;
   2587  1.1  christos     eval ${_UNSET} mdf_spec;
   2588  1.1  christos     eval "${return_good}";
   2589  1.1  christos   fi;
   2590  1.1  christos   eval ${_UNSET} mdf_got_one;
   2591  1.1  christos   eval ${_UNSET} mdf_name;
   2592  1.1  christos   eval ${_UNSET} mdf_s;
   2593  1.1  christos   eval ${_UNSET} mdf_section;
   2594  1.1  christos   eval ${_UNSET} mdf_spec;
   2595  1.1  christos   eval "${return_bad}";
   2596  1.1  christos } # man_do_filespec()
   2597  1.1  christos 
   2598  1.1  christos 
   2599  1.1  christos ########################################################################
   2600  1.1  christos # man_register_file (<file> <name> [<section>])
   2601  1.1  christos #
   2602  1.1  christos # Write a found man page file and register the title element.
   2603  1.1  christos #
   2604  1.1  christos # Arguments: 1, 2, or 3; maybe empty
   2605  1.1  christos # Output: none
   2606  1.1  christos #
   2607  1.1  christos man_register_file()
   2608  1.1  christos {
   2609  1.1  christos   func_check man_register_file '>=' 2 "$@";
   2610  1.1  christos   case "$#" in
   2611  1.1  christos     2|3) do_nothing; ;;
   2612  1.1  christos     *)
   2613  1.1  christos       error "man_register_file() expects 2 or 3 arguments.";
   2614  1.1  christos       ;;
   2615  1.1  christos   esac;
   2616  1.1  christos   if is_empty "$1"
   2617  1.1  christos   then
   2618  1.1  christos     error 'man_register_file(): file name is empty';
   2619  1.1  christos   fi;
   2620  1.1  christos   to_tmp "$1";
   2621  1.1  christos   case "$#" in
   2622  1.1  christos     2)
   2623  1.1  christos        register_title "man:$2";
   2624  1.1  christos        eval "${return_ok}";
   2625  1.1  christos        ;;
   2626  1.1  christos     3)
   2627  1.1  christos        register_title "$2.$3";
   2628  1.1  christos        eval "${return_ok}";
   2629  1.1  christos        ;;
   2630  1.1  christos   esac;
   2631  1.1  christos   eval "${return_ok}";
   2632  1.1  christos }
   2633  1.1  christos 
   2634  1.1  christos 
   2635  1.1  christos ########################################################################
   2636  1.1  christos # man_search_section (<name> <section>)
   2637  1.1  christos #
   2638  1.1  christos # Retrieve man pages.
   2639  1.1  christos #
   2640  1.1  christos # Arguments : 2
   2641  1.1  christos # Globals   : $_MAN_PATH, $_MAN_EXT
   2642  1.1  christos # Return    : 0 if found, 1 otherwise
   2643  1.1  christos #
   2644  1.1  christos # Variable prefix: mss
   2645  1.1  christos #
   2646  1.1  christos man_search_section()
   2647  1.1  christos {
   2648  1.1  christos   func_check man_search_section = 2 "$@";
   2649  1.1  christos   if obj _MAN_PATH is_empty
   2650  1.1  christos   then
   2651  1.1  christos     eval "${return_bad}";
   2652  1.1  christos   fi;
   2653  1.1  christos   if is_empty "$1"
   2654  1.1  christos   then
   2655  1.1  christos     eval "${return_bad}";
   2656  1.1  christos   fi;
   2657  1.1  christos   if is_empty "$2"
   2658  1.1  christos   then
   2659  1.1  christos     eval "${return_bad}";
   2660  1.1  christos   fi;
   2661  1.1  christos   mss_name="$1";
   2662  1.1  christos   mss_section="$2";
   2663  1.1  christos   eval set x "$(path_split "${_MAN_PATH}")";
   2664  1.1  christos   exit_test;
   2665  1.1  christos   shift;
   2666  1.1  christos   mss_got_one='no';
   2667  1.1  christos   if obj _MAN_EXT is_empty
   2668  1.1  christos   then
   2669  1.1  christos     for d
   2670  1.1  christos     do
   2671  1.1  christos       mss_dir="$(dirname_append "$d" "man${mss_section}")";
   2672  1.1  christos       exit_test;
   2673  1.1  christos       if obj mss_dir is_dir
   2674  1.1  christos       then
   2675  1.1  christos         mss_prefix="$(\
   2676  1.1  christos           dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
   2677  1.1  christos         if obj _OPT_WHATIS is_yes
   2678  1.1  christos         then
   2679  1.1  christos           mss_files="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
   2680  1.1  christos                        sed -e '\| found|s|.*||'
   2681  1.1  christos                        )";
   2682  1.1  christos         else
   2683  1.1  christos           mss_files="$(eval ls "'${mss_prefix}'"'*' 2>${_NULL_DEV} |
   2684  1.1  christos                        sed -e '\| found|s|.*||'
   2685  1.1  christos                        )";
   2686  1.1  christos         fi;
   2687  1.1  christos         exit_test;
   2688  1.1  christos         if obj mss_files is_not_empty
   2689  1.1  christos         then
   2690  1.1  christos           # for f in $mss_files
   2691  1.1  christos           for f in $(eval set x ${mss_files}; shift; echo1 "$@")
   2692  1.1  christos           do
   2693  1.1  christos             exit_test;
   2694  1.1  christos             mss_f="$f";
   2695  1.1  christos             if obj mss_f is_file
   2696  1.1  christos             then
   2697  1.1  christos               if is_yes "${mss_got_one}"
   2698  1.1  christos               then
   2699  1.1  christos                 register_file "${mss_f}";
   2700  1.1  christos               elif obj _MAN_ALL is_yes
   2701  1.1  christos               then
   2702  1.1  christos                 man_register_file "${mss_f}" "${mss_name}";
   2703  1.1  christos               else
   2704  1.1  christos                 man_register_file "${mss_f}" "${mss_name}" "${mss_section}";
   2705  1.1  christos                 eval ${_UNSET} mss_dir;
   2706  1.1  christos                 eval ${_UNSET} mss_ext;
   2707  1.1  christos                 eval ${_UNSET} mss_f;
   2708  1.1  christos                 eval ${_UNSET} mss_files;
   2709  1.1  christos                 eval ${_UNSET} mss_got_one;
   2710  1.1  christos                 eval ${_UNSET} mss_name;
   2711  1.1  christos                 eval ${_UNSET} mss_prefix;
   2712  1.1  christos                 eval ${_UNSET} mss_section;
   2713  1.1  christos                 eval "${return_good}";
   2714  1.1  christos               fi;
   2715  1.1  christos               mss_got_one='yes';
   2716  1.1  christos             fi;
   2717  1.1  christos           done;
   2718  1.1  christos         fi;
   2719  1.1  christos       fi;
   2720  1.1  christos     done;
   2721  1.1  christos   else
   2722  1.1  christos     mss_ext="${_MAN_EXT}";
   2723  1.1  christos     # check for directory name having trailing extension
   2724  1.1  christos     for d
   2725  1.1  christos     do
   2726  1.1  christos       mss_dir="$(dirname_append $d man${mss_section}${mss_ext})";
   2727  1.1  christos       exit_test;
   2728  1.1  christos       if obj mss_dir is_dir
   2729  1.1  christos       then
   2730  1.1  christos         mss_prefix=\
   2731  1.1  christos           "$(dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
   2732  1.1  christos         mss_files="$( eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
   2733  1.1  christos                      sed -e '\|not found|s|.*||'
   2734  1.1  christos                      )";
   2735  1.1  christos         exit_test;
   2736  1.1  christos         if obj mss_files is_not_empty
   2737  1.1  christos         then
   2738  1.1  christos           # for f in $mss_files
   2739  1.1  christos           for f in $(eval set x ${mss_files}; shift; echo1 "$@")
   2740  1.1  christos           do
   2741  1.1  christos             mss_f="$f";
   2742  1.1  christos             if obj mss_f is_file
   2743  1.1  christos             then
   2744  1.1  christos               if is_yes "${mss_got_one}"
   2745  1.1  christos               then
   2746  1.1  christos                 register_file "${mss_f}";
   2747  1.1  christos               elif obj _MAN_ALL is_yes
   2748  1.1  christos               then
   2749  1.1  christos                 man_register_file "${mss_f}" "${mss_name}";
   2750  1.1  christos               else
   2751  1.1  christos                 man_register_file "${mss_f}" "${mss_name}" "${mss_section}";
   2752  1.1  christos                 eval ${_UNSET} mss_dir;
   2753  1.1  christos                 eval ${_UNSET} mss_ext;
   2754  1.1  christos                 eval ${_UNSET} mss_f;
   2755  1.1  christos                 eval ${_UNSET} mss_files;
   2756  1.1  christos                 eval ${_UNSET} mss_got_one;
   2757  1.1  christos                 eval ${_UNSET} mss_name;
   2758  1.1  christos                 eval ${_UNSET} mss_prefix;
   2759  1.1  christos                 eval ${_UNSET} mss_section;
   2760  1.1  christos                 eval "${return_good}";
   2761  1.1  christos               fi;
   2762  1.1  christos               mss_got_one='yes';
   2763  1.1  christos             fi;
   2764  1.1  christos           done;
   2765  1.1  christos         fi;
   2766  1.1  christos       fi;
   2767  1.1  christos     done;
   2768  1.1  christos     # check for files with extension in directories without extension
   2769  1.1  christos     for d
   2770  1.1  christos     do
   2771  1.1  christos       mss_dir="$(dirname_append "$d" "man${mss_section}")";
   2772  1.1  christos       exit_test;
   2773  1.1  christos       if obj mss_dir is_dir
   2774  1.1  christos       then
   2775  1.1  christos         mss_prefix="$(dirname_append "${mss_dir}" \
   2776  1.1  christos                         "${mss_name}.${mss_section}${mss_ext}")";
   2777  1.1  christos         mss_files="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
   2778  1.1  christos                      sed -e '\|not found|s|.*||'
   2779  1.1  christos                      )";
   2780  1.1  christos         exit_test;
   2781  1.1  christos         if obj mss_files is_not_empty
   2782  1.1  christos         then
   2783  1.1  christos           # for f in $mss_files
   2784  1.1  christos           for f in $(eval set x ${mss_files}; shift; echo1 "$@")
   2785  1.1  christos           do
   2786  1.1  christos             mss_f="$f";
   2787  1.1  christos             if obj mss_f is_file
   2788  1.1  christos             then
   2789  1.1  christos               if is_yes "${mss_got_one}"
   2790  1.1  christos               then
   2791  1.1  christos                 register_file "${mss_f}";
   2792  1.1  christos               elif obj _MAN_ALL is_yes
   2793  1.1  christos               then
   2794  1.1  christos                 man_register_file "${mss_f}" "${mss_name}";
   2795  1.1  christos               else
   2796  1.1  christos                 man_register_file "${mss_f}" "${mss_name}" "${mss_section}";
   2797  1.1  christos                 eval ${_UNSET} mss_dir;
   2798  1.1  christos                 eval ${_UNSET} mss_ext;
   2799  1.1  christos                 eval ${_UNSET} mss_f;
   2800  1.1  christos                 eval ${_UNSET} mss_files;
   2801  1.1  christos                 eval ${_UNSET} mss_got_one;
   2802  1.1  christos                 eval ${_UNSET} mss_name;
   2803  1.1  christos                 eval ${_UNSET} mss_prefix;
   2804  1.1  christos                 eval ${_UNSET} mss_section;
   2805  1.1  christos                 eval "${return_good}";
   2806  1.1  christos               fi;
   2807  1.1  christos               mss_got_one='yes';
   2808  1.1  christos             fi;
   2809  1.1  christos           done;
   2810  1.1  christos         fi;
   2811  1.1  christos       fi;
   2812  1.1  christos     done;
   2813  1.1  christos   fi;
   2814  1.1  christos   if obj _MAN_ALL is_yes && is_yes "${mss_got_one}"
   2815  1.1  christos   then
   2816  1.1  christos     eval ${_UNSET} mss_dir;
   2817  1.1  christos     eval ${_UNSET} mss_ext;
   2818  1.1  christos     eval ${_UNSET} mss_f;
   2819  1.1  christos     eval ${_UNSET} mss_files;
   2820  1.1  christos     eval ${_UNSET} mss_got_one;
   2821  1.1  christos     eval ${_UNSET} mss_name;
   2822  1.1  christos     eval ${_UNSET} mss_prefix;
   2823  1.1  christos     eval ${_UNSET} mss_section;
   2824  1.1  christos     eval "${return_good}";
   2825  1.1  christos   fi;
   2826  1.1  christos   eval ${_UNSET} mss_dir;
   2827  1.1  christos   eval ${_UNSET} mss_ext;
   2828  1.1  christos   eval ${_UNSET} mss_f;
   2829  1.1  christos   eval ${_UNSET} mss_files;
   2830  1.1  christos   eval ${_UNSET} mss_got_one;
   2831  1.1  christos   eval ${_UNSET} mss_name;
   2832  1.1  christos   eval ${_UNSET} mss_prefix;
   2833  1.1  christos   eval ${_UNSET} mss_section;
   2834  1.1  christos   eval "${return_bad}";
   2835  1.1  christos } # man_search_section()
   2836  1.1  christos 
   2837  1.1  christos 
   2838  1.1  christos ########################################################################
   2839  1.1  christos # man_setup ()
   2840  1.1  christos #
   2841  1.1  christos # Setup the variables $_MAN_* needed for man page searching.
   2842  1.1  christos #
   2843  1.1  christos # Globals:
   2844  1.1  christos #   in:     $_OPT_*, $_MANOPT_*, $LANG, $LC_MESSAGES, $LC_ALL,
   2845  1.1  christos #           $MANPATH, $MANROFFSEQ, $MANSEC, $PAGER, $SYSTEM, $MANOPT.
   2846  1.1  christos #   out:    $_MAN_PATH, $_MAN_LANG, $_MAN_SYS, $_MAN_LANG, $_MAN_LANG2,
   2847  1.1  christos #           $_MAN_SEC, $_MAN_ALL
   2848  1.1  christos #   in/out: $_MAN_ENABLE
   2849  1.1  christos #
   2850  1.1  christos # The precedence for the variables related to `man' is that of GNU
   2851  1.1  christos # `man', i.e.
   2852  1.1  christos #
   2853  1.1  christos # $LANG; overridden by
   2854  1.1  christos # $LC_MESSAGES; overridden by
   2855  1.1  christos # $LC_ALL; this has the same precedence as
   2856  1.1  christos # $MANPATH, $MANROFFSEQ, $MANSEC, $PAGER, $SYSTEM; overridden by
   2857  1.1  christos # $MANOPT; overridden by
   2858  1.1  christos # the groffer command line options.
   2859  1.1  christos #
   2860  1.1  christos # Variable prefix: ms
   2861  1.1  christos #
   2862  1.1  christos man_setup()
   2863  1.1  christos {
   2864  1.1  christos   func_check main_man_setup = 0 "$@";
   2865  1.1  christos 
   2866  1.1  christos   if obj _MAN_IS_SETUP is_yes
   2867  1.1  christos   then
   2868  1.1  christos     eval "${return_ok}";
   2869  1.1  christos   fi;
   2870  1.1  christos   _MAN_IS_SETUP='yes';
   2871  1.1  christos 
   2872  1.1  christos   if obj _MAN_ENABLE is_not_yes
   2873  1.1  christos   then
   2874  1.1  christos     eval "${return_ok}";
   2875  1.1  christos   fi;
   2876  1.1  christos 
   2877  1.1  christos   # determine basic path for man pages
   2878  1.1  christos   _MAN_PATH="$(get_first_essential \
   2879  1.1  christos                "${_OPT_MANPATH}" "${_MANOPT_PATH}" "${MANPATH}")";
   2880  1.1  christos   exit_test;
   2881  1.1  christos   if obj _MAN_PATH is_empty
   2882  1.1  christos   then
   2883  1.1  christos     manpath_set_from_path;
   2884  1.1  christos   else
   2885  1.1  christos     _MAN_PATH="$(path_clean "${_MAN_PATH}")";
   2886  1.1  christos     exit_test;
   2887  1.1  christos   fi;
   2888  1.1  christos   if obj _MAN_PATH is_empty
   2889  1.1  christos   then
   2890  1.1  christos     if is_prog 'manpath'
   2891  1.1  christos     then
   2892  1.1  christos       _MAN_PATH="$(manpath 2>${_NULL_DEV})"; # not always available
   2893  1.1  christos       exit_test;
   2894  1.1  christos     fi;
   2895  1.1  christos   fi;
   2896  1.1  christos   if obj _MAN_PATH is_empty
   2897  1.1  christos   then
   2898  1.1  christos     _MAN_ENABLE="no";
   2899  1.1  christos     eval "${return_ok}";
   2900  1.1  christos   fi;
   2901  1.1  christos 
   2902  1.1  christos   _MAN_ALL="$(get_first_essential "${_OPT_ALL}" "${_MANOPT_ALL}")";
   2903  1.1  christos   exit_test;
   2904  1.1  christos   if obj _MAN_ALL is_empty
   2905  1.1  christos   then
   2906  1.1  christos     _MAN_ALL='no';
   2907  1.1  christos   fi;
   2908  1.1  christos 
   2909  1.1  christos   _MAN_SYS="$(get_first_essential \
   2910  1.1  christos               "${_OPT_SYSTEMS}" "${_MANOPT_SYS}" "${SYSTEM}")";
   2911  1.1  christos   ms_lang="$(get_first_essential \
   2912  1.1  christos            "${_OPT_LANG}" "${LC_ALL}" "${LC_MESSAGES}" "${LANG}")";
   2913  1.1  christos   exit_test;
   2914  1.1  christos   case "${ms_lang}" in
   2915  1.1  christos     C|POSIX)
   2916  1.1  christos       _MAN_LANG="";
   2917  1.1  christos       _MAN_LANG2="";
   2918  1.1  christos       ;;
   2919  1.1  christos     ?)
   2920  1.1  christos       _MAN_LANG="${ms_lang}";
   2921  1.1  christos       _MAN_LANG2="";
   2922  1.1  christos       ;;
   2923  1.1  christos     *)
   2924  1.1  christos       _MAN_LANG="${ms_lang}";
   2925  1.1  christos       # get first two characters of $ms_lang
   2926  1.1  christos       _MAN_LANG2="$(echo1 "${ms_lang}" | sed -e 's/^\(..\).*$/\1/')";
   2927  1.1  christos       exit_test;
   2928  1.1  christos       ;;
   2929  1.1  christos   esac;
   2930  1.1  christos   # from now on, use only $_LANG, forget about $_OPT_LANG, $LC_*.
   2931  1.1  christos 
   2932  1.1  christos   manpath_add_lang_sys;		# this is very slow
   2933  1.1  christos 
   2934  1.1  christos   _MAN_SEC="$(get_first_essential \
   2935  1.1  christos               "${_OPT_SECT}" "${_MANOPT_SEC}" "${MANSEC}")";
   2936  1.1  christos   exit_test;
   2937  1.1  christos   if obj _MAN_PATH is_empty
   2938  1.1  christos   then
   2939  1.1  christos     _MAN_ENABLE="no";
   2940  1.1  christos     eval ${_UNSET} ms_lang;
   2941  1.1  christos     eval "${return_ok}";
   2942  1.1  christos   fi;
   2943  1.1  christos 
   2944  1.1  christos   _MAN_EXT="$(get_first_essential \
   2945  1.1  christos               "${_OPT_EXTENSION}" "${_MANOPT_EXTENSION}")";
   2946  1.1  christos   exit_test;
   2947  1.1  christos   eval ${_UNSET} ms_lang;
   2948  1.1  christos   eval "${return_ok}";
   2949  1.1  christos } # man_setup()
   2950  1.1  christos 
   2951  1.1  christos 
   2952  1.1  christos ########################################################################
   2953  1.1  christos landmark '8: manpath_*()';
   2954  1.1  christos ########################################################################
   2955  1.1  christos 
   2956  1.1  christos ########################################################################
   2957  1.1  christos # manpath_add_lang_sys ()
   2958  1.1  christos #
   2959  1.1  christos # Add language and operating system specific directories to man path.
   2960  1.1  christos #
   2961  1.1  christos # Arguments : 0
   2962  1.1  christos # Output    : none
   2963  1.1  christos # Globals:
   2964  1.1  christos #   in:     $_MAN_SYS: has the form `os1,os2,...', a comma separated
   2965  1.1  christos #             list of names of operating systems.
   2966  1.1  christos #           $_MAN_LANG and $_MAN_LANG2: each a single name
   2967  1.1  christos #   in/out: $_MAN_PATH: has the form `dir1:dir2:...', a colon
   2968  1.1  christos #             separated list of directories.
   2969  1.1  christos #
   2970  1.1  christos # Variable prefix: mals
   2971  1.1  christos #
   2972  1.1  christos manpath_add_lang_sys()
   2973  1.1  christos {
   2974  1.1  christos   func_check manpath_add_lang_sys = 0 "$@";
   2975  1.1  christos   if obj _MAN_PATH is_empty
   2976  1.1  christos   then
   2977  1.1  christos     eval "${return_ok}";
   2978  1.1  christos   fi;
   2979  1.1  christos   # twice test both sys and lang
   2980  1.1  christos   eval set x "$(path_split "${_MAN_PATH}")";
   2981  1.1  christos   shift;
   2982  1.1  christos   exit_test;
   2983  1.1  christos   mals_mp='';
   2984  1.1  christos   for p
   2985  1.1  christos   do				# loop on man path directories
   2986  1.1  christos     mals_mp="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
   2987  1.1  christos     exit_test;
   2988  1.1  christos   done;
   2989  1.1  christos   eval set x "$(path_split "${mals_mp}")";
   2990  1.1  christos   shift;
   2991  1.1  christos   exit_test;
   2992  1.1  christos   for p
   2993  1.1  christos   do				# loop on man path directories
   2994  1.1  christos     mals_mp="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
   2995  1.1  christos     exit_test;
   2996  1.1  christos   done;
   2997  1.1  christos   _MAN_PATH="$(path_chop "${mals_mp}")";
   2998  1.1  christos   exit_test;
   2999  1.1  christos   eval ${_UNSET} mals_mp;
   3000  1.1  christos   eval "${return_ok}";
   3001  1.1  christos }
   3002  1.1  christos 
   3003  1.1  christos 
   3004  1.1  christos # To the directory in $1 append existing sys/lang subdirectories
   3005  1.1  christos # Function is necessary to split the OS list.
   3006  1.1  christos #
   3007  1.1  christos # globals: in: $_MAN_SYS, $_MAN_LANG, $_MAN_LANG2
   3008  1.1  christos # argument: 2: `man_path' and `dir'
   3009  1.1  christos # output: colon-separated path of the retrieved subdirectories
   3010  1.1  christos #
   3011  1.1  christos # Variable prefix: _mals
   3012  1.1  christos #
   3013  1.1  christos _manpath_add_lang_sys_single()
   3014  1.1  christos {
   3015  1.1  christos   func_check _manpath_add_lang_sys_single = 2 "$@";
   3016  1.1  christos   _mals_res="$1";
   3017  1.1  christos   _mals_parent="$2";
   3018  1.1  christos   eval set x "$(list_from_split "${_MAN_SYS}" ',')";
   3019  1.1  christos   shift;
   3020  1.1  christos   exit_test;
   3021  1.1  christos   for d in "$@" "${_MAN_LANG}" "${_MAN_LANG2}"
   3022  1.1  christos   do
   3023  1.1  christos     _mals_dir="$(dirname_append "${_mals_parent}" "$d")";
   3024  1.1  christos     exit_test;
   3025  1.1  christos     if obj _mals_res path_not_contains "${_mals_dir}" && \
   3026  1.1  christos        obj _mals_dir is_dir
   3027  1.1  christos     then
   3028  1.1  christos       _mals_res="${_mals_res}:${_mals_dir}";
   3029  1.1  christos     fi;
   3030  1.1  christos   done;
   3031  1.1  christos   if path_not_contains "${_mals_res}" "${_mals_parent}"
   3032  1.1  christos   then
   3033  1.1  christos     _mals_res="${_mals_res}:${_mals_parent}";
   3034  1.1  christos   fi;
   3035  1.1  christos   path_chop "${_mals_res}";
   3036  1.1  christos   eval ${_UNSET} _mals_dir;
   3037  1.1  christos   eval ${_UNSET} _mals_parent;
   3038  1.1  christos   eval ${_UNSET} _mals_res;
   3039  1.1  christos   eval "${return_ok}";
   3040  1.1  christos }
   3041  1.1  christos 
   3042  1.1  christos # end manpath_add_lang_sys ()
   3043  1.1  christos 
   3044  1.1  christos 
   3045  1.1  christos ########################################################################
   3046  1.1  christos # manpath_set_from_path ()
   3047  1.1  christos #
   3048  1.1  christos # Determine basic search path for man pages from $PATH.
   3049  1.1  christos #
   3050  1.1  christos # Return:    `0' if a valid man path was retrieved.
   3051  1.1  christos # Output:    none
   3052  1.1  christos # Globals:
   3053  1.1  christos #   in:  $PATH
   3054  1.1  christos #   out: $_MAN_PATH
   3055  1.1  christos #
   3056  1.1  christos # Variable prefix: msfp
   3057  1.1  christos #
   3058  1.1  christos manpath_set_from_path()
   3059  1.1  christos {
   3060  1.1  christos   func_check manpath_set_from_path = 0 "$@";
   3061  1.1  christos 
   3062  1.1  christos   msfp_manpath='';
   3063  1.1  christos 
   3064  1.1  christos   # get a basic man path from $PATH
   3065  1.1  christos   if obj PATH is_not_empty
   3066  1.1  christos   then
   3067  1.1  christos     eval set x "$(path_split "${PATH}")";
   3068  1.1  christos     shift;
   3069  1.1  christos     exit_test;
   3070  1.1  christos     for d
   3071  1.1  christos     do
   3072  1.1  christos       # delete the final `/bin' part
   3073  1.1  christos       msfp_base="$(echo1 "$d" | sed -e 's|//*bin/*$||')";
   3074  1.1  christos       exit_test;
   3075  1.1  christos       for e in /share/man /man
   3076  1.1  christos       do
   3077  1.1  christos         msfp_mandir="${msfp_base}$e";
   3078  1.1  christos         if test -d "${msfp_mandir}" && test -r "${msfp_mandir}"
   3079  1.1  christos         then
   3080  1.1  christos           msfp_manpath="${msfp_manpath}:${msfp_mandir}";
   3081  1.1  christos         fi;
   3082  1.1  christos       done;
   3083  1.1  christos     done;
   3084  1.1  christos   fi;
   3085  1.1  christos 
   3086  1.1  christos   # append some default directories
   3087  1.1  christos   for d in /usr/local/share/man /usr/local/man \
   3088  1.1  christos            /usr/share/man /usr/man \
   3089  1.1  christos            /usr/X11R6/man /usr/openwin/man \
   3090  1.1  christos            /opt/share/man /opt/man \
   3091  1.1  christos            /opt/gnome/man /opt/kde/man
   3092  1.1  christos   do
   3093  1.1  christos     msfp_d="$d";
   3094  1.1  christos     if obj msfp_manpath path_not_contains "${msfp_d}" && obj mfsp_d is_dir
   3095  1.1  christos     then
   3096  1.1  christos       msfp_manpath="${msfp_manpath}:${mfsp_d}";
   3097  1.1  christos     fi;
   3098  1.1  christos   done;
   3099  1.1  christos 
   3100  1.1  christos   _MAN_PATH="${msfp_manpath}";
   3101  1.1  christos   eval ${_UNSET} msfp_base;
   3102  1.1  christos   eval ${_UNSET} msfp_d;
   3103  1.1  christos   eval ${_UNSET} msfp_mandir;
   3104  1.1  christos   eval ${_UNSET} msfp_manpath;
   3105  1.1  christos   eval "${return_ok}";
   3106  1.1  christos } # manpath_set_from_path()
   3107  1.1  christos 
   3108  1.1  christos 
   3109  1.1  christos ########################################################################
   3110  1.1  christos landmark '9: obj_*()';
   3111  1.1  christos ########################################################################
   3112  1.1  christos 
   3113  1.1  christos ########################################################################
   3114  1.1  christos # obj (<object> <call_name> <arg>...)
   3115  1.1  christos #
   3116  1.1  christos # This works like a method (object function) call for an object.
   3117  1.1  christos # Run "<call_name> $<object> <arg> ...".
   3118  1.1  christos #
   3119  1.1  christos # The first argument represents an object whose data is given as first
   3120  1.1  christos # argument to <call_name>().
   3121  1.1  christos #
   3122  1.1  christos # Argument: >=2
   3123  1.1  christos #           <object>: variable name
   3124  1.1  christos #           <call_name>: a program or function name
   3125  1.1  christos #
   3126  1.1  christos # Variable prefix: o
   3127  1.1  christos #
   3128  1.1  christos obj()
   3129  1.1  christos {
   3130  1.1  christos   func_check obj '>=' 2 "$@";
   3131  1.1  christos   eval o_arg1='"${'$1'}"';
   3132  1.1  christos   if is_empty "$2"
   3133  1.1  christos   then
   3134  1.1  christos     error "obj(): function name is empty."
   3135  1.1  christos   else
   3136  1.1  christos     o_func="$2";
   3137  1.1  christos   fi;
   3138  1.1  christos   shift;
   3139  1.1  christos   shift;
   3140  1.1  christos   eval "${o_func}"' "${o_arg1}" "$@"';
   3141  1.1  christos   n="$?";
   3142  1.1  christos   eval ${_UNSET} o_arg1;
   3143  1.1  christos   eval ${_UNSET} o_func;
   3144  1.1  christos   eval "${return_var} $n";
   3145  1.1  christos } # obj()
   3146  1.1  christos 
   3147  1.1  christos 
   3148  1.1  christos ########################################################################
   3149  1.1  christos # obj_data (<object>)
   3150  1.1  christos #
   3151  1.1  christos # Print the data of <object>, i.e. the content of $<object>.
   3152  1.1  christos # For possible later extensions.
   3153  1.1  christos #
   3154  1.1  christos # Arguments: 1
   3155  1.1  christos #            <object>: a variable name
   3156  1.1  christos # Output:    the data of <object>
   3157  1.1  christos #
   3158  1.1  christos # Variable prefix: od
   3159  1.1  christos #
   3160  1.1  christos obj_data()
   3161  1.1  christos {
   3162  1.1  christos   func_check obj '=' 1 "$@";
   3163  1.1  christos   if is_empty "$1"
   3164  1.1  christos   then
   3165  1.1  christos     error "obj_data(): object name is empty."
   3166  1.1  christos   fi;
   3167  1.1  christos   eval od_res='"${'$1'}"';
   3168  1.1  christos   obj od_res echo1;
   3169  1.1  christos   eval ${_UNSET} od_res;
   3170  1.1  christos   eval "${return_ok}";
   3171  1.1  christos }
   3172  1.1  christos 
   3173  1.1  christos 
   3174  1.1  christos ########################################################################
   3175  1.1  christos # obj_from_output (<object> <call_name> <arg>...)
   3176  1.1  christos #
   3177  1.1  christos # Run '$<object>="$(<call_name> <arg>...)"' to set the result of a
   3178  1.1  christos # function call to a global variable.
   3179  1.1  christos #
   3180  1.1  christos # Arguments: >=2
   3181  1.1  christos #            <object>: a variable name
   3182  1.1  christos #            <call_name>: the name of a function or program
   3183  1.1  christos #            <arg>: optional argument to <call_name>
   3184  1.1  christos # Output:    none
   3185  1.1  christos #
   3186  1.1  christos # Variable prefix: ofo
   3187  1.1  christos #
   3188  1.1  christos obj_from_output()
   3189  1.1  christos {
   3190  1.1  christos   func_check obj_from_output '>=' 2 "$@";
   3191  1.1  christos   if is_empty "$1"
   3192  1.1  christos   then
   3193  1.1  christos     error "res(): variable name is empty.";
   3194  1.1  christos   elif is_empty "$2"
   3195  1.1  christos   then
   3196  1.1  christos     error "res(): function name is empty."
   3197  1.1  christos   else
   3198  1.1  christos     ofo_result_name="$1";
   3199  1.1  christos   fi;
   3200  1.1  christos   shift;
   3201  1.1  christos   eval "${ofo_result_name}"'="$('"$@"')"';
   3202  1.1  christos   exit_test;
   3203  1.1  christos   eval "${return_ok}";
   3204  1.1  christos }
   3205  1.1  christos 
   3206  1.1  christos 
   3207  1.1  christos ########################################################################
   3208  1.1  christos # obj_set (<object> <data>)
   3209  1.1  christos #
   3210  1.1  christos # Set the data of <object>, i.e. call "$<object>=<data>".
   3211  1.1  christos #
   3212  1.1  christos # Arguments: 2
   3213  1.1  christos #            <object>: a variable name
   3214  1.1  christos #            <data>: a string
   3215  1.1  christos # Output::   none
   3216  1.1  christos #
   3217  1.1  christos obj_set()
   3218  1.1  christos {
   3219  1.1  christos   func_check obj_set '=' 2 "$@";
   3220  1.1  christos   if is_empty "$1"
   3221  1.1  christos   then
   3222  1.1  christos     error "obj_set(): object name is empty."
   3223  1.1  christos   fi;
   3224  1.1  christos   eval "$1"='"$2"';
   3225  1.1  christos   eval "${return_ok}";
   3226  1.1  christos }
   3227  1.1  christos 
   3228  1.1  christos 
   3229  1.1  christos ########################################################################
   3230  1.1  christos # path_chop (<path>)
   3231  1.1  christos #
   3232  1.1  christos # Remove unnecessary colons from path.
   3233  1.1  christos #
   3234  1.1  christos # Argument: 1, a colon separated path.
   3235  1.1  christos # Output:   path without leading, double, or trailing colons.
   3236  1.1  christos #
   3237  1.1  christos path_chop()
   3238  1.1  christos {
   3239  1.1  christos   func_check path_chop = 1 "$@";
   3240  1.1  christos 
   3241  1.1  christos   # replace multiple colons by a single colon `:'
   3242  1.1  christos   # remove leading and trailing colons
   3243  1.1  christos   echo1 "$1" | sed -e '
   3244  1.1  christos s/^:*//
   3245  1.1  christos s/:::*/:/g
   3246  1.1  christos s/:*$//
   3247  1.1  christos ';
   3248  1.1  christos   eval "${return_ok}";
   3249  1.1  christos }
   3250  1.1  christos 
   3251  1.1  christos 
   3252  1.1  christos ########################################################################
   3253  1.1  christos # path_clean (<path>)
   3254  1.1  christos #
   3255  1.1  christos # Remove non-existing directories from a colon-separated list.
   3256  1.1  christos #
   3257  1.1  christos # Argument: 1, a colon separated path.
   3258  1.1  christos # Output:   colon-separated list of existing directories.
   3259  1.1  christos #
   3260  1.1  christos # Variable prefix: pc
   3261  1.1  christos #
   3262  1.1  christos path_clean()
   3263  1.1  christos {
   3264  1.1  christos   func_check path_clean = 1 "$@";
   3265  1.1  christos   if is_not_equal "$#" 1
   3266  1.1  christos   then
   3267  1.1  christos     error 'path_clean() needs 1 argument.';
   3268  1.1  christos   fi;
   3269  1.1  christos   pc_arg="$1";
   3270  1.1  christos   eval set x "$(path_split "${pc_arg}")";
   3271  1.1  christos   exit_test;
   3272  1.1  christos   shift;
   3273  1.1  christos   pc_res="";
   3274  1.1  christos   for i
   3275  1.1  christos   do
   3276  1.1  christos     pc_i="$i";
   3277  1.1  christos     if obj pc_i is_not_empty \
   3278  1.1  christos        && obj pc_res path_not_contains "${pc_i}" \
   3279  1.1  christos        && obj pc_i is_dir
   3280  1.1  christos     then
   3281  1.1  christos       case "${pc_i}" in
   3282  1.1  christos       ?*/)
   3283  1.1  christos         pc_res="${pc_res}$(dirname_chop "${pc_i}")";
   3284  1.1  christos         exit_test;
   3285  1.1  christos         ;;
   3286  1.1  christos       *)
   3287  1.1  christos         pc_res="${pc_res}:${pc_i}";
   3288  1.1  christos         exit_test;
   3289  1.1  christos         ;;
   3290  1.1  christos       esac;
   3291  1.1  christos     fi;
   3292  1.1  christos   done;
   3293  1.1  christos   eval ${_UNSET} pc_arg;
   3294  1.1  christos   eval ${_UNSET} pc_i;
   3295  1.1  christos   eval ${_UNSET} pc_res;
   3296  1.1  christos   if path_chop "${pc_res}"
   3297  1.1  christos   then
   3298  1.1  christos     eval "${return_ok}";
   3299  1.1  christos   else
   3300  1.1  christos     eval "${return_bad}";
   3301  1.1  christos   fi;
   3302  1.1  christos }
   3303  1.1  christos 
   3304  1.1  christos 
   3305  1.1  christos ########################################################################
   3306  1.1  christos # path_contains (<path> <dir>)
   3307  1.1  christos #-
   3308  1.1  christos # Test whether `dir' is contained in `path', a list separated by `:'.
   3309  1.1  christos #
   3310  1.1  christos # Arguments : 2 arguments.
   3311  1.1  christos # Return    : `0' if arg2 is substring of arg1, `1' otherwise.
   3312  1.1  christos #
   3313  1.1  christos path_contains()
   3314  1.1  christos {
   3315  1.1  christos   func_check path_contains = 2 "$@";
   3316  1.1  christos   case ":$1:" in
   3317  1.1  christos     *":$2:"*)
   3318  1.1  christos       eval "${return_yes}";
   3319  1.1  christos       ;;
   3320  1.1  christos     *)
   3321  1.1  christos       eval "${return_no}";
   3322  1.1  christos       ;;
   3323  1.1  christos   esac;
   3324  1.1  christos   eval "${return_ok}";
   3325  1.1  christos }
   3326  1.1  christos 
   3327  1.1  christos 
   3328  1.1  christos ########################################################################
   3329  1.1  christos # path_not_contains (<path> <dir>)
   3330  1.1  christos #
   3331  1.1  christos # Test whether `dir' is not contained in colon separated `path'.
   3332  1.1  christos #
   3333  1.1  christos # Arguments : 2 arguments.
   3334  1.1  christos #
   3335  1.1  christos path_not_contains()
   3336  1.1  christos {
   3337  1.1  christos   func_check path_not_contains = 2 "$@";
   3338  1.1  christos   if path_contains "$1" "$2"
   3339  1.1  christos   then
   3340  1.1  christos     eval "${return_no}";
   3341  1.1  christos   else
   3342  1.1  christos     eval "${return_yes}";
   3343  1.1  christos   fi;
   3344  1.1  christos   eval "${return_ok}";
   3345  1.1  christos }
   3346  1.1  christos 
   3347  1.1  christos 
   3348  1.1  christos ########################################################################
   3349  1.1  christos # path_split (<path>)
   3350  1.1  christos #
   3351  1.1  christos # In `path' escape white space and replace each colon by a space.
   3352  1.1  christos #
   3353  1.1  christos # Arguments: 1: a colon-separated path
   3354  1.1  christos # Output:    the resulting list, process with `eval set'
   3355  1.1  christos #
   3356  1.1  christos path_split()
   3357  1.1  christos {
   3358  1.1  christos   func_check path_split = 1 "$@";
   3359  1.1  christos   list_from_split "$1" ':';
   3360  1.1  christos   eval "${return_ok}";
   3361  1.1  christos }
   3362  1.1  christos 
   3363  1.1  christos 
   3364  1.1  christos ########################################################################
   3365  1.1  christos landmark '10: register_*()';
   3366  1.1  christos ########################################################################
   3367  1.1  christos 
   3368  1.1  christos ########################################################################
   3369  1.1  christos # register_file (<filename>)
   3370  1.1  christos #
   3371  1.1  christos # Write a found file and register the title element.
   3372  1.1  christos #
   3373  1.1  christos # Arguments: 1: a file name
   3374  1.1  christos # Output: none
   3375  1.1  christos #
   3376  1.1  christos register_file()
   3377  1.1  christos {
   3378  1.1  christos   func_check register_file = 1 "$@";
   3379  1.1  christos   if is_empty "$1"
   3380  1.1  christos   then
   3381  1.1  christos     error 'register_file(): file name is empty';
   3382  1.1  christos   fi;
   3383  1.1  christos   if is_equal "$1" '-'
   3384  1.1  christos   then
   3385  1.1  christos     to_tmp "${_TMP_STDIN}";
   3386  1.1  christos     register_title 'stdin';
   3387  1.1  christos   else
   3388  1.1  christos     to_tmp "$1";
   3389  1.1  christos     register_title "$(base_name "$1")";
   3390  1.1  christos     exit_test;
   3391  1.1  christos   fi;
   3392  1.1  christos   eval "${return_ok}";
   3393  1.1  christos } # register_file()
   3394  1.1  christos 
   3395  1.1  christos 
   3396  1.1  christos ########################################################################
   3397  1.1  christos # register_title (<filespec>)
   3398  1.1  christos #
   3399  1.1  christos # Create title element from <filespec> and append to $_REGISTERED_TITLE
   3400  1.1  christos #
   3401  1.1  christos # Globals: $_REGISTERED_TITLE (rw)
   3402  1.1  christos #
   3403  1.1  christos # Variable prefix: rt
   3404  1.1  christos #
   3405  1.1  christos register_title()
   3406  1.1  christos {
   3407  1.1  christos   func_check register_title '=' 1 "$@";
   3408  1.1  christos   if is_empty "$1"
   3409  1.1  christos   then
   3410  1.1  christos     eval "${return_ok}";
   3411  1.1  christos   fi;
   3412  1.1  christos 
   3413  1.1  christos   case "${_REGISTERED_TITLE}" in
   3414  1.1  christos   *\ *\ *\ *)
   3415  1.1  christos     eval "${return_ok}";
   3416  1.1  christos     ;;
   3417  1.1  christos   esac;
   3418  1.1  christos 
   3419  1.1  christos   # remove directory part
   3420  1.1  christos   rt_title="$(base_name "$1")";
   3421  1.1  christos   # replace space characters by `_'
   3422  1.1  christos   rt_title="$(echo1 "${rt_title}" | sed -e 's/[ 	]/_/g')";
   3423  1.1  christos   # remove extension `.bz2'
   3424  1.1  christos   rt_title="$(echo1 "${rt_title}" | sed -e 's/\.bz2$//')";
   3425  1.1  christos   # remove extension `.gz'
   3426  1.1  christos   rt_title="$(echo1 "${rt_title}" | sed -e 's/\.gz$//')";
   3427  1.1  christos   # remove extension `.Z'
   3428  1.1  christos   rt_title="$(echo1 "${rt_title}" | sed -e 's/\.Z$//')";
   3429  1.1  christos   exit_test;
   3430  1.1  christos 
   3431  1.1  christos   if obj rt_title is_empty
   3432  1.1  christos   then
   3433  1.1  christos     eval ${_UNSET} rt_title;
   3434  1.1  christos     eval "${return_ok}";
   3435  1.1  christos   fi;
   3436  1.1  christos   if obj _REGISTERED_TITLE is_empty
   3437  1.1  christos   then
   3438  1.1  christos     _REGISTERED_TITLE="${rt_title}";
   3439  1.1  christos   else
   3440  1.1  christos     _REGISTERED_TITLE="${_REGISTERED_TITLE} ${rt_title}";
   3441  1.1  christos   fi;
   3442  1.1  christos   eval ${_UNSET} rt_title;
   3443  1.1  christos   eval "${return_ok}";
   3444  1.1  christos } # register_title()
   3445  1.1  christos 
   3446  1.1  christos 
   3447  1.1  christos ########################################################################
   3448  1.1  christos # reset ()
   3449  1.1  christos #
   3450  1.1  christos # Reset the variables that can be affected by options to their default.
   3451  1.1  christos #
   3452  1.1  christos #
   3453  1.1  christos # Defined in section `Preset' after the rudimentary shell tests.
   3454  1.1  christos 
   3455  1.1  christos 
   3456  1.1  christos ########################################################################
   3457  1.1  christos # rm_file (<file_name>)
   3458  1.1  christos #
   3459  1.1  christos # Remove file if $_DEBUG_KEEP_FILES allows it.
   3460  1.1  christos #
   3461  1.1  christos # Globals: $_DEBUG_KEEP_FILES
   3462  1.1  christos #
   3463  1.1  christos rm_file()
   3464  1.1  christos {
   3465  1.1  christos   func_check rm_file '=' 1 "$@";
   3466  1.1  christos   if is_file "$1"
   3467  1.1  christos   then
   3468  1.1  christos     rm -f "$1" >${_NULL_DEV} 2>&1;
   3469  1.1  christos   fi;
   3470  1.1  christos   if is_existing "$1"
   3471  1.1  christos   then
   3472  1.1  christos     eval "${return_bad}";
   3473  1.1  christos   else
   3474  1.1  christos     eval "${return_good}";
   3475  1.1  christos   fi;
   3476  1.1  christos }
   3477  1.1  christos 
   3478  1.1  christos 
   3479  1.1  christos ########################################################################
   3480  1.1  christos # rm_file_with_debug (<file_name>)
   3481  1.1  christos #
   3482  1.1  christos # Remove file if $_DEBUG_KEEP_FILES allows it.
   3483  1.1  christos #
   3484  1.1  christos # Globals: $_DEBUG_KEEP_FILES
   3485  1.1  christos #
   3486  1.1  christos rm_file_with_debug()
   3487  1.1  christos {
   3488  1.1  christos   func_check rm_file_with_debug '=' 1 "$@";
   3489  1.1  christos   if obj _DEBUG_KEEP_FILES is_not_yes
   3490  1.1  christos   then
   3491  1.1  christos     if is_file "$1"
   3492  1.1  christos     then
   3493  1.1  christos       rm -f "$1" >${_NULL_DEV} 2>&1;
   3494  1.1  christos     fi;
   3495  1.1  christos   fi;
   3496  1.1  christos   if is_existing "$1"
   3497  1.1  christos   then
   3498  1.1  christos     eval "${return_bad}";
   3499  1.1  christos   else
   3500  1.1  christos     eval "${return_good}";
   3501  1.1  christos   fi;
   3502  1.1  christos }
   3503  1.1  christos 
   3504  1.1  christos 
   3505  1.1  christos ########################################################################
   3506  1.1  christos # rm_tree (<dir_name>)
   3507  1.1  christos #
   3508  1.1  christos # Remove file if $_DEBUG_KEEP_FILES allows it.
   3509  1.1  christos #
   3510  1.1  christos # Globals: $_DEBUG_KEEP_FILES
   3511  1.1  christos #
   3512  1.1  christos rm_tree()
   3513  1.1  christos {
   3514  1.1  christos   func_check rm_tree '=' 1 "$@";
   3515  1.1  christos   if is_existing "$1"
   3516  1.1  christos   then
   3517  1.1  christos     rm -f -r "$1" >${_NULL_DEV} 2>&1;
   3518  1.1  christos   fi; 
   3519  1.1  christos   if is_existing "$1"
   3520  1.1  christos   then
   3521  1.1  christos     eval "${return_bad}";
   3522  1.1  christos   else
   3523  1.1  christos     eval "${return_good}";
   3524  1.1  christos   fi;
   3525  1.1  christos }
   3526  1.1  christos 
   3527  1.1  christos 
   3528  1.1  christos ########################################################################
   3529  1.1  christos # save_stdin ()
   3530  1.1  christos #
   3531  1.1  christos # Store standard input to temporary file (with decompression).
   3532  1.1  christos #
   3533  1.1  christos # Variable prefix: ss
   3534  1.1  christos #
   3535  1.1  christos if obj _HAS_COMPRESSION is_yes
   3536  1.1  christos then
   3537  1.1  christos   save_stdin()
   3538  1.1  christos   {
   3539  1.1  christos     func_check save_stdin '=' 0 "$@";
   3540  1.1  christos     ss_f="${_TMP_DIR}"/INPUT;
   3541  1.1  christos     cat >"${ss_f}";
   3542  1.1  christos     cat_z "${ss_f}" >"${_TMP_STDIN}";
   3543  1.1  christos     rm_file "${ss_f}";
   3544  1.1  christos     eval ${_UNSET} ss_f;
   3545  1.1  christos     eval "${return_ok}";
   3546  1.1  christos   }
   3547  1.1  christos else
   3548  1.1  christos   save_stdin()
   3549  1.1  christos   {
   3550  1.1  christos     func_check save_stdin = 0 "$@";
   3551  1.1  christos     cat >"${_TMP_STDIN}";
   3552  1.1  christos     eval "${return_ok}";
   3553  1.1  christos   }
   3554  1.1  christos fi;
   3555  1.1  christos 
   3556  1.1  christos 
   3557  1.1  christos ########################################################################
   3558  1.1  christos # special_filespec ()
   3559  1.1  christos #
   3560  1.1  christos # Handle special modes like whatis and apropos.
   3561  1.1  christos #
   3562  1.1  christos special_filespec()
   3563  1.1  christos {
   3564  1.1  christos   func_check special_setup '=' 0 "$@";
   3565  1.1  christos   if obj _OPT_APROPOS is_yes
   3566  1.1  christos   then
   3567  1.1  christos     if obj _OPT_WHATIS is_yes
   3568  1.1  christos     then
   3569  1.1  christos       error \
   3570  1.1  christos         'special_setup: $_OPT_APROPOS and $_OPT_WHATIS are both "yes"';
   3571  1.1  christos     fi;
   3572  1.1  christos     apropos_filespec;
   3573  1.1  christos     eval "${return_ok}";
   3574  1.1  christos   fi;
   3575  1.1  christos   if obj _OPT_WHATIS is_yes
   3576  1.1  christos   then
   3577  1.1  christos     whatis_filespec;
   3578  1.1  christos   fi;
   3579  1.1  christos   eval "${return_ok}";
   3580  1.1  christos }
   3581  1.1  christos 
   3582  1.1  christos 
   3583  1.1  christos ########################################################################
   3584  1.1  christos # special_setup ()
   3585  1.1  christos #
   3586  1.1  christos # Handle special modes like whatis and apropos.
   3587  1.1  christos #
   3588  1.1  christos special_setup()
   3589  1.1  christos {
   3590  1.1  christos   func_check special_setup '=' 0 "$@";
   3591  1.1  christos   if obj _OPT_APROPOS is_yes
   3592  1.1  christos   then
   3593  1.1  christos     if obj _OPT_WHATIS is_yes
   3594  1.1  christos     then
   3595  1.1  christos       error \
   3596  1.1  christos         'special_setup: $_OPT_APROPOS and $_OPT_WHATIS are both "yes"';
   3597  1.1  christos     fi;
   3598  1.1  christos     apropos_setup;
   3599  1.1  christos     eval "${return_ok}";
   3600  1.1  christos   fi;
   3601  1.1  christos   if obj _OPT_WHATIS is_yes
   3602  1.1  christos   then
   3603  1.1  christos     whatis_header;
   3604  1.1  christos   fi;  
   3605  1.1  christos   eval "${return_ok}";
   3606  1.1  christos }
   3607  1.1  christos 
   3608  1.1  christos 
   3609  1.1  christos ########################################################################
   3610  1.1  christos landmark '11: stack_*()';
   3611  1.1  christos ########################################################################
   3612  1.1  christos 
   3613  1.1  christos ########################################################################
   3614  1.1  christos # string_contains (<string> <part>)
   3615  1.1  christos #
   3616  1.1  christos # Test whether `part' is contained in `string'.
   3617  1.1  christos #
   3618  1.1  christos # Arguments : 2 text arguments.
   3619  1.1  christos # Return    : `0' if arg2 is substring of arg1, `1' otherwise.
   3620  1.1  christos #
   3621  1.1  christos string_contains()
   3622  1.1  christos {
   3623  1.1  christos   func_check string_contains '=' 2 "$@";
   3624  1.1  christos   case "$1" in
   3625  1.1  christos     *"$2"*)
   3626  1.1  christos       eval "${return_yes}";
   3627  1.1  christos       ;;
   3628  1.1  christos     *)
   3629  1.1  christos       eval "${return_no}";
   3630  1.1  christos       ;;
   3631  1.1  christos   esac;
   3632  1.1  christos   eval "${return_ok}";
   3633  1.1  christos }
   3634  1.1  christos 
   3635  1.1  christos 
   3636  1.1  christos ########################################################################
   3637  1.1  christos # string_not_contains (<string> <part>)
   3638  1.1  christos #
   3639  1.1  christos # Test whether `part' is not substring of `string'.
   3640  1.1  christos #
   3641  1.1  christos # Arguments : 2 text arguments.
   3642  1.1  christos # Return    : `0' if arg2 is substring of arg1, `1' otherwise.
   3643  1.1  christos #
   3644  1.1  christos string_not_contains()
   3645  1.1  christos {
   3646  1.1  christos   func_check string_not_contains '=' 2 "$@";
   3647  1.1  christos   if string_contains "$1" "$2"
   3648  1.1  christos   then
   3649  1.1  christos     eval "${return_no}";
   3650  1.1  christos   else
   3651  1.1  christos     eval "${return_yes}";
   3652  1.1  christos   fi;
   3653  1.1  christos   eval "${return_ok}";
   3654  1.1  christos }
   3655  1.1  christos 
   3656  1.1  christos 
   3657  1.1  christos ########################################################################
   3658  1.1  christos landmark '12: tmp_*()';
   3659  1.1  christos ########################################################################
   3660  1.1  christos 
   3661  1.1  christos ########################################################################
   3662  1.1  christos # tmp_cat ()
   3663  1.1  christos #
   3664  1.1  christos # output the temporary cat file (the concatenation of all input)
   3665  1.1  christos #
   3666  1.1  christos tmp_cat()
   3667  1.1  christos {
   3668  1.1  christos   func_check tmp_cat '=' 0 "$@";
   3669  1.1  christos   cat "${_TMP_CAT}";
   3670  1.1  christos   eval "${return_var}" "$?";
   3671  1.1  christos }
   3672  1.1  christos 
   3673  1.1  christos 
   3674  1.1  christos ########################################################################
   3675  1.1  christos # tmp_create (<suffix>?)
   3676  1.1  christos #
   3677  1.1  christos # Create temporary file.
   3678  1.1  christos #
   3679  1.1  christos # It's safe to use the shell process ID together with a suffix to
   3680  1.1  christos # have multiple temporary files.
   3681  1.1  christos #
   3682  1.1  christos # Globals: $_TMP_DIR
   3683  1.1  christos #
   3684  1.1  christos # Output : name of created file
   3685  1.1  christos #
   3686  1.1  christos # Variable prefix: tc
   3687  1.1  christos #
   3688  1.1  christos tmp_create()
   3689  1.1  christos {
   3690  1.1  christos   func_check tmp_create '<=' 1 "$@";
   3691  1.1  christos   # the output file does not have `,' as first character, so these are
   3692  1.1  christos   # different names from the output file.
   3693  1.1  christos   tc_tmp="${_TMP_DIR}/,$1";
   3694  1.1  christos   : >"${tc_tmp}"
   3695  1.1  christos   obj tc_tmp echo1;
   3696  1.1  christos   eval ${_UNSET} tc_tmp;
   3697  1.1  christos   eval "${return_ok}";
   3698  1.1  christos }
   3699  1.1  christos 
   3700  1.1  christos 
   3701  1.1  christos ########################################################################
   3702  1.1  christos # to_tmp (<filename>)
   3703  1.1  christos #
   3704  1.1  christos # print file (decompressed) to the temporary cat file
   3705  1.1  christos #
   3706  1.1  christos to_tmp()
   3707  1.1  christos {
   3708  1.1  christos   func_check to_tmp '=' 1 "$@";
   3709  1.1  christos   if obj _TMP_CAT is_empty
   3710  1.1  christos   then
   3711  1.1  christos     error 'to_tmp_line: $_TMP_CAT is not yet set';
   3712  1.1  christos   fi;
   3713  1.1  christos   if is_file "$1"
   3714  1.1  christos   then
   3715  1.1  christos     if obj _OPT_LOCATION is_yes
   3716  1.1  christos     then
   3717  1.1  christos       echo2 "$1";
   3718  1.1  christos     fi;
   3719  1.1  christos     if obj _OPT_WHATIS is_yes
   3720  1.1  christos     then
   3721  1.1  christos       whatis_filename "$1" >>"${_TMP_CAT}";
   3722  1.1  christos     else
   3723  1.1  christos       cat_z "$1" >>"${_TMP_CAT}";
   3724  1.1  christos     fi;
   3725  1.1  christos   else
   3726  1.1  christos     error "to_tmp(): could not read file \`$1'.";
   3727  1.1  christos   fi;
   3728  1.1  christos   eval "${return_ok}";
   3729  1.1  christos }
   3730  1.1  christos 
   3731  1.1  christos 
   3732  1.1  christos ########################################################################
   3733  1.1  christos # to_tmp_line ([<text>])
   3734  1.1  christos #
   3735  1.1  christos # print line to the temporary cat file
   3736  1.1  christos #
   3737  1.1  christos to_tmp_line()
   3738  1.1  christos {
   3739  1.1  christos   func_check to_tmp '>=' 0 "$@";
   3740  1.1  christos   if obj _TMP_CAT is_empty
   3741  1.1  christos   then
   3742  1.1  christos     error 'to_tmp_line: $_TMP_CAT is not yet set';
   3743  1.1  christos   fi;
   3744  1.1  christos   echo1 "$*" >>"${_TMP_CAT}";
   3745  1.1  christos   eval "${return_ok}";
   3746  1.1  christos }
   3747  1.1  christos 
   3748  1.1  christos 
   3749  1.1  christos ########################################################################
   3750  1.1  christos # trap_set
   3751  1.1  christos #
   3752  1.1  christos # call function on signal 0
   3753  1.1  christos #
   3754  1.1  christos trap_set()
   3755  1.1  christos {
   3756  1.1  christos   func_check trap_set '=' 0 "$@";
   3757  1.1  christos   trap 'clean_up' 0 2>${_NULL_DEV} || :;
   3758  1.1  christos   eval "${return_ok}";
   3759  1.1  christos }
   3760  1.1  christos 
   3761  1.1  christos 
   3762  1.1  christos ########################################################################
   3763  1.1  christos # trap_unset ()
   3764  1.1  christos #
   3765  1.1  christos # disable trap on signal 0.
   3766  1.1  christos #
   3767  1.1  christos trap_unset()
   3768  1.1  christos {
   3769  1.1  christos   func_check trap_unset '=' 0 "$@";
   3770  1.1  christos   trap '' 0 2>${_NULL_DEV} || :;
   3771  1.1  christos   eval "${return_ok}";
   3772  1.1  christos }
   3773  1.1  christos 
   3774  1.1  christos 
   3775  1.1  christos ########################################################################
   3776  1.1  christos # usage ()
   3777  1.1  christos #
   3778  1.1  christos # print usage information to stderr; for groffer option --help.
   3779  1.1  christos #
   3780  1.1  christos usage()
   3781  1.1  christos {
   3782  1.1  christos   func_check usage = 0 "$@";
   3783  1.1  christos   echo;
   3784  1.1  christos   version;
   3785  1.1  christos   echo1 'Usage: groffer [option]... [filespec]...';
   3786  1.1  christos   cat <<EOF
   3787  1.1  christos 
   3788  1.1  christos Display roff files, standard input, and/or Unix manual pages with a X
   3789  1.1  christos Window viewer or in several text modes.  All input is decompressed
   3790  1.1  christos on-the-fly with all formats that gzip can handle.
   3791  1.1  christos 
   3792  1.1  christos "filespec" is one of
   3793  1.1  christos   "filename"       name of a readable file
   3794  1.1  christos   "-"              for standard input
   3795  1.1  christos   "man:name.n"     man page "name" in section "n"
   3796  1.1  christos   "man:name"       man page "name" in first section found
   3797  1.1  christos   "name.n"         man page "name" in section "n"
   3798  1.1  christos   "name"           man page "name" in first section found
   3799  1.1  christos and some more (see groffer(1) for details).
   3800  1.1  christos 
   3801  1.1  christos -h --help         print this usage message.
   3802  1.1  christos -Q --source       output as roff source.
   3803  1.1  christos -T --device=name  pass to groff using output device "name".
   3804  1.1  christos -v --version      print version information.
   3805  1.1  christos -V                display the groff execution pipe instead of formatting.
   3806  1.1  christos -X                display with "gxditview" using groff -X.
   3807  1.1  christos -Z --ditroff --intermediate-output
   3808  1.1  christos                   generate groff intermediate output without
   3809  1.1  christos                   post-processing and viewing, like groff -Z.
   3810  1.1  christos All other short options are interpreted as "groff" formatting options.
   3811  1.1  christos 
   3812  1.1  christos The most important groffer long options are
   3813  1.1  christos 
   3814  1.1  christos --apropos=name    start man's "apropos" program for "name".
   3815  1.1  christos --apropos-data=name
   3816  1.1  christos                   "apropos" for "name" in man's data sections 4, 5, 7.
   3817  1.1  christos --apropos-devel=name
   3818  1.1  christos                   "apropos" for "name" in development sections 2, 3, 9.
   3819  1.1  christos --apropos-progs=name
   3820  1.1  christos                   "apropos" for "name" in man's program sections 1, 6, 8.
   3821  1.1  christos --auto            choose mode automatically from the default mode list.
   3822  1.1  christos --default         reset all options to the default value.
   3823  1.1  christos --default-modes=mode1,mode2,...
   3824  1.1  christos                   set sequence of automatically tried modes.
   3825  1.1  christos --dvi             display in a viewer for TeX device independent format.
   3826  1.1  christos --dvi-viewer=prog choose the viewer program for dvi mode.
   3827  1.1  christos --groff           process like groff, disable viewing features.
   3828  1.1  christos --help            display this helping output.
   3829  1.1  christos --html            display in a web browser.
   3830  1.1  christos --html-viewer=program
   3831  1.1  christos                   choose the web browser for html mode.
   3832  1.1  christos --man             check file parameters first whether they are man pages.
   3833  1.1  christos --mode=auto|dvi|groff|html|pdf|ps|source|text|tty|www|x|X
   3834  1.1  christos                   choose display mode.
   3835  1.1  christos --no-man          disable man-page facility.
   3836  1.1  christos --no-special      disable --all, --apropos*, and --whatis
   3837  1.1  christos --pager=program   preset the paging program for tty mode.
   3838  1.1  christos --pdf             display in a PDF viewer.
   3839  1.1  christos --pdf-viewer=prog choose the viewer program for pdf mode.
   3840  1.1  christos --ps              display in a Postscript viewer.
   3841  1.1  christos --ps-viewer=prog  choose the viewer program for ps mode.
   3842  1.1  christos --shell=program   specify a shell under which to run groffer2.sh.
   3843  1.1  christos --text            output in a text device without a pager.
   3844  1.1  christos --tty             display with a pager on text terminal even when in X.
   3845  1.1  christos --tty-viewer=prog select a pager for tty mode; same as --pager.
   3846  1.1  christos --whatis          display the file name and description of man pages
   3847  1.1  christos --www             same as --html.
   3848  1.1  christos --www-viewer=prog same as --html-viewer
   3849  1.1  christos --x --X           display with "gxditview" using an X* device.
   3850  1.1  christos --x-viewer=prog   choose viewer program for x mode (X mode).
   3851  1.1  christos --X-viewer=prog   same as "--xviewer".
   3852  1.1  christos 
   3853  1.1  christos Development options that are not useful for normal usage:
   3854  1.1  christos --debug, --debug-all, --debug-keep, --debug-lm, --debug-params,
   3855  1.1  christos --debug-shell, --debug-stacks, --debug-tmpdir, --debug-user,
   3856  1.1  christos --do-nothing, --print=text
   3857  1.1  christos 
   3858  1.1  christos Viewer programs for the different modes that run on the terminal:
   3859  1.1  christos --dvi-viewer-tty=prog, --html-viewer-tty=prog, --pdf-viewer-tty=prog,
   3860  1.1  christos --ps-viewer-tty=prog, --tty-viewer-tty, --X-viewer-tty=prog,
   3861  1.1  christos --x-viewer-tty=prog, --www-viewer-tty=prog
   3862  1.1  christos 
   3863  1.1  christos The usual X Windows toolkit options transformed into GNU long options:
   3864  1.1  christos --background=color, --bd=size, --bg=color, --bordercolor=color,
   3865  1.1  christos --borderwidth=size, --bw=size, --display=Xdisplay, --fg=color,
   3866  1.1  christos --fn=font, --font=font, --foreground=color, --geometry=geom, --iconic,
   3867  1.1  christos --resolution=dpi, --rv, --title=text, --xrm=resource
   3868  1.1  christos 
   3869  1.1  christos Long options of GNU "man":
   3870  1.1  christos --all, --ascii, --ditroff, --extension=suffix, --locale=language,
   3871  1.1  christos --local-file=name, --location, --manpath=dir1:dir2:...,
   3872  1.1  christos --sections=s1:s2:..., --systems=s1,s2,..., --where, ...
   3873  1.1  christos 
   3874  1.1  christos EOF
   3875  1.1  christos   eval "${return_ok}";
   3876  1.1  christos }
   3877  1.1  christos 
   3878  1.1  christos 
   3879  1.1  christos ########################################################################
   3880  1.1  christos # version ()
   3881  1.1  christos #
   3882  1.1  christos # print version information to stderr
   3883  1.1  christos #
   3884  1.1  christos version()
   3885  1.1  christos {
   3886  1.1  christos   func_check version = 0 "$@";
   3887  1.1  christos   echo1 "groffer ${_PROGRAM_VERSION} of ${_LAST_UPDATE}";
   3888  1.1  christos   # also display groff's version, but not the called subprograms
   3889  1.1  christos   groff -v 2>&1 | sed -e '/^ *$/q' | sed -e '1s/^/is part of /';
   3890  1.1  christos   eval "${return_ok}";
   3891  1.1  christos }
   3892  1.1  christos 
   3893  1.1  christos 
   3894  1.1  christos ########################################################################
   3895  1.1  christos # warning (<string>)
   3896  1.1  christos #
   3897  1.1  christos # Print warning to stderr
   3898  1.1  christos #
   3899  1.1  christos warning()
   3900  1.1  christos {
   3901  1.1  christos   echo2 "warning: $*";
   3902  1.1  christos }
   3903  1.1  christos 
   3904  1.1  christos 
   3905  1.1  christos ########################################################################
   3906  1.1  christos # whatis_filename (<filename>)
   3907  1.1  christos #
   3908  1.1  christos # Interpret <filename> as a man page and display its `whatis'
   3909  1.1  christos # information as a fragment written in the groff language.
   3910  1.1  christos #
   3911  1.1  christos # Variable prefix: wf
   3912  1.1  christos #
   3913  1.1  christos whatis_filename()
   3914  1.1  christos {
   3915  1.1  christos   func_check whatis_filename = 1 "$@";
   3916  1.1  christos   wf_arg="$1";
   3917  1.1  christos   if obj wf_arg is_not_file
   3918  1.1  christos   then
   3919  1.1  christos     error "whatis_filename(): argument is not a readable file."
   3920  1.1  christos   fi;
   3921  1.1  christos   wf_dot='^\.'"${_SPACE_SED}"'*';
   3922  1.1  christos   if obj _FILESPEC_ARG is_equal '-'
   3923  1.1  christos   then
   3924  1.1  christos     wf_arg='stdin';
   3925  1.1  christos   fi;
   3926  1.1  christos   cat <<EOF
   3927  1.1  christos \f[CR]${wf_arg}\f[]:
   3928  1.1  christos .br
   3929  1.1  christos EOF
   3930  1.1  christos 
   3931  1.1  christos   # get the parts of the file name
   3932  1.1  christos   wf_name="$(base_name $1)";
   3933  1.1  christos   wf_section="$(echo1 $1 | sed -n -e '
   3934  1.1  christos s|^.*/man\('"${_MAN_AUTO_SEC_CHARS}"'\).*$|\1|p
   3935  1.1  christos ')";
   3936  1.1  christos   if obj wf_section is_not_empty
   3937  1.1  christos   then
   3938  1.1  christos     case "${wf_name}" in
   3939  1.1  christos     *.${wf_section}*)
   3940  1.1  christos       s='yes';
   3941  1.1  christos       ;;
   3942  1.1  christos     *)
   3943  1.1  christos       s='';
   3944  1.1  christos       wf_section='';
   3945  1.1  christos       ;;
   3946  1.1  christos     esac
   3947  1.1  christos     if obj s is_yes
   3948  1.1  christos     then
   3949  1.1  christos       wf_name="$(echo1 ${wf_name} | sed -e '
   3950  1.1  christos s/^\(.*\)\.'${wf_section}'.*$/\1/
   3951  1.1  christos ')";
   3952  1.1  christos     fi;
   3953  1.1  christos   fi;
   3954  1.1  christos 
   3955  1.1  christos   # traditional man style; grep the line containing `.TH' macro, if any
   3956  1.1  christos   wf_res="$(cat_z "$1" | sed -e '
   3957  1.1  christos /'"${wf_dot}"'TH /p
   3958  1.1  christos d
   3959  1.1  christos ')";
   3960  1.1  christos   exit_test;
   3961  1.1  christos   if obj wf_res is_not_empty
   3962  1.1  christos   then				# traditional man style
   3963  1.1  christos     # get the first line after the first `.SH' macro, by
   3964  1.1  christos     # - delete up to first .SH;
   3965  1.1  christos     # - print all lines before the next .SH;
   3966  1.1  christos     # - quit.
   3967  1.1  christos     wf_res="$(cat_z "$1" | sed -n -e '
   3968  1.1  christos 1,/'"${wf_dot}"'SH/d
   3969  1.1  christos /'"${wf_dot}"'SH/q
   3970  1.1  christos p
   3971  1.1  christos ')";
   3972  1.1  christos 
   3973  1.1  christos     if obj wf_section is_not_empty
   3974  1.1  christos     then
   3975  1.1  christos       case "${wf_res}" in
   3976  1.1  christos       ${wf_name}${_SPACE_CASE}*-${_SPACE_CASE}*)
   3977  1.1  christos         s='yes';
   3978  1.1  christos         ;;
   3979  1.1  christos       *)
   3980  1.1  christos         s='';
   3981  1.1  christos         ;;
   3982  1.1  christos       esac;
   3983  1.1  christos       if obj s is_yes
   3984  1.1  christos       then
   3985  1.1  christos         wf_res="$(obj wf_res echo1 | sed -e '
   3986  1.1  christos s/^'"${wf_name}${_SPACE_SED}"'[^-]*-'"${_SPACE_SED}"'*\(.*\)$/'"${wf_name}"' ('"${wf_section}"') \\[em] \1/
   3987  1.1  christos ')";
   3988  1.1  christos       fi;
   3989  1.1  christos     fi;
   3990  1.1  christos     obj wf_res echo1;
   3991  1.1  christos     echo;
   3992  1.1  christos     eval ${_UNSET} wf_arg;
   3993  1.1  christos     eval ${_UNSET} wf_dot;
   3994  1.1  christos     eval ${_UNSET} wf_name;
   3995  1.1  christos     eval ${_UNSET} wf_res;
   3996  1.1  christos     eval ${_UNSET} wf_section;
   3997  1.1  christos     eval "${return_ok}";
   3998  1.1  christos   fi;
   3999  1.1  christos 
   4000  1.1  christos   # mdoc style (BSD doc); grep the line containing `.Nd' macro, if any
   4001  1.1  christos   wf_res="$(cat_z "$1" | sed -n -e '/'"${wf_dot}"'Nd /s///p')";
   4002  1.1  christos   exit_test;
   4003  1.1  christos   if obj wf_res is_not_empty
   4004  1.1  christos   then				# BSD doc style
   4005  1.1  christos     if obj wf_section is_not_empty
   4006  1.1  christos     then
   4007  1.1  christos       wf_res="$(obj wf_res echo1 | sed -n -e '
   4008  1.1  christos s/^\(.*\)$/'"${wf_name}"' ('"${wf_section}"') \\[em] \1/p
   4009  1.1  christos ')";
   4010  1.1  christos     fi;
   4011  1.1  christos     obj wf_res echo1;
   4012  1.1  christos     echo;
   4013  1.1  christos     eval ${_UNSET} wf_arg;
   4014  1.1  christos     eval ${_UNSET} wf_dot;
   4015  1.1  christos     eval ${_UNSET} wf_name;
   4016  1.1  christos     eval ${_UNSET} wf_res;
   4017  1.1  christos     eval ${_UNSET} wf_section;
   4018  1.1  christos     eval "${return_ok}";
   4019  1.1  christos   fi;
   4020  1.1  christos   echo1 'is not a man page';
   4021  1.1  christos   echo;
   4022  1.1  christos   eval ${_UNSET} wf_arg;
   4023  1.1  christos   eval ${_UNSET} wf_dot;
   4024  1.1  christos   eval ${_UNSET} wf_name;
   4025  1.1  christos   eval ${_UNSET} wf_res;
   4026  1.1  christos   eval ${_UNSET} wf_section;
   4027  1.1  christos   eval "${return_bad}";
   4028  1.1  christos }
   4029  1.1  christos 
   4030  1.1  christos 
   4031  1.1  christos ########################################################################
   4032  1.1  christos # whatis_filespec ()
   4033  1.1  christos #
   4034  1.1  christos # Print the filespec name as .SH to the temporary cat file.
   4035  1.1  christos #
   4036  1.1  christos whatis_filespec()
   4037  1.1  christos {
   4038  1.1  christos   func_check whatis_filespec '=' 0 "$@";
   4039  1.1  christos   if obj _OPT_WHATIS is_yes
   4040  1.1  christos   then
   4041  1.1  christos     eval to_tmp_line \
   4042  1.1  christos       "'.SH $(echo1 "${_FILESPEC_ARG}" | sed 's/[^\\]-/\\-/g')'";
   4043  1.1  christos     exit_test;
   4044  1.1  christos   fi;
   4045  1.1  christos   eval "${return_ok}";
   4046  1.1  christos }
   4047  1.1  christos 
   4048  1.1  christos 
   4049  1.1  christos ########################################################################
   4050  1.1  christos # whatis_header ()
   4051  1.1  christos #
   4052  1.1  christos # Print the whatis header to the temporary cat file.
   4053  1.1  christos #
   4054  1.1  christos whatis_header()
   4055  1.1  christos {
   4056  1.1  christos   func_check whatis_header '=' 0 "$@";
   4057  1.1  christos   if obj _OPT_WHATIS is_yes
   4058  1.1  christos   then
   4059  1.1  christos      to_tmp_line '.TH GROFFER WHATIS';
   4060  1.1  christos   fi;
   4061  1.1  christos   eval "${return_ok}";
   4062  1.1  christos }
   4063  1.1  christos 
   4064  1.1  christos 
   4065  1.1  christos ########################################################################
   4066  1.1  christos # where_is (<program>)
   4067  1.1  christos #
   4068  1.1  christos # Output path of a program if in $PATH.
   4069  1.1  christos #
   4070  1.1  christos # Arguments : >=1 (empty allowed)
   4071  1.1  christos #   more args are ignored, this allows to specify progs with arguments
   4072  1.1  christos # Return    : `0' if arg1 is a program in $PATH, `1' otherwise.
   4073  1.1  christos #
   4074  1.1  christos # Variable prefix: w
   4075  1.1  christos #
   4076  1.1  christos where_is()
   4077  1.1  christos {
   4078  1.1  christos   func_check where_is '>=' 1 "$@";
   4079  1.1  christos   w_arg="$1";
   4080  1.1  christos   if obj w_arg is_empty
   4081  1.1  christos   then
   4082  1.1  christos     eval ${_UNSET} w_arg;
   4083  1.1  christos     eval "${return_bad}";
   4084  1.1  christos   fi;
   4085  1.1  christos   case "${w_arg}" in
   4086  1.1  christos     /*)
   4087  1.1  christos       eval ${_UNSET} w_arg;
   4088  1.1  christos       eval ${_UNSET} w_file;
   4089  1.1  christos       if test -f "${w_arg}" && test -x "${w_arg}"
   4090  1.1  christos       then
   4091  1.1  christos         eval "${return_ok}";
   4092  1.1  christos       else
   4093  1.1  christos         eval "${return_bad}";
   4094  1.1  christos       fi;
   4095  1.1  christos       ;;
   4096  1.1  christos   esac;
   4097  1.1  christos   eval set x "$(path_split "${PATH}")";
   4098  1.1  christos   exit_test;
   4099  1.1  christos   shift;
   4100  1.1  christos   for p
   4101  1.1  christos   do
   4102  1.1  christos     case "$p" in
   4103  1.1  christos       */) w_file=${p}${w_arg}; ;;
   4104  1.1  christos       *)  w_file=${p}/${w_arg}; ;;
   4105  1.1  christos     esac;
   4106  1.1  christos     if test -f "${w_file}" && test -x "${w_file}"
   4107  1.1  christos     then
   4108  1.1  christos       obj w_file echo1;
   4109  1.1  christos       eval ${_UNSET} w_arg;
   4110  1.1  christos       eval ${_UNSET} w_file;
   4111  1.1  christos       eval "${return_ok}";
   4112  1.1  christos     fi;
   4113  1.1  christos   done;
   4114  1.1  christos   eval ${_UNSET} w_arg;
   4115  1.1  christos   eval ${_UNSET} w_file;
   4116  1.1  christos   eval "${return_bad}";
   4117  1.1  christos }
   4118  1.1  christos 
   4119  1.1  christos 
   4120  1.1  christos ########################################################################
   4121  1.1  christos #                        main* Functions
   4122  1.1  christos ########################################################################
   4123  1.1  christos 
   4124  1.1  christos # The main area contains the following parts:
   4125  1.1  christos # - main_init(): initialize temporary files and set exit trap
   4126  1.1  christos # - main_parse_MANOPT(): parse $MANOPT
   4127  1.1  christos # - main_parse_args(): argument parsing
   4128  1.1  christos # - main_set_mode (): determine the display mode
   4129  1.1  christos # - main_do_fileargs(): process filespec arguments
   4130  1.1  christos # - main_set_resources(): setup X resources
   4131  1.1  christos # - main_display(): do the displaying
   4132  1.1  christos # - main(): the main function that calls all main_*()
   4133  1.1  christos 
   4134  1.1  christos 
   4135  1.1  christos #######################################################################
   4136  1.1  christos # main_init ()
   4137  1.1  christos #
   4138  1.1  christos # set exit trap and create temporary files
   4139  1.1  christos #
   4140  1.1  christos # Globals: $_TMP_DIR, $_TMP_CAT, $_TMP_STDIN
   4141  1.1  christos #
   4142  1.1  christos # Variable prefix: mi
   4143  1.1  christos #
   4144  1.1  christos main_init()
   4145  1.1  christos {
   4146  1.1  christos   func_check main_init = 0 "$@";
   4147  1.1  christos   # call clean_up() on shell termination.
   4148  1.1  christos   trap_set;
   4149  1.1  christos 
   4150  1.1  christos   # create temporary directory
   4151  1.1  christos   umask 0022;
   4152  1.1  christos   _TMP_DIR='';
   4153  1.1  christos   for d in "${GROFF_TMPDIR}" "${TMPDIR}" "${TMP}" "${TEMP}" \
   4154  1.1  christos            "${TEMPDIR}" "${HOME}"'/tmp' '/tmp' "${HOME}" '.'
   4155  1.1  christos   do
   4156  1.1  christos     mi_dir="$d";
   4157  1.1  christos     if obj mi_dir is_empty || obj mi_dir is_not_dir || \
   4158  1.1  christos        obj mi_dir is_not_writable
   4159  1.1  christos     then
   4160  1.1  christos       continue;
   4161  1.1  christos     fi;
   4162  1.1  christos 
   4163  1.1  christos     case "${mi_dir}" in
   4164  1.1  christos     */)
   4165  1.1  christos       _TMP_DIR="${mi_dir}";
   4166  1.1  christos       ;;
   4167  1.1  christos     *)
   4168  1.1  christos       _TMP_DIR="${mi_dir}"'/';
   4169  1.1  christos       ;;
   4170  1.1  christos     esac;
   4171  1.1  christos     _TMP_DIR="${_TMP_DIR}groffer${_PROCESS_ID}";
   4172  1.1  christos     if obj _TMP_DIR rm_tree
   4173  1.1  christos     then
   4174  1.1  christos       :
   4175  1.1  christos     else
   4176  1.1  christos       mi_tdir_="${_TMP_DIR}"_;
   4177  1.1  christos       mi_n=1;
   4178  1.1  christos       mi_tdir_n="${mi_tdir_}${mi_n}";
   4179  1.1  christos       while obj mi_tdir_n is_existing
   4180  1.1  christos       do
   4181  1.1  christos         if obj mi_tdir_n rm_tree
   4182  1.1  christos         then
   4183  1.1  christos           # directory could not be removed
   4184  1.1  christos           mi_n="$(expr "${mi_n}" + 1)";
   4185  1.1  christos           mi_tdir_n="${mi_tdir_}${mi_n}";
   4186  1.1  christos           continue;
   4187  1.1  christos         fi;
   4188  1.1  christos       done;
   4189  1.1  christos       _TMP_DIR="${mi_tdir_n}";
   4190  1.1  christos     fi;
   4191  1.1  christos     eval mkdir "${_TMP_DIR}";
   4192  1.1  christos     if is_not_equal "$?" 0
   4193  1.1  christos     then
   4194  1.1  christos       obj _TMP_DIR rm_tree;
   4195  1.1  christos       _TMP_DIR='';
   4196  1.1  christos       continue;
   4197  1.1  christos     fi;
   4198  1.1  christos     if obj _TMP_DIR is_dir && obj _TMP_DIR is_writable
   4199  1.1  christos     then
   4200  1.1  christos       # $_TMP_DIR can now be used as temporary directory
   4201  1.1  christos       break;
   4202  1.1  christos     fi;
   4203  1.1  christos     obj _TMP_DIR rm_tree;
   4204  1.1  christos     _TMP_DIR='';
   4205  1.1  christos     continue;
   4206  1.1  christos   done;
   4207  1.1  christos   if obj _TMP_DIR is_empty
   4208  1.1  christos   then
   4209  1.1  christos     error "main_init: \
   4210  1.1  christos Couldn't create a directory for storing temporary files.";
   4211  1.1  christos   fi;
   4212  1.1  christos   if obj _DEBUG_PRINT_TMPDIR is_yes
   4213  1.1  christos   then
   4214  1.1  christos     echo2 "temporary directory: ${_TMP_DIR}";
   4215  1.1  christos   fi;
   4216  1.1  christos 
   4217  1.1  christos   _TMP_CAT="$(tmp_create groffer_cat)";
   4218  1.1  christos   _TMP_STDIN="$(tmp_create groffer_input)";
   4219  1.1  christos   exit_test;
   4220  1.1  christos 
   4221  1.1  christos   eval ${_UNSET} mi_dir;
   4222  1.1  christos   eval ${_UNSET} mi_n;
   4223  1.1  christos   eval ${_UNSET} mi_tdir_;
   4224  1.1  christos   eval ${_UNSET} mi_tdir_n;
   4225  1.1  christos   eval "${return_ok}";
   4226  1.1  christos } # main_init()
   4227  1.1  christos 
   4228  1.1  christos 
   4229  1.1  christos ########################################################################
   4230  1.1  christos # main_parse_MANOPT ()
   4231  1.1  christos #
   4232  1.1  christos # Parse $MANOPT to retrieve man options, but only if it is a non-empty
   4233  1.1  christos # string; found man arguments can be overwritten by the command line.
   4234  1.1  christos #
   4235  1.1  christos # Globals:
   4236  1.1  christos #   in: $MANOPT, $_OPTS_MANOPT_*
   4237  1.1  christos #   out: $_MANOPT_*
   4238  1.1  christos #
   4239  1.1  christos # Variable prefix: mpm
   4240  1.1  christos #
   4241  1.1  christos main_parse_MANOPT()
   4242  1.1  christos {
   4243  1.1  christos   func_check main_parse_MANOPT = 0 "$@";
   4244  1.1  christos 
   4245  1.1  christos   if obj MANOPT is_not_empty
   4246  1.1  christos   then
   4247  1.1  christos     # Delete leading and final spaces
   4248  1.1  christos     MANOPT="$(echo1 "${MANOPT}" | sed -e '
   4249  1.1  christos s/^'"${_SPACE_SED}"'*//
   4250  1.1  christos s/'"${_SPACE_SED}"'*$//
   4251  1.1  christos ')";
   4252  1.1  christos   exit_test;
   4253  1.1  christos   fi;
   4254  1.1  christos   if obj MANOPT is_empty
   4255  1.1  christos   then
   4256  1.1  christos     eval "${return_ok}";
   4257  1.1  christos   fi;
   4258  1.1  christos 
   4259  1.1  christos   mpm_list='';
   4260  1.1  christos   # add arguments in $MANOPT by mapping them to groffer options
   4261  1.1  christos   eval set x "$(list_from_cmdline _OPTS_MANOPT "${MANOPT}")";
   4262  1.1  christos   exit_test;
   4263  1.1  christos   shift;
   4264  1.1  christos   until test "$#" -le 0 || is_equal "$1" '--'
   4265  1.1  christos   do
   4266  1.1  christos     mpm_opt="$1";
   4267  1.1  christos     shift;
   4268  1.1  christos     case "${mpm_opt}" in
   4269  1.1  christos     -7|--ascii)
   4270  1.1  christos       list_append mpm_list '--ascii';
   4271  1.1  christos       ;;
   4272  1.1  christos     -a|--all)
   4273  1.1  christos       list_append mpm_list '--all';
   4274  1.1  christos       ;;
   4275  1.1  christos     -c|--catman)
   4276  1.1  christos       do_nothing;
   4277  1.1  christos       shift;
   4278  1.1  christos       ;;
   4279  1.1  christos     -d|--debug)
   4280  1.1  christos       do_nothing;
   4281  1.1  christos       ;;
   4282  1.1  christos     -D|--default)
   4283  1.1  christos       # undo all man options so far
   4284  1.1  christos       mpm_list='';
   4285  1.1  christos       ;;
   4286  1.1  christos     -e|--extension)
   4287  1.1  christos       list_append mpm_list '--extension';
   4288  1.1  christos       shift;
   4289  1.1  christos       ;;
   4290  1.1  christos     -f|--whatis)
   4291  1.1  christos       list_append mpm_list '--whatis';
   4292  1.1  christos       shift;
   4293  1.1  christos       ;;
   4294  1.1  christos     -h|--help)
   4295  1.1  christos       do_nothing;
   4296  1.1  christos       shift;
   4297  1.1  christos       ;;
   4298  1.1  christos     -k|--apropos)
   4299  1.1  christos       # groffer's --apropos takes an argument, but man's does not, so
   4300  1.1  christos       do_nothing;
   4301  1.1  christos       ;;
   4302  1.1  christos     -l|--local-file)
   4303  1.1  christos       do_nothing;
   4304  1.1  christos       ;;
   4305  1.1  christos     -L|--locale)
   4306  1.1  christos       list_append mpm_list '--locale' "$1";
   4307  1.1  christos       shift;
   4308  1.1  christos       ;;
   4309  1.1  christos     -m|--systems)
   4310  1.1  christos       list_append mpm_list '--systems' "$1";
   4311  1.1  christos       shift;
   4312  1.1  christos       ;;
   4313  1.1  christos     -M|--manpath)
   4314  1.1  christos       list_append mpm_list '--manpath' "$1";
   4315  1.1  christos       shift;
   4316  1.1  christos       ;;
   4317  1.1  christos     -p|--preprocessor)
   4318  1.1  christos       do_nothing;
   4319  1.1  christos       shift;
   4320  1.1  christos       ;;
   4321  1.1  christos     -P|--pager)
   4322  1.1  christos       list_append mpm_list '--pager' "$1";
   4323  1.1  christos       shift;
   4324  1.1  christos       ;;
   4325  1.1  christos     -r|--prompt)
   4326  1.1  christos       do_nothing;
   4327  1.1  christos       shift;
   4328  1.1  christos       ;;
   4329  1.1  christos     -S|--sections)
   4330  1.1  christos       list_append mpm_list '--sections' "$1";
   4331  1.1  christos       shift;
   4332  1.1  christos       ;;
   4333  1.1  christos     -t|--troff)
   4334  1.1  christos       do_nothing;
   4335  1.1  christos       shift;
   4336  1.1  christos       ;;
   4337  1.1  christos     -T|--device)
   4338  1.1  christos       list_append mpm_list '-T' "$1";
   4339  1.1  christos       shift;
   4340  1.1  christos       ;;
   4341  1.1  christos     -u|--update)
   4342  1.1  christos       do_nothing;
   4343  1.1  christos       shift;
   4344  1.1  christos       ;;
   4345  1.1  christos     -V|--version)
   4346  1.1  christos       do_nothing;
   4347  1.1  christos       ;;
   4348  1.1  christos     -w|--where|--location)
   4349  1.1  christos       list_append mpm_list '--location';
   4350  1.1  christos       ;;
   4351  1.1  christos     -Z|--ditroff)
   4352  1.1  christos       do_nothing;
   4353  1.1  christos       ;;
   4354  1.1  christos     # ignore all other options
   4355  1.1  christos     esac;
   4356  1.1  christos   done;
   4357  1.1  christos 
   4358  1.1  christos   # prepend $mpm_list to the command line
   4359  1.1  christos   if obj mpm_list is_not_empty
   4360  1.1  christos   then
   4361  1.1  christos     eval set x "${mpm_list}" '"$@"';
   4362  1.1  christos     shift;
   4363  1.1  christos   fi;
   4364  1.1  christos 
   4365  1.1  christos   eval ${_UNSET} mpm_list;
   4366  1.1  christos   eval ${_UNSET} mpm_opt;
   4367  1.1  christos   eval "${return_ok}";
   4368  1.1  christos } # main_parse_MANOPT()
   4369  1.1  christos 
   4370  1.1  christos 
   4371  1.1  christos ########################################################################
   4372  1.1  christos # main_parse_args (<command_line_args>*)
   4373  1.1  christos #
   4374  1.1  christos # Parse arguments; process options and filespec parameters
   4375  1.1  christos #
   4376  1.1  christos # Arguments: pass the command line arguments unaltered.
   4377  1.1  christos # Globals:
   4378  1.1  christos #   in:  $_OPTS_*
   4379  1.1  christos #   out: $_OPT_*, $_ADDOPTS, $_FILEARGS
   4380  1.1  christos #
   4381  1.1  christos # Variable prefix: mpa
   4382  1.1  christos #
   4383  1.1  christos main_parse_args()
   4384  1.1  christos {
   4385  1.1  christos   func_check main_parse_args '>=' 0 "$@";
   4386  1.1  christos   _ALL_PARAMS="$(list_from_cmdline _OPTS_CMDLINE "$@")";
   4387  1.1  christos   exit_test;
   4388  1.1  christos   if obj _DEBUG_PRINT_PARAMS is_yes
   4389  1.1  christos   then
   4390  1.1  christos     echo2 "parameters: ${_ALL_PARAMS}";
   4391  1.1  christos   fi;
   4392  1.1  christos   eval set x "${_ALL_PARAMS}";
   4393  1.1  christos   shift;
   4394  1.1  christos 
   4395  1.1  christos   # By the call of `eval', unnecessary quoting was removed.  So the
   4396  1.1  christos   # positional shell parameters ($1, $2, ...) are now guaranteed to
   4397  1.1  christos   # represent an option or an argument to the previous option, if any;
   4398  1.1  christos   # then a `--' argument for separating options and
   4399  1.1  christos   # parameters; followed by the filespec parameters if any.
   4400  1.1  christos 
   4401  1.1  christos   # Note, the existence of arguments to options has already been checked.
   4402  1.1  christos   # So a check for `$#' or `--' should not be done for arguments.
   4403  1.1  christos 
   4404  1.1  christos   until test "$#" -le 0 || is_equal "$1" '--'
   4405  1.1  christos   do
   4406  1.1  christos     mpa_opt="$1";		# $mpa_opt is fed into the option handler
   4407  1.1  christos     shift;
   4408  1.1  christos     case "${mpa_opt}" in
   4409  1.1  christos     -h|--help)
   4410  1.1  christos       usage;
   4411  1.1  christos       leave;
   4412  1.1  christos       ;;
   4413  1.1  christos     -Q|--source)		# output source code (`Quellcode').
   4414  1.1  christos       _OPT_MODE='source';
   4415  1.1  christos       ;;
   4416  1.1  christos     -T|--device|--troff-device) # device; arg
   4417  1.1  christos       _OPT_DEVICE="$1";
   4418  1.1  christos       _check_device_with_mode;
   4419  1.1  christos       shift;
   4420  1.1  christos       ;;
   4421  1.1  christos     -v|--version)
   4422  1.1  christos       version;
   4423  1.1  christos       leave;
   4424  1.1  christos       ;;
   4425  1.1  christos     -V)
   4426  1.1  christos       _OPT_V='yes';
   4427  1.1  christos       ;;
   4428  1.1  christos     -Z|--ditroff|--intermediate-output) # groff intermediate output
   4429  1.1  christos       _OPT_Z='yes';
   4430  1.1  christos       ;;
   4431  1.1  christos     -X)
   4432  1.1  christos       if is_X
   4433  1.1  christos       then
   4434  1.1  christos         _OPT_MODE=X;
   4435  1.1  christos       fi;
   4436  1.1  christos       ;;
   4437  1.1  christos     -?)
   4438  1.1  christos       # delete leading `-'
   4439  1.1  christos       mpa_optchar="$(echo1 "${mpa_opt}" | sed -e 's/^-//')";
   4440  1.1  christos       exit_test;
   4441  1.1  christos       if list_has _OPTS_GROFF_SHORT_NA "${mpa_optchar}"
   4442  1.1  christos       then
   4443  1.1  christos         list_append _ADDOPTS_GROFF "${mpa_opt}";
   4444  1.1  christos       elif list_has _OPTS_GROFF_SHORT_ARG "${mpa_optchar}"
   4445  1.1  christos       then
   4446  1.1  christos         list_append _ADDOPTS_GROFF "${mpa_opt}" "$1";
   4447  1.1  christos         shift;
   4448  1.1  christos       else
   4449  1.1  christos         error "main_parse_args(): Unknown option : \`$1'";
   4450  1.1  christos       fi;
   4451  1.1  christos       ;;
   4452  1.1  christos     --all)
   4453  1.1  christos         _OPT_ALL='yes';
   4454  1.1  christos         ;;
   4455  1.1  christos     --apropos)			# run `apropos'
   4456  1.1  christos       _OPT_APROPOS='yes';
   4457  1.1  christos       _APROPOS_SECTIONS='';
   4458  1.1  christos       _OPT_WHATIS='no';
   4459  1.1  christos       ;;
   4460  1.1  christos     --apropos-data)		# run `apropos' for data sections
   4461  1.1  christos       _OPT_APROPOS='yes';
   4462  1.1  christos       _APROPOS_SECTIONS='457';
   4463  1.1  christos       _OPT_WHATIS='no';
   4464  1.1  christos       ;;
   4465  1.1  christos     --apropos-devel)		# run `apropos' for development sections
   4466  1.1  christos       _OPT_APROPOS='yes';
   4467  1.1  christos       _APROPOS_SECTIONS='239';
   4468  1.1  christos       _OPT_WHATIS='no';
   4469  1.1  christos       ;;
   4470  1.1  christos     --apropos-progs)		# run `apropos' for program sections
   4471  1.1  christos       _OPT_APROPOS='yes';
   4472  1.1  christos       _APROPOS_SECTIONS='168';
   4473  1.1  christos       _OPT_WHATIS='no';
   4474  1.1  christos       ;;
   4475  1.1  christos     --ascii)
   4476  1.1  christos       list_append _ADDOPTS_GROFF '-mtty-char';
   4477  1.1  christos       if obj _OPT_MODE is_empty
   4478  1.1  christos       then
   4479  1.1  christos         _OPT_MODE='text';
   4480  1.1  christos       fi;
   4481  1.1  christos       ;;
   4482  1.1  christos     --auto)			# the default automatic mode
   4483  1.1  christos       _OPT_MODE='';
   4484  1.1  christos       ;;
   4485  1.1  christos     --bd)			# border color for viewers, arg;
   4486  1.1  christos       _OPT_BD="$1";
   4487  1.1  christos       shift;
   4488  1.1  christos       ;;
   4489  1.1  christos     --bg|--backgroud)		# background color for viewers, arg;
   4490  1.1  christos       _OPT_BG="$1";
   4491  1.1  christos       shift;
   4492  1.1  christos       ;;
   4493  1.1  christos     --bw)			# border width for viewers, arg;
   4494  1.1  christos       _OPT_BW="$1";
   4495  1.1  christos       shift;
   4496  1.1  christos       ;;
   4497  1.1  christos     --debug|--debug-all|--debug-keep|--debug-lm|--debug-params|\
   4498  1.1  christos --debug-shell|--debug-stacks|--debug-tmpdir|--debug-user)
   4499  1.1  christos       # debug is handled at the beginning
   4500  1.1  christos       :;
   4501  1.1  christos       ;;
   4502  1.1  christos     --default)			# reset variables to default
   4503  1.1  christos       reset;
   4504  1.1  christos       ;;
   4505  1.1  christos     --default-modes)		# sequence of modes in auto mode; arg
   4506  1.1  christos       _OPT_DEFAULT_MODES="$1";
   4507  1.1  christos       shift;
   4508  1.1  christos       ;;
   4509  1.1  christos     --display)			# set X display, arg
   4510  1.1  christos       _OPT_DISPLAY="$1";
   4511  1.1  christos       shift;
   4512  1.1  christos       ;;
   4513  1.1  christos     --do-nothing)
   4514  1.1  christos       _OPT_DO_NOTHING='yes';
   4515  1.1  christos       ;;
   4516  1.1  christos     --dvi)
   4517  1.1  christos       if is_X
   4518  1.1  christos       then
   4519  1.1  christos         _OPT_MODE='dvi';
   4520  1.1  christos       fi;
   4521  1.1  christos       ;;
   4522  1.1  christos     --dvi-viewer)		# viewer program for dvi mode; arg
   4523  1.1  christos       _VIEWER_TERMINAL='no';
   4524  1.1  christos       _OPT_VIEWER_DVI="$1";
   4525  1.1  christos       shift;
   4526  1.1  christos       ;;
   4527  1.1  christos     --dvi-viewer-tty)		# viewer program for dvi mode in tty; arg
   4528  1.1  christos       _VIEWER_TERMINAL='yes';
   4529  1.1  christos       _OPT_VIEWER_DVI="$1";
   4530  1.1  christos       shift;
   4531  1.1  christos       ;;
   4532  1.1  christos     --extension)		# the extension for man pages, arg
   4533  1.1  christos       _OPT_EXTENSION="$1";
   4534  1.1  christos       shift;
   4535  1.1  christos       ;;
   4536  1.1  christos     --fg|--foreground)		# foreground color for viewers, arg;
   4537  1.1  christos       _OPT_FG="$1";
   4538  1.1  christos       shift;
   4539  1.1  christos       ;;
   4540  1.1  christos     --fn|--font)		# set font for viewers, arg;
   4541  1.1  christos       _OPT_FN="$1";
   4542  1.1  christos       shift;
   4543  1.1  christos       ;;
   4544  1.1  christos     --geometry)			# window geometry for viewers, arg;
   4545  1.1  christos       _OPT_GEOMETRY="$1";
   4546  1.1  christos       shift;
   4547  1.1  christos       ;;
   4548  1.1  christos     --groff)
   4549  1.1  christos       _OPT_MODE='groff';
   4550  1.1  christos       ;;
   4551  1.1  christos     --html|--www)		# display with web browser
   4552  1.1  christos       _OPT_MODE=html;
   4553  1.1  christos       ;;
   4554  1.1  christos     --html-viewer|--www-viewer) # viewer program for html mode; arg
   4555  1.1  christos       _VIEWER_TERMINAL='no';
   4556  1.1  christos       _OPT_VIEWER_HTML="$1";
   4557  1.1  christos       shift;
   4558  1.1  christos       ;;
   4559  1.1  christos     --html-viewer-tty|--www-viewer-tty) # viewer for html mode in tty; arg
   4560  1.1  christos       _VIEWER_TERMINAL='yes';
   4561  1.1  christos       _OPT_VIEWER_HTML="$1";
   4562  1.1  christos       shift;
   4563  1.1  christos       ;;
   4564  1.1  christos     --iconic)			# start viewers as icons
   4565  1.1  christos       _OPT_ICONIC='yes';
   4566  1.1  christos       ;;
   4567  1.1  christos     --locale)			# set language for man pages, arg
   4568  1.1  christos       # argument is xx[_territory[.codeset[@modifier]]] (ISO 639,...)
   4569  1.1  christos       _OPT_LANG="$1";
   4570  1.1  christos       shift;
   4571  1.1  christos       ;;
   4572  1.1  christos     --local-file)		# force local files; same as `--no-man'
   4573  1.1  christos       _MAN_FORCE='no';
   4574  1.1  christos       _MAN_ENABLE='no';
   4575  1.1  christos       ;;
   4576  1.1  christos     --location|--where)		# print file locations to stderr
   4577  1.1  christos       _OPT_LOCATION='yes';
   4578  1.1  christos       ;;
   4579  1.1  christos     --man)		       # force all file params to be man pages
   4580  1.1  christos       _MAN_ENABLE='yes';
   4581  1.1  christos       _MAN_FORCE='yes';
   4582  1.1  christos       ;;
   4583  1.1  christos     --manpath)		      # specify search path for man pages, arg
   4584  1.1  christos       # arg is colon-separated list of directories
   4585  1.1  christos       _OPT_MANPATH="$1";
   4586  1.1  christos       shift;
   4587  1.1  christos       ;;
   4588  1.1  christos     --mode)			# display mode
   4589  1.1  christos       mpa_arg="$1";
   4590  1.1  christos       shift;
   4591  1.1  christos       case "${mpa_arg}" in
   4592  1.1  christos       auto|'')		     # search mode automatically among default
   4593  1.1  christos         _OPT_MODE='';
   4594  1.1  christos         ;;
   4595  1.1  christos       groff)			# pass input to plain groff
   4596  1.1  christos         _OPT_MODE='groff';
   4597  1.1  christos         ;;
   4598  1.1  christos       html|www)			# display with a web browser
   4599  1.1  christos         _OPT_MODE='html';
   4600  1.1  christos         ;;
   4601  1.1  christos       dvi)			# display with xdvi viewer
   4602  1.1  christos         if is_X
   4603  1.1  christos         then
   4604  1.1  christos           _OPT_MODE='dvi';
   4605  1.1  christos         fi;
   4606  1.1  christos         ;;
   4607  1.1  christos       pdf)			# display with PDF viewer
   4608  1.1  christos         if is_X
   4609  1.1  christos         then
   4610  1.1  christos           _OPT_MODE='pdf';
   4611  1.1  christos         fi;
   4612  1.1  christos         ;;
   4613  1.1  christos       ps)			# display with Postscript viewer
   4614  1.1  christos         if is_X
   4615  1.1  christos         then
   4616  1.1  christos           _OPT_MODE='ps';
   4617  1.1  christos         fi;
   4618  1.1  christos         ;;
   4619  1.1  christos       text)			# output on terminal
   4620  1.1  christos         _OPT_MODE='text';
   4621  1.1  christos         ;;
   4622  1.1  christos       tty)			# output on terminal
   4623  1.1  christos         _OPT_MODE='tty';
   4624  1.1  christos         ;;
   4625  1.1  christos       X|x)			# output on X roff viewer
   4626  1.1  christos         if is_X
   4627  1.1  christos         then
   4628  1.1  christos           _OPT_MODE='x';
   4629  1.1  christos         fi;
   4630  1.1  christos         ;;
   4631  1.1  christos       Q|source)			# display source code
   4632  1.1  christos         _OPT_MODE="source";
   4633  1.1  christos         ;;
   4634  1.1  christos       *)
   4635  1.1  christos         error "main_parse_args(): unknown mode ${mpa_arg}";
   4636  1.1  christos         ;;
   4637  1.1  christos       esac;
   4638  1.1  christos       ;;
   4639  1.1  christos     --no-location)		# disable former call to `--location'
   4640  1.1  christos       _OPT_LOCATION='yes';
   4641  1.1  christos       ;;
   4642  1.1  christos     --no-man)			# disable search for man pages
   4643  1.1  christos       # the same as --local-file
   4644  1.1  christos       _MAN_FORCE='no';
   4645  1.1  christos       _MAN_ENABLE='no';
   4646  1.1  christos       ;;
   4647  1.1  christos     --no-special)		# disable some special former calls
   4648  1.1  christos       _OPT_ALL='no'
   4649  1.1  christos       _OPT_APROPOS='no'
   4650  1.1  christos       _OPT_WHATIS='no'
   4651  1.1  christos       ;;
   4652  1.1  christos     --pager|--tty-viewer|--tty-viewer-tty)
   4653  1.1  christos       # set paging program for tty mode, arg
   4654  1.1  christos       _VIEWER_TERMINAL='yes';
   4655  1.1  christos       _OPT_PAGER="$1";
   4656  1.1  christos       shift;
   4657  1.1  christos       ;;
   4658  1.1  christos     --pdf)
   4659  1.1  christos       if is_X
   4660  1.1  christos       then
   4661  1.1  christos         _OPT_MODE='pdf';
   4662  1.1  christos       fi;
   4663  1.1  christos       ;;
   4664  1.1  christos     --pdf-viewer)		# viewer program for ps mode; arg
   4665  1.1  christos       _VIEWER_TERMINAL='no';
   4666  1.1  christos       _OPT_VIEWER_PDF="$1";
   4667  1.1  christos       shift;
   4668  1.1  christos       ;;
   4669  1.1  christos     --pdf-viewer-tty)		# viewer program for ps mode in tty; arg
   4670  1.1  christos       _VIEWER_TERMINAL='yes';
   4671  1.1  christos       _OPT_VIEWER_PDF="$1";
   4672  1.1  christos       shift;
   4673  1.1  christos       ;;
   4674  1.1  christos     --print)			# for argument test
   4675  1.1  christos       echo2 "$1";
   4676  1.1  christos       shift;
   4677  1.1  christos       ;;
   4678  1.1  christos     --ps)
   4679  1.1  christos       if is_X
   4680  1.1  christos       then
   4681  1.1  christos         _OPT_MODE='ps';
   4682  1.1  christos       fi;
   4683  1.1  christos       ;;
   4684  1.1  christos     --ps-viewer)		# viewer program for ps mode; arg
   4685  1.1  christos       _VIEWER_TERMINAL='no';
   4686  1.1  christos       _OPT_VIEWER_PS="$1";
   4687  1.1  christos       shift;
   4688  1.1  christos       ;;
   4689  1.1  christos     --ps-viewer-tty)		# viewer program for ps mode in tty; arg
   4690  1.1  christos       _VIEWER_TERMINAL='yes';
   4691  1.1  christos       _OPT_VIEWER_PS="$1";
   4692  1.1  christos       shift;
   4693  1.1  christos       ;;
   4694  1.1  christos     --resolution)		# set resolution for X devices, arg
   4695  1.1  christos       mpa_arg="$1";
   4696  1.1  christos       shift;
   4697  1.1  christos       case "${mpa_arg}" in
   4698  1.1  christos       75|75dpi)
   4699  1.1  christos         mpa_dpi=75;
   4700  1.1  christos         ;;
   4701  1.1  christos       100|100dpi)
   4702  1.1  christos         mpa_dpi=100;
   4703  1.1  christos         ;;
   4704  1.1  christos       *)
   4705  1.1  christos         error "main_parse_args(): \
   4706  1.1  christos only resoutions of 75 or 100 dpi are supported";
   4707  1.1  christos         ;;
   4708  1.1  christos       esac;
   4709  1.1  christos       _OPT_RESOLUTION="${mpa_dpi}";
   4710  1.1  christos       ;;
   4711  1.1  christos     --rv)
   4712  1.1  christos       _OPT_RV='yes';
   4713  1.1  christos       ;;
   4714  1.1  christos     --sections)			# specify sections for man pages, arg
   4715  1.1  christos       # arg is colon-separated list of section names
   4716  1.1  christos       _OPT_SECTIONS="$1";
   4717  1.1  christos       shift;
   4718  1.1  christos       ;;
   4719  1.1  christos     --shell)
   4720  1.1  christos       # already done during the first run; so ignore the argument
   4721  1.1  christos       shift;
   4722  1.1  christos       ;;
   4723  1.1  christos     --systems)			# man pages for different OS's, arg
   4724  1.1  christos       # argument is a comma-separated list
   4725  1.1  christos       _OPT_SYSTEMS="$1";
   4726  1.1  christos       shift;
   4727  1.1  christos       ;;
   4728  1.1  christos     --text)			# text mode without pager
   4729  1.1  christos       _OPT_MODE=text;
   4730  1.1  christos       ;;
   4731  1.1  christos     --title)			# title for X viewers; arg
   4732  1.1  christos       _OPT_TITLE="$1";
   4733  1.1  christos       shift;
   4734  1.1  christos       ;;
   4735  1.1  christos     --tty)			# tty mode, text with pager
   4736  1.1  christos       _OPT_MODE=tty;
   4737  1.1  christos       ;;
   4738  1.1  christos     --text-device|--tty-device) # device for tty mode; arg
   4739  1.1  christos       _OPT_TEXT_DEVICE="$1";
   4740  1.1  christos       shift;
   4741  1.1  christos       ;;
   4742  1.1  christos     --whatis)
   4743  1.1  christos       _OPT_WHATIS='yes';
   4744  1.1  christos       _OPT_ALL='yes';
   4745  1.1  christos       _OPT_APROPOS='no';
   4746  1.1  christos       ;;
   4747  1.1  christos     --X|--x)
   4748  1.1  christos       if is_X
   4749  1.1  christos       then
   4750  1.1  christos         _OPT_MODE=x;
   4751  1.1  christos       fi;
   4752  1.1  christos       ;;
   4753  1.1  christos     --xrm)			# pass X resource string, arg;
   4754  1.1  christos       list_append _OPT_XRM "$1";
   4755  1.1  christos       shift;
   4756  1.1  christos       ;;
   4757  1.1  christos     --x-viewer|--X-viewer)	# viewer program for x mode; arg
   4758  1.1  christos       _VIEWER_TERMINAL='no';
   4759  1.1  christos       _OPT_VIEWER_X="$1";
   4760  1.1  christos       shift;
   4761  1.1  christos       ;;
   4762  1.1  christos     --x-viewer-tty|--X-viewer-tty) # viewer program for x mode in tty; arg
   4763  1.1  christos       _VIEWER_TERMINAL='yes';
   4764  1.1  christos       _OPT_VIEWER_X="$1";
   4765  1.1  christos       shift;
   4766  1.1  christos       ;;
   4767  1.1  christos     *)
   4768  1.1  christos       error 'main_parse_args(): error on argument parsing : '"\`$*'";
   4769  1.1  christos       ;;
   4770  1.1  christos     esac;
   4771  1.1  christos   done;
   4772  1.1  christos   shift;			# remove `--' argument
   4773  1.1  christos 
   4774  1.1  christos   if obj _OPT_DO_NOTHING is_yes
   4775  1.1  christos   then
   4776  1.1  christos     leave;
   4777  1.1  christos   fi;
   4778  1.1  christos 
   4779  1.1  christos   # Remaining arguments are file names (filespecs).
   4780  1.1  christos   # Save them to list $_FILEARGS
   4781  1.1  christos   if is_equal "$#" 0
   4782  1.1  christos   then				# use "-" for standard input
   4783  1.1  christos     set x '-';
   4784  1.1  christos     shift;
   4785  1.1  christos   fi;
   4786  1.1  christos   _FILEARGS='';
   4787  1.1  christos   list_append _FILEARGS "$@";
   4788  1.1  christos   if list_has _FILEARGS '-'
   4789  1.1  christos   then
   4790  1.1  christos     save_stdin;
   4791  1.1  christos   fi;
   4792  1.1  christos   # $_FILEARGS must be retrieved with `eval set x "$_FILEARGS"; shift;'
   4793  1.1  christos   eval ${_UNSET} mpa_arg;
   4794  1.1  christos   eval ${_UNSET} mpa_dpi;
   4795  1.1  christos   eval ${_UNSET} mpa_opt;
   4796  1.1  christos   eval ${_UNSET} mpa_optchar;
   4797  1.1  christos   eval "${return_ok}";
   4798  1.1  christos } # main_parse_args()
   4799  1.1  christos 
   4800  1.1  christos 
   4801  1.1  christos # Called from main_parse_args() because double `case' is not possible.
   4802  1.1  christos # Globals: $_OPT_DEVICE, $_OPT_MODE
   4803  1.1  christos _check_device_with_mode()
   4804  1.1  christos {
   4805  1.1  christos   func_check _check_device_with_mode = 0 "$@";
   4806  1.1  christos   case "${_OPT_DEVICE}" in
   4807  1.1  christos   dvi)
   4808  1.1  christos     _OPT_MODE=dvi;
   4809  1.1  christos     eval "${return_ok}";
   4810  1.1  christos     ;;
   4811  1.1  christos   html)
   4812  1.1  christos     _OPT_MODE=html;
   4813  1.1  christos     eval "${return_ok}";
   4814  1.1  christos     ;;
   4815  1.1  christos   lbp|lj4)
   4816  1.1  christos     _OPT_MODE=groff;
   4817  1.1  christos     eval "${return_ok}";
   4818  1.1  christos     ;;
   4819  1.1  christos   ps)
   4820  1.1  christos     _OPT_MODE=ps;
   4821  1.1  christos     eval "${return_ok}";
   4822  1.1  christos     ;;
   4823  1.1  christos   ascii|cp1047|latin1|utf8)
   4824  1.1  christos     if obj _OPT_MODE is_not_equal text
   4825  1.1  christos     then
   4826  1.1  christos       _OPT_MODE=tty;		# default text mode
   4827  1.1  christos     fi;
   4828  1.1  christos     eval "${return_ok}";
   4829  1.1  christos     ;;
   4830  1.1  christos   X*)
   4831  1.1  christos     _OPT_MODE=x;
   4832  1.1  christos     eval "${return_ok}";
   4833  1.1  christos     ;;
   4834  1.1  christos   *)				# unknown device, go to groff mode
   4835  1.1  christos     _OPT_MODE=groff;
   4836  1.1  christos     eval "${return_ok}";
   4837  1.1  christos     ;;
   4838  1.1  christos   esac;
   4839  1.1  christos   eval "${return_error}";
   4840  1.1  christos } # _check_device_with_mode() of main_parse_args()
   4841  1.1  christos 
   4842  1.1  christos 
   4843  1.1  christos ########################################################################
   4844  1.1  christos # main_set_mode ()
   4845  1.1  christos #
   4846  1.1  christos # Determine the display mode.
   4847  1.1  christos #
   4848  1.1  christos # Globals:
   4849  1.1  christos #   in:  $DISPLAY, $_OPT_MODE, $_OPT_DEVICE
   4850  1.1  christos #   out: $_DISPLAY_MODE
   4851  1.1  christos #
   4852  1.1  christos # Variable prefix: msm
   4853  1.1  christos #
   4854  1.1  christos main_set_mode()
   4855  1.1  christos {
   4856  1.1  christos   func_check main_set_mode = 0 "$@";
   4857  1.1  christos 
   4858  1.1  christos   # set display
   4859  1.1  christos   if obj _OPT_DISPLAY is_not_empty
   4860  1.1  christos   then
   4861  1.1  christos     DISPLAY="${_OPT_DISPLAY}";
   4862  1.1  christos   fi;
   4863  1.1  christos 
   4864  1.1  christos   if obj _OPT_V is_yes
   4865  1.1  christos   then
   4866  1.1  christos     list_append _ADDOPTS_GROFF '-V';
   4867  1.1  christos   fi;
   4868  1.1  christos   if obj _OPT_Z is_yes
   4869  1.1  christos   then
   4870  1.1  christos     _DISPLAY_MODE='groff';
   4871  1.1  christos     list_append _ADDOPTS_GROFF '-Z';
   4872  1.1  christos   fi;
   4873  1.1  christos   if obj _OPT_MODE is_equal 'groff'
   4874  1.1  christos   then
   4875  1.1  christos     _DISPLAY_MODE='groff';
   4876  1.1  christos   fi;
   4877  1.1  christos   if obj _DISPLAY_MODE is_equal 'groff'
   4878  1.1  christos   then
   4879  1.1  christos     eval ${_UNSET} msm_modes;
   4880  1.1  christos     eval ${_UNSET} msm_viewer;
   4881  1.1  christos     eval ${_UNSET} msm_viewers;
   4882  1.1  christos     eval "${return_ok}";
   4883  1.1  christos   fi;
   4884  1.1  christos 
   4885  1.1  christos   if obj _OPT_MODE is_equal 'source'
   4886  1.1  christos   then
   4887  1.1  christos     _DISPLAY_MODE='source';
   4888  1.1  christos     eval ${_UNSET} msm_modes;
   4889  1.1  christos     eval ${_UNSET} msm_viewer;
   4890  1.1  christos     eval ${_UNSET} msm_viewers;
   4891  1.1  christos     eval "${return_ok}";
   4892  1.1  christos   fi;
   4893  1.1  christos 
   4894  1.1  christos   case "${_OPT_MODE}" in
   4895  1.1  christos   '')				# automatic mode
   4896  1.1  christos     case "${_OPT_DEVICE}" in
   4897  1.1  christos     X*)
   4898  1.1  christos      if is_not_X
   4899  1.1  christos       then
   4900  1.1  christos         error_user "no X display found for device ${_OPT_DEVICE}";
   4901  1.1  christos       fi;
   4902  1.1  christos       _DISPLAY_MODE='x';
   4903  1.1  christos       eval ${_UNSET} msm_modes;
   4904  1.1  christos       eval ${_UNSET} msm_viewer;
   4905  1.1  christos       eval ${_UNSET} msm_viewers;
   4906  1.1  christos       eval "${return_ok}";
   4907  1.1  christos       ;;
   4908  1.1  christos     ascii|cp1047|latin1|utf8)
   4909  1.1  christos       if obj _DISPLAY_MODE is_not_equal 'text'
   4910  1.1  christos       then
   4911  1.1  christos         _DISPLAY_MODE='tty';
   4912  1.1  christos       fi;
   4913  1.1  christos       eval ${_UNSET} msm_modes;
   4914  1.1  christos       eval ${_UNSET} msm_viewer;
   4915  1.1  christos       eval ${_UNSET} msm_viewers;
   4916  1.1  christos       eval "${return_ok}";
   4917  1.1  christos       ;;
   4918  1.1  christos     esac;
   4919  1.1  christos     if is_not_X
   4920  1.1  christos     then
   4921  1.1  christos       _DISPLAY_MODE='tty';
   4922  1.1  christos       eval ${_UNSET} msm_modes;
   4923  1.1  christos       eval ${_UNSET} msm_viewer;
   4924  1.1  christos       eval ${_UNSET} msm_viewers;
   4925  1.1  christos       eval "${return_ok}";
   4926  1.1  christos     fi;
   4927  1.1  christos 
   4928  1.1  christos     if obj _OPT_DEFAULT_MODES is_empty
   4929  1.1  christos     then
   4930  1.1  christos       msm_modes="${_DEFAULT_MODES}";
   4931  1.1  christos     else
   4932  1.1  christos       msm_modes="${_OPT_DEFAULT_MODES}";
   4933  1.1  christos     fi;
   4934  1.1  christos     ;;
   4935  1.1  christos   text)
   4936  1.1  christos     _DISPLAY_MODE='text';
   4937  1.1  christos     eval ${_UNSET} msm_modes;
   4938  1.1  christos     eval ${_UNSET} msm_viewer;
   4939  1.1  christos     eval ${_UNSET} msm_viewers;
   4940  1.1  christos     eval "${return_ok}";
   4941  1.1  christos     ;;
   4942  1.1  christos   tty)
   4943  1.1  christos     _DISPLAY_MODE='tty';
   4944  1.1  christos     eval ${_UNSET} msm_modes;
   4945  1.1  christos     eval ${_UNSET} msm_viewer;
   4946  1.1  christos     eval ${_UNSET} msm_viewers;
   4947  1.1  christos     eval "${return_ok}";
   4948  1.1  christos     ;;
   4949  1.1  christos   html)
   4950  1.1  christos     _DISPLAY_MODE='html';
   4951  1.1  christos     msm_modes="${_OPT_MODE}";
   4952  1.1  christos     ;;
   4953  1.1  christos   *)				# display mode was given
   4954  1.1  christos     if is_not_X
   4955  1.1  christos     then
   4956  1.1  christos       error_user "You must be in X Window for ${_OPT_MODE} mode.";
   4957  1.1  christos     fi;
   4958  1.1  christos     msm_modes="${_OPT_MODE}";
   4959  1.1  christos     ;;
   4960  1.1  christos   esac;
   4961  1.1  christos 
   4962  1.1  christos   # only viewer modes are left
   4963  1.1  christos   eval set x "$(list_from_split "${msm_modes}" ',')";
   4964  1.1  christos   exit_test;
   4965  1.1  christos   shift;
   4966  1.1  christos   while test "$#" -gt 0
   4967  1.1  christos   do
   4968  1.1  christos     m="$1";
   4969  1.1  christos     shift;
   4970  1.1  christos     case "$m" in
   4971  1.1  christos     dvi)
   4972  1.1  christos       if obj _OPT_VIEWER_DVI is_not_empty
   4973  1.1  christos       then
   4974  1.1  christos         msm_viewer="${_OPT_VIEWER_DVI}";
   4975  1.1  christos       else
   4976  1.1  christos         msm_viewer="$(_get_first_prog "$_VIEWER_DVI}")";
   4977  1.1  christos         exit_test;
   4978  1.1  christos       fi;
   4979  1.1  christos       if obj msm_viewer is_empty
   4980  1.1  christos       then
   4981  1.1  christos         error 'No viewer for dvi mode available.';
   4982  1.1  christos       fi;
   4983  1.1  christos       if is_not_equal "$?" 0
   4984  1.1  christos       then
   4985  1.1  christos         continue;
   4986  1.1  christos       fi;
   4987  1.1  christos       _DISPLAY_PROG="${msm_viewer}";
   4988  1.1  christos       _DISPLAY_MODE="dvi";
   4989  1.1  christos       eval ${_UNSET} msm_modes;
   4990  1.1  christos       eval ${_UNSET} msm_viewer;
   4991  1.1  christos       eval ${_UNSET} msm_viewers;
   4992  1.1  christos       eval "${return_ok}";
   4993  1.1  christos       ;;
   4994  1.1  christos     html)
   4995  1.1  christos       if obj _OPT_VIEWER_HTML is_not_empty
   4996  1.1  christos       then
   4997  1.1  christos         msm_viewer="${_OPT_VIEWER_HTML}";
   4998  1.1  christos       else
   4999  1.1  christos         if is_X
   5000  1.1  christos         then
   5001  1.1  christos           msm_viewers="${_VIEWER_HTML_X}";
   5002  1.1  christos         else
   5003  1.1  christos           msm_viewers="${_VIEWER_HTML_TTY}";
   5004  1.1  christos         fi;
   5005  1.1  christos         msm_viewer="$(_get_first_prog "${msm_viewers}")";
   5006  1.1  christos         exit_test;
   5007  1.1  christos       fi;
   5008  1.1  christos       if obj msm_viewer is_empty
   5009  1.1  christos       then
   5010  1.1  christos         error 'No viewer for html mode available.';
   5011  1.1  christos       fi;
   5012  1.1  christos       if is_not_equal "$?" 0
   5013  1.1  christos       then
   5014  1.1  christos         continue;
   5015  1.1  christos       fi;
   5016  1.1  christos       _DISPLAY_PROG="${msm_viewer}";
   5017  1.1  christos       _DISPLAY_MODE=html;
   5018  1.1  christos       eval ${_UNSET} msm_modes;
   5019  1.1  christos       eval ${_UNSET} msm_viewer;
   5020  1.1  christos       eval ${_UNSET} msm_viewers;
   5021  1.1  christos       eval "${return_ok}";
   5022  1.1  christos       ;;
   5023  1.1  christos     pdf)
   5024  1.1  christos       if obj _OPT_VIEWER_PDF is_not_empty
   5025  1.1  christos       then
   5026  1.1  christos         msm_viewer="${_OPT_VIEWER_PDF}";
   5027  1.1  christos       else
   5028  1.1  christos         msm_viewer="$(_get_first_prog "${_VIEWER_PDF}")";
   5029  1.1  christos         exit_test;
   5030  1.1  christos       fi;
   5031  1.1  christos       if obj msm_viewer is_empty
   5032  1.1  christos       then
   5033  1.1  christos         error 'No viewer for pdf mode available.';
   5034  1.1  christos       fi;
   5035  1.1  christos       if is_not_equal "$?" 0
   5036  1.1  christos       then
   5037  1.1  christos         continue;
   5038  1.1  christos       fi;
   5039  1.1  christos       _DISPLAY_PROG="${msm_viewer}";
   5040  1.1  christos       _DISPLAY_MODE="pdf";
   5041  1.1  christos       eval ${_UNSET} msm_modes;
   5042  1.1  christos       eval ${_UNSET} msm_viewer;
   5043  1.1  christos       eval ${_UNSET} msm_viewers;
   5044  1.1  christos       eval "${return_ok}";
   5045  1.1  christos       ;;
   5046  1.1  christos     ps)
   5047  1.1  christos       if obj _OPT_VIEWER_PS is_not_empty
   5048  1.1  christos       then
   5049  1.1  christos         msm_viewer="${_OPT_VIEWER_PS}";
   5050  1.1  christos       else
   5051  1.1  christos         msm_viewer="$(_get_first_prog "${_VIEWER_PS}")";
   5052  1.1  christos         exit_test;
   5053  1.1  christos       fi;
   5054  1.1  christos       if obj msm_viewer is_empty
   5055  1.1  christos       then
   5056  1.1  christos         error 'No viewer for ps mode available.';
   5057  1.1  christos       fi;
   5058  1.1  christos       if is_not_equal "$?" 0
   5059  1.1  christos       then
   5060  1.1  christos         continue;
   5061  1.1  christos       fi;
   5062  1.1  christos       _DISPLAY_PROG="${msm_viewer}";
   5063  1.1  christos       _DISPLAY_MODE="ps";
   5064  1.1  christos      eval ${_UNSET} msm_modes;
   5065  1.1  christos       eval ${_UNSET} msm_viewer;
   5066  1.1  christos       eval ${_UNSET} msm_viewers;
   5067  1.1  christos       eval "${return_ok}";
   5068  1.1  christos       ;;
   5069  1.1  christos     text)
   5070  1.1  christos       _DISPLAY_MODE='text';
   5071  1.1  christos       eval ${_UNSET} msm_modes;
   5072  1.1  christos       eval ${_UNSET} msm_viewer;
   5073  1.1  christos       eval ${_UNSET} msm_viewers;
   5074  1.1  christos       eval "${return_ok}";
   5075  1.1  christos       ;;
   5076  1.1  christos     tty)
   5077  1.1  christos       _DISPLAY_MODE='tty';
   5078  1.1  christos       eval ${_UNSET} msm_modes;
   5079  1.1  christos       eval ${_UNSET} msm_viewer;
   5080  1.1  christos       eval ${_UNSET} msm_viewers;
   5081  1.1  christos       eval "${return_ok}";
   5082  1.1  christos       ;;
   5083  1.1  christos     x)
   5084  1.1  christos       if obj _OPT_VIEWER_X is_not_empty
   5085  1.1  christos       then
   5086  1.1  christos         msm_viewer="${_OPT_VIEWER_X}";
   5087  1.1  christos       else
   5088  1.1  christos         msm_viewer="$(_get_first_prog "${_VIEWER_X}")";
   5089  1.1  christos         exit_test;
   5090  1.1  christos       fi;
   5091  1.1  christos       if obj msm_viewer is_empty
   5092  1.1  christos       then
   5093  1.1  christos         error 'No viewer for x mode available.';
   5094  1.1  christos       fi;
   5095  1.1  christos       if is_not_equal "$?" 0
   5096  1.1  christos       then
   5097  1.1  christos         continue;
   5098  1.1  christos       fi;
   5099  1.1  christos       _DISPLAY_PROG="${msm_viewer}";
   5100  1.1  christos       _DISPLAY_MODE='x';
   5101  1.1  christos       eval ${_UNSET} msm_modes;
   5102  1.1  christos       eval ${_UNSET} msm_viewer;
   5103  1.1  christos       eval ${_UNSET} msm_viewers;
   5104  1.1  christos       eval "${return_ok}";
   5105  1.1  christos       ;;
   5106  1.1  christos     X)
   5107  1.1  christos       _DISPLAY_MODE='X';
   5108  1.1  christos       eval ${_UNSET} msm_modes;
   5109  1.1  christos       eval ${_UNSET} msm_viewer;
   5110  1.1  christos       eval ${_UNSET} msm_viewers;
   5111  1.1  christos       eval "${return_ok}";
   5112  1.1  christos       ;;
   5113  1.1  christos     esac;
   5114  1.1  christos   done;
   5115  1.1  christos   eval ${_UNSET} msm_modes;
   5116  1.1  christos   eval ${_UNSET} msm_viewer;
   5117  1.1  christos   eval ${_UNSET} msm_viewers;
   5118  1.1  christos   error_user "No suitable display mode found.";
   5119  1.1  christos } # main_set_mode()
   5120  1.1  christos 
   5121  1.1  christos 
   5122  1.1  christos # _get_first_prog (<proglist>)
   5123  1.1  christos #
   5124  1.1  christos # Retrieve first argument that represents an existing program in $PATH.
   5125  1.1  christos # Local function for main_set_mode().
   5126  1.1  christos #
   5127  1.1  christos # Arguments: 1; a comma-separated list of commands (with options),
   5128  1.1  christos #               like $_VIEWER_*.
   5129  1.1  christos #
   5130  1.1  christos # Return  : `1' if none found, `0' if found.
   5131  1.1  christos # Output  : the argument that succeded.
   5132  1.1  christos #
   5133  1.1  christos # Variable prefix: _gfp
   5134  1.1  christos #
   5135  1.1  christos _get_first_prog()
   5136  1.1  christos {
   5137  1.1  christos   if is_equal "$#" 0
   5138  1.1  christos   then
   5139  1.1  christos     error "_get_first_prog() needs 1 argument.";
   5140  1.1  christos   fi;
   5141  1.1  christos   if is_empty "$1"
   5142  1.1  christos   then
   5143  1.1  christos     return "${_BAD}";
   5144  1.1  christos   fi;
   5145  1.1  christos   eval set x "$(list_from_split "$1" ',')";
   5146  1.1  christos   exit_test;
   5147  1.1  christos   shift;
   5148  1.1  christos   for i
   5149  1.1  christos   do
   5150  1.1  christos     _gfp_i="$i";
   5151  1.1  christos     if obj _gfp_i is_empty
   5152  1.1  christos     then
   5153  1.1  christos       continue;
   5154  1.1  christos     fi;
   5155  1.1  christos     if eval is_prog "$(get_first_essential ${_gfp_i})"
   5156  1.1  christos     then
   5157  1.1  christos       exit_test;
   5158  1.1  christos       obj _gfp_i echo1;
   5159  1.1  christos       eval ${_UNSET} _gfp_i;
   5160  1.1  christos       return "${_GOOD}";
   5161  1.1  christos     fi;
   5162  1.1  christos   done;
   5163  1.1  christos   eval ${_UNSET} _gfp_i;
   5164  1.1  christos   return "${_BAD}";
   5165  1.1  christos } # _get_first_prog() of main_set_mode()
   5166  1.1  christos 
   5167  1.1  christos 
   5168  1.1  christos #######################################################################
   5169  1.1  christos # main_do_fileargs ()
   5170  1.1  christos #
   5171  1.1  christos # Process filespec arguments in $_FILEARGS.
   5172  1.1  christos #
   5173  1.1  christos # Globals:
   5174  1.1  christos #   in: $_FILEARGS (process with `eval set x "$_FILEARGS"; shift;')
   5175  1.1  christos #
   5176  1.1  christos # Variable prefix: mdfa
   5177  1.1  christos #
   5178  1.1  christos main_do_fileargs()
   5179  1.1  christos {
   5180  1.1  christos   func_check main_do_fileargs = 0 "$@";
   5181  1.1  christos   special_setup;
   5182  1.1  christos   eval set x "${_FILEARGS}";
   5183  1.1  christos   shift;
   5184  1.1  christos   eval ${_UNSET} _FILEARGS;
   5185  1.1  christos   # temporary storage of all input to $_TMP_CAT
   5186  1.1  christos   while test "$#" -ge 2
   5187  1.1  christos   do
   5188  1.1  christos     # test for `s name' arguments, with `s' a 1-char standard section
   5189  1.1  christos     mdfa_filespec="$1";
   5190  1.1  christos     _FILESPEC_ARG="$1";
   5191  1.1  christos     shift;
   5192  1.1  christos     case "${mdfa_filespec}" in
   5193  1.1  christos     '')
   5194  1.1  christos       continue;
   5195  1.1  christos       ;;
   5196  1.1  christos     '-')
   5197  1.1  christos       special_filespec;
   5198  1.1  christos       if obj _OPT_APROPOS is_yes
   5199  1.1  christos       then
   5200  1.1  christos         continue;
   5201  1.1  christos       fi;
   5202  1.1  christos       register_file '-'
   5203  1.1  christos       continue;
   5204  1.1  christos       ;;
   5205  1.1  christos     ?)
   5206  1.1  christos       if obj _OPT_APROPOS is_yes
   5207  1.1  christos       then
   5208  1.1  christos         special_filespec;
   5209  1.1  christos         continue;
   5210  1.1  christos       fi;
   5211  1.1  christos       if list_has_not _MAN_AUTO_SEC_LIST "${mdfa_filespec}"
   5212  1.1  christos       then
   5213  1.1  christos         special_filespec;
   5214  1.1  christos         do_filearg "${mdfa_filespec}"
   5215  1.1  christos         continue;
   5216  1.1  christos       fi;
   5217  1.1  christos       mdfa_name="$1";
   5218  1.1  christos       _FILESPEC_ARG="${_FILESPEC_ARG} $1";
   5219  1.1  christos       special_filespec;
   5220  1.1  christos       case "${mdfa_name}" in
   5221  1.1  christos       */*|man:*|*\(*\)|*."${mdfa_filespec}")
   5222  1.1  christos         do_filearg "${mdfa_filespec}"
   5223  1.1  christos         continue;
   5224  1.1  christos         ;;
   5225  1.1  christos       esac;
   5226  1.1  christos       shift;
   5227  1.1  christos       if do_filearg "man:${mdfa_name}(${mdfa_filespec})"
   5228  1.1  christos       then
   5229  1.1  christos         continue;
   5230  1.1  christos       else
   5231  1.1  christos         do_filearg "${mdfa_filespec}"
   5232  1.1  christos         continue;
   5233  1.1  christos       fi;
   5234  1.1  christos       ;;
   5235  1.1  christos     *)
   5236  1.1  christos       special_filespec;
   5237  1.1  christos       if obj _OPT_APROPOS is_yes
   5238  1.1  christos       then
   5239  1.1  christos         continue;
   5240  1.1  christos       fi;
   5241  1.1  christos       do_filearg "${mdfa_filespec}"
   5242  1.1  christos       continue;
   5243  1.1  christos       ;;
   5244  1.1  christos     esac;
   5245  1.1  christos   done;				# end of `s name' test
   5246  1.1  christos   while test "$#" -gt 0
   5247  1.1  christos   do
   5248  1.1  christos     mdfa_filespec="$1";
   5249  1.1  christos     _FILESPEC_ARG="$1";
   5250  1.1  christos     shift;
   5251  1.1  christos     special_filespec;
   5252  1.1  christos     if obj _OPT_APROPOS is_yes
   5253  1.1  christos     then
   5254  1.1  christos       continue;
   5255  1.1  christos     fi;
   5256  1.1  christos     do_filearg "${mdfa_filespec}"
   5257  1.1  christos   done;
   5258  1.1  christos   obj _TMP_STDIN rm_file_with_debug;
   5259  1.1  christos   eval ${_UNSET} mdfa_filespec;
   5260  1.1  christos   eval ${_UNSET} mdfa_name;
   5261  1.1  christos   eval "${return_ok}";
   5262  1.1  christos } # main_do_fileargs()
   5263  1.1  christos 
   5264  1.1  christos 
   5265  1.1  christos ########################################################################
   5266  1.1  christos # main_set_resources ()
   5267  1.1  christos #
   5268  1.1  christos # Determine options for setting X resources with $_DISPLAY_PROG.
   5269  1.1  christos #
   5270  1.1  christos # Globals: $_DISPLAY_PROG, $_OUTPUT_FILE_NAME
   5271  1.1  christos #
   5272  1.1  christos # Variable prefix: msr
   5273  1.1  christos #
   5274  1.1  christos main_set_resources()
   5275  1.1  christos {
   5276  1.1  christos   func_check main_set_resources = 0 "$@";
   5277  1.1  christos   # $msr_prog   viewer program
   5278  1.1  christos   # $msr_rl     resource list
   5279  1.1  christos   msr_title="$(get_first_essential \
   5280  1.1  christos                  "${_OPT_TITLE}" "${_REGISTERED_TITLE}")";
   5281  1.1  christos   exit_test;
   5282  1.1  christos   _OUTPUT_FILE_NAME='';
   5283  1.1  christos   eval set x "${msr_title}";
   5284  1.1  christos   shift;
   5285  1.1  christos   until is_equal "$#" 0
   5286  1.1  christos   do
   5287  1.1  christos     msr_n="$1";
   5288  1.1  christos     case "${msr_n}" in
   5289  1.1  christos     '')
   5290  1.1  christos       continue;
   5291  1.1  christos       ;;
   5292  1.1  christos     ,*)
   5293  1.1  christos       msr_n="$(echo1 "$1" | sed -e 's/^,,*//')";
   5294  1.1  christos       exit_test;
   5295  1.1  christos       ;;
   5296  1.1  christos     esac
   5297  1.1  christos     if obj msr_n is_empty
   5298  1.1  christos     then
   5299  1.1  christos       continue;
   5300  1.1  christos     fi;
   5301  1.1  christos     if obj _OUTPUT_FILE_NAME is_not_empty
   5302  1.1  christos     then
   5303  1.1  christos       _OUTPUT_FILE_NAME="${_OUTPUT_FILE_NAME}"',';
   5304  1.1  christos     fi;
   5305  1.1  christos     _OUTPUT_FILE_NAME="${_OUTPUT_FILE_NAME}${msr_n}";
   5306  1.1  christos     shift;
   5307  1.1  christos   done;
   5308  1.1  christos   case "${_OUTPUT_FILE_NAME}" in
   5309  1.1  christos   '')
   5310  1.1  christos     _OUTPUT_FILE_NAME='-';
   5311  1.1  christos     ;;
   5312  1.1  christos   ,*)
   5313  1.1  christos     error "main_set_resources(): ${_OUTPUT_FILE_NAME} starts with a comma.";
   5314  1.1  christos     ;;
   5315  1.1  christos   esac;
   5316  1.1  christos   _OUTPUT_FILE_NAME="${_TMP_DIR}/${_OUTPUT_FILE_NAME}";
   5317  1.1  christos 
   5318  1.1  christos   if obj _DISPLAY_PROG is_empty
   5319  1.1  christos   then				# for example, for groff mode
   5320  1.1  christos     _DISPLAY_ARGS='';
   5321  1.1  christos     eval ${_UNSET} msr_n;
   5322  1.1  christos     eval ${_UNSET} msr_prog;
   5323  1.1  christos     eval ${_UNSET} msr_rl;
   5324  1.1  christos     eval ${_UNSET} msr_title;
   5325  1.1  christos     eval "${return_ok}";
   5326  1.1  christos   fi;
   5327  1.1  christos 
   5328  1.1  christos   eval set x "${_DISPLAY_PROG}";
   5329  1.1  christos   shift;
   5330  1.1  christos   msr_prog="$(base_name "$1")";
   5331  1.1  christos   exit_test;
   5332  1.1  christos   shift;
   5333  1.1  christos   if test $# != 0
   5334  1.1  christos   then
   5335  1.1  christos     if obj _DISPLAY_PROG is_empty
   5336  1.1  christos     then
   5337  1.1  christos       _DISPLAY_ARGS="$*";
   5338  1.1  christos     else
   5339  1.1  christos       _DISPLAY_ARGS="$* ${_DISPLAY_ARGS}";
   5340  1.1  christos     fi;
   5341  1.1  christos   fi;
   5342  1.1  christos   msr_rl='';
   5343  1.1  christos   if obj _OPT_BD is_not_empty
   5344  1.1  christos   then
   5345  1.1  christos     case "${msr_prog}" in
   5346  1.1  christos     ghostview|gv|gxditview|xditview|xdvi)
   5347  1.1  christos       list_append msr_rl '-bd' "${_OPT_BD}";
   5348  1.1  christos       ;;
   5349  1.1  christos     esac;
   5350  1.1  christos   fi;
   5351  1.1  christos   if obj _OPT_BG is_not_empty
   5352  1.1  christos   then
   5353  1.1  christos     case "${msr_prog}" in
   5354  1.1  christos     ghostview|gv|gxditview|xditview|xdvi)
   5355  1.1  christos       list_append msr_rl '-bg' "${_OPT_BG}";
   5356  1.1  christos       ;;
   5357  1.1  christos     kghostview)
   5358  1.1  christos       list_append msr_rl '--bg' "${_OPT_BG}";
   5359  1.1  christos       ;;
   5360  1.1  christos     xpdf)
   5361  1.1  christos       list_append msr_rl '-papercolor' "${_OPT_BG}";
   5362  1.1  christos       ;;
   5363  1.1  christos     esac;
   5364  1.1  christos   fi;
   5365  1.1  christos   if obj _OPT_BW is_not_empty
   5366  1.1  christos   then
   5367  1.1  christos     case "${msr_prog}" in
   5368  1.1  christos     ghostview|gv|gxditview|xditview|xdvi)
   5369  1.1  christos       _list_append msr_rl '-bw' "${_OPT_BW}";
   5370  1.1  christos       ;;
   5371  1.1  christos     esac;
   5372  1.1  christos   fi;
   5373  1.1  christos   if obj _OPT_FG is_not_empty
   5374  1.1  christos   then
   5375  1.1  christos     case "${msr_prog}" in
   5376  1.1  christos     ghostview|gv|gxditview|xditview|xdvi)
   5377  1.1  christos       list_append msr_rl '-fg' "${_OPT_FG}";
   5378  1.1  christos       ;;
   5379  1.1  christos     kghostview)
   5380  1.1  christos       list_append msr_rl '--fg' "${_OPT_FG}";
   5381  1.1  christos       ;;
   5382  1.1  christos     esac;
   5383  1.1  christos   fi;
   5384  1.1  christos   if is_not_empty "${_OPT_FN}"
   5385  1.1  christos   then
   5386  1.1  christos     case "${msr_prog}" in
   5387  1.1  christos     ghostview|gv|gxditview|xditview|xdvi)
   5388  1.1  christos       list_append msr_rl '-fn' "${_OPT_FN}";
   5389  1.1  christos       ;;
   5390  1.1  christos     kghostview)
   5391  1.1  christos       list_append msr_rl '--fn' "${_OPT_FN}";
   5392  1.1  christos       ;;
   5393  1.1  christos     esac;
   5394  1.1  christos   fi;
   5395  1.1  christos   if is_not_empty "${_OPT_GEOMETRY}"
   5396  1.1  christos   then
   5397  1.1  christos     case "${msr_prog}" in
   5398  1.1  christos     ghostview|gv|gxditview|xditview|xdvi|xpdf)
   5399  1.1  christos       list_append msr_rl '-geometry' "${_OPT_GEOMETRY}";
   5400  1.1  christos       ;;
   5401  1.1  christos     kghostview)
   5402  1.1  christos       list_append msr_rl '--geometry' "${_OPT_GEOMETRY}";
   5403  1.1  christos       ;;
   5404  1.1  christos     esac;
   5405  1.1  christos   fi;
   5406  1.1  christos   if is_empty "${_OPT_RESOLUTION}"
   5407  1.1  christos   then
   5408  1.1  christos     _OPT_RESOLUTION="${_DEFAULT_RESOLUTION}";
   5409  1.1  christos     case "${msr_prog}" in
   5410  1.1  christos     gxditview|xditview)
   5411  1.1  christos       list_append msr_rl '-resolution' "${_DEFAULT_RESOLUTION}";
   5412  1.1  christos       ;;
   5413  1.1  christos     xpdf)
   5414  1.1  christos       case "${_DEFAULT_RESOLUTION}" in
   5415  1.1  christos       75)
   5416  1.1  christos         # 72dpi is '100'
   5417  1.1  christos         list_append msr_rl '-z' '104';
   5418  1.1  christos         ;;
   5419  1.1  christos       100)
   5420  1.1  christos         list_append msr_rl '-z' '139';
   5421  1.1  christos         ;;
   5422  1.1  christos       esac;
   5423  1.1  christos       ;;
   5424  1.1  christos     esac;
   5425  1.1  christos   else
   5426  1.1  christos     case "${msr_prog}" in
   5427  1.1  christos     ghostview|gv|gxditview|xditview|xdvi)
   5428  1.1  christos       list_append msr_rl '-resolution' "${_OPT_RESOLUTION}";
   5429  1.1  christos       ;;
   5430  1.1  christos     xpdf)
   5431  1.1  christos       case "${_OPT_RESOLUTION}" in
   5432  1.1  christos       75)
   5433  1.1  christos         list_append msr_rl '-z' '104';
   5434  1.1  christos         # '100' corresponds to 72dpi
   5435  1.1  christos         ;;
   5436  1.1  christos       100)
   5437  1.1  christos         list_append msr_rl '-z' '139';
   5438  1.1  christos         ;;
   5439  1.1  christos       esac;
   5440  1.1  christos       ;;
   5441  1.1  christos     esac;
   5442  1.1  christos   fi;
   5443  1.1  christos   if is_yes "${_OPT_ICONIC}"
   5444  1.1  christos   then
   5445  1.1  christos     case "${msr_prog}" in
   5446  1.1  christos     ghostview|gv|gxditview|xditview|xdvi)
   5447  1.1  christos       list_append msr_rl '-iconic';
   5448  1.1  christos       ;;
   5449  1.1  christos     esac;
   5450  1.1  christos   fi;
   5451  1.1  christos   if is_yes "${_OPT_RV}"
   5452  1.1  christos   then
   5453  1.1  christos     case "${msr_prog}" in
   5454  1.1  christos     ghostview|gv|gxditview|xditview|xdvi)
   5455  1.1  christos       list_append msr_rl '-rv';
   5456  1.1  christos       ;;
   5457  1.1  christos     esac;
   5458  1.1  christos   fi;
   5459  1.1  christos   if is_not_empty "${_OPT_XRM}"
   5460  1.1  christos   then
   5461  1.1  christos     case "${msr_prog}" in
   5462  1.1  christos     ghostview|gv|gxditview|xditview|xdvi|xpdf)
   5463  1.1  christos       eval set x "${_OPT_XRM}";
   5464  1.1  christos       shift;
   5465  1.1  christos       for i
   5466  1.1  christos       do
   5467  1.1  christos         list_append msr_rl '-xrm' "$i";
   5468  1.1  christos       done;
   5469  1.1  christos       ;;
   5470  1.1  christos     esac;
   5471  1.1  christos   fi;
   5472  1.1  christos   if is_not_empty "${msr_title}"
   5473  1.1  christos   then
   5474  1.1  christos     case "${msr_prog}" in
   5475  1.1  christos     gxditview|xditview)
   5476  1.1  christos       list_append msr_rl '-title' "${msr_title}";
   5477  1.1  christos       ;;
   5478  1.1  christos     esac;
   5479  1.1  christos   fi;
   5480  1.1  christos   _DISPLAY_ARGS="${msr_rl}";
   5481  1.1  christos   eval ${_UNSET} msr_n;
   5482  1.1  christos   eval ${_UNSET} msr_prog;
   5483  1.1  christos   eval ${_UNSET} msr_rl;
   5484  1.1  christos   eval ${_UNSET} msr_title;
   5485  1.1  christos   eval "${return_ok}";
   5486  1.1  christos } # main_set_resources
   5487  1.1  christos 
   5488  1.1  christos 
   5489  1.1  christos ########################################################################
   5490  1.1  christos # main_display ()
   5491  1.1  christos #
   5492  1.1  christos # Do the actual display of the whole thing.
   5493  1.1  christos #
   5494  1.1  christos # Globals:
   5495  1.1  christos #   in: $_DISPLAY_MODE, $_OPT_DEVICE,
   5496  1.1  christos #       $_ADDOPTS_GROFF, $_ADDOPTS_POST, $_ADDOPTS_X,
   5497  1.1  christos #       $_TMP_CAT, $_OPT_PAGER, $PAGER, $_MANOPT_PAGER,
   5498  1.1  christos #       $_OUTPUT_FILE_NAME
   5499  1.1  christos #
   5500  1.1  christos # Variable prefix: md
   5501  1.1  christos #
   5502  1.1  christos main_display()
   5503  1.1  christos {
   5504  1.1  christos   func_check main_display = 0 "$@";
   5505  1.1  christos 
   5506  1.1  christos   export md_addopts;
   5507  1.1  christos   export md_groggy;
   5508  1.1  christos   export md_modefile;
   5509  1.1  christos 
   5510  1.1  christos   if obj _TMP_CAT is_non_empty_file
   5511  1.1  christos   then
   5512  1.1  christos     md_modefile="${_OUTPUT_FILE_NAME}";
   5513  1.1  christos   else
   5514  1.1  christos     echo2 'groffer: empty input.';
   5515  1.1  christos     clean_up;
   5516  1.1  christos     eval ${_UNSET} md_modefile;
   5517  1.1  christos     eval "${return_ok}";
   5518  1.1  christos   fi;
   5519  1.1  christos 
   5520  1.1  christos   # go to the temporary directory to be able to access internal data files
   5521  1.1  christos   cd "${_TMP_DIR}" >"${_NULL_DEV}" 2>&1;
   5522  1.1  christos 
   5523  1.1  christos   case "${_DISPLAY_MODE}" in
   5524  1.1  christos   groff)
   5525  1.1  christos     _ADDOPTS_GROFF="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
   5526  1.1  christos     if obj _OPT_DEVICE is_not_empty
   5527  1.1  christos     then
   5528  1.1  christos       _ADDOPTS_GROFF="${_ADDOPTS_GROFF} -T${_OPT_DEVICE}";
   5529  1.1  christos     fi;
   5530  1.1  christos     md_groggy="$(tmp_cat | eval grog "${md_options}")";
   5531  1.1  christos     exit_test;
   5532  1.1  christos     _do_opt_V;
   5533  1.1  christos 
   5534  1.1  christos     obj md_modefile rm_file;
   5535  1.1  christos     mv "${_TMP_CAT}" "${md_modefile}";
   5536  1.1  christos     trap_unset;
   5537  1.1  christos     cat "${md_modefile}" | \
   5538  1.1  christos     {
   5539  1.1  christos       trap_set;
   5540  1.1  christos       eval "${md_groggy}" "${_ADDOPTS_GROFF}";
   5541  1.1  christos     } &
   5542  1.1  christos     ;;
   5543  1.1  christos   text|tty)
   5544  1.1  christos     case "${_OPT_DEVICE}" in
   5545  1.1  christos     '')
   5546  1.1  christos       md_device="$(get_first_essential \
   5547  1.1  christos                      "${_OPT_TEXT_DEVICE}" "${_DEFAULT_TTY_DEVICE}")";
   5548  1.1  christos       exit_test;
   5549  1.1  christos       ;;
   5550  1.1  christos     ascii|cp1047|latin1|utf8)
   5551  1.1  christos       md_device="${_OPT_DEVICE}";
   5552  1.1  christos       ;;
   5553  1.1  christos     *)
   5554  1.1  christos       warning "main_display(): \
   5555  1.1  christos wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
   5556  1.1  christos       ;;
   5557  1.1  christos     esac;
   5558  1.1  christos     md_addopts="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
   5559  1.1  christos     md_groggy="$(tmp_cat | grog -T${md_device})";
   5560  1.1  christos     exit_test;
   5561  1.1  christos     if obj _DISPLAY_MODE is_equal 'text'
   5562  1.1  christos     then
   5563  1.1  christos       _do_opt_V;
   5564  1.1  christos       tmp_cat | eval "${md_groggy}" "${md_addopts}";
   5565  1.1  christos     else
   5566  1.1  christos       md_pager='';
   5567  1.1  christos       for p in "${_OPT_PAGER}" "${PAGER}" "${_MANOPT_PAGER}" \
   5568  1.1  christos                'less -r -R' 'more' 'pager' 'cat'
   5569  1.1  christos       do
   5570  1.1  christos         md_p="$p";
   5571  1.1  christos         if eval is_prog ${md_p}
   5572  1.1  christos         then		      # no "" for is_prog() allows args for $p
   5573  1.1  christos           md_pager="${md_p}";
   5574  1.1  christos           break;
   5575  1.1  christos         fi;
   5576  1.1  christos       done;
   5577  1.1  christos       if obj md_pager is_empty
   5578  1.1  christos       then
   5579  1.1  christos         error 'main_display(): no pager program found for tty mode';
   5580  1.1  christos       fi;
   5581  1.1  christos       _do_opt_V;
   5582  1.1  christos       tmp_cat | eval "${md_groggy}" "${md_addopts}" | \
   5583  1.1  christos                 eval "${md_pager}";
   5584  1.1  christos     fi;
   5585  1.1  christos     clean_up;
   5586  1.1  christos     ;;
   5587  1.1  christos   source)
   5588  1.1  christos     tmp_cat;
   5589  1.1  christos     clean_up;
   5590  1.1  christos     ;;
   5591  1.1  christos 
   5592  1.1  christos   #### viewer modes
   5593  1.1  christos 
   5594  1.1  christos   dvi)
   5595  1.1  christos     case "${_OPT_DEVICE}" in
   5596  1.1  christos     ''|dvi) do_nothing; ;;
   5597  1.1  christos     *)
   5598  1.1  christos       warning "main_display(): \
   5599  1.1  christos wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"
   5600  1.1  christos       ;;
   5601  1.1  christos     esac;
   5602  1.1  christos     md_modefile="${md_modefile}".dvi;
   5603  1.1  christos     md_groggy="$(tmp_cat | grog -Tdvi)";
   5604  1.1  christos     exit_test;
   5605  1.1  christos     _do_display;
   5606  1.1  christos     ;;
   5607  1.1  christos   html)
   5608  1.1  christos     case "${_OPT_DEVICE}" in
   5609  1.1  christos     ''|html) do_nothing; ;;
   5610  1.1  christos     *)
   5611  1.1  christos       warning "main_display(): \
   5612  1.1  christos wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
   5613  1.1  christos       ;;
   5614  1.1  christos     esac;
   5615  1.1  christos     md_modefile="${md_modefile}".html;
   5616  1.1  christos     md_groggy="$(tmp_cat | grog -Thtml)";
   5617  1.1  christos     exit_test;
   5618  1.1  christos     _do_display;
   5619  1.1  christos     ;;
   5620  1.1  christos   pdf)
   5621  1.1  christos     case "${_OPT_DEVICE}" in
   5622  1.1  christos     ''|ps)
   5623  1.1  christos       do_nothing;
   5624  1.1  christos       ;;
   5625  1.1  christos     *)
   5626  1.1  christos       warning "main_display(): \
   5627  1.1  christos wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
   5628  1.1  christos       ;;
   5629  1.1  christos     esac;
   5630  1.1  christos     md_groggy="$(tmp_cat | grog -Tps)";
   5631  1.1  christos     exit_test;
   5632  1.1  christos     _do_display _make_pdf;
   5633  1.1  christos     ;;
   5634  1.1  christos   ps)
   5635  1.1  christos     case "${_OPT_DEVICE}" in
   5636  1.1  christos     ''|ps)
   5637  1.1  christos       do_nothing;
   5638  1.1  christos       ;;
   5639  1.1  christos     *)
   5640  1.1  christos       warning "main_display(): \
   5641  1.1  christos wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
   5642  1.1  christos       ;;
   5643  1.1  christos     esac;
   5644  1.1  christos     md_modefile="${md_modefile}".ps;
   5645  1.1  christos     md_groggy="$(tmp_cat | grog -Tps)";
   5646  1.1  christos     exit_test;
   5647  1.1  christos     _do_display;
   5648  1.1  christos     ;;
   5649  1.1  christos   x)
   5650  1.1  christos     case "${_OPT_DEVICE}" in
   5651  1.1  christos     X*)
   5652  1.1  christos       md_device="${_OPT_DEVICE}"
   5653  1.1  christos       ;;
   5654  1.1  christos     *)
   5655  1.1  christos       case "${_OPT_RESOLUTION}" in
   5656  1.1  christos       100)
   5657  1.1  christos         md_device='X100';
   5658  1.1  christos         if obj _OPT_GEOMETRY is_empty
   5659  1.1  christos         then
   5660  1.1  christos           case "${_DISPLAY_PROG}" in
   5661  1.1  christos           gxditview|xditview)
   5662  1.1  christos             # add width of 800dpi for resolution of 100dpi to the args
   5663  1.1  christos             list_append _DISPLAY_ARGS '-geometry' '800';
   5664  1.1  christos             ;;
   5665  1.1  christos           esac;
   5666  1.1  christos         fi;
   5667  1.1  christos         ;;
   5668  1.1  christos       *)
   5669  1.1  christos         md_device='X75-12';
   5670  1.1  christos         ;;
   5671  1.1  christos       esac
   5672  1.1  christos     esac;
   5673  1.1  christos     md_groggy="$(tmp_cat | grog -T${md_device} -Z)";
   5674  1.1  christos     exit_test;
   5675  1.1  christos     _do_display;
   5676  1.1  christos     ;;
   5677  1.1  christos   X)
   5678  1.1  christos     case "${_OPT_DEVICE}" in
   5679  1.1  christos     '')
   5680  1.1  christos       md_groggy="$(tmp_cat | grog -X)";
   5681  1.1  christos       exit_test;
   5682  1.1  christos       ;;
   5683  1.1  christos     X*|dvi|html|lbp|lj4|ps)
   5684  1.1  christos       # these devices work with 
   5685  1.1  christos       md_groggy="$(tmp_cat | grog -T"${_OPT_DEVICE}" -X)";
   5686  1.1  christos       exit_test;
   5687  1.1  christos       ;;
   5688  1.1  christos     *)
   5689  1.1  christos       warning "main_display(): \
   5690  1.1  christos wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
   5691  1.1  christos       md_groggy="$(tmp_cat | grog -Z)";
   5692  1.1  christos       exit_test;
   5693  1.1  christos       ;;
   5694  1.1  christos     esac;
   5695  1.1  christos     _do_display;
   5696  1.1  christos     ;;
   5697  1.1  christos   *)
   5698  1.1  christos     error "main_display(): unknown mode \`${_DISPLAY_MODE}'";
   5699  1.1  christos     ;;
   5700  1.1  christos   esac;
   5701  1.1  christos   eval ${_UNSET} md_addopts;
   5702  1.1  christos   eval ${_UNSET} md_device;
   5703  1.1  christos   eval ${_UNSET} md_groggy;
   5704  1.1  christos   eval ${_UNSET} md_modefile;
   5705  1.1  christos   eval ${_UNSET} md_options;
   5706  1.1  christos   eval ${_UNSET} md_p;
   5707  1.1  christos   eval ${_UNSET} md_pager;
   5708  1.1  christos   eval "${return_ok}";
   5709  1.1  christos } # main_display()
   5710  1.1  christos 
   5711  1.1  christos 
   5712  1.1  christos ########################
   5713  1.1  christos # _do_display ([<prog>])
   5714  1.1  christos #
   5715  1.1  christos # Perform the generation of the output and view the result.  If an
   5716  1.1  christos # argument is given interpret it as a function name that is called in
   5717  1.1  christos # the midst (actually only for `pdf').
   5718  1.1  christos #
   5719  1.1  christos # Globals: $md_modefile, $md_groggy (from main_display())
   5720  1.1  christos #
   5721  1.1  christos _do_display()
   5722  1.1  christos {
   5723  1.1  christos   func_check _do_display '>=' 0 "$@";
   5724  1.1  christos   _do_opt_V;
   5725  1.1  christos   if obj _DISPLAY_PROG is_empty
   5726  1.1  christos   then
   5727  1.1  christos     trap_unset;
   5728  1.1  christos     {
   5729  1.1  christos       trap_set;
   5730  1.1  christos       eval "${md_groggy}" "${_ADDOPTS_GROFF}" "${_TMP_CAT}";
   5731  1.1  christos     } &
   5732  1.1  christos   else
   5733  1.1  christos     obj md_modefile rm_file;
   5734  1.1  christos     cat "${_TMP_CAT}" | \
   5735  1.1  christos       eval "${md_groggy}" "${_ADDOPTS_GROFF}" > "${md_modefile}";
   5736  1.1  christos     if is_not_empty "$1"
   5737  1.1  christos     then
   5738  1.1  christos       eval "$1";
   5739  1.1  christos     fi;
   5740  1.1  christos     obj _TMP_CAT rm_file_with_debug;
   5741  1.1  christos     if obj _VIEWER_TERMINAL is_yes # for programs that run on tty
   5742  1.1  christos     then
   5743  1.1  christos       eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
   5744  1.1  christos     else
   5745  1.1  christos       case "${_DISPLAY_PROG}" in
   5746  1.1  christos #      lynx\ *|less\ *|more\ *) # programs known to run on the terminal
   5747  1.1  christos #        eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
   5748  1.1  christos #        ;;
   5749  1.1  christos       *)
   5750  1.1  christos         trap_unset;
   5751  1.1  christos         {
   5752  1.1  christos           trap_set;
   5753  1.1  christos           eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
   5754  1.1  christos         } &
   5755  1.1  christos         ;;
   5756  1.1  christos       esac;
   5757  1.1  christos     fi;
   5758  1.1  christos   fi;
   5759  1.1  christos   eval "${return_ok}";
   5760  1.1  christos } # _do_display() of main_display()
   5761  1.1  christos 
   5762  1.1  christos 
   5763  1.1  christos #############
   5764  1.1  christos # _do_opt_V ()
   5765  1.1  christos #
   5766  1.1  christos # Check on option `-V'; if set print the corresponding output and leave.
   5767  1.1  christos #
   5768  1.1  christos # Globals: $_ALL_PARAMS, $_ADDOPTS_GROFF, $_DISPLAY_MODE, $_DISPLAY_PROG,
   5769  1.1  christos #          $_DISPLAY_ARGS, $md_groggy,  $md_modefile
   5770  1.1  christos #
   5771  1.1  christos # Variable prefix: _doV
   5772  1.1  christos #
   5773  1.1  christos _do_opt_V()
   5774  1.1  christos {
   5775  1.1  christos   func_check _do_opt_V '=' 0 "$@";
   5776  1.1  christos   if obj _OPT_V is_yes
   5777  1.1  christos   then
   5778  1.1  christos     _OPT_V='no';
   5779  1.1  christos     echo1 "Parameters:     ${_ALL_PARAMS}";
   5780  1.1  christos     echo1 "Display mode:   ${_DISPLAY_MODE}";
   5781  1.1  christos     echo1 "Output file:    ${md_modefile}";
   5782  1.1  christos     echo1 "Display prog:   ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
   5783  1.1  christos     a="$(eval echo1 "'${_ADDOPTS_GROFF}'")";
   5784  1.1  christos     exit_test;
   5785  1.1  christos     echo1 "Output of grog: ${md_groggy} $a";
   5786  1.1  christos     _doV_res="$(eval "${md_groggy}" "${_ADDOPTS_GROFF}")";
   5787  1.1  christos     exit_test;
   5788  1.1  christos     echo1 "groff -V:       ${_doV_res}"
   5789  1.1  christos     leave;
   5790  1.1  christos   fi;
   5791  1.1  christos   eval "${return_ok}";
   5792  1.1  christos } # _do_opt_V() of main_display()
   5793  1.1  christos 
   5794  1.1  christos 
   5795  1.1  christos ##############
   5796  1.1  christos # _make_pdf ()
   5797  1.1  christos #
   5798  1.1  christos # Transform to pdf format; for pdf mode in _do_display().
   5799  1.1  christos #
   5800  1.1  christos # Globals: $md_modefile (from main_display())
   5801  1.1  christos # 
   5802  1.1  christos # Variable prefix: _mp
   5803  1.1  christos #
   5804  1.1  christos _make_pdf()
   5805  1.1  christos {
   5806  1.1  christos   func_check _do_display '=' 0 "$@";
   5807  1.1  christos   _mp_psfile="${md_modefile}";
   5808  1.1  christos   md_modefile="${md_modefile}.pdf";
   5809  1.1  christos   obj md_modefile rm_file;
   5810  1.1  christos   if gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
   5811  1.1  christos         -sOutputFile="${md_modefile}" -c save pop -f "${_mp_psfile}"
   5812  1.1  christos   then
   5813  1.1  christos     :;
   5814  1.1  christos   else
   5815  1.1  christos     error '_make_pdf: could not transform into pdf format.';
   5816  1.1  christos   fi;
   5817  1.1  christos   obj _mp_psfile rm_file_with_debug;
   5818  1.1  christos   eval ${_UNSET} _mp_psfile;
   5819  1.1  christos   eval "${return_ok}";
   5820  1.1  christos } # _make_pdf() of main_display()
   5821  1.1  christos 
   5822  1.1  christos 
   5823  1.1  christos ########################################################################
   5824  1.1  christos # main (<command_line_args>*)
   5825  1.1  christos #
   5826  1.1  christos # The main function for groffer.
   5827  1.1  christos #
   5828  1.1  christos # Arguments:
   5829  1.1  christos #
   5830  1.1  christos main()
   5831  1.1  christos {
   5832  1.1  christos   func_check main '>=' 0 "$@";
   5833  1.1  christos   # Do not change the sequence of the following functions!
   5834  1.1  christos   landmark '13: main_init()';
   5835  1.1  christos   main_init;
   5836  1.1  christos   landmark '14: main_parse_MANOPT()';
   5837  1.1  christos   main_parse_MANOPT;
   5838  1.1  christos   landmark '15: main_parse_args()';
   5839  1.1  christos   main_parse_args "$@";
   5840  1.1  christos   landmark '16: main_set_mode()';
   5841  1.1  christos   main_set_mode;
   5842  1.1  christos   landmark '17: main_do_fileargs()';
   5843  1.1  christos   main_do_fileargs;
   5844  1.1  christos   landmark '18: main_set_resources()';
   5845  1.1  christos   main_set_resources;
   5846  1.1  christos   landmark '19: main_display()';
   5847  1.1  christos   main_display;
   5848  1.1  christos   eval "${return_ok}";
   5849  1.1  christos }
   5850  1.1  christos 
   5851  1.1  christos 
   5852  1.1  christos ########################################################################
   5853  1.1  christos 
   5854  1.1  christos main "$@";
   5855