mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-20 02:12:51 +02:00
bash-5.1 distribution sources and documentation
This commit is contained in:
+158
-62
@@ -1,6 +1,6 @@
|
||||
/* glob.c -- file-name wildcard pattern matching for Bash.
|
||||
|
||||
Copyright (C) 1985-2017 Free Software Foundation, Inc.
|
||||
Copyright (C) 1985-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include "shell.h"
|
||||
#include "general.h"
|
||||
|
||||
#include "glob.h"
|
||||
#include "strmatch.h"
|
||||
@@ -83,11 +84,11 @@ struct globval
|
||||
char *name;
|
||||
};
|
||||
|
||||
extern void throw_to_top_level __P((void));
|
||||
extern int sh_eaccess __P((const char *, int));
|
||||
extern char *sh_makepath __P((const char *, const char *, int));
|
||||
extern int signal_is_pending __P((int));
|
||||
extern void run_pending_traps __P((void));
|
||||
extern void throw_to_top_level PARAMS((void));
|
||||
extern int sh_eaccess PARAMS((const char *, int));
|
||||
extern char *sh_makepath PARAMS((const char *, const char *, int));
|
||||
extern int signal_is_pending PARAMS((int));
|
||||
extern void run_pending_traps PARAMS((void));
|
||||
|
||||
extern int extended_glob;
|
||||
|
||||
@@ -99,34 +100,40 @@ int noglob_dot_filenames = 1;
|
||||
is done without regard to case. */
|
||||
int glob_ignore_case = 0;
|
||||
|
||||
/* Global variable controlling whether globbing ever returns . or ..
|
||||
regardless of the pattern. If set to 1, no glob pattern will ever
|
||||
match `.' or `..'. Disabled by default. */
|
||||
int glob_always_skip_dot_and_dotdot = 0;
|
||||
|
||||
/* Global variable to return to signify an error in globbing. */
|
||||
char *glob_error_return;
|
||||
|
||||
static struct globval finddirs_error_return;
|
||||
|
||||
/* Some forward declarations. */
|
||||
static int skipname __P((char *, char *, int));
|
||||
static int skipname PARAMS((char *, char *, int));
|
||||
#if HANDLE_MULTIBYTE
|
||||
static int mbskipname __P((char *, char *, int));
|
||||
static int mbskipname PARAMS((char *, char *, int));
|
||||
#endif
|
||||
void udequote_pathname PARAMS((char *));
|
||||
#if HANDLE_MULTIBYTE
|
||||
static void udequote_pathname __P((char *));
|
||||
static void wdequote_pathname __P((char *));
|
||||
void wcdequote_pathname PARAMS((wchar_t *));
|
||||
static void wdequote_pathname PARAMS((char *));
|
||||
#else
|
||||
# define dequote_pathname udequote_pathname
|
||||
#endif
|
||||
static void dequote_pathname __P((char *));
|
||||
static int glob_testdir __P((char *, int));
|
||||
static char **glob_dir_to_array __P((char *, char **, int));
|
||||
static void dequote_pathname PARAMS((char *));
|
||||
static int glob_testdir PARAMS((char *, int));
|
||||
static char **glob_dir_to_array PARAMS((char *, char **, int));
|
||||
|
||||
/* 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));
|
||||
extern char *glob_patscan PARAMS((char *, char *, int));
|
||||
extern wchar_t *glob_patscan_wc PARAMS((wchar_t *, wchar_t *, int));
|
||||
|
||||
/* And this from gmisc.c/gm_loop.c */
|
||||
extern int wextglob_pattern_p __P((wchar_t *));
|
||||
extern int wextglob_pattern_p PARAMS((wchar_t *));
|
||||
|
||||
extern char *glob_dirscan __P((char *, int));
|
||||
extern char *glob_dirscan PARAMS((char *, int));
|
||||
|
||||
/* Compile `glob_loop.c' for single-byte characters. */
|
||||
#define GCHAR unsigned char
|
||||
@@ -159,7 +166,7 @@ glob_pattern_p (pattern)
|
||||
wchar_t *wpattern;
|
||||
int r;
|
||||
|
||||
if (MB_CUR_MAX == 1)
|
||||
if (MB_CUR_MAX == 1 || mbsmbchar (pattern) == 0)
|
||||
return (internal_glob_pattern_p ((unsigned char *)pattern));
|
||||
|
||||
/* Convert strings to wide chars, and call the multibyte version. */
|
||||
@@ -173,7 +180,7 @@ glob_pattern_p (pattern)
|
||||
|
||||
return r;
|
||||
#else
|
||||
return (internal_glob_pattern_p (pattern));
|
||||
return (internal_glob_pattern_p ((unsigned char *)pattern));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -187,7 +194,7 @@ extglob_skipname (pat, dname, flags)
|
||||
int flags;
|
||||
{
|
||||
char *pp, *pe, *t, *se;
|
||||
int n, r, negate, wild;
|
||||
int n, r, negate, wild, nullpat;
|
||||
|
||||
negate = *pat == '!';
|
||||
wild = *pat == '*' || *pat == '?';
|
||||
@@ -214,6 +221,11 @@ extglob_skipname (pat, dname, flags)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Is the extglob pattern between the parens the null pattern? The null
|
||||
pattern can match nothing, so should we check any remaining portion of
|
||||
the pattern? */
|
||||
nullpat = pe >= (pat + 2) && pe[-2] == '(' && pe[-1] == ')';
|
||||
|
||||
/* check every subpattern */
|
||||
while (t = glob_patscan (pp, pe, '|'))
|
||||
{
|
||||
@@ -257,12 +269,14 @@ skipname (pat, dname, flags)
|
||||
return (extglob_skipname (pat, dname, flags));
|
||||
#endif
|
||||
|
||||
if (glob_always_skip_dot_and_dotdot && DOT_OR_DOTDOT (dname))
|
||||
return 1;
|
||||
|
||||
/* 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[0] != '.' &&
|
||||
(pat[0] != '\\' || pat[1] != '.') &&
|
||||
(dname[0] == '.' &&
|
||||
(dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))))
|
||||
DOT_OR_DOTDOT (dname))
|
||||
return 1;
|
||||
|
||||
/* If a dot must be explicitly matched, check to see if they do. */
|
||||
@@ -280,12 +294,14 @@ wskipname (pat, dname, flags)
|
||||
wchar_t *pat, *dname;
|
||||
int flags;
|
||||
{
|
||||
if (glob_always_skip_dot_and_dotdot && WDOT_OR_DOTDOT (dname))
|
||||
return 1;
|
||||
|
||||
/* 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[0] != L'.' &&
|
||||
(pat[0] != L'\\' || pat[1] != L'.') &&
|
||||
(dname[0] == L'.' &&
|
||||
(dname[1] == L'\0' || (dname[1] == L'.' && dname[2] == L'\0'))))
|
||||
WDOT_OR_DOTDOT (dname))
|
||||
return 1;
|
||||
|
||||
/* If a leading dot must be explicitly matched, check to see if the
|
||||
@@ -305,7 +321,7 @@ wextglob_skipname (pat, dname, flags)
|
||||
{
|
||||
#if EXTENDED_GLOB
|
||||
wchar_t *pp, *pe, *t, n, *se;
|
||||
int r, negate, wild;
|
||||
int r, negate, wild, nullpat;
|
||||
|
||||
negate = *pat == L'!';
|
||||
wild = *pat == L'*' || *pat == L'?';
|
||||
@@ -323,6 +339,11 @@ wextglob_skipname (pat, dname, flags)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Is the extglob pattern between the parens the null pattern? The null
|
||||
pattern can match nothing, so should we check any remaining portion of
|
||||
the pattern? */
|
||||
nullpat = pe >= (pat + 2) && pe[-2] == L'(' && pe[-1] == L')';
|
||||
|
||||
/* check every subpattern */
|
||||
while (t = glob_patscan_wc (pp, pe, '|'))
|
||||
{
|
||||
@@ -389,7 +410,7 @@ mbskipname (pat, dname, flags)
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
|
||||
static void
|
||||
void
|
||||
udequote_pathname (pathname)
|
||||
char *pathname;
|
||||
{
|
||||
@@ -411,26 +432,11 @@ udequote_pathname (pathname)
|
||||
|
||||
#if HANDLE_MULTIBYTE
|
||||
/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
|
||||
static void
|
||||
wdequote_pathname (pathname)
|
||||
char *pathname;
|
||||
void
|
||||
wcdequote_pathname (wpathname)
|
||||
wchar_t *wpathname;
|
||||
{
|
||||
mbstate_t ps;
|
||||
size_t len, n;
|
||||
wchar_t *wpathname;
|
||||
int i, j;
|
||||
wchar_t *orig_wpathname;
|
||||
|
||||
len = strlen (pathname);
|
||||
/* Convert the strings into wide characters. */
|
||||
n = xdupmbstowcs (&wpathname, NULL, pathname);
|
||||
if (n == (size_t) -1)
|
||||
{
|
||||
/* Something wrong. Fall back to single-byte */
|
||||
udequote_pathname (pathname);
|
||||
return;
|
||||
}
|
||||
orig_wpathname = wpathname;
|
||||
|
||||
for (i = j = 0; wpathname && wpathname[i]; )
|
||||
{
|
||||
@@ -444,10 +450,46 @@ wdequote_pathname (pathname)
|
||||
}
|
||||
if (wpathname)
|
||||
wpathname[j] = L'\0';
|
||||
}
|
||||
|
||||
static void
|
||||
wdequote_pathname (pathname)
|
||||
char *pathname;
|
||||
{
|
||||
mbstate_t ps;
|
||||
size_t len, n;
|
||||
wchar_t *wpathname;
|
||||
int i, j;
|
||||
wchar_t *orig_wpathname;
|
||||
|
||||
if (mbsmbchar (pathname) == 0)
|
||||
{
|
||||
udequote_pathname (pathname);
|
||||
return;
|
||||
}
|
||||
|
||||
len = strlen (pathname);
|
||||
/* Convert the strings into wide characters. */
|
||||
n = xdupmbstowcs (&wpathname, NULL, pathname);
|
||||
if (n == (size_t) -1)
|
||||
{
|
||||
/* Something wrong. Fall back to single-byte */
|
||||
udequote_pathname (pathname);
|
||||
return;
|
||||
}
|
||||
orig_wpathname = wpathname;
|
||||
|
||||
wcdequote_pathname (wpathname);
|
||||
|
||||
/* Convert the wide character string into unibyte character set. */
|
||||
memset (&ps, '\0', sizeof(mbstate_t));
|
||||
n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps);
|
||||
if (n == (size_t)-1 || (wpathname && *wpathname != 0)) /* what? now you tell me? */
|
||||
{
|
||||
wpathname = orig_wpathname;
|
||||
memset (&ps, '\0', sizeof(mbstate_t));
|
||||
n = xwcsrtombs (pathname, (const wchar_t **)&wpathname, len, &ps);
|
||||
}
|
||||
pathname[len] = '\0';
|
||||
|
||||
/* Can't just free wpathname here; wcsrtombs changes it in many cases. */
|
||||
@@ -607,6 +649,7 @@ glob_vector (pat, dir, flags)
|
||||
register unsigned int i;
|
||||
int mflags; /* Flags passed to strmatch (). */
|
||||
int pflags; /* flags passed to sh_makepath () */
|
||||
int hasglob; /* return value from glob_pattern_p */
|
||||
int nalloca;
|
||||
struct globval *firstmalloc, *tmplink;
|
||||
char *convfn;
|
||||
@@ -648,10 +691,12 @@ glob_vector (pat, dir, flags)
|
||||
patlen = (pat && *pat) ? strlen (pat) : 0;
|
||||
|
||||
/* If the filename pattern (PAT) does not contain any globbing characters,
|
||||
or contains a pattern with only backslash escapes (hasglob == 2),
|
||||
we can dispense with reading the directory, and just see if there is
|
||||
a filename `DIR/PAT'. If there is, and we can access it, just make the
|
||||
vector to return and bail immediately. */
|
||||
if (skip == 0 && glob_pattern_p (pat) == 0)
|
||||
hasglob = 0;
|
||||
if (skip == 0 && ((hasglob = glob_pattern_p (pat)) == 0 || hasglob == 2))
|
||||
{
|
||||
int dirlen;
|
||||
struct stat finfo;
|
||||
@@ -807,14 +852,6 @@ glob_vector (pat, dir, flags)
|
||||
}
|
||||
}
|
||||
|
||||
/* When FLAGS includes GX_ALLDIRS, we want to skip a symlink
|
||||
to a directory, since we will pick the directory up later. */
|
||||
if (isdir == -2 && glob_testdir (subdir, 0) == 0)
|
||||
{
|
||||
free (subdir);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* XXX - should we even add this if it's not a directory? */
|
||||
nextlink = (struct globval *) malloc (sizeof (struct globval));
|
||||
if (firstmalloc == 0)
|
||||
@@ -1024,17 +1061,22 @@ glob_dir_to_array (dir, array, flags)
|
||||
strcpy (result[i], dir);
|
||||
if (add_slash)
|
||||
result[i][l] = '/';
|
||||
strcpy (result[i] + l + add_slash, array[i]);
|
||||
if (flags & GX_MARKDIRS)
|
||||
if (array[i][0])
|
||||
{
|
||||
if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode))
|
||||
strcpy (result[i] + l + add_slash, array[i]);
|
||||
if (flags & GX_MARKDIRS)
|
||||
{
|
||||
size_t rlen;
|
||||
rlen = strlen (result[i]);
|
||||
result[i][rlen] = '/';
|
||||
result[i][rlen+1] = '\0';
|
||||
if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode))
|
||||
{
|
||||
size_t rlen;
|
||||
rlen = strlen (result[i]);
|
||||
result[i][rlen] = '/';
|
||||
result[i][rlen+1] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
result[i][l+add_slash] = '\0';
|
||||
}
|
||||
result[i] = NULL;
|
||||
|
||||
@@ -1228,6 +1270,7 @@ glob_filename (pathname, flags)
|
||||
files ending in `h' with a `/' appended. */
|
||||
dname = directories[i];
|
||||
dflags = flags & ~(GX_MARKDIRS|GX_ALLDIRS|GX_ADDCURDIR);
|
||||
/* last_starstar? */
|
||||
if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
|
||||
dflags |= GX_ALLDIRS|GX_ADDCURDIR;
|
||||
if (dname[0] == '\0' && filename[0])
|
||||
@@ -1235,7 +1278,44 @@ glob_filename (pathname, flags)
|
||||
dflags |= GX_NULLDIR;
|
||||
dname = "."; /* treat null directory name and non-null filename as current directory */
|
||||
}
|
||||
temp_results = glob_vector (filename, dname, dflags);
|
||||
|
||||
/* Special handling for symlinks to directories with globstar on */
|
||||
if (all_starstar && (dflags & GX_NULLDIR) == 0)
|
||||
{
|
||||
int dlen;
|
||||
|
||||
/* If we have a directory name that is not null (GX_NULLDIR above)
|
||||
and is a symlink to a directory, we return the symlink if
|
||||
we're not `descending' into it (filename[0] == 0) and return
|
||||
glob_error_return (which causes the code below to skip the
|
||||
name) otherwise. I should fold this into a test that does both
|
||||
checks instead of calling stat twice. */
|
||||
if (glob_testdir (dname, flags|GX_ALLDIRS) == -2 && glob_testdir (dname, 0) == 0)
|
||||
{
|
||||
if (filename[0] != 0)
|
||||
temp_results = (char **)&glob_error_return; /* skip */
|
||||
else
|
||||
{
|
||||
/* Construct array to pass to glob_dir_to_array */
|
||||
temp_results = (char **)malloc (2 * sizeof (char *));
|
||||
if (temp_results == NULL)
|
||||
goto memory_error;
|
||||
temp_results[0] = (char *)malloc (1);
|
||||
if (temp_results[0] == 0)
|
||||
{
|
||||
free (temp_results);
|
||||
goto memory_error;
|
||||
}
|
||||
**temp_results = '\0';
|
||||
temp_results[1] = NULL;
|
||||
dflags |= GX_SYMLINK; /* mostly for debugging */
|
||||
}
|
||||
}
|
||||
else
|
||||
temp_results = glob_vector (filename, dname, dflags);
|
||||
}
|
||||
else
|
||||
temp_results = glob_vector (filename, dname, dflags);
|
||||
|
||||
/* Handle error cases. */
|
||||
if (temp_results == NULL)
|
||||
@@ -1283,6 +1363,8 @@ glob_filename (pathname, flags)
|
||||
else
|
||||
array = temp_results;
|
||||
}
|
||||
else if (dflags & GX_SYMLINK)
|
||||
array = glob_dir_to_array (directories[i], temp_results, flags);
|
||||
else
|
||||
array = glob_dir_to_array (directories[i], temp_results, flags);
|
||||
l = 0;
|
||||
@@ -1347,7 +1429,21 @@ only_filename:
|
||||
|
||||
/* We could check whether or not the dequoted directory_name is a
|
||||
directory and return it here, returning the original directory_name
|
||||
if not, but we don't do that yet. I'm not sure it matters. */
|
||||
if not, but we don't do that. We do return the dequoted directory
|
||||
name if we're not being called recursively and the dequoted name
|
||||
corresponds to an actual directory. For better backwards compatibility,
|
||||
we can return &glob_error_return unconditionally in this case. */
|
||||
|
||||
if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) == 0)
|
||||
{
|
||||
dequote_pathname (directory_name);
|
||||
if (glob_testdir (directory_name, 0) < 0)
|
||||
{
|
||||
if (free_dirname)
|
||||
free (directory_name);
|
||||
return ((char **)&glob_error_return);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle GX_MARKDIRS here. */
|
||||
result[0] = (char *) malloc (directory_len + 1);
|
||||
|
||||
+6
-5
@@ -1,5 +1,5 @@
|
||||
/* File-name wildcard pattern matching for GNU.
|
||||
Copyright (C) 1985, 1988, 1989, 2008,2009 Free Software Foundation, Inc.
|
||||
Copyright (C) 1985-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -31,12 +31,13 @@
|
||||
#define GX_ADDCURDIR 0x200 /* internal -- add passed directory name */
|
||||
#define GX_GLOBSTAR 0x400 /* turn on special handling of ** */
|
||||
#define GX_RECURSE 0x800 /* internal -- glob_filename called recursively */
|
||||
#define GX_SYMLINK 0x1000 /* internal -- symlink to a directory */
|
||||
|
||||
extern int glob_pattern_p __P((const char *));
|
||||
extern char **glob_vector __P((char *, char *, int));
|
||||
extern char **glob_filename __P((char *, int));
|
||||
extern int glob_pattern_p PARAMS((const char *));
|
||||
extern char **glob_vector PARAMS((char *, char *, int));
|
||||
extern char **glob_filename PARAMS((char *, int));
|
||||
|
||||
extern int extglob_pattern_p __P((const char *));
|
||||
extern int extglob_pattern_p PARAMS((const char *));
|
||||
|
||||
extern char *glob_error_return;
|
||||
extern int noglob_dot_filenames;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
static int INTERNAL_GLOB_PATTERN_P __P((const GCHAR *));
|
||||
static int INTERNAL_GLOB_PATTERN_P PARAMS((const GCHAR *));
|
||||
|
||||
/* Return nonzero if PATTERN has any special globbing chars in it.
|
||||
Compiled twice, once each for single-byte and multibyte characters. */
|
||||
@@ -70,7 +70,11 @@ INTERNAL_GLOB_PATTERN_P (pattern)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
return bsquote ? 2 : 0;
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef INTERNAL_GLOB_PATTERN_P
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* gmisc.c -- miscellaneous pattern matching utility functions for Bash.
|
||||
|
||||
Copyright (C) 2010-2017 Free Software Foundation, Inc.
|
||||
Copyright (C) 2010-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#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 char *glob_patscan PARAMS((char *, char *, int));
|
||||
|
||||
/* Compile `gm_loop.c' for single-byte characters. */
|
||||
#define CHAR char
|
||||
|
||||
+35
-20
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -22,14 +22,16 @@ struct STRUCT
|
||||
CHAR *string;
|
||||
};
|
||||
|
||||
int FCT __P((CHAR *, CHAR *, int));
|
||||
int FCT PARAMS((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));
|
||||
static int GMATCH PARAMS((CHAR *, CHAR *, CHAR *, CHAR *, struct STRUCT *, int));
|
||||
static CHAR *PARSE_COLLSYM PARAMS((CHAR *, INT *));
|
||||
static CHAR *BRACKMATCH PARAMS((CHAR *, U_CHAR, int));
|
||||
static int EXTMATCH PARAMS((INT, CHAR *, CHAR *, CHAR *, CHAR *, int));
|
||||
|
||||
/*static*/ CHAR *PATSCAN __P((CHAR *, CHAR *, INT));
|
||||
extern void DEQUOTE_PATHNAME PARAMS((CHAR *));
|
||||
|
||||
/*static*/ CHAR *PATSCAN PARAMS((CHAR *, CHAR *, INT));
|
||||
|
||||
int
|
||||
FCT (pattern, string, flags)
|
||||
@@ -384,9 +386,10 @@ BRACKMATCH (p, test, flags)
|
||||
{
|
||||
register CHAR cstart, cend, c;
|
||||
register int not; /* Nonzero if the sense of the character class is inverted. */
|
||||
int brcnt, brchr, forcecoll, isrange;
|
||||
int brcnt, forcecoll, isrange;
|
||||
INT pc;
|
||||
CHAR *savep;
|
||||
CHAR *brchrp;
|
||||
U_CHAR orig_test;
|
||||
|
||||
orig_test = test;
|
||||
@@ -455,6 +458,9 @@ BRACKMATCH (p, test, flags)
|
||||
{
|
||||
bcopy (p + 1, ccname, (close - p - 1) * sizeof (CHAR));
|
||||
*(ccname + (close - p - 1)) = L('\0');
|
||||
/* As a result of a POSIX discussion, char class names are
|
||||
allowed to be quoted (?) */
|
||||
DEQUOTE_PATHNAME (ccname);
|
||||
pc = IS_CCLASS (orig_test, (XCHAR *)ccname);
|
||||
}
|
||||
if (pc == -1)
|
||||
@@ -577,15 +583,10 @@ BRACKMATCH (p, test, flags)
|
||||
isrange = 1;
|
||||
}
|
||||
|
||||
#if 0 /* TAG: bash-5.1 */
|
||||
if (isrange == 0 && test == cstart)
|
||||
goto matched;
|
||||
if (isrange && RANGECMP (test, cstart, forcecoll) >= 0 && RANGECMP (test, cend, forcecoll) <= 0)
|
||||
goto matched;
|
||||
#else
|
||||
if (RANGECMP (test, cstart, forcecoll) >= 0 && RANGECMP (test, cend, forcecoll) <= 0)
|
||||
goto matched;
|
||||
#endif
|
||||
|
||||
if (c == L(']'))
|
||||
break;
|
||||
@@ -597,7 +598,7 @@ matched:
|
||||
/* Skip the rest of the [...] that already matched. */
|
||||
c = *--p;
|
||||
brcnt = 1;
|
||||
brchr = 0;
|
||||
brchrp = 0;
|
||||
while (brcnt > 0)
|
||||
{
|
||||
int oc;
|
||||
@@ -611,13 +612,26 @@ matched:
|
||||
if (c == L('[') && (*p == L('=') || *p == L(':') || *p == L('.')))
|
||||
{
|
||||
brcnt++;
|
||||
brchr = *p;
|
||||
brchrp = p++; /* skip over the char after the left bracket */
|
||||
if ((c = *p) == L('\0'))
|
||||
return ((test == L('[')) ? savep : (CHAR *)0);
|
||||
/* If *brchrp == ':' we should check that the rest of the characters
|
||||
form a valid character class name. We don't do that yet, but we
|
||||
keep BRCHRP in case we want to. */
|
||||
}
|
||||
/* we only want to check brchr if we set it above */
|
||||
else if (c == L(']') && brcnt > 1 && brchr != 0 && oc == brchr)
|
||||
brcnt--;
|
||||
else if (c == L(']') && brcnt == 1)
|
||||
brcnt--;
|
||||
/* We only want to check brchrp if we set it above. */
|
||||
else if (c == L(']') && brcnt > 1 && brchrp != 0 && oc == *brchrp)
|
||||
{
|
||||
brcnt--;
|
||||
brchrp = 0; /* just in case */
|
||||
}
|
||||
/* Left bracket loses its special meaning inside a bracket expression.
|
||||
It is only valid when followed by a `.', `=', or `:', which we check
|
||||
for above. Technically the right bracket can appear in a collating
|
||||
symbol, so we check for that here. Otherwise, it terminates the
|
||||
bracket expression. */
|
||||
else if (c == L(']') && (brchrp == 0 || *brchrp != L('.')) && brcnt >= 1)
|
||||
brcnt = 0;
|
||||
else if (!(flags & FNM_NOESCAPE) && c == L('\\'))
|
||||
{
|
||||
if (*p == '\0')
|
||||
@@ -915,6 +929,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
|
||||
#undef PATSCAN
|
||||
#undef STRCOMPARE
|
||||
#undef EXTMATCH
|
||||
#undef DEQUOTE_PATHNAME
|
||||
#undef STRUCT
|
||||
#undef BRACKMATCH
|
||||
#undef STRCHR
|
||||
|
||||
+90
-28
@@ -1,7 +1,7 @@
|
||||
/* strmatch.c -- ksh-like extended pattern matching for the shell and filename
|
||||
globbing. */
|
||||
|
||||
/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -36,6 +36,12 @@
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if FNMATCH_EQUIV_FALLBACK
|
||||
/* We don't include <fnmatch.h> in order to avoid namespace collisions; the
|
||||
internal strmatch still uses the FNM_ constants. */
|
||||
extern int fnmatch (const char *, const char *, int);
|
||||
#endif
|
||||
|
||||
/* First, compile `sm_loop.c' for single-byte characters. */
|
||||
#define CHAR unsigned char
|
||||
#define U_CHAR unsigned char
|
||||
@@ -55,6 +61,32 @@ extern int errno;
|
||||
|
||||
int glob_asciirange = GLOBASCII_DEFAULT;
|
||||
|
||||
#if FNMATCH_EQUIV_FALLBACK
|
||||
/* Construct a string w1 = "c1" and a pattern w2 = "[[=c2=]]" and pass them
|
||||
to fnmatch to see if wide characters c1 and c2 collate as members of the
|
||||
same equivalence class. We can't really do this portably any other way */
|
||||
static int
|
||||
_fnmatch_fallback (s, p)
|
||||
int s, p; /* string char, patchar */
|
||||
{
|
||||
char s1[2]; /* string */
|
||||
char s2[8]; /* constructed pattern */
|
||||
|
||||
s1[0] = (unsigned char)s;
|
||||
s1[1] = '\0';
|
||||
|
||||
/* reconstruct the pattern */
|
||||
s2[0] = s2[1] = '[';
|
||||
s2[2] = '=';
|
||||
s2[3] = (unsigned char)p;
|
||||
s2[4] = '=';
|
||||
s2[5] = s2[6] = ']';
|
||||
s2[7] = '\0';
|
||||
|
||||
return (fnmatch ((const char *)s2, (const char *)s1, 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We use strcoll(3) for range comparisons in bracket expressions,
|
||||
even though it can have unwanted side effects in locales
|
||||
other than POSIX or US. For instance, in the de locale, [A-Z] matches
|
||||
@@ -63,9 +95,11 @@ int glob_asciirange = GLOBASCII_DEFAULT;
|
||||
straight ordering as if in the C locale. */
|
||||
|
||||
#if defined (HAVE_STRCOLL)
|
||||
/* Helper function for collating symbol equivalence. */
|
||||
/* Helper functions for collating symbol equivalence. */
|
||||
|
||||
/* Return 0 if C1 == C2 or collates equally if FORCECOLL is non-zero. */
|
||||
static int
|
||||
rangecmp (c1, c2, forcecoll)
|
||||
charcmp (c1, c2, forcecoll)
|
||||
int c1, c2;
|
||||
int forcecoll;
|
||||
{
|
||||
@@ -86,8 +120,21 @@ rangecmp (c1, c2, forcecoll)
|
||||
s1[0] = c1;
|
||||
s2[0] = c2;
|
||||
|
||||
if ((ret = strcoll (s1, s2)) != 0)
|
||||
return ret;
|
||||
return (strcoll (s1, s2));
|
||||
}
|
||||
|
||||
static int
|
||||
rangecmp (c1, c2, forcecoll)
|
||||
int c1, c2;
|
||||
int forcecoll;
|
||||
{
|
||||
int r;
|
||||
|
||||
r = charcmp (c1, c2, forcecoll);
|
||||
|
||||
/* We impose a total ordering here by returning c1-c2 if charcmp returns 0 */
|
||||
if (r != 0)
|
||||
return r;
|
||||
return (c1 - c2); /* impose total ordering */
|
||||
}
|
||||
#else /* !HAVE_STRCOLL */
|
||||
@@ -95,14 +142,23 @@ rangecmp (c1, c2, forcecoll)
|
||||
#endif /* !HAVE_STRCOLL */
|
||||
|
||||
#if defined (HAVE_STRCOLL)
|
||||
/* Returns 1 if chars C and EQUIV collate equally in the current locale. */
|
||||
static int
|
||||
collequiv (c1, c2)
|
||||
int c1, c2;
|
||||
collequiv (c, equiv)
|
||||
int c, equiv;
|
||||
{
|
||||
return (rangecmp (c1, c2, 1) == 0);
|
||||
if (charcmp (c, equiv, 1) == 0)
|
||||
return 1;
|
||||
|
||||
#if FNMATCH_EQUIV_FALLBACK
|
||||
return (_fnmatch_fallback (c, equiv) == 0);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
#else
|
||||
# define collequiv(c1, c2) ((c1) == (c2))
|
||||
# define collequiv(c, equiv) ((c) == (equiv))
|
||||
#endif
|
||||
|
||||
#define _COLLSYM _collsym
|
||||
@@ -260,6 +316,7 @@ is_cclass (c, name)
|
||||
#define PATSCAN glob_patscan
|
||||
#define STRCOMPARE strcompare
|
||||
#define EXTMATCH extmatch
|
||||
#define DEQUOTE_PATHNAME udequote_pathname
|
||||
#define STRUCT smat_struct
|
||||
#define STRCHR(S, C) strchr((S), (C))
|
||||
#define MEMCHR(S, C, N) memchr((S), (C), (N))
|
||||
@@ -286,13 +343,9 @@ is_cclass (c, name)
|
||||
# define STREQ(s1, s2) ((wcscmp (s1, s2) == 0))
|
||||
# define STREQN(a, b, n) ((a)[0] == (b)[0] && wcsncmp(a, b, n) == 0)
|
||||
|
||||
extern char *mbsmbchar __P((const char *));
|
||||
extern char *mbsmbchar PARAMS((const char *));
|
||||
|
||||
#if FNMATCH_EQUIV_FALLBACK
|
||||
/* We don't include <fnmatch.h> in order to avoid namespace collisions; the
|
||||
internal strmatch still uses the FNM_ constants. */
|
||||
extern int fnmatch (const char *, const char *, int);
|
||||
|
||||
/* Construct a string w1 = "c1" and a pattern w2 = "[[=c2=]]" and pass them
|
||||
to fnmatch to see if wide characters c1 and c2 collate as members of the
|
||||
same equivalence class. We can't really do this portably any other way */
|
||||
@@ -324,13 +377,13 @@ _fnmatch_fallback_wc (c1, c2)
|
||||
#endif
|
||||
|
||||
static int
|
||||
rangecmp_wc (c1, c2, forcecoll)
|
||||
charcmp_wc (c1, c2, forcecoll)
|
||||
wint_t c1, c2;
|
||||
int forcecoll;
|
||||
{
|
||||
static wchar_t s1[2] = { L' ', L'\0' };
|
||||
static wchar_t s2[2] = { L' ', L'\0' };
|
||||
int r, oerrno;
|
||||
int r;
|
||||
|
||||
if (c1 == c2)
|
||||
return 0;
|
||||
@@ -341,27 +394,35 @@ rangecmp_wc (c1, c2, forcecoll)
|
||||
s1[0] = c1;
|
||||
s2[0] = c2;
|
||||
|
||||
#if 0 /* TAG:bash-5.1 */
|
||||
/* We impose a total ordering here by returning c1-c2 if wcscoll returns 0,
|
||||
as we do above in the single-byte case. If we do this, we can no longer
|
||||
use this code in collequiv_wc */
|
||||
if ((r = wcscoll (s1, s2)) != 0)
|
||||
return r;
|
||||
return ((int)(c1 - c2)); /* impose total ordering */
|
||||
#else
|
||||
return (wcscoll (s1, s2));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Returns non-zero on success */
|
||||
static int
|
||||
rangecmp_wc (c1, c2, forcecoll)
|
||||
wint_t c1, c2;
|
||||
int forcecoll;
|
||||
{
|
||||
int r;
|
||||
|
||||
r = charcmp_wc (c1, c2, forcecoll);
|
||||
|
||||
/* We impose a total ordering here by returning c1-c2 if charcmp returns 0,
|
||||
as we do above in the single-byte case. */
|
||||
if (r != 0 || forcecoll)
|
||||
return r;
|
||||
return ((int)(c1 - c2)); /* impose total ordering */
|
||||
}
|
||||
|
||||
/* Returns 1 if wide chars C and EQUIV collate equally in the current locale. */
|
||||
static int
|
||||
collequiv_wc (c, equiv)
|
||||
wint_t c, equiv;
|
||||
{
|
||||
wchar_t s, p;
|
||||
|
||||
if (rangecmp_wc (c, equiv, 1) == 0)
|
||||
if (charcmp_wc (c, equiv, 1) == 0)
|
||||
return 1;
|
||||
|
||||
#if FNMATCH_EQUIV_FALLBACK
|
||||
/* We check explicitly for success (fnmatch returns 0) to avoid problems if
|
||||
our local definition of FNM_NOMATCH (strmatch.h) doesn't match the
|
||||
@@ -500,6 +561,7 @@ posix_cclass_only (pattern)
|
||||
#define PATSCAN glob_patscan_wc
|
||||
#define STRCOMPARE wscompare
|
||||
#define EXTMATCH extmatch_wc
|
||||
#define DEQUOTE_PATHNAME wcdequote_pathname
|
||||
#define STRUCT wcsmat_struct
|
||||
#define STRCHR(S, C) wcschr((S), (C))
|
||||
#define MEMCHR(S, C, N) wmemchr((S), (C), (N))
|
||||
@@ -529,7 +591,7 @@ xstrmatch (pattern, string, flags)
|
||||
if (MB_CUR_MAX == 1)
|
||||
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
|
||||
|
||||
if (mbsmbchar (string) == 0 && mbsmbchar (pattern) == 0 && posix_cclass_only (pattern) )
|
||||
if (mbsmbchar (string) == 0 && mbsmbchar (pattern) == 0 && posix_cclass_only (pattern))
|
||||
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
|
||||
|
||||
n = xdupmbstowcs (&wpattern, NULL, pattern);
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
/* strmatch.c -- ksh-like extended pattern matching for the shell and filename
|
||||
globbing. */
|
||||
|
||||
/* Copyright (C) 1991-2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
#include "stdc.h"
|
||||
#include "strmatch.h"
|
||||
|
||||
extern int xstrmatch __P((char *, char *, int));
|
||||
extern int xstrmatch PARAMS((char *, char *, int));
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
extern int internal_wstrmatch __P((wchar_t *, wchar_t *, int));
|
||||
extern int internal_wstrmatch PARAMS((wchar_t *, wchar_t *, int));
|
||||
#endif
|
||||
|
||||
int
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991-2004 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -55,10 +55,10 @@
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN,
|
||||
returning zero if it matches, FNM_NOMATCH if not. */
|
||||
extern int strmatch __P((char *, char *, int));
|
||||
extern int strmatch PARAMS((char *, char *, int));
|
||||
|
||||
#if HANDLE_MULTIBYTE
|
||||
extern int wcsmatch __P((wchar_t *, wchar_t *, int));
|
||||
extern int wcsmatch PARAMS((wchar_t *, wchar_t *, int));
|
||||
#endif
|
||||
|
||||
#endif /* _STRMATCH_H */
|
||||
|
||||
+116
-2
@@ -1,6 +1,6 @@
|
||||
/* xmbsrtowcs.c -- replacement function for mbsrtowcs */
|
||||
|
||||
/* Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
|
||||
#if HANDLE_MULTIBYTE
|
||||
|
||||
#include <errno.h>
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#define WSBUF_INC 32
|
||||
|
||||
#ifndef FREE
|
||||
@@ -42,7 +47,7 @@
|
||||
#endif
|
||||
|
||||
#if ! HAVE_STRCHRNUL
|
||||
extern char *strchrnul __P((const char *, int));
|
||||
extern char *strchrnul PARAMS((const char *, int));
|
||||
#endif
|
||||
|
||||
/* On some locales (ex. ja_JP.sjis), mbsrtowc doesn't convert 0x5c to U<0x5c>.
|
||||
@@ -406,4 +411,113 @@ xdupmbstowcs (destp, indicesp, src)
|
||||
return (wcnum - 1);
|
||||
}
|
||||
|
||||
/* Convert wide character string to multibyte character string. Treat invalid
|
||||
wide characters as bytes. Used only in unusual circumstances.
|
||||
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2008, adapted by Chet Ramey
|
||||
for use in Bash. */
|
||||
|
||||
/* Convert wide character string *SRCP to a multibyte character string and
|
||||
store the result in DEST. Store at most LEN bytes in DEST. */
|
||||
size_t
|
||||
xwcsrtombs (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps)
|
||||
{
|
||||
const wchar_t *src;
|
||||
size_t cur_max; /* XXX - locale_cur_max */
|
||||
char buf[64], *destptr, *tmp_dest;
|
||||
unsigned char uc;
|
||||
mbstate_t prev_state;
|
||||
|
||||
cur_max = MB_CUR_MAX;
|
||||
if (cur_max > sizeof (buf)) /* Holy cow. */
|
||||
return (size_t)-1;
|
||||
|
||||
src = *srcp;
|
||||
|
||||
if (dest != NULL)
|
||||
{
|
||||
destptr = dest;
|
||||
|
||||
for (; len > 0; src++)
|
||||
{
|
||||
wchar_t wc;
|
||||
size_t ret;
|
||||
|
||||
wc = *src;
|
||||
/* If we have room, store directly into DEST. */
|
||||
tmp_dest = destptr;
|
||||
ret = wcrtomb (len >= cur_max ? destptr : buf, wc, ps);
|
||||
|
||||
if (ret == (size_t)(-1)) /* XXX */
|
||||
{
|
||||
/* Since this is used for globbing and other uses of filenames,
|
||||
treat invalid wide character sequences as bytes. This is
|
||||
intended to be symmetric with xdupmbstowcs2. */
|
||||
handle_byte:
|
||||
destptr = tmp_dest; /* in case wcrtomb modified it */
|
||||
uc = wc;
|
||||
ret = 1;
|
||||
if (len >= cur_max)
|
||||
*destptr = uc;
|
||||
else
|
||||
buf[0] = uc;
|
||||
if (ps)
|
||||
memset (ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
|
||||
if (ret > cur_max) /* Holy cow */
|
||||
goto bad_input;
|
||||
|
||||
if (len < ret)
|
||||
break;
|
||||
|
||||
if (len < cur_max)
|
||||
memcpy (destptr, buf, ret);
|
||||
|
||||
if (wc == 0)
|
||||
{
|
||||
src = NULL;
|
||||
/* Here mbsinit (ps). */
|
||||
break;
|
||||
}
|
||||
destptr += ret;
|
||||
len -= ret;
|
||||
}
|
||||
*srcp = src;
|
||||
return destptr - dest;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ignore dest and len, don't store *srcp at the end, and
|
||||
don't clobber *ps. */
|
||||
mbstate_t state = *ps;
|
||||
size_t totalcount = 0;
|
||||
|
||||
for (;; src++)
|
||||
{
|
||||
wchar_t wc;
|
||||
size_t ret;
|
||||
|
||||
wc = *src;
|
||||
ret = wcrtomb (buf, wc, &state);
|
||||
|
||||
if (ret == (size_t)(-1))
|
||||
goto bad_input2;
|
||||
if (wc == 0)
|
||||
{
|
||||
/* Here mbsinit (&state). */
|
||||
break;
|
||||
}
|
||||
totalcount += ret;
|
||||
}
|
||||
return totalcount;
|
||||
}
|
||||
|
||||
bad_input:
|
||||
*srcp = src;
|
||||
bad_input2:
|
||||
errno = EILSEQ;
|
||||
return (size_t)(-1);
|
||||
}
|
||||
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* imalloc.h -- internal malloc definitions shared by source files. */
|
||||
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -67,11 +67,11 @@
|
||||
# endif /* HAVE_BCOPY */
|
||||
#endif /* !__GNUC__ */
|
||||
|
||||
#if !defined (__P)
|
||||
#if !defined (PARAMS)
|
||||
# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) || defined (PROTOTYPES)
|
||||
# define __P(protos) protos
|
||||
# define PARAMS(protos) protos
|
||||
# else
|
||||
# define __P(protos) ()
|
||||
# define PARAMS(protos) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -167,7 +167,7 @@ do { \
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
extern void _malloc_block_signals __P((sigset_t *, sigset_t *));
|
||||
extern void _malloc_unblock_signals __P((sigset_t *, sigset_t *));
|
||||
extern void _malloc_block_signals PARAMS((sigset_t *, sigset_t *));
|
||||
extern void _malloc_unblock_signals PARAMS((sigset_t *, sigset_t *));
|
||||
|
||||
#endif /* _IMALLOC_H */
|
||||
|
||||
+85
-26
@@ -1,6 +1,6 @@
|
||||
/* malloc.c - dynamic memory allocation for bash. */
|
||||
|
||||
/* Copyright (C) 1985-2005 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1985-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
*
|
||||
* Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
|
||||
*
|
||||
* [VERY] old explanation:
|
||||
*
|
||||
* This is a very fast storage allocator. It allocates blocks of a small
|
||||
* number of different sizes, and keeps free lists of each size. Blocks
|
||||
* that don't exactly fit are passed up to the next larger size. In this
|
||||
@@ -84,6 +86,10 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined (botch)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_MMAP)
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
@@ -134,22 +140,35 @@
|
||||
enough room in the block for the new size. Range checking is always
|
||||
done. */
|
||||
union mhead {
|
||||
#if SIZEOF_CHAR_P == 8
|
||||
bits64_t mh_align[2]; /* 16 */
|
||||
#else
|
||||
bits64_t mh_align; /* 8 */
|
||||
#endif
|
||||
struct {
|
||||
char mi_alloc; /* ISALLOC or ISFREE */ /* 1 */
|
||||
char mi_index; /* index in nextf[] */ /* 1 */
|
||||
/* Remainder are valid only when block is allocated */
|
||||
u_bits16_t mi_magic2; /* should be == MAGIC2 */ /* 2 */
|
||||
u_bits32_t mi_nbytes; /* # of bytes allocated */ /* 4 */
|
||||
#if SIZEOF_CHAR_P == 8
|
||||
char mi_magic8[8]; /* MAGIC1 guard bytes */ /* 8 */
|
||||
#endif
|
||||
} minfo;
|
||||
};
|
||||
#define mh_alloc minfo.mi_alloc
|
||||
#define mh_index minfo.mi_index
|
||||
#define mh_nbytes minfo.mi_nbytes
|
||||
#define mh_magic2 minfo.mi_magic2
|
||||
#define mh_magic8 minfo.mi_magic8
|
||||
|
||||
#define MOVERHEAD sizeof(union mhead)
|
||||
|
||||
#if SIZEOF_CHAR_P == 8
|
||||
#define MALIGN_MASK 15
|
||||
#else
|
||||
#define MALIGN_MASK 7 /* one less than desired alignment */
|
||||
#endif
|
||||
|
||||
typedef union _malloc_guard {
|
||||
char s[4];
|
||||
@@ -163,6 +182,8 @@ typedef union _malloc_guard {
|
||||
to describe the overhead for when the block is in use,
|
||||
and we do not want the free-list pointer to count in that. */
|
||||
|
||||
/* If SIZEOF_CHAR_P == 8, this goes into the mh_magic8 buffer at the end of
|
||||
the rest of the struct. This may need adjusting. */
|
||||
#define CHAIN(a) \
|
||||
(*(union mhead **) (sizeof (char *) + (char *) (a)))
|
||||
|
||||
@@ -170,13 +191,14 @@ typedef union _malloc_guard {
|
||||
and end of each allocated block, and make sure they are undisturbed
|
||||
whenever a free or a realloc occurs. */
|
||||
|
||||
/* Written in the 2 bytes before the block's real space (-4 bytes) */
|
||||
/* Written in the bytes before the block's real space (-SIZEOF_CHAR_P bytes) */
|
||||
#define MAGIC1 0x55
|
||||
#define MAGIC2 0x5555
|
||||
#define MSLOP 4 /* 4 bytes extra for u_bits32_t size */
|
||||
|
||||
/* How many bytes are actually allocated for a request of size N --
|
||||
rounded up to nearest multiple of 8 after accounting for malloc
|
||||
overhead. */
|
||||
rounded up to nearest multiple of 2*SIZEOF_CHAR_P after accounting for
|
||||
malloc overhead. */
|
||||
#define ALLOCATED_BYTES(n) \
|
||||
(((n) + MOVERHEAD + MSLOP + MALIGN_MASK) & ~MALIGN_MASK)
|
||||
|
||||
@@ -204,12 +226,12 @@ typedef union _malloc_guard {
|
||||
|
||||
/* Should we use mmap for large allocations? */
|
||||
#if defined (HAVE_MMAP)
|
||||
# if !defined (MAP_ANON) && defined (MAP_ANONYMOUS)
|
||||
# define MAP_ANON MAP_ANONYMOUS
|
||||
# if defined (MAP_ANON) && !defined (MAP_ANONYMOUS)
|
||||
# define MAP_ANONYMOUS MAP_ANON
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_MMAP) && defined (MAP_ANON)
|
||||
#if defined (HAVE_MMAP) && defined (MAP_ANONYMOUS)
|
||||
# define USE_MMAP
|
||||
#endif
|
||||
|
||||
@@ -273,32 +295,32 @@ extern int errno;
|
||||
#endif
|
||||
|
||||
/* Declarations for internal functions */
|
||||
static PTR_T internal_malloc __P((size_t, const char *, int, int));
|
||||
static PTR_T internal_realloc __P((PTR_T, size_t, const char *, int, int));
|
||||
static void internal_free __P((PTR_T, const char *, int, int));
|
||||
static PTR_T internal_memalign __P((size_t, size_t, const char *, int, int));
|
||||
static PTR_T internal_malloc PARAMS((size_t, const char *, int, int));
|
||||
static PTR_T internal_realloc PARAMS((PTR_T, size_t, const char *, int, int));
|
||||
static void internal_free PARAMS((PTR_T, const char *, int, int));
|
||||
static PTR_T internal_memalign PARAMS((size_t, size_t, const char *, int, int));
|
||||
#ifndef NO_CALLOC
|
||||
static PTR_T internal_calloc __P((size_t, size_t, const char *, int, int));
|
||||
static void internal_cfree __P((PTR_T, const char *, int, int));
|
||||
static PTR_T internal_calloc PARAMS((size_t, size_t, const char *, int, int));
|
||||
static void internal_cfree PARAMS((PTR_T, const char *, int, int));
|
||||
#endif
|
||||
#ifndef NO_VALLOC
|
||||
static PTR_T internal_valloc __P((size_t, const char *, int, int));
|
||||
static PTR_T internal_valloc PARAMS((size_t, const char *, int, int));
|
||||
#endif
|
||||
|
||||
#if defined (botch)
|
||||
extern void botch ();
|
||||
#else
|
||||
static void botch __P((const char *, const char *, int));
|
||||
static void botch PARAMS((const char *, const char *, int));
|
||||
#endif
|
||||
static void xbotch __P((PTR_T, int, const char *, const char *, int));
|
||||
static void xbotch PARAMS((PTR_T, int, const char *, const char *, int));
|
||||
|
||||
#if !HAVE_DECL_SBRK
|
||||
extern char *sbrk ();
|
||||
#endif /* !HAVE_DECL_SBRK */
|
||||
|
||||
#ifdef SHELL
|
||||
extern int interrupt_immediately, running_trap;
|
||||
extern int signal_is_trapped __P((int));
|
||||
extern int running_trap;
|
||||
extern int signal_is_trapped PARAMS((int));
|
||||
#endif
|
||||
|
||||
#ifdef MALLOC_STATS
|
||||
@@ -317,8 +339,8 @@ int malloc_mmap_threshold = MMAP_THRESHOLD;
|
||||
char _malloc_trace_buckets[NBUCKETS];
|
||||
|
||||
/* These should really go into a header file. */
|
||||
extern void mtrace_alloc __P((const char *, PTR_T, size_t, const char *, int));
|
||||
extern void mtrace_free __P((PTR_T, int, const char *, int));
|
||||
extern void mtrace_alloc PARAMS((const char *, PTR_T, size_t, const char *, int));
|
||||
extern void mtrace_free PARAMS((PTR_T, int, const char *, int));
|
||||
#endif
|
||||
|
||||
#if !defined (botch)
|
||||
@@ -598,9 +620,9 @@ morecore (nu)
|
||||
blocked_sigs = 0;
|
||||
#ifdef SHELL
|
||||
# if defined (SIGCHLD)
|
||||
if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
|
||||
if (running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
|
||||
# else
|
||||
if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT))
|
||||
if (running_trap || signal_is_trapped (SIGINT))
|
||||
# endif
|
||||
#endif
|
||||
{
|
||||
@@ -689,7 +711,7 @@ morecore (nu)
|
||||
|
||||
memtop += sbrk_amt;
|
||||
|
||||
/* shouldn't happen, but just in case -- require 8-byte alignment */
|
||||
/* shouldn't happen, but just in case -- require 8- or 16-byte alignment */
|
||||
if ((long)mp & MALIGN_MASK)
|
||||
{
|
||||
mp = (union mhead *) (((long)mp + MALIGN_MASK) & ~MALIGN_MASK);
|
||||
@@ -719,8 +741,13 @@ malloc_debug_dummy ()
|
||||
write (1, "malloc_debug_dummy\n", 19);
|
||||
}
|
||||
|
||||
#if SIZEOF_CHAR_P == 8
|
||||
#define PREPOP_BIN 3
|
||||
#define PREPOP_SIZE 64
|
||||
#else
|
||||
#define PREPOP_BIN 2
|
||||
#define PREPOP_SIZE 32
|
||||
#endif
|
||||
|
||||
static int
|
||||
pagealign ()
|
||||
@@ -756,8 +783,8 @@ pagealign ()
|
||||
memtop += sbrk_needed;
|
||||
|
||||
/* Take the memory which would otherwise be wasted and populate the most
|
||||
popular bin (2 == 32 bytes) with it. Add whatever we need to curbrk
|
||||
to make things 32-byte aligned, compute how many 32-byte chunks we're
|
||||
popular bin (3 == 64 bytes) with it. Add whatever we need to curbrk
|
||||
to make things 64-byte aligned, compute how many 64-byte chunks we're
|
||||
going to get, and set up the bin. */
|
||||
curbrk += sbrk_needed & (PREPOP_SIZE - 1);
|
||||
sbrk_needed -= sbrk_needed & (PREPOP_SIZE - 1);
|
||||
@@ -818,7 +845,7 @@ internal_malloc (n, file, line, flags) /* get a block */
|
||||
if (nbytes <= binsize(nunits))
|
||||
break;
|
||||
|
||||
/* Silently reject too-large requests. */
|
||||
/* Silently reject too-large requests. XXX - can increase this if HAVE_MMAP */
|
||||
if (nunits >= NBUCKETS)
|
||||
return ((PTR_T) NULL);
|
||||
|
||||
@@ -859,6 +886,11 @@ internal_malloc (n, file, line, flags) /* get a block */
|
||||
p->mh_magic2 = MAGIC2;
|
||||
p->mh_nbytes = n;
|
||||
|
||||
#if SIZEOF_CHAR_P == 8
|
||||
/* Begin guard */
|
||||
MALLOC_MEMSET ((char *)p->mh_magic8, MAGIC1, 8);
|
||||
#endif
|
||||
|
||||
/* End guard */
|
||||
mg.i = n;
|
||||
z = mg.s;
|
||||
@@ -893,6 +925,14 @@ internal_malloc (n, file, line, flags) /* get a block */
|
||||
_malloc_ckwatch (p + 1, file, line, W_ALLOC, n);
|
||||
#endif
|
||||
|
||||
#if defined (MALLOC_DEBUG)
|
||||
z = (char *) (p + 1);
|
||||
/* Check alignment of returned pointer */
|
||||
if ((unsigned long)z & MALIGN_MASK)
|
||||
fprintf (stderr, "malloc: %s:%d: warning: request for %d bytes not aligned on %d byte boundary\r\n",
|
||||
file ? file : _("unknown"), line, p->mh_nbytes, MALIGN_MASK+1);
|
||||
#endif
|
||||
|
||||
return (PTR_T) (p + 1);
|
||||
}
|
||||
|
||||
@@ -952,6 +992,15 @@ internal_free (mem, file, line, flags)
|
||||
if (IN_BUCKET(nbytes, nunits) == 0)
|
||||
xbotch (mem, ERR_UNDERFLOW,
|
||||
_("free: underflow detected; mh_nbytes out of range"), file, line);
|
||||
#if SIZEOF_CHAR_P == 8
|
||||
{
|
||||
int i;
|
||||
for (i = 0, z = p->mh_magic8; i < 8; i++)
|
||||
if (*z++ != MAGIC1)
|
||||
xbotch (mem, ERR_UNDERFLOW,
|
||||
_("free: underflow detected; magic8 corrupted"), file, line);
|
||||
}
|
||||
#endif
|
||||
|
||||
ap += p->mh_nbytes;
|
||||
z = mg.s;
|
||||
@@ -1083,6 +1132,16 @@ internal_realloc (mem, n, file, line, flags)
|
||||
if (IN_BUCKET(nbytes, nunits) == 0)
|
||||
xbotch (mem, ERR_UNDERFLOW,
|
||||
_("realloc: underflow detected; mh_nbytes out of range"), file, line);
|
||||
#if SIZEOF_CHAR_P == 8
|
||||
{
|
||||
int i;
|
||||
for (i = 0, z = p->mh_magic8; i < 8; i++)
|
||||
if (*z++ != MAGIC1)
|
||||
xbotch (mem, ERR_UNDERFLOW,
|
||||
_("realloc: underflow detected; magic8 corrupted"), file, line);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
m = (char *)mem + (tocopy = p->mh_nbytes);
|
||||
z = mg.s;
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
/* mstats.h - definitions for malloc statistics */
|
||||
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -104,10 +104,10 @@ struct bucket_stats {
|
||||
int nmmap; /* currently unused */
|
||||
};
|
||||
|
||||
extern struct bucket_stats malloc_bucket_stats __P((int));
|
||||
extern struct _malstats malloc_stats __P((void));
|
||||
extern void print_malloc_stats __P((char *));
|
||||
extern void trace_malloc_stats __P((char *, char *));
|
||||
extern struct bucket_stats malloc_bucket_stats PARAMS((int));
|
||||
extern struct _malstats malloc_stats PARAMS((void));
|
||||
extern void print_malloc_stats PARAMS((char *));
|
||||
extern void trace_malloc_stats PARAMS((char *, char *));
|
||||
|
||||
#endif /* MALLOC_STATS */
|
||||
|
||||
|
||||
+18
-18
@@ -1,6 +1,6 @@
|
||||
/* Functions (currently) for use by the shell to do malloc debugging and
|
||||
tracking. */
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
#ifndef _SH_MALLOC_H
|
||||
#define _SH_MALLOC_H
|
||||
|
||||
#ifndef __P
|
||||
#ifndef PARAMS
|
||||
# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus)
|
||||
# define __P(protos) protos
|
||||
# define PARAMS(protos) protos
|
||||
# else
|
||||
# define __P(protos) ()
|
||||
# define PARAMS(protos) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -41,30 +41,30 @@
|
||||
#endif /* PTR_T */
|
||||
|
||||
|
||||
extern PTR_T sh_malloc __P((size_t, const char *, int));
|
||||
extern PTR_T sh_realloc __P((PTR_T, size_t, const char *, int));
|
||||
extern void sh_free __P((PTR_T, const char *, int));
|
||||
extern PTR_T sh_malloc PARAMS((size_t, const char *, int));
|
||||
extern PTR_T sh_realloc PARAMS((PTR_T, size_t, const char *, int));
|
||||
extern void sh_free PARAMS((PTR_T, const char *, int));
|
||||
|
||||
extern PTR_T sh_memalign __P((size_t, size_t, const char *, int));
|
||||
extern PTR_T sh_memalign PARAMS((size_t, size_t, const char *, int));
|
||||
|
||||
extern PTR_T sh_calloc __P((size_t, size_t, const char *, int));
|
||||
extern void sh_cfree __P((PTR_T, const char *, int));
|
||||
extern PTR_T sh_calloc PARAMS((size_t, size_t, const char *, int));
|
||||
extern void sh_cfree PARAMS((PTR_T, const char *, int));
|
||||
|
||||
extern PTR_T sh_valloc __P((size_t, const char *, int));
|
||||
extern PTR_T sh_valloc PARAMS((size_t, const char *, int));
|
||||
|
||||
/* trace.c */
|
||||
extern int malloc_set_trace __P((int));
|
||||
extern int malloc_set_trace PARAMS((int));
|
||||
extern void malloc_set_tracefp (); /* full prototype requires stdio.h */
|
||||
extern void malloc_set_tracefn __P((char *, char *));
|
||||
extern void malloc_set_tracefn PARAMS((char *, char *));
|
||||
|
||||
/* table.c */
|
||||
extern void mregister_dump_table __P((void));
|
||||
extern void mregister_table_init __P((void));
|
||||
extern int malloc_set_register __P((int));
|
||||
extern void mregister_dump_table PARAMS((void));
|
||||
extern void mregister_table_init PARAMS((void));
|
||||
extern int malloc_set_register PARAMS((int));
|
||||
|
||||
/* stats.c */
|
||||
extern void print_malloc_stats __P((char *));
|
||||
extern void print_malloc_stats PARAMS((char *));
|
||||
extern void fprint_malloc_stats (); /* full prototype requires stdio.h */
|
||||
extern void trace_malloc_stats __P((char *, char *));
|
||||
extern void trace_malloc_stats PARAMS((char *, char *));
|
||||
|
||||
#endif
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
/* stats.c - malloc statistics */
|
||||
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -34,13 +34,13 @@
|
||||
|
||||
#include "mstats.h"
|
||||
|
||||
extern int malloc_free_blocks __P((int));
|
||||
extern int malloc_free_blocks PARAMS((int));
|
||||
|
||||
extern int malloc_mmap_threshold;
|
||||
|
||||
extern struct _malstats _mstats;
|
||||
|
||||
extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
|
||||
extern FILE *_imalloc_fopen PARAMS((char *, char *, char *, char *, size_t));
|
||||
|
||||
struct bucket_stats
|
||||
malloc_bucket_stats (size)
|
||||
@@ -110,7 +110,7 @@ _print_malloc_stats (s, fp)
|
||||
if (i == malloc_mmap_threshold+1)
|
||||
fprintf (fp, "--------\n");
|
||||
if (v.nmal > 0)
|
||||
fprintf (fp, "%8lu\t%4d\t%6d\t%5d\t%8d\t%8d %5d %8d\n", (unsigned long)v.blocksize, v.nfree, v.nused, v.nmal, v.nmorecore, v.nlesscore, v.nsplit, v.ncoalesce);
|
||||
fprintf (fp, "%8lu\t%4d\t%6d\t%5d%8d\t%8d %5d %8d\n", (unsigned long)v.blocksize, v.nfree, v.nused, v.nmal, v.nmorecore, v.nlesscore, v.nsplit, v.ncoalesce);
|
||||
totfree += v.nfree * v.blocksize;
|
||||
totused += v.nused * v.blocksize;
|
||||
}
|
||||
|
||||
+6
-6
@@ -1,6 +1,6 @@
|
||||
/* table.c - bookkeeping functions for allocated memory */
|
||||
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -29,15 +29,15 @@
|
||||
#include "table.h"
|
||||
|
||||
#ifdef SHELL
|
||||
extern int interrupt_immediately, running_trap;
|
||||
extern int signal_is_trapped __P((int));
|
||||
extern int running_trap;
|
||||
extern int signal_is_trapped PARAMS((int));
|
||||
#endif
|
||||
|
||||
extern int malloc_register;
|
||||
|
||||
#ifdef MALLOC_REGISTER
|
||||
|
||||
extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
|
||||
extern FILE *_imalloc_fopen PARAMS((char *, char *, char *, char *, size_t));
|
||||
|
||||
#define FIND_ALLOC 0x01 /* find slot for new allocation */
|
||||
#define FIND_EXIST 0x02 /* find slot for existing entry for free() or search */
|
||||
@@ -174,7 +174,7 @@ mregister_alloc (tag, mem, size, file, line)
|
||||
/* Block all signals in case we are executed from a signal handler. */
|
||||
blocked_sigs = 0;
|
||||
#ifdef SHELL
|
||||
if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
|
||||
if (running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
|
||||
#endif
|
||||
{
|
||||
_malloc_block_signals (&set, &oset);
|
||||
@@ -229,7 +229,7 @@ mregister_free (mem, size, file, line)
|
||||
/* Block all signals in case we are executed from a signal handler. */
|
||||
blocked_sigs = 0;
|
||||
#ifdef SHELL
|
||||
if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
|
||||
if (running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
|
||||
#endif
|
||||
{
|
||||
_malloc_block_signals (&set, &oset);
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
/* table.h - definitions for tables for keeping track of allocated memory */
|
||||
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -57,12 +57,12 @@ typedef struct mr_table {
|
||||
|
||||
#define REG_TABLE_SIZE 8192
|
||||
|
||||
extern mr_table_t *mr_table_entry __P((PTR_T));
|
||||
extern void mregister_alloc __P((const char *, PTR_T, size_t, const char *, int));
|
||||
extern void mregister_free __P((PTR_T, int, const char *, int));
|
||||
extern mr_table_t *mr_table_entry PARAMS((PTR_T));
|
||||
extern void mregister_alloc PARAMS((const char *, PTR_T, size_t, const char *, int));
|
||||
extern void mregister_free PARAMS((PTR_T, int, const char *, int));
|
||||
extern void mregister_describe_mem ();
|
||||
extern void mregister_dump_table __P((void));
|
||||
extern void mregister_table_init __P((void));
|
||||
extern void mregister_dump_table PARAMS((void));
|
||||
extern void mregister_table_init PARAMS((void));
|
||||
|
||||
typedef struct ma_table {
|
||||
const char *file;
|
||||
@@ -70,10 +70,10 @@ typedef struct ma_table {
|
||||
int nalloc;
|
||||
} ma_table_t;
|
||||
|
||||
extern void mlocation_register_alloc __P((const char *, int));
|
||||
extern void mlocation_table_init __P((void));
|
||||
extern void mlocation_dump_table __P((void));
|
||||
extern void mlocation_write_table __P((void));
|
||||
extern void mlocation_register_alloc PARAMS((const char *, int));
|
||||
extern void mlocation_table_init PARAMS((void));
|
||||
extern void mlocation_dump_table PARAMS((void));
|
||||
extern void mlocation_write_table PARAMS((void));
|
||||
|
||||
/* NOTE: HASH_MIX taken from dmalloc (http://dmalloc.com) */
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* trace.c - tracing functions for malloc */
|
||||
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -35,7 +35,7 @@ static int _mtrace_verbose = 0;
|
||||
|
||||
#ifdef MALLOC_TRACE
|
||||
|
||||
extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
|
||||
extern FILE *_imalloc_fopen PARAMS((char *, char *, char *, char *, size_t));
|
||||
|
||||
FILE *_mtrace_fp = NULL;
|
||||
extern char _malloc_trace_buckets[];
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* watch.h - definitions for tables for keeping track of allocated memory */
|
||||
|
||||
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne-Again SHell.
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
extern int _malloc_nwatch;
|
||||
|
||||
extern void _malloc_ckwatch __P((PTR_T, const char *, int, int, unsigned long));
|
||||
extern void _malloc_ckwatch PARAMS((PTR_T, const char *, int, int, unsigned long));
|
||||
|
||||
#endif /* MALLOC_WATCH */
|
||||
|
||||
|
||||
+154
-104
@@ -1,6 +1,6 @@
|
||||
/* bind.c -- key binding and startup file support for the readline library. */
|
||||
|
||||
/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -135,12 +135,13 @@ rl_add_defun (const char *name, rl_command_func_t *function, int key)
|
||||
int
|
||||
rl_bind_key (int key, rl_command_func_t *function)
|
||||
{
|
||||
char keyseq[3];
|
||||
char keyseq[4];
|
||||
int l;
|
||||
|
||||
if (key < 0)
|
||||
if (key < 0 || key > largest_char)
|
||||
return (key);
|
||||
|
||||
/* Want to make this a multi-character key sequence with an ESC prefix */
|
||||
if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
|
||||
{
|
||||
if (_rl_keymap[ESC].type == ISKMAP)
|
||||
@@ -153,24 +154,43 @@ rl_bind_key (int key, rl_command_func_t *function)
|
||||
escmap[key].function = function;
|
||||
return (0);
|
||||
}
|
||||
return (key);
|
||||
|
||||
/* Otherwise, let's just let rl_generic_bind handle the key sequence.
|
||||
We start it off with ESC here and let the code below add the rest
|
||||
of the sequence. */
|
||||
keyseq[0] = ESC;
|
||||
l = 1;
|
||||
key = UNMETA(key);
|
||||
goto bind_keyseq;
|
||||
}
|
||||
|
||||
/* If it's bound to a function or macro, just overwrite. Otherwise we have
|
||||
to treat it as a key sequence so rl_generic_bind handles shadow keymaps
|
||||
for us. If we are binding '\' make sure to escape it so it makes it
|
||||
through the call to rl_translate_keyseq. */
|
||||
for us. If we are binding '\' or \C-@ (NUL) make sure to escape it so
|
||||
it makes it through the call to rl_translate_keyseq. */
|
||||
if (_rl_keymap[key].type != ISKMAP)
|
||||
{
|
||||
if (_rl_keymap[key].type == ISMACR)
|
||||
xfree ((char *)_rl_keymap[key].function);
|
||||
_rl_keymap[key].type = ISFUNC;
|
||||
_rl_keymap[key].function = function;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = 0;
|
||||
bind_keyseq:
|
||||
if (key == '\\')
|
||||
keyseq[l++] = '\\';
|
||||
keyseq[l++] = key;
|
||||
{
|
||||
keyseq[l++] = '\\';
|
||||
keyseq[l++] = '\\';
|
||||
}
|
||||
else if (key == '\0')
|
||||
{
|
||||
keyseq[l++] = '\\';
|
||||
keyseq[l++] = '0';
|
||||
}
|
||||
else
|
||||
keyseq[l++] = key;
|
||||
keyseq[l] = '\0';
|
||||
rl_bind_keyseq (keyseq, function);
|
||||
}
|
||||
@@ -242,6 +262,13 @@ rl_unbind_function_in_map (rl_command_func_t *func, Keymap map)
|
||||
map[i].function = (rl_command_func_t *)NULL;
|
||||
rval = 1;
|
||||
}
|
||||
else if (map[i].type == ISKMAP) /* TAG:readline-8.1 */
|
||||
{
|
||||
int r;
|
||||
r = rl_unbind_function_in_map (func, FUNCTION_TO_KEYMAP (map, i));
|
||||
if (r == 1)
|
||||
rval = 1;
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
@@ -352,7 +379,7 @@ int
|
||||
rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
|
||||
{
|
||||
char *keys;
|
||||
int keys_len, prevkey;
|
||||
int keys_len, prevkey, ic;
|
||||
register int i;
|
||||
KEYMAP_ENTRY k;
|
||||
Keymap prevmap;
|
||||
@@ -385,7 +412,6 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
|
||||
for (i = 0; i < keys_len; i++)
|
||||
{
|
||||
unsigned char uc = keys[i];
|
||||
int ic;
|
||||
|
||||
if (i > 0)
|
||||
prevkey = ic;
|
||||
@@ -397,6 +423,9 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We now rely on rl_translate_keyseq to do this conversion, so this
|
||||
check is superfluous. */
|
||||
#if 0
|
||||
if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
|
||||
{
|
||||
ic = UNMETA (ic);
|
||||
@@ -406,6 +435,7 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
|
||||
map = FUNCTION_TO_KEYMAP (map, ESC);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((i + 1) < keys_len)
|
||||
{
|
||||
@@ -439,9 +469,7 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (map[ic].type == ISMACR)
|
||||
xfree ((char *)map[ic].function);
|
||||
else if (map[ic].type == ISKMAP)
|
||||
if (map[ic].type == ISKMAP)
|
||||
{
|
||||
prevmap = map;
|
||||
map = FUNCTION_TO_KEYMAP (map, ic);
|
||||
@@ -454,6 +482,8 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
|
||||
if (type == ISFUNC && data == 0)
|
||||
data = (char *)_rl_null_function;
|
||||
}
|
||||
if (map[ic].type == ISMACR)
|
||||
xfree ((char *)map[ic].function);
|
||||
|
||||
map[ic].function = KEYMAP_TO_FUNCTION (data);
|
||||
map[ic].type = type;
|
||||
@@ -492,59 +522,38 @@ rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
|
||||
int
|
||||
rl_translate_keyseq (const char *seq, char *array, int *len)
|
||||
{
|
||||
register int i, c, l, temp;
|
||||
register int i, l, temp;
|
||||
int has_control, has_meta;
|
||||
unsigned char c;
|
||||
|
||||
for (i = l = 0; c = seq[i]; i++)
|
||||
has_control = 0;
|
||||
has_meta = 0;
|
||||
|
||||
/* When there are incomplete prefixes \C- or \M- (has_control || has_meta)
|
||||
without base character at the end of SEQ, they are processed as the
|
||||
prefixes for '\0'.
|
||||
*/
|
||||
for (i = l = 0; (c = seq[i]) || has_control || has_meta; i++)
|
||||
{
|
||||
if (c == '\\')
|
||||
/* Only backslashes followed by a non-null character are handled
|
||||
specially. Trailing backslash (backslash followed by '\0') is
|
||||
processed as a normal character.
|
||||
*/
|
||||
if (c == '\\' && seq[i + 1] != '\0')
|
||||
{
|
||||
c = seq[++i];
|
||||
|
||||
if (c == 0)
|
||||
{
|
||||
array[l++] = '\\'; /* preserve trailing backslash */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Handle \C- and \M- prefixes. */
|
||||
if ((c == 'C' || c == 'M') && seq[i + 1] == '-')
|
||||
if (c == 'C' && seq[i + 1] == '-')
|
||||
{
|
||||
/* Handle special case of backwards define. */
|
||||
if (strncmp (&seq[i], "C-\\M-", 5) == 0)
|
||||
{
|
||||
array[l++] = ESC; /* ESC is meta-prefix */
|
||||
i += 5;
|
||||
array[l++] = CTRL (_rl_to_upper (seq[i]));
|
||||
}
|
||||
else if (c == 'M')
|
||||
{
|
||||
i++; /* seq[i] == '-' */
|
||||
/* XXX - obey convert-meta setting */
|
||||
if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP)
|
||||
array[l++] = ESC; /* ESC is meta-prefix */
|
||||
else if (seq[i+1] == '\\' && seq[i+2] == 'C' && seq[i+3] == '-')
|
||||
{
|
||||
i += 4;
|
||||
temp = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
|
||||
array[l++] = META (temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This doesn't yet handle things like \M-\a, which may
|
||||
or may not have any reasonable meaning. You're
|
||||
probably better off using straight octal or hex. */
|
||||
i++;
|
||||
array[l++] = META (seq[i]);
|
||||
}
|
||||
}
|
||||
else if (c == 'C')
|
||||
{
|
||||
i += 2;
|
||||
/* Special hack for C-?... */
|
||||
array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
|
||||
}
|
||||
if (seq[i] == '\0')
|
||||
break;
|
||||
i++;
|
||||
has_control = 1;
|
||||
continue;
|
||||
}
|
||||
else if (c == 'M' && seq[i + 1] == '-')
|
||||
{
|
||||
i++;
|
||||
has_meta = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -555,34 +564,34 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
|
||||
switch (c)
|
||||
{
|
||||
case 'a':
|
||||
array[l++] = '\007';
|
||||
c = '\007';
|
||||
break;
|
||||
case 'b':
|
||||
array[l++] = '\b';
|
||||
c = '\b';
|
||||
break;
|
||||
case 'd':
|
||||
array[l++] = RUBOUT; /* readline-specific */
|
||||
c = RUBOUT; /* readline-specific */
|
||||
break;
|
||||
case 'e':
|
||||
array[l++] = ESC;
|
||||
c = ESC;
|
||||
break;
|
||||
case 'f':
|
||||
array[l++] = '\f';
|
||||
c = '\f';
|
||||
break;
|
||||
case 'n':
|
||||
array[l++] = NEWLINE;
|
||||
c = NEWLINE;
|
||||
break;
|
||||
case 'r':
|
||||
array[l++] = RETURN;
|
||||
c = RETURN;
|
||||
break;
|
||||
case 't':
|
||||
array[l++] = TAB;
|
||||
c = TAB;
|
||||
break;
|
||||
case 'v':
|
||||
array[l++] = 0x0B;
|
||||
c = 0x0B;
|
||||
break;
|
||||
case '\\':
|
||||
array[l++] = '\\';
|
||||
c = '\\';
|
||||
break;
|
||||
case '0': case '1': case '2': case '3':
|
||||
case '4': case '5': case '6': case '7':
|
||||
@@ -590,7 +599,7 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
|
||||
for (temp = 2, c -= '0'; ISOCTAL ((unsigned char)seq[i]) && temp--; i++)
|
||||
c = (c * 8) + OCTVALUE (seq[i]);
|
||||
i--; /* auto-increment in for loop */
|
||||
array[l++] = c & largest_char;
|
||||
c &= largest_char;
|
||||
break;
|
||||
case 'x':
|
||||
i++;
|
||||
@@ -599,16 +608,40 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
|
||||
if (temp == 2)
|
||||
c = 'x';
|
||||
i--; /* auto-increment in for loop */
|
||||
array[l++] = c & largest_char;
|
||||
c &= largest_char;
|
||||
break;
|
||||
default: /* backslashes before non-special chars just add the char */
|
||||
array[l++] = c;
|
||||
c &= largest_char;
|
||||
break; /* the backslash is stripped */
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
array[l++] = c;
|
||||
/* Process \C- and \M- flags */
|
||||
if (has_control)
|
||||
{
|
||||
/* Special treatment for C-? */
|
||||
c = (c == '?') ? RUBOUT : CTRL (_rl_to_upper (c));
|
||||
has_control = 0;
|
||||
}
|
||||
if (has_meta)
|
||||
{
|
||||
c = META (c);
|
||||
has_meta = 0;
|
||||
}
|
||||
|
||||
/* If convert-meta is turned on, convert a meta char to a key sequence */
|
||||
if (META_CHAR (c) && _rl_convert_meta_chars_to_ascii)
|
||||
{
|
||||
array[l++] = ESC; /* ESC is meta-prefix */
|
||||
array[l++] = UNMETA (c);
|
||||
}
|
||||
else
|
||||
array[l++] = (c);
|
||||
|
||||
/* Null characters may be processed for incomplete prefixes at the end of
|
||||
sequence */
|
||||
if (seq[i] == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
*len = l;
|
||||
@@ -756,7 +789,7 @@ _rl_untranslate_macro_value (char *seq, int use_escapes)
|
||||
|
||||
/* Return a pointer to the function that STRING represents.
|
||||
If STRING doesn't have a matching function, then a NULL pointer
|
||||
is returned. */
|
||||
is returned. The string match is case-insensitive. */
|
||||
rl_command_func_t *
|
||||
rl_named_function (const char *string)
|
||||
{
|
||||
@@ -809,7 +842,7 @@ _rl_function_of_keyseq_internal (const char *keyseq, size_t len, Keymap map, int
|
||||
{
|
||||
/* If this is the last key in the key sequence, return the
|
||||
map. */
|
||||
if (keyseq[i + 1] == '\0')
|
||||
if (i + 1 == len)
|
||||
{
|
||||
if (type)
|
||||
*type = ISKMAP;
|
||||
@@ -822,9 +855,9 @@ _rl_function_of_keyseq_internal (const char *keyseq, size_t len, Keymap map, int
|
||||
/* If we're not at the end of the key sequence, and the current key
|
||||
is bound to something other than a keymap, then the entire key
|
||||
sequence is not bound. */
|
||||
else if (map[ic].type != ISKMAP && keyseq[i+1])
|
||||
else if (map[ic].type != ISKMAP && i+1 < len)
|
||||
return ((rl_command_func_t *)NULL);
|
||||
else /* map[ic].type != ISKMAP && keyseq[i+1] == 0 */
|
||||
else /* map[ic].type != ISKMAP && i+1 == len */
|
||||
{
|
||||
if (type)
|
||||
*type = map[ic].type;
|
||||
@@ -1569,15 +1602,11 @@ rl_parse_and_bind (char *string)
|
||||
/* Strip trailing whitespace from values of boolean variables. */
|
||||
if (find_boolean_var (var) >= 0)
|
||||
{
|
||||
/* remove trailing whitespace */
|
||||
remove_trailing:
|
||||
e = value + strlen (value) - 1;
|
||||
while (e >= value && whitespace (*e))
|
||||
e--;
|
||||
e++; /* skip back to whitespace or EOS */
|
||||
|
||||
if (*e && e >= value)
|
||||
*e = '\0';
|
||||
/* just read a whitespace-delimited word or empty string */
|
||||
for (e = value; *e && whitespace (*e) == 0; e++)
|
||||
;
|
||||
if (e > value)
|
||||
*e = '\0'; /* cut off everything trailing */
|
||||
}
|
||||
else if ((i = find_string_var (var)) >= 0)
|
||||
{
|
||||
@@ -1589,9 +1618,24 @@ remove_trailing:
|
||||
value++; /* skip past the quote */
|
||||
}
|
||||
else
|
||||
goto remove_trailing;
|
||||
{
|
||||
/* remove trailing whitespace */
|
||||
e = value + strlen (value) - 1;
|
||||
while (e >= value && whitespace (*e))
|
||||
e--;
|
||||
e++; /* skip back to whitespace or EOS */
|
||||
|
||||
if (*e && e >= value)
|
||||
*e = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* avoid calling rl_variable_bind just to find this out */
|
||||
_rl_init_file_error ("%s: unknown variable name", var);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rl_variable_bind (var, value);
|
||||
return 0;
|
||||
}
|
||||
@@ -1768,7 +1812,7 @@ static const struct {
|
||||
{ "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
|
||||
{ "disable-completion", &rl_inhibit_completion, 0 },
|
||||
{ "echo-control-characters", &_rl_echo_control_chars, 0 },
|
||||
{ "enable-bracketed-paste", &_rl_enable_bracketed_paste, 0 },
|
||||
{ "enable-bracketed-paste", &_rl_enable_bracketed_paste, V_SPECIAL },
|
||||
{ "enable-keypad", &_rl_enable_keypad, 0 },
|
||||
{ "enable-meta-key", &_rl_enable_meta, 0 },
|
||||
{ "expand-tilde", &rl_complete_with_tilde_expansion, 0 },
|
||||
@@ -1834,6 +1878,8 @@ hack_special_boolean_var (int i)
|
||||
}
|
||||
else if (_rl_stricmp (name, "show-mode-in-prompt") == 0)
|
||||
_rl_reset_prompt ();
|
||||
else if (_rl_stricmp (name, "enable-bracketed-paste") == 0)
|
||||
_rl_enable_active_region = _rl_enable_bracketed_paste;
|
||||
}
|
||||
|
||||
typedef int _rl_sv_func_t PARAMS((const char *));
|
||||
@@ -1903,7 +1949,7 @@ string_varname (int i)
|
||||
}
|
||||
|
||||
/* A boolean value that can appear in a `set variable' command is true if
|
||||
the value is null or empty, `on' (case-insensitive), or "1". Any other
|
||||
the value is null or empty, `on' (case-insensitive), or "1". All other
|
||||
values result in 0 (false). */
|
||||
static int
|
||||
bool_to_int (const char *value)
|
||||
@@ -1928,7 +1974,7 @@ rl_variable_value (const char *name)
|
||||
return (_rl_get_string_variable_value (string_varlist[i].name));
|
||||
|
||||
/* Unknown variable names return NULL. */
|
||||
return 0;
|
||||
return (char *)NULL;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1959,6 +2005,8 @@ rl_variable_bind (const char *name, const char *value)
|
||||
}
|
||||
|
||||
v = (*string_varlist[i].set_func) (value);
|
||||
if (v != 0)
|
||||
_rl_init_file_error ("%s: could not set value to `%s'", name, value);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -2581,20 +2629,22 @@ rl_invoking_keyseqs_in_map (rl_command_func_t *function, Keymap map)
|
||||
else
|
||||
sprintf (keyname, "\\e");
|
||||
}
|
||||
else if (CTRL_CHAR (key))
|
||||
sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key)));
|
||||
else if (key == RUBOUT)
|
||||
sprintf (keyname, "\\C-?");
|
||||
else if (key == '\\' || key == '"')
|
||||
{
|
||||
keyname[0] = '\\';
|
||||
keyname[1] = (char) key;
|
||||
keyname[2] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
keyname[0] = (char) key;
|
||||
keyname[1] = '\0';
|
||||
int c = key, l = 0;
|
||||
if (CTRL_CHAR (c) || c == RUBOUT)
|
||||
{
|
||||
keyname[l++] = '\\';
|
||||
keyname[l++] = 'C';
|
||||
keyname[l++] = '-';
|
||||
c = (c == RUBOUT) ? '?' : _rl_to_lower (UNCTRL (c));
|
||||
}
|
||||
|
||||
if (c == '\\' || c == '"')
|
||||
keyname[l++] = '\\';
|
||||
|
||||
keyname[l++] = (char) c;
|
||||
keyname[l++] = '\0';
|
||||
}
|
||||
|
||||
strcat (keyname, seqs[i]);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Modified by Chet Ramey for Readline.
|
||||
|
||||
Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015, 2017
|
||||
Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015, 2017, 2019
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -32,6 +32,13 @@
|
||||
|
||||
#include "rlconf.h"
|
||||
|
||||
#if defined __TANDEM
|
||||
# define _XOPEN_SOURCE_EXTENDED 1
|
||||
# define _TANDEM_SOURCE 1
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "posixstat.h" // stat related macros (S_ISREG, ...)
|
||||
@@ -175,7 +182,7 @@ _rl_print_color_indicator (const char *f)
|
||||
|
||||
if (linkok == -1 && _rl_color_indicator[C_MISSING].string != NULL)
|
||||
colored_filetype = C_MISSING;
|
||||
else if (linkok == 0 && S_ISLNK(mode) && _rl_color_indicator[C_ORPHAN].string != NULL)
|
||||
else if (linkok == 0 && _rl_color_indicator[C_ORPHAN].string != NULL)
|
||||
colored_filetype = C_ORPHAN; /* dangling symlink */
|
||||
else if(stat_ok != 0)
|
||||
{
|
||||
|
||||
+68
-36
@@ -1,6 +1,6 @@
|
||||
/* complete.c -- filename completion for readline. */
|
||||
|
||||
/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -21,11 +21,18 @@
|
||||
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (__TANDEM)
|
||||
# define _XOPEN_SOURCE_EXTENDED 1
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined (__TANDEM)
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#if defined (HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
@@ -141,6 +148,7 @@ static int complete_fncmp PARAMS((const char *, int, const char *, int));
|
||||
static void display_matches PARAMS((char **));
|
||||
static int compute_lcd_of_matches PARAMS((char **, int, const char *));
|
||||
static int postprocess_matches PARAMS((char ***, int));
|
||||
static int compare_match PARAMS((char *, const char *));
|
||||
static int complete_get_screenwidth PARAMS((void));
|
||||
|
||||
static char *make_quoted_replacement PARAMS((char *, int, char *));
|
||||
@@ -406,6 +414,7 @@ int rl_sort_completion_matches = 1;
|
||||
|
||||
/* Local variable states what happened during the last completion attempt. */
|
||||
static int completion_changed_buffer;
|
||||
static int last_completion_failed = 0;
|
||||
|
||||
/* The result of the query to the user about displaying completion matches */
|
||||
static int completion_y_or_n;
|
||||
@@ -428,7 +437,11 @@ rl_complete (int ignore, int invoking_key)
|
||||
|
||||
if (rl_inhibit_completion)
|
||||
return (_rl_insert_char (ignore, invoking_key));
|
||||
else if (rl_last_func == rl_complete && !completion_changed_buffer)
|
||||
#if 0
|
||||
else if (rl_last_func == rl_complete && completion_changed_buffer == 0 && last_completion_failed == 0)
|
||||
#else
|
||||
else if (rl_last_func == rl_complete && completion_changed_buffer == 0)
|
||||
#endif
|
||||
return (rl_complete_internal ('?'));
|
||||
else if (_rl_complete_show_all)
|
||||
return (rl_complete_internal ('!'));
|
||||
@@ -477,7 +490,7 @@ rl_completion_mode (rl_command_func_t *cfunc)
|
||||
/* */
|
||||
/************************************/
|
||||
|
||||
/* Reset readline state on a signal or other event. */
|
||||
/* Reset public readline state on a signal or other event. */
|
||||
void
|
||||
_rl_reset_completion_state (void)
|
||||
{
|
||||
@@ -1330,12 +1343,13 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text)
|
||||
memset (&ps2, 0, sizeof (mbstate_t));
|
||||
}
|
||||
#endif
|
||||
if (_rl_completion_case_fold)
|
||||
for (si = 0; (c1 = match_list[i][si]) && (c2 = match_list[i + 1][si]); si++)
|
||||
{
|
||||
for (si = 0;
|
||||
(c1 = _rl_to_lower(match_list[i][si])) &&
|
||||
(c2 = _rl_to_lower(match_list[i + 1][si]));
|
||||
si++)
|
||||
if (_rl_completion_case_fold)
|
||||
{
|
||||
c1 = _rl_to_lower (c1);
|
||||
c2 = _rl_to_lower (c2);
|
||||
}
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
@@ -1347,35 +1361,17 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
wc1 = towlower (wc1);
|
||||
wc2 = towlower (wc2);
|
||||
if (_rl_completion_case_fold)
|
||||
{
|
||||
wc1 = towlower (wc1);
|
||||
wc2 = towlower (wc2);
|
||||
}
|
||||
if (wc1 != wc2)
|
||||
break;
|
||||
else if (v1 > 1)
|
||||
si += v1 - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (c1 != c2)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (si = 0;
|
||||
(c1 = match_list[i][si]) &&
|
||||
(c2 = match_list[i + 1][si]);
|
||||
si++)
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
mbstate_t ps_back;
|
||||
ps_back = ps1;
|
||||
if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))
|
||||
break;
|
||||
else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)
|
||||
si += v - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (c1 != c2)
|
||||
break;
|
||||
@@ -1969,6 +1965,26 @@ _rl_free_match_list (char **matches)
|
||||
xfree (matches);
|
||||
}
|
||||
|
||||
/* Compare a possibly-quoted filename TEXT from the line buffer and a possible
|
||||
MATCH that is the product of filename completion, which acts on the dequoted
|
||||
text. */
|
||||
static int
|
||||
compare_match (char *text, const char *match)
|
||||
{
|
||||
char *temp;
|
||||
int r;
|
||||
|
||||
if (rl_filename_completion_desired && rl_filename_quoting_desired &&
|
||||
rl_completion_found_quote && rl_filename_dequoting_function)
|
||||
{
|
||||
temp = (*rl_filename_dequoting_function) (text, rl_completion_quote_character);
|
||||
r = strcmp (temp, match);
|
||||
free (temp);
|
||||
return r;
|
||||
}
|
||||
return (strcmp (text, match));
|
||||
}
|
||||
|
||||
/* Complete the word at or before point.
|
||||
WHAT_TO_DO says what to do with the completion.
|
||||
`?' means list the possible completions.
|
||||
@@ -1986,10 +2002,12 @@ rl_complete_internal (int what_to_do)
|
||||
int start, end, delimiter, found_quote, i, nontrivial_lcd;
|
||||
char *text, *saved_line_buffer;
|
||||
char quote_char;
|
||||
int tlen, mlen;
|
||||
int tlen, mlen, saved_last_completion_failed;
|
||||
|
||||
RL_SETSTATE(RL_STATE_COMPLETING);
|
||||
|
||||
saved_last_completion_failed = last_completion_failed;
|
||||
|
||||
set_completion_defaults (what_to_do);
|
||||
|
||||
saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL;
|
||||
@@ -2013,7 +2031,7 @@ rl_complete_internal (int what_to_do)
|
||||
matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
|
||||
/* nontrivial_lcd is set if the common prefix adds something to the word
|
||||
being completed. */
|
||||
nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
|
||||
nontrivial_lcd = matches && compare_match (text, matches[0]) != 0;
|
||||
if (what_to_do == '!' || what_to_do == '@')
|
||||
tlen = strlen (text);
|
||||
xfree (text);
|
||||
@@ -2023,6 +2041,7 @@ rl_complete_internal (int what_to_do)
|
||||
rl_ding ();
|
||||
FREE (saved_line_buffer);
|
||||
completion_changed_buffer = 0;
|
||||
last_completion_failed = 1;
|
||||
RL_UNSETSTATE(RL_STATE_COMPLETING);
|
||||
_rl_reset_completion_state ();
|
||||
return (0);
|
||||
@@ -2038,11 +2057,15 @@ rl_complete_internal (int what_to_do)
|
||||
rl_ding ();
|
||||
FREE (saved_line_buffer);
|
||||
completion_changed_buffer = 0;
|
||||
last_completion_failed = 1;
|
||||
RL_UNSETSTATE(RL_STATE_COMPLETING);
|
||||
_rl_reset_completion_state ();
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (matches && matches[0] && *matches[0])
|
||||
last_completion_failed = 0;
|
||||
|
||||
switch (what_to_do)
|
||||
{
|
||||
case TAB:
|
||||
@@ -2098,6 +2121,15 @@ rl_complete_internal (int what_to_do)
|
||||
break;
|
||||
|
||||
case '?':
|
||||
/* Let's try to insert a single match here if the last completion failed
|
||||
but this attempt returned a single match. */
|
||||
if (saved_last_completion_failed && matches[0] && *matches[0] && matches[1] == 0)
|
||||
{
|
||||
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, "e_char);
|
||||
append_to_match (matches[0], delimiter, quote_char, nontrivial_lcd);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rl_completion_display_matches_hook == 0)
|
||||
{
|
||||
_rl_sigcleanup = _rl_complete_sigcleanup;
|
||||
@@ -2761,7 +2793,7 @@ rl_old_menu_complete (int count, int invoking_key)
|
||||
{
|
||||
insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char);
|
||||
append_to_match (matches[match_list_index], delimiter, quote_char,
|
||||
strcmp (orig_text, matches[match_list_index]));
|
||||
compare_match (orig_text, matches[match_list_index]));
|
||||
}
|
||||
|
||||
completion_changed_buffer = 1;
|
||||
@@ -2835,7 +2867,7 @@ rl_menu_complete (int count, int ignore)
|
||||
matches = gen_completion_matches (orig_text, orig_start, orig_end,
|
||||
our_func, found_quote, quote_char);
|
||||
|
||||
nontrivial_lcd = matches && strcmp (orig_text, matches[0]) != 0;
|
||||
nontrivial_lcd = matches && compare_match (orig_text, matches[0]) != 0;
|
||||
|
||||
/* If we are matching filenames, the attempted completion function will
|
||||
have set rl_filename_completion_desired to a non-zero value. The basic
|
||||
@@ -2942,7 +2974,7 @@ rl_menu_complete (int count, int ignore)
|
||||
{
|
||||
insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char);
|
||||
append_to_match (matches[match_list_index], delimiter, quote_char,
|
||||
strcmp (orig_text, matches[match_list_index]));
|
||||
compare_match (orig_text, matches[match_list_index]));
|
||||
}
|
||||
|
||||
completion_changed_buffer = 1;
|
||||
|
||||
+568
-254
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@ This document describes the GNU History library
|
||||
a programming tool that provides a consistent user interface for
|
||||
recalling lines of previously typed input.
|
||||
|
||||
Copyright @copyright{} 1988--2016 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1988--2020 Free Software Foundation, Inc.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@ignore
|
||||
This file documents the user interface to the GNU History library.
|
||||
|
||||
Copyright (C) 1988-2016 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2020 Free Software Foundation, Inc.
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this manual
|
||||
@@ -48,7 +48,7 @@ History library is able to keep track of those lines, associate arbitrary
|
||||
data with each line, and utilize information from previous lines in
|
||||
composing new ones.
|
||||
|
||||
The programmer using the History library has available functions
|
||||
A programmer using the History library has available functions
|
||||
for remembering lines on a history list, associating arbitrary data
|
||||
with a line, removing lines from the list, searching through the list
|
||||
for a line containing an arbitrary text string, and referencing any line
|
||||
@@ -62,7 +62,7 @@ commands for manipulating the text of previous lines and using that text
|
||||
in new commands. The basic history manipulation commands are similar to
|
||||
the history substitution provided by @code{csh}.
|
||||
|
||||
If the programmer desires, he can use the Readline library, which
|
||||
The programmer can also use the Readline library, which
|
||||
includes some history manipulation by default, and has the added
|
||||
advantage of command line editing.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@ignore
|
||||
This file documents the user interface to the GNU History library.
|
||||
|
||||
Copyright (C) 1988--2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988--2020 Free Software Foundation, Inc.
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this manual
|
||||
@@ -149,7 +149,14 @@ Both @var{first} and
|
||||
@var{last} may be specified as a string (to locate the most recent
|
||||
command beginning with that string) or as a number (an index into the
|
||||
history list, where a negative number is used as an offset from the
|
||||
current command number). If @var{last} is not specified, it is set to
|
||||
current command number).
|
||||
|
||||
When listing, a @var{first} or @var{last} of 0 is equivalent to -1
|
||||
and -0 is equivalent to the current command (usually the @code{fc}
|
||||
command);
|
||||
otherwise 0 is equivalent to -1 and -0 is invalid.
|
||||
|
||||
If @var{last} is not specified, it is set to
|
||||
@var{first}. If @var{first} is not specified, it is set to the previous
|
||||
command for editing and @minus{}16 for listing. If the @option{-l} flag is
|
||||
given, the commands are listed on standard output. The @option{-n} flag
|
||||
@@ -164,7 +171,7 @@ When editing is complete, the edited commands are echoed and executed.
|
||||
|
||||
In the second form, @var{command} is re-executed after each instance
|
||||
of @var{pat} in the selected command is replaced by @var{rep}.
|
||||
@var{command} is intepreted the same as @var{first} above.
|
||||
@var{command} is interpreted the same as @var{first} above.
|
||||
|
||||
A useful alias to use with the @code{fc} command is @code{r='fc -s'}, so
|
||||
that typing @samp{r cc} runs the last command beginning with @code{cc}
|
||||
@@ -370,11 +377,13 @@ containing @var{string}.
|
||||
The trailing
|
||||
@samp{?} may be omitted if the @var{string} is followed immediately by
|
||||
a newline.
|
||||
If @var{string} is missing, the string from the most recent search is used;
|
||||
it is an error if there is no previous search string.
|
||||
|
||||
@item @code{^@var{string1}^@var{string2}^}
|
||||
Quick Substitution. Repeat the last command, replacing @var{string1}
|
||||
with @var{string2}. Equivalent to
|
||||
@code{!!:s/@var{string1}/@var{string2}/}.
|
||||
@code{!!:s^@var{string1}^@var{string2}^}.
|
||||
|
||||
@item @code{!#}
|
||||
The entire command line typed so far.
|
||||
@@ -426,7 +435,8 @@ The first argument; that is, word 1.
|
||||
The last argument.
|
||||
|
||||
@item %
|
||||
The word matched by the most recent @samp{?@var{string}?} search.
|
||||
The first word matched by the most recent @samp{?@var{string}?} search,
|
||||
if the search string begins with a character that is part of a word.
|
||||
|
||||
@item @var{x}-@var{y}
|
||||
A range of words; @samp{-@var{y}} abbreviates @samp{0-@var{y}}.
|
||||
@@ -441,6 +451,7 @@ Abbreviates @samp{@var{x}-$}
|
||||
|
||||
@item @var{x}-
|
||||
Abbreviates @samp{@var{x}-$} like @samp{@var{x}*}, but omits the last word.
|
||||
If @samp{x} is missing, it defaults to 0.
|
||||
|
||||
@end table
|
||||
|
||||
@@ -452,6 +463,7 @@ previous command is used as the event.
|
||||
|
||||
After the optional word designator, you can add a sequence of one or more
|
||||
of the following modifiers, each preceded by a @samp{:}.
|
||||
These modify, or edit, the word or words selected from the history event.
|
||||
|
||||
@table @code
|
||||
|
||||
@@ -478,15 +490,25 @@ Quote the substituted words, escaping further substitutions.
|
||||
@item x
|
||||
Quote the substituted words as with @samp{q},
|
||||
but break into words at spaces, tabs, and newlines.
|
||||
The @samp{q} and @samp{x} modifiers are mutually exclusive; the last one
|
||||
supplied is used.
|
||||
@end ifset
|
||||
|
||||
@item s/@var{old}/@var{new}/
|
||||
Substitute @var{new} for the first occurrence of @var{old} in the
|
||||
event line. Any delimiter may be used in place of @samp{/}.
|
||||
event line.
|
||||
Any character may be used as the delimiter in place of @samp{/}.
|
||||
The delimiter may be quoted in @var{old} and @var{new}
|
||||
with a single backslash. If @samp{&} appears in @var{new},
|
||||
it is replaced by @var{old}. A single backslash will quote
|
||||
the @samp{&}. The final delimiter is optional if it is the last
|
||||
the @samp{&}.
|
||||
If @var{old} is null, it is set to the last @var{old}
|
||||
substituted, or, if no previous history substitutions took place,
|
||||
the last @var{string}
|
||||
in a !?@var{string}@code{[?]}
|
||||
search.
|
||||
If @var{new} is is null, each matching @var{old} is deleted.
|
||||
The final delimiter is optional if it is the last
|
||||
character on the input line.
|
||||
|
||||
@item &
|
||||
@@ -499,6 +521,7 @@ conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/},
|
||||
or with @samp{&}.
|
||||
|
||||
@item G
|
||||
Apply the following @samp{s} modifier once to each word in the event.
|
||||
Apply the following @samp{s} or @samp{&} modifier once to each word
|
||||
in the event.
|
||||
|
||||
@end table
|
||||
|
||||
@@ -13,7 +13,7 @@ This manual describes the GNU Readline Library
|
||||
consistency of user interface across discrete programs which provide
|
||||
a command line interface.
|
||||
|
||||
Copyright @copyright{} 1988--2016 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1988--2020 Free Software Foundation, Inc.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
|
||||
@@ -7,7 +7,7 @@ This document describes the GNU Readline Library, a utility for aiding
|
||||
in the consistency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
Copyright (C) 1988--2016 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988--2020 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -1342,6 +1342,29 @@ This differs from @code{clear_history} because it frees private data
|
||||
Readline saves in the history list.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {void} rl_activate_mark (void)
|
||||
Enable an @emph{active} mark.
|
||||
When this is enabled, the text between point and mark (the @var{region}) is
|
||||
displayed in the terminal's standout mode (a @var{face}).
|
||||
This is called by various readline functions that set the mark and insert
|
||||
text, and is available for applications to call.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {void} rl_deactivate_mark (void)
|
||||
Turn off the active mark.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {void} rl_keep_mark_active (void)
|
||||
Indicate that the mark should remain active when the current readline function
|
||||
completes and after redisplay occurs.
|
||||
In most cases, the mark remains active for only the duration of a single
|
||||
bindable readline function.
|
||||
@end deftypefun
|
||||
|
||||
@deftypefun {int} rl_mark_active_p (void)
|
||||
Return a non-zero value if the mark is currently active; zero otherwise.
|
||||
@end deftypefun
|
||||
|
||||
@node Alternate Interface
|
||||
@subsection Alternate Interface
|
||||
|
||||
@@ -1733,8 +1756,8 @@ to determine whether or not there are any pending signals.
|
||||
|
||||
If an application does not wish Readline to catch @code{SIGWINCH}, it may
|
||||
call @code{rl_resize_terminal()} or @code{rl_set_screen_size()} to force
|
||||
Readline to update its idea of the terminal size when a @code{SIGWINCH}
|
||||
is received.
|
||||
Readline to update its idea of the terminal size when it receives
|
||||
a @code{SIGWINCH}.
|
||||
|
||||
@deftypefun void rl_echo_signal_char (int sig)
|
||||
If an application wishes to install its own signal handlers, but still
|
||||
@@ -1751,11 +1774,14 @@ Update Readline's internal screen size by reading values from the kernel.
|
||||
Set Readline's idea of the terminal size to @var{rows} rows and
|
||||
@var{cols} columns. If either @var{rows} or @var{columns} is less than
|
||||
or equal to 0, Readline's idea of that terminal dimension is unchanged.
|
||||
This is intended to tell Readline the physical dimensions of the terminal,
|
||||
and is used internally to calculate the maximum number of characters that
|
||||
may appear on a single line and on the screen.
|
||||
@end deftypefun
|
||||
|
||||
If an application does not want to install a @code{SIGWINCH} handler, but
|
||||
is still interested in the screen dimensions, Readline's idea of the screen
|
||||
size may be queried.
|
||||
is still interested in the screen dimensions, it may query Readline's idea
|
||||
of the screen size.
|
||||
|
||||
@deftypefun void rl_get_screen_size (int *rows, int *cols)
|
||||
Return Readline's idea of the terminal's size in the
|
||||
@@ -2039,7 +2065,7 @@ remove any quote characters from the directory name, because its result will
|
||||
be passed directly to @code{opendir()}.
|
||||
|
||||
The directory rewrite hook returns an integer that should be non-zero if
|
||||
the function modfies its directory argument.
|
||||
the function modifies its directory argument.
|
||||
The function should not modify the directory argument if it returns 0.
|
||||
@end deftypevar
|
||||
|
||||
@@ -2051,7 +2077,7 @@ is passed to @code{stat()} to determine the file's type and characteristics.
|
||||
This function does not need to remove quote characters from the filename.
|
||||
|
||||
The stat hook returns an integer that should be non-zero if
|
||||
the function modfies its directory argument.
|
||||
the function modifies its directory argument.
|
||||
The function should not modify the directory argument if it returns 0.
|
||||
@end deftypevar
|
||||
|
||||
@@ -2645,7 +2671,7 @@ com_help (arg)
|
||||
|
||||
if (!printed)
|
||||
@{
|
||||
printf ("No commands match `%s'. Possibilties are:\n", arg);
|
||||
printf ("No commands match `%s'. Possibilities are:\n", arg);
|
||||
|
||||
for (i = 0; commands[i].name; i++)
|
||||
@{
|
||||
|
||||
@@ -9,7 +9,7 @@ use these features. There is a document entitled "readline.texinfo"
|
||||
which contains both end-user and programmer documentation for the
|
||||
GNU Readline Library.
|
||||
|
||||
Copyright (C) 1988--2016 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988--2020 Free Software Foundation, Inc.
|
||||
|
||||
Authored by Brian Fox and Chet Ramey.
|
||||
|
||||
@@ -350,6 +350,11 @@ file is taken from the value of the environment variable @env{INPUTRC}. If
|
||||
that variable is unset, the default is @file{~/.inputrc}. If that
|
||||
file does not exist or cannot be read, the ultimate default is
|
||||
@file{/etc/inputrc}.
|
||||
@ifset BashFeatures
|
||||
The @w{@code{bind}} builtin command can also be used to set Readline
|
||||
keybindings and variables.
|
||||
@xref{Bash Builtins}.
|
||||
@end ifset
|
||||
|
||||
When a program which uses the Readline library starts up, the
|
||||
init file is read, and the key bindings are set.
|
||||
@@ -488,9 +493,9 @@ replaced with an ellipsis when displaying possible completions.
|
||||
@vindex completion-query-items
|
||||
The number of possible completions that determines when the user is
|
||||
asked whether the list of possibilities should be displayed.
|
||||
If the number of possible completions is greater than this value,
|
||||
Readline will ask the user whether or not he wishes to view
|
||||
them; otherwise, they are simply listed.
|
||||
If the number of possible completions is greater than or equal to this value,
|
||||
Readline will ask whether or not the user wishes to view them;
|
||||
otherwise, they are simply listed.
|
||||
This variable must be set to an integer value greater than or equal to 0.
|
||||
A negative value means Readline should never ask.
|
||||
The default limit is @code{100}.
|
||||
@@ -541,7 +546,7 @@ When set to @samp{On}, Readline will configure the terminal in a way
|
||||
that will enable it to insert each paste into the editing buffer as a
|
||||
single string of characters, instead of treating each character as if
|
||||
it had been read from the keyboard. This can prevent pasted characters
|
||||
from being interpreted as editing commands. The default is @samp{off}.
|
||||
from being interpreted as editing commands. The default is @samp{On}.
|
||||
|
||||
@item enable-keypad
|
||||
@vindex enable-keypad
|
||||
@@ -583,8 +588,9 @@ the maximum number of history entries will be set to 500.
|
||||
This variable can be set to either @samp{on} or @samp{off}. Setting it
|
||||
to @samp{on} means that the text of the lines being edited will scroll
|
||||
horizontally on a single screen line when they are longer than the width
|
||||
of the screen, instead of wrapping onto a new screen line. By default,
|
||||
this variable is set to @samp{off}.
|
||||
of the screen, instead of wrapping onto a new screen line.
|
||||
This variable is automatically set to @samp{on} for terminals of height 1.
|
||||
By default, this variable is set to @samp{off}.
|
||||
|
||||
@item input-meta
|
||||
@vindex input-meta
|
||||
@@ -1109,8 +1115,8 @@ set convert-meta off
|
||||
# rather than as meta-prefixed characters
|
||||
set output-meta on
|
||||
|
||||
# if there are more than 150 possible completions for
|
||||
# a word, ask the user if he wants to see all of them
|
||||
# if there are 150 or more possible completions for a word,
|
||||
# ask whether or not the user wants to see all of them
|
||||
set completion-query-items 150
|
||||
|
||||
# For FTP
|
||||
@@ -1173,11 +1179,11 @@ Move back to the start of the current or previous word.
|
||||
Words are composed of letters and digits.
|
||||
|
||||
@ifset BashFeatures
|
||||
@item shell-forward-word ()
|
||||
@item shell-forward-word (M-C-f)
|
||||
Move forward to the end of the next word.
|
||||
Words are delimited by non-quoted shell metacharacters.
|
||||
|
||||
@item shell-backward-word ()
|
||||
@item shell-backward-word (M-C-b)
|
||||
Move back to the start of the current or previous word.
|
||||
Words are delimited by non-quoted shell metacharacters.
|
||||
@end ifset
|
||||
@@ -1195,8 +1201,14 @@ Readline line does not take up more than one physical line or if the length
|
||||
of the current Readline line is not greater than the length of the prompt
|
||||
plus the screen width.
|
||||
|
||||
@item clear-display (M-C-l)
|
||||
Clear the screen and, if possible, the terminal's scrollback buffer,
|
||||
then redraw the current line,
|
||||
leaving the current line at the top of the screen.
|
||||
|
||||
@item clear-screen (C-l)
|
||||
Clear the screen and redraw the current line,
|
||||
Clear the screen,
|
||||
then redraw the current line,
|
||||
leaving the current line at the top of the screen.
|
||||
|
||||
@item redraw-current-line ()
|
||||
@@ -1242,10 +1254,12 @@ being entered.
|
||||
@item reverse-search-history (C-r)
|
||||
Search backward starting at the current line and moving `up' through
|
||||
the history as necessary. This is an incremental search.
|
||||
This command sets the region to the matched text and activates the mark.
|
||||
|
||||
@item forward-search-history (C-s)
|
||||
Search forward starting at the current line and moving `down' through
|
||||
the history as necessary. This is an incremental search.
|
||||
This command sets the region to the matched text and activates the mark.
|
||||
|
||||
@item non-incremental-reverse-search-history (M-p)
|
||||
Search backward starting at the current line and moving `up'
|
||||
@@ -1310,6 +1324,14 @@ the direction through the history (back or forward).
|
||||
The history expansion facilities are used to extract the last argument,
|
||||
as if the @samp{!$} history expansion had been specified.
|
||||
|
||||
@item operate-and-get-next (C-o)
|
||||
Accept the current line for return to the calling application as if a
|
||||
newline had been entered,
|
||||
and fetch the next line relative to the current line from the history
|
||||
for editing.
|
||||
A numeric argument, if supplied, specifies the history entry to use instead
|
||||
of the current line.
|
||||
|
||||
@end ftable
|
||||
|
||||
@node Commands For Text
|
||||
@@ -1357,6 +1379,11 @@ each character as if it had been read from the keyboard. The characters
|
||||
are inserted as if each one was bound to @code{self-insert} instead of
|
||||
executing any editing commands.
|
||||
|
||||
Bracketed paste sets the region (the characters between point and the mark)
|
||||
to the inserted text. It uses the concept of an @emph{active mark}: when the
|
||||
mark is active, Readline redisplay uses the terminal's standout mode to
|
||||
denote the region.
|
||||
|
||||
@item transpose-chars (C-t)
|
||||
Drag the character before the cursor forward over
|
||||
the character at the cursor, moving the
|
||||
@@ -1406,9 +1433,13 @@ By default, this command is unbound.
|
||||
|
||||
@item kill-line (C-k)
|
||||
Kill the text from point to the end of the line.
|
||||
With a negative numeric argument, kill backward from the cursor to the
|
||||
beginning of the current line.
|
||||
|
||||
@item backward-kill-line (C-x Rubout)
|
||||
Kill backward from the cursor to the beginning of the current line.
|
||||
With a negative numeric argument, kill forward from the cursor to the
|
||||
end of the current line.
|
||||
|
||||
@item unix-line-discard (C-u)
|
||||
Kill backward from the cursor to the beginning of the current line.
|
||||
@@ -1427,7 +1458,7 @@ Kill the word behind point.
|
||||
Word boundaries are the same as @code{backward-word}.
|
||||
|
||||
@ifset BashFeatures
|
||||
@item shell-kill-word ()
|
||||
@item shell-kill-word (M-C-d)
|
||||
Kill from point to the end of the current word, or if between
|
||||
words, to the end of the next word.
|
||||
Word boundaries are the same as @code{shell-forward-word}.
|
||||
@@ -1437,6 +1468,14 @@ Kill the word behind point.
|
||||
Word boundaries are the same as @code{shell-backward-word}.
|
||||
@end ifset
|
||||
|
||||
@item shell-transpose-words (M-C-t)
|
||||
Drag the word before point past the word after point,
|
||||
moving point past that word as well.
|
||||
If the insertion point is at the end of the line, this transposes
|
||||
the last two words on the line.
|
||||
Word boundaries are the same as @code{shell-forward-word} and
|
||||
@code{shell-backward-word}.
|
||||
|
||||
@item unix-word-rubout (C-w)
|
||||
Kill the word behind point, using white space as a word boundary.
|
||||
The killed text is saved on the kill-ring.
|
||||
@@ -1774,12 +1813,6 @@ Perform history and alias expansion on the current line.
|
||||
@item insert-last-argument (M-. or M-_)
|
||||
A synonym for @code{yank-last-arg}.
|
||||
|
||||
@item operate-and-get-next (C-o)
|
||||
Accept the current line for execution and fetch the next line
|
||||
relative to the current line from the history for editing.
|
||||
A numeric argument, if supplied, specifies the history entry to use instead
|
||||
of the current line.
|
||||
|
||||
@item edit-and-execute-command (C-x C-e)
|
||||
Invoke an editor on the current command line, and execute the result as shell
|
||||
commands.
|
||||
@@ -2044,7 +2077,7 @@ The @option{-E} option indicates that other supplied options and actions should
|
||||
apply to ``empty'' command completion; that is, completion attempted on a
|
||||
blank line.
|
||||
The @option{-I} option indicates that other supplied options and actions should
|
||||
apply to completion on the inital non-assignment word on the line, or after a
|
||||
apply to completion on the initial non-assignment word on the line, or after a
|
||||
command delimiter such as @samp{;} or @samp{|}, which is usually command
|
||||
name completion.
|
||||
If multiple options are supplied, the @option{-D} option takes precedence
|
||||
@@ -2255,7 +2288,7 @@ The @option{-E} option indicates that other supplied options should
|
||||
apply to ``empty'' command completion; that is, completion attempted on a
|
||||
blank line.
|
||||
The @option{-I} option indicates that other supplied options should
|
||||
apply to completion on the inital non-assignment word on the line, or after a
|
||||
apply to completion on the initial non-assignment word on the line, or after a
|
||||
command delimiter such as @samp{;} or @samp{|}, which is usually command
|
||||
name completion.
|
||||
|
||||
@@ -2370,7 +2403,7 @@ character to the directory name, in case we want to append to it.
|
||||
The @option{-o bashdefault} option brings in the rest of the "Bash default"
|
||||
completions -- possible completion that Bash adds to the default Readline
|
||||
set. These include things like command name completion, variable completion
|
||||
for words beginning with @samp{@{}, completions containing pathname
|
||||
for words beginning with @samp{$} or @samp{$@{}, completions containing pathname
|
||||
expansion patterns (@pxref{Filename Expansion}), and so on.
|
||||
|
||||
Once installed using @code{complete}, @code{_comp_cd} will be called every
|
||||
@@ -2380,7 +2413,7 @@ Many more examples -- an extensive collection of completions for most of
|
||||
the common GNU, Unix, and Linux commands -- are available as part of the
|
||||
bash_completion project. This is installed by default on many GNU/Linux
|
||||
distributions. Originally written by Ian Macdonald, the project now lives
|
||||
at @url{http://bash-completion.alioth.debian.org/}. There are ports for
|
||||
at @url{https://github.com/scop/bash-completion/}. There are ports for
|
||||
other systems such as Solaris and Mac OS X.
|
||||
|
||||
An older version of the bash_completion package is distributed with bash
|
||||
|
||||
@@ -12,7 +12,7 @@ This manual describes the end user interface of the GNU Readline Library
|
||||
consistency of user interface across discrete programs which provide
|
||||
a command line interface.
|
||||
|
||||
Copyright @copyright{} 1988--2016 Free Software Foundation, Inc.
|
||||
Copyright @copyright{} 1988--2020 Free Software Foundation, Inc.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
@ignore
|
||||
Copyright (C) 1988-2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988-2020 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set EDITION 8.0
|
||||
@set VERSION 8.0
|
||||
@set UPDATED 30 November 2018
|
||||
@set UPDATED-MONTH November 2018
|
||||
@set EDITION 8.1
|
||||
@set VERSION 8.1
|
||||
@set UPDATED 29 October 2020
|
||||
@set UPDATED-MONTH October 2020
|
||||
|
||||
@set LASTCHANGE Fri Nov 30 22:50:53 EST 2018
|
||||
@set LASTCHANGE Thu Oct 29 16:49:01 EDT 2020
|
||||
|
||||
@@ -47,7 +47,7 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
|
||||
{ ISFUNC, rl_clear_screen }, /* Control-l */
|
||||
{ ISFUNC, rl_newline }, /* Control-m */
|
||||
{ ISFUNC, rl_get_next_history }, /* Control-n */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
|
||||
{ ISFUNC, rl_operate_and_get_next }, /* Control-o */
|
||||
{ ISFUNC, rl_get_previous_history }, /* Control-p */
|
||||
{ ISFUNC, rl_quoted_insert }, /* Control-q */
|
||||
{ ISFUNC, rl_reverse_search_history }, /* Control-r */
|
||||
@@ -327,7 +327,7 @@ KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
|
||||
{ ISFUNC, rl_tab_insert }, /* Meta-Control-i */
|
||||
{ ISFUNC, rl_vi_editing_mode }, /* Meta-Control-j */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-k */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-l */
|
||||
{ ISFUNC, rl_clear_display }, /* Meta-Control-l */
|
||||
{ ISFUNC, rl_vi_editing_mode }, /* Meta-Control-m */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-n */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-o */
|
||||
|
||||
@@ -377,11 +377,11 @@ com_stat (arg)
|
||||
|
||||
printf ("Statistics for `%s':\n", arg);
|
||||
|
||||
printf ("%s has %d link%s, and is %d byte%s in length.\n",
|
||||
printf ("%s has %d link%s, and is %lu byte%s in length.\n",
|
||||
arg,
|
||||
finfo.st_nlink,
|
||||
(finfo.st_nlink == 1) ? "" : "s",
|
||||
finfo.st_size,
|
||||
(unsigned long)finfo.st_size,
|
||||
(finfo.st_size == 1) ? "" : "s");
|
||||
printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime));
|
||||
printf (" Last access at: %s", ctime (&finfo.st_atime));
|
||||
@@ -417,7 +417,7 @@ com_help (arg)
|
||||
|
||||
if (!printed)
|
||||
{
|
||||
printf ("No commands match `%s'. Possibilties are:\n", arg);
|
||||
printf ("No commands match `%s'. Possibilities are:\n", arg);
|
||||
|
||||
for (i = 0; commands[i].name; i++)
|
||||
{
|
||||
|
||||
@@ -46,6 +46,7 @@ extern void exit();
|
||||
|
||||
extern HIST_ENTRY **history_list ();
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
char *temp, *prompt;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* funmap.c -- attach names to functions. */
|
||||
|
||||
/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -73,6 +73,7 @@ static const FUNMAP default_funmap[] = {
|
||||
{ "capitalize-word", rl_capitalize_word },
|
||||
{ "character-search", rl_char_search },
|
||||
{ "character-search-backward", rl_backward_char_search },
|
||||
{ "clear-display", rl_clear_display },
|
||||
{ "clear-screen", rl_clear_screen },
|
||||
{ "complete", rl_complete },
|
||||
{ "copy-backward-word", rl_copy_backward_word },
|
||||
@@ -116,6 +117,7 @@ static const FUNMAP default_funmap[] = {
|
||||
{ "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
|
||||
{ "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
|
||||
{ "old-menu-complete", rl_old_menu_complete },
|
||||
{ "operate-and-get-next", rl_operate_and_get_next },
|
||||
{ "overwrite-mode", rl_overwrite_mode },
|
||||
#if defined (_WIN32)
|
||||
{ "paste-from-clipboard", rl_paste_from_clipboard },
|
||||
@@ -157,7 +159,7 @@ static const FUNMAP default_funmap[] = {
|
||||
{ "vi-backward-bigword", rl_vi_bWord },
|
||||
{ "vi-backward-word", rl_vi_bword },
|
||||
{ "vi-bWord", rl_vi_bWord },
|
||||
{ "vi-bword", rl_vi_bword },
|
||||
{ "vi-bword", rl_vi_bword }, /* BEWARE: name matching is case insensitive */
|
||||
{ "vi-change-case", rl_vi_change_case },
|
||||
{ "vi-change-char", rl_vi_change_char },
|
||||
{ "vi-change-to", rl_vi_change_to },
|
||||
@@ -171,13 +173,13 @@ static const FUNMAP default_funmap[] = {
|
||||
{ "vi-end-bigword", rl_vi_eWord },
|
||||
{ "vi-end-word", rl_vi_end_word },
|
||||
{ "vi-eof-maybe", rl_vi_eof_maybe },
|
||||
{ "vi-eword", rl_vi_eword },
|
||||
{ "vi-eword", rl_vi_eword }, /* BEWARE: name matching is case insensitive */
|
||||
{ "vi-fWord", rl_vi_fWord },
|
||||
{ "vi-fetch-history", rl_vi_fetch_history },
|
||||
{ "vi-first-print", rl_vi_first_print },
|
||||
{ "vi-forward-bigword", rl_vi_fWord },
|
||||
{ "vi-forward-word", rl_vi_fword },
|
||||
{ "vi-fword", rl_vi_fword },
|
||||
{ "vi-fword", rl_vi_fword }, /* BEWARE: name matching is case insensitive */
|
||||
{ "vi-goto-mark", rl_vi_goto_mark },
|
||||
{ "vi-insert-beg", rl_vi_insert_beg },
|
||||
{ "vi-insertion-mode", rl_vi_insert_mode },
|
||||
|
||||
@@ -89,7 +89,7 @@ char history_expansion_char = '!';
|
||||
char history_subst_char = '^';
|
||||
|
||||
/* During tokenization, if this character is seen as the first character
|
||||
of a word, then it, and all subsequent characters upto a newline are
|
||||
of a word, then it, and all subsequent characters up to a newline are
|
||||
ignored. For a Bourne shell, this should be '#'. Bash special cases
|
||||
the interactive comment character to not be a comment delimiter. */
|
||||
char history_comment_char = '\0';
|
||||
@@ -180,7 +180,7 @@ get_history_event (const char *string, int *caller_index, int delimiting_quote)
|
||||
}
|
||||
|
||||
/* Hack case of numeric line specification. */
|
||||
if (string[i] == '-')
|
||||
if (string[i] == '-' && _rl_digit_p (string[i+1]))
|
||||
{
|
||||
sign = -1;
|
||||
i++;
|
||||
@@ -230,10 +230,12 @@ get_history_event (const char *string, int *caller_index, int delimiting_quote)
|
||||
}
|
||||
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
if ((!substring_okay && (whitespace (c) || c == ':' ||
|
||||
(history_event_delimiter_chars && member (c, history_event_delimiter_chars)) ||
|
||||
(history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
|
||||
string[i] == delimiting_quote)) ||
|
||||
if ((!substring_okay &&
|
||||
(whitespace (c) || c == ':' ||
|
||||
(i > local_index && history_event_delimiter_chars && c == '-') ||
|
||||
(c != '-' && history_event_delimiter_chars && member (c, history_event_delimiter_chars)) ||
|
||||
(history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
|
||||
string[i] == delimiting_quote)) ||
|
||||
string[i] == '\n' ||
|
||||
(substring_okay && string[i] == '?'))
|
||||
break;
|
||||
@@ -409,7 +411,10 @@ hist_error(char *s, int start, int current, int errtype)
|
||||
}
|
||||
|
||||
temp = (char *)xmalloc (ll + elen + 3);
|
||||
strncpy (temp, s + start, ll);
|
||||
if (s[start])
|
||||
strncpy (temp, s + start, ll);
|
||||
else
|
||||
ll = 0;
|
||||
temp[ll] = ':';
|
||||
temp[ll + 1] = ' ';
|
||||
strcpy (temp + ll + 2, emsg);
|
||||
@@ -624,7 +629,7 @@ history_expand_internal (char *string, int start, int qc, int *end_index_ptr, ch
|
||||
return an error state after adding this line to the
|
||||
history. */
|
||||
case 'p':
|
||||
print_only++;
|
||||
print_only = 1;
|
||||
break;
|
||||
|
||||
/* :t discards all but the last part of the pathname. */
|
||||
@@ -1356,6 +1361,11 @@ get_history_word_specifier (char *spec, char *from, int *caller_index)
|
||||
i++;
|
||||
last = '$';
|
||||
}
|
||||
else if (spec[i] == '^')
|
||||
{
|
||||
i++;
|
||||
last = 1;
|
||||
}
|
||||
#if 0
|
||||
else if (!spec[i] || spec[i] == ':')
|
||||
/* check against `:' because there could be a modifier separator */
|
||||
|
||||
+42
-12
@@ -1,6 +1,6 @@
|
||||
/* histfile.c - functions to manipulate the history file. */
|
||||
|
||||
/* Copyright (C) 1989-2018 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1989-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (History), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
@@ -26,6 +26,8 @@
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (__TANDEM)
|
||||
# define _XOPEN_SOURCE_EXTENDED 1
|
||||
# include <unistd.h>
|
||||
# include <floss.h>
|
||||
#endif
|
||||
|
||||
@@ -79,6 +81,11 @@
|
||||
|
||||
#endif /* HISTORY_USE_MMAP */
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
|
||||
on win 95/98/nt), we want to open files with O_BINARY mode so that there
|
||||
is no \n -> \r\n conversion performed. On other systems, we don't want to
|
||||
@@ -138,6 +145,7 @@ static char *history_backupfile PARAMS((const char *));
|
||||
static char *history_tempfile PARAMS((const char *));
|
||||
static int histfile_backup PARAMS((const char *, const char *));
|
||||
static int histfile_restore PARAMS((const char *, const char *));
|
||||
static int history_rename PARAMS((const char *, const char *));
|
||||
|
||||
/* Return the string that should be used in the place of this
|
||||
filename. This only matters when you don't specify the
|
||||
@@ -449,6 +457,18 @@ read_history_range (const char *filename, int from, int to)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* We need a special version for WIN32 because Windows rename() refuses to
|
||||
overwrite an existing file. */
|
||||
static int
|
||||
history_rename (const char *old, const char *new)
|
||||
{
|
||||
#if defined (_WIN32)
|
||||
return (MoveFileEx (old, new, MOVEFILE_REPLACE_EXISTING) == 0 ? -1 : 0);
|
||||
#else
|
||||
return (rename (old, new));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Save FILENAME to BACK, handling case where FILENAME is a symlink
|
||||
(e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */
|
||||
static int
|
||||
@@ -462,10 +482,10 @@ histfile_backup (const char *filename, const char *back)
|
||||
if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0)
|
||||
{
|
||||
linkbuf[n] = '\0';
|
||||
return (rename (linkbuf, back));
|
||||
return (history_rename (linkbuf, back));
|
||||
}
|
||||
#endif
|
||||
return (rename (filename, back));
|
||||
return (history_rename (filename, back));
|
||||
}
|
||||
|
||||
/* Restore ORIG from BACKUP handling case where ORIG is a symlink
|
||||
@@ -481,12 +501,18 @@ histfile_restore (const char *backup, const char *orig)
|
||||
if ((n = readlink (orig, linkbuf, sizeof (linkbuf) - 1)) > 0)
|
||||
{
|
||||
linkbuf[n] = '\0';
|
||||
return (rename (backup, linkbuf));
|
||||
return (history_rename (backup, linkbuf));
|
||||
}
|
||||
#endif
|
||||
return (rename (backup, orig));
|
||||
return (history_rename (backup, orig));
|
||||
}
|
||||
|
||||
/* Should we call chown, based on whether finfo and nfinfo describe different
|
||||
files with different owners? */
|
||||
|
||||
#define SHOULD_CHOWN(finfo, nfinfo) \
|
||||
(finfo.st_uid != nfinfo.st_uid || finfo.st_gid != nfinfo.st_gid)
|
||||
|
||||
/* Truncate the history file FNAME, leaving only LINES trailing lines.
|
||||
If FNAME is NULL, then use ~/.history. Writes a new file and renames
|
||||
it to the original name. Returns 0 on success, errno on failure. */
|
||||
@@ -495,7 +521,7 @@ history_truncate_file (const char *fname, int lines)
|
||||
{
|
||||
char *buffer, *filename, *tempname, *bp, *bp1; /* bp1 == bp+1 */
|
||||
int file, chars_read, rv, orig_lines, exists, r;
|
||||
struct stat finfo;
|
||||
struct stat finfo, nfinfo;
|
||||
size_t file_size;
|
||||
|
||||
history_lines_written_to_file = 0;
|
||||
@@ -516,6 +542,9 @@ history_truncate_file (const char *fname, int lines)
|
||||
}
|
||||
exists = 1;
|
||||
|
||||
nfinfo.st_uid = finfo.st_uid;
|
||||
nfinfo.st_gid = finfo.st_gid;
|
||||
|
||||
if (S_ISREG (finfo.st_mode) == 0)
|
||||
{
|
||||
close (file);
|
||||
@@ -604,6 +633,9 @@ history_truncate_file (const char *fname, int lines)
|
||||
if (write (file, bp, chars_read - (bp - buffer)) < 0)
|
||||
rv = errno;
|
||||
|
||||
if (fstat (file, &nfinfo) < 0 && rv == 0)
|
||||
rv = errno;
|
||||
|
||||
if (close (file) < 0 && rv == 0)
|
||||
rv = errno;
|
||||
}
|
||||
@@ -620,6 +652,7 @@ history_truncate_file (const char *fname, int lines)
|
||||
|
||||
if (rv != 0)
|
||||
{
|
||||
rv = errno;
|
||||
if (tempname)
|
||||
unlink (tempname);
|
||||
history_lines_written_to_file = 0;
|
||||
@@ -630,7 +663,7 @@ history_truncate_file (const char *fname, int lines)
|
||||
user is running this, it's a no-op. If the shell is running after sudo
|
||||
with a shared history file, we don't want to leave the history file
|
||||
owned by root. */
|
||||
if (rv == 0 && exists)
|
||||
if (rv == 0 && exists && SHOULD_CHOWN (finfo, nfinfo))
|
||||
r = chown (filename, finfo.st_uid, finfo.st_gid);
|
||||
#endif
|
||||
|
||||
@@ -649,7 +682,7 @@ history_do_write (const char *filename, int nelements, int overwrite)
|
||||
register int i;
|
||||
char *output, *tempname, *histname;
|
||||
int file, mode, rv, exists;
|
||||
struct stat finfo;
|
||||
struct stat finfo, nfinfo;
|
||||
#ifdef HISTORY_USE_MMAP
|
||||
size_t cursize;
|
||||
|
||||
@@ -694,15 +727,11 @@ history_do_write (const char *filename, int nelements, int overwrite)
|
||||
the_history = history_list ();
|
||||
/* Calculate the total number of bytes to write. */
|
||||
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
|
||||
#if 0
|
||||
buffer_size += 2 + HISTENT_BYTES (the_history[i]);
|
||||
#else
|
||||
{
|
||||
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
|
||||
buffer_size += strlen (the_history[i]->timestamp) + 1;
|
||||
buffer_size += strlen (the_history[i]->line) + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate the buffer, and fill it. */
|
||||
#ifdef HISTORY_USE_MMAP
|
||||
@@ -767,6 +796,7 @@ mmap_error:
|
||||
|
||||
if (rv != 0)
|
||||
{
|
||||
rv = errno;
|
||||
if (tempname)
|
||||
unlink (tempname);
|
||||
history_lines_written_to_file = 0;
|
||||
|
||||
+27
-6
@@ -22,6 +22,8 @@
|
||||
#define READLINE_LIBRARY
|
||||
|
||||
#if defined (__TANDEM)
|
||||
# define _XOPEN_SOURCE_EXTENDED 1
|
||||
# define _TANDEM_SOURCE 1
|
||||
# include <floss.h>
|
||||
#endif
|
||||
|
||||
@@ -347,8 +349,7 @@ _rl_input_available (void)
|
||||
FD_ZERO (&exceptfds);
|
||||
FD_SET (tty, &readfds);
|
||||
FD_SET (tty, &exceptfds);
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = _keyboard_input_timeout;
|
||||
USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout);
|
||||
return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
|
||||
#else
|
||||
|
||||
@@ -367,6 +368,24 @@ _rl_input_available (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_rl_nchars_available ()
|
||||
{
|
||||
int chars_avail, fd, result;
|
||||
|
||||
chars_avail = 0;
|
||||
|
||||
#if defined (FIONREAD)
|
||||
fd = fileno (rl_instream);
|
||||
errno = 0;
|
||||
result = ioctl (fd, FIONREAD, &chars_avail);
|
||||
if (result == -1 && errno == EIO)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
return chars_avail;
|
||||
}
|
||||
|
||||
int
|
||||
_rl_input_queued (int t)
|
||||
{
|
||||
@@ -493,7 +512,7 @@ rl_read_key (void)
|
||||
{
|
||||
if (rl_get_char (&c) == 0)
|
||||
c = (*rl_getc_function) (rl_instream);
|
||||
/* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d", _rl_caught_signal); */
|
||||
/* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d\r\n", _rl_caught_signal); */
|
||||
RL_CHECK_SIGNALS ();
|
||||
}
|
||||
}
|
||||
@@ -596,6 +615,10 @@ handle_error:
|
||||
else if (_rl_caught_signal == SIGINT)
|
||||
#endif
|
||||
RL_CHECK_SIGNALS ();
|
||||
#if defined (SIGTSTP)
|
||||
else if (_rl_caught_signal == SIGTSTP)
|
||||
RL_CHECK_SIGNALS ();
|
||||
#endif
|
||||
/* non-keyboard-generated signals of interest */
|
||||
#if defined (SIGWINCH)
|
||||
else if (_rl_caught_signal == SIGWINCH)
|
||||
@@ -631,9 +654,7 @@ _rl_read_mbchar (char *mbchar, int size)
|
||||
mb_len = 0;
|
||||
while (mb_len < size)
|
||||
{
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
c = (mb_len == 0) ? _rl_bracketed_read_key () : rl_read_key ();
|
||||
|
||||
if (c < 0)
|
||||
break;
|
||||
|
||||
+68
-7
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -185,11 +185,13 @@ rl_display_search (char *search_string, int flags, int where)
|
||||
strcpy (message + msglen, "i-search)`");
|
||||
msglen += 10;
|
||||
|
||||
if (search_string)
|
||||
if (search_string && *search_string)
|
||||
{
|
||||
strcpy (message + msglen, search_string);
|
||||
msglen += searchlen;
|
||||
}
|
||||
else
|
||||
_rl_optimize_redisplay ();
|
||||
|
||||
strcpy (message + msglen, "': ");
|
||||
|
||||
@@ -255,6 +257,9 @@ _rl_isearch_init (int direction)
|
||||
|
||||
_rl_iscxt = cxt; /* save globally */
|
||||
|
||||
/* experimental right now */
|
||||
_rl_init_executing_keyseq ();
|
||||
|
||||
return cxt;
|
||||
}
|
||||
|
||||
@@ -287,16 +292,22 @@ _rl_isearch_fini (_rl_search_cxt *cxt)
|
||||
else
|
||||
cxt->sline_index = strlen (rl_line_buffer);
|
||||
rl_mark = cxt->save_mark;
|
||||
rl_deactivate_mark ();
|
||||
}
|
||||
|
||||
rl_point = cxt->sline_index;
|
||||
/* Don't worry about where to put the mark here; rl_get_previous_history
|
||||
and rl_get_next_history take care of it. */
|
||||
and rl_get_next_history take care of it.
|
||||
If we want to highlight the search string, this is where to set the
|
||||
point and mark to do it. */
|
||||
_rl_fix_point (0);
|
||||
rl_deactivate_mark ();
|
||||
|
||||
/* _rl_optimize_redisplay (); */
|
||||
rl_clear_message ();
|
||||
}
|
||||
|
||||
/* XXX - we could use _rl_bracketed_read_mbstring () here. */
|
||||
int
|
||||
_rl_search_getchar (_rl_search_cxt *cxt)
|
||||
{
|
||||
@@ -342,6 +353,24 @@ _rl_isearch_dispatch (_rl_search_cxt *cxt, int c)
|
||||
return -1;
|
||||
}
|
||||
|
||||
_rl_add_executing_keyseq (c);
|
||||
|
||||
/* XXX - experimental code to allow users to bracketed-paste into the search
|
||||
string even when ESC is one of the isearch-terminators. Not perfect yet. */
|
||||
if (_rl_enable_bracketed_paste && c == ESC && strchr (cxt->search_terminators, c) && (n = _rl_nchars_available ()) > (BRACK_PASTE_SLEN-1))
|
||||
{
|
||||
j = _rl_read_bracketed_paste_prefix (c);
|
||||
if (j == 1)
|
||||
{
|
||||
cxt->lastc = -7; /* bracketed paste, see below */
|
||||
goto opcode_dispatch;
|
||||
}
|
||||
else if (_rl_pushed_input_available ()) /* eat extra char we pushed back */
|
||||
c = cxt->lastc = rl_read_key ();
|
||||
else
|
||||
c = cxt->lastc; /* last ditch */
|
||||
}
|
||||
|
||||
/* If we are moving into a new keymap, modify cxt->keymap and go on.
|
||||
This can be a problem if c == ESC and we want to terminate the
|
||||
incremental search, so we check */
|
||||
@@ -387,7 +416,18 @@ add_character:
|
||||
/* Translate the keys we do something with to opcodes. */
|
||||
if (c >= 0 && cxt->keymap[c].type == ISFUNC)
|
||||
{
|
||||
f = cxt->keymap[c].function;
|
||||
/* If we have a multibyte character, see if it's bound to something that
|
||||
affects the search. */
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0 && cxt->mb[1])
|
||||
f = rl_function_of_keyseq (cxt->mb, cxt->keymap, (int *)NULL);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
f = cxt->keymap[c].function;
|
||||
if (f == rl_do_lowercase_version)
|
||||
f = cxt->keymap[_rl_to_lower (c)].function;
|
||||
}
|
||||
|
||||
if (f == rl_reverse_search_history)
|
||||
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
|
||||
@@ -454,9 +494,14 @@ add_character:
|
||||
}
|
||||
else if (cxt->lastc > 0 && cxt->prevc > 0 && f && f != rl_insert)
|
||||
{
|
||||
rl_stuff_char (cxt->lastc);
|
||||
rl_execute_next (cxt->prevc);
|
||||
/* XXX - do we insert everything in cxt->pmb? */
|
||||
_rl_term_executing_keyseq (); /* should this go in the caller? */
|
||||
|
||||
_rl_pending_command.map = cxt->keymap;
|
||||
_rl_pending_command.count = 1; /* XXX */
|
||||
_rl_pending_command.key = cxt->lastc;
|
||||
_rl_pending_command.func = f;
|
||||
_rl_command_to_execute = &_rl_pending_command;
|
||||
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@@ -502,6 +547,9 @@ add_character:
|
||||
return (0);
|
||||
}
|
||||
|
||||
_rl_init_executing_keyseq ();
|
||||
|
||||
opcode_dispatch:
|
||||
/* Now dispatch on the character. `Opcodes' affect the search string or
|
||||
state. Other characters are added to the string. */
|
||||
switch (cxt->lastc)
|
||||
@@ -519,6 +567,7 @@ add_character:
|
||||
rl_display_search (cxt->search_string, cxt->sflags, -1);
|
||||
break;
|
||||
}
|
||||
/* XXX - restore keymap here? */
|
||||
return (1);
|
||||
}
|
||||
else if ((cxt->sflags & SF_REVERSE) && cxt->sline_index >= 0)
|
||||
@@ -566,9 +615,11 @@ add_character:
|
||||
rl_replace_line (cxt->lines[cxt->save_line], 0);
|
||||
rl_point = cxt->save_point;
|
||||
rl_mark = cxt->save_mark;
|
||||
rl_deactivate_mark ();
|
||||
rl_restore_prompt();
|
||||
rl_clear_message ();
|
||||
|
||||
_rl_fix_point (1); /* in case save_line and save_point are out of sync */
|
||||
return -1;
|
||||
|
||||
case -5: /* C-W */
|
||||
@@ -632,6 +683,8 @@ add_character:
|
||||
free (paste);
|
||||
break;
|
||||
}
|
||||
if (_rl_enable_active_region)
|
||||
rl_activate_mark ();
|
||||
if (cxt->search_string_index + pastelen + 1 >= cxt->search_string_size)
|
||||
{
|
||||
cxt->search_string_size += pastelen + 2;
|
||||
@@ -736,11 +789,15 @@ add_character:
|
||||
cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0;
|
||||
}
|
||||
|
||||
/* reset the keymaps for the next time through the loop */
|
||||
cxt->keymap = cxt->okeymap = _rl_keymap;
|
||||
|
||||
if (cxt->sflags & SF_FAILED)
|
||||
{
|
||||
/* We cannot find the search string. Ding the bell. */
|
||||
rl_ding ();
|
||||
cxt->history_pos = cxt->last_found_line;
|
||||
rl_deactivate_mark ();
|
||||
rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
|
||||
return 1;
|
||||
}
|
||||
@@ -752,7 +809,11 @@ add_character:
|
||||
{
|
||||
cxt->prev_line_found = cxt->lines[cxt->history_pos];
|
||||
rl_replace_line (cxt->lines[cxt->history_pos], 0);
|
||||
if (_rl_enable_active_region)
|
||||
rl_activate_mark ();
|
||||
rl_point = cxt->sline_index;
|
||||
if (rl_mark_active_p () && cxt->search_string_index > 0)
|
||||
rl_mark = rl_point + cxt->search_string_index;
|
||||
cxt->last_found_line = cxt->history_pos;
|
||||
rl_display_search (cxt->search_string, cxt->sflags, (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
|
||||
}
|
||||
|
||||
+105
-5
@@ -1,6 +1,6 @@
|
||||
/* kill.c -- kill ring management. */
|
||||
|
||||
/* Copyright (C) 1994-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -408,6 +408,7 @@ region_kill_internal (int delete)
|
||||
_rl_copy_to_kill_ring (text, rl_point < rl_mark);
|
||||
}
|
||||
|
||||
_rl_fix_point (1);
|
||||
_rl_last_command_was_kill++;
|
||||
return 0;
|
||||
}
|
||||
@@ -427,8 +428,8 @@ rl_kill_region (int count, int key)
|
||||
|
||||
npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
|
||||
r = region_kill_internal (1);
|
||||
_rl_fix_point (1);
|
||||
rl_point = npoint;
|
||||
_rl_fix_point (1);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -605,7 +606,7 @@ rl_yank_nth_arg_internal (int count, int key, int history_skip)
|
||||
#if defined (VI_MODE)
|
||||
/* Vi mode always inserts a space before yanking the argument, and it
|
||||
inserts it right *after* rl_point. */
|
||||
if (rl_editing_mode == vi_mode)
|
||||
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
|
||||
{
|
||||
rl_vi_append_mode (1, key);
|
||||
rl_insert_text (" ");
|
||||
@@ -668,8 +669,7 @@ rl_yank_last_arg (int count, int key)
|
||||
|
||||
/* Having read the special escape sequence denoting the beginning of a
|
||||
`bracketed paste' sequence, read the rest of the pasted input until the
|
||||
closing sequence and insert the pasted text as a single unit without
|
||||
interpretation. */
|
||||
closing sequence and return the pasted text. */
|
||||
char *
|
||||
_rl_bracketed_text (size_t *lenp)
|
||||
{
|
||||
@@ -715,6 +715,10 @@ _rl_bracketed_text (size_t *lenp)
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/* Having read the special escape sequence denoting the beginning of a
|
||||
`bracketed paste' sequence, read the rest of the pasted input until the
|
||||
closing sequence and insert the pasted text as a single unit without
|
||||
interpretation. Temporarily highlight the inserted text. */
|
||||
int
|
||||
rl_bracketed_paste_begin (int count, int key)
|
||||
{
|
||||
@@ -723,12 +727,108 @@ rl_bracketed_paste_begin (int count, int key)
|
||||
char *buf;
|
||||
|
||||
buf = _rl_bracketed_text (&len);
|
||||
rl_mark = rl_point;
|
||||
retval = rl_insert_text (buf) == len ? 0 : 1;
|
||||
if (_rl_enable_active_region)
|
||||
rl_activate_mark ();
|
||||
|
||||
xfree (buf);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
_rl_read_bracketed_paste_prefix (int c)
|
||||
{
|
||||
char pbuf[BRACK_PASTE_SLEN+1], *pbpref;
|
||||
int key, ind, j;
|
||||
|
||||
pbpref = BRACK_PASTE_PREF; /* XXX - debugging */
|
||||
if (c != pbpref[0])
|
||||
return (0);
|
||||
pbuf[ind = 0] = c;
|
||||
while (ind < BRACK_PASTE_SLEN-1 &&
|
||||
(RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
|
||||
_rl_pushed_input_available () == 0 &&
|
||||
_rl_input_queued (0))
|
||||
{
|
||||
key = rl_read_key (); /* XXX - for now */
|
||||
if (key < 0)
|
||||
break;
|
||||
pbuf[++ind] = key;
|
||||
if (pbuf[ind] != pbpref[ind])
|
||||
break;
|
||||
}
|
||||
|
||||
if (ind < BRACK_PASTE_SLEN-1) /* read incomplete sequence */
|
||||
{
|
||||
while (ind >= 0)
|
||||
_rl_unget_char (pbuf[ind--]);
|
||||
return (key < 0 ? key : 0);
|
||||
}
|
||||
return (key < 0 ? key : 1);
|
||||
}
|
||||
|
||||
/* Get a character from wherever we read input, handling input in bracketed
|
||||
paste mode. If we don't have or use bracketed paste mode, this can be
|
||||
used in place of rl_read_key(). */
|
||||
int
|
||||
_rl_bracketed_read_key ()
|
||||
{
|
||||
int c, r;
|
||||
char *pbuf;
|
||||
size_t pblen;
|
||||
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
if (c < 0)
|
||||
return -1;
|
||||
|
||||
/* read pasted data with bracketed-paste mode enabled. */
|
||||
if (_rl_enable_bracketed_paste && c == ESC && (r = _rl_read_bracketed_paste_prefix (c)) == 1)
|
||||
{
|
||||
pbuf = _rl_bracketed_text (&pblen);
|
||||
if (pblen == 0)
|
||||
{
|
||||
xfree (pbuf);
|
||||
return 0; /* XXX */
|
||||
}
|
||||
c = (unsigned char)pbuf[0];
|
||||
if (pblen > 1)
|
||||
{
|
||||
while (--pblen > 0)
|
||||
_rl_unget_char ((unsigned char)pbuf[pblen]);
|
||||
}
|
||||
xfree (pbuf);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Get a character from wherever we read input, handling input in bracketed
|
||||
paste mode. If we don't have or use bracketed paste mode, this can be
|
||||
used in place of rl_read_key(). */
|
||||
int
|
||||
_rl_bracketed_read_mbstring (char *mb, int mlen)
|
||||
{
|
||||
int c, r;
|
||||
|
||||
c = _rl_bracketed_read_key ();
|
||||
if (c < 0)
|
||||
return -1;
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
c = _rl_read_mbstring (c, mb, mlen);
|
||||
else
|
||||
#endif
|
||||
mb[0] = c;
|
||||
mb[mlen] = '\0'; /* just in case */
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* A special paste command for Windows users. */
|
||||
#if defined (_WIN32)
|
||||
#include <windows.h>
|
||||
|
||||
+95
-11
@@ -1,6 +1,6 @@
|
||||
/* mbutil.c -- readline multibyte character utility functions */
|
||||
|
||||
/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -86,7 +86,7 @@ int _rl_utf8locale = 0;
|
||||
static int
|
||||
_rl_utf8_mblen (const char *s, size_t n)
|
||||
{
|
||||
unsigned char c, c1;
|
||||
unsigned char c, c1, c2, c3;
|
||||
|
||||
if (s == 0)
|
||||
return (0); /* no shift states */
|
||||
@@ -101,25 +101,46 @@ _rl_utf8_mblen (const char *s, size_t n)
|
||||
c1 = (unsigned char)s[1];
|
||||
if (c < 0xe0)
|
||||
{
|
||||
if (n >= 2 && (s[1] ^ 0x80) < 0x40)
|
||||
if (n == 1)
|
||||
return -2;
|
||||
if (n >= 2 && (c1 ^ 0x80) < 0x40)
|
||||
return 2;
|
||||
}
|
||||
else if (c < 0xf0)
|
||||
{
|
||||
if (n >= 3
|
||||
&& (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
if (n == 1)
|
||||
return -2;
|
||||
if ((c1 ^ 0x80) < 0x40
|
||||
&& (c >= 0xe1 || c1 >= 0xa0)
|
||||
&& (c != 0xed || c1 < 0xa0))
|
||||
return 3;
|
||||
{
|
||||
if (n == 2)
|
||||
return -2;
|
||||
c2 = (unsigned char)s[2];
|
||||
if ((c2 ^ 0x80) < 0x40)
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf8)
|
||||
else if (c < 0xf4)
|
||||
{
|
||||
if (n >= 4
|
||||
&& (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40
|
||||
if (n == 1)
|
||||
return -2;
|
||||
if (((c1 ^ 0x80) < 0x40)
|
||||
&& (c >= 0xf1 || c1 >= 0x90)
|
||||
&& (c < 0xf4 || (c == 0xf4 && c1 < 0x90)))
|
||||
return 4;
|
||||
{
|
||||
if (n == 2)
|
||||
return -2;
|
||||
c2 = (unsigned char)s[2];
|
||||
if ((c2 ^ 0x80) < 0x40)
|
||||
{
|
||||
if (n == 3)
|
||||
return -2;
|
||||
c3 = (unsigned char)s[3];
|
||||
if ((c3 ^ 0x80) < 0x40)
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* invalid or incomplete multibyte character */
|
||||
@@ -206,6 +227,66 @@ _rl_find_next_mbchar_internal (char *string, int seed, int count, int find_non_z
|
||||
return point;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_rl_test_nonzero (char *string, int ind, int len)
|
||||
{
|
||||
size_t tmp;
|
||||
wchar_t wc;
|
||||
mbstate_t ps;
|
||||
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
tmp = mbrtowc (&wc, string + ind, len - ind, &ps);
|
||||
/* treat invalid multibyte sequences as non-zero-width */
|
||||
return (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp) || WCWIDTH (wc) > 0);
|
||||
}
|
||||
|
||||
/* experimental -- needs to handle zero-width characters better */
|
||||
static int
|
||||
_rl_find_prev_utf8char (char *string, int seed, int find_non_zero)
|
||||
{
|
||||
char *s;
|
||||
unsigned char b;
|
||||
int save, prev;
|
||||
size_t len;
|
||||
|
||||
if (find_non_zero)
|
||||
len = RL_STRLEN (string);
|
||||
|
||||
prev = seed - 1;
|
||||
while (prev >= 0)
|
||||
{
|
||||
b = (unsigned char)string[prev];
|
||||
if (UTF8_SINGLEBYTE (b))
|
||||
return (prev);
|
||||
|
||||
save = prev;
|
||||
|
||||
/* Move back until we're not in the middle of a multibyte char */
|
||||
if (UTF8_MBCHAR (b))
|
||||
{
|
||||
while (prev > 0 && (b = (unsigned char)string[--prev]) && UTF8_MBCHAR (b))
|
||||
;
|
||||
}
|
||||
|
||||
if (UTF8_MBFIRSTCHAR (b))
|
||||
{
|
||||
if (find_non_zero)
|
||||
{
|
||||
if (_rl_test_nonzero (string, prev, len))
|
||||
return (prev);
|
||||
else /* valid but WCWIDTH (wc) == 0 */
|
||||
prev = prev - 1;
|
||||
}
|
||||
else
|
||||
return (prev);
|
||||
}
|
||||
else
|
||||
return (save); /* invalid utf-8 multibyte sequence */
|
||||
}
|
||||
|
||||
return ((prev < 0) ? 0 : prev);
|
||||
}
|
||||
|
||||
/*static*/ int
|
||||
_rl_find_prev_mbchar_internal (char *string, int seed, int find_non_zero)
|
||||
{
|
||||
@@ -214,6 +295,9 @@ _rl_find_prev_mbchar_internal (char *string, int seed, int find_non_zero)
|
||||
size_t tmp;
|
||||
wchar_t wc;
|
||||
|
||||
if (_rl_utf8locale)
|
||||
return (_rl_find_prev_utf8char (string, seed, find_non_zero));
|
||||
|
||||
memset(&ps, 0, sizeof(mbstate_t));
|
||||
length = strlen(string);
|
||||
|
||||
|
||||
+58
-5
@@ -1,6 +1,6 @@
|
||||
/* misc.c -- miscellaneous bindable readline functions. */
|
||||
|
||||
/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -138,9 +138,7 @@ _rl_arg_dispatch (_rl_arg_cxt cxt, int c)
|
||||
}
|
||||
else
|
||||
{
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
key = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
key = _rl_bracketed_read_key ();
|
||||
rl_restore_prompt ();
|
||||
rl_clear_message ();
|
||||
RL_UNSETSTATE(RL_STATE_NUMERICARG);
|
||||
@@ -435,7 +433,7 @@ rl_replace_from_history (HIST_ENTRY *entry, int flags)
|
||||
intended to be called while actively editing, and the current line is
|
||||
not assumed to have been added to the history list. */
|
||||
void
|
||||
_rl_revert_all_lines (void)
|
||||
_rl_revert_previous_lines (void)
|
||||
{
|
||||
int hpos;
|
||||
HIST_ENTRY *entry;
|
||||
@@ -479,6 +477,19 @@ _rl_revert_all_lines (void)
|
||||
xfree (lbuf);
|
||||
}
|
||||
|
||||
/* Revert all lines in the history by making sure we are at the end of the
|
||||
history before calling _rl_revert_previous_lines() */
|
||||
void
|
||||
_rl_revert_all_lines (void)
|
||||
{
|
||||
int pos;
|
||||
|
||||
pos = where_history ();
|
||||
using_history ();
|
||||
_rl_revert_previous_lines ();
|
||||
history_set_pos (pos);
|
||||
}
|
||||
|
||||
/* Free the history list, including private readline data and take care
|
||||
of pointer aliases to history data. Resets rl_undo_list if it points
|
||||
to an UNDO_LIST * saved as some history entry's data member. This
|
||||
@@ -626,6 +637,48 @@ rl_get_previous_history (int count, int key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The equivalent of the Korn shell C-o operate-and-get-next-history-line
|
||||
editing command. */
|
||||
|
||||
/* This could stand to be global to the readline library */
|
||||
static rl_hook_func_t *_rl_saved_internal_startup_hook = 0;
|
||||
static int saved_history_logical_offset = -1;
|
||||
|
||||
#define HISTORY_FULL() (history_is_stifled () && history_length >= history_max_entries)
|
||||
|
||||
static int
|
||||
set_saved_history ()
|
||||
{
|
||||
int absolute_offset, count;
|
||||
|
||||
if (saved_history_logical_offset >= 0)
|
||||
{
|
||||
absolute_offset = saved_history_logical_offset - history_base;
|
||||
count = where_history () - absolute_offset;
|
||||
rl_get_previous_history (count, 0);
|
||||
}
|
||||
saved_history_logical_offset = -1;
|
||||
_rl_internal_startup_hook = _rl_saved_internal_startup_hook;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_operate_and_get_next (count, c)
|
||||
int count, c;
|
||||
{
|
||||
/* Accept the current line. */
|
||||
rl_newline (1, c);
|
||||
|
||||
saved_history_logical_offset = rl_explicit_arg ? count : where_history () + history_base + 1;
|
||||
|
||||
|
||||
_rl_saved_internal_startup_hook = _rl_internal_startup_hook;
|
||||
_rl_internal_startup_hook = set_saved_history;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Editing Modes */
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
# define D_NAMLEN(d) ((d)->d_namlen)
|
||||
#endif /* !HAVE_DIRENT_H */
|
||||
|
||||
/* The bash code fairly consistenly uses d_fileno; make sure it's available */
|
||||
/* The bash code fairly consistently uses d_fileno; make sure it's available */
|
||||
#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO)
|
||||
# define d_fileno d_ino
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* posixstat.h -- Posix stat(2) definitions for systems that
|
||||
don't have them. */
|
||||
|
||||
/* Copyright (C) 1987,1991 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -132,6 +132,26 @@
|
||||
# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
|
||||
# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
|
||||
# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
|
||||
#else /* !S_IRWXU */
|
||||
/* S_IRWXU is defined, but "group" and "other" bits might not be
|
||||
(happens in certain versions of MinGW). */
|
||||
# if !defined (S_IRGRP)
|
||||
# define S_IRGRP (S_IREAD >> 3) /* read, group */
|
||||
# define S_IWGRP (S_IWRITE >> 3) /* write, group */
|
||||
# define S_IXGRP (S_IEXEC >> 3) /* execute, group */
|
||||
# endif /* !S_IRGRP */
|
||||
|
||||
# if !defined (S_IROTH)
|
||||
# define S_IROTH (S_IREAD >> 6) /* read, other */
|
||||
# define S_IWOTH (S_IWRITE >> 6) /* write, other */
|
||||
# define S_IXOTH (S_IEXEC >> 6) /* execute, other */
|
||||
# endif /* !S_IROTH */
|
||||
# if !defined (S_IRWXG)
|
||||
# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
|
||||
# endif
|
||||
# if !defined (S_IRWXO)
|
||||
# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
|
||||
# endif
|
||||
#endif /* !S_IRWXU */
|
||||
|
||||
/* These are non-standard, but are used in builtins.c$symbolic_umask() */
|
||||
|
||||
+91
-7
@@ -1,7 +1,7 @@
|
||||
/* readline.c -- a general facility for reading lines of input
|
||||
with emacs style editing and completion. */
|
||||
|
||||
/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -73,11 +73,11 @@ extern int errno;
|
||||
#include "xmalloc.h"
|
||||
|
||||
#ifndef RL_LIBRARY_VERSION
|
||||
# define RL_LIBRARY_VERSION "5.1"
|
||||
# define RL_LIBRARY_VERSION "8.0"
|
||||
#endif
|
||||
|
||||
#ifndef RL_READLINE_VERSION
|
||||
# define RL_READLINE_VERSION 0x0501
|
||||
# define RL_READLINE_VERSION 0x0800
|
||||
#endif
|
||||
|
||||
extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
|
||||
@@ -199,6 +199,10 @@ int rl_key_sequence_length = 0;
|
||||
before readline_internal_setup () prints the first prompt. */
|
||||
rl_hook_func_t *rl_startup_hook = (rl_hook_func_t *)NULL;
|
||||
|
||||
/* Any readline function can set this and have it run just before the user's
|
||||
rl_startup_hook. */
|
||||
rl_hook_func_t *_rl_internal_startup_hook = (rl_hook_func_t *)NULL;
|
||||
|
||||
/* If non-zero, this is the address of a function to call just before
|
||||
readline_internal_setup () returns and readline_internal starts
|
||||
reading input characters. */
|
||||
@@ -258,6 +262,9 @@ int rl_executing_key;
|
||||
char *rl_executing_keyseq = 0;
|
||||
int _rl_executing_keyseq_size = 0;
|
||||
|
||||
struct _rl_cmd _rl_pending_command;
|
||||
struct _rl_cmd *_rl_command_to_execute = (struct _rl_cmd *)NULL;
|
||||
|
||||
/* Timeout (specified in milliseconds) when reading characters making up an
|
||||
ambiguous multiple-key sequence */
|
||||
int _rl_keyseq_timeout = 500;
|
||||
@@ -314,7 +321,8 @@ int _rl_show_mode_in_prompt = 0;
|
||||
/* Non-zero means to attempt to put the terminal in `bracketed paste mode',
|
||||
where it will prefix pasted text with an escape sequence and send
|
||||
another to mark the end of the paste. */
|
||||
int _rl_enable_bracketed_paste = 0;
|
||||
int _rl_enable_bracketed_paste = BRACKETED_PASTE_DEFAULT;
|
||||
int _rl_enable_active_region = BRACKETED_PASTE_DEFAULT;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
@@ -417,6 +425,11 @@ readline_internal_setup (void)
|
||||
if (rl_startup_hook)
|
||||
(*rl_startup_hook) ();
|
||||
|
||||
if (_rl_internal_startup_hook)
|
||||
(*_rl_internal_startup_hook) ();
|
||||
|
||||
rl_deactivate_mark ();
|
||||
|
||||
#if defined (VI_MODE)
|
||||
if (rl_editing_mode == vi_mode)
|
||||
rl_vi_insertion_mode (1, 'i'); /* don't want to reset last */
|
||||
@@ -632,12 +645,34 @@ readline_internal_charloop (void)
|
||||
r = _rl_dispatch ((unsigned char)c, _rl_keymap);
|
||||
RL_CHECK_SIGNALS ();
|
||||
|
||||
if (_rl_command_to_execute)
|
||||
{
|
||||
(*rl_redisplay_function) ();
|
||||
|
||||
rl_executing_keymap = _rl_command_to_execute->map;
|
||||
rl_executing_key = _rl_command_to_execute->key;
|
||||
|
||||
rl_dispatching = 1;
|
||||
RL_SETSTATE(RL_STATE_DISPATCHING);
|
||||
r = (*(_rl_command_to_execute->func)) (_rl_command_to_execute->count, _rl_command_to_execute->key);
|
||||
_rl_command_to_execute = 0;
|
||||
RL_UNSETSTATE(RL_STATE_DISPATCHING);
|
||||
rl_dispatching = 0;
|
||||
|
||||
RL_CHECK_SIGNALS ();
|
||||
}
|
||||
|
||||
/* If there was no change in _rl_last_command_was_kill, then no kill
|
||||
has taken place. Note that if input is pending we are reading
|
||||
a prefix command, so nothing has changed yet. */
|
||||
if (rl_pending_input == 0 && lk == _rl_last_command_was_kill)
|
||||
_rl_last_command_was_kill = 0;
|
||||
|
||||
if (_rl_keep_mark_active)
|
||||
_rl_keep_mark_active = 0;
|
||||
else if (rl_mark_active_p ())
|
||||
rl_deactivate_mark ();
|
||||
|
||||
_rl_internal_char_cleanup ();
|
||||
|
||||
#if defined (READLINE_CALLBACKS)
|
||||
@@ -856,7 +891,11 @@ _rl_dispatch_subseq (register int key, Keymap map, int got_subseq)
|
||||
/* If we have input pending, then the last command was a prefix
|
||||
command. Don't change the state of rl_last_func. Otherwise,
|
||||
remember the last command executed in this variable. */
|
||||
#if defined (VI_MODE)
|
||||
if (rl_pending_input == 0 && map[key].function != rl_digit_argument && map[key].function != rl_vi_arg_digit)
|
||||
#else
|
||||
if (rl_pending_input == 0 && map[key].function != rl_digit_argument)
|
||||
#endif
|
||||
rl_last_func = map[key].function;
|
||||
|
||||
RL_CHECK_SIGNALS ();
|
||||
@@ -870,6 +909,8 @@ _rl_dispatch_subseq (register int key, Keymap map, int got_subseq)
|
||||
_rl_prev_macro_key ();
|
||||
else
|
||||
_rl_unget_char (key);
|
||||
if (rl_key_sequence_length > 0)
|
||||
rl_executing_keyseq[--rl_key_sequence_length] = '\0';
|
||||
return -2;
|
||||
}
|
||||
else if (got_subseq)
|
||||
@@ -882,6 +923,8 @@ _rl_dispatch_subseq (register int key, Keymap map, int got_subseq)
|
||||
_rl_prev_macro_key ();
|
||||
else
|
||||
_rl_unget_char (key);
|
||||
if (rl_key_sequence_length > 0)
|
||||
rl_executing_keyseq[--rl_key_sequence_length] = '\0';
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
@@ -974,7 +1017,11 @@ _rl_dispatch_subseq (register int key, Keymap map, int got_subseq)
|
||||
_rl_pushed_input_available () == 0 &&
|
||||
_rl_dispatching_keymap[ANYOTHERKEY].function &&
|
||||
_rl_input_queued (_rl_keyseq_timeout*1000) == 0)
|
||||
return (_rl_subseq_result (-2, map, key, got_subseq));
|
||||
{
|
||||
if (rl_key_sequence_length > 0)
|
||||
rl_executing_keyseq[--rl_key_sequence_length] = '\0';
|
||||
return (_rl_subseq_result (-2, map, key, got_subseq));
|
||||
}
|
||||
|
||||
newkey = _rl_subseq_getchar (key);
|
||||
if (newkey < 0)
|
||||
@@ -1065,6 +1112,8 @@ _rl_subseq_result (int r, Keymap map, int key, int got_subseq)
|
||||
_rl_prev_macro_key ();
|
||||
else
|
||||
_rl_unget_char (key);
|
||||
if (rl_key_sequence_length > 0)
|
||||
rl_executing_keyseq[--rl_key_sequence_length] = '\0';
|
||||
_rl_dispatching_keymap = map;
|
||||
return -2;
|
||||
}
|
||||
@@ -1075,6 +1124,8 @@ _rl_subseq_result (int r, Keymap map, int key, int got_subseq)
|
||||
_rl_prev_macro_key ();
|
||||
else
|
||||
_rl_unget_char (key);
|
||||
if (rl_key_sequence_length > 0)
|
||||
rl_executing_keyseq[--rl_key_sequence_length] = '\0';
|
||||
_rl_dispatching_keymap = map;
|
||||
return -1;
|
||||
}
|
||||
@@ -1241,7 +1292,7 @@ readline_initialize_everything (void)
|
||||
|
||||
rl_executing_keyseq = malloc (_rl_executing_keyseq_size = 16);
|
||||
if (rl_executing_keyseq)
|
||||
rl_executing_keyseq[0] = '\0';
|
||||
rl_executing_keyseq[rl_key_sequence_length = 0] = '\0';
|
||||
}
|
||||
|
||||
/* If this system allows us to look at the values of the regular
|
||||
@@ -1356,9 +1407,12 @@ bind_bracketed_paste_prefix (void)
|
||||
|
||||
_rl_keymap = emacs_standard_keymap;
|
||||
rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_bracketed_paste_begin);
|
||||
|
||||
|
||||
#if defined (VI_MODE)
|
||||
_rl_keymap = vi_insertion_keymap;
|
||||
rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_bracketed_paste_begin);
|
||||
/* XXX - is there a reason to do this in the vi command keymap? */
|
||||
#endif
|
||||
|
||||
_rl_keymap = xkeymap;
|
||||
}
|
||||
@@ -1446,5 +1500,35 @@ rl_restore_state (struct readline_state *sp)
|
||||
rl_attempted_completion_function = sp->attemptfunc;
|
||||
rl_completer_word_break_characters = sp->wordbreakchars;
|
||||
|
||||
rl_deactivate_mark ();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Functions to manage the string that is the current key sequence. */
|
||||
|
||||
void
|
||||
_rl_init_executing_keyseq (void)
|
||||
{
|
||||
rl_executing_keyseq[rl_key_sequence_length = 0] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
_rl_term_executing_keyseq (void)
|
||||
{
|
||||
rl_executing_keyseq[rl_key_sequence_length] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
_rl_end_executing_keyseq (void)
|
||||
{
|
||||
if (rl_key_sequence_length > 0)
|
||||
rl_executing_keyseq[--rl_key_sequence_length] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
_rl_add_executing_keyseq (int key)
|
||||
{
|
||||
RESIZE_KEYSEQ_BUFFER ();
|
||||
rl_executing_keyseq[rl_key_sequence_length++] = key;
|
||||
}
|
||||
|
||||
+13
-3
@@ -1,6 +1,6 @@
|
||||
/* Readline.h -- the names of functions callable from within readline. */
|
||||
|
||||
/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -39,9 +39,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Hex-encoded Readline version number. */
|
||||
#define RL_READLINE_VERSION 0x0800 /* Readline 8.0 */
|
||||
#define RL_READLINE_VERSION 0x0801 /* Readline 8.0 */
|
||||
#define RL_VERSION_MAJOR 8
|
||||
#define RL_VERSION_MINOR 0
|
||||
#define RL_VERSION_MINOR 1
|
||||
|
||||
/* Readline data structures. */
|
||||
|
||||
@@ -95,6 +95,7 @@ extern int rl_forward_word PARAMS((int, int));
|
||||
extern int rl_backward_word PARAMS((int, int));
|
||||
extern int rl_refresh_line PARAMS((int, int));
|
||||
extern int rl_clear_screen PARAMS((int, int));
|
||||
extern int rl_clear_display PARAMS((int, int));
|
||||
extern int rl_skip_csi_sequence PARAMS((int, int));
|
||||
extern int rl_arrow_keys PARAMS((int, int));
|
||||
|
||||
@@ -132,6 +133,7 @@ extern int rl_beginning_of_history PARAMS((int, int));
|
||||
extern int rl_end_of_history PARAMS((int, int));
|
||||
extern int rl_get_next_history PARAMS((int, int));
|
||||
extern int rl_get_previous_history PARAMS((int, int));
|
||||
extern int rl_operate_and_get_next PARAMS((int, int));
|
||||
|
||||
/* Bindable commands for managing the mark and region. */
|
||||
extern int rl_set_mark PARAMS((int, int));
|
||||
@@ -392,6 +394,14 @@ extern int rl_clear_message PARAMS((void));
|
||||
extern int rl_reset_line_state PARAMS((void));
|
||||
extern int rl_crlf PARAMS((void));
|
||||
|
||||
/* Functions to manage the mark and region, especially the notion of an
|
||||
active mark and an active region. */
|
||||
extern void rl_keep_mark_active PARAMS((void));
|
||||
|
||||
extern void rl_activate_mark PARAMS((void));
|
||||
extern void rl_deactivate_mark PARAMS((void));
|
||||
extern int rl_mark_active_p PARAMS((void));
|
||||
|
||||
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
|
||||
extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
|
||||
#else
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
/* check multibyte capability for I18N code */
|
||||
/************************************************/
|
||||
|
||||
/* For platforms which support the ISO C amendement 1 functionality we
|
||||
/* For platforms which support the ISO C amendment 1 functionality we
|
||||
support user defined character classes. */
|
||||
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
|
||||
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) && defined (HAVE_LOCALE_H)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* rlprivate.h -- functions and variables global to the readline library,
|
||||
but not intended for use by applications. */
|
||||
|
||||
/* Copyright (C) 1999-2015 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -65,7 +65,8 @@
|
||||
#define SF_FOUND 0x02
|
||||
#define SF_FAILED 0x04
|
||||
#define SF_CHGKMAP 0x08
|
||||
#define SF_PATTERN 0x10 /* unused so far */
|
||||
#define SF_PATTERN 0x10
|
||||
#define SF_NOCASE 0x20 /* unused so far */
|
||||
|
||||
typedef struct __rl_search_context
|
||||
{
|
||||
@@ -109,6 +110,15 @@ typedef struct __rl_search_context
|
||||
char *search_terminators;
|
||||
} _rl_search_cxt;
|
||||
|
||||
struct _rl_cmd {
|
||||
Keymap map;
|
||||
int count;
|
||||
int key;
|
||||
rl_command_func_t *func;
|
||||
};
|
||||
extern struct _rl_cmd _rl_pending_command;
|
||||
extern struct _rl_cmd *_rl_command_to_execute;
|
||||
|
||||
/* Callback data for reading numeric arguments */
|
||||
#define NUM_SAWMINUS 0x01
|
||||
#define NUM_SAWDIGITS 0x02
|
||||
@@ -267,23 +277,25 @@ extern void _rl_free_match_list PARAMS((char **));
|
||||
/* display.c */
|
||||
extern char *_rl_strip_prompt PARAMS((char *));
|
||||
extern void _rl_reset_prompt PARAMS((void));
|
||||
extern void _rl_move_cursor_relative PARAMS((int, const char *));
|
||||
extern void _rl_move_vert PARAMS((int));
|
||||
extern void _rl_save_prompt PARAMS((void));
|
||||
extern void _rl_restore_prompt PARAMS((void));
|
||||
extern char *_rl_make_prompt_for_search PARAMS((int));
|
||||
extern void _rl_erase_at_end_of_line PARAMS((int));
|
||||
extern void _rl_clear_to_eol PARAMS((int));
|
||||
extern void _rl_clear_screen PARAMS((void));
|
||||
extern void _rl_clear_screen PARAMS((int));
|
||||
extern void _rl_update_final PARAMS((void));
|
||||
extern void _rl_optimize_redisplay PARAMS((void));
|
||||
extern void _rl_redisplay_after_sigwinch PARAMS((void));
|
||||
extern void _rl_clean_up_for_exit PARAMS((void));
|
||||
extern void _rl_erase_entire_line PARAMS((void));
|
||||
extern int _rl_current_display_line PARAMS((void));
|
||||
extern void _rl_refresh_line PARAMS((void));
|
||||
|
||||
/* input.c */
|
||||
extern int _rl_any_typein PARAMS((void));
|
||||
extern int _rl_input_available PARAMS((void));
|
||||
extern int _rl_nchars_available PARAMS((void));
|
||||
extern int _rl_input_queued PARAMS((int));
|
||||
extern void _rl_insert_typein PARAMS((int));
|
||||
extern int _rl_unget_char PARAMS((int));
|
||||
@@ -300,6 +312,10 @@ extern int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
|
||||
extern int _rl_search_getchar PARAMS((_rl_search_cxt *));
|
||||
|
||||
/* kill.c */
|
||||
#ifndef BRACKETED_PASTE_DEFAULT
|
||||
# define BRACKETED_PASTE_DEFAULT 1 /* XXX - for now */
|
||||
#endif
|
||||
|
||||
#define BRACK_PASTE_PREF "\033[200~"
|
||||
#define BRACK_PASTE_SUFF "\033[201~"
|
||||
|
||||
@@ -309,7 +325,10 @@ extern int _rl_search_getchar PARAMS((_rl_search_cxt *));
|
||||
#define BRACK_PASTE_INIT "\033[?2004h"
|
||||
#define BRACK_PASTE_FINI "\033[?2004l\r"
|
||||
|
||||
extern int _rl_read_bracketed_paste_prefix PARAMS((int));
|
||||
extern char *_rl_bracketed_text PARAMS((size_t *));
|
||||
extern int _rl_bracketed_read_key PARAMS((void));
|
||||
extern int _rl_bracketed_read_mbstring PARAMS((char *, int));
|
||||
|
||||
/* macro.c */
|
||||
extern void _rl_with_macro_input PARAMS((char *));
|
||||
@@ -332,6 +351,7 @@ extern void _rl_start_using_history PARAMS((void));
|
||||
extern int _rl_free_saved_history_line PARAMS((void));
|
||||
extern void _rl_set_insert_mode PARAMS((int, int));
|
||||
|
||||
extern void _rl_revert_previous_lines PARAMS((void));
|
||||
extern void _rl_revert_all_lines PARAMS((void));
|
||||
|
||||
/* nls.c */
|
||||
@@ -348,6 +368,11 @@ extern int _rl_dispatch PARAMS((int, Keymap));
|
||||
extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
|
||||
extern void _rl_internal_char_cleanup PARAMS((void));
|
||||
|
||||
extern void _rl_init_executing_keyseq PARAMS((void));
|
||||
extern void _rl_term_executing_keyseq PARAMS((void));
|
||||
extern void _rl_end_executing_keyseq PARAMS((void));
|
||||
extern void _rl_add_executing_keyseq PARAMS((int));
|
||||
|
||||
/* rltty.c */
|
||||
extern int _rl_disable_tty_signals PARAMS((void));
|
||||
extern int _rl_restore_tty_signals PARAMS((void));
|
||||
@@ -373,15 +398,19 @@ extern void _rl_output_character_function PARAMS((int));
|
||||
#else
|
||||
extern int _rl_output_character_function PARAMS((int));
|
||||
#endif
|
||||
extern void _rl_cr PARAMS((void));
|
||||
extern void _rl_output_some_chars PARAMS((const char *, int));
|
||||
extern int _rl_backspace PARAMS((int));
|
||||
extern void _rl_enable_meta_key PARAMS((void));
|
||||
extern void _rl_disable_meta_key PARAMS((void));
|
||||
extern void _rl_control_keypad PARAMS((int));
|
||||
extern void _rl_set_cursor PARAMS((int, int));
|
||||
extern void _rl_standout_on PARAMS((void));
|
||||
extern void _rl_standout_off PARAMS((void));
|
||||
|
||||
/* text.c */
|
||||
extern void _rl_fix_point PARAMS((int));
|
||||
extern void _rl_fix_mark PARAMS((void));
|
||||
extern int _rl_replace_text PARAMS((const char *, int, int));
|
||||
extern int _rl_forward_char_internal PARAMS((int));
|
||||
extern int _rl_backward_char_internal PARAMS((int));
|
||||
@@ -507,6 +536,7 @@ extern int _rl_revert_all_at_newline;
|
||||
extern int _rl_echo_control_chars;
|
||||
extern int _rl_show_mode_in_prompt;
|
||||
extern int _rl_enable_bracketed_paste;
|
||||
extern int _rl_enable_active_region;
|
||||
extern char *_rl_comment_begin;
|
||||
extern unsigned char _rl_parsing_conditionalized_out;
|
||||
extern Keymap _rl_keymap;
|
||||
@@ -521,11 +551,12 @@ extern int _rl_keyseq_timeout;
|
||||
|
||||
extern int _rl_executing_keyseq_size;
|
||||
|
||||
extern rl_hook_func_t *_rl_internal_startup_hook;
|
||||
|
||||
/* search.c */
|
||||
extern _rl_search_cxt *_rl_nscxt;
|
||||
|
||||
/* signals.c */
|
||||
extern int _rl_interrupt_immediately;
|
||||
extern int volatile _rl_caught_signal;
|
||||
|
||||
extern _rl_sigcleanup_func_t *_rl_sigcleanup;
|
||||
@@ -560,6 +591,7 @@ extern int _rl_term_autowrap;
|
||||
|
||||
/* text.c */
|
||||
extern int _rl_optimize_typeahead;
|
||||
extern int _rl_keep_mark_active;
|
||||
|
||||
/* undo.c */
|
||||
extern int _rl_doing_an_undo;
|
||||
|
||||
+42
-5
@@ -1,6 +1,6 @@
|
||||
/* search.c - code for non-incremental searching in emacs and vi modes. */
|
||||
|
||||
/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1992-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -159,7 +159,7 @@ noninc_search_from_pos (char *string, int pos, int dir, int flags, int *ncp)
|
||||
static int
|
||||
noninc_dosearch (char *string, int dir, int flags)
|
||||
{
|
||||
int oldpos, pos;
|
||||
int oldpos, pos, ind;
|
||||
HIST_ENTRY *entry;
|
||||
|
||||
if (string == 0 || *string == '\0' || noninc_history_pos < 0)
|
||||
@@ -168,7 +168,7 @@ noninc_dosearch (char *string, int dir, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir, flags, (int *)0);
|
||||
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir, flags, &ind);
|
||||
if (pos == -1)
|
||||
{
|
||||
/* Search failed, current history position unchanged. */
|
||||
@@ -192,8 +192,19 @@ noninc_dosearch (char *string, int dir, int flags)
|
||||
|
||||
make_history_line_current (entry);
|
||||
|
||||
rl_point = 0;
|
||||
rl_mark = rl_end;
|
||||
if (_rl_enable_active_region && ((flags & SF_PATTERN) == 0) && ind > 0 && ind < rl_end)
|
||||
{
|
||||
rl_point = ind;
|
||||
rl_mark = ind + strlen (string);
|
||||
if (rl_mark > rl_end)
|
||||
rl_mark = rl_end; /* can't happen? */
|
||||
rl_activate_mark ();
|
||||
}
|
||||
else
|
||||
{
|
||||
rl_point = 0;
|
||||
rl_mark = rl_end;
|
||||
}
|
||||
|
||||
rl_clear_message ();
|
||||
return 1;
|
||||
@@ -256,6 +267,7 @@ _rl_nsearch_abort (_rl_search_cxt *cxt)
|
||||
rl_clear_message ();
|
||||
rl_point = cxt->save_point;
|
||||
rl_mark = cxt->save_mark;
|
||||
_rl_fix_point (1);
|
||||
rl_restore_prompt ();
|
||||
|
||||
RL_UNSETSTATE (RL_STATE_NSEARCH);
|
||||
@@ -267,6 +279,8 @@ _rl_nsearch_abort (_rl_search_cxt *cxt)
|
||||
static int
|
||||
_rl_nsearch_dispatch (_rl_search_cxt *cxt, int c)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (c < 0)
|
||||
c = CTRL ('C');
|
||||
|
||||
@@ -300,6 +314,28 @@ _rl_nsearch_dispatch (_rl_search_cxt *cxt, int c)
|
||||
_rl_nsearch_abort (cxt);
|
||||
return -1;
|
||||
|
||||
case ESC:
|
||||
/* XXX - experimental code to allow users to bracketed-paste into the
|
||||
search string. Similar code is in isearch.c:_rl_isearch_dispatch().
|
||||
The difference here is that the bracketed paste sometimes doesn't
|
||||
paste everything, so checking for the prefix and the suffix in the
|
||||
input queue doesn't work well. We just have to check to see if the
|
||||
number of chars in the input queue is enough for the bracketed paste
|
||||
prefix and hope for the best. */
|
||||
if (_rl_enable_bracketed_paste && ((n = _rl_nchars_available ()) >= (BRACK_PASTE_SLEN-1)))
|
||||
{
|
||||
if (_rl_read_bracketed_paste_prefix (c) == 1)
|
||||
rl_bracketed_paste_begin (1, c);
|
||||
else
|
||||
{
|
||||
c = rl_read_key (); /* get the ESC that got pushed back */
|
||||
_rl_insert_char (1, c);
|
||||
}
|
||||
}
|
||||
else
|
||||
_rl_insert_char (1, c);
|
||||
break;
|
||||
|
||||
default:
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
@@ -311,6 +347,7 @@ _rl_nsearch_dispatch (_rl_search_cxt *cxt, int c)
|
||||
}
|
||||
|
||||
(*rl_redisplay_function) ();
|
||||
rl_deactivate_mark ();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+62
-25
@@ -99,7 +99,6 @@ int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
|
||||
#endif
|
||||
|
||||
/* Private variables. */
|
||||
int _rl_interrupt_immediately = 0;
|
||||
int volatile _rl_caught_signal = 0; /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
|
||||
|
||||
/* If non-zero, print characters corresponding to received signals as long as
|
||||
@@ -136,7 +135,7 @@ void *_rl_sigcleanarg;
|
||||
|
||||
/* Readline signal handler functions. */
|
||||
|
||||
/* Called from RL_CHECK_SIGNALS() macro */
|
||||
/* Called from RL_CHECK_SIGNALS() macro to run signal handling code. */
|
||||
RETSIGTYPE
|
||||
_rl_signal_handler (int sig)
|
||||
{
|
||||
@@ -145,6 +144,8 @@ _rl_signal_handler (int sig)
|
||||
#if defined (SIGWINCH)
|
||||
if (sig == SIGWINCH)
|
||||
{
|
||||
RL_SETSTATE(RL_STATE_SIGHANDLER);
|
||||
|
||||
rl_resize_terminal ();
|
||||
/* XXX - experimental for now */
|
||||
/* Call a signal hook because though we called the original signal handler
|
||||
@@ -152,6 +153,8 @@ _rl_signal_handler (int sig)
|
||||
ourselves. */
|
||||
if (rl_signal_event_hook)
|
||||
(*rl_signal_event_hook) ();
|
||||
|
||||
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -163,22 +166,20 @@ _rl_signal_handler (int sig)
|
||||
static RETSIGTYPE
|
||||
rl_signal_handler (int sig)
|
||||
{
|
||||
if (_rl_interrupt_immediately)
|
||||
{
|
||||
_rl_interrupt_immediately = 0;
|
||||
_rl_handle_signal (sig);
|
||||
}
|
||||
else
|
||||
_rl_caught_signal = sig;
|
||||
|
||||
_rl_caught_signal = sig;
|
||||
SIGHANDLER_RETURN;
|
||||
}
|
||||
|
||||
/* This is called to handle a signal when it is safe to do so (out of the
|
||||
signal handler execution path). Called by _rl_signal_handler for all the
|
||||
signals readline catches except SIGWINCH. */
|
||||
static RETSIGTYPE
|
||||
_rl_handle_signal (int sig)
|
||||
{
|
||||
int block_sig;
|
||||
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
sigset_t set;
|
||||
sigset_t set, oset;
|
||||
#else /* !HAVE_POSIX_SIGNALS */
|
||||
# if defined (HAVE_BSD_SIGNALS)
|
||||
long omask;
|
||||
@@ -208,7 +209,16 @@ _rl_handle_signal (int sig)
|
||||
_rl_sigcleanup = 0;
|
||||
_rl_sigcleanarg = 0;
|
||||
}
|
||||
|
||||
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
/* Get the current set of blocked signals. If we want to block a signal for
|
||||
the duration of the cleanup functions, make sure to add it to SET and
|
||||
set block_sig = 1 (see the SIGHUP case below). */
|
||||
block_sig = 0; /* sentinel to block signals with sigprocmask */
|
||||
sigemptyset (&set);
|
||||
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
|
||||
#endif
|
||||
|
||||
switch (sig)
|
||||
{
|
||||
case SIGINT:
|
||||
@@ -223,38 +233,60 @@ _rl_handle_signal (int sig)
|
||||
#if defined (SIGTSTP)
|
||||
case SIGTSTP:
|
||||
case SIGTTIN:
|
||||
case SIGTTOU:
|
||||
# if defined (HAVE_POSIX_SIGNALS)
|
||||
/* Block SIGTTOU so we can restore the terminal settings to something
|
||||
sane without stopping on SIGTTOU if we have been placed into the
|
||||
background. Even trying to get the current terminal pgrp with
|
||||
tcgetpgrp() will generate SIGTTOU, so we don't bother. Don't bother
|
||||
doing this if we've been stopped on SIGTTOU; it's aready too late. */
|
||||
sigemptyset (&set);
|
||||
tcgetpgrp() will generate SIGTTOU, so we don't bother. We still do
|
||||
this even if we've been stopped on SIGTTOU, since we handle signals
|
||||
when we have returned from the signal handler and the signal is no
|
||||
longer blocked. */
|
||||
sigaddset (&set, SIGTTOU);
|
||||
sigprocmask (SIG_BLOCK, &set, (sigset_t *)NULL);
|
||||
block_sig = 1;
|
||||
# endif
|
||||
case SIGTTOU:
|
||||
#endif /* SIGTSTP */
|
||||
case SIGTERM:
|
||||
/* Any signals that should be blocked during cleanup should go here. */
|
||||
#if defined (SIGHUP)
|
||||
case SIGHUP:
|
||||
# if defined (_AIX)
|
||||
if (block_sig == 0)
|
||||
{
|
||||
sigaddset (&set, sig);
|
||||
block_sig = 1;
|
||||
}
|
||||
# endif // _AIX
|
||||
#endif
|
||||
/* Signals that don't require blocking during cleanup should go here. */
|
||||
case SIGTERM:
|
||||
#if defined (SIGALRM)
|
||||
case SIGALRM:
|
||||
#endif
|
||||
#if defined (SIGQUIT)
|
||||
case SIGQUIT:
|
||||
#endif
|
||||
|
||||
if (block_sig)
|
||||
sigprocmask (SIG_BLOCK, &set, &oset);
|
||||
|
||||
rl_echo_signal_char (sig);
|
||||
rl_cleanup_after_signal ();
|
||||
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
# if defined (SIGTSTP)
|
||||
/* Unblock SIGTTOU blocked above */
|
||||
if (sig == SIGTTIN || sig == SIGTSTP)
|
||||
sigprocmask (SIG_UNBLOCK, &set, (sigset_t *)NULL);
|
||||
# endif
|
||||
/* At this point, the application's signal handler, if any, is the
|
||||
current handler. */
|
||||
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
/* Unblock any signal(s) blocked above */
|
||||
if (block_sig)
|
||||
sigprocmask (SIG_UNBLOCK, &oset, (sigset_t *)NULL);
|
||||
#endif
|
||||
|
||||
/* We don't have to bother unblocking the signal because we are not
|
||||
running in a signal handler context. */
|
||||
#if 0
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
/* Make sure this signal is not blocked when we resend it to the
|
||||
calling application. */
|
||||
sigemptyset (&set);
|
||||
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
|
||||
sigdelset (&set, sig);
|
||||
@@ -263,6 +295,7 @@ _rl_handle_signal (int sig)
|
||||
omask = sigblock (0);
|
||||
# endif /* HAVE_BSD_SIGNALS */
|
||||
#endif /* !HAVE_POSIX_SIGNALS */
|
||||
#endif
|
||||
|
||||
#if defined (__EMX__)
|
||||
signal (sig, SIG_ACK);
|
||||
@@ -274,7 +307,10 @@ _rl_handle_signal (int sig)
|
||||
raise (sig); /* assume we have raise */
|
||||
#endif
|
||||
|
||||
/* Let the signal that we just sent through. */
|
||||
/* We don't need to modify the signal mask now that this is not run in
|
||||
a signal handler context. */
|
||||
#if 0
|
||||
/* Let the signal that we just sent through if it is blocked. */
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
|
||||
#else /* !HAVE_POSIX_SIGNALS */
|
||||
@@ -282,6 +318,7 @@ _rl_handle_signal (int sig)
|
||||
sigsetmask (omask & ~(sigmask (sig)));
|
||||
# endif /* HAVE_BSD_SIGNALS */
|
||||
#endif /* !HAVE_POSIX_SIGNALS */
|
||||
#endif
|
||||
|
||||
rl_reset_after_signal ();
|
||||
}
|
||||
|
||||
+71
-5
@@ -152,6 +152,10 @@ static int term_has_meta;
|
||||
static char *_rl_term_mm;
|
||||
static char *_rl_term_mo;
|
||||
|
||||
/* The sequences to enter and exit standout mode. */
|
||||
static char *_rl_term_so;
|
||||
static char *_rl_term_se;
|
||||
|
||||
/* The key sequences output by the arrow keys, if this terminal has any. */
|
||||
static char *_rl_term_ku;
|
||||
static char *_rl_term_kd;
|
||||
@@ -177,6 +181,19 @@ static char *_rl_term_kI;
|
||||
static char *_rl_term_vs; /* very visible */
|
||||
static char *_rl_term_ve; /* normal */
|
||||
|
||||
/* It's not clear how HPUX is so broken here. */
|
||||
#ifdef TGETENT_BROKEN
|
||||
# define TGETENT_SUCCESS 0
|
||||
#else
|
||||
# define TGETENT_SUCCESS 1
|
||||
#endif
|
||||
#ifdef TGETFLAG_BROKEN
|
||||
# define TGETFLAG_SUCCESS 0
|
||||
#else
|
||||
# define TGETFLAG_SUCCESS 1
|
||||
#endif
|
||||
#define TGETFLAG(cap) (tgetflag (cap) == TGETFLAG_SUCCESS)
|
||||
|
||||
static void bind_termcap_arrow_keys PARAMS((Keymap));
|
||||
|
||||
/* Variables that hold the screen dimensions, used by the display code. */
|
||||
@@ -410,6 +427,8 @@ static const struct _tc_string tc_strings[] =
|
||||
{ "mo", &_rl_term_mo },
|
||||
{ "nd", &_rl_term_forward_char },
|
||||
{ "pc", &_rl_term_pc },
|
||||
{ "se", &_rl_term_se },
|
||||
{ "so", &_rl_term_so },
|
||||
{ "up", &_rl_term_up },
|
||||
{ "vb", &_rl_visible_bell },
|
||||
{ "vs", &_rl_term_vs },
|
||||
@@ -437,7 +456,7 @@ _rl_init_terminal_io (const char *terminal_name)
|
||||
{
|
||||
const char *term;
|
||||
char *buffer;
|
||||
int tty, tgetent_ret;
|
||||
int tty, tgetent_ret, dumbterm;
|
||||
|
||||
term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
|
||||
_rl_term_clrpag = _rl_term_cr = _rl_term_clreol = _rl_term_clrscroll = (char *)NULL;
|
||||
@@ -446,6 +465,8 @@ _rl_init_terminal_io (const char *terminal_name)
|
||||
if (term == 0)
|
||||
term = "dumb";
|
||||
|
||||
dumbterm = STREQ (term, "dumb");
|
||||
|
||||
#ifdef __MSDOS__
|
||||
_rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
|
||||
_rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
|
||||
@@ -457,6 +478,7 @@ _rl_init_terminal_io (const char *terminal_name)
|
||||
_rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL;
|
||||
_rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL;
|
||||
_rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL;
|
||||
_rl_term_so = _rl_term_se = (char *)NULL;
|
||||
#if defined(HACK_TERMCAP_MOTION)
|
||||
_rl_term_forward_char = (char *)NULL;
|
||||
#endif
|
||||
@@ -483,7 +505,7 @@ _rl_init_terminal_io (const char *terminal_name)
|
||||
tgetent_ret = tgetent (term_buffer, term);
|
||||
}
|
||||
|
||||
if (tgetent_ret <= 0)
|
||||
if (tgetent_ret != TGETENT_SUCCESS)
|
||||
{
|
||||
FREE (term_string_buffer);
|
||||
FREE (term_buffer);
|
||||
@@ -521,8 +543,13 @@ _rl_init_terminal_io (const char *terminal_name)
|
||||
_rl_term_mm = _rl_term_mo = (char *)NULL;
|
||||
_rl_term_ve = _rl_term_vs = (char *)NULL;
|
||||
_rl_term_forward_char = (char *)NULL;
|
||||
_rl_term_so = _rl_term_se = (char *)NULL;
|
||||
_rl_terminal_can_insert = term_has_meta = 0;
|
||||
|
||||
/* Assume generic unknown terminal can't handle the enable/disable
|
||||
escape sequences */
|
||||
_rl_enable_bracketed_paste = 0;
|
||||
|
||||
/* Reasonable defaults for tgoto(). Readline currently only uses
|
||||
tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
|
||||
change that later... */
|
||||
@@ -541,10 +568,10 @@ _rl_init_terminal_io (const char *terminal_name)
|
||||
BC = _rl_term_backspace;
|
||||
UP = _rl_term_up;
|
||||
|
||||
if (!_rl_term_cr)
|
||||
if (_rl_term_cr == 0)
|
||||
_rl_term_cr = "\r";
|
||||
|
||||
_rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
|
||||
_rl_term_autowrap = TGETFLAG ("am") && TGETFLAG ("xn");
|
||||
|
||||
/* Allow calling application to set default height and width, using
|
||||
rl_set_screen_size */
|
||||
@@ -559,7 +586,7 @@ _rl_init_terminal_io (const char *terminal_name)
|
||||
|
||||
/* Check to see if this terminal has a meta key and clear the capability
|
||||
variables if there is none. */
|
||||
term_has_meta = tgetflag ("km") != 0;
|
||||
term_has_meta = TGETFLAG ("km");
|
||||
if (term_has_meta == 0)
|
||||
_rl_term_mm = _rl_term_mo = (char *)NULL;
|
||||
#endif /* !__MSDOS__ */
|
||||
@@ -574,6 +601,11 @@ _rl_init_terminal_io (const char *terminal_name)
|
||||
bind_termcap_arrow_keys (vi_insertion_keymap);
|
||||
#endif /* VI_MODE */
|
||||
|
||||
/* There's no way to determine whether or not a given terminal supports
|
||||
bracketed paste mode, so we assume a terminal named "dumb" does not. */
|
||||
if (dumbterm)
|
||||
_rl_enable_bracketed_paste = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -676,6 +708,16 @@ rl_crlf (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_rl_cr (void)
|
||||
{
|
||||
#if defined (__MSDOS__)
|
||||
putc ('\r', rl_outstream);
|
||||
#else
|
||||
tputs (_rl_term_cr, 1, _rl_output_character_function);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Ring the terminal bell. */
|
||||
int
|
||||
rl_ding (void)
|
||||
@@ -708,6 +750,30 @@ rl_ding (void)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Entering and leaving terminal standout mode */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
void
|
||||
_rl_standout_on (void)
|
||||
{
|
||||
#ifndef __MSDOS__
|
||||
if (_rl_term_so && _rl_term_se)
|
||||
tputs (_rl_term_so, 1, _rl_output_character_function);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
_rl_standout_off (void)
|
||||
{
|
||||
#ifndef __MSDOS__
|
||||
if (_rl_term_so && _rl_term_se)
|
||||
tputs (_rl_term_se, 1, _rl_output_character_function);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Controlling the Meta Key and Keypad */
|
||||
|
||||
+85
-20
@@ -1,6 +1,6 @@
|
||||
/* text.c -- text handling commands for readline. */
|
||||
|
||||
/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -154,6 +154,7 @@ rl_delete_text (int from, int to)
|
||||
|
||||
rl_end -= diff;
|
||||
rl_line_buffer[rl_end] = '\0';
|
||||
_rl_fix_mark ();
|
||||
return (diff);
|
||||
}
|
||||
|
||||
@@ -176,6 +177,12 @@ _rl_fix_point (int fix_mark_too)
|
||||
if (fix_mark_too)
|
||||
_RL_FIX_POINT (rl_mark);
|
||||
}
|
||||
|
||||
void
|
||||
_rl_fix_mark (void)
|
||||
{
|
||||
_RL_FIX_POINT (rl_mark);
|
||||
}
|
||||
#undef _RL_FIX_POINT
|
||||
|
||||
/* Replace the contents of the line buffer between START and END with
|
||||
@@ -479,6 +486,8 @@ rl_forward_word (int count, int key)
|
||||
|
||||
while (count)
|
||||
{
|
||||
if (rl_point > rl_end)
|
||||
rl_point = rl_end;
|
||||
if (rl_point == rl_end)
|
||||
return 0;
|
||||
|
||||
@@ -498,6 +507,8 @@ rl_forward_word (int count, int key)
|
||||
}
|
||||
}
|
||||
|
||||
if (rl_point > rl_end)
|
||||
rl_point = rl_end;
|
||||
if (rl_point == rl_end)
|
||||
return 0;
|
||||
|
||||
@@ -569,18 +580,8 @@ rl_backward_word (int count, int key)
|
||||
int
|
||||
rl_refresh_line (int ignore1, int ignore2)
|
||||
{
|
||||
int curr_line;
|
||||
|
||||
curr_line = _rl_current_display_line ();
|
||||
|
||||
_rl_move_vert (curr_line);
|
||||
_rl_move_cursor_relative (0, rl_line_buffer); /* XXX is this right */
|
||||
|
||||
_rl_clear_to_eol (0); /* arg of 0 means to not use spaces */
|
||||
|
||||
rl_redraw_prompt_last_line ();
|
||||
_rl_refresh_line ();
|
||||
rl_display_fixed = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -596,7 +597,18 @@ rl_clear_screen (int count, int key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
_rl_clear_screen (); /* calls termcap function to clear screen */
|
||||
_rl_clear_screen (0); /* calls termcap function to clear screen */
|
||||
rl_keep_mark_active ();
|
||||
rl_forced_update_display ();
|
||||
rl_display_fixed = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rl_clear_display (int count, int key)
|
||||
{
|
||||
_rl_clear_screen (1); /* calls termcap function to clear screen and scrollback buffer */
|
||||
rl_forced_update_display ();
|
||||
rl_display_fixed = 1;
|
||||
|
||||
@@ -1080,6 +1092,13 @@ rl_tab_insert (int count, int key)
|
||||
int
|
||||
rl_newline (int count, int key)
|
||||
{
|
||||
if (rl_mark_active_p ())
|
||||
{
|
||||
rl_deactivate_mark ();
|
||||
(*rl_redisplay_function) ();
|
||||
_rl_want_redisplay = 0;
|
||||
}
|
||||
|
||||
rl_done = 1;
|
||||
|
||||
if (_rl_history_preserve_point)
|
||||
@@ -1452,7 +1471,18 @@ rl_change_case (int count, int op)
|
||||
if (nwc != wc) /* just skip unchanged characters */
|
||||
{
|
||||
char *s, *e;
|
||||
mlen = wcrtomb (mb, nwc, &mps);
|
||||
mbstate_t ts;
|
||||
|
||||
memset (&ts, 0, sizeof (mbstate_t));
|
||||
mlen = wcrtomb (mb, nwc, &ts);
|
||||
if (mlen < 0)
|
||||
{
|
||||
nwc = wc;
|
||||
memset (&ts, 0, sizeof (mbstate_t));
|
||||
mlen = wcrtomb (mb, nwc, &ts);
|
||||
if (mlen < 0) /* should not happen */
|
||||
strncpy (mb, rl_line_buffer + start, mlen = m);
|
||||
}
|
||||
if (mlen > 0)
|
||||
mb[mlen] = '\0';
|
||||
/* what to do if m != mlen? adjust below */
|
||||
@@ -1472,7 +1502,9 @@ rl_change_case (int count, int op)
|
||||
}
|
||||
else if (m < mlen)
|
||||
{
|
||||
rl_extend_line_buffer (mlen - m + 1);
|
||||
rl_extend_line_buffer (rl_end + mlen + (e - s) - m + 2);
|
||||
s = rl_line_buffer + start; /* have to redo this */
|
||||
e = rl_line_buffer + rl_end;
|
||||
memmove (s + mlen, s + m, (e - s) - m);
|
||||
memcpy (s, mb, mlen);
|
||||
next += mlen - m; /* next char changes */
|
||||
@@ -1711,10 +1743,7 @@ _rl_char_search (int count, int fdir, int bdir)
|
||||
{
|
||||
int c;
|
||||
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
c = _rl_bracketed_read_key ();
|
||||
if (c < 0)
|
||||
return 1;
|
||||
|
||||
@@ -1809,7 +1838,43 @@ rl_exchange_point_and_mark (int count, int key)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
SWAP (rl_point, rl_mark);
|
||||
{
|
||||
SWAP (rl_point, rl_mark);
|
||||
rl_activate_mark ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Active mark support */
|
||||
|
||||
/* Is the region active? */
|
||||
static int mark_active = 0;
|
||||
|
||||
/* Does the current command want the mark to remain active when it completes? */
|
||||
int _rl_keep_mark_active;
|
||||
|
||||
void
|
||||
rl_keep_mark_active (void)
|
||||
{
|
||||
_rl_keep_mark_active++;
|
||||
}
|
||||
|
||||
void
|
||||
rl_activate_mark (void)
|
||||
{
|
||||
mark_active = 1;
|
||||
rl_keep_mark_active ();
|
||||
}
|
||||
|
||||
void
|
||||
rl_deactivate_mark (void)
|
||||
{
|
||||
mark_active = 0;
|
||||
}
|
||||
|
||||
int
|
||||
rl_mark_active_p (void)
|
||||
{
|
||||
return (mark_active);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
|
||||
|
||||
/* Copyright (C) 1988-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1988-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -57,10 +57,10 @@ static void *xmalloc (), *xrealloc ();
|
||||
|
||||
#if !defined (HAVE_GETPW_DECLS)
|
||||
# if defined (HAVE_GETPWUID)
|
||||
extern struct passwd *getpwuid PARAMS((uid_t));
|
||||
extern struct passwd *getpwuid (uid_t);
|
||||
# endif
|
||||
# if defined (HAVE_GETPWNAM)
|
||||
extern struct passwd *getpwnam PARAMS((const char *));
|
||||
extern struct passwd *getpwnam (const char *);
|
||||
# endif
|
||||
#endif /* !HAVE_GETPW_DECLS */
|
||||
|
||||
@@ -79,8 +79,8 @@ extern struct passwd *getpwnam PARAMS((const char *));
|
||||
/* If being compiled as part of bash, these will be satisfied from
|
||||
variables.o. If being compiled as part of readline, they will
|
||||
be satisfied from shell.o. */
|
||||
extern char *sh_get_home_dir PARAMS((void));
|
||||
extern char *sh_get_env_value PARAMS((const char *));
|
||||
extern char *sh_get_home_dir (void);
|
||||
extern char *sh_get_env_value (const char *);
|
||||
|
||||
/* The default value of tilde_additional_prefixes. This is set to
|
||||
whitespace preceding a tilde so that simple programs which do not
|
||||
@@ -116,10 +116,10 @@ char **tilde_additional_prefixes = (char **)default_prefixes;
|
||||
`:' and `=~'. */
|
||||
char **tilde_additional_suffixes = (char **)default_suffixes;
|
||||
|
||||
static int tilde_find_prefix PARAMS((const char *, int *));
|
||||
static int tilde_find_suffix PARAMS((const char *));
|
||||
static char *isolate_tilde_prefix PARAMS((const char *, int *));
|
||||
static char *glue_prefix_and_suffix PARAMS((char *, const char *, int));
|
||||
static int tilde_find_prefix (const char *, int *);
|
||||
static int tilde_find_suffix (const char *);
|
||||
static char *isolate_tilde_prefix (const char *, int *);
|
||||
static char *glue_prefix_and_suffix (char *, const char *, int);
|
||||
|
||||
/* Find the start of a tilde expansion in STRING, and return the index of
|
||||
the tilde which starts the expansion. Place the length of the text
|
||||
|
||||
@@ -196,6 +196,7 @@ rl_do_undo (void)
|
||||
/* Undoing deletes means inserting some text. */
|
||||
case UNDO_DELETE:
|
||||
rl_point = start;
|
||||
_rl_fix_point (1);
|
||||
rl_insert_text (rl_undo_list->text);
|
||||
xfree (rl_undo_list->text);
|
||||
break;
|
||||
@@ -204,6 +205,7 @@ rl_do_undo (void)
|
||||
case UNDO_INSERT:
|
||||
rl_delete_text (start, end);
|
||||
rl_point = start;
|
||||
_rl_fix_point (1);
|
||||
break;
|
||||
|
||||
/* Undoing an END means undoing everything 'til we get to a BEGIN. */
|
||||
|
||||
+2
-1
@@ -102,10 +102,11 @@ _rl_abort_internal (void)
|
||||
rl_clear_message ();
|
||||
_rl_reset_argument ();
|
||||
rl_clear_pending_input ();
|
||||
rl_deactivate_mark ();
|
||||
|
||||
RL_UNSETSTATE (RL_STATE_MACRODEF);
|
||||
while (rl_executing_macro)
|
||||
_rl_pop_executing_macro ();
|
||||
_rl_kill_kbd_macro ();
|
||||
|
||||
RL_UNSETSTATE (RL_STATE_MULTIKEY); /* XXX */
|
||||
|
||||
|
||||
+138
-44
@@ -1,7 +1,7 @@
|
||||
/* vi_mode.c -- A vi emulation mode for Bash.
|
||||
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
|
||||
|
||||
/* Copyright (C) 1987-2018 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -298,6 +298,11 @@ rl_vi_redo (int count, int c)
|
||||
if (rl_point > 0)
|
||||
_rl_vi_backup ();
|
||||
}
|
||||
else if (_rl_vi_last_command == '.' && _rl_keymap == vi_movement_keymap)
|
||||
{
|
||||
rl_ding ();
|
||||
r = 0;
|
||||
}
|
||||
else
|
||||
r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
|
||||
|
||||
@@ -320,9 +325,9 @@ rl_vi_yank_arg (int count, int key)
|
||||
/* Readline thinks that the first word on a line is the 0th, while vi
|
||||
thinks the first word on a line is the 1st. Compensate. */
|
||||
if (rl_explicit_arg)
|
||||
rl_yank_nth_arg (count - 1, 0);
|
||||
rl_yank_nth_arg (count - 1, key);
|
||||
else
|
||||
rl_yank_nth_arg ('$', 0);
|
||||
rl_yank_nth_arg ('$', key);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -837,6 +842,12 @@ _rl_vi_save_replace (void)
|
||||
start = end - vi_replace_count + 1;
|
||||
len = vi_replace_count + 1;
|
||||
|
||||
if (start < 0)
|
||||
{
|
||||
len = end + 1;
|
||||
start = 0;
|
||||
}
|
||||
|
||||
vi_save_insert_buffer (start, len);
|
||||
}
|
||||
|
||||
@@ -864,8 +875,8 @@ _rl_vi_done_inserting (void)
|
||||
{
|
||||
if (_rl_vi_doing_insert)
|
||||
{
|
||||
/* The `C', `s', and `S' commands set this. */
|
||||
rl_end_undo_group ();
|
||||
/* The `c', `s', `S', and `R' commands set this. */
|
||||
rl_end_undo_group (); /* for the group in rl_vi_start_inserting */
|
||||
/* Now, the text between rl_undo_list->next->start and
|
||||
rl_undo_list->next->end is what was inserted while in insert
|
||||
mode. It gets copied to VI_INSERT_BUFFER because it depends
|
||||
@@ -876,7 +887,9 @@ _rl_vi_done_inserting (void)
|
||||
_rl_vi_save_replace (); /* Half the battle */
|
||||
else
|
||||
_rl_vi_save_insert (rl_undo_list->next);
|
||||
vi_continued_command = 1;
|
||||
/* sanity check, should always be >= 1 here */
|
||||
if (_rl_undo_group_level > 0)
|
||||
rl_end_undo_group (); /* for the group in the command (change or replace) */
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -888,10 +901,12 @@ _rl_vi_done_inserting (void)
|
||||
/* XXX - Other keys probably need to be checked. */
|
||||
else if (_rl_vi_last_key_before_insert == 'C')
|
||||
rl_end_undo_group ();
|
||||
while (_rl_undo_group_level > 0)
|
||||
rl_end_undo_group ();
|
||||
vi_continued_command = 0;
|
||||
}
|
||||
|
||||
/* Sanity check, make sure all the undo groups are closed before we leave
|
||||
insert mode */
|
||||
while (_rl_undo_group_level > 0)
|
||||
rl_end_undo_group ();
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1162,6 +1177,7 @@ rl_domove_motion_callback (_rl_vimotion_cxt *m)
|
||||
/* Append a blank character temporarily so that the motion routines
|
||||
work right at the end of the line. Original value of rl_end is saved
|
||||
as m->end. */
|
||||
rl_extend_line_buffer (rl_end + 1);
|
||||
rl_line_buffer[rl_end++] = ' ';
|
||||
rl_line_buffer[rl_end] = '\0';
|
||||
|
||||
@@ -1193,12 +1209,15 @@ _rl_vi_domove_motion_cleanup (int c, _rl_vimotion_cxt *m)
|
||||
/* Remove the blank that we added in rl_domove_motion_callback. */
|
||||
rl_end = m->end;
|
||||
rl_line_buffer[rl_end] = '\0';
|
||||
if (rl_point > rl_end)
|
||||
rl_point = rl_end;
|
||||
_rl_fix_point (0);
|
||||
|
||||
/* No change in position means the command failed. */
|
||||
if (rl_mark == rl_point)
|
||||
{
|
||||
/* 'c' and 'C' enter insert mode after the delete even if the motion
|
||||
didn't delete anything, as long as the motion command is valid. */
|
||||
if (_rl_to_upper (m->key) == 'C' && _rl_vi_motion_command (c))
|
||||
return (vidomove_dispatch (m));
|
||||
RL_UNSETSTATE (RL_STATE_VIMOTION);
|
||||
return (-1);
|
||||
}
|
||||
@@ -1316,13 +1335,7 @@ rl_domove_read_callback (_rl_vimotion_cxt *m)
|
||||
static int
|
||||
rl_vi_domove_getchar (_rl_vimotion_cxt *m)
|
||||
{
|
||||
int c;
|
||||
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
return c;
|
||||
return (_rl_bracketed_read_key ());
|
||||
}
|
||||
|
||||
#if defined (READLINE_CALLBACKS)
|
||||
@@ -1377,7 +1390,11 @@ rl_vi_delete_to (int count, int key)
|
||||
{
|
||||
int c, r;
|
||||
|
||||
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key);
|
||||
if (_rl_vimvcxt)
|
||||
_rl_mvcxt_init (_rl_vimvcxt, VIM_DELETE, key);
|
||||
else
|
||||
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key);
|
||||
|
||||
_rl_vimvcxt->start = rl_point;
|
||||
|
||||
rl_mark = rl_point;
|
||||
@@ -1465,7 +1482,10 @@ rl_vi_change_to (int count, int key)
|
||||
{
|
||||
int c, r;
|
||||
|
||||
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key);
|
||||
if (_rl_vimvcxt)
|
||||
_rl_mvcxt_init (_rl_vimvcxt, VIM_CHANGE, key);
|
||||
else
|
||||
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key);
|
||||
_rl_vimvcxt->start = rl_point;
|
||||
|
||||
rl_mark = rl_point;
|
||||
@@ -1524,6 +1544,8 @@ vi_yank_dispatch (_rl_vimotion_cxt *m)
|
||||
rl_do_undo ();
|
||||
rl_point = m->start;
|
||||
|
||||
_rl_fix_point (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -1532,7 +1554,10 @@ rl_vi_yank_to (int count, int key)
|
||||
{
|
||||
int c, r;
|
||||
|
||||
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key);
|
||||
if (_rl_vimvcxt)
|
||||
_rl_mvcxt_init (_rl_vimvcxt, VIM_YANK, key);
|
||||
else
|
||||
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key);
|
||||
_rl_vimvcxt->start = rl_point;
|
||||
|
||||
rl_mark = rl_point;
|
||||
@@ -2000,21 +2025,7 @@ _rl_vi_change_char (int count, int c, char *mb)
|
||||
static int
|
||||
_rl_vi_callback_getchar (char *mb, int mlen)
|
||||
{
|
||||
int c;
|
||||
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
if (c < 0)
|
||||
return -1;
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
c = _rl_read_mbstring (c, mb, mlen);
|
||||
#endif
|
||||
|
||||
return c;
|
||||
return (_rl_bracketed_read_mbstring (mb, mlen));
|
||||
}
|
||||
|
||||
#if defined (READLINE_CALLBACKS)
|
||||
@@ -2026,10 +2037,11 @@ _rl_vi_callback_change_char (_rl_callback_generic_arg *data)
|
||||
|
||||
c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
|
||||
#else
|
||||
_rl_vi_last_replacement[0] = c;
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
|
||||
else
|
||||
#endif
|
||||
_rl_vi_last_replacement[0] = c;
|
||||
_rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* XXX */
|
||||
|
||||
if (c < 0)
|
||||
@@ -2066,10 +2078,11 @@ rl_vi_change_char (int count, int key)
|
||||
{
|
||||
c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
|
||||
#ifdef HANDLE_MULTIBYTE
|
||||
strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
|
||||
#else
|
||||
_rl_vi_last_replacement[0] = c;
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
|
||||
else
|
||||
#endif
|
||||
_rl_vi_last_replacement[0] = c;
|
||||
_rl_vi_last_replacement[MB_LEN_MAX] = '\0'; /* just in case */
|
||||
}
|
||||
|
||||
@@ -2122,7 +2135,7 @@ rl_vi_overstrike_delete (int count, int key)
|
||||
s = rl_point;
|
||||
|
||||
if (rl_do_undo ())
|
||||
vi_replace_count--;
|
||||
vi_replace_count--; /* XXX */
|
||||
|
||||
if (rl_point == s)
|
||||
rl_backward_char (1, key);
|
||||
@@ -2137,6 +2150,67 @@ rl_vi_overstrike_delete (int count, int key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
rl_vi_overstrike_kill_line (int count, int key)
|
||||
{
|
||||
int r, end;
|
||||
|
||||
end = rl_end;
|
||||
r = rl_unix_line_discard (count, key);
|
||||
vi_replace_count -= end - rl_end;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
rl_vi_overstrike_kill_word (int count, int key)
|
||||
{
|
||||
int r, end;
|
||||
|
||||
end = rl_end;
|
||||
r = rl_vi_unix_word_rubout (count, key);
|
||||
vi_replace_count -= end - rl_end;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
rl_vi_overstrike_yank (int count, int key)
|
||||
{
|
||||
int r, end;
|
||||
|
||||
end = rl_end;
|
||||
r = rl_yank (count, key);
|
||||
vi_replace_count += rl_end - end;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Read bracketed paste mode pasted text and insert it in overwrite mode */
|
||||
static int
|
||||
rl_vi_overstrike_bracketed_paste (int count, int key)
|
||||
{
|
||||
int r;
|
||||
char *pbuf;
|
||||
size_t pblen;
|
||||
|
||||
pbuf = _rl_bracketed_text (&pblen);
|
||||
if (pblen == 0)
|
||||
{
|
||||
xfree (pbuf);
|
||||
return 0;
|
||||
}
|
||||
r = pblen;
|
||||
while (--r >= 0)
|
||||
_rl_unget_char ((unsigned char)pbuf[r]);
|
||||
xfree (pbuf);
|
||||
|
||||
while (_rl_pushed_input_available ())
|
||||
{
|
||||
key = rl_read_key ();
|
||||
r = rl_vi_overstrike (1, key);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
rl_vi_replace (int count, int key)
|
||||
{
|
||||
@@ -2169,6 +2243,21 @@ rl_vi_replace (int count, int key)
|
||||
vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
|
||||
vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
|
||||
|
||||
/* Same for ^U and unix-line-discard. */
|
||||
if (vi_insertion_keymap[CTRL ('U')].type == ISFUNC &&
|
||||
vi_insertion_keymap[CTRL ('U')].function == rl_unix_line_discard)
|
||||
vi_replace_map[CTRL ('U')].function = rl_vi_overstrike_kill_line;
|
||||
|
||||
/* And for ^W and unix-word-rubout. */
|
||||
if (vi_insertion_keymap[CTRL ('W')].type == ISFUNC &&
|
||||
vi_insertion_keymap[CTRL ('W')].function == rl_vi_unix_word_rubout)
|
||||
vi_replace_map[CTRL ('W')].function = rl_vi_overstrike_kill_word;
|
||||
|
||||
/* And finally for ^Y and yank. */
|
||||
if (vi_insertion_keymap[CTRL ('Y')].type == ISFUNC &&
|
||||
vi_insertion_keymap[CTRL ('Y')].function == rl_yank)
|
||||
vi_replace_map[CTRL ('Y')].function = rl_vi_overstrike_yank;
|
||||
|
||||
/* Make sure this is the value we need. */
|
||||
vi_replace_map[ANYOTHERKEY].type = ISFUNC;
|
||||
vi_replace_map[ANYOTHERKEY].function = (rl_command_func_t *)NULL;
|
||||
@@ -2176,9 +2265,12 @@ rl_vi_replace (int count, int key)
|
||||
|
||||
rl_vi_start_inserting (key, 1, rl_arg_sign);
|
||||
|
||||
_rl_vi_last_key_before_insert = key;
|
||||
_rl_vi_last_key_before_insert = 'R'; /* in case someone rebinds it */
|
||||
_rl_keymap = vi_replace_map;
|
||||
|
||||
if (_rl_enable_bracketed_paste)
|
||||
rl_bind_keyseq_if_unbound (BRACK_PASTE_PREF, rl_vi_overstrike_bracketed_paste);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -2268,6 +2360,7 @@ _rl_vi_goto_mark (void)
|
||||
if (ch == '`')
|
||||
{
|
||||
rl_point = rl_mark;
|
||||
_rl_fix_point (1);
|
||||
return 0;
|
||||
}
|
||||
else if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
|
||||
@@ -2283,6 +2376,7 @@ _rl_vi_goto_mark (void)
|
||||
return 1;
|
||||
}
|
||||
rl_point = vi_mark_chars[ch];
|
||||
_rl_fix_point (1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+13
-4
@@ -2,7 +2,7 @@
|
||||
# Makefile for the Bash library
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1998-2010 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1998-2020 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -93,7 +93,7 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \
|
||||
wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \
|
||||
casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c \
|
||||
strchrnul.c unicode.c wcswidth.c wcsnwidth.c shmbchar.c strdup.c \
|
||||
utf8.c
|
||||
utf8.c random.c gettimeofday.c
|
||||
|
||||
# The header files for this library.
|
||||
HSOURCES =
|
||||
@@ -108,7 +108,7 @@ OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \
|
||||
fmtullong.o fmtumax.o zcatfd.o zmapfd.o winsize.o wcsdup.o \
|
||||
fpurge.o zgetline.o mbscmp.o uconvert.o ufuncs.o casemod.o \
|
||||
input_avail.o mbscasecmp.o fnxform.o unicode.o shmbchar.o \
|
||||
utf8.o wcsnwidth.o ${LIBOBJS}
|
||||
utf8.o random.o gettimeofday.o wcsnwidth.o ${LIBOBJS}
|
||||
|
||||
SUPPORT = Makefile
|
||||
|
||||
@@ -155,6 +155,7 @@ fnxform.o: fnxform.c
|
||||
fpurge.o: fpurge.c
|
||||
getcwd.o: getcwd.c
|
||||
getenv.o: getenv.c
|
||||
gettimeofday.o: gettimeofday.c
|
||||
inet_aton.o: inet_aton.c
|
||||
input_avail.o: input_avail.c
|
||||
itos.o: itos.c
|
||||
@@ -170,6 +171,7 @@ netopen.o: netopen.c
|
||||
oslib.o: oslib.c
|
||||
pathcanon.o: pathcanon.c
|
||||
pathphys.o: pathphys.c
|
||||
random.o: random.c
|
||||
rename.o: rename.c
|
||||
setlinebuf.o: setlinebuf.c
|
||||
shmatch.o: shmatch.c
|
||||
@@ -233,6 +235,7 @@ fnxform.o: ${BUILD_DIR}/config.h
|
||||
fpurge.o: ${BUILD_DIR}/config.h
|
||||
getcwd.o: ${BUILD_DIR}/config.h
|
||||
getenv.o: ${BUILD_DIR}/config.h
|
||||
gettimeofday.o: ${BUILD_DIR}/config.h
|
||||
inet_aton.o: ${BUILD_DIR}/config.h
|
||||
input_avail.o: ${BUILD_DIR}/config.h
|
||||
itos.o: ${BUILD_DIR}/config.h
|
||||
@@ -248,6 +251,7 @@ netopen.o: ${BUILD_DIR}/config.h
|
||||
oslib.o: ${BUILD_DIR}/config.h
|
||||
pathcanon.o: ${BUILD_DIR}/config.h
|
||||
pathphys.o: ${BUILD_DIR}/config.h
|
||||
random.o: ${BUILD_DIR}/config.h
|
||||
rename.o: ${BUILD_DIR}/config.h
|
||||
setlinebuf.o: ${BUILD_DIR}/config.h
|
||||
shmatch.o: ${BUILD_DIR}/config.h
|
||||
@@ -275,7 +279,7 @@ strtoumax.o: ${BUILD_DIR}/config.h
|
||||
strtrans.o: ${BUILD_DIR}/config.h
|
||||
times.o: ${BUILD_DIR}/config.h
|
||||
timeval.o: ${BUILD_DIR}/config.h
|
||||
tmpfile.o: ${BUILD_DIR}/config.h
|
||||
tmpfile.o: ${BUILD_DIR}/config.h ${topdir}/config-top.h
|
||||
uconvert.o: ${BUILD_DIR}/config.h
|
||||
ufuncs.o: ${BUILD_DIR}/config.h
|
||||
unicode.o: ${BUILD_DIR}/config.h
|
||||
@@ -380,6 +384,10 @@ pathphys.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h
|
||||
pathphys.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h
|
||||
#pathphys.o: ${BUILD_DIR}/version.h
|
||||
|
||||
random.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h
|
||||
random.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
|
||||
random.o: ${BASHINCDIR}/filecntl.h
|
||||
|
||||
rename.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h
|
||||
rename.o: ${BASHINCDIR}/posixstat.h
|
||||
|
||||
@@ -505,6 +513,7 @@ times.o: ${BASHINCDIR}/systimes.h
|
||||
times.o: ${BASHINCDIR}/posixtime.h
|
||||
|
||||
timeval.o: ${BASHINCDIR}/posixtime.h
|
||||
gettimeofday.o: ${BASHINCDIR}/posixtime.h
|
||||
|
||||
tmpfile.o: ${topdir}/bashtypes.h
|
||||
tmpfile.o: ${BASHINCDIR}/chartypes.h
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* casemod.c -- functions to change case of strings */
|
||||
|
||||
/* Copyright (C) 2008,2009,2015 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2008-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
#define CASE_USEWORDS 0x1000 /* modify behavior to act on words in passed string */
|
||||
|
||||
extern char *substring __P((char *, int, int));
|
||||
extern char *substring PARAMS((char *, int, int));
|
||||
|
||||
#ifndef UCHAR_MAX
|
||||
# define UCHAR_MAX TYPE_MAXIMUM(unsigned char)
|
||||
|
||||
+6
-6
@@ -1,6 +1,6 @@
|
||||
/* eaccess.c - eaccess replacement for the shell, plus other access functions. */
|
||||
|
||||
/* Copyright (C) 2006-2010 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2006-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -52,10 +52,10 @@ extern int errno;
|
||||
#define F_OK 0
|
||||
#endif /* R_OK */
|
||||
|
||||
static int path_is_devfd __P((const char *));
|
||||
static int sh_stataccess __P((const char *, int));
|
||||
static int path_is_devfd PARAMS((const char *));
|
||||
static int sh_stataccess PARAMS((const char *, int));
|
||||
#if HAVE_DECL_SETREGID
|
||||
static int sh_euidaccess __P((const char *, int));
|
||||
static int sh_euidaccess PARAMS((const char *, int));
|
||||
#endif
|
||||
|
||||
static int
|
||||
@@ -213,10 +213,10 @@ sh_eaccess (path, mode)
|
||||
# else /* HAVE_EACCESS */ /* FreeBSD */
|
||||
ret = eaccess (path, mode); /* XXX -- not always correct for X_OK */
|
||||
# endif /* HAVE_EACCESS */
|
||||
# if defined (__FreeBSD__) || defined (SOLARIS)
|
||||
# if defined (__FreeBSD__) || defined (SOLARIS) || defined (_AIX)
|
||||
if (ret == 0 && current_user.euid == 0 && mode == X_OK)
|
||||
return (sh_stataccess (path, mode));
|
||||
# endif /* __FreeBSD__ || SOLARIS */
|
||||
# endif /* __FreeBSD__ || SOLARIS || _AIX */
|
||||
return ret;
|
||||
#elif defined (EFF_ONLY_OK) /* SVR4(?), SVR4.2 */
|
||||
return access (path, mode|EFF_ONLY_OK);
|
||||
|
||||
+6
-6
@@ -1,6 +1,6 @@
|
||||
/* fnxform - use iconv(3) to transform strings to and from "filename" format */
|
||||
|
||||
/* Copyright (C) 2009-2010 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2009-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_LOCALE_CHARSET)
|
||||
extern const char *locale_charset __P((void));
|
||||
extern const char *locale_charset PARAMS((void));
|
||||
#else
|
||||
extern char *get_locale_var __P((char *));
|
||||
extern char *get_locale_var PARAMS((char *));
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_ICONV)
|
||||
@@ -49,9 +49,9 @@ static iconv_t conv_tofs = (iconv_t)-1;
|
||||
static char *outbuf = 0;
|
||||
static size_t outlen = 0;
|
||||
|
||||
static char *curencoding __P((void));
|
||||
static void init_tofs __P((void));
|
||||
static void init_fromfs __P((void));
|
||||
static char *curencoding PARAMS((void));
|
||||
static void init_tofs PARAMS((void));
|
||||
static void init_fromfs PARAMS((void));
|
||||
|
||||
static char *
|
||||
curencoding ()
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* fpurge - Flushing buffers of a FILE stream. */
|
||||
|
||||
/* Copyright (C) 2007-2010 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2007-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#if HAVE_FPURGE
|
||||
# define fpurge _bash_fpurge
|
||||
#endif
|
||||
extern int fpurge __P((FILE *stream));
|
||||
extern int fpurge PARAMS((FILE *stream));
|
||||
|
||||
#if HAVE___FPURGE /* glibc >= 2.2, Haiku, Solaris >= 7 */
|
||||
# include <stdio_ext.h>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/* gettimeofday.c - gettimeofday replacement using time() */
|
||||
|
||||
/* Copyright (C) 2020 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/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if !defined (HAVE_GETTIMEOFDAY)
|
||||
|
||||
#include "posixtime.h"
|
||||
|
||||
/* A version of gettimeofday that just sets tv_sec from time(3) */
|
||||
int
|
||||
gettimeofday (struct timeval *tv, void *tz)
|
||||
{
|
||||
tv->tv_sec = (time_t) time ((time_t *)0);
|
||||
tv->tv_usec = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
+70
-3
@@ -1,7 +1,7 @@
|
||||
/* input_avail.c -- check whether or not data is available for reading on a
|
||||
specified file descriptor. */
|
||||
|
||||
/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2008,2009-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
# include <sys/file.h>
|
||||
#endif /* HAVE_SYS_FILE_H */
|
||||
|
||||
#if defined (HAVE_PSELECT)
|
||||
# include <signal.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
@@ -82,10 +86,8 @@ input_avail (fd)
|
||||
timeout.tv_usec = 0;
|
||||
result = select (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
|
||||
return ((result <= 0) ? 0 : 1);
|
||||
|
||||
#endif
|
||||
|
||||
result = -1;
|
||||
#if defined (FIONREAD)
|
||||
errno = 0;
|
||||
result = ioctl (fd, FIONREAD, &chars_avail);
|
||||
@@ -96,3 +98,68 @@ input_avail (fd)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait until NCHARS are available for reading on file descriptor FD.
|
||||
This can wait indefinitely. Return -1 on error. */
|
||||
int
|
||||
nchars_avail (fd, nchars)
|
||||
int fd;
|
||||
int nchars;
|
||||
{
|
||||
int result, chars_avail;
|
||||
#if defined(HAVE_SELECT)
|
||||
fd_set readfds, exceptfds;
|
||||
#endif
|
||||
#if defined (HAVE_PSELECT)
|
||||
sigset_t set, oset;
|
||||
#endif
|
||||
|
||||
if (fd < 0 || nchars < 0)
|
||||
return -1;
|
||||
if (nchars == 0)
|
||||
return (input_avail (fd));
|
||||
|
||||
chars_avail = 0;
|
||||
|
||||
#if defined (HAVE_SELECT)
|
||||
FD_ZERO (&readfds);
|
||||
FD_ZERO (&exceptfds);
|
||||
FD_SET (fd, &readfds);
|
||||
FD_SET (fd, &exceptfds);
|
||||
#endif
|
||||
#if defined (HAVE_SELECT) || defined (HAVE_PSELECT)
|
||||
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
|
||||
# ifdef SIGCHLD
|
||||
sigaddset (&set, SIGCHLD);
|
||||
# endif
|
||||
sigemptyset (&oset);
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
result = 0;
|
||||
#if defined (HAVE_PSELECT)
|
||||
/* XXX - use pselect(2) to block SIGCHLD atomically */
|
||||
result = pselect (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, (struct timespec *)NULL, &set);
|
||||
#elif defined (HAVE_SELECT)
|
||||
sigprocmask (SIG_BLOCK, &set, &oset);
|
||||
result = select (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, (struct timeval *)NULL);
|
||||
sigprocmask (SIG_BLOCK, &oset, (sigset_t *)NULL);
|
||||
#endif
|
||||
if (result < 0)
|
||||
return -1;
|
||||
|
||||
#if defined (FIONREAD)
|
||||
errno = 0;
|
||||
result = ioctl (fd, FIONREAD, &chars_avail);
|
||||
if (result == -1 && errno == EIO)
|
||||
return -1;
|
||||
if (chars_avail >= nchars)
|
||||
break;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ mailstat(path, st)
|
||||
struct stat st_ret, st_tmp;
|
||||
DIR *dd;
|
||||
struct dirent *fn;
|
||||
char dir[PATH_MAX * 2], file[PATH_MAX * 2];
|
||||
char dir[PATH_MAX * 2], file[PATH_MAX * 2 + 1];
|
||||
int i, l;
|
||||
time_t atime, mtime;
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* makepath.c - glue PATH and DIR together into a full pathname. */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
# define MP_IGNDOT 0x08
|
||||
#endif
|
||||
|
||||
extern char *get_working_directory __P((char *));
|
||||
extern char *get_working_directory PARAMS((char *));
|
||||
|
||||
static char *nullpath = "";
|
||||
|
||||
|
||||
+9
-9
@@ -1,6 +1,6 @@
|
||||
/* mktime - convert struct tm to a time_t value */
|
||||
|
||||
/* Copyright (C) 1993-2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
Contributed by Paul Eggert (eggert@twinsun.com).
|
||||
@@ -56,13 +56,13 @@
|
||||
#define mktime my_mktime
|
||||
#endif /* DEBUG_MKTIME */
|
||||
|
||||
#ifndef __P
|
||||
#ifndef PARAMS
|
||||
#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
|
||||
#define __P(args) args
|
||||
#define PARAMS(args) args
|
||||
#else
|
||||
#define __P(args) ()
|
||||
#define PARAMS(args) ()
|
||||
#endif /* GCC. */
|
||||
#endif /* Not __P. */
|
||||
#endif /* Not PARAMS. */
|
||||
|
||||
#ifndef CHAR_BIT
|
||||
#define CHAR_BIT 8
|
||||
@@ -117,13 +117,13 @@ const unsigned short int __mon_yday[2][13] =
|
||||
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
|
||||
};
|
||||
|
||||
static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
|
||||
time_t __mktime_internal __P ((struct tm *,
|
||||
static time_t ydhms_tm_diff PARAMS ((int, int, int, int, int, const struct tm *));
|
||||
time_t __mktime_internal PARAMS ((struct tm *,
|
||||
struct tm *(*) (const time_t *, struct tm *),
|
||||
time_t *));
|
||||
|
||||
|
||||
static struct tm *my_localtime_r __P ((const time_t *, struct tm *));
|
||||
static struct tm *my_localtime_r PARAMS ((const time_t *, struct tm *));
|
||||
static struct tm *
|
||||
my_localtime_r (t, tp)
|
||||
const time_t *t;
|
||||
@@ -193,7 +193,7 @@ mktime (tp)
|
||||
time_t
|
||||
__mktime_internal (tp, convert, offset)
|
||||
struct tm *tp;
|
||||
struct tm *(*convert) __P ((const time_t *, struct tm *));
|
||||
struct tm *(*convert) PARAMS ((const time_t *, struct tm *));
|
||||
time_t *offset;
|
||||
{
|
||||
time_t t, dt, t0;
|
||||
|
||||
+7
-7
@@ -5,7 +5,7 @@
|
||||
* chet@ins.CWRU.Edu
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -63,18 +63,18 @@ extern int errno;
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_INET_ATON)
|
||||
extern int inet_aton __P((const char *, struct in_addr *));
|
||||
extern int inet_aton PARAMS((const char *, struct in_addr *));
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
static int _getaddr __P((char *, struct in_addr *));
|
||||
static int _getserv __P((char *, int, unsigned short *));
|
||||
static int _netopen4 __P((char *, char *, int));
|
||||
static int _getaddr PARAMS((char *, struct in_addr *));
|
||||
static int _getserv PARAMS((char *, int, unsigned short *));
|
||||
static int _netopen4 PARAMS((char *, char *, int));
|
||||
#else /* HAVE_GETADDRINFO */
|
||||
static int _netopen6 __P((char *, char *, int));
|
||||
static int _netopen6 PARAMS((char *, char *, int));
|
||||
#endif
|
||||
|
||||
static int _netopen __P((char *, char *, int));
|
||||
static int _netopen PARAMS((char *, char *, int));
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
/* Stuff the internet address corresponding to HOST into AP, in network
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ _path_isdir (path)
|
||||
|
||||
/* Canonicalize PATH, and return a new path. The new path differs from PATH
|
||||
in that:
|
||||
Multple `/'s are collapsed to a single `/'.
|
||||
Multiple `/'s are collapsed to a single `/'.
|
||||
Leading `./'s and trailing `/.'s are removed.
|
||||
Trailing `/'s are removed.
|
||||
Non-leading `../'s and trailing `..'s are handled by removing
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* pathphys.c -- return pathname with all symlinks expanded. */
|
||||
|
||||
/* Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2000-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern char *get_working_directory __P((char *));
|
||||
extern char *get_working_directory PARAMS((char *));
|
||||
|
||||
static int
|
||||
_path_readlink (path, buf, bufsiz)
|
||||
|
||||
+240
@@ -0,0 +1,240 @@
|
||||
/* random.c -- Functions for managing 16-bit and 32-bit random numbers. */
|
||||
|
||||
/* Copyright (C) 2020 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/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "bashtypes.h"
|
||||
|
||||
#if defined (HAVE_SYS_RANDOM_H)
|
||||
# include <sys/random.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include "filecntl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bashansi.h"
|
||||
|
||||
#include "shell.h"
|
||||
|
||||
extern time_t shell_start_time;
|
||||
|
||||
extern int last_random_value;
|
||||
|
||||
static u_bits32_t intrand32 PARAMS((u_bits32_t));
|
||||
static u_bits32_t genseed PARAMS((void));
|
||||
|
||||
static u_bits32_t brand32 PARAMS((void));
|
||||
static void sbrand32 PARAMS((u_bits32_t));
|
||||
static void perturb_rand32 PARAMS((void));
|
||||
|
||||
/* The random number seed. You can change this by setting RANDOM. */
|
||||
static u_bits32_t rseed = 1;
|
||||
|
||||
/* Returns a 32-bit pseudo-random number. */
|
||||
static u_bits32_t
|
||||
intrand32 (last)
|
||||
u_bits32_t last;
|
||||
{
|
||||
/* Minimal Standard generator from
|
||||
"Random number generators: good ones are hard to find",
|
||||
Park and Miller, Communications of the ACM, vol. 31, no. 10,
|
||||
October 1988, p. 1195. Filtered through FreeBSD.
|
||||
|
||||
x(n+1) = 16807 * x(n) mod (m).
|
||||
|
||||
We split up the calculations to avoid overflow.
|
||||
|
||||
h = last / q; l = x - h * q; t = a * l - h * r
|
||||
m = 2147483647, a = 16807, q = 127773, r = 2836
|
||||
|
||||
There are lots of other combinations of constants to use; look at
|
||||
https://www.gnu.org/software/gsl/manual/html_node/Other-random-number-generators.html#Other-random-number-generators */
|
||||
|
||||
bits32_t h, l, t;
|
||||
u_bits32_t ret;
|
||||
|
||||
/* Can't seed with 0. */
|
||||
ret = (last == 0) ? 123459876 : last;
|
||||
h = ret / 127773;
|
||||
l = ret - (127773 * h);
|
||||
t = 16807 * l - 2836 * h;
|
||||
ret = (t < 0) ? t + 0x7fffffff : t;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static u_bits32_t
|
||||
genseed ()
|
||||
{
|
||||
struct timeval tv;
|
||||
u_bits32_t iv;
|
||||
|
||||
gettimeofday (&tv, NULL);
|
||||
iv = (u_bits32_t)seedrand; /* let the compiler truncate */
|
||||
iv = tv.tv_sec ^ tv.tv_usec ^ getpid () ^ getppid () ^ current_user.uid ^ iv;
|
||||
return (iv);
|
||||
}
|
||||
|
||||
#define BASH_RAND_MAX 32767 /* 0x7fff - 16 bits */
|
||||
|
||||
/* Returns a pseudo-random number between 0 and 32767. */
|
||||
int
|
||||
brand ()
|
||||
{
|
||||
unsigned int ret;
|
||||
|
||||
rseed = intrand32 (rseed);
|
||||
if (shell_compatibility_level > 50)
|
||||
ret = (rseed >> 16) ^ (rseed & 65535);
|
||||
else
|
||||
ret = rseed;
|
||||
return (ret & BASH_RAND_MAX);
|
||||
}
|
||||
|
||||
/* Set the random number generator seed to SEED. */
|
||||
void
|
||||
sbrand (seed)
|
||||
unsigned long seed;
|
||||
{
|
||||
rseed = seed;
|
||||
last_random_value = 0;
|
||||
}
|
||||
|
||||
void
|
||||
seedrand ()
|
||||
{
|
||||
u_bits32_t iv;
|
||||
|
||||
iv = genseed ();
|
||||
sbrand (iv);
|
||||
}
|
||||
|
||||
static u_bits32_t rseed32 = 1073741823;
|
||||
static int last_rand32;
|
||||
|
||||
static int urandfd = -1;
|
||||
|
||||
#define BASH_RAND32_MAX 0x7fffffff /* 32 bits */
|
||||
|
||||
/* Returns a 32-bit pseudo-random number between 0 and 4294967295. */
|
||||
static u_bits32_t
|
||||
brand32 ()
|
||||
{
|
||||
u_bits32_t ret;
|
||||
|
||||
rseed32 = intrand32 (rseed32);
|
||||
return (rseed32 & BASH_RAND32_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
sbrand32 (seed)
|
||||
u_bits32_t seed;
|
||||
{
|
||||
last_rand32 = rseed32 = seed;
|
||||
}
|
||||
|
||||
void
|
||||
seedrand32 ()
|
||||
{
|
||||
u_bits32_t iv;
|
||||
|
||||
iv = genseed ();
|
||||
sbrand32 (iv);
|
||||
}
|
||||
|
||||
static void
|
||||
perturb_rand32 ()
|
||||
{
|
||||
rseed32 ^= genseed ();
|
||||
}
|
||||
|
||||
/* Force another attempt to open /dev/urandom on the next call to get_urandom32 */
|
||||
void
|
||||
urandom_close ()
|
||||
{
|
||||
if (urandfd >= 0)
|
||||
close (urandfd);
|
||||
urandfd = -1;
|
||||
}
|
||||
|
||||
#if !defined (HAVE_GETRANDOM)
|
||||
/* Imperfect emulation of getrandom(2). */
|
||||
#ifndef GRND_NONBLOCK
|
||||
# define GRND_NONBLOCK 1
|
||||
# define GRND_RANDOM 2
|
||||
#endif
|
||||
|
||||
static ssize_t
|
||||
getrandom (buf, len, flags)
|
||||
void *buf;
|
||||
size_t len;
|
||||
unsigned int flags;
|
||||
{
|
||||
int oflags;
|
||||
ssize_t r;
|
||||
static int urand_unavail = 0;
|
||||
|
||||
#if HAVE_GETENTROPY
|
||||
r = getentropy (buf, len);
|
||||
return (r == 0) ? len : -1;
|
||||
#endif
|
||||
|
||||
if (urandfd == -1 && urand_unavail == 0)
|
||||
{
|
||||
oflags = O_RDONLY;
|
||||
if (flags & GRND_NONBLOCK)
|
||||
oflags |= O_NONBLOCK;
|
||||
urandfd = open ("/dev/urandom", oflags, 0);
|
||||
if (urandfd >= 0)
|
||||
SET_CLOSE_ON_EXEC (urandfd);
|
||||
else
|
||||
{
|
||||
urand_unavail = 1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (urandfd >= 0 && (r = read (urandfd, buf, len)) == len)
|
||||
return (r);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
u_bits32_t
|
||||
get_urandom32 ()
|
||||
{
|
||||
u_bits32_t ret;
|
||||
|
||||
if (getrandom ((void *)&ret, sizeof (ret), GRND_NONBLOCK) == sizeof (ret))
|
||||
return (last_rand32 = ret);
|
||||
|
||||
#if defined (HAVE_ARC4RANDOM)
|
||||
ret = arc4random ();
|
||||
#else
|
||||
if (subshell_environment)
|
||||
perturb_rand32 ();
|
||||
do
|
||||
ret = brand32 ();
|
||||
while (ret == last_rand32);
|
||||
#endif
|
||||
return (last_rand32 = ret);
|
||||
}
|
||||
+3
-1
@@ -64,7 +64,7 @@ sh_regmatch (string, pattern, flags)
|
||||
#endif
|
||||
|
||||
rflags = REG_EXTENDED;
|
||||
if (glob_ignore_case || match_ignore_case)
|
||||
if (match_ignore_case)
|
||||
rflags |= REG_ICASE;
|
||||
#if !defined (ARRAY_VARS)
|
||||
rflags |= REG_NOSUB;
|
||||
@@ -107,7 +107,9 @@ sh_regmatch (string, pattern, flags)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
VSETATTR (rematch, att_readonly);
|
||||
#endif
|
||||
|
||||
free (subexp_str);
|
||||
free (matches);
|
||||
|
||||
+61
-16
@@ -1,6 +1,6 @@
|
||||
/* shquote - functions to quote and dequote strings */
|
||||
|
||||
/* Copyright (C) 1999-2015 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
#include "shmbchar.h"
|
||||
#include "shmbutil.h"
|
||||
|
||||
extern char *ansic_quote __P((char *, int, int *));
|
||||
extern int ansic_shouldquote __P((const char *));
|
||||
extern char *ansic_quote PARAMS((char *, int, int *));
|
||||
extern int ansic_shouldquote PARAMS((const char *));
|
||||
|
||||
/* Default set of characters that should be backslash-quoted in strings */
|
||||
static const char bstab[256] =
|
||||
@@ -136,8 +136,15 @@ sh_double_quote (string)
|
||||
const char *string;
|
||||
{
|
||||
register unsigned char c;
|
||||
int mb_cur_max;
|
||||
char *result, *r;
|
||||
const char *s;
|
||||
size_t slen;
|
||||
const char *s, *send;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
slen = strlen (string);
|
||||
send = string + slen;
|
||||
mb_cur_max = MB_CUR_MAX;
|
||||
|
||||
result = (char *)xmalloc (3 + (2 * strlen (string)));
|
||||
r = result;
|
||||
@@ -148,12 +155,19 @@ sh_double_quote (string)
|
||||
/* Backslash-newline disappears within double quotes, so don't add one. */
|
||||
if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
|
||||
*r++ = '\\';
|
||||
#if 0
|
||||
/* Assume that the string will not be further expanded. */
|
||||
else if (c == CTLESC || c == CTLNUL)
|
||||
*r++ = CTLESC; /* could be '\\'? */
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if ((locale_utf8locale && (c & 0x80)) ||
|
||||
(locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0))
|
||||
{
|
||||
COPY_CHAR_P (r, s, send);
|
||||
s--; /* compensate for auto-increment in loop above */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Assume that the string will not be further expanded, so no need to
|
||||
add CTLESC to protect CTLESC or CTLNUL. */
|
||||
*r++ = c;
|
||||
}
|
||||
|
||||
@@ -171,16 +185,29 @@ sh_mkdoublequoted (s, slen, flags)
|
||||
int slen, flags;
|
||||
{
|
||||
char *r, *ret;
|
||||
int rlen;
|
||||
const char *send;
|
||||
int rlen, mb_cur_max;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
send = s + slen;
|
||||
mb_cur_max = flags ? MB_CUR_MAX : 1;
|
||||
rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1;
|
||||
ret = r = (char *)xmalloc (rlen);
|
||||
|
||||
|
||||
*r++ = '"';
|
||||
while (*s)
|
||||
{
|
||||
if (flags && *s == '"')
|
||||
*r++ = '\\';
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (flags && ((locale_utf8locale && (*s & 0x80)) ||
|
||||
(locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (*s) == 0)))
|
||||
{
|
||||
COPY_CHAR_P (r, s, send);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
*r++ = *s++;
|
||||
}
|
||||
*r++ = '"';
|
||||
@@ -259,7 +286,8 @@ sh_backslash_quote (string, table, flags)
|
||||
*r++ = c;
|
||||
continue;
|
||||
}
|
||||
if (mb_cur_max > 1 && is_basic (c) == 0)
|
||||
if ((locale_utf8locale && (c & 0x80)) ||
|
||||
(locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0))
|
||||
{
|
||||
COPY_CHAR_P (r, s, send);
|
||||
s--; /* compensate for auto-increment in loop above */
|
||||
@@ -291,18 +319,35 @@ sh_backslash_quote_for_double_quotes (string)
|
||||
char *string;
|
||||
{
|
||||
unsigned char c;
|
||||
char *result, *r, *s;
|
||||
|
||||
result = (char *)xmalloc (2 * strlen (string) + 1);
|
||||
char *result, *r, *s, *send;
|
||||
size_t slen;
|
||||
int mb_cur_max;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
slen = strlen (string);
|
||||
send = string + slen;
|
||||
mb_cur_max = MB_CUR_MAX;
|
||||
result = (char *)xmalloc (2 * slen + 1);
|
||||
|
||||
for (r = result, s = string; s && (c = *s); s++)
|
||||
{
|
||||
if (sh_syntaxtab[c] & CBSDQUOTE)
|
||||
/* Backslash-newline disappears within double quotes, so don't add one. */
|
||||
if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
|
||||
*r++ = '\\';
|
||||
/* I should probably add flags for these to sh_syntaxtab[] */
|
||||
/* I should probably use the CSPECL flag for these in sh_syntaxtab[] */
|
||||
else if (c == CTLESC || c == CTLNUL)
|
||||
*r++ = CTLESC; /* could be '\\'? */
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if ((locale_utf8locale && (c & 0x80)) ||
|
||||
(locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0))
|
||||
{
|
||||
COPY_CHAR_P (r, s, send);
|
||||
s--; /* compensate for auto-increment in loop above */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
*r++ = c;
|
||||
}
|
||||
|
||||
|
||||
+21
-21
@@ -9,7 +9,7 @@
|
||||
Unix snprintf implementation.
|
||||
derived from inetutils/libinetutils/snprintf.c Version 1.1
|
||||
|
||||
Copyright (C) 2001,2006,2010,2012 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -129,8 +129,8 @@
|
||||
# define FL_ADDBASE 0x02 /* add base# prefix to converted value */
|
||||
# define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */
|
||||
# define FL_UNSIGNED 0x08 /* don't add any sign */
|
||||
extern char *fmtulong __P((unsigned long int, int, char *, size_t, int));
|
||||
extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
|
||||
extern char *fmtulong PARAMS((unsigned long int, int, char *, size_t, int));
|
||||
extern char *fmtullong PARAMS((unsigned long long int, int, char *, size_t, int));
|
||||
#endif
|
||||
|
||||
#ifndef FREE
|
||||
@@ -271,38 +271,38 @@ struct DATA
|
||||
|
||||
/* the floating point stuff */
|
||||
#ifdef FLOATING_POINT
|
||||
static double pow_10 __P((int));
|
||||
static int log_10 __P((double));
|
||||
static double integral __P((double, double *));
|
||||
static char *numtoa __P((double, int, int, char **));
|
||||
static double pow_10 PARAMS((int));
|
||||
static int log_10 PARAMS((double));
|
||||
static double integral PARAMS((double, double *));
|
||||
static char *numtoa PARAMS((double, int, int, char **));
|
||||
#endif
|
||||
|
||||
static void init_data __P((struct DATA *, char *, size_t, const char *, int));
|
||||
static void init_conv_flag __P((struct DATA *));
|
||||
static void init_data PARAMS((struct DATA *, char *, size_t, const char *, int));
|
||||
static void init_conv_flag PARAMS((struct DATA *));
|
||||
|
||||
/* for the format */
|
||||
#ifdef FLOATING_POINT
|
||||
static void floating __P((struct DATA *, double));
|
||||
static void exponent __P((struct DATA *, double));
|
||||
static void floating PARAMS((struct DATA *, double));
|
||||
static void exponent PARAMS((struct DATA *, double));
|
||||
#endif
|
||||
static void number __P((struct DATA *, unsigned long, int));
|
||||
static void number PARAMS((struct DATA *, unsigned long, int));
|
||||
#ifdef HAVE_LONG_LONG
|
||||
static void lnumber __P((struct DATA *, unsigned long long, int));
|
||||
static void lnumber PARAMS((struct DATA *, unsigned long long, int));
|
||||
#endif
|
||||
static void pointer __P((struct DATA *, unsigned long));
|
||||
static void strings __P((struct DATA *, char *));
|
||||
static void pointer PARAMS((struct DATA *, unsigned long));
|
||||
static void strings PARAMS((struct DATA *, char *));
|
||||
|
||||
#ifdef FLOATING_POINT
|
||||
# define FALLBACK_FMTSIZE 32
|
||||
# define FALLBACK_BASE 4096
|
||||
# define LFALLBACK_BASE 5120
|
||||
# ifdef HAVE_LONG_DOUBLE
|
||||
static void ldfallback __P((struct DATA *, const char *, const char *, long double));
|
||||
static void ldfallback PARAMS((struct DATA *, const char *, const char *, long double));
|
||||
# endif
|
||||
static void dfallback __P((struct DATA *, const char *, const char *, double));
|
||||
static void dfallback PARAMS((struct DATA *, const char *, const char *, double));
|
||||
#endif
|
||||
|
||||
static char *groupnum __P((char *));
|
||||
static char *groupnum PARAMS((char *));
|
||||
|
||||
#if defined (HAVE_LONG_DOUBLE)
|
||||
# define LONGDOUBLE long double
|
||||
@@ -332,9 +332,9 @@ static char *groupnum __P((char *));
|
||||
|
||||
#ifdef DRIVER
|
||||
static void memory_error_and_abort ();
|
||||
static void *xmalloc __P((size_t));
|
||||
static void *xrealloc __P((void *, size_t));
|
||||
static void xfree __P((void *));
|
||||
static void *xmalloc PARAMS((size_t));
|
||||
static void *xrealloc PARAMS((void *, size_t));
|
||||
static void xfree PARAMS((void *));
|
||||
#else
|
||||
# include <xmalloc.h>
|
||||
#endif
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
/* spell.c -- spelling correction for pathnames. */
|
||||
|
||||
/* Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2000-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
#include <maxpath.h>
|
||||
#include <stdc.h>
|
||||
|
||||
static int mindist __P((char *, char *, char *));
|
||||
static int spdist __P((char *, char *));
|
||||
static int mindist PARAMS((char *, char *, char *));
|
||||
static int spdist PARAMS((char *, char *));
|
||||
|
||||
/*
|
||||
* `spname' and its helpers are inspired by the code in "The UNIX
|
||||
|
||||
+13
-4
@@ -62,6 +62,7 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(TM_IN_SYS_TIME)
|
||||
#include <sys/types.h>
|
||||
@@ -80,6 +81,10 @@
|
||||
|
||||
#undef strchr /* avoid AIX weirdness */
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if defined (SHELL)
|
||||
extern char *get_string_value (const char *);
|
||||
#endif
|
||||
@@ -172,7 +177,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
char *start = s;
|
||||
auto char tbuf[100];
|
||||
long off;
|
||||
int i, w;
|
||||
int i, w, oerrno;
|
||||
long y;
|
||||
static short first = 1;
|
||||
#ifdef POSIX_SEMANTICS
|
||||
@@ -217,6 +222,8 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
};
|
||||
static const char *ampm[] = { "AM", "PM", };
|
||||
|
||||
oerrno = errno;
|
||||
|
||||
if (s == NULL || format == NULL || timeptr == NULL || maxsize == 0)
|
||||
return 0;
|
||||
|
||||
@@ -642,7 +649,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
sprintf(tbuf+1, "%02ld%02ld", off/60, off%60);
|
||||
break;
|
||||
|
||||
case 'Z': /* time zone name or abbrevation */
|
||||
case 'Z': /* time zone name or abbreviation */
|
||||
#ifdef HAVE_TZNAME
|
||||
i = (daylight && timeptr->tm_isdst > 0); /* 0 or 1 */
|
||||
strcpy(tbuf, tzname[i]);
|
||||
@@ -716,6 +723,8 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
out:
|
||||
if (s < endp && *format == '\0') {
|
||||
*s = '\0';
|
||||
if (s == start)
|
||||
errno = oerrno;
|
||||
return (s - start);
|
||||
} else
|
||||
return 0;
|
||||
@@ -939,7 +948,7 @@ static char *array[] =
|
||||
"(%%H) hour (24-hour clock, 00..23) %H",
|
||||
"(%%I) hour (12-hour clock, 01..12) %I",
|
||||
"(%%M) minute (00..59) %M",
|
||||
"(%%N) Emporer/Era Name %N",
|
||||
"(%%N) Emperor/Era Name %N",
|
||||
"(%%O) Locale extensions (ignored) %O",
|
||||
"(%%R) time, 24-hour (%%H:%%M) %R",
|
||||
"(%%S) second (00..60) %S",
|
||||
@@ -960,7 +969,7 @@ static char *array[] =
|
||||
"(%%k) hour, 24-hour clock, blank pad ( 0..23) %k",
|
||||
"(%%l) hour, 12-hour clock, blank pad ( 0..12) %l",
|
||||
"(%%m) month (01..12) %m",
|
||||
"(%%o) Emporer/Era Year %o",
|
||||
"(%%o) Emperor/Era Year %o",
|
||||
"(%%p) locale's AM or PM based on 12-hour clock %p",
|
||||
"(%%r) time, 12-hour (same as %%I:%%M:%%S %%p) %r",
|
||||
"(%%u) ISO 8601: Weekday as decimal number [1 (Monday) - 7] %u",
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* stringlist.c - functions to handle a generic `list of strings' structure */
|
||||
|
||||
/* Copyright (C) 2000-2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2000-2019 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -255,7 +255,7 @@ strlist_sort (sl)
|
||||
{
|
||||
if (sl == 0 || sl->list_len == 0 || sl->list == 0)
|
||||
return;
|
||||
strvec_sort (sl->list);
|
||||
strvec_sort (sl->list, 0);
|
||||
}
|
||||
|
||||
STRINGLIST *
|
||||
|
||||
+28
-4
@@ -122,7 +122,6 @@ strvec_remove (array, name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_UNUSED
|
||||
/* Find NAME in ARRAY. Return the index of NAME, or -1 if not present.
|
||||
ARRAY should be NULL terminated. */
|
||||
int
|
||||
@@ -137,7 +136,6 @@ strvec_search (array, name)
|
||||
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate and return a new copy of ARRAY and its contents. */
|
||||
char **
|
||||
@@ -158,6 +156,28 @@ strvec_copy (array)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Comparison routine for use by qsort that conforms to the new Posix
|
||||
requirements (http://austingroupbugs.net/view.php?id=1070).
|
||||
|
||||
Perform a bytewise comparison if *S1 and *S2 collate equally. */
|
||||
int
|
||||
strvec_posixcmp (s1, s2)
|
||||
register char **s1, **s2;
|
||||
{
|
||||
int result;
|
||||
|
||||
#if defined (HAVE_STRCOLL)
|
||||
result = strcoll (*s1, *s2);
|
||||
if (result != 0)
|
||||
return result;
|
||||
#endif
|
||||
|
||||
if ((result = **s1 - **s2) == 0)
|
||||
result = strcmp (*s1, *s2);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Comparison routine for use with qsort() on arrays of strings. Uses
|
||||
strcoll(3) if available, otherwise it uses strcmp(3). */
|
||||
int
|
||||
@@ -178,10 +198,14 @@ strvec_strcmp (s1, s2)
|
||||
|
||||
/* Sort ARRAY, a null terminated array of pointers to strings. */
|
||||
void
|
||||
strvec_sort (array)
|
||||
strvec_sort (array, posix)
|
||||
char **array;
|
||||
int posix;
|
||||
{
|
||||
qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_strcmp);
|
||||
if (posix)
|
||||
qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_posixcmp);
|
||||
else
|
||||
qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_strcmp);
|
||||
}
|
||||
|
||||
/* Cons up a new array of words. The words are taken from LIST,
|
||||
|
||||
+7
-1
@@ -49,6 +49,10 @@ extern int errno;
|
||||
# define HUGE_VAL HUGE
|
||||
#endif
|
||||
|
||||
#ifndef locale_decpoint
|
||||
extern int locale_decpoint PARAMS((void));
|
||||
#endif
|
||||
|
||||
/* Convert NPTR to a double. If ENDPTR is not NULL, a pointer to the
|
||||
character after the last one used in the number is put in *ENDPTR. */
|
||||
double
|
||||
@@ -62,6 +66,7 @@ strtod (nptr, endptr)
|
||||
/* The number so far. */
|
||||
double num;
|
||||
|
||||
int radixchar;
|
||||
int got_dot; /* Found a decimal point. */
|
||||
int got_digit; /* Seen any digits. */
|
||||
|
||||
@@ -85,6 +90,7 @@ strtod (nptr, endptr)
|
||||
if (*s == '-' || *s == '+')
|
||||
++s;
|
||||
|
||||
radixchar = locale_decpoint ();
|
||||
num = 0.0;
|
||||
got_dot = 0;
|
||||
got_digit = 0;
|
||||
@@ -113,7 +119,7 @@ strtod (nptr, endptr)
|
||||
if (got_dot)
|
||||
--exponent;
|
||||
}
|
||||
else if (!got_dot && *s == '.')
|
||||
else if (!got_dot && *s == radixchar)
|
||||
/* Record that we have found the decimal point. */
|
||||
got_dot = 1;
|
||||
else
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
/* strtoimax - convert string representation of a number into an intmax_t value. */
|
||||
|
||||
/* Copyright 1999-2009 Free Software Foundation, Inc.
|
||||
/* Copyright 1999-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -45,14 +45,14 @@
|
||||
"this configure-time declaration test was not run"
|
||||
#endif
|
||||
#if !HAVE_DECL_STRTOL
|
||||
extern long strtol __P((const char *, char **, int));
|
||||
extern long strtol PARAMS((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DECL_STRTOLL
|
||||
"this configure-time declaration test was not run"
|
||||
#endif
|
||||
#if !HAVE_DECL_STRTOLL && HAVE_LONG_LONG
|
||||
extern long long strtoll __P((const char *, char **, int));
|
||||
extern long long strtoll PARAMS((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
#ifdef strtoimax
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
/* strtoumax - convert string representation of a number into an uintmax_t value. */
|
||||
|
||||
/* Copyright 1999-2009 Free Software Foundation, Inc.
|
||||
/* Copyright 1999-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -45,14 +45,14 @@
|
||||
"this configure-time declaration test was not run"
|
||||
#endif
|
||||
#if !HAVE_DECL_STRTOUL
|
||||
extern unsigned long strtoul __P((const char *, char **, int));
|
||||
extern unsigned long strtoul PARAMS((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DECL_STRTOULL
|
||||
"this configure-time declaration test was not run"
|
||||
#endif
|
||||
#if !HAVE_DECL_STRTOULL && HAVE_UNSIGNED_LONG_LONG
|
||||
extern unsigned long long strtoull __P((const char *, char **, int));
|
||||
extern unsigned long long strtoull PARAMS((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
#ifdef strtoumax
|
||||
|
||||
+22
-2
@@ -55,12 +55,18 @@ ansicstr (string, len, flags, sawc, rlen)
|
||||
int c, temp;
|
||||
char *ret, *r, *s;
|
||||
unsigned long v;
|
||||
size_t clen;
|
||||
int b, mb_cur_max;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
wchar_t wc;
|
||||
#endif
|
||||
|
||||
if (string == 0 || *string == '\0')
|
||||
return ((char *)NULL);
|
||||
|
||||
mb_cur_max = MB_CUR_MAX;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
temp = 4*len + 1;
|
||||
temp = 4*len + 4;
|
||||
if (temp < 12)
|
||||
temp = 12; /* ensure enough for eventual u32cesc */
|
||||
ret = (char *)xmalloc (temp);
|
||||
@@ -71,7 +77,21 @@ ansicstr (string, len, flags, sawc, rlen)
|
||||
{
|
||||
c = *s++;
|
||||
if (c != '\\' || *s == '\0')
|
||||
*r++ = c;
|
||||
{
|
||||
clen = 1;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if ((locale_utf8locale && (c & 0x80)) ||
|
||||
(locale_utf8locale == 0 && mb_cur_max > 0 && is_basic (c) == 0))
|
||||
{
|
||||
clen = mbrtowc (&wc, s - 1, mb_cur_max, 0);
|
||||
if (MB_INVALIDCH (clen))
|
||||
clen = 1;
|
||||
}
|
||||
#endif
|
||||
*r++ = c;
|
||||
for (--clen; clen > 0; clen--)
|
||||
*r++ = *s++;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (c = *s++)
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
/* times.c - times(3) library function */
|
||||
|
||||
/* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
# include <sys/resource.h>
|
||||
#endif /* HAVE_SYS_RESOURCE_H && HAVE_GETRUSAGE */
|
||||
|
||||
extern long get_clk_tck __P((void));
|
||||
extern long get_clk_tck PARAMS((void));
|
||||
|
||||
#define CONVTCK(r) (r.tv_sec * clk_tck + r.tv_usec / (1000000 / clk_tck))
|
||||
|
||||
@@ -58,7 +58,7 @@ times(tms)
|
||||
tms->tms_cutime = CONVTCK(ru.ru_utime);
|
||||
tms->tms_cstime = CONVTCK(ru.ru_stime);
|
||||
|
||||
if (gettimeofday(&tv, (struct timezone *) 0) < 0)
|
||||
if (gettimeofday(&tv, NULL) < 0)
|
||||
return ((clock_t)-1);
|
||||
rv = (clock_t)(CONVTCK(tv));
|
||||
#else /* !HAVE_GETRUSAGE */
|
||||
|
||||
@@ -67,6 +67,32 @@ addtimeval (d, t1, t2)
|
||||
return d;
|
||||
}
|
||||
|
||||
struct timeval *
|
||||
multimeval (d, m)
|
||||
struct timeval *d;
|
||||
int m;
|
||||
{
|
||||
time_t t;
|
||||
|
||||
t = d->tv_usec * m;
|
||||
d->tv_sec = d->tv_sec * m + t / 1000000;
|
||||
d->tv_usec = t % 1000000;
|
||||
return d;
|
||||
}
|
||||
|
||||
struct timeval *
|
||||
divtimeval (d, m)
|
||||
struct timeval *d;
|
||||
int m;
|
||||
{
|
||||
time_t t;
|
||||
|
||||
t = d->tv_sec;
|
||||
d->tv_sec = t / m;
|
||||
d->tv_usec = (d->tv_usec + 1000000 * (t % m)) / m;
|
||||
return d;
|
||||
}
|
||||
|
||||
/* Do "cpu = ((user + sys) * 10000) / real;" with timevals.
|
||||
Barely-tested code from Deven T. Corzine <deven@ties.org>. */
|
||||
int
|
||||
@@ -149,4 +175,5 @@ print_timeval (fp, tvp)
|
||||
|
||||
fprintf (fp, "%ldm%d%c%03ds", minutes, seconds, locale_decpoint (), seconds_fraction);
|
||||
}
|
||||
|
||||
#endif /* HAVE_TIMEVAL */
|
||||
|
||||
+69
-5
@@ -2,7 +2,7 @@
|
||||
* tmpfile.c - functions to create and safely open temp files for the shell.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2000-2015 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2000-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -54,8 +54,8 @@ extern int errno;
|
||||
|
||||
extern pid_t dollar_dollar_pid;
|
||||
|
||||
static char *get_sys_tmpdir __P((void));
|
||||
static char *get_tmpdir __P((int));
|
||||
static char *get_sys_tmpdir PARAMS((void));
|
||||
static char *get_tmpdir PARAMS((int));
|
||||
|
||||
static char *sys_tmpdir = (char *)NULL;
|
||||
static int ntmpfiles;
|
||||
@@ -146,9 +146,17 @@ sh_mktmpname (nameroot, flags)
|
||||
tdlen = strlen (tdir);
|
||||
|
||||
lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
|
||||
if (nameroot == 0)
|
||||
flags &= ~MT_TEMPLATE;
|
||||
|
||||
if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX)
|
||||
flags &= ~MT_TEMPLATE;
|
||||
|
||||
#ifdef USE_MKTEMP
|
||||
sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
|
||||
if (flags & MT_TEMPLATE)
|
||||
strcpy (filename, nameroot);
|
||||
else
|
||||
sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
|
||||
if (mktemp (filename) == 0)
|
||||
{
|
||||
free (filename);
|
||||
@@ -192,9 +200,17 @@ sh_mktmpfd (nameroot, flags, namep)
|
||||
tdlen = strlen (tdir);
|
||||
|
||||
lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
|
||||
if (nameroot == 0)
|
||||
flags &= ~MT_TEMPLATE;
|
||||
|
||||
if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX)
|
||||
flags &= ~MT_TEMPLATE;
|
||||
|
||||
#ifdef USE_MKSTEMP
|
||||
sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
|
||||
if (flags & MT_TEMPLATE)
|
||||
strcpy (filename, nameroot);
|
||||
else
|
||||
sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
|
||||
fd = mkstemp (filename);
|
||||
if (fd < 0 || namep == 0)
|
||||
{
|
||||
@@ -245,3 +261,51 @@ sh_mktmpfp (nameroot, flags, namep)
|
||||
close (fd);
|
||||
return fp;
|
||||
}
|
||||
|
||||
char *
|
||||
sh_mktmpdir (nameroot, flags)
|
||||
char *nameroot;
|
||||
int flags;
|
||||
{
|
||||
char *filename, *tdir, *lroot, *dirname;
|
||||
int fd, tdlen;
|
||||
|
||||
#ifdef USE_MKDTEMP
|
||||
filename = (char *)xmalloc (PATH_MAX + 1);
|
||||
tdir = get_tmpdir (flags);
|
||||
tdlen = strlen (tdir);
|
||||
|
||||
lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
|
||||
if (nameroot == 0)
|
||||
flags &= ~MT_TEMPLATE;
|
||||
|
||||
if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX)
|
||||
flags &= ~MT_TEMPLATE;
|
||||
|
||||
if (flags & MT_TEMPLATE)
|
||||
strcpy (filename, nameroot);
|
||||
else
|
||||
sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
|
||||
dirname = mkdtemp (filename);
|
||||
if (dirname == 0)
|
||||
{
|
||||
free (filename);
|
||||
filename = NULL;
|
||||
}
|
||||
return dirname;
|
||||
#else /* !USE_MKDTEMP */
|
||||
filename = (char *)NULL;
|
||||
do
|
||||
{
|
||||
filename = sh_mktmpname (nameroot, flags);
|
||||
fd = mkdir (filename, 0700);
|
||||
if (fd == 0)
|
||||
break;
|
||||
free (filename);
|
||||
filename = (char *)NULL;
|
||||
}
|
||||
while (fd < 0 && errno == EEXIST);
|
||||
|
||||
return (filename);
|
||||
#endif /* !USE_MKDTEMP */
|
||||
}
|
||||
|
||||
+21
-13
@@ -1,7 +1,7 @@
|
||||
/* uconvert - convert string representations of decimal numbers into whole
|
||||
number/fractional value pairs. */
|
||||
|
||||
/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2008,2009,2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -23,16 +23,7 @@
|
||||
|
||||
#include "bashtypes.h"
|
||||
|
||||
#if defined (TIME_WITH_SYS_TIME)
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# if defined (HAVE_SYS_TIME_H)
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
#include "posixtime.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
@@ -50,6 +41,7 @@
|
||||
do { \
|
||||
if (ip) *ip = ipart * mult; \
|
||||
if (up) *up = upart; \
|
||||
if (ep) *ep = p; \
|
||||
return (x); \
|
||||
} while (0)
|
||||
|
||||
@@ -61,12 +53,14 @@ static int multiplier[7] = { 1, 100000, 10000, 1000, 100, 10, 1 };
|
||||
/* Take a decimal number int-part[.[micro-part]] and convert it to the whole
|
||||
and fractional portions. The fractional portion is returned in
|
||||
millionths (micro); callers are responsible for multiplying appropriately.
|
||||
EP, if non-null, gets the address of the character where conversion stops.
|
||||
Return 1 if value converted; 0 if invalid integer for either whole or
|
||||
fractional parts. */
|
||||
int
|
||||
uconvert(s, ip, up)
|
||||
uconvert(s, ip, up, ep)
|
||||
char *s;
|
||||
long *ip, *up;
|
||||
char **ep;
|
||||
{
|
||||
int n, mult;
|
||||
long ipart, upart;
|
||||
@@ -102,7 +96,14 @@ uconvert(s, ip, up)
|
||||
for (n = 0; n < 6 && p[n]; n++)
|
||||
{
|
||||
if (DIGIT(p[n]) == 0)
|
||||
RETURN(0);
|
||||
{
|
||||
if (ep)
|
||||
{
|
||||
upart *= multiplier[n];
|
||||
p += n; /* To set EP */
|
||||
}
|
||||
RETURN(0);
|
||||
}
|
||||
upart = (upart * 10) + (p[n] - '0');
|
||||
}
|
||||
|
||||
@@ -112,5 +113,12 @@ uconvert(s, ip, up)
|
||||
if (n == 6 && p[6] >= '5' && p[6] <= '9')
|
||||
upart++; /* round up 1 */
|
||||
|
||||
if (ep)
|
||||
{
|
||||
p += n;
|
||||
while (DIGIT(*p))
|
||||
p++;
|
||||
}
|
||||
|
||||
RETURN(1);
|
||||
}
|
||||
|
||||
+3
-12
@@ -1,6 +1,6 @@
|
||||
/* ufuncs - sleep and alarm functions that understand fractional values */
|
||||
|
||||
/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2008,2009-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -22,16 +22,7 @@
|
||||
|
||||
#include "bashtypes.h"
|
||||
|
||||
#if defined (TIME_WITH_SYS_TIME)
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# if defined (HAVE_SYS_TIME_H)
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
#include "posixtime.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
@@ -130,7 +121,7 @@ fsleep(sec, usec)
|
||||
#endif
|
||||
e = errno;
|
||||
if (r < 0 && errno == EINTR)
|
||||
QUIT; /* just signals, no traps */
|
||||
return -1; /* caller will handle */
|
||||
errno = e;
|
||||
}
|
||||
while (r < 0 && errno == EINTR);
|
||||
|
||||
+8
-8
@@ -1,6 +1,6 @@
|
||||
/* unicode.c - functions to convert unicode characters */
|
||||
|
||||
/* Copyright (C) 2010-2016 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2010-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -50,9 +50,9 @@
|
||||
#endif /* !STREQ */
|
||||
|
||||
#if defined (HAVE_LOCALE_CHARSET)
|
||||
extern const char *locale_charset __P((void));
|
||||
extern const char *locale_charset PARAMS((void));
|
||||
#else
|
||||
extern char *get_locale_var __P((char *));
|
||||
extern char *get_locale_var PARAMS((char *));
|
||||
#endif
|
||||
|
||||
extern int locale_utf8locale;
|
||||
@@ -196,7 +196,7 @@ u32toutf8 (wc, s)
|
||||
}
|
||||
else if (wc < 0x080000000)
|
||||
{
|
||||
s[0] = (wc >> 30) | 0xf8;
|
||||
s[0] = (wc >> 30) | 0xfc;
|
||||
s[1] = ((wc >> 24) & 0x3f) | 0x80;
|
||||
s[2] = ((wc >> 18) & 0x3f) | 0x80;
|
||||
s[3] = ((wc >> 12) & 0x3f) | 0x80;
|
||||
@@ -216,21 +216,21 @@ u32toutf8 (wc, s)
|
||||
int
|
||||
u32toutf16 (c, s)
|
||||
u_bits32_t c;
|
||||
unsigned short *s;
|
||||
wchar_t *s;
|
||||
{
|
||||
int l;
|
||||
|
||||
l = 0;
|
||||
if (c < 0x0d800 || (c >= 0x0e000 && c <= 0x0ffff))
|
||||
{
|
||||
s[0] = (unsigned short) (c & 0xFFFF);
|
||||
s[0] = (wchar_t) (c & 0xFFFF);
|
||||
l = 1;
|
||||
}
|
||||
else if (c >= 0x10000 && c <= 0x010ffff)
|
||||
{
|
||||
c -= 0x010000;
|
||||
s[0] = (unsigned short)((c >> 10) + 0xd800);
|
||||
s[1] = (unsigned short)((c & 0x3ff) + 0xdc00);
|
||||
s[0] = (wchar_t)((c >> 10) + 0xd800);
|
||||
s[1] = (wchar_t)((c & 0x3ff) + 0xdc00);
|
||||
l = 2;
|
||||
}
|
||||
s[l] = 0;
|
||||
|
||||
+60
-11
@@ -76,13 +76,13 @@ utf8_mbsnlen(src, srclen, maxlen)
|
||||
return (count);
|
||||
}
|
||||
|
||||
/* Adapted from GNU gnulib */
|
||||
/* Adapted from GNU gnulib. Handles UTF-8 characters up to 4 bytes long */
|
||||
int
|
||||
utf8_mblen (s, n)
|
||||
const char *s;
|
||||
size_t n;
|
||||
{
|
||||
unsigned char c, c1;
|
||||
unsigned char c, c1, c2, c3;
|
||||
|
||||
if (s == 0)
|
||||
return (0); /* no shift states */
|
||||
@@ -97,25 +97,74 @@ utf8_mblen (s, n)
|
||||
c1 = (unsigned char)s[1];
|
||||
if (c < 0xe0)
|
||||
{
|
||||
if (n >= 2 && (s[1] ^ 0x80) < 0x40)
|
||||
if (n == 1)
|
||||
return -2;
|
||||
|
||||
/*
|
||||
* c c1
|
||||
*
|
||||
* U+0080..U+07FF C2..DF 80..BF
|
||||
*/
|
||||
|
||||
if (n >= 2 && (c1 ^ 0x80) < 0x40) /* 0x80..0xbf */
|
||||
return 2;
|
||||
}
|
||||
else if (c < 0xf0)
|
||||
{
|
||||
if (n >= 3
|
||||
&& (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
if (n == 1)
|
||||
return -2;
|
||||
|
||||
/*
|
||||
* c c1 c2
|
||||
*
|
||||
* U+0800..U+0FFF E0 A0..BF 80..BF
|
||||
* U+1000..U+CFFF E1..EC 80..BF 80..BF
|
||||
* U+D000..U+D7FF ED 80..9F 80..BF
|
||||
* U+E000..U+FFFF EE..EF 80..BF 80..BF
|
||||
*/
|
||||
|
||||
if ((c1 ^ 0x80) < 0x40
|
||||
&& (c >= 0xe1 || c1 >= 0xa0)
|
||||
&& (c != 0xed || c1 < 0xa0))
|
||||
return 3;
|
||||
{
|
||||
if (n == 2)
|
||||
return -2; /* incomplete */
|
||||
|
||||
c2 = (unsigned char)s[2];
|
||||
if ((c2 ^ 0x80) < 0x40)
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
else if (c < 0xf8)
|
||||
else if (c <= 0xf4)
|
||||
{
|
||||
if (n >= 4
|
||||
&& (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
|
||||
&& (s[3] ^ 0x80) < 0x40
|
||||
if (n == 1)
|
||||
return -2;
|
||||
|
||||
/*
|
||||
* c c1 c2 c3
|
||||
*
|
||||
* U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
|
||||
* U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
|
||||
* U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
|
||||
*/
|
||||
if (((c1 ^ 0x80) < 0x40)
|
||||
&& (c >= 0xf1 || c1 >= 0x90)
|
||||
&& (c < 0xf4 || (c == 0xf4 && c1 < 0x90)))
|
||||
return 4;
|
||||
{
|
||||
if (n == 2)
|
||||
return -2; /* incomplete */
|
||||
|
||||
c2 = (unsigned char)s[2];
|
||||
if ((c2 ^ 0x80) < 0x40)
|
||||
{
|
||||
if (n == 3)
|
||||
return -2;
|
||||
|
||||
c3 = (unsigned char)s[3];
|
||||
if ((c3 ^ 0x80) < 0x40)
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* invalid or incomplete multibyte character */
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
/* winsize.c - handle window size changes and information. */
|
||||
|
||||
/* Copyright (C) 2005-2015 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2005-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -68,9 +68,9 @@ extern int errno;
|
||||
extern int shell_tty;
|
||||
|
||||
#if defined (READLINE)
|
||||
extern void rl_set_screen_size __P((int, int));
|
||||
extern void rl_set_screen_size PARAMS((int, int));
|
||||
#endif
|
||||
extern void sh_set_lines_and_columns __P((int, int));
|
||||
extern void sh_set_lines_and_columns PARAMS((int, int));
|
||||
|
||||
void
|
||||
get_new_window_size (from_sig, rp, cp)
|
||||
|
||||
+8
-4
@@ -1,6 +1,6 @@
|
||||
/* zcatfd - copy contents of file descriptor to another */
|
||||
|
||||
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -34,8 +34,12 @@
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
extern ssize_t zread __P((int, char *, size_t));
|
||||
extern int zwrite __P((int, char *, ssize_t));
|
||||
#ifndef ZBUFSIZ
|
||||
# define ZBUFSIZ 4096
|
||||
#endif
|
||||
|
||||
extern ssize_t zread PARAMS((int, char *, size_t));
|
||||
extern int zwrite PARAMS((int, char *, ssize_t));
|
||||
|
||||
/* Dump contents of file descriptor FD to OFD. FN is the filename for
|
||||
error messages (not used right now). */
|
||||
@@ -46,7 +50,7 @@ zcatfd (fd, ofd, fn)
|
||||
{
|
||||
ssize_t nr;
|
||||
int rval;
|
||||
char lbuf[128];
|
||||
char lbuf[ZBUFSIZ];
|
||||
|
||||
rval = 0;
|
||||
while (1)
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
/* zgetline - read a line of input from a specified file descriptor and return
|
||||
a pointer to a newly-allocated buffer containing the data. */
|
||||
|
||||
/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2008-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -34,13 +34,13 @@
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
extern ssize_t zread __P((int, char *, size_t));
|
||||
extern ssize_t zreadc __P((int, char *));
|
||||
extern ssize_t zreadintr __P((int, char *, size_t));
|
||||
extern ssize_t zreadcintr __P((int, char *));
|
||||
extern ssize_t zread PARAMS((int, char *, size_t));
|
||||
extern ssize_t zreadc PARAMS((int, char *));
|
||||
extern ssize_t zreadintr PARAMS((int, char *, size_t));
|
||||
extern ssize_t zreadcintr PARAMS((int, char *));
|
||||
|
||||
typedef ssize_t breadfunc_t __P((int, char *, size_t));
|
||||
typedef ssize_t creadfunc_t __P((int, char *));
|
||||
typedef ssize_t breadfunc_t PARAMS((int, char *, size_t));
|
||||
typedef ssize_t creadfunc_t PARAMS((int, char *));
|
||||
|
||||
/* Initial memory allocation for automatic growing buffer in zreadlinec */
|
||||
#define GET_LINE_INITIAL_ALLOCATION 16
|
||||
|
||||
+9
-5
@@ -1,6 +1,6 @@
|
||||
/* zmapfd - read contents of file descriptor into a newly-allocated buffer */
|
||||
|
||||
/* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2006-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -36,7 +36,11 @@
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
extern ssize_t zread __P((int, char *, size_t));
|
||||
#ifndef ZBUFSIZ
|
||||
# define ZBUFSIZ 4096
|
||||
#endif
|
||||
|
||||
extern ssize_t zread PARAMS((int, char *, size_t));
|
||||
|
||||
/* Dump contents of file descriptor FD to *OSTR. FN is the filename for
|
||||
error messages (not used right now). */
|
||||
@@ -48,12 +52,12 @@ zmapfd (fd, ostr, fn)
|
||||
{
|
||||
ssize_t nr;
|
||||
int rval;
|
||||
char lbuf[128];
|
||||
char lbuf[ZBUFSIZ];
|
||||
char *result;
|
||||
int rsize, rind;
|
||||
|
||||
rval = 0;
|
||||
result = (char *)xmalloc (rsize = 64);
|
||||
result = (char *)xmalloc (rsize = ZBUFSIZ);
|
||||
rind = 0;
|
||||
|
||||
while (1)
|
||||
@@ -72,7 +76,7 @@ zmapfd (fd, ostr, fn)
|
||||
return -1;
|
||||
}
|
||||
|
||||
RESIZE_MALLOCED_BUFFER (result, rind, nr, rsize, 128);
|
||||
RESIZE_MALLOCED_BUFFER (result, rind, nr, rsize, ZBUFSIZ);
|
||||
memcpy (result+rind, lbuf, nr);
|
||||
rind += nr;
|
||||
}
|
||||
|
||||
+17
-8
@@ -1,6 +1,6 @@
|
||||
/* zread - read data from file descriptor into buffer with retries */
|
||||
|
||||
/* Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -37,6 +37,10 @@ extern int errno;
|
||||
# define SEEK_CUR 1
|
||||
#endif
|
||||
|
||||
#ifndef ZBUFSIZ
|
||||
# define ZBUFSIZ 4096
|
||||
#endif
|
||||
|
||||
extern int executing_builtin;
|
||||
|
||||
extern void check_signals_and_traps (void);
|
||||
@@ -55,12 +59,17 @@ zread (fd, buf, len)
|
||||
|
||||
check_signals (); /* check for signals before a blocking read */
|
||||
while ((r = read (fd, buf, len)) < 0 && errno == EINTR)
|
||||
/* XXX - bash-5.0 */
|
||||
/* We check executing_builtin and run traps here for backwards compatibility */
|
||||
if (executing_builtin)
|
||||
check_signals_and_traps (); /* XXX - should it be check_signals()? */
|
||||
else
|
||||
check_signals ();
|
||||
{
|
||||
int t;
|
||||
t = errno;
|
||||
/* XXX - bash-5.0 */
|
||||
/* We check executing_builtin and run traps here for backwards compatibility */
|
||||
if (executing_builtin)
|
||||
check_signals_and_traps (); /* XXX - should it be check_signals()? */
|
||||
else
|
||||
check_signals ();
|
||||
errno = t;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -112,7 +121,7 @@ zreadintr (fd, buf, len)
|
||||
in read(2). This does some local buffering to avoid many one-character
|
||||
calls to read(2), like those the `read' builtin performs. */
|
||||
|
||||
static char lbuf[128];
|
||||
static char lbuf[ZBUFSIZ];
|
||||
static size_t lind, lused;
|
||||
|
||||
ssize_t
|
||||
|
||||
+9
-9
@@ -1,6 +1,6 @@
|
||||
/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
|
||||
|
||||
/* Copyright (C) 1988-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1988-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -57,10 +57,10 @@ static void *xmalloc (), *xrealloc ();
|
||||
|
||||
#if !defined (HAVE_GETPW_DECLS)
|
||||
# if defined (HAVE_GETPWUID)
|
||||
extern struct passwd *getpwuid PARAMS((uid_t));
|
||||
extern struct passwd *getpwuid (uid_t);
|
||||
# endif
|
||||
# if defined (HAVE_GETPWNAM)
|
||||
extern struct passwd *getpwnam PARAMS((const char *));
|
||||
extern struct passwd *getpwnam (const char *);
|
||||
# endif
|
||||
#endif /* !HAVE_GETPW_DECLS */
|
||||
|
||||
@@ -79,8 +79,8 @@ extern struct passwd *getpwnam PARAMS((const char *));
|
||||
/* If being compiled as part of bash, these will be satisfied from
|
||||
variables.o. If being compiled as part of readline, they will
|
||||
be satisfied from shell.o. */
|
||||
extern char *sh_get_home_dir PARAMS((void));
|
||||
extern char *sh_get_env_value PARAMS((const char *));
|
||||
extern char *sh_get_home_dir (void);
|
||||
extern char *sh_get_env_value (const char *);
|
||||
|
||||
/* The default value of tilde_additional_prefixes. This is set to
|
||||
whitespace preceding a tilde so that simple programs which do not
|
||||
@@ -116,10 +116,10 @@ char **tilde_additional_prefixes = (char **)default_prefixes;
|
||||
`:' and `=~'. */
|
||||
char **tilde_additional_suffixes = (char **)default_suffixes;
|
||||
|
||||
static int tilde_find_prefix PARAMS((const char *, int *));
|
||||
static int tilde_find_suffix PARAMS((const char *));
|
||||
static char *isolate_tilde_prefix PARAMS((const char *, int *));
|
||||
static char *glue_prefix_and_suffix PARAMS((char *, const char *, int));
|
||||
static int tilde_find_prefix (const char *, int *);
|
||||
static int tilde_find_suffix (const char *);
|
||||
static char *isolate_tilde_prefix (const char *, int *);
|
||||
static char *glue_prefix_and_suffix (char *, const char *, int);
|
||||
|
||||
/* Find the start of a tilde expansion in STRING, and return the index of
|
||||
the tilde which starts the expansion. Place the length of the text
|
||||
|
||||
Reference in New Issue
Block a user