changeset 719:b2757e72b517

farray.sh: The first preparations to allow arrays/alists as values in other arrays or alists
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 04 Oct 2024 23:18:10 +0200
parents 2502e077d5e9
children 47620b3c1080
files share/local-bsdtools/farray.sh tests/farray-alist.t tests/farray-array.t
diffstat 3 files changed, 245 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/share/local-bsdtools/farray.sh	Fri Oct 04 18:20:15 2024 +0200
+++ b/share/local-bsdtools/farray.sh	Fri Oct 04 23:18:10 2024 +0200
@@ -482,7 +482,8 @@
 #:
 #: Output (Globals):
 #:   __farr_name (str): The name of the array.
-#:   __farr_token (str): The token that is the value of the name.
+#:   __farr_token (str): The token that is the value of the name without its
+#:                       token prefix.
 #:   __farr_gvrname (str): The variable prefix for all items.
 #:   __farr_len (int): The length of the array.
 #:
@@ -523,7 +524,8 @@
 #:
 #: Output (Globals):
 #:   __farr_name (str): The name of the array.
-#:   __farr_token (str): The token that is the value of the name.
+#:   __farr_token (str): The token that is the value of the name without its
+#:                       token prefix.
 #:   __farr_gvrname (str): The variable prefix for all items.
 #:   __farr_len (int): The length of the array
 #:
@@ -580,7 +582,8 @@
 #:
 #: Output (Globals):
 #:   __farr_name (str): The name of the array.
-#:   __farr_token (str): The token that is the value of the name.
+#:   __farr_token (str): The token that is the value of the name without its
+#:                       token prefix.
 #:   __farr_gvrname (str): The variable prefix for all items.
 #:   __farr_len (int): The length of the array
 #:
@@ -619,6 +622,57 @@
 
 
 #:
+#: Internal helper to try to get all the metadata for an array directoy from
+#: a given array token with prefix.
+#:
+#: Args:
+#:   $1 (str): The token value with its prefix for an array.
+#:
+#: Output (Globals):
+#:   __farr_token (str): The token that is the value of the name without its
+#:                       token prefix.
+#:   __farr_gvrname (str): The variable prefix for all items.
+#:   __farr_len (int): The length of the array
+#:
+#: Returns:
+#:   0 if the array exists, 1 if something is missing or wrong.
+#:
+#: An error is printed only if the storage of an otherwise correct array
+#: is missing.
+#:
+_farr_array_tryget_meta_from_value() {
+    local __farr_input_token_value
+
+    __farr_input_token_value="${1-}"
+    __farr_token=''
+    __farr_gvrname=''
+    __farr_len=''
+    case "${__farr_input_token_value}" in
+        '')
+            return 1
+            ;;
+
+        "${_farr_array_token_prefix}"*)
+            __farr_token="${__farr_input_token_value#"${_farr_array_token_prefix}"}"
+            ;;
+        *)
+            return 1
+            ;;
+    esac
+    __farr_gvrname="${_farr_array_prefix}${__farr_token}"
+
+    eval __farr_len=\$\{${__farr_gvrname}__:+SET\}
+    if [ -z "${__farr_len}" ]; then
+        _farr_err "farray with token value \`${__farr_input_token_value}' not created properly: no storage for token \`${__farr_token}'"
+        return 1
+    fi
+    # eval __farr_len="\$((\${${__farr_gvrname}__} + 0))"
+    eval __farr_len=\"\$\{${__farr_gvrname}__\}\"
+    return 0
+}
+
+
+#:
 #: Get the length of an array and put it into a variable
 #:
 #: Args:
@@ -1084,6 +1138,36 @@
 
 
 #:
+#: Destroy and unset an array and all its elements from its complete token
+#: value
+#:
+#: Args:
+#:   $1 (str): An array token value including its prefix
+#:
+#: Returns:
+#:   - A truthy value if the array existed and has been deleted.
+#:   - A falsy value if the array does not exist.
+#:
+_farr_array_destroy_value() {
+
+    local __farr_token __farr_gvrname __farr_len
+    local __farr_idx
+
+    _farr_array_tryget_meta_from_value "$1" || return 1
+
+    # Remove "storage"
+    __farr_idx=1
+    while [ ${__farr_idx} -le ${__farr_len} ]; do
+	eval unset ${__farr_gvrname}_${__farr_idx}
+	__farr_idx=$((__farr_idx + 1))
+    done
+
+    # Remove length itselt
+    eval unset ${__farr_gvrname}__
+}
+
+
+#:
 #: Test the boolean truth of an array.
 #:
 #: Args:
@@ -1589,7 +1673,8 @@
 #:
 #: Output (Globals):
 #:   __farr_name (str): The name of the alist.
-#:   __farr_token (str): The token that is the value of the name.
+#:   __farr_token (str): The token that is the value of the name without its
+#:                       token prefix.
 #:   __farr_objname (str): The variable prefix for the length ("object").
 #:   __farr_keyname (str): The variable prefix for all item keys.
 #:   __farr_valname (str): The variable prefix for all item values.
@@ -1641,6 +1726,64 @@
 
 
 #:
