From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id C72A51581D3 for ; Wed, 22 May 2024 01:12:35 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 02FB2E2A34; Wed, 22 May 2024 01:12:27 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id D0C35E2A34 for ; Wed, 22 May 2024 01:12:26 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id BFFCF33BF29 for ; Wed, 22 May 2024 01:12:25 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 1933C1B03 for ; Wed, 22 May 2024 01:12:24 +0000 (UTC) From: "Sam James" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Sam James" Message-ID: <1716197299.3de0f4f80587a58d93eb4d67dc0d536035cbd566.sam@gentoo> Subject: [gentoo-commits] proj/gentoo-functions:master commit in: / X-VCS-Repository: proj/gentoo-functions X-VCS-Files: functions.sh test-functions X-VCS-Directories: / X-VCS-Committer: sam X-VCS-Committer-Name: Sam James X-VCS-Revision: 3de0f4f80587a58d93eb4d67dc0d536035cbd566 X-VCS-Branch: master Date: Wed, 22 May 2024 01:12:24 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 1b9d3ea4-b9bc-4c68-85a4-1c071cd27cfa X-Archives-Hash: 3df5273a47d53dcd74dd81aebba7e302 commit: 3de0f4f80587a58d93eb4d67dc0d536035cbd566 Author: Kerin Millar plushkava net> AuthorDate: Mon May 20 07:37:15 2024 +0000 Commit: Sam James gentoo org> CommitDate: Mon May 20 09:28:19 2024 +0000 URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=3de0f4f8 Render argument checking more stringent; standardise diagnostics Have esyslog(), is_older_than(), veend(), vewend() and yesno() die for invalid arguments rather than issue a warning. Have yesno() die if given no arguments, just as several other functions already do. Introduce a helper function named _throw_invalid_args() to assist. It calls upon _print_args() to safely display any offending argument(s) while also helping to standardise the diagnostics. To that end, the diagnostic messages concerning wrong argument counts have been adjusted to follow suit. Below are some examples. test-functions: is_older_than: too few arguments (got 0, expected at least 2) test-functions: is_older_than: too few arguments (got 1, expected at least 2) test-functions: esyslog: too few arguments (got 0, expected at least 2) test-functions: esyslog: too few arguments (got 1, expected at least 2) test-functions: yesno: invalid argument: 'not-a-valid-nameref' test-functions: yesno: invalid argument: '_"; set -- yes # code injection' Signed-off-by: Kerin Millar plushkava.net> functions.sh | 45 +++++++++++++++++++++++++++++++-------------- test-functions | 11 +++++------ 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/functions.sh b/functions.sh index 100bd30..c82c229 100644 --- a/functions.sh +++ b/functions.sh @@ -216,7 +216,7 @@ eqatag() { case ${arg} in [!=/]*=?*) if [ "${positional}" -eq 1 ]; then - die "eqatag: invalid argument in positional context -- ${arg}" + _throw_invalid_args eqatag "${arg}" fi set -- "$@" --arg "${arg%%=*}" "${arg#*=}" ;; @@ -228,7 +228,7 @@ eqatag() { set -- "$@" "${arg}" ;; *) - die "eqatag: invalid argument -- ${arg}" + _throw_invalid_args eqatag "${arg}" esac done shift "${argc}" @@ -263,8 +263,7 @@ esyslog() local pri tag msg if [ "$#" -lt 2 ]; then - ewarn "Too few arguments for esyslog (got $#, expected at least 2)" - return 1 + die "esyslog: too few arguments (got $#, expected at least 2)" elif yesno "${EINFO_LOG}" && hash logger 2>/dev/null; then pri=$1 tag=$2 @@ -376,8 +375,7 @@ is_older_than() local ref has_gfind if [ "$#" -lt 2 ]; then - ewarn "Too few arguments for is_older_than (got $#, expected at least 2)" - return 1 + die "is_older_than: too few arguments (got $#, expected at least 2)" elif [ -e "$1" ]; then ref=$1 else @@ -424,7 +422,7 @@ veend() if yesno "${EINFO_VERBOSE}"; then GENFUN_CALLER=veend eend "$@" elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then - ewarn "Invalid argument given to veend (the exit status code must be an integer >= 0)" + _throw_invalid_args veend "$1" else return "$1" fi @@ -435,7 +433,7 @@ vewend() if yesno "${EINFO_VERBOSE}"; then GENFUN_CALLER=vewend ewend "$@" elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then - ewarn "Invalid argument given to vewend (the exit status code must be an integer >= 0)" + _throw_invalid_args vewend "$1" else return "$1" fi @@ -449,8 +447,14 @@ vewend() # yesno() { + local arg + + if [ "$#" -eq 0 ]; then + die "yesno: too few arguments (got $#, expected 1)" + fi + arg=$1 for _ in 1 2; do - case $1 in + case ${arg} in [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0|'') return 1 ;; @@ -462,9 +466,9 @@ yesno() else # The value appears to be a legal variable name. Treat # it as a name reference and try again, once only. - eval "set -- \"\$$1\"" + eval "arg=\$$1" fi - done || vewarn "Invalid argument given to yesno (expected a boolean-like or a legal name)" + done || _throw_invalid_args yesno "$1" return 1 } @@ -481,9 +485,7 @@ _eend() if [ "$#" -eq 0 ]; then retval=0 elif ! is_int "$1" || [ "$1" -lt 0 ]; then - ewarn "Invalid argument given to ${GENFUN_CALLER} (the exit status code must be an integer >= 0)" - retval=0 - msg= + _throw_invalid_args "${GENFUN_CALLER}" "$1" else retval=$1 shift @@ -650,6 +652,21 @@ _print_args() { EOF } +# +# Prints a diganostic message concerning invalid function arguments then exits. +# The first argument shall be taken as a function identifier. The remaining +# arguments shall be safely rendered as a part of the diagnostic. +# +_throw_invalid_args() +{ + local ident plural + + ident=$1 + shift + [ "$#" -gt 1 ] && plural=s || plural= + die "${ident}: invalid argument${plural}: $(_print_args "$@")" +} + # # Determines whether the terminal on STDIN is able to report its dimensions. # Upon success, the number of columns shall be stored in genfun_cols. diff --git a/test-functions b/test-functions index 7eb5981..40beded 100755 --- a/test-functions +++ b/test-functions @@ -196,7 +196,7 @@ test_is_older_than() { callback() { shift test_description="is_older_than $(_print_args "$@")" - is_older_than "$@" + ( is_older_than "$@" ) } iterate_tests 4 "$@" @@ -239,18 +239,17 @@ test_esyslog() { logger() { # esyslog() ignores empty messages. By overriding logger(1), it # can be determined whether a message would have been logged. - logged=$((logged + 1)) + printf '1\n' } callback() { should_log=$2 shift 2 - logged=0 test_description="esyslog $(_print_args "$@")" - EINFO_LOG=1 esyslog "$@" 2>/dev/null + logged=$(EINFO_LOG=1 esyslog "$@") case $? in 0) - test "${logged}" -eq "${should_log}" + test "${logged:-0}" -eq "${should_log}" ;; *) return "$?" @@ -393,7 +392,7 @@ test_yesno() { callback() { shift test_description="yesno $(_print_args "$@")" - yesno "$@" + ( yesno "$@" ) } iterate_tests 3 "$@"