shflags.sh
Go to the documentation of this file.
1 # ============================================================================
2 # Copyright (c) 2008 Kate Ward
3 # Copyright (c) 2011 University of Pennsylvania
4 # Copyright (c) 2011-2014 Andreas Schuh
5 # All Rights Reserved.
6 #
7 # Released under the LGPL (GNU Lesser General Public License)
8 # ============================================================================
9 
10 ##############################################################################
11 # @file shflags.sh
12 # @author Kate Ward <kate.ward at forestent.com>, Andreas Schuh
13 # @brief Advanced command-line flag library for Unix shell scripts.
14 #
15 # @sa http://code.google.com/p/shflags/
16 #
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.
20 #
21 # This module implements something like the google-gflags library available
22 # from http://code.google.com/p/google-gflags/.
23 #
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.
27 #
28 # - DEFINE_string: takes any input, and intreprets it as a string.
29 #
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.
36 #
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.
40 #
41 # - DEFINE_integer: takes an input and intreprets it as an integer.
42 #
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
47 #
48 # EXAMPLE USAGE:
49 #
50 # Example script hello.sh(.in):
51 # @code
52 # #! /bin/sh
53 # . ${BASIS_SOURCE} || exit 1
54 #
55 # DEFINE_string name 'world' "somebody's name" n
56 #
57 # FLAGS "$@" || exit $?
58 # eval set -- "${FLAGS_ARGV}"
59 #
60 # echo "Hello, ${FLAGS_name}."
61 # @endcode
62 #
63 # Usage of example script hello.sh:
64 # @code
65 # $ ./hello.sh -n Kate
66 # Hello, Kate.
67 # @endcode
68 #
69 # CUSTOMIZABLE BEHAVIOR:
70 #
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.
73 #
74 # ATTRIBUTES:
75 #
76 # Shared attributes:
77 # flags_error: last error message
78 # flags_return: last return value
79 #
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
83 #
84 # __flags_opts: options parsed by getopt
85 #
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
95 #
96 # NOTES:
97 #
98 # - Not all systems include a getopt version that supports long flags. On these
99 # systems, only short flags are recognized.
100 #
101 # - Lists of strings are space separated, and a null value is the '~' char.
102 
103 # return if FLAGS already loaded
104 [ -n "${FLAGS_VERSION:-}" ] && return 0
105 
106 FLAGS_VERSION='1.0.4pre-basis'
107 
108 # ============================================================================
109 # variables
110 # ============================================================================
111 
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}
115 
116 # return values that scripts can use
117 FLAGS_TRUE=0
118 FLAGS_FALSE=1
119 FLAGS_ERROR=2
120 
121 # logging functions
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}; }
126 
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'
132  fi
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"
136  fi
137 fi
138 
139 # ----------------------------------------------------------------------------
140 # constants
141 # ----------------------------------------------------------------------------
142 
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 "
146 
147 # getopt version
148 __FLAGS_GETOPT_VERS_STD=0
149 __FLAGS_GETOPT_VERS_ENH=1
150 __FLAGS_GETOPT_VERS_BSD=2
151 
152 ${FLAGS_GETOPT_CMD} >/dev/null 2>&1
153 case $? in
154  0) __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_STD} ;; # bsd getopt
155  2)
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}
159  else
160  __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_ENH}
161  fi
162  ;;
163  *) _flags_fatal 'unable to determine getopt version' ;;
164 esac
165 
166 # getopt optstring lengths
167 __FLAGS_OPTSTR_SHORT=0
168 __FLAGS_OPTSTR_LONG=1
169 
170 __FLAGS_NULL='~'
171 
172 # flag info strings
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'
178 
179 # flag lengths
180 __FLAGS_LEN_SHORT=0
181 __FLAGS_LEN_LONG=1
182 
183 # flag types
184 __FLAGS_TYPE_NONE=0
185 __FLAGS_TYPE_BOOLEAN=1
186 __FLAGS_TYPE_FLOAT=2
187 __FLAGS_TYPE_INTEGER=3
188 __FLAGS_TYPE_STRING=4
189 
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`
195 
196 # set the constants readonly
197 __flags_constants=`set |awk -F= '/^FLAGS_/ || /^__FLAGS_/ {print $1}'`
198 for __flags_const in ${__flags_constants}; do
199  # skip certain flags
200  case ${__flags_const} in
201  FLAGS_PARENT) continue ;;
202  esac
203  # set flag readonly
204  if [ -z "${ZSH_VERSION:-}" ]; then
205  readonly ${__flags_const}
206  else # handle zsh
207  case ${ZSH_VERSION} in
208  [123].*) readonly ${__flags_const} ;;
209  *) readonly -g ${__flags_const} ;; # declare readonly constants globally
210  esac
211  fi
212 done
213 unset __flags_const __flags_constants
214 
215 # ----------------------------------------------------------------------------
216 # internal variables
217 # ----------------------------------------------------------------------------
218 
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)
224 
225 # arrays
226 __flags_categoryNames=() # flag category names
227 
228 # others
229 __flags_columns='' # determined screen width in columns
230 __flags_opts='' # temporary storage for parsed getopt flags
231 
232 # ============================================================================
233 # private functions
234 # ============================================================================
235 
236 ##############################################################################
237 # Define a flag.
238 #
239 # Calling this function will define the following info variables for the
240 # specified flag:
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
247 #
248 # Args:
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
255 # Returns:
256 # integer: success of operation, or error
257 _flags_define()
258 {
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}
264  fi
265 
266  _flags_type_="$1"
267  _flags_name_="$2"
268  _flags_default_="$3"
269  _flags_help_="$4"
270  _flags_short_="${5:-${__FLAGS_NULL}}"
271  _flags_category_="${6:-${__FLAGS_NULL}}"
272 
273  _flags_return_=${FLAGS_TRUE}
274  _flags_usName_=`_flags_underscoreName ${_flags_name_}`
275 
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}
281  fi
282 
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}" ]
287  then
288  flags_error="short flag required for (${_flags_name_}) on this platform"
289  _flags_return_=${FLAGS_ERROR}
290  fi
291 
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}
298  fi
299  fi
300 
301  # check for existing short name definition
302  if [ ${_flags_return_} -eq ${FLAGS_TRUE} \
303  -a "${_flags_short_}" != "${__FLAGS_NULL}" ]
304  then
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}
309  fi
310  fi
311 
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_})"
317  else
318  if [ ${#_flags_default_[@]} -ne 1 ]; then
319  flags_error="${_flags_name_}: invalid default flag value '${_flags_default_}'"
320  _flags_return_=${FLAGS_ERROR}
321  fi
322  _flags_valueType_=${_flags_type_}
323  fi
324 
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} ;;
335  esac
336  else
337  flags_error="${_flags_name_}: invalid default flag value '${_flags_default_}'"
338  _flags_return_=${FLAGS_ERROR}
339  fi
340  ;;
341 
342  ${__FLAGS_TYPE_MULTI_BOOLEAN})
343  if _flags_validateInteger "${_flags_default_}"; then
344  :
345  else
346  flags_error="${_flags_name_}: invalid default flag value '${_flags_default_}'"
347  _flags_return_=${FLAGS_ERROR}
348  fi
349  ;;
350 
351  *)
352  for _flags_defaultValue_ in "${_flags_default_[@]}"; do
353  case ${_flags_valueType_} in
354  ${__FLAGS_TYPE_FLOAT})
355  if _flags_validateFloat "${_flags_defaultValue_}"; then
356  :
357  else
358  flags_error="${_flags_name_}: invalid default flag value '${_flags_defaultValue_}'"
359  _flags_return_=${FLAGS_ERROR}
360  fi
361  ;;
362 
363  ${__FLAGS_TYPE_INTEGER})
364  if _flags_validateInteger "${_flags_defaultValue_}"; then
365  :
366  else
367  flags_error="${_flags_name_}: invalid default flag value '${_flags_defaultValue_}'"
368  _flags_return_=${FLAGS_ERROR}
369  fi
370  ;;
371 
372  ${__FLAGS_TYPE_STRING}) ;; # everything in shell is a valid string
373 
374  *)
375  flags_error="${_flags_name_}: unrecognized flag type '${_flags_type_}'"
376  _flags_return_=${FLAGS_ERROR}
377  ;;
378  esac
379  done
380  ;;
381  esac
382  fi
383 
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_[@]}\")"
389  else
390  eval "FLAGS_${_flags_usName_}='${_flags_default_}'"
391  eval "__flags_${_flags_usName_}_${__FLAGS_INFO_DEFAULT}='${_flags_default_}'"
392  fi
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_}'"
397 
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_} "
404 
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_} "
409 
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}
416  break
417  fi
418  done
419  if [ ${_flags_found_} -eq ${FLAGS_FALSE} ]; then
420  __flags_categoryNames[${#__flags_categoryNames[@]}]="${_flags_category_}"
421  fi
422  fi
423  fi
424 
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}
431 }
432 
433 ##############################################################################
434 # Return valid getopt options using currently defined list of long options.
435 #
436 # This function builds a proper getopt option string for short (and long)
437 # options, using the current list of long options for reference.
438 #
439 # Args:
440 # _flags_optStr: integer: option string type (__FLAGS_OPTSTR_*)
441 # Output:
442 # string: generated option string for getopt
443 # Returns:
444 # boolean: success of operation (always returns True)
445 _flags_genOptStr()
446 {
447  _flags_optStrType_=$1
448 
449  _flags_opts_=''
450 
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_}:"
465  fi
466  ;;
467 
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_}:"
474  ;;
475  esac
476  done
477 
478  echo "${_flags_opts_}"
479  unset _flags_name_ _flags_opts_ _flags_optStrType_ _flags_shortName_ \
480  _flags_type_ _flags_usName_
481  return ${FLAGS_TRUE}
482 }
483 
484 ##############################################################################
485 # Returns flag details based on a flag name and flag info.
486 #
487 # Args:
488 # string: underscored flag name
489 # string: flag info (see the _flags_define function for valid info types)
490 # Output:
491 # string: value of dereferenced flag variable
492 # Returns:
493 # integer: one of FLAGS_{TRUE|FALSE|ERROR}
494 _flags_getFlagInfo()
495 {
496  # note: adding gFI to variable names to prevent naming conflicts with calling
497  # functions
498  _flags_gFI_usName_=$1
499  _flags_gFI_info_=$2
500 
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}
506  else
507  # see if the _flags_gFI_usName_ variable is a string as strings can be
508  # empty...
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
514  # good ;-)
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}
520  else
521  flags_return=${FLAGS_ERROR}
522  flags_error="missing flag info variable (${_flags_infoVar_})"
523  fi
524  fi
525 
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}
531 }
532 
533 ##############################################################################
534 # Returns flag value based on a flag name.
535 #
536 # Args:
537 # unnamed: string: underscored flag name
538 # unnamed: string: name of the output variable
539 # Output:
540 # sets the variable named by the second argument to the current value,
541 # which is an array in case of a multi-flag.
542 # Returns:
543 # integer: one of FLAGS_{TRUE|FALSE|ERROR}
544 _flags_getFlagValue()
545 {
546  _flags_gFV_usName_=$1
547  _flags_gFV_type_=`_flags_getFlagInfo ${_flags_gFV_usName_} ${__FLAGS_INFO_TYPE}`
548 
549  if [ ${_flags_gFV_type_} -gt 128 ]; then
550  eval "$2=(\"\${FLAGS_${_flags_gFV_usName_}[@]}\")"
551  else
552  eval "$2=\"\${FLAGS_${_flags_gFV_usName_}:-}\""
553  fi
554 
555  unset _flags_gFV_usName_ _flags_gFV_type_
556 
557  return ${FLAGS_TRUE}
558 }
559 
560 ##############################################################################
561 # Returns flag default value based on a flag name.
562 #
563 # Args:
564 # unnamed: string: underscored flag name
565 # unnamed: string: name of the output variable
566 # Output:
567 # sets the variable named by the second argument to the default value,
568 # which is an array in case of a multi-flag.
569 # Returns:
570 # integer: one of FLAGS_{TRUE|FALSE|ERROR}
571 _flags_getFlagDefault()
572 {
573  _flags_gFD_usName_=$1
574  _flags_gFD_type_=`_flags_getFlagInfo ${_flags_gFD_usName_} ${__FLAGS_INFO_TYPE}`
575 
576  if [ ${_flags_gFD_type_} -gt 128 ]; then
577  eval "$2=(\"\${__flags_${_flags_gFD_usName_}_${__FLAGS_INFO_DEFAULT}[@]}\")"
578  else
579  eval "$2=\"\${__flags_${_flags_gFD_usName_}_${__FLAGS_INFO_DEFAULT}:-}\""
580  fi
581 
582  unset _flags_gFD_usName_ _flags_gFD_type_
583 
584  return ${FLAGS_TRUE}
585 }
586 
587 # ----------------------------------------------------------------------------
588 # helpers
589 # ----------------------------------------------------------------------------
590 
591 ##############################################################################
592 # Underscore a flag or category name by replacing dashes and whitespaces with underscores.
593 #
594 # Args:
595 # unnamed: string: long flag or category name
596 # Output:
597 # string: underscored name
598 _flags_underscoreName()
599 {
600  echo $1 | sed 's/[ -]/_/g'
601 }
602 
603 ##############################################################################
604 # Returns the width of the current screen.
605 #
606 # Output:
607 # integer: width in columns of the current screen.
608 _flags_columns()
609 {
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 :-)
614  set -- `stty size`
615  __flags_columns=$2
616  elif eval tput cols >/dev/null 2>&1; then
617  set -- `tput cols`
618  __flags_columns=$1
619  else
620  __flags_columns=80 # default terminal width
621  fi
622  fi
623  echo ${__flags_columns}
624 }
625 
626 ##############################################################################
627 # Check for presense of item in a list.
628 #
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 ').
631 #
632 # Args:
633 # _flags_str_: string: string to search for in a list of strings
634 # unnamed: list: list of strings
635 # Returns:
636 # boolean: true if item is in the list
637 _flags_itemInList()
638 {
639  _flags_str_=$1
640  shift
641 
642  echo " ${*:-} " |grep " ${_flags_str_} " >/dev/null
643  if [ $? -eq 0 ]; then
644  flags_return=${FLAGS_TRUE}
645  else
646  flags_return=${FLAGS_FALSE}
647  fi
648 
649  unset _flags_str_
650  return ${flags_return}
651 }
652 
653 ##############################################################################
654 # Sort space separated list.
655 #
656 # Args:
657 # @: list: space separated list of strings
658 # Output:
659 # list: sorted space separated list of strings
660 _flags_sortList()
661 {
662  echo "$@" | tr ' ' '\n' | sort | tr '\n' ' '
663 }
664 
665 # ----------------------------------------------------------------------------
666 # validators
667 # ----------------------------------------------------------------------------
668 
669 ##############################################################################
670 # Validate a boolean.
671 #
672 # Args:
673 # _flags__bool: boolean: value to validate
674 # Returns:
675 # bool: true if the value is a valid boolean
676 _flags_validateBoolean()
677 {
678  _flags_bool_=$1
679 
680  flags_return=${FLAGS_TRUE}
681  case "${_flags_bool_}" in
682  true|t|0) ;;
683  false|f|1) ;;
684  *) flags_return=${FLAGS_FALSE} ;;
685  esac
686 
687  unset _flags_bool_
688  return ${flags_return}
689 }
690 
691 ##############################################################################
692 # Validate a float.
693 #
694 # Args:
695 # _flags__float: float: value to validate
696 # Returns:
697 # bool: true if the value is a valid float
698 _flags_validateFloat()
699 {
700  _flags_float_=$1
701 
702  if _flags_validateInteger ${_flags_float_}; then
703  flags_return=${FLAGS_TRUE}
704  else
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]*\)'`
710  ;;
711  *) # positive floats
712  _flags_test_=`expr -- "${_flags_float_}" :\
713  '\([0-9][0-9]*\.[0-9][0-9]*\)'`
714  ;;
715  esac
716  [ "${_flags_test_}" != "${_flags_float_}" ] && flags_return=${FLAGS_FALSE}
717  fi
718 
719  unset _flags_float_ _flags_test_
720  return ${flags_return}
721 }
722 
723 ##############################################################################
724 # Validate an integer.
725 #
726 # Args:
727 # _flags__int_: interger: value to validate
728 # Returns:
729 # bool: true if the value is a valid integer
730 _flags_validateInteger()
731 {
732  _flags_int_=$1
733 
734  flags_return=${FLAGS_TRUE}
735  case ${_flags_int_} in
736  -*) # negative ints
737  _flags_test_=`expr -- "${_flags_int_}" : '\(-[0-9][0-9]*\)'`
738  ;;
739  *) # positive ints
740  _flags_test_=`expr -- "${_flags_int_}" : '\([0-9][0-9]*\)'`
741  ;;
742  esac
743  [ "${_flags_test_}" != "${_flags_int_}" ] && flags_return=${FLAGS_FALSE}
744 
745  unset _flags_int_ _flags_test_
746  return ${flags_return}
747 }
748 
749 ##############################################################################
750 # Validate an unsigned integer.
751 #
752 # Args:
753 # _flags__uint_: interger: value to validate
754 # Returns:
755 # bool: true if the value is a valid unsigned integer
756 _flags_validateUnsignedInteger()
757 {
758  _flags_uint_=$1
759 
760  flags_return=${FLAGS_TRUE}
761  _flags_test_=`expr -- "${_flags_uint_}" : '\([0-9][0-9]*\)'`
762  [ "${_flags_test_}" != "${_flags_uint_}" ] && flags_return=${FLAGS_FALSE}
763 
764  unset _flags_uint_ _flags_test_
765  return ${flags_return}
766 }
767 
768 # ----------------------------------------------------------------------------
769 # helpers for command-line parsing
770 # ----------------------------------------------------------------------------
771 
772 ##############################################################################
773 # Parse command-line options using the standard getopt.
774 #
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.
777 #
778 # Args:
779 # @: varies: command-line options to parse
780 # Returns:
781 # integer: a FLAGS success condition
782 _flags_getoptStandard()
783 {
784  flags_return=${FLAGS_TRUE}
785  _flags_shortOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}`
786 
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}
794  break
795  fi
796  done
797 
798  if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then
799  __flags_opts=`getopt ${_flags_shortOpts_} $@ 2>&1`
800  _flags_rtrn_=$?
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}
805  fi
806  fi
807 
808  unset _flags_match_ _flags_opt_ _flags_rtrn_ _flags_shortOpts_
809  return ${flags_return}
810 }
811 
812 ##############################################################################
813 # Parse command-line options using the enhanced getopt.
814 #
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.
817 #
818 # Args:
819 # @: varies: command-line options to parse
820 # Returns:
821 # integer: a FLAGS success condition
822 _flags_getoptEnhanced()
823 {
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}`
829 
830  __flags_opts=`${FLAGS_GETOPT_CMD} \
831  -o ${_flags_shortOpts_} \
832  -l "${_flags_longOpts_},${_flags_boolOpts_}" \
833  -- "$@" 2>&1`
834  _flags_rtrn_=$?
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}
839  fi
840 
841  unset _flags_boolOpts_ _flags_longOpts_ _flags_rtrn_ _flags_shortOpts_
842  return ${flags_return}
843 }
844 
845 ##############################################################################
846 # Dynamically parse a getopt result and set appropriate variables.
847 #
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.
851 #
852 # Args:
853 # argc: int: original command-line argument count
854 # @: varies: output from getopt parsing
855 # Returns:
856 # integer: a FLAGS success condition
857 _flags_parseGetopt()
858 {
859  _flags_argc_=$1
860  shift
861 
862  flags_return=${FLAGS_TRUE}
863 
864  if [ ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} ]; then
865  set -- $@
866  else
867  # note the quotes around the `$@' -- they are essential!
868  eval set -- "$@"
869  fi
870 
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_}`
877 
878  # handle options. note options with values must do an additional shift
879  while true; do
880  _flags_opt_=$1
881  _flags_arg_=${2:-}
882  _flags_name_=''
883 
884  # determine long flag name
885  case "${_flags_opt_}" in
886  --) shift; break ;; # discontinue option parsing
887 
888  --*) # long option
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_}
893  else
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}
898  fi
899  fi
900  ;;
901 
902  -*) # short option
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}' \
910  e=${_flags_opt_}`
911  _flags_name_=`echo "${__flags_longNames}" \
912  |awk 'BEGIN{RS=" "}rn==NR{print $0}' rn="${_flags_pos_}"`
913  fi
914  ;;
915  esac
916 
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}
921  break
922  fi
923 
924  # set new flag value
925  _flags_usName_=`_flags_underscoreName ${_flags_name_}`
926  _flags_type_=`_flags_getFlagInfo "${_flags_usName_}" ${__FLAGS_INFO_TYPE}`
927 
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`
934  else
935  _flags_val_=`expr "${_flags_val_}" - 1`
936  fi
937  eval "FLAGS_${_flags_usName_}=${_flags_val_}"
938  ;;
939 
940  *)
941  if [ ${_flags_type_} -ge 128 ]; then
942  eval "_flags_idx_=\${#FLAGS_${_flags_usName_}[@]}"
943  _flags_type_=`expr "${_flags_type_}" - 128`
944  else
945  _flags_idx_=0
946  fi
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}"
952  else
953  eval "FLAGS_${_flags_usName_}[${_flags_idx_}]=${FLAGS_FALSE}"
954  fi
955  else
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}"
960  else
961  eval "FLAGS_${_flags_usName_}[${_flags_idx_}]=${FLAGS_FALSE}"
962  fi
963  fi
964  ;;
965 
966  ${__FLAGS_TYPE_FLOAT})
967  if _flags_validateFloat "${_flags_arg_}"; then
968  eval "FLAGS_${_flags_usName_}[${_flags_idx_}]='${_flags_arg_}'"
969  else
970  flags_error="${_flags_name_}: invalid float value (${_flags_arg_})"
971  flags_return=${FLAGS_ERROR}
972  break
973  fi
974  ;;
975 
976  ${__FLAGS_TYPE_INTEGER})
977  if _flags_validateInteger "${_flags_arg_}"; then
978  eval "FLAGS_${_flags_usName_}[${_flags_idx_}]='${_flags_arg_}'"
979  else
980  flags_error="${_flags_name_}: invalid integer value (${_flags_arg_})"
981  flags_return=${FLAGS_ERROR}
982  break
983  fi
984  ;;
985 
986  ${__FLAGS_TYPE_STRING})
987  eval "FLAGS_${_flags_usName_}[${_flags_idx_}]='${_flags_arg_}'"
988  ;;
989  esac
990  ;;
991  esac
992 
993  # handle special case help flag
994  if [ "${_flags_usName_}" = 'help' ]; then
995  if [ ${FLAGS_help} -eq ${FLAGS_TRUE} ]; then
996  flags_help
997  flags_error='help requested'
998  flags_return=${FLAGS_TRUE}
999  break
1000  fi
1001  fi
1002 
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
1012  break
1013  fi
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}
1019  break
1020  fi
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}
1025  break
1026  fi
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}
1031  break
1032  fi
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}
1038  fi
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}
1044  fi
1045  break
1046  fi
1047  fi
1048 
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}
1055  break
1056  fi
1057  fi
1058 
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}
1065  break
1066  fi
1067  fi
1068 
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}
1075  break
1076  fi
1077  fi
1078 
1079  # shift the option and non-boolean arguments out.
1080  shift
1081  [ ${_flags_type_} != ${__FLAGS_TYPE_BOOLEAN} -a \
1082  ${_flags_type_} != ${__FLAGS_TYPE_MULTI_BOOLEAN} ] && shift
1083  done
1084 
1085  # give user back non-flag arguments
1086  FLAGS_ARGV=''
1087  while [ $# -gt 0 ]; do
1088  FLAGS_ARGV="${FLAGS_ARGV:+${FLAGS_ARGV} }'$1'"
1089  shift
1090  done
1091 
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}
1095 }
1096 
1097 # ----------------------------------------------------------------------------
1098 # helpers for help output
1099 # ----------------------------------------------------------------------------
1100 
1101 ##############################################################################
1102 # Convert type ID to type string.
1103 #
1104 # Args:
1105 # _flags_type_: integer: type ID
1106 # Outputs:
1107 # string: type string
1108 _flags_typeStr()
1109 {
1110  _flags_tS_type_=$1
1111 
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`
1115  echo -n 'multi '
1116  fi
1117 
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'; ;;
1125  esac
1126 
1127  unset _flags_tS_type_
1128 }
1129 
1130 ##############################################################################
1131 # Convert current value to string for help output.
1132 _flags_currentStr()
1133 {
1134  _flags_name__=$1
1135 
1136  # get flag info
1137  _flags_usName__=`_flags_underscoreName ${_flags_name__}`
1138  _flags_type__=`_flags_getFlagInfo "${_flags_usName__}" ${__FLAGS_INFO_TYPE}`
1139  _flags_getFlagValue "${_flags_usName__}" '_flags_current__'
1140 
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}
1147  echo -n '['
1148  else
1149  _flags_valueType__=${_flags_type__}
1150  fi
1151 
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
1158  echo -n 'true'
1159  else
1160  echo -n 'false'
1161  fi
1162  ;;
1163 
1164  ${__FLAGS_TYPE_STRING})
1165  echo -n "'${_flags_value__}'"
1166  ;;
1167 
1168  *)
1169  echo -n ${_flags_value__}
1170  ;;
1171  esac
1172  _flags_separator__=' '
1173  done
1174 
1175  if [ ${_flags_multi__} -eq ${FLAGS_TRUE} ]; then
1176  echo -n ']'
1177  fi
1178 
1179  unset _flags_name__ _flags_usName__ _flags_current__ _flags_type__ \
1180  _flags_valueType__ _flags_value__ _flags_multi__ _flags_separator__
1181 }
1182 
1183 ##############################################################################
1184 # Convert default value to string for help output.
1185 _flags_defaultStr()
1186 {
1187  _flags_dS_name_=$1
1188 
1189  # get flag info
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_'
1193 
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}
1200  echo -n '['
1201  else
1202  _flags_dS_valueType_=${_flags_dS_type_}
1203  fi
1204 
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
1211  echo -n 'true'
1212  else
1213  echo -n 'false'
1214  fi
1215  ;;
1216 
1217  ${__FLAGS_TYPE_STRING})
1218  echo -n "'${_flags_dS_value_}'"
1219  ;;
1220 
1221  *)
1222  echo -n ${_flags_dS_value_}
1223  ;;
1224  esac
1225  _flags_dS_separator_=' '
1226  done
1227 
1228  if [ ${_flags_dS_multi_} -eq ${FLAGS_TRUE} ]; then
1229  echo -n ']'
1230  fi
1231 
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_
1234 }
1235 
1236 ##############################################################################
1237 # Escape string for use in XML output.
1238 #
1239 # Args:
1240 # unnamed: string: some string
1241 # Output:
1242 # string: xml-escaped string
1243 _flags_xmlText()
1244 {
1245  echo -e "$1" | sed 's/\&/\&amp;/g;s/</\&lt;/g'
1246 }
1247 
1248 ##############################################################################
1249 # Escape string for use in man page output.
1250 #
1251 # Args:
1252 # unnamed: string: some string
1253 # Output:
1254 # string: man page-escaped string
1255 _flags_manText()
1256 {
1257  echo -e "$1" | sed 's/\\/\\\\/g;s/-/\\-/g'
1258 }
1259 
1260 ##############################################################################
1261 # Output short usage of named flag.
1262 #
1263 # Args:
1264 # _flags_name_: string: long flag name
1265 # Outputs:
1266 # string: usage of flag, e.g., "--someflag=<int>"
1267 _flags_flagusage()
1268 {
1269  _flags_name_=$1
1270 
1271  # get type of flag
1272  _flags_usName_=`_flags_underscoreName ${_flags_name_}`
1273  _flags_type_=`_flags_getFlagInfo "${_flags_usName_}" ${__FLAGS_INFO_TYPE}`
1274 
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`
1279  else
1280  _flags_multi_=${FLAGS_FALSE}
1281  fi
1282 
1283  # value type
1284  case ${_flags_type_} in
1285  ${__FLAGS_TYPE_BOOLEAN})
1286  echo -n "--[no]${_flags_name_}"
1287  ;;
1288 
1289  *)
1290  echo -n "--${_flags_name_}=<`_flags_typeStr ${_flags_type_}`>"
1291  ;;
1292  esac
1293 
1294  # append '...' if it's a multi-flag
1295  if [ ${_flags_multi_} -eq ${FLAGS_TRUE} ]; then
1296  echo -n '...'
1297  fi
1298 
1299  unset _flags_name_ _flags_usName_ _flags_type_ _flags_multi_
1300 }
1301 
1302 ##############################################################################
1303 # Output short usage of named flag in man page format.
1304 #
1305 # Args:
1306 # _flags_name_: string: long flag name
1307 # Outputs:
1308 # string: usage of flag, e.g., "--someflag=<int>"
1309 _flags_helpman_flagusage()
1310 {
1311  _flags_name_=$1
1312 
1313  # get type of flag
1314  _flags_usName_=`_flags_underscoreName ${_flags_name_}`
1315  _flags_type_=`_flags_getFlagInfo "${_flags_usName_}" ${__FLAGS_INFO_TYPE}`
1316 
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`
1321  else
1322  _flags_multi_=${FLAGS_FALSE}
1323  fi
1324 
1325  # value type
1326  case ${_flags_type_} in
1327  ${__FLAGS_TYPE_BOOLEAN})
1328  echo -n "\fB--[no]${_flags_name_}\fR"
1329  ;;
1330 
1331  *)
1332  echo -n "\fB--${_flags_name_}\fR=<\fI`_flags_typeStr ${_flags_type_}`\fR>"
1333  ;;
1334  esac
1335 
1336  # append '...' if it's a multi-flag
1337  if [ ${_flags_multi_} -eq ${FLAGS_TRUE} ]; then
1338  echo -n '...'
1339  fi
1340 
1341  unset _flags_name_ _flags_usName_ _flags_type_ _flags_multi_
1342 }
1343 
1344 # ============================================================================
1345 # public functions
1346 # ============================================================================
1347 
1348 # ----------------------------------------------------------------------------
1349 # flag definition
1350 # ----------------------------------------------------------------------------
1351 
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.
1358 #
1359 # A default value is required for boolean flags.
1360 #
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} "$@"; }
1367 
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} "$@"; }
1373 
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.
1378 #
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} "$@"; }
1383 
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} "$@"; }
1389 
1390 # ----------------------------------------------------------------------------
1391 # command-line parsing
1392 # ----------------------------------------------------------------------------
1393 
1394 ##############################################################################
1395 # Parse the flags.
1396 #
1397 # Args:
1398 # unnamed: list: command-line flags to parse
1399 # Returns:
1400 # integer: success of operation, or error
1401 FLAGS()
1402 {
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'
1424 
1425  # parse options
1426  if [ $# -gt 0 ]; then
1427  if [ ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} ]; then
1428  _flags_getoptStandard "$@"
1429  else
1430  _flags_getoptEnhanced "$@"
1431  fi
1432  flags_return=$?
1433  else
1434  # nothing passed; won't bother running getopt
1435  __flags_opts='--'
1436  flags_return=${FLAGS_TRUE}
1437  fi
1438 
1439  if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then
1440  _flags_parseGetopt $# "${__flags_opts}"
1441  flags_return=$?
1442  fi
1443 
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}
1448 }
1449 
1450 # ----------------------------------------------------------------------------
1451 # getopt information
1452 # ----------------------------------------------------------------------------
1453 
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.
1458 #
1459 # Args:
1460 # none
1461 # Output:
1462 # debug info that can be included in a bug report
1463 # Returns:
1464 # nothing
1466 {
1467  # platform info
1468  _flags_debug "uname -a: `uname -a`"
1469  _flags_debug "PATH: ${PATH}"
1470 
1471  # shell info
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}"
1478  fi
1479 
1480  # getopt info
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`"
1485 
1486  unset _flags_getoptReturn
1487 }
1488 
1489 ##############################################################################
1490 # Returns whether the detected getopt version is the enhanced version.
1491 #
1492 # Args:
1493 # none
1494 # Output:
1495 # none
1496 # Returns:
1497 # bool: true if getopt is the enhanced version
1499 {
1500  test ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH}
1501 }
1502 
1503 ##############################################################################
1504 # Returns whether the detected getopt version is the standard version.
1505 #
1506 # Args:
1507 # none
1508 # Returns:
1509 # bool: true if getopt is the standard version
1511 {
1512  test ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_STD}
1513 }
1514 
1515 # ----------------------------------------------------------------------------
1516 # help and usage information
1517 # ----------------------------------------------------------------------------
1518 
1519 ##############################################################################
1520 # Prints usage as in synopsis section of man pages.
1521 flags_usage()
1522 {
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_} "
1532  fi
1533  done
1534 
1535  flags_command_=${HELP_COMMAND:-${0##*/}} # actual command name (constant)
1536  flags_executable_="${FLAGS_PARENT:-${0##*/}}" # name of executable (may differ)
1537 
1538  flags_usage_=''
1539  if [ -n "${flags_optionalFlags_}" ]; then
1540  for flags_name_ in ${flags_optionalFlags_}; do
1541  flags_usage_="${flags_usage_} [`_flags_flagusage ${flags_name_}`]"
1542  done
1543  fi
1544  if [ -n "${flags_requiredFlags_}" ]; then
1545  for flags_name_ in ${flags_requiredFlags_}; do
1546  flags_usage_="${flags_usage_} `_flags_flagusage ${flags_name_}`"
1547  done
1548  fi
1549  flags_usage_="${flags_usage_} [args]"
1550 
1551  echo "NAME"
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_% *}..."
1562  fi
1563  echo "${flags_brief_}"
1564  else
1565  echo " ${flags_command_}"
1566  fi
1567  echo
1568  echo "SYNOPSIS"
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_}"
1577 
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_
1581 
1582  return ${FLAGS_TRUE}
1583 }
1584 
1585 ##############################################################################
1586 # Print help for named flag.
1587 #
1588 # Args:
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)
1593 # Returns:
1594 # integer: success of operation (always returns true)
1596 {
1597  flags_name_=$1
1598  flags_maxNameLen=${2:-0}
1599  flags_showDefault_=${3:-${FLAGS_TRUE}}
1600  flags_flagStr_=''
1601  flags_boolStr_=''
1602  flags_usName_=`_flags_underscoreName ${flags_name_}`
1603 
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}`
1612 
1613  flags_help_=$(echo "${flags_help_}"|sed 's/^\ *//g'|tr '\n' ' ')
1614 
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]'
1619  # long flag name
1620  flags_flagStr_="${flags_flagStr_}--${flags_boolStr_}${flags_name_}"
1621  fi
1622  # short flag 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_}"
1631  # default value
1632  flags_defaultStr_="(default: `_flags_defaultStr ${flags_name_}`)"
1633  # help text
1634  flags_helpStr_=" ${flags_flagStr_} ${flags_help_}"
1635  if [ ${flags_showDefault_} -eq ${FLAGS_TRUE} ]; then
1636  flags_helpStr_="${flags_helpStr_} ${flags_defaultStr_}"
1637  fi
1638  if [ ${flags_showDefault_} -eq ${FLAGS_TRUE} ]; then
1639  flags_helpStr_="${flags_help_} ${flags_defaultStr_}"
1640  else
1641  flags_helpStr_="${flags_help_}"
1642  fi
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_}"
1654 
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_
1658 
1659  return ${FLAGS_TRUE}
1660 }
1661 
1662 ##############################################################################
1663 # Print help of all flags.
1664 #
1665 # This function is used by flags_help() and flags_helpshort().
1666 #
1667 # Args:
1668 # flags_helpshort_: bool: display only short help of options, leaving out
1669 # less important options
1670 # Returns:
1671 # integer: success of operation (always returns true)
1673 {
1674  flags_helpshort_=${1:-${FLAGS_FALSE}}
1675 
1676  echo "OPTIONS"
1677 
1678  # reset (all) categories
1679  flags_maxNameLen_=0
1680  flags_otherFlags_=''
1681  for flags_category_ in "${__flags_categoryNames[@]}"; do
1682  flags_usCategory_=`_flags_underscoreName ${flags_category_}`
1683  eval "flags_${flags_usCategory_}Flags_=''"
1684  done
1685 
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_}`
1690 
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`
1697  fi
1698  if [ ${flags_nameStrLen_} -gt ${flags_maxNameLen_} ]; then
1699  flags_maxNameLen_=${flags_nameStrLen_}
1700  fi
1701 
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_}"
1706  else
1707  flags_usCategory_=`_flags_underscoreName ${flags_category_}`
1708  eval "flags_${flags_usCategory_}Flags_=\"\${flags_${flags_usCategory_}Flags_} ${flags_name_}\""
1709  fi
1710  done
1711 
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_"
1719  continue
1720  fi
1721  flags_categories_[${#flags_categories_[@]}]="${flags_category_}"
1722  done
1723  else
1724  flags_categories_=("${__flags_categoryNames[@]}")
1725  fi
1726 
1727  # output help of required flags
1728  if [ -n "${flags_requiredFlags_}" ]; then
1729  echo " The required options are as follows:"
1730  echo
1731  flags_requiredFlags_=`_flags_sortList "${flags_requiredFlags_}"`
1732  for flags_name_ in ${flags_requiredFlags_}; do
1733  flags_helpflag ${flags_name_} ${flags_maxNameLen_} ${FLAGS_FALSE}
1734  done
1735  echo
1736  fi
1737 
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
1742  continue
1743  fi
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:"
1749  echo
1750  for flags_name_ in ${flags_names_}; do
1751  flags_helpflag ${flags_name_} ${flags_maxNameLen_} ${FLAGS_TRUE}
1752  done
1753  echo
1754  fi
1755  done
1756 
1757  # output help of remaining non-help flags
1758  if [ -n "${flags_otherFlags_}" ]; then
1759  echo " The available options are as follows:"
1760  echo
1761  flags_otherFlags_=`_flags_sortList "${flags_otherFlags_}"`
1762  for flags_name_ in ${flags_otherFlags_}; do
1763  flags_helpflag ${flags_name_} ${flags_maxNameLen_} ${FLAGS_TRUE}
1764  done
1765  echo
1766  fi
1767 
1768  # output help of help flags
1769  if [ -n "${flags_helpFlags_}" ]; then
1770  echo " The help options are as follows:"
1771  echo
1772  for flags_name_ in ${flags_helpFlags_}; do
1773  flags_helpflag ${flags_name_} ${flags_maxNameLen_} ${FLAGS_FALSE}
1774  done
1775  echo
1776  fi
1777 
1778  # clean up
1779  for flags_category_ in "${flags_categories_[@]}"; do
1780  flags_usCategory_=`_flags_underscoreName ${flags_category_}`
1781  eval "unset flags_${flags_usCategory_}Flags_"
1782  done
1783  unset flags_maxNameLen_ flags_name_ flags_nameStrLen_ flags_type_ \
1784  flags_otherFlags flags_categories_ flags_category_ flags_usCategory_
1785 
1786  return ${FLAGS_TRUE}
1787 }
1788 
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.
1794 #
1795 # Args:
1796 # none
1797 # Returns:
1798 # integer: success of operation (always returns true)
1800 {
1801  # head / usage
1802  echo
1803  flags_usage
1804  echo
1805  # flags
1806  flags_helpflags ${FLAGS_TRUE}
1807 
1808  return ${FLAGS_TRUE}
1809 }
1810 
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.
1816 #
1817 # Args:
1818 # none
1819 # Returns:
1820 # integer: success of operation (always returns true)
1821 flags_help()
1822 {
1823  # head / usage
1824  echo
1825  flags_usage
1826  # description
1827  if [ -n "${HELP_DESCRIPTION:-}" ]; then
1828  echo
1829  echo "DESCRIPTION"
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_}"
1835  fi
1836  # flags
1837  echo
1838  flags_helpflags ${FLAGS_FALSE} # attention: unsets flags_columns_
1839  # contact
1840  if [ -n "${HELP_CONTACT:-}" ]; then
1841  echo "CONTACT"
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_}"
1847  echo
1848  fi
1849 
1850  unset flags_fmtStr_
1851 
1852  return ${FLAGS_TRUE}
1853 }
1854 
1855 # ----------------------------------------------------------------------------
1856 # XML help
1857 # ----------------------------------------------------------------------------
1858 
1859 ##############################################################################
1860 # This function outputs the help of named flag in XML format
1861 #
1862 # Args:
1863 # flags_name_: string: long name of flag
1864 # indentation: integer: (optional) indentation
1865 # Returns:
1866 # integer: success of operation (always returns true)
1868 {
1869  # get flag attributes
1870  flags_name_=$1
1871  flags_indentation_=${2:-0}
1872  flags_usName_=`_flags_underscoreName ${flags_name_}`
1873 
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}`
1882 
1883  # re-format strings
1884  flags_help_=$(echo "${flags_help_}"|sed 's/^\ *//g'|tr '\n' ' '|sed 's/^\ *//g;s/\ *$//g')
1885 
1886  [ "${flags_short_}" = "${__FLAGS_NULL}" ] && flags_short_=''
1887  [ "${flags_category_}" = "${__FLAGS_NULL}" ] && flags_category_=''
1888 
1889  # current and default value
1890  flags_current_=`_flags_currentStr ${flags_usName_}`
1891  flags_default_=`_flags_defaultStr ${flags_usName_}`
1892 
1893  # convert type
1894  flags_type_=`_flags_typeStr ${flags_type_}`
1895 
1896  # xml-escape values
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_}"`
1903 
1904  # indentation
1905  flags_emptyStr_=`printf %${flags_indentation_}s`
1906 
1907  # output XML tags
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>"
1917 
1918  unset flags_current_ flags_default_ flags_name_ flags_usName_ \
1919  flags_short_ flags_type_ flags_help_ flags_indentation_ \
1920  flags_emptyStr_
1921 }
1922 
1923 ##############################################################################
1924 # This function outputs the help in XML format.
1925 #
1926 # Args:
1927 # none
1928 # Returns:
1929 # integer: success of operation (always returns true)
1930 flags_helpxml()
1931 {
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')
1945 
1946  # xml-escape values
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_}"`
1953 
1954  # output XML tags
1955  echo "<?xml version=\"1.0\"?>"
1956  echo "<AllFlags>"
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
1964  flags_helpflagxml ${flags_name_} 2
1965  done
1966  echo "</AllFlags>"
1967 
1968  # clean up
1969  unset flags_executable_ flags_command_ flags_version_ \
1970  flags_name_ flags_description_ flags_copyright_ flags_contact_
1971 
1972  return ${FLAGS_TRUE}
1973 }
1974 
1975 # ----------------------------------------------------------------------------
1976 # man page
1977 # ----------------------------------------------------------------------------
1978 
1979 ##############################################################################
1980 # Prints NAME section of man page.
1982 {
1983  flags_command_=${HELP_COMMAND:-${0##*/}}
1984  flags_command_=`_flags_manText "${flags_command_}"`
1985 
1986  echo ".SH NAME"
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_% *}..."
1998  fi
1999  flags_brief_=`_flags_manText "${flags_brief_}"`
2000  echo "${flags_brief_}"
2001  else
2002  echo "${flags_command_}"
2003  fi
2004 
2005  unset flags_command_ flags_brief_ flags_columns_
2006 
2007  return ${FLAGS_TRUE}
2008 }
2009 
2010 ##############################################################################
2011 # Prints SYNOPSIS section of man page.
2013 {
2014  flags_executable_="${FLAGS_PARENT:-${0##*/}}"
2015 
2016  echo ".SH SYNOPSIS"
2017  echo "\fB${flags_executable_}\fR"
2018 
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_} "
2028  fi
2029  done
2030 
2031  flags_requiredFlags_=`_flags_sortList "${flags_requiredFlags_}"`
2032  flags_optionalFlags_=`_flags_sortList "${flags_optionalFlags_}"`
2033 
2034  if [ -n "${flags_optionalFlags_}" ]; then
2035  for flags_name_ in ${flags_optionalFlags_}; do
2036  echo "[\fB`_flags_helpman_flagusage ${flags_name_}`\fR]"
2037  done
2038  fi
2039  if [ -n "${flags_requiredFlags_}" ]; then
2040  for flags_name_ in ${flags_requiredFlags_}; do
2041  echo "\fB`_flags_helpman_flagusage ${flags_name_}`\fR"
2042  done
2043  fi
2044  echo "[args]"
2045 
2046  unset flags_executable_ flags_name_ flags_usName_ flags_type_ \
2047  flags_optionalFlags_ flags_requiredFlags_
2048 
2049  return ${FLAGS_TRUE}
2050 }
2051 
2052 ##############################################################################
2053 # Prints DESCRIPTION section of man page.
2055 {
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_}"
2061 
2062  unset flags_description_
2063  fi
2064 }
2065 
2066 ##############################################################################
2067 # Prints OPTIONS section entry of man page of named flag.
2069 {
2070  flags_name_=$1
2071  flags_showDefault_=${2:-${FLAGS_TRUE}}
2072  flags_flagStr_=''
2073  flags_boolStr_=''
2074  flags_usName_=`_flags_underscoreName ${flags_name_}`
2075 
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}`
2085 
2086  flags_help_=$(echo "${flags_help_}"|sed 's/^\ *//g'|tr '\n' ' ')
2087 
2088  # adjust type ID for multi-flags
2089  if [ ${flags_type_} -gt 128 ]; then
2090  flags_type_=`expr "${flags_type_}" - 128`
2091  fi
2092  # flag name
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]'
2097  # long flag name
2098  flags_flagStr_="\fB${flags_flagStr_}--${flags_boolStr_}${flags_name_}"
2099  fi
2100  [ "${flags_short_}" != "${__FLAGS_NULL}" ] && \
2101  # short flag name
2102  flags_flagStr_="${flags_flagStr_}, -${flags_short_}"
2103  flags_flagStr_="${flags_flagStr_}\fR"
2104  # argument
2105  if [ ${flags_type_} -ne ${__FLAGS_TYPE_BOOLEAN} ]; then
2106  flags_flagStr_="${flags_flagStr_} \fI`_flags_typeStr ${flags_type_}`\fR"
2107  fi
2108  # default value
2109  if [ ${flags_showDefault_} -eq ${FLAGS_TRUE} ]; then
2110  flags_defaultStr_=`_flags_defaultStr "${flags_usName_}"`
2111  flags_defaultStr_=" (default:\ ${flags_defaultStr_//\ /\\ })"
2112  else
2113  flags_defaultStr_=''
2114  fi
2115 
2116  echo ".TP 8"
2117  echo "${flags_flagStr_}"
2118  echo "${flags_help_}${flags_defaultStr_}"
2119 
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_
2123 
2124  return ${FLAGS_TRUE}
2125 }
2126 
2127 ##############################################################################
2128 # Prints OPTIONS section of man page.
2130 {
2131  echo ".SH OPTIONS"
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_=''"
2137  done
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_}"
2144  else
2145  flags_usCategory_=`_flags_underscoreName ${flags_category_}`
2146  eval "flags_${flags_usCategory_}Flags_=\"\${flags_${flags_usCategory_}Flags_} ${flags_name_}\""
2147  fi
2148  done
2149  # output help of required flags
2150  if [ -n "${flags_requiredFlags_}" ]; then
2151  echo ".P"
2152  echo "\fBThe required options are as follows:\fR"
2153  flags_requiredFlags_=`_flags_sortList "${flags_requiredFlags_}"`
2154  for flags_name_ in ${flags_requiredFlags_}; do
2155  flags_helpman_flag ${flags_name_} ${FLAGS_FALSE}
2156  done
2157  fi
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
2162  continue
2163  fi
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
2168  echo ".P"
2169  echo "\fBThe ${flags_category_} options are as follows:\fR"
2170  for flags_name_ in ${flags_names_}; do
2171  flags_helpman_flag ${flags_name_}
2172  done
2173  fi
2174  done
2175  # output help of remaining non-help flags
2176  if [ -n "${flags_otherFlags_}" ]; then
2177  echo ".P"
2178  echo "\fBThe available options are as follows:\fR"
2179  flags_otherFlags_=`_flags_sortList "${flags_otherFlags_}"`
2180  for flags_name_ in ${flags_otherFlags_}; do
2181  flags_helpman_flag ${flags_name_}
2182  done
2183  fi
2184  # output help of help flags
2185  if [ -n "${flags_helpFlags_}" ]; then
2186  echo ".P"
2187  echo "\fBThe help options are as follows:\fR"
2188  for flags_name_ in ${flags_helpFlags_}; do
2189  flags_helpman_flag ${flags_name_} ${FLAGS_FALSE}
2190  done
2191  fi
2192 
2193  # clean up
2194  for flags_category_ in "${__flags_categoryNames[@]}"; do
2195  flags_usCategory_=`_flags_underscoreName ${flags_category_}`
2196  eval "unset flags_${flags_usCategory_}Flags_"
2197  done
2198  unset flags_maxNameLen_ flags_name_ flags_nameStrLen_ flags_type_ \
2199  flags_otherFlags flags_category_ flags_usCategory_
2200 }
2201 
2202 ##############################################################################
2203 # Prints COPYRIGHT section of man page.
2205 {
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_}"
2212 
2213  unset flags_copyright_
2214  fi
2215 }
2216 
2217 ##############################################################################
2218 # Prints CONTACT section of man page.
2220 {
2221  if [ -n "${HELP_CONTACT}" ]; then
2222  echo ".SH CONTACT"
2223  flags_contact_="${HELP_CONTACT}"
2224  flags_contact_=`_flags_manText "${flags_contact_}"`
2225  echo "${flags_contact_}"
2226 
2227  unset flags_contact_
2228  fi
2229 }
2230 
2231 ##############################################################################
2232 # This function outputs the help in man page format.
2233 #
2234 # Args:
2235 # none
2236 # Returns:
2237 # integer: success of operation (always returns true)
2238 flags_helpman()
2239 {
2240  flags_command_=${FLAGS_PARENT:-${0##*/}}
2241  flags_command_=`_flags_manText "${flags_command_}"`
2242 
2243  echo ".TH \"${flags_command_}\" 1 `date '+%e\ %B\ %G'`"
2250 
2251  unset flags_command_
2252 
2253  return ${FLAGS_TRUE}
2254 }
2255 
2256 # ----------------------------------------------------------------------------
2257 # version information
2258 # ----------------------------------------------------------------------------
2259 
2260 ##############################################################################
2261 # This function outputs the version and copyright.
2262 #
2263 # Args:
2264 # none
2265 # Returns:
2266 # integer: success of operation (always returns true)
2267 flags_version()
2268 {
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_}"
2277  fi
2278  unset flags_command_ flags_version_ flags_copyright_
2279 }
2280 
2281 # ----------------------------------------------------------------------------
2282 # reset
2283 # ----------------------------------------------------------------------------
2284 
2285 ##############################################################################
2286 # Reset shflags back to an uninitialized state.
2287 #
2288 # Args:
2289 # none
2290 # Returns:
2291 # nothing
2292 flags_reset()
2293 {
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}
2303  do
2304  flags_strToEval_=\
2305 "${flags_strToEval_} __flags_${flags_usName_}_${flags_type_}"
2306  done
2307  eval ${flags_strToEval_}
2308  done
2309 
2310  # reset internal variables
2311  __flags_boolNames=' '
2312  __flags_longNames=' '
2313  __flags_shortNames=' '
2314  __flags_definedNames=' '
2315  __flags_categoryNames=' '
2316 
2317  unset flags_name_ flags_type_ flags_strToEval_ flags_usName_
2318 }
function flags_help()
function is(in result, in expected, in name)
Test whether a given result is equal to the expected result.
function flags_getoptInfo()
function flags_reset()
function flags_helpman_copyright()
cmake NAME
function FLAGS()
function flags_helpman_name()
bool exists(const std::string path)
Test the existance of a file or directory.
Definition: path.cxx:476
function flags_getoptIsStd()
function flags_helpxml()
function flags_getoptIsEnh()
function flags_usage()
function flags_helpshort()
function flags_helpman_flags()
function flags_helpflags()
function flags_helpflag()
function flags_helpman()
function flags_version()
function flags_helpflagxml()
function flags_helpman_description()
function flags_helpman_synopsis()
if(oldcoutbuf)
function flags_helpman_flag()
function flags_helpman_contact()