From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17747 invoked by alias); 27 Jan 2016 06:55:33 -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: 37810 Received: (qmail 26289 invoked from network); 27 Jan 2016 06:55:30 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brasslantern-com.20150623.gappssmtp.com; s=20150623; h=from:message-id:date:in-reply-to:comments:references:to:subject :mime-version:content-type; bh=enTz9KnPFynYP4CccOuYWJESrkz0puPWEo4aOuiMZjE=; b=c0CgL93VEehBJgaBvXi7SgoFRxTrQT0Q3lO7o339rJbA2rQBv9joVNkLuQLJqSmer8 TrDDtj8hwzc6iWZRkgs7ra0cH+/6R5G12kg7V1x3tZhl25iJzcbep6AlsphoaAdSFneg u7IlAXAXIMfHEc7i/RF/mpuGWxMhf6JhMixXeRJgw8Qkf207AETarWXmqHqFS1PaUHtx U147fibpWA23Qk1jMF/Bkw7eosPd4DWAnILr6xPwXjde8r+VtdviFFtAopmlfS+tyWN6 nKXioyAVKUlvURTdbyYfVF9oHRr4waD/lYrwlF0hT8q0Mgb+5JSCgchjjDFWiqEngr+P mizw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:message-id:date:in-reply-to:comments :references:to:subject:mime-version:content-type; bh=enTz9KnPFynYP4CccOuYWJESrkz0puPWEo4aOuiMZjE=; b=jat4u/DxR/JScOvGYNCVx3SD7cjHbNEDCgfP9cY2uv2NE4IYQCBqbHu4Y7sDEfFAHf bmjdMMJ1/O/lYVyBWusiupvpflJZz2/thuwdvSyYq49Az2//yPx3uLSUGT19OrH49iXo RChfEKuL1ut6QcjeerIkFuWXxrR0np4tGee52N5CmWf2FObqHEgThXwGl89zWj0HZEA6 3Y6eyEk4Ld3JWGpYVggYaKdRKK4HMRHklZR6Fhu4Y0xiGuxWMRHWHKi5s+QceCWhSx8a TP2sDdKFnNyKgOVmnxAPvYWaQ0hVIUHPOderkrAjMX25vSN5qLXpXjM4t/lZT5lChqzR p1WA== X-Gm-Message-State: AG10YORYf44YawMVHkKZ57qqLrFW5pZzAV2P9Sk5Ce/yrJwQR1m4YLXl9GnR6dnv141XJQ== X-Received: by 10.98.44.66 with SMTP id s63mr40498957pfs.2.1453877726521; Tue, 26 Jan 2016 22:55:26 -0800 (PST) From: Bart Schaefer Message-Id: <160126225609.ZM3651@torch.brasslantern.com> Date: Tue, 26 Jan 2016 22:56:09 -0800 In-Reply-To: Comments: In reply to Sebastian Gniazdowski "Re: Advanced option parsing across zsh commands" (Jan 26, 7:59pm) References: <160126102847.ZM18281@torch.brasslantern.com> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: Zsh hackers list Subject: Re: Advanced option parsing across zsh commands MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii On Jan 26, 7:59pm, Sebastian Gniazdowski wrote: } Subject: Re: Advanced option parsing across zsh commands } } > zparseopts also doesn't handle "negated options" in the +X format } } This sounded like if there would a workaround for +X. I tried the } following: define option "+", which takes argument. Then replace "+X" } with "-+X" in the command line. However: } } % zparseopts -A opts -D -E b: c +: That does not define an option "+" which takes an argument. That in fact defines an option (empty string) which may be repeated multiple times and takes an argument, because the "+" invokes the NAME+ form of option description. There's not a lot of internal consistency checking in zparseopts. Old code that has not been reviewed since it was written. To define an option named "+" instead of an option named "", you are intended to use: zparseopts -A opts -D -E b: c '\+:' However, because of a bug, you can't actually do that. The backslash causes everything after it to shift one character to the left, but the NUL-terminator is not also shifted, so the above accidentally defines the option "++" instead of the option "+". torch% typeset -A opts torch% set -- a -b something -++X -- -c torch% zparseopts -A opts -D -E b: c \\+: torch% print -lr -- $@ a -- -c torch% print -r -- ${(kv)opts} -b something -++ X torch% With the patch below, the very first character of the option spec is always taken to be part of the option name (unless that first char is is a backslash, in which case it is shifted off as usual). So you no longer need to escape a "+" (though it doesn't hurt to do so): torch% typeset -A opts torch% set -- a -b something -+X -- -c torch% zparseopts -A opts -D -E b: c +: torch% print -r -- ${(kv)opts} -b something -+ X And using "++" does the expected thing: torch% typeset -A opts=() torch% set -- a -b something -+X -+Y -+Z -- -c torch% zparseopts -A opts -D -E b: c ++: torch% print -r -- ${(kv)opts} -b something -+ XYZ torch% For pre-5.3 zsh I suggest you use a different character than "+" for your proposed workaround, e.g. set -- a -b something -\*X -\*Y -\*Z -- -c zparseopts -A opts -D -E b: c '*+:' should work. diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c index d98028a..12a4c03 100644 --- a/Src/Modules/zutil.c +++ b/Src/Modules/zutil.c @@ -1745,13 +1745,15 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) for (p = o; *p; p++) { if (*p == '\\' && p[1]) p++; - else if (*p == '+') { - f |= ZOF_MULT; - *p = '\0'; - p++; - break; - } else if (*p == ':' || *p == '=') - break; + else if (p > o) { /* At least one character of option name */ + if (*p == '+') { + f |= ZOF_MULT; + *p = '\0'; + p++; + break; + } else if (*p == ':' || *p == '=') + break; + } } if (*p == ':') { f |= ZOF_ARG; @@ -1789,6 +1791,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) p++; *n++ = *p; } + *n = '\0'; if (get_opt_desc(o)) { zwarnnam(nam, "option defined more than once: %s", o); return 1;