# HG changeset patch # User Franz Glasner # Date 1725182101 -7200 # Node ID 4186db70abe60fcc0755079d924a31af9f1cd052 # Parent 5f8c4c4546b10e404c548f493bc971350e0926f0 array.sh: REFACTOR: All functions that are value getters (get, tryget, find, length) set a variable now. This is similar to the shell's builtin "read". This is to behave better for errors: no subshells invoked: because $(foo bar) would invoke a subshell and prohibit proper fatal exits. BUGS: Name clases on variables. Check that _varname does not clash with a declared local. diff -r 5f8c4c4546b1 -r 4186db70abe6 share/local-bsdtools/array.sh --- a/share/local-bsdtools/array.sh Sat Aug 31 23:20:03 2024 +0200 +++ b/share/local-bsdtools/array.sh Sun Sep 01 11:15:01 2024 +0200 @@ -135,6 +135,41 @@ } + +#: +#: Get the length of an array and put it into a variable +#: +#: Args: +#: $1 (str): The name of the variable to put the length into +#: $2 (str): The name of the array. +#: +#: Returns: +#: 0 (truthy) if the array exists, +#: 1 (falsy) if the array does not exist +#: +array_length() { + local _varname _name + + local _gvrname _l + + [ $# -lt 1 ] && _array_fatal "missing variable name" + _varname=$1 + [ $# -lt 2 ] && _array_fatal "missing array name" + _name=$2 + _gvrname=${_farr_global_prefix}$2 + + # Check whether the variable already exists + eval _l=\${${_gvrname}__:-${_farr_unset}} + + if [ "${_l}" = ${_farr_unset} ]; then + return 1 + else + eval ${_varname}=${_l} + return 0 + fi +} + + #: #: Get the length of an array. #: @@ -145,22 +180,20 @@ #: The number of elements of the array. #: If the array does not exist the output is -1. #: -array_length() { +array_print_length() { local _name - local _gvrname _l + local _vn [ $# -lt 1 ] && _array_fatal "missing array name" _name=$1 - _gvrname=${_farr_global_prefix}$1 - # Check whether the variable already exists - eval _l=\${${_gvrname}__:-${_farr_unset}} - - if [ "${_l}" = ${_farr_unset} ]; then - printf "%s" "-1" + if array_length _vn ${_name}; then + printf "%s" "${_vn}" + return 0 else - printf "%s" "${_l}" + printf "%s" "-1" + return 1 fi } @@ -254,25 +287,25 @@ #: -#: Get an array value from a given index. +#: Get an array value from a given index and put it into given variable. #: #: Args: -#: $1 (str): The name of the existing array -#: $2 (int): The index -#: -#: Output (stdout): -#: The value at index $2. +#: $1 (str): The name of the variable to put the value into +#: $2 (str): The name of the existing array +#: $3 (int): The index #: array_get() { - local _name _index + local _varname _name _index local _gvrname _l _value - [ $# -lt 1 ] && _array_fatal "missing array name" - _name=$1 - _gvrname=${_farr_global_prefix}$1 - [ $# -lt 2 ] && _array_fatal "missing array index" - _index=$2 + [ $# -lt 1 ] && _array_fatal "missing variable name" + _varname=$1 + [ $# -lt 2 ] && _array_fatal "missing array name" + _name=$2 + _gvrname=${_farr_global_prefix}$2 + [ $# -lt 3 ] && _array_fatal "missing array index" + _index=$3 # Check whether the variable already exists eval _l=\${${_gvrname}__:-${_farr_unset}} @@ -285,8 +318,52 @@ _array_fatal "array index out of bounds" fi - eval _value=\"\${${_gvrname}_${_index}}\" - printf "%s" "${_value}" + eval ${_varname}=\"\${${_gvrname}_${_index}}\" +} + + +#: +#: Try to get an array value from a given index into a variable +#: +#: Args: +#: $1 (str): The name of the variable to put the value into +#: $2 (str): The name of the existing array +#: $3 (int): The index +#: +#: Returns: +#: 0 (truthy) on success, +#: 1 (falsy) if the given index is out of bounds (i.e. EOD) +#: +#: Exit: +#: Other errors (missing array name, missing index value) are considered +#: fatal and call `_array_fatal` (i.e. `exit`). +#: +array_tryget() { + local _varname _name _index + + local _gvrname _l _value + + [ $# -lt 1 ] && _array_fatal "missing variable name" + _varname=$1 + [ $# -lt 2 ] && _array_fatal "missing array name" + _name=$2 + _gvrname=${_farr_global_prefix}$2 + [ $# -lt 3 ] && _array_fatal "missing array index" + _index=$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 + + # check index range + if [ \( "${_index}" -lt 1 \) -o \( "${_index}" -gt ${_l} \) ]; then + return 1 + fi + + eval ${_varname}=\"\${${_gvrname}_${_index}}\" + return 0 } @@ -337,52 +414,6 @@ #: -#: Try to get an array value from a given index. -#: -#: Args: -#: $1 (str): The name of the existing array -#: $2 (int): The index -#: -#: Output (stdout): -#: The value at index $2. -#: -#: Returns: -#: 0 (truthy) on success, -#: 1 (falsy) if the given index is out of bounds (i.e. EOD) -#: -#: Exit: -#: Other errors (missing array name, missing index value) are considered -#: fatal and call `_array_fatal` (i.e. `exit`). -#: -array_tryget() { - local _name _index - - local _gvrname _l _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 - return 1 - fi - - eval _value=\"\${${_gvrname}_${_index}}\" - printf "%s" "${_value}" - return 0 -} - - -#: #: Empty an existing array. #: #: Args: @@ -491,10 +522,11 @@ #: Try to find the index of a given value in an existing array. #: #: Args: -#: $1: The name of an existing array -#: $2: The value to search for -#: $3 (int, optional): The start index to search for (inclusive) -#: $4 (int, optional): The index to stop (inclusive) +#: $1 (str): The name of a variable where to put the found index into +#: $2 (str): The name of an existing array +#: $3: The value to search for +#: $4 (int, optional): The start index to search for (inclusive) +#: $5 (int, optional): The index to stop (inclusive) #: #: Output (stdout): #: The index number where the value is found -- if any @@ -505,15 +537,17 @@ #: - 1 (falsy) otherwise #: array_find() { - local _name _searched_value _start _end + local _varname _name _searched_value _start _end - local _gvrname _l _idx _existing_value + local _gvrname _l _sidx _existing_value - [ $# -lt 1 ] && _array_fatal "missing array name" - _name=$1 - _gvrname=${_farr_global_prefix}$1 - [ $# -lt 2 ] && _array_fatal "missing value to search for" - _searched_value="$2" + [ $# -lt 1 ] && _array_fatal "missing variable name" + _varname=$1 + [ $# -lt 2 ] && _array_fatal "missing array name" + _name=$2 + _gvrname=${_farr_global_prefix}$2 + [ $# -lt 3 ] && _array_fatal "missing value to search for" + _searched_value="$3" # Check whether the variable already exists eval _l=\${${_gvrname}__:-${_farr_unset}} @@ -521,17 +555,18 @@ _array_fatal "array \`${_name}' does not exist" fi - _start=${3-1} - _end=${4-${_l}} + _start=${4-1} + _end=${5-${_l}} - _idx=${_start} - while [ ${_idx} -le ${_end} ]; do - eval _existing_value=\"\${${_gvrname}_${_idx}}\" + _sidx=${_start} + while [ ${_sidx} -le ${_end} ]; do + eval _existing_value=\"\${${_gvrname}_${_sidx}}\" if [ "${_existing_value}" = "${_searched_value}" ]; then - printf "%d" ${_idx} + #printf "%d" ${_isdx} + eval ${_varname}=${_sidx} return 0 fi - _idx=$((${_idx} + 1)) + _sidx=$((${_sidx} + 1)) done return 1 }