groff-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Groff-commit] groff/contrib/groffer ChangeLog Makefile.sub RE...


From: Werner LEMBERG
Subject: [Groff-commit] groff/contrib/groffer ChangeLog Makefile.sub RE...
Date: Wed, 03 Aug 2005 02:32:11 -0400

CVSROOT:        /cvsroot/groff
Module name:    groff
Branch:         
Changes by:     Werner LEMBERG <address@hidden> 05/08/03 06:32:11

Modified files:
        contrib/groffer: ChangeLog Makefile.sub README README_SH TODO 
                         groffer.man groffer.sh groffer2.sh 

Log message:
        * release of groffer 0.9.21
        
        ### @...@ constructs
        
        * groffer.sh:
        - $_AT: New variable for `@'.
        - @...@: Replace the @...@ constructs by variables _AT_..._AT.
        These constructs are transformed by `make' to useful information.
        Keep all of these constructs in the first part of groffer.sh.  For
        a run before a `make' call, the script sets these variables to
        special values for testing purpose.
        - $_GROFFER_LIBDIR: Variable pointing to the groffer library
        directory @libdir@/groff/groffer.
        
        ### Configuration files
        
        * groffer.sh:
        - Add test for `$()' construct.
        - Read and transform the configuration files and execute the
        emerging commands.  The `sed' script was heavily enlarged to
        handle line with spaces and quotes.  The emerging script is now
        called by `eval', so no temporary file is needed.
        - $_CONF_FILE_ETC, $_CONF_FILE_HOME: New variables for the config
        files.
        - $_SQ, $_SP: Move variables for characters before the handling of
        the configuration files.  Rename $_SQUOTE to $_SQ and $_SPACE to
        $_SP.
        - $GROFFER_OPT: Remove cleaning of this variable before the
        reading of the configuration files.
        
        * groffer2.sh:
        - main_init(): Remove the getting of the configuration files.
        
        ### Rewrite the shell determination
        
        * groffer.sh:
        - Get rid of all functions in `groffer.sh'.  Rewrite the shell
        determination with `` and $().
        - --shell: Shortest abbreviation is `--sh'.  Allow arguments for
        the shell name.
        - Allow an empty argument for --shell as shell name to overwrite a
        specified shell; an empty shell name gets back to the default
        shell.
        - The shell determination now inludes the full handling of the
        config files.  The `--shell' option needs no longer a line
        starting with `-'.
        
        ### Test of unset
        
        * groffer.sh:
        - Remove test of `unset'.
        - Remove all calls of `unset'.
        - Use one character names for all variables that are meant to be
        local in this script.
        
        * groffer2.sh:
        - Move the test of `unset' to the testing of rudimentary shell
        functionality without change.
        
        ### Allow abbreviations for long options
        
        * groffer2.sh:
        - list_has_abbrev(): New function for checking a list having an
        element with a given abbreviation.
        - list_get_single_from_abbrev(): New function to retrieve the
        element having a given abbreviation.
        - list_from_cmd_line(): For an option abbreviation determine the
        corresponding long option.
        - From the man option lists remove the elements that are also in
        a groffer list.
        - Allow abbreviation for the early test of --debug.
        
        * groffer.sh: Allow abbreviation for the early test on --shell.
        - get_opt_shell(): Rewrite _get_opt_shell() and the shell test
        around it.
        - test_on_shell(): Rename function _test_on_shell().
        - $_SHELL: global variable for the shell to run groffer2.sh.
        
        ### Get rid of `sh -c'
        
        * groffer2.sh:
        - main_display(), _do_display(): Remove the `sh -c' calls.  Make
        the cleanup working without it.
        - _do_display(): Extend _do_display() such thatit can be used for
        the pdf mode as well.
        - _make_pdf(): New subfunction of main_display() for running the
        additional parts of pdf mode in _do_display().
        - rm_file(), rm_file_with_debug(), rm_tree(): New functions for
        removing files and directories.
        
        ### Change directory
        
        * groffer2.sh:
        - $_START_DIR: New variable to store the directory at the starting
        time of the script.
        - main_display(): Go to the groffer temporary directory to be able
        to process internal `groff' data like pictures.
        - clean_up(): Get back to the starting directory.
        
        ### Compatibility with strange shells
        
        * groffer2.sh:
        - clean_up(): `zsh' and `posh' had difficulties with `eval'.
        - is_*(): Add test on empty argument.  Some shells return true on
        `test -d' etc. with empty argument, while most shells return
        false.
        - echo1(); New function to print single line `cat <<EOF'.  Replace
        all `echo x' by `echo1'.
        - list_has_abbrev(), list_from_cmdline(): Correction.
        - main_parse_MANOPT(): Repair and revise.
        - --do-nothing: New option without output (for development).
        - Rewrite rudimentary shell functionality near the beginning of
        the script.
        
        * groffer.sh, groffer2.sh:
        - Remove `;' after the commands `if', `while', and `until'.
        
        ### Debugging information
        
        * groffer2.sh:
        - $_DEBUG_PRINT_PARAMS: New variable for printing all parameters
        from the config files, $GROFFER_OPT, and command line after they
        have been transformed.
        - $_DEBUG_PRINT_SHELL: New variable for printing the name of the
        shell found in groff.sh.
        - main(): Move the landmarks of main-*() into main().
        
        ### Further checks and additions
        
        * groffer.sh, groffer2.sh:
        - $_PROGRAM_NAME: Replace this variable by `groffer'.  The program
        name is now stable.
        - $_GROFFER_RUN: Remove this variable.  As `groffer.sh' or
        `groffer' is no longer rerun, this variable is not necessary any
        more.
        
        * groffer2.sh:
        - main_set_resources(): Make the default viewers capable to use
        arguments in the list.
        - leave(): Add an argument for given exit code.  Use it where
        suitable in main_*().
        - do_filearg(): Add error messages for non-existing files and man
        pages.
        - _do_opt_V(): New subfunction of main_display() to handle the
        output for option `-V'.  `groff -V' is greatly enlarged by
        `groffer' specific information.
        - register_title(): Handle file names with spaces.  Replace spaces
        by `_'.
        - is_existing(): Add `test -c' for special files.
        - usage(): Add `=arg' to the options with an argument.  Add option
        `--tty-viewer'.
        - kghostview: In the default viewer list, add option
        `--scale=1.45'.
        - $_OPTS_CMDLINE_SHORT_NA: Correct a lacking space.
        
        * Makefile.sub: Repair the installation instructions for
        groffer2.sh.
        
        * groffer.man:
        - Add paragraph on option handling.
        - Add option `--do-nothing'.
        - Reorder option for development and `groff'.
        - Rewrite documentation for option `-V'.
        - Expand `--shell'.
        - Reformulate sections CONFIGURATION FILES, COMPATIBILITY and SEE
        ALSO.
        - Make `man' italic where possible.
        - .copyleft: Adjust the fonts.
        
        * README: Update sections `Output' and `Compatibility'.
        
        * README_SH:
        - Add `mksh' as compatible shell.
        - Add information on the scripts after the split.
        
        * TODO: Remove some fulfilled parts.
        
        * ChangeLog: Remove final spaces.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/ChangeLog.diff?tr1=1.31&tr2=1.32&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/Makefile.sub.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/README.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/README_SH.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/TODO.diff?tr1=1.13&tr2=1.14&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/groffer.man.diff?tr1=1.26&tr2=1.27&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/groffer.sh.diff?tr1=1.31&tr2=1.32&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/contrib/groffer/groffer2.sh.diff?tr1=1.1&tr2=1.2&r1=text&r2=text

Patches:
Index: groff/contrib/groffer/ChangeLog
diff -u groff/contrib/groffer/ChangeLog:1.31 
groff/contrib/groffer/ChangeLog:1.32
--- groff/contrib/groffer/ChangeLog:1.31        Sun Jul 31 07:53:15 2005
+++ groff/contrib/groffer/ChangeLog     Wed Aug  3 06:32:11 2005
@@ -1,4 +1,186 @@
        ________________________________________________________________
+       * release of groffer 0.9.21
+
+2005-08-02  Bernd Warken
+
+       ### @...@ constructs
+
+       * groffer.sh:
+       - $_AT: New variable for `@'.
+       - @...@: Replace the @...@ constructs by variables _AT_..._AT.
+       These constructs are transformed by `make' to useful information.
+       Keep all of these constructs in the first part of groffer.sh.  For
+       a run before a `make' call, the script sets these variables to
+       special values for testing purpose.
+       - $_GROFFER_LIBDIR: Variable pointing to the groffer library
+       directory @libdir@/groff/groffer.
+
+       ### Configuration files
+
+       * groffer.sh:
+       - Add test for `$()' construct.
+       - Read and transform the configuration files and execute the
+       emerging commands.  The `sed' script was heavily enlarged to
+       handle line with spaces and quotes.  The emerging script is now
+       called by `eval', so no temporary file is needed.
+       - $_CONF_FILE_ETC, $_CONF_FILE_HOME: New variables for the config
+       files.
+       - $_SQ, $_SP: Move variables for characters before the handling of
+       the configuration files.  Rename $_SQUOTE to $_SQ and $_SPACE to
+       $_SP.
+       - $GROFFER_OPT: Remove cleaning of this variable before the
+       reading of the configuration files.
+
+       * groffer2.sh:
+       - main_init(): Remove the getting of the configuration files.
+
+       ### Rewrite the shell determination
+
+       * groffer.sh:
+       - Get rid of all functions in `groffer.sh'.  Rewrite the shell
+       determination with `` and $().
+       - --shell: Shortest abbreviation is `--sh'.  Allow arguments for
+       the shell name.
+       - Allow an empty argument for --shell as shell name to overwrite a
+       specified shell; an empty shell name gets back to the default
+       shell.
+       - The shell determination now inludes the full handling of the
+       config files.  The `--shell' option needs no longer a line
+       starting with `-'.
+
+       ### Test of unset
+
+       * groffer.sh:
+       - Remove test of `unset'.
+       - Remove all calls of `unset'.
+       - Use one character names for all variables that are meant to be
+       local in this script.
+
+       * groffer2.sh:
+       - Move the test of `unset' to the testing of rudimentary shell
+       functionality without change.
+
+        ### Allow abbreviations for long options
+
+       * groffer2.sh:
+       - list_has_abbrev(): New function for checking a list having an
+       element with a given abbreviation.
+       - list_get_single_from_abbrev(): New function to retrieve the
+       element having a given abbreviation.
+       - list_from_cmd_line(): For an option abbreviation determine the
+       corresponding long option.
+       - From the man option lists remove the elements that are also in
+       a groffer list.
+       - Allow abbreviation for the early test of --debug.
+
+       * groffer.sh: Allow abbreviation for the early test on --shell.
+       - get_opt_shell(): Rewrite _get_opt_shell() and the shell test
+       around it.
+       - test_on_shell(): Rename function _test_on_shell().
+       - $_SHELL: global variable for the shell to run groffer2.sh.
+
+       ### Get rid of `sh -c'
+
+       * groffer2.sh:
+       - main_display(), _do_display(): Remove the `sh -c' calls.  Make
+       the cleanup working without it.
+       - _do_display(): Extend _do_display() such that it can be used for
+       the pdf mode as well.
+       - _make_pdf(): New subfunction of main_display() for running the
+       additional parts of pdf mode in _do_display().
+       - rm_file(), rm_file_with_debug(), rm_tree(): New functions for
+       removing files and directories.
+
+       ### Change directory
+
+       * groffer2.sh:
+       - $_START_DIR: New variable to store the directory at the starting
+       time of the script.
+       - main_display(): Go to the groffer temporary directory to be able
+       to process internal `groff' data like pictures.
+       - clean_up(): Get back to the starting directory.
+
+       ### Compatibility with strange shells
+
+       * groffer2.sh:
+       - clean_up(): `zsh' and `posh' had difficulties with `eval'.
+       - is_*(): Add test on empty argument.  Some shells return true on
+       `test -d' etc. with empty argument, while most shells return
+       false.
+       - echo1(); New function to print single line `cat <<EOF'.  Replace
+       all `echo x' by `echo1'.
+       - list_has_abbrev(), list_from_cmdline(): Correction.
+       - main_parse_MANOPT(): Repair and revise.
+       - --do-nothing: New option without output (for development).
+       - Rewrite rudimentary shell functionality near the beginning of
+       the script.
+
+       * groffer.sh, groffer2.sh:
+       - Remove `;' after the commands `if', `while', and `until'.
+
+       ### Debugging information
+
+       * groffer2.sh:
+       - $_DEBUG_PRINT_PARAMS: New variable for printing all parameters
+       from the config files, $GROFFER_OPT, and command line after they
+       have been transformed.
+       - $_DEBUG_PRINT_SHELL: New variable for printing the name of the
+       shell found in groff.sh.
+       - main(): Move the landmarks of main-*() into main().
+
+       ### Further checks and additions
+
+       * groffer.sh, groffer2.sh:
+       - $_PROGRAM_NAME: Replace this variable by `groffer'.  The program
+       name is now stable.
+       - $_GROFFER_RUN: Remove this variable.  As `groffer.sh' or
+       `groffer' is no longer rerun, this variable is not necessary any
+       more.
+
+       * groffer2.sh:
+       - main_set_resources(): Make the default viewers capable to use
+       arguments in the list.
+       - leave(): Add an argument for given exit code.  Use it where
+       suitable in main_*().
+       - do_filearg(): Add error messages for non-existing files and man
+       pages.
+       - _do_opt_V(): New subfunction of main_display() to handle the
+       output for option `-V'.  `groff -V' is greatly enlarged by
+       `groffer' specific information.
+       - register_title(): Handle file names with spaces.  Replace spaces
+       by `_'.
+       - is_existing(): Add `test -c' for special files.
+       - usage(): Add `=arg' to the options with an argument.  Add option
+       `--tty-viewer'.
+       - kghostview: In the default viewer list, add option
+       `--scale=1.45'.
+       - $_OPTS_CMDLINE_SHORT_NA: Correct a lacking space.
+
+       * Makefile.sub: Repair the installation instructions for
+       groffer2.sh.
+
+       * groffer.man:
+       - Add paragraph on option handling.
+       - Add option `--do-nothing'.
+       - Reorder option for development and `groff'.
+       - Rewrite documentation for option `-V'.
+       - Expand `--shell'.
+       - Reformulate sections CONFIGURATION FILES, COMPATIBILITY and SEE
+       ALSO.
+       - Make `man' italic where possible.
+       - .copyleft: Adjust the fonts.
+
+       * README: Update sections `Output' and `Compatibility'.
+
+       * README_SH:
+       - Add `mksh' as compatible shell.
+       - Add information on the scripts after the split.
+
+       * TODO: Remove some fulfilled parts.
+
+       * ChangeLog: Remove final spaces.
+
+       ________________________________________________________________
        * release of groffer 0.9.20
 
 2005-07-30  Bernd Warken
@@ -80,7 +262,7 @@
        - Add information on the debug process.
        - Add information on the default devices in `x mode'.
        - Minor corrections.
-       
+
        ________________________________________________________________
        * release of groffer 0.9.18
 
@@ -135,7 +317,7 @@
        - Add date line `Latest update:'.
        - Add `...' quoting to essential terms.
        - Add Emacs mode at the end.
-       
+
        * README_SH:
        - Add documentation on the above compatibility changes.
        - Add documentation on used commands.
@@ -179,7 +361,7 @@
 2005-06-20 Keith Marshall
 
        * README-SH: Information of `Portable shells' in info autoconf.
-       
+
        ________________________________________________________________
        * release of groffer 0.9.16
 
@@ -193,7 +375,7 @@
        * README_SH:
        - Add compatibility information.
        - Correct documentation for function arguments.
-       
+
 2005-06-18  Keith Marshall
 
        * groffer.sh: $_NULL_DEV: Replace /dev/null by $_NULL_DEV which is
@@ -203,7 +385,7 @@
 
        * Makefile.sub: $(RM): Define it to `rm -f' because not all `make'
        programs have it predefined.
-       
+
 2005-06-16  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.9.15
@@ -266,7 +448,7 @@
        * groffer.sh:
        - To the search of the `--apropos-*' options, add man pages with a
        subsection in their apropos output.
-       
+
 2004-06-02  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.9.10
@@ -294,7 +476,7 @@
        - Add minus line behavior of `--shell' for configuration and add a
        corresponding example.
        - Update the information on $POSIXLY_CORRECT.
-               
+
 2004-05-29  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.9.9
@@ -305,7 +487,7 @@
 
        * groffer.man:
        Remove unnecessary information on groffer version.
-       
+
 2004-05-12  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.9.8
@@ -319,7 +501,7 @@
 
        * .cvsignore:
        Restore this file.
-       
+
 2004-04-30  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.9.7
@@ -329,7 +511,7 @@
        oriented functions to minimize complicated `eval' commands.
        - list_*(): Corrections.
        - usage(): Streamlining.
-       
+
        * groffer.man, README_SH:
        Corrections.
 
@@ -348,7 +530,7 @@
 
        * README, README_SH, TODO:
        Add license GNU General Public License (GPL).
-       
+
        * Makefile.sub, groffer.sh:
        Keep the GNU General Public License (GPL), but refer to the
        COPYING and LICENSE files.
@@ -371,7 +553,7 @@
        New file:
        <groffer-source>/README_SH
 
-       
+
        ******* Extension of the `apropos' handling
 
         The output of man's `apropos' has grown immensely meanwhile, so it
@@ -402,7 +584,7 @@
        specify function arguments and the calling syntax in a simpler way
        by letting the first argument be a variable name, usable for input
        or output.
-       
+
        Such an object type is `list', the string value of a shell
        variable arranged in space-separated single-quoted elements, such
        as $GROFFER_OPT internally.
@@ -424,7 +606,7 @@
        spaces at the beginning.of the line are omitted.
        - all other lines are interpreted as a shell command and executed
        in the current shell of the groffer call.
-       
+
        Precedence:
        - The command line and the external environment variables such as
        $GROFFER_OPT of the groffer call have the highest precedence.
@@ -432,8 +614,8 @@
        directory.
        - The system configuration file in /etc has the lowest
        precedence.
-       
-       * groffer.sh:   
+
+       * groffer.sh:
        The configuration files are now called after the determination of
        the temporary files in main_init().
 
@@ -450,7 +632,7 @@
        - Force the script to be called as an executable file, so $0 must
        contain the program name.
 
-       
+
        ******* Improved temporary file names
 
        Just like groff, groffer mixes all file parameters into a single
@@ -458,7 +640,7 @@
        list built from the file name arguments without a leading comma.
        So a leading comma can be used for the internal temporary file
        names.
-       
+
        * groffer.sh:
        - $_OUTPUT_FILE_NAME: new global variable as basis for the output
        file name; it is set in main_set_resources().
@@ -523,9 +705,9 @@
        - man_search_section(): correction of some `for' loops.
        - Remove export of external non-groffer variables.
 
-       
+
        ******* Documentation
-       
+
        * groffer.man:
        - Reorder the option details according to the option origin as
        groffer, groff, X, and man options.
@@ -535,19 +717,19 @@
        * README_SH: new file
        Move large parts of the documentation in `groffer.sh' into this
        file.
-       
+
        * groffer.sh: usage():
        - Change the output for `--help' to standard output.
        - Restructure the information for this help output.
-       
+
 
        ******* Removement of the author's email address
-       
+
        Because of the extreme spam attacks, the author removed all
        occurencies of his email address in every file of the groffer
        source.
 
-2003-01-22  Bernd Warken 
+2003-01-22  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.9.4
 
@@ -564,11 +746,11 @@
        - Test existence of directory before deleting it in the
        `clean_up' definitions.
        - Correct help output in `usage' (called by `--help').
-       
+
        * TODO:
        Remove mention of `shoop' and `apropos'.
 
-2002-10-21  Bernd Warken 
+2002-10-21  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.9.3
 
@@ -591,8 +773,8 @@
        * TODO: think about...
        - writing part of groffer in C/C++.
        - handling several files with different macro packages.
-       
-2002-10-17  Bernd Warken 
+
+2002-10-17  Bernd Warken
        ________________________________________________________________
        * fixes of groffer 0.9.2
 
@@ -604,12 +786,12 @@
        - New macro ".Header_CB" for CB font in .TP headers; used for
        definition of variables in option --mode.
        - Fix some option references to refer to long options.
-       
+
        * README:
        New file for general information on the groffer source; it is
        not installed.
-       
-2002-10-14  Bernd Warken 
+
+2002-10-14  Bernd Warken
 
        * Makefile.sub:
        add replacement "@BINDIR@" to "$(bindir)" for "groffer:"
@@ -621,7 +803,7 @@
        * groffer.man:
        Remove double definition of filespec parameters.
 
-2002-10-13  Bernd Warken 
+2002-10-13  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.9.2
 
@@ -643,16 +825,16 @@
        - New macro for file names ".File_name".
        - "Option Parsing" is moved to section "COMPATIBILITY".
        - Fix some "EXAMPLES".
-       
-2002-09-30  Bernd Warken 
+
+2002-09-30  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.9.1
-       
+
        * TODO: remove done entries
        - Remove request for different shells.
        - Remove the 'sed' complaints.
 
-2002-07-15  Bernd Warken 
+2002-07-15  Bernd Warken
 
        * groffer.sh: replace `sed' interface by direct `sed'
        - This improves the performance of the shell programming parts
@@ -676,7 +858,7 @@
          groffer was called from the command line, or with the shell
          name in the first line of the script, actually `/bin/sh'.
 
-2002-07-12  Bernd Warken 
+2002-07-12  Bernd Warken
        ________________________________________________________________
        * fixes for groffer 0.9.0
 
@@ -686,7 +868,7 @@
        - the string `is part of '
        - groff's version information (version number and copyright),
          but not groff's `called subprograms' information.
-       
+
        * groffer.sh: minor fixes
        - Fix the argument parser to process argument `-' correctly.
        - Some display programs have trouble with empty input; feed a
@@ -696,7 +878,7 @@
        * TODO:
        fix entry `shoop' (not 'shopt').
 
-2002-06-28  Bernd Warken 
+2002-06-28  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.9.0
 
@@ -709,25 +891,25 @@
        - New options `--pdf', `--pdf-viewer', `--mode pdf'.
        - Standard pdf viewers `xpdf' and `acroread'.
        - For `xpdf', choose zoom `z 3' for 100 dpi, `z 2' for 75 dpi.
-       
+
        * groffer.sh: support bzip2 decompression
        - add test for `bzip2' with necessary options
        - extend functions `catz()' and `save_stdin()'.
 
        * TODO
        remove entry on `bzip' decompression (done).
-       
+
        * groffer.man:
        - Document new `pdf' features.
        - Document new `bzip2' decompression.
        - Fix documentation for `--auto-modes'.
-       
+
        * groffer.sh: minor fixes
        - Improve device tests in `tty' and `dvi' modes.
        - Internally, map mode `auto' to '' to facilitate tests.
        - Fix auto mode sequence to: `ps,x,tty' as was intended.
 
-2002-06-25  Bernd Warken 
+2002-06-25  Bernd Warken
 
        * groffer.sh:
        Fix `source' mode.
@@ -735,7 +917,7 @@
        * groffer.man:
        Fix some indentations.
 
-2002-06-23  Bernd Warken 
+2002-06-23  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.8
 
@@ -747,7 +929,7 @@
        - Document the configuration files in new section `FILES'.
        - Redesign section `EXAMPLES'.
        - Remove documentation for `-W'.
-       
+
        * groffer.sh: new debugging features
        - Disabled by default; enabled by environment variables.
        - Add landmark() to catch typos with quotes.
@@ -759,7 +941,7 @@
        - Actually, the groffer script uses only shell builtins found
          in `ash' (a subset of POSIX) and POSIX `sed' as the only
          external shell utility.
-               
+
        * groffer.sh: customization of viewers
        - In `groff' mode, the groffer viewing facilities are disabled.
        - The postprocessor option `-P' costumizes the viewer only in
@@ -780,7 +962,7 @@
          -> `--title': set viewer window title.
          -> `--xrm': set X resource.
        - Remove misnamed option `--xrdb'.
-       
+
        * groffer.sh: new mode structure
        - New Postcript mode `ps' (`--ps'):
          -> default viewers: gv,ghostview,gs_x11,gs;
@@ -805,7 +987,7 @@
          -> automatically active with one of `-V', `-X', `-Z'.
        - Revise `tty' mode:
          -> allow several text devices.
-         -> 
+         ->
        - Reorganize the mode management:
          -> new mode setting option `--mode'.
          -> logically separate source, groff, and display modes.
@@ -818,7 +1000,7 @@
        - `${HOME}/.groff/groffer.conf' user configuration.
        - The configuration file are shell scripts for now; later
          implementations can identify this from the `#! /bin/sh' line.
-       
+
        * groffer.sh: new data structure `list':
        - Implement a `list' data structure as a string consisting of
          single-quoted elements, separated by a space character;
@@ -835,18 +1017,18 @@
          allow unusual characters in options.
        - Parse $MANOPT first; translate essential arguments into
          groffer options.
-       
+
        * groffer.man:
        - determine prompt length for `.Shell_cmd'* dynamically.
        - naming scheme for static strings and registers changed to
          `namespace:macro.variable'.
 
-       
+
 2002-06-16  Werner Lemberg  <address@hidden>
 
        * groffer.sh:
        Implement man option `--ascii' by `-mtty-char'.
-           
+
 
 2002-05-31  Werner LEMBERG  <address@hidden>
 
