[net.unix-wizards] Yet even MORE Csh Quirks

argv@ucb-vax.ARPA (04/18/85)

(Yell at me if you're sick of them)
This is the case of the matching "if" statements with their respective
"endif" statements. It seems that "endif"'s don't know who they are
ending.  Exibit A:

#!/bin/csh -f
@ count = 0
if($#argv == 2) then
    echo hi there
    if( 1 ) then  # this statement if obviously a no-op.
	@ count++  # count should be 1
	echo true
    endif
    echo hi there again
    @ count++      # count should be 2
endif
echo count = $count  

if argv is NOT 2, then $count should be 0, right?!
else count should be 2...  but in ANY event, count
should NEVER be 1. Also, you should either see, 
"hi there" AND "hi there again" or NEITHER, am I right?

The fault lies in the fact that you can't have nested if statements.
The first endif it sees ends ALL ifs, not just the one associated with
it.  If this is the case, why aren't I getting syntax errors for the 
extra (non-matching) endif?

						Dan Heller (aka Frank)
------------------------------------------------------------------------------
		UCSC Computing Center Consultant
      (Looking for a UNIX/C hacking Job - nudge nudge wink wink)

UUCP:    ucbvax!ucscc!argv  {ihnp4,sun,cbosgd,decwrl}!qubix!ucscc!argv
ARPA:    argv%ucscc.uucp@ucb-vax.arpa
CSnet:   c.argv@ucsc.csnet

                   (say no more, say no more)
-------------------------------------------------------------------------------

p.s. csh man entry doesn't address this (at least OURS doesn't).

jwp@sdchema.UUCP (John Pierce) (04/20/85)

In article <10032@brl-tgr.ARPA> argv@ucb-vax.ARPA writes:

 > ... It seems that "endif"'s don't know who they are ending.  Exibit A:

 > #!/bin/csh -f
 > @ count = 0
 > if($#argv == 2) then
 >     echo hi there
 >     if( 1 ) then  # this statement if obviously a no-op.
 > 	@ count++  # count should be 1
 > 	echo true
 >     endif
 >     echo hi there again
 >     @ count++      # count should be 2
 > endif
 > echo count = $count  
 > 
 > if argv is NOT 2, then $count should be 0, right?!
 > else count should be 2...  but in ANY event, count
 > should NEVER be 1. Also, you should either see, 
 > "hi there" AND "hi there again" or NEITHER, am I right?

No, not really.

 > The fault lies in the fact that you can't have nested if statements....

You can have nested 'if' statements.  The "fault" lies in a syntax error.  The
two 'if' statements should be

	if ($#argv == 2)
and
	if (1)

While it is annoying, that space between 'f' and '(' is necessary for csh to
handle the statement properly [the manual entry *does* specify "if (expr)..."].
It is also the case that

	if (expr1) then
		stmt1
	else
		if (expr2) then
			stmt2
	endif

is handled differently from

	if (expr1) then
		stmt1
	else if (expr2) then	# Syntax specified by the manual
		stmt2
	endif

when either the "if" portion or the "else" portion contains further "if"
statements.  I believe, though it's been a long time since I tested all of
this, that there are also problems with "while" and "foreach" inside improperly
typed "if" statements.  I do remember that

	while(expr)
		...
		while(expr)
			...
		end
		...
	end

(and the equivalent "foreach") also break, since the specified syntax is

	while (expr)		foreach (expr)

I have forgotten whether or not the space is absolutely necessary in "switch"
statements, but I believe it is.  While having to have the space there seems
dumb, with it things work as you would expect; without it, they do not.  The
problem can be fixed in the source, though it isn't completely trivial [meaning
it didn't seem to be sufficiently trivial for me to waste time on a problem
that doesn't annoy me any more than this one does].

				John Pierce, Chemistry, UC San Diego
				{sdcsvax,decvax}!sdchema!jwp
				jwp@ucsd

chris@umcp-cs.UUCP (Chris Torek) (04/20/85)

You have run into the C Shell's "parser": ifs inside false ifs must
have whitespace after the word "if"; elsewhere, ifs may be separated
from their arguments by parentheses.  Thus

	if (anything_false)
		foo
		if(anything)
			bar
		endif
		echo oops
	endif

fails, while

	if (anything_false)
		foo
		if (anything)
			bar
		endif
		echo oops
	endif

succeeds.  The only difference is a single space.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland