PageRenderTime 64ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/contrib/groff/contrib/groffer/groffer2.sh

https://bitbucket.org/freebsd/freebsd-head/
Shell | 5854 lines | 4370 code | 361 blank | 1123 comment | 359 complexity | 56f108a0a126ad0a9df7a8b9539c98fa MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0
  1. #! /bin/sh
  2. # groffer - display groff files
  3. # Source file position: <groff-source>/contrib/groffer/groffer2.sh
  4. # Installed position: <prefix>/lib/groff/groffer/groffer2.sh
  5. # This file should not be run independently. It is called by
  6. # `groffer.sh' in the source or by the installed `groffer' program.
  7. # Copyright (C) 2001,2002,2003,2004,2005
  8. # Free Software Foundation, Inc.
  9. # Written by Bernd Warken
  10. # Last update: 22 August 2005
  11. # This file is part of `groffer', which is part of `groff'.
  12. # `groff' is free software; you can redistribute it and/or modify it
  13. # under the terms of the GNU General Public License as published by
  14. # the Free Software Foundation; either version 2, or (at your option)
  15. # any later version.
  16. # `groff' is distributed in the hope that it will be useful, but
  17. # WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. # General Public License for more details.
  20. # You should have received a copy of the GNU General Public License
  21. # along with `groff'; see the files COPYING and LICENSE in the top
  22. # directory of the `groff' source. If not, write to the Free Software
  23. # Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301,
  24. # USA.
  25. ########################################################################
  26. # Test of rudimentary shell functionality
  27. ########################################################################
  28. ########################################################################
  29. # Test of `unset'
  30. #
  31. export _UNSET;
  32. export _foo;
  33. _foo=bar;
  34. _res="$(unset _foo 2>&1)";
  35. if unset _foo >${_NULL_DEV} 2>&1 && \
  36. test _"${_res}"_ = __ && test _"${_foo}"_ = __
  37. then
  38. _UNSET='unset';
  39. eval "${_UNSET}" _foo;
  40. eval "${_UNSET}" _res;
  41. else
  42. _UNSET=':';
  43. fi;
  44. ########################################################################
  45. # Test of `test'.
  46. #
  47. if test a = a && test a != b && test -f "${_GROFFER_SH}"
  48. then
  49. :;
  50. else
  51. echo '"test" did not work.' >&2;
  52. exit "${_ERROR}";
  53. fi;
  54. ########################################################################
  55. # Test of `echo' and the `$()' construct.
  56. #
  57. if echo '' >${_NULL_DEV}
  58. then
  59. :;
  60. else
  61. echo '"echo" did not work.' >&2;
  62. exit "${_ERROR}";
  63. fi;
  64. if test _"$(t1="$(echo te)" &&
  65. t2="$(echo '')" &&
  66. t3="$(echo 'st')" &&
  67. echo "${t1}${t2}${t3}")"_ \
  68. != _test_
  69. then
  70. echo 'The "$()" construct did not work' >&2;
  71. exit "${_ERROR}";
  72. fi;
  73. ########################################################################
  74. # Test of sed program; test in groffer.sh is not valid here.
  75. #
  76. if test _"$(echo red | sed -e 's/r/s/')"_ != _sed_
  77. then
  78. echo 'The sed program did not work.' >&2;
  79. exit "${_ERROR}";
  80. fi;
  81. ########################################################################
  82. # Test of function definitions.
  83. #
  84. _t_e_s_t_f_u_n_c_()
  85. {
  86. return 0;
  87. }
  88. if _t_e_s_t_f_u_n_c_ 2>${_NULL_DEV}
  89. then
  90. :;
  91. else
  92. echo 'Shell '"${_SHELL}"' does not support function definitions.' >&2;
  93. exit "${_ERROR}";
  94. fi;
  95. ########################################################################
  96. # debug - diagnostic messages
  97. ########################################################################
  98. export _DEBUG_STACKS;
  99. _DEBUG_STACKS='no'; # disable stack output in each function
  100. #_DEBUG_STACKS='yes'; # enable stack output in each function
  101. export _DEBUG_LM;
  102. _DEBUG_LM='no'; # disable landmark messages
  103. #_DEBUG_LM='yes'; # enable landmark messages
  104. export _DEBUG_KEEP_FILES;
  105. _DEBUG_KEEP_FILES='no' # disable file keeping in temporary dir
  106. #_DEBUG_KEEP_FILES='yes' # enable file keeping in temporary dir
  107. export _DEBUG_PRINT_PARAMS;
  108. _DEBUG_PRINT_PARAMS='no'; # disable printing of all parameters
  109. #_DEBUG_PRINT_PARAMS='yes'; # enable printing of all parameters
  110. export _DEBUG_PRINT_SHELL;
  111. _DEBUG_PRINT_SHELL='no'; # disable printing of the shell name
  112. #_DEBUG_PRINT_SHELL='yes'; # enable printing of the shell name
  113. export _DEBUG_PRINT_TMPDIR;
  114. _DEBUG_PRINT_TMPDIR='no'; # disable printing of the temporary dir
  115. #_DEBUG_PRINT_TMPDIR='yes'; # enable printing of the temporary dir
  116. export _DEBUG_USER_WITH_STACK;
  117. _DEBUG_USER_WITH_STACK='no'; # disable stack dump in error_user()
  118. #_DEBUG_USER_WITH_STACK='yes'; # enable stack dump in error_user()
  119. # determine all --debug* options
  120. case " $*" in
  121. *\ --debug*)
  122. case " $* " in
  123. *' --debug '*)
  124. # _DEBUG_STACKS='yes';
  125. # _DEBUG_LM='yes';
  126. _DEBUG_KEEP_FILES='yes';
  127. _DEBUG_PRINT_PARAMS='yes';
  128. _DEBUG_PRINT_SHELL='yes';
  129. _DEBUG_PRINT_TMPDIR='yes';
  130. _DEBUG_USER_WITH_STACK='yes';
  131. ;;
  132. esac;
  133. d=' --debug-all --debug-keep --debug-lm --debug-params --debug-shell '\
  134. '--debug-stacks --debug-tmpdir --debug-user ';
  135. for i
  136. do
  137. case "$i" in
  138. --debug-s)
  139. echo 'The abbreviation --debug-s has multiple options: '\
  140. '--debug-shell and --debug-stacks.' >&2
  141. exit "${_ERROR}";
  142. ;;
  143. esac;
  144. case "$d" in
  145. *\ ${i}*)
  146. # extract whole word of abbreviation $i
  147. s="$(cat <<EOF | sed -n -e 's/^.* \('"$i"'[^ ]*\) .*/\1/p'
  148. $d
  149. EOF
  150. )"
  151. case "$s" in
  152. '') continue; ;;
  153. --debug-all)
  154. _DEBUG_STACKS='yes';
  155. _DEBUG_LM='yes';
  156. _DEBUG_KEEP_FILES='yes';
  157. _DEBUG_PRINT_PARAMS='yes';
  158. _DEBUG_PRINT_SHELL='yes';
  159. _DEBUG_PRINT_TMPDIR='yes';
  160. _DEBUG_USER_WITH_STACK='yes';
  161. ;;
  162. --debug-keep)
  163. _DEBUG_PRINT_TMPDIR='yes';
  164. _DEBUG_KEEP_FILES='yes';
  165. ;;
  166. --debug-lm)
  167. _DEBUG_LM='yes';
  168. ;;
  169. --debug-params)
  170. _DEBUG_PRINT_PARAMS='yes';
  171. ;;
  172. --debug-shell)
  173. _DEBUG_PRINT_SHELL='yes';
  174. ;;
  175. --debug-stacks)
  176. _DEBUG_STACKS='yes';
  177. ;;
  178. --debug-tmpdir)
  179. _DEBUG_PRINT_TMPDIR='yes';
  180. ;;
  181. --debug-user)
  182. _DEBUG_USER_WITH_STACK='yes';
  183. ;;
  184. esac;
  185. ;;
  186. esac;
  187. done
  188. ;;
  189. esac;
  190. if test _"${_DEBUG_PRINT_PARAMS}"_ = _yes_
  191. then
  192. echo "parameters: $@" >&2;
  193. fi;
  194. if test _"${_DEBUG_PRINT_SHELL}"_ = _yes_
  195. then
  196. if test _"${_SHELL}"_ = __
  197. then
  198. if test _"${POSIXLY_CORRECT}"_ = _y_
  199. then
  200. echo 'shell: bash as /bin/sh (none specified)' >&2;
  201. else
  202. echo 'shell: /bin/sh (none specified)' >&2;
  203. fi;
  204. else
  205. echo "shell: ${_SHELL}" >&2;
  206. fi;
  207. fi;
  208. ########################################################################
  209. # Environment Variables
  210. ########################################################################
  211. # Environment variables that exist only for this file start with an
  212. # underscore letter. Global variables to this file are written in
  213. # upper case letters, e.g. $_GLOBAL_VARIABLE; temporary variables
  214. # start with an underline and use only lower case letters and
  215. # underlines, e.g. $_local_variable .
  216. # [A-Z]* system variables, e.g. $MANPATH
  217. # _[A-Z_]* global file variables, e.g. $_MAN_PATH
  218. # _[a-z_]* temporary variables, e.g. $_manpath
  219. # Due to incompatibilities of the `ash' shell, the name of loop
  220. # variables in `for' must be single character
  221. # [a-z] local loop variables, e.g. $i
  222. ########################################################################
  223. # read-only variables (global to this file)
  224. ########################################################################
  225. # function return values; `0' means ok; other values are error codes
  226. export _ALL_EXIT;
  227. export _BAD;
  228. export _GOOD;
  229. export _NO;
  230. export _OK;
  231. export _YES;
  232. _GOOD='0'; # return ok
  233. _BAD='1'; # return negatively, error code `1'
  234. # $_ERROR was already defined as `7' in groffer.sh.
  235. _NO="${_BAD}";
  236. _YES="${_GOOD}";
  237. _OK="${_GOOD}";
  238. # quasi-functions, call with `eval', e.g `eval "${return_ok}"'
  239. export return_ok;
  240. export return_good;
  241. export return_bad;
  242. export return_yes;
  243. export return_no;
  244. export return_error;
  245. export return_var;
  246. return_ok="func_pop; return ${_OK}";
  247. return_good="func_pop; return ${_GOOD}";
  248. return_bad="func_pop; return ${_BAD}";
  249. return_yes="func_pop; return ${_YES}";
  250. return_no="func_pop; return ${_NO}";
  251. return_error="func_pop; return ${_ERROR}";
  252. return_var="func_pop; return"; # add number, e.g. `eval "${return_var} $n'
  253. export _DEFAULT_MODES;
  254. _DEFAULT_MODES='x,ps,tty';
  255. export _DEFAULT_RESOLUTION;
  256. _DEFAULT_RESOLUTION='75';
  257. export _DEFAULT_TTY_DEVICE;
  258. _DEFAULT_TTY_DEVICE='latin1';
  259. # _VIEWER_* viewer programs for different modes (only X is necessary)
  260. # _VIEWER_* a comma-separated list of viewer programs (with options)
  261. export _VIEWER_DVI; # viewer program for dvi mode
  262. export _VIEWER_HTML_TTY; # viewer program for html mode in tty
  263. export _VIEWER_HTML_X; # viewer program for html mode in X
  264. export _VIEWER_PDF; # viewer program for pdf mode
  265. export _VIEWER_PS; # viewer program for ps mode
  266. export _VIEWER_X; # viewer program for X mode
  267. _VIEWER_DVI='kdvi,xdvi,dvilx';
  268. _VIEWER_HTML_TTY='lynx';
  269. _VIEWER_HTML_X='konqueror,mozilla,netscape,galeon,opera,amaya,arena';
  270. _VIEWER_PDF='kghostview --scale 1.45,ggv,xpdf,acroread,kpdf';
  271. _VIEWER_PS='kghostview --scale 1.45,ggv,gv,ghostview,gs_x11,gs';
  272. _VIEWER_X='gxditview,xditview';
  273. # Search automatically in standard sections `1' to `8', and in the
  274. # traditional sections `9', `n', and `o'. On many systems, there
  275. # exist even more sections, mostly containing a set of man pages
  276. # special to a specific program package. These aren't searched for
  277. # automatically, but must be specified on the command line.
  278. export _MAN_AUTO_SEC_LIST;
  279. _MAN_AUTO_SEC_LIST="'1' '2' '3' '4' '5' '6' '7' '8' '9' 'n' 'o'";
  280. export _MAN_AUTO_SEC_CHARS;
  281. _MAN_AUTO_SEC_CHARS='[123456789no]';
  282. export _SPACE_SED;
  283. _SPACE_SED='['"${_SP}${_TAB}"']';
  284. export _SPACE_CASE;
  285. _SPACE_CASE='[\'"${_SP}"'\'"${_TAB}"']';
  286. export _PROCESS_ID; # for shutting down the program
  287. _PROCESS_ID="$$";
  288. ############ the command line options of the involved programs
  289. #
  290. # The naming scheme for the options environment names is
  291. # $_OPTS_<prog>_<length>[_<argspec>]
  292. #
  293. # <prog>: program name GROFFER, GROFF, or CMDLINE (for all
  294. # command line options)
  295. # <length>: LONG (long options) or SHORT (single character options)
  296. # <argspec>: ARG for options with argument, NA for no argument;
  297. # without _<argspec> both the ones with and without arg.
  298. #
  299. # Each option that takes an argument must be specified with a
  300. # trailing : (colon).
  301. # exports
  302. export _OPTS_GROFFER_SHORT_NA;
  303. export _OPTS_GROFFER_SHORT_ARG;
  304. export _OPTS_GROFFER_LONG_NA;
  305. export _OPTS_GROFFER_LONG_ARG;
  306. export _OPTS_GROFF_SHORT_NA;
  307. export _OPTS_GROFF_SHORT_ARG;
  308. export _OPTS_GROFF_LONG_NA;
  309. export _OPTS_GROFF_LONG_ARG;
  310. export _OPTS_X_SHORT_ARG;
  311. export _OPTS_X_SHORT_NA;
  312. export _OPTS_X_LONG_ARG;
  313. export _OPTS_X_LONG_NA;
  314. export _OPTS_MAN_SHORT_ARG;
  315. export _OPTS_MAN_SHORT_NA;
  316. export _OPTS_MAN_LONG_ARG;
  317. export _OPTS_MAN_LONG_NA;
  318. export _OPTS_MANOPT_SHORT_ARG;
  319. export _OPTS_MANOPT_SHORT_NA;
  320. export _OPTS_MANOPT_LONG_ARG;
  321. export _OPTS_MANOPT_LONG_NA;
  322. export _OPTS_CMDLINE_SHORT_NA;
  323. export _OPTS_CMDLINE_SHORT_ARG;
  324. export _OPTS_CMDLINE_LONG_NA;
  325. export _OPTS_CMDLINE_LONG_ARG;
  326. ###### groffer native options
  327. _OPTS_GROFFER_SHORT_NA="'h' 'Q' 'v' 'V' 'X' 'Z'";
  328. _OPTS_GROFFER_SHORT_ARG="'T'";
  329. _OPTS_GROFFER_LONG_NA="'auto' \
  330. 'apropos' 'apropos-data' 'apropos-devel' 'apropos-progs' \
  331. 'debug' 'debug-all' 'debug-keep' 'debug-lm' 'debug-params' 'debug-shell' \
  332. 'debug-stacks' 'debug-tmpdir' 'debug-user' 'default' 'do-nothing' 'dvi' \
  333. 'groff' 'help' 'intermediate-output' 'html' 'man' \
  334. 'no-location' 'no-man' 'no-special' 'pdf' 'ps' 'rv' 'source' \
  335. 'text' 'text-device' \
  336. 'tty' 'tty-device' 'version' 'whatis' 'where' 'www' 'x' 'X'";
  337. _OPTS_GROFFER_LONG_ARG="\
  338. 'default-modes' 'device' 'dvi-viewer' 'dvi-viewer-tty' 'extension' 'fg' \
  339. 'fn' 'font' 'foreground' 'html-viewer' 'html-viewer-tty' 'mode' \
  340. 'pdf-viewer' 'pdf-viewer-tty' 'print' 'ps-viewer' 'ps-viewer-tty' 'shell' \
  341. 'title' 'tty-viewer' 'tty-viewer-tty' 'www-viewer' 'www-viewer-tty' \
  342. 'x-viewer' 'x-viewer-tty' 'X-viewer' 'X-viewer-tty'";
  343. ##### groffer options inhereted from groff
  344. _OPTS_GROFF_SHORT_NA="'a' 'b' 'c' 'C' 'e' 'E' 'g' 'G' 'i' 'l' 'N' 'p' \
  345. 'R' 's' 'S' 't' 'U' 'z'";
  346. _OPTS_GROFF_SHORT_ARG="'d' 'f' 'F' 'I' 'L' 'm' 'M' 'n' 'o' 'P' 'r' \
  347. 'w' 'W'";
  348. _OPTS_GROFF_LONG_NA="";
  349. _OPTS_GROFF_LONG_ARG="";
  350. ##### groffer options inhereted from the X Window toolkit
  351. _OPTS_X_SHORT_NA="";
  352. _OPTS_X_SHORT_ARG="";
  353. _OPTS_X_LONG_NA="'iconic' 'rv'";
  354. _OPTS_X_LONG_ARG="'background' 'bd' 'bg' 'bordercolor' 'borderwidth' \
  355. 'bw' 'display' 'fg' 'fn' 'font' 'foreground' 'ft' 'geometry' \
  356. 'resolution' 'title' 'xrm'";
  357. ###### groffer options inherited from man
  358. _OPTS_MAN_SHORT_NA="";
  359. _OPTS_MAN_SHORT_ARG="";
  360. _OPTS_MAN_LONG_NA="'all' 'ascii' 'catman' 'ditroff' \
  361. 'local-file' 'location' 'troff' 'update'";
  362. _OPTS_MAN_LONG_ARG="'locale' 'manpath' \
  363. 'pager' 'preprocessor' 'prompt' 'sections' 'systems' 'troff-device'";
  364. ###### additional options for parsing $MANOPT only
  365. _OPTS_MANOPT_SHORT_NA="'7' 'a' 'c' 'd' 'D' 'f' 'h' 'k' 'l' 't' 'u' \
  366. 'V' 'w' 'Z'";
  367. _OPTS_MANOPT_SHORT_ARG="'e' 'L' 'm' 'M' 'p' 'P' 'r' 'S' 'T'";
  368. _OPTS_MANOPT_LONG_NA="${_OPTS_MAN_LONG_NA} \
  369. 'apropos' 'debug' 'default' 'help' 'html' 'ignore-case' 'location-cat' \
  370. 'match-case' 'troff' 'update' 'version' 'whatis' 'where' 'where-cat'";
  371. _OPTS_MANOPT_LONG_ARG="${_OPTS_MAN_LONG_NA} \
  372. 'config_file' 'encoding' 'extension' 'locale'";
  373. ###### collections of command line options
  374. _OPTS_CMDLINE_SHORT_NA="${_OPTS_GROFFER_SHORT_NA} \
  375. ${_OPTS_GROFF_SHORT_NA} ${_OPTS_X_SHORT_NA} ${_OPTS_MAN_SHORT_NA}";
  376. _OPTS_CMDLINE_SHORT_ARG="${_OPTS_GROFFER_SHORT_ARG} \
  377. ${_OPTS_GROFF_SHORT_ARG} ${_OPTS_X_SHORT_ARG} ${_OPTS_MAN_SHORT_ARG}";
  378. _OPTS_CMDLINE_LONG_NA="${_OPTS_GROFFER_LONG_NA} \
  379. ${_OPTS_GROFF_LONG_NA} ${_OPTS_X_LONG_NA} ${_OPTS_MAN_LONG_NA}";
  380. _OPTS_CMDLINE_LONG_ARG="${_OPTS_GROFFER_LONG_ARG} \
  381. ${_OPTS_GROFF_LONG_ARG} ${_OPTS_MAN_LONG_ARG} ${_OPTS_X_LONG_ARG}";
  382. ########################################################################
  383. # read-write variables (global to this file)
  384. ########################################################################
  385. export _ALL_PARAMS; # All options and file name parameters
  386. export _ADDOPTS_GROFF; # Transp. options for groff (`eval').
  387. export _ADDOPTS_POST; # Transp. options postproc (`eval').
  388. export _ADDOPTS_X; # Transp. options X postproc (`eval').
  389. export _APROPOS_PROG; # Program to run apropos.
  390. export _APROPOS_SECTIONS; # Sections for different --apropos-*.
  391. export _DEFAULT_MODES; # Set default modes.
  392. export _DISPLAY_MODE; # Display mode.
  393. export _DISPLAY_PROG; # Viewer program to be used for display.
  394. export _DISPLAY_ARGS; # X resources for the viewer program.
  395. export _FILEARGS; # Stores filespec parameters.
  396. export _FILESPEC_ARG; # Stores the actual filespec parameter.
  397. export _FUNC_STACK; # Store debugging information.
  398. export _REGISTERED_TITLE; # Processed file names.
  399. # _HAS_* from availability tests
  400. export _HAS_COMPRESSION; # `yes' if gzip compression is available
  401. export _HAS_BZIP; # `yes' if bzip2 compression is available
  402. # _MAN_* finally used configuration of man searching
  403. export _MAN_ALL; # search all man pages per filespec
  404. export _MAN_ENABLE; # enable search for man pages
  405. export _MAN_EXT; # extension for man pages
  406. export _MAN_FORCE; # force file parameter to be man pages
  407. export _MAN_IS_SETUP; # setup man variables only once
  408. export _MAN_LANG; # language for man pages
  409. export _MAN_LANG2; # language for man pages
  410. export _MAN_LANG_DONE; # language dirs added to man path
  411. export _MAN_PATH; # search path for man pages
  412. export _MAN_SEC; # sections for man pages; sep. `:'
  413. export _MAN_SEC_DONE; # sections added to man path
  414. export _MAN_SYS; # system names for man pages; sep. `,'
  415. export _MAN_SYS; # system names added to man path
  416. # _MANOPT_* as parsed from $MANOPT
  417. export _MANOPT_ALL; # $MANOPT --all
  418. export _MANOPT_EXTENSION; # $MANOPT --extension
  419. export _MANOPT_LANG; # $MANOPT --locale
  420. export _MANOPT_PATH; # $MANOPT --manpath
  421. export _MANOPT_PAGER; # $MANOPT --pager
  422. export _MANOPT_SEC; # $MANOPT --sections
  423. export _MANOPT_SYS; # $MANOPT --systems
  424. # _OPT_* as parsed from groffer command line
  425. export _OPT_ALL; # display all suitable man pages.
  426. export _OPT_APROPOS; # call `apropos' program.
  427. export _OPT_BD; # set border color in some modes.
  428. export _OPT_BG; # set background color in some modes.
  429. export _OPT_BW; # set border width in some modes.
  430. export _OPT_DEFAULT_MODES; # `,'-list of modes when no mode given.
  431. export _OPT_DEVICE; # device option.
  432. export _OPT_DO_NOTHING; # do nothing in main_display().
  433. export _OPT_DISPLAY; # set X display.
  434. export _OPT_FG; # set foreground color in some modes.
  435. export _OPT_FN; # set font in some modes.
  436. export _OPT_GEOMETRY; # set size and position of viewer in X.
  437. export _OPT_ICONIC; # -iconic option for X viewers.
  438. export _OPT_LANG; # set language for man pages
  439. export _OPT_LOCATION; # print processed file names to stderr
  440. export _OPT_MODE; # values: X, tty, Q, Z, ""
  441. export _OPT_MANPATH; # manual setting of path for man-pages
  442. export _OPT_PAGER; # specify paging program for tty mode
  443. export _OPT_RESOLUTION; # set X resolution in dpi
  444. export _OPT_RV; # reverse fore- and background colors.
  445. export _OPT_SECTIONS; # sections for man page search
  446. export _OPT_SYSTEMS; # man pages of different OS's
  447. export _OPT_TITLE; # title for gxditview window
  448. export _OPT_TEXT_DEVICE; # set device for tty mode.
  449. export _OPT_V; # groff option -V.
  450. export _OPT_VIEWER_DVI; # viewer program for dvi mode
  451. export _OPT_VIEWER_PDF; # viewer program for pdf mode
  452. export _OPT_VIEWER_PS; # viewer program for ps mode
  453. export _OPT_VIEWER_HTML; # viewer program for html mode
  454. export _OPT_VIEWER_X; # viewer program for x mode
  455. export _OPT_WHATIS; # print the man description
  456. export _OPT_XRM; # specify X resource.
  457. export _OPT_Z; # groff option -Z.
  458. export _OUTPUT_FILE_NAME; # output generated, see main_set_res..()
  459. export _VIEWER_TERMINAL; # viewer options for terminal (--*-viewer-tty)
  460. # _TMP_* temporary directory and files
  461. export _TMP_DIR; # groffer directory for temporary files
  462. export _TMP_CAT; # stores concatenation of everything
  463. export _TMP_STDIN; # stores stdin, if any
  464. # these variables are preset in section `Preset' after the rudim. test
  465. ########################################################################
  466. # Preset and reset of read-write global variables
  467. ########################################################################
  468. export _START_DIR; # directory at start time of the script
  469. _START_DIR="$(pwd)";
  470. # For variables that can be reset by option `--default', see reset().
  471. _FILEARGS='';
  472. # _HAS_* from availability tests
  473. _HAS_COMPRESSION='';
  474. _HAS_BZIP='';
  475. # _TMP_* temporary files
  476. _TMP_DIR='';
  477. _TMP_CAT='';
  478. _TMP_CONF='';
  479. _TMP_STDIN='';
  480. ########################################################################
  481. # reset ()
  482. #
  483. # Reset the variables that can be affected by options to their default.
  484. #
  485. reset()
  486. {
  487. if test "$#" -ne 0
  488. then
  489. error "reset() does not have arguments.";
  490. fi;
  491. _ADDOPTS_GROFF='';
  492. _ADDOPTS_POST='';
  493. _ADDOPTS_X='';
  494. _APROPOS_PROG='';
  495. _APROPOS_SECTIONS='';
  496. _DISPLAY_ARGS='';
  497. _DISPLAY_MODE='';
  498. _DISPLAY_PROG='';
  499. _REGISTERED_TITLE='';
  500. # _MAN_* finally used configuration of man searching
  501. _MAN_ALL='no';
  502. _MAN_ENABLE='yes'; # do search for man-pages
  503. _MAN_EXT='';
  504. _MAN_FORCE='no'; # first local file, then search man page
  505. _MAN_IS_SETUP='no';
  506. _MAN_LANG='';
  507. _MAN_LANG2='';
  508. _MAN_PATH='';
  509. _MAN_SEC='';
  510. _MAN_SEC_DONE='no';
  511. _MAN_SYS='';
  512. _MAN_SYS_DONE='no';
  513. # _MANOPT_* as parsed from $MANOPT
  514. _MANOPT_ALL='no';
  515. _MANOPT_EXTENSION='';
  516. _MANOPT_LANG='';
  517. _MANOPT_PATH='';
  518. _MANOPT_PAGER='';
  519. _MANOPT_SEC='';
  520. _MANOPT_SYS='';
  521. # _OPT_* as parsed from groffer command line
  522. _OPT_ALL='no';
  523. _OPT_APROPOS='no';
  524. _OPT_BD='';
  525. _OPT_BG='';
  526. _OPT_BW='';
  527. _OPT_DEFAULT_MODES='';
  528. _OPT_DEVICE='';
  529. _OPT_DISPLAY='';
  530. _OPT_DO_NOTHING='no';
  531. _OPT_FG='';
  532. _OPT_FN='';
  533. _OPT_GEOMETRY='';
  534. _OPT_ICONIC='no';
  535. _OPT_LANG='';
  536. _OPT_LOCATION='no';
  537. _OPT_MODE='';
  538. _OPT_MANPATH='';
  539. _OPT_PAGER='';
  540. _OPT_RESOLUTION='';
  541. _OPT_RV='no';
  542. _OPT_SECTIONS='';
  543. _OPT_SYSTEMS='';
  544. _OPT_TITLE='';
  545. _OPT_TEXT_DEVICE='';
  546. _OPT_V='no';
  547. _OPT_VIEWER_DVI='';
  548. _OPT_VIEWER_PDF='';
  549. _OPT_VIEWER_PS='';
  550. _OPT_VIEWER_HTML='';
  551. _OPT_VIEWER_X='';
  552. _OPT_WHATIS='no';
  553. _OPT_XRM='';
  554. _OPT_Z='no';
  555. _VIEWER_TERMINAL='no';
  556. }
  557. reset;
  558. ########################################################################
  559. # Functions for error handling and debugging
  560. ########################################################################
  561. ##############
  562. # echo1 (<text>*)
  563. #
  564. # Output to stdout.
  565. #
  566. # Arguments : arbitrary text including `-'.
  567. #
  568. echo1()
  569. {
  570. cat <<EOF
  571. $@
  572. EOF
  573. }
  574. ##############
  575. # echo2 (<text>*)
  576. #
  577. # Output to stderr.
  578. #
  579. # Arguments : arbitrary text.
  580. #
  581. echo2()
  582. {
  583. cat >&2 <<EOF
  584. $@
  585. EOF
  586. }
  587. ##############
  588. # landmark (<text>)
  589. #
  590. # Print <text> to standard error as a debugging aid.
  591. #
  592. # Globals: $_DEBUG_LM
  593. #
  594. landmark()
  595. {
  596. if test _"${_DEBUG_LM}"_ = _yes_
  597. then
  598. echo2 "LM: $*";
  599. fi;
  600. }
  601. landmark "1: debugging functions";
  602. ##############
  603. # clean_up ()
  604. #
  605. # Clean up at exit.
  606. #
  607. clean_up()
  608. {
  609. cd "${_START_DIR}" >"${_NULL_DEV}" 2>&1;
  610. if test _${_DEBUG_KEEP_FILES}_ = _yes_
  611. then
  612. echo2 "Kept temporary directory ${_TMP_DIR}."
  613. else
  614. if test _"${_TMP_DIR}"_ != __
  615. then
  616. if test -d "${_TMP_DIR}" || test -f "${_TMP_DIR}"
  617. then
  618. rm -f -r "${_TMP_DIR}" >${_NULL_DEV} 2>&1;
  619. fi;
  620. fi;
  621. fi;
  622. }
  623. #############
  624. # diag (text>*)
  625. #
  626. # Output a diagnostic message to stderr
  627. #
  628. diag()
  629. {
  630. echo2 '>>>>>'"$*";
  631. }
  632. #############
  633. # error (<text>*)
  634. #
  635. # Print an error message to standard error, print the function stack,
  636. # exit with an error condition. The argument should contain the name
  637. # of the function from which it was called. This is for system errors.
  638. #
  639. error()
  640. {
  641. case "$#" in
  642. 1) echo2 'groffer error: '"$1"; ;;
  643. *) echo2 'groffer error: wrong number of arguments in error().'; ;;
  644. esac;
  645. func_stack_dump;
  646. if test _"${_TMP_DIR}"_ != __ && test -d "${_TMP_DIR}"
  647. then
  648. : >"${_TMP_DIR}"/,error;
  649. fi;
  650. exit "${_ERROR}";
  651. }
  652. #############
  653. # error_user (<text>*)
  654. #
  655. # Print an error message to standard error; exit with an error condition.
  656. # The error is supposed to be produce by the user. So the funtion stack
  657. # is omitted.
  658. #
  659. error_user()
  660. {
  661. case "$#" in
  662. 1)
  663. echo2 'groffer error: '"$1";
  664. ;;
  665. *)
  666. echo2 'groffer error: wrong number of arguments in error_user().';
  667. ;;
  668. esac;
  669. if test _"${_DEBUG_USER_WITH_STACK}"_ = _yes_
  670. then
  671. func_stack_dump;
  672. fi;
  673. if test _"${_TMP_DIR}"_ != __ && test -d "${_TMP_DIR}"
  674. then
  675. : >"${_TMP_DIR}"/,error;
  676. fi;
  677. exit "${_ERROR}";
  678. }
  679. #############
  680. # exit_test ()
  681. #
  682. # Test whether the former command ended with error(). Exit again.
  683. #
  684. # Globals: $_ERROR
  685. #
  686. exit_test()
  687. {
  688. if test "$?" = "${_ERROR}"
  689. then
  690. exit ${_ERROR};
  691. fi;
  692. if test _"${_TMP_DIR}"_ != __ && test -f "${_TMP_DIR}"/,error
  693. then
  694. exit ${_ERROR};
  695. fi;
  696. }
  697. #############
  698. # func_check (<func_name> <rel_op> <nr_args> "$@")
  699. #
  700. # Check number of arguments and register to _FUNC_STACK.
  701. #
  702. # Arguments: >=3
  703. # <func_name>: name of the calling function.
  704. # <rel_op>: a relational operator: = != < > <= >=
  705. # <nr_args>: number of arguments to be checked against <operator>
  706. # "$@": the arguments of the calling function.
  707. #
  708. # Variable prefix: fc
  709. #
  710. func_check()
  711. {
  712. if test "$#" -lt 3
  713. then
  714. error 'func_check() needs at least 3 arguments.';
  715. fi;
  716. fc_fname="$1";
  717. case "$3" in
  718. 1)
  719. fc_nargs="$3";
  720. fc_s='';
  721. ;;
  722. 0|[2-9])
  723. fc_nargs="$3";
  724. fc_s='s';
  725. ;;
  726. *)
  727. error "func_check(): third argument must be a digit.";
  728. ;;
  729. esac;
  730. case "$2" in
  731. '='|'-eq')
  732. fc_op='-eq';
  733. fc_comp='exactly';
  734. ;;
  735. '>='|'-ge')
  736. fc_op='-ge';
  737. fc_comp='at least';
  738. ;;
  739. '<='|'-le')
  740. fc_op='-le';
  741. fc_comp='at most';
  742. ;;
  743. '<'|'-lt')
  744. fc_op='-lt';
  745. fc_comp='less than';
  746. ;;
  747. '>'|'-gt')
  748. fc_op='-gt';
  749. fc_comp='more than';
  750. ;;
  751. '!='|'-ne')
  752. fc_op='-ne';
  753. fc_comp='not';
  754. ;;
  755. *)
  756. error \
  757. 'func_check(): second argument is not a relational operator.';
  758. ;;
  759. esac;
  760. shift;
  761. shift;
  762. shift;
  763. if test "$#" "${fc_op}" "${fc_nargs}"
  764. then
  765. do_nothing;
  766. else
  767. error "func_check(): \
  768. ${fc_fname}"'() needs '"${fc_comp} ${fc_nargs}"' argument'"${fc_s}"'.';
  769. fi;
  770. func_push "${fc_fname}";
  771. if test _"${_DEBUG_STACKS}"_ = _yes_
  772. then
  773. echo2 '+++ '"${fc_fname} $@";
  774. echo2 '>>> '"${_FUNC_STACK}";
  775. fi;
  776. eval ${_UNSET} fc_comp;
  777. eval ${_UNSET} fc_fname;
  778. eval ${_UNSET} fc_nargs;
  779. eval ${_UNSET} fc_op;
  780. eval ${_UNSET} fc_s;
  781. }
  782. #############
  783. # func_pop ()
  784. #
  785. # Retrieve the top element from the stack.
  786. #
  787. # The stack elements are separated by `!'; the popped element is
  788. # identical to the original element, except that all `!' characters
  789. # were removed.
  790. #
  791. # Arguments: 1
  792. #
  793. func_pop()
  794. {
  795. if test "$#" -ne 0
  796. then
  797. error 'func_pop() does not have arguments.';
  798. fi;
  799. case "${_FUNC_STACK}" in
  800. '')
  801. if test _"${_DEBUG_STACKS}"_ = _yes_
  802. then
  803. error 'func_pop(): stack is empty.';
  804. fi;
  805. ;;
  806. *!*)
  807. # split at first bang `!'.
  808. _FUNC_STACK="$(echo1 "${_FUNC_STACK}" | sed -e 's/^[^!]*!//')";
  809. exit_test;
  810. ;;
  811. *)
  812. _FUNC_STACK='';
  813. ;;
  814. esac;
  815. if test _"${_DEBUG_STACKS}"_ = _yes_
  816. then
  817. echo2 '<<< '"${_FUNC_STACK}";
  818. fi;
  819. }
  820. #############
  821. # func_push (<element>)
  822. #
  823. # Store another element to stack.
  824. #
  825. # The stack elements are separated by `!'; if <element> contains a `!'
  826. # it is removed first.
  827. #
  828. # Arguments: 1
  829. #
  830. # Variable prefix: fp
  831. #
  832. func_push()
  833. {
  834. if test "$#" -ne 1
  835. then
  836. error 'func_push() needs 1 argument.';
  837. fi;
  838. case "$1" in
  839. *'!'*)
  840. # remove all bangs `!'.
  841. fp_element="$(echo1 "$1" | sed -e 's/!//g')";
  842. exit_test;
  843. ;;
  844. *)
  845. fp_element="$1";
  846. ;;
  847. esac;
  848. if test _"${_FUNC_STACK}"_ = __
  849. then
  850. _FUNC_STACK="${fp_element}";
  851. else
  852. _FUNC_STACK="${fp_element}!${_FUNC_STACK}";
  853. fi;
  854. eval ${_UNSET} fp_element;
  855. }
  856. #############
  857. # func_stack_dump ()
  858. #
  859. # Print the content of the stack. Ignore the arguments.
  860. #
  861. func_stack_dump()
  862. {
  863. diag 'call stack: '"${_FUNC_STACK}";
  864. }
  865. ########################################################################
  866. # System Test
  867. ########################################################################
  868. landmark "2: system test";
  869. # Test the availability of the system utilities used in this script.
  870. ########################################################################
  871. # Test of function `sed'.
  872. #
  873. if test _"$(echo xTesTx \
  874. | sed -e 's/^.\([Tt]e*x*sTT*\).*$/\1/' \
  875. | sed -e 's|T|t|g')"_ != _test_
  876. then
  877. error 'Test of "sed" command failed.';
  878. fi;
  879. ########################################################################
  880. # Test of function `cat'.
  881. #
  882. if test _"$(echo test | cat)"_ != _test_
  883. then
  884. error 'Test of "cat" command failed.';
  885. fi;
  886. ########################################################################
  887. # Test for compression.
  888. #
  889. if test _"$(echo 'test' | gzip -c -d -f - 2>${_NULL_DEV})"_ = _test_
  890. then
  891. _HAS_COMPRESSION='yes';
  892. if echo1 'test' | bzip2 -c 2>${_NULL_DEV} | bzip2 -t 2>${_NULL_DEV} \
  893. && test _"$(echo 'test' | bzip2 -c 2>${_NULL_DEV} \
  894. | bzip2 -d -c 2>${_NULL_DEV})"_ \
  895. = _test_
  896. then
  897. _HAS_BZIP='yes';
  898. else
  899. _HAS_BZIP='no';
  900. fi;
  901. else
  902. _HAS_COMPRESSION='no';
  903. _HAS_BZIP='no';
  904. fi;
  905. ########################################################################
  906. # Definition of normal Functions in alphabetical order
  907. ########################################################################
  908. landmark "3: functions";
  909. ########################################################################
  910. # apropos_filespec ()
  911. #
  912. # Setup for the --apropos* options
  913. #
  914. apropos_filespec()
  915. {
  916. func_check apropos_filespec '=' 0 "$@";
  917. if obj _OPT_APROPOS is_yes
  918. then
  919. eval to_tmp_line \
  920. "'.SH $(echo1 "${_FILESPEC_ARG}" | sed 's/[^\\]-/\\-/g')'";
  921. exit_test;
  922. if obj _APROPOS_PROG is_empty
  923. then
  924. error 'apropos_filespec: apropos_setup() must be run first.';
  925. fi;
  926. if obj _APROPOS_SECTIONS is_empty
  927. then
  928. if obj _OPT_SECTIONS is_empty
  929. then
  930. s='^.*(.*).*$';
  931. else
  932. s='^.*(['"$(echo1 "${_OPT_SECTIONS}" | sed -e 's/://g')"']';
  933. fi;
  934. else
  935. s='^.*(['"${_APROPOS_SECTIONS}"']';
  936. fi;
  937. eval "${_APROPOS_PROG}" "'${_FILESPEC_ARG}'" | \
  938. sed -n -e '
  939. /^'"${_FILESPEC_ARG}"': /p
  940. /'"$s"'/p
  941. ' | \
  942. sort |\
  943. sed -e '
  944. s/^\(.* (..*)\) *- *\(.*\)$/\.br\n\.TP 15\n\.BR \1\n\2/
  945. ' >>"${_TMP_CAT}";
  946. fi;
  947. eval "${return_ok}";
  948. }
  949. ########################################################################
  950. # apropos_setup ()
  951. #
  952. # Setup for the --apropos* options
  953. #
  954. apropos_setup()
  955. {
  956. func_check apropos_setup '=' 0 "$@";
  957. if obj _OPT_APROPOS is_yes
  958. then
  959. if is_prog apropos
  960. then
  961. _APROPOS_PROG='apropos';
  962. elif is_prog man
  963. then
  964. if man --apropos man >${_NULL_DEV} 2>${_NULL_DEV}
  965. then
  966. _APROPOS_PROG='man --apropos';
  967. elif man -k man >${_NULL_DEV} 2>${_NULL_DEV}
  968. then
  969. _APROPOS_PROG='man -k';
  970. fi;
  971. fi;
  972. if obj _APROPOS_PROG is_empty
  973. then
  974. error 'apropos_setup: no apropos program available.';
  975. fi;
  976. to_tmp_line '.TH GROFFER APROPOS';
  977. fi;
  978. eval "${return_ok}";
  979. }
  980. ########################################################################
  981. # base_name (<path>)
  982. #
  983. # Get the file name part of <path>, i.e. delete everything up to last
  984. # `/' from the beginning of <path>. Remove final slashes, too, to get a
  985. # non-empty output.
  986. #
  987. # Arguments : 1
  988. # Output : the file name part (without slashes)
  989. #
  990. # Variable prefix: bn
  991. #
  992. base_name()
  993. {
  994. func_check base_name = 1 "$@";
  995. bn_name="$1";
  996. case "${bn_name}" in
  997. */)
  998. # delete all final slashes
  999. bn_name="$(echo1 "${bn_name}" | sed -e 's|//*$||')";
  1000. exit_test;
  1001. ;;
  1002. esac;
  1003. case "${bn_name}" in
  1004. /|'')
  1005. eval ${_UNSET} bn_name;
  1006. eval "${return_bad}";
  1007. ;;
  1008. */*)
  1009. # delete everything before and including the last slash `/'.
  1010. echo1 "${bn_name}" | sed -e 's|^.*//*\([^/]*\)$|\1|';
  1011. ;;
  1012. *)
  1013. obj bn_name echo1;
  1014. ;;
  1015. esac;
  1016. eval ${_UNSET} bn_name;
  1017. eval "${return_ok}";
  1018. }
  1019. ########################################################################
  1020. # cat_z (<file>)
  1021. #
  1022. # Decompress if possible or just print <file> to standard output.
  1023. #
  1024. # gzip, bzip2, and .Z decompression is supported.
  1025. #
  1026. # Arguments: 1, a file name.
  1027. # Output: the content of <file>, possibly decompressed.
  1028. #
  1029. if test _"${_HAS_COMPRESSION}"_ = _yes_
  1030. then
  1031. cat_z()
  1032. {
  1033. func_check cat_z = 1 "$@";
  1034. case "$1" in
  1035. '')
  1036. error 'cat_z(): empty file name';
  1037. ;;
  1038. '-')
  1039. error 'cat_z(): for standard input use save_stdin()';
  1040. ;;
  1041. esac;
  1042. if obj _HAS_BZIP is_yes
  1043. then
  1044. if bzip2 -t "$1" 2>${_NULL_DEV}
  1045. then
  1046. bzip2 -c -d "$1" 2>${_NULL_DEV};
  1047. eval "${return_ok}";
  1048. fi;
  1049. fi;
  1050. gzip -c -d -f "$1" 2>${_NULL_DEV};
  1051. eval "${return_ok}";
  1052. }
  1053. else
  1054. cat_z()
  1055. {
  1056. func_check cat_z = 1 "$@";
  1057. cat "$1";
  1058. eval "${return_ok}";
  1059. }
  1060. fi;
  1061. ########################################################################
  1062. # clean_up ()
  1063. #
  1064. # Do the final cleaning up before exiting; used by the trap calls.
  1065. #
  1066. # defined above
  1067. ########################################################################
  1068. # diag (<text>*)
  1069. #
  1070. # Print marked message to standard error; useful for debugging.
  1071. #
  1072. # defined above
  1073. ########################################################################
  1074. landmark '4: dirname()*';
  1075. ########################################################################
  1076. #######################################################################
  1077. # dirname_append (<dir> <name>)
  1078. #
  1079. # Append `name' to `dir' with clean handling of `/'.
  1080. #
  1081. # Arguments : 2
  1082. # Output : the generated new directory name <dir>/<name>
  1083. #
  1084. dirname_append()
  1085. {
  1086. func_check dirname_append = 2 "$@";
  1087. if is_empty "$1"
  1088. then
  1089. error "dir_append(): first argument is empty.";
  1090. fi;
  1091. if is_empty "$2"
  1092. then
  1093. echo1 "$1";
  1094. else
  1095. dirname_chop "$1"/"$2";
  1096. fi;
  1097. eval "${return_ok}";
  1098. }
  1099. ########################################################################
  1100. # dirname_chop (<name>)
  1101. #
  1102. # Remove unnecessary slashes from directory name.
  1103. #
  1104. # Argument: 1, a directory name.
  1105. # Output: path without double, or trailing slashes.
  1106. #
  1107. # Variable prefix: dc
  1108. #
  1109. dirname_chop()
  1110. {
  1111. func_check dirname_chop = 1 "$@";
  1112. # replace all multiple slashes by a single slash `/'.
  1113. dc_res="$(echo1 "$1" | sed -e 's|///*|/|g')";
  1114. exit_test;
  1115. case "${dc_res}" in
  1116. ?*/)
  1117. # remove trailing slash '/';
  1118. echo1 "${dc_res}" | sed -e 's|/$||';
  1119. ;;
  1120. *)
  1121. obj dc_res echo1
  1122. ;;
  1123. esac;
  1124. eval ${_UNSET} dc_res;
  1125. eval "${return_ok}";
  1126. }
  1127. ########################################################################
  1128. # do_filearg (<filearg>)
  1129. #
  1130. # Append the file, man-page, or standard input corresponding to the
  1131. # argument to the temporary file. If this is compressed in the gzip
  1132. # or Z format it is decompressed. A title element is generated.
  1133. #
  1134. # Argument either:
  1135. # - name of an existing file.
  1136. # - `-' to represent standard input (several times allowed).
  1137. # - `man:name.(section)' the man-page for `name' in `section'.
  1138. # - `man:name.section' the man-page for `name' in `section'.
  1139. # - `man:name' the man-page for `name' in the lowest `section'.
  1140. # - `name.section' the man-page for `name' in `section'.
  1141. # - `name' the man-page for `name' in the lowest `section'.
  1142. # Globals :
  1143. # $_TMP_STDIN, $_MAN_ENABLE, $_MAN_IS_SETUP, $_OPT_MAN
  1144. #
  1145. # Output : none
  1146. # Return : $_GOOD if found, ${_BAD} otherwise.
  1147. #
  1148. # Variable prefix: df
  1149. #
  1150. do_filearg()
  1151. {
  1152. func_check do_filearg = 1 "$@";
  1153. df_filespec="$1";
  1154. # store sequence into positional parameters
  1155. case "${df_filespec}" in
  1156. '')
  1157. eval ${_UNSET} df_filespec;
  1158. eval "${return_good}";
  1159. ;;
  1160. '-')
  1161. register_file '-';
  1162. eval ${_UNSET} df_filespec;
  1163. eval "${return_good}";
  1164. ;;
  1165. */*) # with directory part; so no man search
  1166. set 'File';
  1167. ;;
  1168. *)
  1169. if obj _MAN_ENABLE is_yes
  1170. then
  1171. if obj _MAN_FORCE is_yes
  1172. then
  1173. set 'Manpage' 'File';
  1174. else
  1175. set 'File' 'Manpage';
  1176. fi;
  1177. else
  1178. set 'File';
  1179. fi;
  1180. ;;
  1181. esac;
  1182. for i
  1183. do
  1184. case "$i" in
  1185. File)
  1186. if test -f "${df_filespec}"
  1187. then
  1188. if test -r "${df_filespec}"
  1189. then
  1190. register_file "${df_filespec}";
  1191. eval ${_UNSET} df_filespec;
  1192. eval ${_UNSET} df_no_man;
  1193. eval "${return_good}";
  1194. else
  1195. echo2 "could not read \`${df_filespec}'";
  1196. eval ${_UNSET} df_filespec;
  1197. eval ${_UNSET} df_no_man;
  1198. eval "${return_bad}";
  1199. fi;
  1200. else
  1201. if obj df_no_man is_not_empty
  1202. then
  1203. if obj _OPT_WHATIS is_yes
  1204. then
  1205. to_tmp_line "This is neither a file nor a man page."
  1206. else
  1207. echo2 "\`${df_filespec}' is neither a file nor a man page."
  1208. fi;
  1209. fi;
  1210. df_no_file=yes;
  1211. continue;
  1212. fi;
  1213. ;;
  1214. Manpage) # parse filespec as man page
  1215. if obj _MAN_IS_SETUP is_not_yes
  1216. then
  1217. man_setup;
  1218. fi;
  1219. if man_do_filespec "${df_filespec}"
  1220. then
  1221. eval ${_UNSET} df_filespec;
  1222. eval ${_UNSET} df_no_file;
  1223. eval "${return_good}";
  1224. else
  1225. if obj df_no_file is_not_empty
  1226. then
  1227. if obj _OPT_WHATIS is_yes
  1228. then
  1229. to_tmp_line "This is neither a file nor a man page."
  1230. else
  1231. echo2 "\`${df_filespec}' is neither a file nor a man page."
  1232. fi;
  1233. fi;
  1234. df_no_man=yes;
  1235. continue;
  1236. fi;
  1237. ;;
  1238. esac;
  1239. done;
  1240. eval ${_UNSET} df_filespec;
  1241. eval ${_UNSET} df_no_file;
  1242. eval ${_UNSET} df_no_man;
  1243. eval "${return_bad}";
  1244. } # do_filearg()
  1245. ########################################################################
  1246. # do_nothing ()
  1247. #
  1248. # Dummy function.
  1249. #
  1250. do_nothing()
  1251. {
  1252. eval return "${_OK}";
  1253. }
  1254. ########################################################################
  1255. # echo2 (<text>*)
  1256. #
  1257. # Print to standard error with final line break.
  1258. #
  1259. # defined above
  1260. ########################################################################
  1261. # error (<text>*)
  1262. #
  1263. # Print error message and exit with error code.
  1264. #
  1265. # defined above
  1266. ########################################################################
  1267. # exit_test ()
  1268. #
  1269. # Test whether the former command ended with error(). Exit again.
  1270. #
  1271. # defined above
  1272. ########################################################################
  1273. # func_check (<func_name> <rel_op> <nr_args> "$@")
  1274. #
  1275. # Check number of arguments and register to _FUNC_STACK.
  1276. #
  1277. # Arguments: >=3
  1278. # <func_name>: name of the calling function.
  1279. # <rel_op>: a relational operator: = != < > <= >=
  1280. # <nr_args>: number of arguments to be checked against <operator>
  1281. # "$@": the arguments of the calling function.
  1282. #
  1283. # defined above
  1284. #########################################################################
  1285. # func_pop ()
  1286. #
  1287. # Delete the top element from the function call stack.
  1288. #
  1289. # defined above
  1290. ########################################################################
  1291. # func_push (<element>)
  1292. #
  1293. # Store another element to function call stack.
  1294. #
  1295. # defined above
  1296. ########################################################################
  1297. # func_stack_dump ()
  1298. #
  1299. # Print the content of the stack.
  1300. #
  1301. # defined above
  1302. ########################################################################
  1303. # get_first_essential (<arg>*)
  1304. #
  1305. # Retrieve first non-empty argument.
  1306. #
  1307. # Return : `1' if all arguments are empty, `0' if found.
  1308. # Output : the retrieved non-empty argument.
  1309. #
  1310. # Variable prefix: gfe
  1311. #
  1312. get_first_essential()
  1313. {
  1314. func_check get_first_essential '>=' 0 "$@";
  1315. if is_equal "$#" 0
  1316. then
  1317. eval "${return_ok}";
  1318. fi;
  1319. for i
  1320. do
  1321. gfe_var="$i";
  1322. if obj gfe_var is_not_empty
  1323. then
  1324. obj gfe_var echo1;
  1325. eval ${_UNSET} gfe_var;
  1326. eval "${return_ok}";
  1327. fi;
  1328. done;
  1329. eval ${_UNSET} gfe_var;
  1330. eval "${return_bad}";
  1331. }
  1332. ########################################################################
  1333. landmark '5: is_*()';
  1334. ########################################################################
  1335. ########################################################################
  1336. # is_dir (<name>)
  1337. #
  1338. # Test whether `name' is a directory.
  1339. #
  1340. # Arguments : 1
  1341. # Return : `0' if arg1 is a directory, `1' otherwise.
  1342. #
  1343. is_dir()
  1344. {
  1345. func_check is_dir '=' 1 "$@";
  1346. if test _"$1"_ != __ && test -d "$1" && test -r "$1"
  1347. then
  1348. eval "${return_yes}";
  1349. fi;
  1350. eval "${return_no}";
  1351. }
  1352. ########################################################################
  1353. # is_empty (<string>)
  1354. #
  1355. # Test whether `string' is empty.
  1356. #
  1357. # Arguments : <=1
  1358. # Return : `0' if arg1 is empty or does not exist, `1' otherwise.
  1359. #
  1360. is_empty()
  1361. {
  1362. func_check is_empty '=' 1 "$@";
  1363. if test _"$1"_ = __
  1364. then
  1365. eval "${return_yes}";
  1366. fi;
  1367. eval "${return_no}";
  1368. }
  1369. ########################################################################
  1370. # is_equal (<string1> <string2>)
  1371. #
  1372. # Test whether `string1' is equal to <string2>.
  1373. #
  1374. # Arguments : 2
  1375. # Return : `0' both arguments are equal strings, `1' otherwise.
  1376. #
  1377. is_equal()
  1378. {
  1379. func_check is_equal '=' 2 "$@";
  1380. if test _"$1"_ = _"$2"_
  1381. then
  1382. eval "${return_yes}";
  1383. fi;
  1384. eval "${return_no}";
  1385. }
  1386. ########################################################################
  1387. # is_existing (<name>)
  1388. #
  1389. # Test whether `name' is an existing file or directory. Solaris 2.5 does
  1390. # not have `test -e'.
  1391. #
  1392. # Arguments : 1
  1393. # Return : `0' if arg1 exists, `1' otherwise.
  1394. #
  1395. is_existing()
  1396. {
  1397. func_check is_existing '=' 1 "$@";
  1398. if test _"$1"_ = __
  1399. then
  1400. eval "${return_no}";
  1401. fi;
  1402. if test -f "$1" || test -d "$1" || test -c "$1"
  1403. then
  1404. eval "${return_yes}";
  1405. fi;
  1406. eval "${return_no}";
  1407. }
  1408. ########################################################################
  1409. # is_file (<name>)
  1410. #
  1411. # Test whether `name' is a readable file.
  1412. #
  1413. # Arguments : 1
  1414. # Return : `0' if arg1 is a readable file, `1' otherwise.
  1415. #
  1416. is_file()
  1417. {
  1418. func_check is_file '=' 1 "$@";
  1419. if is_not_empty "$1" && test -f "$1" && test -r "$1"
  1420. then
  1421. eval "${return_yes}";
  1422. fi;
  1423. eval "${return_no}";
  1424. }
  1425. ########################################################################
  1426. # is_non_empty_file (<file_name>)
  1427. #
  1428. # Test whether `file_name' is a non-empty existing file.
  1429. #
  1430. # Arguments : <=1
  1431. # Return :
  1432. # `0' if arg1 is a non-empty existing file
  1433. # `1' otherwise
  1434. #
  1435. is_non_empty_file()
  1436. {
  1437. func_check is_non_empty_file '=' 1 "$@";
  1438. if is_file "$1" && test -s "$1"
  1439. then
  1440. eval "${return_yes}";
  1441. fi;
  1442. eval "${return_no}";
  1443. }
  1444. ########################################################################
  1445. # is_not_dir (<name>)
  1446. #
  1447. # Test whether `name' is not a readable directory.
  1448. #
  1449. # Arguments : 1
  1450. # Return : `0' if arg1 is a directory, `1' otherwise.
  1451. #
  1452. is_not_dir()
  1453. {
  1454. func_check is_not_dir '=' 1 "$@";
  1455. if is_dir "$1"
  1456. then
  1457. eval "${return_no}";
  1458. fi;
  1459. eval "${return_yes}";
  1460. }
  1461. ########################################################################
  1462. # is_not_empty (<string>)
  1463. #
  1464. # Test whether `string' is not empty.
  1465. #
  1466. # Arguments : <=1
  1467. # Return : `0' if arg1 exists and is not empty, `1' otherwise.
  1468. #
  1469. is_not_empty()
  1470. {
  1471. func_check is_not_empty '=' 1 "$@";
  1472. if is_empty "$1"
  1473. then
  1474. eval "${return_no}";
  1475. fi;
  1476. eval "${return_yes}";
  1477. }
  1478. ########################################################################
  1479. # is_not_equal (<string1> <string2>)
  1480. #
  1481. # Test whether `string1' differs from `string2'.
  1482. #
  1483. # Arguments : 2
  1484. #
  1485. is_not_equal()
  1486. {
  1487. func_check is_not_equal '=' 2 "$@";
  1488. if is_equal "$1" "$2"
  1489. then
  1490. eval "${return_no}";
  1491. fi
  1492. eval "${return_yes}";
  1493. }
  1494. ########################################################################
  1495. # is_not_file (<filename>)
  1496. #
  1497. # Test whether `name' is a not readable file.
  1498. #
  1499. # Arguments : 1 (empty allowed)
  1500. #
  1501. is_not_file()
  1502. {
  1503. func_check is_not_file '=' 1 "$@";
  1504. if is_file "$1"
  1505. then
  1506. eval "${return_no}";
  1507. fi;
  1508. eval "${return_yes}";
  1509. }
  1510. ########################################################################
  1511. # is_not_prog ([<name> [<arg>*]])
  1512. #
  1513. # Verify that arg is a not program in $PATH.
  1514. #
  1515. # Arguments : >=0 (empty allowed)
  1516. # more args are ignored, this allows to specify progs with arguments
  1517. #
  1518. is_not_prog()
  1519. {
  1520. func_check is_not_prog '>=' 0 "$@";
  1521. case "$#" in
  1522. 0)
  1523. eval "${return_yes}";
  1524. ;;
  1525. *)
  1526. if where_is "$1" >${_NULL_DEV}
  1527. then
  1528. eval "${return_no}";
  1529. fi;
  1530. ;;
  1531. esac
  1532. eval "${return_yes}";
  1533. }
  1534. ########################################################################
  1535. # is_not_writable (<name>)
  1536. #
  1537. # Test whether `name' is a not a writable file or directory.
  1538. #
  1539. # Arguments : >=1 (empty allowed), more args are ignored
  1540. #
  1541. is_not_writable()
  1542. {
  1543. func_check is_not_writable '>=' 1 "$@";
  1544. if is_writable "$1"
  1545. then
  1546. eval "${return_no}";
  1547. fi;
  1548. eval "${return_yes}";
  1549. }
  1550. ########################################################################
  1551. # is_not_X ()
  1552. #
  1553. # Test whether not running in X Window by checking $DISPLAY
  1554. #
  1555. is_not_X()
  1556. {
  1557. func_check is_X '=' 0 "$@";
  1558. if obj DISPLAY is_empty
  1559. then
  1560. eval "${return_yes}";
  1561. fi;
  1562. eval "${return_no}";
  1563. }
  1564. ########################################################################
  1565. # is_not_yes (<string>)
  1566. #
  1567. # Test whether `string' is not "yes".
  1568. #
  1569. # Arguments : 1
  1570. #
  1571. is_not_yes()
  1572. {
  1573. func_check is_not_yes = 1 "$@";
  1574. if is_yes "$1"
  1575. then
  1576. eval "${return_no}";
  1577. fi;
  1578. eval "${return_yes}";
  1579. }
  1580. ########################################################################
  1581. # is_prog ([<name> [<arg>*]])
  1582. #
  1583. # Determine whether <name> is a program in $PATH
  1584. #
  1585. # Arguments : >=0 (empty allowed)
  1586. # <arg>* are ignored, this allows to specify progs with arguments.
  1587. #
  1588. is_prog()
  1589. {
  1590. func_check is_prog '>=' 0 "$@";
  1591. case "$#" in
  1592. 0)
  1593. eval "${return_no}";
  1594. ;;
  1595. *)
  1596. if where_is "$1" >${_NULL_DEV}
  1597. then
  1598. eval "${return_yes}";
  1599. fi;
  1600. ;;
  1601. esac
  1602. eval "${return_no}";
  1603. }
  1604. ########################################################################
  1605. # is_writable (<name>)
  1606. #
  1607. # Test whether `name' is a writable file or directory.
  1608. #
  1609. # Arguments : >=1 (empty allowed), more args are ignored
  1610. #
  1611. is_writable()
  1612. {
  1613. func_check is_writable '>=' 1 "$@";
  1614. if test _"$1"_ = __
  1615. then
  1616. eval "${return_no}";
  1617. fi;
  1618. if test -r "$1"
  1619. then
  1620. if test -w "$1"
  1621. then
  1622. eval "${return_yes}";
  1623. fi;
  1624. fi;
  1625. eval "${return_no}";
  1626. }
  1627. ########################################################################
  1628. # is_X ()
  1629. #
  1630. # Test whether running in X Window by checking $DISPLAY
  1631. #
  1632. is_X()
  1633. {
  1634. func_check is_X '=' 0 "$@";
  1635. if obj DISPLAY is_not_empty
  1636. then
  1637. eval "${return_yes}";
  1638. fi;
  1639. eval "${return_no}";
  1640. }
  1641. ########################################################################
  1642. # is_yes (<string>)
  1643. #
  1644. # Test whether `string' has value "yes".
  1645. #
  1646. # Return : `0' if arg1 is `yes', `1' otherwise.
  1647. #
  1648. is_yes()
  1649. {
  1650. func_check is_yes '=' 1 "$@";
  1651. if is_equal "$1" 'yes'
  1652. then
  1653. eval "${return_yes}";
  1654. fi;
  1655. eval "${return_no}";
  1656. }
  1657. ########################################################################
  1658. # landmark ()
  1659. #
  1660. # Print debugging information on standard error if $_DEBUG_LM is `yes'.
  1661. #
  1662. # Globals: $_DEBUG_LM
  1663. #
  1664. # Defined in section `Debugging functions'.
  1665. ########################################################################
  1666. # leave ([<code>])
  1667. #
  1668. # Clean exit without an error or with <code>.
  1669. #
  1670. leave()
  1671. {
  1672. clean_up;
  1673. if test $# = 0
  1674. then
  1675. exit "${_OK}";
  1676. else
  1677. exit "$1";
  1678. fi;
  1679. }
  1680. ########################################################################
  1681. landmark '6: list_*()';
  1682. ########################################################################
  1683. #
  1684. # `list' is an object class that represents an array or list. Its
  1685. # data consists of space-separated single-quoted elements. So a list
  1686. # has the form "'first' 'second' '...' 'last'". See list_append() for
  1687. # more details on the list structure. The array elements of `list'
  1688. # can be get by `eval set x "$list"; shift`.
  1689. ########################################################################
  1690. # list_append (<list> <element>...)
  1691. #
  1692. # Arguments: >=2
  1693. # <list>: a variable name for a list of single-quoted elements
  1694. # <element>: some sequence of characters.
  1695. # Output: none, but $<list> is set to
  1696. # if <list> is empty: "'<element>' '...'"
  1697. # otherwise: "$list '<element>' ..."
  1698. #
  1699. # Variable prefix: la
  1700. #
  1701. list_append()
  1702. {
  1703. func_check list_append '>=' 2 "$@";
  1704. la_name="$1";
  1705. eval la_list='"${'$1'}"';
  1706. shift;
  1707. for s
  1708. do
  1709. la_s="$s";
  1710. case "${la_s}" in
  1711. *\'*)
  1712. # escape each single quote by replacing each
  1713. # "'" (squote) by "'\''" (squote bslash squote squote);
  1714. # note that the backslash must be doubled in the following `sed'
  1715. la_element="$(echo1 "${la_s}" | sed -e 's/'"${_SQ}"'/&\\&&/g')";
  1716. exit_test;
  1717. ;;
  1718. '')
  1719. la_element="";
  1720. ;;
  1721. *)
  1722. la_element="${la_s}";
  1723. ;;
  1724. esac;
  1725. if obj la_list is_empty
  1726. then
  1727. la_list="'${la_element}'";
  1728. else
  1729. la_list="${la_list} '${la_element}'";
  1730. fi;
  1731. done;
  1732. eval "${la_name}"='"${la_list}"';
  1733. eval ${_UNSET} la_element;
  1734. eval ${_UNSET} la_list;
  1735. eval ${_UNSET} la_name;
  1736. eval ${_UNSET} la_s;
  1737. eval "${return_ok}";
  1738. }
  1739. ########################################################################
  1740. # list_from_cmdline (<pre_name_of_opt_lists> [<cmdline_arg>...])
  1741. #
  1742. # Transform command line arguments into a normalized form.
  1743. #
  1744. # Options, option arguments, and file parameters are identified and
  1745. # output each as a single-quoted argument of its own. Options and
  1746. # file parameters are separated by a '--' argument.
  1747. #
  1748. # Arguments: >=1
  1749. # <pre_name>: common part of a set of 4 environment variable names:
  1750. # $<pre_name>_SHORT_NA: list of short options without an arg.
  1751. # $<pre_name>_SHORT_ARG: list of short options that have an arg.
  1752. # $<pre_name>_LONG_NA: list of long options without an arg.
  1753. # $<pre_name>_LONG_ARG: list of long options that have an arg.
  1754. # <cmdline_arg>...: the arguments from a command line, such as "$@",
  1755. # the content of a variable, or direct arguments.
  1756. #
  1757. # Output: ['-[-]opt' ['optarg']]... '--' ['filename']...
  1758. #
  1759. # Example:
  1760. # list_from_cmdline PRE 'a b' 'c' '' 'long' -a f1 -bcarg --long=larg f2
  1761. # If $PRE_SHORT_NA, $PRE_SHORT_ARG, $PRE_LONG_NA, and $PRE_LONG_ARG are
  1762. # none-empty option lists, this will result in printing:
  1763. # '-a' '-b' '-c' 'arg' '--long' 'larg' '--' 'f1' 'f2'
  1764. #
  1765. # Use this function in the following way:
  1766. # eval set x "$(args_norm PRE_NAME "$@")";
  1767. # shift;
  1768. # while test "$1" != '--'; do
  1769. # case "$1" in
  1770. # ...
  1771. # esac;
  1772. # shift;
  1773. # done;
  1774. # shift; #skip '--'
  1775. # # all positional parameters ("$@") left are file name parameters.
  1776. #
  1777. # Variable prefix: lfc
  1778. #
  1779. list_from_cmdline()
  1780. {
  1781. func_check list_from_cmdline '>=' 1 "$@";
  1782. lfc_short_n="$(obj_data "$1"_SHORT_NA)"; # short options, no argument
  1783. lfc_short_a="$(obj_data "$1"_SHORT_ARG)"; # short options, with argument
  1784. lfc_long_n="$(obj_data "$1"_LONG_NA)"; # long options, no argument
  1785. lfc_long_a="$(obj_data "$1"_LONG_ARG)"; # long options, with argument
  1786. exit_test;
  1787. if obj lfc_short_n is_empty
  1788. then
  1789. error 'list_from_cmdline(): no $'"$1"'_SHORT_NA options.';
  1790. fi;
  1791. if obj lfc_short_a is_empty
  1792. then
  1793. error 'list_from_cmdline(): no $'"$1"'_SHORT_ARG options.';
  1794. fi;
  1795. if obj lfc_long_n is_empty
  1796. then
  1797. error 'list_from_cmdline(): no $'"$1"'_LONG_NA options.';
  1798. fi;
  1799. if obj lfc_long_a is_empty
  1800. then
  1801. error 'list_from_cmdline(): no $'"$1"'_LONG_ARG options.';
  1802. fi;
  1803. shift;
  1804. if is_equal "$#" 0
  1805. then
  1806. echo1 --
  1807. eval ${_UNSET} lfc_fparams;
  1808. eval ${_UNSET} lfc_short_a;
  1809. eval ${_UNSET} lfc_short_n;
  1810. eval ${_UNSET} lfc_long_a;
  1811. eval ${_UNSET} lfc_long_n;
  1812. eval ${_UNSET} lfc_result;
  1813. eval "${return_ok}";
  1814. fi;
  1815. lfc_fparams='';
  1816. lfc_result='';
  1817. while test "$#" -ge 1
  1818. do
  1819. lfc_arg="$1";
  1820. shift;
  1821. case "${lfc_arg}" in
  1822. --) break; ;;
  1823. --*=*)
  1824. # delete leading '--';
  1825. lfc_abbrev="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
  1826. lfc_with_equal="${lfc_abbrev}";
  1827. # extract option by deleting from the first '=' to the end
  1828. lfc_abbrev="$(echo1 "${lfc_with_equal}" | \
  1829. sed -e 's/^\([^=]*\)=.*$/\1/')";
  1830. lfc_opt="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
  1831. exit_test;
  1832. if obj lfc_opt is_empty
  1833. then
  1834. error_user "--${lfc_abbrev} is not an option.";
  1835. else
  1836. # get the option argument by deleting up to first `='
  1837. lfc_optarg="$(echo1 "${lfc_with_equal}" | sed -e 's/^[^=]*=//')";
  1838. exit_test;
  1839. list_append lfc_result "--${lfc_opt}" "${lfc_optarg}";
  1840. continue;
  1841. fi;
  1842. ;;
  1843. --*)
  1844. # delete leading '--';
  1845. lfc_abbrev="$(echo1 "${lfc_arg}" | sed -e 's/^--//')";
  1846. if list_has lfc_long_n "${lfc_abbrev}"
  1847. then
  1848. lfc_opt="${lfc_abbrev}";
  1849. else
  1850. exit_test;
  1851. lfc_opt="$(list_single_from_abbrev lfc_long_n "${lfc_abbrev}")";
  1852. exit_test;
  1853. if obj lfc_opt is_not_empty && is_not_equal "$#" 0
  1854. then
  1855. a="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
  1856. exit_test;
  1857. if obj a is_not_empty
  1858. then
  1859. error_user "The abbreviation ${lfc_arg} \
  1860. has multiple options: --${lfc_opt} and --${a}.";
  1861. fi;
  1862. fi;
  1863. fi;
  1864. if obj lfc_opt is_not_empty
  1865. then
  1866. # long option, no argument
  1867. list_append lfc_result "--${lfc_opt}";
  1868. continue;
  1869. fi;
  1870. lfc_opt="$(list_single_from_abbrev lfc_long_a "${lfc_abbrev}")";
  1871. exit_test;
  1872. if obj lfc_opt is_not_empty
  1873. then
  1874. # long option with argument
  1875. if test "$#" -le 0
  1876. then
  1877. error_user "no argument for option --${lfc_opt}."
  1878. fi;
  1879. list_append lfc_result "--${lfc_opt}" "$1";
  1880. shift;
  1881. continue;
  1882. fi;
  1883. error_user "${lfc_arg} is not an option.";
  1884. ;;
  1885. -?*) # short option (cluster)
  1886. # delete leading `-';
  1887. lfc_rest="$(echo1 "${lfc_arg}" | sed -e 's/^-//')";
  1888. exit_test;
  1889. while obj lfc_rest is_not_empty
  1890. do
  1891. # get next short option from cluster (first char of $lfc_rest)
  1892. lfc_optchar="$(echo1 "${lfc_rest}" | sed -e 's/^\(.\).*$/\1/')";
  1893. # remove first character from ${lfc_rest};
  1894. lfc_rest="$(echo1 "${lfc_rest}" | sed -e 's/^.//')";
  1895. exit_test;
  1896. if list_has lfc_short_n "${lfc_optchar}"
  1897. then
  1898. list_append lfc_result "-${lfc_optchar}";
  1899. continue;
  1900. elif list_has lfc_short_a "${lfc_optchar}"
  1901. then
  1902. if obj lfc_rest is_empty
  1903. then
  1904. if test "$#" -ge 1
  1905. then
  1906. list_append lfc_result "-${lfc_optchar}" "$1";
  1907. shift;
  1908. continue;
  1909. else
  1910. error_user "no argument for option -${lfc_optchar}.";
  1911. fi;
  1912. else # rest is the argument
  1913. list_append lfc_result "-${lfc_optchar}" "${lfc_rest}";
  1914. lfc_rest='';
  1915. continue;
  1916. fi;
  1917. else
  1918. error_user "unknown option -${lfc_optchar}.";
  1919. fi;
  1920. done;
  1921. ;;
  1922. *)
  1923. # Here, $lfc_arg is not an option, so a file parameter.
  1924. list_append lfc_fparams "${lfc_arg}";
  1925. # Ignore the strange POSIX option handling to end option
  1926. # parsing after the first file name argument. To reuse it, do
  1927. # a `break' here if $POSIXLY_CORRECT of `bash' is not empty.
  1928. # When `bash' is called as `sh' $POSIXLY_CORRECT is set
  1929. # automatically to `y'.
  1930. ;;
  1931. esac;
  1932. done;
  1933. list_append lfc_result '--';
  1934. if obj lfc_fparams is_not_empty
  1935. then
  1936. lfc_result="${lfc_result} ${lfc_fparams}";
  1937. fi;
  1938. if test "$#" -gt 0
  1939. then
  1940. list_append lfc_result "$@";
  1941. fi;
  1942. obj lfc_result echo1;
  1943. eval ${_UNSET} lfc_abbrev;
  1944. eval ${_UNSET} lfc_fparams;
  1945. eval ${_UNSET} lfc_short_a;
  1946. eval ${_UNSET} lfc_short_n;
  1947. eval ${_UNSET} lfc_long_a;
  1948. eval ${_UNSET} lfc_long_n;
  1949. eval ${_UNSET} lfc_result;
  1950. eval ${_UNSET} lfc_arg;
  1951. eval ${_UNSET} lfc_opt;
  1952. eval ${_UNSET} lfc_opt_arg;
  1953. eval ${_UNSET} lfc_opt_char;
  1954. eval ${_UNSET} lfc_with_equal;
  1955. eval ${_UNSET} lfc_rest;
  1956. eval "${return_ok}";
  1957. } # list_from_cmdline()
  1958. ########################################################################
  1959. # list_from_split (<string> <separator>)
  1960. #
  1961. # In <string>, escape all white space characters and replace each
  1962. # <separator> by space.
  1963. #
  1964. # Arguments: 2: a <string> that is to be split into parts divided by
  1965. # <separator>
  1966. # Output: the resulting list string
  1967. #
  1968. # Variable prefix: lfs
  1969. #
  1970. list_from_split()
  1971. {
  1972. func_check list_from_split = 2 "$@";
  1973. # precede each space or tab by a backslash `\' (doubled for `sed')
  1974. lfs_s="$(echo1 "$1" | sed -e 's/\('"${_SPACE_SED}"'\)/\\\1/g')";
  1975. exit_test;
  1976. # replace split character of string by the list separator ` ' (space).
  1977. case "$2" in
  1978. /) # cannot use normal `sed' separator
  1979. echo1 "${lfs_s}" | sed -e 's|'"$2"'| |g';
  1980. ;;
  1981. ?) # use normal `sed' separator
  1982. echo1 "${lfs_s}" | sed -e 's/'"$2"'/ /g';
  1983. ;;
  1984. ??*)
  1985. error 'list_from_split(): separator must be a single character.';
  1986. ;;
  1987. esac;
  1988. eval ${_UNSET} lfs_s;
  1989. eval "${return_ok}";
  1990. }
  1991. ########################################################################
  1992. # list_get (<list>)
  1993. #
  1994. # Check whether <list> is a space-separated list of '-quoted elements.
  1995. #
  1996. # If the test fails an error is raised.
  1997. # If the test succeeds the argument is echoed.
  1998. #
  1999. # Testing criteria:
  2000. # A list has the form "'first' 'second' '...' 'last'". So it has a
  2001. # leading and a final quote and the elements are separated by "' '"
  2002. # constructs. If these are all removed there should not be any
  2003. # unescaped single-quotes left. Watch out for escaped single
  2004. # quotes; they have the form '\'' (sq bs sq sq).
  2005. # Arguments: 1
  2006. # Output: the argument <list> unchanged, if the check succeeded.
  2007. #
  2008. # Variable prefix: lg
  2009. #
  2010. list_get()
  2011. {
  2012. func_check list_get = 1 "$@";
  2013. eval lg_list='"${'$1'}"';
  2014. # remove leading and final space characters
  2015. lg_list="$(echo1 "${lg_list}" | sed -e '
  2016. s/^'"${_SPACE_SED}"'*//
  2017. s/'"${_SPACE_SED}"'*$//
  2018. ')";
  2019. exit_test;
  2020. case "${lg_list}" in
  2021. '')
  2022. eval ${_UNSET} lg_list;
  2023. eval "${return_ok}";
  2024. ;;
  2025. \'*\')
  2026. obj lg_list echo1;
  2027. eval ${_UNSET} lg_list;
  2028. eval "${return_ok}";
  2029. ;;
  2030. *)
  2031. error "list_get(): bad list: $1"
  2032. ;;
  2033. esac;
  2034. eval ${_UNSET} lg_list;
  2035. eval "${return_ok}";
  2036. }
  2037. ########################################################################
  2038. # list_has (<var_name> <element>)
  2039. #
  2040. # Test whether the list <var_name> has the element <element>.
  2041. #
  2042. # Arguments: 2
  2043. # <var_name>: a variable name for a list of single-quoted elements
  2044. # <element>: some sequence of characters.
  2045. #
  2046. # Variable prefix: lh
  2047. #
  2048. list_has()
  2049. {
  2050. func_check list_has = 2 "$@";
  2051. eval lh_list='"${'$1'}"';
  2052. if obj lh_list is_empty
  2053. then
  2054. eval "${_UNSET}" lh_list;
  2055. eval "${return_no}";
  2056. fi;
  2057. case "$2" in
  2058. \'*\') lh_element=" $2 "; ;;
  2059. *) lh_element=" '$2' "; ;;
  2060. esac;
  2061. if string_contains " ${lh_list} " "${lh_element}"
  2062. then
  2063. eval "${_UNSET}" lh_list;
  2064. eval "${_UNSET}" lh_element;
  2065. eval "${return_yes}";
  2066. else
  2067. eval "${_UNSET}" lh_list;
  2068. eval "${_UNSET}" lh_element;
  2069. eval "${return_no}";
  2070. fi;
  2071. }
  2072. ########################################################################
  2073. # list_has_abbrev (<var_name> <abbrev>)
  2074. #
  2075. # Test whether the list <var_name> has an element starting with <abbrev>.
  2076. #
  2077. # Arguments: 2
  2078. # <var_name>: a variable name for a list of single-quoted elements
  2079. # <abbrev>: some sequence of characters.
  2080. #
  2081. # Variable prefix: lha
  2082. #
  2083. list_has_abbrev()
  2084. {
  2085. func_check list_has_abbrev = 2 "$@";
  2086. eval lha_list='"${'$1'}"';
  2087. if obj lha_list is_empty
  2088. then
  2089. eval "${_UNSET}" lha_list;
  2090. eval "${return_no}";
  2091. fi;
  2092. case "$2" in
  2093. \'*)
  2094. lha_element="$(echo1 "$2" | sed -e 's/'"${_SQ}"'$//')";
  2095. exit_test;
  2096. ;;
  2097. *) lha_element="'$2"; ;;
  2098. esac;
  2099. if string_contains " ${lha_list}" " ${lha_element}"
  2100. then
  2101. eval "${_UNSET}" lha_list;
  2102. eval "${_UNSET}" lha_element;
  2103. eval "${return_yes}";
  2104. else
  2105. eval "${_UNSET}" lha_list;
  2106. eval "${_UNSET}" lha_element;
  2107. eval "${return_no}";
  2108. fi;
  2109. eval "${return_ok}";
  2110. }
  2111. ########################################################################
  2112. # list_has_not (<list> <element>)
  2113. #
  2114. # Test whether <list> has no <element>.
  2115. #
  2116. # Arguments: 2
  2117. # <list>: a space-separated list of single-quoted elements.
  2118. # <element>: some sequence of characters.
  2119. #
  2120. # Variable prefix: lhn
  2121. #
  2122. list_has_not()
  2123. {
  2124. func_check list_has_not = 2 "$@";
  2125. eval lhn_list='"${'$1'}"';
  2126. if obj lhn_list is_empty
  2127. then
  2128. eval "${_UNSET}" lhn_list;
  2129. eval "${return_yes}";
  2130. fi;
  2131. case "$2" in
  2132. \'*\') lhn_element=" $2 "; ;;
  2133. *) lhn_element=" '$2' "; ;;
  2134. esac;
  2135. if string_contains " ${lhn_list} " "${lhn_element}"
  2136. then
  2137. eval "${_UNSET}" lhn_list;
  2138. eval "${_UNSET}" lhn_element;
  2139. eval "${return_no}";
  2140. else
  2141. eval "${_UNSET}" lhn_list;
  2142. eval "${_UNSET}" lhn_element;
  2143. eval "${return_yes}";
  2144. fi;
  2145. }
  2146. ########################################################################
  2147. # list_single_from_abbrev (<list> <abbrev>)
  2148. #
  2149. # Check whether the list has an element starting with <abbrev>. If
  2150. # there are more than a single element an error is created.
  2151. #
  2152. # Arguments: 2
  2153. # <list>: a variable name for a list of single-quoted elements
  2154. # <abbrev>: some sequence of characters.
  2155. #
  2156. # Output: the found element.
  2157. #
  2158. # Variable prefix: lsfa
  2159. #
  2160. list_single_from_abbrev()
  2161. {
  2162. func_check list_single_from_abbrev = 2 "$@";
  2163. eval lsfa_list='"${'$1'}"';
  2164. if obj lsfa_list is_empty
  2165. then
  2166. eval "${_UNSET}" lsfa_list;
  2167. eval "${return_no}";
  2168. fi;
  2169. lsfa_abbrev="$2";
  2170. if list_has lsfa_list "${lsfa_abbrev}"
  2171. then
  2172. obj lsfa_abbrev echo1;
  2173. eval "${_UNSET}" lsfa_abbrev;
  2174. eval "${_UNSET}" lsfa_list;
  2175. eval "${return_yes}";
  2176. fi;
  2177. if list_has_abbrev lsfa_list "${lsfa_abbrev}"
  2178. then
  2179. lsfa_element='';
  2180. eval set x "${lsfa_list}";
  2181. shift;
  2182. for i
  2183. do
  2184. case "$i" in
  2185. ${lsfa_abbrev}*)
  2186. if obj lsfa_element is_not_empty
  2187. then
  2188. error_user "The abbreviation --${lsfa_abbrev} \
  2189. has multiple options: --${lsfa_element} and --${i}.";
  2190. fi;
  2191. lsfa_element="$i";
  2192. ;;
  2193. esac;
  2194. done;
  2195. obj lsfa_element echo1;
  2196. eval "${_UNSET}" lsfa_abbrev;
  2197. eval "${_UNSET}" lsfa_element;
  2198. eval "${_UNSET}" lsfa_list;
  2199. eval "${return_yes}";
  2200. else
  2201. eval "${_UNSET}" lsfa_abbrev;
  2202. eval "${_UNSET}" lsfa_element;
  2203. eval "${_UNSET}" lsfa_list;
  2204. eval "${return_no}";
  2205. fi;
  2206. }
  2207. ########################################################################
  2208. landmark '7: man_*()';
  2209. ########################################################################
  2210. ########################################################################
  2211. # man_do_filespec (<filespec>)
  2212. #
  2213. # Print suitable man page(s) for filespec to $_TMP_CAT.
  2214. #
  2215. # Arguments : 2
  2216. # <filespec>: argument of the form `man:name.section', `man:name',
  2217. # `man:name(section)', `name.section', `name'.
  2218. #
  2219. # Globals : $_OPT_ALL
  2220. #
  2221. # Output : none.
  2222. # Return : `0' if man page was found, `1' else.
  2223. #
  2224. # Only called from do_fileargs(), checks on $MANPATH and $_MAN_ENABLE
  2225. # are assumed (see man_setup()).
  2226. #
  2227. # Variable prefix: mdf
  2228. #
  2229. man_do_filespec()
  2230. {
  2231. func_check man_do_filespec = 1 "$@";
  2232. if obj _MAN_PATH is_empty
  2233. then
  2234. eval "${return_bad}";
  2235. fi;
  2236. if is_empty "$1"
  2237. then
  2238. eval "${return_bad}";
  2239. fi;
  2240. mdf_spec="$1";
  2241. mdf_name='';
  2242. mdf_section='';
  2243. case "${mdf_spec}" in
  2244. */*) # not a man spec with containing '/'
  2245. eval ${_UNSET} mdf_got_one;
  2246. eval ${_UNSET} mdf_name;
  2247. eval ${_UNSET} mdf_section;
  2248. eval ${_UNSET} mdf_spec;
  2249. eval "${return_bad}";
  2250. ;;
  2251. man:?*\(?*\)) # man:name(section)
  2252. mdf_name="$(echo1 "${mdf_spec}" \
  2253. | sed -e 's/^man:\(..*\)(\(..*\))$/\1/')";
  2254. mdf_section="$(echo1 "${mdf_spec}" \
  2255. | sed -e 's/^man:\(..*\)(\(..*\))$/\2/')";
  2256. exit_test;
  2257. ;;
  2258. man:?*.${_MAN_AUTO_SEC_CHARS}) # man:name.section
  2259. mdf_name="$(echo1 "${mdf_spec}" \
  2260. | sed -e 's/^man:\(..*\)\..$/\1/')";
  2261. mdf_section="$(echo1 "${mdf_spec}" \
  2262. | sed -e 's/^.*\(.\)$/\1/')";
  2263. exit_test;
  2264. ;;
  2265. man:?*) # man:name
  2266. mdf_name="$(echo1 "${mdf_spec}" | sed -e 's/^man://')";
  2267. exit_test;
  2268. ;;
  2269. ?*\(?*\)) # name(section)
  2270. mdf_name="$(echo1 "${mdf_spec}" \
  2271. | sed -e 's/^\(..*\)(\(..*\))$/\1/')";
  2272. mdf_section="$(echo1 "${mdf_spec}" \
  2273. | sed -e 's/^\(..*\)(\(..*\))$/\2/')";
  2274. exit_test;
  2275. ;;
  2276. ?*.${_MAN_AUTO_SEC_CHARS}) # name.section
  2277. mdf_name="$(echo1 "${mdf_spec}" \
  2278. | sed -e 's/^\(..*\)\..$/\1/')";
  2279. mdf_section="$(echo1 "${mdf_spec}" \
  2280. | sed -e 's/^.*\(.\)$/\1/')";
  2281. exit_test;
  2282. ;;
  2283. ?*)
  2284. mdf_name="${mdf_spec}";
  2285. ;;
  2286. esac;
  2287. if obj mdf_name is_empty
  2288. then
  2289. eval ${_UNSET} mdf_got_one;
  2290. eval ${_UNSET} mdf_name;
  2291. eval ${_UNSET} mdf_section;
  2292. eval ${_UNSET} mdf_spec;
  2293. eval "${return_bad}";
  2294. fi;
  2295. mdf_got_one='no';
  2296. if obj mdf_section is_empty
  2297. then
  2298. if obj _OPT_SECTIONS is_empty
  2299. then
  2300. eval set x "${_MAN_AUTO_SEC_LIST}";
  2301. else
  2302. # use --sections when no section is given to filespec
  2303. eval set x "$(echo1 "${_OPT_SECTIONS}" | sed -e 's/:/ /g')";
  2304. fi;
  2305. shift;
  2306. for s
  2307. do
  2308. mdf_s="$s";
  2309. if man_search_section "${mdf_name}" "${mdf_s}"
  2310. then # found
  2311. if obj _MAN_ALL is_yes
  2312. then
  2313. mdf_got_one='yes';
  2314. else
  2315. eval ${_UNSET} mdf_got_one;
  2316. eval ${_UNSET} mdf_name;
  2317. eval ${_UNSET} mdf_s;
  2318. eval ${_UNSET} mdf_section;
  2319. eval ${_UNSET} mdf_spec;
  2320. eval "${return_good}";
  2321. fi;
  2322. fi;
  2323. done;
  2324. else
  2325. if man_search_section "${mdf_name}" "${mdf_section}"
  2326. then
  2327. eval ${_UNSET} mdf_got_one;
  2328. eval ${_UNSET} mdf_name;
  2329. eval ${_UNSET} mdf_s;
  2330. eval ${_UNSET} mdf_section;
  2331. eval ${_UNSET} mdf_spec;
  2332. eval "${return_good}";
  2333. else
  2334. eval ${_UNSET} mdf_got_one;
  2335. eval ${_UNSET} mdf_name;
  2336. eval ${_UNSET} mdf_section;
  2337. eval ${_UNSET} mdf_spec;
  2338. eval "${return_bad}";
  2339. fi;
  2340. fi;
  2341. if obj _MAN_ALL is_yes && obj mdf_got_one is_yes
  2342. then
  2343. eval ${_UNSET} mdf_got_one;
  2344. eval ${_UNSET} mdf_name;
  2345. eval ${_UNSET} mdf_s;
  2346. eval ${_UNSET} mdf_section;
  2347. eval ${_UNSET} mdf_spec;
  2348. eval "${return_good}";
  2349. fi;
  2350. eval ${_UNSET} mdf_got_one;
  2351. eval ${_UNSET} mdf_name;
  2352. eval ${_UNSET} mdf_s;
  2353. eval ${_UNSET} mdf_section;
  2354. eval ${_UNSET} mdf_spec;
  2355. eval "${return_bad}";
  2356. } # man_do_filespec()
  2357. ########################################################################
  2358. # man_register_file (<file> <name> [<section>])
  2359. #
  2360. # Write a found man page file and register the title element.
  2361. #
  2362. # Arguments: 1, 2, or 3; maybe empty
  2363. # Output: none
  2364. #
  2365. man_register_file()
  2366. {
  2367. func_check man_register_file '>=' 2 "$@";
  2368. case "$#" in
  2369. 2|3) do_nothing; ;;
  2370. *)
  2371. error "man_register_file() expects 2 or 3 arguments.";
  2372. ;;
  2373. esac;
  2374. if is_empty "$1"
  2375. then
  2376. error 'man_register_file(): file name is empty';
  2377. fi;
  2378. to_tmp "$1";
  2379. case "$#" in
  2380. 2)
  2381. register_title "man:$2";
  2382. eval "${return_ok}";
  2383. ;;
  2384. 3)
  2385. register_title "$2.$3";
  2386. eval "${return_ok}";
  2387. ;;
  2388. esac;
  2389. eval "${return_ok}";
  2390. }
  2391. ########################################################################
  2392. # man_search_section (<name> <section>)
  2393. #
  2394. # Retrieve man pages.
  2395. #
  2396. # Arguments : 2
  2397. # Globals : $_MAN_PATH, $_MAN_EXT
  2398. # Return : 0 if found, 1 otherwise
  2399. #
  2400. # Variable prefix: mss
  2401. #
  2402. man_search_section()
  2403. {
  2404. func_check man_search_section = 2 "$@";
  2405. if obj _MAN_PATH is_empty
  2406. then
  2407. eval "${return_bad}";
  2408. fi;
  2409. if is_empty "$1"
  2410. then
  2411. eval "${return_bad}";
  2412. fi;
  2413. if is_empty "$2"
  2414. then
  2415. eval "${return_bad}";
  2416. fi;
  2417. mss_name="$1";
  2418. mss_section="$2";
  2419. eval set x "$(path_split "${_MAN_PATH}")";
  2420. exit_test;
  2421. shift;
  2422. mss_got_one='no';
  2423. if obj _MAN_EXT is_empty
  2424. then
  2425. for d
  2426. do
  2427. mss_dir="$(dirname_append "$d" "man${mss_section}")";
  2428. exit_test;
  2429. if obj mss_dir is_dir
  2430. then
  2431. mss_prefix="$(\
  2432. dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
  2433. if obj _OPT_WHATIS is_yes
  2434. then
  2435. mss_files="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
  2436. sed -e '\| found|s|.*||'
  2437. )";
  2438. else
  2439. mss_files="$(eval ls "'${mss_prefix}'"'*' 2>${_NULL_DEV} |
  2440. sed -e '\| found|s|.*||'
  2441. )";
  2442. fi;
  2443. exit_test;
  2444. if obj mss_files is_not_empty
  2445. then
  2446. # for f in $mss_files
  2447. for f in $(eval set x ${mss_files}; shift; echo1 "$@")
  2448. do
  2449. exit_test;
  2450. mss_f="$f";
  2451. if obj mss_f is_file
  2452. then
  2453. if is_yes "${mss_got_one}"
  2454. then
  2455. register_file "${mss_f}";
  2456. elif obj _MAN_ALL is_yes
  2457. then
  2458. man_register_file "${mss_f}" "${mss_name}";
  2459. else
  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}";
  2470. fi;
  2471. mss_got_one='yes';
  2472. fi;
  2473. done;
  2474. fi;
  2475. fi;
  2476. done;
  2477. else
  2478. mss_ext="${_MAN_EXT}";
  2479. # check for directory name having trailing extension
  2480. for d
  2481. do
  2482. mss_dir="$(dirname_append $d man${mss_section}${mss_ext})";
  2483. exit_test;
  2484. if obj mss_dir is_dir
  2485. then
  2486. mss_prefix=\
  2487. "$(dirname_append "${mss_dir}" "${mss_name}.${mss_section}")";
  2488. mss_files="$( eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
  2489. sed -e '\|not found|s|.*||'
  2490. )";
  2491. exit_test;
  2492. if obj mss_files is_not_empty
  2493. then
  2494. # for f in $mss_files
  2495. for f in $(eval set x ${mss_files}; shift; echo1 "$@")
  2496. do
  2497. mss_f="$f";
  2498. if obj mss_f is_file
  2499. then
  2500. if is_yes "${mss_got_one}"
  2501. then
  2502. register_file "${mss_f}";
  2503. elif obj _MAN_ALL is_yes
  2504. then
  2505. man_register_file "${mss_f}" "${mss_name}";
  2506. else
  2507. man_register_file "${mss_f}" "${mss_name}" "${mss_section}";
  2508. eval ${_UNSET} mss_dir;
  2509. eval ${_UNSET} mss_ext;
  2510. eval ${_UNSET} mss_f;
  2511. eval ${_UNSET} mss_files;
  2512. eval ${_UNSET} mss_got_one;
  2513. eval ${_UNSET} mss_name;
  2514. eval ${_UNSET} mss_prefix;
  2515. eval ${_UNSET} mss_section;
  2516. eval "${return_good}";
  2517. fi;
  2518. mss_got_one='yes';
  2519. fi;
  2520. done;
  2521. fi;
  2522. fi;
  2523. done;
  2524. # check for files with extension in directories without extension
  2525. for d
  2526. do
  2527. mss_dir="$(dirname_append "$d" "man${mss_section}")";
  2528. exit_test;
  2529. if obj mss_dir is_dir
  2530. then
  2531. mss_prefix="$(dirname_append "${mss_dir}" \
  2532. "${mss_name}.${mss_section}${mss_ext}")";
  2533. mss_files="$(eval ls "${mss_prefix}"'*' 2>${_NULL_DEV} |
  2534. sed -e '\|not found|s|.*||'
  2535. )";
  2536. exit_test;
  2537. if obj mss_files is_not_empty
  2538. then
  2539. # for f in $mss_files
  2540. for f in $(eval set x ${mss_files}; shift; echo1 "$@")
  2541. do
  2542. mss_f="$f";
  2543. if obj mss_f is_file
  2544. then
  2545. if is_yes "${mss_got_one}"
  2546. then
  2547. register_file "${mss_f}";
  2548. elif obj _MAN_ALL is_yes
  2549. then
  2550. man_register_file "${mss_f}" "${mss_name}";
  2551. else
  2552. man_register_file "${mss_f}" "${mss_name}" "${mss_section}";
  2553. eval ${_UNSET} mss_dir;
  2554. eval ${_UNSET} mss_ext;
  2555. eval ${_UNSET} mss_f;
  2556. eval ${_UNSET} mss_files;
  2557. eval ${_UNSET} mss_got_one;
  2558. eval ${_UNSET} mss_name;
  2559. eval ${_UNSET} mss_prefix;
  2560. eval ${_UNSET} mss_section;
  2561. eval "${return_good}";
  2562. fi;
  2563. mss_got_one='yes';
  2564. fi;
  2565. done;
  2566. fi;
  2567. fi;
  2568. done;
  2569. fi;
  2570. if obj _MAN_ALL is_yes && is_yes "${mss_got_one}"
  2571. then
  2572. eval ${_UNSET} mss_dir;
  2573. eval ${_UNSET} mss_ext;
  2574. eval ${_UNSET} mss_f;
  2575. eval ${_UNSET} mss_files;
  2576. eval ${_UNSET} mss_got_one;
  2577. eval ${_UNSET} mss_name;
  2578. eval ${_UNSET} mss_prefix;
  2579. eval ${_UNSET} mss_section;
  2580. eval "${return_good}";
  2581. fi;
  2582. eval ${_UNSET} mss_dir;
  2583. eval ${_UNSET} mss_ext;
  2584. eval ${_UNSET} mss_f;
  2585. eval ${_UNSET} mss_files;
  2586. eval ${_UNSET} mss_got_one;
  2587. eval ${_UNSET} mss_name;
  2588. eval ${_UNSET} mss_prefix;
  2589. eval ${_UNSET} mss_section;
  2590. eval "${return_bad}";
  2591. } # man_search_section()
  2592. ########################################################################
  2593. # man_setup ()
  2594. #
  2595. # Setup the variables $_MAN_* needed for man page searching.
  2596. #
  2597. # Globals:
  2598. # in: $_OPT_*, $_MANOPT_*, $LANG, $LC_MESSAGES, $LC_ALL,
  2599. # $MANPATH, $MANROFFSEQ, $MANSEC, $PAGER, $SYSTEM, $MANOPT.
  2600. # out: $_MAN_PATH, $_MAN_LANG, $_MAN_SYS, $_MAN_LANG, $_MAN_LANG2,
  2601. # $_MAN_SEC, $_MAN_ALL
  2602. # in/out: $_MAN_ENABLE
  2603. #
  2604. # The precedence for the variables related to `man' is that of GNU
  2605. # `man', i.e.
  2606. #
  2607. # $LANG; overridden by
  2608. # $LC_MESSAGES; overridden by
  2609. # $LC_ALL; this has the same precedence as
  2610. # $MANPATH, $MANROFFSEQ, $MANSEC, $PAGER, $SYSTEM; overridden by
  2611. # $MANOPT; overridden by
  2612. # the groffer command line options.
  2613. #
  2614. # Variable prefix: ms
  2615. #
  2616. man_setup()
  2617. {
  2618. func_check main_man_setup = 0 "$@";
  2619. if obj _MAN_IS_SETUP is_yes
  2620. then
  2621. eval "${return_ok}";
  2622. fi;
  2623. _MAN_IS_SETUP='yes';
  2624. if obj _MAN_ENABLE is_not_yes
  2625. then
  2626. eval "${return_ok}";
  2627. fi;
  2628. # determine basic path for man pages
  2629. _MAN_PATH="$(get_first_essential \
  2630. "${_OPT_MANPATH}" "${_MANOPT_PATH}" "${MANPATH}")";
  2631. exit_test;
  2632. if obj _MAN_PATH is_empty
  2633. then
  2634. manpath_set_from_path;
  2635. else
  2636. _MAN_PATH="$(path_clean "${_MAN_PATH}")";
  2637. exit_test;
  2638. fi;
  2639. if obj _MAN_PATH is_empty
  2640. then
  2641. if is_prog 'manpath'
  2642. then
  2643. _MAN_PATH="$(manpath 2>${_NULL_DEV})"; # not always available
  2644. exit_test;
  2645. fi;
  2646. fi;
  2647. if obj _MAN_PATH is_empty
  2648. then
  2649. _MAN_ENABLE="no";
  2650. eval "${return_ok}";
  2651. fi;
  2652. _MAN_ALL="$(get_first_essential "${_OPT_ALL}" "${_MANOPT_ALL}")";
  2653. exit_test;
  2654. if obj _MAN_ALL is_empty
  2655. then
  2656. _MAN_ALL='no';
  2657. fi;
  2658. _MAN_SYS="$(get_first_essential \
  2659. "${_OPT_SYSTEMS}" "${_MANOPT_SYS}" "${SYSTEM}")";
  2660. ms_lang="$(get_first_essential \
  2661. "${_OPT_LANG}" "${LC_ALL}" "${LC_MESSAGES}" "${LANG}")";
  2662. exit_test;
  2663. case "${ms_lang}" in
  2664. C|POSIX)
  2665. _MAN_LANG="";
  2666. _MAN_LANG2="";
  2667. ;;
  2668. ?)
  2669. _MAN_LANG="${ms_lang}";
  2670. _MAN_LANG2="";
  2671. ;;
  2672. *)
  2673. _MAN_LANG="${ms_lang}";
  2674. # get first two characters of $ms_lang
  2675. _MAN_LANG2="$(echo1 "${ms_lang}" | sed -e 's/^\(..\).*$/\1/')";
  2676. exit_test;
  2677. ;;
  2678. esac;
  2679. # from now on, use only $_LANG, forget about $_OPT_LANG, $LC_*.
  2680. manpath_add_lang_sys; # this is very slow
  2681. _MAN_SEC="$(get_first_essential \
  2682. "${_OPT_SECT}" "${_MANOPT_SEC}" "${MANSEC}")";
  2683. exit_test;
  2684. if obj _MAN_PATH is_empty
  2685. then
  2686. _MAN_ENABLE="no";
  2687. eval ${_UNSET} ms_lang;
  2688. eval "${return_ok}";
  2689. fi;
  2690. _MAN_EXT="$(get_first_essential \
  2691. "${_OPT_EXTENSION}" "${_MANOPT_EXTENSION}")";
  2692. exit_test;
  2693. eval ${_UNSET} ms_lang;
  2694. eval "${return_ok}";
  2695. } # man_setup()
  2696. ########################################################################
  2697. landmark '8: manpath_*()';
  2698. ########################################################################
  2699. ########################################################################
  2700. # manpath_add_lang_sys ()
  2701. #
  2702. # Add language and operating system specific directories to man path.
  2703. #
  2704. # Arguments : 0
  2705. # Output : none
  2706. # Globals:
  2707. # in: $_MAN_SYS: has the form `os1,os2,...', a comma separated
  2708. # list of names of operating systems.
  2709. # $_MAN_LANG and $_MAN_LANG2: each a single name
  2710. # in/out: $_MAN_PATH: has the form `dir1:dir2:...', a colon
  2711. # separated list of directories.
  2712. #
  2713. # Variable prefix: mals
  2714. #
  2715. manpath_add_lang_sys()
  2716. {
  2717. func_check manpath_add_lang_sys = 0 "$@";
  2718. if obj _MAN_PATH is_empty
  2719. then
  2720. eval "${return_ok}";
  2721. fi;
  2722. # twice test both sys and lang
  2723. eval set x "$(path_split "${_MAN_PATH}")";
  2724. shift;
  2725. exit_test;
  2726. mals_mp='';
  2727. for p
  2728. do # loop on man path directories
  2729. mals_mp="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
  2730. exit_test;
  2731. done;
  2732. eval set x "$(path_split "${mals_mp}")";
  2733. shift;
  2734. exit_test;
  2735. for p
  2736. do # loop on man path directories
  2737. mals_mp="$(_manpath_add_lang_sys_single "${mals_mp}" "$p")";
  2738. exit_test;
  2739. done;
  2740. _MAN_PATH="$(path_chop "${mals_mp}")";
  2741. exit_test;
  2742. eval ${_UNSET} mals_mp;
  2743. eval "${return_ok}";
  2744. }
  2745. # To the directory in $1 append existing sys/lang subdirectories
  2746. # Function is necessary to split the OS list.
  2747. #
  2748. # globals: in: $_MAN_SYS, $_MAN_LANG, $_MAN_LANG2
  2749. # argument: 2: `man_path' and `dir'
  2750. # output: colon-separated path of the retrieved subdirectories
  2751. #
  2752. # Variable prefix: _mals
  2753. #
  2754. _manpath_add_lang_sys_single()
  2755. {
  2756. func_check _manpath_add_lang_sys_single = 2 "$@";
  2757. _mals_res="$1";
  2758. _mals_parent="$2";
  2759. eval set x "$(list_from_split "${_MAN_SYS}" ',')";
  2760. shift;
  2761. exit_test;
  2762. for d in "$@" "${_MAN_LANG}" "${_MAN_LANG2}"
  2763. do
  2764. _mals_dir="$(dirname_append "${_mals_parent}" "$d")";
  2765. exit_test;
  2766. if obj _mals_res path_not_contains "${_mals_dir}" && \
  2767. obj _mals_dir is_dir
  2768. then
  2769. _mals_res="${_mals_res}:${_mals_dir}";
  2770. fi;
  2771. done;
  2772. if path_not_contains "${_mals_res}" "${_mals_parent}"
  2773. then
  2774. _mals_res="${_mals_res}:${_mals_parent}";
  2775. fi;
  2776. path_chop "${_mals_res}";
  2777. eval ${_UNSET} _mals_dir;
  2778. eval ${_UNSET} _mals_parent;
  2779. eval ${_UNSET} _mals_res;
  2780. eval "${return_ok}";
  2781. }
  2782. # end manpath_add_lang_sys ()
  2783. ########################################################################
  2784. # manpath_set_from_path ()
  2785. #
  2786. # Determine basic search path for man pages from $PATH.
  2787. #
  2788. # Return: `0' if a valid man path was retrieved.
  2789. # Output: none
  2790. # Globals:
  2791. # in: $PATH
  2792. # out: $_MAN_PATH
  2793. #
  2794. # Variable prefix: msfp
  2795. #
  2796. manpath_set_from_path()
  2797. {
  2798. func_check manpath_set_from_path = 0 "$@";
  2799. msfp_manpath='';
  2800. # get a basic man path from $PATH
  2801. if obj PATH is_not_empty
  2802. then
  2803. eval set x "$(path_split "${PATH}")";
  2804. shift;
  2805. exit_test;
  2806. for d
  2807. do
  2808. # delete the final `/bin' part
  2809. msfp_base="$(echo1 "$d" | sed -e 's|//*bin/*$||')";
  2810. exit_test;
  2811. for e in /share/man /man
  2812. do
  2813. msfp_mandir="${msfp_base}$e";
  2814. if test -d "${msfp_mandir}" && test -r "${msfp_mandir}"
  2815. then
  2816. msfp_manpath="${msfp_manpath}:${msfp_mandir}";
  2817. fi;
  2818. done;
  2819. done;
  2820. fi;
  2821. # append some default directories
  2822. for d in /usr/local/share/man /usr/local/man \
  2823. /usr/share/man /usr/man \
  2824. /usr/X11R6/man /usr/openwin/man \
  2825. /opt/share/man /opt/man \
  2826. /opt/gnome/man /opt/kde/man
  2827. do
  2828. msfp_d="$d";
  2829. if obj msfp_manpath path_not_contains "${msfp_d}" && obj mfsp_d is_dir
  2830. then
  2831. msfp_manpath="${msfp_manpath}:${mfsp_d}";
  2832. fi;
  2833. done;
  2834. _MAN_PATH="${msfp_manpath}";
  2835. eval ${_UNSET} msfp_base;
  2836. eval ${_UNSET} msfp_d;
  2837. eval ${_UNSET} msfp_mandir;
  2838. eval ${_UNSET} msfp_manpath;
  2839. eval "${return_ok}";
  2840. } # manpath_set_from_path()
  2841. ########################################################################
  2842. landmark '9: obj_*()';
  2843. ########################################################################
  2844. ########################################################################
  2845. # obj (<object> <call_name> <arg>...)
  2846. #
  2847. # This works like a method (object function) call for an object.
  2848. # Run "<call_name> $<object> <arg> ...".
  2849. #
  2850. # The first argument represents an object whose data is given as first
  2851. # argument to <call_name>().
  2852. #
  2853. # Argument: >=2
  2854. # <object>: variable name
  2855. # <call_name>: a program or function name
  2856. #
  2857. # Variable prefix: o
  2858. #
  2859. obj()
  2860. {
  2861. func_check obj '>=' 2 "$@";
  2862. eval o_arg1='"${'$1'}"';
  2863. if is_empty "$2"
  2864. then
  2865. error "obj(): function name is empty."
  2866. else
  2867. o_func="$2";
  2868. fi;
  2869. shift;
  2870. shift;
  2871. eval "${o_func}"' "${o_arg1}" "$@"';
  2872. n="$?";
  2873. eval ${_UNSET} o_arg1;
  2874. eval ${_UNSET} o_func;
  2875. eval "${return_var} $n";
  2876. } # obj()
  2877. ########################################################################
  2878. # obj_data (<object>)
  2879. #
  2880. # Print the data of <object>, i.e. the content of $<object>.
  2881. # For possible later extensions.
  2882. #
  2883. # Arguments: 1
  2884. # <object>: a variable name
  2885. # Output: the data of <object>
  2886. #
  2887. # Variable prefix: od
  2888. #
  2889. obj_data()
  2890. {
  2891. func_check obj '=' 1 "$@";
  2892. if is_empty "$1"
  2893. then
  2894. error "obj_data(): object name is empty."
  2895. fi;
  2896. eval od_res='"${'$1'}"';
  2897. obj od_res echo1;
  2898. eval ${_UNSET} od_res;
  2899. eval "${return_ok}";
  2900. }
  2901. ########################################################################
  2902. # obj_from_output (<object> <call_name> <arg>...)
  2903. #
  2904. # Run '$<object>="$(<call_name> <arg>...)"' to set the result of a
  2905. # function call to a global variable.
  2906. #
  2907. # Arguments: >=2
  2908. # <object>: a variable name
  2909. # <call_name>: the name of a function or program
  2910. # <arg>: optional argument to <call_name>
  2911. # Output: none
  2912. #
  2913. # Variable prefix: ofo
  2914. #
  2915. obj_from_output()
  2916. {
  2917. func_check obj_from_output '>=' 2 "$@";
  2918. if is_empty "$1"
  2919. then
  2920. error "res(): variable name is empty.";
  2921. elif is_empty "$2"
  2922. then
  2923. error "res(): function name is empty."
  2924. else
  2925. ofo_result_name="$1";
  2926. fi;
  2927. shift;
  2928. eval "${ofo_result_name}"'="$('"$@"')"';
  2929. exit_test;
  2930. eval "${return_ok}";
  2931. }
  2932. ########################################################################
  2933. # obj_set (<object> <data>)
  2934. #
  2935. # Set the data of <object>, i.e. call "$<object>=<data>".
  2936. #
  2937. # Arguments: 2
  2938. # <object>: a variable name
  2939. # <data>: a string
  2940. # Output:: none
  2941. #
  2942. obj_set()
  2943. {
  2944. func_check obj_set '=' 2 "$@";
  2945. if is_empty "$1"
  2946. then
  2947. error "obj_set(): object name is empty."
  2948. fi;
  2949. eval "$1"='"$2"';
  2950. eval "${return_ok}";
  2951. }
  2952. ########################################################################
  2953. # path_chop (<path>)
  2954. #
  2955. # Remove unnecessary colons from path.
  2956. #
  2957. # Argument: 1, a colon separated path.
  2958. # Output: path without leading, double, or trailing colons.
  2959. #
  2960. path_chop()
  2961. {
  2962. func_check path_chop = 1 "$@";
  2963. # replace multiple colons by a single colon `:'
  2964. # remove leading and trailing colons
  2965. echo1 "$1" | sed -e '
  2966. s/^:*//
  2967. s/:::*/:/g
  2968. s/:*$//
  2969. ';
  2970. eval "${return_ok}";
  2971. }
  2972. ########################################################################
  2973. # path_clean (<path>)
  2974. #
  2975. # Remove non-existing directories from a colon-separated list.
  2976. #
  2977. # Argument: 1, a colon separated path.
  2978. # Output: colon-separated list of existing directories.
  2979. #
  2980. # Variable prefix: pc
  2981. #
  2982. path_clean()
  2983. {
  2984. func_check path_clean = 1 "$@";
  2985. if is_not_equal "$#" 1
  2986. then
  2987. error 'path_clean() needs 1 argument.';
  2988. fi;
  2989. pc_arg="$1";
  2990. eval set x "$(path_split "${pc_arg}")";
  2991. exit_test;
  2992. shift;
  2993. pc_res="";
  2994. for i
  2995. do
  2996. pc_i="$i";
  2997. if obj pc_i is_not_empty \
  2998. && obj pc_res path_not_contains "${pc_i}" \
  2999. && obj pc_i is_dir
  3000. then
  3001. case "${pc_i}" in
  3002. ?*/)
  3003. pc_res="${pc_res}$(dirname_chop "${pc_i}")";
  3004. exit_test;
  3005. ;;
  3006. *)
  3007. pc_res="${pc_res}:${pc_i}";
  3008. exit_test;
  3009. ;;
  3010. esac;
  3011. fi;
  3012. done;
  3013. eval ${_UNSET} pc_arg;
  3014. eval ${_UNSET} pc_i;
  3015. eval ${_UNSET} pc_res;
  3016. if path_chop "${pc_res}"
  3017. then
  3018. eval "${return_ok}";
  3019. else
  3020. eval "${return_bad}";
  3021. fi;
  3022. }
  3023. ########################################################################
  3024. # path_contains (<path> <dir>)
  3025. #-
  3026. # Test whether `dir' is contained in `path', a list separated by `:'.
  3027. #
  3028. # Arguments : 2 arguments.
  3029. # Return : `0' if arg2 is substring of arg1, `1' otherwise.
  3030. #
  3031. path_contains()
  3032. {
  3033. func_check path_contains = 2 "$@";
  3034. case ":$1:" in
  3035. *":$2:"*)
  3036. eval "${return_yes}";
  3037. ;;
  3038. *)
  3039. eval "${return_no}";
  3040. ;;
  3041. esac;
  3042. eval "${return_ok}";
  3043. }
  3044. ########################################################################
  3045. # path_not_contains (<path> <dir>)
  3046. #
  3047. # Test whether `dir' is not contained in colon separated `path'.
  3048. #
  3049. # Arguments : 2 arguments.
  3050. #
  3051. path_not_contains()
  3052. {
  3053. func_check path_not_contains = 2 "$@";
  3054. if path_contains "$1" "$2"
  3055. then
  3056. eval "${return_no}";
  3057. else
  3058. eval "${return_yes}";
  3059. fi;
  3060. eval "${return_ok}";
  3061. }
  3062. ########################################################################
  3063. # path_split (<path>)
  3064. #
  3065. # In `path' escape white space and replace each colon by a space.
  3066. #
  3067. # Arguments: 1: a colon-separated path
  3068. # Output: the resulting list, process with `eval set'
  3069. #
  3070. path_split()
  3071. {
  3072. func_check path_split = 1 "$@";
  3073. list_from_split "$1" ':';
  3074. eval "${return_ok}";
  3075. }
  3076. ########################################################################
  3077. landmark '10: register_*()';
  3078. ########################################################################
  3079. ########################################################################
  3080. # register_file (<filename>)
  3081. #
  3082. # Write a found file and register the title element.
  3083. #
  3084. # Arguments: 1: a file name
  3085. # Output: none
  3086. #
  3087. register_file()
  3088. {
  3089. func_check register_file = 1 "$@";
  3090. if is_empty "$1"
  3091. then
  3092. error 'register_file(): file name is empty';
  3093. fi;
  3094. if is_equal "$1" '-'
  3095. then
  3096. to_tmp "${_TMP_STDIN}";
  3097. register_title 'stdin';
  3098. else
  3099. to_tmp "$1";
  3100. register_title "$(base_name "$1")";
  3101. exit_test;
  3102. fi;
  3103. eval "${return_ok}";
  3104. } # register_file()
  3105. ########################################################################
  3106. # register_title (<filespec>)
  3107. #
  3108. # Create title element from <filespec> and append to $_REGISTERED_TITLE
  3109. #
  3110. # Globals: $_REGISTERED_TITLE (rw)
  3111. #
  3112. # Variable prefix: rt
  3113. #
  3114. register_title()
  3115. {
  3116. func_check register_title '=' 1 "$@";
  3117. if is_empty "$1"
  3118. then
  3119. eval "${return_ok}";
  3120. fi;
  3121. case "${_REGISTERED_TITLE}" in
  3122. *\ *\ *\ *)
  3123. eval "${return_ok}";
  3124. ;;
  3125. esac;
  3126. # remove directory part
  3127. rt_title="$(base_name "$1")";
  3128. # replace space characters by `_'
  3129. rt_title="$(echo1 "${rt_title}" | sed -e 's/[ ]/_/g')";
  3130. # remove extension `.bz2'
  3131. rt_title="$(echo1 "${rt_title}" | sed -e 's/\.bz2$//')";
  3132. # remove extension `.gz'
  3133. rt_title="$(echo1 "${rt_title}" | sed -e 's/\.gz$//')";
  3134. # remove extension `.Z'
  3135. rt_title="$(echo1 "${rt_title}" | sed -e 's/\.Z$//')";
  3136. exit_test;
  3137. if obj rt_title is_empty
  3138. then
  3139. eval ${_UNSET} rt_title;
  3140. eval "${return_ok}";
  3141. fi;
  3142. if obj _REGISTERED_TITLE is_empty
  3143. then
  3144. _REGISTERED_TITLE="${rt_title}";
  3145. else
  3146. _REGISTERED_TITLE="${_REGISTERED_TITLE} ${rt_title}";
  3147. fi;
  3148. eval ${_UNSET} rt_title;
  3149. eval "${return_ok}";
  3150. } # register_title()
  3151. ########################################################################
  3152. # reset ()
  3153. #
  3154. # Reset the variables that can be affected by options to their default.
  3155. #
  3156. #
  3157. # Defined in section `Preset' after the rudimentary shell tests.
  3158. ########################################################################
  3159. # rm_file (<file_name>)
  3160. #
  3161. # Remove file if $_DEBUG_KEEP_FILES allows it.
  3162. #
  3163. # Globals: $_DEBUG_KEEP_FILES
  3164. #
  3165. rm_file()
  3166. {
  3167. func_check rm_file '=' 1 "$@";
  3168. if is_file "$1"
  3169. then
  3170. rm -f "$1" >${_NULL_DEV} 2>&1;
  3171. fi;
  3172. if is_existing "$1"
  3173. then
  3174. eval "${return_bad}";
  3175. else
  3176. eval "${return_good}";
  3177. fi;
  3178. }
  3179. ########################################################################
  3180. # rm_file_with_debug (<file_name>)
  3181. #
  3182. # Remove file if $_DEBUG_KEEP_FILES allows it.
  3183. #
  3184. # Globals: $_DEBUG_KEEP_FILES
  3185. #
  3186. rm_file_with_debug()
  3187. {
  3188. func_check rm_file_with_debug '=' 1 "$@";
  3189. if obj _DEBUG_KEEP_FILES is_not_yes
  3190. then
  3191. if is_file "$1"
  3192. then
  3193. rm -f "$1" >${_NULL_DEV} 2>&1;
  3194. fi;
  3195. fi;
  3196. if is_existing "$1"
  3197. then
  3198. eval "${return_bad}";
  3199. else
  3200. eval "${return_good}";
  3201. fi;
  3202. }
  3203. ########################################################################
  3204. # rm_tree (<dir_name>)
  3205. #
  3206. # Remove file if $_DEBUG_KEEP_FILES allows it.
  3207. #
  3208. # Globals: $_DEBUG_KEEP_FILES
  3209. #
  3210. rm_tree()
  3211. {
  3212. func_check rm_tree '=' 1 "$@";
  3213. if is_existing "$1"
  3214. then
  3215. rm -f -r "$1" >${_NULL_DEV} 2>&1;
  3216. fi;
  3217. if is_existing "$1"
  3218. then
  3219. eval "${return_bad}";
  3220. else
  3221. eval "${return_good}";
  3222. fi;
  3223. }
  3224. ########################################################################
  3225. # save_stdin ()
  3226. #
  3227. # Store standard input to temporary file (with decompression).
  3228. #
  3229. # Variable prefix: ss
  3230. #
  3231. if obj _HAS_COMPRESSION is_yes
  3232. then
  3233. save_stdin()
  3234. {
  3235. func_check save_stdin '=' 0 "$@";
  3236. ss_f="${_TMP_DIR}"/INPUT;
  3237. cat >"${ss_f}";
  3238. cat_z "${ss_f}" >"${_TMP_STDIN}";
  3239. rm_file "${ss_f}";
  3240. eval ${_UNSET} ss_f;
  3241. eval "${return_ok}";
  3242. }
  3243. else
  3244. save_stdin()
  3245. {
  3246. func_check save_stdin = 0 "$@";
  3247. cat >"${_TMP_STDIN}";
  3248. eval "${return_ok}";
  3249. }
  3250. fi;
  3251. ########################################################################
  3252. # special_filespec ()
  3253. #
  3254. # Handle special modes like whatis and apropos.
  3255. #
  3256. special_filespec()
  3257. {
  3258. func_check special_setup '=' 0 "$@";
  3259. if obj _OPT_APROPOS is_yes
  3260. then
  3261. if obj _OPT_WHATIS is_yes
  3262. then
  3263. error \
  3264. 'special_setup: $_OPT_APROPOS and $_OPT_WHATIS are both "yes"';
  3265. fi;
  3266. apropos_filespec;
  3267. eval "${return_ok}";
  3268. fi;
  3269. if obj _OPT_WHATIS is_yes
  3270. then
  3271. whatis_filespec;
  3272. fi;
  3273. eval "${return_ok}";
  3274. }
  3275. ########################################################################
  3276. # special_setup ()
  3277. #
  3278. # Handle special modes like whatis and apropos.
  3279. #
  3280. special_setup()
  3281. {
  3282. func_check special_setup '=' 0 "$@";
  3283. if obj _OPT_APROPOS is_yes
  3284. then
  3285. if obj _OPT_WHATIS is_yes
  3286. then
  3287. error \
  3288. 'special_setup: $_OPT_APROPOS and $_OPT_WHATIS are both "yes"';
  3289. fi;
  3290. apropos_setup;
  3291. eval "${return_ok}";
  3292. fi;
  3293. if obj _OPT_WHATIS is_yes
  3294. then
  3295. whatis_header;
  3296. fi;
  3297. eval "${return_ok}";
  3298. }
  3299. ########################################################################
  3300. landmark '11: stack_*()';
  3301. ########################################################################
  3302. ########################################################################
  3303. # string_contains (<string> <part>)
  3304. #
  3305. # Test whether `part' is contained in `string'.
  3306. #
  3307. # Arguments : 2 text arguments.
  3308. # Return : `0' if arg2 is substring of arg1, `1' otherwise.
  3309. #
  3310. string_contains()
  3311. {
  3312. func_check string_contains '=' 2 "$@";
  3313. case "$1" in
  3314. *"$2"*)
  3315. eval "${return_yes}";
  3316. ;;
  3317. *)
  3318. eval "${return_no}";
  3319. ;;
  3320. esac;
  3321. eval "${return_ok}";
  3322. }
  3323. ########################################################################
  3324. # string_not_contains (<string> <part>)
  3325. #
  3326. # Test whether `part' is not substring of `string'.
  3327. #
  3328. # Arguments : 2 text arguments.
  3329. # Return : `0' if arg2 is substring of arg1, `1' otherwise.
  3330. #
  3331. string_not_contains()
  3332. {
  3333. func_check string_not_contains '=' 2 "$@";
  3334. if string_contains "$1" "$2"
  3335. then
  3336. eval "${return_no}";
  3337. else
  3338. eval "${return_yes}";
  3339. fi;
  3340. eval "${return_ok}";
  3341. }
  3342. ########################################################################
  3343. landmark '12: tmp_*()';
  3344. ########################################################################
  3345. ########################################################################
  3346. # tmp_cat ()
  3347. #
  3348. # output the temporary cat file (the concatenation of all input)
  3349. #
  3350. tmp_cat()
  3351. {
  3352. func_check tmp_cat '=' 0 "$@";
  3353. cat "${_TMP_CAT}";
  3354. eval "${return_var}" "$?";
  3355. }
  3356. ########################################################################
  3357. # tmp_create (<suffix>?)
  3358. #
  3359. # Create temporary file.
  3360. #
  3361. # It's safe to use the shell process ID together with a suffix to
  3362. # have multiple temporary files.
  3363. #
  3364. # Globals: $_TMP_DIR
  3365. #
  3366. # Output : name of created file
  3367. #
  3368. # Variable prefix: tc
  3369. #
  3370. tmp_create()
  3371. {
  3372. func_check tmp_create '<=' 1 "$@";
  3373. # the output file does not have `,' as first character, so these are
  3374. # different names from the output file.
  3375. tc_tmp="${_TMP_DIR}/,$1";
  3376. : >"${tc_tmp}"
  3377. obj tc_tmp echo1;
  3378. eval ${_UNSET} tc_tmp;
  3379. eval "${return_ok}";
  3380. }
  3381. ########################################################################
  3382. # to_tmp (<filename>)
  3383. #
  3384. # print file (decompressed) to the temporary cat file
  3385. #
  3386. to_tmp()
  3387. {
  3388. func_check to_tmp '=' 1 "$@";
  3389. if obj _TMP_CAT is_empty
  3390. then
  3391. error 'to_tmp_line: $_TMP_CAT is not yet set';
  3392. fi;
  3393. if is_file "$1"
  3394. then
  3395. if obj _OPT_LOCATION is_yes
  3396. then
  3397. echo2 "$1";
  3398. fi;
  3399. if obj _OPT_WHATIS is_yes
  3400. then
  3401. whatis_filename "$1" >>"${_TMP_CAT}";
  3402. else
  3403. cat_z "$1" >>"${_TMP_CAT}";
  3404. fi;
  3405. else
  3406. error "to_tmp(): could not read file \`$1'.";
  3407. fi;
  3408. eval "${return_ok}";
  3409. }
  3410. ########################################################################
  3411. # to_tmp_line ([<text>])
  3412. #
  3413. # print line to the temporary cat file
  3414. #
  3415. to_tmp_line()
  3416. {
  3417. func_check to_tmp '>=' 0 "$@";
  3418. if obj _TMP_CAT is_empty
  3419. then
  3420. error 'to_tmp_line: $_TMP_CAT is not yet set';
  3421. fi;
  3422. echo1 "$*" >>"${_TMP_CAT}";
  3423. eval "${return_ok}";
  3424. }
  3425. ########################################################################
  3426. # trap_set
  3427. #
  3428. # call function on signal 0
  3429. #
  3430. trap_set()
  3431. {
  3432. func_check trap_set '=' 0 "$@";
  3433. trap 'clean_up' 0 2>${_NULL_DEV} || :;
  3434. eval "${return_ok}";
  3435. }
  3436. ########################################################################
  3437. # trap_unset ()
  3438. #
  3439. # disable trap on signal 0.
  3440. #
  3441. trap_unset()
  3442. {
  3443. func_check trap_unset '=' 0 "$@";
  3444. trap '' 0 2>${_NULL_DEV} || :;
  3445. eval "${return_ok}";
  3446. }
  3447. ########################################################################
  3448. # usage ()
  3449. #
  3450. # print usage information to stderr; for groffer option --help.
  3451. #
  3452. usage()
  3453. {
  3454. func_check usage = 0 "$@";
  3455. echo;
  3456. version;
  3457. echo1 'Usage: groffer [option]... [filespec]...';
  3458. cat <<EOF
  3459. Display roff files, standard input, and/or Unix manual pages with a X
  3460. Window viewer or in several text modes. All input is decompressed
  3461. on-the-fly with all formats that gzip can handle.
  3462. "filespec" is one of
  3463. "filename" name of a readable file
  3464. "-" for standard input
  3465. "man:name.n" man page "name" in section "n"
  3466. "man:name" man page "name" in first section found
  3467. "name.n" man page "name" in section "n"
  3468. "name" man page "name" in first section found
  3469. and some more (see groffer(1) for details).
  3470. -h --help print this usage message.
  3471. -Q --source output as roff source.
  3472. -T --device=name pass to groff using output device "name".
  3473. -v --version print version information.
  3474. -V display the groff execution pipe instead of formatting.
  3475. -X display with "gxditview" using groff -X.
  3476. -Z --ditroff --intermediate-output
  3477. generate groff intermediate output without
  3478. post-processing and viewing, like groff -Z.
  3479. All other short options are interpreted as "groff" formatting options.
  3480. The most important groffer long options are
  3481. --apropos=name start man's "apropos" program for "name".
  3482. --apropos-data=name
  3483. "apropos" for "name" in man's data sections 4, 5, 7.
  3484. --apropos-devel=name
  3485. "apropos" for "name" in development sections 2, 3, 9.
  3486. --apropos-progs=name
  3487. "apropos" for "name" in man's program sections 1, 6, 8.
  3488. --auto choose mode automatically from the default mode list.
  3489. --default reset all options to the default value.
  3490. --default-modes=mode1,mode2,...
  3491. set sequence of automatically tried modes.
  3492. --dvi display in a viewer for TeX device independent format.
  3493. --dvi-viewer=prog choose the viewer program for dvi mode.
  3494. --groff process like groff, disable viewing features.
  3495. --help display this helping output.
  3496. --html display in a web browser.
  3497. --html-viewer=program
  3498. choose the web browser for html mode.
  3499. --man check file parameters first whether they are man pages.
  3500. --mode=auto|dvi|groff|html|pdf|ps|source|text|tty|www|x|X
  3501. choose display mode.
  3502. --no-man disable man-page facility.
  3503. --no-special disable --all, --apropos*, and --whatis
  3504. --pager=program preset the paging program for tty mode.
  3505. --pdf display in a PDF viewer.
  3506. --pdf-viewer=prog choose the viewer program for pdf mode.
  3507. --ps display in a Postscript viewer.
  3508. --ps-viewer=prog choose the viewer program for ps mode.
  3509. --shell=program specify a shell under which to run groffer2.sh.
  3510. --text output in a text device without a pager.
  3511. --tty display with a pager on text terminal even when in X.
  3512. --tty-viewer=prog select a pager for tty mode; same as --pager.
  3513. --whatis display the file name and description of man pages
  3514. --www same as --html.
  3515. --www-viewer=prog same as --html-viewer
  3516. --x --X display with "gxditview" using an X* device.
  3517. --x-viewer=prog choose viewer program for x mode (X mode).
  3518. --X-viewer=prog same as "--xviewer".
  3519. Development options that are not useful for normal usage:
  3520. --debug, --debug-all, --debug-keep, --debug-lm, --debug-params,
  3521. --debug-shell, --debug-stacks, --debug-tmpdir, --debug-user,
  3522. --do-nothing, --print=text
  3523. Viewer programs for the different modes that run on the terminal:
  3524. --dvi-viewer-tty=prog, --html-viewer-tty=prog, --pdf-viewer-tty=prog,
  3525. --ps-viewer-tty=prog, --tty-viewer-tty, --X-viewer-tty=prog,
  3526. --x-viewer-tty=prog, --www-viewer-tty=prog
  3527. The usual X Windows toolkit options transformed into GNU long options:
  3528. --background=color, --bd=size, --bg=color, --bordercolor=color,
  3529. --borderwidth=size, --bw=size, --display=Xdisplay, --fg=color,
  3530. --fn=font, --font=font, --foreground=color, --geometry=geom, --iconic,
  3531. --resolution=dpi, --rv, --title=text, --xrm=resource
  3532. Long options of GNU "man":
  3533. --all, --ascii, --ditroff, --extension=suffix, --locale=language,
  3534. --local-file=name, --location, --manpath=dir1:dir2:...,
  3535. --sections=s1:s2:..., --systems=s1,s2,..., --where, ...
  3536. EOF
  3537. eval "${return_ok}";
  3538. }
  3539. ########################################################################
  3540. # version ()
  3541. #
  3542. # print version information to stderr
  3543. #
  3544. version()
  3545. {
  3546. func_check version = 0 "$@";
  3547. echo1 "groffer ${_PROGRAM_VERSION} of ${_LAST_UPDATE}";
  3548. # also display groff's version, but not the called subprograms
  3549. groff -v 2>&1 | sed -e '/^ *$/q' | sed -e '1s/^/is part of /';
  3550. eval "${return_ok}";
  3551. }
  3552. ########################################################################
  3553. # warning (<string>)
  3554. #
  3555. # Print warning to stderr
  3556. #
  3557. warning()
  3558. {
  3559. echo2 "warning: $*";
  3560. }
  3561. ########################################################################
  3562. # whatis_filename (<filename>)
  3563. #
  3564. # Interpret <filename> as a man page and display its `whatis'
  3565. # information as a fragment written in the groff language.
  3566. #
  3567. # Variable prefix: wf
  3568. #
  3569. whatis_filename()
  3570. {
  3571. func_check whatis_filename = 1 "$@";
  3572. wf_arg="$1";
  3573. if obj wf_arg is_not_file
  3574. then
  3575. error "whatis_filename(): argument is not a readable file."
  3576. fi;
  3577. wf_dot='^\.'"${_SPACE_SED}"'*';
  3578. if obj _FILESPEC_ARG is_equal '-'
  3579. then
  3580. wf_arg='stdin';
  3581. fi;
  3582. cat <<EOF
  3583. \f[CR]${wf_arg}\f[]:
  3584. .br
  3585. EOF
  3586. # get the parts of the file name
  3587. wf_name="$(base_name $1)";
  3588. wf_section="$(echo1 $1 | sed -n -e '
  3589. s|^.*/man\('"${_MAN_AUTO_SEC_CHARS}"'\).*$|\1|p
  3590. ')";
  3591. if obj wf_section is_not_empty
  3592. then
  3593. case "${wf_name}" in
  3594. *.${wf_section}*)
  3595. s='yes';
  3596. ;;
  3597. *)
  3598. s='';
  3599. wf_section='';
  3600. ;;
  3601. esac
  3602. if obj s is_yes
  3603. then
  3604. wf_name="$(echo1 ${wf_name} | sed -e '
  3605. s/^\(.*\)\.'${wf_section}'.*$/\1/
  3606. ')";
  3607. fi;
  3608. fi;
  3609. # traditional man style; grep the line containing `.TH' macro, if any
  3610. wf_res="$(cat_z "$1" | sed -e '
  3611. /'"${wf_dot}"'TH /p
  3612. d
  3613. ')";
  3614. exit_test;
  3615. if obj wf_res is_not_empty
  3616. then # traditional man style
  3617. # get the first line after the first `.SH' macro, by
  3618. # - delete up to first .SH;
  3619. # - print all lines before the next .SH;
  3620. # - quit.
  3621. wf_res="$(cat_z "$1" | sed -n -e '
  3622. 1,/'"${wf_dot}"'SH/d
  3623. /'"${wf_dot}"'SH/q
  3624. p
  3625. ')";
  3626. if obj wf_section is_not_empty
  3627. then
  3628. case "${wf_res}" in
  3629. ${wf_name}${_SPACE_CASE}*-${_SPACE_CASE}*)
  3630. s='yes';
  3631. ;;
  3632. *)
  3633. s='';
  3634. ;;
  3635. esac;
  3636. if obj s is_yes
  3637. then
  3638. wf_res="$(obj wf_res echo1 | sed -e '
  3639. s/^'"${wf_name}${_SPACE_SED}"'[^-]*-'"${_SPACE_SED}"'*\(.*\)$/'"${wf_name}"' ('"${wf_section}"') \\[em] \1/
  3640. ')";
  3641. fi;
  3642. fi;
  3643. obj wf_res echo1;
  3644. echo;
  3645. eval ${_UNSET} wf_arg;
  3646. eval ${_UNSET} wf_dot;
  3647. eval ${_UNSET} wf_name;
  3648. eval ${_UNSET} wf_res;
  3649. eval ${_UNSET} wf_section;
  3650. eval "${return_ok}";
  3651. fi;
  3652. # mdoc style (BSD doc); grep the line containing `.Nd' macro, if any
  3653. wf_res="$(cat_z "$1" | sed -n -e '/'"${wf_dot}"'Nd /s///p')";
  3654. exit_test;
  3655. if obj wf_res is_not_empty
  3656. then # BSD doc style
  3657. if obj wf_section is_not_empty
  3658. then
  3659. wf_res="$(obj wf_res echo1 | sed -n -e '
  3660. s/^\(.*\)$/'"${wf_name}"' ('"${wf_section}"') \\[em] \1/p
  3661. ')";
  3662. fi;
  3663. obj wf_res echo1;
  3664. echo;
  3665. eval ${_UNSET} wf_arg;
  3666. eval ${_UNSET} wf_dot;
  3667. eval ${_UNSET} wf_name;
  3668. eval ${_UNSET} wf_res;
  3669. eval ${_UNSET} wf_section;
  3670. eval "${return_ok}";
  3671. fi;
  3672. echo1 'is not a man page';
  3673. echo;
  3674. eval ${_UNSET} wf_arg;
  3675. eval ${_UNSET} wf_dot;
  3676. eval ${_UNSET} wf_name;
  3677. eval ${_UNSET} wf_res;
  3678. eval ${_UNSET} wf_section;
  3679. eval "${return_bad}";
  3680. }
  3681. ########################################################################
  3682. # whatis_filespec ()
  3683. #
  3684. # Print the filespec name as .SH to the temporary cat file.
  3685. #
  3686. whatis_filespec()
  3687. {
  3688. func_check whatis_filespec '=' 0 "$@";
  3689. if obj _OPT_WHATIS is_yes
  3690. then
  3691. eval to_tmp_line \
  3692. "'.SH $(echo1 "${_FILESPEC_ARG}" | sed 's/[^\\]-/\\-/g')'";
  3693. exit_test;
  3694. fi;
  3695. eval "${return_ok}";
  3696. }
  3697. ########################################################################
  3698. # whatis_header ()
  3699. #
  3700. # Print the whatis header to the temporary cat file.
  3701. #
  3702. whatis_header()
  3703. {
  3704. func_check whatis_header '=' 0 "$@";
  3705. if obj _OPT_WHATIS is_yes
  3706. then
  3707. to_tmp_line '.TH GROFFER WHATIS';
  3708. fi;
  3709. eval "${return_ok}";
  3710. }
  3711. ########################################################################
  3712. # where_is (<program>)
  3713. #
  3714. # Output path of a program if in $PATH.
  3715. #
  3716. # Arguments : >=1 (empty allowed)
  3717. # more args are ignored, this allows to specify progs with arguments
  3718. # Return : `0' if arg1 is a program in $PATH, `1' otherwise.
  3719. #
  3720. # Variable prefix: w
  3721. #
  3722. where_is()
  3723. {
  3724. func_check where_is '>=' 1 "$@";
  3725. w_arg="$1";
  3726. if obj w_arg is_empty
  3727. then
  3728. eval ${_UNSET} w_arg;
  3729. eval "${return_bad}";
  3730. fi;
  3731. case "${w_arg}" in
  3732. /*)
  3733. eval ${_UNSET} w_arg;
  3734. eval ${_UNSET} w_file;
  3735. if test -f "${w_arg}" && test -x "${w_arg}"
  3736. then
  3737. eval "${return_ok}";
  3738. else
  3739. eval "${return_bad}";
  3740. fi;
  3741. ;;
  3742. esac;
  3743. eval set x "$(path_split "${PATH}")";
  3744. exit_test;
  3745. shift;
  3746. for p
  3747. do
  3748. case "$p" in
  3749. */) w_file=${p}${w_arg}; ;;
  3750. *) w_file=${p}/${w_arg}; ;;
  3751. esac;
  3752. if test -f "${w_file}" && test -x "${w_file}"
  3753. then
  3754. obj w_file echo1;
  3755. eval ${_UNSET} w_arg;
  3756. eval ${_UNSET} w_file;
  3757. eval "${return_ok}";
  3758. fi;
  3759. done;
  3760. eval ${_UNSET} w_arg;
  3761. eval ${_UNSET} w_file;
  3762. eval "${return_bad}";
  3763. }
  3764. ########################################################################
  3765. # main* Functions
  3766. ########################################################################
  3767. # The main area contains the following parts:
  3768. # - main_init(): initialize temporary files and set exit trap
  3769. # - main_parse_MANOPT(): parse $MANOPT
  3770. # - main_parse_args(): argument parsing
  3771. # - main_set_mode (): determine the display mode
  3772. # - main_do_fileargs(): process filespec arguments
  3773. # - main_set_resources(): setup X resources
  3774. # - main_display(): do the displaying
  3775. # - main(): the main function that calls all main_*()
  3776. #######################################################################
  3777. # main_init ()
  3778. #
  3779. # set exit trap and create temporary files
  3780. #
  3781. # Globals: $_TMP_DIR, $_TMP_CAT, $_TMP_STDIN
  3782. #
  3783. # Variable prefix: mi
  3784. #
  3785. main_init()
  3786. {
  3787. func_check main_init = 0 "$@";
  3788. # call clean_up() on shell termination.
  3789. trap_set;
  3790. # create temporary directory
  3791. umask 0022;
  3792. _TMP_DIR='';
  3793. for d in "${GROFF_TMPDIR}" "${TMPDIR}" "${TMP}" "${TEMP}" \
  3794. "${TEMPDIR}" "${HOME}"'/tmp' '/tmp' "${HOME}" '.'
  3795. do
  3796. mi_dir="$d";
  3797. if obj mi_dir is_empty || obj mi_dir is_not_dir || \
  3798. obj mi_dir is_not_writable
  3799. then
  3800. continue;
  3801. fi;
  3802. case "${mi_dir}" in
  3803. */)
  3804. _TMP_DIR="${mi_dir}";
  3805. ;;
  3806. *)
  3807. _TMP_DIR="${mi_dir}"'/';
  3808. ;;
  3809. esac;
  3810. _TMP_DIR="${_TMP_DIR}groffer${_PROCESS_ID}";
  3811. if obj _TMP_DIR rm_tree
  3812. then
  3813. :
  3814. else
  3815. mi_tdir_="${_TMP_DIR}"_;
  3816. mi_n=1;
  3817. mi_tdir_n="${mi_tdir_}${mi_n}";
  3818. while obj mi_tdir_n is_existing
  3819. do
  3820. if obj mi_tdir_n rm_tree
  3821. then
  3822. # directory could not be removed
  3823. mi_n="$(expr "${mi_n}" + 1)";
  3824. mi_tdir_n="${mi_tdir_}${mi_n}";
  3825. continue;
  3826. fi;
  3827. done;
  3828. _TMP_DIR="${mi_tdir_n}";
  3829. fi;
  3830. eval mkdir "${_TMP_DIR}";
  3831. if is_not_equal "$?" 0
  3832. then
  3833. obj _TMP_DIR rm_tree;
  3834. _TMP_DIR='';
  3835. continue;
  3836. fi;
  3837. if obj _TMP_DIR is_dir && obj _TMP_DIR is_writable
  3838. then
  3839. # $_TMP_DIR can now be used as temporary directory
  3840. break;
  3841. fi;
  3842. obj _TMP_DIR rm_tree;
  3843. _TMP_DIR='';
  3844. continue;
  3845. done;
  3846. if obj _TMP_DIR is_empty
  3847. then
  3848. error "main_init: \
  3849. Couldn't create a directory for storing temporary files.";
  3850. fi;
  3851. if obj _DEBUG_PRINT_TMPDIR is_yes
  3852. then
  3853. echo2 "temporary directory: ${_TMP_DIR}";
  3854. fi;
  3855. _TMP_CAT="$(tmp_create groffer_cat)";
  3856. _TMP_STDIN="$(tmp_create groffer_input)";
  3857. exit_test;
  3858. eval ${_UNSET} mi_dir;
  3859. eval ${_UNSET} mi_n;
  3860. eval ${_UNSET} mi_tdir_;
  3861. eval ${_UNSET} mi_tdir_n;
  3862. eval "${return_ok}";
  3863. } # main_init()
  3864. ########################################################################
  3865. # main_parse_MANOPT ()
  3866. #
  3867. # Parse $MANOPT to retrieve man options, but only if it is a non-empty
  3868. # string; found man arguments can be overwritten by the command line.
  3869. #
  3870. # Globals:
  3871. # in: $MANOPT, $_OPTS_MANOPT_*
  3872. # out: $_MANOPT_*
  3873. #
  3874. # Variable prefix: mpm
  3875. #
  3876. main_parse_MANOPT()
  3877. {
  3878. func_check main_parse_MANOPT = 0 "$@";
  3879. if obj MANOPT is_not_empty
  3880. then
  3881. # Delete leading and final spaces
  3882. MANOPT="$(echo1 "${MANOPT}" | sed -e '
  3883. s/^'"${_SPACE_SED}"'*//
  3884. s/'"${_SPACE_SED}"'*$//
  3885. ')";
  3886. exit_test;
  3887. fi;
  3888. if obj MANOPT is_empty
  3889. then
  3890. eval "${return_ok}";
  3891. fi;
  3892. mpm_list='';
  3893. # add arguments in $MANOPT by mapping them to groffer options
  3894. eval set x "$(list_from_cmdline _OPTS_MANOPT "${MANOPT}")";
  3895. exit_test;
  3896. shift;
  3897. until test "$#" -le 0 || is_equal "$1" '--'
  3898. do
  3899. mpm_opt="$1";
  3900. shift;
  3901. case "${mpm_opt}" in
  3902. -7|--ascii)
  3903. list_append mpm_list '--ascii';
  3904. ;;
  3905. -a|--all)
  3906. list_append mpm_list '--all';
  3907. ;;
  3908. -c|--catman)
  3909. do_nothing;
  3910. shift;
  3911. ;;
  3912. -d|--debug)
  3913. do_nothing;
  3914. ;;
  3915. -D|--default)
  3916. # undo all man options so far
  3917. mpm_list='';
  3918. ;;
  3919. -e|--extension)
  3920. list_append mpm_list '--extension';
  3921. shift;
  3922. ;;
  3923. -f|--whatis)
  3924. list_append mpm_list '--whatis';
  3925. shift;
  3926. ;;
  3927. -h|--help)
  3928. do_nothing;
  3929. shift;
  3930. ;;
  3931. -k|--apropos)
  3932. # groffer's --apropos takes an argument, but man's does not, so
  3933. do_nothing;
  3934. ;;
  3935. -l|--local-file)
  3936. do_nothing;
  3937. ;;
  3938. -L|--locale)
  3939. list_append mpm_list '--locale' "$1";
  3940. shift;
  3941. ;;
  3942. -m|--systems)
  3943. list_append mpm_list '--systems' "$1";
  3944. shift;
  3945. ;;
  3946. -M|--manpath)
  3947. list_append mpm_list '--manpath' "$1";
  3948. shift;
  3949. ;;
  3950. -p|--preprocessor)
  3951. do_nothing;
  3952. shift;
  3953. ;;
  3954. -P|--pager)
  3955. list_append mpm_list '--pager' "$1";
  3956. shift;
  3957. ;;
  3958. -r|--prompt)
  3959. do_nothing;
  3960. shift;
  3961. ;;
  3962. -S|--sections)
  3963. list_append mpm_list '--sections' "$1";
  3964. shift;
  3965. ;;
  3966. -t|--troff)
  3967. do_nothing;
  3968. shift;
  3969. ;;
  3970. -T|--device)
  3971. list_append mpm_list '-T' "$1";
  3972. shift;
  3973. ;;
  3974. -u|--update)
  3975. do_nothing;
  3976. shift;
  3977. ;;
  3978. -V|--version)
  3979. do_nothing;
  3980. ;;
  3981. -w|--where|--location)
  3982. list_append mpm_list '--location';
  3983. ;;
  3984. -Z|--ditroff)
  3985. do_nothing;
  3986. ;;
  3987. # ignore all other options
  3988. esac;
  3989. done;
  3990. # prepend $mpm_list to the command line
  3991. if obj mpm_list is_not_empty
  3992. then
  3993. eval set x "${mpm_list}" '"$@"';
  3994. shift;
  3995. fi;
  3996. eval ${_UNSET} mpm_list;
  3997. eval ${_UNSET} mpm_opt;
  3998. eval "${return_ok}";
  3999. } # main_parse_MANOPT()
  4000. ########################################################################
  4001. # main_parse_args (<command_line_args>*)
  4002. #
  4003. # Parse arguments; process options and filespec parameters
  4004. #
  4005. # Arguments: pass the command line arguments unaltered.
  4006. # Globals:
  4007. # in: $_OPTS_*
  4008. # out: $_OPT_*, $_ADDOPTS, $_FILEARGS
  4009. #
  4010. # Variable prefix: mpa
  4011. #
  4012. main_parse_args()
  4013. {
  4014. func_check main_parse_args '>=' 0 "$@";
  4015. _ALL_PARAMS="$(list_from_cmdline _OPTS_CMDLINE "$@")";
  4016. exit_test;
  4017. if obj _DEBUG_PRINT_PARAMS is_yes
  4018. then
  4019. echo2 "parameters: ${_ALL_PARAMS}";
  4020. fi;
  4021. eval set x "${_ALL_PARAMS}";
  4022. shift;
  4023. # By the call of `eval', unnecessary quoting was removed. So the
  4024. # positional shell parameters ($1, $2, ...) are now guaranteed to
  4025. # represent an option or an argument to the previous option, if any;
  4026. # then a `--' argument for separating options and
  4027. # parameters; followed by the filespec parameters if any.
  4028. # Note, the existence of arguments to options has already been checked.
  4029. # So a check for `$#' or `--' should not be done for arguments.
  4030. until test "$#" -le 0 || is_equal "$1" '--'
  4031. do
  4032. mpa_opt="$1"; # $mpa_opt is fed into the option handler
  4033. shift;
  4034. case "${mpa_opt}" in
  4035. -h|--help)
  4036. usage;
  4037. leave;
  4038. ;;
  4039. -Q|--source) # output source code (`Quellcode').
  4040. _OPT_MODE='source';
  4041. ;;
  4042. -T|--device|--troff-device) # device; arg
  4043. _OPT_DEVICE="$1";
  4044. _check_device_with_mode;
  4045. shift;
  4046. ;;
  4047. -v|--version)
  4048. version;
  4049. leave;
  4050. ;;
  4051. -V)
  4052. _OPT_V='yes';
  4053. ;;
  4054. -Z|--ditroff|--intermediate-output) # groff intermediate output
  4055. _OPT_Z='yes';
  4056. ;;
  4057. -X)
  4058. if is_X
  4059. then
  4060. _OPT_MODE=X;
  4061. fi;
  4062. ;;
  4063. -?)
  4064. # delete leading `-'
  4065. mpa_optchar="$(echo1 "${mpa_opt}" | sed -e 's/^-//')";
  4066. exit_test;
  4067. if list_has _OPTS_GROFF_SHORT_NA "${mpa_optchar}"
  4068. then
  4069. list_append _ADDOPTS_GROFF "${mpa_opt}";
  4070. elif list_has _OPTS_GROFF_SHORT_ARG "${mpa_optchar}"
  4071. then
  4072. list_append _ADDOPTS_GROFF "${mpa_opt}" "$1";
  4073. shift;
  4074. else
  4075. error "main_parse_args(): Unknown option : \`$1'";
  4076. fi;
  4077. ;;
  4078. --all)
  4079. _OPT_ALL='yes';
  4080. ;;
  4081. --apropos) # run `apropos'
  4082. _OPT_APROPOS='yes';
  4083. _APROPOS_SECTIONS='';
  4084. _OPT_WHATIS='no';
  4085. ;;
  4086. --apropos-data) # run `apropos' for data sections
  4087. _OPT_APROPOS='yes';
  4088. _APROPOS_SECTIONS='457';
  4089. _OPT_WHATIS='no';
  4090. ;;
  4091. --apropos-devel) # run `apropos' for development sections
  4092. _OPT_APROPOS='yes';
  4093. _APROPOS_SECTIONS='239';
  4094. _OPT_WHATIS='no';
  4095. ;;
  4096. --apropos-progs) # run `apropos' for program sections
  4097. _OPT_APROPOS='yes';
  4098. _APROPOS_SECTIONS='168';
  4099. _OPT_WHATIS='no';
  4100. ;;
  4101. --ascii)
  4102. list_append _ADDOPTS_GROFF '-mtty-char';
  4103. if obj _OPT_MODE is_empty
  4104. then
  4105. _OPT_MODE='text';
  4106. fi;
  4107. ;;
  4108. --auto) # the default automatic mode
  4109. _OPT_MODE='';
  4110. ;;
  4111. --bd) # border color for viewers, arg;
  4112. _OPT_BD="$1";
  4113. shift;
  4114. ;;
  4115. --bg|--backgroud) # background color for viewers, arg;
  4116. _OPT_BG="$1";
  4117. shift;
  4118. ;;
  4119. --bw) # border width for viewers, arg;
  4120. _OPT_BW="$1";
  4121. shift;
  4122. ;;
  4123. --debug|--debug-all|--debug-keep|--debug-lm|--debug-params|\
  4124. --debug-shell|--debug-stacks|--debug-tmpdir|--debug-user)
  4125. # debug is handled at the beginning
  4126. :;
  4127. ;;
  4128. --default) # reset variables to default
  4129. reset;
  4130. ;;
  4131. --default-modes) # sequence of modes in auto mode; arg
  4132. _OPT_DEFAULT_MODES="$1";
  4133. shift;
  4134. ;;
  4135. --display) # set X display, arg
  4136. _OPT_DISPLAY="$1";
  4137. shift;
  4138. ;;
  4139. --do-nothing)
  4140. _OPT_DO_NOTHING='yes';
  4141. ;;
  4142. --dvi)
  4143. if is_X
  4144. then
  4145. _OPT_MODE='dvi';
  4146. fi;
  4147. ;;
  4148. --dvi-viewer) # viewer program for dvi mode; arg
  4149. _VIEWER_TERMINAL='no';
  4150. _OPT_VIEWER_DVI="$1";
  4151. shift;
  4152. ;;
  4153. --dvi-viewer-tty) # viewer program for dvi mode in tty; arg
  4154. _VIEWER_TERMINAL='yes';
  4155. _OPT_VIEWER_DVI="$1";
  4156. shift;
  4157. ;;
  4158. --extension) # the extension for man pages, arg
  4159. _OPT_EXTENSION="$1";
  4160. shift;
  4161. ;;
  4162. --fg|--foreground) # foreground color for viewers, arg;
  4163. _OPT_FG="$1";
  4164. shift;
  4165. ;;
  4166. --fn|--font) # set font for viewers, arg;
  4167. _OPT_FN="$1";
  4168. shift;
  4169. ;;
  4170. --geometry) # window geometry for viewers, arg;
  4171. _OPT_GEOMETRY="$1";
  4172. shift;
  4173. ;;
  4174. --groff)
  4175. _OPT_MODE='groff';
  4176. ;;
  4177. --html|--www) # display with web browser
  4178. _OPT_MODE=html;
  4179. ;;
  4180. --html-viewer|--www-viewer) # viewer program for html mode; arg
  4181. _VIEWER_TERMINAL='no';
  4182. _OPT_VIEWER_HTML="$1";
  4183. shift;
  4184. ;;
  4185. --html-viewer-tty|--www-viewer-tty) # viewer for html mode in tty; arg
  4186. _VIEWER_TERMINAL='yes';
  4187. _OPT_VIEWER_HTML="$1";
  4188. shift;
  4189. ;;
  4190. --iconic) # start viewers as icons
  4191. _OPT_ICONIC='yes';
  4192. ;;
  4193. --locale) # set language for man pages, arg
  4194. # argument is xx[_territory[.codeset[@modifier]]] (ISO 639,...)
  4195. _OPT_LANG="$1";
  4196. shift;
  4197. ;;
  4198. --local-file) # force local files; same as `--no-man'
  4199. _MAN_FORCE='no';
  4200. _MAN_ENABLE='no';
  4201. ;;
  4202. --location|--where) # print file locations to stderr
  4203. _OPT_LOCATION='yes';
  4204. ;;
  4205. --man) # force all file params to be man pages
  4206. _MAN_ENABLE='yes';
  4207. _MAN_FORCE='yes';
  4208. ;;
  4209. --manpath) # specify search path for man pages, arg
  4210. # arg is colon-separated list of directories
  4211. _OPT_MANPATH="$1";
  4212. shift;
  4213. ;;
  4214. --mode) # display mode
  4215. mpa_arg="$1";
  4216. shift;
  4217. case "${mpa_arg}" in
  4218. auto|'') # search mode automatically among default
  4219. _OPT_MODE='';
  4220. ;;
  4221. groff) # pass input to plain groff
  4222. _OPT_MODE='groff';
  4223. ;;
  4224. html|www) # display with a web browser
  4225. _OPT_MODE='html';
  4226. ;;
  4227. dvi) # display with xdvi viewer
  4228. if is_X
  4229. then
  4230. _OPT_MODE='dvi';
  4231. fi;
  4232. ;;
  4233. pdf) # display with PDF viewer
  4234. if is_X
  4235. then
  4236. _OPT_MODE='pdf';
  4237. fi;
  4238. ;;
  4239. ps) # display with Postscript viewer
  4240. if is_X
  4241. then
  4242. _OPT_MODE='ps';
  4243. fi;
  4244. ;;
  4245. text) # output on terminal
  4246. _OPT_MODE='text';
  4247. ;;
  4248. tty) # output on terminal
  4249. _OPT_MODE='tty';
  4250. ;;
  4251. X|x) # output on X roff viewer
  4252. if is_X
  4253. then
  4254. _OPT_MODE='x';
  4255. fi;
  4256. ;;
  4257. Q|source) # display source code
  4258. _OPT_MODE="source";
  4259. ;;
  4260. *)
  4261. error "main_parse_args(): unknown mode ${mpa_arg}";
  4262. ;;
  4263. esac;
  4264. ;;
  4265. --no-location) # disable former call to `--location'
  4266. _OPT_LOCATION='yes';
  4267. ;;
  4268. --no-man) # disable search for man pages
  4269. # the same as --local-file
  4270. _MAN_FORCE='no';
  4271. _MAN_ENABLE='no';
  4272. ;;
  4273. --no-special) # disable some special former calls
  4274. _OPT_ALL='no'
  4275. _OPT_APROPOS='no'
  4276. _OPT_WHATIS='no'
  4277. ;;
  4278. --pager|--tty-viewer|--tty-viewer-tty)
  4279. # set paging program for tty mode, arg
  4280. _VIEWER_TERMINAL='yes';
  4281. _OPT_PAGER="$1";
  4282. shift;
  4283. ;;
  4284. --pdf)
  4285. if is_X
  4286. then
  4287. _OPT_MODE='pdf';
  4288. fi;
  4289. ;;
  4290. --pdf-viewer) # viewer program for ps mode; arg
  4291. _VIEWER_TERMINAL='no';
  4292. _OPT_VIEWER_PDF="$1";
  4293. shift;
  4294. ;;
  4295. --pdf-viewer-tty) # viewer program for ps mode in tty; arg
  4296. _VIEWER_TERMINAL='yes';
  4297. _OPT_VIEWER_PDF="$1";
  4298. shift;
  4299. ;;
  4300. --print) # for argument test
  4301. echo2 "$1";
  4302. shift;
  4303. ;;
  4304. --ps)
  4305. if is_X
  4306. then
  4307. _OPT_MODE='ps';
  4308. fi;
  4309. ;;
  4310. --ps-viewer) # viewer program for ps mode; arg
  4311. _VIEWER_TERMINAL='no';
  4312. _OPT_VIEWER_PS="$1";
  4313. shift;
  4314. ;;
  4315. --ps-viewer-tty) # viewer program for ps mode in tty; arg
  4316. _VIEWER_TERMINAL='yes';
  4317. _OPT_VIEWER_PS="$1";
  4318. shift;
  4319. ;;
  4320. --resolution) # set resolution for X devices, arg
  4321. mpa_arg="$1";
  4322. shift;
  4323. case "${mpa_arg}" in
  4324. 75|75dpi)
  4325. mpa_dpi=75;
  4326. ;;
  4327. 100|100dpi)
  4328. mpa_dpi=100;
  4329. ;;
  4330. *)
  4331. error "main_parse_args(): \
  4332. only resoutions of 75 or 100 dpi are supported";
  4333. ;;
  4334. esac;
  4335. _OPT_RESOLUTION="${mpa_dpi}";
  4336. ;;
  4337. --rv)
  4338. _OPT_RV='yes';
  4339. ;;
  4340. --sections) # specify sections for man pages, arg
  4341. # arg is colon-separated list of section names
  4342. _OPT_SECTIONS="$1";
  4343. shift;
  4344. ;;
  4345. --shell)
  4346. # already done during the first run; so ignore the argument
  4347. shift;
  4348. ;;
  4349. --systems) # man pages for different OS's, arg
  4350. # argument is a comma-separated list
  4351. _OPT_SYSTEMS="$1";
  4352. shift;
  4353. ;;
  4354. --text) # text mode without pager
  4355. _OPT_MODE=text;
  4356. ;;
  4357. --title) # title for X viewers; arg
  4358. _OPT_TITLE="$1";
  4359. shift;
  4360. ;;
  4361. --tty) # tty mode, text with pager
  4362. _OPT_MODE=tty;
  4363. ;;
  4364. --text-device|--tty-device) # device for tty mode; arg
  4365. _OPT_TEXT_DEVICE="$1";
  4366. shift;
  4367. ;;
  4368. --whatis)
  4369. _OPT_WHATIS='yes';
  4370. _OPT_ALL='yes';
  4371. _OPT_APROPOS='no';
  4372. ;;
  4373. --X|--x)
  4374. if is_X
  4375. then
  4376. _OPT_MODE=x;
  4377. fi;
  4378. ;;
  4379. --xrm) # pass X resource string, arg;
  4380. list_append _OPT_XRM "$1";
  4381. shift;
  4382. ;;
  4383. --x-viewer|--X-viewer) # viewer program for x mode; arg
  4384. _VIEWER_TERMINAL='no';
  4385. _OPT_VIEWER_X="$1";
  4386. shift;
  4387. ;;
  4388. --x-viewer-tty|--X-viewer-tty) # viewer program for x mode in tty; arg
  4389. _VIEWER_TERMINAL='yes';
  4390. _OPT_VIEWER_X="$1";
  4391. shift;
  4392. ;;
  4393. *)
  4394. error 'main_parse_args(): error on argument parsing : '"\`$*'";
  4395. ;;
  4396. esac;
  4397. done;
  4398. shift; # remove `--' argument
  4399. if obj _OPT_DO_NOTHING is_yes
  4400. then
  4401. leave;
  4402. fi;
  4403. # Remaining arguments are file names (filespecs).
  4404. # Save them to list $_FILEARGS
  4405. if is_equal "$#" 0
  4406. then # use "-" for standard input
  4407. set x '-';
  4408. shift;
  4409. fi;
  4410. _FILEARGS='';
  4411. list_append _FILEARGS "$@";
  4412. if list_has _FILEARGS '-'
  4413. then
  4414. save_stdin;
  4415. fi;
  4416. # $_FILEARGS must be retrieved with `eval set x "$_FILEARGS"; shift;'
  4417. eval ${_UNSET} mpa_arg;
  4418. eval ${_UNSET} mpa_dpi;
  4419. eval ${_UNSET} mpa_opt;
  4420. eval ${_UNSET} mpa_optchar;
  4421. eval "${return_ok}";
  4422. } # main_parse_args()
  4423. # Called from main_parse_args() because double `case' is not possible.
  4424. # Globals: $_OPT_DEVICE, $_OPT_MODE
  4425. _check_device_with_mode()
  4426. {
  4427. func_check _check_device_with_mode = 0 "$@";
  4428. case "${_OPT_DEVICE}" in
  4429. dvi)
  4430. _OPT_MODE=dvi;
  4431. eval "${return_ok}";
  4432. ;;
  4433. html)
  4434. _OPT_MODE=html;
  4435. eval "${return_ok}";
  4436. ;;
  4437. lbp|lj4)
  4438. _OPT_MODE=groff;
  4439. eval "${return_ok}";
  4440. ;;
  4441. ps)
  4442. _OPT_MODE=ps;
  4443. eval "${return_ok}";
  4444. ;;
  4445. ascii|cp1047|latin1|utf8)
  4446. if obj _OPT_MODE is_not_equal text
  4447. then
  4448. _OPT_MODE=tty; # default text mode
  4449. fi;
  4450. eval "${return_ok}";
  4451. ;;
  4452. X*)
  4453. _OPT_MODE=x;
  4454. eval "${return_ok}";
  4455. ;;
  4456. *) # unknown device, go to groff mode
  4457. _OPT_MODE=groff;
  4458. eval "${return_ok}";
  4459. ;;
  4460. esac;
  4461. eval "${return_error}";
  4462. } # _check_device_with_mode() of main_parse_args()
  4463. ########################################################################
  4464. # main_set_mode ()
  4465. #
  4466. # Determine the display mode.
  4467. #
  4468. # Globals:
  4469. # in: $DISPLAY, $_OPT_MODE, $_OPT_DEVICE
  4470. # out: $_DISPLAY_MODE
  4471. #
  4472. # Variable prefix: msm
  4473. #
  4474. main_set_mode()
  4475. {
  4476. func_check main_set_mode = 0 "$@";
  4477. # set display
  4478. if obj _OPT_DISPLAY is_not_empty
  4479. then
  4480. DISPLAY="${_OPT_DISPLAY}";
  4481. fi;
  4482. if obj _OPT_V is_yes
  4483. then
  4484. list_append _ADDOPTS_GROFF '-V';
  4485. fi;
  4486. if obj _OPT_Z is_yes
  4487. then
  4488. _DISPLAY_MODE='groff';
  4489. list_append _ADDOPTS_GROFF '-Z';
  4490. fi;
  4491. if obj _OPT_MODE is_equal 'groff'
  4492. then
  4493. _DISPLAY_MODE='groff';
  4494. fi;
  4495. if obj _DISPLAY_MODE is_equal 'groff'
  4496. then
  4497. eval ${_UNSET} msm_modes;
  4498. eval ${_UNSET} msm_viewer;
  4499. eval ${_UNSET} msm_viewers;
  4500. eval "${return_ok}";
  4501. fi;
  4502. if obj _OPT_MODE is_equal 'source'
  4503. then
  4504. _DISPLAY_MODE='source';
  4505. eval ${_UNSET} msm_modes;
  4506. eval ${_UNSET} msm_viewer;
  4507. eval ${_UNSET} msm_viewers;
  4508. eval "${return_ok}";
  4509. fi;
  4510. case "${_OPT_MODE}" in
  4511. '') # automatic mode
  4512. case "${_OPT_DEVICE}" in
  4513. X*)
  4514. if is_not_X
  4515. then
  4516. error_user "no X display found for device ${_OPT_DEVICE}";
  4517. fi;
  4518. _DISPLAY_MODE='x';
  4519. eval ${_UNSET} msm_modes;
  4520. eval ${_UNSET} msm_viewer;
  4521. eval ${_UNSET} msm_viewers;
  4522. eval "${return_ok}";
  4523. ;;
  4524. ascii|cp1047|latin1|utf8)
  4525. if obj _DISPLAY_MODE is_not_equal 'text'
  4526. then
  4527. _DISPLAY_MODE='tty';
  4528. fi;
  4529. eval ${_UNSET} msm_modes;
  4530. eval ${_UNSET} msm_viewer;
  4531. eval ${_UNSET} msm_viewers;
  4532. eval "${return_ok}";
  4533. ;;
  4534. esac;
  4535. if is_not_X
  4536. then
  4537. _DISPLAY_MODE='tty';
  4538. eval ${_UNSET} msm_modes;
  4539. eval ${_UNSET} msm_viewer;
  4540. eval ${_UNSET} msm_viewers;
  4541. eval "${return_ok}";
  4542. fi;
  4543. if obj _OPT_DEFAULT_MODES is_empty
  4544. then
  4545. msm_modes="${_DEFAULT_MODES}";
  4546. else
  4547. msm_modes="${_OPT_DEFAULT_MODES}";
  4548. fi;
  4549. ;;
  4550. text)
  4551. _DISPLAY_MODE='text';
  4552. eval ${_UNSET} msm_modes;
  4553. eval ${_UNSET} msm_viewer;
  4554. eval ${_UNSET} msm_viewers;
  4555. eval "${return_ok}";
  4556. ;;
  4557. tty)
  4558. _DISPLAY_MODE='tty';
  4559. eval ${_UNSET} msm_modes;
  4560. eval ${_UNSET} msm_viewer;
  4561. eval ${_UNSET} msm_viewers;
  4562. eval "${return_ok}";
  4563. ;;
  4564. html)
  4565. _DISPLAY_MODE='html';
  4566. msm_modes="${_OPT_MODE}";
  4567. ;;
  4568. *) # display mode was given
  4569. if is_not_X
  4570. then
  4571. error_user "You must be in X Window for ${_OPT_MODE} mode.";
  4572. fi;
  4573. msm_modes="${_OPT_MODE}";
  4574. ;;
  4575. esac;
  4576. # only viewer modes are left
  4577. eval set x "$(list_from_split "${msm_modes}" ',')";
  4578. exit_test;
  4579. shift;
  4580. while test "$#" -gt 0
  4581. do
  4582. m="$1";
  4583. shift;
  4584. case "$m" in
  4585. dvi)
  4586. if obj _OPT_VIEWER_DVI is_not_empty
  4587. then
  4588. msm_viewer="${_OPT_VIEWER_DVI}";
  4589. else
  4590. msm_viewer="$(_get_first_prog "$_VIEWER_DVI}")";
  4591. exit_test;
  4592. fi;
  4593. if obj msm_viewer is_empty
  4594. then
  4595. error 'No viewer for dvi mode available.';
  4596. fi;
  4597. if is_not_equal "$?" 0
  4598. then
  4599. continue;
  4600. fi;
  4601. _DISPLAY_PROG="${msm_viewer}";
  4602. _DISPLAY_MODE="dvi";
  4603. eval ${_UNSET} msm_modes;
  4604. eval ${_UNSET} msm_viewer;
  4605. eval ${_UNSET} msm_viewers;
  4606. eval "${return_ok}";
  4607. ;;
  4608. html)
  4609. if obj _OPT_VIEWER_HTML is_not_empty
  4610. then
  4611. msm_viewer="${_OPT_VIEWER_HTML}";
  4612. else
  4613. if is_X
  4614. then
  4615. msm_viewers="${_VIEWER_HTML_X}";
  4616. else
  4617. msm_viewers="${_VIEWER_HTML_TTY}";
  4618. fi;
  4619. msm_viewer="$(_get_first_prog "${msm_viewers}")";
  4620. exit_test;
  4621. fi;
  4622. if obj msm_viewer is_empty
  4623. then
  4624. error 'No viewer for html mode available.';
  4625. fi;
  4626. if is_not_equal "$?" 0
  4627. then
  4628. continue;
  4629. fi;
  4630. _DISPLAY_PROG="${msm_viewer}";
  4631. _DISPLAY_MODE=html;
  4632. eval ${_UNSET} msm_modes;
  4633. eval ${_UNSET} msm_viewer;
  4634. eval ${_UNSET} msm_viewers;
  4635. eval "${return_ok}";
  4636. ;;
  4637. pdf)
  4638. if obj _OPT_VIEWER_PDF is_not_empty
  4639. then
  4640. msm_viewer="${_OPT_VIEWER_PDF}";
  4641. else
  4642. msm_viewer="$(_get_first_prog "${_VIEWER_PDF}")";
  4643. exit_test;
  4644. fi;
  4645. if obj msm_viewer is_empty
  4646. then
  4647. error 'No viewer for pdf mode available.';
  4648. fi;
  4649. if is_not_equal "$?" 0
  4650. then
  4651. continue;
  4652. fi;
  4653. _DISPLAY_PROG="${msm_viewer}";
  4654. _DISPLAY_MODE="pdf";
  4655. eval ${_UNSET} msm_modes;
  4656. eval ${_UNSET} msm_viewer;
  4657. eval ${_UNSET} msm_viewers;
  4658. eval "${return_ok}";
  4659. ;;
  4660. ps)
  4661. if obj _OPT_VIEWER_PS is_not_empty
  4662. then
  4663. msm_viewer="${_OPT_VIEWER_PS}";
  4664. else
  4665. msm_viewer="$(_get_first_prog "${_VIEWER_PS}")";
  4666. exit_test;
  4667. fi;
  4668. if obj msm_viewer is_empty
  4669. then
  4670. error 'No viewer for ps mode available.';
  4671. fi;
  4672. if is_not_equal "$?" 0
  4673. then
  4674. continue;
  4675. fi;
  4676. _DISPLAY_PROG="${msm_viewer}";
  4677. _DISPLAY_MODE="ps";
  4678. eval ${_UNSET} msm_modes;
  4679. eval ${_UNSET} msm_viewer;
  4680. eval ${_UNSET} msm_viewers;
  4681. eval "${return_ok}";
  4682. ;;
  4683. text)
  4684. _DISPLAY_MODE='text';
  4685. eval ${_UNSET} msm_modes;
  4686. eval ${_UNSET} msm_viewer;
  4687. eval ${_UNSET} msm_viewers;
  4688. eval "${return_ok}";
  4689. ;;
  4690. tty)
  4691. _DISPLAY_MODE='tty';
  4692. eval ${_UNSET} msm_modes;
  4693. eval ${_UNSET} msm_viewer;
  4694. eval ${_UNSET} msm_viewers;
  4695. eval "${return_ok}";
  4696. ;;
  4697. x)
  4698. if obj _OPT_VIEWER_X is_not_empty
  4699. then
  4700. msm_viewer="${_OPT_VIEWER_X}";
  4701. else
  4702. msm_viewer="$(_get_first_prog "${_VIEWER_X}")";
  4703. exit_test;
  4704. fi;
  4705. if obj msm_viewer is_empty
  4706. then
  4707. error 'No viewer for x mode available.';
  4708. fi;
  4709. if is_not_equal "$?" 0
  4710. then
  4711. continue;
  4712. fi;
  4713. _DISPLAY_PROG="${msm_viewer}";
  4714. _DISPLAY_MODE='x';
  4715. eval ${_UNSET} msm_modes;
  4716. eval ${_UNSET} msm_viewer;
  4717. eval ${_UNSET} msm_viewers;
  4718. eval "${return_ok}";
  4719. ;;
  4720. X)
  4721. _DISPLAY_MODE='X';
  4722. eval ${_UNSET} msm_modes;
  4723. eval ${_UNSET} msm_viewer;
  4724. eval ${_UNSET} msm_viewers;
  4725. eval "${return_ok}";
  4726. ;;
  4727. esac;
  4728. done;
  4729. eval ${_UNSET} msm_modes;
  4730. eval ${_UNSET} msm_viewer;
  4731. eval ${_UNSET} msm_viewers;
  4732. error_user "No suitable display mode found.";
  4733. } # main_set_mode()
  4734. # _get_first_prog (<proglist>)
  4735. #
  4736. # Retrieve first argument that represents an existing program in $PATH.
  4737. # Local function for main_set_mode().
  4738. #
  4739. # Arguments: 1; a comma-separated list of commands (with options),
  4740. # like $_VIEWER_*.
  4741. #
  4742. # Return : `1' if none found, `0' if found.
  4743. # Output : the argument that succeded.
  4744. #
  4745. # Variable prefix: _gfp
  4746. #
  4747. _get_first_prog()
  4748. {
  4749. if is_equal "$#" 0
  4750. then
  4751. error "_get_first_prog() needs 1 argument.";
  4752. fi;
  4753. if is_empty "$1"
  4754. then
  4755. return "${_BAD}";
  4756. fi;
  4757. eval set x "$(list_from_split "$1" ',')";
  4758. exit_test;
  4759. shift;
  4760. for i
  4761. do
  4762. _gfp_i="$i";
  4763. if obj _gfp_i is_empty
  4764. then
  4765. continue;
  4766. fi;
  4767. if eval is_prog "$(get_first_essential ${_gfp_i})"
  4768. then
  4769. exit_test;
  4770. obj _gfp_i echo1;
  4771. eval ${_UNSET} _gfp_i;
  4772. return "${_GOOD}";
  4773. fi;
  4774. done;
  4775. eval ${_UNSET} _gfp_i;
  4776. return "${_BAD}";
  4777. } # _get_first_prog() of main_set_mode()
  4778. #######################################################################
  4779. # main_do_fileargs ()
  4780. #
  4781. # Process filespec arguments in $_FILEARGS.
  4782. #
  4783. # Globals:
  4784. # in: $_FILEARGS (process with `eval set x "$_FILEARGS"; shift;')
  4785. #
  4786. # Variable prefix: mdfa
  4787. #
  4788. main_do_fileargs()
  4789. {
  4790. func_check main_do_fileargs = 0 "$@";
  4791. special_setup;
  4792. eval set x "${_FILEARGS}";
  4793. shift;
  4794. eval ${_UNSET} _FILEARGS;
  4795. # temporary storage of all input to $_TMP_CAT
  4796. while test "$#" -ge 2
  4797. do
  4798. # test for `s name' arguments, with `s' a 1-char standard section
  4799. mdfa_filespec="$1";
  4800. _FILESPEC_ARG="$1";
  4801. shift;
  4802. case "${mdfa_filespec}" in
  4803. '')
  4804. continue;
  4805. ;;
  4806. '-')
  4807. special_filespec;
  4808. if obj _OPT_APROPOS is_yes
  4809. then
  4810. continue;
  4811. fi;
  4812. register_file '-'
  4813. continue;
  4814. ;;
  4815. ?)
  4816. if obj _OPT_APROPOS is_yes
  4817. then
  4818. special_filespec;
  4819. continue;
  4820. fi;
  4821. if list_has_not _MAN_AUTO_SEC_LIST "${mdfa_filespec}"
  4822. then
  4823. special_filespec;
  4824. do_filearg "${mdfa_filespec}"
  4825. continue;
  4826. fi;
  4827. mdfa_name="$1";
  4828. _FILESPEC_ARG="${_FILESPEC_ARG} $1";
  4829. special_filespec;
  4830. case "${mdfa_name}" in
  4831. */*|man:*|*\(*\)|*."${mdfa_filespec}")
  4832. do_filearg "${mdfa_filespec}"
  4833. continue;
  4834. ;;
  4835. esac;
  4836. shift;
  4837. if do_filearg "man:${mdfa_name}(${mdfa_filespec})"
  4838. then
  4839. continue;
  4840. else
  4841. do_filearg "${mdfa_filespec}"
  4842. continue;
  4843. fi;
  4844. ;;
  4845. *)
  4846. special_filespec;
  4847. if obj _OPT_APROPOS is_yes
  4848. then
  4849. continue;
  4850. fi;
  4851. do_filearg "${mdfa_filespec}"
  4852. continue;
  4853. ;;
  4854. esac;
  4855. done; # end of `s name' test
  4856. while test "$#" -gt 0
  4857. do
  4858. mdfa_filespec="$1";
  4859. _FILESPEC_ARG="$1";
  4860. shift;
  4861. special_filespec;
  4862. if obj _OPT_APROPOS is_yes
  4863. then
  4864. continue;
  4865. fi;
  4866. do_filearg "${mdfa_filespec}"
  4867. done;
  4868. obj _TMP_STDIN rm_file_with_debug;
  4869. eval ${_UNSET} mdfa_filespec;
  4870. eval ${_UNSET} mdfa_name;
  4871. eval "${return_ok}";
  4872. } # main_do_fileargs()
  4873. ########################################################################
  4874. # main_set_resources ()
  4875. #
  4876. # Determine options for setting X resources with $_DISPLAY_PROG.
  4877. #
  4878. # Globals: $_DISPLAY_PROG, $_OUTPUT_FILE_NAME
  4879. #
  4880. # Variable prefix: msr
  4881. #
  4882. main_set_resources()
  4883. {
  4884. func_check main_set_resources = 0 "$@";
  4885. # $msr_prog viewer program
  4886. # $msr_rl resource list
  4887. msr_title="$(get_first_essential \
  4888. "${_OPT_TITLE}" "${_REGISTERED_TITLE}")";
  4889. exit_test;
  4890. _OUTPUT_FILE_NAME='';
  4891. eval set x "${msr_title}";
  4892. shift;
  4893. until is_equal "$#" 0
  4894. do
  4895. msr_n="$1";
  4896. case "${msr_n}" in
  4897. '')
  4898. continue;
  4899. ;;
  4900. ,*)
  4901. msr_n="$(echo1 "$1" | sed -e 's/^,,*//')";
  4902. exit_test;
  4903. ;;
  4904. esac
  4905. if obj msr_n is_empty
  4906. then
  4907. continue;
  4908. fi;
  4909. if obj _OUTPUT_FILE_NAME is_not_empty
  4910. then
  4911. _OUTPUT_FILE_NAME="${_OUTPUT_FILE_NAME}"',';
  4912. fi;
  4913. _OUTPUT_FILE_NAME="${_OUTPUT_FILE_NAME}${msr_n}";
  4914. shift;
  4915. done;
  4916. case "${_OUTPUT_FILE_NAME}" in
  4917. '')
  4918. _OUTPUT_FILE_NAME='-';
  4919. ;;
  4920. ,*)
  4921. error "main_set_resources(): ${_OUTPUT_FILE_NAME} starts with a comma.";
  4922. ;;
  4923. esac;
  4924. _OUTPUT_FILE_NAME="${_TMP_DIR}/${_OUTPUT_FILE_NAME}";
  4925. if obj _DISPLAY_PROG is_empty
  4926. then # for example, for groff mode
  4927. _DISPLAY_ARGS='';
  4928. eval ${_UNSET} msr_n;
  4929. eval ${_UNSET} msr_prog;
  4930. eval ${_UNSET} msr_rl;
  4931. eval ${_UNSET} msr_title;
  4932. eval "${return_ok}";
  4933. fi;
  4934. eval set x "${_DISPLAY_PROG}";
  4935. shift;
  4936. msr_prog="$(base_name "$1")";
  4937. exit_test;
  4938. shift;
  4939. if test $# != 0
  4940. then
  4941. if obj _DISPLAY_PROG is_empty
  4942. then
  4943. _DISPLAY_ARGS="$*";
  4944. else
  4945. _DISPLAY_ARGS="$* ${_DISPLAY_ARGS}";
  4946. fi;
  4947. fi;
  4948. msr_rl='';
  4949. if obj _OPT_BD is_not_empty
  4950. then
  4951. case "${msr_prog}" in
  4952. ghostview|gv|gxditview|xditview|xdvi)
  4953. list_append msr_rl '-bd' "${_OPT_BD}";
  4954. ;;
  4955. esac;
  4956. fi;
  4957. if obj _OPT_BG is_not_empty
  4958. then
  4959. case "${msr_prog}" in
  4960. ghostview|gv|gxditview|xditview|xdvi)
  4961. list_append msr_rl '-bg' "${_OPT_BG}";
  4962. ;;
  4963. kghostview)
  4964. list_append msr_rl '--bg' "${_OPT_BG}";
  4965. ;;
  4966. xpdf)
  4967. list_append msr_rl '-papercolor' "${_OPT_BG}";
  4968. ;;
  4969. esac;
  4970. fi;
  4971. if obj _OPT_BW is_not_empty
  4972. then
  4973. case "${msr_prog}" in
  4974. ghostview|gv|gxditview|xditview|xdvi)
  4975. _list_append msr_rl '-bw' "${_OPT_BW}";
  4976. ;;
  4977. esac;
  4978. fi;
  4979. if obj _OPT_FG is_not_empty
  4980. then
  4981. case "${msr_prog}" in
  4982. ghostview|gv|gxditview|xditview|xdvi)
  4983. list_append msr_rl '-fg' "${_OPT_FG}";
  4984. ;;
  4985. kghostview)
  4986. list_append msr_rl '--fg' "${_OPT_FG}";
  4987. ;;
  4988. esac;
  4989. fi;
  4990. if is_not_empty "${_OPT_FN}"
  4991. then
  4992. case "${msr_prog}" in
  4993. ghostview|gv|gxditview|xditview|xdvi)
  4994. list_append msr_rl '-fn' "${_OPT_FN}";
  4995. ;;
  4996. kghostview)
  4997. list_append msr_rl '--fn' "${_OPT_FN}";
  4998. ;;
  4999. esac;
  5000. fi;
  5001. if is_not_empty "${_OPT_GEOMETRY}"
  5002. then
  5003. case "${msr_prog}" in
  5004. ghostview|gv|gxditview|xditview|xdvi|xpdf)
  5005. list_append msr_rl '-geometry' "${_OPT_GEOMETRY}";
  5006. ;;
  5007. kghostview)
  5008. list_append msr_rl '--geometry' "${_OPT_GEOMETRY}";
  5009. ;;
  5010. esac;
  5011. fi;
  5012. if is_empty "${_OPT_RESOLUTION}"
  5013. then
  5014. _OPT_RESOLUTION="${_DEFAULT_RESOLUTION}";
  5015. case "${msr_prog}" in
  5016. gxditview|xditview)
  5017. list_append msr_rl '-resolution' "${_DEFAULT_RESOLUTION}";
  5018. ;;
  5019. xpdf)
  5020. case "${_DEFAULT_RESOLUTION}" in
  5021. 75)
  5022. # 72dpi is '100'
  5023. list_append msr_rl '-z' '104';
  5024. ;;
  5025. 100)
  5026. list_append msr_rl '-z' '139';
  5027. ;;
  5028. esac;
  5029. ;;
  5030. esac;
  5031. else
  5032. case "${msr_prog}" in
  5033. ghostview|gv|gxditview|xditview|xdvi)
  5034. list_append msr_rl '-resolution' "${_OPT_RESOLUTION}";
  5035. ;;
  5036. xpdf)
  5037. case "${_OPT_RESOLUTION}" in
  5038. 75)
  5039. list_append msr_rl '-z' '104';
  5040. # '100' corresponds to 72dpi
  5041. ;;
  5042. 100)
  5043. list_append msr_rl '-z' '139';
  5044. ;;
  5045. esac;
  5046. ;;
  5047. esac;
  5048. fi;
  5049. if is_yes "${_OPT_ICONIC}"
  5050. then
  5051. case "${msr_prog}" in
  5052. ghostview|gv|gxditview|xditview|xdvi)
  5053. list_append msr_rl '-iconic';
  5054. ;;
  5055. esac;
  5056. fi;
  5057. if is_yes "${_OPT_RV}"
  5058. then
  5059. case "${msr_prog}" in
  5060. ghostview|gv|gxditview|xditview|xdvi)
  5061. list_append msr_rl '-rv';
  5062. ;;
  5063. esac;
  5064. fi;
  5065. if is_not_empty "${_OPT_XRM}"
  5066. then
  5067. case "${msr_prog}" in
  5068. ghostview|gv|gxditview|xditview|xdvi|xpdf)
  5069. eval set x "${_OPT_XRM}";
  5070. shift;
  5071. for i
  5072. do
  5073. list_append msr_rl '-xrm' "$i";
  5074. done;
  5075. ;;
  5076. esac;
  5077. fi;
  5078. if is_not_empty "${msr_title}"
  5079. then
  5080. case "${msr_prog}" in
  5081. gxditview|xditview)
  5082. list_append msr_rl '-title' "${msr_title}";
  5083. ;;
  5084. esac;
  5085. fi;
  5086. _DISPLAY_ARGS="${msr_rl}";
  5087. eval ${_UNSET} msr_n;
  5088. eval ${_UNSET} msr_prog;
  5089. eval ${_UNSET} msr_rl;
  5090. eval ${_UNSET} msr_title;
  5091. eval "${return_ok}";
  5092. } # main_set_resources
  5093. ########################################################################
  5094. # main_display ()
  5095. #
  5096. # Do the actual display of the whole thing.
  5097. #
  5098. # Globals:
  5099. # in: $_DISPLAY_MODE, $_OPT_DEVICE,
  5100. # $_ADDOPTS_GROFF, $_ADDOPTS_POST, $_ADDOPTS_X,
  5101. # $_TMP_CAT, $_OPT_PAGER, $PAGER, $_MANOPT_PAGER,
  5102. # $_OUTPUT_FILE_NAME
  5103. #
  5104. # Variable prefix: md
  5105. #
  5106. main_display()
  5107. {
  5108. func_check main_display = 0 "$@";
  5109. export md_addopts;
  5110. export md_groggy;
  5111. export md_modefile;
  5112. if obj _TMP_CAT is_non_empty_file
  5113. then
  5114. md_modefile="${_OUTPUT_FILE_NAME}";
  5115. else
  5116. echo2 'groffer: empty input.';
  5117. clean_up;
  5118. eval ${_UNSET} md_modefile;
  5119. eval "${return_ok}";
  5120. fi;
  5121. # go to the temporary directory to be able to access internal data files
  5122. cd "${_TMP_DIR}" >"${_NULL_DEV}" 2>&1;
  5123. case "${_DISPLAY_MODE}" in
  5124. groff)
  5125. _ADDOPTS_GROFF="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
  5126. if obj _OPT_DEVICE is_not_empty
  5127. then
  5128. _ADDOPTS_GROFF="${_ADDOPTS_GROFF} -T${_OPT_DEVICE}";
  5129. fi;
  5130. md_groggy="$(tmp_cat | eval grog "${md_options}")";
  5131. exit_test;
  5132. _do_opt_V;
  5133. obj md_modefile rm_file;
  5134. mv "${_TMP_CAT}" "${md_modefile}";
  5135. trap_unset;
  5136. cat "${md_modefile}" | \
  5137. {
  5138. trap_set;
  5139. eval "${md_groggy}" "${_ADDOPTS_GROFF}";
  5140. } &
  5141. ;;
  5142. text|tty)
  5143. case "${_OPT_DEVICE}" in
  5144. '')
  5145. md_device="$(get_first_essential \
  5146. "${_OPT_TEXT_DEVICE}" "${_DEFAULT_TTY_DEVICE}")";
  5147. exit_test;
  5148. ;;
  5149. ascii|cp1047|latin1|utf8)
  5150. md_device="${_OPT_DEVICE}";
  5151. ;;
  5152. *)
  5153. warning "main_display(): \
  5154. wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
  5155. ;;
  5156. esac;
  5157. md_addopts="${_ADDOPTS_GROFF} ${_ADDOPTS_POST}";
  5158. md_groggy="$(tmp_cat | grog -T${md_device})";
  5159. exit_test;
  5160. if obj _DISPLAY_MODE is_equal 'text'
  5161. then
  5162. _do_opt_V;
  5163. tmp_cat | eval "${md_groggy}" "${md_addopts}";
  5164. else
  5165. md_pager='';
  5166. for p in "${_OPT_PAGER}" "${PAGER}" "${_MANOPT_PAGER}" \
  5167. 'less -r -R' 'more' 'pager' 'cat'
  5168. do
  5169. md_p="$p";
  5170. if eval is_prog ${md_p}
  5171. then # no "" for is_prog() allows args for $p
  5172. md_pager="${md_p}";
  5173. break;
  5174. fi;
  5175. done;
  5176. if obj md_pager is_empty
  5177. then
  5178. error 'main_display(): no pager program found for tty mode';
  5179. fi;
  5180. _do_opt_V;
  5181. tmp_cat | eval "${md_groggy}" "${md_addopts}" | \
  5182. eval "${md_pager}";
  5183. fi;
  5184. clean_up;
  5185. ;;
  5186. source)
  5187. tmp_cat;
  5188. clean_up;
  5189. ;;
  5190. #### viewer modes
  5191. dvi)
  5192. case "${_OPT_DEVICE}" in
  5193. ''|dvi) do_nothing; ;;
  5194. *)
  5195. warning "main_display(): \
  5196. wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}"
  5197. ;;
  5198. esac;
  5199. md_modefile="${md_modefile}".dvi;
  5200. md_groggy="$(tmp_cat | grog -Tdvi)";
  5201. exit_test;
  5202. _do_display;
  5203. ;;
  5204. html)
  5205. case "${_OPT_DEVICE}" in
  5206. ''|html) do_nothing; ;;
  5207. *)
  5208. warning "main_display(): \
  5209. wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
  5210. ;;
  5211. esac;
  5212. md_modefile="${md_modefile}".html;
  5213. md_groggy="$(tmp_cat | grog -Thtml)";
  5214. exit_test;
  5215. _do_display;
  5216. ;;
  5217. pdf)
  5218. case "${_OPT_DEVICE}" in
  5219. ''|ps)
  5220. do_nothing;
  5221. ;;
  5222. *)
  5223. warning "main_display(): \
  5224. wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
  5225. ;;
  5226. esac;
  5227. md_groggy="$(tmp_cat | grog -Tps)";
  5228. exit_test;
  5229. _do_display _make_pdf;
  5230. ;;
  5231. ps)
  5232. case "${_OPT_DEVICE}" in
  5233. ''|ps)
  5234. do_nothing;
  5235. ;;
  5236. *)
  5237. warning "main_display(): \
  5238. wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
  5239. ;;
  5240. esac;
  5241. md_modefile="${md_modefile}".ps;
  5242. md_groggy="$(tmp_cat | grog -Tps)";
  5243. exit_test;
  5244. _do_display;
  5245. ;;
  5246. x)
  5247. case "${_OPT_DEVICE}" in
  5248. X*)
  5249. md_device="${_OPT_DEVICE}"
  5250. ;;
  5251. *)
  5252. case "${_OPT_RESOLUTION}" in
  5253. 100)
  5254. md_device='X100';
  5255. if obj _OPT_GEOMETRY is_empty
  5256. then
  5257. case "${_DISPLAY_PROG}" in
  5258. gxditview|xditview)
  5259. # add width of 800dpi for resolution of 100dpi to the args
  5260. list_append _DISPLAY_ARGS '-geometry' '800';
  5261. ;;
  5262. esac;
  5263. fi;
  5264. ;;
  5265. *)
  5266. md_device='X75-12';
  5267. ;;
  5268. esac
  5269. esac;
  5270. md_groggy="$(tmp_cat | grog -T${md_device} -Z)";
  5271. exit_test;
  5272. _do_display;
  5273. ;;
  5274. X)
  5275. case "${_OPT_DEVICE}" in
  5276. '')
  5277. md_groggy="$(tmp_cat | grog -X)";
  5278. exit_test;
  5279. ;;
  5280. X*|dvi|html|lbp|lj4|ps)
  5281. # these devices work with
  5282. md_groggy="$(tmp_cat | grog -T"${_OPT_DEVICE}" -X)";
  5283. exit_test;
  5284. ;;
  5285. *)
  5286. warning "main_display(): \
  5287. wrong device for ${_DISPLAY_MODE} mode: ${_OPT_DEVICE}";
  5288. md_groggy="$(tmp_cat | grog -Z)";
  5289. exit_test;
  5290. ;;
  5291. esac;
  5292. _do_display;
  5293. ;;
  5294. *)
  5295. error "main_display(): unknown mode \`${_DISPLAY_MODE}'";
  5296. ;;
  5297. esac;
  5298. eval ${_UNSET} md_addopts;
  5299. eval ${_UNSET} md_device;
  5300. eval ${_UNSET} md_groggy;
  5301. eval ${_UNSET} md_modefile;
  5302. eval ${_UNSET} md_options;
  5303. eval ${_UNSET} md_p;
  5304. eval ${_UNSET} md_pager;
  5305. eval "${return_ok}";
  5306. } # main_display()
  5307. ########################
  5308. # _do_display ([<prog>])
  5309. #
  5310. # Perform the generation of the output and view the result. If an
  5311. # argument is given interpret it as a function name that is called in
  5312. # the midst (actually only for `pdf').
  5313. #
  5314. # Globals: $md_modefile, $md_groggy (from main_display())
  5315. #
  5316. _do_display()
  5317. {
  5318. func_check _do_display '>=' 0 "$@";
  5319. _do_opt_V;
  5320. if obj _DISPLAY_PROG is_empty
  5321. then
  5322. trap_unset;
  5323. {
  5324. trap_set;
  5325. eval "${md_groggy}" "${_ADDOPTS_GROFF}" "${_TMP_CAT}";
  5326. } &
  5327. else
  5328. obj md_modefile rm_file;
  5329. cat "${_TMP_CAT}" | \
  5330. eval "${md_groggy}" "${_ADDOPTS_GROFF}" > "${md_modefile}";
  5331. if is_not_empty "$1"
  5332. then
  5333. eval "$1";
  5334. fi;
  5335. obj _TMP_CAT rm_file_with_debug;
  5336. if obj _VIEWER_TERMINAL is_yes # for programs that run on tty
  5337. then
  5338. eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
  5339. else
  5340. case "${_DISPLAY_PROG}" in
  5341. # lynx\ *|less\ *|more\ *) # programs known to run on the terminal
  5342. # eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
  5343. # ;;
  5344. *)
  5345. trap_unset;
  5346. {
  5347. trap_set;
  5348. eval "${_DISPLAY_PROG}" ${_DISPLAY_ARGS} "\"${md_modefile}\"";
  5349. } &
  5350. ;;
  5351. esac;
  5352. fi;
  5353. fi;
  5354. eval "${return_ok}";
  5355. } # _do_display() of main_display()
  5356. #############
  5357. # _do_opt_V ()
  5358. #
  5359. # Check on option `-V'; if set print the corresponding output and leave.
  5360. #
  5361. # Globals: $_ALL_PARAMS, $_ADDOPTS_GROFF, $_DISPLAY_MODE, $_DISPLAY_PROG,
  5362. # $_DISPLAY_ARGS, $md_groggy, $md_modefile
  5363. #
  5364. # Variable prefix: _doV
  5365. #
  5366. _do_opt_V()
  5367. {
  5368. func_check _do_opt_V '=' 0 "$@";
  5369. if obj _OPT_V is_yes
  5370. then
  5371. _OPT_V='no';
  5372. echo1 "Parameters: ${_ALL_PARAMS}";
  5373. echo1 "Display mode: ${_DISPLAY_MODE}";
  5374. echo1 "Output file: ${md_modefile}";
  5375. echo1 "Display prog: ${_DISPLAY_PROG} ${_DISPLAY_ARGS}";
  5376. a="$(eval echo1 "'${_ADDOPTS_GROFF}'")";
  5377. exit_test;
  5378. echo1 "Output of grog: ${md_groggy} $a";
  5379. _doV_res="$(eval "${md_groggy}" "${_ADDOPTS_GROFF}")";
  5380. exit_test;
  5381. echo1 "groff -V: ${_doV_res}"
  5382. leave;
  5383. fi;
  5384. eval "${return_ok}";
  5385. } # _do_opt_V() of main_display()
  5386. ##############
  5387. # _make_pdf ()
  5388. #
  5389. # Transform to pdf format; for pdf mode in _do_display().
  5390. #
  5391. # Globals: $md_modefile (from main_display())
  5392. #
  5393. # Variable prefix: _mp
  5394. #
  5395. _make_pdf()
  5396. {
  5397. func_check _do_display '=' 0 "$@";
  5398. _mp_psfile="${md_modefile}";
  5399. md_modefile="${md_modefile}.pdf";
  5400. obj md_modefile rm_file;
  5401. if gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
  5402. -sOutputFile="${md_modefile}" -c save pop -f "${_mp_psfile}"
  5403. then
  5404. :;
  5405. else
  5406. error '_make_pdf: could not transform into pdf format.';
  5407. fi;
  5408. obj _mp_psfile rm_file_with_debug;
  5409. eval ${_UNSET} _mp_psfile;
  5410. eval "${return_ok}";
  5411. } # _make_pdf() of main_display()
  5412. ########################################################################
  5413. # main (<command_line_args>*)
  5414. #
  5415. # The main function for groffer.
  5416. #
  5417. # Arguments:
  5418. #
  5419. main()
  5420. {
  5421. func_check main '>=' 0 "$@";
  5422. # Do not change the sequence of the following functions!
  5423. landmark '13: main_init()';
  5424. main_init;
  5425. landmark '14: main_parse_MANOPT()';
  5426. main_parse_MANOPT;
  5427. landmark '15: main_parse_args()';
  5428. main_parse_args "$@";
  5429. landmark '16: main_set_mode()';
  5430. main_set_mode;
  5431. landmark '17: main_do_fileargs()';
  5432. main_do_fileargs;
  5433. landmark '18: main_set_resources()';
  5434. main_set_resources;
  5435. landmark '19: main_display()';
  5436. main_display;
  5437. eval "${return_ok}";
  5438. }
  5439. ########################################################################
  5440. main "$@";