summaryrefslogtreecommitdiff
path: root/Src/glob.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/glob.c')
-rw-r--r--Src/glob.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/Src/glob.c b/Src/glob.c
index 623a50706..828f703d5 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -2056,6 +2056,39 @@ getmatcharr(char ***ap, char *pat, int fl, int n, char *replstr)
}
/**/
+static void
+set_pat_start(Patprog p, int offs)
+{
+ /*
+ * If we are messing around with the test string by advancing up
+ * it from the start, we need to tell the pattern matcher that
+ * a start-of-string assertion, i.e. (#s), should fail. Hence
+ * we test whether the offset of the real start of string from
+ * the actual start, passed as offs, is zero.
+ */
+ if (offs)
+ p->flags |= PAT_NOTSTART;
+ else
+ p->flags &= ~PAT_NOTSTART;
+}
+
+/**/
+static void
+set_pat_end(Patprog p, char null_me)
+{
+ /*
+ * If we are messing around with the string by shortening it at the
+ * tail, we need to tell the pattern matcher that an end-of-string
+ * assertion, i.e. (#e), should fail. Hence we test whether
+ * the character null_me about to be zapped is or is not already a null.
+ */
+ if (null_me)
+ p->flags |= PAT_NOTEND;
+ else
+ p->flags &= ~PAT_NOTEND;
+}
+
+/**/
static int
igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
{
@@ -2068,6 +2101,9 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
if (p->mustoff && !strstr((char *)s, (char *)p + p->mustoff))
matched = 0;
+ /* in case we used the prog before... */
+ p->flags &= ~(PAT_NOTSTART|PAT_NOTEND);
+
if (fl & SUB_ALL) {
i = matched && pattry(p, s);
*sp = get_match_ret(*sp, 0, i ? l : 0, fl, i ? replstr : 0);
@@ -2092,6 +2128,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
*/
for (t = s; t < mpos; METAINC(t)) {
sav = *t;
+ set_pat_end(p, sav);
*t = '\0';
if (pattry(p, s)) {
mpos = patinput;
@@ -2112,6 +2149,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
* There's no optimization here. */
patoffset = ml;
for (t = s + l; t >= s; t--, patoffset--) {
+ set_pat_start(p, t-s);
if (pattry(p, t)) {
*sp = get_match_ret(*sp, t - s, l, fl, replstr);
patoffset = 0;
@@ -2128,6 +2166,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
* move forward along string until we get a match. *
* Again there's no optimisation. */
for (i = 0, t = s; i < l; i++, t++, patoffset++) {
+ set_pat_start(p, t-s);
if (pattry(p, t)) {
*sp = get_match_ret(*sp, i, l, fl, replstr);
patoffset = 0;
@@ -2141,6 +2180,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
case SUB_SUBSTR:
/* 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);
return 1;
@@ -2155,12 +2195,14 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
matched = 0;
for (; t < s + l; t++, patoffset++) {
/* Find the longest match from this position. */
+ set_pat_start(p, t-s);
if (pattry(p, t) && patinput > t) {
char *mpos = patinput;
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;
@@ -2209,6 +2251,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
* at the start. Goodness knows if this is a good idea
* with global substitution, so it doesn't happen.
*/
+ 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);
@@ -2219,6 +2262,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
case (SUB_END|SUB_SUBSTR):
/* Shortest at end with substrings */
patoffset = ml;
+ set_pat_start(p, l);
if (pattry(p, s + l) && !--n) {
*sp = get_match_ret(*sp, l, l, fl, replstr);
patoffset = 0;
@@ -2230,6 +2274,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
for (t = s + l - 1; t >= s; t--, patoffset--) {
if (t > s && t[-1] == Meta)
t--;
+ set_pat_start(p, t-s);
if (pattry(p, t) && patinput > t && !--n) {
/* Found the longest match */
char *mpos = patinput;
@@ -2237,6 +2282,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
char *ptr;
for (ptr = t; ptr < mpos; METAINC(ptr)) {
sav = *ptr;
+ set_pat_end(p, sav);
*ptr = '\0';
if (pattry(p, t)) {
mpos = patinput;
@@ -2252,6 +2298,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr)
}
}
patoffset = ml;
+ set_pat_start(p, l);
if ((fl & SUB_LONG) && pattry(p, s + l) && !--n) {
*sp = get_match_ret(*sp, l, l, fl, replstr);
patoffset = 0;