changeset 635:2d0201f54870

farray.sh: Also provide a strict posixly correct quoting alternative. Because $'...' is not a POSIX standard supply now the possibility to encode using just single quotes (without dollar): this is posixly correct. More quoting tests.
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 26 Sep 2024 11:58:44 +0200
parents 618f8e72e5e6
children 7800bac1fe7e
files share/local-bsdtools/farray.sh tests/farray-array.t
diffstat 2 files changed, 92 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/share/local-bsdtools/farray.sh	Wed Sep 25 21:04:19 2024 +0200
+++ b/share/local-bsdtools/farray.sh	Thu Sep 26 11:58:44 2024 +0200
@@ -219,6 +219,8 @@
 #:   The properly quoted string including surrounding "Dollar-Single-Quotes"
 #:   (e.g. $'...').
 #:
+#: Using "Dollar-Single-Quotes" is not strictly posixly correct. But
+#: FreeBSD's :command:`/bin/sh` understands them.
 #:
 #: From FreeBSD's :manpage:`sh(1)`:
 #:
@@ -282,6 +284,75 @@
 
 
 #:
+#: Quote the given input using just POSIX correct "Single-Quotes" to be safely
+#: used in evals.
+#:
+#: Args:
+#:   $1: The value to be quoted.
+#:
+#: Output (stdout):
+#:   The properly quoted string including surrounding "Single-Quotes"
+#:   (e.g. '...').
+#:
+#:
+#: From FreeBSD's :manpage:`sh(1)`:
+#:
+#:   Single Quotes
+#:
+#:     Enclosing characters in single quotes preserves the literal
+#:     meaning of all the characters (except single quotes, making it
+#:     impossible to put single-quotes in a single-quoted string).
+#:
+_farr_quote_for_eval_sq() {
+    printf "'%s'" "$(_farr_inner_quote_for_sq "${1}")"
+}
+
+
+#:
+#: Helper to quote for "Single-Quotes".
+#:
+#: This function handles just the quoting mechanics. It does not surround
+#: the result with any other string decoration.
+#: See also `_farr_quote_for_eval_dsq`.
+#:
+_farr_inner_quote_for_sq() {
+    printf "%s" "${1}" \
+        | LC_ALL=C /usr/bin/sed -e $'s/\'/\'\\\\\\\'\'/g'
+    #                             escape a single quote
+    #                             (here double-escaped: for $'...' AND sed
+    # '    # make Emacs happy for correct syntax highlighting
+}
+
+
+#:
+#: Quote the given input string for eval and produce a strictly posixly correct
+#: encoding.
+#:
+#: It does not use FreeBSD's ``$'...'`` shell feature.
+#:
+#: If the argument contains a ``'`` character then a proper "Single-Quotes"
+#: combination is used.
+#:
+#: Args:
+#:   $1: The value to be quoted.
+#:
+#: Output (stdout):
+#:   The properly quoted string including surrounding quotes.
+#:
+#:
+_farr_quote_for_eval_strict() {
+    case "${1}" in
+        *\'*)
+            _farr_quote_for_eval_sq "${1}"
+            ;;
+        *)
+            printf "'%s'" "${1}"
+            ;;
+    esac
+}
+
+
+#:
 #: Create a new array.
 #:
 #: It is assumed that the array does not exist already.
--- a/tests/farray-array.t	Wed Sep 25 21:04:19 2024 +0200
+++ b/tests/farray-array.t	Thu Sep 26 11:58:44 2024 +0200
@@ -906,15 +906,30 @@
   $ check_no_array_artifacts
 
 
-Eval
-====
+Eval / Quoting
+==============
 
-  $ _var=$'" 678" \\\'910 '
-  $ eval _evar="\$(_farr_quote_for_eval \"\${_var}\")"
+# Use Dollar-Single-Quotes
+  $ _var1=$'" 678" \\\'910 '
+# Use just Single-Quotes
+  $ _var2='" 678" \'\''910 '
+# Use a Double-Quotes to insert a single quote
+  $ _var3='" 678" \'"'"'910 '
+  $ test "${_var1}" = "${_var2}"
+  $ test "${_var1}" = "${_var3}"
+  $ eval _evar="\$(_farr_quote_for_eval \"\${_var1}\")"
   $ eval printf '%s' "${_evar}"
   " 678" \'910  (no-eol)
-  $ _var=$'" 678" \\\'910\t\''
-  $ eval _evar="\$(_farr_quote_for_eval \"\${_var}\")"
+  $ _var1=$'" 678" \\\'910\t\''
+  $ _var2='" 678" \'\''910	'\'''
+  $ _var3='" 678" \'"'"'910	'"'"''
+  $ test "${_var1}" = "${_var2}"
+  $ test "${_var1}" = "${_var3}"
+  $ eval _evar="\$(_farr_quote_for_eval \"\${_var1}\")"
+  $ eval printf '%s' "${_evar}"
+  " 678" \'910	' (no-eol)
+  $ _var1=$'" 678" \\\'910\t\''
+  $ eval _evar="\$(_farr_quote_for_eval_strict \"\${_var1}\")"
   $ eval printf '%s' "${_evar}"
   " 678" \'910	' (no-eol)