| 1 | # Cross-cutting test of serialization formats. That is, what QSTR should fix. |
| 2 | # |
| 3 | # TODO: Also see spec/xtrace for another use case. |
| 4 | |
| 5 | #### printf %q newline |
| 6 | case $SH in (ash) return ;; esac # yash and ash don't implement this |
| 7 | |
| 8 | newline=$'one\ntwo' |
| 9 | printf '%q\n' "$newline" |
| 10 | |
| 11 | quoted="$(printf '%q\n' "$newline")" |
| 12 | restored=$(eval "echo $quoted") |
| 13 | test "$newline" = "$restored" && echo roundtrip-ok |
| 14 | |
| 15 | ## STDOUT: |
| 16 | $'one\ntwo' |
| 17 | roundtrip-ok |
| 18 | ## END |
| 19 | ## OK mksh STDOUT: |
| 20 | 'one'$'\n''two' |
| 21 | roundtrip-ok |
| 22 | ## END |
| 23 | ## OK zsh STDOUT: |
| 24 | one$'\n'two |
| 25 | roundtrip-ok |
| 26 | ## END |
| 27 | ## N-I ash stdout-json: "" |
| 28 | |
| 29 | #### printf %q spaces |
| 30 | case $SH in (ash) return ;; esac # yash and ash don't implement this |
| 31 | |
| 32 | # bash does a weird thing and uses \ |
| 33 | |
| 34 | spaces='one two' |
| 35 | printf '%q\n' "$spaces" |
| 36 | |
| 37 | ## STDOUT: |
| 38 | 'one two' |
| 39 | ## END |
| 40 | ## OK bash/zsh STDOUT: |
| 41 | one\ two |
| 42 | ## END |
| 43 | ## N-I ash stdout-json: "" |
| 44 | |
| 45 | #### printf %q quotes |
| 46 | case $SH in (ash) return ;; esac # yash and ash don't implement %q |
| 47 | |
| 48 | quotes=\'\" |
| 49 | printf '%q\n' "$quotes" |
| 50 | |
| 51 | quoted="$(printf '%q\n' "$quotes")" |
| 52 | restored=$(eval "echo $quoted") |
| 53 | test "$quotes" = "$restored" && echo roundtrip-ok |
| 54 | |
| 55 | ## STDOUT: |
| 56 | \'\" |
| 57 | roundtrip-ok |
| 58 | ## END |
| 59 | ## OK osh STDOUT: |
| 60 | $'\'"' |
| 61 | roundtrip-ok |
| 62 | ## END |
| 63 | ## BUG mksh STDOUT: |
| 64 | ''\''"' |
| 65 | roundtrip-ok |
| 66 | ## END |
| 67 | ## N-I ash stdout-json: "" |
| 68 | |
| 69 | #### printf %q unprintable |
| 70 | case $SH in (ash) return ;; esac # yash and ash don't implement this |
| 71 | |
| 72 | unprintable=$'\xff' |
| 73 | printf '%q\n' "$unprintable" |
| 74 | |
| 75 | # bash and zsh agree |
| 76 | ## STDOUT: |
| 77 | $'\377' |
| 78 | ## END |
| 79 | ## OK osh STDOUT: |
| 80 | $'\xff' |
| 81 | ## END |
| 82 | ## BUG mksh STDOUT: |
| 83 | ''$'\377' |
| 84 | ## END |
| 85 | ## N-I ash stdout-json: "" |
| 86 | |
| 87 | #### printf %q unicode |
| 88 | case $SH in (ash) return ;; esac # yash and ash don't implement this |
| 89 | |
| 90 | unicode=$'\u03bc' |
| 91 | unicode=$'\xce\xbc' # does the same thing |
| 92 | |
| 93 | printf '%q\n' "$unicode" |
| 94 | |
| 95 | # Oil issue: we have quotes. Isn't that OK? |
| 96 | ## STDOUT: |
| 97 | μ |
| 98 | ## END |
| 99 | ## OK osh STDOUT: |
| 100 | 'μ' |
| 101 | ## END |
| 102 | ## N-I ash stdout-json: "" |
| 103 | |
| 104 | #### printf %q invalid unicode |
| 105 | case $SH in (ash) return ;; esac |
| 106 | |
| 107 | # Hm bash/mksh/zsh understand these. They are doing decoding and error |
| 108 | # recovery! inspecting the bash source seems to confirm this. |
| 109 | unicode=$'\xce' |
| 110 | printf '%q\n' "$unicode" |
| 111 | |
| 112 | unicode=$'\xce\xce\xbc' |
| 113 | printf '%q\n' "$unicode" |
| 114 | |
| 115 | unicode=$'\xce\xbc\xce' |
| 116 | printf '%q\n' "$unicode" |
| 117 | |
| 118 | case $SH in (mksh) return ;; esac # it prints unprintable chars here! |
| 119 | |
| 120 | unicode=$'\xcea' |
| 121 | printf '%q\n' "$unicode" |
| 122 | unicode=$'a\xce' |
| 123 | printf '%q\n' "$unicode" |
| 124 | ## STDOUT: |
| 125 | $'\xce' |
| 126 | $'\xceμ' |
| 127 | $'μ\xce' |
| 128 | $'\xcea' |
| 129 | $'a\xce' |
| 130 | ## END |
| 131 | ## OK bash STDOUT: |
| 132 | $'\316' |
| 133 | $'\316μ' |
| 134 | $'μ\316' |
| 135 | $'\316a' |
| 136 | $'a\316' |
| 137 | ## END |
| 138 | ## BUG mksh STDOUT: |
| 139 | ''$'\316' |
| 140 | ''$'\316''μ' |
| 141 | 'μ'$'\316' |
| 142 | ## END |
| 143 | ## OK zsh STDOUT: |
| 144 | $'\316' |
| 145 | $'\316'μ |
| 146 | μ$'\316' |
| 147 | $'\316'a |
| 148 | a$'\316' |
| 149 | ## END |
| 150 | ## N-I ash stdout-json: "" |
| 151 | |
| 152 | #### set |
| 153 | case $SH in (zsh) return ;; esac # zsh doesn't make much sense |
| 154 | |
| 155 | zz=$'one\ntwo' |
| 156 | |
| 157 | set | grep zz |
| 158 | ## STDOUT: |
| 159 | zz=$'one\ntwo' |
| 160 | ## END |
| 161 | ## OK ash stdout-json: "zz='one\n" |
| 162 | ## BUG zsh stdout-json: "" |
| 163 | |
| 164 | |
| 165 | #### declare |
| 166 | case $SH in (ash|zsh) return ;; esac # zsh doesn't make much sense |
| 167 | |
| 168 | zz=$'one\ntwo' |
| 169 | |
| 170 | typeset | grep zz |
| 171 | typeset -p zz |
| 172 | |
| 173 | ## STDOUT: |
| 174 | zz=$'one\ntwo' |
| 175 | declare -- zz=$'one\ntwo' |
| 176 | ## END |
| 177 | |
| 178 | # bash uses a different format for 'declare' and 'declare -p'! |
| 179 | ## OK bash STDOUT: |
| 180 | zz=$'one\ntwo' |
| 181 | declare -- zz="one |
| 182 | two" |
| 183 | ## END |
| 184 | ## OK mksh STDOUT: |
| 185 | typeset zz |
| 186 | typeset zz=$'one\ntwo' |
| 187 | ## BUG zsh stdout-json: "" |
| 188 | ## N-I ash stdout-json: "" |
| 189 | |
| 190 | #### ${var@Q} |
| 191 | case $SH in (zsh|ash) exit ;; esac |
| 192 | |
| 193 | zz=$'one\ntwo \u03bc' |
| 194 | |
| 195 | # wierdly, quoted and unquoted aren't different |
| 196 | echo ${zz@Q} |
| 197 | echo "${zz@Q}" |
| 198 | ## STDOUT: |
| 199 | $'one\ntwo μ' |
| 200 | $'one\ntwo μ' |
| 201 | ## END |
| 202 | ## OK mksh STDOUT: |
| 203 | $'one |
| 204 | two μ' |
| 205 | $'one |
| 206 | two μ' |
| 207 | ## END |
| 208 | ## N-I ash/zsh stdout-json: "" |
| 209 | |
| 210 | #### xtrace |
| 211 | zz=$'one\ntwo' |
| 212 | set -x |
| 213 | echo "$zz" |
| 214 | ## STDOUT: |
| 215 | one |
| 216 | two |
| 217 | ## END |
| 218 | ## STDERR: |
| 219 | + echo $'one\ntwo' |
| 220 | ## END |
| 221 | ## OK bash/ash STDERR: |
| 222 | + echo 'one |
| 223 | two' |
| 224 | ## END |
| 225 | ## OK zsh STDERR: |
| 226 | +zsh:3> echo 'one |
| 227 | two' |
| 228 | ## END |
| 229 |