From owner-freebsd-bugs Tue Mar 24 02:10:04 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id CAA03642 for freebsd-bugs-outgoing; Tue, 24 Mar 1998 02:10:04 -0800 (PST) (envelope-from owner-freebsd-bugs@FreeBSD.ORG) Received: (from gnats@localhost) by hub.freebsd.org (8.8.8/8.8.8) id CAA03606; Tue, 24 Mar 1998 02:10:01 -0800 (PST) (envelope-from gnats) Date: Tue, 24 Mar 1998 02:10:01 -0800 (PST) Message-Id: <199803241010.CAA03606@hub.freebsd.org> To: freebsd-bugs Cc: From: Martin Cracauer Subject: Re: bin/5263: sh bug (with example) Reply-To: Martin Cracauer Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR bin/5263; it has been noted by GNATS. From: Martin Cracauer To: tom@sdf.com Cc: FreeBSD-gnats-submit@FreeBSD.ORG Subject: Re: bin/5263: sh bug (with example) Date: Tue, 24 Mar 1998 11:14:32 +0100 In <199712100201.SAA14215@shell.uniserve.com>, tom@sdf.com wrote: > sh has a problem with joining lists within a "for x in list1:list2" > construct. Basically, the last element of list1 gets attached to > the remaining elements of list2, and this thing gets returned as > single item. > #! /bin/sh > > PATH=/bin:/usr/bin:/sbin > > # The whitespace below is a space followed by a tab > IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" > for ac_dir in $PATH:/usr/local/bin$ac_dummy; do > echo "ac_dir is $ac_dir" > done > > > When run under /bin/sh this script produces: > > ac_dir is /bin > ac_dir is /usr/bin > ac_dir is /sbin:/usr/local/bin > > When run under bash this script produces: > > ac_dir is /bin > ac_dir is /usr/bin > ac_dir is /sbin > ac_dir is /usr/local/bin The appended diff fixes this particular problem. It is an ugly one, I didn't even attempt to understand sh's regular IFS handling. I'm not going to commit it (unless we officially give up clean fixing of /bin/sh :-] ). BUT I welcome feedback. I'm not that much of an /bin/sh (script) programmer, I'd like to know what other cases are being broken by this hack. Especially, I'd like to get example scripts where $IFS is used in places where normal words are expected (like in this for loop construct). So please give it a try and keep me updated, I want to gain better understanding of sh syntax issues. > This is a big problem for ports, as auto-conf configure scripts > often use for loops like this to scan for certain binaries. In the particular case of GNU configure, I strongly reccommend using an intermediate variable: foobar=$PATH:/usr/local/bin$ac_dummy for ac_dir in $foobar; do echo "ac_dir is $ac_dir" done This works fine in our sh. pdksh has the same problem as our sh, and I'm sure there are more sh variants that have. The word list of a for-loop statement is easy to consider non-IFS-affected. I think a highly portable, reusable package like autoconf should take the extra work, although the problems are not its fault. Tom, are you in any way assosicated with the autoconf maintainers and could approach them for an opinion? Martin -- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Martin Cracauer http://www.cons.org/cracauer BSD User Group Hamburg, Germany http://www.bsdhh.org/ diff -r -c bin/sh.current.original/parser.c bin/sh.deleteme/parser.c *** bin/sh.current.original/parser.c Tue Aug 26 11:11:10 1997 --- bin/sh.deleteme/parser.c Tue Mar 24 10:38:36 1998 *************** *** 211,216 **** --- 211,218 ---- pungetc(); /* push back EOF on input */ return n1; default: + + if (nlflag) synexpect(-1); tokpushback++; *************** *** 916,924 **** setprompt(0); c = pgetc(); goto loop; /* continue outer loop */ - case CWORD: - USTPUTC(c, out); - break; case CCTL: if (eofmark == NULL || dblquote) USTPUTC(CTLESC, out); --- 918,923 ---- *************** *** 1004,1009 **** --- 1003,1018 ---- break; case CEOF: goto endword; /* exit outer loop */ + case CWORD: + if (strchr(ifsval(),c) && + syntax == BASESYNTAX) { + if (varnest == 0) { + c = pgetc_macro(); + goto endword; /* exit outer loop */ + } + } + USTPUTC(c, out); + break; default: if (varnest == 0) goto endword; /* exit outer loop */ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message