bug-m4
[Top][All Lists]
Advanced

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

Re: format bug


From: Gary V. Vaughan
Subject: Re: format bug
Date: Thu, 31 May 2007 12:19:56 +0100

Hi Eric,

On 31 May 2007, at 01:56, Eric Blake wrote:
According to Eric Blake on 5/28/2007 10:15 PM:
Try this for a fun time:

$ echo 'format(%*.*d,-1,-1,1)' | m4 | wc
      1       1 2280281


A related question I have about the format builtin:

Consider printf(1).  POSIX allows conversion from integer value to
character (with ASCII, "printf %b '\x09'" results in a literal TAB),
[[...]] 
Meanwhile, m4's format builtin, for the past 17 years, has handled %c as
a conversion from integer to character (with ASCII, format(%c,9) results
in TAB, [[...]]

Gratuitously breaking 17 years of accumulated GNU m4 input seems like a
bad idea to me.  What do other m4 implementations do?

I'm thinking of changing this setup so that m4's format is more like
printf(1) (unlike C, where printf(3) can distinguish between character
literals and integers, m4's format is restricted that all arguments
start out as strings, much like the shell's printf(1).)  But this is a
backwards-incompatible change.  So what I am proposing is to make m4
1.4.10 implement %b, and issue a warning when \ is encountered in the
format or when %c is encountered in the format with an integer argument,
but keep output identical with earlier m4 1.4.x except that %b now
results in content instead of the undocumented behavior of being
skipped.  Then m4 2.0 could just use the newer printf(1) semantics
without worry.  I would also update the documentation to mention the
change in direction, as well as these portability guidelines for using
format consistently across both 1.4.x and 2.0:

- - avoid \ in the first argument to format
- - if you want a literal \, use format(%s,\) or just rely on m4
concatenation of \ outside of format
- - if you want to convert an integer to a character, write a wrapper:
ifelse(format(%b,1),1,format(%b,\x09),format(%c,9))
- - no portable way to convert a character to an integer short of a
255-element reverse-lookup table (you could use a forloop recursion
construct, but be sure your iterator and quote characters are
multi-character for the duration of the loop to avoid parse problems; hmm,
maybe I should code this up and add it to the examples directory)
- - if you want the first character of a string, use %.1s instead of %c

Any objections to this approach?

Not if it is only turned on in POSIXLY_CORRECT mode, at least in the
stable branch.  For 2.0, using a posixy approach by default is okay,
provided there is no code in recent autoconf releases that barfs at the
change...

Cheers,
Gary
-- 
  ())_.              Email me: address@hidden
  ( '/           Read my blog: http://blog.azazil.net
  / )=         ...and my book: http://sources.redhat.com/autobook
`(_~)_ Join my AGLOCO Network: http://www.agloco.com/r/BBBS7912 




Attachment: PGP.sig
Description: This is a digitally signed message part


reply via email to

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