1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-27 18:21:10 +02:00

20500: Unmetafy patterns where possible and other minor pattern fixes

This commit is contained in:
Peter Stephenson 2004-10-18 11:56:14 +00:00
parent bc704ef05c
commit b115ca307a
7 changed files with 538 additions and 249 deletions

View file

@ -1,3 +1,11 @@
2004-10-18 Peter Stephenson <pws@csr.com>
* 20500: Misc/globtests, Src/glob.c, Src/pattern.c, Src/zsh.h,
Src/Zle/complist.c, Test/D02glob.ztst: Use unmetafied strings
in patterns more; improve glob.c/pattern.c interface; fix
minor <num-> issue; add bogus quotation from Proust (it's
my file and I'll do what I like with it).
2004-10-17 Wayne Davison <wayned@users.sourceforge.net> 2004-10-17 Wayne Davison <wayned@users.sourceforge.net>
* 20496: Src/utils.c: made zclose() not call close() when the * 20496: Src/utils.c: made zclose() not call close() when the

View file

@ -134,6 +134,9 @@ t 633 <1-1000>33
t 633 <-1000>33 t 633 <-1000>33
t 633 <1->33 t 633 <1->33
t 633 <->33 t 633 <->33
# An open top end of a range will match any integer, even
# if not representable in the internal integer type.
t 12345678901234567890123456789012345678901234567890123456789012345678901234567890foo <42->foo
# Approximate matching # Approximate matching
t READ.ME (#ia1)readme t READ.ME (#ia1)readme
f READ..ME (#ia1)readme f READ..ME (#ia1)readme

View file

@ -601,7 +601,7 @@ putmatchcol(Listcols c, char *group, char *n)
for (pc = c->pats; pc; pc = pc->next) for (pc = c->pats; pc; pc = pc->next)
if ((!pc->prog || !group || pattry(pc->prog, group)) && if ((!pc->prog || !group || pattry(pc->prog, group)) &&
pattryrefs(pc->pat, n, &nrefs, begpos, endpos)) { pattryrefs(pc->pat, n, -1, 0, &nrefs, begpos, endpos)) {
if (pc->cols[1]) { if (pc->cols[1]) {
patcols = pc->cols; patcols = pc->cols;
@ -639,7 +639,7 @@ putfilecol(Listcols c, char *group, char *n, mode_t m)
for (pc = c->pats; pc; pc = pc->next) for (pc = c->pats; pc; pc = pc->next)
if ((!pc->prog || !group || pattry(pc->prog, group)) && if ((!pc->prog || !group || pattry(pc->prog, group)) &&
pattryrefs(pc->pat, n, &nrefs, begpos, endpos)) { pattryrefs(pc->pat, n, -1, 0, &nrefs, begpos, endpos)) {
if (pc->cols[1]) { if (pc->cols[1]) {
patcols = pc->cols; patcols = pc->cols;

View file

@ -2195,8 +2195,13 @@ set_pat_end(Patprog p, char null_me)
static int static int
igetmatch(char **sp, Patprog p, int fl, int n, char *replstr) igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
{ {
char *s = *sp, *t, sav; char *s = *sp, *t;
int i, l = strlen(*sp), ml = ztrlen(*sp), matched = 1; /*
* Note that ioff and ml count characters in the character
* set (Meta's are not included), while l counts characters in the
* string.
*/
int ioff, l = strlen(*sp), ml = ztrlen(*sp), matched = 1;
repllist = NULL; repllist = NULL;
@ -2208,7 +2213,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
p->flags &= ~(PAT_NOTSTART|PAT_NOTEND); p->flags &= ~(PAT_NOTSTART|PAT_NOTEND);
if (fl & SUB_ALL) { if (fl & SUB_ALL) {
i = matched && pattry(p, s); int i = matched && pattry(p, s);
*sp = get_match_ret(*sp, 0, i ? l : 0, fl, i ? replstr : 0); *sp = get_match_ret(*sp, 0, i ? l : 0, fl, i ? replstr : 0);
if (! **sp && (((fl & SUB_MATCH) && !i) || ((fl & SUB_REST) && i))) if (! **sp && (((fl & SUB_MATCH) && !i) || ((fl & SUB_REST) && i)))
return 0; return 0;
@ -2223,25 +2228,22 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
* First get the longest match... * First get the longest match...
*/ */
if (pattry(p, s)) { if (pattry(p, s)) {
char *mpos = patinput; /* patmatchlen returns metafied length, as we need */
int mlen = patmatchlen();
if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) { if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) {
/* /*
* ... now we know whether it's worth looking for the * ... now we know whether it's worth looking for the
* shortest, which we do by brute force. * shortest, which we do by brute force.
*/ */
for (t = s; t < mpos; METAINC(t)) { for (t = s; t < s + mlen; METAINC(t)) {
sav = *t; set_pat_end(p, *t);
set_pat_end(p, sav); if (pattrylen(p, s, t - s, 0)) {
*t = '\0'; mlen = patmatchlen();
if (pattry(p, s)) {
mpos = patinput;
*t = sav;
break; break;
} }
*t = sav;
} }
} }
*sp = get_match_ret(*sp, 0, mpos-s, fl, replstr); *sp = get_match_ret(*sp, 0, mlen, fl, replstr);
return 1; return 1;
} }
break; break;
@ -2250,35 +2252,30 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
/* Smallest possible match at tail of string: * /* Smallest possible match at tail of string: *
* move back down string until we get a match. * * move back down string until we get a match. *
* There's no optimization here. */ * There's no optimization here. */
patoffset = ml; for (ioff = ml, t = s + l; t >= s; t--, ioff--) {
for (t = s + l; t >= s; t--, patoffset--) {
set_pat_start(p, t-s); set_pat_start(p, t-s);
if (pattry(p, t)) { if (pattrylen(p, t, -1, ioff)) {
*sp = get_match_ret(*sp, t - s, l, fl, replstr); *sp = get_match_ret(*sp, t - s, l, fl, replstr);
patoffset = 0;
return 1; return 1;
} }
if (t > s+1 && t[-2] == Meta) if (t > s+1 && t[-2] == Meta)
t--; t--;
} }
patoffset = 0;
break; break;
case (SUB_END|SUB_LONG): case (SUB_END|SUB_LONG):
/* Largest possible match at tail of string: * /* Largest possible match at tail of string: *
* move forward along string until we get a match. * * move forward along string until we get a match. *
* Again there's no optimisation. */ * Again there's no optimisation. */
for (i = 0, t = s; i < l; i++, t++, patoffset++) { for (ioff = 0, t = s; t < s + l; ioff++, t++) {
set_pat_start(p, t-s); set_pat_start(p, t-s);
if (pattry(p, t)) { if (pattrylen(p, t, -1, ioff)) {
*sp = get_match_ret(*sp, i, l, fl, replstr); *sp = get_match_ret(*sp, t-s, l, fl, replstr);
patoffset = 0;
return 1; return 1;
} }
if (*t == Meta) if (*t == Meta)
i++, t++; t++;
} }
patoffset = 0;
break; break;
case SUB_SUBSTR: case SUB_SUBSTR:
@ -2293,26 +2290,23 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
t = s; t = s;
if (fl & SUB_GLOBAL) if (fl & SUB_GLOBAL)
repllist = newlinklist(); repllist = newlinklist();
ioff = 0; /* offset into string */
do { do {
/* loop over all matches for global substitution */ /* loop over all matches for global substitution */
matched = 0; matched = 0;
for (; t < s + l; t++, patoffset++) { for (; t < s + l; t++, ioff++) {
/* Find the longest match from this position. */ /* Find the longest match from this position. */
set_pat_start(p, t-s); set_pat_start(p, t-s);
if (pattry(p, t)) { if (pattrylen(p, t, -1, ioff)) {
char *mpos = patinput; char *mpos = t + patmatchlen();
if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) { if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) {
char *ptr; char *ptr;
for (ptr = t; ptr < mpos; METAINC(ptr)) { for (ptr = t; ptr < mpos; METAINC(ptr)) {
sav = *ptr; set_pat_end(p, *ptr);
set_pat_end(p, sav); if (pattrylen(p, t, ptr - t, ioff)) {
*ptr = '\0'; mpos = t + patmatchlen();
if (pattry(p, t)) {
mpos = patinput;
*ptr = sav;
break; break;
} }
*ptr = sav;
} }
} }
if (!--n || (n <= 0 && (fl & SUB_GLOBAL))) { if (!--n || (n <= 0 && (fl & SUB_GLOBAL))) {
@ -2330,7 +2324,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
*/ */
continue; continue;
} else { } else {
patoffset = 0;
return 1; return 1;
} }
} }
@ -2339,7 +2332,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
* which is already marked for replacement. * which is already marked for replacement.
*/ */
matched = 1; matched = 1;
for ( ; t < mpos; t++, patoffset++) for ( ; t < mpos; t++, ioff++)
if (*t == Meta) if (*t == Meta)
t++; t++;
break; break;
@ -2348,7 +2341,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
t++; t++;
} }
} while (matched); } while (matched);
patoffset = 0;
/* /*
* check if we can match a blank string, if so do it * check if we can match a blank string, if so do it
* at the start. Goodness knows if this is a good idea * at the start. Goodness knows if this is a good idea
@ -2365,50 +2357,39 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
case (SUB_END|SUB_SUBSTR): case (SUB_END|SUB_SUBSTR):
case (SUB_END|SUB_LONG|SUB_SUBSTR): case (SUB_END|SUB_LONG|SUB_SUBSTR):
/* Longest/shortest at end, matching substrings. */ /* Longest/shortest at end, matching substrings. */
patoffset = ml;
if (!(fl & SUB_LONG)) { if (!(fl & SUB_LONG)) {
set_pat_start(p, l); set_pat_start(p, l);
if (pattry(p, s + l) && !--n) { if (pattrylen(p, s + l, -1, ml) && !--n) {
*sp = get_match_ret(*sp, l, l, fl, replstr); *sp = get_match_ret(*sp, l, l, fl, replstr);
patoffset = 0;
return 1; return 1;
} }
} }
patoffset--; for (ioff = ml - 1, t = s + l - 1; t >= s; t--, ioff--) {
for (t = s + l - 1; t >= s; t--, patoffset--) {
if (t > s && t[-1] == Meta) if (t > s && t[-1] == Meta)
t--; t--;
set_pat_start(p, t-s); set_pat_start(p, t-s);
if (pattry(p, t) && !--n) { if (pattrylen(p, t, -1, ioff) && !--n) {
/* Found the longest match */ /* Found the longest match */
char *mpos = patinput; char *mpos = t + patmatchlen();
if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) { if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) {
char *ptr; char *ptr;
for (ptr = t; ptr < mpos; METAINC(ptr)) { for (ptr = t; ptr < mpos; METAINC(ptr)) {
sav = *ptr; set_pat_end(p, *ptr);
set_pat_end(p, sav); if (pattrylen(p, t, ptr - t, ioff)) {
*ptr = '\0'; mpos = t + patmatchlen();
if (pattry(p, t)) {
mpos = patinput;
*ptr = sav;
break; break;
} }
*ptr = sav;
} }
} }
*sp = get_match_ret(*sp, t-s, mpos-s, fl, replstr); *sp = get_match_ret(*sp, t-s, mpos-s, fl, replstr);
patoffset = 0;
return 1; return 1;
} }
} }
patoffset = ml;
set_pat_start(p, l); set_pat_start(p, l);
if ((fl & SUB_LONG) && pattry(p, s + l) && !--n) { if ((fl & SUB_LONG) && pattrylen(p, s + l, -1, ml) && !--n) {
*sp = get_match_ret(*sp, l, l, fl, replstr); *sp = get_match_ret(*sp, l, l, fl, replstr);
patoffset = 0;
return 1; return 1;
} }
patoffset = 0;
break; break;
} }
} }
@ -2419,6 +2400,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
Repldata rd; Repldata rd;
int lleft = 0; /* size of returned string */ int lleft = 0; /* size of returned string */
char *ptr, *start; char *ptr, *start;
int i;
i = 0; /* start of last chunk we got from *sp */ i = 0; /* start of last chunk we got from *sp */
for (nd = firstnode(repllist); nd; incnode(nd)) { for (nd = firstnode(repllist); nd; incnode(nd)) {

File diff suppressed because it is too large Load diff

View file

@ -1088,10 +1088,10 @@ struct patprog {
long startoff; /* length before start of programme */ long startoff; /* length before start of programme */
long size; /* total size from start of struct */ long size; /* total size from start of struct */
long mustoff; /* offset to string that must be present */ long mustoff; /* offset to string that must be present */
long patmlen; /* length of pure string or longest match */
int globflags; /* globbing flags to set at start */ int globflags; /* globbing flags to set at start */
int globend; /* globbing flags set after finish */ int globend; /* globbing flags set after finish */
int flags; /* PAT_* flags */ int flags; /* PAT_* flags */
int patmlen; /* length of pure string or longest match */
int patnpar; /* number of active parentheses */ int patnpar; /* number of active parentheses */
char patstartch; char patstartch;
}; };

View file

@ -132,6 +132,7 @@
>0: [[ 633 = <-1000>33 ]] >0: [[ 633 = <-1000>33 ]]
>0: [[ 633 = <1->33 ]] >0: [[ 633 = <1->33 ]]
>0: [[ 633 = <->33 ]] >0: [[ 633 = <->33 ]]
>0: [[ 12345678901234567890123456789012345678901234567890123456789012345678901234567890foo = <42->foo ]]
>0: [[ READ.ME = (#ia1)readme ]] >0: [[ READ.ME = (#ia1)readme ]]
>1: [[ READ..ME = (#ia1)readme ]] >1: [[ READ..ME = (#ia1)readme ]]
>0: [[ README = (#ia1)readm ]] >0: [[ README = (#ia1)readm ]]