[gentoo-commits] proj/gentoo-functions:master commit in: functions/, /

2024-08-11 Thread Sam James
commit: 6cf0940b8d336eb35a970af2ffc819f55e3ab429
Author: Kerin Millar  plushkava  net>
AuthorDate: Sat Aug 10 05:12:15 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Sun Aug 11 10:11:03 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6cf0940b

Use the -nt and -ot test primaries again rather than depend on GNU find

As regards the test(1) utility, the POSIX.1-2024 specification defines
the -nt and -ot primaries as standard features. Given that the
specification in question was only recently published, this would not
normally be an adequate reason for using them in gentoo-functions, in
and as of itself. However, I was already aware that the these primaries
are commonly implemented and have been so for years.

So, I decided to evaluate a number of shells and see how things stand
now. Here is a list of the ones that I tested:

- ash (busybox 1.36.1)
- dash 0.5.12
- bash 5.2.26
- ksh 93u+
- loksh 7.5
- mksh 59c
- oksh 7.5
- sh (FreeBSD 14.1)
- sh (NetBSD 10.0)
- sh (OpenBSD 7.5)
- yash 2.56.1

Of these, bash, ksh93, loksh, mksh, oksh, OpenBSD sh and yash appear to
conform with the POSIX-1.2024 specification. The remaining four fail to
conform in one particular respect, which is as follows.

$ touch existent
$ set -- existent nonexistent
$ [ "$1" -nt "$2" ]; echo "$?" # should be 0
1
$ [ "$2" -ot "$1" ]; echo "$?" # should be 0
1

To address this, I discerned a reasonably straightforward workaround
that involves testing both whether the file under consideration exists
and whether the variable keeping track of the newest/oldest file has yet
been assigned to.

As far as I am concerned, the coverage is more than adequate for both
primaries to be used by gentoo-functions. As such, this commit adjusts
the following three functions so as to do exactly that.

- is_older_than()
- newest()
- oldest()

It also removes the following functions, since they are no longer used.

- _find0()
- _select_by_mtime()

With this, GNU findutils is no longer a required runtime dependency. Of
course, should a newly introduced feature of gentoo-functions benefit
from the presence of findutils in the future, there is no reason that it
cannot be brought back in that capacity.

Signed-off-by: Kerin Millar  plushkava.net>
Signed-off-by: Sam James  gentoo.org>

 functions.sh| 157 +---
 functions/rc.sh |  25 +++--
 2 files changed, 113 insertions(+), 69 deletions(-)

diff --git a/functions.sh b/functions.sh
index 641deb6..43ea385 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,3043
+# shellcheck shell=sh disable=2209,3013,3043
 
 # This file contains a series of function declarations followed by some
 # initialisation code. Functions intended for internal use shall be prefixed
@@ -294,17 +294,55 @@ is_anyof()
 
 #
 # 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.
