diff options
Diffstat (limited to 'Src/pattern.c')
-rw-r--r-- | Src/pattern.c | 82 |
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; |