-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathposix-arrays-a-mini.sh
90 lines (72 loc) · 2.17 KB
/
posix-arrays-a-mini.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/bin/sh
# shellcheck disable=SC2154,SC2086
# Copyright: friendly bits
# github.com/friendly-bits
# posix-arrays-a-mini.sh
# emulates associative arrays in POSIX shell
# NOTE: this is a stripped down to a minimum and optimized for very small arrays version,
# which includes a minimal subset of functions from the main project:
# https://github.com/friendly-bits/POSIX-arrays
# get keys from an associative array
# whitespace-delimited output is set as a value of a global variable
# 1 - array name
# 2 - var name for output
get_a_arr_keys() {
___me="get_a_arr_keys"
case $# in 2) ;; *) wrongargs "$@"; return 1; esac
_arr_name="$1"; _out_var="$2"
_check_vars _arr_name _out_var || return 1
eval "$_out_var=\"\$(printf '%s ' \${_a_${_arr_name}___keys:-})\""
:
}
# 1 - array name
# 2 - 'key=value' pair
set_a_arr_el() {
___me="set_a_arr_el"
case $# in 2) ;; *) wrongargs "$@"; return 1; esac
_arr_name="$1"; ___pair="$2"
case "$___pair" in *=* ) ;; *) printf '%s\n' "$___me: Error: '$___pair' is not a 'key=value' pair." >&2; return 1; esac
___key="${___pair%%=*}"
___new_val="${___pair#*=}"
_check_vars _arr_name ___key || return 1
eval "___keys=\"\${_a_${_arr_name}___keys:-}\"
_a_${_arr_name}_${___key}"='${___new_val}'
case "$___keys" in
*"$_nl$___key"|*"$_nl$___key$_nl"* ) ;;
*) eval "_a_${_arr_name}___keys=\"$___keys$_nl$___key\""
esac
:
}
# 1 - array name
# 2 - key
# 3 - var name for output
get_a_arr_val() {
___me="get_a_arr_val"
case $# in 3) ;; *) wrongargs "$@"; return 1; esac
_arr_name="$1"; ___key="$2"; _out_var="$3"
_check_vars _arr_name ___key _out_var || return 1
eval "$_out_var=\"\$_a_${_arr_name}_${___key}\""
}
## Backend functions
_check_vars() {
case "${nocheckvars:-}" in *?*) return 0; esac
for ___var in "$@"; do
eval "_var_val=\"\$$___var\""
case "$_var_val" in ''|*[!A-Za-z0-9_]* )
case "$___var" in
___key) _var_desc="key" ;;
_arr_name) _var_desc="array name" ;;
_out_var) _var_desc="output variable name"
esac
printf '%s\n' "$___me: Error: invalid $_var_desc '$_var_val'." >&2
return 1
esac
done
}
wrongargs() {
echo "$___me: Error: '$*': wrong number of arguments '$#'." >&2
}
set -f
export LC_ALL=C
_nl='
'