From owner-svn-src-all@FreeBSD.ORG Mon Aug 23 21:58:52 2010 Return-Path: Delivered-To: svn-src-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BE527106567A; Mon, 23 Aug 2010 21:58:52 +0000 (UTC) (envelope-from jilles@stack.nl) Received: from mx1.stack.nl (relay04.stack.nl [IPv6:2001:610:1108:5010::107]) by mx1.freebsd.org (Postfix) with ESMTP id 836AC8FC15; Mon, 23 Aug 2010 21:58:52 +0000 (UTC) Received: from turtle.stack.nl (turtle.stack.nl [IPv6:2001:610:1108:5010::132]) by mx1.stack.nl (Postfix) with ESMTP id C2D001DD687; Mon, 23 Aug 2010 23:58:50 +0200 (CEST) Received: by turtle.stack.nl (Postfix, from userid 1677) id B71E81721B; Mon, 23 Aug 2010 23:58:50 +0200 (CEST) Date: Mon, 23 Aug 2010 23:58:50 +0200 From: Jilles Tjoelker To: Brian Somers Message-ID: <20100823215850.GC67671@stack.nl> References: <201008221104.o7MB4Ung001538@svn.freebsd.org> <20100823003314.57d41b94@dev.lan.Awfulhak.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20100823003314.57d41b94@dev.lan.Awfulhak.org> User-Agent: Mutt/1.5.20 (2009-06-14) Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org Subject: Re: svn commit: r211609 - head/tools/regression/bin/sh/builtins X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Aug 2010 21:58:52 -0000 On Mon, Aug 23, 2010 at 12:33:14AM -0700, Brian Somers wrote: > On Sun, 22 Aug 2010 11:04:30 +0000 (UTC) Jilles Tjoelker wrote: > > Author: jilles > > Date: Sun Aug 22 11:04:30 2010 > > New Revision: 211609 > > URL: http://svn.freebsd.org/changeset/base/211609 > > Log: > > sh: Add a test for breaking from a loop outside the current function. > > It is unwise to rely on this but I'd like to know if this would break. > > Added: > > head/tools/regression/bin/sh/builtins/break3.0 (contents, props changed) > > Added: head/tools/regression/bin/sh/builtins/break3.0 > > ============================================================================== > > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > > +++ head/tools/regression/bin/sh/builtins/break3.0 Sun Aug 22 11:04:30 2010 (r211609) > > @@ -0,0 +1,15 @@ > > +# $FreeBSD$ > > + > > +# We accept this and people might rely on it. > > +# However, various other shells do not accept it. > > + > > +f() { > > + break > > + echo bad1 > > +} > > + > > +while :; do > > + f > > + echo bad2 > > + exit 2 > > +done > This feature should be counted as a bug IMHO. How can f() possibly > know whether there's a surrounding context to break from? If you replace f by its definition, there is an obvious meaning. And how about a script like: while :; do f() { ...; break; ...; } ... f ... done I will admit that there are various other shells that do not implement this. > Having said that, this behaviour is the same in bash except that bash > will complain if it's asked to break when the context is wrong, > perhaps we should complain too? > $ bash -c 'f() { break; echo no break; }; for f in good bad; do echo $f; f; done' > good > $ sh -c 'f() { break; echo no break; }; for f in good bad; do echo $f; f; done' > good > $ bash -c 'f() { break; echo no break; }; f' > bash: line 0: break: only meaningful in a `for', `while', or `until' loop > no break > $ bash -c 'f() { break 2>/dev/null; echo no break; }; f' > no break > $ sh -c 'f() { break; echo no break; }; f' > no break The System V sh and ksh93 behave the same way with break and continue builtins outside loops. I don't think this is very broken, and there is a limit on how many incompatible changes I'm willing to make. This doesn't make the cut. Warning messages to stderr mostly get lost in the noise, I don't really like them. I do not expect people to test for failure of break and continue, and bash even sets $? to 0 despite printing a warning. If this error is so important as to need an error message I think should abort the shell as well (via error(), so that "command break" will avoid aborting). Furthermore note that bash disables these warnings in POSIX mode. As an aside, if breaking out of a function were to be disallowed, a stronger approach seems possible: special builtins cannot be overridden by functions or PATH (we currently do not implement this), so if the parser (after alias expansion) sees a command "break" or "continue", it must be the special builtin and a parse error could result if it is not in a loop, or possibly a ksh93-like parse warning with -n. -- Jilles Tjoelker