[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: A little m4 puzzle
From: |
Eric Blake |
Subject: |
Re: A little m4 puzzle |
Date: |
Mon, 12 Nov 2018 11:49:31 -0600 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.0 |
On 11/10/18 12:01 PM, Doug McIlroy wrote:
Consider this predicate on strings.
define(eq,`define(`_$1',F)define(`_2',T)_$1')
Underquoted. I highly recommend using full quoting:
define(`eq', `define(`_$1', `F')define(`_2', `T')_$1')
Also, did you mean for that _2 to be _$2 instead? And do you want to
undef your temporary variable(s) after the fact?
eq(x,y) yields T or F according as strings x and y are
the same or different. (The strings may contain only
characters allowed in macro names).
So you are (trying to) exploit the fact that if the strings are
different, you define two separate temporary variables (assuming you
meant _$2); if they are equal, you redefine a single temporary variable.
The puzzle: If you omit inner quotes from the definition,
eq(A,A) yields T as intended. But what happens when you
repeat the test?
You mean, as in:
define(eq, `define(_$1, F)define(_$2, T)_$1')
If so, then it's pretty easy to trace:
The first eq(A,A) expands to:
define(_A, F)define(_A, T)_A
which results in defining the macro "_A" to be "F" before expanding:
define(_A, T)_A
which is the same as:
define(F, T)_A
which defines the "F" to be "T", then expands the macro _A into F, and
the macro F into T.
The second eq(A,A) expands to:
define(_A, F)define(_A, T)_A
where the first define is now the same as:
define(T, T)define(_A, T)_A
which defines the macro "T" to "T". At which point, ANY attempt to
expand the macro T will infinitely recurse, which is exactly what
happens when you reach the second define().
(Incidentally, you can replace T by `$3' and F by `$4'
to make a near replacement for the builtin ifelse.)
Not with your lack of proper quoting. And the builtin can handle any
two strings, not just strings that are valid as part of a macro name.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org