Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
changeset 612:c9ef2339618d
farray.sh: Implemented comparison (ordered and unordered) for alists
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Thu, 19 Sep 2024 18:29:57 +0200 |
| parents | dbd793238b94 |
| children | 17194ffe3638 |
| files | share/local-bsdtools/farray.sh tests/farray-alist.t |
| diffstat | 2 files changed, 168 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/share/local-bsdtools/farray.sh Thu Sep 19 17:31:59 2024 +0200 +++ b/share/local-bsdtools/farray.sh Thu Sep 19 18:29:57 2024 +0200 @@ -64,6 +64,8 @@ #: Exceptions to this rule are documented. #: - An alist preserves insertion order. Note that updating a key does not #: affect the order. Keys added after deletion are inserted at the end. +#: - Alists compare equal if and only if they have the same (key, value) pairs +#: (regardless of ordering). #: #: Hints and rules for indexes: #: @@ -1896,6 +1898,131 @@ #: +#: Test whether two alists are equal. +#: +#: Two alists compare equal if and only if they have the same (key, value) +#: pairs (regardless of ordering). Comparison is done using the shell's +#: builtin ``=`` operator for both keys and values. +#: +#: Args: +#: $1 (str): The name of the first alist +#: $2 (str): The name of the second alist +#: +#: Returns: +#: int: 0 if both input alists are equal, 1 otherwise +#: +falist_are_equal() { + local __farr_l_name __farr_r_name + + local __farr_l_token __farr_l_objname __farr_l_keyname __farr_l_valname __farr_l_len + local __farr_r_token __farr_r_objname __farr_r_keyname __farr_r_valname __farr_r_len + + local __farr_name __farr_token __farr_objname __farr_keyname __farr_valname __farr_len + local __farr_l_idx __farr_l_key __farr_l_value + local __farr_r_idx __farr_r_key __farr_r_value + + [ $# -ne 2 ] && _farr_fatal "missing alist parameter" + + _farr_alist_get_meta "$1" + __farr_l_name="${__farr_name}" + __farr_l_token="${__farr_token}" + __farr_l_objname="${__farr_objname}" + __farr_l_keyname="${__farr_keyname}" + __farr_l_valname="${__farr_valname}" + __farr_l_len="${__farr_len}" + _farr_alist_get_meta "$2" + __farr_r_name="${__farr_name}" + __farr_r_token="${__farr_token}" + __farr_r_objname="${__farr_objname}" + __farr_r_keyname="${__farr_keyname}" + __farr_r_valname="${__farr_valname}" + __farr_r_len="${__farr_len}" + + [ ${__farr_l_len} -ne ${__farr_r_len} ] && return 1 + + __farr_l_idx=1 + while [ ${__farr_l_idx} -le ${__farr_l_len} ]; do + __farr_r_idx=1 + eval __farr_l_key=\"\$\{${__farr_l_keyname}_${__farr_l_idx}\}\" + # Find within the right alist + __farr_r_idx=1 + while [ ${__farr_r_idx} -le ${__farr_r_len} ]; do + eval __farr_r_key=\"\$\{${__farr_r_keyname}_${__farr_r_idx}\}\" + [ "${__farr_l_key}" = "${__farr_r_key}" ] && break + __farr_r_idx=$((__farr_r_idx + 1)) + done + # The index is above the right length if not found + [ ${__farr_r_idx} -gt ${__farr_r_len} ] && return 1 + # Also compare the values + eval __farr_l_value=\"\$\{${__farr_l_valname}_${__farr_l_idx}\}\" + eval __farr_r_value=\"\$\{${__farr_r_valname}_${__farr_r_idx}\}\" + [ "${__farr_l_value}" != "${__farr_r_value}" ] && return 1 + __farr_l_idx=$((__farr_l_idx + 1)) + done + return 0 +} + + +#: +#: Test whether two alists are equal respecting the (insertion) order. +#: +#: Two alists compare equal if and only if they have the same (key, value) +#: pairs **with** regard of ordering. Comparison is done using the shell's +#: builtin ``=`` operator for both keys and values. +#: +#: Args: +#: $1 (str): The name of the first alist +#: $2 (str): The name of the second alist +#: +#: Returns: +#: int: 0 if both input alists are equal, 1 otherwise +#: +falist_are_equal_with_order() { + local __farr_l_name __farr_r_name + + local __farr_l_token __farr_l_objname __farr_l_keyname __farr_l_valname __farr_l_len + local __farr_r_token __farr_r_objname __farr_r_keyname __farr_r_valname __farr_r_len + + local __farr_name __farr_token __farr_objname __farr_keyname __farr_valname __farr_len + local __farr_idx + local __farr_l_key __farr_l_value + local __farr_r_key __farr_r_value + + [ $# -ne 2 ] && _farr_fatal "missing alist parameter" + + _farr_alist_get_meta "$1" + __farr_l_name="${__farr_name}" + __farr_l_token="${__farr_token}" + __farr_l_objname="${__farr_objname}" + __farr_l_keyname="${__farr_keyname}" + __farr_l_valname="${__farr_valname}" + __farr_l_len="${__farr_len}" + _farr_alist_get_meta "$2" + __farr_r_name="${__farr_name}" + __farr_r_token="${__farr_token}" + __farr_r_objname="${__farr_objname}" + __farr_r_keyname="${__farr_keyname}" + __farr_r_valname="${__farr_valname}" + __farr_r_len="${__farr_len}" + + [ ${__farr_l_len} -ne ${__farr_r_len} ] && return 1 + + __farr_idx=1 + while [ ${__farr_idx} -le ${__farr_l_len} ]; do + eval __farr_l_key=\"\$\{${__farr_l_keyname}_${__farr_idx}\}\" + eval __farr_r_key=\"\$\{${__farr_r_keyname}_${__farr_idx}\}\" + [ "${__farr_l_key}" != "${__farr_r_key}" ] && return 1 + # Also compare the values + eval __farr_l_value=\"\$\{${__farr_l_valname}_${__farr_idx}\}\" + eval __farr_r_value=\"\$\{${__farr_r_valname}_${__farr_idx}\}\" + [ "${__farr_l_value}" != "${__farr_r_value}" ] && return 1 + __farr_idx=$((__farr_idx + 1)) + done + return 0 +} + + +#: #: Call a function for every key-value pair in an alist starting in index order. #: #: The function to be called must accept three or four arguments:
--- a/tests/farray-alist.t Thu Sep 19 17:31:59 2024 +0200 +++ b/tests/farray-alist.t Thu Sep 19 18:29:57 2024 +0200 @@ -225,3 +225,44 @@ $ falist_destroy LIST $ check_no_alist_artifacts + + +Compare +======= + + $ falist_create LIST1 + $ falist_set LIST1 K1 V1 + $ falist_set LIST1 K2 V2 + + $ falist_create LIST2 + $ falist_set LIST2 K2 V2 + $ falist_set LIST2 K1 V1 + + $ falist_create LIST3 + $ falist_set LIST3 K1 V1 + $ falist_set LIST3 K2 V2 + + $ falist_create LIST4 + $ falist_set LIST4 K1 V1 + $ falist_set LIST4 K2 V2-4 + + $ falist_are_equal LIST1 LIST2 + $ falist_are_equal LIST1 LIST4 + [1] + $ falist_are_equal_with_order LIST1 LIST2 + [1] + $ falist_are_equal_with_order LIST1 LIST3 + + $ falist_clear LIST2 + $ falist_are_equal LIST1 LIST2 + [1] + + $ falist_clear LIST3 + $ falist_are_equal_with_order LIST2 LIST3 + + $ falist_destroy LIST1 + $ falist_destroy LIST2 + $ falist_destroy LIST3 + $ falist_destroy LIST4 + + $ check_no_alist_artifacts \ No newline at end of file
