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 }