1

Is it possible to define a m4 macro (without arguments), which expands to 1 on first invocation, expands to 2 on second invocation, and so on? In other words, it should have internal memory storing the number of times it is invoked. Can this be done?

adgadg
  • 69
  • 7

2 Answers2

5

You can do that by having two macros, a counter holding the current value, and a count macro that expands to the value and redefines `counter'. For example, it could look like this

define(`counter',`0')dnl
define(`count',`define(`counter',eval(counter+1))counter')dnl

When the count macro is used, it firstly redefines counter to hold its next value (adding 1 to its present value), and then it uses that value.

I'm not immediately sure how to do this with a single macro, and if that's an important aspect of your problem then this is not the answer.

Ralph Rönnquist
  • 3,183
  • 1
  • 10
  • 11
  • Thanks Ralph. This works just as I intended to, so long as I use it (with appropriate quotes and `eval`s) within a macro which is defined directly. It provides an invocation number for the called macro. But I also have a macro-defining macro whose purpose is to define a macro named `$1` having expansion `$2` (and do other processing to the expansion), and I am having trouble to get it to work in this indirect situation. – adgadg May 04 '16 at 02:43
  • You mean like using your own `mydef` instead of `define` in the above, where the `mydef' would include like `define($1,$2)` in its expansion? or is it more like including `define($1,F($2))` where F does things to its argument? Actually if you can add an explicit example of the essentials of your `mydef' to your question... – Ralph Rönnquist May 04 '16 at 04:26
  • It is like my own `mydef` as in `define(mydef, define($1, F($2)))`, which is then used to define more macros using the form `mydef(mymacroname, stuff)` (I am omitting quotes). Your method should still work, so my guess is that I am probably messing up some nested quoting. I will try some more, and if I am unable to fix it myself, I will ask again with an explicit example added to my question. Thanks for your help. – adgadg May 04 '16 at 05:20
  • I was able to fix my problem -- Ralph's answer works in the indirect situation as well. Thanks. (If any one is interested, I can post the code in my question above.) – adgadg May 05 '16 at 03:38
  • Thanks for this. Very useful. I expanded a bit on how I use this technique in Markdown https://gist.github.com/alecthegeek/737cb92a4a45cdbbda6329c977f31bd5 – Alec the Geek Dec 09 '18 at 04:47
0

I posted a similar question to the GNU m4-discuss mailing list. Doug McIlroy replied and shared this code:

define(bump,`define(`$1',incr($1))')dnl
define(counter,0)dnl
counter
bump(`counter')counter
bump(`counter')counter