From 1c172cb080800ff2a6cedb63574c376faf42510a Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 24 Oct 2013 18:45:50 +0100 Subject: 31877: fix behaviour of disable -p with parentheses --- Src/pattern.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'Src/pattern.c') diff --git a/Src/pattern.c b/Src/pattern.c index 609a9e372..c86f86d69 100644 --- a/Src/pattern.c +++ b/Src/pattern.c @@ -748,7 +748,7 @@ patcompswitch(int paren, int *flagp) starter = 0; br = patnode(P_BRANCH); - if (!patcompbranch(&flags)) + if (!patcompbranch(&flags, paren)) return 0; if (patglobflags != (int)savglobflags) gfchanged++; @@ -839,7 +839,7 @@ patcompswitch(int paren, int *flagp) patglobflags = (int)savglobflags; } } - newbr = patcompbranch(&flags); + newbr = patcompbranch(&flags, paren); if (tilde == 2) { /* restore special treatment of / */ zpc_special[ZPC_SLASH] = '/'; @@ -902,7 +902,7 @@ patcompswitch(int paren, int *flagp) /**/ static long -patcompbranch(int *flagp) +patcompbranch(int *flagp, int paren) { long chain, latest = 0, starter; int flags = 0; @@ -973,7 +973,7 @@ patcompbranch(int *flagp) patparse++; latest = patcompnot(0, &flags); } else - latest = patcomppiece(&flags); + latest = patcomppiece(&flags, paren); if (!latest) return 0; if (!starter) @@ -1221,7 +1221,7 @@ pattern_range_to_string(char *rangestr, char *outstr) /**/ static long -patcomppiece(int *flagp) +patcomppiece(int *flagp, int paren) { long starter = 0, next, op, opnd; int flags, flags2, kshchar, len, ch, patch, nmeta; @@ -1253,17 +1253,25 @@ patcomppiece(int *flagp) } /* - * End of string (or no string at all) if ksh-type parentheses, - * or special character, unless that character is a tilde and - * the character following is an end-of-segment character. Thus - * tildes are not special if there is nothing following to - * be excluded. + * If '(' is disabled as a pattern char, allow ')' as + * an ordinary string character if there are no parentheses to + * close. Don't allow it otherwise, it changes the syntax. */ - if (kshchar || (memchr(zpc_special, *patparse, ZPC_COUNT) && - (*patparse != zpc_special[ZPC_TILDE] || - patparse[1] == '/' || - !memchr(zpc_special, patparse[1], ZPC_SEG_COUNT)))) - break; + if (zpc_special[ZPC_INPAR] != Marker || *patparse != Outpar || + paren) { + /* + * End of string (or no string at all) if ksh-type parentheses, + * or special character, unless that character is a tilde and + * the character following is an end-of-segment character. Thus + * tildes are not special if there is nothing following to + * be excluded. + */ + if (kshchar || (memchr(zpc_special, *patparse, ZPC_COUNT) && + (*patparse != zpc_special[ZPC_TILDE] || + patparse[1] == '/' || + !memchr(zpc_special, patparse[1], ZPC_SEG_COUNT)))) + break; + } /* Remember the previous character for backtracking */ patprev = patparse; @@ -1438,7 +1446,7 @@ patcomppiece(int *flagp) patadd(NULL, 0, 1, 0); break; case Inpar: - DPUTS(zpc_special[ZPC_INPAR] == Marker, + DPUTS(!kshchar && zpc_special[ZPC_INPAR] == Marker, "Treating '(' as pattern character although disabled"); DPUTS(isset(SHGLOB) && !kshchar, "Treating bare '(' as pattern character with SHGLOB"); @@ -1523,7 +1531,7 @@ patcomppiece(int *flagp) * Marker for restoring a backslash in output: * does not match a character. */ - next = patcomppiece(flagp); + next = patcomppiece(flagp, paren); /* * Can't match a pure string since we need to do this * as multiple chunks. @@ -1710,7 +1718,7 @@ patcompnot(int paren, int *flagsp) pattail(starter, excl = patnode(P_EXCLUDE)); up.p = NULL; patadd((char *)&up, 0, sizeof(up), 0); - if (!(br = (paren ? patcompswitch(1, &dummy) : patcompbranch(&dummy)))) + if (!(br = (paren ? patcompswitch(1, &dummy) : patcompbranch(&dummy, 0)))) return 0; pattail(br, patnode(P_EXCEND)); n = patnode(P_NOTHING); /* just so much easier */ -- cgit 1.4.1