HeSYINUvSBZfxqA-capistrano 2.5.23 → 2.5.24

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,78 @@
1
+ #!/bin/bash
2
+
3
+ : ${__meat__:=x}
4
+ if [[ "$__meat__" != 'x' ]]; then
5
+ return 0
6
+ fi
7
+ __meat__='y'
8
+
9
+ function check_help {
10
+ # taken from shocco
11
+ if expr -- "$*" : ".*--help" >/dev/null; then
12
+ display_help
13
+ exit 0
14
+ fi
15
+ }
16
+
17
+ function display_help {
18
+ # taken from shocco
19
+ grep '^#/' <"$shome/bin/$(basename -- "$0")" | cut -c4-
20
+ }
21
+
22
+ function which_library {
23
+ local library="$1"; shift
24
+ echo "$shome/bin/_$library"
25
+ }
26
+
27
+ function require {
28
+ source "$(which_library "$@")"
29
+ }
30
+
31
+ function parse_command_line {
32
+ if ! FLAGS "$@"; then
33
+ if [[ "$flags_error" = "help requested" ]]; then
34
+ echo ""
35
+ display_help
36
+ exit 0
37
+ fi
38
+
39
+ return 4
40
+ fi
41
+ return 0
42
+ }
43
+
44
+ function configure_logging {
45
+ # load log4sh (disabling properties file warning) and clear the default
46
+ # configuration
47
+ LOG4SH_CONFIGURATION='none' require 'log4sh'
48
+ log4sh_resetConfiguration
49
+
50
+ # set the global logging level to INFO
51
+ logger_setLevel INFO
52
+
53
+ # add and configure a FileAppender that outputs to STDERR, and activate the
54
+ # configuration
55
+ logger_addAppender stderr
56
+ appender_setType stderr FileAppender
57
+ appender_file_setFile stderr STDERR
58
+ appender_activateOptions stderr
59
+ }
60
+
61
+ function _main {
62
+ if [[ "$0" = "-bash" ]]; then
63
+ echo 'ERROR: cannot source library without setting $shome'
64
+ exit 1
65
+ fi
66
+
67
+ if [[ -z "$shome" ]]; then
68
+ shome="$(cd -P -- "$(dirname -- "$0")/.." && pwd -P)"
69
+ fi
70
+
71
+ require 'shflags'
72
+
73
+ configure_logging
74
+
75
+ PATH="$shome/bin:$PATH"
76
+ }
77
+
78
+ _main "$@"
@@ -0,0 +1,13 @@
1
+ #!/bin/bash
2
+
3
+ if [[ "$0" = "-bash" ]]; then
4
+ echo 'ERROR: cannot source binwithout setting $shome'
5
+ exit 1
6
+ fi
7
+
8
+ if [[ -z "$shome" ]]; then
9
+ shome="$(cd -P -- "$(dirname -- "$0")/.." && pwd -P)"
10
+ fi
11
+
12
+ source "$shome/bin/_meat" "$@"
13
+ set -fue
@@ -0,0 +1,1009 @@
1
+ # $Id$
2
+ # vim:et:ft=sh:sts=2:sw=2
3
+ #
4
+ # Copyright 2008 Kate Ward. All Rights Reserved.
5
+ # Released under the LGPL (GNU Lesser General Public License)
6
+ #
7
+ # shFlags -- Advanced command-line flag library for Unix shell scripts.
8
+ # http://code.google.com/p/shflags/
9
+ #
10
+ # Author: kate.ward@forestent.com (Kate Ward)
11
+ #
12
+ # This module implements something like the google-gflags library available
13
+ # from http://code.google.com/p/google-gflags/.
14
+ #
15
+ # FLAG TYPES: This is a list of the DEFINE_*'s that you can do. All flags take
16
+ # a name, default value, help-string, and optional 'short' name (one-letter
17
+ # name). Some flags have other arguments, which are described with the flag.
18
+ #
19
+ # DEFINE_string: takes any input, and intreprets it as a string.
20
+ #
21
+ # DEFINE_boolean: typically does not take any argument: say --myflag to set
22
+ # FLAGS_myflag to true, or --nomyflag to set FLAGS_myflag to false.
23
+ # Alternately, you can say
24
+ # --myflag=true or --myflag=t or --myflag=0 or
25
+ # --myflag=false or --myflag=f or --myflag=1
26
+ # Passing an option has the same affect as passing the option once.
27
+ #
28
+ # DEFINE_float: takes an input and intreprets it as a floating point number. As
29
+ # shell does not support floats per-se, the input is merely validated as
30
+ # being a valid floating point value.
31
+ #
32
+ # DEFINE_integer: takes an input and intreprets it as an integer.
33
+ #
34
+ # SPECIAL FLAGS: There are a few flags that have special meaning:
35
+ # --help (or -?) prints a list of all the flags in a human-readable fashion
36
+ # --flagfile=foo read flags from foo. (not implemented yet)
37
+ # -- as in getopt(), terminates flag-processing
38
+ #
39
+ # EXAMPLE USAGE:
40
+ #
41
+ # -- begin hello.sh --
42
+ # #! /bin/sh
43
+ # . ./shflags
44
+ # DEFINE_string name 'world' "somebody's name" n
45
+ # FLAGS "$@" || exit $?
46
+ # eval set -- "${FLAGS_ARGV}"
47
+ # echo "Hello, ${FLAGS_name}."
48
+ # -- end hello.sh --
49
+ #
50
+ # $ ./hello.sh -n Kate
51
+ # Hello, Kate.
52
+ #
53
+ # NOTE: Not all systems include a getopt version that supports long flags. On
54
+ # these systems, only short flags are recognized.
55
+
56
+ #==============================================================================
57
+ # shFlags
58
+ #
59
+ # Shared attributes:
60
+ # flags_error: last error message
61
+ # flags_return: last return value
62
+ #
63
+ # __flags_longNames: list of long names for all flags
64
+ # __flags_shortNames: list of short names for all flags
65
+ # __flags_boolNames: list of boolean flag names
66
+ #
67
+ # __flags_opts: options parsed by getopt
68
+ #
69
+ # Per-flag attributes:
70
+ # FLAGS_<flag_name>: contains value of flag named 'flag_name'
71
+ # __flags_<flag_name>_default: the default flag value
72
+ # __flags_<flag_name>_help: the flag help string
73
+ # __flags_<flag_name>_short: the flag short name
74
+ # __flags_<flag_name>_type: the flag type
75
+ #
76
+ # Notes:
77
+ # - lists of strings are space separated, and a null value is the '~' char.
78
+
79
+ # return if FLAGS already loaded
80
+ [ -n "${FLAGS_VERSION:-}" ] && return 0
81
+ FLAGS_VERSION='1.0.3'
82
+
83
+ # return values
84
+ FLAGS_TRUE=0
85
+ FLAGS_FALSE=1
86
+ FLAGS_ERROR=2
87
+
88
+ # reserved flag names
89
+ FLAGS_RESERVED='ARGC ARGV ERROR FALSE HELP PARENT RESERVED TRUE VERSION'
90
+
91
+ _flags_debug() { echo "flags:DEBUG $@" >&2; }
92
+ _flags_warn() { echo "flags:WARN $@" >&2; }
93
+ _flags_error() { echo "flags:ERROR $@" >&2; }
94
+ _flags_fatal() { echo "flags:FATAL $@" >&2; }
95
+
96
+ # specific shell checks
97
+ if [ -n "${ZSH_VERSION:-}" ]; then
98
+ setopt |grep "^shwordsplit$" >/dev/null
99
+ if [ $? -ne ${FLAGS_TRUE} ]; then
100
+ _flags_fatal 'zsh shwordsplit option is required for proper zsh operation'
101
+ exit ${FLAGS_ERROR}
102
+ fi
103
+ if [ -z "${FLAGS_PARENT:-}" ]; then
104
+ _flags_fatal "zsh does not pass \$0 through properly. please declare' \
105
+ \"FLAGS_PARENT=\$0\" before calling shFlags"
106
+ exit ${FLAGS_ERROR}
107
+ fi
108
+ fi
109
+
110
+ #
111
+ # constants
112
+ #
113
+
114
+ # getopt version
115
+ __FLAGS_GETOPT_VERS_STD=0
116
+ __FLAGS_GETOPT_VERS_ENH=1
117
+ __FLAGS_GETOPT_VERS_BSD=2
118
+
119
+ getopt >/dev/null 2>&1
120
+ case $? in
121
+ 0) __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_STD} ;; # bsd getopt
122
+ 2)
123
+ # TODO(kward): look into '-T' option to test the internal getopt() version
124
+ if [ "`getopt --version`" = '-- ' ]; then
125
+ __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_STD}
126
+ else
127
+ __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_ENH}
128
+ fi
129
+ ;;
130
+ *)
131
+ _flags_fatal 'unable to determine getopt version'
132
+ exit ${FLAGS_ERROR}
133
+ ;;
134
+ esac
135
+
136
+ # getopt optstring lengths
137
+ __FLAGS_OPTSTR_SHORT=0
138
+ __FLAGS_OPTSTR_LONG=1
139
+
140
+ __FLAGS_NULL='~'
141
+
142
+ # flag info strings
143
+ __FLAGS_INFO_DEFAULT='default'
144
+ __FLAGS_INFO_HELP='help'
145
+ __FLAGS_INFO_SHORT='short'
146
+ __FLAGS_INFO_TYPE='type'
147
+
148
+ # flag lengths
149
+ __FLAGS_LEN_SHORT=0
150
+ __FLAGS_LEN_LONG=1
151
+
152
+ # flag types
153
+ __FLAGS_TYPE_NONE=0
154
+ __FLAGS_TYPE_BOOLEAN=1
155
+ __FLAGS_TYPE_FLOAT=2
156
+ __FLAGS_TYPE_INTEGER=3
157
+ __FLAGS_TYPE_STRING=4
158
+
159
+ # set the constants readonly
160
+ __flags_constants=`set |awk -F= '/^FLAGS_/ || /^__FLAGS_/ {print $1}'`
161
+ for __flags_const in ${__flags_constants}; do
162
+ # skip certain flags
163
+ case ${__flags_const} in
164
+ FLAGS_HELP) continue ;;
165
+ FLAGS_PARENT) continue ;;
166
+ esac
167
+ # set flag readonly
168
+ if [ -z "${ZSH_VERSION:-}" ]; then
169
+ readonly ${__flags_const}
170
+ else # handle zsh
171
+ case ${ZSH_VERSION} in
172
+ [123].*) readonly ${__flags_const} ;;
173
+ *) readonly -g ${__flags_const} ;; # declare readonly constants globally
174
+ esac
175
+ fi
176
+ done
177
+ unset __flags_const __flags_constants
178
+
179
+ #
180
+ # internal variables
181
+ #
182
+
183
+ __flags_boolNames=' ' # space separated list of boolean flag names
184
+ __flags_longNames=' ' # space separated list of long flag names
185
+ __flags_shortNames=' ' # space separated list of short flag names
186
+
187
+ __flags_columns='' # screen width in columns
188
+ __flags_opts='' # temporary storage for parsed getopt flags
189
+
190
+ #------------------------------------------------------------------------------
191
+ # private functions
192
+ #
193
+
194
+ # Define a flag.
195
+ #
196
+ # Calling this function will define the following info variables for the
197
+ # specified flag:
198
+ # FLAGS_flagname - the name for this flag (based upon the long flag name)
199
+ # __flags_<flag_name>_default - the default value
200
+ # __flags_flagname_help - the help string
201
+ # __flags_flagname_short - the single letter alias
202
+ # __flags_flagname_type - the type of flag (one of __FLAGS_TYPE_*)
203
+ #
204
+ # Args:
205
+ # _flags__type: integer: internal type of flag (__FLAGS_TYPE_*)
206
+ # _flags__name: string: long flag name
207
+ # _flags__default: default flag value
208
+ # _flags__help: string: help string
209
+ # _flags__short: string: (optional) short flag name
210
+ # Returns:
211
+ # integer: success of operation, or error
212
+ _flags_define()
213
+ {
214
+ if [ $# -lt 4 ]; then
215
+ flags_error='DEFINE error: too few arguments'
216
+ flags_return=${FLAGS_ERROR}
217
+ _flags_error "${flags_error}"
218
+ return ${flags_return}
219
+ fi
220
+
221
+ _flags_type_=$1
222
+ _flags_name_=$2
223
+ _flags_default_=$3
224
+ _flags_help_=$4
225
+ _flags_short_=${5:-${__FLAGS_NULL}}
226
+
227
+ _flags_return_=${FLAGS_TRUE}
228
+
229
+ # TODO(kward): check for validity of the flag name (e.g. dashes)
230
+
231
+ # check whether the flag name is reserved
232
+ echo " ${FLAGS_RESERVED} " |grep " ${_flags_name_} " >/dev/null
233
+ if [ $? -eq 0 ]; then
234
+ flags_error="flag name (${_flags_name_}) is reserved"
235
+ _flags_return_=${FLAGS_ERROR}
236
+ fi
237
+
238
+ # require short option for getopt that don't support long options
239
+ if [ ${_flags_return_} -eq ${FLAGS_TRUE} \
240
+ -a ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} \
241
+ -a "${_flags_short_}" = "${__FLAGS_NULL}" ]
242
+ then
243
+ flags_error="short flag required for (${_flags_name_}) on this platform"
244
+ _flags_return_=${FLAGS_ERROR}
245
+ fi
246
+
247
+ # check for existing long name definition
248
+ if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then
249
+ if _flags_itemInList "${_flags_name_}" \
250
+ ${__flags_longNames} ${__flags_boolNames}
251
+ then
252
+ flags_error="flag name ([no]${_flags_name_}) already defined"
253
+ _flags_warn "${flags_error}"
254
+ _flags_return_=${FLAGS_FALSE}
255
+ fi
256
+ fi
257
+
258
+ # check for existing short name definition
259
+ if [ ${_flags_return_} -eq ${FLAGS_TRUE} \
260
+ -a "${_flags_short_}" != "${__FLAGS_NULL}" ]
261
+ then
262
+ if _flags_itemInList "${_flags_short_}" ${__flags_shortNames}; then
263
+ flags_error="flag short name (${_flags_short_}) already defined"
264
+ _flags_warn "${flags_error}"
265
+ _flags_return_=${FLAGS_FALSE}
266
+ fi
267
+ fi
268
+
269
+ # handle default value. note, on several occasions the 'if' portion of an
270
+ # if/then/else contains just a ':' which does nothing. a binary reversal via
271
+ # '!' is not done because it does not work on all shells.
272
+ if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then
273
+ case ${_flags_type_} in
274
+ ${__FLAGS_TYPE_BOOLEAN})
275
+ if _flags_validateBoolean "${_flags_default_}"; then
276
+ case ${_flags_default_} in
277
+ true|t|0) _flags_default_=${FLAGS_TRUE} ;;
278
+ false|f|1) _flags_default_=${FLAGS_FALSE} ;;
279
+ esac
280
+ else
281
+ flags_error="invalid default flag value '${_flags_default_}'"
282
+ _flags_return_=${FLAGS_ERROR}
283
+ fi
284
+ ;;
285
+
286
+ ${__FLAGS_TYPE_FLOAT})
287
+ if _flags_validateFloat "${_flags_default_}"; then
288
+ :
289
+ else
290
+ flags_error="invalid default flag value '${_flags_default_}'"
291
+ _flags_return_=${FLAGS_ERROR}
292
+ fi
293
+ ;;
294
+
295
+ ${__FLAGS_TYPE_INTEGER})
296
+ if _flags_validateInteger "${_flags_default_}"; then
297
+ :
298
+ else
299
+ flags_error="invalid default flag value '${_flags_default_}'"
300
+ _flags_return_=${FLAGS_ERROR}
301
+ fi
302
+ ;;
303
+
304
+ ${__FLAGS_TYPE_STRING}) ;; # everything in shell is a valid string
305
+
306
+ *)
307
+ flags_error="unrecognized flag type '${_flags_type_}'"
308
+ _flags_return_=${FLAGS_ERROR}
309
+ ;;
310
+ esac
311
+ fi
312
+
313
+ if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then
314
+ # store flag information
315
+ eval "FLAGS_${_flags_name_}='${_flags_default_}'"
316
+ eval "__flags_${_flags_name_}_${__FLAGS_INFO_TYPE}=${_flags_type_}"
317
+ eval "__flags_${_flags_name_}_${__FLAGS_INFO_DEFAULT}=\
318
+ \"${_flags_default_}\""
319
+ eval "__flags_${_flags_name_}_${__FLAGS_INFO_HELP}=\"${_flags_help_}\""
320
+ eval "__flags_${_flags_name_}_${__FLAGS_INFO_SHORT}='${_flags_short_}'"
321
+
322
+ # append flag name(s) to list of names
323
+ __flags_longNames="${__flags_longNames}${_flags_name_} "
324
+ __flags_shortNames="${__flags_shortNames}${_flags_short_} "
325
+ [ ${_flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} ] && \
326
+ __flags_boolNames="${__flags_boolNames}no${_flags_name_} "
327
+ fi
328
+
329
+ flags_return=${_flags_return_}
330
+ unset _flags_default_ _flags_help_ _flags_name_ _flags_return_ _flags_short_ \
331
+ _flags_type_
332
+ [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_error "${flags_error}"
333
+ return ${flags_return}
334
+ }
335
+
336
+ # Return valid getopt options using currently defined list of long options.
337
+ #
338
+ # This function builds a proper getopt option string for short (and long)
339
+ # options, using the current list of long options for reference.
340
+ #
341
+ # Args:
342
+ # _flags_optStr: integer: option string type (__FLAGS_OPTSTR_*)
343
+ # Output:
344
+ # string: generated option string for getopt
345
+ # Returns:
346
+ # boolean: success of operation (always returns True)
347
+ _flags_genOptStr()
348
+ {
349
+ _flags_optStrType_=$1
350
+
351
+ _flags_opts_=''
352
+
353
+ for _flags_flag_ in ${__flags_longNames}; do
354
+ _flags_type_=`_flags_getFlagInfo ${_flags_flag_} ${__FLAGS_INFO_TYPE}`
355
+ case ${_flags_optStrType_} in
356
+ ${__FLAGS_OPTSTR_SHORT})
357
+ _flags_shortName_=`_flags_getFlagInfo \
358
+ ${_flags_flag_} ${__FLAGS_INFO_SHORT}`
359
+ if [ "${_flags_shortName_}" != "${__FLAGS_NULL}" ]; then
360
+ _flags_opts_="${_flags_opts_}${_flags_shortName_}"
361
+ # getopt needs a trailing ':' to indicate a required argument
362
+ [ ${_flags_type_} -ne ${__FLAGS_TYPE_BOOLEAN} ] && \
363
+ _flags_opts_="${_flags_opts_}:"
364
+ fi
365
+ ;;
366
+
367
+ ${__FLAGS_OPTSTR_LONG})
368
+ _flags_opts_="${_flags_opts_:+${_flags_opts_},}${_flags_flag_}"
369
+ # getopt needs a trailing ':' to indicate a required argument
370
+ [ ${_flags_type_} -ne ${__FLAGS_TYPE_BOOLEAN} ] && \
371
+ _flags_opts_="${_flags_opts_}:"
372
+ ;;
373
+ esac
374
+ done
375
+
376
+ echo "${_flags_opts_}"
377
+ unset _flags_flag_ _flags_opts_ _flags_optStrType_ _flags_shortName_ \
378
+ _flags_type_
379
+ return ${FLAGS_TRUE}
380
+ }
381
+
382
+ # Returns flag details based on a flag name and flag info.
383
+ #
384
+ # Args:
385
+ # string: long flag name
386
+ # string: flag info (see the _flags_define function for valid info types)
387
+ # Output:
388
+ # string: value of dereferenced flag variable
389
+ # Returns:
390
+ # integer: one of FLAGS_{TRUE|FALSE|ERROR}
391
+ _flags_getFlagInfo()
392
+ {
393
+ _flags_name_=$1
394
+ _flags_info_=$2
395
+
396
+ _flags_nameVar_="__flags_${_flags_name_}_${_flags_info_}"
397
+ _flags_strToEval_="_flags_value_=\"\${${_flags_nameVar_}:-}\""
398
+ eval "${_flags_strToEval_}"
399
+ if [ -n "${_flags_value_}" ]; then
400
+ flags_return=${FLAGS_TRUE}
401
+ else
402
+ # see if the _flags_name_ variable is a string as strings can be empty...
403
+ # note: the DRY principle would say to have this function call itself for
404
+ # the next three lines, but doing so results in an infinite loop as an
405
+ # invalid _flags_name_ will also not have the associated _type variable.
406
+ # Because it doesn't (it will evaluate to an empty string) the logic will
407
+ # try to find the _type variable of the _type variable, and so on. Not so
408
+ # good ;-)
409
+ _flags_typeVar_="__flags_${_flags_name_}_${__FLAGS_INFO_TYPE}"
410
+ _flags_strToEval_="_flags_type_=\"\${${_flags_typeVar_}:-}\""
411
+ eval "${_flags_strToEval_}"
412
+ if [ "${_flags_type_}" = "${__FLAGS_TYPE_STRING}" ]; then
413
+ flags_return=${FLAGS_TRUE}
414
+ else
415
+ flags_return=${FLAGS_ERROR}
416
+ flags_error="invalid flag name (${_flags_nameVar_})"
417
+ fi
418
+ fi
419
+
420
+ echo "${_flags_value_}"
421
+ unset _flags_info_ _flags_name_ _flags_strToEval_ _flags_type_ _flags_value_ \
422
+ _flags_nameVar_ _flags_typeVar_
423
+ [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_error "${flags_error}"
424
+ return ${flags_return}
425
+ }
426
+
427
+ # check for presense of item in a list. passed a string (e.g. 'abc'), this
428
+ # function will determine if the string is present in the list of strings (e.g.
429
+ # ' foo bar abc ').
430
+ #
431
+ # Args:
432
+ # _flags__str: string: string to search for in a list of strings
433
+ # unnamed: list: list of strings
434
+ # Returns:
435
+ # boolean: true if item is in the list
436
+ _flags_itemInList()
437
+ {
438
+ _flags_str_=$1
439
+ shift
440
+
441
+ echo " ${*:-} " |grep " ${_flags_str_} " >/dev/null
442
+ if [ $? -eq 0 ]; then
443
+ flags_return=${FLAGS_TRUE}
444
+ else
445
+ flags_return=${FLAGS_FALSE}
446
+ fi
447
+
448
+ unset _flags_str_
449
+ return ${flags_return}
450
+ }
451
+
452
+ # Returns the width of the current screen.
453
+ #
454
+ # Output:
455
+ # integer: width in columns of the current screen.
456
+ _flags_columns()
457
+ {
458
+ if [ -z "${__flags_columns}" ]; then
459
+ # determine the value and store it
460
+ if eval stty size >/dev/null 2>&1; then
461
+ # stty size worked :-)
462
+ set -- `stty size`
463
+ __flags_columns=$2
464
+ elif eval tput cols >/dev/null 2>&1; then
465
+ set -- `tput cols`
466
+ __flags_columns=$1
467
+ else
468
+ __flags_columns=80 # default terminal width
469
+ fi
470
+ fi
471
+ echo ${__flags_columns}
472
+ }
473
+
474
+ # Validate a boolean.
475
+ #
476
+ # Args:
477
+ # _flags__bool: boolean: value to validate
478
+ # Returns:
479
+ # bool: true if the value is a valid boolean
480
+ _flags_validateBoolean()
481
+ {
482
+ _flags_bool_=$1
483
+
484
+ flags_return=${FLAGS_TRUE}
485
+ case "${_flags_bool_}" in
486
+ true|t|0) ;;
487
+ false|f|1) ;;
488
+ *) flags_return=${FLAGS_FALSE} ;;
489
+ esac
490
+
491
+ unset _flags_bool_
492
+ return ${flags_return}
493
+ }
494
+
495
+ # Validate a float.
496
+ #
497
+ # Args:
498
+ # _flags__float: float: value to validate
499
+ # Returns:
500
+ # bool: true if the value is a valid float
501
+ _flags_validateFloat()
502
+ {
503
+ _flags_float_=$1
504
+
505
+ if _flags_validateInteger ${_flags_float_}; then
506
+ flags_return=${FLAGS_TRUE}
507
+ else
508
+ flags_return=${FLAGS_TRUE}
509
+ case ${_flags_float_} in
510
+ -*) # negative floats
511
+ _flags_test_=`expr "${_flags_float_}" : '\(-[0-9][0-9]*\.[0-9][0-9]*\)'`
512
+ ;;
513
+ *) # positive floats
514
+ _flags_test_=`expr "${_flags_float_}" : '\([0-9][0-9]*\.[0-9][0-9]*\)'`
515
+ ;;
516
+ esac
517
+ [ "${_flags_test_}" != "${_flags_float_}" ] && flags_return=${FLAGS_FALSE}
518
+ fi
519
+
520
+ unset _flags_float_ _flags_test_
521
+ return ${flags_return}
522
+ }
523
+
524
+ # Validate an integer.
525
+ #
526
+ # Args:
527
+ # _flags__integer: interger: value to validate
528
+ # Returns:
529
+ # bool: true if the value is a valid integer
530
+ _flags_validateInteger()
531
+ {
532
+ _flags_int_=$1
533
+
534
+ flags_return=${FLAGS_TRUE}
535
+ case ${_flags_int_} in
536
+ -*) # negative ints
537
+ _flags_test_=`expr "${_flags_int_}" : '\(-[0-9][0-9]*\)'`
538
+ ;;
539
+ *) # positive ints
540
+ _flags_test_=`expr "${_flags_int_}" : '\([0-9][0-9]*\)'`
541
+ ;;
542
+ esac
543
+ [ "${_flags_test_}" != "${_flags_int_}" ] && flags_return=${FLAGS_FALSE}
544
+
545
+ unset _flags_int_ _flags_test_
546
+ return ${flags_return}
547
+ }
548
+
549
+ # Parse command-line options using the standard getopt.
550
+ #
551
+ # Note: the flag options are passed around in the global __flags_opts so that
552
+ # the formatting is not lost due to shell parsing and such.
553
+ #
554
+ # Args:
555
+ # @: varies: command-line options to parse
556
+ # Returns:
557
+ # integer: a FLAGS success condition
558
+ _flags_getoptStandard()
559
+ {
560
+ flags_return=${FLAGS_TRUE}
561
+ _flags_shortOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}`
562
+
563
+ # check for spaces in passed options
564
+ for _flags_opt_ in "$@"; do
565
+ # note: the silliness with the x's is purely for ksh93 on Ubuntu 6.06
566
+ _flags_match_=`echo "x${_flags_opt_}x" |sed 's/ //g'`
567
+ if [ "${_flags_match_}" != "x${_flags_opt_}x" ]; then
568
+ flags_error='the available getopt does not support spaces in options'
569
+ flags_return=${FLAGS_ERROR}
570
+ break
571
+ fi
572
+ done
573
+
574
+ if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then
575
+ __flags_opts=`getopt ${_flags_shortOpts_} $@ 2>&1`
576
+ _flags_rtrn_=$?
577
+ if [ ${_flags_rtrn_} -ne ${FLAGS_TRUE} ]; then
578
+ _flags_warn "${__flags_opts}"
579
+ flags_error='unable to parse provided options with getopt.'
580
+ flags_return=${FLAGS_ERROR}
581
+ fi
582
+ fi
583
+
584
+ unset _flags_match_ _flags_opt_ _flags_rtrn_ _flags_shortOpts_
585
+ return ${flags_return}
586
+ }
587
+
588
+ # Parse command-line options using the enhanced getopt.
589
+ #
590
+ # Note: the flag options are passed around in the global __flags_opts so that
591
+ # the formatting is not lost due to shell parsing and such.
592
+ #
593
+ # Args:
594
+ # @: varies: command-line options to parse
595
+ # Returns:
596
+ # integer: a FLAGS success condition
597
+ _flags_getoptEnhanced()
598
+ {
599
+ flags_return=${FLAGS_TRUE}
600
+ _flags_shortOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}`
601
+ _flags_boolOpts_=`echo "${__flags_boolNames}" \
602
+ |sed 's/^ *//;s/ *$//;s/ /,/g'`
603
+ _flags_longOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_LONG}`
604
+
605
+ __flags_opts=`getopt \
606
+ -o ${_flags_shortOpts_} \
607
+ -l "${_flags_longOpts_},${_flags_boolOpts_}" \
608
+ -- "$@" 2>&1`
609
+ _flags_rtrn_=$?
610
+ if [ ${_flags_rtrn_} -ne ${FLAGS_TRUE} ]; then
611
+ _flags_warn "${__flags_opts}"
612
+ flags_error='unable to parse provided options with getopt.'
613
+ flags_return=${FLAGS_ERROR}
614
+ fi
615
+
616
+ unset _flags_boolOpts_ _flags_longOpts_ _flags_rtrn_ _flags_shortOpts_
617
+ return ${flags_return}
618
+ }
619
+
620
+ # Dynamically parse a getopt result and set appropriate variables.
621
+ #
622
+ # This function does the actual conversion of getopt output and runs it through
623
+ # the standard case structure for parsing. The case structure is actually quite
624
+ # dynamic to support any number of flags.
625
+ #
626
+ # Args:
627
+ # argc: int: original command-line argument count
628
+ # @: varies: output from getopt parsing
629
+ # Returns:
630
+ # integer: a FLAGS success condition
631
+ _flags_parseGetopt()
632
+ {
633
+ _flags_argc_=$1
634
+ shift
635
+
636
+ flags_return=${FLAGS_TRUE}
637
+
638
+ if [ ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} ]; then
639
+ set -- $@
640
+ else
641
+ # note the quotes around the `$@' -- they are essential!
642
+ eval set -- "$@"
643
+ fi
644
+
645
+ # provide user with number of arguments to shift by later
646
+ # NOTE: the FLAGS_ARGC variable is obsolete as of 1.0.3 because it does not
647
+ # properly give user access to non-flag arguments mixed in between flag
648
+ # arguments. Its usage was replaced by FLAGS_ARGV, and it is being kept only
649
+ # for backwards compatibility reasons.
650
+ FLAGS_ARGC=`expr $# - 1 - ${_flags_argc_}`
651
+
652
+ # handle options. note options with values must do an additional shift
653
+ while true; do
654
+ _flags_opt_=$1
655
+ _flags_arg_=${2:-}
656
+ _flags_type_=${__FLAGS_TYPE_NONE}
657
+ _flags_name_=''
658
+
659
+ # determine long flag name
660
+ case "${_flags_opt_}" in
661
+ --) shift; break ;; # discontinue option parsing
662
+
663
+ --*) # long option
664
+ _flags_opt_=`expr "${_flags_opt_}" : '--\(.*\)'`
665
+ _flags_len_=${__FLAGS_LEN_LONG}
666
+ if _flags_itemInList "${_flags_opt_}" ${__flags_longNames}; then
667
+ _flags_name_=${_flags_opt_}
668
+ else
669
+ # check for negated long boolean version
670
+ if _flags_itemInList "${_flags_opt_}" ${__flags_boolNames}; then
671
+ _flags_name_=`expr "${_flags_opt_}" : 'no\(.*\)'`
672
+ _flags_type_=${__FLAGS_TYPE_BOOLEAN}
673
+ _flags_arg_=${__FLAGS_NULL}
674
+ fi
675
+ fi
676
+ ;;
677
+
678
+ -*) # short option
679
+ _flags_opt_=`expr "${_flags_opt_}" : '-\(.*\)'`
680
+ _flags_len_=${__FLAGS_LEN_SHORT}
681
+ if _flags_itemInList "${_flags_opt_}" ${__flags_shortNames}; then
682
+ # yes. match short name to long name. note purposeful off-by-one
683
+ # (too high) with awk calculations.
684
+ _flags_pos_=`echo "${__flags_shortNames}" \
685
+ |awk 'BEGIN{RS=" ";rn=0}$0==e{rn=NR}END{print rn}' \
686
+ e=${_flags_opt_}`
687
+ _flags_name_=`echo "${__flags_longNames}" \
688
+ |awk 'BEGIN{RS=" "}rn==NR{print $0}' rn="${_flags_pos_}"`
689
+ fi
690
+ ;;
691
+ esac
692
+
693
+ # die if the flag was unrecognized
694
+ if [ -z "${_flags_name_}" ]; then
695
+ flags_error="unrecognized option (${_flags_opt_})"
696
+ flags_return=${FLAGS_ERROR}
697
+ break
698
+ fi
699
+
700
+ # set new flag value
701
+ [ ${_flags_type_} -eq ${__FLAGS_TYPE_NONE} ] && \
702
+ _flags_type_=`_flags_getFlagInfo \
703
+ "${_flags_name_}" ${__FLAGS_INFO_TYPE}`
704
+ case ${_flags_type_} in
705
+ ${__FLAGS_TYPE_BOOLEAN})
706
+ if [ ${_flags_len_} -eq ${__FLAGS_LEN_LONG} ]; then
707
+ if [ "${_flags_arg_}" != "${__FLAGS_NULL}" ]; then
708
+ eval "FLAGS_${_flags_name_}=${FLAGS_TRUE}"
709
+ else
710
+ eval "FLAGS_${_flags_name_}=${FLAGS_FALSE}"
711
+ fi
712
+ else
713
+ _flags_strToEval_="_flags_val_=\
714
+ \${__flags_${_flags_name_}_${__FLAGS_INFO_DEFAULT}}"
715
+ eval "${_flags_strToEval_}"
716
+ if [ ${_flags_val_} -eq ${FLAGS_FALSE} ]; then
717
+ eval "FLAGS_${_flags_name_}=${FLAGS_TRUE}"
718
+ else
719
+ eval "FLAGS_${_flags_name_}=${FLAGS_FALSE}"
720
+ fi
721
+ fi
722
+ ;;
723
+
724
+ ${__FLAGS_TYPE_FLOAT})
725
+ if _flags_validateFloat "${_flags_arg_}"; then
726
+ eval "FLAGS_${_flags_name_}='${_flags_arg_}'"
727
+ else
728
+ flags_error="invalid float value (${_flags_arg_})"
729
+ flags_return=${FLAGS_ERROR}
730
+ break
731
+ fi
732
+ ;;
733
+
734
+ ${__FLAGS_TYPE_INTEGER})
735
+ if _flags_validateInteger "${_flags_arg_}"; then
736
+ eval "FLAGS_${_flags_name_}='${_flags_arg_}'"
737
+ else
738
+ flags_error="invalid integer value (${_flags_arg_})"
739
+ flags_return=${FLAGS_ERROR}
740
+ break
741
+ fi
742
+ ;;
743
+
744
+ ${__FLAGS_TYPE_STRING})
745
+ eval "FLAGS_${_flags_name_}='${_flags_arg_}'"
746
+ ;;
747
+ esac
748
+
749
+ # handle special case help flag
750
+ if [ "${_flags_name_}" = 'help' ]; then
751
+ if [ ${FLAGS_help} -eq ${FLAGS_TRUE} ]; then
752
+ flags_help
753
+ flags_error='help requested'
754
+ flags_return=${FLAGS_FALSE}
755
+ break
756
+ fi
757
+ fi
758
+
759
+ # shift the option and non-boolean arguements out.
760
+ shift
761
+ [ ${_flags_type_} != ${__FLAGS_TYPE_BOOLEAN} ] && shift
762
+ done
763
+
764
+ # give user back non-flag arguments
765
+ FLAGS_ARGV=''
766
+ while [ $# -gt 0 ]; do
767
+ FLAGS_ARGV="${FLAGS_ARGV:+${FLAGS_ARGV} }'$1'"
768
+ shift
769
+ done
770
+
771
+ unset _flags_arg_ _flags_len_ _flags_name_ _flags_opt_ _flags_pos_ \
772
+ _flags_strToEval_ _flags_type_ _flags_val_
773
+ return ${flags_return}
774
+ }
775
+
776
+ #------------------------------------------------------------------------------
777
+ # public functions
778
+ #
779
+
780
+ # A basic boolean flag. Boolean flags do not take any arguments, and their
781
+ # value is either 1 (false) or 0 (true). For long flags, the false value is
782
+ # specified on the command line by prepending the word 'no'. With short flags,
783
+ # the presense of the flag toggles the current value between true and false.
784
+ # Specifying a short boolean flag twice on the command results in returning the
785
+ # value back to the default value.
786
+ #
787
+ # A default value is required for boolean flags.
788
+ #
789
+ # For example, lets say a Boolean flag was created whose long name was 'update'
790
+ # and whose short name was 'x', and the default value was 'false'. This flag
791
+ # could be explicitly set to 'true' with '--update' or by '-x', and it could be
792
+ # explicitly set to 'false' with '--noupdate'.
793
+ DEFINE_boolean() { _flags_define ${__FLAGS_TYPE_BOOLEAN} "$@" || return "$?"; }
794
+
795
+ # Other basic flags.
796
+ DEFINE_float() { _flags_define ${__FLAGS_TYPE_FLOAT} "$@" || return "$?"; }
797
+ DEFINE_integer() { _flags_define ${__FLAGS_TYPE_INTEGER} "$@" || return "$?"; }
798
+ DEFINE_string() { _flags_define ${__FLAGS_TYPE_STRING} "$@" || return "$?"; }
799
+
800
+ # Parse the flags.
801
+ #
802
+ # Args:
803
+ # unnamed: list: command-line flags to parse
804
+ # Returns:
805
+ # integer: success of operation, or error
806
+ FLAGS()
807
+ {
808
+ # define a standard 'help' flag if one isn't already defined
809
+ [ -z "${__flags_help_type:-}" ] && \
810
+ DEFINE_boolean 'help' false 'show this help' 'h'
811
+
812
+ # parse options
813
+ if [ $# -gt 0 ]; then
814
+ if [ ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} ]; then
815
+ _flags_getoptStandard "$@"
816
+ else
817
+ _flags_getoptEnhanced "$@"
818
+ fi
819
+ flags_return=$?
820
+ else
821
+ # nothing passed; won't bother running getopt
822
+ __flags_opts='--'
823
+ flags_return=${FLAGS_TRUE}
824
+ fi
825
+
826
+ if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then
827
+ _flags_parseGetopt $# "${__flags_opts}"
828
+ flags_return=$?
829
+ fi
830
+
831
+ [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_fatal "${flags_error}"
832
+ return ${flags_return}
833
+ }
834
+
835
+ # This is a helper function for determining the `getopt` version for platforms
836
+ # where the detection isn't working. It simply outputs debug information that
837
+ # can be included in a bug report.
838
+ #
839
+ # Args:
840
+ # none
841
+ # Output:
842
+ # debug info that can be included in a bug report
843
+ # Returns:
844
+ # nothing
845
+ flags_getoptInfo()
846
+ {
847
+ # platform info
848
+ _flags_debug "uname -a: `uname -a`"
849
+ _flags_debug "PATH: ${PATH}"
850
+
851
+ # shell info
852
+ if [ -n "${BASH_VERSION:-}" ]; then
853
+ _flags_debug 'shell: bash'
854
+ _flags_debug "BASH_VERSION: ${BASH_VERSION}"
855
+ elif [ -n "${ZSH_VERSION:-}" ]; then
856
+ _flags_debug 'shell: zsh'
857
+ _flags_debug "ZSH_VERSION: ${ZSH_VERSION}"
858
+ fi
859
+
860
+ # getopt info
861
+ getopt >/dev/null
862
+ _flags_getoptReturn=$?
863
+ _flags_debug "getopt return: ${_flags_getoptReturn}"
864
+ _flags_debug "getopt --version: `getopt --version 2>&1`"
865
+
866
+ unset _flags_getoptReturn
867
+ }
868
+
869
+ # Returns whether the detected getopt version is the enhanced version.
870
+ #
871
+ # Args:
872
+ # none
873
+ # Output:
874
+ # none
875
+ # Returns:
876
+ # bool: true if getopt is the enhanced version
877
+ flags_getoptIsEnh()
878
+ {
879
+ test ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH}
880
+ }
881
+
882
+ # Returns whether the detected getopt version is the standard version.
883
+ #
884
+ # Args:
885
+ # none
886
+ # Returns:
887
+ # bool: true if getopt is the standard version
888
+ flags_getoptIsStd()
889
+ {
890
+ test ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_STD}
891
+ }
892
+
893
+ # This is effectively a 'usage()' function. It prints usage information and
894
+ # exits the program with ${FLAGS_FALSE} if it is ever found in the command line
895
+ # arguments. Note this function can be overridden so other apps can define
896
+ # their own --help flag, replacing this one, if they want.
897
+ #
898
+ # Args:
899
+ # none
900
+ # Returns:
901
+ # integer: success of operation (always returns true)
902
+ flags_help()
903
+ {
904
+ if [ -n "${FLAGS_HELP:-}" ]; then
905
+ echo "${FLAGS_HELP}" >&2
906
+ else
907
+ echo "USAGE: ${FLAGS_PARENT:-$0} [flags] args" >&2
908
+ fi
909
+ if [ -n "${__flags_longNames}" ]; then
910
+ echo 'flags:' >&2
911
+ for flags_name_ in ${__flags_longNames}; do
912
+ flags_flagStr_=''
913
+ flags_boolStr_=''
914
+
915
+ flags_default_=`_flags_getFlagInfo \
916
+ "${flags_name_}" ${__FLAGS_INFO_DEFAULT}`
917
+ flags_help_=`_flags_getFlagInfo \
918
+ "${flags_name_}" ${__FLAGS_INFO_HELP}`
919
+ flags_short_=`_flags_getFlagInfo \
920
+ "${flags_name_}" ${__FLAGS_INFO_SHORT}`
921
+ flags_type_=`_flags_getFlagInfo \
922
+ "${flags_name_}" ${__FLAGS_INFO_TYPE}`
923
+
924
+ [ "${flags_short_}" != "${__FLAGS_NULL}" ] \
925
+ && flags_flagStr_="-${flags_short_}"
926
+
927
+ if [ ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH} ]; then
928
+ [ "${flags_short_}" != "${__FLAGS_NULL}" ] \
929
+ && flags_flagStr_="${flags_flagStr_},"
930
+ [ ${flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} ] \
931
+ && flags_boolStr_='[no]'
932
+ flags_flagStr_="${flags_flagStr_}--${flags_boolStr_}${flags_name_}:"
933
+ fi
934
+
935
+ case ${flags_type_} in
936
+ ${__FLAGS_TYPE_BOOLEAN})
937
+ if [ ${flags_default_} -eq ${FLAGS_TRUE} ]; then
938
+ flags_defaultStr_='true'
939
+ else
940
+ flags_defaultStr_='false'
941
+ fi
942
+ ;;
943
+ ${__FLAGS_TYPE_FLOAT}|${__FLAGS_TYPE_INTEGER})
944
+ flags_defaultStr_=${flags_default_} ;;
945
+ ${__FLAGS_TYPE_STRING}) flags_defaultStr_="'${flags_default_}'" ;;
946
+ esac
947
+ flags_defaultStr_="(default: ${flags_defaultStr_})"
948
+
949
+ flags_helpStr_=" ${flags_flagStr_} ${flags_help_} ${flags_defaultStr_}"
950
+ flags_helpStrLen_=`expr "${flags_helpStr_}" : '.*'`
951
+ flags_columns_=`_flags_columns`
952
+ if [ ${flags_helpStrLen_} -lt ${flags_columns_} ]; then
953
+ echo "${flags_helpStr_}" >&2
954
+ else
955
+ echo " ${flags_flagStr_} ${flags_help_}" >&2
956
+ # note: the silliness with the x's is purely for ksh93 on Ubuntu 6.06
957
+ # because it doesn't like empty strings when used in this manner.
958
+ flags_emptyStr_="`echo \"x${flags_flagStr_}x\" \
959
+ |awk '{printf "%"length($0)-2"s", ""}'`"
960
+ flags_helpStr_=" ${flags_emptyStr_} ${flags_defaultStr_}"
961
+ flags_helpStrLen_=`expr "${flags_helpStr_}" : '.*'`
962
+ if [ ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_STD} \
963
+ -o ${flags_helpStrLen_} -lt ${flags_columns_} ]; then
964
+ # indented to match help string
965
+ echo "${flags_helpStr_}" >&2
966
+ else
967
+ # indented four from left to allow for longer defaults as long flag
968
+ # names might be used too, making things too long
969
+ echo " ${flags_defaultStr_}" >&2
970
+ fi
971
+ fi
972
+ done
973
+ fi
974
+
975
+ unset flags_boolStr_ flags_default_ flags_defaultStr_ flags_emptyStr_ \
976
+ flags_flagStr_ flags_help_ flags_helpStr flags_helpStrLen flags_name_ \
977
+ flags_columns_ flags_short_ flags_type_
978
+ return ${FLAGS_TRUE}
979
+ }
980
+
981
+ # Reset shflags back to an uninitialized state.
982
+ #
983
+ # Args:
984
+ # none
985
+ # Returns:
986
+ # nothing
987
+ flags_reset()
988
+ {
989
+ for flags_name_ in ${__flags_longNames}; do
990
+ flags_strToEval_="unset FLAGS_${flags_name_}"
991
+ for flags_type_ in \
992
+ ${__FLAGS_INFO_DEFAULT} \
993
+ ${__FLAGS_INFO_HELP} \
994
+ ${__FLAGS_INFO_SHORT} \
995
+ ${__FLAGS_INFO_TYPE}
996
+ do
997
+ flags_strToEval_=\
998
+ "${flags_strToEval_} __flags_${flags_name_}_${flags_type_}"
999
+ done
1000
+ eval ${flags_strToEval_}
1001
+ done
1002
+
1003
+ # reset internal variables
1004
+ __flags_boolNames=' '
1005
+ __flags_longNames=' '
1006
+ __flags_shortNames=' '
1007
+
1008
+ unset flags_name_ flags_type_ flags_strToEval_
1009
+ }