+# 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
+# null-terminated records. In the case that two or more pathnames are
+# candidates, whichever was first specified shall take precedence over the
+# other. If no pathnames are given, or those specified do not exist, the return
+# value shall be greater than 0.
+#
+# Pathnames containing  characters shall be handled correctly if
+# conveyed as positional parameters. Otherwise, the behaviour for such
+# pathnames is unspecified. Users of the function are duly expected to refrain
+# from conveying such pathnames for consumption from the standard input; for
+# example, by specifying a predicate of ! -path $'*\n*' to the find utility.
+# This constraint is expected to be eliminated by a future amendment to the
+# function, once support for read -d becomes sufficiently widespread.
+#
+# The test utility is required to support the -nt primary, per POSIX-1.2024.
+# However, measures are in place to to achieve compatibility with shells that
+# implement the primary without yet fully adhering to the specification.
 #
 newest()
 {
-   _select_by_mtime -r "$@"
+   local path newest
+
+   newest=
+   if [ "$#" -gt 0 ]; then
+ 

[gentoo-commits] proj/gentoo-functions:master commit in: /, functions/

2024-08-11 Thread Sam James
commit: 8f708ef54a07f200b308f82fd64c2c87f5e89b11
Author: Kerin Millar  plushkava  net>
AuthorDate: Sat Aug 10 06:57:17 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Sun Aug 11 10:11:05 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=8f708ef5

Remedy false positives in categories SC2034 and SC2154

Signed-off-by: Kerin Millar  plushkava.net>
Signed-off-by: Sam James  gentoo.org>

 functions.sh  | 5 -
 functions/experimental.sh | 1 +
 functions/rc.sh   | 8 
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/functions.sh b/functions.sh
index eff7f5f..38eef62 100644
--- a/functions.sh
+++ b/functions.sh
@@ -958,11 +958,6 @@ if [ ! "${genfun_basedir+set}" ]; then
genfun_basedir=${genfun_prefix}/lib/gentoo
 fi
 
-# 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='
-'
-
 # 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

diff --git a/functions/experimental.sh b/functions/experimental.sh
index 0ca9904..7c2fb25 100644
--- a/functions/experimental.sh
+++ b/functions/experimental.sh
@@ -168,6 +168,7 @@ str_between()
else
set -- "$2" "$1" "$3"
i=0
+   # shellcheck disable=2034
printf '%s\n' "$@" |
sort |
while IFS= read -r line; do

diff --git a/functions/rc.sh b/functions/rc.sh
index 4eff3c8..101b99e 100644
--- a/functions/rc.sh
+++ b/functions/rc.sh
@@ -347,6 +347,7 @@ _eend()
"${efunc}" "${msg}"
fi
# Generate an indicator for ebegin's unsuccessful conclusion.
+   # shellcheck disable=2154
if _update_tty_level <&1; [ "${genfun_tty}" -eq 0 ]; then
msg="[ !! ]"
else
@@ -356,6 +357,7 @@ _eend()
return "${retval}"
else
# Generate an indicator for ebegin's successful conclusion.
+   # shellcheck disable=2154
if _update_tty_level <&1; [ "${genfun_tty}" -eq 0 ]; then
msg="[ ok ]"
else
@@ -367,6 +369,7 @@ _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.
+   # shellcheck disable=2154
col=$(( genfun_cols > 6 ? genfun_cols - 6 : 1 ))
printf '\0337\033[1A\033[%dG %s\0338' "$(( col + genfun_offset 
))" "${msg}"
else
@@ -484,5 +487,10 @@ else
genfun_offset=0
 fi
 
+# 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='
+'
+
 # shellcheck disable=2034
 RC_GOT_FUNCTIONS=yes



[gentoo-commits] proj/gentoo-functions:master commit in: functions/, /

2024-08-11 Thread Sam James
commit: 5a34ca0e2001d70bc2037fc2226ad510e26a3349
Author: Kerin Millar  plushkava  net>
AuthorDate: Thu Aug  8 01:27:52 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Sun Aug 11 10:10:58 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=5a34ca0e

Avoid unspecified behaviour around simple commands in general

As mentioned by the previous commit, the Shell Command Language leaves
it unspecified as to whether variable assignments affecting the
execution environment of a simple command charged with executing a
function (that is not the implementation of a standard utility) shall
persist after the completion of the function.

It transpires that modifying gentoo-functions so as to steer clear of
this pitfall isn't particularly difficult so this commit does exactly
that. Most of the changes are in test-functions but functions/rc.sh also
required some minor changes regarding the use of the GENFUN_CALLER
variable.

With this, loksh very nearly passes the test suite. There is one
individual test that continues to fail, although it looks as though that
may be caused by a genuine bug on the part of the shell. That will
require investigating in its own right.

Signed-off-by: Kerin Millar  plushkava.net>
Signed-off-by: Sam James  gentoo.org>

 functions/rc.sh | 16 +++-
 test-functions  | 43 ---
 2 files changed, 35 insertions(+), 24 deletions(-)

diff --git a/functions/rc.sh b/functions/rc.sh
index 12444d1..0c14035 100644
--- a/functions/rc.sh
+++ b/functions/rc.sh
@@ -49,7 +49,8 @@ ebegin()
 #
 eend()
 {
-   GENFUN_CALLER=${GENFUN_CALLER:-eend} _eend eerror "$@"
+   : "${genfun_caller:=eend}"
+   _eend eerror "$@"
 }
 
 #
@@ -161,7 +162,8 @@ ewarnn()
 #
 ewend()
 {
-   GENFUN_CALLER=${GENFUN_CALLER:-ewend} _eend ewarn "$@"
+   : "${genfun_caller:=ewend}"
+   _eend ewarn "$@"
 }
 
 #
