Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!lll-crg!lll-lcc!well!dv From: dv@well.UUCP (David W. Vezie) Newsgroups: net.unix-wizards Subject: Re: possible problem in csh if/then/endif Message-ID: <1901@well.UUCP> Date: Thu, 9-Oct-86 02:54:52 EDT Article-I.D.: well.1901 Posted: Thu Oct 9 02:54:52 1986 Date-Received: Thu, 9-Oct-86 06:31:20 EDT References: <113@pixar.UUCP> Reply-To: dv@well.UUCP (David W. Vezie) Distribution: net Organization: Whole Earth Lectronic Link, Sausalito CA Lines: 56 In article <113@pixar.UUCP> brighton@pixar.UUCP (Bill Carson) writes: >consider this: (as run on a virgin 4.3BSD csh (vax)) > > 1 #! /bin/csh -fx > 2 > 3 set machine = string > 4 set host = string > 5 set foo = bar > 6 > 7 if ( $machine !~ $host ) then > 8 if ( $foo =~ bar ) then > 9 echo dummy if statement > 10 endif > 11 echo this should not happen > 12 else > 13 echo this should happen > 14 endif > >Ok, on line 8, if you remove the space between the 'if' and the '(' so that >it looks like this: > > 8 if( $foo =~ bar ) then > >then it will echo "this should not happen". I know this sounds confusing, >but extract the shell script, play with it, and you'll see what I mean. What's happening is that it evaluates the first if, which in this case returns false. It then calls search() (for those of you with source, this is all in sh.func.c), looking for an 'else' or an 'endif'. It uses a very limited parser for this (the function getword()), instead of using the full blown parsing routines in sh.lex.c. That parser knows about the basic word delimiter characters (space, tab, single/double quote, pound-sign (why's it called "sharp"?), etc). Unfortunatelly, it doesn't know about '(', so when it reads "if( $foo =~ bar ) then", it treats the "if(" as one word. Since it doesn't see it as "if", it treats the following "endif" as the "endif" that corresponds to the original "if" and runs everything after that. By the way, it's technically not an error to have an "else" without a corresponding "if". It just ignores everything between the "else" and the next "endif". This has been a problem with csh since at least 4.1 (probably forever). As far as fixes go, the fix would probably be to tell getword() about '('. I havn't tried installing a fix, as I use a safer programming style :-) > ... Joe Bob says "pull your hair out" Yes, well, that's what you get for asking HIM... :-) > -Bill ...!{ucbvax,sun}!pixar!brighton --- David W. Vezie {dual|hplabs}!well!dv - Whole Earth 'Lectronics Link, Sausalito, CA (4 lines, 114 chars)