On 12/10/2014 02:36 PM, Kevin Thibedeau wrote: > I recently ran into a problem in m4 (1.4.16) when passing hex arguments to > the incr() and decr() builtins: > > incr(0x4) > > m4:incr.m4:1: non-numeric argument to builtin `incr' > > I've checked the latest versions of the 1.4 and 1.6 branches and the issue > seems to stem from this line in numeric_arg() in builtin.c: > > *valuep = strtol (arg, &endp, 10); > > The radix is fixed as base-10.
Yes, and this behavior is intentional and matches historical implementations. You can always do: define(`incr', `eval(($1)+1)') to get arbitrary bases, so it is not worth breaking historical assumptions of incr(010) resulting in 11. > > I don't know if this is necessarily a bug since the POSIX and GNU docs are > vague about the acceptable arguments other than that they must be "numeric" > or "integers". It seems to me that all of the numeric formats supported by > eval() should also work with incr() and decr(). POSIX is explicit: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/m4.html "Except for the first argument to the eval macro, all numeric arguments to built-in macros shall be interpreted as decimal values." > > As a partial fix, the base in strtol() could be changed to 0 to get support > for octal and hex literals but that leaves binary and arbitrary bases > unsupported. At a quick glance it looks like eval_lex() could be used for > converting numeric arguments in all formats after a check for unary +/- at > the start of a string. The fix could be restricted to m4_incr() and > m4_decr() if there is concern about breaking legacy m4 code using other > builtins that call numeric_arg(). Thanks for the suggestion, but taking it would violate POSIX. About all we can do is enhance the documentation that you found unclear, to make it obvious that eval is the only builtin that takes non-decimals. Suggestions on wording or locations within the docs to update? -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature