|
1 | 1 | # Utility xfunc functions for array manipulations -*- shell-script -*- |
2 | 2 |
|
| 3 | +# usage: _comp_xfunc_ARRAY__init_predicate pattern pattype [anchoring flags] |
| 4 | +# @param $1 pattern Pattern |
| 5 | +# @param $2 pattype /[EFG]/ or empty |
| 6 | +# @param[opt] $3 anchoring /[psmx]/ or empty |
| 7 | +# @param[opt] $4 flags /r/ or empty |
| 8 | +# See _comp_xfunc_ARRAY_filter for details of pattern, pattype, |
| 9 | +# anchoring, and flags. |
| 10 | +# @var[out] _predicate |
| 11 | +# @var[out] _predicate_pat |
| 12 | +# @var[out] _predicate_type |
| 13 | +# @var[out] _predicate_revert |
| 14 | +_comp_xfunc_ARRAY__init_predicate() |
| 15 | +{ |
| 16 | + _predicate=false |
| 17 | + _predicate_pat=$1 |
| 18 | + _predicate_type=$2 |
| 19 | + _predicate_revert="" |
| 20 | + |
| 21 | + local old_nocasematch="" |
| 22 | + if shopt -q nocasematch; then |
| 23 | + old_nocasematch=set |
| 24 | + shopt -u nocasematch |
| 25 | + fi |
| 26 | + |
| 27 | + local _pattype=$2 _anchoring=${3-} flags=${4-} |
| 28 | + case $_pattype in |
| 29 | + E) |
| 30 | + case $_anchoring in |
| 31 | + p) _predicate='[[ $_value =~ ^($_predicate_pat) ]]' ;; |
| 32 | + s) _predicate='[[ $_value =~ ($_predicate_pat)$ ]]' ;; |
| 33 | + x) _predicate='[[ $_value =~ ^($_predicate_pat)$ ]]' ;; |
| 34 | + *) _predicate='[[ $_value =~ $_predicate_pat ]]' ;; |
| 35 | + esac |
| 36 | + ;; |
| 37 | + F) |
| 38 | + case $_anchoring in |
| 39 | + p) _predicate='[[ $_value == "$_predicate_pat"* ]]' ;; |
| 40 | + s) _predicate='[[ $_value == *"$_predicate_pat" ]]' ;; |
| 41 | + x) _predicate='[[ $_value == "$_predicate_pat" ]]' ;; |
| 42 | + *) _predicate='[[ $_value == *"$_predicate_pat"* ]]' ;; |
| 43 | + esac |
| 44 | + ;; |
| 45 | + G) |
| 46 | + case $_anchoring in |
| 47 | + p) _predicate='[[ $_value == $_predicate_pat* ]]' ;; |
| 48 | + s) _predicate='[[ $_value == *$_predicate_pat ]]' ;; |
| 49 | + m) _predicate='[[ $_value == *$_predicate_pat* ]]' ;; |
| 50 | + *) _predicate='[[ $_value == $_predicate_pat ]]' ;; |
| 51 | + esac |
| 52 | + ;; |
| 53 | + *) |
| 54 | + if type -t "$2" &>/dev/null; then |
| 55 | + _predicate="$2 \"\$_value\"" |
| 56 | + else |
| 57 | + _predicate="local -x value=\$_value; $2" |
| 58 | + fi |
| 59 | + ;; |
| 60 | + esac |
| 61 | + |
| 62 | + [[ $_flags == *r* ]] && _predicate_revert=set |
| 63 | + [[ $old_nocasematch ]] && shopt -s nocasematch |
| 64 | +} |
| 65 | + |
| 66 | +_comp_xfunc_ARRAY__predicate() |
| 67 | +{ |
| 68 | + local _value=$1 |
| 69 | + eval "$_predicate" |
| 70 | + |
| 71 | + local _ext=$? |
| 72 | + case $_ext in |
| 73 | + [01]) [[ $_predicate_revert ]] && _ext=$((1 - _ext)) ;; |
| 74 | + 27) ;; |
| 75 | + *) |
| 76 | + printf 'bash_completion: %s: %s\n' "$FUNCNAME" \ |
| 77 | + "filter condition broken '${_predicate_type:+-$_predicate_type }$2'" >&2 |
| 78 | + return 2 |
| 79 | + ;; |
| 80 | + esac |
| 81 | + return "$_ext" |
| 82 | +} |
| 83 | + |
3 | 84 | # Filter the array elements with the specified condition. |
4 | 85 | # @param $1 Array name (that is not "value", "_*" or other internal variable |
5 | 86 | # names) |
@@ -80,67 +161,28 @@ _comp_xfunc_ARRAY_filter() |
80 | 161 | elif [[ $1 == @(_*|OPTIND|OPTARG|OPTERR) ]]; then |
81 | 162 | printf 'bash_completion: %s: %s\n' "$FUNCNAME" "array name '$1' is reserved for internal uses" >&2 |
82 | 163 | return 2 |
83 | | - elif [[ ! $_pattype && $1 == value ]]; then |
84 | | - printf 'bash_completion: %s: %s\n' "$FUNCNAME" "array name '$1' cannot be used for the predicate" >&2 |
85 | | - return 2 |
86 | 164 | fi |
87 | 165 | # When the array is empty: |
88 | 166 | eval "((\${#$1[@]}))" || return 0 |
89 | 167 |
|
90 | | - local _predicate='' _pattern=$2 |
91 | | - case $_pattype in |
92 | | - E) |
93 | | - case $_anchoring in |
94 | | - p) _predicate='[[ $_value =~ ^($_pattern) ]]' ;; |
95 | | - s) _predicate='[[ $_value =~ ($_pattern)$ ]]' ;; |
96 | | - x) _predicate='[[ $_value =~ ^($_pattern)$ ]]' ;; |
97 | | - *) _predicate='[[ $_value =~ $_pattern ]]' ;; |
98 | | - esac |
99 | | - ;; |
100 | | - F) |
101 | | - case $_anchoring in |
102 | | - p) _predicate='[[ $_value == "$_pattern"* ]]' ;; |
103 | | - s) _predicate='[[ $_value == *"$_pattern" ]]' ;; |
104 | | - x) _predicate='[[ $_value == "$_pattern" ]]' ;; |
105 | | - *) _predicate='[[ $_value == *"$_pattern"* ]]' ;; |
106 | | - esac |
107 | | - ;; |
108 | | - G) |
109 | | - case $_anchoring in |
110 | | - p) _predicate='[[ $_value == $_pattern* ]]' ;; |
111 | | - s) _predicate='[[ $_value == *$_pattern ]]' ;; |
112 | | - m) _predicate='[[ $_value == *$_pattern* ]]' ;; |
113 | | - *) _predicate='[[ $_value == $_pattern ]]' ;; |
114 | | - esac |
115 | | - ;; |
116 | | - *) |
117 | | - if type -t "$2" &>/dev/null; then |
118 | | - _predicate="$2 \"\$_value\"" |
119 | | - else |
120 | | - _predicate="local -x value=\$_value; $2" |
121 | | - fi |
122 | | - ;; |
123 | | - esac |
| 168 | + local _predicate _predicate_pat _predicate_type _predicate_revert |
| 169 | + _comp_xfunc_ARRAY__init_predicate "$2" "$_pattype" "$_anchoring" "$_flags" |
124 | 170 |
|
125 | | - local _unset="" _expected_status=0 |
126 | | - [[ $_flags == *r* ]] && _expected_status=1 |
| 171 | + local _unset="" |
127 | 172 |
|
128 | | - local _indices _index _value |
| 173 | + local _indices _index _ref |
129 | 174 | eval "_indices=(\"\${!$1[@]}\")" |
130 | 175 | for _index in "${_indices[@]}"; do |
131 | | - eval "_value=\${$1[\$_index]}; $_predicate" |
| 176 | + _ref="$1[\$_index]" |
| 177 | + _comp_xfunc_ARRAY__predicate "${!_ref}" |
132 | 178 | case $? in |
133 | | - "$_expected_status") continue ;; |
134 | | - [01]) |
135 | | - unset -v "$1[\$_index]" |
| 179 | + 0) continue ;; |
| 180 | + 1) |
| 181 | + unset -v "$_ref" |
136 | 182 | _unset=set |
137 | 183 | ;; |
138 | 184 | 27) break ;; |
139 | | - *) |
140 | | - printf 'bash_completion: %s: %s\n' "$FUNCNAME" \ |
141 | | - "filter condition broken '${_pattype:+-$_pattype }$2'" >&2 |
142 | | - return 2 |
143 | | - ;; |
| 185 | + *) return 2 ;; |
144 | 186 | esac |
145 | 187 | done |
146 | 188 |
|
|
0 commit comments