On Sat, Mar 21, 2020 at 3:26 AM Jeff King <peff@xxxxxxxx> wrote: > > On Sat, Mar 21, 2020 at 12:07:05AM -0300, Matheus Tavares wrote: > > > In cases like this, CLIs usually allow the short options to be stacked > > in a single argument, for convenience and agility. Let's add this > > feature to test-lib, allowing the above command to be run as: > > Most getopt implementations I've seen call this "bundling" rather than > "stacking" (I don't care too much either way, but Junio mentioned being > confused at the name). Yeah, "stacking" wasn't the best word choice. I will replace it by "bundling" then, thanks. > > > + case "$opt" in > > + --*) > > + parse_option "$opt" ;; > > + -?*) > > + # stacked short options must be fed separately to parse_option > > + for c in $(echo "${opt#-}" | sed 's/./& /g') > > + do > > + parse_option "-$c" > > + done > > I wondered if we could do this without the extra process. This works: > > opt=${opt#-} > while test -n "$opt" > do > extra=${opt#?} > this=${opt%$extra} > opt=$extra > parse_option "-$this" > done > > It's a little convoluted. I'm not sure if saving a process per unbundled > short option is worth it. I quite liked this alternative with builtins. It's a little more verbose, but it remains very clear. > What happens to bundled short options with arguments? I think "-r" is > the only one. We don't allow "stuck" short options like "-r5", so we > don't have to worry about feeding non-option bits to parse_option(). It > looks like we'd only examine $store_arg_to outside of the short-option > loop, so we'd treat: > > ./t1234-foo.sh -vrix 5 > > the same as: > > ./t1234-foo.sh -v -r 5 -i -x Yes. I just thought, though, that if another "short option with arguments" gets added in the future, the bundle would not work correctly. I don't think we need to be prepared for such a scenario now, but ... > which seems reasonable. But: > > ./t1234-foo.sh -rr 5 6 > > would get garbled. ... we could prohibit using more than one "short option with arguments" in the same bundle. This would not only solve the problem for "-rr 5 6"[1] but also for the scenario of future new options. And it's quite simple to implement, we just have to check whether $store_arg_to is set before setting it to another value. I'll try that for v2. [1]: Someone that used '-rr 5 6' might have wanted the script to run *both* tests 5 and 6. But I don't think we need to support that now, since '-r 5 -r 6' doesn't do that as well (instead, the last value overrides all previous ones).