From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19592 invoked by alias); 13 Jan 2015 21:34:58 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 34271 Received: (qmail 22734 invoked from network); 13 Jan 2015 21:34:56 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:content-type; bh=K2+pjiD9KBTw4VxV1PdzkzgojQCMKTlIb6F/3yq6A5k=; b=hrTspFapyMSwRvW0y55RjFS9W6Arw9jGgic5/cP8wfFClOrhiHSs9JY8wUsI1pE/9q Yuf8Hk0CuzYAYlVezO2gvlrE+HZGTCNo2SLo5mi47rsp2hCCgGkT+lE3ImfntbyTB8ch WXz7PP3p09m16xMKekbwynYdYU+f3h2+XjxkyYAhK8y7ki5nt488C4lvK8h/ZELermUE yTdVZjg6H3LT0FbV4p9YQECDGlIrHLnT0rgrilsGAQsKZZO24RvW2c0ypc8a3PDqH/RD d9ZSX/+R5kmx56Jn5ul1lkbm7jcnp5wdS4YxFVPsiqjGQ6bzMUfhF2+lbjt+OvoQpDt5 2z3A== X-Gm-Message-State: ALoCoQkH/ICt098wsgV560qfcqFe9mxxxNqMT2JaqQKrQsoJmCn4n6oFeaefU6BCnDXP4ZPytTga MIME-Version: 1.0 X-Received: by 10.194.86.135 with SMTP id p7mr672639wjz.89.1421184890444; Tue, 13 Jan 2015 13:34:50 -0800 (PST) In-Reply-To: References: Date: Tue, 13 Jan 2015 13:34:50 -0800 Message-ID: Subject: Re: OPTIND set incorrectly by getopts for options without arg From: Bart Schaefer To: Zsh hackers list Content-Type: text/plain; charset=UTF-8 Quoting a bit more than I normally would to keep the POSIX text ... jump to below. On Tue, Jan 13, 2015 at 12:38 PM, Simon Chiang wrote: > > func() { > OPTIND=1 # reset OPTIND each time in to prevent carryover > getopts a:b optvar > shift $(( OPTIND -1 )) > echo "$OPTIND, $1" > } > > func -a x y z > output: 3, y # this is the correct output > > func -b x y z > output: 1, -b # this is the questionable output > > > Turns out according to the POSIX spec this is a bug ( > http://pubs.opengroup.org/onlinepubs/000095399/utilities/getopts.html) > > When the end of options is encountered, the getopts utility shall exit with > a return value greater than zero; the shell > variable OPTIND shall be set to the index of the first > non-option-argument.... Any of the following shall identify the end of > options: the special option "--", finding an argument that does not begin > with a '-', or encountering an error. > > > Unless I'm misreading that means that in the first example "y" indicates > the end of options so the correct output is "3, y". In the second example > the "x" indicates the end of options so the correct output is "2, x". For > what it's worth bash and dash set OPTIND in this way. If you add an "echo $?" after the call to getopts in the example function, you will find that bash getopts has NOT "exit[ed] with a return value greater than zero". Neither has zsh getopts. In zsh, if you add a SECOND call to getopts in the example function, you will find that the second call DOES exit with a value of 1, and that WHEN zsh getopts exits with a return value greater than zero, THEN the value of OPTIND is set as POSIX specifies. The distinction is the definition of "When the end of options is encountered." Zsh does not "encounter" the "end of options" until the getopts call that actually attempts to "read past" the recognized options. You can see this better if you invoke the original example as "func -b -a x y z". Whether this is actually wrong or the spec is incomplete, I won't try to argue here.