@@ -854,7 +1036,7 @@
        Increase to 4m (we use `sh#' as the prompt).
 
 
-2002-05-31  Bernd Warken 
+2002-05-31  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.7
 
@@ -890,14 +1072,14 @@
        - fix TP_header.
 
 
-2002-05-28  Bernd Warken 
+2002-05-28  Bernd Warken
        ________________________________________________________________
        * release of groffer 0.6
 
        This is almost a complete rewrite since groffer 0.5 .
        ________________________________________________________________
        * Documentation
-       
+
        * groffer.man:
        - Apply the changes done in www.tmac (.URL and .MTO)
        - Replace \fP by \f[].
@@ -930,7 +1112,7 @@
        - The only external programs used are POSIX `sed' and the
          fallback to `apropos'.  All other program calls were
          replaced by shell builtins and functions.
-       
+
        ________________________________________________________________
        * Cosmetics
 
@@ -982,10 +1164,10 @@
          characters in file names).
        - Fix and complement usage().
        - The filespec parsers gets a function of its own do_manpage().
-       
-       
-2002-01-08  Bernd Warken 
-       
+
+
+2002-01-08  Bernd Warken
+
        * groffer 0.5 (beta) released
 
        * groffer.man:
@@ -994,7 +1176,7 @@
        - Examples of shell commands now print in font CR instead of CB.
        - Remove documentation for option `-X'.
        - Add documentation for option `--dpi'.
-       
+
        * groffer.sh:
        - New method for creating temporary files, based on process
          IDs.  This is reliable enough and suitable for GNU and POSIX.
@@ -1011,15 +1193,15 @@
        - Implement option `--dpi' for setting the resolution for the X
          viewer, which had already been documented in earlier versions.
 
-2002-01-07  Bernd Warken 
+2002-01-07  Bernd Warken
 
        * groffer 0.4 (beta) released (as groff `contrib')
-       
+
        * groffer.man:
        - New features documented.
        - Macros stream-lined.
        - Section EXAMPLES added.
-       
+
        * groffer.sh:
        - System tests added/optimized.
        - Speed/memory optimizations by defining some shell functions
@@ -1050,7 +1232,7 @@
         * groffer.man (OptDef): Add missing backslashes.
         Update copyright.
 
-2001-12-15  Bernd Warken 
+2001-12-15  Bernd Warken
 
        * groffer 0.3 (alpha) released (still stand-alone package).
 
@@ -1068,20 +1250,20 @@
 
        * Recognize the following filespecs as man-page parameters:
          man:name(section), man:name, name.section, name.
-       
-2001-12-03  Bernd Warken 
+
+2001-12-03  Bernd Warken
 
        * Stand-alone package for groffer 0.2 (alpha) created
        Files: groffer, groffer.man, Makefile, TODO, ChangeLog
-       
-2001-12-02  Bernd Warken 
+
+2001-12-02  Bernd Warken
 
        * groffer 0.2 (alpha) program released.
 
        * Name changed from `groffview' to `groffer'.
 
        * Comments added.
-       
+
        * Name changed from `groffview' to `groffer'.
 
        * Options harmonized with groff.
@@ -1093,14 +1275,14 @@
        * Bugs with temporary files fixed.
 
        * Code restructured and comments added.
-       
-2001-11-28  Bernd Warken 
+
+2001-11-28  Bernd Warken
 
        ***** groffview 0.1 (experimental) and groffview.man released
        (predecessor of groffer, shell script)
 
        * Options : -h --help, -v --version
-       
+
        * Search for man-pages based on $MANPATH
 
        * development of `groffview' shell script started
@@ -1110,11 +1292,13 @@
        ________________________________________________________________
        License
 
-       Copyright (C) 2001,2002,2003,2004,2005 Free Software Foundation,
-       Inc.
+       Copyright (C) 2001,2002,2003,2004,2005
+       Free Software Foundation, Inc.
        Written by Bernd Warken
+       
        Copying and distribution of this file, with or without
        modification, are permitted provided the copyright notice and this
        notice are preserved.
 
-       This file is part of groffer, which is part of the groff project.
+       This file is part of `groffer', which is part of the `groff'
+       project.
Index: groff/contrib/groffer/Makefile.sub
diff -u groff/contrib/groffer/Makefile.sub:1.11 
groff/contrib/groffer/Makefile.sub:1.12
--- groff/contrib/groffer/Makefile.sub:1.11     Sun Jul 31 07:53:15 2005
+++ groff/contrib/groffer/Makefile.sub  Wed Aug  3 06:32:11 2005
@@ -1,29 +1,27 @@
-# Makefile.sub for `groffer' (integration into the groff source tree)
+# Makefile.sub for `groffer' (integration into the `groff' source tree)
 
 # File position: <groff-source>/contrib/groffer/Makefile.sub
 
-# Last update: 30 June 2005
-
 # Copyright (C) 2001,2002,2005 Free Software Foundation, Inc.
 # Written by Werner Lemberg <address@hidden> and Bernd Warken.
 
-# Last update: 30 July 2005
+# Last update: 2 August 2005
 
-# This file is part of groffer which is part of groff.
+# This file is part of `groffer' which is part of `groff'.
 
-# groff is free software; you can redistribute it and/or modify it
+# `groff' is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 2, or (at your option)
 # any later version.
 
-# groff is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-# License for more details.
+# `groff' is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with groff; see the files COPYING and LICENSE in the top
-# directory of the groff source.  If not, write to the Free Software
+# along with `groff'; see the files COPYING and LICENSE in the top
+# directory of the `groff' source.  If not, write to the Free Software
 # Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
 
 ########################################################################
@@ -51,8 +49,9 @@
        -test -d $(libdir)/groff/groffer || \
           $(mkinstalldirs) $(libdir)/groff/groffer
        -$(RM) $(bindir)/groffer
+       -$(RM) $(libdir)/groff/groffer/groffer2.sh
        $(INSTALL_SCRIPT) groffer $(bindir)/groffer
-       $(INSTALL_SCRIPT) groffer2.sh $(libdir)/groff/groffer
+       $(INSTALL_SCRIPT) groffer2.sh $(libdir)/groff/groffer/groffer2.sh
 
 uninstall_sub:
        -$(RM) $(bindir)/groffer
Index: groff/contrib/groffer/README
diff -u groff/contrib/groffer/README:1.6 groff/contrib/groffer/README:1.7
--- groff/contrib/groffer/README:1.6    Sat Jul  2 17:37:54 2005
+++ groff/contrib/groffer/README        Wed Aug  3 06:32:11 2005
@@ -34,7 +34,7 @@
 The following displaying modes for the output are available:
 - Display formatted input with
 -- the X `roff' viewer `gxditview',
--- a Prostcript viewer,
+-- a Postcript viewer,
 -- a PDF viewer,
 -- a DVI viewer,
 -- a web browser,
@@ -43,6 +43,10 @@
 - Generate the `groff intermediate output' on standard output without
   postprocessing.
 - Output the source code without any `groff' processing.
+- There are some information outputs without `groff' processing, such
+  as by option `-V' and the `man' like `whatis' and `apropos'
+  outputs.
+
 By default, the program tries to display with `gxditview' as graphical
 device in X; on non-X text terminals, the `tty' text mode with a pager
 is tried by default.
@@ -50,42 +54,46 @@
 
 Compatibility
 
-`groffer' is a shell script.  It should run on any POSIX or Bourne
-style shell that supports shell functions.  See file `README_SH'.
+`groffer' consists of two shell scripts.  It should run on any POSIX
+or Bourne style shell that supports shell functions.  See file
+`README_SH' for more information.
 
 
 Mailing lists
 
 For reporting bugs of `groffer', groff's free mailing list
-<address@hidden> can be used.  For a general discussion, the
-mailing list <address@hidden> is more useful, but one has to subscribe
-to this list at http://lists.gnu.org/mailman/listinfo/groff.  See the
-`README' file in the top directory of the `groff' source package for
-more details on these mailing lists.
+<address@hidden> can be used.
+
+For a general discussion, the mailing list <address@hidden> is more
+useful, but one has to subscribe to this list at
+http://lists.gnu.org/mailman/listinfo/groff.
+
+See the `README' file in the top directory of the `groff' source
+package for more details on these mailing lists.
 
 
 ####### License
 
-Last update: 30 June 2005
+Last update: 2 August 2005
 
 Copyright (C) 2003,2004,2005 Free Software Foundation, Inc.
 Written by Bernd Warken
 
-This file is part of groffer, which is part of groff.
+This file is part of `groffer', which is part of `groff'.
 
-groff is free software; you can redistribute it and/or modify it
+`groff' is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
-groff is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-License for more details.
+`groff' is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
 
 You should have received a copy of the GNU General Public License
-along with groff; see the files COPYING and LICENSE in the top
-directory of the groff source.  If not, write to the Free Software
+along with `groff'; see the files COPYING and LICENSE in the top
+directory of the `groff' source.  If not, write to the Free Software
 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
 
 
Index: groff/contrib/groffer/README_SH
diff -u groff/contrib/groffer/README_SH:1.10 
groff/contrib/groffer/README_SH:1.11
--- groff/contrib/groffer/README_SH:1.10        Sun Jul 31 07:53:15 2005
+++ groff/contrib/groffer/README_SH     Wed Aug  3 06:32:11 2005
@@ -4,15 +4,20 @@
 Scripts
 
 The shell version of `groffer' contains two files, `groffer.sh' and
-`groffer2.sh'.  `groffer.sh' is a short introductory script; it is
-transformed by `make' into `groffer'; this will be installed in
+`groffer2.sh'.
+
+`groffer.sh' is a short introductory script without any functions.  I
+can be run with a very poor Bourne shell.  It just contains some basic
+variables, the reading of the configuration files, and the
+determination of the shell for `groffer2.sh'.  This script is
+transformed by `make' into `groffer' which will be installed into
 @bindir@, which is usually /usr/local/bin.
 
-`groffer2.sh' is a long main script with all functions that is called
-by `groffer.sh' and `groffer'.  It is installed unchanged into
address@hidden@/groff/groffer, which is usually /usr/local/lib/groff/groffer.
-This script can be called with a different shell, using the option
-`--shell'.  So it makes sense to split the script into two parts.
+`groffer2.sh' is a long main script with all functions; it is called
+by `groffer.sh' (`groffer' after installation).  It is installed
+unchanged into @libdir@/groff/groffer, which is usually
+/usr/local/lib/groff/groffer.  This script can be called with a
+different shell, using the `groffer' option `--shell'.
 
 
 Shell Compatibility
@@ -31,10 +36,11 @@
 function.
 
 The `groffer' scripts were tested under the shells `ash', `bash',
-`dash', 'ksh', `pdksh', 'posh', and `zsh' without problems in Linux
-Debian.  A shell can be tested by the `groffer' option `--shell', but
-that will run only with groffer2.sh.  To start it directly from the
-beginning under this shell the following command can be used.
+`dash', 'ksh', `mksh', `pdksh', 'posh', and `zsh' without problems in
+Linux Debian.  A shell can be tested by the `groffer' option
+`--shell', but that will run only with groffer2.sh.  To start it
+directly from the beginning under this shell the following command can
+be used.
 
   <shell-name> groffer.sh --shell=<shell-name> <argument>...
 
@@ -79,6 +85,11 @@
   ${_UNSET}' where this variable is `unset' if it exists and `:'
   otherwise.
 
+- Some shells have problems with options in `eval'.  So quoting must
+  be done right to hide the options from `eval'.
+
+- In backquote calls `` avoid the backquote ` in comments.
+
 - Replace `true' by `:', `false' isn't used.
 
 - Do not redefine builtins as functions (ash).
@@ -95,6 +106,7 @@
 bzip2 -c -d -t
 cat
 catz
+cd
 continue
 echo
 eval
@@ -109,6 +121,7 @@
 man -k --apropos
 mkdir
 mv
+pwd
 return
 rm -f -r
 rmdir
@@ -116,7 +129,7 @@
 set -e
 sh -c
 shift
-test -d -f -r -s -w -x
+test -c -d -f -r -s -w -x
 trap
 umask
 unset
@@ -217,26 +230,26 @@
 
 ####### License
 
-Last update: 30 July 2005
+Last update: 2 August 2005
 
 Copyright (C) 2003,2004,2005 Free Software Foundation, Inc.
 Written by Bernd Warken
 
-This file is part of groffer, which is part of groff.
+This file is part of `groffer', which is part of `groff'.
 
-groff is free software; you can redistribute it and/or modify it
+`groff' is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
-groff is distributed in the hope that it will be useful, but WITHOUT
+`groff' is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
 License for more details.
 
 You should have received a copy of the GNU General Public License
-along with groff; see the files COPYING and LICENSE in the top
-directory of the groff source.  If not, write to the Free Software
+along with `groff'; see the files COPYING and LICENSE in the top
+directory of the `groff' source.  If not, write to the Free Software
 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
 
 
Index: groff/contrib/groffer/TODO
diff -u groff/contrib/groffer/TODO:1.13 groff/contrib/groffer/TODO:1.14
--- groff/contrib/groffer/TODO:1.13     Sat Jul  2 17:37:54 2005
+++ groff/contrib/groffer/TODO  Wed Aug  3 06:32:11 2005
@@ -6,10 +6,11 @@
 ####### TODO
 
 Revision:
-- Revise the `--all' feature to better reflect GNU `man'.
-- The debug function stack is buggy (no effect on normal operation).
-- Check main_parse_MANOPT(), not too important.
-- Add long option shortcuts.
+
+- Make --apropos-* options without arguments, based on all filespecs.
+  Transform the output into a `groff' file and have it viewed; maybe
+  also for --version and -V.
+- Make --whatis a breaking option and its output a good man-page.
 
 Optimization:
 - Optimize `man' path determination in manpath_add_lang_sys() for speed
@@ -17,43 +18,41 @@
   (not trivial).
 - To increase the running speed write part of the `groffer' shell
   script in C/C++.
-- Split the `groffer.sh' shell script into several files for better
-  tests of the shell compatibility.
 
 Features of external programs:
 - Revise option handling of `grog'.
 
 Documentation:
-- Improve the documentation of the search algorithm for man pages in
-  both the `groffer' script and the man page `groffer.man'.
-- In `groff.man', add more documentation for parts that were taken over
-  from GNU `man'.
+- Improve the documentation of the search algorithm for `man' pages in
+  both the `groffer' scripts and the `man' page `groffer.man'.
+- In `groffer.man', add more documentation for parts that were taken
+  over from GNU `man'.
 - The documentation in the headers for some function definitions in
-  `groffer.sh' needs to be updated.
+  `groffer2.sh' needs to be updated.
 
 
 ####### License
 
-Last update: 30 June 2005
+Last update: 2 August 2005
 
 Copyright (C) 2003,2004,2005 Free Software Foundation, Inc.
 Written by Bernd Warken
 
-This file is part of groffer, which is part of groff.
+This file is part of `groffer', which is part of `groff'.
 
-groff is free software; you can redistribute it and/or modify it
+`groff' is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
-groff is distributed in the hope that it will be useful, but WITHOUT
+`groff' is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
 License for more details.
 
 You should have received a copy of the GNU General Public License
-along with groff; see the files COPYING and LICENSE in the top
-directory of the groff source.  If not, write to the Free Software
+along with `groff'; see the files COPYING and LICENSE in the top
+directory of the `groff' source.  If not, write to the Free Software
 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
 
 
Index: groff/contrib/groffer/groffer.man
diff -u groff/contrib/groffer/groffer.man:1.26 
groff/contrib/groffer/groffer.man:1.27
--- groff/contrib/groffer/groffer.man:1.26      Thu Jul  7 20:03:13 2005
+++ groff/contrib/groffer/groffer.man   Wed Aug  3 06:32:11 2005
@@ -15,7 +15,7 @@
 Source file position:  <groff_source_top>/contrib/groffer/groffer.man
 Installed position:    $prefix/share/man/man1/groffer.1
 
-Last update : 4 July 2005
+Last update : 2 August 2005
 
 Source file position: <groff-source>/contrib/groffer/groffer.man
 ..
@@ -26,21 +26,39 @@
 Copyright (C) 2001,2002,2004,2005 Free Software Foundation, Inc.
 .
 .P
-This file is part of groff, a free software project.
+This file is part of
+.IR \%groffer ,
+which is part of
+.IR \%groff ,
+a free software project.
 .
-You can redistribute it and/or modify it under the terms of the GNU
-General Public License as published by the Free Software Foundation;
+You can redistribute it and/or modify it under the terms of the
+.nh
+.B GNU General Public License
+.hy
+as published by the
+.nh
+.BR "Free Software Foundation" ,
+.hy
 either version 2, or (at your option) any later version.
 .
 .P
 You should have received a copy of the GNU General Public License
-along with groff, see the files COPYING and LICENSE in the top
-directory of the groff source package.
+along with
+.IR groff ,
+see the files \%\f[CB]COPYING\f[] and \%\f[CB]LICENSE\f[] in the top
+directory of the
+.I groff
+source package.
 .
-Or read the man page
+Or read the
+.I man\~page
 .BR gpl (1).
-You can also write to the Free Software Foundation, 51 Franklin St -
-Fifth Floor, Boston, MA 02110-1301, USA.
+You can also write to the
+.nh
+.B Free Software Foundation, 51 Franklin St - Fifth Floor, Boston,
+.BR "MA 02110-1301, USA" .
+.hy
 ..
 .
 .\" --------------------------------------------------------------------
@@ -700,16 +718,20 @@
 .
 .P
 The normal usage is quite simple by supplying a file name or name of a
-man\~page without further options.
+.I \%man\~page
+without further options.
 .
 But the option handling has many possibilities for creating special
 behaviors.
 .
-This can be done in configuration files, with the shell environment
-variable
+This can be done either in configuration files, with the shell
+environment variable
 .BR \%$GROFFER_OPT ,
 or on the command line.
 .
+For example, it makes sense to specify a faster shell in a
+configuration file.
+.
 .
 .P
 The output can be generated and viewed in several different ways
@@ -747,7 +769,20 @@
 Several file names can be specified on the command line arguments.
 .
 They are transformed into a single document in the normal way of
-.IR \%groff .
+.BR \%groff .
+.
+.
+.P
+Option handling is done in GNU style.
+.
+Options and file names can be mixed freely.
+.
+The option
+.RB ` \-\- '
+closes the option handling, all following arguments are treated as
+file names.
+.
+Long options can be abbreviated.
 .
 .
 .\" --------------------------------------------------------------------
@@ -801,7 +836,10 @@
 .RS
 .P
 .Opt_[alt] -- debug
-.Opt_[alt] -- shell
+.Opt_[alt] -- do\-nothing
+.Opt_[alt] -- shell prog
+.Opt_[alt] - Q -- source
+.Opt_[alt] - V
 .RE
 .
 .
@@ -809,8 +847,6 @@
 .I options related to \%groff
 .RS
 .P
-.Opt_[alt] - P -- postproc\-arg opt_or_arg
-.Opt_[alt] - Q -- source
 .Opt_[alt] - T -- device device
 .Opt_[alt] - Z -- intermediate\-output -- ditroff
 .P
@@ -884,9 +920,9 @@
 .BI man: name ( section )
 .TP+
 .IB name ( section )
-search the man\~page
+search the \%man\~page
 .I \%name
-in man\~section
+in \%man\~section
 .IR section .
 .
 .
@@ -898,15 +934,15 @@
 .I s
 is a character in
 .BR \%[1-9on] ,
-search for a man\~page
+search for a \%man\~page
 .I \%name
-in man\~section
+in \%man\~section
 .IR s .
 .
 .
 .TP
 .BI man: name
-man\~page in the lowest man\~section that has
+\%man\~page in the lowest \%man\~section that has
 .IR \%name .
 .
 .
@@ -916,9 +952,9 @@
 .I s
 is a character in
 .BR \%[1-9on] ,
-search for a man\~page
+search for a \%man\~page
 .I \%name
-in man\~section
+in \%man\~section
 .IR s .
 .
 .
@@ -973,7 +1009,8 @@
 .Opt_def -- apropos name
 Start the
 .BR \%apropos (1)
-command for searching within man\~page
+command for searching within
+.I \%man\~page
 descriptions.
 .
 That slightly differs from the strange behavior of the
@@ -1355,10 +1392,15 @@
 .Opt_long_arg mode tty .
 .
 .
-.Opt_def -- tty\-viewer
-Choose tty display mode, that means displaying in a text pager even
-when in X; eqivalent to
-.Opt_long_arg mode tty .
+.Opt_def -- tty\-viewer prog
+Choose a text pager for mode
+.IR tty .
+The standard pager is
+.BR less (1).
+This option is eqivalent to
+.I man
+option
+.Opt_long_arg pager prog .
 .
 .
 .Opt_def -- www
@@ -1432,20 +1474,27 @@
 formatting files is prohibited.
 .
 .
+.Opt_def -- do-nothing
+This is like
+.Opt_long version ,
+but without the output; no viewer is started.
+.
+This makes only sense in development.
+.
+.
 .Opt_def -- shell "shell_program"
 Specify the shell under which the
-.B \%groffer
+.File_name \%groffer2.sh
 script should be run.
 .
-The script first tests whether this option is set (either by
-configuration, within
-.Env_var $GROFF_OPT
-or as a command line option); if so, the script is rerun under the
-shell program specified with the option argument.
-.
-If you want to add this option in a configuration file you must do
-this under a line starting with a minus sign `\-', such as the line
-.Opt_long shell=\fIname\fP .
+If the argument
+.I shell_program
+is empty a former shell option is cancelled and the default shell is
+restored.
+.
+Some shells run considerably faster than the standard shell.
+.
+It makes sense to set this option in a configuration file.
 .
 .
 .Opt_def - Q -- source
@@ -1456,12 +1505,42 @@
 .Opt_long_arg mode source .
 .
 .
+.Opt_def - V
+This is an advanced option for debugging only.
+.
+Instead of displaying the formatted input, a lot of
+.I \%groffer
+specific information is printed to standard output:
+.
+.RS
+.Topic
+the output file name in the temporary directory,
+.
+.Topic
+the display mode of the actual
+.B \%groffer
+run,
+.
+.Topic
+the display program for viewing the output with its arguments,
+.
+.Topic
+the active parameters from the config files, the arguments in
+.Env_var $GROFFER_OPT ,
+and the arguments of the command line,
+.
+.Topic
+the pipeline that would be run by the
+.B \%groff
+program, but without executing it.
+.RE
+.
+.
 .P
 Other useful debugging options are the
 .B \%groff
-options
-.Opt_short V ,
-.Opt_short Z ,
+option
+.Opt_short Z
 and
 .Opt_long_arg mode groff .
 .
@@ -1485,14 +1564,12 @@
 .P
 Because of the special outputting behavior of the
 .B \%groff
-options
-.Opt_short V
-and
+option
 .Opt_short Z
 .B \%groffer
 was designed to be switched into
-.I \%groff\~mode
-by these; the
+.I \%groff\~mode ;
+the
 .I \%groffer
 viewing features are disabled there.
 .
@@ -1503,11 +1580,12 @@
 .
 .
 .Opt_def - a
-This generates an ascii approximation of output in
+This generates an ascii approximation of output in the
 .IR \%text\~modes .
 .
 That could be important when the text pager has problems with control
-sequences.
+sequences in
+.IR "tty mode" .
 .
 .
 .Opt_def - m file
@@ -1571,17 +1649,6 @@
 using this device.
 .
 .
-.Opt_def - V
-Instead of displaying the formatted input,
-.I \%groffer
-specific information is printed: the output file name , the display
-mode, the display program, and the pipeline that would be run by the
-.B \%groff
-program, but without executing it.
-.
-This is an advanced option for debugging only.
-.
-.
 .Opt_def - X
 is equivalent to
 .BR "groff \-X" .
@@ -1773,7 +1840,8 @@
 The following two options were added to
 .B \%groffer
 for choosing whether the file name arguments are interpreted as names
-for local files or as a search pattern for man\~pages.
+for local files or as a search pattern for
+.IR \%man\~pages .
 .
 The default is looking up for local files.
 .
@@ -1783,8 +1851,9 @@
 .nh
 .RI ( filespecs )
 .hy
-first on being man\~pages, then whether they represent an existing
-file.
+first on being
+.IR \%man\~pages ,
+then whether they represent an existing file.
 .
 By default, a
 .I \%filespec
@@ -1792,7 +1861,8 @@
 .
 .
 .Opt_def -- no-man -- local-file
-Do not check for man\~pages.
+Do not check for
+.IR \%man\~pages .
 .
 .Opt_long local-file
 is the corresponding
@@ -1821,8 +1891,9 @@
 .
 .
 .Opt_def -- all
-In searching man\~pages, retrieve all suitable documents instead of
-only one.
+In searching
+.IR \%man\~pages ,
+retrieve all suitable documents instead of only one.
 .
 .
 .Opt_def - 7 -- ascii
@@ -1843,19 +1914,24 @@
 .
 .
 .Opt_def -- extension suffix
-Restrict man\~page search to file names that have
+Restrict
+.I \%man\~page
+search to file names that have
 .I \%suffix
 appended to their section element.
 .
 For example, in the file name
 .I \%/usr/share/man/man3/terminfo.3ncurses.gz
-the man\~page extension is
+the
+.I \%man\~page
+extension is
 .IR \%ncurses .
 .
 .
 .Opt_def -- locale language
 .
-Set the language for man\~pages.
+Set the language for
+.IR \%man\~pages .
 .
 This has the same effect, but overwrites
 .Env_var $LANG
@@ -1875,10 +1951,12 @@
 .
 .
 .Opt_def -- manpath "'dir1:dir2:\*[Ellipsis]'"
-Use the specified search path for retrieving man\~pages instead of the
-program defaults.
+Use the specified search path for retrieving
+.I \%man\~pages
+instead of the program defaults.
 .
-If the argument is set to the empty string "" the search for man\~page
+If the argument is set to the empty string "" the search for
+.I \%man\~page
 is disabled.
 .
 .
@@ -1892,20 +1970,27 @@
 .
 .
 .Opt_def -- sections "'sec1:sec2:\*[Ellipsis]'"
-Restrict searching for man\~pages to the given
+Restrict searching for
+.I \%man\~pages
+to the given
 .IR sections ,
 a colon-separated list.
 .
 .
 .Opt_def -- systems "'sys1,sys2,\*[Ellipsis]'"
-Search for man\~pages for the given operating systems; the argument
+Search for
+.I \%man\~pages
+for the given operating systems; the argument
 .I \%systems
 is a comma-separated list.
 .
 .
 .Opt_def -- whatis
 Instead of displaying the content, get the one-liner description from
-the retrieved man\~page files \[em] or say that it is not a man\~page.
+the retrieved
+.I \%man\~page
+files \[em] or say that it is not a
+.IR \%man\~page .
 .
 .
 .Opt_def -- where
@@ -1920,7 +2005,8 @@
 A
 .I \%filespec
 parameter is an argument meaning an input source, such as a file name
-or template for searching man\~pages.
+or template for searching
+.IR \%man\~pages .
 .
 These input sources are collected and composed into a single output
 file such as
@@ -1966,12 +2052,14 @@
 .I \%filespec
 is tested whether it is the path name of an existing file.
 .
-Otherwise it is assumed as a searching pattern for a man\~page.
+Otherwise it is assumed as a searching pattern for a
+.IR \%man\~page .
 .
 .
 .P
-On each system, the man\~pages are sorted according to their content
-into several sections.
+On each system, the
+.I \%man\~pages
+are sorted according to their content into several sections.
 .
 The
 .I classical man sections
@@ -1992,24 +2080,27 @@
 .P
 The internal precedence of
 .B \%man
-for searching man\~pages with the same name within several sections
-goes according to the classical single-character sequence.
+for searching
+.I \%man\~pages
+with the same name within several sections goes according to the
+classical single-character sequence.
 .
 On some systems, this single character can be extended by a following
 string.
 .
 But the special
 .B \%groffer
-man\~page facility is based on the classical single character sections.
+.I \%man\~page
+facility is based on the classical single character sections.
 .
 .
 .P
 .BI \%man: name ( section )
 and
 .IB \%name ( section )
-search the man\~page
+search the \%man\~page
 .I \%name
-in man\~section\~\c
+in \%man\~section\~\c
 .IR \%section ,
 where
 .I \%section
@@ -2026,9 +2117,9 @@
 .BI \%man: name . s
 and
 .IB \%name . s
-search for a man\~page
+search for a \%man\~page
 .I \%name
-in man\~section
+in \%man\~section
 .I s
 if
 .I s
@@ -2036,7 +2127,9 @@
 .I classical man section
 mentioned above.
 .
-Otherwise search for a man\~page named
+Otherwise search for a
+.I \%man\~page
+named
 .IR \%name.s
 in the lowest
 .B man\~section .
@@ -2045,8 +2138,11 @@
 .P
 Now
 .BI \%man: name
-searches for a man\~page in the lowest man\~section that has a
-document called
+searches for a
+.I \%man\~page
+in the lowest
+.I \%man\~section
+that has a document called
 .IR \%name .
 .
 .
@@ -2061,7 +2157,9 @@
 .I s
 is a
 .I classical man section
-interpret it as a search for a man\~page called
+interpret it as a search for a
+.I \%man\~page
+called
 .I \%name
 in man\~section
 .IR s ,
@@ -2079,9 +2177,13 @@
 .I \%name
 which is not an existing file.
 .
-So this searches for the man\~page called
+So this searches for the
+.I \%man\~page
+called
 .I \%name
-in the lowest man\~section that has a document for this name.
+in the lowest
+.I \%man\~section
+that has a document for this name.
 .
 .
 .P
@@ -2158,8 +2260,9 @@
 .
 .
 .P
-The searching for man\~pages and the decompression of the input are
-active in every mode.
+The searching for
+.I \%man\~pages
+and the decompression of the input are active in every mode.
 .
 .
 .\" --------------------------------------------------------------------
@@ -2250,7 +2353,7 @@
 .
 .
 .\" --------------------------------------------------------------------
-.SS "Text mode"
+.SS "Text modes"
 .\" --------------------------------------------------------------------
 .
 There are two modes for text output,
@@ -2369,7 +2472,8 @@
 .B \%groffer
 is to first test whether a file parameter represents a local file; if
 it is not an existing file name, it is assumed to represent a name of
-a man\~page.
+a
+.IR \%man\~page .
 .
 This behavior can be modified by the following options.
 .
@@ -2377,33 +2481,40 @@
 .TP
 .Opt_long man
 forces to interpret all file parameters as filespecs for searching
-man\~pages.
+.IR \%man\~pages .
 .
 .TP
 .Opt_long no\-man
 .TP+
 .Opt_long local\-file
-disable the man searching; so only local files are displayed.
+disable the
+.I man
+searching; so only local files are displayed.
 .
 .
 .P
-If neither a local file nor a man\~page was retrieved for some file
-parameter a warning is issued on standard error, but processing is
-continued.
+If neither a local file nor a
+.I \%man\~page
+was retrieved for some file parameter a warning is issued on standard
+error, but processing is continued.
 .
 .
 .P
 The
 .B \%groffer
-program provides a search facility for man\~pages.
+program provides a search facility for
+.IR \%man\~pages .
 .
 All long options, all environment variables, and most of the
 functionality of the GNU
 .BR \%man (1)
 program were implemented.
 .
-This inludes the extended file names of man\~pages, for example,
-the man\~page of
+This inludes the extended file names of
+.IR \%man\~pages ,
+for example, the
+.I \%man\~page
+of
 .B \%groff
 in man\~section 7 may be stored under
 .File_name /usr/share/man/man7/groff.7.gz ,
@@ -2421,19 +2532,24 @@
 .P
 The
 .I cat\~pages
-(preformatted man\~pages) are intentionally excluded from the search
-because
+(preformatted
+.IR \%man\~pages )
+are intentionally excluded from the search because
 .B \%groffer
 is a
 .I roff
 program that wants to format by its own.
 .
 With the excellent performance of the actual computers, the
-preformatted man\~pages aren't necessary any longer.
+preformatted
+.I \%man\~pages
+aren't necessary any longer.
 .
 .
 .P
-The algorithm for retrieving man\~pages uses five search methods.
+The algorithm for retrieving
+\I \%man\~pages
+uses five search methods.
 .
 They are successively tried until a method works.
 .
@@ -2441,7 +2557,9 @@
 .Topic
 The search path can be manually specified by using the option
 .Opt_long manpath .
-An empty argument disables the man\~page searching.
+An empty argument disables the
+.I \%man\~page
+searching.
 .
 This overwrites the other methods.
 .
@@ -2461,25 +2579,33 @@
 .Topic
 If this does not work a reasonable default path from
 .Env_var $PATH
-is searched for man\~pages.
+is searched for
+.IR \%man\~pages .
 .
 .
 .Topic
 If this does not work, the
 .BR \%manpath (1)
-program for determining a path of man directories is tried.
+program for determining a path of
+.I man
+directories is tried.
 .
 .
 .P
 After this, the path elements for the language (locale) and operating
-system specific man\~pages are added to the man\~path; their sequence
-is determined automatically.
+system specific
+.I \%man\~pages
+are added to the
+.IR man\~path ;
+their sequence is determined automatically.
 .
 For example, both
 .File_name /usr/share/man/linux/fr
 and
 .File_name /usr/share/man/fr/linux
-for french linux man\~pages are found.
+for french linux
+.I \%man\~pages
+are found.
 .
 The language and operating system names are determined from both
 environment variables and command line options.
@@ -2525,20 +2651,24 @@
 .
 .
 .P
-If no man\~pages for a complicated locale are found the country part
-consisting of the first two characters (without the `\f[CB]_\f[]',
-`\f[CB].\f[]', and `\f[CB],\f[]' parts) of the locale is searched as
-well.
+If no
+.I \%man\~pages
+for a complicated locale are found the country part consisting of the
+first two characters (without the `\f[CB]_\f[]', `\f[CB].\f[]', and
+`\f[CB],\f[]' parts) of the locale is searched as well.
 .
 .
 .P
-If still not found the corresponding man\~page in the default language
-is used instead.
+If still not found the corresponding
+.I \%man\~page
+in the default language is used instead.
 .
 As usual, this default can be specified by one of \f[CR]C\f[] or
 \f[CR]\%POSIX\f[].
 .
-The man\~pages in the default language are usually in English.
+The
+.I \%man\~pages
+in the default language are usually in English.
 .
 .
 .P
@@ -2566,8 +2696,11 @@
 .
 .
 .P
-When searching for man\~pages this man\~path with the additional
-language and system specific directories is used.
+When searching for
+.I \%man\~pages
+this
+.I man\~path
+with the additional language and system specific directories is used.
 .
 .
 .P
@@ -2581,7 +2714,9 @@
 .Env_var $MANSECT .
 .
 When no section was specified a set of standard sections is searched
-until a suitable man\~page was found.
+until a suitable
+.I \%man\~page
+was found.
 .
 .
 .P
@@ -2596,7 +2731,9 @@
 .
 .
 .P
-For further details on man\~page searching, see
+For further details on
+.I \%man\~page
+searching, see
 .BR \%man (1).
 .
 .
@@ -2700,7 +2837,8 @@
 .Env_var $LANG
 If one of these variables is set (in the above sequence), its content
 is interpreted as the locale, the language to be used, especially when
-retrieving man\~pages.
+retrieving
+\IR \%man\~pages .
 .
 A locale name is typically of the form
 .nh
@@ -2726,8 +2864,9 @@
 .B C
 and
 .B \%POSIX
-stand for the default, i.e. the man\~page directories without a
-language prefix.
+stand for the default, i.e. the
+.I \%man\~page
+directories without a language prefix.
 .
 This is the same behavior as when all 3\~variables are unset.
 .
@@ -2754,25 +2893,6 @@
 .BR \%groffer .
 .
 .
-.TP
-.Env_var $POSIXLY_CORRECT
-If set to a non-empty value this chooses the \%POSIX mode of the shell.
-.
-This is done internally by some shells, such as
-.IR bash .
-.
-.B \%groffer
-ignores the bad \%POSIX behavior for option processing, that means that
-option processing will be finished as soon as a non-option argument is
-found.
-.
-Instead the GNU behavior of freely mixing options and
-.I \%filespec
-arguments is used in any case.
-.
-Usually, you do not want to set this environment variable externally.
-.
-.
 .\" --------------------------------------------------------------------
 .SS "Groff Variables"
 .\" --------------------------------------------------------------------
@@ -2802,7 +2922,9 @@
 .SS "Man Variables"
 .\" --------------------------------------------------------------------
 .
-Parts of the functionality of the man\~program were implemented in
+Parts of the functionality of the
+.B man
+program were implemented in
 .BR \%groffer ;
 support for all environment variables documented in
 .BR \%man (1)
@@ -2821,7 +2943,9 @@
 .
 .TP
 .Env_var $EXTENSION
-Restrict the search for man\~pages to files having this extension.
+Restrict the search for
+.I \%man\~pages
+to files having this extension.
 .
 This is overridden by option
 .Opt_long extension ;
@@ -2837,7 +2961,8 @@
 only the essential parts of its value are extracted.
 .
 The options specified in this variable overwrite the values of the
-other environment variables taht are specific to man.
+other environment variables that are specific to
+.IR man .
 .
 All options specified in this variable are overridden by the options
 given on the command line.
@@ -2845,7 +2970,8 @@
 .
 .TP
 .Env_var $MANPATH
-If set, this variable contains the directories in which the man\~page
+If set, this variable contains the directories in which the
+.I \%man\~page
 trees are stored.
 .
 This is overridden by option
@@ -2855,7 +2981,8 @@
 .TP
 .Env_var $MANSECT
 If this is a colon separated list of section names, the search for
-man\~pages is restricted to those manual sections in that order.
+.I \%man\~pages
+is restricted to those manual sections in that order.
 .
 This is overridden by option
 .Opt_long sections .
@@ -2864,7 +2991,9 @@
 .TP
 .Env_var $SYSTEM
 If this is set to a comma separated list of names these are interpreted
-as man\~page trees for different operating systems.
+as
+.I \%man\~page
+trees for different operating systems.
 .
 This variable can be overwritten by option
 .Opt_long systems ;
@@ -2887,10 +3016,6 @@
 .B \%groffer
 program can be preconfigured by two configuration files.
 .
-This configuration can be overridden at each program start by command
-line options or by the environment variable
-.Env_var $GROFFER_OPT .
-.
 .
 .TP
 .File_name /etc/groff/groffer.conf
@@ -2906,55 +3031,63 @@
 .Env_var $HOME
 denotes the user's home directory.
 .
-This script is called after the system-wide configuration file to
-enable overriding by the user.
+This file is called after the system-wide configuration file to enable
+overriding by the user.
+.
+.
+.P
+The precedence of option delivery is given in the following.
+.
+The configuration file in
+.File_name /etc
+has the lowest precedence; it is overwritten by the configuration file
+in the home directory; both configuration files are overwritten by the
+environment variable
+.Env_var $GROFFER_OPT ;
+everything is overwritten by the command line.
 .
 .
 .P
-Their lines either start with a minus character or are shell commands.
+In the configuration files, arbitrary spaces are allowed at the
+beginning of each line, they are just ignored.
 .
-Arbitrary spaces are allowed at the beginning, they are just ignored.
+Apart from that, the lines of the configuration lines either start
+with a minus character, all other lines are interpreted as shell
+commands.
 .
-The lines with the beginning minus can be all
+.
+.P
+The lines with the beginning minus are interpreted as
 .B groffer
-options; they are appended to the existing value
-of
-.Env_var $GROFFER_OPT .
+options.
 .
 This easily allows to set general
 .B \%groffer
 options that should be used with any call of
 .BR \%groffer .
 .
+Each line can represent a single short option, a short option cluster,
+or a long option with two minus signs, eventually with an argument.
 .
-.P
-After the transformation of the minus lines, the emerging
-configuration shell scripts are called using the `\c
-.nh
-.CB \.\~\c
-.IR filename '
-.hy
-shell syntax within
-.BR \%groffer .
-.
+The argument can be appended either after a space character or an
+equal sign
+.RB ` = '.
+The argument can be surrounded by quotes, but this is not necessary.
 .
-.P
-In the configuration files, there is only one option that really needs
-a line starting with a minus character because it cannot be restored
-by any shell tricks.
+The options from these lines are collected and prepended to the
+existing value of
+.Env_var $GROFFER_OPT
+at the end of each configuration file.
 .
-This is
-.Opt_long shell .
-The reason is that its argument must be retrieved at a very early
-stage of
-.BR \%groffer .
-So to specify a shell to rerun the
-.B groffer
-script enter a line
-.Opt_long shell=\fIname\fP
-in a configuration file.
 .
-Some shells run faster.
+.P
+After the transformation of the minus lines, the configuration files
+have been transferred into a shell script that is called within
+.B \%groffer
+using the `\c
+.CB \.\~\c
+.IR \%filename '
+shell syntax.
 .
 .
 .P
@@ -2967,7 +3100,8 @@
 .
 .Topic
 Preset environment variables recognized by
-.BR \%groffer .
+.BR \%groffer ;
+but do not forget to export them.
 .
 .Topic
 Write a function for calling a viewer program for a special
@@ -2976,12 +3110,25 @@
 .Opt_long \f[I]mode\f[]\-viewer
 option.
 .
-Note that the name of such a function must coincide with some existing
-program in the system path
+Note that the name of such a function must either be given as the full
+file name or coincide with some existing program in the system path
 .Env_var $PATH
 in order to be recognized by
 .BR groffer .
 .
+.Topic
+Enter
+.Opt_long shell
+to specify a shell for the run of
+.File_name groffer2.sh .
+Some shells run much faster than the standard shell; the fastest
+Bourne shell that I know is
+.BR ash (1).
+It makes really sense to add a line like
+.Opt_long shell=ash
+to your configuration file as long as the given shell is installed on
+your system.
+.
 .
 .P
 As an example, consider the following configuration file in
@@ -3092,7 +3239,8 @@
 .B \%groffer
 is very easy.
 .
-Usually, it is just called with a file name or man\~page.
+Usually, it is just called with a file name or
+.IR \%man\~page .
 .
 The following examples, however, show that
 .B \%groffer
@@ -3118,14 +3266,20 @@
 .File_name \%./groff
 exists use it as input.
 .
-Otherwise interpret the argument as a search for the man\~page named
-.B \%groff
-in the smallest possible man\~section, being section 1 in this case.
+Otherwise interpret the argument as a search for the
+.I \%man\~page
+named
+.B \%groff
+in the smallest possible
+.IR \%man\~section ,
+being section 1 in this case.
 .
 .
 .TP
 .Shell_cmd "groffer\~man:groff"
-search for the man\~page of
+search for the
+.I \%man\~page
+of
 .B \%groff
 even when the file
 .File_name ./groff
@@ -3136,9 +3290,12 @@
 .Shell_cmd "groffer\~groff.7"
 .TP+
 .Shell_cmd "groffer\~7\~groff"
-search the man\~page of
+search the
+.I \%man\~page
+of
 .B \%groff
-in man\~section
+in
+.I \%man\~section
 .BR 7 .
 This section search works only for a digit or a single character from
 a small set.
@@ -3148,7 +3305,9 @@
 .Shell_cmd "groffer\~fb.modes"
 If the file
 .File_name ./fb.modes
-does not exist interpret this as a search for the man\~page of
+does not exist interpret this as a search for the
+.I \%man\~page
+of
 .BR fb.modes .
 As the extension
 .I \%modes
@@ -3161,9 +3320,10 @@
 .Shell_cmd "groffer\~groff\~\[cq]troff(1)\[cq]\~man:roff"
 .
 The arguments that are not existing files are looked-up as the
-following man\~pages:
+following
+.IR \%man\~pages :
 .B \%groff
-(automatic search, should be found in man\~section\~1),
+(automatic search, should be found in \fIman\fP\~section\~1),
 .B \%troff
 (in section\~1),
 and
@@ -3187,7 +3347,9 @@
 .TP
 .Shell_cmd "LANG=de\~groffer\~--man\~--www\~--www-viever=mozilla\~ls"
 .
-Retrieve the German man\~page (language
+Retrieve the German
+.I \%man\~page
+(language
 .IR de )
 for the
 .B ls
@@ -3201,7 +3363,9 @@
 .BR \%galeon .
 The option
 .Opt_long man
-guarantees that the man\~page is retrieved, even when a local file
+guarantees that the
+.I \%man\~page
+is retrieved, even when a local file
 .File_name \%ls
 exists in the actual directory.
 .
@@ -3209,10 +3373,12 @@
 .TP
 .Shell_cmd "groffer\~--source\~'man:roff(7)'"
 .
-Get the man\~page called
+Get the
+.I \%man\~page
+called
 .I \%roff
-in man\~section 7, decompress it, and print its unformatted content,
-its source code.
+in \fIman\fP\~section 7, decompress it, and print its unformatted
+content, its source code.
 .
 .
 .TP
@@ -3246,69 +3412,81 @@
 .
 The
 .B \%groffer
-shell script is compatible with both GNU and \%POSIX.
+program consists of two shell scripts.
 .
-\%POSIX compatibility refers to
-.B IEEE P1003.2/D11.2
-of September 1991, a very early version of the \%POSIX standard that
-is still freely available in the internet at
-.URL http://\:www.funet.fi/pub/doc/posix/p1003.2/d11.2/all \
-"\%POSIX P1003.2 draft 11.2" .
 .
-Unfortunately, this version of the standard removed `local' for shell
-function variables, but later \%POSIX versions restored this again.
+.P
+The starting script is the file
+.File_name \%groffer
+that is installed in a
+.File_name bin
+directory.
 .
-As `local' is needed for serious programming this temporary \%POSIX
-deprecation was ignored.
+It is generated from the source file
+.File_name \%groffer.sh .
 .
+It is just a short starting script without any functions such that it
+can run on very poor shells.
 .
-.P
-Most GNU shells are compatible with this interpretation of \%POSIX,
-but provide much more facilities.
 .
-Nevertheless this script uses only a restricted set of shell language
-elements and shell builtins.
+.P
+The main part of the
+.B \%groffer
+program is the file
+.File_name groffer2.sh
+that is installed in the
+.I groff
+library directory.
 .
-The
+This script can be run under a different shell by using the
 .B \%groffer
-script should work on most actual free and commercial operating
-systems.
+option
+.Opt_long shell .
 .
 .
 .P
-The
-.B \%groffer
-program provides its own parser for command line options; it can
-handle option arguments and file names containing white space and a
-large set of special characters.
+Both scripts are compatible with both
+GNU and \%POSIX.
+.
+\%POSIX compatibility refers to
+.B IEEE P1003.2/D11.2
+of September 1991, a very early version of the \%POSIX standard that
+is still freely available in the internet at
+.URL http://\:www.funet.fi/\:pub/\:doc/\:posix/\:p1003.2/\:d11.2/\:all \
+"\%POSIX P1003.2 draft 11.2" .
 .
 .
 .P
+Only a restricted set of shell language elements and shell builtins is
+used to achieve even compatibility with some Bourne shells that are
+not fully \%POSIX compatible.
+.
 The
 .B \%groffer
-shell script was tested with the following common implementations of
-the GNU shells:
-.I \%POSIX
-.BR \%sh (1),
+shell scripts were tested on many shells, including the following
+Bourne shells:
+.BR \%ash (1),
 .BR \%bash (1),
-and others.
-.
-Free
-.I \%POSIX
-compatible shells and shell utilities for most operating
-systems are available at the
-.URL http://\:www.gnu.org/software/ "GNU software archive" .
+.BR \%dash (1),
+.BR \%ksh (1),
+.BR \%pdksh (1),
+.BR \%posh (1),
+and
+.BR \%zsh (1).
+So it should work on most actual free and commercial operating
+systems.
 .
 .
 .P
-The shell can be chosen by the option
-.Opt_long shell .
-This option can also be given to the environment variable
+The shell for the run of
+.File_name groffer2.sh
+can be chosen by the option
+.Opt_long shell
+on the command line or the environment variable
 .Env_var $GROFF_OPT .
-If you want to write it to one of the
+If you want to add it to one of the
 .B \%groffer
-configuration files you must use the single option style, a line
-starting with
+configuration files you must write a line starting with
 .Opt_long shell .
 .
 .
@@ -3321,15 +3499,22 @@
 .BR \%getopts (1)
 and
 .I \%GNU
-.BR \%getopt (1)
-except for shortcuts of long options.
+.BR \%getopt (1).
+It can handle option arguments and file names containing white space
+and a large set of special characters.
 .
 The following standard types of options are supported.
 .
 .
 .Topic
-A single minus always refers to single character option or a
-combination thereof, for example, the
+The option consisiting of a single minus
+.Opt_short
+refers to standard input.
+.
+.
+.Topic
+A single minus followed by characters refers to a single character
+option or a combination thereof; for example, the
 .B \%groffer
 short option combination
 .Opt_short Qmfoo
@@ -3339,7 +3524,7 @@
 .
 .Topic
 Long options are options with names longer than one character; they
-are always prededed by a double minus.
+are always preceded by a double minus.
 .
 An option argument can either go to the next command line argument or
 be appended with an equal sign to the argument; for example,
@@ -3352,36 +3537,33 @@
 An argument of
 .Opt_--
 ends option parsing; all further command line arguments are
-interpreted as file name arguments.
+interpreted as filespec parameters, i.e. file names or constructs for
+searching
+.IR \%man\~pages ).
 .
 .
 .Topic
-By default, all command line arguments that are neither options nor
-option arguments are interpreted as filespec parameters and stored
-until option parsing has finished.
+All command line arguments that are neither options nor option
+arguments are interpreted as filespec parameters and stored until
+option parsing has finished.
 .
 For example, the command line
 .Shell_cmd "groffer file1 -a -o arg file2"
-is, by default, equivalent to
+is equivalent to
 .Shell_cmd "groffer -a -o arg -- file1 file2"
 .
 .
 .P
-This behavior can be changed by setting the environment variable
-.Env_var \%$POSIXLY_CORRECT
-to a non-empty value.
-.
-Then the strange \%POSIX non-option behavior is adopted, i. e. option
-processing is stopped as soon as the first non-option argument is
-found and each following argument is taken as a file name.
+The free mixing of options and filespec parameters follows the GNU
+principle.
 .
-For example, in posixly correct mode, the command line
-.Shell_cmd "groffer file1 -a -o arg file 2"
-is equivalent to
-.Shell_cmd "groffer -- file1 -a -o arg file 2"
-As this leads to unwanted behavior in most cases, most people do not
-want to set
-.Env_var \%$POSIXLY_CORRECT .
+That does not fulfill the strange option behavior of \%POSIX that ends
+option processing as soon as the first non-option argument has been
+reached.
+.
+The end of option processing can be forced by the option
+.RB ` \-\- '
+anyway.
 .
 .
 .\" --------------------------------------------------------------------
@@ -3403,7 +3585,7 @@
 but you must first subscribe to this list.
 .
 You can do that by visiting the
-.URL http://lists.gnu.org/mailman/listinfo/groff \
+.URL http://\:lists.gnu.org/\:mailman/\:listinfo/\:groff \
 "groff mailing list web page" .
 .
 .
@@ -3417,14 +3599,15 @@
 .SH "SEE ALSO"
 .\" --------------------------------------------------------------------
 .
-.TP
-.BR \%groff (@MAN1EXT@)
-.TP+
+.P
+.BR \%groff (@MAN1EXT@),
 .BR address@hidden@troff (@MAN1EXT@)
+.RS
 Details on the options and environment variables available in
 .BR \%groff ;
 all of them can be used with
 .BR \%groffer .
+.RE
 .
 .
 .TP
@@ -3462,76 +3645,91 @@
 .
 .TP
 .BR \%man (1)
-The standard program to diplay man\~pages.
+The standard program to display
+.IR \%man\~pages .
 .
-The information there is only useful if it is the man\~page for GNU
+The information there is only useful if it is the
+.I \%man\~page
+for GNU
 .BR man .
 Then it documents the options and environment variables that are
 supported by
 .BR \%groffer .
 .
 .
-.TP
-.BR \%gxditview (@MAN1EXT@)
-.TP+
+.P
+.BR \%ash (1),
+.BR \%bash (1),
+.BR \%dash (1),
+.BR \%ksh (1),
+.BR \%pdksh (1),
+.BR \%posh (1),
+.BR \%sh (1),
+.BR \%zsh (1)
+.RS
+Bourne shells that were tested with
+.BR \%groffer .
+.RE
+.
+.
+.P
+.BR \%gxditview (@MAN1EXT@),
 .BR \%xditview (1x)
+.RS
 Viewers for
 .BR \%groffer 's
 .IR \%x\~mode .
+.RE
 .
 .
-.TP
-.BR \%kghostview (1)
-.TP+
-.BR \%ggv (1)
-.TP+
-.BR \%gv (1)
-.TP+
-.BR \%ghostview (1)
-.TP+
+.P
+.BR \%kghostview (1),
+.BR \%ggv (1),
+.BR \%gv (1),
+.BR \%ghostview (1),
 .BR \%gs (1)
+.RS
 Viewers for
 .BR \%groffer 's
 .IR \%ps\~mode .
+.RE
 .
 .
-.TP
-.BR \%kghostview (1)
-.TP+
-.BR \%ggv (1)
-.TP+
-.BR \%xpdf (1)
-.TP+
-.BR \%acroread (1)
-.TP+
+.P
+.BR \%kghostview (1),
+.BR \%ggv (1),
+.BR \%xpdf (1),
+.BR \%acroread (1),
 .BR \%kpdf (1)
+.RS
 Viewers for
 .BR \%groffer 's
 .IR \%pdf\~mode .
+.RE
 .
 .
-.TP
-.BR \%kdvi (1)
-.TP+
-.BR \%xdvi (1)
-.TP+
+.P
+.BR \%kdvi (1),
+.BR \%xdvi (1),
 .BR \%dvilx (1)
+.RS
 Viewers for
 .BR \%groffer 's
 .IR \%dvi\~mode .
+.RE
 .
 .
-.TP
-.BR \%konqueror (1)
-.TP+
-.BR \%mozilla (1)
-.TP+
+.P
+.BR \%konqueror (1),
+.BR \%mozilla (1),
 .BR \%lynx (1)
+.RS
 Web-browsers for
 .BR \%groffer 's
 .I \%html
 or
 .IR \%www\~mode .
+.RE
 .
 .
 .TP
@@ -3540,12 +3738,13 @@
 .I \%tty\~mode .
 .
 .
-.TP
-.BR \%gzip (1)
-.TP+
+.P
+.BR \%gzip (1),
 .BR \%bzip2 (1)
+.RS
 The decompression programs supported by
 .BR \%groffer .
+.RE
 .
 .
 .\" --------------------------------------------------------------------
Index: groff/contrib/groffer/groffer.sh
diff -u groff/contrib/groffer/groffer.sh:1.31 
groff/contrib/groffer/groffer.sh:1.32
--- groff/contrib/groffer/groffer.sh:1.31       Sun Jul 31 07:53:15 2005
+++ groff/contrib/groffer/groffer.sh    Wed Aug  3 06:32:11 2005
@@ -8,194 +8,243 @@
 # Free Software Foundation, Inc.
 # Written by Bernd Warken
 
-# This file is part of groff version @VERSION@ (eventually 1.19.2).
+# This file is part of `groffer', which is part of `groff' version
+# 1.19.2.
 
-# groff is free software; you can redistribute it and/or modify it
+# `groff' is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 2, or (at your option)
 # any later version.
 
-# groff is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-# License for more details.
+# `groff' is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with groff; see the files COPYING and LICENSE in the top
-# directory of the groff source.  If not, write to the Free Software
-# Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
-
-_PROGRAM_NAME='groffer';
-_PROGRAM_VERSION='0.9.20';
-_LAST_UPDATE='30 July 2005';
+# along with `groff'; see the files COPYING and LICENSE in the top
+# directory of the `groff' source.  If not, write to the Free Software
+# Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301,
+# USA.
+
+_PROGRAM_VERSION='0.9.21';
+_LAST_UPDATE='2 August 2005';
+
+export _PROGRAM_VERSION;
+export _LAST_UPDATE;
+
+export GROFFER_OPT;            # option environment for groffer
+export _OUTPUT_FILE_NAME;      # output generated, see main_set_res..()
+
+export _CONF_FILE_ETC;         # configuration file in /etc
+export _CONF_FILE_HOME;                # configuration file in $HOME
+export _CONF_FILES;            # configuration files
+_CONF_FILE_ETC='/etc/groff/groffer.conf';
+_CONF_FILE_HOME="${HOME}/.groff/groffer.conf";
+_CONF_FILES="${_CONF_FILE_ETC} ${_CONF_FILE_HOME}";
+
+# characters
+
+export _AT;
+export _SP;
+export _SQ;
+export _TAB;
+
+_AT='@';
+_SP=' ';
+_SQ="'";
+_TAB=' ';
+
+# @...@ constructs
+
+export _AT_BINDIR_AT;
+export _AT_G_AT;
+export _AT_LIBDIR_AT;
+export _GROFFER_LIBDIR;
+if test address@hidden@_ = _${_AT}BINDIR${_AT}_
+then
+  # script before `make'
+  _AT_BINDIR_AT='.';
+  _AT_G_AT='';
+  _AT_LIBDIR_AT='';
+  _GROFFER_LIBDIR='.';
+else
+  _AT_BINDIR_AT='@BINDIR@';
+  _AT_G_AT='@g@';
+  _AT_LIBDIR_AT='@libdir@';
+  _GROFFER_LIBDIR="${_AT_LIBDIR_AT}"'/groff/groffer';
+fi;
 
+export _GROFFER_SH;            # file name of this shell script
+case "$0" in
+*groffer*)
+  _GROFFER_SH="$0";
+  # was: _GROFFER_SH="${_AT_BINDIR_AT}/groffer";
+  ;;
+*)
+  echo 'The groffer script should be started directly.' >&2
+  exit 1;
+  ;;
+esac;
 
-########################################################################
-# Determine the shell under which to run this script from the command
-# line arguments or $GROFF_OPT; if none is specified, just go on with
-# the starting shell.
+export _GROFFER2_SH;           # file name of the script that follows up
+_GROFFER2_SH="${_GROFFER_LIBDIR}"/groffer2.sh;
 
-if test _"${_GROFFER_RUN}"_ = __;
+export _NULL_DEV;
+if test -c /dev/null
 then
-  # only reached during the first run of the script
+  _NULL_DEV="/dev/null";
+else
+  _NULL_DEV="NUL";
+fi;
 
-  export _GROFFER_RUN;         # counter for the runs of groffer
-  _GROFFER_RUN='first';
 
-  export _PROGRAM_NAME;
-  export _PROGRAM_VERSION;
-  export _LAST_UPDATE;
-
-  export GROFFER_OPT;          # option environment for groffer
-  export _GROFFER_SH;          # file name of this shell script
-  export _OUTPUT_FILE_NAME;    # output generated, see main_set_res..()
-
-  export _CONF_FILES;          # configuration files
-  _CONF_FILES="/etc/groff/groffer.conf ${HOME}/.groff/groffer.conf";
-
-  case "$0" in
-  *${_PROGRAM_NAME}*)
-    _GROFFER_SH="$0";
-    # was: _GROFFER_SH="@BINDIR@/${_PROGRAM_NAME}";
-    ;;
-  *)
-    echo "The ${_PROGRAM_NAME} script should be started directly." >&2
-    exit 1;
-    ;;
-  esac;
+# Test of the `$()' construct.
+if test _"$(echo "$(echo 'test')")"_ \
+     != _test_
+then
+  echo 'The "$()" construct did not work' >&2;
+  exit "${_ERROR}";
+fi;
 
-  export _NULL_DEV;
-  if test -c /dev/null;
+
+# read and transform the configuration files, execute the arising commands
+for f in "${_CONF_FILE_HOME}" "${_CONF_FILE_ETC}"
+do
+  if test -f "$f"
   then
-    _NULL_DEV="/dev/null";
-  else
-    _NULL_DEV="NUL";
+    o="";                      # $o means groffer option
+    # use "" quotes because of ksh and posh
+    eval "$(cat "$f" | sed -n -e '
+# Ignore comments
+/^['"${_SP}${_TAB}"']*#/d
+# Delete leading and final space
+s/^['"${_SP}${_TAB}"']*//
+s/['"${_SP}${_TAB}"']*$//
+# Print all shell commands
+/^[^-]/p
+# Replace empty arguments
+s/^\(-[^ ]*\)=$/o="${o} \1 '"${_SQ}${_SQ}"'"/p
+# Replace division between option and argument by single space
+s/[='"${_SP}${_TAB}"']['"${_SP}${_TAB}"']*/'"${_SP}"'/
+# Handle lines without spaces
+s/^\(-[^'"${_SP}"']*\)$/o="${o} \1"/p
+# Print options that have their argument encircled with single quotes
+/^-[^ ]* '"${_SQ}"'.*'"${_SQ}"'$/s/^.*$/o="${o} &"/p
+# Replace encircled double quotes by single quotes and print the result
+s/^\(-[^ ]*\) "\(.*\)"$/o="${o} \1 '"${_SQ}"'\2'"${_SQ}"'"/p
+# Encircle the remaining arguments with single quotes
+s/^\(-[^ ]*\) \(.*\)$/o="${o} \1 '"${_SQ}"'\2'"${_SQ}"'"/p
+')"
+    if test _"${o}"_ != __
+    then
+      if test _"{GROFFER_OPT}"_ = __
+      then
+        GROFFER_OPT="${o}";
+      else
+        GROFFER_OPT="${o} ${GROFFER_OPT}";
+      fi;
+    fi;
   fi;
