MS Macros/ME macros/MAN macros TROFF Universal Diversion Bug

idallen at watmath.UUCP idallen at watmath.UUCP
Thu Feb 28 10:25:26 AEST 1985


Try to format the following text in a filled diversion (e.g. a footnote,
abstract, or keep) in any of your favourite macro packages.  I will use
the Footnote macros of -ms here as an example:

.LP
Start test.
.FS
x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
.FE
End test.

For those unable to get to their computers, I'll explain what you get.

".tm" is the "type message" macro in TROFF.  When it appears at the
start of a line, the remainder of the line is sent to the standard
error output unit (not to the regular output stream).  Now, you will
note that no line above begins with ".tm", so you should expect that
nothing should appear on the error output stream.  This is not the case.

The text above is being collected in a filled diversion.  That means
that the words are shuffled around and "formatted" into an internal
buffer.  Depending on the current line length, the format of the text
in that internal buffer looks something like this:

    x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
    .tm .tm .tm x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
    .tm .tm .tm .tm .tm .tm x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
    .tm .tm .tm .tm .tm .tm .tm .tm .tm x .tm .tm .tm .tm .tm .tm .tm
    .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm x .tm .tm .tm .tm
    .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm x .tm
    .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm  .tm  .tm
    .tm .tm x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
    .tm .tm .tm .tm .tm x .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm
    .tm .tm .tm .tm .tm .tm .tm .tm x .tm .tm .tm .tm .tm .tm .tm .tm
    .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm x .tm .tm .tm .tm .tm
    .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm .tm

You can tell what's coming next, right?  How does TROFF put that
internal buffer into the normal input stream?  As a macro call.
And what is in the macro?  A whole bunch of lines that start with ".tm".
They execute.  In the above example, only one line gets put into the
real text and the rest spill out onto your error output unit because
of the executing ".tm" macro.

Now, consider what happens if, instead of ".tm", you had some other
word that began with a dot, such as ".login".  Since ".lo" isn't a
valid TROFF command, it ignores the line.  You get nothing.  No error.
No output.  No explanation.

To crown this disaster, replace all the ".tm" words with the
single-quoted string "'boo'".  Surprise!  The single-quote character
is also a control character to invoke a macro!  So you call the "'bo"
macro; no error message; no output; no explanation.

Fix: Unless you can get your local TROFF hack to change the macros,
you'd better not start any words in filled diversions with periods or
single quote characters.  It may \&'look a bit odd' to have these
silly empty \&'guard characters' in your running text, especially when
you talk about a \&.profile or \&.login file, or the \&.FS or \&.FE
macros, but you're used to these strange things on UNIX, aren't you?
-- 
        -IAN!  (Ian! D. Allen)      University of Waterloo



More information about the Comp.bugs.4bsd.ucb-fixes mailing list