+#: Internal helper to try to get all the metadata for an alist directly from
+#: a given alist token with prefix.
+#:
+#: Args:
+#:   $1 (str): The token value with its prefix for an alist.
+#:
+#: Output (Globals):
+#:   __farr_token (str): The token that is the value of the name without its
+#:                       token prefix.
+#:   __farr_objname (str): The variable prefix for the length ("object").
+#:   __farr_keyname (str): The variable prefix for all item keys.
+#:   __farr_valname (str): The variable prefix for all item values.
+#:   __farr_len (int): The length of the alist.
+#:
+#: Returns:
+#:   0 if the array exists, 1 if something is missing or wrong.
+#:
+#: An error is printed only if the storage of an otherwise correct alist
+#: is missing.
+#:
+_farr_alist_tryget_meta_from_value() {
+    local __farr_input_token_value
+
+    __farr_input_token_value="${1-}"
+    __farr_token=""
+    __farr_objname=""
+    __farr_keyname=""
+    __farr_valname=""
+    __farr_len=""
+    case "${__farr_input_token_value}" in
+        '')
+            return 1
+            ;;
+
+        "${_farr_alist_token_prefix}"*)
+            __farr_token="${__farr_input_token_value#"${_farr_alist_token_prefix}"}"
+            ;;
+        *)
+            return 1
+            ;;
+    esac
+
+    __farr_objname="${_farr_alist_prefix}${__farr_token}"
+    __farr_keyname=${_farr_alist_key_prefix}${__farr_token}
+    __farr_valname=${_farr_alist_value_prefix}${__farr_token}
+
+    eval __farr_len=\$\{${__farr_objname}__:+SET\}
+    if [ -z "${__farr_len}" ]; then
+        _farr_err "falist with token value \`${__farr_input_token_value}' not created properly: no object for token \`${__farr_token}'"
+        return 1
+    fi
+    # eval __farr_len="\$((\${${__farr_objname}__} + 0))"
+    eval __farr_len="\${${__farr_objname}__}"
+    return 0
+}
+
+
+#:
 #: Get the length of an alist and put it into a variable.
 #:
 #: Args:
@@ -1746,6 +1889,37 @@
 
 
 #:
+#: Destroy and unset an alist from its complete token value including prefix.
+#:
+#: Args:
+#:   $1 (str): The alist token value including its prefix.
+#:
+#: Returns:
+#:   - A truthy value if the alist existed and has been deleted.
+#:   - A falsy value if the alist does not exist.
+#:
+_farr_alist_destroy_value() {
+
+    local __farr_token __farr_objname __farr_keyname __farr_valname __farr_len
+    local __farr_idx
+
+    _farr_alist_tryget_meta_from_value "$1" || return 1
+
+    # Remove "storage"
+    __farr_idx=1
+    while [ ${__farr_idx} -le ${__farr_len} ]; do
+        eval unset ${__farr_valname}_${__farr_idx}
+        eval unset ${__farr_keyname}_${__farr_idx}
+        __farr_idx=$((__farr_idx + 1))
+    done
+
+    # Remove object (length) itselt
+    eval unset ${__farr_objname}__
+    return 0
+}
+
+
+#:
 #: Map a key to a value.
 #:
 #: Args:
@@ -2687,3 +2861,34 @@
     done
     return 0
 }
+
+
+#:
+#: Destroy any object.
+#:
+#: If an object represents an array or alist its contents will be destroyed
+#: properly.
+#:
+#: Args:
+#:   $1: The object's value
+#:
+#: Returns:
+#:   int: 0 if the destruction went properly without errors, 1 otherwise
+#:
+_farr_destroy_object() {
+
+    case "$1" in
+        '')
+            return 0;;
+        "${_farr_array_token_prefix}"*)
+            _farr_array_destroy_value "$1"
+            # let the return value pass through
+            ;;
+        "${_farr_alist_token_prefix}"*)
+            _farr_alist_destroy_value "$1"
+            # let the return value pass through
+            ;;
+        *)
+            return 0;;
+    esac
+}
--- a/tests/farray-alist.t	Fri Oct 04 18:20:15 2024 +0200
+++ b/tests/farray-alist.t	Fri Oct 04 23:18:10 2024 +0200
@@ -404,3 +404,20 @@
   $ falist_isalist LIST
   $ falist_destroy LIST
   $ check_no_alist_artifacts
+
+
+Generic Destruction
+===================
+
+  $ falist_create LIST k1 v2
+  $ falist_debug LIST
+  DEBUG: alist `LIST' has length 1
+  DEBUG:     `k1' -> `v2'
+  $ _farr_destroy_object "$LIST"
+  $ check_no_alist_artifacts
+  $ (_farr_destroy_object "$LIST")
+  ERROR: falist with token value `_farr_KV\*_([a-f0-9]+)' not created properly: no object for token `\1' (re)
+  [1]
+  $ LIST=''
+  $ _farr_destroy_object "$LIST"
+  $ check_no_alist_artifacts
--- a/tests/farray-array.t	Fri Oct 04 18:20:15 2024 +0200
+++ b/tests/farray-array.t	Fri Oct 04 23:18:10 2024 +0200
@@ -1045,3 +1045,22 @@
   $ farray_isarray TEST
   $ farray_destroy TEST
   $ check_no_array_artifacts
+
+
+Generic Destruction
+===================
+
+  $ farray_create TEST i1 i2
+  $ farray_debug TEST
+  DEBUG: array `TEST' has length 2
+  DEBUG:   its contents:
+  DEBUG:     1: `i1'
+  DEBUG:     2: `i2'
+  $ _farr_destroy_object "$TEST"
+  $ check_no_array_artifacts
+  $ (_farr_destroy_object "$TEST")
+  ERROR: farray with token value `_farr_A\*_([a-f0-9]+)' not created properly: no storage for token `\1' (re)
+  [1]
+  $ TEST=''
+  $ _farr_destroy_object "$TEST"
+  $ check_no_array_artifacts