bug-m4
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: incr() and decr() don't support non-decimal arguments


From: Eric Blake
Subject: Re: incr() and decr() don't support non-decimal arguments
Date: Wed, 10 Dec 2014 15:38:00 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0

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

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]