+done;
 
 
-  # test of `unset'
-  export _UNSET;
-  export _foo;
-  _foo=bar;
-  _res="$(unset _foo 2>&1)";
-  if unset _foo >${_NULL_DEV} 2>&1 && \
-     test _"${_res}"_ = __ && test _"${_foo}"_ = __
-  then
-    _UNSET='unset';
-    eval "${_UNSET}" _res;
-  else
-    _UNSET=':';
-  fi;
+########################### Determine the shell
 
+export _SHELL;
 
-  ###########################
-  # _get_opt_shell ("$@")
-  #
-  # Determine whether `--shell' was specified in $GROFF_OPT or in $*;
-  # if so, echo its argument.
-  #
-  # Output: the shell name if it was specified
-  #
-  _get_opt_shell()
-  {
-    case " ${GROFFER_OPT} $*" in
-      *\ --shell\ *|*\ --shell=*)
-        (
-          eval set x "${GROFFER_OPT}" '"$@"';
+# use "``" instead of "$()" for using the case ")" construct
+# do not use "" quotes because of ksh
+_SHELL=`
+  # $x means list
+  # $s means shell
+  export x;  
+  case " ${GROFFER_OPT} $*" in
+  *\ --sh*)                    # abbreviation for --shell
+    x='';
+    s='';
+    eval set x "${GROFFER_OPT}" '"$@"';
+    shift;
+    # determine all --shell arguments, store them in $x in reverse order
+    while test $# != 0
+    do
+      case "$1" in
+      --shell|--sh|--she|--shel)
+        if test "$#" -ge 2
+        then
+          s="$2";
           shift;
-          _sh='';
-          while test $# != 0
-          do
-            case "$1" in
-              --shell)
-                if test "$#" -ge 2;
-                then
-                  _sh="$2";
-                  shift;
-                fi;
-                ;;
-              --shell=?*)
-                # delete up to first `=' character
-                _sh="$(echo x"$1" | sed -e '
-s/^x//
-s/^[^=]*=//
-')";
-                ;;
-            esac;
-            shift;
-          done;
-          cat <<EOF
-${_sh}
-EOF
-        )
+        fi;
         ;;
-    esac;
-  }
-
-
-  ###########################
-  # _test_on_shell (<name>)
-  #
-  # Test whether <name> is a shell program of Bourne type (POSIX sh).
-  #
-  _test_on_shell()
-  {
-    if test "$#" -le 0 || test _"$1"_ = __;
-    then
-      return 1;
-    fi;
-    # do not quote $1 to allow arguments
-    test _"$(eval $1 -c "'"'s=ok; echo $s'"'" 2>${_NULL_DEV})"_ = _ok_;
-  }
-
+      --shell=*|--sh=*|--she=*|--shel=*)
+        # delete up to first "=" character
+        s="$(echo x"$1" | sed -e 's/^x[^=]*=//')";
+        ;;
+      *)
+        shift;
+        continue;
+      esac;
+      if test _"${x}"_ = __
+      then
+        x="'${s}'";
+      else
+        x="'${s}' ${x}";
+      fi;
+      shift;
+    done;
 
-  ###########################
-  # do the shell determination from command line and $GROFFER_OPT
-  _shell="$(_get_opt_shell "$@")";
-  if test _"${_shell}"_ = __;
-  then
-    # none found, so look at the `--shell' lines in configuration files
-    export f;
-    # for f in $_CONF_FILES
-    for f in $(eval set x ${_CONF_FILES}; shift; echo "$@")
-    do
-      if test -f "$f";
+    # from all possible shells in $x determine the first being a shell
+    # or being empty
+    s="$(
+      # "" quotes because of posh
+      eval set x "${x}";
+      shift;
+      if test $# != 0
       then
-        _all="$(cat "$f" | sed -n -e 's/^--shell[= ] *\([^ ]*\)$/\1/p')"
-        # for s in $_all
-        for s in $(eval set x ${_all}; shift; echo "$@")
+        for i
         do
-          _shell="$s";
+          if test _"$i"_ = __
+          then
+            # use the empty argument as the default shell
+            break;
+          else
+            # test $i on being a shell program;
+            # use this kind of quoting for posh
+            if test _"$(eval "$i -c 'echo ok'" 2>${_NULL_DEV})"_ = _ok_ >&2
+            then
+              # shell found
+              cat <<EOF
+${i}
+EOF
+              break;
+            else
+              # if not being a shell go on searching
+              continue;
+            fi;
+          fi;
         done;
       fi;
-    done;
-    eval ${_UNSET} f;
-    eval ${_UNSET} s;
-    eval ${_UNSET} _all;
-  fi;
-
-  export _GROFFER2_SH;            # file name of the script that follows up
-  _GROFFER2_SH='@libdir@/groff/groffer/groffer2.sh';
-
-  # restart the script with the last found $_shell, if it is a shell
-  if _test_on_shell "${_shell}";
-  then
-    _GROFFER_RUN='second';
-    # do not quote $_shell to allow arguments
-    eval exec ${_shell} "'${_GROFFER2_SH}'" '"$@"';
-    exit;
-  fi;
-
-  _GROFFER_RUN='second';
-  eval ${_UNSET} _shell;
-  eval exec "'${_GROFFER2_SH}'" '"$@"';
+    )";
+    if test _"${s}"_ != __
+    then
+      cat <<EOF
+${s}
+EOF
+    fi;
+    ;;
+  esac;
+`
 
-fi; # end of first run
+########################### start groffer2.sh
 
-if test _"${_GROFFER_RUN}"_ != _second_;
+if test _"${_SHELL}"_ = __
 then
-  echo "$_GROFFER_RUN should be 'second' here." >&2
-  exit 1
+  # no shell found, so start groffer2.sh normally
+  eval exec "'${_GROFFER2_SH}'" '"$@"';
+  exit;
+else
+  # start groffer2.sh with the found $_SHELL
+  # do not quote $_SHELL to allow arguments
+  eval exec "${_SHELL} '${_GROFFER2_SH}'" '"$@"';
+  exit;
 fi;
-
-eval ${_UNSET} _GROFFER_RUN
Index: groff/contrib/groffer/groffer2.sh
diff -u groff/contrib/groffer/groffer2.sh:1.1 
groff/contrib/groffer/groffer2.sh:1.2
--- groff/contrib/groffer/groffer2.sh:1.1       Sun Jul 31 07:53:15 2005
+++ groff/contrib/groffer/groffer2.sh   Wed Aug  3 06:32:11 2005
@@ -5,32 +5,36 @@
 # Source file position: <groff-source>/contrib/groffer/groffer2.sh
 # Installed position: <prefix>/lib/groff/groffer/groffer2.sh
 
+# This file should not be run independently.  It is called by
+# `groffer.sh' in the source or by the installed `groffer' program.
+
 # Copyright (C) 2001,2002,2003,2004,2005
 # Free Software Foundation, Inc.
 # Written by Bernd Warken
 
-# Last update: 30 July 2005
+# Last update: 2 August 2005
 
-# This file is part of groffer, which is part of groff.
+# This file is part of `groffer', which is part of `groff'.
 
-# groff is free software; you can redistribute it and/or modify it
+# `groff' is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 2, or (at your option)
 # any later version.
 
-# groff is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-# License for more details.
+# `groff' is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with groff; see the files COPYING and LICENSE in the top
-# directory of the groff source.  If not, write to the Free Software
-# Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
+# along with `groff'; see the files COPYING and LICENSE in the top
+# directory of the `groff' source.  If not, write to the Free Software
+# Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301,
+# USA.
 
 
 ########################################################################
-# diagnostic messages
+# diagnostic messages for debugging
 #
 export _DEBUG;
 _DEBUG='no';                   # disable debugging information
@@ -42,17 +46,48 @@
 
 export _DEBUG_KEEP_FILES;
 _DEBUG_KEEP_FILES='no'         # disable file keeping in temporary dir
-_DEBUG_KEEP_FILES='yes'                # enable file keeping in temporary dir
+#_DEBUG_KEEP_FILES='yes'       # enable file keeping in temporary dir
+
+export _DEBUG_PRINT_PARAMS;
+_DEBUG_PRINT_PARAMS='no';      # disable printing of all parameters
+#_DEBUG_PRINT_PARAMS='yes';    # enable printing of all parameters
+
+export _DEBUG_PRINT_SHELL;
+_DEBUG_PRINT_SHELL='no';       # disable printing of the shell name
+#_DEBUG_PRINT_SHELL='yes';     # enable printing of the shell name
+
 
-# test of $* on --debug
-case " $* " in
-*' --debug '*)
+# test of $GROFFER_OPT and $* on `--debug' with shortest abbreviation `--deb'
+case " ${GROFFER_OPT} $* " in
+*' --deb '*|*' --debu '*|*' --debug '*)
   _DEBUG='yes';
   _DEBUG_LM='yes';
   _DEBUG_KEEP_FILES='yes';
+  _DEBUG_PRINT_PARAMS='yes';
+  _DEBUG_PRINT_SHELL='yes';
   ;;
 esac;
 
+if test _"${_DEBUG_PRINT_PARAMS}"_ = _yes_
+then
+  echo "parameters: ${GROFFER_OPT} $@" >&2;
+fi;
+
+if test _"${_DEBUG_PRINT_SHELL}"_ = _yes_
+then
+  if test _"${_SHELL}"_ = __
+  then
+    if test _"${POSIXLY_CORRECT}"_ = _y_
+    then
+      echo 'shell: bash as /bin/sh (none specified)' >&2;
+    else
+      echo 'shell: /bin/sh (none specified)' >&2;
+    fi;
+  else
+    echo "shell: ${_SHELL}" >&2;
+  fi;
+fi;
+
 
 ########################################################################
 #                       Environment Variables
@@ -77,16 +112,6 @@
 # read-only variables (global to this file)
 ########################################################################
 
-# characters
-
-export _SPACE;
-export _SQUOTE;
-export _TAB;
-
-_SPACE=' ';
-_SQUOTE="'";
-_TAB=' ';
-
 # function return values; `0' means ok; other values are error codes
 export _ALL_EXIT;
 export _BAD;
@@ -100,7 +125,8 @@
 _BAD='1';                      # return negatively, error code `1'
 _ERROR='7';                    # for syntax errors; no `-1' in `ash'
 
-_ALL_EXIT="${_GOOD} ${_BAD} ${_ERROR}"; # all exit codes (for `trap_set')
+ # all exit codes (for `trap_set()')
+_ALL_EXIT="${_GOOD} ${_BAD} ${_ERROR}";
 
 _NO="${_BAD}";
 _YES="${_GOOD}";
@@ -138,8 +164,8 @@
 export _VIEWER_HTML_X;         # viewer program for html mode in X
 export _VIEWER_HTML_TTY;       # viewer program for html mode in tty
 _VIEWER_DVI='kdvi,xdvi,dvilx';
-_VIEWER_PDF='kghostview,ggv,xpdf,acroread,kpdf';
-_VIEWER_PS='kghostview,ggv,gv,ghostview,gs_x11,gs';
+_VIEWER_PDF='kghostview --scale 1.45,ggv,xpdf,acroread,kpdf';
+_VIEWER_PS='kghostview --scale 1.45,ggv,gv,ghostview,gs_x11,gs';
 _VIEWER_HTML='konqueror,mozilla,netscape,opera,amaya,arena,lynx';
 _VIEWER_X='gxditview,xditview';
 
@@ -200,7 +226,7 @@
 _OPTS_GROFFER_SHORT_NA="'h' 'Q' 'v' 'V' 'X' 'Z'";
 _OPTS_GROFFER_SHORT_ARG="'T'";
 
-_OPTS_GROFFER_LONG_NA="'auto' 'debug' 'default' 'dvi' \
+_OPTS_GROFFER_LONG_NA="'auto' 'debug' 'default' 'do-nothing' 'dvi' \
 'groff' 'help' 'intermediate-output' 'html' 'man' \
 'no-location' 'no-man' 'pdf' 'ps' 'rv' 'source' 'text' 'text-device' \
 'title' 'tty' 'tty-device' 'version' 'whatis' 'where' 'www' 'x' 'X'";
@@ -228,7 +254,7 @@
 _OPTS_X_LONG_NA="'iconic' 'rv'";
 
 _OPTS_X_LONG_ARG="'background' 'bd' 'bg' 'bordercolor' 'borderwidth' \
-'bw' 'display' 'fg' 'fn' 'font' 'foreground' 'ft', 'geometry'
+'bw' 'display' 'fg' 'fn' 'font' 'foreground' 'ft' 'geometry' \
 'resolution' 'title' 'xrm'";
 
 ###### groffer options inherited from man
@@ -236,11 +262,10 @@
 _OPTS_MAN_SHORT_NA="";
 _OPTS_MAN_SHORT_ARG="";
 
-_OPTS_MAN_LONG_NA="'all' 'ascii' 'catman' 'debug' 'ditroff' 'help' \
-'local-file' 'location' 'pager' 'troff' 'update' 'version' \
-'whatis' 'where'";
+_OPTS_MAN_LONG_NA="'all' 'ascii' 'catman' 'ditroff' \
+'local-file' 'location' 'troff' 'update'";
 
-_OPTS_MAN_LONG_ARG="'extension' 'locale' 'manpath' \
+_OPTS_MAN_LONG_ARG="'locale' 'manpath' \
 'pager' 'preprocessor' 'prompt' 'sections' 'systems' 'troff-device'";
 
 ###### additional options for parsing $MANOPT only
@@ -250,15 +275,15 @@
 _OPTS_MANOPT_SHORT_ARG="'e' 'L' 'm' 'M' 'p' 'P' 'r' 'S' 'T'";
 
 _OPTS_MANOPT_LONG_NA="${_OPTS_MAN_LONG_NA} \
-'apropos' 'debug' 'default' 'html' 'ignore-case' 'location-cat' \
-'match-case' 'troff' 'update' 'version' 'where-cat'";
+'apropos' 'debug' 'default' 'help' 'html' 'ignore-case' 'location-cat' \
+'match-case' 'troff' 'update' 'version' 'whatis' 'where' 'where-cat'";
 
 _OPTS_MANOPT_LONG_ARG="${_OPTS_MAN_LONG_NA} \
-'config_file' 'encoding' 'locale'";
+'config_file' 'encoding' 'extension' 'locale'";
 
 ###### collections of command line options
 
-_OPTS_CMDLINE_SHORT_NA="${_OPTS_GROFFER_SHORT_NA}\
+_OPTS_CMDLINE_SHORT_NA="${_OPTS_GROFFER_SHORT_NA} \
 ${_OPTS_GROFF_SHORT_NA} ${_OPTS_X_SHORT_NA} ${_OPTS_MAN_SHORT_NA}";
 _OPTS_CMDLINE_SHORT_ARG="${_OPTS_GROFFER_SHORT_ARG} \
 ${_OPTS_GROFF_SHORT_ARG} ${_OPTS_X_SHORT_ARG} ${_OPTS_MAN_SHORT_ARG}";
@@ -273,6 +298,7 @@
 # read-write variables (global to this file)
 ########################################################################
 
+export _ALL_PARAMS;            # All options and file name parameters
 export _ADDOPTS_GROFF;         # Transp. options for groff (`eval').
 export _ADDOPTS_POST;          # Transp. options postproc (`eval').
 export _ADDOPTS_X;             # Transp. options X postproc (`eval').
@@ -345,7 +371,7 @@
 export _OPT_WHATIS;            # print the one-liner man info
 export _OPT_XRM;               # specify X resource.
 export _OPT_Z;                 # groff option -Z.
-# _TMP_* temporary files
+# _TMP_* temporary directory and files
 export _TMP_DIR;               # groffer directory for temporary files
 export _TMP_CAT;               # stores concatenation of everything
 export _TMP_STDIN;             # stores stdin, if any
@@ -359,21 +385,51 @@
 
 
 ########################################################################
+# Test of `unset'
+#
+export _UNSET;
+export _foo;
+_foo=bar;
+_res="$(unset _foo 2>&1)";
+if unset _foo >${_NULL_DEV} 2>&1 && \
+   test _"${_res}"_ = __ && test _"${_foo}"_ = __
+then
+  _UNSET='unset';
+  eval "${_UNSET}" _res;
+else
+  _UNSET=':';
+fi;
+
+
+########################################################################
 # Test of `test'.
 #
-test "a" = "a" || exit 1;
+if test a = a && test a != b && test -f "${_GROFFER_SH}"
+then
+  :;
+else
+  echo '"test" did not work.' >&2;
+  exit "${_ERROR}";
+fi;
 
 
 ########################################################################
 # Test of `echo' and the `$()' construct.
 #
-echo '' >${_NULL_DEV} || exit "${_ERROR}";
+if echo '' >${_NULL_DEV}
+then
+  :;
+else
+  echo '"echo" did not work.' >&2;
+  exit "${_ERROR}";
+fi;
 if test _"$(t1="$(echo te)" &&
             t2="$(echo '')" &&
             t3="$(echo 'st')" &&
             echo "${t1}${t2}${t3}")"_ \
-     != _test_;
+     != _test_
 then
+  echo 'The "$()" construct did not work' >&2;
   exit "${_ERROR}";
 fi;
 
@@ -386,11 +442,11 @@
   return "${_OK}";
 }
 
-if _t_e_s_t_f_u_n_c_ 2>${_NULL_DEV};
+if _t_e_s_t_f_u_n_c_ 2>${_NULL_DEV}
 then
-  :
+  :;
 else
-  echo 'shell does not support function definitions.' >&2;
+  echo 'Shell '"${_SHELL}"' does not support function definitions.' >&2;
   exit "${_ERROR}";
 fi;
 
@@ -400,6 +456,9 @@
 ########################################################################
 
 
+export _START_DIR;             # directory at start time of the script
+_START_DIR="$(pwd)";
+
 # For variables that can be reset by option `--default', see reset().
 
 _FILEARGS='';
@@ -411,6 +470,7 @@
 # _TMP_* temporary files
 _TMP_DIR='';
 _TMP_CAT='';
+_TMP_CONF='';
 _TMP_STDIN='';
 
 
@@ -421,7 +481,7 @@
 #
 reset()
 {
-  if test "$#" -ne 0;
+  if test "$#" -ne 0
   then
     error "reset() does not have arguments.";
   fi;
@@ -506,6 +566,21 @@
 
 
 ##############
+# echo1 (<text>*)
+#
+# Output to stdout.
+#
+# Arguments : arbitrary text including `-'.
+#
+echo1()
+{
+  cat <<EOF
+$*
+EOF
+}
+
+
+##############
 # echo2 (<text>*)
 #
 # Output to stderr.
@@ -529,9 +604,9 @@
 #
 landmark()
 {
-  if test _"${_DEBUG_LM}"_ = _yes_;
+  if test _"${_DEBUG_LM}"_ = _yes_
   then
-    echo2 "LM: $*" >&2;
+    echo2 "LM: $*";
   fi;
 }
 
@@ -545,9 +620,13 @@
 #
 clean_up()
 {
-  if test -d "${_TMP_DIR}";
+  cd "${_START_DIR}" >"${_NULL_DEV}" 2>&1;
+  if test _"${_TMP_DIR}"_ != __
   then
-    eval rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1;
+    if test -d "${_TMP_DIR}" || test -f "${_TMP_DIR}"
+    then
+      rm -f -r "${_TMP_DIR}" >${_NULL_DEV} 2>&1;
+    fi; 
   fi;
 }
 
@@ -619,7 +698,7 @@
 #
 func_check()
 {
-  if test "$#" -lt 3;
+  if test "$#" -lt 3
   then
     error 'func_check() needs at least 3 arguments.';
   fi;
@@ -670,7 +749,7 @@
   shift;
   shift;
   shift;
-  if test "$#" "${fc_op}" "${fc_nargs}";
+  if test "$#" "${fc_op}" "${fc_nargs}"
   then
     do_nothing;
   else
@@ -678,7 +757,7 @@
 ${fc_fname}"'() needs '"${fc_comp} ${fc_nargs}"' argument'"${fc_s}"'.';
   fi;
   func_push "${fc_fname}";
-  if test _"${_DEBUG}"_ = _yes_;
+  if test _"${_DEBUG}"_ = _yes_
   then
     echo2 '+++ '"${fc_fname} $@";
     echo2 '>>> '"${_FUNC_STACK}";
@@ -704,29 +783,26 @@
 #
 func_pop()
 {
-  if test "$#" -ne 0;
+  if test "$#" -ne 0
   then
     error 'func_pop() does not have arguments.';
   fi;
   case "${_FUNC_STACK}" in
   '')
-    if test _"${_DEBUG}"_ = _yes_;
+    if test _"${_DEBUG}"_ = _yes_
     then
       error 'func_pop(): stack is empty.';
     fi;
     ;;
   *!*)
     # split at first bang `!'.
-   _FUNC_STACK="$(echo x"${_FUNC_STACK}" | sed -e '
-s/^x//
-s/^[^!]*!//
-')";
+   _FUNC_STACK="$(echo1 "${_FUNC_STACK}" | sed -e 's/^[^!]*!//')";
     ;;
   *)
     _FUNC_STACK='';
     ;;
   esac;
