diff --git a/lib/bash/parse_options.sh b/lib/bash/parse_options.sh index 3689f82d..a33e68f8 100644 --- a/lib/bash/parse_options.sh +++ b/lib/bash/parse_options.sh @@ -236,6 +236,7 @@ _eval_po() { local opt="" local default_val="" local neg=0 + local size=0 while read key val; do case "$key" in long) @@ -247,6 +248,7 @@ _eval_po() { "short form") ;; type) + [ "$val" = "size" ] && size=1 ;; desc) ;; @@ -273,6 +275,11 @@ _eval_po() { fi fi + # Convert sizes. + if [ $size -eq 1 -a -n "$default_val" ]; then + default_val=$(size_to_bytes $default_val) + fi + # Eval the option into existence as a global variable. eval "OPT_${opt}"="$default_val" done @@ -339,6 +346,7 @@ _parse_command_line() { local opt_is_negated="" local real_opt="" local required_arg="" + local spec="" for opt in "$@"; do if [ "$opt" = "--" -o "$opt" = "----" ]; then @@ -438,6 +446,11 @@ _parse_command_line() { # Get and transform the opt's long form. E.g.: -q == --quiet == QUIET. opt=$(cat "$spec" | grep '^long:' | cut -d':' -f2 | sed 's/-/_/g' | tr [:lower:] [:upper:]) + # Convert sizes. + if grep "^type:size" "$spec" >/dev/null; then + val=$(size_to_bytes $val) + fi + # Re-eval the option to update its global variable value. eval "OPT_$opt"="'$val'" @@ -448,10 +461,16 @@ _parse_command_line() { opt_is_negated="" real_opt="" required_arg="" + spec="" fi done } +size_to_bytes() { + local size="$1" + echo $size | perl -ne '%f=(B=>1, K=>1_024, M=>1_048_576, G=>1_073_741_824, T=>1_099_511_627_776); m/^(\d+)([kMGT])?/i; print $1 * $f{uc($2 || "B")};' +} + # ########################################################################### # End parse_options package # ########################################################################### diff --git a/t/lib/bash/parse_options.sh b/t/lib/bash/parse_options.sh index 9c124858..b66f8584 100644 --- a/t/lib/bash/parse_options.sh +++ b/t/lib/bash/parse_options.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -TESTS=64 +TESTS=72 TMPFILE="$TEST_TMPDIR/parse-opts-output" TOOL="pt-stalk" @@ -183,6 +183,34 @@ is "$OPT_STRING_OPT" "hello world" "Option value with space (cmd line)" is "$ARGV" "" "ARGV (cmd line)" is "$EXT_ARGV" "" "External ARGV (cmd line)" +# ############################################################################ +# Size options. +# ############################################################################ + +parse_options "$T_LIB_DIR/samples/bash/po004.sh" --disk-bytes-free 1T +is "$OPT_DISK_BYTES_FREE" "1099511627776" "Size: 1T" + +parse_options "$T_LIB_DIR/samples/bash/po004.sh" --disk-bytes-free 1G +is "$OPT_DISK_BYTES_FREE" "1073741824" "Size: 1G" + +parse_options "$T_LIB_DIR/samples/bash/po004.sh" --disk-bytes-free 1M +is "$OPT_DISK_BYTES_FREE" "1048576" "Size: 1M" + +parse_options "$T_LIB_DIR/samples/bash/po004.sh" --disk-bytes-free 1K +is "$OPT_DISK_BYTES_FREE" "1024" "Size: 1K" + +parse_options "$T_LIB_DIR/samples/bash/po004.sh" --disk-bytes-free 1k +is "$OPT_DISK_BYTES_FREE" "1024" "Size: 1k" + +parse_options "$T_LIB_DIR/samples/bash/po004.sh" --disk-bytes-free 1 +is "$OPT_DISK_BYTES_FREE" "1" "Size: 1" + +parse_options "$T_LIB_DIR/samples/bash/po004.sh" --disk-bytes-free 100M +is "$OPT_DISK_BYTES_FREE" "104857600" "Size: 100M" + +parse_options "$T_LIB_DIR/samples/bash/po004.sh" +is "$OPT_DISK_BYTES_FREE" "104857600" "Size: 100M default" + # ############################################################################ # Done # ############################################################################ diff --git a/t/lib/samples/bash/po004.sh b/t/lib/samples/bash/po004.sh new file mode 100644 index 00000000..0574f221 --- /dev/null +++ b/t/lib/samples/bash/po004.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +: + +# ############################################################################ +# Documentation +# ############################################################################ +:<<'DOCUMENTATION' +=pod + +=head1 NAME + +pt-stalk - Wait for a condition to occur then begin collecting data. + +=head1 OPTIONS + +=over + +=item --disk-bytes-free + +type: size; default: 100M + +Fall apart if there's less than this many bytes free on the disk. + +=item --help + +Print help. + +=back + +=head1 ENVIRONMENT + +No env vars used. + +=cut + +DOCUMENTATION