Hallo Thorsten,

I do not know whether you have followed the thread on the standard
list, but Robert Elz has written a shell function which allows
round-tripping quoted strings from and to the positional parameter
stack, Stephane did so in awk(1), effectively we are talking about

  stephane_quote() {
    LC_ALL=C awk -v q="'" -v b='\\' '
      function quote(s){
        gsub(q, q b q q, s)
        return q s q
      }
      BEGIN{
        sep = ""
        for(i = 1; i < ARGC; i++){
          printf "%s", sep quote(ARGV[i])
          sep = " "
        }
        if(sep)
          print ""
      }' "$@"
  }

mksh fails to roundtrip the string

  set -- x 'a \ b' "foo'" "\\'b\\a\\r\\" A
  echo "$#: <${1}><${2}><${3}><$4><$5>"
  saved_parameters=$(robert_quote "$@")
  eval "set -- $saved_parameters"
  echo "$#: <${1}><${2}><${3}><$4><$5>"

i think, the \r is expanded, the output is

  \><A><a \ b><foo'><\'b

instead of

  5: <x><a \ b><foo'><\'b\a\r\><A>

Interested in the attached addition to check.t?

--steffen
|
|Ralph says i must not use signatures which spread the light!
diff --git a/check.t b/check.t
index e0c8d5e..7cc08d6 100644
--- a/check.t
+++ b/check.t
@@ -6835,6 +6835,61 @@ expected-stdout:
 	3 10 .
 	4 -2147483646 .
 ---
+name: quote-roundtrip
+description:
+	Check roundtrip quoting behaviour via Robert Elz quote()
+stdin:
+	robert__quote() {
+	        case "$1" in
+	        *\'*)   ;;
+	        *)      printf "'%s'" "$1"; return 0;;
+	        esac
+	        __A__="$1" __S__= __E__=
+	        while case "$__A__" in
+	                \'*)    __A__=${__A__#?}; __S__="${__S__}\\\\'";;
+	                *\')    __A__=${__A__%?}; __E__="${__E__}\\\\'";;
+	                '')     printf "${__S__}${__E__}"; return 0;;
+	                *)      false;;
+	                esac
+	        do
+	                continue
+	        done
+	        _save_IFS="${IFS}"; ${IFS+":"} unset _save_IFS
+	        _save_OPTS="$(set +o)"
+	        IFS=\'
+	        set -f
+	        set -- $__A__
+	        _result_="${1}"
+	        shift
+	        for __A__
+	        do
+	                _result_="${_result_}'\\''${__A__}"
+	        done
+	        printf "${__S__}'%s'${__E__}" "${_result_}"
+	        # now clean up
+	        IFS="${_save_IFS}"; ${_save_IFS+":"} unset IFS
+	        eval "${_save_OPTS}"
+	        unset _result_ _save_IFS _save_OPTS __A__ __E__ __S__
+	        return 0;
+	}
+	robert_quote() {
+	        j=
+	        for i
+	        do
+	                [ -n "$j" ] && printf ' '
+	                j=' '
+	                robert__quote "$i"
+	        done
+	}
+	set -- x 'a \ b' "foo'" "\\'b\\a\\r\\" A
+	echo "$#: <${1}><${2}><${3}><$4><$5>"
+	saved_parameters=$(robert_quote "$@")
+	eval "set -- $saved_parameters"
+	echo "$#: <${1}><${2}><${3}><$4><$5>"
+expected-stdout:
+	5: <x><a \ b><foo'><\'b\a\r\><A>
+	5: <x><a \ b><foo'><\'b\a\r\><A>
+---
 name: readonly-0
 description:
 	Ensure readonly is honoured for assignments and unset

Reply via email to