first check-in of feisty meow codebase. many things broken still due to recent
[feisty_meow.git] / scripts / core / array_sifter.sh
1 #!/bin/bash
2 #
3 # Provides functions for checking and sorting the contents of arrays.
4
5 # given the name of an array as the first parameter, this signals
6 # success (return value zero) if the second parameter is found in the
7 # array.  failure (non-zero return) occurs if the item is missing.
8 function test_presence()
9 {
10   array_name=$1; shift
11   flag_to_find=$1; shift
12   temp_name="${array_name}[*]"
13   declare -a array_to_check=(${!temp_name})
14 #echo "array to check is: ${array_to_check[*]}"
15   local i;
16   for (( i=0; i < ${#array_to_check[*]}; i++ )); do
17     if [ "${array_to_check[i]}" == "$flag_to_find" ]; then
18 #      echo "found the flag $flag_to_find"
19       return 0
20     fi
21   done
22 #  echo "did not find the flag $flag_to_find"
23   return 1
24 }
25
26 # takes two arrays of items and checks whether any of the members of the second
27 # array are present in the first array.  zero is returned when a match is found.
28 function match_any()
29 {
30   match_within_name=$1; shift
31   items_to_match_name=$1; shift
32 #  temp_name="${match_within}[*]"
33 #  declare -a match_within_array=(${!temp_name})
34 #echo "the list to match within is: ${match_within_array[*]}"
35   temp_name="${items_to_match_name}[*]"
36   declare -a items_to_match_array=(${!temp_name})
37 #echo "the items to match are: ${items_to_match_array[*]}"
38
39   for onetag in ${items_to_match_array[*]}; do
40 #echo curr tag is $onetag 
41     test_presence $match_within_name $onetag
42     if [ $? -eq 0 ]; then return 0; fi  # got a match.
43   done
44   return 1  # no match found.
45 }
46
47 # sifts an array by finding matching items in a second array and storing
48 # those extracted items into a third array.  the original array is modified
49 # by removing those matched items.  the first parameter is the array to sift,
50 # the second is a list of items to sift out of the array, and the third is
51 # an array to fill with removed/matched items.  each of these is just a
52 # name, which will be indirectly referenced to get its contents.
53 # success (zero) is returned when any item to match was found in the array.
54 function sift_array()
55 {
56   sift_name=$1; shift
57   temp_name="${sift_name}[*]"
58   declare -a array_to_sift=(${!temp_name})
59   match_name=$1; shift
60   temp_name="${match_name}[*]"
61   declare -a match_items=(${!temp_name})
62   store_name=$1; shift
63
64   declare -a temp_store=()  # put our extracted items for the moment.
65
66   # seek backwards through the array to sift, so we can destructively
67   # rearrange it without adjusting loop index.
68   sift_len=${#array_to_sift[*]}
69   local i; local j;
70   for (( i=$sift_len; i >= 0; i-- )); do
71     # look through match items to see if they're in the sifting array.
72     for (( j=0; j < ${#match_items[*]}; j++ )); do
73       curname=${match_items[$j]}
74       if [ "${array_to_sift[$i]}" == "$curname" ]; then
75         # found a lucky participant; move it to the storage array.
76         temp_store+=($curname)
77 #echo temp store now ${temp_store[*]}
78         # remove this item from the containing array.
79         ((after=$i+1))
80         ((afterlen=$sift_len-$i))
81
82         array_to_sift=(${array_to_sift[*]:0:$i} ${array_to_sift[*]:$after:$afterlen})
83       fi
84     done
85   done
86
87   # update our list for what was removed.
88   eval ${sift_name}=\(${array_to_sift[*]}\)
89
90   # now assign to the external arrays.
91   eval ${store_name}=\(${temp_store[*]}\)
92
93   if [ ${#temp_store} -ne 0 ]; then
94     return 0
95   else
96     return 1
97   fi
98 }
99