changeset 510:5f8c4c4546b1

array.sh: Implement "array_set()" and "array_del()" to set and delete array entries at given indexes
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 31 Aug 2024 23:20:03 +0200
parents 527d38d0003d
children 4186db70abe6
files share/local-bsdtools/array.sh
diffstat 1 files changed, 95 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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: