-/* Copyright (C) 1991-2002 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2006 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
- Bash is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2, or (at your option) any later
- version.
-
- Bash is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
-
- You should have received a copy of the GNU General Public License along
- with Bash; see the file COPYING. If not, write to the Free Software
- Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
-
-static int FCT __P((CHAR *, CHAR *, int));
+ Bash is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Bash is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Bash. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+int FCT __P((CHAR *, CHAR *, int));
+
static int GMATCH __P((CHAR *, CHAR *, CHAR *, CHAR *, int));
static CHAR *PARSE_COLLSYM __P((CHAR *, INT *));
static CHAR *BRACKMATCH __P((CHAR *, U_CHAR, int));
static int EXTMATCH __P((INT, CHAR *, CHAR *, CHAR *, CHAR *, int));
static CHAR *PATSCAN __P((CHAR *, CHAR *, INT));
-static int
+int
FCT (pattern, string, flags)
CHAR *pattern;
CHAR *string;
if ((flags & FNM_PATHNAME) && sc == L('/'))
/* A slash does not match a wildcard under FNM_PATHNAME. */
return FNM_NOMATCH;
+#ifdef EXTENDED_GLOB
+ else if ((flags & FNM_EXTMATCH) && c == L('?') && *p == L('(')) /* ) */
+ {
+ CHAR *newn;
+ for (newn = n; newn < se; ++newn)
+ {
+ if (EXTMATCH (c, newn, se, p, pe, flags) == 0)
+ return (0);
+ }
+ /* We didn't match. If we have a `?(...)', that's failure. */
+ return FNM_NOMATCH;
+ }
+#endif
else if (c == L('?'))
{
if (sc == L('\0'))
{
bcopy (p + 1, ccname, (close - p - 1) * sizeof (CHAR));
*(ccname + (close - p - 1)) = L('\0');
- pc = IS_CCLASS (test, ccname);
+ pc = IS_CCLASS (test, (XCHAR *)ccname);
}
if (pc == -1)
pc = 0;
CHAR *string, *end;
INT delim;
{
- int pnest, bnest;
+ int pnest, bnest, skip;
INT cchar;
CHAR *s, c, *bfirst;
- pnest = bnest = 0;
+ pnest = bnest = skip = 0;
cchar = 0;
bfirst = NULL;
{
if (s >= end)
return (s);
+ if (skip)
+ {
+ skip = 0;
+ continue;
+ }
switch (c)
{
+ case L('\\'):
+ skip = 1;
+ break;
+
case L('\0'):
return ((CHAR *)NULL);
CHAR *psub; /* pointer to sub-pattern */
CHAR *pnext; /* pointer to next sub-pattern */
CHAR *srest; /* pointer to rest of string */
- int m1, m2;
+ int m1, m2, xflags; /* xflags = flags passed to recursive matches */
#if DEBUG_MATCHING
fprintf(stderr, "extmatch: xc = %c\n", xc);
fprintf(stderr, "extmatch: s = %s; se = %s\n", s, se);
fprintf(stderr, "extmatch: p = %s; pe = %s\n", p, pe);
+fprintf(stderr, "extmatch: flags = %d\n", flags);
#endif
prest = PATSCAN (p + (*p == L('(')), pe, 0); /* ) */
string matches the rest of the pattern. Also handle
multiple matches of the pattern. */
if (m1)
- m2 = (GMATCH (srest, se, prest, pe, flags) == 0) ||
- (s != srest && GMATCH (srest, se, p - 1, pe, flags) == 0);
+ {
+ /* if srest > s, we are not at start of string */
+ xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
+ m2 = (GMATCH (srest, se, prest, pe, xflags) == 0) ||
+ (s != srest && GMATCH (srest, se, p - 1, pe, xflags) == 0);
+ }
if (m1 && m2)
return (0);
}
return (FNM_NOMATCH);
case L('?'): /* match zero or one of the patterns */
- case L('@'): /* match exactly one of the patterns */
+ case L('@'): /* match one (or more) of the patterns */
/* If we can get away with no matches, don't even bother. Just
call gmatch on the rest of the pattern and return success if
it succeeds. */
srest = (prest == pe) ? se : s;
for ( ; srest <= se; srest++)
{
+ /* if srest > s, we are not at start of string */
+ xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
if (GMATCH (s, srest, psub, pnext - 1, flags) == 0 &&
- GMATCH (srest, se, prest, pe, flags) == 0)
+ GMATCH (srest, se, prest, pe, xflags) == 0)
return (0);
}
if (pnext == prest)
if (pnext == prest)
break;
}
- if (m1 == 0 && GMATCH (srest, se, prest, pe, flags) == 0)
+ /* if srest > s, we are not at start of string */
+ xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
+ if (m1 == 0 && GMATCH (srest, se, prest, pe, xflags) == 0)
return (0);
}
return (FNM_NOMATCH);