@@ -240,7 +242,8 @@ done
 veend()
 {
if yesno "${EINFO_VERBOSE}"; then
-   GENFUN_CALLER=veend eend "$@"
+   genfun_caller=veend
+   eend "$@"
elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then
_warn_for_args veend "$1"
false
@@ -252,7 +255,8 @@ veend()
 vewend()
 {
if yesno "${EINFO_VERBOSE}"; then
-   GENFUN_CALLER=vewend ewend "$@"
+   genfun_caller=vewend
+   ewend "$@"
elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then
_warn_for_args vewend "$1"
false
@@ -311,7 +315,7 @@ _eend()
if [ "$#" -eq 0 ]; then
retval=0
elif ! is_int "$1" || [ "$1" -lt 0 ]; then
-   _warn_for_args "${GENFUN_CALLER}" "$1"
+   _warn_for_args "${genfun_caller}" "$1"
retval=1
msg=
else
@@ -320,6 +324,8 @@ _eend()
msg=$*
fi
 
+   genfun_caller=
+
if [ "${retval}" -ne 0 ]; then
# If a message was given, print it with the specified function.
if _is_visible "${msg}"; then

diff --git a/test-functions b/test-functions
index afc56eb..0b0e127 100755
--- a/test-functions
+++ b/test-functions
@@ -46,19 +46,6 @@ 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  ''  \
@@ -76,13 +63,17 @@ test_chdir() {
fi
 
callback() {
+   local CDPATH var
+
shift
test_description="chdir $(quote_args "$@")"
if [ "$BASH" ]; then
# shellcheck disable=3044
shopt -s cdable_vars
fi
-   CDPATH=child var=child chdir "$@" \
+   CDPATH=child
+   var=child
+   chdir "$@" \
&& test "$PWD" != "$OLDPWD" \
&& cd - >/dev/null
}
@@ -266,7 +257,7 @@ test_esyslog() {
should_log=$2
shift 2
test_description="esyslog $(quote_args "$@")"
-   logged=$(EINFO_LOG=1 esyslog "$@")
+   logged=$(EINFO_LOG=1; esyslog "$@")
case $? in
0)
test "${logged:-0}" -eq "${should_log}"
@@ -680,10 +671,22 @@ test_whenceforth() {
whenceforth "$@" >/dev/null
else
test_description="PATH=${path} whenceforth $(quote_args 
"$@")"
-   PATH=${path} whenceforth "$@" >/dev/null
+   (
+

[gentoo-commits] proj/gentoo-functions:master commit in: functions/

2024-08-04 Thread Sam James
commit: fed96ec1da2fad4070a02803ceef4a322a87eb4f
Author: Kerin Millar  plushkava  net>
AuthorDate: Sun Aug  4 23:48:04 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Sun Aug  4 23:53:22 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=fed96ec1

Do not yet deprecate RC_NOCOLOR

It would be sensible to conduct a survey to determine whether - and
where - it is being used beforehand.

Signed-off-by: Kerin Millar  plushkava.net>

 functions/rc.sh | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/functions/rc.sh b/functions/rc.sh
index 9b1fc5d..12444d1 100644
--- a/functions/rc.sh
+++ b/functions/rc.sh
@@ -426,9 +426,7 @@ _is_visible()
 
#--#
 
 # Determine whether the use of color is to be wilfully avoided.
-if [ "${RC_NOCOLOR+set}" ]; then
-   warn "the RC_NOCOLOR variable is deprecated by gentoo-functions; please 
set NO_COLOR instead"
-elif [ -n "${NO_COLOR}" ]; then
+if [ "${NO_COLOR}" ]; then
# See https://no-color.org/.
RC_NOCOLOR=yes
 else



[gentoo-commits] proj/gentoo-functions:master commit in: functions/

2024-08-02 Thread Sam James
commit: d6e689bc832e4b033f4af9cb6746a99649ecc8d8
Author: Kerin Millar  plushkava  net>
AuthorDate: Wed Jul 31 23:20:10 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Wed Jul 31 23:36:10 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d6e689bc

Treat EINFO_LOG as false if equal to RC_SERVICE

Consider the value of EINFO_LOG to be false in the event that it is
equal to the value of RC_SERVICE. The reason for this is that, as of the
time of writing, openrc-run(8) defines and uses EINFO_LOG in a way that
is at odds with gentoo-functions. Ideally, the behaviour of OpenRC would
be modified so that it becomes possible to jettison this workaround.

Fixes: 0dd8364c03c6f8737150ee4f146ddeeec57efee9
Bug: https://bugs.gentoo.org/936613
Signed-off-by: Kerin Millar  plushkava.net>

 functions/rc.sh | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/functions/rc.sh b/functions/rc.sh
index 9129b32..9b1fc5d 100644
--- a/functions/rc.sh
+++ b/functions/rc.sh
@@ -117,7 +117,11 @@ eoutdent()
 #
 # 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.
+# and the remaining parameters as the message to be logged. As a special case,
+# the value of EINFO_LOG shall be treated as if were false in the event that it
+# is equal to the value of RC_SERVICE. The reason for this is that, as of the
+# time of writing, openrc-run(8) defines and uses EINFO_LOG in a way that is
+# at odds with gentoo-functions.
 #
 esyslog()
 {
@@ -126,7 +130,7 @@ esyslog()
if [ "$#" -lt 2 ]; then
warn "esyslog: too few arguments (got $#, expected at least 2)"
return 1
-   elif yesno "${EINFO_LOG}" && hash logger 2>/dev/null; then
+   elif [ "${EINFO_LOG}" != "${RC_SERVICE}" ] && yesno "${EINFO_LOG}"; then
pri=$1 tag=$2
shift 2
msg=$*



[gentoo-commits] proj/gentoo-functions:master commit in: /, functions/

2024-08-02 Thread Sam James
commit: 2e8bbd04cb55163b3d18ab407ffd8be24bf82c6e
Author: Kerin Millar  plushkava  net>
AuthorDate: Fri Aug  2 14:31:54 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Fri Aug  2 16:21:14 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2e8bbd04

Move is_subset() to experimental

I'm not yet ready to commit to it being among the core functions for the
inaugural API level.

Signed-off-by: Kerin Millar  plushkava.net>

 functions.sh  | 40 
 functions/experimental.sh | 40 
 test-functions|  2 +-
 3 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/functions.sh b/functions.sh
index a002e54..69b9bf5 100644
--- a/functions.sh
+++ b/functions.sh
@@ -246,46 +246,6 @@ is_anyof()
false
 }
 
-#
-# 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, it
-# shall be taken as the value of the sentinel. Otherwise, the value of the
-# sentinel shall be defined as . 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'
-   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/functions/experimental.sh b/functions/experimental.sh
index bbbf0fa..0ca9904 100644
--- a/functions/experimental.sh
+++ b/functions/experimental.sh
@@ -82,6 +82,46 @@ is_interactive()
test -t 0 && { true 3>&1; } 2>/dev/null
 }
 
+#
+# 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, it
+# shall be taken as the value of the sentinel. Otherwise, the value of the
+# sentinel shall be defined as . 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'
+   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
+}
+
 #
 # Continuously reads lines from the standard input, prepending each with a
 # timestamp before printing to the standard output. Timestamps shall be in the

diff --git a/test-functions b/test-functions
index 8070c8d..43b5320 100755
--- a/test-functions
+++ b/test-functions
@@ -909,7 +909,7 @@ else
test_whenceforth || rc=1
test_parallel_run || rc=1
test_is_anyof || rc=1
-   test_is_subset || rc=1
+   #test_is_subset || rc=1
test_trueof_all || rc=1
test_trueof_any || rc=1
#test_substr || rc=1



[gentoo-commits] proj/gentoo-functions:master commit in: functions/, /

2024-08-02 Thread Sam James
commit: 4e09cd6073e9f7906081231af7511bc74cd1d1bb
Author: Kerin Millar  plushkava  net>
AuthorDate: Mon Jul  8 05:24:32 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Mon Jul  8 05:24:32 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=4e09cd60

Add the _find0() helper function

The function is a simple wrapper around GNU find(1) which presumes the
intent to use the -files0-from option to read NUL-delimited path names
from the standard input. The benefit in having it is twofold. Firstly,
the _select_by_mtime() and is_older_than() functions are thereby made a
little easier to read. Secondly, the genfun_bin_find variable is now
initialised lazily.

Signed-off-by: Kerin Millar  plushkava.net>

 functions.sh| 33 -
 functions/rc.sh |  2 +-
 2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/functions.sh b/functions.sh
index 82f59a3..dd4eef8 100644
--- a/functions.sh
+++ b/functions.sh
@@ -652,6 +652,33 @@ whenceforth()
 
 
#--#
 
+#
+# See the definitions of _select_by_mtime() and is_older_than().
+#
+_find0()
+{
+   # Store the name of the GNU find binary, which may be "gfind".
+   hash gfind 2>/dev/null && genfun_bin_find=gfind || genfun_bin_find=find
+
+   _find0()
+   {
+   local opt
+
+   case $1 in
+   -[HL])
+   opt=$1
+   shift
+   set -- "${opt}" -files0-from - "$@"
+   ;;
+   *)
+   set -- -files0-from - "$@"
+   esac
+   "${genfun_bin_find}" "$@"
+   }
+
+   _find0 "$@"
+}
+
 #
 # Determines whether the terminal is a dumb one.
 #
