commit bash-20170428 snapshot

This commit is contained in:
Chet Ramey
2017-05-01 15:46:46 -04:00
parent 787bb204f9
commit 2a39157723
14 changed files with 426 additions and 570 deletions
+52 -25
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1991-2011 Free Software Foundation, Inc.
/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -16,9 +16,15 @@
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
struct STRUCT
{
CHAR *pattern;
CHAR *string;
};
int FCT __P((CHAR *, CHAR *, int));
static int GMATCH __P((CHAR *, CHAR *, CHAR *, CHAR *, int));
static int GMATCH __P((CHAR *, CHAR *, CHAR *, CHAR *, struct STRUCT *, 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));
@@ -39,15 +45,16 @@ FCT (pattern, string, flags)
se = string + STRLEN ((XCHAR *)string);
pe = pattern + STRLEN ((XCHAR *)pattern);
return (GMATCH (string, se, pattern, pe, flags));
return (GMATCH (string, se, pattern, pe, (struct STRUCT *)NULL, flags));
}
/* Match STRING against the filename pattern PATTERN, returning zero if
it matches, FNM_NOMATCH if not. */
static int
GMATCH (string, se, pattern, pe, flags)
GMATCH (string, se, pattern, pe, ends, flags)
CHAR *string, *se;
CHAR *pattern, *pe;
struct STRUCT *ends;
int flags;
{
CHAR *p, *n; /* pattern, string */
@@ -121,7 +128,16 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
return FNM_NOMATCH;
break;
case '*': /* Match zero or more characters */
case L('*'): /* Match zero or more characters */
/* See below for the reason for using this. It avoids backtracking
back to a previous `*'. Picked up from glibc. */
if (ends != NULL)
{
ends->pattern = p - 1;
ends->string = n;
return (0);
}
if ((flags & FNM_PERIOD) && sc == L('.') &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/'))))
/* `*' cannot match a `.' if it is the first character of the
@@ -144,17 +160,9 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
{
CHAR *newn;
#if 0
for (newn = n; newn < se; ++newn)
{
if (EXTMATCH (c, newn, se, p, pe, flags) == 0)
return (0);
}
#else
/* We can match 0 or 1 times. If we match, return success */
if (EXTMATCH (c, n, se, p, pe, flags) == 0)
return (0);
#endif
/* We didn't match the extended glob pattern, but
that's OK, since we can match 0 or 1 occurrences.
@@ -244,7 +252,7 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
{
while (n < se && *n != L('/'))
++n;
if (n < se && *n == L('/') && (GMATCH (n+1, se, p, pe, flags) == 0))
if (n < se && *n == L('/') && (GMATCH (n+1, se, p, pe, NULL, flags) == 0))
return 0;
return FNM_NOMATCH; /* XXX */
}
@@ -253,10 +261,13 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
{
U_CHAR c1;
const CHAR *endp;
struct STRUCT end;
end.pattern = NULL;
endp = MEMCHR (n, (flags & FNM_PATHNAME) ? L('/') : L('\0'), se - n);
if (endp == 0)
endp = se;
c1 = ((flags & FNM_NOESCAPE) == 0 && c == L('\\')) ? *p : c;
c1 = FOLD (c1);
for (--p; n < endp; ++n)
@@ -275,9 +286,24 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
continue;
/* Otherwise, we just recurse. */
if (GMATCH (n, se, p, pe, flags & ~FNM_PERIOD) == 0)
return (0);
if (GMATCH (n, se, p, pe, &end, flags & ~FNM_PERIOD) == 0)
{
if (end.pattern == NULL)
return (0);
break;
}
}
/* This is a clever idea from glibc, used to avoid backtracking
to a `*' that appears earlier in the pattern. We get away
without saving se and pe because they are always the same,
even in the recursive calls to gmatch */
if (end.pattern != NULL)
{
p = end.pattern;
n = end.string;
continue;
}
return FNM_NOMATCH;
}
@@ -753,7 +779,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
/* 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. */
if (xc == L('*') && (GMATCH (s, se, prest, pe, flags) == 0))
if (xc == L('*') && (GMATCH (s, se, prest, pe, NULL, flags) == 0))
return 0;
/* OK, we have to do this the hard way. First, we make sure one of
@@ -766,7 +792,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
{
/* Match this substring (S -> SREST) against this
subpattern (psub -> pnext - 1) */
m1 = GMATCH (s, srest, psub, pnext - 1, flags) == 0;
m1 = GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0;
/* OK, we matched a subpattern, so make sure the rest of the
string matches the rest of the pattern. Also handle
multiple matches of the pattern. */
@@ -774,8 +800,8 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
{
/* 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);
m2 = (GMATCH (srest, se, prest, pe, NULL, xflags) == 0) ||
(s != srest && GMATCH (srest, se, p - 1, pe, NULL, xflags) == 0);
}
if (m1 && m2)
return (0);
@@ -790,7 +816,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
/* 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. */
if (xc == L('?') && (GMATCH (s, se, prest, pe, flags) == 0))
if (xc == L('?') && (GMATCH (s, se, prest, pe, NULL, flags) == 0))
return 0;
/* OK, we have to do this the hard way. First, we see if one of
@@ -804,8 +830,8 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
{
/* 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, xflags) == 0)
if (GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0 &&
GMATCH (srest, se, prest, pe, NULL, xflags) == 0)
return (0);
}
if (pnext == prest)
@@ -821,14 +847,14 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
{
pnext = PATSCAN (psub, pe, L('|'));
/* If one of the patterns matches, just bail immediately. */
if (m1 = (GMATCH (s, srest, psub, pnext - 1, flags) == 0))
if (m1 = (GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0))
break;
if (pnext == prest)
break;
}
/* 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)
if (m1 == 0 && GMATCH (srest, se, prest, pe, NULL, xflags) == 0)
return (0);
}
return (FNM_NOMATCH);
@@ -852,6 +878,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
#undef PATSCAN
#undef STRCOMPARE
#undef EXTMATCH
#undef STRUCT
#undef BRACKMATCH
#undef STRCHR
#undef STRCOLL
+3 -1
View File
@@ -1,7 +1,7 @@
/* strmatch.c -- ksh-like extended pattern matching for the shell and filename
globbing. */
/* Copyright (C) 1991-2011 Free Software Foundation, Inc.
/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -254,6 +254,7 @@ is_cclass (c, name)
#define PATSCAN glob_patscan
#define STRCOMPARE strcompare
#define EXTMATCH extmatch
#define STRUCT smat_struct
#define STRCHR(S, C) strchr((S), (C))
#define MEMCHR(S, C, N) memchr((S), (C), (N))
#define STRCOLL(S1, S2) strcoll((S1), (S2))
@@ -389,6 +390,7 @@ is_wcclass (wc, name)
#define PATSCAN glob_patscan_wc
#define STRCOMPARE wscompare
#define EXTMATCH extmatch_wc
#define STRUCT wcsmat_struct
#define STRCHR(S, C) wcschr((S), (C))
#define MEMCHR(S, C, N) wmemchr((S), (C), (N))
#define STRCOLL(S1, S2) wcscoll((S1), (S2))
+13 -2
View File
@@ -452,8 +452,6 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
array[l++] = ESC; /* ESC is meta-prefix */
i += 5;
array[l++] = CTRL (_rl_to_upper (seq[i]));
if (seq[i] == '\0')
i--;
}
else if (c == 'M')
{
@@ -482,6 +480,8 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
/* Special hack for C-?... */
array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
}
if (seq[i] == '\0')
break;
continue;
}
@@ -1263,6 +1263,12 @@ rl_parse_and_bind (char *string)
/* Advance to the colon (:) or whitespace which separates the two objects. */
for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
if (i == 0)
{
_rl_init_file_error ("`%s': invalid key binding: missing key sequence", string);
return 1;
}
equivalency = (c == ':' && string[i + 1] == '=');
foundsep = c != 0;
@@ -1341,6 +1347,11 @@ remove_trailing:
i = _rl_skip_to_delim (string, i+1, *funname);
if (string[i])
i++;
else
{
_rl_init_file_error ("`%s': missing closing quote for macro", funname);
return 1;
}
}
/* Advance to the end of the string. */
+4 -1
View File
@@ -293,7 +293,10 @@ read_history_range (const char *filename, int from, int to)
}
if (file_size == 0)
return 0; /* don't waste time if we don't have to */
{
free (input);
return 0; /* don't waste time if we don't have to */
}
#ifdef HISTORY_USE_MMAP
/* We map read/write and private so we can change newlines to NULs without