summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKerin Millar <kfm@plushkava.net>2024-06-11 06:26:41 +0100
committerKerin Millar <kfm@plushkava.net>2024-06-14 01:27:44 +0100
commit449fed1c13525c8420b4366014ba34616cb20239 (patch)
treed80dfc5d0777e9c30179e8088a3e503eb770b978
parentAdd the from_unit() function (diff)
downloadgentoo-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.sh62
-rwxr-xr-xtest-functions49
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