-  if test _"${_DEBUG}"_ = _yes_;
+  if test _"${_DEBUG}"_ = _yes_
   then
     echo2 '<<< '"${_FUNC_STACK}";
   fi;
@@ -747,23 +823,20 @@
 #
 func_push()
 {
-  if test "$#" -ne 1;
+  if test "$#" -ne 1
   then
     error 'func_push() needs 1 argument.';
   fi;
   case "$1" in
   *'!'*)
     # remove all bangs `!'.
-    fp_element="$(echo x"$1" | sed -e '
-s/^x//
-s/!//g
-')";
+    fp_element="$(echo1 "$1" | sed -e 's/!//g')";
     ;;
   *)
     fp_element="$1";
     ;;
   esac;
-  if test _"${_FUNC_STACK}"_ = __;
+  if test _"${_FUNC_STACK}"_ = __
   then
     _FUNC_STACK="${fp_element}";
   else
@@ -799,7 +872,7 @@
 
 if test _"$(echo xTesTx \
            | sed -e 's/^.\([Tt]e*x*sTT*\).*$/\1/' \
-           | sed -e 's|T|t|g')"_ != _test_;
+           | sed -e 's|T|t|g')"_ != _test_
 then
   error 'Test of "sed" command failed.';
 fi;
@@ -808,7 +881,7 @@
 ########################################################################
 # Test of function `cat'.
 #
-if test _"$(echo test | cat)"_ != _test_;
+if test _"$(echo test | cat)"_ != _test_
 then
   error 'Test of "cat" command failed.';
 fi;
@@ -817,13 +890,13 @@
 ########################################################################
 # Test for compression.
 #
-if test _"$(echo 'test' | gzip -c -d -f - 2>${_NULL_DEV})"_ = _test_;
+if test _"$(echo 'test' | gzip -c -d -f - 2>${_NULL_DEV})"_ = _test_
 then
   _HAS_COMPRESSION='yes';
   if echo 'test' | bzip2 -c 2>${_NULL_DEV} | bzip2 -t 2>${_NULL_DEV} \
      && test _"$(echo 'test' | bzip2 -c 2>${_NULL_DEV} \
                              | bzip2 -d -c 2>${_NULL_DEV})"_ \
-             = _test_;
+             = _test_
   then
     _HAS_BZIP='yes';
   else
@@ -855,13 +928,13 @@
 #
 apropos_run() {
   func_check apropos_run = 1 "$@";
-  if apropos apropos >${_NULL_DEV} 2>${_NULL_DEV};
+  if apropos apropos >${_NULL_DEV} 2>${_NULL_DEV}
   then
     apropos "$1";
-  elif man --apropos man >${_NULL_DEV} 2>${_NULL_DEV};
+  elif man --apropos man >${_NULL_DEV} 2>${_NULL_DEV}
   then
     man --apropos "$1";
-  elif man -k man >${_NULL_DEV} 2>${_NULL_DEV};
+  elif man -k man >${_NULL_DEV} 2>${_NULL_DEV}
   then
     man -k "$1";
   fi;
@@ -888,10 +961,7 @@
   case "${bn_name}" in
     */)
       # delete all final slashes
-      bn_name="$(echo x"${bn_name}" | sed -e '
-s/^x//
-s|//*$||
-')";
+      bn_name="$(echo1 "${bn_name}" | sed -e 's|//*$||')";
       ;;
   esac;
   case "${bn_name}" in
@@ -901,15 +971,10 @@
       ;;
     */*)
       # delete everything before and including the last slash `/'.
-      echo x"${bn_name}" | sed -e '
-s/^x//
-s|^.*//*\([^/]*\)$|\1|
-';
+      echo1 "${bn_name}" | sed -e 's|^.*//*\([^/]*\)$|\1|';
       ;;
     *)
-      cat <<EOF
-${bn_name}
-EOF
+      obj bn_name echo1;
       ;;
   esac;
   eval ${_UNSET} bn_name;
@@ -927,7 +992,7 @@
 # Arguments: 1, a file name.
 # Output: the content of <file>, possibly decompressed.
 #
-if test _"${_HAS_COMPRESSION}"_ = _yes_;
+if test _"${_HAS_COMPRESSION}"_ = _yes_
 then
   cat_z()
   {
@@ -940,9 +1005,9 @@
         error 'cat_z(): for standard input use save_stdin()';
         ;;
     esac;
-    if obj _HAS_BZIP is_yes;
+    if obj _HAS_BZIP is_yes
     then
-      if bzip2 -t "$1" 2>${_NULL_DEV};
+      if bzip2 -t "$1" 2>${_NULL_DEV}
       then
         bzip2 -c -d "$1" 2>${_NULL_DEV};
         eval "${return_ok}";
@@ -992,15 +1057,13 @@
 dirname_append()
 {
   func_check dirname_append = 2 "$@";
-  if is_empty "$1";
+  if is_empty "$1"
   then
     error "dir_append(): first argument is empty.";
   fi;
-  if is_empty "$2";
+  if is_empty "$2"
   then
-    cat <<EOF
-$1
-EOF
+    echo1 "$1";
   else
     dirname_chop "$1"/"$2";
   fi;
@@ -1022,22 +1085,15 @@
 {
   func_check dirname_chop = 1 "$@";
   # replace all multiple slashes by a single slash `/'.
-  dc_res="$(echo x"$1" | sed -e '
-s/^x//
-s|///*|/|g
-')";
+  dc_res="$(echo1 "$1" | sed -e 's|///*|/|g')";
   case "${dc_res}" in
-    ?*/)
-      # remove trailing slash '/';
-      echo x"${dc_res}" | sed -e '
-s/^x//
-s|/$||
-';
-      ;;
-    *) cat <<EOF
-${dc_res}
-EOF
-  ;;
+  ?*/)
+    # remove trailing slash '/';
+    echo1 "${dc_res}" | sed -e 's|/$||';
+    ;;
+  *)
+    obj dc_res echo1
+    ;;
   esac;
   eval ${_UNSET} dc_res;
   eval "${return_ok}";
@@ -1086,9 +1142,9 @@
       set 'File';
       ;;
     *)
-      if obj _MAN_ENABLE is_yes;
+      if obj _MAN_ENABLE is_yes
       then
-        if obj _MAN_FORCE is_yes;
+        if obj _MAN_FORCE is_yes
         then
           set 'Manpage' 'File';
         else
@@ -1103,38 +1159,53 @@
   do
     case "$i" in
       File)
-        if test -f "${df_filespec}";
+        if test -f "${df_filespec}"
         then
-          if test -r "${df_filespec}";
+          if test -r "${df_filespec}"
           then
             register_file "${df_filespec}";
             eval ${_UNSET} df_filespec;
+            eval ${_UNSET} df_no_man;
             eval "${return_good}";
           else
            echo2 "could not read \`${df_filespec}'";
             eval ${_UNSET} df_filespec;
+            eval ${_UNSET} df_no_man;
             eval "${return_bad}";
           fi;
         else
+          if obj df_no_man is_not_empty
+          then
+            echo2 "\`${df_filespec}' is neither a file nor a man page."
+          fi;
+          df_no_file=yes;
           continue;
         fi;
         ;;
       Manpage)                 # parse filespec as man page
-        if obj _MAN_IS_SETUP is_not_yes;
+        if obj _MAN_IS_SETUP is_not_yes
         then
           man_setup;
         fi;
-        if man_do_filespec "${df_filespec}";
+        if man_do_filespec "${df_filespec}"
         then
           eval ${_UNSET} df_filespec;
+          eval ${_UNSET} df_no_file;
           eval "${return_good}";
         else
+          if obj df_no_file is_not_empty
+          then
+            echo2 "\`${df_filespec}' is neither a file nor a man page."
+          fi;
+          df_no_man=yes;
           continue;
        fi;
         ;;
     esac;
   done;
   eval ${_UNSET} df_filespec;
+  eval ${_UNSET} df_no_file;
+  eval ${_UNSET} df_no_man;
   eval "${return_bad}";
 } # do_filearg()
 
@@ -1216,18 +1287,16 @@
 get_first_essential()
 {
   func_check get_first_essential '>=' 0 "$@";
-  if is_equal "$#" 0;
+  if is_equal "$#" 0
   then
     eval "${return_ok}";
   fi;
   for i
   do
     gfe_var="$i";
-    if obj gfe_var is_not_empty;
+    if obj gfe_var is_not_empty
     then
-      cat <<EOF
-${gfe_var}
-EOF
+      obj gfe_var echo1;
       eval ${_UNSET} gfe_var;
       eval "${return_ok}";
     fi;
@@ -1252,7 +1321,7 @@
 is_dir()
 {
   func_check is_dir = 1 "$@";
-  if test -d "$1" && test -r "$1";
+  if test _"$1"_ != __ && test -d "$1" && test -r "$1"
   then
     eval "${return_yes}";
   fi;
@@ -1271,7 +1340,7 @@
 is_empty()
 {
   func_check is_empty = 1 "$@";
-  if test _"$1"_ = __;
+  if test _"$1"_ = __
   then
     eval "${return_yes}";
   fi;
@@ -1290,7 +1359,7 @@
 is_equal()
 {
   func_check is_equal = 2 "$@";
-  if test _"$1"_ = _"$2"_;
+  if test _"$1"_ = _"$2"_
   then
     eval "${return_yes}";
   fi;
@@ -1310,7 +1379,11 @@
 is_existing()
 {
   func_check is_existing = 1 "$@";
-  if test -f "$1" || test -d "$1";
+  if test _"$1"_ = __
+  then
+    eval "${return_no}";
+  fi;
+  if test -f "$1" || test -d "$1" || test -c "$1"
   then
     eval "${return_yes}";
   fi;
@@ -1329,7 +1402,7 @@
 is_file()
 {
   func_check is_file = 1 "$@";
-  if test -f "$1" && test -r "$1";
+  if test _"$1"_ != __ && test -f "$1" && test -r "$1"
   then
     eval "${return_yes}";
   fi;
@@ -1350,7 +1423,7 @@
 is_non_empty_file()
 {
   func_check is_non_empty_file = 1 "$@";
-  if is_file "$1" && test -s "$1";
+  if is_file "$1" && test -s "$1"
   then
     eval "${return_yes}";
   fi;
@@ -1369,7 +1442,7 @@
 is_not_dir()
 {
   func_check is_not_dir = 1 "$@";
-  if is_dir "$1";
+  if is_dir "$1"
   then
     eval "${return_no}";
   fi;
@@ -1388,7 +1461,7 @@
 is_not_empty()
 {
   func_check is_not_empty = 1 "$@";
-  if is_empty "$1";
+  if is_empty "$1"
   then
     eval "${return_no}";
   fi;
@@ -1406,7 +1479,7 @@
 is_not_equal()
 {
   func_check is_not_equal = 2 "$@";
-  if is_equal "$1" "$2";
+  if is_equal "$1" "$2"
   then
     eval "${return_no}";
   fi
@@ -1424,7 +1497,7 @@
 is_not_file()
 {
   func_check is_not_file '>=' 1 "$@";
-  if is_file "$1";
+  if is_file "$1"
   then
     eval "${return_no}";
   fi;
@@ -1443,7 +1516,7 @@
 is_not_prog()
 {
   func_check is_not_prog '>=' 1 "$@";
-  if where_is "$1" >${_NULL_DEV};
+  if where_is "$1" >${_NULL_DEV}
   then
     eval "${return_no}";
   fi;
@@ -1461,7 +1534,7 @@
 is_not_writable()
 {
   func_check is_not_writable '>=' 1 "$@";
-  if is_writable "$1";
+  if is_writable "$1"
   then
     eval "${return_no}";
   fi;
@@ -1479,7 +1552,7 @@
 is_not_yes()
 {
   func_check is_not_yes = 1 "$@";
-  if is_yes "$1";
+  if is_yes "$1"
   then
     eval "${return_no}";
   fi;
@@ -1503,7 +1576,7 @@
     eval "${return_no}";
     ;;
   *)
-    if where_is "$1" >${_NULL_DEV};
+    if where_is "$1" >${_NULL_DEV}
     then
       eval "${return_yes}";
     fi;
@@ -1523,9 +1596,13 @@
 is_writable()
 {
   func_check is_writable '>=' 1 "$@";
-  if test -r "$1";
+  if test _"$1"_ = __
   then
-    if test -w "$1";
+    eval "${return_no}";
+  fi;
+  if test -r "$1"
+  then
+    if test -w "$1"
     then
       eval "${return_yes}";
     fi;
@@ -1545,7 +1622,7 @@
 is_yes()
 {
   func_check is_yes = 1 "$@";
-  if is_equal "$1" 'yes';
+  if is_equal "$1" 'yes'
   then
     eval "${return_yes}";
   fi;
@@ -1564,14 +1641,19 @@
 
 
 ########################################################################
-# leave ()
+# leave ([<code>])
 #
-# Clean exit without an error.
+# Clean exit without an error or with <code>.
 #
 leave()
 {
   clean_up;
-  exit "${_OK}";
+  if test $# = 0
+  then
+    exit "${_OK}";
+  else
+    exit "$1";
+  fi;
 }
 
 
@@ -1583,7 +1665,7 @@
 # data consists of space-separated single-quoted elements.  So a list
 # has the form "'first' 'second' '...' 'last'".  See list_append() for
 # more details on the list structure.  The array elements of `list'
-# can be get by `set x $list; shift`.
+# can be get by `eval set x "$list"; shift`.
 
 
 ########################################################################
@@ -1612,10 +1694,7 @@
       # escape each single quote by replacing each
       # "'" (squote) by "'\''" (squote bslash squote squote);
       # note that the backslash must be doubled in the following `sed'
-      la_element="$(echo x"${la_s}" | sed -e '
-s/^x//
-s/'"${_SQUOTE}"'/&\\&&/g
-')";
+      la_element="$(echo1 "${la_s}" | sed -e 's/'"${_SQ}"'/&\\&&/g')";
       ;;
     '')
       la_element="";
@@ -1624,7 +1703,7 @@
       la_element="${la_s}";
       ;;
     esac;
-    if obj la_list is_empty;
+    if obj la_list is_empty
     then
       la_list="'${la_element}'";
     else
@@ -1687,31 +1766,27 @@
   lfc_short_a="$(obj_data "$1"_SHORT_ARG)"; # short options, with argument
   lfc_long_n="$(obj_data "$1"_LONG_NA)";    # long options, no argument
   lfc_long_a="$(obj_data "$1"_LONG_ARG)";   # long options, with argument
-  if obj lfc_short_n is_empty;
+  if obj lfc_short_n is_empty
   then
     error 'list_from_cmdline(): no $'"$1"'_SHORT_NA options.';
   fi;
-  if obj lfc_short_a is_empty;
+  if obj lfc_short_a is_empty
   then
     error 'list_from_cmdline(): no $'"$1"'_SHORT_ARG options.';
   fi;
-  if obj lfc_long_n is_empty;
+  if obj lfc_long_n is_empty
   then
     error 'list_from_cmdline(): no $'"$1"'_LONG_NA options.';
   fi;
-  if obj lfc_long_a is_empty;
+  if obj lfc_long_a is_empty
   then
     error 'list_from_cmdline(): no $'"$1"'_LONG_ARG options.';
   fi;
   shift;
-  lfc_fn='list_from_cmdline():';        # for error messages
-  if is_equal "$#" 0;
+  if is_equal "$#" 0
   then
-    cat <<EOF
---
-EOF
+    echo1 --
     eval ${_UNSET} lfc_fparams;
-    eval ${_UNSET} lfc_fn;
     eval ${_UNSET} lfc_short_a;
     eval ${_UNSET} lfc_short_n;
     eval ${_UNSET} lfc_long_a;
@@ -1721,116 +1796,112 @@
   fi;
   lfc_fparams='';
   lfc_result='';
-  while test "$#" -ge 1;
+  while test "$#" -ge 1
   do
     lfc_arg="$1";
     shift;
     case "${lfc_arg}" in
-      --) break; ;;
-      --?*)
-        # delete leading '--';
-        lfc_opt="$(echo x"${lfc_arg}" | sed -e 's/^x--//')";
-        if list_has lfc_long_n "${lfc_opt}";
+    --) break; ;;
+    --?*)
+      # delete leading '--';
+      lfc_abbrev="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
+      lfc_opt="$(list_single_from_abbrev lfc_long_n "${lfc_abbrev}")";
+      if obj lfc_opt is_not_empty
+      then
+        # long option, no argument
+        list_append lfc_result "--${lfc_opt}";
+        continue;
+      fi;
+      # test on `--opt=arg'
+      if string_contains "${lfc_abbrev}" '='
+      then
+        lfc_with_equal="${lfc_abbrev}";
+        # extract option by deleting from the first '=' to the end
+        lfc_abbrev="$(echo1 "${lfc_with_equal}" | \
+                      sed -e 's/^\([^=]*\)=.*$/\1/')";
+        lfc_opt="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
+        if obj lfc_opt is_not_empty
         then
-          # long option, no argument
-          list_append lfc_result "--${lfc_opt}";
+          # get the option argument by deleting up to first `='
+          lfc_optarg="$(echo1 "${lfc_with_equal}" | sed -e 's/^[^=]*=//')";
+          list_append lfc_result "--${lfc_opt}" "${lfc_optarg}";
           continue;
         fi;
-        # test on `--opt=arg'
-        if string_contains "${lfc_opt}" '=';
+      fi;
+      lfc_opt="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
+      if obj lfc_opt is_not_empty
+      then
+        # long option with argument
+        if test "$#" -le 0
         then
-          # extract option by deleting from the first '=' to the end
-          lfc_lopt="$(echo x"${lfc_opt}" | sed -e '
-s/^x//
-s/=.*$//
-')";
-          if list_has lfc_long_a "${lfc_lopt}";
-          then
-            # get the option argument by deleting up to first `='
-            lfc_optarg="$(echo x"${lfc_opt}" | sed -e '
-s/^x//
-s/^[^=]*=//
-')";
-            list_append lfc_result "--${lfc_lopt}" "${lfc_optarg}";
-            continue;
-          fi;
+          error "list_from_cmdline(): no argument for option --${lfc_opt}."
         fi;
-        if list_has lfc_long_a "${lfc_opt}";
+        list_append lfc_result "--${lfc_opt}" "$1";
+        shift;
+        continue;
+      fi;
+      error "list_from_cmdline(): --${lfc_opt} is not an option."
+      ;;
+    -?*)                       # short option (cluster)
+      # delete leading `-';
+      lfc_rest="$(echo1 "${lfc_arg}" | sed -e 's/^-//')";
+      while obj lfc_rest is_not_empty
+      do
+        # get next short option from cluster (first char of $lfc_rest)
+        lfc_optchar="$(echo1 "${lfc_rest}" | sed -e 's/^\(.\).*$/\1/')";
+        # remove first character from ${lfc_rest};
+        lfc_rest="$(echo1 "${lfc_rest}" | sed -e 's/^.//')";
+        if list_has lfc_short_n "${lfc_optchar}"
         then
-          # long option with argument
-          if test "$#" -le 0;
-          then
-            error "list_from_cmdline(): \
-${lfc_fn} no argument for option --${lfc_opt}."
-          fi;
-          list_append lfc_result "--${lfc_opt}" "$1";
-          shift;
+          list_append lfc_result "-${lfc_optchar}";
           continue;
-        fi;
-        error "list_from_cmdline(): ${lfc_fn} --${lfc_opt} is not an option."
-        ;;
-      -?*)                     # short option (cluster)
-        # delete leading `-';
-        lfc_rest="$(echo x"${lfc_arg}" | sed -e 's/^x-//')";
-        while obj lfc_rest is_not_empty;
-        do
-          # get next short option from cluster (first char of $lfc_rest)
-          lfc_optchar="$(echo x"${lfc_rest}" | sed -e 's/^x\(.\).*$/\1/')";
-          # remove first character from ${lfc_rest};
-          lfc_rest="$(echo x"${lfc_rest}" | sed -e 's/^x.//')";
-          if list_has lfc_short_n "${lfc_optchar}";
-          then
-            list_append lfc_result "-${lfc_optchar}";
-            continue;
-          elif list_has lfc_short_a "${lfc_optchar}";
+        elif list_has lfc_short_a "${lfc_optchar}"
+        then
+          if obj lfc_rest is_empty
           then
-            if obj lfc_rest is_empty;
+            if test "$#" -ge 1
             then
-              if test "$#" -ge 1;
-              then
-                list_append lfc_result "-${lfc_optchar}" "$1";
-                shift;
-                continue;
-              else
-                error "list_from_cmdline(): \
-${lfc_fn}"' no argument for option -'"${lfc_optchar}."
-              fi;
-            else               # rest is the argument
-              list_append lfc_result "-${lfc_optchar}" "${lfc_rest}";
-              lfc_rest='';
+              list_append lfc_result "-${lfc_optchar}" "$1";
+              shift;
               continue;
+            else
+              error 'list_from_cmdline(): no argument for option -'\
+"${lfc_optchar}."
             fi;
-          else
-            error "list_from_cmdline(): \
-${lfc_fn} unknown option -${lfc_optchar}."
+          else                 # rest is the argument
+            list_append lfc_result "-${lfc_optchar}" "${lfc_rest}";
+            lfc_rest='';
+            continue;
           fi;
-        done;
-        ;;
-      *)
-       # Here, $lfc_arg is not an option, so a file parameter.
-        list_append lfc_fparams "${lfc_arg}";
+        else
+          error "list_from_cmdline(): unknown option -${lfc_optchar}."
+        fi;
+      done;
+      ;;
+    *)
+      # Here, $lfc_arg is not an option, so a file parameter.
+      list_append lfc_fparams "${lfc_arg}";
 
-        # Ignore the strange option handling of $POSIXLY_CORRECT to
-        # end option parsing after the first file name argument.  To
-        # reuse it, do a `break' here if $POSIXLY_CORRECT is
-        # non-empty.
-        ;;
+      # Ignore the strange POSIX option handling to end option
+      # parsing after the first file name argument.  To reuse it, do
+      # a `break' here if $POSIXLY_CORRECT of `bash' is not empty.
+      # When `bash' is called as `sh' $POSIXLY_CORRECT is set
+      # automatically to `y'.
+      ;;
     esac;
   done;
   list_append lfc_result '--';
-  if obj lfc_fparams is_not_empty;
+  if obj lfc_fparams is_not_empty
   then
     lfc_result="${lfc_result} ${lfc_fparams}";
   fi;
-  if test "$#" -gt 0;
+  if test "$#" -gt 0
   then
     list_append lfc_result "$@";
   fi;
-  cat <<EOF
-${lfc_result}
-EOF
+  obj lfc_result echo1;
+  eval ${_UNSET} lfc_abbrev;
   eval ${_UNSET} lfc_fparams;
-  eval ${_UNSET} lfc_fn;
   eval ${_UNSET} lfc_short_a;
   eval ${_UNSET} lfc_short_n;
   eval ${_UNSET} lfc_long_a;
@@ -1840,7 +1911,7 @@
   eval ${_UNSET} lfc_opt;
   eval ${_UNSET} lfc_opt_arg;
   eval ${_UNSET} lfc_opt_char;
-  eval ${_UNSET} lfc_lopt;
+  eval ${_UNSET} lfc_with_equal;
   eval ${_UNSET} lfc_rest;
   eval "${return_ok}";
 } # list_from_cmdline()
@@ -1863,24 +1934,15 @@
   func_check list_from_split = 2 "$@";
 
   # precede each space or tab by a backslash `\' (doubled for `sed')
-  lfs_s="$(echo x"$1" | sed -e '
-s/^x//
-s/\(['"${_SPACE}${_TAB}"']\)/\\\1/g
-')";
+  lfs_s="$(echo1 "$1" | sed -e 's/\(['"${_SP}${_TAB}"']\)/\\\1/g')";
 
   # replace split character of string by the list separator ` ' (space).
   case "$2" in
     /)                         # cannot use normal `sed' separator
-      echo x"${lfs_s}" | sed -e '
-s/^x//
-s|'"$2"'| |g
-';
+      echo1 "${lfs_s}" | sed -e 's|'"$2"'| |g';
       ;;
     ?)                         # use normal `sed' separator
-      echo x"${lfs_s}" | sed -e '
-s/^x//
-s/'"$2"'/ /g
-';
+      echo1 "${lfs_s}" | sed -e 's/'"$2"'/ /g';
       ;;
     ??*)
       error 'list_from_split(): separator must be a single character.';
@@ -1916,9 +1978,9 @@
   func_check list_get = 1 "$@";
   eval lg_list='"${'$1'}"';
   # remove leading and final space characters
-  lg_list="$(echo x"${lg_list}" | sed -e '
-s/^x['"${_SPACE}${_TAB}"']*//
-s/['"${_SPACE}${_TAB}"']*$//
+  lg_list="$(echo1 "${lg_list}" | sed -e '
+s/^['"${_SP}${_TAB}"']*//
+s/['"${_SP}${_TAB}"']*$//
 ')";
   case "${lg_list}" in
   '')
@@ -1926,9 +1988,7 @@
     eval "${return_ok}";
     ;;
   \'*\')
-    cat <<EOF
-${lg_list}
-EOF
+    obj lg_list echo1;
     eval ${_UNSET} lg_list;
     eval "${return_ok}";
     ;;
@@ -1944,30 +2004,72 @@
 ########################################################################
 # list_has (<var_name> <element>)
 #
+# Test whether the list <var_name> has the element <element>.
+#
 # Arguments: 2
 #   <var_name>: a variable name for a list of single-quoted elements
 #   <element>:  some sequence of characters.
-# Output:
-#   if <list> is empty:  "'<element>' '...'"
-#   otherwise:           "list '<element>' ..."
+#
+# Variable prefix: lh
 #
 list_has()
 {
   func_check list_has = 2 "$@";
-  eval _list='"${'$1'}"';
-  if obj _list is_empty;
+  eval lh_list='"${'$1'}"';
+  if obj lh_list is_empty
   then
+    eval "${_UNSET}" lh_list;
     eval "${return_no}";
   fi;
-  _element="$2";
   case "$2" in
-    \'*\')  _element="$2"; ;;
-    *)      _element="'$2'"; ;;
+    \'*\')  lh_element=" $2 "; ;;
+    *)      lh_element=" '$2' "; ;;
   esac;
-  if string_contains "${_list}" "${_element}";
+  if string_contains " ${lh_list} " "${lh_element}"
   then
+    eval "${_UNSET}" lh_list;
+    eval "${_UNSET}" lh_element;
     eval "${return_yes}";
   else
