commit:     449fed1c13525c8420b4366014ba34616cb20239
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Jun 11 05:26:41 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 14 00:27:44 2024 +0000
URL:        
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=449fed1c

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 <AT> plushkava.net>

 functions.sh   | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 test-functions | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+)

diff --git a/functions.sh b/functions.sh
index 7d146c8..166f184 100644
--- a/functions.sh
+++ b/functions.sh
@@ -446,6 +446,28 @@ is_int()
        esac
 }
 
+#
+# 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.
@@ -468,6 +490,46 @@ is_older_than()
        | read -r _
 }
 
+#
+# 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

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
 

Reply via email to