Re: bug#20733: coreutils build problem

2015-06-04 Thread Nick Bowler
On 2015-06-04 14:41 -0600, Eric Blake wrote:
 On 06/04/2015 02:17 PM, Nick Bowler wrote:
  Do these problematic shells properly handle:
  
for arg
do
  ...
done
  
  when $# is 0?
 
 Yes; all shells do.

OK, good to know.

[...]
 it's not the expand-to-nothing that is a problem, it is the actual
 omission:
 
 $ /bin/sh -c 'for a in ; do :; done'
 /bin/sh: syntax error at line 1: `;' unexpected
 $ /bin/sh -c 'for a in $nothing; do :; done'
 $

Right, I see that now in the doc patch you posted.  So in Autoconf this
might turn up if you generate the list with m4, but is highly unlikely
to be an issue for pure shell code.

Thanks,
-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)



Re: bug#20733: coreutils build problem

2015-06-04 Thread Eric Blake
On 06/04/2015 02:17 PM, Nick Bowler wrote:
 Do these problematic shells properly handle:
 
   for arg
   do
 ...
   done
 
 when $# is 0?

Yes; all shells do.

$ /bin/sh -c 'echo $#; for arg
do echo hi; done; echo bye'
0
bye

 
 If so, can we use the following as a workaround?
 
   set x words-that-might-expand-to-nothing; shift
   for arg
   do
 ...
   done

Not ideal, when there are shorter invocations that can do the same.  And
it's not the expand-to-nothing that is a problem, it is the actual omission:

$ /bin/sh -c 'for a in ; do :; done'
/bin/sh: syntax error at line 1: `;' unexpected
$ /bin/sh -c 'for a in $nothing; do :; done'
$

so anything that expands in shell to nothing (whether $nothing, ``, or
use of a shell variable rather than a make variable) is fine; the
problem is most common in Makefiles where make variables are expanded
before the shell sees anything.

 
 I suppose that might be hard to do in this /particular/ case, as it
 looks like the error is coming from a make rule.  The Autoconf manual
 quite emphatically says to avoid 'for arg; do ...' by using a newline
 instead of a semicolon, a feat which is not easily done in make rules.

The manual also has a workaround for getting a literal newline in make
rules:
 nlinit=`echo 'nl='; echo ''`; eval $$nlinit

although that only gives you $nl containing newline, and you'd still
need another layer of 'eval' if you wanted to actually write the
makefile fragment to interpret the newline as a separator between the
var-name and 'do'.  So yeah, it's not worth it.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: bug#20733: coreutils build problem

2015-06-04 Thread Paul Eggert

Eric Blake wrote:

Actually, POSIX_does_  allow for missing words between 'in' and the
terminator (; or newline) before 'do' (whether by a word that expands to
nothing, or by omission of words), requiring that the body of the for
statement is skipped in that case:


Ah, sorry, I was thinking of previous versions of POSIX, which required at least 
one word after the 'in'.  You're right, the current POSIX version doesn't 
require this any more.  So the Solaris sh in question is conforming to the old 
POSIX standard but not to the current one.


I liked the approach with ``; I hadn't thought of that.  I used the coreutils 
fix I did because other coreutils code already fixed similar for-loop problems 
that way.




Re: bug#20733: coreutils build problem

2015-06-04 Thread Nick Bowler
On 2015-06-04 13:34 -0600, Eric Blake wrote:
 [adding autoconf]
 
 On 06/04/2015 01:17 PM, Paul Eggert wrote:
  
  On 06/04/2015 09:41 AM, Michael Felt wrote:
GEN  src/coreutils.h
  /bin/sh: 0403-057 Syntax error at line 1 : `;' is not expected.
  
 
  Port to POSIX shell, which doesn't allow 'for i in ; do ...'.
 
 Actually, POSIX _does_ allow for missing words between 'in' and the
 terminator (; or newline) before 'do' (whether by a word that expands to
 nothing, or by omission of words), requiring that the body of the for
 statement is skipped in that case:
 
 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04
 
 But it is also true that older shells did not always follow this rule,
 so you are indeed better off always supplying at least one word that
 won't be expanded into nothingness.
 
 Hmmm, I thought that autoconf would document it as a portability
 pitfall, but I don't see it under 'for' in this link:
 
 https://www.gnu.org/software/autoconf/manual/autoconf.html#Limitations-of-Builtins

Yikes!

Some questions:

Do these problematic shells properly handle:

  for arg
  do
...
  done

when $# is 0?

If so, can we use the following as a workaround?

  set x words-that-might-expand-to-nothing; shift
  for arg
  do
...
  done

I suppose that might be hard to do in this /particular/ case, as it
looks like the error is coming from a make rule.  The Autoconf manual
quite emphatically says to avoid 'for arg; do ...' by using a newline
instead of a semicolon, a feat which is not easily done in make rules.

Cheers,
-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)