# HG changeset patch # User Franz Glasner # Date 1728058815 -7200 # Node ID 2502e077d5e9e672aba90a2d621ba76e68b89ca9 # Parent f4725ad5cd21ee7be5a9b1834b8567c4130c7fdc farray.sh: Implement "falist_set_unique()" that does not overwrite existing key-value pairs diff -r f4725ad5cd21 -r 2502e077d5e9 share/local-bsdtools/farray.sh --- a/share/local-bsdtools/farray.sh Fri Oct 04 17:18:14 2024 +0200 +++ b/share/local-bsdtools/farray.sh Fri Oct 04 18:20:15 2024 +0200 @@ -1804,6 +1804,68 @@ #: +#: Map a key to a value but error if the alist contains already an item +#: with the given key. +#: +#: Args: +#: $1 (str): The name of an existing alist. +#: $2, $3 ... (optional): A sequence of key-value pairs the alist will be +#: populated with. +#: +#: Returns: +#: int: 0 (truthy) if the item got set, 1 (falsy) if there is already an +#: item with key `$1` in the alist +#: +#: Exit: +#: If one of the underlying arrays that implement the alist does not exist +#: or if an internal inconsistency will be detected. +#: +falist_set_unique() { + local __farr_name __farr_key __farr_value + + local __farr_token __farr_objname __farr_keyname __farr_valname __farr_len + local __farr_idx __farr_elkey + + _farr_alist_get_meta "$@" + shift + + while [ $# -ne 0 ]; do + [ $# -lt 1 ] && _farr_fatal "missing key" + __farr_key="$1" + [ $# -lt 2 ] && _farr_fatal "missing value" + __farr_value="$2" + + __farr_idx=1 + while [ ${__farr_idx} -le ${__farr_len} ]; do + eval __farr_elkey=\"\$\{${__farr_keyname}_${__farr_idx}+SET\}\" + if [ -n "${__farr_elkey}" ]; then + eval __farr_elkey=\"\$\{${__farr_keyname}_${__farr_idx}\}\" + if [ "${__farr_elkey}" = "${__farr_key}" ]; then + return 1 + fi + else + _farr_fatal "key unexpectedly unset (index ${__farr_idx})" + fi + __farr_idx=$((__farr_idx + 1)) + done + # + # Not yet found: "append" .. + # + # NOTE: __farr_idx here already is the new correct length + # + __farr_len=${__farr_idx} + # ... the key/value pairs to storage + eval ${__farr_keyname}_${__farr_len}="$(_farr_quote_for_eval "${__farr_key}")" + eval ${__farr_valname}_${__farr_len}="$(_farr_quote_for_eval "${__farr_value}")" + # ... the new length + eval ${__farr_objname}__=${__farr_len} + shift 2 + done + return 0 +} + + +#: #: Update an alist from another alist. #: #: Key-values from the other alist are given precedence. diff -r f4725ad5cd21 -r 2502e077d5e9 tests/farray-alist.t --- a/tests/farray-alist.t Fri Oct 04 17:18:14 2024 +0200 +++ b/tests/farray-alist.t Fri Oct 04 18:20:15 2024 +0200 @@ -90,6 +90,8 @@ 2 (no-eol) $ falist_set LIST K2 "V2 2" + $ falist_set_unique LIST K2 "V2 duplicate" + [1] $ falist_set LIST K3 $'" 111222333" \\\'444555 ' # ' $ falist_debug LIST DEBUG: alist `LIST' has length 3 @@ -117,7 +119,13 @@ ERROR: object `NON_EXISTING_LIST' not created properly: token empty $ echo "${_var}" -1 - + $ falist_set_unique LIST K4 "V4" + $ falist_debug LIST + DEBUG: alist `LIST' has length 4 + DEBUG: `K1' -> `V1' + DEBUG: `K2' -> `V2 2' + DEBUG: `K3' -> `" 111222333" \'444555 ' + DEBUG: `K4' -> `V4' $ falist_destroy LIST $ check_no_alist_artifacts