3 # groffer - display groff files
5 # Source file position: <groff-source>/contrib/groffer/groffer.sh
7 # Copyright (C) 2001,2002,2003,2004,2005 Free Software Foundation,
9 # Written by Bernd Warken
11 # This file is part of groff version @VERSION@ (eventually 1.19.2).
13 # groff is free software; you can redistribute it and/or modify it
14 # under the terms of the GNU General Public License as published by
15 # the Free Software Foundation; either version 2, or (at your option)
18 # groff is distributed in the hope that it will be useful, but WITHOUT
19 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
21 # License for more details.
23 # You should have received a copy of the GNU General Public License
24 # along with groff; see the files COPYING and LICENSE in the top
25 # directory of the groff source. If not, write to the Free Software
26 # Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
28 _PROGRAM_NAME
='groffer';
29 _PROGRAM_VERSION
='0.9.19';
30 _LAST_UPDATE
='7 July 2005';
33 ########################################################################
34 # Determine the shell under which to run this script from the command
35 # line arguments or $GROFF_OPT; if none is specified, just go on with
38 if test _
"${_GROFFER_RUN}"_
= __
;
40 # only reached during the first run of the script
42 export _GROFFER_RUN
; # counter for the runs of groffer
46 export _PROGRAM_VERSION
;
49 export GROFFER_OPT
; # option environment for groffer
50 export _GROFFER_SH
; # file name of this shell script
51 export _OUTPUT_FILE_NAME
; # output generated, see main_set_res..()
53 export _CONF_FILES
; # configuration files
54 _CONF_FILES
="/etc/groff/groffer.conf ${HOME}/.groff/groffer.conf";
59 # was: _GROFFER_SH="@BINDIR@/${_PROGRAM_NAME}";
62 echo "The ${_PROGRAM_NAME} script should be started directly." >&2
70 _NULL_DEV
="/dev/null";
80 _res
="$(unset _foo 2>&1)";
81 if unset _foo
>${_NULL_DEV} 2>&1 && \
82 test _
"${_res}"_
= __
&& test _
"${_foo}"_
= __
85 eval "${_UNSET}" _res
;
91 ###########################
92 # _get_opt_shell ("$@")
94 # Determine whether `--shell' was specified in $GROFF_OPT or in $*;
95 # if so, echo its argument.
97 # Output: the shell name if it was specified
101 case " ${GROFFER_OPT} $*" in
102 *\
--shell\
*|
*\
--shell=*)
104 eval set x
"${GROFFER_OPT}" '"$@"';
118 # delete up to first `=' character
119 _sh
="$(echo x"$1" | sed -e '
136 ###########################
137 # _test_on_shell (<name>)
139 # Test whether <name> is a shell program of Bourne type (POSIX sh).
143 if test "$#" -le 0 ||
test _
"$1"_
= __
;
147 # do not quote $1 to allow arguments
148 test _
"$(eval $1 -c "'"'s
=ok
; echo $s'"'" 2>${_NULL_DEV})"_
= _ok_
;
152 ###########################
153 # do the shell determination from command line and $GROFFER_OPT
154 _shell
="$(_get_opt_shell "$@
")";
155 if test _
"${_shell}"_
= __
;
157 # none found, so look at the `--shell' lines in configuration files
159 # for f in $_CONF_FILES
160 for f
in $
(eval set x
${_CONF_FILES}; shift; echo "$@")
164 _all
="$(cat "$f" | sed -n -e 's/^--shell[= ] *\([^ ]*\)$/\1/p')"
166 for s
in $
(eval set x
${_all}; shift; echo "$@")
177 # restart the script with the last found $_shell, if it is a shell
178 if _test_on_shell
"${_shell}";
180 _GROFFER_RUN
='second';
181 # do not quote $_shell to allow arguments
182 eval exec ${_shell} "'${_GROFFER_SH}'" '"$@"';
186 _GROFFER_RUN
='second';
187 eval ${_UNSET} _shell
;
189 fi; # end of first run
191 if test _
"${_GROFFER_RUN}"_
!= _second_
;
193 echo "$_GROFFER_RUN should be 'second' here." >&2
197 eval ${_UNSET} _GROFFER_RUN
200 ########################################################################
201 # diagnostic messages
204 _DEBUG
='no'; # disable debugging information
205 #_DEBUG='yes'; # enable debugging information
208 _DEBUG_LM
='no'; # disable landmark messages
209 #_DEBUG_LM='yes'; # enable landmark messages
211 export _DEBUG_KEEP_FILES
;
212 _DEBUG_KEEP_FILES
='no' # disable file keeping in temporary dir
213 _DEBUG_KEEP_FILES
='yes' # enable file keeping in temporary dir
215 # test of $* on --debug
220 _DEBUG_KEEP_FILES
='yes';
225 ########################################################################
226 # Environment Variables
227 ########################################################################
229 # Environment variables that exist only for this file start with an
230 # underscore letter. Global variables to this file are written in
231 # upper case letters, e.g. $_GLOBAL_VARIABLE; temporary variables
232 # start with an underline and use only lower case letters and
233 # underlines, e.g. $_local_variable .
235 # [A-Z]* system variables, e.g. $MANPATH
236 # _[A-Z_]* global file variables, e.g. $_MAN_PATH
237 # _[a-z_]* temporary variables, e.g. $_manpath
239 # Due to incompatibilities of the `ash' shell, the name of loop
240 # variables in `for' must be single character
241 # [a-z] local loop variables, e.g. $i
244 ########################################################################
245 # read-only variables (global to this file)
246 ########################################################################
258 # function return values; `0' means ok; other values are error codes
267 _GOOD
='0'; # return ok
268 _BAD
='1'; # return negatively, error code `1'
269 _ERROR
='7'; # for syntax errors; no `-1' in `ash'
271 _ALL_EXIT
="${_GOOD} ${_BAD} ${_ERROR}"; # all exit codes (for `trap_set')
277 # quasi-functions, call with `eval', e.g `eval "${return_ok}"'
285 return_ok
="func_pop; return ${_OK}";
286 return_good
="func_pop; return ${_GOOD}";
287 return_bad
="func_pop; return ${_BAD}";
288 return_yes
="func_pop; return ${_YES}";
289 return_no
="func_pop; return ${_NO}";
290 return_error
="func_pop; return ${_ERROR}";
291 return_var
="func_pop; return"; # add number, e.g. `eval "${return_var} $n'
294 export _DEFAULT_MODES
;
295 _DEFAULT_MODES
='x,ps,tty';
296 export _DEFAULT_RESOLUTION
;
297 _DEFAULT_RESOLUTION
='75';
299 export _DEFAULT_TTY_DEVICE
;
300 _DEFAULT_TTY_DEVICE
='latin1';
302 # _VIEWER_* viewer programs for different modes (only X is necessary)
303 # _VIEWER_* a comma-separated list of viewer programs (with options)
304 export _VIEWER_DVI
; # viewer program for dvi mode
305 export _VIEWER_PS
; # viewer program for ps mode
306 export _VIEWER_HTML_X
; # viewer program for html mode in X
307 export _VIEWER_HTML_TTY
; # viewer program for html mode in tty
308 _VIEWER_DVI
='kdvi,xdvi,dvilx';
309 _VIEWER_PDF
='kghostview,ggv,xpdf,acroread,kpdf';
310 _VIEWER_PS
='kghostview,ggv,gv,ghostview,gs_x11,gs';
311 _VIEWER_HTML
='konqueror,mozilla,netscape,opera,amaya,arena,lynx';
312 _VIEWER_X
='gxditview,xditview';
314 # Search automatically in standard sections `1' to `8', and in the
315 # traditional sections `9', `n', and `o'. On many systems, there
316 # exist even more sections, mostly containing a set of man pages
317 # special to a specific program package. These aren't searched for
318 # automatically, but must be specified on the command line.
319 export _MAN_AUTO_SEC
;
320 _MAN_AUTO_SEC
="'1' '2' '3' '4' '5' '6' '7' '8' '9' 'n' 'o'"
322 export _PROCESS_ID
; # for shutting down the program
326 ############ the command line options of the involved programs
328 # The naming scheme for the options environment names is
329 # $_OPTS_<prog>_<length>[_<argspec>]
331 # <prog>: program name GROFFER, GROFF, or CMDLINE (for all
332 # command line options)
333 # <length>: LONG (long options) or SHORT (single character options)
334 # <argspec>: ARG for options with argument, NA for no argument;
335 # without _<argspec> both the ones with and without arg.
337 # Each option that takes an argument must be specified with a
338 # trailing : (colon).
341 export _OPTS_GROFFER_SHORT_NA
;
342 export _OPTS_GROFFER_SHORT_ARG
;
343 export _OPTS_GROFFER_LONG_NA
;
344 export _OPTS_GROFFER_LONG_ARG
;
345 export _OPTS_GROFF_SHORT_NA
;
346 export _OPTS_GROFF_SHORT_ARG
;
347 export _OPTS_GROFF_LONG_NA
;
348 export _OPTS_GROFF_LONG_ARG
;
349 export _OPTS_X_SHORT_ARG
;
350 export _OPTS_X_SHORT_NA
;
351 export _OPTS_X_LONG_ARG
;
352 export _OPTS_X_LONG_NA
;
353 export _OPTS_MAN_SHORT_ARG
;
354 export _OPTS_MAN_SHORT_NA
;
355 export _OPTS_MAN_LONG_ARG
;
356 export _OPTS_MAN_LONG_NA
;
357 export _OPTS_MANOPT_SHORT_ARG
;
358 export _OPTS_MANOPT_SHORT_NA
;
359 export _OPTS_MANOPT_LONG_ARG
;
360 export _OPTS_MANOPT_LONG_NA
;
361 export _OPTS_CMDLINE_SHORT_NA
;
362 export _OPTS_CMDLINE_SHORT_ARG
;
363 export _OPTS_CMDLINE_LONG_NA
;
364 export _OPTS_CMDLINE_LONG_ARG
;
366 ###### groffer native options
368 _OPTS_GROFFER_SHORT_NA
="'h' 'Q' 'v' 'V' 'X' 'Z'";
369 _OPTS_GROFFER_SHORT_ARG
="'T'";
371 _OPTS_GROFFER_LONG_NA
="'auto' 'debug' 'default' 'dvi' \
372 'groff' 'help' 'intermediate-output' 'html' 'man' \
373 'no-location' 'no-man' 'pdf' 'ps' 'rv' 'source' 'text' 'text-device' \
374 'title' 'tty' 'tty-device' 'version' 'whatis' 'where' 'www' 'x' 'X'";
376 _OPTS_GROFFER_LONG_ARG
="\
377 'apropos' 'apropos-data' 'apropos-devel' 'apropos-progs' \
378 'default-modes' 'device' 'dvi-viewer' 'extension' 'fg' 'fn' 'font' \
379 'foreground' 'html-viewer' 'mode' 'pdf-viewer' 'ps-viewer' 'shell' \
380 'tty-viewer' 'www-viewer' 'x-viewer' 'X-viewer'";
382 ##### groffer options inhereted from groff
384 _OPTS_GROFF_SHORT_NA
="'a' 'b' 'c' 'C' 'e' 'E' 'g' 'G' 'i' 'l' 'N' 'p' \
385 'R' 's' 'S' 't' 'U' 'z'";
386 _OPTS_GROFF_SHORT_ARG
="'d' 'f' 'F' 'I' 'L' 'm' 'M' 'n' 'o' 'P' 'r' \
388 _OPTS_GROFF_LONG_NA
="";
389 _OPTS_GROFF_LONG_ARG
="";
391 ##### groffer options inhereted from the X Window toolkit
394 _OPTS_X_SHORT_ARG
="";
396 _OPTS_X_LONG_NA
="'iconic' 'rv'";
398 _OPTS_X_LONG_ARG
="'background' 'bd' 'bg' 'bordercolor' 'borderwidth' \
399 'bw' 'display' 'fg' 'fn' 'font' 'foreground' 'ft', 'geometry'
400 'resolution' 'title' 'xrm'";
402 ###### groffer options inherited from man
404 _OPTS_MAN_SHORT_NA
="";
405 _OPTS_MAN_SHORT_ARG
="";
407 _OPTS_MAN_LONG_NA
="'all' 'ascii' 'catman' 'debug' 'ditroff' 'help' \
408 'local-file' 'location' 'pager' 'troff' 'update' 'version' \
411 _OPTS_MAN_LONG_ARG
="'extension' 'locale' 'manpath' \
412 'pager' 'preprocessor' 'prompt' 'sections' 'systems' 'troff-device'";
414 ###### additional options for parsing $MANOPT only
416 _OPTS_MANOPT_SHORT_NA
="'7' 'a' 'c' 'd' 'D' 'f' 'h' 'k' 'l' 't' 'u' \
418 _OPTS_MANOPT_SHORT_ARG
="'e' 'L' 'm' 'M' 'p' 'P' 'r' 'S' 'T'";
420 _OPTS_MANOPT_LONG_NA
="${_OPTS_MAN_LONG_NA} \
421 'apropos' 'debug' 'default' 'html' 'ignore-case' 'location-cat' \
422 'match-case' 'troff' 'update' 'version' 'where-cat'";
424 _OPTS_MANOPT_LONG_ARG
="${_OPTS_MAN_LONG_NA} \
425 'config_file' 'encoding' 'locale'";
427 ###### collections of command line options
429 _OPTS_CMDLINE_SHORT_NA
="${_OPTS_GROFFER_SHORT_NA}\
430 ${_OPTS_GROFF_SHORT_NA} ${_OPTS_X_SHORT_NA} ${_OPTS_MAN_SHORT_NA}";
431 _OPTS_CMDLINE_SHORT_ARG
="${_OPTS_GROFFER_SHORT_ARG} \
432 ${_OPTS_GROFF_SHORT_ARG} ${_OPTS_X_SHORT_ARG} ${_OPTS_MAN_SHORT_ARG}";
434 _OPTS_CMDLINE_LONG_NA
="${_OPTS_GROFFER_LONG_NA} \
435 ${_OPTS_GROFF_LONG_NA} ${_OPTS_X_LONG_NA} ${_OPTS_MAN_LONG_NA}";
436 _OPTS_CMDLINE_LONG_ARG
="${_OPTS_GROFFER_LONG_ARG} \
437 ${_OPTS_GROFF_LONG_ARG} ${_OPTS_MAN_LONG_ARG} ${_OPTS_X_LONG_ARG}";
440 ########################################################################
441 # read-write variables (global to this file)
442 ########################################################################
444 export _ADDOPTS_GROFF
; # Transp. options for groff (`eval').
445 export _ADDOPTS_POST
; # Transp. options postproc (`eval').
446 export _ADDOPTS_X
; # Transp. options X postproc (`eval').
447 export _DEFAULT_MODES
; # Set default modes.
448 export _DISPLAY_MODE
; # Display mode.
449 export _DISPLAY_PROG
; # Viewer program to be used for display.
450 export _DISPLAY_ARGS
; # X resources for the viewer program.
451 export _FILEARGS
; # Stores filespec parameters.
452 export _FUNC_STACK
; # Store debugging information.
453 export _REGISTERED_TITLE
; # Processed file names.
454 # _HAS_* from availability tests
455 export _HAS_COMPRESSION
; # `yes' if gzip compression is available
456 export _HAS_BZIP
; # `yes' if bzip2 compression is available
457 # _MAN_* finally used configuration of man searching
458 export _MAN_ALL
; # search all man pages per filespec
459 export _MAN_ENABLE
; # enable search for man pages
460 export _MAN_EXT
; # extension for man pages
461 export _MAN_FORCE
; # force file parameter to be man pages
462 export _MAN_IS_SETUP
; # setup man variables only once
463 export _MAN_LANG
; # language for man pages
464 export _MAN_LANG2
; # language for man pages
465 export _MAN_LANG_DONE
; # language dirs added to man path
466 export _MAN_PATH
; # search path for man pages
467 export _MAN_SEC
; # sections for man pages; sep. `:'
468 export _MAN_SEC_DONE
; # sections added to man path
469 export _MAN_SYS
; # system names for man pages; sep. `,'
470 export _MAN_SYS
; # system names added to man path
471 # _MANOPT_* as parsed from $MANOPT
472 export _MANOPT_ALL
; # $MANOPT --all
473 export _MANOPT_EXTENSION
; # $MANOPT --extension
474 export _MANOPT_LANG
; # $MANOPT --locale
475 export _MANOPT_PATH
; # $MANOPT --manpath
476 export _MANOPT_PAGER
; # $MANOPT --pager
477 export _MANOPT_SEC
; # $MANOPT --sections
478 export _MANOPT_SYS
; # $MANOPT --systems
479 # _OPT_* as parsed from groffer command line
480 export _OPT_ALL
; # display all suitable man pages.
481 export _OPT_APROPOS
; # call `apropos' program.
482 export _OPT_APROPOS_DATA
; # `apropos' for man sections 4, 5, 7
483 export _OPT_APROPOS_DEVEL
; # `apropos' for man sections 2, 3, 9
484 export _OPT_APROPOS_PROGS
; # `apropos' for man sections 1, 6, 8
485 export _OPT_BD
; # set border color in some modes.
486 export _OPT_BG
; # set background color in some modes.
487 export _OPT_BW
; # set border width in some modes.
488 export _OPT_DEBUG
; # print debugging information on stderr.
489 export _OPT_DEFAULT_MODES
; # `,'-list of modes when no mode given.
490 export _OPT_DEVICE
; # device option.
491 export _OPT_DISPLAY
; # set X display.
492 export _OPT_FG
; # set foreground color in some modes.
493 export _OPT_FN
; # set font in some modes.
494 export _OPT_GEOMETRY
; # set size and position of viewer in X.
495 export _OPT_ICONIC
; # -iconic option for X viewers.
496 export _OPT_LANG
; # set language for man pages
497 export _OPT_LOCATION
; # print processed file names to stderr
498 export _OPT_MODE
; # values: X, tty, Q, Z, ""
499 export _OPT_MANPATH
; # manual setting of path for man-pages
500 export _OPT_PAGER
; # specify paging program for tty mode
501 export _OPT_RESOLUTION
; # set X resolution in dpi
502 export _OPT_RV
; # reverse fore- and background colors.
503 export _OPT_SECTIONS
; # sections for man page search
504 export _OPT_SYSTEMS
; # man pages of different OS's
505 export _OPT_TITLE
; # title for gxditview window
506 export _OPT_TEXT_DEVICE
; # set device for tty mode.
507 export _OPT_V
; # groff option -V.
508 export _OPT_VIEWER_DVI
; # viewer program for dvi mode
509 export _OPT_VIEWER_PDF
; # viewer program for pdf mode
510 export _OPT_VIEWER_PS
; # viewer program for ps mode
511 export _OPT_VIEWER_HTML
; # viewer program for html mode
512 export _OPT_VIEWER_X
; # viewer program for x mode
513 export _OPT_WHATIS
; # print the one-liner man info
514 export _OPT_XRM
; # specify X resource.
515 export _OPT_Z
; # groff option -Z.
516 # _TMP_* temporary files
517 export _TMP_DIR
; # groffer directory for temporary files
518 export _TMP_CAT
; # stores concatenation of everything
519 export _TMP_STDIN
; # stores stdin, if any
521 # these variables are preset in section `Preset' after the rudim. test
524 ########################################################################
525 # Test of rudimentary shell functionality
526 ########################################################################
529 ########################################################################
532 test "a" = "a" ||
exit 1;
535 ########################################################################
536 # Test of `echo' and the `$()' construct.
538 echo '' >${_NULL_DEV} ||
exit "${_ERROR}";
539 if test _
"$(t1="$
(echo te
)" &&
542 echo "${t1}${t2}${t3}")"_ \
549 ########################################################################
550 # Test of function definitions.
557 if _t_e_s_t_f_u_n_c_
2>${_NULL_DEV};
561 echo 'shell does not support function definitions.' >&2;
566 ########################################################################
567 # Preset and reset of read-write global variables
568 ########################################################################
571 # For variables that can be reset by option `--default', see reset().
575 # _HAS_* from availability tests
579 # _TMP_* temporary files
585 ########################################################################
588 # Reset the variables that can be affected by options to their default.
594 error
"reset() does not have arguments.";
603 _REGISTERED_TITLE
='';
605 # _MAN_* finally used configuration of man searching
607 _MAN_ENABLE
='yes'; # do search for man-pages
609 _MAN_FORCE
='no'; # first local file, then search man page
619 # _MANOPT_* as parsed from $MANOPT
621 _MANOPT_EXTENSION
='';
628 # _OPT_* as parsed from groffer command line
631 _OPT_APROPOS_DATA
='';
632 _OPT_APROPOS_DEVEL
='';
633 _OPT_APROPOS_PROGS
='';
638 _OPT_DEFAULT_MODES
='';
671 ########################################################################
672 # Functions for error handling and debugging
673 ########################################################################
681 # Arguments : arbitrary text.
694 # Print <text> to standard error as a debugging aid.
696 # Globals: $_DEBUG_LM
700 if test _
"${_DEBUG_LM}"_
= _yes_
;
706 landmark
"1: debugging functions";
716 if test -d "${_TMP_DIR}";
718 eval rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1;
726 # Output a diagnostic message to stderr
737 # Print an error message to standard error; exit with an error condition
739 # Variable prefix: err
743 err_code
="${_ERROR}";
746 1) echo2
'groffer error: '"$1"; ;;
748 echo2
'groffer error: '"$1";
751 *) echo2
'groffer error: wrong number of arguments in error().'; ;;
755 kill "${_PROCESS_ID}" >${_NULL_DEV} 2>&1;
756 kill -9 "${_PROCESS_ID}" >${_NULL_DEV} 2>&1;
758 eval ${_UNSET} err_code
;
766 # Terminate program with error condition
770 error
"abort(): Program aborted.";
776 # func_check (<func_name> <rel_op> <nr_args> "$@")
778 # Check number of arguments and register to _FUNC_STACK.
781 # <func_name>: name of the calling function.
782 # <rel_op>: a relational operator: = != < > <= >=
783 # <nr_args>: number of arguments to be checked against <operator>
784 # "$@": the arguments of the calling function.
786 # Variable prefix: fc
792 error
'func_check() needs at least 3 arguments.';
805 error
"func_check(): third argument must be a digit.";
835 'func_check(): second argument is not a relational operator.';
841 if test "$#" "${fc_op}" "${fc_nargs}";
845 error
"func_check(): \
846 ${fc_fname}"'() needs '"${fc_comp} ${fc_nargs}"' argument'"${fc_s}"'.';
848 func_push
"${fc_fname}";
849 if test _
"${_DEBUG}"_
= _yes_
;
851 echo2
'+++ '"${fc_fname} $@";
852 echo2
'>>> '"${_FUNC_STACK}";
854 eval ${_UNSET} fc_comp
;
855 eval ${_UNSET} fc_fname
;
856 eval ${_UNSET} fc_nargs
;
857 eval ${_UNSET} fc_op
;
865 # Retrieve the top element from the stack.
867 # The stack elements are separated by `!'; the popped element is
868 # identical to the original element, except that all `!' characters
877 error
'func_pop() does not have arguments.';
879 case "${_FUNC_STACK}" in
881 if test _
"${_DEBUG}"_
= _yes_
;
883 error
'func_pop(): stack is empty.';
887 # split at first bang `!'.
888 _FUNC_STACK
="$(echo x"${_FUNC_STACK}" | sed -e '
897 if test _
"${_DEBUG}"_
= _yes_
;
899 echo2
'<<< '"${_FUNC_STACK}";
905 # func_push (<element>)
907 # Store another element to stack.
909 # The stack elements are separated by `!'; if <element> contains a `!'
910 # it is removed first.
914 # Variable prefix: fp
920 error
'func_push() needs 1 argument.';
924 # remove all bangs `!'.
925 fp_element
="$(echo x"$1" | sed -e '
934 if test _
"${_FUNC_STACK}"_
= __
;
936 _FUNC_STACK
="${fp_element}";
938 _FUNC_STACK
="${fp_element}!${_FUNC_STACK}";
940 eval ${_UNSET} fp_element
;
947 # Print the content of the stack. Ignore the arguments.
951 diag
'call stack: '"${_FUNC_STACK}";
955 ########################################################################
957 ########################################################################
959 landmark
"2: system test";
961 # Test the availability of the system utilities used in this script.
964 ########################################################################
965 # Test of function `sed'.
968 if test _
"$(echo xTesTx \
969 | sed -e 's/^.\([Tt]e*x*sTT*\).*$/\1/' \
970 | sed -e 's|T|t|g')"_
!= _test_
;
972 error
'Test of "sed" command failed.';
976 ########################################################################
977 # Test of function `cat'.
979 if test _
"$(echo test | cat)"_
!= _test_
;
981 error
'Test of "cat" command failed.';
985 ########################################################################
986 # Test for compression.
988 if test _
"$(echo 'test' | gzip -c -d -f - 2>${_NULL_DEV})"_
= _test_
;
990 _HAS_COMPRESSION
='yes';
991 if echo 'test' |
bzip2 -c 2>${_NULL_DEV} |
bzip2 -t 2>${_NULL_DEV} \
992 && test _
"$(echo 'test' | bzip2 -c 2>${_NULL_DEV} \
993 | bzip2 -d -c 2>${_NULL_DEV})"_ \
1001 _HAS_COMPRESSION
='no';
1006 ########################################################################
1007 # Definition of normal Functions in alphabetical order
1008 ########################################################################
1009 landmark
"3: functions";
1011 ########################################################################
1014 # Unconditionally terminate the program with error code;
1015 # useful for debugging.
1020 ########################################################################
1021 # apropos_run (<name>)
1025 func_check apropos_run
= 1 "$@";
1026 if apropos apropos
>${_NULL_DEV} 2>${_NULL_DEV};
1029 elif man
--apropos man
>${_NULL_DEV} 2>${_NULL_DEV};
1032 elif man
-k man
>${_NULL_DEV} 2>${_NULL_DEV};
1036 eval "${return_ok}";
1040 ########################################################################
1041 # base_name (<path>)
1043 # Get the file name part of <path>, i.e. delete everything up to last
1044 # `/' from the beginning of <path>. Remove final slashes, too, to get a
1048 # Output : the file name part (without slashes)
1050 # Variable prefix: bn
1054 func_check base_name
= 1 "$@";
1056 case "${bn_name}" in
1058 # delete all final slashes
1059 bn_name
="$(echo x"${bn_name}" | sed -e '
1065 case "${bn_name}" in
1067 eval ${_UNSET} bn_name
;
1068 eval "${return_bad}";
1071 # delete everything before and including the last slash `/'.
1072 echo x
"${bn_name}" |
sed -e '
1074 s|^.*//*\([^/]*\)$|\1|
1083 eval ${_UNSET} bn_name
;
1084 eval "${return_ok}";
1088 ########################################################################
1091 # Decompress if possible or just print <file> to standard output.
1093 # gzip, bzip2, and .Z decompression is supported.
1095 # Arguments: 1, a file name.
1096 # Output: the content of <file>, possibly decompressed.
1098 if test _
"${_HAS_COMPRESSION}"_
= _yes_
;
1102 func_check cat_z
= 1 "$@";
1105 error
'cat_z(): empty file name';
1108 error
'cat_z(): for standard input use save_stdin()';
1111 if obj _HAS_BZIP is_yes
;
1113 if bzip2 -t "$1" 2>${_NULL_DEV};
1115 bzip2 -c -d "$1" 2>${_NULL_DEV};
1116 eval "${return_ok}";
1119 gzip -c -d -f "$1" 2>${_NULL_DEV};
1120 eval "${return_ok}";
1125 func_check cat_z
= 1 "$@";
1127 eval "${return_ok}";
1132 ########################################################################
1135 # Do the final cleaning up before exiting; used by the trap calls.
1140 ########################################################################
1143 # Print marked message to standard error; useful for debugging.
1148 ########################################################################
1149 landmark
'4: dirname()*';
1150 ########################################################################
1152 #######################################################################
1153 # dirname_append (<dir> <name>)
1155 # Append `name' to `dir' with clean handling of `/'.
1158 # Output : the generated new directory name <dir>/<name>
1162 func_check dirname_append
= 2 "$@";
1165 error
"dir_append(): first argument is empty.";
1173 dirname_chop
"$1"/"$2";
1175 eval "${return_ok}";
1179 ########################################################################
1180 # dirname_chop (<name>)
1182 # Remove unnecessary slashes from directory name.
1184 # Argument: 1, a directory name.
1185 # Output: path without double, or trailing slashes.
1187 # Variable prefix: dc
1191 func_check dirname_chop
= 1 "$@";
1192 # replace all multiple slashes by a single slash `/'.
1193 dc_res
="$(echo x"$1" | sed -e '
1199 # remove trailing slash '/';
1200 echo x
"${dc_res}" |
sed -e '
1210 eval ${_UNSET} dc_res
;
1211 eval "${return_ok}";
1215 ########################################################################
1216 # do_filearg (<filearg>)
1218 # Append the file, man-page, or standard input corresponding to the
1219 # argument to the temporary file. If this is compressed in the gzip
1220 # or Z format it is decompressed. A title element is generated.
1223 # - name of an existing files.
1224 # - `-' to represent standard input (several times allowed).
1225 # - `man:name.(section)' the man-page for `name' in `section'.
1226 # - `man:name.section' the man-page for `name' in `section'.
1227 # - `man:name' the man-page for `name' in the lowest `section'.
1228 # - `name.section' the man-page for `name' in `section'.
1229 # - `name' the man-page for `name' in the lowest `section'.
1231 # $_TMP_STDIN, $_MAN_ENABLE, $_MAN_IS_SETUP, $_OPT_MAN
1234 # Return : $_GOOD if found, ${_BAD} otherwise.
1236 # Variable prefix: df
1240 func_check do_filearg
= 1 "$@";
1242 # store sequence into positional parameters
1243 case "${df_filespec}" in
1245 eval ${_UNSET} df_filespec
;
1246 eval "${return_good}";
1250 eval ${_UNSET} df_filespec
;
1251 eval "${return_good}";
1253 */*) # with directory part; so no man search
1257 if obj _MAN_ENABLE is_yes
;
1259 if obj _MAN_FORCE is_yes
;
1261 set 'Manpage' 'File';
1263 set 'File' 'Manpage';
1274 if test -f "${df_filespec}";
1276 if test -r "${df_filespec}";
1278 register_file
"${df_filespec}";
1279 eval ${_UNSET} df_filespec
;
1280 eval "${return_good}";
1282 echo2
"could not read \`${df_filespec}'";
1283 eval ${_UNSET} df_filespec
;
1284 eval "${return_bad}";
1290 Manpage
) # parse filespec as man page
1291 if obj _MAN_IS_SETUP is_not_yes
;
1295 if man_do_filespec
"${df_filespec}";
1297 eval ${_UNSET} df_filespec
;
1298 eval "${return_good}";
1305 eval ${_UNSET} df_filespec
;
1306 eval "${return_bad}";
1310 ########################################################################
1317 eval return "${_OK}";
1321 ########################################################################
1324 # Print to standard error with final line break.
1329 ########################################################################
1332 # Print error message and exit with error code.
1337 ########################################################################
1338 # func_check (<func_name> <rel_op> <nr_args> "$@")
1340 # Check number of arguments and register to _FUNC_STACK.
1343 # <func_name>: name of the calling function.
1344 # <rel_op>: a relational operator: = != < > <= >=
1345 # <nr_args>: number of arguments to be checked against <operator>
1346 # "$@": the arguments of the calling function.
1350 #########################################################################
1353 # Delete the top element from the function call stack.
1358 ########################################################################
1359 # func_push (<element>)
1361 # Store another element to function call stack.
1366 ########################################################################
1367 # func_stack_dump ()
1369 # Print the content of the stack.
1374 ########################################################################
1375 # get_first_essential (<arg>*)
1377 # Retrieve first non-empty argument.
1379 # Return : `1' if all arguments are empty, `0' if found.
1380 # Output : the retrieved non-empty argument.
1382 # Variable prefix: gfe
1384 get_first_essential
()
1386 func_check get_first_essential
'>=' 0 "$@";
1389 eval "${return_ok}";
1394 if obj gfe_var is_not_empty
;
1399 eval ${_UNSET} gfe_var
;
1400 eval "${return_ok}";
1403 eval ${_UNSET} gfe_var
;
1404 eval "${return_bad}";
1408 ########################################################################
1409 landmark
'5: is_*()';
1410 ########################################################################
1412 ########################################################################
1415 # Test whether `name' is a directory.
1418 # Return : `0' if arg1 is a directory, `1' otherwise.
1422 func_check is_dir
= 1 "$@";
1423 if test -d "$1" && test -r "$1";
1425 eval "${return_yes}";
1427 eval "${return_no}";
1431 ########################################################################
1432 # is_empty (<string>)
1434 # Test whether `string' is empty.
1437 # Return : `0' if arg1 is empty or does not exist, `1' otherwise.
1441 func_check is_empty
= 1 "$@";
1442 if test _
"$1"_
= __
;
1444 eval "${return_yes}";
1446 eval "${return_no}";
1450 ########################################################################
1451 # is_equal (<string1> <string2>)
1453 # Test whether `string1' is equal to <string2>.
1456 # Return : `0' both arguments are equal strings, `1' otherwise.
1460 func_check is_equal
= 2 "$@";
1461 if test _
"$1"_
= _
"$2"_
;
1463 eval "${return_yes}";
1465 eval "${return_no}";
1469 ########################################################################
1470 # is_existing (<name>)
1472 # Test whether `name' is an existing file or directory. Solaris 2.5 does
1473 # not have `test -e'.
1476 # Return : `0' if arg1 exists, `1' otherwise.
1480 func_check is_existing
= 1 "$@";
1481 if test -f "$1" ||
test -d "$1";
1483 eval "${return_yes}";
1485 eval "${return_no}";
1489 ########################################################################
1492 # Test whether `name' is a readable file.
1495 # Return : `0' if arg1 is a readable file, `1' otherwise.
1499 func_check is_file
= 1 "$@";
1500 if test -f "$1" && test -r "$1";
1502 eval "${return_yes}";
1504 eval "${return_no}";
1508 ########################################################################
1509 # is_non_empty_file (<file_name>)
1511 # Test whether `file_name' is a non-empty existing file.
1515 # `0' if arg1 is a non-empty existing file
1520 func_check is_non_empty_file
= 1 "$@";
1521 if is_file
"$1" && test -s "$1";
1523 eval "${return_yes}";
1525 eval "${return_no}";
1529 ########################################################################
1530 # is_not_dir (<name>)
1532 # Test whether `name' is not a readable directory.
1535 # Return : `0' if arg1 is a directory, `1' otherwise.
1539 func_check is_not_dir
= 1 "$@";
1542 eval "${return_no}";
1544 eval "${return_yes}";
1548 ########################################################################
1549 # is_not_empty (<string>)
1551 # Test whether `string' is not empty.
1554 # Return : `0' if arg1 exists and is not empty, `1' otherwise.
1558 func_check is_not_empty
= 1 "$@";
1561 eval "${return_no}";
1563 eval "${return_yes}";
1567 ########################################################################
1568 # is_not_equal (<string1> <string2>)
1570 # Test whether `string1' differs from `string2'.
1576 func_check is_not_equal
= 2 "$@";
1577 if is_equal
"$1" "$2";
1579 eval "${return_no}";
1581 eval "${return_yes}";
1585 ########################################################################
1586 # is_not_file (<filename>)
1588 # Test whether `name' is a not readable file.
1590 # Arguments : >=1 (empty allowed), more args are ignored
1594 func_check is_not_file
'>=' 1 "$@";
1597 eval "${return_no}";
1599 eval "${return_yes}";
1603 ########################################################################
1604 # is_not_prog (<name>)
1606 # Verify that arg is a not program in $PATH.
1608 # Arguments : >=1 (empty allowed)
1609 # more args are ignored, this allows to specify progs with arguments
1613 func_check is_not_prog
'>=' 1 "$@";
1614 if where_is
"$1" >${_NULL_DEV};
1616 eval "${return_no}";
1618 eval "${return_yes}";
1622 ########################################################################
1623 # is_not_writable (<name>)
1625 # Test whether `name' is a not a writable file or directory.
1627 # Arguments : >=1 (empty allowed), more args are ignored
1631 func_check is_not_writable
'>=' 1 "$@";
1632 if is_writable
"$1";
1634 eval "${return_no}";
1636 eval "${return_yes}";
1640 ########################################################################
1641 # is_not_yes (<string>)
1643 # Test whether `string' is not "yes".
1649 func_check is_not_yes
= 1 "$@";
1652 eval "${return_no}";
1654 eval "${return_yes}";
1658 ########################################################################
1659 # is_prog (<name> [<arg>*])
1661 # Determine whether <name> is a program in $PATH
1663 # Arguments : >=0 (empty allowed)
1664 # <arg>* are ignored, this allows to specify progs with arguments.
1668 func_check is_prog
'>=' 0 "$@";
1671 eval "${return_no}";
1674 if where_is
"$1" >${_NULL_DEV};
1676 eval "${return_yes}";
1680 eval "${return_no}";
1684 ########################################################################
1685 # is_writable (<name>)
1687 # Test whether `name' is a writable file or directory.
1689 # Arguments : >=1 (empty allowed), more args are ignored
1693 func_check is_writable
'>=' 1 "$@";
1698 eval "${return_yes}";
1701 eval "${return_no}";
1705 ########################################################################
1708 # Test whether `string' has value "yes".
1711 # Return : `0' if arg1 is `yes', `1' otherwise.
1715 func_check is_yes
= 1 "$@";
1716 if is_equal
"$1" 'yes';
1718 eval "${return_yes}";
1720 eval "${return_no}";
1724 ########################################################################
1727 # Print debugging information on standard error if $_DEBUG_LM is `yes'.
1729 # Globals: $_DEBUG_LM
1731 # Defined in section `Debugging functions'.
1734 ########################################################################
1737 # Clean exit without an error.
1746 ########################################################################
1747 landmark
'6: list_*()';
1748 ########################################################################
1750 # `list' is an object class that represents an array or list. Its
1751 # data consists of space-separated single-quoted elements. So a list
1752 # has the form "'first' 'second' '...' 'last'". See list_append() for
1753 # more details on the list structure. The array elements of `list'
1754 # can be get by `set x $list; shift`.
1757 ########################################################################
1758 # list_append (<list> <element>...)
1761 # <list>: a variable name for a list of single-quoted elements
1762 # <element>: some sequence of characters.
1763 # Output: none, but $<list> is set to
1764 # if <list> is empty: "'<element>' '...'"
1765 # otherwise: "$list '<element>' ..."
1767 # Variable prefix: la
1771 func_check list_append
'>=' 2 "$@";
1773 eval la_list
='"${'$1'}"';
1780 # escape each single quote by replacing each
1781 # "'" (squote) by "'\''" (squote bslash squote squote);
1782 # note that the backslash must be doubled in the following `sed'
1783 la_element
="$(echo x"${la_s}" | sed -e '
1785 s/'"${_SQUOTE}"'/&\\&&/g
1792 la_element
="${la_s}";
1795 if obj la_list is_empty
;
1797 la_list
="'${la_element}'";
1799 la_list
="${la_list} '${la_element}'";
1802 eval "${la_name}"='"${la_list}"';
1803 eval ${_UNSET} la_element
;
1804 eval ${_UNSET} la_list
;
1805 eval ${_UNSET} la_name
;
1806 eval ${_UNSET} la_s
;
1807 eval "${return_ok}";
1811 ########################################################################
1812 # list_from_cmdline (<pre_name_of_opt_lists> [<cmdline_arg>...])
1814 # Transform command line arguments into a normalized form.
1816 # Options, option arguments, and file parameters are identified and
1817 # output each as a single-quoted argument of its own. Options and
1818 # file parameters are separated by a '--' argument.
1821 # <pre_name>: common part of a set of 4 environment variable names:
1822 # $<pre_name>_SHORT_NA: list of short options without an arg.
1823 # $<pre_name>_SHORT_ARG: list of short options that have an arg.
1824 # $<pre_name>_LONG_NA: list of long options without an arg.
1825 # $<pre_name>_LONG_ARG: list of long options that have an arg.
1826 # <cmdline_arg>...: the arguments from a command line, such as "$@",
1827 # the content of a variable, or direct arguments.
1829 # Output: ['-[-]opt' ['optarg']]... '--' ['filename']...
1832 # list_from_cmdline PRE 'a b' 'c' '' 'long' -a f1 -bcarg --long=larg f2
1833 # If $PRE_SHORT_NA, $PRE_SHORT_ARG, $PRE_LONG_NA, and $PRE_LONG_ARG are
1834 # none-empty option lists, this will result in printing:
1835 # '-a' '-b' '-c' 'arg' '--long' 'larg' '--' 'f1' 'f2'
1837 # Use this function in the following way:
1838 # eval set x "$(args_norm PRE_NAME "$@")";
1840 # while test "$1" != '--'; do
1847 # # all positional parameters ("$@") left are file name parameters.
1849 # Variable prefix: lfc
1853 func_check list_from_cmdline
'>=' 1 "$@";
1854 lfc_short_n
="$(obj_data "$1"_SHORT_NA)"; # short options, no argument
1855 lfc_short_a
="$(obj_data "$1"_SHORT_ARG)"; # short options, with argument
1856 lfc_long_n
="$(obj_data "$1"_LONG_NA)"; # long options, no argument
1857 lfc_long_a
="$(obj_data "$1"_LONG_ARG)"; # long options, with argument
1858 if obj lfc_short_n is_empty
;
1860 error
'list_from_cmdline(): no $'"$1"'_SHORT_NA options.';
1862 if obj lfc_short_a is_empty
;
1864 error
'list_from_cmdline(): no $'"$1"'_SHORT_ARG options.';
1866 if obj lfc_long_n is_empty
;
1868 error
'list_from_cmdline(): no $'"$1"'_LONG_NA options.';
1870 if obj lfc_long_a is_empty
;
1872 error
'list_from_cmdline(): no $'"$1"'_LONG_ARG options.';
1875 lfc_fn
='list_from_cmdline():'; # for error messages
1881 eval ${_UNSET} lfc_fparams
;
1882 eval ${_UNSET} lfc_fn
;
1883 eval ${_UNSET} lfc_short_a
;
1884 eval ${_UNSET} lfc_short_n
;
1885 eval ${_UNSET} lfc_long_a
;
1886 eval ${_UNSET} lfc_long_n
;
1887 eval ${_UNSET} lfc_result
;
1888 eval "${return_ok}";
1892 while test "$#" -ge 1;
1896 case "${lfc_arg}" in
1899 # delete leading '--';
1900 lfc_opt
="$(echo x"${lfc_arg}" | sed -e 's/^x--//')";
1901 if list_has lfc_long_n
"${lfc_opt}";
1903 # long option, no argument
1904 list_append lfc_result
"--${lfc_opt}";
1907 # test on `--opt=arg'
1908 if string_contains
"${lfc_opt}" '=';
1910 # extract option by deleting from the first '=' to the end
1911 lfc_lopt
="$(echo x"${lfc_opt}" | sed -e '
1915 if list_has lfc_long_a
"${lfc_lopt}";
1917 # get the option argument by deleting up to first `='
1918 lfc_optarg
="$(echo x"${lfc_opt}" | sed -e '
1922 list_append lfc_result
"--${lfc_lopt}" "${lfc_optarg}";
1926 if list_has lfc_long_a
"${lfc_opt}";
1928 # long option with argument
1931 error
"list_from_cmdline(): \
1932 ${lfc_fn} no argument for option --${lfc_opt}."
1934 list_append lfc_result
"--${lfc_opt}" "$1";
1938 error
"list_from_cmdline(): ${lfc_fn} --${lfc_opt} is not an option."
1940 -?
*) # short option (cluster)
1941 # delete leading `-';
1942 lfc_rest
="$(echo x"${lfc_arg}" | sed -e 's/^x-//')";
1943 while obj lfc_rest is_not_empty
;
1945 # get next short option from cluster (first char of $lfc_rest)
1946 lfc_optchar
="$(echo x"${lfc_rest}" | sed -e 's/^x\(.\).*$/\1/')";
1947 # remove first character from ${lfc_rest};
1948 lfc_rest
="$(echo x"${lfc_rest}" | sed -e 's/^x.//')";
1949 if list_has lfc_short_n
"${lfc_optchar}";
1951 list_append lfc_result
"-${lfc_optchar}";
1953 elif list_has lfc_short_a
"${lfc_optchar}";
1955 if obj lfc_rest is_empty
;
1959 list_append lfc_result
"-${lfc_optchar}" "$1";
1963 error
"list_from_cmdline(): \
1964 ${lfc_fn}"' no argument for option -'"${lfc_optchar}."
1966 else # rest is the argument
1967 list_append lfc_result
"-${lfc_optchar}" "${lfc_rest}";
1972 error
"list_from_cmdline(): \
1973 ${lfc_fn} unknown option -${lfc_optchar}."
1978 # Here, $lfc_arg is not an option, so a file parameter.
1979 list_append lfc_fparams
"${lfc_arg}";
1981 # Ignore the strange option handling of $POSIXLY_CORRECT to
1982 # end option parsing after the first file name argument. To
1983 # reuse it, do a `break' here if $POSIXLY_CORRECT is
1988 list_append lfc_result
'--';
1989 if obj lfc_fparams is_not_empty
;
1991 lfc_result
="${lfc_result} ${lfc_fparams}";
1995 list_append lfc_result
"$@";
2000 eval ${_UNSET} lfc_fparams
;
2001 eval ${_UNSET} lfc_fn
;
2002 eval ${_UNSET} lfc_short_a
;
2003 eval ${_UNSET} lfc_short_n
;
2004 eval ${_UNSET} lfc_long_a
;
2005 eval ${_UNSET} lfc_long_n
;
2006 eval ${_UNSET} lfc_result
;
2007 eval ${_UNSET} lfc_arg
;
2008 eval ${_UNSET} lfc_opt
;
2009 eval ${_UNSET} lfc_opt_arg
;
2010 eval ${_UNSET} lfc_opt_char
;
2011 eval ${_UNSET} lfc_lopt
;
2012 eval ${_UNSET} lfc_rest
;
2013 eval "${return_ok}";
2014 } # list_from_cmdline()
2017 ########################################################################
2018 # list_from_split (<string> <separator>)
2020 # In <string>, escape all white space characters and replace each
2021 # <separator> by space.
2023 # Arguments: 2: a <string> that is to be split into parts divided by
2025 # Output: the resulting list string
2027 # Variable prefix: lfs
2031 func_check list_from_split
= 2 "$@";
2033 # precede each space or tab by a backslash `\' (doubled for `sed')
2034 lfs_s
="$(echo x"$1" | sed -e '
2036 s/\(['"${_SPACE}${_TAB}"']\)/\\\1/g
2039 # replace split character of string by the list separator ` ' (space).
2041 /) # cannot use normal `sed' separator
2042 echo x
"${lfs_s}" |
sed -e '
2047 ?
) # use normal `sed' separator
2048 echo x
"${lfs_s}" |
sed -e '
2054 error
'list_from_split(): separator must be a single character.';
2057 eval ${_UNSET} lfs_s
;
2058 eval "${return_ok}";
2062 ########################################################################
2065 # Check whether <list> is a space-separated list of '-quoted elements.
2067 # If the test fails an error is raised.
2068 # If the test succeeds the argument is echoed.
2071 # A list has the form "'first' 'second' '...' 'last'". So it has a
2072 # leading and a final quote and the elements are separated by "' '"
2073 # constructs. If these are all removed there should not be any
2074 # unescaped single-quotes left. Watch out for escaped single
2075 # quotes; they have the form '\'' (sq bs sq sq).
2078 # Output: the argument <list> unchanged, if the check succeeded.
2080 # Variable prefix: lg
2084 func_check list_get
= 1 "$@";
2085 eval lg_list
='"${'$1'}"';
2086 # remove leading and final space characters
2087 lg_list
="$(echo x"${lg_list}" | sed -e '
2088 s/^x['"${_SPACE}${_TAB}"']*//
2089 s/['"${_SPACE}${_TAB}"']*$//
2091 case "${lg_list}" in
2093 eval ${_UNSET} lg_list
;
2094 eval "${return_ok}";
2100 eval ${_UNSET} lg_list
;
2101 eval "${return_ok}";
2104 error
"list_get(): bad list: $1"
2107 eval ${_UNSET} lg_list
;
2108 eval "${return_ok}";
2112 ########################################################################
2113 # list_has (<var_name> <element>)
2116 # <var_name>: a variable name for a list of single-quoted elements
2117 # <element>: some sequence of characters.
2119 # if <list> is empty: "'<element>' '...'"
2120 # otherwise: "list '<element>' ..."
2124 func_check list_has
= 2 "$@";
2125 eval _list
='"${'$1'}"';
2126 if obj _list is_empty
;
2128 eval "${return_no}";
2132 \'*\') _element
="$2"; ;;
2133 *) _element
="'$2'"; ;;
2135 if string_contains
"${_list}" "${_element}";
2137 eval "${return_yes}";
2139 eval "${return_no}";
2141 eval "${return_ok}";
2145 ########################################################################
2146 # list_has_not (<list> <element>)
2149 # <list>: a space-separated list of single-quoted elements.
2150 # <element>: some sequence of characters.
2152 # if <list> is empty: "'<element>' '...'"
2153 # otherwise: "<list> '<element>' ..."
2157 func_check list_has_not
= 2 "$@";
2158 eval _list
='"${'$1'}"';
2159 if obj _list is_empty
;
2161 eval "${return_yes}";
2165 \'*\') _element
="$2"; ;;
2166 *) _element
="'$2'"; ;;
2168 if string_contains
"${_list}" "${_element}";
2170 eval "${return_no}";
2172 eval "${return_yes}";
2174 eval "${return_ok}";
2178 ########################################################################
2179 landmark
'7: man_*()';
2180 ########################################################################
2182 ########################################################################
2183 # man_do_filespec (<filespec>)
2185 # Print suitable man page(s) for filespec to $_TMP_CAT.
2188 # <filespec>: argument of the form `man:name.section', `man:name',
2189 # `man:name(section)', `name.section', `name'.
2191 # Globals : $_OPT_ALL
2194 # Return : `0' if man page was found, `1' else.
2196 # Only called from do_fileargs(), checks on $MANPATH and
2197 # $_MAN_ENABLE are assumed.
2199 # Variable prefix: mdf
2203 func_check man_do_filespec
= 1 "$@";
2204 if obj _MAN_PATH is_empty
;
2206 eval "${return_bad}";
2210 eval "${return_bad}";
2215 case "${mdf_spec}" in
2216 */*) # not a man spec when it contains '/'
2217 eval ${_UNSET} mdf_got_one
;
2218 eval ${_UNSET} mdf_name
;
2219 eval ${_UNSET} mdf_section
;
2220 eval ${_UNSET} mdf_spec
;
2221 eval "${return_bad}";
2223 man
:?
*\
(?
*\
)) # man:name(section)
2224 mdf_name
="$(echo x"${mdf_spec}" \
2225 | sed -e 's/^xman:\(..*\)(\(..*\))$/\1/')";
2226 mdf_section
="$(echo x"${mdf_spec}" \
2227 | sed -e 's/^xman:\(..*\)(\(..*\))$/\2/')";
2229 man
:?
*.
[0-9on]) # man:name.section
2230 mdf_name
="$(echo x"${mdf_spec}" \
2231 | sed -e 's/^xman:\(..*\)\..$/\1/')";
2232 mdf_section
="$(echo x"${mdf_spec}" \
2233 | sed -e 's/^x.*\(.\)$/\1/')";
2236 mdf_name
="$(echo x"${mdf_spec}" | sed -e 's/^xman://')";
2238 ?
*\
(?
*\
)) # name(section)
2239 mdf_name
="$(echo x"${mdf_spec}" \
2240 | sed -e 's/^x\(..*\)(\(..*\))$/\1/')";
2241 mdf_section
="$(echo x"${mdf_spec}" \
2242 | sed -e 's/^x\(..*\)(\(..*\))$/\2/')";
2244 ?
*.
[0-9on]) # name.section
2245 mdf_name
="$(echo x"${mdf_spec}" \
2246 | sed -e 's/^x\(..*\)\..$/\1/')";
2247 mdf_section
="$(echo x"${mdf_spec}" \
2248 | sed -e 's/^x.*\(.\)$/\1/')";
2251 mdf_name
="${mdf_spec}";
2254 if obj mdf_name is_empty
;
2256 eval ${_UNSET} mdf_got_one
;
2257 eval ${_UNSET} mdf_name
;
2258 eval ${_UNSET} mdf_section
;
2259 eval ${_UNSET} mdf_spec
;
2260 eval "${return_bad}";
2263 if obj mdf_section is_empty
;
2265 eval set x
"${_MAN_AUTO_SEC}";
2270 if man_search_section
"${mdf_name}" "${mdf_s}";
2272 if obj _MAN_ALL is_yes
;
2276 eval ${_UNSET} mdf_got_one
;
2277 eval ${_UNSET} mdf_name
;
2278 eval ${_UNSET} mdf_s
;
2279 eval ${_UNSET} mdf_section
;
2280 eval ${_UNSET} mdf_spec
;
2281 eval "${return_good}";
2286 if man_search_section
"${mdf_name}" "${mdf_section}";
2288 eval ${_UNSET} mdf_got_one
;
2289 eval ${_UNSET} mdf_name
;
2290 eval ${_UNSET} mdf_s
;
2291 eval ${_UNSET} mdf_section
;
2292 eval ${_UNSET} mdf_spec
;
2293 eval "${return_good}";
2295 eval ${_UNSET} mdf_got_one
;
2296 eval ${_UNSET} mdf_name
;
2297 eval ${_UNSET} mdf_section
;
2298 eval ${_UNSET} mdf_spec
;
2299 eval "${return_bad}";
2302 if obj _MAN_ALL is_yes
&& is_yes
"${mdf_got_one}";
2304 eval ${_UNSET} mdf_got_one
;
2305 eval ${_UNSET} mdf_name
;
2306 eval ${_UNSET} mdf_s
;
2307 eval ${_UNSET} mdf_section
;
2308 eval ${_UNSET} mdf_spec
;
2309 eval "${return_good}";
2311 eval ${_UNSET} mdf_got_one
;
2312 eval ${_UNSET} mdf_name
;
2313 eval ${_UNSET} mdf_s
;
2314 eval ${_UNSET} mdf_section
;
2315 eval ${_UNSET} mdf_spec
;
2316 eval "${return_bad}";
2317 } # man_do_filespec()
2320 ########################################################################
2321 # man_register_file (<file> <name> [<section>])
2323 # Write a found man page file and register the title element.
2325 # Arguments: 1, 2, or 3; maybe empty
2330 func_check man_register_file
'>=' 2 "$@";
2334 error
"man_register_file() expects 2 or 3 arguments.";
2339 error
'man_register_file(): file name is empty';
2344 register_title
"man:$2";
2345 eval "${return_ok}";
2348 register_title
"$2.$3";
2349 eval "${return_ok}";
2352 eval "${return_ok}";
2356 ########################################################################
2357 # man_search_section (<name> <section>)
2359 # Retrieve man pages.
2362 # Globals : $_MAN_PATH, $_MAN_EXT
2363 # Return : 0 if found, 1 otherwise
2365 # Variable prefix: mss
2367 man_search_section
()
2369 func_check man_search_section
= 2 "$@";
2370 if obj _MAN_PATH is_empty
;
2372 eval "${return_bad}";
2376 eval "${return_bad}";
2380 eval "${return_bad}";
2384 eval set x
"$(path_split "${_MAN_PATH}")";
2387 if obj _MAN_EXT is_empty
;
2391 mss_dir
="$(dirname_append "$d" "man
${mss_section}")";
2392 if obj mss_dir is_dir
;
2395 dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
2396 mss_files
="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
2397 sed -e '\| found|s|.*||'
2399 if obj mss_files is_not_empty
;
2401 # for f in $mss_files
2402 for f
in $
(eval set x
${mss_files}; shift; echo "$@")
2405 if obj mss_f is_file
;
2407 if is_yes
"${mss_got_one}";
2409 register_file
"${mss_f}";
2410 elif obj _MAN_ALL is_yes
;
2412 man_register_file
"${mss_f}" "${mss_name}";
2414 man_register_file
"${mss_f}" "${mss_name}" "${mss_section}";
2415 eval ${_UNSET} mss_dir
;
2416 eval ${_UNSET} mss_ext
;
2417 eval ${_UNSET} mss_f
;
2418 eval ${_UNSET} mss_files
;
2419 eval ${_UNSET} mss_got_one
;
2420 eval ${_UNSET} mss_name
;
2421 eval ${_UNSET} mss_prefix
;
2422 eval ${_UNSET} mss_section
;
2423 eval "${return_good}";
2432 mss_ext
="${_MAN_EXT}";
2433 # check for directory name having trailing extension
2436 mss_dir
="$(dirname_append $d man${mss_section}${mss_ext})";
2437 if obj mss_dir is_dir
;
2440 "$(dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
2441 mss_files
="$( eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
2442 sed -e '\|not found|s|.*||'
2444 if obj mss_files is_not_empty
;
2446 # for f in $mss_files
2447 for f
in $
(eval set x
${mss_files}; shift; echo "$@")
2450 if obj mss_f is_file
;
2452 if is_yes
"${mss_got_one}";
2454 register_file
"${mss_f}";
2455 elif obj _MAN_ALL is_yes
;
2457 man_register_file
"${mss_f}" "${mss_name}";
2459 man_register_file
"${mss_f}" "${mss_name}" "${mss_section}";
2460 eval ${_UNSET} mss_dir
;
2461 eval ${_UNSET} mss_ext
;
2462 eval ${_UNSET} mss_f
;
2463 eval ${_UNSET} mss_files
;
2464 eval ${_UNSET} mss_got_one
;
2465 eval ${_UNSET} mss_name
;
2466 eval ${_UNSET} mss_prefix
;
2467 eval ${_UNSET} mss_section
;
2468 eval "${return_good}";
2476 # check for files with extension in directories without extension
2479 mss_dir
="$(dirname_append "$d" "man
${mss_section}")";
2480 if obj mss_dir is_dir
;
2482 mss_prefix
="$(dirname_append "${mss_dir}" \
2483 "${mss_name}.${mss_section}${mss_ext}")";
2484 mss_files
="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
2485 sed -e '\|not found|s|.*||'
2487 if obj mss_files is_not_empty
;
2489 # for f in $mss_files
2490 for f
in $
(eval set x
${mss_files}; shift; echo "$@")
2493 if obj mss_f is_file
;
2495 if is_yes
"${mss_got_one}";
2497 register_file
"${mss_f}";
2498 elif obj _MAN_ALL is_yes
;
2500 man_register_file
"${mss_f}" "${mss_name}";
2502 man_register_file
"${mss_f}" "${mss_name}" "${mss_section}";
2503 eval ${_UNSET} mss_dir
;
2504 eval ${_UNSET} mss_ext
;
2505 eval ${_UNSET} mss_f
;
2506 eval ${_UNSET} mss_files
;
2507 eval ${_UNSET} mss_got_one
;
2508 eval ${_UNSET} mss_name
;
2509 eval ${_UNSET} mss_prefix
;
2510 eval ${_UNSET} mss_section
;
2511 eval "${return_good}";
2520 if obj _MAN_ALL is_yes
&& is_yes
"${mss_got_one}";
2522 eval ${_UNSET} mss_dir
;
2523 eval ${_UNSET} mss_ext
;
2524 eval ${_UNSET} mss_f
;
2525 eval ${_UNSET} mss_files
;
2526 eval ${_UNSET} mss_got_one
;
2527 eval ${_UNSET} mss_name
;
2528 eval ${_UNSET} mss_prefix
;
2529 eval ${_UNSET} mss_section
;
2530 eval "${return_good}";
2532 eval ${_UNSET} mss_dir
;
2533 eval ${_UNSET} mss_ext
;
2534 eval ${_UNSET} mss_f
;
2535 eval ${_UNSET} mss_files
;
2536 eval ${_UNSET} mss_got_one
;
2537 eval ${_UNSET} mss_name
;
2538 eval ${_UNSET} mss_prefix
;
2539 eval ${_UNSET} mss_section
;
2540 eval "${return_bad}";
2541 } # man_search_section()
2544 ########################################################################
2547 # Setup the variables $_MAN_* needed for man page searching.
2550 # in: $_OPT_*, $_MANOPT_*, $LANG, $LC_MESSAGES, $LC_ALL,
2551 # $MANPATH, $MANROFFSEQ, $MANSEC, $PAGER, $SYSTEM, $MANOPT.
2552 # out: $_MAN_PATH, $_MAN_LANG, $_MAN_SYS, $_MAN_LANG, $_MAN_LANG2,
2553 # $_MAN_SEC, $_MAN_ALL
2554 # in/out: $_MAN_ENABLE
2556 # The precedence for the variables related to `man' is that of GNU
2559 # $LANG; overridden by
2560 # $LC_MESSAGES; overridden by
2561 # $LC_ALL; this has the same precedence as
2562 # $MANPATH, $MANROFFSEQ, $MANSEC, $PAGER, $SYSTEM; overridden by
2563 # $MANOPT; overridden by
2564 # the groffer command line options.
2566 # Variable prefix: ms
2570 func_check main_man_setup
= 0 "$@";
2572 if obj _MAN_IS_SETUP is_yes
;
2574 eval "${return_ok}";
2576 _MAN_IS_SETUP
='yes';
2578 if obj _MAN_ENABLE is_not_yes
;
2580 eval "${return_ok}";
2583 # determine basic path for man pages
2584 _MAN_PATH
="$(get_first_essential \
2585 "${_OPT_MANPATH}" "${_MANOPT_PATH}" "${MANPATH}")";
2586 if obj _MAN_PATH is_empty
;
2588 manpath_set_from_path
;
2590 _MAN_PATH
="$(path_clean "${_MAN_PATH}")";
2592 if obj _MAN_PATH is_empty
;
2594 if is_prog
'manpath';
2596 _MAN_PATH
="$(manpath 2>${_NULL_DEV})"; # not always available
2599 if obj _MAN_PATH is_empty
;
2602 eval "${return_ok}";
2605 _MAN_ALL
="$(get_first_essential "${_OPT_ALL}" "${_MANOPT_ALL}")";
2606 if obj _MAN_ALL is_empty
;
2611 _MAN_SYS
="$(get_first_essential \
2612 "${_OPT_SYSTEMS}" "${_MANOPT_SYS}" "${SYSTEM}")";
2613 ms_lang
="$(get_first_essential \
2614 "${_OPT_LANG}" "${LC_ALL}" "${LC_MESSAGES}" "${LANG}")";
2615 case "${ms_lang}" in
2621 _MAN_LANG
="${ms_lang}";
2625 _MAN_LANG
="${ms_lang}";
2626 # get first two characters of $ms_lang
2627 _MAN_LANG2
="$(echo x"${ms_lang}" | sed -e 's/^x\(..\).*$/\1/')";
2630 # from now on, use only $_LANG, forget about $_OPT_LANG, $LC_*.
2632 manpath_add_lang_sys
; # this is very slow
2634 _MAN_SEC
="$(get_first_essential \
2635 "${_OPT_SECT}" "${_MANOPT_SEC}" "${MANSEC}")";
2636 if obj _MAN_PATH is_empty
;
2639 eval ${_UNSET} ms_lang
;
2640 eval "${return_ok}";
2643 _MAN_EXT
="$(get_first_essential \
2644 "${_OPT_EXTENSION}" "${_MANOPT_EXTENSION}")";
2645 eval ${_UNSET} ms_lang
;
2646 eval "${return_ok}";
2650 ########################################################################
2651 landmark
'8: manpath_*()';
2652 ########################################################################
2654 ########################################################################
2655 # manpath_add_lang_sys ()
2657 # Add language and operating system specific directories to man path.
2662 # in: $_MAN_SYS: has the form `os1,os2,...', a comma separated
2663 # list of names of operating systems.
2664 # $_MAN_LANG and $_MAN_LANG2: each a single name
2665 # in/out: $_MAN_PATH: has the form `dir1:dir2:...', a colon
2666 # separated list of directories.
2668 # Variable prefix: mals
2670 manpath_add_lang_sys
()
2672 func_check manpath_add_lang_sys
= 0 "$@";
2673 if obj _MAN_PATH is_empty
;
2675 eval "${return_ok}";
2677 # twice test both sys and lang
2678 eval set x
"$(path_split "${_MAN_PATH}")";
2682 do # loop on man path directories
2683 mals_mp
="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
2685 eval set x
"$(path_split "${mals_mp}")";
2688 do # loop on man path directories
2689 mals_mp
="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
2691 _MAN_PATH
="$(path_chop "${mals_mp}")";
2692 eval ${_UNSET} mals_mp
;
2693 eval "${return_ok}";
2697 # To the directory in $1 append existing sys/lang subdirectories
2698 # Function is necessary to split the OS list.
2700 # globals: in: $_MAN_SYS, $_MAN_LANG, $_MAN_LANG2
2701 # argument: 2: `man_path' and `dir'
2702 # output: colon-separated path of the retrieved subdirectories
2704 # Variable prefix: _mals
2706 _manpath_add_lang_sys_single
()
2708 func_check _manpath_add_lang_sys_single
= 2 "$@";
2711 eval set x
"$(list_from_split "${_MAN_SYS}" ',')";
2713 for d
in "$@" "${_MAN_LANG}" "${_MAN_LANG2}"
2715 _mals_dir
="$(dirname_append "${_mals_parent}" "$d")";
2716 if obj _mals_res path_not_contains
"${_mals_dir}" && \
2717 obj _mals_dir is_dir
;
2719 _mals_res
="${_mals_res}:${_mals_dir}";
2722 if path_not_contains
"${_mals_res}" "${_mals_parent}";
2724 _mals_res
="${_mals_res}:${_mals_parent}";
2726 path_chop
"${_mals_res}";
2727 eval ${_UNSET} _mals_dir
;
2728 eval ${_UNSET} _mals_parent
;
2729 eval ${_UNSET} _mals_res
;
2730 eval "${return_ok}";
2733 # end manpath_add_lang_sys ()
2736 ########################################################################
2737 # manpath_set_from_path ()
2739 # Determine basic search path for man pages from $PATH.
2741 # Return: `0' if a valid man path was retrieved.
2747 # Variable prefix: msfp
2749 manpath_set_from_path
()
2751 func_check manpath_set_from_path
= 0 "$@";
2755 # get a basic man path from $PATH
2756 if obj PATH is_not_empty
;
2758 eval set x
"$(path_split "${PATH}")";
2762 # delete the final `/bin' part
2763 msfp_base
="$(echo x"$d" | sed -e '
2767 for e
in /share
/man
/man
2769 msfp_mandir
="${msfp_base}$e";
2770 if test -d "${msfp_mandir}" && test -r "${msfp_mandir}";
2772 msfp_manpath
="${msfp_manpath}:${msfp_mandir}";
2778 # append some default directories
2779 for d
in /usr
/local
/share
/man
/usr
/local
/man \
2780 /usr
/share
/man
/usr
/man \
2781 /usr
/X11R
6/man
/usr
/openwin
/man \
2782 /opt
/share
/man
/opt
/man \
2783 /opt
/gnome
/man
/opt
/kde
/man
2786 if obj msfp_manpath path_not_contains
"${msfp_d}" && obj mfsp_d is_dir
;
2788 msfp_manpath
="${msfp_manpath}:${mfsp_d}";
2792 _MAN_PATH
="${msfp_manpath}";
2793 eval ${_UNSET} msfp_base
;
2794 eval ${_UNSET} msfp_d
;
2795 eval ${_UNSET} msfp_mandir
;
2796 eval ${_UNSET} msfp_manpath
;
2797 eval "${return_ok}";
2798 } # manpath_set_from_path()
2801 ########################################################################
2802 landmark
'9: obj_*()';
2803 ########################################################################
2805 ########################################################################
2806 # obj (<object> <call_name> <arg>...)
2808 # This works like a method (object function) call for an object.
2809 # Run "<call_name> $<object> <arg> ...".
2811 # The first argument represents an object whose data is given as first
2812 # argument to <call_name>().
2815 # <object>: variable name
2816 # <call_name>: a program or function name
2818 # Variable prefix: o
2822 func_check obj
'>=' 2 "$@";
2825 error
"obj(): function name is empty."
2829 eval o_arg1
='"${'$1'}"';
2832 eval "${o_func}"' "${o_arg1}" "$@"';
2834 eval ${_UNSET} o_arg1
;
2835 eval ${_UNSET} o_func
;
2836 eval "${return_var} $n";
2840 ########################################################################
2841 # obj_data (<object>)
2843 # Print the data of <object>, i.e. the content of $<object>.
2844 # For possible later extensions.
2847 # <object>: a variable name
2848 # Output: the data of <object>
2850 # Variable prefix: od
2854 func_check obj
'=' 1 "$@";
2857 error
"obj_data(): object name is empty."
2859 eval od_res
='"${'$1'}"';
2863 eval ${_UNSET} od_res
;
2864 eval "${return_ok}";
2868 ########################################################################
2869 # obj_from_output (<object> <call_name> <arg>...)
2871 # Run '$<object>="$(<call_name> <arg>...)"' to set the result of a
2872 # function call to a global variable.
2875 # <object>: a variable name
2876 # <call_name>: the name of a function or program
2877 # <arg>: optional argument to <call_name>
2880 # Variable prefix: ofo
2884 func_check obj_from_output
'>=' 2 "$@";
2887 error
"res(): variable name is empty.";
2890 error
"res(): function name is empty."
2892 ofo_result_name
="$1";
2895 eval "${ofo_result_name}"'="$('"$@"')"';
2896 eval "${return_ok}";
2900 ########################################################################
2901 # obj_set (<object> <data>)
2903 # Set the data of <object>, i.e. call "$<object>=<data>".
2906 # <object>: a variable name
2912 func_check obj_set
'=' 2 "$@";
2915 error
"obj_set(): object name is empty."
2918 eval "${return_ok}";
2922 ########################################################################
2923 # path_chop (<path>)
2925 # Remove unnecessary colons from path.
2927 # Argument: 1, a colon separated path.
2928 # Output: path without leading, double, or trailing colons.
2932 func_check path_chop
= 1 "$@";
2934 # replace multiple colons by a single colon `:'
2935 # remove leading and trailing colons
2936 echo x
"$1" |
sed -e '
2941 eval "${return_ok}";
2945 ########################################################################
2946 # path_clean (<path>)
2948 # Remove non-existing directories from a colon-separated list.
2950 # Argument: 1, a colon separated path.
2951 # Output: colon-separated list of existing directories.
2953 # Variable prefix: pc
2957 func_check path_clean
= 1 "$@";
2958 if is_not_equal
"$#" 1;
2960 error
'path_clean() needs 1 argument.';
2963 eval set x
"$(path_split "${pc_arg}")";
2969 if obj pc_i is_not_empty \
2970 && obj pc_res path_not_contains
"${pc_i}" \
2974 ?
*/) pc_res
="${pc_res}$(dirname_chop "${pc_i}")"; ;;
2975 *) pc_res
="${pc_res}:${pc_i}";
2979 eval ${_UNSET} pc_arg
;
2980 eval ${_UNSET} pc_i
;
2981 eval ${_UNSET} pc_res
;
2982 if path_chop
"${pc_res}";
2984 eval "${return_ok}";
2986 eval "${return_bad}";
2991 ########################################################################
2992 # path_contains (<path> <dir>)
2994 # Test whether `dir' is contained in `path', a list separated by `:'.
2996 # Arguments : 2 arguments.
2997 # Return : `0' if arg2 is substring of arg1, `1' otherwise.
3001 func_check path_contains
= 2 "$@";
3004 eval "${return_yes}";
3007 eval "${return_no}";
3010 eval "${return_ok}";
3014 ########################################################################
3015 # path_not_contains (<path> <dir>)
3017 # Test whether `dir' is not contained in colon separated `path'.
3019 # Arguments : 2 arguments.
3023 func_check path_not_contains
= 2 "$@";
3024 if path_contains
"$1" "$2";
3026 eval "${return_no}";
3028 eval "${return_yes}";
3030 eval "${return_ok}";
3034 ########################################################################
3035 # path_split (<path>)
3037 # In `path' escape white space and replace each colon by a space.
3039 # Arguments: 1: a colon-separated path
3040 # Output: the resulting list, process with `eval set'
3044 func_check path_split
= 1 "$@";
3045 list_from_split
"$1" ':';
3046 eval "${return_ok}";
3050 ########################################################################
3051 landmark
'10: register_*()';
3052 ########################################################################
3054 ########################################################################
3055 # register_file (<filename>)
3057 # Write a found file and register the title element.
3059 # Arguments: 1: a file name
3064 func_check register_file
= 1 "$@";
3067 error
'register_file(): file name is empty';
3069 if is_equal
"$1" '-';
3071 to_tmp
"${_TMP_STDIN}";
3072 register_title
'stdin';
3075 register_title
"$(base_name "$1")";
3077 eval "${return_ok}";
3081 ########################################################################
3082 # register_title (<filespec>)
3084 # Create title element from <filespec> and append to $_REGISTERED_TITLE
3086 # Globals: $_REGISTERED_TITLE (rw)
3088 # Variable prefix: rt
3092 func_check register_title
= 1 "$@";
3095 eval "${return_ok}";
3097 rt_title
="$(base_name "$1")"; # remove directory part
3099 # remove extension `.gz'
3100 rt_title
="$(echo x"${rt_title}" | sed -e '
3104 # remove extension `.Z'
3105 rt_title
="$(echo x"${rt_title}" | sed -e '
3110 if obj rt_title is_empty
;
3112 eval "${return_ok}";
3114 _REGISTERED_TITLE
="${_REGISTERED_TITLE} ${rt_title}";
3115 eval ${_UNSET} rt_title
;
3116 eval "${return_ok}";
3120 ########################################################################
3123 # Reset the variables that can be affected by options to their default.
3126 # Defined in section `Preset' after the rudimentary shell tests.
3129 ########################################################################
3132 # Store standard input to temporary file (with decompression).
3134 # Variable prefix: ss
3136 if obj _HAS_COMPRESSION is_yes
;
3140 func_check save_stdin
= 0 "$@";
3141 ss_f
="${_TMP_DIR}"/INPUT
;
3143 cat_z
"${ss_f}" >"${_TMP_STDIN}";
3145 eval ${_UNSET} ss_f
;
3146 eval "${return_ok}";
3151 func_check save_stdin
= 0 "$@";
3152 cat >"${_TMP_STDIN}";
3153 eval "${return_ok}";
3158 ########################################################################
3159 landmark
'11: stack_*()';
3160 ########################################################################
3162 ########################################################################
3163 # string_contains (<string> <part>)
3165 # Test whether `part' is contained in `string'.
3167 # Arguments : 2 text arguments.
3168 # Return : `0' if arg2 is substring of arg1, `1' otherwise.
3172 func_check string_contains
= 2 "$@";
3175 eval "${return_yes}";
3178 eval "${return_no}";
3181 eval "${return_ok}";
3185 ########################################################################
3186 # string_not_contains (<string> <part>)
3188 # Test whether `part' is not substring of `string'.
3190 # Arguments : 2 text arguments.
3191 # Return : `0' if arg2 is substring of arg1, `1' otherwise.
3193 string_not_contains
()
3195 func_check string_not_contains
= 2 "$@";
3196 if string_contains
"$1" "$2";
3198 eval "${return_no}";
3200 eval "${return_yes}";
3202 eval "${return_ok}";
3206 ########################################################################
3207 landmark
'12: tmp_*()';
3208 ########################################################################
3210 ########################################################################
3213 # output the temporary cat file (the concatenation of all input)
3217 func_check tmp_cat
'=' 0 "$@";
3219 eval "${return_var}" "$?";
3223 ########################################################################
3224 # tmp_create (<suffix>?)
3226 # Create temporary file.
3228 # It's safe to use the shell process ID together with a suffix to
3229 # have multiple temporary files.
3231 # Globals: $_TMP_DIR
3233 # Output : name of created file
3235 # Variable prefix: tc
3239 func_check tmp_create
'<=' 1 "$@";
3240 # the output file does not have `,' as first character, so these are
3241 # different names from the output file.
3242 tc_tmp
="${_TMP_DIR}/,$1";
3247 eval ${_UNSET} tc_tmp
;
3248 eval "${return_ok}";
3252 ########################################################################
3253 # to_tmp (<filename>)
3255 # print file (decompressed) to the temporary cat file
3259 func_check to_tmp
= 1 "$@";
3262 if obj _OPT_LOCATION is_yes
;
3266 if obj _OPT_WHATIS is_yes
;
3268 what_is
"$1" >>"${_TMP_CAT}";
3270 cat_z
"$1" >>"${_TMP_CAT}";
3273 error
"to_tmp(): could not read file \`$1'.";
3275 eval "${return_ok}";
3279 ########################################################################
3282 # disable trap on all exit codes ($_ALL_EXIT)
3285 # Globals: $_ALL_EXIT
3289 func_check trap_clean
= 0 "$@";
3290 # for i in $_ALL_EXIT
3291 for i
in $
(eval set x
${_ALL_EXIT}; shift; echo "$@")
3293 trap "" "$i" 2>${_NULL_DEV} ||
:;
3295 eval "${return_ok}";
3299 ########################################################################
3300 # trap_set (<functionname>)
3302 # call function on all exit codes ($_ALL_EXIT)
3304 # Arguments: 1 (name of a shell function)
3305 # Globals: $_ALL_EXIT
3309 func_check trap_set
= 1 "$@";
3310 # for i in $_ALL_EXIT
3311 for i
in $
(eval set x
${_ALL_EXIT}; shift; echo "$@")
3313 trap "$1" "$i" 2>${_NULL_DEV} ||
:;
3315 eval "${return_ok}";
3319 ########################################################################
3322 # print usage information to stderr; for groffer option --help.
3326 func_check usage
= 0 "$@";
3329 echo 'Usage: '"${_PROGRAM_NAME}"' [option]... [filespec]...';
3332 Display roff files, standard input, and/or Unix manual pages with a X
3333 Window viewer or in several text modes. All input is decompressed
3334 on-the-fly with all formats that gzip can handle.
3336 "filespec" is one of
3337 "filename" name of a readable file
3338 "-" for standard input
3339 "man:name.n" man page "name" in section "n"
3340 "man:name" man page "name" in first section found
3341 "name.n" man page "name" in section "n"
3342 "name" man page "name" in first section found
3343 and some more (see groffer(1) for details).
3345 -h --help print this usage message.
3346 -Q --source output as roff source.
3347 -T --device=name pass to groff using output device "name".
3348 -v --version print version information.
3349 -V display the groff execution pipe instead of formatting.
3350 -X --X --x display with "gxditview" using groff -X.
3351 -Z --ditroff --intermediate-output
3352 generate groff intermediate output without
3353 post-processing and viewing, like groff -Z.
3354 All other short options are interpreted as "groff" formatting options.
3356 The most important groffer long options are
3358 --apropos=name start man's "apropos" program for "name".
3360 "apropos" for "name" in man's data sections 4, 5, 7.
3361 --apropos-devel=name
3362 "apropos" for "name" in development sections 2, 3, 9.
3363 --apropos-progs=name
3364 "apropos" for "name" in man's program sections 1, 6, 8.
3365 --auto choose mode automatically from the default mode list.
3366 --default reset all options to the default value.
3367 --default-modes=mode1,mode2,...
3368 set sequence of automatically tried modes.
3369 --dvi display in a viewer for TeX device independent format.
3370 --dvi-viewer choose the viewer program for dvi mode.
3371 --groff process like groff, disable viewing features.
3372 --help display this helping output.
3373 --html --www display in a web browser.
3374 --html-viewer choose the web browser for www mode.
3375 --man check file parameters first whether they are man pages.
3376 --mode=auto|dvi|groff|html|pdf|ps|source|text|tty|www|x|X
3377 choose display mode.
3378 --no-man disable man-page facility.
3379 --pager=program preset the paging program for tty mode.
3380 --pdf display in a PDF viewer.
3381 --pdf-viewer choose the viewer program for pdf mode.
3382 --ps display in a Postscript viewer.
3383 --ps-viewer choose the viewer program for ps mode.
3384 --shell specify shell under which to run this program.
3385 --text output in a text device without a pager.
3386 --tty display with a pager on text terminal even when in X.
3387 --www-viewer same as --html-viewer
3388 --x-viewer choose viewer program for x mode (X mode).
3389 --X-viewer same as "--xviewer".
3391 The usual X Windows toolkit options transformed into GNU long options
3392 --background=color, --bd=size, --bg=color, --bordercolor=color,
3393 --borderwidth=size, --bw=size, --display=Xdisplay, --fg=color,
3394 --fn=font, --font=font, --foreground=color, --geometry=geom, --iconic,
3395 --resolution=dpi, --rv, --title=text, --xrm=resource
3397 Long options of GNU "man"
3398 --all, --ascii, --ditroff, --extension=suffix, --locale=language,
3399 --local-file=name, --location, --manpath=dir1:dir2:...,
3400 --sections=s1:s2:..., --systems=s1,s2,..., --whatis, --where, ...
3403 eval "${return_ok}";
3407 ########################################################################
3410 # print version information to stderr
3414 func_check version
= 0 "$@";
3415 echo2
"${_PROGRAM_NAME} ${_PROGRAM_VERSION} of ${_LAST_UPDATE}";
3416 # also display groff's version, but not the called subprograms
3417 groff -v 2>&1 |
sed -e '/^ *$/q' |
sed -e '1s/^/is part of /' >&2;
3418 eval "${return_ok}";
3422 ########################################################################
3423 # warning (<string>)
3425 # Print warning to stderr
3429 echo2
"warning: $*";
3433 ########################################################################
3434 # what_is (<filename>)
3436 # Interpret <filename> as a man page and display its `whatis'
3437 # information as a fragment written in the groff language.
3439 # Variable prefix: wi
3443 func_check what_is
= 1 "$@";
3444 if is_not_file
"$1";
3446 error
"what_is(): argument is not a readable file."
3448 wi_dot
='^\.['"${_SPACE}${_TAB}"']*';
3454 # grep the line containing `.TH' macro, if any
3455 wi_res
="$(cat_z "$1" | sed -e '/'"${wi_dot}"'TH /p
3457 if obj wi_res is_not_empty
;
3458 then # traditional man style
3459 # get the text between the first and the second `.SH' macro, by
3460 # - delete up to first .SH;
3461 # - of this, print everything up to next .SH, and delete the rest;
3462 # - of this, delete the final .SH line;
3463 cat_z
"$1" |
sed -e '1,/'"${wi_dot}"'SH/d' \
3464 |
sed -e '1,/'"${wi_dot}"'SH/p
3466 |
sed -e '/'"${wi_dot}"'SH/d';
3467 eval ${_UNSET} wi_dot
;
3468 eval ${_UNSET} wi_res
;
3469 eval "${return_ok}";
3471 # grep the line containing `.Dd' macro, if any
3472 wi_res
="$(cat_z "$1" | sed -e '/'"${wi_dot}"'Dd /p
3474 if obj wi_res is_not_empty
;
3475 then # BSD doc style
3476 # get the text between the first and the second `.Nd' macro, by
3477 # - delete up to first .Nd;
3478 # - of this, print everything up to next .Nd, and delete the rest;
3479 # - of this, delete the final .Nd line;
3480 cat_z
"$1" |
sed -e '1,/'"${wi_dot}"'Nd/d' \
3481 |
sed -e '1,/'"${wi_dot}"'Nd/p
3483 |
sed -e '/'"${wi_dot}"'Nd/d';
3484 eval ${_UNSET} wi_dot
;
3485 eval ${_UNSET} wi_res
;
3486 eval "${return_ok}";
3488 echo 'is not a man page.';
3489 eval ${_UNSET} wi_dot
;
3490 eval ${_UNSET} wi_res
;
3491 eval "${return_bad}";
3495 ########################################################################
3496 # where_is (<program>)
3498 # Output path of a program if in $PATH.
3500 # Arguments : >=1 (empty allowed)
3501 # more args are ignored, this allows to specify progs with arguments
3502 # Return : `0' if arg1 is a program in $PATH, `1' otherwise.
3504 # Variable prefix: w
3508 func_check where_is
'>=' 1 "$@";
3510 if obj w_arg is_empty
;
3512 eval ${_UNSET} w_arg
;
3513 eval "${return_bad}";
3517 eval ${_UNSET} w_arg
;
3518 eval ${_UNSET} w_file
;
3519 if test -f "${w_arg}" && test -x "${w_arg}";
3521 eval "${return_ok}";
3523 eval "${return_bad}";
3527 eval set x
"$(path_split "${PATH}")";
3532 */) w_file
=${p}${w_arg}; ;;
3533 *) w_file
=${p}/${w_arg}; ;;
3535 if test -f "${w_file}" && test -x "${w_file}";
3540 eval ${_UNSET} w_arg
;
3541 eval ${_UNSET} w_file
;
3542 eval "${return_ok}";
3545 eval ${_UNSET} w_arg
;
3546 eval ${_UNSET} w_file
;
3547 eval "${return_bad}";
3551 ########################################################################
3553 ########################################################################
3555 # The main area contains the following parts:
3556 # - main_init(): initialize temporary files and set exit trap
3557 # - main_parse_MANOPT(): parse $MANOPT
3558 # - main_parse_args(): argument parsing
3559 # - main_set_mode (): determine the display mode
3560 # - main_do_fileargs(): process filespec arguments
3561 # - main_set_resources(): setup X resources
3562 # - main_display(): do the displaying
3563 # - main(): the main function that calls all main_*()
3565 # These parts are implemented as functions, being defined below in the
3566 # sequence they are called in the main() function.
3569 landmark
'13: main_init()';
3570 #######################################################################
3573 # set exit trap and create temporary files
3575 # Globals: $_TMP_DIR, $_TMP_CAT, $_TMP_STDIN
3577 # Variable prefix: mi
3581 func_check main_init
= 0 "$@";
3582 # call clean_up() on any signal
3585 # create temporary directory
3588 for d
in "${GROFF_TMPDIR}" "${TMPDIR}" "${TMP}" "${TEMP}" \
3589 "${TEMPDIR}" "${HOME}"'/tmp' '/tmp' "${HOME}" '.'
3592 if obj mi_dir is_empty || obj mi_dir is_not_dir || \
3593 obj mi_dir is_not_writable
;
3600 _TMP_DIR
="${mi_dir}";
3603 _TMP_DIR
="${mi_dir}"'/';
3606 _TMP_DIR
="${_TMP_DIR}${_PROGRAM_NAME}${_PROCESS_ID}";
3607 if obj _TMP_DIR is_existing
;
3609 eval rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1;
3610 if obj _TMP_DIR is_existing
;
3612 mi_tdir_
="${_TMP_DIR}"_
;
3614 mi_tdir_n
="${mi_tdir_}${mi_n}";
3615 while obj mi_tdir_n is_existing
;
3617 eval rm -f -r "'${mi_tdir_n}'" >${_NULL_DEV} 2>&1;
3618 if obj mi_tdir_n is_existing
;
3620 # directory could not be removed
3621 mi_n
="$(expr "${mi_n}" + 1)";
3622 mi_tdir_n
="${mi_tdir_}${mi_n}";
3626 _TMP_DIR
="${mi_tdir_n}";
3629 eval mkdir
"${_TMP_DIR}";
3630 if is_not_equal
"$?" 0;
3632 if obj _TMP_DIR is_existing
;
3634 eval rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1;
3639 if obj _TMP_DIR is_dir
&& obj _TMP_DIR is_writable
;
3641 # $_TMP_DIR can now be used as temporary directory
3644 if obj _TMP_DIR is_existing
;
3646 rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1;
3651 if obj _TMP_DIR is_empty
;
3654 Couldn't create a directory for storing temporary files.";
3657 _TMP_CAT
="$(tmp_create groffer_cat)";
3658 _TMP_STDIN
="$(tmp_create groffer_input)";
3660 # groffer configuration files
3661 # for f in $_CONF_FILES
3662 for f
in $
(eval set x
${_CONF_FILES}; shift; echo "$@")
3665 if obj mi_file is_file
;
3667 echo '_groffer_opt=""' >>${_TMP_CAT};
3668 # collect the lines starting with a minus
3669 cat "$mi_file" |
sed -e '
3671 s/^[ ]*\(-.*\)$/_groffer_opt="${_groffer_opt} \1"/
3673 # prepend the collected information to $GROFFER_OPT
3674 echo 'GROFFER_OPT="${_groffer_opt} ${GROFFER_OPT}"' >>${_TMP_CAT};
3677 eval . "${_TMP_CAT}";
3678 _TMP_CAT="$(tmp_create groffer_cat)";
3680 eval ${_UNSET} mi_dir;
3681 eval ${_UNSET} mi_file;
3682 eval ${_UNSET} mi_n;
3683 eval ${_UNSET} mi_tdir_;
3684 eval ${_UNSET} mi_tdir_n;
3685 eval "${return_ok}";
3689 landmark '14: main_parse_MANOPT
()';
3690 ########################################################################
3691 # main_parse_MANOPT ()
3693 # Parse $MANOPT to retrieve man options, but only if it is a non-empty
3694 # string; found man arguments can be overwritten by the command line.
3697 # in: $MANOPT, $_OPTS_MANOPT_*
3699 # in/out: $GROFFER_OPT
3701 # Variable prefix: mpm
3705 func_check main_parse_MANOPT = 0 "$@";
3707 if obj MANOPT is_not_empty;
3709 MANOPT="$(echo x"${MANOPT}" | sed -e 's/^x'"${_SPACE}${_SPACE}"'*//')";
3711 if obj MANOPT is_empty;
3713 eval ${_UNSET} mpm_list;
3714 eval ${_UNSET} mpm_opt;
3715 eval "${return_ok}";
3717 # add arguments in $MANOPT by mapping them to groffer options
3718 eval set x "$(list_from_cmdline _OPTS_MANOPT "${MANOPT}")";
3720 until test "$#" -le 0 || is_equal "$1" '--';
3724 case "${mpm_opt}" in
3726 list_append mpm_list '--ascii';
3729 list_append mpm_list '--all';
3736 list_append mpm_list '--debug';
3739 # undo all man options so far
3743 list_append mpm_list '--extension';
3747 list_append mpm_list '--whatis';
3755 # groffer's
--apropos takes an argument
, but man
's does not, so
3760 list_append mpm_list '--local-file';
3763 list_append mpm_list '--locale' "$1";
3767 list_append mpm_list '--systems' "$1";
3771 list_append mpm_list '--manpath' "$1";
3778 -P|--pager|--tty-viewer)
3779 list_append mpm_list '--pager' "$1";
3787 list_append mpm_list '--sections' "$1";
3795 list_append mpm_list '-T' "$1";
3805 -w|--where|--location)
3806 list_append mpm_list '--location';
3809 list_append mpm_list '-Z' "$1";
3812 # ignore all other options
3815 # append the 2 lists in $mpm_list and $GROFFER_OPT to $GROFFER_OPT
3816 if obj GROFFER_OPT is_empty;
3818 GROFFER_OPT="${mpm_list}";
3819 elif obj mpm_list is_not_empty;
3821 GROFFER_OPT="${mpm_list} ${GROFFER_OPT}";
3823 eval ${_UNSET} mpm_list;
3824 eval ${_UNSET} mpm_opt;
3825 eval "${return_ok}";
3826 } # main_parse_MANOPT()
3829 landmark '15: main_parse_args
()';
3830 ########################################################################
3831 # main_parse_args (<command_line_args>*)
3833 # Parse arguments; process options and filespec parameters
3835 # Arguments: pass the command line arguments unaltered.
3838 # out: $_OPT_*, $_ADDOPTS, $_FILEARGS
3840 # Variable prefix: mpa
3844 func_check main_parse_args '>=' 0 "$@";
3846 eval set x "${GROFFER_OPT}" '"$@"';
3849 eval set x "$(list_from_cmdline _OPTS_CMDLINE "$@")";
3852 # By the call of `eval', unnecessary quoting was removed. So the
3853 # positional shell parameters ($1, $2, ...) are now guaranteed to
3854 # represent an option or an argument to the previous option, if any;
3855 # then a `--' argument for separating options and
3856 # parameters; followed by the filespec parameters if any.
3858 # Note, the existence of arguments to options has already been checked.
3859 # So a check for `$#' or `--' should not be done for arguments.
3861 until test "$#" -le 0 || is_equal
"$1" '--';
3863 mpa_opt
="$1"; # $mpa_opt is fed into the option handler
3865 case "${mpa_opt}" in
3870 -Q|
--source) # output source code (`Quellcode').
3873 -T|
--device|
--troff-device) # device; arg
3875 _check_device_with_mode
;
3885 -Z|
--ditroff|
--intermediate-output) # groff intermediate output
3892 # delete leading `-'
3893 mpa_optchar
="$(echo x"${mpa_opt}" | sed -e 's/^x-//')";
3894 if list_has _OPTS_GROFF_SHORT_NA
"${mpa_optchar}";
3896 list_append _ADDOPTS_GROFF
"${mpa_opt}";
3897 elif list_has _OPTS_GROFF_SHORT_ARG
"${mpa_optchar}";
3899 list_append _ADDOPTS_GROFF
"${mpa_opt}" "$1";
3902 error
"main_parse_args(): Unknown option : \`$1'";
3908 --apropos) # run `apropos'
3914 --apropos-data) # run `apropos' for data sections
3915 apropos_run
"$1" |
grep '^[^(]*([457][^)]*)';
3920 --apropos-devel) # run `apropos' for development sections
3921 apropos_run
"$1" |
grep '^[^(]*([239][^)]*)';
3926 --apropos-progs) # run `apropos' for program sections
3927 apropos_run
"$1" |
grep '^[^(]*([168][^)]*)';
3933 list_append _ADDOPTS_GROFF
'-mtty-char';
3934 if obj _OPT_MODE is_empty
;
3939 --auto) # the default automatic mode
3942 --bd) # border color for viewers, arg;
3946 --bg|
--backgroud) # background color for viewers, arg;
3950 --bw) # border width for viewers, arg;
3954 --default) # reset variables to default
3957 --default-modes) # sequence of modes in auto mode; arg
3958 _OPT_DEFAULT_MODES
="$1";
3961 --debug) # only for development
3964 --display) # set X display, arg
3971 --dvi-viewer) # viewer program for dvi mode; arg
3972 _OPT_VIEWER_DVI
="$1";
3975 --extension) # the extension for man pages, arg
3976 _OPT_EXTENSION
="$1";
3979 --fg|
--foreground) # foreground color for viewers, arg;
3983 --fn|
--font) # set font for viewers, arg;
3987 --geometry) # window geometry for viewers, arg;
3994 --html|
--www) # display with web browser
3997 --html-viewer|
--www-viewer) # viewer program for html mode; arg
3998 _OPT_VIEWER_HTML
="$1";
4001 --iconic) # start viewers as icons
4004 --locale) # set language for man pages, arg
4005 # argument is xx[_territory[.codeset[@modifier]]] (ISO 639,...)
4009 --local-file) # force local files; same as `--no-man'
4013 --location|
--where) # print file locations to stderr
4014 _OPT_LOCATION
='yes';
4016 --man) # force all file params to be man pages
4020 --manpath) # specify search path for man pages, arg
4021 # arg is colon-separated list of directories
4025 --mode) # display mode
4028 case "${mpa_arg}" in
4029 auto|
'') # search mode automatically among default
4032 groff) # pass input to plain groff
4035 html|www
) # display with a web browser
4038 dvi
) # display with xdvi viewer
4041 pdf
) # display with PDF viewer
4044 ps
) # display with Postscript viewer
4047 text
) # output on terminal
4050 tty
) # output on terminal
4053 X|x
) # output on X roff viewer
4056 Q|
source) # display source code
4060 error
"main_parse_args(): unknown mode ${mpa_arg}";
4064 --no-location) # disable former call to `--location'
4065 _OPT_LOCATION
='yes';
4067 --no-man) # disable search for man pages
4068 # the same as --local-file
4072 --pager) # set paging program for tty mode, arg
4079 --pdf-viewer) # viewer program for ps mode; arg
4080 _OPT_VIEWER_PDF
="$1";
4086 --ps-viewer) # viewer program for ps mode; arg
4087 _OPT_VIEWER_PS
="$1";
4090 --resolution) # set resolution for X devices, arg
4093 case "${mpa_arg}" in
4101 error
"main_parse_args(): \
4102 only resoutions of 75 or 100 dpi are supported";
4105 _OPT_RESOLUTION
="${mpa_dpi}";
4110 --sections) # specify sections for man pages, arg
4111 # arg is colon-separated list of section names
4116 # already done during the first run; so ignore the argument
4119 --systems) # man pages for different OS's, arg
4120 # argument is a comma-separated list
4124 --text) # text mode without pager
4127 --title) # title for X viewers; arg
4131 --tty) # tty mode, text with pager
4134 --text-device|
--tty-device) # device for tty mode; arg
4135 _OPT_TEXT_DEVICE
="$1";
4144 --xrm) # pass X resource string, arg;
4145 list_append _OPT_XRM
"$1";
4148 --x-viewer|
--X-viewer) # viewer program for x mode; arg
4153 error
'main_parse_args(): error on argument parsing : '"\`$*'";
4157 shift; # remove `--' argument
4159 if obj _DEBUG is_not_yes
;
4161 if obj _OPT_DEBUG is_yes
;
4165 _DEBUG_KEEP_FILES
='yes';
4169 # Remaining arguments are file names (filespecs).
4170 # Save them to list $_FILEARGS
4172 then # use "-" for standard input
4177 list_append _FILEARGS
"$@";
4178 if list_has _FILEARGS
'-';
4182 # $_FILEARGS must be retrieved with `eval set x "$_FILEARGS"; shift;'
4183 eval ${_UNSET} mpa_arg
;
4184 eval ${_UNSET} mpa_code
;
4185 eval ${_UNSET} mpa_dpi
;
4186 eval ${_UNSET} mpa_opt
;
4187 eval ${_UNSET} mpa_optchar
;
4188 eval "${return_ok}";
4189 } # main_parse_args()
4192 # Called from main_parse_args() because double `case' is not possible.
4193 # Globals: $_OPT_DEVICE, $_OPT_MODE
4194 _check_device_with_mode
()
4196 func_check _check_device_with_mode
= 0 "$@";
4197 case "${_OPT_DEVICE}" in
4200 eval "${return_ok}";
4204 eval "${return_ok}";
4208 eval "${return_ok}";
4212 eval "${return_ok}";
4214 ascii|cp1047|latin1|utf8
)
4215 if obj _OPT_MODE is_not_equal text
;
4217 _OPT_MODE
=tty
; # default text mode
4219 eval "${return_ok}";
4223 eval "${return_ok}";
4225 *) # unknown device, go to groff mode
4227 eval "${return_ok}";
4230 eval "${return_error}";
4231 } # _check_device_with_mode() of main_parse_args()
4234 landmark
'16: main_set_mode()';
4235 ########################################################################
4238 # Determine the display mode.
4241 # in: $DISPLAY, $_OPT_MODE, $_OPT_DEVICE
4242 # out: $_DISPLAY_MODE
4244 # Variable prefix: msm
4248 func_check main_set_mode
= 0 "$@";
4251 if obj _OPT_APROPOS is_not_empty
;
4253 apropos
"${_OPT_APROPOS}";
4258 if obj _OPT_APROPOS_DATA is_not_empty
;
4260 apropos
"$@" |
grep '^[^(]*([457])';
4265 if obj _OPT_APROPOS_DEVEL is_not_empty
;
4267 apropos
"$@" |
grep '^[^(]*([239])';
4272 if obj _OPT_APROPOS_PROGS is_not_empty
;
4274 apropos
"$@" |
grep '^[^(]*([168])';
4281 if obj _OPT_DISPLAY is_not_empty
;
4283 DISPLAY
="${_OPT_DISPLAY}";
4286 if obj _OPT_V is_yes
;
4288 list_append _ADDOPTS_GROFF
'-V';
4290 if obj _OPT_Z is_yes
;
4292 _DISPLAY_MODE
='groff';
4293 list_append _ADDOPTS_GROFF
'-Z';
4295 if obj _OPT_MODE is_equal
'groff';
4297 _DISPLAY_MODE
='groff';
4299 if obj _DISPLAY_MODE is_equal
'groff';
4301 eval ${_UNSET} msm_code
;
4302 eval ${_UNSET} msm_modes
;
4303 eval ${_UNSET} msm_viewer
;
4304 eval ${_UNSET} msm_viewers
;
4305 eval "${return_ok}";
4308 if obj _OPT_MODE is_equal
'source';
4310 _DISPLAY_MODE
='source';
4311 eval ${_UNSET} msm_code
;
4312 eval ${_UNSET} msm_modes
;
4313 eval ${_UNSET} msm_viewer
;
4314 eval ${_UNSET} msm_viewers
;
4315 eval "${return_ok}";
4318 case "${_OPT_MODE}" in
4319 '') # automatic mode
4320 case "${_OPT_DEVICE}" in
4322 if obj DISPLAY is_empty
;
4324 error
"main_set_mode(): \
4325 no X display found for device ${_OPT_DEVICE}";
4328 eval ${_UNSET} msm_code
;
4329 eval ${_UNSET} msm_modes
;
4330 eval ${_UNSET} msm_viewer
;
4331 eval ${_UNSET} msm_viewers
;
4332 eval "${return_ok}";
4334 ascii|cp1047|latin1|utf8
)
4335 if obj _DISPLAY_MODE is_not_equal
'text';
4337 _DISPLAY_MODE
='tty';
4339 eval ${_UNSET} msm_code
;
4340 eval ${_UNSET} msm_modes
;
4341 eval ${_UNSET} msm_viewer
;
4342 eval ${_UNSET} msm_viewers
;
4343 eval "${return_ok}";
4346 if obj DISPLAY is_empty
;
4348 _DISPLAY_MODE
='tty';
4349 eval ${_UNSET} msm_code
;
4350 eval ${_UNSET} msm_modes
;
4351 eval ${_UNSET} msm_viewer
;
4352 eval ${_UNSET} msm_viewers
;
4353 eval "${return_ok}";
4356 if obj _OPT_DEFAULT_MODES is_empty
;
4358 msm_modes
="${_DEFAULT_MODES}";
4360 msm_modes
="${_OPT_DEFAULT_MODES}";
4364 _DISPLAY_MODE
='text';
4365 eval ${_UNSET} msm_code
;
4366 eval ${_UNSET} msm_modes
;
4367 eval ${_UNSET} msm_viewer
;
4368 eval ${_UNSET} msm_viewers
;
4369 eval "${return_ok}";
4372 _DISPLAY_MODE
='tty';
4373 eval ${_UNSET} msm_code
;
4374 eval ${_UNSET} msm_modes
;
4375 eval ${_UNSET} msm_viewer
;
4376 eval ${_UNSET} msm_viewers
;
4377 eval "${return_ok}";
4379 *) # display mode was given
4380 if obj DISPLAY is_empty
;
4382 error
"main_set_mode(): \
4383 you must be in X Window for ${_OPT_MODE} mode.";
4385 msm_modes
="${_OPT_MODE}";
4389 # only viewer modes are left
4390 eval set x
"$(list_from_split "${msm_modes}" ',')";
4392 while test "$#" -gt 0;
4398 _DISPLAY_MODE
='text';
4399 eval ${_UNSET} msm_code
;
4400 eval ${_UNSET} msm_modes
;
4401 eval ${_UNSET} msm_viewer
;
4402 eval ${_UNSET} msm_viewers
;
4403 eval "${return_ok}";
4406 _DISPLAY_MODE
='tty';
4407 eval ${_UNSET} msm_code
;
4408 eval ${_UNSET} msm_modes
;
4409 eval ${_UNSET} msm_viewer
;
4410 eval ${_UNSET} msm_viewers
;
4411 eval "${return_ok}";
4414 if obj _OPT_VIEWER_X is_not_empty
;
4416 msm_viewers
="${_OPT_VIEWER_X}";
4418 msm_viewers
="${_VIEWER_X}";
4420 msm_viewer
="$(_get_first_prog "${msm_viewers}")";
4421 if is_not_equal
"$?" 0;
4425 _DISPLAY_PROG
="${msm_viewer}";
4427 eval ${_UNSET} msm_code
;
4428 eval ${_UNSET} msm_modes
;
4429 eval ${_UNSET} msm_viewer
;
4430 eval ${_UNSET} msm_viewers
;
4431 eval "${return_ok}";
4435 eval ${_UNSET} msm_code
;
4436 eval ${_UNSET} msm_modes
;
4437 eval ${_UNSET} msm_viewer
;
4438 eval ${_UNSET} msm_viewers
;
4439 eval "${return_ok}";
4442 if obj _OPT_VIEWER_DVI is_not_empty
;
4444 msm_viewers
="${_OPT_VIEWER_DVI}";
4446 msm_viewers
="${_VIEWER_DVI}";
4448 msm_viewer
="$(_get_first_prog "${msm_viewers}")";
4449 if is_not_equal
"$?" 0;
4453 _DISPLAY_PROG
="${msm_viewer}";
4454 _DISPLAY_MODE
="dvi";
4455 eval ${_UNSET} msm_code
;
4456 eval ${_UNSET} msm_modes
;
4457 eval ${_UNSET} msm_viewer
;
4458 eval ${_UNSET} msm_viewers
;
4459 eval "${return_ok}";
4462 if obj _OPT_VIEWER_PDF is_not_empty
;
4464 msm_viewers
="${_OPT_VIEWER_PDF}";
4466 msm_viewers
="${_VIEWER_PDF}";
4468 msm_viewer
="$(_get_first_prog "${msm_viewers}")";
4469 if is_not_equal
"$?" 0;
4473 _DISPLAY_PROG
="${msm_viewer}";
4474 _DISPLAY_MODE
="pdf";
4475 eval ${_UNSET} msm_code
;
4476 eval ${_UNSET} msm_modes
;
4477 eval ${_UNSET} msm_viewer
;
4478 eval ${_UNSET} msm_viewers
;
4479 eval "${return_ok}";
4482 if obj _OPT_VIEWER_PS is_not_empty
;
4484 msm_viewers
="${_OPT_VIEWER_PS}";
4486 msm_viewers
="${_VIEWER_PS}";
4488 msm_viewer
="$(_get_first_prog "${msm_viewers}")";
4489 if is_not_equal
"$?" 0;
4493 _DISPLAY_PROG
="${msm_viewer}";
4495 eval ${_UNSET} msm_code
;
4496 eval ${_UNSET} msm_modes
;
4497 eval ${_UNSET} msm_viewer
;
4498 eval ${_UNSET} msm_viewers
;
4499 eval "${return_ok}";
4502 if obj _OPT_VIEWER_HTML is_not_empty
;
4504 msm_viewers
="${_OPT_VIEWER_HTML}";
4506 msm_viewers
="${_VIEWER_HTML}";
4508 msm_viewer
="$(_get_first_prog "${msm_viewers}")";
4509 if is_not_equal
"$?" 0;
4513 _DISPLAY_PROG
="${msm_viewer}";
4515 eval ${_UNSET} msm_code
;
4516 eval ${_UNSET} msm_modes
;
4517 eval ${_UNSET} msm_viewer
;
4518 eval ${_UNSET} msm_viewers
;
4519 eval "${return_ok}";
4523 eval ${_UNSET} msm_code
;
4524 eval ${_UNSET} msm_modes
;
4525 eval ${_UNSET} msm_viewer
;
4526 eval ${_UNSET} msm_viewers
;
4527 error
"main_set_mode(): no suitable display mode found.";
4531 # _get_first_prog (<proglist>)
4533 # Retrieve first argument that represents an existing program in $PATH.
4534 # Local function for main_set_mode().
4536 # Arguments: 1; a comma-separated list of commands (with options),
4539 # Return : `1' if none found, `0' if found.
4540 # Output : the argument that succeded.
4542 # Variable prefix: _gfp
4548 error
"_get_first_prog() needs 1 argument.";
4554 eval set x
"$(list_from_split "$1" ',')";
4559 if obj _gfp_i is_empty
;
4563 if eval is_prog
"$(get_first_essential ${_gfp_i})";
4568 eval ${_UNSET} _gfp_i
;
4572 eval ${_UNSET} _gfp_i
;
4574 } # _get_first_prog() of main_set_mode()
4577 landmark
'17: main_do_fileargs()';
4578 #######################################################################
4579 # main_do_fileargs ()
4581 # Process filespec arguments in $_FILEARGS.
4584 # in: $_FILEARGS (process with `eval set x "$_FILEARGS"; shift;')
4586 # Variable prefix: mdfa
4590 func_check main_do_fileargs
= 0 "$@";
4591 mdfa_exitcode
="${_BAD}";
4592 eval set x
"${_FILEARGS}";
4594 eval ${_UNSET} _FILEARGS
;
4595 # temporary storage of all input to $_TMP_CAT
4596 while test "$#" -ge 2;
4598 # test for `s name' arguments, with `s' a 1-char standard section
4601 case "${mdfa_filespec}" in
4606 if register_file
'-';
4608 mdfa_exitcode
="${_GOOD}";
4613 if list_has_not _MAN_AUTO_SEC
"${mdfa_filespec}";
4615 if do_filearg
"${mdfa_filespec}";
4617 mdfa_exitcode
="${_GOOD}";
4622 case "${mdfa_name}" in
4623 */*|man
:*|
*\
(*\
)|
*.
"${mdfa_filespec}")
4624 if do_filearg
"${mdfa_filespec}";
4626 mdfa_exitcode
="${_GOOD}";
4631 if do_filearg
"man:${mdfa_name}(${mdfa_filespec})";
4633 mdfa_exitcode
="${_GOOD}";
4637 if do_filearg
"${mdfa_filespec}";
4639 mdfa_exitcode
="${_GOOD}";
4645 if do_filearg
"${mdfa_filespec}";
4647 mdfa_exitcode
="${_GOOD}";
4652 done; # end of `s name' test
4653 while test "$#" -gt 0;
4657 if do_filearg
"${mdfa_filespec}";
4659 mdfa_exitcode
="${_GOOD}";
4662 if obj _DEBUG_KEEP_FILES is_not_yes
;
4664 rm -f "${_TMP_STDIN}";
4666 if is_equal
"${mdfa_exitcode}" "${_BAD}";
4668 eval ${_UNSET} mdfa_exitcode
;
4669 eval ${_UNSET} mdfa_filespec
;
4670 eval ${_UNSET} mdfa_name
;
4671 eval "${return_bad}";
4673 eval ${_UNSET} mdfa_exitcode
;
4674 eval ${_UNSET} mdfa_filespec
;
4675 eval ${_UNSET} mdfa_name
;
4676 eval "${return_ok}";
4677 } # main_do_fileargs()
4680 landmark
'18: main_set_resources()';
4681 ########################################################################
4682 # main_set_resources ()
4684 # Determine options for setting X resources with $_DISPLAY_PROG.
4686 # Globals: $_DISPLAY_PROG, $_OUTPUT_FILE_NAME
4688 # Variable prefix: msr
4690 main_set_resources
()
4692 func_check main_set_resources
= 0 "$@";
4693 # $msr_prog viewer program
4694 # $msr_rl resource list
4695 msr_title
="$(get_first_essential \
4696 "${_OPT_TITLE}" "${_REGISTERED_TITLE}")";
4697 _OUTPUT_FILE_NAME
='';
4698 eval set x
"${msr_title}";
4700 until is_equal
"$#" 0;
4708 msr_n
="$(echo x"$1" | sed -e 's/^x,,*//')";
4711 if obj msr_n is_empty
;
4715 if obj _OUTPUT_FILE_NAME is_not_empty
;
4717 _OUTPUT_FILE_NAME
="${_OUTPUT_FILE_NAME}"',';
4719 _OUTPUT_FILE_NAME
="${_OUTPUT_FILE_NAME}${msr_n}";
4722 case "${_OUTPUT_FILE_NAME}" in
4724 _OUTPUT_FILE_NAME
='-';
4727 error
"main_set_resources(): ${_OUTPUT_FILE_NAME} starts with a comma.";
4730 _OUTPUT_FILE_NAME
="${_TMP_DIR}/${_OUTPUT_FILE_NAME}";
4732 if obj _DISPLAY_PROG is_empty
;
4733 then # for example, for groff mode
4735 eval ${_UNSET} msr_n
;
4736 eval ${_UNSET} msr_prog
;
4737 eval ${_UNSET} msr_rl
;
4738 eval ${_UNSET} msr_title
;
4739 eval "${return_ok}";
4742 eval set x
"${_DISPLAY_PROG}";
4744 msr_prog
="$(base_name "$1")";
4746 if obj _OPT_BD is_not_empty
;
4748 case "${msr_prog}" in
4749 ghostview|gv|gxditview|xditview|xdvi
)
4750 list_append msr_rl
'-bd' "${_OPT_BD}";
4754 if obj _OPT_BG is_not_empty
;
4756 case "${msr_prog}" in
4757 ghostview|gv|gxditview|xditview|xdvi
)
4758 list_append msr_rl
'-bg' "${_OPT_BG}";
4761 list_append msr_rl
'-papercolor' "${_OPT_BG}";
4765 if obj _OPT_BW is_not_empty
;
4767 case "${msr_prog}" in
4768 ghostview|gv|gxditview|xditview|xdvi
)
4769 _list_append msr_rl
'-bw' "${_OPT_BW}";
4773 if obj _OPT_FG is_not_empty
;
4775 case "${msr_prog}" in
4776 ghostview|gv|gxditview|xditview|xdvi
)
4777 list_append msr_rl
'-fg' "${_OPT_FG}";
4781 if is_not_empty
"${_OPT_FN}";
4783 case "${msr_prog}" in
4784 ghostview|gv|gxditview|xditview|xdvi
)
4785 list_append msr_rl
'-fn' "${_OPT_FN}";
4789 if is_not_empty
"${_OPT_GEOMETRY}";
4791 case "${msr_prog}" in
4792 ghostview|gv|gxditview|xditview|xdvi|xpdf
)
4793 list_append msr_rl
'-geometry' "${_OPT_GEOMETRY}";
4797 if is_empty
"${_OPT_RESOLUTION}";
4799 _OPT_RESOLUTION
="${_DEFAULT_RESOLUTION}";
4800 case "${msr_prog}" in
4802 list_append msr_rl
'-resolution' "${_DEFAULT_RESOLUTION}";
4805 case "${_DEFAULT_RESOLUTION}" in
4808 list_append msr_rl
'-z' '104';
4811 list_append msr_rl
'-z' '139';
4817 case "${msr_prog}" in
4818 ghostview|gv|gxditview|xditview|xdvi
)
4819 list_append msr_rl
'-resolution' "${_OPT_RESOLUTION}";
4822 case "${_OPT_RESOLUTION}" in
4824 list_append msr_rl
'-z' '104';
4825 # '100' corresponds to 72dpi
4828 list_append msr_rl
'-z' '139';
4834 if is_yes
"${_OPT_ICONIC}";
4836 case "${msr_prog}" in
4837 ghostview|gv|gxditview|xditview|xdvi
)
4838 list_append msr_rl
'-iconic';
4842 if is_yes
"${_OPT_RV}";
4844 case "${msr_prog}" in
4845 ghostview|gv|gxditview|xditview|xdvi
)
4846 list_append msr_rl
'-rv';
4850 if is_not_empty
"${_OPT_XRM}";
4852 case "${msr_prog}" in
4853 ghostview|gv|gxditview|xditview|xdvi|xpdf
)
4854 eval set x
"${_OPT_XRM}";
4858 list_append msr_rl
'-xrm' "$i";
4863 if is_not_empty
"${msr_title}";
4865 case "${msr_prog}" in
4867 list_append msr_rl
'-title' "${msr_title}";
4871 _DISPLAY_ARGS
="${msr_rl}";
4872 eval ${_UNSET} msr_n
;
4873 eval ${_UNSET} msr_prog
;
4874 eval ${_UNSET} msr_rl
;
4875 eval ${_UNSET} msr_title
;
4876 eval "${return_ok}";
4877 } # main_set_resources
4880 landmark
'19: main_display()';
4881 ########################################################################
4884 # Do the actual display of the whole thing.
4887 # in: $_DISPLAY_MODE, $_OPT_DEVICE,
4888 # $_ADDOPTS_GROFF, $_ADDOPTS_POST, $_ADDOPTS_X,
4889 # $_REGISTERED_TITLE, $_TMP_CAT,
4890 # $_OPT_PAGER $PAGER, $_MANOPT_PAGER,
4891 # $_OUTPUT_FILE_NAME
4893 # Variable prefix: md
4897 func_check main_display
= 0 "$@";
4903 if obj _TMP_CAT is_non_empty_file
;
4905 md_modefile
="${_OUTPUT_FILE_NAME}";
4908 echo2
'groffer: empty input.';
4909 eval ${_UNSET} md_modefile
;
4910 eval "${return_ok}";
4912 case "${_DISPLAY_MODE}" in
4914 _ADDOPTS_GROFF
="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
4915 if obj _OPT_DEVICE is_not_empty
;
4917 _ADDOPTS_GROFF
="${_ADDOPTS_GROFF} -T${_OPT_DEVICE}";
4919 md_groggy
="$(tmp_cat | eval grog "${md_options}")";
4921 if obj _OPT_V is_yes
;
4923 echo "File: ${md_modefile}";
4924 echo "Mode: ${_DISPLAY_MODE}";
4925 echo "Display program: ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
4926 eval "${md_groggy}" "${_ADDOPTS_GROFF}";
4929 # start a new shell program to get another process ID.
4932 test -f "${md_modefile}" && rm -f "${md_modefile}";
4933 mv "${_TMP_CAT}" "${md_modefile}";
4934 cat "${md_modefile}" | \
4938 if test -d "${_TMP_DIR}";
4940 rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1 || :;
4943 trap clean_up 0 2>${_NULL_DEV} || :;
4944 eval "${md_groggy}" "${_ADDOPTS_GROFF}";
4949 case "${_OPT_DEVICE}" in
4951 md_device
="$(get_first_essential \
4952 "${_OPT_TEXT_DEVICE}" "${_DEFAULT_TTY_DEVICE}")";
4954 ascii|cp1047|latin1|utf8
)
4955 md_device
="${_OPT_DEVICE}";
4958 warning
"main_display(): \
4959 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
4962 md_addopts
="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
4963 md_groggy
="$(tmp_cat | grog -T${md_device})";
4964 if obj _DISPLAY_MODE is_equal
'text';
4966 if obj _OPT_V is_yes
;
4968 echo "File: ${md_modefile}";
4969 echo "Mode: ${_DISPLAY_MODE}";
4970 echo "Display program: ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
4971 eval "${md_groggy}" "${md_addopts}";
4973 tmp_cat |
eval "${md_groggy}" "${md_addopts}";
4977 for p
in "${_OPT_PAGER}" "${PAGER}" "${_MANOPT_PAGER}" \
4978 'less -r -R' 'more' 'pager' 'cat'
4981 if eval is_prog
${md_p};
4982 then # no "" for is_prog() allows args for $p
4987 if obj md_pager is_empty
;
4989 error
'main_display(): no pager program found for tty mode';
4991 if obj _OPT_V is_yes
;
4993 echo "File: ${md_modefile}";
4994 echo "Mode: ${_DISPLAY_MODE}";
4995 echo "Display program: ${md_pager}";
4996 eval "${md_groggy}" "${md_addopts}";
4998 tmp_cat |
eval "${md_groggy}" "${md_addopts}" | \
5012 case "${_OPT_DEVICE}" in
5013 ''|dvi
) do_nothing
; ;;
5015 warning
"main_display(): \
5016 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"
5019 md_modefile
="${md_modefile}".dvi
;
5020 md_groggy
="$(tmp_cat | grog -Tdvi)";
5024 case "${_OPT_DEVICE}" in
5025 ''|html
) do_nothing
; ;;
5027 warning
"main_display(): \
5028 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
5031 md_modefile
="${md_modefile}".html
;
5032 md_groggy
="$(tmp_cat | grog -Thtml)";
5036 case "${_OPT_DEVICE}" in
5041 warning
"main_display(): \
5042 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
5045 md_groggy
="$(tmp_cat | grog -Tps)";
5047 if obj _OPT_V is_yes
;
5049 echo "File: ${md_modefile}.pdf";
5050 echo "Mode: ${_DISPLAY_MODE}";
5051 echo "Display program: ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
5052 eval "${md_groggy}" "${_ADDOPTS_GROFF}";
5055 # start a new shell program to get another process ID.
5058 _psfile="${md_modefile}.ps";
5059 md_modefile="${md_modefile}.pdf";
5060 test -f "${_psfile}" && rm -f "${_psfile}";
5061 test -f "${md_modefile}" && rm -f "${md_modefile}";
5062 cat "${_TMP_CAT}" | \
5063 eval "${md_groggy}" "${_ADDOPTS_GROFF}" > "${_psfile}";
5064 gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
5065 -sOutputFile="${md_modefile}" -c save pop -f "${_psfile}";
5066 if test _"${_DEBUG_KEEP_FILES}"_ != _yes_;
5068 test -f "${_psfile}" && rm -f "${_psfile}";
5069 test -f "${_TMP_CAT}" && rm -f "${_TMP_CAT}";
5073 if test -d "${_TMP_DIR}";
5075 rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1 || :;
5078 trap clean_up 0 2>${_NULL_DEV} || :;
5079 eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "${md_modefile}";
5084 case "${_OPT_DEVICE}" in
5089 warning
"main_display(): \
5090 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
5093 md_modefile
="${md_modefile}".ps
;
5094 md_groggy
="$(tmp_cat | grog -Tps)";
5098 case "${_OPT_DEVICE}" in
5100 md_device
="${_OPT_DEVICE}"
5103 case "${_OPT_RESOLUTION}" in
5106 if obj _OPT_GEOMETRY is_empty
5108 case "${_DISPLAY_PROG}" in
5110 # add width of 800dpi for resolution of 100dpi to the args
5111 list_append _DISPLAY_ARGS
'-geometry' '800';
5121 md_groggy
="$(tmp_cat | grog -T${md_device} -Z)";
5125 case "${_OPT_DEVICE}" in
5127 md_groggy
="$(tmp_cat | grog -X)";
5129 X
*|dvi|html|lbp|lj4|ps
)
5130 # these devices work with
5131 md_groggy
="$(tmp_cat | grog -T"${_OPT_DEVICE}" -X)";
5134 warning
"main_display(): \
5135 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
5136 md_groggy
="$(tmp_cat | grog -Z)";
5142 error
"main_display(): unknown mode \`${_DISPLAY_MODE}'";
5145 eval ${_UNSET} md_addopts
;
5146 eval ${_UNSET} md_device
;
5147 eval ${_UNSET} md_groggy
;
5148 eval ${_UNSET} md_modefile
;
5149 eval ${_UNSET} md_options
;
5150 eval ${_UNSET} md_p
;
5151 eval ${_UNSET} md_pager
;
5152 eval "${return_ok}";
5156 # $md_modefile and $md_groggy come from main_display()
5159 func_check _do_display
= 0 "$@";
5161 if obj _OPT_V is_yes
;
5163 echo "File: ${md_modefile}";
5164 echo "Mode: ${_DISPLAY_MODE}";
5165 echo "Display program: ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
5166 eval "${md_groggy}" "${_ADDOPTS_GROFF}";
5169 # start a new shell program for another process ID and better
5170 # cleaning-up of the temporary files.
5173 test -f "${md_modefile}" && rm -f "${md_modefile}";
5174 cat "${_TMP_CAT}" | \
5175 eval "${md_groggy}" "${_ADDOPTS_GROFF}" > "${md_modefile}";
5176 if test _"${_DEBUG_KEEP_FILES}"_ != _yes_;
5178 rm -f "${_TMP_CAT}";
5182 if test -d "${_TMP_DIR}";
5184 rm -f -r "'${_TMP_DIR}'" >${_NULL_DEV} 2>&1 || :;
5187 trap clean_up 0 2>${_NULL_DEV} || :;
5188 eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "${md_modefile}";
5191 eval "${return_ok}";
5192 } # _do_display() of main_display()
5195 ########################################################################
5196 # main (<command_line_args>*)
5198 # The main function for groffer.
5204 func_check main
'>=' 0 "$@";
5205 # Do not change the sequence of the following functions!
5208 main_parse_args
"$@";
5213 eval "${return_ok}";
5216 landmark
'20: end of function definitions';
5218 ########################################################################