diff --git a/bin/sh/expand.c b/bin/sh/expand.c index 5ceda3543206..dc55d52f91c0 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -1,4 +1,4 @@ -/* $NetBSD: expand.c,v 1.44 1999/02/06 17:23:09 christos Exp $ */ +/* $NetBSD: expand.c,v 1.45 1999/03/26 15:49:34 christos Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -41,7 +41,7 @@ #if 0 static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; #else -__RCSID("$NetBSD: expand.c,v 1.44 1999/02/06 17:23:09 christos Exp $"); +__RCSID("$NetBSD: expand.c,v 1.45 1999/03/26 15:49:34 christos Exp $"); #endif #endif /* not lint */ @@ -112,7 +112,7 @@ STATIC void expmeta __P((char *, char *)); STATIC void addfname __P((char *)); STATIC struct strlist *expsort __P((struct strlist *)); STATIC struct strlist *msort __P((struct strlist *, int)); -STATIC int pmatch __P((char *, char *)); +STATIC int pmatch __P((char *, char *, int)); STATIC char *cvtnum __P((int, char *)); /* @@ -496,6 +496,7 @@ subevalvar(p, str, strloc, subtype, startloc, varflags) { char *startp; char *loc = NULL; + char *q; int c = 0; int saveherefd = herefd; struct nodelist *saveargbackq = argbackq; @@ -534,32 +535,56 @@ subevalvar(p, str, strloc, subtype, startloc, varflags) for (loc = startp; loc < str; loc++) { c = *loc; *loc = '\0'; - if (patmatch(str, startp)) + if (patmatch(str, startp, varflags & VSQUOTE)) goto recordleft; *loc = c; + if ((varflags && VSQUOTE) && *loc == CTLESC) + loc++; } return 0; case VSTRIMLEFTMAX: - for (loc = str - 1; loc >= startp; loc--) { + for (loc = str - 1; loc >= startp;) { c = *loc; *loc = '\0'; - if (patmatch(str, startp)) + if (patmatch(str, startp, varflags & VSQUOTE)) goto recordleft; *loc = c; + loc--; + if ((varflags & VSQUOTE) && loc > startp && + *(loc - 1) == CTLESC) { + for (q = startp; q < loc; q++) + if (*q == CTLESC) + q++; + if (q > loc) + loc--; + } } return 0; case VSTRIMRIGHT: - for (loc = str - 1; loc >= startp; loc--) - if (patmatch(str, loc)) + for (loc = str - 1; loc >= startp;) { + if (patmatch(str, loc, varflags & VSQUOTE)) goto recordright; + loc--; + if ((varflags & VSQUOTE) && loc > startp && + *(loc - 1) == CTLESC) { + for (q = startp; q < loc; q++) + if (*q == CTLESC) + q++; + if (q > loc) + loc--; + } + } return 0; case VSTRIMRIGHTMAX: - for (loc = startp; loc < str - 1; loc++) - if (patmatch(str, loc)) + for (loc = startp; loc < str - 1; loc++) { + if (patmatch(str, loc, varflags & VSQUOTE)) goto recordright; + if ((varflags & VSQUOTE) && *loc == CTLESC) + loc++; + } return 0; default: @@ -1195,7 +1220,7 @@ expmeta(enddir, name) while (! int_pending() && (dp = readdir(dirp)) != NULL) { if (dp->d_name[0] == '.' && ! matchdot) continue; - if (patmatch(start, dp->d_name)) { + if (patmatch(start, dp->d_name, 0)) { if (atend) { scopy(dp->d_name, enddir); addfname(expdir); @@ -1304,23 +1329,25 @@ msort(list, len) */ int -patmatch(pattern, string) +patmatch(pattern, string, squoted) char *pattern; char *string; + int squoted; /* string might have quote chars */ { #ifdef notdef if (pattern[0] == '!' && pattern[1] == '!') return 1 - pmatch(pattern + 2, string); else #endif - return pmatch(pattern, string); + return pmatch(pattern, string, squoted); } STATIC int -pmatch(pattern, string) +pmatch(pattern, string, squoted) char *pattern; char *string; + int squoted; { char *p, *q; char c; @@ -1332,12 +1359,16 @@ pmatch(pattern, string) case '\0': goto breakloop; case CTLESC: + if (squoted && *q == CTLESC) + q++; if (*q++ != *p++) return 0; break; case CTLQUOTEMARK: continue; case '?': + if (squoted && *q == CTLESC) + q++; if (*q++ == '\0') return 0; break; @@ -1348,14 +1379,21 @@ pmatch(pattern, string) if (c != CTLESC && c != CTLQUOTEMARK && c != '?' && c != '*' && c != '[') { while (*q != c) { + if (squoted && *q == CTLESC && + q[1] == c) + break; if (*q == '\0') return 0; + if (squoted && *q == CTLESC) + q++; q++; } } do { - if (pmatch(p, q)) + if (pmatch(p, q, squoted)) return 1; + if (squoted && *q == CTLESC) + q++; } while (*q++ != '\0'); return 0; case '[': { @@ -1383,6 +1421,8 @@ pmatch(pattern, string) } found = 0; chr = *q++; + if (squoted && chr == CTLESC) + chr = *q++; if (chr == '\0') return 0; c = *p++; @@ -1410,6 +1450,8 @@ pmatch(pattern, string) break; } dft: default: + if (squoted && *q == CTLESC) + q++; if (*q++ != c) return 0; break; @@ -1473,7 +1515,7 @@ casematch(pattern, val) argstr(pattern->narg.text, EXP_TILDE | EXP_CASE); STPUTC('\0', expdest); p = grabstackstr(expdest); - result = patmatch(p, val); + result = patmatch(p, val, 0); popstackmark(&smark); return result; } diff --git a/bin/sh/expand.h b/bin/sh/expand.h index d9c0762fd63a..3b15fb65d37b 100644 --- a/bin/sh/expand.h +++ b/bin/sh/expand.h @@ -1,4 +1,4 @@ -/* $NetBSD: expand.h,v 1.10 1999/02/05 07:52:52 christos Exp $ */ +/* $NetBSD: expand.h,v 1.11 1999/03/26 15:49:34 christos Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -64,7 +64,7 @@ union node; void expandhere __P((union node *, int)); void expandarg __P((union node *, struct arglist *, int)); void expari __P((int)); -int patmatch __P((char *, char *)); +int patmatch __P((char *, char *, int)); void rmescapes __P((char *)); int casematch __P((union node *, char *));