From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26746 invoked from network); 12 Jan 1998 11:30:04 -0000 Received: from math.gatech.edu (list@130.207.146.50) by ns1.primenet.com.au with SMTP; 12 Jan 1998 11:30:04 -0000 Received: (from list@localhost) by math.gatech.edu (8.8.5/8.8.5) id GAA15635; Mon, 12 Jan 1998 06:12:33 -0500 (EST) Resent-Date: Mon, 12 Jan 1998 06:12:33 -0500 (EST) Message-Id: <199801121113.MAA25513@sgi.ifh.de> To: zsh-workers@math.gatech.edu (Zsh hackers list), zsh@peak.org Subject: PATCH: zsh 3.x: <..> ranges in globbing In-reply-to: "Geoff Wing"'s message of "31 Dec 1997 06:17:43 MET." Date: Mon, 12 Jan 1998 12:13:47 +0100 From: Peter Stephenson Resent-Message-ID: <"0eHwa3.0.Eq3.XgVkq"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/3680 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu Geoff Wing wrote: > Geoff Wing typed: > :% touch 101 111 121 > :% ls <10-12>1 > :ls: <10-12>1: No such file or directory > :Now, it's obvious why it's failing, since 101, 111 & 121 don't match the > :10 to 12 range. My opinion is that it probably shouldn't fail in this case, > :but maybe a different operator or option/modifier should be used to get it > :to match. since there may be cases where someone wants to match on, say, > :``<1-50>foo'' and not get, say, ``100foo'' matching. > > ``<1-50>*oo'' and ``100foo'' might be better examples. This is the fix. This is entirely consistent with the way globbing usually works, I don't think a new operator is needed. If you want to make <1-50>*oo avoid matching 100foo, you will need <1-50>([^0-9]*|)oo (to be pedantic). I don't think it's fair to force to consider only all the digits present, since it's not consistent with the usual pattern rule 'use as many characters as possible without causing the match to fail', even if it is the current behaviour. Is anyone sure that they rely on <1-50>*oo not matching 100foo? The old behaviour is tantamount to making * not match 0foo, which is counterintuitive. As far as I can remember I've always been careful to anchor the end of a numeric range for just this reason, not realising there was a bug. You should probably note that <100->0foo won't match 1000foo, since the 1000 gets swallowed up before the shell even knows it's going to have to match another digit next. This is a much more difficult problem requiring backtracking. I could make a special case so that simple things like this work, but expressions like <100->(0|bar)foo would require much more fiddling. (Of course, <100-999>0foo works now.) *** Src/glob.c.range Mon Jan 12 10:41:46 1998 --- Src/glob.c Mon Jan 12 10:41:57 1998 *************** *** 2265,2270 **** --- 2265,2271 ---- } else { /* Flag that there is no upper limit */ int not3 = 0; + char *opptr = pptr; /* * Form is , where a or b are numbers or blank. * t1 = number supplied: must be positive, so use *************** *** 2284,2289 **** --- 2285,2299 ---- t3 = (unsigned long)zstrtol(ptr + 1, &pat, 10); DPUTS(*pat != Outang, "BUG: wrong internal range pattern"); pat++; + /* + * If the number found is too large for the pattern, + * try matching just the first part. This way + * we always get the longest possible match. + */ + while (!not3 && t1 > t3 && pptr > opptr+1) { + pptr--; + t1 /= 10; + } if (t1 < t2 || (!not3 && t1 > t3)) break; } -- Peter Stephenson Tel: +39 50 911239 WWW: http://www.ifh.de/~pws/ Gruppo Teorico, Dipartimento di Fisica Piazza Torricelli 2, 56100 Pisa, Italy