diff options
author | Kerin Millar <kfm@plushkava.net> | 2024-06-11 06:26:41 +0100 |
---|---|---|
committer | Kerin Millar <kfm@plushkava.net> | 2024-06-14 01:27:44 +0100 |
commit | 449fed1c13525c8420b4366014ba34616cb20239 (patch) | |
tree | d80dfc5d0777e9c30179e8088a3e503eb770b978 | |
parent | Add the from_unit() function (diff) | |
download | gentoo-functions-449fed1c13525c8420b4366014ba34616cb20239.tar.gz gentoo-functions-449fed1c13525c8420b4366014ba34616cb20239.tar.bz2 gentoo-functions-449fed1c13525c8420b4366014ba34616cb20239.zip |
Add the is_anyof() and is_subset() functions
Examples follow.
is_anyof y x y z # returns 0
is_anoyf y x w z # returns 1
is_subset x y -- x y z # returns 0
is_subset x y z -- z y x # returns 0
is_subset x y -- x w z # returns 1
Signed-off-by: Kerin Millar <kfm@plushkava.net>
-rw-r--r-- | functions.sh | 62 | ||||
-rwxr-xr-x | test-functions | 49 |
2 files changed, 111 insertions, 0 deletions
diff --git a/functions.sh b/functions.sh index 7d146c8..166f184 100644 --- a/functions.sh +++ b/functions.sh @@ -447,6 +447,28 @@ is_int() } # +# Determines whether the first parameter matches any of the parameters that +# follow it. +# +is_anyof() +{ + local arg needle + + if [ "$#" -eq 0 ]; then + warn "is_anyof: too few arguments (got $#, expected at least 1)" + else + needle=$1 + shift + for arg; do + if [ "${arg}" = "${needle}" ]; then + return + fi + done + fi + false +} + +# # Takes the first parameter as a reference file/directory then determines # whether any of the following parameters refer to newer files/directories. # @@ -469,6 +491,46 @@ is_older_than() } # +# Collects the intersection of the parameters up to - but not including - a +# sentinel value then determines whether the resulting set is a subset of the +# interection of the remaining parameters. If the SENTINEL variable is set and +# non-empty, it shall be taken as the value of the sentinel. Otherwise, the +# value of the sentinel shall be defined as <hyphen-dash><hyphen-dash>. If the +# sentinel value is not encountered or if either set is empty then the returm +# value shall be greater than 1. +# +is_subset() +{ + SENTINEL=${SENTINEL:-'--'} awk -f - -- "$@" <<-'EOF' + BEGIN { + argc = ARGC + ARGC = 1 + for (i = 1; i < argc; i++) { + word = ARGV[i] + if (word == ENVIRON["SENTINEL"]) { + break + } else { + set1[word] = "" + } + } + if (i == 1 || argc - i < 2) { + exit 1 + } + for (i++; i < argc; i++) { + word = ARGV[i] + set2[word] = "" + } + for (word in set2) { + delete set1[word] + } + for (word in set1) { + exit 1 + } + } + EOF +} + +# # Considers one or more pathnames and prints the one having the newest # modification time. If at least one parameter is provided, all parameters shall # be considered as pathnames to be compared to one another. Otherwise, the diff --git a/test-functions b/test-functions index 1a2eb81..0b987ab 100755 --- a/test-functions +++ b/test-functions @@ -575,6 +575,53 @@ test_parallel_run() { iterate_tests 4 "$@" } +test_is_anyof() { + set -- \ + ge 1 N/A N/A N/A \ + ge 1 x N/A N/A \ + ge 1 x y N/A \ + ge 1 x y z \ + eq 0 x x N/A \ + eq 0 x x y \ + eq 0 x y x + + callback() { + shift + test_description="is_anyof $(quote_args "$@")" + is_anyof "$@" + } + + iterate_tests 5 "$@" +} + +test_is_subset() { + set -- \ + ge 1 N/A N/A N/A N/A N/A \ + ge 1 -- N/A N/A N/A N/A \ + ge 1 -- -- N/A N/A N/A \ + ge 1 -- x N/A N/A N/A \ + ge 1 x -- N/A N/A N/A \ + ge 1 x y N/A N/A N/A \ + ge 1 x y x N/A N/A \ + eq 0 x -- x N/A N/A \ + eq 0 x -- x y N/A \ + eq 0 x -- y x N/A \ + eq 0 x y -- x y \ + eq 0 x y -- y x \ + ge 1 x y -- x z \ + ge 1 y x -- z x \ + ge 1 x z -- x y \ + ge 1 z x -- y x + + callback() { + shift + test_description="is_subset $(quote_args "$@")" + is_subset "$@" + } + + iterate_tests 7 "$@" +} + iterate_tests() { slice_width=$1 shift @@ -641,6 +688,8 @@ test_trim || rc=1 test_hr || rc=1 test_whenceforth || rc=1 test_parallel_run || rc=1 +test_is_anyof || rc=1 +test_is_subset || rc=1 cleanup_tmpdir |