/contrib/groff/contrib/groffer/groffer2.sh
Shell | 5854 lines | 4370 code | 361 blank | 1123 comment | 359 complexity | 56f108a0a126ad0a9df7a8b9539c98fa MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0
- #! /bin/sh
- # groffer - display groff files
- # 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: 22 August 2005
- # This file is part of `groffer', which is part of `groff'.
- # `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.
- # 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.
- ########################################################################
- # Test of rudimentary shell functionality
- ########################################################################
- ########################################################################
- # 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}" _foo;
- eval "${_UNSET}" _res;
- else
- _UNSET=':';
- fi;
- ########################################################################
- # Test of `test'.
- #
- 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.
- #
- 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_
- then
- echo 'The "$()" construct did not work' >&2;
- exit "${_ERROR}";
- fi;
- ########################################################################
- # Test of sed program; test in groffer.sh is not valid here.
- #
- if test _"$(echo red | sed -e 's/r/s/')"_ != _sed_
- then
- echo 'The sed program did not work.' >&2;
- exit "${_ERROR}";
- fi;
- ########################################################################
- # Test of function definitions.
- #
- _t_e_s_t_f_u_n_c_()
- {
- return 0;
- }
- if _t_e_s_t_f_u_n_c_ 2>${_NULL_DEV}
- then
- :;
- else
- echo 'Shell '"${_SHELL}"' does not support function definitions.' >&2;
- exit "${_ERROR}";
- fi;
- ########################################################################
- # debug - diagnostic messages
- ########################################################################
- export _DEBUG_STACKS;
- _DEBUG_STACKS='no'; # disable stack output in each function
- #_DEBUG_STACKS='yes'; # enable stack output in each function
- export _DEBUG_LM;
- _DEBUG_LM='no'; # disable landmark messages
- #_DEBUG_LM='yes'; # enable 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
- 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
- export _DEBUG_PRINT_TMPDIR;
- _DEBUG_PRINT_TMPDIR='no'; # disable printing of the temporary dir
- #_DEBUG_PRINT_TMPDIR='yes'; # enable printing of the temporary dir
- export _DEBUG_USER_WITH_STACK;
- _DEBUG_USER_WITH_STACK='no'; # disable stack dump in error_user()
- #_DEBUG_USER_WITH_STACK='yes'; # enable stack dump in error_user()
- # determine all --debug* options
- case " $*" in
- *\ --debug*)
- case " $* " in
- *' --debug '*)
- # _DEBUG_STACKS='yes';
- # _DEBUG_LM='yes';
- _DEBUG_KEEP_FILES='yes';
- _DEBUG_PRINT_PARAMS='yes';
- _DEBUG_PRINT_SHELL='yes';
- _DEBUG_PRINT_TMPDIR='yes';
- _DEBUG_USER_WITH_STACK='yes';
- ;;
- esac;
- d=' --debug-all --debug-keep --debug-lm --debug-params --debug-shell '\
- '--debug-stacks --debug-tmpdir --debug-user ';
- for i
- do
- case "$i" in
- --debug-s)
- echo 'The abbreviation --debug-s has multiple options: '\
- '--debug-shell and --debug-stacks.' >&2
- exit "${_ERROR}";
- ;;
- esac;
- case "$d" in
- *\ ${i}*)
- # extract whole word of abbreviation $i
- s="$(cat <<EOF | sed -n -e 's/^.* \('"$i"'[^ ]*\) .*/\1/p'
- $d
- EOF
- )"
- case "$s" in
- '') continue; ;;
- --debug-all)
- _DEBUG_STACKS='yes';
- _DEBUG_LM='yes';
- _DEBUG_KEEP_FILES='yes';
- _DEBUG_PRINT_PARAMS='yes';
- _DEBUG_PRINT_SHELL='yes';
- _DEBUG_PRINT_TMPDIR='yes';
- _DEBUG_USER_WITH_STACK='yes';
- ;;
- --debug-keep)
- _DEBUG_PRINT_TMPDIR='yes';
- _DEBUG_KEEP_FILES='yes';
- ;;
- --debug-lm)
- _DEBUG_LM='yes';
- ;;
- --debug-params)
- _DEBUG_PRINT_PARAMS='yes';
- ;;
- --debug-shell)
- _DEBUG_PRINT_SHELL='yes';
- ;;
- --debug-stacks)
- _DEBUG_STACKS='yes';
- ;;
- --debug-tmpdir)
- _DEBUG_PRINT_TMPDIR='yes';
- ;;
- --debug-user)
- _DEBUG_USER_WITH_STACK='yes';
- ;;
- esac;
- ;;
- esac;
- done
- ;;
- esac;
- if test _"${_DEBUG_PRINT_PARAMS}"_ = _yes_
- then
- echo "parameters: $@" >&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
- ########################################################################
- # Environment variables that exist only for this file start with an
- # underscore letter. Global variables to this file are written in
- # upper case letters, e.g. $_GLOBAL_VARIABLE; temporary variables
- # start with an underline and use only lower case letters and
- # underlines, e.g. $_local_variable .
- # [A-Z]* system variables, e.g. $MANPATH
- # _[A-Z_]* global file variables, e.g. $_MAN_PATH
- # _[a-z_]* temporary variables, e.g. $_manpath
- # Due to incompatibilities of the `ash' shell, the name of loop
- # variables in `for' must be single character
- # [a-z] local loop variables, e.g. $i
- ########################################################################
- # read-only variables (global to this file)
- ########################################################################
- # function return values; `0' means ok; other values are error codes
- export _ALL_EXIT;
- export _BAD;
- export _GOOD;
- export _NO;
- export _OK;
- export _YES;
- _GOOD='0'; # return ok
- _BAD='1'; # return negatively, error code `1'
- # $_ERROR was already defined as `7' in groffer.sh.
- _NO="${_BAD}";
- _YES="${_GOOD}";
- _OK="${_GOOD}";
- # quasi-functions, call with `eval', e.g `eval "${return_ok}"'
- export return_ok;
- export return_good;
- export return_bad;
- export return_yes;
- export return_no;
- export return_error;
- export return_var;
- return_ok="func_pop; return ${_OK}";
- return_good="func_pop; return ${_GOOD}";
- return_bad="func_pop; return ${_BAD}";
- return_yes="func_pop; return ${_YES}";
- return_no="func_pop; return ${_NO}";
- return_error="func_pop; return ${_ERROR}";
- return_var="func_pop; return"; # add number, e.g. `eval "${return_var} $n'
- export _DEFAULT_MODES;
- _DEFAULT_MODES='x,ps,tty';
- export _DEFAULT_RESOLUTION;
- _DEFAULT_RESOLUTION='75';
- export _DEFAULT_TTY_DEVICE;
- _DEFAULT_TTY_DEVICE='latin1';
- # _VIEWER_* viewer programs for different modes (only X is necessary)
- # _VIEWER_* a comma-separated list of viewer programs (with options)
- export _VIEWER_DVI; # viewer program for dvi mode
- export _VIEWER_HTML_TTY; # viewer program for html mode in tty
- export _VIEWER_HTML_X; # viewer program for html mode in X
- export _VIEWER_PDF; # viewer program for pdf mode
- export _VIEWER_PS; # viewer program for ps mode
- export _VIEWER_X; # viewer program for X mode
- _VIEWER_DVI='kdvi,xdvi,dvilx';
- _VIEWER_HTML_TTY='lynx';
- _VIEWER_HTML_X='konqueror,mozilla,netscape,galeon,opera,amaya,arena';
- _VIEWER_PDF='kghostview --scale 1.45,ggv,xpdf,acroread,kpdf';
- _VIEWER_PS='kghostview --scale 1.45,ggv,gv,ghostview,gs_x11,gs';
- _VIEWER_X='gxditview,xditview';
- # Search automatically in standard sections `1' to `8', and in the
- # traditional sections `9', `n', and `o'. On many systems, there
- # exist even more sections, mostly containing a set of man pages
- # special to a specific program package. These aren't searched for
- # automatically, but must be specified on the command line.
- export _MAN_AUTO_SEC_LIST;
- _MAN_AUTO_SEC_LIST="'1' '2' '3' '4' '5' '6' '7' '8' '9' 'n' 'o'";
- export _MAN_AUTO_SEC_CHARS;
- _MAN_AUTO_SEC_CHARS='[123456789no]';
- export _SPACE_SED;
- _SPACE_SED='['"${_SP}${_TAB}"']';
- export _SPACE_CASE;
- _SPACE_CASE='[\'"${_SP}"'\'"${_TAB}"']';
- export _PROCESS_ID; # for shutting down the program
- _PROCESS_ID="$$";
- ############ the command line options of the involved programs
- #
- # The naming scheme for the options environment names is
- # $_OPTS_<prog>_<length>[_<argspec>]
- #
- # <prog>: program name GROFFER, GROFF, or CMDLINE (for all
- # command line options)
- # <length>: LONG (long options) or SHORT (single character options)
- # <argspec>: ARG for options with argument, NA for no argument;
- # without _<argspec> both the ones with and without arg.
- #
- # Each option that takes an argument must be specified with a
- # trailing : (colon).
- # exports
- export _OPTS_GROFFER_SHORT_NA;
- export _OPTS_GROFFER_SHORT_ARG;
- export _OPTS_GROFFER_LONG_NA;
- export _OPTS_GROFFER_LONG_ARG;
- export _OPTS_GROFF_SHORT_NA;
- export _OPTS_GROFF_SHORT_ARG;
- export _OPTS_GROFF_LONG_NA;
- export _OPTS_GROFF_LONG_ARG;
- export _OPTS_X_SHORT_ARG;
- export _OPTS_X_SHORT_NA;
- export _OPTS_X_LONG_ARG;
- export _OPTS_X_LONG_NA;
- export _OPTS_MAN_SHORT_ARG;
- export _OPTS_MAN_SHORT_NA;
- export _OPTS_MAN_LONG_ARG;
- export _OPTS_MAN_LONG_NA;
- export _OPTS_MANOPT_SHORT_ARG;
- export _OPTS_MANOPT_SHORT_NA;
- export _OPTS_MANOPT_LONG_ARG;
- export _OPTS_MANOPT_LONG_NA;
- export _OPTS_CMDLINE_SHORT_NA;
- export _OPTS_CMDLINE_SHORT_ARG;
- export _OPTS_CMDLINE_LONG_NA;
- export _OPTS_CMDLINE_LONG_ARG;
- ###### groffer native options
- _OPTS_GROFFER_SHORT_NA="'h' 'Q' 'v' 'V' 'X' 'Z'";
- _OPTS_GROFFER_SHORT_ARG="'T'";
- _OPTS_GROFFER_LONG_NA="'auto' \
- 'apropos' 'apropos-data' 'apropos-devel' 'apropos-progs' \
- 'debug' 'debug-all' 'debug-keep' 'debug-lm' 'debug-params' 'debug-shell' \
- 'debug-stacks' 'debug-tmpdir' 'debug-user' 'default' 'do-nothing' 'dvi' \
- 'groff' 'help' 'intermediate-output' 'html' 'man' \
- 'no-location' 'no-man' 'no-special' 'pdf' 'ps' 'rv' 'source' \
- 'text' 'text-device' \
- 'tty' 'tty-device' 'version' 'whatis' 'where' 'www' 'x' 'X'";
- _OPTS_GROFFER_LONG_ARG="\
- 'default-modes' 'device' 'dvi-viewer' 'dvi-viewer-tty' 'extension' 'fg' \
- 'fn' 'font' 'foreground' 'html-viewer' 'html-viewer-tty' 'mode' \
- 'pdf-viewer' 'pdf-viewer-tty' 'print' 'ps-viewer' 'ps-viewer-tty' 'shell' \
- 'title' 'tty-viewer' 'tty-viewer-tty' 'www-viewer' 'www-viewer-tty' \
- 'x-viewer' 'x-viewer-tty' 'X-viewer' 'X-viewer-tty'";
- ##### groffer options inhereted from groff
- _OPTS_GROFF_SHORT_NA="'a' 'b' 'c' 'C' 'e' 'E' 'g' 'G' 'i' 'l' 'N' 'p' \
- 'R' 's' 'S' 't' 'U' 'z'";
- _OPTS_GROFF_SHORT_ARG="'d' 'f' 'F' 'I' 'L' 'm' 'M' 'n' 'o' 'P' 'r' \
- 'w' 'W'";
- _OPTS_GROFF_LONG_NA="";
- _OPTS_GROFF_LONG_ARG="";
- ##### groffer options inhereted from the X Window toolkit
- _OPTS_X_SHORT_NA="";
- _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' \
- 'resolution' 'title' 'xrm'";
- ###### groffer options inherited from man
- _OPTS_MAN_SHORT_NA="";
- _OPTS_MAN_SHORT_ARG="";
- _OPTS_MAN_LONG_NA="'all' 'ascii' 'catman' 'ditroff' \
- 'local-file' 'location' 'troff' 'update'";
- _OPTS_MAN_LONG_ARG="'locale' 'manpath' \
- 'pager' 'preprocessor' 'prompt' 'sections' 'systems' 'troff-device'";
- ###### additional options for parsing $MANOPT only
- _OPTS_MANOPT_SHORT_NA="'7' 'a' 'c' 'd' 'D' 'f' 'h' 'k' 'l' 't' 'u' \
- 'V' 'w' 'Z'";
- _OPTS_MANOPT_SHORT_ARG="'e' 'L' 'm' 'M' 'p' 'P' 'r' 'S' 'T'";
- _OPTS_MANOPT_LONG_NA="${_OPTS_MAN_LONG_NA} \
- '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' 'extension' 'locale'";
- ###### collections of command line options
- _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}";
- _OPTS_CMDLINE_LONG_NA="${_OPTS_GROFFER_LONG_NA} \
- ${_OPTS_GROFF_LONG_NA} ${_OPTS_X_LONG_NA} ${_OPTS_MAN_LONG_NA}";
- _OPTS_CMDLINE_LONG_ARG="${_OPTS_GROFFER_LONG_ARG} \
- ${_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').
- export _APROPOS_PROG; # Program to run apropos.
- export _APROPOS_SECTIONS; # Sections for different --apropos-*.
- export _DEFAULT_MODES; # Set default modes.
- export _DISPLAY_MODE; # Display mode.
- export _DISPLAY_PROG; # Viewer program to be used for display.
- export _DISPLAY_ARGS; # X resources for the viewer program.
- export _FILEARGS; # Stores filespec parameters.
- export _FILESPEC_ARG; # Stores the actual filespec parameter.
- export _FUNC_STACK; # Store debugging information.
- export _REGISTERED_TITLE; # Processed file names.
- # _HAS_* from availability tests
- export _HAS_COMPRESSION; # `yes' if gzip compression is available
- export _HAS_BZIP; # `yes' if bzip2 compression is available
- # _MAN_* finally used configuration of man searching
- export _MAN_ALL; # search all man pages per filespec
- export _MAN_ENABLE; # enable search for man pages
- export _MAN_EXT; # extension for man pages
- export _MAN_FORCE; # force file parameter to be man pages
- export _MAN_IS_SETUP; # setup man variables only once
- export _MAN_LANG; # language for man pages
- export _MAN_LANG2; # language for man pages
- export _MAN_LANG_DONE; # language dirs added to man path
- export _MAN_PATH; # search path for man pages
- export _MAN_SEC; # sections for man pages; sep. `:'
- export _MAN_SEC_DONE; # sections added to man path
- export _MAN_SYS; # system names for man pages; sep. `,'
- export _MAN_SYS; # system names added to man path
- # _MANOPT_* as parsed from $MANOPT
- export _MANOPT_ALL; # $MANOPT --all
- export _MANOPT_EXTENSION; # $MANOPT --extension
- export _MANOPT_LANG; # $MANOPT --locale
- export _MANOPT_PATH; # $MANOPT --manpath
- export _MANOPT_PAGER; # $MANOPT --pager
- export _MANOPT_SEC; # $MANOPT --sections
- export _MANOPT_SYS; # $MANOPT --systems
- # _OPT_* as parsed from groffer command line
- export _OPT_ALL; # display all suitable man pages.
- export _OPT_APROPOS; # call `apropos' program.
- export _OPT_BD; # set border color in some modes.
- export _OPT_BG; # set background color in some modes.
- export _OPT_BW; # set border width in some modes.
- export _OPT_DEFAULT_MODES; # `,'-list of modes when no mode given.
- export _OPT_DEVICE; # device option.
- export _OPT_DO_NOTHING; # do nothing in main_display().
- export _OPT_DISPLAY; # set X display.
- export _OPT_FG; # set foreground color in some modes.
- export _OPT_FN; # set font in some modes.
- export _OPT_GEOMETRY; # set size and position of viewer in X.
- export _OPT_ICONIC; # -iconic option for X viewers.
- export _OPT_LANG; # set language for man pages
- export _OPT_LOCATION; # print processed file names to stderr
- export _OPT_MODE; # values: X, tty, Q, Z, ""
- export _OPT_MANPATH; # manual setting of path for man-pages
- export _OPT_PAGER; # specify paging program for tty mode
- export _OPT_RESOLUTION; # set X resolution in dpi
- export _OPT_RV; # reverse fore- and background colors.
- export _OPT_SECTIONS; # sections for man page search
- export _OPT_SYSTEMS; # man pages of different OS's
- export _OPT_TITLE; # title for gxditview window
- export _OPT_TEXT_DEVICE; # set device for tty mode.
- export _OPT_V; # groff option -V.
- export _OPT_VIEWER_DVI; # viewer program for dvi mode
- export _OPT_VIEWER_PDF; # viewer program for pdf mode
- export _OPT_VIEWER_PS; # viewer program for ps mode
- export _OPT_VIEWER_HTML; # viewer program for html mode
- export _OPT_VIEWER_X; # viewer program for x mode
- export _OPT_WHATIS; # print the man description
- export _OPT_XRM; # specify X resource.
- export _OPT_Z; # groff option -Z.
- export _OUTPUT_FILE_NAME; # output generated, see main_set_res..()
- export _VIEWER_TERMINAL; # viewer options for terminal (--*-viewer-tty)
- # _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
- # these variables are preset in section `Preset' after the rudim. test
- ########################################################################
- # Preset and reset of read-write global variables
- ########################################################################
- 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='';
- # _HAS_* from availability tests
- _HAS_COMPRESSION='';
- _HAS_BZIP='';
- # _TMP_* temporary files
- _TMP_DIR='';
- _TMP_CAT='';
- _TMP_CONF='';
- _TMP_STDIN='';
- ########################################################################
- # reset ()
- #
- # Reset the variables that can be affected by options to their default.
- #
- reset()
- {
- if test "$#" -ne 0
- then
- error "reset() does not have arguments.";
- fi;
- _ADDOPTS_GROFF='';
- _ADDOPTS_POST='';
- _ADDOPTS_X='';
- _APROPOS_PROG='';
- _APROPOS_SECTIONS='';
- _DISPLAY_ARGS='';
- _DISPLAY_MODE='';
- _DISPLAY_PROG='';
- _REGISTERED_TITLE='';
- # _MAN_* finally used configuration of man searching
- _MAN_ALL='no';
- _MAN_ENABLE='yes'; # do search for man-pages
- _MAN_EXT='';
- _MAN_FORCE='no'; # first local file, then search man page
- _MAN_IS_SETUP='no';
- _MAN_LANG='';
- _MAN_LANG2='';
- _MAN_PATH='';
- _MAN_SEC='';
- _MAN_SEC_DONE='no';
- _MAN_SYS='';
- _MAN_SYS_DONE='no';
- # _MANOPT_* as parsed from $MANOPT
- _MANOPT_ALL='no';
- _MANOPT_EXTENSION='';
- _MANOPT_LANG='';
- _MANOPT_PATH='';
- _MANOPT_PAGER='';
- _MANOPT_SEC='';
- _MANOPT_SYS='';
- # _OPT_* as parsed from groffer command line
- _OPT_ALL='no';
- _OPT_APROPOS='no';
- _OPT_BD='';
- _OPT_BG='';
- _OPT_BW='';
- _OPT_DEFAULT_MODES='';
- _OPT_DEVICE='';
- _OPT_DISPLAY='';
- _OPT_DO_NOTHING='no';
- _OPT_FG='';
- _OPT_FN='';
- _OPT_GEOMETRY='';
- _OPT_ICONIC='no';
- _OPT_LANG='';
- _OPT_LOCATION='no';
- _OPT_MODE='';
- _OPT_MANPATH='';
- _OPT_PAGER='';
- _OPT_RESOLUTION='';
- _OPT_RV='no';
- _OPT_SECTIONS='';
- _OPT_SYSTEMS='';
- _OPT_TITLE='';
- _OPT_TEXT_DEVICE='';
- _OPT_V='no';
- _OPT_VIEWER_DVI='';
- _OPT_VIEWER_PDF='';
- _OPT_VIEWER_PS='';
- _OPT_VIEWER_HTML='';
- _OPT_VIEWER_X='';
- _OPT_WHATIS='no';
- _OPT_XRM='';
- _OPT_Z='no';
- _VIEWER_TERMINAL='no';
- }
- reset;
- ########################################################################
- # Functions for error handling and debugging
- ########################################################################
- ##############
- # echo1 (<text>*)
- #
- # Output to stdout.
- #
- # Arguments : arbitrary text including `-'.
- #
- echo1()
- {
- cat <<EOF
- $@
- EOF
- }
- ##############
- # echo2 (<text>*)
- #
- # Output to stderr.
- #
- # Arguments : arbitrary text.
- #
- echo2()
- {
- cat >&2 <<EOF
- $@
- EOF
- }
- ##############
- # landmark (<text>)
- #
- # Print <text> to standard error as a debugging aid.
- #
- # Globals: $_DEBUG_LM
- #
- landmark()
- {
- if test _"${_DEBUG_LM}"_ = _yes_
- then
- echo2 "LM: $*";
- fi;
- }
- landmark "1: debugging functions";
- ##############
- # clean_up ()
- #
- # Clean up at exit.
- #
- clean_up()
- {
- cd "${_START_DIR}" >"${_NULL_DEV}" 2>&1;
- if test _${_DEBUG_KEEP_FILES}_ = _yes_
- then
- echo2 "Kept temporary directory ${_TMP_DIR}."
- else
- if test _"${_TMP_DIR}"_ != __
- then
- if test -d "${_TMP_DIR}" || test -f "${_TMP_DIR}"
- then
- rm -f -r "${_TMP_DIR}" >${_NULL_DEV} 2>&1;
- fi;
- fi;
- fi;
- }
- #############
- # diag (text>*)
- #
- # Output a diagnostic message to stderr
- #
- diag()
- {
- echo2 '>>>>>'"$*";
- }
- #############
- # error (<text>*)
- #
- # Print an error message to standard error, print the function stack,
- # exit with an error condition. The argument should contain the name
- # of the function from which it was called. This is for system errors.
- #
- error()
- {
- case "$#" in
- 1) echo2 'groffer error: '"$1"; ;;
- *) echo2 'groffer error: wrong number of arguments in error().'; ;;
- esac;
- func_stack_dump;
- if test _"${_TMP_DIR}"_ != __ && test -d "${_TMP_DIR}"
- then
- : >"${_TMP_DIR}"/,error;
- fi;
- exit "${_ERROR}";
- }
- #############
- # error_user (<text>*)
- #
- # Print an error message to standard error; exit with an error condition.
- # The error is supposed to be produce by the user. So the funtion stack
- # is omitted.
- #
- error_user()
- {
- case "$#" in
- 1)
- echo2 'groffer error: '"$1";
- ;;
- *)
- echo2 'groffer error: wrong number of arguments in error_user().';
- ;;
- esac;
- if test _"${_DEBUG_USER_WITH_STACK}"_ = _yes_
- then
- func_stack_dump;
- fi;
- if test _"${_TMP_DIR}"_ != __ && test -d "${_TMP_DIR}"
- then
- : >"${_TMP_DIR}"/,error;
- fi;
- exit "${_ERROR}";
- }
- #############
- # exit_test ()
- #
- # Test whether the former command ended with error(). Exit again.
- #
- # Globals: $_ERROR
- #
- exit_test()
- {
- if test "$?" = "${_ERROR}"
- then
- exit ${_ERROR};
- fi;
- if test _"${_TMP_DIR}"_ != __ && test -f "${_TMP_DIR}"/,error
- then
- exit ${_ERROR};
- fi;
- }
- #############
- # func_check (<func_name> <rel_op> <nr_args> "$@")
- #
- # Check number of arguments and register to _FUNC_STACK.
- #
- # Arguments: >=3
- # <func_name>: name of the calling function.
- # <rel_op>: a relational operator: = != < > <= >=
- # <nr_args>: number of arguments to be checked against <operator>
- # "$@": the arguments of the calling function.
- #
- # Variable prefix: fc
- #
- func_check()
- {
- if test "$#" -lt 3
- then
- error 'func_check() needs at least 3 arguments.';
- fi;
- fc_fname="$1";
- case "$3" in
- 1)
- fc_nargs="$3";
- fc_s='';
- ;;
- 0|[2-9])
- fc_nargs="$3";
- fc_s='s';
- ;;
- *)
- error "func_check(): third argument must be a digit.";
- ;;
- esac;
- case "$2" in
- '='|'-eq')
- fc_op='-eq';
- fc_comp='exactly';
- ;;
- '>='|'-ge')
- fc_op='-ge';
- fc_comp='at least';
- ;;
- '<='|'-le')
- fc_op='-le';
- fc_comp='at most';
- ;;
- '<'|'-lt')
- fc_op='-lt';
- fc_comp='less than';
- ;;
- '>'|'-gt')
- fc_op='-gt';
- fc_comp='more than';
- ;;
- '!='|'-ne')
- fc_op='-ne';
- fc_comp='not';
- ;;
- *)
- error \
- 'func_check(): second argument is not a relational operator.';
- ;;
- esac;
- shift;
- shift;
- shift;
- if test "$#" "${fc_op}" "${fc_nargs}"
- then
- do_nothing;
- else
- error "func_check(): \
- ${fc_fname}"'() needs '"${fc_comp} ${fc_nargs}"' argument'"${fc_s}"'.';
- fi;
- func_push "${fc_fname}";
- if test _"${_DEBUG_STACKS}"_ = _yes_
- then
- echo2 '+++ '"${fc_fname} $@";
- echo2 '>>> '"${_FUNC_STACK}";
- fi;
- eval ${_UNSET} fc_comp;
- eval ${_UNSET} fc_fname;
- eval ${_UNSET} fc_nargs;
- eval ${_UNSET} fc_op;
- eval ${_UNSET} fc_s;
- }
- #############
- # func_pop ()
- #
- # Retrieve the top element from the stack.
- #
- # The stack elements are separated by `!'; the popped element is
- # identical to the original element, except that all `!' characters
- # were removed.
- #
- # Arguments: 1
- #
- func_pop()
- {
- if test "$#" -ne 0
- then
- error 'func_pop() does not have arguments.';
- fi;
- case "${_FUNC_STACK}" in
- '')
- if test _"${_DEBUG_STACKS}"_ = _yes_
- then
- error 'func_pop(): stack is empty.';
- fi;
- ;;
- *!*)
- # split at first bang `!'.
- _FUNC_STACK="$(echo1 "${_FUNC_STACK}" | sed -e 's/^[^!]*!//')";
- exit_test;
- ;;
- *)
- _FUNC_STACK='';
- ;;
- esac;
- if test _"${_DEBUG_STACKS}"_ = _yes_
- then
- echo2 '<<< '"${_FUNC_STACK}";
- fi;
- }
- #############
- # func_push (<element>)
- #
- # Store another element to stack.
- #
- # The stack elements are separated by `!'; if <element> contains a `!'
- # it is removed first.
- #
- # Arguments: 1
- #
- # Variable prefix: fp
- #
- func_push()
- {
- if test "$#" -ne 1
- then
- error 'func_push() needs 1 argument.';
- fi;
- case "$1" in
- *'!'*)
- # remove all bangs `!'.
- fp_element="$(echo1 "$1" | sed -e 's/!//g')";
- exit_test;
- ;;
- *)
- fp_element="$1";
- ;;
- esac;
- if test _"${_FUNC_STACK}"_ = __
- then
- _FUNC_STACK="${fp_element}";
- else
- _FUNC_STACK="${fp_element}!${_FUNC_STACK}";
- fi;
- eval ${_UNSET} fp_element;
- }
- #############
- # func_stack_dump ()
- #
- # Print the content of the stack. Ignore the arguments.
- #
- func_stack_dump()
- {
- diag 'call stack: '"${_FUNC_STACK}";
- }
- ########################################################################
- # System Test
- ########################################################################
- landmark "2: system test";
- # Test the availability of the system utilities used in this script.
- ########################################################################
- # Test of function `sed'.
- #
- if test _"$(echo xTesTx \
- | sed -e 's/^.\([Tt]e*x*sTT*\).*$/\1/' \
- | sed -e 's|T|t|g')"_ != _test_
- then
- error 'Test of "sed" command failed.';
- fi;
- ########################################################################
- # Test of function `cat'.
- #
- if test _"$(echo test | cat)"_ != _test_
- then
- error 'Test of "cat" command failed.';
- fi;
- ########################################################################
- # Test for compression.
- #
- if test _"$(echo 'test' | gzip -c -d -f - 2>${_NULL_DEV})"_ = _test_
- then
- _HAS_COMPRESSION='yes';
- if echo1 '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_
- then
- _HAS_BZIP='yes';
- else
- _HAS_BZIP='no';
- fi;
- else
- _HAS_COMPRESSION='no';
- _HAS_BZIP='no';
- fi;
- ########################################################################
- # Definition of normal Functions in alphabetical order
- ########################################################################
- landmark "3: functions";
- ########################################################################
- # apropos_filespec ()
- #
- # Setup for the --apropos* options
- #
- apropos_filespec()
- {
- func_check apropos_filespec '=' 0 "$@";
- if obj _OPT_APROPOS is_yes
- then
- eval to_tmp_line \
- "'.SH $(echo1 "${_FILESPEC_ARG}" | sed 's/[^\\]-/\\-/g')'";
- exit_test;
- if obj _APROPOS_PROG is_empty
- then
- error 'apropos_filespec: apropos_setup() must be run first.';
- fi;
- if obj _APROPOS_SECTIONS is_empty
- then
- if obj _OPT_SECTIONS is_empty
- then
- s='^.*(.*).*$';
- else
- s='^.*(['"$(echo1 "${_OPT_SECTIONS}" | sed -e 's/://g')"']';
- fi;
- else
- s='^.*(['"${_APROPOS_SECTIONS}"']';
- fi;
- eval "${_APROPOS_PROG}" "'${_FILESPEC_ARG}'" | \
- sed -n -e '
- /^'"${_FILESPEC_ARG}"': /p
- /'"$s"'/p
- ' | \
- sort |\
- sed -e '
- s/^\(.* (..*)\) *- *\(.*\)$/\.br\n\.TP 15\n\.BR \1\n\2/
- ' >>"${_TMP_CAT}";
- fi;
- eval "${return_ok}";
- }
- ########################################################################
- # apropos_setup ()
- #
- # Setup for the --apropos* options
- #
- apropos_setup()
- {
- func_check apropos_setup '=' 0 "$@";
- if obj _OPT_APROPOS is_yes
- then
- if is_prog apropos
- then
- _APROPOS_PROG='apropos';
- elif is_prog man
- then
- if man --apropos man >${_NULL_DEV} 2>${_NULL_DEV}
- then
- _APROPOS_PROG='man --apropos';
- elif man -k man >${_NULL_DEV} 2>${_NULL_DEV}
- then
- _APROPOS_PROG='man -k';
- fi;
- fi;
- if obj _APROPOS_PROG is_empty
- then
- error 'apropos_setup: no apropos program available.';
- fi;
- to_tmp_line '.TH GROFFER APROPOS';
- fi;
- eval "${return_ok}";
- }
- ########################################################################
- # base_name (<path>)
- #
- # Get the file name part of <path>, i.e. delete everything up to last
- # `/' from the beginning of <path>. Remove final slashes, too, to get a
- # non-empty output.
- #
- # Arguments : 1
- # Output : the file name part (without slashes)
- #
- # Variable prefix: bn
- #
- base_name()
- {
- func_check base_name = 1 "$@";
- bn_name="$1";
- case "${bn_name}" in
- */)
- # delete all final slashes
- bn_name="$(echo1 "${bn_name}" | sed -e 's|//*$||')";
- exit_test;
- ;;
- esac;
- case "${bn_name}" in
- /|'')
- eval ${_UNSET} bn_name;
- eval "${return_bad}";
- ;;
- */*)
- # delete everything before and including the last slash `/'.
- echo1 "${bn_name}" | sed -e 's|^.*//*\([^/]*\)$|\1|';
- ;;
- *)
- obj bn_name echo1;
- ;;
- esac;
- eval ${_UNSET} bn_name;
- eval "${return_ok}";
- }
- ########################################################################
- # cat_z (<file>)
- #
- # Decompress if possible or just print <file> to standard output.
- #
- # gzip, bzip2, and .Z decompression is supported.
- #
- # Arguments: 1, a file name.
- # Output: the content of <file>, possibly decompressed.
- #
- if test _"${_HAS_COMPRESSION}"_ = _yes_
- then
- cat_z()
- {
- func_check cat_z = 1 "$@";
- case "$1" in
- '')
- error 'cat_z(): empty file name';
- ;;
- '-')
- error 'cat_z(): for standard input use save_stdin()';
- ;;
- esac;
- if obj _HAS_BZIP is_yes
- then
- if bzip2 -t "$1" 2>${_NULL_DEV}
- then
- bzip2 -c -d "$1" 2>${_NULL_DEV};
- eval "${return_ok}";
- fi;
- fi;
- gzip -c -d -f "$1" 2>${_NULL_DEV};
- eval "${return_ok}";
- }
- else
- cat_z()
- {
- func_check cat_z = 1 "$@";
- cat "$1";
- eval "${return_ok}";
- }
- fi;
- ########################################################################
- # clean_up ()
- #
- # Do the final cleaning up before exiting; used by the trap calls.
- #
- # defined above
- ########################################################################
- # diag (<text>*)
- #
- # Print marked message to standard error; useful for debugging.
- #
- # defined above
- ########################################################################
- landmark '4: dirname()*';
- ########################################################################
- #######################################################################
- # dirname_append (<dir> <name>)
- #
- # Append `name' to `dir' with clean handling of `/'.
- #
- # Arguments : 2
- # Output : the generated new directory name <dir>/<name>
- #
- dirname_append()
- {
- func_check dirname_append = 2 "$@";
- if is_empty "$1"
- then
- error "dir_append(): first argument is empty.";
- fi;
- if is_empty "$2"
- then
- echo1 "$1";
- else
- dirname_chop "$1"/"$2";
- fi;
- eval "${return_ok}";
- }
- ########################################################################
- # dirname_chop (<name>)
- #
- # Remove unnecessary slashes from directory name.
- #
- # Argument: 1, a directory name.
- # Output: path without double, or trailing slashes.
- #
- # Variable prefix: dc
- #
- dirname_chop()
- {
- func_check dirname_chop = 1 "$@";
- # replace all multiple slashes by a single slash `/'.
- dc_res="$(echo1 "$1" | sed -e 's|///*|/|g')";
- exit_test;
- case "${dc_res}" in
- ?*/)
- # remove trailing slash '/';
- echo1 "${dc_res}" | sed -e 's|/$||';
- ;;
- *)
- obj dc_res echo1
- ;;
- esac;
- eval ${_UNSET} dc_res;
- eval "${return_ok}";
- }
- ########################################################################
- # do_filearg (<filearg>)
- #
- # Append the file, man-page, or standard input corresponding to the
- # argument to the temporary file. If this is compressed in the gzip
- # or Z format it is decompressed. A title element is generated.
- #
- # Argument either:
- # - name of an existing file.
- # - `-' to represent standard input (several times allowed).
- # - `man:name.(section)' the man-page for `name' in `section'.
- # - `man:name.section' the man-page for `name' in `section'.
- # - `man:name' the man-page for `name' in the lowest `section'.
- # - `name.section' the man-page for `name' in `section'.
- # - `name' the man-page for `name' in the lowest `section'.
- # Globals :
- # $_TMP_STDIN, $_MAN_ENABLE, $_MAN_IS_SETUP, $_OPT_MAN
- #
- # Output : none
- # Return : $_GOOD if found, ${_BAD} otherwise.
- #
- # Variable prefix: df
- #
- do_filearg()
- {
- func_check do_filearg = 1 "$@";
- df_filespec="$1";
- # store sequence into positional parameters
- case "${df_filespec}" in
- '')
- eval ${_UNSET} df_filespec;
- eval "${return_good}";
- ;;
- '-')
- register_file '-';
- eval ${_UNSET} df_filespec;
- eval "${return_good}";
- ;;
- */*) # with directory part; so no man search
- set 'File';
- ;;
- *)
- if obj _MAN_ENABLE is_yes
- then
- if obj _MAN_FORCE is_yes
- then
- set 'Manpage' 'File';
- else
- set 'File' 'Manpage';
- fi;
- else
- set 'File';
- fi;
- ;;
- esac;
- for i
- do
- case "$i" in
- File)
- if test -f "${df_filespec}"
- then
- 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
- if obj _OPT_WHATIS is_yes
- then
- to_tmp_line "This is neither a file nor a man page."
- else
- echo2 "\`${df_filespec}' is neither a file nor a man page."
- fi;
- fi;
- df_no_file=yes;
- continue;
- fi;
- ;;
- Manpage) # parse filespec as man page
- if obj _MAN_IS_SETUP is_not_yes
- then
- man_setup;
- fi;
- 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
- if obj _OPT_WHATIS is_yes
- then
- to_tmp_line "This is neither a file nor a man page."
- else
- echo2 "\`${df_filespec}' is neither a file nor a man page."
- fi;
- 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()
- ########################################################################
- # do_nothing ()
- #
- # Dummy function.
- #
- do_nothing()
- {
- eval return "${_OK}";
- }
- ########################################################################
- # echo2 (<text>*)
- #
- # Print to standard error with final line break.
- #
- # defined above
- ########################################################################
- # error (<text>*)
- #
- # Print error message and exit with error code.
- #
- # defined above
- ########################################################################
- # exit_test ()
- #
- # Test whether the former command ended with error(). Exit again.
- #
- # defined above
- ########################################################################
- # func_check (<func_name> <rel_op> <nr_args> "$@")
- #
- # Check number of arguments and register to _FUNC_STACK.
- #
- # Arguments: >=3
- # <func_name>: name of the calling function.
- # <rel_op>: a relational operator: = != < > <= >=
- # <nr_args>: number of arguments to be checked against <operator>
- # "$@": the arguments of the calling function.
- #
- # defined above
- #########################################################################
- # func_pop ()
- #
- # Delete the top element from the function call stack.
- #
- # defined above
- ########################################################################
- # func_push (<element>)
- #
- # Store another element to function call stack.
- #
- # defined above
- ########################################################################
- # func_stack_dump ()
- #
- # Print the content of the stack.
- #
- # defined above
- ########################################################################
- # get_first_essential (<arg>*)
- #
- # Retrieve first non-empty argument.
- #
- # Return : `1' if all arguments are empty, `0' if found.
- # Output : the retrieved non-empty argument.
- #
- # Variable prefix: gfe
- #
- get_first_essential()
- {
- func_check get_first_essential '>=' 0 "$@";
- if is_equal "$#" 0
- then
- eval "${return_ok}";
- fi;
- for i
- do
- gfe_var="$i";
- if obj gfe_var is_not_empty
- then
- obj gfe_var echo1;
- eval ${_UNSET} gfe_var;
- eval "${return_ok}";
- fi;
- done;
- eval ${_UNSET} gfe_var;
- eval "${return_bad}";
- }
- ########################################################################
- landmark '5: is_*()';
- ########################################################################
- ########################################################################
- # is_dir (<name>)
- #
- # Test whether `name' is a directory.
- #
- # Arguments : 1
- # Return : `0' if arg1 is a directory, `1' otherwise.
- #
- is_dir()
- {
- func_check is_dir '=' 1 "$@";
- if test _"$1"_ != __ && test -d "$1" && test -r "$1"
- then
- eval "${return_yes}";
- fi;
- eval "${return_no}";
- }
- ########################################################################
- # is_empty (<string>)
- #
- # Test whether `string' is empty.
- #
- # Arguments : <=1
- # Return : `0' if arg1 is empty or does not exist, `1' otherwise.
- #
- is_empty()
- {
- func_check is_empty '=' 1 "$@";
- if test _"$1"_ = __
- then
- eval "${return_yes}";
- fi;
- eval "${return_no}";
- }
- ########################################################################
- # is_equal (<string1> <string2>)
- #
- # Test whether `string1' is equal to <string2>.
- #
- # Arguments : 2
- # Return : `0' both arguments are equal strings, `1' otherwise.
- #
- is_equal()
- {
- func_check is_equal '=' 2 "$@";
- if test _"$1"_ = _"$2"_
- then
- eval "${return_yes}";
- fi;
- eval "${return_no}";
- }
- ########################################################################
- # is_existing (<name>)
- #
- # Test whether `name' is an existing file or directory. Solaris 2.5 does
- # not have `test -e'.
- #
- # Arguments : 1
- # Return : `0' if arg1 exists, `1' otherwise.
- #
- is_existing()
- {
- func_check is_existing '=' 1 "$@";
- if test _"$1"_ = __
- then
- eval "${return_no}";
- fi;
- if test -f "$1" || test -d "$1" || test -c "$1"
- then
- eval "${return_yes}";
- fi;
- eval "${return_no}";
- }
- ########################################################################
- # is_file (<name>)
- #
- # Test whether `name' is a readable file.
- #
- # Arguments : 1
- # Return : `0' if arg1 is a readable file, `1' otherwise.
- #
- is_file()
- {
- func_check is_file '=' 1 "$@";
- if is_not_empty "$1" && test -f "$1" && test -r "$1"
- then
- eval "${return_yes}";
- fi;
- eval "${return_no}";
- }
- ########################################################################
- # is_non_empty_file (<file_name>)
- #
- # Test whether `file_name' is a non-empty existing file.
- #
- # Arguments : <=1
- # Return :
- # `0' if arg1 is a non-empty existing file
- # `1' otherwise
- #
- is_non_empty_file()
- {
- func_check is_non_empty_file '=' 1 "$@";
- if is_file "$1" && test -s "$1"
- then
- eval "${return_yes}";
- fi;
- eval "${return_no}";
- }
- ########################################################################
- # is_not_dir (<name>)
- #
- # Test whether `name' is not a readable directory.
- #
- # Arguments : 1
- # Return : `0' if arg1 is a directory, `1' otherwise.
- #
- is_not_dir()
- {
- func_check is_not_dir '=' 1 "$@";
- if is_dir "$1"
- then
- eval "${return_no}";
- fi;
- eval "${return_yes}";
- }
- ########################################################################
- # is_not_empty (<string>)
- #
- # Test whether `string' is not empty.
- #
- # Arguments : <=1
- # Return : `0' if arg1 exists and is not empty, `1' otherwise.
- #
- is_not_empty()
- {
- func_check is_not_empty '=' 1 "$@";
- if is_empty "$1"
- then
- eval "${return_no}";
- fi;
- eval "${return_yes}";
- }
- ########################################################################
- # is_not_equal (<string1> <string2>)
- #
- # Test whether `string1' differs from `string2'.
- #
- # Arguments : 2
- #
- is_not_equal()
- {
- func_check is_not_equal '=' 2 "$@";
- if is_equal "$1" "$2"
- then
- eval "${return_no}";
- fi
- eval "${return_yes}";
- }
- ########################################################################
- # is_not_file (<filename>)
- #
- # Test whether `name' is a not readable file.
- #
- # Arguments : 1 (empty allowed)
- #
- is_not_file()
- {
- func_check is_not_file '=' 1 "$@";
- if is_file "$1"
- then
- eval "${return_no}";
- fi;
- eval "${return_yes}";
- }
- ########################################################################
- # is_not_prog ([<name> [<arg>*]])
- #
- # Verify that arg is a not program in $PATH.
- #
- # Arguments : >=0 (empty allowed)
- # more args are ignored, this allows to specify progs with arguments
- #
- is_not_prog()
- {
- func_check is_not_prog '>=' 0 "$@";
- case "$#" in
- 0)
- eval "${return_yes}";
- ;;
- *)
- if where_is "$1" >${_NULL_DEV}
- then
- eval "${return_no}";
- fi;
- ;;
- esac
- eval "${return_yes}";
- }
- ########################################################################
- # is_not_writable (<name>)
- #
- # Test whether `name' is a not a writable file or directory.
- #
- # Arguments : >=1 (empty allowed), more args are ignored
- #
- is_not_writable()
- {
- func_check is_not_writable '>=' 1 "$@";
- if is_writable "$1"
- then
- eval "${return_no}";
- fi;
- eval "${return_yes}";
- }
- ########################################################################
- # is_not_X ()
- #
- # Test whether not running in X Window by checking $DISPLAY
- #
- is_not_X()
- {
- func_check is_X '=' 0 "$@";
- if obj DISPLAY is_empty
- then
- eval "${return_yes}";
- fi;
- eval "${return_no}";
- }
- ########################################################################
- # is_not_yes (<string>)
- #
- # Test whether `string' is not "yes".
- #
- # Arguments : 1
- #
- is_not_yes()
- {
- func_check is_not_yes = 1 "$@";
- if is_yes "$1"
- then
- eval "${return_no}";
- fi;
- eval "${return_yes}";
- }
- ########################################################################
- # is_prog ([<name> [<arg>*]])
- #
- # Determine whether <name> is a program in $PATH
- #
- # Arguments : >=0 (empty allowed)
- # <arg>* are ignored, this allows to specify progs with arguments.
- #
- is_prog()
- {
- func_check is_prog '>=' 0 "$@";
- case "$#" in
- 0)
- eval "${return_no}";
- ;;
- *)
- if where_is "$1" >${_NULL_DEV}
- then
- eval "${return_yes}";
- fi;
- ;;
- esac
- eval "${return_no}";
- }
- ########################################################################
- # is_writable (<name>)
- #
- # Test whether `name' is a writable file or directory.
- #
- # Arguments : >=1 (empty allowed), more args are ignored
- #
- is_writable()
- {
- func_check is_writable '>=' 1 "$@";
- if test _"$1"_ = __
- then
- eval "${return_no}";
- fi;
- if test -r "$1"
- then
- if test -w "$1"
- then
- eval "${return_yes}";
- fi;
- fi;
- eval "${return_no}";
- }
- ########################################################################
- # is_X ()
- #
- # Test whether running in X Window by checking $DISPLAY
- #
- is_X()
- {
- func_check is_X '=' 0 "$@";
- if obj DISPLAY is_not_empty
- then
- eval "${return_yes}";
- fi;
- eval "${return_no}";
- }
- ########################################################################
- # is_yes (<string>)
- #
- # Test whether `string' has value "yes".
- #
- # Return : `0' if arg1 is `yes', `1' otherwise.
- #
- is_yes()
- {
- func_check is_yes '=' 1 "$@";
- if is_equal "$1" 'yes'
- then
- eval "${return_yes}";
- fi;
- eval "${return_no}";
- }
- ########################################################################
- # landmark ()
- #
- # Print debugging information on standard error if $_DEBUG_LM is `yes'.
- #
- # Globals: $_DEBUG_LM
- #
- # Defined in section `Debugging functions'.
- ########################################################################
- # leave ([<code>])
- #
- # Clean exit without an error or with <code>.
- #
- leave()
- {
- clean_up;
- if test $# = 0
- then
- exit "${_OK}";
- else
- exit "$1";
- fi;
- }
- ########################################################################
- landmark '6: list_*()';
- ########################################################################
- #
- # `list' is an object class that represents an array or list. Its
- # 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 `eval set x "$list"; shift`.
- ########################################################################
- # list_append (<list> <element>...)
- #
- # Arguments: >=2
- # <list>: a variable name for a list of single-quoted elements
- # <element>: some sequence of characters.
- # Output: none, but $<list> is set to
- # if <list> is empty: "'<element>' '...'"
- # otherwise: "$list '<element>' ..."
- #
- # Variable prefix: la
- #
- list_append()
- {
- func_check list_append '>=' 2 "$@";
- la_name="$1";
- eval la_list='"${'$1'}"';
- shift;
- for s
- do
- la_s="$s";
- case "${la_s}" in
- *\'*)
- # 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="$(echo1 "${la_s}" | sed -e 's/'"${_SQ}"'/&\\&&/g')";
- exit_test;
- ;;
- '')
- la_element="";
- ;;
- *)
- la_element="${la_s}";
- ;;
- esac;
- if obj la_list is_empty
- then
- la_list="'${la_element}'";
- else
- la_list="${la_list} '${la_element}'";
- fi;
- done;
- eval "${la_name}"='"${la_list}"';
- eval ${_UNSET} la_element;
- eval ${_UNSET} la_list;
- eval ${_UNSET} la_name;
- eval ${_UNSET} la_s;
- eval "${return_ok}";
- }
- ########################################################################
- # list_from_cmdline (<pre_name_of_opt_lists> [<cmdline_arg>...])
- #
- # Transform command line arguments into a normalized form.
- #
- # Options, option arguments, and file parameters are identified and
- # output each as a single-quoted argument of its own. Options and
- # file parameters are separated by a '--' argument.
- #
- # Arguments: >=1
- # <pre_name>: common part of a set of 4 environment variable names:
- # $<pre_name>_SHORT_NA: list of short options without an arg.
- # $<pre_name>_SHORT_ARG: list of short options that have an arg.
- # $<pre_name>_LONG_NA: list of long options without an arg.
- # $<pre_name>_LONG_ARG: list of long options that have an arg.
- # <cmdline_arg>...: the arguments from a command line, such as "$@",
- # the content of a variable, or direct arguments.
- #
- # Output: ['-[-]opt' ['optarg']]... '--' ['filename']...
- #
- # Example:
- # list_from_cmdline PRE 'a b' 'c' '' 'long' -a f1 -bcarg --long=larg f2
- # If $PRE_SHORT_NA, $PRE_SHORT_ARG, $PRE_LONG_NA, and $PRE_LONG_ARG are
- # none-empty option lists, this will result in printing:
- # '-a' '-b' '-c' 'arg' '--long' 'larg' '--' 'f1' 'f2'
- #
- # Use this function in the following way:
- # eval set x "$(args_norm PRE_NAME "$@")";
- # shift;
- # while test "$1" != '--'; do
- # case "$1" in
- # ...
- # esac;
- # shift;
- # done;
- # shift; #skip '--'
- # # all positional parameters ("$@") left are file name parameters.
- #
- # Variable prefix: lfc
- #
- list_from_cmdline()
- {
- func_check list_from_cmdline '>=' 1 "$@";
- lfc_short_n="$(obj_data "$1"_SHORT_NA)"; # short options, no argument
- 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
- exit_test;
- 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
- then
- error 'list_from_cmdline(): no $'"$1"'_SHORT_ARG options.';
- fi;
- 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
- then
- error 'list_from_cmdline(): no $'"$1"'_LONG_ARG options.';
- fi;
- shift;
- if is_equal "$#" 0
- then
- echo1 --
- eval ${_UNSET} lfc_fparams;
- eval ${_UNSET} lfc_short_a;
- eval ${_UNSET} lfc_short_n;
- eval ${_UNSET} lfc_long_a;
- eval ${_UNSET} lfc_long_n;
- eval ${_UNSET} lfc_result;
- eval "${return_ok}";
- fi;
- lfc_fparams='';
- lfc_result='';
- while test "$#" -ge 1
- do
- lfc_arg="$1";
- shift;
- case "${lfc_arg}" in
- --) break; ;;
- --*=*)
- # delete leading '--';
- lfc_abbrev="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
- 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}")";
- exit_test;
- if obj lfc_opt is_empty
- then
- error_user "--${lfc_abbrev} is not an option.";
- else
- # get the option argument by deleting up to first `='
- lfc_optarg="$(echo1 "${lfc_with_equal}" | sed -e 's/^[^=]*=//')";
- exit_test;
- list_append lfc_result "--${lfc_opt}" "${lfc_optarg}";
- continue;
- fi;
- ;;
- --*)
- # delete leading '--';
- lfc_abbrev="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
- if list_has lfc_long_n "${lfc_abbrev}"
- then
- lfc_opt="${lfc_abbrev}";
- else
- exit_test;
- lfc_opt="$(list_single_from_abbrev lfc_long_n "${lfc_abbrev}")";
- exit_test;
- if obj lfc_opt is_not_empty && is_not_equal "$#" 0
- then
- a="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
- exit_test;
- if obj a is_not_empty
- then
- error_user "The abbreviation ${lfc_arg} \
- has multiple options: --${lfc_opt} and --${a}.";
- fi;
- fi;
- fi;
- if obj lfc_opt is_not_empty
- then
- # long option, no argument
- list_append lfc_result "--${lfc_opt}";
- continue;
- fi;
- lfc_opt="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
- exit_test;
- if obj lfc_opt is_not_empty
- then
- # long option with argument
- if test "$#" -le 0
- then
- error_user "no argument for option --${lfc_opt}."
- fi;
- list_append lfc_result "--${lfc_opt}" "$1";
- shift;
- continue;
- fi;
- error_user "${lfc_arg} is not an option.";
- ;;
- -?*) # short option (cluster)
- # delete leading `-';
- lfc_rest="$(echo1 "${lfc_arg}" | sed -e 's/^-//')";
- exit_test;
- 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/^.//')";
- exit_test;
- if list_has lfc_short_n "${lfc_optchar}"
- then
- list_append lfc_result "-${lfc_optchar}";
- continue;
- elif list_has lfc_short_a "${lfc_optchar}"
- then
- if obj lfc_rest is_empty
- then
- if test "$#" -ge 1
- then
- list_append lfc_result "-${lfc_optchar}" "$1";
- shift;
- continue;
- else
- error_user "no argument for option -${lfc_optchar}.";
- fi;
- else # rest is the argument
- list_append lfc_result "-${lfc_optchar}" "${lfc_rest}";
- lfc_rest='';
- continue;
- fi;
- else
- error_user "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
- then
- lfc_result="${lfc_result} ${lfc_fparams}";
- fi;
- if test "$#" -gt 0
- then
- list_append lfc_result "$@";
- fi;
- obj lfc_result echo1;
- eval ${_UNSET} lfc_abbrev;
- eval ${_UNSET} lfc_fparams;
- eval ${_UNSET} lfc_short_a;
- eval ${_UNSET} lfc_short_n;
- eval ${_UNSET} lfc_long_a;
- eval ${_UNSET} lfc_long_n;
- eval ${_UNSET} lfc_result;
- eval ${_UNSET} lfc_arg;
- eval ${_UNSET} lfc_opt;
- eval ${_UNSET} lfc_opt_arg;
- eval ${_UNSET} lfc_opt_char;
- eval ${_UNSET} lfc_with_equal;
- eval ${_UNSET} lfc_rest;
- eval "${return_ok}";
- } # list_from_cmdline()
- ########################################################################
- # list_from_split (<string> <separator>)
- #
- # In <string>, escape all white space characters and replace each
- # <separator> by space.
- #
- # Arguments: 2: a <string> that is to be split into parts divided by
- # <separator>
- # Output: the resulting list string
- #
- # Variable prefix: lfs
- #
- list_from_split()
- {
- func_check list_from_split = 2 "$@";
- # precede each space or tab by a backslash `\' (doubled for `sed')
- lfs_s="$(echo1 "$1" | sed -e 's/\('"${_SPACE_SED}"'\)/\\\1/g')";
- exit_test;
- # replace split character of string by the list separator ` ' (space).
- case "$2" in
- /) # cannot use normal `sed' separator
- echo1 "${lfs_s}" | sed -e 's|'"$2"'| |g';
- ;;
- ?) # use normal `sed' separator
- echo1 "${lfs_s}" | sed -e 's/'"$2"'/ /g';
- ;;
- ??*)
- error 'list_from_split(): separator must be a single character.';
- ;;
- esac;
- eval ${_UNSET} lfs_s;
- eval "${return_ok}";
- }
- ########################################################################
- # list_get (<list>)
- #
- # Check whether <list> is a space-separated list of '-quoted elements.
- #
- # If the test fails an error is raised.
- # If the test succeeds the argument is echoed.
- #
- # Testing criteria:
- # A list has the form "'first' 'second' '...' 'last'". So it has a
- # leading and a final quote and the elements are separated by "' '"
- # constructs. If these are all removed there should not be any
- # unescaped single-quotes left. Watch out for escaped single
- # quotes; they have the form '\'' (sq bs sq sq).
- # Arguments: 1
- # Output: the argument <list> unchanged, if the check succeeded.
- #
- # Variable prefix: lg
- #
- list_get()
- {
- func_check list_get = 1 "$@";
- eval lg_list='"${'$1'}"';
- # remove leading and final space characters
- lg_list="$(echo1 "${lg_list}" | sed -e '
- s/^'"${_SPACE_SED}"'*//
- s/'"${_SPACE_SED}"'*$//
- ')";
- exit_test;
- case "${lg_list}" in
- '')
- eval ${_UNSET} lg_list;
- eval "${return_ok}";
- ;;
- \'*\')
- obj lg_list echo1;
- eval ${_UNSET} lg_list;
- eval "${return_ok}";
- ;;
- *)
- error "list_get(): bad list: $1"
- ;;
- esac;
- eval ${_UNSET} lg_list;
- eval "${return_ok}";
- }
- ########################################################################
- # 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.
- #
- # Variable prefix: lh
- #
- list_has()
- {
- func_check list_has = 2 "$@";
- eval lh_list='"${'$1'}"';
- if obj lh_list is_empty
- then
- eval "${_UNSET}" lh_list;
- eval "${return_no}";
- fi;
- case "$2" in
- \'*\') lh_element=" $2 "; ;;
- *) lh_element=" '$2' "; ;;
- esac;
- 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}"'$//')";
- exit_test;
- ;;
- *) 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}";
- }
- ########################################################################
- # 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.
- #
- # Variable prefix: lhn
- #
- list_has_not()
- {
- func_check list_has_not = 2 "$@";
- eval lhn_list='"${'$1'}"';
- if obj lhn_list is_empty
- then
- eval "${_UNSET}" lhn_list;
- eval "${return_yes}";
- fi;
- case "$2" in
- \'*\') lhn_element=" $2 "; ;;
- *) lhn_element=" '$2' "; ;;
- esac;
- 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;
- }
- ########################################################################
- # 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_user "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;
- }
- ########################################################################
- landmark '7: man_*()';
- ########################################################################
- ########################################################################
- # man_do_filespec (<filespec>)
- #
- # Print suitable man page(s) for filespec to $_TMP_CAT.
- #
- # Arguments : 2
- # <filespec>: argument of the form `man:name.section', `man:name',
- # `man:name(section)', `name.section', `name'.
- #
- # Globals : $_OPT_ALL
- #
- # Output : none.
- # Return : `0' if man page was found, `1' else.
- #
- # 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
- then
- eval "${return_bad}";
- fi;
- if is_empty "$1"
- then
- eval "${return_bad}";
- fi;
- mdf_spec="$1";
- mdf_name='';
- mdf_section='';
- case "${mdf_spec}" in
- */*) # not a man spec with containing '/'
- eval ${_UNSET} mdf_got_one;
- eval ${_UNSET} mdf_name;
- eval ${_UNSET} mdf_section;
- eval ${_UNSET} mdf_spec;
- eval "${return_bad}";
- ;;
- man:?*\(?*\)) # man:name(section)
- mdf_name="$(echo1 "${mdf_spec}" \
- | sed -e 's/^man:\(..*\)(\(..*\))$/\1/')";
- mdf_section="$(echo1 "${mdf_spec}" \
- | sed -e 's/^man:\(..*\)(\(..*\))$/\2/')";
- exit_test;
- ;;
- man:?*.${_MAN_AUTO_SEC_CHARS}) # man:name.section
- mdf_name="$(echo1 "${mdf_spec}" \
- | sed -e 's/^man:\(..*\)\..$/\1/')";
- mdf_section="$(echo1 "${mdf_spec}" \
- | sed -e 's/^.*\(.\)$/\1/')";
- exit_test;
- ;;
- man:?*) # man:name
- mdf_name="$(echo1 "${mdf_spec}" | sed -e 's/^man://')";
- exit_test;
- ;;
- ?*\(?*\)) # name(section)
- mdf_name="$(echo1 "${mdf_spec}" \
- | sed -e 's/^\(..*\)(\(..*\))$/\1/')";
- mdf_section="$(echo1 "${mdf_spec}" \
- | sed -e 's/^\(..*\)(\(..*\))$/\2/')";
- exit_test;
- ;;
- ?*.${_MAN_AUTO_SEC_CHARS}) # name.section
- mdf_name="$(echo1 "${mdf_spec}" \
- | sed -e 's/^\(..*\)\..$/\1/')";
- mdf_section="$(echo1 "${mdf_spec}" \
- | sed -e 's/^.*\(.\)$/\1/')";
- exit_test;
- ;;
- ?*)
- mdf_name="${mdf_spec}";
- ;;
- esac;
- if obj mdf_name is_empty
- then
- eval ${_UNSET} mdf_got_one;
- eval ${_UNSET} mdf_name;
- eval ${_UNSET} mdf_section;
- eval ${_UNSET} mdf_spec;
- eval "${return_bad}";
- fi;
- mdf_got_one='no';
- if obj mdf_section is_empty
- then
- if obj _OPT_SECTIONS is_empty
- then
- eval set x "${_MAN_AUTO_SEC_LIST}";
- else
- # use --sections when no section is given to filespec
- eval set x "$(echo1 "${_OPT_SECTIONS}" | sed -e 's/:/ /g')";
- fi;
- shift;
- for s
- do
- mdf_s="$s";
- if man_search_section "${mdf_name}" "${mdf_s}"
- then # found
- if obj _MAN_ALL is_yes
- then
- mdf_got_one='yes';
- else
- eval ${_UNSET} mdf_got_one;
- eval ${_UNSET} mdf_name;
- eval ${_UNSET} mdf_s;
- eval ${_UNSET} mdf_section;
- eval ${_UNSET} mdf_spec;
- eval "${return_good}";
- fi;
- fi;
- done;
- else
- if man_search_section "${mdf_name}" "${mdf_section}"
- then
- eval ${_UNSET} mdf_got_one;
- eval ${_UNSET} mdf_name;
- eval ${_UNSET} mdf_s;
- eval ${_UNSET} mdf_section;
- eval ${_UNSET} mdf_spec;
- eval "${return_good}";
- else
- eval ${_UNSET} mdf_got_one;
- eval ${_UNSET} mdf_name;
- eval ${_UNSET} mdf_section;
- eval ${_UNSET} mdf_spec;
- eval "${return_bad}";
- fi;
- fi;
- if obj _MAN_ALL is_yes && obj mdf_got_one is_yes
- then
- eval ${_UNSET} mdf_got_one;
- eval ${_UNSET} mdf_name;
- eval ${_UNSET} mdf_s;
- eval ${_UNSET} mdf_section;
- eval ${_UNSET} mdf_spec;
- eval "${return_good}";
- fi;
- eval ${_UNSET} mdf_got_one;
- eval ${_UNSET} mdf_name;
- eval ${_UNSET} mdf_s;
- eval ${_UNSET} mdf_section;
- eval ${_UNSET} mdf_spec;
- eval "${return_bad}";
- } # man_do_filespec()
- ########################################################################
- # man_register_file (<file> <name> [<section>])
- #
- # Write a found man page file and register the title element.
- #
- # Arguments: 1, 2, or 3; maybe empty
- # Output: none
- #
- man_register_file()
- {
- func_check man_register_file '>=' 2 "$@";
- case "$#" in
- 2|3) do_nothing; ;;
- *)
- error "man_register_file() expects 2 or 3 arguments.";
- ;;
- esac;
- if is_empty "$1"
- then
- error 'man_register_file(): file name is empty';
- fi;
- to_tmp "$1";
- case "$#" in
- 2)
- register_title "man:$2";
- eval "${return_ok}";
- ;;
- 3)
- register_title "$2.$3";
- eval "${return_ok}";
- ;;
- esac;
- eval "${return_ok}";
- }
- ########################################################################
- # man_search_section (<name> <section>)
- #
- # Retrieve man pages.
- #
- # Arguments : 2
- # Globals : $_MAN_PATH, $_MAN_EXT
- # Return : 0 if found, 1 otherwise
- #
- # Variable prefix: mss
- #
- man_search_section()
- {
- func_check man_search_section = 2 "$@";
- if obj _MAN_PATH is_empty
- then
- eval "${return_bad}";
- fi;
- if is_empty "$1"
- then
- eval "${return_bad}";
- fi;
- if is_empty "$2"
- then
- eval "${return_bad}";
- fi;
- mss_name="$1";
- mss_section="$2";
- eval set x "$(path_split "${_MAN_PATH}")";
- exit_test;
- shift;
- mss_got_one='no';
- if obj _MAN_EXT is_empty
- then
- for d
- do
- mss_dir="$(dirname_append "$d" "man${mss_section}")";
- exit_test;
- if obj mss_dir is_dir
- then
- mss_prefix="$(\
- dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
- if obj _OPT_WHATIS is_yes
- then
- mss_files="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
- sed -e '\| found|s|.*||'
- )";
- else
- mss_files="$(eval ls "'${mss_prefix}'"'*' 2>${_NULL_DEV} |
- sed -e '\| found|s|.*||'
- )";
- fi;
- exit_test;
- if obj mss_files is_not_empty
- then
- # for f in $mss_files
- for f in $(eval set x ${mss_files}; shift; echo1 "$@")
- do
- exit_test;
- mss_f="$f";
- if obj mss_f is_file
- then
- if is_yes "${mss_got_one}"
- then
- register_file "${mss_f}";
- elif obj _MAN_ALL is_yes
- then
- man_register_file "${mss_f}" "${mss_name}";
- else
- man_register_file "${mss_f}" "${mss_name}" "${mss_section}";
- eval ${_UNSET} mss_dir;
- eval ${_UNSET} mss_ext;
- eval ${_UNSET} mss_f;
- eval ${_UNSET} mss_files;
- eval ${_UNSET} mss_got_one;
- eval ${_UNSET} mss_name;
- eval ${_UNSET} mss_prefix;
- eval ${_UNSET} mss_section;
- eval "${return_good}";
- fi;
- mss_got_one='yes';
- fi;
- done;
- fi;
- fi;
- done;
- else
- mss_ext="${_MAN_EXT}";
- # check for directory name having trailing extension
- for d
- do
- mss_dir="$(dirname_append $d man${mss_section}${mss_ext})";
- exit_test;
- 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|.*||'
- )";
- exit_test;
- if obj mss_files is_not_empty
- then
- # for f in $mss_files
- for f in $(eval set x ${mss_files}; shift; echo1 "$@")
- do
- mss_f="$f";
- if obj mss_f is_file
- then
- if is_yes "${mss_got_one}"
- then
- register_file "${mss_f}";
- elif obj _MAN_ALL is_yes
- then
- man_register_file "${mss_f}" "${mss_name}";
- else
- man_register_file "${mss_f}" "${mss_name}" "${mss_section}";
- eval ${_UNSET} mss_dir;
- eval ${_UNSET} mss_ext;
- eval ${_UNSET} mss_f;
- eval ${_UNSET} mss_files;
- eval ${_UNSET} mss_got_one;
- eval ${_UNSET} mss_name;
- eval ${_UNSET} mss_prefix;
- eval ${_UNSET} mss_section;
- eval "${return_good}";
- fi;
- mss_got_one='yes';
- fi;
- done;
- fi;
- fi;
- done;
- # check for files with extension in directories without extension
- for d
- do
- mss_dir="$(dirname_append "$d" "man${mss_section}")";
- exit_test;
- 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|.*||'
- )";
- exit_test;
- if obj mss_files is_not_empty
- then
- # for f in $mss_files
- for f in $(eval set x ${mss_files}; shift; echo1 "$@")
- do
- mss_f="$f";
- if obj mss_f is_file
- then
- if is_yes "${mss_got_one}"
- then
- register_file "${mss_f}";
- elif obj _MAN_ALL is_yes
- then
- man_register_file "${mss_f}" "${mss_name}";
- else
- man_register_file "${mss_f}" "${mss_name}" "${mss_section}";
- eval ${_UNSET} mss_dir;
- eval ${_UNSET} mss_ext;
- eval ${_UNSET} mss_f;
- eval ${_UNSET} mss_files;
- eval ${_UNSET} mss_got_one;
- eval ${_UNSET} mss_name;
- eval ${_UNSET} mss_prefix;
- eval ${_UNSET} mss_section;
- eval "${return_good}";
- fi;
- mss_got_one='yes';
- fi;
- done;
- fi;
- fi;
- done;
- fi;
- if obj _MAN_ALL is_yes && is_yes "${mss_got_one}"
- then
- eval ${_UNSET} mss_dir;
- eval ${_UNSET} mss_ext;
- eval ${_UNSET} mss_f;
- eval ${_UNSET} mss_files;
- eval ${_UNSET} mss_got_one;
- eval ${_UNSET} mss_name;
- eval ${_UNSET} mss_prefix;
- eval ${_UNSET} mss_section;
- eval "${return_good}";
- fi;
- eval ${_UNSET} mss_dir;
- eval ${_UNSET} mss_ext;
- eval ${_UNSET} mss_f;
- eval ${_UNSET} mss_files;
- eval ${_UNSET} mss_got_one;
- eval ${_UNSET} mss_name;
- eval ${_UNSET} mss_prefix;
- eval ${_UNSET} mss_section;
- eval "${return_bad}";
- } # man_search_section()
- ########################################################################
- # man_setup ()
- #
- # Setup the variables $_MAN_* needed for man page searching.
- #
- # Globals:
- # in: $_OPT_*, $_MANOPT_*, $LANG, $LC_MESSAGES, $LC_ALL,
- # $MANPATH, $MANROFFSEQ, $MANSEC, $PAGER, $SYSTEM, $MANOPT.
- # out: $_MAN_PATH, $_MAN_LANG, $_MAN_SYS, $_MAN_LANG, $_MAN_LANG2,
- # $_MAN_SEC, $_MAN_ALL
- # in/out: $_MAN_ENABLE
- #
- # The precedence for the variables related to `man' is that of GNU
- # `man', i.e.
- #
- # $LANG; overridden by
- # $LC_MESSAGES; overridden by
- # $LC_ALL; this has the same precedence as
- # $MANPATH, $MANROFFSEQ, $MANSEC, $PAGER, $SYSTEM; overridden by
- # $MANOPT; overridden by
- # the groffer command line options.
- #
- # Variable prefix: ms
- #
- man_setup()
- {
- func_check main_man_setup = 0 "$@";
- if obj _MAN_IS_SETUP is_yes
- then
- eval "${return_ok}";
- fi;
- _MAN_IS_SETUP='yes';
- if obj _MAN_ENABLE is_not_yes
- then
- eval "${return_ok}";
- fi;
- # determine basic path for man pages
- _MAN_PATH="$(get_first_essential \
- "${_OPT_MANPATH}" "${_MANOPT_PATH}" "${MANPATH}")";
- exit_test;
- if obj _MAN_PATH is_empty
- then
- manpath_set_from_path;
- else
- _MAN_PATH="$(path_clean "${_MAN_PATH}")";
- exit_test;
- fi;
- if obj _MAN_PATH is_empty
- then
- if is_prog 'manpath'
- then
- _MAN_PATH="$(manpath 2>${_NULL_DEV})"; # not always available
- exit_test;
- fi;
- fi;
- if obj _MAN_PATH is_empty
- then
- _MAN_ENABLE="no";
- eval "${return_ok}";
- fi;
- _MAN_ALL="$(get_first_essential "${_OPT_ALL}" "${_MANOPT_ALL}")";
- exit_test;
- if obj _MAN_ALL is_empty
- then
- _MAN_ALL='no';
- fi;
- _MAN_SYS="$(get_first_essential \
- "${_OPT_SYSTEMS}" "${_MANOPT_SYS}" "${SYSTEM}")";
- ms_lang="$(get_first_essential \
- "${_OPT_LANG}" "${LC_ALL}" "${LC_MESSAGES}" "${LANG}")";
- exit_test;
- case "${ms_lang}" in
- C|POSIX)
- _MAN_LANG="";
- _MAN_LANG2="";
- ;;
- ?)
- _MAN_LANG="${ms_lang}";
- _MAN_LANG2="";
- ;;
- *)
- _MAN_LANG="${ms_lang}";
- # get first two characters of $ms_lang
- _MAN_LANG2="$(echo1 "${ms_lang}" | sed -e 's/^\(..\).*$/\1/')";
- exit_test;
- ;;
- esac;
- # from now on, use only $_LANG, forget about $_OPT_LANG, $LC_*.
- manpath_add_lang_sys; # this is very slow
- _MAN_SEC="$(get_first_essential \
- "${_OPT_SECT}" "${_MANOPT_SEC}" "${MANSEC}")";
- exit_test;
- if obj _MAN_PATH is_empty
- then
- _MAN_ENABLE="no";
- eval ${_UNSET} ms_lang;
- eval "${return_ok}";
- fi;
- _MAN_EXT="$(get_first_essential \
- "${_OPT_EXTENSION}" "${_MANOPT_EXTENSION}")";
- exit_test;
- eval ${_UNSET} ms_lang;
- eval "${return_ok}";
- } # man_setup()
- ########################################################################
- landmark '8: manpath_*()';
- ########################################################################
- ########################################################################
- # manpath_add_lang_sys ()
- #
- # Add language and operating system specific directories to man path.
- #
- # Arguments : 0
- # Output : none
- # Globals:
- # in: $_MAN_SYS: has the form `os1,os2,...', a comma separated
- # list of names of operating systems.
- # $_MAN_LANG and $_MAN_LANG2: each a single name
- # in/out: $_MAN_PATH: has the form `dir1:dir2:...', a colon
- # separated list of directories.
- #
- # Variable prefix: mals
- #
- manpath_add_lang_sys()
- {
- func_check manpath_add_lang_sys = 0 "$@";
- if obj _MAN_PATH is_empty
- then
- eval "${return_ok}";
- fi;
- # twice test both sys and lang
- eval set x "$(path_split "${_MAN_PATH}")";
- shift;
- exit_test;
- mals_mp='';
- for p
- do # loop on man path directories
- mals_mp="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
- exit_test;
- done;
- eval set x "$(path_split "${mals_mp}")";
- shift;
- exit_test;
- for p
- do # loop on man path directories
- mals_mp="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
- exit_test;
- done;
- _MAN_PATH="$(path_chop "${mals_mp}")";
- exit_test;
- eval ${_UNSET} mals_mp;
- eval "${return_ok}";
- }
- # To the directory in $1 append existing sys/lang subdirectories
- # Function is necessary to split the OS list.
- #
- # globals: in: $_MAN_SYS, $_MAN_LANG, $_MAN_LANG2
- # argument: 2: `man_path' and `dir'
- # output: colon-separated path of the retrieved subdirectories
- #
- # Variable prefix: _mals
- #
- _manpath_add_lang_sys_single()
- {
- func_check _manpath_add_lang_sys_single = 2 "$@";
- _mals_res="$1";
- _mals_parent="$2";
- eval set x "$(list_from_split "${_MAN_SYS}" ',')";
- shift;
- exit_test;
- for d in "$@" "${_MAN_LANG}" "${_MAN_LANG2}"
- do
- _mals_dir="$(dirname_append "${_mals_parent}" "$d")";
- exit_test;
- if obj _mals_res path_not_contains "${_mals_dir}" && \
- obj _mals_dir is_dir
- then
- _mals_res="${_mals_res}:${_mals_dir}";
- fi;
- done;
- if path_not_contains "${_mals_res}" "${_mals_parent}"
- then
- _mals_res="${_mals_res}:${_mals_parent}";
- fi;
- path_chop "${_mals_res}";
- eval ${_UNSET} _mals_dir;
- eval ${_UNSET} _mals_parent;
- eval ${_UNSET} _mals_res;
- eval "${return_ok}";
- }
- # end manpath_add_lang_sys ()
- ########################################################################
- # manpath_set_from_path ()
- #
- # Determine basic search path for man pages from $PATH.
- #
- # Return: `0' if a valid man path was retrieved.
- # Output: none
- # Globals:
- # in: $PATH
- # out: $_MAN_PATH
- #
- # Variable prefix: msfp
- #
- manpath_set_from_path()
- {
- func_check manpath_set_from_path = 0 "$@";
- msfp_manpath='';
- # get a basic man path from $PATH
- if obj PATH is_not_empty
- then
- eval set x "$(path_split "${PATH}")";
- shift;
- exit_test;
- for d
- do
- # delete the final `/bin' part
- msfp_base="$(echo1 "$d" | sed -e 's|//*bin/*$||')";
- exit_test;
- for e in /share/man /man
- do
- msfp_mandir="${msfp_base}$e";
- if test -d "${msfp_mandir}" && test -r "${msfp_mandir}"
- then
- msfp_manpath="${msfp_manpath}:${msfp_mandir}";
- fi;
- done;
- done;
- fi;
- # append some default directories
- for d in /usr/local/share/man /usr/local/man \
- /usr/share/man /usr/man \
- /usr/X11R6/man /usr/openwin/man \
- /opt/share/man /opt/man \
- /opt/gnome/man /opt/kde/man
- do
- msfp_d="$d";
- if obj msfp_manpath path_not_contains "${msfp_d}" && obj mfsp_d is_dir
- then
- msfp_manpath="${msfp_manpath}:${mfsp_d}";
- fi;
- done;
- _MAN_PATH="${msfp_manpath}";
- eval ${_UNSET} msfp_base;
- eval ${_UNSET} msfp_d;
- eval ${_UNSET} msfp_mandir;
- eval ${_UNSET} msfp_manpath;
- eval "${return_ok}";
- } # manpath_set_from_path()
- ########################################################################
- landmark '9: obj_*()';
- ########################################################################
- ########################################################################
- # obj (<object> <call_name> <arg>...)
- #
- # This works like a method (object function) call for an object.
- # Run "<call_name> $<object> <arg> ...".
- #
- # The first argument represents an object whose data is given as first
- # argument to <call_name>().
- #
- # Argument: >=2
- # <object>: variable name
- # <call_name>: a program or function name
- #
- # Variable prefix: o
- #
- obj()
- {
- func_check obj '>=' 2 "$@";
- eval o_arg1='"${'$1'}"';
- if is_empty "$2"
- then
- error "obj(): function name is empty."
- else
- o_func="$2";
- fi;
- shift;
- shift;
- eval "${o_func}"' "${o_arg1}" "$@"';
- n="$?";
- eval ${_UNSET} o_arg1;
- eval ${_UNSET} o_func;
- eval "${return_var} $n";
- } # obj()
- ########################################################################
- # obj_data (<object>)
- #
- # Print the data of <object>, i.e. the content of $<object>.
- # For possible later extensions.
- #
- # Arguments: 1
- # <object>: a variable name
- # Output: the data of <object>
- #
- # Variable prefix: od
- #
- obj_data()
- {
- func_check obj '=' 1 "$@";
- if is_empty "$1"
- then
- error "obj_data(): object name is empty."
- fi;
- eval od_res='"${'$1'}"';
- obj od_res echo1;
- eval ${_UNSET} od_res;
- eval "${return_ok}";
- }
- ########################################################################
- # obj_from_output (<object> <call_name> <arg>...)
- #
- # Run '$<object>="$(<call_name> <arg>...)"' to set the result of a
- # function call to a global variable.
- #
- # Arguments: >=2
- # <object>: a variable name
- # <call_name>: the name of a function or program
- # <arg>: optional argument to <call_name>
- # Output: none
- #
- # Variable prefix: ofo
- #
- obj_from_output()
- {
- func_check obj_from_output '>=' 2 "$@";
- if is_empty "$1"
- then
- error "res(): variable name is empty.";
- elif is_empty "$2"
- then
- error "res(): function name is empty."
- else
- ofo_result_name="$1";
- fi;
- shift;
- eval "${ofo_result_name}"'="$('"$@"')"';
- exit_test;
- eval "${return_ok}";
- }
- ########################################################################
- # obj_set (<object> <data>)
- #
- # Set the data of <object>, i.e. call "$<object>=<data>".
- #
- # Arguments: 2
- # <object>: a variable name
- # <data>: a string
- # Output:: none
- #
- obj_set()
- {
- func_check obj_set '=' 2 "$@";
- if is_empty "$1"
- then
- error "obj_set(): object name is empty."
- fi;
- eval "$1"='"$2"';
- eval "${return_ok}";
- }
- ########################################################################
- # path_chop (<path>)
- #
- # Remove unnecessary colons from path.
- #
- # Argument: 1, a colon separated path.
- # Output: path without leading, double, or trailing colons.
- #
- path_chop()
- {
- func_check path_chop = 1 "$@";
- # replace multiple colons by a single colon `:'
- # remove leading and trailing colons
- echo1 "$1" | sed -e '
- s/^:*//
- s/:::*/:/g
- s/:*$//
- ';
- eval "${return_ok}";
- }
- ########################################################################
- # path_clean (<path>)
- #
- # Remove non-existing directories from a colon-separated list.
- #
- # Argument: 1, a colon separated path.
- # Output: colon-separated list of existing directories.
- #
- # Variable prefix: pc
- #
- path_clean()
- {
- func_check path_clean = 1 "$@";
- if is_not_equal "$#" 1
- then
- error 'path_clean() needs 1 argument.';
- fi;
- pc_arg="$1";
- eval set x "$(path_split "${pc_arg}")";
- exit_test;
- shift;
- pc_res="";
- for i
- do
- pc_i="$i";
- if obj pc_i is_not_empty \
- && obj pc_res path_not_contains "${pc_i}" \
- && obj pc_i is_dir
- then
- case "${pc_i}" in
- ?*/)
- pc_res="${pc_res}$(dirname_chop "${pc_i}")";
- exit_test;
- ;;
- *)
- pc_res="${pc_res}:${pc_i}";
- exit_test;
- ;;
- esac;
- fi;
- done;
- eval ${_UNSET} pc_arg;
- eval ${_UNSET} pc_i;
- eval ${_UNSET} pc_res;
- if path_chop "${pc_res}"
- then
- eval "${return_ok}";
- else
- eval "${return_bad}";
- fi;
- }
- ########################################################################
- # path_contains (<path> <dir>)
- #-
- # Test whether `dir' is contained in `path', a list separated by `:'.
- #
- # Arguments : 2 arguments.
- # Return : `0' if arg2 is substring of arg1, `1' otherwise.
- #
- path_contains()
- {
- func_check path_contains = 2 "$@";
- case ":$1:" in
- *":$2:"*)
- eval "${return_yes}";
- ;;
- *)
- eval "${return_no}";
- ;;
- esac;
- eval "${return_ok}";
- }
- ########################################################################
- # path_not_contains (<path> <dir>)
- #
- # Test whether `dir' is not contained in colon separated `path'.
- #
- # Arguments : 2 arguments.
- #
- path_not_contains()
- {
- func_check path_not_contains = 2 "$@";
- if path_contains "$1" "$2"
- then
- eval "${return_no}";
- else
- eval "${return_yes}";
- fi;
- eval "${return_ok}";
- }
- ########################################################################
- # path_split (<path>)
- #
- # In `path' escape white space and replace each colon by a space.
- #
- # Arguments: 1: a colon-separated path
- # Output: the resulting list, process with `eval set'
- #
- path_split()
- {
- func_check path_split = 1 "$@";
- list_from_split "$1" ':';
- eval "${return_ok}";
- }
- ########################################################################
- landmark '10: register_*()';
- ########################################################################
- ########################################################################
- # register_file (<filename>)
- #
- # Write a found file and register the title element.
- #
- # Arguments: 1: a file name
- # Output: none
- #
- register_file()
- {
- func_check register_file = 1 "$@";
- if is_empty "$1"
- then
- error 'register_file(): file name is empty';
- fi;
- if is_equal "$1" '-'
- then
- to_tmp "${_TMP_STDIN}";
- register_title 'stdin';
- else
- to_tmp "$1";
- register_title "$(base_name "$1")";
- exit_test;
- fi;
- eval "${return_ok}";
- } # register_file()
- ########################################################################
- # register_title (<filespec>)
- #
- # Create title element from <filespec> and append to $_REGISTERED_TITLE
- #
- # Globals: $_REGISTERED_TITLE (rw)
- #
- # Variable prefix: rt
- #
- register_title()
- {
- func_check register_title '=' 1 "$@";
- if is_empty "$1"
- then
- eval "${return_ok}";
- fi;
- case "${_REGISTERED_TITLE}" in
- *\ *\ *\ *)
- eval "${return_ok}";
- ;;
- esac;
- # remove directory part
- rt_title="$(base_name "$1")";
- # replace space characters by `_'
- rt_title="$(echo1 "${rt_title}" | sed -e 's/[ ]/_/g')";
- # remove extension `.bz2'
- rt_title="$(echo1 "${rt_title}" | sed -e 's/\.bz2$//')";
- # remove extension `.gz'
- rt_title="$(echo1 "${rt_title}" | sed -e 's/\.gz$//')";
- # remove extension `.Z'
- rt_title="$(echo1 "${rt_title}" | sed -e 's/\.Z$//')";
- exit_test;
- if obj rt_title is_empty
- then
- eval ${_UNSET} rt_title;
- eval "${return_ok}";
- fi;
- if obj _REGISTERED_TITLE is_empty
- then
- _REGISTERED_TITLE="${rt_title}";
- else
- _REGISTERED_TITLE="${_REGISTERED_TITLE} ${rt_title}";
- fi;
- eval ${_UNSET} rt_title;
- eval "${return_ok}";
- } # register_title()
- ########################################################################
- # reset ()
- #
- # Reset the variables that can be affected by options to their default.
- #
- #
- # Defined in section `Preset' after the rudimentary shell tests.
- ########################################################################
- # 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
- then
- save_stdin()
- {
- func_check save_stdin '=' 0 "$@";
- ss_f="${_TMP_DIR}"/INPUT;
- cat >"${ss_f}";
- cat_z "${ss_f}" >"${_TMP_STDIN}";
- rm_file "${ss_f}";
- eval ${_UNSET} ss_f;
- eval "${return_ok}";
- }
- else
- save_stdin()
- {
- func_check save_stdin = 0 "$@";
- cat >"${_TMP_STDIN}";
- eval "${return_ok}";
- }
- fi;
- ########################################################################
- # special_filespec ()
- #
- # Handle special modes like whatis and apropos.
- #
- special_filespec()
- {
- func_check special_setup '=' 0 "$@";
- if obj _OPT_APROPOS is_yes
- then
- if obj _OPT_WHATIS is_yes
- then
- error \
- 'special_setup: $_OPT_APROPOS and $_OPT_WHATIS are both "yes"';
- fi;
- apropos_filespec;
- eval "${return_ok}";
- fi;
- if obj _OPT_WHATIS is_yes
- then
- whatis_filespec;
- fi;
- eval "${return_ok}";
- }
- ########################################################################
- # special_setup ()
- #
- # Handle special modes like whatis and apropos.
- #
- special_setup()
- {
- func_check special_setup '=' 0 "$@";
- if obj _OPT_APROPOS is_yes
- then
- if obj _OPT_WHATIS is_yes
- then
- error \
- 'special_setup: $_OPT_APROPOS and $_OPT_WHATIS are both "yes"';
- fi;
- apropos_setup;
- eval "${return_ok}";
- fi;
- if obj _OPT_WHATIS is_yes
- then
- whatis_header;
- fi;
- eval "${return_ok}";
- }
- ########################################################################
- landmark '11: stack_*()';
- ########################################################################
- ########################################################################
- # string_contains (<string> <part>)
- #
- # Test whether `part' is contained in `string'.
- #
- # Arguments : 2 text arguments.
- # Return : `0' if arg2 is substring of arg1, `1' otherwise.
- #
- string_contains()
- {
- func_check string_contains '=' 2 "$@";
- case "$1" in
- *"$2"*)
- eval "${return_yes}";
- ;;
- *)
- eval "${return_no}";
- ;;
- esac;
- eval "${return_ok}";
- }
- ########################################################################
- # string_not_contains (<string> <part>)
- #
- # Test whether `part' is not substring of `string'.
- #
- # Arguments : 2 text arguments.
- # Return : `0' if arg2 is substring of arg1, `1' otherwise.
- #
- string_not_contains()
- {
- func_check string_not_contains '=' 2 "$@";
- if string_contains "$1" "$2"
- then
- eval "${return_no}";
- else
- eval "${return_yes}";
- fi;
- eval "${return_ok}";
- }
- ########################################################################
- landmark '12: tmp_*()';
- ########################################################################
- ########################################################################
- # tmp_cat ()
- #
- # output the temporary cat file (the concatenation of all input)
- #
- tmp_cat()
- {
- func_check tmp_cat '=' 0 "$@";
- cat "${_TMP_CAT}";
- eval "${return_var}" "$?";
- }
- ########################################################################
- # tmp_create (<suffix>?)
- #
- # Create temporary file.
- #
- # It's safe to use the shell process ID together with a suffix to
- # have multiple temporary files.
- #
- # Globals: $_TMP_DIR
- #
- # Output : name of created file
- #
- # Variable prefix: tc
- #
- tmp_create()
- {
- func_check tmp_create '<=' 1 "$@";
- # the output file does not have `,' as first character, so these are
- # different names from the output file.
- tc_tmp="${_TMP_DIR}/,$1";
- : >"${tc_tmp}"
- obj tc_tmp echo1;
- eval ${_UNSET} tc_tmp;
- eval "${return_ok}";
- }
- ########################################################################
- # to_tmp (<filename>)
- #
- # print file (decompressed) to the temporary cat file
- #
- to_tmp()
- {
- func_check to_tmp '=' 1 "$@";
- if obj _TMP_CAT is_empty
- then
- error 'to_tmp_line: $_TMP_CAT is not yet set';
- fi;
- if is_file "$1"
- then
- if obj _OPT_LOCATION is_yes
- then
- echo2 "$1";
- fi;
- if obj _OPT_WHATIS is_yes
- then
- whatis_filename "$1" >>"${_TMP_CAT}";
- else
- cat_z "$1" >>"${_TMP_CAT}";
- fi;
- else
- error "to_tmp(): could not read file \`$1'.";
- fi;
- eval "${return_ok}";
- }
- ########################################################################
- # to_tmp_line ([<text>])
- #
- # print line to the temporary cat file
- #
- to_tmp_line()
- {
- func_check to_tmp '>=' 0 "$@";
- if obj _TMP_CAT is_empty
- then
- error 'to_tmp_line: $_TMP_CAT is not yet set';
- fi;
- echo1 "$*" >>"${_TMP_CAT}";
- eval "${return_ok}";
- }
- ########################################################################
- # trap_set
- #
- # call function on signal 0
- #
- trap_set()
- {
- func_check trap_set '=' 0 "$@";
- trap 'clean_up' 0 2>${_NULL_DEV} || :;
- eval "${return_ok}";
- }
- ########################################################################
- # trap_unset ()
- #
- # disable trap on signal 0.
- #
- trap_unset()
- {
- func_check trap_unset '=' 0 "$@";
- trap '' 0 2>${_NULL_DEV} || :;
- eval "${return_ok}";
- }
- ########################################################################
- # usage ()
- #
- # print usage information to stderr; for groffer option --help.
- #
- usage()
- {
- func_check usage = 0 "$@";
- echo;
- version;
- echo1 'Usage: groffer [option]... [filespec]...';
- cat <<EOF
- Display roff files, standard input, and/or Unix manual pages with a X
- Window viewer or in several text modes. All input is decompressed
- on-the-fly with all formats that gzip can handle.
- "filespec" is one of
- "filename" name of a readable file
- "-" for standard input
- "man:name.n" man page "name" in section "n"
- "man:name" man page "name" in first section found
- "name.n" man page "name" in section "n"
- "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 display with "gxditview" using groff -X.
- -Z --ditroff --intermediate-output
- 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-data=name
- "apropos" for "name" in man's data sections 4, 5, 7.
- --apropos-devel=name
- "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.
- --default-modes=mode1,mode2,...
- 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.
- --no-special disable --all, --apropos*, and --whatis
- --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 a 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.
- --whatis display the file name and description of man pages
- --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".
- Development options that are not useful for normal usage:
- --debug, --debug-all, --debug-keep, --debug-lm, --debug-params,
- --debug-shell, --debug-stacks, --debug-tmpdir, --debug-user,
- --do-nothing, --print=text
- Viewer programs for the different modes that run on the terminal:
- --dvi-viewer-tty=prog, --html-viewer-tty=prog, --pdf-viewer-tty=prog,
- --ps-viewer-tty=prog, --tty-viewer-tty, --X-viewer-tty=prog,
- --x-viewer-tty=prog, --www-viewer-tty=prog
- The usual X Windows toolkit options transformed into GNU long options:
- --background=color, --bd=size, --bg=color, --bordercolor=color,
- --borderwidth=size, --bw=size, --display=Xdisplay, --fg=color,
- --fn=font, --font=font, --foreground=color, --geometry=geom, --iconic,
- --resolution=dpi, --rv, --title=text, --xrm=resource
- Long options of GNU "man":
- --all, --ascii, --ditroff, --extension=suffix, --locale=language,
- --local-file=name, --location, --manpath=dir1:dir2:...,
- --sections=s1:s2:..., --systems=s1,s2,..., --where, ...
- EOF
- eval "${return_ok}";
- }
- ########################################################################
- # version ()
- #
- # print version information to stderr
- #
- version()
- {
- func_check version = 0 "$@";
- echo1 "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 /';
- eval "${return_ok}";
- }
- ########################################################################
- # warning (<string>)
- #
- # Print warning to stderr
- #
- warning()
- {
- echo2 "warning: $*";
- }
- ########################################################################
- # whatis_filename (<filename>)
- #
- # Interpret <filename> as a man page and display its `whatis'
- # information as a fragment written in the groff language.
- #
- # Variable prefix: wf
- #
- whatis_filename()
- {
- func_check whatis_filename = 1 "$@";
- wf_arg="$1";
- if obj wf_arg is_not_file
- then
- error "whatis_filename(): argument is not a readable file."
- fi;
- wf_dot='^\.'"${_SPACE_SED}"'*';
- if obj _FILESPEC_ARG is_equal '-'
- then
- wf_arg='stdin';
- fi;
- cat <<EOF
- \f[CR]${wf_arg}\f[]:
- .br
- EOF
- # get the parts of the file name
- wf_name="$(base_name $1)";
- wf_section="$(echo1 $1 | sed -n -e '
- s|^.*/man\('"${_MAN_AUTO_SEC_CHARS}"'\).*$|\1|p
- ')";
- if obj wf_section is_not_empty
- then
- case "${wf_name}" in
- *.${wf_section}*)
- s='yes';
- ;;
- *)
- s='';
- wf_section='';
- ;;
- esac
- if obj s is_yes
- then
- wf_name="$(echo1 ${wf_name} | sed -e '
- s/^\(.*\)\.'${wf_section}'.*$/\1/
- ')";
- fi;
- fi;
- # traditional man style; grep the line containing `.TH' macro, if any
- wf_res="$(cat_z "$1" | sed -e '
- /'"${wf_dot}"'TH /p
- d
- ')";
- exit_test;
- if obj wf_res is_not_empty
- then # traditional man style
- # get the first line after the first `.SH' macro, by
- # - delete up to first .SH;
- # - print all lines before the next .SH;
- # - quit.
- wf_res="$(cat_z "$1" | sed -n -e '
- 1,/'"${wf_dot}"'SH/d
- /'"${wf_dot}"'SH/q
- p
- ')";
- if obj wf_section is_not_empty
- then
- case "${wf_res}" in
- ${wf_name}${_SPACE_CASE}*-${_SPACE_CASE}*)
- s='yes';
- ;;
- *)
- s='';
- ;;
- esac;
- if obj s is_yes
- then
- wf_res="$(obj wf_res echo1 | sed -e '
- s/^'"${wf_name}${_SPACE_SED}"'[^-]*-'"${_SPACE_SED}"'*\(.*\)$/'"${wf_name}"' ('"${wf_section}"') \\[em] \1/
- ')";
- fi;
- fi;
- obj wf_res echo1;
- echo;
- eval ${_UNSET} wf_arg;
- eval ${_UNSET} wf_dot;
- eval ${_UNSET} wf_name;
- eval ${_UNSET} wf_res;
- eval ${_UNSET} wf_section;
- eval "${return_ok}";
- fi;
- # mdoc style (BSD doc); grep the line containing `.Nd' macro, if any
- wf_res="$(cat_z "$1" | sed -n -e '/'"${wf_dot}"'Nd /s///p')";
- exit_test;
- if obj wf_res is_not_empty
- then # BSD doc style
- if obj wf_section is_not_empty
- then
- wf_res="$(obj wf_res echo1 | sed -n -e '
- s/^\(.*\)$/'"${wf_name}"' ('"${wf_section}"') \\[em] \1/p
- ')";
- fi;
- obj wf_res echo1;
- echo;
- eval ${_UNSET} wf_arg;
- eval ${_UNSET} wf_dot;
- eval ${_UNSET} wf_name;
- eval ${_UNSET} wf_res;
- eval ${_UNSET} wf_section;
- eval "${return_ok}";
- fi;
- echo1 'is not a man page';
- echo;
- eval ${_UNSET} wf_arg;
- eval ${_UNSET} wf_dot;
- eval ${_UNSET} wf_name;
- eval ${_UNSET} wf_res;
- eval ${_UNSET} wf_section;
- eval "${return_bad}";
- }
- ########################################################################
- # whatis_filespec ()
- #
- # Print the filespec name as .SH to the temporary cat file.
- #
- whatis_filespec()
- {
- func_check whatis_filespec '=' 0 "$@";
- if obj _OPT_WHATIS is_yes
- then
- eval to_tmp_line \
- "'.SH $(echo1 "${_FILESPEC_ARG}" | sed 's/[^\\]-/\\-/g')'";
- exit_test;
- fi;
- eval "${return_ok}";
- }
- ########################################################################
- # whatis_header ()
- #
- # Print the whatis header to the temporary cat file.
- #
- whatis_header()
- {
- func_check whatis_header '=' 0 "$@";
- if obj _OPT_WHATIS is_yes
- then
- to_tmp_line '.TH GROFFER WHATIS';
- fi;
- eval "${return_ok}";
- }
- ########################################################################
- # where_is (<program>)
- #
- # Output path of a program if in $PATH.
- #
- # Arguments : >=1 (empty allowed)
- # more args are ignored, this allows to specify progs with arguments
- # Return : `0' if arg1 is a program in $PATH, `1' otherwise.
- #
- # Variable prefix: w
- #
- where_is()
- {
- func_check where_is '>=' 1 "$@";
- w_arg="$1";
- if obj w_arg is_empty
- then
- eval ${_UNSET} w_arg;
- eval "${return_bad}";
- fi;
- case "${w_arg}" in
- /*)
- eval ${_UNSET} w_arg;
- eval ${_UNSET} w_file;
- if test -f "${w_arg}" && test -x "${w_arg}"
- then
- eval "${return_ok}";
- else
- eval "${return_bad}";
- fi;
- ;;
- esac;
- eval set x "$(path_split "${PATH}")";
- exit_test;
- shift;
- for p
- do
- case "$p" in
- */) w_file=${p}${w_arg}; ;;
- *) w_file=${p}/${w_arg}; ;;
- esac;
- if test -f "${w_file}" && test -x "${w_file}"
- then
- obj w_file echo1;
- eval ${_UNSET} w_arg;
- eval ${_UNSET} w_file;
- eval "${return_ok}";
- fi;
- done;
- eval ${_UNSET} w_arg;
- eval ${_UNSET} w_file;
- eval "${return_bad}";
- }
- ########################################################################
- # main* Functions
- ########################################################################
- # The main area contains the following parts:
- # - main_init(): initialize temporary files and set exit trap
- # - main_parse_MANOPT(): parse $MANOPT
- # - main_parse_args(): argument parsing
- # - main_set_mode (): determine the display mode
- # - main_do_fileargs(): process filespec arguments
- # - main_set_resources(): setup X resources
- # - main_display(): do the displaying
- # - main(): the main function that calls all main_*()
- #######################################################################
- # main_init ()
- #
- # set exit trap and create temporary files
- #
- # Globals: $_TMP_DIR, $_TMP_CAT, $_TMP_STDIN
- #
- # Variable prefix: mi
- #
- main_init()
- {
- func_check main_init = 0 "$@";
- # call clean_up() on shell termination.
- trap_set;
- # create temporary directory
- umask 0022;
- _TMP_DIR='';
- for d in "${GROFF_TMPDIR}" "${TMPDIR}" "${TMP}" "${TEMP}" \
- "${TEMPDIR}" "${HOME}"'/tmp' '/tmp' "${HOME}" '.'
- do
- mi_dir="$d";
- if obj mi_dir is_empty || obj mi_dir is_not_dir || \
- obj mi_dir is_not_writable
- then
- continue;
- fi;
- case "${mi_dir}" in
- */)
- _TMP_DIR="${mi_dir}";
- ;;
- *)
- _TMP_DIR="${mi_dir}"'/';
- ;;
- esac;
- _TMP_DIR="${_TMP_DIR}groffer${_PROCESS_ID}";
- if obj _TMP_DIR rm_tree
- then
- :
- 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
- then
- obj _TMP_DIR rm_tree;
- _TMP_DIR='';
- continue;
- fi;
- if obj _TMP_DIR is_dir && obj _TMP_DIR is_writable
- then
- # $_TMP_DIR can now be used as temporary directory
- break;
- fi;
- obj _TMP_DIR rm_tree;
- _TMP_DIR='';
- continue;
- done;
- if obj _TMP_DIR is_empty
- then
- error "main_init: \
- Couldn't create a directory for storing temporary files.";
- fi;
- if obj _DEBUG_PRINT_TMPDIR is_yes
- then
- echo2 "temporary directory: ${_TMP_DIR}";
- fi;
- _TMP_CAT="$(tmp_create groffer_cat)";
- _TMP_STDIN="$(tmp_create groffer_input)";
- exit_test;
- eval ${_UNSET} mi_dir;
- eval ${_UNSET} mi_n;
- eval ${_UNSET} mi_tdir_;
- eval ${_UNSET} mi_tdir_n;
- eval "${return_ok}";
- } # main_init()
- ########################################################################
- # main_parse_MANOPT ()
- #
- # Parse $MANOPT to retrieve man options, but only if it is a non-empty
- # string; found man arguments can be overwritten by the command line.
- #
- # Globals:
- # in: $MANOPT, $_OPTS_MANOPT_*
- # out: $_MANOPT_*
- #
- # Variable prefix: mpm
- #
- main_parse_MANOPT()
- {
- func_check main_parse_MANOPT = 0 "$@";
- if obj MANOPT is_not_empty
- then
- # Delete leading and final spaces
- MANOPT="$(echo1 "${MANOPT}" | sed -e '
- s/^'"${_SPACE_SED}"'*//
- s/'"${_SPACE_SED}"'*$//
- ')";
- exit_test;
- fi;
- if obj MANOPT is_empty
- then
- 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}")";
- exit_test;
- shift;
- until test "$#" -le 0 || is_equal "$1" '--'
- do
- mpm_opt="$1";
- shift;
- case "${mpm_opt}" in
- -7|--ascii)
- list_append mpm_list '--ascii';
- ;;
- -a|--all)
- list_append mpm_list '--all';
- ;;
- -c|--catman)
- do_nothing;
- shift;
- ;;
- -d|--debug)
- do_nothing;
- ;;
- -D|--default)
- # undo all man options so far
- mpm_list='';
- ;;
- -e|--extension)
- list_append mpm_list '--extension';
- shift;
- ;;
- -f|--whatis)
- list_append mpm_list '--whatis';
- shift;
- ;;
- -h|--help)
- do_nothing;
- shift;
- ;;
- -k|--apropos)
- # groffer's --apropos takes an argument, but man's does not, so
- do_nothing;
- ;;
- -l|--local-file)
- do_nothing;
- ;;
- -L|--locale)
- list_append mpm_list '--locale' "$1";
- shift;
- ;;
- -m|--systems)
- list_append mpm_list '--systems' "$1";
- shift;
- ;;
- -M|--manpath)
- list_append mpm_list '--manpath' "$1";
- shift;
- ;;
- -p|--preprocessor)
- do_nothing;
- shift;
- ;;
- -P|--pager)
- list_append mpm_list '--pager' "$1";
- shift;
- ;;
- -r|--prompt)
- do_nothing;
- shift;
- ;;
- -S|--sections)
- list_append mpm_list '--sections' "$1";
- shift;
- ;;
- -t|--troff)
- do_nothing;
- shift;
- ;;
- -T|--device)
- list_append mpm_list '-T' "$1";
- shift;
- ;;
- -u|--update)
- do_nothing;
- shift;
- ;;
- -V|--version)
- do_nothing;
- ;;
- -w|--where|--location)
- list_append mpm_list '--location';
- ;;
- -Z|--ditroff)
- do_nothing;
- ;;
- # ignore all other options
- esac;
- done;
- # prepend $mpm_list to the command line
- if obj mpm_list is_not_empty
- then
- eval set x "${mpm_list}" '"$@"';
- shift;
- fi;
- eval ${_UNSET} mpm_list;
- eval ${_UNSET} mpm_opt;
- eval "${return_ok}";
- } # main_parse_MANOPT()
- ########################################################################
- # main_parse_args (<command_line_args>*)
- #
- # Parse arguments; process options and filespec parameters
- #
- # Arguments: pass the command line arguments unaltered.
- # Globals:
- # in: $_OPTS_*
- # out: $_OPT_*, $_ADDOPTS, $_FILEARGS
- #
- # Variable prefix: mpa
- #
- main_parse_args()
- {
- func_check main_parse_args '>=' 0 "$@";
- _ALL_PARAMS="$(list_from_cmdline _OPTS_CMDLINE "$@")";
- exit_test;
- 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
- # positional shell parameters ($1, $2, ...) are now guaranteed to
- # represent an option or an argument to the previous option, if any;
- # then a `--' argument for separating options and
- # parameters; followed by the filespec parameters if any.
- # 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" '--'
- do
- mpa_opt="$1"; # $mpa_opt is fed into the option handler
- shift;
- case "${mpa_opt}" in
- -h|--help)
- usage;
- leave;
- ;;
- -Q|--source) # output source code (`Quellcode').
- _OPT_MODE='source';
- ;;
- -T|--device|--troff-device) # device; arg
- _OPT_DEVICE="$1";
- _check_device_with_mode;
- shift;
- ;;
- -v|--version)
- version;
- leave;
- ;;
- -V)
- _OPT_V='yes';
- ;;
- -Z|--ditroff|--intermediate-output) # groff intermediate output
- _OPT_Z='yes';
- ;;
- -X)
- if is_X
- then
- _OPT_MODE=X;
- fi;
- ;;
- -?)
- # delete leading `-'
- mpa_optchar="$(echo1 "${mpa_opt}" | sed -e 's/^-//')";
- exit_test;
- 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}"
- then
- list_append _ADDOPTS_GROFF "${mpa_opt}" "$1";
- shift;
- else
- error "main_parse_args(): Unknown option : \`$1'";
- fi;
- ;;
- --all)
- _OPT_ALL='yes';
- ;;
- --apropos) # run `apropos'
- _OPT_APROPOS='yes';
- _APROPOS_SECTIONS='';
- _OPT_WHATIS='no';
- ;;
- --apropos-data) # run `apropos' for data sections
- _OPT_APROPOS='yes';
- _APROPOS_SECTIONS='457';
- _OPT_WHATIS='no';
- ;;
- --apropos-devel) # run `apropos' for development sections
- _OPT_APROPOS='yes';
- _APROPOS_SECTIONS='239';
- _OPT_WHATIS='no';
- ;;
- --apropos-progs) # run `apropos' for program sections
- _OPT_APROPOS='yes';
- _APROPOS_SECTIONS='168';
- _OPT_WHATIS='no';
- ;;
- --ascii)
- list_append _ADDOPTS_GROFF '-mtty-char';
- if obj _OPT_MODE is_empty
- then
- _OPT_MODE='text';
- fi;
- ;;
- --auto) # the default automatic mode
- _OPT_MODE='';
- ;;
- --bd) # border color for viewers, arg;
- _OPT_BD="$1";
- shift;
- ;;
- --bg|--backgroud) # background color for viewers, arg;
- _OPT_BG="$1";
- shift;
- ;;
- --bw) # border width for viewers, arg;
- _OPT_BW="$1";
- shift;
- ;;
- --debug|--debug-all|--debug-keep|--debug-lm|--debug-params|\
- --debug-shell|--debug-stacks|--debug-tmpdir|--debug-user)
- # debug is handled at the beginning
- :;
- ;;
- --default) # reset variables to default
- reset;
- ;;
- --default-modes) # sequence of modes in auto mode; arg
- _OPT_DEFAULT_MODES="$1";
- shift;
- ;;
- --display) # set X display, arg
- _OPT_DISPLAY="$1";
- shift;
- ;;
- --do-nothing)
- _OPT_DO_NOTHING='yes';
- ;;
- --dvi)
- if is_X
- then
- _OPT_MODE='dvi';
- fi;
- ;;
- --dvi-viewer) # viewer program for dvi mode; arg
- _VIEWER_TERMINAL='no';
- _OPT_VIEWER_DVI="$1";
- shift;
- ;;
- --dvi-viewer-tty) # viewer program for dvi mode in tty; arg
- _VIEWER_TERMINAL='yes';
- _OPT_VIEWER_DVI="$1";
- shift;
- ;;
- --extension) # the extension for man pages, arg
- _OPT_EXTENSION="$1";
- shift;
- ;;
- --fg|--foreground) # foreground color for viewers, arg;
- _OPT_FG="$1";
- shift;
- ;;
- --fn|--font) # set font for viewers, arg;
- _OPT_FN="$1";
- shift;
- ;;
- --geometry) # window geometry for viewers, arg;
- _OPT_GEOMETRY="$1";
- shift;
- ;;
- --groff)
- _OPT_MODE='groff';
- ;;
- --html|--www) # display with web browser
- _OPT_MODE=html;
- ;;
- --html-viewer|--www-viewer) # viewer program for html mode; arg
- _VIEWER_TERMINAL='no';
- _OPT_VIEWER_HTML="$1";
- shift;
- ;;
- --html-viewer-tty|--www-viewer-tty) # viewer for html mode in tty; arg
- _VIEWER_TERMINAL='yes';
- _OPT_VIEWER_HTML="$1";
- shift;
- ;;
- --iconic) # start viewers as icons
- _OPT_ICONIC='yes';
- ;;
- --locale) # set language for man pages, arg
- # argument is xx[_territory[.codeset[@modifier]]] (ISO 639,...)
- _OPT_LANG="$1";
- shift;
- ;;
- --local-file) # force local files; same as `--no-man'
- _MAN_FORCE='no';
- _MAN_ENABLE='no';
- ;;
- --location|--where) # print file locations to stderr
- _OPT_LOCATION='yes';
- ;;
- --man) # force all file params to be man pages
- _MAN_ENABLE='yes';
- _MAN_FORCE='yes';
- ;;
- --manpath) # specify search path for man pages, arg
- # arg is colon-separated list of directories
- _OPT_MANPATH="$1";
- shift;
- ;;
- --mode) # display mode
- mpa_arg="$1";
- shift;
- case "${mpa_arg}" in
- auto|'') # search mode automatically among default
- _OPT_MODE='';
- ;;
- groff) # pass input to plain groff
- _OPT_MODE='groff';
- ;;
- html|www) # display with a web browser
- _OPT_MODE='html';
- ;;
- dvi) # display with xdvi viewer
- if is_X
- then
- _OPT_MODE='dvi';
- fi;
- ;;
- pdf) # display with PDF viewer
- if is_X
- then
- _OPT_MODE='pdf';
- fi;
- ;;
- ps) # display with Postscript viewer
- if is_X
- then
- _OPT_MODE='ps';
- fi;
- ;;
- text) # output on terminal
- _OPT_MODE='text';
- ;;
- tty) # output on terminal
- _OPT_MODE='tty';
- ;;
- X|x) # output on X roff viewer
- if is_X
- then
- _OPT_MODE='x';
- fi;
- ;;
- Q|source) # display source code
- _OPT_MODE="source";
- ;;
- *)
- error "main_parse_args(): unknown mode ${mpa_arg}";
- ;;
- esac;
- ;;
- --no-location) # disable former call to `--location'
- _OPT_LOCATION='yes';
- ;;
- --no-man) # disable search for man pages
- # the same as --local-file
- _MAN_FORCE='no';
- _MAN_ENABLE='no';
- ;;
- --no-special) # disable some special former calls
- _OPT_ALL='no'
- _OPT_APROPOS='no'
- _OPT_WHATIS='no'
- ;;
- --pager|--tty-viewer|--tty-viewer-tty)
- # set paging program for tty mode, arg
- _VIEWER_TERMINAL='yes';
- _OPT_PAGER="$1";
- shift;
- ;;
- --pdf)
- if is_X
- then
- _OPT_MODE='pdf';
- fi;
- ;;
- --pdf-viewer) # viewer program for ps mode; arg
- _VIEWER_TERMINAL='no';
- _OPT_VIEWER_PDF="$1";
- shift;
- ;;
- --pdf-viewer-tty) # viewer program for ps mode in tty; arg
- _VIEWER_TERMINAL='yes';
- _OPT_VIEWER_PDF="$1";
- shift;
- ;;
- --print) # for argument test
- echo2 "$1";
- shift;
- ;;
- --ps)
- if is_X
- then
- _OPT_MODE='ps';
- fi;
- ;;
- --ps-viewer) # viewer program for ps mode; arg
- _VIEWER_TERMINAL='no';
- _OPT_VIEWER_PS="$1";
- shift;
- ;;
- --ps-viewer-tty) # viewer program for ps mode in tty; arg
- _VIEWER_TERMINAL='yes';
- _OPT_VIEWER_PS="$1";
- shift;
- ;;
- --resolution) # set resolution for X devices, arg
- mpa_arg="$1";
- shift;
- case "${mpa_arg}" in
- 75|75dpi)
- mpa_dpi=75;
- ;;
- 100|100dpi)
- mpa_dpi=100;
- ;;
- *)
- error "main_parse_args(): \
- only resoutions of 75 or 100 dpi are supported";
- ;;
- esac;
- _OPT_RESOLUTION="${mpa_dpi}";
- ;;
- --rv)
- _OPT_RV='yes';
- ;;
- --sections) # specify sections for man pages, arg
- # arg is colon-separated list of section names
- _OPT_SECTIONS="$1";
- shift;
- ;;
- --shell)
- # already done during the first run; so ignore the argument
- shift;
- ;;
- --systems) # man pages for different OS's, arg
- # argument is a comma-separated list
- _OPT_SYSTEMS="$1";
- shift;
- ;;
- --text) # text mode without pager
- _OPT_MODE=text;
- ;;
- --title) # title for X viewers; arg
- _OPT_TITLE="$1";
- shift;
- ;;
- --tty) # tty mode, text with pager
- _OPT_MODE=tty;
- ;;
- --text-device|--tty-device) # device for tty mode; arg
- _OPT_TEXT_DEVICE="$1";
- shift;
- ;;
- --whatis)
- _OPT_WHATIS='yes';
- _OPT_ALL='yes';
- _OPT_APROPOS='no';
- ;;
- --X|--x)
- if is_X
- then
- _OPT_MODE=x;
- fi;
- ;;
- --xrm) # pass X resource string, arg;
- list_append _OPT_XRM "$1";
- shift;
- ;;
- --x-viewer|--X-viewer) # viewer program for x mode; arg
- _VIEWER_TERMINAL='no';
- _OPT_VIEWER_X="$1";
- shift;
- ;;
- --x-viewer-tty|--X-viewer-tty) # viewer program for x mode in tty; arg
- _VIEWER_TERMINAL='yes';
- _OPT_VIEWER_X="$1";
- shift;
- ;;
- *)
- error 'main_parse_args(): error on argument parsing : '"\`$*'";
- ;;
- esac;
- done;
- shift; # remove `--' argument
- if obj _OPT_DO_NOTHING is_yes
- then
- leave;
- fi;
- # Remaining arguments are file names (filespecs).
- # Save them to list $_FILEARGS
- if is_equal "$#" 0
- then # use "-" for standard input
- set x '-';
- shift;
- fi;
- _FILEARGS='';
- list_append _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_dpi;
- eval ${_UNSET} mpa_opt;
- eval ${_UNSET} mpa_optchar;
- eval "${return_ok}";
- } # main_parse_args()
- # Called from main_parse_args() because double `case' is not possible.
- # Globals: $_OPT_DEVICE, $_OPT_MODE
- _check_device_with_mode()
- {
- func_check _check_device_with_mode = 0 "$@";
- case "${_OPT_DEVICE}" in
- dvi)
- _OPT_MODE=dvi;
- eval "${return_ok}";
- ;;
- html)
- _OPT_MODE=html;
- eval "${return_ok}";
- ;;
- lbp|lj4)
- _OPT_MODE=groff;
- eval "${return_ok}";
- ;;
- ps)
- _OPT_MODE=ps;
- eval "${return_ok}";
- ;;
- ascii|cp1047|latin1|utf8)
- if obj _OPT_MODE is_not_equal text
- then
- _OPT_MODE=tty; # default text mode
- fi;
- eval "${return_ok}";
- ;;
- X*)
- _OPT_MODE=x;
- eval "${return_ok}";
- ;;
- *) # unknown device, go to groff mode
- _OPT_MODE=groff;
- eval "${return_ok}";
- ;;
- esac;
- eval "${return_error}";
- } # _check_device_with_mode() of main_parse_args()
- ########################################################################
- # main_set_mode ()
- #
- # Determine the display mode.
- #
- # Globals:
- # in: $DISPLAY, $_OPT_MODE, $_OPT_DEVICE
- # out: $_DISPLAY_MODE
- #
- # Variable prefix: msm
- #
- main_set_mode()
- {
- func_check main_set_mode = 0 "$@";
- # set display
- if obj _OPT_DISPLAY is_not_empty
- then
- DISPLAY="${_OPT_DISPLAY}";
- fi;
- if obj _OPT_V is_yes
- then
- list_append _ADDOPTS_GROFF '-V';
- fi;
- if obj _OPT_Z is_yes
- then
- _DISPLAY_MODE='groff';
- list_append _ADDOPTS_GROFF '-Z';
- fi;
- if obj _OPT_MODE is_equal 'groff'
- then
- _DISPLAY_MODE='groff';
- fi;
- if obj _DISPLAY_MODE is_equal 'groff'
- then
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- fi;
- if obj _OPT_MODE is_equal 'source'
- then
- _DISPLAY_MODE='source';
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- fi;
- case "${_OPT_MODE}" in
- '') # automatic mode
- case "${_OPT_DEVICE}" in
- X*)
- if is_not_X
- then
- error_user "no X display found for device ${_OPT_DEVICE}";
- fi;
- _DISPLAY_MODE='x';
- 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'
- then
- _DISPLAY_MODE='tty';
- fi;
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- ;;
- esac;
- if is_not_X
- then
- _DISPLAY_MODE='tty';
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- fi;
- if obj _OPT_DEFAULT_MODES is_empty
- then
- msm_modes="${_DEFAULT_MODES}";
- else
- msm_modes="${_OPT_DEFAULT_MODES}";
- fi;
- ;;
- text)
- _DISPLAY_MODE='text';
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- ;;
- tty)
- _DISPLAY_MODE='tty';
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- ;;
- html)
- _DISPLAY_MODE='html';
- msm_modes="${_OPT_MODE}";
- ;;
- *) # display mode was given
- if is_not_X
- then
- error_user "You must be in X Window for ${_OPT_MODE} mode.";
- fi;
- msm_modes="${_OPT_MODE}";
- ;;
- esac;
- # only viewer modes are left
- eval set x "$(list_from_split "${msm_modes}" ',')";
- exit_test;
- shift;
- while test "$#" -gt 0
- do
- m="$1";
- shift;
- case "$m" in
- dvi)
- if obj _OPT_VIEWER_DVI is_not_empty
- then
- msm_viewer="${_OPT_VIEWER_DVI}";
- else
- msm_viewer="$(_get_first_prog "$_VIEWER_DVI}")";
- exit_test;
- fi;
- if obj msm_viewer is_empty
- then
- error 'No viewer for dvi mode available.';
- fi;
- if is_not_equal "$?" 0
- then
- continue;
- fi;
- _DISPLAY_PROG="${msm_viewer}";
- _DISPLAY_MODE="dvi";
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- ;;
- html)
- if obj _OPT_VIEWER_HTML is_not_empty
- then
- msm_viewer="${_OPT_VIEWER_HTML}";
- else
- if is_X
- then
- msm_viewers="${_VIEWER_HTML_X}";
- else
- msm_viewers="${_VIEWER_HTML_TTY}";
- fi;
- msm_viewer="$(_get_first_prog "${msm_viewers}")";
- exit_test;
- fi;
- if obj msm_viewer is_empty
- then
- error 'No viewer for html mode available.';
- fi;
- if is_not_equal "$?" 0
- then
- continue;
- fi;
- _DISPLAY_PROG="${msm_viewer}";
- _DISPLAY_MODE=html;
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- ;;
- pdf)
- if obj _OPT_VIEWER_PDF is_not_empty
- then
- msm_viewer="${_OPT_VIEWER_PDF}";
- else
- msm_viewer="$(_get_first_prog "${_VIEWER_PDF}")";
- exit_test;
- fi;
- if obj msm_viewer is_empty
- then
- error 'No viewer for pdf mode available.';
- fi;
- if is_not_equal "$?" 0
- then
- continue;
- fi;
- _DISPLAY_PROG="${msm_viewer}";
- _DISPLAY_MODE="pdf";
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- ;;
- ps)
- if obj _OPT_VIEWER_PS is_not_empty
- then
- msm_viewer="${_OPT_VIEWER_PS}";
- else
- msm_viewer="$(_get_first_prog "${_VIEWER_PS}")";
- exit_test;
- fi;
- if obj msm_viewer is_empty
- then
- error 'No viewer for ps mode available.';
- fi;
- if is_not_equal "$?" 0
- then
- continue;
- fi;
- _DISPLAY_PROG="${msm_viewer}";
- _DISPLAY_MODE="ps";
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- ;;
- text)
- _DISPLAY_MODE='text';
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- ;;
- tty)
- _DISPLAY_MODE='tty';
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- ;;
- x)
- if obj _OPT_VIEWER_X is_not_empty
- then
- msm_viewer="${_OPT_VIEWER_X}";
- else
- msm_viewer="$(_get_first_prog "${_VIEWER_X}")";
- exit_test;
- fi;
- if obj msm_viewer is_empty
- then
- error 'No viewer for x mode available.';
- fi;
- if is_not_equal "$?" 0
- then
- continue;
- fi;
- _DISPLAY_PROG="${msm_viewer}";
- _DISPLAY_MODE='x';
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- ;;
- X)
- _DISPLAY_MODE='X';
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- eval "${return_ok}";
- ;;
- esac;
- done;
- eval ${_UNSET} msm_modes;
- eval ${_UNSET} msm_viewer;
- eval ${_UNSET} msm_viewers;
- error_user "No suitable display mode found.";
- } # main_set_mode()
- # _get_first_prog (<proglist>)
- #
- # Retrieve first argument that represents an existing program in $PATH.
- # Local function for main_set_mode().
- #
- # Arguments: 1; a comma-separated list of commands (with options),
- # like $_VIEWER_*.
- #
- # Return : `1' if none found, `0' if found.
- # Output : the argument that succeded.
- #
- # Variable prefix: _gfp
- #
- _get_first_prog()
- {
- if is_equal "$#" 0
- then
- error "_get_first_prog() needs 1 argument.";
- fi;
- if is_empty "$1"
- then
- return "${_BAD}";
- fi;
- eval set x "$(list_from_split "$1" ',')";
- exit_test;
- shift;
- for i
- do
- _gfp_i="$i";
- if obj _gfp_i is_empty
- then
- continue;
- fi;
- if eval is_prog "$(get_first_essential ${_gfp_i})"
- then
- exit_test;
- obj _gfp_i echo1;
- eval ${_UNSET} _gfp_i;
- return "${_GOOD}";
- fi;
- done;
- eval ${_UNSET} _gfp_i;
- return "${_BAD}";
- } # _get_first_prog() of main_set_mode()
- #######################################################################
- # main_do_fileargs ()
- #
- # Process filespec arguments in $_FILEARGS.
- #
- # Globals:
- # in: $_FILEARGS (process with `eval set x "$_FILEARGS"; shift;')
- #
- # Variable prefix: mdfa
- #
- main_do_fileargs()
- {
- func_check main_do_fileargs = 0 "$@";
- special_setup;
- eval set x "${_FILEARGS}";
- shift;
- eval ${_UNSET} _FILEARGS;
- # temporary storage of all input to $_TMP_CAT
- while test "$#" -ge 2
- do
- # test for `s name' arguments, with `s' a 1-char standard section
- mdfa_filespec="$1";
- _FILESPEC_ARG="$1";
- shift;
- case "${mdfa_filespec}" in
- '')
- continue;
- ;;
- '-')
- special_filespec;
- if obj _OPT_APROPOS is_yes
- then
- continue;
- fi;
- register_file '-'
- continue;
- ;;
- ?)
- if obj _OPT_APROPOS is_yes
- then
- special_filespec;
- continue;
- fi;
- if list_has_not _MAN_AUTO_SEC_LIST "${mdfa_filespec}"
- then
- special_filespec;
- do_filearg "${mdfa_filespec}"
- continue;
- fi;
- mdfa_name="$1";
- _FILESPEC_ARG="${_FILESPEC_ARG} $1";
- special_filespec;
- case "${mdfa_name}" in
- */*|man:*|*\(*\)|*."${mdfa_filespec}")
- do_filearg "${mdfa_filespec}"
- continue;
- ;;
- esac;
- shift;
- if do_filearg "man:${mdfa_name}(${mdfa_filespec})"
- then
- continue;
- else
- do_filearg "${mdfa_filespec}"
- continue;
- fi;
- ;;
- *)
- special_filespec;
- if obj _OPT_APROPOS is_yes
- then
- continue;
- fi;
- do_filearg "${mdfa_filespec}"
- continue;
- ;;
- esac;
- done; # end of `s name' test
- while test "$#" -gt 0
- do
- mdfa_filespec="$1";
- _FILESPEC_ARG="$1";
- shift;
- special_filespec;
- if obj _OPT_APROPOS is_yes
- then
- continue;
- fi;
- do_filearg "${mdfa_filespec}"
- done;
- obj _TMP_STDIN rm_file_with_debug;
- eval ${_UNSET} mdfa_filespec;
- eval ${_UNSET} mdfa_name;
- eval "${return_ok}";
- } # main_do_fileargs()
- ########################################################################
- # main_set_resources ()
- #
- # Determine options for setting X resources with $_DISPLAY_PROG.
- #
- # Globals: $_DISPLAY_PROG, $_OUTPUT_FILE_NAME
- #
- # Variable prefix: msr
- #
- main_set_resources()
- {
- func_check main_set_resources = 0 "$@";
- # $msr_prog viewer program
- # $msr_rl resource list
- msr_title="$(get_first_essential \
- "${_OPT_TITLE}" "${_REGISTERED_TITLE}")";
- exit_test;
- _OUTPUT_FILE_NAME='';
- eval set x "${msr_title}";
- shift;
- until is_equal "$#" 0
- do
- msr_n="$1";
- case "${msr_n}" in
- '')
- continue;
- ;;
- ,*)
- msr_n="$(echo1 "$1" | sed -e 's/^,,*//')";
- exit_test;
- ;;
- esac
- if obj msr_n is_empty
- then
- continue;
- fi;
- if obj _OUTPUT_FILE_NAME is_not_empty
- then
- _OUTPUT_FILE_NAME="${_OUTPUT_FILE_NAME}"',';
- fi;
- _OUTPUT_FILE_NAME="${_OUTPUT_FILE_NAME}${msr_n}";
- shift;
- done;
- case "${_OUTPUT_FILE_NAME}" in
- '')
- _OUTPUT_FILE_NAME='-';
- ;;
- ,*)
- error "main_set_resources(): ${_OUTPUT_FILE_NAME} starts with a comma.";
- ;;
- esac;
- _OUTPUT_FILE_NAME="${_TMP_DIR}/${_OUTPUT_FILE_NAME}";
- if obj _DISPLAY_PROG is_empty
- then # for example, for groff mode
- _DISPLAY_ARGS='';
- eval ${_UNSET} msr_n;
- eval ${_UNSET} msr_prog;
- eval ${_UNSET} msr_rl;
- eval ${_UNSET} msr_title;
- eval "${return_ok}";
- fi;
- eval set x "${_DISPLAY_PROG}";
- shift;
- msr_prog="$(base_name "$1")";
- exit_test;
- 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
- then
- case "${msr_prog}" in
- ghostview|gv|gxditview|xditview|xdvi)
- list_append msr_rl '-bd' "${_OPT_BD}";
- ;;
- esac;
- fi;
- if obj _OPT_BG is_not_empty
- then
- case "${msr_prog}" in
- 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
- then
- case "${msr_prog}" in
- ghostview|gv|gxditview|xditview|xdvi)
- _list_append msr_rl '-bw' "${_OPT_BW}";
- ;;
- esac;
- fi;
- if obj _OPT_FG is_not_empty
- then
- case "${msr_prog}" in
- 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}"
- then
- case "${msr_prog}" in
- 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}"
- then
- case "${msr_prog}" in
- 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}"
- then
- _OPT_RESOLUTION="${_DEFAULT_RESOLUTION}";
- case "${msr_prog}" in
- gxditview|xditview)
- list_append msr_rl '-resolution' "${_DEFAULT_RESOLUTION}";
- ;;
- xpdf)
- case "${_DEFAULT_RESOLUTION}" in
- 75)
- # 72dpi is '100'
- list_append msr_rl '-z' '104';
- ;;
- 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}";
- ;;
- xpdf)
- case "${_OPT_RESOLUTION}" in
- 75)
- list_append msr_rl '-z' '104';
- # '100' corresponds to 72dpi
- ;;
- 100)
- list_append msr_rl '-z' '139';
- ;;
- esac;
- ;;
- esac;
- fi;
- if is_yes "${_OPT_ICONIC}"
- then
- case "${msr_prog}" in
- ghostview|gv|gxditview|xditview|xdvi)
- list_append msr_rl '-iconic';
- ;;
- esac;
- fi;
- if is_yes "${_OPT_RV}"
- then
- case "${msr_prog}" in
- ghostview|gv|gxditview|xditview|xdvi)
- list_append msr_rl '-rv';
- ;;
- esac;
- fi;
- 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;
- ;;
- esac;
- fi;
- if is_not_empty "${msr_title}"
- then
- case "${msr_prog}" in
- gxditview|xditview)
- list_append msr_rl '-title' "${msr_title}";
- ;;
- esac;
- fi;
- _DISPLAY_ARGS="${msr_rl}";
- eval ${_UNSET} msr_n;
- eval ${_UNSET} msr_prog;
- eval ${_UNSET} msr_rl;
- eval ${_UNSET} msr_title;
- eval "${return_ok}";
- } # main_set_resources
- ########################################################################
- # main_display ()
- #
- # Do the actual display of the whole thing.
- #
- # Globals:
- # in: $_DISPLAY_MODE, $_OPT_DEVICE,
- # $_ADDOPTS_GROFF, $_ADDOPTS_POST, $_ADDOPTS_X,
- # $_TMP_CAT, $_OPT_PAGER, $PAGER, $_MANOPT_PAGER,
- # $_OUTPUT_FILE_NAME
- #
- # Variable prefix: md
- #
- main_display()
- {
- func_check main_display = 0 "$@";
- export md_addopts;
- export md_groggy;
- export md_modefile;
- if obj _TMP_CAT is_non_empty_file
- then
- md_modefile="${_OUTPUT_FILE_NAME}";
- else
- 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
- then
- _ADDOPTS_GROFF="${_ADDOPTS_GROFF} -T${_OPT_DEVICE}";
- fi;
- md_groggy="$(tmp_cat | eval grog "${md_options}")";
- exit_test;
- _do_opt_V;
- obj md_modefile rm_file;
- mv "${_TMP_CAT}" "${md_modefile}";
- trap_unset;
- cat "${md_modefile}" | \
- {
- trap_set;
- eval "${md_groggy}" "${_ADDOPTS_GROFF}";
- } &
- ;;
- text|tty)
- case "${_OPT_DEVICE}" in
- '')
- md_device="$(get_first_essential \
- "${_OPT_TEXT_DEVICE}" "${_DEFAULT_TTY_DEVICE}")";
- exit_test;
- ;;
- ascii|cp1047|latin1|utf8)
- md_device="${_OPT_DEVICE}";
- ;;
- *)
- warning "main_display(): \
- wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
- ;;
- esac;
- md_addopts="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
- md_groggy="$(tmp_cat | grog -T${md_device})";
- exit_test;
- if obj _DISPLAY_MODE is_equal 'text'
- then
- _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}
- then # no "" for is_prog() allows args for $p
- md_pager="${md_p}";
- break;
- fi;
- done;
- if obj md_pager is_empty
- then
- error 'main_display(): no pager program found for tty mode';
- fi;
- _do_opt_V;
- tmp_cat | eval "${md_groggy}" "${md_addopts}" | \
- eval "${md_pager}";
- fi;
- clean_up;
- ;;
- source)
- tmp_cat;
- clean_up;
- ;;
- #### viewer modes
- dvi)
- case "${_OPT_DEVICE}" in
- ''|dvi) do_nothing; ;;
- *)
- warning "main_display(): \
- wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"
- ;;
- esac;
- md_modefile="${md_modefile}".dvi;
- md_groggy="$(tmp_cat | grog -Tdvi)";
- exit_test;
- _do_display;
- ;;
- html)
- case "${_OPT_DEVICE}" in
- ''|html) do_nothing; ;;
- *)
- warning "main_display(): \
- wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
- ;;
- esac;
- md_modefile="${md_modefile}".html;
- md_groggy="$(tmp_cat | grog -Thtml)";
- exit_test;
- _do_display;
- ;;
- pdf)
- case "${_OPT_DEVICE}" in
- ''|ps)
- do_nothing;
- ;;
- *)
- warning "main_display(): \
- wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
- ;;
- esac;
- md_groggy="$(tmp_cat | grog -Tps)";
- exit_test;
- _do_display _make_pdf;
- ;;
- ps)
- case "${_OPT_DEVICE}" in
- ''|ps)
- do_nothing;
- ;;
- *)
- warning "main_display(): \
- wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
- ;;
- esac;
- md_modefile="${md_modefile}".ps;
- md_groggy="$(tmp_cat | grog -Tps)";
- exit_test;
- _do_display;
- ;;
- x)
- case "${_OPT_DEVICE}" in
- X*)
- md_device="${_OPT_DEVICE}"
- ;;
- *)
- case "${_OPT_RESOLUTION}" in
- 100)
- md_device='X100';
- if obj _OPT_GEOMETRY is_empty
- then
- case "${_DISPLAY_PROG}" in
- gxditview|xditview)
- # add width of 800dpi for resolution of 100dpi to the args
- list_append _DISPLAY_ARGS '-geometry' '800';
- ;;
- esac;
- fi;
- ;;
- *)
- md_device='X75-12';
- ;;
- esac
- esac;
- md_groggy="$(tmp_cat | grog -T${md_device} -Z)";
- exit_test;
- _do_display;
- ;;
- X)
- case "${_OPT_DEVICE}" in
- '')
- md_groggy="$(tmp_cat | grog -X)";
- exit_test;
- ;;
- X*|dvi|html|lbp|lj4|ps)
- # these devices work with
- md_groggy="$(tmp_cat | grog -T"${_OPT_DEVICE}" -X)";
- exit_test;
- ;;
- *)
- warning "main_display(): \
- wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
- md_groggy="$(tmp_cat | grog -Z)";
- exit_test;
- ;;
- esac;
- _do_display;
- ;;
- *)
- error "main_display(): unknown mode \`${_DISPLAY_MODE}'";
- ;;
- esac;
- eval ${_UNSET} md_addopts;
- eval ${_UNSET} md_device;
- eval ${_UNSET} md_groggy;
- eval ${_UNSET} md_modefile;
- eval ${_UNSET} md_options;
- eval ${_UNSET} md_p;
- eval ${_UNSET} md_pager;
- eval "${return_ok}";
- } # 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 (actually only for `pdf').
- #
- # Globals: $md_modefile, $md_groggy (from main_display())
- #
- _do_display()
- {
- func_check _do_display '>=' 0 "$@";
- _do_opt_V;
- if obj _DISPLAY_PROG is_empty
- then
- trap_unset;
- {
- trap_set;
- eval "${md_groggy}" "${_ADDOPTS_GROFF}" "${_TMP_CAT}";
- } &
- else
- obj md_modefile rm_file;
- cat "${_TMP_CAT}" | \
- eval "${md_groggy}" "${_ADDOPTS_GROFF}" > "${md_modefile}";
- if is_not_empty "$1"
- then
- eval "$1";
- fi;
- obj _TMP_CAT rm_file_with_debug;
- if obj _VIEWER_TERMINAL is_yes # for programs that run on tty
- then
- eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
- else
- case "${_DISPLAY_PROG}" in
- # lynx\ *|less\ *|more\ *) # programs known to run on the terminal
- # eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
- # ;;
- *)
- trap_unset;
- {
- trap_set;
- eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
- } &
- ;;
- esac;
- fi;
- fi;
- 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';
- echo1 "Parameters: ${_ALL_PARAMS}";
- echo1 "Display mode: ${_DISPLAY_MODE}";
- echo1 "Output file: ${md_modefile}";
- echo1 "Display prog: ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
- a="$(eval echo1 "'${_ADDOPTS_GROFF}'")";
- exit_test;
- echo1 "Output of grog: ${md_groggy} $a";
- _doV_res="$(eval "${md_groggy}" "${_ADDOPTS_GROFF}")";
- exit_test;
- echo1 "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>*)
- #
- # The main function for groffer.
- #
- # Arguments:
- #
- 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}";
- }
- ########################################################################
- main "$@";