@@ -660,7 +687,6 @@ _has_dumb_terminal()
! case ${TERM} in *dumb*) false ;; esac
 }
 
-#
 #
 # See the definitions of oldest() and newest().
 #
@@ -674,7 +700,7 @@ _select_by_mtime() {
else
cat
fi \
-   | "${genfun_bin_find}" -files0-from - -maxdepth 0 ! -path 
"*${genfun_newline}*" -printf '%T+ %p\n' \
+   | _find0 -maxdepth 0 ! -path "*${genfun_newline}*" -printf '%T+ %p\n' \
| sort "${sort_opt}" \
| { IFS= read -r line && printf '%s\n' "${line#* }"; }
 }
@@ -841,9 +867,6 @@ if [ ! "${genfun_basedir+set}" ]; then
genfun_basedir=${genfun_prefix}/lib/gentoo
 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
-
 # 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='

diff --git a/functions/rc.sh b/functions/rc.sh
index 2f2dc52..9129b32 100644
--- a/functions/rc.sh
+++ b/functions/rc.sh
@@ -213,7 +213,7 @@ is_older_than()
fi
shift
{ test "$#" -gt 0 && printf '%s\0' "$@"; } \
-   | "${genfun_bin_find}" -L -files0-from - ${ref:+-newermm} 
${ref:+"${ref}"} -printf '\n' -quit \
+   | _find0 -L ${ref:+-newermm} ${ref:+"${ref}"} -printf '\n' -quit \
| read -r _
 }
 



