changeset 767:54fefbabcf78

farray.sh: Implement "farray_pop()"
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 21 Oct 2024 16:26:49 +0200
parents f5d0cdc3432c
children 53d05f470f4a
files share/local-bsdtools/farray.sh tests/farray-array.t
diffstat 2 files changed, 91 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/share/local-bsdtools/farray.sh	Mon Oct 21 16:26:23 2024 +0200
+++ b/share/local-bsdtools/farray.sh	Mon Oct 21 16:26:49 2024 +0200
@@ -994,8 +994,55 @@
     fi
 
     # Release the item at index
-    eval __farr_del_value=\"\$\{"${__farr_gvrname}"_"${__farr_index}"\}\"
-    _farr_release_object "${__farr_del_value}"
+    eval _farr_release_object \"\$\{"${__farr_gvrname}"_"${__farr_index}"\}\"
+
+    # Move all other items down by one
+    __farr_idx="${__farr_index}"
+    while [ "${__farr_idx}" -lt "${__farr_len}" ]; do
+        # copy the following value to the current index
+        eval "${__farr_gvrname}"_"${__farr_idx}"=\"\$\{"${__farr_gvrname}"_$((__farr_idx + 1))\}\"
+        __farr_idx=$((__farr_idx + 1))
+    done
+    # Drop the last item
+    eval unset "${__farr_gvrname}"_"${__farr_idx}"
+    # Set the new length
+    setvar "${__farr_gvrname}__" $((__farr_len - 1))
+}
+
+
+#:
+#: Delete an array value at a given index and return the deleted value.
+#:
+#: Args:
+#:   $1 (str, null): The name of a variable where to store the deleted value
+#:                   into. If `null` then the deleted value is not stored
+#:                   and/or returned.
+#:   $2 (str): The name of the existing array.
+#:   $3 (int): The index to delete to.
+#:
+#: Returns:
+#:   int: 0 if the value exists and is deleted, 1 otherwise
+#:
+farray_pop() {
+    # $1
+    local __farr_name __farr_index
+
+    local __farr_token __farr_gvrname __farr_len __farr_idx
+
+    _farr_array_get_meta "${2-}"
+    _farr_make_index __farr_index "${3-}" "${__farr_len}"
+    # check index range
+    if [ "${__farr_index}" -lt 1 ] || [ "${__farr_index}" -gt "${__farr_len}" ]; then
+	return 1
+    fi
+
+    if [ -n "${1-}" ] ; then
+        # Just transfer ownership
+        eval "${1}"=\"\$\{"${__farr_gvrname}"_"${__farr_index}"\}\"
+    else
+        # Release the item at index
+        eval _farr_release_object \"\$\{"${__farr_gvrname}"_"${__farr_index}"\}\"
+    fi
 
     # Move all other items down by one
     __farr_idx="${__farr_index}"
--- a/tests/farray-array.t	Mon Oct 21 16:26:23 2024 +0200
+++ b/tests/farray-array.t	Mon Oct 21 16:26:49 2024 +0200
@@ -420,6 +420,48 @@
   $ farray_release TEST
   $ check_no_array_artifacts
 
+
+Pop
+===
+
+  $ farray_create TEST 0 1 2 '3  4   5' $'" 678" \\\'910 ' 11
+
+  $ farray_pop _var TEST 1
+  $ echo "$_var"
+  0
+
+  $ farray_pop _var TEST 0
+  $ echo "$_var"
+  11
+  $ farray_pop _var TEST 0
+  $ printf '<%s>' "$_var"
+  <" 678" \'910 > (no-eol)
+
+  $ farray_pop _var TEST ""
+  [1]
+
+  $ farray_pop _var TEST 100
+  [1]
+
+  $ farray_release TEST
+  $ check_no_array_artifacts
+
+Special case with one element
+
+  $ farray_create TEST 'val'
+  $ farray_pop _var TEST 0
+  $ echo "$_var"
+  val
+
+Special case empty array: popping from an empty list is not possible
+
+  $ farray_pop _var TEST 0
+  [1]
+
+  $ farray_release TEST
+  $ check_no_array_artifacts
+
+
 Splicing
 ========