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
 }

Reply via email to