disambiguate $((…)) vs. $((…)…) in “typeset -f” output

This commit is contained in:
tg
2017-04-11 12:34:04 +00:00
parent ca6bd1f99b
commit 15e4861f71
2 changed files with 40 additions and 38 deletions

74
check.t
View File

@@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.773 2017/04/08 01:07:12 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.774 2017/04/11 12:34:02 tg Exp $
# -*- mode: sh -*- # -*- mode: sh -*-
#- #-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@@ -11097,7 +11097,7 @@ expected-stdout:
function comsub_TCOM { x=$( function comsub_TCOM { x=$(
vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4" vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4"
); } ); }
function comsub_TCOM { function comsub_TCOM {
x=$(vara=1 varb="2 3" \cmd arg1 $arg2 "$arg3 4" ) x=$(vara=1 varb="2 3" \cmd arg1 $arg2 "$arg3 4" )
} }
function reread_TCOM { x=$(( function reread_TCOM { x=$((
@@ -11110,13 +11110,13 @@ expected-stdout:
(echo $foo | tr -dc 0-9; echo) (echo $foo | tr -dc 0-9; echo)
} }
inline_TPAREN_TPIPE_TLIST() { inline_TPAREN_TPIPE_TLIST() {
( \echo $foo | \tr -dc 0-9 ( \echo $foo | \tr -dc 0-9
\echo ) \echo )
} }
function comsub_TPAREN_TPIPE_TLIST { x=$( function comsub_TPAREN_TPIPE_TLIST { x=$(
(echo $foo | tr -dc 0-9; echo) (echo $foo | tr -dc 0-9; echo)
); } ); }
function comsub_TPAREN_TPIPE_TLIST { function comsub_TPAREN_TPIPE_TLIST {
x=$( ( \echo $foo | \tr -dc 0-9 ; \echo ) ) x=$( ( \echo $foo | \tr -dc 0-9 ; \echo ) )
} }
function reread_TPAREN_TPIPE_TLIST { x=$(( function reread_TPAREN_TPIPE_TLIST { x=$((
@@ -11134,7 +11134,7 @@ expected-stdout:
function comsub_TAND_TOR { x=$( function comsub_TAND_TOR { x=$(
cmd && echo ja || echo nein cmd && echo ja || echo nein
); } ); }
function comsub_TAND_TOR { function comsub_TAND_TOR {
x=$(\cmd && \echo ja || \echo nein ) x=$(\cmd && \echo ja || \echo nein )
} }
function reread_TAND_TOR { x=$(( function reread_TAND_TOR { x=$((
@@ -11156,7 +11156,7 @@ expected-stdout:
function comsub_TSELECT { x=$( function comsub_TSELECT { x=$(
select file in *; do echo "<$file>" ; break ; done select file in *; do echo "<$file>" ; break ; done
); } ); }
function comsub_TSELECT { function comsub_TSELECT {
x=$(select file in * ; do \echo "<$file>" ; \break ; done ) x=$(select file in * ; do \echo "<$file>" ; \break ; done )
} }
function reread_TSELECT { x=$(( function reread_TSELECT { x=$((
@@ -11177,7 +11177,7 @@ expected-stdout:
function comsub_TFOR_TTIME { x=$( function comsub_TFOR_TTIME { x=$(
time for i in {1,2,3} ; do echo $i ; done time for i in {1,2,3} ; do echo $i ; done
); } ); }
function comsub_TFOR_TTIME { function comsub_TFOR_TTIME {
x=$(time for i in {1,2,3} ; do \echo $i ; done ) x=$(time for i in {1,2,3} ; do \echo $i ; done )
} }
function reread_TFOR_TTIME { x=$(( function reread_TFOR_TTIME { x=$((
@@ -11205,7 +11205,7 @@ expected-stdout:
function comsub_TCASE { x=$( function comsub_TCASE { x=$(
case $foo in 1) echo eins;& 2) echo zwei ;| *) echo kann net bis drei zählen;; esac case $foo in 1) echo eins;& 2) echo zwei ;| *) echo kann net bis drei zählen;; esac
); } ); }
function comsub_TCASE { function comsub_TCASE {
x=$(case $foo in (1) \echo eins ;& (2) \echo zwei ;| (*) \echo kann net bis drei zählen ;; esac ) x=$(case $foo in (1) \echo eins ;& (2) \echo zwei ;| (*) \echo kann net bis drei zählen ;; esac )
} }
function reread_TCASE { x=$(( function reread_TCASE { x=$((
@@ -11231,7 +11231,7 @@ expected-stdout:
function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$( function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$(
if ! [[ 1 = 1 ]] ; then echo eins; elif [[ 1 = 2 ]]; then echo zwei ;else echo drei; fi if ! [[ 1 = 1 ]] ; then echo eins; elif [[ 1 = 2 ]]; then echo zwei ;else echo drei; fi
); } ); }
function comsub_TIF_TBANG_TDBRACKET_TELIF { function comsub_TIF_TBANG_TDBRACKET_TELIF {
x=$(if ! [[ 1 = 1 ]] ; then \echo eins ; elif [[ 1 = 2 ]] ; then \echo zwei ; else \echo drei ; fi ) x=$(if ! [[ 1 = 1 ]] ; then \echo eins ; elif [[ 1 = 2 ]] ; then \echo zwei ; else \echo drei ; fi )
} }
function reread_TIF_TBANG_TDBRACKET_TELIF { x=$(( function reread_TIF_TBANG_TDBRACKET_TELIF { x=$((
@@ -11256,7 +11256,7 @@ expected-stdout:
function comsub_TWHILE { x=$( function comsub_TWHILE { x=$(
i=1; while (( i < 10 )); do echo $i; let ++i; done i=1; while (( i < 10 )); do echo $i; let ++i; done
); } ); }
function comsub_TWHILE { function comsub_TWHILE {
x=$(i=1 ; while { \\builtin let " i < 10 " ; } ; do \echo $i ; \let ++i ; done ) x=$(i=1 ; while { \\builtin let " i < 10 " ; } ; do \echo $i ; \let ++i ; done )
} }
function reread_TWHILE { x=$(( function reread_TWHILE { x=$((
@@ -11280,7 +11280,7 @@ expected-stdout:
function comsub_TUNTIL { x=$( function comsub_TUNTIL { x=$(
i=10; until (( !--i )) ; do echo $i; done i=10; until (( !--i )) ; do echo $i; done
); } ); }
function comsub_TUNTIL { function comsub_TUNTIL {
x=$(i=10 ; until { \\builtin let " !--i " ; } ; do \echo $i ; done ) x=$(i=10 ; until { \\builtin let " !--i " ; } ; do \echo $i ; done )
} }
function reread_TUNTIL { x=$(( function reread_TUNTIL { x=$((
@@ -11299,7 +11299,7 @@ expected-stdout:
function comsub_TCOPROC { x=$( function comsub_TCOPROC { x=$(
cat * |& ls cat * |& ls
); } ); }
function comsub_TCOPROC { function comsub_TCOPROC {
x=$(\cat * |& \ls ) x=$(\cat * |& \ls )
} }
function reread_TCOPROC { x=$(( function reread_TCOPROC { x=$((
@@ -11326,7 +11326,7 @@ expected-stdout:
bourne () { logger * & } bourne () { logger * & }
); } ); }
function comsub_TFUNCT_TBRACE_TASYNC { function comsub_TFUNCT_TBRACE_TASYNC {
x=$(function korn { \echo eins ; \echo zwei ; } ; bourne() { \logger * & } ) x=$(function korn { \echo eins ; \echo zwei ; } ; bourne() { \logger * & } )
} }
function reread_TFUNCT_TBRACE_TASYNC { x=$(( function reread_TFUNCT_TBRACE_TASYNC { x=$((
function korn { echo eins; echo zwei ; } function korn { echo eins; echo zwei ; }
@@ -11344,7 +11344,7 @@ expected-stdout:
function comsub_IOREAD_IOCAT { x=$( function comsub_IOREAD_IOCAT { x=$(
tr x u 0<foo >>bar tr x u 0<foo >>bar
); } ); }
function comsub_IOREAD_IOCAT { function comsub_IOREAD_IOCAT {
x=$(\tr x u <foo >>bar ) x=$(\tr x u <foo >>bar )
} }
function reread_IOREAD_IOCAT { x=$(( function reread_IOREAD_IOCAT { x=$((
@@ -11374,7 +11374,7 @@ expected-stdout:
foo foo
EOFN EOFN
) )
} }
function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$(( function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$((
cat >|bar <<'EOFN' cat >|bar <<'EOFN'
foo foo
@@ -11407,7 +11407,7 @@ expected-stdout:
foo foo
EOFI EOFI
) )
} }
function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$(( function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$((
cat 1>bar <<-EOFI cat 1>bar <<-EOFI
foo foo
@@ -11428,7 +11428,7 @@ expected-stdout:
function comsub_IORDWR_IODUP { x=$( function comsub_IORDWR_IODUP { x=$(
sh 1<>/dev/console 0<&1 2>&1 sh 1<>/dev/console 0<&1 2>&1
); } ); }
function comsub_IORDWR_IODUP { function comsub_IORDWR_IODUP {
x=$(\sh 1<>/dev/console <&1 2>&1 ) x=$(\sh 1<>/dev/console <&1 2>&1 )
} }
function reread_IORDWR_IODUP { x=$(( function reread_IORDWR_IODUP { x=$((
@@ -11446,7 +11446,7 @@ expected-stdout:
function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$( function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$(
echo $(true) $((1+ 2)) ${ :;} ${| REPLY=x;} echo $(true) $((1+ 2)) ${ :;} ${| REPLY=x;}
); } ); }
function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB { function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB {
x=$(\echo $(\true ) $((1+ 2)) ${ : ;} ${|REPLY=x ;} ) x=$(\echo $(\true ) $((1+ 2)) ${ : ;} ${|REPLY=x ;} )
} }
function reread_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$(( function reread_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$((
@@ -11472,7 +11472,7 @@ expected-stdout:
); } ); }
function comsub_QCHAR_OQUOTE_CQUOTE { function comsub_QCHAR_OQUOTE_CQUOTE {
x=$(\echo fo\ob\"a\`r\'b\$az ; \echo "fo\ob\"a\`r\'b\$az" ; \echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" ) x=$(\echo fo\ob\"a\`r\'b\$az ; \echo "fo\ob\"a\`r\'b\$az" ; \echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" )
} }
function reread_QCHAR_OQUOTE_CQUOTE { x=$(( function reread_QCHAR_OQUOTE_CQUOTE { x=$((
echo fo\ob\"a\`r\'b\$az echo fo\ob\"a\`r\'b\$az
echo "fo\ob\"a\`r\'b\$az" echo "fo\ob\"a\`r\'b\$az"
@@ -11490,7 +11490,7 @@ expected-stdout:
function comsub_OSUBST_CSUBST_OPAT_SPAT_CPAT { x=$( function comsub_OSUBST_CSUBST_OPAT_SPAT_CPAT { x=$(
[[ ${foo#bl\(u\)b} = @(bar|baz) ]] [[ ${foo#bl\(u\)b} = @(bar|baz) ]]
); } ); }
function comsub_OSUBST_CSUBST_OPAT_SPAT_CPAT { function comsub_OSUBST_CSUBST_OPAT_SPAT_CPAT {
x=$([[ ${foo#bl\(u\)b} = @(bar|baz) ]] ) x=$([[ ${foo#bl\(u\)b} = @(bar|baz) ]] )
} }
function reread_OSUBST_CSUBST_OPAT_SPAT_CPAT { x=$(( function reread_OSUBST_CSUBST_OPAT_SPAT_CPAT { x=$((
@@ -11521,7 +11521,7 @@ expected-stdout:
note there must be no space between EOFN and ) note there must be no space between EOFN and )
EOFN EOFN
) ; \echo $x ) ) ; \echo $x )
} }
function reread_heredoc_closed { x=$(( function reread_heredoc_closed { x=$((
x=$(cat <<EOFN x=$(cat <<EOFN
note there must be no space between EOFN and ) note there must be no space between EOFN and )
@@ -11555,7 +11555,7 @@ expected-stdout:
note the space between EOFN and ) is actually part of the here document marker note the space between EOFN and ) is actually part of the here document marker
EOFN EOFN
) ; \echo $x ) ) ; \echo $x )
} }
function reread_heredoc_space { x=$(( function reread_heredoc_space { x=$((
x=$(cat <<EOFN\ x=$(cat <<EOFN\
note the space between EOFN and ) is actually part of the here document marker note the space between EOFN and ) is actually part of the here document marker
@@ -11637,7 +11637,7 @@ expected-stdout:
. .
wq wq
EOF)" = @(?) ]] && rm -f /etc/motd EOF)" = @(?) ]] && rm -f /etc/motd
if [[ ! -s /etc/motd ]]; then if [[ ! -s /etc/motd ]]; then
install -c -o root -g wheel -m 664 /dev/null /etc/motd install -c -o root -g wheel -m 664 /dev/null /etc/motd
print -- "$x\n" >/etc/motd print -- "$x\n" >/etc/motd
@@ -11674,7 +11674,7 @@ expected-stdout:
); } ); }
function comsub_wdarrassign { function comsub_wdarrassign {
x=$(case x in (x) a+=b ; \\builtin set -A c+ -- d e ;; esac ) x=$(case x in (x) a+=b ; \\builtin set -A c+ -- d e ;; esac )
} }
function reread_wdarrassign { x=$(( function reread_wdarrassign { x=$((
case x in case x in
x) a+=b; c+=(d e) x) a+=b; c+=(d e)
@@ -11753,7 +11753,7 @@ expected-stdout:
function comsub_TCOM { x=$( function comsub_TCOM { x=$(
vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4" >&3 vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4" >&3
); } ); }
function comsub_TCOM { function comsub_TCOM {
x=$(vara=1 varb="2 3" \cmd arg1 $arg2 "$arg3 4" >&3 ) x=$(vara=1 varb="2 3" \cmd arg1 $arg2 "$arg3 4" >&3 )
} }
function reread_TCOM { x=$(( function reread_TCOM { x=$((
@@ -11766,13 +11766,13 @@ expected-stdout:
(echo $foo | tr -dc 0-9 >&3; echo >&3) >&3 (echo $foo | tr -dc 0-9 >&3; echo >&3) >&3
} }
inline_TPAREN_TPIPE_TLIST() { inline_TPAREN_TPIPE_TLIST() {
( \echo $foo | \tr -dc 0-9 >&3 ( \echo $foo | \tr -dc 0-9 >&3
\echo >&3 ) >&3 \echo >&3 ) >&3
} }
function comsub_TPAREN_TPIPE_TLIST { x=$( function comsub_TPAREN_TPIPE_TLIST { x=$(
(echo $foo | tr -dc 0-9 >&3; echo >&3) >&3 (echo $foo | tr -dc 0-9 >&3; echo >&3) >&3
); } ); }
function comsub_TPAREN_TPIPE_TLIST { function comsub_TPAREN_TPIPE_TLIST {
x=$( ( \echo $foo | \tr -dc 0-9 >&3 ; \echo >&3 ) >&3 ) x=$( ( \echo $foo | \tr -dc 0-9 >&3 ; \echo >&3 ) >&3 )
} }
function reread_TPAREN_TPIPE_TLIST { x=$(( function reread_TPAREN_TPIPE_TLIST { x=$((
@@ -11790,7 +11790,7 @@ expected-stdout:
function comsub_TAND_TOR { x=$( function comsub_TAND_TOR { x=$(
cmd >&3 && >&3 echo ja || echo >&3 nein cmd >&3 && >&3 echo ja || echo >&3 nein
); } ); }
function comsub_TAND_TOR { function comsub_TAND_TOR {
x=$(\cmd >&3 && \echo ja >&3 || \echo nein >&3 ) x=$(\cmd >&3 && \echo ja >&3 || \echo nein >&3 )
} }
function reread_TAND_TOR { x=$(( function reread_TAND_TOR { x=$((
@@ -11812,7 +11812,7 @@ expected-stdout:
function comsub_TSELECT { x=$( function comsub_TSELECT { x=$(
select file in *; do echo "<$file>" ; break >&3 ; done >&3 select file in *; do echo "<$file>" ; break >&3 ; done >&3
); } ); }
function comsub_TSELECT { function comsub_TSELECT {
x=$(select file in * ; do \echo "<$file>" ; \break >&3 ; done >&3 ) x=$(select file in * ; do \echo "<$file>" ; \break >&3 ; done >&3 )
} }
function reread_TSELECT { x=$(( function reread_TSELECT { x=$((
@@ -11833,7 +11833,7 @@ expected-stdout:
function comsub_TFOR_TTIME { x=$( function comsub_TFOR_TTIME { x=$(
for i in {1,2,3} ; do time >&3 echo $i ; done >&3 for i in {1,2,3} ; do time >&3 echo $i ; done >&3
); } ); }
function comsub_TFOR_TTIME { function comsub_TFOR_TTIME {
x=$(for i in {1,2,3} ; do time \echo $i >&3 ; done >&3 ) x=$(for i in {1,2,3} ; do time \echo $i >&3 ; done >&3 )
} }
function reread_TFOR_TTIME { x=$(( function reread_TFOR_TTIME { x=$((
@@ -11861,7 +11861,7 @@ expected-stdout:
function comsub_TCASE { x=$( function comsub_TCASE { x=$(
case $foo in 1) echo eins >&3;& 2) echo zwei >&3 ;| *) echo kann net bis drei zählen >&3;; esac >&3 case $foo in 1) echo eins >&3;& 2) echo zwei >&3 ;| *) echo kann net bis drei zählen >&3;; esac >&3
); } ); }
function comsub_TCASE { function comsub_TCASE {
x=$(case $foo in (1) \echo eins >&3 ;& (2) \echo zwei >&3 ;| (*) \echo kann net bis drei zählen >&3 ;; esac >&3 ) x=$(case $foo in (1) \echo eins >&3 ;& (2) \echo zwei >&3 ;| (*) \echo kann net bis drei zählen >&3 ;; esac >&3 )
} }
function reread_TCASE { x=$(( function reread_TCASE { x=$((
@@ -11887,7 +11887,7 @@ expected-stdout:
function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$( function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$(
if ! [[ 1 = 1 ]] >&3 ; then echo eins; elif [[ 1 = 2 ]] >&3; then echo zwei ;else echo drei; fi >&3 if ! [[ 1 = 1 ]] >&3 ; then echo eins; elif [[ 1 = 2 ]] >&3; then echo zwei ;else echo drei; fi >&3
); } ); }
function comsub_TIF_TBANG_TDBRACKET_TELIF { function comsub_TIF_TBANG_TDBRACKET_TELIF {
x=$(if ! [[ 1 = 1 ]] >&3 ; then \echo eins ; elif [[ 1 = 2 ]] >&3 ; then \echo zwei ; else \echo drei ; fi >&3 ) x=$(if ! [[ 1 = 1 ]] >&3 ; then \echo eins ; elif [[ 1 = 2 ]] >&3 ; then \echo zwei ; else \echo drei ; fi >&3 )
} }
function reread_TIF_TBANG_TDBRACKET_TELIF { x=$(( function reread_TIF_TBANG_TDBRACKET_TELIF { x=$((
@@ -11912,7 +11912,7 @@ expected-stdout:
function comsub_TWHILE { x=$( function comsub_TWHILE { x=$(
i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3 i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
); } ); }
function comsub_TWHILE { function comsub_TWHILE {
x=$(i=1 ; while { \\builtin let " i < 10 " ; } >&3 ; do \echo $i ; \let ++i ; done >&3 ) x=$(i=1 ; while { \\builtin let " i < 10 " ; } >&3 ; do \echo $i ; \let ++i ; done >&3 )
} }
function reread_TWHILE { x=$(( function reread_TWHILE { x=$((
@@ -11936,7 +11936,7 @@ expected-stdout:
function comsub_TUNTIL { x=$( function comsub_TUNTIL { x=$(
i=10; until (( !--i )) >&3 ; do echo $i; done >&3 i=10; until (( !--i )) >&3 ; do echo $i; done >&3
); } ); }
function comsub_TUNTIL { function comsub_TUNTIL {
x=$(i=10 ; until { \\builtin let " !--i " ; } >&3 ; do \echo $i ; done >&3 ) x=$(i=10 ; until { \\builtin let " !--i " ; } >&3 ; do \echo $i ; done >&3 )
} }
function reread_TUNTIL { x=$(( function reread_TUNTIL { x=$((
@@ -11955,7 +11955,7 @@ expected-stdout:
function comsub_TCOPROC { x=$( function comsub_TCOPROC { x=$(
cat * >&3 |& >&3 ls cat * >&3 |& >&3 ls
); } ); }
function comsub_TCOPROC { function comsub_TCOPROC {
x=$(\cat * >&3 |& \ls >&3 ) x=$(\cat * >&3 |& \ls >&3 )
} }
function reread_TCOPROC { x=$(( function reread_TCOPROC { x=$((
@@ -11982,7 +11982,7 @@ expected-stdout:
bourne () { logger * >&3 & } bourne () { logger * >&3 & }
); } ); }
function comsub_TFUNCT_TBRACE_TASYNC { function comsub_TFUNCT_TBRACE_TASYNC {
x=$(function korn { \echo eins ; \echo zwei >&3 ; } ; bourne() { \logger * >&3 & } ) x=$(function korn { \echo eins ; \echo zwei >&3 ; } ; bourne() { \logger * >&3 & } )
} }
function reread_TFUNCT_TBRACE_TASYNC { x=$(( function reread_TFUNCT_TBRACE_TASYNC { x=$((
function korn { echo eins; echo >&3 zwei ; } function korn { echo eins; echo >&3 zwei ; }
@@ -12000,7 +12000,7 @@ expected-stdout:
function comsub_COMSUB_EXPRSUB { x=$( function comsub_COMSUB_EXPRSUB { x=$(
echo $(true >&3) $((1+ 2)) echo $(true >&3) $((1+ 2))
); } ); }
function comsub_COMSUB_EXPRSUB { function comsub_COMSUB_EXPRSUB {
x=$(\echo $(\true >&3 ) $((1+ 2)) ) x=$(\echo $(\true >&3 ) $((1+ 2)) )
} }
function reread_COMSUB_EXPRSUB { x=$(( function reread_COMSUB_EXPRSUB { x=$((

4
tree.c
View File

@@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.87 2017/04/06 01:59:58 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/tree.c,v 1.88 2017/04/11 12:34:04 tg Exp $");
#define INDENT 8 #define INDENT 8
@@ -365,6 +365,8 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
case COMSUB: case COMSUB:
shf_puts("$(", shf); shf_puts("$(", shf);
cs = ")"; cs = ")";
if (*wp == '(' /*)*/)
shf_putc(' ', shf);
pSUB: pSUB:
while ((c = *wp++) != 0) while ((c = *wp++) != 0)
shf_putc(c, shf); shf_putc(c, shf);