+    eval "${_UNSET}" lh_list;
+    eval "${_UNSET}" lh_element;
+    eval "${return_no}";
+  fi;
+}
+
+
+########################################################################
+# list_has_abbrev (<var_name> <abbrev>)
+#
+# Test whether the list <var_name> has an element starting with <abbrev>.
+#
+# Arguments: 2
+#   <var_name>: a variable name for a list of single-quoted elements
+#   <abbrev>:   some sequence of characters.
+#
+# Variable prefix: lha
+#
+list_has_abbrev()
+{
+  func_check list_has_abbrev = 2 "$@";
+  eval lha_list='"${'$1'}"';
+  if obj lha_list is_empty
+  then
+    eval "${_UNSET}" lha_list;
+    eval "${return_no}";
+  fi;
+  case "$2" in
+    \'*) lha_element=" $(echo1 "$2" | sed -e 's/'"${_SQ}"'$//')"; ;;
+    *)   lha_element=" '$2"; ;;
+  esac;
+  if string_contains " ${lha_list}" "${lha_element}"
+  then
+    eval "${_UNSET}" lha_list;
+    eval "${_UNSET}" lha_element;
+    eval "${return_yes}";
+  else
+    eval "${_UNSET}" lha_list;
+    eval "${_UNSET}" lha_element;
     eval "${return_no}";
   fi;
   eval "${return_ok}";
@@ -1977,33 +2079,100 @@
 ########################################################################
 # list_has_not (<list> <element>)
 #
+# Test whether <list> has no <element>.
+#
 # Arguments: 2
 #   <list>:    a space-separated list of single-quoted elements.
 #   <element>: some sequence of characters.
-# Output:
-#   if <list> is empty:  "'<element>' '...'"
-#   otherwise:           "<list> '<element>' ..."
+#
+# Variable prefix: lhn
 #
 list_has_not()
 {
   func_check list_has_not = 2 "$@";
-  eval _list='"${'$1'}"';
-  if obj _list is_empty;
+  eval lhn_list='"${'$1'}"';
+  if obj lhn_list is_empty
   then
+    eval "${_UNSET}" lhn_list;
     eval "${return_yes}";
   fi;
-  _element="$2";
   case "$2" in
-    \'*\')  _element="$2"; ;;
-    *)      _element="'$2'"; ;;
+    \'*\') lhn_element=" $2 "; ;;
+    *)     lhn_element="' $2 '"; ;;
   esac;
-  if string_contains "${_list}" "${_element}";
+  if string_contains " ${lhn_list} " "${lhn_element}"
   then
+    eval "${_UNSET}" lhn_list;
+    eval "${_UNSET}" lhn_element;
     eval "${return_no}";
   else
+    eval "${_UNSET}" lhn_list;
+    eval "${_UNSET}" lhn_element;
     eval "${return_yes}";
   fi;
-  eval "${return_ok}";
+}
+
+
+########################################################################
+# list_single_from_abbrev (<list> <abbrev>)
+#
+# Check whether the list has an element starting with <abbrev>.  If
+# there are more than a single element an error is created.
+#
+# Arguments: 2
+#   <list>:   a variable name for a list of single-quoted elements
+#   <abbrev>: some sequence of characters.
+#
+# Output: the found element.
+#
+# Variable prefix: lsfa
+#
+list_single_from_abbrev()
+{
+  func_check list_single_from_abbrev = 2 "$@";
+  eval lsfa_list='"${'$1'}"';
+  if obj lsfa_list is_empty
+  then
+    eval "${_UNSET}" lsfa_list;
+    eval "${return_no}";
+  fi;
+  lsfa_abbrev="$2";
+  if list_has lsfa_list "${lsfa_abbrev}"
+  then
+    obj lsfa_abbrev echo1;
+    eval "${_UNSET}" lsfa_abbrev;
+    eval "${_UNSET}" lsfa_list;
+    eval "${return_yes}";
+  fi;
+  if list_has_abbrev lsfa_list "${lsfa_abbrev}"
+  then
+    lsfa_element='';
+    eval set x "${lsfa_list}";
+    shift;
+    for i
+    do
+      case "$i" in
+      ${lsfa_abbrev}*)
+        if obj lsfa_element is_not_empty
+        then
+          error "list_single_from_abbrev: the abbreviation ${lsfa_abbrev} \
+has multiple options: ${lsfa_element} and ${i}.";
+        fi;
+        lsfa_element="$i";
+        ;;
+      esac;
+    done;
+    obj lsfa_element echo1;
+    eval "${_UNSET}" lsfa_abbrev;
+    eval "${_UNSET}" lsfa_element;
+    eval "${_UNSET}" lsfa_list;
+    eval "${return_yes}";
+  else
+    eval "${_UNSET}" lsfa_abbrev;
+    eval "${_UNSET}" lsfa_element;
+    eval "${_UNSET}" lsfa_list;
+    eval "${return_no}";
+  fi;
 }
 
 
@@ -2025,19 +2194,19 @@
 # Output    : none.
 # Return    : `0' if man page was found, `1' else.
 #
-# Only called from do_fileargs(), checks on $MANPATH and
-# $_MAN_ENABLE are assumed.
+# Only called from do_fileargs(), checks on $MANPATH and $_MAN_ENABLE
+# are assumed (see man_setup()).
 #
 # Variable prefix: mdf
 #
 man_do_filespec()
 {
   func_check man_do_filespec = 1 "$@";
-  if obj _MAN_PATH is_empty;
+  if obj _MAN_PATH is_empty
   then
     eval "${return_bad}";
   fi;
-  if is_empty "$1";
+  if is_empty "$1"
   then
     eval "${return_bad}";
   fi;
@@ -2053,37 +2222,37 @@
       eval "${return_bad}";
       ;;
     man:?*\(?*\))              # man:name(section)
-      mdf_name="$(echo x"${mdf_spec}" \
-               | sed -e 's/^xman:\(..*\)(\(..*\))$/\1/')";
-      mdf_section="$(echo x"${mdf_spec}" \
-               | sed -e 's/^xman:\(..*\)(\(..*\))$/\2/')";
+      mdf_name="$(echo1 "${mdf_spec}" \
+               | sed -e 's/^man:\(..*\)(\(..*\))$/\1/')";
+      mdf_section="$(echo1 "${mdf_spec}" \
+               | sed -e 's/^man:\(..*\)(\(..*\))$/\2/')";
       ;;
     man:?*.[0-9on])                    # man:name.section
-      mdf_name="$(echo x"${mdf_spec}" \
-               | sed -e 's/^xman:\(..*\)\..$/\1/')";
-      mdf_section="$(echo x"${mdf_spec}" \
-               | sed -e 's/^x.*\(.\)$/\1/')";
+      mdf_name="$(echo1 "${mdf_spec}" \
+               | sed -e 's/^man:\(..*\)\..$/\1/')";
+      mdf_section="$(echo1 "${mdf_spec}" \
+               | sed -e 's/^.*\(.\)$/\1/')";
       ;;
     man:?*)                    # man:name
-      mdf_name="$(echo x"${mdf_spec}" | sed -e 's/^xman://')";
+      mdf_name="$(echo1 "${mdf_spec}" | sed -e 's/^man://')";
       ;;
     ?*\(?*\))                  # name(section)
-      mdf_name="$(echo x"${mdf_spec}" \
-               | sed -e 's/^x\(..*\)(\(..*\))$/\1/')";
-      mdf_section="$(echo x"${mdf_spec}" \
-               | sed -e 's/^x\(..*\)(\(..*\))$/\2/')";
+      mdf_name="$(echo1 "${mdf_spec}" \
+               | sed -e 's/^\(..*\)(\(..*\))$/\1/')";
+      mdf_section="$(echo1 "${mdf_spec}" \
+               | sed -e 's/^\(..*\)(\(..*\))$/\2/')";
       ;;
     ?*.[0-9on])                        # name.section
-      mdf_name="$(echo x"${mdf_spec}" \
-               | sed -e 's/^x\(..*\)\..$/\1/')";
-      mdf_section="$(echo x"${mdf_spec}" \
-               | sed -e 's/^x.*\(.\)$/\1/')";
+      mdf_name="$(echo1 "${mdf_spec}" \
+               | sed -e 's/^\(..*\)\..$/\1/')";
+      mdf_section="$(echo1 "${mdf_spec}" \
+               | sed -e 's/^.*\(.\)$/\1/')";
       ;;
     ?*)
       mdf_name="${mdf_spec}";
       ;;
   esac;
-  if obj mdf_name is_empty;
+  if obj mdf_name is_empty
   then
     eval ${_UNSET} mdf_got_one;
     eval ${_UNSET} mdf_name;
@@ -2092,16 +2261,16 @@
     eval "${return_bad}";
   fi;
   mdf_got_one='no';
-  if obj mdf_section is_empty;
+  if obj mdf_section is_empty
   then
     eval set x "${_MAN_AUTO_SEC}";
     shift;
     for s
     do
       mdf_s="$s";
-      if man_search_section "${mdf_name}" "${mdf_s}";
+      if man_search_section "${mdf_name}" "${mdf_s}"
       then                     # found
-        if obj _MAN_ALL is_yes;
+        if obj _MAN_ALL is_yes
         then
           mdf_got_one='yes';
         else
@@ -2115,7 +2284,7 @@
       fi;
     done;
   else
-    if man_search_section "${mdf_name}" "${mdf_section}";
+    if man_search_section "${mdf_name}" "${mdf_section}"
     then
       eval ${_UNSET} mdf_got_one;
       eval ${_UNSET} mdf_name;
@@ -2131,7 +2300,7 @@
       eval "${return_bad}";
     fi;
   fi;
-  if obj _MAN_ALL is_yes && is_yes "${mdf_got_one}";
+  if obj _MAN_ALL is_yes && is_yes "${mdf_got_one}"
   then
     eval ${_UNSET} mdf_got_one;
     eval ${_UNSET} mdf_name;
@@ -2166,7 +2335,7 @@
       error "man_register_file() expects 2 or 3 arguments.";
       ;;
   esac;
-  if is_empty "$1";
+  if is_empty "$1"
   then
     error 'man_register_file(): file name is empty';
   fi;
@@ -2199,15 +2368,15 @@
 man_search_section()
 {
   func_check man_search_section = 2 "$@";
-  if obj _MAN_PATH is_empty;
+  if obj _MAN_PATH is_empty
   then
     eval "${return_bad}";
   fi;
-  if is_empty "$1";
+  if is_empty "$1"
   then
     eval "${return_bad}";
   fi;
-  if is_empty "$2";
+  if is_empty "$2"
   then
     eval "${return_bad}";
   fi;
@@ -2216,30 +2385,30 @@
   eval set x "$(path_split "${_MAN_PATH}")";
   shift;
   mss_got_one='no';
-  if obj _MAN_EXT is_empty;
+  if obj _MAN_EXT is_empty
   then
     for d
     do
       mss_dir="$(dirname_append "$d" "man${mss_section}")";
-      if obj mss_dir is_dir;
+      if obj mss_dir is_dir
       then
         mss_prefix="$(\
           dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
         mss_files="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
                      sed -e '\| found|s|.*||'
                      )";
-        if obj mss_files is_not_empty;
+        if obj mss_files is_not_empty
         then
           # for f in $mss_files
           for f in $(eval set x ${mss_files}; shift; echo "$@")
           do
             mss_f="$f";
-            if obj mss_f is_file;
+            if obj mss_f is_file
             then
-              if is_yes "${mss_got_one}";
+              if is_yes "${mss_got_one}"
               then
                 register_file "${mss_f}";
-              elif obj _MAN_ALL is_yes;
+              elif obj _MAN_ALL is_yes
               then
                 man_register_file "${mss_f}" "${mss_name}";
               else
@@ -2266,25 +2435,25 @@
     for d
     do
       mss_dir="$(dirname_append $d man${mss_section}${mss_ext})";
-      if obj mss_dir is_dir;
+      if obj mss_dir is_dir
       then
         mss_prefix=\
           "$(dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
         mss_files="$( eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
                      sed -e '\|not found|s|.*||'
                      )";
-        if obj mss_files is_not_empty;
+        if obj mss_files is_not_empty
         then
           # for f in $mss_files
           for f in $(eval set x ${mss_files}; shift; echo "$@")
           do
             mss_f="$f";
-            if obj mss_f is_file;
+            if obj mss_f is_file
             then
-              if is_yes "${mss_got_one}";
+              if is_yes "${mss_got_one}"
               then
                 register_file "${mss_f}";
-              elif obj _MAN_ALL is_yes;
+              elif obj _MAN_ALL is_yes
               then
                 man_register_file "${mss_f}" "${mss_name}";
               else
@@ -2309,25 +2478,25 @@
     for d
     do
       mss_dir="$(dirname_append "$d" "man${mss_section}")";
-      if obj mss_dir is_dir;
+      if obj mss_dir is_dir
       then
         mss_prefix="$(dirname_append "${mss_dir}" \
                         "${mss_name}.${mss_section}${mss_ext}")";
         mss_files="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
                      sed -e '\|not found|s|.*||'
                      )";
-        if obj mss_files is_not_empty;
+        if obj mss_files is_not_empty
         then
           # for f in $mss_files
           for f in $(eval set x ${mss_files}; shift; echo "$@")
           do
             mss_f="$f";
-            if obj mss_f is_file;
+            if obj mss_f is_file
             then
-              if is_yes "${mss_got_one}";
+              if is_yes "${mss_got_one}"
               then
                 register_file "${mss_f}";
-              elif obj _MAN_ALL is_yes;
+              elif obj _MAN_ALL is_yes
               then
                 man_register_file "${mss_f}" "${mss_name}";
               else
@@ -2349,7 +2518,7 @@
       fi;
     done;
   fi;
-  if obj _MAN_ALL is_yes && is_yes "${mss_got_one}";
+  if obj _MAN_ALL is_yes && is_yes "${mss_got_one}"
   then
     eval ${_UNSET} mss_dir;
     eval ${_UNSET} mss_ext;
@@ -2401,13 +2570,13 @@
 {
   func_check main_man_setup = 0 "$@";
 
-  if obj _MAN_IS_SETUP is_yes;
+  if obj _MAN_IS_SETUP is_yes
   then
     eval "${return_ok}";
   fi;
   _MAN_IS_SETUP='yes';
 
-  if obj _MAN_ENABLE is_not_yes;
+  if obj _MAN_ENABLE is_not_yes
   then
     eval "${return_ok}";
   fi;
@@ -2415,27 +2584,27 @@
   # determine basic path for man pages
   _MAN_PATH="$(get_first_essential \
                "${_OPT_MANPATH}" "${_MANOPT_PATH}" "${MANPATH}")";
-  if obj _MAN_PATH is_empty;
+  if obj _MAN_PATH is_empty
   then
     manpath_set_from_path;
   else
     _MAN_PATH="$(path_clean "${_MAN_PATH}")";
   fi;
-  if obj _MAN_PATH is_empty;
+  if obj _MAN_PATH is_empty
   then
-    if is_prog 'manpath';
+    if is_prog 'manpath'
     then
       _MAN_PATH="$(manpath 2>${_NULL_DEV})"; # not always available
     fi;
   fi;
-  if obj _MAN_PATH is_empty;
+  if obj _MAN_PATH is_empty
   then
     _MAN_ENABLE="no";
     eval "${return_ok}";
   fi;
 
   _MAN_ALL="$(get_first_essential "${_OPT_ALL}" "${_MANOPT_ALL}")";
-  if obj _MAN_ALL is_empty;
+  if obj _MAN_ALL is_empty
   then
     _MAN_ALL='no';
   fi;
@@ -2456,7 +2625,7 @@
     *)
       _MAN_LANG="${ms_lang}";
       # get first two characters of $ms_lang
-      _MAN_LANG2="$(echo x"${ms_lang}" | sed -e 's/^x\(..\).*$/\1/')";
+      _MAN_LANG2="$(echo1 "${ms_lang}" | sed -e 's/^\(..\).*$/\1/')";
       ;;
   esac;
   # from now on, use only $_LANG, forget about $_OPT_LANG, $LC_*.
@@ -2465,7 +2634,7 @@
 
   _MAN_SEC="$(get_first_essential \
               "${_OPT_SECT}" "${_MANOPT_SEC}" "${MANSEC}")";
-  if obj _MAN_PATH is_empty;
+  if obj _MAN_PATH is_empty
   then
     _MAN_ENABLE="no";
     eval ${_UNSET} ms_lang;
