diff options
author | wl <wl> | 2005-08-03 06:32:11 +0000 |
---|---|---|
committer | wl <wl> | 2005-08-03 06:32:11 +0000 |
commit | e23c8e3f050bc1655dfff6f776e806996133dc27 (patch) | |
tree | 20b2778fd7f83835f8766904dbd181ff5ee22bc4 /contrib/groffer | |
parent | 2e3ebdab4dfa59a9197ebad1f68258c32ec31af8 (diff) | |
download | groff-e23c8e3f050bc1655dfff6f776e806996133dc27.tar.gz |
* 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.
Diffstat (limited to 'contrib/groffer')
-rw-r--r-- | contrib/groffer/ChangeLog | 336 | ||||
-rw-r--r-- | contrib/groffer/Makefile.sub | 25 | ||||
-rw-r--r-- | contrib/groffer/README | 42 | ||||
-rw-r--r-- | contrib/groffer/README_SH | 49 | ||||
-rw-r--r-- | contrib/groffer/TODO | 33 | ||||
-rw-r--r-- | contrib/groffer/groffer.man | 817 | ||||
-rw-r--r-- | contrib/groffer/groffer.sh | 379 | ||||
-rw-r--r-- | contrib/groffer/groffer2.sh | 1799 |
8 files changed, 2061 insertions, 1419 deletions
diff --git a/contrib/groffer/ChangeLog b/contrib/groffer/ChangeLog index 0fd2106c..c549f81d 100644 --- a/contrib/groffer/ChangeLog +++ b/contrib/groffer/ChangeLog @@ -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 <wl@gnu.org> * groffer.sh: Implement man option `--ascii' by `-mtty-char'. - + 2002-05-31 Werner LEMBERG <wl@gnu.org> @@ -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. diff --git a/contrib/groffer/Makefile.sub b/contrib/groffer/Makefile.sub index a546ea4f..6559da7c 100644 --- a/contrib/groffer/Makefile.sub +++ b/contrib/groffer/Makefile.sub @@ -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 <wl@gnu.org> 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 @@ install_data: groffer -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 diff --git a/contrib/groffer/README b/contrib/groffer/README index 36308d95..66d36123 100644 --- a/contrib/groffer/README +++ b/contrib/groffer/README @@ -34,7 +34,7 @@ appropriate. 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 @@ The following displaying modes for the output are available: - 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 @@ is tried by default. 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 -<bug-groff@gnu.org> can be used. For a general discussion, the -mailing list <groff@gnu.org> 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. +<bug-groff@gnu.org> can be used. + +For a general discussion, the mailing list <groff@gnu.org> 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. diff --git a/contrib/groffer/README_SH b/contrib/groffer/README_SH index 4f1249aa..3dd52081 100644 --- a/contrib/groffer/README_SH +++ b/contrib/groffer/README_SH @@ -4,15 +4,20 @@ Additional description for the shell version of `groffer' 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 -@libdir@/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 @@ name. These quasi-local variables are unset before each return of the 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 @@ documentation `Portable shells' in the `info' page of `autoconf' ${_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 @@ break bzip2 -c -d -t cat catz +cd continue echo eval @@ -109,6 +121,7 @@ ls man -k --apropos mkdir mv +pwd return rm -f -r rmdir @@ -116,7 +129,7 @@ sed -e -n 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 @@ The class `list' represents an array structure, see list_*(). ####### 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. diff --git a/contrib/groffer/TODO b/contrib/groffer/TODO index d3d8dac2..01e1fed9 100644 --- a/contrib/groffer/TODO +++ b/contrib/groffer/TODO @@ -6,10 +6,11 @@ File position: <groff-source>/contrib/groffer/TODO ####### 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 @@ Optimization: (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. diff --git a/contrib/groffer/groffer.man b/contrib/groffer/groffer.man index aed486d0..b5af5faf 100644 --- a/contrib/groffer/groffer.man +++ b/contrib/groffer/groffer.man @@ -15,7 +15,7 @@ groffer.1 - man page for groffer (section 1). 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 @@ This file was written by \m[blue]Bernd Warken\m[]. 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 @@ are decompressed on-the-fly. . .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 @@ But all parts can also be controlled manually by arguments. 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 @@ They are transformed into a single document in the normal way of .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 @@ They are transformed into a single document in the normal way of .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 @@ the path name of an existing file. .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 @@ if .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 @@ if .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 @@ All other arguments are ignored. .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 @@ Equivalent to .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 @@ the program is running, and the early deletion of the temporary 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 the argument +.I shell_program +is empty a former shell option is cancelled and the default shell is +restored. . -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 . +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 @@ This is the equivalent .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 @@ or make sense for normal usage. .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 @@ process. . . .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 @@ argument switches to 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 @@ so most of them are just ignored. 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 @@ Check the non-option command line arguments .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 @@ is first tested whether it is an existing file. . . .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 @@ installed. . . .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 @@ Eqivalent to . . .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 @@ This was added by . . .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 @@ This is equivalent to . . .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 @@ Eqivalent to 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 @@ Next .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 @@ means this scheme. .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 @@ were constructed. .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 @@ is a .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 @@ in the lowest .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 @@ If .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 @@ We are left with the argument .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 @@ option . . .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 @@ the . . .\" -------------------------------------------------------------------- -.SS "Text mode" +.SS "Text modes" .\" -------------------------------------------------------------------- . There are two modes for text output, @@ -2369,7 +2472,8 @@ The default behavior of .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 @@ This behavior can be modified by the following options. .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 @@ shows the compression of the file. .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 @@ They are successively tried until a method works. .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 @@ variable .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 @@ is sufficient for most purposes. . . .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 @@ Topic . . .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 @@ or environment variable .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 @@ or environment variable . . .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 @@ can be started on the second monitor by the command .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 @@ The locale values\~\c .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 @@ within the run of .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 @@ uses it for storing its temporary files, just as groff does. .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 @@ which in turn is overwritten by the command line. . .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 @@ As not all of these are relevant for 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 @@ given on the command line. . .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 @@ This is overridden by option .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 @@ This is overridden by option .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 @@ The .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 @@ where .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 @@ minus sign. . .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 @@ and feed this name into its corresponding .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 @@ The usage of .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 @@ If the file .File_name \%./groff exists use it as input. . -Otherwise interpret the argument as a search for the man\~page named +Otherwise interpret the argument as a search for the +.I \%man\~page +named .B \%groff -in the smallest possible man\~section, being section 1 in this case. +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 @@ exists. .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 @@ a small set. .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 @@ not split to a search for .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 @@ The formatted files are concatenated and displayed in one piece. .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 @@ and view the result in the web browser .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 @@ exists in the actual directory. .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 @@ bold font, using color yellow on red background. . 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 @@ compatible to both .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 @@ is equivalent to . .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 @@ is equivalent to 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. +The free mixing of options and filespec parameters follows the GNU +principle. . -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. +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. . -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 . +The end of option processing can be forced by the option +.RB ` \-\- ' +anyway. . . .\" -------------------------------------------------------------------- @@ -3403,7 +3585,7 @@ You can also use the 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 @@ for information on availability. .SH "SEE ALSO" .\" -------------------------------------------------------------------- . -.TP -.BR \%groff (@MAN1EXT@) -.TP+ +.P +.BR \%groff (@MAN1EXT@), .BR \%@g@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 @@ macro files. . .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 @@ Standard pager program for the .I \%tty\~mode . . . -.TP -.BR \%gzip (1) -.TP+ +.P +.BR \%gzip (1), .BR \%bzip2 (1) +.RS The decompression programs supported by .BR \%groffer . +.RE . . .\" -------------------------------------------------------------------- diff --git a/contrib/groffer/groffer.sh b/contrib/groffer/groffer.sh index 4a9cdab4..6914bd95 100644 --- a/contrib/groffer/groffer.sh +++ b/contrib/groffer/groffer.sh @@ -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'; - - -######################################################################## -# 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. - -if test _"${_GROFFER_RUN}"_ = __; +# 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 _@BINDIR@_ = _${_AT}BINDIR${_AT}_ then - # only reached during the first run of the script - - 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..() + # 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 _CONF_FILES; # configuration files - _CONF_FILES="/etc/groff/groffer.conf ${HOME}/.groff/groffer.conf"; +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; + +export _GROFFER2_SH; # file name of the script that follows up +_GROFFER2_SH="${_GROFFER_LIBDIR}"/groffer2.sh; + +export _NULL_DEV; +if test -c /dev/null +then + _NULL_DEV="/dev/null"; +else + _NULL_DEV="NUL"; +fi; - 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; - export _NULL_DEV; - if test -c /dev/null; - then - _NULL_DEV="/dev/null"; - else - _NULL_DEV="NUL"; - fi; +# Test of the `$()' construct. +if test _"$(echo "$(echo 'test')")"_ \ + != _test_ +then + echo 'The "$()" construct did not work' >&2; + exit "${_ERROR}"; +fi; - # 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}"_ = __ +# 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 - _UNSET='unset'; - eval "${_UNSET}" _res; - else - _UNSET=':'; + 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; - - - ########################### - # _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}" '"$@"'; +done; + + +########################### Determine the shell + +export _SHELL; + +# 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 diff --git a/contrib/groffer/groffer2.sh b/contrib/groffer/groffer2.sh index d2253841..0563eade 100644 --- a/contrib/groffer/groffer2.sh +++ b/contrib/groffer/groffer2.sh @@ -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 @@ _DEBUG_LM='no'; # disable landmark messages 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 @@ esac; # 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 @@ _GOOD='0'; # return ok _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_PS; # viewer program for ps mode 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 @@ export _OPTS_CMDLINE_LONG_ARG; _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_SHORT_ARG=""; _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_X_LONG_ARG="'background' 'bd' 'bg' 'bordercolor' 'borderwidth' \ _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_NA="'7' 'a' 'c' 'd' 'D' 'f' 'h' 'k' 'l' 't' 'u' \ _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 @@ ${_OPTS_GROFF_LONG_ARG} ${_OPTS_MAN_LONG_ARG} ${_OPTS_X_LONG_ARG}"; # 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_VIEWER_X; # viewer program for x mode 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 @@ export _TMP_STDIN; # stores stdin, if any ######################################################################## +# 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 @@ _t_e_s_t_f_u_n_c_() 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 @@ fi; ######################################################################## +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 @@ _HAS_BZIP=''; # _TMP_* temporary files _TMP_DIR=''; _TMP_CAT=''; +_TMP_CONF=''; _TMP_STDIN=''; @@ -421,7 +481,7 @@ _TMP_STDIN=''; # reset() { - if test "$#" -ne 0; + if test "$#" -ne 0 then error "reset() does not have arguments."; fi; @@ -506,6 +566,21 @@ reset; ############## +# echo1 (<text>*) +# +# Output to stdout. +# +# Arguments : arbitrary text including `-'. +# +echo1() +{ + cat <<EOF +$* +EOF +} + + +############## # echo2 (<text>*) # # Output to stderr. @@ -529,9 +604,9 @@ EOF # landmark() { - if test _"${_DEBUG_LM}"_ = _yes_; + if test _"${_DEBUG_LM}"_ = _yes_ then - echo2 "LM: $*" >&2; + echo2 "LM: $*"; fi; } @@ -545,9 +620,13 @@ landmark "1: debugging functions"; # 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 @@ abort() # func_check() { - if test "$#" -lt 3; + if test "$#" -lt 3 then error 'func_check() needs at least 3 arguments.'; fi; @@ -670,7 +749,7 @@ func_check() shift; shift; shift; - if test "$#" "${fc_op}" "${fc_nargs}"; + if test "$#" "${fc_op}" "${fc_nargs}" then do_nothing; else @@ -678,7 +757,7 @@ func_check() ${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 @@ ${fc_fname}"'() needs '"${fc_comp} ${fc_nargs}"' argument'"${fc_s}"'.'; # 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 @@ s/^[^!]*!// # 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 @@ landmark "2: system test"; 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 @@ fi; ######################################################################## # 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 @@ fi; ######################################################################## # 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 @@ landmark "3: functions"; # 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 @@ base_name() 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 @@ s|//*$|| ;; */*) # 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 @@ EOF # 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 @@ then 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 @@ landmark '4: dirname()*'; 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 @@ dirname_chop() { 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 @@ do_filearg() 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_filearg() 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 @@ do_nothing() 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 @@ landmark '5: is_*()'; 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_dir() is_empty() { func_check is_empty = 1 "$@"; - if test _"$1"_ = __; + if test _"$1"_ = __ then eval "${return_yes}"; fi; @@ -1290,7 +1359,7 @@ is_empty() 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_equal() 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_existing() 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_file() 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_non_empty_file() 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_dir() 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_empty() 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_equal() 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_file() 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_prog() 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_writable() 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 @@ is_prog() 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_prog() 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_writable() 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 @@ is_yes() ######################################################################## -# 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 @@ landmark '6: list_*()'; # 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 @@ list_append() # 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 @@ s/'"${_SQUOTE}"'/&\\&&/g 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 @@ list_from_cmdline() 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 @@ EOF 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}"; - - # 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. - ;; + 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 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 @@ EOF 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 @@ list_from_split() 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 @@ list_get() 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 @@ s/['"${_SPACE}${_TAB}"']*$// eval "${return_ok}"; ;; \'*\') - cat <<EOF -${lg_list} -EOF + obj lg_list echo1; eval ${_UNSET} lg_list; eval "${return_ok}"; ;; @@ -1944,30 +2004,72 @@ EOF ######################################################################## # 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() ######################################################################## # 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 @@ landmark '7: man_*()'; # 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 @@ man_do_filespec() 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 @@ man_do_filespec() 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 @@ man_do_filespec() 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 @@ man_do_filespec() 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 @@ man_register_file() 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_register_file() 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 @@ man_search_section() 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 @@ man_search_section() 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 @@ man_search_section() 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 @@ man_search_section() 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 @@ man_setup() { 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 @@ man_setup() # 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_setup() *) _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_setup() _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 @@ landmark '8: manpath_*()'; 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 @@ _manpath_add_lang_sys_single() 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 @@ manpath_set_from_path() 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 @@ s|//*bin/*$|| /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 @@ landmark '9: obj_*()'; 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() 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 @@ EOF 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_from_output() 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 @@ path_chop() # 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 @@ s/:*$// 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 @@ path_clean() 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 @@ path_clean() 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_contains() 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 @@ landmark '10: register_*()'; 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_file() # 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 @@ s/\.Z$// ######################################################################## +# 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 @@ landmark '11: stack_*()'; # string_contains() { - func_check string_contains = 2 "$@"; + func_check string_contains '=' 2 "$@"; case "$1" in *"$2"*) eval "${return_yes}"; @@ -3024,8 +3256,8 @@ string_contains() # 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 @@ tmp_create() # 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 @@ EOF 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 @@ trap_clean() { 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 @@ trap_set() { 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 @@ usage() 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 @@ on-the-fly with all formats that gzip can handle. "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 @@ EOF 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 @@ warning() 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 @@ EOF # 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 @@ d' \ # 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 @@ where_is() { 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 @@ where_is() /*) 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 @@ where_is() */) 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 @@ EOF # sequence they are called in the main() function. -landmark '13: main_init()'; ####################################################################### # main_init () # @@ -3422,7 +3653,7 @@ main_init() 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 @@ main_init() _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 @@ Couldn't create a directory for storing temporary files."; _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 @@ s/^[ ]*\(-.*\)$/_groffer_opt="${_groffer_opt} \1"/ } # main_init() -landmark '14: main_parse_MANOPT()'; ######################################################################## # main_parse_MANOPT () # @@ -3535,21 +3735,25 @@ landmark '14: main_parse_MANOPT()'; 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 @@ main_parse_MANOPT() shift; ;; -d|--debug) - list_append mpm_list '--debug'; + do_nothing; ;; -D|--default) # undo all man options so far @@ -3586,10 +3790,9 @@ main_parse_MANOPT() -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 @@ main_parse_MANOPT() do_nothing; shift; ;; - -P|--pager|--tty-viewer) + -P|--pager) list_append mpm_list '--pager' "$1"; shift; ;; @@ -3638,27 +3841,27 @@ main_parse_MANOPT() 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 @@ landmark '15: main_parse_args()'; # 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 @@ main_parse_args() # 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 @@ main_parse_args() ;; -?) # 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 @@ main_parse_args() ;; --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 @@ main_parse_args() _OPT_DISPLAY="$1"; shift; ;; + --do-nothing) + leave; + ;; --dvi) _OPT_MODE='dvi'; ;; @@ -3901,7 +4103,7 @@ main_parse_args() _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 @@ only resoutions of 75 or 100 dpi are supported"; 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 @@ _check_device_with_mode() 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() } # _check_device_with_mode() of main_parse_args() -landmark '16: main_set_mode()'; ######################################################################## # main_set_mode () # @@ -4080,67 +4281,57 @@ main_set_mode() 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 @@ main_set_mode() '') # 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 @@ no X display found for device ${_OPT_DEVICE}"; ;; text) _DISPLAY_MODE='text'; - eval ${_UNSET} msm_code; eval ${_UNSET} msm_modes; eval ${_UNSET} msm_viewer; eval ${_UNSET} msm_viewers; @@ -4202,14 +4389,13 @@ no X display found for device ${_OPT_DEVICE}"; ;; 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 @@ you must be in X Window for ${_OPT_MODE} mode."; # 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 @@ you must be in X Window for ${_OPT_MODE} mode."; ;; 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 @@ you must be in X Window for ${_OPT_MODE} mode."; ;; 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 @@ you must be in X Window for ${_OPT_MODE} mode."; ;; esac; done; - eval ${_UNSET} msm_code; eval ${_UNSET} msm_modes; eval ${_UNSET} msm_viewer; eval ${_UNSET} msm_viewers; @@ -4375,11 +4552,11 @@ you must be in X Window for ${_OPT_MODE} mode."; # _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 @@ _get_first_prog() 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 @@ EOF } # _get_first_prog() of main_set_mode() -landmark '17: main_do_fileargs()'; ####################################################################### # main_do_fileargs () # @@ -4425,7 +4599,7 @@ main_do_fileargs() 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 @@ main_do_fileargs() 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 @@ main_do_fileargs() 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 @@ main_do_fileargs() fi; ;; *) - if do_filearg "${mdfa_filespec}"; + if do_filearg "${mdfa_filespec}" then mdfa_exitcode="${_GOOD}"; fi; @@ -4482,20 +4656,17 @@ main_do_fileargs() ;; 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() } # main_do_fileargs() -landmark '18: main_set_resources()'; ######################################################################## # main_set_resources () # @@ -4529,7 +4699,7 @@ main_set_resources() _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 @@ main_set_resources() 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 @@ main_set_resources() 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 @@ main_set_resources() 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() } # main_set_resources -landmark '19: main_display()'; ######################################################################## # main_display () # @@ -4732,50 +4923,38 @@ main_display() 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 @@ wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"; 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 @@ wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"; ;; 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 @@ wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"; } # 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 @@ main() { 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}"; } |