5855 lines
138 KiB
Bash
5855 lines
138 KiB
Bash
#! /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 "$@";
|