@@ -2502,7 +2671,7 @@
 manpath_add_lang_sys()
 {
   func_check manpath_add_lang_sys = 0 "$@";
-  if obj _MAN_PATH is_empty;
+  if obj _MAN_PATH is_empty
   then
     eval "${return_ok}";
   fi;
@@ -2546,12 +2715,12 @@
   do
     _mals_dir="$(dirname_append "${_mals_parent}" "$d")";
     if obj _mals_res path_not_contains "${_mals_dir}" && \
-       obj _mals_dir is_dir;
+       obj _mals_dir is_dir
     then
       _mals_res="${_mals_res}:${_mals_dir}";
     fi;
   done;
-  if path_not_contains "${_mals_res}" "${_mals_parent}";
+  if path_not_contains "${_mals_res}" "${_mals_parent}"
   then
     _mals_res="${_mals_res}:${_mals_parent}";
   fi;
@@ -2585,21 +2754,18 @@
   msfp_manpath='';
 
   # get a basic man path from $PATH
-  if obj PATH is_not_empty;
+  if obj PATH is_not_empty
   then
     eval set x "$(path_split "${PATH}")";
     shift;
     for d
     do
       # delete the final `/bin' part
-      msfp_base="$(echo x"$d" | sed -e '
-s/^x//
-s|//*bin/*$||
-')";
+      msfp_base="$(echo1 "$d" | sed -e 's|//*bin/*$||')";
       for e in /share/man /man
       do
         msfp_mandir="${msfp_base}$e";
-        if test -d "${msfp_mandir}" && test -r "${msfp_mandir}";
+        if test -d "${msfp_mandir}" && test -r "${msfp_mandir}"
         then
           msfp_manpath="${msfp_manpath}:${msfp_mandir}";
         fi;
@@ -2615,7 +2781,7 @@
            /opt/gnome/man /opt/kde/man
   do
     msfp_d="$d";
-    if obj msfp_manpath path_not_contains "${msfp_d}" && obj mfsp_d is_dir;
+    if obj msfp_manpath path_not_contains "${msfp_d}" && obj mfsp_d is_dir
     then
       msfp_manpath="${msfp_manpath}:${mfsp_d}";
     fi;
@@ -2652,7 +2818,7 @@
 obj()
 {
   func_check obj '>=' 2 "$@";
-  if is_empty "$2";
+  if is_empty "$2"
   then
     error "obj(): function name is empty."
   else
@@ -2684,14 +2850,12 @@
 obj_data()
 {
   func_check obj '=' 1 "$@";
-  if is_empty "$1";
+  if is_empty "$1"
   then
     error "obj_data(): object name is empty."
   fi;
   eval od_res='"${'$1'}"';
-  cat <<EOF
-${od_res}
-EOF
+  obj od_res echo1;
   eval ${_UNSET} od_res;
   eval "${return_ok}";
 }
@@ -2714,10 +2878,10 @@
 obj_from_output()
 {
   func_check obj_from_output '>=' 2 "$@";
-  if is_empty "$1";
+  if is_empty "$1"
   then
     error "res(): variable name is empty.";
-  elif is_empty "$2";
+  elif is_empty "$2"
   then
     error "res(): function name is empty."
   else
@@ -2742,7 +2906,7 @@
 obj_set()
 {
   func_check obj_set '=' 2 "$@";
-  if is_empty "$1";
+  if is_empty "$1"
   then
     error "obj_set(): object name is empty."
   fi;
@@ -2765,8 +2929,8 @@
 
   # replace multiple colons by a single colon `:'
   # remove leading and trailing colons
-  echo x"$1" | sed -e '
-s/^x:*//
+  echo1 "$1" | sed -e '
+s/^:*//
 s/:::*/:/g
 s/:*$//
 ';
@@ -2787,7 +2951,7 @@
 path_clean()
 {
   func_check path_clean = 1 "$@";
-  if is_not_equal "$#" 1;
+  if is_not_equal "$#" 1
   then
     error 'path_clean() needs 1 argument.';
   fi;
@@ -2800,7 +2964,7 @@
     pc_i="$i";
     if obj pc_i is_not_empty \
        && obj pc_res path_not_contains "${pc_i}" \
-       && obj pc_i is_dir;
+       && obj pc_i is_dir
     then
       case "${pc_i}" in
         ?*/) pc_res="${pc_res}$(dirname_chop "${pc_i}")"; ;;
@@ -2811,7 +2975,7 @@
   eval ${_UNSET} pc_arg;
   eval ${_UNSET} pc_i;
   eval ${_UNSET} pc_res;
-  if path_chop "${pc_res}";
+  if path_chop "${pc_res}"
   then
     eval "${return_ok}";
   else
@@ -2853,7 +3017,7 @@
 path_not_contains()
 {
   func_check path_not_contains = 2 "$@";
-  if path_contains "$1" "$2";
+  if path_contains "$1" "$2"
   then
     eval "${return_no}";
   else
@@ -2894,11 +3058,11 @@
 register_file()
 {
   func_check register_file = 1 "$@";
-  if is_empty "$1";
+  if is_empty "$1"
   then
     error 'register_file(): file name is empty';
   fi;
-  if is_equal "$1" '-';
+  if is_equal "$1" '-'
   then
     to_tmp "${_TMP_STDIN}";
     register_title 'stdin';
@@ -2921,25 +3085,21 @@
 #
 register_title()
 {
-  func_check register_title = 1 "$@";
-  if is_empty "$1";
+  func_check register_title '=' 1 "$@";
+  if is_empty "$1"
   then
     eval "${return_ok}";
   fi;
   rt_title="$(base_name "$1")";        # remove directory part
 
+  # replace space characters by `_'
+  rt_title="$(echo1 "${rt_title}" | sed -e 's/[        ]/_/g')";
   # remove extension `.gz'
-  rt_title="$(echo x"${rt_title}" | sed -e '
-s/^x//
-s/\.gz$//
-')";
+  rt_title="$(echo1 "${rt_title}" | sed -e 's/\.gz$//')";
   # remove extension `.Z'
-  rt_title="$(echo x"${rt_title}" | sed -e '
-s/^x//
-s/\.Z$//
-')";
+  rt_title="$(echo1 "${rt_title}" | sed -e 's/\.Z$//')";
 
-  if obj rt_title is_empty;
+  if obj rt_title is_empty
   then
     eval "${return_ok}";
   fi;
@@ -2959,21 +3119,93 @@
 
 
 ########################################################################
+# rm_file (<file_name>)
+#
+# Remove file if $_DEBUG_KEEP_FILES allows it.
+#
+# Globals: $_DEBUG_KEEP_FILES
+#
+rm_file()
+{
+  func_check rm_file '=' 1 "$@";
+  if is_file "$1"
+  then
+    rm -f "$1" >${_NULL_DEV} 2>&1;
+  fi;
+  if is_existing "$1"
+  then
+    eval "${return_bad}";
+  else
+    eval "${return_good}";
+  fi;
+}
+
+
+########################################################################
+# rm_file_with_debug (<file_name>)
+#
+# Remove file if $_DEBUG_KEEP_FILES allows it.
+#
+# Globals: $_DEBUG_KEEP_FILES
+#
+rm_file_with_debug()
+{
+  func_check rm_file_with_debug '=' 1 "$@";
+  if obj _DEBUG_KEEP_FILES is_not_yes
+  then
+    if is_file "$1"
+    then
+      rm -f "$1" >${_NULL_DEV} 2>&1;
+    fi;
+  fi;
+  if is_existing "$1"
+  then
+    eval "${return_bad}";
+  else
+    eval "${return_good}";
+  fi;
+}
+
+
+########################################################################
+# rm_tree (<dir_name>)
+#
+# Remove file if $_DEBUG_KEEP_FILES allows it.
+#
+# Globals: $_DEBUG_KEEP_FILES
+#
+rm_tree()
+{
+  func_check rm_tree '=' 1 "$@";
+  if is_existing "$1"
+  then
+    rm -f -r "$1" >${_NULL_DEV} 2>&1;
+  fi; 
+  if is_existing "$1"
+  then
+    eval "${return_bad}";
+  else
+    eval "${return_good}";
+  fi;
+}
+
+
+########################################################################
 # save_stdin ()
 #
 # Store standard input to temporary file (with decompression).
 #
 # Variable prefix: ss
 #
-if obj _HAS_COMPRESSION is_yes;
+if obj _HAS_COMPRESSION is_yes
 then
   save_stdin()
   {
-    func_check save_stdin = 0 "$@";
+    func_check save_stdin '=' 0 "$@";
     ss_f="${_TMP_DIR}"/INPUT;
     cat >"${ss_f}";
     cat_z "${ss_f}" >"${_TMP_STDIN}";
-    rm -f "${ss_f}";
+    rm_file "${ss_f}";
     eval ${_UNSET} ss_f;
     eval "${return_ok}";
   }
@@ -3001,7 +3233,7 @@
 #
 string_contains()
 {
-  func_check string_contains = 2 "$@";
+  func_check string_contains '=' 2 "$@";
   case "$1" in
     *"$2"*)
       eval "${return_yes}";
@@ -3024,8 +3256,8 @@
 #
 string_not_contains()
 {
-  func_check string_not_contains = 2 "$@";
-  if string_contains "$1" "$2";
+  func_check string_not_contains '=' 2 "$@";
+  if string_contains "$1" "$2"
   then
     eval "${return_no}";
   else
@@ -3073,9 +3305,7 @@
   # different names from the output file.
   tc_tmp="${_TMP_DIR}/,$1";
   : >"${tc_tmp}"
-  cat <<EOF
-${tc_tmp}
-EOF
+  obj tc_tmp echo1;
   eval ${_UNSET} tc_tmp;
   eval "${return_ok}";
 }
@@ -3089,13 +3319,13 @@
 to_tmp()
 {
   func_check to_tmp = 1 "$@";
-  if is_file "$1";
+  if is_file "$1"
   then
-    if obj _OPT_LOCATION is_yes;
+    if obj _OPT_LOCATION is_yes
     then
       echo2 "$1";
     fi;
-    if obj _OPT_WHATIS is_yes;
+    if obj _OPT_WHATIS is_yes
     then
       what_is "$1" >>"${_TMP_CAT}";
     else
@@ -3120,7 +3350,7 @@
 {
   func_check trap_clean = 0 "$@";
   # for i in $_ALL_EXIT
-  for i in $(eval set x ${_ALL_EXIT}; shift; echo "$@")
+  for i in $(eval set x "${_ALL_EXIT}"; shift; echo "$@")
   do
     trap "" "$i" 2>${_NULL_DEV} || :;
   done;
@@ -3140,7 +3370,7 @@
 {
   func_check trap_set = 1 "$@";
   # for i in $_ALL_EXIT
-  for i in $(eval set x ${_ALL_EXIT}; shift; echo "$@")
+  for i in $(eval set x "${_ALL_EXIT}"; shift; echo "$@")
   do
     trap "$1" "$i" 2>${_NULL_DEV} || :;
   done;
@@ -3158,7 +3388,7 @@
   func_check usage = 0 "$@";
   echo;
   version;
-  echo 'Usage: '"${_PROGRAM_NAME}"' [option]... [filespec]...';
+  echo 'Usage: groffer [option]... [filespec]...';
   cat <<EOF
 
 Display roff files, standard input, and/or Unix manual pages with a X
@@ -3174,51 +3404,55 @@
   "name"           man page "name" in first section found
 and some more (see groffer(1) for details).
 
--h --help        print this usage message.
--Q --source      output as roff source.
--T --device=name pass to groff using output device "name".
--v --version     print version information.
--V               display the groff execution pipe instead of formatting.
--X --X --x       display with "gxditview" using groff -X.
+-h --help         print this usage message.
+-Q --source       output as roff source.
+-T --device=name  pass to groff using output device "name".
+-v --version      print version information.
+-V                display the groff execution pipe instead of formatting.
+-X                display with "gxditview" using groff -X.
 -Z --ditroff --intermediate-output
-                 generate groff intermediate output without
-                 post-processing and viewing, like groff -Z.
+                  generate groff intermediate output without
+                  post-processing and viewing, like groff -Z.
 All other short options are interpreted as "groff" formatting options.
 
 The most important groffer long options are
 
---apropos=name   start man's "apropos" program for "name".
+--apropos=name    start man's "apropos" program for "name".
 --apropos-data=name
-                 "apropos" for "name" in man's data sections 4, 5, 7.
+                  "apropos" for "name" in man's data sections 4, 5, 7.
 --apropos-devel=name
-                 "apropos" for "name" in development sections 2, 3, 9.
+                  "apropos" for "name" in development sections 2, 3, 9.
 --apropos-progs=name
-                 "apropos" for "name" in man's program sections 1, 6, 8.
---auto           choose mode automatically from the default mode list.
---default        reset all options to the default value.
+                  "apropos" for "name" in man's program sections 1, 6, 8.
+--auto            choose mode automatically from the default mode list.
+--default         reset all options to the default value.
 --default-modes=mode1,mode2,...
-                 set sequence of automatically tried modes.
---dvi            display in a viewer for TeX device independent format.
---dvi-viewer     choose the viewer program for dvi mode.
---groff          process like groff, disable viewing features.
---help           display this helping output.
---html --www     display in a web browser.
---html-viewer    choose the web browser for www mode.
---man            check file parameters first whether they are man pages.
+                  set sequence of automatically tried modes.
+--dvi             display in a viewer for TeX device independent format.
+--dvi-viewer=prog choose the viewer program for dvi mode.
+--groff           process like groff, disable viewing features.
+--help            display this helping output.
+--html            display in a web browser.
+--html-viewer=program
+                  choose the web browser for html mode.
+--man             check file parameters first whether they are man pages.
 --mode=auto|dvi|groff|html|pdf|ps|source|text|tty|www|x|X
-                 choose display mode.
---no-man         disable man-page facility.
---pager=program  preset the paging program for tty mode.
---pdf            display in a PDF viewer.
---pdf-viewer     choose the viewer program for pdf mode.
---ps             display in a Postscript viewer.
---ps-viewer      choose the viewer program for ps mode.
---shell          specify shell under which to run this program.
---text           output in a text device without a pager.
---tty            display with a pager on text terminal even when in X.
---www-viewer     same as --html-viewer
---x-viewer       choose viewer program for x mode (X mode).
---X-viewer       same as "--xviewer".
+                  choose display mode.
+--no-man          disable man-page facility.
+--pager=program   preset the paging program for tty mode.
+--pdf             display in a PDF viewer.
+--pdf-viewer=prog choose the viewer program for pdf mode.
+--ps              display in a Postscript viewer.
+--ps-viewer=prog  choose the viewer program for ps mode.
+--shell=program   specify shell under which to run groffer2.sh.
+--text            output in a text device without a pager.
+--tty             display with a pager on text terminal even when in X.
+--tty-viewer=prog select a pager for tty mode; same as --pager.
+--www             same as --html.
+--www-viewer=prog same as --html-viewer
+--x --X           display with "gxditview" using an X* device.
+--x-viewer=prog   choose viewer program for x mode (X mode).
+--X-viewer=prog   same as "--xviewer".
 
 The usual X Windows toolkit options transformed into GNU long options
 --background=color, --bd=size, --bg=color, --bordercolor=color,
@@ -3244,7 +3478,7 @@
 version()
 {
   func_check version = 0 "$@";
-  echo2 "${_PROGRAM_NAME} ${_PROGRAM_VERSION} of ${_LAST_UPDATE}";
+  echo2 "groffer ${_PROGRAM_VERSION} of ${_LAST_UPDATE}";
   # also display groff's version, but not the called subprograms
   groff -v 2>&1 | sed -e '/^ *$/q' | sed -e '1s/^/is part of /' >&2;
   eval "${return_ok}";
@@ -3273,11 +3507,11 @@
 what_is()
 {
   func_check what_is = 1 "$@";
-  if is_not_file "$1";
+  if is_not_file "$1"
   then
     error "what_is(): argument is not a readable file."
   fi;
-  wi_dot='^\.['"${_SPACE}${_TAB}"']*';
+  wi_dot='^\.['"${_SP}${_TAB}"']*';
   cat <<EOF
 .br
   $1:
@@ -3286,7 +3520,7 @@
   # grep the line containing `.TH' macro, if any
   wi_res="$(cat_z "$1" | sed -e '/'"${wi_dot}"'TH /p
 d')";
-  if obj wi_res is_not_empty;
+  if obj wi_res is_not_empty
   then                         # traditional man style
     # get the text between the first and the second `.SH' macro, by
     # - delete up to first .SH;
@@ -3303,7 +3537,7 @@
   # grep the line containing `.Dd' macro, if any
   wi_res="$(cat_z "$1" | sed -e '/'"${wi_dot}"'Dd /p
 d')";
-  if obj wi_res is_not_empty;
+  if obj wi_res is_not_empty
   then                         # BSD doc style
     # get the text between the first and the second `.Nd' macro, by
     # - delete up to first .Nd;
@@ -3339,7 +3573,7 @@
 {
   func_check where_is '>=' 1 "$@";
   w_arg="$1";
-  if obj w_arg is_empty;
+  if obj w_arg is_empty
   then
     eval ${_UNSET} w_arg;
     eval "${return_bad}";
@@ -3348,7 +3582,7 @@
     /*)
       eval ${_UNSET} w_arg;
       eval ${_UNSET} w_file;
-      if test -f "${w_arg}" && test -x "${w_arg}";
+      if test -f "${w_arg}" && test -x "${w_arg}"
       then
         eval "${return_ok}";
       else
@@ -3364,11 +3598,9 @@
       */) w_file=${p}${w_arg}; ;;
       *)  w_file=${p}/${w_arg}; ;;
     esac;
-    if test -f "${w_file}" && test -x "${w_file}";
+    if test -f "${w_file}" && test -x "${w_file}"
     then
-      cat <<EOF
-${w_file}
-EOF
+      obj w_file echo1;
       eval ${_UNSET} w_arg;
       eval ${_UNSET} w_file;
       eval "${return_ok}";
@@ -3398,7 +3630,6 @@
 # sequence they are called in the main() function.
 
 
-landmark '13: main_init()';
 #######################################################################
 # main_init ()
 #
@@ -3422,7 +3653,7 @@
   do
     mi_dir="$d";
     if obj mi_dir is_empty || obj mi_dir is_not_dir || \
-       obj mi_dir is_not_writable;
+       obj mi_dir is_not_writable
     then
       continue;
     fi;
@@ -3435,52 +3666,43 @@
       _TMP_DIR="${mi_dir}"'/';
       ;;
     esac;
-    _TMP_DIR="${_TMP_DIR}${_PROGRAM_NAME}${_PROCESS_ID}";
-    if obj _TMP_DIR is_existing;
+    _TMP_DIR="${_TMP_DIR}groffer${_PROCESS_ID}";
+    if obj _TMP_DIR rm_tree
     then
-      eval rm -f -r  "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1;
-      if obj _TMP_DIR is_existing;
-      then
-        mi_tdir_="${_TMP_DIR}"_;
-        mi_n=1;
-        mi_tdir_n="${mi_tdir_}${mi_n}";
-        while obj mi_tdir_n is_existing;
-        do
-          eval rm -f -r "'${mi_tdir_n}'" >${_NULL_DEV} 2>&1;
-          if obj mi_tdir_n is_existing;
-          then
-            # directory could not be removed
-            mi_n="$(expr "${mi_n}" + 1)";
-            mi_tdir_n="${mi_tdir_}${mi_n}";
-            continue;
-          fi;
-        done;
-        _TMP_DIR="${mi_tdir_n}";
-      fi;
+      :
+    else
+      mi_tdir_="${_TMP_DIR}"_;
+      mi_n=1;
+      mi_tdir_n="${mi_tdir_}${mi_n}";
+      while obj mi_tdir_n is_existing
+      do
+        if obj mi_tdir_n rm_tree
+        then
+          # directory could not be removed
+          mi_n="$(expr "${mi_n}" + 1)";
+          mi_tdir_n="${mi_tdir_}${mi_n}";
+          continue;
+        fi;
+      done;
+      _TMP_DIR="${mi_tdir_n}";
     fi;
     eval mkdir "${_TMP_DIR}";
-    if is_not_equal "$?" 0;
+    if is_not_equal "$?" 0
     then
-      if obj _TMP_DIR is_existing;
-      then
-        eval rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1;
-      fi;
+      obj _TMP_DIR rm_tree;
       _TMP_DIR='';
       continue;
     fi;
-    if obj _TMP_DIR is_dir && obj _TMP_DIR is_writable;
+    if obj _TMP_DIR is_dir && obj _TMP_DIR is_writable
     then
       # $_TMP_DIR can now be used as temporary directory
       break;
     fi;
-    if obj _TMP_DIR is_existing;
-    then
-      rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1;
-    fi;
+    obj _TMP_DIR rm_tree;
     _TMP_DIR='';
     continue;
   done;
-  if obj _TMP_DIR is_empty;
+  if obj _TMP_DIR is_empty
   then
     error "main_init: \
 Couldn't create a directory for storing temporary files.";
@@ -3489,28 +3711,7 @@
   _TMP_CAT="$(tmp_create groffer_cat)";
   _TMP_STDIN="$(tmp_create groffer_input)";
 
-  # groffer configuration files
-  # for f in $_CONF_FILES
-  for f in $(eval set x ${_CONF_FILES}; shift; echo "$@")
-  do
-    mi_file="$f";
-    if obj mi_file is_file;
-    then
-      echo '_groffer_opt=""' >>${_TMP_CAT};
-      # collect the lines starting with a minus
-      cat "$mi_file" | sed -e '
-/^[     ]*#/d
-s/^[    ]*\(-.*\)$/_groffer_opt="${_groffer_opt} \1"/
-' >>${_TMP_CAT};
-      # prepend the collected information to $GROFFER_OPT
-      echo 'GROFFER_OPT="${_groffer_opt} ${GROFFER_OPT}"' >>${_TMP_CAT};
-    fi;
-  done;
-  eval . "${_TMP_CAT}";
-  _TMP_CAT="$(tmp_create groffer_cat)";
-
   eval ${_UNSET} mi_dir;
-  eval ${_UNSET} mi_file;
   eval ${_UNSET} mi_n;
   eval ${_UNSET} mi_tdir_;
   eval ${_UNSET} mi_tdir_n;
@@ -3518,7 +3719,6 @@
 } # main_init()
 
 
-landmark '14: main_parse_MANOPT()';
 ########################################################################
 # main_parse_MANOPT ()
 #
@@ -3535,21 +3735,25 @@
 main_parse_MANOPT()
 {
   func_check main_parse_MANOPT = 0 "$@";
-  mpm_list='';
-  if obj MANOPT is_not_empty;
+
+  if obj MANOPT is_not_empty
   then
-    MANOPT="$(echo x"${MANOPT}" | sed -e 's/^x'"${_SPACE}${_SPACE}"'*//')";
+    # Delete leading and final spaces
+    MANOPT="$(echo1 "${MANOPT}" | sed -e '
+s/^['"${_SP}${_TAB}"']*//
+s/['"${_SP}${_TAB}"']*$//
+')";
   fi;
-  if obj MANOPT is_empty;
+  if obj MANOPT is_empty
   then
-    eval ${_UNSET} mpm_list;
-    eval ${_UNSET} mpm_opt;
     eval "${return_ok}";
   fi;
+
+  mpm_list='';
   # add arguments in $MANOPT by mapping them to groffer options
   eval set x "$(list_from_cmdline _OPTS_MANOPT "${MANOPT}")";
   shift;
-  until test "$#" -le 0 || is_equal "$1" '--';
+  until test "$#" -le 0 || is_equal "$1" '--'
   do
     mpm_opt="$1";
     shift;
@@ -3565,7 +3769,7 @@
         shift;
         ;;
       -d|--debug)
-        list_append mpm_list '--debug';
+       do_nothing;
         ;;
       -D|--default)
         # undo all man options so far
@@ -3586,10 +3790,9 @@
       -k|--apropos)
        # groffer's --apropos takes an argument, but man's does not, so
         do_nothing;
-        shift;
         ;;
       -l|--local-file)
-        list_append mpm_list '--local-file';
+        do_nothing;
         ;;
       -L|--locale)
         list_append mpm_list '--locale' "$1";
@@ -3607,7 +3810,7 @@
         do_nothing;
         shift;
         ;;
-      -P|--pager|--tty-viewer)
+      -P|--pager)
         list_append mpm_list '--pager' "$1";
         shift;
         ;;
@@ -3638,27 +3841,27 @@
         list_append mpm_list '--location';
         ;;
       -Z|--ditroff)
-        list_append mpm_list '-Z' "$1";
-        shift;
+        do_nothing;
         ;;
       # ignore all other options
     esac;
   done;
-  # append the 2 lists in $mpm_list and $GROFFER_OPT to $GROFFER_OPT
-  if obj GROFFER_OPT is_empty;
+
+  # prepend $mpm_list to $GROFFER_OPT
+  if obj GROFFER_OPT is_empty
   then
     GROFFER_OPT="${mpm_list}";
-  elif obj mpm_list is_not_empty;
+  elif obj mpm_list is_not_empty
   then
     GROFFER_OPT="${mpm_list} ${GROFFER_OPT}";
   fi;
+
   eval ${_UNSET} mpm_list;
   eval ${_UNSET} mpm_opt;
   eval "${return_ok}";
 } # main_parse_MANOPT()
 
 
-landmark '15: main_parse_args()';
 ########################################################################
 # main_parse_args (<command_line_args>*)
 #
@@ -3669,16 +3872,20 @@
 #   in:  $_OPTS_*
 #   out: $_OPT_*, $_ADDOPTS, $_FILEARGS
 #
-#  Variable prefix: mpa
+# Variable prefix: mpa
 #
 main_parse_args()
 {
   func_check main_parse_args '>=' 0 "$@";
-
   eval set x "${GROFFER_OPT}" '"$@"';
   shift;
 
-  eval set x "$(list_from_cmdline _OPTS_CMDLINE "$@")";
+  _ALL_PARAMS="$(list_from_cmdline _OPTS_CMDLINE "$@")";
+  if obj _DEBUG_PRINT_PARAMS is_yes
+  then
+    echo2 "parameters: ${_ALL_PARAMS}";
+  fi;
+  eval set x "${_ALL_PARAMS}";
   shift;
 
   # By the call of `eval', unnecessary quoting was removed.  So the
@@ -3690,7 +3897,7 @@
   # Note, the existence of arguments to options has already been checked.
   # So a check for `$#' or `--' should not be done for arguments.
 
-  until test "$#" -le 0 || is_equal "$1" '--';
+  until test "$#" -le 0 || is_equal "$1" '--'
   do
     mpa_opt="$1";              # $mpa_opt is fed into the option handler
     shift;
@@ -3722,11 +3929,11 @@
         ;;
       -?)
         # delete leading `-'
-        mpa_optchar="$(echo x"${mpa_opt}" | sed -e 's/^x-//')";
-        if list_has _OPTS_GROFF_SHORT_NA "${mpa_optchar}";
+        mpa_optchar="$(echo1 "${mpa_opt}" | sed -e 's/^-//')";
+        if list_has _OPTS_GROFF_SHORT_NA "${mpa_optchar}"
         then
           list_append _ADDOPTS_GROFF "${mpa_opt}";
-        elif list_has _OPTS_GROFF_SHORT_ARG "${mpa_optchar}";
+        elif list_has _OPTS_GROFF_SHORT_ARG "${mpa_optchar}"
         then
           list_append _ADDOPTS_GROFF "${mpa_opt}" "$1";
           shift;
@@ -3739,31 +3946,23 @@
           ;;
       --apropos)               # run `apropos'
        apropos_run "$1";
-        mpa_code="$?";
-        clean_up;
-        exit "${mpa_code}";
+        leave "$?";
         ;;
       --apropos-data)          # run `apropos' for data sections
        apropos_run "$1" | grep '^[^(]*([457][^)]*)';
-        mpa_code="$?";
-        clean_up;
-        exit "${mpa_code}";
+        leave "$?";
         ;;
       --apropos-devel)         # run `apropos' for development sections
        apropos_run "$1" | grep '^[^(]*([239][^)]*)';
-        mpa_code="$?";
-        clean_up;
-        exit "${mpa_code}";
+        leave "$?";
         ;;
       --apropos-progs)         # run `apropos' for program sections
        apropos_run "$1" | grep '^[^(]*([168][^)]*)';
-        mpa_code="$?";
-        clean_up;
-        exit "${mpa_code}";
+        leave "$?";
         ;;
       --ascii)
         list_append _ADDOPTS_GROFF '-mtty-char';
-        if obj _OPT_MODE is_empty;
+        if obj _OPT_MODE is_empty
         then
          _OPT_MODE='text';
         fi;
@@ -3797,6 +3996,9 @@
         _OPT_DISPLAY="$1";
         shift;
         ;;
+      --do-nothing)
+        leave;
+        ;;
       --dvi)
         _OPT_MODE='dvi';
         ;;
@@ -3901,7 +4103,7 @@
         _MAN_FORCE="no";
         _MAN_ENABLE="no";
         ;;
-      --pager)                 # set paging program for tty mode, arg
+      --pager|--tty-viewer)    # set paging program for tty mode, arg
         _OPT_PAGER="$1";
         shift;
         ;;
@@ -3987,33 +4189,33 @@
     esac;
   done;
   shift;                       # remove `--' argument
-
-  if obj _DEBUG is_not_yes;
+  if obj _DEBUG is_not_yes
   then
-    if obj _OPT_DEBUG is_yes;
+    if obj _OPT_DEBUG is_yes
     then
       _DEBUG='yes';
       _DEBUG_LM='yes';
       _DEBUG_KEEP_FILES='yes';
+      _DEBUG_PRINT_PARAMS='yes';
+      _DEBUG_PRINT_SHELL='yes';
     fi;
   fi;
 
   # Remaining arguments are file names (filespecs).
   # Save them to list $_FILEARGS
-  if is_equal "$#" 0;
+  if is_equal "$#" 0
   then                         # use "-" for standard input
     set x '-';
     shift;
   fi;
   _FILEARGS='';
   list_append _FILEARGS "$@";
-  if list_has _FILEARGS '-';
+  if list_has _FILEARGS '-'
   then
     save_stdin;
   fi;
   # $_FILEARGS must be retrieved with `eval set x "$_FILEARGS"; shift;'
   eval ${_UNSET} mpa_arg;
-  eval ${_UNSET} mpa_code;
   eval ${_UNSET} mpa_dpi;
   eval ${_UNSET} mpa_opt;
   eval ${_UNSET} mpa_optchar;
@@ -4044,7 +4246,7 @@
       eval "${return_ok}";
       ;;
     ascii|cp1047|latin1|utf8)
-      if obj _OPT_MODE is_not_equal text;
+      if obj _OPT_MODE is_not_equal text
       then
         _OPT_MODE=tty;         # default text mode
       fi;
@@ -4063,7 +4265,6 @@
 } # _check_device_with_mode() of main_parse_args()
 
 
-landmark '16: main_set_mode()';
 ########################################################################
 # main_set_mode ()
 #
@@ -4080,67 +4281,57 @@
   func_check main_set_mode = 0 "$@";
 
   # handle apropos
-  if obj _OPT_APROPOS is_not_empty;
+  if obj _OPT_APROPOS is_not_empty
   then
     apropos "${_OPT_APROPOS}";
-    msm_code="$?";
-    clean_up;
-    exit "${msm_code}";
+    leave "$?";
   fi;
-  if obj _OPT_APROPOS_DATA is_not_empty;
+  if obj _OPT_APROPOS_DATA is_not_empty
   then
     apropos "$@" | grep '^[^(]*([457])';
-    msm_code="$?";
-    clean_up;
-    exit "${msm_code}";
+    leave "$?";
   fi;
-  if obj _OPT_APROPOS_DEVEL is_not_empty;
+  if obj _OPT_APROPOS_DEVEL is_not_empty
   then
     apropos "$@" | grep '^[^(]*([239])';
-    msm_code="$?";
-    clean_up;
-    exit "${msm_code}";
+    leave "$?";
   fi;
-  if obj _OPT_APROPOS_PROGS is_not_empty;
+  if obj _OPT_APROPOS_PROGS is_not_empty
   then
     apropos "$@" | grep '^[^(]*([168])';
-    msm_code="$?";
-    clean_up;
-    exit "${msm_code}";
+    leave "$?";
   fi;
 
   # set display
-  if obj _OPT_DISPLAY is_not_empty;
+  if obj _OPT_DISPLAY is_not_empty
   then
     DISPLAY="${_OPT_DISPLAY}";
   fi;
 
-  if obj _OPT_V is_yes;
+  if obj _OPT_V is_yes
   then
     list_append _ADDOPTS_GROFF '-V';
   fi;
-  if obj _OPT_Z is_yes;
+  if obj _OPT_Z is_yes
   then
     _DISPLAY_MODE='groff';
     list_append _ADDOPTS_GROFF '-Z';
   fi;
-  if obj _OPT_MODE is_equal 'groff';
+  if obj _OPT_MODE is_equal 'groff'
   then
     _DISPLAY_MODE='groff';
   fi;
-  if obj _DISPLAY_MODE is_equal 'groff';
+  if obj _DISPLAY_MODE is_equal 'groff'
   then
-    eval ${_UNSET} msm_code;
     eval ${_UNSET} msm_modes;
     eval ${_UNSET} msm_viewer;
     eval ${_UNSET} msm_viewers;
     eval "${return_ok}";
   fi;
 
-  if obj _OPT_MODE is_equal 'source';
+  if obj _OPT_MODE is_equal 'source'
   then
     _DISPLAY_MODE='source';
-    eval ${_UNSET} msm_code;
     eval ${_UNSET} msm_modes;
     eval ${_UNSET} msm_viewer;
     eval ${_UNSET} msm_viewers;
@@ -4151,41 +4342,38 @@
     '')                                # automatic mode
       case "${_OPT_DEVICE}" in
         X*)
-          if obj DISPLAY is_empty;
+          if obj DISPLAY is_empty
           then
             error "main_set_mode(): \
 no X display found for device ${_OPT_DEVICE}";
           fi;
           _DISPLAY_MODE='x';
-          eval ${_UNSET} msm_code;
           eval ${_UNSET} msm_modes;
           eval ${_UNSET} msm_viewer;
           eval ${_UNSET} msm_viewers;
           eval "${return_ok}";
           ;;
         ascii|cp1047|latin1|utf8)
-          if obj _DISPLAY_MODE is_not_equal 'text';
+          if obj _DISPLAY_MODE is_not_equal 'text'
           then
             _DISPLAY_MODE='tty';
           fi;
-          eval ${_UNSET} msm_code;
           eval ${_UNSET} msm_modes;
           eval ${_UNSET} msm_viewer;
           eval ${_UNSET} msm_viewers;
           eval "${return_ok}";
           ;;
       esac;
-      if obj DISPLAY is_empty;
+      if obj DISPLAY is_empty
       then
         _DISPLAY_MODE='tty';
-        eval ${_UNSET} msm_code;
         eval ${_UNSET} msm_modes;
         eval ${_UNSET} msm_viewer;
         eval ${_UNSET} msm_viewers;
         eval "${return_ok}";
       fi;
 
-      if obj _OPT_DEFAULT_MODES is_empty;
+      if obj _OPT_DEFAULT_MODES is_empty
       then
         msm_modes="${_DEFAULT_MODES}";
       else
@@ -4194,7 +4382,6 @@
       ;;
     text)
       _DISPLAY_MODE='text';
-      eval ${_UNSET} msm_code;
       eval ${_UNSET} msm_modes;
       eval ${_UNSET} msm_viewer;
       eval ${_UNSET} msm_viewers;
@@ -4202,14 +4389,13 @@
       ;;
     tty)
       _DISPLAY_MODE='tty';
-      eval ${_UNSET} msm_code;
       eval ${_UNSET} msm_modes;
       eval ${_UNSET} msm_viewer;
       eval ${_UNSET} msm_viewers;
       eval "${return_ok}";
       ;;
     *)                         # display mode was given
-      if obj DISPLAY is_empty;
+      if obj DISPLAY is_empty
       then
         error "main_set_mode(): \
 you must be in X Window for ${_OPT_MODE} mode.";
@@ -4221,14 +4407,13 @@
   # only viewer modes are left
   eval set x "$(list_from_split "${msm_modes}" ',')";
   shift;
-  while test "$#" -gt 0;
+  while test "$#" -gt 0
   do
     m="$1";
     shift;
     case "$m" in
       text)
         _DISPLAY_MODE='text';
-        eval ${_UNSET} msm_code;
         eval ${_UNSET} msm_modes;
         eval ${_UNSET} msm_viewer;
         eval ${_UNSET} msm_viewers;
@@ -4236,27 +4421,25 @@
         ;;
       tty)
         _DISPLAY_MODE='tty';
-        eval ${_UNSET} msm_code;
         eval ${_UNSET} msm_modes;
         eval ${_UNSET} msm_viewer;
         eval ${_UNSET} msm_viewers;
         eval "${return_ok}";
         ;;
       x)
-        if obj _OPT_VIEWER_X is_not_empty;
+        if obj _OPT_VIEWER_X is_not_empty
         then
           msm_viewers="${_OPT_VIEWER_X}";
         else
           msm_viewers="${_VIEWER_X}";
         fi;
         msm_viewer="$(_get_first_prog "${msm_viewers}")";
-        if is_not_equal "$?" 0;
+        if is_not_equal "$?" 0
         then
           continue;
         fi;
         _DISPLAY_PROG="${msm_viewer}";
         _DISPLAY_MODE='x';
-        eval ${_UNSET} msm_code;
         eval ${_UNSET} msm_modes;
         eval ${_UNSET} msm_viewer;
         eval ${_UNSET} msm_viewers;
@@ -4264,87 +4447,82 @@
         ;;
       X)
         _DISPLAY_MODE='X';
