|
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