Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Mar 1998 02:10:01 -0800 (PST)
From:      Martin Cracauer <cracauer@cons.org>
To:        freebsd-bugs
Subject:   Re: bin/5263: sh bug (with example)
Message-ID:  <199803241010.CAA03606@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/5263; it has been noted by GNATS.

From: Martin Cracauer <cracauer@cons.org>
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 <cracauer@cons.org> 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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199803241010.CAA03606>