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

Reply via email to