#! /bin/sh
# groffer - display groff files
# Source file position: /contrib/groffer/groffer2.sh
# Installed position: /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,2006
# Free Software Foundation, Inc.
# Written by Bernd Warken
# Last update: 5 Oct 2006
# 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 xTesTx \
| sed -n -e 's/^.\([Tt]e*x*sTT*\).*$/\1/p' \
| sed -e 's|T|t|g')"_ != _test_
then
echo 'The sed program did not work.' >&2;
exit "${_ERROR}";
fi;
########################################################################
# Test of `cat'.
#
if test _"$(echo test | cat)"_ != _test_
then
error 'Test of "cat" command failed.';
fi;
########################################################################
# Test of function definitions.
#
_t_e_s_t_f_u_n_c_()
{
return 0;
}
_test_func()
{
echo test;
}
if _t_e_s_t_f_u_n_c_ 2>${_NULL_DEV} && \
test _"$(_test_func 2>${_NULL_DEV})"_ = _test_
then
:;
else
echo 'Shell '"${_SHELL}"' does not support function definitions.' >&2;
exit "${_ERROR}";
fi;
########################################################################
# landmark ()
#
# Print to standard error as a debugging aid.
#
# Globals: $_DEBUG_LM
#
landmark()
{
if test _"${_DEBUG_LM}"_ = _yes_
then
echo "LM: $*" >&2;
fi;
} # landmark()
########################################################################
# test for compression.
#
export _HAS_COMPRESSION;
export _HAS_BZIP;
if test _"$(echo 'test' | gzip -c -d -f - 2>${_NULL_DEV})"_ = _test_
then
_HAS_COMPRESSION='yes';
if echo 'test' | bzip2 -c 2>${_NULL_DEV} | bzip2 -t 2>${_NULL_DEV} \
&& test _"$(echo 'test' | bzip2 -c 2>${_NULL_DEV} \
| bzip2 -d -c 2>${_NULL_DEV})"_ \
= _test_
then
_HAS_BZIP='yes';
else
_HAS_BZIP='no';
fi;
else
_HAS_COMPRESSION='no';
_HAS_BZIP='no';
fi;
########################################################################
# debug - diagnostic messages
########################################################################
export _DEBUG_FUNC_CHECK;
if test _"${_BEFORE_MAKE}"_ = _yes_
then
_DEBUG_FUNC_CHECK='yes';
else
_DEBUG_FUNC_CHECK='no';
fi;
_DEBUG_FUNC_CHECK='no'; # disable function checking
#_DEBUG_FUNC_CHECK='yes'; # enable function checking
export _DEBUG_STACKS;
_DEBUG_STACKS='no'; # disable stack output in each function
#_DEBUG_STACKS='yes'; # enable stack output in each function
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()
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_PRINT_FILENAMES;
_DEBUG_PRINT_FILENAMES='no'; # disable printing of the found file names
#_DEBUG_PRINT_FILENAMES='yes'; # enable printing of the found file names
# determine all --debug* options
case " $*" in
*\ --deb*|*\ --d*-*)
# --debug-* options
d=' --debug-all --debug-filenames --debug-func --debug-not-func '\
'--debug-keep --debug-lm --debug-params --debug-shell --debug-stacks '\
'--debug-tmpdir --debug-user ';
# non-debug options with scheme --d*-*
n=' --do-nothing --default-modes --dvi-viewer --dvi-viewer-tty ';
for i
do
case "$i" in
--deb|--debu|--debug)
_DEBUG_FUNC_CHECK='yes';
# _DEBUG_STACKS='yes';
_DEBUG_USER_WITH_STACK='yes';
# _DEBUG_LM='yes';
_DEBUG_KEEP_FILES='yes';
_DEBUG_PRINT_PARAMS='yes';
_DEBUG_PRINT_SHELL='yes';
_DEBUG_PRINT_TMPDIR='yes';
_DEBUG_PRINT_FILENAMES='yes';
continue;
;;
--d*-*)
# before `-'
b="$(echo x"$i" | sed -e 's/^x--\([^-]*\)-.*$/\1/')";
# after `-'
a="$(echo x"$i" | sed -e 's/^x--[^-]*-\(.*\)$/\1/')";
;;
*)
continue;
;;
esac;
case "$n" in
*\ --$b*-$a*)
continue;
;;
esac;
case "$d" in
*\ --$b*-$a*)
case "$a" in
f|s) # double --debug-* options
continue;
;;
esac;
# extract whole word of double abbreviation
s="$(cat <&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
########################################################################
landmark "1: 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 a single character.
# [a-z] local loop variables, e.g. $i
# In functions, other writings are used for variables. As some shells
# do not support the `local' command a unique prefix in lower case is
# constructed for each function, most are the abbreviation of the
# function name. All variable names start with this prefix.
# ${prefix}_[a-z_]* variable name in a function, e.g. $msm_modes
########################################################################
# read-only variables (global to this file)
########################################################################
# function return values; `0' means ok; other values are error codes
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="'pdf' 'html' 'ps' 'x' 'dvi' 'tty'";
export _DEFAULT_RESOLUTION;
_DEFAULT_RESOLUTION='75';
export _DEFAULT_TTY_DEVICE;
_DEFAULT_TTY_DEVICE='latin1';
# _VIEWER_* viewer programs for different modes constructed as lists
export _VIEWER_DVI_TTY; # viewer program for dvi mode in tty
export _VIEWER_DVI_X; # viewer program for dvi mode in X
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_TTY; # viewer program for pdf mode in tty
export _VIEWER_PDF_X; # viewer program for pdf mode in X
export _VIEWER_PS_TTY; # viewer program for ps mode in tty
export _VIEWER_PS_X; # viewer program for ps mode in X
export _VIEWER_TTY_TTY; # viewer program for X/x mode in tty
export _VIEWER_TTY_X; # viewer program for X/x mode in X
export _VIEWER_X_TTY; # viewer program for X/x mode in tty
export _VIEWER_X_X; # viewer program for X/x mode in X
_VIEWER_DVI_TTY="";
_VIEWER_DVI_X="'kdvi' 'xdvi' 'dvilx'";
_VIEWER_HTML_TTY="'lynx' 'w3m'";
_VIEWER_HTML_X="'konqueror' 'epiphany' 'mozilla-firefox' 'firefox' 'mozilla' \
'netscape' 'galeon' 'opera' 'amaya' 'arena' 'mosaic'";
_VIEWER_PDF_TTY="";
_VIEWER_PDF_X="'kpdf' 'acroread' 'evince' 'xpdf -z 150' 'gpdf' \
'kghostview --scale 1.45' 'ggv'";
_VIEWER_PS_TTY="";
_VIEWER_PS_X="'kpdf' 'kghostview --scale 1.45' 'evince' 'ggv' 'gv' \
'ghostview' 'gs_x11,gs'";
_VIEWER_TTY_TTY="'less -r -R' 'more' 'pager'";
_VIEWER_TTY_X="'xless'";
_VIEWER_X_TTY="";
_VIEWER_X_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="$$";
export _START_DIR; # directory at start time of the script
_START_DIR="$(pwd)";
############ the command line options of the involved programs
#
# The naming scheme for the options environment names is
# $_OPTS__[_]
#
# : program name GROFFER, GROFF, or CMDLINE (for all
# command line options)
# : LONG (long options) or SHORT (single character options)
# : ARG for options with argument, NA for no argument;
# without _ 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-filenames' \
'debug-func' 'debug-not-func' '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' 'to-stdout' 'text-device' 'tty' 'tty-device' \
'version' 'whatis' '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' 'k' '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' 'where'";
_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 _APROPOS_PROG; # Program to run apropos.
export _APROPOS_SECTIONS; # Sections for different --apropos-*.
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 _FILE_NR; # number for temporary `,file,*'
export _FILEARGS; # Stores filespec parameters.
export _FILESPEC_ARG; # Stores the actual filespec parameter.
export _FILESPEC_IS_MAN; # filespec is for searching a man page
export _FUNC_STACK; # Store debugging information.
export _MACRO_PACKAGES; # groff's macro packages.
export _MACRO_PKG; # Macro package for each found file.
export _NO_FILESPECS; # Yes, if there are no filespec arguments.
export _OUTPUT_FILE_NAME; # output generated, see main_set_res..()
export _REG_TITLE_LIST; # Processed file names.
export _SOELIM_R; # option -r for soelim
export _SPECIAL_FILESPEC; # Filespec ran for apropos or whatis.
export _SPECIAL_SETUP; # Test on setup for apropos or whatis.
export _VIEWER_BACKGROUND; # viewer shall be run in the background or not
# _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_PATH; # search path for man pages as a list
export _MAN_SEC; # sections for man pages; sep. `:'
export _MAN_SEC_CHARS; # sections for man pages as [] construct
export _MAN_SEC_LIST; # sections for man pages as a list
export _MAN_SYS; # system names for man pages as a list
# _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
# variables for mode pdf
export _PDF_DID_NOT_WORK;
export _PDF_HAS_GS;
export _PDF_HAS_PS2PDF;
# _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_EXTENSION; # set extension for man page search
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_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_STDOUT; # print mode file to standard output
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_HTML; # viewer program for html mode
export _OPT_VIEWER_PDF; # viewer program for pdf mode
export _OPT_VIEWER_PS; # viewer program for ps 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
# _TMP_* temporary directory and files
export _TMP_DIR; # groffer directory for temporary files
export _TMP_CAT; # stores concatenation of everything
export _TMP_MAN; # stores find of man path
export _TMP_MANSPEC; # filters man pages with filespec
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
########################################################################
# For variables that can be reset by option `--default', see reset().
_FILE_NR=0;
_FILEARGS='';
_MACRO_PACKAGES="'-man' '-mdoc' '-me' '-mm' '-mom' '-ms'";
_SPECIAL_FILESPEC='no';
_SPECIAL_SETUP='no';
# _TMP_* temporary files
_TMP_DIR='';
_TMP_CAT='';
_TMP_MAN='';
_TMP_CONF='';
_TMP_STDIN='';
# variables for mode pdf
_PDF_DID_NOT_WORK='no';
_PDF_HAS_GS='no';
_PDF_HAS_PS2PDF='no';
# option -r for soelim
if echo -n '' | soelim -r 2>${_NULL_DEV} >${_NULL_DEV}
then
_SOELIM_R='-r';
else
_SOELIM_R='';
fi;
########################################################################
# 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='';
_APROPOS_PROG='';
_APROPOS_SECTIONS='';
_DISPLAY_ARGS='';
_DISPLAY_MODE='';
_DISPLAY_PROG='';
_MACRO_PKG='';
_NO_FILESPECS='';
_REG_TITLE_LIST='';
# _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_CHARS='';
_MAN_SEC_LIST='';
_MAN_SYS='';
# _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_EXTENSION='';
_OPT_FG='';
_OPT_FN='';
_OPT_GEOMETRY='';
_OPT_ICONIC='no';
_OPT_LANG='';
_OPT_MODE='';
_OPT_MANPATH='';
_OPT_PAGER='';
_OPT_RESOLUTION='';
_OPT_RV='no';
_OPT_SECTIONS='';
_OPT_SYSTEMS='';
_OPT_STDOUT='no';
_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_BACKGROUND='no';
}
reset;
########################################################################
# Preliminary functions for error handling
########################################################################
landmark "2: preliminary functions";
# These functions do not have a func-check frame. Basically they could be
# moved to the functions in alphabetical order.
##############
# echo1 (*)
#
# Output to stdout with final line break.
#
# Arguments : arbitrary text including `-'.
#
echo1()
{
cat <*)
#
# Output to stderr with final line break.
#
# Arguments : arbitrary text including `-'.
#
echo2()
{
cat >&2 <"${_NULL_DEV}" 2>&1;
if test _${_DEBUG_KEEP_FILES}_ = _yes_
then
if test _"$cu_already"_ = _yes_
then
eval "${return_ok}";
fi;
cu_already=yes;
echo2 "Kept temporary directory ${_TMP_DIR}."
else
if test _"${_TMP_DIR}"_ != __
then
if test -e "${_TMP_DIR}"
then
rm -f -r "${_TMP_DIR}" >${_NULL_DEV} 2>&1;
fi;
fi;
fi;
eval "${return_ok}";
} # clean_up()
#############
# diag (text>*)
#
# Output a diagnostic message to stderr.
#
diag()
{
echo2 '>>>>>'"$*";
} # diag()
#############
# error (*)
#
# 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()
#############
# error_user (*)
#
# Print an error message to standard error; exit with an error condition.
# The error is supposed to be produced 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}";
} # error_user()
#############
# 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;
} # exit_test()
########################################################################
# Definition of normal Functions in alphabetical order
########################################################################
landmark "3: functions";
########################################################################
# apropos_filespec ()
#
# Compose temporary file for filspec.
#
# Globals: in: $_OPT_APROPOS, $_SPECIAL_SETUP, $_FILESPEC_ARG,
# $_APROPOS_PROG, $_APROPOS_SECTIONS, $_OPT_SECTIONS
# out: $_SPECIAL_FILESPEC
#
# Variable prefix: af
#
apropos_filespec()
{
func_check apropos_filespec '=' 0 "$@";
if obj _OPT_APROPOS is_yes
then
if obj _SPECIAL_SETUP is_not_yes
then
error 'apropos_filespec(): apropos_setup() must be run first.';
fi;
_SPECIAL_FILESPEC='yes';
if obj _NO_FILESPECS is_yes
then
to_tmp_line '.SH no filespec';
eval "${_APROPOS_PROG}" | sed -e 's/^/\\\&/' >>"${_TMP_CAT}";
eval "${return_ok}";
fi;
eval to_tmp_line \
"'.SH $(echo1 "${_FILESPEC_ARG}" | sed 's/[^\\]-/\\-/g')'";
exit_test;
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;
### apropos_filespec()
af_filespec="$(echo1 "${_FILESPEC_ARG}" | sed -e '
s,/,\\/,g
s/\./\\./g
')";
eval "${_APROPOS_PROG}" "'${_FILESPEC_ARG}'" | \
sed -n -e '
/^'"${af_filespec}"': /s/^\(.*\)$/\\\&\1/p
/'"$s"'/p
' | \
sort |\
sed -e '
s/^\(.*(..*).*\) *- *\(.*\)$/\.br\n\.TP 15\n\.BR \"\1\"\n\\\&\2/
' >>"${_TMP_CAT}";
eval ${_UNSET} af_filespec;
eval "${return_ok}";
else
eval "${return_bad}";
fi;
} # apropos_filespec()
########################################################################
# apropos_setup ()
#
# Setup for the --apropos* options, just 2 global variables are set.
#
# Globals: in: $_OPT_APROPOS
# out: $_SPECIAL_SETUP, $_APROPOS_PROG
#
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';
_SPECIAL_SETUP='yes';
if obj _OPT_TITLE is_empty
then
_OPT_TITLE='apropos';
fi;
eval "${return_ok}";
else
eval "${return_bad}";
fi;
} # apropos_setup()
########################################################################
# base_name ()
#
# Get the file name part of , i.e. delete everything up to last
# `/' from the beginning of . Remove final slashes, too, to get
# a non-empty output. The output is constructed according the shell
# program `basename'.
#
# 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}";
;;
/)
# this is like `basename' does
echo1 '/';
;;
*/*)
# 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}";
} # base_name()
########################################################################
# cat_z ()
#
# Decompress if possible or just print to standard output.
# gzip, bzip2, and .Z decompression is supported.
#
# Arguments: 1, a file name.
# Output: the content of , possibly decompressed.
#
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 is_file "$1"
then
:;
else
error 'cat_z(): argument $1 is not a file.';
fi;
if test -s "$1"
then
:;
else
eval "${return_ok}";
fi;
if obj _HAS_COMPRESSION is_yes
then
if obj _HAS_BZIP is_yes
then
# test whether being compressed with bz2
if bzip2 -t "$1" 2>${_NULL_DEV}
then
bzip2 -c -d "$1" 2>${_NULL_DEV};
eval "${return_ok}";
fi;
fi;
# if not compressed gzip acts like `cat'
gzip -c -d -f "$1" 2>${_NULL_DEV};
else
cat "$1";
fi;
eval "${return_ok}";
} # cat_z()
########################################################################
# clean_up ()
#
# Do the final cleaning up before exiting; used by the trap calls.
#
# defined above
########################################################################
# diag (*)
#
# Print marked message to standard error; useful for debugging.
#
# defined above
########################################################################
landmark '4: dir_name()*';
########################################################################
#######################################################################
# dir_name ()
#
# Get the directory name of . The output is constructed
# according to the shell program `dirname'.
#
# Arguments : 1
# Output : the directory part of
#
# Variable prefix: dn
#
dir_name()
{
func_check dir_name = 1 "$@";
obj_from_output dn_name dir_name_chop "$1";
case "${dn_name}" in
''|.)
echo1 '.';
;;
/)
echo1 '/';
;;
*/*)
echo1 "$(echo1 "${dn_name}" | sed 's#/*[^/][^/]*$##')";
;;
*)
echo1 "${dn_name}";
;;
esac;
eval "${return_ok}";
} # dir_name()
#######################################################################
# dir_name_append ()
#
# Append `name' to `dir' with clean handling of `/'.
#
# Arguments : 2
# Output : the generated new directory name /
#
dir_name_append()
{
func_check dir_name_append = 2 "$@";
if is_empty "$1"
then
echo1 "$2";
elif is_empty "$2"
then
echo1 "$1";
else
dir_name_chop "$1"/"$2";
fi;
eval "${return_ok}";
} # dir_name_append()
########################################################################
# dir_name_chop ()
#
# Remove unnecessary slashes from directory name.
#
# Argument: 1, a directory name.
# Output: path without double, or trailing slashes.
#
# Variable prefix: dc
#
dir_name_chop()
{
func_check dir_name_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}";
} # dir_name_chop()
########################################################################
# do_nothing ()
#
# Dummy function that does nothing.
#
do_nothing()
{
eval return "${_OK}";
} # do_nothing()
########################################################################
# echo1 (*)
#
# Print to standard output with final line break.
#
# defined above
########################################################################
# echo2 (*)
#
# Print to standard error with final line break.
#
# defined above
########################################################################
# error (*)
#
# Print error message and exit with error code.
#
# defined above
########################################################################
# exit_test ()
#
# Test whether the former command ended with error(). Exit again.
#
# defined above
if test _"${_DEBUG_FUNC_CHECK}"_ = _yes_
then
#############
# func_check ( "$@")
#
# This is called at the first line of each function. It checks the
# number of arguments of function and registers the
# function call to _FUNC_STACK.
#
# Arguments: >=3
# : name of the calling function.
# : a relational operator: = != < > <= >=
# : number of arguments to be checked against
# "$@": 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;
### func_check()
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';
;;
### func_check()
*)
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_check()
#############
# func_pop ()
#
# Retrieve the top element from the function stack. This is called
# by every return variable in each function.
#
# 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_pop()
#############
# func_push ()
#
# Store another element to the function stack. This is called by
# func_check() at the beginning of each function.
#
# The stack elements are separated by `!'; if 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_push()
#############
# func_stack_dump ()
#
# Print the content of the function stack. Ignore the arguments.
#
func_stack_dump()
{
diag 'call stack(): '"${_FUNC_STACK}";
} # func_stack_dump()
else # $_DEBUG_FUNC_CHECK is not `yes'
func_check() { return; }
func_pop() { return; }
func_push() { return; }
func_stack_dump() { return; }
fi; # test of $_DEBUG_FUNC_CHECK
########################################################################
# get_first_essential (*)
#
# 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}";
} # get_first_essential()
########################################################################
landmark '5: is_*()';
########################################################################
########################################################################
# is_dir ()
#
# Test whether `name' is a readable directory.
#
# Arguments : 1
# Return : `0' if arg1 is a directory, `1' otherwise.
#
is_dir()
{
func_check is_dir '=' 1 "$@";
if is_not_empty "$1" && test -d "$1" && test -r "$1"
then
eval "${return_yes}";
fi;
eval "${return_no}";
} # is_dir()
########################################################################
# is_empty ()
#
# Test whether 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_empty()
########################################################################
# is_empty_file ()
#
# Test whether is an empty existing file.
#
# Arguments : <=1
# Return :
# `0' if arg1 is an empty existing file
# `1' otherwise
#
is_empty_file()
{
func_check is_empty_file '=' 1 "$@";
if is_file "$1"
then
if test -s "$1"
then
eval "${return_no}";
else
eval "${return_yes}";
fi;
fi;
eval "${return_no}";
} # is_empty_file()
########################################################################
# is_equal ()
#
# Test whether is equal to .
#
# 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_equal()
########################################################################
# is_existing ()
#
# Test whether 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 is_empty "$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_existing()
########################################################################
# is_file ()
#
# Test whether 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_file()
########################################################################
# is_greater_than ()
#
# Test whether is greater than .
#
# Arguments : 2
# Return : `0' if is a greater integer than ,
# `1' otherwise.
#
is_greater_than()
{
func_check is_greater_than '=' 2 "$@";
if is_integer "$1" && is_integer "$2" && test "$1" -gt "$2"
then
eval "${return_yes}";
fi;
eval "${return_no}";
} # is_greater_than()
########################################################################
# is_integer ()
#
# Test whether `string' is an integer.
#
# Arguments : 1
# Return : `0' if argument is an integer, `1' otherwise.
#
is_integer()
{
func_check is_integer '=' 1 "$@";
if is_equal "$(echo1 "$1" | sed -n -e '
s/^[0-9][0-9]*$/ok/p
s/^[-+][0-9][0-9]*$/ok/p
')" 'ok'
then
eval "${return_yes}";
fi;
eval "${return_no}";
} # is_integer()
########################################################################
# is_not_empty_file ()
#
# Test whether is a non-empty existing file.
#
# Arguments : <=1
# Return :
# `0' if arg1 is a non-empty existing file
# `1' otherwise
#
is_not_empty_file()
{
func_check is_not_empty_file '=' 1 "$@";
if is_file "$1" && test -s "$1"
then
eval "${return_yes}";
fi;
eval "${return_no}";
} # is_not_empty_file()
########################################################################
# is_not_dir ()
#
# Test whether 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_dir()
########################################################################
# is_not_empty ()
#
# Test whether 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_empty()
########################################################################
# is_not_equal ()
#
# Test whether differs from .
#
# 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_equal()
########################################################################
# is_not_file ()
#
# Test whether 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_file()
########################################################################
# is_not_prog ()
#
# Verify that is not a command in $PATH.
#
# Arguments : 1, can have spaces and arguments.
#
is_not_prog()
{
func_check is_not_prog '=' 1 "$@";
if where_is_prog "$1" >${_NULL_DEV}
then
eval "${return_no}";
fi;
eval "${return_yes}";
} # is_not_prog()
########################################################################
# is_not_writable ()
#
# Test whether is 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_writable()
########################################################################
# is_not_X ()
#
# Test whether the script is not running in X Window by checking $DISPLAY.
#
is_not_X()
{
func_check is_not_X '=' 0 "$@";
if obj DISPLAY is_empty
then
eval "${return_yes}";
fi;
eval "${return_no}";
} # is_not_X()
########################################################################
# is_not_yes ()
#
# Test whether 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_not_yes()
########################################################################
# is_prog ()
#
# Determine whether is a program in $PATH.
#
# Arguments : 1, can have spaces and arguments.
#
is_prog()
{
func_check is_prog '=' 1 "$@";
if where_is_prog "$1" >${_NULL_DEV}
then
eval "${return_yes}";
fi;
eval "${return_no}";
} # is_prog()
########################################################################
# is_writable ()
#
# Test whether is a writable file or directory.
#
# Arguments : >=1 (empty allowed), more args are ignored
#
is_writable()
{
func_check is_writable '>=' 1 "$@";
if is_empty "$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_writable()
########################################################################
# is_X ()
#
# Test whether the script is 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_X()
########################################################################
# is_yes ()
#
# Test whether 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}";
} # is_yes()
########################################################################
# landmark ()
#
# Print debugging information on standard error if $_DEBUG_LM is `yes'.
#
# Globals: $_DEBUG_LM
#
# Defined in section `Debugging functions'.
########################################################################
# leave ([])
#
# Clean exit without an error or with error .
#
leave()
{
clean_up;
if test $# = 0
then
exit "${_OK}";
else
exit "$1";
fi;
} # leave()
########################################################################
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 (...)
#
# Add one or more elements to an existing list. may also be
# empty.
#
# Arguments: >=2
# : a variable name for a list of single-quoted elements
# : some sequence of characters.
# Output: none, but $ is set to
# if is empty: "'' '...'"
# otherwise: "$list '' ..."
#
# 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;
### list_append()
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_append()
########################################################################
# list_from_cmdline ( [...])
#
# 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
# : common part of a set of 4 environment variable names:
# $_SHORT_NA: list of short options without an arg.
# $_SHORT_ARG: list of short options that have an arg.
# $_LONG_NA: list of long options without an arg.
# $_LONG_ARG: list of long options that have an 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 f1 -bcarg --lon=larg f2 low larg2
# PRE_SHORT_NA="'a' 'b'"
# PRE_SHORT_ARG="'c' 'd'"
# PRE_LONG_NA="'help' 'version'"
# PRE_LONG_ARG="'longer' 'lower'"
# This will result in printing:
# '-a' '-b' '-c' 'arg' '--longer' 'larg' '--lower' 'larg2' '--' 'f1' 'f2'
#
# Use this function in the following way:
# eval set x "$(list_from_cmdline 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 "$@";
# short options, no argument
obj_from_output lfc_short_n obj_data "$1"_SHORT_NA;
# short options, with argument
obj_from_output lfc_short_a obj_data "$1"_SHORT_ARG;
# long options, no argument
obj_from_output lfc_long_n obj_data "$1"_LONG_NA;
# long options, with argument
obj_from_output lfc_long_a obj_data "$1"_LONG_ARG;
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;
### list_from_cmdline()
eval ${_UNSET} lfc_long_a;
eval ${_UNSET} lfc_long_n;
eval ${_UNSET} lfc_result;
eval "${return_ok}";
fi;
lfc_fparams='';
lfc_result='';
while is_greater_than "$#" 0
do
lfc_arg="$1";
shift;
case "${lfc_arg}" in
--) break; ;;
--*=*)
# delete leading '--';
lfc_with_equal="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
# extract option by deleting from the first '=' to the end
lfc_abbrev="$(echo1 "${lfc_with_equal}" | \
sed -e 's/^\([^=]*\)=.*$/\1/')";
obj_from_output lfc_opt \
list_single_from_abbrev lfc_long_a "${lfc_abbrev}";
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;
### list_from_cmdline()
;;
--*)
# delete leading '--';
lfc_abbrev="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
if list_has lfc_long_n "${lfc_abbrev}"
then
lfc_opt="${lfc_abbrev}";
else
obj_from_output lfc_opt \
list_single_from_abbrev lfc_long_n "${lfc_abbrev}";
if obj lfc_opt is_not_empty && is_not_equal "$#" 0
then
obj_from_output a \
list_single_from_abbrev lfc_long_a "${lfc_abbrev}";
if obj a is_not_empty
then
error_user "The abbreviation ${lfc_arg} \
has multiple options: --${lfc_opt} and --${a}.";
fi;
fi;
fi; # if list_has lfc_long_n "${lfc_abbrev}"
if obj lfc_opt is_not_empty
then
# long option, no argument
list_append lfc_result "--${lfc_opt}";
continue;
fi;
obj_from_output lfc_opt \
list_single_from_abbrev lfc_long_a "${lfc_abbrev}";
if obj lfc_opt is_not_empty
then
### list_from_cmdline()
# long option with argument
if is_equal "$#" 0
then
error_user "no argument for option --${lfc_opt}."
fi;
list_append lfc_result "--${lfc_opt}" "$1";
shift;
continue;
fi; # if obj lfc_opt is_not_empty
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 is_greater_than "$#" 0
then
### list_from_cmdline()
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; # if obj lfc_rest is_empty
else
error_user "unknown option -${lfc_optchar}.";
fi; # if list_has lfc_short_n "${lfc_optchar}"
done; # while obj lfc_rest is_not_empty
;;
*)
# 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; # case "${lfc_arg}" in
done; # while is_greater_than "$#" 0
list_append lfc_result '--';
if obj lfc_fparams is_not_empty
then
lfc_result="${lfc_result} ${lfc_fparams}";
fi;
### list_from_cmdline()
if is_greater_than "$#" 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_cmdline_with_minus ( [...])
#
# Transform command line arguments into a normalized form with a double
# abbreviation before and after an internal `-' sign.
#
# 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
# : common part of a set of 4 environment variable names:
# $_SHORT_NA: list of short options without an arg.
# $_SHORT_ARG: list of short options that have an arg.
# $_LONG_NA: list of long options without an arg.
# $_LONG_ARG: list of long options that have an 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 f1 -bcarg --lon=larg --h-n f2 low larg2
# PRE_SHORT_NA="'a' 'b'"
# PRE_SHORT_ARG="'c' 'd'"
# PRE_LONG_NA="'help' 'version' 'hi-non-arg'"
# PRE_LONG_ARG="'long-arg' 'low-arg'"
# This will result in printing:
# '-a' '-b' '-c' 'arg' '--long-arg' 'larg' '--hi-non-arg' \
# '--low-arg' 'larg2' '--' 'f1' 'f2'
#
# Use this function in the following way:
# eval set x "$(list_from_cmdline_with_minus 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: lfcwm
#
list_from_cmdline_with_minus()
{
func_check list_from_cmdline_with_minus '>=' 1 "$@";
# short options, no argument
obj_from_output lfcwm_short_n obj_data "$1"_SHORT_NA;
# short options, with argument
obj_from_output lfcwm_short_a obj_data "$1"_SHORT_ARG;
# long options, no argument
obj_from_output lfcwm_long_n obj_data "$1"_LONG_NA;
# long options, with argument
obj_from_output lfcwm_long_a obj_data "$1"_LONG_ARG;
if obj lfcwm_short_n is_empty
then
error 'list_from_cmdline(): no $'"$1"'_SHORT_NA options.';
fi;
if obj lfcwm_short_a is_empty
then
error 'list_from_cmdline(): no $'"$1"'_SHORT_ARG options.';
fi;
if obj lfcwm_long_n is_empty
then
error 'list_from_cmdline(): no $'"$1"'_LONG_NA options.';
fi;
if obj lfcwm_long_a is_empty
then
error 'list_from_cmdline(): no $'"$1"'_LONG_ARG options.';
fi;
shift;
if is_equal "$#" 0
then
echo1 "'--'";
eval ${_UNSET} lfcwm_short_a;
eval ${_UNSET} lfcwm_short_n;
### list_from_cmdline_with_minus()
eval ${_UNSET} lfcwm_long_a;
eval ${_UNSET} lfcwm_long_n;
eval "${return_ok}";
fi;
obj_from_output lfcwm_long_both lists_combine lfcwm_long_a lfcwm_long_n;
lfcwm_fparams='';
lfcwm_result='';
while is_greater_than "$#" 0 # command line arguments
do
lfcwm_arg="$1";
shift;
lfcwm_optarg='';
case "${lfcwm_arg}" in
--)
break;
;;
--*=*)
# delete leading '--';
lfcwm_with_equal="$(echo1 "${lfcwm_arg}" | sed -e 's/^--//')";
# extract option by deleting from the first '=' to the end
lfcwm_abbrev="$(echo1 "${lfcwm_with_equal}" | \
sed -e 's/^\([^=]*\)=.*$/\1/')";
# extract option argument by deleting up to the first '='
lfcwm_optarg="$(echo1 "${lfcwm_with_equal}" | \
sed -e 's/^[^=]*=\(.*\)$/\1/')";
### list_from_cmdline_with_minus()
if list_has lfcwm_long_a "${lfcwm_abbrev}"
then
lfcwm_opt="${lfcwm_abbrev}";
else
obj_from_output lfcwm_opt \
_search_abbrev lfcwm_long_a "${lfcwm_abbrev}";
fi;
list_append lfcwm_result "--${lfcwm_opt}" "${lfcwm_optarg}";
continue;
;;
--*)
# delete leading '--';
lfcwm_abbrev="$(echo1 "${lfcwm_arg}" | sed -e 's/^--//')";
if list_has lfcwm_long_both "${lfcwm_abbrev}"
then
lfcwm_opt="${lfcwm_abbrev}";
else
obj_from_output lfcwm_opt \
_search_abbrev lfcwm_long_both "${lfcwm_abbrev}";
fi;
### list_from_cmdline_with_minus()
if list_has lfcwm_long_a "${lfcwm_opt}"
then
if is_equal "$#" 0
then
error_user "Option ${lfcwm_opt} needs an argument.";
fi;
lfcwm_optarg="$1";
shift;
list_append lfcwm_result "--${lfcwm_opt}" "${lfcwm_optarg}";
else
list_append lfcwm_result "--${lfcwm_opt}";
fi;
continue;
;;
-?*) # short option (cluster)
# delete leading '-';
lfcwm_rest="$(echo1 "${lfcwm_arg}" | sed -e 's/^-//')";
while obj lfcwm_rest is_not_empty
do
# get next short option from cluster (first char of $lfcwm_rest)
lfcwm_optchar="$(echo1 "${lfcwm_rest}" | sed -e 's/^\(.\).*$/\1/')";
# remove first character from ${lfcwm_rest};
lfcwm_rest="$(echo1 "${lfcwm_rest}" | sed -e 's/^.//')";
if list_has lfcwm_short_n "${lfcwm_optchar}"
then
list_append lfcwm_result "-${lfcwm_optchar}";
continue;
elif list_has lfcwm_short_a "${lfcwm_optchar}"
then
if obj lfcwm_rest is_empty
then
if is_greater_than "$#" 0
then
### list_from_cmdline_with_minus()
list_append lfcwm_result "-${lfcwm_optchar}" "$1";
shift;
continue;
else
error_user "no argument for option -${lfcwm_optchar}.";
fi;
else # rest is the argument
list_append lfcwm_result "-${lfcwm_optchar}" "${lfcwm_rest}";
lfcwm_rest='';
continue;
fi; # if obj lfcwm_rest is_empty
else
error_user "unknown option -${lfcwm_optchar}.";
fi; # if list_has lfcwm_short_n "${lfcwm_optchar}"
done; # while obj lfcwm_rest is_not_empty
;;
*)
# Here, $lfcwm_arg is not an option, so a file parameter.
list_append lfcwm_fparams "${lfcwm_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 lfcwm_result '--';
if obj lfcwm_fparams is_not_empty
then
lfcwm_result="${lfcwm_result} ${lfcwm_fparams}";
fi;
### list_from_cmdline_with_minus()
if is_greater_than "$#" 0
then
list_append lfcwm_result "$@";
fi;
obj lfcwm_result echo1;
eval ${_UNSET} lfcwm_abbrev;
eval ${_UNSET} lfcwm_fparams;
eval ${_UNSET} lfcwm_short_a;
eval ${_UNSET} lfcwm_short_n;
eval ${_UNSET} lfcwm_long_a;
eval ${_UNSET} lfcwm_long_both;
eval ${_UNSET} lfcwm_long_n;
eval ${_UNSET} lfcwm_result;
eval ${_UNSET} lfcwm_arg;
eval ${_UNSET} lfcwm_opt;
eval ${_UNSET} lfcwm_optarg;
eval ${_UNSET} lfcwm_optchar;
eval ${_UNSET} lfcwm_with_equal;
eval ${_UNSET} lfcwm_rest;
eval "${return_ok}";
} # list_from_cmdline_with_minus()
# _search_abbrev ()
#
# Check whether has an element constructed from the abbreviation
# . All `-' in are replaced by `-*'. This construction
# is searched first with `[^-]*'. If there is more than a
# single element an error is created. If none is found `*'
# is searched. Again an error is created for several results.
# This function was constructed from the former function
# list_single_from_abbrev().
#
# This is a local function of list_from_cmdline_with_minus().
#
# Arguments: 2
# : a variable name for a list of single-quoted elements
# : some sequence of characters.
#
# Output: the found element (always not empty), error when none found.
#
# Variable prefix: _sa
#
_search_abbrev()
{
func_check _search_abbrev '=' 2 "$@";
eval _sa_list='"${'$1'}"';
if obj _sa_list is_empty
then
error "_search_abbrev(): list is empty.";
fi;
_sa_abbrev="$2";
if obj _sa_abbrev is_empty
then
error "_search_abbrev(): abbreviation argument is empty.";
fi;
_sa_case="$(echo1 "${_sa_abbrev}" | sed -e 's/-/\*-/g')";
_sa_opt='';
case " ${_sa_list}" in
*\ \'${_sa_case}*) # list has the abbreviation
_sa_m1='';
_sa_m2='';
_sa_nm='';
eval set x "${_sa_list}";
shift;
for i # over the option list
do
_sa_i="$i";
### _search_abbrev() of list_from_cmdline_with_minus()
case "${_sa_i}" in
${_sa_case}*-*)
if obj _sa_m1 is_empty
then
_sa_m1="${_sa_i}";
continue;
fi;
_sa_m2="${_sa_i}";
continue;
;;
${_sa_case}*)
if obj _sa_nm is_empty
then
_sa_nm="${_sa_i}";
continue;
fi;
error_user "The abbreviation --${_sa_abbrev} has multiple options "\
"--${_sa_nm} and --${_sa_i}.";
;;
esac;
done;
if obj _sa_nm is_empty
then
if obj _sa_m2 is_not_empty
then
error_user "The abbreviation --${_sa_abbrev} has multiple options "\
"--${_sa_m1} and --${_sa_m2}.";
fi;
### _search_abbrev() of list_from_cmdline_with_minus()
if obj _sa_m1 is_not_empty
then
_sa_opt="${_sa_m1}";
fi;
else
_sa_opt="${_sa_nm}";
fi;
;;
esac;
if obj _sa_opt is_empty
then
error_user "--${_sa_abbrev} is not an option.";
fi;
obj _sa_opt echo1;
eval "${_UNSET}" _sa_abbrev;
eval "${_UNSET}" _sa_case;
eval "${_UNSET}" _sa_i;
eval "${_UNSET}" _sa_list;
eval "${_UNSET}" _sa_m1;
eval "${_UNSET}" _sa_m2;
eval "${_UNSET}" _sa_nm;
eval "${_UNSET}" _sa_opt;
eval "${return_ok}";
} # _search_abbrev() of list_from_cmdline_with_minus()
########################################################################
# list_from_file ()
#
# Extrect the lines from and store them as elements to list
# .
#
# Arguments: 2
# : a variable name for output, a list of single-quoted elts
# : the name of an existing file
#
# Variable prefix: lff
#
list_from_file()
{
func_check list_from_file '=' 2 "$@";
if is_not_file "$2"
then
eval "${return_bad}";
fi;
lff_n="$(wc -l "$2" | eval sed -e "'s/^[ ${_TAB}]*\([0-9]\+\).*$/\1/'")";
eval "$1"="''";
if obj lff_n is_equal 0
then
eval "${return_good}";
fi;
lff_i=0;
while obj lff_i is_not_equal "${lff_n}"
do
lff_i="$(expr "${lff_i}" + 1)";
list_append "$1" "$(eval sed -n -e "'${lff_i}p
${lff_i}q'" "'$2'")";
done;
eval "${_UNSET}" lff_i;
eval "${_UNSET}" lff_n;
eval "${return_good}";
} # list_from_file()
########################################################################
# list_from_split ()
#
# Split by into a list, omitting the separator.
#
# Arguments: 2: a that is to be split into parts divided by
# character
# Output: the resulting list string
#
# Variable prefix: lfs
#
list_from_split()
{
func_check list_from_split = 2 "$@";
if is_empty "$1"
then
eval "${return_ok}";
fi;
case "$2" in
?)
lfs_splitter="$2";
;;
'\:')
lfs_splitter=':';
;;
*)
error "list_from_split(): split argument $2 must be a single character.";
;;
esac;
lfs_list='';
lfs_rest="$1";
while :
do
case "${lfs_rest}" in
*${lfs_splitter}*)
case "${lfs_splitter}" in
/)
lfs_elt="$(echo1 ${lfs_rest} | sed -e \
's|^\([^'"${lfs_splitter}"']*\)'"${lfs_splitter}"'.*|\1|')";
lfs_rest="$(echo1 ${lfs_rest} | sed -e \
's|^[^'"${lfs_splitter}"']*'"${lfs_splitter}"'\(.*\)$|\1|')";
;;
*)
### list_from_split()
lfs_elt="$(echo1 ${lfs_rest} | sed -e \
's/^\([^'"${lfs_splitter}"']*\)'"${lfs_splitter}"'.*/\1/')";
lfs_rest="$(echo1 ${lfs_rest} | sed -e \
's/^[^'"${lfs_splitter}"']*'"${lfs_splitter}"'\(.*\)$/\1/')";
;;
esac;
list_append lfs_list "${lfs_elt}"
continue;
;;
*)
list_append lfs_list "${lfs_rest}"
break
;;
esac;
done
echo1 "${lfs_list}";
eval ${_UNSET} lfs_elt;
eval ${_UNSET} lfs_list;
eval ${_UNSET} lfs_rest;
eval ${_UNSET} lfs_splitter;
eval "${return_ok}";
} # list_from_split()
########################################################################
# list_has ()
#
# Test whether the list has the element .
#
# Arguments: 2
# : a variable name for a list of single-quoted elements
# : 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()
########################################################################
# list_has_abbrev ()
#
# Test whether the list of has an element starting with
# .
#
# Arguments: 2
# : a variable name for a list of single-quoted elements
# : some sequence of characters.
#
# Variable prefix: lha
#
list_has_abbrev()
{
func_check list_has_abbrev '=' 2 "$@";
eval lha_list='"${'$1'}"';
if obj lha_list is_empty
then
eval "${_UNSET}" lha_list;
eval "${return_no}";
fi;
case "$2" in
\'*)
lha_element="$(echo1 "$2" | sed -e 's/'"${_SQ}"'$//')";
;;
*)
lha_element="'$2";
;;
esac;
if string_contains " ${lha_list}" " ${lha_element}"
then
eval "${_UNSET}" lha_list;
eval "${_UNSET}" lha_element;
eval "${return_yes}";
else
eval "${_UNSET}" lha_list;
eval "${_UNSET}" lha_element;
eval "${return_no}";
fi;
eval "${return_ok}";
} # list_has_abbrev()
########################################################################
# list_has_not ()
#
# Test whether has no .
#
# Arguments: 2
# : a space-separated list of single-quoted elements.
# : 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_has_not()
########################################################################
# list_single_from_abbrev ()
#
# Check whether the list has an element starting with . If
# there are more than a single element an error is raised.
#
# Arguments: 2
# : a variable name for a list of single-quoted elements
# : 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;
### list_single_from_abbrev()
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;
} # list_single_from_abbrev()
########################################################################
# list_uniq ()
#
# Generate a list with only unique elements.
#
# Output: the corrected list
#
# Variable prefix: lu
#
list_uniq()
{
func_check list_uniq '=' 1 "$@";
if is_empty "$1"
then
eval "${return_ok}";
fi;
eval a='"${'"$1"'}"';
if obj a is_empty
then
eval "${return_ok}";
fi;
eval set x "$a";
shift;
lu_list='';
for i
do
lu_i="$i";
if list_has lu_list "${lu_i}"
then
continue;
else
list_append lu_list ${lu_i};
fi;
done;
obj lu_list echo1;
eval "${_UNSET}" lu_i;
eval "${_UNSET}" lu_list;
eval "${return_ok}";
} # list_uniq()
########################################################################
# lists_combine ( ...)
#
# Combine several lists to a single list. All arguments are list names.
#
# Output: the combined list
#
# Variable prefix: lc
#
lists_combine()
{
func_check lists_combine '>=' 2 "$@";
lc_list='';
for i
do
eval lc_arg='"${'"$i"'}"';
case "${lc_arg}" in
'') :; ;;
"'"*"'")
if obj lc_list is_empty
then
lc_list="${lc_arg}";
else
lc_list="${lc_list} ${lc_arg}";
fi;
;;
*)
error 'lists_combine(): $'"$i"' is not a list.';
;;
esac;
done;
obj lc_list echo1;
eval "${_UNSET}" lc_arg;
eval "${_UNSET}" lc_list;
eval "${return_ok}";
} # lists_combine()
########################################################################
landmark '7: man_*()';
########################################################################
########################################################################
# Information on the search of man pages in groffer
# The search of man pages is based on a set of directories. That
# starts with the so-called man path. This is determined in function
# man_setup() either by the command-line option --manpath, by $MANOPT,
# or by $MANPATH. There is also a program `manpath'. If all of this
# does not work a man path is created from $PATH with function
# manpath_set_from_path(). We now have a set of existing directories
# for the search of man pages; usually they end with `/man'.
# The directory set of the man path can be changed in 2 ways. If
# operating system names are given in $SYSTEM or by --systems on the
# command-line all man path directory will be appended by these names.
# The appended system names replace the original man path; but if no
# system name is set, the original man path is kept. In `groffer',
# this is done by the function manpath_add_lang_sys() in man_setup().
# The next addition for directories is the language. It is specified
# by --locale or by one of the environment variables $LC_ALL,
# $LC_MESSAGES, and $LANG. The language name of `C' or `POSIX' means
# the return to the default language (usually English); this deletes
# former language specifications. The language name and its
# abbreviation with 2 characters is appended to the man page
# directories. But these new arising directories are added to the man
# page, they do not replace it such as the system names did. This is
# done by function manpath_add_lang_sys() in man_setup() as well.
# Now we have the basic set of directories for the search of man pages
# for given filespec arguments. The real directories with the man
# page source files are gotten by appending `man' to each
# directory, where section is a single character of the form
# `[1-9on]'.
# There you find files named according to the form
# .[][], where `[]' means
# optional this time. is the name of the man page;
# is the single character from the last paragraphe; the optional
# consists of some letters denoting special aspects for
# the section; and the optional is something like `.gz',
# `.Z', or `.bz2', meaning that the file is compressed.
# If name, section. and extension are specified on the command-line
# the file of the form . with or without
# are handled. The first one found according to the
# directory set for the section is shown.
# If just name and section are specified on the command-line then
# first . with or without are searched.
# If no matching file was found, . with or
# without are searched for all possible extensions.
# If only name is specified on the command-line then the section
# directories are searched by and by, starting with section `1', until
# a file is matched.
# The function man_is_man() determines all suitable man files for a
# command-line argument, while man_get() searches the single matching
# file for display.
########################################################################
# man_get ( [ []])
#
# Write a man page to the temporary file.
#
# Globals in: $_TMP_MANSPEC, $_MAN_SEC_CHARS, $_MAN_EXT, $_MAN_ALL
#
# Arguments: 1, 2, or 3
#
# Variable prefix: mg
#
man_get()
{
func_check man_get '>=' 1 "$@";
if obj _TMP_MANSPEC is_empty
then
error 'man_get(): man_is_man() must be run first on '"$*".;
fi;
mg_name="$1";
mg_sec="$2";
if is_empty "$2"
then
mg_sec="${_MAN_SEC_CHARS}"; # take care it is not a single section
fi;
mg_ext="$3";
if is_empty "$3"
then
mg_ext="${_MAN_EXT}";
fi;
if obj _TMP_MANSPEC is_not_equal "${_TMP_DIR}/,man:$1:${mg_sec}${mg_ext}"
then
error 'man_get(): $_TMP_MANSPEC does not suit to the arguments '"$*".;
fi;
### man_get()
if obj _MAN_ALL is_yes
then
list_from_file mg_list "${_TMP_MANSPEC}";
eval set x ${mg_list};
shift;
mg_ok='no';
mg_list='';
for f
do
mg_f="$f";
if list_has mg_list "${mg_f}"
then
continue;
else
list_append mg_list "${mg_f}";
fi;
### man_get()
if obj mg_f is_file
then
to_tmp "${mg_f}" && mg_ok='yes';
fi;
done;
if obj mg_ok is_yes
then
register_title man:"${mg_name}";
fi;
eval ${_UNSET} mg_ext;
eval ${_UNSET} mg_f;
eval ${_UNSET} mg_list;
eval ${_UNSET} mg_name;
eval ${_UNSET} mg_sec;
eval "${return_ok}";
else # $_MAN_ALL is not 'yes'
if is_empty "$2"
then # no section from command line
if obj _MAN_SEC_LIST is_empty
then
m="${_MAN_AUTO_SEC_LIST}"; # list of all sections
else
m="${_MAN_SEC_LIST}"; # from --sections
fi;
### man_get()
for s in $(eval set x $m; shift; echo1 "$@")
do
mg_s="$s";
list_from_file mg_list "${_TMP_MANSPEC}";
eval set x ${mg_list};
shift;
if obj mg_ext is_empty
then
for f
do
mg_f="$f";
case "${mg_f}" in
*/man"${mg_s}"/"${mg_name}"."${mg_s}"|*/man"${mg_s}"/"${mg_name}"."${mg_s}".*)
if obj mg_f is_file
then
to_tmp "${mg_f}" && register_title "${mg_name}(${mg_s})";
eval ${_UNSET} mg_ext;
eval ${_UNSET} mg_f;
eval ${_UNSET} mg_list;
eval ${_UNSET} mg_name;
eval ${_UNSET} mg_s;
eval ${_UNSET} mg_sec;
eval "${return_ok}";
fi;
;;
esac; # "$mg_f"
done; # for f
fi; # mg_ext is_empty
### man_get()
for f
do
mg_f="$f";
case "${mg_f}" in
*/man"${mg_s}"/"${mg_name}"."${mg_s}""${mg_ext}"*)
if obj mg_f is_file
then
to_tmp "${mg_f}" && register_title "${mg_name}(${mg_s})";
eval ${_UNSET} mg_ext;
eval ${_UNSET} mg_f;
eval ${_UNSET} mg_list;
eval ${_UNSET} mg_name;
eval ${_UNSET} mg_s;
eval ${_UNSET} mg_sec;
eval "${return_ok}";
fi;
;;
esac; # "$mg_f"
done; # for f
done; # for s
else # $mg_sec is not empty, do with section
list_from_file mg_list "${_TMP_MANSPEC}";
eval set x ${mg_list};
shift;
if obj mg_ext is_empty
then
for f
do
mg_f="$f";
### man_get()
case "${mg_f}" in
*/man"${mg_sec}"/"${mg_name}"."${mg_sec}"|\
*/man"${mg_sec}"/"${mg_name}"."${mg_sec}".*)
if obj mg_f is_file
then
obj mg_f to_tmp && \
register_title "${mg_name}(${mg_sec})";
eval ${_UNSET} mg_ext;
eval ${_UNSET} mg_f;
eval ${_UNSET} mg_list;
eval ${_UNSET} mg_name;
eval ${_UNSET} mg_s;
eval ${_UNSET} mg_sec;
eval "${return_ok}";
fi;
;;
esac;
done; # for f
for f
do
mg_f="$f";
### man_get()
case "${mg_f}" in
*/man"${mg_sec}"/"${mg_name}"."${mg_sec}"*)
if obj mg_f is_file
then
obj mg_f to_tmp && \
register_title "${mg_name}(${mg_sec})";
eval ${_UNSET} mg_ext;
eval ${_UNSET} mg_f;
eval ${_UNSET} mg_list;
eval ${_UNSET} mg_name;
eval ${_UNSET} mg_s;
eval ${_UNSET} mg_sec;
eval "${return_ok}";
fi;
;;
esac;
done; # for f
else # mg_ext is not empty
for f
do
mg_f="$f";
### man_get()
case "${mg_f}" in
*/man"${mg_sec}"/"${mg_name}"."${mg_sec}""${mg_ext}"|\
*/man"${mg_sec}"/"${mg_name}"."${mg_sec}""${mg_ext}".*)
if obj mg_f is_file
then
obj mg_f to_tmp && \
register_title "${mg_name}(${mg_sec}${mg_ext})";
eval ${_UNSET} mg_ext;
eval ${_UNSET} mg_f;
eval ${_UNSET} mg_list;
eval ${_UNSET} mg_name;
eval ${_UNSET} mg_s;
eval ${_UNSET} mg_sec;
eval "${return_ok}";
fi;
;;
esac;
done; # for f
for f
do
mg_f="$f";
### man_get()
case "${mg_f}" in
*/man"${mg_sec}"/"${mg_name}"."${mg_sec}""${mg_ext}"*)
if obj mg_f is_file
then
obj mg_f to_tmp && \
register_title "${mg_name}(${mg_sec}${mg_ext})";
eval ${_UNSET} mg_ext;
eval ${_UNSET} mg_f;
eval ${_UNSET} mg_list;
eval ${_UNSET} mg_name;
eval ${_UNSET} mg_s;
eval ${_UNSET} mg_sec;
eval "${return_ok}";
fi;
;;
esac;
done; # for f
fi;
fi; # $mg_sec
fi; # $_MAN_ALL
eval ${_UNSET} mg_ext;
eval ${_UNSET} mg_f;
eval ${_UNSET} mg_list;
eval ${_UNSET} mg_name;
eval ${_UNSET} mg_sec;
eval ${_UNSET} mg_s;
eval "${return_ok}";
} # man_get()
########################################################################
# man_is_man ( [ []])
#
# Test whether exists as man page.
#
# Globals: in: $_TMP_MAN, $_MAN_SEC_CHARS, $_TMP_DIR, $_MAN_EXT,
# $_MAN_AUTO_SEC_CHARS
# out: $_TMP_MANSPEC
#
# Arguments: 1, 2, or 3
#
# Variable prefix: mim
#
man_is_man()
{
func_check man_is_man '>=' 1 "$@";
if is_empty "$1"
then
_TMP_MANSPEC='';
eval "${return_no}";
fi;
if obj _TMP_DIR is_empty
then
error 'man_is_man(): main_init() must be run first.';
fi;
if obj _MAN_IS_SETUP is_not_yes
then
error 'man_is_man(): man_setup() must be run first.';
fi;
mim_sec="$2";
if is_empty "$2"
then
mim_sec="${_MAN_SEC_CHARS}";
fi;
if is_empty "$3"
then
mim_ext="${_MAN_EXT}";
else
mim_ext="$3";
fi;
_TMP_MANSPEC="${_TMP_DIR}/,man:$1:${mim_sec}${mim_ext}";
### man_is_man()
if obj _TMP_MANSPEC is_not_file
then
if obj mim_sec is_empty
then
m="${_MAN_AUTO_SEC_CHARS}";
eval grep "'/man$m/$1\.$m${mim_ext}'" \
"${_TMP_MAN}" > "${_TMP_MANSPEC}";
else
eval grep "'/man${mim_sec}/$1\.${mim_sec}${mim_ext}'" \
"${_TMP_MAN}" > "${_TMP_MANSPEC}";
fi;
fi;
eval ${_UNSET} mim_ext;
eval ${_UNSET} mim_sec;
if obj _TMP_MANSPEC is_empty_file
then
rm_file_with_debug "${_TMP_MANSPEC}";
eval "${return_no}";
else
eval "${return_yes}";
fi;
} # man_is_man()
########################################################################
# man_setup ()
#
# Setup the variables $_MAN_* needed for man page searching.
#
# Globals:
# in: $_OPT_*, $_MANOPT_*, $LANG, $LC_MESSAGES, $LC_ALL,
# $MANPATH, $MANSEC, $PAGER, $SYSTEM, $MANOPT.
# out: $_MAN_PATH, $_MAN_LANG, $_MAN_SYS, $_MAN_LANG, $_MAN_LANG2,
# $_MAN_SEC, $_MAN_ALL, $_TMP_MAN
# 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, $MANSEC, $PAGER, $SYSTEM; overridden by
# $MANOPT; overridden by
# the groffer command line options.
#
# $MANROFFSEQ is ignored because grog determines the preprocessors.
#
# Variable prefix: ms
#
man_setup()
{
func_check 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
obj_from_output ms_path \
get_first_essential "${_OPT_MANPATH}" "${_MANOPT_PATH}" "${MANPATH}";
if obj ms_path is_empty && is_prog 'manpath'
then
obj_from_output ms_path manpath 2>${_NULL_DEV}; # not always available
fi;
if obj ms_path is_empty
then
manpath_set_from_path;
else
obj_from_output _MAN_PATH path_list "${ms_path}";
fi;
if obj _MAN_PATH is_empty
then
_MAN_ENABLE="no";
echo2 "man_setup(): man path is empty";
eval ${_UNSET} ms_path;
eval "${return_ok}";
fi;
obj_from_output _MAN_PATH list_uniq _MAN_PATH;
### man_setup()
if obj _MAN_ALL is_not_yes
then
if obj _OPT_ALL is_yes || obj _MANOPT_ALL is_yes
then
_MAN_ALL='yes';
else
_MAN_ALL='no';
fi;
fi;
ms_sys="$(get_first_essential \
"${_OPT_SYSTEMS}" "${_MANOPT_SYS}" "${SYSTEM}")";
if obj ms_sys is_not_empty
then
obj_from_output _MAN_SYS list_from_split "${ms_sys}" ',';
fi;
obj_from_output ms_lang get_first_essential \
"${_OPT_LANG}" "${LC_ALL}" "${LC_MESSAGES}" "${LANG}";
case "${ms_lang}" in
C|POSIX)
_MAN_LANG="";
_MAN_LANG2="";
;;
?)
_MAN_LANG="${ms_lang}";
_MAN_LANG2="";
;;
??)
_MAN_LANG="${ms_lang}";
_MAN_LANG2="${ms_lang}";
;;
### man_setup()
*)
_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 $_MAN_LANG*, forget about $_OPT_LANG, $LC_*.
manpath_add_lang_sys;
obj_from_output _MAN_PATH list_uniq _MAN_PATH;
obj_from_output _MAN_SEC get_first_essential \
"${_OPT_SECTIONS}" "${_MANOPT_SEC}" "${MANSEC}";
_MAN_SEC_LIST="";
_MAN_SEC_CHARS="";
case "${_MAN_SEC}" in
*:*)
eval set x "$(list_from_split "${_MAN_SEC}" :)";
shift;
for s
do
if list_has _MAN_AUTO_SEC_LIST "$s"
then
list_append _MAN_SEC_LIST "$s";
_MAN_SEC_CHARS="${_MAN_SEC_CHARS}$s";
fi;
done
if obj _MAN_SEC_CHARS is_not_empty
then
_MAN_SEC_CHARS="[${_MAN_SEC_CHARS}]";
fi;
;;
*)
if list_has _MAN_AUTO_SEC_LIST "${_MAN_SEC}"
then
list_append _MAN_SEC_LIST "${_MAN_SEC}";
_MAN_SEC_CHARS="[${_MAN_SEC}]";
fi;
;;
esac;
### man_setup()
obj_from_output _MAN_EXT get_first_essential \
"${_OPT_EXTENSION}" "${_MANOPT_EXTENSION}" "${EXTENSION}";
_TMP_MAN="$(tmp_create man)";
eval set x "${_MAN_PATH}";
shift;
if is_not_equal "$#" 0
then
for i
do
for j in "$i"/man*
do
find "$j" >>"${_TMP_MAN}";
done
done;
fi;
eval ${_UNSET} ms_lang;
eval ${_UNSET} ms_list;
eval ${_UNSET} ms_path;
eval ${_UNSET} ms_sys;
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: a list of names of operating systems.
# $_MAN_LANG and $_MAN_LANG2: each a single name
# in/out: $_MAN_PATH: list of directories which shall have the `man?'
# subdirectories.
#
# 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;
if obj _MAN_SYS is_empty
then
mals_mp="${_MAN_PATH}";
else
mals_mp='';
eval set x "${_MAN_SYS}";
shift;
for s
do
_manpath_add_sys "$s";
done;
fi;
if obj mals_mp is_not_empty
then
mals_lang_path='';
if is_equal "$_MAN_LANG" "$_MAN_LANG2"
then
mals_man_lang2='';
else
mals_man_lang2="${_MAN_LANG2}";
fi;
for i in "${_MAN_LANG}" "${mals_man_lang2}"
do
if obj i is_empty
then
continue;
fi;
### manpath_add_lang_sys()
mals_lang="$i";
eval set x "${mals_mp}";
shift;
for p
do
obj_from_output mals_dir dir_name_append "${p}" "${mals_lang}";
if obj mals_dir is_dir
then
list_append mals_lang_path "${mals_dir}";
fi;
done;
done;
obj_from_output mals_mp lists_combine mals_lang_path mals_mp;
fi;
_MAN_PATH="${mals_mp}";
eval ${_UNSET} mals_dir;
eval ${_UNSET} mals_lang;
eval ${_UNSET} mals_lang_path;
eval ${_UNSET} mals_man_lang2;
eval ${_UNSET} mals_mp;
eval "${return_ok}";
} # manpath_add_lang_sys()
# _manpath_add_sys ()
#
# Append the existing subdirectories of man path directories to
# the list $mals_mp.
#
# Local function to manpath_add_lang_sys().
#
# Argument: 1, a operating system name (for appending to a man path
# directory)
#
# Globals in: $_MAN_PATH
# Globals in/out: $mals_mp
#
# Variable prefix: _mas
#
_manpath_add_sys()
{
func_check _manpath_add_sys '=' 1 "$@";
case "$1" in
'')
:;
;;
man)
obj_from_output mals_mp lists_combine mals_mp _MAN_PATH;
;;
*)
_mas_sys="$1";
eval set x "${_MAN_PATH}";
shift;
for p
do
obj_from_output _mas_dir dir_name_append "${p}" "${_mas_sys}";
if obj _mas_dir is_dir
then
list_append mals_mp "${_mas_dir}";
fi;
done;
;;
esac;
eval ${_UNSET} _mas_dir;
eval ${_UNSET} _mas_sys;
eval "${return_ok}";
} # _manpath_add_sys() of 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
# delete the final `/bin' part
p="$(echo1 "${PATH}" | sed -e 's|//*bin/*:|:|g')";
obj_from_output msfp_list path_list "$p";
# append some default directories
for b in /usr/local /usr/local /usr /usr \
/usr/X11R6 /usr/openwin \
/opt /opt/gnome /opt/kde
do
msfp_base="$b";
if list_has_not msfp_list "${msfp_base}" && obj msfp_base is_dir
then
list_append msfp_list "${msfp_base}";
fi;
done;
eval set x "${msfp_list}";
shift;
for d
do
# including empty for former `/bin'.
msfp_base="$d";
for e in /share/man /share/MAN /man /MAN
do
msfp_mandir="${msfp_base}$e";
if obj msfp_mandir is_dir
then
list_append msfp_manpath "${msfp_mandir}";
fi;
done;
done;
fi;
_MAN_PATH="${msfp_manpath}";
eval ${_UNSET} msfp_base;
eval ${_UNSET} msfp_list;
eval ${_UNSET} msfp_mandir;
eval ${_UNSET} msfp_manpath;
eval "${return_ok}";
} # manpath_set_from_path()
########################################################################
landmark '9: obj_*()';
########################################################################
########################################################################
# obj (