public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-25  4:06 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-25  4:06 UTC (permalink / raw
  To: gentoo-commits

commit:     3194b89d3043b9c1581203c7e07301281357585b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun 24 23:43:41 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Jun 25 01:17:09 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=3194b89d

Add the trueof_all() and trueof_any() functions

These functions allow for it to be determined whether an arbitrary
simple command yields true for either all of an arbitrary list of
parameters or at least one of them. The simple command shall be given
each parameter, one at a time. Some examples are shown below.

trueof_all test -d -- /          /var/empty # returns 0
trueof_all test -d -- /          /dev/null  # returns 1
trueof_any test -d -- /          /dev/null  # returns 0
trueof_any test -d -- /etc/fstab /dev/null  # returns 1

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 test-functions | 44 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

diff --git a/functions.sh b/functions.sh
index 9336174..afc170a 100644
--- a/functions.sh
+++ b/functions.sh
@@ -454,6 +454,70 @@ trim()
 	sed -e 's/^[[:space:]]\{1,\}//' -e 's/[[:space:]]\{1,\}$//'
 }
 
+#
+# Considers the parameters up to - but not including - a sentinel value as the
+# words comprising a simple command then determines whether said command
+# succeeds for all of the remaining parameters, passing them one at a time. If
+# the SENTINEL variable is set, it shall be taken as the value of the sentinel.
+# Otherwise, the value of the sentinel shall be defined as <hyphen-dash>
+# <hyphen-dash>. If the composed command is empty, the sentinel value is not
+# encountered or there are no parameters following the sentinel, the return
+# value shall be greater than 0.
+#
+trueof_all()
+{
+	local arg arg_idx i j
+
+	arg_idx=0
+	i=0
+	j=0
+	for arg; do
+		if [ "$(( arg_idx += 1 ))" -eq 1 ]; then
+			set --
+		fi
+		if [ "$i" -gt 1 ]; then
+			"$@" "${arg}" || return
+			j=${arg_idx}
+		elif [ "${arg}" = "${SENTINEL-"--"}" ]; then
+			i=${arg_idx}
+		else
+			set -- "$@" "${arg}"
+		fi
+	done
+	test "$i" -gt 1 && test "$j" -gt "$i"
+}
+
+#
+# Considers the parameters up to - but not including - a sentinel value as the
+# words comprising a simple command then determines whether said command
+# succeeds for at least one of the remaining parameters, passing them one at a
+# time. If the SENTINEL variable is set, it shall be taken as the value of the
+# sentinel. Otherwise, the value of the sentinel shall be defined as
+# <hyphen-dash> <hyphen-dash>. If the composed command is empty, the sentinel
+# value is not encountered or there are no parameters following the sentinel,
+# the return value shall be greater than 0.
+#
+trueof_any()
+{
+	local arg arg_idx i
+
+	arg_idx=0
+	i=0
+	for arg; do
+		if [ "$(( arg_idx += 1 ))" -eq 1 ]; then
+			set --
+		fi
+		if [ "$i" -gt 1 ]; then
+			"$@" "${arg}" && return
+		elif [ "${arg}" = "${SENTINEL-"--"}" ]; then
+			i=${arg_idx}
+		else
+			set -- "$@" "${arg}"
+		fi
+	done
+	false
+}
+
 #
 # Prints a diagnostic message prefixed with the basename of the running script.
 #

diff --git a/test-functions b/test-functions
index d086e16..13be61c 100755
--- a/test-functions
+++ b/test-functions
@@ -622,6 +622,48 @@ test_is_subset() {
 	iterate_tests 7 "$@"
 }
 
+test_trueof_all() {
+	set -- \
+		ge  1  N/A   N/A  N/A  N/A        N/A        \
+		ge  1  test  -d   N/A  N/A        N/A        \
+		ge  1  test  -d   --   N/A        N/A        \
+		ge  1  test  -d   --   /dev/null  N/A        \
+		ge  1  test  -d   --   /dev/null  /dev/null  \
+		eq  0  test  -d   --   /          N/A        \
+		eq  0  test  -d   --   /          /          \
+		ge  1  test  -d   --   /          /dev/null  \
+		ge  1  test  -d   --   /dev/null  /
+
+	callback() {
+		shift
+		test_description="trueof_all $(quote_args "$@")"
+		trueof_all "$@"
+	}
+
+	iterate_tests 7 "$@"
+}
+
+test_trueof_any() {
+	set -- \
+		ge  1  N/A   N/A  N/A  N/A        N/A        \
+		ge  1  test  -d   N/A  N/A        N/A        \
+		ge  1  test  -d   --   N/A        N/A        \
+		ge  1  test  -d   --   /dev/null  N/A        \
+		ge  1  test  -d   --   /dev/null  /dev/null  \
+		eq  0  test  -d   --   /          N/A        \
+		eq  0  test  -d   --   /          /          \
+		eq  0  test  -d   --   /          /dev/null  \
+		eq  0  test  -d   --   /dev/null  /
+
+	callback() {
+		shift
+		test_description="trueof_any $(quote_args "$@")"
+		trueof_any "$@"
+	}
+
+	iterate_tests 7 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -694,6 +736,8 @@ test_whenceforth || rc=1
 test_parallel_run || rc=1
 test_is_anyof || rc=1
 test_is_subset || rc=1
+test_trueof_all || rc=1
+test_trueof_any || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  7:25 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  7:25 UTC (permalink / raw
  To: gentoo-commits

commit:     30c14c84cc144032d40d9807e332c1770fcbc778
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sat Oct  5 07:25:04 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Oct  5 07:25:04 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=30c14c84

meson.build: prepare for gentoo-functions-1.7.3

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 66b492a..bcb4705 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project(
   'gentoo-functions', 'c',
-  version: '1.7.2',
+  version: '1.7.3',
   license: 'GPL-2.0-only',
   default_options : [
     'warning_level=2',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     cfd3bd51ba0e619835e531fff6e2c71214600ee4
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Aug 20 20:30:58 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Aug 22 19:37:46 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=cfd3bd51

Document that the pipefail option is unsupported

This is worth mentioning because POSIX-1.2024 (Issue 8) introduces
pipefail as a standard feature.

https://austingroupbugs.net/view.php?id=789

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/functions.sh b/functions.sh
index 2e2916b..2414612 100644
--- a/functions.sh
+++ b/functions.sh
@@ -12,9 +12,9 @@
 # The functions shall be compatible with the POSIX-1.2018 Shell and Utilities
 # (XCU), except where otherwise noted and with the exception that the use of
 # the local utility is permitted, despite the results of its invocation being
-# formally unspecified. Should either of the errexit and nounset options be
-# enabled in the shell, the behaviour of gentoo-functions as a whole shall be
-# unspecified.
+# formally unspecified. Should any of the errexit, pipefail or nounset options
+# be enabled in the shell, the behaviour of gentoo-functions as a whole shall
+# be unspecified.
 
 # The following variables affect initialisation and/or function behaviour.
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     d0ac19c92c6dd72a585b8d4bc76b6fde6e74680f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Aug 13 12:57:19 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Aug 22 19:37:46 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d0ac19c9

Disable shellcheck SC2153

SC2153 is informational in nature and triggers only for environment
variables (all uppercase variables) whose names are similar to others
and for which no explicit assignment can be observed. In the case of
gentoo-functions, it was being raised as a result of KSH_VERSION and
YASH_VERSION being expanded. In other words, it is a nuisance.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 871d846..57dfbb6 100644
--- a/functions.sh
+++ b/functions.sh
@@ -1,6 +1,6 @@
 # Copyright 1999-2024 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
-# shellcheck shell=sh disable=2209,3013,3043
+# shellcheck shell=sh disable=2153,2209,3013,3043
 
 # This file contains a series of function declarations followed by some
 # initialisation code. Functions intended for internal use shall be prefixed


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     d51d103cb345d3ba96af3c4b5bba9eeb13fe55f7
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Aug 13 03:36:37 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Aug 21 12:36:27 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d51d103c

Check for SRANDOM support in a safer manner

Given that the SRANDOM variable loses its special properties if unset,
to compare two expansions of it to one another ought to be more robust.
Do so up to three times, so as not to be foiled by the unlikely event of
the RNG repeating the same number.

Further, the prior check was defective because it incorrectly presumed
the minimum required version of bash to be 5.0 rather than 5.1.

Fixes: 5ee035a364bea8d12bc8abfe769014e230a212a6
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 37ac8c2..a47bb2b 100644
--- a/functions.sh
+++ b/functions.sh
@@ -575,7 +575,20 @@ quote_args()
 srandom()
 {
 	# shellcheck disable=3028
-	if [ "${BASH_VERSINFO:-0}" -ge 5 ]; then
+	_has_srandom()
+	{
+		# The SRANDOM variable was introduced by bash 5.1. Check for at
+		# least 5.0, letting the alternate branch confirm its efficacy.
+		if [ "${BASH_VERSINFO-0}" -lt 5 ]; then
+			false
+		else
+			for _ in 1 2 3; do
+				test "${SRANDOM}" != "${SRANDOM}" && break
+			done
+		fi
+	}
+
+	if _has_srandom; then
 		srandom()
 		{
 			printf '%d\n' "$(( SRANDOM >> 1 ))"
@@ -625,6 +638,7 @@ srandom()
 		return 1
 	fi
 
+	unset -f _has_srandom
 	srandom
 }
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     116645c35885a32b994e49794aa60e9c8216ba9b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Aug 14 06:23:25 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Aug 22 19:37:46 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=116645c3

Have whenceforth() work around a word splitting bug in OpenBSD sh

Consider the case where IFS consists of a single character whose value
is neither <space>, <tab> nor <newline>. The following example employs
the colon, since it is the character that the whenceforth() function
relies upon during word splitting.

$ bash -c 'IFS=":"; path=":"; set -- $path; echo "$# ${1@Q}"'
1 ''

The result is very much as expected because the colon in path serves as
a terminator for an empty field. Now, let's consider how many fields are
produced in OpenBSD sh as a consequence of word splitting.

$ sh -c 'IFS=":"; path=":"; set -- $path; echo "$#"'
0

For the time being, work around it by having whenceforth() repeat the
field terminator for the affected edge cases, which are two in number.
With this change, the test suite is now able to pass for:

- loksh 7.5
- oksh 7.5
- sh (OpenBSD 7.5)

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 6cf7439..1a87100 100644
--- a/functions.sh
+++ b/functions.sh
@@ -759,7 +759,15 @@ whenceforth()
 			# Relative command paths must be searched for in PATH.
 			# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03
 			case ${PATH} in
-				''|*:)
+				''|:)
+					# Work around a bug in OpenBSD sh and
+					# its ports. Where IFS has a value of
+					# ":", splitting a word having the same
+					# value produces no words at all. Handle
+					# it by repeating the field terminator.
+					path=::
+					;;
+				*:)
 					path=${PATH}:
 					;;
 				*)


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     ce39d2261967db9fbb7a78c0e1dca4a24a05f8b1
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Aug 13 11:18:28 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Aug 22 19:37:46 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=ce39d226

Put braces around the expansion of the path variable

In accordance with the Gentoo style.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/functions.sh b/functions.sh
index b19831d..871d846 100644
--- a/functions.sh
+++ b/functions.sh
@@ -349,7 +349,7 @@ newest()
 			# dash, FreeBSD sh and NetBSD sh are known to be
 			# non-conforming in this respect.
 			if { [ ! "${newest}" ] && [ -e "${path}" ]; } || [ "${path}" -nt "${newest}" ]; then
-				newest=$path
+				newest=${path}
 			fi
 		done
 		test "${newest}" && printf '%s\n' "${newest}"
@@ -359,7 +359,7 @@ newest()
 		{
 		while IFS= read -r path; do
 			if { [ ! "${newest}" ] && [ -e "${path}" ]; } || [ "${path}" -nt "${newest}" ]; then
-				newest=$path
+				newest=${path}
 			fi
 		done
 		test "${newest}" && printf '%s\n' "${newest}"
@@ -421,7 +421,7 @@ oldest()
 			if [ ! -e "${path}" ]; then
 				continue
 			elif [ ! "${oldest}" ] || [ "${path}" -ot "${oldest}" ]; then
-				oldest=$path
+				oldest=${path}
 			fi
 		done
 		test "${oldest}" && printf '%s\n' "${oldest}"
@@ -433,7 +433,7 @@ oldest()
 			if [ ! -e "${path}" ]; then
 				continue
 			elif [ ! "${oldest}" ] || [ "${path}" -ot "${oldest}" ]; then
-				oldest=$path
+				oldest=${path}
 			fi
 		done
 		test "${oldest}" && printf '%s\n' "${oldest}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     c4db6fbdb626865063943a4b969c887211ab393f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug 16 06:27:58 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Aug 22 19:37:46 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=c4db6fbd

Warn upon sourcing if errexit or nounset be enabled

I am unwilling to pander to those that elect to enable either of the
errexit or nounset options. Rather than gloss over the matter, comment
as to the behaviour of gentoo-functions being unspecified in that event.
Further, display a warning for each of those options found to be enabled
at the time of sourcing functions.sh.

It is worth noting that the behaviour of nounset can be selectively
employed with the ${parameter:?} form of parameter expansion. Such is
occasionally useful and does not require for library authors to
acquiesce to the cult of the "unofficial strict mode".

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/functions.sh b/functions.sh
index 8180182..2e2916b 100644
--- a/functions.sh
+++ b/functions.sh
@@ -10,9 +10,11 @@
 # and to reduce the probability of name space conflicts.
 
 # The functions shall be compatible with the POSIX-1.2018 Shell and Utilities
-# (XCU), except where otherwise noted, and with the additional exception that
-# the use of the local utility is permitted, despite the results of its
-# invocation being formally unspecified.
+# (XCU), except where otherwise noted and with the exception that the use of
+# the local utility is permitted, despite the results of its invocation being
+# formally unspecified. Should either of the errexit and nounset options be
+# enabled in the shell, the behaviour of gentoo-functions as a whole shall be
+# unspecified.
 
 # The following variables affect initialisation and/or function behaviour.
 
@@ -43,6 +45,16 @@ warn()
 	printf '%s: %s\n' "${0##*/}" "$*" >&2
 }
 
+case $- in *e*)
+	# https://lists.gnu.org/archive/html/help-bash/2020-04/msg00049.html
+	warn "gentoo-functions does not support the errexit option; unexpected behaviour may ensue"
+esac
+
+case $- in *u*)
+	# https://lists.gnu.org/archive/html/help-bash/2020-04/msg00049.html
+	warn "gentoo-functions does not support the nounset option; unexpected behaviour may ensue"
+esac
+
 case ${KSH_VERSION} in 'Version AJM 93'*)
 	# The ksh93 shell has a typeset builtin but no local builtin.
 	warn "gentoo-functions does not currently support ksh93"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     f60b038e3ae789d01b38eb44ed15dc44ad78bf7c
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Aug 17 18:25:22 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Aug 22 19:37:46 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f60b038e

Double quote a ${parameter+word} expansion in defer()

Doing so protects against the following scenario.

$ IFS=e word=1
$ set -x; test ${word+set}
+ test s t
dash: 2: test: s: unexpected operator

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 3dd2969..8180182 100644
--- a/functions.sh
+++ b/functions.sh
@@ -175,7 +175,7 @@ deref()
 	elif ! trueof_all is_identifier -- "$@"; then
 		_warn_for_args deref "$@"
 		false
-	elif ! eval "test \${$1+set}"; then
+	elif ! eval "test \"\${$1+set}\""; then
 		false
 	elif [ "$#" -eq 1 ]; then
 		eval "printf '%s\\n' \"\$$1\""


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     b51db5ffb23808dcddf93bdbdfaf3a5ee0e391cc
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Aug 13 02:08:59 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Aug 21 12:36:19 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b51db5ff

Reduce the two non-bash srandom() implementations to just one

The implementation of srandom() that was written with mksh first and
foremost in mind is no longer as slow as it was. I decided to benchmark
30,000 iterations of both of the non-bash implementations with varying
maximal pool sizes. The results are beneath. Note that both "dash/1" and
"mksh/1" refer to the mksh-targeting implementation.

Pool Size  dash/1   dash/2    mksh/1
     48 B   6.67s    5.57s    58.84s
     64 B   5.39s    4.78s    58.20s
     96 B   5.49s    4.36s    58.13s
    128 B   5.87s    4.63s    59.94s
    160 B   5.93s    5.46s    64.64s

These figures demonstrate that the optimal pool size is roughly between
64 and 96 bytes, and that the performance of both implementations is now
comparable. In addition to testing Linux (6.6) on x86_64 hardware, I
experimented with the pool size on macOS Sonoma (using an Apple M1 CPU)
and found a value of 64 to be close to optimal.

In view of these findings, have _collect_entropy() collect 64 bytes at a
time and remove the marginally faster implementation. That is, the one
that depended on being able to perform arithmetic on a number as high as
2^32-1 without overflowing.

Additionally, increase the maximum number of times that the remaining
implementation tries to find a suitable sequence of hex digits from 2 to
3. Finally, remove the overflow check, for it is no longer required.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 53 ++++++++++++-----------------------------------------
 1 file changed, 12 insertions(+), 41 deletions(-)

diff --git a/functions.sh b/functions.sh
index 4598c5b..37ac8c2 100644
--- a/functions.sh
+++ b/functions.sh
@@ -580,12 +580,9 @@ srandom()
 		{
 			printf '%d\n' "$(( SRANDOM >> 1 ))"
 		}
-	elif [ -c /dev/urandom ] && [ "$(( 1 << 31 == -2147483648 ))" -eq 1 ]; then
-		# The shell implements integers as signed int rather than
-		# signed long, contrary to the specification. Therefore, bit
-		# shifting cannot be a viable strategy. Instead, try to discern
-		# a suitably constrained sequence of 8 hex digits.
-
+	elif [ -c /dev/urandom ]; then
+		# Employ a method which entails searching for 8 consecutive hex
+		# digits, where the first is between 0 and 7.
 		genfun_int32_pat='[0-7][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]'
 		unset -v genfun_entropy
 
@@ -594,7 +591,7 @@ srandom()
 			local hex i slice
 
 			# If the shell has forked, or if it cannot be determined
-			# whether it has done so, repopulate the pool with 256
+			# whether it has done so, populate the pool with 64
 			# bytes worth of fresh entropy.
 			if ! _update_pid; then
 				_collect_entropy
@@ -603,7 +600,7 @@ srandom()
 				eval "genfun_pool_${genfun_pid}=1"
 			fi || return
 
-			for i in 1 2; do
+			for i in 1 2 3; do
 				# shellcheck disable=2295
 				slice=${genfun_entropy%${genfun_int32_pat}*}
 				if [ "${#slice}" -ne "${#genfun_entropy}" ]; then
@@ -613,10 +610,9 @@ srandom()
 						hex=${hex%?}
 					done
 					break
-				elif [ "$i" -eq 1 ]; then
-					# The pool is too small to contain a
-					# suitable sequence. Refill then try
-					# again.
+				elif [ "$i" -lt 3 ]; then
+					# The pool does not contain a suitable
+					# sequence. Refill it then try again.
 					_collect_entropy
 				else
 					false
@@ -624,31 +620,6 @@ srandom()
 			done &&
 			printf '%d\n' "0x${hex}"
 		}
-	elif [ -c /dev/urandom ]; then
-		unset -v genfun_entropy
-
-		srandom()
-		{
-			local hex
-
-			if ! _update_pid; then
-				# It cannot be determined whether the shell has
-				# forked. Generate a number from 4 bytes worth
-				# of fresh entropy.
-				hex=$(LC_ALL=C od -vAn -N4 -tx1 /dev/urandom | tr -d '[:space:]')
-				test "${#hex}" -eq 8 && printf '%d\n' "$(( 0x${hex} >> 1 ))"
-				return
-			elif [ "${#genfun_entropy}" -lt 8 ] || ! eval "test \"\${genfun_pool_${genfun_pid}+set}\""; then
-				# Either the pool is too small or the shell has
-				# forked. Repopulate the pool with 256 bytes
-				# worth of fresh entropy.
-				_collect_entropy || return
-				eval "genfun_pool_${genfun_pid}=1"
-			fi
-			hex=${genfun_entropy}
-			genfun_entropy=${genfun_entropy%????????}
-			printf '%d\n' "$(( 0x${hex#"$genfun_entropy"} >> 1 ))"
-		}
 	else
 		warn "srandom: /dev/urandom doesn't exist as a character device"
 		return 1
@@ -799,12 +770,12 @@ whenceforth()
 #------------------------------------------------------------------------------#
 
 #
-# Collects 256 bytes worth of entropy from /dev/urandom and assigns it to the
-# genfun_entropy variable in the form of 512 hex digits.
+# Collects 64 bytes worth of entropy from /dev/urandom and assigns it to the
+# genfun_entropy variable in the form of 128 hex digits.
 #
 _collect_entropy() {
-	genfun_entropy=$(LC_ALL=C od -vAn -N256 -tx1 /dev/urandom | tr -d '[:space:]')
-	test "${#genfun_entropy}" -eq 512
+	genfun_entropy=$(LC_ALL=C od -vAn -N64 -tx1 /dev/urandom | tr -d '[:space:]')
+	test "${#genfun_entropy}" -eq 128
 }
 
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     f77a397df8c2a623a296600ee38a01dbdd98933b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Aug 17 15:42:41 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Aug 22 19:37:46 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f77a397d

Optimise trim() for bash where processing the positional parameters

Render trim() faster in bash for cases where only the positional
parameters are to be processed e.g. var=$(trim "$var") or
var=${ trim "$var"; }.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index bd96df6..3dd2969 100644
--- a/functions.sh
+++ b/functions.sh
@@ -650,12 +650,21 @@ srandom()
 #
 trim()
 {
-	if [ "$#" -gt 0 ]; then
-		printf '%s\n' "$@"
+	local arg
+
+	if [ "$#" -gt 0 ] && [ "${BASH}" ]; then
+		for arg; do
+			eval '[[ ${arg} =~ ^[[:space:]]+ ]] && arg=${arg:${#BASH_REMATCH}}'
+			eval '[[ ${arg} =~ [[:space:]]+$ ]] && arg=${arg:0:${#arg} - ${#BASH_REMATCH}}'
+			printf '%s\n' "${arg}"
+		done
 	else
-		cat
-	fi |
-	sed -e 's/^[[:space:]]\{1,\}//' -e 's/[[:space:]]\{1,\}$//'
+		if [ "$#" -gt 0 ]; then
+			printf '%s\n' "$@"
+		else
+			cat
+		fi | sed -e 's/^[[:space:]]\{1,\}//' -e 's/[[:space:]]\{1,\}$//'
+	fi
 }
 
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     b0a71d9aa9b0506eabde36fde85f384af5283267
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Aug 13 13:15:07 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Aug 22 19:37:46 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b0a71d9a

Print a diagnostic message if no modules can be found

The ability to locate and source the modules depends on the
genfun_basedir variable being set correctly. In the case that no modules
can be found, print a useful diagnostic message and ensure that the
return value is non-zero.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 57dfbb6..6cf7439 100644
--- a/functions.sh
+++ b/functions.sh
@@ -1060,7 +1060,10 @@ fi
 
 # Source any modules that have been selected by the GENFUN_MODULES variable.
 for _ in "${genfun_basedir}/functions"/*.sh; do
-	if _want_module "$_"; then
+	if ! test -e "$_"; then
+		warn "no gentoo-functions modules were found (genfun_basedir might be set incorrectly)"
+		! break
+	elif _want_module "$_"; then
 		. "$_" || return
 	fi
 done


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     416fb79902e8ea42421c563076de39b3d3048f0f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Aug 12 19:41:01 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Aug 21 12:24:01 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=416fb799

Use an entropy pool in srandom(), even if the shell has forked

Presently, there are two srandom() implementations that do not require
bash, one of which is intended for use with mksh and the other of which
is intended for the various other implementations of sh(1). Both of
these implementations are capable of maintaining an entropy pool, which
markedly enhances performance for repeated invocations of the function.
However, the pool cannot be effectively utilised in cases where the
shell has forked.

$ srandom              # initialises the pool
$ srandom              # reads from the now-initialised pool
$ ( srandom )          # may fork, rendering the pool rather ineffective
$ ( srandom; srandom ) # ditto, despite the consecutive calls

This commit addresses the discrepancy by keeping track of whether the
pool has been populated on a per-PID basis. Consider the following
benchmark, in which the loop is forced to execute within a subshell
environment.

(
  i=0
  while [ $((i+=1)) -le 30000 ]; do srandom; done >/dev/null
  /bin/true
)

As conducted with mksh 59c on a system with a 2nd generation Intel Xeon,
I obtained the following figures.

BEFORE

real    3m8.857s
user    2m57.276s
sys     0m59.511s

AFTER

real    1m24.047s
user    1m6.435s
sys     0m19.565s

As conducted with dash on the same system, I obtained the following
figures.

BEFORE

real    0m52.056s
user    1m2.913s
sys     0m18.143s

AFTER

real    0m12.887s
user    0m12.521s
sys     0m1.016s

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 43 ++++++++++++++++++++++---------------------
 1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/functions.sh b/functions.sh
index 454c62d..4598c5b 100644
--- a/functions.sh
+++ b/functions.sh
@@ -593,11 +593,15 @@ srandom()
 		{
 			local hex i slice
 
-			# If the shell is understood to have potentially forked
-			# itself then collect fresh entropy from the outset.
-			if ! _update_pid || [ "$$" != "${genfun_pid}" ]; then
+			# If the shell has forked, or if it cannot be determined
+			# whether it has done so, repopulate the pool with 256
+			# bytes worth of fresh entropy.
+			if ! _update_pid; then
 				_collect_entropy
-			fi
+			elif ! eval "test \"\${genfun_pool_${genfun_pid}+set}\""; then
+				_collect_entropy &&
+				eval "genfun_pool_${genfun_pid}=1"
+			fi || return
 
 			for i in 1 2; do
 				# shellcheck disable=2295
@@ -627,27 +631,23 @@ srandom()
 		{
 			local hex
 
-			# If the shell is understood to have potentially forked
-			# itself then collect 4 bytes worth of entropy.
-			if ! _update_pid || [ "$$" != "${genfun_pid}" ]; then
+			if ! _update_pid; then
+				# It cannot be determined whether the shell has
+				# forked. Generate a number from 4 bytes worth
+				# of fresh entropy.
 				hex=$(LC_ALL=C od -vAn -N4 -tx1 /dev/urandom | tr -d '[:space:]')
 				test "${#hex}" -eq 8 && printf '%d\n' "$(( 0x${hex} >> 1 ))"
 				return
+			elif [ "${#genfun_entropy}" -lt 8 ] || ! eval "test \"\${genfun_pool_${genfun_pid}+set}\""; then
+				# Either the pool is too small or the shell has
+				# forked. Repopulate the pool with 256 bytes
+				# worth of fresh entropy.
+				_collect_entropy || return
+				eval "genfun_pool_${genfun_pid}=1"
 			fi
-
-			# Otherwise, employ a faster method whereby the shell
-			# maintains an entropy pool of up to 512 hex digits in
-			# size.
-			if [ "${#genfun_entropy}" -lt 8 ]; then
-				_collect_entropy
-			fi
-			if [ "${#genfun_entropy}" -lt 8 ]; then
-				false
-			else
-				hex=${genfun_entropy}
-				genfun_entropy=${genfun_entropy%????????}
-				printf '%d\n' "$(( 0x${hex#"$genfun_entropy"} >> 1 ))"
-			fi
+			hex=${genfun_entropy}
+			genfun_entropy=${genfun_entropy%????????}
+			printf '%d\n' "$(( 0x${hex#"$genfun_entropy"} >> 1 ))"
 		}
 	else
 		warn "srandom: /dev/urandom doesn't exist as a character device"
@@ -804,6 +804,7 @@ whenceforth()
 #
 _collect_entropy() {
 	genfun_entropy=$(LC_ALL=C od -vAn -N256 -tx1 /dev/urandom | tr -d '[:space:]')
+	test "${#genfun_entropy}" -eq 512
 }
 
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     f36877ecf039c53ba43ca4ebcc8c465412d12fd6
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Aug 13 12:44:19 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Aug 22 19:37:43 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f36877ec

Check for EPOCHREALTIME support in a safer manner

Given that the EPOCHREALTIME variable loses its special properties if
unset, to compare two expansions of it to one another ought to be more
robust.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index a47bb2b..b19831d 100644
--- a/functions.sh
+++ b/functions.sh
@@ -940,7 +940,7 @@ _update_pid()
 _update_time()
 {
 	# shellcheck disable=3028
-	if [ "${BASH_VERSINFO:-0}" -ge 5 ]; then
+	if [ "${EPOCHREALTIME}" != "${EPOCHREALTIME}" ]; then
 		# shellcheck disable=2034,3045
 		_update_time()
 		{


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     aabfa913c30b184e7a2a89156aafb5e281ea4c27
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug 16 07:09:09 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Aug 22 19:37:46 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=aabfa913

Move an SC2317 exemption closer to where it is needed

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 1a87100..bd96df6 100644
--- a/functions.sh
+++ b/functions.sh
@@ -836,11 +836,11 @@ fi
 # whether fewer have elapsed since the last occasion on which the function was
 # called, or whether the last genfun_time update resulted in integer overflow.
 #
-# shellcheck disable=2317
 _should_throttle()
 {
 	_update_time || return
 
+	# shellcheck disable=2317
 	_should_throttle()
 	{
 		_update_time || return


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     4d72028326dfea6d8360dad441e80cd52cafb5b9
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Aug 11 17:47:25 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Aug 17 16:16:17 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=4d720283

Abort sourcing for ksh93

In the case of ksh93, the commonly implemented behaviour of "local" can
be approximated with "typeset". However, to use typeset in this way
requires the use of the function f { ...; } syntax instead of the
POSIX-compatible f() compound-command syntax. As things stand, there is
no sense in allowing for functions.sh to be sourced by ksh93.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/functions.sh b/functions.sh
index 1c8721f..b618054 100644
--- a/functions.sh
+++ b/functions.sh
@@ -24,6 +24,7 @@
 # GENFUN_MODULES   : which of the optional function collections must be sourced
 # IFS              : warn() operands are joined by its first character
 # INVOCATION_ID    : used by from_unit()
+# KSH_VERSION      : used to detect ksh93, which is currently unsupported
 # PORTAGE_BIN_PATH : used by from_portage()
 # POSIXLY_CORRECT  : if unset/empty, quote_args() may emit dollar-single-quotes
 # RC_OPENRC_PID    : used by from_runscript()
@@ -42,6 +43,12 @@ warn()
 	printf '%s: %s\n' "${0##*/}" "$*" >&2
 }
 
+case ${KSH_VERSION} in 'Version AJM 93'*)
+	# The ksh93 shell has a typeset builtin but no local builtin.
+	warn "gentoo-functions does not currently support ksh93"
+	return 1
+esac
+
 if [ "${YASH_VERSION}" ] && set +o | grep -qxF 'set -o posixlycorrect'; then
 	# The yash shell disables the local builtin in its POSIXly-correct mode.
 	warn "gentoo-functions does not support yash in posixlycorrect mode"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     e9e8c66c681b980668a8e9225bf8ec19135b9acc
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Aug 11 18:37:44 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Aug 17 16:16:36 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=e9e8c66c

Ensure that LC_ALL is exported in srandom(); be safer for macOS

The slowest implementation of srandom() runs od(1) and awk(1) within a
command substitution. There, both LC_ALL and LC_CTYPE are overridden but
they should also be exported.

For now, export LC_ALL=C exclusively, even though it overrides
LC_MESSAGES, potentially affecting the user's preferred language for
diagnostics. The reason for choosing this course of action is as
follows.

$ uname
Darwin
$ echo "$BASH_VERSION"
5.2.26(1)-release
$ f() { nonexistent; }; $ ( export LC_ALL=; f )
objc[29971]: +[__SwiftNativeNSStringBase initialize] may have been in
progress in another thread when fork() was called.
objc[29971]: +[__SwiftNativeNSStringBase initialize] may have been in
progress in another thread when fork() was called. We cannot safely call
it or ignore it in the fork() child process. Crashing instead. Set a
breakpoint on objc_initializeAfterForkError to debug.

A fix for this is present in the devel branch:

- https://git.savannah.gnu.org/cgit/bash.git/commit/?h=devel&id=b3d8c8a

See, also:

- https://trac.macports.org/ticket/68638
- https://lists.gnu.org/archive/html/bug-bash/2024-05/msg00088.html

Of course, the fix hasn't been backported to an actual release. As such,
I would prefer to play it safe for the time being.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index 8b7896f..406fe7f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -590,8 +590,7 @@ srandom()
 			local hex
 
 			hex=$(
-				LC_ALL=
-				LC_CTYPE=C
+				export LC_ALL=C
 				od -vAn -N256 -tx1 /dev/urandom | awk '
 					{
 						gsub(/[[:space:]]/, "")


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     977cdf1ba863e599abcf2cc80cbd719cb3b0f67e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Aug 12 10:19:10 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Aug 17 16:16:36 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=977cdf1b

Use an entropy pool for the mksh-targeting srandom() implementation

The slowest of the the three srandom() implementations is presently
selected for shells that overflow numbers at the 2^31 mark. A prominent
shell which does so is mksh (even for LP64 architectures).

Recently, one of the other srandom() implementations was accelerated by
having the shell maintain its own entropy pool of up to 512 hex digits
in size. Make it so that the mksh-targeting implementation employs a
similar technique. Consider the following benchmark.

i=0; while [ $((i += 1)) -le 30000 ]; do srandom; done >/dev/null

As conducted with mksh 59c on a system with a 2nd generation Intel Xeon,
I obtained the following figures.

BEFORE

real    0m56.414s
user    0m47.043s
sys     0m24.751s

AFTER

real    0m28.900s
user    0m22.795s
sys     0m6.802s

Note that the performance increase cannot be applied in all situations.
For further details regarding the constraints, refer to commit 866af9c.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 71 ++++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 45 insertions(+), 26 deletions(-)

diff --git a/functions.sh b/functions.sh
index 406fe7f..454c62d 100644
--- a/functions.sh
+++ b/functions.sh
@@ -581,30 +581,43 @@ srandom()
 			printf '%d\n' "$(( SRANDOM >> 1 ))"
 		}
 	elif [ -c /dev/urandom ] && [ "$(( 1 << 31 == -2147483648 ))" -eq 1 ]; then
-		# The shell implements integers as signed int rather than signed
-		# long, contrary to the specification. Therefore, bit shifting
-		# cannot be a viable strategy. Instead, use awk to generate a
-		# number that is immediately within range.
+		# The shell implements integers as signed int rather than
+		# signed long, contrary to the specification. Therefore, bit
+		# shifting cannot be a viable strategy. Instead, try to discern
+		# a suitably constrained sequence of 8 hex digits.
+
+		genfun_int32_pat='[0-7][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]'
+		unset -v genfun_entropy
+
 		srandom()
 		{
-			local hex
+			local hex i slice
 
-			hex=$(
-				export LC_ALL=C
-				od -vAn -N256 -tx1 /dev/urandom | awk '
-					{
-						gsub(/[[:space:]]/, "")
-						hex = hex $0
-					}
-					END {
-						if (match(hex, /[0-7][[:xdigit:]]{7}/)) {
-							print substr(hex, RSTART, RLENGTH)
-						} else {
-							exit 1
-						}
-					}
-				'
-			) &&
+			# If the shell is understood to have potentially forked
+			# itself then collect fresh entropy from the outset.
+			if ! _update_pid || [ "$$" != "${genfun_pid}" ]; then
+				_collect_entropy
+			fi
+
+			for i in 1 2; do
+				# shellcheck disable=2295
+				slice=${genfun_entropy%${genfun_int32_pat}*}
+				if [ "${#slice}" -ne "${#genfun_entropy}" ]; then
+					hex=${genfun_entropy#"$slice"}
+					genfun_entropy=${genfun_entropy%"$hex"}
+					while [ "${#hex}" -gt 8 ]; do
+						hex=${hex%?}
+					done
+					break
+				elif [ "$i" -eq 1 ]; then
+					# The pool is too small to contain a
+					# suitable sequence. Refill then try
+					# again.
+					_collect_entropy
+				else
+					false
+				fi
+			done &&
 			printf '%d\n' "0x${hex}"
 		}
 	elif [ -c /dev/urandom ]; then
@@ -614,8 +627,8 @@ srandom()
 		{
 			local hex
 
-			# If the shell has forked itself, collect 4 bytes worth
-			# of entropy.
+			# If the shell is understood to have potentially forked
+			# itself then collect 4 bytes worth of entropy.
 			if ! _update_pid || [ "$$" != "${genfun_pid}" ]; then
 				hex=$(LC_ALL=C od -vAn -N4 -tx1 /dev/urandom | tr -d '[:space:]')
 				test "${#hex}" -eq 8 && printf '%d\n' "$(( 0x${hex} >> 1 ))"
@@ -626,9 +639,7 @@ srandom()
 			# maintains an entropy pool of up to 512 hex digits in
 			# size.
 			if [ "${#genfun_entropy}" -lt 8 ]; then
-				genfun_entropy=$(
-					LC_ALL=C od -vAn -N256 -tx1 /dev/urandom | tr -d '[:space:]'
-				)
+				_collect_entropy
 			fi
 			if [ "${#genfun_entropy}" -lt 8 ]; then
 				false
@@ -787,6 +798,14 @@ whenceforth()
 
 #------------------------------------------------------------------------------#
 
+#
+# Collects 256 bytes worth of entropy from /dev/urandom and assigns it to the
+# genfun_entropy variable in the form of 512 hex digits.
+#
+_collect_entropy() {
+	genfun_entropy=$(LC_ALL=C od -vAn -N256 -tx1 /dev/urandom | tr -d '[:space:]')
+}
+
 #
 # Determines whether the terminal is a dumb one.
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     324bb9eda0989e39f4afe94e019c521fb3c0d377
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Aug 11 17:29:42 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Aug 17 16:16:36 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=324bb9ed

test-functions: do not check that genfun_time is greater than -1

In point of fact, it can be expected to overflow sometimes. Especially
if running mksh.

Fixes: 52f551e5a01ab030c131c2e7f196a8a76235583d
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-functions b/test-functions
index 51f3adf..16f9481 100755
--- a/test-functions
+++ b/test-functions
@@ -1111,7 +1111,7 @@ test_update_time() {
 		fi
 		case $? in
 			0)
-				is_int "${genfun_time}" && test "${genfun_time}" -ge 0
+				is_int "${genfun_time}"
 				;;
 			2)
 				# Unsupported for the platform and therefore untestable.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     7e0ce224c81eef7959aedb787d1512c61631a63f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Aug 11 17:09:19 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Aug 17 16:16:36 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7e0ce224

Explicitly initialise a local variable in _update_pid()

I normally always do this for local variables that may immediately be
checked for emptiness or non-emptiness, owing to the formally
unspecified behaviour of the local command.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/functions.sh b/functions.sh
index b618054..8b7896f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -905,6 +905,7 @@ _update_pid()
 		{
 			local dir tid
 
+			tid=
 			for dir in /proc/self/task/*/; do
 				if [ "${tid}" ] || [ ! -e "${dir}" ]; then
 					return 1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-10-05  4:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-10-05  4:15 UTC (permalink / raw
  To: gentoo-commits

commit:     9550ec3e9bbb6ffa996db5c4da889413588f7689
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Aug 11 17:02:50 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Aug 16 06:36:53 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9550ec3e

Abort sourcing for yash in posixlycorrect mode

The yash shell takes conformance so seriously that it goes as far as to
disable the local builtin in its posixlycorrect mode.

https://magicant.github.io/yash/doc/posix.html

$ yash -o posixlycorrect -c 'f() { local var; }; f'
yash: local: non-portable built-in is not supported in the POSIXly-correct mode

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/functions.sh b/functions.sh
index 733e4e9..1c8721f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -30,9 +30,24 @@
 # SENTINEL         : can define a value separating two distinct argument lists
 # SYSTEMD_EXEC_PID : used by from_unit()
 # TERM             : used to detect dumb terminals
+# YASH_VERSION     : for detecting yash before checking for incompatible options
 
 #------------------------------------------------------------------------------#
 
+#
+# Prints a diagnostic message prefixed with the basename of the running script.
+#
+warn()
+{
+	printf '%s: %s\n' "${0##*/}" "$*" >&2
+}
+
+if [ "${YASH_VERSION}" ] && set +o | grep -qxF 'set -o posixlycorrect'; then
+	# The yash shell disables the local builtin in its POSIXly-correct mode.
+	warn "gentoo-functions does not support yash in posixlycorrect mode"
+	return 1
+fi
+
 #
 # Considers the first parameter as a reference to a variable by name and
 # assigns the second parameter as its value. If the first parameter is found
@@ -705,14 +720,6 @@ trueof_any()
 	false
 }
 
-#
-# Prints a diagnostic message prefixed with the basename of the running script.
-#
-warn()
-{
-	printf '%s: %s\n' "${0##*/}" "$*" >&2
-}
-
 #
 # Considers the first parameter as a command name before trying to locate it as
 # a regular file. If not specified as an absolute pathname, a PATH search shall


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:23 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:23 UTC (permalink / raw
  To: gentoo-commits

commit:     76ece84815b56cebb7714cde85e650ffa3b27733
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sun Aug 11 10:22:43 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:22:43 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=76ece848

meosn.build: prepare for gentoo-functions-1.7.2

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 10a9f32..66b492a 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project(
   'gentoo-functions', 'c',
-  version: '1.7.1',
+  version: '1.7.2',
   license: 'GPL-2.0-only',
   default_options : [
     'warning_level=2',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     6ee0913b255b36c6fef503564bb26b56ee4c3268
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Aug 10 05:59:00 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:04 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6ee0913b

test-functions: don't increment testnum by 2 for test_ebegin()

Also, restore the correct test_description string, which was being lost
in a subshell.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/test-functions b/test-functions
index 28c72da..81593b8 100755
--- a/test-functions
+++ b/test-functions
@@ -109,14 +109,16 @@ test_die() {
 test_ebegin() {
 	set -- eq 0
 
-	callback() (
+	callback() {
 		test_description="ebegin message (expecting terminating newline)"
-		_eprint() {
-			shift
-			_ends_with_newline "$*"
-		}
-		ebegin "message"
-	)
+		(
+			_eprint() {
+				shift
+				_ends_with_newline "$*"
+			}
+			ebegin "message"
+		)
+	}
 
 	iterate_tests 2 "$@"
 }
@@ -1200,7 +1202,7 @@ elif ! GENFUN_MODULES="portage rc" . ./functions.sh; then
 else
 	assign_tmpdir
 	test_chdir || rc=1
-	test_ebegin || rc=1; testnum=$((testnum + 1))
+	test_ebegin || rc=1
 	test_is_older_than || rc=1
 	test_get_bootparam || rc=1
 	test_esyslog || rc=1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     739c62e4d8be2425c676026843a0a4c07f2f2dd1
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Aug 10 05:42:01 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:03 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=739c62e4

test-functions: comment as to why test_quote_args() fails for yash

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/test-functions b/test-functions
index 0ab203b..28c72da 100755
--- a/test-functions
+++ b/test-functions
@@ -957,6 +957,12 @@ test_quote_args() {
 
 		test_description="quote_args output test (expecting cksum 380900690)"
 		i=0
+		# The generator fails to produce the correct ouput in yash
+		# unless the effective character type is C/POSIX. However, once
+		# launched, yash ignores assignments to the LC_CTYPE variable
+		# if in its posix mode. As things stand, there is little point
+		# in fixing it because yash also disables the local builtin in
+		# its posix mode, causing test-functions to bail out sooner.
 		while [ "$((i += 1))" -le 255 ]; do
 			fmt=$(printf '\\%o' "$i")
 			# shellcheck disable=2059


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     866af9c1fe47529bdefa02cd0e3eccfea2bebd2b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Aug 10 08:34:25 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:05 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=866af9c1

Render the non-bash srandom() implementation faster

Presently, there are three implementations of srandom(), one of which is
the preferred implementation for shells other than bash. It is a little
on the slow side as it has to fork and execute both od(1) and tr(1)
every time, just to read 4 bytes. Accelerate it by having the shell
maintain its own entropy pool of up to 512 hex digits in size. Consider
the following benchmark.

i=0; while [ $((i += 1)) -le 30000 ]; do srandom; done >/dev/null

As conducted with dash on a system with a 2nd generation Intel Xeon, I
obtained the following figures.

BEFORE

real    0m49.878s
use     1m1.985s
sys     0m17.035s

AFTER

real    0m12.866s
user    0m12.559s
sys     0m0.962s

It should be noted that the optimised routine will only be utilised in
cases where the kernel is Linux and the shell has not forked itself.

$ uname
Linux
$ srandom                       # uses the fast path
$ number=$(srandom)             # subshell; probably uses the slow path
$ srandom | { read -r number; } # ditto

Still, there are conceivable use cases for which this optimisation may
prove useful. Below is an example in which it is known in advance that
up to 100 random numbers are required, and where writing them to
temporary storage is not considered to be a risk.

i=0
tmpfile=${TMPDIR:-/tmp}/random-numbers.$$.$(srandom)
while [ $((i += 1)) -le 100 ]; do
	srandom
done > "$tmpfile"
while read -r number; do
	do_something_with "$number"
done < "$tmpfile"

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh   | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 test-functions | 44 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 109 insertions(+), 4 deletions(-)

diff --git a/functions.sh b/functions.sh
index 38eef62..733e4e9 100644
--- a/functions.sh
+++ b/functions.sh
@@ -18,7 +18,7 @@
 
 # BASH             : whether bash-specific features may be employed
 # BASH_VERSINFO    : whether bash-specific features may be employed
-# BASHPID          : may be used by _update_columns() to detect subshells
+# BASHPID          : may be used by _update_columns() and _update_pid()
 # COLUMNS          : may be used by _update_columns() to get the column count
 # EPOCHREALTIME    : potentially used by _update_time() to get the time
 # GENFUN_MODULES   : which of the optional function collections must be sourced
@@ -587,12 +587,35 @@ srandom()
 			printf '%d\n' "0x${hex}"
 		}
 	elif [ -c /dev/urandom ]; then
+		unset -v genfun_entropy
+
 		srandom()
 		{
 			local hex
 
-			hex=$(LC_ALL=C od -vAn -N4 -tx1 /dev/urandom | tr -d '[:space:]')
-			[ "${hex}" ] && printf '%d\n' "$(( 0x${hex} >> 1 ))"
+			# If the shell has forked itself, collect 4 bytes worth
+			# of entropy.
+			if ! _update_pid || [ "$$" != "${genfun_pid}" ]; then
+				hex=$(LC_ALL=C od -vAn -N4 -tx1 /dev/urandom | tr -d '[:space:]')
+				test "${#hex}" -eq 8 && printf '%d\n' "$(( 0x${hex} >> 1 ))"
+				return
+			fi
+
+			# Otherwise, employ a faster method whereby the shell
+			# maintains an entropy pool of up to 512 hex digits in
+			# size.
+			if [ "${#genfun_entropy}" -lt 8 ]; then
+				genfun_entropy=$(
+					LC_ALL=C od -vAn -N256 -tx1 /dev/urandom | tr -d '[:space:]'
+				)
+			fi
+			if [ "${#genfun_entropy}" -lt 8 ]; then
+				false
+			else
+				hex=${genfun_entropy}
+				genfun_entropy=${genfun_entropy%????????}
+				printf '%d\n' "$(( 0x${hex#"$genfun_entropy"} >> 1 ))"
+			fi
 		}
 	else
 		warn "srandom: /dev/urandom doesn't exist as a character device"
@@ -848,6 +871,46 @@ _update_columns()
 	_update_columns
 }
 
+#
+# Determines the PID of the current shell process. Upon success, the PID shall
+# be assigned to genfun_pid. Otherwise, the return value shall be greater than
+# 0. The obtained PID value will differ from the value of $$ under certain
+# circumstances, such as where a shell forks itself to create a subshell.
+#
+_update_pid()
+{
+	if [ "${BASH}" ]; then
+		_update_pid()
+		{
+			# shellcheck disable=3028
+			genfun_pid=${BASHPID}
+		}
+	elif [ -d /proc/self/task ]; then
+		# This method relies on the proc_pid_task(5) interface of Linux.
+		_update_pid()
+		{
+			local dir tid
+
+			for dir in /proc/self/task/*/; do
+				if [ "${tid}" ] || [ ! -e "${dir}" ]; then
+					return 1
+				else
+					dir=${dir%/}
+					tid=${dir##*/}
+				fi
+			done
+			genfun_pid=${tid}
+		}
+	else
+		_update_pid()
+		{
+			false
+		}
+	fi
+
+	_update_pid
+}
+
 #
 # Determines either the number of centiseconds elapsed since the unix epoch or
 # the number of centiseconds that the operating system has been online,

diff --git a/test-functions b/test-functions
index fe26905..51f3adf 100755
--- a/test-functions
+++ b/test-functions
@@ -454,6 +454,44 @@ test_srandom() {
 	iterate_tests 2 "$@"
 }
 
+test_srandom_forked()
+{
+	set -- \
+		eq  0  unforked  \
+		eq  0  forking
+
+	callback() {
+		local mode number
+
+		shift
+		mode=$1
+		set --
+		test_description="srandom equality where $mode"
+		if [ "${mode}" = "forking" ]; then
+			srandom
+			( srandom )
+			srandom
+			( srandom )
+		else
+			srandom
+			srandom
+			srandom
+			srandom
+		fi > random_numbers || return
+		while read -r number; do
+			set -- "$@" "${number}"
+		done < random_numbers
+		test_description="srandom equality where $mode ($*)"
+		if [ "${mode}" = "forking" ]; then
+			test "$#" -eq 4 && test "$1" -ne "$2" && test "$3" -ne "$4"
+		else
+			test "$#" -eq 4 && ! trueof_all test "$1" -eq -- "$@"
+		fi
+	}
+
+	iterate_tests 3 "$@"
+}
+
 test_newest() {
 	set -- \
 		ge  1  non-existent  non-existent  \
@@ -1212,7 +1250,11 @@ else
 	test_yesno || rc=1
 	test_die || rc=1
 	test_edo || rc=1
-	test_srandom || rc=1
+	if ! test_srandom; then
+		rc=1
+	else
+		test_srandom_forked || rc=1
+	fi
 	test_newest || rc=1
 	test_oldest || rc=1
 	test_trim || rc=1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     ca559d4a6713958ede1d2720316ff567e3c1eb01
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Aug 10 06:42:44 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:04 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=ca559d4a

Exempt _should_throttle() from shellcheck SC2317

The _should_throttle() function gets the best of shellcheck, which
incorrectly reports that there is unreachable code.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/functions.sh b/functions.sh
index 43ea385..eff7f5f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -787,6 +787,7 @@ fi
 # whether fewer have elapsed since the last occasion on which the function was
 # called, or whether the last genfun_time update resulted in integer overflow.
 #
+# shellcheck disable=2317
 _should_throttle()
 {
 	_update_time || return


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     29c0a982c1a0c7c985d02fc8833eff16036e8366
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Aug 10 06:08:05 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:04 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=29c0a982

test-functions: consistently align the test parameter declarations

This is merely a whitespace cleanup.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 264 ++++++++++++++++++++++++++++-----------------------------
 1 file changed, 132 insertions(+), 132 deletions(-)

diff --git a/test-functions b/test-functions
index 81593b8..fe26905 100755
--- a/test-functions
+++ b/test-functions
@@ -84,9 +84,9 @@ test_chdir() {
 
 test_die() {
 	set -- \
-		eq    1    0 \
-		eq    2    2 \
-		eq  126  126 \
+		eq    1    0  \
+		eq    2    2  \
+		eq  126  126  \
 		eq  255  255
 
 	callback() {
@@ -141,59 +141,59 @@ test_is_older_than() {
 	local age tstamp
 
 	set -- \
-		ge  1  N/A           N/A \
-		ge  1  newer         N/A \
-		ge  1  newer-empty   N/A \
-		ge  1  newer/file    N/A \
-		ge  1  non-existent  N/A \
-		eq  0  newer         newer \
-		ge  1  newer         newer-empty \
-		eq  0  newer         newer/file \
-		ge  1  newer         non-existent \
-		ge  1  newer         older \
-		ge  1  newer         older-empty \
-		ge  1  newer         older/file \
-		eq  0  newer-empty   newer \
-		ge  1  newer-empty   newer-empty \
-		eq  0  newer-empty   newer/file \
-		ge  1  newer-empty   non-existent \
-		ge  1  newer-empty   older \
-		ge  1  newer-empty   older-empty \
-		ge  1  newer-empty   older/file \
-		ge  1  newer/file    newer \
-		ge  1  newer/file    newer-empty \
-		ge  1  newer/file    newer/file \
-		ge  1  newer/file    non-existent \
-		ge  1  newer/file    older \
-		ge  1  newer/file    older-empty \
-		ge  1  newer/file    older/file \
-		eq  0  non-existent  newer \
-		eq  0  non-existent  newer-empty \
-		eq  0  non-existent  newer/file \
-		ge  1  non-existent  non-existent \
-		eq  0  non-existent  older \
-		eq  0  non-existent  older-empty \
-		eq  0  non-existent  older/file \
-		eq  0  older         newer \
-		eq  0  older         newer-empty \
-		eq  0  older         newer/file \
-		ge  1  older         non-existent \
-		eq  0  older         older \
-		ge  1  older         older-empty \
-		eq  0  older         older/file \
-		eq  0  older-empty   newer \
-		eq  0  older-empty   newer-empty \
-		eq  0  older-empty   newer/file \
-		ge  1  older-empty   non-existent \
-		eq  0  older-empty   older \
-		ge  1  older-empty   older-empty \
-		eq  0  older-empty   older/file \
-		eq  0  older/file    newer \
-		eq  0  older/file    newer-empty \
-		eq  0  older/file    newer/file \
-		ge  1  older/file    non-existent \
-		ge  1  older/file    older \
-		ge  1  older/file    older-empty \
+		ge  1  N/A           N/A           \
+		ge  1  newer         N/A           \
+		ge  1  newer-empty   N/A           \
+		ge  1  newer/file    N/A           \
+		ge  1  non-existent  N/A           \
+		eq  0  newer         newer         \
+		ge  1  newer         newer-empty   \
+		eq  0  newer         newer/file    \
+		ge  1  newer         non-existent  \
+		ge  1  newer         older         \
+		ge  1  newer         older-empty   \
+		ge  1  newer         older/file    \
+		eq  0  newer-empty   newer         \
+		ge  1  newer-empty   newer-empty   \
+		eq  0  newer-empty   newer/file    \
+		ge  1  newer-empty   non-existent  \
+		ge  1  newer-empty   older         \
+		ge  1  newer-empty   older-empty   \
+		ge  1  newer-empty   older/file    \
+		ge  1  newer/file    newer         \
+		ge  1  newer/file    newer-empty   \
+		ge  1  newer/file    newer/file    \
+		ge  1  newer/file    non-existent  \
+		ge  1  newer/file    older         \
+		ge  1  newer/file    older-empty   \
+		ge  1  newer/file    older/file    \
+		eq  0  non-existent  newer         \
+		eq  0  non-existent  newer-empty   \
+		eq  0  non-existent  newer/file    \
+		ge  1  non-existent  non-existent  \
+		eq  0  non-existent  older         \
+		eq  0  non-existent  older-empty   \
+		eq  0  non-existent  older/file    \
+		eq  0  older         newer         \
+		eq  0  older         newer-empty   \
+		eq  0  older         newer/file    \
+		ge  1  older         non-existent  \
+		eq  0  older         older         \
+		ge  1  older         older-empty   \
+		eq  0  older         older/file    \
+		eq  0  older-empty   newer         \
+		eq  0  older-empty   newer-empty   \
+		eq  0  older-empty   newer/file    \
+		ge  1  older-empty   non-existent  \
+		eq  0  older-empty   older         \
+		ge  1  older-empty   older-empty   \
+		eq  0  older-empty   older/file    \
+		eq  0  older/file    newer         \
+		eq  0  older/file    newer-empty   \
+		eq  0  older/file    newer/file    \
+		ge  1  older/file    non-existent  \
+		ge  1  older/file    older         \
+		ge  1  older/file    older-empty   \
 		ge  1  older/file    older/file
 
 	# The mtimes need to be explicitly assigned. Empirical evidence has
@@ -222,17 +222,17 @@ test_get_bootparam() {
 
 	cmdline="foo gentoo=bar,baz quux"
 	set -- \
-		ge  1  "${cmdline}"                   N/A \
-		ge  1  "${cmdline}"                   '' \
-		ge  1  "gentoo="                      '' \
-		ge  1  "${cmdline}"                   foo \
-		eq  0  "${cmdline}"                   bar \
-		eq  0  "foo gentoo=gentoo=1,bar baz"  bar \
-		eq  0  "foo gentoo=bar,gentoo=1 baz"  bar \
-		eq  0  "${cmdline}"                   baz \
-		ge  1  "${cmdline}"                   bar,baz \
-		eq  0  "foo gentoo=bar,gentoo=1 baz"  gentoo=1 \
-		eq  0  "foo gentoo=gentoo=1,bar baz"  gentoo=1 \
+		ge  1  "${cmdline}"                   N/A       \
+		ge  1  "${cmdline}"                   ''        \
+		ge  1  "gentoo="                      ''        \
+		ge  1  "${cmdline}"                   foo       \
+		eq  0  "${cmdline}"                   bar       \
+		eq  0  "foo gentoo=gentoo=1,bar baz"  bar       \
+		eq  0  "foo gentoo=bar,gentoo=1 baz"  bar       \
+		eq  0  "${cmdline}"                   baz       \
+		ge  1  "${cmdline}"                   bar,baz   \
+		eq  0  "foo gentoo=bar,gentoo=1 baz"  gentoo=1  \
+		eq  0  "foo gentoo=gentoo=1,bar baz"  gentoo=1  \
 		ge  1  "${cmdline}"                   quux
 
 	callback() {
@@ -249,10 +249,10 @@ test_get_bootparam() {
 
 test_esyslog() {
 	set -- \
-		ge  1  0  N/A    N/A   N/A \
-		ge  1  0  debug  N/A   N/A \
-		eq  0  0  debug  user  N/A \
-		eq  0  0  debug  user  '' \
+		ge  1  0  N/A    N/A   N/A      \
+		ge  1  0  debug  N/A   N/A      \
+		eq  0  0  debug  user  N/A      \
+		eq  0  0  debug  user  ''       \
 		eq  0  1  debug  user  message
 
 	logger() {
@@ -295,7 +295,7 @@ test_is_identifier() {
 		ge  1   /Z   \
 		ge  1   .a   \
 		ge  1   .Z   \
-		ge  1  '[a'   \
+		ge  1  '[a'  \
 		ge  1  '[Z'  \
 		ge  1  '`a'  \
 		ge  1  '`Z'  \
@@ -346,18 +346,18 @@ test_is_identifier() {
 
 test_is_int() {
 	set -- \
-		ge  1  N/A \
-		ge  1  ' ' \
-		ge  1  ' 1 ' \
-		ge  1  '' \
-		ge  1  +1 \
-		ge  1  +008 \
-		ge  1  -008 \
-		ge  1  008 \
-		ge  1  x \
-		eq  0  0 \
-		eq  0  1 \
-		eq  0  -1 \
+		ge  1  N/A        \
+		ge  1  ' '        \
+		ge  1  ' 1 '      \
+		ge  1  ''         \
+		ge  1  +1         \
+		ge  1  +008       \
+		ge  1  -008       \
+		ge  1  008        \
+		ge  1  x          \
+		eq  0  0          \
+		eq  0  1          \
+		eq  0  -1         \
 		eq  0  123456789
 
 	callback() {
@@ -371,13 +371,13 @@ test_is_int() {
 
 test_is_visible() {
 	set -- \
-		ge  1  '' \
-		ge  1  ' ' \
-		ge  1  "$(printf '\t')" \
-		ge  1  "$(printf '\a')" \
-		eq  0  . \
-		eq  0  ' . ' \
-		eq  0  "$(printf '\t.\t')" \
+		ge  1  ''                   \
+		ge  1  ' '                  \
+		ge  1  "$(printf '\t')"     \
+		ge  1  "$(printf '\a')"     \
+		eq  0  .                    \
+		eq  0  ' . '                \
+		eq  0  "$(printf '\t.\t')"  \
 		eq  0  "$(printf '\a.\a')"
 
 	callback() {
@@ -391,29 +391,29 @@ test_is_visible() {
 
 test_yesno() {
 	set -- \
-		eq  0  yes \
-		eq  0  YES \
-		eq  0  Yes \
-		eq  0  true \
-		eq  0  TRUE \
-		eq  0  true \
-		eq  0  on \
-		eq  0  ON \
-		eq  0  On \
-		eq  0  1 \
-		eq  0  truthful_nameref \
-		ge  1  no \
-		ge  1  NO \
-		ge  1  No \
-		ge  1  false \
-		ge  1  FALSE \
-		ge  1  False \
-		ge  1  off \
-		ge  1  OFF \
-		ge  1  Off \
-		ge  1  0 \
-		ge  1  not_a_nameref \
-		ge  1  not-a-valid-nameref \
+		eq  0  yes                                \
+		eq  0  YES                                \
+		eq  0  Yes                                \
+		eq  0  true                               \
+		eq  0  TRUE                               \
+		eq  0  true                               \
+		eq  0  on                                 \
+		eq  0  ON                                 \
+		eq  0  On                                 \
+		eq  0  1                                  \
+		eq  0  truthful_nameref                   \
+		ge  1  no                                 \
+		ge  1  NO                                 \
+		ge  1  No                                 \
+		ge  1  false                              \
+		ge  1  FALSE                              \
+		ge  1  False                              \
+		ge  1  off                                \
+		ge  1  OFF                                \
+		ge  1  Off                                \
+		ge  1  0                                  \
+		ge  1  not_a_nameref                      \
+		ge  1  not-a-valid-nameref                \
 		ge  1  '_"; set -- yes # code injection'
 
 	# shellcheck disable=2034
@@ -430,16 +430,16 @@ test_yesno() {
 
 test_srandom() {
 	set -- \
-		eq 0 \
-		eq 0 \
-		eq 0 \
-		eq 0 \
-		eq 0 \
-		eq 0 \
-		eq 0 \
-		eq 0 \
-		eq 0 \
-		eq 0
+		eq  0  \
+		eq  0  \
+		eq  0  \
+		eq  0  \
+		eq  0  \
+		eq  0  \
+		eq  0  \
+		eq  0  \
+		eq  0  \
+		eq  0
 
 	callback() {
 		local number
@@ -621,7 +621,7 @@ test_hr() {
 		eq  0  "$(printf '%80s' | tr ' ' -)"  -    N/A  \
 		eq  0  ''                             -    0    \
 		eq  0  -                              -    1    \
-		eq  0  -----------------              -    17    \
+		eq  0  -----------------              -    17   \
 		eq  0  ''                             xyz  0    \
 		eq  0  x                              xyz  1    \
 		eq  0  xxxxxxxxxxxxxxxxx              xyz  17
@@ -1117,13 +1117,13 @@ test_should_throttle() {
 	# return value should always be 1. For the fifth test, integer overflow
 	# is expected to occur. Again, the return value should always be 1.
 	set -- \
-		ge  1  "${max_int}" \
-		eq  0  2            \
-		ge  1  1            \
-		ge  1  0            \
-		ge  1  2            \
-		eq  0  2            \
-		ge  1  1            \
+		ge  1  "${max_int}"  \
+		eq  0  2             \
+		ge  1  1             \
+		ge  1  0             \
+		ge  1  2             \
+		eq  0  2             \
+		ge  1  1             \
 		ge  1  0
 
 	_update_time() {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     414feeebda73ef58c07a411596569372bbcc19c8
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Aug  8 08:54:43 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:10:59 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=414feeeb

test-functions: silence several shellcheck false-positives

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/test-functions b/test-functions
index 00a128a..275d32f 100755
--- a/test-functions
+++ b/test-functions
@@ -1,5 +1,5 @@
 #!/bin/sh
-# shellcheck disable=1007,2015,2164,2317,3043
+# shellcheck disable=1007,2015,2031,2164,2317,3043
 
 # Requires mktemp(1), which is not a standard utility, but is commonly
 # available. The implementations provided by GNU coreutils, busybox and toybox
@@ -265,6 +265,7 @@ test_esyslog() {
 		should_log=$2
 		shift 2
 		test_description="esyslog $(quote_args "$@")"
+		# shellcheck disable=2034
 		logged=$(EINFO_LOG=1; esyslog "$@")
 		case $? in
 			0)
@@ -694,6 +695,7 @@ test_whenceforth() {
 				case ${printf_cmd} in
 					/*) printf() { "${printf_cmd}" "$@"; }
 				esac
+				# shellcheck disable=2030
 				PATH=${path}
 				whenceforth "$@" >/dev/null
 			)


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     2f32e4a026a1d45bfc8223f55bb8913f2d455ec5
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Aug  8 09:28:03 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:00 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2f32e4a0

test-functions: choose a better variable name for storing the temp dir

The name, dir, is rather generic. Rename it to global_tmpdir to diminish
the likelihood of an accidental name space conflict.

Also, don't pass the -f option to rm(1) at the point that the directory
is to be removed.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/test-functions b/test-functions
index 275d32f..1f54208 100755
--- a/test-functions
+++ b/test-functions
@@ -12,14 +12,14 @@ bailout() {
 }
 
 assign_tmpdir() {
-	dir=$(mktemp -d) \
-	&& chdir "${dir}" \
+	global_tmpdir=$(mktemp -d) \
+	&& chdir "${global_tmpdir}" \
 	|| bailout "Couldn't create or change to the temp dir"
 }
 
 cleanup_tmpdir() {
-	if [ -n "${dir}" ]; then
-		rm -rf -- "${dir}"
+	if [ "${global_tmpdir}" ]; then
+		rm -r -- "${global_tmpdir}"
 	fi
 }
 
@@ -1103,7 +1103,7 @@ iterate_tests() {
 
 printf 'TAP version 13\n'
 
-unset -v dir
+unset -v global_tmpdir
 
 # PATH is redefined to prevent ebuild-helpers such as die from interfering.
 export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/opt/pkg/bin


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     52d8b440df4e68c9c3dfdea7f3142b1641f2b08e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug  9 07:22:10 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:01 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=52d8b440

Render _update_time() a no-op for the yash shell

When integer overflow occurs in a non-interactive yash shell, it prints
"yash: arithmetic: overflow" as a diagnostic message before proceeding
to exit. That makes it extremely difficult for the arithmetic in the
_should_throttle() function to be implemented safely for it. For now,
ensure that _update_time() does nothing for yash but return a non-zero
status code. In turn, this disables the rate limiting feature for yash.

Additionally, refrain from running test_update_time() and
test_should_throttle() for yash in test-functions. The former would only
amount to a waste of time and the latter would be guaranteed to fail.

For the record, my testing was performed with yash 2.56.1.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh   |  3 ++-
 test-functions | 12 ++++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index e7ef6fe..641deb6 100644
--- a/functions.sh
+++ b/functions.sh
@@ -846,7 +846,8 @@ _update_time()
 			fi
 			genfun_time=$(( s * 100 + cs ))
 		}
-	elif [ -f /proc/uptime ]; then
+	elif [ -f /proc/uptime ] && [ ! "${YASH_VERSION}" ]; then
+		# Yash is blacklisted because it dies upon integer overflow.
 		_update_time()
 		{
 			local cs s

diff --git a/test-functions b/test-functions
index 34ffc41..c96ac48 100755
--- a/test-functions
+++ b/test-functions
@@ -1024,6 +1024,12 @@ test_deref() {
 test_update_time() {
 	local locale
 
+	# The yash shell dies upon integer overflow and _update_time() ends up
+	# being deactivated for it. Hence, there is no reason to run this test.
+	if [ "${YASH_VERSION}" ]; then
+		return
+	fi
+
 	set -- \
 		de_BE de_DE es_ES fr_BE fr_CA fr_FR it_IT nl_BE nl_NL pl_PL \
 		pt_BR pt_PT ru_RU sv_SE
@@ -1072,6 +1078,12 @@ test_update_time() {
 test_should_throttle() {
 	local bits max_int
 
+	# The yash shell dies upon integer overflow and _update_time() ends up
+	# being deactivated for it. Hence, there is no reason to run this test.
+	if [ "${YASH_VERSION}" ]; then
+		return
+	fi
+
 	genfun_time=
 	bits=30
 	while [ "${bits}" -lt 128 ]; do


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     2a0259ec7d5d3095221854dbf89f6ead435c592d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Aug  8 08:56:49 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:00 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2a0259ec

Implement a variant of quote_args() optimised for bash

Add the quote_args_bash() function, which will be called from
quote_args() under the appropriate circumstances. It is faster than the
sh implementation, not merely because it takes advantage of the
${parameter@Q} form of parameter expansion, but also because executing
external utilities exacts a greater performance toll for bash than it
does for, say, dash. The difference is appreciable if running the test
suite.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/functions.sh b/functions.sh
index 1c55b3d..a111f12 100644
--- a/functions.sh
+++ b/functions.sh
@@ -407,6 +407,12 @@ parallel_run()
 #
 quote_args()
 {
+	# Call into a bash-optimised implementation where appropriate.
+	# shellcheck disable=3028
+	if [ ! "${POSIXLY_CORRECT}" ] && [ "${BASH_VERSINFO-0}" -ge 5 ]; then
+		quote_args_bash "$@"
+		return
+	fi
 	LC_ALL=C awk -v q=\' -f - -- "$@" <<-'EOF'
 	function init_table() {
 		# Iterate over ranges \001-\037 and \177-\377.
@@ -462,6 +468,26 @@ quote_args()
 	EOF
 }
 
+# shellcheck disable=3028
+if [ "${BASH_VERSINFO-0}" -ge 5 ]; then
+	# Note that the ${parameter@Q} form of expansion is supported as of
+	# bash 4.4. However, it is simpler to test for 5.0 or greater in sh.
+	eval '
+		quote_args_bash() {
+			local IFS=" " args i
+
+			(( $# > 0 )) || return 0
+			args=("${@@Q}")
+			for i in "${!args[@]}"; do
+				if [[ ${args[i]} == \$* ]]; then
+					args[i]=${args[i]//\\E/\\e}
+				fi
+			done
+			printf "%s\\n" "${args[*]}"
+		}
+	'
+fi
+
 #
 # Generates a random number between 0 and 2147483647 (2^31-1) with the
 # assistance of the kernel CSPRNG. Upon success, the number shall be printed to


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     b6e0ded26d8aad17e6af1cf799f7165d943e88a3
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug  9 08:12:15 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:02 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b6e0ded2

test-functions: account for the potential absence of test(1) as a builtin

Presently, the test_whenceforth() function potects itself from being
adversely affected by printf(1) not being a builtin utility. Consider
the following test.

PATH=.
whenceforth -x newer/file

Owing to the modification of PATH, it becomes impossible to execute any
of the standard utilities unless they happen to be builtins. The
workaround is to temporarily define printf as a function which duly
executes the external utility.

Having run the test suite with the yash shell, it has served as a sharp
reminder that one cannot assume that test(1) is always available as a
builtin either. In fact, yash implements test(1) as a "substitutative
built-in command". Below is the relevant material from its manual.

- https://magicant.github.io/yash/doc/builtin.html#types
- https://magicant.github.io/yash/doc/exec.html#search
- https://magicant.github.io/yash/doc/index.html#builtins

It is a curious thing, to say the least. Essentially, substitutative
builtins can only be used for as long as an executable of the same name
can be found in PATH. Since the purpose of test_whenceforth() is not to
directly evaluate the behaviour of the test(1) utility, this commit
implements the same safeguard for test(1) as is present for printf(1).

Signed-off-by: Kerin Millar <kfm <AT> plushava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/test-functions b/test-functions
index c96ac48..7c848c1 100755
--- a/test-functions
+++ b/test-functions
@@ -687,14 +687,17 @@ test_whenceforth() {
 		else
 			test_description="PATH=${path} whenceforth $(quote_args "$@")"
 			(
-				# If necessary, conduct the test with a printf
-				# function in effect, duly covering shells that
-				# do not implement it as a builtin. Otherwise,
-				# it could become unavailable on account of the
-				# various values of PATH being tested.
+				# If necessary, declare functions to cover the
+				# utilities that might otherwise be unavailable
+				# on account of the various values of PATH
+				# being tested. It cannot be assumed that the
+				# utilities in question are builtins.
 				case ${printf_cmd} in
 					/*) printf() { "${printf_cmd}" "$@"; }
 				esac
+				case ${test_cmd} in
+					/*) test() { "${test_cmd}" "$@"; }
+				esac
 				# shellcheck disable=2030
 				PATH=${path}
 				whenceforth "$@" >/dev/null
@@ -703,6 +706,7 @@ test_whenceforth() {
 	}
 
 	printf_cmd=$(command -v printf)
+	test_cmd=$(command -v test)
 	iterate_tests 5 "$@"
 }
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     8b747094a6444a02631706922ee572493ed4caab
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Aug  8 17:06:08 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:00 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=8b747094

Rename quote_args_bash() to _quote_args_bash()

For it need not be in the public name space.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 45 ++++++++++++++++++++++++---------------------
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/functions.sh b/functions.sh
index a111f12..78830c6 100644
--- a/functions.sh
+++ b/functions.sh
@@ -410,7 +410,7 @@ quote_args()
 	# Call into a bash-optimised implementation where appropriate.
 	# shellcheck disable=3028
 	if [ ! "${POSIXLY_CORRECT}" ] && [ "${BASH_VERSINFO-0}" -ge 5 ]; then
-		quote_args_bash "$@"
+		_quote_args_bash "$@"
 		return
 	fi
 	LC_ALL=C awk -v q=\' -f - -- "$@" <<-'EOF'
@@ -468,26 +468,6 @@ quote_args()
 	EOF
 }
 
-# shellcheck disable=3028
-if [ "${BASH_VERSINFO-0}" -ge 5 ]; then
-	# Note that the ${parameter@Q} form of expansion is supported as of
-	# bash 4.4. However, it is simpler to test for 5.0 or greater in sh.
-	eval '
-		quote_args_bash() {
-			local IFS=" " args i
-
-			(( $# > 0 )) || return 0
-			args=("${@@Q}")
-			for i in "${!args[@]}"; do
-				if [[ ${args[i]} == \$* ]]; then
-					args[i]=${args[i]//\\E/\\e}
-				fi
-			done
-			printf "%s\\n" "${args[*]}"
-		}
-	'
-fi
-
 #
 # Generates a random number between 0 and 2147483647 (2^31-1) with the
 # assistance of the kernel CSPRNG. Upon success, the number shall be printed to
@@ -731,6 +711,29 @@ _has_dumb_terminal()
 	! case ${TERM} in *dumb*) false ;; esac
 }
 
+#
+# Potentially called by quote_args(), duly acting as a bash-optimised variant.
+# It leverages the ${paramater@Q} form of expansion, which is supported as of
+# bash 4.4. However, it is simpler just to test for 5.0 or greater in sh.
+#
+# shellcheck disable=3028
+if [ "${BASH_VERSINFO-0}" -ge 5 ]; then
+	eval '
+		_quote_args_bash() {
+			local IFS=" " args i
+
+			(( $# > 0 )) || return 0
+			args=("${@@Q}")
+			for i in "${!args[@]}"; do
+				if [[ ${args[i]} == \$* ]]; then
+					args[i]=${args[i]//\\E/\\e}
+				fi
+			done
+			printf "%s\\n" "${args[*]}"
+		}
+	'
+fi
+
 #
 # See the definitions of oldest() and newest().
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     1c8a0a340de9b4e9b69e3e373bb8f55e2a1f030b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Aug  7 22:00:36 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:10:57 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1c8a0a34

test-functions: test for simple commands persisting environmental changes

Some implementations allow for alterations made to the execution
environment to persist beyond the scope of a simple command. Consider
loksh as a case in point.

$ f() { :; }
$ unset LEAKED
$ LEAKED=1 /bin/true; echo "LEAKED = $LEAKED"
LEAKED =
$ LEAKED=1      cmd2; echo "LEAKED = $LEAKED"
LEAKED = 1

Strictly speaking, such behaviour is permitted. The Shell Command
Language specification states:

"""
If the command name is a function that is not a standard utility
implemented as a function, variable assignments shall affect the current
execution environment during the execution of the function. It is
unspecified:

- Whether or not the variable assignments persist after the completion
  of the function

- Whether or not the variables gain the export attribute during the
  execution of the function

- Whether or not export attributes gained as a result of the variable
  assignments persist after the completion of the function (if variable
  assignments persist after the completion of the function)
"""

Unfortunately, loksh elects not to be aligned with the practices of the
overwhelming majority of implementations in this regard. For now, have
test-functions detect and abort for shells that go against the grain. I
shall consider reviewing and adapting gentoo-functions to account for
such unspecified behaviour but it is not an immediate priority.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/test-functions b/test-functions
index 487caa9..afc56eb 100755
--- a/test-functions
+++ b/test-functions
@@ -46,6 +46,19 @@ test_local() {
 	return "${retval}"
 }
 
+test_simple_command() {
+	f() { :; }
+	LEAKED=
+	LEAKED=1 f
+	retval=0
+	if [ "${LEAKED}" ]; then
+		printf 'not '
+		retval=1
+	fi
+	printf "ok %d - /bin/sh refrains from leaking environmental changes for simple commands\\n" "$((testnum += 1))"
+	return "${retval}"
+}
+
 test_chdir() {
 	set -- \
 		ge  1          ''  \
@@ -1071,7 +1084,7 @@ if [ "${PORTAGE_BIN_PATH}" ] && [ "${S}" ]; then
 	genfun_basedir=${S}
 fi
 
-if ! test_local; then
+if ! test_local || ! test_simple_command; then
 	rc=1
 elif ! GENFUN_MODULES="portage rc" . ./functions.sh; then
 	bailout "Couldn't source ./functions.sh"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     e28b1e4e0053c1f2827ba62eaf2da3b7b8b824de
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug  9 10:36:58 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:02 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=e28b1e4e

test-functions: comment as to the implications of test_local() failing

In particular, comment as to why the test can be expected to fail for
ksh93 and - in some cases - yash.

Signed-off-by: Kerin Millar <kfm <AT> plushava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/test-functions b/test-functions
index 7c848c1..0ab203b 100755
--- a/test-functions
+++ b/test-functions
@@ -1180,6 +1180,14 @@ if [ "${PORTAGE_BIN_PATH}" ] && [ "${S}" ]; then
 fi
 
 if ! test_local; then
+	# Currently, this test is known to fail for ksh93 and yash. As regards
+	# the former, the commonly implemented behaviour of "local" can be
+	# approximated with "typeset". However, to use typeset in this way
+	# requires the use of the function f { ...; } syntax instead of the
+	# POSIX-compatible f() compound-command syntax. Further, ksh93
+	# implements static scoping. As regards the latter, yash is rather
+	# stringent and simply disables its local builtin if in its posix mode.
+	# Running yash as "sh" would be one way of activating said mode.
 	rc=1
 elif ! GENFUN_MODULES="portage rc" . ./functions.sh; then
 	bailout "Couldn't source ./functions.sh"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     39a108d58143886c78c76fa1d9000210102624f7
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Aug  8 23:51:46 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:11:01 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=39a108d5

Handle integer overflow as a special case in _should_throttle()

At the point that the genfun_time variable overflows, guarantee that the
should_throttle() function behaves as if no throttling should occur
rather than proceed to perform arithmetic based on the result of
deducting genfun_last_time from genfun_time.

Further, guarantee that the should_throttle() function behaves as if no
throttling should occur upon the very first occasion that it is called,
provided that the call to update_time() succeeds.

Finally, add a test case.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh   | 22 +++++++++++++++-------
 test-functions | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/functions.sh b/functions.sh
index 78830c6..e7ef6fe 100644
--- a/functions.sh
+++ b/functions.sh
@@ -756,15 +756,25 @@ _select_by_mtime()
 #
 # Considers the first parameter as a number of centiseconds and determines
 # whether fewer have elapsed since the last occasion on which the function was
-# called.
+# called, or whether the last genfun_time update resulted in integer overflow.
 #
 _should_throttle()
 {
 	_update_time || return
-	if [ "$(( genfun_time - genfun_last_time > $1 ))" -eq 1 ]; then
-		genfun_last_time=${genfun_time}
-		false
-	fi
+
+	_should_throttle()
+	{
+		_update_time || return
+		if [ "$(( (genfun_time < 0 && genfun_last_time >= 0) || genfun_time - genfun_last_time > $1 ))" -eq 1 ]
+		then
+			genfun_last_time=${genfun_time}
+			false
+		fi
+
+	}
+
+	genfun_last_time=${genfun_time}
+	false
 }
 
 #
@@ -817,8 +827,6 @@ _update_columns()
 #
 _update_time()
 {
-	genfun_last_time=0
-
 	# shellcheck disable=3028
 	if [ "${BASH_VERSINFO:-0}" -ge 5 ]; then
 		# shellcheck disable=2034,3045

diff --git a/test-functions b/test-functions
index 1f54208..34ffc41 100755
--- a/test-functions
+++ b/test-functions
@@ -1069,6 +1069,52 @@ test_update_time() {
 	iterate_tests 3 "$@"
 }
 
+test_should_throttle() {
+	local bits max_int
+
+	genfun_time=
+	bits=30
+	while [ "${bits}" -lt 128 ]; do
+		# Dash is buggy and fails to handle $(( 1 << ++bits )).
+		bits=$(( bits + 1 ))
+		case $(( max_int = 1 << bits )) in
+			-*)
+				max_int=$(( max_int - 1 ))
+				genfun_time=$(( max_int - 4 ))
+				break
+		esac
+	done
+
+	if [ ! "${genfun_time}" ]; then
+		bailout "Failed to calculate the maximum possible integer value"
+	fi
+
+	# For the first test, genfun_last_time is not yet known. Therefore, the
+	# return value should always be 1. For the fifth test, integer overflow
+	# is expected to occur. Again, the return value should always be 1.
+	set -- \
+		ge  1  "${max_int}" \
+		eq  0  2            \
+		ge  1  1            \
+		ge  1  0            \
+		ge  1  2            \
+		eq  0  2            \
+		ge  1  1            \
+		ge  1  0
+
+	_update_time() {
+		true
+	}
+
+	callback() {
+		shift
+		test_description="_should_throttle $1 (${genfun_time}, $(( genfun_time += 1 )))"
+		_should_throttle "$1"
+	}
+
+	iterate_tests 3 "$@"
+}
+
 iterate_tests() {
 	local code i j passed slice_width total
 
@@ -1152,6 +1198,7 @@ else
 	test_assign || rc=1
 	test_deref || rc=1
 	test_update_time || rc=1
+	test_should_throttle || rc=1
 fi
 
 cleanup_tmpdir


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     df8c32007069a96a6ae56645b46771f598418b3e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Aug  8 08:27:48 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:10:59 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=df8c3200

test-functions: declare local variables where possible

Given that test-functions bails out immediately in the absence of a
conventional local builtin, one might as well. Besides, it would be
trivial to eliminate local in the future, if so desired.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/test-functions b/test-functions
index 79c66a9..00a128a 100755
--- a/test-functions
+++ b/test-functions
@@ -90,6 +90,8 @@ test_die() {
 		eq  255  255
 
 	callback() {
+		local retval stderr
+
 		test_description="( exit $2 ); die"
 		( exit "$2" )
 		stderr=$(die "$2" 2>&1)
@@ -134,6 +136,8 @@ test_edo() {
 }
 
 test_is_older_than() {
+	local age tstamp
+
 	set -- \
 		ge  1  N/A           N/A \
 		ge  1  newer         N/A \
@@ -212,6 +216,8 @@ test_is_older_than() {
 }
 
 test_get_bootparam() {
+	local cmdline
+
 	cmdline="foo gentoo=bar,baz quux"
 	set -- \
 		ge  1  "${cmdline}"                   N/A \
@@ -228,6 +234,8 @@ test_get_bootparam() {
 		ge  1  "${cmdline}"                   quux
 
 	callback() {
+		local cmdline
+
 		cmdline=$2
 		shift 2
 		test_description="get_bootparam $(quote_args "$@")"
@@ -252,6 +260,8 @@ test_esyslog() {
 	}
 
 	callback() {
+		local logged should_log
+
 		should_log=$2
 		shift 2
 		test_description="esyslog $(quote_args "$@")"
@@ -429,6 +439,8 @@ test_srandom() {
 		eq 0
 
 	callback() {
+		local number
+
 		number=$(srandom)
 		test_description="srandom ($(( row += 1 ))/10: ${number:-blank})"
 		is_int "${number}" \
@@ -612,6 +624,8 @@ test_hr() {
 		eq  0  xxxxxxxxxxxxxxxxx              xyz  17
 
 	callback() {
+		local expected
+
 		shift
 		expected=$1
 		shift
@@ -661,6 +675,8 @@ test_whenceforth() {
 	chmod +x newer/file
 
 	callback() {
+		local path
+
 		shift
 		path=$1
 		shift
@@ -692,6 +708,8 @@ test_get_nprocs() {
 	set -- eq 0
 
 	callback() {
+		local nproc
+
 		shift
 		test_description="get_nprocs"
 		nproc=$(get_nprocs) && is_int "${nproc}" && test "${nproc}" -gt 0
@@ -836,6 +854,8 @@ test_substr() {
 		eq  0  ''      foobar  4    -1
 
 	callback() {
+		local expected str
+
 		shift
 		expected=$1
 		shift
@@ -927,7 +947,7 @@ test_quote_args() {
 	set -- eq 0
 
 	callback() {
-		local POSIXLY_CORRECT i
+		local POSIXLY_CORRECT cksum fmt i str
 
 		test_description="quote_args output test (expecting cksum 380900690)"
 		i=0
@@ -957,6 +977,8 @@ test_assign() {
 		eq  0  valid_nameref    marmoset
 
 	callback() {
+		local injection
+
 		shift
 		test_description="assign $(quote_args "$@")"
 		injection=
@@ -978,6 +1000,8 @@ test_deref() {
 		ge  1  PWD            'injection=1 #'
 
 	callback() {
+		local assignee injection stdout
+
 		shift
 		test_description="deref $(quote_args "$@")"
 		case $# in
@@ -996,6 +1020,8 @@ test_deref() {
 }
 
 test_update_time() {
+	local locale
+
 	set -- \
 		de_BE de_DE es_ES fr_BE fr_CA fr_FR it_IT nl_BE nl_NL pl_PL \
 		pt_BR pt_PT ru_RU sv_SE
@@ -1015,6 +1041,8 @@ test_update_time() {
 	set -- "$@" eq 0 ''
 
 	callback() {
+		local genfun_time
+
 		shift
 		if [ "$1" ]; then
 			test_description="LC_ALL=$1 _update_time"
@@ -1040,9 +1068,10 @@ test_update_time() {
 }
 
 iterate_tests() {
+	local code i j passed slice_width total
+
 	slice_width=$1
 	shift
-
 	total=$(( $# / slice_width ))
 	passed=0
 	i=0


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     f76dddb6a9e66ba3ffcb44822af0016d2b158b25
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Aug  8 08:10:32 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:10:58 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f76dddb6

test-functions: have three tests employ callback functions

Convert test_local(), test_ebegin() and test_quote_args() so as to
declare and use callbacks, just like the other tests. An appreciable
code cleanup is the result.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 99 ++++++++++++++++++++++++++++------------------------------
 1 file changed, 48 insertions(+), 51 deletions(-)

diff --git a/test-functions b/test-functions
index 0b0e127..79c66a9 100755
--- a/test-functions
+++ b/test-functions
@@ -24,26 +24,27 @@ cleanup_tmpdir() {
 }
 
 test_local() {
-	(
-		var=1
-		f() {
-			local var=2
-			g
-			test "${var}" = 3 || exit
-		}
-		g() {
-			test "${var}" = 2 || exit
-			var=3
-		}
-		f
-		test "${var}" = 1
-	) 2>/dev/null
-	retval=$?
-	if [ "${retval}" -ne 0 ]; then
-		printf 'not '
-	fi
-	printf 'ok %d - /bin/sh supports local\n' "$((testnum += 1))"
-	return "${retval}"
+	set -- eq 0
+
+	callback() {
+		test_description="/bin/sh supports local"
+		(
+			var=1
+			f() {
+				local var=2
+				g
+				test "${var}" = 3 || exit
+			}
+			g() {
+				test "${var}" = 2 || exit
+				var=3
+			}
+			f
+			test "${var}" = 1
+		) 2>/dev/null
+	}
+
+	iterate_tests 2 "$@"
 }
 
 test_chdir() {
@@ -104,21 +105,18 @@ test_die() {
 }
 
 test_ebegin() {
-	_eprint() {
-		shift
-		_ends_with_newline "$*"
-	}
-
-	set -- "message"
-	ebegin "$1"
-	retval=$?
+	set -- eq 0
 
-	if [ "${retval}" -ne 0 ]; then
-		printf 'not '
-	fi
-	printf 'ok %d - ebegin %s (expecting terminating newline)\n' "$((testnum + 1))" "$1"
+	callback() (
+		test_description="ebegin message (expecting terminating newline)"
+		_eprint() {
+			shift
+			_ends_with_newline "$*"
+		}
+		ebegin "message"
+	)
 
-	return "${retval}"
+	iterate_tests 2 "$@"
 }
 
 test_edo() {
@@ -926,25 +924,24 @@ test_contains_any() {
 }
 
 test_quote_args() {
-	local POSIXLY_CORRECT
+	set -- eq 0
 
-	testnum=$((testnum + 1))
-	retval=0
-	i=0
-	while [ "$(( i += 1 ))" -le 255 ]; do
-		fmt=$(printf '\\%o' "$i")
-		# shellcheck disable=2059
-		str=$(printf "$fmt.")
-		quote_args "${str%.}" || break
-	done | cksum | {
-		read -r cksum _
-		if [ "${cksum}" != "380900690" ]; then
-			printf 'not '
-			retval=1
-		fi
-		printf 'ok %d - quote_args output test (expected cksum 380900690, got %s)\n' "${testnum}" "${cksum}"
-		return "${retval}"
+	callback() {
+		local POSIXLY_CORRECT i
+
+		test_description="quote_args output test (expecting cksum 380900690)"
+		i=0
+		while [ "$((i += 1))" -le 255 ]; do
+			fmt=$(printf '\\%o' "$i")
+			# shellcheck disable=2059
+			str=$(printf "$fmt.")
+			quote_args "${str%.}" || break
+		done \
+		| cksum \
+		| { read -r cksum _ && test "${cksum}" = "380900690"; }
 	}
+
+	iterate_tests 2 "$@"
 }
 
 test_assign() {
@@ -1096,7 +1093,7 @@ elif ! GENFUN_MODULES="portage rc" . ./functions.sh; then
 else
 	assign_tmpdir
 	test_chdir || rc=1
-	( test_ebegin ) || rc=1; testnum=$((testnum + 1))
+	test_ebegin || rc=1; testnum=$((testnum + 1))
 	test_is_older_than || rc=1
 	test_get_bootparam || rc=1
 	test_esyslog || rc=1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     d5b850a938c5f70c33891fa08c7224dce96294e0
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Aug  6 06:47:13 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:10:56 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d5b850a9

Avoid a subshell for is_identifier()

Also, extend the coverage of the test suite a little further.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh   |  8 ++++----
 test-functions | 10 +++++++++-
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index 2174fec..b591acb 100644
--- a/functions.sh
+++ b/functions.sh
@@ -242,12 +242,12 @@ hr()
 # Determines whether the first parameter is a valid identifier (variable name).
 #
 is_identifier()
-(
-	LC_ALL=C
+{
 	case $1 in
-		''|_|[[:digit:]]*|*[!_[:alnum:]]*) false
+		''|_|[0123456789]*|*[!_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]*)
+			false
 	esac
-)
+}
 
 #
 # Determines whether the first parameter is a valid integer. A leading

diff --git a/test-functions b/test-functions
index 2f831c8..fd3f176 100755
--- a/test-functions
+++ b/test-functions
@@ -310,7 +310,15 @@ test_is_identifier() {
 		eq  0  a_a   \
 		eq  0  a_Z   \
 		eq  0  Z_a   \
-		eq  0  Z_Z
+		eq  0  Z_Z   \
+		eq  0   a0   \
+		eq  0   a9   \
+		eq  0   Z0   \
+		eq  0   Z9   \
+		eq  0  a_0   \
+		eq  0  a_9   \
+		eq  0  Z_0   \
+		eq  0  Z_9
 
 	callback() {
 		shift


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     f6f791f3c6ff6a4b94499c3fa61ffb20d2c5d733
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Aug  7 20:36:16 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:10:57 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f6f791f3

test-functions: avoid unspecified behaviour in test_quote_args()

In test_quote_args(), there is the following code.

fmt=$(printf '\%o' "$i")

However, the behaviour of the <backslash> character followed by the
<number-sign> character is unspecified. Since it is intended to be taken
as a literal backslash, fix it by writing it as thus.

fmt=$(printf '\\%o' "$i")

Doing so addresses a spurious test failure where using the loksh shell.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-functions b/test-functions
index 96781f2..487caa9 100755
--- a/test-functions
+++ b/test-functions
@@ -914,7 +914,7 @@ test_quote_args() {
 	retval=0
 	i=0
 	while [ "$(( i += 1 ))" -le 255 ]; do
-		fmt=$(printf '\%o' "$i")
+		fmt=$(printf '\\%o' "$i")
 		# shellcheck disable=2059
 		str=$(printf "$fmt.")
 		POSIXLY_CORRECT= quote_args "${str%.}" || break


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     c940730f523589511160dd5be74404c4606f225f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Aug  6 06:15:47 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:10:55 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=c940730f

Document POSIXLY_CORRECT as an influential variable

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/functions.sh b/functions.sh
index 177dad8..f84708f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -25,6 +25,7 @@
 # IFS              : warn() operands are joined by its first character
 # INVOCATION_ID    : used by from_unit()
 # PORTAGE_BIN_PATH : used by from_portage()
+# POSIXLY_CORRECT  : if unset/empty, quote_args() may emit dollar-single-quotes
 # RC_OPENRC_PID    : used by from_runscript()
 # SENTINEL         : can define a value separating two distinct argument lists
 # SYSTEMD_EXEC_PID : used by from_unit()


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     2500778920f533c56fa55798ec8d381276ae84d1
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Aug  7 17:45:02 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:10:57 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=25007789

Have srandom() employ an upper bound of 2^31-1

In the case of some shells - mksh, at least - the maximum value of an
integer is 2147483647. Such is a consequence of implementing integers as
signed int rather than signed long, even though doing so contravenes the
specification.

Reduce the output range of srandom() so as to be between 0 and
2147483647, rather than 0 and 4294967295. A change of this scope would
normally justify incrementing GENFUN_API_LEVEL but I shall not do so on
this occasion. My rationale is that >=gentoo-functions-1.7 has not yet
had enough exposure for srandom() to be in use by other projects.

Additionally, have test-functions test srandom() 10 times instead of 5.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh   | 42 +++++++++++++++++++++++++++++++++++++-----
 test-functions | 12 ++++++++----
 2 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/functions.sh b/functions.sh
index b591acb..1c55b3d 100644
--- a/functions.sh
+++ b/functions.sh
@@ -463,7 +463,10 @@ quote_args()
 }
 
 #
-# Generates a random uint32 with the assistance of the kernel CSPRNG.
+# Generates a random number between 0 and 2147483647 (2^31-1) with the
+# assistance of the kernel CSPRNG. Upon success, the number shall be printed to
+# the standard output along with a trailing <newline>. Otherwise, the return
+# value shall be greater than 0.
 #
 srandom()
 {
@@ -471,14 +474,43 @@ srandom()
 	if [ "${BASH_VERSINFO:-0}" -ge 5 ]; then
 		srandom()
 		{
-			printf '%d\n' "${SRANDOM}"
+			printf '%d\n' "$(( SRANDOM >> 1 ))"
+		}
+	elif [ -c /dev/urandom ] && [ "$(( 1 << 31 == -2147483648 ))" -eq 1 ]; then
+		# The shell implements integers as signed int rather than signed
+		# long, contrary to the specification. Therefore, bit shifting
+		# cannot be a viable strategy. Instead, use awk to generate a
+		# number that is immediately within range.
+		srandom()
+		{
+			local hex
+
+			hex=$(
+				LC_ALL=
+				LC_CTYPE=C
+				od -vAn -N256 -tx1 /dev/urandom | awk '
+					{
+						gsub(/[[:space:]]/, "")
+						hex = hex $0
+					}
+					END {
+						if (match(hex, /[0-7][[:xdigit:]]{7}/)) {
+							print substr(hex, RSTART, RLENGTH)
+						} else {
+							exit 1
+						}
+					}
+				'
+			) &&
+			printf '%d\n' "0x${hex}"
 		}
 	elif [ -c /dev/urandom ]; then
 		srandom()
 		{
-			printf '%d\n' "0x$(
-				LC_ALL=C od -vAn -N4 -tx1 /dev/urandom | tr -d '[:space:]'
-			)"
+			local hex
+
+			hex=$(LC_ALL=C od -vAn -N4 -tx1 /dev/urandom | tr -d '[:space:]')
+			[ "${hex}" ] && printf '%d\n' "$(( 0x${hex} >> 1 ))"
 		}
 	else
 		warn "srandom: /dev/urandom doesn't exist as a character device"

diff --git a/test-functions b/test-functions
index 4b2f7f9..96781f2 100755
--- a/test-functions
+++ b/test-functions
@@ -415,21 +415,25 @@ test_yesno() {
 
 test_srandom() {
 	set -- \
+		eq 0 \
+		eq 0 \
+		eq 0 \
+		eq 0 \
+		eq 0 \
 		eq 0 \
 		eq 0 \
 		eq 0 \
 		eq 0 \
 		eq 0
 
-	row=0
-
 	callback() {
 		number=$(srandom)
-		test_description="srandom ($(( row += 1 ))/5: ${number:-blank})"
+		test_description="srandom ($(( row += 1 ))/10: ${number:-blank})"
 		is_int "${number}" \
-		&& awk -v "n=${number}" 'BEGIN { exit !(n >= 0 && n <= 4294967295) }'
+		&& awk -v "n=${number}" 'BEGIN { exit !(n >= 0 && n <= 2147483647) }'
 	}
 
+	row=0
 	iterate_tests 2 "$@"
 }
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     7128696bd54bc2c6d286552d3806fd5e4e7a1b42
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Aug  6 06:24:28 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:10:55 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7128696b

Re-wrap a comment in get_nprocs()

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index f84708f..2174fec 100644
--- a/functions.sh
+++ b/functions.sh
@@ -319,7 +319,8 @@ get_nprocs()
 		true
 	elif getconf _NPROCESSORS_ONLN 2>/dev/null; then
 		# This constant is standard as of POSIX-1.2024 and was already
-		# supported by glibc, musl-utils, macOS, FreeBSD, NetBSD and OpenBSD.
+		# supported by glibc, musl-utils, macOS, FreeBSD, NetBSD and
+		# OpenBSD.
 		true
 	else
 		warn "get_nprocs: failed to determine the number of processors"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-11 10:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-11 10:11 UTC (permalink / raw
  To: gentoo-commits

commit:     a56d2680c5f2a3dfa2a402fe138641721d42df24
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Aug  7 09:13:53 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug 11 10:10:56 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=a56d2680

test-functions: check numerical bounds with awk in test_srandom()

Use awk(1) to test whether the numbers produced by the srandom()
function are within bounds. One cannot necesarily rely upon the shell to
perform this task. Consider mksh(1) as a case in point. Contrary to the
specification, it implements integers as signed int rather than signed
long. Consequently, it can only handle numbers between -2147483648 and
2147483647, resulting in easily reproducible test failures caused by
overflow.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/test-functions b/test-functions
index fd3f176..4b2f7f9 100755
--- a/test-functions
+++ b/test-functions
@@ -427,8 +427,7 @@ test_srandom() {
 		number=$(srandom)
 		test_description="srandom ($(( row += 1 ))/5: ${number:-blank})"
 		is_int "${number}" \
-		&& test "${number}" -ge 0 \
-		&& test "${number}" -le 4294967295
+		&& awk -v "n=${number}" 'BEGIN { exit !(n >= 0 && n <= 4294967295) }'
 	}
 
 	iterate_tests 2 "$@"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-05 20:39 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-05 20:39 UTC (permalink / raw
  To: gentoo-commits

commit:     7d8e163ca6b60c35f8d5baff18a2be781e9a97e5
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Aug  5 14:49:51 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Aug  5 20:38:56 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7d8e163c

Ensure a radix character of U+2E in _update_time()

I overlooked that bash respects the radix character defined by the
locale in the course of synthesizing the value of the EPOCHREALTIME
value. Set LC_NUMERIC as C to guarantee that the radix character is
considered as U+2E (FULL STOP) within the scope of the bash-specific
function. Doing so also addresses a distinct issue whereby the
invocation of printf was sensitive to the implied value of LC_NUMERIC.

Another way to address this would have been to set LC_ALL as C. I
decided not to because it would decrease the likelihood of the relevant
diagnostic messages being rendered in the user's native language.

Additionally, add a test case.

Closes: https://bugs.gentoo.org/937376
Reported-by: Christian Bricart <christian <AT> bricart.de>
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh   |  6 ++++--
 test-functions | 22 ++++++++++++++++++++++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index bea948f..561a98f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -761,7 +761,9 @@ _update_time()
 		# shellcheck disable=2034,3045
 		_update_time()
 		{
-			local cs s timeval
+			# Setting LC_NUMERIC as C ensures a radix character of
+			# U+2E, duly affecting both EPOCHREALTIME and printf.
+			local LC_ALL LC_NUMERIC=C cs s timeval
 
 			timeval=${EPOCHREALTIME}
 			s=${timeval%.*}
@@ -784,7 +786,7 @@ _update_time()
 	else
 		_update_time()
 		{
-			false
+			return 2
 		}
 	fi
 

diff --git a/test-functions b/test-functions
index 561ddc5..14bb49f 100755
--- a/test-functions
+++ b/test-functions
@@ -875,6 +875,27 @@ test_deref() {
 	iterate_tests 4 "$@"
 }
 
+test_update_time() {
+	retval=0
+	genfun_time=$(_update_time && printf %s "${genfun_time}")
+	case $? in
+		0)
+			is_int "${genfun_time}"
+			;;
+		2)
+			# Unsupported for the platform and therefore untestable.
+			;;
+		*)
+			false
+	esac ||
+	{
+		printf 'not '
+		retval=1
+	}
+	printf 'ok %d - _update_time (test %d -eq 0)\n' "$((testnum += 1))" "${retval}"
+	return "${retval}"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -955,6 +976,7 @@ else
 	test_quote_args || rc=1
 	test_assign || rc=1
 	test_deref || rc=1
+	test_update_time || rc=1
 fi
 
 cleanup_tmpdir


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-05 20:39 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-05 20:39 UTC (permalink / raw
  To: gentoo-commits

commit:     91c9cb17fc8d22ddb0bdb0f7b44a9205bcd014cd
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Mon Aug  5 20:38:07 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Aug  5 20:38:56 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=91c9cb17

meson.build: prepare for gentoo-functions-1.7.1

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 791bcf0..03852a6 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project(
   'gentoo-functions', 'c',
-  version: '1.7',
+  version: '1.7.1',
   license: 'GPL-2.0-only',
   default_options : [
     'warning_level=2',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-05  2:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-05  2:03 UTC (permalink / raw
  To: gentoo-commits

commit:     816ec2b63ab378aebb9f2ee94a0b67943b652090
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Mon Aug  5 02:02:50 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Aug  5 02:02:50 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=816ec2b6

meson.build: prepare for gentoo-functions-1.7

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index f7985a4..791bcf0 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project(
   'gentoo-functions', 'c',
-  version: '1.6',
+  version: '1.7',
   license: 'GPL-2.0-only',
   default_options : [
     'warning_level=2',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-05  2:02 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-05  2:02 UTC (permalink / raw
  To: gentoo-commits

commit:     f4ce893c16ede796c9a524650702e49afb5d0361
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Aug  4 23:43:44 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Aug  4 23:52:51 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f4ce893c

Add the assign() and deref() functions

These two functions are primarily intended to mitigate the appalling use
of eval in projects such as netifrc and openrc. Consider the following
code.

net/iproute2.sh:29:	eval netns="\$netns_${IFVAR}"

This could instead be be written as:

deref "netns_${IFVAR}" netns

Alternatively, it could be written so as to use a command substitution:

netns=$(deref "netns_${IFVAR}")

Either method would protect against against illegal identifier names and
code injection.

Consider, also, the following code.

net/iproute2.sh:185:                            eval "$x=$1" ; shift ;;

This could instead be written as:

assign "$x" "$1"

As with deref, it would protect against illegal identifier names and
code injection.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 44 ++++++++++++++++++++++++++++++++++++++++++++
 test-functions | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+)

diff --git a/functions.sh b/functions.sh
index 94114cc..bea948f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -32,6 +32,25 @@
 
 #------------------------------------------------------------------------------#
 
+#
+# Considers the first parameter as a reference to a variable by name and
+# assigns the second parameter as its value. If the first parameter is found
+# not to be a legal identifier, no assignment shall occur and the return value
+# shall be greater than 0.
+#
+assign()
+{
+	if [ "$#" -ne 2 ]; then
+		warn "assign: wrong number of arguments (got $#, expected 2)"
+		false
+	elif ! is_identifier "$1"; then
+		_warn_for_args assign "$@"
+		false
+	else
+		eval "$1=\$2"
+	fi
+}
+
 #
 # A safe wrapper for the cd builtin. To run cd "$dir" is problematic because:
 #
@@ -117,6 +136,31 @@ contains_any()
 	false
 }
 
+#
+# Considers the first parameter as a reference to a variable by name and
+# attempts to retrieve its presently assigned value. If only one parameter is
+# specified, the retrieved value shall be printed to the standard output. If a
+# second parameter is also specified, it shall be be taken as the name of a
+# variable to which the retrieved value shall be assigned. If any parameter is
+# found not to be a legal identifier, or if the variable referenced by the
+# first parameter is unset, the return value shall be greater than 0.
+#
+deref()
+{
+	if [ "$#" -eq 0 ] || [ "$#" -gt 2 ]; then
+		warn "deref: wrong number of arguments (got $#, expected between 1 and 2)"
+	elif ! trueof_all is_identifier -- "$@"; then
+		_warn_for_args deref "$@"
+		false
+	elif ! eval "test \${$1+set}"; then
+		false
+	elif [ "$#" -eq 1 ]; then
+		eval "printf '%s\\n' \"\$$1\""
+	else
+		eval "$2=\$$1"
+	fi
+}
+
 #
 # Determines whether the current shell is a subprocess of portage.
 #

diff --git a/test-functions b/test-functions
index 8acb731..561ddc5 100755
--- a/test-functions
+++ b/test-functions
@@ -824,6 +824,57 @@ test_quote_args() {
 	}
 }
 
+test_assign() {
+	set -- \
+		ge  1  N/A              N/A       \
+		ge  1  ''               N/A       \
+		ge  1  0                N/A       \
+		ge  1  valid_nameref    N/A       \
+		ge  1  ''               marmoset  \
+		ge  1  0                marmoset  \
+		ge  1  valid_nameref    N/A       \
+		ge  1  'injection=1 #'  comment   \
+		eq  0  valid_nameref    marmoset
+
+	callback() {
+		shift
+		test_description="assign $(quote_args "$@")"
+		injection=
+		assign "$@" 2>/dev/null || test "${injection}"
+	}
+
+	iterate_tests 4 "$@"
+}
+
+test_deref() {
+	set -- \
+		ge  1  N/A            N/A              \
+		ge  1  ''             N/A              \
+		ge  1  0              N/A              \
+		ge  1  ''             ''               \
+		ge  1  0              0                \
+		eq  0  valid_nameref  N/A              \
+		eq  0  valid_nameref  assignee         \
+		ge  1  PWD            'injection=1 #'
+
+	callback() {
+		shift
+		test_description="deref $(quote_args "$@")"
+		case $# in
+			2)
+				assignee= injection=
+				deref "$@" \
+				&& { test "${assignee}" = "marmoset" || test "${injection}"; }
+				;;
+			*)
+				stdout=$(deref "$@") && test "${stdout}" = "marmoset"
+				;;
+		esac 2>/dev/null
+	}
+
+	iterate_tests 4 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -902,6 +953,8 @@ else
 	test_contains_all || rc=1
 	test_contains_any || rc=1
 	test_quote_args || rc=1
+	test_assign || rc=1
+	test_deref || rc=1
 fi
 
 cleanup_tmpdir


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-05  2:02 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-05  2:02 UTC (permalink / raw
  To: gentoo-commits

commit:     23e3f65f2723f80c335d9309629439c27080b29f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Aug  3 00:52:02 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Aug  3 00:52:02 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=23e3f65f

Alter a variable name in quote_args()

Now that POSIX-1.2024 has been ratified, strictly_posix no longer makes
sense as a variable name.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index 7dd4d8f..94114cc 100644
--- a/functions.sh
+++ b/functions.sh
@@ -380,14 +380,14 @@ quote_args()
 		seq_by["\134"] = "\\"
 	}
 	BEGIN {
-		strictly_posix = length(ENVIRON["POSIXLY_CORRECT"])
+		issue = length(ENVIRON["POSIXLY_CORRECT"]) ? 7 : 8;
 		argc = ARGC
 		ARGC = 1
 		for (arg_idx = 1; arg_idx < argc; arg_idx++) {
 			arg = ARGV[arg_idx]
 			if (arg == q) {
 				word = "\\" q
-			} else if (strictly_posix || arg !~ /[\001-\037\177-\377]/) {
+			} else if (issue < 8 || arg !~ /[\001-\037\177-\377]/) {
 				gsub(q, q "\\" q q, arg)
 				word = q arg q
 			} else {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-05  2:02 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-05  2:02 UTC (permalink / raw
  To: gentoo-commits

commit:     7e82a40f39b75efa66ccbd73580d4c3a051b155e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Aug  3 04:19:23 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Aug  3 04:22:39 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7e82a40f

test-functions: jettison a few shellcheck exemptions

They are no longer applicable.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/test-functions b/test-functions
index db89e73..7d75eda 100755
--- a/test-functions
+++ b/test-functions
@@ -1,5 +1,5 @@
 #!/bin/sh
-# shellcheck disable=2015,2154,2164,2181,2317
+# shellcheck disable=2015,2164,2317
 
 # Requires mktemp(1), which is not a standard utility, but is commonly
 # available. The implementations provided by GNU coreutils, busybox and toybox
@@ -12,7 +12,6 @@ bailout() {
 }
 
 assign_tmpdir() {
-	# shellcheck disable=1007
 	dir=$(mktemp -d) \
 	&& chdir "${dir}" \
 	|| bailout "Couldn't create or change to the temp dir"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-05  2:02 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-05  2:02 UTC (permalink / raw
  To: gentoo-commits

commit:     9240fe699926f4f413ad4b2bb09ee66bf3834aa7
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Aug  3 04:29:29 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Aug  3 04:29:29 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9240fe69

test-functions: add several shellcheck exemptions

Notably, SC2317 and SC3034 in the global scope. The former produces
false positives whereas the latter permits the use of local.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/test-functions b/test-functions
index 7d75eda..8acb731 100755
--- a/test-functions
+++ b/test-functions
@@ -1,5 +1,5 @@
 #!/bin/sh
-# shellcheck disable=2015,2164,2317
+# shellcheck disable=1007,2015,2164,2317,3043
 
 # Requires mktemp(1), which is not a standard utility, but is commonly
 # available. The implementations provided by GNU coreutils, busybox and toybox
@@ -810,6 +810,7 @@ test_quote_args() {
 	i=0
 	while [ "$(( i += 1 ))" -le 255 ]; do
 		fmt=$(printf '\%o' "$i")
+		# shellcheck disable=2059
 		str=$(printf "$fmt.")
 		POSIXLY_CORRECT= quote_args "${str%.}" || break
 	done | cksum | {
@@ -866,6 +867,7 @@ testnum=0
 rc=0
 
 if [ "${PORTAGE_BIN_PATH}" ] && [ "${S}" ]; then
+	# shellcheck disable=2034
 	genfun_basedir=${S}
 fi
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     61045c5ff6a5939f81bc64190c0d3d137f40f8c2
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug  2 22:50:54 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Aug  2 23:08:57 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=61045c5f

Have chdir() enforce POSIX interpretation 1047

POSIX-1.2024 (Issue 8) requires for the cd builtin to raise an error
where given an empty directory operand. However, various implementations
have yet to catch up. Given that it is a sensible change, let's have the
chdir() function behave accordingly. Further, since doing so renders the
test_chdir_noop test useless, get rid of it. The purpose that the test
served is now subsumed by test_chdir.

Closes: https://bugs.gentoo.org/937157
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 13 ++++++++++---
 test-functions | 17 +----------------
 2 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/functions.sh b/functions.sh
index 9b6220b..7dd4d8f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -42,13 +42,20 @@
 #
 chdir()
 {
+	if [ "$#" -eq 1 ]; then
+		case $1 in
+			'')
+				_warn_for_args chdir "$1"
+				return 1
+				;;
+			-)
+				set -- ./-
+		esac
+	fi
 	if [ "${BASH}" ]; then
 		# shellcheck disable=3044
 		shopt -u cdable_vars
 	fi
-	if [ "$1" = - ]; then
-		set -- ./-
-	fi
 	# shellcheck disable=1007,2164
 	CDPATH= cd -- "$@"
 }

diff --git a/test-functions b/test-functions
index 2ad76e8..db89e73 100755
--- a/test-functions
+++ b/test-functions
@@ -49,6 +49,7 @@ test_local() {
 
 test_chdir() {
 	set -- \
+		ge  1          ''  \
 		ge  1  grandchild  \
 		ge  1         var  \
 		eq  0          -L  \
@@ -77,21 +78,6 @@ test_chdir() {
 	iterate_tests 3 "$@"
 }
 
-test_chdir_noop() {
-	set -- \
-		eq  0  ''
-
-	callback() {
-		shift
-		test_description="chdir $(quote_args "$@")"
-		chdir "$@" \
-		&& test "$PWD" = "$OLDPWD" \
-		|| { cd - >/dev/null; false; }
-	}
-
-	iterate_tests 3 "$@"
-}
-
 test_die() {
 	set -- \
 		eq    1    0 \
@@ -891,7 +877,6 @@ elif ! GENFUN_MODULES="portage rc" . ./functions.sh; then
 else
 	assign_tmpdir
 	test_chdir || rc=1
-	test_chdir_noop || rc=1
 	( test_ebegin ) || rc=1; testnum=$((testnum + 1))
 	test_is_older_than || rc=1
 	test_get_bootparam || rc=1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     1d2c629638374fd9d784e142065b63d3551dad34
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug  2 14:54:01 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Aug  2 16:21:14 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1d2c6296

Explain that get_nprocs() is called by parallel_run()

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/functions.sh b/functions.sh
index 69b9bf5..4fe0e86 100644
--- a/functions.sh
+++ b/functions.sh
@@ -300,10 +300,10 @@ oldest()
 # Executes a simple command in parallel. At least two parameters are expected.
 # The first parameter shall be taken as the maximum number of jobs to run
 # concurrently. If specified as less than or equal to 0, the number shall be
-# determined by running the nproc function. The second parameter shall be taken
-# as a command name. The remaining parameters shall be conveyed to the specified
-# command, one at a time. Should at least one command fail, the return value
-# shall be greater than 0.
+# determined by calling the get_nprocs function. The second parameter shall be
+# taken as a command name. The remaining parameters shall be conveyed to the
+# specified command, one at a time. Should at least one command fail, the
+# return value shall be greater than 0.
 #
 parallel_run()
 {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     f426bf67aaaac78938aff33f6cc018fdcf7c3466
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug  2 10:14:03 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Aug  2 16:21:14 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f426bf67

Render hr() faster still for shells other than bash

Reduce the number of loop iterations by initially trying to append
characters 8 at a time.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 4 ++++
 test-functions | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index b40e17b..a002e54 100644
--- a/functions.sh
+++ b/functions.sh
@@ -181,6 +181,10 @@ hr()
 		eval 'printf %s\\n "${hr//?/"$char"}"'
 	else
 		i=0
+		while [ "$(( i += 8 ))" -le "${length}" ]; do
+			hr=${hr}${char}${char}${char}${char}${char}${char}${char}${char}
+		done
+		i=${#hr}
 		while [ "$(( i += 1 ))" -le "${length}" ]; do
 			hr=${hr}${char}
 		done

diff --git a/test-functions b/test-functions
index 4b3107f..8070c8d 100755
--- a/test-functions
+++ b/test-functions
@@ -514,10 +514,10 @@ test_hr() {
 		eq  0  "$(printf '%80s' | tr ' ' -)"  -    N/A  \
 		eq  0  ''                             -    0    \
 		eq  0  -                              -    1    \
-		eq  0  -----                          -    5    \
+		eq  0  ---------                      -    9    \
 		eq  0  ''                             xyz  0    \
 		eq  0  x                              xyz  1    \
-		eq  0  xxxxx                          xyz  5
+		eq  0  xxxxxxxxx                      xyz  9
 
 	callback() {
 		shift


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     8a83cf36a847fbd32990d3590bfd22a1516af898
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug  2 09:28:58 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Aug  2 16:21:14 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=8a83cf36

Render hr() faster

Render hr() faster by eliminating the requirement to fork and execute
any external utilities after having established the intended length of
the rule. Also, use printf -v and string-replacing parameter expansion
where the shell is found to be bash. Doing so helps considerably because
bash is very slow at looping.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 34 ++++++++++++++++++++--------------
 test-functions |  2 +-
 2 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/functions.sh b/functions.sh
index f120564..b40e17b 100644
--- a/functions.sh
+++ b/functions.sh
@@ -156,30 +156,36 @@ has_systemd()
 
 #
 # Prints a horizontal rule. If specified, the first parameter shall be taken as
-# a string to be repeated in the course of composing the rule. Otherwise, it
-# shall default to the <hyphen-minus>. If specified, the second parameter shall
-# define the length of the rule in characters. Otherwise, it shall default to
-# the width of the terminal if such can be determined, or 80 if it cannot be.
+# a string whose first character is to be repeated in the course of composing
+# the rule. Otherwise, or if specified as the empty string, it shall default to
+# the <hyphen-minus>. If specified, the second parameter shall define the length
+# of the rule in characters. Otherwise, it shall default to the width of the
+# terminal if such can be determined, or 80 if it cannot be.
 #
 hr()
 {
-	local length
+	local char hr i length
 
-	if is_int "$2"; then
+	if [ "$#" -ge 2 ] && is_int "$2"; then
 		length=$2
 	elif _update_tty_level <&1; [ "${genfun_tty}" -eq 2 ]; then
 		length=${genfun_cols}
 	else
 		length=80
 	fi
-	PATTERN=${1:--} awk -v "width=${length}" -f - <<-'EOF'
-	BEGIN {
-		while (length(rule) < width) {
-			rule = rule substr(ENVIRON["PATTERN"], 1, width - length(rule))
-		}
-		print rule
-	}
-	EOF
+	char=${1--}
+	char=${char%"${char#?}"}
+	if [ "${BASH}" ]; then
+		# shellcheck disable=3045
+		printf -v hr '%*s' "${length}" ''
+		eval 'printf %s\\n "${hr//?/"$char"}"'
+	else
+		i=0
+		while [ "$(( i += 1 ))" -le "${length}" ]; do
+			hr=${hr}${char}
+		done
+		printf '%s\n' "${hr}"
+	fi
 }
 
 #

diff --git a/test-functions b/test-functions
index f11234a..4b3107f 100755
--- a/test-functions
+++ b/test-functions
@@ -517,7 +517,7 @@ test_hr() {
 		eq  0  -----                          -    5    \
 		eq  0  ''                             xyz  0    \
 		eq  0  x                              xyz  1    \
-		eq  0  xyzxy                          xyz  5
+		eq  0  xxxxx                          xyz  5
 
 	callback() {
 		shift


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     50a9e6e7714c646d4347dc5b283fef0410d2616d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug  2 15:16:02 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Aug  2 16:21:14 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=50a9e6e7

Adhere to the Allman style for _select_by_mtime()

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 4fe0e86..5ef96ae 100644
--- a/functions.sh
+++ b/functions.sh
@@ -629,7 +629,8 @@ _has_dumb_terminal()
 #
 # See the definitions of oldest() and newest().
 #
-_select_by_mtime() {
+_select_by_mtime()
+{
 	local sort_opt
 
 	sort_opt=$1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     971b8702719cf2ed697a6017deeff1f2facc0080
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Aug  1 19:16:02 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Aug  2 16:21:14 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=971b8702

Render contains_all() and contains_any() faster

Re-implement the contains_all() and contains_any() functions in such a
way that they are faster than their forebears by an order of magnitude.
In order to achieve this level of performance, the value of IFS is no
longer taken into account. Instead, words are always presumed to be
separated by characters matching the [[:space:]] character class.

Consider a scenario in which the FEATURES variable is comprised of 33
words.

$ FEATURES="assume-digests binpkg-docompress binpkg-dostrip binpkg-logs
buildpkg buildpkg-live config-protect-if-modified distlocks ebuild-locks
fixlafiles ipc-sandbox merge-sync merge-wait multilib-strict
network-sandbox news parallel-fetch pid-sandbox pkgdir-index-trusted
preserve-libs protect-owned qa-unresolved-soname-deps sandbox sfperms
strict unknown-features-warn unmerge-logs unmerge-orphans userfetch
userpriv usersandbox usersync xattr"

Let's say that the contains_any function is used to search for 10 words,
where only the 10th can be matched and where FEATURES must be scanned in
its entirety exactly 10 times.

$ contains_any "$FEATURES" the quick brown fox jumped over the lazy hen xattr

The following benchmarks show how long it took to call the function
50,000 times consecutively on a system with an Apple M1 CPU for both the
original and new implementations. This is with the dash shell.

contains_any (BEFORE)

real    0m19.135s
user    0m16.781s
sys     0m2.258s

contains_any (AFTER)

real    0m1.571s
user    0m1.497s
sys     0m0.063s

Now let's say that the contains_all function is used to search for 3
words, where all can be matched while requiring for FEATURES to be
scanned in its entirety at least once.

$ contains_all "$FEATURES" assume-digests news xattr

Again, The following benchmarks show how long it took to call the
function 50,000 times consecutively.

contains_all (BEFORE)

real    1m8.052s
user    0m19.363s
sys     0m42.742s

contains_all (AFTER)

real    0m0.689s
user    0m0.627s
sys     0m0.057s

The performance improvements are similarly impressive if using bash.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 138 ++++++++++++++++++---------------------------------------
 test-functions | 125 +++++++++++++--------------------------------------
 2 files changed, 74 insertions(+), 189 deletions(-)

diff --git a/functions.sh b/functions.sh
index 036e3a7..f120564 100644
--- a/functions.sh
+++ b/functions.sh
@@ -22,7 +22,7 @@
 # COLUMNS          : may be used by _update_columns() to get the column count
 # EPOCHREALTIME    : potentially used by _update_time() to get the time
 # GENFUN_MODULES   : which of the optional function collections must be sourced
-# IFS              : affects contains_all(), contains_any() and warn()
+# IFS              : warn() operands are joined by its first character
 # INVOCATION_ID    : used by from_unit()
 # PORTAGE_BIN_PATH : used by from_portage()
 # RC_OPENRC_PID    : used by from_runscript()
@@ -54,112 +54,60 @@ chdir()
 }
 
 #
-# Takes the first parameter as a string comprising zero or more words, composes
-# a set consisting of the intersection of those words, then determines whether
-# the intersection of the remaining parameters forms a subset thereof. The
-# words shall be collected by splitting the string into individual fields, in
-# accordance with section 2.6.5 of the Shell Command Language specification.
-# Therefore, the value of IFS shall be taken into account. If fewer than two
-# parameters are provided, or if the first parameter yields no fields, or if the
-# second set is disjoint from - or a superset of - the first, the return value
-# shall be greater than 0.
+# Considers the first parameter as a string comprising zero or more
+# whitespace-separated words then determines whether all of the remaining
+# parameters can be found within the resulting list in their capacity as
+# discrete words. If they cannot be, or if fewer than two parameters were given,
+# the return value shall be 1. Of the words to be searched for, any which are
+# empty or which contain whitespace characters shall be deemed unfindable.
 #
 contains_all()
 {
-	# shellcheck disable=2097,2098
-	[ "$#" -ge 2 ] &&
-	IFS=${IFS} awk -v ifs_set=${IFS+1} -f - -- "$@" <<-'EOF'
-	BEGIN {
-		haystack = ARGV[1]
-		argc = ARGC
-		ARGC = 1
-		if (ifs_set) {
-			ifs = ENVIRON["IFS"]
-		} else {
-			ifs = " \t\n"
-		}
-		# Translate IFS to FS, in accordance with section 2.6.5.
-		if (length(ifs) == 0) {
-			FS = "^"
-		} else {
-			fs = "("
-			for (i = 1; i <= length(ifs); i++) {
-				char = substr(ifs, i, 1)
-				if (seen[char]++) {
-					continue
-				} else if (char ~ /[ \t\n]/) {
-					whitespace = whitespace char
-					fs = fs "[" char "]+|"
-				} else {
-					fs = fs "[" char "]|"
-				}
-			}
-			sub(/\|$/, "", fs)
-			FS = fs = fs ")"
-		}
-		# Leading whitespace characters must be removed.
-		if (length(whitespace) > 0) {
-			sub("^[" whitespace "]+", "", haystack)
-		}
-		# In sh, fields are terminated, not separated.
-		sub(FS "$", "", haystack)
-		len = split(haystack, words)
-		for (i = 1; i <= len; i++) {
-			set2[words[i]]
-		}
-		for (i = 2; i < argc; i++) {
-			set1[ARGV[i]]
-		}
-		for (word in set2) {
-			delete set1[word]
-		}
-		for (word in set1) {
-			exit 1
-		}
-	}
-	EOF
+	local arg haystack
+
+	[ "$#" -gt 1 ] || return
+	haystack=" $1 "
+	shift
+	for arg; do
+		case ${arg} in
+			''|*[[:space:]]*)
+				return 1
+		esac
+		case ${haystack} in
+			*" ${arg} "*)
+				;;
+			*)
+				return 1
+		esac
+	done
 }
 
 #
-# Takes the first parameter as a string comprising zero or more words then
-# determines whether at least one of the remaining parameters can be matched
-# against any of those words. The words shall be collected by splitting the
-# string into individual fields, in accordance with section 2.6.5 of the Shell
-# Command Language specification. Therefore, the value of IFS shall be taken
-# into account. If fewer than two parameters are provided, or if the first
-# parameter yields no fields, or if none of the following parameters can be
-# matched, the return value shall be greater than 0.
+# Considers the first parameter as a string comprising zero or more
+# whitespace-separated words then determines whether any of the remaining
+# parameters can be found within the resulting list in their capacity as
+# discrete words. If none can be, or if no parameters were given, the return
+# value shall be greater than 0. Of the words to be searched for, any which are
+# empty or which contain whitespace characters shall be disregarded.
 #
 contains_any()
 {
-	local had_noglob haystack i item needle retval
+	local arg haystack
 
-	[ "$#" -ge 2 ] || return
-	haystack=$1
+	[ "$#" -gt 0 ] || return
+	haystack=" $1 "
 	shift
-	i=0
-	case $- in
-		*f*)
-			had_noglob=1
-			;;
-		*)
-			had_noglob=0
-	esac
-	set -f
-	for needle; do
-		if [ "$(( i += 1 ))" -eq 1 ]; then
-			# shellcheck disable=2086
-			set -- ${haystack}
-		fi
-		for item; do
-			[ "${item}" = "${needle}" ] && break 2
-		done
+	for arg; do
+		case ${arg} in
+			''|*[[:space:]]*)
+				continue
+		esac
+		case ${haystack} in
+			*" ${arg} "*)
+				return 0
+		esac
 	done
-	retval=$?
-	if [ "${had_noglob}" -eq 0 ]; then
-		set +f
-	fi
-	return "${retval}"
+	false
 }
 
 #

diff --git a/test-functions b/test-functions
index ef2aa98..f11234a 100755
--- a/test-functions
+++ b/test-functions
@@ -744,105 +744,42 @@ test_substr() {
 
 test_contains_all() {
 	set -- \
-		ge  1  default  N/A           N/A         N/A         N/A  \
-		ge  1  default  ' foo  bar '  ''          N/A         N/A  \
-		ge  1  default  ' foo  bar '  ''          ' '         N/A  \
-		ge  1  default  ' foo  bar '  ''          ' bar'      N/A  \
-		ge  1  default  ' foo  bar '  ''          'foo '      N/A  \
-		ge  1  default  ' foo  bar '  ''          'foo  bar'  N/A  \
-		ge  1  default  ' foo  bar '  ' '         ''          N/A  \
-		ge  1  default  ' foo  bar '  ' '         ' '         N/A  \
-		ge  1  default  ' foo  bar '  ' '         N/A         N/A  \
-		ge  1  default  ' foo  bar '  ' bar'      ''          N/A  \
-		ge  1  default  ' foo  bar '  ' bar'      N/A         N/A  \
-		ge  1  default  ' foo  bar '  'foo '      ''          N/A  \
-		ge  1  default  ' foo  bar '  'foo '      ' bar'      N/A  \
-		ge  1  default  ' foo  bar '  'foo '      N/A         N/A  \
-		ge  1  default  ' foo  bar '  'foo  bar'  ''          N/A  \
-		ge  1  default  ' foo  bar '  'foo  bar'  N/A         N/A  \
-		ge  1  default  ' foo  bar '  N/A         N/A         N/A  \
-		ge  1  default  ' foo  bar '  bar         foo         ''   \
-		ge  1  default  ' foo  bar '  bar         foo         ' '  \
-		ge  1  default  ' foo  bar '  baz         bar         foo  \
-		ge  1  default  ' foo  bar '  fo          ba          N/A  \
-		ge  1  default  ' foo  bar '  foo         bar         ''   \
-		ge  1  default  ' foo  bar '  foo         bar         ' '  \
-		ge  1  default  ' foo  bar '  foo         bar         baz  \
-		ge  1  default  ' foo  bar '  o           a           N/A  \
-		ge  1  default  ' foo  bar '  oo          ar          N/A  \
-		eq  0  default  ' foo  bar '  foo         bar         N/A  \
-		eq  0  default  ' foo  bar '  bar         foo         N/A  \
-		ge  1  ', '     N/A           N/A         N/A         N/A  \
-		ge  1  ', '     ' foo  bar '  ''          N/A         N/A  \
-		ge  1  ', '     ' foo  bar '  ''          ' '         N/A  \
-		ge  1  ', '     ' foo ,bar, ' ''          ','         N/A  \
-		ge  1  ', '     ' foo  bar '  ''          ' bar'      N/A  \
-		ge  1  ', '     ' foo ,bar '  ''          ',bar'      N/A  \
-		ge  1  ', '     ' foo  bar '  ''          'foo '      N/A  \
-		ge  1  ', '     ' foo, bar '  ''          'foo,'      N/A  \
-		ge  1  ', '     ' foo  bar '  ''          'foo  bar'  N/A  \
-		ge  1  ', '     ' foo  bar '  ' '         ''          N/A  \
-		ge  1  ', '     ' foo,bar, '  ','         ''          N/A  \
-		ge  1  ', '     ' foo  bar '  ' '         ' '         N/A  \
-		ge  1  ', '     ',foo,,bar,'  ','         ','         N/A  \
-		ge  1  ', '     ' foo  bar '  ' '         N/A         N/A  \
-		ge  1  ', '     ',foo,,bar,'  ','         N/A         N/A  \
-		ge  1  ', '     ' foo  bar '  ' bar'      ''          N/A  \
-		ge  1  ', '     'foo,bar,'    ',bar'      ''          N/A  \
-		ge  1  ', '     ' foo  bar '  ' bar'      N/A         N/A  \
-		ge  1  ', '     ',foo,,bar,'  ',bar'      N/A         N/A  \
-		ge  1  ', '     ' foo  bar '  'foo '      ''          N/A  \
-		ge  1  ', '     'foo,bar,'    'foo,'      ''          N/A  \
-		ge  1  ', '     ' foo  bar '  'foo '      ' bar'      N/A  \
-		ge  1  ', '     ',foo,,bar,'  'foo,'      ',bar'      N/A  \
-		ge  1  ', '     ' foo  bar '  'foo '      N/A         N/A  \
-		ge  1  ', '     ',foo,,bar,'  'foo,'      N/A         N/A  \
-		ge  1  ', '     ' foo  bar '  'foo  bar'  ''          N/A  \
-		ge  1  ', '     'foo,bar,'    'foo,bar'   ''          N/A  \
-		ge  1  ', '     ' foo  bar '  'foo  bar'  N/A         N/A  \
-		ge  1  ', '     ',foo,,bar,'  'foo,,bar'  N/A         N/A  \
-		ge  1  ', '     ' foo  bar '  N/A         N/A         N/A  \
-		ge  1  ', '     ' foo  bar '  bar         foo         ''   \
-		ge  1  ', '     ' foo,bar  '  bar         foo         ''   \
-		ge  1  ', '     ' foo  bar '  bar         foo         ' '  \
-		ge  1  ', '     ' foo,,bar '  bar         foo         ','  \
-		ge  1  ', '     ' foo  bar '  baz         bar         foo  \
-		ge  1  ', '     ',foo,,bar,'  baz         bar         foo  \
-		ge  1  ', '     ' foo  bar '  fo          ba          N/A  \
-		ge  1  ', '     ',foo,,bar,'  fo          ba          N/A  \
-		ge  1  ', '     ' foo  bar '  foo         bar         ''   \
-		ge  1  ', '     ' foo,bar '   foo         bar         ''   \
-		ge  1  ', '     ' foo  bar '  foo         bar         ' '  \
-		ge  1  ', '     ' foo,,bar '  foo         bar         ','  \
-		ge  1  ', '     ' foo  bar '  foo         bar         baz  \
-		ge  1  ', '     ',foo,,bar,'  foo         bar         baz  \
-		ge  1  ', '     ' foo  bar '  o           a           N/A  \
-		ge  1  ', '     ',foo,,bar,'  o           a           N/A  \
-		ge  1  ', '     ' foo  bar '  oo          ar          N/A  \
-		ge  1  ', '     ',foo,,bar,'  oo          ar          N/A  \
-		eq  0  ', '     ' foo  bar '  foo         bar         N/A  \
-		eq  0  ', '     ',foo  bar,'  foo         bar         N/A  \
-		eq  0  ', '     ' foo,,bar '  foo         bar         N/A  \
-		eq  0  ', '     ',foo,,bar,'  foo         bar         N/A  \
-		eq  0  ', '     ' foo  bar '  bar         foo         N/A  \
-		eq  0  ', '     ',foo  bar,'  bar         foo         N/A  \
-		eq  0  ', '     ' foo,,bar '  bar         foo         N/A  \
-		eq  0  ', '     ',foo,,bar,'  bar         foo         N/A
+		ge  1  N/A           N/A         N/A         N/A  \
+		ge  1  ' foo  bar '  ''          N/A         N/A  \
+		ge  1  ' foo  bar '  ''          ' '         N/A  \
+		ge  1  ' foo  bar '  ''          ' bar'      N/A  \
+		ge  1  ' foo  bar '  ''          'foo '      N/A  \
+		ge  1  ' foo  bar '  ''          'foo  bar'  N/A  \
+		ge  1  ' foo  bar '  ' '         ''          N/A  \
+		ge  1  ' foo  bar '  ' '         ' '         N/A  \
+		ge  1  ' foo  bar '  ' '         N/A         N/A  \
+		ge  1  ' foo  bar '  ' bar'      ''          N/A  \
+		ge  1  ' foo  bar '  ' bar'      N/A         N/A  \
+		ge  1  ' foo  bar '  'foo '      ''          N/A  \
+		ge  1  ' foo  bar '  'foo '      ' bar'      N/A  \
+		ge  1  ' foo  bar '  'foo '      N/A         N/A  \
+		ge  1  ' foo  bar '  'foo  bar'  ''          N/A  \
+		ge  1  ' foo  bar '  'foo  bar'  N/A         N/A  \
+		ge  1  ' foo  bar '  N/A         N/A         N/A  \
+		ge  1  ' foo  bar '  bar         foo         ''   \
+		ge  1  ' foo  bar '  bar         foo         ' '  \
+		ge  1  ' foo  bar '  baz         bar         foo  \
+		ge  1  ' foo  bar '  fo          ba          N/A  \
+		ge  1  ' foo  bar '  foo         bar         ''   \
+		ge  1  ' foo  bar '  foo         bar         ' '  \
+		ge  1  ' foo  bar '  foo         bar         baz  \
+		ge  1  ' foo  bar '  o           a           N/A  \
+		ge  1  ' foo  bar '  oo          ar          N/A  \
+		eq  0  ' foo  bar '  foo         bar         N/A  \
+		eq  0  ' foo  bar '  bar         foo         N/A
 
 	callback() {
 		shift
-		ifs=$1
-		shift
-		if [ "${ifs}" = "default" ]; then
-			test_description="contains_all $(quote_args "$@")"
-			contains_all "$@"
-		else
-			test_description="IFS='${ifs}' contains_all $(quote_args "$@")"
-			IFS=${ifs} contains_all "$@"
-		fi
+		test_description="contains_all $(quote_args "$@")"
+		contains_all "$@"
 	}
 
-	iterate_tests 7 "$@"
+	iterate_tests 6 "$@"
 }
 
 test_contains_any() {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     e390c04e706b9a095e50749c119b97d455839146
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Jul 10 00:32:32 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jul 10 00:32:32 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=e390c04e

Replace "Issue 8" with "POSIX-1.2024"

The POSIX-1.2024 specification was published on 2024/06/14.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index 660e697..b4c4ef1 100644
--- a/functions.sh
+++ b/functions.sh
@@ -427,8 +427,8 @@ parallel_run()
 # characters shall be replaced by octal escape sequences, <apostrophe> by
 # <backslash><apostrophe> and <backslash> by <backslash><backslash>, prior to
 # the value being given a prefix of <dollar-sign><apostrophe> and a suffix of
-# <apostrophe>, per Issue 8. Finally, the resulting values shall be printed as
-# <space> separated. The latter quoting strategy can be suppressed by setting
+# <apostrophe>, per POSIX-1.2024. Finally, the resulting values shall be printed
+# as <space> separated. The latter quoting strategy can be suppressed by setting
 # the POSIXLY_CORRECT variable as non-empty in the environment.
 #
 quote_args()
@@ -444,7 +444,7 @@ quote_args()
 				gsub(q, q "\\" q q, arg)
 				word = q arg q
 			} else {
-				# Use $'' quoting per Issue 8
+				# Use $'' quoting per POSIX-1.2024
 				if (! ("\001" in ord_by)) {
 					for (i = 1; i < 32; i++) {
 						char = sprintf("%c", i)
@@ -869,8 +869,8 @@ if [ ! "${genfun_basedir+set}" ]; then
 	genfun_basedir=${genfun_prefix}/lib/gentoo
 fi
 
-# Assign the LF ('\n') character for later expansion. POSIX Issue 8 permits
-# $'\n' but it may take years for it to be commonly implemented.
+# Assign the LF ('\n') character for later expansion. POSIX-1.2024 permits $'\n'
+# but it may take years for it to be commonly implemented.
 genfun_newline='
 '
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     1fb70d59e4e9339c4988f17844c91803031904e0
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jul 11 14:10:05 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Jul 11 14:10:05 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1fb70d59

Mention that _find0() requires findutils >=4.9

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index b4c4ef1..6d691e2 100644
--- a/functions.sh
+++ b/functions.sh
@@ -653,7 +653,8 @@ whenceforth()
 #------------------------------------------------------------------------------#
 
 #
-# See the definitions of _select_by_mtime() and is_older_than().
+# See the definitions of _select_by_mtime() and is_older_than(). This function
+# requires that GNU findutils >=4.9 be installed.
 #
 _find0()
 {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     38f482bf5beafb1b998d2beb4f3030aee0013e16
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jul 11 14:30:25 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Jul 11 14:30:25 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=38f482bf

Add a comment regarding POSIX XCU compatibility

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/functions.sh b/functions.sh
index 6d691e2..faacdca 100644
--- a/functions.sh
+++ b/functions.sh
@@ -9,6 +9,11 @@
 # intended for internal use shall be prefixed with "genfun_" to indicate so,
 # and to reduce the probability of name space conflicts.
 
+# The functions shall be compatible with the POSIX-1.2018 Shell and Utilities
+# (XCU), except where otherwise noted, and with the additional exception that
+# the use of the local utility is permitted, despite the results of its
+# invocation being formally unspecified.
+
 # The following variables affect initialisation and/or function behaviour.
 
 # BASH             : whether bash-specific features may be employed


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     282fbd3bc2cca32b1a83c28cb9649de46cf404da
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Aug  1 06:30:19 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Aug  2 16:21:12 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=282fbd3b

Render quote_args() robust and implement a test case

Coerce the effective character set as being C (US-ASCII) in the course
of executing awk(1). Some implementations are strict and will otherwise
fail in situations where the bytes cannot be decoded.

$ uname -o
Darwin
$ echo "$LC_ALL"
en_GB.UTF-8
$ printf '\200' | awk '/[\001-\037\177-\377]/'
awk: towc: multibyte conversion failure on: ''

In the above case, awk aborts because it has a need to decode the input,
which turns out not to be valid UTF-8. Now, it is rather beyond the
purview of quote_args() to guarantee that its parameters adhere to any
particular character encoding. Fortunately, for it to contend with
strings on a byte-by-byte basis is acceptable.

Refactor the code somewhat. The behaviour has been adjusted so to be
virtually identical to that of the "${*@Q}" expansion in bash, with the
exception that the ESC character is rendered as $'\e' instead of $'\E'.
Such an exception is necessary for POSIX-1.2024 conformance, wherein
dollar-single-quotes are now a standard feature (see section 2.2.4 of
the Shell Command Language).

Revise the comment preceding the function so as to accurately document
its behaviour.

Finally, add a test case. It works by calling quote_args for every
possible single-byte string before calculating a CRC checksum for the
cumulative output and comparing it against a pre-determined value.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 65 ++++++++++++++++++++++++++++++++++++----------------------
 test-functions | 20 ++++++++++++++++++
 2 files changed, 60 insertions(+), 25 deletions(-)

diff --git a/functions.sh b/functions.sh
index faacdca..036e3a7 100644
--- a/functions.sh
+++ b/functions.sh
@@ -425,47 +425,62 @@ parallel_run()
 #
 # Prints the positional parameters in a format that may be reused as shell
 # input. For each considered, it shall be determined whether its value contains
-# any non-printable characters in lieu of the US-ASCII character set. If no such
-# characters are found, the value shall have each instance of <apostrophe> be
-# replaced by <apostrophe><backslash><apostrophe><apostrophe> before being
-# enclosed by a pair of <apostrophe> characters. Otherwise, non-printable
-# characters shall be replaced by octal escape sequences, <apostrophe> by
-# <backslash><apostrophe> and <backslash> by <backslash><backslash>, prior to
-# the value being given a prefix of <dollar-sign><apostrophe> and a suffix of
-# <apostrophe>, per POSIX-1.2024. Finally, the resulting values shall be printed
-# as <space> separated. The latter quoting strategy can be suppressed by setting
-# the POSIXLY_CORRECT variable as non-empty in the environment.
+# any bytes that are either outside the scope of the US-ASCII character set or
+# which are considered as non-printable. If no such bytes are found, the value
+# shall have each instance of <apostrophe> be replaced by <apostrophe>
+# <backslash> <apostrophe> <apostrophe> before being enclosed by a pair of
+# <apostrophe> characters. However, as a special case, a value consisting of a
+# single <apostrophe> shall be replaced by <backslash> <apostrophe>.
+#
+# If any such bytes are found, the value shall instead be requoted in a manner
+# that conforms with section 2.2.4 of the Shell Command Language, wherein the
+# the use of dollar-single-quotes sequences is described. Such sequences are
+# standard as of POSIX-1.2024. However, as of August 2024, many implementations
+# lack support for this feature. So as to mitigate this state of affairs, the
+# use of dollar-single-quotes may be suppressed by setting POSIXLY_CORRECT as a
+# non-empty string.
 #
 quote_args()
 {
-	awk -v q=\' -f - -- "$@" <<-'EOF'
+	LC_ALL=C awk -v q=\' -f - -- "$@" <<-'EOF'
+	function init_table() {
+		# Iterate over ranges \001-\037 and \177-\377.
+		for (i = 1; i <= 255; i += (i == 31 ? 96 : 1)) {
+			char = sprintf("%c", i)
+			seq_by[char] = sprintf("%03o", i)
+		}
+		seq_by["\007"] = "a"
+		seq_by["\010"] = "b"
+		seq_by["\011"] = "t"
+		seq_by["\012"] = "n"
+		seq_by["\013"] = "v"
+		seq_by["\014"] = "f"
+		seq_by["\015"] = "r"
+		seq_by["\033"] = "e"
+		seq_by["\047"] = "'"
+		seq_by["\134"] = "\\"
+	}
 	BEGIN {
 		strictly_posix = length(ENVIRON["POSIXLY_CORRECT"])
 		argc = ARGC
 		ARGC = 1
 		for (arg_idx = 1; arg_idx < argc; arg_idx++) {
 			arg = ARGV[arg_idx]
-			if (strictly_posix || arg !~ /[\001-\037\177]/) {
+			if (arg == q) {
+				word = "\\" q
+			} else if (strictly_posix || arg !~ /[\001-\037\177-\377]/) {
 				gsub(q, q "\\" q q, arg)
 				word = q arg q
 			} else {
-				# Use $'' quoting per POSIX-1.2024
-				if (! ("\001" in ord_by)) {
-					for (i = 1; i < 32; i++) {
-						char = sprintf("%c", i)
-						ord_by[char] = i
-					}
-					ord_by["\177"] = 127
+				# Use $'' quoting per POSIX-1.2024.
+				if (! ("\001" in seq_by)) {
+					init_table()
 				}
 				word = "$'"
 				for (i = 1; i <= length(arg); i++) {
 					char = substr(arg, i, 1)
-					if (char == "\\") {
-						word = word "\\\\"
-					} else if (char == q) {
-						word = word "\\'"
-					} else if (char in ord_by) {
-						word = word "\\" sprintf("%03o", ord_by[char])
+					if (char in seq_by) {
+						word = word "\\" seq_by[char]
 					} else {
 						word = word char
 					}

diff --git a/test-functions b/test-functions
index f37477c..ef2aa98 100755
--- a/test-functions
+++ b/test-functions
@@ -882,6 +882,25 @@ test_contains_any() {
 	iterate_tests 5 "$@"
 }
 
+test_quote_args() {
+	testnum=$((testnum + 1))
+	retval=0
+	i=0
+	while [ "$(( i += 1 ))" -le 255 ]; do
+		fmt=$(printf '\%o' "$i")
+		str=$(printf "$fmt.")
+		POSIXLY_CORRECT= quote_args "${str%.}" || break
+	done | cksum | {
+		read -r cksum _
+		if [ "${cksum}" != "380900690" ]; then
+			printf 'not '
+			retval=1
+		fi
+		printf 'ok %d - quote_args output test (expected cksum 380900690, got %s)\n' "${testnum}" "${cksum}"
+		return "${retval}"
+	}
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -959,6 +978,7 @@ else
 	#test_substr || rc=1
 	test_contains_all || rc=1
 	test_contains_any || rc=1
+	test_quote_args || rc=1
 fi
 
 cleanup_tmpdir


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     81d81d22d039f3ed966df31c61d8ef5b664f1c4d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug  2 17:31:16 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Aug  2 17:31:16 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=81d81d22

Jettison the bash-specific hr() implementation

Testing the BASH variable for non-emptiness is an inadequate pretext for
activating the bash-optimised code path. Instead, the test would have to
be implemented like so ...

if ! case ${BASH_COMPAT} in 3?|4[012]) false ;; esac && _has_bash 4 3
then
    ...
fi

Given that hr() is not expected to be called often, and that the sh code
was already improved by employing a divide-by-8 strategy, I don't
consider it to be worth the trouble.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/functions.sh b/functions.sh
index 5ef96ae..b7e6c1d 100644
--- a/functions.sh
+++ b/functions.sh
@@ -175,21 +175,15 @@ hr()
 	fi
 	char=${1--}
 	char=${char%"${char#?}"}
-	if [ "${BASH}" ]; then
-		# shellcheck disable=3045
-		printf -v hr '%*s' "${length}" ''
-		eval 'printf %s\\n "${hr//?/"$char"}"'
-	else
-		i=0
-		while [ "$(( i += 8 ))" -le "${length}" ]; do
-			hr=${hr}${char}${char}${char}${char}${char}${char}${char}${char}
-		done
-		i=${#hr}
-		while [ "$(( i += 1 ))" -le "${length}" ]; do
-			hr=${hr}${char}
-		done
-		printf '%s\n' "${hr}"
-	fi
+	i=0
+	while [ "$(( i += 8 ))" -le "${length}" ]; do
+		hr=${hr}${char}${char}${char}${char}${char}${char}${char}${char}
+	done
+	i=${#hr}
+	while [ "$(( i += 1 ))" -le "${length}" ]; do
+		hr=${hr}${char}
+	done
+	printf '%s\n' "${hr}"
 }
 
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     a9dd85a8a1954ee516fc989a04afd7f43e58ffe8
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Aug  2 18:41:50 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Aug  2 18:58:20 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=a9dd85a8

Have hr() employ a divide-by-16 strategy

A factor of 16 was shown to be faster on average by timing how long it
takes for bash to print a rule 5000 times for all lengths between 40 and
132, inclusive.

Factor  Time       StdDev
8       87.004000  3.961607
16      82.893000  3.971257

Further, 16 remains a factor of 80, which is often the number of columns
that a terminal emulator is initialised with.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 12 ++++++------
 test-functions |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/functions.sh b/functions.sh
index b7e6c1d..9b6220b 100644
--- a/functions.sh
+++ b/functions.sh
@@ -164,7 +164,7 @@ has_systemd()
 #
 hr()
 {
-	local char hr i length
+	local c hr i length
 
 	if [ "$#" -ge 2 ] && is_int "$2"; then
 		length=$2
@@ -173,15 +173,15 @@ hr()
 	else
 		length=80
 	fi
-	char=${1--}
-	char=${char%"${char#?}"}
+	c=${1--}
+	c=${c%"${c#?}"}
 	i=0
-	while [ "$(( i += 8 ))" -le "${length}" ]; do
-		hr=${hr}${char}${char}${char}${char}${char}${char}${char}${char}
+	while [ "$(( i += 16 ))" -le "${length}" ]; do
+		hr=${hr}${c}${c}${c}${c}${c}${c}${c}${c}${c}${c}${c}${c}${c}${c}${c}${c}
 	done
 	i=${#hr}
 	while [ "$(( i += 1 ))" -le "${length}" ]; do
-		hr=${hr}${char}
+		hr=${hr}${c}
 	done
 	printf '%s\n' "${hr}"
 }

diff --git a/test-functions b/test-functions
index 43b5320..2ad76e8 100755
--- a/test-functions
+++ b/test-functions
@@ -514,10 +514,10 @@ test_hr() {
 		eq  0  "$(printf '%80s' | tr ' ' -)"  -    N/A  \
 		eq  0  ''                             -    0    \
 		eq  0  -                              -    1    \
-		eq  0  ---------                      -    9    \
+		eq  0  -----------------              -    17    \
 		eq  0  ''                             xyz  0    \
 		eq  0  x                              xyz  1    \
-		eq  0  xxxxxxxxx                      xyz  9
+		eq  0  xxxxxxxxxxxxxxxxx              xyz  17
 
 	callback() {
 		shift


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     9d7875e5c6d7f772918f0dad077c7a582a2647e8
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Jul  9 11:12:16 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Jul  9 11:12:16 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9d7875e5

Mention that _SC_NPROCESSORS_ONLN is now standard

https://austingroupbugs.net/view.php?id=339

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index 7f4bc25..660e697 100644
--- a/functions.sh
+++ b/functions.sh
@@ -349,8 +349,8 @@ get_nprocs()
 		# advantage of acknowledging the effect of sched_setaffinity(2).
 		true
 	elif getconf _NPROCESSORS_ONLN 2>/dev/null; then
-		# This is a non-standard extension. Nevertheless, it works for
-		# glibc, musl-utils, macOS, FreeBSD, NetBSD and OpenBSD.
+		# This constant is standard as of POSIX-1.2024 and was already
+		# supported by glibc, musl-utils, macOS, FreeBSD, NetBSD and OpenBSD.
 		true
 	else
 		warn "get_nprocs: failed to determine the number of processors"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     c8aaf36b70029898822934615283ac3fbf5ae785
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Jul 10 00:22:46 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jul 10 00:26:59 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=c8aaf36b

test-functions: Check whether local is supported

Test whether the (non-standard) local builtin is present and behaving in
a manner considered to be conventional. Should the test fail, refrain
from conducting any further tests. This causes the test suite to fail
early for ksh - a shell not currently supported by the project.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 82 +++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 53 insertions(+), 29 deletions(-)

diff --git a/test-functions b/test-functions
index dab0aea..f37477c 100755
--- a/test-functions
+++ b/test-functions
@@ -24,6 +24,29 @@ cleanup_tmpdir() {
 	fi
 }
 
+test_local() {
+	(
+		var=1
+		f() {
+			local var=2
+			g
+			test "${var}" = 3 || exit
+		}
+		g() {
+			test "${var}" = 2 || exit
+			var=3
+		}
+		f
+		test "${var}" = 1
+	) 2>/dev/null
+	retval=$?
+	if [ "${retval}" -ne 0 ]; then
+		printf 'not '
+	fi
+	printf 'ok %d - /bin/sh supports local\n' "$((testnum += 1))"
+	return "${retval}"
+}
+
 test_chdir() {
 	set -- \
 		ge  1  grandchild  \
@@ -905,38 +928,39 @@ if [ "${PORTAGE_BIN_PATH}" ] && [ "${S}" ]; then
 	genfun_basedir=${S}
 fi
 
-if ! GENFUN_MODULES="portage rc" . ./functions.sh; then
+if ! test_local; then
+	rc=1
+elif ! GENFUN_MODULES="portage rc" . ./functions.sh; then
 	bailout "Couldn't source ./functions.sh"
+else
+	assign_tmpdir
+	test_chdir || rc=1
+	test_chdir_noop || rc=1
+	( test_ebegin ) || rc=1; testnum=$((testnum + 1))
+	test_is_older_than || rc=1
+	test_get_bootparam || rc=1
+	test_esyslog || rc=1
+	test_is_identifier || rc=1
+	test_is_int || rc=1
+	test_is_visible || rc=1
+	test_yesno || rc=1
+	test_die || rc=1
+	test_edo || rc=1
+	test_srandom || rc=1
+	test_newest || rc=1
+	test_trim || rc=1
+	test_hr || rc=1
+	test_whenceforth || rc=1
+	test_parallel_run || rc=1
+	test_is_anyof || rc=1
+	test_is_subset || rc=1
+	test_trueof_all || rc=1
+	test_trueof_any || rc=1
+	#test_substr || rc=1
+	test_contains_all || rc=1
+	test_contains_any || rc=1
 fi
 
-assign_tmpdir
-
-test_chdir || rc=1
-test_chdir_noop || rc=1
-( test_ebegin ) || rc=1; testnum=$((testnum + 1))
-test_is_older_than || rc=1
-test_get_bootparam || rc=1
-test_esyslog || rc=1
-test_is_identifier || rc=1
-test_is_int || rc=1
-test_is_visible || rc=1
-test_yesno || rc=1
-test_die || rc=1
-test_edo || rc=1
-test_srandom || rc=1
-test_newest || rc=1
-test_trim || rc=1
-test_hr || rc=1
-test_whenceforth || rc=1
-test_parallel_run || rc=1
-test_is_anyof || rc=1
-test_is_subset || rc=1
-test_trueof_all || rc=1
-test_trueof_any || rc=1
-#test_substr || rc=1
-test_contains_all || rc=1
-test_contains_any || rc=1
-
 cleanup_tmpdir
 
 printf '1..%d\n' "${testnum}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     74b7514e3de9d0bad82595afcd9ea2c2d936c81f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jul  8 05:46:51 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Jul  8 05:46:51 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=74b7514e

Initialise the genfun_bin_true variable lazily

Also, require for true(1) to be executable in order for it to be deemed
usable.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 58 ++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 32 insertions(+), 26 deletions(-)

diff --git a/functions.sh b/functions.sh
index dd4eef8..ad509fa 100644
--- a/functions.sh
+++ b/functions.sh
@@ -725,28 +725,39 @@ _should_throttle()
 #
 _update_columns()
 {
-	# Two optimisations are applied. Firstly, the rate at which updates can
-	# be performed is throttled to intervals of 5 deciseconds. Secondly, if
-	# running on bash then the COLUMNS variable may be gauged, albeit only
-	# in situations where doing so can be expected to work reliably; not if
-	# in a subshell. Note that executing true(1) is faster than executing
-	# stty(1) within a comsub.
-	# shellcheck disable=3028,3044
-	if _should_throttle 5; then
-		test "${genfun_cols}"
-		return
-	elif [ "$$" = "${BASHPID}" ] && shopt -q checkwinsize; then
-		"${genfun_bin_true}"
-		set -- 0 "${COLUMNS}"
-	else
-		# The following use of stty(1) is portable as of POSIX Issue 8.
-		genfun_ifs=${IFS}
-		IFS=' '
-		# shellcheck disable=2046
-		set -- $(stty size 2>/dev/null)
-		IFS=${genfun_ifs}
+	# shellcheck disable=3044
+	if [ "${BASH}" ] && shopt -q checkwinsize; then
+		genfun_bin_true=$(whenceforth -x true)
 	fi
-	[ "$#" -eq 2 ] && is_int "$2" && [ "$2" -gt 0 ] && genfun_cols=$2
+
+	_update_columns()
+	{
+		# Two optimisations are applied. Firstly, the rate at which
+		# updates can be performed is throttled to intervals of 5
+		# deciseconds. Secondly, if running on bash then the COLUMNS
+		# variable may be gauged, albeit only in situations where doing
+		# so can be expected to work reliably; it is an unreliable
+		# method where operating from a subshell. Note that executing
+		# true(1) is faster than executing stty(1) within a comsub.
+		# shellcheck disable=3028
+		if _should_throttle 5; then
+			test "${genfun_cols}"
+			return
+		elif [ "${genfun_bin_true}" ] && [ "$$" = "${BASHPID}" ]; then
+			"${genfun_bin_true}"
+			set -- 0 "${COLUMNS}"
+		else
+			# This use of stty(1) is portable as of POSIX-1.2024.
+			genfun_ifs=${IFS}
+			IFS=' '
+			# shellcheck disable=2046
+			set -- $(stty size 2>/dev/null)
+			IFS=${genfun_ifs}
+		fi
+		[ "$#" -eq 2 ] && is_int "$2" && [ "$2" -gt 0 ] && genfun_cols=$2
+	}
+
+	_update_columns
 }
 
 #
@@ -872,11 +883,6 @@ fi
 genfun_newline='
 '
 
-# Store the path to the true binary. It is potentially used by _update_columns.
-if [ "${BASH}" ]; then
-	genfun_bin_true=$(whenceforth true)
-fi
-
 # The GENFUN_MODULES variable acts as a means of selecting modules, which are
 # merely optional collections of functions. If unset then set it now.
 if [ ! "${GENFUN_MODULES+set}" ]; then


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-08-02 23:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-08-02 23:14 UTC (permalink / raw
  To: gentoo-commits

commit:     ac5f9575ad1fd7953d8c9c249ae1a0d0d7024e9b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Jul  9 11:01:28 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Jul  9 11:03:54 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=ac5f9575

Have _update_time() measure in centiseconds

Doing so simplifies the case where /proc/uptime is read. Having one more
digit's worth of accuracy is no bad thing either.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 53 ++++++++++++++++++++++-------------------------------
 1 file changed, 22 insertions(+), 31 deletions(-)

diff --git a/functions.sh b/functions.sh
index ad509fa..7f4bc25 100644
--- a/functions.sh
+++ b/functions.sh
@@ -706,7 +706,7 @@ _select_by_mtime() {
 }
 
 #
-# Considers the first parameter as a number of deciseconds and determines
+# Considers the first parameter as a number of centiseconds and determines
 # whether fewer have elapsed since the last occasion on which the function was
 # called.
 #
@@ -733,14 +733,14 @@ _update_columns()
 	_update_columns()
 	{
 		# Two optimisations are applied. Firstly, the rate at which
-		# updates can be performed is throttled to intervals of 5
-		# deciseconds. Secondly, if running on bash then the COLUMNS
-		# variable may be gauged, albeit only in situations where doing
-		# so can be expected to work reliably; it is an unreliable
-		# method where operating from a subshell. Note that executing
-		# true(1) is faster than executing stty(1) within a comsub.
+		# updates can be performed is throttled to intervals of half a
+		# second. Secondly, if running on bash then the COLUMNS variable
+		# may be gauged, albeit only in situations where doing so can be
+		# expected to work reliably; it is an unreliable method where
+		# operating from a subshell. Note that executing true(1) is
+		# faster than executing stty(1) within a comsub.
 		# shellcheck disable=3028
-		if _should_throttle 5; then
+		if _should_throttle 50; then
 			test "${genfun_cols}"
 			return
 		elif [ "${genfun_bin_true}" ] && [ "$$" = "${BASHPID}" ]; then
@@ -761,11 +761,11 @@ _update_columns()
 }
 
 #
-# Determines either the number of deciseconds elapsed since the unix epoch or
-# the number of deciseconds that the operating system has been online, depending
-# on the capabilities of the shell and/or platform. Upon success, the obtained
-# value shall be assigned to genfun_time. Otherwise, the return value shall be
-# greater than 0.
+# Determines either the number of centiseconds elapsed since the unix epoch or
+# the number of centiseconds that the operating system has been online,
+# depending on the capabilities of the shell and/or platform. Upon success, the
+# obtained value shall be assigned to genfun_time. Otherwise, the return value
+# shall be greater than 0.
 #
 _update_time()
 {
@@ -776,34 +776,25 @@ _update_time()
 		# shellcheck disable=2034,3045
 		_update_time()
 		{
-			local ds s timeval
+			local cs s timeval
 
 			timeval=${EPOCHREALTIME}
 			s=${timeval%.*}
-			printf -v ds '%.1f' ".${timeval#*.}"
-			if [ "${ds}" = "1.0" ]; then
-				ds=10
+			printf -v cs '%.2f' ".${timeval#*.}"
+			if [ "${cs}" = "1.00" ]; then
+				cs=100
 			else
-				ds=${ds#0.}
+				cs=${cs#0.} cs=${cs#0}
 			fi
-			genfun_time=$(( s * 10 + ds ))
+			genfun_time=$(( s * 100 + cs ))
 		}
 	elif [ -f /proc/uptime ]; then
 		_update_time()
 		{
-			local cs ds s timeval
+			local cs s
 
-			IFS=' ' read -r timeval _ < /proc/uptime || return
-			s=${timeval%.*}
-			cs=${timeval#*.}
-			case ${cs} in
-				?[0-4])
-					ds=${cs%?}
-					;;
-				?[5-9])
-					ds=$(( ${cs%?} + 1 ))
-			esac
-			genfun_time=$(( s * 10 + ds ))
+			IFS='. ' read -r s cs _ < /proc/uptime \
+			&& genfun_time=$(( s * 100 + ${cs#0} ))
 		}
 	else
 		_update_time()


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-08  3:00 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-08  3:00 UTC (permalink / raw
  To: gentoo-commits

commit:     51fbbf3b0b8dcb7435cfedf91a3d5ef0e94f7912
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jul  8 02:56:19 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Jul  8 02:56:19 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=51fbbf3b

Render _contains_all() compatible with mawk

The mawk implementation does not react well to FS containing an invalid
ERE at any juncture. Address the issue by composing the pattern in full
before assigning it to FS.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/functions.sh b/functions.sh
index 1295a2b..82f59a3 100644
--- a/functions.sh
+++ b/functions.sh
@@ -77,21 +77,20 @@ contains_all()
 		if (length(ifs) == 0) {
 			FS = "^"
 		} else {
-			whitespace = ""
-			FS = "("
+			fs = "("
 			for (i = 1; i <= length(ifs); i++) {
 				char = substr(ifs, i, 1)
 				if (seen[char]++) {
 					continue
 				} else if (char ~ /[ \t\n]/) {
 					whitespace = whitespace char
-					FS = FS "[" char "]+|"
+					fs = fs "[" char "]+|"
 				} else {
-					FS = FS "[" char "]|"
+					fs = fs "[" char "]|"
 				}
 			}
-			sub(/\|$/, "", FS)
-			FS = FS ")"
+			sub(/\|$/, "", fs)
+			FS = fs = fs ")"
 		}
 		# Leading whitespace characters must be removed.
 		if (length(whitespace) > 0) {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-08  2:31 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-08  2:31 UTC (permalink / raw
  To: gentoo-commits

commit:     8ac82c7c7923954765b994de841f82ec2d5456b7
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jul  7 23:16:44 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Jul  7 23:38:27 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=8ac82c7c

Correct the implementation of contains_all()

It was not translating IFS to FS correctly. Have it do so and extend the
test suite accordingly.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   |  36 +++++++++++++----
 test-functions | 126 ++++++++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 122 insertions(+), 40 deletions(-)

diff --git a/functions.sh b/functions.sh
index cfaddc3..ccd0d1d 100644
--- a/functions.sh
+++ b/functions.sh
@@ -61,21 +61,41 @@ chdir()
 #
 contains_all()
 {
-	[ "$#" -ge 2 ] && IFS=${IFS} awk -f - -- "$@" <<-'EOF'
+	# shellcheck disable=2097,2098
+	[ "$#" -ge 2 ] &&
+	IFS=${IFS} awk -v ifs_set=${IFS+1} -f - -- "$@" <<-'EOF'
 	BEGIN {
-		ifs = ENVIRON["IFS"]
 		haystack = ARGV[1]
 		argc = ARGC
 		ARGC = 1
+		if (ifs_set) {
+			ifs = ENVIRON["IFS"]
+		} else {
+			ifs = " \t\n"
+		}
+		# Translate IFS to FS, in accordance with section 2.6.5.
 		if (length(ifs) == 0) {
 			FS = "^"
-		} else if (length(ifs) != 3 || ifs ~ /[^ \t\n]/) {
-			# Split by the first character of IFS.
-			FS = "[" substr(ifs, 1, 1) "]"
 		} else {
-			# Mimic default field splitting behaviour, per section 2.6.5.
-			FS = "[ \t\n]+"
-			sub("^" FS, "", haystack)
+			whitespace = ""
+			FS = "("
+			for (i = 1; i <= length(ifs); i++) {
+				char = substr(ifs, i, 1)
+				if (seen[char]++) {
+					continue
+				} else if (char ~ /[ \t\n]/) {
+					whitespace = whitespace char
+					FS = FS "[" char "]+|"
+				} else {
+					FS = FS "[" char "]|"
+				}
+			}
+			sub(/\|$/, "", FS)
+			FS = FS ")"
+		}
+		# Leading whitespace characters must be removed.
+		if (length(whitespace) > 0) {
+			sub("^[" whitespace "]+", "", haystack)
 		}
 		# In sh, fields are terminated, not separated.
 		sub(FS "$", "", haystack)

diff --git a/test-functions b/test-functions
index 59c0b29..dab0aea 100755
--- a/test-functions
+++ b/test-functions
@@ -721,43 +721,105 @@ test_substr() {
 
 test_contains_all() {
 	set -- \
-		ge  1  N/A         N/A         N/A         N/A  \
-		ge  1  'foo  bar'  ''          N/A         N/A  \
-		ge  1  'foo  bar'  ''          ' '         N/A  \
-		ge  1  'foo  bar'  ''          ' bar'      N/A  \
-		ge  1  'foo  bar'  ''          ' bar'      N/A  \
-		ge  1  'foo  bar'  ''          'foo '      N/A  \
-		ge  1  'foo  bar'  ''          'foo  bar'  N/A  \
-		ge  1  'foo  bar'  ' '         ''          N/A  \
-		ge  1  'foo  bar'  ' '         ' '         N/A  \
-		ge  1  'foo  bar'  ' '         N/A         N/A  \
-		ge  1  'foo  bar'  ' bar'      ''          N/A  \
-		ge  1  'foo  bar'  ' bar'      N/A         N/A  \
-		ge  1  'foo  bar'  'foo '      ''          N/A  \
-		ge  1  'foo  bar'  'foo '      ' bar'      N/A  \
-		ge  1  'foo  bar'  'foo '      N/A         N/A  \
-		ge  1  'foo  bar'  'foo  bar'  ''          N/A  \
-		ge  1  'foo  bar'  'foo  bar'  N/A         N/A  \
-		ge  1  'foo  bar'  N/A         N/A         N/A  \
-		ge  1  'foo  bar'  bar         foo         ''   \
-		ge  1  'foo  bar'  bar         foo         ' '  \
-		ge  1  'foo  bar'  baz         bar         foo  \
-		ge  1  'foo  bar'  fo          ba          N/A  \
-		ge  1  'foo  bar'  foo         bar         ''   \
-		ge  1  'foo  bar'  foo         bar         ' '  \
-		ge  1  'foo  bar'  foo         bar         baz  \
-		ge  1  'foo  bar'  o           a           N/A  \
-		ge  1  'foo  bar'  oo          ar          N/A  \
-		eq  0  'foo  bar'  foo         bar         N/A  \
-		eq  0  'foo  bar'  bar         foo         N/A
+		ge  1  default  N/A           N/A         N/A         N/A  \
+		ge  1  default  ' foo  bar '  ''          N/A         N/A  \
+		ge  1  default  ' foo  bar '  ''          ' '         N/A  \
+		ge  1  default  ' foo  bar '  ''          ' bar'      N/A  \
+		ge  1  default  ' foo  bar '  ''          'foo '      N/A  \
+		ge  1  default  ' foo  bar '  ''          'foo  bar'  N/A  \
+		ge  1  default  ' foo  bar '  ' '         ''          N/A  \
+		ge  1  default  ' foo  bar '  ' '         ' '         N/A  \
+		ge  1  default  ' foo  bar '  ' '         N/A         N/A  \
+		ge  1  default  ' foo  bar '  ' bar'      ''          N/A  \
+		ge  1  default  ' foo  bar '  ' bar'      N/A         N/A  \
+		ge  1  default  ' foo  bar '  'foo '      ''          N/A  \
+		ge  1  default  ' foo  bar '  'foo '      ' bar'      N/A  \
+		ge  1  default  ' foo  bar '  'foo '      N/A         N/A  \
+		ge  1  default  ' foo  bar '  'foo  bar'  ''          N/A  \
+		ge  1  default  ' foo  bar '  'foo  bar'  N/A         N/A  \
+		ge  1  default  ' foo  bar '  N/A         N/A         N/A  \
+		ge  1  default  ' foo  bar '  bar         foo         ''   \
+		ge  1  default  ' foo  bar '  bar         foo         ' '  \
+		ge  1  default  ' foo  bar '  baz         bar         foo  \
+		ge  1  default  ' foo  bar '  fo          ba          N/A  \
+		ge  1  default  ' foo  bar '  foo         bar         ''   \
+		ge  1  default  ' foo  bar '  foo         bar         ' '  \
+		ge  1  default  ' foo  bar '  foo         bar         baz  \
+		ge  1  default  ' foo  bar '  o           a           N/A  \
+		ge  1  default  ' foo  bar '  oo          ar          N/A  \
+		eq  0  default  ' foo  bar '  foo         bar         N/A  \
+		eq  0  default  ' foo  bar '  bar         foo         N/A  \
+		ge  1  ', '     N/A           N/A         N/A         N/A  \
+		ge  1  ', '     ' foo  bar '  ''          N/A         N/A  \
+		ge  1  ', '     ' foo  bar '  ''          ' '         N/A  \
+		ge  1  ', '     ' foo ,bar, ' ''          ','         N/A  \
+		ge  1  ', '     ' foo  bar '  ''          ' bar'      N/A  \
+		ge  1  ', '     ' foo ,bar '  ''          ',bar'      N/A  \
+		ge  1  ', '     ' foo  bar '  ''          'foo '      N/A  \
+		ge  1  ', '     ' foo, bar '  ''          'foo,'      N/A  \
+		ge  1  ', '     ' foo  bar '  ''          'foo  bar'  N/A  \
+		ge  1  ', '     ' foo  bar '  ' '         ''          N/A  \
+		ge  1  ', '     ' foo,bar, '  ','         ''          N/A  \
+		ge  1  ', '     ' foo  bar '  ' '         ' '         N/A  \
+		ge  1  ', '     ',foo,,bar,'  ','         ','         N/A  \
+		ge  1  ', '     ' foo  bar '  ' '         N/A         N/A  \
+		ge  1  ', '     ',foo,,bar,'  ','         N/A         N/A  \
+		ge  1  ', '     ' foo  bar '  ' bar'      ''          N/A  \
+		ge  1  ', '     'foo,bar,'    ',bar'      ''          N/A  \
+		ge  1  ', '     ' foo  bar '  ' bar'      N/A         N/A  \
+		ge  1  ', '     ',foo,,bar,'  ',bar'      N/A         N/A  \
+		ge  1  ', '     ' foo  bar '  'foo '      ''          N/A  \
+		ge  1  ', '     'foo,bar,'    'foo,'      ''          N/A  \
+		ge  1  ', '     ' foo  bar '  'foo '      ' bar'      N/A  \
+		ge  1  ', '     ',foo,,bar,'  'foo,'      ',bar'      N/A  \
+		ge  1  ', '     ' foo  bar '  'foo '      N/A         N/A  \
+		ge  1  ', '     ',foo,,bar,'  'foo,'      N/A         N/A  \
+		ge  1  ', '     ' foo  bar '  'foo  bar'  ''          N/A  \
+		ge  1  ', '     'foo,bar,'    'foo,bar'   ''          N/A  \
+		ge  1  ', '     ' foo  bar '  'foo  bar'  N/A         N/A  \
+		ge  1  ', '     ',foo,,bar,'  'foo,,bar'  N/A         N/A  \
+		ge  1  ', '     ' foo  bar '  N/A         N/A         N/A  \
+		ge  1  ', '     ' foo  bar '  bar         foo         ''   \
+		ge  1  ', '     ' foo,bar  '  bar         foo         ''   \
+		ge  1  ', '     ' foo  bar '  bar         foo         ' '  \
+		ge  1  ', '     ' foo,,bar '  bar         foo         ','  \
+		ge  1  ', '     ' foo  bar '  baz         bar         foo  \
+		ge  1  ', '     ',foo,,bar,'  baz         bar         foo  \
+		ge  1  ', '     ' foo  bar '  fo          ba          N/A  \
+		ge  1  ', '     ',foo,,bar,'  fo          ba          N/A  \
+		ge  1  ', '     ' foo  bar '  foo         bar         ''   \
+		ge  1  ', '     ' foo,bar '   foo         bar         ''   \
+		ge  1  ', '     ' foo  bar '  foo         bar         ' '  \
+		ge  1  ', '     ' foo,,bar '  foo         bar         ','  \
+		ge  1  ', '     ' foo  bar '  foo         bar         baz  \
+		ge  1  ', '     ',foo,,bar,'  foo         bar         baz  \
+		ge  1  ', '     ' foo  bar '  o           a           N/A  \
+		ge  1  ', '     ',foo,,bar,'  o           a           N/A  \
+		ge  1  ', '     ' foo  bar '  oo          ar          N/A  \
+		ge  1  ', '     ',foo,,bar,'  oo          ar          N/A  \
+		eq  0  ', '     ' foo  bar '  foo         bar         N/A  \
+		eq  0  ', '     ',foo  bar,'  foo         bar         N/A  \
+		eq  0  ', '     ' foo,,bar '  foo         bar         N/A  \
+		eq  0  ', '     ',foo,,bar,'  foo         bar         N/A  \
+		eq  0  ', '     ' foo  bar '  bar         foo         N/A  \
+		eq  0  ', '     ',foo  bar,'  bar         foo         N/A  \
+		eq  0  ', '     ' foo,,bar '  bar         foo         N/A  \
+		eq  0  ', '     ',foo,,bar,'  bar         foo         N/A
 
 	callback() {
 		shift
-		test_description="contains_all $(quote_args "$@")"
-		contains_all "$@"
+		ifs=$1
+		shift
+		if [ "${ifs}" = "default" ]; then
+			test_description="contains_all $(quote_args "$@")"
+			contains_all "$@"
+		else
+			test_description="IFS='${ifs}' contains_all $(quote_args "$@")"
+			IFS=${ifs} contains_all "$@"
+		fi
 	}
 
-	iterate_tests 6 "$@"
+	iterate_tests 7 "$@"
 }
 
 test_contains_any() {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-08  2:31 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-08  2:31 UTC (permalink / raw
  To: gentoo-commits

commit:     d639ef781b644478213025450c26fe802cee2a7e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jul  8 02:03:12 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Jul  8 02:04:28 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d639ef78

Have _update_time() use a faster rounding method for sh

Directly implement a round half up algorithm for sh, thereby avoiding a
command substitution and a potential subshell along with it.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/functions.sh b/functions.sh
index ccd0d1d..1295a2b 100644
--- a/functions.sh
+++ b/functions.sh
@@ -755,16 +755,18 @@ _update_time()
 	elif [ -f /proc/uptime ]; then
 		_update_time()
 		{
-			local ds s timeval
+			local cs ds s timeval
 
 			IFS=' ' read -r timeval _ < /proc/uptime || return
 			s=${timeval%.*}
-			ds=$(printf '%.1f' ".${timeval#*.}")
-			if [ "${ds}" = "1.0" ]; then
-				ds=10
-			else
-				ds=${ds#0.}
-			fi
+			cs=${timeval#*.}
+			case ${cs} in
+				?[0-4])
+					ds=${cs%?}
+					;;
+				?[5-9])
+					ds=$(( ${cs%?} + 1 ))
+			esac
 			genfun_time=$(( s * 10 + ds ))
 		}
 	else


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-07  5:55 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-07  5:55 UTC (permalink / raw
  To: gentoo-commits

commit:     44dfa57e789d4549166a5c8eea4748f92db8583d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun 27 19:38:40 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 28 17:39:01 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=44dfa57e

Have whenceforce() require the -x option to check the execute bit

This renders the behaviour of whenceforth() almost equivalent to type -P
in the absence of the -x option, the exception being that whenceforth()
never consults the hash table.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 32 +++++++++++++++++++++++---------
 test-functions | 57 +++++++++++++++++++++++++++++++++++++--------------------
 2 files changed, 60 insertions(+), 29 deletions(-)

diff --git a/functions.sh b/functions.sh
index 367c4a3..4f6c0a0 100644
--- a/functions.sh
+++ b/functions.sh
@@ -565,23 +565,37 @@ warn()
 }
 
 #
-# Considers the first parameter as the potential name of an executable regular
-# file before attempting to locate it. If not specified as an absolute pathname,
-# a PATH search shall be performed in accordance with the Environment Variables
-# section of the Base Definitions. If an executable is found, its path shall be
-# printed. Otherwise, the return value shall be 1. This function is intended as
-# an alternative to type -P in bash. That is, it is useful for determining the
+# Considers the first parameter as a command name before trying to locate it as
+# a regular file. If not specified as an absolute pathname, a PATH search shall
+# be performed in accordance with the Environment Variables section of the Base
+# Definitions. If a file is found, its path shall be printed. Otherwise, the
+# return value shall be 1. If the -x option is specified then the file must
+# also be executable by the present user in order to be matched. This function
+# serves as an alternative to type -P in bash. It is useful for determining the
 # existence and location of an external utility without potentially matching
 # against aliases, builtins and functions (as command -v can).
 #
 whenceforth()
 (
-	local bin path prefix
+	local bin executable opt path prefix
+
+	executable=
+	while getopts :x opt; do
+		case ${opt} in
+			x)
+				executable=1
+				;;
+			'?')
+				_warn_for_args whenceforth "-${OPTARG}"
+				return 1
+		esac
+	done
+	shift "$(( OPTIND - 1 ))"
 
 	case $1 in
 		/*)
 			# Absolute command paths must be directly checked.
-			[ -f "$1" ] && [ -x "$1" ] && bin=$1
+			test -f "$1" && test ${executable:+-x} "$1" && bin=$1
 			;;
 		*)
 			# Relative command paths must be searched for in PATH.
@@ -603,7 +617,7 @@ whenceforth()
 					*)
 						bin=${prefix:-.}/$1
 				esac
-				[ -f "${bin}" ] && [ -x "${bin}" ] && break
+				test -f "${bin}" && test ${executable:+-x} "${bin}" && break
 			done
 	esac \
 	&& printf '%s\n' "${bin}"

diff --git a/test-functions b/test-functions
index 736836b..68e73eb 100755
--- a/test-functions
+++ b/test-functions
@@ -508,24 +508,40 @@ test_hr() {
 }
 
 test_whenceforth() {
-	set -- \
-		ge  1  PATH                        N/A                       \
-		ge  1  PATH                        .                         \
-		ge  1  PATH                        rather-unlikely-to-exist  \
-		ge  1  PATH                        /var/empty                \
-		ge  1  PATH                        /var/empty/nofile         \
-		eq  0  PATH                        /bin/sh                   \
-		eq  0  PATH                        sh                        \
-		eq  0  ''                          newer/file                \
-		eq  0  .                           newer/file                \
-		eq  0  :/var/empty/x               newer/file                \
-		eq  0  /var/empty/x:               newer/file                \
-		eq  0  /var/empty/x::/var/empty/y  newer/file                \
-		ge  1  ''                          older/file                \
-		ge  1  .                           older/file                \
-		ge  1  :/var/empty/x               older/file                \
-		ge  1  /var/empty/x:               older/file                \
-		ge  1  /var/empty/x::/var/empty/y  older/file
+	set  --  \
+		ge  1  PATH                        N/A                N/A                \
+		ge  1  PATH                        .                  N/A                \
+		ge  1  PATH                        unlikely-to-exist  N/A                \
+		ge  1  PATH                        /var/empty         N/A                \
+		ge  1  PATH                        /var/empty/nofile  N/A                \
+		eq  0  PATH                        /bin/sh            N/A                \
+		eq  0  PATH                        sh                 N/A                \
+		ge  1  PATH                        -x                 .                  \
+		ge  1  PATH                        -x                 unlikely-to-exist  \
+		ge  1  PATH                        -x                 /var/empty         \
+		ge  1  PATH                        -x                 /var/empty/nofile  \
+		eq  0  PATH                        -x                 /bin/sh            \
+		eq  0  PATH                        -x                 sh                 \
+		eq  0  ''                          -x                 newer/file         \
+		eq  0  .                           -x                 newer/file         \
+		eq  0  :/var/empty/x               -x                 newer/file         \
+		eq  0  /var/empty/x:               -x                 newer/file         \
+		eq  0  /var/empty/x::/var/empty/y  -x                 newer/file         \
+		eq  0  ''                          -x                 newer/file         \
+		eq  0  .                           -x                 newer/file         \
+		eq  0  :/var/empty/x               -x                 newer/file         \
+		eq  0  /var/empty/x:               -x                 newer/file         \
+		eq  0  /var/empty/x::/var/empty/y  -x                 newer/file         \
+		eq  0  ''                          older/file         N/A                \
+		eq  0  .                           older/file         N/A                \
+		eq  0  :/var/empty/x               older/file         N/A                \
+		eq  0  /var/empty/x:               older/file         N/A                \
+		eq  0  /var/empty/x::/var/empty/y  older/file         N/A                \
+		ge  1  ''                          -x                 older/file         \
+		ge  1  .                           -x                 older/file         \
+		ge  1  :/var/empty/x               -x                 older/file         \
+		ge  1  /var/empty/x:               -x                 older/file         \
+		ge  1  /var/empty/x::/var/empty/y  -x                 older/file
 
 	chmod +x newer/file
 
@@ -533,15 +549,16 @@ test_whenceforth() {
 		shift
 		path=$1
 		shift
-		test_description="whenceforth $(quote_args "$@")"
 		if [ "${path}" = PATH ]; then
+			test_description="whenceforth $(quote_args "$@")"
 			whenceforth "$@" >/dev/null
 		else
+			test_description="PATH=${path} whenceforth $(quote_args "$@")"
 			PATH=${path} whenceforth "$@" >/dev/null
 		fi
 	}
 
-	iterate_tests 4 "$@"
+	iterate_tests 5 "$@"
 }
 
 test_get_nprocs() {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-07  5:55 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-07  5:55 UTC (permalink / raw
  To: gentoo-commits

commit:     7dec95c33a711a01f90993ee08a06de6df1a0806
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun 27 17:24:03 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 28 17:39:01 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7dec95c3

Implement array membership tests idiomatically in quote_args()

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/functions.sh b/functions.sh
index 3dd6239..367c4a3 100644
--- a/functions.sh
+++ b/functions.sh
@@ -377,7 +377,7 @@ quote_args()
 				word = q arg q
 			} else {
 				# Use $'' quoting per Issue 8
-				if (ord_by["\001"] == "") {
+				if (! ("\001" in ord_by)) {
 					for (i = 1; i < 32; i++) {
 						char = sprintf("%c", i)
 						ord_by[char] = i
@@ -391,13 +391,10 @@ quote_args()
 						word = word "\\\\"
 					} else if (char == q) {
 						word = word "\\'"
+					} else if (char in ord_by) {
+						word = word "\\" sprintf("%03o", ord_by[char])
 					} else {
-						ord = ord_by[char]
-						if (ord != "") {
-							word = word "\\" sprintf("%03o", ord)
-						} else {
-							word = word char
-						}
+						word = word char
 					}
 				}
 				word = word q


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-07  5:55 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-07  5:55 UTC (permalink / raw
  To: gentoo-commits

commit:     7f4c121af64e938daba2a30579078bedb760baac
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun 27 15:25:31 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 28 17:39:01 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7f4c121a

Use printf -v only for bash in _update_time()

After all, the -v option is an extension. This was a mistake made
through copying and pasting during a bout of refactoring and rebasing.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index faf9d64..798c6c7 100644
--- a/functions.sh
+++ b/functions.sh
@@ -702,7 +702,7 @@ _update_time()
 
 			IFS=' ' read -r timeval _ < /proc/uptime || return
 			s=${timeval%.*}
-			printf -v ds '%.1f' ".${timeval#*.}"
+			ds=$(printf '%.1f' ".${timeval#*.}")
 			if [ "${ds}" = "1.0" ]; then
 				ds=10
 			else


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-07  5:55 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-07  5:55 UTC (permalink / raw
  To: gentoo-commits

commit:     2a0c3ce54dda9e72310745d04960bcea7071fc4e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jul  1 01:34:25 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Jul  1 02:32:27 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2a0c3ce5

Add the contains_all() and contains_any() functions

Here are some examples which presume the default value of IFS.

contains_all " cat mat " cat dog # returns 1
contains_all " cat mat " mat cat # returns 0
contains_any " cat mat " cat dog # returns 0
contains_any " cat mat " dog     # returns 1

Here are some examples showing that IFS is taken into account.

IFS=, contains_all "cat,mat" cat dog # returns 1
IFS=, contains_all "cat,mat" mat cat # returns 0
IFS=, contains_any "cat,mat" cat dog # returns 0
IFS=, contains_any "cat,mat" dog     # returns 1

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 117 +++++++++++++++++++++++++++++++++++++++++++++------------
 test-functions |  80 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 172 insertions(+), 25 deletions(-)

diff --git a/functions.sh b/functions.sh
index 1926c40..a4fa946 100644
--- a/functions.sh
+++ b/functions.sh
@@ -17,7 +17,7 @@
 # COLUMNS          : may be used by _update_columns() to get the column count
 # EPOCHREALTIME    : potentially used by _update_time() to get the time
 # GENFUN_MODULES   : which of the optional function collections must be sourced
-# IFS              : multiple warn() operands are joined by its first character
+# IFS              : affects contains_all(), contains_any() and warn()
 # INVOCATION_ID    : used by from_unit()
 # PORTAGE_BIN_PATH : used by from_portage()
 # RC_OPENRC_PID    : used by from_runscript()
@@ -48,6 +48,96 @@ chdir()
 	CDPATH= cd -- "$@"
 }
 
+#
+# Takes the first parameter as a string comprising zero or more words, composes
+# a set consisting of the intersection of those words, then determines whether
+# the intersection of the remaining parameters forms a subset thereof. The
+# words shall be collected by splitting the string into individual fields, in
+# accordance with section 2.6.5 of the Shell Command Language specification.
+# Therefore, the value of IFS shall be taken into account. If fewer than two
+# parameters are provided, or if the first parameter yields no fields, or if the
+# second set is disjoint from - or a superset of - the first, the return value
+# shall be greater than 0.
+#
+contains_all()
+{
+	[ "$#" -ge 2 ] && IFS=${IFS} awk -f - -- "$@" <<-'EOF'
+	BEGIN {
+		ifs = ENVIRON["IFS"]
+		haystack = ARGV[1]
+		argc = ARGC
+		ARGC = 1
+		if (length(ifs) == 0) {
+			FS = "^"
+		} else if (length(ifs) != 3 || ifs ~ /[^ \t\n]/) {
+			# Split by the first character of IFS.
+			FS = "[" substr(ifs, 1, 1) "]"
+		} else {
+			# Mimic default field splitting behaviour, per section 2.6.5.
+			FS = "[ \t\n]+"
+			sub("^" FS, "", haystack)
+		}
+		# In sh, fields are terminated, not separated.
+		sub(FS "$", "", haystack)
+		len = split(haystack, words)
+		for (i = 1; i <= len; i++) {
+			set2[words[i]]
+		}
+		for (i = 2; i < argc; i++) {
+			set1[ARGV[i]]
+		}
+		for (word in set2) {
+			delete set1[word]
+		}
+		for (word in set1) {
+			exit 1
+		}
+	}
+	EOF
+}
+
+#
+# Takes the first parameter as a string comprising zero or more words then
+# determines whether at least one of the remaining parameters can be matched
+# against any of those words. The words shall be collected by splitting the
+# string into individual fields, in accordance with section 2.6.5 of the Shell
+# Command Language specification. Therefore, the value of IFS shall be taken
+# into account. If fewer than two parameters are provided, or if the first
+# parameter yields no fields, or if none of the following parameters can be
+# matched, the return value shall be greater than 0.
+#
+contains_any()
+{
+	local had_noglob haystack i item needle retval
+
+	[ "$#" -ge 2 ] || return
+	haystack=$1
+	shift
+	i=0
+	case $- in
+		*f*)
+			had_noglob=1
+			;;
+		*)
+			had_noglob=0
+	esac
+	set -f
+	for needle; do
+		if [ "$(( i += 1 ))" -eq 1 ]; then
+			# shellcheck disable=2086
+			set -- ${haystack}
+		fi
+		for item; do
+			[ "${item}" = "${needle}" ] && break 2
+		done
+	done
+	retval=$?
+	if [ "${had_noglob}" -eq 0 ]; then
+		set +f
+	fi
+	return "${retval}"
+}
+
 #
 # Considers the first parameter as an URL then attempts to fetch it with either
 # curl(1) or wget(1). If the URL does not contain a scheme then the https://
@@ -585,29 +675,6 @@ whenceforth()
 
 #------------------------------------------------------------------------------#
 
-#
-# Considers the first parameter as containing zero or more blank-separated words
-# then determines whether any of the remaining parameters can be matched in
-# their capacity as discrete words.
-#
-_contains_word()
-{
-	local word wordlist
-
-	wordlist=$1 word=$2
-	case ${word} in
-		''|*[[:blank:]]*)
-			;;
-		*)
-			case " ${wordlist} " in
-				*[[:blank:]]"${word}"[[:blank:]]*)
-					return
-					;;
-			esac
-	esac
-	false
-}
-
 #
 # Determines whether the terminal is a dumb one.
 #
@@ -761,7 +828,7 @@ _want_module()
 	local basename
 
 	basename=${1##*/}
-	_contains_word "${GENFUN_MODULES}" "${basename%.sh}"
+	contains_any "${GENFUN_MODULES}" "${basename%.sh}"
 }
 
 #

diff --git a/test-functions b/test-functions
index 34ff54a..59c0b29 100755
--- a/test-functions
+++ b/test-functions
@@ -719,6 +719,84 @@ test_substr() {
 	iterate_tests 6 "$@"
 }
 
+test_contains_all() {
+	set -- \
+		ge  1  N/A         N/A         N/A         N/A  \
+		ge  1  'foo  bar'  ''          N/A         N/A  \
+		ge  1  'foo  bar'  ''          ' '         N/A  \
+		ge  1  'foo  bar'  ''          ' bar'      N/A  \
+		ge  1  'foo  bar'  ''          ' bar'      N/A  \
+		ge  1  'foo  bar'  ''          'foo '      N/A  \
+		ge  1  'foo  bar'  ''          'foo  bar'  N/A  \
+		ge  1  'foo  bar'  ' '         ''          N/A  \
+		ge  1  'foo  bar'  ' '         ' '         N/A  \
+		ge  1  'foo  bar'  ' '         N/A         N/A  \
+		ge  1  'foo  bar'  ' bar'      ''          N/A  \
+		ge  1  'foo  bar'  ' bar'      N/A         N/A  \
+		ge  1  'foo  bar'  'foo '      ''          N/A  \
+		ge  1  'foo  bar'  'foo '      ' bar'      N/A  \
+		ge  1  'foo  bar'  'foo '      N/A         N/A  \
+		ge  1  'foo  bar'  'foo  bar'  ''          N/A  \
+		ge  1  'foo  bar'  'foo  bar'  N/A         N/A  \
+		ge  1  'foo  bar'  N/A         N/A         N/A  \
+		ge  1  'foo  bar'  bar         foo         ''   \
+		ge  1  'foo  bar'  bar         foo         ' '  \
+		ge  1  'foo  bar'  baz         bar         foo  \
+		ge  1  'foo  bar'  fo          ba          N/A  \
+		ge  1  'foo  bar'  foo         bar         ''   \
+		ge  1  'foo  bar'  foo         bar         ' '  \
+		ge  1  'foo  bar'  foo         bar         baz  \
+		ge  1  'foo  bar'  o           a           N/A  \
+		ge  1  'foo  bar'  oo          ar          N/A  \
+		eq  0  'foo  bar'  foo         bar         N/A  \
+		eq  0  'foo  bar'  bar         foo         N/A
+
+	callback() {
+		shift
+		test_description="contains_all $(quote_args "$@")"
+		contains_all "$@"
+	}
+
+	iterate_tests 6 "$@"
+}
+
+test_contains_any() {
+	set -- \
+		ge  1  N/A        N/A        N/A        \
+		ge  1  'foo bar'  N/A        N/A        \
+		ge  1  'foo bar'  fo         ba         \
+		ge  1  'foo bar'  oo         ar         \
+		ge  1  'foo bar'  o          a          \
+		ge  1  'foo bar'  'foo bar'  'foo bar'  \
+		ge  1  'foo bar'  'foo bar'  _          \
+		ge  1  'foo bar'  _          'foo bar'  \
+		ge  1  'foo bar'  'foo '     ' bar'     \
+		ge  1  'foo bar'  'foo '     _          \
+		ge  1  'foo bar'  _          ' bar'     \
+		ge  1  'foo bar'  ' bar'     _          \
+		ge  1  'foo bar'  _          'foo '     \
+		ge  1  'foo bar'  ''         ''         \
+		ge  1  'foo bar'  ''         _          \
+		ge  1  'foo bar'  _          ''         \
+		ge  1  'foo bar'  ' '        ' '        \
+		ge  1  'foo bar'  ' '        _          \
+		ge  1  'foo bar'  _          ' '        \
+		eq  0  'foo bar'  foo        bar        \
+		eq  0  'foo bar'  bar        foo        \
+		eq  0  'foo bar'  foo        _          \
+		eq  0  'foo bar'  _          bar        \
+		eq  0  'foo bar'  bar        _          \
+		eq  0  'foo bar'  _          foo
+
+	callback() {
+		shift
+		test_description="contains_any $(quote_args "$@")"
+		contains_any "$@"
+	}
+
+	iterate_tests 5 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -794,6 +872,8 @@ test_is_subset || rc=1
 test_trueof_all || rc=1
 test_trueof_any || rc=1
 #test_substr || rc=1
+test_contains_all || rc=1
+test_contains_any || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-07  5:55 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-07  5:55 UTC (permalink / raw
  To: gentoo-commits

commit:     6e79dbc50ddfe25cb1746ca6ce7cdaca9e1c9822
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun 27 20:03:46 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 28 17:39:01 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6e79dbc5

Describe the SENTINEL variable

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/functions.sh b/functions.sh
index 4f6c0a0..87c2085 100644
--- a/functions.sh
+++ b/functions.sh
@@ -21,6 +21,7 @@
 # INVOCATION_ID    : used by from_unit()
 # PORTAGE_BIN_PATH : used by from_portage()
 # RC_OPENRC_PID    : used by from_runscript()
+# SENTINEL         : can define a value separating two distinct argument lists
 # SYSTEMD_EXEC_PID : used by from_unit()
 # TERM             : used to detect dumb terminals
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-07  5:55 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-07  5:55 UTC (permalink / raw
  To: gentoo-commits

commit:     31fe87701736e117803a19211fb40bf7f518ae68
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun 27 17:19:40 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 28 17:39:01 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=31fe8770

Align the indentation of inlined awk programs with their respective heredocs

This also makes it more pleasant to read where using the (proper) tab
size of 8 spaces.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 128 +++++++++++++++++++++++++++++------------------------------
 1 file changed, 64 insertions(+), 64 deletions(-)

diff --git a/functions.sh b/functions.sh
index 4103f9d..3dd6239 100644
--- a/functions.sh
+++ b/functions.sh
@@ -152,12 +152,12 @@ hr()
 		length=80
 	fi
 	PATTERN=${1:--} awk -v "width=${length}" -f - <<-'EOF'
-		BEGIN {
-			while (length(rule) < width) {
-				rule = rule substr(ENVIRON["PATTERN"], 1, width - length(rule))
-			}
-			print rule
+	BEGIN {
+		while (length(rule) < width) {
+			rule = rule substr(ENVIRON["PATTERN"], 1, width - length(rule))
 		}
+		print rule
+	}
 	EOF
 }
 
@@ -227,31 +227,31 @@ is_anyof()
 is_subset()
 {
 	SENTINEL=${SENTINEL-'--'} awk -f - -- "$@" <<-'EOF'
-		BEGIN {
-			argc = ARGC
-			ARGC = 1
-			for (i = 1; i < argc; i++) {
-				word = ARGV[i]
-				if (word == ENVIRON["SENTINEL"]) {
-					break
-				} else {
-					set1[word]
-				}
-			}
-			if (i == 1 || argc - i < 2) {
-				exit 1
-			}
-			for (i++; i < argc; i++) {
-				word = ARGV[i]
-				set2[word]
-			}
-			for (word in set2) {
-				delete set1[word]
-			}
-			for (word in set1) {
-				exit 1
+	BEGIN {
+		argc = ARGC
+		ARGC = 1
+		for (i = 1; i < argc; i++) {
+			word = ARGV[i]
+			if (word == ENVIRON["SENTINEL"]) {
+				break
+			} else {
+				set1[word]
 			}
 		}
+		if (i == 1 || argc - i < 2) {
+			exit 1
+		}
+		for (i++; i < argc; i++) {
+			word = ARGV[i]
+			set2[word]
+		}
+		for (word in set2) {
+			delete set1[word]
+		}
+		for (word in set1) {
+			exit 1
+		}
+	}
 	EOF
 }
 
@@ -366,49 +366,49 @@ parallel_run()
 quote_args()
 {
 	awk -v q=\' -f - -- "$@" <<-'EOF'
-		BEGIN {
-			strictly_posix = length(ENVIRON["POSIXLY_CORRECT"])
-			argc = ARGC
-			ARGC = 1
-			for (arg_idx = 1; arg_idx < argc; arg_idx++) {
-				arg = ARGV[arg_idx]
-				if (strictly_posix || arg !~ /[\001-\037\177]/) {
-					gsub(q, q "\\" q q, arg)
-					word = q arg q
-				} else {
-					# Use $'' quoting per Issue 8
-					if (ord_by["\001"] == "") {
-						for (i = 1; i < 32; i++) {
-							char = sprintf("%c", i)
-							ord_by[char] = i
-						}
-						ord_by["\177"] = 127
+	BEGIN {
+		strictly_posix = length(ENVIRON["POSIXLY_CORRECT"])
+		argc = ARGC
+		ARGC = 1
+		for (arg_idx = 1; arg_idx < argc; arg_idx++) {
+			arg = ARGV[arg_idx]
+			if (strictly_posix || arg !~ /[\001-\037\177]/) {
+				gsub(q, q "\\" q q, arg)
+				word = q arg q
+			} else {
+				# Use $'' quoting per Issue 8
+				if (ord_by["\001"] == "") {
+					for (i = 1; i < 32; i++) {
+						char = sprintf("%c", i)
+						ord_by[char] = i
 					}
-					word = "$'"
-					for (i = 1; i <= length(arg); i++) {
-						char = substr(arg, i, 1)
-						if (char == "\\") {
-							word = word "\\\\"
-						} else if (char == q) {
-							word = word "\\'"
+					ord_by["\177"] = 127
+				}
+				word = "$'"
+				for (i = 1; i <= length(arg); i++) {
+					char = substr(arg, i, 1)
+					if (char == "\\") {
+						word = word "\\\\"
+					} else if (char == q) {
+						word = word "\\'"
+					} else {
+						ord = ord_by[char]
+						if (ord != "") {
+							word = word "\\" sprintf("%03o", ord)
 						} else {
-							ord = ord_by[char]
-							if (ord != "") {
-								word = word "\\" sprintf("%03o", ord)
-							} else {
-								word = word char
-							}
+							word = word char
 						}
 					}
-					word = word q
-				}
-				line = line word
-				if (arg_idx < argc - 1) {
-					line = line " "
 				}
+				word = word q
+			}
+			line = line word
+			if (arg_idx < argc - 1) {
+				line = line " "
 			}
-			print line
 		}
+		print line
+	}
 	EOF
 }
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-07  5:55 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-07  5:55 UTC (permalink / raw
  To: gentoo-commits

commit:     076c24b986e10aa76cbd614643c87a4c15af6a13
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun 27 20:54:45 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 28 17:39:33 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=076c24b9

Use curly braces around a variable expansion in chdir()

Thus adhering to Gentoo's convention.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 87c2085..087b62d 100644
--- a/functions.sh
+++ b/functions.sh
@@ -37,7 +37,7 @@
 #
 chdir()
 {
-	if [ "$BASH" ]; then
+	if [ "${BASH}" ]; then
 		# shellcheck disable=3044
 		shopt -u cdable_vars
 	fi


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-07  5:55 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-07  5:55 UTC (permalink / raw
  To: gentoo-commits

commit:     9caeb57e67c48376fbd7d8121ae4d3a9e1888b35
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun 27 15:15:51 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 28 17:39:01 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9caeb57e

Add the substr() function

POSIX sh does not support substring expansion so it may come in handy.
The implementation is based on the awk function of the same name.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 41 +++++++++++++++++++++++++++++++++++++++++
 test-functions | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)

diff --git a/functions.sh b/functions.sh
index 798c6c7..43a21e4 100644
--- a/functions.sh
+++ b/functions.sh
@@ -438,6 +438,47 @@ srandom()
 	srandom
 }
 
+#
+# Takes the first parameter as a string (s), the second parameter as a numerical
+# position (m) and, optionally, the third parameter as a numerical length (n).
+# It shall then print a <newline> terminated substring of s that is at most, n
+# characters in length and which begins at position m, numbering from 1. If n is
+# omitted, or if n specifies more characters than are left in the string, the
+# length of the substring shall be limited by the length of s. The function
+# shall return 0 provided that none of the parameters are invalid.
+#
+substr()
+{
+	local i str
+
+	if [ "$#" -lt 2 ]; then
+		warn "substr: too few arguments (got $#, expected at least 2)"
+		return 1
+	elif ! is_int "$2"; then
+		_warn_for_args substr "$2"
+		return 1
+	elif [ "$#" -ge 3 ]; then
+		if ! is_int "$3"; then
+			_warn_for_args substr "$3"
+			return 1
+		elif [ "$3" -lt 0 ]; then
+			set -- "$1" "$2" 0
+		fi
+	fi
+	str=$1
+	i=0
+	while [ "$(( i += 1 ))" -lt "$2" ]; do
+		str=${str#?}
+	done
+	i=0
+	while [ "${#str}" -gt "${3-${#str}}" ]; do
+		str=${str%?}
+	done
+	if [ "${#str}" -gt 0 ]; then
+		printf '%s\n' "${str}"
+	fi
+}
+
 #
 # Trims leading and trailing whitespace from one or more lines. If at least one
 # parameter is provided, each positional parameter shall be considered as a line

diff --git a/test-functions b/test-functions
index 13be61c..736836b 100755
--- a/test-functions
+++ b/test-functions
@@ -664,6 +664,44 @@ test_trueof_any() {
 	iterate_tests 7 "$@"
 }
 
+test_substr() {
+	set -- \
+		ge  1  -       foobar  N/A  N/A  \
+		ge  1  -       foobar  ''   N/A  \
+		ge  1  -       foobar  x    N/A  \
+		ge  1  -       foobar  ''   ''   \
+		ge  1  -       foobar  x    y    \
+		eq  0  foobar  foobar  1    N/A  \
+		eq  0  foobar  foobar  -1   N/A  \
+		eq  0  foobar  foobar  1    7    \
+		eq  0  foobar  foobar  -1   7    \
+		eq  0  foo     foobar  1    3    \
+		eq  0  foo     foobar  -1   3    \
+		eq  0  f       foobar  1    1    \
+		eq  0  f       foobar  -1   1    \
+		eq  0  ''      foobar  1    0    \
+		eq  0  ''      foobar  1    -1   \
+		eq  0  ''      foobar  0    0    \
+		eq  0  ''      foobar  0    -1   \
+		eq  0  ''      foobar  -1   0    \
+		eq  0  ''      foobar  -1   -1   \
+		eq  0  bar     foobar  4    N/A  \
+		eq  0  bar     foobar  4    4    \
+		eq  0  b       foobar  4    1    \
+		eq  0  ''      foobar  4    0    \
+		eq  0  ''      foobar  4    -1
+
+	callback() {
+		shift
+		expected=$1
+		shift
+		test_description="substr $(quote_args "$@")"
+		str=$(substr "$@") && test "${str}" = "${expected}"
+	}
+
+	iterate_tests 6 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -738,6 +776,7 @@ test_is_anyof || rc=1
 test_is_subset || rc=1
 test_trueof_all || rc=1
 test_trueof_any || rc=1
+test_substr || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-07  5:55 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-07  5:55 UTC (permalink / raw
  To: gentoo-commits

commit:     97812b30f2810a29a4ade83b31514877254f63e3
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun 27 17:04:59 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 28 17:39:01 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=97812b30

Rectify a grammatical error in fetch()

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 43a21e4..4103f9d 100644
--- a/functions.sh
+++ b/functions.sh
@@ -82,7 +82,7 @@ fetch()
 			wget -nv -O - --connect-timeout 10 -- "$@"
 		}
 	else
-		warn "fetch: this function requires that curl or wget to be installed"
+		warn "fetch: this function requires that curl or wget be installed"
 		return 127
 	fi
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-07-07  5:55 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-07-07  5:55 UTC (permalink / raw
  To: gentoo-commits

commit:     33d5c19549aa60568dbc6c9faf6f426f7193fbd1
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun 27 13:26:27 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Jun 27 13:26:27 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=33d5c195

Don't explicitly assign the empty string in is_subset()

While it is correct to do so, the key may be created without assignment.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index afc170a..faf9d64 100644
--- a/functions.sh
+++ b/functions.sh
@@ -235,7 +235,7 @@ is_subset()
 				if (word == ENVIRON["SENTINEL"]) {
 					break
 				} else {
-					set1[word] = ""
+					set1[word]
 				}
 			}
 			if (i == 1 || argc - i < 2) {
@@ -243,7 +243,7 @@ is_subset()
 			}
 			for (i++; i < argc; i++) {
 				word = ARGV[i]
-				set2[word] = ""
+				set2[word]
 			}
 			for (word in set2) {
 				delete set1[word]


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-25  4:06 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-25  4:06 UTC (permalink / raw
  To: gentoo-commits

commit:     cd943e5ff05dcf221c5137720a902b620e23a54f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun 23 20:02:00 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Jun 23 21:19:15 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=cd943e5f

Rectify several typos among the comments

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/functions.sh b/functions.sh
index d80a49c..55b6c3e 100644
--- a/functions.sh
+++ b/functions.sh
@@ -132,7 +132,7 @@ is_identifier()
 
 #
 # Determines whether the first parameter is a valid integer. A leading
-# <hypen-minus> shall be permitted. Thereafter, leading zeroes shall not be
+# <hyphen-minus> shall be permitted. Thereafter, leading zeroes shall not be
 # permitted because the string might later be considered to be octal in an
 # arithmetic context, causing the shell to exit if the number be invalid.
 #
@@ -176,10 +176,10 @@ is_anyof()
 #
 # Collects the intersection of the parameters up to - but not including - a
 # sentinel value then determines whether the resulting set is a subset of the
-# interection of the remaining parameters. If the SENTINEL variable is set and
+# intersection of the remaining parameters. If the SENTINEL variable is set and
 # non-empty, it shall be taken as the value of the sentinel. Otherwise, the
 # value of the sentinel shall be defined as <hyphen-dash><hyphen-dash>. If the
-# sentinel value is not encountered or if either set is empty then the returm
+# sentinel value is not encountered or if either set is empty then the return
 # value shall be greater than 1.
 #
 is_subset()
@@ -422,7 +422,7 @@ warn()
 
 #
 # Considers the first parameter as the potential name of an executable regular
-# file before attempting to locate it. If not specifed as an absolute pathname,
+# file before attempting to locate it. If not specified as an absolute pathname,
 # a PATH search shall be performed in accordance with the Environment Variables
 # section of the Base Definitions. If an executable is found, its path shall be
 # printed. Otherwise, the return value shall be 1. This function is intended as


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-25  4:06 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-25  4:06 UTC (permalink / raw
  To: gentoo-commits

commit:     4cdb3c0869a9e6353fee69a7d61123ba8be01c06
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun 24 21:34:37 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Jun 25 01:17:08 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=4cdb3c08

Add the fetch() function

This function makes it trivial to issue a network request - such as HTTP
GET - in a manner that is quiet and which yields a useful exit status
value. It prefers curl if present but supports wget also.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/functions.sh b/functions.sh
index 7e09611..9336174 100644
--- a/functions.sh
+++ b/functions.sh
@@ -47,6 +47,48 @@ chdir()
 	CDPATH= cd -- "$@"
 }
 
+#
+# Considers the first parameter as an URL then attempts to fetch it with either
+# curl(1) or wget(1). If the URL does not contain a scheme then the https://
+# scheme shall be presumed. Both utilities shall be invoked in a manner that
+# suppresses all output unless an error occurs, and whereby HTTP redirections
+# are honoured. Upon success, the body of the response shall be printed to the
+# standard output. Otherwise, the return value shall be greater than 0.
+#
+fetch()
+{
+	if hash curl 2>/dev/null; then
+		fetch()
+		{
+			if [ "$#" -gt 0 ]; then
+				# Discard any extraneous parameters.
+				set -- "$1"
+			fi
+			curl -f -sS -L --connect-timeout 10 --proto-default https -- "$@"
+		}
+	elif hash wget 2>/dev/null; then
+		fetch()
+		{
+			if [ "$#" -gt 0 ]; then
+				# Discard any extraneous parameters.
+				case $1 in
+					''|ftp://*|ftps://*|https://*)
+						set -- "$1"
+						;;
+					*)
+						set -- "https://$1"
+				esac
+			fi
+			wget -nv -O - --connect-timeout 10 -- "$@"
+		}
+	else
+		warn "fetch: this function requires that curl or wget to be installed"
+		return 127
+	fi
+
+	fetch "$@"
+}
+
 #
 # Determines whether the current shell is a subprocess of portage.
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-25  4:06 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-25  4:06 UTC (permalink / raw
  To: gentoo-commits

commit:     58cca9b40298f5b2e0f45963488e1ed50a1d0048
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun 23 22:35:13 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Jun 23 22:35:13 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=58cca9b4

Have is_subset() permit the empty string as a sentinel

I can think of no compelling reason not to.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/functions.sh b/functions.sh
index 55b6c3e..7e09611 100644
--- a/functions.sh
+++ b/functions.sh
@@ -176,15 +176,15 @@ is_anyof()
 #
 # Collects the intersection of the parameters up to - but not including - a
 # sentinel value then determines whether the resulting set is a subset of the
-# intersection of the remaining parameters. If the SENTINEL variable is set and
-# non-empty, it shall be taken as the value of the sentinel. Otherwise, the
-# value of the sentinel shall be defined as <hyphen-dash><hyphen-dash>. If the
-# sentinel value is not encountered or if either set is empty then the return
-# value shall be greater than 1.
+# intersection of the remaining parameters. If the SENTINEL variable is set, it
+# shall be taken as the value of the sentinel. Otherwise, the value of the
+# sentinel shall be defined as <hyphen-dash><hyphen-dash>. If the sentinel value
+# is not encountered or if either set is empty then the return value shall be
+# greater than 1.
 #
 is_subset()
 {
-	SENTINEL=${SENTINEL:-'--'} awk -f - -- "$@" <<-'EOF'
+	SENTINEL=${SENTINEL-'--'} awk -f - -- "$@" <<-'EOF'
 		BEGIN {
 			argc = ARGC
 			ARGC = 1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     449fed1c13525c8420b4366014ba34616cb20239
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Jun 11 05:26:41 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 14 00:27:44 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=449fed1c

Add the is_anyof() and is_subset() functions

Examples follow.

is_anyof  y x y z        # returns 0
is_anoyf  y x w z        # returns 1
is_subset x y   -- x y z # returns 0
is_subset x y z -- z y x # returns 0
is_subset x y   -- x w z # returns 1

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 test-functions | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+)

diff --git a/functions.sh b/functions.sh
index 7d146c8..166f184 100644
--- a/functions.sh
+++ b/functions.sh
@@ -446,6 +446,28 @@ is_int()
 	esac
 }
 
+#
+# Determines whether the first parameter matches any of the parameters that
+# follow it.
+#
+is_anyof()
+{
+	local arg needle
+
+	if [ "$#" -eq 0 ]; then
+		warn "is_anyof: too few arguments (got $#, expected at least 1)"
+	else
+		needle=$1
+		shift
+		for arg; do
+			if [ "${arg}" = "${needle}" ]; then
+				return
+			fi
+		done
+	fi
+	false
+}
+
 #
 # Takes the first parameter as a reference file/directory then determines
 # whether any of the following parameters refer to newer files/directories.
@@ -468,6 +490,46 @@ is_older_than()
 	| read -r _
 }
 
+#
+# Collects the intersection of the parameters up to - but not including - a
+# sentinel value then determines whether the resulting set is a subset of the
+# interection of the remaining parameters. If the SENTINEL variable is set and
+# non-empty, it shall be taken as the value of the sentinel. Otherwise, the
+# value of the sentinel shall be defined as <hyphen-dash><hyphen-dash>. If the
+# sentinel value is not encountered or if either set is empty then the returm
+# value shall be greater than 1.
+#
+is_subset()
+{
+	SENTINEL=${SENTINEL:-'--'} awk -f - -- "$@" <<-'EOF'
+		BEGIN {
+			argc = ARGC
+			ARGC = 1
+			for (i = 1; i < argc; i++) {
+				word = ARGV[i]
+				if (word == ENVIRON["SENTINEL"]) {
+					break
+				} else {
+					set1[word] = ""
+				}
+			}
+			if (i == 1 || argc - i < 2) {
+				exit 1
+			}
+			for (i++; i < argc; i++) {
+				word = ARGV[i]
+				set2[word] = ""
+			}
+			for (word in set2) {
+				delete set1[word]
+			}
+			for (word in set1) {
+				exit 1
+			}
+		}
+	EOF
+}
+
 #
 # Considers one or more pathnames and prints the one having the newest
 # modification time. If at least one parameter is provided, all parameters shall

diff --git a/test-functions b/test-functions
index 1a2eb81..0b987ab 100755
--- a/test-functions
+++ b/test-functions
@@ -575,6 +575,53 @@ test_parallel_run() {
 	iterate_tests 4 "$@"
 }
 
+test_is_anyof() {
+	set -- \
+		ge  1  N/A  N/A  N/A  \
+		ge  1  x    N/A  N/A  \
+		ge  1  x    y    N/A  \
+		ge  1  x    y    z    \
+		eq  0  x    x    N/A  \
+		eq  0  x    x    y    \
+		eq  0  x    y    x
+
+	callback() {
+		shift
+		test_description="is_anyof $(quote_args "$@")"
+		is_anyof "$@"
+	}
+
+	iterate_tests 5 "$@"
+}
+
+test_is_subset() {
+	set -- \
+		ge  1  N/A  N/A  N/A  N/A  N/A  \
+		ge  1  --   N/A  N/A  N/A  N/A  \
+		ge  1  --   --   N/A  N/A  N/A  \
+		ge  1  --   x    N/A  N/A  N/A  \
+		ge  1  x    --   N/A  N/A  N/A  \
+		ge  1  x    y    N/A  N/A  N/A  \
+		ge  1  x    y    x    N/A  N/A  \
+		eq  0  x    --   x    N/A  N/A  \
+		eq  0  x    --   x    y    N/A  \
+		eq  0  x    --   y    x    N/A  \
+		eq  0  x    y    --   x    y    \
+		eq  0  x    y    --   y    x    \
+		ge  1  x    y    --   x    z    \
+		ge  1  y    x    --   z    x    \
+		ge  1  x    z    --   x    y    \
+		ge  1  z    x    --   y    x
+
+	callback() {
+		shift
+		test_description="is_subset $(quote_args "$@")"
+		is_subset "$@"
+	}
+
+	iterate_tests 7 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -641,6 +688,8 @@ test_trim || rc=1
 test_hr || rc=1
 test_whenceforth || rc=1
 test_parallel_run || rc=1
+test_is_anyof || rc=1
+test_is_subset || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     5ca33b525b56f0e255e2e3bb35441b78b23aee4a
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Jun 12 05:41:22 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 14 00:27:44 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=5ca33b52

Add the from_unit() function

The function determines whether the current shell is a subprocess of a
systemd unit that handles a service, socket, mount point or swap device,
per systemd.exec(5).

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/functions.sh b/functions.sh
index 605aa48..7d146c8 100644
--- a/functions.sh
+++ b/functions.sh
@@ -324,6 +324,15 @@ from_runscript()
 	has_openrc && test "${RC_OPENRC_PID}"
 }
 
+#
+# Determines whether the current shell is a subprocess of a systemd unit that
+# handles a service, socket, mount point or swap device, per systemd.exec(5).
+#
+from_unit()
+{
+	has_systemd && test "${SYSTEMD_EXEC_PID}" && test "${INVOCATION_ID}"
+}
+
 #
 # Determines whether the kernel cmdline contains the specified parameter as a
 # component of a comma-separated list specified in the format of gentoo=<list>.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     9bc6cee2b8e1325b096cf91fe7f58918b79ee7ba
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun 10 23:47:14 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 14 00:27:44 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9bc6cee2

Add the from_portage() function

The function determines whether the current shell appears to be a
subprocess of portage.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 39 ++++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/functions.sh b/functions.sh
index 0cd5316..8963b12 100644
--- a/functions.sh
+++ b/functions.sh
@@ -11,21 +11,22 @@
 
 # The following variables affect initialisation and/or function behaviour.
 
-# BASH          : whether bash-specific features may be employed
-# BASH_VERSINFO : whether bash-specific features may be employed
-# BASHPID       : potentially used by _update_columns() to detect subshells
-# COLUMNS       : potentially used by _update_columns() to get the column count
-# EERROR_QUIET  : whether error printing functions should be silenced
-# EINFO_LOG     : whether printing functions should call esyslog()
-# EINFO_QUIET   : whether info message printing functions should be silenced
-# EINFO_VERBOSE : whether v-prefixed functions should do anything
-# EPOCHREALTIME : potentially used by _update_time() to get the time
-# IFS           : multiple message operands are joined by its first character
-# INSIDE_EMACS  : whether to work around an emacs-specific bug in _eend()
-# NO_COLOR      : whether colored output should be suppressed
-# RC_NOCOLOR    : like NO_COLOR but deprecated
-# TEST_GENFUNCS : used for testing the behaviour of get_bootparam()
-# TERM          : may influence message formatting and whether color is used
+# BASH             : whether bash-specific features may be employed
+# BASH_VERSINFO    : whether bash-specific features may be employed
+# BASHPID          : may be used by _update_columns() to detect subshells
+# COLUMNS          : may be used by _update_columns() to get the column count
+# EERROR_QUIET     : whether error printing functions should be silenced
+# EINFO_LOG        : whether printing functions should call esyslog()
+# EINFO_QUIET      : whether info message printing functions should be silenced
+# EINFO_VERBOSE    : whether v-prefixed functions should do anything
+# EPOCHREALTIME    : potentially used by _update_time() to get the time
+# IFS              : multiple message operands are joined by its first character
+# INSIDE_EMACS     : whether to work around an emacs-specific bug in _eend()
+# NO_COLOR         : whether colored output should be suppressed
+# PORTAGE_BIN_PATH : used by from_portage()
+# RC_NOCOLOR       : like NO_COLOR but deprecated
+# TEST_GENFUNCS    : used for testing the behaviour of get_bootparam()
+# TERM             : may influence message formatting and whether color is used
 
 ################################################################################
 
@@ -306,6 +307,14 @@ ewend()
 	GENFUN_CALLER=${GENFUN_CALLER:-ewend} _eend ewarn "$@"
 }
 
+#
+# Determines whether the current shell is a subprocess of portage.
+#
+from_portage()
+{
+	test "${PORTAGE_BIN_PATH}"
+}
+
 #
 # Determines whether the kernel cmdline contains the specified parameter as a
 # component of a comma-separated list specified in the format of gentoo=<list>.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     9c3da406f53faf3098932ce61edede414c6aef2a
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun  9 06:06:43 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9c3da406

Have _eend() assume 80 columns in the absence of a smart terminal

In cases where the value of genfun_tty is lower than 2, it is implied
that the standard output refers either to a terminal insufficiently
capable of handling ECMA-48 CSI sequences or to a resource that is not a
terminal. Use <space> characters to indent the indicator to the extent
that the last character falls on the 80th column. Previously, the
indicator was indented by only one <space>.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/functions.sh b/functions.sh
index 409d424..fcba801 100644
--- a/functions.sh
+++ b/functions.sh
@@ -818,9 +818,12 @@ _eend()
 		col=$(( genfun_cols > 6 ? genfun_cols - 6 : 1 ))
 		printf '\0337\033[1A\033[%dG %s\0338' "$(( col + genfun_offset ))" "${msg}"
 	else
-		# The standard output does not refer to a sufficiently capable
-		# terminal. Print only the indicator.
-		printf ' %s\n' "${msg}"
+		# The standard output refers either to an insufficiently capable
+		# terminal or to something other than a terminal. Print the
+		# indicator, using <space> characters to indent to the extent
+		# that the last character falls on the 80th column. This hinges
+		# on the fair assumption that a newline was already printed.
+		printf '%80s\n' "${msg}"
 	fi
 
 	return "${retval}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     6e2c50a81f3625aa3f415bd6253404a6af617dbf
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun  9 01:08:05 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 14 00:27:44 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6e2c50a8

Rectify a typo for _update_tty_level()

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 52224a5..0cd5316 100644
--- a/functions.sh
+++ b/functions.sh
@@ -1036,7 +1036,7 @@ _update_tty_level()
 }
 
 #
-# Prints a diganostic message concerning invalid function arguments. The first
+# Prints a diagnostic message concerning invalid function arguments. The first
 # argument shall be taken as a function identifier. The remaining arguments
 # shall be safely rendered as a part of the diagnostic.
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     eb788da3f1af8f506226986f12de6b2b04cdaba1
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun  2 03:42:00 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=eb788da3

Add the parallel_run() function

Here is an example of how to use it.

$ parallel_run 0 sha256sum dir/*

Simple commands of a greater level of sophistication can easily be
composed with the aid of functions.

$ sm3sum() { cksum -a sm3 "$@"; }
$ parallel_run 0 sm3sum dir/*

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 44 ++++++++++++++++++++++++++++++++++++++++++++
 test-functions | 21 ++++++++++++++++++++-
 2 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 60a4b2e..e849541 100644
--- a/functions.sh
+++ b/functions.sh
@@ -495,6 +495,50 @@ oldest()
 	_select_by_mtime -- "$@"
 }
 
+#
+# Executes a simple command in parallel. At least two parameters are expected.
+# The first parameter shall be taken as the maximum number of jobs to run
+# concurrently. If specified as less than or equal to 0, the number shall be
+# determined by running the nproc function. The second parameter shall be taken
+# as a command name. The remaining parameters shall be conveyed to the specified
+# command, one at a time. Should at least one command fail, the return value
+# shall be greater than 0.
+#
+parallel_run()
+{
+	local arg cmd i statedir w workers
+
+	if [ "$#" -lt 3 ]; then
+		warn "parallel_run: too few arguments (got $#, expected at least 3)"
+		return 1
+	elif ! is_int "$1"; then
+		_warn_for_args parallel_run "$1"
+		return 1
+	elif [ "$1" -le 0 ] && ! workers=$(get_nprocs); then
+		return 1
+	elif ! statedir=${TMPDIR:-/tmp}/parallel_run.$$.$(srandom); then
+		return 1
+	fi
+	workers=${workers:-$1} cmd=$2
+	shift 2
+	w=0
+	i=0
+	(
+		while [ "$(( w += 1 ))" -le "${workers}" ]; do
+			i=$w
+			while [ "$i" -le "$#" ]; do
+				eval "arg=\$${i}"
+				if ! "${cmd}" "${arg}"; then
+					mkdir -p -- "${statedir}"
+				fi
+				i=$(( i + workers ))
+			done &
+		done
+		wait
+	)
+	! rmdir -- "${statedir}" 2>/dev/null
+}
+
 #
 # Declare the vebegin, veerror, veindent, veinfo, veinfon, veoutdent and vewarn
 # functions. These differ from their non-v-prefixed counterparts in that they

diff --git a/test-functions b/test-functions
index c734141..ed3da42 100755
--- a/test-functions
+++ b/test-functions
@@ -556,6 +556,25 @@ test_get_nprocs() {
 	iterate_tests 2 "$@"
 }
 
+test_parallel_run() {
+	set -- \
+		ge  1  N/A                     N/A                     \
+		eq  0  /                       N/A                     \
+		ge  1  /var/empty/nonexistent  N/A                     \
+		eq  0  /                       /                       \
+		ge  1  /                       /var/empty/nonexistent  \
+		ge  1  /var/empty/nonexistent  /var/empty/nonexistent  \
+		ge  1  /var/empty/nonexistent  /
+
+	callback() {
+		shift
+		test_description="parallel_run $(_print_args 0 ls "$@")"
+		parallel_run 0 ls "$@" >/dev/null 2>&1
+	}
+
+	iterate_tests 4 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -621,7 +640,7 @@ test_newest || rc=1
 test_trim || rc=1
 test_hr || rc=1
 test_whenceforth || rc=1
-test_get_nprocs || rc=1
+test_parallel_run || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     f0ceaf3607b88982bad6bc9954d9e14f7b8f512c
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Jun  4 03:24:27 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f0ceaf36

Reposition the declaration of quote_args()

So as to maintain an alphabetical order.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 106 +++++++++++++++++++++++++++++------------------------------
 1 file changed, 53 insertions(+), 53 deletions(-)

diff --git a/functions.sh b/functions.sh
index a9af6b6..f440dab 100644
--- a/functions.sh
+++ b/functions.sh
@@ -539,6 +539,59 @@ parallel_run()
 	! rmdir -- "${statedir}" 2>/dev/null
 }
 
+#
+# Prints the positional parameters in a manner that approximates the behaviour
+# of the ${*@Q} expansion in bash. The output shall be POSIX sh compatible as of
+# Issue 8. This should probably be made to exist as a standalone awk script.
+#
+quote_args()
+{
+	awk -v q=\' -f - -- "$@" <<-'EOF'
+		BEGIN {
+			argc = ARGC
+			ARGC = 1
+			for (arg_idx = 1; arg_idx < argc; arg_idx++) {
+				arg = ARGV[arg_idx]
+				if (arg !~ /[\001-\037\177]/) {
+					gsub(q, q "\\" q q, arg)
+					word = q arg q
+				} else {
+					# Use $'' quoting per Issue 8
+					if (ord_by["\001"] == "") {
+						for (i = 1; i < 32; i++) {
+							char = sprintf("%c", i)
+							ord_by[char] = i
+						}
+						ord_by["\177"] = 127
+					}
+					word = "$'"
+					for (i = 1; i <= length(arg); i++) {
+						char = substr(arg, i, 1)
+						if (char == "\\") {
+							word = word "\\\\"
+						} else if (char == q) {
+							word = word "\\'"
+						} else {
+							ord = ord_by[char]
+							if (ord != "") {
+								word = word "\\" sprintf("%03o", ord)
+							} else {
+								word = word char
+							}
+						}
+					}
+					word = word q
+				}
+				line = line word
+				if (arg_idx < argc - 1) {
+					line = line " "
+				}
+			}
+			print line
+		}
+	EOF
+}
+
 #
 # Declare the vebegin, veerror, veindent, veinfo, veinfon, veoutdent and vewarn
 # functions. These differ from their non-v-prefixed counterparts in that they
@@ -839,59 +892,6 @@ _is_visible()
 	! case $1 in *[[:graph:]]*) false ;; esac
 }
 
-#
-# Prints the positional parameters in a manner that approximates the behaviour
-# of the ${*@Q} expansion in bash. The output shall be POSIX sh compatible as of
-# Issue 8. This should probably be made to exist as a standalone awk script.
-#
-quote_args()
-{
-	awk -v q=\' -f - -- "$@" <<-'EOF'
-		BEGIN {
-			argc = ARGC
-			ARGC = 1
-			for (arg_idx = 1; arg_idx < argc; arg_idx++) {
-				arg = ARGV[arg_idx]
-				if (arg !~ /[\001-\037\177]/) {
-					gsub(q, q "\\" q q, arg)
-					word = q arg q
-				} else {
-					# Use $'' quoting per Issue 8
-					if (ord_by["\001"] == "") {
-						for (i = 1; i < 32; i++) {
-							char = sprintf("%c", i)
-							ord_by[char] = i
-						}
-						ord_by["\177"] = 127
-					}
-					word = "$'"
-					for (i = 1; i <= length(arg); i++) {
-						char = substr(arg, i, 1)
-						if (char == "\\") {
-							word = word "\\\\"
-						} else if (char == q) {
-							word = word "\\'"
-						} else {
-							ord = ord_by[char]
-							if (ord != "") {
-								word = word "\\" sprintf("%03o", ord)
-							} else {
-								word = word char
-							}
-						}
-					}
-					word = word q
-				}
-				line = line word
-				if (arg_idx < argc - 1) {
-					line = line " "
-				}
-			}
-			print line
-		}
-	EOF
-}
-
 #
 # See the definitions of oldest() and newest().
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     01660459fdbbf8585bd0958211a467a620c7e2c0
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun  3 23:39:42 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=01660459

Don't use ewarn to display a diagnostic in eqatag()

I'd rather leave the use of ewarn() to the consumers of
gentoo-functions.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 79cd06a..6b4c3fa 100644
--- a/functions.sh
+++ b/functions.sh
@@ -200,7 +200,7 @@ eqatag()
 			if command -v jq >/dev/null; then
 				genfun_has_jq=1
 			else
-				ewarn "The eqatag() function requires that jq be installed"
+				warn "eqatag: this function requires that jq be installed"
 				genfun_has_jq=0
 				return 1
 			fi


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     f30da506a0827a3e698697692abe168174e0ad6d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun  3 23:30:38 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f30da506

Add the GENFUN_API_LEVEL variable declaration

This allows for simple API capability checks to be performed by users of
the library. It might also obsolete the RC_GOT_FUNCTIONS variable.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/functions.sh b/functions.sh
index e849541..a0315f9 100644
--- a/functions.sh
+++ b/functions.sh
@@ -970,6 +970,11 @@ _warn_for_args()
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS=yes
 
+# This shall be incremented by one upon any change being made to the public API.
+# It was introduced by gentoo-functions-1.7 with an initial value of 1.
+# shellcheck disable=2034
+GENFUN_API_LEVEL=1
+
 # Assign the LF ('\n') character for later expansion. POSIX Issue 8 permits
 # $'\n' but it may take years for it to be commonly implemented.
 genfun_newline='


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     a46a94768d76cd1f52cc7d6743575887fa416407
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun  6 00:23:54 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=a46a9476

Have quote_args() respect POSIXLY_CORRECT for Issue 7 conformance

Also, markedly improve the comment that documents the function.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/functions.sh b/functions.sh
index f440dab..79cd06a 100644
--- a/functions.sh
+++ b/functions.sh
@@ -540,19 +540,29 @@ parallel_run()
 }
 
 #
-# Prints the positional parameters in a manner that approximates the behaviour
-# of the ${*@Q} expansion in bash. The output shall be POSIX sh compatible as of
-# Issue 8. This should probably be made to exist as a standalone awk script.
+# Prints the positional parameters in a format that may be reused as shell
+# input. For each considered, it shall be determined whether its value contains
+# any non-printable characters in lieu of the US-ASCII character set. If no such
+# characters are found, the value shall have each instance of <apostrophe> be
+# replaced by <apostrophe><backslash><apostrophe><apostrophe> before being
+# enclosed by a pair of <apostrophe> characters. Otherwise, non-printable
+# characters shall be replaced by octal escape sequences, <apostrophe> by
+# <backslash><apostrophe> and <backslash> by <backslash><backslash>, prior to
+# the value being given a prefix of <dollar-sign><apostrophe> and a suffix of
+# <apostrophe>, per Issue 8. Finally, the resulting values shall be printed as
+# <space> separated. The latter quoting strategy can be suppressed by setting
+# the POSIXLY_CORRECT variable as non-empty in the environment.
 #
 quote_args()
 {
 	awk -v q=\' -f - -- "$@" <<-'EOF'
 		BEGIN {
+			strictly_posix = length(ENVIRON["POSIXLY_CORRECT"])
 			argc = ARGC
 			ARGC = 1
 			for (arg_idx = 1; arg_idx < argc; arg_idx++) {
 				arg = ARGV[arg_idx]
-				if (arg !~ /[\001-\037\177]/) {
+				if (strictly_posix || arg !~ /[\001-\037\177]/) {
 					gsub(q, q "\\" q q, arg)
 					word = q arg q
 				} else {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     72b754bb11066b10ae14b8f017f93ad5c62e7467
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Jun  8 15:44:32 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 14 00:27:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=72b754bb

Throttle the rate at which genfun_cols may be refreshed

Limit the rate at which genfun_cols can be refreshed to intervals that
are no shorter than 5 decisconds (half a second). Doing so renders
repeated calls to the _eend() function at short intervals faster by an
order of magnitude.

On one of my fastest available machines, I performed the following
benchmark with bash 5.2.26.

$ time for ((i=0; i<50000; i++)); do ebegin "$i"; eend; done

The results were as follows.

BEFORE

real    0m56.897s
user    0m16.990s
sys     0m28.540s

AFTER

real    0m6.663s
user    0m6.435s
sys     0m0.191s

On one of my slowest available machines, I performed the following
benchmark with bash 5.2.26.

$ time for ((i=0; i<15000; i++)); do ebegin "$i"; eend; done

The results were as follows.

BEFORE

real    0m52.557s
user    0m34.484s
sys     0m18.231s

AFTER

real    0m11.422s
user    0m10.654s
sys     0m0.535s

On that same (slow) machine, I performed the following benchmark with
dash 0.5.12.

$ time dash -c '
    . ./functions.sh
    while :; do ebegin $((i+=1)); eend; [ $i -eq 15000 ] && exit; done'

The results were as follows.

BEFORE

real    0m43.762s
user    0m22.202s
sys     0m21.415s

AFTER

real    0m3.470s
user    0m2.535s
sys     0m0.736s

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 78 insertions(+), 3 deletions(-)

diff --git a/functions.sh b/functions.sh
index fcba801..52224a5 100644
--- a/functions.sh
+++ b/functions.sh
@@ -19,6 +19,7 @@
 # EINFO_LOG     : whether printing functions should call esyslog()
 # EINFO_QUIET   : whether info message printing functions should be silenced
 # EINFO_VERBOSE : whether v-prefixed functions should do anything
+# EPOCHREALTIME : potentially used by _update_time() to get the time
 # IFS           : multiple message operands are joined by its first character
 # INSIDE_EMACS  : whether to work around an emacs-specific bug in _eend()
 # NO_COLOR      : whether colored output should be suppressed
@@ -919,16 +920,37 @@ _select_by_mtime() {
 	| { IFS= read -r line && printf '%s\n' "${line#* }"; }
 }
 
+#
+# Considers the first parameter as a number of deciseconds and determines
+# whether fewer have elapsed since the last occasion on which the function was
+# called.
+#
+_should_throttle()
+{
+	_update_time || return
+	if [ "$(( genfun_time - genfun_last_time > $1 ))" -eq 1 ]; then
+		genfun_last_time=${genfun_time}
+		false
+	fi
+}
+
 #
 # Determines whether the terminal on STDIN is able to report its dimensions.
 # Upon success, the number of columns shall be stored in genfun_cols.
 #
 _update_columns()
 {
-	# Command substitutions are rather slow in bash. Using the COLUMNS
-	# variable helps but checkwinsize won't work properly in subshells.
+	# Two optimisations are applied. Firstly, the rate at which updates can
+	# be performed is throttled to intervals of 5 deciseconds. Secondly, if
+	# running on bash then the COLUMNS variable may be gauged, albeit only
+	# in situations where doing so can be expected to work reliably; not if
+	# in a subshell. Note that executing true(1) is faster than executing
+	# stty(1) within a comsub.
 	# shellcheck disable=3028,3044
-	if [ "$$" = "${BASHPID}" ] && shopt -q checkwinsize; then
+	if _should_throttle 5; then
+		test "${genfun_cols}"
+		return
+	elif [ "$$" = "${BASHPID}" ] && shopt -q checkwinsize; then
 		"${genfun_bin_true}"
 		set -- 0 "${COLUMNS}"
 	else
@@ -942,6 +964,59 @@ _update_columns()
 	[ "$#" -eq 2 ] && is_int "$2" && [ "$2" -gt 0 ] && genfun_cols=$2
 }
 
+#
+# Determines either the number of deciseconds elapsed since the unix epoch or
+# the number of deciseconds that the operating system has been online, depending
+# on the capabilities of the shell and/or platform. Upon success, the obtained
+# value shall be assigned to genfun_time. Otherwise, the return value shall be
+# greater than 0.
+#
+_update_time()
+{
+	genfun_last_time=0
+
+	# shellcheck disable=3028
+	if [ "${BASH_VERSINFO:-0}" -ge 5 ]; then
+		# shellcheck disable=2034,3045
+		_update_time()
+		{
+			local ds s timeval
+
+			timeval=${EPOCHREALTIME}
+			s=${timeval%.*}
+			printf -v ds '%.1f' ".${timeval#*.}"
+			if [ "${ds}" = "1.0" ]; then
+				ds=10
+			else
+				ds=${ds#0.}
+			fi
+			genfun_time=$(( s * 10 + ds ))
+		}
+	elif [ -f /proc/uptime ]; then
+		_update_time()
+		{
+			local ds s timeval
+
+			IFS=' ' read -r timeval _ < /proc/uptime || return
+			s=${timeval%.*}
+			printf -v ds '%.1f' ".${timeval#*.}"
+			if [ "${ds}" = "1.0" ]; then
+				ds=10
+			else
+				ds=${ds#0.}
+			fi
+			genfun_time=$(( s * 10 + ds ))
+		}
+	else
+		_update_time()
+		{
+			false
+		}
+	fi
+
+	_update_time
+}
+
 #
 # Grades the capability of the terminal attached to STDIN, assigning the level
 # to genfun_tty. If no terminal is detected, the level shall be 0. If a dumb


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     5e599c75905b04918ce7d7fdaa9dfd845c322d8e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Jun  4 03:23:10 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=5e599c75

Promote _print_args() to the public function, quote_args()

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   |  6 +++---
 test-functions | 28 ++++++++++++++--------------
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/functions.sh b/functions.sh
index a0315f9..a9af6b6 100644
--- a/functions.sh
+++ b/functions.sh
@@ -95,7 +95,7 @@ ebegin()
 #
 edo()
 {
-	genfun_cmd=$(_print_args "$@")
+	genfun_cmd=$(quote_args "$@")
 	einfo "Executing: ${genfun_cmd}"
 	"$@" || die "Failed to execute command: ${genfun_cmd}"
 }
@@ -844,7 +844,7 @@ _is_visible()
 # of the ${*@Q} expansion in bash. The output shall be POSIX sh compatible as of
 # Issue 8. This should probably be made to exist as a standalone awk script.
 #
-_print_args()
+quote_args()
 {
 	awk -v q=\' -f - -- "$@" <<-'EOF'
 		BEGIN {
@@ -963,7 +963,7 @@ _warn_for_args()
 	ident=$1
 	shift
 	[ "$#" -gt 1 ] && plural=s || plural=
-	warn "${ident}: invalid argument${plural}: $(_print_args "$@")"
+	warn "${ident}: invalid argument${plural}: $(quote_args "$@")"
 }
 
 # All function declarations end here! Initialisation code only from hereon.

diff --git a/test-functions b/test-functions
index ed3da42..1a2eb81 100755
--- a/test-functions
+++ b/test-functions
@@ -41,7 +41,7 @@ test_chdir() {
 
 	callback() {
 		shift
-		test_description="chdir $(_print_args "$@")"
+		test_description="chdir $(quote_args "$@")"
 		if [ "$BASH" ]; then
 			# shellcheck disable=3044
 			shopt -s cdable_vars
@@ -60,7 +60,7 @@ test_chdir_noop() {
 
 	callback() {
 		shift
-		test_description="chdir $(_print_args "$@")"
+		test_description="chdir $(quote_args "$@")"
 		chdir "$@" \
 		&& test "$PWD" = "$OLDPWD" \
 		|| { cd - >/dev/null; false; }
@@ -194,7 +194,7 @@ test_is_older_than() {
 
 	callback() {
 		shift
-		test_description="is_older_than $(_print_args "$@")"
+		test_description="is_older_than $(quote_args "$@")"
 		is_older_than "$@"
 	}
 
@@ -220,7 +220,7 @@ test_get_bootparam() {
 	callback() {
 		cmdline=$2
 		shift 2
-		test_description="get_bootparam $(_print_args "$@")"
+		test_description="get_bootparam $(quote_args "$@")"
 		printf '%s\n' "${cmdline}" | get_bootparam "$@"
 	}
 
@@ -244,7 +244,7 @@ test_esyslog() {
 	callback() {
 		should_log=$2
 		shift 2
-		test_description="esyslog $(_print_args "$@")"
+		test_description="esyslog $(quote_args "$@")"
 		logged=$(EINFO_LOG=1 esyslog "$@")
 		case $? in
 			0)
@@ -306,7 +306,7 @@ test_is_identifier() {
 
 	callback() {
 		shift
-		test_description="is_identifier $(_print_args "$@")"
+		test_description="is_identifier $(quote_args "$@")"
 		is_identifier "$@"
 	}
 
@@ -331,7 +331,7 @@ test_is_int() {
 
 	callback() {
 		shift
-		test_description="is_int $(_print_args "$@")"
+		test_description="is_int $(quote_args "$@")"
 		is_int "$@"
 	}
 
@@ -351,7 +351,7 @@ test_is_visible() {
 
 	callback() {
 		shift
-		test_description="_is_visible $(_print_args "$@")"
+		test_description="_is_visible $(quote_args "$@")"
 		_is_visible "$@"
 	}
 
@@ -390,7 +390,7 @@ test_yesno() {
 
 	callback() {
 		shift
-		test_description="yesno $(_print_args "$@")"
+		test_description="yesno $(quote_args "$@")"
 		yesno "$@"
 	}
 
@@ -441,7 +441,7 @@ test_newest() {
 
 	callback() {
 		shift
-		test_description="newest $(_print_args "$@")"
+		test_description="newest $(quote_args "$@")"
 		row=$(( row + 1 ))
 		true |
 		if [ "${row}" -le 2 ]; then
@@ -477,7 +477,7 @@ test_trim() {
 
 	callback() {
 		shift
-		test_description="trim $(_print_args "$1") (expecting $(_print_args "$2"))"
+		test_description="trim $(quote_args "$1") (expecting $(quote_args "$2"))"
 		test "$(trim "$1")" = "$2"
 	}
 
@@ -500,7 +500,7 @@ test_hr() {
 		shift
 		expected=$1
 		shift
-		test_description="hr $(_print_args "$@")"
+		test_description="hr $(quote_args "$@")"
 		test "$(hr "$@")" = "${expected}"
 	}
 
@@ -533,7 +533,7 @@ test_whenceforth() {
 		shift
 		path=$1
 		shift
-		test_description="whenceforth $(_print_args "$@")"
+		test_description="whenceforth $(quote_args "$@")"
 		if [ "${path}" = PATH ]; then
 			whenceforth "$@" >/dev/null
 		else
@@ -568,7 +568,7 @@ test_parallel_run() {
 
 	callback() {
 		shift
-		test_description="parallel_run $(_print_args 0 ls "$@")"
+		test_description="parallel_run $(quote_args 0 ls "$@")"
 		parallel_run 0 ls "$@" >/dev/null 2>&1
 	}
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     f8b3029be34143dbd19737aa9bad2948bf0b88c7
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Jun  4 02:35:09 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f8b3029b

Clean up the jq detection procedure in eqatag()

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/functions.sh b/functions.sh
index 6b4c3fa..f5a59fc 100644
--- a/functions.sh
+++ b/functions.sh
@@ -194,14 +194,9 @@ eqatag()
 		0)
 			return 1
 			;;
-		1)
-			;;
-		*)
-			if command -v jq >/dev/null; then
-				genfun_has_jq=1
-			else
+		'')
+			if ! hash jq 2>/dev/null; [ "$(( genfun_has_jq = $? ))" -eq 0 ]; then
 				warn "eqatag: this function requires that jq be installed"
-				genfun_has_jq=0
 				return 1
 			fi
 	esac


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     b56690548449e96d7af3c794434ba89ae0c7fc88
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Jun 11 05:48:11 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun 14 00:27:44 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b5669054

Add the from_runscript() function

The function determines whether the current shell is executing an OpenRC
runscript, or is a subprocess of one.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/functions.sh b/functions.sh
index 8963b12..605aa48 100644
--- a/functions.sh
+++ b/functions.sh
@@ -315,6 +315,15 @@ from_portage()
 	test "${PORTAGE_BIN_PATH}"
 }
 
+#
+# Determines whether the current shell is executing an OpenRC runscript, or is
+# a subprocess of one.
+#
+from_runscript()
+{
+	has_openrc && test "${RC_OPENRC_PID}"
+}
+
 #
 # Determines whether the kernel cmdline contains the specified parameter as a
 # component of a comma-separated list specified in the format of gentoo=<list>.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     15a828808106b943eea2e3b1c89705c51d91d4af
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Jun  4 01:34:28 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=15a82880

Never print CHA sequences containing negative numbers in _eend()

In cases where the value of genfun_tty is 2, render it impossible for
_eend() ever to produce a CHA sequence that incorporates a negative
column number. Some terminal emulators handle it sensibly whereas others
do not.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index f5a59fc..409d424 100644
--- a/functions.sh
+++ b/functions.sh
@@ -773,7 +773,7 @@ yesno()
 #
 _eend()
 {
-	local efunc msg retval
+	local col efunc msg retval
 
 	efunc=$1
 	shift
@@ -815,7 +815,8 @@ _eend()
 		# Save the cursor position with DECSC, move it up by one line
 		# with CUU, position it horizontally with CHA, print the
 		# indicator, then restore the cursor position with DECRC.
-		printf '\0337\033[1A\033[%dG %s\0338' "$(( genfun_cols - 6 + genfun_offset ))" "${msg}"
+		col=$(( genfun_cols > 6 ? genfun_cols - 6 : 1 ))
+		printf '\0337\033[1A\033[%dG %s\0338' "$(( col + genfun_offset ))" "${msg}"
 	else
 		# The standard output does not refer to a sufficiently capable
 		# terminal. Print only the indicator.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     5ee035a364bea8d12bc8abfe769014e230a212a6
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun  2 17:46:43 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:41 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=5ee035a3

Add the srandom() function

This is based on the behaviour of the special SRANDOM variable in bash.
It should be noted that sh is capable of bitwise arithmetic. For
instance, it is possible to clamp the number in such a way that it does
not exceed the minimum possible value of RAND_MAX (32767).

n=$(srandom) && : $(( n >>= 17 ))

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 27 +++++++++++++++++++++++++++
 test-functions | 22 ++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/functions.sh b/functions.sh
index a97dde7..0c35b2d 100644
--- a/functions.sh
+++ b/functions.sh
@@ -12,6 +12,7 @@
 # The following variables affect initialisation and/or function behaviour.
 
 # BASH          : whether bash-specific features may be employed
+# BASH_VERSINFO : whether bash-specific features may be employed
 # BASHPID       : potentially used by _update_columns() to detect subshells
 # COLUMNS       : potentially used by _update_columns() to get the column count
 # EERROR_QUIET  : whether error printing functions should be silenced
@@ -473,6 +474,32 @@ vewend()
 	fi
 }
 
+#
+# Generates a random uint32 with the assistance of the kernel CSPRNG.
+#
+srandom()
+{
+	# shellcheck disable=3028
+	if [ "${BASH_VERSINFO:-0}" -ge 5 ]; then
+		srandom()
+		{
+			printf '%d\n' "${SRANDOM}"
+		}
+	elif [ -c /dev/urandom ]; then
+		srandom()
+		{
+			printf '%d\n' "0x$(
+				LC_ALL=C od -vAn -N4 -tx1 /dev/urandom | tr -d '[:space:]'
+			)"
+		}
+	else
+		warn "srandom: /dev/urandom doesn't exist as a character device"
+		return 1
+	fi
+
+	srandom
+}
+
 #
 # Prints a diagnostic message prefixed with the basename of the running script.
 #

diff --git a/test-functions b/test-functions
index 8ff6380..0c4a222 100755
--- a/test-functions
+++ b/test-functions
@@ -397,6 +397,27 @@ test_yesno() {
 	iterate_tests 3 "$@"
 }
 
+test_srandom() {
+	set -- \
+		eq 0 \
+		eq 0 \
+		eq 0 \
+		eq 0 \
+		eq 0
+
+	row=0
+
+	callback() {
+		number=$(srandom)
+		test_description="srandom ($(( row += 1 ))/5: ${number:-blank})"
+		is_int "${number}" \
+		&& test "${number}" -ge 0 \
+		&& test "${number}" -le 4294967295
+	}
+
+	iterate_tests 2 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -457,6 +478,7 @@ test_is_visible || rc=1
 test_yesno || rc=1
 test_die || rc=1
 test_edo || rc=1
+test_srandom || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     d6b03b9ae75d0e76a2620e227cf24d9bcdb5e321
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun  3 10:58:44 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d6b03b9a

Add the whenceforth() function as a type -P alternative

It acts much as type -P does in bash. I would have liked to name it
whence but ksh and zsh already have builtins by that name.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
 test-functions | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index c077290..504ee9e 100644
--- a/functions.sh
+++ b/functions.sh
@@ -565,6 +565,51 @@ warn()
 	printf '%s: %s\n' "${0##*/}" "$*" >&2
 }
 
+#
+# Considers the first parameter as the potential name of an executable regular
+# file before attempting to locate it. If not specifed as an absolute pathname,
+# a PATH search shall be performed in accordance with the Environment Variables
+# section of the Base Definitions. If an executable is found, its path shall be
+# printed. Otherwise, the return value shall be 1. This function is intended as
+# an alternative to type -P in bash. That is, it is useful for determining the
+# existence and location of an external utility without potentially matching
+# against aliases, builtins and functions (as command -v can).
+#
+whenceforth()
+(
+	local bin path prefix
+
+	case $1 in
+		/*)
+			# Absolute command paths must be directly checked.
+			[ -f "$1" ] && [ -x "$1" ] && bin=$1
+			;;
+		*)
+			# Relative command paths must be searched for in PATH.
+			# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03
+			case ${PATH} in
+				''|*:)
+					path=${PATH}:
+					;;
+				*)
+					path=${PATH}
+			esac
+			IFS=:
+			set -f
+			for prefix in ${path}; do
+				case ${prefix} in
+					*/)
+						bin=${prefix}$1
+						;;
+					*)
+						bin=${prefix:-.}/$1
+				esac
+				[ -f "${bin}" ] && [ -x "${bin}" ] && break
+			done
+	esac \
+	&& printf '%s\n' "${bin}"
+)
+
 #
 # Determines whether the first parameter is truthy. The values taken to be true
 # are "yes", "true", "on" and "1", whereas their opposites are taken to be
@@ -876,8 +921,7 @@ fi
 
 # Store the path to the true binary. It is potentially used by _update_columns.
 if [ "${BASH}" ]; then
-	# shellcheck disable=3045
-	genfun_bin_true=$(type -P true)
+	genfun_bin_true=$(whenceforth true)
 fi
 
 # Store the name of the GNU find binary. Some platforms may have it as "gfind".

diff --git a/test-functions b/test-functions
index d90462e..813d524 100755
--- a/test-functions
+++ b/test-functions
@@ -507,6 +507,44 @@ test_hr() {
 	iterate_tests 5 "$@"
 }
 
+test_whenceforth() {
+	set -- \
+		ge  1  PATH                        N/A                       \
+		ge  1  PATH                        .                         \
+		ge  1  PATH                        rather-unlikely-to-exist  \
+		ge  1  PATH                        /var/empty                \
+		ge  1  PATH                        /var/empty/nofile         \
+		eq  0  PATH                        /bin/sh                   \
+		eq  0  PATH                        sh                        \
+		eq  0  ''                          newer/file                \
+		eq  0  .                           newer/file                \
+		eq  0  :/var/empty/x               newer/file                \
+		eq  0  /var/empty/x:               newer/file                \
+		eq  0  /var/empty/x::/var/empty/y  newer/file                \
+		ge  1  ''                          older/file                \
+		ge  1  .                           older/file                \
+		ge  1  :/var/empty/x               older/file                \
+		ge  1  /var/empty/x:               older/file                \
+		ge  1  /var/empty/x::/var/empty/y  older/file
+
+	chmod +x newer/file
+
+	callback() {
+		shift
+		path=$1
+		shift
+		test_description="whenceforth $(_print_args "$@")"
+		if [ "${path}" = PATH ]; then
+			whenceforth "$@" >/dev/null
+		else
+			PATH=${path} whenceforth "$@" >/dev/null
+		fi
+	}
+
+	iterate_tests 4 "$@"
+}
+
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -571,6 +609,7 @@ test_srandom || rc=1
 test_newest || rc=1
 test_trim || rc=1
 test_hr || rc=1
+test_whenceforth || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     302084ee5cb39610378d1f963bb16adc7a78abbc
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun  3 01:21:52 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=302084ee

Add the trim() function

As based on the implementation in Maarten Billemont's bashlib library.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 16 ++++++++++++++++
 test-functions | 29 +++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/functions.sh b/functions.sh
index 1548bd0..30c2447 100644
--- a/functions.sh
+++ b/functions.sh
@@ -513,6 +513,22 @@ srandom()
 	srandom
 }
 
+#
+# Trims leading and trailing whitespace from one or more lines. If at least one
+# parameter is provided, each positional parameter shall be considered as a line
+# to be processed. Otherwise, the lines to be processed shall be read from the
+# standard input. The trimmed lines shall be printed to the standard output.
+#
+trim()
+{
+	if [ "$#" -gt 0 ]; then
+		printf '%s\n' "$@"
+	else
+		cat
+	fi |
+	sed -e 's/^[[:space:]]\{1,\}//' -e 's/[[:space:]]\{1,\}$//'
+}
+
 #
 # Prints a diagnostic message prefixed with the basename of the running script.
 #

diff --git a/test-functions b/test-functions
index 400ddb2..bbb74f1 100755
--- a/test-functions
+++ b/test-functions
@@ -456,6 +456,34 @@ test_newest() {
 	iterate_tests 4 "$@"
 }
 
+test_trim() {
+	set -- \
+		eq  0  ''                       ''     \
+		eq  0  ' '                      ''     \
+		eq  0  '  '                     ''     \
+		eq  0  ' X'                     'X'    \
+		eq  0  '  X'                    'X'    \
+		eq  0  'X  '                    'X'    \
+		eq  0  ' X Y'                   'X Y'  \
+		eq  0  '  X Y'                  'X Y'  \
+		eq  0  'X Y '                   'X Y'  \
+		eq  0  'X Y  '                  'X Y'  \
+		eq  0  "$(printf ' \tX')"       'X'    \
+		eq  0  "$(printf ' \tX\t ')"    'X'    \
+		eq  0  "$(printf    'X\t ')"    'X'    \
+		eq  0  "$(printf ' \tX Y')"     'X Y'  \
+		eq  0  "$(printf ' \tX Y\t ')"  'X Y'  \
+		eq  0  "$(printf    'X Y\t ')"  'X Y'
+
+	callback() {
+		shift
+		test_description="trim $(_print_args "$1") (expecting $(_print_args "$2"))"
+		test "$(trim "$1")" = "$2"
+	}
+
+	iterate_tests 4 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -518,6 +546,7 @@ test_die || rc=1
 test_edo || rc=1
 test_srandom || rc=1
 test_newest || rc=1
+test_trim || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     1124356ee9f4d6065953d8aecf6e06c617e930c1
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun  3 01:39:20 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1124356e

Add the hr() function to print a horizontal rule

As based on the implementation in Maarten Billemont's bashlib library.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 28 ++++++++++++++++++++++++++++
 test-functions | 24 ++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/functions.sh b/functions.sh
index 30c2447..c077290 100644
--- a/functions.sh
+++ b/functions.sh
@@ -363,6 +363,34 @@ has_systemd()
 	test -d /run/systemd
 }
 
+#
+# Prints a horizontal rule. If specified, the first parameter shall be taken as
+# a string to be repeated in the course of composing the rule. Otherwise, it
+# shall default to the <hyphen-minus>. If specified, the second parameter shall
+# define the length of the rule in characters. Otherwise, it shall default to
+# the width of the terminal if such can be determined, or 80 if it cannot be.
+#
+hr()
+{
+	local length
+
+	if is_int "$2"; then
+		length=$2
+	elif _update_tty_level <&1; [ "${genfun_tty}" -eq 2 ]; then
+		length=${genfun_cols}
+	else
+		length=80
+	fi
+	PATTERN=${1:--} awk -v "width=${length}" -f - <<-'EOF'
+		BEGIN {
+			while (length(rule) < width) {
+				rule = rule substr(ENVIRON["PATTERN"], 1, width - length(rule))
+			}
+			print rule
+		}
+	EOF
+}
+
 #
 # Determines whether the first parameter is a valid identifier (variable name).
 #

diff --git a/test-functions b/test-functions
index bbb74f1..d90462e 100755
--- a/test-functions
+++ b/test-functions
@@ -484,6 +484,29 @@ test_trim() {
 	iterate_tests 4 "$@"
 }
 
+test_hr() {
+	# shellcheck disable=2183
+	set -- \
+		eq  0  "$(printf '%80s' | tr ' ' -)"  N/A  N/A  \
+		eq  0  "$(printf '%80s' | tr ' ' -)"  -    N/A  \
+		eq  0  ''                             -    0    \
+		eq  0  -                              -    1    \
+		eq  0  -----                          -    5    \
+		eq  0  ''                             xyz  0    \
+		eq  0  x                              xyz  1    \
+		eq  0  xyzxy                          xyz  5
+
+	callback() {
+		shift
+		expected=$1
+		shift
+		test_description="hr $(_print_args "$@")"
+		test "$(hr "$@")" = "${expected}"
+	}
+
+	iterate_tests 5 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -547,6 +570,7 @@ test_edo || rc=1
 test_srandom || rc=1
 test_newest || rc=1
 test_trim || rc=1
+test_hr || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     a3a1544a8631af9e79bddb408c29f2c4f5b1af55
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Jun  1 00:14:59 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Jun 11 06:11:59 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=a3a1544a

Add the has_openrc() and has_systemd() functions

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/functions.sh b/functions.sh
index ec1f339..9736747 100644
--- a/functions.sh
+++ b/functions.sh
@@ -344,6 +344,24 @@ get_bootparam()
 	return 1
 )
 
+#
+# Determines whether OpenRC appears to be operational as a service manager in
+# the context of the present root filesystem namespace.
+#
+has_openrc()
+{
+	test -d /run/openrc
+}
+
+#
+# Determines whether systemd appears to be operational as a service manager in
+# the context of the present root filesystem namespace.
+#
+has_systemd()
+{
+	test -d /run/systemd
+}
+
 #
 # Determines whether the first parameter is a valid identifier (variable name).
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     0cdb10747efaafcb7aa9a217289a5e4f61ee91cd
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun  2 21:27:27 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Jun 11 06:11:59 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=0cdb1074

test-functions: Remove an unused variable

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 1 -
 1 file changed, 1 deletion(-)

diff --git a/test-functions b/test-functions
index 4a6e7dd..e0bd127 100755
--- a/test-functions
+++ b/test-functions
@@ -97,7 +97,6 @@ test_ebegin() {
 		_ends_with_newline "$*"
 	}
 
-	ok=0
 	set -- "message"
 	ebegin "$1"
 	retval=$?


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     fa942450e3b289057881a60fd98a9d4b35d99604
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Jun  7 13:00:01 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=fa942450

Add the get_nprocs() function

It stands a good chance of printing a useful value, even in the case
that nproc(1) from coreutils is unavailable.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 20 ++++++++++++++++++++
 test-functions | 12 ++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/functions.sh b/functions.sh
index 504ee9e..60a4b2e 100644
--- a/functions.sh
+++ b/functions.sh
@@ -460,6 +460,26 @@ newest()
 	_select_by_mtime -r "$@"
 }
 
+#
+# Tries to determine the number of available processors. Falls back to trying to
+# determine the number of online processors in a way that is somewhat portable.
+#
+get_nprocs()
+{
+	if nproc 2>/dev/null; then
+		# The nproc(1) utility is provided by GNU coreutils. It has the
+		# advantage of acknowledging the effect of sched_setaffinity(2).
+		true
+	elif getconf _NPROCESSORS_ONLN 2>/dev/null; then
+		# This is a non-standard extension. Nevertheless, it works for
+		# glibc, musl-utils, macOS, FreeBSD, NetBSD and OpenBSD.
+		true
+	else
+		warn "get_nprocs: failed to determine the number of processors"
+		false
+	fi
+}
+
 #
 # Considers one or more pathnames and prints the one having the oldest
 # modification time. If at least one parameter is provided, all parameters shall

diff --git a/test-functions b/test-functions
index 813d524..c734141 100755
--- a/test-functions
+++ b/test-functions
@@ -544,6 +544,17 @@ test_whenceforth() {
 	iterate_tests 4 "$@"
 }
 
+test_get_nprocs() {
+	set -- eq 0
+
+	callback() {
+		shift
+		test_description="get_nprocs"
+		nproc=$(get_nprocs) && is_int "${nproc}" && test "${nproc}" -gt 0
+	}
+
+	iterate_tests 2 "$@"
+}
 
 iterate_tests() {
 	slice_width=$1
@@ -610,6 +621,7 @@ test_newest || rc=1
 test_trim || rc=1
 test_hr || rc=1
 test_whenceforth || rc=1
+test_get_nprocs || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     6b1ea77cf5befc19999701a73c64eb39f0dafacd
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun  2 20:57:49 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun 12 07:06:42 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6b1ea77c

Add the oldest() and newest() functions

It compares potentially existing pathnames, printing the oldest and
newest among them by modification time, respectively.

$ . /lib/gentoo/functions.sh
$ newest /etc/*
/etc/environment.d
$ printf '%s\0' /etc/* | newest
/etc/environment.d

Support for pathnames containing <newline> characters may be added once
read -d becomes broadly supported.

https://austingroupbugs.net/view.php?id=245

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh   | 74 ++++++++++++++++++++++++++++++++++++++++++----------------
 test-functions | 39 +++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 20 deletions(-)

diff --git a/functions.sh b/functions.sh
index 0c35b2d..1548bd0 100644
--- a/functions.sh
+++ b/functions.sh
@@ -1,6 +1,6 @@
 # Copyright 1999-2023 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
-# shellcheck shell=sh disable=3043
+# shellcheck shell=sh disable=2209,3043
 
 # This file contains a series of function declarations followed by some
 # initialisation code. Functions intended for internal use shall be prefixed
@@ -401,7 +401,7 @@ is_int()
 #
 is_older_than()
 {
-	local ref has_gfind
+	local ref
 
 	if [ "$#" -eq 0 ]; then
 		warn "is_older_than: too few arguments (got $#, expected at least 1)"
@@ -412,26 +412,39 @@ is_older_than()
 		ref=
 	fi
 	shift
+	{ test "$#" -gt 0 && printf '%s\0' "$@"; } \
+	| "${genfun_bin_find}" -L -files0-from - ${ref:+-newermm} ${ref:+"${ref}"} -printf '\n' -quit \
+	| read -r _
+}
 
-	# Check whether GNU find is installed by the name of "gfind". So as to
-	# avoid repeated PATH lookups, run the hash builtin in the present
-	# shell, prior to forking.
-	hash gfind 2>/dev/null; has_gfind=$(( $? == 0 ))
+#
+# Considers one or more pathnames and prints the one having the newest
+# modification time. If at least one parameter is provided, all parameters shall
+# be considered as pathnames to be compared to one another. Otherwise, the
+# pathnames to be compared shall be read from the standard input as
+# NUL-delimited records. If no pathnames are given, or those specified do not
+# exist, the return value shall be greater than 0. In the case that two or more
+# pathnames are candidates, the one having the lexicographically greatest value
+# shall be selected. Pathnames containing newline characters shall be ignored.
+#
+newest()
+{
+	_select_by_mtime -r "$@"
+}
 
-	for path; do
-		if [ -e "${path}" ]; then
-			printf '%s\0' "${path}"
-		fi
-	done |
-	{
-		set -- -L -files0-from - ${ref:+-newermm} ${ref:+"${ref}"} -printf '\n' -quit
-		if [ "${has_gfind}" -eq 1 ]; then
-			gfind "$@"
-		else
-			find "$@"
-		fi
-	} |
-	read -r _
+#
+# Considers one or more pathnames and prints the one having the oldest
+# modification time. If at least one parameter is provided, all parameters shall
+# be considered as pathnames to be compared to one another. Otherwise, the
+# pathnames to be compared shall be read from the standard input as
+# NUL-delimited records. If no pathnames are given, or those specified do not
+# exist, the return value shall be greater than 0. In the case that two or more
+# pathnames are candidates, the one having the lexicographically lesser value
+# shall be selected. Pathnames containing newline characters shall be ignored.
+#
+oldest()
+{
+	_select_by_mtime -- "$@"
 }
 
 #
@@ -726,6 +739,24 @@ _print_args()
 	EOF
 }
 
+#
+# See the definitions of oldest() and newest().
+#
+_select_by_mtime() {
+	local sort_opt
+
+	sort_opt=$1
+	shift
+	if [ "$#" -ge 0 ]; then
+		printf '%s\0' "$@"
+	else
+		cat
+	fi \
+	| "${genfun_bin_find}" -files0-from - -maxdepth 0 ! -path "*${genfun_newline}*" -printf '%T+ %p\n' \
+	| sort "${sort_opt}" \
+	| { IFS= read -r line && printf '%s\n' "${line#* }"; }
+}
+
 #
 # Determines whether the terminal on STDIN is able to report its dimensions.
 # Upon success, the number of columns shall be stored in genfun_cols.
@@ -805,6 +836,9 @@ if [ "${BASH}" ]; then
 	genfun_bin_true=$(type -P true)
 fi
 
+# Store the name of the GNU find binary. Some platforms may have it as "gfind".
+hash gfind 2>/dev/null && genfun_bin_find=gfind || genfun_bin_find=find
+
 # Determine whether the use of color is to be wilfully avoided.
 if [ -n "${NO_COLOR}" ]; then
 	# See https://no-color.org/.

diff --git a/test-functions b/test-functions
index 0c4a222..400ddb2 100755
--- a/test-functions
+++ b/test-functions
@@ -418,6 +418,44 @@ test_srandom() {
 	iterate_tests 2 "$@"
 }
 
+test_newest() {
+	set -- \
+		ge  1  non-existent  non-existent  \
+		ge  1  N/A           N/A           \
+		                                   \
+		eq  0  newer/file    N/A           \
+		eq  0  newer/file    newer/file    \
+		eq  0  newer/file    non-existent  \
+		eq  0  newer/file    older/file    \
+		eq  0  non-existent  newer/file    \
+		eq  0  older/file    newer/file    \
+		                                   \
+		eq  0  older/file    N/A           \
+		eq  0  older/file    older/file    \
+		eq  0  older/file    non-existent  \
+		ge  1  newer/file    older/file    \
+		eq  0  non-existent  older/file    \
+		ge  1  older/file    newer/file
+
+	row=0
+
+	callback() {
+		shift
+		test_description="newest $(_print_args "$@")"
+		row=$(( row + 1 ))
+		true |
+		if [ "${row}" -le 2 ]; then
+			newest "$@"
+		elif [ "${row}" -le 8 ]; then
+			test "$(newest "$@")" = "newer/file"
+		else
+			test "$(newest "$@")" = "older/file"
+		fi
+	}
+
+	iterate_tests 4 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -479,6 +517,7 @@ test_yesno || rc=1
 test_die || rc=1
 test_edo || rc=1
 test_srandom || rc=1
+test_newest || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     875d349103daa320f3a6cc155bd26103adec89de
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun  2 17:33:55 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Jun 11 06:11:59 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=875d3491

test-functions: Clean up the indentation

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 52 ++++++++++++++++++++++++++--------------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/test-functions b/test-functions
index e0bd127..8ff6380 100755
--- a/test-functions
+++ b/test-functions
@@ -304,13 +304,13 @@ test_is_identifier() {
 		eq  0  Z_a   \
 		eq  0  Z_Z
 
-		callback() {
-			shift
-			test_description="is_identifier $(_print_args "$@")"
-			is_identifier "$@"
-		}
+	callback() {
+		shift
+		test_description="is_identifier $(_print_args "$@")"
+		is_identifier "$@"
+	}
 
-		iterate_tests 3 "$@"
+	iterate_tests 3 "$@"
 }
 
 test_is_int() {
@@ -329,13 +329,13 @@ test_is_int() {
 		eq  0  -1 \
 		eq  0  123456789
 
-		callback() {
-			shift
-			test_description="is_int $(_print_args "$@")"
-			is_int "$@"
-		}
+	callback() {
+		shift
+		test_description="is_int $(_print_args "$@")"
+		is_int "$@"
+	}
 
-		iterate_tests 3 "$@"
+	iterate_tests 3 "$@"
 }
 
 test_is_visible() {
@@ -349,13 +349,13 @@ test_is_visible() {
 		eq  0  "$(printf '\t.\t')" \
 		eq  0  "$(printf '\a.\a')"
 
-		callback() {
-			shift
-			test_description="_is_visible $(_print_args "$@")"
-			_is_visible "$@"
-		}
+	callback() {
+		shift
+		test_description="_is_visible $(_print_args "$@")"
+		_is_visible "$@"
+	}
 
-		iterate_tests 3 "$@"
+	iterate_tests 3 "$@"
 }
 
 test_yesno() {
@@ -385,16 +385,16 @@ test_yesno() {
 		ge  1  not-a-valid-nameref \
 		ge  1  '_"; set -- yes # code injection'
 
-		# shellcheck disable=2034
-		truthful_nameref=yes
+	# shellcheck disable=2034
+	truthful_nameref=yes
 
-		callback() {
-			shift
-			test_description="yesno $(_print_args "$@")"
-			yesno "$@"
-		}
+	callback() {
+		shift
+		test_description="yesno $(_print_args "$@")"
+		yesno "$@"
+	}
 
-		iterate_tests 3 "$@"
+	iterate_tests 3 "$@"
 }
 
 iterate_tests() {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-06-21 13:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-06-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     755177bbfcf4c46ad1ac31ad9501a6c8725b1a68
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun  2 03:36:27 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Jun 11 06:11:59 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=755177bb

Add the warn() function

This will be used internally by a forthcoming commit.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/functions.sh b/functions.sh
index 9736747..a97dde7 100644
--- a/functions.sh
+++ b/functions.sh
@@ -473,6 +473,14 @@ vewend()
 	fi
 }
 
+#
+# Prints a diagnostic message prefixed with the basename of the running script.
+#
+warn()
+{
+	printf '%s: %s\n' "${0##*/}" "$*" >&2
+}
+
 #
 # Determines whether the first parameter is truthy. The values taken to be true
 # are "yes", "true", "on" and "1", whereas their opposites are taken to be


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-24  6:05 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-24  6:05 UTC (permalink / raw
  To: gentoo-commits

commit:     6f545efa90041e0743086f8f99ebe8f711b1fbe9
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Fri May 24 06:04:51 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri May 24 06:04:51 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6f545efa

meson.build: prepare for gentoo-functions-1.6

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 624f5c0..6590240 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project(
   'gentoo-functions', 'c',
-  version: '1.5',
+  version: '1.6',
   license: 'GPL-2.0-only',
   default_options : [
     'warning_level=2',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-24  1:18 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-24  1:18 UTC (permalink / raw
  To: gentoo-commits

commit:     b5feaf2444ae625f5756c7566042d28f81a2cda1
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed May 22 05:54:12 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed May 22 16:27:00 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b5feaf24

Micro-optimise the eqatag() argument parsing loop

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/functions.sh b/functions.sh
index 98e7a6f..f965534 100644
--- a/functions.sh
+++ b/functions.sh
@@ -187,7 +187,7 @@ eoutdent()
 #
 eqatag()
 {
-	local arg argc json positional tag
+	local arg i json positional tag
 
 	case ${genfun_has_jq} in
 		0)
@@ -211,11 +211,14 @@ eqatag()
 	if [ "$#" -eq 0 ]; then
 		die "eqatag: no tag specified"
 	fi
+	positional=0
 	tag=$1
 	shift
-	argc=$#
-	positional=0
+	i=0
 	for arg; do
+		if [ "$(( i += 1 ))" -eq 1 ]; then
+			set --
+		fi
 		case ${arg} in
 			[!=/]*=?*)
 				if [ "${positional}" -eq 1 ]; then
@@ -234,7 +237,6 @@ eqatag()
 				_throw_invalid_args eqatag "${arg}"
 		esac
 	done
-	shift "${argc}"
 	json=$(
 		jq -cn '{
 			eqatag: {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-24  1:18 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-24  1:18 UTC (permalink / raw
  To: gentoo-commits

commit:     2143fdb2adf0131e9baa4f308b8125cfe5e92a47
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed May 22 16:38:23 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed May 22 16:38:23 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2143fdb2

Correct the wrapping of a comment

In accordance with the presumption of a tab being as wide as 8 spaces.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/functions.sh b/functions.sh
index f965534..48b4c5a 100644
--- a/functions.sh
+++ b/functions.sh
@@ -389,9 +389,9 @@ is_older_than()
 	fi
 	shift
 
-	# Check whether GNU find is installed by the name of "gfind". So as to avoid
-	# repeated PATH lookups, run the hash builtin in the present shell, prior to
-	# forking.
+	# Check whether GNU find is installed by the name of "gfind". So as to
+	# avoid repeated PATH lookups, run the hash builtin in the present
+	# shell, prior to forking.
 	hash gfind 2>/dev/null; has_gfind=$(( $? == 0 ))
 
 	for path; do


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-22  1:12 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-22  1:12 UTC (permalink / raw
  To: gentoo-commits

commit:     3de0f4f80587a58d93eb4d67dc0d536035cbd566
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon May 20 07:37:15 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> 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 <kfm <AT> 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 "$@"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-22  1:12 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-22  1:12 UTC (permalink / raw
  To: gentoo-commits

commit:     7b63d3d64275c32676a8cad3377294ab59b54486
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue May 21 10:48:37 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue May 21 12:51:48 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7b63d3d6

test-functions: Minor ebegin() test refactoring

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/test-functions b/test-functions
index 6f755db..d65a3a2 100755
--- a/test-functions
+++ b/test-functions
@@ -95,19 +95,19 @@ test_ebegin() {
 	_eprint() {
 		shift
 		_ends_with_newline "$*"
-		ok=$(( $? == 0 ))
 	}
 
 	ok=0
 	set -- "message"
 	ebegin "$1"
+	retval=$?
 
-	if [ "${ok}" -eq 0 ]; then
+	if [ "${retval}" -ne 0 ]; then
 		printf 'not '
 	fi
 	printf 'ok %d - ebegin %s (expecting terminating newline)\n' "$((testnum + 1))" "$1"
 
-	return "$(( ok ? 0 : 1 ))"
+	return "${retval}"
 }
 
 test_edo() {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-22  1:12 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-22  1:12 UTC (permalink / raw
  To: gentoo-commits

commit:     e1b0fb2a8eb93814ff1d895964ad03d5166175e3
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon May 20 05:55:55 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon May 20 07:50:07 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=e1b0fb2a

Correct an awk else clause in _print_args()

The routine was working correctly anyway, but through fortune. Stick to using
curly braces to avoid any mishaps further down the line.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/functions.sh b/functions.sh
index bbbd114..100bd30 100644
--- a/functions.sh
+++ b/functions.sh
@@ -625,21 +625,25 @@ _print_args() {
 					word = "$'"
 					for (i = 1; i <= length(arg); i++) {
 						char = substr(arg, i, 1)
-						if (char == "\\")
+						if (char == "\\") {
 							word = word "\\\\"
-						else if (char == q)
+						} else if (char == q) {
 							word = word "\\'"
-						else
+						} else {
 							ord = ord_by[char]
-							if (ord != "")
+							if (ord != "") {
 								word = word "\\" sprintf("%03o", ord)
-							else
+							} else {
 								word = word char
+							}
+						}
 					}
 					word = word q
 				}
 				line = line word
-				if (arg_idx < argc - 1) line = line " "
+				if (arg_idx < argc - 1) {
+					line = line " "
+				}
 			}
 			print line
 		}


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-22  1:12 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-22  1:12 UTC (permalink / raw
  To: gentoo-commits

commit:     b68b40c719d66641a1a0d23b912523ab72d52277
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue May 21 12:46:17 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue May 21 12:51:56 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b68b40c7

Explain why is_older_than() checks for the presence of gfind

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 8c0d1c1..98e7a6f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -387,7 +387,9 @@ is_older_than()
 	fi
 	shift
 
-	# Consult the hash table in the present shell, prior to forking.
+	# Check whether GNU find is installed by the name of "gfind". So as to avoid
+	# repeated PATH lookups, run the hash builtin in the present shell, prior to
+	# forking.
 	hash gfind 2>/dev/null; has_gfind=$(( $? == 0 ))
 
 	for path; do


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-22  1:12 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-22  1:12 UTC (permalink / raw
  To: gentoo-commits

commit:     cac89f9c95f04128a7cd119ac9acd1127f0d3e64
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue May 21 10:45:54 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue May 21 11:03:07 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=cac89f9c

test-functions: Render tests somewhat fast again

Do so by having the tests for is_older_than() and yesno() employ
subshells only where necessary.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/test-functions b/test-functions
index 40beded..6f755db 100755
--- a/test-functions
+++ b/test-functions
@@ -196,7 +196,11 @@ test_is_older_than() {
 	callback() {
 		shift
 		test_description="is_older_than $(_print_args "$@")"
-		( is_older_than "$@" )
+		if [ "$#" -lt 2 ]; then
+			( is_older_than "$@" )
+		else
+			is_older_than "$@"
+		fi
 	}
 
 	iterate_tests 4 "$@"
@@ -371,6 +375,7 @@ test_yesno() {
 		eq  0  ON \
 		eq  0  On \
 		eq  0  1 \
+		eq  0  truthful_nameref \
 		ge  1  no \
 		ge  1  NO \
 		ge  1  No \
@@ -383,16 +388,20 @@ test_yesno() {
 		ge  1  0 \
 		ge  1  not_a_nameref \
 		ge  1  not-a-valid-nameref \
-		ge  1  '_"; set -- yes # code injection' \
-		eq  0  truthful_nameref
+		ge  1  '_"; set -- yes # code injection'
 
 		# shellcheck disable=2034
 		truthful_nameref=yes
+		row=0
 
 		callback() {
 			shift
 			test_description="yesno $(_print_args "$@")"
-			( yesno "$@" )
+			if [ "$(( row += 1 ))" -ge 22 ]; then
+				( yesno "$@" )
+			else
+				yesno "$@"
+			fi
 		}
 
 		iterate_tests 3 "$@"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-22  1:12 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-22  1:12 UTC (permalink / raw
  To: gentoo-commits

commit:     5c82cfc08a05e994dbb719040a8ed6c81f6b6ec6
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon May 20 07:45:22 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon May 20 09:28:20 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=5c82cfc0

Adhere to the Allman style (again)

For sh, not awk.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/functions.sh b/functions.sh
index c82c229..8c0d1c1 100644
--- a/functions.sh
+++ b/functions.sh
@@ -92,7 +92,8 @@ ebegin()
 # Should the command fail, a diagnostic message shall be printed and the shell
 # be made to exit by calling the die function.
 #
-edo() {
+edo()
+{
 	genfun_cmd=$(_print_args "$@")
 	einfo "Executing: ${genfun_cmd}"
 	"$@" || die "Failed to execute command: ${genfun_cmd}"
@@ -117,7 +118,8 @@ eend()
 #
 for _ in eerror einfo ewarn; do
 	eval "
-		$_ () {
+		$_ ()
+		{
 			${_}n \"\${*}\${genfun_newline}\"
 		}
 	"
@@ -183,7 +185,8 @@ eoutdent()
 # parameters the value of a "files" key. The resulting object shall be rendered
 # as JSON by jq(1) before being logged by the logger(1) utility.
 #
-eqatag() {
+eqatag()
+{
 	local arg argc json positional tag
 
 	case ${genfun_has_jq} in
@@ -249,7 +252,8 @@ eqatag() {
 # the message shall also be conveyed to the esyslog function. For now, this is
 # implemented merely as an ewarn wrapper.
 #
-eqawarn() {
+eqawarn()
+{
 	ewarn "$@"
 }
 
@@ -409,7 +413,8 @@ is_older_than()
 #
 for _ in vebegin veerror veindent veinfo veinfon veoutdent vewarn; do
 	eval "
-		$_ () {
+		$_ ()
+		{
 			if yesno \"\${EINFO_VERBOSE}\"; then
 				${_#v} \"\$@\"
 			fi
@@ -605,7 +610,8 @@ _is_visible()
 # of the ${*@Q} expansion in bash. The output shall be POSIX sh compatible as of
 # Issue 8. This should probably be made to exist as a standalone awk script.
 #
-_print_args() {
+_print_args()
+{
 	awk -v q=\' -f - -- "$@" <<-'EOF'
 		BEGIN {
 			argc = ARGC


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-22  1:12 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-22  1:12 UTC (permalink / raw
  To: gentoo-commits

commit:     85e364c40ed8ec473888b28d71a759365cc78aa5
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun May 19 19:45:30 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon May 20 07:49:54 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=85e364c4

test-functions: Include /opt/pkg/bin in PATH

This helps where testing on platforms having utilities that were
installed by pkgsrc. In particular, gfind.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-functions b/test-functions
index 1fe07ad..7eb5981 100755
--- a/test-functions
+++ b/test-functions
@@ -435,7 +435,7 @@ printf 'TAP version 13\n'
 unset -v dir
 
 # PATH is redefined to prevent ebuild-helpers such as die from interfering.
-export PATH=/sbin:/bin:/usr/sbin:/usr/bin
+export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/opt/pkg/bin
 export TEST_GENFUNCS=1
 export TZ=UTC
 testnum=0


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-22  1:12 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-22  1:12 UTC (permalink / raw
  To: gentoo-commits

commit:     1515b614f83bc30fe1ed63d6a76bf4ede0b5c2f8
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun May 19 22:03:53 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon May 20 07:50:05 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1515b614

Have _print_args() produce octal sequences for DEL

With this change, octal sequences are rendered for all non-printable
characters in the US-ASCII character set.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index 94d0f98..bbbd114 100644
--- a/functions.sh
+++ b/functions.sh
@@ -603,7 +603,6 @@ _is_visible()
 # of the ${*@Q} expansion in bash. The output shall be POSIX sh compatible as of
 # Issue 8. This should probably be made to exist as a standalone awk script.
 #
-#
 _print_args() {
 	awk -v q=\' -f - -- "$@" <<-'EOF'
 		BEGIN {
@@ -611,7 +610,7 @@ _print_args() {
 			ARGC = 1
 			for (arg_idx = 1; arg_idx < argc; arg_idx++) {
 				arg = ARGV[arg_idx]
-				if (arg !~ /[\001-\037]/) {
+				if (arg !~ /[\001-\037\177]/) {
 					gsub(q, q "\\" q q, arg)
 					word = q arg q
 				} else {
@@ -621,6 +620,7 @@ _print_args() {
 							char = sprintf("%c", i)
 							ord_by[char] = i
 						}
+						ord_by["\177"] = 127
 					}
 					word = "$'"
 					for (i = 1; i <= length(arg); i++) {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-22  1:12 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-22  1:12 UTC (permalink / raw
  To: gentoo-commits

commit:     8a8dc3b63c8c639117c12a22960b03102dc00942
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun May 19 17:41:23 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon May 20 07:49:53 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=8a8dc3b6

Add an eqatag() function

This differs from the isolated-functions implementation in that it will
render a line of compact JSON then use the logger(1) utility to log it.
It requires jq in order to do so. Should jq be unavailable, a warning
will be displayed, though no more than once.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Bug: https://bugs.gentoo.org/878505

 functions.sh | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/functions.sh b/functions.sh
index f2e5bb5..94d0f98 100644
--- a/functions.sh
+++ b/functions.sh
@@ -172,6 +172,78 @@ eoutdent()
 	_esetdent "$(( ${#genfun_indent} - $1 ))"
 }
 
+#
+# This is based on the eqatag function defined by isolated-functions.sh in
+# portage. If the first parameter is the -v option, it shall be disregarded.
+# Discounting said option, at least one parameter is required, which shall be
+# taken as a tag name. Thereafter, zero or more parameters shall be accepted in
+# the form of "key=val", followed by zero or more parameters beginning with a
+# <slash>. An object shall be composed in which the tag is the value of a "tag"
+# key, the key/value pairs the value of a "data" key, and the <slash>-prefixed
+# parameters the value of a "files" key. The resulting object shall be rendered
+# as JSON by jq(1) before being logged by the logger(1) utility.
+#
+eqatag() {
+	local arg argc json positional tag
+
+	case ${genfun_has_jq} in
+		0)
+			return 1
+			;;
+		1)
+			;;
+		*)
+			if command -v jq >/dev/null; then
+				genfun_has_jq=1
+			else
+				ewarn "The eqatag() function requires that jq be installed"
+				genfun_has_jq=0
+				return 1
+			fi
+	esac
+	# Acknowledge the -v option for isolated-functions API compatibility.
+	if [ "$1" = "-v" ]; then
+		shift
+	fi
+	if [ "$#" -eq 0 ]; then
+		die "eqatag: no tag specified"
+	fi
+	tag=$1
+	shift
+	argc=$#
+	positional=0
+	for arg; do
+		case ${arg} in
+			[!=/]*=?*)
+				if [ "${positional}" -eq 1 ]; then
+					die "eqatag: invalid argument in positional context -- ${arg}"
+				fi
+				set -- "$@" --arg "${arg%%=*}" "${arg#*=}"
+				;;
+			/*)
+				if [ "${positional}" -eq 0 ]; then
+					set -- "$@" --args --
+					positional=1
+				fi
+				set -- "$@" "${arg}"
+				;;
+			*)
+				die "eqatag: invalid argument -- ${arg}"
+		esac
+	done
+	shift "${argc}"
+	json=$(
+		jq -cn '{
+			eqatag: {
+				tag:   $ARGS.named["=tag"],
+				data:  $ARGS.named | with_entries(select(.key | startswith("=") | not)),
+				files: $ARGS.positional
+			}
+		}' --arg "=tag" "${tag}" "$@"
+	) \
+	&& logger -p user.debug -t "${0##*/}" -- "${json}"
+}
+
 #
 # Prints a QA warning message, provided that EINFO_QUIET is false. If printed,
 # the message shall also be conveyed to the esyslog function. For now, this is


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-19 15:27 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-19 15:27 UTC (permalink / raw
  To: gentoo-commits

commit:     1b936a7427ec2100b782dd2e19b47b7f54886be3
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun May 19 14:33:54 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun May 19 14:48:33 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1b936a74

Significantly improve _print_args() behaviour

It will now employ $'' style quoting where useful, per Issue 8:

https://austingroupbugs.net/view.php?id=249

Characters whose ordinal values are lower than 0x20 will be converted to
octal sequences. It should be considered in due course whether this
ought to exist as a standalone awk script.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 42 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/functions.sh b/functions.sh
index 462db97..890fa7a 100644
--- a/functions.sh
+++ b/functions.sh
@@ -94,8 +94,8 @@ ebegin()
 #
 edo() {
 	genfun_cmd=$(_print_args "$@")
-	einfo "${genfun_cmd% }"
-	"$@" || die "Failed to run command: ${genfun_cmd% }"
+	einfo "${genfun_cmd}"
+	"$@" || die "Failed to run command: ${genfun_cmd}"
 }
 
 #
@@ -528,18 +528,46 @@ _is_visible()
 
 #
 # Prints the positional parameters in a manner that approximates the behaviour
-# of the ${*@Q} expansion in bash.
+# of the ${*@Q} expansion in bash. The output shall be POSIX sh compatible as of
+# Issue 8. This should probably be made to exist as a standalone awk script.
+#
 #
 _print_args() {
 	awk -v q=\' -f - -- "$@" <<-'EOF'
 		BEGIN {
+			for (i = 1; i < 32; i++) {
+				char = sprintf("%c", i)
+				ord_by[char] = i
+			}
 			argc = ARGC
 			ARGC = 1
-			for (i = 1; i < argc; i++) {
-				arg = ARGV[i]
-				gsub(q, q "\\" q q, arg)
-				printf("'%s' ", arg)
+			for (arg_idx = 1; arg_idx < argc; arg_idx++) {
+				arg = ARGV[arg_idx]
+				if (arg !~ /[\001-\037]/) {
+					gsub(q, q "\\" q q, arg)
+					word = q arg q
+				} else {
+					# Use $'' quoting per Issue 8
+					word = "$'"
+					for (i = 1; i <= length(arg); i++) {
+						char = substr(arg, i, 1)
+						if (char == "\\")
+							word = word "\\\\"
+						else if (char == q)
+							word = word "\\'"
+						else
+							ord = ord_by[char]
+							if (ord != "")
+								word = word "\\" sprintf("%03o", ord)
+							else
+								word = word char
+					}
+					word = word q
+				}
+				line = line word
+				if (arg_idx < argc - 1) line = line " "
 			}
+			print line
 		}
 	EOF
 }


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-19 15:27 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-19 15:27 UTC (permalink / raw
  To: gentoo-commits

commit:     0744f81fd5109779a86026db2d1c42ee0230a38d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun May 19 14:31:06 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun May 19 14:31:06 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=0744f81f

test-functions: Actually remove print_args()

This was supposed to be staged for the last commit that touched
test-functions but was harmlessly omitted.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/test-functions b/test-functions
index 24a7527..1fe07ad 100755
--- a/test-functions
+++ b/test-functions
@@ -430,23 +430,6 @@ iterate_tests() {
 	return "$(( passed < total ))"
 }
 
-print_args() {
-	i=0
-	for arg; do
-		if [ "$((i += 1))" -eq 1 ]; then
-			set --
-		fi
-		case ${arg} in
-			''|*[[:space:]]*)
-				set -- "$@" "'${arg}'"
-				;;
-			*)
-				set -- "$@" "${arg}"
-		esac
-	done
-	printf '%s\n' "$*"
-}
-
 printf 'TAP version 13\n'
 
 unset -v dir


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-19 15:27 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-19 15:27 UTC (permalink / raw
  To: gentoo-commits

commit:     774be3a959c128a8cac1d641edb2e208421cc796
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun May 19 14:51:16 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun May 19 14:51:16 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=774be3a9

Have edo() clarify that something is being executed

Because that is what happens.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index 890fa7a..0f0aa44 100644
--- a/functions.sh
+++ b/functions.sh
@@ -94,8 +94,8 @@ ebegin()
 #
 edo() {
 	genfun_cmd=$(_print_args "$@")
-	einfo "${genfun_cmd}"
-	"$@" || die "Failed to run command: ${genfun_cmd}"
+	einfo "Executing: ${genfun_cmd}"
+	"$@" || die "Failed to execute command: ${genfun_cmd}"
 }
 
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-19 15:27 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-19 15:27 UTC (permalink / raw
  To: gentoo-commits

commit:     0fbe3a4835e538969c5818ca6bece91de933a8de
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun May 19 14:56:18 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun May 19 14:56:18 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=0fbe3a48

Micro-optimise _print_args()

Optimise _print_args() by initialising the ord_by array lazily.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/functions.sh b/functions.sh
index 0f0aa44..f2e5bb5 100644
--- a/functions.sh
+++ b/functions.sh
@@ -535,10 +535,6 @@ _is_visible()
 _print_args() {
 	awk -v q=\' -f - -- "$@" <<-'EOF'
 		BEGIN {
-			for (i = 1; i < 32; i++) {
-				char = sprintf("%c", i)
-				ord_by[char] = i
-			}
 			argc = ARGC
 			ARGC = 1
 			for (arg_idx = 1; arg_idx < argc; arg_idx++) {
@@ -548,6 +544,12 @@ _print_args() {
 					word = q arg q
 				} else {
 					# Use $'' quoting per Issue 8
+					if (ord_by["\001"] == "") {
+						for (i = 1; i < 32; i++) {
+							char = sprintf("%c", i)
+							ord_by[char] = i
+						}
+					}
 					word = "$'"
 					for (i = 1; i <= length(arg); i++) {
 						char = substr(arg, i, 1)


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 16:07 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 16:07 UTC (permalink / raw
  To: gentoo-commits

commit:     69c7011e4fc200c569afdd289b447efa0e27b856
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sat May 18 16:06:59 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 16:06:59 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=69c7011e

meson.build: prepare for gentoo-functions-1.5

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 7490294..624f5c0 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project(
   'gentoo-functions', 'c',
-  version: '1.4',
+  version: '1.5',
   license: 'GPL-2.0-only',
   default_options : [
     'warning_level=2',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 16:06 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 16:06 UTC (permalink / raw
  To: gentoo-commits

commit:     c0868e07f874b47c9f353c47b3b9ad34e0b5f828
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat May 18 15:51:23 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 16:06:45 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=c0868e07

Signify end of options to awk in edo()

This is a fairly important fix because awk doesn't stop looking for
options upon encountering the first non-option argument.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index fdba0c1..db3314a 100644
--- a/functions.sh
+++ b/functions.sh
@@ -95,7 +95,7 @@ ebegin()
 edo() {
 	# Approximate the effect of ${param@Q} bash expansion.
 	genfun_cmd=$(
-		awk -v q=\' -f - "$@" <<-'EOF'
+		awk -v q=\' -f - -- "$@" <<-'EOF'
 			BEGIN {
 				argc = ARGC
 				ARGC = 1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 16:06 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 16:06 UTC (permalink / raw
  To: gentoo-commits

commit:     18e702eb8d32695dc503fc272d23e21cad7a6b12
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat May 18 16:03:46 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 16:06:45 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=18e702eb

Separate some edo() code into a _print_args() helper function

Further, make test-functions use _print_args() and jettison the inferior
print_args() function that it was previously using.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh   | 33 +++++++++++++++++++--------------
 test-functions | 18 +++++++++---------
 2 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/functions.sh b/functions.sh
index db3314a..462db97 100644
--- a/functions.sh
+++ b/functions.sh
@@ -93,20 +93,7 @@ ebegin()
 # be made to exit by calling the die function.
 #
 edo() {
-	# Approximate the effect of ${param@Q} bash expansion.
-	genfun_cmd=$(
-		awk -v q=\' -f - -- "$@" <<-'EOF'
-			BEGIN {
-				argc = ARGC
-				ARGC = 1
-				for (i = 1; i < argc; i++) {
-					arg = ARGV[i]
-					gsub(q, q "\\" q q, arg)
-					printf("'%s' ", arg)
-				}
-			}
-		EOF
-	)
+	genfun_cmd=$(_print_args "$@")
 	einfo "${genfun_cmd% }"
 	"$@" || die "Failed to run command: ${genfun_cmd% }"
 }
@@ -539,6 +526,24 @@ _is_visible()
 	! case $1 in *[[:graph:]]*) false ;; esac
 }
 
+#
+# Prints the positional parameters in a manner that approximates the behaviour
+# of the ${*@Q} expansion in bash.
+#
+_print_args() {
+	awk -v q=\' -f - -- "$@" <<-'EOF'
+		BEGIN {
+			argc = ARGC
+			ARGC = 1
+			for (i = 1; i < argc; i++) {
+				arg = ARGV[i]
+				gsub(q, q "\\" q q, arg)
+				printf("'%s' ", arg)
+			}
+		}
+	EOF
+}
+
 #
 # 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 0c0bb45..24a7527 100755
--- a/test-functions
+++ b/test-functions
@@ -41,7 +41,7 @@ test_chdir() {
 
 	callback() {
 		shift
-		test_description="chdir $(print_args "$@")"
+		test_description="chdir $(_print_args "$@")"
 		if [ "$BASH" ]; then
 			# shellcheck disable=3044
 			shopt -s cdable_vars
@@ -60,7 +60,7 @@ test_chdir_noop() {
 
 	callback() {
 		shift
-		test_description="chdir $(print_args "$@")"
+		test_description="chdir $(_print_args "$@")"
 		chdir "$@" \
 		&& test "$PWD" = "$OLDPWD" \
 		|| { cd - >/dev/null; false; }
@@ -195,7 +195,7 @@ test_is_older_than() {
 
 	callback() {
 		shift
-		test_description="is_older_than $(print_args "$@")"
+		test_description="is_older_than $(_print_args "$@")"
 		is_older_than "$@"
 	}
 
@@ -221,7 +221,7 @@ test_get_bootparam() {
 	callback() {
 		cmdline=$2
 		shift 2
-		test_description="get_bootparam $(print_args "$@")"
+		test_description="get_bootparam $(_print_args "$@")"
 		printf '%s\n' "${cmdline}" | get_bootparam "$@"
 	}
 
@@ -246,7 +246,7 @@ test_esyslog() {
 		should_log=$2
 		shift 2
 		logged=0
-		test_description="esyslog $(print_args "$@")"
+		test_description="esyslog $(_print_args "$@")"
 		EINFO_LOG=1 esyslog "$@" 2>/dev/null
 		case $? in
 			0)
@@ -308,7 +308,7 @@ test_is_identifier() {
 
 		callback() {
 			shift
-			test_description="is_identifier $(print_args "$@")"
+			test_description="is_identifier $(_print_args "$@")"
 			is_identifier "$@"
 		}
 
@@ -333,7 +333,7 @@ test_is_int() {
 
 		callback() {
 			shift
-			test_description="is_int $(print_args "$@")"
+			test_description="is_int $(_print_args "$@")"
 			is_int "$@"
 		}
 
@@ -353,7 +353,7 @@ test_is_visible() {
 
 		callback() {
 			shift
-			test_description="_is_visible $(print_args "$@")"
+			test_description="_is_visible $(_print_args "$@")"
 			_is_visible "$@"
 		}
 
@@ -392,7 +392,7 @@ test_yesno() {
 
 		callback() {
 			shift
-			test_description="yesno $(print_args "$@")"
+			test_description="yesno $(_print_args "$@")"
 			yesno "$@"
 		}
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 15:34 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 15:34 UTC (permalink / raw
  To: gentoo-commits

commit:     d35f48614dcdae664b3d20103ba25c747e117990
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sat May 18 15:33:52 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 15:34:01 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d35f4861

meson.build: prepare for gentoo-functions-1.4

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index d868613..7490294 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project(
   'gentoo-functions', 'c',
-  version: '1.3',
+  version: '1.4',
   license: 'GPL-2.0-only',
   default_options : [
     'warning_level=2',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 15:32 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 15:32 UTC (permalink / raw
  To: gentoo-commits

commit:     66c893e7e073006d9b437ed1b5d24644d4a384af
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat May 18 15:16:54 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 15:32:16 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=66c893e7

test-functions: Fix spurious edo() test failures

Portage amends PATH in such a way that "ebuild-helper" utilities can be
found. One of those is a die utility. What purpose that can serve is
presently unclear to me. In any case, it was impeding the declaration of
the die() function provided by gentoo-functions. Address it by setting
PATH to a sane, generic value prior to sourcing the functions for
testing.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/test-functions b/test-functions
index 0dea9f3..0c0bb45 100755
--- a/test-functions
+++ b/test-functions
@@ -451,17 +451,19 @@ printf 'TAP version 13\n'
 
 unset -v dir
 
+# PATH is redefined to prevent ebuild-helpers such as die from interfering.
+export PATH=/sbin:/bin:/usr/sbin:/usr/bin
+export TEST_GENFUNCS=1
+export TZ=UTC
+testnum=0
+rc=0
+
 if ! . ./functions.sh; then
 	bailout "Couldn't source ./functions.sh"
 fi
 
 assign_tmpdir
 
-export TEST_GENFUNCS=1
-export TZ=UTC
-testnum=0
-rc=0
-
 test_chdir || rc=1
 test_chdir_noop || rc=1
 ( test_ebegin ) || rc=1; testnum=$((testnum + 1))


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 15:32 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 15:32 UTC (permalink / raw
  To: gentoo-commits

commit:     11043c2d2f4efc455877e68380b711464d4b0d59
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat May 18 14:46:26 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 15:32:14 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=11043c2d

test-functions: Fix invalid TAP output

Quite rightly, meson complains about the output of the edo tests constituting
invalid TAP. Since only the exit status matters, mute STDOUT for these
particular tests.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-functions b/test-functions
index 9414136..0dea9f3 100755
--- a/test-functions
+++ b/test-functions
@@ -118,7 +118,7 @@ test_edo() {
 	callback() {
 		shift
 		test_description="edo $1"
-		( edo "$1" )
+		( edo "$1" >/dev/null )
 	}
 
 	iterate_tests 3 "$@"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 14:04 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 14:04 UTC (permalink / raw
  To: gentoo-commits

commit:     225875f2041902344e6e9744af17836b1fdfe67c
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sat May 18 14:04:17 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 14:04:30 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=225875f2

meson.build: prepare for gentoo-functions-1.3

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 0c564b3..d868613 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project(
   'gentoo-functions', 'c',
-  version: '1.2',
+  version: '1.3',
   license: 'GPL-2.0-only',
   default_options : [
     'warning_level=2',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 14:04 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 14:04 UTC (permalink / raw
  To: gentoo-commits

commit:     dea9bf08dd93895101331a3d4e307199d6962891
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat May 18 13:13:37 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 13:27:54 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=dea9bf08

Add an edo() function

Its implementation is similar to that of the edo eclass.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Bug: https://bugs.gentoo.org/878505

 functions.sh   | 25 +++++++++++++++++++++++++
 test-functions | 15 +++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/functions.sh b/functions.sh
index 2efcf1f..6301c40 100644
--- a/functions.sh
+++ b/functions.sh
@@ -86,6 +86,31 @@ ebegin()
 	fi
 }
 
+#
+# Takes the positional parameters as the definition of a simple command then
+# prints the command as an informational message with einfo before executing it.
+# Should the command fail, a diagnostic message shall be printed and the shell
+# be made to exit by calling the die function.
+#
+edo() {
+	# Approximate the effect of ${param@Q} bash expansion.
+	genfun_cmd=$(
+		awk -v q=\' -f - "$@" <<-'EOF'
+			BEGIN {
+				argc = ARGC
+				ARGC = 1
+				for (i = 1; i < argc; i++) {
+					arg = ARGV[i]
+					gsub(q, q "\\" q q, arg)
+					printf("'%s' ", arg)
+				}
+			}
+		EOF
+	)
+	einfo "${genfun_cmd% }"
+	"$@" || die "Failed to run command: ${genfun_cmd% }"
+}
+
 #
 # Prints an indicator to convey the completion of a given process, provided that
 # EINFO_QUIET is false. It is expected that it be paired with an earlier call to

diff --git a/test-functions b/test-functions
index d46546a..9414136 100755
--- a/test-functions
+++ b/test-functions
@@ -110,6 +110,20 @@ test_ebegin() {
 	return "$(( ok ? 0 : 1 ))"
 }
 
+test_edo() {
+	set -- \
+		eq  1  false \
+		eq  0  true
+
+	callback() {
+		shift
+		test_description="edo $1"
+		( edo "$1" )
+	}
+
+	iterate_tests 3 "$@"
+}
+
 test_is_older_than() {
 	set -- \
 		ge  1  N/A           N/A \
@@ -459,6 +473,7 @@ test_is_int || rc=1
 test_is_visible || rc=1
 test_yesno || rc=1
 test_die || rc=1
+test_edo || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 14:04 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 14:04 UTC (permalink / raw
  To: gentoo-commits

commit:     973fe5e1968e4ee6bcffa78b59807eb4f81e5823
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat May 18 13:15:36 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 13:28:00 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=973fe5e1

Reposition the declaration of _has_dumb_terminal()

So as to maintain an alphabetical order.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/functions.sh b/functions.sh
index 6301c40..fdba0c1 100644
--- a/functions.sh
+++ b/functions.sh
@@ -505,14 +505,6 @@ _esetdent()
 	genfun_indent=$(printf "%${1}s" '')
 }
 
-#
-# Determines whether the terminal is a dumb one.
-#
-_has_dumb_terminal()
-{
-	! case ${TERM} in *dumb*) false ;; esac
-}
-
 #
 # Tries to determine whether the terminal supports ECMA-48 SGR color sequences.
 #
@@ -531,6 +523,14 @@ _has_color_terminal()
 	fi
 }
 
+#
+# Determines whether the terminal is a dumb one.
+#
+_has_dumb_terminal()
+{
+	! case ${TERM} in *dumb*) false ;; esac
+}
+
 #
 # Determines whether the first parameter contains any visible characters.
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 14:04 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 14:04 UTC (permalink / raw
  To: gentoo-commits

commit:     730f6a6388342cdbe2a80fe78cfce30b8c952cab
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat May 18 10:04:13 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 10:14:34 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=730f6a63

test-functions: Fix a spurious test failure

The second-to-last commit added a test case for the die() function but
also made it so that the exit status of each test is always compared to
the expected value with the -eq operator. This turns out be
insufficiently inflexible. For example, cd may return 2 in bash but 1 in
another shell.

Address this by requiring for each operand slice defined by a callback
function to begin with an operator name, and by having the
iterate_tests() function use the operator at the time of invoking the
test utility.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 373 +++++++++++++++++++++++++++++----------------------------
 1 file changed, 188 insertions(+), 185 deletions(-)

diff --git a/test-functions b/test-functions
index e087a3c..4360eb2 100755
--- a/test-functions
+++ b/test-functions
@@ -26,14 +26,14 @@ cleanup_tmpdir() {
 
 test_chdir() {
 	set -- \
-		1  grandchild  \
-		1         var  \
-		0          -L  \
-		0          -p  \
-		0          -e  \
-		0          -@  \
-		0           -  \
-		0       child
+		ge  1  grandchild  \
+		ge  1         var  \
+		eq  0          -L  \
+		eq  0          -p  \
+		eq  0          -e  \
+		eq  0          -@  \
+		eq  0           -  \
+		eq  0       child
 
 	if ! mkdir -p -- -L -p -e -@ - child child/grandchild; then
 		bailout "Couldn't set up all test directories"
@@ -51,11 +51,12 @@ test_chdir() {
 		&& cd - >/dev/null
 	}
 
-	iterate_tests 2 "$@"
+	iterate_tests 3 "$@"
 }
 
 test_chdir_noop() {
-	set -- 0 ''
+	set -- \
+		eq  0  ''
 
 	callback() {
 		shift
@@ -65,15 +66,15 @@ test_chdir_noop() {
 		|| { cd - >/dev/null; false; }
 	}
 
-	iterate_tests 2 "$@"
+	iterate_tests 3 "$@"
 }
 
 test_die() {
 	set -- \
-		1     0 \
-		2     2 \
-		126 126 \
-		255 255
+		eq    1    0 \
+		eq    2    2 \
+		eq  126  126 \
+		eq  255  255
 
 	callback() {
 		test_description="( exit "$2" ); die"
@@ -87,7 +88,7 @@ test_die() {
 		fi
 	}
 
-	iterate_tests 2 "$@"
+	iterate_tests 3 "$@"
 }
 
 test_ebegin() {
@@ -111,60 +112,60 @@ test_ebegin() {
 
 test_is_older_than() {
 	set -- \
-		1  N/A           N/A \
-		1  newer         N/A \
-		1  newer-empty   N/A \
-		1  newer/file    N/A \
-		1  non-existent  N/A \
-		0  newer         newer \
-		1  newer         newer-empty \
-		0  newer         newer/file \
-		1  newer         non-existent \
-		1  newer         older \
-		1  newer         older-empty \
-		1  newer         older/file \
-		0  newer-empty   newer \
-		1  newer-empty   newer-empty \
-		0  newer-empty   newer/file \
-		1  newer-empty   non-existent \
-		1  newer-empty   older \
-		1  newer-empty   older-empty \
-		1  newer-empty   older/file \
-		1  newer/file    newer \
-		1  newer/file    newer-empty \
-		1  newer/file    newer/file \
-		1  newer/file    non-existent \
-		1  newer/file    older \
-		1  newer/file    older-empty \
-		1  newer/file    older/file \
-		0  non-existent  newer \
-		0  non-existent  newer-empty \
-		0  non-existent  newer/file \
-		1  non-existent  non-existent \
-		0  non-existent  older \
-		0  non-existent  older-empty \
-		0  non-existent  older/file \
-		0  older         newer \
-		0  older         newer-empty \
-		0  older         newer/file \
-		1  older         non-existent \
-		0  older         older \
-		1  older         older-empty \
-		0  older         older/file \
-		0  older-empty   newer \
-		0  older-empty   newer-empty \
-		0  older-empty   newer/file \
-		1  older-empty   non-existent \
-		0  older-empty   older \
-		1  older-empty   older-empty \
-		0  older-empty   older/file \
-		0  older/file    newer \
-		0  older/file    newer-empty \
-		0  older/file    newer/file \
-		1  older/file    non-existent \
-		1  older/file    older \
-		1  older/file    older-empty \
-		1  older/file    older/file
+		ge  1  N/A           N/A \
+		ge  1  newer         N/A \
+		ge  1  newer-empty   N/A \
+		ge  1  newer/file    N/A \
+		ge  1  non-existent  N/A \
+		eq  0  newer         newer \
+		ge  1  newer         newer-empty \
+		eq  0  newer         newer/file \
+		ge  1  newer         non-existent \
+		ge  1  newer         older \
+		ge  1  newer         older-empty \
+		ge  1  newer         older/file \
+		eq  0  newer-empty   newer \
+		ge  1  newer-empty   newer-empty \
+		eq  0  newer-empty   newer/file \
+		ge  1  newer-empty   non-existent \
+		ge  1  newer-empty   older \
+		ge  1  newer-empty   older-empty \
+		ge  1  newer-empty   older/file \
+		ge  1  newer/file    newer \
+		ge  1  newer/file    newer-empty \
+		ge  1  newer/file    newer/file \
+		ge  1  newer/file    non-existent \
+		ge  1  newer/file    older \
+		ge  1  newer/file    older-empty \
+		ge  1  newer/file    older/file \
+		eq  0  non-existent  newer \
+		eq  0  non-existent  newer-empty \
+		eq  0  non-existent  newer/file \
+		ge  1  non-existent  non-existent \
+		eq  0  non-existent  older \
+		eq  0  non-existent  older-empty \
+		eq  0  non-existent  older/file \
+		eq  0  older         newer \
+		eq  0  older         newer-empty \
+		eq  0  older         newer/file \
+		ge  1  older         non-existent \
+		eq  0  older         older \
+		ge  1  older         older-empty \
+		eq  0  older         older/file \
+		eq  0  older-empty   newer \
+		eq  0  older-empty   newer-empty \
+		eq  0  older-empty   newer/file \
+		ge  1  older-empty   non-existent \
+		eq  0  older-empty   older \
+		ge  1  older-empty   older-empty \
+		eq  0  older-empty   older/file \
+		eq  0  older/file    newer \
+		eq  0  older/file    newer-empty \
+		eq  0  older/file    newer/file \
+		ge  1  older/file    non-existent \
+		ge  1  older/file    older \
+		ge  1  older/file    older-empty \
+		ge  1  older/file    older/file
 
 	# The mtimes need to be explicitly assigned. Empirical evidence has
 	# shown that executing mkdir(1) sequentially, with a single operand
@@ -184,24 +185,24 @@ test_is_older_than() {
 		is_older_than "$@"
 	}
 
-	iterate_tests 3 "$@"
+	iterate_tests 4 "$@"
 }
 
 test_get_bootparam() {
 	cmdline="foo gentoo=bar,baz quux"
 	set -- \
-		1  "${cmdline}"                   N/A \
-		1  "${cmdline}"                   '' \
-		1  "gentoo="                      '' \
-		1  "${cmdline}"                   foo \
-		0  "${cmdline}"                   bar \
-		0  "foo gentoo=gentoo=1,bar baz"  bar \
-		0  "foo gentoo=bar,gentoo=1 baz"  bar \
-		0  "${cmdline}"                   baz \
-		1  "${cmdline}"                   bar,baz \
-		0  "foo gentoo=bar,gentoo=1 baz"  gentoo=1 \
-		0  "foo gentoo=gentoo=1,bar baz"  gentoo=1 \
-		1  "${cmdline}"                   quux
+		ge  1  "${cmdline}"                   N/A \
+		ge  1  "${cmdline}"                   '' \
+		ge  1  "gentoo="                      '' \
+		ge  1  "${cmdline}"                   foo \
+		eq  0  "${cmdline}"                   bar \
+		eq  0  "foo gentoo=gentoo=1,bar baz"  bar \
+		eq  0  "foo gentoo=bar,gentoo=1 baz"  bar \
+		eq  0  "${cmdline}"                   baz \
+		ge  1  "${cmdline}"                   bar,baz \
+		eq  0  "foo gentoo=bar,gentoo=1 baz"  gentoo=1 \
+		eq  0  "foo gentoo=gentoo=1,bar baz"  gentoo=1 \
+		ge  1  "${cmdline}"                   quux
 
 	callback() {
 		cmdline=$2
@@ -210,16 +211,16 @@ test_get_bootparam() {
 		printf '%s\n' "${cmdline}" | get_bootparam "$@"
 	}
 
-	iterate_tests 3 "$@"
+	iterate_tests 4 "$@"
 }
 
 test_esyslog() {
 	set -- \
-		1  0  N/A    N/A   N/A \
-		1  0  debug  N/A   N/A \
-		0  0  debug  user  N/A \
-		0  0  debug  user  '' \
-		0  1  debug  user  message
+		ge  1  0  N/A    N/A   N/A \
+		ge  1  0  debug  N/A   N/A \
+		eq  0  0  debug  user  N/A \
+		eq  0  0  debug  user  '' \
+		eq  0  1  debug  user  message
 
 	logger() {
 		# esyslog() ignores empty messages. By overriding logger(1), it
@@ -242,54 +243,54 @@ test_esyslog() {
 		esac
 	}
 
-	iterate_tests 5 "$@"
+	iterate_tests 6 "$@"
 }
 
 test_is_identifier() {
 	set -- \
-		1   ''   \
-		1    _   \
-		1    0   \
-		1   0a   \
-		1   0Z   \
-		1    9   \
-		1   9a   \
-		1   9Z   \
-		1   /a   \
-		1   /Z   \
-		1   .a   \
-		1   .Z   \
-		1   [a   \
-		1   [Z   \
-		1  '`a'  \
-		1  '`Z'  \
-		1  '{a'  \
-		1  '{Z'  \
-		1  '|a'  \
-		1  '|Z'  \
-		1   a/   \
-		1   Z/   \
-		1   a.   \
-		1   Z.   \
-		1   a[   \
-		1   Z[   \
-		1  'a`'  \
-		1  'Z`'  \
-		1  'a{'  \
-		1  'Z{'  \
-		1  'a|'  \
-		1  'Z|'  \
-		0    a   \
-		0    Z   \
-		0   __   \
-		0   _a   \
-		0   _Z   \
-		0   a_   \
-		0   Z_   \
-		0  a_a   \
-		0  a_Z   \
-		0  Z_a   \
-		0  Z_Z
+		ge  1   ''   \
+		ge  1    _   \
+		ge  1    0   \
+		ge  1   0a   \
+		ge  1   0Z   \
+		ge  1    9   \
+		ge  1   9a   \
+		ge  1   9Z   \
+		ge  1   /a   \
+		ge  1   /Z   \
+		ge  1   .a   \
+		ge  1   .Z   \
+		ge  1  '[a'   \
+		ge  1  '[Z'  \
+		ge  1  '`a'  \
+		ge  1  '`Z'  \
+		ge  1  '{a'  \
+		ge  1  '{Z'  \
+		ge  1  '|a'  \
+		ge  1  '|Z'  \
+		ge  1   a/   \
+		ge  1   Z/   \
+		ge  1   a.   \
+		ge  1   Z.   \
+		ge  1  'a['  \
+		ge  1  'Z['  \
+		ge  1  'a`'  \
+		ge  1  'Z`'  \
+		ge  1  'a{'  \
+		ge  1  'Z{'  \
+		ge  1  'a|'  \
+		ge  1  'Z|'  \
+		eq  0    a   \
+		eq  0    Z   \
+		eq  0   __   \
+		eq  0   _a   \
+		eq  0   _Z   \
+		eq  0   a_   \
+		eq  0   Z_   \
+		eq  0  a_a   \
+		eq  0  a_Z   \
+		eq  0  Z_a   \
+		eq  0  Z_Z
 
 		callback() {
 			shift
@@ -297,24 +298,24 @@ test_is_identifier() {
 			is_identifier "$@"
 		}
 
-		iterate_tests 2 "$@"
+		iterate_tests 3 "$@"
 }
 
 test_is_int() {
 	set -- \
-		1  N/A \
-		1  ' ' \
-		1  ' 1 ' \
-		1  '' \
-		1  +1 \
-		1  +008 \
-		1  -008 \
-		1  008 \
-		1  x \
-		0  0 \
-		0  1 \
-		0  -1 \
-		0  123456789
+		ge  1  N/A \
+		ge  1  ' ' \
+		ge  1  ' 1 ' \
+		ge  1  '' \
+		ge  1  +1 \
+		ge  1  +008 \
+		ge  1  -008 \
+		ge  1  008 \
+		ge  1  x \
+		eq  0  0 \
+		eq  0  1 \
+		eq  0  -1 \
+		eq  0  123456789
 
 		callback() {
 			shift
@@ -322,19 +323,19 @@ test_is_int() {
 			is_int "$@"
 		}
 
-		iterate_tests 2 "$@"
+		iterate_tests 3 "$@"
 }
 
 test_is_visible() {
 	set -- \
-		1  '' \
-		1  ' ' \
-		1  "$(printf '\t')" \
-		1  "$(printf '\a')" \
-		0  . \
-		0  ' . ' \
-		0  "$(printf '\t.\t')" \
-		0  "$(printf '\a.\a')"
+		ge  1  '' \
+		ge  1  ' ' \
+		ge  1  "$(printf '\t')" \
+		ge  1  "$(printf '\a')" \
+		eq  0  . \
+		eq  0  ' . ' \
+		eq  0  "$(printf '\t.\t')" \
+		eq  0  "$(printf '\a.\a')"
 
 		callback() {
 			shift
@@ -342,35 +343,35 @@ test_is_visible() {
 			_is_visible "$@"
 		}
 
-		iterate_tests 2 "$@"
+		iterate_tests 3 "$@"
 }
 
 test_yesno() {
 	set -- \
-		0  yes \
-		0  YES \
-		0  Yes \
-		0  true \
-		0  TRUE \
-		0  true \
-		0  on \
-		0  ON \
-		0  On \
-		0  1 \
-		1  no \
-		1  NO \
-		1  No \
-		1  false \
-		1  FALSE \
-		1  False \
-		1  off \
-		1  OFF \
-		1  Off \
-		1  0 \
-		1  not_a_nameref \
-		1  not-a-valid-nameref \
-		1  '_"; set -- yes # code injection' \
-		0  truthful_nameref
+		eq  0  yes \
+		eq  0  YES \
+		eq  0  Yes \
+		eq  0  true \
+		eq  0  TRUE \
+		eq  0  true \
+		eq  0  on \
+		eq  0  ON \
+		eq  0  On \
+		eq  0  1 \
+		ge  1  no \
+		ge  1  NO \
+		ge  1  No \
+		ge  1  false \
+		ge  1  FALSE \
+		ge  1  False \
+		ge  1  off \
+		ge  1  OFF \
+		ge  1  Off \
+		ge  1  0 \
+		ge  1  not_a_nameref \
+		ge  1  not-a-valid-nameref \
+		ge  1  '_"; set -- yes # code injection' \
+		eq  0  truthful_nameref
 
 		# shellcheck disable=2034
 		truthful_nameref=yes
@@ -381,7 +382,7 @@ test_yesno() {
 			yesno "$@"
 		}
 
-		iterate_tests 2 "$@"
+		iterate_tests 3 "$@"
 }
 
 iterate_tests() {
@@ -393,7 +394,7 @@ iterate_tests() {
 	i=0
 	while [ "$((i += 1))" -le "${total}" ]; do
 		code="callback"
-		j=0
+		j=1
 		while [ "$((j += 1))" -le "${slice_width}" ]; do
 			if eval "[ \"\$${j}\" = N/A ]"; then
 				break
@@ -402,12 +403,14 @@ iterate_tests() {
 			fi
 		done
 		eval "${code}"
-		if [ "$?" -eq "$1" ]; then
+		retval=$?
+		if [ "${retval}" -"$1" "$2" ]; then
 			passed=$((passed + 1))
 		else
 			printf 'not '
 		fi
-		printf 'ok %d - %s (expecting %s)\n' "$((testnum += 1))" "${test_description}" "$1"
+		printf 'ok %d - %s (test %d -%s %d)\n' \
+			"$((testnum += 1))" "${test_description}" "${retval}" "$1" "$2"
 		shift "${slice_width}"
 	done
 	return "$(( passed < total ))"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 14:04 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 14:04 UTC (permalink / raw
  To: gentoo-commits

commit:     61e6f15aab5524331946d5172fcd73d30c3c16f0
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat May 18 10:26:00 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 11:28:43 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=61e6f15a

Add an eqawarn() function

In portage's isolated-functions, eqawarn() prints a warning with the
asterisk in dark yellow as opposed to bright yellow. To my mind, this
does not merit yet another cookier-cutter function in gentoo-functions.
So, for now, implement it as an ewarn() wrapper.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Bug: https://bugs.gentoo.org/878505

 functions.sh | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/functions.sh b/functions.sh
index dd5bb76..2efcf1f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -160,6 +160,15 @@ eoutdent()
 	_esetdent "$(( ${#genfun_indent} - $1 ))"
 }
 
+#
+# Prints a QA warning message, provided that EINFO_QUIET is false. If printed,
+# the message shall also be conveyed to the esyslog function. For now, this is
+# implemented merely as an ewarn wrapper.
+#
+eqawarn() {
+	ewarn "$@"
+}
+
 #
 # Invokes the logger(1) utility, provided that EINFO_LOG is true. The first
 # parameter shall be taken as a priority level, the second as the message tag,


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-18 14:04 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-18 14:04 UTC (permalink / raw
  To: gentoo-commits

commit:     895bd87dc035ace26aefb460ee0a192da6c9521e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat May 18 10:20:06 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 18 10:20:06 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=895bd87d

test-functions: Use test rather than [ to placate shellcheck

Also, fix an accidental - though ultimately harmless - case of SC2027.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test-functions b/test-functions
index 4360eb2..d46546a 100755
--- a/test-functions
+++ b/test-functions
@@ -77,7 +77,7 @@ test_die() {
 		eq  255  255
 
 	callback() {
-		test_description="( exit "$2" ); die"
+		test_description="( exit $2 ); die"
 		( exit "$2" )
 		stderr=$(die "$2" 2>&1)
 		retval=$?
@@ -404,7 +404,7 @@ iterate_tests() {
 		done
 		eval "${code}"
 		retval=$?
-		if [ "${retval}" -"$1" "$2" ]; then
+		if test "${retval}" -"$1" "$2"; then
 			passed=$((passed + 1))
 		else
 			printf 'not '


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     1bd941e3de386fd04e23b23407d213868920dbd3
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 06:20:02 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri May 17 01:40:19 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1bd941e3

Make _eend() much faster in bash

This is accomplished by instead invoking the true binary and taking a
reading of the COLUMNS variable. However, this is only done in
situations where it can be expected to be reliable. Even as of
bash 5.3-alpha, the checkwinsize feature does not work reliably in a
subshell.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/functions.sh b/functions.sh
index 57f6aa2..1f547d0 100644
--- a/functions.sh
+++ b/functions.sh
@@ -469,14 +469,20 @@ _is_visible()
 #
 _update_columns()
 {
-	local ifs
-
-	# The following use of stty(1) is portable as of POSIX Issue 8.
-	ifs=$IFS
-	IFS=' '
-	# shellcheck disable=2046
-	set -- $(stty size 2>/dev/null)
-	IFS=$ifs
+	# Command substitutions are rather slow in bash. Using the COLUMNS
+	# variable helps but checkwinsize won't work properly in subshells.
+	# shellcheck disable=3028,3044
+	if [ "$$" = "${BASHPID}" ] && shopt -q checkwinsize; then
+		"${genfun_bin_true}"
+		set -- 0 "${COLUMNS}"
+	else
+		# The following use of stty(1) is portable as of POSIX Issue 8.
+		genfun_ifs=${IFS}
+		IFS=' '
+		# shellcheck disable=2046
+		set -- $(stty size 2>/dev/null)
+		IFS=${genfun_ifs}
+	fi
 	[ "$#" -eq 2 ] && is_int "$2" && [ "$2" -gt 0 ] && genfun_cols=$2
 }
 
@@ -515,6 +521,12 @@ else
 	genfun_offset=0
 fi
 
+# Store the path to the true binary. It is potentially used by _update_columns.
+if [ "${BASH}" ]; then
+	# shellcheck disable=3045
+	genfun_bin_true=$(type -P true)
+fi
+
 # Determine whether the use of color is to be wilfully avoided.
 if [ -n "${NO_COLOR}" ]; then
 	# See https://no-color.org/.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     e4eab7040c9b36f5ebfc9eb0880cfd39735e4a85
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 01:51:13 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu May 16 01:53:05 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=e4eab704

Declare some of the v-prefixed functions dynamically

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 62 ++++++++++++++----------------------------------------------
 1 file changed, 14 insertions(+), 48 deletions(-)

diff --git a/functions.sh b/functions.sh
index 8561eb3..6647c67 100644
--- a/functions.sh
+++ b/functions.sh
@@ -272,12 +272,20 @@ is_older_than()
 	read -r _
 }
 
-vebegin()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		ebegin "$@"
-	fi
-}
+#
+#   Declare the vebegin, veerror, veindent, veinfo, veinfon, veoutdent and
+#   vewarn functions. These differ from their non-v-prefixed counterparts in
+#   that they only have an effect where EINFO_VERBOSE is set as a truthy value.
+#
+for _ in vebegin veerror veindent veinfo veinfon veoutdent vewarn; do
+	eval "
+		$_ () {
+			if yesno \"\${EINFO_VERBOSE}\"; then
+				${_#v} \"\$@\"
+			fi
+		}
+	"
+done
 
 veend()
 {
@@ -290,48 +298,6 @@ veend()
 	fi
 }
 
-veerror()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		eerror "$@"
-	fi
-}
-
-veindent()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		eindent "$@"
-	fi
-}
-
-veinfo()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		einfo "$@"
-	fi
-}
-
-veinfon()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		einfon "$@"
-	fi
-}
-
-veoutdent()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		eoutdent "$@"
-	fi
-}
-
-vewarn()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		ewarn "$@"
-	fi
-}
-
 vewend()
 {
 	if yesno "${EINFO_VERBOSE}"; then


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     e3f08cc9af0f8310ada80af54fbea9e69f70e39c
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 05:14:03 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu May 16 05:14:03 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=e3f08cc9

Don't call is_int() from _esetdent()

There is no need.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index bd97f7e..57f6aa2 100644
--- a/functions.sh
+++ b/functions.sh
@@ -423,7 +423,7 @@ _eprint()
 #
 _esetdent()
 {
-	if ! is_int "$1" || [ "$1" -lt 0 ]; then
+	if [ "$1" -lt 0 ]; then
 		set -- 0
 	fi
 	genfun_indent=$(printf "%${1}s" '')


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     2ba6c4f1f86ff15cf11fdb515a22989a3d16f5ab
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 12:32:50 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri May 17 01:40:20 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2ba6c4f1

Rename _has_monochrome_terminal() to _has_color_terminal()

This also inverts the sense of its exit status but it feels a little
more natural this way. Moreover, the behaviour now matches the
description of the function.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index e2af8cf..e494765 100644
--- a/functions.sh
+++ b/functions.sh
@@ -444,18 +444,18 @@ _has_dumb_terminal()
 #
 # Tries to determine whether the terminal supports ECMA-48 SGR color sequences.
 #
-_has_monochrome_terminal()
+_has_color_terminal()
 {
 	local colors
 
 	# The tput(1) invocation is not portable, though ncurses suffices. In
 	# this day and age, it is exceedingly unlikely that it will be needed.
 	if _has_dumb_terminal; then
-		true
+		false
 	elif colors=$(tput colors 2>/dev/null) && is_int "${colors}"; then
-		test "${colors}" -eq -1
+		test "${colors}" -gt 0
 	else
-		false
+		true
 	fi
 }
 
@@ -545,7 +545,7 @@ else
 	done
 fi
 
-if _has_monochrome_terminal || yesno "${RC_NOCOLOR}"; then
+if ! _has_color_terminal || yesno "${RC_NOCOLOR}"; then
 	unset -v BAD BRACKET GOOD HILITE NORMAL WARN
 else
 	# Define some ECMA-48 SGR sequences for color support. These variables


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     d3e39fba9cafdc78a92363702bcc117bf6c30a9e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 02:32:10 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu May 16 02:36:54 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d3e39fba

Declare eerror(), einfo() and ewarn() dynamically

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 30 +++++++++---------------------
 1 file changed, 9 insertions(+), 21 deletions(-)

diff --git a/functions.sh b/functions.sh
index dfbbe31..60fa2fa 100644
--- a/functions.sh
+++ b/functions.sh
@@ -56,12 +56,16 @@ eend()
 }
 
 #
-#    show an error message (with a newline) and log it
+#   Declare the eerror, einfo and ewarn functions. These wrap errorn, einfon and
+#   ewarnn respectively, the difference being that a newline is appended.
 #
-eerror()
-{
-	eerrorn "${*}${genfun_newline}"
-}
+for _ in eerror einfo ewarn; do
+	eval "
+		$_ () {
+			${_}n \"\${*}\${genfun_newline}\"
+		}
+	"
+done
 
 #
 #    show an error message (without a newline) and log it
@@ -86,14 +90,6 @@ eindent()
 	_esetdent "$(( ${#genfun_indent} + $1 ))"
 }
 
-#
-#    show an informative message (with a newline)
-#
-einfo()
-{
-	einfon "${*}${genfun_newline}"
-}
-
 #
 #    show an informative message (without a newline)
 #
@@ -138,14 +134,6 @@ esyslog()
 	fi
 }
 
-#
-#    show a warning message (with a newline) and log it
-#
-ewarn()
-{
-	ewarnn "${*}${genfun_newline}"
-}
-
 #
 #    show a warning message (without a newline) and log it
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     13e1d297905a7be552af2f4407da188c242e1efe
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 06:56:30 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri May 17 01:40:20 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=13e1d297

Tweak the comment style for yesno()

Following William's style because it remains the prevailing one.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/functions.sh b/functions.sh
index 1f547d0..9424660 100644
--- a/functions.sh
+++ b/functions.sh
@@ -307,6 +307,7 @@ vewend()
 	fi
 }
 
+#
 # Determines whether the first parameter is truthy. The values taken to be true
 # are "yes", "true", "on" and "1", whereas their opposites are taken to be
 # false. The empty string is also taken to be false. All pattern matching is


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     6761163b5c8667a1a111683f5bf72e5dff4e604e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 12:55:08 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri May 17 01:40:20 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6761163b

Add a die() function

For now, it will only be defined if no utility, function or alias
already exists by that name. Like the exit builtin, it is able to
preserve the value of $? but will never exit with a status of 0. For
example, the following will preserve the exit status of failing_command.

failing_command || die "gadzooks"

Whereas the following will ignore the value of $? - being that it is 0 -
and instead exit with a status of 1.

if prevailing_command; then
	die "fiddlesticks"
fi

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Bug: https://bugs.gentoo.org/878505

 functions.sh   | 20 ++++++++++++++++++++
 test-functions | 39 +++++++++++++++++++++++++--------------
 2 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/functions.sh b/functions.sh
index e494765..b0170f9 100644
--- a/functions.sh
+++ b/functions.sh
@@ -30,6 +30,26 @@ chdir()
 	CDPATH= cd -- "$@"
 }
 
+#
+# Prints a diagnostic message prefixed with the basename of the running script
+# before exiting. It shall preserve the value of $? as it was at the time of
+# invocation unless its value was 0, in which case the exit status shall be 1.
+#
+if ! command -v die >/dev/null; then
+	die()
+	{
+		case $? in
+			0)
+				genfun_status=1
+				;;
+			*)
+				genfun_status=$?
+		esac
+		printf '%s: %s\n' "${0##*/}" "$*" >&2
+		exit "${genfun_status}"
+	}
+fi
+
 #
 # Prints a message indicating the onset of a given process, provided that
 # EINFO_QUIET is false. It is expected that eend eventually be called, so as to

diff --git a/test-functions b/test-functions
index a2d15b4..e087a3c 100755
--- a/test-functions
+++ b/test-functions
@@ -68,6 +68,28 @@ test_chdir_noop() {
 	iterate_tests 2 "$@"
 }
 
+test_die() {
+	set -- \
+		1     0 \
+		2     2 \
+		126 126 \
+		255 255
+
+	callback() {
+		test_description="( exit "$2" ); die"
+		( exit "$2" )
+		stderr=$(die "$2" 2>&1)
+		retval=$?
+		if [ "${stderr}" = "test-functions: $2" ]; then
+			return "${retval}"
+		else
+			return 1
+		fi
+	}
+
+	iterate_tests 2 "$@"
+}
+
 test_ebegin() {
 	_eprint() {
 		shift
@@ -380,24 +402,12 @@ iterate_tests() {
 			fi
 		done
 		eval "${code}"
-		case $? in
-			0)
-				test "$?" -eq "$1"
-				;;
-			*)
-				test "$?" -ge "$1"
-		esac
-		if [ "$?" -eq 0 ]; then
+		if [ "$?" -eq "$1" ]; then
 			passed=$((passed + 1))
 		else
 			printf 'not '
 		fi
-		if [ "$1" -eq 0 ]; then
-			expected=$1
-		else
-			expected=">=$1"
-		fi
-		printf 'ok %d - %s (expecting %s)\n' "$((testnum += 1))" "${test_description}" "${expected}"
+		printf 'ok %d - %s (expecting %s)\n' "$((testnum += 1))" "${test_description}" "$1"
 		shift "${slice_width}"
 	done
 	return "$(( passed < total ))"
@@ -445,6 +455,7 @@ test_is_identifier || rc=1
 test_is_int || rc=1
 test_is_visible || rc=1
 test_yesno || rc=1
+test_die || rc=1
 
 cleanup_tmpdir
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     57f643e81c8bd8ab5d428aa5770c3a8097a456a2
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri May 17 01:21:15 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri May 17 02:17:13 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=57f643e8

Document variables influencing runtime behaviour

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index b0170f9..dd5bb76 100644
--- a/functions.sh
+++ b/functions.sh
@@ -3,12 +3,30 @@
 # shellcheck shell=sh disable=3043
 
 # This file contains a series of function declarations followed by some
-# initialization code. Functions intended for internal use shall be prefixed
+# initialisation code. Functions intended for internal use shall be prefixed
 # with an <underscore> and shall not be considered as being a part of the public
 # API. With the exception of those declared by the local builtin, all variables
 # intended for internal use shall be prefixed with "genfun_" to indicate so,
 # and to reduce the probability of name space conflicts.
 
+# The following variables affect initialisation and/or function behaviour.
+
+# BASH          : whether bash-specific features may be employed
+# BASHPID       : potentially used by _update_columns() to detect subshells
+# COLUMNS       : potentially used by _update_columns() to get the column count
+# EERROR_QUIET  : whether error printing functions should be silenced
+# EINFO_LOG     : whether printing functions should call esyslog()
+# EINFO_QUIET   : whether info message printing functions should be silenced
+# EINFO_VERBOSE : whether v-prefixed functions should do anything
+# IFS           : multiple message operands are joined by its first character
+# INSIDE_EMACS  : whether to work around an emacs-specific bug in _eend()
+# NO_COLOR      : whether colored output should be suppressed
+# RC_NOCOLOR    : like NO_COLOR but deprecated
+# TEST_GENFUNCS : used for testing the behaviour of get_bootparam()
+# TERM          : may influence message formatting and whether color is used
+
+################################################################################
+
 #
 # A safe wrapper for the cd builtin. To run cd "$dir" is problematic because:
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     83a380418dd6b669e633074def33edc370978b01
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 02:15:15 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu May 16 02:34:10 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=83a38041

Remove some superfluous boolean variable declarations

Remove the superfluous declarations of EINFO_QUIET, EINFO_VERBOSE,
RC_NOCOLOR and genfun_indent. No attempt has been made to appease the
nounset cultists because it was already the case that gentoo-functions
be incompatible with it. Should push come to shove, nounset could be
accommodated but such a requirement ought then to be attended to in its
own right.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/functions.sh b/functions.sh
index 6647c67..dfbbe31 100644
--- a/functions.sh
+++ b/functions.sh
@@ -488,14 +488,7 @@ _update_tty_level()
 
 # This is the main script, please add all functions above this point!
 # shellcheck disable=2034
-RC_GOT_FUNCTIONS="yes"
-
-# Dont output to stdout?
-EINFO_QUIET="${EINFO_QUIET:-no}"
-EINFO_VERBOSE="${EINFO_VERBOSE:-no}"
-
-# Set the initial value for e-message indentation.
-genfun_indent=
+RC_GOT_FUNCTIONS=yes
 
 # Assign the LF ('\n') character for later expansion. POSIX Issue 8 permits
 # $'\n' but it may take years for it to be commonly implemented.
@@ -513,13 +506,12 @@ fi
 # Should we use color?
 if [ -n "${NO_COLOR}" ]; then
 	# See https://no-color.org/.
-	RC_NOCOLOR="yes"
+	RC_NOCOLOR=yes
 else
-	RC_NOCOLOR="${RC_NOCOLOR:-no}"
 	for _ in "$@"; do
 		case $_ in
 			--nocolor|--nocolour|-C)
-				RC_NOCOLOR="yes"
+				RC_NOCOLOR=yes
 				break
 		esac
 	done


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     4f6bbc44f0a0264e0a1d1d034dad863a69ce1f07
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 05:04:32 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu May 16 05:08:50 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=4f6bbc44

Improve the comments

Also, add comments for several functions that did not have any.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 125 +++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 75 insertions(+), 50 deletions(-)

diff --git a/functions.sh b/functions.sh
index 60fa2fa..050a1d8 100644
--- a/functions.sh
+++ b/functions.sh
@@ -10,12 +10,12 @@
 # and to reduce the probability of name space conflicts.
 
 #
-#   A safe wrapper for the cd builtin. To run cd "$dir" is problematic because:
+# A safe wrapper for the cd builtin. To run cd "$dir" is problematic because:
 #
-#   1) it may consider its operand as an option
-#   2) it will search CDPATH for an operand not beginning with ./, ../ or /
-#   3) it will switch to OLDPWD if the operand is -
-#   4) cdable_vars causes bash to treat the operand as a potential variable name
+# - it may consider its operand as an option
+# - it will search CDPATH for an operand not beginning with ./, ../ or /
+# - it will switch to OLDPWD if the operand is -
+# - cdable_vars causes bash to treat the operand as a potential variable name
 #
 chdir()
 {
@@ -31,7 +31,9 @@ chdir()
 }
 
 #
-#    show a message indicating the start of a process
+# Prints a message indicating the onset of a given process, provided that
+# EINFO_QUIET is false. It is expected that eend eventually be called, so as to
+# indicate whether the process completed successfully or not.
 #
 ebegin()
 {
@@ -47,8 +49,12 @@ ebegin()
 }
 
 #
-#    indicate the completion of process
-#    if error, show errstr via eerror
+# Prints an indicator to convey the completion of a given process, provided that
+# EINFO_QUIET is false. It is expected that it be paired with an earlier call to
+# ebegin. The first parameter shall be taken as an exit status value, making it
+# possible to distinguish between success and failure. If unspecified, it shall
+# default to 0. The remaining parameters, if any, shall be taken as a diagnostic
+# message to convey as an error where the exit status is not 0.
 #
 eend()
 {
@@ -56,8 +62,8 @@ eend()
 }
 
 #
-#   Declare the eerror, einfo and ewarn functions. These wrap errorn, einfon and
-#   ewarnn respectively, the difference being that a newline is appended.
+# Declare the eerror, einfo and ewarn functions. These wrap errorn, einfon and
+# ewarnn respectively, the difference being that a newline is appended.
 #
 for _ in eerror einfo ewarn; do
 	eval "
@@ -68,7 +74,8 @@ for _ in eerror einfo ewarn; do
 done
 
 #
-#    show an error message (without a newline) and log it
+# Prints an error message without appending a newline, while also conveying it
+# to the esyslog function.
 #
 eerrorn()
 {
@@ -80,7 +87,8 @@ eerrorn()
 }
 
 #
-#    increase the indent used for e-commands.
+# Decreases the level of indentation used by various printing functions. If no
+# numerical parameter is given, or if it is negative, increase by 2 spaces.
 #
 eindent()
 {
@@ -91,7 +99,8 @@ eindent()
 }
 
 #
-#    show an informative message (without a newline)
+# Prints an informational message without appending a newline, provided that
+# EINFO_QUIET is false.
 #
 einfon()
 {
@@ -101,7 +110,8 @@ einfon()
 }
 
 #
-#    decrease the indent used for e-commands.
+# Decreases the level of indentation used by various printing functions. If no
+# numerical parameter is given, or if it is negative, decrease by 2 spaces.
 #
 eoutdent()
 {
@@ -112,7 +122,8 @@ eoutdent()
 }
 
 #
-#    use the system logger to log a message
+# Invokes logger(1) to log the given message, provided that EINFO_LOG is set as
+# a non-empty value.
 #
 esyslog()
 {
@@ -135,7 +146,9 @@ esyslog()
 }
 
 #
-#    show a warning message (without a newline) and log it
+# Prints a warning message without appending a newline, provided that
+# EINFO_QUIET is false. If printed, the message shall also be conveyed to the
+# esyslog function.
 #
 ewarnn()
 {
@@ -146,8 +159,8 @@ ewarnn()
 }
 
 #
-#    indicate the completion of process
-#    if error, show errstr via ewarn
+# This behaves as the eend function does, except that the given diagnostic
+# message shall be presented as a warning rather than an error.
 #
 ewend()
 {
@@ -155,9 +168,8 @@ ewend()
 }
 
 #
-#   return 0 if gentoo=param was passed to the kernel
-#
-#   EXAMPLE:  if get_bootparam "nodevfs" ; then ....
+# Determines whether the kernel cmdline contains the specified parameter as a
+# component of a comma-separated list specified in the format of gentoo=<list>.
 #
 get_bootparam()
 (
@@ -191,7 +203,7 @@ get_bootparam()
 )
 
 #
-#   Determine whether the first operand is a valid identifier (variable name).
+# Determines whether the first parameter is a valid identifier (variable name).
 #
 is_identifier()
 (
@@ -202,10 +214,10 @@ is_identifier()
 )
 
 #
-#   Determine whether the first operand is in the form of an integer. A leading
-#   <hypen-minus> shall be permitted. Thereafter, leading zeroes shall not be
-#   permitted because the string might later be considered to be octal in an
-#   arithmetic context, causing the shell to exit if the number be invalid.
+# Determines whether the first parameter is a valid integer. A leading
+# <hypen-minus> shall be permitted. Thereafter, leading zeroes shall not be
+# permitted because the string might later be considered to be octal in an
+# arithmetic context, causing the shell to exit if the number be invalid.
 #
 is_int()
 {
@@ -223,10 +235,9 @@ is_int()
 }
 
 #
-#   return 0 if any of the files/dirs are newer than
-#   the reference file
+# Takes the first parameter as a reference file/directory then determines
+# whether any of the following parameters refer to newer files/directories.
 #
-#   EXAMPLE: if is_older_than a.out *.o ; then ...
 is_older_than()
 {
 	local ref has_gfind
@@ -261,9 +272,9 @@ is_older_than()
 }
 
 #
-#   Declare the vebegin, veerror, veindent, veinfo, veinfon, veoutdent and
-#   vewarn functions. These differ from their non-v-prefixed counterparts in
-#   that they only have an effect where EINFO_VERBOSE is set as a truthy value.
+# Declare the vebegin, veerror, veindent, veinfo, veinfon, veoutdent and vewarn
+# functions. These differ from their non-v-prefixed counterparts in that they
+# only print where EINFO_VERBOSE is true.
 #
 for _ in vebegin veerror veindent veinfo veinfon veoutdent vewarn; do
 	eval "
@@ -297,10 +308,10 @@ vewend()
 	fi
 }
 
-#
-# this function was lifted from OpenRC. It returns 0 if the argument  or
-# the value of the argument is "yes", "true", "on", or "1" or 1
-# otherwise.
+# Determines whether the first parameter is truthy. The values taken to be true
+# are "yes", "true", "on" and "1", whereas their opposites are taken to be
+# false. The empty string is also taken to be false. All pattern matching is
+# performed case-insensitively.
 #
 yesno()
 {
@@ -324,8 +335,8 @@ yesno()
 }
 
 #
-#    indicate the completion of process, called from eend/ewend
-#    if error, show errstr via efunc
+# Called by eend, ewend, veend and vewend. See the definition of eend for an
+# overall description of its purpose.
 #
 _eend()
 {
@@ -381,6 +392,9 @@ _eend()
 	return "${retval}"
 }
 
+#
+# Determines whether the given string is newline-terminated.
+#
 _ends_with_newline()
 {
 	test "${genfun_newline}" \
@@ -388,7 +402,7 @@ _ends_with_newline()
 }
 
 #
-#    Called by ebegin, eerrorn, einfon, and ewarnn.
+# Called by ebegin, eerrorn, einfon, and ewarnn.
 #
 _eprint()
 {
@@ -405,8 +419,8 @@ _eprint()
 }
 
 #
-#    hard set the indent used for e-commands.
-#    num defaults to 0
+# Called by eindent, eoutdent, veindent and veoutdent. It is here that the
+# variable containing the horizontal whitespace is updated.
 #
 _esetdent()
 {
@@ -416,11 +430,17 @@ _esetdent()
 	genfun_indent=$(printf "%${1}s" '')
 }
 
+#
+# Determines whether the terminal is a dumb one.
+#
 _has_dumb_terminal()
 {
 	! case ${TERM} in *dumb*) false ;; esac
 }
 
+#
+# Tries to determine whether the terminal supports ECMA-48 SGR color sequences.
+#
 _has_monochrome_terminal()
 {
 	local colors
@@ -437,13 +457,17 @@ _has_monochrome_terminal()
 }
 
 #
-#   Determine whether the first operand contains any visible characters.
+# Determines whether the first parameter contains any visible characters.
 #
 _is_visible()
 {
 	! case $1 in *[[:graph:]]*) false ;; esac
 }
 
+#
+# Determines whether the terminal on STDIN is able to report its dimensions.
+# Upon success, the number of columns shall be stored.
+#
 _update_columns()
 {
 	local ifs
@@ -457,14 +481,15 @@ _update_columns()
 	[ "$#" -eq 2 ] && is_int "$2" && [ "$2" -gt 0 ] && genfun_cols=$2
 }
 
+#
+# Grades the capability of the terminal attached to STDIN, assigning the level
+# to genfun_tty. If no terminal is detected, the level shall be 0. If a dumb
+# terminal is detected, the level shall be 1. If a smart terminal is detected,
+# the level shall be 2. For a terminal to be considered as smart, it must be
+# able to successfully report its dimensions.
+#
 _update_tty_level()
 {
-	# Grade the capability of the terminal attached to STDIN (if any) on a
-	# scale of 0 to 2, assigning the resulting value to genfun_tty. If no
-	# terminal is detected, the value shall be 0. If a dumb terminal is
-	# detected, the value shall be 1. If a smart terminal is detected, the
-	# value shall be 2. For a terminal to be considered as smart, it must be
-	# able to successfully report its dimensions.
 	if [ ! -t 0 ]; then
 		genfun_tty=0
 	elif _has_dumb_terminal || ! _update_columns; then
@@ -474,7 +499,7 @@ _update_tty_level()
 	fi
 }
 
-# This is the main script, please add all functions above this point!
+# All function declarations end here! Initialisation code only from hereon.
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS=yes
 
@@ -491,7 +516,7 @@ else
 	genfun_offset=0
 fi
 
-# Should we use color?
+# Determine whether the use of color is to be wilfully avoided.
 if [ -n "${NO_COLOR}" ]; then
 	# See https://no-color.org/.
 	RC_NOCOLOR=yes


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     0dd8364c03c6f8737150ee4f146ddeeec57efee9
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 05:11:16 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu May 16 05:11:16 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=0dd8364c

Have esyslog() check that EINFO_LOG is true instead of non-empty

It makes no sense for EINFO_LOG to be exceptional.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/functions.sh b/functions.sh
index 050a1d8..bd97f7e 100644
--- a/functions.sh
+++ b/functions.sh
@@ -122,8 +122,7 @@ eoutdent()
 }
 
 #
-# Invokes logger(1) to log the given message, provided that EINFO_LOG is set as
-# a non-empty value.
+# Invokes logger(1) to log the given message, provided that EINFO_LOG is true.
 #
 esyslog()
 {
@@ -132,7 +131,7 @@ esyslog()
 	if [ "$#" -lt 2 ]; then
 		ewarn "Too few arguments for esyslog (got $#, expected at least 2)"
 		return 1
-	elif [ -n "${EINFO_LOG}" ] && hash logger 2>/dev/null; then
+	elif yesno "${EINFO_LOG}" && hash logger 2>/dev/null; then
 		pri=$1
 		tag=$2
 		shift 2


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     36d3b72507a6142d9453a55dbcc6ca038768f3f5
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 12:22:51 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri May 17 01:40:20 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=36d3b725

More comment improvements

Render the descriptions of eerrorn(), esyslog(), _update_columns() and
the v-prefixed functions more accurate.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index 9424660..e2af8cf 100644
--- a/functions.sh
+++ b/functions.sh
@@ -74,8 +74,9 @@ for _ in eerror einfo ewarn; do
 done
 
 #
-# Prints an error message without appending a newline, while also conveying it
-# to the esyslog function.
+# Prints an error message without appending a newline, provided that
+# EERROR_QUIET is false. If printed, the message shall also be conveyed to the
+# esyslog function.
 #
 eerrorn()
 {
@@ -122,7 +123,9 @@ eoutdent()
 }
 
 #
-# Invokes logger(1) to log the given message, provided that EINFO_LOG is true.
+# Invokes the logger(1) utility, provided that EINFO_LOG is true. The first
+# parameter shall be taken as a priority level, the second as the message tag,
+# and the remaining parameters as the message to be logged.
 #
 esyslog()
 {
@@ -273,7 +276,7 @@ is_older_than()
 #
 # Declare the vebegin, veerror, veindent, veinfo, veinfon, veoutdent and vewarn
 # functions. These differ from their non-v-prefixed counterparts in that they
-# only print where EINFO_VERBOSE is true.
+# only have an effect where EINFO_VERBOSE is true.
 #
 for _ in vebegin veerror veindent veinfo veinfon veoutdent vewarn; do
 	eval "
@@ -466,7 +469,7 @@ _is_visible()
 
 #
 # Determines whether the terminal on STDIN is able to report its dimensions.
-# Upon success, the number of columns shall be stored.
+# Upon success, the number of columns shall be stored in genfun_cols.
 #
 _update_columns()
 {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-17  4:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-17  4:03 UTC (permalink / raw
  To: gentoo-commits

commit:     50ce35639679a07286dff5a409df6d44a6d9166c
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu May 16 01:38:31 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu May 16 01:38:31 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=50ce3563

Reorganise the order in which functions are declared

Sort by alphabetical order, grouped by public then private scope.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh | 598 +++++++++++++++++++++++++++++------------------------------
 1 file changed, 298 insertions(+), 300 deletions(-)

diff --git a/functions.sh b/functions.sh
index 7bd4b11..8561eb3 100644
--- a/functions.sh
+++ b/functions.sh
@@ -10,32 +10,69 @@
 # and to reduce the probability of name space conflicts.
 
 #
-#    Called by ebegin, eerrorn, einfon, and ewarnn.
+#   A safe wrapper for the cd builtin. To run cd "$dir" is problematic because:
 #
-_eprint()
+#   1) it may consider its operand as an option
+#   2) it will search CDPATH for an operand not beginning with ./, ../ or /
+#   3) it will switch to OLDPWD if the operand is -
+#   4) cdable_vars causes bash to treat the operand as a potential variable name
+#
+chdir()
 {
-	local color
+	if [ "$BASH" ]; then
+		# shellcheck disable=3044
+		shopt -u cdable_vars
+	fi
+	if [ "$1" = - ]; then
+		set -- ./-
+	fi
+	# shellcheck disable=1007,2164
+	CDPATH= cd -- "$@"
+}
 
-	color=$1
-	shift
+#
+#    show a message indicating the start of a process
+#
+ebegin()
+{
+	local msg
 
-	if [ -t 1 ]; then
-		printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "$*"
-	else
-		printf ' * %s%s' "${genfun_indent}" "$*"
+	if ! yesno "${EINFO_QUIET}"; then
+		msg=$*
+		while _ends_with_newline "${msg}"; do
+			msg=${msg%"${genfun_newline}"}
+		done
+		_eprint "${GOOD}" "${msg} ...${genfun_newline}"
 	fi
 }
 
 #
-#    hard set the indent used for e-commands.
-#    num defaults to 0
+#    indicate the completion of process
+#    if error, show errstr via eerror
 #
-_esetdent()
+eend()
 {
-	if ! is_int "$1" || [ "$1" -lt 0 ]; then
-		set -- 0
+	GENFUN_CALLER=${GENFUN_CALLER:-eend} _eend eerror "$@"
+}
+
+#
+#    show an error message (with a newline) and log it
+#
+eerror()
+{
+	eerrorn "${*}${genfun_newline}"
+}
+
+#
+#    show an error message (without a newline) and log it
+#
+eerrorn()
+{
+	if ! yesno "${EERROR_QUIET}"; then
+		_eprint "${BAD}" "$@" >&2
+		esyslog "daemon.err" "${0##*/}" "$@"
 	fi
-	genfun_indent=$(printf "%${1}s" '')
+	return 1
 }
 
 #
@@ -50,40 +87,32 @@ eindent()
 }
 
 #
-#    decrease the indent used for e-commands.
+#    show an informative message (with a newline)
 #
-eoutdent()
+einfo()
 {
-	if ! is_int "$1" || [ "$1" -le 0 ]; then
-		set -- 2
+	einfon "${*}${genfun_newline}"
+}
+
+#
+#    show an informative message (without a newline)
+#
+einfon()
+{
+	if ! yesno "${EINFO_QUIET}"; then
+		_eprint "${GOOD}" "$@"
 	fi
-	_esetdent "$(( ${#genfun_indent} - $1 ))"
 }
 
 #
-# this function was lifted from OpenRC. It returns 0 if the argument  or
-# the value of the argument is "yes", "true", "on", or "1" or 1
-# otherwise.
+#    decrease the indent used for e-commands.
 #
-yesno()
+eoutdent()
 {
-	for _ in 1 2; do
-		case $1 in
-			[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0|'')
-				return 1
-				;;
-			[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
-				return 0
-		esac
-		if [ "$_" -ne 1 ] || ! is_identifier "$1"; then
-			! break
-		else
-			# The value appears to be a legal variable name. Treat
-			# it as a name reference and try again, once only.
-			eval "set -- \"\$$1\""
-		fi
-	done || vewarn "Invalid argument given to yesno (expected a boolean-like or a legal name)"
-	return 1
+	if ! is_int "$1" || [ "$1" -le 0 ]; then
+		set -- 2
+	fi
+	_esetdent "$(( ${#genfun_indent} - $1 ))"
 }
 
 #
@@ -110,21 +139,11 @@ esyslog()
 }
 
 #
-#    show an informative message (without a newline)
-#
-einfon()
-{
-	if ! yesno "${EINFO_QUIET}"; then
-		_eprint "${GOOD}" "$@"
-	fi
-}
-
-#
-#    show an informative message (with a newline)
+#    show a warning message (with a newline) and log it
 #
-einfo()
+ewarn()
 {
-	einfon "${*}${genfun_newline}"
+	ewarnn "${*}${genfun_newline}"
 }
 
 #
@@ -139,49 +158,217 @@ ewarnn()
 }
 
 #
-#    show a warning message (with a newline) and log it
+#    indicate the completion of process
+#    if error, show errstr via ewarn
 #
-ewarn()
+ewend()
 {
-	ewarnn "${*}${genfun_newline}"
+	GENFUN_CALLER=${GENFUN_CALLER:-ewend} _eend ewarn "$@"
 }
 
 #
-#    show an error message (without a newline) and log it
+#   return 0 if gentoo=param was passed to the kernel
 #
-eerrorn()
-{
-	if ! yesno "${EERROR_QUIET}"; then
-		_eprint "${BAD}" "$@" >&2
-		esyslog "daemon.err" "${0##*/}" "$@"
-	fi
+#   EXAMPLE:  if get_bootparam "nodevfs" ; then ....
+#
+get_bootparam()
+(
+	# Gentoo cmdline parameters are comma-delimited, so a search
+	# string containing a comma must not be allowed to match.
+	# Similarly, the empty string must not be allowed to match.
+	case $1 in ''|*,*) return 1 ;; esac
+
+	# Reset the value of IFS because there is no telling what it may be.
+	IFS=$(printf ' \n\t')
+
+	if [ "${TEST_GENFUNCS}" = 1 ]; then
+		read -r cmdline
+	else
+		read -r cmdline < /proc/cmdline
+	fi || return
+
+	# Disable pathname expansion. The definition of this function
+	# is a compound command that incurs a subshell. Therefore, the
+	# prior state of the option does not need to be recalled.
+	set -f
+	for opt in ${cmdline}; do
+		gentoo_opt=${opt#gentoo=}
+		if [ "${opt}" != "${gentoo_opt}" ]; then
+			case ,${gentoo_opt}, in
+				*,"$1",*) return 0
+			esac
+		fi
+	done
 	return 1
-}
+)
 
 #
-#    show an error message (with a newline) and log it
+#   Determine whether the first operand is a valid identifier (variable name).
 #
-eerror()
+is_identifier()
+(
+	LC_ALL=C
+	case $1 in
+		''|_|[[:digit:]]*|*[!_[:alnum:]]*) false
+	esac
+)
+
+#
+#   Determine whether the first operand is in the form of an integer. A leading
+#   <hypen-minus> shall be permitted. Thereafter, leading zeroes shall not be
+#   permitted because the string might later be considered to be octal in an
+#   arithmetic context, causing the shell to exit if the number be invalid.
+#
+is_int()
 {
-	eerrorn "${*}${genfun_newline}"
+	set -- "${1#-}"
+	case $1 in
+		''|*[!0123456789]*)
+			false
+			;;
+		0)
+			true
+			;;
+		*)
+			test "$1" = "${1#0}"
+	esac
 }
 
 #
-#    show a message indicating the start of a process
+#   return 0 if any of the files/dirs are newer than
+#   the reference file
 #
-ebegin()
+#   EXAMPLE: if is_older_than a.out *.o ; then ...
+is_older_than()
 {
-	local msg
+	local ref has_gfind
 
-	if ! yesno "${EINFO_QUIET}"; then
-		msg=$*
-		while _ends_with_newline "${msg}"; do
-			msg=${msg%"${genfun_newline}"}
-		done
-		_eprint "${GOOD}" "${msg} ...${genfun_newline}"
+	if [ "$#" -lt 2 ]; then
+		ewarn "Too few arguments for is_older_than (got $#, expected at least 2)"
+		return 1
+	elif [ -e "$1" ]; then
+		ref=$1
+	else
+		ref=
+	fi
+	shift
+
+	# Consult the hash table in the present shell, prior to forking.
+	hash gfind 2>/dev/null; has_gfind=$(( $? == 0 ))
+
+	for path; do
+		if [ -e "${path}" ]; then
+			printf '%s\0' "${path}"
+		fi
+	done |
+	{
+		set -- -L -files0-from - ${ref:+-newermm} ${ref:+"${ref}"} -printf '\n' -quit
+		if [ "${has_gfind}" -eq 1 ]; then
+			gfind "$@"
+		else
+			find "$@"
+		fi
+	} |
+	read -r _
+}
+
+vebegin()
+{
+	if yesno "${EINFO_VERBOSE}"; then
+		ebegin "$@"
+	fi
+}
+
+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)"
+	else
+		return "$1"
+	fi
+}
+
+veerror()
+{
+	if yesno "${EINFO_VERBOSE}"; then
+		eerror "$@"
 	fi
 }
 
+veindent()
+{
+	if yesno "${EINFO_VERBOSE}"; then
+		eindent "$@"
+	fi
+}
+
+veinfo()
+{
+	if yesno "${EINFO_VERBOSE}"; then
+		einfo "$@"
+	fi
+}
+
+veinfon()
+{
+	if yesno "${EINFO_VERBOSE}"; then
+		einfon "$@"
+	fi
+}
+
+veoutdent()
+{
+	if yesno "${EINFO_VERBOSE}"; then
+		eoutdent "$@"
+	fi
+}
+
+vewarn()
+{
+	if yesno "${EINFO_VERBOSE}"; then
+		ewarn "$@"
+	fi
+}
+
+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)"
+	else
+		return "$1"
+	fi
+}
+
+#
+# this function was lifted from OpenRC. It returns 0 if the argument  or
+# the value of the argument is "yes", "true", "on", or "1" or 1
+# otherwise.
+#
+yesno()
+{
+	for _ in 1 2; do
+		case $1 in
+			[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0|'')
+				return 1
+				;;
+			[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
+				return 0
+		esac
+		if [ "$_" -ne 1 ] || ! is_identifier "$1"; then
+			! break
+		else
+			# The value appears to be a legal variable name. Treat
+			# it as a name reference and try again, once only.
+			eval "set -- \"\$$1\""
+		fi
+	done || vewarn "Invalid argument given to yesno (expected a boolean-like or a legal name)"
+	return 1
+}
+
 #
 #    indicate the completion of process, called from eend/ewend
 #    if error, show errstr via efunc
@@ -240,231 +427,41 @@ _eend()
 	return "${retval}"
 }
 
-#
-#    indicate the completion of process
-#    if error, show errstr via eerror
-#
-eend()
+_ends_with_newline()
 {
-	GENFUN_CALLER=${GENFUN_CALLER:-eend} _eend eerror "$@"
+	test "${genfun_newline}" \
+	&& ! case $1 in *"${genfun_newline}") false ;; esac
 }
 
 #
-#    indicate the completion of process
-#    if error, show errstr via ewarn
+#    Called by ebegin, eerrorn, einfon, and ewarnn.
 #
-ewend()
-{
-	GENFUN_CALLER=${GENFUN_CALLER:-ewend} _eend ewarn "$@"
-}
-
-# v-e-commands honor EINFO_VERBOSE which defaults to no.
-veinfo()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		einfo "$@"
-	fi
-}
-
-veinfon()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		einfon "$@"
-	fi
-}
-
-vewarn()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		ewarn "$@"
-	fi
-}
-
-veerror()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		eerror "$@"
-	fi
-}
-
-vebegin()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		ebegin "$@"
-	fi
-}
-
-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)"
-	else
-		return "$1"
-	fi
-}
-
-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)"
-	else
-		return "$1"
-	fi
-}
-
-veindent()
-{
-	if yesno "${EINFO_VERBOSE}"; then
-		eindent "$@"
-	fi
-}
-
-veoutdent()
+_eprint()
 {
-	if yesno "${EINFO_VERBOSE}"; then
-		eoutdent "$@"
-	fi
-}
-
-#
-#   return 0 if gentoo=param was passed to the kernel
-#
-#   EXAMPLE:  if get_bootparam "nodevfs" ; then ....
-#
-get_bootparam()
-(
-	# Gentoo cmdline parameters are comma-delimited, so a search
-	# string containing a comma must not be allowed to match.
-	# Similarly, the empty string must not be allowed to match.
-	case $1 in ''|*,*) return 1 ;; esac
-
-	# Reset the value of IFS because there is no telling what it may be.
-	IFS=$(printf ' \n\t')
-
-	if [ "${TEST_GENFUNCS}" = 1 ]; then
-		read -r cmdline
-	else
-		read -r cmdline < /proc/cmdline
-	fi || return
-
-	# Disable pathname expansion. The definition of this function
-	# is a compound command that incurs a subshell. Therefore, the
-	# prior state of the option does not need to be recalled.
-	set -f
-	for opt in ${cmdline}; do
-		gentoo_opt=${opt#gentoo=}
-		if [ "${opt}" != "${gentoo_opt}" ]; then
-			case ,${gentoo_opt}, in
-				*,"$1",*) return 0
-			esac
-		fi
-	done
-	return 1
-)
+	local color
 
-#
-#   return 0 if any of the files/dirs are newer than
-#   the reference file
-#
-#   EXAMPLE: if is_older_than a.out *.o ; then ...
-is_older_than()
-{
-	local ref has_gfind
+	color=$1
+	shift
 
-	if [ "$#" -lt 2 ]; then
-		ewarn "Too few arguments for is_older_than (got $#, expected at least 2)"
-		return 1
-	elif [ -e "$1" ]; then
-		ref=$1
+	if [ -t 1 ]; then
+		printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "$*"
 	else
-		ref=
+		printf ' * %s%s' "${genfun_indent}" "$*"
 	fi
-	shift
-
-	# Consult the hash table in the present shell, prior to forking.
-	hash gfind 2>/dev/null; has_gfind=$(( $? == 0 ))
-
-	for path; do
-		if [ -e "${path}" ]; then
-			printf '%s\0' "${path}"
-		fi
-	done |
-	{
-		set -- -L -files0-from - ${ref:+-newermm} ${ref:+"${ref}"} -printf '\n' -quit
-		if [ "${has_gfind}" -eq 1 ]; then
-			gfind "$@"
-		else
-			find "$@"
-		fi
-	} |
-	read -r _
-}
-
-#
-#   Determine whether the first operand is in the form of an integer. A leading
-#   <hypen-minus> shall be permitted. Thereafter, leading zeroes shall not be
-#   permitted because the string might later be considered to be octal in an
-#   arithmetic context, causing the shell to exit if the number be invalid.
-#
-is_int()
-{
-	set -- "${1#-}"
-	case $1 in
-		''|*[!0123456789]*)
-			false
-			;;
-		0)
-			true
-			;;
-		*)
-			test "$1" = "${1#0}"
-	esac
 }
 
 #
-#   A safe wrapper for the cd builtin. To run cd "$dir" is problematic because:
-#
-#   1) it may consider its operand as an option
-#   2) it will search CDPATH for an operand not beginning with ./, ../ or /
-#   3) it will switch to OLDPWD if the operand is -
-#   4) cdable_vars causes bash to treat the operand as a potential variable name
+#    hard set the indent used for e-commands.
+#    num defaults to 0
 #
-chdir()
+_esetdent()
 {
-	if [ "$BASH" ]; then
-		# shellcheck disable=3044
-		shopt -u cdable_vars
-	fi
-	if [ "$1" = - ]; then
-		set -- ./-
+	if ! is_int "$1" || [ "$1" -lt 0 ]; then
+		set -- 0
 	fi
-	# shellcheck disable=1007,2164
-	CDPATH= cd -- "$@"
-}
-
-#
-#   Determine whether the first operand contains any visible characters.
-#
-_is_visible()
-{
-	! case $1 in *[[:graph:]]*) false ;; esac
+	genfun_indent=$(printf "%${1}s" '')
 }
 
-#
-#   Determine whether the first operand is a valid identifier (variable name).
-#
-is_identifier()
-(
-	LC_ALL=C
-	case $1 in
-		''|_|[[:digit:]]*|*[!_[:alnum:]]*) false
-	esac
-)
-
 _has_dumb_terminal()
 {
 	! case ${TERM} in *dumb*) false ;; esac
@@ -485,12 +482,26 @@ _has_monochrome_terminal()
 	fi
 }
 
-_ends_with_newline()
+#
+#   Determine whether the first operand contains any visible characters.
+#
+_is_visible()
 {
-	test "${genfun_newline}" \
-	&& ! case $1 in *"${genfun_newline}") false ;; esac
+	! case $1 in *[[:graph:]]*) false ;; esac
 }
 
+_update_columns()
+{
+	local ifs
+
+	# The following use of stty(1) is portable as of POSIX Issue 8.
+	ifs=$IFS
+	IFS=' '
+	# shellcheck disable=2046
+	set -- $(stty size 2>/dev/null)
+	IFS=$ifs
+	[ "$#" -eq 2 ] && is_int "$2" && [ "$2" -gt 0 ] && genfun_cols=$2
+}
 
 _update_tty_level()
 {
@@ -509,19 +520,6 @@ _update_tty_level()
 	fi
 }
 
-_update_columns()
-{
-	local ifs
-
-	# The following use of stty(1) is portable as of POSIX Issue 8.
-	ifs=$IFS
-	IFS=' '
-	# shellcheck disable=2046
-	set -- $(stty size 2>/dev/null)
-	IFS=$ifs
-	[ "$#" -eq 2 ] && is_int "$2" && [ "$2" -gt 0 ] && genfun_cols=$2
-}
-
 # This is the main script, please add all functions above this point!
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS="yes"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-15 10:28 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-15 10:28 UTC (permalink / raw
  To: gentoo-commits

commit:     f3e254127ebad7c8774081e3834653effe1966d0
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue May 14 08:33:09 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed May 15 10:28:30 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f3e25412

Have _eend() remember the cursor position before printing

The act of printing a LF character after the indicator moves the cursor
back to the row beneath - as intended - but also results in the cursor
being positioned at the first column, even though it may have been
elsewhere initially. Address this by using the DECSC sequence to save
the cursor position prior to printing the indicator, then the DECRC
sequence to restore it afterwards. My testing shows no measurable
performance impact.

Consider the following script as a test case.

#!/bin/sh
. ./functions.sh
ebegin Testing
einfon more output
eend 0

Below is a depicted invocation which clearly demonstrates the beneficial
effect of this change.

$ /.testcase; printf done
 * Testing ...                                                    [ ok ]
 * more outputdone$ ▉

Whereas, previously, the outcome would have been as shown below.

$ /.testcase; printf done
 * Testing ...                                                    [ ok ]
done$ ▉ output

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/functions.sh b/functions.sh
index 6d77f59..7bd4b11 100644
--- a/functions.sh
+++ b/functions.sh
@@ -227,10 +227,10 @@ _eend()
 	fi
 
 	if [ "${genfun_tty}" -eq 2 ]; then
-		# Move the cursor up by one line with CUU before positioning it
-		# horizontally with CHA. Both are formal ECMA-48 CSI sequences.
-		# Print the indicator afterwards.
-		printf '\033[1A\033[%dG %s\n' "$(( genfun_cols - 6 + genfun_offset ))" "${msg}"
+		# Save the cursor position with DECSC, move it up by one line
+		# with CUU, position it horizontally with CHA, print the
+		# indicator, then restore the cursor position with DECRC.
+		printf '\0337\033[1A\033[%dG %s\0338' "$(( genfun_cols - 6 + genfun_offset ))" "${msg}"
 	else
 		# The standard output does not refer to a sufficiently capable
 		# terminal. Print only the indicator.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-15 10:28 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-15 10:28 UTC (permalink / raw
  To: gentoo-commits

commit:     68c3ed9035165e4daa902421fa9de4589d631b3b
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Wed May 15 10:28:15 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed May 15 10:28:31 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=68c3ed90

meson.build: prepare for gentoo-functions-1.2

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index de4abf0..0c564b3 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project(
   'gentoo-functions', 'c',
-  version: '1.1',
+  version: '1.2',
   license: 'GPL-2.0-only',
   default_options : [
     'warning_level=2',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-14  0:18 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-14  0:18 UTC (permalink / raw
  To: gentoo-commits

commit:     c75ed22e9360f44e202581527269f830f8585d7b
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Tue May 14 00:18:06 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue May 14 00:18:06 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=c75ed22e

meson.build: prepare for gentoo-functions-1.1

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index b89d1be..de4abf0 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project(
   'gentoo-functions', 'c',
-  version: '1.0',
+  version: '1.1',
   license: 'GPL-2.0-only',
   default_options : [
     'warning_level=2',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-14  0:15 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-14  0:15 UTC (permalink / raw
  To: gentoo-commits

commit:     12d78db029707bc459f8ddded827dc46078fb8ad
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Tue May 14 00:15:24 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue May 14 00:15:24 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=12d78db0

meson.build: fix tests

Fixes: ea4fb2a1e34900635d0db7bd1d8e5e1bea06ced0
Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 05dba85..b89d1be 100644
--- a/meson.build
+++ b/meson.build
@@ -29,7 +29,7 @@ do_tests = get_option('tests')
 if do_tests
   test(
     'test-functions', files('test-functions'),
-    workdir : meson.current_build_dir(),
+    workdir : meson.current_source_dir(),
     protocol : 'tap',
     verbose : true
   )


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-14  0:12 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-14  0:12 UTC (permalink / raw
  To: gentoo-commits

commit:     f1dd9a109f67ff77ce8a312cb737ab68a3f3a3fb
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Tue May 14 00:11:53 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue May 14 00:12:25 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f1dd9a10

Drop ecma48-cpr

Obsolete as of bfd5710de9b14712c4a621259b951bd10489d0c0. A neat tool, but
it ended up not being a good fit for the reasons described in that commit.

Signed-off-by: Sam James <sam <AT> gentoo.org>

 ecma48-cpr.c | 239 -----------------------------------------------------------
 meson.build  |   7 --
 2 files changed, 246 deletions(-)

diff --git a/ecma48-cpr.c b/ecma48-cpr.c
deleted file mode 100644
index d910f6f..0000000
--- a/ecma48-cpr.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * ecma48-cpr.c
- * Treat STDIN as a tty and report the cursor position using the CPR sequence.
- *
- * Originally distributed as wsize.c by Stephen J. Friedl <steve@unixwiz.net>.
- * Repurposed for gentoo-functions by Kerin F. Millar <kfm@plushkava.net>.
- * This software is in the public domain.
- */
-
-#define _POSIX_C_SOURCE 200809L
-
-#define PROGRAM "ecma48-cpr"
-#define READ_TIMEOUT_NS 250000000
-#define BUFSIZE 100
-#define MAX_LOOPS 20
-
-#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <time.h>
-#include <unistd.h>
-
-static struct termios save_tty;
-static bool is_timed_out = false;
-static bool is_tty_saved = false;
-
-static void cleanup(void);
-static void die(char const * const errmsg);
-static void on_signal(int const signo);
-
-#ifndef __APPLE__
-static timer_t init_timer(void);
-#endif
-
-int
-main(void) {
-	/*
-	 * Establish that STDIN is a terminal.
-	 */
-	if (! isatty(STDIN_FILENO)) {
-		die("cannot determine the cursor position because stdin is not a tty");
-	}
-
-	/*
-	 * Duplicate STDIN to a new file descriptor before reopening it as a
-	 * writeable stream.
-	 */
-	int fd = dup(STDIN_FILENO);
-	FILE *tty;
-	if (fd < 0) {
-		die("failed to dup stdin");
-	} else {
-		tty = fdopen(fd, "w");
-		if (tty == NULL) {
-			die("failed to re-open the tty for writing");
-		}
-	}
-
-	/*
-	 * Save the current terminal settings.
-	 */
-	if (tcgetattr(STDIN_FILENO, &save_tty) != 0) {
-		die("failed to obtain the current terminal settings");
-	} else {
-		is_tty_saved = true;
-	}
-
-	/*
-	 * Duplicate the current terminal settings for modification.
-	 */
-	struct termios new_tty = save_tty;
-
-	/*
-	 * Turn off ECHO, so that the response from the terminal isn't printed.
-	 * Also, the terminal must be operating in its noncanonical mode,
-	 * thereby ensuring that its input is always immediately available,
-	 * with no processing having been performed.
-	 */
-	new_tty.c_lflag &= ~(ECHO | ICANON | IXON);
-
-	/*
-	 * Set an interbyte timeout of 1 decisecond. The timer is started only
-	 * after the first byte is read, so read(2) will block until then.
-	 */
-	new_tty.c_cc[VMIN]  = 1;
-	new_tty.c_cc[VTIME] = 1;
-
-	/*
-	 * Prepare to catch our signals. We treat both an interrupt and a
-	 * depleted timer as essentially the same thing: fatal errors.
-	 */
-	struct sigaction act = {
-		.sa_handler = on_signal,
-		.sa_flags = 0
-	};
-	sigemptyset(&act.sa_mask);
-	sigaction(SIGALRM, &act, NULL);
-
-
-	/*
-	 * Ignore the signals most likely to interrupt the process from hereon.
-	 */
-	signal(SIGINT, SIG_IGN);
-	signal(SIGTERM, SIG_IGN);
-	signal(SIGTSTP, SIG_IGN);
-
-	/*
-	 * Try to apply the new terminal settings.
-	 */
-	if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &new_tty) != 0) {
-		die("failed to modify the terminal settings");
-	} else if (fprintf(tty, "\033[6n") != 4) {
-		die("failed to write the CPR sequence to the terminal");
-	} else if (fclose(tty) != 0) {
-		die("failed to flush the stream after writing the CPR sequence");
-	}
-
-	/*
-	 * A timeout is required, just in case read(2) proves unable to read an
-	 * initial byte, otherwise causing the program to hang.
-	 */
-#ifdef __APPLE__
-	alarm(1);
-#else
-	timer_t timerid = init_timer();
-#endif
-
-	/*
-	 * Read up to (sizeof ibuf - 1) bytes of input in total. Upon each
-	 * successful read, scan the input buffer for a valid ECMA4-8 CPR
-	 * response. Abort if no such response is found within MAX_LOOPS
-	 * iterations.
-	 */
-	char ibuf[BUFSIZE];
-	char const * const imax = ibuf + sizeof ibuf - 1;
-	char *iptr = ibuf;
-	int maxloops = MAX_LOOPS;
-	int row = -1;
-	int col = -1;
-	ssize_t nr;
-	while (--maxloops > 0 && (nr = read(STDIN_FILENO, iptr, imax - iptr)) > 0) {
-		iptr += nr;
-		*iptr = '\0'; /* NUL-terminate for strchr(3) and sscanf(3) */
-		char const *p;
-		if ((p = strchr(ibuf, '\033')) != 0) {
-			if (sscanf(p, "\033[%d;%dR", &row, &col) == 2) {
-				break;
-			} else {
-				col = -1;
-				row = -1;
-			}
-		}
-	}
-
-	/*
-	 * Deactivate the timer.
-	 */
-#ifdef __APPLE__
-	alarm(0);
-#else
-	timer_delete(timerid);
-#endif
-
-	/*
-	 * Die in the case that the timer fired.
-	 */
-	if (is_timed_out) {
-		die("timed out waiting for the terminal to respond to CPR");
-	}
-
-	/*
-	 * Restore the original terminal settings.
-	 */
-	cleanup();
-
-	/*
-	 * Print the cursor position, provided both col and row are above zero.
-	 */
-	if (col < 1 || row < 1) {
-		die("failed to read the cursor position");
-	} else if (printf("%d %d\n", row, col) == -1 || fflush(stdout) == EOF) {
-		return EXIT_FAILURE;
-	} else {
-		return EXIT_SUCCESS;
-	}
-}
-
-#ifndef __APPLE__
-static timer_t
-init_timer(void) {
-	timer_t timerid;
-	struct sigevent event = {
-		.sigev_value.sival_ptr = &timerid,
-		.sigev_notify = SIGEV_SIGNAL,
-		.sigev_signo = SIGALRM
-	};
-	if (timer_create(CLOCK_REALTIME, &event, &timerid) == -1) {
-		die("failed to create a per-process timer");
-	} else {
-		struct itimerspec timer = {
-			.it_value.tv_nsec = READ_TIMEOUT_NS,
-			.it_interval.tv_nsec = 0,
-			.it_interval.tv_sec = 0,
-			.it_value.tv_sec = 0
-		};
-		if (timer_settime(timerid, 0, &timer, NULL) == -1) {
-			die("failed to configure the per-process timer");
-		}
-	}
-	return timerid;
-}
-#endif
-
-/*
- * Tries to restore the terminal settings. Only one attempt will ever be made.
- */
-static void
-cleanup(void) {
-	bool const is_saved = is_tty_saved;
-	if (is_saved) {
-		tcsetattr(STDIN_FILENO, TCSAFLUSH, &save_tty);
-		is_tty_saved = false;
-	}
-}
-
-static void
-die(char const * const errmsg) {
-	cleanup();
-	fprintf(stderr, "%s: %s\n", PROGRAM, errmsg);
-	exit(EXIT_FAILURE);
-}
-
-static void
-on_signal(int const signo) {
-	is_timed_out = true;
-}

diff --git a/meson.build b/meson.build
index f18c5f8..05dba85 100644
--- a/meson.build
+++ b/meson.build
@@ -25,13 +25,6 @@ install_man(
   'consoletype.1',
 )
 
-executable(
-  'ecma48-cpr',
-  'ecma48-cpr.c',
-  install: true,
-  install_dir: get_option('prefix') / 'lib' / 'gentoo'
-)
-
 do_tests = get_option('tests')
 if do_tests
   test(


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-14  0:12 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-14  0:12 UTC (permalink / raw
  To: gentoo-commits

commit:     ea4fb2a1e34900635d0db7bd1d8e5e1bea06ced0
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Tue May 14 00:10:24 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue May 14 00:10:45 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=ea4fb2a1

Cleanup functions.sh.in template

No longer needed since bfd5710de9b14712c4a621259b951bd10489d0c0.

Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh.in => functions.sh |  0
 meson.build                     | 14 ++------------
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/functions.sh.in b/functions.sh
similarity index 100%
rename from functions.sh.in
rename to functions.sh

diff --git a/meson.build b/meson.build
index 6846d40..f18c5f8 100644
--- a/meson.build
+++ b/meson.build
@@ -8,18 +8,8 @@ project(
   ]
 )
 
-conf_data = configuration_data()
-conf_data.set('version', meson.project_version())
-# For now, we can't really use libexec, given everyone hardcodes /lib/gentoo.
-# We might be able to install some symlinks to get around this though?
-conf_data.set('GENTOO_LIBEXEC_DIR', get_option('prefix') / 'lib' / 'gentoo')
-
-# TODO: Cleanup now that functions.sh no longer uses ecma48-cpr
-configure_file(
-  input: 'functions.sh.in',
-  output: 'functions.sh',
-  configuration: conf_data,
-  install: true,
+install_data(
+  'functions.sh',
   install_dir: 'lib/gentoo'
 )
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-14  0:08 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-14  0:08 UTC (permalink / raw
  To: gentoo-commits

commit:     6f8204800db6d66cc006cea972c6936c6675d8cc
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Tue May 14 00:07:53 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue May 14 00:08:25 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6f820480

functions.sh.in: fix typo

Kerin fixed this in a later push but I'd already pulled it in by that
point.

Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh.in b/functions.sh.in
index e40f1ff..6d77f59 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -499,7 +499,7 @@ _update_tty_level()
 	# terminal is detected, the value shall be 0. If a dumb terminal is
 	# detected, the value shall be 1. If a smart terminal is detected, the
 	# value shall be 2. For a terminal to be considered as smart, it must be
-	# able to successfuly reports its dimensions.
+	# able to successfully report its dimensions.
 	if [ ! -t 0 ]; then
 		genfun_tty=0
 	elif _has_dumb_terminal || ! _update_columns; then


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-14  0:08 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-14  0:08 UTC (permalink / raw
  To: gentoo-commits

commit:     7c0ade278efd23419813824453284d525a544e28
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Tue May 14 00:07:06 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue May 14 00:07:40 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7c0ade27

meson.build: add TODO wrt cleaning up functions.sh template

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 1 +
 1 file changed, 1 insertion(+)

diff --git a/meson.build b/meson.build
index 5346aee..6846d40 100644
--- a/meson.build
+++ b/meson.build
@@ -14,6 +14,7 @@ conf_data.set('version', meson.project_version())
 # We might be able to install some symlinks to get around this though?
 conf_data.set('GENTOO_LIBEXEC_DIR', get_option('prefix') / 'lib' / 'gentoo')
 
+# TODO: Cleanup now that functions.sh no longer uses ecma48-cpr
 configure_file(
   input: 'functions.sh.in',
   output: 'functions.sh',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-14  0:05 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-14  0:05 UTC (permalink / raw
  To: gentoo-commits

commit:     520388fda047e61a04802faf86a3d8d850cc58dc
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon May 13 21:56:09 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon May 13 22:19:14 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=520388fd

Render _update_winsize() immune to the prevailing value of IFS

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh.in | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/functions.sh.in b/functions.sh.in
index d1df518..555d1d1 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -638,12 +638,17 @@ _update_tty_level()
 
 _update_winsize()
 {
+	local ifs
+
 	# The following use of stty(1) is portable as of POSIX Issue 8. It would
 	# be beneficial to leverage the checkwinsize option in bash but the
 	# implementation is buggy. Given that Chet has agreed to investigate,
 	# it may eventually become possible to support it.
+	ifs=$IFS
+	IFS=' '
 	# shellcheck disable=2046
 	set -- $(stty size 2>/dev/null)
+	IFS=$ifs
 	if [ "$#" -eq 2 ] && is_int "$1" && is_int "$2" && [ "$1" -gt 0 ] && [ "$2" -gt 0 ]; then
 		genfun_rows=$1
 		genfun_cols=$2


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-14  0:05 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-14  0:05 UTC (permalink / raw
  To: gentoo-commits

commit:     bfd5710de9b14712c4a621259b951bd10489d0c0
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon May 13 23:18:02 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon May 13 23:18:02 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=bfd5710d

Simplify _eprint() and _eend() behaviour markedly

Following almost a year of usage and testing, I now consider my
experiments in smart terminal handling to be both a success and a
failure by equal measure. I deem them to be a successful in so far as
the code functions as intended, and that there have been several
positive reports from those intrepid enough to unmask
gentoo-functions-1.0. However, I also deem them to be a failure in so
far as there is a noticeable impact upon performance. In particular,
repeated calls to ebegin() and eend() are handled rather slowly. As
such, this commit greatly simplifies the code whilst retaining the most
compelling traits of the work that has been performed. The exact changes
are described herewith.

The _eprint() function shall now only check whether STDOUT refers to a
tty. In the event that it does, the message may be printed in a
colourised fashion. Otherwise, it shall be printed plainly. No longer
will the terminal be asked to remember the position of the cursor (using
DECSC), nor shall any variables be used for the purpose of keeping
state.

The _eend() function shall no longer attempt to restore the prior
position of the cursor (using DECRC), nor attempt to determine the
present position of the cursor (using ecma48-cpr). Instead, the
behaviour is reduced to that of checking whether STDOUT refers to a
smart terminal. In the event that it does, the success/failure
identifier shall always be printed on the preceding line, right-aligned.
Otherwise, it shall be printed plainly on the present line. It remains
the case that the terminal will be asked to report its dimensions, so
that _eend() can adapt to any adjustments made to the width of the
terminal emulator.

As a consequence of these changes, the _update_cursor_coords() and
_ecma48_cpr() functions are rendered obsolete and have been removed.
Additionally, the "genfun_cols", "genfun_y" and "genfun_is_pending_lf"
variables are rendered obsolete and have been removed. Finally, the
_update_winsize() function has been renamed to _update_columns().

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh.in | 194 +++++++-------------------------------------------------
 test-functions  |  34 ----------
 2 files changed, 22 insertions(+), 206 deletions(-)

diff --git a/functions.sh.in b/functions.sh.in
index c97219b..e40f1ff 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -14,81 +14,15 @@
 #
 _eprint()
 {
-	local color msg
+	local color
+
 	color=$1
 	shift
 
-	# Check whether STDOUT is a terminal, and how capable it is.
-	_update_tty_level <&1
-
-	if [ "${genfun_tty}" -eq 2 ]; then
-		# If the cursor is not situated on column 1, print a LF
-		# character. The assumption here is that the last call may have
-		# been via ebegin, or any of the other printing functions that
-		# pass a message without a trailing LF.
-		if [ "${genfun_x}" -ne 1 ]; then
-			printf '\n'
-		fi
-	elif [ "${genfun_is_pending_lf}" -eq 1 ]; then
-		# We are about to print to a dumb terminal or something other
-		# than a terminal. Print a LF character because the last printed
-		# message did not end with one. This technique is not ideal.
-		# For one thing, it can be thwarted by having called a printing
-		# function from a subshell or a shell launched by a subprocess,
-		# because the change to the flag variable would be lost. For
-		# another, it's possible for the user of the library to be
-		# directing STDOUT/STDERR to different places between calls.
-		# Such weaknesses cannot be addressed without some form of IPC.
-		printf '\n'
-	fi
-
-	msg=$*
-	if [ "${genfun_tty}" -lt 2 ]; then
-		if [ "${genfun_tty}" -eq 1 ]; then
-			# Print but do not attempt to save the cursor position.
-			printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "${msg}"
-		else
-			printf ' * %s%s' "${genfun_indent}" "${msg}"
-		fi
-		if _ends_with_newline "${msg}"; then
-			genfun_is_pending_lf=0
-		else
-			# Record the fact that a LF character is pending.
-			genfun_is_pending_lf=1
-		fi
-	elif ! _ends_with_newline "${msg}"; then
-		# Print the message before saving the cursor position with the
-		# DECSC sequence. This is a private mode sequence that is not
-		# defined by ECMA-48. However, it was introduced by DEC for the
-		# VT100 and can be considered as a de-facto standard.
-		printf ' %s*%s %s%s\0337' "${color}" "${NORMAL}" "${genfun_indent}" "${msg}"
+	if [ -t 1 ]; then
+		printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "$*"
 	else
-		# Strip all trailing LF characters before printing the message.
-		while true; do
-			msg=${msg%"${genfun_newline}"}
-			if ! _ends_with_newline "${msg}"; then
-				break
-			fi
-		done
-		printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "${msg}"
-
-		# Determine the current position of the cursor
-		_update_cursor_coords <&1
-
-		if [ "${genfun_y}" -ne "${genfun_rows}" ]; then
-			# Have the terminal save the position of the cursor
-			# with DECSC before printing a LF character to advance
-			# to the next line.
-			printf '\0337\n'
-		else
-			# The cursor is situated on the last row of the
-			# terminal, meaning that vertical scrolling will occur.
-			# Move the cursor up by one row with CUU (ECMA-48 CSI)
-			# before having the terminal save the position of the
-			# cursor with DECSC. Finally, print two LF characters to
-			# advance to the next line.
-			printf '\033[1A\0337\n\n'
-		fi
+		printf ' * %s%s' "${genfun_indent}" "$*"
 	fi
 }
 
@@ -254,7 +188,7 @@ ebegin()
 #
 _eend()
 {
-	local efunc indent msg offset retval
+	local efunc msg retval
 
 	efunc=$1
 	shift
@@ -270,19 +204,13 @@ _eend()
 		msg=$*
 	fi
 
-	# Stash the last known terminal dimensions, if any.
-	set -- "${genfun_rows}" "${genfun_cols}"
-
-	# Check whether STDOUT is a terminal, and how capable it is.
-	_update_tty_level <&1
-
 	if [ "${retval}" -ne 0 ]; then
 		# If a message was given, print it with the specified function.
 		if _is_visible "${msg}"; then
 			"${efunc}" "${msg}"
 		fi
 		# Generate an indicator for ebegin's unsuccessful conclusion.
-		if [ "${genfun_tty}" -eq 0 ]; then
+		if _update_tty_level <&1; [ "${genfun_tty}" -eq 0 ]; then
 			msg="[ !! ]"
 		else
 			msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
@@ -291,63 +219,21 @@ _eend()
 		return "${retval}"
 	else
 		# Generate an indicator for ebegin's successful conclusion.
-		if [ "${genfun_tty}" -eq 0 ]; then
+		if _update_tty_level <&1; [ "${genfun_tty}" -eq 0 ]; then
 			msg="[ ok ]"
 		else
 			msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
 		fi
 	fi
 
-	if [ "${genfun_tty}" -lt 2 ]; then
-		printf ' %s\n' "${msg}"
-		genfun_is_pending_lf=0
+	if [ "${genfun_tty}" -eq 2 ]; then
+		# Move the cursor up by one line with CUU before positioning it
+		# horizontally with CHA. Both are formal ECMA-48 CSI sequences.
+		# Print the indicator afterwards.
+		printf '\033[1A\033[%dG %s\n' "$(( genfun_cols - 6 + genfun_offset ))" "${msg}"
 	else
-		# Provided that the terminal has not since been resized, it may
-		# be possible to write the indicator on the same row as the
-		# last printed message, even if it were LF-terminated.
-		if [ "${genfun_rows}" -eq "$1" ] && [ "${genfun_cols}" -eq "$2" ]; then
-			# Stash the current position of the cursor.
-			set -- "${genfun_y}" "${genfun_x}"
-
-			# Using the DECRC sequence, restore the cursor position
-			# to wherever it was just after the last message was
-			# printed, but before the trailing LF character, if any.
-			# This is a private mode sequence, and thus not defined
-			# by ECMA-48. However, it was introduced by DEC for the
-			# VT100 and can be considered as a de-facto standard.
-			printf '\0338'
-
-			# Determine the position of the cursor again.
-			_update_cursor_coords <&1
-
-			# Check whether the act of restoring the cursor position
-			# moved it to a different row, excepting the immediately
-			# preceding row. If it did, assume that scrolling has
-			# occurred since printing the last message and move the
-			# cursor back to where it was with CUP (ECMA-48 CSI).
-			offset=$(( $1 - genfun_y ))
-			if [ "${offset}" -lt 0 ] || [ "${offset}" -gt 1 ]; then
-				printf '\033[%d;%dH' "$1" "$2"
-				genfun_y=$1
-				genfun_x=$2
-			fi
-		fi
-
-		# Calculate the column at which the indicator may be printed.
-		indent=$(( genfun_cols - genfun_x - 6 ))
-
-		# Determine whether the cursor needs to be repositioned.
-		if [ "${indent}" -gt 0 ]; then
-			# Use CHA (ECMA-48 CSI) to move the cursor to the right.
-			printf '\033[%dG' "$(( genfun_x + indent + genfun_offset ))"
-		elif [ "${indent}" -lt 0 ]; then
-			# The indent is negative, meaning that there is not
-			# enough room. Arrange for the indicator to be printed
-			# on the next line instead.
-			printf '\n\033[%dG' "$(( genfun_cols - 6 + genfun_offset ))"
-		fi
-
-		# Finally, print the indicator.
+		# The standard output does not refer to a sufficiently capable
+		# terminal. Print only the indicator.
 		printf ' %s\n' "${msg}"
 	fi
 
@@ -605,68 +491,35 @@ _ends_with_newline()
 	&& ! case $1 in *"${genfun_newline}") false ;; esac
 }
 
+
 _update_tty_level()
 {
 	# Grade the capability of the terminal attached to STDIN (if any) on a
 	# scale of 0 to 2, assigning the resulting value to genfun_tty. If no
 	# terminal is detected, the value shall be 0. If a dumb terminal is
 	# detected, the value shall be 1. If a smart terminal is detected, the
-	# value shall be 2.
-	#
-	# In the case that a smart terminal is detected, its dimensions shall
-	# be assigned to genfun_cols and genfun_rows, and the position of the
-	# cursor shall be assigned to genfun_x and genfun_y. Further, it may
-	# reasonably be assumed that the ECMA-48 CSI and DECSC/DECRC escape
-	# sequences are supported.
+	# value shall be 2. For a terminal to be considered as smart, it must be
+	# able to successfuly reports its dimensions.
 	if [ ! -t 0 ]; then
 		genfun_tty=0
-	elif _has_dumb_terminal || ! _update_winsize || ! _update_cursor_coords; then
+	elif _has_dumb_terminal || ! _update_columns; then
 		genfun_tty=1
 	else
 		genfun_tty=2
 	fi
 }
 
-_update_winsize()
+_update_columns()
 {
 	local ifs
 
-	# The following use of stty(1) is portable as of POSIX Issue 8. It would
-	# be beneficial to leverage the checkwinsize option in bash but the
-	# implementation is buggy. Given that Chet has agreed to investigate,
-	# it may eventually become possible to support it.
+	# The following use of stty(1) is portable as of POSIX Issue 8.
 	ifs=$IFS
 	IFS=' '
 	# shellcheck disable=2046
 	set -- $(stty size 2>/dev/null)
 	IFS=$ifs
-	if [ "$#" -eq 2 ] && is_int "$1" && is_int "$2" && [ "$1" -gt 0 ] && [ "$2" -gt 0 ]; then
-		genfun_rows=$1
-		genfun_cols=$2
-	else
-		genfun_rows=
-		genfun_cols=
-		false
-	fi
-}
-
-_update_cursor_coords()
-{
-	# shellcheck disable=2046
-	set -- $(_ecma48_cpr)
-	if [ "$#" -eq 2 ] && is_int "$1" && is_int "$2"; then
-		genfun_y=$1
-		genfun_x=$2
-	else
-		genfun_y=
-		genfun_x=
-		false
-	fi
-}
-
-_ecma48_cpr()
-{
-	@GENTOO_LIBEXEC_DIR@/ecma48-cpr
+	[ "$#" -eq 2 ] && is_int "$2" && [ "$2" -gt 0 ] && genfun_cols=$2
 }
 
 # This is the main script, please add all functions above this point!
@@ -685,9 +538,6 @@ genfun_indent=
 genfun_newline='
 '
 
-# Whether the last printed message is pending a concluding LF character.
-genfun_is_pending_lf=0
-
 # In Emacs, M-x term opens an "eterm-color" terminal, whose implementation of
 # the CHA (ECMA-48 CSI) sequence suffers from an off-by-one error.
 if [ "${INSIDE_EMACS}" ] && [ "${TERM}" = "eterm-color" ]; then

diff --git a/test-functions b/test-functions
index 513deb3..a2d15b4 100755
--- a/test-functions
+++ b/test-functions
@@ -323,31 +323,6 @@ test_is_visible() {
 		iterate_tests 2 "$@"
 }
 
-test_update_cursor_coords() {
-	skip() {
-		printf 'ok %d - _update_cursor_coords # SKIP\n' "$((testnum += 1))"
-	}
-	if _has_dumb_terminal; then
-		skip
-	elif ! ctty=$(ps -p "$$" -otty= 2>/dev/null) || [ -z "${ctty}" ]; then
-		# The ps(1) implementation is defective or non-compliant
-		skip
-	elif [ "${ctty}" = "?" ]; then
-		# No controlling terminal is available
-		skip
-	elif [ ! -e /dev/tty ]; then
-		skip
-	elif ! _update_winsize </dev/tty; then
-		# The terminal isn't smart
-		skip
-	elif ! _update_cursor_coords <>/dev/tty; then
-		printf 'not ok %d - _update_cursor_coords\n' "$((testnum += 1))"
-		false
-	else
-		printf 'ok %d - _update_cursor_coords (x = %d, y = %d)\n' "$((testnum += 1))" "${genfun_x}" "${genfun_y}"
-	fi
-}
-
 test_yesno() {
 	set -- \
 		0  yes \
@@ -453,14 +428,6 @@ if ! . ./functions.sh; then
 	bailout "Couldn't source ./functions.sh"
 fi
 
-# Since the test suite is normally executed during the src_test phase, the
-# ecma48-cpr utility will not yet have been installed. Account for that by
-# redeclaring its shim function.
-if [ "${EBUILD_PHASE}" = test ]; then
-	export BUILD_DIR="${PWD}"
-	_ecma48_cpr() { "${BUILD_DIR}"/ecma48-cpr; }
-fi
-
 assign_tmpdir
 
 export TEST_GENFUNCS=1
@@ -477,7 +444,6 @@ test_esyslog || rc=1
 test_is_identifier || rc=1
 test_is_int || rc=1
 test_is_visible || rc=1
-test_update_cursor_coords || rc=1
 test_yesno || rc=1
 
 cleanup_tmpdir


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-14  0:05 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-14  0:05 UTC (permalink / raw
  To: gentoo-commits

commit:     bc8ced13c5a987a9f1b0ac6d425d00d580d09519
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon May 13 21:34:22 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon May 13 21:34:22 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=bc8ced13

ecma48-cpr: Use designated initialisers for legibility

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 ecma48-cpr.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/ecma48-cpr.c b/ecma48-cpr.c
index 5a0f936..d910f6f 100644
--- a/ecma48-cpr.c
+++ b/ecma48-cpr.c
@@ -92,10 +92,11 @@ main(void) {
 	 * Prepare to catch our signals. We treat both an interrupt and a
 	 * depleted timer as essentially the same thing: fatal errors.
 	 */
-	struct sigaction act;
-	act.sa_handler = on_signal;
+	struct sigaction act = {
+		.sa_handler = on_signal,
+		.sa_flags = 0
+	};
 	sigemptyset(&act.sa_mask);
-	act.sa_flags = 0;
 	sigaction(SIGALRM, &act, NULL);
 
 
@@ -190,19 +191,21 @@ main(void) {
 #ifndef __APPLE__
 static timer_t
 init_timer(void) {
-	struct itimerspec timer;
-	struct sigevent event;
 	timer_t timerid;
-	event.sigev_notify = SIGEV_SIGNAL;
-	event.sigev_signo = SIGALRM;
-	event.sigev_value.sival_ptr = &timerid;
+	struct sigevent event = {
+		.sigev_value.sival_ptr = &timerid,
+		.sigev_notify = SIGEV_SIGNAL,
+		.sigev_signo = SIGALRM
+	};
 	if (timer_create(CLOCK_REALTIME, &event, &timerid) == -1) {
 		die("failed to create a per-process timer");
 	} else {
-		timer.it_value.tv_sec = 0;
-		timer.it_value.tv_nsec = READ_TIMEOUT_NS;
-		timer.it_interval.tv_sec = 0;
-		timer.it_interval.tv_nsec = 0;
+		struct itimerspec timer = {
+			.it_value.tv_nsec = READ_TIMEOUT_NS,
+			.it_interval.tv_nsec = 0,
+			.it_interval.tv_sec = 0,
+			.it_value.tv_sec = 0
+		};
 		if (timer_settime(timerid, 0, &timer, NULL) == -1) {
 			die("failed to configure the per-process timer");
 		}


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-14  0:05 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-14  0:05 UTC (permalink / raw
  To: gentoo-commits

commit:     1fd9f819fbb2493c47c2166cd234246c1f8f85a7
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon May 13 22:14:05 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon May 13 22:19:16 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1fd9f819

Don't check for Emacs every time _eend() is called

For it is an edge case and it is not clear that it is worth it. Instead,
check at the time of sourcing. The underlying bug really ought to be
addressed upstream.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh.in | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/functions.sh.in b/functions.sh.in
index 555d1d1..c97219b 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -336,24 +336,15 @@ _eend()
 		# Calculate the column at which the indicator may be printed.
 		indent=$(( genfun_cols - genfun_x - 6 ))
 
-		# In Emacs, M-x term opens an "eterm-color" terminal, whose
-		# implementation of the CHA (ECMA-48 CSI) sequence suffers from
-		# an off-by-one error.
-		if [ "${INSIDE_EMACS}" ] && [ "${TERM}" = "eterm-color" ]; then
-			offset=-1
-		else
-			offset=0
-		fi
-
 		# Determine whether the cursor needs to be repositioned.
 		if [ "${indent}" -gt 0 ]; then
 			# Use CHA (ECMA-48 CSI) to move the cursor to the right.
-			printf '\033[%dG' "$(( genfun_x + indent + offset ))"
+			printf '\033[%dG' "$(( genfun_x + indent + genfun_offset ))"
 		elif [ "${indent}" -lt 0 ]; then
 			# The indent is negative, meaning that there is not
 			# enough room. Arrange for the indicator to be printed
 			# on the next line instead.
-			printf '\n\033[%dG' "$(( genfun_cols - 6 + offset ))"
+			printf '\n\033[%dG' "$(( genfun_cols - 6 + genfun_offset ))"
 		fi
 
 		# Finally, print the indicator.
@@ -697,6 +688,14 @@ genfun_newline='
 # Whether the last printed message is pending a concluding LF character.
 genfun_is_pending_lf=0
 
+# In Emacs, M-x term opens an "eterm-color" terminal, whose implementation of
+# the CHA (ECMA-48 CSI) sequence suffers from an off-by-one error.
+if [ "${INSIDE_EMACS}" ] && [ "${TERM}" = "eterm-color" ]; then
+	genfun_offset=-1
+else
+	genfun_offset=0
+fi
+
 # Should we use color?
 if [ -n "${NO_COLOR}" ]; then
 	# See https://no-color.org/.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-05-14  0:05 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-05-14  0:05 UTC (permalink / raw
  To: gentoo-commits

commit:     7fcc1c137a79587b26db03079ee659bcbac8c533
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon May 13 21:37:02 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon May 13 21:52:45 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7fcc1c13

Unify the brace style

I tend to define functions in accordance with the K&R brace style. In
deference to the traditions of the project, employ the Allman style
instead.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh.in | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/functions.sh.in b/functions.sh.in
index d2baf5d..d1df518 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -12,7 +12,8 @@
 #
 #    Called by ebegin, eerrorn, einfon, and ewarnn.
 #
-_eprint() {
+_eprint()
+{
 	local color msg
 	color=$1
 	shift
@@ -532,7 +533,8 @@ is_older_than()
 #   permitted because the string might later be considered to be octal in an
 #   arithmetic context, causing the shell to exit if the number be invalid.
 #
-is_int() {
+is_int()
+{
 	set -- "${1#-}"
 	case $1 in
 		''|*[!0123456789]*)
@@ -554,7 +556,8 @@ is_int() {
 #   3) it will switch to OLDPWD if the operand is -
 #   4) cdable_vars causes bash to treat the operand as a potential variable name
 #
-chdir() {
+chdir()
+{
 	if [ "$BASH" ]; then
 		# shellcheck disable=3044
 		shopt -u cdable_vars
@@ -569,7 +572,8 @@ chdir() {
 #
 #   Determine whether the first operand contains any visible characters.
 #
-_is_visible() {
+_is_visible()
+{
 	! case $1 in *[[:graph:]]*) false ;; esac
 }
 
@@ -584,11 +588,13 @@ is_identifier()
 	esac
 )
 
-_has_dumb_terminal() {
+_has_dumb_terminal()
+{
 	! case ${TERM} in *dumb*) false ;; esac
 }
 
-_has_monochrome_terminal() {
+_has_monochrome_terminal()
+{
 	local colors
 
 	# The tput(1) invocation is not portable, though ncurses suffices. In
@@ -602,12 +608,14 @@ _has_monochrome_terminal() {
 	fi
 }
 
-_ends_with_newline() {
+_ends_with_newline()
+{
 	test "${genfun_newline}" \
 	&& ! case $1 in *"${genfun_newline}") false ;; esac
 }
 
-_update_tty_level() {
+_update_tty_level()
+{
 	# Grade the capability of the terminal attached to STDIN (if any) on a
 	# scale of 0 to 2, assigning the resulting value to genfun_tty. If no
 	# terminal is detected, the value shall be 0. If a dumb terminal is
@@ -628,7 +636,8 @@ _update_tty_level() {
 	fi
 }
 
-_update_winsize() {
+_update_winsize()
+{
 	# The following use of stty(1) is portable as of POSIX Issue 8. It would
 	# be beneficial to leverage the checkwinsize option in bash but the
 	# implementation is buggy. Given that Chet has agreed to investigate,
@@ -645,7 +654,8 @@ _update_winsize() {
 	fi
 }
 
-_update_cursor_coords() {
+_update_cursor_coords()
+{
 	# shellcheck disable=2046
 	set -- $(_ecma48_cpr)
 	if [ "$#" -eq 2 ] && is_int "$1" && is_int "$2"; then
@@ -658,7 +668,8 @@ _update_cursor_coords() {
 	fi
 }
 
-_ecma48_cpr() {
+_ecma48_cpr()
+{
 	@GENTOO_LIBEXEC_DIR@/ecma48-cpr
 }
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2024-02-16 21:35 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2024-02-16 21:35 UTC (permalink / raw
  To: gentoo-commits

commit:     a72102fe08752fefc8243855285affd93e5ff015
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Fri Feb 16 21:35:32 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 16 21:35:32 2024 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=a72102fe

meson.build: crank version to 1.0

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 2557168..5346aee 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
 project(
   'gentoo-functions', 'c',
-  version: '0.20',
+  version: '1.0',
   license: 'GPL-2.0-only',
   default_options : [
     'warning_level=2',


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-11 16:47 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-11 16:47 UTC (permalink / raw
  To: gentoo-commits

commit:     075761b394201951e2948be8730f8cb8e7fc8122
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun 11 11:26:16 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Jun 11 11:36:13 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=075761b3

Account for the buggy CHA implementation in Emacs

In Emacs, M-x term opens an "eterm-color" terminal, whose
implementation of the CHA (ECMA-48 CSI) sequence suffers from an
off-by-one error. Work around it. Note that Eterm does not have this
same bug.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh.in | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/functions.sh.in b/functions.sh.in
index 6f1ee75..d2baf5d 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -335,15 +335,24 @@ _eend()
 		# Calculate the column at which the indicator may be printed.
 		indent=$(( genfun_cols - genfun_x - 6 ))
 
+		# In Emacs, M-x term opens an "eterm-color" terminal, whose
+		# implementation of the CHA (ECMA-48 CSI) sequence suffers from
+		# an off-by-one error.
+		if [ "${INSIDE_EMACS}" ] && [ "${TERM}" = "eterm-color" ]; then
+			offset=-1
+		else
+			offset=0
+		fi
+
 		# Determine whether the cursor needs to be repositioned.
 		if [ "${indent}" -gt 0 ]; then
 			# Use CHA (ECMA-48 CSI) to move the cursor to the right.
-			printf '\033[%dG' "$(( genfun_x + indent ))"
+			printf '\033[%dG' "$(( genfun_x + indent + offset ))"
 		elif [ "${indent}" -lt 0 ]; then
 			# The indent is negative, meaning that there is not
 			# enough room. Arrange for the indicator to be printed
 			# on the next line instead.
-			printf '\n\033[%dG' "$(( genfun_cols - 6 ))"
+			printf '\n\033[%dG' "$(( genfun_cols - 6 + offset ))"
 		fi
 
 		# Finally, print the indicator.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-11 16:47 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-11 16:47 UTC (permalink / raw
  To: gentoo-commits

commit:     87ee7f2a56d712246eb8d630e3282295ab92bbbe
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Jun 10 23:36:15 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Jun 11 08:32:22 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=87ee7f2a

ecma48-cpr: Set up the signal handler before writing to the terminal

The idea being to narrow the window of time during which the terminal
is in its raw mode as much as is possible.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 ecma48-cpr.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/ecma48-cpr.c b/ecma48-cpr.c
index 4710b39..f397ab7 100644
--- a/ecma48-cpr.c
+++ b/ecma48-cpr.c
@@ -89,6 +89,17 @@ main(void) {
 	new_tty.c_cc[VMIN]  = 1;
 	new_tty.c_cc[VTIME] = 1;
 
+	/*
+	 * Prepare to catch our signals. We treat both an interrupt and a
+	 * depleted timer as essentially the same thing: fatal errors.
+	 */
+	struct sigaction act;
+	act.sa_handler = on_signal;
+	sigemptyset(&act.sa_mask);
+	act.sa_flags = 0;
+	sigaction(SIGALRM, &act, NULL);
+
+
 	/*
 	 * Try to apply the new terminal settings.
 	 */
@@ -100,16 +111,6 @@ main(void) {
 		die("failed to flush the stream after writing the CPR sequence");
 	}
 
-	/*
-	 * Prepare to catch our signals. We treat both an interrupt and a
-	 * depleted timer as essentially the same thing: fatal errors.
-	 */
-	struct sigaction act;
-	act.sa_handler = on_signal;
-	sigemptyset(&act.sa_mask);
-	act.sa_flags = 0;
-	sigaction(SIGALRM, &act, NULL);
-
 	/*
 	 * A timeout is required, just in case read(2) proves unable to read an
 	 * initial byte, otherwise causing the program to hang.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-11 16:47 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-11 16:47 UTC (permalink / raw
  To: gentoo-commits

commit:     6f6440c538efb2edbcdfe298521252b6510a1a80
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun 11 08:57:47 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Jun 11 09:18:32 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6f6440c5

Detect PTYs that aren't sufficiently functional to be considered as smart

In this case, the offender is the PTY that is set up by the
_create_pty_or_pipe() utility function in portage, which uses python's
pty module. I transpires that its behaviour is not exactly equivalent to
whichever controlling terminal is in effect at the time that emerge(1)
is executed, if any. As a consequence, the ecma48-cpr utility times out
while waiting for a response to the CPR (ECMA-48 CSI) sequence.

I can discern no option other than to refrain from considering the
terminal as being "smart" in this case. This is accomplished by
recognising that stty(1) reports "0 0" when asked to check its size.
These are nonsensical readings that would never be produced for a
properly functioning, non-dumb terminal. In fact, this check used to be
in place but was removed, simply because I forgot how important it is.

Processes running under portage that call into gentoo-functions will
still be able to produce coloured messages, but all the advantages of
the smart terminal handling path will be obviated. This is unfortunate,
but I have no intention of returning to the original, broken behaviour
of gentoo-functions, which was to assume that the characteristics of the
terminal found at the time of sourcing hold forever, and that STDOUT
and STDERR will never refer to anything other than that same terminal.

I would add that script(1) does not exhibit the same issue.

$ tty
/dev/pts/0
$ script -c 'tty; stty size <&1; /lib/gentoo/ecma48-cpr <&1' /dev/null
Script started, output log file is '/dev/null'.
/dev/pts/11
34 144
34 1
Script done.

In other words, it is portage that is broken and which should be fixed.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Reported-by: Sam James <sam <AT> gentoo.org>

 functions.sh.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh.in b/functions.sh.in
index 9be9978..6f1ee75 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -626,7 +626,7 @@ _update_winsize() {
 	# it may eventually become possible to support it.
 	# shellcheck disable=2046
 	set -- $(stty size 2>/dev/null)
-	if [ "$#" -eq 2 ] && is_int "$1" && is_int "$2"; then
+	if [ "$#" -eq 2 ] && is_int "$1" && is_int "$2" && [ "$1" -gt 0 ] && [ "$2" -gt 0 ]; then
 		genfun_rows=$1
 		genfun_cols=$2
 	else


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-11 16:47 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-11 16:47 UTC (permalink / raw
  To: gentoo-commits

commit:     b6fe181d26b6819ca0086a2fc9b664ee3f84a555
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun 11 08:43:35 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Jun 11 08:43:35 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b6fe181d

ecma48-cpr: Disable flow control in the terminal

While at it, don't bother disabling ECHOE, ECHOK and ECHONL, for they do
nothing in the case that ICANON has been disabled.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 ecma48-cpr.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/ecma48-cpr.c b/ecma48-cpr.c
index f397ab7..7d32c63 100644
--- a/ecma48-cpr.c
+++ b/ecma48-cpr.c
@@ -79,8 +79,7 @@ main(void) {
 	 * thereby ensuring that its input is always immediately available,
 	 * with no processing having been performed.
 	 */
-	new_tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL);
-	new_tty.c_lflag &= ~(ICANON);
+	new_tty.c_lflag &= ~(ECHO | ICANON | IXON);
 
 	/*
 	 * Set an interbyte timeout of 1 decisecond. The timer is started only


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-11 16:47 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-11 16:47 UTC (permalink / raw
  To: gentoo-commits

commit:     a608aa2b90299f74dbced4a31822aff7e4dc30ff
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Jun 10 23:21:58 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Jun 11 08:32:16 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=a608aa2b

ecma48-cpr: Flush the input queue with tcsetattr(3) instead

Doing so saves an additional syscall and waits for the output queue to
be drained, which is no bad thing.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 ecma48-cpr.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/ecma48-cpr.c b/ecma48-cpr.c
index 144c4ea..813621e 100644
--- a/ecma48-cpr.c
+++ b/ecma48-cpr.c
@@ -93,10 +93,8 @@ main(void) {
 	/*
 	 * Try to apply the new terminal settings.
 	 */
-	if (tcsetattr(STDIN_FILENO, TCSANOW, &new_tty) != 0) {
+	if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &new_tty) != 0) {
 		die("failed to modify the terminal settings");
-	} else if (tcflush(STDIN_FILENO, TCIFLUSH) != 0) {
-		die("failed to flush the terminal's input queue");
 	} else if (fprintf(tty, "\033[6n") != 4) {
 		die("failed to write the CPR sequence to the terminal");
 	} else if (fclose(tty) != 0) {
@@ -214,7 +212,7 @@ static void
 cleanup(void) {
 	bool const is_saved = is_tty_saved;
 	if (is_saved) {
-		tcsetattr(STDIN_FILENO, TCSANOW, &save_tty);
+		tcsetattr(STDIN_FILENO, TCSAFLUSH, &save_tty);
 		is_tty_saved = false;
 	}
 }


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-11 16:47 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-11 16:47 UTC (permalink / raw
  To: gentoo-commits

commit:     8d257696be7383ff8533e50b893f93365bea9756
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Jun 10 23:22:57 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Jun 11 08:32:19 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=8d257696

ecma48-cpr: Don't assign to new_tty twice

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 ecma48-cpr.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/ecma48-cpr.c b/ecma48-cpr.c
index 813621e..4710b39 100644
--- a/ecma48-cpr.c
+++ b/ecma48-cpr.c
@@ -72,7 +72,6 @@ main(void) {
 	 * Duplicate the current terminal settings for modification.
 	 */
 	struct termios new_tty = save_tty;
-	new_tty = save_tty;
 
 	/*
 	 * Turn off ECHO, so that the response from the terminal isn't printed.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-11 16:47 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-11 16:47 UTC (permalink / raw
  To: gentoo-commits

commit:     7f27dfa0ca0969837a9a40df49281ec7a2dae035
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Jun 10 07:40:16 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Jun 10 07:42:07 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7f27dfa0

test-functions: Add a test for the ebegin() function

The test determines whether ebegin() appends at least one <newline>
character to the message (following the ASCII ellipsis).

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/test-functions b/test-functions
index aed6620..513deb3 100755
--- a/test-functions
+++ b/test-functions
@@ -68,6 +68,25 @@ test_chdir_noop() {
 	iterate_tests 2 "$@"
 }
 
+test_ebegin() {
+	_eprint() {
+		shift
+		_ends_with_newline "$*"
+		ok=$(( $? == 0 ))
+	}
+
+	ok=0
+	set -- "message"
+	ebegin "$1"
+
+	if [ "${ok}" -eq 0 ]; then
+		printf 'not '
+	fi
+	printf 'ok %d - ebegin %s (expecting terminating newline)\n' "$((testnum + 1))" "$1"
+
+	return "$(( ok ? 0 : 1 ))"
+}
+
 test_is_older_than() {
 	set -- \
 		1  N/A           N/A \
@@ -451,6 +470,7 @@ rc=0
 
 test_chdir || rc=1
 test_chdir_noop || rc=1
+( test_ebegin ) || rc=1; testnum=$((testnum + 1))
 test_is_older_than || rc=1
 test_get_bootparam || rc=1
 test_esyslog || rc=1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-11 16:47 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-11 16:47 UTC (permalink / raw
  To: gentoo-commits

commit:     a930fa7a97375463d02cde833f6f31c5aef479e9
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Jun 11 08:49:19 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Jun 11 08:51:42 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=a930fa7a

ecma48-cpr: Ignore SIGINT, SIGTERM and SIGTSTP

There seems little sense in honouring these signals at the point that
the terminal settings are about to be altered and the CPR sequence
written.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 ecma48-cpr.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/ecma48-cpr.c b/ecma48-cpr.c
index 7d32c63..5a0f936 100644
--- a/ecma48-cpr.c
+++ b/ecma48-cpr.c
@@ -99,6 +99,13 @@ main(void) {
 	sigaction(SIGALRM, &act, NULL);
 
 
+	/*
+	 * Ignore the signals most likely to interrupt the process from hereon.
+	 */
+	signal(SIGINT, SIG_IGN);
+	signal(SIGTERM, SIG_IGN);
+	signal(SIGTSTP, SIG_IGN);
+
 	/*
 	 * Try to apply the new terminal settings.
 	 */


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  7:23 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  7:23 UTC (permalink / raw
  To: gentoo-commits

commit:     c3c6ba532055f01cde10882b67aecda00abd01e1
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Jun 10 07:10:48 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Jun 10 07:15:56 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=c3c6ba53

Fix the order of the arguments used to compose the CUP sequence

The CUP (ECMA-48 CSI) sequence expects for the row to come first, and
the column second. I could have just swapped the arguments but, instead,
I have adjusted the surrounding code so as to strictly adhere to this
convention (one that is also observed by stty size). This should
eliminate the possibility of any such mistake being made in the future.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Fixes: 20bc15b5b1009149c4a3d531911d3c219dc55f3a

 functions.sh.in | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/functions.sh.in b/functions.sh.in
index 0c3e7ba..9be9978 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -270,7 +270,7 @@ _eend()
 	fi
 
 	# Stash the last known terminal dimensions, if any.
-	set -- "${genfun_cols}" "${genfun_rows}"
+	set -- "${genfun_rows}" "${genfun_cols}"
 
 	# Check whether STDOUT is a terminal, and how capable it is.
 	_update_tty_level <&1
@@ -304,9 +304,9 @@ _eend()
 		# Provided that the terminal has not since been resized, it may
 		# be possible to write the indicator on the same row as the
 		# last printed message, even if it were LF-terminated.
-		if [ "${genfun_cols}" -eq "$1" ] && [ "${genfun_rows}" -eq "$2" ]; then
+		if [ "${genfun_rows}" -eq "$1" ] && [ "${genfun_cols}" -eq "$2" ]; then
 			# Stash the current position of the cursor.
-			set -- "${genfun_x}" "${genfun_y}"
+			set -- "${genfun_y}" "${genfun_x}"
 
 			# Using the DECRC sequence, restore the cursor position
 			# to wherever it was just after the last message was
@@ -324,11 +324,11 @@ _eend()
 			# preceding row. If it did, assume that scrolling has
 			# occurred since printing the last message and move the
 			# cursor back to where it was with CUP (ECMA-48 CSI).
-			offset=$(( $2 - genfun_y ))
+			offset=$(( $1 - genfun_y ))
 			if [ "${offset}" -lt 0 ] || [ "${offset}" -gt 1 ]; then
 				printf '\033[%d;%dH' "$1" "$2"
-				genfun_x=$1
-				genfun_y=$2
+				genfun_y=$1
+				genfun_x=$2
 			fi
 		fi
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  7:23 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  7:23 UTC (permalink / raw
  To: gentoo-commits

commit:     3f62d58dbb7fcb4ddaf14f7216110eebe9bd0b3e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Jun 10 07:03:07 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Jun 10 07:15:49 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=3f62d58d

Ensure that ebegin() appends a newline to the final message

The ebegin() function was recently modified to strip the trailing <newline>,
if any, from the given message. Later, it was modified to strip all trailing
<newline> characters. The purpose of doing so is to ensure that there is
no accidental line breaking betwixt the message and the ASCII ellipsis
that is appended. However, the function should then have been appending a
single <newline> to the composed message before handing it off to _eprint().
Make it so.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Fixes: 1947f0ed81f3b95a7e10a8a5a707776948f8a487

 functions.sh.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh.in b/functions.sh.in
index 76f1ad4..0c3e7ba 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -243,7 +243,7 @@ ebegin()
 		while _ends_with_newline "${msg}"; do
 			msg=${msg%"${genfun_newline}"}
 		done
-		_eprint "${GOOD}" "${msg} ..."
+		_eprint "${GOOD}" "${msg} ...${genfun_newline}"
 	fi
 }
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  6:04 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  6:04 UTC (permalink / raw
  To: gentoo-commits

commit:     02d2824b4daeedd4084da53ebf3633a8b5508a92
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Jun 10 05:40:35 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Jun 10 05:40:35 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=02d2824b

test-functions: Really fix non-conforming TAP output

The previous "fix" was an experimental patch that was not yet intended
for inclusion. This supplemental commit does as little as is necessary
to render the test suite properly functional under meson, given that
meson.build has been configured to expect the use of the TAP protocol.
It also configures meson to be verbose while executing the test suite.

As far as I can gather, the TAP support in meson is weak. Subtests do
not appear to be supported. For that reason, I have dropped the TAP
version from 14 to 13. While meson recognises "# SKIP" as a directive,
it does not report the reason that may follow the text. Another issue is
that no controlling terminal is present under meson. Therefore,
test_update_cursor_coords() is rendered useless, for it will always be
skipped. I have left the test in for the time being, in the hope that
there may yet be a solution.

In any case, this should be enough to render the -9999 ebuild both
testable and usable.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 meson.build    |  3 ++-
 test-functions | 21 +++++++++++----------
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/meson.build b/meson.build
index aa56907..2557168 100644
--- a/meson.build
+++ b/meson.build
@@ -46,6 +46,7 @@ if do_tests
   test(
     'test-functions', files('test-functions'),
     workdir : meson.current_build_dir(),
-    protocol : 'tap'
+    protocol : 'tap',
+    verbose : true
   )
 endif

diff --git a/test-functions b/test-functions
index 5e04c5f..aed6620 100755
--- a/test-functions
+++ b/test-functions
@@ -305,9 +305,8 @@ test_is_visible() {
 }
 
 test_update_cursor_coords() {
-	printf '%d..%d\n' "${tap_i}" "${tap_i}"
 	skip() {
-		print 'ok %d # SKIP\n' "${tap_i}"
+		printf 'ok %d - _update_cursor_coords # SKIP\n' "$((testnum += 1))"
 	}
 	if _has_dumb_terminal; then
 		skip
@@ -323,10 +322,10 @@ test_update_cursor_coords() {
 		# The terminal isn't smart
 		skip
 	elif ! _update_cursor_coords <>/dev/tty; then
-		printf 'not ok %d - _update_cursor_coords\n' "${tap_i}"
+		printf 'not ok %d - _update_cursor_coords\n' "$((testnum += 1))"
 		false
 	else
-		printf 'ok %d - _update_cursor_coords (x = %d, y = %d)\n' "${tap_i}" "${genfun_x}" "${genfun_y}"
+		printf 'ok %d - _update_cursor_coords (x = %d, y = %d)\n' "$((testnum += 1))" "${genfun_x}" "${genfun_y}"
 	fi
 }
 
@@ -374,7 +373,6 @@ iterate_tests() {
 	shift
 
 	total=$(( $# / slice_width ))
-	printf '%d..%d\n' "${tap_i}" "$((tap_i + total - 1))"
 	passed=0
 	i=0
 	while [ "$((i += 1))" -le "${total}" ]; do
@@ -405,9 +403,8 @@ iterate_tests() {
 		else
 			expected=">=$1"
 		fi
-		printf 'ok %d - %s (expecting %s)\n' "${tap_i}" "${test_description}" "${expected}"
+		printf 'ok %d - %s (expecting %s)\n' "$((testnum += 1))" "${test_description}" "${expected}"
 		shift "${slice_width}"
-		tap_i=$((tap_i + 1))
 	done
 	return "$(( passed < total ))"
 }
@@ -429,7 +426,7 @@ print_args() {
 	printf '%s\n' "$*"
 }
 
-printf 'TAP version 14\n'
+printf 'TAP version 13\n'
 
 unset -v dir
 
@@ -449,9 +446,9 @@ assign_tmpdir
 
 export TEST_GENFUNCS=1
 export TZ=UTC
-tap_i=1
-
+testnum=0
 rc=0
+
 test_chdir || rc=1
 test_chdir_noop || rc=1
 test_is_older_than || rc=1
@@ -462,5 +459,9 @@ test_is_int || rc=1
 test_is_visible || rc=1
 test_update_cursor_coords || rc=1
 test_yesno || rc=1
+
 cleanup_tmpdir
+
+printf '1..%d\n' "${testnum}"
+
 exit "${rc}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  4:22 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  4:22 UTC (permalink / raw
  To: gentoo-commits

commit:     be49b00f58db2c62e1a908507e80d11a1bc64611
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Jun 10 01:45:16 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Jun 10 01:48:42 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=be49b00f

test-functions: Fix non-conforming TAP 14 output

Given that there are no subtests, it isn't permissible to duplicate any
of the test numbers. Also, the test_update_cursor_coords() function was
not correctly conveying the case where the test is skipped.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/test-functions b/test-functions
index 34dc8b8..5e04c5f 100755
--- a/test-functions
+++ b/test-functions
@@ -305,23 +305,28 @@ test_is_visible() {
 }
 
 test_update_cursor_coords() {
+	printf '%d..%d\n' "${tap_i}" "${tap_i}"
+	skip() {
+		print 'ok %d # SKIP\n' "${tap_i}"
+	}
 	if _has_dumb_terminal; then
-		printf '1..0 # TERM defines the terminal as being dumb\n'
+		skip
 	elif ! ctty=$(ps -p "$$" -otty= 2>/dev/null) || [ -z "${ctty}" ]; then
-		printf '1..0 # the ps(1) implementation is defective or non-compliant\n'
+		# The ps(1) implementation is defective or non-compliant
+		skip
 	elif [ "${ctty}" = "?" ]; then
-		printf '1..0 # no controlling terminal is available\n'
+		# No controlling terminal is available
+		skip
 	elif [ ! -e /dev/tty ]; then
-		printf '1..0 # the /dev/tty character device is missing\n'
+		skip
 	elif ! _update_winsize </dev/tty; then
-		printf '1..0 # the controlling terminal is not smart\n'
+		# The terminal isn't smart
+		skip
 	elif ! _update_cursor_coords <>/dev/tty; then
-		printf '1..1\n'
-		printf 'not ok 1 - ecm48-cpr failed\n'
+		printf 'not ok %d - _update_cursor_coords\n' "${tap_i}"
 		false
 	else
-		printf '1..1\n'
-		printf 'ok 1 - ecm48-cpr succeeded (x = %d, y = %d)\n' "${genfun_x}" "${genfun_y}"
+		printf 'ok %d - _update_cursor_coords (x = %d, y = %d)\n' "${tap_i}" "${genfun_x}" "${genfun_y}"
 	fi
 }
 
@@ -369,7 +374,7 @@ iterate_tests() {
 	shift
 
 	total=$(( $# / slice_width ))
-	printf '1..%d\n' "${total}"
+	printf '%d..%d\n' "${tap_i}" "$((tap_i + total - 1))"
 	passed=0
 	i=0
 	while [ "$((i += 1))" -le "${total}" ]; do
@@ -400,8 +405,9 @@ iterate_tests() {
 		else
 			expected=">=$1"
 		fi
-		printf 'ok %d - %s (expecting %s)\n' "${i}" "${test_description}" "${expected}"
+		printf 'ok %d - %s (expecting %s)\n' "${tap_i}" "${test_description}" "${expected}"
 		shift "${slice_width}"
+		tap_i=$((tap_i + 1))
 	done
 	return "$(( passed < total ))"
 }
@@ -443,6 +449,7 @@ assign_tmpdir
 
 export TEST_GENFUNCS=1
 export TZ=UTC
+tap_i=1
 
 rc=0
 test_chdir || rc=1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  4:22 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  4:22 UTC (permalink / raw
  To: gentoo-commits

commit:     9ed12f2dbbd47a621839a4ba3183669f8ec5806c
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Jun  9 20:49:49 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 20:54:07 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9ed12f2d

Have ecma48-cpr flush the terminal's input queue

There is no guarantee that the input queue is empty at the time that
ecma48-cpr is executed. If the terminal has input waiting, not only
will ecma48-cpr potentially fail but it will pollute the input queue.
Work around this by flushing the input queue entirely. I'm not
especially pleased by this approach but I can see no other option,
short of giving up on the idea of using the CPR sequence at all.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 ecma48-cpr.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ecma48-cpr.c b/ecma48-cpr.c
index 9aef182..144c4ea 100644
--- a/ecma48-cpr.c
+++ b/ecma48-cpr.c
@@ -95,6 +95,8 @@ main(void) {
 	 */
 	if (tcsetattr(STDIN_FILENO, TCSANOW, &new_tty) != 0) {
 		die("failed to modify the terminal settings");
+	} else if (tcflush(STDIN_FILENO, TCIFLUSH) != 0) {
+		die("failed to flush the terminal's input queue");
 	} else if (fprintf(tty, "\033[6n") != 4) {
 		die("failed to write the CPR sequence to the terminal");
 	} else if (fclose(tty) != 0) {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  4:22 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  4:22 UTC (permalink / raw
  To: gentoo-commits

commit:     de41ef45b33e645d04756c3a7dba2230f847eb0f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Jun  9 22:10:04 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 22:25:47 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=de41ef45

test-functions: Add a test for the _update_cursor_coords() function

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/test-functions b/test-functions
index 0fd998d..9f87e98 100755
--- a/test-functions
+++ b/test-functions
@@ -303,6 +303,27 @@ test_is_visible() {
 		iterate_tests 2 "$@"
 }
 
+test_update_cursor_coords() {
+	if _has_dumb_terminal; then
+		printf '1..0 # TERM defines the terminal as being dumb\n'
+	elif ! ctty=$(ps -p "$$" -otty= 2>/dev/null) || [ -z "${ctty}" ]; then
+		printf '1..0 # the ps(1) implementation is defective or non-compliant\n'
+	elif [ "${ctty}" = "?" ]; then
+		printf '1..0 # no controlling terminal is available\n'
+	elif [ ! -e /dev/tty ]; then
+		printf '1..0 # the /dev/tty character device is missing\n'
+	elif ! _update_winsize </dev/tty; then
+		printf '1..0 # the controlling terminal is not smart\n'
+	elif ! _update_cursor_coords <>/dev/tty; then
+		printf '1..1\n'
+		printf 'not ok 1 - ecm48-cpr failed\n'
+		false
+	else
+		printf '1..1\n'
+		printf 'ok 1 - ecm48-cpr succeeded (x = %d, y = %d)\n' "${genfun_x}" "${genfun_y}"
+	fi
+}
+
 test_yesno() {
 	set -- \
 		0  yes \
@@ -430,6 +451,7 @@ test_esyslog || rc=1
 test_is_identifier || rc=1
 test_is_int || rc=1
 test_is_visible || rc=1
+test_update_cursor_coords || rc=1
 test_yesno || rc=1
 cleanup_tmpdir
 exit "${rc}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  4:22 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  4:22 UTC (permalink / raw
  To: gentoo-commits

commit:     bf484caa1884d1045df7fcd4a5e40c0e0cd717fb
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Jun  9 21:34:45 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 21:34:45 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=bf484caa

Restore genfun_y at the same time as genfun_x in _eend()

That this was not happening did not yet amount to a bug but let's ensure
that it cannot be one in the future.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh.in | 1 +
 1 file changed, 1 insertion(+)

diff --git a/functions.sh.in b/functions.sh.in
index d13be7d..d4becf8 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -328,6 +328,7 @@ _eend()
 			if [ "${offset}" -lt 0 ] || [ "${offset}" -gt 1 ]; then
 				printf '\033[%d;%dH' "$1" "$2"
 				genfun_x=$1
+				genfun_y=$2
 			fi
 		fi
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  4:22 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  4:22 UTC (permalink / raw
  To: gentoo-commits

commit:     347c3975525e15f52a537ef4ecccf8f3b33087bf
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Jun  9 21:26:16 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 21:26:16 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=347c3975

Remove the vim modeline

I am fed up with the indentation behaviour being wrecked by the
imablance between ts and sw and I aleady assume that a tabstop is
equivalent to 8 spaces. Enough.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh.in | 2 --
 1 file changed, 2 deletions(-)

diff --git a/functions.sh.in b/functions.sh.in
index 5141670..d13be7d 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -698,5 +698,3 @@ else
 	NORMAL=$(printf '\033[0m')
 	WARN=$(printf '\033[33;01m')
 fi
-
-# vim:ts=4


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  4:22 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  4:22 UTC (permalink / raw
  To: gentoo-commits

commit:     3f455919da23065ac6cbff9fa86791ae67798654
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Jun 10 01:50:15 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Jun 10 01:50:15 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=3f455919

meson.build: Use the TAP protocol for running the tests

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 meson.build | 1 +
 1 file changed, 1 insertion(+)

diff --git a/meson.build b/meson.build
index 8996d95..aa56907 100644
--- a/meson.build
+++ b/meson.build
@@ -46,5 +46,6 @@ if do_tests
   test(
     'test-functions', files('test-functions'),
     workdir : meson.current_build_dir(),
+    protocol : 'tap'
   )
 endif


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  4:22 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  4:22 UTC (permalink / raw
  To: gentoo-commits

commit:     6c59a01b2e2454cd286cc9d701cb6648d428106e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Jun  9 21:38:13 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 21:38:13 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6c59a01b

test-functions: Do not silence ewarn() while testing is_older_than()

I changed my mind about this. It's probable that more diagnostic
messages will be added in the future and it may then be useful to
observe them in the case that the test suite fails.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 test-functions | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-functions b/test-functions
index 0d7b1ab..0fd998d 100755
--- a/test-functions
+++ b/test-functions
@@ -424,7 +424,7 @@ export TZ=UTC
 rc=0
 test_chdir || rc=1
 test_chdir_noop || rc=1
-( ewarn() { true; }; test_is_older_than ) || rc=1
+test_is_older_than || rc=1
 test_get_bootparam || rc=1
 test_esyslog || rc=1
 test_is_identifier || rc=1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  4:22 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  4:22 UTC (permalink / raw
  To: gentoo-commits

commit:     721c22bcd300b9a5d995e3dfbe66e46ca944e08d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Jun  9 21:21:35 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 21:21:51 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=721c22bc

Right-trim messages given to ebegin() and _eprint() where appropriate

Have ebegin() strip all trailing newlines rather than just one at most.
Likewise for _eprint() in the case that a smart terminal is found.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh.in | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/functions.sh.in b/functions.sh.in
index 673be7d..5141670 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -62,8 +62,13 @@ _eprint() {
 		# VT100 and can be considered as a de-facto standard.
 		printf ' %s*%s %s%s\0337' "${color}" "${NORMAL}" "${genfun_indent}" "${msg}"
 	else
-		# Print the message without its trailing LF character.
-		msg=${msg%"${genfun_newline}"}
+		# Strip all trailing LF characters before printing the message.
+		while true; do
+			msg=${msg%"${genfun_newline}"}
+			if ! _ends_with_newline "${msg}"; then
+				break
+			fi
+		done
 		printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "${msg}"
 
 		# Determine the current position of the cursor
@@ -235,7 +240,9 @@ ebegin()
 
 	if ! yesno "${EINFO_QUIET}"; then
 		msg=$*
-		msg=${msg%"${genfun_newline}"}
+		while _ends_with_newline "${msg}"; do
+			msg=${msg%"${genfun_newline}"}
+		done
 		_eprint "${GOOD}" "${msg} ..."
 	fi
 }
@@ -584,7 +591,8 @@ _has_monochrome_terminal() {
 }
 
 _ends_with_newline() {
-	! case $1 in *"${genfun_newline}") false ;; esac
+	test "${genfun_newline}" \
+	&& ! case $1 in *"${genfun_newline}") false ;; esac
 }
 
 _update_tty_level() {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  4:22 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  4:22 UTC (permalink / raw
  To: gentoo-commits

commit:     6dea8b6b960b3370461a1b42c05f101bf42c89a4
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Jun  9 22:44:10 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 22:47:49 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6dea8b6b

Address a slew of shellcheck warnings

False-positives galore. It's getting out of hand for test-functions, so
I disabled several more tests in its global scope. It was correct to
point out that "${PWD}" should be quoted, however. Bash doesn't mind but
other sh implementations might.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh.in |  4 +++-
 test-functions  | 18 ++++++++++--------
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/functions.sh.in b/functions.sh.in
index d4becf8..76f1ad4 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -547,11 +547,13 @@ is_int() {
 #
 chdir() {
 	if [ "$BASH" ]; then
+		# shellcheck disable=3044
 		shopt -u cdable_vars
 	fi
 	if [ "$1" = - ]; then
 		set -- ./-
 	fi
+	# shellcheck disable=1007,2164
 	CDPATH= cd -- "$@"
 }
 
@@ -648,7 +650,7 @@ _update_cursor_coords() {
 }
 
 _ecma48_cpr() {
-	@GENTOO_LIBEXEC_DIR@/ecma48-cpr "$@"
+	@GENTOO_LIBEXEC_DIR@/ecma48-cpr
 }
 
 # This is the main script, please add all functions above this point!

diff --git a/test-functions b/test-functions
index 9f87e98..34dc8b8 100755
--- a/test-functions
+++ b/test-functions
@@ -1,5 +1,5 @@
 #!/bin/sh
-# shellcheck disable=2015
+# shellcheck disable=2015,2154,2164,2181,2317
 
 # Requires mktemp(1), which is not a standard utility, but is commonly
 # available. The implementations provided by GNU coreutils, busybox and toybox
@@ -43,9 +43,10 @@ test_chdir() {
 		shift
 		test_description="chdir $(print_args "$@")"
 		if [ "$BASH" ]; then
+			# shellcheck disable=3044
 			shopt -s cdable_vars
 		fi
-		CDPATH=child var=$CDPATH chdir "$@" \
+		CDPATH=child var=child chdir "$@" \
 		&& test "$PWD" != "$OLDPWD" \
 		&& cd - >/dev/null
 	}
@@ -221,8 +222,8 @@ test_is_identifier() {
 		1   [Z   \
 		1  '`a'  \
 		1  '`Z'  \
-		1   {a   \
-		1   {Z   \
+		1  '{a'  \
+		1  '{Z'  \
 		1  '|a'  \
 		1  '|Z'  \
 		1   a/   \
@@ -233,8 +234,8 @@ test_is_identifier() {
 		1   Z[   \
 		1  'a`'  \
 		1  'Z`'  \
-		1   a{   \
-		1   Z{   \
+		1  'a{'  \
+		1  'Z{'  \
 		1  'a|'  \
 		1  'Z|'  \
 		0    a   \
@@ -351,6 +352,7 @@ test_yesno() {
 		1  '_"; set -- yes # code injection' \
 		0  truthful_nameref
 
+		# shellcheck disable=2034
 		truthful_nameref=yes
 
 		callback() {
@@ -433,8 +435,8 @@ fi
 # ecma48-cpr utility will not yet have been installed. Account for that by
 # redeclaring its shim function.
 if [ "${EBUILD_PHASE}" = test ]; then
-	export BUILD_DIR=${PWD}
-	_ecma48_cpr() { "${BUILD_DIR}"/ecma48-cpr "$@"; }
+	export BUILD_DIR="${PWD}"
+	_ecma48_cpr() { "${BUILD_DIR}"/ecma48-cpr; }
 fi
 
 assign_tmpdir


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-10  4:22 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-10  4:22 UTC (permalink / raw
  To: gentoo-commits

commit:     be8077d728a39ae606dc6ace51cb18fe45955f78
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Jun  9 20:30:57 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 20:45:18 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=be8077d7

test-functions: Ensure that ecma48-cpr can be resolved during src_test()

The test phase is run prior to the install phase. Compensate for this by
wrapping ecma48-cpr with a shim function and redeclaring said function
where the value of EBUILD_PHASE is equal to "test".

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>

 functions.sh.in | 6 +++++-
 test-functions  | 8 ++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/functions.sh.in b/functions.sh.in
index 3053162..673be7d 100644
--- a/functions.sh.in
+++ b/functions.sh.in
@@ -627,7 +627,7 @@ _update_winsize() {
 
 _update_cursor_coords() {
 	# shellcheck disable=2046
-	set -- $(@GENTOO_LIBEXEC_DIR@/ecma48-cpr)
+	set -- $(_ecma48_cpr)
 	if [ "$#" -eq 2 ] && is_int "$1" && is_int "$2"; then
 		genfun_y=$1
 		genfun_x=$2
@@ -638,6 +638,10 @@ _update_cursor_coords() {
 	fi
 }
 
+_ecma48_cpr() {
+	@GENTOO_LIBEXEC_DIR@/ecma48-cpr "$@"
+}
+
 # This is the main script, please add all functions above this point!
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS="yes"

diff --git a/test-functions b/test-functions
index 5a6b23b..0d7b1ab 100755
--- a/test-functions
+++ b/test-functions
@@ -408,6 +408,14 @@ if ! . ./functions.sh; then
 	bailout "Couldn't source ./functions.sh"
 fi
 
+# Since the test suite is normally executed during the src_test phase, the
+# ecma48-cpr utility will not yet have been installed. Account for that by
+# redeclaring its shim function.
+if [ "${EBUILD_PHASE}" = test ]; then
+	export BUILD_DIR=${PWD}
+	_ecma48_cpr() { "${BUILD_DIR}"/ecma48-cpr "$@"; }
+fi
+
 assign_tmpdir
 
 export TEST_GENFUNCS=1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-09 11:17 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-09 11:17 UTC (permalink / raw
  To: gentoo-commits

commit:     d06bd4a6b6dac170724c17cabd282fee4eb8f91e
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Fri Jun  9 11:16:11 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 11:16:11 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d06bd4a6

meson.build: drop libexecdir for now

Right now, I don't think there's much benefit for putting the ecma tool
in libexecdir given it's in /usr and everything assumes functions.sh is at
/lib/gentoo/functions.sh - i.e. it unnecessarily breaks split-usr.

Maybe we can just add some symlinks later though.

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/meson.build b/meson.build
index f86edd5..8996d95 100644
--- a/meson.build
+++ b/meson.build
@@ -10,7 +10,9 @@ project(
 
 conf_data = configuration_data()
 conf_data.set('version', meson.project_version())
-conf_data.set('GENTOO_LIBEXEC_DIR', get_option('prefix') / get_option('libexecdir') / 'gentoo')
+# For now, we can't really use libexec, given everyone hardcodes /lib/gentoo.
+# We might be able to install some symlinks to get around this though?
+conf_data.set('GENTOO_LIBEXEC_DIR', get_option('prefix') / 'lib' / 'gentoo')
 
 configure_file(
   input: 'functions.sh.in',
@@ -36,7 +38,7 @@ executable(
   'ecma48-cpr',
   'ecma48-cpr.c',
   install: true,
-  install_dir: get_option('prefix') / get_option('libexecdir') / 'gentoo'
+  install_dir: get_option('prefix') / 'lib' / 'gentoo'
 )
 
 do_tests = get_option('tests')


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-09 11:11 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-09 11:11 UTC (permalink / raw
  To: gentoo-commits

commit:     33e23d38b0235978641e29ea367a89614b7bc999
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Fri Jun  9 11:11:22 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 11:11:22 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=33e23d38

meson.build: fix running tests out of source

Signed-off-by: Sam James <sam <AT> gentoo.org>

 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 049812d..f86edd5 100644
--- a/meson.build
+++ b/meson.build
@@ -43,6 +43,6 @@ do_tests = get_option('tests')
 if do_tests
   test(
     'test-functions', files('test-functions'),
-    workdir : meson.current_source_dir(),
+    workdir : meson.current_build_dir(),
   )
 endif


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-09 11:02 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-09 11:02 UTC (permalink / raw
  To: gentoo-commits

commit:     2a78a15de6e5d90da0657bf74929993b1b51a337
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun  8 05:48:02 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 06:57:10 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2a78a15d

Add a chdir() function to act as a safer alternative to the cd builtin

To run cd "$dir" is problematic because:

1) it may consider its operand as an option
2) it will search CDPATH for an operand not beginning with ./, ../ or /
3) it will switch to OLDPWD if the operand is -
4) cdable_vars causes bash to treat the operand as a potential varname

This commit introduces a chdir() function that addresses all of these
pitfalls.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh   | 18 +++++++++++++++++
 test-functions | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/functions.sh b/functions.sh
index 7838c90..154c8a4 100644
--- a/functions.sh
+++ b/functions.sh
@@ -534,6 +534,24 @@ is_int() {
 	esac
 }
 
+#
+#   A safe wrapper for the cd builtin. To run cd "$dir" is problematic because:
+#
+#   1) it may consider its operand as an option
+#   2) it will search CDPATH for an operand not beginning with ./, ../ or /
+#   3) it will switch to OLDPWD if the operand is -
+#   4) cdable_vars causes bash to treat the operand as a potential variable name
+#
+chdir() {
+	if [ "$BASH" ]; then
+		shopt -u cdable_vars
+	fi
+	if [ "$1" = - ]; then
+		set -- ./-
+	fi
+	CDPATH= cd -- "$@"
+}
+
 #
 #   Determine whether the first operand contains any visible characters.
 #

diff --git a/test-functions b/test-functions
index b80587b..5a6b23b 100755
--- a/test-functions
+++ b/test-functions
@@ -14,7 +14,7 @@ bailout() {
 assign_tmpdir() {
 	# shellcheck disable=1007
 	dir=$(mktemp -d) \
-	&& CDPATH= cd -- "${dir}" \
+	&& chdir "${dir}" \
 	|| bailout "Couldn't create or change to the temp dir"
 }
 
@@ -24,6 +24,49 @@ cleanup_tmpdir() {
 	fi
 }
 
+test_chdir() {
+	set -- \
+		1  grandchild  \
+		1         var  \
+		0          -L  \
+		0          -p  \
+		0          -e  \
+		0          -@  \
+		0           -  \
+		0       child
+
+	if ! mkdir -p -- -L -p -e -@ - child child/grandchild; then
+		bailout "Couldn't set up all test directories"
+	fi
+
+	callback() {
+		shift
+		test_description="chdir $(print_args "$@")"
+		if [ "$BASH" ]; then
+			shopt -s cdable_vars
+		fi
+		CDPATH=child var=$CDPATH chdir "$@" \
+		&& test "$PWD" != "$OLDPWD" \
+		&& cd - >/dev/null
+	}
+
+	iterate_tests 2 "$@"
+}
+
+test_chdir_noop() {
+	set -- 0 ''
+
+	callback() {
+		shift
+		test_description="chdir $(print_args "$@")"
+		chdir "$@" \
+		&& test "$PWD" = "$OLDPWD" \
+		|| { cd - >/dev/null; false; }
+	}
+
+	iterate_tests 2 "$@"
+}
+
 test_is_older_than() {
 	set -- \
 		1  N/A           N/A \
@@ -317,12 +360,24 @@ iterate_tests() {
 			fi
 		done
 		eval "${code}"
-		if [ "$?" -eq "$1" ]; then
+		case $? in
+			0)
+				test "$?" -eq "$1"
+				;;
+			*)
+				test "$?" -ge "$1"
+		esac
+		if [ "$?" -eq 0 ]; then
 			passed=$((passed + 1))
 		else
 			printf 'not '
 		fi
-		printf 'ok %d - %s (expecting %d)\n' "${i}" "${test_description}" "$1"
+		if [ "$1" -eq 0 ]; then
+			expected=$1
+		else
+			expected=">=$1"
+		fi
+		printf 'ok %d - %s (expecting %s)\n' "${i}" "${test_description}" "${expected}"
 		shift "${slice_width}"
 	done
 	return "$(( passed < total ))"
@@ -359,6 +414,8 @@ export TEST_GENFUNCS=1
 export TZ=UTC
 
 rc=0
+test_chdir || rc=1
+test_chdir_noop || rc=1
 ( ewarn() { true; }; test_is_older_than ) || rc=1
 test_get_bootparam || rc=1
 test_esyslog || rc=1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-09 11:02 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-09 11:02 UTC (permalink / raw
  To: gentoo-commits

commit:     e08b541e2c875d7718d4452bbd8bb1228bd1a53b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Jun  6 03:54:50 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun  7 11:14:24 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=e08b541e

Introduce a utility to obtain the cursor coordinates via ECMA-48 CPR

The ECMA-48 specification defines the CPR (Cursor Position Report)
sequence which, as its name implies, instructs the terminal to divulge
the present coordinates of the cursor. Though it is theoretically
possible to make use of this sequence by using the shell and standard
utilities, it would be tremendously costly and somewhat unreliable to
do so. This commit introduces a utility - written in C - that does the
job.

Its behaviour is quite simple. If STDIN is found to be a terminal, an
attempt will be made to initiate - and read - a Cursor Position Report.
Upon success, the present row and column of the cursor shall be printed
as two space-separated decimal integers. Otherwise, a diagnostic
message shall be printed to STDERR, and the utility shall exit with
a non-zero status.

This utility will be used by the impending overhaul of the _eprint()
and _eend() functions.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 ecma48-cpr.c | 230 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 230 insertions(+)

diff --git a/ecma48-cpr.c b/ecma48-cpr.c
new file mode 100644
index 0000000..9aef182
--- /dev/null
+++ b/ecma48-cpr.c
@@ -0,0 +1,230 @@
+/*
+ * ecma48-cpr.c
+ * Treat STDIN as a tty and report the cursor position using the CPR sequence.
+ *
+ * Originally distributed as wsize.c by Stephen J. Friedl <steve@unixwiz.net>.
+ * Repurposed for gentoo-functions by Kerin F. Millar <kfm@plushkava.net>.
+ * This software is in the public domain.
+ */
+
+#define _POSIX_C_SOURCE 200809L
+
+#define PROGRAM "ecma48-cpr"
+#define READ_TIMEOUT_NS 250000000
+#define BUFSIZE 100
+#define MAX_LOOPS 20
+
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <time.h>
+#include <unistd.h>
+
+static struct termios save_tty;
+static bool is_timed_out = false;
+static bool is_tty_saved = false;
+
+static void cleanup(void);
+static void die(char const * const errmsg);
+static void on_signal(int const signo);
+
+#ifndef __APPLE__
+static timer_t init_timer(void);
+#endif
+
+int
+main(void) {
+	/*
+	 * Establish that STDIN is a terminal.
+	 */
+	if (! isatty(STDIN_FILENO)) {
+		die("cannot determine the cursor position because stdin is not a tty");
+	}
+
+	/*
+	 * Duplicate STDIN to a new file descriptor before reopening it as a
+	 * writeable stream.
+	 */
+	int fd = dup(STDIN_FILENO);
+	FILE *tty;
+	if (fd < 0) {
+		die("failed to dup stdin");
+	} else {
+		tty = fdopen(fd, "w");
+		if (tty == NULL) {
+			die("failed to re-open the tty for writing");
+		}
+	}
+
+	/*
+	 * Save the current terminal settings.
+	 */
+	if (tcgetattr(STDIN_FILENO, &save_tty) != 0) {
+		die("failed to obtain the current terminal settings");
+	} else {
+		is_tty_saved = true;
+	}
+
+	/*
+	 * Duplicate the current terminal settings for modification.
+	 */
+	struct termios new_tty = save_tty;
+	new_tty = save_tty;
+
+	/*
+	 * Turn off ECHO, so that the response from the terminal isn't printed.
+	 * Also, the terminal must be operating in its noncanonical mode,
+	 * thereby ensuring that its input is always immediately available,
+	 * with no processing having been performed.
+	 */
+	new_tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL);
+	new_tty.c_lflag &= ~(ICANON);
+
+	/*
+	 * Set an interbyte timeout of 1 decisecond. The timer is started only
+	 * after the first byte is read, so read(2) will block until then.
+	 */
+	new_tty.c_cc[VMIN]  = 1;
+	new_tty.c_cc[VTIME] = 1;
+
+	/*
+	 * Try to apply the new terminal settings.
+	 */
+	if (tcsetattr(STDIN_FILENO, TCSANOW, &new_tty) != 0) {
+		die("failed to modify the terminal settings");
+	} else if (fprintf(tty, "\033[6n") != 4) {
+		die("failed to write the CPR sequence to the terminal");
+	} else if (fclose(tty) != 0) {
+		die("failed to flush the stream after writing the CPR sequence");
+	}
+
+	/*
+	 * Prepare to catch our signals. We treat both an interrupt and a
+	 * depleted timer as essentially the same thing: fatal errors.
+	 */
+	struct sigaction act;
+	act.sa_handler = on_signal;
+	sigemptyset(&act.sa_mask);
+	act.sa_flags = 0;
+	sigaction(SIGALRM, &act, NULL);
+
+	/*
+	 * A timeout is required, just in case read(2) proves unable to read an
+	 * initial byte, otherwise causing the program to hang.
+	 */
+#ifdef __APPLE__
+	alarm(1);
+#else
+	timer_t timerid = init_timer();
+#endif
+
+	/*
+	 * Read up to (sizeof ibuf - 1) bytes of input in total. Upon each
+	 * successful read, scan the input buffer for a valid ECMA4-8 CPR
+	 * response. Abort if no such response is found within MAX_LOOPS
+	 * iterations.
+	 */
+	char ibuf[BUFSIZE];
+	char const * const imax = ibuf + sizeof ibuf - 1;
+	char *iptr = ibuf;
+	int maxloops = MAX_LOOPS;
+	int row = -1;
+	int col = -1;
+	ssize_t nr;
+	while (--maxloops > 0 && (nr = read(STDIN_FILENO, iptr, imax - iptr)) > 0) {
+		iptr += nr;
+		*iptr = '\0'; /* NUL-terminate for strchr(3) and sscanf(3) */
+		char const *p;
+		if ((p = strchr(ibuf, '\033')) != 0) {
+			if (sscanf(p, "\033[%d;%dR", &row, &col) == 2) {
+				break;
+			} else {
+				col = -1;
+				row = -1;
+			}
+		}
+	}
+
+	/*
+	 * Deactivate the timer.
+	 */
+#ifdef __APPLE__
+	alarm(0);
+#else
+	timer_delete(timerid);
+#endif
+
+	/*
+	 * Die in the case that the timer fired.
+	 */
+	if (is_timed_out) {
+		die("timed out waiting for the terminal to respond to CPR");
+	}
+
+	/*
+	 * Restore the original terminal settings.
+	 */
+	cleanup();
+
+	/*
+	 * Print the cursor position, provided both col and row are above zero.
+	 */
+	if (col < 1 || row < 1) {
+		die("failed to read the cursor position");
+	} else if (printf("%d %d\n", row, col) == -1 || fflush(stdout) == EOF) {
+		return EXIT_FAILURE;
+	} else {
+		return EXIT_SUCCESS;
+	}
+}
+
+#ifndef __APPLE__
+static timer_t
+init_timer(void) {
+	struct itimerspec timer;
+	struct sigevent event;
+	timer_t timerid;
+	event.sigev_notify = SIGEV_SIGNAL;
+	event.sigev_signo = SIGALRM;
+	event.sigev_value.sival_ptr = &timerid;
+	if (timer_create(CLOCK_REALTIME, &event, &timerid) == -1) {
+		die("failed to create a per-process timer");
+	} else {
+		timer.it_value.tv_sec = 0;
+		timer.it_value.tv_nsec = READ_TIMEOUT_NS;
+		timer.it_interval.tv_sec = 0;
+		timer.it_interval.tv_nsec = 0;
+		if (timer_settime(timerid, 0, &timer, NULL) == -1) {
+			die("failed to configure the per-process timer");
+		}
+	}
+	return timerid;
+}
+#endif
+
+/*
+ * Tries to restore the terminal settings. Only one attempt will ever be made.
+ */
+static void
+cleanup(void) {
+	bool const is_saved = is_tty_saved;
+	if (is_saved) {
+		tcsetattr(STDIN_FILENO, TCSANOW, &save_tty);
+		is_tty_saved = false;
+	}
+}
+
+static void
+die(char const * const errmsg) {
+	cleanup();
+	fprintf(stderr, "%s: %s\n", PROGRAM, errmsg);
+	exit(EXIT_FAILURE);
+}
+
+static void
+on_signal(int const signo) {
+	is_timed_out = true;
+}


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-09 11:02 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-09 11:02 UTC (permalink / raw
  To: gentoo-commits

commit:     20bc15b5b1009149c4a3d531911d3c219dc55f3a
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Jun  6 04:07:13 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 06:57:07 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=20bc15b5

Overhaul _eprint() and _eend() so as to better leverage smart terminals

This commit introduces a function named _update_tty_level(), whose
reponsibility is to grade the capability of the terminal, if any, on a
scale of 0 to 2. A value of 0 indicates that no terminal has been
detected, 1 that a dumb terminal has been detected, while 2 indicates
that a smart terminal has been detected. For the terminal to be
considered as smart, all of the following conditions must hold true.

- the TERM variable must not contain "dumb" as a substring
- the stty(1) utility must be able to report the terminal's dimensions
- the cursor's position must be reported for the ECMA-48 CPR sequence

Both the _eprint() and _eend() functions have been adjusted, so as to
evaluate the terminal's capabilites on each occasion that they are
called, with the overall intention of better exploiting the capabilities
of modern terminals, thus providing a better experience for a majority
of Gentoo users. These adjustments are described herewith.

Common to both functions is that the mechanism of tracking whether a
<newline> character is pending for the last printed message is no longer
employed for smart terminals.

As concerns _eprint(), it now begins by not only determining whether a
terminal is attached to STDOUT, but whether it is a smart terminal. In
the case that it is smart, it shall be determined whether the cursor is
situated at the first column. Should it not be, a <newline> character
shall be emitted, on the basis that the last call may have been to a
function that printed a message without a trailing <newline>.

Next, the message shall be checked, so as to determine whether it
contains a trailing <newline> character. Should it not, the message
shall be printed, along with a trailing DECSC sequence. The effect of
this sequence is to instruct the terminal emulator to save the current
position of the cursor.

If, on the other hand, the message is found to contain a trailing
<newline> character, it shall be stripped prior to printing the message.
The terminal shall then be asked to report the new position of the
cursor. Should the cursor turn out to be situated at the very last row
of the terminal, it shall be assumed that vertical scrolling is about to
occur and the cursor shall be moved up by one row, prior to its position
being saved by way of the DECSC sequence. Thereafter, two <newline>
characters shall be printed, so as to advance to the next line (relative
to the message). Otherwise, should the cursor be found to be situated at
a row that precedes the last row of the terminal, the DECSC sequence
shall be emitted, followed by a single <newline> character.

Note that the overall intention is to stash the exact position of the
cursor at the point that it is situated at the end of the printed
message, but just before a <newline> is printed (if any).

As concerns _eend(), and as with _eprint(), it now begins by not only
determining whether a terminal is attached to STDOUT, but whether it is
a smart terminal, though not before saving the last-known dimensions
of the terminal. Next, in the case of a dumb terminal - or no terminal
at all - the message shall be printed with a single preceding space.
That is, no attempt shall be made to right-align the success/failure
indicator. If, on the other hand, the terminal is found to be smart, the
behaviour shall be as described by the next paragraph.

The current dimensions of the terminal shall be compared against the
last-known dimensions of the terminal, as they were prior to the
terminal grading procedure. The purpose of doing so is to determine
whether the terminal has been recently resized. For the terminal not to
have been resized implies that it may yet be possible to write the
success/failure indicator on the very same row as the last printed
message, even if it were <newline>-terminated. With that in mind, the
current position of the cursor shall be saved. Next, the DECRC sequence
shall be emitted to the terminal. The effect of this sequence is to
instruct the terminal emulator to restore the position of the cursor,
as was saved by the DECSC sequence. In other words, the cursor position
shall be moved to wherever it was just after the last message was
printed, albeit before the trailing <newline> character (if any). Next,
the terminal shall be asked to report the new position of the cursor. In
the event that the cursor is found to have moved to any other row than
the immediately preceding one, it shall be assumed that scrolling has
occurred since printing the last message, in which case the cursor shall
be moved back to its prior position. Otherwise, the cursor shall be left
at its present position.

With that out of the way, the degree of indentation required to
right-align the indicator shall be trivially calculated by deducting
the present column number from the total number of columns spanned by
the terminal, with a further 6 deducted to account for the width of the
indicator. Should the resulting value be greater than 0, the cursor
shall be shifted that many cells to the right. Should the resulting
value be negative, it shall be recognised that there is insufficient
room to print the indicator on the same line and, instead, the indicator
shall be printed on the next line. Should the resulting value be 0, it
shall be recognised that the cursor is already situated at the correct
column.

Finally, the indicator shall be printed, along with a trailing <newline>
character.

As a consequence of these changes, the genfun_endcol variable has been
eliminated, as it is no longer required.

It should be noted that both DECSC and DECRC are private mode sequences,
and are, thus, not defined by ECMA-48. However, they were introduced by
DEC for the VT100 terminal, which was released in 1978. As such, they
can be considered as a de-facto standard.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 209 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 165 insertions(+), 44 deletions(-)

diff --git a/functions.sh b/functions.sh
index 34bb266..7838c90 100644
--- a/functions.sh
+++ b/functions.sh
@@ -9,6 +9,11 @@
 # intended for internal use shall be prefixed with "genfun_" to indicate so,
 # and to reduce the probability of name space conflicts.
 
+# FIXME. There is just one invocation of ./ecma48-cpr, which can be found in
+# the _update_cursor_coords function. If you think it should be named sometime
+# else, I'm open to suggestions. Its behaviour now resembles that of stty size,
+# except that it reports the cursor coordinates (obviously).
+
 #
 #    Called by ebegin, eerrorn, einfon, and ewarnn.
 #
@@ -17,17 +22,72 @@ _eprint() {
 	color=$1
 	shift
 
-	msg=$*
-	if [ -t 1 ]; then
-		printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "${msg}"
-	else
-		printf ' * %s%s' "${genfun_indent}" "${msg}"
+	# Check whether STDOUT is a terminal, and how capable it is.
+	_update_tty_level <&1
+
+	if [ "${genfun_tty}" -eq 2 ]; then
+		# If the cursor is not situated on column 1, print a LF
+		# character. The assumption here is that the last call may have
+		# been via ebegin, or any of the other printing functions that
+		# pass a message without a trailing LF.
+		if [ "${genfun_x}" -ne 1 ]; then
+			printf '\n'
+		fi
+	elif [ "${genfun_is_pending_lf}" -eq 1 ]; then
+		# We are about to print to a dumb terminal or something other
+		# than a terminal. Print a LF character because the last printed
+		# message did not end with one. This technique is not ideal.
+		# For one thing, it can be thwarted by having called a printing
+		# function from a subshell or a shell launched by a subprocess,
+		# because the change to the flag variable would be lost. For
+		# another, it's possible for the user of the library to be
+		# directing STDOUT/STDERR to different places between calls.
+		# Such weaknesses cannot be addressed without some form of IPC.
+		printf '\n'
 	fi
 
-	if _ends_with_newline "${msg}"; then
-		genfun_is_pending_lf=0
+	msg=$*
+	if [ "${genfun_tty}" -lt 2 ]; then
+		if [ "${genfun_tty}" -eq 1 ]; then
+			# Print but do not attempt to save the cursor position.
+			printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "${msg}"
+		else
+			printf ' * %s%s' "${genfun_indent}" "${msg}"
+		fi
+		if _ends_with_newline "${msg}"; then
+			genfun_is_pending_lf=0
+		else
+			# Record the fact that a LF character is pending.
+			genfun_is_pending_lf=1
+		fi
+	elif ! _ends_with_newline "${msg}"; then
+		# Print the message before saving the cursor position with the
+		# DECSC sequence. This is a private mode sequence that is not
+		# defined by ECMA-48. However, it was introduced by DEC for the
+		# VT100 and can be considered as a de-facto standard.
+		printf ' %s*%s %s%s\0337' "${color}" "${NORMAL}" "${genfun_indent}" "${msg}"
 	else
-		genfun_is_pending_lf=1
+		# Print the message without its trailing LF character.
+		msg=${msg%"${genfun_newline}"}
+		printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "${msg}"
+
+		# Determine the current position of the cursor
+		_update_cursor_coords <&1
+
+		if [ "${genfun_y}" -ne "${genfun_rows}" ]; then
+			# Have the terminal save the position of the cursor
+			# with DECSC before printing a LF character to advance
+			# to the next line.
+			printf '\0337\n'
+		else
+			# The cursor is situated on the last row of the
+			# terminal, meaning that vertical scrolling will occur.
+			# Move the cursor up by one row with CUU (ECMA-48 CSI)
+			# before having the terminal save the position of the
+			# cursor with DECSC. Finally, print two LF characters to
+			# advance to the next line.
+			printf '\033[1A\0337\n\n'
+		fi
 	fi
 }
 
@@ -181,7 +241,7 @@ ebegin()
 	if ! yesno "${EINFO_QUIET}"; then
 		msg=$*
 		msg=${msg%"${genfun_newline}"}
-		_eprint "${GOOD}" "${msg} ...${genfun_newline}"
+		_eprint "${GOOD}" "${msg} ..."
 	fi
 }
 
@@ -191,7 +251,7 @@ ebegin()
 #
 _eend()
 {
-	local efunc is_tty msg retval
+	local efunc indent msg offset retval
 
 	efunc=$1
 	shift
@@ -200,28 +260,26 @@ _eend()
 	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
-		shift
+		msg=
 	else
 		retval=$1
 		shift
+		msg=$*
 	fi
 
-	if [ -t 1 ]; then
-		is_tty=1
-	else
-		is_tty=0
-	fi
+	# Stash the last known terminal dimensions, if any.
+	set -- "${genfun_cols}" "${genfun_rows}"
+
+	# Check whether STDOUT is a terminal, and how capable it is.
+	_update_tty_level <&1
 
 	if [ "${retval}" -ne 0 ]; then
 		# If a message was given, print it with the specified function.
-		if [ "$#" -gt 0 ]; then
-			msg=$*
-			if _is_visible "${msg}"; then
-				"${efunc}" "${msg}"
-			fi
+		if _is_visible "${msg}"; then
+			"${efunc}" "${msg}"
 		fi
 		# Generate an indicator for ebegin's unsuccessful conclusion.
-		if [ "${is_tty}" -eq 0 ]; then
+		if [ "${genfun_tty}" -eq 0 ]; then
 			msg="[ !! ]"
 		else
 			msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
@@ -230,28 +288,65 @@ _eend()
 		return "${retval}"
 	else
 		# Generate an indicator for ebegin's successful conclusion.
-		if [ "${is_tty}" -eq 0 ]; then
+		if [ "${genfun_tty}" -eq 0 ]; then
 			msg="[ ok ]"
 		else
 			msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
 		fi
 	fi
 
-	if [ "${is_tty}" -eq 1 ] && [ -n "${genfun_endcol}" ]; then
-		# Should a LF character be pending then print one. The CUU
-		# (ECMA-48 CSI) sequence will move the cursor up by one line
-		# prior to printing the indicator, right-justified.
-		if [ "${genfun_is_pending_lf}" -eq 1 ]; then
-			printf '\n'
-		fi
-		printf '%b %s\n' "${genfun_endcol}" "${msg}"
+	if [ "${genfun_tty}" -lt 2 ]; then
+		printf ' %s\n' "${msg}"
+		genfun_is_pending_lf=0
 	else
+		# Provided that the terminal has not since been resized, it may
+		# be possible to write the indicator on the same row as the
+		# last printed message, even if it were LF-terminated.
+		if [ "${genfun_cols}" -eq "$1" ] && [ "${genfun_rows}" -eq "$2" ]; then
+			# Stash the current position of the cursor.
+			set -- "${genfun_x}" "${genfun_y}"
+
+			# Using the DECRC sequence, restore the cursor position
+			# to wherever it was just after the last message was
+			# printed, but before the trailing LF character, if any.
+			# This is a private mode sequence, and thus not defined
+			# by ECMA-48. However, it was introduced by DEC for the
+			# VT100 and can be considered as a de-facto standard.
+			printf '\0338'
+
+			# Determine the position of the cursor again.
+			_update_cursor_coords <&1
+
+			# Check whether the act of restoring the cursor position
+			# moved it to a different row, excepting the immediately
+			# preceding row. If it did, assume that scrolling has
+			# occurred since printing the last message and move the
+			# cursor back to where it was with CUP (ECMA-48 CSI).
+			offset=$(( $2 - genfun_y ))
+			if [ "${offset}" -lt 0 ] || [ "${offset}" -gt 1 ]; then
+				printf '\033[%d;%dH' "$1" "$2"
+				genfun_x=$1
+			fi
+		fi
+
+		# Calculate the column at which the indicator may be printed.
+		indent=$(( genfun_cols - genfun_x - 6 ))
+
+		# Determine whether the cursor needs to be repositioned.
+		if [ "${indent}" -gt 0 ]; then
+			# Use CHA (ECMA-48 CSI) to move the cursor to the right.
+			printf '\033[%dG' "$(( genfun_x + indent ))"
+		elif [ "${indent}" -lt 0 ]; then
+			# The indent is negative, meaning that there is not
+			# enough room. Arrange for the indicator to be printed
+			# on the next line instead.
+			printf '\n\033[%dG' "$(( genfun_cols - 6 ))"
+		fi
+
+		# Finally, print the indicator.
 		printf ' %s\n' "${msg}"
 	fi
 
-	# Record the fact that a LF character is no longer pending.
-	genfun_is_pending_lf=0
-
 	return "${retval}"
 }
 
@@ -479,6 +574,27 @@ _ends_with_newline() {
 	! case $1 in *"${genfun_newline}") false ;; esac
 }
 
+_update_tty_level() {
+	# Grade the capability of the terminal attached to STDIN (if any) on a
+	# scale of 0 to 2, assigning the resulting value to genfun_tty. If no
+	# terminal is detected, the value shall be 0. If a dumb terminal is
+	# detected, the value shall be 1. If a smart terminal is detected, the
+	# value shall be 2.
+	#
+	# In the case that a smart terminal is detected, its dimensions shall
+	# be assigned to genfun_cols and genfun_rows, and the position of the
+	# cursor shall be assigned to genfun_x and genfun_y. Further, it may
+	# reasonably be assumed that the ECMA-48 CSI and DECSC/DECRC escape
+	# sequences are supported.
+	if [ ! -t 0 ]; then
+		genfun_tty=0
+	elif _has_dumb_terminal || ! _update_winsize || ! _update_cursor_coords; then
+		genfun_tty=1
+	else
+		genfun_tty=2
+	fi
+}
+
 _update_winsize() {
 	# The following use of stty(1) is portable as of POSIX Issue 8. It would
 	# be beneficial to leverage the checkwinsize option in bash but the
@@ -486,7 +602,7 @@ _update_winsize() {
 	# it may eventually become possible to support it.
 	# shellcheck disable=2046
 	set -- $(stty size 2>/dev/null)
-	if is_int "$1" && is_int "$2" && [ "$1" -gt 0 ] && [ "$2" -gt 0 ]; then
+	if [ "$#" -eq 2 ] && is_int "$1" && is_int "$2"; then
 		genfun_rows=$1
 		genfun_cols=$2
 	else
@@ -496,6 +612,19 @@ _update_winsize() {
 	fi
 }
 
+_update_cursor_coords() {
+	# shellcheck disable=2046
+	set -- $(./ecma48-cpr)
+	if [ "$#" -eq 2 ] && is_int "$1" && is_int "$2"; then
+		genfun_y=$1
+		genfun_x=$2
+	else
+		genfun_y=
+		genfun_x=
+		false
+	fi
+}
+
 # This is the main script, please add all functions above this point!
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS="yes"
@@ -530,20 +659,12 @@ else
 	done
 fi
 
-if _has_dumb_terminal || ! _update_winsize; then
-	unset -v genfun_endcol
-else
-	# Set some ECMA-48 CSI sequences (CUU and CUF) for cursor positioning.
-	# These are standard and, conveniently, documented by console_codes(4).
-	genfun_endcol="\\033[A\\033[$(( genfun_cols - 7 ))C"
-fi
-
 if _has_monochrome_terminal || yesno "${RC_NOCOLOR}"; then
 	unset -v BAD BRACKET GOOD HILITE NORMAL WARN
 else
 	# Define some ECMA-48 SGR sequences for color support. These variables
 	# are public, in so far as users of the library may be expanding them.
-	# The sequences are also documented by console_codes(4).
+	# Conveniently, these sequences are documented by console_codes(4).
 	BAD=$(printf '\033[31;01m')
 	BRACKET=$(printf '\033[34;01m')
 	GOOD=$(printf '\033[32;01m')


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-09 11:02 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-09 11:02 UTC (permalink / raw
  To: gentoo-commits

commit:     16f347ffdff4da72d9a262a82f32777229c413b2
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Fri Jun  9 00:38:23 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  9 06:57:10 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=16f347ff

Port to Meson

... yielding
```
/tmp/destdir
└── usr
    └── local
        ├── bin
        │   └── consoletype
        ├── lib
        │   └── gentoo
        │       └── functions.sh
        ├── libexec
        │   └── gentoo
        │       └── ecma48-cpr
        └── share
            └── man
                └── man1
                    └── consoletype.1
11 directories, 4 files
```

Signed-off-by: Sam James <sam <AT> gentoo.org>

 Makefile                        | 39 ---------------------------------
 functions.sh => functions.sh.in |  7 +-----
 meson.build                     | 48 +++++++++++++++++++++++++++++++++++++++++
 meson_options.txt               |  3 +++
 4 files changed, 52 insertions(+), 45 deletions(-)

diff --git a/Makefile b/Makefile
deleted file mode 100644
index 3fa8d85..0000000
--- a/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-# gentoo-functions Makefile
-# Copyright 2014-2023 Gentoo Authors
-# Distributed under the terms of the GNU General Public License v2
-
-VERSION = 0.20
-GITREF ?= $(VERSION)
-PKG ?= gentoo-functions-$(VERSION)
-
-ROOTPREFIX ?=
-ROOTSBINDIR ?= $(ROOTPREFIX)/sbin
-ROOTLIBEXECDIR ?= $(ROOTPREFIX)/lib/gentoo
-
-PREFIX ?= /usr
-MANDIR ?= $(PREFIX)/share/man
-
-PROGRAMS = consoletype
-
-all: $(PROGRAMS)
-
-check: all
-	./test-functions
-
-install: all
-	install -m 0755 -d $(DESTDIR)$(ROOTSBINDIR)
-	install -m 0755 consoletype $(DESTDIR)$(ROOTSBINDIR)
-	install -m 0755 -d $(DESTDIR)$(ROOTLIBEXECDIR)
-	install -m 0644 functions.sh $(DESTDIR)$(ROOTLIBEXECDIR)
-	install -m 0755 -d $(DESTDIR)$(MANDIR)/man1
-	install -m 0644 consoletype.1 $(DESTDIR)$(MANDIR)/man1
-
-clean:
-	rm -rf $(PROGRAMS)
-
-dist:
-	git archive --prefix=$(PKG)/ $(GITREF) | xz > $(PKG).tar.xz
-
-consoletype: consoletype.c
-
-# vim: set ts=4 :

diff --git a/functions.sh b/functions.sh.in
similarity index 98%
rename from functions.sh
rename to functions.sh.in
index 154c8a4..3053162 100644
--- a/functions.sh
+++ b/functions.sh.in
@@ -9,11 +9,6 @@
 # intended for internal use shall be prefixed with "genfun_" to indicate so,
 # and to reduce the probability of name space conflicts.
 
-# FIXME. There is just one invocation of ./ecma48-cpr, which can be found in
-# the _update_cursor_coords function. If you think it should be named sometime
-# else, I'm open to suggestions. Its behaviour now resembles that of stty size,
-# except that it reports the cursor coordinates (obviously).
-
 #
 #    Called by ebegin, eerrorn, einfon, and ewarnn.
 #
@@ -632,7 +627,7 @@ _update_winsize() {
 
 _update_cursor_coords() {
 	# shellcheck disable=2046
-	set -- $(./ecma48-cpr)
+	set -- $(@GENTOO_LIBEXEC_DIR@/ecma48-cpr)
 	if [ "$#" -eq 2 ] && is_int "$1" && is_int "$2"; then
 		genfun_y=$1
 		genfun_x=$2

diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..049812d
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,48 @@
+project(
+  'gentoo-functions', 'c',
+  version: '0.20',
+  license: 'GPL-2.0-only',
+  default_options : [
+    'warning_level=2',
+    'c_std=gnu11',
+  ]
+)
+
+conf_data = configuration_data()
+conf_data.set('version', meson.project_version())
+conf_data.set('GENTOO_LIBEXEC_DIR', get_option('prefix') / get_option('libexecdir') / 'gentoo')
+
+configure_file(
+  input: 'functions.sh.in',
+  output: 'functions.sh',
+  configuration: conf_data,
+  install: true,
+  install_dir: 'lib/gentoo'
+)
+
+cc = meson.get_compiler('c')
+
+executable(
+  'consoletype',
+  'consoletype.c',
+  install: true
+)
+
+install_man(
+  'consoletype.1',
+)
+
+executable(
+  'ecma48-cpr',
+  'ecma48-cpr.c',
+  install: true,
+  install_dir: get_option('prefix') / get_option('libexecdir') / 'gentoo'
+)
+
+do_tests = get_option('tests')
+if do_tests
+  test(
+    'test-functions', files('test-functions'),
+    workdir : meson.current_source_dir(),
+  )
+endif

diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..7fbab2d
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,3 @@
+option('tests', type : 'boolean', value : true,
+  description : 'Build tests'
+)


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-07 11:13 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-07 11:13 UTC (permalink / raw
  To: gentoo-commits

commit:     17aa01321a250b99fa487e8be430d71a459e75e6
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun  5 02:42:26 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun  7 11:12:53 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=17aa0132

test-functions: Add a test for the is_identifier() function

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/test-functions b/test-functions
index 2c1fa67..892a255 100755
--- a/test-functions
+++ b/test-functions
@@ -160,6 +160,61 @@ test_esyslog() {
 	iterate_tests 5 "$@"
 }
 
+test_is_identifier() {
+	set -- \
+		1   ''   \
+		1    _   \
+		1    0   \
+		1   0a   \
+		1   0Z   \
+		1    9   \
+		1   9a   \
+		1   9Z   \
+		1   /a   \
+		1   /Z   \
+		1   .a   \
+		1   .Z   \
+		1   [a   \
+		1   [Z   \
+		1  '`a'  \
+		1  '`Z'  \
+		1   {a   \
+		1   {Z   \
+		1  '|a'  \
+		1  '|Z'  \
+		1   a/   \
+		1   Z/   \
+		1   a.   \
+		1   Z.   \
+		1   a[   \
+		1   Z[   \
+		1  'a`'  \
+		1  'Z`'  \
+		1   a{   \
+		1   Z{   \
+		1  'a|'  \
+		1  'Z|'  \
+		0    a   \
+		0    Z   \
+		0   __   \
+		0   _a   \
+		0   _Z   \
+		0   a_   \
+		0   Z_   \
+		0  a_a   \
+		0  a_Z   \
+		0  Z_a   \
+		0  Z_Z
+
+		callback() {
+			shift
+			test_description="is_identifier $(print_args "$@")"
+			is_identifier "$@"
+		}
+
+		iterate_tests 2 "$@"
+}
+
 test_is_int() {
 	set -- \
 		1  N/A \
@@ -287,6 +342,7 @@ rc=0
 test_is_older_than || rc=1
 test_get_bootparam || rc=1
 test_esyslog || rc=1
+test_is_identifier || rc=1
 test_is_int || rc=1
 test_yesno || rc=1
 cleanup_tmpdir


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-07 11:13 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-07 11:13 UTC (permalink / raw
  To: gentoo-commits

commit:     b7245f936e1cd16aad6d9c7481fd0b52b2371703
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 25 00:55:20 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun  7 11:12:18 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b7245f93

Add and integrate the _update_winsize() function

This new function assumes responsibility for updating the genfun_cols
variable. Additionally, it assumes responsibility for updating the newly
introduced genfun_rows variable.

As before, stty(1) is used to determine the dimensions of the terminal.
The approach has been slightly altered so as to incur just one subshell
in the course of doing so. The reason for this is that changes will soon
be made to the _eprint() and _eend() functions that require for the
function to be called repeatedly, not merely at the time of sourcing
functions.sh.

Should stty(1) fail - or produce nonsensical output - it will no longer
be assumed that there are 80 available columns. The requirement for the
"[ ok ]" and "[ !! ]" indicators to always be indented was recently
eliminated, so there is no longer any need to falsify a value for
genfun_cols.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 42 ++++++++++++++++++------------------------
 1 file changed, 18 insertions(+), 24 deletions(-)

diff --git a/functions.sh b/functions.sh
index 44a6dce..c326af4 100644
--- a/functions.sh
+++ b/functions.sh
@@ -477,6 +477,23 @@ _ends_with_newline() {
 	! case $1 in *"${genfun_newline}") false ;; esac
 }
 
+_update_winsize() {
+	# The following use of stty(1) is portable as of POSIX Issue 8. It would
+	# be beneficial to leverage the checkwinsize option in bash but the
+	# implementation is buggy. Given that Chet has agreed to investigate,
+	# it may eventually become possible to support it.
+	# shellcheck disable=2046
+	set -- $(stty size 2>/dev/null)
+	if is_int "$1" && is_int "$2" && [ "$1" -gt 0 ] && [ "$2" -gt 0 ]; then
+		genfun_rows=$1
+		genfun_cols=$2
+	else
+		genfun_rows=
+		genfun_cols=
+		false
+	fi
+}
+
 # This is the main script, please add all functions above this point!
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS="yes"
@@ -511,30 +528,7 @@ else
 	done
 fi
 
-# Try to determine the number of available columns in the terminal.
-for _ in 1 2; do
-	case $_ in
-		1)
-			# This use of stty(1) is portable as of POSIX Issue 8.
-			genfun_cols=$(
-				stty size 2>/dev/null | {
-					if IFS=' ' read -r _ cols; then
-						printf '%s\n' "${cols}"
-					fi
-				}
-			)
-			;;
-		2)
-			# Give up and assume 80 available columns.
-			genfun_cols=80
-			break
-	esac
-	if is_int "${genfun_cols}" && [ "${genfun_cols}" -gt 0 ]; then
-		break
-	fi
-done
-
-if _has_dumb_terminal; then
+if _has_dumb_terminal || ! _update_winsize; then
 	unset -v genfun_endcol
 else
 	# Set some ECMA-48 CSI sequences (CUU and CUF) for cursor positioning.


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-07 11:13 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-07 11:13 UTC (permalink / raw
  To: gentoo-commits

commit:     bf2c509abfe1bcd2835531861425d2f33c06e13e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 24 19:27:32 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun  7 11:12:18 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=bf2c509a

Drop support for the checkwinsize feature of bash

While there is nothing wrong with the way in which it is presently
being used, the feature is sufficiently bug-ridden that it will not work
correctly with the impending overhaul of the _eprint() and _eend()
functions. As such, drop support for it in advance. Chet has pledged to
treat my bug report as a feature request, so it may yet be possible to
re-introduce support for it in the future.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Bug: https://lists.gnu.org/archive/html/bug-bash/2023-02/msg00142.html
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/functions.sh b/functions.sh
index 78317b3..44a6dce 100644
--- a/functions.sh
+++ b/functions.sh
@@ -512,19 +512,9 @@ else
 fi
 
 # Try to determine the number of available columns in the terminal.
-for _ in 1 2 3; do
+for _ in 1 2; do
 	case $_ in
 		1)
-			# Running an external command causes bash >=4.3 to set
-			# the COLUMNS variable, provided that the checkwinsize
-			# shopt is enabled. As of 5.0, it's enabled by default.
-			# shellcheck disable=3044
-			if [ -n "${BASH}" ] && shopt -s checkwinsize 2>/dev/null; then
-				/bin/true
-			fi
-			genfun_cols=${COLUMNS}
-			;;
-		2)
 			# This use of stty(1) is portable as of POSIX Issue 8.
 			genfun_cols=$(
 				stty size 2>/dev/null | {
@@ -534,7 +524,7 @@ for _ in 1 2 3; do
 				}
 			)
 			;;
-		3)
+		2)
 			# Give up and assume 80 available columns.
 			genfun_cols=80
 			break


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-07 11:13 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-07 11:13 UTC (permalink / raw
  To: gentoo-commits

commit:     cc75239fd896bb528e4faf9e6b54a900fb657f2e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 24 06:15:57 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun  7 11:12:18 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=cc75239f

Jettison the genfun_lastbegun_strlen and genfun_lastcall variables

The genfun_lastbegun_strlen variable was previously used by _eend() to
indent the "[ ok ]" and "[ !! ]" indicators in the case that STDOUT is
found not to be a tty. Dispense with this variable. Instead, refrain
from indenting the indicator at all. After all, the width of the
controlling terminal is immaterial unless one is actually intending to
print to it.

$ { ebegin "Testing"; eend 0; } | cat
 * Testing ... [ ok ]

Apart from simplifying the code, this change brings the overall
behaviour of the printing functions closer to that of their counterparts
in OpenRC.

The genfun_lastcall variable was previously used by the _eprint()
function for the sole purpose of printing a LF (newline) character in
the case that the last message was printed as a consequence of calling
the ebegin() function. It would do so in anticipation of the _eend()
function later emitting the CUU (ECMA-48 CSI) sequence to move the
cursor up by one line, just prior to printing the "[ ok ]" and "[ !! ]"
indicators. Additionally, it was used by the ebegin() function to
determine whether a terminating LF character should follow the printed
message. Specifically, it would elect to print a LF character in the
case that ECMA-48 CSI sequences had been disabled at the time of
functions.sh being sourced. Finally, the value of genfun_lastcall would
influence the (now defunct) method by which the _eend() function would
calculate the degree of indentation required for the indicator in the
case of STDOUT not being a tty.

This variable has been dispensed with and replaced by a variable named
genfun_is_pending_lf. As its name suggests, its purpose is to track
whether the last printed message happened to contain a terminating LF
character. Now, whenever the _eprint() function is called, it consults
the variable so as to determine whether a LF character should be printed
for the purpose of terminating the last message, just before proceeding
to print the next one. Once the next one has been printed, the value of
the variable is updated accordingly. Similarly, the _eend() function
consults the variable so as to determine whether a LF character should
be printed to a terminal, just prior to the CUU (ECMA-48 CSI) sequence.

Ultimately, ebegin() will no longer be sloppily treated as a special
case. Rather, any printing function that inhibits the addition of a
terminating LF character (ebegin, einfon, ewarn, errorn etc) will have
its message be terminated upon calling any printing function thereafter.

In addition to cleaning up the code a little, these changes should
render the impending overhaul of the _eprint() and _eend() functions
easier to digest, once it lands.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 94 ++++++++++++++++++++++++++++--------------------------------
 1 file changed, 44 insertions(+), 50 deletions(-)

diff --git a/functions.sh b/functions.sh
index 31d1b43..97b0e6b 100644
--- a/functions.sh
+++ b/functions.sh
@@ -13,17 +13,21 @@
 #    Called by ebegin, eerrorn, einfon, and ewarnn.
 #
 _eprint() {
-	local color
+	local color msg
 	color=$1
 	shift
 
-	if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
-		printf '\n'
-	fi
+	msg=$*
 	if [ -t 1 ]; then
-		printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "$*"
+		printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "${msg}"
 	else
-		printf ' * %s%s' "${genfun_indent}" "$*"
+		printf ' * %s%s' "${genfun_indent}" "${msg}"
+	fi
+
+	if _ends_with_newline "${msg}"; then
+		genfun_is_pending_lf=0
+	else
+		genfun_is_pending_lf=1
 	fi
 }
 
@@ -117,7 +121,6 @@ einfon()
 {
 	if ! yesno "${EINFO_QUIET}"; then
 		_eprint "${GOOD}" "$@"
-		genfun_lastcall="einfon"
 	fi
 }
 
@@ -126,9 +129,7 @@ einfon()
 #
 einfo()
 {
-	einfon "$*
-"
-	genfun_lastcall="einfo"
+	einfon "${*}${genfun_newline}"
 }
 
 #
@@ -139,7 +140,6 @@ ewarnn()
 	if ! yesno "${EINFO_QUIET}"; then
 		_eprint "${WARN}" "$@" >&2
 		esyslog "daemon.warning" "${0##*/}" "$@"
-		genfun_lastcall="ewarnn"
 	fi
 }
 
@@ -148,9 +148,7 @@ ewarnn()
 #
 ewarn()
 {
-	ewarnn "$*
-"
-	genfun_lastcall="ewarn"
+	ewarnn "${*}${genfun_newline}"
 }
 
 #
@@ -161,7 +159,6 @@ eerrorn()
 	if ! yesno "${EERROR_QUIET}"; then
 		_eprint "${BAD}" "$@" >&2
 		esyslog "daemon.err" "${0##*/}" "$@"
-		genfun_lastcall="eerrorn"
 	fi
 	return 1
 }
@@ -171,10 +168,7 @@ eerrorn()
 #
 eerror()
 {
-	eerrorn "$*
-"
-	genfun_lastcall="eerror"
-	return 1
+	eerrorn "${*}${genfun_newline}"
 }
 
 #
@@ -185,13 +179,8 @@ ebegin()
 	local msg
 
 	if ! yesno "${EINFO_QUIET}"; then
-		msg="$* ..."
-		_eprint "${GOOD}" "${msg}"
-		if [ -n "${genfun_endcol}" ]; then
-			printf '\n'
-		fi
-		genfun_lastbegun_strlen="$(( 3 + ${#genfun_indent} + ${#msg} ))"
-		genfun_lastcall="ebegin"
+		msg="$* ...${genfun_newline}"
+		GENFUN_CALLER=ebegin _eprint "${GOOD}" "${msg}"
 	fi
 }
 
@@ -201,14 +190,14 @@ ebegin()
 #
 _eend()
 {
-	local cols efunc is_tty msg retval
+	local efunc is_tty msg retval
 
 	efunc=$1
 	shift
 	if [ "$#" -eq 0 ]; then
 		retval=0
 	elif ! is_int "$1" || [ "$1" -lt 0 ]; then
-		ewarn "Invalid argument given to ${CALLER} (the exit status code must be an integer >= 0)"
+		ewarn "Invalid argument given to ${GENFUN_CALLER} (the exit status code must be an integer >= 0)"
 		retval=0
 		shift
 	else
@@ -218,13 +207,8 @@ _eend()
 
 	if [ -t 1 ]; then
 		is_tty=1
-		cols=${genfun_cols}
 	else
-		# STDOUT is not currently a TTY. Therefore, the width of the
-		# controlling terminal, if any, is irrelevant. For this call,
-		# consider the number of columns as being 80.
 		is_tty=0
-		cols=80
 	fi
 
 	if [ "${retval}" -ne 0 ]; then
@@ -253,12 +237,20 @@ _eend()
 	fi
 
 	if [ "${is_tty}" -eq 1 ] && [ -n "${genfun_endcol}" ]; then
+		# Should a LF character be pending then print one. The CUU
+		# (ECMA-48 CSI) sequence will move the cursor up by one line
+		# prior to printing the indicator, right-justified.
+		if [ "${genfun_is_pending_lf}" -eq 1 ]; then
+			printf '\n'
+		fi
 		printf '%b %s\n' "${genfun_endcol}" "${msg}"
 	else
-		[ "${genfun_lastcall}" = ebegin ] || genfun_lastbegun_strlen=0
-		printf "%$(( cols - genfun_lastbegun_strlen - 7 ))s %s\n" '' "${msg}"
+		printf ' %s\n' "${msg}"
 	fi
 
+	# Record the fact that a LF character is no longer pending.
+	genfun_is_pending_lf=0
+
 	return "${retval}"
 }
 
@@ -268,12 +260,7 @@ _eend()
 #
 eend()
 {
-	local retval
-
-	CALLER=${CALLER:-eend} _eend eerror "$@"
-	retval=$?
-	genfun_lastcall="eend"
-	return "${retval}"
+	GENFUN_CALLER=${GENFUN_CALLER:-eend} _eend eerror "$@"
 }
 
 #
@@ -282,12 +269,7 @@ eend()
 #
 ewend()
 {
-	local retval
-
-	CALLER=${CALLER:-ewend} _eend ewarn "$@"
-	retval=$?
-	genfun_lastcall="ewend"
-	return "${retval}"
+	GENFUN_CALLER=${GENFUN_CALLER:-ewend} _eend ewarn "$@"
 }
 
 # v-e-commands honor EINFO_VERBOSE which defaults to no.
@@ -329,7 +311,7 @@ vebegin()
 veend()
 {
 	if yesno "${EINFO_VERBOSE}"; then
-		CALLER=veend eend "$@"
+		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)"
 	else
@@ -340,7 +322,7 @@ veend()
 vewend()
 {
 	if yesno "${EINFO_VERBOSE}"; then
-		CALLER=vewend ewend "$@"
+		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)"
 	else
@@ -490,6 +472,10 @@ _has_monochrome_terminal() {
 	fi
 }
 
+_ends_with_newline() {
+	! case $1 in *"${genfun_newline}") false ;; esac
+}
+
 # This is the main script, please add all functions above this point!
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS="yes"
@@ -501,6 +487,14 @@ EINFO_VERBOSE="${EINFO_VERBOSE:-no}"
 # Set the initial value for e-message indentation.
 genfun_indent=
 
+# Assign the LF ('\n') character for later expansion. POSIX Issue 8 permits
+# $'\n' but it may take years for it to be commonly implemented.
+genfun_newline='
+'
+
+# Whether the last printed message is pending a concluding LF character.
+genfun_is_pending_lf=0
+
 # Should we use color?
 if [ -n "${NO_COLOR}" ]; then
 	# See https://no-color.org/.
@@ -552,7 +546,7 @@ done
 if _has_dumb_terminal; then
 	unset -v genfun_endcol
 else
-	# Set some ECMA-48 CSI sequences (CUU1 and CUF) for cursor positioning.
+	# Set some ECMA-48 CSI sequences (CUU and CUF) for cursor positioning.
 	# These are standard and, conveniently, documented by console_codes(4).
 	genfun_endcol="\\033[A\\033[$(( genfun_cols - 7 ))C"
 fi


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-07 11:13 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-07 11:13 UTC (permalink / raw
  To: gentoo-commits

commit:     f8260d8494ac1fc243f9543a6b6836e69d7054d0
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 24 02:24:23 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun  7 11:12:18 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f8260d84

Use ewarn() to print the recently added diagnostic messages

Both the _eprint() and _eend() functions will be overhauled in the near
future, at which point conveying diagnostic messages (indirectly) to
_eprint() will become beneficial. This commit affects the following
functions.

  - esyslog
  - is_older_than
  - veend
  - vewend

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index 53f3205..31d1b43 100644
--- a/functions.sh
+++ b/functions.sh
@@ -95,7 +95,7 @@ esyslog()
 	local pri tag msg
 
 	if [ "$#" -lt 2 ]; then
-		printf 'Too few arguments for esyslog (got %d, expected at least 2)\n' "$#" >&2
+		ewarn "Too few arguments for esyslog (got $#, expected at least 2)"
 		return 1
 	elif [ -n "${EINFO_LOG}" ] && hash logger 2>/dev/null; then
 		pri=$1
@@ -208,7 +208,7 @@ _eend()
 	if [ "$#" -eq 0 ]; then
 		retval=0
 	elif ! is_int "$1" || [ "$1" -lt 0 ]; then
-		printf 'Invalid argument given to %s (the exit status code must be an integer >= 0)\n' "${CALLER}" >&2
+		ewarn "Invalid argument given to ${CALLER} (the exit status code must be an integer >= 0)"
 		retval=0
 		shift
 	else
@@ -331,7 +331,7 @@ veend()
 	if yesno "${EINFO_VERBOSE}"; then
 		CALLER=veend eend "$@"
 	elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then
-		printf 'Invalid argument given to veend (the exit status code must be an integer >= 0)\n' >&2
+		ewarn "Invalid argument given to veend (the exit status code must be an integer >= 0)"
 	else
 		return "$1"
 	fi
@@ -342,7 +342,7 @@ vewend()
 	if yesno "${EINFO_VERBOSE}"; then
 		CALLER=vewend ewend "$@"
 	elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then
-		printf 'Invalid argument given to vewend (the exit status code must be an integer >= 0)\n' >&2
+		ewarn "Invalid argument given to vewend (the exit status code must be an integer >= 0)"
 	else
 		return "$1"
 	fi
@@ -408,7 +408,7 @@ is_older_than()
 	local ref has_gfind
 
 	if [ "$#" -lt 2 ]; then
-		printf 'Too few arguments for is_older_than (got %d, expected at least 2)\n' "$#" >&2
+		ewarn "Too few arguments for is_older_than (got $#, expected at least 2)"
 		return 1
 	elif [ -e "$1" ]; then
 		ref=$1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-07 11:13 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-07 11:13 UTC (permalink / raw
  To: gentoo-commits

commit:     1947f0ed81f3b95a7e10a8a5a707776948f8a487
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 24 18:49:33 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun  7 11:12:18 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1947f0ed

Have ebegin() strip the trailing LF of the message it is given, if any

This is a precautionary measure, given that ebegin() appends " ..." to
the message.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index 97b0e6b..78317b3 100644
--- a/functions.sh
+++ b/functions.sh
@@ -179,8 +179,9 @@ ebegin()
 	local msg
 
 	if ! yesno "${EINFO_QUIET}"; then
-		msg="$* ...${genfun_newline}"
-		GENFUN_CALLER=ebegin _eprint "${GOOD}" "${msg}"
+		msg=$*
+		msg=${msg%"${genfun_newline}"}
+		_eprint "${GOOD}" "${msg} ...${genfun_newline}"
 	fi
 }
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-07 11:13 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-07 11:13 UTC (permalink / raw
  To: gentoo-commits

commit:     12eedb30ca60f0a7ae781b845d7bc22cc1b3267f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun  5 03:01:43 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun  7 11:12:53 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=12eedb30

test-functions: Add a test for the _is_visible() function

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/test-functions b/test-functions
index 72b5cae..b80587b 100755
--- a/test-functions
+++ b/test-functions
@@ -240,6 +240,26 @@ test_is_int() {
 		iterate_tests 2 "$@"
 }
 
+test_is_visible() {
+	set -- \
+		1  '' \
+		1  ' ' \
+		1  "$(printf '\t')" \
+		1  "$(printf '\a')" \
+		0  . \
+		0  ' . ' \
+		0  "$(printf '\t.\t')" \
+		0  "$(printf '\a.\a')"
+
+		callback() {
+			shift
+			test_description="_is_visible $(print_args "$@")"
+			_is_visible "$@"
+		}
+
+		iterate_tests 2 "$@"
+}
+
 test_yesno() {
 	set -- \
 		0  yes \
@@ -344,6 +364,7 @@ test_get_bootparam || rc=1
 test_esyslog || rc=1
 test_is_identifier || rc=1
 test_is_int || rc=1
+test_is_visible || rc=1
 test_yesno || rc=1
 cleanup_tmpdir
 exit "${rc}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-07 11:13 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-07 11:13 UTC (permalink / raw
  To: gentoo-commits

commit:     7e6ee7b371f5cc56dcf0e5918c6ec93ea0f7fb1b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun  5 02:44:30 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun  7 11:12:53 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7e6ee7b3

test-functions: Silence ewarn() while testing is_older_than()

The is_older_than() function now calls ewarn() if given invalid
arguments. For the purposes of the test suite, the resulting diagnostic
messages aren't particularly interesting.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-functions b/test-functions
index 892a255..72b5cae 100755
--- a/test-functions
+++ b/test-functions
@@ -339,7 +339,7 @@ export TEST_GENFUNCS=1
 export TZ=UTC
 
 rc=0
-test_is_older_than || rc=1
+( ewarn() { true; }; test_is_older_than ) || rc=1
 test_get_bootparam || rc=1
 test_esyslog || rc=1
 test_is_identifier || rc=1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-06-07 11:13 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-06-07 11:13 UTC (permalink / raw
  To: gentoo-commits

commit:     dd7522f3df09b8a92a303cc72690363979ecff3d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Jun  5 04:08:39 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Jun  7 11:12:53 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=dd7522f3

Don't assume a monochrome terminal in the case that tput colors fails

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/functions.sh b/functions.sh
index c326af4..34bb266 100644
--- a/functions.sh
+++ b/functions.sh
@@ -470,6 +470,8 @@ _has_monochrome_terminal() {
 		true
 	elif colors=$(tput colors 2>/dev/null) && is_int "${colors}"; then
 		test "${colors}" -eq -1
+	else
+		false
 	fi
 }
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-19 16:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-19 16:14 UTC (permalink / raw
  To: gentoo-commits

commit:     9e0d9b555da6866d366bfcb8cb40f3e4c4e79a2b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 18 06:46:12 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 19 16:14:06 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9e0d9b55

Drop -nc as a supported argument for disabling color

https://bugs.gentoo.org/599792#c1 went unnoted at the time, but the
commenter was quite right. It is just silly. Get rid of it.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 3b56b1d..fbc0812 100644
--- a/functions.sh
+++ b/functions.sh
@@ -488,7 +488,7 @@ genfun_indent=
 for _ in "$@"; do
 	case $_ in
 		# Check whether the user specifed an argument to disable color.
-		--nocolor|--nocolour|-nc|-C)
+		--nocolor|--nocolour|-C)
 			RC_NOCOLOR="yes"
 			break
 	esac


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-19 16:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-19 16:14 UTC (permalink / raw
  To: gentoo-commits

commit:     9bbf95a8fc7c280eb6cf323dc88b89e67293316a
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 18 08:03:14 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 19 16:14:06 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9bbf95a8

Add and integrate an is_identifier() function

Break out the routine to check for a valid identifier (variable name)
from yesno() into its own function. It is designated as a public
function because a great many scripts exist that use eval in an
exceedingly dangerous fashion, essentially performing code injection.
This function could well benefit scripts of such a calibre.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/functions.sh b/functions.sh
index 7246179..beaef03 100644
--- a/functions.sh
+++ b/functions.sh
@@ -76,19 +76,11 @@ yesno()
 			[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
 				return 0
 		esac
-		if [ "$_" -gt 1 ]; then
+		if [ "$_" -ne 1 ] || ! is_identifier "$1"; then
 			! break
 		else
-			# Using eval can be very dangerous. Check whether the
-			# value is a legitimate variable name before proceeding
-			# to treat it as one.
-			(
-				LC_ALL=C
-				case $1 in
-					''|_|[[:digit:]]*|*[!_[:alnum:]]*) exit 1
-				esac
-			) || ! break
-			# Treat the value as a nameref then try again.
+			# The value appears to be a legal variable name. Treat
+			# it as a name reference and try again, once only.
 			eval "set -- \"\$$1\""
 		fi
 	done || vewarn "Invalid argument given to yesno (expected a boolean-like or a legal name)"
@@ -471,6 +463,17 @@ _is_visible() {
 	! case $1 in *[[:graph:]]*) false ;; esac
 }
 
+#
+#   Determine whether the first operand is a valid identifier (variable name).
+#
+is_identifier()
+(
+	LC_ALL=C
+	case $1 in
+		''|_|[[:digit:]]*|*[!_[:alnum:]]*) false
+	esac
+)
+
 # This is the main script, please add all functions above this point!
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS="yes"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-19 16:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-19 16:14 UTC (permalink / raw
  To: gentoo-commits

commit:     3bd65f0f5598fc4bf93deb46b60775f19ba7c3e2
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 18 07:00:38 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 19 16:14:06 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=3bd65f0f

Avoid a needless test where the number of TTY columns can't be detected

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/functions.sh b/functions.sh
index d068627..e818049 100644
--- a/functions.sh
+++ b/functions.sh
@@ -523,6 +523,7 @@ for _ in 1 2 3; do
 		3)
 			# Give up and assume 80 available columns.
 			genfun_cols=80
+			break
 	esac
 	if is_int "${genfun_cols}" && [ "${genfun_cols}" -gt 0 ]; then
 		break


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-19 16:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-19 16:14 UTC (permalink / raw
  To: gentoo-commits

commit:     4927d7758cc4885680d1613ba818ee119738eac1
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 18 07:34:30 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 19 16:14:06 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=4927d775

Prevent shellcheck from complaining that HILITE is unused

Despite the fact that HILITE has never been expanded internally,
shellcheck only began to complain about it recently. Regardless, it is
a superfluous warning.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/functions.sh b/functions.sh
index e818049..7246179 100644
--- a/functions.sh
+++ b/functions.sh
@@ -553,6 +553,7 @@ else
 	BAD=$(printf '\033[31;01m')
 	BRACKET=$(printf '\033[34;01m')
 	GOOD=$(printf '\033[32;01m')
+	# shellcheck disable=2034
 	HILITE=$(printf '\033[36;01m')
 	NORMAL=$(printf '\033[0m')
 	WARN=$(printf '\033[33;01m')


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-19 16:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-19 16:14 UTC (permalink / raw
  To: gentoo-commits

commit:     c517951d98b6ae3c9ca0c838c029641287bd4d8d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 18 06:55:02 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 19 16:14:06 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=c517951d

Support NO_COLOR as a means of suppressing coloured output

Per https://no-color.org/, NO_COLOR is a de-facto standard for allowing
the user to express their preference for not seeing coloured output.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/functions.sh b/functions.sh
index fbc0812..d068627 100644
--- a/functions.sh
+++ b/functions.sh
@@ -479,20 +479,23 @@ RC_GOT_FUNCTIONS="yes"
 EINFO_QUIET="${EINFO_QUIET:-no}"
 EINFO_VERBOSE="${EINFO_VERBOSE:-no}"
 
-# Should we use color?
-RC_NOCOLOR="${RC_NOCOLOR:-no}"
-
 # Set the initial value for e-message indentation.
 genfun_indent=
 
-for _ in "$@"; do
-	case $_ in
-		# Check whether the user specifed an argument to disable color.
-		--nocolor|--nocolour|-C)
-			RC_NOCOLOR="yes"
-			break
-	esac
-done
+# Should we use color?
+if [ -n "${NO_COLOR}" ]; then
+	# See https://no-color.org/.
+	RC_NOCOLOR="yes"
+else
+	RC_NOCOLOR="${RC_NOCOLOR:-no}"
+	for _ in "$@"; do
+		case $_ in
+			--nocolor|--nocolour|-C)
+				RC_NOCOLOR="yes"
+				break
+		esac
+	done
+fi
 
 # Try to determine the number of available columns in the terminal.
 for _ in 1 2 3; do


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-19 16:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-19 16:14 UTC (permalink / raw
  To: gentoo-commits

commit:     60775e89a1411c772def465ef9b901b3fe78e450
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 18 16:55:17 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 19 16:14:19 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=60775e89

Simplify ECMA-48 sequence definition and dial back on the use of tput(1)

Up until very recently, functions.sh would not attempt to determine
whether a given message was being printed to a terminal. Over the years,
this has caused some deleterious effects, such as printing ECMA-48 CSI
and SGR sequences to file descriptors that are not necessarily attached
to a terminal. Another issue used to be that these sequences would be
emitted to terminals identifying themselves as "dumb".

Rather than tackle the underlying problems, the historical response has
tended towards further entrenching the use of the ncurses implementation
of tput(1). While it has its uses, the way in which it is employed is in
no way portable. POSIX only guarantees the availability of the clear,
init and reset operands. Presently, the colors operand is used as a
heuristic to determine whether the ncurses implementation is available
before proceeding to run a series of commands that will usually output
ECMA-48 SGR sequences that are standard for all but ancient and/or
obscure video terminals.

Another present use of tput(1) is in generating the CUU1 and CUF
sequences. In the overwhelming majority of cases, it will generate these
as standard ECMA-48 CSI sequences. To put this in perspective, the DEC
VT100, a video terminal released almost 45 years ago, supports these
sequences. The ECMA-48 specification, itself, is almost as old.

Unfortunately, reasoning with such matters tends towards a dichotomy.
On the one hand, there is a camp that considers it a cardinal sin to
attempt to emit an ANSI escape sequence without first having consulted a
specific implementation of tput(1). On the other, there is the camp that
points out that ECMA-48 sequences are highly portable and that video
terminals from the 1970s and 1980s are largely obsolete. Here are two
articles that present opposing points of view.

  https://mywiki.wooledge.org/BashFAQ/037
  https://xn--rpa.cc/irl/term.html

Of late, I find the arguments presented by the latter camp to be
increasingly convincing. As such, the goal of this commit is twofold.

Firstly, to implement an independent method for detecting a dumb
terminal. To that end, a _has_dumb_terminal() function has been added,
which simply checks the value of TERM. This, alone, determines whether
the CUU1 and CUF sequences should be assigned, with tput(1) no longer
being used to generate them.

Secondly, to further dial back on the use of tput(1) by not using it to
generate the SGR (colour) sequences. While I believe that nobody would
notice if we were to do away with the use of tput(1) altogether, I have
taken a nuanced approach by continuing to use it for detecting the
number of available colours. To that end, a _has_monochrome_terminal()
function has been implemented. This, alone, determines whether the SGR
sequences should be assigned. The function works by first checking
whether the terminal is dumb. If not, it tries to run "tput colors",
before checking whether -1 colours are reported, for that is how the
ncurses implementation reports the absence of colour support.

The resulting code is simpler and more pleasing to read, with tput being
run once, at most. Also, because there is no longer a requirement to
handle the CSI sequences in a raw form, they are now declared as strings
containing backslash-escape sequences, with printf %b being used to
decode them. This has the advantage of not emitting the raw codes to
STDERR while using xtrace for debugging.

In the future, I think that it may well be possible to drop the function
that detects a monochrome terminal and rely on dumb terminal detection
instead but let's see how it goes.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 46 ++++++++++++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 18 deletions(-)

diff --git a/functions.sh b/functions.sh
index c287b24..53f3205 100644
--- a/functions.sh
+++ b/functions.sh
@@ -253,7 +253,7 @@ _eend()
 	fi
 
 	if [ "${is_tty}" -eq 1 ] && [ -n "${genfun_endcol}" ]; then
-		printf '%s %s\n' "${genfun_endcol}" "${msg}"
+		printf '%b %s\n' "${genfun_endcol}" "${msg}"
 	else
 		[ "${genfun_lastcall}" = ebegin ] || genfun_lastbegun_strlen=0
 		printf "%$(( cols - genfun_lastbegun_strlen - 7 ))s %s\n" '' "${msg}"
@@ -474,6 +474,22 @@ is_identifier()
 	esac
 )
 
+_has_dumb_terminal() {
+	! case ${TERM} in *dumb*) false ;; esac
+}
+
+_has_monochrome_terminal() {
+	local colors
+
+	# The tput(1) invocation is not portable, though ncurses suffices. In
+	# this day and age, it is exceedingly unlikely that it will be needed.
+	if _has_dumb_terminal; then
+		true
+	elif colors=$(tput colors 2>/dev/null) && is_int "${colors}"; then
+		test "${colors}" -eq -1
+	fi
+}
+
 # This is the main script, please add all functions above this point!
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS="yes"
@@ -533,26 +549,20 @@ for _ in 1 2 3; do
 	fi
 done
 
-# Set an ECMA-48 CSI sequence, allowing for eend to line up the [ ok ] string.
-{
-	genfun_endcol="$(tput cuu1)" \
-	&& genfun_endcol="${genfun_endcol}$(tput cuf -- "$(( genfun_cols - 7 ))")" \
-	|| genfun_endcol="$(printf '\033[A\033[%dC' "$(( genfun_cols - 7 ))")"
-} 2>/dev/null
+if _has_dumb_terminal; then
+	unset -v genfun_endcol
+else
+	# Set some ECMA-48 CSI sequences (CUU1 and CUF) for cursor positioning.
+	# These are standard and, conveniently, documented by console_codes(4).
+	genfun_endcol="\\033[A\\033[$(( genfun_cols - 7 ))C"
+fi
 
-# Setup the colors so our messages all look pretty
-if yesno "${RC_NOCOLOR}"; then
+if _has_monochrome_terminal || yesno "${RC_NOCOLOR}"; then
 	unset -v BAD BRACKET GOOD HILITE NORMAL WARN
-elif { hash tput && tput colors >/dev/null; } 2>/dev/null; then
-	genfun_bold=$(tput bold) genfun_norm=$(tput sgr0)
-	BAD="${genfun_norm}${genfun_bold}$(tput setaf 1)"
-	BRACKET="${genfun_norm}${genfun_bold}$(tput setaf 4)"
-	GOOD="${genfun_norm}${genfun_bold}$(tput setaf 2)"
-	HILITE="${genfun_norm}${genfun_bold}$(tput setaf 6)"
-	NORMAL="${genfun_norm}"
-	WARN="${genfun_norm}${genfun_bold}$(tput setaf 3)"
-	unset -v genfun_bold genfun_norm
 else
+	# Define some ECMA-48 SGR sequences for color support. These variables
+	# are public, in so far as users of the library may be expanding them.
+	# The sequences are also documented by console_codes(4).
 	BAD=$(printf '\033[31;01m')
 	BRACKET=$(printf '\033[34;01m')
 	GOOD=$(printf '\033[32;01m')


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-19 16:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-19 16:14 UTC (permalink / raw
  To: gentoo-commits

commit:     47a622418d5745d15d6b47ec2c63ab060e39dd25
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 18 11:00:09 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 19 16:14:07 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=47a62241

Precede end columns with a single space, not two, in _eend()

A beneficial effect of doing so, apart from being able to show one more
character, is that the the associated arithmetic expansions uniformly
work with the genuine length of the end column, which is 7.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/functions.sh b/functions.sh
index beaef03..c287b24 100644
--- a/functions.sh
+++ b/functions.sh
@@ -253,10 +253,10 @@ _eend()
 	fi
 
 	if [ "${is_tty}" -eq 1 ] && [ -n "${genfun_endcol}" ]; then
-		printf '%s  %s\n' "${genfun_endcol}" "${msg}"
+		printf '%s %s\n' "${genfun_endcol}" "${msg}"
 	else
 		[ "${genfun_lastcall}" = ebegin ] || genfun_lastbegun_strlen=0
-		printf "%$(( cols - genfun_lastbegun_strlen - 6 ))s%s\n" '' "${msg}"
+		printf "%$(( cols - genfun_lastbegun_strlen - 7 ))s %s\n" '' "${msg}"
 	fi
 
 	return "${retval}"
@@ -536,8 +536,8 @@ done
 # Set an ECMA-48 CSI sequence, allowing for eend to line up the [ ok ] string.
 {
 	genfun_endcol="$(tput cuu1)" \
-	&& genfun_endcol="${genfun_endcol}$(tput cuf -- "$(( genfun_cols - 8 ))")" \
-	|| genfun_endcol="$(printf '\033[A\033[%dC' "$(( genfun_cols - 8 ))")"
+	&& genfun_endcol="${genfun_endcol}$(tput cuf -- "$(( genfun_cols - 7 ))")" \
+	|| genfun_endcol="$(printf '\033[A\033[%dC' "$(( genfun_cols - 7 ))")"
 } 2>/dev/null
 
 # Setup the colors so our messages all look pretty


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-19 16:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-19 16:14 UTC (permalink / raw
  To: gentoo-commits

commit:     de7a2ae7c416efe0fa75443f9174b05b1c6bbc5b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 18 06:11:53 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 19 16:14:06 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=de7a2ae7

Explain the composition and naming conventions of gentoo-functions.sh

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/functions.sh b/functions.sh
index 2918558..3b56b1d 100644
--- a/functions.sh
+++ b/functions.sh
@@ -2,8 +2,15 @@
 # Distributed under the terms of the GNU General Public License v2
 # shellcheck shell=sh disable=3043
 
+# This file contains a series of function declarations followed by some
+# initialization code. Functions intended for internal use shall be prefixed
+# with an <underscore> and shall not be considered as being a part of the public
+# API. With the exception of those declared by the local builtin, all variables
+# intended for internal use shall be prefixed with "genfun_" to indicate so,
+# and to reduce the probability of name space conflicts.
+
 #
-#    This is a private function, called by ebegin, eerrorn, einfon, and ewarnn.
+#    Called by ebegin, eerrorn, einfon, and ewarnn.
 #
 _eprint() {
 	local color
@@ -23,7 +30,6 @@ _eprint() {
 #
 #    hard set the indent used for e-commands.
 #    num defaults to 0
-# This is a private function.
 #
 _esetdent()
 {
@@ -201,9 +207,6 @@ ebegin()
 #    indicate the completion of process, called from eend/ewend
 #    if error, show errstr via efunc
 #
-#    This function is private to functions.sh.  Do not call it from a
-#    script.
-#
 _eend()
 {
 	local cols efunc is_tty msg retval
@@ -462,8 +465,7 @@ is_int() {
 }
 
 #
-#   Determine whether the first operand contains any visible characters. This
-#   is intended to be a private function.
+#   Determine whether the first operand contains any visible characters.
 #
 _is_visible() {
 	! case $1 in *[[:graph:]]*) false ;; esac


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-19 16:14 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-19 16:14 UTC (permalink / raw
  To: gentoo-commits

commit:     efdf0a4d0a889eb1549163b32a3a1c68521e4c42
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 18 05:53:23 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 19 16:14:05 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=efdf0a4d

Declare RC_GOT_FUNCTIONS after having declared all functions, not before

There is no sense in claiming that the functions have been gotten until
such time as the shell has successfully evaluated their declarations.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/functions.sh b/functions.sh
index 01f2972..2918558 100644
--- a/functions.sh
+++ b/functions.sh
@@ -2,9 +2,6 @@
 # Distributed under the terms of the GNU General Public License v2
 # shellcheck shell=sh disable=3043
 
-# shellcheck disable=2034
-RC_GOT_FUNCTIONS="yes"
-
 #
 #    This is a private function, called by ebegin, eerrorn, einfon, and ewarnn.
 #
@@ -473,6 +470,8 @@ _is_visible() {
 }
 
 # This is the main script, please add all functions above this point!
+# shellcheck disable=2034
+RC_GOT_FUNCTIONS="yes"
 
 # Dont output to stdout?
 EINFO_QUIET="${EINFO_QUIET:-no}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-17  7:44 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-17  7:44 UTC (permalink / raw
  To: gentoo-commits

commit:     9b955a2693fe679b03005128867525f4b8363a22
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 17 04:45:13 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 17 07:38:33 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9b955a26

Only join the positional parameters where necessary in _eend()

Also, don't join them twice.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index 816acf4..01f2972 100644
--- a/functions.sh
+++ b/functions.sh
@@ -237,8 +237,11 @@ _eend()
 
 	if [ "${retval}" -ne 0 ]; then
 		# If a message was given, print it with the specified function.
-		if _is_visible "$*"; then
-			"${efunc}" "$*"
+		if [ "$#" -gt 0 ]; then
+			msg=$*
+			if _is_visible "${msg}"; then
+				"${efunc}" "${msg}"
+			fi
 		fi
 		# Generate an indicator for ebegin's unsuccessful conclusion.
 		if [ "${is_tty}" -eq 0 ]; then


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-17  7:44 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-17  7:44 UTC (permalink / raw
  To: gentoo-commits

commit:     1a1b2373220086a98ced0af6e43057819ab8833f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 17 03:11:35 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 17 07:37:00 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1a1b2373

Don't try to write to a variable named arg upon being sourced

The consumer should be free to use this variable for their own purposes.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/functions.sh b/functions.sh
index 02627d2..816acf4 100644
--- a/functions.sh
+++ b/functions.sh
@@ -481,13 +481,12 @@ RC_NOCOLOR="${RC_NOCOLOR:-no}"
 # Set the initial value for e-message indentation.
 genfun_indent=
 
-for arg in "$@" ; do
-	case "${arg}" in
-		# Lastly check if the user disabled it with --nocolor argument
+for _ in "$@"; do
+	case $_ in
+		# Check whether the user specifed an argument to disable color.
 		--nocolor|--nocolour|-nc|-C)
 			RC_NOCOLOR="yes"
 			break
-			;;
 	esac
 done
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-17  7:44 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-17  7:44 UTC (permalink / raw
  To: gentoo-commits

commit:     0af4e76511a1235990e10d0e616a261cb6a4714f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 17 03:04:49 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 17 07:36:59 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=0af4e765

Improve the legibility of the routine that detects the number of columns

Also, mention that the use of stty size is portable as of POSIX Issue 8.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 52 ++++++++++++++++++++++++++++------------------------
 1 file changed, 28 insertions(+), 24 deletions(-)

diff --git a/functions.sh b/functions.sh
index df72d4a..02627d2 100644
--- a/functions.sh
+++ b/functions.sh
@@ -492,32 +492,36 @@ for arg in "$@" ; do
 done
 
 # Try to determine the number of available columns in the terminal.
-# shellcheck disable=3044
-if [ -n "${BASH}" ] && shopt -s checkwinsize 2>/dev/null; then
-	# As is documented, running an external command will cause bash to set
-	# the COLUMNS variable. This technique is effective for >=4.3, though
-	# it requires for the checkwinsize shopt to be enabled. By default, it
-	# is only enabled for >=5.0.
-	/bin/true
-fi
-if is_int "${COLUMNS}" && [ "${COLUMNS}" -gt 0 ]; then
-	# The value of COLUMNS was likely set by a shell such as bash or mksh.
-	genfun_cols=${COLUMNS}
-else
-	# Try to use stty(1) to determine the number of columns. The use of the
-	# size operand is not portable.
-	genfun_cols=$(
-		stty size 2>/dev/null | {
-			if IFS=' ' read -r _ cols _; then
-				printf '%s\n' "${cols}"
+for _ in 1 2 3; do
+	case $_ in
+		1)
+			# Running an external command causes bash >=4.3 to set
+			# the COLUMNS variable, provided that the checkwinsize
+			# shopt is enabled. As of 5.0, it's enabled by default.
+			# shellcheck disable=3044
+			if [ -n "${BASH}" ] && shopt -s checkwinsize 2>/dev/null; then
+				/bin/true
 			fi
-		}
-	)
-	if ! is_int "${genfun_cols}" || [ "${genfun_cols}" -le 0 ]; then
-		# Give up and assume 80 available columns.
-		genfun_cols=80
+			genfun_cols=${COLUMNS}
+			;;
+		2)
+			# This use of stty(1) is portable as of POSIX Issue 8.
+			genfun_cols=$(
+				stty size 2>/dev/null | {
+					if IFS=' ' read -r _ cols; then
+						printf '%s\n' "${cols}"
+					fi
+				}
+			)
+			;;
+		3)
+			# Give up and assume 80 available columns.
+			genfun_cols=80
+	esac
+	if is_int "${genfun_cols}" && [ "${genfun_cols}" -gt 0 ]; then
+		break
 	fi
-fi
+done
 
 # Set an ECMA-48 CSI sequence, allowing for eend to line up the [ ok ] string.
 {


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-17  1:33 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-17  1:33 UTC (permalink / raw
  To: gentoo-commits

commit:     95914526b1e0c3482031b17c7bc8b0d1c29b3ec7
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Feb 16 13:28:55 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 17 01:32:54 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=95914526

Ensure that the hard-coded ECMA-48 CSI sequence is assigned in raw form

This is necessary because format string injection no longer occurs, nor
is the %b format specifier being used in any of the format strings.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index ad2a551..6523fa8 100644
--- a/functions.sh
+++ b/functions.sh
@@ -519,7 +519,7 @@ fi
 if hash tput 2>/dev/null; then
 	genfun_endcol="$(tput cuu1)$(tput cuf $(( genfun_cols - 8 )) )"
 else
-	genfun_endcol='\033[A\033['$(( genfun_cols - 8 ))'C'
+	genfun_endcol="$(printf '\033[A\033[%dC' "$(( genfun_cols - 8 ))")"
 fi
 
 # Setup the colors so our messages all look pretty


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-17  1:33 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-17  1:33 UTC (permalink / raw
  To: gentoo-commits

commit:     ded20c5e676c093c592ebadb1d83d41989a4ef5d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Feb 16 14:15:36 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 17 01:33:28 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=ded20c5e

Explicitly define IFS for invocations of the read builtin

This is appropriate for library code because there is no telling what
the value of IFS will be at any given moment. Also, POSIX does not
forbid implementations of sh(1) from inheriting the value of IFS from
the parent process, though this defect will be addressed by Issue 8. See
https://austingroupbugs.net/view.php?id=884 for further details.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 22e6ef9..df72d4a 100644
--- a/functions.sh
+++ b/functions.sh
@@ -379,6 +379,9 @@ get_bootparam()
 	# Similarly, the empty string must not be allowed to match.
 	case $1 in ''|*,*) return 1 ;; esac
 
+	# Reset the value of IFS because there is no telling what it may be.
+	IFS=$(printf ' \n\t')
+
 	if [ "${TEST_GENFUNCS}" = 1 ]; then
 		read -r cmdline
 	else
@@ -505,7 +508,7 @@ else
 	# size operand is not portable.
 	genfun_cols=$(
 		stty size 2>/dev/null | {
-			if read -r _ cols _; then
+			if IFS=' ' read -r _ cols _; then
 				printf '%s\n' "${cols}"
 			fi
 		}


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-17  1:33 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-17  1:33 UTC (permalink / raw
  To: gentoo-commits

commit:     b86f278da7389b6a9e70cccb0bee831a53d50b83
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Feb 16 13:57:54 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 17 01:33:09 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b86f278d

Don't assume that tput supports the cuu1 and cuf operands and will succeed

POSIX only guarantees for tput(1) to support the clear, init and reset
operands. Further, while the ncurses implementation supports many more,
it is foolhardy to assume that any given invocation of tput(1) will
succeed, let alone both. To remedy this, check the exit status of both
invocations and, should either fail, fall back to the method of directly
defining the (standard) ECMA-48 CSI sequences.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/functions.sh b/functions.sh
index 6523fa8..22e6ef9 100644
--- a/functions.sh
+++ b/functions.sh
@@ -488,7 +488,7 @@ for arg in "$@" ; do
 	esac
 done
 
-# Define genfun_cols and genfun_endcol so that eend can line up the [ ok ].
+# Try to determine the number of available columns in the terminal.
 # shellcheck disable=3044
 if [ -n "${BASH}" ] && shopt -s checkwinsize 2>/dev/null; then
 	# As is documented, running an external command will cause bash to set
@@ -516,11 +516,12 @@ else
 	fi
 fi
 
-if hash tput 2>/dev/null; then
-	genfun_endcol="$(tput cuu1)$(tput cuf $(( genfun_cols - 8 )) )"
-else
-	genfun_endcol="$(printf '\033[A\033[%dC' "$(( genfun_cols - 8 ))")"
-fi
+# Set an ECMA-48 CSI sequence, allowing for eend to line up the [ ok ] string.
+{
+	genfun_endcol="$(tput cuu1)" \
+	&& genfun_endcol="${genfun_endcol}$(tput cuf -- "$(( genfun_cols - 8 ))")" \
+	|| genfun_endcol="$(printf '\033[A\033[%dC' "$(( genfun_cols - 8 ))")"
+} 2>/dev/null
 
 # Setup the colors so our messages all look pretty
 if yesno "${RC_NOCOLOR}"; then


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-15  8:18 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-15  8:18 UTC (permalink / raw
  To: gentoo-commits

commit:     008c88e05d15b19a80a55863d9c71709a0b61216
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Feb 15 08:14:01 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 08:17:56 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=008c88e0

Do not try to account for genfun_endcol being unset

To do so was very briefly useful but rendered obsolete by the commit
that introduced "proper TTY detection". Since then, the distinction
between genfun_endcol being unset or merely empty has been immaterial.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/functions.sh b/functions.sh
index 6b11645..ad2a551 100644
--- a/functions.sh
+++ b/functions.sh
@@ -475,9 +475,6 @@ EINFO_VERBOSE="${EINFO_VERBOSE:-no}"
 # Should we use color?
 RC_NOCOLOR="${RC_NOCOLOR:-no}"
 
-# Can the terminal handle endcols? Begin by assuming not.
-unset -v genfun_endcol
-
 # Set the initial value for e-message indentation.
 genfun_indent=
 
@@ -519,12 +516,10 @@ else
 	fi
 fi
 
-if [ -z "${genfun_endcol+set}" ]; then
-	if hash tput 2>/dev/null; then
-		genfun_endcol="$(tput cuu1)$(tput cuf $(( genfun_cols - 8 )) )"
-	else
-		genfun_endcol='\033[A\033['$(( genfun_cols - 8 ))'C'
-	fi
+if hash tput 2>/dev/null; then
+	genfun_endcol="$(tput cuu1)$(tput cuf $(( genfun_cols - 8 )) )"
+else
+	genfun_endcol='\033[A\033['$(( genfun_cols - 8 ))'C'
 fi
 
 # Setup the colors so our messages all look pretty


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-15  7:48 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-15  7:48 UTC (permalink / raw
  To: gentoo-commits

commit:     7740d326249aee9f4e3b4032932e272792de16b2
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Wed Feb 15 07:48:12 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 07:48:12 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7740d326

Makefile: crank version to 0.20 in preparation

I'll likely forget otherwise.

Signed-off-by: Sam James <sam <AT> gentoo.org>

 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 739bfcb..3fa8d85 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 # Copyright 2014-2023 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
-VERSION = 0.19
+VERSION = 0.20
 GITREF ?= $(VERSION)
 PKG ?= gentoo-functions-$(VERSION)
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-15  7:46 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-15  7:46 UTC (permalink / raw
  To: gentoo-commits

commit:     c7d99dc38a647899e8dad2e036439ecf4b1fdf2b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Feb 15 06:27:54 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 07:32:40 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=c7d99dc3

Don't use %b to format the "[ ok ]" and "[ !! ]" strings in _eend()

The success/failure strings were once injected into format strings. The
effect of doing so does not need to be mimicked because, even where
_eend() incororates ECMA-48 sequences, they are always in a raw form and
do not require decoding.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index 4f94ab0..151775f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -229,10 +229,10 @@ _eend()
 	fi
 
 	if [ -n "${genfun_endcol}" ]; then
-		printf '%s  %b\n' "${genfun_endcol}" "${msg}"
+		printf '%s  %s\n' "${genfun_endcol}" "${msg}"
 	else
 		[ "${genfun_lastcall}" = ebegin ] || genfun_lastbegun_strlen=0
-		printf "%$(( genfun_cols - genfun_lastbegun_strlen - 6 ))s%b\n" '' "${msg}"
+		printf "%$(( genfun_cols - genfun_lastbegun_strlen - 6 ))s%s\n" '' "${msg}"
 	fi
 
 	return "${retval}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-15  7:46 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-15  7:46 UTC (permalink / raw
  To: gentoo-commits

commit:     eb36c3077fd69b7cbc5ef64c68d42baff50b3d43
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Feb 15 07:02:48 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 07:32:45 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=eb36c307

Implement proper TTY detection, once and for all

Following a litany of ill-considered bodges and hacks over the years, it
is high time that the matter of tty detection was conclusively dealt
with. This commit aims to accomplish exactly that, in a fashion that can
be described twofold.

Firstly, the recently introduced _eprint() function will now test
whether STDOUT is a tty at the time of invocation. If found to be a tty,
ECMA-48 SGR sequences shall be incorporated into the message. Otherwise,
they shall not be. This positively affects the following functions.

  - ebegin
  - einfo
  - einfon
  - eerror
  - eerrorn
  - ewarnn
  - ewarn
  - vebegin
  - veinfo
  - veinfon
  - veerror
  - veerrorn
  - vewarnn
  - vewarn

Note that the *eerror* and *ewarn* functions duplicate file descriptor 2
(STDERR) to file descriptor 1 (STDOUT), meaning that the -t 1 test will
always be in the context of the appropriate file descriptor.

Secondly, the _eend() function will now test whether STDOUT is a tty at
the time of invocation. Just as with _eprint(), ECMA-48 SGR sequences
will be omitted in the case that STDOUT is found not to be a tty
However, the fact that _eend() prints a so-called end column must also
be taken into account. The end column string is not defined by this
function, but may or may not incorporate ECMA-48 CSI sequences that are
intended to move the cursor up - and to the end of - the previous line.
Previously, _eend() would always use the end column if was found to be
non-empty, despite containing such sequences. Now, it will refrain from
printing the end column where STDOUT is not a tty. Instead, it will fall
back to the method of printing the success/failure indicator on the
current line. Furthemore, if the fallback method is used under these
exact circumstances, the number of available columns will be assumed as
being 80 for the scope of the function call. After all, the width of the
controlling terminal is wholly immaterial unless printing to it. This
positively affects the following functions.

  - eend
  - ewend
  - veend
  - vewend

Consequently, all eighteen of the aformentioned functions will act
properly, in accordance with the state of both STDOUT and STDERR, at the
time that they are called. As such, the truly repulsive hack that was to
permanently disable colour if _either_ were found not to be a tty at the
time of sourcing functions.sh has been jettisoned. Good riddance.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Bug: https://bugs.gentoo.org/631870
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 47 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/functions.sh b/functions.sh
index 151775f..a0422b6 100644
--- a/functions.sh
+++ b/functions.sh
@@ -16,7 +16,11 @@ _eprint() {
 	if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
 		printf '\n'
 	fi
-	printf ' %s*%s %s%b' "${color}" "${NORMAL}" "${genfun_indent}" "$*"
+	if [ -t 1 ]; then
+		printf ' %s*%s %s%b' "${color}" "${NORMAL}" "${genfun_indent}" "$*"
+	else
+		printf ' * %s%b' "${genfun_indent}" "$*"
+	fi
 }
 
 #
@@ -202,7 +206,7 @@ ebegin()
 #
 _eend()
 {
-	local efunc msg retval
+	local cols efunc is_tty msg retval
 
 	efunc=$1
 	shift
@@ -217,22 +221,44 @@ _eend()
 		shift
 	fi
 
+	if [ -t 1 ]; then
+		is_tty=1
+		cols=${genfun_cols}
+	else
+		# STDOUT is not currently a TTY. Therefore, the width of the
+		# controlling terminal, if any, is irrelevant. For this call,
+		# consider the number of columns as being 80.
+		is_tty=0
+		cols=80
+	fi
+
 	if [ "${retval}" -ne 0 ]; then
+		# If a message was given, print it with the specified function.
 		if _is_visible "$*"; then
 			"${efunc}" "$*"
 		fi
-		msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
+		# Generate an indicator for ebegin's unsuccessful conclusion.
+		if [ "${is_tty}" -eq 0 ]; then
+			msg="[ !! ]"
+		else
+			msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
+		fi
 	elif yesno "${EINFO_QUIET}"; then
 		return "${retval}"
 	else
-		msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
+		# Generate an indicator for ebegin's successful conclusion.
+		if [ "${is_tty}" -eq 0 ]; then
+			msg="[ ok ]"
+		else
+			msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
+		fi
 	fi
 
-	if [ -n "${genfun_endcol}" ]; then
+	if [ "${is_tty}" -eq 1 ] && [ -n "${genfun_endcol}" ]; then
 		printf '%s  %s\n' "${genfun_endcol}" "${msg}"
 	else
 		[ "${genfun_lastcall}" = ebegin ] || genfun_lastbegun_strlen=0
-		printf "%$(( genfun_cols - genfun_lastbegun_strlen - 6 ))s%s\n" '' "${msg}"
+		printf "%$(( cols - genfun_lastbegun_strlen - 6 ))s%s\n" '' "${msg}"
 	fi
 
 	return "${retval}"
@@ -452,15 +478,6 @@ unset -v genfun_endcol
 # Set the initial value for e-message indentation.
 genfun_indent=
 
-# If either STDOUT or STDERR is not a tty, disable coloured output. A useful
-# improvement for  the future would be to have the individual logging functions
-# act as they should. For example, ewarn prints to STDOUT whereas eerror prints
-# to STDERR. For now, this is a reasonable compromise.
-if [ ! -t 1 ] || [ ! -t 2 ]; then
-	RC_NOCOLOR="yes"
-	genfun_endcol=
-fi
-
 for arg in "$@" ; do
 	case "${arg}" in
 		# Lastly check if the user disabled it with --nocolor argument


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-15  7:46 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-15  7:46 UTC (permalink / raw
  To: gentoo-commits

commit:     ce648e7539607a1809a1e4a037ade84bb4cde7b2
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Feb 15 07:35:20 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 07:43:55 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=ce648e75

Do not use %b to decode user-supplied message strings

For a long time, user-supplied message strings were injected into format
strings used by printf. Obviously, doing so was a bad thing because it
would cause printf to interpret any escape sequences and format
specifiers that might be present in the string.

The issue of specifier injection was dealt with by the introduction of
_eprint(). This commit deals with the remaining issue by eliminating the
use of %b, whose only effect was to needlessly try to decode the message
string according to the same rules as echo -e (for XSI-conformant
systems).

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Bug: https://bugs.gentoo.org/730432
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index a0422b6..6b11645 100644
--- a/functions.sh
+++ b/functions.sh
@@ -17,9 +17,9 @@ _eprint() {
 		printf '\n'
 	fi
 	if [ -t 1 ]; then
-		printf ' %s*%s %s%b' "${color}" "${NORMAL}" "${genfun_indent}" "$*"
+		printf ' %s*%s %s%s' "${color}" "${NORMAL}" "${genfun_indent}" "$*"
 	else
-		printf ' * %s%b' "${genfun_indent}" "$*"
+		printf ' * %s%s' "${genfun_indent}" "$*"
 	fi
 }
 
@@ -131,7 +131,8 @@ einfon()
 #
 einfo()
 {
-	einfon "$*\\n"
+	einfon "$*
+"
 	genfun_lastcall="einfo"
 }
 
@@ -152,7 +153,8 @@ ewarnn()
 #
 ewarn()
 {
-	ewarnn "$*\\n"
+	ewarnn "$*
+"
 	genfun_lastcall="ewarn"
 }
 
@@ -174,7 +176,8 @@ eerrorn()
 #
 eerror()
 {
-	eerrorn "$*\\n"
+	eerrorn "$*
+"
 	genfun_lastcall="eerror"
 	return 1
 }


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-15  7:46 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-15  7:46 UTC (permalink / raw
  To: gentoo-commits

commit:     93015498cc2167315dbde003ecd6b5cdef6a96bb
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Feb 15 05:20:36 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 07:32:39 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=93015498

Fix an SC2059 warning in ebegin()

The SC2059 warning concerns potential injection into a format string.
At this point, and for the first ever time, functions.sh raises no
warnings in shellcheck

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index c1ff6a4..4f94ab0 100644
--- a/functions.sh
+++ b/functions.sh
@@ -229,7 +229,7 @@ _eend()
 	fi
 
 	if [ -n "${genfun_endcol}" ]; then
-		printf "${genfun_endcol}  ${msg}\n"
+		printf '%s  %b\n' "${genfun_endcol}" "${msg}"
 	else
 		[ "${genfun_lastcall}" = ebegin ] || genfun_lastbegun_strlen=0
 		printf "%$(( genfun_cols - genfun_lastbegun_strlen - 6 ))s%b\n" '' "${msg}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-15  7:46 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-15  7:46 UTC (permalink / raw
  To: gentoo-commits

commit:     f100672645829212d8a2b2b3b273cecbee1e2f18
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Feb 15 04:28:06 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 07:32:33 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f1006726

Remove the comment imploring developers not to use bashisms

The shellcheck hint makes it clear that the target is sh(1) with support
for the local builtin.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index b223ce8..bd45c6f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -2,11 +2,6 @@
 # Distributed under the terms of the GNU General Public License v2
 # shellcheck shell=sh disable=3043
 
-#
-# All functions in this file should be written in POSIX sh. Please do
-# not use bashisms.
-#
-
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS="yes"
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-15  7:46 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-15  7:46 UTC (permalink / raw
  To: gentoo-commits

commit:     34abe2307694673a704009d3baf8862008711fab
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Feb 15 05:03:42 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 07:32:35 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=34abe230

Implement - and integrate - an _eprint() helper function

The _eprint() function encapsulates some of the behaviour that the
following functions have in common.

  - ebegin
  - einfo
  - einfon
  - eerror
  - eerrorn
  - ewarnn
  - ewarn

Additionally, have einfo() wrap einfon(), eerror() wrap eerrorn(), and
ewarn() wrap ewarnn().

All of this allows for a pleasing degree of code reduction while
improving the structure of the functions overall, partly owing to a
complementary reduction in the number of return statements. It also
plots a course for the eventual implementation of proper TTY detection,
in a context-sensitive manner.

Bug: https://bugs.gentoo.org/730432
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 109 ++++++++++++++++++++---------------------------------------
 1 file changed, 37 insertions(+), 72 deletions(-)

diff --git a/functions.sh b/functions.sh
index bd45c6f..c1ff6a4 100644
--- a/functions.sh
+++ b/functions.sh
@@ -5,6 +5,20 @@
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS="yes"
 
+#
+#    This is a private function, called by ebegin, eerrorn, einfon, and ewarnn.
+#
+_eprint() {
+	local color
+	color=$1
+	shift
+
+	if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
+		printf '\n'
+	fi
+	printf ' %s*%s %s%b' "${color}" "${NORMAL}" "${genfun_indent}" "$*"
+}
+
 #
 #    hard set the indent used for e-commands.
 #    num defaults to 0
@@ -102,15 +116,10 @@ esyslog()
 #
 einfon()
 {
-	if yesno "${EINFO_QUIET}"; then
-		return 0
+	if ! yesno "${EINFO_QUIET}"; then
+		_eprint "${GOOD}" "$@"
+		genfun_lastcall="einfon"
 	fi
-	if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
-		printf "\n"
-	fi
-	printf " ${GOOD}*${NORMAL} ${genfun_indent}$*"
-	genfun_lastcall="einfon"
-	return 0
 }
 
 #
@@ -118,9 +127,8 @@ einfon()
 #
 einfo()
 {
-	einfon "$*\n"
+	einfon "$*\\n"
 	genfun_lastcall="einfo"
-	return 0
 }
 
 #
@@ -128,20 +136,11 @@ einfo()
 #
 ewarnn()
 {
-	if yesno "${EINFO_QUIET}"; then
-		return 0
-	else
-		if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
-			printf "\n" >&2
-		fi
-		printf " ${WARN}*${NORMAL} ${genfun_indent}$*" >&2
+	if ! yesno "${EINFO_QUIET}"; then
+		_eprint "${WARN}" "$@" >&2
+		esyslog "daemon.warning" "${0##*/}" "$@"
+		genfun_lastcall="ewarnn"
 	fi
-
-	# Log warnings to system log
-	esyslog "daemon.warning" "${0##*/}" "$@"
-
-	genfun_lastcall="ewarnn"
-	return 0
 }
 
 #
@@ -149,20 +148,8 @@ ewarnn()
 #
 ewarn()
 {
-	if yesno "${EINFO_QUIET}"; then
-		return 0
-	else
-		if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
-			printf "\n" >&2
-		fi
-		printf " ${WARN}*${NORMAL} ${genfun_indent}$*\n" >&2
-	fi
-
-	# Log warnings to system log
-	esyslog "daemon.warning" "${0##*/}" "$@"
-
+	ewarnn "$*\\n"
 	genfun_lastcall="ewarn"
-	return 0
 }
 
 #
@@ -170,19 +157,11 @@ ewarn()
 #
 eerrorn()
 {
-	if yesno "${EERROR_QUIET}"; then
-		return 1
-	else
-		if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
-			printf "\n" >&2
-		fi
-		printf " ${BAD}*${NORMAL} ${genfun_indent}$*" >&2
+	if ! yesno "${EERROR_QUIET}"; then
+		_eprint "${BAD}" "$@" >&2
+		esyslog "daemon.err" "${0##*/}" "$@"
+		genfun_lastcall="eerrorn"
 	fi
-
-	# Log errors to system log
-	esyslog "daemon.err" "${0##*/}" "$@"
-
-	genfun_lastcall="eerrorn"
 	return 1
 }
 
@@ -191,18 +170,7 @@ eerrorn()
 #
 eerror()
 {
-	if yesno "${EERROR_QUIET}"; then
-		return 1
-	else
-		if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
-			printf "\n" >&2
-		fi
-		printf " ${BAD}*${NORMAL} ${genfun_indent}$*\n" >&2
-	fi
-
-	# Log errors to system log
-	esyslog "daemon.err" "${0##*/}" "$@"
-
+	eerrorn "$*\\n"
 	genfun_lastcall="eerror"
 	return 1
 }
@@ -212,20 +180,17 @@ eerror()
 #
 ebegin()
 {
-	local msg="$*"
-	if yesno "${EINFO_QUIET}"; then
-		return 0
-	fi
+	local msg
 
-	msg="${msg} ..."
-	einfon "${msg}"
-	if [ -n "${genfun_endcol}" ]; then
-		printf "\n"
+	if ! yesno "${EINFO_QUIET}"; then
+		msg="$* ..."
+		_eprint "${GOOD}" "${msg}"
+		if [ -n "${genfun_endcol}" ]; then
+			printf '\n'
+		fi
+		genfun_lastbegun_strlen="$(( 3 + ${#genfun_indent} + ${#msg} ))"
+		genfun_lastcall="ebegin"
 	fi
-
-	genfun_lastbegun_strlen="$(( 3 + ${#genfun_indent} + ${#msg} ))"
-	genfun_lastcall="ebegin"
-	return 0
 }
 
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-15  2:24 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-15  2:24 UTC (permalink / raw
  To: gentoo-commits

commit:     9a9a34ca4d59097bd795720560fdfe64105200e5
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Feb 15 00:41:45 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 02:14:13 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9a9a34ca

Render the RC_ENDCOL variable redundant and eliminate it

There is no need for it. To determine whether end columns are enabled,
it is only necessary to check that the length of ENDCOL is greater than
zero. Also, this eliminates many yesno() calls, which were comparatively
expensive.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/functions.sh b/functions.sh
index c80bc41..19e4a37 100644
--- a/functions.sh
+++ b/functions.sh
@@ -110,7 +110,7 @@ einfon()
 	if yesno "${EINFO_QUIET}"; then
 		return 0
 	fi
-	if ! yesno "${RC_ENDCOL}" && [ "${LAST_E_CMD}" = "ebegin" ]; then
+	if [ -z "${ENDCOL}" ] && [ "${LAST_E_CMD}" = "ebegin" ]; then
 		printf "\n"
 	fi
 	printf " ${GOOD}*${NORMAL} ${RC_INDENTATION}$*"
@@ -136,7 +136,7 @@ ewarnn()
 	if yesno "${EINFO_QUIET}"; then
 		return 0
 	else
-		if ! yesno "${RC_ENDCOL}" && [ "${LAST_E_CMD}" = "ebegin" ]; then
+		if [ -z "${ENDCOL}" ] && [ "${LAST_E_CMD}" = "ebegin" ]; then
 			printf "\n" >&2
 		fi
 		printf " ${WARN}*${NORMAL} ${RC_INDENTATION}$*" >&2
@@ -157,7 +157,7 @@ ewarn()
 	if yesno "${EINFO_QUIET}"; then
 		return 0
 	else
-		if ! yesno "${RC_ENDCOL}" && [ "${LAST_E_CMD}" = "ebegin" ]; then
+		if [ -z "${ENDCOL}" ] && [ "${LAST_E_CMD}" = "ebegin" ]; then
 			printf "\n" >&2
 		fi
 		printf " ${WARN}*${NORMAL} ${RC_INDENTATION}$*\n" >&2
@@ -178,7 +178,7 @@ eerrorn()
 	if yesno "${EERROR_QUIET}"; then
 		return 1
 	else
-		if ! yesno "${RC_ENDCOL}" && [ "${LAST_E_CMD}" = "ebegin" ]; then
+		if [ -z "${ENDCOL}" ] && [ "${LAST_E_CMD}" = "ebegin" ]; then
 			printf "\n" >&2
 		fi
 		printf " ${BAD}*${NORMAL} ${RC_INDENTATION}$*" >&2
@@ -199,7 +199,7 @@ eerror()
 	if yesno "${EERROR_QUIET}"; then
 		return 1
 	else
-		if ! yesno "${RC_ENDCOL}" && [ "${LAST_E_CMD}" = "ebegin" ]; then
+		if [ -z "${ENDCOL}" ] && [ "${LAST_E_CMD}" = "ebegin" ]; then
 			printf "\n" >&2
 		fi
 		printf " ${BAD}*${NORMAL} ${RC_INDENTATION}$*\n" >&2
@@ -224,7 +224,7 @@ ebegin()
 
 	msg="${msg} ..."
 	einfon "${msg}"
-	if yesno "${RC_ENDCOL}"; then
+	if [ -n "${ENDCOL}" ]; then
 		printf "\n"
 	fi
 
@@ -268,7 +268,7 @@ _eend()
 		msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
 	fi
 
-	if yesno "${RC_ENDCOL}"; then
+	if [ -n "${ENDCOL}" ]; then
 		printf "${ENDCOL}  ${msg}\n"
 	else
 		[ "${LAST_E_CMD}" = ebegin ] || LAST_E_LEN=0
@@ -485,8 +485,9 @@ EINFO_VERBOSE="${EINFO_VERBOSE:-no}"
 
 # Should we use color?
 RC_NOCOLOR="${RC_NOCOLOR:-no}"
-# Can the terminal handle endcols?
-RC_ENDCOL="yes"
+
+# Can the terminal handle endcols? Begin by assuming not.
+unset -v ENDCOL
 
 # Default values for e-message indentation and dots
 RC_INDENTATION=''
@@ -498,7 +499,7 @@ RC_DEFAULT_INDENT=2
 # to STDERR. For now, this is a reasonable compromise.
 if [ ! -t 1 ] || [ ! -t 2 ]; then
 	RC_NOCOLOR="yes"
-	RC_ENDCOL="no"
+	ENDCOL=
 fi
 
 for arg in "$@" ; do
@@ -539,12 +540,12 @@ else
 	fi
 fi
 
-if ! yesno "${RC_ENDCOL}"; then
-	ENDCOL=''
-elif hash tput 2>/dev/null; then
-	ENDCOL="$(tput cuu1)$(tput cuf $(( COLS - 8 )) )"
-else
-	ENDCOL='\033[A\033['$(( COLS - 8 ))'C'
+if [ -z "${ENDCOL+set}" ]; then
+	if hash tput 2>/dev/null; then
+		ENDCOL="$(tput cuu1)$(tput cuf $(( COLS - 8 )) )"
+	else
+		ENDCOL='\033[A\033['$(( COLS - 8 ))'C'
+	fi
 fi
 
 # Setup the colors so our messages all look pretty


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-15  2:24 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-15  2:24 UTC (permalink / raw
  To: gentoo-commits

commit:     55599a3ee94468ffc95a1dac13a948b5c4b5f26e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Feb 15 02:03:21 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 02:14:20 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=55599a3e

Implement a naming scheme for variables used only for internal purposes

The variable naming scheme employed by functions.sh has a number of
issues that are addressed herewith.

Firstly, it is not straightforward to determine whether a variable is
intended for internal use by functions.sh, except for those declared
with the (non-standard) local builtin. Nor is it straightforward to
determine whether it is deemed acceptable for a given variable to exist
in the execution environment at the time that functions.sh was sourced.

Secondly, by convention, environment variables (PATH, EDITOR, SHELL etc)
and internal shell variables (BASH_VERSION, RANDOM etc) are fully
capitalised. Given that variables names are case-sensitive, shell
variables ought to be in lower case. Indeed, POSIX offers some guidance
on this matter. Below is a quotation from the Base Definitions.

"The name space of environment variable names containing lowercase
letters is reserved for applications. Applications can define any
environment variables with names from this name space without modifying
the behavior of the standard utilities."

Thirdly, the absence of any consistent naming convention increases the
probability of a name space conflict. That is, there is a risk - no
matter how slight - that a user of the library may attempt to declare a
variable whose name conflicts, or sources code that does so. This might
interfere with feature detection or even affect runtime behaviour.

This commit goes some way towards addressing these concerns by renaming
five variables that are intended only for internal use. Each is given
a prefix of "genfun_" which makes it immediately apparent that it is
intended only for use by gentoo-functions, in any scope.

  COLS           => genfun_cols
  ENDCOL         => genfun_endcol
  LAST_E_CMD     => genfun_lastcall
  LAST_E_LEN     => genfun_lastbegun_strlen
  RC_INDENTATION => genfun_indent

Another seven variables were considered but left unchanged. Some define
various ECMA-48 SGR sequences and some ebuilds and scripts expect to
be able to expand them by their current names. Those were as follows.

  BAD
  BRACKET
  GOOD
  HILITE
  NORMAL
  RC_GOT_FUNCTIONS
  WARN

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 94 ++++++++++++++++++++++++++++++------------------------------
 1 file changed, 47 insertions(+), 47 deletions(-)

diff --git a/functions.sh b/functions.sh
index c911fe3..b223ce8 100644
--- a/functions.sh
+++ b/functions.sh
@@ -20,7 +20,7 @@ _esetdent()
 	if ! is_int "$1" || [ "$1" -lt 0 ]; then
 		set -- 0
 	fi
-	RC_INDENTATION=$(printf "%${1}s" '')
+	genfun_indent=$(printf "%${1}s" '')
 }
 
 #
@@ -31,7 +31,7 @@ eindent()
 	if ! is_int "$1" || [ "$1" -le 0 ]; then
 		set -- 2
 	fi
-	_esetdent "$(( ${#RC_INDENTATION} + $1 ))"
+	_esetdent "$(( ${#genfun_indent} + $1 ))"
 }
 
 #
@@ -42,7 +42,7 @@ eoutdent()
 	if ! is_int "$1" || [ "$1" -le 0 ]; then
 		set -- 2
 	fi
-	_esetdent "$(( ${#RC_INDENTATION} - $1 ))"
+	_esetdent "$(( ${#genfun_indent} - $1 ))"
 }
 
 #
@@ -110,11 +110,11 @@ einfon()
 	if yesno "${EINFO_QUIET}"; then
 		return 0
 	fi
-	if [ -z "${ENDCOL}" ] && [ "${LAST_E_CMD}" = "ebegin" ]; then
+	if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
 		printf "\n"
 	fi
-	printf " ${GOOD}*${NORMAL} ${RC_INDENTATION}$*"
-	LAST_E_CMD="einfon"
+	printf " ${GOOD}*${NORMAL} ${genfun_indent}$*"
+	genfun_lastcall="einfon"
 	return 0
 }
 
@@ -124,7 +124,7 @@ einfon()
 einfo()
 {
 	einfon "$*\n"
-	LAST_E_CMD="einfo"
+	genfun_lastcall="einfo"
 	return 0
 }
 
@@ -136,16 +136,16 @@ ewarnn()
 	if yesno "${EINFO_QUIET}"; then
 		return 0
 	else
-		if [ -z "${ENDCOL}" ] && [ "${LAST_E_CMD}" = "ebegin" ]; then
+		if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
 			printf "\n" >&2
 		fi
-		printf " ${WARN}*${NORMAL} ${RC_INDENTATION}$*" >&2
+		printf " ${WARN}*${NORMAL} ${genfun_indent}$*" >&2
 	fi
 
 	# Log warnings to system log
 	esyslog "daemon.warning" "${0##*/}" "$@"
 
-	LAST_E_CMD="ewarnn"
+	genfun_lastcall="ewarnn"
 	return 0
 }
 
@@ -157,16 +157,16 @@ ewarn()
 	if yesno "${EINFO_QUIET}"; then
 		return 0
 	else
-		if [ -z "${ENDCOL}" ] && [ "${LAST_E_CMD}" = "ebegin" ]; then
+		if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
 			printf "\n" >&2
 		fi
-		printf " ${WARN}*${NORMAL} ${RC_INDENTATION}$*\n" >&2
+		printf " ${WARN}*${NORMAL} ${genfun_indent}$*\n" >&2
 	fi
 
 	# Log warnings to system log
 	esyslog "daemon.warning" "${0##*/}" "$@"
 
-	LAST_E_CMD="ewarn"
+	genfun_lastcall="ewarn"
 	return 0
 }
 
@@ -178,16 +178,16 @@ eerrorn()
 	if yesno "${EERROR_QUIET}"; then
 		return 1
 	else
-		if [ -z "${ENDCOL}" ] && [ "${LAST_E_CMD}" = "ebegin" ]; then
+		if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
 			printf "\n" >&2
 		fi
-		printf " ${BAD}*${NORMAL} ${RC_INDENTATION}$*" >&2
+		printf " ${BAD}*${NORMAL} ${genfun_indent}$*" >&2
 	fi
 
 	# Log errors to system log
 	esyslog "daemon.err" "${0##*/}" "$@"
 
-	LAST_E_CMD="eerrorn"
+	genfun_lastcall="eerrorn"
 	return 1
 }
 
@@ -199,16 +199,16 @@ eerror()
 	if yesno "${EERROR_QUIET}"; then
 		return 1
 	else
-		if [ -z "${ENDCOL}" ] && [ "${LAST_E_CMD}" = "ebegin" ]; then
+		if [ -z "${genfun_endcol}" ] && [ "${genfun_lastcall}" = "ebegin" ]; then
 			printf "\n" >&2
 		fi
-		printf " ${BAD}*${NORMAL} ${RC_INDENTATION}$*\n" >&2
+		printf " ${BAD}*${NORMAL} ${genfun_indent}$*\n" >&2
 	fi
 
 	# Log errors to system log
 	esyslog "daemon.err" "${0##*/}" "$@"
 
-	LAST_E_CMD="eerror"
+	genfun_lastcall="eerror"
 	return 1
 }
 
@@ -224,12 +224,12 @@ ebegin()
 
 	msg="${msg} ..."
 	einfon "${msg}"
-	if [ -n "${ENDCOL}" ]; then
+	if [ -n "${genfun_endcol}" ]; then
 		printf "\n"
 	fi
 
-	LAST_E_LEN="$(( 3 + ${#RC_INDENTATION} + ${#msg} ))"
-	LAST_E_CMD="ebegin"
+	genfun_lastbegun_strlen="$(( 3 + ${#genfun_indent} + ${#msg} ))"
+	genfun_lastcall="ebegin"
 	return 0
 }
 
@@ -268,11 +268,11 @@ _eend()
 		msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
 	fi
 
-	if [ -n "${ENDCOL}" ]; then
-		printf "${ENDCOL}  ${msg}\n"
+	if [ -n "${genfun_endcol}" ]; then
+		printf "${genfun_endcol}  ${msg}\n"
 	else
-		[ "${LAST_E_CMD}" = ebegin ] || LAST_E_LEN=0
-		printf "%$(( COLS - LAST_E_LEN - 6 ))s%b\n" '' "${msg}"
+		[ "${genfun_lastcall}" = ebegin ] || genfun_lastbegun_strlen=0
+		printf "%$(( genfun_cols - genfun_lastbegun_strlen - 6 ))s%b\n" '' "${msg}"
 	fi
 
 	return "${retval}"
@@ -288,7 +288,7 @@ eend()
 
 	CALLER=${CALLER:-eend} _eend eerror "$@"
 	retval=$?
-	LAST_E_CMD="eend"
+	genfun_lastcall="eend"
 	return "${retval}"
 }
 
@@ -302,7 +302,7 @@ ewend()
 
 	CALLER=${CALLER:-ewend} _eend ewarn "$@"
 	retval=$?
-	LAST_E_CMD="ewend"
+	genfun_lastcall="ewend"
 	return "${retval}"
 }
 
@@ -487,10 +487,10 @@ EINFO_VERBOSE="${EINFO_VERBOSE:-no}"
 RC_NOCOLOR="${RC_NOCOLOR:-no}"
 
 # Can the terminal handle endcols? Begin by assuming not.
-unset -v ENDCOL
+unset -v genfun_endcol
 
 # Set the initial value for e-message indentation.
-RC_INDENTATION=
+genfun_indent=
 
 # If either STDOUT or STDERR is not a tty, disable coloured output. A useful
 # improvement for  the future would be to have the individual logging functions
@@ -498,7 +498,7 @@ RC_INDENTATION=
 # to STDERR. For now, this is a reasonable compromise.
 if [ ! -t 1 ] || [ ! -t 2 ]; then
 	RC_NOCOLOR="yes"
-	ENDCOL=
+	genfun_endcol=
 fi
 
 for arg in "$@" ; do
@@ -511,7 +511,7 @@ for arg in "$@" ; do
 	esac
 done
 
-# Define COLS and ENDCOL so that eend can line up the [ ok ].
+# Define genfun_cols and genfun_endcol so that eend can line up the [ ok ].
 # shellcheck disable=3044
 if [ -n "${BASH}" ] && shopt -s checkwinsize 2>/dev/null; then
 	# As is documented, running an external command will cause bash to set
@@ -522,28 +522,28 @@ if [ -n "${BASH}" ] && shopt -s checkwinsize 2>/dev/null; then
 fi
 if is_int "${COLUMNS}" && [ "${COLUMNS}" -gt 0 ]; then
 	# The value of COLUMNS was likely set by a shell such as bash or mksh.
-	COLS=${COLUMNS}
+	genfun_cols=${COLUMNS}
 else
 	# Try to use stty(1) to determine the number of columns. The use of the
 	# size operand is not portable.
-	COLS=$(
+	genfun_cols=$(
 		stty size 2>/dev/null | {
 			if read -r _ cols _; then
 				printf '%s\n' "${cols}"
 			fi
 		}
 	)
-	if ! is_int "${COLS}" || [ "${COLS}" -le 0 ]; then
+	if ! is_int "${genfun_cols}" || [ "${genfun_cols}" -le 0 ]; then
 		# Give up and assume 80 available columns.
-		COLS=80
+		genfun_cols=80
 	fi
 fi
 
-if [ -z "${ENDCOL+set}" ]; then
+if [ -z "${genfun_endcol+set}" ]; then
 	if hash tput 2>/dev/null; then
-		ENDCOL="$(tput cuu1)$(tput cuf $(( COLS - 8 )) )"
+		genfun_endcol="$(tput cuu1)$(tput cuf $(( genfun_cols - 8 )) )"
 	else
-		ENDCOL='\033[A\033['$(( COLS - 8 ))'C'
+		genfun_endcol='\033[A\033['$(( genfun_cols - 8 ))'C'
 	fi
 fi
 
@@ -551,14 +551,14 @@ fi
 if yesno "${RC_NOCOLOR}"; then
 	unset -v BAD BRACKET GOOD HILITE NORMAL WARN
 elif { hash tput && tput colors >/dev/null; } 2>/dev/null; then
-	genfuncs_bold=$(tput bold) genfuncs_norm=$(tput sgr0)
-	BAD="${genfuncs_norm}${genfuncs_bold}$(tput setaf 1)"
-	BRACKET="${genfuncs_norm}${genfuncs_bold}$(tput setaf 4)"
-	GOOD="${genfuncs_norm}${genfuncs_bold}$(tput setaf 2)"
-	HILITE="${genfuncs_norm}${genfuncs_bold}$(tput setaf 6)"
-	NORMAL="${genfuncs_norm}"
-	WARN="${genfuncs_norm}${genfuncs_bold}$(tput setaf 3)"
-	unset -v genfuncs_bold genfuncs_norm
+	genfun_bold=$(tput bold) genfun_norm=$(tput sgr0)
+	BAD="${genfun_norm}${genfun_bold}$(tput setaf 1)"
+	BRACKET="${genfun_norm}${genfun_bold}$(tput setaf 4)"
+	GOOD="${genfun_norm}${genfun_bold}$(tput setaf 2)"
+	HILITE="${genfun_norm}${genfun_bold}$(tput setaf 6)"
+	NORMAL="${genfun_norm}"
+	WARN="${genfun_norm}${genfun_bold}$(tput setaf 3)"
+	unset -v genfun_bold genfun_norm
 else
 	BAD=$(printf '\033[31;01m')
 	BRACKET=$(printf '\033[34;01m')


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-15  2:24 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-15  2:24 UTC (permalink / raw
  To: gentoo-commits

commit:     4f3b38f5c910980352c76de3f99b3bd4d6534cbc
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Feb 15 00:51:10 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 15 02:14:13 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=4f3b38f5

Drop the RC_DEFAULT_INDENT variable

Clearly, it's not intended to be configurable, otherwise it would have
been written as RC_DEFAULT_INDENT=${RC_DEFAULT_INDENT:-2}. It is only
expanded in two places, so things are made simpler by getting rid of it.
Doing so further increases the reliability of the library.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index 19e4a37..c911fe3 100644
--- a/functions.sh
+++ b/functions.sh
@@ -29,7 +29,7 @@ _esetdent()
 eindent()
 {
 	if ! is_int "$1" || [ "$1" -le 0 ]; then
-		set -- "${RC_DEFAULT_INDENT}"
+		set -- 2
 	fi
 	_esetdent "$(( ${#RC_INDENTATION} + $1 ))"
 }
@@ -40,7 +40,7 @@ eindent()
 eoutdent()
 {
 	if ! is_int "$1" || [ "$1" -le 0 ]; then
-		set -- "${RC_DEFAULT_INDENT}"
+		set -- 2
 	fi
 	_esetdent "$(( ${#RC_INDENTATION} - $1 ))"
 }
@@ -489,9 +489,8 @@ RC_NOCOLOR="${RC_NOCOLOR:-no}"
 # Can the terminal handle endcols? Begin by assuming not.
 unset -v ENDCOL
 
-# Default values for e-message indentation and dots
-RC_INDENTATION=''
-RC_DEFAULT_INDENT=2
+# Set the initial value for e-message indentation.
+RC_INDENTATION=
 
 # If either STDOUT or STDERR is not a tty, disable coloured output. A useful
 # improvement for  the future would be to have the individual logging functions


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-14  3:40 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-14  3:40 UTC (permalink / raw
  To: gentoo-commits

commit:     1af833c06ecd9750d69bb291d4ff01fd0f88c8d2
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb 14 00:18:39 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb 14 03:39:48 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1af833c0

Fix a typo in eend() whereby the wrong function name is given to _eend()

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Fixes: f97465ca0bf8134f811c3a89af25693a2802c31b
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 8a2a788..a5d6502 100644
--- a/functions.sh
+++ b/functions.sh
@@ -286,7 +286,7 @@ eend()
 {
 	local retval
 
-	_eend error "$@"
+	_eend eerror "$@"
 	retval=$?
 	LAST_E_CMD="eend"
 	return "${retval}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-14  3:40 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-14  3:40 UTC (permalink / raw
  To: gentoo-commits

commit:     e6165f114e4e640dee266af7f0aeef174a930bbc
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb 14 00:48:30 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb 14 03:39:49 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=e6165f11

Permit the empty string to directly indicate falsehood in yesno()

This restores the prior behaviour of not issuing warnings with ewarn()
for the empty string. Though it could only happen where EINFO_VERBOSE
was enabled, doing so generated too many insufficiently useful warnings.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 82d2192..c80bc41 100644
--- a/functions.sh
+++ b/functions.sh
@@ -54,7 +54,7 @@ yesno()
 {
 	for _ in 1 2; do
 		case $1 in
-			[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
+			[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0|'')
 				return 1
 				;;
 			[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-14  3:40 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-14  3:40 UTC (permalink / raw
  To: gentoo-commits

commit:     e650022a1291ab98efd2af02a4c83c395e2d5fa1
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb 14 00:29:41 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb 14 03:39:49 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=e650022a

Validate the exit status given to veend() and vewend() as an argument

Presently, both functions trust that the first argument is either empty
or a valid exit status code. If given a bogus value, the call to return
may cause sh(1) to unceremoniously exit, as demonstrated below.

$ dash -c 'return junk; echo done'
dash: 1: return: Illegal number: junk

Instead, validate that the argument is an integer whose value is greater
than or equal to 0. Should validation fail, a diagnostic mesage will be
printed to STDERR and the return value will be 0, provided that the call
to print succeeded.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index a5d6502..28764d8 100644
--- a/functions.sh
+++ b/functions.sh
@@ -346,8 +346,10 @@ veend()
 {
 	if yesno "${EINFO_VERBOSE}"; then
 		eend "$@"
+	elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then
+		printf 'Invalid argument given to veend (the exit status code must be an integer >= 0)\n' >&2
 	else
-		return "${1:-0}"
+		return "$1"
 	fi
 }
 
@@ -355,8 +357,10 @@ vewend()
 {
 	if yesno "${EINFO_VERBOSE}"; then
 		ewend "$@"
+	elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then
+		printf 'Invalid argument given to vewend (the exit status code must be an integer >= 0)\n' >&2
 	else
-		return "${1:-0}"
+		return "$1"
 	fi
 }
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-14  3:40 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-14  3:40 UTC (permalink / raw
  To: gentoo-commits

commit:     ee5ecbda72c1b6f39878ef16d52d48a4d7d0636d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb 14 00:38:12 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb 14 03:39:49 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=ee5ecbda

Have _eend() show the name of the calling function in its diagnostics

Currently, the diagnostic message reports that an invalid argument was
given to "_eend". Given that it is intended as a private function, users
of this library would be better off seeing the name of the function that
they originally invoked. Make it possible by having eend(), ewend(),
veend() and vewend() set the CALLER variable in the execution
environment of _eend(), duly affecting the content of the message.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index 28764d8..82d2192 100644
--- a/functions.sh
+++ b/functions.sh
@@ -249,7 +249,7 @@ _eend()
 	if [ "$#" -eq 0 ]; then
 		retval=0
 	elif ! is_int "$1" || [ "$1" -lt 0 ]; then
-		printf 'Invalid argument given to _eend (the exit status code must be an integer >= 0)\n' >&2
+		printf 'Invalid argument given to %s (the exit status code must be an integer >= 0)\n' "${CALLER}" >&2
 		retval=0
 		shift
 	else
@@ -286,7 +286,7 @@ eend()
 {
 	local retval
 
-	_eend eerror "$@"
+	CALLER=${CALLER:-eend} _eend eerror "$@"
 	retval=$?
 	LAST_E_CMD="eend"
 	return "${retval}"
@@ -300,7 +300,7 @@ ewend()
 {
 	local retval
 
-	_eend ewarn "$@"
+	CALLER=${CALLER:-ewend} _eend ewarn "$@"
 	retval=$?
 	LAST_E_CMD="ewend"
 	return "${retval}"
@@ -345,7 +345,7 @@ vebegin()
 veend()
 {
 	if yesno "${EINFO_VERBOSE}"; then
-		eend "$@"
+		CALLER=veend eend "$@"
 	elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then
 		printf 'Invalid argument given to veend (the exit status code must be an integer >= 0)\n' >&2
 	else
@@ -356,7 +356,7 @@ veend()
 vewend()
 {
 	if yesno "${EINFO_VERBOSE}"; then
-		ewend "$@"
+		CALLER=vewend ewend "$@"
 	elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then
 		printf 'Invalid argument given to vewend (the exit status code must be an integer >= 0)\n' >&2
 	else


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-14  0:09 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-14  0:09 UTC (permalink / raw
  To: gentoo-commits

commit:     d874f5ca008b2838925194347f76139acdcc43ba
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb 13 23:00:00 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb 14 00:08:13 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d874f5ca

Have is_older_than() check the argument count and guard against errexit

If fewer than 2 arguments are provided, print a diagnostic message to
STDERR before immediately returning. Doing so allows for an
unconditional shift.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index 51c6dbd..8a2a788 100644
--- a/functions.sh
+++ b/functions.sh
@@ -416,12 +416,15 @@ is_older_than()
 {
 	local ref has_gfind
 
-	if [ -e "$1" ]; then
+	if [ "$#" -lt 2 ]; then
+		printf 'Too few arguments for is_older_than (got %d, expected at least 2)\n' "$#" >&2
+		return 1
+	elif [ -e "$1" ]; then
 		ref=$1
 	else
 		ref=
 	fi
-	[ "$#" -gt 0 ] && shift
+	shift
 
 	# Consult the hash table in the present shell, prior to forking.
 	hash gfind 2>/dev/null; has_gfind=$(( $? == 0 ))


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-14  0:09 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-14  0:09 UTC (permalink / raw
  To: gentoo-commits

commit:     26d09671f8994d7e1ac43d743f77a1f10e8d92c9
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb 13 23:02:49 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb 14 00:08:13 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=26d09671

test-functions: Also test is_older_than with just one argument

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/test-functions b/test-functions
index df838f7..2c1fa67 100755
--- a/test-functions
+++ b/test-functions
@@ -27,6 +27,10 @@ cleanup_tmpdir() {
 test_is_older_than() {
 	set -- \
 		1  N/A           N/A \
+		1  newer         N/A \
+		1  newer-empty   N/A \
+		1  newer/file    N/A \
+		1  non-existent  N/A \
 		0  newer         newer \
 		1  newer         newer-empty \
 		0  newer         newer/file \


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-13 21:37 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-13 21:37 UTC (permalink / raw
  To: gentoo-commits

commit:     786a135634a062f3eb1c1dc46e8e46a9f22aba57
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb 13 03:11:44 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb 13 21:35:26 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=786a1356

Add an _is_visible() function and use it internally

Joining one or more positional parameters by the first character of IFS
then checking whether the resulting string has a length of zero, is not
an effective way of determining whether the collective message is
blank. This implements a helper function that implements the check in
the fashion that was seemingly intended.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/functions.sh b/functions.sh
index 9bae772..2361808 100644
--- a/functions.sh
+++ b/functions.sh
@@ -91,12 +91,11 @@ esyslog()
 		tag=$2
 		shift 2
 		msg=$*
-		case ${msg} in
-			*[[:graph:]]*)
-				# This is not strictly portable because POSIX
-				# defines no options whatsoever for logger(1).
-				logger -p "${pri}" -t "${tag}" -- "${msg}"
-		esac
+		if _is_visible "${msg}"; then
+			# This is not strictly portable because POSIX defines
+			# no options whatsoever for logger(1).
+			logger -p "${pri}" -t "${tag}" -- "${msg}"
+		fi
 	fi
 }
 
@@ -244,7 +243,7 @@ _eend()
 	shift 2
 
 	if [ "${retval}" != "0" ]; then
-		if [ -n "$*" ]; then
+		if _is_visible "$*"; then
 			"${efunc}" "$*"
 		fi
 		msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
@@ -431,6 +430,14 @@ is_int() {
 	esac
 }
 
+#
+#   Determine whether the first operand contains any visible characters. This
+#   is intended to be a private function.
+#
+_is_visible() {
+	! case $1 in *[[:graph:]]*) false ;; esac
+}
+
 # This is the main script, please add all functions above this point!
 
 # Dont output to stdout?


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-13 21:37 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-13 21:37 UTC (permalink / raw
  To: gentoo-commits

commit:     d21e27f228a99a0f4c2ed2d534fa5cc8040212f6
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb 13 05:55:59 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb 13 21:36:17 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d21e27f2

Return the correct exit status from _eend() where EINFO_QUIET is enabled

For EINFO_QUIET to be in effect is not a valid pretext for returning 0.
This bug is as old as the repository itself.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 26a4d7a..51c6dbd 100644
--- a/functions.sh
+++ b/functions.sh
@@ -263,7 +263,7 @@ _eend()
 		fi
 		msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
 	elif yesno "${EINFO_QUIET}"; then
-		return 0
+		return "${retval}"
 	else
 		msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
 	fi


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-13 21:37 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-13 21:37 UTC (permalink / raw
  To: gentoo-commits

commit:     df52bb0f4b48f3abd935709770a66107a38196d8
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb 13 02:12:17 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb 13 05:29:40 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=df52bb0f

Alleviate and/or mute some ineffectual shellcheck warnings

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/functions.sh b/functions.sh
index aa3d1d9..9bae772 100644
--- a/functions.sh
+++ b/functions.sh
@@ -7,6 +7,7 @@
 # not use bashisms.
 #
 
+# shellcheck disable=2034
 RC_GOT_FUNCTIONS="yes"
 
 #
@@ -407,7 +408,7 @@ is_older_than()
 			find "$@"
 		fi
 	} |
-	read -r line
+	read -r _
 }
 
 #
@@ -465,6 +466,7 @@ for arg in "$@" ; do
 done
 
 # Define COLS and ENDCOL so that eend can line up the [ ok ].
+# shellcheck disable=3044
 if [ -n "${BASH}" ] && shopt -s checkwinsize 2>/dev/null; then
 	# As is documented, running an external command will cause bash to set
 	# the COLUMNS variable. This technique is effective for >=4.3, though
@@ -480,8 +482,8 @@ else
 	# size operand is not portable.
 	COLS=$(
 		stty size 2>/dev/null | {
-			if read -r h w _; then
-				printf '%s\n' "$w"
+			if read -r _ cols _; then
+				printf '%s\n' "${cols}"
 			fi
 		}
 	)


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-13 21:37 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-13 21:37 UTC (permalink / raw
  To: gentoo-commits

commit:     747923957049eb32c2a7b6aa5e52c12e6dcc561e
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb 13 03:52:24 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb 13 21:35:40 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=74792395

Guard against errexit in the v-prefixed functions

This also improves the structure of some of them, slightly.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 43 +++++++++++++++++++++++++++++++------------
 1 file changed, 31 insertions(+), 12 deletions(-)

diff --git a/functions.sh b/functions.sh
index 2361808..3c782cd 100644
--- a/functions.sh
+++ b/functions.sh
@@ -294,52 +294,71 @@ ewend()
 }
 
 # v-e-commands honor EINFO_VERBOSE which defaults to no.
-# The condition is negated so the return value will be zero.
 veinfo()
 {
-	yesno "${EINFO_VERBOSE}" && einfo "$@"
+	if yesno "${EINFO_VERBOSE}"; then
+		einfo "$@"
+	fi
 }
 
 veinfon()
 {
-	yesno "${EINFO_VERBOSE}" && einfon "$@"
+	if yesno "${EINFO_VERBOSE}"; then
+		einfon "$@"
+	fi
 }
 
 vewarn()
 {
-	yesno "${EINFO_VERBOSE}" && ewarn "$@"
+	if yesno "${EINFO_VERBOSE}"; then
+		ewarn "$@"
+	fi
 }
 
 veerror()
 {
-	yesno "${EINFO_VERBOSE}" && eerror "$@"
+	if yesno "${EINFO_VERBOSE}"; then
+		eerror "$@"
+	fi
 }
 
 vebegin()
 {
-	yesno "${EINFO_VERBOSE}" && ebegin "$@"
+	if yesno "${EINFO_VERBOSE}"; then
+		ebegin "$@"
+	fi
 }
 
 veend()
 {
-	yesno "${EINFO_VERBOSE}" && { eend "$@"; return $?; }
-	return "${1:-0}"
+	if yesno "${EINFO_VERBOSE}"; then
+		eend "$@"
+	else
+		return "${1:-0}"
+	fi
 }
 
 vewend()
 {
-	yesno "${EINFO_VERBOSE}" && { ewend "$@"; return $?; }
-	return "${1:-0}"
+	if yesno "${EINFO_VERBOSE}"; then
+		ewend "$@"
+	else
+		return "${1:-0}"
+	fi
 }
 
 veindent()
 {
-	yesno "${EINFO_VERBOSE}" && eindent
+	if yesno "${EINFO_VERBOSE}"; then
+		eindent
+	fi
 }
 
 veoutdent()
 {
-	yesno "${EINFO_VERBOSE}" && eoutdent
+	if yesno "${EINFO_VERBOSE}"; then
+		eoutdent
+	fi
 }
 
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-13 21:37 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-13 21:37 UTC (permalink / raw
  To: gentoo-commits

commit:     279ff36af3eada93776a5001f6125be12aea9241
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb 13 02:09:58 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb 13 05:29:40 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=279ff36a

Add global shellcheck hints

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/functions.sh b/functions.sh
index 7882113..aa3d1d9 100644
--- a/functions.sh
+++ b/functions.sh
@@ -1,5 +1,6 @@
 # Copyright 1999-2023 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
+# shellcheck shell=sh disable=3043
 
 #
 # All functions in this file should be written in POSIX sh. Please do


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-13 21:37 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-13 21:37 UTC (permalink / raw
  To: gentoo-commits

commit:     f97465ca0bf8134f811c3a89af25693a2802c31b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb 13 05:20:25 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb 13 21:35:54 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f97465ca

Improve the __end(), eend() and ewend() functions

The _eend() function has a poor calling convention because, while both
eend() and ewend() always pass a function name, _eend() expects for it
to be the second argument. A better design would be for mandatory
arguments to precede optional ones. Make it so.

Also, implement a parameter validation routine for the optionally
specified exit status code. It determines whether the parameter is in
the form of an integer and whether its value is greater than or equal
to 0. Should the parameter be considered invalid, a diagnostic message
will be printed to STDERR and its value will be taken as if it were 0.
Note that negative values are not necessarily tolerated by builtins such
as return and exit. As is shown below, they may cause sh(1) to exit.

$ dash -c 'return -1; echo done'
dash: 1: return: Illegal number: -1

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/functions.sh b/functions.sh
index 38c49fd..26a4d7a 100644
--- a/functions.sh
+++ b/functions.sh
@@ -242,10 +242,22 @@ ebegin()
 #
 _eend()
 {
-	local retval="${1:-0}" efunc="${2:-eerror}" msg
-	shift 2
+	local efunc msg retval
+
+	efunc=$1
+	shift
+	if [ "$#" -eq 0 ]; then
+		retval=0
+	elif ! is_int "$1" || [ "$1" -lt 0 ]; then
+		printf 'Invalid argument given to _eend (the exit status code must be an integer >= 0)\n' >&2
+		retval=0
+		shift
+	else
+		retval=$1
+		shift
+	fi
 
-	if [ "${retval}" != "0" ]; then
+	if [ "${retval}" -ne 0 ]; then
 		if _is_visible "$*"; then
 			"${efunc}" "$*"
 		fi
@@ -272,11 +284,10 @@ _eend()
 #
 eend()
 {
-	local retval="${1:-0}"
-	[ $# -eq 0 ] || shift
-
-	_eend "${retval}" eerror "$*"
+	local retval
 
+	_eend error "$@"
+	retval=$?
 	LAST_E_CMD="eend"
 	return "${retval}"
 }
@@ -287,11 +298,10 @@ eend()
 #
 ewend()
 {
-	local retval="${1:-0}"
-	[ $# -eq 0 ] || shift
-
-	_eend "${retval}" ewarn "$*"
+	local retval
 
+	_eend ewarn "$@"
+	retval=$?
 	LAST_E_CMD="ewend"
 	return "${retval}"
 }


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-13 21:37 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-13 21:37 UTC (permalink / raw
  To: gentoo-commits

commit:     17a4c845a6b36a48327051eb1f3662b3704bb820
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb 13 04:17:44 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb 13 21:35:40 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=17a4c845

Improve the _esetdent(), eindent() and eoutdent() functions

Eliminate the useless use of the (non-standard) local builtin.

Use is_int() to validate that the first argument is an integer.

Use if, as opposed to the somewhat contorted combinations of the && and
|| control operators.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/functions.sh b/functions.sh
index 4747b0e..38c49fd 100644
--- a/functions.sh
+++ b/functions.sh
@@ -17,9 +17,10 @@ RC_GOT_FUNCTIONS="yes"
 #
 _esetdent()
 {
-	local i="$1"
-	[ -z "$i" ] || [ "$i" -lt 0 ] && i=0
-	RC_INDENTATION=$(printf "%${i}s" '')
+	if ! is_int "$1" || [ "$1" -lt 0 ]; then
+		set -- 0
+	fi
+	RC_INDENTATION=$(printf "%${1}s" '')
 }
 
 #
@@ -27,9 +28,10 @@ _esetdent()
 #
 eindent()
 {
-	local i="$1"
-	[ -n "$i" ] && [ "$i" -gt 0 ] || i=${RC_DEFAULT_INDENT}
-	_esetdent $(( ${#RC_INDENTATION} + i ))
+	if ! is_int "$1" || [ "$1" -le 0 ]; then
+		set -- "${RC_DEFAULT_INDENT}"
+	fi
+	_esetdent "$(( ${#RC_INDENTATION} + $1 ))"
 }
 
 #
@@ -37,9 +39,10 @@ eindent()
 #
 eoutdent()
 {
-	local i="$1"
-	[ -n "$i" ] && [ "$i" -gt 0 ] || i=${RC_DEFAULT_INDENT}
-	_esetdent $(( ${#RC_INDENTATION} - i ))
+	if ! is_int "$1" || [ "$1" -le 0 ]; then
+		set -- "${RC_DEFAULT_INDENT}"
+	fi
+	_esetdent "$(( ${#RC_INDENTATION} - $1 ))"
 }
 
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-13 21:37 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-13 21:37 UTC (permalink / raw
  To: gentoo-commits

commit:     755410e6ef4a7562d68b4c0288efd569696979b6
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb 13 04:02:28 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb 13 21:35:40 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=755410e6

Have veindent() and veoutdent() propagate the positional parameters

There is no apparent reason for them not to do so. This also alleviates
some SC2219 and SC2120 warnings issued by shellcheck.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index 3c782cd..4747b0e 100644
--- a/functions.sh
+++ b/functions.sh
@@ -350,14 +350,14 @@ vewend()
 veindent()
 {
 	if yesno "${EINFO_VERBOSE}"; then
-		eindent
+		eindent "$@"
 	fi
 }
 
 veoutdent()
 {
 	if yesno "${EINFO_VERBOSE}"; then
-		eoutdent
+		eoutdent "$@"
 	fi
 }
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-12 18:53 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-12 18:53 UTC (permalink / raw
  To: gentoo-commits

commit:     b675ffe825a13789f240d94312e8cff472c34418
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Feb 12 09:19:07 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 12 18:12:40 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b675ffe8

test-functions: Add a test for the yesno() function

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/test-functions b/test-functions
index 9f4dfc5..df838f7 100755
--- a/test-functions
+++ b/test-functions
@@ -181,6 +181,44 @@ test_is_int() {
 		iterate_tests 2 "$@"
 }
 
+test_yesno() {
+	set -- \
+		0  yes \
+		0  YES \
+		0  Yes \
+		0  true \
+		0  TRUE \
+		0  true \
+		0  on \
+		0  ON \
+		0  On \
+		0  1 \
+		1  no \
+		1  NO \
+		1  No \
+		1  false \
+		1  FALSE \
+		1  False \
+		1  off \
+		1  OFF \
+		1  Off \
+		1  0 \
+		1  not_a_nameref \
+		1  not-a-valid-nameref \
+		1  '_"; set -- yes # code injection' \
+		0  truthful_nameref
+
+		truthful_nameref=yes
+
+		callback() {
+			shift
+			test_description="yesno $(print_args "$@")"
+			yesno "$@"
+		}
+
+		iterate_tests 2 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -246,5 +284,6 @@ test_is_older_than || rc=1
 test_get_bootparam || rc=1
 test_esyslog || rc=1
 test_is_int || rc=1
+test_yesno || rc=1
 cleanup_tmpdir
 exit "${rc}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-12 18:53 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-12 18:53 UTC (permalink / raw
  To: gentoo-commits

commit:     b654697f3d39014e4600ec5f314a7e94a0637c26
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Feb 12 09:14:13 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 12 18:12:21 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b654697f

Prevent code injection and naming conflicts in yesno()

Currently, the yesno() function works by first trying to match the first
argument against a series of patterns that would reasonably indicate a
truthful or falseful value. If it fails to do so, it proceeds to treat
the argument as if it were a name reference. However, it does so without
bothering to check whether its value could be a legal variable name in
the first place, which is extremely dangerous! Below is a trivial
example of a code injection.

$ . ./functions.sh
$ untrusted_input='_; echo "you just got pwned"'
$ yesno "$untrusted_input"
you just got pwned

Frankly, I think the name dereferencing is a monumental anti-feature and
would urge that it be removed. However, it is beyond my purview to make
such a decision. Instead, add a check to ensure that the name appears to
be a valid one before calling upon eval. Here is the same test, as
conducted against the new implementation.

$ yesno "$untrusted_input"
$ echo $?
1
$ EINFO_VERBOSE=1
$ yesno "$untrusted_input"
 * Invalid argument given to yesno (expected a boolean-like or a legal name)

Another issue with allowing for name dereferencing is that, by its very
nature, it is anethema to the use of the (non-standard) local builtin.
Here is a concrete example of the prior implementation producing a bogus
warning and returning the wrong exit status value entirely.

$ value=yes
$ yesno value
 * $value is not set properly
$ echo $?
1

Compare and contrast to the new implementation, which works correctly.

$ yesno value
$ echo $?
0

This has been accomplished by eradicating the use of local. Now only the
first positional parameter and _ are ever assigned to, with the latter
variable being used a loop iterator. This is rather unconventional but
is, nevertheless, safe. Although _ is a special variable, its value
will not normally be affected by the shell until the enclosing compound
command has concluded. Further, any conforming implementation of sh(1)
is able to use a for loop to assign to it.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 39 +++++++++++++++++++++++++--------------
 1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/functions.sh b/functions.sh
index 6ad22f3..7882113 100644
--- a/functions.sh
+++ b/functions.sh
@@ -47,20 +47,31 @@ eoutdent()
 #
 yesno()
 {
-	[ -z "$1" ] && return 1
-
-	case "$1" in
-		[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0;;
-		[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1;;
-	esac
-
-	local value=
-	eval "value=\$${1}"
-	case "$value" in
-		[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0;;
-		[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1;;
-		*) vewarn "\$$1 is not set properly"; return 1;;
-	esac
+	for _ in 1 2; do
+		case $1 in
+			[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
+				return 1
+				;;
+			[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
+				return 0
+		esac
+		if [ "$_" -gt 1 ]; then
+			! break
+		else
+			# Using eval can be very dangerous. Check whether the
+			# value is a legitimate variable name before proceeding
+			# to treat it as one.
+			(
+				LC_ALL=C
+				case $1 in
+					''|_|[[:digit:]]*|*[!_[:alnum:]]*) exit 1
+				esac
+			) || ! break
+			# Treat the value as a nameref then try again.
+			eval "set -- \"\$$1\""
+		fi
+	done || vewarn "Invalid argument given to yesno (expected a boolean-like or a legal name)"
+	return 1
 }
 
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-12  6:53 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-12  6:53 UTC (permalink / raw
  To: gentoo-commits

commit:     3c7f54101cfaf566572d37de98e0c5ba4743270b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 11 07:20:06 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 12 06:53:20 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=3c7f5410

Guard against errexit in _eend()

Further relief is thus duly administered to the cult of set -e.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/functions.sh b/functions.sh
index 33ef26e..6092841 100644
--- a/functions.sh
+++ b/functions.sh
@@ -230,14 +230,15 @@ _eend()
 	local retval="${1:-0}" efunc="${2:-eerror}" msg
 	shift 2
 
-	if [ "${retval}" = "0" ]; then
-		yesno "${EINFO_QUIET}" && return 0
-		msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
-	else
-		if [ -n "$*" ] ; then
-			${efunc} "$*"
+	if [ "${retval}" != "0" ]; then
+		if [ -n "$*" ]; then
+			"${efunc}" "$*"
 		fi
 		msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
+	elif yesno "${EINFO_QUIET}"; then
+		return 0
+	else
+		msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
 	fi
 
 	if yesno "${RC_ENDCOL}"; then


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-12  6:53 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-12  6:53 UTC (permalink / raw
  To: gentoo-commits

commit:     bfc30a7744ad0043969969250f01c4d3fd74fc55
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 11 01:20:45 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 12 06:53:17 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=bfc30a77

Attend to several instances of SC2086, courtesy of shellcheck

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/functions.sh b/functions.sh
index eb9a168..33ef26e 100644
--- a/functions.sh
+++ b/functions.sh
@@ -55,7 +55,7 @@ yesno()
 	esac
 
 	local value=
-	eval value=\$${1}
+	eval "value=\$${1}"
 	case "$value" in
 		[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0;;
 		[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1;;
@@ -247,7 +247,7 @@ _eend()
 		printf "%$(( COLS - LAST_E_LEN - 6 ))s%b\n" '' "${msg}"
 	fi
 
-	return ${retval}
+	return "${retval}"
 }
 
 #
@@ -262,7 +262,7 @@ eend()
 	_eend "${retval}" eerror "$*"
 
 	LAST_E_CMD="eend"
-	return ${retval}
+	return "${retval}"
 }
 
 #
@@ -277,7 +277,7 @@ ewend()
 	_eend "${retval}" ewarn "$*"
 
 	LAST_E_CMD="ewend"
-	return ${retval}
+	return "${retval}"
 }
 
 # v-e-commands honor EINFO_VERBOSE which defaults to no.
@@ -310,13 +310,13 @@ vebegin()
 veend()
 {
 	yesno "${EINFO_VERBOSE}" && { eend "$@"; return $?; }
-	return ${1:-0}
+	return "${1:-0}"
 }
 
 vewend()
 {
 	yesno "${EINFO_VERBOSE}" && { ewend "$@"; return $?; }
-	return ${1:-0}
+	return "${1:-0}"
 }
 
 veindent()


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-12  6:53 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-12  6:53 UTC (permalink / raw
  To: gentoo-commits

commit:     828ecbd3d8b768f5cbc36d1dd63d7ce0fdde8e44
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 11 07:22:39 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Feb 12 06:53:20 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=828ecbd3

Drop the unused RC_DOT_PATTERN variable

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 1 -
 1 file changed, 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 6092841..6ad22f3 100644
--- a/functions.sh
+++ b/functions.sh
@@ -432,7 +432,6 @@ RC_ENDCOL="yes"
 # Default values for e-message indentation and dots
 RC_INDENTATION=''
 RC_DEFAULT_INDENT=2
-RC_DOT_PATTERN=''
 
 # If either STDOUT or STDERR is not a tty, disable coloured output. A useful
 # improvement for  the future would be to have the individual logging functions


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-11  1:43 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-11  1:43 UTC (permalink / raw
  To: gentoo-commits

commit:     9b3c0592552ecba127fd872b8ba168efea0fdaaf
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 10 23:46:10 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Feb 11 01:29:27 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9b3c0592

Ensure that COLUMNS is set in the case that /bin/sh is bash

To reasonably ensure that the COLUMNS variable is set requires for
three conditions to be fulfilled. Firstly, the version of bash must be
at least 4.3. Secondly, the checkwinsize shopt must be enabled (since
5.0, it is enabled by default). Thirdly, an external command must be
executed.

Better fulfil these conditions by checking whether the shell appears to
be bash and, should it appear to be, enabling checkwinsize before
executing /bin/true. Determining the number of columns in this way is
preferable to falling back to the method of attempting to use stty(1).

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 9ab8d0c..241f238 100644
--- a/functions.sh
+++ b/functions.sh
@@ -453,8 +453,15 @@ for arg in "$@" ; do
 done
 
 # Define COLS and ENDCOL so that eend can line up the [ ok ].
+if [ -n "${BASH}" ] && shopt -s checkwinsize 2>/dev/null; then
+	# As is documented, running an external command will cause bash to set
+	# the COLUMNS variable. This technique is effective for >=4.3, though
+	# it requires for the checkwinsize shopt to be enabled. By default, it
+	# is only enabled for >=5.0.
+	/bin/true
+fi
 if is_int "${COLUMNS}" && [ "${COLUMNS}" -gt 0 ]; then
-	# The value of COLUMNS was likely set by a shell such as bash. Trust it.
+	# The value of COLUMNS was likely set by a shell such as bash or mksh.
 	COLS=${COLUMNS}
 else
 	# Try to use stty(1) to determine the number of columns. The use of the


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-11  1:43 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-11  1:43 UTC (permalink / raw
  To: gentoo-commits

commit:     8447b39c08cd1cf2630fbce627594c54b373f0e5
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sat Feb 11 00:14:57 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Feb 11 01:29:29 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=8447b39c

Guard against errexit in the course of reading from stty(1)

Otherwise, it will only be a matter of time before a devotee of the
cult of set -e begins complaining.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 241f238..eb9a168 100644
--- a/functions.sh
+++ b/functions.sh
@@ -468,7 +468,9 @@ else
 	# size operand is not portable.
 	COLS=$(
 		stty size 2>/dev/null | {
-			read -r h w _ && printf '%s\n' "$w"
+			if read -r h w _; then
+				printf '%s\n' "$w"
+			fi
 		}
 	)
 	if ! is_int "${COLS}" || [ "${COLS}" -le 0 ]; then


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-10  6:09 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-10  6:09 UTC (permalink / raw
  To: gentoo-commits

commit:     027ffe6fa60995f2c18c66e992644a9d3092edb1
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 10 05:59:45 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 10 06:07:36 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=027ffe6f

test-functions: Add a test for the is_int() function

Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 38 +++++++++++++++++++++++++++++++++-----
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/test-functions b/test-functions
index 8db2191..9f4dfc5 100755
--- a/test-functions
+++ b/test-functions
@@ -156,6 +156,31 @@ test_esyslog() {
 	iterate_tests 5 "$@"
 }
 
+test_is_int() {
+	set -- \
+		1  N/A \
+		1  ' ' \
+		1  ' 1 ' \
+		1  '' \
+		1  +1 \
+		1  +008 \
+		1  -008 \
+		1  008 \
+		1  x \
+		0  0 \
+		0  1 \
+		0  -1 \
+		0  123456789
+
+		callback() {
+			shift
+			test_description="is_int $(print_args "$@")"
+			is_int "$@"
+		}
+
+		iterate_tests 2 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
@@ -192,11 +217,13 @@ print_args() {
 		if [ "$((i += 1))" -eq 1 ]; then
 			set --
 		fi
-		if [ -n "${arg}" ]; then
-			set -- "$@" "${arg}"
-		else
-			set -- "$@" "''"
-		fi
+		case ${arg} in
+			''|*[[:space:]]*)
+				set -- "$@" "'${arg}'"
+				;;
+			*)
+				set -- "$@" "${arg}"
+		esac
 	done
 	printf '%s\n' "$*"
 }
@@ -218,5 +245,6 @@ rc=0
 test_is_older_than || rc=1
 test_get_bootparam || rc=1
 test_esyslog || rc=1
+test_is_int || rc=1
 cleanup_tmpdir
 exit "${rc}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-10  6:09 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-10  6:09 UTC (permalink / raw
  To: gentoo-commits

commit:     92741aa01fcdc6535c3582a00a3cbe7c6a030e40
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 10 04:30:54 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 10 06:07:33 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=92741aa0

Improve the means by which the number of terminal columns is detected

The existing routine is not well structured and is perhaps a little too
trusting of its inputs. Clean it up and check that the value of COLUMNS
and the second field obtained from stty(1) are actually integers. To
this end, an is_int() function has been added. This function may yet
prove to be useful elsewhere.

This also fixes an instance of SC2068 by using read to consume the
output of stty(1), rather than perform word splitting and/or pathname
expansion. It also fixes an instance of SC2059 (format string abuse).

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 43 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git a/functions.sh b/functions.sh
index 9775e2c..9ab8d0c 100644
--- a/functions.sh
+++ b/functions.sh
@@ -397,6 +397,26 @@ is_older_than()
 	read -r line
 }
 
+#
+#   Determine whether the first operand is in the form of an integer. A leading
+#   <hypen-minus> shall be permitted. Thereafter, leading zeroes shall not be
+#   permitted because the string might later be considered to be octal in an
+#   arithmetic context, causing the shell to exit if the number be invalid.
+#
+is_int() {
+	set -- "${1#-}"
+	case $1 in
+		''|*[!0123456789]*)
+			false
+			;;
+		0)
+			true
+			;;
+		*)
+			test "$1" = "${1#0}"
+	esac
+}
+
 # This is the main script, please add all functions above this point!
 
 # Dont output to stdout?
@@ -432,12 +452,23 @@ for arg in "$@" ; do
 	esac
 done
 
-# Setup COLS and ENDCOL so eend can line up the [ ok ]
-COLS="${COLUMNS:-0}"            # bash's internal COLUMNS variable
-[ "${COLS}" -eq 0 ] && \
-        COLS="$(set -- $(stty size 2>/dev/null) ; printf "$2\n")"
-[ -z "${COLS}" ] && COLS=80
-[ "${COLS}" -gt 0 ] || COLS=80	# width of [ ok ] == 7
+# Define COLS and ENDCOL so that eend can line up the [ ok ].
+if is_int "${COLUMNS}" && [ "${COLUMNS}" -gt 0 ]; then
+	# The value of COLUMNS was likely set by a shell such as bash. Trust it.
+	COLS=${COLUMNS}
+else
+	# Try to use stty(1) to determine the number of columns. The use of the
+	# size operand is not portable.
+	COLS=$(
+		stty size 2>/dev/null | {
+			read -r h w _ && printf '%s\n' "$w"
+		}
+	)
+	if ! is_int "${COLS}" || [ "${COLS}" -le 0 ]; then
+		# Give up and assume 80 available columns.
+		COLS=80
+	fi
+fi
 
 if ! yesno "${RC_ENDCOL}"; then
 	ENDCOL=''


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-10  6:09 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-10  6:09 UTC (permalink / raw
  To: gentoo-commits

commit:     0c9a68e0915b7c10aea37f2209579858a3d010dd
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 10 03:29:07 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 10 06:07:30 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=0c9a68e0

Consistently specify the tag where calling esyslog()

In some cases, the tag name is specified as "rc-scripts" whereas, in
others, it is specified as "${0##*/}". Consistently use the latter.

Eliminate some useless uses of the (non-portable) local builtin.

Convey the positional parameters to esyslog() with "$@". They end up
being re-joined, so they may as well be conveyed exactly as they were.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/functions.sh b/functions.sh
index f756a9f..9775e2c 100644
--- a/functions.sh
+++ b/functions.sh
@@ -127,9 +127,8 @@ ewarnn()
 		printf " ${WARN}*${NORMAL} ${RC_INDENTATION}$*" >&2
 	fi
 
-	local name="${0##*/}"
 	# Log warnings to system log
-	esyslog "daemon.warning" "${name}" "$*"
+	esyslog "daemon.warning" "${0##*/}" "$@"
 
 	LAST_E_CMD="ewarnn"
 	return 0
@@ -149,9 +148,8 @@ ewarn()
 		printf " ${WARN}*${NORMAL} ${RC_INDENTATION}$*\n" >&2
 	fi
 
-	local name="${0##*/}"
 	# Log warnings to system log
-	esyslog "daemon.warning" "${name}" "$*"
+	esyslog "daemon.warning" "${0##*/}" "$@"
 
 	LAST_E_CMD="ewarn"
 	return 0
@@ -171,9 +169,8 @@ eerrorn()
 		printf " ${BAD}*${NORMAL} ${RC_INDENTATION}$*" >&2
 	fi
 
-	local name="${0##*/}"
 	# Log errors to system log
-	esyslog "daemon.err" "rc-scripts" "$*"
+	esyslog "daemon.err" "${0##*/}" "$@"
 
 	LAST_E_CMD="eerrorn"
 	return 1
@@ -193,9 +190,8 @@ eerror()
 		printf " ${BAD}*${NORMAL} ${RC_INDENTATION}$*\n" >&2
 	fi
 
-	local name="${0##*/}"
 	# Log errors to system log
-	esyslog "daemon.err" "rc-scripts" "$*"
+	esyslog "daemon.err" "${0##*/}" "$@"
 
 	LAST_E_CMD="eerror"
 	return 1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-09  3:54 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-09  3:54 UTC (permalink / raw
  To: gentoo-commits

commit:     3cb2261328c1f8e46a4ecf2a7516c226f1c9f9d7
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Feb  9 02:52:56 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Feb  9 03:14:41 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=3cb22613

test-functions: Add a test for the esyslog() function

In order to facilitate the appropriate tests, the test suite was
adjusted slightly. Now, iterate_tests() will compose the code to be
evaluated for each test being conducted. Consequently, it is able to
recognise "N/A" as a special word to indicate that no further parameters
should be specified. In turn, that means that the callback() function
no longer needs to assume responsibility for recognising said word and
can instead work with the positional parameters it receives in a natural
fashion. Further, a print_args() function has been added that is used to
compose the test descriptions.

Also, further clarify the runtime requirements in the opening comment.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 120 +++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 83 insertions(+), 37 deletions(-)

diff --git a/test-functions b/test-functions
index d6471ed..8db2191 100755
--- a/test-functions
+++ b/test-functions
@@ -1,7 +1,9 @@
 #!/bin/sh
 # shellcheck disable=2015
-# Requires mktemp(1) and touch(1). The implementations provided by GNU
-# coreutils are compatible, as are the builtins provided by busybox.
+
+# Requires mktemp(1), which is not a standard utility, but is commonly
+# available. The implementations provided by GNU coreutils, busybox and toybox
+# are known to be compatible.
 
 bailout() {
 	printf 'Bail out! %s.\n' "$1"
@@ -88,13 +90,9 @@ test_is_older_than() {
 	done
 
 	callback() {
-		if [ "$2" != "N/A" ] && [ "$3" != "N/A" ]; then
-			description="is_older_than $2 $3"
-			is_older_than "$2" "$3"
-		else
-			description="is_older_than"
-			is_older_than
-		fi
+		shift
+		test_description="is_older_than $(print_args "$@")"
+		is_older_than "$@"
 	}
 
 	iterate_tests 3 "$@"
@@ -103,59 +101,106 @@ test_is_older_than() {
 test_get_bootparam() {
 	cmdline="foo gentoo=bar,baz quux"
 	set -- \
-		1  N/A       "${cmdline}" \
-		1  ''        "${cmdline}" \
-		1  ''        "gentoo=" \
-		1  foo       "${cmdline}" \
-		0  bar       "${cmdline}" \
-		0  bar       "foo gentoo=gentoo=1,bar baz" \
-		0  bar       "foo gentoo=bar,gentoo=1 baz" \
-		0  baz       "${cmdline}" \
-		1  bar,baz   "${cmdline}" \
-		0  gentoo=1  "foo gentoo=bar,gentoo=1 baz" \
-		0  gentoo=1  "foo gentoo=gentoo=1,bar baz" \
-		1  quux      "${cmdline}"
+		1  "${cmdline}"                   N/A \
+		1  "${cmdline}"                   '' \
+		1  "gentoo="                      '' \
+		1  "${cmdline}"                   foo \
+		0  "${cmdline}"                   bar \
+		0  "foo gentoo=gentoo=1,bar baz"  bar \
+		0  "foo gentoo=bar,gentoo=1 baz"  bar \
+		0  "${cmdline}"                   baz \
+		1  "${cmdline}"                   bar,baz \
+		0  "foo gentoo=bar,gentoo=1 baz"  gentoo=1 \
+		0  "foo gentoo=gentoo=1,bar baz"  gentoo=1 \
+		1  "${cmdline}"                   quux
 
 	callback() {
-		if [ "$2" = "N/A" ]; then
-			description="get_bootparam"
-			printf '%s\n' "$3" | get_bootparam
-		else
-			description="get_bootparam \"$2\""
-			printf '%s\n' "$3" | get_bootparam "$2"
-		fi
+		cmdline=$2
+		shift 2
+		test_description="get_bootparam $(print_args "$@")"
+		printf '%s\n' "${cmdline}" | get_bootparam "$@"
 	}
 
 	iterate_tests 3 "$@"
 }
 
+test_esyslog() {
+	set -- \
+		1  0  N/A    N/A   N/A \
+		1  0  debug  N/A   N/A \
+		0  0  debug  user  N/A \
+		0  0  debug  user  '' \
+		0  1  debug  user  message
+
+	logger() {
+		# esyslog() ignores empty messages. By overriding logger(1), it
+		# can be determined whether a message would have been logged.
+		logged=$((logged + 1))
+	}
+
+	callback() {
+		should_log=$2
+		shift 2
+		logged=0
+		test_description="esyslog $(print_args "$@")"
+		EINFO_LOG=1 esyslog "$@" 2>/dev/null
+		case $? in
+			0)
+				test "${logged}" -eq "${should_log}"
+				;;
+			*)
+				return "$?"
+		esac
+	}
+
+	iterate_tests 5 "$@"
+}
+
 iterate_tests() {
 	slice_width=$1
 	shift
 
 	total=$(( $# / slice_width ))
 	printf '1..%d\n' "${total}"
-	code="callback"
-	i=0
-	while [ "$((i += 1))" -le "${slice_width}" ]; do
-		code="${code} \"\$${i}\""
-	done
 	passed=0
-	i=1
-	while [ "${i}" -le "${total}" ]; do
+	i=0
+	while [ "$((i += 1))" -le "${total}" ]; do
+		code="callback"
+		j=0
+		while [ "$((j += 1))" -le "${slice_width}" ]; do
+			if eval "[ \"\$${j}\" = N/A ]"; then
+				break
+			else
+				code="${code} \"\$${j}\""
+			fi
+		done
 		eval "${code}"
 		if [ "$?" -eq "$1" ]; then
 			passed=$((passed + 1))
 		else
 			printf 'not '
 		fi
-		printf 'ok %d - %s\n' "${i}" "${description} (expecting $1)"
-		i=$((i + 1))
+		printf 'ok %d - %s (expecting %d)\n' "${i}" "${test_description}" "$1"
 		shift "${slice_width}"
 	done
 	return "$(( passed < total ))"
 }
 
+print_args() {
+	i=0
+	for arg; do
+		if [ "$((i += 1))" -eq 1 ]; then
+			set --
+		fi
+		if [ -n "${arg}" ]; then
+			set -- "$@" "${arg}"
+		else
+			set -- "$@" "''"
+		fi
+	done
+	printf '%s\n' "$*"
+}
+
 printf 'TAP version 14\n'
 
 unset -v dir
@@ -172,5 +217,6 @@ export TZ=UTC
 rc=0
 test_is_older_than || rc=1
 test_get_bootparam || rc=1
+test_esyslog || rc=1
 cleanup_tmpdir
 exit "${rc}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-09  3:54 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-09  3:54 UTC (permalink / raw
  To: gentoo-commits

commit:     1c1a37045e0e1b5719874a89520899f86f03dac0
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Feb  9 03:02:35 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Feb  9 03:14:24 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1c1a3704

Don't unconditionally shift 2 in esyslog()

Where esyslog() decides that it is appropriate to log a message, it
unconditionally tries to shift two of of the positional parameters,
regardless of how many were given. As has been seen before, this will
cause a non-interactive instance of sh(1) to immediately exit.

The other functions that call into it are not able to trigger this bug.
Still, it's possible for esyslog() to be directly invoked with too few
arguments. Fix it by testing whether a minimum of two arguments were
given. Should the test fail, print an error message and return 1.

Also, improve the method by which superfluous messages are ignored. The
prior strategy was to join the messages by the first character of IFS,
then check that the length of the resulting string is greater than 0.
Instead, check that the resulting string contains at least one visible
character.

Finally, mention that the invocation of logger(1) is not portable.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/functions.sh b/functions.sh
index 5b1b9bf..f756a9f 100644
--- a/functions.sh
+++ b/functions.sh
@@ -68,20 +68,23 @@ yesno()
 #
 esyslog()
 {
-	local pri=
-	local tag=
-
-	if [ -n "${EINFO_LOG}" ] && hash logger 2>/dev/null; then
-		pri="$1"
-		tag="$2"
+	local pri tag msg
 
+	if [ "$#" -lt 2 ]; then
+		printf 'Too few arguments for esyslog (got %d, expected at least 2)\n' "$#" >&2
+		return 1
+	elif [ -n "${EINFO_LOG}" ] && hash logger 2>/dev/null; then
+		pri=$1
+		tag=$2
 		shift 2
-		[ -z "$*" ] && return 0
-
-		logger -p "${pri}" -t "${tag}" -- "$*"
+		msg=$*
+		case ${msg} in
+			*[[:graph:]]*)
+				# This is not strictly portable because POSIX
+				# defines no options whatsoever for logger(1).
+				logger -p "${pri}" -t "${tag}" -- "${msg}"
+		esac
 	fi
-
-	return 0
 }
 
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-08  3:37 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-08  3:37 UTC (permalink / raw
  To: gentoo-commits

commit:     53862bd97274363393c35f192763eddc0f2b351d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Feb  8 02:01:48 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb  8 03:37:34 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=53862bd9

test-functions: Reduce the boilerplate required for new tests

Test functions may now define a callback() function before calling
iterate_tests() to iterate over the tests defined by the positional
parameters. The callback() function is responsible for performing a
single given test, and for setting the description variable.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 57 +++++++++++++++++++++++++++++++--------------------------
 1 file changed, 31 insertions(+), 26 deletions(-)

diff --git a/test-functions b/test-functions
index f6985ef..d6471ed 100755
--- a/test-functions
+++ b/test-functions
@@ -87,28 +87,17 @@ test_is_older_than() {
 		tstamp=197001010100 # add an hour
 	done
 
-	passed=0
-	total=$(( $# / 3 ))
-	i=1
-	printf '%d..%d\n' "${i}" "${total}"
-	while [ "${i}" -le "${total}" ]; do
+	callback() {
 		if [ "$2" != "N/A" ] && [ "$3" != "N/A" ]; then
-			desc="is_older_than $2 $3 (expecting $1)"
+			description="is_older_than $2 $3"
 			is_older_than "$2" "$3"
 		else
-			desc="is_older_than (expecting $1)"
+			description="is_older_than"
 			is_older_than
 		fi
-		if [ "$?" -eq "$1" ]; then
-			passed=$((passed + 1))
-		else
-			printf 'not '
-		fi
-		printf 'ok %d - %s\n' "${i}" "${desc}"
-		i=$((i + 1))
-		shift 3
-	done
-	return "$(( passed < total ))"
+	}
+
+	iterate_tests 3 "$@"
 }
 
 test_get_bootparam() {
@@ -127,26 +116,42 @@ test_get_bootparam() {
 		0  gentoo=1  "foo gentoo=gentoo=1,bar baz" \
 		1  quux      "${cmdline}"
 
-	passed=0
-	total=$(( $# / 3 ))
-	i=1
-	printf '%d..%d\n' "${i}" "${total}"
-	while [ "${i}" -le "${total}" ]; do
+	callback() {
 		if [ "$2" = "N/A" ]; then
-			desc="get_bootparam (expecting $1)"
+			description="get_bootparam"
 			printf '%s\n' "$3" | get_bootparam
 		else
-			desc="get_bootparam \"$2\" (expecting $1)"
+			description="get_bootparam \"$2\""
 			printf '%s\n' "$3" | get_bootparam "$2"
 		fi
+	}
+
+	iterate_tests 3 "$@"
+}
+
+iterate_tests() {
+	slice_width=$1
+	shift
+
+	total=$(( $# / slice_width ))
+	printf '1..%d\n' "${total}"
+	code="callback"
+	i=0
+	while [ "$((i += 1))" -le "${slice_width}" ]; do
+		code="${code} \"\$${i}\""
+	done
+	passed=0
+	i=1
+	while [ "${i}" -le "${total}" ]; do
+		eval "${code}"
 		if [ "$?" -eq "$1" ]; then
 			passed=$((passed + 1))
 		else
 			printf 'not '
 		fi
-		printf 'ok %d - %s\n' "${i}" "${desc}"
+		printf 'ok %d - %s\n' "${i}" "${description} (expecting $1)"
 		i=$((i + 1))
-		shift 3
+		shift "${slice_width}"
 	done
 	return "$(( passed < total ))"
 }


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-08  1:06 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-08  1:06 UTC (permalink / raw
  To: gentoo-commits

commit:     53a85d71a7f1a6f5a251b9622d7a1defe6ed54e6
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb  7 05:48:55 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb  8 01:06:28 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=53a85d71

Mention that the busybox builtins work with the test script

Busybox provides builtins for mktemp(1) and touch(1), both of which are
now known to be compatible with the test suite. Mention so in a comment.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/test-functions b/test-functions
index 8602a05..f6985ef 100755
--- a/test-functions
+++ b/test-functions
@@ -1,6 +1,7 @@
 #!/bin/sh
 # shellcheck disable=2015
-# Requires mktemp(1) and touch(1) from GNU coreutils.
+# Requires mktemp(1) and touch(1). The implementations provided by GNU
+# coreutils are compatible, as are the builtins provided by busybox.
 
 bailout() {
 	printf 'Bail out! %s.\n' "$1"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-08  0:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-08  0:03 UTC (permalink / raw
  To: gentoo-commits

commit:     833c5600ba5fd3570c8b53470f317151be85d2f4
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb  7 23:53:13 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb  8 00:02:20 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=833c5600

test-functions: unset -v dir a little earlier

That way, it's guaranteed that it's unset at the point that the cleanup
function is called on account of not sourcing the functions.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test-functions b/test-functions
index 3f34d59..d3cd154 100755
--- a/test-functions
+++ b/test-functions
@@ -151,14 +151,14 @@ test_get_bootparam() {
 	return "$(( passed < total ))"
 }
 
-
 printf 'TAP version 14\n'
 
+unset -v dir
+
 if ! . ./functions.sh; then
 	bailout "Couldn't source ./functions.sh"
 fi
 
-unset -v dir
 assign_tmpdir
 
 export TEST_GENFUNCS=1


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-08  0:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-08  0:03 UTC (permalink / raw
  To: gentoo-commits

commit:     e888b6390ceebeab87dd047e7633af581fa9c860
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb  7 23:56:29 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb  8 00:02:37 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=e888b639

test-functions: Don't imply that coreutils is required

The runtime requirements are made clear by the opening comment, but there was
still a reference to coreutils made in another comment. Remove the latter.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/test-functions b/test-functions
index d3cd154..8602a05 100755
--- a/test-functions
+++ b/test-functions
@@ -74,10 +74,9 @@ test_is_older_than() {
 		1  older/file    older-empty \
 		1  older/file    older/file
 
-	# The mtimes need to be explicitly assigned. Empirical evidence has shown
-	# that executing mkdir(1) sequentially, with a single operand each time,
-	# does not guarantee the order of the resulting mtimes. As such, the
-	# implementation of touch(1) from coreutils is required.
+	# The mtimes need to be explicitly assigned. Empirical evidence has
+	# shown that executing mkdir(1) sequentially, with a single operand
+	# each time, does not guarantee the order of the resulting mtimes.
 	tstamp=197001010000
 	for age in older newer; do
 		mkdir "${age}" "${age}-empty" \


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-07 23:47 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-07 23:47 UTC (permalink / raw
  To: gentoo-commits

commit:     eba1e10cf534577d62e6c007708ab1b517108911
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Tue Feb  7 23:47:28 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb  7 23:47:28 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=eba1e10c

Makefile: crank version to 0.19

Signed-off-by: Sam James <sam <AT> gentoo.org>

 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 30e0ac5..739bfcb 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 # Copyright 2014-2023 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
-VERSION = 0.18
+VERSION = 0.19
 GITREF ?= $(VERSION)
 PKG ?= gentoo-functions-$(VERSION)
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-07 23:42 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-07 23:42 UTC (permalink / raw
  To: gentoo-commits

commit:     ac7ba4b2801edebb6588dbee7728ab7ae2e7e03d
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb  7 06:10:36 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb  7 23:39:51 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=ac7ba4b2

Add some more tests for the get_bootparam() function

These additional tests include some that would have easily foiled the
old parser, so it seems sensible to have them be included.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/test-functions b/test-functions
index d5816f1..3f34d59 100755
--- a/test-functions
+++ b/test-functions
@@ -112,14 +112,20 @@ test_is_older_than() {
 }
 
 test_get_bootparam() {
+	cmdline="foo gentoo=bar,baz quux"
 	set -- \
-		1  N/A      "${cmdline:=foo gentoo=bar,baz quux}" \
-		1  ''       "${cmdline}" \
-		1  ''       "gentoo=" \
-		1  foo      "${cmdline}" \
-		0  bar      "${cmdline}" \
-		0  baz      "${cmdline}" \
-		1  bar,baz  "${cmdline}"
+		1  N/A       "${cmdline}" \
+		1  ''        "${cmdline}" \
+		1  ''        "gentoo=" \
+		1  foo       "${cmdline}" \
+		0  bar       "${cmdline}" \
+		0  bar       "foo gentoo=gentoo=1,bar baz" \
+		0  bar       "foo gentoo=bar,gentoo=1 baz" \
+		0  baz       "${cmdline}" \
+		1  bar,baz   "${cmdline}" \
+		0  gentoo=1  "foo gentoo=bar,gentoo=1 baz" \
+		0  gentoo=1  "foo gentoo=gentoo=1,bar baz" \
+		1  quux      "${cmdline}"
 
 	passed=0
 	total=$(( $# / 3 ))


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-07 23:42 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-07 23:42 UTC (permalink / raw
  To: gentoo-commits

commit:     b90fdda915a32d501df61aa92710e32ca0bd79ed
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb  7 05:06:51 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb  7 23:39:33 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b90fdda9

Don't shift in is_older_than() unless at least one parameter was given

Now that the test suite runs under sh(1), it has revealed a bug of my
own design. While bash will tolerate the invocation of shift in the
case that the positional parameter list is empty, sh(1) will not. Fix
it by checking whether there is anything to be shifted.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Fixes: b6c180b9851ba94f68016836cbce2dde46e07165
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index ca43e06..3f2dbcd 100644
--- a/functions.sh
+++ b/functions.sh
@@ -377,7 +377,7 @@ is_older_than()
 	else
 		ref=
 	fi
-	shift
+	[ "$#" -gt 0 ] && shift
 
 	# Consult the hash table in the present shell, prior to forking.
 	hash gfind 2>/dev/null; has_gfind=$(( $? == 0 ))


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-07 23:42 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-07 23:42 UTC (permalink / raw
  To: gentoo-commits

commit:     cdfb0ef04feb09260ee2631c6900044fdbfe476f
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb  7 05:06:14 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb  7 23:39:33 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=cdfb0ef0

Convert the test suite to sh, eliminating the bash dependency

This renders the test suite much more useful than it was because the
tests will now be performed using the system's sh(1) implementation,
whatever it may be.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 189 ++++++++++++++++++++++++++++++---------------------------
 1 file changed, 100 insertions(+), 89 deletions(-)

diff --git a/test-functions b/test-functions
index 39216b2..d5816f1 100755
--- a/test-functions
+++ b/test-functions
@@ -1,154 +1,165 @@
-#!/bin/bash
-
+#!/bin/sh
+# shellcheck disable=2015
 # Requires mktemp(1) and touch(1) from GNU coreutils.
 
 bailout() {
 	printf 'Bail out! %s.\n' "$1"
+	cleanup_tmpdir
 	exit 1
 }
 
 assign_tmpdir() {
+	# shellcheck disable=1007
 	dir=$(mktemp -d) \
 	&& CDPATH= cd -- "${dir}" \
 	|| bailout "Couldn't create or change to the temp dir"
 }
 
+cleanup_tmpdir() {
+	if [ -n "${dir}" ]; then
+		rm -rf -- "${dir}"
+	fi
+}
+
 test_is_older_than() {
-	local age desc i passed total tstamp
-	local -a tests=(
-		1  N/A           N/A
-		0  newer         newer
-		1  newer         newer-empty
-		0  newer         newer/file
-		1  newer         non-existent
-		1  newer         older
-		1  newer         older-empty
-		1  newer         older/file
-		0  newer-empty   newer
-		1  newer-empty   newer-empty
-		0  newer-empty   newer/file
-		1  newer-empty   non-existent
-		1  newer-empty   older
-		1  newer-empty   older-empty
-		1  newer-empty   older/file
-		1  newer/file    newer
-		1  newer/file    newer-empty
-		1  newer/file    newer/file
-		1  newer/file    non-existent
-		1  newer/file    older
-		1  newer/file    older-empty
-		1  newer/file    older/file
-		0  non-existent  newer
-		0  non-existent  newer-empty
-		0  non-existent  newer/file
-		1  non-existent  non-existent
-		0  non-existent  older
-		0  non-existent  older-empty
-		0  non-existent  older/file
-		0  older         newer
-		0  older         newer-empty
-		0  older         newer/file
-		1  older         non-existent
-		0  older         older
-		1  older         older-empty
-		0  older         older/file
-		0  older-empty   newer
-		0  older-empty   newer-empty
-		0  older-empty   newer/file
-		1  older-empty   non-existent
-		0  older-empty   older
-		1  older-empty   older-empty
-		0  older-empty   older/file
-		0  older/file    newer
-		0  older/file    newer-empty
-		0  older/file    newer/file
-		1  older/file    non-existent
-		1  older/file    older
-		1  older/file    older-empty
+	set -- \
+		1  N/A           N/A \
+		0  newer         newer \
+		1  newer         newer-empty \
+		0  newer         newer/file \
+		1  newer         non-existent \
+		1  newer         older \
+		1  newer         older-empty \
+		1  newer         older/file \
+		0  newer-empty   newer \
+		1  newer-empty   newer-empty \
+		0  newer-empty   newer/file \
+		1  newer-empty   non-existent \
+		1  newer-empty   older \
+		1  newer-empty   older-empty \
+		1  newer-empty   older/file \
+		1  newer/file    newer \
+		1  newer/file    newer-empty \
+		1  newer/file    newer/file \
+		1  newer/file    non-existent \
+		1  newer/file    older \
+		1  newer/file    older-empty \
+		1  newer/file    older/file \
+		0  non-existent  newer \
+		0  non-existent  newer-empty \
+		0  non-existent  newer/file \
+		1  non-existent  non-existent \
+		0  non-existent  older \
+		0  non-existent  older-empty \
+		0  non-existent  older/file \
+		0  older         newer \
+		0  older         newer-empty \
+		0  older         newer/file \
+		1  older         non-existent \
+		0  older         older \
+		1  older         older-empty \
+		0  older         older/file \
+		0  older-empty   newer \
+		0  older-empty   newer-empty \
+		0  older-empty   newer/file \
+		1  older-empty   non-existent \
+		0  older-empty   older \
+		1  older-empty   older-empty \
+		0  older-empty   older/file \
+		0  older/file    newer \
+		0  older/file    newer-empty \
+		0  older/file    newer/file \
+		1  older/file    non-existent \
+		1  older/file    older \
+		1  older/file    older-empty \
 		1  older/file    older/file
-	)
 
 	# The mtimes need to be explicitly assigned. Empirical evidence has shown
 	# that executing mkdir(1) sequentially, with a single operand each time,
 	# does not guarantee the order of the resulting mtimes. As such, the
 	# implementation of touch(1) from coreutils is required.
-	local -x TZ=UTC
 	tstamp=197001010000
 	for age in older newer; do
-		mkdir "${age}"{,-empty} \
+		mkdir "${age}" "${age}-empty" \
 		&& touch -m -t "${tstamp%0}1" "${age}"/file \
-		&& touch -m -t "${tstamp}" "${age}"{,-empty} \
+		&& touch -m -t "${tstamp}" "${age}" "${age}-empty" \
 		|| bailout "Couldn't create or adjust the mtimes of the sample files"
 		tstamp=197001010100 # add an hour
 	done
 
-	total=$(( ${#tests[@]} / 3 ))
 	passed=0
-	printf '1..%d\n' "${total}"
-	for ((i = 0; i < total; i++)); do
-		set -- "${tests[@]:i*3:3}"
-		if [[ $2 != N/A && $3 != N/A ]]; then
+	total=$(( $# / 3 ))
+	i=1
+	printf '%d..%d\n' "${i}" "${total}"
+	while [ "${i}" -le "${total}" ]; do
+		if [ "$2" != "N/A" ] && [ "$3" != "N/A" ]; then
 			desc="is_older_than $2 $3 (expecting $1)"
 			is_older_than "$2" "$3"
 		else
 			desc="is_older_than (expecting $1)"
 			is_older_than
 		fi
-		if (( $? == $1 )); then
-			(( ++passed ))
+		if [ "$?" -eq "$1" ]; then
+			passed=$((passed + 1))
 		else
 			printf 'not '
 		fi
-		printf 'ok %d - %s\n' "$((i + 1))" "${desc}"
+		printf 'ok %d - %s\n' "${i}" "${desc}"
+		i=$((i + 1))
+		shift 3
 	done
 	return "$(( passed < total ))"
 }
 
 test_get_bootparam() {
-	local desc i input passed total
-	local -a tests=(
-		1  N/A      "${input:=foo gentoo=bar,baz quux}"
-		1  ''       "${input}"
-		1  ''       "gentoo="
-		1  foo      "${input}"
-		0  bar      "${input}"
-		0  baz      "${input}"
-		1  bar,baz  "${input}"
-	)
+	set -- \
+		1  N/A      "${cmdline:=foo gentoo=bar,baz quux}" \
+		1  ''       "${cmdline}" \
+		1  ''       "gentoo=" \
+		1  foo      "${cmdline}" \
+		0  bar      "${cmdline}" \
+		0  baz      "${cmdline}" \
+		1  bar,baz  "${cmdline}"
 
-	total=$(( ${#tests[@]} / 3 ))
-	printf '1..%d\n' "${total}"
-	for ((i = 0; i < total; i++)); do
-		set -- "${tests[@]:i*3:3}"
-		if [[ $2 == N/A ]]; then
+	passed=0
+	total=$(( $# / 3 ))
+	i=1
+	printf '%d..%d\n' "${i}" "${total}"
+	while [ "${i}" -le "${total}" ]; do
+		if [ "$2" = "N/A" ]; then
 			desc="get_bootparam (expecting $1)"
-			get_bootparam
+			printf '%s\n' "$3" | get_bootparam
 		else
 			desc="get_bootparam \"$2\" (expecting $1)"
-			get_bootparam "$2"
-		fi <<<"$3"
-		if (( $? == $1 )); then
-			(( ++passed ))
+			printf '%s\n' "$3" | get_bootparam "$2"
+		fi
+		if [ "$?" -eq "$1" ]; then
+			passed=$((passed + 1))
 		else
 			printf 'not '
 		fi
-		printf 'ok %d - %s\n' "$((i + 1))" "${desc}"
+		printf 'ok %d - %s\n' "${i}" "${desc}"
+		i=$((i + 1))
+		shift 3
 	done
 	return "$(( passed < total ))"
 }
 
+
 printf 'TAP version 14\n'
 
-if ! source ./functions.sh; then
+if ! . ./functions.sh; then
 	bailout "Couldn't source ./functions.sh"
 fi
 
 unset -v dir
-trap '[[ ${dir} ]] && rm -rf -- "${dir}"' EXIT
 assign_tmpdir
 
-TEST_GENFUNCS=1
+export TEST_GENFUNCS=1
+export TZ=UTC
+
 rc=0
 test_is_older_than || rc=1
 test_get_bootparam || rc=1
+cleanup_tmpdir
 exit "${rc}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-07 23:42 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-07 23:42 UTC (permalink / raw
  To: gentoo-commits

commit:     e715750304e4b77afa65cc65927a58b75f4eb7eb
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Tue Feb  7 23:41:20 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb  7 23:41:20 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=e7157503

Fix copyright header in functions.sh

Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/functions.sh b/functions.sh
index 3f2dbcd..5b1b9bf 100644
--- a/functions.sh
+++ b/functions.sh
@@ -1,4 +1,4 @@
-# Copyright 1999-2014 Gentoo Foundation
+# Copyright 1999-2023 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-07  1:08 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-07  1:08 UTC (permalink / raw
  To: gentoo-commits

commit:     2a7399e84b2fcb37e9f2e9ec9f7ecd9c60111f3b
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb  7 00:39:59 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb  7 01:02:31 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2a7399e8

Re-implement get_bootparam as pure sh, eliminating the gawk dependency

The current implementation of get_bootparam() specifically invokes gawk
and has some deficiencies, such as failing to inhibit pathname
expansion and not breaking the loop once a match has been made.

In fact, the problem can be solved using sh(1) alone, and the revised
function does precisely that. Note that the definition of the function
is now the kind of compound command that incurs a subshell. Hence, one
subshell is incurred for the entire routine and there is no compelling
reason to use the (non-standard) local keyword, nor be concerned with
the consequences of disabling pathname expansion.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Bug: https://bugs.gentoo.org/886017
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 45 ++++++++++++++++++++-------------------------
 1 file changed, 20 insertions(+), 25 deletions(-)

diff --git a/functions.sh b/functions.sh
index 0a5d38e..08950b8 100644
--- a/functions.sh
+++ b/functions.sh
@@ -336,33 +336,28 @@ veoutdent()
 #   EXAMPLE:  if get_bootparam "nodevfs" ; then ....
 #
 get_bootparam()
-{
-	local x copt params retval=1
-
-	[ ! -r /proc/cmdline ] && return 1
-
-	read copts < /proc/cmdline
-	for copt in $copts ; do
-		if [ "${copt%=*}" = "gentoo" ] ; then
-			params=$(gawk -v PARAMS="${copt##*=}" '
-				BEGIN {
-					split(PARAMS, nodes, ",")
-					for (x in nodes)
-						print nodes[x]
-				}')
-
-			# Parse gentoo option
-			for x in ${params} ; do
-				if [ "${x}" = "$1" ] ; then
-#					echo "YES"
-					retval=0
-				fi
-			done
+(
+	# Gentoo cmdline parameters are comma-delimited, so a search
+	# string containing a comma must not be allowed to match.
+	# Similarly, the empty string must not be allowed to match.
+	case $1 in ''|*,*) return 1 ;; esac
+
+	read -r cmdline < /proc/cmdline || return
+
+	# Disable pathname expansion. The definition of this function
+	# is a compound command that incurs a subshell. Therefore, the
+	# prior state of the option does not need to be recalled.
+	set -f
+	for opt in ${cmdline}; do
+		gentoo_opt=${opt#gentoo=}
+		if [ "${opt}" != "${gentoo_opt}" ]; then
+			case ,${gentoo_opt}, in
+				*,"$1",*) return 0
+			esac
 		fi
 	done
-
-	return ${retval}
-}
+	return 1
+)
 
 #
 #   return 0 if any of the files/dirs are newer than


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-07  1:08 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-07  1:08 UTC (permalink / raw
  To: gentoo-commits

commit:     91ceadf4b0e1b2d1e5c8a45ee7abc38005ec0f2a
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Feb  7 00:41:16 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb  7 01:02:44 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=91ceadf4

Add a test for the get_bootparam() function

The changes are not as drastic as they appear. It's mostly on account
of having moved the individual tests into functions.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh   |   6 +-
 test-functions | 233 +++++++++++++++++++++++++++++++++------------------------
 2 files changed, 141 insertions(+), 98 deletions(-)

diff --git a/functions.sh b/functions.sh
index 08950b8..ca43e06 100644
--- a/functions.sh
+++ b/functions.sh
@@ -342,7 +342,11 @@ get_bootparam()
 	# Similarly, the empty string must not be allowed to match.
 	case $1 in ''|*,*) return 1 ;; esac
 
-	read -r cmdline < /proc/cmdline || return
+	if [ "${TEST_GENFUNCS}" = 1 ]; then
+		read -r cmdline
+	else
+		read -r cmdline < /proc/cmdline
+	fi || return
 
 	# Disable pathname expansion. The definition of this function
 	# is a compound command that incurs a subshell. Therefore, the

diff --git a/test-functions b/test-functions
index 699cc23..39216b2 100755
--- a/test-functions
+++ b/test-functions
@@ -1,6 +1,5 @@
 #!/bin/bash
 
-# Presently, only the is_older_than() function is tested.
 # Requires mktemp(1) and touch(1) from GNU coreutils.
 
 bailout() {
@@ -8,108 +7,148 @@ bailout() {
 	exit 1
 }
 
-printf 'TAP version 14\n'
-
-if ! source ./functions.sh; then
-	bailout "Couldn't source ./functions.sh"
-fi
+assign_tmpdir() {
+	dir=$(mktemp -d) \
+	&& CDPATH= cd -- "${dir}" \
+	|| bailout "Couldn't create or change to the temp dir"
+}
 
-unset -v dir
-trap '[[ ${dir} ]] && rm -rf -- "${dir}"' EXIT
+test_is_older_than() {
+	local age desc i passed total tstamp
+	local -a tests=(
+		1  N/A           N/A
+		0  newer         newer
+		1  newer         newer-empty
+		0  newer         newer/file
+		1  newer         non-existent
+		1  newer         older
+		1  newer         older-empty
+		1  newer         older/file
+		0  newer-empty   newer
+		1  newer-empty   newer-empty
+		0  newer-empty   newer/file
+		1  newer-empty   non-existent
+		1  newer-empty   older
+		1  newer-empty   older-empty
+		1  newer-empty   older/file
+		1  newer/file    newer
+		1  newer/file    newer-empty
+		1  newer/file    newer/file
+		1  newer/file    non-existent
+		1  newer/file    older
+		1  newer/file    older-empty
+		1  newer/file    older/file
+		0  non-existent  newer
+		0  non-existent  newer-empty
+		0  non-existent  newer/file
+		1  non-existent  non-existent
+		0  non-existent  older
+		0  non-existent  older-empty
+		0  non-existent  older/file
+		0  older         newer
+		0  older         newer-empty
+		0  older         newer/file
+		1  older         non-existent
+		0  older         older
+		1  older         older-empty
+		0  older         older/file
+		0  older-empty   newer
+		0  older-empty   newer-empty
+		0  older-empty   newer/file
+		1  older-empty   non-existent
+		0  older-empty   older
+		1  older-empty   older-empty
+		0  older-empty   older/file
+		0  older/file    newer
+		0  older/file    newer-empty
+		0  older/file    newer/file
+		1  older/file    non-existent
+		1  older/file    older
+		1  older/file    older-empty
+		1  older/file    older/file
+	)
 
-dir=$(mktemp -d) \
-&& CDPATH= cd -- "${dir}" \
-|| bailout "Couldn't create or change to the temp dir"
+	# The mtimes need to be explicitly assigned. Empirical evidence has shown
+	# that executing mkdir(1) sequentially, with a single operand each time,
+	# does not guarantee the order of the resulting mtimes. As such, the
+	# implementation of touch(1) from coreutils is required.
+	local -x TZ=UTC
+	tstamp=197001010000
+	for age in older newer; do
+		mkdir "${age}"{,-empty} \
+		&& touch -m -t "${tstamp%0}1" "${age}"/file \
+		&& touch -m -t "${tstamp}" "${age}"{,-empty} \
+		|| bailout "Couldn't create or adjust the mtimes of the sample files"
+		tstamp=197001010100 # add an hour
+	done
 
-# The mtimes need to be explicitly assigned. Empirical evidence has shown
-# that executing mkdir(1) sequentially, with a single operand each time,
-# does not guarantee the order of the resulting mtimes. As such, the
-# implementation of touch(1) from coreutils is required.
-export TZ=UTC
-tstamp=197001010000
-for age in older newer; do
-	mkdir "${age}"{,-empty} \
-	&& touch -m -t "${tstamp%0}1" "${age}"/file \
-	&& touch -m -t "${tstamp}" "${age}"{,-empty} \
-	|| bailout "Couldn't create or adjust the mtimes of the sample files"
-	tstamp=197001010100 # add an hour
-done
+	total=$(( ${#tests[@]} / 3 ))
+	passed=0
+	printf '1..%d\n' "${total}"
+	for ((i = 0; i < total; i++)); do
+		set -- "${tests[@]:i*3:3}"
+		if [[ $2 != N/A && $3 != N/A ]]; then
+			desc="is_older_than $2 $3 (expecting $1)"
+			is_older_than "$2" "$3"
+		else
+			desc="is_older_than (expecting $1)"
+			is_older_than
+		fi
+		if (( $? == $1 )); then
+			(( ++passed ))
+		else
+			printf 'not '
+		fi
+		printf 'ok %d - %s\n' "$((i + 1))" "${desc}"
+	done
+	return "$(( passed < total ))"
+}
 
-tests=(
-	1  ''            ''
-	0  newer         newer
-	1  newer         newer-empty
-	0  newer         newer/file
-	1  newer         non-existent
-	1  newer         older
-	1  newer         older-empty
-	1  newer         older/file
-	0  newer-empty   newer
-	1  newer-empty   newer-empty
-	0  newer-empty   newer/file
-	1  newer-empty   non-existent
-	1  newer-empty   older
-	1  newer-empty   older-empty
-	1  newer-empty   older/file
-	1  newer/file    newer
-	1  newer/file    newer-empty
-	1  newer/file    newer/file
-	1  newer/file    non-existent
-	1  newer/file    older
-	1  newer/file    older-empty
-	1  newer/file    older/file
-	0  non-existent  newer
-	0  non-existent  newer-empty
-	0  non-existent  newer/file
-	1  non-existent  non-existent
-	0  non-existent  older
-	0  non-existent  older-empty
-	0  non-existent  older/file
-	0  older         newer
-	0  older         newer-empty
-	0  older         newer/file
-	1  older         non-existent
-	0  older         older
-	1  older         older-empty
-	0  older         older/file
-	0  older-empty   newer
-	0  older-empty   newer-empty
-	0  older-empty   newer/file
-	1  older-empty   non-existent
-	0  older-empty   older
-	1  older-empty   older-empty
-	0  older-empty   older/file
-	0  older/file    newer
-	0  older/file    newer-empty
-	0  older/file    newer/file
-	1  older/file    non-existent
-	1  older/file    older
-	1  older/file    older-empty
-	1  older/file    older/file
-)
+test_get_bootparam() {
+	local desc i input passed total
+	local -a tests=(
+		1  N/A      "${input:=foo gentoo=bar,baz quux}"
+		1  ''       "${input}"
+		1  ''       "gentoo="
+		1  foo      "${input}"
+		0  bar      "${input}"
+		0  baz      "${input}"
+		1  bar,baz  "${input}"
+	)
 
-total=$(( ${#tests[@]} / 3 ))
-passed=0
+	total=$(( ${#tests[@]} / 3 ))
+	printf '1..%d\n' "${total}"
+	for ((i = 0; i < total; i++)); do
+		set -- "${tests[@]:i*3:3}"
+		if [[ $2 == N/A ]]; then
+			desc="get_bootparam (expecting $1)"
+			get_bootparam
+		else
+			desc="get_bootparam \"$2\" (expecting $1)"
+			get_bootparam "$2"
+		fi <<<"$3"
+		if (( $? == $1 )); then
+			(( ++passed ))
+		else
+			printf 'not '
+		fi
+		printf 'ok %d - %s\n' "$((i + 1))" "${desc}"
+	done
+	return "$(( passed < total ))"
+}
 
-printf '1..%d\n' "${total}"
+printf 'TAP version 14\n'
 
-for ((i = 0; i < total; i++)); do
-	set -- "${tests[@]:i*3:3}"
-	if [[ $2 && $3 ]]; then
-		desc="is_older_than $2 $3 (expecting $1)"
-		is_older_than "$2" "$3"
-	else
-		desc="is_older_than (expecting $1)"
-		is_older_than
-	fi
-	if (( $? == $1 )); then
-		(( ++passed ))
-	else
-		printf 'not '
-	fi
-	printf 'ok %d - %s\n' "$((i + 1))" "${desc}"
-done
+if ! source ./functions.sh; then
+	bailout "Couldn't source ./functions.sh"
+fi
 
-printf >&2 '%d/%d tests passed.\n' "${passed}" "${total}"
+unset -v dir
+trap '[[ ${dir} ]] && rm -rf -- "${dir}"' EXIT
+assign_tmpdir
 
-exit "$(( passed < total ))"
+TEST_GENFUNCS=1
+rc=0
+test_is_older_than || rc=1
+test_get_bootparam || rc=1
+exit "${rc}"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-06 13:47 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-06 13:47 UTC (permalink / raw
  To: gentoo-commits

commit:     f0a6155b2ec6f737d7258cf9baa75a9aeca8f1de
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb  6 06:27:47 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb  6 13:46:56 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f0a6155b

Don't unsuccessfully attempt to background the defunct rc_splash utility

The media-gfx/splashutils package was dropped in November 2018, and was
probably not even usable for some time before that. Currently, every
time the _eend() function handles an exit status code other than 0, it
tries to run rc_splash in the background with no possible chance of
success. It also incurs an utterly useless syscall, in order to
determine whether /dev/null is a character device. Cease and desist.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index ae7d151..0a5d38e 100644
--- a/functions.sh
+++ b/functions.sh
@@ -235,11 +235,6 @@ _eend()
 		yesno "${EINFO_QUIET}" && return 0
 		msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
 	else
-		if [ -c /dev/null ] ; then
-			rc_splash "stop" >/dev/null 2>&1 &
-		else
-			rc_splash "stop" &
-		fi
 		if [ -n "$*" ] ; then
 			${efunc} "$*"
 		fi


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-06  4:32 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-06  4:32 UTC (permalink / raw
  To: gentoo-commits

commit:     f3c0e42c0f8e6dbdb59a4be588756566abddd7e6
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb  6 04:24:28 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb  6 04:32:06 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f3c0e42c

test-functions: Fix a comment typo

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test-functions b/test-functions
index 291d468..699cc23 100755
--- a/test-functions
+++ b/test-functions
@@ -22,7 +22,7 @@ dir=$(mktemp -d) \
 || bailout "Couldn't create or change to the temp dir"
 
 # The mtimes need to be explicitly assigned. Empirical evidence has shown
-# theat executing mkdir(1) sequentially, with a single operand each time,
+# that executing mkdir(1) sequentially, with a single operand each time,
 # does not guarantee the order of the resulting mtimes. As such, the
 # implementation of touch(1) from coreutils is required.
 export TZ=UTC


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-06  4:23 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-06  4:23 UTC (permalink / raw
  To: gentoo-commits

commit:     baa424d7342213004ca9585ca811eb76825bac94
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Mon Feb  6 04:22:59 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb  6 04:22:59 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=baa424d7

Makefile: bump to 0.18

Signed-off-by: Sam James <sam <AT> gentoo.org>

 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index ca64a3a..30e0ac5 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 # Copyright 2014-2023 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
-VERSION = 0.17
+VERSION = 0.18
 GITREF ?= $(VERSION)
 PKG ?= gentoo-functions-$(VERSION)
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-06  4:19 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-06  4:19 UTC (permalink / raw
  To: gentoo-commits

commit:     aed9189be415fdfdbc8666151747e9b4a23a2f1d
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Mon Feb  6 04:16:10 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb  6 04:16:19 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=aed9189b

Makefile: wire up check target

Followup to 1553c3bc0f0c18892aa03880183e95d0aa8089e9 which did the real
work.

Signed-off-by: Sam James <sam <AT> gentoo.org>

 Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Makefile b/Makefile
index 6014d03..ca64a3a 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,9 @@ PROGRAMS = consoletype
 
 all: $(PROGRAMS)
 
+check: all
+	./test-functions
+
 install: all
 	install -m 0755 -d $(DESTDIR)$(ROOTSBINDIR)
 	install -m 0755 consoletype $(DESTDIR)$(ROOTSBINDIR)


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-06  4:10 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-06  4:10 UTC (permalink / raw
  To: gentoo-commits

commit:     254e2ef21b36b5ae523f607e5d919d6f1489e697
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Mon Feb  6 04:09:29 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb  6 04:09:29 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=254e2ef2

Makefile: fix VERSION

Signed-off-by: Sam James <sam <AT> gentoo.org>

 Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 76c2e9a..10fc4fa 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 # gentoo-functions Makefile
-# Copyright 2014-2021 Gentoo Authors
+# Copyright 2014-2022 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
-VERSION = 0.15
+VERSION = 0.17
 GITREF ?= $(VERSION)
 PKG ?= gentoo-functions-$(VERSION)
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-06  4:10 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-06  4:10 UTC (permalink / raw
  To: gentoo-commits

commit:     2ade6e455e29e88b63436b646052bd3de19f3010
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Mon Feb  6 04:09:50 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb  6 04:10:06 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2ade6e45

Makefile: use xz for dist

Signed-off-by: Sam James <sam <AT> gentoo.org>

 Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 10fc4fa..6014d03 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 # gentoo-functions Makefile
-# Copyright 2014-2022 Gentoo Authors
+# Copyright 2014-2023 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 VERSION = 0.17
@@ -29,7 +29,7 @@ clean:
 	rm -rf $(PROGRAMS)
 
 dist:
-	git archive --prefix=$(PKG)/ $(GITREF) | bzip2 > $(PKG).tar.bz2
+	git archive --prefix=$(PKG)/ $(GITREF) | xz > $(PKG).tar.xz
 
 consoletype: consoletype.c
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-06  3:59 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-06  3:59 UTC (permalink / raw
  To: gentoo-commits

commit:     1553c3bc0f0c18892aa03880183e95d0aa8089e9
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb  6 01:02:57 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb  6 03:08:50 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1553c3bc

Add a gentoo-functions test suite

Presently, it tests only the is_older_than() function, and requires
bash, in addition to mktemp(1) and touch(1) from GNU coreutils. Note
that this commit does not touch the Makefile.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Bug: https://bugs.gentoo.org/579688
Signed-off-by: Sam James <sam <AT> gentoo.org>

 test-functions | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/test-functions b/test-functions
new file mode 100755
index 0000000..291d468
--- /dev/null
+++ b/test-functions
@@ -0,0 +1,115 @@
+#!/bin/bash
+
+# Presently, only the is_older_than() function is tested.
+# Requires mktemp(1) and touch(1) from GNU coreutils.
+
+bailout() {
+	printf 'Bail out! %s.\n' "$1"
+	exit 1
+}
+
+printf 'TAP version 14\n'
+
+if ! source ./functions.sh; then
+	bailout "Couldn't source ./functions.sh"
+fi
+
+unset -v dir
+trap '[[ ${dir} ]] && rm -rf -- "${dir}"' EXIT
+
+dir=$(mktemp -d) \
+&& CDPATH= cd -- "${dir}" \
+|| bailout "Couldn't create or change to the temp dir"
+
+# The mtimes need to be explicitly assigned. Empirical evidence has shown
+# theat executing mkdir(1) sequentially, with a single operand each time,
+# does not guarantee the order of the resulting mtimes. As such, the
+# implementation of touch(1) from coreutils is required.
+export TZ=UTC
+tstamp=197001010000
+for age in older newer; do
+	mkdir "${age}"{,-empty} \
+	&& touch -m -t "${tstamp%0}1" "${age}"/file \
+	&& touch -m -t "${tstamp}" "${age}"{,-empty} \
+	|| bailout "Couldn't create or adjust the mtimes of the sample files"
+	tstamp=197001010100 # add an hour
+done
+
+tests=(
+	1  ''            ''
+	0  newer         newer
+	1  newer         newer-empty
+	0  newer         newer/file
+	1  newer         non-existent
+	1  newer         older
+	1  newer         older-empty
+	1  newer         older/file
+	0  newer-empty   newer
+	1  newer-empty   newer-empty
+	0  newer-empty   newer/file
+	1  newer-empty   non-existent
+	1  newer-empty   older
+	1  newer-empty   older-empty
+	1  newer-empty   older/file
+	1  newer/file    newer
+	1  newer/file    newer-empty
+	1  newer/file    newer/file
+	1  newer/file    non-existent
+	1  newer/file    older
+	1  newer/file    older-empty
+	1  newer/file    older/file
+	0  non-existent  newer
+	0  non-existent  newer-empty
+	0  non-existent  newer/file
+	1  non-existent  non-existent
+	0  non-existent  older
+	0  non-existent  older-empty
+	0  non-existent  older/file
+	0  older         newer
+	0  older         newer-empty
+	0  older         newer/file
+	1  older         non-existent
+	0  older         older
+	1  older         older-empty
+	0  older         older/file
+	0  older-empty   newer
+	0  older-empty   newer-empty
+	0  older-empty   newer/file
+	1  older-empty   non-existent
+	0  older-empty   older
+	1  older-empty   older-empty
+	0  older-empty   older/file
+	0  older/file    newer
+	0  older/file    newer-empty
+	0  older/file    newer/file
+	1  older/file    non-existent
+	1  older/file    older
+	1  older/file    older-empty
+	1  older/file    older/file
+)
+
+total=$(( ${#tests[@]} / 3 ))
+passed=0
+
+printf '1..%d\n' "${total}"
+
+for ((i = 0; i < total; i++)); do
+	set -- "${tests[@]:i*3:3}"
+	if [[ $2 && $3 ]]; then
+		desc="is_older_than $2 $3 (expecting $1)"
+		is_older_than "$2" "$3"
+	else
+		desc="is_older_than (expecting $1)"
+		is_older_than
+	fi
+	if (( $? == $1 )); then
+		(( ++passed ))
+	else
+		printf 'not '
+	fi
+	printf 'ok %d - %s\n' "$((i + 1))" "${desc}"
+done
+
+printf >&2 '%d/%d tests passed.\n' "${passed}" "${total}"
+
+exit "$(( passed < total ))"


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-06  3:59 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-06  3:59 UTC (permalink / raw
  To: gentoo-commits

commit:     b6c180b9851ba94f68016836cbce2dde46e07165
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Mon Feb  6 00:59:11 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb  6 03:08:33 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b6c180b9

Eliminate the bashism that is the -nt test operator

Presently, the is_older_than() function uses the -nt operator as part
of a test command. As was reported by bug 579688, it is not supported by
POSIX. In fact, there is no way to perform this kind of check with sh(1)
and the standard utilities alone. After some deliberation, I concluded
that relying on GNU findutils would be the best course of action. Not
only does it provide the -newerXY predicate, but it is also required by
PMS to begin with.

The revised function works by using the -newermm predicate to compare
any of the pathnames that it encounters against the specified reference
path. In the event that it encounters any other path that is newer than
the reference path, it shall immediately quit, rendering it fairly
efficient. In fact, there is no circumstance under which more than one
line of output needs to be read from find(1).

The prior implementation would aggressively follow directories, even for
symlinks. This seems unwise to me. Nevertheless, find(1) is given the
-L option so as to preserve this behaviour.

Considerable care has been taken to ensure that the revised function
remains exit status compatible. I performed 50 individual tests to that
end. One obvious difference is that directories whose names begin with
a dot will now be recursed. I determined that there was no obviously
apparent reason that this should be an issue. Regardless, it would be
trivial to alter this behaviour in the future, if so neeed.

Please note that it requires findutils >=4.9 as a runtime dependency,
owing to its use of -files0-from, which is far too useful an option to
wish to forgo. It will prefer "gfind" over "find", if the former is
found to exist.

Incidentally, the revised function is resilient to the case in which
the sh(1) implementation does not support local. The anti-pattern of
using local (which is undefined behaviour) to define a variable, while
simultaneously assigning it, is becoming a most tiresome one.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Bug: https://bugs.gentoo.org/579688
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/functions.sh b/functions.sh
index acce989..0391c90 100644
--- a/functions.sh
+++ b/functions.sh
@@ -376,16 +376,32 @@ get_bootparam()
 #   EXAMPLE: if is_older_than a.out *.o ; then ...
 is_older_than()
 {
-	local x=
-	local ref="$1"
-	[ $# -eq 0 ] || shift
+	local ref has_gfind
 
-	for x in "$@" ; do
-		[ "${x}" -nt "${ref}" ] && return 0
-		[ -d "${x}" ] && is_older_than "${ref}" "${x}"/* && return 0
-	done
+	if [ -e "$1" ]; then
+		ref=$1
+	else
+		ref=
+	fi
+	shift
 
-	return 1
+	# Consult the hash table in the present shell, prior to forking.
+	hash gfind 2>/dev/null; has_gfind=$(( $? == 0 ))
+
+	for path; do
+		if [ -e "${path}" ]; then
+			printf '%s\0' "${path}"
+		fi
+	done |
+	{
+		set -- -L -files0-from - ${ref:+-newermm} ${ref:+"${ref}"} -printf '\n' -quit
+		if [ "${has_gfind}" -eq 1 ]; then
+			gfind "$@"
+		else
+			find "$@"
+		fi
+	} |
+	read -r line
 }
 
 # This is the main script, please add all functions above this point!


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2023-02-06  3:59 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2023-02-06  3:59 UTC (permalink / raw
  To: gentoo-commits

commit:     a1b7172e3c094c2a0db29e4e346bbe4a8c824200
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Sun Feb  5 23:40:41 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Feb  6 03:09:04 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=a1b7172e

Avoid unnecessary subshells and use hash to avoid repeated PATH lookups

Use hash to determine whether logger is available, preventing repeated
PATH searches in the case that esyslog() is called more than once.

Once RC_NOCOLOR is set to "yes", don't waste any further time iterating
over the remaining positional parameters.

Use hash to determine whether tput is available, preventing at least one
repeated PATH lookup.

Don't incur a pointless subshell in the course of checking whether tput
is available on the second occasion.

Don't repeatedly execute tput, incurring a subshell on each occasion, to
get the sequences for "bold" and "sgr0". Obtain both, once.

Use unset -v to indicate that variables, specifically, are to be unset.

Remove the true hack at the end of the script. It's no longer needed.

The overall reduction in the number of subshells amounts to 9 and it can
be trivially proven that the code is executed more quickly.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/functions.sh b/functions.sh
index 0391c90..ae7d151 100644
--- a/functions.sh
+++ b/functions.sh
@@ -71,7 +71,7 @@ esyslog()
 	local pri=
 	local tag=
 
-	if [ -n "${EINFO_LOG}" ] && command -v logger > /dev/null 2>&1; then
+	if [ -n "${EINFO_LOG}" ] && hash logger 2>/dev/null; then
 		pri="$1"
 		tag="$2"
 
@@ -434,6 +434,7 @@ for arg in "$@" ; do
 		# Lastly check if the user disabled it with --nocolor argument
 		--nocolor|--nocolour|-nc|-C)
 			RC_NOCOLOR="yes"
+			break
 			;;
 	esac
 done
@@ -447,7 +448,7 @@ COLS="${COLUMNS:-0}"            # bash's internal COLUMNS variable
 
 if ! yesno "${RC_ENDCOL}"; then
 	ENDCOL=''
-elif command -v tput >/dev/null 2>&1; then
+elif hash tput 2>/dev/null; then
 	ENDCOL="$(tput cuu1)$(tput cuf $(( COLS - 8 )) )"
 else
 	ENDCOL='\033[A\033['$(( COLS - 8 ))'C'
@@ -455,14 +456,16 @@ fi
 
 # Setup the colors so our messages all look pretty
 if yesno "${RC_NOCOLOR}"; then
-	unset BAD BRACKET GOOD HILITE NORMAL WARN
-elif (command -v tput && tput colors) >/dev/null 2>&1; then
-	BAD="$(tput sgr0)$(tput bold)$(tput setaf 1)"
-	BRACKET="$(tput sgr0)$(tput bold)$(tput setaf 4)"
-	GOOD="$(tput sgr0)$(tput bold)$(tput setaf 2)"
-	HILITE="$(tput sgr0)$(tput bold)$(tput setaf 6)"
-	NORMAL="$(tput sgr0)"
-	WARN="$(tput sgr0)$(tput bold)$(tput setaf 3)"
+	unset -v BAD BRACKET GOOD HILITE NORMAL WARN
+elif { hash tput && tput colors >/dev/null; } 2>/dev/null; then
+	genfuncs_bold=$(tput bold) genfuncs_norm=$(tput sgr0)
+	BAD="${genfuncs_norm}${genfuncs_bold}$(tput setaf 1)"
+	BRACKET="${genfuncs_norm}${genfuncs_bold}$(tput setaf 4)"
+	GOOD="${genfuncs_norm}${genfuncs_bold}$(tput setaf 2)"
+	HILITE="${genfuncs_norm}${genfuncs_bold}$(tput setaf 6)"
+	NORMAL="${genfuncs_norm}"
+	WARN="${genfuncs_norm}${genfuncs_bold}$(tput setaf 3)"
+	unset -v genfuncs_bold genfuncs_norm
 else
 	BAD=$(printf '\033[31;01m')
 	BRACKET=$(printf '\033[34;01m')
@@ -472,8 +475,4 @@ else
 	WARN=$(printf '\033[33;01m')
 fi
 
-# If we made it this far, the script succeeded, so don't let failures
-# from earlier commands (like `tput`) screw up the $? value.
-:
-
 # vim:ts=4


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2022-07-30  5:48 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2022-07-30  5:48 UTC (permalink / raw
  To: gentoo-commits

commit:     44c2ebb24e53bbf8c8848072cbe3b66471f883df
Author:     Ulrich Müller <ulm <AT> gentoo <DOT> org>
AuthorDate: Sat Sep 23 18:38:29 2017 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Jul 30 05:46:33 2022 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=44c2ebb2

functions.sh: Don't hardcode escape seqences for ENDCOL

Similar to handling of colors, this should make use of tput,
rather than sending unknown escape sequences to dumb terminals.

Bug: https://bugs.gentoo.org/631870
Signed-off-by: Ulrich Müller <ulm <AT> gentoo.org>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/functions.sh b/functions.sh
index a5f3bfd..acce989 100644
--- a/functions.sh
+++ b/functions.sh
@@ -429,10 +429,12 @@ COLS="${COLUMNS:-0}"            # bash's internal COLUMNS variable
 [ -z "${COLS}" ] && COLS=80
 [ "${COLS}" -gt 0 ] || COLS=80	# width of [ ok ] == 7
 
-if yesno "${RC_ENDCOL}"; then
-	ENDCOL='\033[A\033['$(( COLS - 8 ))'C'
-else
+if ! yesno "${RC_ENDCOL}"; then
 	ENDCOL=''
+elif command -v tput >/dev/null 2>&1; then
+	ENDCOL="$(tput cuu1)$(tput cuf $(( COLS - 8 )) )"
+else
+	ENDCOL='\033[A\033['$(( COLS - 8 ))'C'
 fi
 
 # Setup the colors so our messages all look pretty


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2022-07-29  2:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2022-07-29  2:03 UTC (permalink / raw
  To: gentoo-commits

commit:     7b4d2dbba7937c7576631ffeb3538f81ca9e02f7
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 28 01:01:15 2022 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jul 29 02:03:18 2022 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7b4d2dbb

functions.sh: sort color definition ordering

Makes it easier to compare with Portage's isolated-functions.sh.

Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/functions.sh b/functions.sh
index be67536..0b9e9cf 100644
--- a/functions.sh
+++ b/functions.sh
@@ -437,21 +437,21 @@ fi
 
 # Setup the colors so our messages all look pretty
 if yesno "${RC_NOCOLOR}"; then
-	unset GOOD WARN BAD NORMAL HILITE BRACKET
+	unset BAD BRACKET GOOD HILITE NORMAL WARN
 elif (command -v tput && tput colors) >/dev/null 2>&1; then
-	GOOD="$(tput sgr0)$(tput bold)$(tput setaf 2)"
-	WARN="$(tput sgr0)$(tput bold)$(tput setaf 3)"
 	BAD="$(tput sgr0)$(tput bold)$(tput setaf 1)"
-	HILITE="$(tput sgr0)$(tput bold)$(tput setaf 6)"
 	BRACKET="$(tput sgr0)$(tput bold)$(tput setaf 4)"
+	GOOD="$(tput sgr0)$(tput bold)$(tput setaf 2)"
+	HILITE="$(tput sgr0)$(tput bold)$(tput setaf 6)"
 	NORMAL="$(tput sgr0)"
+	WARN="$(tput sgr0)$(tput bold)$(tput setaf 3)"
 else
-	GOOD=$(printf '\033[32;01m')
-	WARN=$(printf '\033[33;01m')
 	BAD=$(printf '\033[31;01m')
-	HILITE=$(printf '\033[36;01m')
 	BRACKET=$(printf '\033[34;01m')
+	GOOD=$(printf '\033[32;01m')
+	HILITE=$(printf '\033[36;01m')
 	NORMAL=$(printf '\033[0m')
+	WARN=$(printf '\033[33;01m')
 fi
 
 # If we made it this far, the script succeeded, so don't let failures


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2022-07-29  2:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2022-07-29  2:03 UTC (permalink / raw
  To: gentoo-commits

commit:     173e25b61a7ccc838250280cd7cd2aa262484e57
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 28 01:06:18 2022 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jul 29 02:03:18 2022 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=173e25b6

functions.sh: use consistent Gentoo style for braces

Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/functions.sh b/functions.sh
index 0b9e9cf..a5f3bfd 100644
--- a/functions.sh
+++ b/functions.sh
@@ -26,7 +26,7 @@ _esetdent()
 eindent()
 {
 	local i="$1"
-	[ -n "$i" ] && [ "$i" -gt 0 ] || i=$RC_DEFAULT_INDENT
+	[ -n "$i" ] && [ "$i" -gt 0 ] || i=${RC_DEFAULT_INDENT}
 	_esetdent $(( ${#RC_INDENTATION} + i ))
 }
 
@@ -36,7 +36,7 @@ eindent()
 eoutdent()
 {
 	local i="$1"
-	[ -n "$i" ] && [ "$i" -gt 0 ] || i=$RC_DEFAULT_INDENT
+	[ -n "$i" ] && [ "$i" -gt 0 ] || i=${RC_DEFAULT_INDENT}
 	_esetdent $(( ${#RC_INDENTATION} - i ))
 }
 
@@ -71,7 +71,7 @@ esyslog()
 	local pri=
 	local tag=
 
-	if [ -n "$EINFO_LOG" ] && command -v logger > /dev/null 2>&1; then
+	if [ -n "${EINFO_LOG}" ] && command -v logger > /dev/null 2>&1; then
 		pri="$1"
 		tag="$2"
 
@@ -424,10 +424,10 @@ done
 
 # Setup COLS and ENDCOL so eend can line up the [ ok ]
 COLS="${COLUMNS:-0}"            # bash's internal COLUMNS variable
-[ "$COLS" -eq 0 ] && \
+[ "${COLS}" -eq 0 ] && \
         COLS="$(set -- $(stty size 2>/dev/null) ; printf "$2\n")"
-[ -z "$COLS" ] && COLS=80
-[ "$COLS" -gt 0 ] || COLS=80	# width of [ ok ] == 7
+[ -z "${COLS}" ] && COLS=80
+[ "${COLS}" -gt 0 ] || COLS=80	# width of [ ok ] == 7
 
 if yesno "${RC_ENDCOL}"; then
 	ENDCOL='\033[A\033['$(( COLS - 8 ))'C'


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2022-07-29  2:03 Sam James
  0 siblings, 0 replies; 281+ messages in thread
From: Sam James @ 2022-07-29  2:03 UTC (permalink / raw
  To: gentoo-commits

commit:     1c801ce130726a81c59b96cdf4e2bef27893e0b7
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jul 28 00:57:17 2022 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jul 29 02:03:03 2022 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=1c801ce1

functions.sh: fix TTY detection

The use of stdout as an argument in consoletype seems to be based
on a misunderstanding. It doesn't do anything except guarantee
the exit status is 0. The value is thrown away anyway.

This fixes e.g. elibtoolize (from elt-patches) having no colour
for its e.g. ewarn/einfo/etc because when invoked from an ebuild,
it's detected as serial.

Use a simpler test instead. We may want to clean up the logic
in consoletype in future too (just drop lines 82-85?).

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/functions.sh b/functions.sh
index 53cc189..be67536 100644
--- a/functions.sh
+++ b/functions.sh
@@ -404,13 +404,11 @@ RC_INDENTATION=''
 RC_DEFAULT_INDENT=2
 RC_DOT_PATTERN=''
 
-# Cache the CONSOLETYPE - this is important as backgrounded shells don't
-# have a TTY. rc unsets it at the end of running so it shouldn't hang
-# around
-if [ -z "${CONSOLETYPE}" ] ; then
-	CONSOLETYPE="$(consoletype stdout 2>/dev/null )"; export CONSOLETYPE
-fi
-if [ "${CONSOLETYPE}" = "serial" ] ; then
+# If either STDOUT or STDERR is not a tty, disable coloured output. A useful
+# improvement for  the future would be to have the individual logging functions
+# act as they should. For example, ewarn prints to STDOUT whereas eerror prints
+# to STDERR. For now, this is a reasonable compromise.
+if [ ! -t 1 ] || [ ! -t 2 ]; then
 	RC_NOCOLOR="yes"
 	RC_ENDCOL="no"
 fi


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2021-08-30 21:14 Mike Gilbert
  0 siblings, 0 replies; 281+ messages in thread
From: Mike Gilbert @ 2021-08-30 21:14 UTC (permalink / raw
  To: gentoo-commits

commit:     b4986e8ca60437c6c155efedc14cc4480b519482
Author:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
AuthorDate: Mon Aug 30 21:03:00 2021 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Mon Aug 30 21:13:15 2021 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b4986e8c

functions.sh: drop get_libdir

libdir is defined when packages are built. Trying to determine its value
via a runtime function makes no sense.

On a typical Gentoo system, this function will always return "lib",
which is often the wrong value on a multilib system with SYMLINK_LIB=no.

Bug: https://bugs.gentoo.org/640456
Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 functions.sh | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/functions.sh b/functions.sh
index 3ea9daa..53cc189 100644
--- a/functions.sh
+++ b/functions.sh
@@ -335,19 +335,6 @@ veoutdent()
 	yesno "${EINFO_VERBOSE}" && eoutdent
 }
 
-#
-#    prints the current libdir {lib,lib32,lib64}
-#
-get_libdir()
-{
-	if [ -n "${CONF_LIBDIR_OVERRIDE}" ] ; then
-		CONF_LIBDIR="${CONF_LIBDIR_OVERRIDE}"
-	elif command -v portageq > /dev/null 2>&1; then
-		CONF_LIBDIR="$(portageq envvar CONF_LIBDIR)"
-	fi
-	printf "${CONF_LIBDIR:=lib}\n"
-}
-
 #
 #   return 0 if gentoo=param was passed to the kernel
 #


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2021-08-30 21:14 Mike Gilbert
  0 siblings, 0 replies; 281+ messages in thread
From: Mike Gilbert @ 2021-08-30 21:14 UTC (permalink / raw
  To: gentoo-commits

commit:     6cf8f4e686bec4e423d1195dfa5f23845866a310
Author:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
AuthorDate: Mon Aug 30 21:08:23 2021 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Mon Aug 30 21:13:36 2021 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6cf8f4e6

Set VERSION = 0.15

Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index a5612a0..76c2e9a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 # gentoo-functions Makefile
-# Copyright 2014-2020 Gentoo Authors
+# Copyright 2014-2021 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
-VERSION = 0.14
+VERSION = 0.15
 GITREF ?= $(VERSION)
 PKG ?= gentoo-functions-$(VERSION)
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2020-11-19 18:20 Mike Gilbert
  0 siblings, 0 replies; 281+ messages in thread
From: Mike Gilbert @ 2020-11-19 18:20 UTC (permalink / raw
  To: gentoo-commits

commit:     f0ca05097fc2f454deae6eedc1bf94d6cd543013
Author:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
AuthorDate: Thu Nov 19 18:20:18 2020 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Thu Nov 19 18:20:18 2020 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f0ca0509

Update copyright notice

Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 consoletype.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/consoletype.c b/consoletype.c
index b7bf4e6..4249504 100644
--- a/consoletype.c
+++ b/consoletype.c
@@ -3,7 +3,7 @@
  * simple app to figure out whether the current terminal
  * is serial, console (vt), or remote (pty).
  *
- * Copyright 1999-2007 Gentoo Foundation
+ * Copyright 1999-2020 Gentoo Authors
  * Distributed under the terms of the GNU General Public License v2
  */
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2020-11-19 18:20 Mike Gilbert
  0 siblings, 0 replies; 281+ messages in thread
From: Mike Gilbert @ 2020-11-19 18:20 UTC (permalink / raw
  To: gentoo-commits

commit:     f7c81e9c99a7b3ae1e9d96e25cfe97e52ca5115c
Author:     Jacob Floyd <cognifloyd <AT> gmail <DOT> com>
AuthorDate: Thu Nov 19 17:33:56 2020 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Thu Nov 19 18:16:49 2020 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f7c81e9c

Update to version 0.14

Signed-off-by: Jacob Floyd <cognifloyd <AT> gmail.com>
Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 47f41ca..a5612a0 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 # Copyright 2014-2020 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
-VERSION = 0.13
+VERSION = 0.14
 GITREF ?= $(VERSION)
 PKG ?= gentoo-functions-$(VERSION)
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2020-11-19 18:20 Mike Gilbert
  0 siblings, 0 replies; 281+ messages in thread
From: Mike Gilbert @ 2020-11-19 18:20 UTC (permalink / raw
  To: gentoo-commits

commit:     9d503ef40a6d73eea14b6f5015cb2abd9eee292b
Author:     Jacob Floyd <cognifloyd <AT> gmail <DOT> com>
AuthorDate: Thu Nov 19 17:20:01 2020 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Thu Nov 19 18:16:42 2020 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9d503ef4

Only include sysmacros.h on linux

sysmacros.h is only needed for major() which is only used within an
`#if defined(__linux__)` block. So, this header is only needed on linux.

Bug: https://bugs.gentoo.org/751511
Signed-off-by: Jacob Floyd <cognifloyd <AT> gmail.com>
Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 consoletype.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/consoletype.c b/consoletype.c
index dfbda22..b7bf4e6 100644
--- a/consoletype.c
+++ b/consoletype.c
@@ -13,7 +13,9 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
+#if defined(__linux__)
 #include <sys/sysmacros.h>
+#endif
 
 enum termtype {
 	IS_VT = 0,


^ permalink raw reply related	[flat|nested] 281+ messages in thread
* [gentoo-commits] proj/gentoo-functions:master commit in: /
@ 2020-01-26 23:19 Mike Gilbert
  0 siblings, 0 replies; 281+ messages in thread
From: Mike Gilbert @ 2020-01-26 23:19 UTC (permalink / raw
  To: gentoo-commits

commit:     7cd936fe31f611dc932fa2280392543bf3729a94
Author:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
AuthorDate: Sun Jan 26 23:15:11 2020 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Sun Jan 26 23:18:38 2020 +0000
URL:        https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=7cd936fe

Update version (0.13)

Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 6de74d7..47f41ca 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 # gentoo-functions Makefile
-# Copyright 2014 Gentoo Foundation
+# Copyright 2014-2020 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
-VERSION = 0.12
+VERSION = 0.13
 GITREF ?= $(VERSION)
 PKG ?= gentoo-functions-$(VERSION)
 


^ permalink raw reply related	[flat|nested] 281+ messages in thread

end of thread, other threads:[~2024-10-05  7:25 UTC | newest]

Thread overview: 281+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-25  4:06 [gentoo-commits] proj/gentoo-functions:master commit in: / Sam James
  -- strict thread matches above, loose matches on Subject: below --
2024-10-05  7:25 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-10-05  4:15 Sam James
2024-08-11 10:23 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-11 10:11 Sam James
2024-08-05 20:39 Sam James
2024-08-05 20:39 Sam James
2024-08-05  2:03 Sam James
2024-08-05  2:02 Sam James
2024-08-05  2:02 Sam James
2024-08-05  2:02 Sam James
2024-08-05  2:02 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-08-02 23:14 Sam James
2024-07-08  3:00 Sam James
2024-07-08  2:31 Sam James
2024-07-08  2:31 Sam James
2024-07-07  5:55 Sam James
2024-07-07  5:55 Sam James
2024-07-07  5:55 Sam James
2024-07-07  5:55 Sam James
2024-07-07  5:55 Sam James
2024-07-07  5:55 Sam James
2024-07-07  5:55 Sam James
2024-07-07  5:55 Sam James
2024-07-07  5:55 Sam James
2024-07-07  5:55 Sam James
2024-06-25  4:06 Sam James
2024-06-25  4:06 Sam James
2024-06-25  4:06 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-06-21 13:14 Sam James
2024-05-24  6:05 Sam James
2024-05-24  1:18 Sam James
2024-05-24  1:18 Sam James
2024-05-22  1:12 Sam James
2024-05-22  1:12 Sam James
2024-05-22  1:12 Sam James
2024-05-22  1:12 Sam James
2024-05-22  1:12 Sam James
2024-05-22  1:12 Sam James
2024-05-22  1:12 Sam James
2024-05-22  1:12 Sam James
2024-05-22  1:12 Sam James
2024-05-19 15:27 Sam James
2024-05-19 15:27 Sam James
2024-05-19 15:27 Sam James
2024-05-19 15:27 Sam James
2024-05-18 16:07 Sam James
2024-05-18 16:06 Sam James
2024-05-18 16:06 Sam James
2024-05-18 15:34 Sam James
2024-05-18 15:32 Sam James
2024-05-18 15:32 Sam James
2024-05-18 14:04 Sam James
2024-05-18 14:04 Sam James
2024-05-18 14:04 Sam James
2024-05-18 14:04 Sam James
2024-05-18 14:04 Sam James
2024-05-18 14:04 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-17  4:03 Sam James
2024-05-15 10:28 Sam James
2024-05-15 10:28 Sam James
2024-05-14  0:18 Sam James
2024-05-14  0:15 Sam James
2024-05-14  0:12 Sam James
2024-05-14  0:12 Sam James
2024-05-14  0:08 Sam James
2024-05-14  0:08 Sam James
2024-05-14  0:05 Sam James
2024-05-14  0:05 Sam James
2024-05-14  0:05 Sam James
2024-05-14  0:05 Sam James
2024-05-14  0:05 Sam James
2024-02-16 21:35 Sam James
2023-06-11 16:47 Sam James
2023-06-11 16:47 Sam James
2023-06-11 16:47 Sam James
2023-06-11 16:47 Sam James
2023-06-11 16:47 Sam James
2023-06-11 16:47 Sam James
2023-06-11 16:47 Sam James
2023-06-11 16:47 Sam James
2023-06-10  7:23 Sam James
2023-06-10  7:23 Sam James
2023-06-10  6:04 Sam James
2023-06-10  4:22 Sam James
2023-06-10  4:22 Sam James
2023-06-10  4:22 Sam James
2023-06-10  4:22 Sam James
2023-06-10  4:22 Sam James
2023-06-10  4:22 Sam James
2023-06-10  4:22 Sam James
2023-06-10  4:22 Sam James
2023-06-10  4:22 Sam James
2023-06-10  4:22 Sam James
2023-06-09 11:17 Sam James
2023-06-09 11:11 Sam James
2023-06-09 11:02 Sam James
2023-06-09 11:02 Sam James
2023-06-09 11:02 Sam James
2023-06-09 11:02 Sam James
2023-06-07 11:13 Sam James
2023-06-07 11:13 Sam James
2023-06-07 11:13 Sam James
2023-06-07 11:13 Sam James
2023-06-07 11:13 Sam James
2023-06-07 11:13 Sam James
2023-06-07 11:13 Sam James
2023-06-07 11:13 Sam James
2023-06-07 11:13 Sam James
2023-02-19 16:14 Sam James
2023-02-19 16:14 Sam James
2023-02-19 16:14 Sam James
2023-02-19 16:14 Sam James
2023-02-19 16:14 Sam James
2023-02-19 16:14 Sam James
2023-02-19 16:14 Sam James
2023-02-19 16:14 Sam James
2023-02-19 16:14 Sam James
2023-02-17  7:44 Sam James
2023-02-17  7:44 Sam James
2023-02-17  7:44 Sam James
2023-02-17  1:33 Sam James
2023-02-17  1:33 Sam James
2023-02-17  1:33 Sam James
2023-02-15  8:18 Sam James
2023-02-15  7:48 Sam James
2023-02-15  7:46 Sam James
2023-02-15  7:46 Sam James
2023-02-15  7:46 Sam James
2023-02-15  7:46 Sam James
2023-02-15  7:46 Sam James
2023-02-15  7:46 Sam James
2023-02-15  2:24 Sam James
2023-02-15  2:24 Sam James
2023-02-15  2:24 Sam James
2023-02-14  3:40 Sam James
2023-02-14  3:40 Sam James
2023-02-14  3:40 Sam James
2023-02-14  3:40 Sam James
2023-02-14  0:09 Sam James
2023-02-14  0:09 Sam James
2023-02-13 21:37 Sam James
2023-02-13 21:37 Sam James
2023-02-13 21:37 Sam James
2023-02-13 21:37 Sam James
2023-02-13 21:37 Sam James
2023-02-13 21:37 Sam James
2023-02-13 21:37 Sam James
2023-02-13 21:37 Sam James
2023-02-12 18:53 Sam James
2023-02-12 18:53 Sam James
2023-02-12  6:53 Sam James
2023-02-12  6:53 Sam James
2023-02-12  6:53 Sam James
2023-02-11  1:43 Sam James
2023-02-11  1:43 Sam James
2023-02-10  6:09 Sam James
2023-02-10  6:09 Sam James
2023-02-10  6:09 Sam James
2023-02-09  3:54 Sam James
2023-02-09  3:54 Sam James
2023-02-08  3:37 Sam James
2023-02-08  1:06 Sam James
2023-02-08  0:03 Sam James
2023-02-08  0:03 Sam James
2023-02-07 23:47 Sam James
2023-02-07 23:42 Sam James
2023-02-07 23:42 Sam James
2023-02-07 23:42 Sam James
2023-02-07 23:42 Sam James
2023-02-07  1:08 Sam James
2023-02-07  1:08 Sam James
2023-02-06 13:47 Sam James
2023-02-06  4:32 Sam James
2023-02-06  4:23 Sam James
2023-02-06  4:19 Sam James
2023-02-06  4:10 Sam James
2023-02-06  4:10 Sam James
2023-02-06  3:59 Sam James
2023-02-06  3:59 Sam James
2023-02-06  3:59 Sam James
2022-07-30  5:48 Sam James
2022-07-29  2:03 Sam James
2022-07-29  2:03 Sam James
2022-07-29  2:03 Sam James
2021-08-30 21:14 Mike Gilbert
2021-08-30 21:14 Mike Gilbert
2020-11-19 18:20 Mike Gilbert
2020-11-19 18:20 Mike Gilbert
2020-11-19 18:20 Mike Gilbert
2020-01-26 23:19 Mike Gilbert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox