[PATCH 1/9] esplit.eclass: add new eclass

Sam James <[email protected]> Thu, 9 Jul 2026 22:22:10 +0100
Newsgroups gmane.linux.gentoo.devel
Message-ID <f249a960529bcc6317932952adc1fb970256b408.1783632118.git.sam@gentoo.org>
Quoting the DESCRIPTION:
> This eclass provides the 'esplit' command as a substitute for the
> 'IFS=... while read <<<${var}' idiom which may invoke the use of a temporary
> file, which is undesirable in global scope.
>
> The provided function is simple but its interface makes it easy to use
> correctly and not fumble the restoration of IFS.

The need for such a helper has become clear with recent Portage improvements
to sandbox the 'depend' phase, as any global scope reads or writes are
now prohibited.

The 'esplit' function itself is from Kerin, I've just written the eclass
scaffold.

Bug: https://bugs.gentoo.org/978857
Bug: https://bugs.gentoo.org/978938
Bug: https://bugs.gentoo.org/978939
Bug: https://bugs.gentoo.org/978940
Bug: https://bugs.gentoo.org/978941
Co-authored-by: Kerin Millar <[email protected]>
Signed-off-by: Sam James <[email protected]>
---
 eclass/esplit.eclass | 70 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 eclass/esplit.eclass

diff --git a/eclass/esplit.eclass b/eclass/esplit.eclass
new file mode 100644
index 0000000000000..50028cddd194a
--- /dev/null
+++ b/eclass/esplit.eclass
@@ -0,0 +1,70 @@
+# Copyright 2026 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: esplit.eclass
+# @MAINTAINER:
+# QA Team <[email protected]>
+# @AUTHOR:
+# Sam James <[email protected]>
+# Kerin Millar <[email protected]>
+# @SUPPORTED_EAPIS: 8 9
+# @BLURB: Convenience function to split input based on IFS.
+# @DESCRIPTION:
+# This eclass provides the 'esplit' command as a substitute for the
+# 'IFS=... while read <<<${var}' idiom which may invoke the use of a temporary
+# file, which is undesirable in global scope.
+#
+# The provided function is simple but its interface makes it easy to use
+# correctly and not fumble the restoration of IFS.
+#
+# @EXAMPLE:
+#
+# @CODE
+# EAPI=9
+#
+#
+# LIST_OF_SITES=(
+#         a:1,2,3,4
+#         b:4,5,6,7
+# )
+#
+# process_list() {
+#         local site ids some_array
+#         for entry in "${LIST_OF_SITES[@]}" ; do
+#                 site=${entry%%:*}
+#                 ids=${entry#*:}
+#
+#                 mapfile -td '' some_array < <(IFS=, esplit "${ids}")
+#
+#                 local num
+#                 for num in "${some_array[@]}" ; do
+#                         printf "site %s has an ID: %d\n" "${site}" "${num}"
+#                         SRC_URI+= "${site}?id=${num}"
+#                 done
+#         done
+# }
+#
+# process_list
+case ${EAPI} in
+	8|9) ;;
+	*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+if [[ -z ${_ESPLIT_ECLASS} ]] ; then
+_ESPLIT_ECLASS=1
+
+# @FUNCTION: esplit
+# @USAGE: IFS=... <command> <string-to-be-split>
+# @DESCRIPTION:
+# Split the first parameter in accordance with IFS, printing the resulting words
+# to standard output as NUL-terminated records.
+#
+# Suggested use is as follows:
+#  mapfile -d '' some_array < <(IFS=... esplit "${str}")
+esplit() {
+	local -
+	shopt -o -s noglob
+	printf '%s\0' $1
+}
+
+fi
-- 
2.55.0