mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-21 00:01:26 +01:00
21655: bug in ${..//../${..//../..}}
This commit is contained in:
parent
5e803c0fcf
commit
b0ca393c47
3 changed files with 36 additions and 23 deletions
|
@ -1,3 +1,9 @@
|
|||
2005-08-18 Peter Stephenson <pws@pwstephenson.fsnet.co.uk>
|
||||
|
||||
* 21655: Src/glob.c, Test/D04parameter.ztst: replacing multiple
|
||||
matches where the replacement string itself came from a match
|
||||
could get confused.
|
||||
|
||||
2005-08-17 Wayne Davison <wayned@users.sourceforge.net>
|
||||
|
||||
* 21654: Src/string.c, Src/utils.c: Marked some ifdef/endif lines
|
||||
|
|
45
Src/glob.c
45
Src/glob.c
|
@ -2000,15 +2000,6 @@ struct repldata {
|
|||
};
|
||||
typedef struct repldata *Repldata;
|
||||
|
||||
/*
|
||||
* List of bits of matches to concatenate with replacement string.
|
||||
* The data is a struct repldata. It is not used in cases like
|
||||
* ${...//#foo/bar} even though SUB_GLOBAL is set, since the match
|
||||
* is anchored. It goes on the heap.
|
||||
*/
|
||||
|
||||
static LinkList repllist;
|
||||
|
||||
/* Having found a match in getmatch, decide what part of string
|
||||
* to return. The matched part starts b characters into string s
|
||||
* and finishes e characters in: 0 <= b <= e <= strlen(s)
|
||||
|
@ -2020,7 +2011,8 @@ static LinkList repllist;
|
|||
|
||||
/**/
|
||||
static char *
|
||||
get_match_ret(char *s, int b, int e, int fl, char *replstr)
|
||||
get_match_ret(char *s, int b, int e, int fl, char *replstr,
|
||||
LinkList repllist)
|
||||
{
|
||||
char buf[80], *r, *p, *rr;
|
||||
int ll = 0, l = strlen(s), bl = 0, t = 0, i;
|
||||
|
@ -2230,8 +2222,13 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
|
|||
* lengths.
|
||||
*/
|
||||
int ioff, l = strlen(*sp), uml = ztrlen(*sp), matched = 1, umlen;
|
||||
|
||||
repllist = NULL;
|
||||
/*
|
||||
* List of bits of matches to concatenate with replacement string.
|
||||
* The data is a struct repldata. It is not used in cases like
|
||||
* ${...//#foo/bar} even though SUB_GLOBAL is set, since the match
|
||||
* is anchored. It goes on the heap.
|
||||
*/
|
||||
static LinkList repllist = NULL;
|
||||
|
||||
/* perform must-match test for complex closures */
|
||||
if (p->mustoff)
|
||||
|
@ -2254,7 +2251,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
|
|||
|
||||
if (fl & SUB_ALL) {
|
||||
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, repllist);
|
||||
if (! **sp && (((fl & SUB_MATCH) && !i) || ((fl & SUB_REST) && i)))
|
||||
return 0;
|
||||
return 1;
|
||||
|
@ -2283,7 +2280,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
|
|||
}
|
||||
}
|
||||
}
|
||||
*sp = get_match_ret(*sp, 0, mlen, fl, replstr);
|
||||
*sp = get_match_ret(*sp, 0, mlen, fl, replstr, repllist);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
@ -2298,7 +2295,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
|
|||
t--;
|
||||
set_pat_start(p, t-s);
|
||||
if (pattrylen(p, t, s + l - t, umlen, ioff)) {
|
||||
*sp = get_match_ret(*sp, t - s, l, fl, replstr);
|
||||
*sp = get_match_ret(*sp, t - s, l, fl, replstr, repllist);
|
||||
return 1;
|
||||
}
|
||||
if (t > s+1 && t[-2] == Meta)
|
||||
|
@ -2314,7 +2311,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
|
|||
ioff++, METAINC(t), umlen--) {
|
||||
set_pat_start(p, t-s);
|
||||
if (pattrylen(p, t, s + l - t, umlen, ioff)) {
|
||||
*sp = get_match_ret(*sp, t-s, l, fl, replstr);
|
||||
*sp = get_match_ret(*sp, t-s, l, fl, replstr, repllist);
|
||||
return 1;
|
||||
}
|
||||
if (*t == Meta)
|
||||
|
@ -2326,7 +2323,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
|
|||
/* Smallest at start, but matching substrings. */
|
||||
set_pat_start(p, l);
|
||||
if (!(fl & SUB_GLOBAL) && pattry(p, s + l) && !--n) {
|
||||
*sp = get_match_ret(*sp, 0, 0, fl, replstr);
|
||||
*sp = get_match_ret(*sp, 0, 0, fl, replstr, repllist);
|
||||
return 1;
|
||||
} /* fall through */
|
||||
case (SUB_SUBSTR|SUB_LONG):
|
||||
|
@ -2357,7 +2354,8 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
|
|||
}
|
||||
}
|
||||
if (!--n || (n <= 0 && (fl & SUB_GLOBAL))) {
|
||||
*sp = get_match_ret(*sp, t-s, mpos-s, fl, replstr);
|
||||
*sp = get_match_ret(*sp, t-s, mpos-s, fl,
|
||||
replstr, repllist);
|
||||
if (mpos == t)
|
||||
METAINC(mpos);
|
||||
}
|
||||
|
@ -2396,7 +2394,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
|
|||
set_pat_start(p, l);
|
||||
if ((fl & (SUB_LONG|SUB_GLOBAL)) == SUB_LONG &&
|
||||
pattry(p, s + l) && !--n) {
|
||||
*sp = get_match_ret(*sp, 0, 0, fl, replstr);
|
||||
*sp = get_match_ret(*sp, 0, 0, fl, replstr, repllist);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
@ -2407,7 +2405,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
|
|||
if (!(fl & SUB_LONG)) {
|
||||
set_pat_start(p, l);
|
||||
if (pattrylen(p, s + l, 0, 0, uml) && !--n) {
|
||||
*sp = get_match_ret(*sp, l, l, fl, replstr);
|
||||
*sp = get_match_ret(*sp, l, l, fl, replstr, repllist);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -2431,13 +2429,14 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
|
|||
}
|
||||
}
|
||||
}
|
||||
*sp = get_match_ret(*sp, t-s, mpos-s, fl, replstr);
|
||||
*sp = get_match_ret(*sp, t-s, mpos-s, fl,
|
||||
replstr, repllist);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
set_pat_start(p, l);
|
||||
if ((fl & SUB_LONG) && pattrylen(p, s + l, 0, 0, uml) && !--n) {
|
||||
*sp = get_match_ret(*sp, l, l, fl, replstr);
|
||||
*sp = get_match_ret(*sp, l, l, fl, replstr, repllist);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
@ -2478,7 +2477,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
|
|||
}
|
||||
|
||||
/* munge the whole string: no match, so no replstr */
|
||||
*sp = get_match_ret(*sp, 0, 0, fl, 0);
|
||||
*sp = get_match_ret(*sp, 0, 0, fl, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -604,3 +604,11 @@
|
|||
print "${${foo}/?*/replacement}"
|
||||
0:Quoted zero-length strings are handled properly
|
||||
>
|
||||
|
||||
file=aleftkept
|
||||
print ${file//(#b)(*)left/${match/a/andsome}}
|
||||
print ${file//(#b)(*)left/${match//a/andsome}}
|
||||
0:Substitutions where $match is itself substituted in the replacement
|
||||
>andsomekept
|
||||
>andsomekept
|
||||
|
||||
|
|
Loading…
Reference in a new issue