[gentoo-commits] proj/gentoo-functions:master commit in: functions/

2024-07-06 Thread Sam James
commit: b720081b68dfba3ed4ebacb4d7564977708bfa25
Author: Kerin Millar  plushkava  net>
AuthorDate: Thu Jun 27 20:42:23 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Fri Jun 28 17:39:33 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b720081b

Add the int_between() and str_between() functions to experimental

Signed-off-by: Kerin Millar  plushkava.net>

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

diff --git a/functions/experimental.sh b/functions/experimental.sh
index e02923a..1aac078 100644
--- a/functions/experimental.sh
+++ b/functions/experimental.sh
@@ -12,6 +12,24 @@
 
 warn "sourcing the experimental module from gentoo-functions; no stability 
guarantee is provided"
 
+#
+# Expects three parameters, all of which must be integers, and determines
+# whether the first is numerically greater than or equal to the second, and
+# numerically lower than or equal to the third.
+#
+int_between()
+{
+   if [ "$#" -lt 3 ]; then
+   warn "int_between: too few arguments (got $#, expected 3)"
+   false
+   elif ! is_int "$2" || ! is_int "$3"; then
+   _warn_for_args int_between "$@"
+   false
+   else
+   is_int "$1" && [ "$1" -ge "$2" ] && [ "$1" -le "$3" ]
+   fi
+}
+
 #
 # Returns 0 provided that two conditions hold. Firstly, that the standard input
 # is connected to a tty. Secondly, that the standard output has not been 
closed.
@@ -52,6 +70,30 @@ prepend_ts()
prepend_ts
 }
 
+#
+# Expects three parameters and determines whether the first is 
lexicographically
+# greater than or equal to the second, and lexicographically lower than or 
equal
+# to the third. The effective system collation shall affect the results, given
+# the involvement of the sort(1) utility.
+#
+str_between()
+{
+   local i
+
+   if [ "$#" -ne 3 ]; then
+   warn "str_between: wrong number of arguments (got $#, expected 
3)"
+   false
+   else
+   set -- "$2" "$1" "$3"
+   i=0
+   printf '%s\n' "$@" |
+   sort |
+   while IFS= read -r line; do
+   eval "[ \"\${line}\" = \"\$$(( i += 1 ))\" ]" || ! break
+   done
+   fi
+}
+
 #
 # Takes the first parameter as either a relative pathname or an integer
 # referring to a number of iterations. To be recognised as a pathname, the 
first



[gentoo-commits] proj/gentoo-functions:master commit in: functions/

2024-07-06 Thread Sam James
commit: 9dc4a6c4a383b1214babe14b4b7091ad56840486
Author: Kerin Millar  plushkava  net>
AuthorDate: Thu Jun 27 20:36:10 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Fri Jun 28 17:39:27 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9dc4a6c4

