Hello Eric,

Many thanks for your explanation.  It makes sense and now the "defn"
versus double quoting approaches are clear.

Best regards,

Denis/

On 03/08/2018 10:58 PM, Eric Blake wrote:
> On 03/08/2018 03:29 PM, Denis Valois wrote:
>> Hello m4 wizards,
>>
>> My problem is passing a single parenthesis as a macro argument.  I do
>> not understand m4 behavior; this tells me that I miss some fundamentals.
>>
>> example 1:  notice the litteral `('
>>      index(`abcdef', `(')
>> this works perfectly with the expected results -1.
>>
>> example 2: use of a macro
>>      define(`c', `(')
>>      index(`abcdef', c)
>> Here we have "ERROR: end of file in argument list".  This is because the
>> macro c is expanded before index so the parenthesis are unbalanced.
>
> Yep. During argument collection, m4 groups all text between unquoted
> () as part of a single argument, so you have to have balanced () if
> they are unquoted.  And once the macro "c" is expanded, you have
> introduced an unquoted ( into the stream that m4 is processing:
>
> index(`abcdef', ()
>
> as that lacks a closing ), you get the syntax error about end of file.
>
> (Why are unquoted parenthesis special? So you can do things like:
>
> define(`cat', `$1$2')
> cat(`index', (`abcdef', `b'))
>
> which passes only two (not three) arguments to cat(), and is a
> long-hand way of writing index(`abcdef', `b').  Annoyingly, unpaired
> parenthesis are more common than you think: in autoconf, shell case
> statements tend to have more ')' than '(', leading to tricks like:
>
> case $foo in # for balance (
>   bar) ... ;;
> esac
>
> in the input handed to m4.)
>
>>
>> Other approaches such as
>>      builtin(`index', `abcdef', `c')
>
> That expanded the same as:
>
> index(`abcdef', `c')
>
> which is not the contents of macro c like you wanted.
>
>> are either expanding to a wrong result or generate a run-time error.  I
>> simply do not see how to pass a macro defined with a parenthesis as
>> argument.
>
> It sounds like you want:
>
> index(`abcdef', defn(`c'))
>
> the defn() macro outputs the quoted value of macro c, which is then
> equivalent to what you originally used with a literal quoted string.
>
> Another thing you could try is defining "c" to be a quoted rather than
> bare unmatched parenthesis:
>
> define(`c', ``('')
>
> which may be what you want depending on where you expand the macro "c".
>
> In general, life with mismatched parenthesis can be tricky, but it's
> puzzlers like that which are fun to help on, so feel free to ask
> further related questions.
>


-- 
Denis Valois/
PGP KeyID 0xB5418E1A

Reply via email to