mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-29 08:29:54 +02:00
commit bash-20170120 snapshot
This commit is contained in:
+32
-2
@@ -12988,12 +12988,42 @@ lib/glob/glob.c
|
||||
|
||||
lib/glob/glob_loop.c
|
||||
- CHAR -> GCHAR (unsigned char); change uses of CHAR to GCHAR
|
||||
- extglob_skipname: move here from gmisc.c, generalize for regular
|
||||
and wide-char versions
|
||||
|
||||
lib/glob/glob.c
|
||||
- wchkname -> wskipname
|
||||
- wskipname: now takes a third `flags' argument, like the other variants
|
||||
of skipname
|
||||
|
||||
1/17
|
||||
----
|
||||
redir.c
|
||||
- here_document_to_fd: set the file descriptor open for writing to the
|
||||
here document to be close-on-exec. Fixes bug reported by
|
||||
Siteshwar Vashisht <svashisht@redhat.com>
|
||||
|
||||
1/18
|
||||
----
|
||||
{gmisc,gm_loop}.c
|
||||
- match_pattern_char,match_pattern_wchar: moved to gm_loop.c (new file),
|
||||
compile twice for single and wide characters as with the rest of
|
||||
the functions
|
||||
- umatchlen,wmatchlen: ditto
|
||||
- extglob_pattern_p: move to gm_loop.c, generalize for regular and
|
||||
wide-char versions
|
||||
|
||||
1/19
|
||||
----
|
||||
lib/readline/complete.c
|
||||
- stat_char: fix small memory leak if stat/lstat returns -1
|
||||
|
||||
bashline.c
|
||||
- bash_filename_stat_hook,bash_directory_completion_hook: make sure
|
||||
expand_prompt_string is caled wth W_NOPROCSUB flag
|
||||
- directory_exists: don't dequote the filename passed as an argument;
|
||||
this function should never get quoted pathnames
|
||||
|
||||
subst.c
|
||||
- expand_word_internal: when calling expand_word_internal recursively
|
||||
after reading a double-quoted string, make sure the W_NOCOMSUB and
|
||||
W_NOPROCSUB flags make it to the recursive invocation. Fixes bug
|
||||
reported by Jens Heyens <jens.heyens@cispa.saarland>
|
||||
|
||||
@@ -239,6 +239,7 @@ lib/glob/glob.c f
|
||||
lib/glob/glob.h f
|
||||
lib/glob/glob_loop.c f
|
||||
lib/glob/gmisc.c f
|
||||
lib/glob/gm_loop.c f
|
||||
lib/glob/xmbsrtowcs.c f
|
||||
lib/glob/collsyms.h f
|
||||
lib/glob/doc/Makefile f
|
||||
|
||||
+13
-11
@@ -143,7 +143,7 @@ static int executable_completion __P((const char *, int));
|
||||
static rl_icppfunc_t *save_directory_hook __P((void));
|
||||
static void restore_directory_hook __P((rl_icppfunc_t));
|
||||
|
||||
static int directory_exists __P((const char *));
|
||||
static int directory_exists __P((const char *, int));
|
||||
|
||||
static void cleanup_expansion_error __P((void));
|
||||
static void maybe_make_readline_line __P((char *));
|
||||
@@ -1157,7 +1157,7 @@ bash_backward_shellword (count, key)
|
||||
size_t slen;
|
||||
int sindex, c, p;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
|
||||
if (count < 0)
|
||||
return (bash_forward_shellword (-count, key));
|
||||
|
||||
@@ -3106,18 +3106,20 @@ restore_directory_hook (hookf)
|
||||
rl_directory_rewrite_hook = hookf;
|
||||
}
|
||||
|
||||
/* Check whether not the (dequoted) version of DIRNAME, with any trailing slash
|
||||
removed, exists. */
|
||||
/* Check whether not DIRNAME, with any trailing slash removed, exists. If
|
||||
SHOULD_DEQUOTE is non-zero, we dequote the directory name first. */
|
||||
static int
|
||||
directory_exists (dirname)
|
||||
directory_exists (dirname, should_dequote)
|
||||
const char *dirname;
|
||||
int should_dequote;
|
||||
{
|
||||
char *new_dirname;
|
||||
int dirlen, r;
|
||||
struct stat sb;
|
||||
|
||||
/* First, dequote the directory name */
|
||||
new_dirname = bash_dequote_filename ((char *)dirname, rl_completion_quote_character);
|
||||
/* We save the string and chop the trailing slash because stat/lstat behave
|
||||
inconsistently if one is present. */
|
||||
new_dirname = should_dequote ? bash_dequote_filename ((char *)dirname, rl_completion_quote_character) : savestring (dirname);
|
||||
dirlen = STRLEN (new_dirname);
|
||||
if (new_dirname[dirlen - 1] == '/')
|
||||
new_dirname[dirlen - 1] = '\0';
|
||||
@@ -3149,7 +3151,7 @@ bash_filename_stat_hook (dirname)
|
||||
else if (t = mbschr (local_dirname, '`')) /* XXX */
|
||||
should_expand_dirname = '`';
|
||||
|
||||
if (should_expand_dirname && directory_exists (local_dirname))
|
||||
if (should_expand_dirname && directory_exists (local_dirname, 0))
|
||||
should_expand_dirname = 0;
|
||||
|
||||
if (should_expand_dirname)
|
||||
@@ -3159,7 +3161,7 @@ bash_filename_stat_hook (dirname)
|
||||
have to worry about restoring this setting. */
|
||||
global_nounset = unbound_vars_is_error;
|
||||
unbound_vars_is_error = 0;
|
||||
wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_COMPLETE); /* does the right thing */
|
||||
wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */
|
||||
unbound_vars_is_error = global_nounset;
|
||||
if (wl)
|
||||
{
|
||||
@@ -3259,13 +3261,13 @@ bash_directory_completion_hook (dirname)
|
||||
should_expand_dirname = '`';
|
||||
}
|
||||
|
||||
if (should_expand_dirname && directory_exists (local_dirname))
|
||||
if (should_expand_dirname && directory_exists (local_dirname, 1))
|
||||
should_expand_dirname = 0;
|
||||
|
||||
if (should_expand_dirname)
|
||||
{
|
||||
new_dirname = savestring (local_dirname);
|
||||
wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_COMPLETE); /* does the right thing */
|
||||
wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */
|
||||
if (wl)
|
||||
{
|
||||
*dirname = string_list (wl);
|
||||
|
||||
@@ -445,6 +445,14 @@ sh_unset_nodelay_mode (fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Just a wrapper for the define in include/filecntl.h */
|
||||
int
|
||||
sh_setclexec (fd)
|
||||
int fd;
|
||||
{
|
||||
return (SET_CLOSE_ON_EXEC (fd));
|
||||
}
|
||||
|
||||
/* Return 1 if file descriptor FD is valid; 0 otherwise. */
|
||||
int
|
||||
sh_validfd (fd)
|
||||
|
||||
@@ -295,6 +295,7 @@ extern int legal_alias_name __P((const char *, int));
|
||||
extern int assignment __P((const char *, int));
|
||||
|
||||
extern int sh_unset_nodelay_mode __P((int));
|
||||
extern int sh_setclexec __P((int));
|
||||
extern int sh_validfd __P((int));
|
||||
extern int fd_ispipe __P((int));
|
||||
extern void check_dev_tty __P((void));
|
||||
|
||||
@@ -164,4 +164,5 @@ xmbsrtowcs.o: xmbsrtowcs.c
|
||||
|
||||
# dependencies for C files that include other C files
|
||||
glob.o: glob_loop.c
|
||||
gmisc.o: gm_loop.c
|
||||
smatch.o: sm_loop.c
|
||||
|
||||
+13
-12
@@ -1,6 +1,6 @@
|
||||
/* glob.c -- file-name wildcard pattern matching for Bash.
|
||||
|
||||
Copyright (C) 1985-2009 Free Software Foundation, Inc.
|
||||
Copyright (C) 1985-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -123,6 +123,9 @@ static char **glob_dir_to_array __P((char *, char **, int));
|
||||
extern char *glob_patscan __P((char *, char *, int));
|
||||
extern wchar_t *glob_patscan_wc __P((wchar_t *, wchar_t *, int));
|
||||
|
||||
/* And this from gmisc.c/gm_loop.c */
|
||||
extern int wextglob_pattern_p __P((wchar_t *));
|
||||
|
||||
extern char *glob_dirscan __P((char *, int));
|
||||
|
||||
/* Compile `glob_loop.c' for single-byte characters. */
|
||||
@@ -131,7 +134,6 @@ extern char *glob_dirscan __P((char *, int));
|
||||
#define INT int
|
||||
#define L(CS) CS
|
||||
#define INTERNAL_GLOB_PATTERN_P internal_glob_pattern_p
|
||||
#define EXTGLOB_PATTERN_P extglob_pattern_p
|
||||
#include "glob_loop.c"
|
||||
|
||||
/* Compile `glob_loop.c' again for multibyte characters. */
|
||||
@@ -142,7 +144,6 @@ extern char *glob_dirscan __P((char *, int));
|
||||
#define INT wint_t
|
||||
#define L(CS) L##CS
|
||||
#define INTERNAL_GLOB_PATTERN_P internal_glob_wpattern_p
|
||||
#define EXTGLOB_PATTERN_P wextglob_pattern_p
|
||||
#include "glob_loop.c"
|
||||
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
@@ -275,23 +276,23 @@ skipname (pat, dname, flags)
|
||||
#if HANDLE_MULTIBYTE
|
||||
|
||||
static int
|
||||
wskipname (pat_wc, dn_wc, flags)
|
||||
wchar_t *pat_wc, *dn_wc;
|
||||
wskipname (pat, dname, flags)
|
||||
wchar_t *pat, *dname;
|
||||
int flags;
|
||||
{
|
||||
/* If a leading dot need not be explicitly matched, and the
|
||||
pattern doesn't start with a `.', don't match `.' or `..' */
|
||||
if (noglob_dot_filenames == 0 && pat_wc[0] != L'.' &&
|
||||
(pat_wc[0] != L'\\' || pat_wc[1] != L'.') &&
|
||||
(dn_wc[0] == L'.' &&
|
||||
(dn_wc[1] == L'\0' || (dn_wc[1] == L'.' && dn_wc[2] == L'\0'))))
|
||||
if (noglob_dot_filenames == 0 && pat[0] != L'.' &&
|
||||
(pat[0] != L'\\' || pat[1] != L'.') &&
|
||||
(dname[0] == L'.' &&
|
||||
(dname[1] == L'\0' || (dname[1] == L'.' && dname[2] == L'\0'))))
|
||||
return 1;
|
||||
|
||||
/* If a leading dot must be explicitly matched, check to see if the
|
||||
pattern and dirname both have one. */
|
||||
else if (noglob_dot_filenames && dn_wc[0] == L'.' &&
|
||||
pat_wc[0] != L'.' &&
|
||||
(pat_wc[0] != L'\\' || pat_wc[1] != L'.'))
|
||||
else if (noglob_dot_filenames && dname[0] == L'.' &&
|
||||
pat[0] != L'.' &&
|
||||
(pat[0] != L'\\' || pat[1] != L'.'))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
||||
+1
-23
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991-2005 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -61,28 +61,6 @@ INTERNAL_GLOB_PATTERN_P (pattern)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if EXTENDED_GLOB
|
||||
int
|
||||
EXTGLOB_PATTERN_P (pat)
|
||||
const CHAR *pat;
|
||||
{
|
||||
switch (pat[0])
|
||||
{
|
||||
case L('*'):
|
||||
case L('+'):
|
||||
case L('!'):
|
||||
case L('@'):
|
||||
case L('?'):
|
||||
return (pat[1] == L('(')); /* ) */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef EXTGLOB_PATTERN_P
|
||||
#undef INTERNAL_GLOB_PATTERN_P
|
||||
#undef L
|
||||
#undef INT
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
/* Copyright (C) 1991-2017 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 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/>.
|
||||
*/
|
||||
|
||||
#if EXTENDED_GLOB
|
||||
int
|
||||
EXTGLOB_PATTERN_P (pat)
|
||||
const CHAR *pat;
|
||||
{
|
||||
switch (pat[0])
|
||||
{
|
||||
case L('*'):
|
||||
case L('+'):
|
||||
case L('!'):
|
||||
case L('@'):
|
||||
case L('?'):
|
||||
return (pat[1] == L('(')); /* ) */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return 1 of the first character of STRING could match the first
|
||||
character of pattern PAT. Compiled to both single and wiide character
|
||||
versions. FLAGS is a subset of strmatch flags; used to do case-insensitive
|
||||
matching for now. */
|
||||
int
|
||||
MATCH_PATTERN_CHAR (pat, string, flags)
|
||||
CHAR *pat, *string;
|
||||
int flags;
|
||||
{
|
||||
CHAR c;
|
||||
|
||||
if (*string == 0)
|
||||
return (*pat == L('*')); /* XXX - allow only * to match empty string */
|
||||
|
||||
switch (c = *pat++)
|
||||
{
|
||||
default:
|
||||
return (FOLD(*string) == FOLD(c));
|
||||
case L('\\'):
|
||||
return (FOLD(*string) == FOLD(*pat));
|
||||
case L('?'):
|
||||
return (*pat == L('(') ? 1 : (*string != L'\0'));
|
||||
case L('*'):
|
||||
return (1);
|
||||
case L('+'):
|
||||
case L('!'):
|
||||
case L('@'):
|
||||
return (*pat == L('(') ? 1 : (FOLD(*string) == FOLD(c)));
|
||||
case L('['):
|
||||
return (*string != L('\0'));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MATCHLEN (pat, max)
|
||||
CHAR *pat;
|
||||
size_t max;
|
||||
{
|
||||
CHAR c;
|
||||
int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
|
||||
|
||||
if (*pat == 0)
|
||||
return (0);
|
||||
|
||||
matlen = in_cclass = in_collsym = in_equiv = 0;
|
||||
while (c = *pat++)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
default:
|
||||
matlen++;
|
||||
break;
|
||||
case L('\\'):
|
||||
if (*pat == 0)
|
||||
return ++matlen;
|
||||
else
|
||||
{
|
||||
matlen++;
|
||||
pat++;
|
||||
}
|
||||
break;
|
||||
case L('?'):
|
||||
if (*pat == LPAREN)
|
||||
return (matlen = -1); /* XXX for now */
|
||||
else
|
||||
matlen++;
|
||||
break;
|
||||
case L('*'):
|
||||
return (matlen = -1);
|
||||
case L('+'):
|
||||
case L('!'):
|
||||
case L('@'):
|
||||
if (*pat == LPAREN)
|
||||
return (matlen = -1); /* XXX for now */
|
||||
else
|
||||
matlen++;
|
||||
break;
|
||||
case L('['):
|
||||
/* scan for ending `]', skipping over embedded [:...:] */
|
||||
bracklen = 1;
|
||||
c = *pat++;
|
||||
do
|
||||
{
|
||||
if (c == 0)
|
||||
{
|
||||
pat--; /* back up to NUL */
|
||||
matlen += bracklen;
|
||||
goto bad_bracket;
|
||||
}
|
||||
else if (c == L('\\'))
|
||||
{
|
||||
/* *pat == backslash-escaped character */
|
||||
bracklen++;
|
||||
/* If the backslash or backslash-escape ends the string,
|
||||
bail. The ++pat skips over the backslash escape */
|
||||
if (*pat == 0 || *++pat == 0)
|
||||
{
|
||||
matlen += bracklen;
|
||||
goto bad_bracket;
|
||||
}
|
||||
}
|
||||
else if (c == L('[') && *pat == L(':')) /* character class */
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
in_cclass = 1;
|
||||
}
|
||||
else if (in_cclass && c == L(':') && *pat == L(']'))
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
in_cclass = 0;
|
||||
}
|
||||
else if (c == L('[') && *pat == L('.')) /* collating symbol */
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
if (*pat == L(']')) /* right bracket can appear as collating symbol */
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
}
|
||||
in_collsym = 1;
|
||||
}
|
||||
else if (in_collsym && c == L('.') && *pat == L(']'))
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
in_collsym = 0;
|
||||
}
|
||||
else if (c == L('[') && *pat == L('=')) /* equivalence class */
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
if (*pat == L(']')) /* right bracket can appear as equivalence class */
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
}
|
||||
in_equiv = 1;
|
||||
}
|
||||
else if (in_equiv && c == L('=') && *pat == L(']'))
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
in_equiv = 0;
|
||||
}
|
||||
else
|
||||
bracklen++;
|
||||
}
|
||||
while ((c = *pat++) != L(']'));
|
||||
matlen++; /* bracket expression can only match one char */
|
||||
bad_bracket:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return matlen;
|
||||
}
|
||||
|
||||
#undef EXTGLOB_PATTERN_P
|
||||
#undef MATCH_PATTERN_CHAR
|
||||
#undef MATCHLEN
|
||||
#undef FOLD
|
||||
#undef L
|
||||
#undef LPAREN
|
||||
#undef RPAREN
|
||||
#undef INT
|
||||
#undef CHAR
|
||||
+27
-331
@@ -1,6 +1,6 @@
|
||||
/* gmisc.c -- miscellaneous pattern matching utility functions for Bash.
|
||||
|
||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
Copyright (C) 2010-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -35,348 +35,44 @@
|
||||
#ifndef FNM_CASEFOLD
|
||||
# include "strmatch.h"
|
||||
#endif
|
||||
|
||||
#ifndef LPAREN
|
||||
# define LPAREN '('
|
||||
#endif
|
||||
#ifndef RPAREN
|
||||
# define RPAREN ')'
|
||||
#endif
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
#define WLPAREN L'('
|
||||
#define WRPAREN L')'
|
||||
#include "glob.h"
|
||||
|
||||
/* Make sure these names continue to agree with what's in smatch.c */
|
||||
extern char *glob_patscan __P((char *, char *, int));
|
||||
extern wchar_t *glob_patscan_wc __P((wchar_t *, wchar_t *, int));
|
||||
|
||||
#define FOLD(c) ((flags & FNM_CASEFOLD) && iswupper (c) ? towlower (c) : (c))
|
||||
|
||||
/* Return 1 of the first character of WSTRING could match the first
|
||||
character of pattern WPAT. Wide character version. FLAGS is a
|
||||
subset of strmatch flags; used to do case-insensitive matching for now. */
|
||||
int
|
||||
match_pattern_wchar (wpat, wstring, flags)
|
||||
wchar_t *wpat, *wstring;
|
||||
int flags;
|
||||
{
|
||||
wchar_t wc;
|
||||
|
||||
if (*wstring == 0)
|
||||
return (*wpat == L'*'); /* XXX - allow only * to match empty string */
|
||||
|
||||
switch (wc = *wpat++)
|
||||
{
|
||||
default:
|
||||
return (FOLD(*wstring) == FOLD(wc));
|
||||
case L'\\':
|
||||
return (FOLD(*wstring) == FOLD(*wpat));
|
||||
case L'?':
|
||||
return (*wpat == WLPAREN ? 1 : (*wstring != L'\0'));
|
||||
case L'*':
|
||||
return (1);
|
||||
case L'+':
|
||||
case L'!':
|
||||
case L'@':
|
||||
return (*wpat == WLPAREN ? 1 : (FOLD(*wstring) == FOLD(wc)));
|
||||
case L'[':
|
||||
return (*wstring != L'\0');
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
wmatchlen (wpat, wmax)
|
||||
wchar_t *wpat;
|
||||
size_t wmax;
|
||||
{
|
||||
wchar_t wc;
|
||||
int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
|
||||
|
||||
if (*wpat == 0)
|
||||
return (0);
|
||||
|
||||
matlen = in_cclass = in_collsym = in_equiv = 0;
|
||||
while (wc = *wpat++)
|
||||
{
|
||||
switch (wc)
|
||||
{
|
||||
default:
|
||||
matlen++;
|
||||
break;
|
||||
case L'\\':
|
||||
if (*wpat == 0)
|
||||
return ++matlen;
|
||||
else
|
||||
{
|
||||
matlen++;
|
||||
wpat++;
|
||||
}
|
||||
break;
|
||||
case L'?':
|
||||
if (*wpat == WLPAREN)
|
||||
return (matlen = -1); /* XXX for now */
|
||||
else
|
||||
matlen++;
|
||||
break;
|
||||
case L'*':
|
||||
return (matlen = -1);
|
||||
case L'+':
|
||||
case L'!':
|
||||
case L'@':
|
||||
if (*wpat == WLPAREN)
|
||||
return (matlen = -1); /* XXX for now */
|
||||
else
|
||||
matlen++;
|
||||
break;
|
||||
case L'[':
|
||||
/* scan for ending `]', skipping over embedded [:...:] */
|
||||
bracklen = 1;
|
||||
wc = *wpat++;
|
||||
do
|
||||
{
|
||||
if (wc == 0)
|
||||
{
|
||||
wpat--; /* back up to NUL */
|
||||
matlen += bracklen;
|
||||
goto bad_bracket;
|
||||
}
|
||||
else if (wc == L'\\')
|
||||
{
|
||||
/* *wpat == backslash-escaped character */
|
||||
bracklen++;
|
||||
/* If the backslash or backslash-escape ends the string,
|
||||
bail. The ++wpat skips over the backslash escape */
|
||||
if (*wpat == 0 || *++wpat == 0)
|
||||
{
|
||||
matlen += bracklen;
|
||||
goto bad_bracket;
|
||||
}
|
||||
}
|
||||
else if (wc == L'[' && *wpat == L':') /* character class */
|
||||
{
|
||||
wpat++;
|
||||
bracklen++;
|
||||
in_cclass = 1;
|
||||
}
|
||||
else if (in_cclass && wc == L':' && *wpat == L']')
|
||||
{
|
||||
wpat++;
|
||||
bracklen++;
|
||||
in_cclass = 0;
|
||||
}
|
||||
else if (wc == L'[' && *wpat == L'.') /* collating symbol */
|
||||
{
|
||||
wpat++;
|
||||
bracklen++;
|
||||
if (*wpat == L']') /* right bracket can appear as collating symbol */
|
||||
{
|
||||
wpat++;
|
||||
bracklen++;
|
||||
}
|
||||
in_collsym = 1;
|
||||
}
|
||||
else if (in_collsym && wc == L'.' && *wpat == L']')
|
||||
{
|
||||
wpat++;
|
||||
bracklen++;
|
||||
in_collsym = 0;
|
||||
}
|
||||
else if (wc == L'[' && *wpat == L'=') /* equivalence class */
|
||||
{
|
||||
wpat++;
|
||||
bracklen++;
|
||||
if (*wpat == L']') /* right bracket can appear as equivalence class */
|
||||
{
|
||||
wpat++;
|
||||
bracklen++;
|
||||
}
|
||||
in_equiv = 1;
|
||||
}
|
||||
else if (in_equiv && wc == L'=' && *wpat == L']')
|
||||
{
|
||||
wpat++;
|
||||
bracklen++;
|
||||
in_equiv = 0;
|
||||
}
|
||||
else
|
||||
bracklen++;
|
||||
}
|
||||
while ((wc = *wpat++) != L']');
|
||||
matlen++; /* bracket expression can only match one char */
|
||||
bad_bracket:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return matlen;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef FOLD
|
||||
/* Compile `gm_loop.c' for single-byte characters. */
|
||||
#define CHAR char
|
||||
#define INT int
|
||||
#define L(CS) CS
|
||||
#define EXTGLOB_PATTERN_P extglob_pattern_p
|
||||
#define MATCH_PATTERN_CHAR match_pattern_char
|
||||
#define MATCHLEN umatchlen
|
||||
#define FOLD(c) ((flags & FNM_CASEFOLD) \
|
||||
? TOLOWER ((unsigned char)c) \
|
||||
: ((unsigned char)c))
|
||||
#ifndef LPAREN
|
||||
#define LPAREN '('
|
||||
#define RPAREN ')'
|
||||
#endif
|
||||
#include "gm_loop.c"
|
||||
|
||||
/* Return 1 of the first character of STRING could match the first
|
||||
character of pattern PAT. Used to avoid n2 calls to strmatch().
|
||||
FLAGS is a subset of strmatch flags; used to do case-insensitive
|
||||
matching for now. */
|
||||
int
|
||||
match_pattern_char (pat, string, flags)
|
||||
char *pat, *string;
|
||||
int flags;
|
||||
{
|
||||
char c;
|
||||
/* Compile `gm_loop.c' again for multibyte characters. */
|
||||
#if HANDLE_MULTIBYTE
|
||||
|
||||
if (*string == 0)
|
||||
return (*pat == '*'); /* XXX - allow only * to match empty string */
|
||||
#define CHAR wchar_t
|
||||
#define INT wint_t
|
||||
#define L(CS) L##CS
|
||||
#define EXTGLOB_PATTERN_P wextglob_pattern_p
|
||||
#define MATCH_PATTERN_CHAR match_pattern_wchar
|
||||
#define MATCHLEN wmatchlen
|
||||
|
||||
switch (c = *pat++)
|
||||
{
|
||||
default:
|
||||
return (FOLD(*string) == FOLD(c));
|
||||
case '\\':
|
||||
return (FOLD(*string) == FOLD(*pat));
|
||||
case '?':
|
||||
return (*pat == LPAREN ? 1 : (*string != '\0'));
|
||||
case '*':
|
||||
return (1);
|
||||
case '+':
|
||||
case '!':
|
||||
case '@':
|
||||
return (*pat == LPAREN ? 1 : (FOLD(*string) == FOLD(c)));
|
||||
case '[':
|
||||
return (*string != '\0');
|
||||
}
|
||||
}
|
||||
#define FOLD(c) ((flags & FNM_CASEFOLD) && iswupper (c) ? towlower (c) : (c))
|
||||
#define LPAREN L'('
|
||||
#define RPAREN L')'
|
||||
#include "gm_loop.c"
|
||||
|
||||
int
|
||||
umatchlen (pat, max)
|
||||
char *pat;
|
||||
size_t max;
|
||||
{
|
||||
char c;
|
||||
int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
if (*pat == 0)
|
||||
return (0);
|
||||
|
||||
matlen = in_cclass = in_collsym = in_equiv = 0;
|
||||
while (c = *pat++)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
default:
|
||||
matlen++;
|
||||
break;
|
||||
case '\\':
|
||||
if (*pat == 0)
|
||||
return ++matlen;
|
||||
else
|
||||
{
|
||||
matlen++;
|
||||
pat++;
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
if (*pat == LPAREN)
|
||||
return (matlen = -1); /* XXX for now */
|
||||
else
|
||||
matlen++;
|
||||
break;
|
||||
case '*':
|
||||
return (matlen = -1);
|
||||
case '+':
|
||||
case '!':
|
||||
case '@':
|
||||
if (*pat == LPAREN)
|
||||
return (matlen = -1); /* XXX for now */
|
||||
else
|
||||
matlen++;
|
||||
break;
|
||||
case '[':
|
||||
/* scan for ending `]', skipping over embedded [:...:] */
|
||||
bracklen = 1;
|
||||
c = *pat++;
|
||||
do
|
||||
{
|
||||
if (c == 0)
|
||||
{
|
||||
pat--; /* back up to NUL */
|
||||
matlen += bracklen;
|
||||
goto bad_bracket;
|
||||
}
|
||||
else if (c == '\\')
|
||||
{
|
||||
/* *pat == backslash-escaped character */
|
||||
bracklen++;
|
||||
/* If the backslash or backslash-escape ends the string,
|
||||
bail. The ++pat skips over the backslash escape */
|
||||
if (*pat == 0 || *++pat == 0)
|
||||
{
|
||||
matlen += bracklen;
|
||||
goto bad_bracket;
|
||||
}
|
||||
}
|
||||
else if (c == '[' && *pat == ':') /* character class */
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
in_cclass = 1;
|
||||
}
|
||||
else if (in_cclass && c == ':' && *pat == ']')
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
in_cclass = 0;
|
||||
}
|
||||
else if (c == '[' && *pat == '.') /* collating symbol */
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
if (*pat == ']') /* right bracket can appear as collating symbol */
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
}
|
||||
in_collsym = 1;
|
||||
}
|
||||
else if (in_collsym && c == '.' && *pat == ']')
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
in_collsym = 0;
|
||||
}
|
||||
else if (c == '[' && *pat == '=') /* equivalence class */
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
if (*pat == ']') /* right bracket can appear as equivalence class */
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
}
|
||||
in_equiv = 1;
|
||||
}
|
||||
else if (in_equiv && c == '=' && *pat == ']')
|
||||
{
|
||||
pat++;
|
||||
bracklen++;
|
||||
in_equiv = 0;
|
||||
}
|
||||
else
|
||||
bracklen++;
|
||||
}
|
||||
while ((c = *pat++) != ']');
|
||||
matlen++; /* bracket expression can only match one char */
|
||||
bad_bracket:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return matlen;
|
||||
}
|
||||
|
||||
#if defined (EXTENDED_GLOB)
|
||||
/* Skip characters in PAT and return the final occurrence of DIRSEP. This
|
||||
|
||||
@@ -625,7 +625,10 @@ stat_char (filename)
|
||||
#endif
|
||||
|
||||
if (r == -1)
|
||||
return (0);
|
||||
{
|
||||
xfree (f);
|
||||
return (0);
|
||||
}
|
||||
|
||||
character = 0;
|
||||
if (S_ISDIR (finfo.st_mode))
|
||||
|
||||
@@ -466,6 +466,8 @@ here_document_to_fd (redirectee, ri)
|
||||
return (fd);
|
||||
}
|
||||
|
||||
SET_CLOSE_ON_EXEC (fd);
|
||||
|
||||
errno = r = 0; /* XXX */
|
||||
/* write_here_document returns 0 on success, errno on failure. */
|
||||
if (redirectee->word)
|
||||
|
||||
@@ -9612,6 +9612,10 @@ add_twochars:
|
||||
tword->flags |= word->flags & (W_ASSIGNARG|W_ASSIGNRHS); /* affects $@ */
|
||||
if (word->flags & W_COMPLETE)
|
||||
tword->flags |= W_COMPLETE; /* for command substitutions */
|
||||
if (word->flags & W_NOCOMSUB)
|
||||
tword->flags |= W_NOCOMSUB;
|
||||
if (word->flags & W_NOPROCSUB)
|
||||
tword->flags |= W_NOPROCSUB;
|
||||
|
||||
temp = (char *)NULL;
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
+8
-2
@@ -16,8 +16,14 @@ export PATH
|
||||
|
||||
# unset BASH_ENV only if it is set
|
||||
[ "${BASH_ENV+set}" = "set" ] && unset BASH_ENV
|
||||
# ditto for SHELLOPTS
|
||||
[ "${SHELLOPTS+set}" = "set" ] && unset SHELLOPTS
|
||||
# can't reliably do it for SHELLOPTS; SHELLOPTS is readonly in bash
|
||||
if [ "${BASH_VERSION+set}" = "set" ]; then
|
||||
export -n SHELLOPTS # just make sure its not exported
|
||||
set +o posix
|
||||
typeset -p SHELLOPTS
|
||||
else
|
||||
[ "${SHELLOPTS+set}" = "set" ] && unset SHELLOPTS 2>/dev/null
|
||||
fi
|
||||
|
||||
: ${THIS_SH:=../bash}
|
||||
export THIS_SH
|
||||
|
||||
Reference in New Issue
Block a user