3 # groffer - display groff files
5 # Source file position: <groff-source>/contrib/groffer/groffer2.sh
6 # Installed position: <prefix>/lib/groff/groffer/groffer2.sh
8 # This file should not be run independently. It is called by
9 # `groffer.sh' in the source or by the installed `groffer' program.
11 # Copyright (C) 2001,2002,2003,2004,2005
12 # Free Software Foundation, Inc.
13 # Written by Bernd Warken
15 # Last update: 2 August 2005
17 # This file is part of `groffer', which is part of `groff'.
19 # `groff' is free software; you can redistribute it and/or modify it
20 # under the terms of the GNU General Public License as published by
21 # the Free Software Foundation; either version 2, or (at your option)
24 # `groff' is distributed in the hope that it will be useful, but
25 # WITHOUT ANY WARRANTY; without even the implied warranty of
26 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 # General Public License for more details.
29 # You should have received a copy of the GNU General Public License
30 # along with `groff'; see the files COPYING and LICENSE in the top
31 # directory of the `groff' source. If not, write to the Free Software
32 # Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301,
36 ########################################################################
37 # diagnostic messages for debugging
40 _DEBUG
='no'; # disable debugging information
41 #_DEBUG='yes'; # enable debugging information
44 _DEBUG_LM
='no'; # disable landmark messages
45 #_DEBUG_LM='yes'; # enable landmark messages
47 export _DEBUG_KEEP_FILES
;
48 _DEBUG_KEEP_FILES
='no' # disable file keeping in temporary dir
49 #_DEBUG_KEEP_FILES='yes' # enable file keeping in temporary dir
51 export _DEBUG_PRINT_PARAMS
;
52 _DEBUG_PRINT_PARAMS
='no'; # disable printing of all parameters
53 #_DEBUG_PRINT_PARAMS='yes'; # enable printing of all parameters
55 export _DEBUG_PRINT_SHELL
;
56 _DEBUG_PRINT_SHELL
='no'; # disable printing of the shell name
57 #_DEBUG_PRINT_SHELL='yes'; # enable printing of the shell name
60 # test of $GROFFER_OPT and $* on `--debug' with shortest abbreviation `--deb'
61 case " ${GROFFER_OPT} $* " in
62 *' --deb '*|
*' --debu '*|
*' --debug '*)
65 _DEBUG_KEEP_FILES
='yes';
66 _DEBUG_PRINT_PARAMS
='yes';
67 _DEBUG_PRINT_SHELL
='yes';
71 if test _
"${_DEBUG_PRINT_PARAMS}"_
= _yes_
73 echo "parameters: ${GROFFER_OPT} $@" >&2;
76 if test _
"${_DEBUG_PRINT_SHELL}"_
= _yes_
78 if test _
"${_SHELL}"_
= __
80 if test _
"${POSIXLY_CORRECT}"_
= _y_
82 echo 'shell: bash as /bin/sh (none specified)' >&2;
84 echo 'shell: /bin/sh (none specified)' >&2;
87 echo "shell: ${_SHELL}" >&2;
92 ########################################################################
93 # Environment Variables
94 ########################################################################
96 # Environment variables that exist only for this file start with an
97 # underscore letter. Global variables to this file are written in
98 # upper case letters, e.g. $_GLOBAL_VARIABLE; temporary variables
99 # start with an underline and use only lower case letters and
100 # underlines, e.g. $_local_variable .
102 # [A-Z]* system variables, e.g. $MANPATH
103 # _[A-Z_]* global file variables, e.g. $_MAN_PATH
104 # _[a-z_]* temporary variables, e.g. $_manpath
106 # Due to incompatibilities of the `ash' shell, the name of loop
107 # variables in `for' must be single character
108 # [a-z] local loop variables, e.g. $i
111 ########################################################################
112 # read-only variables (global to this file)
113 ########################################################################
115 # function return values; `0' means ok; other values are error codes
124 _GOOD
='0'; # return ok
125 _BAD
='1'; # return negatively, error code `1'
126 _ERROR
='7'; # for syntax errors; no `-1' in `ash'
128 # all exit codes (for `trap_set()')
129 _ALL_EXIT
="${_GOOD} ${_BAD} ${_ERROR}";
135 # quasi-functions, call with `eval', e.g `eval "${return_ok}"'
143 return_ok
="func_pop; return ${_OK}";
144 return_good
="func_pop; return ${_GOOD}";
145 return_bad
="func_pop; return ${_BAD}";
146 return_yes
="func_pop; return ${_YES}";
147 return_no
="func_pop; return ${_NO}";
148 return_error
="func_pop; return ${_ERROR}";
149 return_var
="func_pop; return"; # add number, e.g. `eval "${return_var} $n'
152 export _DEFAULT_MODES
;
153 _DEFAULT_MODES
='x,ps,tty';
154 export _DEFAULT_RESOLUTION
;
155 _DEFAULT_RESOLUTION
='75';
157 export _DEFAULT_TTY_DEVICE
;
158 _DEFAULT_TTY_DEVICE
='latin1';
160 # _VIEWER_* viewer programs for different modes (only X is necessary)
161 # _VIEWER_* a comma-separated list of viewer programs (with options)
162 export _VIEWER_DVI
; # viewer program for dvi mode
163 export _VIEWER_PS
; # viewer program for ps mode
164 export _VIEWER_HTML_X
; # viewer program for html mode in X
165 export _VIEWER_HTML_TTY
; # viewer program for html mode in tty
166 _VIEWER_DVI
='kdvi,xdvi,dvilx';
167 _VIEWER_PDF
='kghostview --scale 1.45,ggv,xpdf,acroread,kpdf';
168 _VIEWER_PS
='kghostview --scale 1.45,ggv,gv,ghostview,gs_x11,gs';
169 _VIEWER_HTML
='konqueror,mozilla,netscape,opera,amaya,arena,lynx';
170 _VIEWER_X
='gxditview,xditview';
172 # Search automatically in standard sections `1' to `8', and in the
173 # traditional sections `9', `n', and `o'. On many systems, there
174 # exist even more sections, mostly containing a set of man pages
175 # special to a specific program package. These aren't searched for
176 # automatically, but must be specified on the command line.
177 export _MAN_AUTO_SEC
;
178 _MAN_AUTO_SEC
="'1' '2' '3' '4' '5' '6' '7' '8' '9' 'n' 'o'"
180 export _PROCESS_ID
; # for shutting down the program
184 ############ the command line options of the involved programs
186 # The naming scheme for the options environment names is
187 # $_OPTS_<prog>_<length>[_<argspec>]
189 # <prog>: program name GROFFER, GROFF, or CMDLINE (for all
190 # command line options)
191 # <length>: LONG (long options) or SHORT (single character options)
192 # <argspec>: ARG for options with argument, NA for no argument;
193 # without _<argspec> both the ones with and without arg.
195 # Each option that takes an argument must be specified with a
196 # trailing : (colon).
199 export _OPTS_GROFFER_SHORT_NA
;
200 export _OPTS_GROFFER_SHORT_ARG
;
201 export _OPTS_GROFFER_LONG_NA
;
202 export _OPTS_GROFFER_LONG_ARG
;
203 export _OPTS_GROFF_SHORT_NA
;
204 export _OPTS_GROFF_SHORT_ARG
;
205 export _OPTS_GROFF_LONG_NA
;
206 export _OPTS_GROFF_LONG_ARG
;
207 export _OPTS_X_SHORT_ARG
;
208 export _OPTS_X_SHORT_NA
;
209 export _OPTS_X_LONG_ARG
;
210 export _OPTS_X_LONG_NA
;
211 export _OPTS_MAN_SHORT_ARG
;
212 export _OPTS_MAN_SHORT_NA
;
213 export _OPTS_MAN_LONG_ARG
;
214 export _OPTS_MAN_LONG_NA
;
215 export _OPTS_MANOPT_SHORT_ARG
;
216 export _OPTS_MANOPT_SHORT_NA
;
217 export _OPTS_MANOPT_LONG_ARG
;
218 export _OPTS_MANOPT_LONG_NA
;
219 export _OPTS_CMDLINE_SHORT_NA
;
220 export _OPTS_CMDLINE_SHORT_ARG
;
221 export _OPTS_CMDLINE_LONG_NA
;
222 export _OPTS_CMDLINE_LONG_ARG
;
224 ###### groffer native options
226 _OPTS_GROFFER_SHORT_NA
="'h' 'Q' 'v' 'V' 'X' 'Z'";
227 _OPTS_GROFFER_SHORT_ARG
="'T'";
229 _OPTS_GROFFER_LONG_NA
="'auto' 'debug' 'default' 'do-nothing' 'dvi' \
230 'groff' 'help' 'intermediate-output' 'html' 'man' \
231 'no-location' 'no-man' 'pdf' 'ps' 'rv' 'source' 'text' 'text-device' \
232 'title' 'tty' 'tty-device' 'version' 'whatis' 'where' 'www' 'x' 'X'";
234 _OPTS_GROFFER_LONG_ARG
="\
235 'apropos' 'apropos-data' 'apropos-devel' 'apropos-progs' \
236 'default-modes' 'device' 'dvi-viewer' 'extension' 'fg' 'fn' 'font' \
237 'foreground' 'html-viewer' 'mode' 'pdf-viewer' 'ps-viewer' 'shell' \
238 'tty-viewer' 'www-viewer' 'x-viewer' 'X-viewer'";
240 ##### groffer options inhereted from groff
242 _OPTS_GROFF_SHORT_NA
="'a' 'b' 'c' 'C' 'e' 'E' 'g' 'G' 'i' 'l' 'N' 'p' \
243 'R' 's' 'S' 't' 'U' 'z'";
244 _OPTS_GROFF_SHORT_ARG
="'d' 'f' 'F' 'I' 'L' 'm' 'M' 'n' 'o' 'P' 'r' \
246 _OPTS_GROFF_LONG_NA
="";
247 _OPTS_GROFF_LONG_ARG
="";
249 ##### groffer options inhereted from the X Window toolkit
252 _OPTS_X_SHORT_ARG
="";
254 _OPTS_X_LONG_NA
="'iconic' 'rv'";
256 _OPTS_X_LONG_ARG
="'background' 'bd' 'bg' 'bordercolor' 'borderwidth' \
257 'bw' 'display' 'fg' 'fn' 'font' 'foreground' 'ft' 'geometry' \
258 'resolution' 'title' 'xrm'";
260 ###### groffer options inherited from man
262 _OPTS_MAN_SHORT_NA
="";
263 _OPTS_MAN_SHORT_ARG
="";
265 _OPTS_MAN_LONG_NA
="'all' 'ascii' 'catman' 'ditroff' \
266 'local-file' 'location' 'troff' 'update'";
268 _OPTS_MAN_LONG_ARG
="'locale' 'manpath' \
269 'pager' 'preprocessor' 'prompt' 'sections' 'systems' 'troff-device'";
271 ###### additional options for parsing $MANOPT only
273 _OPTS_MANOPT_SHORT_NA
="'7' 'a' 'c' 'd' 'D' 'f' 'h' 'k' 'l' 't' 'u' \
275 _OPTS_MANOPT_SHORT_ARG
="'e' 'L' 'm' 'M' 'p' 'P' 'r' 'S' 'T'";
277 _OPTS_MANOPT_LONG_NA
="${_OPTS_MAN_LONG_NA} \
278 'apropos' 'debug' 'default' 'help' 'html' 'ignore-case' 'location-cat' \
279 'match-case' 'troff' 'update' 'version' 'whatis' 'where' 'where-cat'";
281 _OPTS_MANOPT_LONG_ARG
="${_OPTS_MAN_LONG_NA} \
282 'config_file' 'encoding' 'extension' 'locale'";
284 ###### collections of command line options
286 _OPTS_CMDLINE_SHORT_NA
="${_OPTS_GROFFER_SHORT_NA} \
287 ${_OPTS_GROFF_SHORT_NA} ${_OPTS_X_SHORT_NA} ${_OPTS_MAN_SHORT_NA}";
288 _OPTS_CMDLINE_SHORT_ARG
="${_OPTS_GROFFER_SHORT_ARG} \
289 ${_OPTS_GROFF_SHORT_ARG} ${_OPTS_X_SHORT_ARG} ${_OPTS_MAN_SHORT_ARG}";
291 _OPTS_CMDLINE_LONG_NA
="${_OPTS_GROFFER_LONG_NA} \
292 ${_OPTS_GROFF_LONG_NA} ${_OPTS_X_LONG_NA} ${_OPTS_MAN_LONG_NA}";
293 _OPTS_CMDLINE_LONG_ARG
="${_OPTS_GROFFER_LONG_ARG} \
294 ${_OPTS_GROFF_LONG_ARG} ${_OPTS_MAN_LONG_ARG} ${_OPTS_X_LONG_ARG}";
297 ########################################################################
298 # read-write variables (global to this file)
299 ########################################################################
301 export _ALL_PARAMS
; # All options and file name parameters
302 export _ADDOPTS_GROFF
; # Transp. options for groff (`eval').
303 export _ADDOPTS_POST
; # Transp. options postproc (`eval').
304 export _ADDOPTS_X
; # Transp. options X postproc (`eval').
305 export _DEFAULT_MODES
; # Set default modes.
306 export _DISPLAY_MODE
; # Display mode.
307 export _DISPLAY_PROG
; # Viewer program to be used for display.
308 export _DISPLAY_ARGS
; # X resources for the viewer program.
309 export _FILEARGS
; # Stores filespec parameters.
310 export _FUNC_STACK
; # Store debugging information.
311 export _REGISTERED_TITLE
; # Processed file names.
312 # _HAS_* from availability tests
313 export _HAS_COMPRESSION
; # `yes' if gzip compression is available
314 export _HAS_BZIP
; # `yes' if bzip2 compression is available
315 # _MAN_* finally used configuration of man searching
316 export _MAN_ALL
; # search all man pages per filespec
317 export _MAN_ENABLE
; # enable search for man pages
318 export _MAN_EXT
; # extension for man pages
319 export _MAN_FORCE
; # force file parameter to be man pages
320 export _MAN_IS_SETUP
; # setup man variables only once
321 export _MAN_LANG
; # language for man pages
322 export _MAN_LANG2
; # language for man pages
323 export _MAN_LANG_DONE
; # language dirs added to man path
324 export _MAN_PATH
; # search path for man pages
325 export _MAN_SEC
; # sections for man pages; sep. `:'
326 export _MAN_SEC_DONE
; # sections added to man path
327 export _MAN_SYS
; # system names for man pages; sep. `,'
328 export _MAN_SYS
; # system names added to man path
329 # _MANOPT_* as parsed from $MANOPT
330 export _MANOPT_ALL
; # $MANOPT --all
331 export _MANOPT_EXTENSION
; # $MANOPT --extension
332 export _MANOPT_LANG
; # $MANOPT --locale
333 export _MANOPT_PATH
; # $MANOPT --manpath
334 export _MANOPT_PAGER
; # $MANOPT --pager
335 export _MANOPT_SEC
; # $MANOPT --sections
336 export _MANOPT_SYS
; # $MANOPT --systems
337 # _OPT_* as parsed from groffer command line
338 export _OPT_ALL
; # display all suitable man pages.
339 export _OPT_APROPOS
; # call `apropos' program.
340 export _OPT_APROPOS_DATA
; # `apropos' for man sections 4, 5, 7
341 export _OPT_APROPOS_DEVEL
; # `apropos' for man sections 2, 3, 9
342 export _OPT_APROPOS_PROGS
; # `apropos' for man sections 1, 6, 8
343 export _OPT_BD
; # set border color in some modes.
344 export _OPT_BG
; # set background color in some modes.
345 export _OPT_BW
; # set border width in some modes.
346 export _OPT_DEBUG
; # print debugging information on stderr.
347 export _OPT_DEFAULT_MODES
; # `,'-list of modes when no mode given.
348 export _OPT_DEVICE
; # device option.
349 export _OPT_DISPLAY
; # set X display.
350 export _OPT_FG
; # set foreground color in some modes.
351 export _OPT_FN
; # set font in some modes.
352 export _OPT_GEOMETRY
; # set size and position of viewer in X.
353 export _OPT_ICONIC
; # -iconic option for X viewers.
354 export _OPT_LANG
; # set language for man pages
355 export _OPT_LOCATION
; # print processed file names to stderr
356 export _OPT_MODE
; # values: X, tty, Q, Z, ""
357 export _OPT_MANPATH
; # manual setting of path for man-pages
358 export _OPT_PAGER
; # specify paging program for tty mode
359 export _OPT_RESOLUTION
; # set X resolution in dpi
360 export _OPT_RV
; # reverse fore- and background colors.
361 export _OPT_SECTIONS
; # sections for man page search
362 export _OPT_SYSTEMS
; # man pages of different OS's
363 export _OPT_TITLE
; # title for gxditview window
364 export _OPT_TEXT_DEVICE
; # set device for tty mode.
365 export _OPT_V
; # groff option -V.
366 export _OPT_VIEWER_DVI
; # viewer program for dvi mode
367 export _OPT_VIEWER_PDF
; # viewer program for pdf mode
368 export _OPT_VIEWER_PS
; # viewer program for ps mode
369 export _OPT_VIEWER_HTML
; # viewer program for html mode
370 export _OPT_VIEWER_X
; # viewer program for x mode
371 export _OPT_WHATIS
; # print the one-liner man info
372 export _OPT_XRM
; # specify X resource.
373 export _OPT_Z
; # groff option -Z.
374 # _TMP_* temporary directory and files
375 export _TMP_DIR
; # groffer directory for temporary files
376 export _TMP_CAT
; # stores concatenation of everything
377 export _TMP_STDIN
; # stores stdin, if any
379 # these variables are preset in section `Preset' after the rudim. test
382 ########################################################################
383 # Test of rudimentary shell functionality
384 ########################################################################
387 ########################################################################
393 _res
="$(unset _foo 2>&1)";
394 if unset _foo
>${_NULL_DEV} 2>&1 && \
395 test _
"${_res}"_
= __
&& test _
"${_foo}"_
= __
398 eval "${_UNSET}" _res
;
404 ########################################################################
407 if test a
= a
&& test a
!= b
&& test -f "${_GROFFER_SH}"
411 echo '"test" did not work.' >&2;
416 ########################################################################
417 # Test of `echo' and the `$()' construct.
419 if echo '' >${_NULL_DEV}
423 echo '"echo" did not work.' >&2;
426 if test _
"$(t1="$
(echo te
)" &&
429 echo "${t1}${t2}${t3}")"_ \
432 echo 'The "$()" construct did not work' >&2;
437 ########################################################################
438 # Test of function definitions.
445 if _t_e_s_t_f_u_n_c_
2>${_NULL_DEV}
449 echo 'Shell '"${_SHELL}"' does not support function definitions.' >&2;
454 ########################################################################
455 # Preset and reset of read-write global variables
456 ########################################################################
459 export _START_DIR
; # directory at start time of the script
462 # For variables that can be reset by option `--default', see reset().
466 # _HAS_* from availability tests
470 # _TMP_* temporary files
477 ########################################################################
480 # Reset the variables that can be affected by options to their default.
486 error
"reset() does not have arguments.";
495 _REGISTERED_TITLE
='';
497 # _MAN_* finally used configuration of man searching
499 _MAN_ENABLE
='yes'; # do search for man-pages
501 _MAN_FORCE
='no'; # first local file, then search man page
511 # _MANOPT_* as parsed from $MANOPT
513 _MANOPT_EXTENSION
='';
520 # _OPT_* as parsed from groffer command line
523 _OPT_APROPOS_DATA
='';
524 _OPT_APROPOS_DEVEL
='';
525 _OPT_APROPOS_PROGS
='';
530 _OPT_DEFAULT_MODES
='';
563 ########################################################################
564 # Functions for error handling and debugging
565 ########################################################################
573 # Arguments : arbitrary text including `-'.
588 # Arguments : arbitrary text.
601 # Print <text> to standard error as a debugging aid.
603 # Globals: $_DEBUG_LM
607 if test _
"${_DEBUG_LM}"_
= _yes_
613 landmark
"1: debugging functions";
623 cd "${_START_DIR}" >"${_NULL_DEV}" 2>&1;
624 if test _
"${_TMP_DIR}"_
!= __
626 if test -d "${_TMP_DIR}" ||
test -f "${_TMP_DIR}"
628 rm -f -r "${_TMP_DIR}" >${_NULL_DEV} 2>&1;
637 # Output a diagnostic message to stderr
648 # Print an error message to standard error; exit with an error condition
650 # Variable prefix: err
654 err_code
="${_ERROR}";
657 1) echo2
'groffer error: '"$1"; ;;
659 echo2
'groffer error: '"$1";
662 *) echo2
'groffer error: wrong number of arguments in error().'; ;;
666 kill "${_PROCESS_ID}" >${_NULL_DEV} 2>&1;
667 kill -9 "${_PROCESS_ID}" >${_NULL_DEV} 2>&1;
669 eval ${_UNSET} err_code
;
677 # Terminate program with error condition
681 error
"abort(): Program aborted.";
687 # func_check (<func_name> <rel_op> <nr_args> "$@")
689 # Check number of arguments and register to _FUNC_STACK.
692 # <func_name>: name of the calling function.
693 # <rel_op>: a relational operator: = != < > <= >=
694 # <nr_args>: number of arguments to be checked against <operator>
695 # "$@": the arguments of the calling function.
697 # Variable prefix: fc
703 error
'func_check() needs at least 3 arguments.';
716 error
"func_check(): third argument must be a digit.";
746 'func_check(): second argument is not a relational operator.';
752 if test "$#" "${fc_op}" "${fc_nargs}"
756 error
"func_check(): \
757 ${fc_fname}"'() needs '"${fc_comp} ${fc_nargs}"' argument'"${fc_s}"'.';
759 func_push
"${fc_fname}";
760 if test _
"${_DEBUG}"_
= _yes_
762 echo2
'+++ '"${fc_fname} $@";
763 echo2
'>>> '"${_FUNC_STACK}";
765 eval ${_UNSET} fc_comp
;
766 eval ${_UNSET} fc_fname
;
767 eval ${_UNSET} fc_nargs
;
768 eval ${_UNSET} fc_op
;
776 # Retrieve the top element from the stack.
778 # The stack elements are separated by `!'; the popped element is
779 # identical to the original element, except that all `!' characters
788 error
'func_pop() does not have arguments.';
790 case "${_FUNC_STACK}" in
792 if test _
"${_DEBUG}"_
= _yes_
794 error
'func_pop(): stack is empty.';
798 # split at first bang `!'.
799 _FUNC_STACK
="$(echo1 "${_FUNC_STACK}" | sed -e 's/^[^!]*!//')";
805 if test _
"${_DEBUG}"_
= _yes_
807 echo2
'<<< '"${_FUNC_STACK}";
813 # func_push (<element>)
815 # Store another element to stack.
817 # The stack elements are separated by `!'; if <element> contains a `!'
818 # it is removed first.
822 # Variable prefix: fp
828 error
'func_push() needs 1 argument.';
832 # remove all bangs `!'.
833 fp_element
="$(echo1 "$1" | sed -e 's/!//g')";
839 if test _
"${_FUNC_STACK}"_
= __
841 _FUNC_STACK
="${fp_element}";
843 _FUNC_STACK
="${fp_element}!${_FUNC_STACK}";
845 eval ${_UNSET} fp_element
;
852 # Print the content of the stack. Ignore the arguments.
856 diag
'call stack: '"${_FUNC_STACK}";
860 ########################################################################
862 ########################################################################
864 landmark
"2: system test";
866 # Test the availability of the system utilities used in this script.
869 ########################################################################
870 # Test of function `sed'.
873 if test _
"$(echo xTesTx \
874 | sed -e 's/^.\([Tt]e*x*sTT*\).*$/\1/' \
875 | sed -e 's|T|t|g')"_
!= _test_
877 error
'Test of "sed" command failed.';
881 ########################################################################
882 # Test of function `cat'.
884 if test _
"$(echo test | cat)"_
!= _test_
886 error
'Test of "cat" command failed.';
890 ########################################################################
891 # Test for compression.
893 if test _
"$(echo 'test' | gzip -c -d -f - 2>${_NULL_DEV})"_
= _test_
895 _HAS_COMPRESSION
='yes';
896 if echo 'test' |
bzip2 -c 2>${_NULL_DEV} |
bzip2 -t 2>${_NULL_DEV} \
897 && test _
"$(echo 'test' | bzip2 -c 2>${_NULL_DEV} \
898 | bzip2 -d -c 2>${_NULL_DEV})"_ \
906 _HAS_COMPRESSION
='no';
911 ########################################################################
912 # Definition of normal Functions in alphabetical order
913 ########################################################################
914 landmark
"3: functions";
916 ########################################################################
919 # Unconditionally terminate the program with error code;
920 # useful for debugging.
925 ########################################################################
926 # apropos_run (<name>)
930 func_check apropos_run
= 1 "$@";
931 if apropos apropos
>${_NULL_DEV} 2>${_NULL_DEV}
934 elif man
--apropos man
>${_NULL_DEV} 2>${_NULL_DEV}
937 elif man
-k man
>${_NULL_DEV} 2>${_NULL_DEV}
945 ########################################################################
948 # Get the file name part of <path>, i.e. delete everything up to last
949 # `/' from the beginning of <path>. Remove final slashes, too, to get a
953 # Output : the file name part (without slashes)
955 # Variable prefix: bn
959 func_check base_name
= 1 "$@";
963 # delete all final slashes
964 bn_name
="$(echo1 "${bn_name}" | sed -e 's|//*$||')";
969 eval ${_UNSET} bn_name
;
970 eval "${return_bad}";
973 # delete everything before and including the last slash `/'.
974 echo1
"${bn_name}" |
sed -e 's|^.*//*\([^/]*\)$|\1|';
980 eval ${_UNSET} bn_name
;
985 ########################################################################
988 # Decompress if possible or just print <file> to standard output.
990 # gzip, bzip2, and .Z decompression is supported.
992 # Arguments: 1, a file name.
993 # Output: the content of <file>, possibly decompressed.
995 if test _
"${_HAS_COMPRESSION}"_
= _yes_
999 func_check cat_z
= 1 "$@";
1002 error
'cat_z(): empty file name';
1005 error
'cat_z(): for standard input use save_stdin()';
1008 if obj _HAS_BZIP is_yes
1010 if bzip2 -t "$1" 2>${_NULL_DEV}
1012 bzip2 -c -d "$1" 2>${_NULL_DEV};
1013 eval "${return_ok}";
1016 gzip -c -d -f "$1" 2>${_NULL_DEV};
1017 eval "${return_ok}";
1022 func_check cat_z
= 1 "$@";
1024 eval "${return_ok}";
1029 ########################################################################
1032 # Do the final cleaning up before exiting; used by the trap calls.
1037 ########################################################################
1040 # Print marked message to standard error; useful for debugging.
1045 ########################################################################
1046 landmark
'4: dirname()*';
1047 ########################################################################
1049 #######################################################################
1050 # dirname_append (<dir> <name>)
1052 # Append `name' to `dir' with clean handling of `/'.
1055 # Output : the generated new directory name <dir>/<name>
1059 func_check dirname_append
= 2 "$@";
1062 error
"dir_append(): first argument is empty.";
1068 dirname_chop
"$1"/"$2";
1070 eval "${return_ok}";
1074 ########################################################################
1075 # dirname_chop (<name>)
1077 # Remove unnecessary slashes from directory name.
1079 # Argument: 1, a directory name.
1080 # Output: path without double, or trailing slashes.
1082 # Variable prefix: dc
1086 func_check dirname_chop
= 1 "$@";
1087 # replace all multiple slashes by a single slash `/'.
1088 dc_res
="$(echo1 "$1" | sed -e 's|///*|/|g')";
1091 # remove trailing slash '/';
1092 echo1
"${dc_res}" |
sed -e 's|/$||';
1098 eval ${_UNSET} dc_res
;
1099 eval "${return_ok}";
1103 ########################################################################
1104 # do_filearg (<filearg>)
1106 # Append the file, man-page, or standard input corresponding to the
1107 # argument to the temporary file. If this is compressed in the gzip
1108 # or Z format it is decompressed. A title element is generated.
1111 # - name of an existing files.
1112 # - `-' to represent standard input (several times allowed).
1113 # - `man:name.(section)' the man-page for `name' in `section'.
1114 # - `man:name.section' the man-page for `name' in `section'.
1115 # - `man:name' the man-page for `name' in the lowest `section'.
1116 # - `name.section' the man-page for `name' in `section'.
1117 # - `name' the man-page for `name' in the lowest `section'.
1119 # $_TMP_STDIN, $_MAN_ENABLE, $_MAN_IS_SETUP, $_OPT_MAN
1122 # Return : $_GOOD if found, ${_BAD} otherwise.
1124 # Variable prefix: df
1128 func_check do_filearg
= 1 "$@";
1130 # store sequence into positional parameters
1131 case "${df_filespec}" in
1133 eval ${_UNSET} df_filespec
;
1134 eval "${return_good}";
1138 eval ${_UNSET} df_filespec
;
1139 eval "${return_good}";
1141 */*) # with directory part; so no man search
1145 if obj _MAN_ENABLE is_yes
1147 if obj _MAN_FORCE is_yes
1149 set 'Manpage' 'File';
1151 set 'File' 'Manpage';
1162 if test -f "${df_filespec}"
1164 if test -r "${df_filespec}"
1166 register_file
"${df_filespec}";
1167 eval ${_UNSET} df_filespec
;
1168 eval ${_UNSET} df_no_man
;
1169 eval "${return_good}";
1171 echo2
"could not read \`${df_filespec}'";
1172 eval ${_UNSET} df_filespec
;
1173 eval ${_UNSET} df_no_man
;
1174 eval "${return_bad}";
1177 if obj df_no_man is_not_empty
1179 echo2
"\`${df_filespec}' is neither a file nor a man page."
1185 Manpage
) # parse filespec as man page
1186 if obj _MAN_IS_SETUP is_not_yes
1190 if man_do_filespec
"${df_filespec}"
1192 eval ${_UNSET} df_filespec
;
1193 eval ${_UNSET} df_no_file
;
1194 eval "${return_good}";
1196 if obj df_no_file is_not_empty
1198 echo2
"\`${df_filespec}' is neither a file nor a man page."
1206 eval ${_UNSET} df_filespec
;
1207 eval ${_UNSET} df_no_file
;
1208 eval ${_UNSET} df_no_man
;
1209 eval "${return_bad}";
1213 ########################################################################
1220 eval return "${_OK}";
1224 ########################################################################
1227 # Print to standard error with final line break.
1232 ########################################################################
1235 # Print error message and exit with error code.
1240 ########################################################################
1241 # func_check (<func_name> <rel_op> <nr_args> "$@")
1243 # Check number of arguments and register to _FUNC_STACK.
1246 # <func_name>: name of the calling function.
1247 # <rel_op>: a relational operator: = != < > <= >=
1248 # <nr_args>: number of arguments to be checked against <operator>
1249 # "$@": the arguments of the calling function.
1253 #########################################################################
1256 # Delete the top element from the function call stack.
1261 ########################################################################
1262 # func_push (<element>)
1264 # Store another element to function call stack.
1269 ########################################################################
1270 # func_stack_dump ()
1272 # Print the content of the stack.
1277 ########################################################################
1278 # get_first_essential (<arg>*)
1280 # Retrieve first non-empty argument.
1282 # Return : `1' if all arguments are empty, `0' if found.
1283 # Output : the retrieved non-empty argument.
1285 # Variable prefix: gfe
1287 get_first_essential
()
1289 func_check get_first_essential
'>=' 0 "$@";
1292 eval "${return_ok}";
1297 if obj gfe_var is_not_empty
1300 eval ${_UNSET} gfe_var
;
1301 eval "${return_ok}";
1304 eval ${_UNSET} gfe_var
;
1305 eval "${return_bad}";
1309 ########################################################################
1310 landmark
'5: is_*()';
1311 ########################################################################
1313 ########################################################################
1316 # Test whether `name' is a directory.
1319 # Return : `0' if arg1 is a directory, `1' otherwise.
1323 func_check is_dir
= 1 "$@";
1324 if test _
"$1"_
!= __
&& test -d "$1" && test -r "$1"
1326 eval "${return_yes}";
1328 eval "${return_no}";
1332 ########################################################################
1333 # is_empty (<string>)
1335 # Test whether `string' is empty.
1338 # Return : `0' if arg1 is empty or does not exist, `1' otherwise.
1342 func_check is_empty
= 1 "$@";
1345 eval "${return_yes}";
1347 eval "${return_no}";
1351 ########################################################################
1352 # is_equal (<string1> <string2>)
1354 # Test whether `string1' is equal to <string2>.
1357 # Return : `0' both arguments are equal strings, `1' otherwise.
1361 func_check is_equal
= 2 "$@";
1362 if test _
"$1"_
= _
"$2"_
1364 eval "${return_yes}";
1366 eval "${return_no}";
1370 ########################################################################
1371 # is_existing (<name>)
1373 # Test whether `name' is an existing file or directory. Solaris 2.5 does
1374 # not have `test -e'.
1377 # Return : `0' if arg1 exists, `1' otherwise.
1381 func_check is_existing
= 1 "$@";
1384 eval "${return_no}";
1386 if test -f "$1" ||
test -d "$1" ||
test -c "$1"
1388 eval "${return_yes}";
1390 eval "${return_no}";
1394 ########################################################################
1397 # Test whether `name' is a readable file.
1400 # Return : `0' if arg1 is a readable file, `1' otherwise.
1404 func_check is_file
= 1 "$@";
1405 if test _
"$1"_
!= __
&& test -f "$1" && test -r "$1"
1407 eval "${return_yes}";
1409 eval "${return_no}";
1413 ########################################################################
1414 # is_non_empty_file (<file_name>)
1416 # Test whether `file_name' is a non-empty existing file.
1420 # `0' if arg1 is a non-empty existing file
1425 func_check is_non_empty_file
= 1 "$@";
1426 if is_file
"$1" && test -s "$1"
1428 eval "${return_yes}";
1430 eval "${return_no}";
1434 ########################################################################
1435 # is_not_dir (<name>)
1437 # Test whether `name' is not a readable directory.
1440 # Return : `0' if arg1 is a directory, `1' otherwise.
1444 func_check is_not_dir
= 1 "$@";
1447 eval "${return_no}";
1449 eval "${return_yes}";
1453 ########################################################################
1454 # is_not_empty (<string>)
1456 # Test whether `string' is not empty.
1459 # Return : `0' if arg1 exists and is not empty, `1' otherwise.
1463 func_check is_not_empty
= 1 "$@";
1466 eval "${return_no}";
1468 eval "${return_yes}";
1472 ########################################################################
1473 # is_not_equal (<string1> <string2>)
1475 # Test whether `string1' differs from `string2'.
1481 func_check is_not_equal
= 2 "$@";
1482 if is_equal
"$1" "$2"
1484 eval "${return_no}";
1486 eval "${return_yes}";
1490 ########################################################################
1491 # is_not_file (<filename>)
1493 # Test whether `name' is a not readable file.
1495 # Arguments : >=1 (empty allowed), more args are ignored
1499 func_check is_not_file
'>=' 1 "$@";
1502 eval "${return_no}";
1504 eval "${return_yes}";
1508 ########################################################################
1509 # is_not_prog (<name>)
1511 # Verify that arg is a not program in $PATH.
1513 # Arguments : >=1 (empty allowed)
1514 # more args are ignored, this allows to specify progs with arguments
1518 func_check is_not_prog
'>=' 1 "$@";
1519 if where_is
"$1" >${_NULL_DEV}
1521 eval "${return_no}";
1523 eval "${return_yes}";
1527 ########################################################################
1528 # is_not_writable (<name>)
1530 # Test whether `name' is a not a writable file or directory.
1532 # Arguments : >=1 (empty allowed), more args are ignored
1536 func_check is_not_writable
'>=' 1 "$@";
1539 eval "${return_no}";
1541 eval "${return_yes}";
1545 ########################################################################
1546 # is_not_yes (<string>)
1548 # Test whether `string' is not "yes".
1554 func_check is_not_yes
= 1 "$@";
1557 eval "${return_no}";
1559 eval "${return_yes}";
1563 ########################################################################
1564 # is_prog (<name> [<arg>*])
1566 # Determine whether <name> is a program in $PATH
1568 # Arguments : >=0 (empty allowed)
1569 # <arg>* are ignored, this allows to specify progs with arguments.
1573 func_check is_prog
'>=' 0 "$@";
1576 eval "${return_no}";
1579 if where_is
"$1" >${_NULL_DEV}
1581 eval "${return_yes}";
1585 eval "${return_no}";
1589 ########################################################################
1590 # is_writable (<name>)
1592 # Test whether `name' is a writable file or directory.
1594 # Arguments : >=1 (empty allowed), more args are ignored
1598 func_check is_writable
'>=' 1 "$@";
1601 eval "${return_no}";
1607 eval "${return_yes}";
1610 eval "${return_no}";
1614 ########################################################################
1617 # Test whether `string' has value "yes".
1620 # Return : `0' if arg1 is `yes', `1' otherwise.
1624 func_check is_yes
= 1 "$@";
1625 if is_equal
"$1" 'yes'
1627 eval "${return_yes}";
1629 eval "${return_no}";
1633 ########################################################################
1636 # Print debugging information on standard error if $_DEBUG_LM is `yes'.
1638 # Globals: $_DEBUG_LM
1640 # Defined in section `Debugging functions'.
1643 ########################################################################
1646 # Clean exit without an error or with <code>.
1660 ########################################################################
1661 landmark
'6: list_*()';
1662 ########################################################################
1664 # `list' is an object class that represents an array or list. Its
1665 # data consists of space-separated single-quoted elements. So a list
1666 # has the form "'first' 'second' '...' 'last'". See list_append() for
1667 # more details on the list structure. The array elements of `list'
1668 # can be get by `eval set x "$list"; shift`.
1671 ########################################################################
1672 # list_append (<list> <element>...)
1675 # <list>: a variable name for a list of single-quoted elements
1676 # <element>: some sequence of characters.
1677 # Output: none, but $<list> is set to
1678 # if <list> is empty: "'<element>' '...'"
1679 # otherwise: "$list '<element>' ..."
1681 # Variable prefix: la
1685 func_check list_append
'>=' 2 "$@";
1687 eval la_list
='"${'$1'}"';
1694 # escape each single quote by replacing each
1695 # "'" (squote) by "'\''" (squote bslash squote squote);
1696 # note that the backslash must be doubled in the following `sed'
1697 la_element
="$(echo1 "${la_s}" | sed -e 's/'"${_SQ}"'/&\\&&/g')";
1703 la_element
="${la_s}";
1706 if obj la_list is_empty
1708 la_list
="'${la_element}'";
1710 la_list
="${la_list} '${la_element}'";
1713 eval "${la_name}"='"${la_list}"';
1714 eval ${_UNSET} la_element
;
1715 eval ${_UNSET} la_list
;
1716 eval ${_UNSET} la_name
;
1717 eval ${_UNSET} la_s
;
1718 eval "${return_ok}";
1722 ########################################################################
1723 # list_from_cmdline (<pre_name_of_opt_lists> [<cmdline_arg>...])
1725 # Transform command line arguments into a normalized form.
1727 # Options, option arguments, and file parameters are identified and
1728 # output each as a single-quoted argument of its own. Options and
1729 # file parameters are separated by a '--' argument.
1732 # <pre_name>: common part of a set of 4 environment variable names:
1733 # $<pre_name>_SHORT_NA: list of short options without an arg.
1734 # $<pre_name>_SHORT_ARG: list of short options that have an arg.
1735 # $<pre_name>_LONG_NA: list of long options without an arg.
1736 # $<pre_name>_LONG_ARG: list of long options that have an arg.
1737 # <cmdline_arg>...: the arguments from a command line, such as "$@",
1738 # the content of a variable, or direct arguments.
1740 # Output: ['-[-]opt' ['optarg']]... '--' ['filename']...
1743 # list_from_cmdline PRE 'a b' 'c' '' 'long' -a f1 -bcarg --long=larg f2
1744 # If $PRE_SHORT_NA, $PRE_SHORT_ARG, $PRE_LONG_NA, and $PRE_LONG_ARG are
1745 # none-empty option lists, this will result in printing:
1746 # '-a' '-b' '-c' 'arg' '--long' 'larg' '--' 'f1' 'f2'
1748 # Use this function in the following way:
1749 # eval set x "$(args_norm PRE_NAME "$@")";
1751 # while test "$1" != '--'; do
1758 # # all positional parameters ("$@") left are file name parameters.
1760 # Variable prefix: lfc
1764 func_check list_from_cmdline
'>=' 1 "$@";
1765 lfc_short_n
="$(obj_data "$1"_SHORT_NA)"; # short options, no argument
1766 lfc_short_a
="$(obj_data "$1"_SHORT_ARG)"; # short options, with argument
1767 lfc_long_n
="$(obj_data "$1"_LONG_NA)"; # long options, no argument
1768 lfc_long_a
="$(obj_data "$1"_LONG_ARG)"; # long options, with argument
1769 if obj lfc_short_n is_empty
1771 error
'list_from_cmdline(): no $'"$1"'_SHORT_NA options.';
1773 if obj lfc_short_a is_empty
1775 error
'list_from_cmdline(): no $'"$1"'_SHORT_ARG options.';
1777 if obj lfc_long_n is_empty
1779 error
'list_from_cmdline(): no $'"$1"'_LONG_NA options.';
1781 if obj lfc_long_a is_empty
1783 error
'list_from_cmdline(): no $'"$1"'_LONG_ARG options.';
1789 eval ${_UNSET} lfc_fparams
;
1790 eval ${_UNSET} lfc_short_a
;
1791 eval ${_UNSET} lfc_short_n
;
1792 eval ${_UNSET} lfc_long_a
;
1793 eval ${_UNSET} lfc_long_n
;
1794 eval ${_UNSET} lfc_result
;
1795 eval "${return_ok}";
1799 while test "$#" -ge 1
1803 case "${lfc_arg}" in
1806 # delete leading '--';
1807 lfc_abbrev
="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
1808 lfc_opt
="$(list_single_from_abbrev lfc_long_n "${lfc_abbrev}")";
1809 if obj lfc_opt is_not_empty
1811 # long option, no argument
1812 list_append lfc_result
"--${lfc_opt}";
1815 # test on `--opt=arg'
1816 if string_contains
"${lfc_abbrev}" '='
1818 lfc_with_equal
="${lfc_abbrev}";
1819 # extract option by deleting from the first '=' to the end
1820 lfc_abbrev
="$(echo1 "${lfc_with_equal}" | \
1821 sed -e 's/^\([^=]*\)=.*$/\1/')";
1822 lfc_opt
="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
1823 if obj lfc_opt is_not_empty
1825 # get the option argument by deleting up to first `='
1826 lfc_optarg
="$(echo1 "${lfc_with_equal}" | sed -e 's/^[^=]*=//')";
1827 list_append lfc_result
"--${lfc_opt}" "${lfc_optarg}";
1831 lfc_opt
="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
1832 if obj lfc_opt is_not_empty
1834 # long option with argument
1837 error
"list_from_cmdline(): no argument for option --${lfc_opt}."
1839 list_append lfc_result
"--${lfc_opt}" "$1";
1843 error
"list_from_cmdline(): --${lfc_opt} is not an option."
1845 -?
*) # short option (cluster)
1846 # delete leading `-';
1847 lfc_rest
="$(echo1 "${lfc_arg}" | sed -e 's/^-//')";
1848 while obj lfc_rest is_not_empty
1850 # get next short option from cluster (first char of $lfc_rest)
1851 lfc_optchar
="$(echo1 "${lfc_rest}" | sed -e 's/^\(.\).*$/\1/')";
1852 # remove first character from ${lfc_rest};
1853 lfc_rest
="$(echo1 "${lfc_rest}" | sed -e 's/^.//')";
1854 if list_has lfc_short_n
"${lfc_optchar}"
1856 list_append lfc_result
"-${lfc_optchar}";
1858 elif list_has lfc_short_a
"${lfc_optchar}"
1860 if obj lfc_rest is_empty
1864 list_append lfc_result
"-${lfc_optchar}" "$1";
1868 error
'list_from_cmdline(): no argument for option -'\
1871 else # rest is the argument
1872 list_append lfc_result
"-${lfc_optchar}" "${lfc_rest}";
1877 error
"list_from_cmdline(): unknown option -${lfc_optchar}."
1882 # Here, $lfc_arg is not an option, so a file parameter.
1883 list_append lfc_fparams
"${lfc_arg}";
1885 # Ignore the strange POSIX option handling to end option
1886 # parsing after the first file name argument. To reuse it, do
1887 # a `break' here if $POSIXLY_CORRECT of `bash' is not empty.
1888 # When `bash' is called as `sh' $POSIXLY_CORRECT is set
1889 # automatically to `y'.
1893 list_append lfc_result
'--';
1894 if obj lfc_fparams is_not_empty
1896 lfc_result
="${lfc_result} ${lfc_fparams}";
1900 list_append lfc_result
"$@";
1902 obj lfc_result echo1
;
1903 eval ${_UNSET} lfc_abbrev
;
1904 eval ${_UNSET} lfc_fparams
;
1905 eval ${_UNSET} lfc_short_a
;
1906 eval ${_UNSET} lfc_short_n
;
1907 eval ${_UNSET} lfc_long_a
;
1908 eval ${_UNSET} lfc_long_n
;
1909 eval ${_UNSET} lfc_result
;
1910 eval ${_UNSET} lfc_arg
;
1911 eval ${_UNSET} lfc_opt
;
1912 eval ${_UNSET} lfc_opt_arg
;
1913 eval ${_UNSET} lfc_opt_char
;
1914 eval ${_UNSET} lfc_with_equal
;
1915 eval ${_UNSET} lfc_rest
;
1916 eval "${return_ok}";
1917 } # list_from_cmdline()
1920 ########################################################################
1921 # list_from_split (<string> <separator>)
1923 # In <string>, escape all white space characters and replace each
1924 # <separator> by space.
1926 # Arguments: 2: a <string> that is to be split into parts divided by
1928 # Output: the resulting list string
1930 # Variable prefix: lfs
1934 func_check list_from_split
= 2 "$@";
1936 # precede each space or tab by a backslash `\' (doubled for `sed')
1937 lfs_s
="$(echo1 "$1" | sed -e 's/\(['"${_SP}${_TAB}"']\)/\\\1/g')";
1939 # replace split character of string by the list separator ` ' (space).
1941 /) # cannot use normal `sed' separator
1942 echo1
"${lfs_s}" |
sed -e 's|'"$2"'| |g';
1944 ?
) # use normal `sed' separator
1945 echo1
"${lfs_s}" |
sed -e 's/'"$2"'/ /g';
1948 error
'list_from_split(): separator must be a single character.';
1951 eval ${_UNSET} lfs_s
;
1952 eval "${return_ok}";
1956 ########################################################################
1959 # Check whether <list> is a space-separated list of '-quoted elements.
1961 # If the test fails an error is raised.
1962 # If the test succeeds the argument is echoed.
1965 # A list has the form "'first' 'second' '...' 'last'". So it has a
1966 # leading and a final quote and the elements are separated by "' '"
1967 # constructs. If these are all removed there should not be any
1968 # unescaped single-quotes left. Watch out for escaped single
1969 # quotes; they have the form '\'' (sq bs sq sq).
1972 # Output: the argument <list> unchanged, if the check succeeded.
1974 # Variable prefix: lg
1978 func_check list_get
= 1 "$@";
1979 eval lg_list
='"${'$1'}"';
1980 # remove leading and final space characters
1981 lg_list
="$(echo1 "${lg_list}" | sed -e '
1982 s/^['"${_SP}${_TAB}"']*//
1983 s/['"${_SP}${_TAB}"']*$//
1985 case "${lg_list}" in
1987 eval ${_UNSET} lg_list
;
1988 eval "${return_ok}";
1992 eval ${_UNSET} lg_list
;
1993 eval "${return_ok}";
1996 error
"list_get(): bad list: $1"
1999 eval ${_UNSET} lg_list
;
2000 eval "${return_ok}";
2004 ########################################################################
2005 # list_has (<var_name> <element>)
2007 # Test whether the list <var_name> has the element <element>.
2010 # <var_name>: a variable name for a list of single-quoted elements
2011 # <element>: some sequence of characters.
2013 # Variable prefix: lh
2017 func_check list_has
= 2 "$@";
2018 eval lh_list
='"${'$1'}"';
2019 if obj lh_list is_empty
2021 eval "${_UNSET}" lh_list
;
2022 eval "${return_no}";
2025 \'*\') lh_element
=" $2 "; ;;
2026 *) lh_element
=" '$2' "; ;;
2028 if string_contains
" ${lh_list} " "${lh_element}"
2030 eval "${_UNSET}" lh_list
;
2031 eval "${_UNSET}" lh_element
;
2032 eval "${return_yes}";
2034 eval "${_UNSET}" lh_list
;
2035 eval "${_UNSET}" lh_element
;
2036 eval "${return_no}";
2041 ########################################################################
2042 # list_has_abbrev (<var_name> <abbrev>)
2044 # Test whether the list <var_name> has an element starting with <abbrev>.
2047 # <var_name>: a variable name for a list of single-quoted elements
2048 # <abbrev>: some sequence of characters.
2050 # Variable prefix: lha
2054 func_check list_has_abbrev
= 2 "$@";
2055 eval lha_list
='"${'$1'}"';
2056 if obj lha_list is_empty
2058 eval "${_UNSET}" lha_list
;
2059 eval "${return_no}";
2062 \'*) lha_element
=" $(echo1 "$2" | sed -e 's/'"${_SQ}"'$//')"; ;;
2063 *) lha_element
=" '$2"; ;;
2065 if string_contains
" ${lha_list}" "${lha_element}"
2067 eval "${_UNSET}" lha_list
;
2068 eval "${_UNSET}" lha_element
;
2069 eval "${return_yes}";
2071 eval "${_UNSET}" lha_list
;
2072 eval "${_UNSET}" lha_element
;
2073 eval "${return_no}";
2075 eval "${return_ok}";
2079 ########################################################################
2080 # list_has_not (<list> <element>)
2082 # Test whether <list> has no <element>.
2085 # <list>: a space-separated list of single-quoted elements.
2086 # <element>: some sequence of characters.
2088 # Variable prefix: lhn
2092 func_check list_has_not
= 2 "$@";
2093 eval lhn_list
='"${'$1'}"';
2094 if obj lhn_list is_empty
2096 eval "${_UNSET}" lhn_list
;
2097 eval "${return_yes}";
2100 \'*\') lhn_element
=" $2 "; ;;
2101 *) lhn_element
="' $2 '"; ;;
2103 if string_contains
" ${lhn_list} " "${lhn_element}"
2105 eval "${_UNSET}" lhn_list
;
2106 eval "${_UNSET}" lhn_element
;
2107 eval "${return_no}";
2109 eval "${_UNSET}" lhn_list
;
2110 eval "${_UNSET}" lhn_element
;
2111 eval "${return_yes}";
2116 ########################################################################
2117 # list_single_from_abbrev (<list> <abbrev>)
2119 # Check whether the list has an element starting with <abbrev>. If
2120 # there are more than a single element an error is created.
2123 # <list>: a variable name for a list of single-quoted elements
2124 # <abbrev>: some sequence of characters.
2126 # Output: the found element.
2128 # Variable prefix: lsfa
2130 list_single_from_abbrev
()
2132 func_check list_single_from_abbrev
= 2 "$@";
2133 eval lsfa_list
='"${'$1'}"';
2134 if obj lsfa_list is_empty
2136 eval "${_UNSET}" lsfa_list
;
2137 eval "${return_no}";
2140 if list_has lsfa_list
"${lsfa_abbrev}"
2142 obj lsfa_abbrev echo1
;
2143 eval "${_UNSET}" lsfa_abbrev
;
2144 eval "${_UNSET}" lsfa_list
;
2145 eval "${return_yes}";
2147 if list_has_abbrev lsfa_list
"${lsfa_abbrev}"
2150 eval set x
"${lsfa_list}";
2156 if obj lsfa_element is_not_empty
2158 error
"list_single_from_abbrev: the abbreviation ${lsfa_abbrev} \
2159 has multiple options: ${lsfa_element} and ${i}.";
2165 obj lsfa_element echo1
;
2166 eval "${_UNSET}" lsfa_abbrev
;
2167 eval "${_UNSET}" lsfa_element
;
2168 eval "${_UNSET}" lsfa_list
;
2169 eval "${return_yes}";
2171 eval "${_UNSET}" lsfa_abbrev
;
2172 eval "${_UNSET}" lsfa_element
;
2173 eval "${_UNSET}" lsfa_list
;
2174 eval "${return_no}";
2179 ########################################################################
2180 landmark
'7: man_*()';
2181 ########################################################################
2183 ########################################################################
2184 # man_do_filespec (<filespec>)
2186 # Print suitable man page(s) for filespec to $_TMP_CAT.
2189 # <filespec>: argument of the form `man:name.section', `man:name',
2190 # `man:name(section)', `name.section', `name'.
2192 # Globals : $_OPT_ALL
2195 # Return : `0' if man page was found, `1' else.
2197 # Only called from do_fileargs(), checks on $MANPATH and $_MAN_ENABLE
2198 # are assumed (see man_setup()).
2200 # Variable prefix: mdf
2204 func_check man_do_filespec
= 1 "$@";
2205 if obj _MAN_PATH is_empty
2207 eval "${return_bad}";
2211 eval "${return_bad}";
2216 case "${mdf_spec}" in
2217 */*) # not a man spec when it contains '/'
2218 eval ${_UNSET} mdf_got_one
;
2219 eval ${_UNSET} mdf_name
;
2220 eval ${_UNSET} mdf_section
;
2221 eval ${_UNSET} mdf_spec
;
2222 eval "${return_bad}";
2224 man
:?
*\
(?
*\
)) # man:name(section)
2225 mdf_name
="$(echo1 "${mdf_spec}" \
2226 | sed -e 's/^man:\(..*\)(\(..*\))$/\1/')";
2227 mdf_section
="$(echo1 "${mdf_spec}" \
2228 | sed -e 's/^man:\(..*\)(\(..*\))$/\2/')";
2230 man
:?
*.
[0-9on]) # man:name.section
2231 mdf_name
="$(echo1 "${mdf_spec}" \
2232 | sed -e 's/^man:\(..*\)\..$/\1/')";
2233 mdf_section
="$(echo1 "${mdf_spec}" \
2234 | sed -e 's/^.*\(.\)$/\1/')";
2237 mdf_name
="$(echo1 "${mdf_spec}" | sed -e 's/^man://')";
2239 ?
*\
(?
*\
)) # name(section)
2240 mdf_name
="$(echo1 "${mdf_spec}" \
2241 | sed -e 's/^\(..*\)(\(..*\))$/\1/')";
2242 mdf_section
="$(echo1 "${mdf_spec}" \
2243 | sed -e 's/^\(..*\)(\(..*\))$/\2/')";
2245 ?
*.
[0-9on]) # name.section
2246 mdf_name
="$(echo1 "${mdf_spec}" \
2247 | sed -e 's/^\(..*\)\..$/\1/')";
2248 mdf_section
="$(echo1 "${mdf_spec}" \
2249 | sed -e 's/^.*\(.\)$/\1/')";
2252 mdf_name
="${mdf_spec}";
2255 if obj mdf_name is_empty
2257 eval ${_UNSET} mdf_got_one
;
2258 eval ${_UNSET} mdf_name
;
2259 eval ${_UNSET} mdf_section
;
2260 eval ${_UNSET} mdf_spec
;
2261 eval "${return_bad}";
2264 if obj mdf_section is_empty
2266 eval set x
"${_MAN_AUTO_SEC}";
2271 if man_search_section
"${mdf_name}" "${mdf_s}"
2273 if obj _MAN_ALL is_yes
2277 eval ${_UNSET} mdf_got_one
;
2278 eval ${_UNSET} mdf_name
;
2279 eval ${_UNSET} mdf_s
;
2280 eval ${_UNSET} mdf_section
;
2281 eval ${_UNSET} mdf_spec
;
2282 eval "${return_good}";
2287 if man_search_section
"${mdf_name}" "${mdf_section}"
2289 eval ${_UNSET} mdf_got_one
;
2290 eval ${_UNSET} mdf_name
;
2291 eval ${_UNSET} mdf_s
;
2292 eval ${_UNSET} mdf_section
;
2293 eval ${_UNSET} mdf_spec
;
2294 eval "${return_good}";
2296 eval ${_UNSET} mdf_got_one
;
2297 eval ${_UNSET} mdf_name
;
2298 eval ${_UNSET} mdf_section
;
2299 eval ${_UNSET} mdf_spec
;
2300 eval "${return_bad}";
2303 if obj _MAN_ALL is_yes
&& is_yes
"${mdf_got_one}"
2305 eval ${_UNSET} mdf_got_one
;
2306 eval ${_UNSET} mdf_name
;
2307 eval ${_UNSET} mdf_s
;
2308 eval ${_UNSET} mdf_section
;
2309 eval ${_UNSET} mdf_spec
;
2310 eval "${return_good}";
2312 eval ${_UNSET} mdf_got_one
;
2313 eval ${_UNSET} mdf_name
;
2314 eval ${_UNSET} mdf_s
;
2315 eval ${_UNSET} mdf_section
;
2316 eval ${_UNSET} mdf_spec
;
2317 eval "${return_bad}";
2318 } # man_do_filespec()
2321 ########################################################################
2322 # man_register_file (<file> <name> [<section>])
2324 # Write a found man page file and register the title element.
2326 # Arguments: 1, 2, or 3; maybe empty
2331 func_check man_register_file
'>=' 2 "$@";
2335 error
"man_register_file() expects 2 or 3 arguments.";
2340 error
'man_register_file(): file name is empty';
2345 register_title
"man:$2";
2346 eval "${return_ok}";
2349 register_title
"$2.$3";
2350 eval "${return_ok}";
2353 eval "${return_ok}";
2357 ########################################################################
2358 # man_search_section (<name> <section>)
2360 # Retrieve man pages.
2363 # Globals : $_MAN_PATH, $_MAN_EXT
2364 # Return : 0 if found, 1 otherwise
2366 # Variable prefix: mss
2368 man_search_section
()
2370 func_check man_search_section
= 2 "$@";
2371 if obj _MAN_PATH is_empty
2373 eval "${return_bad}";
2377 eval "${return_bad}";
2381 eval "${return_bad}";
2385 eval set x
"$(path_split "${_MAN_PATH}")";
2388 if obj _MAN_EXT is_empty
2392 mss_dir
="$(dirname_append "$d" "man
${mss_section}")";
2393 if obj mss_dir is_dir
2396 dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
2397 mss_files
="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
2398 sed -e '\| found|s|.*||'
2400 if obj mss_files is_not_empty
2402 # for f in $mss_files
2403 for f
in $
(eval set x
${mss_files}; shift; echo "$@")
2406 if obj mss_f is_file
2408 if is_yes
"${mss_got_one}"
2410 register_file
"${mss_f}";
2411 elif obj _MAN_ALL is_yes
2413 man_register_file
"${mss_f}" "${mss_name}";
2415 man_register_file
"${mss_f}" "${mss_name}" "${mss_section}";
2416 eval ${_UNSET} mss_dir
;
2417 eval ${_UNSET} mss_ext
;
2418 eval ${_UNSET} mss_f
;
2419 eval ${_UNSET} mss_files
;
2420 eval ${_UNSET} mss_got_one
;
2421 eval ${_UNSET} mss_name
;
2422 eval ${_UNSET} mss_prefix
;
2423 eval ${_UNSET} mss_section
;
2424 eval "${return_good}";
2433 mss_ext
="${_MAN_EXT}";
2434 # check for directory name having trailing extension
2437 mss_dir
="$(dirname_append $d man${mss_section}${mss_ext})";
2438 if obj mss_dir is_dir
2441 "$(dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
2442 mss_files
="$( eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
2443 sed -e '\|not found|s|.*||'
2445 if obj mss_files is_not_empty
2447 # for f in $mss_files
2448 for f
in $
(eval set x
${mss_files}; shift; echo "$@")
2451 if obj mss_f is_file
2453 if is_yes
"${mss_got_one}"
2455 register_file
"${mss_f}";
2456 elif obj _MAN_ALL is_yes
2458 man_register_file
"${mss_f}" "${mss_name}";
2460 man_register_file
"${mss_f}" "${mss_name}" "${mss_section}";
2461 eval ${_UNSET} mss_dir
;
2462 eval ${_UNSET} mss_ext
;
2463 eval ${_UNSET} mss_f
;
2464 eval ${_UNSET} mss_files
;
2465 eval ${_UNSET} mss_got_one
;
2466 eval ${_UNSET} mss_name
;
2467 eval ${_UNSET} mss_prefix
;
2468 eval ${_UNSET} mss_section
;
2469 eval "${return_good}";
2477 # check for files with extension in directories without extension
2480 mss_dir
="$(dirname_append "$d" "man
${mss_section}")";
2481 if obj mss_dir is_dir
2483 mss_prefix
="$(dirname_append "${mss_dir}" \
2484 "${mss_name}.${mss_section}${mss_ext}")";
2485 mss_files
="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
2486 sed -e '\|not found|s|.*||'
2488 if obj mss_files is_not_empty
2490 # for f in $mss_files
2491 for f
in $
(eval set x
${mss_files}; shift; echo "$@")
2494 if obj mss_f is_file
2496 if is_yes
"${mss_got_one}"
2498 register_file
"${mss_f}";
2499 elif obj _MAN_ALL is_yes
2501 man_register_file
"${mss_f}" "${mss_name}";
2503 man_register_file
"${mss_f}" "${mss_name}" "${mss_section}";
2504 eval ${_UNSET} mss_dir
;
2505 eval ${_UNSET} mss_ext
;
2506 eval ${_UNSET} mss_f
;
2507 eval ${_UNSET} mss_files
;
2508 eval ${_UNSET} mss_got_one
;
2509 eval ${_UNSET} mss_name
;
2510 eval ${_UNSET} mss_prefix
;
2511 eval ${_UNSET} mss_section
;
2512 eval "${return_good}";
2521 if obj _MAN_ALL is_yes
&& is_yes
"${mss_got_one}"
2523 eval ${_UNSET} mss_dir
;
2524 eval ${_UNSET} mss_ext
;
2525 eval ${_UNSET} mss_f
;
2526 eval ${_UNSET} mss_files
;
2527 eval ${_UNSET} mss_got_one
;
2528 eval ${_UNSET} mss_name
;
2529 eval ${_UNSET} mss_prefix
;
2530 eval ${_UNSET} mss_section
;
2531 eval "${return_good}";
2533 eval ${_UNSET} mss_dir
;
2534 eval ${_UNSET} mss_ext
;
2535 eval ${_UNSET} mss_f
;
2536 eval ${_UNSET} mss_files
;
2537 eval ${_UNSET} mss_got_one
;
2538 eval ${_UNSET} mss_name
;
2539 eval ${_UNSET} mss_prefix
;
2540 eval ${_UNSET} mss_section
;
2541 eval "${return_bad}";
2542 } # man_search_section()
2545 ########################################################################
2548 # Setup the variables $_MAN_* needed for man page searching.
2551 # in: $_OPT_*, $_MANOPT_*, $LANG, $LC_MESSAGES, $LC_ALL,
2552 # $MANPATH, $MANROFFSEQ, $MANSEC, $PAGER, $SYSTEM, $MANOPT.
2553 # out: $_MAN_PATH, $_MAN_LANG, $_MAN_SYS, $_MAN_LANG, $_MAN_LANG2,
2554 # $_MAN_SEC, $_MAN_ALL
2555 # in/out: $_MAN_ENABLE
2557 # The precedence for the variables related to `man' is that of GNU
2560 # $LANG; overridden by
2561 # $LC_MESSAGES; overridden by
2562 # $LC_ALL; this has the same precedence as
2563 # $MANPATH, $MANROFFSEQ, $MANSEC, $PAGER, $SYSTEM; overridden by
2564 # $MANOPT; overridden by
2565 # the groffer command line options.
2567 # Variable prefix: ms
2571 func_check main_man_setup
= 0 "$@";
2573 if obj _MAN_IS_SETUP is_yes
2575 eval "${return_ok}";
2577 _MAN_IS_SETUP
='yes';
2579 if obj _MAN_ENABLE is_not_yes
2581 eval "${return_ok}";
2584 # determine basic path for man pages
2585 _MAN_PATH
="$(get_first_essential \
2586 "${_OPT_MANPATH}" "${_MANOPT_PATH}" "${MANPATH}")";
2587 if obj _MAN_PATH is_empty
2589 manpath_set_from_path
;
2591 _MAN_PATH
="$(path_clean "${_MAN_PATH}")";
2593 if obj _MAN_PATH is_empty
2595 if is_prog
'manpath'
2597 _MAN_PATH
="$(manpath 2>${_NULL_DEV})"; # not always available
2600 if obj _MAN_PATH is_empty
2603 eval "${return_ok}";
2606 _MAN_ALL
="$(get_first_essential "${_OPT_ALL}" "${_MANOPT_ALL}")";
2607 if obj _MAN_ALL is_empty
2612 _MAN_SYS
="$(get_first_essential \
2613 "${_OPT_SYSTEMS}" "${_MANOPT_SYS}" "${SYSTEM}")";
2614 ms_lang
="$(get_first_essential \
2615 "${_OPT_LANG}" "${LC_ALL}" "${LC_MESSAGES}" "${LANG}")";
2616 case "${ms_lang}" in
2622 _MAN_LANG
="${ms_lang}";
2626 _MAN_LANG
="${ms_lang}";
2627 # get first two characters of $ms_lang
2628 _MAN_LANG2
="$(echo1 "${ms_lang}" | sed -e 's/^\(..\).*$/\1/')";
2631 # from now on, use only $_LANG, forget about $_OPT_LANG, $LC_*.
2633 manpath_add_lang_sys
; # this is very slow
2635 _MAN_SEC
="$(get_first_essential \
2636 "${_OPT_SECT}" "${_MANOPT_SEC}" "${MANSEC}")";
2637 if obj _MAN_PATH is_empty
2640 eval ${_UNSET} ms_lang
;
2641 eval "${return_ok}";
2644 _MAN_EXT
="$(get_first_essential \
2645 "${_OPT_EXTENSION}" "${_MANOPT_EXTENSION}")";
2646 eval ${_UNSET} ms_lang
;
2647 eval "${return_ok}";
2651 ########################################################################
2652 landmark
'8: manpath_*()';
2653 ########################################################################
2655 ########################################################################
2656 # manpath_add_lang_sys ()
2658 # Add language and operating system specific directories to man path.
2663 # in: $_MAN_SYS: has the form `os1,os2,...', a comma separated
2664 # list of names of operating systems.
2665 # $_MAN_LANG and $_MAN_LANG2: each a single name
2666 # in/out: $_MAN_PATH: has the form `dir1:dir2:...', a colon
2667 # separated list of directories.
2669 # Variable prefix: mals
2671 manpath_add_lang_sys
()
2673 func_check manpath_add_lang_sys
= 0 "$@";
2674 if obj _MAN_PATH is_empty
2676 eval "${return_ok}";
2678 # twice test both sys and lang
2679 eval set x
"$(path_split "${_MAN_PATH}")";
2683 do # loop on man path directories
2684 mals_mp
="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
2686 eval set x
"$(path_split "${mals_mp}")";
2689 do # loop on man path directories
2690 mals_mp
="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
2692 _MAN_PATH
="$(path_chop "${mals_mp}")";
2693 eval ${_UNSET} mals_mp
;
2694 eval "${return_ok}";
2698 # To the directory in $1 append existing sys/lang subdirectories
2699 # Function is necessary to split the OS list.
2701 # globals: in: $_MAN_SYS, $_MAN_LANG, $_MAN_LANG2
2702 # argument: 2: `man_path' and `dir'
2703 # output: colon-separated path of the retrieved subdirectories
2705 # Variable prefix: _mals
2707 _manpath_add_lang_sys_single
()
2709 func_check _manpath_add_lang_sys_single
= 2 "$@";
2712 eval set x
"$(list_from_split "${_MAN_SYS}" ',')";
2714 for d
in "$@" "${_MAN_LANG}" "${_MAN_LANG2}"
2716 _mals_dir
="$(dirname_append "${_mals_parent}" "$d")";
2717 if obj _mals_res path_not_contains
"${_mals_dir}" && \
2718 obj _mals_dir is_dir
2720 _mals_res
="${_mals_res}:${_mals_dir}";
2723 if path_not_contains
"${_mals_res}" "${_mals_parent}"
2725 _mals_res
="${_mals_res}:${_mals_parent}";
2727 path_chop
"${_mals_res}";
2728 eval ${_UNSET} _mals_dir
;
2729 eval ${_UNSET} _mals_parent
;
2730 eval ${_UNSET} _mals_res
;
2731 eval "${return_ok}";
2734 # end manpath_add_lang_sys ()
2737 ########################################################################
2738 # manpath_set_from_path ()
2740 # Determine basic search path for man pages from $PATH.
2742 # Return: `0' if a valid man path was retrieved.
2748 # Variable prefix: msfp
2750 manpath_set_from_path
()
2752 func_check manpath_set_from_path
= 0 "$@";
2756 # get a basic man path from $PATH
2757 if obj PATH is_not_empty
2759 eval set x
"$(path_split "${PATH}")";
2763 # delete the final `/bin' part
2764 msfp_base
="$(echo1 "$d" | sed -e 's|//*bin/*$||')";
2765 for e
in /share
/man
/man
2767 msfp_mandir
="${msfp_base}$e";
2768 if test -d "${msfp_mandir}" && test -r "${msfp_mandir}"
2770 msfp_manpath
="${msfp_manpath}:${msfp_mandir}";
2776 # append some default directories
2777 for d
in /usr
/local
/share
/man
/usr
/local
/man \
2778 /usr
/share
/man
/usr
/man \
2779 /usr
/X11R
6/man
/usr
/openwin
/man \
2780 /opt
/share
/man
/opt
/man \
2781 /opt
/gnome
/man
/opt
/kde
/man
2784 if obj msfp_manpath path_not_contains
"${msfp_d}" && obj mfsp_d is_dir
2786 msfp_manpath
="${msfp_manpath}:${mfsp_d}";
2790 _MAN_PATH
="${msfp_manpath}";
2791 eval ${_UNSET} msfp_base
;
2792 eval ${_UNSET} msfp_d
;
2793 eval ${_UNSET} msfp_mandir
;
2794 eval ${_UNSET} msfp_manpath
;
2795 eval "${return_ok}";
2796 } # manpath_set_from_path()
2799 ########################################################################
2800 landmark
'9: obj_*()';
2801 ########################################################################
2803 ########################################################################
2804 # obj (<object> <call_name> <arg>...)
2806 # This works like a method (object function) call for an object.
2807 # Run "<call_name> $<object> <arg> ...".
2809 # The first argument represents an object whose data is given as first
2810 # argument to <call_name>().
2813 # <object>: variable name
2814 # <call_name>: a program or function name
2816 # Variable prefix: o
2820 func_check obj
'>=' 2 "$@";
2823 error
"obj(): function name is empty."
2827 eval o_arg1
='"${'$1'}"';
2830 eval "${o_func}"' "${o_arg1}" "$@"';
2832 eval ${_UNSET} o_arg1
;
2833 eval ${_UNSET} o_func
;
2834 eval "${return_var} $n";
2838 ########################################################################
2839 # obj_data (<object>)
2841 # Print the data of <object>, i.e. the content of $<object>.
2842 # For possible later extensions.
2845 # <object>: a variable name
2846 # Output: the data of <object>
2848 # Variable prefix: od
2852 func_check obj
'=' 1 "$@";
2855 error
"obj_data(): object name is empty."
2857 eval od_res
='"${'$1'}"';
2859 eval ${_UNSET} od_res
;
2860 eval "${return_ok}";
2864 ########################################################################
2865 # obj_from_output (<object> <call_name> <arg>...)
2867 # Run '$<object>="$(<call_name> <arg>...)"' to set the result of a
2868 # function call to a global variable.
2871 # <object>: a variable name
2872 # <call_name>: the name of a function or program
2873 # <arg>: optional argument to <call_name>
2876 # Variable prefix: ofo
2880 func_check obj_from_output
'>=' 2 "$@";
2883 error
"res(): variable name is empty.";
2886 error
"res(): function name is empty."
2888 ofo_result_name
="$1";
2891 eval "${ofo_result_name}"'="$('"$@"')"';
2892 eval "${return_ok}";
2896 ########################################################################
2897 # obj_set (<object> <data>)
2899 # Set the data of <object>, i.e. call "$<object>=<data>".
2902 # <object>: a variable name
2908 func_check obj_set
'=' 2 "$@";
2911 error
"obj_set(): object name is empty."
2914 eval "${return_ok}";
2918 ########################################################################
2919 # path_chop (<path>)
2921 # Remove unnecessary colons from path.
2923 # Argument: 1, a colon separated path.
2924 # Output: path without leading, double, or trailing colons.
2928 func_check path_chop
= 1 "$@";
2930 # replace multiple colons by a single colon `:'
2931 # remove leading and trailing colons
2932 echo1
"$1" |
sed -e '
2937 eval "${return_ok}";
2941 ########################################################################
2942 # path_clean (<path>)
2944 # Remove non-existing directories from a colon-separated list.
2946 # Argument: 1, a colon separated path.
2947 # Output: colon-separated list of existing directories.
2949 # Variable prefix: pc
2953 func_check path_clean
= 1 "$@";
2954 if is_not_equal
"$#" 1
2956 error
'path_clean() needs 1 argument.';
2959 eval set x
"$(path_split "${pc_arg}")";
2965 if obj pc_i is_not_empty \
2966 && obj pc_res path_not_contains
"${pc_i}" \
2970 ?
*/) pc_res
="${pc_res}$(dirname_chop "${pc_i}")"; ;;
2971 *) pc_res
="${pc_res}:${pc_i}";
2975 eval ${_UNSET} pc_arg
;
2976 eval ${_UNSET} pc_i
;
2977 eval ${_UNSET} pc_res
;
2978 if path_chop
"${pc_res}"
2980 eval "${return_ok}";
2982 eval "${return_bad}";
2987 ########################################################################
2988 # path_contains (<path> <dir>)
2990 # Test whether `dir' is contained in `path', a list separated by `:'.
2992 # Arguments : 2 arguments.
2993 # Return : `0' if arg2 is substring of arg1, `1' otherwise.
2997 func_check path_contains
= 2 "$@";
3000 eval "${return_yes}";
3003 eval "${return_no}";
3006 eval "${return_ok}";
3010 ########################################################################
3011 # path_not_contains (<path> <dir>)
3013 # Test whether `dir' is not contained in colon separated `path'.
3015 # Arguments : 2 arguments.
3019 func_check path_not_contains
= 2 "$@";
3020 if path_contains
"$1" "$2"
3022 eval "${return_no}";
3024 eval "${return_yes}";
3026 eval "${return_ok}";
3030 ########################################################################
3031 # path_split (<path>)
3033 # In `path' escape white space and replace each colon by a space.
3035 # Arguments: 1: a colon-separated path
3036 # Output: the resulting list, process with `eval set'
3040 func_check path_split
= 1 "$@";
3041 list_from_split
"$1" ':';
3042 eval "${return_ok}";
3046 ########################################################################
3047 landmark
'10: register_*()';
3048 ########################################################################
3050 ########################################################################
3051 # register_file (<filename>)
3053 # Write a found file and register the title element.
3055 # Arguments: 1: a file name
3060 func_check register_file
= 1 "$@";
3063 error
'register_file(): file name is empty';
3065 if is_equal
"$1" '-'
3067 to_tmp
"${_TMP_STDIN}";
3068 register_title
'stdin';
3071 register_title
"$(base_name "$1")";
3073 eval "${return_ok}";
3077 ########################################################################
3078 # register_title (<filespec>)
3080 # Create title element from <filespec> and append to $_REGISTERED_TITLE
3082 # Globals: $_REGISTERED_TITLE (rw)
3084 # Variable prefix: rt
3088 func_check register_title
'=' 1 "$@";
3091 eval "${return_ok}";
3093 rt_title
="$(base_name "$1")"; # remove directory part
3095 # replace space characters by `_'
3096 rt_title
="$(echo1 "${rt_title}" | sed -e 's/[ ]/_/g')";
3097 # remove extension `.gz'
3098 rt_title
="$(echo1 "${rt_title}" | sed -e 's/\.gz$//')";
3099 # remove extension `.Z'
3100 rt_title
="$(echo1 "${rt_title}" | sed -e 's/\.Z$//')";
3102 if obj rt_title is_empty
3104 eval "${return_ok}";
3106 _REGISTERED_TITLE
="${_REGISTERED_TITLE} ${rt_title}";
3107 eval ${_UNSET} rt_title
;
3108 eval "${return_ok}";
3112 ########################################################################
3115 # Reset the variables that can be affected by options to their default.
3118 # Defined in section `Preset' after the rudimentary shell tests.
3121 ########################################################################
3122 # rm_file (<file_name>)
3124 # Remove file if $_DEBUG_KEEP_FILES allows it.
3126 # Globals: $_DEBUG_KEEP_FILES
3130 func_check rm_file
'=' 1 "$@";
3133 rm -f "$1" >${_NULL_DEV} 2>&1;
3137 eval "${return_bad}";
3139 eval "${return_good}";
3144 ########################################################################
3145 # rm_file_with_debug (<file_name>)
3147 # Remove file if $_DEBUG_KEEP_FILES allows it.
3149 # Globals: $_DEBUG_KEEP_FILES
3151 rm_file_with_debug
()
3153 func_check rm_file_with_debug
'=' 1 "$@";
3154 if obj _DEBUG_KEEP_FILES is_not_yes
3158 rm -f "$1" >${_NULL_DEV} 2>&1;
3163 eval "${return_bad}";
3165 eval "${return_good}";
3170 ########################################################################
3171 # rm_tree (<dir_name>)
3173 # Remove file if $_DEBUG_KEEP_FILES allows it.
3175 # Globals: $_DEBUG_KEEP_FILES
3179 func_check rm_tree
'=' 1 "$@";
3182 rm -f -r "$1" >${_NULL_DEV} 2>&1;
3186 eval "${return_bad}";
3188 eval "${return_good}";
3193 ########################################################################
3196 # Store standard input to temporary file (with decompression).
3198 # Variable prefix: ss
3200 if obj _HAS_COMPRESSION is_yes
3204 func_check save_stdin
'=' 0 "$@";
3205 ss_f
="${_TMP_DIR}"/INPUT
;
3207 cat_z
"${ss_f}" >"${_TMP_STDIN}";
3209 eval ${_UNSET} ss_f
;
3210 eval "${return_ok}";
3215 func_check save_stdin
= 0 "$@";
3216 cat >"${_TMP_STDIN}";
3217 eval "${return_ok}";
3222 ########################################################################
3223 landmark
'11: stack_*()';
3224 ########################################################################
3226 ########################################################################
3227 # string_contains (<string> <part>)
3229 # Test whether `part' is contained in `string'.
3231 # Arguments : 2 text arguments.
3232 # Return : `0' if arg2 is substring of arg1, `1' otherwise.
3236 func_check string_contains
'=' 2 "$@";
3239 eval "${return_yes}";
3242 eval "${return_no}";
3245 eval "${return_ok}";
3249 ########################################################################
3250 # string_not_contains (<string> <part>)
3252 # Test whether `part' is not substring of `string'.
3254 # Arguments : 2 text arguments.
3255 # Return : `0' if arg2 is substring of arg1, `1' otherwise.
3257 string_not_contains
()
3259 func_check string_not_contains
'=' 2 "$@";
3260 if string_contains
"$1" "$2"
3262 eval "${return_no}";
3264 eval "${return_yes}";
3266 eval "${return_ok}";
3270 ########################################################################
3271 landmark
'12: tmp_*()';
3272 ########################################################################
3274 ########################################################################
3277 # output the temporary cat file (the concatenation of all input)
3281 func_check tmp_cat
'=' 0 "$@";
3283 eval "${return_var}" "$?";
3287 ########################################################################
3288 # tmp_create (<suffix>?)
3290 # Create temporary file.
3292 # It's safe to use the shell process ID together with a suffix to
3293 # have multiple temporary files.
3295 # Globals: $_TMP_DIR
3297 # Output : name of created file
3299 # Variable prefix: tc
3303 func_check tmp_create
'<=' 1 "$@";
3304 # the output file does not have `,' as first character, so these are
3305 # different names from the output file.
3306 tc_tmp
="${_TMP_DIR}/,$1";
3309 eval ${_UNSET} tc_tmp
;
3310 eval "${return_ok}";
3314 ########################################################################
3315 # to_tmp (<filename>)
3317 # print file (decompressed) to the temporary cat file
3321 func_check to_tmp
= 1 "$@";
3324 if obj _OPT_LOCATION is_yes
3328 if obj _OPT_WHATIS is_yes
3330 what_is
"$1" >>"${_TMP_CAT}";
3332 cat_z
"$1" >>"${_TMP_CAT}";
3335 error
"to_tmp(): could not read file \`$1'.";
3337 eval "${return_ok}";
3341 ########################################################################
3344 # disable trap on all exit codes ($_ALL_EXIT)
3347 # Globals: $_ALL_EXIT
3351 func_check trap_clean
= 0 "$@";
3352 # for i in $_ALL_EXIT
3353 for i
in $
(eval set x
"${_ALL_EXIT}"; shift; echo "$@")
3355 trap "" "$i" 2>${_NULL_DEV} ||
:;
3357 eval "${return_ok}";
3361 ########################################################################
3362 # trap_set (<functionname>)
3364 # call function on all exit codes ($_ALL_EXIT)
3366 # Arguments: 1 (name of a shell function)
3367 # Globals: $_ALL_EXIT
3371 func_check trap_set
= 1 "$@";
3372 # for i in $_ALL_EXIT
3373 for i
in $
(eval set x
"${_ALL_EXIT}"; shift; echo "$@")
3375 trap "$1" "$i" 2>${_NULL_DEV} ||
:;
3377 eval "${return_ok}";
3381 ########################################################################
3384 # print usage information to stderr; for groffer option --help.
3388 func_check usage
= 0 "$@";
3391 echo 'Usage: groffer [option]... [filespec]...';
3394 Display roff files, standard input, and/or Unix manual pages with a X
3395 Window viewer or in several text modes. All input is decompressed
3396 on-the-fly with all formats that gzip can handle.
3398 "filespec" is one of
3399 "filename" name of a readable file
3400 "-" for standard input
3401 "man:name.n" man page "name" in section "n"
3402 "man:name" man page "name" in first section found
3403 "name.n" man page "name" in section "n"
3404 "name" man page "name" in first section found
3405 and some more (see groffer(1) for details).
3407 -h --help print this usage message.
3408 -Q --source output as roff source.
3409 -T --device=name pass to groff using output device "name".
3410 -v --version print version information.
3411 -V display the groff execution pipe instead of formatting.
3412 -X display with "gxditview" using groff -X.
3413 -Z --ditroff --intermediate-output
3414 generate groff intermediate output without
3415 post-processing and viewing, like groff -Z.
3416 All other short options are interpreted as "groff" formatting options.
3418 The most important groffer long options are
3420 --apropos=name start man's "apropos" program for "name".
3422 "apropos" for "name" in man's data sections 4, 5, 7.
3423 --apropos-devel=name
3424 "apropos" for "name" in development sections 2, 3, 9.
3425 --apropos-progs=name
3426 "apropos" for "name" in man's program sections 1, 6, 8.
3427 --auto choose mode automatically from the default mode list.
3428 --default reset all options to the default value.
3429 --default-modes=mode1,mode2,...
3430 set sequence of automatically tried modes.
3431 --dvi display in a viewer for TeX device independent format.
3432 --dvi-viewer=prog choose the viewer program for dvi mode.
3433 --groff process like groff, disable viewing features.
3434 --help display this helping output.
3435 --html display in a web browser.
3436 --html-viewer=program
3437 choose the web browser for html mode.
3438 --man check file parameters first whether they are man pages.
3439 --mode=auto|dvi|groff|html|pdf|ps|source|text|tty|www|x|X
3440 choose display mode.
3441 --no-man disable man-page facility.
3442 --pager=program preset the paging program for tty mode.
3443 --pdf display in a PDF viewer.
3444 --pdf-viewer=prog choose the viewer program for pdf mode.
3445 --ps display in a Postscript viewer.
3446 --ps-viewer=prog choose the viewer program for ps mode.
3447 --shell=program specify shell under which to run groffer2.sh.
3448 --text output in a text device without a pager.
3449 --tty display with a pager on text terminal even when in X.
3450 --tty-viewer=prog select a pager for tty mode; same as --pager.
3451 --www same as --html.
3452 --www-viewer=prog same as --html-viewer
3453 --x --X display with "gxditview" using an X* device.
3454 --x-viewer=prog choose viewer program for x mode (X mode).
3455 --X-viewer=prog same as "--xviewer".
3457 The usual X Windows toolkit options transformed into GNU long options
3458 --background=color, --bd=size, --bg=color, --bordercolor=color,
3459 --borderwidth=size, --bw=size, --display=Xdisplay, --fg=color,
3460 --fn=font, --font=font, --foreground=color, --geometry=geom, --iconic,
3461 --resolution=dpi, --rv, --title=text, --xrm=resource
3463 Long options of GNU "man"
3464 --all, --ascii, --ditroff, --extension=suffix, --locale=language,
3465 --local-file=name, --location, --manpath=dir1:dir2:...,
3466 --sections=s1:s2:..., --systems=s1,s2,..., --whatis, --where, ...
3469 eval "${return_ok}";
3473 ########################################################################
3476 # print version information to stderr
3480 func_check version
= 0 "$@";
3481 echo2
"groffer ${_PROGRAM_VERSION} of ${_LAST_UPDATE}";
3482 # also display groff's version, but not the called subprograms
3483 groff -v 2>&1 |
sed -e '/^ *$/q' |
sed -e '1s/^/is part of /' >&2;
3484 eval "${return_ok}";
3488 ########################################################################
3489 # warning (<string>)
3491 # Print warning to stderr
3495 echo2
"warning: $*";
3499 ########################################################################
3500 # what_is (<filename>)
3502 # Interpret <filename> as a man page and display its `whatis'
3503 # information as a fragment written in the groff language.
3505 # Variable prefix: wi
3509 func_check what_is
= 1 "$@";
3512 error
"what_is(): argument is not a readable file."
3514 wi_dot
='^\.['"${_SP}${_TAB}"']*';
3520 # grep the line containing `.TH' macro, if any
3521 wi_res
="$(cat_z "$1" | sed -e '/'"${wi_dot}"'TH /p
3523 if obj wi_res is_not_empty
3524 then # traditional man style
3525 # get the text between the first and the second `.SH' macro, by
3526 # - delete up to first .SH;
3527 # - of this, print everything up to next .SH, and delete the rest;
3528 # - of this, delete the final .SH line;
3529 cat_z
"$1" |
sed -e '1,/'"${wi_dot}"'SH/d' \
3530 |
sed -e '1,/'"${wi_dot}"'SH/p
3532 |
sed -e '/'"${wi_dot}"'SH/d';
3533 eval ${_UNSET} wi_dot
;
3534 eval ${_UNSET} wi_res
;
3535 eval "${return_ok}";
3537 # grep the line containing `.Dd' macro, if any
3538 wi_res
="$(cat_z "$1" | sed -e '/'"${wi_dot}"'Dd /p
3540 if obj wi_res is_not_empty
3541 then # BSD doc style
3542 # get the text between the first and the second `.Nd' macro, by
3543 # - delete up to first .Nd;
3544 # - of this, print everything up to next .Nd, and delete the rest;
3545 # - of this, delete the final .Nd line;
3546 cat_z
"$1" |
sed -e '1,/'"${wi_dot}"'Nd/d' \
3547 |
sed -e '1,/'"${wi_dot}"'Nd/p
3549 |
sed -e '/'"${wi_dot}"'Nd/d';
3550 eval ${_UNSET} wi_dot
;
3551 eval ${_UNSET} wi_res
;
3552 eval "${return_ok}";
3554 echo 'is not a man page.';
3555 eval ${_UNSET} wi_dot
;
3556 eval ${_UNSET} wi_res
;
3557 eval "${return_bad}";
3561 ########################################################################
3562 # where_is (<program>)
3564 # Output path of a program if in $PATH.
3566 # Arguments : >=1 (empty allowed)
3567 # more args are ignored, this allows to specify progs with arguments
3568 # Return : `0' if arg1 is a program in $PATH, `1' otherwise.
3570 # Variable prefix: w
3574 func_check where_is
'>=' 1 "$@";
3576 if obj w_arg is_empty
3578 eval ${_UNSET} w_arg
;
3579 eval "${return_bad}";
3583 eval ${_UNSET} w_arg
;
3584 eval ${_UNSET} w_file
;
3585 if test -f "${w_arg}" && test -x "${w_arg}"
3587 eval "${return_ok}";
3589 eval "${return_bad}";
3593 eval set x
"$(path_split "${PATH}")";
3598 */) w_file
=${p}${w_arg}; ;;
3599 *) w_file
=${p}/${w_arg}; ;;
3601 if test -f "${w_file}" && test -x "${w_file}"
3604 eval ${_UNSET} w_arg
;
3605 eval ${_UNSET} w_file
;
3606 eval "${return_ok}";
3609 eval ${_UNSET} w_arg
;
3610 eval ${_UNSET} w_file
;
3611 eval "${return_bad}";
3615 ########################################################################
3617 ########################################################################
3619 # The main area contains the following parts:
3620 # - main_init(): initialize temporary files and set exit trap
3621 # - main_parse_MANOPT(): parse $MANOPT
3622 # - main_parse_args(): argument parsing
3623 # - main_set_mode (): determine the display mode
3624 # - main_do_fileargs(): process filespec arguments
3625 # - main_set_resources(): setup X resources
3626 # - main_display(): do the displaying
3627 # - main(): the main function that calls all main_*()
3629 # These parts are implemented as functions, being defined below in the
3630 # sequence they are called in the main() function.
3633 #######################################################################
3636 # set exit trap and create temporary files
3638 # Globals: $_TMP_DIR, $_TMP_CAT, $_TMP_STDIN
3640 # Variable prefix: mi
3644 func_check main_init
= 0 "$@";
3645 # call clean_up() on any signal
3648 # create temporary directory
3651 for d
in "${GROFF_TMPDIR}" "${TMPDIR}" "${TMP}" "${TEMP}" \
3652 "${TEMPDIR}" "${HOME}"'/tmp' '/tmp' "${HOME}" '.'
3655 if obj mi_dir is_empty || obj mi_dir is_not_dir || \
3656 obj mi_dir is_not_writable
3663 _TMP_DIR
="${mi_dir}";
3666 _TMP_DIR
="${mi_dir}"'/';
3669 _TMP_DIR
="${_TMP_DIR}groffer${_PROCESS_ID}";
3670 if obj _TMP_DIR rm_tree
3674 mi_tdir_
="${_TMP_DIR}"_
;
3676 mi_tdir_n
="${mi_tdir_}${mi_n}";
3677 while obj mi_tdir_n is_existing
3679 if obj mi_tdir_n rm_tree
3681 # directory could not be removed
3682 mi_n
="$(expr "${mi_n}" + 1)";
3683 mi_tdir_n
="${mi_tdir_}${mi_n}";
3687 _TMP_DIR
="${mi_tdir_n}";
3689 eval mkdir
"${_TMP_DIR}";
3690 if is_not_equal
"$?" 0
3692 obj _TMP_DIR rm_tree
;
3696 if obj _TMP_DIR is_dir
&& obj _TMP_DIR is_writable
3698 # $_TMP_DIR can now be used as temporary directory
3701 obj _TMP_DIR rm_tree
;
3705 if obj _TMP_DIR is_empty
3708 Couldn't create a directory for storing temporary files.";
3711 _TMP_CAT
="$(tmp_create groffer_cat)";
3712 _TMP_STDIN
="$(tmp_create groffer_input)";
3714 eval ${_UNSET} mi_dir
;
3715 eval ${_UNSET} mi_n
;
3716 eval ${_UNSET} mi_tdir_
;
3717 eval ${_UNSET} mi_tdir_n
;
3718 eval "${return_ok}";
3722 ########################################################################
3723 # main_parse_MANOPT ()
3725 # Parse $MANOPT to retrieve man options, but only if it is a non-empty
3726 # string; found man arguments can be overwritten by the command line.
3729 # in: $MANOPT, $_OPTS_MANOPT_*
3731 # in/out: $GROFFER_OPT
3733 # Variable prefix: mpm
3737 func_check main_parse_MANOPT
= 0 "$@";
3739 if obj MANOPT is_not_empty
3741 # Delete leading and final spaces
3742 MANOPT
="$(echo1 "${MANOPT}" | sed -e '
3743 s/^['"${_SP}${_TAB}"']*//
3744 s/['"${_SP}${_TAB}"']*$//
3747 if obj MANOPT is_empty
3749 eval "${return_ok}";
3753 # add arguments in $MANOPT by mapping them to groffer options
3754 eval set x
"$(list_from_cmdline _OPTS_MANOPT "${MANOPT}")";
3756 until test "$#" -le 0 || is_equal
"$1" '--'
3760 case "${mpm_opt}" in
3762 list_append mpm_list
'--ascii';
3765 list_append mpm_list
'--all';
3775 # undo all man options so far
3779 list_append mpm_list
'--extension';
3783 list_append mpm_list
'--whatis';
3791 # groffer's --apropos takes an argument, but man's does not, so
3798 list_append mpm_list
'--locale' "$1";
3802 list_append mpm_list
'--systems' "$1";
3806 list_append mpm_list
'--manpath' "$1";
3814 list_append mpm_list
'--pager' "$1";
3822 list_append mpm_list
'--sections' "$1";
3830 list_append mpm_list
'-T' "$1";
3840 -w|
--where|
--location)
3841 list_append mpm_list
'--location';
3846 # ignore all other options
3850 # prepend $mpm_list to $GROFFER_OPT
3851 if obj GROFFER_OPT is_empty
3853 GROFFER_OPT
="${mpm_list}";
3854 elif obj mpm_list is_not_empty
3856 GROFFER_OPT
="${mpm_list} ${GROFFER_OPT}";
3859 eval ${_UNSET} mpm_list
;
3860 eval ${_UNSET} mpm_opt
;
3861 eval "${return_ok}";
3862 } # main_parse_MANOPT()
3865 ########################################################################
3866 # main_parse_args (<command_line_args>*)
3868 # Parse arguments; process options and filespec parameters
3870 # Arguments: pass the command line arguments unaltered.
3873 # out: $_OPT_*, $_ADDOPTS, $_FILEARGS
3875 # Variable prefix: mpa
3879 func_check main_parse_args
'>=' 0 "$@";
3880 eval set x
"${GROFFER_OPT}" '"$@"';
3883 _ALL_PARAMS
="$(list_from_cmdline _OPTS_CMDLINE "$@
")";
3884 if obj _DEBUG_PRINT_PARAMS is_yes
3886 echo2
"parameters: ${_ALL_PARAMS}";
3888 eval set x
"${_ALL_PARAMS}";
3891 # By the call of `eval', unnecessary quoting was removed. So the
3892 # positional shell parameters ($1, $2, ...) are now guaranteed to
3893 # represent an option or an argument to the previous option, if any;
3894 # then a `--' argument for separating options and
3895 # parameters; followed by the filespec parameters if any.
3897 # Note, the existence of arguments to options has already been checked.
3898 # So a check for `$#' or `--' should not be done for arguments.
3900 until test "$#" -le 0 || is_equal
"$1" '--'
3902 mpa_opt
="$1"; # $mpa_opt is fed into the option handler
3904 case "${mpa_opt}" in
3909 -Q|
--source) # output source code (`Quellcode').
3912 -T|
--device|
--troff-device) # device; arg
3914 _check_device_with_mode
;
3924 -Z|
--ditroff|
--intermediate-output) # groff intermediate output
3931 # delete leading `-'
3932 mpa_optchar
="$(echo1 "${mpa_opt}" | sed -e 's/^-//')";
3933 if list_has _OPTS_GROFF_SHORT_NA
"${mpa_optchar}"
3935 list_append _ADDOPTS_GROFF
"${mpa_opt}";
3936 elif list_has _OPTS_GROFF_SHORT_ARG
"${mpa_optchar}"
3938 list_append _ADDOPTS_GROFF
"${mpa_opt}" "$1";
3941 error
"main_parse_args(): Unknown option : \`$1'";
3947 --apropos) # run `apropos'
3951 --apropos-data) # run `apropos' for data sections
3952 apropos_run
"$1" |
grep '^[^(]*([457][^)]*)';
3955 --apropos-devel) # run `apropos' for development sections
3956 apropos_run
"$1" |
grep '^[^(]*([239][^)]*)';
3959 --apropos-progs) # run `apropos' for program sections
3960 apropos_run
"$1" |
grep '^[^(]*([168][^)]*)';
3964 list_append _ADDOPTS_GROFF
'-mtty-char';
3965 if obj _OPT_MODE is_empty
3970 --auto) # the default automatic mode
3973 --bd) # border color for viewers, arg;
3977 --bg|
--backgroud) # background color for viewers, arg;
3981 --bw) # border width for viewers, arg;
3985 --default) # reset variables to default
3988 --default-modes) # sequence of modes in auto mode; arg
3989 _OPT_DEFAULT_MODES
="$1";
3992 --debug) # only for development
3995 --display) # set X display, arg
4005 --dvi-viewer) # viewer program for dvi mode; arg
4006 _OPT_VIEWER_DVI
="$1";
4009 --extension) # the extension for man pages, arg
4010 _OPT_EXTENSION
="$1";
4013 --fg|
--foreground) # foreground color for viewers, arg;
4017 --fn|
--font) # set font for viewers, arg;
4021 --geometry) # window geometry for viewers, arg;
4028 --html|
--www) # display with web browser
4031 --html-viewer|
--www-viewer) # viewer program for html mode; arg
4032 _OPT_VIEWER_HTML
="$1";
4035 --iconic) # start viewers as icons
4038 --locale) # set language for man pages, arg
4039 # argument is xx[_territory[.codeset[@modifier]]] (ISO 639,...)
4043 --local-file) # force local files; same as `--no-man'
4047 --location|
--where) # print file locations to stderr
4048 _OPT_LOCATION
='yes';
4050 --man) # force all file params to be man pages
4054 --manpath) # specify search path for man pages, arg
4055 # arg is colon-separated list of directories
4059 --mode) # display mode
4062 case "${mpa_arg}" in
4063 auto|
'') # search mode automatically among default
4066 groff) # pass input to plain groff
4069 html|www
) # display with a web browser
4072 dvi
) # display with xdvi viewer
4075 pdf
) # display with PDF viewer
4078 ps
) # display with Postscript viewer
4081 text
) # output on terminal
4084 tty
) # output on terminal
4087 X|x
) # output on X roff viewer
4090 Q|
source) # display source code
4094 error
"main_parse_args(): unknown mode ${mpa_arg}";
4098 --no-location) # disable former call to `--location'
4099 _OPT_LOCATION
='yes';
4101 --no-man) # disable search for man pages
4102 # the same as --local-file
4106 --pager|
--tty-viewer) # set paging program for tty mode, arg
4113 --pdf-viewer) # viewer program for ps mode; arg
4114 _OPT_VIEWER_PDF
="$1";
4120 --ps-viewer) # viewer program for ps mode; arg
4121 _OPT_VIEWER_PS
="$1";
4124 --resolution) # set resolution for X devices, arg
4127 case "${mpa_arg}" in
4135 error
"main_parse_args(): \
4136 only resoutions of 75 or 100 dpi are supported";
4139 _OPT_RESOLUTION
="${mpa_dpi}";
4144 --sections) # specify sections for man pages, arg
4145 # arg is colon-separated list of section names
4150 # already done during the first run; so ignore the argument
4153 --systems) # man pages for different OS's, arg
4154 # argument is a comma-separated list
4158 --text) # text mode without pager
4161 --title) # title for X viewers; arg
4165 --tty) # tty mode, text with pager
4168 --text-device|
--tty-device) # device for tty mode; arg
4169 _OPT_TEXT_DEVICE
="$1";
4178 --xrm) # pass X resource string, arg;
4179 list_append _OPT_XRM
"$1";
4182 --x-viewer|
--X-viewer) # viewer program for x mode; arg
4187 error
'main_parse_args(): error on argument parsing : '"\`$*'";
4191 shift; # remove `--' argument
4192 if obj _DEBUG is_not_yes
4194 if obj _OPT_DEBUG is_yes
4198 _DEBUG_KEEP_FILES
='yes';
4199 _DEBUG_PRINT_PARAMS
='yes';
4200 _DEBUG_PRINT_SHELL
='yes';
4204 # Remaining arguments are file names (filespecs).
4205 # Save them to list $_FILEARGS
4207 then # use "-" for standard input
4212 list_append _FILEARGS
"$@";
4213 if list_has _FILEARGS
'-'
4217 # $_FILEARGS must be retrieved with `eval set x "$_FILEARGS"; shift;'
4218 eval ${_UNSET} mpa_arg
;
4219 eval ${_UNSET} mpa_dpi
;
4220 eval ${_UNSET} mpa_opt
;
4221 eval ${_UNSET} mpa_optchar
;
4222 eval "${return_ok}";
4223 } # main_parse_args()
4226 # Called from main_parse_args() because double `case' is not possible.
4227 # Globals: $_OPT_DEVICE, $_OPT_MODE
4228 _check_device_with_mode
()
4230 func_check _check_device_with_mode
= 0 "$@";
4231 case "${_OPT_DEVICE}" in
4234 eval "${return_ok}";
4238 eval "${return_ok}";
4242 eval "${return_ok}";
4246 eval "${return_ok}";
4248 ascii|cp1047|latin1|utf8
)
4249 if obj _OPT_MODE is_not_equal text
4251 _OPT_MODE
=tty
; # default text mode
4253 eval "${return_ok}";
4257 eval "${return_ok}";
4259 *) # unknown device, go to groff mode
4261 eval "${return_ok}";
4264 eval "${return_error}";
4265 } # _check_device_with_mode() of main_parse_args()
4268 ########################################################################
4271 # Determine the display mode.
4274 # in: $DISPLAY, $_OPT_MODE, $_OPT_DEVICE
4275 # out: $_DISPLAY_MODE
4277 # Variable prefix: msm
4281 func_check main_set_mode
= 0 "$@";
4284 if obj _OPT_APROPOS is_not_empty
4286 apropos
"${_OPT_APROPOS}";
4289 if obj _OPT_APROPOS_DATA is_not_empty
4291 apropos
"$@" |
grep '^[^(]*([457])';
4294 if obj _OPT_APROPOS_DEVEL is_not_empty
4296 apropos
"$@" |
grep '^[^(]*([239])';
4299 if obj _OPT_APROPOS_PROGS is_not_empty
4301 apropos
"$@" |
grep '^[^(]*([168])';
4306 if obj _OPT_DISPLAY is_not_empty
4308 DISPLAY
="${_OPT_DISPLAY}";
4311 if obj _OPT_V is_yes
4313 list_append _ADDOPTS_GROFF
'-V';
4315 if obj _OPT_Z is_yes
4317 _DISPLAY_MODE
='groff';
4318 list_append _ADDOPTS_GROFF
'-Z';
4320 if obj _OPT_MODE is_equal
'groff'
4322 _DISPLAY_MODE
='groff';
4324 if obj _DISPLAY_MODE is_equal
'groff'
4326 eval ${_UNSET} msm_modes
;
4327 eval ${_UNSET} msm_viewer
;
4328 eval ${_UNSET} msm_viewers
;
4329 eval "${return_ok}";
4332 if obj _OPT_MODE is_equal
'source'
4334 _DISPLAY_MODE
='source';
4335 eval ${_UNSET} msm_modes
;
4336 eval ${_UNSET} msm_viewer
;
4337 eval ${_UNSET} msm_viewers
;
4338 eval "${return_ok}";
4341 case "${_OPT_MODE}" in
4342 '') # automatic mode
4343 case "${_OPT_DEVICE}" in
4345 if obj DISPLAY is_empty
4347 error
"main_set_mode(): \
4348 no X display found for device ${_OPT_DEVICE}";
4351 eval ${_UNSET} msm_modes
;
4352 eval ${_UNSET} msm_viewer
;
4353 eval ${_UNSET} msm_viewers
;
4354 eval "${return_ok}";
4356 ascii|cp1047|latin1|utf8
)
4357 if obj _DISPLAY_MODE is_not_equal
'text'
4359 _DISPLAY_MODE
='tty';
4361 eval ${_UNSET} msm_modes
;
4362 eval ${_UNSET} msm_viewer
;
4363 eval ${_UNSET} msm_viewers
;
4364 eval "${return_ok}";
4367 if obj DISPLAY is_empty
4369 _DISPLAY_MODE
='tty';
4370 eval ${_UNSET} msm_modes
;
4371 eval ${_UNSET} msm_viewer
;
4372 eval ${_UNSET} msm_viewers
;
4373 eval "${return_ok}";
4376 if obj _OPT_DEFAULT_MODES is_empty
4378 msm_modes
="${_DEFAULT_MODES}";
4380 msm_modes
="${_OPT_DEFAULT_MODES}";
4384 _DISPLAY_MODE
='text';
4385 eval ${_UNSET} msm_modes
;
4386 eval ${_UNSET} msm_viewer
;
4387 eval ${_UNSET} msm_viewers
;
4388 eval "${return_ok}";
4391 _DISPLAY_MODE
='tty';
4392 eval ${_UNSET} msm_modes
;
4393 eval ${_UNSET} msm_viewer
;
4394 eval ${_UNSET} msm_viewers
;
4395 eval "${return_ok}";
4397 *) # display mode was given
4398 if obj DISPLAY is_empty
4400 error
"main_set_mode(): \
4401 you must be in X Window for ${_OPT_MODE} mode.";
4403 msm_modes
="${_OPT_MODE}";
4407 # only viewer modes are left
4408 eval set x
"$(list_from_split "${msm_modes}" ',')";
4410 while test "$#" -gt 0
4416 _DISPLAY_MODE
='text';
4417 eval ${_UNSET} msm_modes
;
4418 eval ${_UNSET} msm_viewer
;
4419 eval ${_UNSET} msm_viewers
;
4420 eval "${return_ok}";
4423 _DISPLAY_MODE
='tty';
4424 eval ${_UNSET} msm_modes
;
4425 eval ${_UNSET} msm_viewer
;
4426 eval ${_UNSET} msm_viewers
;
4427 eval "${return_ok}";
4430 if obj _OPT_VIEWER_X is_not_empty
4432 msm_viewers
="${_OPT_VIEWER_X}";
4434 msm_viewers
="${_VIEWER_X}";
4436 msm_viewer
="$(_get_first_prog "${msm_viewers}")";
4437 if is_not_equal
"$?" 0
4441 _DISPLAY_PROG
="${msm_viewer}";
4443 eval ${_UNSET} msm_modes
;
4444 eval ${_UNSET} msm_viewer
;
4445 eval ${_UNSET} msm_viewers
;
4446 eval "${return_ok}";
4450 eval ${_UNSET} msm_modes
;
4451 eval ${_UNSET} msm_viewer
;
4452 eval ${_UNSET} msm_viewers
;
4453 eval "${return_ok}";
4456 if obj _OPT_VIEWER_DVI is_not_empty
4458 msm_viewers
="${_OPT_VIEWER_DVI}";
4460 msm_viewers
="${_VIEWER_DVI}";
4462 msm_viewer
="$(_get_first_prog "${msm_viewers}")";
4463 if is_not_equal
"$?" 0
4467 _DISPLAY_PROG
="${msm_viewer}";
4468 _DISPLAY_MODE
="dvi";
4469 eval ${_UNSET} msm_modes
;
4470 eval ${_UNSET} msm_viewer
;
4471 eval ${_UNSET} msm_viewers
;
4472 eval "${return_ok}";
4475 if obj _OPT_VIEWER_PDF is_not_empty
4477 msm_viewers
="${_OPT_VIEWER_PDF}";
4479 msm_viewers
="${_VIEWER_PDF}";
4481 msm_viewer
="$(_get_first_prog "${msm_viewers}")";
4482 if is_not_equal
"$?" 0
4486 _DISPLAY_PROG
="${msm_viewer}";
4487 _DISPLAY_MODE
="pdf";
4488 eval ${_UNSET} msm_modes
;
4489 eval ${_UNSET} msm_viewer
;
4490 eval ${_UNSET} msm_viewers
;
4491 eval "${return_ok}";
4494 if obj _OPT_VIEWER_PS is_not_empty
4496 msm_viewers
="${_OPT_VIEWER_PS}";
4498 msm_viewers
="${_VIEWER_PS}";
4500 msm_viewer
="$(_get_first_prog "${msm_viewers}")";
4501 if is_not_equal
"$?" 0
4505 _DISPLAY_PROG
="${msm_viewer}";
4507 eval ${_UNSET} msm_modes
;
4508 eval ${_UNSET} msm_viewer
;
4509 eval ${_UNSET} msm_viewers
;
4510 eval "${return_ok}";
4513 if obj _OPT_VIEWER_HTML is_not_empty
4515 msm_viewers
="${_OPT_VIEWER_HTML}";
4517 msm_viewers
="${_VIEWER_HTML}";
4519 msm_viewer
="$(_get_first_prog "${msm_viewers}")";
4520 if is_not_equal
"$?" 0
4524 _DISPLAY_PROG
="${msm_viewer}";
4526 eval ${_UNSET} msm_modes
;
4527 eval ${_UNSET} msm_viewer
;
4528 eval ${_UNSET} msm_viewers
;
4529 eval "${return_ok}";
4533 eval ${_UNSET} msm_modes
;
4534 eval ${_UNSET} msm_viewer
;
4535 eval ${_UNSET} msm_viewers
;
4536 error
"main_set_mode(): no suitable display mode found.";
4540 # _get_first_prog (<proglist>)
4542 # Retrieve first argument that represents an existing program in $PATH.
4543 # Local function for main_set_mode().
4545 # Arguments: 1; a comma-separated list of commands (with options),
4548 # Return : `1' if none found, `0' if found.
4549 # Output : the argument that succeded.
4551 # Variable prefix: _gfp
4557 error
"_get_first_prog() needs 1 argument.";
4563 eval set x
"$(list_from_split "$1" ',')";
4568 if obj _gfp_i is_empty
4572 if eval is_prog
"$(get_first_essential ${_gfp_i})"
4575 eval ${_UNSET} _gfp_i
;
4579 eval ${_UNSET} _gfp_i
;
4581 } # _get_first_prog() of main_set_mode()
4584 #######################################################################
4585 # main_do_fileargs ()
4587 # Process filespec arguments in $_FILEARGS.
4590 # in: $_FILEARGS (process with `eval set x "$_FILEARGS"; shift;')
4592 # Variable prefix: mdfa
4596 func_check main_do_fileargs
= 0 "$@";
4597 mdfa_exitcode
="${_BAD}";
4598 eval set x
"${_FILEARGS}";
4600 eval ${_UNSET} _FILEARGS
;
4601 # temporary storage of all input to $_TMP_CAT
4602 while test "$#" -ge 2
4604 # test for `s name' arguments, with `s' a 1-char standard section
4607 case "${mdfa_filespec}" in
4612 if register_file
'-'
4614 mdfa_exitcode
="${_GOOD}";
4619 if list_has_not _MAN_AUTO_SEC
"${mdfa_filespec}"
4621 if do_filearg
"${mdfa_filespec}"
4623 mdfa_exitcode
="${_GOOD}";
4628 case "${mdfa_name}" in
4629 */*|man
:*|
*\
(*\
)|
*.
"${mdfa_filespec}")
4630 if do_filearg
"${mdfa_filespec}"
4632 mdfa_exitcode
="${_GOOD}";
4637 if do_filearg
"man:${mdfa_name}(${mdfa_filespec})"
4639 mdfa_exitcode
="${_GOOD}";
4643 if do_filearg
"${mdfa_filespec}"
4645 mdfa_exitcode
="${_GOOD}";
4651 if do_filearg
"${mdfa_filespec}"
4653 mdfa_exitcode
="${_GOOD}";
4658 done; # end of `s name' test
4659 while test "$#" -gt 0
4663 if do_filearg
"${mdfa_filespec}"
4665 mdfa_exitcode
="${_GOOD}";
4668 obj _TMP_STDIN rm_file_with_debug
;
4669 if is_equal
"${mdfa_exitcode}" "${_BAD}"
4671 eval ${_UNSET} mdfa_exitcode
;
4672 eval ${_UNSET} mdfa_filespec
;
4673 eval ${_UNSET} mdfa_name
;
4674 eval "${return_bad}";
4676 eval ${_UNSET} mdfa_exitcode
;
4677 eval ${_UNSET} mdfa_filespec
;
4678 eval ${_UNSET} mdfa_name
;
4679 eval "${return_ok}";
4680 } # main_do_fileargs()
4683 ########################################################################
4684 # main_set_resources ()
4686 # Determine options for setting X resources with $_DISPLAY_PROG.
4688 # Globals: $_DISPLAY_PROG, $_OUTPUT_FILE_NAME
4690 # Variable prefix: msr
4692 main_set_resources
()
4694 func_check main_set_resources
= 0 "$@";
4695 # $msr_prog viewer program
4696 # $msr_rl resource list
4697 msr_title
="$(get_first_essential \
4698 "${_OPT_TITLE}" "${_REGISTERED_TITLE}")";
4699 _OUTPUT_FILE_NAME
='';
4700 eval set x
"${msr_title}";
4702 until is_equal
"$#" 0
4710 msr_n
="$(echo1 "$1" | sed -e 's/^,,*//')";
4713 if obj msr_n is_empty
4717 if obj _OUTPUT_FILE_NAME is_not_empty
4719 _OUTPUT_FILE_NAME
="${_OUTPUT_FILE_NAME}"',';
4721 _OUTPUT_FILE_NAME
="${_OUTPUT_FILE_NAME}${msr_n}";
4724 case "${_OUTPUT_FILE_NAME}" in
4726 _OUTPUT_FILE_NAME
='-';
4729 error
"main_set_resources(): ${_OUTPUT_FILE_NAME} starts with a comma.";
4732 _OUTPUT_FILE_NAME
="${_TMP_DIR}/${_OUTPUT_FILE_NAME}";
4734 if obj _DISPLAY_PROG is_empty
4735 then # for example, for groff mode
4737 eval ${_UNSET} msr_n
;
4738 eval ${_UNSET} msr_prog
;
4739 eval ${_UNSET} msr_rl
;
4740 eval ${_UNSET} msr_title
;
4741 eval "${return_ok}";
4744 eval set x
"${_DISPLAY_PROG}";
4746 msr_prog
="$(base_name "$1")";
4750 if obj _DISPLAY_PROG is_empty
4754 _DISPLAY_ARGS
="$* ${_DISPLAY_ARGS}";
4758 if obj _OPT_BD is_not_empty
4760 case "${msr_prog}" in
4761 ghostview|gv|gxditview|xditview|xdvi
)
4762 list_append msr_rl
'-bd' "${_OPT_BD}";
4766 if obj _OPT_BG is_not_empty
4768 case "${msr_prog}" in
4769 ghostview|gv|gxditview|xditview|xdvi
)
4770 list_append msr_rl
'-bg' "${_OPT_BG}";
4773 list_append msr_rl
'--bg' "${_OPT_BG}";
4776 list_append msr_rl
'-papercolor' "${_OPT_BG}";
4780 if obj _OPT_BW is_not_empty
4782 case "${msr_prog}" in
4783 ghostview|gv|gxditview|xditview|xdvi
)
4784 _list_append msr_rl
'-bw' "${_OPT_BW}";
4788 if obj _OPT_FG is_not_empty
4790 case "${msr_prog}" in
4791 ghostview|gv|gxditview|xditview|xdvi
)
4792 list_append msr_rl
'-fg' "${_OPT_FG}";
4795 list_append msr_rl
'--fg' "${_OPT_FG}";
4799 if is_not_empty
"${_OPT_FN}"
4801 case "${msr_prog}" in
4802 ghostview|gv|gxditview|xditview|xdvi
)
4803 list_append msr_rl
'-fn' "${_OPT_FN}";
4806 list_append msr_rl
'--fn' "${_OPT_FN}";
4810 if is_not_empty
"${_OPT_GEOMETRY}"
4812 case "${msr_prog}" in
4813 ghostview|gv|gxditview|xditview|xdvi|xpdf
)
4814 list_append msr_rl
'-geometry' "${_OPT_GEOMETRY}";
4817 list_append msr_rl
'--geometry' "${_OPT_GEOMETRY}";
4821 if is_empty
"${_OPT_RESOLUTION}"
4823 _OPT_RESOLUTION
="${_DEFAULT_RESOLUTION}";
4824 case "${msr_prog}" in
4826 list_append msr_rl
'-resolution' "${_DEFAULT_RESOLUTION}";
4829 case "${_DEFAULT_RESOLUTION}" in
4832 list_append msr_rl
'-z' '104';
4835 list_append msr_rl
'-z' '139';
4841 case "${msr_prog}" in
4842 ghostview|gv|gxditview|xditview|xdvi
)
4843 list_append msr_rl
'-resolution' "${_OPT_RESOLUTION}";
4846 case "${_OPT_RESOLUTION}" in
4848 list_append msr_rl
'-z' '104';
4849 # '100' corresponds to 72dpi
4852 list_append msr_rl
'-z' '139';
4858 if is_yes
"${_OPT_ICONIC}"
4860 case "${msr_prog}" in
4861 ghostview|gv|gxditview|xditview|xdvi
)
4862 list_append msr_rl
'-iconic';
4866 if is_yes
"${_OPT_RV}"
4868 case "${msr_prog}" in
4869 ghostview|gv|gxditview|xditview|xdvi
)
4870 list_append msr_rl
'-rv';
4874 if is_not_empty
"${_OPT_XRM}"
4876 case "${msr_prog}" in
4877 ghostview|gv|gxditview|xditview|xdvi|xpdf
)
4878 eval set x
"${_OPT_XRM}";
4882 list_append msr_rl
'-xrm' "$i";
4887 if is_not_empty
"${msr_title}"
4889 case "${msr_prog}" in
4891 list_append msr_rl
'-title' "${msr_title}";
4895 _DISPLAY_ARGS
="${msr_rl}";
4896 eval ${_UNSET} msr_n
;
4897 eval ${_UNSET} msr_prog
;
4898 eval ${_UNSET} msr_rl
;
4899 eval ${_UNSET} msr_title
;
4900 eval "${return_ok}";
4901 } # main_set_resources
4904 ########################################################################
4907 # Do the actual display of the whole thing.
4910 # in: $_DISPLAY_MODE, $_OPT_DEVICE,
4911 # $_ADDOPTS_GROFF, $_ADDOPTS_POST, $_ADDOPTS_X,
4912 # $_REGISTERED_TITLE, $_TMP_CAT,
4913 # $_OPT_PAGER $PAGER, $_MANOPT_PAGER,
4914 # $_OUTPUT_FILE_NAME
4916 # Variable prefix: md
4920 func_check main_display
= 0 "$@";
4926 if obj _TMP_CAT is_non_empty_file
4928 md_modefile
="${_OUTPUT_FILE_NAME}";
4930 echo2
'groffer: empty input.';
4932 eval ${_UNSET} md_modefile
;
4933 eval "${return_ok}";
4936 # go to the temporary directory to be able to access internal data files
4937 cd "${_TMP_DIR}" >"${_NULL_DEV}" 2>&1;
4939 case "${_DISPLAY_MODE}" in
4941 _ADDOPTS_GROFF
="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
4942 if obj _OPT_DEVICE is_not_empty
4944 _ADDOPTS_GROFF
="${_ADDOPTS_GROFF} -T${_OPT_DEVICE}";
4946 md_groggy
="$(tmp_cat | eval grog "${md_options}")";
4950 obj md_modefile rm_file
;
4951 mv "${_TMP_CAT}" "${md_modefile}";
4952 cat "${md_modefile}" | \
4954 trap clean_up
0 2>${_NULL_DEV} ||
:;
4955 eval "${md_groggy}" "${_ADDOPTS_GROFF}";
4960 case "${_OPT_DEVICE}" in
4962 md_device
="$(get_first_essential \
4963 "${_OPT_TEXT_DEVICE}" "${_DEFAULT_TTY_DEVICE}")";
4965 ascii|cp1047|latin1|utf8
)
4966 md_device
="${_OPT_DEVICE}";
4969 warning
"main_display(): \
4970 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
4973 md_addopts
="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
4974 md_groggy
="$(tmp_cat | grog -T${md_device})";
4975 if obj _DISPLAY_MODE is_equal
'text'
4978 tmp_cat |
eval "${md_groggy}" "${md_addopts}";
4981 for p
in "${_OPT_PAGER}" "${PAGER}" "${_MANOPT_PAGER}" \
4982 'less -r -R' 'more' 'pager' 'cat'
4985 if eval is_prog
${md_p}
4986 then # no "" for is_prog() allows args for $p
4991 if obj md_pager is_empty
4993 error
'main_display(): no pager program found for tty mode';
4996 tmp_cat |
eval "${md_groggy}" "${md_addopts}" | \
5009 case "${_OPT_DEVICE}" in
5010 ''|dvi
) do_nothing
; ;;
5012 warning
"main_display(): \
5013 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"
5016 md_modefile
="${md_modefile}".dvi
;
5017 md_groggy
="$(tmp_cat | grog -Tdvi)";
5021 case "${_OPT_DEVICE}" in
5022 ''|html
) do_nothing
; ;;
5024 warning
"main_display(): \
5025 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
5028 md_modefile
="${md_modefile}".html
;
5029 md_groggy
="$(tmp_cat | grog -Thtml)";
5033 case "${_OPT_DEVICE}" in
5038 warning
"main_display(): \
5039 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
5042 md_groggy
="$(tmp_cat | grog -Tps)";
5043 _do_display _make_pdf
;
5046 case "${_OPT_DEVICE}" in
5051 warning
"main_display(): \
5052 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
5055 md_modefile
="${md_modefile}".ps
;
5056 md_groggy
="$(tmp_cat | grog -Tps)";
5060 case "${_OPT_DEVICE}" in
5062 md_device
="${_OPT_DEVICE}"
5065 case "${_OPT_RESOLUTION}" in
5068 if obj _OPT_GEOMETRY is_empty
5070 case "${_DISPLAY_PROG}" in
5072 # add width of 800dpi for resolution of 100dpi to the args
5073 list_append _DISPLAY_ARGS
'-geometry' '800';
5083 md_groggy
="$(tmp_cat | grog -T${md_device} -Z)";
5087 case "${_OPT_DEVICE}" in
5089 md_groggy
="$(tmp_cat | grog -X)";
5091 X
*|dvi|html|lbp|lj4|ps
)
5092 # these devices work with
5093 md_groggy
="$(tmp_cat | grog -T"${_OPT_DEVICE}" -X)";
5096 warning
"main_display(): \
5097 wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
5098 md_groggy
="$(tmp_cat | grog -Z)";
5104 error
"main_display(): unknown mode \`${_DISPLAY_MODE}'";
5107 eval ${_UNSET} md_addopts
;
5108 eval ${_UNSET} md_device
;
5109 eval ${_UNSET} md_groggy
;
5110 eval ${_UNSET} md_modefile
;
5111 eval ${_UNSET} md_options
;
5112 eval ${_UNSET} md_p
;
5113 eval ${_UNSET} md_pager
;
5114 eval "${return_ok}";
5118 ########################
5119 # _do_display ([<prog>])
5121 # Perform the generation of the output and view the result. If an
5122 # argument is given interpret it as a function name that is called in
5125 # Globals: $md_modefile, $md_groggy (from main_display())
5129 func_check _do_display
'>=' 0 "$@";
5132 obj md_modefile rm_file
;
5133 if cat "${_TMP_CAT}" | \
5134 eval "${md_groggy}" "${_ADDOPTS_GROFF}" > "${md_modefile}"
5138 error
"_do_display: error on groff call";
5140 if is_not_empty
"$1"
5144 obj _TMP_CAT rm_file_with_debug
;
5146 trap clean_up
0 2>${_NULL_DEV} ||
:;
5147 eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
5150 eval "${return_ok}";
5151 } # _do_display() of main_display()
5157 # Check on option `-V'; if set print the corresponding output and leave.
5159 # Globals: $_ALL_PARAMS, $_ADDOPTS_GROFF, $_DISPLAY_MODE, $_DISPLAY_PROG,
5160 # $_DISPLAY_ARGS, $md_groggy, $md_modefile
5162 # Variable prefix: _doV
5166 func_check _do_opt_V
'=' 0 "$@";
5167 if obj _OPT_V is_yes
5170 echo "Output file: ${md_modefile}";
5171 echo "Display mode: ${_DISPLAY_MODE}";
5172 echo "Display prog: ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
5173 echo "Parameters: ${_ALL_PARAMS}";
5174 echo "Output of grog: ${md_groggy} $(eval echo1 "'${_ADDOPTS_GROFF}'")";
5175 _doV_res
="$(eval "${md_groggy}" "${_ADDOPTS_GROFF}")";
5176 echo "groff -V: ${_doV_res}"
5179 eval "${return_ok}";
5180 } # _do_opt_V() of main_display()
5186 # Transform to pdf format; for pdf mode in _do_display().
5188 # Globals: $md_modefile (from main_display())
5190 # Variable prefix: _mp
5194 func_check _do_display
'=' 0 "$@";
5195 _mp_psfile
="${md_modefile}";
5196 md_modefile
="${md_modefile}.pdf";
5197 obj md_modefile rm_file
;
5198 if gs
-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
5199 -sOutputFile="${md_modefile}" -c save pop
-f "${_mp_psfile}"
5203 error
'_make_pdf: could not transform into pdf format.';
5205 obj _mp_psfile rm_file_with_debug
;
5206 eval ${_UNSET} _mp_psfile
;
5207 eval "${return_ok}";
5208 } # _make_pdf() of main_display()
5211 ########################################################################
5212 # main (<command_line_args>*)
5214 # The main function for groffer.
5220 func_check main
'>=' 0 "$@";
5221 # Do not change the sequence of the following functions!
5222 landmark
'13: main_init()';
5224 landmark
'14: main_parse_MANOPT()';
5226 landmark
'15: main_parse_args()';
5227 main_parse_args
"$@";
5228 landmark
'16: main_set_mode()';
5230 landmark
'17: main_do_fileargs()';
5232 landmark
'18: main_set_resources()';
5234 landmark
'19: main_display()';
5236 eval "${return_ok}";
5239 landmark
'20: end of function definitions';
5241 ########################################################################