ExtendingAMacro


Here is my example code and I'm puzzled at the infinite recursion when LP is invoked. I'm sure this must be obvious to many people but (not me at present!)

 .mso s.tmac
 .\" extend LP
 .rn LP LP-old
 .rm LP
 .de LP
 .  tm inside new LP
 .  LP-old
 ..
 .\" example text
 .LP
 .TL
 Hello
 .LP
 world

This is a cute example of "self-modifying code". In s.tmac, LP starts out with this definition:

  .de LP
  .\" [stuff removed]
  .cov*ab-init
  \\*[\\$0]\\
  ..

The \$0 is what causes the recursion. Normally, this "LP" is only called the very first time, however, since cov*ab-init contains the following line:

  .als LP @LP

which effectively redefines LP to mean @LP, so when the original LP evaluates \*[\$0], it is actually @LP that's expanded, and all's well. (After that, only @LP gets called anyway.)

However, when you're renaming LP to LP-old, the \$0 evaluates to LP-old and not LP. Since LP-old has *not* in the meantime been aliased to something else, LP-old keeps on calling LP-old, and the recursion doesn't stop.

If you try the following (@LP instead of LP)

  .mso s.tmac
  .\" extend LP
  .rn @LP @LP-old
  .rm @LP
  .de @LP
  .  tm inside new LP
  .  @LP-old
  ..
  .\" example text
  .LP
  .TL
  Hello
  .LP
  world

I think everything will work as expected.


Back to: GroffTips


Edit ExtendingAMacro FrontPage PageList RecentChanges PageHistory