On 2004-08-27 12:13, "Crist J. Clark" <[EMAIL PROTECTED]> wrote: > I want to do something that I _think_ should be rather simple > within m4(1). I want to test if a macro value has been set. > If it is set, I want to modify it and continue. If it is not > set, I want to produce an error message and bail out. However, > it is not working. > > Here is an example of a test script, > > $ cat testerr.mc > ifdef(`TEST', ``TEST' defined.', `TEST not defined.') > > ifdef(`TEST', define(`TEST', `NEW'TEST), errprint(`TEST not specified, exiting.') > m4exit(1)) > > The value of `TEST' is TEST.
The trick is to avoid evaluation of the two conditional parts by quoting them at least ONE level more than the enclosing ifdef(). This: ifdef(`a', foo, bar) will evaluate both foo anr bar at the same time that ifdef() is evaluated and checked. This second form though: ifdef(`a', `foo', `bar') will still evaluate `foo' and `bar' at the outter level, yielding foo and bar, but only one of foo or bar will eventually be evaluated depending on the value of `a'. I don't know if this sounds confusing or it helps at all, but here's a modified version of testerr.mc that works as (I think) you expect: # cat /tmp/testerr.mc ifdef(`TEST', ``TEST' defined.', `TEST not defined.') ifdef(`TEST', `define(`TEST', `NEW'TEST)', `errprint(`TEST not specified, exiting.') m4exit(1)') The value of `TEST' is TEST. If you don't define TEST, m4exit(1) is evaluated: # m4 /tmp/testerr.mc TEST not defined. TEST not specified, exiting. # Note the SPACE character right before my shell prompt, which is the space character immediatelly before `m4exit(1)'. Now, if you *do* define TEST: # m4 -DTEST=foo /tmp/testerr.mc TEST defined. The value of TEST is NEWfoo. # The NEW definition is printed ;-) > What quoting scheme do I need to use here to get this to work > correctly? Or is there some other trick to it? Can someone > explain m4(1)'s order of evaluation and what actually gets > evaluated in each case? If you don't quote the arguments to ifdef() they are ALL evaluated and the result of their evaluation is substituted before the choise of ifdef() takes place. This is why regardless of TEST being defined or not the second part of your ifdef() was evaluated and caused m4exit() to abort the entire process *before* ifdef() made its choise of what to evaluate next. To see this in action check the output of the following script: # cat /tmp/foo.mc ifdef(`foo', define(`foo', `more'foo), errprint(`foo is 'foo) m4exit(1)) # echo ? 1 # m4 /tmp/foo.mc foo is morefoo # m4 -Dfoo=bar /tmp/foo.mc foo is morebar # echo $? 1 In both cases keep in mind that the arguments of ifdef() are evaluated once before ifdef() makes a choise. a) When foo is undefined, this is evaluated: define(`foo', `more'foo) and `foo' is defined to be `morefoo' (because `foo' is undefined and is interpreted literally in the second part of the define(). Then the second part of ifdef() is evaluated and m4exit() terminates all evaluation with an error of 1 after having printed errprint's message. b) When foo is defined to `bar', exactly the same happens only this time at the second argument of define() foo has a different value. ... An entirely different thing happens when you quote the arguments of ifdef(): # cat /tmp/foo2.mc ifdef(`foo', `define(`foo', `more'foo)', `errprint(`foo is 'foo) m4exit(1)') foo # m4 /tmp/foo2.mc foo is foo # echo $? 1 $ m4 -Dfoo=bar /tmp/foo2.mc morebar # echo $? 0 I hope all this random m4-rambling helps a bit, Giorgos _______________________________________________ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "[EMAIL PROTECTED]"