mirror of
https://github.com/moparisthebest/pacman
synced 2025-02-28 09:21:53 -05:00
scripts/library: add human_to_size
This is a bash wrapper around an awk function that parses human readable sizes and returns their representative values in bytes, as a string. A small test harness is added to validate the functionality. Signed-off-by: Dave Reisner <dreisner@archlinux.org>
This commit is contained in:
parent
e183522e31
commit
b58489d29a
@ -41,6 +41,8 @@ test-vercmp: test/util src/util
|
||||
test-parseopts: test/scripts scripts
|
||||
$(BASH_SHELL) $(top_srcdir)/test/scripts/parseopts_test.sh \
|
||||
$(top_srcdir)/scripts/library/parseopts.sh
|
||||
$(BASH_SHELL) $(top_srcdir)/test/scripts/human_to_size_test.sh \
|
||||
$(top_srcdir)/scripts/library/human_to_size.sh
|
||||
|
||||
# create the pacman DB and cache directories upon install
|
||||
install-data-local:
|
||||
|
@ -27,7 +27,8 @@ EXTRA_DIST = \
|
||||
|
||||
LIBRARY = \
|
||||
library/output_format.sh \
|
||||
library/parseopts.sh
|
||||
library/parseopts.sh \
|
||||
library/human_to_size.sh
|
||||
|
||||
# Files that should be removed, but which Automake does not know.
|
||||
MOSTLYCLEANFILES = $(bin_SCRIPTS)
|
||||
|
@ -27,3 +27,11 @@ Reccommended Usage:
|
||||
Returns:
|
||||
0: parse success
|
||||
1: parse failure (error message supplied)
|
||||
|
||||
human_to_size.sh:
|
||||
A function to convert human readable sizes (such as "5.3 GiB") to raw byte
|
||||
equivalents. base10 and base2 suffixes are supported, case sensitively. If
|
||||
successful, the converted byte value is written to stdout and the function
|
||||
returns 0. If an error occurs, nothing in written and the function returns 1.
|
||||
Results may be inaccurate when using a broken implementation of awk, such
|
||||
as mawk or busybox awk.
|
||||
|
51
scripts/library/human_to_size.sh
Normal file
51
scripts/library/human_to_size.sh
Normal file
@ -0,0 +1,51 @@
|
||||
human_to_size() {
|
||||
awk -v human="$1" '
|
||||
function trim(s) {
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", s)
|
||||
return s
|
||||
}
|
||||
|
||||
function parse_units(units) {
|
||||
if (!units || units == "B")
|
||||
return 1
|
||||
if (match(units, /^.iB$/))
|
||||
return 1024
|
||||
if (match(units, /^.B$/))
|
||||
return 1000
|
||||
if (length(units) == 1)
|
||||
return 1024
|
||||
|
||||
# parse failure: invalid base
|
||||
return -1
|
||||
}
|
||||
|
||||
function parse_scale(s) {
|
||||
return index("BKMGTPE", s) - 1
|
||||
}
|
||||
|
||||
function isnumeric(string) {
|
||||
return match(string, /^[-+]?[[:digit:]]*(\.[[:digit:]]*)?/)
|
||||
}
|
||||
|
||||
BEGIN {
|
||||
# peel off the leading number as the size, fail on invalid number
|
||||
human = trim(human)
|
||||
if (isnumeric(human))
|
||||
size = substr(human, RSTART, RLENGTH)
|
||||
else
|
||||
exit 1
|
||||
|
||||
# the trimmed remainder is assumed to be the units
|
||||
units = trim(substr(human, RLENGTH + 1))
|
||||
|
||||
base = parse_units(units)
|
||||
if (base < 0)
|
||||
exit 1
|
||||
|
||||
scale = parse_scale(substr(units, 1, 1))
|
||||
if (scale < 0)
|
||||
exit 1
|
||||
|
||||
printf "%d\n", size * base^scale + (size + 0 > 0 ? 0.5 : -0.5)
|
||||
}'
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
check_SCRIPTS = \
|
||||
parseopts_test.sh
|
||||
parseopts_test.sh \
|
||||
human_to_size_test.sh
|
||||
|
||||
noinst_SCRIPTS = $(check_SCRIPTS)
|
||||
|
||||
|
75
test/scripts/human_to_size_test.sh
Normal file
75
test/scripts/human_to_size_test.sh
Normal file
@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
|
||||
# source the library function
|
||||
if [[ -z $1 || ! -f $1 ]]; then
|
||||
printf "error: path to human_to_size library not provided or does not exist\n"
|
||||
exit 1
|
||||
fi
|
||||
. "$1"
|
||||
|
||||
if ! type -t human_to_size >/dev/null; then
|
||||
printf 'human_to_size function not found\n'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
parse_hts() {
|
||||
local input=$1 expected=$2 result
|
||||
|
||||
(( ++testcount ))
|
||||
|
||||
result=$(human_to_size "$1")
|
||||
if [[ $result = "$expected" ]]; then
|
||||
(( ++pass ))
|
||||
else
|
||||
(( ++fail ))
|
||||
printf '[TEST %3s]: FAIL\n' "$testcount"
|
||||
printf ' input: %s\n' "$input"
|
||||
printf ' output: %s\n' "$result"
|
||||
printf ' expected: %s\n' "$expected"
|
||||
fi
|
||||
}
|
||||
|
||||
summarize() {
|
||||
if (( !fail )); then
|
||||
printf 'All %s tests successful\n' "$testcount"
|
||||
exit 0
|
||||
else
|
||||
printf '%s of %s tests failed\n' "$fail" "$testcount"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
trap 'summarize' EXIT
|
||||
|
||||
printf 'Beginning human_to_size tests\n'
|
||||
|
||||
# parse_hts <input> <expected output>
|
||||
|
||||
parse_hts '1MiB' 1048576
|
||||
|
||||
parse_hts '10XiB' ''
|
||||
|
||||
parse_hts '10 MiB' 10485760
|
||||
|
||||
parse_hts '10 XiB' ''
|
||||
|
||||
parse_hts '.1 TiB' 109951162778
|
||||
|
||||
parse_hts ' -3 KiB ' -3072
|
||||
|
||||
parse_hts 'foo3KiB' ''
|
||||
|
||||
parse_hts '3KiBfoo' ''
|
||||
|
||||
parse_hts '3kib' ''
|
||||
|
||||
parse_hts '+1KiB' 1024
|
||||
|
||||
parse_hts '+1.0 KiB' 1024
|
||||
|
||||
parse_hts '1MB' 1000000
|
||||
|
||||
parse_hts '1M' 1048576
|
||||
|
||||
parse_hts ' 1 G ' 1073741824
|
||||
|
||||
parse_hts '1Q' ''
|
Loading…
x
Reference in New Issue
Block a user