-        eval ${_UNSET} msm_code;
         eval ${_UNSET} msm_modes;
         eval ${_UNSET} msm_viewer;
         eval ${_UNSET} msm_viewers;
         eval "${return_ok}";
         ;;
       dvi)
-        if obj _OPT_VIEWER_DVI is_not_empty;
+        if obj _OPT_VIEWER_DVI is_not_empty
         then
           msm_viewers="${_OPT_VIEWER_DVI}";
         else
           msm_viewers="${_VIEWER_DVI}";
         fi;
         msm_viewer="$(_get_first_prog "${msm_viewers}")";
-        if is_not_equal "$?" 0;
+        if is_not_equal "$?" 0
         then
           continue;
         fi;
         _DISPLAY_PROG="${msm_viewer}";
         _DISPLAY_MODE="dvi";
-        eval ${_UNSET} msm_code;
         eval ${_UNSET} msm_modes;
         eval ${_UNSET} msm_viewer;
         eval ${_UNSET} msm_viewers;
         eval "${return_ok}";
         ;;
       pdf)
-        if obj _OPT_VIEWER_PDF is_not_empty;
+        if obj _OPT_VIEWER_PDF is_not_empty
         then
           msm_viewers="${_OPT_VIEWER_PDF}";
         else
           msm_viewers="${_VIEWER_PDF}";
         fi;
         msm_viewer="$(_get_first_prog "${msm_viewers}")";
-        if is_not_equal "$?" 0;
+        if is_not_equal "$?" 0
         then
           continue;
         fi;
         _DISPLAY_PROG="${msm_viewer}";
         _DISPLAY_MODE="pdf";
-        eval ${_UNSET} msm_code;
         eval ${_UNSET} msm_modes;
         eval ${_UNSET} msm_viewer;
         eval ${_UNSET} msm_viewers;
         eval "${return_ok}";
         ;;
       ps)
-        if obj _OPT_VIEWER_PS is_not_empty;
+        if obj _OPT_VIEWER_PS is_not_empty
         then
           msm_viewers="${_OPT_VIEWER_PS}";
         else
           msm_viewers="${_VIEWER_PS}";
         fi;
         msm_viewer="$(_get_first_prog "${msm_viewers}")";
-        if is_not_equal "$?" 0;
+        if is_not_equal "$?" 0
         then
           continue;
         fi;
         _DISPLAY_PROG="${msm_viewer}";
         _DISPLAY_MODE="ps";
-        eval ${_UNSET} msm_code;
         eval ${_UNSET} msm_modes;
         eval ${_UNSET} msm_viewer;
         eval ${_UNSET} msm_viewers;
         eval "${return_ok}";
         ;;
       html)
-        if obj _OPT_VIEWER_HTML is_not_empty;
+        if obj _OPT_VIEWER_HTML is_not_empty
         then
           msm_viewers="${_OPT_VIEWER_HTML}";
         else
           msm_viewers="${_VIEWER_HTML}";
         fi;
         msm_viewer="$(_get_first_prog "${msm_viewers}")";
-        if is_not_equal "$?" 0;
+        if is_not_equal "$?" 0
         then
           continue;
         fi;
         _DISPLAY_PROG="${msm_viewer}";
         _DISPLAY_MODE=html;
-        eval ${_UNSET} msm_code;
         eval ${_UNSET} msm_modes;
         eval ${_UNSET} msm_viewer;
         eval ${_UNSET} msm_viewers;
@@ -4352,7 +4530,6 @@
         ;;
     esac;
   done;
-  eval ${_UNSET} msm_code;
   eval ${_UNSET} msm_modes;
   eval ${_UNSET} msm_viewer;
   eval ${_UNSET} msm_viewers;
@@ -4375,11 +4552,11 @@
 #
 _get_first_prog()
 {
-  if is_equal "$#" 0;
+  if is_equal "$#" 0
   then
     error "_get_first_prog() needs 1 argument.";
   fi;
-  if is_empty "$1";
+  if is_empty "$1"
   then
     return "${_BAD}";
   fi;
@@ -4388,15 +4565,13 @@
   for i
   do
     _gfp_i="$i";
-    if obj _gfp_i is_empty;
+    if obj _gfp_i is_empty
     then
       continue;
     fi;
-    if eval is_prog "$(get_first_essential ${_gfp_i})";
+    if eval is_prog "$(get_first_essential ${_gfp_i})"
     then
-      cat <<EOF
-${_gfp_i}
-EOF
+      obj _gfp_i echo1;
       eval ${_UNSET} _gfp_i;
       return "${_GOOD}";
     fi;
@@ -4406,7 +4581,6 @@
 } # _get_first_prog() of main_set_mode()
 
 
-landmark '17: main_do_fileargs()';
 #######################################################################
 # main_do_fileargs ()
 #
@@ -4425,7 +4599,7 @@
   shift;
   eval ${_UNSET} _FILEARGS;
   # temporary storage of all input to $_TMP_CAT
-  while test "$#" -ge 2;
+  while test "$#" -ge 2
   do
     # test for `s name' arguments, with `s' a 1-char standard section
     mdfa_filespec="$1";
@@ -4435,16 +4609,16 @@
         continue;
         ;;
       '-')
-        if register_file '-';
+        if register_file '-'
         then
           mdfa_exitcode="${_GOOD}";
         fi;
         continue;
         ;;
       ?)
-        if list_has_not _MAN_AUTO_SEC "${mdfa_filespec}";
+        if list_has_not _MAN_AUTO_SEC "${mdfa_filespec}"
         then
-          if do_filearg "${mdfa_filespec}";
+          if do_filearg "${mdfa_filespec}"
           then
             mdfa_exitcode="${_GOOD}";
           fi;
@@ -4453,20 +4627,20 @@
         mdfa_name="$1";
         case "${mdfa_name}" in
           */*|man:*|*\(*\)|*."${mdfa_filespec}")
-            if do_filearg "${mdfa_filespec}";
+            if do_filearg "${mdfa_filespec}"
             then
               mdfa_exitcode="${_GOOD}";
             fi;
             continue;
             ;;
         esac;
-        if do_filearg "man:${mdfa_name}(${mdfa_filespec})";
+        if do_filearg "man:${mdfa_name}(${mdfa_filespec})"
         then
           mdfa_exitcode="${_GOOD}";
           shift;
           continue;
         else
-          if do_filearg "${mdfa_filespec}";
+          if do_filearg "${mdfa_filespec}"
           then
             mdfa_exitcode="${_GOOD}";
           fi;
@@ -4474,7 +4648,7 @@
         fi;
         ;;
       *)
-        if do_filearg "${mdfa_filespec}";
+        if do_filearg "${mdfa_filespec}"
         then
           mdfa_exitcode="${_GOOD}";
         fi;
@@ -4482,20 +4656,17 @@
         ;;
     esac;
   done;                                # end of `s name' test
-  while test "$#" -gt 0;
+  while test "$#" -gt 0
   do
     mdfa_filespec="$1";
     shift;
-    if do_filearg "${mdfa_filespec}";
+    if do_filearg "${mdfa_filespec}"
     then
       mdfa_exitcode="${_GOOD}";
     fi;
   done;
-  if obj _DEBUG_KEEP_FILES is_not_yes;
-  then
-    rm -f "${_TMP_STDIN}";
-  fi;
-  if is_equal "${mdfa_exitcode}" "${_BAD}";
+  obj _TMP_STDIN rm_file_with_debug;
+  if is_equal "${mdfa_exitcode}" "${_BAD}"
   then
     eval ${_UNSET} mdfa_exitcode;
     eval ${_UNSET} mdfa_filespec;
@@ -4509,7 +4680,6 @@
 } # main_do_fileargs()
 
 
-landmark '18: main_set_resources()';
 ########################################################################
 # main_set_resources ()
 #
@@ -4529,7 +4699,7 @@
   _OUTPUT_FILE_NAME='';
   eval set x "${msr_title}";
   shift;
-  until is_equal "$#" 0;
+  until is_equal "$#" 0
   do
     msr_n="$1";
     case "${msr_n}" in
@@ -4537,14 +4707,14 @@
       continue;
       ;;
     ,*)
-      msr_n="$(echo x"$1" | sed -e 's/^x,,*//')";
+      msr_n="$(echo1 "$1" | sed -e 's/^,,*//')";
       ;;
     esac
-    if obj msr_n is_empty;
+    if obj msr_n is_empty
     then
       continue;
     fi;
-    if obj _OUTPUT_FILE_NAME is_not_empty;
+    if obj _OUTPUT_FILE_NAME is_not_empty
     then
       _OUTPUT_FILE_NAME="${_OUTPUT_FILE_NAME}"',';
     fi;
@@ -4561,7 +4731,7 @@
   esac;
   _OUTPUT_FILE_NAME="${_TMP_DIR}/${_OUTPUT_FILE_NAME}";
 
-  if obj _DISPLAY_PROG is_empty;
+  if obj _DISPLAY_PROG is_empty
   then                         # for example, for groff mode
     _DISPLAY_ARGS='';
     eval ${_UNSET} msr_n;
@@ -4574,130 +4744,152 @@
   eval set x "${_DISPLAY_PROG}";
   shift;
   msr_prog="$(base_name "$1")";
+  shift;
+  if test $# != 0
+  then
+    if obj _DISPLAY_PROG is_empty
+    then
+      _DISPLAY_ARGS="$*";
+    else
+      _DISPLAY_ARGS="$* ${_DISPLAY_ARGS}";
+    fi;
+  fi;
   msr_rl='';
-  if obj _OPT_BD is_not_empty;
+  if obj _OPT_BD is_not_empty
   then
     case "${msr_prog}" in
-      ghostview|gv|gxditview|xditview|xdvi)
-        list_append msr_rl '-bd' "${_OPT_BD}";
-        ;;
+    ghostview|gv|gxditview|xditview|xdvi)
+      list_append msr_rl '-bd' "${_OPT_BD}";
+      ;;
     esac;
   fi;
-  if obj _OPT_BG is_not_empty;
+  if obj _OPT_BG is_not_empty
   then
     case "${msr_prog}" in
-      ghostview|gv|gxditview|xditview|xdvi)
-        list_append msr_rl '-bg' "${_OPT_BG}";
-        ;;
-      xpdf)
-        list_append msr_rl '-papercolor' "${_OPT_BG}";
-        ;;
+    ghostview|gv|gxditview|xditview|xdvi)
+      list_append msr_rl '-bg' "${_OPT_BG}";
+      ;;
+    kghostview)
+      list_append msr_rl '--bg' "${_OPT_BG}";
+      ;;
+    xpdf)
+      list_append msr_rl '-papercolor' "${_OPT_BG}";
+      ;;
     esac;
   fi;
-  if obj _OPT_BW is_not_empty;
+  if obj _OPT_BW is_not_empty
   then
     case "${msr_prog}" in
-      ghostview|gv|gxditview|xditview|xdvi)
-        _list_append msr_rl '-bw' "${_OPT_BW}";
-        ;;
+    ghostview|gv|gxditview|xditview|xdvi)
+      _list_append msr_rl '-bw' "${_OPT_BW}";
+      ;;
     esac;
   fi;
-  if obj _OPT_FG is_not_empty;
+  if obj _OPT_FG is_not_empty
   then
     case "${msr_prog}" in
-      ghostview|gv|gxditview|xditview|xdvi)
-        list_append msr_rl '-fg' "${_OPT_FG}";
-        ;;
+    ghostview|gv|gxditview|xditview|xdvi)
+      list_append msr_rl '-fg' "${_OPT_FG}";
+      ;;
+    kghostview)
+      list_append msr_rl '--fg' "${_OPT_FG}";
+      ;;
     esac;
   fi;
-  if is_not_empty "${_OPT_FN}";
+  if is_not_empty "${_OPT_FN}"
   then
     case "${msr_prog}" in
-      ghostview|gv|gxditview|xditview|xdvi)
-        list_append msr_rl '-fn' "${_OPT_FN}";
-        ;;
+    ghostview|gv|gxditview|xditview|xdvi)
+      list_append msr_rl '-fn' "${_OPT_FN}";
+      ;;
+    kghostview)
+      list_append msr_rl '--fn' "${_OPT_FN}";
+      ;;
     esac;
   fi;
-  if is_not_empty "${_OPT_GEOMETRY}";
+  if is_not_empty "${_OPT_GEOMETRY}"
   then
     case "${msr_prog}" in
-      ghostview|gv|gxditview|xditview|xdvi|xpdf)
-        list_append msr_rl '-geometry' "${_OPT_GEOMETRY}";
-        ;;
+    ghostview|gv|gxditview|xditview|xdvi|xpdf)
+      list_append msr_rl '-geometry' "${_OPT_GEOMETRY}";
+      ;;
+    kghostview)
+      list_append msr_rl '--geometry' "${_OPT_GEOMETRY}";
+      ;;
     esac;
   fi;
-  if is_empty "${_OPT_RESOLUTION}";
+  if is_empty "${_OPT_RESOLUTION}"
   then
     _OPT_RESOLUTION="${_DEFAULT_RESOLUTION}";
     case "${msr_prog}" in
-      gxditview|xditview)
-        list_append msr_rl '-resolution' "${_DEFAULT_RESOLUTION}";
+    gxditview|xditview)
+      list_append msr_rl '-resolution' "${_DEFAULT_RESOLUTION}";
+      ;;
+    xpdf)
+      case "${_DEFAULT_RESOLUTION}" in
+      75)
+        # 72dpi is '100'
+        list_append msr_rl '-z' '104';
         ;;
-      xpdf)
-        case "${_DEFAULT_RESOLUTION}" in
-          75)
-            # 72dpi is '100'
-            list_append msr_rl '-z' '104';
-            ;;
-          100)
-            list_append msr_rl '-z' '139';
-            ;;
-        esac;
+      100)
+        list_append msr_rl '-z' '139';
         ;;
+      esac;
+      ;;
     esac;
   else
     case "${msr_prog}" in
-      ghostview|gv|gxditview|xditview|xdvi)
-        list_append msr_rl '-resolution' "${_OPT_RESOLUTION}";
+    ghostview|gv|gxditview|xditview|xdvi)
+      list_append msr_rl '-resolution' "${_OPT_RESOLUTION}";
+      ;;
+    xpdf)
+      case "${_OPT_RESOLUTION}" in
+      75)
+        list_append msr_rl '-z' '104';
+        # '100' corresponds to 72dpi
         ;;
-      xpdf)
-        case "${_OPT_RESOLUTION}" in
-          75)
-            list_append msr_rl '-z' '104';
-            # '100' corresponds to 72dpi
-            ;;
-          100)
-            list_append msr_rl '-z' '139';
-            ;;
-        esac;
+      100)
+        list_append msr_rl '-z' '139';
         ;;
+      esac;
+      ;;
     esac;
   fi;
-  if is_yes "${_OPT_ICONIC}";
+  if is_yes "${_OPT_ICONIC}"
   then
     case "${msr_prog}" in
-      ghostview|gv|gxditview|xditview|xdvi)
-        list_append msr_rl '-iconic';
-        ;;
+    ghostview|gv|gxditview|xditview|xdvi)
+      list_append msr_rl '-iconic';
+      ;;
     esac;
   fi;
-  if is_yes "${_OPT_RV}";
+  if is_yes "${_OPT_RV}"
   then
     case "${msr_prog}" in
-      ghostview|gv|gxditview|xditview|xdvi)
-        list_append msr_rl '-rv';
-        ;;
+    ghostview|gv|gxditview|xditview|xdvi)
+      list_append msr_rl '-rv';
+      ;;
     esac;
   fi;
-  if is_not_empty "${_OPT_XRM}";
+  if is_not_empty "${_OPT_XRM}"
   then
     case "${msr_prog}" in
-      ghostview|gv|gxditview|xditview|xdvi|xpdf)
-        eval set x "${_OPT_XRM}";
-        shift;
-        for i
-        do
-          list_append msr_rl '-xrm' "$i";
-        done;
-        ;;
+    ghostview|gv|gxditview|xditview|xdvi|xpdf)
+      eval set x "${_OPT_XRM}";
+      shift;
+      for i
+      do
+        list_append msr_rl '-xrm' "$i";
+      done;
+      ;;
     esac;
   fi;
-  if is_not_empty "${msr_title}";
+  if is_not_empty "${msr_title}"
   then
     case "${msr_prog}" in
-      gxditview|xditview)
-        list_append msr_rl '-title' "${msr_title}";
-        ;;
+    gxditview|xditview)
+      list_append msr_rl '-title' "${msr_title}";
+      ;;
     esac;
   fi;
   _DISPLAY_ARGS="${msr_rl}";
@@ -4709,7 +4901,6 @@
 } # main_set_resources
 
 
-landmark '19: main_display()';
 ########################################################################
 # main_display ()
 #
@@ -4732,50 +4923,38 @@
   export md_groggy;
   export md_modefile;
 
-  if obj _TMP_CAT is_non_empty_file;
+  if obj _TMP_CAT is_non_empty_file
   then
     md_modefile="${_OUTPUT_FILE_NAME}";
   else
-    clean_up;
     echo2 'groffer: empty input.';
+    clean_up;
     eval ${_UNSET} md_modefile;
     eval "${return_ok}";
   fi;
+
+  # go to the temporary directory to be able to access internal data files
+  cd "${_TMP_DIR}" >"${_NULL_DEV}" 2>&1;
+
   case "${_DISPLAY_MODE}" in
     groff)
       _ADDOPTS_GROFF="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
-      if obj _OPT_DEVICE is_not_empty;
+      if obj _OPT_DEVICE is_not_empty
       then
         _ADDOPTS_GROFF="${_ADDOPTS_GROFF} -T${_OPT_DEVICE}";
       fi;
       md_groggy="$(tmp_cat | eval grog "${md_options}")";
       trap_clean;
-      if obj _OPT_V is_yes;
-      then
-        echo "File:            ${md_modefile}";
-        echo "Mode:            ${_DISPLAY_MODE}";
-        echo "Display program: ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
+      _do_opt_V;
+
+      obj md_modefile rm_file;
+      mv "${_TMP_CAT}" "${md_modefile}";
+      cat "${md_modefile}" | \
+      {
+        trap clean_up 0 2>${_NULL_DEV} || :;
         eval "${md_groggy}" "${_ADDOPTS_GROFF}";
         clean_up;
-      else
-        # start a new shell program to get another process ID.
-        /bin/sh -c '
-          set -e;
-          test -f "${md_modefile}" && rm -f "${md_modefile}";
-          mv "${_TMP_CAT}" "${md_modefile}";
-          cat "${md_modefile}" | \
-          (
-            clean_up()
-            {
-              if test -d "${_TMP_DIR}";
-              then
-                rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1 || :;
-              fi;
-            }
-            trap clean_up 0 2>${_NULL_DEV} || :;
-            eval "${md_groggy}" "${_ADDOPTS_GROFF}";
-          ) &'
-      fi;
+      } &
       ;;
     text|tty)
       case "${_OPT_DEVICE}" in
@@ -4793,43 +4972,29 @@
       esac;
       md_addopts="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
       md_groggy="$(tmp_cat | grog -T${md_device})";
-      if obj _DISPLAY_MODE is_equal 'text';
+      if obj _DISPLAY_MODE is_equal 'text'
       then
-        if obj _OPT_V is_yes;
-        then
-          echo "File:            ${md_modefile}";
-          echo "Mode:            ${_DISPLAY_MODE}";
-          echo "Display program: ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
-          eval "${md_groggy}" "${md_addopts}";
-        else
-          tmp_cat | eval "${md_groggy}" "${md_addopts}";
-        fi;
+        _do_opt_V;
+        tmp_cat | eval "${md_groggy}" "${md_addopts}";
       else
         md_pager='';
         for p in "${_OPT_PAGER}" "${PAGER}" "${_MANOPT_PAGER}" \
                  'less -r -R' 'more' 'pager' 'cat'
         do
           md_p="$p";
-          if eval is_prog ${md_p};
+          if eval is_prog ${md_p}
           then               # no "" for is_prog() allows args for $p
             md_pager="${md_p}";
             break;
           fi;
         done;
-        if obj md_pager is_empty;
+        if obj md_pager is_empty
         then
           error 'main_display(): no pager program found for tty mode';
         fi;
-        if obj _OPT_V is_yes;
-        then
-          echo "File:            ${md_modefile}";
-          echo "Mode:            ${_DISPLAY_MODE}";
-          echo "Display program: ${md_pager}";
-          eval "${md_groggy}" "${md_addopts}";
-        else
-          tmp_cat | eval "${md_groggy}" "${md_addopts}" | \
-                    eval "${md_pager}";
-        fi;
+        _do_opt_V;
+        tmp_cat | eval "${md_groggy}" "${md_addopts}" | \
+                  eval "${md_pager}";
       fi;
       clean_up;
       ;;
@@ -4875,42 +5040,7 @@
           ;;
       esac;
       md_groggy="$(tmp_cat | grog -Tps)";
-      trap_clean;
-      if obj _OPT_V is_yes;
-      then
-        echo "File:            ${md_modefile}.pdf";
-        echo "Mode:            ${_DISPLAY_MODE}";
-        echo "Display program: ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
-        eval "${md_groggy}" "${_ADDOPTS_GROFF}";
-        clean_up;
-      else
-        # start a new shell program to get another process ID.
-        /bin/sh -c '
-          set -e;
-          _psfile="${md_modefile}.ps";
-          md_modefile="${md_modefile}.pdf";
-          test -f "${_psfile}" && rm -f "${_psfile}";
-          test -f "${md_modefile}" && rm -f "${md_modefile}";
-          cat "${_TMP_CAT}" | \
-            eval "${md_groggy}" "${_ADDOPTS_GROFF}" > "${_psfile}";
-          gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
-             -sOutputFile="${md_modefile}" -c save pop -f "${_psfile}";
-          if test _"${_DEBUG_KEEP_FILES}"_ != _yes_;
-          then
-            test -f "${_psfile}" && rm -f "${_psfile}";
-            test -f "${_TMP_CAT}" && rm -f "${_TMP_CAT}";
-          fi;
-          (
-            clean_up() {
-              if test -d "${_TMP_DIR}";
-              then
-                rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1 || :;
-              fi;
-            }
-            trap clean_up 0 2>${_NULL_DEV} || :;
-            eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "${md_modefile}";
-          ) &'
-      fi;
+      _do_display _make_pdf;
       ;;
     ps)
       case "${_OPT_DEVICE}" in
@@ -4985,45 +5115,99 @@
 } # main_display()
 
 
-# $md_modefile and $md_groggy come from main_display()
+########################
+# _do_display ([<prog>])
+#
+# Perform the generation of the output and view the result.  If an
+# argument is given interpret it as a function name that is called in
+# the midst.
+#
+# Globals: $md_modefile, $md_groggy (from main_display())
+#
 _do_display()
 {
-  func_check _do_display = 0 "$@";
+  func_check _do_display '>=' 0 "$@";
   trap_clean;
-  if obj _OPT_V is_yes;
+  _do_opt_V;
+  obj md_modefile rm_file;
+  if cat "${_TMP_CAT}" | \
+     eval "${md_groggy}" "${_ADDOPTS_GROFF}" > "${md_modefile}"
   then
-    echo "File:            ${md_modefile}";
-    echo "Mode:            ${_DISPLAY_MODE}";
-    echo "Display program: ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
-    eval "${md_groggy}" "${_ADDOPTS_GROFF}";
-    clean_up;
+    :;
   else
-    # start a new shell program for another process ID and better
-    # cleaning-up of the temporary files.
-    /bin/sh -c '
-      set -e;
-      test -f "${md_modefile}" && rm -f "${md_modefile}";
-      cat "${_TMP_CAT}" | \
-        eval "${md_groggy}" "${_ADDOPTS_GROFF}" > "${md_modefile}";
-      if test _"${_DEBUG_KEEP_FILES}"_ != _yes_;
-      then
-        rm -f "${_TMP_CAT}";
-      fi;
-      (
-        clean_up() {
-          if test -d "${_TMP_DIR}";
-          then
-            rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1 || :;
-          fi;
-        }
-        trap clean_up 0 2>${_NULL_DEV} || :;
-        eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "${md_modefile}";
-      ) &'
+    error "_do_display: error on groff call";
+  fi;
+  if is_not_empty "$1"
+  then
+    eval "$1";
   fi;
+  obj _TMP_CAT rm_file_with_debug;
+  {
+    trap clean_up 0 2>${_NULL_DEV} || :;
+    eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
+    clean_up;
+  } &
   eval "${return_ok}";
 } # _do_display() of main_display()
 
 
+#############
+# _do_opt_V ()
+#
+# Check on option `-V'; if set print the corresponding output and leave.
+#
+# Globals: $_ALL_PARAMS, $_ADDOPTS_GROFF, $_DISPLAY_MODE, $_DISPLAY_PROG,
+#          $_DISPLAY_ARGS, $md_groggy,  $md_modefile
+#
+# Variable prefix: _doV
+#
+_do_opt_V()
+{
+  func_check _do_opt_V '=' 0 "$@";
+  if obj _OPT_V is_yes
+  then
+    _OPT_V='no';
+    echo "Output file:    ${md_modefile}";
+    echo "Display mode:   ${_DISPLAY_MODE}";
+    echo "Display prog:   ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
+    echo "Parameters:     ${_ALL_PARAMS}";
+    echo "Output of grog: ${md_groggy} $(eval echo1 "'${_ADDOPTS_GROFF}'")";
+    _doV_res="$(eval "${md_groggy}" "${_ADDOPTS_GROFF}")";
+    echo "groff -V:       ${_doV_res}"
+    leave;
+  fi;
+  eval "${return_ok}";
+} # _do_opt_V() of main_display()
+
+
+##############
+# _make_pdf ()
+#
+# Transform to pdf format; for pdf mode in _do_display().
+#
+# Globals: $md_modefile (from main_display())
+# 
+# Variable prefix: _mp
+#
+_make_pdf()
+{
+  func_check _do_display '=' 0 "$@";
+  _mp_psfile="${md_modefile}";
+  md_modefile="${md_modefile}.pdf";
+  obj md_modefile rm_file;
+  if gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
+        -sOutputFile="${md_modefile}" -c save pop -f "${_mp_psfile}"
+  then
+    :;
+  else
+    error '_make_pdf: could not transform into pdf format.';
+  fi;
+  obj _mp_psfile rm_file_with_debug;
+  eval ${_UNSET} _mp_psfile;
+  eval "${return_ok}";
+} # _make_pdf() of main_display()
+
+
 ########################################################################
 # main (<command_line_args>*)
 #
@@ -5035,12 +5219,19 @@
 {
   func_check main '>=' 0 "$@";
   # Do not change the sequence of the following functions!
+  landmark '13: main_init()';
   main_init;
+  landmark '14: main_parse_MANOPT()';
   main_parse_MANOPT;
+  landmark '15: main_parse_args()';
   main_parse_args "$@";
+  landmark '16: main_set_mode()';
   main_set_mode;
+  landmark '17: main_do_fileargs()';
   main_do_fileargs;
+  landmark '18: main_set_resources()';
   main_set_resources;
+  landmark '19: main_display()';
   main_display;
   eval "${return_ok}";
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]