# HG changeset patch # User Franz Glasner # Date 1725139203 -7200 # Node ID 5f8c4c4546b10e404c548f493bc971350e0926f0 # Parent 527d38d0003d0e45e8b91de546d8a3294225188b array.sh: Implement "array_set()" and "array_del()" to set and delete array entries at given indexes diff -r 527d38d0003d -r 5f8c4c4546b1 share/local-bsdtools/array.sh --- a/share/local-bsdtools/array.sh Sat Aug 31 20:31:10 2024 +0200 +++ b/share/local-bsdtools/array.sh Sat Aug 31 23:20:03 2024 +0200 @@ -205,6 +205,55 @@ #: +#: Set an array at an index to a value. +#: +#: Args: +#: $1 (str): The name of the existing array +#: $2 (int): The index +#: $3 (optional): The value to set. If the value is not given the null +#: will be appended. +#: +#: No holes are allowed in an array: only values at existing indices are +#: allowed. As an exception a value can be appended if the given index +#: is exactly the current length + 1. +#: +array_set() { + local _name _index _value + + local _gvrname _l _l1 + + [ $# -lt 1 ] && _array_fatal "missing array name" + _name=$1 + _gvrname=${_farr_global_prefix}$1 + [ $# -lt 2 ] && _array_fatal "missing array index" + _index=$2 + _value="${3-}" + + # Check whether the variable already exists + eval _l=\${${_gvrname}__:-${_farr_unset}} + if [ "${_l}" = ${_farr_unset} ]; then + _array_fatal "array \`${_name}' does not exist" + fi + + # For proper quoting: see array_append + if [ \( ${_index} -ge 1 \) -a \( ${_index} -le ${_l} \) ]; then + # replace a value at an existing index + eval ${_gvrname}_${_l}=\$\'"$(_quote_for_eval_dsq "${_value}")"\' + else + _l1=$((${_l} + 1)) + if [ ${_index} -eq ${_l1} ]; then + # append value + eval ${_gvrname}_${_l1}=\$\'"$(_quote_for_eval_dsq "${_value}")"\' + # and set new length + eval ${_gvrname}__=${_l1} + else + _array_fatal "array index out of bounds (cannot create holes)" + fi + fi +} + + +#: #: Get an array value from a given index. #: #: Args: @@ -242,6 +291,52 @@ #: +#: Delete an array value at a given index. +#: +#: Args: +#: $1 (str): The name of the existing array +#: $2 (int): The index to delete to +#: +array_del() { + local _name _index + + local _gvrname _l _new_l _idx _idx1 _value + + [ $# -lt 1 ] && _array_fatal "missing array name" + _name=$1 + _gvrname=${_farr_global_prefix}$1 + [ $# -lt 2 ] && _array_fatal "missing array index" + _index=$2 + + # Check whether the variable already exists + eval _l=\${${_gvrname}__:-${_farr_unset}} + if [ "${_l}" = ${_farr_unset} ]; then + _array_fatal "array \`${_name}' does not exist" + fi + + # check index range + if [ \( "${_index}" -lt 1 \) -o \( "${_index}" -gt ${_l} \) ]; then + _array_fatal "array index out of bounds" + fi + + _new_l=$((${_l} - 1)) + _idx=${_index} + _idx1=$((${_idx} + 1)) + while [ ${_idx} -lt ${_l} ]; do + # copy the following value to the current index + eval _value=\"\${${_gvrname}_${_idx1}}\" + eval ${_gvrname}_${_idx}=\$\'"$(_quote_for_eval_dsq "${_value}")"\' + _idx=$((${_idx} + 1)) + _idx1=$((${_idx} + 1)) + done + # Drop the last item + eval unset unset ${_gvrname}_${_idx} + # Set the new length + eval ${_gvrname}__=${_new_l} +} + + +#: #: Try to get an array value from a given index. #: #: Args: