summaryrefslogtreecommitdiff
path: root/Src/pattern.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/pattern.c')
-rw-r--r--Src/pattern.c82
1 files changed, 58 insertions, 24 deletions
diff --git a/Src/pattern.c b/Src/pattern.c
index 72c7d97d5..1f2e94bd9 100644
--- a/Src/pattern.c
+++ b/Src/pattern.c
@@ -669,12 +669,14 @@ patcompile(char *exp, int inflags, char **endexp)
nmeta++;
if (nmeta) {
char *oldpatout = patout;
+ ptrdiff_t pd;
patadd(NULL, 0, nmeta, 0);
/*
* Yuk.
*/
p = (Patprog)patout;
- opnd = patout + (opnd - oldpatout);
+ pd = patout - oldpatout;
+ opnd += pd;
dst = patout + startoff;
}
@@ -686,6 +688,8 @@ patcompile(char *exp, int inflags, char **endexp)
*dst++ = *opnd++;
}
}
+ /* Only one string in a PAT_PURES, so now done. */
+ break;
}
}
p->size = dst - patout;
@@ -1838,7 +1842,8 @@ pattail(long p, long val)
/* do pattail, but on operand of first argument; nop if operandless */
/**/
-static void patoptail(long p, long val)
+static void
+patoptail(long p, long val)
{
Upat ptr = (Upat)patout + p;
int op = P_OP(ptr);
@@ -1854,19 +1859,34 @@ static void patoptail(long p, long val)
/*
* Run a pattern.
*/
-static char *patinstart; /* Start of input string */
-static char *patinend; /* End of input string */
-static char *patinput; /* String input pointer */
-static char *patinpath; /* Full path for use with ~ exclusions */
-static int patinlen; /* Length of last successful match.
+struct rpat {
+ char *patinstart; /* Start of input string */
+ char *patinend; /* End of input string */
+ char *patinput; /* String input pointer */
+ char *patinpath; /* Full path for use with ~ exclusions */
+ int patinlen; /* Length of last successful match.
* Includes count of Meta characters.
*/
-static char *patbeginp[NSUBEXP]; /* Pointer to backref beginnings */
-static char *patendp[NSUBEXP]; /* Pointer to backref ends */
-static int parsfound; /* parentheses (with backrefs) found */
+ char *patbeginp[NSUBEXP]; /* Pointer to backref beginnings */
+ char *patendp[NSUBEXP]; /* Pointer to backref ends */
+ int parsfound; /* parentheses (with backrefs) found */
+
+ int globdots; /* Glob initial dots? */
+};
+
+static struct rpat pattrystate;
+
+#define patinstart (pattrystate.patinstart)
+#define patinend (pattrystate.patinend)
+#define patinput (pattrystate.patinput)
+#define patinpath (pattrystate.patinpath)
+#define patinlen (pattrystate.patinlen)
+#define patbeginp (pattrystate.patbeginp)
+#define patendp (pattrystate.patendp)
+#define parsfound (pattrystate.parsfound)
+#define globdots (pattrystate.globdots)
-static int globdots; /* Glob initial dots? */
/*
* Character functions operating on unmetafied strings.
@@ -2302,7 +2322,7 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
* Either we are testing against a pure string,
* or we can match anything at all.
*/
- int ret, pstrlen;
+ int pstrlen;
char *pstr;
if (patstralloc->alloced)
{
@@ -2404,11 +2424,7 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
}
}
}
-
- return ret;
} else {
- int q = queue_signal_level();
-
/*
* Test for a `must match' string, unless we're scanning for a match
* in which case we don't need to do this each time.
@@ -2440,9 +2456,8 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
ret = 0;
}
}
- if (!ret) {
+ if (!ret)
return 0;
- }
patglobflags = prog->globflags;
if (!(patflags & PAT_FILE)) {
@@ -2454,8 +2469,6 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
patinput = patinstart;
- dont_queue_signals();
-
if (patmatch((Upat)progstr)) {
/*
* we were lazy and didn't save the globflags if an exclusion
@@ -2594,11 +2607,9 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
ret = 1;
} else
ret = 0;
-
- restore_queue_signals(q);
-
- return ret;
}
+
+ return ret;
}
/*
@@ -2674,6 +2685,26 @@ patmatch(Upat prog)
int savglobflags, op, no, min, fail = 0, saverrsfound;
zrange_t from, to, comp;
patint_t nextch;
+ int q = queue_signal_level();
+
+ /*
+ * To avoid overhead of saving state if there are no queued signals
+ * waiting, we pierce the signals.h veil and examine queue state.
+ */
+#define check_for_signals() do if (queue_front != queue_rear) { \
+ int savpatflags = patflags, savpatglobflags = patglobflags; \
+ char *savexactpos = exactpos, *savexactend = exactend; \
+ struct rpat savpattrystate = pattrystate; \
+ dont_queue_signals(); \
+ restore_queue_signals(q); \
+ exactpos = savexactpos; \
+ exactend = savexactend; \
+ patflags = savpatflags; \
+ patglobflags = savpatglobflags; \
+ pattrystate = savpattrystate; \
+ } while (0)
+
+ check_for_signals();
while (scan && !errflag) {
next = PATNEXT(scan);
@@ -3508,6 +3539,9 @@ patmatch(Upat prog)
}
scan = next;
+
+ /* Allow handlers to run once per loop */
+ check_for_signals();
}
return 0;