summaryrefslogtreecommitdiff
path: root/Src/glob.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2004-10-18 11:56:14 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2004-10-18 11:56:14 +0000
commitb115ca307adf7ef9dca13f6e7ce40768bc0b2b75 (patch)
tree64a7e6568c6f082ae52e2e28e342d82a9947ad29 /Src/glob.c
parentbc704ef05c532cff4a9ae49a22aa6cd35299cd5b (diff)
downloadzsh-b115ca307adf7ef9dca13f6e7ce40768bc0b2b75.tar.gz
zsh-b115ca307adf7ef9dca13f6e7ce40768bc0b2b75.zip
20500: Unmetafy patterns where possible and other minor pattern fixes
Diffstat (limited to 'Src/glob.c')
-rw-r--r--Src/glob.c94
1 files changed, 38 insertions, 56 deletions
diff --git a/Src/glob.c b/Src/glob.c
index 85111a190..84ee8a751 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -2195,8 +2195,13 @@ set_pat_end(Patprog p, char null_me)
static int
igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
{
- char *s = *sp, *t, sav;
- int i, l = strlen(*sp), ml = ztrlen(*sp), matched = 1;
+ char *s = *sp, *t;
+ /*
+ * 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;
@@ -2208,7 +2213,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
p->flags &= ~(PAT_NOTSTART|PAT_NOTEND);
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);
if (! **sp && (((fl & SUB_MATCH) && !i) || ((fl & SUB_REST) && i)))
return 0;
@@ -2223,25 +2228,22 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
* First get the longest match...
*/
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)) {
/*
* ... now we know whether it's worth looking for the
* shortest, which we do by brute force.
*/
- for (t = s; t < mpos; METAINC(t)) {
- sav = *t;
- set_pat_end(p, sav);
- *t = '\0';
- if (pattry(p, s)) {
- mpos = patinput;
- *t = sav;
+ for (t = s; t < s + mlen; METAINC(t)) {
+ set_pat_end(p, *t);
+ if (pattrylen(p, s, t - s, 0)) {
+ mlen = patmatchlen();
break;
}
- *t = sav;
}
}
- *sp = get_match_ret(*sp, 0, mpos-s, fl, replstr);
+ *sp = get_match_ret(*sp, 0, mlen, fl, replstr);
return 1;
}
break;
@@ -2250,35 +2252,30 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
/* Smallest possible match at tail of string: *
* move back down string until we get a match. *
* There's no optimization here. */
- patoffset = ml;
- for (t = s + l; t >= s; t--, patoffset--) {
+ for (ioff = ml, t = s + l; t >= s; t--, ioff--) {
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);
- patoffset = 0;
return 1;
}
if (t > s+1 && t[-2] == Meta)
t--;
}
- patoffset = 0;
break;
case (SUB_END|SUB_LONG):
/* Largest possible match at tail of string: *
* move forward along string until we get a match. *
* 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);
- if (pattry(p, t)) {
- *sp = get_match_ret(*sp, i, l, fl, replstr);
- patoffset = 0;
+ if (pattrylen(p, t, -1, ioff)) {
+ *sp = get_match_ret(*sp, t-s, l, fl, replstr);
return 1;
}
if (*t == Meta)
- i++, t++;
+ t++;
}
- patoffset = 0;
break;
case SUB_SUBSTR:
@@ -2293,26 +2290,23 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
t = s;
if (fl & SUB_GLOBAL)
repllist = newlinklist();
+ ioff = 0; /* offset into string */
do {
/* loop over all matches for global substitution */
matched = 0;
- for (; t < s + l; t++, patoffset++) {
+ for (; t < s + l; t++, ioff++) {
/* Find the longest match from this position. */
set_pat_start(p, t-s);
- if (pattry(p, t)) {
- char *mpos = patinput;
+ if (pattrylen(p, t, -1, ioff)) {
+ char *mpos = t + patmatchlen();
if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) {
char *ptr;
for (ptr = t; ptr < mpos; METAINC(ptr)) {
- sav = *ptr;
- set_pat_end(p, sav);
- *ptr = '\0';
- if (pattry(p, t)) {
- mpos = patinput;
- *ptr = sav;
+ set_pat_end(p, *ptr);
+ if (pattrylen(p, t, ptr - t, ioff)) {
+ mpos = t + patmatchlen();
break;
}
- *ptr = sav;
}
}
if (!--n || (n <= 0 && (fl & SUB_GLOBAL))) {
@@ -2330,7 +2324,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
*/
continue;
} else {
- patoffset = 0;
return 1;
}
}
@@ -2339,7 +2332,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
* which is already marked for replacement.
*/
matched = 1;
- for ( ; t < mpos; t++, patoffset++)
+ for ( ; t < mpos; t++, ioff++)
if (*t == Meta)
t++;
break;
@@ -2348,7 +2341,6 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
t++;
}
} while (matched);
- patoffset = 0;
/*
* check if we can match a blank string, if so do it
* 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_LONG|SUB_SUBSTR):
/* Longest/shortest at end, matching substrings. */
- patoffset = ml;
if (!(fl & SUB_LONG)) {
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);
- patoffset = 0;
return 1;
}
}
- patoffset--;
- for (t = s + l - 1; t >= s; t--, patoffset--) {
+ for (ioff = ml - 1, t = s + l - 1; t >= s; t--, ioff--) {
if (t > s && t[-1] == Meta)
t--;
set_pat_start(p, t-s);
- if (pattry(p, t) && !--n) {
+ if (pattrylen(p, t, -1, ioff) && !--n) {
/* Found the longest match */
- char *mpos = patinput;
+ char *mpos = t + patmatchlen();
if (!(fl & SUB_LONG) && !(p->flags & PAT_PURES)) {
char *ptr;
for (ptr = t; ptr < mpos; METAINC(ptr)) {
- sav = *ptr;
- set_pat_end(p, sav);
- *ptr = '\0';
- if (pattry(p, t)) {
- mpos = patinput;
- *ptr = sav;
+ set_pat_end(p, *ptr);
+ if (pattrylen(p, t, ptr - t, ioff)) {
+ mpos = t + patmatchlen();
break;
}
- *ptr = sav;
}
}
*sp = get_match_ret(*sp, t-s, mpos-s, fl, replstr);
- patoffset = 0;
return 1;
}
}
- patoffset = ml;
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);
- patoffset = 0;
return 1;
}
- patoffset = 0;
break;
}
}
@@ -2419,6 +2400,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
Repldata rd;
int lleft = 0; /* size of returned string */
char *ptr, *start;
+ int i;
i = 0; /* start of last chunk we got from *sp */
for (nd = firstnode(repllist); nd; incnode(nd)) {