/contrib/groff/contrib/groffer/groffer2.sh
Shell | 5854 lines | 4370 code | 361 blank | 1123 comment | 359 complexity | 56f108a0a126ad0a9df7a8b9539c98fa MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1#! /bin/sh 2 3# groffer - display groff files 4 5# Source file position: <groff-source>/contrib/groffer/groffer2.sh 6# Installed position: <prefix>/lib/groff/groffer/groffer2.sh 7 8# This file should not be run independently. It is called by 9# `groffer.sh' in the source or by the installed `groffer' program. 10 11# Copyright (C) 2001,2002,2003,2004,2005 12# Free Software Foundation, Inc. 13# Written by Bernd Warken 14 15# Last update: 22 August 2005 16 17# This file is part of `groffer', which is part of `groff'. 18 19# `groff' is free software; you can redistribute it and/or modify it 20# under the terms of the GNU General Public License as published by 21# the Free Software Foundation; either version 2, or (at your option) 22# any later version. 23 24# `groff' is distributed in the hope that it will be useful, but 25# WITHOUT ANY WARRANTY; without even the implied warranty of 26# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 27# General Public License for more details. 28 29# You should have received a copy of the GNU General Public License 30# along with `groff'; see the files COPYING and LICENSE in the top 31# directory of the `groff' source. If not, write to the Free Software 32# Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, 33# USA. 34 35 36######################################################################## 37# Test of rudimentary shell functionality 38######################################################################## 39 40 41######################################################################## 42# Test of `unset' 43# 44export _UNSET; 45export _foo; 46_foo=bar; 47_res="$(unset _foo 2>&1)"; 48if unset _foo >${_NULL_DEV} 2>&1 && \ 49 test _"${_res}"_ = __ && test _"${_foo}"_ = __ 50then 51 _UNSET='unset'; 52 eval "${_UNSET}" _foo; 53 eval "${_UNSET}" _res; 54else 55 _UNSET=':'; 56fi; 57 58 59######################################################################## 60# Test of `test'. 61# 62if test a = a && test a != b && test -f "${_GROFFER_SH}" 63then 64 :; 65else 66 echo '"test" did not work.' >&2; 67 exit "${_ERROR}"; 68fi; 69 70 71######################################################################## 72# Test of `echo' and the `$()' construct. 73# 74if echo '' >${_NULL_DEV} 75then 76 :; 77else 78 echo '"echo" did not work.' >&2; 79 exit "${_ERROR}"; 80fi; 81if test _"$(t1="$(echo te)" && 82 t2="$(echo '')" && 83 t3="$(echo 'st')" && 84 echo "${t1}${t2}${t3}")"_ \ 85 != _test_ 86then 87 echo 'The "$()" construct did not work' >&2; 88 exit "${_ERROR}"; 89fi; 90 91 92######################################################################## 93# Test of sed program; test in groffer.sh is not valid here. 94# 95if test _"$(echo red | sed -e 's/r/s/')"_ != _sed_ 96then 97 echo 'The sed program did not work.' >&2; 98 exit "${_ERROR}"; 99fi; 100 101 102######################################################################## 103# Test of function definitions. 104# 105_t_e_s_t_f_u_n_c_() 106{ 107 return 0; 108} 109 110if _t_e_s_t_f_u_n_c_ 2>${_NULL_DEV} 111then 112 :; 113else 114 echo 'Shell '"${_SHELL}"' does not support function definitions.' >&2; 115 exit "${_ERROR}"; 116fi; 117 118 119######################################################################## 120# debug - diagnostic messages 121######################################################################## 122 123export _DEBUG_STACKS; 124_DEBUG_STACKS='no'; # disable stack output in each function 125#_DEBUG_STACKS='yes'; # enable stack output in each function 126 127export _DEBUG_LM; 128_DEBUG_LM='no'; # disable landmark messages 129#_DEBUG_LM='yes'; # enable landmark messages 130 131export _DEBUG_KEEP_FILES; 132_DEBUG_KEEP_FILES='no' # disable file keeping in temporary dir 133#_DEBUG_KEEP_FILES='yes' # enable file keeping in temporary dir 134 135export _DEBUG_PRINT_PARAMS; 136_DEBUG_PRINT_PARAMS='no'; # disable printing of all parameters 137#_DEBUG_PRINT_PARAMS='yes'; # enable printing of all parameters 138 139export _DEBUG_PRINT_SHELL; 140_DEBUG_PRINT_SHELL='no'; # disable printing of the shell name 141#_DEBUG_PRINT_SHELL='yes'; # enable printing of the shell name 142 143export _DEBUG_PRINT_TMPDIR; 144_DEBUG_PRINT_TMPDIR='no'; # disable printing of the temporary dir 145#_DEBUG_PRINT_TMPDIR='yes'; # enable printing of the temporary dir 146 147export _DEBUG_USER_WITH_STACK; 148_DEBUG_USER_WITH_STACK='no'; # disable stack dump in error_user() 149#_DEBUG_USER_WITH_STACK='yes'; # enable stack dump in error_user() 150 151# determine all --debug* options 152case " $*" in 153*\ --debug*) 154 case " $* " in 155 *' --debug '*) 156 # _DEBUG_STACKS='yes'; 157 # _DEBUG_LM='yes'; 158 _DEBUG_KEEP_FILES='yes'; 159 _DEBUG_PRINT_PARAMS='yes'; 160 _DEBUG_PRINT_SHELL='yes'; 161 _DEBUG_PRINT_TMPDIR='yes'; 162 _DEBUG_USER_WITH_STACK='yes'; 163 ;; 164 esac; 165 d=' --debug-all --debug-keep --debug-lm --debug-params --debug-shell '\ 166'--debug-stacks --debug-tmpdir --debug-user '; 167 for i 168 do 169 case "$i" in 170 --debug-s) 171 echo 'The abbreviation --debug-s has multiple options: '\ 172'--debug-shell and --debug-stacks.' >&2 173 exit "${_ERROR}"; 174 ;; 175 esac; 176 case "$d" in 177 *\ ${i}*) 178 # extract whole word of abbreviation $i 179 s="$(cat <<EOF | sed -n -e 's/^.* \('"$i"'[^ ]*\) .*/\1/p' 180$d 181EOF 182)" 183 case "$s" in 184 '') continue; ;; 185 --debug-all) 186 _DEBUG_STACKS='yes'; 187 _DEBUG_LM='yes'; 188 _DEBUG_KEEP_FILES='yes'; 189 _DEBUG_PRINT_PARAMS='yes'; 190 _DEBUG_PRINT_SHELL='yes'; 191 _DEBUG_PRINT_TMPDIR='yes'; 192 _DEBUG_USER_WITH_STACK='yes'; 193 ;; 194 --debug-keep) 195 _DEBUG_PRINT_TMPDIR='yes'; 196 _DEBUG_KEEP_FILES='yes'; 197 ;; 198 --debug-lm) 199 _DEBUG_LM='yes'; 200 ;; 201 --debug-params) 202 _DEBUG_PRINT_PARAMS='yes'; 203 ;; 204 --debug-shell) 205 _DEBUG_PRINT_SHELL='yes'; 206 ;; 207 --debug-stacks) 208 _DEBUG_STACKS='yes'; 209 ;; 210 --debug-tmpdir) 211 _DEBUG_PRINT_TMPDIR='yes'; 212 ;; 213 --debug-user) 214 _DEBUG_USER_WITH_STACK='yes'; 215 ;; 216 esac; 217 ;; 218 esac; 219 done 220 ;; 221esac; 222 223if test _"${_DEBUG_PRINT_PARAMS}"_ = _yes_ 224then 225 echo "parameters: $@" >&2; 226fi; 227 228if test _"${_DEBUG_PRINT_SHELL}"_ = _yes_ 229then 230 if test _"${_SHELL}"_ = __ 231 then 232 if test _"${POSIXLY_CORRECT}"_ = _y_ 233 then 234 echo 'shell: bash as /bin/sh (none specified)' >&2; 235 else 236 echo 'shell: /bin/sh (none specified)' >&2; 237 fi; 238 else 239 echo "shell: ${_SHELL}" >&2; 240 fi; 241fi; 242 243 244######################################################################## 245# Environment Variables 246######################################################################## 247 248# Environment variables that exist only for this file start with an 249# underscore letter. Global variables to this file are written in 250# upper case letters, e.g. $_GLOBAL_VARIABLE; temporary variables 251# start with an underline and use only lower case letters and 252# underlines, e.g. $_local_variable . 253 254# [A-Z]* system variables, e.g. $MANPATH 255# _[A-Z_]* global file variables, e.g. $_MAN_PATH 256# _[a-z_]* temporary variables, e.g. $_manpath 257 258# Due to incompatibilities of the `ash' shell, the name of loop 259# variables in `for' must be single character 260# [a-z] local loop variables, e.g. $i 261 262 263######################################################################## 264# read-only variables (global to this file) 265######################################################################## 266 267# function return values; `0' means ok; other values are error codes 268export _ALL_EXIT; 269export _BAD; 270export _GOOD; 271export _NO; 272export _OK; 273export _YES; 274 275_GOOD='0'; # return ok 276_BAD='1'; # return negatively, error code `1' 277# $_ERROR was already defined as `7' in groffer.sh. 278 279_NO="${_BAD}"; 280_YES="${_GOOD}"; 281_OK="${_GOOD}"; 282 283# quasi-functions, call with `eval', e.g `eval "${return_ok}"' 284export return_ok; 285export return_good; 286export return_bad; 287export return_yes; 288export return_no; 289export return_error; 290export return_var; 291return_ok="func_pop; return ${_OK}"; 292return_good="func_pop; return ${_GOOD}"; 293return_bad="func_pop; return ${_BAD}"; 294return_yes="func_pop; return ${_YES}"; 295return_no="func_pop; return ${_NO}"; 296return_error="func_pop; return ${_ERROR}"; 297return_var="func_pop; return"; # add number, e.g. `eval "${return_var} $n' 298 299 300export _DEFAULT_MODES; 301_DEFAULT_MODES='x,ps,tty'; 302export _DEFAULT_RESOLUTION; 303_DEFAULT_RESOLUTION='75'; 304 305export _DEFAULT_TTY_DEVICE; 306_DEFAULT_TTY_DEVICE='latin1'; 307 308# _VIEWER_* viewer programs for different modes (only X is necessary) 309# _VIEWER_* a comma-separated list of viewer programs (with options) 310export _VIEWER_DVI; # viewer program for dvi mode 311export _VIEWER_HTML_TTY; # viewer program for html mode in tty 312export _VIEWER_HTML_X; # viewer program for html mode in X 313export _VIEWER_PDF; # viewer program for pdf mode 314export _VIEWER_PS; # viewer program for ps mode 315export _VIEWER_X; # viewer program for X mode 316_VIEWER_DVI='kdvi,xdvi,dvilx'; 317_VIEWER_HTML_TTY='lynx'; 318_VIEWER_HTML_X='konqueror,mozilla,netscape,galeon,opera,amaya,arena'; 319_VIEWER_PDF='kghostview --scale 1.45,ggv,xpdf,acroread,kpdf'; 320_VIEWER_PS='kghostview --scale 1.45,ggv,gv,ghostview,gs_x11,gs'; 321_VIEWER_X='gxditview,xditview'; 322 323# Search automatically in standard sections `1' to `8', and in the 324# traditional sections `9', `n', and `o'. On many systems, there 325# exist even more sections, mostly containing a set of man pages 326# special to a specific program package. These aren't searched for 327# automatically, but must be specified on the command line. 328export _MAN_AUTO_SEC_LIST; 329_MAN_AUTO_SEC_LIST="'1' '2' '3' '4' '5' '6' '7' '8' '9' 'n' 'o'"; 330export _MAN_AUTO_SEC_CHARS; 331_MAN_AUTO_SEC_CHARS='[123456789no]'; 332 333export _SPACE_SED; 334_SPACE_SED='['"${_SP}${_TAB}"']'; 335 336export _SPACE_CASE; 337_SPACE_CASE='[\'"${_SP}"'\'"${_TAB}"']'; 338 339export _PROCESS_ID; # for shutting down the program 340_PROCESS_ID="$$"; 341 342 343############ the command line options of the involved programs 344# 345# The naming scheme for the options environment names is 346# $_OPTS_<prog>_<length>[_<argspec>] 347# 348# <prog>: program name GROFFER, GROFF, or CMDLINE (for all 349# command line options) 350# <length>: LONG (long options) or SHORT (single character options) 351# <argspec>: ARG for options with argument, NA for no argument; 352# without _<argspec> both the ones with and without arg. 353# 354# Each option that takes an argument must be specified with a 355# trailing : (colon). 356 357# exports 358export _OPTS_GROFFER_SHORT_NA; 359export _OPTS_GROFFER_SHORT_ARG; 360export _OPTS_GROFFER_LONG_NA; 361export _OPTS_GROFFER_LONG_ARG; 362export _OPTS_GROFF_SHORT_NA; 363export _OPTS_GROFF_SHORT_ARG; 364export _OPTS_GROFF_LONG_NA; 365export _OPTS_GROFF_LONG_ARG; 366export _OPTS_X_SHORT_ARG; 367export _OPTS_X_SHORT_NA; 368export _OPTS_X_LONG_ARG; 369export _OPTS_X_LONG_NA; 370export _OPTS_MAN_SHORT_ARG; 371export _OPTS_MAN_SHORT_NA; 372export _OPTS_MAN_LONG_ARG; 373export _OPTS_MAN_LONG_NA; 374export _OPTS_MANOPT_SHORT_ARG; 375export _OPTS_MANOPT_SHORT_NA; 376export _OPTS_MANOPT_LONG_ARG; 377export _OPTS_MANOPT_LONG_NA; 378export _OPTS_CMDLINE_SHORT_NA; 379export _OPTS_CMDLINE_SHORT_ARG; 380export _OPTS_CMDLINE_LONG_NA; 381export _OPTS_CMDLINE_LONG_ARG; 382 383###### groffer native options 384 385_OPTS_GROFFER_SHORT_NA="'h' 'Q' 'v' 'V' 'X' 'Z'"; 386_OPTS_GROFFER_SHORT_ARG="'T'"; 387 388_OPTS_GROFFER_LONG_NA="'auto' \ 389'apropos' 'apropos-data' 'apropos-devel' 'apropos-progs' \ 390'debug' 'debug-all' 'debug-keep' 'debug-lm' 'debug-params' 'debug-shell' \ 391'debug-stacks' 'debug-tmpdir' 'debug-user' 'default' 'do-nothing' 'dvi' \ 392'groff' 'help' 'intermediate-output' 'html' 'man' \ 393'no-location' 'no-man' 'no-special' 'pdf' 'ps' 'rv' 'source' \ 394'text' 'text-device' \ 395'tty' 'tty-device' 'version' 'whatis' 'where' 'www' 'x' 'X'"; 396 397_OPTS_GROFFER_LONG_ARG="\ 398'default-modes' 'device' 'dvi-viewer' 'dvi-viewer-tty' 'extension' 'fg' \ 399'fn' 'font' 'foreground' 'html-viewer' 'html-viewer-tty' 'mode' \ 400'pdf-viewer' 'pdf-viewer-tty' 'print' 'ps-viewer' 'ps-viewer-tty' 'shell' \ 401'title' 'tty-viewer' 'tty-viewer-tty' 'www-viewer' 'www-viewer-tty' \ 402'x-viewer' 'x-viewer-tty' 'X-viewer' 'X-viewer-tty'"; 403 404##### groffer options inhereted from groff 405 406_OPTS_GROFF_SHORT_NA="'a' 'b' 'c' 'C' 'e' 'E' 'g' 'G' 'i' 'l' 'N' 'p' \ 407'R' 's' 'S' 't' 'U' 'z'"; 408_OPTS_GROFF_SHORT_ARG="'d' 'f' 'F' 'I' 'L' 'm' 'M' 'n' 'o' 'P' 'r' \ 409'w' 'W'"; 410_OPTS_GROFF_LONG_NA=""; 411_OPTS_GROFF_LONG_ARG=""; 412 413##### groffer options inhereted from the X Window toolkit 414 415_OPTS_X_SHORT_NA=""; 416_OPTS_X_SHORT_ARG=""; 417 418_OPTS_X_LONG_NA="'iconic' 'rv'"; 419 420_OPTS_X_LONG_ARG="'background' 'bd' 'bg' 'bordercolor' 'borderwidth' \ 421'bw' 'display' 'fg' 'fn' 'font' 'foreground' 'ft' 'geometry' \ 422'resolution' 'title' 'xrm'"; 423 424###### groffer options inherited from man 425 426_OPTS_MAN_SHORT_NA=""; 427_OPTS_MAN_SHORT_ARG=""; 428 429_OPTS_MAN_LONG_NA="'all' 'ascii' 'catman' 'ditroff' \ 430'local-file' 'location' 'troff' 'update'"; 431 432_OPTS_MAN_LONG_ARG="'locale' 'manpath' \ 433'pager' 'preprocessor' 'prompt' 'sections' 'systems' 'troff-device'"; 434 435###### additional options for parsing $MANOPT only 436 437_OPTS_MANOPT_SHORT_NA="'7' 'a' 'c' 'd' 'D' 'f' 'h' 'k' 'l' 't' 'u' \ 438'V' 'w' 'Z'"; 439_OPTS_MANOPT_SHORT_ARG="'e' 'L' 'm' 'M' 'p' 'P' 'r' 'S' 'T'"; 440 441_OPTS_MANOPT_LONG_NA="${_OPTS_MAN_LONG_NA} \ 442'apropos' 'debug' 'default' 'help' 'html' 'ignore-case' 'location-cat' \ 443'match-case' 'troff' 'update' 'version' 'whatis' 'where' 'where-cat'"; 444 445_OPTS_MANOPT_LONG_ARG="${_OPTS_MAN_LONG_NA} \ 446'config_file' 'encoding' 'extension' 'locale'"; 447 448###### collections of command line options 449 450_OPTS_CMDLINE_SHORT_NA="${_OPTS_GROFFER_SHORT_NA} \ 451${_OPTS_GROFF_SHORT_NA} ${_OPTS_X_SHORT_NA} ${_OPTS_MAN_SHORT_NA}"; 452_OPTS_CMDLINE_SHORT_ARG="${_OPTS_GROFFER_SHORT_ARG} \ 453${_OPTS_GROFF_SHORT_ARG} ${_OPTS_X_SHORT_ARG} ${_OPTS_MAN_SHORT_ARG}"; 454 455_OPTS_CMDLINE_LONG_NA="${_OPTS_GROFFER_LONG_NA} \ 456${_OPTS_GROFF_LONG_NA} ${_OPTS_X_LONG_NA} ${_OPTS_MAN_LONG_NA}"; 457_OPTS_CMDLINE_LONG_ARG="${_OPTS_GROFFER_LONG_ARG} \ 458${_OPTS_GROFF_LONG_ARG} ${_OPTS_MAN_LONG_ARG} ${_OPTS_X_LONG_ARG}"; 459 460 461######################################################################## 462# read-write variables (global to this file) 463######################################################################## 464 465export _ALL_PARAMS; # All options and file name parameters 466export _ADDOPTS_GROFF; # Transp. options for groff (`eval'). 467export _ADDOPTS_POST; # Transp. options postproc (`eval'). 468export _ADDOPTS_X; # Transp. options X postproc (`eval'). 469export _APROPOS_PROG; # Program to run apropos. 470export _APROPOS_SECTIONS; # Sections for different --apropos-*. 471export _DEFAULT_MODES; # Set default modes. 472export _DISPLAY_MODE; # Display mode. 473export _DISPLAY_PROG; # Viewer program to be used for display. 474export _DISPLAY_ARGS; # X resources for the viewer program. 475export _FILEARGS; # Stores filespec parameters. 476export _FILESPEC_ARG; # Stores the actual filespec parameter. 477export _FUNC_STACK; # Store debugging information. 478export _REGISTERED_TITLE; # Processed file names. 479# _HAS_* from availability tests 480export _HAS_COMPRESSION; # `yes' if gzip compression is available 481export _HAS_BZIP; # `yes' if bzip2 compression is available 482# _MAN_* finally used configuration of man searching 483export _MAN_ALL; # search all man pages per filespec 484export _MAN_ENABLE; # enable search for man pages 485export _MAN_EXT; # extension for man pages 486export _MAN_FORCE; # force file parameter to be man pages 487export _MAN_IS_SETUP; # setup man variables only once 488export _MAN_LANG; # language for man pages 489export _MAN_LANG2; # language for man pages 490export _MAN_LANG_DONE; # language dirs added to man path 491export _MAN_PATH; # search path for man pages 492export _MAN_SEC; # sections for man pages; sep. `:' 493export _MAN_SEC_DONE; # sections added to man path 494export _MAN_SYS; # system names for man pages; sep. `,' 495export _MAN_SYS; # system names added to man path 496# _MANOPT_* as parsed from $MANOPT 497export _MANOPT_ALL; # $MANOPT --all 498export _MANOPT_EXTENSION; # $MANOPT --extension 499export _MANOPT_LANG; # $MANOPT --locale 500export _MANOPT_PATH; # $MANOPT --manpath 501export _MANOPT_PAGER; # $MANOPT --pager 502export _MANOPT_SEC; # $MANOPT --sections 503export _MANOPT_SYS; # $MANOPT --systems 504# _OPT_* as parsed from groffer command line 505export _OPT_ALL; # display all suitable man pages. 506export _OPT_APROPOS; # call `apropos' program. 507export _OPT_BD; # set border color in some modes. 508export _OPT_BG; # set background color in some modes. 509export _OPT_BW; # set border width in some modes. 510export _OPT_DEFAULT_MODES; # `,'-list of modes when no mode given. 511export _OPT_DEVICE; # device option. 512export _OPT_DO_NOTHING; # do nothing in main_display(). 513export _OPT_DISPLAY; # set X display. 514export _OPT_FG; # set foreground color in some modes. 515export _OPT_FN; # set font in some modes. 516export _OPT_GEOMETRY; # set size and position of viewer in X. 517export _OPT_ICONIC; # -iconic option for X viewers. 518export _OPT_LANG; # set language for man pages 519export _OPT_LOCATION; # print processed file names to stderr 520export _OPT_MODE; # values: X, tty, Q, Z, "" 521export _OPT_MANPATH; # manual setting of path for man-pages 522export _OPT_PAGER; # specify paging program for tty mode 523export _OPT_RESOLUTION; # set X resolution in dpi 524export _OPT_RV; # reverse fore- and background colors. 525export _OPT_SECTIONS; # sections for man page search 526export _OPT_SYSTEMS; # man pages of different OS's 527export _OPT_TITLE; # title for gxditview window 528export _OPT_TEXT_DEVICE; # set device for tty mode. 529export _OPT_V; # groff option -V. 530export _OPT_VIEWER_DVI; # viewer program for dvi mode 531export _OPT_VIEWER_PDF; # viewer program for pdf mode 532export _OPT_VIEWER_PS; # viewer program for ps mode 533export _OPT_VIEWER_HTML; # viewer program for html mode 534export _OPT_VIEWER_X; # viewer program for x mode 535export _OPT_WHATIS; # print the man description 536export _OPT_XRM; # specify X resource. 537export _OPT_Z; # groff option -Z. 538export _OUTPUT_FILE_NAME; # output generated, see main_set_res..() 539export _VIEWER_TERMINAL; # viewer options for terminal (--*-viewer-tty) 540# _TMP_* temporary directory and files 541export _TMP_DIR; # groffer directory for temporary files 542export _TMP_CAT; # stores concatenation of everything 543export _TMP_STDIN; # stores stdin, if any 544 545# these variables are preset in section `Preset' after the rudim. test 546 547 548######################################################################## 549# Preset and reset of read-write global variables 550######################################################################## 551 552 553export _START_DIR; # directory at start time of the script 554_START_DIR="$(pwd)"; 555 556# For variables that can be reset by option `--default', see reset(). 557 558_FILEARGS=''; 559 560# _HAS_* from availability tests 561_HAS_COMPRESSION=''; 562_HAS_BZIP=''; 563 564# _TMP_* temporary files 565_TMP_DIR=''; 566_TMP_CAT=''; 567_TMP_CONF=''; 568_TMP_STDIN=''; 569 570 571######################################################################## 572# reset () 573# 574# Reset the variables that can be affected by options to their default. 575# 576reset() 577{ 578 if test "$#" -ne 0 579 then 580 error "reset() does not have arguments."; 581 fi; 582 583 _ADDOPTS_GROFF=''; 584 _ADDOPTS_POST=''; 585 _ADDOPTS_X=''; 586 _APROPOS_PROG=''; 587 _APROPOS_SECTIONS=''; 588 _DISPLAY_ARGS=''; 589 _DISPLAY_MODE=''; 590 _DISPLAY_PROG=''; 591 _REGISTERED_TITLE=''; 592 593 # _MAN_* finally used configuration of man searching 594 _MAN_ALL='no'; 595 _MAN_ENABLE='yes'; # do search for man-pages 596 _MAN_EXT=''; 597 _MAN_FORCE='no'; # first local file, then search man page 598 _MAN_IS_SETUP='no'; 599 _MAN_LANG=''; 600 _MAN_LANG2=''; 601 _MAN_PATH=''; 602 _MAN_SEC=''; 603 _MAN_SEC_DONE='no'; 604 _MAN_SYS=''; 605 _MAN_SYS_DONE='no'; 606 607 # _MANOPT_* as parsed from $MANOPT 608 _MANOPT_ALL='no'; 609 _MANOPT_EXTENSION=''; 610 _MANOPT_LANG=''; 611 _MANOPT_PATH=''; 612 _MANOPT_PAGER=''; 613 _MANOPT_SEC=''; 614 _MANOPT_SYS=''; 615 616 # _OPT_* as parsed from groffer command line 617 _OPT_ALL='no'; 618 _OPT_APROPOS='no'; 619 _OPT_BD=''; 620 _OPT_BG=''; 621 _OPT_BW=''; 622 _OPT_DEFAULT_MODES=''; 623 _OPT_DEVICE=''; 624 _OPT_DISPLAY=''; 625 _OPT_DO_NOTHING='no'; 626 _OPT_FG=''; 627 _OPT_FN=''; 628 _OPT_GEOMETRY=''; 629 _OPT_ICONIC='no'; 630 _OPT_LANG=''; 631 _OPT_LOCATION='no'; 632 _OPT_MODE=''; 633 _OPT_MANPATH=''; 634 _OPT_PAGER=''; 635 _OPT_RESOLUTION=''; 636 _OPT_RV='no'; 637 _OPT_SECTIONS=''; 638 _OPT_SYSTEMS=''; 639 _OPT_TITLE=''; 640 _OPT_TEXT_DEVICE=''; 641 _OPT_V='no'; 642 _OPT_VIEWER_DVI=''; 643 _OPT_VIEWER_PDF=''; 644 _OPT_VIEWER_PS=''; 645 _OPT_VIEWER_HTML=''; 646 _OPT_VIEWER_X=''; 647 _OPT_WHATIS='no'; 648 _OPT_XRM=''; 649 _OPT_Z='no'; 650 _VIEWER_TERMINAL='no'; 651} 652 653reset; 654 655 656######################################################################## 657# Functions for error handling and debugging 658######################################################################## 659 660 661############## 662# echo1 (<text>*) 663# 664# Output to stdout. 665# 666# Arguments : arbitrary text including `-'. 667# 668echo1() 669{ 670 cat <<EOF 671$@ 672EOF 673} 674 675 676############## 677# echo2 (<text>*) 678# 679# Output to stderr. 680# 681# Arguments : arbitrary text. 682# 683echo2() 684{ 685 cat >&2 <<EOF 686$@ 687EOF 688} 689 690 691############## 692# landmark (<text>) 693# 694# Print <text> to standard error as a debugging aid. 695# 696# Globals: $_DEBUG_LM 697# 698landmark() 699{ 700 if test _"${_DEBUG_LM}"_ = _yes_ 701 then 702 echo2 "LM: $*"; 703 fi; 704} 705 706landmark "1: debugging functions"; 707 708 709############## 710# clean_up () 711# 712# Clean up at exit. 713# 714clean_up() 715{ 716 cd "${_START_DIR}" >"${_NULL_DEV}" 2>&1; 717 if test _${_DEBUG_KEEP_FILES}_ = _yes_ 718 then 719 echo2 "Kept temporary directory ${_TMP_DIR}." 720 else 721 if test _"${_TMP_DIR}"_ != __ 722 then 723 if test -d "${_TMP_DIR}" || test -f "${_TMP_DIR}" 724 then 725 rm -f -r "${_TMP_DIR}" >${_NULL_DEV} 2>&1; 726 fi; 727 fi; 728 fi; 729} 730 731 732############# 733# diag (text>*) 734# 735# Output a diagnostic message to stderr 736# 737diag() 738{ 739 echo2 '>>>>>'"$*"; 740} 741 742 743############# 744# error (<text>*) 745# 746# Print an error message to standard error, print the function stack, 747# exit with an error condition. The argument should contain the name 748# of the function from which it was called. This is for system errors. 749# 750error() 751{ 752 case "$#" in 753 1) echo2 'groffer error: '"$1"; ;; 754 *) echo2 'groffer error: wrong number of arguments in error().'; ;; 755 esac; 756 func_stack_dump; 757 if test _"${_TMP_DIR}"_ != __ && test -d "${_TMP_DIR}" 758 then 759 : >"${_TMP_DIR}"/,error; 760 fi; 761 exit "${_ERROR}"; 762} 763 764 765############# 766# error_user (<text>*) 767# 768# Print an error message to standard error; exit with an error condition. 769# The error is supposed to be produce by the user. So the funtion stack 770# is omitted. 771# 772error_user() 773{ 774 case "$#" in 775 1) 776 echo2 'groffer error: '"$1"; 777 ;; 778 *) 779 echo2 'groffer error: wrong number of arguments in error_user().'; 780 ;; 781 esac; 782 if test _"${_DEBUG_USER_WITH_STACK}"_ = _yes_ 783 then 784 func_stack_dump; 785 fi; 786 if test _"${_TMP_DIR}"_ != __ && test -d "${_TMP_DIR}" 787 then 788 : >"${_TMP_DIR}"/,error; 789 fi; 790 exit "${_ERROR}"; 791} 792 793 794############# 795# exit_test () 796# 797# Test whether the former command ended with error(). Exit again. 798# 799# Globals: $_ERROR 800# 801exit_test() 802{ 803 if test "$?" = "${_ERROR}" 804 then 805 exit ${_ERROR}; 806 fi; 807 if test _"${_TMP_DIR}"_ != __ && test -f "${_TMP_DIR}"/,error 808 then 809 exit ${_ERROR}; 810 fi; 811} 812 813 814############# 815# func_check (<func_name> <rel_op> <nr_args> "$@") 816# 817# Check number of arguments and register to _FUNC_STACK. 818# 819# Arguments: >=3 820# <func_name>: name of the calling function. 821# <rel_op>: a relational operator: = != < > <= >= 822# <nr_args>: number of arguments to be checked against <operator> 823# "$@": the arguments of the calling function. 824# 825# Variable prefix: fc 826# 827func_check() 828{ 829 if test "$#" -lt 3 830 then 831 error 'func_check() needs at least 3 arguments.'; 832 fi; 833 fc_fname="$1"; 834 case "$3" in 835 1) 836 fc_nargs="$3"; 837 fc_s=''; 838 ;; 839 0|[2-9]) 840 fc_nargs="$3"; 841 fc_s='s'; 842 ;; 843 *) 844 error "func_check(): third argument must be a digit."; 845 ;; 846 esac; 847 case "$2" in 848 '='|'-eq') 849 fc_op='-eq'; 850 fc_comp='exactly'; 851 ;; 852 '>='|'-ge') 853 fc_op='-ge'; 854 fc_comp='at least'; 855 ;; 856 '<='|'-le') 857 fc_op='-le'; 858 fc_comp='at most'; 859 ;; 860 '<'|'-lt') 861 fc_op='-lt'; 862 fc_comp='less than'; 863 ;; 864 '>'|'-gt') 865 fc_op='-gt'; 866 fc_comp='more than'; 867 ;; 868 '!='|'-ne') 869 fc_op='-ne'; 870 fc_comp='not'; 871 ;; 872 *) 873 error \ 874 'func_check(): second argument is not a relational operator.'; 875 ;; 876 esac; 877 shift; 878 shift; 879 shift; 880 if test "$#" "${fc_op}" "${fc_nargs}" 881 then 882 do_nothing; 883 else 884 error "func_check(): \ 885${fc_fname}"'() needs '"${fc_comp} ${fc_nargs}"' argument'"${fc_s}"'.'; 886 fi; 887 func_push "${fc_fname}"; 888 if test _"${_DEBUG_STACKS}"_ = _yes_ 889 then 890 echo2 '+++ '"${fc_fname} $@"; 891 echo2 '>>> '"${_FUNC_STACK}"; 892 fi; 893 eval ${_UNSET} fc_comp; 894 eval ${_UNSET} fc_fname; 895 eval ${_UNSET} fc_nargs; 896 eval ${_UNSET} fc_op; 897 eval ${_UNSET} fc_s; 898} 899 900 901############# 902# func_pop () 903# 904# Retrieve the top element from the stack. 905# 906# The stack elements are separated by `!'; the popped element is 907# identical to the original element, except that all `!' characters 908# were removed. 909# 910# Arguments: 1 911# 912func_pop() 913{ 914 if test "$#" -ne 0 915 then 916 error 'func_pop() does not have arguments.'; 917 fi; 918 case "${_FUNC_STACK}" in 919 '') 920 if test _"${_DEBUG_STACKS}"_ = _yes_ 921 then 922 error 'func_pop(): stack is empty.'; 923 fi; 924 ;; 925 *!*) 926 # split at first bang `!'. 927 _FUNC_STACK="$(echo1 "${_FUNC_STACK}" | sed -e 's/^[^!]*!//')"; 928 exit_test; 929 ;; 930 *) 931 _FUNC_STACK=''; 932 ;; 933 esac; 934 if test _"${_DEBUG_STACKS}"_ = _yes_ 935 then 936 echo2 '<<< '"${_FUNC_STACK}"; 937 fi; 938} 939 940 941############# 942# func_push (<element>) 943# 944# Store another element to stack. 945# 946# The stack elements are separated by `!'; if <element> contains a `!' 947# it is removed first. 948# 949# Arguments: 1 950# 951# Variable prefix: fp 952# 953func_push() 954{ 955 if test "$#" -ne 1 956 then 957 error 'func_push() needs 1 argument.'; 958 fi; 959 case "$1" in 960 *'!'*) 961 # remove all bangs `!'. 962 fp_element="$(echo1 "$1" | sed -e 's/!//g')"; 963 exit_test; 964 ;; 965 *) 966 fp_element="$1"; 967 ;; 968 esac; 969 if test _"${_FUNC_STACK}"_ = __ 970 then 971 _FUNC_STACK="${fp_element}"; 972 else 973 _FUNC_STACK="${fp_element}!${_FUNC_STACK}"; 974 fi; 975 eval ${_UNSET} fp_element; 976} 977 978 979############# 980# func_stack_dump () 981# 982# Print the content of the stack. Ignore the arguments. 983# 984func_stack_dump() 985{ 986 diag 'call stack: '"${_FUNC_STACK}"; 987} 988 989 990######################################################################## 991# System Test 992######################################################################## 993 994landmark "2: system test"; 995 996# Test the availability of the system utilities used in this script. 997 998 999######################################################################## 1000# Test of function `sed'. 1001# 1002 1003if test _"$(echo xTesTx \ 1004 | sed -e 's/^.\([Tt]e*x*sTT*\).*$/\1/' \ 1005 | sed -e 's|T|t|g')"_ != _test_ 1006then 1007 error 'Test of "sed" command failed.'; 1008fi; 1009 1010 1011######################################################################## 1012# Test of function `cat'. 1013# 1014if test _"$(echo test | cat)"_ != _test_ 1015then 1016 error 'Test of "cat" command failed.'; 1017fi; 1018 1019 1020######################################################################## 1021# Test for compression. 1022# 1023if test _"$(echo 'test' | gzip -c -d -f - 2>${_NULL_DEV})"_ = _test_ 1024then 1025 _HAS_COMPRESSION='yes'; 1026 if echo1 'test' | bzip2 -c 2>${_NULL_DEV} | bzip2 -t 2>${_NULL_DEV} \ 1027 && test _"$(echo 'test' | bzip2 -c 2>${_NULL_DEV} \ 1028 | bzip2 -d -c 2>${_NULL_DEV})"_ \ 1029 = _test_ 1030 then 1031 _HAS_BZIP='yes'; 1032 else 1033 _HAS_BZIP='no'; 1034 fi; 1035else 1036 _HAS_COMPRESSION='no'; 1037 _HAS_BZIP='no'; 1038fi; 1039 1040 1041######################################################################## 1042# Definition of normal Functions in alphabetical order 1043######################################################################## 1044landmark "3: functions"; 1045 1046######################################################################## 1047# apropos_filespec () 1048# 1049# Setup for the --apropos* options 1050# 1051apropos_filespec() 1052{ 1053 1054 func_check apropos_filespec '=' 0 "$@"; 1055 if obj _OPT_APROPOS is_yes 1056 then 1057 eval to_tmp_line \ 1058 "'.SH $(echo1 "${_FILESPEC_ARG}" | sed 's/[^\\]-/\\-/g')'"; 1059 exit_test; 1060 if obj _APROPOS_PROG is_empty 1061 then 1062 error 'apropos_filespec: apropos_setup() must be run first.'; 1063 fi; 1064 if obj _APROPOS_SECTIONS is_empty 1065 then 1066 if obj _OPT_SECTIONS is_empty 1067 then 1068 s='^.*(.*).*$'; 1069 else 1070 s='^.*(['"$(echo1 "${_OPT_SECTIONS}" | sed -e 's/://g')"']'; 1071 fi; 1072 else 1073 s='^.*(['"${_APROPOS_SECTIONS}"']'; 1074 fi; 1075 eval "${_APROPOS_PROG}" "'${_FILESPEC_ARG}'" | \ 1076 sed -n -e ' 1077/^'"${_FILESPEC_ARG}"': /p 1078/'"$s"'/p 1079' | \ 1080 sort |\ 1081 sed -e ' 1082s/^\(.* (..*)\) *- *\(.*\)$/\.br\n\.TP 15\n\.BR \1\n\2/ 1083' >>"${_TMP_CAT}"; 1084 fi; 1085 eval "${return_ok}"; 1086} 1087 1088 1089######################################################################## 1090# apropos_setup () 1091# 1092# Setup for the --apropos* options 1093# 1094apropos_setup() 1095{ 1096 func_check apropos_setup '=' 0 "$@"; 1097 if obj _OPT_APROPOS is_yes 1098 then 1099 if is_prog apropos 1100 then 1101 _APROPOS_PROG='apropos'; 1102 elif is_prog man 1103 then 1104 if man --apropos man >${_NULL_DEV} 2>${_NULL_DEV} 1105 then 1106 _APROPOS_PROG='man --apropos'; 1107 elif man -k man >${_NULL_DEV} 2>${_NULL_DEV} 1108 then 1109 _APROPOS_PROG='man -k'; 1110 fi; 1111 fi; 1112 if obj _APROPOS_PROG is_empty 1113 then 1114 error 'apropos_setup: no apropos program available.'; 1115 fi; 1116 to_tmp_line '.TH GROFFER APROPOS'; 1117 fi; 1118 eval "${return_ok}"; 1119} 1120 1121 1122######################################################################## 1123# base_name (<path>) 1124# 1125# Get the file name part of <path>, i.e. delete everything up to last 1126# `/' from the beginning of <path>. Remove final slashes, too, to get a 1127# non-empty output. 1128# 1129# Arguments : 1 1130# Output : the file name part (without slashes) 1131# 1132# Variable prefix: bn 1133# 1134base_name() 1135{ 1136 func_check base_name = 1 "$@"; 1137 bn_name="$1"; 1138 case "${bn_name}" in 1139 */) 1140 # delete all final slashes 1141 bn_name="$(echo1 "${bn_name}" | sed -e 's|//*$||')"; 1142 exit_test; 1143 ;; 1144 esac; 1145 case "${bn_name}" in 1146 /|'') 1147 eval ${_UNSET} bn_name; 1148 eval "${return_bad}"; 1149 ;; 1150 */*) 1151 # delete everything before and including the last slash `/'. 1152 echo1 "${bn_name}" | sed -e 's|^.*//*\([^/]*\)$|\1|'; 1153 ;; 1154 *) 1155 obj bn_name echo1; 1156 ;; 1157 esac; 1158 eval ${_UNSET} bn_name; 1159 eval "${return_ok}"; 1160} 1161 1162 1163######################################################################## 1164# cat_z (<file>) 1165# 1166# Decompress if possible or just print <file> to standard output. 1167# 1168# gzip, bzip2, and .Z decompression is supported. 1169# 1170# Arguments: 1, a file name. 1171# Output: the content of <file>, possibly decompressed. 1172# 1173if test _"${_HAS_COMPRESSION}"_ = _yes_ 1174then 1175 cat_z() 1176 { 1177 func_check cat_z = 1 "$@"; 1178 case "$1" in 1179 '') 1180 error 'cat_z(): empty file name'; 1181 ;; 1182 '-') 1183 error 'cat_z(): for standard input use save_stdin()'; 1184 ;; 1185 esac; 1186 if obj _HAS_BZIP is_yes 1187 then 1188 if bzip2 -t "$1" 2>${_NULL_DEV} 1189 then 1190 bzip2 -c -d "$1" 2>${_NULL_DEV}; 1191 eval "${return_ok}"; 1192 fi; 1193 fi; 1194 gzip -c -d -f "$1" 2>${_NULL_DEV}; 1195 eval "${return_ok}"; 1196 } 1197else 1198 cat_z() 1199 { 1200 func_check cat_z = 1 "$@"; 1201 cat "$1"; 1202 eval "${return_ok}"; 1203 } 1204fi; 1205 1206 1207######################################################################## 1208# clean_up () 1209# 1210# Do the final cleaning up before exiting; used by the trap calls. 1211# 1212# defined above 1213 1214 1215######################################################################## 1216# diag (<text>*) 1217# 1218# Print marked message to standard error; useful for debugging. 1219# 1220# defined above 1221 1222 1223######################################################################## 1224landmark '4: dirname()*'; 1225######################################################################## 1226 1227####################################################################### 1228# dirname_append (<dir> <name>) 1229# 1230# Append `name' to `dir' with clean handling of `/'. 1231# 1232# Arguments : 2 1233# Output : the generated new directory name <dir>/<name> 1234# 1235dirname_append() 1236{ 1237 func_check dirname_append = 2 "$@"; 1238 if is_empty "$1" 1239 then 1240 error "dir_append(): first argument is empty."; 1241 fi; 1242 if is_empty "$2" 1243 then 1244 echo1 "$1"; 1245 else 1246 dirname_chop "$1"/"$2"; 1247 fi; 1248 eval "${return_ok}"; 1249} 1250 1251 1252######################################################################## 1253# dirname_chop (<name>) 1254# 1255# Remove unnecessary slashes from directory name. 1256# 1257# Argument: 1, a directory name. 1258# Output: path without double, or trailing slashes. 1259# 1260# Variable prefix: dc 1261# 1262dirname_chop() 1263{ 1264 func_check dirname_chop = 1 "$@"; 1265 # replace all multiple slashes by a single slash `/'. 1266 dc_res="$(echo1 "$1" | sed -e 's|///*|/|g')"; 1267 exit_test; 1268 case "${dc_res}" in 1269 ?*/) 1270 # remove trailing slash '/'; 1271 echo1 "${dc_res}" | sed -e 's|/$||'; 1272 ;; 1273 *) 1274 obj dc_res echo1 1275 ;; 1276 esac; 1277 eval ${_UNSET} dc_res; 1278 eval "${return_ok}"; 1279} 1280 1281 1282######################################################################## 1283# do_filearg (<filearg>) 1284# 1285# Append the file, man-page, or standard input corresponding to the 1286# argument to the temporary file. If this is compressed in the gzip 1287# or Z format it is decompressed. A title element is generated. 1288# 1289# Argument either: 1290# - name of an existing file. 1291# - `-' to represent standard input (several times allowed). 1292# - `man:name.(section)' the man-page for `name' in `section'. 1293# - `man:name.section' the man-page for `name' in `section'. 1294# - `man:name' the man-page for `name' in the lowest `section'. 1295# - `name.section' the man-page for `name' in `section'. 1296# - `name' the man-page for `name' in the lowest `section'. 1297# Globals : 1298# $_TMP_STDIN, $_MAN_ENABLE, $_MAN_IS_SETUP, $_OPT_MAN 1299# 1300# Output : none 1301# Return : $_GOOD if found, ${_BAD} otherwise. 1302# 1303# Variable prefix: df 1304# 1305do_filearg() 1306{ 1307 func_check do_filearg = 1 "$@"; 1308 df_filespec="$1"; 1309 # store sequence into positional parameters 1310 case "${df_filespec}" in 1311 '') 1312 eval ${_UNSET} df_filespec; 1313 eval "${return_good}"; 1314 ;; 1315 '-') 1316 register_file '-'; 1317 eval ${_UNSET} df_filespec; 1318 eval "${return_good}"; 1319 ;; 1320 */*) # with directory part; so no man search 1321 set 'File'; 1322 ;; 1323 *) 1324 if obj _MAN_ENABLE is_yes 1325 then 1326 if obj _MAN_FORCE is_yes 1327 then 1328 set 'Manpage' 'File'; 1329 else 1330 set 'File' 'Manpage'; 1331 fi; 1332 else 1333 set 'File'; 1334 fi; 1335 ;; 1336 esac; 1337 for i 1338 do 1339 case "$i" in 1340 File) 1341 if test -f "${df_filespec}" 1342 then 1343 if test -r "${df_filespec}" 1344 then 1345 register_file "${df_filespec}"; 1346 eval ${_UNSET} df_filespec; 1347 eval ${_UNSET} df_no_man; 1348 eval "${return_good}"; 1349 else 1350 echo2 "could not read \`${df_filespec}'"; 1351 eval ${_UNSET} df_filespec; 1352 eval ${_UNSET} df_no_man; 1353 eval "${return_bad}"; 1354 fi; 1355 else 1356 if obj df_no_man is_not_empty 1357 then 1358 if obj _OPT_WHATIS is_yes 1359 then 1360 to_tmp_line "This is neither a file nor a man page." 1361 else 1362 echo2 "\`${df_filespec}' is neither a file nor a man page." 1363 fi; 1364 fi; 1365 df_no_file=yes; 1366 continue; 1367 fi; 1368 ;; 1369 Manpage) # parse filespec as man page 1370 if obj _MAN_IS_SETUP is_not_yes 1371 then 1372 man_setup; 1373 fi; 1374 if man_do_filespec "${df_filespec}" 1375 then 1376 eval ${_UNSET} df_filespec; 1377 eval ${_UNSET} df_no_file; 1378 eval "${return_good}"; 1379 else 1380 if obj df_no_file is_not_empty 1381 then 1382 if obj _OPT_WHATIS is_yes 1383 then 1384 to_tmp_line "This is neither a file nor a man page." 1385 else 1386 echo2 "\`${df_filespec}' is neither a file nor a man page." 1387 fi; 1388 fi; 1389 df_no_man=yes; 1390 continue; 1391 fi; 1392 ;; 1393 esac; 1394 done; 1395 eval ${_UNSET} df_filespec; 1396 eval ${_UNSET} df_no_file; 1397 eval ${_UNSET} df_no_man; 1398 eval "${return_bad}"; 1399} # do_filearg() 1400 1401 1402######################################################################## 1403# do_nothing () 1404# 1405# Dummy function. 1406# 1407do_nothing() 1408{ 1409 eval return "${_OK}"; 1410} 1411 1412 1413######################################################################## 1414# echo2 (<text>*) 1415# 1416# Print to standard error with final line break. 1417# 1418# defined above 1419 1420 1421######################################################################## 1422# error (<text>*) 1423# 1424# Print error message and exit with error code. 1425# 1426# defined above 1427 1428 1429######################################################################## 1430# exit_test () 1431# 1432# Test whether the former command ended with error(). Exit again. 1433# 1434# defined above 1435 1436 1437######################################################################## 1438# func_check (<func_name> <rel_op> <nr_args> "$@") 1439# 1440# Check number of arguments and register to _FUNC_STACK. 1441# 1442# Arguments: >=3 1443# <func_name>: name of the calling function. 1444# <rel_op>: a relational operator: = != < > <= >= 1445# <nr_args>: number of arguments to be checked against <operator> 1446# "$@": the arguments of the calling function. 1447# 1448# defined above 1449 1450######################################################################### 1451# func_pop () 1452# 1453# Delete the top element from the function call stack. 1454# 1455# defined above 1456 1457 1458######################################################################## 1459# func_push (<element>) 1460# 1461# Store another element to function call stack. 1462# 1463# defined above 1464 1465 1466######################################################################## 1467# func_stack_dump () 1468# 1469# Print the content of the stack. 1470# 1471# defined above 1472 1473 1474######################################################################## 1475# get_first_essential (<arg>*) 1476# 1477# Retrieve first non-empty argument. 1478# 1479# Return : `1' if all arguments are empty, `0' if found. 1480# Output : the retrieved non-empty argument. 1481# 1482# Variable prefix: gfe 1483# 1484get_first_essential() 1485{ 1486 func_check get_first_essential '>=' 0 "$@"; 1487 if is_equal "$#" 0 1488 then 1489 eval "${return_ok}"; 1490 fi; 1491 for i 1492 do 1493 gfe_var="$i"; 1494 if obj gfe_var is_not_empty 1495 then 1496 obj gfe_var echo1; 1497 eval ${_UNSET} gfe_var; 1498 eval "${return_ok}"; 1499 fi; 1500 done; 1501 eval ${_UNSET} gfe_var; 1502 eval "${return_bad}"; 1503} 1504 1505 1506######################################################################## 1507landmark '5: is_*()'; 1508######################################################################## 1509 1510######################################################################## 1511# is_dir (<name>) 1512# 1513# Test whether `name' is a directory. 1514# 1515# Arguments : 1 1516# Return : `0' if arg1 is a directory, `1' otherwise. 1517# 1518is_dir() 1519{ 1520 func_check is_dir '=' 1 "$@"; 1521 if test _"$1"_ != __ && test -d "$1" && test -r "$1" 1522 then 1523 eval "${return_yes}"; 1524 fi; 1525 eval "${return_no}"; 1526} 1527 1528 1529######################################################################## 1530# is_empty (<string>) 1531# 1532# Test whether `string' is empty. 1533# 1534# Arguments : <=1 1535# Return : `0' if arg1 is empty or does not exist, `1' otherwise. 1536# 1537is_empty() 1538{ 1539 func_check is_empty '=' 1 "$@"; 1540 if test _"$1"_ = __ 1541 then 1542 eval "${return_yes}"; 1543 fi; 1544 eval "${return_no}"; 1545} 1546 1547 1548######################################################################## 1549# is_equal (<string1> <string2>) 1550# 1551# Test whether `string1' is equal to <string2>. 1552# 1553# Arguments : 2 1554# Return : `0' both arguments are equal strings, `1' otherwise. 1555# 1556is_equal() 1557{ 1558 func_check is_equal '=' 2 "$@"; 1559 if test _"$1"_ = _"$2"_ 1560 then 1561 eval "${return_yes}"; 1562 fi; 1563 eval "${return_no}"; 1564} 1565 1566 1567######################################################################## 1568# is_existing (<name>) 1569# 1570# Test whether `name' is an existing file or directory. Solaris 2.5 does 1571# not have `test -e'. 1572# 1573# Arguments : 1 1574# Return : `0' if arg1 exists, `1' otherwise. 1575# 1576is_existing() 1577{ 1578 func_check is_existing '=' 1 "$@"; 1579 if test _"$1"_ = __ 1580 then 1581 eval "${return_no}"; 1582 fi; 1583 if test -f "$1" || test -d "$1" || test -c "$1" 1584 then 1585 eval "${return_yes}"; 1586 fi; 1587 eval "${return_no}"; 1588} 1589 1590 1591######################################################################## 1592# is_file (<name>) 1593# 1594# Test whether `name' is a readable file. 1595# 1596# Arguments : 1 1597# Return : `0' if arg1 is a readable file, `1' otherwise. 1598# 1599is_file() 1600{ 1601 func_check is_file '=' 1 "$@"; 1602 if is_not_empty "$1" && test -f "$1" && test -r "$1" 1603 then 1604 eval "${return_yes}"; 1605 fi; 1606 eval "${return_no}"; 1607} 1608 1609 1610######################################################################## 1611# is_non_empty_file (<file_name>) 1612# 1613# Test whether `file_name' is a non-empty existing file. 1614# 1615# Arguments : <=1 1616# Return : 1617# `0' if arg1 is a non-empty existing file 1618# `1' otherwise 1619# 1620is_non_empty_file() 1621{ 1622 func_check is_non_empty_file '=' 1 "$@"; 1623 if is_file "$1" && test -s "$1" 1624 then 1625 eval "${return_yes}"; 1626 fi; 1627 eval "${return_no}"; 1628} 1629 1630 1631######################################################################## 1632# is_not_dir (<name>) 1633# 1634# Test whether `name' is not a readable directory. 1635# 1636# Arguments : 1 1637# Return : `0' if arg1 is a directory, `1' otherwise. 1638# 1639is_not_dir() 1640{ 1641 func_check is_not_dir '=' 1 "$@"; 1642 if is_dir "$1" 1643 then 1644 eval "${return_no}"; 1645 fi; 1646 eval "${return_yes}"; 1647} 1648 1649 1650######################################################################## 1651# is_not_empty (<string>) 1652# 1653# Test whether `string' is not empty. 1654# 1655# Arguments : <=1 1656# Return : `0' if arg1 exists and is not empty, `1' otherwise. 1657# 1658is_not_empty() 1659{ 1660 func_check is_not_empty '=' 1 "$@"; 1661 if is_empty "$1" 1662 then 1663 eval "${return_no}"; 1664 fi; 1665 eval "${return_yes}"; 1666} 1667 1668 1669######################################################################## 1670# is_not_equal (<string1> <string2>) 1671# 1672# Test whether `string1' differs from `string2'. 1673# 1674# Arguments : 2 1675# 1676is_not_equal() 1677{ 1678 func_check is_not_equal '=' 2 "$@"; 1679 if is_equal "$1" "$2" 1680 then 1681 eval "${return_no}"; 1682 fi 1683 eval "${return_yes}"; 1684} 1685 1686 1687######################################################################## 1688# is_not_file (<filename>) 1689# 1690# Test whether `name' is a not readable file. 1691# 1692# Arguments : 1 (empty allowed) 1693# 1694is_not_file() 1695{ 1696 func_check is_not_file '=' 1 "$@"; 1697 if is_file "$1" 1698 then 1699 eval "${return_no}"; 1700 fi; 1701 eval "${return_yes}"; 1702} 1703 1704 1705######################################################################## 1706# is_not_prog ([<name> [<arg>*]]) 1707# 1708# Verify that arg is a not program in $PATH. 1709# 1710# Arguments : >=0 (empty allowed) 1711# more args are ignored, this allows to specify progs with arguments 1712# 1713is_not_prog() 1714{ 1715 func_check is_not_prog '>=' 0 "$@"; 1716 case "$#" in 1717 0) 1718 eval "${return_yes}"; 1719 ;; 1720 *) 1721 if where_is "$1" >${_NULL_DEV} 1722 then 1723 eval "${return_no}"; 1724 fi; 1725 ;; 1726 esac 1727 eval "${return_yes}"; 1728} 1729 1730 1731######################################################################## 1732# is_not_writable (<name>) 1733# 1734# Test whether `name' is a not a writable file or directory. 1735# 1736# Arguments : >=1 (empty allowed), more args are ignored 1737# 1738is_not_writable() 1739{ 1740 func_check is_not_writable '>=' 1 "$@"; 1741 if is_writable "$1" 1742 then 1743 eval "${return_no}"; 1744 fi; 1745 eval "${return_yes}"; 1746} 1747 1748 1749######################################################################## 1750# is_not_X () 1751# 1752# Test whether not running in X Window by checking $DISPLAY 1753# 1754is_not_X() 1755{ 1756 func_check is_X '=' 0 "$@"; 1757 if obj DISPLAY is_empty 1758 then 1759 eval "${return_yes}"; 1760 fi; 1761 eval "${return_no}"; 1762} 1763 1764 1765######################################################################## 1766# is_not_yes (<string>) 1767# 1768# Test whether `string' is not "yes". 1769# 1770# Arguments : 1 1771# 1772is_not_yes() 1773{ 1774 func_check is_not_yes = 1 "$@"; 1775 if is_yes "$1" 1776 then 1777 eval "${return_no}"; 1778 fi; 1779 eval "${return_yes}"; 1780} 1781 1782 1783######################################################################## 1784# is_prog ([<name> [<arg>*]]) 1785# 1786# Determine whether <name> is a program in $PATH 1787# 1788# Arguments : >=0 (empty allowed) 1789# <arg>* are ignored, this allows to specify progs with arguments. 1790# 1791is_prog() 1792{ 1793 func_check is_prog '>=' 0 "$@"; 1794 case "$#" in 1795 0) 1796 eval "${return_no}"; 1797 ;; 1798 *) 1799 if where_is "$1" >${_NULL_DEV} 1800 then 1801 eval "${return_yes}"; 1802 fi; 1803 ;; 1804 esac 1805 eval "${return_no}"; 1806} 1807 1808 1809######################################################################## 1810# is_writable (<name>) 1811# 1812# Test whether `name' is a writable file or directory. 1813# 1814# Arguments : >=1 (empty allowed), more args are ignored 1815# 1816is_writable() 1817{ 1818 func_check is_writable '>=' 1 "$@"; 1819 if test _"$1"_ = __ 1820 then 1821 eval "${return_no}"; 1822 fi; 1823 if test -r "$1" 1824 then 1825 if test -w "$1" 1826 then 1827 eval "${return_yes}"; 1828 fi; 1829 fi; 1830 eval "${return_no}"; 1831} 1832 1833 1834######################################################################## 1835# is_X () 1836# 1837# Test whether running in X Window by checking $DISPLAY 1838# 1839is_X() 1840{ 1841 func_check is_X '=' 0 "$@"; 1842 if obj DISPLAY is_not_empty 1843 then 1844 eval "${return_yes}"; 1845 fi; 1846 eval "${return_no}"; 1847} 1848 1849 1850######################################################################## 1851# is_yes (<string>) 1852# 1853# Test whether `string' has value "yes". 1854# 1855# Return : `0' if arg1 is `yes', `1' otherwise. 1856# 1857is_yes() 1858{ 1859 func_check is_yes '=' 1 "$@"; 1860 if is_equal "$1" 'yes' 1861 then 1862 eval "${return_yes}"; 1863 fi; 1864 eval "${return_no}"; 1865} 1866 1867 1868######################################################################## 1869# landmark () 1870# 1871# Print debugging information on standard error if $_DEBUG_LM is `yes'. 1872# 1873# Globals: $_DEBUG_LM 1874# 1875# Defined in section `Debugging functions'. 1876 1877 1878######################################################################## 1879# leave ([<code>]) 1880# 1881# Clean exit without an error or with <code>. 1882# 1883leave() 1884{ 1885 clean_up; 1886 if test $# = 0 1887 then 1888 exit "${_OK}"; 1889 else 1890 exit "$1"; 1891 fi; 1892} 1893 1894 1895######################################################################## 1896landmark '6: list_*()'; 1897######################################################################## 1898# 1899# `list' is an object class that represents an array or list. Its 1900# data consists of space-separated single-quoted elements. So a list 1901# has the form "'first' 'second' '...' 'last'". See list_append() for 1902# more details on the list structure. The array elements of `list' 1903# can be get by `eval set x "$list"; shift`. 1904 1905 1906######################################################################## 1907# list_append (<list> <element>...) 1908# 1909# Arguments: >=2 1910# <list>: a variable name for a list of single-quoted elements 1911# <element>: some sequence of characters. 1912# Output: none, but $<list> is set to 1913# if <list> is empty: "'<element>' '...'" 1914# otherwise: "$list '<element>' ..." 1915# 1916# Variable prefix: la 1917# 1918list_append() 1919{ 1920 func_check list_append '>=' 2 "$@"; 1921 la_name="$1"; 1922 eval la_list='"${'$1'}"'; 1923 shift; 1924 for s 1925 do 1926 la_s="$s"; 1927 case "${la_s}" in 1928 *\'*) 1929 # escape each single quote by replacing each 1930 # "'" (squote) by "'\''" (squote bslash squote squote); 1931 # note that the backslash must be doubled in the following `sed' 1932 la_element="$(echo1 "${la_s}" | sed -e 's/'"${_SQ}"'/&\\&&/g')"; 1933 exit_test; 1934 ;; 1935 '') 1936 la_element=""; 1937 ;; 1938 *) 1939 la_element="${la_s}"; 1940 ;; 1941 esac; 1942 if obj la_list is_empty 1943 then 1944 la_list="'${la_element}'"; 1945 else 1946 la_list="${la_list} '${la_element}'"; 1947 fi; 1948 done; 1949 eval "${la_name}"='"${la_list}"'; 1950 eval ${_UNSET} la_element; 1951 eval ${_UNSET} la_list; 1952 eval ${_UNSET} la_name; 1953 eval ${_UNSET} la_s; 1954 eval "${return_ok}"; 1955} 1956 1957 1958######################################################################## 1959# list_from_cmdline (<pre_name_of_opt_lists> [<cmdline_arg>...]) 1960# 1961# Transform command line arguments into a normalized form. 1962# 1963# Options, option arguments, and file parameters are identified and 1964# output each as a single-quoted argument of its own. Options and 1965# file parameters are separated by a '--' argument. 1966# 1967# Arguments: >=1 1968# <pre_name>: common part of a set of 4 environment variable names: 1969# $<pre_name>_SHORT_NA: list of short options without an arg. 1970# $<pre_name>_SHORT_ARG: list of short options that have an arg. 1971# $<pre_name>_LONG_NA: list of long options without an arg. 1972# $<pre_name>_LONG_ARG: list of long options that have an arg. 1973# <cmdline_arg>...: the arguments from a command line, such as "$@", 1974# the content of a variable, or direct arguments. 1975# 1976# Output: ['-[-]opt' ['optarg']]... '--' ['filename']... 1977# 1978# Example: 1979# list_from_cmdline PRE 'a b' 'c' '' 'long' -a f1 -bcarg --long=larg f2 1980# If $PRE_SHORT_NA, $PRE_SHORT_ARG, $PRE_LONG_NA, and $PRE_LONG_ARG are 1981# none-empty option lists, this will result in printing: 1982# '-a' '-b' '-c' 'arg' '--long' 'larg' '--' 'f1' 'f2' 1983# 1984# Use this function in the following way: 1985# eval set x "$(args_norm PRE_NAME "$@")"; 1986# shift; 1987# while test "$1" != '--'; do 1988# case "$1" in 1989# ... 1990# esac; 1991# shift; 1992# done; 1993# shift; #skip '--' 1994# # all positional parameters ("$@") left are file name parameters. 1995# 1996# Variable prefix: lfc 1997# 1998list_from_cmdline() 1999{ 2000 func_check list_from_cmdline '>=' 1 "$@"; 2001 lfc_short_n="$(obj_data "$1"_SHORT_NA)"; # short options, no argument 2002 lfc_short_a="$(obj_data "$1"_SHORT_ARG)"; # short options, with argument 2003 lfc_long_n="$(obj_data "$1"_LONG_NA)"; # long options, no argument 2004 lfc_long_a="$(obj_data "$1"_LONG_ARG)"; # long options, with argument 2005 exit_test; 2006 if obj lfc_short_n is_empty 2007 then 2008 error 'list_from_cmdline(): no $'"$1"'_SHORT_NA options.'; 2009 fi; 2010 if obj lfc_short_a is_empty 2011 then 2012 error 'list_from_cmdline(): no $'"$1"'_SHORT_ARG options.'; 2013 fi; 2014 if obj lfc_long_n is_empty 2015 then 2016 error 'list_from_cmdline(): no $'"$1"'_LONG_NA options.'; 2017 fi; 2018 if obj lfc_long_a is_empty 2019 then 2020 error 'list_from_cmdline(): no $'"$1"'_LONG_ARG options.'; 2021 fi; 2022 2023 shift; 2024 if is_equal "$#" 0 2025 then 2026 echo1 -- 2027 eval ${_UNSET} lfc_fparams; 2028 eval ${_UNSET} lfc_short_a; 2029 eval ${_UNSET} lfc_short_n; 2030 eval ${_UNSET} lfc_long_a; 2031 eval ${_UNSET} lfc_long_n; 2032 eval ${_UNSET} lfc_result; 2033 eval "${return_ok}"; 2034 fi; 2035 2036 lfc_fparams=''; 2037 lfc_result=''; 2038 while test "$#" -ge 1 2039…
Large files files are truncated, but you can click here to view the full file