-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
The autoconf manual mentions nothing about the limitations of $(( )) arithmetic expansion, other than the fact that $( ) command substition can be confused with it when using subshells. POSIX requires arithmetic expansion, but not all historical shells had it. I think it should be mentioned in the shell substitutions section (10.5) of the manual, since ash (the current default cygwin /bin/sh) has an unusual behavior, and since Solaris 8 /bin/sh rejects it. I encountered this when investigating failures of shell scripts generated as part of the autogen package. However I don't have an assignment on file or enough experience with texinfo to write up a decent patch.
$ bash -c 'echo "x$((1+1))" | cat -A' # bash 2.05b x2$ $ ash -c 'echo "x$((1+1))" | cat -A' # cygwin /bin/sh: ash compiled Jan 2004 xM-^F"1+1M-^G$ $ ash -c 'echo x$((1+1)) | cat -A' xM-^F 1+1M-^G$ $ ... # switch to Solaris $ sh -c 'echo "x$((1+1))"|cat -A' # Solaris 8 x$((1+1))$ $ sh -c 'echo x$((1+1))|cat -A' /bin/sh: syntax error at line 1: `(' unexpected $ /usr/xpg4/bin/sh -c 'echo x$((1+1))|cat -A' x2$ $
Notice that ash emits 8-bit wrapper characters around the enclosed literal text, along with an indication of the current quoting level, rather than an arithmetic evaluation! Likewise, Solaris chokes on the syntax when unquoted, but treats it as a literal when quoted; although the xpg4 sh appears to be POSIX compliant. None of the respective man pages of ash, /bin/sh, and /usr/xpg4/bin/sh mention $(( )) behavior.
Am I correct that the only portable way to do arithmetic evaluation is to use expr in a subshell? In other words, this example idiom from POSIX 2004, section 2.6.4: # repeat a command 100 times x=100 while [ $x -gt 0 ] do ~ command; x=$(($x-1)) done
should be portably rewritten: while [ $x -gt 0 ] do ~ command; x=`expr $x - 1` done
Are there any portability arithmetic limitations of expr to be aware of? (The manual only focused on string matching with expr :.) Fortunately, a quick grep of the autoconf tree didn't turn up any current uses of '\$((', other than in documentation. Still, you may want to add checks to ensure that it doesn't slip in during future development. Or, it may be worth adding an m4sh idiom for optimzed arithmetic evaluation (done in m4 if literal, in $(( )) if supported, else in subshell with `expr`). Something like 'AS_VAR_SET([myvar], [AS_EXPR([AS_VAR_GET([myvar])+1])])' could potentially be useful.
- -- Life is short - so eat dessert first!
Eric Blake ebb9@xxxxxxx -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (Cygwin) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFB1d7W84KuGfSFAYARAmynAJ9p7spws5K9Gyn4dwK9Vkh/qCnojgCgytfK mIC9SaGQpxNVODHyA9uLT4g= =puOA -----END PGP SIGNATURE-----
_______________________________________________ Autoconf mailing list Autoconf@xxxxxxx http://lists.gnu.org/mailman/listinfo/autoconf