1 # ============================================================================ 2 # Copyright (c) 2008 Kate Ward 3 # Copyright (c) 2011 University of Pennsylvania 4 # Copyright (c) 2011-2014 Andreas Schuh 7 # Released under the LGPL (GNU Lesser General Public License) 8 # ============================================================================ 10 ############################################################################## 12 # @author Kate Ward <kate.ward at forestent.com>, Andreas Schuh 13 # @brief Advanced command-line flag library for Unix shell scripts. 15 # @sa http://code.google.com/p/shflags/ 17 # @note The shFlags implementation by Kate Ward (revision 147) has been 18 # considerably modified by Andreas Schuh as part of the BASIS project 19 # to fit the needs of the SBIA Group at The University of Pennsylvania. 21 # This module implements something like the google-gflags library available 22 # from http://code.google.com/p/google-gflags/. 24 # FLAG TYPES: This is a list of the DEFINE_*'s that you can do. All flags take 25 # a name, default value, help-string, and optional 'short' name (one-letter 26 # name). Some flags have other arguments, which are described with the flag. 28 # - DEFINE_string: takes any input, and intreprets it as a string. 30 # - DEFINE_boolean: typically does not take any argument: say --myflag to set 31 # FLAGS_myflag to true, or --nomyflag to set FLAGS_myflag to false. 32 # Alternatively, you can say 33 # --myflag=true or --myflag=t or --myflag=0 or 34 # --myflag=false or --myflag=f or --myflag=1 35 # Passing an option has the same affect as passing the option once. 37 # - DEFINE_float: takes an input and intreprets it as a floating point number. As 38 # shell does not support floats per-se, the input is merely validated as 39 # being a valid floating point value. 41 # - DEFINE_integer: takes an input and intreprets it as an integer. 43 # - SPECIAL FLAGS: There are a few flags that have special meaning: 44 # --help (or -?) prints a list of all the flags in a human-readable fashion 45 # --flagfile=foo read flags from foo. (not implemented yet) 46 # -- as in getopt(), terminates flag-processing 50 # Example script hello.sh(.in): 53 # . ${BASIS_SOURCE} || exit 1 55 # DEFINE_string name 'world' "somebody's name" n 57 # FLAGS "$@" || exit $? 58 # eval set -- "${FLAGS_ARGV}" 60 # echo "Hello, ${FLAGS_name}." 63 # Usage of example script hello.sh: 65 # $ ./hello.sh -n Kate 69 # CUSTOMIZABLE BEHAVIOR: 71 # A script can override the default 'getopt' command by providing the path to 72 # an alternate implementation by defining the FLAGS_GETOPT_CMD variable. 77 # flags_error: last error message 78 # flags_return: last return value 80 # __flags_longNames: list of long names for all flags 81 # __flags_shortNames: list of short names for all flags 82 # __flags_boolNames: list of boolean flag names 84 # __flags_opts: options parsed by getopt 86 # Per-flag attributes: 87 # FLAGS_<flag_name>: contains value of flag named 'flag_name' 88 # __flags_<flag_name>_default: the default flag value 89 # __flags_<flag_name>_help: the flag help string 90 # __flags_<flag_name>_short: the flag short name 91 # __flags_<flag_name>_type: the flag type 92 # __flags_<flag_name>_category: category of flag, use special category 93 # 'required' to denote flags that need to be 94 # given on the command line 98 # - Not all systems include a getopt version that supports long flags. On these 99 # systems, only short flags are recognized. 101 # - Lists of strings are space separated, and a null value is the '~' char. 103 # return if FLAGS already loaded 104 [ -n
"${FLAGS_VERSION:-}" ] &&
return 0
106 FLAGS_VERSION=
'1.0.4pre-basis' 108 # ============================================================================ 110 # ============================================================================ 112 # a user can set the path to a different getopt command by overriding this 113 # variable in their script 114 FLAGS_GETOPT_CMD=${FLAGS_GETOPT_CMD:-getopt}
116 # return values that scripts can use 122 _flags_debug() { echo
"flags:DEBUG $@" >&2; }
123 _flags_warn() { echo
"flags:WARN $@" >&2; }
124 _flags_error() { echo
"flags:ERROR $@" >&2; }
125 _flags_fatal() { echo
"flags:FATAL $@" >&2; exit ${FLAGS_ERROR}; }
127 # specific shell checks 128 if [ -n
"${ZSH_VERSION:-}" ]; then
129 setopt |grep
"^shwordsplit$" >/dev/null
130 if [ $? -ne ${FLAGS_TRUE} ]; then
131 _flags_fatal
'zsh shwordsplit option is required for proper zsh operation' 133 if [ -z
"${FLAGS_PARENT:-}" ]; then
134 _flags_fatal
"zsh does not pass \$0 through properly. please declare' \ 135 \"FLAGS_PARENT=\$0\" before calling shFlags" 139 # ---------------------------------------------------------------------------- 141 # ---------------------------------------------------------------------------- 143 # reserved flag names 144 __FLAGS_RESERVED_LIST=
' ARGC ARGV ERROR FALSE GETOPT_CMD HELP PARENT TRUE ' 145 __FLAGS_RESERVED_LIST=
"${__FLAGS_RESERVED_LIST} VERSION " 148 __FLAGS_GETOPT_VERS_STD=0
149 __FLAGS_GETOPT_VERS_ENH=1
150 __FLAGS_GETOPT_VERS_BSD=2
152 ${FLAGS_GETOPT_CMD} >/dev/null 2>&1
154 0) __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_STD} ;; # bsd getopt
156 # TODO(kward): look into
'-T' option to test the
internal getopt() version
157 if [ "`${FLAGS_GETOPT_CMD} --version`
" = '-- ' ]; then 158 __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_STD} 160 __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_ENH} 163 *) _flags_fatal 'unable to determine getopt version' ;; 166 # getopt optstring lengths 167 __FLAGS_OPTSTR_SHORT=0 168 __FLAGS_OPTSTR_LONG=1 173 __FLAGS_INFO_DEFAULT='default' 174 __FLAGS_INFO_HELP='help' 175 __FLAGS_INFO_SHORT='short' 176 __FLAGS_INFO_TYPE='type' 177 __FLAGS_INFO_CATEGORY='category' 185 __FLAGS_TYPE_BOOLEAN=1 187 __FLAGS_TYPE_INTEGER=3 188 __FLAGS_TYPE_STRING=4 190 # flag multi-types, offset MUST be 128 191 __FLAGS_TYPE_MULTI_BOOLEAN=`expr "${__FLAGS_TYPE_BOOLEAN}
" + 128` 192 __FLAGS_TYPE_MULTI_FLOAT=`expr "${__FLAGS_TYPE_FLOAT}
" + 128` 193 __FLAGS_TYPE_MULTI_INTEGER=`expr "${__FLAGS_TYPE_INTEGER}
" + 128` 194 __FLAGS_TYPE_MULTI_STRING=`expr "${__FLAGS_TYPE_STRING}
" + 128` 196 # set the constants readonly 197 __flags_constants=`set |awk -F= '/^FLAGS_/ || /^__FLAGS_/ {print $1}'` 198 for __flags_const in ${__flags_constants}; do 200 case ${__flags_const} in 201 FLAGS_PARENT) continue ;; 204 if [ -z "${ZSH_VERSION:-}
" ]; then 205 readonly ${__flags_const} 207 case ${ZSH_VERSION} in 208 [123].*) readonly ${__flags_const} ;; 209 *) readonly -g ${__flags_const} ;; # declare readonly constants globally 213 unset __flags_const __flags_constants 215 # ---------------------------------------------------------------------------- 217 # ---------------------------------------------------------------------------- 219 # space separated lists 220 __flags_boolNames=' ' # boolean flag names 221 __flags_longNames=' ' # long flag names 222 __flags_shortNames=' ' # short flag names 223 __flags_definedNames=' ' # defined flag names (used for validation) 226 __flags_categoryNames=() # flag category names 229 __flags_columns='' # determined screen width in columns 230 __flags_opts='' # temporary storage for parsed getopt flags 232 # ============================================================================ 234 # ============================================================================ 236 ############################################################################## 239 # Calling this function will define the following info variables for the 241 # FLAGS_flagname - the name for this flag (based upon the long flag name) 242 # __flags_<flag_name>_default - the default value 243 # __flags_<flag_name>_help - the help string 244 # __flags_<flag_name>_short - the single letter alias 245 # __flags_<flag_name>_type - the type of flag (one of __FLAGS_TYPE_*) 246 # __flags_<flag_name>_category - the category of the flag 249 # _flags_type: integer: internal type of flag (__FLAGS_TYPE_*) 250 # _flags_name: string: long flag name 251 # _flags_default: default flag value 252 # _flags_help: string: help string 253 # _flags_short: string: (optional) short flag name 254 # _flags_category: string: (optional) category name this flags belongs to 256 # integer: success of operation, or error 259 if [ $# -lt 4 ]; then 260 flags_error='DEFINE error: too few arguments' 261 flags_return=${FLAGS_ERROR} 262 _flags_error "${flags_error}
" 263 return ${flags_return} 270 _flags_short_="${5:-${__FLAGS_NULL}}
" 271 _flags_category_="${6:-${__FLAGS_NULL}}
" 273 _flags_return_=${FLAGS_TRUE} 274 _flags_usName_=`_flags_underscoreName ${_flags_name_}` 276 # check whether the flag name is reserved 277 _flags_itemInList ${_flags_usName_} "${__FLAGS_RESERVED_LIST}
" 278 if [ $? -eq ${FLAGS_TRUE} ]; then 279 flags_error="flag name (${_flags_name_})
is reserved
" 280 _flags_return_=${FLAGS_ERROR} 283 # require short option for getopt that don't support long options 284 if [ ${_flags_return_} -eq ${FLAGS_TRUE} \ 285 -a ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} \ 286 -a "${_flags_short_}
" = "${__FLAGS_NULL}
" ] 288 flags_error="short flag required
for (${_flags_name_}) on
this platform
" 289 _flags_return_=${FLAGS_ERROR} 292 # check for existing long name definition 293 if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then 294 if _flags_itemInList ${_flags_usName_} ${__flags_definedNames}; then 295 flags_error="definition
for ([no]${_flags_name_}) already
exists" 296 _flags_warn "${flags_error}
" 297 _flags_return_=${FLAGS_FALSE} 301 # check for existing short name definition 302 if [ ${_flags_return_} -eq ${FLAGS_TRUE} \ 303 -a "${_flags_short_}
" != "${__FLAGS_NULL}
" ] 305 if _flags_itemInList "${_flags_short_}
" ${__flags_shortNames}; then 306 flags_error="flag
short name (${_flags_short_}) already defined
" 307 _flags_warn "${flags_error}
" 308 _flags_return_=${FLAGS_FALSE} 312 # convert array given as string such as "'a 1' 'b 2' 'c' 'd 4'" to array 313 # ('a 1' 'b 2' 'c' 'd 4') and get type of values for multi-flags 314 if [ ${_flags_type_} -gt 128 -a ${_flags_type_} -ne ${__FLAGS_TYPE_MULTI_BOOLEAN} ]; then 315 _flags_valueType_=`expr "${_flags_type_}
" - 128` 316 eval "_flags_default_=(${_flags_default_})
" 318 if [ ${#_flags_default_[@]} -ne 1 ]; then 319 flags_error="${_flags_name_}: invalid
default flag value
'${_flags_default_}'" 320 _flags_return_=${FLAGS_ERROR} 322 _flags_valueType_=${_flags_type_} 325 # handle default value. note, on several occasions the 'if' portion of an 326 # if/then/else contains just a ':' which does nothing. a binary reversal via 327 # '!' is not done because it does not work on all shells. 328 if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then 329 case ${_flags_type_} in 330 ${__FLAGS_TYPE_BOOLEAN}) 331 if _flags_validateBoolean "${_flags_default_}
"; then 332 case ${_flags_default_} in 333 true|t|0) _flags_default_=${FLAGS_TRUE} ;; 334 false|f|1) _flags_default_=${FLAGS_FALSE} ;; 337 flags_error="${_flags_name_}: invalid
default flag value
'${_flags_default_}'" 338 _flags_return_=${FLAGS_ERROR} 342 ${__FLAGS_TYPE_MULTI_BOOLEAN}) 343 if _flags_validateInteger "${_flags_default_}
"; then 346 flags_error="${_flags_name_}: invalid
default flag value
'${_flags_default_}'" 347 _flags_return_=${FLAGS_ERROR} 352 for _flags_defaultValue_ in "${_flags_default_[@]}
"; do 353 case ${_flags_valueType_} in 354 ${__FLAGS_TYPE_FLOAT}) 355 if _flags_validateFloat "${_flags_defaultValue_}
"; then 358 flags_error="${_flags_name_}: invalid
default flag value
'${_flags_defaultValue_}'" 359 _flags_return_=${FLAGS_ERROR} 363 ${__FLAGS_TYPE_INTEGER}) 364 if _flags_validateInteger "${_flags_defaultValue_}
"; then 367 flags_error="${_flags_name_}: invalid
default flag value
'${_flags_defaultValue_}'" 368 _flags_return_=${FLAGS_ERROR} 372 ${__FLAGS_TYPE_STRING}) ;; # everything in shell is a valid string 375 flags_error="${_flags_name_}: unrecognized flag type
'${_flags_type_}'" 376 _flags_return_=${FLAGS_ERROR} 384 if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then 385 # store flag information 386 if [ ${_flags_type_} -gt 128 ]; then 387 eval "FLAGS_${_flags_usName_}=(\
"\${_flags_default_[@]}\")" 388 eval
"__flags_${_flags_usName_}_${__FLAGS_INFO_DEFAULT}=(\"\${_flags_default_[@]}\")" 390 eval
"FLAGS_${_flags_usName_}='${_flags_default_}'" 391 eval
"__flags_${_flags_usName_}_${__FLAGS_INFO_DEFAULT}='${_flags_default_}'" 393 eval
"__flags_${_flags_usName_}_${__FLAGS_INFO_TYPE}=${_flags_type_}" 394 eval
"__flags_${_flags_usName_}_${__FLAGS_INFO_HELP}=\"${_flags_help_}\"" 395 eval
"__flags_${_flags_usName_}_${__FLAGS_INFO_SHORT}='${_flags_short_}'" 396 eval
"__flags_${_flags_usName_}_${__FLAGS_INFO_CATEGORY}='${_flags_category_}'" 398 # append flag names to name lists 399 __flags_shortNames=
"${__flags_shortNames}${_flags_short_} " 400 __flags_longNames=
"${__flags_longNames}${_flags_name_} " 401 [ ${_flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} -o \
402 ${_flags_type_} -eq ${__FLAGS_TYPE_MULTI_BOOLEAN} ] && \
403 __flags_boolNames=
"${__flags_boolNames}no${_flags_name_} " 405 # append flag names to defined names for later validation checks 406 __flags_definedNames=
"${__flags_definedNames}${_flags_usName_} " 407 [ ${_flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} ] && \
408 __flags_definedNames=
"${__flags_definedNames}no${_flags_usName_} " 410 # append category name to category names list 411 if [
"${_flags_category_}" !=
"${__FLAGS_NULL}" ]; then
412 _flags_found_=${FLAGS_FALSE}
413 for _flags_categoryName_ in
"${__flags_categoryNames[@]}";
do 414 if [
"${_flags_categoryName_}" =
"${_flags_category_}" ]; then
415 _flags_found_=${FLAGS_TRUE}
419 if [ ${_flags_found_} -eq ${FLAGS_FALSE} ]; then
420 __flags_categoryNames[${#__flags_categoryNames[@]}]=
"${_flags_category_}" 425 flags_return=${_flags_return_}
426 unset _flags_default_ _flags_help_ _flags_name_ _flags_return_ \
427 _flags_short_ _flags_type_ _flags_usName_ \
428 _flags_category_ _flags_found_
429 [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_error
"${flags_error}" 430 return ${flags_return}
433 ############################################################################## 434 # Return valid getopt options using currently defined list of long options. 436 # This function builds a proper getopt option string for short (and long) 437 # options, using the current list of long options for reference. 440 # _flags_optStr: integer: option string type (__FLAGS_OPTSTR_*) 442 # string: generated option string for getopt 444 # boolean: success of operation (always returns True) 447 _flags_optStrType_=$1
451 for _flags_name_ in ${__flags_longNames};
do 452 _flags_usName_=`_flags_underscoreName ${_flags_name_}`
453 _flags_type_=`_flags_getFlagInfo ${_flags_usName_} ${__FLAGS_INFO_TYPE}`
454 [ $? -eq ${FLAGS_TRUE} ] || _flags_fatal
'call to _flags_type_ failed' 455 case ${_flags_optStrType_} in
456 ${__FLAGS_OPTSTR_SHORT})
457 _flags_shortName_=`_flags_getFlagInfo \
458 ${_flags_usName_} ${__FLAGS_INFO_SHORT}`
459 if [
"${_flags_shortName_}" !=
"${__FLAGS_NULL}" ]; then
460 _flags_opts_=
"${_flags_opts_}${_flags_shortName_}" 461 # getopt needs a trailing ':' to indicate a required argument 462 [ ${_flags_type_} -ne ${__FLAGS_TYPE_BOOLEAN} -a \
463 ${_flags_type_} -ne ${__FLAGS_TYPE_MULTI_BOOLEAN} ] && \
464 _flags_opts_=
"${_flags_opts_}:" 468 ${__FLAGS_OPTSTR_LONG})
469 _flags_opts_=
"${_flags_opts_:+${_flags_opts_},}${_flags_name_}" 470 # getopt needs a trailing
':' to indicate a required argument
471 [ ${_flags_type_} -ne ${__FLAGS_TYPE_BOOLEAN} -a \
472 ${_flags_type_} -ne ${__FLAGS_TYPE_MULTI_BOOLEAN} ] && \
473 _flags_opts_=
"${_flags_opts_}:" 478 echo
"${_flags_opts_}" 479 unset _flags_name_ _flags_opts_ _flags_optStrType_ _flags_shortName_ \
480 _flags_type_ _flags_usName_
484 ############################################################################## 485 # Returns flag details based on a flag name and flag info. 488 # string: underscored flag name 489 # string: flag info (see the _flags_define function for valid info types) 491 # string: value of dereferenced flag variable 493 # integer: one of FLAGS_{TRUE|FALSE|ERROR} 496 # note: adding gFI to variable names to prevent naming conflicts with calling 498 _flags_gFI_usName_=$1
501 _flags_infoVar_=
"__flags_${_flags_gFI_usName_}_${_flags_gFI_info_}" 502 _flags_strToEval_=
"_flags_infoValue_=\"\${${_flags_infoVar_}:-}\"" 503 eval
"${_flags_strToEval_}" 504 if [ -n
"${_flags_infoValue_}" ]; then
505 flags_return=${FLAGS_TRUE}
507 # see if the _flags_gFI_usName_ variable is a string as strings can be 509 # note: the DRY principle would say to have this function call itself for 510 # the next three lines, but doing so results in an infinite loop as an 511 # invalid _flags_name_ will also not have the associated _type variable. 512 # Because it doesn't (it will evaluate to an empty string) the logic will 513 # try to find the _type variable of the _type variable, and so on. Not so 515 _flags_typeVar_=
"__flags_${_flags_gFI_usName_}_${__FLAGS_INFO_TYPE}" 516 _flags_strToEval_=
"_flags_typeValue_=\"\${${_flags_typeVar_}:-}\"" 517 eval
"${_flags_strToEval_}" 518 if [
"${_flags_typeValue_}" =
"${__FLAGS_TYPE_STRING}" -o
"${_flags_typeValue_}" -gt 128 ]; then
519 flags_return=${FLAGS_TRUE}
521 flags_return=${FLAGS_ERROR}
522 flags_error=
"missing flag info variable (${_flags_infoVar_})" 526 echo
"${_flags_infoValue_}" 527 unset _flags_gFI_usName_ _flags_gfI_info_ _flags_infoValue_ _flags_infoVar_ \
528 _flags_strToEval_ _flags_typeValue_ _flags_typeVar_
529 [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_error
"${flags_error}" 530 return ${flags_return}
533 ############################################################################## 534 # Returns flag value based on a flag name. 537 # unnamed: string: underscored flag name 538 # unnamed: string: name of the output variable 540 # sets the variable named by the second argument to the current value, 541 # which is an array in case of a multi-flag. 543 # integer: one of FLAGS_{TRUE|FALSE|ERROR} 544 _flags_getFlagValue()
546 _flags_gFV_usName_=$1
547 _flags_gFV_type_=`_flags_getFlagInfo ${_flags_gFV_usName_} ${__FLAGS_INFO_TYPE}`
549 if [ ${_flags_gFV_type_} -gt 128 ]; then
550 eval
"$2=(\"\${FLAGS_${_flags_gFV_usName_}[@]}\")" 552 eval
"$2=\"\${FLAGS_${_flags_gFV_usName_}:-}\"" 555 unset _flags_gFV_usName_ _flags_gFV_type_
560 ############################################################################## 561 # Returns flag default value based on a flag name. 564 # unnamed: string: underscored flag name 565 # unnamed: string: name of the output variable 567 # sets the variable named by the second argument to the default value, 568 # which is an array in case of a multi-flag. 570 # integer: one of FLAGS_{TRUE|FALSE|ERROR} 571 _flags_getFlagDefault()
573 _flags_gFD_usName_=$1
574 _flags_gFD_type_=`_flags_getFlagInfo ${_flags_gFD_usName_} ${__FLAGS_INFO_TYPE}`
576 if [ ${_flags_gFD_type_} -gt 128 ]; then
577 eval
"$2=(\"\${__flags_${_flags_gFD_usName_}_${__FLAGS_INFO_DEFAULT}[@]}\")" 579 eval
"$2=\"\${__flags_${_flags_gFD_usName_}_${__FLAGS_INFO_DEFAULT}:-}\"" 582 unset _flags_gFD_usName_ _flags_gFD_type_
587 # ---------------------------------------------------------------------------- 589 # ---------------------------------------------------------------------------- 591 ############################################################################## 592 # Underscore a flag or category name by replacing dashes and whitespaces with underscores. 595 # unnamed: string: long flag or category name 597 # string: underscored name 598 _flags_underscoreName()
600 echo $1 | sed
's/[ -]/_/g' 603 ############################################################################## 604 # Returns the width of the current screen. 607 # integer: width in columns of the current screen. 610 if [ -z
"${__flags_columns}" ]; then
611 # determine the value and store it 612 if eval stty size >/dev/null 2>&1; then
613 # stty size worked :-) 616 elif eval tput cols >/dev/null 2>&1; then
620 __flags_columns=80 #
default terminal width
623 echo ${__flags_columns}
626 ############################################################################## 627 # Check for presense of item in a list. 629 # Passed a string (e.g. 'abc'), this function will determine if the string is 630 # present in the list of strings (e.g. ' foo bar abc '). 633 # _flags_str_: string: string to search for in a list of strings 634 # unnamed: list: list of strings 636 # boolean: true if item is in the list 642 echo
" ${*:-} " |grep
" ${_flags_str_} " >/dev/null
643 if [ $? -eq 0 ]; then
644 flags_return=${FLAGS_TRUE}
646 flags_return=${FLAGS_FALSE}
650 return ${flags_return}
653 ############################################################################## 654 # Sort space separated list. 657 # @: list: space separated list of strings 659 # list: sorted space separated list of strings 662 echo
"$@" | tr
' ' '\n' | sort | tr
'\n' ' ' 665 # ---------------------------------------------------------------------------- 667 # ---------------------------------------------------------------------------- 669 ############################################################################## 670 # Validate a boolean. 673 # _flags__bool: boolean: value to validate 675 # bool: true if the value is a valid boolean 676 _flags_validateBoolean()
680 flags_return=${FLAGS_TRUE}
681 case "${_flags_bool_}" in
684 *) flags_return=${FLAGS_FALSE} ;;
688 return ${flags_return}
691 ############################################################################## 695 # _flags__float: float: value to validate 697 # bool: true if the value is a valid float 698 _flags_validateFloat()
702 if _flags_validateInteger ${_flags_float_}; then
703 flags_return=${FLAGS_TRUE}
705 flags_return=${FLAGS_TRUE}
706 case ${_flags_float_} in
707 -*) # negative floats
708 _flags_test_=`expr --
"${_flags_float_}" :\
709 '\(-[0-9][0-9]*\.[0-9][0-9]*\)'`
712 _flags_test_=`expr --
"${_flags_float_}" :\
713 '\([0-9][0-9]*\.[0-9][0-9]*\)'`
716 [
"${_flags_test_}" !=
"${_flags_float_}" ] && flags_return=${FLAGS_FALSE}
719 unset _flags_float_ _flags_test_
720 return ${flags_return}
723 ############################################################################## 724 # Validate an integer. 727 # _flags__int_: interger: value to validate 729 # bool: true if the value is a valid integer 730 _flags_validateInteger()
734 flags_return=${FLAGS_TRUE}
735 case ${_flags_int_} in
737 _flags_test_=`expr --
"${_flags_int_}" :
'\(-[0-9][0-9]*\)'`
740 _flags_test_=`expr --
"${_flags_int_}" :
'\([0-9][0-9]*\)'`
743 [
"${_flags_test_}" !=
"${_flags_int_}" ] && flags_return=${FLAGS_FALSE}
745 unset _flags_int_ _flags_test_
746 return ${flags_return}
749 ############################################################################## 750 # Validate an unsigned integer. 753 # _flags__uint_: interger: value to validate 755 # bool: true if the value is a valid unsigned integer 756 _flags_validateUnsignedInteger()
760 flags_return=${FLAGS_TRUE}
761 _flags_test_=`expr --
"${_flags_uint_}" :
'\([0-9][0-9]*\)'`
762 [
"${_flags_test_}" !=
"${_flags_uint_}" ] && flags_return=${FLAGS_FALSE}
764 unset _flags_uint_ _flags_test_
765 return ${flags_return}
768 # ---------------------------------------------------------------------------- 769 # helpers for command-line parsing 770 # ---------------------------------------------------------------------------- 772 ############################################################################## 773 # Parse command-line options using the standard getopt. 775 # Note: the flag options are passed around in the global __flags_opts so that 776 # the formatting is not lost due to shell parsing and such. 779 # @: varies: command-line options to parse 781 # integer: a FLAGS success condition 782 _flags_getoptStandard()
784 flags_return=${FLAGS_TRUE}
785 _flags_shortOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}`
787 # check for spaces in passed options 788 for _flags_opt_ in
"$@";
do 789 # note: the silliness with the x's is purely for ksh93 on Ubuntu 6.06 790 _flags_match_=`echo
"x${_flags_opt_}x" |sed
's/ //g'`
791 if [
"${_flags_match_}" !=
"x${_flags_opt_}x" ]; then
792 flags_error=
'the available getopt does not support spaces in options' 793 flags_return=${FLAGS_ERROR}
798 if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then
799 __flags_opts=`getopt ${_flags_shortOpts_} $@ 2>&1`
801 if [ ${_flags_rtrn_} -ne ${FLAGS_TRUE} ]; then
802 _flags_warn
"${__flags_opts}" 803 flags_error=
'unable to parse provided options with getopt.' 804 flags_return=${FLAGS_ERROR}
808 unset _flags_match_ _flags_opt_ _flags_rtrn_ _flags_shortOpts_
809 return ${flags_return}
812 ############################################################################## 813 # Parse command-line options using the enhanced getopt. 815 # Note: the flag options are passed around in the global __flags_opts so that 816 # the formatting is not lost due to shell parsing and such. 819 # @: varies: command-line options to parse 821 # integer: a FLAGS success condition 822 _flags_getoptEnhanced()
824 flags_return=${FLAGS_TRUE}
825 _flags_shortOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}`
826 _flags_boolOpts_=`echo
"${__flags_boolNames}" \
827 |sed
's/^ *//;s/ *$//;s/ /,/g'`
828 _flags_longOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_LONG}`
830 __flags_opts=`${FLAGS_GETOPT_CMD} \
831 -o ${_flags_shortOpts_} \
832 -l
"${_flags_longOpts_},${_flags_boolOpts_}" \
835 if [ ${_flags_rtrn_} -ne ${FLAGS_TRUE} ]; then
836 _flags_warn
"${__flags_opts}" 837 flags_error=
'unable to parse provided options with getopt.' 838 flags_return=${FLAGS_ERROR}
841 unset _flags_boolOpts_ _flags_longOpts_ _flags_rtrn_ _flags_shortOpts_
842 return ${flags_return}
845 ############################################################################## 846 # Dynamically parse a getopt result and set appropriate variables. 848 # This function does the actual conversion of getopt output and runs it through 849 # the standard case structure for parsing. The case structure is actually quite 850 # dynamic to support any number of flags. 853 # argc: int: original command-line argument count 854 # @: varies: output from getopt parsing 856 # integer: a FLAGS success condition 862 flags_return=${FLAGS_TRUE}
864 if [ ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} ]; then
867 # note the quotes around the `$@' -- they are essential! 871 # provide user with number of arguments to shift by later 872 # NOTE: the FLAGS_ARGC variable is obsolete as of 1.0.3 because it does not 873 # properly give user access to non-flag arguments mixed in between flag 874 # arguments. Its usage was replaced by FLAGS_ARGV, and it is being kept only 875 # for backwards compatibility reasons. 876 FLAGS_ARGC=`expr $# - 1 - ${_flags_argc_}`
878 # handle options. note options with values must do an additional shift 884 # determine long flag name 885 case "${_flags_opt_}" in
886 --) shift; break ;; # discontinue option parsing
889 _flags_opt_=`expr --
"${_flags_opt_}" :
'--\(.*\)'`
890 _flags_len_=${__FLAGS_LEN_LONG}
891 if _flags_itemInList
"${_flags_opt_}" ${__flags_longNames}; then
892 _flags_name_=${_flags_opt_}
894 # check for negated long boolean version 895 if _flags_itemInList
"${_flags_opt_}" ${__flags_boolNames}; then
896 _flags_name_=`expr --
"${_flags_opt_}" :
'no\(.*\)'`
897 _flags_arg_=${__FLAGS_NULL}
903 _flags_opt_=`expr --
"${_flags_opt_}" :
'-\(.*\)'`
904 _flags_len_=${__FLAGS_LEN_SHORT}
905 if _flags_itemInList
"${_flags_opt_}" ${__flags_shortNames}; then
906 # yes. match short name to long name. note purposeful off-by-one 907 # (too high) with awk calculations. 908 _flags_pos_=`echo
"${__flags_shortNames}" \
909 |awk
'BEGIN{RS=" ";rn=0}$0==e{rn=NR}END{print rn}' \
911 _flags_name_=`echo
"${__flags_longNames}" \
912 |awk
'BEGIN{RS=" "}rn==NR{print $0}' rn=
"${_flags_pos_}"`
917 # die if the flag was unrecognized 918 if [ -z
"${_flags_name_}" ]; then
919 flags_error=
"unrecognized option (${_flags_opt_})" 920 flags_return=${FLAGS_ERROR}
925 _flags_usName_=`_flags_underscoreName ${_flags_name_}`
926 _flags_type_=`_flags_getFlagInfo
"${_flags_usName_}" ${__FLAGS_INFO_TYPE}`
928 case ${_flags_type_} in
929 ${__FLAGS_TYPE_MULTI_BOOLEAN})
930 eval
"_flags_val_=\${FLAGS_${_flags_usName_}}" 931 if [ ${_flags_len_} -eq ${__FLAGS_LEN_SHORT} -o \
932 "${_flags_arg_}" !=
"${__FLAGS_NULL}" ]; then
933 _flags_val_=`expr
"${_flags_val_}" + 1`
935 _flags_val_=`expr
"${_flags_val_}" - 1`
937 eval
"FLAGS_${_flags_usName_}=${_flags_val_}" 941 if [ ${_flags_type_} -ge 128 ]; then
942 eval
"_flags_idx_=\${#FLAGS_${_flags_usName_}[@]}" 943 _flags_type_=`expr
"${_flags_type_}" - 128`
947 case ${_flags_type_} in
948 ${__FLAGS_TYPE_BOOLEAN})
949 if [ ${_flags_len_} -eq ${__FLAGS_LEN_LONG} ]; then
950 if [
"${_flags_arg_}" !=
"${__FLAGS_NULL}" ]; then
951 eval
"FLAGS_${_flags_usName_}[${_flags_idx_}]=${FLAGS_TRUE}" 953 eval
"FLAGS_${_flags_usName_}[${_flags_idx_}]=${FLAGS_FALSE}" 956 _flags_strToEval_=
"_flags_val_=\${__flags_${_flags_usName_}_${__FLAGS_INFO_DEFAULT}}" 957 eval
"${_flags_strToEval_}" 958 if [ ${_flags_val_} -eq ${FLAGS_FALSE} ]; then
959 eval
"FLAGS_${_flags_usName_}[${_flags_idx_}]=${FLAGS_TRUE}" 961 eval
"FLAGS_${_flags_usName_}[${_flags_idx_}]=${FLAGS_FALSE}" 966 ${__FLAGS_TYPE_FLOAT})
967 if _flags_validateFloat
"${_flags_arg_}"; then
968 eval
"FLAGS_${_flags_usName_}[${_flags_idx_}]='${_flags_arg_}'" 970 flags_error=
"${_flags_name_}: invalid float value (${_flags_arg_})" 971 flags_return=${FLAGS_ERROR}
976 ${__FLAGS_TYPE_INTEGER})
977 if _flags_validateInteger
"${_flags_arg_}"; then
978 eval
"FLAGS_${_flags_usName_}[${_flags_idx_}]='${_flags_arg_}'" 980 flags_error=
"${_flags_name_}: invalid integer value (${_flags_arg_})" 981 flags_return=${FLAGS_ERROR}
986 ${__FLAGS_TYPE_STRING})
987 eval
"FLAGS_${_flags_usName_}[${_flags_idx_}]='${_flags_arg_}'" 993 # handle special case help flag 994 if [
"${_flags_usName_}" =
'help' ]; then
995 if [ ${FLAGS_help} -eq ${FLAGS_TRUE} ]; then
997 flags_error=
'help requested' 998 flags_return=${FLAGS_TRUE}
1003 # handle special case helpman flag 1004 if [
"${_flags_usName_}" =
'helpman' ]; then
1005 if [ ${FLAGS_helpman} -eq ${FLAGS_TRUE} ]; then
1006 flags_error=
'help requested' 1007 flags_return=${FLAGS_TRUE}
1008 # if man should not be executed dirtly, 1009 # print generated man page to STDOUT instead 1010 if [ -n
"${FLAGS_execman}" ] && [ ${FLAGS_execman} -eq ${FLAGS_FALSE} ]; then
1014 # save generated man page to temporary file 1015 flags_manFile_=
"`mktemp -t \"${0##*/}.1\"`" 1016 if [ $? -ne 0 ]; then
1017 flags_error=
'failed to create temporary man page file name' 1018 flags_return=${FLAGS_ERROR}
1021 flags_man_=
"`flags_helpman`" 1022 if [ $? -ne ${FLAGS_TRUE} ]; then
1023 flags_error=
'failed to generate temporary man page file' 1024 flags_return=${FLAGS_ERROR}
1027 echo
"${flags_man_}" >
"${flags_manFile_}" 1028 if [ $? -ne ${FLAGS_TRUE} ]; then
1029 flags_error=
'failed to write temporary man page file' 1030 flags_return=${FLAGS_ERROR}
1033 # execute man to view the man page 1034 man
"${flags_manFile_}" 1035 if [ $? -ne ${FLAGS_TRUE} ]; then
1036 flags_error=
'failed to execute man to view generated man page' 1037 flags_return=${FLAGS_ERROR}
1039 # remove temporary man page file 1040 rm -f
"${flags_manFile_}" 1041 if [ ${flags_return} -ne ${FLAGS_ERROR} -a $? -ne ${FLAGS_TRUE} ]; then
1042 flags_error=
'failed to execute man to view generated man page' 1043 flags_return=${FLAGS_ERROR}
1049 # handle special case helpxml flag 1050 if [
"${_flags_usName_}" =
'helpxml' ]; then
1051 if [ ${FLAGS_helpxml} -eq ${FLAGS_TRUE} ]; then
1053 flags_error=
'help requested' 1054 flags_return=${FLAGS_TRUE}
1059 # handle special case usage flag 1060 if [
"${_flags_usName_}" =
'helpshort' ]; then
1061 if [ ${FLAGS_helpshort} -eq ${FLAGS_TRUE} ]; then
1063 flags_error=
'help requested' 1064 flags_return=${FLAGS_TRUE}
1069 # handle special case version flag 1070 if [
"${_flags_usName_}" =
'version' ]; then
1071 if [ ${FLAGS_version} -eq ${FLAGS_TRUE} ]; then
1073 flags_error=
'version requested' 1074 flags_return=${FLAGS_TRUE}
1079 # shift the option and non-boolean arguments out. 1081 [ ${_flags_type_} != ${__FLAGS_TYPE_BOOLEAN} -a \
1082 ${_flags_type_} != ${__FLAGS_TYPE_MULTI_BOOLEAN} ] && shift
1085 # give user back non-flag arguments 1087 while [ $# -gt 0 ];
do 1088 FLAGS_ARGV=
"${FLAGS_ARGV:+${FLAGS_ARGV} }'$1'" 1092 unset _flags_arg_ _flags_len_ _flags_name_ _flags_opt_ _flags_pos_ \
1093 _flags_strToEval_ _flags_type_ _flags_usName_ _flags_val_
1094 return ${flags_return}
1097 # ---------------------------------------------------------------------------- 1098 # helpers for help output 1099 # ---------------------------------------------------------------------------- 1101 ############################################################################## 1102 # Convert type ID to type string. 1105 # _flags_type_: integer: type ID 1107 # string: type string 1112 # type ID's of multi-flags have an offset of 128 (8th bit set) 1113 if [ ${_flags_tS_type_} -gt 128 ]; then
1114 _flags_tS_type_=`expr
"${_flags_type__}" - 128`
1118 # type string of value type 1119 case "${_flags_tS_type_}" in
1120 ${__FLAGS_TYPE_BOOLEAN}) echo -n
'bool'; ;;
1121 ${__FLAGS_TYPE_FLOAT}) echo -n
'float'; ;;
1122 ${__FLAGS_TYPE_INTEGER}) echo -n
'int'; ;;
1123 ${__FLAGS_TYPE_STRING}) echo -n
'string'; ;;
1124 *) echo -n
'unknown'; ;;
1127 unset _flags_tS_type_
1130 ############################################################################## 1131 # Convert current value to string for help output. 1137 _flags_usName__=`_flags_underscoreName ${_flags_name__}`
1138 _flags_type__=`_flags_getFlagInfo
"${_flags_usName__}" ${__FLAGS_INFO_TYPE}`
1139 _flags_getFlagValue
"${_flags_usName__}" '_flags_current__' 1141 _flags_multi__=${FLAGS_FALSE}
1142 if [ ${_flags_type__} -eq ${__FLAGS_TYPE_MULTI_BOOLEAN} ]; then
1143 _flags_valueType__=${__FLAGS_TYPE_INTEGER}
1144 elif [ ${_flags_type__} -gt 128 ]; then
1145 _flags_valueType__=`expr
"${_flags_type__}" - 128`
1146 _flags_multi__=${FLAGS_TRUE}
1149 _flags_valueType__=${_flags_type__}
1152 _flags_separator__=
'' #
set at end of first iteration
1153 for _flags_value__ in
"${_flags_current__[@]}";
do 1154 echo -n
"${_flags_separator__}" 1155 case ${_flags_valueType__} in
1156 ${__FLAGS_TYPE_BOOLEAN})
1157 if [ ${_flags_value__} -eq ${FLAGS_TRUE} ]; then
1164 ${__FLAGS_TYPE_STRING})
1165 echo -n
"'${_flags_value__}'" 1169 echo -n ${_flags_value__}
1172 _flags_separator__=
' ' 1175 if [ ${_flags_multi__} -eq ${FLAGS_TRUE} ]; then
1179 unset _flags_name__ _flags_usName__ _flags_current__ _flags_type__ \
1180 _flags_valueType__ _flags_value__ _flags_multi__ _flags_separator__
1183 ############################################################################## 1184 # Convert default value to string for help output. 1190 _flags_dS_usName_=`_flags_underscoreName ${_flags_dS_name_}`
1191 _flags_dS_type_=`_flags_getFlagInfo
"${_flags_dS_usName_}" ${__FLAGS_INFO_TYPE}`
1192 _flags_getFlagDefault
"${_flags_dS_usName_}" '_flags_dS_default_' 1194 _flags_dS_multi_=${FLAGS_FALSE}
1195 if [ ${_flags_dS_type_} -eq ${__FLAGS_TYPE_MULTI_BOOLEAN} ]; then
1196 _flags_dS_valueType_=${__FLAGS_TYPE_INTEGER}
1197 elif [ ${_flags_dS_type_} -gt 128 ]; then
1198 _flags_dS_valueType_=`expr
"${_flags_dS_type_}" - 128`
1199 _flags_dS_multi_=${FLAGS_TRUE}
1202 _flags_dS_valueType_=${_flags_dS_type_}
1205 _flags_dS_separator_=
'' #
set at end of first iteration
1206 for _flags_dS_value_ in
"${_flags_dS_default_[@]}";
do 1207 echo -n
"${_flags_dS_separator_}" 1208 case ${_flags_dS_valueType_} in
1209 ${__FLAGS_TYPE_BOOLEAN})
1210 if [ ${_flags_dS_value_} -eq ${FLAGS_TRUE} ]; then
1217 ${__FLAGS_TYPE_STRING})
1218 echo -n
"'${_flags_dS_value_}'" 1222 echo -n ${_flags_dS_value_}
1225 _flags_dS_separator_=
' ' 1228 if [ ${_flags_dS_multi_} -eq ${FLAGS_TRUE} ]; then
1232 unset _flags_dS_name_ _flags_dS_usName_ _flags_dS_default_ _flags_dS_type_ \
1233 _flags_dS_valueType_ _flags_dS_value_ _flags_dS_multi_ _flags_dS_separator_
1236 ############################################################################## 1237 # Escape string for use in XML output. 1240 # unnamed: string: some string 1242 # string: xml-escaped string 1245 echo -
e "$1" | sed
's/\&/\&/g;s/</\</g' 1248 ############################################################################## 1249 # Escape string for use in man page output. 1252 # unnamed: string: some string 1254 # string: man page-escaped string 1257 echo -
e "$1" | sed
's/\\/\\\\/g;s/-/\\-/g' 1260 ############################################################################## 1261 # Output short usage of named flag. 1264 # _flags_name_: string: long flag name 1266 # string: usage of flag, e.g., "--someflag=<int>" 1272 _flags_usName_=`_flags_underscoreName ${_flags_name_}`
1273 _flags_type_=`_flags_getFlagInfo
"${_flags_usName_}" ${__FLAGS_INFO_TYPE}`
1275 # type ID's of multi-flags have an offset of 128 (8th bit set) 1276 if [ ${_flags_type_} -ge 128 ]; then
1277 _flags_multi_=${FLAGS_TRUE}
1278 _flags_type_=`expr
"${_flags_type_}" - 128`
1280 _flags_multi_=${FLAGS_FALSE}
1284 case ${_flags_type_} in
1285 ${__FLAGS_TYPE_BOOLEAN})
1286 echo -n
"--[no]${_flags_name_}" 1290 echo -n
"--${_flags_name_}=<`_flags_typeStr ${_flags_type_}`>" 1294 # append '...' if it's a multi-flag 1295 if [ ${_flags_multi_} -eq ${FLAGS_TRUE} ]; then
1299 unset _flags_name_ _flags_usName_ _flags_type_ _flags_multi_
1302 ############################################################################## 1303 # Output short usage of named flag in man page format. 1306 # _flags_name_: string: long flag name 1308 # string: usage of flag, e.g., "--someflag=<int>" 1309 _flags_helpman_flagusage()
1314 _flags_usName_=`_flags_underscoreName ${_flags_name_}`
1315 _flags_type_=`_flags_getFlagInfo
"${_flags_usName_}" ${__FLAGS_INFO_TYPE}`
1317 # type ID's of multi-flags have an offset of 128 (8th bit set) 1318 if [ ${_flags_type_} -ge 128 ]; then
1319 _flags_multi_=${FLAGS_TRUE}
1320 _flags_type_=`expr
"${_flags_type_}" - 128`
1322 _flags_multi_=${FLAGS_FALSE}
1326 case ${_flags_type_} in
1327 ${__FLAGS_TYPE_BOOLEAN})
1328 echo -n
"\fB--[no]${_flags_name_}\fR" 1332 echo -n
"\fB--${_flags_name_}\fR=<\fI`_flags_typeStr ${_flags_type_}`\fR>" 1336 # append '...' if it's a multi-flag 1337 if [ ${_flags_multi_} -eq ${FLAGS_TRUE} ]; then
1341 unset _flags_name_ _flags_usName_ _flags_type_ _flags_multi_
1344 # ============================================================================ 1346 # ============================================================================ 1348 # ---------------------------------------------------------------------------- 1350 # ---------------------------------------------------------------------------- 1352 # A basic boolean flag. Boolean flags do not take any arguments, and their 1353 # value is either 1 (false) or 0 (true). For long flags, the false value is 1354 # specified on the command line by prepending the word 'no'. With short flags, 1355 # the presense of the flag toggles the current value between true and false. 1356 # Specifying a short boolean flag twice on the command results in returning the 1357 # value back to the default value. 1359 # A default value is required for boolean flags. 1361 # For example, lets say a Boolean flag was created whose long name was 'update' 1362 # and whose short name was 'x', and the default value was 'false'. This flag 1363 # could be explicitly set to 'true' with '--update' or by '-x', and it could be 1364 # explicitly set to 'false' with '--noupdate'. 1365 DEFINE_boolean() { _flags_define ${__FLAGS_TYPE_BOOLEAN}
"$@"; }
1366 DEFINE_bool() { _flags_define ${__FLAGS_TYPE_BOOLEAN}
"$@"; }
1368 # Other basic flags. 1369 DEFINE_float() { _flags_define ${__FLAGS_TYPE_FLOAT}
"$@"; }
1370 DEFINE_integer() { _flags_define ${__FLAGS_TYPE_INTEGER}
"$@"; }
1371 DEFINE_int() { _flags_define ${__FLAGS_TYPE_INTEGER}
"$@"; }
1372 DEFINE_string() { _flags_define ${__FLAGS_TYPE_STRING}
"$@"; }
1374 # A multi boolean flag. Such flag can be given multiple times and instead of 1375 # representing a list of boolean values, this flag's value is a counter which 1376 # is incremented for every boolean flag value that is 'true' and decremented 1377 # otherwise. Note that the value of the counter may hence also be negative. 1379 # An example use case of this flag is the --verbose flag. The more often this 1380 # flag was given, the more verbose the output messages should be. 1381 DEFINE_multi_boolean() { _flags_define ${__FLAGS_TYPE_MULTI_BOOLEAN}
"$@"; }
1382 DEFINE_multi_bool() { _flags_define ${__FLAGS_TYPE_MULTI_BOOLEAN}
"$@"; }
1384 # Other multi-flags, i.e., flags that may be given multiple times 1385 DEFINE_multi_float() { _flags_define ${__FLAGS_TYPE_MULTI_FLOAT}
"$@"; }
1386 DEFINE_multi_integer() { _flags_define ${__FLAGS_TYPE_MULTI_INTEGER}
"$@"; }
1387 DEFINE_multi_int() { _flags_define ${__FLAGS_TYPE_MULTI_INTEGER}
"$@"; }
1388 DEFINE_multi_string() { _flags_define ${__FLAGS_TYPE_MULTI_STRING}
"$@"; }
1390 # ---------------------------------------------------------------------------- 1391 # command-line parsing 1392 # ---------------------------------------------------------------------------- 1394 ############################################################################## 1398 # unnamed: list: command-line flags to parse 1400 # integer: success of operation, or error 1403 # define standard flags if not already defined 1404 [ -z
"${__flags_help_type:-}" ] && \
1405 DEFINE_boolean
'help' false 'Show help and exit.' 'h' 'help' 1406 [ -z
"${__flags_helpman_type:-}" -a ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH} ] && \
1407 DEFINE_boolean
'helpman' false 'Show help as man page and exit. If --execman is true (the default), 1408 a temporary man page file is written and displayed using man. 1409 Otherwise, if --noexecman was given before, the generated man 1410 page is printed to stdout instead.' \
1411 "${__FLAGS_NULL}" 'help' 1412 [ -z
"${__flags_execman_type:-}" -a ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH} ] && \
1413 DEFINE_boolean
'execman' true 'Execute man to view generated man page. See --helpman.' \
1414 "${__FLAGS_NULL}" 'help' 1415 [ -z
"${__flags_helpxml_type:-}" -a ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH} ] && \
1416 DEFINE_boolean
'helpxml' false 'Output help in XML format and exit.' "${__FLAGS_NULL}" 'help' 1417 [ -z
"${__flags_helpshort_type:-}" -a ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH} ] && \
1418 DEFINE_boolean
'helpshort' false 'Show usage information and exit.' "${__FLAGS_NULL}" 'help' 1419 [ -z
"${__flags_version_type:-}" ] && \
1420 DEFINE_boolean
'version' false 'Show version and exit.' "${__FLAGS_NULL}" 'help' 1421 [ -z
"${__flags_verbose_type:-}" ] && \
1422 DEFINE_multi_boolean
'verbose' 0
'Increase verbosity of output messages. 1423 Can be given multiple times.' 'v' 'help' 1426 if [ $# -gt 0 ]; then
1427 if [ ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} ]; then
1428 _flags_getoptStandard
"$@" 1430 _flags_getoptEnhanced
"$@" 1434 # nothing passed; won't bother running getopt 1436 flags_return=${FLAGS_TRUE}
1439 if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then
1440 _flags_parseGetopt $#
"${__flags_opts}" 1444 [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_fatal
"${flags_error}" 1445 [[ ${flags_error} =
'help requested' ]] && exit 0
1446 [[ ${flags_error} =
'version requested' ]] && exit 0
1447 return ${flags_return}
1450 # ---------------------------------------------------------------------------- 1451 # getopt information 1452 # ---------------------------------------------------------------------------- 1454 ############################################################################## 1455 # This is a helper function for determining the 'getopt' version for platforms 1456 # where the detection isn't working. It simply outputs debug information that 1457 # can be included in a bug report. 1462 # debug info that can be included in a bug report 1468 _flags_debug
"uname -a: `uname -a`" 1469 _flags_debug
"PATH: ${PATH}" 1472 if [ -n
"${BASH_VERSION:-}" ]; then
1473 _flags_debug
'shell: bash' 1474 _flags_debug
"BASH_VERSION: ${BASH_VERSION}" 1475 elif [ -n
"${ZSH_VERSION:-}" ]; then
1476 _flags_debug
'shell: zsh' 1477 _flags_debug
"ZSH_VERSION: ${ZSH_VERSION}" 1481 ${FLAGS_GETOPT_CMD} >/dev/null
1482 _flags_getoptReturn=$?
1483 _flags_debug
"getopt return: ${_flags_getoptReturn}" 1484 _flags_debug
"getopt --version: `${FLAGS_GETOPT_CMD} --version 2>&1`" 1486 unset _flags_getoptReturn
1489 ############################################################################## 1490 # Returns whether the detected getopt version is the enhanced version. 1497 # bool: true if getopt is the enhanced version 1500 test ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH}
1503 ############################################################################## 1504 # Returns whether the detected getopt version is the standard version. 1509 # bool: true if getopt is the standard version 1512 test ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_STD}
1515 # ---------------------------------------------------------------------------- 1516 # help and usage information 1517 # ---------------------------------------------------------------------------- 1519 ############################################################################## 1520 # Prints usage as in synopsis section of man pages. 1523 flags_requiredFlags_=
' ' 1524 flags_optionalFlags_=
' ' 1525 for flags_name_ in ${__flags_longNames};
do 1526 flags_usName_=`_flags_underscoreName ${flags_name_}`
1527 flags_category_=`_flags_getFlagInfo
"${flags_usName_}" ${__FLAGS_INFO_CATEGORY}`
1528 if [
"${flags_category_}" =
'required' ]; then
1529 flags_requiredFlags_=
"${flags_requiredFlags_}${flags_name_} " 1530 elif [
"${flags_category_}" !=
'help' ]; then
1531 flags_optionalFlags_=
"${flags_optionalFlags_}${flags_name_} " 1535 flags_command_=${HELP_COMMAND:-${0##*/}} # actual command name (constant)
1536 flags_executable_="${FLAGS_PARENT:-${0##*/}}
" # name of executable (may differ) 1539 if [ -n "${flags_optionalFlags_}
" ]; then 1540 for flags_name_ in ${flags_optionalFlags_}; do 1541 flags_usage_="${flags_usage_} [`_flags_flagusage ${flags_name_}`]
" 1544 if [ -n "${flags_requiredFlags_}
" ]; then 1545 for flags_name_ in ${flags_requiredFlags_}; do 1546 flags_usage_="${flags_usage_} `_flags_flagusage ${flags_name_}`
" 1549 flags_usage_="${flags_usage_} [args]
" 1552 # use first sentence of description as brief description similar to Doxygen 1553 if [ -n "${HELP_DESCRIPTION}
" ]; then 1554 flags_brief_=${HELP_DESCRIPTION%%.*} 1555 flags_brief_="$(echo
"${flags_brief_}"|sed
's/^\ *//g;s/\ *$//g'|tr
'\n' ' ')
" 1556 flags_brief_=" ${flags_command_} -- ${flags_brief_}
" 1557 flags_columns_=`_flags_columns` 1558 flags_columns_=`expr -- "${flags_columns_}
" - 3` 1559 if [ `expr -- "${flags_brief_}
" : '.*'` -gt ${flags_columns_} ]; then 1560 flags_brief_="${flags_brief_:0:${flags_columns_}}
" 1561 flags_brief_="${flags_brief_% *}...
" 1563 echo "${flags_brief_}
" 1565 echo " ${flags_command_}
" 1569 # note: the silliness with the x's is purely for ksh93 on Ubuntu 6.06 1570 # because it doesn't like empty strings when used in this manner. 1571 flags_emptyStr_="`echo \
"x${flags_executable_}x\" \ 1572 |awk '{printf "%
"length($0)+3"s
", ""}'`" 1573 flags_emptyStrLen_=`expr --
"${flags_emptyStr_}" :
'.*'`
1574 flags_usage_=
"$(echo "${flags_emptyStr_}${flags_usage_}
" | fmt -l 0 -$(_flags_columns))" 1575 flags_usage_=
" ${flags_executable_}${flags_usage_:${flags_emptyStrLen_}}" 1576 echo
"${flags_usage_}" 1578 unset flags_name_ flags_command_ flags_usage_ flags_brief_ flags_usName_ \
1579 flags_executable_ flags_type_ flags_optionalFlags_ flags_requiredFlags_ \
1580 flags_standardFlags_ flags_emptyStr_ flags_emptyStrLen_ flags_columns_
1582 return ${FLAGS_TRUE}
1585 ############################################################################## 1586 # Print help for named flag. 1589 # flags_name_: string: long name of flag 1590 # flags_maxNameLen: integer: (optional) maximum length of long flag names 1591 # used to align help texts (default: 0) 1592 # flags_showDefault: boolean: (optional) whether to display default value (default: true) 1594 # integer: success of operation (always returns true) 1598 flags_maxNameLen=${2:-0}
1599 flags_showDefault_=${3:-${FLAGS_TRUE}}
1602 flags_usName_=`_flags_underscoreName ${flags_name_}`
1604 flags_help_=`_flags_getFlagInfo \
1605 "${flags_usName_}" ${__FLAGS_INFO_HELP}`
1606 flags_short_=`_flags_getFlagInfo \
1607 "${flags_usName_}" ${__FLAGS_INFO_SHORT}`
1608 flags_type_=`_flags_getFlagInfo \
1609 "${flags_usName_}" ${__FLAGS_INFO_TYPE}`
1610 flags_category_=`_flags_getFlagInfo \
1611 "${flags_usName_}" ${__FLAGS_INFO_CATEGORY}`
1613 flags_help_=$(echo
"${flags_help_}"|sed
's/^\ *//g'|tr
'\n' ' ')
1615 if [ ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH} ]; then
1616 # add [no] to long boolean flag names, except the 'help' flags 1617 [ ${flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} ] && \
1618 flags_boolStr_=
'[no]' 1620 flags_flagStr_=
"${flags_flagStr_}--${flags_boolStr_}${flags_name_}" 1623 [
"${flags_short_}" !=
"${__FLAGS_NULL}" ] && \
1624 flags_flagStr_=
"${flags_flagStr_}, -${flags_short_}" 1625 # fill with spaces for alignment of help texts 1626 flags_flagStrLen_=`expr --
"${flags_flagStr_}" :
'.*'`
1627 flags_numSpaces_=`expr -- 12 +
"${flags_maxNameLen_}" -
"${flags_flagStrLen_}"`
1628 [ ${flags_numSpaces_} -ge 0 ] || flags_numSpaces_=0
1629 flags_spaces_=`printf %${flags_numSpaces_}s`
1630 flags_flagStr_=
"${flags_flagStr_}${flags_spaces_}" 1632 flags_defaultStr_=
"(default: `_flags_defaultStr ${flags_name_}`)" 1634 flags_helpStr_=
" ${flags_flagStr_} ${flags_help_}" 1635 if [ ${flags_showDefault_} -eq ${FLAGS_TRUE} ]; then
1636 flags_helpStr_=
"${flags_helpStr_} ${flags_defaultStr_}" 1638 if [ ${flags_showDefault_} -eq ${FLAGS_TRUE} ]; then
1639 flags_helpStr_=
"${flags_help_} ${flags_defaultStr_}" 1641 flags_helpStr_=
"${flags_help_}" 1643 flags_helpStrLen_=`expr --
"${flags_helpStr_}" :
'.*'`
1644 flags_columns_=`_flags_columns`
1645 # note: the silliness with the x's is purely for ksh93 on Ubuntu 6.06 1646 # because it doesn't like empty strings when used in this manner. 1647 flags_emptyStr_=
"`echo \"x${flags_flagStr_}x\" \ 1648 |awk '{printf "%
"length($0)+6"s
", ""}'`" 1649 flags_emptyStrLen_=`expr --
"${flags_emptyStr_}" :
'.*'`
1650 # split long help text on multiple lines 1651 flags_helpStr_=
"$(echo "${flags_emptyStr_}${flags_helpStr_}
" | fmt -l 0 -${flags_columns_})" 1652 flags_helpStr_=
" ${flags_flagStr_} ${flags_helpStr_:${flags_emptyStrLen_}}" 1653 echo
"${flags_helpStr_}" 1655 unset flags_boolStr_ flags_defaultStr_ flags_emptyStr_ flags_emptyStrLen_ \
1656 flags_flagStr_ flags_help_ flags_helpStr flags_helpStrLen flags_name_ \
1657 flags_columns_ flags_short_ flags_type_ flags_usName_ flags_flagStrLen_
1659 return ${FLAGS_TRUE}
1662 ############################################################################## 1663 # Print help of all flags. 1665 # This function is used by flags_help() and flags_helpshort(). 1668 # flags_helpshort_: bool: display only short help of options, leaving out 1669 # less important options 1671 # integer: success of operation (always returns true) 1674 flags_helpshort_=${1:-${FLAGS_FALSE}}
1678 # reset (all) categories 1680 flags_otherFlags_=
'' 1681 for flags_category_ in
"${__flags_categoryNames[@]}";
do 1682 flags_usCategory_=`_flags_underscoreName ${flags_category_}`
1683 eval
"flags_${flags_usCategory_}Flags_=''" 1686 # get lists of flags belonging to each category and 1687 # maximum length of long names required for alignment of help 1688 for flags_name_ in ${__flags_longNames};
do 1689 flags_usName_=`_flags_underscoreName ${flags_name_}`
1691 # update maximum length of flag name 1692 flags_nameStrLen_=`expr --
"${flags_name_}" :
'.*'`
1693 # length + 4 for boolean flags because of the '[no]' prefix 1694 flags_type_=`_flags_getFlagInfo
"${flags_usName_}" ${__FLAGS_INFO_TYPE}`
1695 if [ ${flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} ]; then
1696 flags_nameStrLen_=`expr --
"${flags_nameStrLen}" + 4`
1698 if [ ${flags_nameStrLen_} -gt ${flags_maxNameLen_} ]; then
1699 flags_maxNameLen_=${flags_nameStrLen_}
1702 # append flag to list for its category 1703 flags_category_=`_flags_getFlagInfo
"${flags_usName_}" ${__FLAGS_INFO_CATEGORY}`
1704 if [
"${flags_category_}" =
"${__FLAGS_NULL}" ]; then
1705 flags_otherFlags_=
"${flags_otherFlags_} ${flags_name_}" 1707 flags_usCategory_=`_flags_underscoreName ${flags_category_}`
1708 eval
"flags_${flags_usCategory_}Flags_=\"\${flags_${flags_usCategory_}Flags_} ${flags_name_}\"" 1712 # select subset of categories to display 1713 if [ ${flags_helpshort_} -eq ${FLAGS_TRUE} ]; then
1714 flags_categories_=()
1715 for flags_category_ in
"${__flags_categoryNames[@]}";
do 1716 if [
"${flags_category_}" =
'help' ]; then
1717 flags_usCategory_=`_flags_underscoreName ${flags_category_}`
1718 eval
"unset flags_${flags_usCategory_}Flags_" 1721 flags_categories_[${#flags_categories_[@]}]=
"${flags_category_}" 1724 flags_categories_=(
"${__flags_categoryNames[@]}")
1727 # output help of required flags
1728 if [ -n
"${flags_requiredFlags_}" ]; then
1729 echo
" The required options are as follows:" 1731 flags_requiredFlags_=`_flags_sortList
"${flags_requiredFlags_}"`
1732 for flags_name_ in ${flags_requiredFlags_};
do 1733 flags_helpflag ${flags_name_} ${flags_maxNameLen_} ${FLAGS_FALSE}
1738 # output help of non-required and non-help flags 1739 for flags_category_ in
"${flags_categories_[@]}";
do 1740 if [
"${flags_category_}" =
'required' -o \
1741 "${flags_category_}" =
'help' ]; then
1744 flags_usCategory_=`_flags_underscoreName ${flags_category_}`
1745 eval
"flags_${flags_usCategory_}Flags_=\`_flags_sortList \"\${flags_${flags_usCategory_}Flags_}\"\`" 1746 eval
"flags_names_=\"\${flags_${flags_usCategory_}Flags_}\"" 1747 if [ -n
"${flags_names_}" ]; then
1748 echo
" The ${flags_category_} options are as follows:" 1750 for flags_name_ in ${flags_names_};
do 1757 # output help of remaining non-help flags 1758 if [ -n
"${flags_otherFlags_}" ]; then
1759 echo
" The available options are as follows:" 1761 flags_otherFlags_=`_flags_sortList
"${flags_otherFlags_}"`
1762 for flags_name_ in ${flags_otherFlags_};
do 1768 # output help of help flags 1769 if [ -n
"${flags_helpFlags_}" ]; then
1770 echo
" The help options are as follows:" 1772 for flags_name_ in ${flags_helpFlags_};
do 1773 flags_helpflag ${flags_name_} ${flags_maxNameLen_} ${FLAGS_FALSE}
1779 for flags_category_ in
"${flags_categories_[@]}";
do 1780 flags_usCategory_=`_flags_underscoreName ${flags_category_}`
1781 eval
"unset flags_${flags_usCategory_}Flags_" 1783 unset flags_maxNameLen_ flags_name_ flags_nameStrLen_ flags_type_ \
1784 flags_otherFlags flags_categories_ flags_category_ flags_usCategory_
1786 return ${FLAGS_TRUE}
1789 ############################################################################## 1790 # This is effectively a 'usage()' function. It prints a usage information on 1791 # how to use the program and the available flags. Note this function can be 1792 # overridden so other apps can define their own short help output, 1793 # replacing this one, if they want. 1798 # integer: success of operation (always returns true) 1808 return ${FLAGS_TRUE}
1811 ############################################################################## 1812 # This is effectively a 'help()' function. It prints a program description together 1813 # with usage information and example command-lines on how to use the program. 1814 # Note this function can be overridden so other apps can define their own help 1815 # output, replacing this one, if they want. 1820 # integer: success of operation (always returns true) 1827 if [ -n
"${HELP_DESCRIPTION:-}" ]; then
1830 flags_fmtStr_=$(echo
"${HELP_DESCRIPTION}"\
1831 |awk
'{printf "%s:NEWLINE:",$0}'\
1832 |sed
's/^\ *:NEWLINE://g;s/:NEWLINE:\ *$//g;s/:NEWLINE:/:NEWLINE: /g;s/:NEWLINE:/\\n/g')
1833 flags_fmtStr_=
"$(echo -e " ${flags_fmtStr_}
" | fmt -l 0 -$(_flags_columns))" 1834 echo
"${flags_fmtStr_}" 1840 if [ -n
"${HELP_CONTACT:-}" ]; then
1842 flags_fmtStr_=$(echo
"${HELP_CONTACT}"\
1843 |awk
'{printf "%s:NEWLINE:",$0}'\
1844 |sed
's/^\ *:NEWLINE://g;s/:NEWLINE:$//g;s/:NEWLINE:/:NEWLINE: /g;s/:NEWLINE:/\\n/g')
1845 flags_fmtStr_=
"$(echo " ${flags_fmtStr_}
" | fmt -l 0 -$(_flags_columns))" 1846 echo
"${flags_fmtStr_}" 1852 return ${FLAGS_TRUE}
1855 # ---------------------------------------------------------------------------- 1857 # ---------------------------------------------------------------------------- 1859 ############################################################################## 1860 # This function outputs the help of named flag in XML format 1863 # flags_name_: string: long name of flag 1864 # indentation: integer: (optional) indentation 1866 # integer: success of operation (always returns true) 1869 # get flag attributes 1871 flags_indentation_=${2:-0}
1872 flags_usName_=`_flags_underscoreName ${flags_name_}`
1874 flags_help_=`_flags_getFlagInfo \
1875 "${flags_usName_}" ${__FLAGS_INFO_HELP}`
1876 flags_short_=`_flags_getFlagInfo \
1877 "${flags_usName_}" ${__FLAGS_INFO_SHORT}`
1878 flags_type_=`_flags_getFlagInfo \
1879 "${flags_usName_}" ${__FLAGS_INFO_TYPE}`
1880 flags_category_=`_flags_getFlagInfo \
1881 "${flags_usName_}" ${__FLAGS_INFO_CATEGORY}`
1884 flags_help_=$(echo
"${flags_help_}"|sed
's/^\ *//g'|tr
'\n' ' '|sed
's/^\ *//g;s/\ *$//g')
1886 [
"${flags_short_}" =
"${__FLAGS_NULL}" ] && flags_short_=
'' 1887 [
"${flags_category_}" =
"${__FLAGS_NULL}" ] && flags_category_=
'' 1889 # current and
default value
1890 flags_current_=`_flags_currentStr ${flags_usName_}`
1891 flags_default_=`_flags_defaultStr ${flags_usName_}`
1894 flags_type_=`_flags_typeStr ${flags_type_}`
1897 flags_short_=`_flags_xmlText
"${flags_short_}"`
1898 flags_category_=`_flags_xmlText
"${flags_category_}"`
1899 flags_help_=`_flags_xmlText
"${flags_help_}"`
1900 flags_current_=`_flags_xmlText
"${flags_current_}"`
1901 flags_default_=`_flags_xmlText
"${flags_default_}"`
1902 flags_type_=`_flags_xmlText
"${flags_type_}"`
1905 flags_emptyStr_=`printf %${flags_indentation_}s`
1908 echo
"${flags_emptyStr_}<flag>" 1909 echo
"${flags_emptyStr_} <category>${flags_category_}</category>" 1910 echo
"${flags_emptyStr_} <name>${flags_name_}</name>" 1911 echo
"${flags_emptyStr_} <short_name>${flags_short_}</short_name>" 1912 echo
"${flags_emptyStr_} <meaning>${flags_help_}</meaning>" 1913 echo
"${flags_emptyStr_} <default>${flags_default_}</default>" 1914 echo
"${flags_emptyStr_} <current>${flags_current_}</current>" 1915 echo
"${flags_emptyStr_} <type>${flags_type_}</type>" 1916 echo
"${flags_emptyStr_}</flag>" 1918 unset flags_current_ flags_default_ flags_name_ flags_usName_ \
1919 flags_short_ flags_type_ flags_help_ flags_indentation_ \
1923 ############################################################################## 1924 # This function outputs the help in XML format. 1929 # integer: success of operation (always returns true) 1932 # get (re-formated) help strings 1933 flags_executable_=${FLAGS_PARENT:-${0##*/}}
1934 flags_command_=${HELP_COMMAND:-${flags_executable_}}
1935 flags_version_=${HELP_VERSION:-
'unknown'}
1936 flags_copyright_=$(echo
"${HELP_COPYRIGHT}"\
1937 |awk
'{printf "%s:NEWLINE:",$0}'\
1938 |sed
's/^\ *:NEWLINE://g;s/:NEWLINE:\ *$//g;s/:NEWLINE:/\\n/g')
1939 flags_contact_=$(echo
"${HELP_CONTACT}"\
1940 |awk
'{printf "%s:NEWLINE:",$0}'\
1941 |sed
's/^\ *:NEWLINE://g;s/:NEWLINE:$//g;s/:NEWLINE:/\\n/g')
1942 flags_description_=$(echo
"${HELP_DESCRIPTION}"\
1943 |awk
'{printf "%s:NEWLINE:",$0}'\
1944 |sed
's/^\ *:NEWLINE://g;s/:NEWLINE:\ *$//g;s/:NEWLINE:/\\n/g')
1947 flags_executable_=`_flags_xmlText
"${flags_executable_}"`
1948 flags_command_=`_flags_xmlText
"${flags_command_}"`
1949 flags_version_=`_flags_xmlText
"${flags_version_}"`
1950 flags_copyright_=`_flags_xmlText
"${flags_copyright_}"`
1951 flags_contact_=`_flags_xmlText
"${flags_contact_}"`
1952 flags_description_=`_flags_xmlText
"${flags_description_}"`
1955 echo
"<?xml version=\"1.0\"?>" 1957 echo
" <name>${flags_command_}</name>" 1958 echo
" <program>${flags_executable_}</program>" 1959 echo
" <version>${flags_version_}</version>" 1960 echo
" <copyright>${flags_copyright_}</copyright>" 1961 echo
" <contact>${flags_contact_}</contact>" 1962 echo
" <usage>${flags_description_}</usage>" 1963 for flags_name_ in ${__flags_longNames};
do 1969 unset flags_executable_ flags_command_ flags_version_ \
1970 flags_name_ flags_description_ flags_copyright_ flags_contact_
1972 return ${FLAGS_TRUE}
1975 # ---------------------------------------------------------------------------- 1977 # ---------------------------------------------------------------------------- 1979 ############################################################################## 1980 # Prints NAME section of man page. 1983 flags_command_=${HELP_COMMAND:-${0##*/}}
1984 flags_command_=`_flags_manText
"${flags_command_}"`
1987 # use first sentence of description as brief description similar to Doxygen 1988 if [ -n
"${HELP_DESCRIPTION}" ]; then
1989 flags_brief_=${HELP_DESCRIPTION%%.*}
1990 flags_brief_=
"$(echo "${flags_brief_}
"|sed 's/^\ *//g;s/\ *$//g'|tr '\n' ' ')" 1991 flags_brief_=
"${flags_command_} -- ${flags_brief_}" 1992 flags_columns_=`_flags_columns`
1993 flags_columns_=`expr --
"${flags_columns_}" - 24`
1994 [ ${flags_columns_} -lt 80 ] && flags_columns_=80
1995 if [ `expr --
"${flags_brief_}" :
'.*'` -gt ${flags_columns_} ]; then
1996 flags_brief_=
"${flags_brief_:0:${flags_columns_}}" 1997 flags_brief_=
"${flags_brief_% *}..." 1999 flags_brief_=`_flags_manText
"${flags_brief_}"`
2000 echo
"${flags_brief_}" 2002 echo
"${flags_command_}" 2005 unset flags_command_ flags_brief_ flags_columns_
2007 return ${FLAGS_TRUE}
2010 ############################################################################## 2011 # Prints SYNOPSIS section of man page. 2014 flags_executable_=
"${FLAGS_PARENT:-${0##*/}}" 2017 echo
"\fB${flags_executable_}\fR" 2019 flags_requiredFlags_=
' ' 2020 flags_optionalFlags_=
' ' 2021 for flags_name_ in ${__flags_longNames};
do 2022 flags_usName_=`_flags_underscoreName ${flags_name_}`
2023 flags_category_=`_flags_getFlagInfo
"${flags_usName_}" ${__FLAGS_INFO_CATEGORY}`
2024 if [
"${flags_category_}" =
'required' ]; then
2025 flags_requiredFlags_=
"${flags_requiredFlags_}${flags_name_} " 2026 elif [
"${flags_category_}" !=
'help' ]; then
2027 flags_optionalFlags_=
"${flags_optionalFlags_}${flags_name_} " 2031 flags_requiredFlags_=`_flags_sortList
"${flags_requiredFlags_}"`
2032 flags_optionalFlags_=`_flags_sortList
"${flags_optionalFlags_}"`
2034 if [ -n
"${flags_optionalFlags_}" ]; then
2035 for flags_name_ in ${flags_optionalFlags_};
do 2036 echo
"[\fB`_flags_helpman_flagusage ${flags_name_}`\fR]" 2039 if [ -n
"${flags_requiredFlags_}" ]; then
2040 for flags_name_ in ${flags_requiredFlags_};
do 2041 echo
"\fB`_flags_helpman_flagusage ${flags_name_}`\fR" 2046 unset flags_executable_ flags_name_ flags_usName_ flags_type_ \
2047 flags_optionalFlags_ flags_requiredFlags_
2049 return ${FLAGS_TRUE}
2052 ############################################################################## 2053 # Prints DESCRIPTION section of man page. 2056 if [ -n
"${HELP_DESCRIPTION}" ]; then
2057 echo
".SH DESCRIPTION" 2058 flags_description_=
"${HELP_DESCRIPTION:-'No description available.'}" 2059 flags_description_=`_flags_manText
"${flags_description_}"`
2060 echo
"${flags_description_}" 2062 unset flags_description_
2066 ############################################################################## 2067 # Prints OPTIONS section entry of man page of named flag. 2071 flags_showDefault_=${2:-${FLAGS_TRUE}}
2074 flags_usName_=`_flags_underscoreName ${flags_name_}`
2076 _flags_getFlagDefault
"${flags_usName_}" 'flags_default_' 2077 flags_help_=`_flags_getFlagInfo \
2078 "${flags_usName_}" ${__FLAGS_INFO_HELP}`
2079 flags_short_=`_flags_getFlagInfo \
2080 "${flags_usName_}" ${__FLAGS_INFO_SHORT}`
2081 flags_type_=`_flags_getFlagInfo \
2082 "${flags_usName_}" ${__FLAGS_INFO_TYPE}`
2083 flags_category_=`_flags_getFlagInfo \
2084 "${flags_usName_}" ${__FLAGS_INFO_CATEGORY}`
2086 flags_help_=$(echo
"${flags_help_}"|sed
's/^\ *//g'|tr
'\n' ' ')
2088 # adjust type ID
for multi-flags
2089 if [ ${flags_type_} -gt 128 ]; then
2090 flags_type_=`expr
"${flags_type_}" - 128`
2093 if [ ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH} ]; then
2094 # add [no] to long boolean flag names, except the 'help' flags 2095 [ ${flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} ] && \
2096 flags_boolStr_=
'[no]' 2098 flags_flagStr_=
"\fB${flags_flagStr_}--${flags_boolStr_}${flags_name_}" 2100 [
"${flags_short_}" !=
"${__FLAGS_NULL}" ] && \
2102 flags_flagStr_=
"${flags_flagStr_}, -${flags_short_}" 2103 flags_flagStr_=
"${flags_flagStr_}\fR" 2105 if [ ${flags_type_} -ne ${__FLAGS_TYPE_BOOLEAN} ]; then
2106 flags_flagStr_=
"${flags_flagStr_} \fI`_flags_typeStr ${flags_type_}`\fR" 2109 if [ ${flags_showDefault_} -eq ${FLAGS_TRUE} ]; then
2110 flags_defaultStr_=`_flags_defaultStr
"${flags_usName_}"`
2111 flags_defaultStr_=
" (default:\ ${flags_defaultStr_//\ /\\ })" 2113 flags_defaultStr_=
'' 2117 echo
"${flags_flagStr_}" 2118 echo
"${flags_help_}${flags_defaultStr_}" 2120 unset flags_boolStr_ flags_default_ flags_defaultStr_ flags_emptyStr_ flags_emptyStrLen_ \
2121 flags_flagStr_ flags_help_ flags_helpStr flags_helpStrLen flags_name_ \
2122 flags_columns_ flags_short_ flags_type_ flags_usName_ flags_flagStrLen_
2124 return ${FLAGS_TRUE}
2127 ############################################################################## 2128 # Prints OPTIONS section of man page. 2132 # get lists of flags belonging to same category 2133 flags_otherFlags_=
'' 2134 for flags_category_ in
"${__flags_categoryNames[@]}";
do 2135 flags_usCategory_=`_flags_underscoreName ${flags_category_}`
2136 eval
"flags_${flags_usCategory_}Flags_=''" 2138 for flags_name_ in ${__flags_longNames};
do 2139 flags_nameStrLen_=`expr --
"${flags_name_}" :
'.*'`
2140 flags_usName_=`_flags_underscoreName ${flags_name_}`
2141 flags_category_=`_flags_getFlagInfo
"${flags_usName_}" ${__FLAGS_INFO_CATEGORY}`
2142 if [
"${flags_category_}" =
"${__FLAGS_NULL}" ]; then
2143 flags_otherFlags_=
"${flags_otherFlags_} ${flags_name_}" 2145 flags_usCategory_=`_flags_underscoreName ${flags_category_}`
2146 eval
"flags_${flags_usCategory_}Flags_=\"\${flags_${flags_usCategory_}Flags_} ${flags_name_}\"" 2149 # output help of required flags 2150 if [ -n
"${flags_requiredFlags_}" ]; then
2152 echo
"\fBThe required options are as follows:\fR" 2153 flags_requiredFlags_=`_flags_sortList
"${flags_requiredFlags_}"`
2154 for flags_name_ in ${flags_requiredFlags_};
do 2158 # output help of non-required and non-help flags 2159 for flags_category_ in
"${__flags_categoryNames[@]}";
do 2160 if [
"${flags_category_}" =
'required' -o \
2161 "${flags_category_}" =
'help' ]; then
2164 flags_usCategory_=`_flags_underscoreName ${flags_category_}`
2165 eval
"flags_${flags_usCategory_}Flags_=\`_flags_sortList \"\${flags_${flags_usCategory_}Flags_}\"\`" 2166 eval
"flags_names_=\"\${flags_${flags_usCategory_}Flags_}\"" 2167 if [ -n
"${flags_names_}" ]; then
2169 echo
"\fBThe ${flags_category_} options are as follows:\fR" 2170 for flags_name_ in ${flags_names_};
do 2175 # output help of remaining non-help flags 2176 if [ -n
"${flags_otherFlags_}" ]; then
2178 echo
"\fBThe available options are as follows:\fR" 2179 flags_otherFlags_=`_flags_sortList
"${flags_otherFlags_}"`
2180 for flags_name_ in ${flags_otherFlags_};
do 2184 # output help of help flags 2185 if [ -n
"${flags_helpFlags_}" ]; then
2187 echo
"\fBThe help options are as follows:\fR" 2188 for flags_name_ in ${flags_helpFlags_};
do 2194 for flags_category_ in
"${__flags_categoryNames[@]}";
do 2195 flags_usCategory_=`_flags_underscoreName ${flags_category_}`
2196 eval
"unset flags_${flags_usCategory_}Flags_" 2198 unset flags_maxNameLen_ flags_name_ flags_nameStrLen_ flags_type_ \
2199 flags_otherFlags flags_category_ flags_usCategory_
2202 ############################################################################## 2203 # Prints COPYRIGHT section of man page. 2206 if [ -n
"${HELP_COPYRIGHT}" ]; then
2207 echo
".SH COPYRIGHT" 2208 flags_copyright_=
"${HELP_COPYRIGHT}" 2209 flags_copyright_=`echo
"${flags_copyright_}"|awk
'{printf "%s\n.br\n",$0}'`
2210 flags_copyright_=`_flags_manText
"${flags_copyright_}"`
2211 echo
"${flags_copyright_}" 2213 unset flags_copyright_
2217 ############################################################################## 2218 # Prints CONTACT section of man page. 2221 if [ -n
"${HELP_CONTACT}" ]; then
2223 flags_contact_=
"${HELP_CONTACT}" 2224 flags_contact_=`_flags_manText
"${flags_contact_}"`
2225 echo
"${flags_contact_}" 2227 unset flags_contact_
2231 ############################################################################## 2232 # This function outputs the help in man page format. 2237 # integer: success of operation (always returns true) 2240 flags_command_=${FLAGS_PARENT:-${0##*/}}
2241 flags_command_=`_flags_manText
"${flags_command_}"`
2243 echo
".TH \"${flags_command_}\" 1 `date '+%e\ %B\ %G'`" 2251 unset flags_command_
2253 return ${FLAGS_TRUE}
2256 # ---------------------------------------------------------------------------- 2257 # version information 2258 # ---------------------------------------------------------------------------- 2260 ############################################################################## 2261 # This function outputs the version and copyright. 2266 # integer: success of operation (always returns true) 2269 flags_command_=${HELP_COMMAND:-$0##*/}
2270 flags_version_=${HELP_VERSION:-
'unknown'}
2271 echo
"${flags_command_} version ${flags_version_}" 2272 if [ -n
"${HELP_COPYRIGHT}" ]; then
2273 flags_copyright_=$(echo
"${HELP_COPYRIGHT}"\
2274 |awk
'{printf "%s:NEWLINE:",$0}'\
2275 |sed
's/^\ *:NEWLINE://g;s/:NEWLINE:\ *$//g;s/:NEWLINE:/\\n/g')
2276 echo -
e "${flags_copyright_}" 2278 unset flags_command_ flags_version_ flags_copyright_
2281 # ----------------------------------------------------------------------------
2283 # ----------------------------------------------------------------------------
2285 ##############################################################################
2286 # Reset shflags back to an uninitialized state.
2294 for flags_name_ in ${__flags_longNames};
do 2295 flags_usName_=`_flags_underscoreName ${flags_name_}`
2296 flags_strToEval_=
"unset FLAGS_${flags_usName_}" 2297 for flags_type_ in \
2298 ${__FLAGS_INFO_DEFAULT} \
2299 ${__FLAGS_INFO_HELP} \
2300 ${__FLAGS_INFO_SHORT} \
2301 ${__FLAGS_INFO_TYPE} \
2302 ${__FLAGS_INFO_CATEGORY}
2305 "${flags_strToEval_} __flags_${flags_usName_}_${flags_type_}" 2307 eval ${flags_strToEval_}
2310 # reset internal variables 2311 __flags_boolNames=
' ' 2312 __flags_longNames=
' ' 2313 __flags_shortNames=
' ' 2314 __flags_definedNames=
' ' 2315 __flags_categoryNames=
' ' 2317 unset flags_name_ flags_type_ flags_strToEval_ flags_usName_
function is(in result, in expected, in name)
Test whether a given result is equal to the expected result.
function flags_getoptInfo()
function flags_helpman_copyright()
function flags_helpman_name()
bool exists(const std::string path)
Test the existance of a file or directory.
function flags_getoptIsStd()
function flags_getoptIsEnh()
function flags_helpshort()
function flags_helpman_flags()
function flags_helpflags()
function flags_helpflag()
function flags_helpflagxml()
function flags_helpman_description()
function flags_helpman_synopsis()
function flags_helpman_flag()
function flags_helpman_contact()