[comp.sys.sun] nested ifs' in csh dont work?

grant@saturn.cs.swin (Grant Collins) (05/31/90)

Howdy Netlanders.  Is csh supposed to interpret nested if's correctly or
not?  Most texts seem to indicate that nested if's will work, but the
following test script (under SunOS 4.0.3) appears to indicate otherwise:

#!/bin/csh -f
set a = 2
set b = 2

if($a == 1) then
   if($b == 1) then
      echo a=1,b=1
   else
      echo a=1,b!=1
   endif
else
   echo ignores from here
   if($b == 1) then
      echo a!=1,b=1
   else
      echo a!=1,b!=1
   endif
   echo all the way to endif above
endif
echo end of script.


Output from this script is:
a=1,b!=1
all the way to endif above
end of script.

It appears that the inner else's and endif's are terminating the outer if.
Is this a feature or a bug, or have I just missed something fundamental?

fbresz@uunet.uu.net (06/01/90)

[[Ed's Note: about two million people answered this one (I should have if
I had been paying a little more attention). In any event, my apologies to
everyone else that sent a note who did not get included. Below is the
correct solution. -bdg]]

>if($a == 1) then
>   if($b == 1) then
    [...]

Due to the way that CSH parses if's, you must separate everything with
spaces.  When I did this to your code it worked fine.

if ( $a == 1 ) then
   if ( $b == 1 ) then

guy@uunet.uu.net (Guy Harris) (06/03/90)

>Due to the way that CSH parses if's, you must separate everything with
>spaces.

If you are ever tempted to write scripts in the C shell, note the
following comment at the end of the SunOS (and now System V Release 4)
"csh" man page, which applies to almost everybody's (if not everybody's)
"csh":

     Although robust enough for general use, adventures into  the
     esoteric  periphery  of  the  C  shell may reveal unexpected
     quirks.

Apparently, the periphery may be closer than you might think....

harp@pkg.mcc.com (Christopher North-Keys) (06/06/90)

They do indeed work, if the "if" in each instance in immediately followed
by a space, as already noted.  The only distinct oddness I've noted in Csh
programs is that aliases don't work placed in the format:

	if (cond) alias

where instead the following *must* be used:

	if (cond) then
		alias
	...

This type of thing also occurs in local variable setting.  There must be
spaces on *both* sides of the "=", or neither.  In contrast "=" is *not*
used in setenv commands.  It's worth noting that all local variables are
vectors (lists), and can easily be used as local stacks.

Nesting of if/then/else/endif, switch/case/breaksw/default/endsw,
while/break/end, etc., all works as expected.  The last person I found
having trouble was trying to use "break"/"end" in "switch", instead of the
required "breaksw"/"endsw".  He enclosed the entire switch in a "while 1 /
end" loop to get the misbegotten "break"/"end"s to do what he wanted.
This is called not reading the manual, folks.

I find the C shell flow constructs much more obvious than I do the Bourne.
The keyword "breaksw" is rather more intuitive than ";;".  But then, I'm a
C(++) programmer, and such were also the C shell authors :-).

Someone needs to write a nice, new (PD) shell from scratch, of course.
None of the existing shells are what I'd call either "consistent", or
"elegant" (personal opinion of: sh, ksh, csh, bash, tcsh).  In particular,
none of them support the loading of additional object modules at runtime,
nor state-dumping or the like (like GNUemacs) to reduce startup time.
Their command sets all require bizarre parsing (contrast to languages like
Lisp and Forth), and all have peculiarities.

------------------------------------/\----------------------------------------
Seo:  Harp[@Mcc.Com]               /  \/\ ^*^           Christopher North-Keys
Tha mi gu trang a'cluich.         /    \ \         Assoc. Systems Analyst, MCC
--------------------------------(disclaimer)----------------------------------