[comp.text] ISC 2.0.2 troff broke?

brown@vidiot.UUCP (Vidiot) (02/26/91)

I am running ISC 2.0.2 Unix and ISC text processing package.  When I have
the following line, with neither of the registers set on the command line:

	.if \nG==1&\nI==0 \{\
	.tm inside coverdef G=\nG I=\nI

It gets past the if statement and shows that both registers are indeed zero.

If I change the order of the test, like this:

	.if \nI==0&\nG==1 \{\
	.tm inside coverdef G=\nG I=\nI

It doesn't get to the next statement, just as I would expect.  If I do -rG1
on the command line, then it gets past the if statement, as I expected.

What the Hell is going on here?  Is the ISC version of DWB 2.0 broke?
-- 
      harvard\     att!nicmad\          spool.cs.wisc.edu!astroatc!vidiot!brown
Vidiot  ucbvax!uwvax..........!astroatc!vidiot!brown
      rutgers/  decvax!nicmad/ INTERNET:vidiot!brown%astroatc@spool.cs.wisc.edu

brown@vidiot.UUCP (Vidiot) (02/26/91)

In article <1434@vidiot.UUCP> brown@vidiot.UUCP (Vidiot) writes:
<
<I am running ISC 2.0.2 Unix and ISC text processing package.  When I have
<the following line, with neither of the registers set on the command line:
<
<	.if \nG==1&\nI==0 \{\
<	.tm inside coverdef G=\nG I=\nI
<
<It gets past the if statement and shows that both registers are indeed zero.
<
<If I change the order of the test, like this:
<
<	.if \nI==0&\nG==1 \{\
<	.tm inside coverdef G=\nG I=\nI
<
<It doesn't get to the next statement, just as I would expect.  If I do -rG1
<on the command line, then it gets past the if statement, as I expected.
<
<What the Hell is going on here?  Is the ISC version of DWB 2.0 broke?

As it turns out, groff 1.00 does the same thing.  Why is the order of testing
important?

BTW, just in case it needs to be said exactly what I want to happen, what I am
after is that the code after the if statement will only be executed IF the
I number register is equal to a 0 AND the G number register is equal to a 1.
-- 
      harvard\     att!nicmad\          spool.cs.wisc.edu!astroatc!vidiot!brown
Vidiot  ucbvax!uwvax..........!astroatc!vidiot!brown
      rutgers/  decvax!nicmad/ INTERNET:vidiot!brown%astroatc@spool.cs.wisc.edu

jeff@itx.isc.com (Jeff Copeland) (02/28/91)

In article <1434@vidiot.UUCP> brown@vidiot.UUCP (Vidiot) writes:
>
>I am running ISC 2.0.2 Unix and ISC text processing package.  When I have
>the following line, with neither of the registers set on the command line:
>
>	.if \nG==1&\nI==0 \{\
>	.tm inside coverdef G=\nG I=\nI
>
>It gets past the if statement and shows that both registers are indeed zero.
>....
>What the Hell is going on here?  Is the ISC version of DWB 2.0 broke?

The secret is evaluation order:  if you add parentheses:
	.if (\nI==0)&(\nG==1) \{\
it works as you expect.  So the line in the DWB 2.0 docs that says:
	"Except where controlled by parentheses, evaluation of
	expressions is left-to-right."
is *really* true.

By the way, Interactive's DWB 2.0, IBM's DWB 2.0 on the RS/6000, DWB 1.0 on 
a VAX running BSD, and old troff as ported by BRL to BSD, all act the same 
on this fragment.  

jaap@mtxinu.COM (Jaap Akkerhuis) (02/28/91)

In article <1435@vidiot.UUCP> brown@vidiot.UUCP (Vidiot) writes:
 > In article <1434@vidiot.UUCP> brown@vidiot.UUCP (Vidiot) writes:
 > <
 > <I am running ISC 2.0.2 Unix and ISC text processing package.  When I have
 > <the following line, with neither of the registers set on the command line:
 > <
 > <	.if \nG==1&\nI==0 \{\
 > <	.tm inside coverdef G=\nG I=\nI
 > <
 > <It gets past the if statement and shows that both registers are indeed zero.
 > <
 > <If I change the order of the test, like this:
 > <
 > <	.if \nI==0&\nG==1 \{\
 > <	.tm inside coverdef G=\nG I=\nI
 > <
 > <It doesn't get to the next statement, just as I would expect.  If I do -rG1
 > <on the command line, then it gets past the if statement, as I expected.
 > <
 > <What the Hell is going on here?  Is the ISC version of DWB 2.0 broke?

Remember that famous line from the manual: ``evaluation is from left
to right''? So in this case, the & doesn't take precedence over the ==
as it would in C (if (G == 1 && I == 0)

What you want to do, is to put the test in paratheses as in

	.if (nG==1)&(\nI==0) .tm condition is true

 > 
 > As it turns out, groff 1.00 does the same thing.  Why is the order of testing
 > important?
 > 

Groff is correctly implementating the left-to-right evaluation
rule. Anyway, a lot of people forget about this so they resort to

	.if \nI==0 .if \nG==1

Common idiom in a macro pacakge is:

	.if !\nI .if \nG .tm true

which is actually a different test (in C: if( I != 0 && G == 0) )


	jaap


PS. I assume that you know that you have to double the backslahes
inside a macro. I guess you didn't want to shoe all these trivial
details.

msb@sq.sq.com (Mark Brader) (03/05/91)

"Vidiot" asked why

	.if \nG==1&\nI==0 ...

didn't work.  Jaap Akkerhuis diagnosed correctly that Vidiot had
forgotten troff's rather counterintuitive rule of no precedence,
and suggested the following (or intended to suggest it, anyway;
I have fixed a typo):

> What you want to do, is to put the test in parentheses as in
> 	.if (\nG==1)&(\nI==0) .tm condition is true

And this is right.  Jaap also observed that some people would say one of:

> 	.if \nI==0 .if \nG==1
> 	.if !\nI .if \nG .tm true

and that these are different if I and G are not really booleans.
However, he falls from grace in saying that the second one is
equivalent to the C code:

>	if( I != 0 && G == 0)

First, the conditions are reversed, but again, that's incidental.
The more important thing is this.  In troff, when an integer value is
treated as boolean, *only* a *positive* value is considered true.
This is counterintuitive for C programmers, who are used to any nonzero
value being considered true.

The last line of troff above is thus actually equivalent to *this* in C:

	if (I <= 0 && G > 0)
-- 
Mark Brader		"The default choice ... is in many ways the most
utzoo!sq!msb		 important thing.  ... People can get started without
msb@sq.com		 reading a big manual."		-- Brian W. Kernighan

This article is in the public domain.