Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Zsh 3 and ${1+"$@"} (Was: [GNU Autoconf 2.53] testsuite.log: 126 failures)

| Akim Demaille wrote:
| > Hi!
| > 
| > We (Autoconf) have a big problem with Zsh 3.0.8.  You know it is
| > shipped on Darwin as /bin/sh.  But this version does not understand
| > ${1+"$@"} properly.  We use this instead of "$@" to work around a bug
| > which still exists today in many many constructors' /bin/sh, so we
| > can't departure from it.
| I think the problem you are running across is that with the option
| SH_WORD_SPLIT set (as it is for sh compatibility), you get this behaviour:
| % set 'one two'
| % for arg in ${1+"$@"}; do echo $arg; done
| one
| two
| whereas you expect `one two' on the same line.  

`you' == akim, or == the sh standard?

| This problem is still in
| zsh 4 --- inside another substitution, either it's splitting all words
| on spaces, or it's splitting none.

I'm sure I understand you here, given that Zsh 4 exhibiting the
behavior I (Akim :) was expecting.

| This sort of mess is why zsh doesn't have SH_WORD_SPLIT on by default,
| but that doesn't help you...

I can understand the logic behind the result here: only "$@" is
expected not to split, but ${1} should, hence ${1+"$@"} splits.  But
then, Zsh (emulate sh) is the only sh I know behaving this way :(

| If you want to work around this you have two basic choices:
| 1. Unset shwordsplit:
|   [ x$ZSH_VERSION != x ] && unsetopt shwordsplit
| This will have a knock on effect on all unquoted shell parameter
| substitutions, however.  If you are relying on these producing multiple
| command arguments --- e.g. for building up arguments for `for' loops in
| a single parameter --- you are stuck unless you can find some way of
| turning shwordsplit off and on before using ${1+"$@"}.  (Writers of
| configure scripts --- not autoconf itself --- often incorrectly assume
| something like `test x$foo != x' will always produce the same number of
| words, but that's a separate problem from the one you face.)

We do want shwordsplit on.  It is heavily used, and we aim at sh, so
there is no choice here.

| 2. Rework the substitution.  In zsh, you would get away with
| ${==1+"$@"}, since the doubled `=' is a flag to turn off SH_WORD_SPLIT
| for that substitution.  Obviously, getting this in for zsh and not for
| other shells is a bit of a nightmare.  Indeed, rather than do that, it
| would presumably be easier to use "$@" for zsh instead of ${1+"$@"}
| (this handles zero arguments correctly), which is exactly what you're
| trying to avoid.
| Neither of these looks very promising.

Nope, indeed.  Too bad.

| "${1+"$@"}" also works in zsh, but this confuses other variants of sh
| --- it works in bash, but sh on SunOS 5.8 tripped over it.

Err, I'm not even sure it does what I want: I suspect that Zsh
understands this as a single argument, while I expect to have $# of
them.  If it does return more than one argument, then I don't
understand what exception sneaked in here.

| I haven't looked for any cleverer substitutions which will always work.
| Given that ${1+"$@"} is already a despairing workaround, it seems
| unlikely there's anything more complicated which will fool everyone at
| once.

Gee :(.

Finally, one question: do you know if Apple plans to continue with Zsh
3?  Why did they stick to it?

Messages sorted by: Reverse Date, Date, Thread, Author