# HG changeset patch # User Franz Glasner # Date 1728076690 -7200 # Node ID b2757e72b5171150ac23971bb7d5364f7837b4fe # Parent 2502e077d5e9e672aba90a2d621ba76e68b89ca9 farray.sh: The first preparations to allow arrays/alists as values in other arrays or alists diff -r 2502e077d5e9 -r b2757e72b517 share/local-bsdtools/farray.sh --- 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 +} diff -r 2502e077d5e9 -r b2757e72b517 tests/farray-alist.t --- 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 diff -r 2502e077d5e9 -r b2757e72b517 tests/farray-array.t --- 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