m4-discuss
[Top][All Lists]
Advanced

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

Re: very basic question incr


From: Eric Blake
Subject: Re: very basic question incr
Date: Wed, 11 Jan 2012 11:41:33 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:9.0) Gecko/20111222 Thunderbird/9.0

On 01/11/2012 11:16 AM, jfw wrote:
> Thanks, ok I'm now beyond infinite recursion.  Now what I want to do is
> increment each time I invoke count.

> 
> I'm using lowercase ~ for left quote and lowercase " for right quote.  I'll
> paste rather than retype.

Okay, assuming a US keyboard, that is indeed how you would type backtick
and apostrophe (but the same cannot be said of all keyboards; for
example, in the UK, lowercase " is 2, not ')

> 
> So using:
> 
> define emit(`text', text)

This didn't define anything.  It called define without arguments, which
is a special case whose output is the quoted string define; then it
looks like a call to emit() with two arguments ("text" and the expansion
of "text"), except that at this point in your file, emit() is not
defined as a macro.  Hence your output of:

define emit(text, text)

I'm not exactly sure what you were trying to accomplish with emit, but I
don't think you need it for your particular problem statement of
defining a macro that expands to a different value on each use.
Meanwhile, if you really did  want to define a macro named emit that
expands to its first argument unquoted, that would be done as:

define(`emit', `$1')

Also, you appear to be mis-understanding how incr() works.  It does
_not_ redefine an existing macro, it only does computation on a numeric
argument.  Perhaps it would be worth adding a GNU extension where incr()
could indeed be used to redefine a macro with an increment of its
current value, but that is not part of the original m4 language, and
someone would have to both write such an extension and justify its
inclusion.

> define(`count',`0')

This defines "count" to the contents of "0", and has no output.

> count

This expands "count", for an output of "0".

> define(`count',incr(count))

This redefines "count" to now be the expansion of incr(count), that is, "1".

> count

This expands to the current contents of count, that is "1".

> count

And again.

> 
> emit(count)

You never defined emit(), so this expands to:

emit(1)

> emit(count)

and again.

> 
> I expected 0,1,2 and 2,4

Why didn't you state your end goal in the first place?  To get that, I'd
recommend the use of a helper macro (the helper macro tracks the value
of the counter, and the public macro modifies and displays the current
count).  As in:

define(`_count', `0')dnl Initialize our helper...
define(`count', `_$0`'define(`_$0',incr(_$0))')dnl and our public macro

Now, every time you expand count, that results in the expansion of the
current value of _count, as well as code to redefine _count to the next
value.  The same trick can be used with expr instead of incr when
operating on the internal macro (basically, incr(value) is short for
expr(value+1)).

-- 
Eric Blake   address@hidden    +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]