Add the up() function to experimental

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

Signed-off-by: Kerin Millar  plushkava.net>

 functions/experimental.sh | 28 
 1 file changed, 28 insertions(+)

diff --git a/functions/experimental.sh b/functions/experimental.sh
index f577fa7..e02923a 100644
--- a/functions/experimental.sh
+++ b/functions/experimental.sh
@@ -51,3 +51,31 @@ prepend_ts()
 
prepend_ts
 }
+
+#
+# Takes the first parameter as either a relative pathname or an integer
+# referring to a number of iterations. To be recognised as a pathname, the 
first
+# four characters must form the special prefix, ".../". It recurses upwards 
from
+# the current directory until either the relative pathname is found to exist,
+# the specified number of iterations has occurred, or the root directory is
+# encountered. In the event that the root directory is reached without either 
of
+# the first two conditions being satisfied, the return value shall be 1.
+# Otherwise, the value of PWD shall be printed to the standard output.
+#
+up()
+{
+   local i
+
+   i=0
+   while [ "${PWD}" != / ]; do
+   chdir ../
+   case $1 in
+   .../*)
+   test -e "${1#.../}"
+   ;;
+   *)
+   test "$(( i += 1 ))" -eq "$1"
+   esac \
+   && pwd && return
+   done
+}



[gentoo-commits] proj/gentoo-functions:master commit in: /, functions/

2024-07-06 Thread Sam James
commit: 23ce043cfccf6b39caf790464c18f2df1d5b7d1b
Author: Kerin Millar  plushkava  net>
AuthorDate: Mon Jul  1 02:29:27 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Mon Jul  1 02:32:27 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=23ce043c

Move fetch() to experimental

I'm not yet ready to commit to it being among the core functions for the
inaugural API level.

Signed-off-by: Kerin Millar  plushkava.net>

 functions.sh  | 42 --
 functions/experimental.sh | 42 ++
 2 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/functions.sh b/functions.sh
index a4fa946..cfaddc3 100644
--- a/functions.sh
+++ b/functions.sh
@@ -138,48 +138,6 @@ contains_any()
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://
-# 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 be 
installed"
-   return 127
-   fi
-
-   fetch "$@"
-}
-
 #
 # Determines whether the current shell is a subprocess of portage.
 #

diff --git a/functions/experimental.sh b/functions/experimental.sh
index 4d56cfa..bbbf0fa 100644
--- a/functions/experimental.sh
+++ b/functions/experimental.sh
@@ -12,6 +12,48 @@
 
 warn "sourcing the experimental module from gentoo-functions; no stability 
guarantee is provided"
 
+#
+# 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 be 
installed"
+   return 127
+   fi
+
+   fetch "$@"
+}
+
 #
 # Expects three parameters, all of which must be integers, and determines
 # whether the first is numerically greater than or equal to the second, and



[gentoo-commits] proj/gentoo-functions:master commit in: /, functions/

2024-07-06 Thread Sam James
commit: feaa7438ef8c749179bf5fb99f93a3683e6d40fd
Author: Kerin Millar  plushkava  net>
AuthorDate: Sun Jun 30 23:15:36 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Mon Jul  1 02:31:58 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=feaa7438

Move substr() to experimental

Though it works very well, I'm not yet ready to commit to it being among
the core functions for the inaugural API level.

Signed-off-by: Kerin Millar  plushkava.net>

 functions.sh  | 41 -
 functions/experimental.sh | 41 +
 test-functions|  2 +-
 3 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/functions.sh b/functions.sh
index 087b62d..1926c40 100644
--- a/functions.sh
+++ b/functions.sh
@@ -436,47 +436,6 @@ 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  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/functions/experimental.sh b/functions/experimental.sh
index 1aac078..4d56cfa 100644
--- a/functions/experimental.sh
+++ b/functions/experimental.sh
@@ -94,6 +94,47 @@ str_between()
fi
 }
 
+#
+# 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  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
+}
+
 #
 # Takes the first parameter as either a relative pathname or an integer
 # referring to a number of iterations. To be recognised as a pathname, the 
first

diff --git a/test-functions b/test-functions
index 68e73eb..34ff54a 100755
--- a/test-functions
+++ b/test-functions
@@ -793,7 +793,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
+#test_substr || rc=1
 
 cleanup_tmpdir
 



[gentoo-commits] proj/gentoo-functions:master commit in: functions/

2024-07-06 Thread Sam James
commit: fd79ab30122474ab5207ea001d92ffac677b5380
Author: Kerin Millar  plushkava  net>
AuthorDate: Thu Jun 27 16:06:38 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Fri Jun 28 17:39:01 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=fd79ab30

Add an experimental module for staging new ideas

The idea is to be able to write new functions without having to
initially commit to their being in the core library or, indeed, any of
the other modules. Experimental functions may be promoted or simply
dropped without warning if it is decided that they are insufficiently
useful to merit incorporation.

This initial commit defines the is_interactive() and prepend_ts()
functions.

Signed-off-by: Kerin Millar  plushkava.net>

 functions/experimental.sh | 53 +++
 1 file changed, 53 insertions(+)

diff --git a/functions/experimental.sh b/functions/experimental.sh
new file mode 100644
index 000..f577fa7
--- /dev/null
+++ b/functions/experimental.sh
@@ -0,0 +1,53 @@
+# Copyright 2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+# shellcheck shell=sh disable=3043
+
+# This file contains functions considered experimental in nature. Any functions
+# defined here may eventually be promoted to the core library or to a distinct
+# module. They may also be dropped without warning, either because they were
+# not considered as being sufficiently within the scope of gentoo-functions as
+# a project or because they were deemed to be insufficiently useful. As such, 
it
+# serves as a staging ground for new ideas. Note that GENFUN_API_LEVEL must
+# never be incremented on account of any changes made to this module.
+
+warn "sourcing the experimental module from gentoo-functions; no stability 
guarantee is provided"
+
+#
+# Returns 0 provided that two conditions hold. Firstly, that the standard input
+# is connected to a tty. Secondly, that the standard output has not been 
closed.
+# This technique is loosely based on the IO::Interactive::Tiny module from 
CPAN.
+#
+is_interactive()
+{
+   test -t 0 && { true 3>&1; } 2>/dev/null
+}
+
+#
+# Continuously reads lines from the standard input, prepending each with a
+# timestamp before printing to the standard output. Timestamps shall be in the
+# format of "%FT%T%z", per strftime(3). Output buffering shall not be employed.
+#
+prepend_ts()
+{
+   if hash gawk 2>/dev/null; then
+   prepend_ts()
+   {
+   gawk '{ print strftime("%FT%T%z"), $0; fflush(); }'
+   }
+   elif hash ts 2>/dev/null; then
+   prepend_ts()
+   {
+   ts '%FT%T%z'
+   }
+   elif bash -c '(( BASH_VERSINFO >= 4 ))' 2>/dev/null; then
+   prepend_ts()
+   {
+   bash -c 'while read -r; do printf "%(%FT%T%z)T %s\n" -1 
"${REPLY}"; done'
+   }
+   else
+   warn "prepend_ts: this function requires that either bash, gawk 
or moreutils be installed"
+   return 1
+   fi
+
+   prepend_ts
+}



[gentoo-commits] proj/gentoo-functions:master commit in: functions/, /

2024-06-24 Thread Sam James
commit: 2a58c0e462538b7fb2d12cd95157a9aaf2b7f7ff
Author: Kerin Millar  plushkava  net>
AuthorDate: Wed Jun 12 12:16:37 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Sun Jun 23 21:18:36 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2a58c0e4

Render gentoo-functions modular in nature

For many years, the implied purpose of gentoo-functions has been to
provided parallel implementations of utilities provided by OpenRC, along
with a handful of peripheral functions. It is probably also fair to say
that it has not seen much in the way of maintenance until comparatively
recently. As of the present day, the status quo is not ideal. For one
thing, the library has never been particularly useful beyond this
definition. It is my hope that some of the recently added functions will
be well received by those needing to write effective shell scripts in
Gentoo for a number of relevant tasks. Certainly, there remains ample
room for improvement in that regard.

For another thing, the implementation of gentoo-functions is presently
inflexible. For instance, it is impossible to source the functions from
an OpenRC runscript without overriding the OpenRC implementations. Nor
may one source the functions from an ebuild or eclass without overriding
the Portage implementations. Indeed, it is has become something of a
mess. Not only does gentoo-functions implement a number of functions
that shadow the OpenRC implementations but so does Portage, owing to the
existence of its "isolated-functions.sh" unit. What's more, the various
implementations are of varying quality and do not necessarily behave in
the same manner.

This commit aims to address some of these issues by rendering
gentoo-functions modular in nature. It establishes the premise of having
a core library, with collections of additional functions being
optionally declarable. As such, all of the functions that shadow OpenRC
have been relocated to a unit named "rc.sh". This first change
encompasses the following public functions:

- ebegin
- eend
- eerrorn
- eindent
- einfon
- eoutdent
- esyslog
- ewarnn
- ewend
- get_bootparam
- is_older_than
- veend
- vewend
- yesno

Similarly, all of the functions that exclusively shadow Portage have
been relocated to a unit named "portage.sh". This second change
encompasses the following public functions:

- die
- edo
- eqatag
- eqawarn

The functions that remain in the "functions.sh" unit may now be
considered as core functions. To accommodate all of this, a new
GENFUN_MODULES variable is supported, whose behaviour is described
herewith.

If GENFUN_MODULES is found to be set at the time of "functions.sh" being
sourced, it shall be taken as a list of zero or more blank-separated
words. In turn, these words shall be taken as the basenames of
potentially available modules - not including the .sh suffix.
Presently, the only supported module names are "rc" and "portage".
Should either or both of these names be present, their respective units
shall be automatically sourced. If neither are present, no additional
units shall be sourced. Consequently, it becomes possible for a consumer
of gentoo-functions to request that only the core functions be declared
by writing:

  GENFUN_MODULES= . /lib/gentoo/functions.sh

If, on the other hand, GENFUN_MODULES is found not to be set then
heuristics shall be employed to determine which of the additional units
should be sourced. The intent of these heuristics is twofold. Firstly,
to maintain an adequate degree of backward-compatibility and, secondly,
to act as is appropriate based on the characteristics of the operating
environment. The exact behaviour of these heuristics is as follows.

If the present shell is neither executing a runscript nor a subprocess
of one, the ensuing behaviour shall be as if "rc" had initially been
among the names defined by the GENFUN_MODULES variable.

If the present shell is not a subprocess of portage, the ensuing
behaviour shall be as if "portage" had initially been among the names
defined by the GENFUN_MODULES variable.

Signed-off-by: Kerin Millar  plushkava.net>

 functions.sh | 633 ++-
 functions/portage.sh | 136 +++
 functions/rc.sh  | 462 +
 meson.build  |   5 +
 test-functions   |   6 +-
 5 files changed, 683 insertions(+), 559 deletions(-)

diff --git a/functions.sh b/functions.sh
index 166f184..d80a49c 100644
--- a/functions.sh
+++ b/functions.sh
@@ -1,4 +1,4 @@
-# Copyright 1999-2023 Gentoo Authors
+# Copyright 1999-2024 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 # shellcheck shell=sh disable=2209,3043
 
@@ -15,20 +15,16 @@
 # 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_

[gentoo-commits] proj/gentoo-functions:master commit in: functions/

2024-06-24 Thread Sam James
commit: 94446b64cc9f9a912184a85fa43070fecbc4ce0f
Author: Kerin Millar  plushkava  net>
AuthorDate: Wed Jun 12 12:51:55 2024 +
Commit: Sam James  gentoo  org>
CommitDate: Sun Jun 23 21:19:15 2024 +
URL:
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=94446b64

Deprecate RC_NOCOLOR and the equivalent use of the positional parameters

Firstly, the "." builtin is not specified to support the passing of
arguments; such is a bashism. It is rather presumptuous to act as if the
present contents of the positional parameters are for the benefit of
gentoo-functions at the time of its initialisation.

Secondly, there exists a de-facto standard for suppressing colored
output, which is to define NO_COLOR as a non-empty string, per
https://no-color.org.

Signed-off-by: Kerin Millar  plushkava.net>

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

diff --git a/functions/rc.sh b/functions/rc.sh
index 519d847..2f2dc52 100644
--- a/functions/rc.sh
+++ b/functions/rc.sh
@@ -422,13 +422,16 @@ _is_visible()
 
#--#
 
 # Determine whether the use of color is to be wilfully avoided.
-if [ -n "${NO_COLOR}" ]; then
+if [ "${RC_NOCOLOR+set}" ]; then
+   warn "the RC_NOCOLOR variable is deprecated by gentoo-functions; please 
set NO_COLOR instead"
+elif [ -n "${NO_COLOR}" ]; then
# See https://no-color.org/.
RC_NOCOLOR=yes
 else
for _; do
case $_ in
--nocolor|--nocolour|-C)
+   warn "the $_ option is deprecated by 
gentoo-functions; please set NO_COLOR=1 instead"
RC_NOCOLOR=yes
break
esac