commit bash-20090813 snapshot

This commit is contained in:
Chet Ramey
2011-12-08 20:14:08 -05:00
parent 3eb2d94ad7
commit 691aebcba3
59 changed files with 13279 additions and 2804 deletions
+486
View File
@@ -0,0 +1,486 @@
/* pathexp.c -- The shell interface to the globbing library. */
/* Copyright (C) 1995-2009 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"
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashansi.h"
#include "shell.h"
#include "pathexp.h"
#include "flags.h"
#include "shmbutil.h"
#include "bashintl.h"
#include <glob/strmatch.h>
static int glob_name_is_acceptable __P((const char *));
static void ignore_globbed_names __P((char **, sh_ignore_func_t *));
#if defined (USE_POSIX_GLOB_LIBRARY)
# include <glob.h>
typedef int posix_glob_errfunc_t __P((const char *, int));
#else
# include <glob/glob.h>
#endif
/* Control whether * matches .files in globbing. */
int glob_dot_filenames;
/* Control whether the extended globbing features are enabled. */
int extended_glob = EXTzg;
/* Control enabling special handling of `**' */
int glob_star = 0;
/* Return nonzero if STRING has any unquoted special globbing chars in it. */
int
unquoted_glob_pattern_p (string)
register char *string;
{
register int c;
char *send;
int open;
DECLARE_MBSTATE;
open = 0;
send = string + strlen (string);
while (c = *string++)
{
switch (c)
{
case '?':
case '*':
return (1);
case '[':
open++;
continue;
case ']':
if (open)
return (1);
continue;
case '+':
case '@':
case '!':
if (*string == '(') /*)*/
return (1);
continue;
case CTLESC:
case '\\':
if (*string++ == '\0')
return (0);
}
/* Advance one fewer byte than an entire multibyte character to
account for the auto-increment in the loop above. */
#ifdef HANDLE_MULTIBYTE
string--;
ADVANCE_CHAR_P (string, send - string);
string++;
#else
ADVANCE_CHAR_P (string, send - string);
#endif
}
return (0);
}
/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to
be quoted to match itself. */
static inline int
ere_char (c)
int c;
{
switch (c)
{
case '.':
case '[':
case '\\':
case '(':
case ')':
case '*':
case '+':
case '?':
case '{':
case '|':
case '^':
case '$':
return 1;
default:
return 0;
}
return (0);
}
int
glob_char_p (s)
const char *s;
{
switch (*s)
{
case '*':
case '[':
case ']':
case '?':
case '\\':
return 1;
case '+':
case '@':
case '!':
if (s[1] == '(') /*(*/
return 1;
break;
}
return 0;
}
/* PATHNAME can contain characters prefixed by CTLESC; this indicates
that the character is to be quoted. We quote it here in the style
that the glob library recognizes. If flags includes QGLOB_CVTNULL,
we change quoted null strings (pathname[0] == CTLNUL) into empty
strings (pathname[0] == 0). If this is called after quote removal
is performed, (flags & QGLOB_CVTNULL) should be 0; if called when quote
removal has not been done (for example, before attempting to match a
pattern while executing a case statement), flags should include
QGLOB_CVTNULL. If flags includes QGLOB_FILENAME, appropriate quoting
to match a filename should be performed. */
char *
quote_string_for_globbing (pathname, qflags)
const char *pathname;
int qflags;
{
char *temp;
register int i, j;
temp = (char *)xmalloc (strlen (pathname) + 1);
if ((qflags & QGLOB_CVTNULL) && QUOTED_NULL (pathname))
{
temp[0] = '\0';
return temp;
}
for (i = j = 0; pathname[i]; i++)
{
if (pathname[i] == CTLESC)
{
if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
continue;
if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
continue;
temp[j++] = '\\';
i++;
if (pathname[i] == '\0')
break;
}
else if (pathname[i] == '\\')
{
temp[j++] = '\\';
i++;
if (pathname[i] == '\0')
break;
}
temp[j++] = pathname[i];
}
temp[j] = '\0';
return (temp);
}
char *
quote_globbing_chars (string)
char *string;
{
size_t slen;
char *temp, *s, *t, *send;
DECLARE_MBSTATE;
slen = strlen (string);
send = string + slen;
temp = (char *)xmalloc (slen * 2 + 1);
for (t = temp, s = string; *s; )
{
if (glob_char_p (s))
*t++ = '\\';
/* Copy a single (possibly multibyte) character from s to t,
incrementing both. */
COPY_CHAR_P (t, s, send);
}
*t = '\0';
return temp;
}
/* Call the glob library to do globbing on PATHNAME. */
char **
shell_glob_filename (pathname)
const char *pathname;
{
#if defined (USE_POSIX_GLOB_LIBRARY)
register int i;
char *temp, **results;
glob_t filenames;
int glob_flags;
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
filenames.gl_offs = 0;
# if defined (GLOB_PERIOD)
glob_flags = glob_dot_filenames ? GLOB_PERIOD : 0;
# else
glob_flags = 0;
# endif /* !GLOB_PERIOD */
glob_flags |= (GLOB_ERR | GLOB_DOOFFS);
i = glob (temp, glob_flags, (posix_glob_errfunc_t *)NULL, &filenames);
free (temp);
if (i == GLOB_NOSPACE || i == GLOB_ABORTED)
return ((char **)NULL);
else if (i == GLOB_NOMATCH)
filenames.gl_pathv = (char **)NULL;
else if (i != 0) /* other error codes not in POSIX.2 */
filenames.gl_pathv = (char **)NULL;
results = filenames.gl_pathv;
if (results && ((GLOB_FAILED (results)) == 0))
{
if (should_ignore_glob_matches ())
ignore_glob_matches (results);
if (results && results[0])
strvec_sort (results);
else
{
FREE (results);
results = (char **)NULL;
}
}
return (results);
#else /* !USE_POSIX_GLOB_LIBRARY */
char *temp, **results;
noglob_dot_filenames = glob_dot_filenames == 0;
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
results = glob_filename (temp, glob_star ? GX_GLOBSTAR : 0);
free (temp);
if (results && ((GLOB_FAILED (results)) == 0))
{
if (should_ignore_glob_matches ())
ignore_glob_matches (results);
if (results && results[0])
strvec_sort (results);
else
{
FREE (results);
results = (char **)&glob_error_return;
}
}
return (results);
#endif /* !USE_POSIX_GLOB_LIBRARY */
}
/* Stuff for GLOBIGNORE. */
static struct ignorevar globignore =
{
"GLOBIGNORE",
(struct ign *)0,
0,
(char *)0,
(sh_iv_item_func_t *)0,
};
/* Set up to ignore some glob matches because the value of GLOBIGNORE
has changed. If GLOBIGNORE is being unset, we also need to disable
the globbing of filenames beginning with a `.'. */
void
setup_glob_ignore (name)
char *name;
{
char *v;
v = get_string_value (name);
setup_ignore_patterns (&globignore);
if (globignore.num_ignores)
glob_dot_filenames = 1;
else if (v == 0)
glob_dot_filenames = 0;
}
int
should_ignore_glob_matches ()
{
return globignore.num_ignores;
}
/* Return 0 if NAME matches a pattern in the globignore.ignores list. */
static int
glob_name_is_acceptable (name)
const char *name;
{
struct ign *p;
int flags;
/* . and .. are never matched */
if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
return (0);
flags = FNM_PATHNAME | FNMATCH_EXTFLAG;
for (p = globignore.ignores; p->val; p++)
{
if (strmatch (p->val, (char *)name, flags) != FNM_NOMATCH)
return (0);
}
return (1);
}
/* Internal function to test whether filenames in NAMES should be
ignored. NAME_FUNC is a pointer to a function to call with each
name. It returns non-zero if the name is acceptable to the particular
ignore function which called _ignore_names; zero if the name should
be removed from NAMES. */
static void
ignore_globbed_names (names, name_func)
char **names;
sh_ignore_func_t *name_func;
{
char **newnames;
int n, i;
for (i = 0; names[i]; i++)
;
newnames = strvec_create (i + 1);
for (n = i = 0; names[i]; i++)
{
if ((*name_func) (names[i]))
newnames[n++] = names[i];
else
free (names[i]);
}
newnames[n] = (char *)NULL;
if (n == 0)
{
names[0] = (char *)NULL;
free (newnames);
return;
}
/* Copy the acceptable names from NEWNAMES back to NAMES and set the
new array end. */
for (n = 0; newnames[n]; n++)
names[n] = newnames[n];
names[n] = (char *)NULL;
free (newnames);
}
void
ignore_glob_matches (names)
char **names;
{
if (globignore.num_ignores == 0)
return;
ignore_globbed_names (names, glob_name_is_acceptable);
}
void
setup_ignore_patterns (ivp)
struct ignorevar *ivp;
{
int numitems, maxitems, ptr;
char *colon_bit, *this_ignoreval;
struct ign *p;
this_ignoreval = get_string_value (ivp->varname);
/* If nothing has changed then just exit now. */
if ((this_ignoreval && ivp->last_ignoreval && STREQ (this_ignoreval, ivp->last_ignoreval)) ||
(!this_ignoreval && !ivp->last_ignoreval))
return;
/* Oops. The ignore variable has changed. Re-parse it. */
ivp->num_ignores = 0;
if (ivp->ignores)
{
for (p = ivp->ignores; p->val; p++)
free(p->val);
free (ivp->ignores);
ivp->ignores = (struct ign *)NULL;
}
if (ivp->last_ignoreval)
{
free (ivp->last_ignoreval);
ivp->last_ignoreval = (char *)NULL;
}
if (this_ignoreval == 0 || *this_ignoreval == '\0')
return;
ivp->last_ignoreval = savestring (this_ignoreval);
numitems = maxitems = ptr = 0;
while (colon_bit = extract_colon_unit (this_ignoreval, &ptr))
{
if (numitems + 1 >= maxitems)
{
maxitems += 10;
ivp->ignores = (struct ign *)xrealloc (ivp->ignores, maxitems * sizeof (struct ign));
}
ivp->ignores[numitems].val = colon_bit;
ivp->ignores[numitems].len = strlen (colon_bit);
ivp->ignores[numitems].flags = 0;
if (ivp->item_func)
(*ivp->item_func) (&ivp->ignores[numitems]);
numitems++;
}
ivp->ignores[numitems].val = (char *)NULL;
ivp->num_ignores = numitems;
}
+98
View File
@@ -8465,3 +8465,101 @@ bashline.c
execute_cmd.c
- change to execute_command_internal to make [[ ... ]] conditional
command subject to settings of `set -e' and the ERR trap
8/14
----
execute_cmd.c
- change to execute_command_internal to make (( ... )) arithmetic
command subject to settings of `set -e' and the ERR trap
lib/readline/text.c
- new bindable function, rl_skip_csi_sequence, reads the characters
that make up a control sequence as defined by ECMA-48. Sequences
are introduced by the Control Sequence Indicator (CSI) and
contain a defined set of characters. Insert, End, Page Up and so
on are CSI sequences. Report and code from Andy Koppe
<andy.koppe@gmail.com>
lib/readline/readline.h
- extern declaration for rl_skip_csi_sequence
lib/readline/funmap.c
- new bindable command "skip-csi-sequence", runs rl_skip_csi_sequence
doc/bash.1,lib/readline/doc/{readline.3,rluser.texi}
- documented new bindable command "skip-csi-sequence", unbound by
default
builtins/evalfile.c
- fix _evalfile to remove embedded null bytes from the file read
into the string. Report and proposed fix from Roman Rakus
<rrakus@redhat.com>
{configure,config.h}.in
- check for syslog(3), define HAVE_SYSLOG
- check for syslog.h, define HAVE_SYSLOG_H
config-top.h
- new define SYSLOG_HISTORY, disabled by default
config-bot.h
- if HAVE_SYSLOG or HAVE_SYSLOG_H are not defined, undef SYSLOG_HISTORY
bashhist.c
- if SYSLOG_HISTORY is defined, call bash_syslog_history with the
line added to the history in bash_add_history.
- new function, bash_syslog_history(line), sends line to syslog at
user.info. The line is truncated to send no more than 600
(SYSLOG_MAXLEN) bytes to syslog. Feature requested by many, and
required by some national laws
sig.c
- in termsig_handler, resend SIGHUP to children if subshell_environment
indicates we're a shell performing command or process substitution
jobs.c
- add CHECK_TERMSIG calls to wait_for in addition to the ones in
waitchld()
builtins/shopt.def
- new functions set_bashopts, parse_bashopts, and initialize_bashopts
to manage new environment variable $BASHOPTS, like $SHELLOPTS but
for shopt options
- change toggle_shopts to call set_bashopts after setting options, so
$BASHOPTS reflects new values
shell.c
- call initialize_bashopts after calling initialize_shell_options at
shell startup
configure.in
- new configure `enable' option --enable-exended-tglob-default, to
set the initial default value of the `extglob' shell option
config.h
- new define, EXTGLOB_DEFAULT, controlled by the `extended-glob-default'
configure option
pathexp.c
- initialize extended_glob variable to EXTGLOB_DEFAULT
doc/{bash.1,bashref.texi}
- document new $BASHOPTS variable and its behavior
doc/bashref.texi
- document new --enable-extended-glob-default configure option
8/16
----
print_cmd.c
- new variables: xtrace_fd and xtrace_fp, the file descriptor and
FILE * to which we send `set -x' tracing output. If fd == -1
then fp == STDERR, the default mode
- new function xtrace_init, sets xtrace_fd == -1 and xtrace_fp = stderr
- new function xtrace_set (fd, fp), sets xtrace_fd and xtrace_fp
to the arguments
- change xtrace functions to fprintf to xtrace_fp instead of stderr
shell.c
- call xtrace_init() very early in main()
+103
View File
@@ -8459,3 +8459,106 @@ bashline.c
rather than the beginning. It doesn't matter where you start if
the results are sorted, and dabbrev-expand is supposed to offer
the most recent completions first
8/12
----
execute_cmd.c
- change to execute_command_internal to make [[ ... ]] conditional
command subject to settings of `set -e' and the ERR trap
8/14
----
execute_cmd.c
- change to execute_command_internal to make (( ... )) arithmetic
command subject to settings of `set -e' and the ERR trap
lib/readline/text.c
- new bindable function, rl_skip_csi_sequence, reads the characters
that make up a control sequence as defined by ECMA-48. Sequences
are introduced by the Control Sequence Indicator (CSI) and
contain a defined set of characters. Insert, End, Page Up and so
on are CSI sequences. Report and code from Andy Koppe
<andy.koppe@gmail.com>
lib/readline/readline.h
- extern declaration for rl_skip_csi_sequence
lib/readline/funmap.c
- new bindable command "skip-csi-sequence", runs rl_skip_csi_sequence
doc/bash.1,lib/readline/doc/{readline.3,rluser.texi}
- documented new bindable command "skip-csi-sequence", unbound by
default
builtins/evalfile.c
- fix _evalfile to remove embedded null bytes from the file read
into the string. Report and proposed fix from Roman Rakus
<rrakus@redhat.com>
{configure,config.h}.in
- check for syslog(3), define HAVE_SYSLOG
- check for syslog.h, define HAVE_SYSLOG_H
config-top.h
- new define SYSLOG_HISTORY, disabled by default
config-bot.h
- if HAVE_SYSLOG or HAVE_SYSLOG_H are not defined, undef SYSLOG_HISTORY
bashhist.c
- if SYSLOG_HISTORY is defined, call bash_syslog_history with the
line added to the history in bash_add_history.
- new function, bash_syslog_history(line), sends line to syslog at
user.info. The line is truncated to send no more than 600
(SYSLOG_MAXLEN) bytes to syslog. Feature requested by many, and
required by some national laws
sig.c
- in termsig_handler, resend SIGHUP to children if subshell_environment
indicates we're a shell performing command or process substitution
jobs.c
- add CHECK_TERMSIG calls to wait_for in addition to the ones in
waitchld()
builtins/shopt.def
- new functions set_bashopts, parse_bashopts, and initialize_bashopts
to manage new environment variable $BASHOPTS, like $SHELLOPTS but
for shopt options
- change toggle_shopts to call set_bashopts after setting options, so
$BASHOPTS reflects new values
shell.c
- call initialize_bashopts after calling initialize_shell_options at
shell startup
configure.in
- new configure `enable' option --enable-exended-tglob-default, to
set the initial default value of the `extglob' shell option
config.h
- new define, EXTGLOB_DEFAULT, controlled by the `extended-glob-default'
configure option
pathexp.c
- initialize extended_glob variable to EXTGLOB_DEFAULT
doc/{bash.1,bashref.texi}
- document new $BASHOPTS variable and its behavior
doc/bashref.texi
- document new --enable-extended-glob-default configure option
8/16
----
print_cmd.c
- new variables: xtrace_fd and xtrace_fp, the file descriptor and
FILE * to which we send `set -x' tracing output. If fd == -1
then fp == STDERR, the default mode
- new function xtrace_init, sets xtrace_fd == -1 and xtrace_fp = stderr
- new function xtrace_set (fd, fp), sets xtrace_fd and xtrace_fp
to the arguments
shell.c
- call xtrace_init() very early in main()
+410 -474
View File
File diff suppressed because it is too large Load Diff
+1720 -1723
View File
File diff suppressed because it is too large Load Diff
+28
View File
@@ -38,6 +38,10 @@
#include "bashintl.h"
#if defined (SYSLOG_HISTORY)
# include <syslog.h>
#endif
#include "shell.h"
#include "flags.h"
#include "input.h"
@@ -691,6 +695,26 @@ check_add_history (line, force)
return 0;
}
#if defined (SYSLOG_HISTORY)
#define SYSLOG_MAXLEN 600
void
bash_syslog_history (line)
const char *line;
{
char trunc[SYSLOG_MAXLEN];
if (strlen(line) < SYSLOG_MAXLEN)
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY: PID=%d UID=%d %s", getpid(), current_user.uid, line);
else
{
strncpy (trunc, line, SYSLOG_MAXLEN);
trunc[SYSLOG_MAXLEN - 1] = '\0';
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY (TRUNCATED): PID=%d UID=%d %s", getpid(), current_user.uid, trunc);
}
}
#endif
/* Add a line to the history list.
The variable COMMAND_ORIENTED_HISTORY controls the style of history
remembering; when non-zero, and LINE is not the first line of a
@@ -746,6 +770,10 @@ bash_add_history (line)
if (add_it)
really_add_history (line);
#if defined (SYSLOG_HISTORY)
bash_syslog_history (line);
#endif
using_history ();
}
+898
View File
@@ -0,0 +1,898 @@
/* bashhist.c -- bash interface to the GNU history library. */
/* Copyright (C) 1993-2009 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 (HISTORY)
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include "bashtypes.h"
#include <stdio.h>
#include <errno.h>
#include "bashansi.h"
#include "posixstat.h"
#include "filecntl.h"
#include "bashintl.h"
#if defined (SYSLOG_HISTORY)
# include <syslog.h>
#endif
#include "shell.h"
#include "flags.h"
#include "input.h"
#include "parser.h" /* for the struct dstack stuff. */
#include "pathexp.h" /* for the struct ignorevar stuff */
#include "bashhist.h" /* matching prototypes and declarations */
#include "builtins/common.h"
#include <readline/history.h>
#include <glob/glob.h>
#include <glob/strmatch.h>
#if defined (READLINE)
# include "bashline.h"
extern int rl_done, rl_dispatching; /* should really include readline.h */
#endif
#if !defined (errno)
extern int errno;
#endif
static int histignore_item_func __P((struct ign *));
static int check_history_control __P((char *));
static void hc_erasedups __P((char *));
static void really_add_history __P((char *));
static struct ignorevar histignore =
{
"HISTIGNORE",
(struct ign *)0,
0,
(char *)0,
(sh_iv_item_func_t *)histignore_item_func,
};
#define HIGN_EXPAND 0x01
/* Declarations of bash history variables. */
/* Non-zero means to remember lines typed to the shell on the history
list. This is different than the user-controlled behaviour; this
becomes zero when we read lines from a file, for example. */
int remember_on_history = 1;
int enable_history_list = 1; /* value for `set -o history' */
/* The number of lines that Bash has added to this history session. The
difference between the number of the top element in the history list
(offset from history_base) and the number of lines in the history file.
Appending this session's history to the history file resets this to 0. */
int history_lines_this_session;
/* The number of lines that Bash has read from the history file. */
int history_lines_in_file;
#if defined (BANG_HISTORY)
/* Non-zero means do no history expansion on this line, regardless
of what history_expansion says. */
int history_expansion_inhibited;
#endif
/* With the old default, every line was saved in the history individually.
I.e., if the user enters:
bash$ for i in a b c
> do
> echo $i
> done
Each line will be individually saved in the history.
bash$ history
10 for i in a b c
11 do
12 echo $i
13 done
14 history
If the variable command_oriented_history is set, multiple lines
which form one command will be saved as one history entry.
bash$ for i in a b c
> do
> echo $i
> done
bash$ history
10 for i in a b c
do
echo $i
done
11 history
The user can then recall the whole command all at once instead
of just being able to recall one line at a time.
This is now enabled by default.
*/
int command_oriented_history = 1;
/* Set to 1 if the first line of a possibly-multi-line command was saved
in the history list. Managed by maybe_add_history(), but global so
the history-manipluating builtins can see it. */
int current_command_first_line_saved = 0;
/* Non-zero means to store newlines in the history list when using
command_oriented_history rather than trying to use semicolons. */
int literal_history;
/* Non-zero means to append the history to the history file at shell
exit, even if the history has been stifled. */
int force_append_history;
/* A nit for picking at history saving. Flags have the following values:
Value == 0 means save all lines parsed by the shell on the history.
Value & HC_IGNSPACE means save all lines that do not start with a space.
Value & HC_IGNDUPS means save all lines that do not match the last
line saved.
Value & HC_ERASEDUPS means to remove all other matching lines from the
history list before saving the latest line. */
int history_control;
/* Set to 1 if the last command was added to the history list successfully
as a separate history entry; set to 0 if the line was ignored or added
to a previous entry as part of command-oriented-history processing. */
int hist_last_line_added;
/* Set to 1 if builtins/history.def:push_history added the last history
entry. */
int hist_last_line_pushed;
#if defined (READLINE)
/* If non-zero, and readline is being used, the user is offered the
chance to re-edit a failed history expansion. */
int history_reediting;
/* If non-zero, and readline is being used, don't directly execute a
line with history substitution. Reload it into the editing buffer
instead and let the user further edit and confirm with a newline. */
int hist_verify;
#endif /* READLINE */
/* Non-zero means to not save function definitions in the history list. */
int dont_save_function_defs;
/* Variables declared in other files used here. */
extern int current_command_line_count;
extern struct dstack dstack;
static int bash_history_inhibit_expansion __P((char *, int));
#if defined (READLINE)
static void re_edit __P((char *));
#endif
static int history_expansion_p __P((char *));
static int shell_comment __P((char *));
static int should_expand __P((char *));
static HIST_ENTRY *last_history_entry __P((void));
static char *expand_histignore_pattern __P((char *));
static int history_should_ignore __P((char *));
/* Is the history expansion starting at string[i] one that should not
be expanded? */
static int
bash_history_inhibit_expansion (string, i)
char *string;
int i;
{
/* The shell uses ! as a pattern negation character in globbing [...]
expressions, so let those pass without expansion. */
if (i > 0 && (string[i - 1] == '[') && member (']', string + i + 1))
return (1);
/* The shell uses ! as the indirect expansion character, so let those
expansions pass as well. */
else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' &&
member ('}', string + i + 1))
return (1);
#if defined (EXTENDED_GLOB)
else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
return (1);
#endif
else
return (0);
}
void
bash_initialize_history ()
{
history_quotes_inhibit_expansion = 1;
history_search_delimiter_chars = ";&()|<>";
history_inhibit_expansion_function = bash_history_inhibit_expansion;
#if defined (BANG_HISTORY)
sv_histchars ("histchars");
#endif
}
void
bash_history_reinit (interact)
int interact;
{
#if defined (BANG_HISTORY)
history_expansion = interact != 0;
history_expansion_inhibited = 1;
#endif
remember_on_history = enable_history_list = interact != 0;
history_inhibit_expansion_function = bash_history_inhibit_expansion;
}
void
bash_history_disable ()
{
remember_on_history = 0;
#if defined (BANG_HISTORY)
history_expansion_inhibited = 1;
#endif
}
void
bash_history_enable ()
{
remember_on_history = 1;
#if defined (BANG_HISTORY)
history_expansion_inhibited = 0;
#endif
history_inhibit_expansion_function = bash_history_inhibit_expansion;
sv_history_control ("HISTCONTROL");
sv_histignore ("HISTIGNORE");
}
/* Load the history list from the history file. */
void
load_history ()
{
char *hf;
/* Truncate history file for interactive shells which desire it.
Note that the history file is automatically truncated to the
size of HISTSIZE if the user does not explicitly set the size
differently. */
set_if_not ("HISTSIZE", "500");
sv_histsize ("HISTSIZE");
set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
sv_histsize ("HISTFILESIZE");
/* Read the history in HISTFILE into the history list. */
hf = get_string_value ("HISTFILE");
if (hf && *hf && file_exists (hf))
{
read_history (hf);
using_history ();
history_lines_in_file = where_history ();
}
}
void
bash_clear_history ()
{
clear_history ();
history_lines_this_session = 0;
}
/* Delete and free the history list entry at offset I. */
int
bash_delete_histent (i)
int i;
{
HIST_ENTRY *discard;
discard = remove_history (i);
if (discard)
free_history_entry (discard);
history_lines_this_session--;
return 1;
}
int
bash_delete_last_history ()
{
register int i;
HIST_ENTRY **hlist, *histent;
int r;
hlist = history_list ();
if (hlist == NULL)
return 0;
for (i = 0; hlist[i]; i++)
;
i--;
/* History_get () takes a parameter that must be offset by history_base. */
histent = history_get (history_base + i); /* Don't free this */
if (histent == NULL)
return 0;
r = bash_delete_histent (i);
if (where_history () > history_length)
history_set_pos (history_length);
return r;
}
#ifdef INCLUDE_UNUSED
/* Write the existing history out to the history file. */
void
save_history ()
{
char *hf;
hf = get_string_value ("HISTFILE");
if (hf && *hf && file_exists (hf))
{
/* Append only the lines that occurred this session to
the history file. */
using_history ();
if (history_lines_this_session < where_history () || force_append_history)
append_history (history_lines_this_session, hf);
else
write_history (hf);
sv_histsize ("HISTFILESIZE");
}
}
#endif
int
maybe_append_history (filename)
char *filename;
{
int fd, result;
struct stat buf;
result = EXECUTION_SUCCESS;
if (history_lines_this_session && (history_lines_this_session < where_history ()))
{
/* If the filename was supplied, then create it if necessary. */
if (stat (filename, &buf) == -1 && errno == ENOENT)
{
fd = open (filename, O_WRONLY|O_CREAT, 0600);
if (fd < 0)
{
builtin_error (_("%s: cannot create: %s"), filename, strerror (errno));
return (EXECUTION_FAILURE);
}
close (fd);
}
result = append_history (history_lines_this_session, filename);
history_lines_in_file += history_lines_this_session;
history_lines_this_session = 0;
}
return (result);
}
/* If this is an interactive shell, then append the lines executed
this session to the history file. */
int
maybe_save_shell_history ()
{
int result;
char *hf;
result = 0;
if (history_lines_this_session)
{
hf = get_string_value ("HISTFILE");
if (hf && *hf)
{
/* If the file doesn't exist, then create it. */
if (file_exists (hf) == 0)
{
int file;
file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (file != -1)
close (file);
}
/* Now actually append the lines if the history hasn't been
stifled. If the history has been stifled, rewrite the
history file. */
using_history ();
if (history_lines_this_session <= where_history () || force_append_history)
{
result = append_history (history_lines_this_session, hf);
history_lines_in_file += history_lines_this_session;
}
else
{
result = write_history (hf);
history_lines_in_file = history_lines_this_session;
}
history_lines_this_session = 0;
sv_histsize ("HISTFILESIZE");
}
}
return (result);
}
#if defined (READLINE)
/* Tell readline () that we have some text for it to edit. */
static void
re_edit (text)
char *text;
{
if (bash_input.type == st_stdin)
bash_re_edit (text);
}
#endif /* READLINE */
/* Return 1 if this line needs history expansion. */
static int
history_expansion_p (line)
char *line;
{
register char *s;
for (s = line; *s; s++)
if (*s == history_expansion_char || *s == history_subst_char)
return 1;
return 0;
}
/* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then
print the results of expanding the line if there were any changes.
If there is an error, return NULL, otherwise the expanded line is
returned. If ADDIT is non-zero the line is added to the history
list after history expansion. ADDIT is just a suggestion;
REMEMBER_ON_HISTORY can veto, and does.
Right now this does history expansion. */
char *
pre_process_line (line, print_changes, addit)
char *line;
int print_changes, addit;
{
char *history_value;
char *return_value;
int expanded;
return_value = line;
expanded = 0;
# if defined (BANG_HISTORY)
/* History expand the line. If this results in no errors, then
add that line to the history if ADDIT is non-zero. */
if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
{
expanded = history_expand (line, &history_value);
if (expanded)
{
if (print_changes)
{
if (expanded < 0)
internal_error ("%s", history_value);
#if defined (READLINE)
else if (hist_verify == 0 || expanded == 2)
#else
else
#endif
fprintf (stderr, "%s\n", history_value);
}
/* If there was an error, return NULL. */
if (expanded < 0 || expanded == 2) /* 2 == print only */
{
# if defined (READLINE)
if (expanded == 2 && rl_dispatching == 0 && *history_value)
# else
if (expanded == 2 && *history_value)
# endif /* !READLINE */
maybe_add_history (history_value);
free (history_value);
# if defined (READLINE)
/* New hack. We can allow the user to edit the
failed history expansion. */
if (history_reediting && expanded < 0 && rl_done)
re_edit (line);
# endif /* READLINE */
return ((char *)NULL);
}
# if defined (READLINE)
if (hist_verify && expanded == 1)
{
re_edit (history_value);
return ((char *)NULL);
}
# endif
}
/* Let other expansions know that return_value can be free'ed,
and that a line has been added to the history list. Note
that we only add lines that have something in them. */
expanded = 1;
return_value = history_value;
}
# endif /* BANG_HISTORY */
if (addit && remember_on_history && *return_value)
maybe_add_history (return_value);
#if 0
if (expanded == 0)
return_value = savestring (line);
#endif
return (return_value);
}
/* Return 1 if the first non-whitespace character in LINE is a `#', indicating
* that the line is a shell comment. */
static int
shell_comment (line)
char *line;
{
char *p;
for (p = line; p && *p && whitespace (*p); p++)
;
return (p && *p == '#');
}
#ifdef INCLUDE_UNUSED
/* Remove shell comments from LINE. A `#' and anything after it is a comment.
This isn't really useful yet, since it doesn't handle quoting. */
static char *
filter_comments (line)
char *line;
{
char *p;
for (p = line; p && *p && *p != '#'; p++)
;
if (p && *p == '#')
*p = '\0';
return (line);
}
#endif
/* Check LINE against what HISTCONTROL says to do. Returns 1 if the line
should be saved; 0 if it should be discarded. */
static int
check_history_control (line)
char *line;
{
HIST_ENTRY *temp;
int r;
if (history_control == 0)
return 1;
/* ignorespace or ignoreboth */
if ((history_control & HC_IGNSPACE) && *line == ' ')
return 0;
/* ignoredups or ignoreboth */
if (history_control & HC_IGNDUPS)
{
using_history ();
temp = previous_history ();
r = (temp == 0 || STREQ (temp->line, line) == 0);
using_history ();
if (r == 0)
return r;
}
return 1;
}
/* Remove all entries matching LINE from the history list. Triggered when
HISTCONTROL includes `erasedups'. */
static void
hc_erasedups (line)
char *line;
{
HIST_ENTRY *temp;
int r;
using_history ();
while (temp = previous_history ())
{
if (STREQ (temp->line, line))
{
r = where_history ();
remove_history (r);
}
}
using_history ();
}
/* Add LINE to the history list, handling possibly multi-line compound
commands. We note whether or not we save the first line of each command
(which is usually the entire command and history entry), and don't add
the second and subsequent lines of a multi-line compound command if we
didn't save the first line. We don't usually save shell comment lines in
compound commands in the history, because they could have the effect of
commenting out the rest of the command when the entire command is saved as
a single history entry (when COMMAND_ORIENTED_HISTORY is enabled). If
LITERAL_HISTORY is set, we're saving lines in the history with embedded
newlines, so it's OK to save comment lines. We also make sure to save
multiple-line quoted strings or other constructs. */
void
maybe_add_history (line)
char *line;
{
hist_last_line_added = 0;
/* Don't use the value of history_control to affect the second
and subsequent lines of a multi-line command (old code did
this only when command_oriented_history is enabled). */
if (current_command_line_count > 1)
{
if (current_command_first_line_saved &&
(literal_history || dstack.delimiter_depth != 0 || shell_comment (line) == 0))
bash_add_history (line);
return;
}
/* This is the first line of a (possible multi-line) command. Note whether
or not we should save the first line and remember it. */
current_command_first_line_saved = check_add_history (line, 0);
}
/* Just check LINE against HISTCONTROL and HISTIGNORE and add it to the
history if it's OK. Used by `history -s' as well as maybe_add_history().
Returns 1 if the line was saved in the history, 0 otherwise. */
int
check_add_history (line, force)
char *line;
int force;
{
if (check_history_control (line) && history_should_ignore (line) == 0)
{
/* We're committed to saving the line. If the user has requested it,
remove other matching lines from the history. */
if (history_control & HC_ERASEDUPS)
hc_erasedups (line);
if (force)
{
really_add_history (line);
using_history ();
}
else
bash_add_history (line);
return 1;
}
return 0;
}
#if defined (SYSLOG_HISTORY)
#define SYSLOG_MAXLEN 600
void
bash_syslog_history (line)
const char *line;
{
char trunc[SYSLOG_MAXLEN];
if (strlen(line) < SYSLOG_MAXLEN)
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY: PID=%d UID=%d %s", getpid(), current_user.uid, line);
else
{
strcpy (trunc, line, SYSLOG_MAXLEN);
trunc[SYSLOG_MAXLEN - 1] = '\0';
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY (TRUNCATED): PID=%d UID=%d %s", getpid(), current_user.uid, trunc);
}
}
#endif
/* Add a line to the history list.
The variable COMMAND_ORIENTED_HISTORY controls the style of history
remembering; when non-zero, and LINE is not the first line of a
complete parser construct, append LINE to the last history line instead
of adding it as a new line. */
void
bash_add_history (line)
char *line;
{
int add_it, offset, curlen;
HIST_ENTRY *current, *old;
char *chars_to_add, *new_line;
add_it = 1;
if (command_oriented_history && current_command_line_count > 1)
{
chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
using_history ();
current = previous_history ();
if (current)
{
/* If the previous line ended with an escaped newline (escaped
with backslash, but otherwise unquoted), then remove the quoted
newline, since that is what happens when the line is parsed. */
curlen = strlen (current->line);
if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
current->line[curlen - 2] != '\\')
{
current->line[curlen - 1] = '\0';
curlen--;
chars_to_add = "";
}
new_line = (char *)xmalloc (1
+ curlen
+ strlen (line)
+ strlen (chars_to_add));
sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
offset = where_history ();
old = replace_history_entry (offset, new_line, current->data);
free (new_line);
if (old)
free_history_entry (old);
add_it = 0;
}
}
if (add_it)
really_add_history (line);
#if defined (SYSLOG_HISTORY)
bash_syslog_history (line);
#endif
using_history ();
}
static void
really_add_history (line)
char *line;
{
hist_last_line_added = 1;
hist_last_line_pushed = 0;
add_history (line);
history_lines_this_session++;
}
int
history_number ()
{
using_history ();
return (remember_on_history ? history_base + where_history () : 1);
}
static int
should_expand (s)
char *s;
{
char *p;
for (p = s; p && *p; p++)
{
if (*p == '\\')
p++;
else if (*p == '&')
return 1;
}
return 0;
}
static int
histignore_item_func (ign)
struct ign *ign;
{
if (should_expand (ign->val))
ign->flags |= HIGN_EXPAND;
return (0);
}
void
setup_history_ignore (varname)
char *varname;
{
setup_ignore_patterns (&histignore);
}
static HIST_ENTRY *
last_history_entry ()
{
HIST_ENTRY *he;
using_history ();
he = previous_history ();
using_history ();
return he;
}
char *
last_history_line ()
{
HIST_ENTRY *he;
he = last_history_entry ();
if (he == 0)
return ((char *)NULL);
return he->line;
}
static char *
expand_histignore_pattern (pat)
char *pat;
{
HIST_ENTRY *phe;
char *ret;
phe = last_history_entry ();
if (phe == (HIST_ENTRY *)0)
return (savestring (pat));
ret = strcreplace (pat, '&', phe->line, 1);
return ret;
}
/* Return 1 if we should not put LINE into the history according to the
patterns in HISTIGNORE. */
static int
history_should_ignore (line)
char *line;
{
register int i, match;
char *npat;
if (histignore.num_ignores == 0)
return 0;
for (i = match = 0; i < histignore.num_ignores; i++)
{
if (histignore.ignores[i].flags & HIGN_EXPAND)
npat = expand_histignore_pattern (histignore.ignores[i].val);
else
npat = histignore.ignores[i].val;
match = strmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH;
if (histignore.ignores[i].flags & HIGN_EXPAND)
free (npat);
if (match)
break;
}
return match;
}
#endif /* HISTORY */
+4
View File
@@ -141,6 +141,10 @@ extern int shopt_listopt __P((char *, int));
extern int set_login_shell __P((int));
extern void set_bashopts __P((void));
extern void parse_bashopts __P((char *));
extern void intialize_bashopts __P((int));
/* Functions from type.def */
extern int describe_command __P((char *, int));
+174
View File
@@ -0,0 +1,174 @@
/* common.h -- extern declarations for functions defined in common.c. */
/* Copyright (C) 1993-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (__COMMON_H)
# define __COMMON_H
#include "stdc.h"
#define ISOPTION(s, c) (s[0] == '-' && !s[2] && s[1] == c)
/* Flag values for parse_and_execute () */
#define SEVAL_NONINT 0x001
#define SEVAL_INTERACT 0x002
#define SEVAL_NOHIST 0x004
#define SEVAL_NOFREE 0x008
#define SEVAL_RESETLINE 0x010
#define SEVAL_PARSEONLY 0x020
#define SEVAL_NOLONGJMP 0x040
/* Flags for describe_command, shared between type.def and command.def */
#define CDESC_ALL 0x001 /* type -a */
#define CDESC_SHORTDESC 0x002 /* command -V */
#define CDESC_REUSABLE 0x004 /* command -v */
#define CDESC_TYPE 0x008 /* type -t */
#define CDESC_PATH_ONLY 0x010 /* type -p */
#define CDESC_FORCE_PATH 0x020 /* type -ap or type -P */
#define CDESC_NOFUNCS 0x040 /* type -f */
#define CDESC_ABSPATH 0x080 /* convert to absolute path, no ./ */
/* Flags for get_job_by_name */
#define JM_PREFIX 0x01 /* prefix of job name */
#define JM_SUBSTRING 0x02 /* substring of job name */
#define JM_EXACT 0x04 /* match job name exactly */
#define JM_STOPPED 0x08 /* match stopped jobs only */
#define JM_FIRSTMATCH 0x10 /* return first matching job */
/* Flags for remember_args and value of changed_dollar_vars */
#define ARGS_NONE 0x0
#define ARGS_INVOC 0x01
#define ARGS_FUNC 0x02
#define ARGS_SETBLTIN 0x04
/* Functions from common.c */
extern void builtin_error __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
extern void builtin_warning __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
extern void builtin_usage __P((void));
extern void no_args __P((WORD_LIST *));
extern int no_options __P((WORD_LIST *));
/* common error message functions */
extern void sh_needarg __P((char *));
extern void sh_neednumarg __P((char *));
extern void sh_notfound __P((char *));
extern void sh_invalidopt __P((char *));
extern void sh_invalidoptname __P((char *));
extern void sh_invalidid __P((char *));
extern void sh_invalidnum __P((char *));
extern void sh_invalidsig __P((char *));
extern void sh_erange __P((char *, char *));
extern void sh_badpid __P((char *));
extern void sh_badjob __P((char *));
extern void sh_readonly __P((const char *));
extern void sh_nojobs __P((char *));
extern void sh_restricted __P((char *));
extern void sh_notbuiltin __P((char *));
extern void sh_wrerror __P((void));
extern void sh_ttyerror __P((int));
extern int sh_chkwrite __P((int));
extern char **make_builtin_argv __P((WORD_LIST *, int *));
extern void remember_args __P((WORD_LIST *, int));
extern int dollar_vars_changed __P((void));
extern void set_dollar_vars_unchanged __P((void));
extern void set_dollar_vars_changed __P((void));
extern int get_numeric_arg __P((WORD_LIST *, int, intmax_t *));
extern int get_exitstat __P((WORD_LIST *));
extern int read_octal __P((char *));
/* Keeps track of the current working directory. */
extern char *the_current_working_directory;
extern char *get_working_directory __P((char *));
extern void set_working_directory __P((char *));
#if defined (JOB_CONTROL)
extern int get_job_by_name __P((const char *, int));
extern int get_job_spec __P((WORD_LIST *));
#endif
extern int display_signal_list __P((WORD_LIST *, int));
/* It's OK to declare a function as returning a Function * without
providing a definition of what a `Function' is. */
extern struct builtin *builtin_address_internal __P((char *, int));
extern sh_builtin_func_t *find_shell_builtin __P((char *));
extern sh_builtin_func_t *builtin_address __P((char *));
extern sh_builtin_func_t *find_special_builtin __P((char *));
extern void initialize_shell_builtins __P((void));
/* Functions from exit.def */
extern void bash_logout __P((void));
/* Functions from getopts.def */
extern void getopts_reset __P((int));
/* Functions from set.def */
extern int minus_o_option_value __P((char *));
extern void list_minus_o_opts __P((int, int));
extern char **get_minus_o_opts __P((void));
extern int set_minus_o_option __P((int, char *));
extern void set_shellopts __P((void));
extern void parse_shellopts __P((char *));
extern void initialize_shell_options __P((int));
extern void reset_shell_options __P((void));
/* Functions from shopt.def */
extern void reset_shopt_options __P((void));
extern char **get_shopt_options __P((void));
extern int shopt_setopt __P((char *, int));
extern int shopt_listopt __P((char *, int));
extern int set_login_shell __P((int));
extern void set_bashopts __P((void));
extern void parse_bashopts __P((void));
extern void intialize_bashopts __P((int));
/* Functions from type.def */
extern int describe_command __P((char *, int));
/* Functions from setattr.def */
extern int set_or_show_attributes __P((WORD_LIST *, int, int));
extern int show_all_var_attributes __P((int, int));
extern int show_var_attributes __P((SHELL_VAR *, int, int));
extern int show_name_attributes __P((char *, int));
extern void set_var_attribute __P((char *, int, int));
/* Functions from pushd.def */
extern char *get_dirstack_from_string __P((char *));
extern char *get_dirstack_element __P((intmax_t, int));
extern void set_dirstack_element __P((intmax_t, int, char *));
extern WORD_LIST *get_directory_stack __P((int));
/* Functions from evalstring.c */
extern int parse_and_execute __P((char *, const char *, int));
extern void parse_and_execute_cleanup __P((void));
extern int parse_string __P((char *, const char *, int, char **));
/* Functions from evalfile.c */
extern int maybe_execute_file __P((const char *, int));
extern int source_file __P((const char *, int));
extern int fc_execute_file __P((const char *));
#endif /* !__COMMON_H */
+12 -1
View File
@@ -81,7 +81,7 @@ _evalfile (filename, flags)
{
volatile int old_interactive;
procenv_t old_return_catch;
int return_val, fd, result, pflags;
int return_val, fd, result, pflags, i;
ssize_t nr; /* return value from read(2) */
char *string;
struct stat finfo;
@@ -186,6 +186,17 @@ file_error_and_exit:
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
}
i = strlen (string);
if (i < nr)
{
for (i = 0; i < nr; i++)
if (string[i] == '\0')
{
memmove (string+i, string+i+1, nr - i);
nr--;
}
}
if (flags & FEVAL_UNWINDPROT)
{
begin_unwind_frame ("_evalfile");
+343
View File
@@ -0,0 +1,343 @@
/* evalfile.c - read and evaluate commands from a file or file descriptor */
/* Copyright (C) 1996-2009 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_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashtypes.h"
#include "posixstat.h"
#include "filecntl.h"
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../jobs.h"
#include "../builtins.h"
#include "../flags.h"
#include "../input.h"
#include "../execute_cmd.h"
#include "../trap.h"
#if defined (HISTORY)
# include "../bashhist.h"
#endif
#include <typemax.h>
#include "common.h"
#if !defined (errno)
extern int errno;
#endif
/* Flags for _evalfile() */
#define FEVAL_ENOENTOK 0x001
#define FEVAL_BUILTIN 0x002
#define FEVAL_UNWINDPROT 0x004
#define FEVAL_NONINT 0x008
#define FEVAL_LONGJMP 0x010
#define FEVAL_HISTORY 0x020
#define FEVAL_CHECKBINARY 0x040
#define FEVAL_REGFILE 0x080
#define FEVAL_NOPUSHARGS 0x100
extern int posixly_correct;
extern int indirection_level, subshell_environment;
extern int return_catch_flag, return_catch_value;
extern int last_command_exit_value;
/* How many `levels' of sourced files we have. */
int sourcelevel = 0;
static int
_evalfile (filename, flags)
const char *filename;
int flags;
{
volatile int old_interactive;
procenv_t old_return_catch;
int return_val, fd, result, pflags, i;
ssize_t nr; /* return value from read(2) */
char *string;
struct stat finfo;
size_t file_size;
sh_vmsg_func_t *errfunc;
#if defined (ARRAY_VARS)
SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;
ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
# if defined (DEBUGGER)
SHELL_VAR *bash_argv_v, *bash_argc_v;
ARRAY *bash_argv_a, *bash_argc_a;
# endif
char *t, tt[2];
#endif
USE_VAR(pflags);
#if defined (ARRAY_VARS)
GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
# if defined (DEBUGGER)
GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
# endif
#endif
fd = open (filename, O_RDONLY);
if (fd < 0 || (fstat (fd, &finfo) == -1))
{
file_error_and_exit:
if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
file_error (filename);
if (flags & FEVAL_LONGJMP)
{
last_command_exit_value = 1;
jump_to_top_level (EXITPROG);
}
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE
: ((errno == ENOENT) ? 0 : -1));
}
errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error);
if (S_ISDIR (finfo.st_mode))
{
(*errfunc) (_("%s: is a directory"), filename);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
{
(*errfunc) (_("%s: not a regular file"), filename);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
file_size = (size_t)finfo.st_size;
/* Check for overflow with large files. */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
(*errfunc) (_("%s: file is too large"), filename);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
#if defined (__CYGWIN__) && defined (O_TEXT)
setmode (fd, O_TEXT);
#endif
if (S_ISREG (finfo.st_mode) && file_size <= SSIZE_MAX)
{
string = (char *)xmalloc (1 + file_size);
nr = read (fd, string, file_size);
if (nr >= 0)
string[nr] = '\0';
}
else
nr = zmapfd (fd, &string, 0);
return_val = errno;
close (fd);
errno = return_val;
if (nr < 0) /* XXX was != file_size, not < 0 */
{
free (string);
goto file_error_and_exit;
}
if (nr == 0)
{
free (string);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1);
}
if ((flags & FEVAL_CHECKBINARY) &&
check_binary_file (string, (nr > 80) ? 80 : nr))
{
free (string);
(*errfunc) (_("%s: cannot execute binary file"), filename);
return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
}
i = strlen (string);
itrace("_evalfile: nr = %d strlen(string) = %d", nr, i);
if (i < nr)
{
for (i = 0; i < nr; i++)
if (string[i] == '\0')
{
memmove (string+i, string+i+1, nr - i);
nr--;
}
}
if (flags & FEVAL_UNWINDPROT)
{
begin_unwind_frame ("_evalfile");
unwind_protect_int (return_catch_flag);
unwind_protect_jmp_buf (return_catch);
if (flags & FEVAL_NONINT)
unwind_protect_int (interactive);
unwind_protect_int (sourcelevel);
}
else
{
COPY_PROCENV (return_catch, old_return_catch);
if (flags & FEVAL_NONINT)
old_interactive = interactive;
}
if (flags & FEVAL_NONINT)
interactive = 0;
return_catch_flag++;
sourcelevel++;
#if defined (ARRAY_VARS)
array_push (bash_source_a, (char *)filename);
t = itos (executing_line_number ());
array_push (bash_lineno_a, t);
free (t);
array_push (funcname_a, "source"); /* not exactly right */
# if defined (DEBUGGER)
/* Have to figure out a better way to do this when `source' is supplied
arguments */
if ((flags & FEVAL_NOPUSHARGS) == 0)
{
array_push (bash_argv_a, (char *)filename);
tt[0] = '1'; tt[1] = '\0';
array_push (bash_argc_a, tt);
}
# endif
#endif
/* set the flags to be passed to parse_and_execute */
pflags = SEVAL_RESETLINE;
pflags |= (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;
if (flags & FEVAL_BUILTIN)
result = EXECUTION_SUCCESS;
return_val = setjmp (return_catch);
/* If `return' was seen outside of a function, but in the script, then
force parse_and_execute () to clean up. */
if (return_val)
{
parse_and_execute_cleanup ();
result = return_catch_value;
}
else
result = parse_and_execute (string, filename, pflags);
if (flags & FEVAL_UNWINDPROT)
run_unwind_frame ("_evalfile");
else
{
if (flags & FEVAL_NONINT)
interactive = old_interactive;
return_catch_flag--;
sourcelevel--;
COPY_PROCENV (old_return_catch, return_catch);
}
#if defined (ARRAY_VARS)
/* These two variables cannot be unset, and cannot be affected by the
sourced file. */
array_pop (bash_source_a);
array_pop (bash_lineno_a);
/* FUNCNAME can be unset, and so can potentially be changed by the
sourced file. */
GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
if (nfv == funcname_v)
array_pop (funcname_a);
# if defined (DEBUGGER)
if ((flags & FEVAL_NOPUSHARGS) == 0)
{
array_pop (bash_argc_a);
array_pop (bash_argv_a);
}
# endif
#endif
return ((flags & FEVAL_BUILTIN) ? result : 1);
}
int
maybe_execute_file (fname, force_noninteractive)
const char *fname;
int force_noninteractive;
{
char *filename;
int result, flags;
filename = bash_tilde_expand (fname, 0);
flags = FEVAL_ENOENTOK;
if (force_noninteractive)
flags |= FEVAL_NONINT;
result = _evalfile (filename, flags);
free (filename);
return result;
}
#if defined (HISTORY)
int
fc_execute_file (filename)
const char *filename;
{
int flags;
/* We want these commands to show up in the history list if
remember_on_history is set. */
flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE;
return (_evalfile (filename, flags));
}
#endif /* HISTORY */
int
source_file (filename, sflags)
const char *filename;
int sflags;
{
int flags, rval;
flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;
if (sflags)
flags |= FEVAL_NOPUSHARGS;
/* POSIX shells exit if non-interactive and file error. */
if (posixly_correct && !interactive_shell)
flags |= FEVAL_LONGJMP;
rval = _evalfile (filename, flags);
run_return_trap ();
return rval;
}
+108
View File
@@ -123,6 +123,7 @@ static int set_restricted_shell __P((int));
static int shopt_login_shell;
static int shopt_compat31;
static int shopt_compat32;
static int shopt_compat40;
typedef int shopt_set_func_t __P((int));
@@ -197,6 +198,10 @@ static struct {
{ (char *)0, (int *)0, (shopt_set_func_t *)NULL }
};
#define N_SHOPT_OPTIONS (sizeof (shopt_vars) / sizeof (shopt_vars[0]))
#define GET_SHOPT_OPTION_VALUE(i) (*shopt_vars[i].value)
static const char * const on = "on";
static const char * const off = "off";
@@ -343,6 +348,8 @@ toggle_shopts (mode, list, quiet)
(*shopt_vars[ind].set_func) (mode);
}
}
set_bashopts ();
return (rval);
}
@@ -579,3 +586,104 @@ shopt_listopt (name, reusable)
print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0);
return (sh_chkwrite (EXECUTION_SUCCESS));
}
void
set_bashopts ()
{
char *value;
char tflag[N_SHOPT_OPTIONS];
int vsize, i, vptr, *ip, exported;
SHELL_VAR *v;
for (vsize = i = 0; shopt_vars[i].name; i++)
{
tflag[i] = 0;
if (GET_SHOPT_OPTION_VALUE (i))
{
vsize += strlen (shopt_vars[i].name) + 1;
tflag[i] = 1;
}
}
value = (char *)xmalloc (vsize + 1);
for (i = vptr = 0; shopt_vars[i].name; i++)
{
if (tflag[i])
{
strcpy (value + vptr, shopt_vars[i].name);
vptr += strlen (shopt_vars[i].name);
value[vptr++] = ':';
}
}
if (vptr)
vptr--; /* cut off trailing colon */
value[vptr] = '\0';
v = find_variable ("BASHOPTS");
/* Turn off the read-only attribute so we can bind the new value, and
note whether or not the variable was exported. */
if (v)
{
VUNSETATTR (v, att_readonly);
exported = exported_p (v);
}
else
exported = 0;
v = bind_variable ("BASHOPTS", value, 0);
/* Turn the read-only attribute back on, and turn off the export attribute
if it was set implicitly by mark_modified_vars and SHELLOPTS was not
exported before we bound the new value. */
VSETATTR (v, att_readonly);
if (mark_modified_vars && exported == 0 && exported_p (v))
VUNSETATTR (v, att_exported);
free (value);
}
void
parse_bashopts (value)
char *value;
{
char *vname;
int vptr, ind;
vptr = 0;
while (vname = extract_colon_unit (value, &vptr))
{
ind = find_shopt (vname);
if (ind >= 0)
*shopt_vars[ind].value = 1;
free (vname);
}
}
void
initialize_bashopts (no_bashopts)
int no_bashopts;
{
char *temp;
SHELL_VAR *var;
if (no_bashopts == 0)
{
var = find_variable ("BASHOPTS");
/* set up any shell options we may have inherited. */
if (var && imported_p (var))
{
temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
if (temp)
{
parse_bashopts (temp);
free (temp);
}
}
}
/* Set up the $BASHOPTS variable. */
set_bashopts ();
}
+687
View File
@@ -0,0 +1,687 @@
This file is shopt.def, from which is created shopt.c.
It implements the Bash `shopt' builtin.
Copyright (C) 1994-2009 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/>.
$PRODUCES shopt.c
$BUILTIN shopt
$FUNCTION shopt_builtin
$SHORT_DOC shopt [-pqsu] [-o] [optname ...]
Set and unset shell options.
Change the setting of each shell option OPTNAME. Without any option
arguments, list all shell options with an indication of whether or not each
is set.
Options:
-o restrict OPTNAMEs to those defined for use with `set -o'
-p print each shell option with an indication of its status
-q suppress output
-s enable (set) each OPTNAME
-u disable (unset) each OPTNAME
Exit Status:
Returns success if OPTNAME is enabled; fails if an invalid option is
given or OPTNAME is disabled.
$END
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include "version.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../flags.h"
#include "common.h"
#include "bashgetopt.h"
#if defined (HISTORY)
# include "../bashhist.h"
#endif
#define UNSETOPT 0
#define SETOPT 1
#define OPTFMT "%-15s\t%s\n"
extern int allow_null_glob_expansion, fail_glob_expansion, glob_dot_filenames;
extern int cdable_vars, mail_warning, source_uses_path;
extern int no_exit_on_failed_exec, print_shift_error;
extern int check_hashed_filenames, promptvars;
extern int cdspelling, expand_aliases;
extern int extended_quote;
extern int check_window_size;
extern int glob_ignore_case, match_ignore_case;
extern int hup_on_exit;
extern int xpg_echo;
extern int gnu_error_format;
extern int check_jobs_at_exit;
extern int autocd;
extern int glob_star;
#if defined (EXTENDED_GLOB)
extern int extended_glob;
#endif
#if defined (READLINE)
extern int hist_verify, history_reediting, perform_hostname_completion;
extern int no_empty_command_completion;
extern int force_fignore;
extern int dircomplete_spelling;
extern int enable_hostname_completion __P((int));
#endif
#if defined (PROGRAMMABLE_COMPLETION)
extern int prog_completion_enabled;
#endif
#if defined (RESTRICTED_SHELL)
extern char *shell_name;
#endif
#if defined (DEBUGGER)
extern int debugging_mode;
#endif
static void shopt_error __P((char *));
static int set_shellopts_after_change __P((int));
static int set_compatibility_level __P((int));
#if defined (RESTRICTED_SHELL)
static int set_restricted_shell __P((int));
#endif
static int shopt_login_shell;
static int shopt_compat31;
static int shopt_compat32;
static int shopt_compat40;
typedef int shopt_set_func_t __P((int));
static struct {
char *name;
int *value;
shopt_set_func_t *set_func;
} shopt_vars[] = {
{ "autocd", &autocd, (shopt_set_func_t *)NULL },
{ "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
{ "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
{ "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL },
#if defined (JOB_CONTROL)
{ "checkjobs", &check_jobs_at_exit, (shopt_set_func_t *)NULL },
#endif
{ "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL },
#if defined (HISTORY)
{ "cmdhist", &command_oriented_history, (shopt_set_func_t *)NULL },
#endif
{ "compat31", &shopt_compat31, set_compatibility_level },
{ "compat32", &shopt_compat32, set_compatibility_level },
#if defined (READLINE)
{ "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
#endif
{ "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
{ "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL },
{ "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL },
#if defined (DEBUGGER)
{ "extdebug", &debugging_mode, (shopt_set_func_t *)NULL },
#endif
#if defined (EXTENDED_GLOB)
{ "extglob", &extended_glob, (shopt_set_func_t *)NULL },
#endif
{ "extquote", &extended_quote, (shopt_set_func_t *)NULL },
{ "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
#if defined (READLINE)
{ "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
#endif
{ "globstar", &glob_star, (shopt_set_func_t *)NULL },
{ "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
#if defined (HISTORY)
{ "histappend", &force_append_history, (shopt_set_func_t *)NULL },
#endif
#if defined (READLINE)
{ "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
{ "histverify", &hist_verify, (shopt_set_func_t *)NULL },
{ "hostcomplete", &perform_hostname_completion, enable_hostname_completion },
#endif
{ "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL },
{ "interactive_comments", &interactive_comments, set_shellopts_after_change },
#if defined (HISTORY)
{ "lithist", &literal_history, (shopt_set_func_t *)NULL },
#endif
{ "login_shell", &shopt_login_shell, set_login_shell },
{ "mailwarn", &mail_warning, (shopt_set_func_t *)NULL },
#if defined (READLINE)
{ "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL },
#endif
{ "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
{ "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
{ "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
#if defined (PROGRAMMABLE_COMPLETION)
{ "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
#endif
{ "promptvars", &promptvars, (shopt_set_func_t *)NULL },
#if defined (RESTRICTED_SHELL)
{ "restricted_shell", &restricted_shell, set_restricted_shell },
#endif
{ "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL },
{ "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL },
{ "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL },
{ (char *)0, (int *)0, (shopt_set_func_t *)NULL }
};
#define N_SHOPT_OPTIONS (sizeof (shopt_vars) / sizeof (shopt_vars[0]))
#define GET_SHOPT_OPTION_VALUE(i) (*shopt_vars[i].value)
static const char * const on = "on";
static const char * const off = "off";
static int find_shopt __P((char *));
static int toggle_shopts __P((int, WORD_LIST *, int));
static void print_shopt __P((char *, int, int));
static int list_shopts __P((WORD_LIST *, int));
static int list_some_shopts __P((int, int));
static int list_shopt_o_options __P((WORD_LIST *, int));
static int list_some_o_options __P((int, int));
static int set_shopt_o_options __P((int, WORD_LIST *, int));
#define SFLAG 0x01
#define UFLAG 0x02
#define QFLAG 0x04
#define OFLAG 0x08
#define PFLAG 0x10
int
shopt_builtin (list)
WORD_LIST *list;
{
int opt, flags, rval;
flags = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "psuoq")) != -1)
{
switch (opt)
{
case 's':
flags |= SFLAG;
break;
case 'u':
flags |= UFLAG;
break;
case 'q':
flags |= QFLAG;
break;
case 'o':
flags |= OFLAG;
break;
case 'p':
flags |= PFLAG;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG))
{
builtin_error (_("cannot set and unset shell options simultaneously"));
return (EXECUTION_FAILURE);
}
rval = EXECUTION_SUCCESS;
if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0)) /* shopt -o */
rval = list_shopt_o_options (list, flags);
else if (list && (flags & OFLAG)) /* shopt -so args */
rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG);
else if (flags & OFLAG) /* shopt -so */
rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags);
else if (list && (flags & (SFLAG|UFLAG))) /* shopt -su args */
rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG);
else if ((flags & (SFLAG|UFLAG)) == 0) /* shopt [args] */
rval = list_shopts (list, flags);
else /* shopt -su */
rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags);
return (rval);
}
/* Reset the options managed by `shopt' to the values they would have at
shell startup. */
void
reset_shopt_options ()
{
allow_null_glob_expansion = glob_dot_filenames = 0;
cdable_vars = mail_warning = 0;
no_exit_on_failed_exec = print_shift_error = 0;
check_hashed_filenames = cdspelling = expand_aliases = check_window_size = 0;
source_uses_path = promptvars = 1;
#if defined (EXTENDED_GLOB)
extended_glob = 0;
#endif
#if defined (HISTORY)
literal_history = force_append_history = 0;
command_oriented_history = 1;
#endif
#if defined (READLINE)
hist_verify = history_reediting = 0;
perform_hostname_completion = 1;
#endif
shopt_login_shell = login_shell;
}
static int
find_shopt (name)
char *name;
{
int i;
for (i = 0; shopt_vars[i].name; i++)
if (STREQ (name, shopt_vars[i].name))
return i;
return -1;
}
static void
shopt_error (s)
char *s;
{
builtin_error (_("%s: invalid shell option name"), s);
}
static int
toggle_shopts (mode, list, quiet)
int mode;
WORD_LIST *list;
int quiet;
{
WORD_LIST *l;
int ind, rval;
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
{
ind = find_shopt (l->word->word);
if (ind < 0)
{
shopt_error (l->word->word);
rval = EXECUTION_FAILURE;
}
else
{
*shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */
if (shopt_vars[ind].set_func)
(*shopt_vars[ind].set_func) (mode);
}
}
return (rval);
}
static void
print_shopt (name, val, flags)
char *name;
int val, flags;
{
if (flags & PFLAG)
printf ("shopt %s %s\n", val ? "-s" : "-u", name);
else
printf (OPTFMT, name, val ? on : off);
}
/* List the values of all or any of the `shopt' options. Returns 0 if
all were listed or all variables queried were on; 1 otherwise. */
static int
list_shopts (list, flags)
WORD_LIST *list;
int flags;
{
WORD_LIST *l;
int i, val, rval;
if (list == 0)
{
for (i = 0; shopt_vars[i].name; i++)
{
val = *shopt_vars[i].value;
if ((flags & QFLAG) == 0)
print_shopt (shopt_vars[i].name, val, flags);
}
return (sh_chkwrite (EXECUTION_SUCCESS));
}
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
{
i = find_shopt (l->word->word);
if (i < 0)
{
shopt_error (l->word->word);
rval = EXECUTION_FAILURE;
continue;
}
val = *shopt_vars[i].value;
if (val == 0)
rval = EXECUTION_FAILURE;
if ((flags & QFLAG) == 0)
print_shopt (l->word->word, val, flags);
}
return (sh_chkwrite (rval));
}
static int
list_some_shopts (mode, flags)
int mode, flags;
{
int val, i;
for (i = 0; shopt_vars[i].name; i++)
{
val = *shopt_vars[i].value;
if (((flags & QFLAG) == 0) && mode == val)
print_shopt (shopt_vars[i].name, val, flags);
}
return (sh_chkwrite (EXECUTION_SUCCESS));
}
static int
list_shopt_o_options (list, flags)
WORD_LIST *list;
int flags;
{
WORD_LIST *l;
int val, rval;
if (list == 0)
{
if ((flags & QFLAG) == 0)
list_minus_o_opts (-1, (flags & PFLAG));
return (sh_chkwrite (EXECUTION_SUCCESS));
}
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
{
val = minus_o_option_value (l->word->word);
if (val == -1)
{
sh_invalidoptname (l->word->word);
rval = EXECUTION_FAILURE;
continue;
}
if (val == 0)
rval = EXECUTION_FAILURE;
if ((flags & QFLAG) == 0)
{
if (flags & PFLAG)
printf ("set %co %s\n", val ? '-' : '+', l->word->word);
else
printf (OPTFMT, l->word->word, val ? on : off);
}
}
return (sh_chkwrite (rval));
}
static int
list_some_o_options (mode, flags)
int mode, flags;
{
if ((flags & QFLAG) == 0)
list_minus_o_opts (mode, (flags & PFLAG));
return (sh_chkwrite (EXECUTION_SUCCESS));
}
static int
set_shopt_o_options (mode, list, quiet)
int mode;
WORD_LIST *list;
int quiet;
{
WORD_LIST *l;
int rval;
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
{
if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE)
rval = EXECUTION_FAILURE;
}
set_shellopts ();
return rval;
}
/* If we set or unset interactive_comments with shopt, make sure the
change is reflected in $SHELLOPTS. */
static int
set_shellopts_after_change (mode)
int mode;
{
set_shellopts ();
return (0);
}
static int
set_compatibility_level (mode)
int mode;
{
/* Need to change logic here as we add more compatibility levels */
if (shopt_compat31)
shell_compatibility_level = 31;
else if (shopt_compat32)
shell_compatibility_level = 32;
else
shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
return 0;
}
#if defined (RESTRICTED_SHELL)
/* Don't allow the value of restricted_shell to be modified. */
static int
set_restricted_shell (mode)
int mode;
{
static int save_restricted = -1;
if (save_restricted == -1)
save_restricted = shell_is_restricted (shell_name);
restricted_shell = save_restricted;
return (0);
}
#endif /* RESTRICTED_SHELL */
/* Not static so shell.c can call it to initialize shopt_login_shell */
int
set_login_shell (mode)
int mode;
{
shopt_login_shell = login_shell != 0;
return (0);
}
char **
get_shopt_options ()
{
char **ret;
int n, i;
n = sizeof (shopt_vars) / sizeof (shopt_vars[0]);
ret = strvec_create (n + 1);
for (i = 0; shopt_vars[i].name; i++)
ret[i] = savestring (shopt_vars[i].name);
ret[i] = (char *)NULL;
return ret;
}
/*
* External interface for other parts of the shell. NAME is a string option;
* MODE is 0 if we want to unset an option; 1 if we want to set an option.
* REUSABLE is 1 if we want to print output in a form that may be reused.
*/
int
shopt_setopt (name, mode)
char *name;
int mode;
{
WORD_LIST *wl;
int r;
wl = add_string_to_list (name, (WORD_LIST *)NULL);
r = toggle_shopts (mode, wl, 0);
dispose_words (wl);
return r;
}
int
shopt_listopt (name, reusable)
char *name;
int reusable;
{
int i;
if (name == 0)
return (list_shopts ((WORD_LIST *)NULL, reusable ? PFLAG : 0));
i = find_shopt (name);
if (i < 0)
{
shopt_error (name);
return (EXECUTION_FAILURE);
}
print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0);
return (sh_chkwrite (EXECUTION_SUCCESS));
}
void
set_bashopts ()
{
char *value;
char tflag[N_SHOPT_OPTIONS];
int vsize, i, vptr, *ip, exported;
SHELL_VAR *v;
for (vsize = i = 0; shopt_vars[i].name; i++)
{
tflag[i] = 0;
if (GET_SHOPT_OPTION_VALUE (i))
{
vsize += strlen (shopt_vars[i].name) + 1;
tflag[i] = 1;
}
}
value = (char *)xmalloc (vsize + 1);
for (i = vptr = 0; shopt_vars[i].name; i++)
{
if (tflag[i])
{
strcpy (value + vptr, shopt_vars[i].name);
vptr += strlen (shopt_vars[i].name);
value[vptr++] = ':';
}
}
if (vptr)
vptr--; /* cut off trailing colon */
value[vptr] = '\0';
v = find_variable ("BASHOPTS");
/* Turn off the read-only attribute so we can bind the new value, and
note whether or not the variable was exported. */
if (v)
{
VUNSETATTR (v, att_readonly);
exported = exported_p (v);
}
else
exported = 0;
v = bind_variable ("BASHOPTS", value, 0);
/* Turn the read-only attribute back on, and turn off the export attribute
if it was set implicitly by mark_modified_vars and SHELLOPTS was not
exported before we bound the new value. */
VSETATTR (v, att_readonly);
if (mark_modified_vars && exported == 0 && exported_p (v))
VUNSETATTR (v, att_exported);
free (value);
}
void
parse_bashopts (value)
char *value;
{
char *vname;
int vptr, ind;
vptr = 0;
while (vname = extract_colon_unit (value, &vptr))
{
ind = find_shopt (vname);
if (ind >= 0)
*shopt_vars[ind].value = 1;
free (vname);
}
}
void
initialize_bashopts (no_bashopts)
int no_bashopts;
{
char *temp;
SHELL_VAR *var;
if (no_bashopts == 0)
{
var = find_variable ("BASHOPTS");
/* set up any shell options we may have inherited. */
if (var && imported_p (var))
{
temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
if (temp)
{
parse_bashopts (temp);
free (temp);
}
}
}
/* Set up the $BASHOPTS variable. */
set_bashopts ();
}
+4
View File
@@ -125,6 +125,10 @@
# define PPROMPT "$ "
#endif
#if !defined (HAVE_SYSLOG) || !defined (HAVE_SYSLOG_H)
# undef SYSLOG_HISTORY
#endif
/************************************************/
/* check multibyte capability for I18N code */
/************************************************/
+195
View File
@@ -0,0 +1,195 @@
/* config-bot.h */
/* modify settings or make new ones based on what autoconf tells us. */
/* Copyright (C) 1989-2009 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/>.
*/
/*********************************************************/
/* Modify or set defines based on the configure results. */
/*********************************************************/
#if !defined (HAVE_VPRINTF) && defined (HAVE_DOPRNT)
# define USE_VFPRINTF_EMULATION
# define HAVE_VPRINTF
#endif
#if defined (HAVE_SYS_RESOURCE_H) && defined (HAVE_GETRLIMIT)
# define HAVE_RESOURCE
#endif
#if !defined (GETPGRP_VOID)
# define HAVE_BSD_PGRP
#endif
/* Try this without testing __STDC__ for the time being. */
#if defined (HAVE_STDARG_H)
# define PREFER_STDARG
# define USE_VARARGS
#else
# if defined (HAVE_VARARGS_H)
# define PREFER_VARARGS
# define USE_VARARGS
# endif
#endif
#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && defined (HAVE_NETINET_IN_H)
# define HAVE_NETWORK
#endif
#if defined (HAVE_REGEX_H) && defined (HAVE_REGCOMP) && defined (HAVE_REGEXEC)
# define HAVE_POSIX_REGEXP
#endif
/* backwards compatibility between different autoconf versions */
#if HAVE_DECL_SYS_SIGLIST && !defined (SYS_SIGLIST_DECLARED)
# define SYS_SIGLIST_DECLARED
#endif
/***********************************************************************/
/* Unset defines based on what configure reports as missing or broken. */
/***********************************************************************/
/* Ultrix botches type-ahead when switching from canonical to
non-canonical mode, at least through version 4.3 */
#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix)
# define TERMIOS_MISSING
#endif
/* If we have a getcwd(3), but one that does not dynamically allocate memory,
#undef HAVE_GETCWD so the replacement in getcwd.c will be built. We do
not do this on Solaris, because their implementation of loopback mounts
breaks the traditional file system assumptions that getcwd uses. */
#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) && !defined (SOLARIS)
# undef HAVE_GETCWD
#endif
#if !defined (HAVE_DEV_FD) && defined (NAMED_PIPES_MISSING)
# undef PROCESS_SUBSTITUTION
#endif
#if defined (JOB_CONTROL_MISSING)
# undef JOB_CONTROL
#endif
#if defined (STRCOLL_BROKEN)
# undef HAVE_STRCOLL
#endif
#if !defined (HAVE_POSIX_REGEXP)
# undef COND_REGEXP
#endif
/* If the shell is called by this name, it will become restricted. */
#if defined (RESTRICTED_SHELL)
# define RESTRICTED_SHELL_NAME "rbash"
#endif
/***********************************************************/
/* Make sure feature defines have necessary prerequisites. */
/***********************************************************/
/* BANG_HISTORY requires HISTORY. */
#if defined (BANG_HISTORY) && !defined (HISTORY)
# define HISTORY
#endif /* BANG_HISTORY && !HISTORY */
#if defined (READLINE) && !defined (HISTORY)
# define HISTORY
#endif
#if defined (PROGRAMMABLE_COMPLETION) && !defined (READLINE)
# undef PROGRAMMABLE_COMPLETION
#endif
#if !defined (V9_ECHO)
# undef DEFAULT_ECHO_TO_XPG
#endif
#if !defined (PROMPT_STRING_DECODE)
# undef PPROMPT
# define PPROMPT "$ "
#endif
/************************************************/
/* check multibyte capability for I18N code */
/************************************************/
/* For platforms which support the ISO C amendement 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)
# include <wchar.h>
# include <wctype.h>
# if defined (HAVE_ISWCTYPE) && \
defined (HAVE_ISWLOWER) && \
defined (HAVE_ISWUPPER) && \
defined (HAVE_MBSRTOWCS) && \
defined (HAVE_MBRTOWC) && \
defined (HAVE_MBRLEN) && \
defined (HAVE_TOWLOWER) && \
defined (HAVE_TOWUPPER) && \
defined (HAVE_WCHAR_T) && \
defined (HAVE_WCTYPE_T) && \
defined (HAVE_WINT_T) && \
defined (HAVE_WCWIDTH) && \
defined (HAVE_WCTYPE)
/* system is supposed to support XPG5 */
# define HANDLE_MULTIBYTE 1
# endif
#endif
/* If we don't want multibyte chars even on a system that supports them, let
the configuring user turn multibyte support off. */
#if defined (NO_MULTIBYTE_SUPPORT)
# undef HANDLE_MULTIBYTE
#endif
/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0)
# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0)
# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
# define mbrlen(s, n, ps) (mbrlen) (s, n, 0)
# define mbstate_t int
#endif
/* Make sure MB_LEN_MAX is at least 16 (some systems define
MB_LEN_MAX as 1) */
#ifdef HANDLE_MULTIBYTE
# include <limits.h>
# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16)
# undef MB_LEN_MAX
# endif
# if !defined (MB_LEN_MAX)
# define MB_LEN_MAX 16
# endif
#endif
/************************************************/
/* end of multibyte capability checks for I18N */
/************************************************/
/******************************************************************/
/* Placeholder for builders to #undef any unwanted features from */
/* config-top.h or created by configure (such as the default mail */
/* file for mail checking). */
/******************************************************************/
/* If you don't want bash to provide a default mail file to check. */
/* #undef DEFAULT_MAIL_DIRECTORY */
+8
View File
@@ -98,3 +98,11 @@
name is not found. If you want to name it something other than the
default ("command_not_found_handle"), change it here. */
/* #define NOTFOUND_HOOK "command_not_found_handle" */
/* Define if you want each line saved to the history list in bashhist.c:
bash_add_history() to be sent to syslog(). */
#define SYSLOG_HISTORY
#if defined (SYSLOG_HISTORY)
# define SYSLOG_FACILITY LOG_USER
# define SYSLOG_LEVEL LOG_INFO
#endif
+106
View File
@@ -0,0 +1,106 @@
/* config-top.h - various user-settable options not under the control of autoconf. */
/* Copyright (C) 2002-2009 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/>.
*/
/* Define CONTINUE_AFTER_KILL_ERROR if you want the kill command to
continue processing arguments after one of them fails. This is
what POSIX.2 specifies. */
#define CONTINUE_AFTER_KILL_ERROR
/* Define BREAK_COMPLAINS if you want the non-standard, but useful
error messages about `break' and `continue' out of context. */
#define BREAK_COMPLAINS
/* Define BUFFERED_INPUT if you want the shell to do its own input
buffering, rather than using stdio. Do not undefine this; it's
required to preserve semantics required by POSIX. */
#define BUFFERED_INPUT
/* Define ONESHOT if you want sh -c 'command' to avoid forking to execute
`command' whenever possible. This is a big efficiency improvement. */
#define ONESHOT
/* Define V9_ECHO if you want to give the echo builtin backslash-escape
interpretation using the -e option, in the style of the Bell Labs 9th
Edition version of echo. You cannot emulate the System V echo behavior
without this option. */
#define V9_ECHO
/* Define DONT_REPORT_SIGPIPE if you don't want to see `Broken pipe' messages
when a job like `cat jobs.c | exit 1' terminates due to a SIGPIPE. */
#define DONT_REPORT_SIGPIPE
/* Define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS if you don't want builtins
like `echo' and `printf' to report errors when output does not succeed
due to EPIPE. */
/* #define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS */
/* The default value of the PATH variable. */
#ifndef DEFAULT_PATH_VALUE
#define DEFAULT_PATH_VALUE \
"/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:."
#endif
/* The value for PATH when invoking `command -p'. This is only used when
the Posix.2 confstr () function, or CS_PATH define are not present. */
#ifndef STANDARD_UTILS_PATH
#define STANDARD_UTILS_PATH \
"/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc"
#endif
/* Default primary and secondary prompt strings. */
#define PPROMPT "\\s-\\v\\$ "
#define SPROMPT "> "
/* Undefine this if you don't want the ksh-compatible behavior of reprinting
the select menu after a valid choice is made only if REPLY is set to NULL
in the body of the select command. The menu is always reprinted if the
reply to the select query is an empty line. */
#define KSH_COMPATIBLE_SELECT
/* System-wide .bashrc file for interactive shells. */
/* #define SYS_BASHRC "/etc/bash.bashrc" */
/* System-wide .bash_logout for login shells. */
/* #define SYS_BASH_LOGOUT "/etc/bash.bash_logout" */
/* Define this to make non-interactive shells begun with argv[0][0] == '-'
run the startup files when not in posix mode. */
/* #define NON_INTERACTIVE_LOGIN_SHELLS */
/* Define this if you want bash to try to check whether it's being run by
sshd and source the .bashrc if so (like the rshd behavior). This checks
for the presence of SSH_CLIENT or SSH2_CLIENT in the initial environment,
which can be fooled under certain not-uncommon circumstances. */
/* #define SSH_SOURCE_BASHRC */
/* Define if you want the case-capitalizing operators (~[~]) and the
`capcase' variable attribute (declare -c). */
#define CASEMOD_CAPCASE
/* This is used as the name of a shell function to call when a command
name is not found. If you want to name it something other than the
default ("command_not_found_handle"), change it here. */
/* #define NOTFOUND_HOOK "command_not_found_handle" */
/* Define if you want each line saved to the history list in bashhist.c:
bash_add_history() to be sent to syslog(). */
/* #define SYSLOG_HISTORY */
/* #define SYSLOG_FACILITY LOG_USER */
/* #define SYSLOG_LEVEL LOG_INFO */
+10
View File
@@ -115,6 +115,10 @@
pattern matching. */
#undef EXTENDED_GLOB
/* Define EXTGLOB_DEFAULT to the value you'd like the extglob shell option
to have by default */
#undef EXTGLOB_DEFAULT
/* Define COND_COMMAND if you want the ksh-style [[...]] conditional
command. */
#undef COND_COMMAND
@@ -795,6 +799,9 @@
/* Define if you have the sysconf function. */
#undef HAVE_SYSCONF
/* Define if you have the syslog function. */
#undef HAVE_SYSLOG
/* Define if you have the tcgetattr function. */
#undef HAVE_TCGETATTR
@@ -920,6 +927,9 @@
/* Define if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
/* Define if you have the <sys/dir.h> header file. */
#undef HAVE_SYS_DIR_H
+9
View File
@@ -659,6 +659,9 @@
/* Define if you have the mbrtowc function. */
#undef HAVE_MBRTOWC
/* Define if you have the mbscasecmp function. */
#undef HAVE_MBSCASECMP
/* Define if you have the mbschr function. */
#undef HAVE_MBSCHR
@@ -792,6 +795,9 @@
/* Define if you have the sysconf function. */
#undef HAVE_SYSCONF
/* Define if you have the syslog function. */
#undef HAVE_SYSLOG
/* Define if you have the tcgetattr function. */
#undef HAVE_TCGETATTR
@@ -917,6 +923,9 @@
/* Define if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
/* Define if you have the <sys/dir.h> header file. */
#undef HAVE_SYS_DIR_H
Vendored
+410 -474
View File
File diff suppressed because it is too large Load Diff
+12 -4
View File
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_REVISION([for Bash 4.0, version 4.013])dnl
AC_REVISION([for Bash 4.0, version 4.014])dnl
define(bashvers, 4.0)
define(relstatus, maint)
@@ -185,6 +185,7 @@ opt_debugger=yes
opt_single_longdoc_strings=yes
opt_casemod_attrs=yes
opt_casemod_expansions=yes
opt_extglob_default=no
dnl options that affect how bash is compiled and linked
opt_static_link=no
@@ -204,7 +205,7 @@ if test $opt_minimal_config = yes; then
opt_extended_glob=no opt_cond_command=no opt_arith_for_command=no
opt_net_redirs=no opt_progcomp=no opt_separate_help=no
opt_multibyte=yes opt_cond_regexp=no opt_coproc=no
opt_casemod_attrs=no opt_casemod_expansions=no
opt_casemod_attrs=no opt_casemod_expansions=no opt_extglob_default=no
fi
AC_ARG_ENABLE(alias, AC_HELP_STRING([--enable-alias], [enable shell aliases]), opt_alias=$enableval)
@@ -223,6 +224,7 @@ AC_ARG_ENABLE(directory-stack, AC_HELP_STRING([--enable-directory-stack], [enabl
AC_ARG_ENABLE(disabled-builtins, AC_HELP_STRING([--enable-disabled-builtins], [allow disabled builtins to still be invoked]), opt_disabled_builtins=$enableval)
AC_ARG_ENABLE(dparen-arithmetic, AC_HELP_STRING([--enable-dparen-arithmetic], [include ((...)) command]), opt_dparen_arith=$enableval)
AC_ARG_ENABLE(extended-glob, AC_HELP_STRING([--enable-extended-glob], [include ksh-style extended pattern matching]), opt_extended_glob=$enableval)
AC_ARG_ENABLE(extended-glob-default, AC_HELP_STRING([--enable-extended-glob-default], [force extended pattern matching to be enabled by default]), opt_extglob_default=$enableval)
AC_ARG_ENABLE(help-builtin, AC_HELP_STRING([--enable-help-builtin], [include the help builtin]), opt_help=$enableval)
AC_ARG_ENABLE(history, AC_HELP_STRING([--enable-history], [turn on command history]), opt_history=$enableval)
AC_ARG_ENABLE(job-control, AC_HELP_STRING([--enable-job-control], [enable job control features]), opt_job_control=$enableval)
@@ -296,6 +298,11 @@ fi
if test $opt_extended_glob = yes ; then
AC_DEFINE(EXTENDED_GLOB)
fi
if test $opt_extglob_default = yes; then
AC_DEFINE(EXTGLOB_DEFAULT, 1)
else
AC_DEFINE(EXTGLOB_DEFAULT, 0)
fi
if test $opt_cond_command = yes ; then
AC_DEFINE(COND_COMMAND)
fi
@@ -651,7 +658,8 @@ BASH_HEADER_INTTYPES
AC_CHECK_HEADERS(unistd.h stdlib.h stdarg.h varargs.h limits.h string.h \
memory.h locale.h termcap.h termio.h termios.h dlfcn.h \
stddef.h stdint.h netdb.h pwd.h grp.h strings.h regex.h)
stddef.h stdint.h netdb.h pwd.h grp.h strings.h regex.h \
syslog.h)
AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h \
sys/resource.h sys/param.h sys/socket.h sys/stat.h \
sys/time.h sys/times.h sys/types.h sys/wait.h)
@@ -723,7 +731,7 @@ AC_CHECK_FUNCS(bcopy bzero confstr fnmatch \
getaddrinfo gethostbyname getservbyname getservent inet_aton \
memmove pathconf putenv raise regcomp regexec \
setenv setlinebuf setlocale setvbuf siginterrupt strchr \
sysconf tcgetattr times ttyname tzset unsetenv)
sysconf syslog tcgetattr times ttyname tzset unsetenv)
AC_CHECK_FUNCS(vsnprintf snprintf vasprintf asprintf)
AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit)
+12 -6
View File
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_REVISION([for Bash 4.0, version 4.013])dnl
AC_REVISION([for Bash 4.0, version 4.014])dnl
define(bashvers, 4.0)
define(relstatus, maint)
@@ -185,6 +185,7 @@ opt_debugger=yes
opt_single_longdoc_strings=yes
opt_casemod_attrs=yes
opt_casemod_expansions=yes
opt_extglob_default=no
dnl options that affect how bash is compiled and linked
opt_static_link=no
@@ -204,7 +205,7 @@ if test $opt_minimal_config = yes; then
opt_extended_glob=no opt_cond_command=no opt_arith_for_command=no
opt_net_redirs=no opt_progcomp=no opt_separate_help=no
opt_multibyte=yes opt_cond_regexp=no opt_coproc=no
opt_casemod_attrs=no opt_casemod_expansions=no
opt_casemod_attrs=no opt_casemod_expansions=no opt_extglob_default=no
fi
AC_ARG_ENABLE(alias, AC_HELP_STRING([--enable-alias], [enable shell aliases]), opt_alias=$enableval)
@@ -223,6 +224,7 @@ AC_ARG_ENABLE(directory-stack, AC_HELP_STRING([--enable-directory-stack], [enabl
AC_ARG_ENABLE(disabled-builtins, AC_HELP_STRING([--enable-disabled-builtins], [allow disabled builtins to still be invoked]), opt_disabled_builtins=$enableval)
AC_ARG_ENABLE(dparen-arithmetic, AC_HELP_STRING([--enable-dparen-arithmetic], [include ((...)) command]), opt_dparen_arith=$enableval)
AC_ARG_ENABLE(extended-glob, AC_HELP_STRING([--enable-extended-glob], [include ksh-style extended pattern matching]), opt_extended_glob=$enableval)
AC_ARG_ENABLE(extended-glob-default, AC_HELP_STRING([--enable-extended-glob-default], [force extended pattern matching to be enabled by default]), opt_extglob_default=$enableval)
AC_ARG_ENABLE(help-builtin, AC_HELP_STRING([--enable-help-builtin], [include the help builtin]), opt_help=$enableval)
AC_ARG_ENABLE(history, AC_HELP_STRING([--enable-history], [turn on command history]), opt_history=$enableval)
AC_ARG_ENABLE(job-control, AC_HELP_STRING([--enable-job-control], [enable job control features]), opt_job_control=$enableval)
@@ -296,6 +298,9 @@ fi
if test $opt_extended_glob = yes ; then
AC_DEFINE(EXTENDED_GLOB)
fi
if test $opt_extglob_default = yes; then
AC_DEFINE(EXTGLOB_DEFAULT)
fi
if test $opt_cond_command = yes ; then
AC_DEFINE(COND_COMMAND)
fi
@@ -651,7 +656,8 @@ BASH_HEADER_INTTYPES
AC_CHECK_HEADERS(unistd.h stdlib.h stdarg.h varargs.h limits.h string.h \
memory.h locale.h termcap.h termio.h termios.h dlfcn.h \
stddef.h stdint.h netdb.h pwd.h grp.h strings.h regex.h)
stddef.h stdint.h netdb.h pwd.h grp.h strings.h regex.h \
syslog.h)
AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h \
sys/resource.h sys/param.h sys/socket.h sys/stat.h \
sys/time.h sys/times.h sys/types.h sys/wait.h)
@@ -723,13 +729,13 @@ AC_CHECK_FUNCS(bcopy bzero confstr fnmatch \
getaddrinfo gethostbyname getservbyname getservent inet_aton \
memmove pathconf putenv raise regcomp regexec \
setenv setlinebuf setlocale setvbuf siginterrupt strchr \
sysconf tcgetattr times ttyname tzset unsetenv)
sysconf syslog tcgetattr times ttyname tzset unsetenv)
AC_CHECK_FUNCS(vsnprintf snprintf vasprintf asprintf)
AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit)
AC_CHECK_FUNCS(getpwent getpwnam getpwuid)
AC_REPLACE_FUNCS(getcwd memset)
AC_REPLACE_FUNCS(strcasecmp strerror strftime strnlen strpbrk strstr)
AC_REPLACE_FUNCS(strcasecmp strcasestr strerror strftime strnlen strpbrk strstr)
AC_REPLACE_FUNCS(strtod strtol strtoul strtoll strtoull strtoimax strtoumax)
AC_REPLACE_FUNCS(fdprintf)
@@ -1026,7 +1032,7 @@ linux*) LOCAL_LDFLAGS=-rdynamic # allow dynamic loading
*qnx*) LOCAL_CFLAGS="-Dqnx -F -3s" LOCAL_LDFLAGS="-3s" LOCAL_LIBS="-lunix -lncurses" ;;
powerux*) LOCAL_LIBS="-lgen" ;;
cygwin*) LOCAL_CFLAGS=-DRECYCLES_PIDS ;;
opennt*|interix*) LOCAL_CFLAGS="-DNO_MAIN_ENV_ARG -DBROKEN_DIRENT_D_INO -D_POSIX_SOURCE" ;;
opennt*|interix*) LOCAL_CFLAGS="-DNO_MAIN_ENV_ARG -DBROKEN_DIRENT_D_INO -D_POSIX_SOURCE -D_ALL_SOURCE" ;;
esac
dnl Stanza for OS/compiler pair-specific flags
+39 -4
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
.\" Last Change: Thu Jul 30 09:25:13 EDT 2009
.\" Last Change: Fri Aug 14 18:32:52 EDT 2009
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2009 July 30" "GNU Bash-4.0"
.TH BASH 1 "2009 August 14" "GNU Bash-4.0"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -429,8 +429,12 @@ If the shell is started with the effective user (group) id not equal to the
real user (group) id, and the \fB\-p\fP option is not supplied, no startup
files are read, shell functions are not inherited from the environment, the
.SM
.B SHELLOPTS
variable, if it appears in the environment, is ignored,
.BR SHELLOPTS ,
.BR BASHOPTS ,
.BR CDPATH ,
and
.B GLOBIGNORE
variables, if they appear in the environment, are ignored,
and the effective user id is set to the real user id.
If the \fB\-p\fP option is supplied at invocation, the startup behavior is
the same, but the effective user id is not reset.
@@ -1304,6 +1308,27 @@ The following variables are set by the shell:
Expands to the full file name used to invoke this instance of
.BR bash .
.TP
.B BASHOPTS
A colon-separated list of enabled shell options. Each word in
the list is a valid argument for the
.B \-s
option to the
.B shopt
builtin command (see
.SM
.B "SHELL BUILTIN COMMANDS"
below). The options appearing in
.SM
.B BASHOPTS
are those reported as
.I on
by \fBshopt\fP.
If this variable is in the environment when
.B bash
starts up, each shell option in the list will be enabled before
reading any startup files.
This variable is read-only.
.TP
.B BASHPID
Expands to the process id of the current \fBbash\fP process.
This differs from \fB$$\fP under certain circumstances, such as subshells
@@ -5632,6 +5657,15 @@ character. A negative count searches for previous occurrences.
A character is read and point is moved to the previous occurrence of that
character. A negative count searches for subsequent occurrences.
.TP
.B skip\-csi\-sequence ()
Read enough characters to consume a multi-key sequence such as those
defined for keys like Home and End. Such sequences begin with a
Control Sequence Indicator (CSI), usually ESC\-[. If this sequence is
bound to "\e[", keys producing such sequences will have no effect
unless explicitly bound to a readline command, instead of inserting
stray characters into the editing buffer. This is unbound by default,
but usually bound to ESC\-[.
.TP
.B insert\-comment (M\-#)
Without a numeric argument, the value of the readline
.B comment\-begin
@@ -8306,6 +8340,7 @@ files are not processed, shell functions are not inherited from the
environment, and the
.SM
.BR SHELLOPTS ,
.BR BASHOPTS ,
.BR CDPATH ,
and
.B GLOBIGNORE
+85 -6
View File
@@ -429,8 +429,12 @@ If the shell is started with the effective user (group) id not equal to the
real user (group) id, and the \fB\-p\fP option is not supplied, no startup
files are read, shell functions are not inherited from the environment, the
.SM
.B SHELLOPTS
variable, if it appears in the environment, is ignored,
.BR SHELLOPTS ,
.BR BASHOPTS ,
.BR CDPATH ,
and
.B GLOBIGNORE
variables, if they appear in the environment, are ignored,
and the effective user id is set to the real user id.
If the \fB\-p\fP option is supplied at invocation, the startup behavior is
the same, but the effective user id is not reset.
@@ -1304,6 +1308,27 @@ The following variables are set by the shell:
Expands to the full file name used to invoke this instance of
.BR bash .
.TP
.B BASHOPTS
A colon-separated list of enabled shell options. Each word in
the list is a valid argument for the
.B \-s
option to the
.B shopt
builtin command (see
.SM
.B "SHELL BUILTIN COMMANDS"
below). The options appearing in
.SM
.B BASHOPTS
are those reported as
.I on
by \fBshopt\fP.
If this variable is in the environment when
.B bash
starts up, each shell option in the list will be enabled before
reading any startup files.
This variable is read-only.
.TP
.B BASHPID
Expands to the process id of the current \fBbash\fP process.
This differs from \fB$$\fP under certain circumstances, such as subshells
@@ -1847,7 +1872,8 @@ adds the contents of the new file to the existing list.
If
.SM
.B HOSTFILE
is set, but has no value, \fBbash\fP attempts to read
is set, but has no value, or does not name a readable file,
\fBbash\fP attempts to read
.FN /etc/hosts
to obtain the list of possible hostname completions.
When
@@ -5631,6 +5657,15 @@ character. A negative count searches for previous occurrences.
A character is read and point is moved to the previous occurrence of that
character. A negative count searches for subsequent occurrences.
.TP
.B skip\-csi\-sequence ()
Read enough characters to consume a multi-key sequence such as those
defined for keys like Home and End. Such sequences begin with a
Control Sequence Indicator (CSI), usually ESC\-[. If this sequence is
bound to "\e[", keys producing such sequences will have no effect
unless explicitly bound to a readline command, instead of inserting
stray characters into the editing buffer. This is unbound by default,
but usually bound to ESC\-[.
.TP
.B insert\-comment (M\-#)
Without a numeric argument, the value of the readline
.B comment\-begin
@@ -5697,12 +5732,17 @@ using the \fBcomplete\fP builtin (see
below), the programmable completion facilities are invoked.
.PP
First, the command name is identified.
If the command word is the empty string (completion attempted at the
beginning of an empty line), any compspec defined with
the \fB\-E\fP option to \fBcomplete\fP is used.
If a compspec has been defined for that command, the
compspec is used to generate the list of possible completions for the word.
If the command word is a full pathname, a compspec for the full
pathname is searched for first.
If no compspec is found for the full pathname, an attempt is made to
find a compspec for the portion following the final slash.
If those searches to not result in a compspec, any compspec defined with
the \fB\-D\fP option to \fBcomplete\fP is used as the default.
.PP
Once a compspec has been found, it is used to generate the list of
matching words.
@@ -5835,6 +5875,35 @@ the programmable completion functions force readline to append a slash
to completed names which are symbolic links to directories, subject to
the value of the \fBmark\-directories\fP readline variable, regardless
of the setting of the \fBmark-symlinked\-directories\fP readline variable.
.PP
There is some support for dynamically modifying completions. This is
most useful when used in combination with a default completion specified
with \fBcomplete -D\fP.
It's possible for shell functions executed as completion
handlers to indicate that completion should be retried by returning an
exit status of 124. If a shell function returns 124, and changes
the compspec associated with the command on which completion is being
attempted (supplied as the first argument when the function is executed),
programmable completion restarts from the beginning, with an
attempt to find a compspec for that command. This allows a set of
completions to be built dynamically as completion is attempted, rather than
being loaded all at once.
.PP
For instance, assuming that there is a library of compspecs, each kept in a
file corresponding to the name of the command, the following default
completion function would load completions dynamically:
.PP
\f(CW_completion_loader()
.br
{
.br
. "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
.br
}
.br
complete -D -F _completion_loader
.br
\fP
.SH HISTORY
When the
.B \-o history
@@ -6566,12 +6635,12 @@ will be displayed.
The return value is true unless an invalid option is supplied, or no
matches were generated.
.TP
\fBcomplete\fP [\fB\-abcdefgjksuv\fP] [\fB\-o\fP \fIcomp-option\fP] [\fB\-E\fP] [\fB\-A\fP \fIaction\fP] [\fB\-G\fP \fIglobpat\fP] [\fB\-W\fP \fIwordlist\fP] [\fB\-F\fP \fIfunction\fP] [\fB\-C\fP \fIcommand\fP]
\fBcomplete\fP [\fB\-abcdefgjksuv\fP] [\fB\-o\fP \fIcomp-option\fP] [\fB\-DE\fP] [\fB\-A\fP \fIaction\fP] [\fB\-G\fP \fIglobpat\fP] [\fB\-W\fP \fIwordlist\fP] [\fB\-F\fP \fIfunction\fP] [\fB\-C\fP \fIcommand\fP]
.br
[\fB\-X\fP \fIfilterpat\fP] [\fB\-P\fP \fIprefix\fP] [\fB\-S\fP \fIsuffix\fP] \fIname\fP [\fIname ...\fP]
.PD 0
.TP
\fBcomplete\fP \fB\-pr\fP [\fB\-E\fP] [\fIname\fP ...]
\fBcomplete\fP \fB\-pr\fP [\fB\-DE\fP] [\fIname\fP ...]
.PD
Specify how arguments to each \fIname\fP should be completed.
If the \fB\-p\fP option is supplied, or if no options are supplied,
@@ -6580,6 +6649,9 @@ them to be reused as input.
The \fB\-r\fP option removes a completion specification for
each \fIname\fP, or, if no \fIname\fPs are supplied, all
completion specifications.
The \fB\-D\fP option indicates that the remaining options and actions should
apply to the ``default'' command completion; that is, completion attempted
on a command for which no completion has previously been defined.
The \fB\-E\fP option indicates that the remaining options and actions should
apply to ``empty'' command completion; that is, completion attempted on a
blank line.
@@ -6759,7 +6831,7 @@ a \fIname\fP for which no specification exists, or
an error occurs adding a completion specification.
.RE
.TP
\fBcompopt\fP [\fB\-o\fP \fIoption\fP] [\fB+o\fP \fIoption\fP] [\fIname\fP]
\fBcompopt\fP [\fB\-o\fP \fIoption\fP] [\fB\-DE\fP] [\fB+o\fP \fIoption\fP] [\fIname\fP]
Modify completion options for each \fIname\fP according to the
\fIoption\fPs, or for the
currently-execution completion if no \fIname\fPs are supplied.
@@ -6767,6 +6839,12 @@ If no \fIoption\fPs are given, display the completion options for each
\fIname\fP or the current completion.
The possible values of \fIoption\fP are those valid for the \fBcomplete\fP
builtin described above.
The \fB\-D\fP option indicates that the remaining options should
apply to the ``default'' command completion; that is, completion attempted
on a command for which no completion has previously been defined.
The \fB\-E\fP option indicates that the remaining options should
apply to ``empty'' command completion; that is, completion attempted on a
blank line.
.PP
The return value is true unless an invalid option is supplied, an attempt
is made to modify the options for a \fIname\fP for which no completion
@@ -8262,6 +8340,7 @@ files are not processed, shell functions are not inherited from the
environment, and the
.SM
.BR SHELLOPTS ,
.BR BASHOPTS ,
.BR CDPATH ,
and
.B GLOBIGNORE
+19 -4
View File
@@ -4136,8 +4136,8 @@ Same as @code{-x}.
Turn on privileged mode.
In this mode, the @env{$BASH_ENV} and @env{$ENV} files are not
processed, shell functions are not inherited from the environment,
and the @env{SHELLOPTS}, @env{CDPATH} and @env{GLOBIGNORE} variables,
if they appear in the environment, are ignored.
and the @env{SHELLOPTS}, @env{BASHOPTS}, @env{CDPATH} and @env{GLOBIGNORE}
variables, if they appear in the environment, are ignored.
If the shell is started with the effective user (group) id not equal to the
real user (group) id, and the @code{-p} option is not supplied, these actions
are taken and the effective user id is set to the real user id.
@@ -4650,6 +4650,16 @@ variables for controlling the job control facilities
@item BASH
The full pathname used to execute the current instance of Bash.
@item BASHOPTS
A colon-separated list of enabled shell options. Each word in
the list is a valid argument for the @option{-s} option to the
@code{shopt} builtin command (@pxref{The Shopt Builtin}).
The options appearing in @env{BASHOPTS} are those reported
as @samp{on} by @samp{shopt}.
If this variable is in the environment when Bash
starts up, each shell option in the list will be enabled before
reading any startup files. This variable is readonly.
@item BASHPID
Expands to the process id of the current Bash process.
This differs from @code{$$} under certain circumstances, such as subshells
@@ -5495,8 +5505,9 @@ allow them to be specified.
If Bash is started with the effective user (group) id not equal to the
real user (group) id, and the @code{-p} option is not supplied, no startup
files are read, shell functions are not inherited from the environment,
the @env{SHELLOPTS} variable, if it appears in the environment, is ignored,
and the effective user id is set to the real user id.
the @env{SHELLOPTS}, @env{BASHOPTS}, @env{CDPATH}, and @env{GLOBIGNORE}
variables, if they appear in the environment, are ignored, and the effective
user id is set to the real user id.
If the @code{-p} option is supplied at invocation, the startup behavior is
the same, but the effective user id is not reset.
@@ -7241,6 +7252,10 @@ Include support for the @code{((@dots{}))} command
Include support for the extended pattern matching features described
above under @ref{Pattern Matching}.
@item --enable-extended-glob-default
Set the default value of the @var{extglob} shell option described
above under @ref{The Shopt Builtin} to be enabled.
@item --enable-help-builtin
Include the @code{help} builtin, which displays help on shell builtins and
variables (@pxref{Bash Builtins}).
+17 -5
View File
@@ -4136,8 +4136,8 @@ Same as @code{-x}.
Turn on privileged mode.
In this mode, the @env{$BASH_ENV} and @env{$ENV} files are not
processed, shell functions are not inherited from the environment,
and the @env{SHELLOPTS}, @env{CDPATH} and @env{GLOBIGNORE} variables,
if they appear in the environment, are ignored.
and the @env{SHELLOPTS}, @env{BASHOPTS}, @env{CDPATH} and @env{GLOBIGNORE}
variables, if they appear in the environment, are ignored.
If the shell is started with the effective user (group) id not equal to the
real user (group) id, and the @code{-p} option is not supplied, these actions
are taken and the effective user id is set to the real user id.
@@ -4650,6 +4650,16 @@ variables for controlling the job control facilities
@item BASH
The full pathname used to execute the current instance of Bash.
@item BASHOPTS
A colon-separated list of enabled shell options. Each word in
the list is a valid argument for the @option{-s} option to the
@code{shopt} builtin command (@pxref{The Shopt Builtin}).
The options appearing in @env{BASHOPTS} are those reported
as @samp{on} by @samp{shopt}.
If this variable is in the environment when Bash
starts up, each shell option in the list will be enabled before
reading any startup files. This variable is readonly.
@item BASHPID
Expands to the process id of the current Bash process.
This differs from @code{$$} under certain circumstances, such as subshells
@@ -4974,7 +4984,8 @@ is running;
the next time hostname completion is attempted after the
value is changed, Bash adds the contents of the new file to the
existing list.
If @env{HOSTFILE} is set, but has no value, Bash attempts to read
If @env{HOSTFILE} is set, but has no value, or does not name a readable file,
Bash attempts to read
@file{/etc/hosts} to obtain the list of possible hostname completions.
When @env{HOSTFILE} is unset, the hostname list is cleared.
@@ -5494,8 +5505,9 @@ allow them to be specified.
If Bash is started with the effective user (group) id not equal to the
real user (group) id, and the @code{-p} option is not supplied, no startup
files are read, shell functions are not inherited from the environment,
the @env{SHELLOPTS} variable, if it appears in the environment, is ignored,
and the effective user id is set to the real user id.
the @env{SHELLOPTS}, @env{BASHOPTS}, @env{CDPATH}, and @env{GLOBIGNORE}
variables, if they appear in the environment, are ignored, and the effective
user id is set to the real user id.
If the @code{-p} option is supplied at invocation, the startup behavior is
the same, but the effective user id is not reset.
+3 -3
View File
@@ -2,9 +2,9 @@
Copyright (C) 1988-2009 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Wed Jun 17 08:50:54 EDT 2009
@set LASTCHANGE Fri Aug 14 18:32:24 EDT 2009
@set EDITION 4.0
@set VERSION 4.0
@set UPDATED 17 June 2009
@set UPDATED-MONTH June 2009
@set UPDATED 14 August 2009
@set UPDATED-MONTH August 2009
+3 -3
View File
@@ -2,9 +2,9 @@
Copyright (C) 1988-2009 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Tue May 26 17:04:05 EDT 2009
@set LASTCHANGE Wed Jun 17 08:50:54 EDT 2009
@set EDITION 4.0
@set VERSION 4.0
@set UPDATED 26 May 2009
@set UPDATED-MONTH May 2009
@set UPDATED 17 June 2009
@set UPDATED-MONTH June 2009
+20
View File
@@ -883,9 +883,29 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
#if defined (DPAREN_ARITHMETIC)
case cm_arith:
was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
if (ignore_return)
command->value.Arith->flags |= CMD_IGNORE_RETURN;
line_number_for_err_trap = save_line_number = line_number;
exec_result = execute_arith_command (command->value.Arith);
line_number = save_line_number;
if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
{
last_command_exit_value = exec_result;
save_line_number = line_number;
line_number = line_number_for_err_trap;
run_error_trap ();
line_number = save_line_number;
}
if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
{
last_command_exit_value = exec_result;
run_pending_traps ();
jump_to_top_level (ERREXIT);
}
break;
#endif
+2 -4
View File
@@ -902,7 +902,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
{
last_command_exit_value = exec_result;
save_line_number = line_number
save_line_number = line_number;
line_number = line_number_for_err_trap;
run_error_trap ();
line_number = save_line_number;
@@ -3270,9 +3270,7 @@ static int
execute_cond_command (cond_command)
COND_COM *cond_command;
{
int retval, save_line_number, invert;
invert = cond_command->flags & CMD_I
int retval, save_line_number;
retval = EXECUTION_SUCCESS;
save_line_number = line_number;
+5
View File
@@ -54,6 +54,11 @@ extern void print_cond_command __P((COND_COM *));
#endif
/* set -x support */
extern void xtrace_init __P((void));
#ifdef NEED_XTRACE_SET_DECL
extern void xtrace_set __P((int, FILE *));
#endif
extern void xtrace_reset __P((void));
extern char *indirection_level_string __P((void));
extern void xtrace_print_assignment __P((char *, char *, int, int));
extern void xtrace_print_word_list __P((WORD_LIST *, int));
+13 -2
View File
@@ -54,6 +54,10 @@ extern void print_cond_command __P((COND_COM *));
#endif
/* set -x support */
extern void xtrace_init __P((void));
#ifdef NEED_XTRACE_SET_DECL
extern void xtrace_set __P((int, FILE *));
#endif
extern char *indirection_level_string __P((void));
extern void xtrace_print_assignment __P((char *, char *, int, int));
extern void xtrace_print_word_list __P((WORD_LIST *, int));
@@ -135,7 +139,7 @@ extern int find_string_in_alist __P((char *, STRING_INT_ALIST *, int));
extern char *find_token_in_alist __P((int, STRING_INT_ALIST *, int));
extern int find_index_in_alist __P((char *, STRING_INT_ALIST *, int));
extern char *substring __P((char *, int, int));
extern char *substring __P((const char *, int, int));
extern char *strsub __P((char *, char *, char *, int));
extern char *strcreplace __P((char *, int, char *, int));
extern void strip_leading __P((char *));
@@ -192,6 +196,8 @@ extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
extern char *fmtumax __P((uintmax_t, int, char *, size_t, int));
/* Declarations for functions defined in lib/sh/fpurge.c */
#if defined NEED_FPURGE_DECL
#if !HAVE_DECL_FPURGE
#if HAVE_FPURGE
@@ -200,7 +206,7 @@ extern char *fmtumax __P((uintmax_t, int, char *, size_t, int));
extern int fpurge __P((FILE *stream));
#endif /* HAVE_DECL_FPURGE */
#endif /* NEED_FPURGE_DECL */
/* Declarations for functions defined in lib/sh/getcwd.c */
#if !defined (HAVE_GETCWD)
@@ -224,6 +230,11 @@ extern char *uitos __P((uintmax_t));
extern char *sh_makepath __P((const char *, const char *, int));
/* declarations for functions defined in lib/sh/mbscasecmp.c */
#if !defined (HAVE_MBSCASECMP)
extern char *mbscasecmp __P((const char *, const char *));
#endif
/* declarations for functions defined in lib/sh/mbschr.c */
#if !defined (HAVE_MBSCHR)
extern char *mbschr __P((const char *, int));
+5
View File
@@ -2372,6 +2372,8 @@ wait_for (pid)
if (interactive && job_control == 0)
QUIT;
/* Check for terminating signals and exit the shell if we receive one */
CHECK_TERMSIG;
/* If we say wait_for (), then we have a record of this child somewhere.
If it and none of its peers are running, don't call waitchld(). */
@@ -2450,6 +2452,8 @@ wait_for (pid)
old SIGINT signal handler. */
if (interactive && job_control == 0)
QUIT;
/* Check for terminating signals and exit the shell if we receive one */
CHECK_TERMSIG;
}
while (PRUNNING (child) || (job != NO_JOB && RUNNING (job)));
@@ -3043,6 +3047,7 @@ waitchld (wpid, block)
: 0;
if (sigchld || block == 0)
waitpid_flags |= WNOHANG;
/* Check for terminating signals and exit the shell if we receive one */
CHECK_TERMSIG;
pid = WAITPID (-1, &status, waitpid_flags);
-3
View File
@@ -455,7 +455,6 @@ start_pipeline ()
cleanup_the_pipeline ();
pipeline_pgrp = 0;
#if defined (PGRP_PIPE)
itrace("start_pipeline: cleaning up existing pipeline: closing %d %d", pgrp_pipe[0], pgrp_pipe[1]);
sh_closepipe (pgrp_pipe);
#endif
}
@@ -465,7 +464,6 @@ itrace("start_pipeline: cleaning up existing pipeline: closing %d %d", pgrp_pipe
{
if (pipe (pgrp_pipe) == -1)
sys_error (_("start_pipeline: pgrp pipe"));
itrace("start_pipeline: pgrp_pipe: %d %d", pgrp_pipe[0], pgrp_pipe[1]);
}
#endif
}
@@ -487,7 +485,6 @@ stop_pipeline (async, deferred)
#if defined (PGRP_PIPE)
/* The parent closes the process group synchronization pipe. */
itrace("stop_pipeline: close pgrp_pipe %d %d", pgrp_pipe[0], pgrp_pipe[1]);
sh_closepipe (pgrp_pipe);
#endif
+9
View File
@@ -1002,6 +1002,15 @@ character. A negative count searches for previous occurrences.
A character is read and point is moved to the previous occurrence of that
character. A negative count searches for subsequent occurrences.
.TP
.B skip\-csi\-sequence ()
Read enough characters to consume a multi-key sequence such as those
defined for keys like Home and End. Such sequences begin with a
Control Sequence Indicator (CSI), usually ESC\-[. If this sequence is
bound to "\e[", keys producing such sequences will have no effect
unless explicitly bound to a readline command, instead of inserting
stray characters into the editing buffer. This is unbound by default,
but usually bound to ESC\-[.
.TP
.B insert\-comment (M\-#)
Without a numeric argument, the value of the readline
.B comment\-begin
File diff suppressed because it is too large Load Diff
+9
View File
@@ -1436,6 +1436,15 @@ A character is read and point is moved to the previous occurrence
of that character. A negative count searches for subsequent
occurrences.
@item skip-csi-sequence ()
Read enough characters to consume a multi-key sequence such as those
defined for keys like Home and End. Such sequences begin with a
Control Sequence Indicator (CSI), usually ESC-[. If this sequence is
bound to "\e[", keys producing such sequences will have no effect
unless explicitly bound to a readline command, instead of inserting
stray characters into the editing buffer. This is unbound by default,
but usually bound to ESC-[.
@item insert-comment (M-#)
Without a numeric argument, the value of the @code{comment-begin}
variable is inserted at the beginning of the current line.
File diff suppressed because it is too large Load Diff
+1
View File
@@ -124,6 +124,7 @@ static const FUNMAP default_funmap[] = {
{ "revert-line", rl_revert_line },
{ "self-insert", rl_insert },
{ "set-mark", rl_set_mark },
{ "skip-csi-sequence", rl_skip_csi_sequence },
{ "start-kbd-macro", rl_start_kbd_macro },
{ "tab-insert", rl_tab_insert },
{ "tilde-expand", rl_tilde_expand },
+256
View File
@@ -0,0 +1,256 @@
/* funmap.c -- attach names to functions. */
/* Copyright (C) 1987-2009 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.
Readline 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.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if !defined (BUFSIZ)
#include <stdio.h>
#endif /* BUFSIZ */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "rlconf.h"
#include "readline.h"
#include "xmalloc.h"
#ifdef __STDC__
typedef int QSFUNC (const void *, const void *);
#else
typedef int QSFUNC ();
#endif
extern int _rl_qsort_string_compare PARAMS((char **, char **));
FUNMAP **funmap;
static int funmap_size;
static int funmap_entry;
/* After initializing the function map, this is the index of the first
program specific function. */
int funmap_program_specific_entry_start;
static const FUNMAP default_funmap[] = {
{ "abort", rl_abort },
{ "accept-line", rl_newline },
{ "arrow-key-prefix", rl_arrow_keys },
{ "backward-byte", rl_backward_byte },
{ "backward-char", rl_backward_char },
{ "backward-delete-char", rl_rubout },
{ "backward-kill-line", rl_backward_kill_line },
{ "backward-kill-word", rl_backward_kill_word },
{ "backward-word", rl_backward_word },
{ "beginning-of-history", rl_beginning_of_history },
{ "beginning-of-line", rl_beg_of_line },
{ "call-last-kbd-macro", rl_call_last_kbd_macro },
{ "capitalize-word", rl_capitalize_word },
{ "character-search", rl_char_search },
{ "character-search-backward", rl_backward_char_search },
{ "clear-screen", rl_clear_screen },
{ "complete", rl_complete },
{ "copy-backward-word", rl_copy_backward_word },
{ "copy-forward-word", rl_copy_forward_word },
{ "copy-region-as-kill", rl_copy_region_to_kill },
{ "delete-char", rl_delete },
{ "delete-char-or-list", rl_delete_or_show_completions },
{ "delete-horizontal-space", rl_delete_horizontal_space },
{ "digit-argument", rl_digit_argument },
{ "do-lowercase-version", rl_do_lowercase_version },
{ "downcase-word", rl_downcase_word },
{ "dump-functions", rl_dump_functions },
{ "dump-macros", rl_dump_macros },
{ "dump-variables", rl_dump_variables },
{ "emacs-editing-mode", rl_emacs_editing_mode },
{ "end-kbd-macro", rl_end_kbd_macro },
{ "end-of-history", rl_end_of_history },
{ "end-of-line", rl_end_of_line },
{ "exchange-point-and-mark", rl_exchange_point_and_mark },
{ "forward-backward-delete-char", rl_rubout_or_delete },
{ "forward-byte", rl_forward_byte },
{ "forward-char", rl_forward_char },
{ "forward-search-history", rl_forward_search_history },
{ "forward-word", rl_forward_word },
{ "history-search-backward", rl_history_search_backward },
{ "history-search-forward", rl_history_search_forward },
{ "insert-comment", rl_insert_comment },
{ "insert-completions", rl_insert_completions },
{ "kill-whole-line", rl_kill_full_line },
{ "kill-line", rl_kill_line },
{ "kill-region", rl_kill_region },
{ "kill-word", rl_kill_word },
{ "menu-complete", rl_menu_complete },
{ "menu-complete-backward", rl_backward_menu_complete },
{ "next-history", rl_get_next_history },
{ "non-incremental-forward-search-history", rl_noninc_forward_search },
{ "non-incremental-reverse-search-history", rl_noninc_reverse_search },
{ "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
{ "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
{ "overwrite-mode", rl_overwrite_mode },
#ifdef __CYGWIN__
{ "paste-from-clipboard", rl_paste_from_clipboard },
#endif
{ "possible-completions", rl_possible_completions },
{ "previous-history", rl_get_previous_history },
{ "quoted-insert", rl_quoted_insert },
{ "re-read-init-file", rl_re_read_init_file },
{ "redraw-current-line", rl_refresh_line},
{ "reverse-search-history", rl_reverse_search_history },
{ "revert-line", rl_revert_line },
{ "self-insert", rl_insert },
{ "set-mark", rl_set_mark },
{ "start-kbd-macro", rl_start_kbd_macro },
{ "tab-insert", rl_tab_insert },
{ "tilde-expand", rl_tilde_expand },
{ "transpose-chars", rl_transpose_chars },
{ "transpose-words", rl_transpose_words },
{ "tty-status", rl_tty_status },
{ "undo", rl_undo_command },
{ "universal-argument", rl_universal_argument },
{ "unix-filename-rubout", rl_unix_filename_rubout },
{ "unix-line-discard", rl_unix_line_discard },
{ "unix-word-rubout", rl_unix_word_rubout },
{ "upcase-word", rl_upcase_word },
{ "yank", rl_yank },
{ "yank-last-arg", rl_yank_last_arg },
{ "yank-nth-arg", rl_yank_nth_arg },
{ "yank-pop", rl_yank_pop },
#if defined (VI_MODE)
{ "vi-append-eol", rl_vi_append_eol },
{ "vi-append-mode", rl_vi_append_mode },
{ "vi-arg-digit", rl_vi_arg_digit },
{ "vi-back-to-indent", rl_vi_back_to_indent },
{ "vi-bWord", rl_vi_bWord },
{ "vi-bword", rl_vi_bword },
{ "vi-change-case", rl_vi_change_case },
{ "vi-change-char", rl_vi_change_char },
{ "vi-change-to", rl_vi_change_to },
{ "vi-char-search", rl_vi_char_search },
{ "vi-column", rl_vi_column },
{ "vi-complete", rl_vi_complete },
{ "vi-delete", rl_vi_delete },
{ "vi-delete-to", rl_vi_delete_to },
{ "vi-eWord", rl_vi_eWord },
{ "vi-editing-mode", rl_vi_editing_mode },
{ "vi-end-word", rl_vi_end_word },
{ "vi-eof-maybe", rl_vi_eof_maybe },
{ "vi-eword", rl_vi_eword },
{ "vi-fWord", rl_vi_fWord },
{ "vi-fetch-history", rl_vi_fetch_history },
{ "vi-first-print", rl_vi_first_print },
{ "vi-fword", rl_vi_fword },
{ "vi-goto-mark", rl_vi_goto_mark },
{ "vi-insert-beg", rl_vi_insert_beg },
{ "vi-insertion-mode", rl_vi_insertion_mode },
{ "vi-match", rl_vi_match },
{ "vi-movement-mode", rl_vi_movement_mode },
{ "vi-next-word", rl_vi_next_word },
{ "vi-overstrike", rl_vi_overstrike },
{ "vi-overstrike-delete", rl_vi_overstrike_delete },
{ "vi-prev-word", rl_vi_prev_word },
{ "vi-put", rl_vi_put },
{ "vi-redo", rl_vi_redo },
{ "vi-replace", rl_vi_replace },
{ "vi-rubout", rl_vi_rubout },
{ "vi-search", rl_vi_search },
{ "vi-search-again", rl_vi_search_again },
{ "vi-set-mark", rl_vi_set_mark },
{ "vi-subst", rl_vi_subst },
{ "vi-tilde-expand", rl_vi_tilde_expand },
{ "vi-yank-arg", rl_vi_yank_arg },
{ "vi-yank-to", rl_vi_yank_to },
#endif /* VI_MODE */
{(char *)NULL, (rl_command_func_t *)NULL }
};
int
rl_add_funmap_entry (name, function)
const char *name;
rl_command_func_t *function;
{
if (funmap_entry + 2 >= funmap_size)
{
funmap_size += 64;
funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
}
funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
funmap[funmap_entry]->name = name;
funmap[funmap_entry]->function = function;
funmap[++funmap_entry] = (FUNMAP *)NULL;
return funmap_entry;
}
static int funmap_initialized;
/* Make the funmap contain all of the default entries. */
void
rl_initialize_funmap ()
{
register int i;
if (funmap_initialized)
return;
for (i = 0; default_funmap[i].name; i++)
rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function);
funmap_initialized = 1;
funmap_program_specific_entry_start = i;
}
/* Produce a NULL terminated array of known function names. The array
is sorted. The array itself is allocated, but not the strings inside.
You should free () the array when you done, but not the pointrs. */
const char **
rl_funmap_names ()
{
const char **result;
int result_size, result_index;
/* Make sure that the function map has been initialized. */
rl_initialize_funmap ();
for (result_index = result_size = 0, result = (const char **)NULL; funmap[result_index]; result_index++)
{
if (result_index + 2 > result_size)
{
result_size += 20;
result = (const char **)xrealloc (result, result_size * sizeof (char *));
}
result[result_index] = funmap[result_index]->name;
result[result_index + 1] = (char *)NULL;
}
qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
return (result);
}
+1
View File
@@ -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_skip_csi_sequence PARAMS((int, int));
extern int rl_arrow_keys PARAMS((int, int));
/* Bindable commands for inserting and deleting text. */
+872
View File
@@ -0,0 +1,872 @@
/* Readline.h -- the names of functions callable from within readline. */
/* Copyright (C) 1987-2009 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.
Readline 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.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_READLINE_H_)
#define _READLINE_H_
#ifdef __cplusplus
extern "C" {
#endif
#if defined (READLINE_LIBRARY)
# include "rlstdc.h"
# include "rltypedefs.h"
# include "keymaps.h"
# include "tilde.h"
#else
# include <readline/rlstdc.h>
# include <readline/rltypedefs.h>
# include <readline/keymaps.h>
# include <readline/tilde.h>
#endif
/* Hex-encoded Readline version number. */
#define RL_READLINE_VERSION 0x0600 /* Readline 6.0 */
#define RL_VERSION_MAJOR 6
#define RL_VERSION_MINOR 0
/* Readline data structures. */
/* Maintaining the state of undo. We remember individual deletes and inserts
on a chain of things to do. */
/* The actions that undo knows how to undo. Notice that UNDO_DELETE means
to insert some text, and UNDO_INSERT means to delete some text. I.e.,
the code tells undo what to undo, not how to undo it. */
enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END };
/* What an element of THE_UNDO_LIST looks like. */
typedef struct undo_list {
struct undo_list *next;
int start, end; /* Where the change took place. */
char *text; /* The text to insert, if undoing a delete. */
enum undo_code what; /* Delete, Insert, Begin, End. */
} UNDO_LIST;
/* The current undo list for RL_LINE_BUFFER. */
extern UNDO_LIST *rl_undo_list;
/* The data structure for mapping textual names to code addresses. */
typedef struct _funmap {
const char *name;
rl_command_func_t *function;
} FUNMAP;
extern FUNMAP **funmap;
/* **************************************************************** */
/* */
/* Functions available to bind to key sequences */
/* */
/* **************************************************************** */
/* Bindable commands for numeric arguments. */
extern int rl_digit_argument PARAMS((int, int));
extern int rl_universal_argument PARAMS((int, int));
/* Bindable commands for moving the cursor. */
extern int rl_forward_byte PARAMS((int, int));
extern int rl_forward_char PARAMS((int, int));
extern int rl_forward PARAMS((int, int));
extern int rl_backward_byte PARAMS((int, int));
extern int rl_backward_char PARAMS((int, int));
extern int rl_backward PARAMS((int, int));
extern int rl_beg_of_line PARAMS((int, int));
extern int rl_end_of_line PARAMS((int, int));
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_arrow_keys PARAMS((int, int));
/* Bindable commands for inserting and deleting text. */
extern int rl_insert PARAMS((int, int));
extern int rl_quoted_insert PARAMS((int, int));
extern int rl_tab_insert PARAMS((int, int));
extern int rl_newline PARAMS((int, int));
extern int rl_do_lowercase_version PARAMS((int, int));
extern int rl_rubout PARAMS((int, int));
extern int rl_delete PARAMS((int, int));
extern int rl_rubout_or_delete PARAMS((int, int));
extern int rl_delete_horizontal_space PARAMS((int, int));
extern int rl_delete_or_show_completions PARAMS((int, int));
extern int rl_insert_comment PARAMS((int, int));
/* Bindable commands for changing case. */
extern int rl_upcase_word PARAMS((int, int));
extern int rl_downcase_word PARAMS((int, int));
extern int rl_capitalize_word PARAMS((int, int));
/* Bindable commands for transposing characters and words. */
extern int rl_transpose_words PARAMS((int, int));
extern int rl_transpose_chars PARAMS((int, int));
/* Bindable commands for searching within a line. */
extern int rl_char_search PARAMS((int, int));
extern int rl_backward_char_search PARAMS((int, int));
/* Bindable commands for readline's interface to the command history. */
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));
/* Bindable commands for managing the mark and region. */
extern int rl_set_mark PARAMS((int, int));
extern int rl_exchange_point_and_mark PARAMS((int, int));
/* Bindable commands to set the editing mode (emacs or vi). */
extern int rl_vi_editing_mode PARAMS((int, int));
extern int rl_emacs_editing_mode PARAMS((int, int));
/* Bindable commands to change the insert mode (insert or overwrite) */
extern int rl_overwrite_mode PARAMS((int, int));
/* Bindable commands for managing key bindings. */
extern int rl_re_read_init_file PARAMS((int, int));
extern int rl_dump_functions PARAMS((int, int));
extern int rl_dump_macros PARAMS((int, int));
extern int rl_dump_variables PARAMS((int, int));
/* Bindable commands for word completion. */
extern int rl_complete PARAMS((int, int));
extern int rl_possible_completions PARAMS((int, int));
extern int rl_insert_completions PARAMS((int, int));
extern int rl_menu_complete PARAMS((int, int));
extern int rl_backward_menu_complete PARAMS((int, int));
/* Bindable commands for killing and yanking text, and managing the kill ring. */
extern int rl_kill_word PARAMS((int, int));
extern int rl_backward_kill_word PARAMS((int, int));
extern int rl_kill_line PARAMS((int, int));
extern int rl_backward_kill_line PARAMS((int, int));
extern int rl_kill_full_line PARAMS((int, int));
extern int rl_unix_word_rubout PARAMS((int, int));
extern int rl_unix_filename_rubout PARAMS((int, int));
extern int rl_unix_line_discard PARAMS((int, int));
extern int rl_copy_region_to_kill PARAMS((int, int));
extern int rl_kill_region PARAMS((int, int));
extern int rl_copy_forward_word PARAMS((int, int));
extern int rl_copy_backward_word PARAMS((int, int));
extern int rl_yank PARAMS((int, int));
extern int rl_yank_pop PARAMS((int, int));
extern int rl_yank_nth_arg PARAMS((int, int));
extern int rl_yank_last_arg PARAMS((int, int));
/* Not available unless __CYGWIN__ is defined. */
#ifdef __CYGWIN__
extern int rl_paste_from_clipboard PARAMS((int, int));
#endif
/* Bindable commands for incremental searching. */
extern int rl_reverse_search_history PARAMS((int, int));
extern int rl_forward_search_history PARAMS((int, int));
/* Bindable keyboard macro commands. */
extern int rl_start_kbd_macro PARAMS((int, int));
extern int rl_end_kbd_macro PARAMS((int, int));
extern int rl_call_last_kbd_macro PARAMS((int, int));
/* Bindable undo commands. */
extern int rl_revert_line PARAMS((int, int));
extern int rl_undo_command PARAMS((int, int));
/* Bindable tilde expansion commands. */
extern int rl_tilde_expand PARAMS((int, int));
/* Bindable terminal control commands. */
extern int rl_restart_output PARAMS((int, int));
extern int rl_stop_output PARAMS((int, int));
/* Miscellaneous bindable commands. */
extern int rl_abort PARAMS((int, int));
extern int rl_tty_status PARAMS((int, int));
/* Bindable commands for incremental and non-incremental history searching. */
extern int rl_history_search_forward PARAMS((int, int));
extern int rl_history_search_backward PARAMS((int, int));
extern int rl_noninc_forward_search PARAMS((int, int));
extern int rl_noninc_reverse_search PARAMS((int, int));
extern int rl_noninc_forward_search_again PARAMS((int, int));
extern int rl_noninc_reverse_search_again PARAMS((int, int));
/* Bindable command used when inserting a matching close character. */
extern int rl_insert_close PARAMS((int, int));
/* Not available unless READLINE_CALLBACKS is defined. */
extern void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *));
extern void rl_callback_read_char PARAMS((void));
extern void rl_callback_handler_remove PARAMS((void));
/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
/* VI-mode bindable commands. */
extern int rl_vi_redo PARAMS((int, int));
extern int rl_vi_undo PARAMS((int, int));
extern int rl_vi_yank_arg PARAMS((int, int));
extern int rl_vi_fetch_history PARAMS((int, int));
extern int rl_vi_search_again PARAMS((int, int));
extern int rl_vi_search PARAMS((int, int));
extern int rl_vi_complete PARAMS((int, int));
extern int rl_vi_tilde_expand PARAMS((int, int));
extern int rl_vi_prev_word PARAMS((int, int));
extern int rl_vi_next_word PARAMS((int, int));
extern int rl_vi_end_word PARAMS((int, int));
extern int rl_vi_insert_beg PARAMS((int, int));
extern int rl_vi_append_mode PARAMS((int, int));
extern int rl_vi_append_eol PARAMS((int, int));
extern int rl_vi_eof_maybe PARAMS((int, int));
extern int rl_vi_insertion_mode PARAMS((int, int));
extern int rl_vi_insert_mode PARAMS((int, int));
extern int rl_vi_movement_mode PARAMS((int, int));
extern int rl_vi_arg_digit PARAMS((int, int));
extern int rl_vi_change_case PARAMS((int, int));
extern int rl_vi_put PARAMS((int, int));
extern int rl_vi_column PARAMS((int, int));
extern int rl_vi_delete_to PARAMS((int, int));
extern int rl_vi_change_to PARAMS((int, int));
extern int rl_vi_yank_to PARAMS((int, int));
extern int rl_vi_rubout PARAMS((int, int));
extern int rl_vi_delete PARAMS((int, int));
extern int rl_vi_back_to_indent PARAMS((int, int));
extern int rl_vi_first_print PARAMS((int, int));
extern int rl_vi_char_search PARAMS((int, int));
extern int rl_vi_match PARAMS((int, int));
extern int rl_vi_change_char PARAMS((int, int));
extern int rl_vi_subst PARAMS((int, int));
extern int rl_vi_overstrike PARAMS((int, int));
extern int rl_vi_overstrike_delete PARAMS((int, int));
extern int rl_vi_replace PARAMS((int, int));
extern int rl_vi_set_mark PARAMS((int, int));
extern int rl_vi_goto_mark PARAMS((int, int));
/* VI-mode utility functions. */
extern int rl_vi_check PARAMS((void));
extern int rl_vi_domove PARAMS((int, int *));
extern int rl_vi_bracktype PARAMS((int));
extern void rl_vi_start_inserting PARAMS((int, int, int));
/* VI-mode pseudo-bindable commands, used as utility functions. */
extern int rl_vi_fWord PARAMS((int, int));
extern int rl_vi_bWord PARAMS((int, int));
extern int rl_vi_eWord PARAMS((int, int));
extern int rl_vi_fword PARAMS((int, int));
extern int rl_vi_bword PARAMS((int, int));
extern int rl_vi_eword PARAMS((int, int));
/* **************************************************************** */
/* */
/* Well Published Functions */
/* */
/* **************************************************************** */
/* Readline functions. */
/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
extern char *readline PARAMS((const char *));
extern int rl_set_prompt PARAMS((const char *));
extern int rl_expand_prompt PARAMS((char *));
extern int rl_initialize PARAMS((void));
/* Undocumented; unused by readline */
extern int rl_discard_argument PARAMS((void));
/* Utility functions to bind keys to readline commands. */
extern int rl_add_defun PARAMS((const char *, rl_command_func_t *, int));
extern int rl_bind_key PARAMS((int, rl_command_func_t *));
extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
extern int rl_unbind_key PARAMS((int));
extern int rl_unbind_key_in_map PARAMS((int, Keymap));
extern int rl_bind_key_if_unbound PARAMS((int, rl_command_func_t *));
extern int rl_bind_key_if_unbound_in_map PARAMS((int, rl_command_func_t *, Keymap));
extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap));
extern int rl_unbind_command_in_map PARAMS((const char *, Keymap));
extern int rl_bind_keyseq PARAMS((const char *, rl_command_func_t *));
extern int rl_bind_keyseq_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *));
extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap));
extern char *rl_variable_value PARAMS((const char *));
extern int rl_variable_bind PARAMS((const char *, const char *));
/* Backwards compatibility, use rl_bind_keyseq_in_map instead. */
extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
/* Backwards compatibility, use rl_generic_bind instead. */
extern int rl_macro_bind PARAMS((const char *, const char *, Keymap));
/* Undocumented in the texinfo manual; not really useful to programs. */
extern int rl_translate_keyseq PARAMS((const char *, char *, int *));
extern char *rl_untranslate_keyseq PARAMS((int));
extern rl_command_func_t *rl_named_function PARAMS((const char *));
extern rl_command_func_t *rl_function_of_keyseq PARAMS((const char *, Keymap, int *));
extern void rl_list_funmap_names PARAMS((void));
extern char **rl_invoking_keyseqs_in_map PARAMS((rl_command_func_t *, Keymap));
extern char **rl_invoking_keyseqs PARAMS((rl_command_func_t *));
extern void rl_function_dumper PARAMS((int));
extern void rl_macro_dumper PARAMS((int));
extern void rl_variable_dumper PARAMS((int));
extern int rl_read_init_file PARAMS((const char *));
extern int rl_parse_and_bind PARAMS((char *));
/* Functions for manipulating keymaps. */
extern Keymap rl_make_bare_keymap PARAMS((void));
extern Keymap rl_copy_keymap PARAMS((Keymap));
extern Keymap rl_make_keymap PARAMS((void));
extern void rl_discard_keymap PARAMS((Keymap));
extern Keymap rl_get_keymap_by_name PARAMS((const char *));
extern char *rl_get_keymap_name PARAMS((Keymap));
extern void rl_set_keymap PARAMS((Keymap));
extern Keymap rl_get_keymap PARAMS((void));
/* Undocumented; used internally only. */
extern void rl_set_keymap_from_edit_mode PARAMS((void));
extern char *rl_get_keymap_name_from_edit_mode PARAMS((void));
/* Functions for manipulating the funmap, which maps command names to functions. */
extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *));
extern const char **rl_funmap_names PARAMS((void));
/* Undocumented, only used internally -- there is only one funmap, and this
function may be called only once. */
extern void rl_initialize_funmap PARAMS((void));
/* Utility functions for managing keyboard macros. */
extern void rl_push_macro_input PARAMS((char *));
/* Functions for undoing, from undo.c */
extern void rl_add_undo PARAMS((enum undo_code, int, int, char *));
extern void rl_free_undo_list PARAMS((void));
extern int rl_do_undo PARAMS((void));
extern int rl_begin_undo_group PARAMS((void));
extern int rl_end_undo_group PARAMS((void));
extern int rl_modifying PARAMS((int, int));
/* Functions for redisplay. */
extern void rl_redisplay PARAMS((void));
extern int rl_on_new_line PARAMS((void));
extern int rl_on_new_line_with_prompt PARAMS((void));
extern int rl_forced_update_display PARAMS((void));
extern int rl_clear_message PARAMS((void));
extern int rl_reset_line_state PARAMS((void));
extern int rl_crlf PARAMS((void));
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else
extern int rl_message ();
#endif
extern int rl_show_char PARAMS((int));
/* Undocumented in texinfo manual. */
extern int rl_character_len PARAMS((int, int));
/* Save and restore internal prompt redisplay information. */
extern void rl_save_prompt PARAMS((void));
extern void rl_restore_prompt PARAMS((void));
/* Modifying text. */
extern void rl_replace_line PARAMS((const char *, int));
extern int rl_insert_text PARAMS((const char *));
extern int rl_delete_text PARAMS((int, int));
extern int rl_kill_text PARAMS((int, int));
extern char *rl_copy_text PARAMS((int, int));
/* Terminal and tty mode management. */
extern void rl_prep_terminal PARAMS((int));
extern void rl_deprep_terminal PARAMS((void));
extern void rl_tty_set_default_bindings PARAMS((Keymap));
extern void rl_tty_unset_default_bindings PARAMS((Keymap));
extern int rl_reset_terminal PARAMS((const char *));
extern void rl_resize_terminal PARAMS((void));
extern void rl_set_screen_size PARAMS((int, int));
extern void rl_get_screen_size PARAMS((int *, int *));
extern void rl_reset_screen_size PARAMS((void));
extern char *rl_get_termcap PARAMS((const char *));
/* Functions for character input. */
extern int rl_stuff_char PARAMS((int));
extern int rl_execute_next PARAMS((int));
extern int rl_clear_pending_input PARAMS((void));
extern int rl_read_key PARAMS((void));
extern int rl_getc PARAMS((FILE *));
extern int rl_set_keyboard_input_timeout PARAMS((int));
/* `Public' utility functions . */
extern void rl_extend_line_buffer PARAMS((int));
extern int rl_ding PARAMS((void));
extern int rl_alphabetic PARAMS((int));
extern void rl_free PARAMS((void *));
/* Readline signal handling, from signals.c */
extern int rl_set_signals PARAMS((void));
extern int rl_clear_signals PARAMS((void));
extern void rl_cleanup_after_signal PARAMS((void));
extern void rl_reset_after_signal PARAMS((void));
extern void rl_free_line_state PARAMS((void));
extern void rl_echo_signal_char PARAMS((int));
extern int rl_set_paren_blink_timeout PARAMS((int));
/* Undocumented. */
extern int rl_maybe_save_line PARAMS((void));
extern int rl_maybe_unsave_line PARAMS((void));
extern int rl_maybe_replace_line PARAMS((void));
/* Completion functions. */
extern int rl_complete_internal PARAMS((int));
extern void rl_display_match_list PARAMS((char **, int, int));
extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *));
extern char *rl_username_completion_function PARAMS((const char *, int));
extern char *rl_filename_completion_function PARAMS((const char *, int));
extern int rl_completion_mode PARAMS((rl_command_func_t *));
#if 0
/* Backwards compatibility (compat.c). These will go away sometime. */
extern void free_undo_list PARAMS((void));
extern int maybe_save_line PARAMS((void));
extern int maybe_unsave_line PARAMS((void));
extern int maybe_replace_line PARAMS((void));
extern int ding PARAMS((void));
extern int alphabetic PARAMS((int));
extern int crlf PARAMS((void));
extern char **completion_matches PARAMS((char *, rl_compentry_func_t *));
extern char *username_completion_function PARAMS((const char *, int));
extern char *filename_completion_function PARAMS((const char *, int));
#endif
/* **************************************************************** */
/* */
/* Well Published Variables */
/* */
/* **************************************************************** */
/* The version of this incarnation of the readline library. */
extern const char *rl_library_version; /* e.g., "4.2" */
extern int rl_readline_version; /* e.g., 0x0402 */
/* True if this is real GNU readline. */
extern int rl_gnu_readline_p;
/* Flags word encapsulating the current readline state. */
extern int rl_readline_state;
/* Says which editing mode readline is currently using. 1 means emacs mode;
0 means vi mode. */
extern int rl_editing_mode;
/* Insert or overwrite mode for emacs mode. 1 means insert mode; 0 means
overwrite mode. Reset to insert mode on each input line. */
extern int rl_insert_mode;
/* The name of the calling program. You should initialize this to
whatever was in argv[0]. It is used when parsing conditionals. */
extern const char *rl_readline_name;
/* The prompt readline uses. This is set from the argument to
readline (), and should not be assigned to directly. */
extern char *rl_prompt;
/* The prompt string that is actually displayed by rl_redisplay. Public so
applications can more easily supply their own redisplay functions. */
extern char *rl_display_prompt;
/* The line buffer that is in use. */
extern char *rl_line_buffer;
/* The location of point, and end. */
extern int rl_point;
extern int rl_end;
/* The mark, or saved cursor position. */
extern int rl_mark;
/* Flag to indicate that readline has finished with the current input
line and should return it. */
extern int rl_done;
/* If set to a character value, that will be the next keystroke read. */
extern int rl_pending_input;
/* Non-zero if we called this function from _rl_dispatch(). It's present
so functions can find out whether they were called from a key binding
or directly from an application. */
extern int rl_dispatching;
/* Non-zero if the user typed a numeric argument before executing the
current function. */
extern int rl_explicit_arg;
/* The current value of the numeric argument specified by the user. */
extern int rl_numeric_arg;
/* The address of the last command function Readline executed. */
extern rl_command_func_t *rl_last_func;
/* The name of the terminal to use. */
extern const char *rl_terminal_name;
/* The input and output streams. */
extern FILE *rl_instream;
extern FILE *rl_outstream;
/* If non-zero, Readline gives values of LINES and COLUMNS from the environment
greater precedence than values fetched from the kernel when computing the
screen dimensions. */
extern int rl_prefer_env_winsize;
/* If non-zero, then this is the address of a function to call just
before readline_internal () prints the first prompt. */
extern rl_hook_func_t *rl_startup_hook;
/* 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. */
extern rl_hook_func_t *rl_pre_input_hook;
/* The address of a function to call periodically while Readline is
awaiting character input, or NULL, for no event handling. */
extern rl_hook_func_t *rl_event_hook;
/* The address of the function to call to fetch a character from the current
Readline input stream */
extern rl_getc_func_t *rl_getc_function;
extern rl_voidfunc_t *rl_redisplay_function;
extern rl_vintfunc_t *rl_prep_term_function;
extern rl_voidfunc_t *rl_deprep_term_function;
/* Dispatch variables. */
extern Keymap rl_executing_keymap;
extern Keymap rl_binding_keymap;
/* Display variables. */
/* If non-zero, readline will erase the entire line, including any prompt,
if the only thing typed on an otherwise-blank line is something bound to
rl_newline. */
extern int rl_erase_empty_line;
/* If non-zero, the application has already printed the prompt (rl_prompt)
before calling readline, so readline should not output it the first time
redisplay is done. */
extern int rl_already_prompted;
/* A non-zero value means to read only this many characters rather than
up to a character bound to accept-line. */
extern int rl_num_chars_to_read;
/* The text of a currently-executing keyboard macro. */
extern char *rl_executing_macro;
/* Variables to control readline signal handling. */
/* If non-zero, readline will install its own signal handlers for
SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
extern int rl_catch_signals;
/* If non-zero, readline will install a signal handler for SIGWINCH
that also attempts to call any calling application's SIGWINCH signal
handler. Note that the terminal is not cleaned up before the
application's signal handler is called; use rl_cleanup_after_signal()
to do that. */
extern int rl_catch_sigwinch;
/* Completion variables. */
/* Pointer to the generator function for completion_matches ().
NULL means to use rl_filename_completion_function (), the default
filename completer. */
extern rl_compentry_func_t *rl_completion_entry_function;
/* Optional generator for menu completion. Default is
rl_completion_entry_function (rl_filename_completion_function). */
extern rl_compentry_func_t *rl_menu_completion_entry_function;
/* If rl_ignore_some_completions_function is non-NULL it is the address
of a function to call after all of the possible matches have been
generated, but before the actual completion is done to the input line.
The function is called with one argument; a NULL terminated array
of (char *). If your function removes any of the elements, they
must be free()'ed. */
extern rl_compignore_func_t *rl_ignore_some_completions_function;
/* Pointer to alternative function to create matches.
Function is called with TEXT, START, and END.
START and END are indices in RL_LINE_BUFFER saying what the boundaries
of TEXT are.
If this function exists and returns NULL then call the value of
rl_completion_entry_function to try to match, otherwise use the
array of strings returned. */
extern rl_completion_func_t *rl_attempted_completion_function;
/* The basic list of characters that signal a break between words for the
completer routine. The initial contents of this variable is what
breaks words in the shell, i.e. "n\"\\'`@$>". */
extern const char *rl_basic_word_break_characters;
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
extern /*const*/ char *rl_completer_word_break_characters;
/* Hook function to allow an application to set the completion word
break characters before readline breaks up the line. Allows
position-dependent word break characters. */
extern rl_cpvfunc_t *rl_completion_word_break_hook;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
rl_completer_word_break_characters are treated as any other character,
unless they also appear within this list. */
extern const char *rl_completer_quote_characters;
/* List of quote characters which cause a word break. */
extern const char *rl_basic_quote_characters;
/* List of characters that need to be quoted in filenames by the completer. */
extern const char *rl_filename_quote_characters;
/* List of characters that are word break characters, but should be left
in TEXT when it is passed to the completion function. The shell uses
this to help determine what kind of completing to do. */
extern const char *rl_special_prefixes;
/* If non-zero, then this is the address of a function to call when
completing on a directory name. The function is called with
the address of a string (the current directory name) as an arg. It
changes what is displayed when the possible completions are printed
or inserted. */
extern rl_icppfunc_t *rl_directory_completion_hook;
/* If non-zero, this is the address of a function to call when completing
a directory name. This function takes the address of the directory name
to be modified as an argument. Unlike rl_directory_completion_hook, it
only modifies the directory name used in opendir(2), not what is displayed
when the possible completions are printed or inserted. It is called
before rl_directory_completion_hook. I'm not happy with how this works
yet, so it's undocumented. */
extern rl_icppfunc_t *rl_directory_rewrite_hook;
/* Backwards compatibility with previous versions of readline. */
#define rl_symbolic_link_hook rl_directory_completion_hook
/* If non-zero, then this is the address of a function to call when
completing a word would normally display the list of possible matches.
This function is called instead of actually doing the display.
It takes three arguments: (char **matches, int num_matches, int max_length)
where MATCHES is the array of strings that matched, NUM_MATCHES is the
number of strings in that array, and MAX_LENGTH is the length of the
longest string in that array. */
extern rl_compdisp_func_t *rl_completion_display_matches_hook;
/* Non-zero means that the results of the matches are to be treated
as filenames. This is ALWAYS zero on entry, and can only be changed
within a completion entry finder function. */
extern int rl_filename_completion_desired;
/* Non-zero means that the results of the matches are to be quoted using
double quotes (or an application-specific quoting mechanism) if the
filename contains any characters in rl_word_break_chars. This is
ALWAYS non-zero on entry, and can only be changed within a completion
entry finder function. */
extern int rl_filename_quoting_desired;
/* Set to a function to quote a filename in an application-specific fashion.
Called with the text to quote, the type of match found (single or multiple)
and a pointer to the quoting character to be used, which the function can
reset if desired. */
extern rl_quote_func_t *rl_filename_quoting_function;
/* Function to call to remove quoting characters from a filename. Called
before completion is attempted, so the embedded quotes do not interfere
with matching names in the file system. */
extern rl_dequote_func_t *rl_filename_dequoting_function;
/* Function to call to decide whether or not a word break character is
quoted. If a character is quoted, it does not break words for the
completer. */
extern rl_linebuf_func_t *rl_char_is_quoted_p;
/* Non-zero means to suppress normal filename completion after the
user-specified completion function has been called. */
extern int rl_attempted_completion_over;
/* Set to a character describing the type of completion being attempted by
rl_complete_internal; available for use by application completion
functions. */
extern int rl_completion_type;
/* Set to the last key used to invoke one of the completion functions */
extern int rl_completion_invoking_key;
/* Up to this many items will be displayed in response to a
possible-completions call. After that, we ask the user if she
is sure she wants to see them all. The default value is 100. */
extern int rl_completion_query_items;
/* Character appended to completed words when at the end of the line. The
default is a space. Nothing is added if this is '\0'. */
extern int rl_completion_append_character;
/* If set to non-zero by an application completion function,
rl_completion_append_character will not be appended. */
extern int rl_completion_suppress_append;
/* Set to any quote character readline thinks it finds before any application
completion function is called. */
extern int rl_completion_quote_character;
/* Set to a non-zero value if readline found quoting anywhere in the word to
be completed; set before any application completion function is called. */
extern int rl_completion_found_quote;
/* If non-zero, the completion functions don't append any closing quote.
This is set to 0 by rl_complete_internal and may be changed by an
application-specific completion function. */
extern int rl_completion_suppress_quote;
/* If non-zero, readline will sort the completion matches. On by default. */
extern int rl_sort_completion_matches;
/* If non-zero, a slash will be appended to completed filenames that are
symbolic links to directory names, subject to the value of the
mark-directories variable (which is user-settable). This exists so
that application completion functions can override the user's preference
(set via the mark-symlinked-directories variable) if appropriate.
It's set to the value of _rl_complete_mark_symlink_dirs in
rl_complete_internal before any application-specific completion
function is called, so without that function doing anything, the user's
preferences are honored. */
extern int rl_completion_mark_symlink_dirs;
/* If non-zero, then disallow duplicates in the matches. */
extern int rl_ignore_completion_duplicates;
/* If this is non-zero, completion is (temporarily) inhibited, and the
completion character will be inserted as any other. */
extern int rl_inhibit_completion;
/* Input error; can be returned by (*rl_getc_function) if readline is reading
a top-level command (RL_ISSTATE (RL_STATE_READCMD)). */
#define READERR (-2)
/* Definitions available for use by readline clients. */
#define RL_PROMPT_START_IGNORE '\001'
#define RL_PROMPT_END_IGNORE '\002'
/* Possible values for do_replace argument to rl_filename_quoting_function,
called by rl_complete_internal. */
#define NO_MATCH 0
#define SINGLE_MATCH 1
#define MULT_MATCH 2
/* Possible state values for rl_readline_state */
#define RL_STATE_NONE 0x000000 /* no state; before first call */
#define RL_STATE_INITIALIZING 0x000001 /* initializing */
#define RL_STATE_INITIALIZED 0x000002 /* initialization done */
#define RL_STATE_TERMPREPPED 0x000004 /* terminal is prepped */
#define RL_STATE_READCMD 0x000008 /* reading a command key */
#define RL_STATE_METANEXT 0x000010 /* reading input after ESC */
#define RL_STATE_DISPATCHING 0x000020 /* dispatching to a command */
#define RL_STATE_MOREINPUT 0x000040 /* reading more input in a command function */
#define RL_STATE_ISEARCH 0x000080 /* doing incremental search */
#define RL_STATE_NSEARCH 0x000100 /* doing non-inc search */
#define RL_STATE_SEARCH 0x000200 /* doing a history search */
#define RL_STATE_NUMERICARG 0x000400 /* reading numeric argument */
#define RL_STATE_MACROINPUT 0x000800 /* getting input from a macro */
#define RL_STATE_MACRODEF 0x001000 /* defining keyboard macro */
#define RL_STATE_OVERWRITE 0x002000 /* overwrite mode */
#define RL_STATE_COMPLETING 0x004000 /* doing completion */
#define RL_STATE_SIGHANDLER 0x008000 /* in readline sighandler */
#define RL_STATE_UNDOING 0x010000 /* doing an undo */
#define RL_STATE_INPUTPENDING 0x020000 /* rl_execute_next called */
#define RL_STATE_TTYCSAVED 0x040000 /* tty special chars saved */
#define RL_STATE_CALLBACK 0x080000 /* using the callback interface */
#define RL_STATE_VIMOTION 0x100000 /* reading vi motion arg */
#define RL_STATE_MULTIKEY 0x200000 /* reading multiple-key command */
#define RL_STATE_VICMDONCE 0x400000 /* entered vi command mode at least once */
#define RL_STATE_REDISPLAYING 0x800000 /* updating terminal display */
#define RL_STATE_DONE 0x1000000 /* done; accepted line */
#define RL_SETSTATE(x) (rl_readline_state |= (x))
#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
#define RL_ISSTATE(x) (rl_readline_state & (x))
struct readline_state {
/* line state */
int point;
int end;
int mark;
char *buffer;
int buflen;
UNDO_LIST *ul;
char *prompt;
/* global state */
int rlstate;
int done;
Keymap kmap;
/* input state */
rl_command_func_t *lastfunc;
int insmode;
int edmode;
int kseqlen;
FILE *inf;
FILE *outf;
int pendingin;
char *macro;
/* signal state */
int catchsigs;
int catchsigwinch;
/* search state */
/* completion state */
/* options state */
/* reserved for future expansion, so the struct size doesn't change */
char reserved[64];
};
extern int rl_save_state PARAMS((struct readline_state *));
extern int rl_restore_state PARAMS((struct readline_state *));
#ifdef __cplusplus
}
#endif
#endif /* _READLINE_H_ */
+15
View File
@@ -574,6 +574,21 @@ rl_clear_screen (count, key)
return 0;
}
int
rl_skip_csi_sequence (count, key)
int count, key;
{
int ch;
RL_SETSTATE (RL_STATE_MOREINPUT);
do
ch = rl_read_key ();
while (ch >= 0x20 && ch < 0x40);
RL_UNSETSTATE (RL_STATE_MOREINPUT);
return 0;
}
int
rl_arrow_keys (count, c)
int count, c;
+17 -1
View File
@@ -574,6 +574,21 @@ rl_clear_screen (count, key)
return 0;
}
int
rl_skip_csi_sequence (count, key)
int count, key;
{
int ch;
RL_SETSTATE (RL_STATE_MOREINPUT);
do
ch = rl_read_key ();
while (ch >= 0x20 && ch < 0x40)
RL_UNSETSTATE (RL_STATE_MOREINPUT);
return 0;
}
int
rl_arrow_keys (count, c)
int count, c;
@@ -1250,7 +1265,8 @@ rl_change_case (count, op)
#if defined (HANDLE_MULTIBYTE)
wchar_t wc, nwc;
char mb[MB_LEN_MAX+1];
int mlen, m;
int mlen;
size_t m;
mbstate_t mps;
#endif
+1 -1
View File
@@ -52,7 +52,7 @@ typedef int posix_glob_errfunc_t __P((const char *, int));
int glob_dot_filenames;
/* Control whether the extended globbing features are enabled. */
int extended_glob = 0;
int extended_glob = EXTGLOB_DEFAULT;
/* Control enabling special handling of `**' */
int glob_star = 0;
+486
View File
@@ -0,0 +1,486 @@
/* pathexp.c -- The shell interface to the globbing library. */
/* Copyright (C) 1995-2009 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"
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashansi.h"
#include "shell.h"
#include "pathexp.h"
#include "flags.h"
#include "shmbutil.h"
#include "bashintl.h"
#include <glob/strmatch.h>
static int glob_name_is_acceptable __P((const char *));
static void ignore_globbed_names __P((char **, sh_ignore_func_t *));
#if defined (USE_POSIX_GLOB_LIBRARY)
# include <glob.h>
typedef int posix_glob_errfunc_t __P((const char *, int));
#else
# include <glob/glob.h>
#endif
/* Control whether * matches .files in globbing. */
int glob_dot_filenames;
/* Control whether the extended globbing features are enabled. */
int extended_glob = 0;
/* Control enabling special handling of `**' */
int glob_star = 0;
/* Return nonzero if STRING has any unquoted special globbing chars in it. */
int
unquoted_glob_pattern_p (string)
register char *string;
{
register int c;
char *send;
int open;
DECLARE_MBSTATE;
open = 0;
send = string + strlen (string);
while (c = *string++)
{
switch (c)
{
case '?':
case '*':
return (1);
case '[':
open++;
continue;
case ']':
if (open)
return (1);
continue;
case '+':
case '@':
case '!':
if (*string == '(') /*)*/
return (1);
continue;
case CTLESC:
case '\\':
if (*string++ == '\0')
return (0);
}
/* Advance one fewer byte than an entire multibyte character to
account for the auto-increment in the loop above. */
#ifdef HANDLE_MULTIBYTE
string--;
ADVANCE_CHAR_P (string, send - string);
string++;
#else
ADVANCE_CHAR_P (string, send - string);
#endif
}
return (0);
}
/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to
be quoted to match itself. */
static inline int
ere_char (c)
int c;
{
switch (c)
{
case '.':
case '[':
case '\\':
case '(':
case ')':
case '*':
case '+':
case '?':
case '{':
case '|':
case '^':
case '$':
return 1;
default:
return 0;
}
return (0);
}
int
glob_char_p (s)
const char *s;
{
switch (*s)
{
case '*':
case '[':
case ']':
case '?':
case '\\':
return 1;
case '+':
case '@':
case '!':
if (s[1] == '(') /*(*/
return 1;
break;
}
return 0;
}
/* PATHNAME can contain characters prefixed by CTLESC; this indicates
that the character is to be quoted. We quote it here in the style
that the glob library recognizes. If flags includes QGLOB_CVTNULL,
we change quoted null strings (pathname[0] == CTLNUL) into empty
strings (pathname[0] == 0). If this is called after quote removal
is performed, (flags & QGLOB_CVTNULL) should be 0; if called when quote
removal has not been done (for example, before attempting to match a
pattern while executing a case statement), flags should include
QGLOB_CVTNULL. If flags includes QGLOB_FILENAME, appropriate quoting
to match a filename should be performed. */
char *
quote_string_for_globbing (pathname, qflags)
const char *pathname;
int qflags;
{
char *temp;
register int i, j;
temp = (char *)xmalloc (strlen (pathname) + 1);
if ((qflags & QGLOB_CVTNULL) && QUOTED_NULL (pathname))
{
temp[0] = '\0';
return temp;
}
for (i = j = 0; pathname[i]; i++)
{
if (pathname[i] == CTLESC)
{
if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
continue;
if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
continue;
temp[j++] = '\\';
i++;
if (pathname[i] == '\0')
break;
}
else if (pathname[i] == '\\')
{
temp[j++] = '\\';
i++;
if (pathname[i] == '\0')
break;
}
temp[j++] = pathname[i];
}
temp[j] = '\0';
return (temp);
}
char *
quote_globbing_chars (string)
char *string;
{
size_t slen;
char *temp, *s, *t, *send;
DECLARE_MBSTATE;
slen = strlen (string);
send = string + slen;
temp = (char *)xmalloc (slen * 2 + 1);
for (t = temp, s = string; *s; )
{
if (glob_char_p (s))
*t++ = '\\';
/* Copy a single (possibly multibyte) character from s to t,
incrementing both. */
COPY_CHAR_P (t, s, send);
}
*t = '\0';
return temp;
}
/* Call the glob library to do globbing on PATHNAME. */
char **
shell_glob_filename (pathname)
const char *pathname;
{
#if defined (USE_POSIX_GLOB_LIBRARY)
register int i;
char *temp, **results;
glob_t filenames;
int glob_flags;
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
filenames.gl_offs = 0;
# if defined (GLOB_PERIOD)
glob_flags = glob_dot_filenames ? GLOB_PERIOD : 0;
# else
glob_flags = 0;
# endif /* !GLOB_PERIOD */
glob_flags |= (GLOB_ERR | GLOB_DOOFFS);
i = glob (temp, glob_flags, (posix_glob_errfunc_t *)NULL, &filenames);
free (temp);
if (i == GLOB_NOSPACE || i == GLOB_ABORTED)
return ((char **)NULL);
else if (i == GLOB_NOMATCH)
filenames.gl_pathv = (char **)NULL;
else if (i != 0) /* other error codes not in POSIX.2 */
filenames.gl_pathv = (char **)NULL;
results = filenames.gl_pathv;
if (results && ((GLOB_FAILED (results)) == 0))
{
if (should_ignore_glob_matches ())
ignore_glob_matches (results);
if (results && results[0])
strvec_sort (results);
else
{
FREE (results);
results = (char **)NULL;
}
}
return (results);
#else /* !USE_POSIX_GLOB_LIBRARY */
char *temp, **results;
noglob_dot_filenames = glob_dot_filenames == 0;
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
results = glob_filename (temp, glob_star ? GX_GLOBSTAR : 0);
free (temp);
if (results && ((GLOB_FAILED (results)) == 0))
{
if (should_ignore_glob_matches ())
ignore_glob_matches (results);
if (results && results[0])
strvec_sort (results);
else
{
FREE (results);
results = (char **)&glob_error_return;
}
}
return (results);
#endif /* !USE_POSIX_GLOB_LIBRARY */
}
/* Stuff for GLOBIGNORE. */
static struct ignorevar globignore =
{
"GLOBIGNORE",
(struct ign *)0,
0,
(char *)0,
(sh_iv_item_func_t *)0,
};
/* Set up to ignore some glob matches because the value of GLOBIGNORE
has changed. If GLOBIGNORE is being unset, we also need to disable
the globbing of filenames beginning with a `.'. */
void
setup_glob_ignore (name)
char *name;
{
char *v;
v = get_string_value (name);
setup_ignore_patterns (&globignore);
if (globignore.num_ignores)
glob_dot_filenames = 1;
else if (v == 0)
glob_dot_filenames = 0;
}
int
should_ignore_glob_matches ()
{
return globignore.num_ignores;
}
/* Return 0 if NAME matches a pattern in the globignore.ignores list. */
static int
glob_name_is_acceptable (name)
const char *name;
{
struct ign *p;
int flags;
/* . and .. are never matched */
if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
return (0);
flags = FNM_PATHNAME | FNMATCH_EXTFLAG;
for (p = globignore.ignores; p->val; p++)
{
if (strmatch (p->val, (char *)name, flags) != FNM_NOMATCH)
return (0);
}
return (1);
}
/* Internal function to test whether filenames in NAMES should be
ignored. NAME_FUNC is a pointer to a function to call with each
name. It returns non-zero if the name is acceptable to the particular
ignore function which called _ignore_names; zero if the name should
be removed from NAMES. */
static void
ignore_globbed_names (names, name_func)
char **names;
sh_ignore_func_t *name_func;
{
char **newnames;
int n, i;
for (i = 0; names[i]; i++)
;
newnames = strvec_create (i + 1);
for (n = i = 0; names[i]; i++)
{
if ((*name_func) (names[i]))
newnames[n++] = names[i];
else
free (names[i]);
}
newnames[n] = (char *)NULL;
if (n == 0)
{
names[0] = (char *)NULL;
free (newnames);
return;
}
/* Copy the acceptable names from NEWNAMES back to NAMES and set the
new array end. */
for (n = 0; newnames[n]; n++)
names[n] = newnames[n];
names[n] = (char *)NULL;
free (newnames);
}
void
ignore_glob_matches (names)
char **names;
{
if (globignore.num_ignores == 0)
return;
ignore_globbed_names (names, glob_name_is_acceptable);
}
void
setup_ignore_patterns (ivp)
struct ignorevar *ivp;
{
int numitems, maxitems, ptr;
char *colon_bit, *this_ignoreval;
struct ign *p;
this_ignoreval = get_string_value (ivp->varname);
/* If nothing has changed then just exit now. */
if ((this_ignoreval && ivp->last_ignoreval && STREQ (this_ignoreval, ivp->last_ignoreval)) ||
(!this_ignoreval && !ivp->last_ignoreval))
return;
/* Oops. The ignore variable has changed. Re-parse it. */
ivp->num_ignores = 0;
if (ivp->ignores)
{
for (p = ivp->ignores; p->val; p++)
free(p->val);
free (ivp->ignores);
ivp->ignores = (struct ign *)NULL;
}
if (ivp->last_ignoreval)
{
free (ivp->last_ignoreval);
ivp->last_ignoreval = (char *)NULL;
}
if (this_ignoreval == 0 || *this_ignoreval == '\0')
return;
ivp->last_ignoreval = savestring (this_ignoreval);
numitems = maxitems = ptr = 0;
while (colon_bit = extract_colon_unit (this_ignoreval, &ptr))
{
if (numitems + 1 >= maxitems)
{
maxitems += 10;
ivp->ignores = (struct ign *)xrealloc (ivp->ignores, maxitems * sizeof (struct ign));
}
ivp->ignores[numitems].val = colon_bit;
ivp->ignores[numitems].len = strlen (colon_bit);
ivp->ignores[numitems].flags = 0;
if (ivp->item_func)
(*ivp->item_func) (&ivp->ignores[numitems]);
numitems++;
}
ivp->ignores[numitems].val = (char *)NULL;
ivp->num_ignores = numitems;
}
+48 -47
View File
@@ -1,13 +1,13 @@
# German language file for GNU Bash 4.0
# Copyright (C) 1996 Free Software Foundation, Inc.
# This file is distributed under the same license as the bash package.
# Nils Naumann <nnau@gmx.net>, 1996, 2008.
# Nils Naumann <nnau@gmx.net>, 1996, 2009.
msgid ""
msgstr ""
"Project-Id-Version: bash 4.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-02-19 14:53-0500\n"
"PO-Revision-Date: 2009-07-21 21:11+0200\n"
"PO-Revision-Date: 2009-08-12 22:04+0200\n"
"Last-Translator: Nils Naumann <nnau@gmx.net>\n"
"Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
"MIME-Version: 1.0\n"
@@ -104,6 +104,7 @@ msgstr "Schleifen Z
msgid "only meaningful in a `for', `while', or `until' loop"
msgstr "nur in einer `for', `while' oder `until' Schleife sinnvoll."
# Problem mit Extraktion des Strings
#: builtins/caller.def:133
msgid ""
"Returns the context of the current subroutine call.\n"
@@ -266,13 +267,13 @@ msgstr "%s: Mehrdeutige Job Bezeichnung."
#: builtins/complete.def:270
#, c-format
msgid "%s: invalid action name"
msgstr ""
msgstr "%s: Ungültige Methode."
#: builtins/complete.def:430 builtins/complete.def:615
#: builtins/complete.def:813
#, c-format
msgid "%s: no completion specification"
msgstr ""
msgstr "%s: Keine Komplettierung angegeben."
#: builtins/complete.def:667
msgid "warning: -F option may not work as you expect"
@@ -284,7 +285,7 @@ msgstr "Warnung: Die -C Option k
#: builtins/complete.def:786
msgid "not currently executing completion function"
msgstr ""
msgstr "Gegenwärtig wird keine Komplettierungsfunktion ausgeführt."
#: builtins/declare.def:122
msgid "can only be used in a function"
@@ -311,22 +312,22 @@ msgstr "%s: Konvertieren von assoziativen in indizierte Arrays ist nicht m
#: builtins/enable.def:137 builtins/enable.def:145
msgid "dynamic loading not available"
msgstr ""
msgstr "Dynamisches Laden ist nicht verfügbar."
#: builtins/enable.def:312
#, c-format
msgid "cannot open shared object %s: %s"
msgstr ""
msgstr "Kann die dynamische Bibiliothek nicht laden %s: %s"
#: builtins/enable.def:335
#, c-format
msgid "cannot find %s in shared object %s: %s"
msgstr ""
msgstr "Kann %s nicht in der dynamischen Bibiliothek finden %s: %s"
#: builtins/enable.def:459
#, c-format
msgid "%s: not dynamically loaded"
msgstr ""
msgstr "%s: Ist nicht dynamisch geladen."
#: builtins/enable.def:474
#, c-format
@@ -412,12 +413,12 @@ msgstr "%s: Diese Option erfordert ein Argument -- %c\n"
#: builtins/hash.def:92
msgid "hashing disabled"
msgstr ""
msgstr "Hashing deaktiviert."
#: builtins/hash.def:138
#, c-format
msgid "%s: hash table empty\n"
msgstr ""
msgstr "%s: Die Hashtabelle ist leer.\n"
#: builtins/hash.def:244
#, c-format
@@ -1112,16 +1113,16 @@ msgstr "initialize_job_control: setpgid"
#: jobs.c:3661
#, c-format
msgid "cannot set terminal process group (%d)"
msgstr ""
msgstr "Kann die Prozessgruppe des Terminals nicht setzen (%d)."
#: jobs.c:3666
msgid "no job control in this shell"
msgstr "Keine Job Steuerung in dieser Shell."
#: lib/malloc/malloc.c:296
#, fuzzy, c-format
#, c-format
msgid "malloc: failed assertion: %s\n"
msgstr "malloc: Fehler bei Speicherzuweisung: %s\n"
msgstr "malloc: Speicherzusicherung gescheitert: %s.\n"
#: lib/malloc/malloc.c:312
#, c-format
@@ -1129,6 +1130,8 @@ msgid ""
"\r\n"
"malloc: %s:%d: assertion botched\r\n"
msgstr ""
"\\r\n"
"malloc: %s:%d: Speicherzusicherung verpfuscht\\r\n"
#: lib/malloc/malloc.c:313
msgid "unknown"
@@ -1136,73 +1139,73 @@ msgstr "Unbekannt"
#: lib/malloc/malloc.c:797
msgid "malloc: block on free list clobbered"
msgstr ""
msgstr "Malloc: Ein frei gekennzeichneter Speicherbereich wurde überschrieben."
#: lib/malloc/malloc.c:874
msgid "free: called with already freed block argument"
msgstr ""
msgstr "free: Wurde für bereits freigegebenen Speicherbereich aufgerufen."
#: lib/malloc/malloc.c:877
msgid "free: called with unallocated block argument"
msgstr ""
msgstr "free: Wurde für nicht zugeordneten Speicherbereich aufgerufen."
#: lib/malloc/malloc.c:896
msgid "free: underflow detected; mh_nbytes out of range"
msgstr ""
msgstr "free: Underflow erkannt; mh_nbytes außerhalb des Gültigkeitsbereichs."
#: lib/malloc/malloc.c:902
msgid "free: start and end chunk sizes differ"
msgstr ""
msgstr "free: Beginn und Ende Segmentgrößen sind unterschiedlich."
#: lib/malloc/malloc.c:1001
msgid "realloc: called with unallocated block argument"
msgstr ""
msgstr "realloc: Mit nicht zugewiesenen Argument aufgerufen."
#: lib/malloc/malloc.c:1016
msgid "realloc: underflow detected; mh_nbytes out of range"
msgstr ""
msgstr "realloc: Underflow erkannt; mh_nbytes außerhalb des Gültigkeitsbereichs."
#: lib/malloc/malloc.c:1022
msgid "realloc: start and end chunk sizes differ"
msgstr ""
msgstr "realloc: Beginn und Ende Segmentgrößen sind unterschiedlich.<"
#: lib/malloc/table.c:177
#, c-format
msgid "register_alloc: alloc table is full with FIND_ALLOC?\n"
msgstr ""
msgstr "register_alloc: Speicherzuordnungstabelle ist mit FIND_ALLOC gefüllt?\n"
#: lib/malloc/table.c:184
#, c-format
msgid "register_alloc: %p already in table as allocated?\n"
msgstr ""
msgstr "register_alloc: %p ist bereits in der Speicherzuordnungstabelle als belegt gekennzeichnet?\n"
#: lib/malloc/table.c:220
#, c-format
msgid "register_free: %p already in table as free?\n"
msgstr ""
msgstr "register_free: %p ist bereits in der Speicherzuordnungstabelle als frei gekennzeichnet?\n"
#: lib/sh/fmtulong.c:101
msgid "invalid base"
msgstr ""
msgstr "Ungültige Basis"
#: lib/sh/netopen.c:168
#, c-format
msgid "%s: host unknown"
msgstr ""
msgstr "%s: Unbekannter Host."
#: lib/sh/netopen.c:175
#, c-format
msgid "%s: invalid service"
msgstr ""
msgstr "%s: unbekannter Dienst."
#: lib/sh/netopen.c:306
#, c-format
msgid "%s: bad network path specification"
msgstr ""
msgstr "%s: Fehlerhafte Netzwerkspfadangabe."
#: lib/sh/netopen.c:346
msgid "network operations not supported"
msgstr ""
msgstr "Der Netzwerkbetrieb ist nicht unterstützt."
# Du oder Sie?
#: mailcheck.c:433
@@ -1268,7 +1271,7 @@ msgstr "Syntaxfehler im bedingen Ausdruck."
#: parse.y:3809
#, c-format
msgid "unexpected token `%s', expected `)'"
msgstr ""
msgstr "Unerwartetes Zeichen: `%s' anstatt von `)'"
#: parse.y:3813
msgid "expected `)'"
@@ -1390,7 +1393,7 @@ msgstr ""
#: redir.c:517
msgid "/dev/(tcp|udp)/host/port not supported without networking"
msgstr ""
msgstr "/dev/(tcp|udp)/host/port Wird ohne Netzwerk nicht unterstützt"
#: redir.c:1023
msgid "redirection error: cannot duplicate fd"
@@ -1474,7 +1477,7 @@ msgstr "Aufgelegt"
#: siglist.c:54
msgid "Interrupt"
msgstr "Unterbrochen"
msgstr "Unterbrochen (Interrupt)"
#: siglist.c:58
msgid "Quit"
@@ -1484,11 +1487,9 @@ msgstr "Quit"
msgid "Illegal instruction"
msgstr "Ungültige Anweisung."
# Was heisst das?
#: siglist.c:66
#, fuzzy
msgid "BPT trace/trap"
msgstr "BPT trace/trap"
msgstr "Verfolgen/anhalten abfangen (Trace/breakpoint trap)"
#: siglist.c:74
msgid "ABORT instruction"
@@ -1496,7 +1497,7 @@ msgstr "Abbruchkommando"
#: siglist.c:78
msgid "EMT instruction"
msgstr "EMT-Kommando"
msgstr "EMT abfangen (EMT trap)"
#: siglist.c:82
msgid "Floating point exception"
@@ -1504,7 +1505,7 @@ msgstr "Gleitkommafehler"
#: siglist.c:86
msgid "Killed"
msgstr "Gekillt"
msgstr "Abgebrochen (Killed)"
#: siglist.c:90
msgid "Bus error"
@@ -1512,7 +1513,7 @@ msgstr "Bus-Fehler"
#: siglist.c:94
msgid "Segmentation fault"
msgstr "Speicherzugriffsfehler"
msgstr "Adressierungsfehler"
#: siglist.c:98
msgid "Bad system call"
@@ -1528,7 +1529,7 @@ msgstr "Wecker"
#: siglist.c:110
msgid "Terminated"
msgstr "Beendet"
msgstr "Abgebrochen (Terminated)"
#: siglist.c:114
msgid "Urgent IO condition"
@@ -1584,11 +1585,11 @@ msgstr "Datei blockiert."
#: siglist.c:174
msgid "User signal 1"
msgstr "Nutzer-Signal 1"
msgstr "Nutzersignal 1"
#: siglist.c:178
msgid "User signal 2"
msgstr "Nutzer-Signal 2"
msgstr "Nutzersignal 2"
#: siglist.c:182
msgid "HFT input data pending"
@@ -1651,7 +1652,7 @@ msgstr "Kann keine Pipe f
#: subst.c:4504
msgid "cannot make child for process substitution"
msgstr ""
msgstr "Kann den Kindsprozess für die Prozeßersetzung nicht erzeugen."
#: subst.c:4549
#, c-format
@@ -2094,7 +2095,7 @@ msgstr "select Name [in Wortliste ... ;] do Kommandos; done"
#: builtins.c:188
msgid "time [-p] pipeline"
msgstr ""
msgstr "time [-p] Pipeline"
#: builtins.c:190
msgid "case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac"
@@ -2116,7 +2117,7 @@ msgstr "until Kommandos; do Kommandos; done"
#: builtins.c:198
msgid "coproc [NAME] command [redirections]"
msgstr ""
msgstr "coproc [Name] Kommando [Umleitungen]"
#: builtins.c:200
msgid "function name { COMMANDS ; } or name () { COMMANDS ; }"
@@ -2164,7 +2165,7 @@ msgstr "printf [-v var] Format [Argumente]"
#: builtins.c:229
msgid "complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]"
msgstr "complete [-abcdefgjksuv] [-pr] [-o Option] [-A Aktion] [-G Suchmuster] [-W Wortliste] [-F Funktion] [-C Kommando] [-X Filtermuster] [-P Prefix] [-S Suffix] [Name ...]"
msgstr "complete [-abcdefgjksuv] [-pr] [-o Option] [-A Methode] [-G Suchmuster] [-W Wortliste] [-F Funktion] [-C Kommando] [-X Filtermuster] [-P Prefix] [-S Suffix] [Name ...]"
#: builtins.c:233
msgid "compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]"
@@ -2499,7 +2500,7 @@ msgid ""
" Returns success unless an invalid option is supplied, an error occurs,\n"
" or the shell is not executing a function."
msgstr ""
"Definiert lokale Vatiablen.\n"
"Definiert lokale Variablen.\n"
" \n"
" Erzeugt eine Lokale Variable NAME und weist ihr den Wert VALUE zu. OPTION\n"
" kann eine beliebige von `declare' akzeptierte Option sein.\n"
+87 -29
View File
@@ -108,6 +108,11 @@ char *the_printed_command = (char *)NULL;
int the_printed_command_size = 0;
int command_string_index = 0;
int xtrace_fd = -1;
FILE *xtrace_fp = 0;
#define CHECK_XTRACE_FP xtrace_fp = (xtrace_fp ? xtrace_fp : stderr)
/* Non-zero means the stuff being printed is inside of a function def. */
static int inside_function_def;
static int skip_this_indent;
@@ -348,6 +353,45 @@ print_word_list (list, separator)
_print_word_list (list, separator, xprintf);
}
void
xtrace_set (fd, fp)
int fd;
FILE *fp;
{
if (fd >= 0 && sh_validfd (fd) == 0)
{
internal_error ("xtrace_set: %d: invalid file descriptor", fd);
return;
}
if (fp == 0)
{
internal_error ("xtrace_set: NULL file pointer");
return;
}
if (fd >= 0 && fileno (fp) != fd)
internal_warning ("xtrace fd (%d) != fileno xtrace fp (%d)", fd, fileno (fp));
xtrace_fd = fd;
xtrace_fp = fp;
}
void
xtrace_init ()
{
xtrace_set (-1, stderr);
}
void
xtrace_reset ()
{
if (xtrace_fd >= 0)
close (xtrace_fd);
xtrace_fd = -1;
if (xtrace_fp)
fclose (xtrace_fp);
xtrace_fp = stderr;
}
/* Return a string denoting what our indirection level is. */
char *
@@ -409,8 +453,10 @@ xtrace_print_assignment (name, value, assign_list, xflags)
{
char *nval;
CHECK_XTRACE_FP;
if (xflags)
fprintf (stderr, "%s", indirection_level_string ());
fprintf (xtrace_fp, "%s", indirection_level_string ());
/* VALUE should not be NULL when this is called. */
if (*value == '\0' || assign_list)
@@ -423,14 +469,14 @@ xtrace_print_assignment (name, value, assign_list, xflags)
nval = value;
if (assign_list)
fprintf (stderr, "%s=(%s)\n", name, nval);
fprintf (xtrace_fp, "%s=(%s)\n", name, nval);
else
fprintf (stderr, "%s=%s\n", name, nval);
fprintf (xtrace_fp, "%s=%s\n", name, nval);
if (nval != value)
FREE (nval);
fflush (stderr);
fflush (xtrace_fp);
}
/* A function to print the words of a simple command when set -x is on. */
@@ -442,30 +488,33 @@ xtrace_print_word_list (list, xtflags)
WORD_LIST *w;
char *t, *x;
CHECK_XTRACE_FP;
if (xtflags)
fprintf (stderr, "%s", indirection_level_string ());
fprintf (xtrace_fp, "%s", indirection_level_string ());
for (w = list; w; w = w->next)
{
t = w->word->word;
if (t == 0 || *t == '\0')
fprintf (stderr, "''%s", w->next ? " " : "");
fprintf (xtrace_fp, "''%s", w->next ? " " : "");
else if (sh_contains_shell_metas (t))
{
x = sh_single_quote (t);
fprintf (stderr, "%s%s", x, w->next ? " " : "");
fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
free (x);
}
else if (ansic_shouldquote (t))
{
x = ansic_quote (t, 0, (int *)0);
fprintf (stderr, "%s%s", x, w->next ? " " : "");
fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
free (x);
}
else
fprintf (stderr, "%s%s", t, w->next ? " " : "");
fprintf (xtrace_fp, "%s%s", t, w->next ? " " : "");
}
fprintf (stderr, "\n");
fprintf (xtrace_fp, "\n");
fflush (xtrace_fp);
}
static void
@@ -488,8 +537,9 @@ void
xtrace_print_for_command_head (for_command)
FOR_COM *for_command;
{
fprintf (stderr, "%s", indirection_level_string ());
fprintf (stderr, "for %s in ", for_command->name->word);
CHECK_XTRACE_FP;
fprintf (xtrace_fp, "%s", indirection_level_string ());
fprintf (xtrace_fp, "for %s in ", for_command->name->word);
xtrace_print_word_list (for_command->map_list, 0);
}
@@ -542,8 +592,9 @@ void
xtrace_print_select_command_head (select_command)
SELECT_COM *select_command;
{
fprintf (stderr, "%s", indirection_level_string ());
fprintf (stderr, "select %s in ", select_command->name->word);
CHECK_XTRACE_FP;
fprintf (xtrace_fp, "%s", indirection_level_string ());
fprintf (xtrace_fp, "select %s in ", select_command->name->word);
xtrace_print_word_list (select_command->map_list, 0);
}
@@ -611,8 +662,9 @@ void
xtrace_print_case_command_head (case_command)
CASE_COM *case_command;
{
fprintf (stderr, "%s", indirection_level_string ());
fprintf (stderr, "case %s in\n", case_command->word->word);
CHECK_XTRACE_FP;
fprintf (xtrace_fp, "%s", indirection_level_string ());
fprintf (xtrace_fp, "case %s in\n", case_command->word->word);
}
static void
@@ -790,25 +842,28 @@ xtrace_print_cond_term (type, invert, op, arg1, arg2)
WORD_DESC *op;
char *arg1, *arg2;
{
CHECK_XTRACE_FP;
command_string_index = 0;
fprintf (stderr, "%s", indirection_level_string ());
fprintf (stderr, "[[ ");
fprintf (xtrace_fp, "%s", indirection_level_string ());
fprintf (xtrace_fp, "[[ ");
if (invert)
fprintf (stderr, "! ");
fprintf (xtrace_fp, "! ");
if (type == COND_UNARY)
{
fprintf (stderr, "%s ", op->word);
fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
fprintf (xtrace_fp, "%s ", op->word);
fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
}
else if (type == COND_BINARY)
{
fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
fprintf (stderr, " %s ", op->word);
fprintf (stderr, "%s", (arg2 && *arg2) ? arg2 : "''");
fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''");
fprintf (xtrace_fp, " %s ", op->word);
fprintf (xtrace_fp, "%s", (arg2 && *arg2) ? arg2 : "''");
}
fprintf (stderr, " ]]\n");
fprintf (xtrace_fp, " ]]\n");
fflush (xtrace_fp);
}
#endif /* COND_COMMAND */
@@ -820,11 +875,14 @@ xtrace_print_arith_cmd (list)
{
WORD_LIST *w;
fprintf (stderr, "%s", indirection_level_string ());
fprintf (stderr, "(( ");
CHECK_XTRACE_FP;
fprintf (xtrace_fp, "%s", indirection_level_string ());
fprintf (xtrace_fp, "(( ");
for (w = list; w; w = w->next)
fprintf (stderr, "%s%s", w->word->word, w->next ? " " : "");
fprintf (stderr, " ))\n");
fprintf (xtrace_fp, "%s%s", w->word->word, w->next ? " " : "");
fprintf (xtrace_fp, " ))\n");
fflush (xtrace_fp);
}
#endif
+1466
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -374,6 +374,8 @@ main (argc, argv, env)
if (code)
exit (2);
xtrace_init ();
#if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS)
# if 1
malloc_set_register (1);
@@ -1713,8 +1715,10 @@ shell_initialize ()
privileged or restricted mode or if the shell is running setuid. */
#if defined (RESTRICTED_SHELL)
initialize_shell_options (privileged_mode||restricted||running_setuid);
initialize_bashopts (privileged_mode||restricted||running_setuid);
#else
initialize_shell_options (privileged_mode||running_setuid);
initialize_bashopts (privileged_mode||running_setuid);
#endif
}
+7 -2
View File
@@ -892,6 +892,9 @@ void
exit_shell (s)
int s;
{
fflush (stdout); /* XXX */
fflush (stderr);
/* Do trap[0] if defined. Allow it to override the exit status
passed to us. */
if (signal_is_trapped (0))
@@ -1710,8 +1713,10 @@ shell_initialize ()
privileged or restricted mode or if the shell is running setuid. */
#if defined (RESTRICTED_SHELL)
initialize_shell_options (privileged_mode||restricted||running_setuid);
initialize_bashopts (privileged_mode||restricted||running_setuid);
#else
initialize_shell_options (privileged_mode||running_setuid);
initialize_bashopts (privileged_mode||running_setuid);
#endif
}
@@ -1790,12 +1795,12 @@ show_shell_usage (fp, extra)
set_opts = savestring (shell_builtins[i].short_doc);
if (set_opts)
{
s = xstrchr (set_opts, '[');
s = strchr (set_opts, '[');
if (s == 0)
s = set_opts;
while (*++s == '-')
;
t = xstrchr (s, ']');
t = strchr (s, ']');
if (t)
*t = '\0';
fprintf (fp, _("\t-%s or -o option\n"), s);
+1
View File
@@ -91,6 +91,7 @@ extern int debugging_mode;
extern int executing, login_shell;
extern int interactive, interactive_shell;
extern int startup_state;
extern int subshell_environment;
extern int shell_compatibility_level;
/* Structure to pass around that holds a bitmap of file descriptors
+166
View File
@@ -0,0 +1,166 @@
/* shell.h -- The data structures used by the shell */
/* Copyright (C) 1993-2009 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/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "bashjmp.h"
#include "command.h"
#include "syntax.h"
#include "general.h"
#include "error.h"
#include "variables.h"
#include "arrayfunc.h"
#include "quit.h"
#include "maxpath.h"
#include "unwind_prot.h"
#include "dispose_cmd.h"
#include "make_cmd.h"
#include "ocache.h"
#include "subst.h"
#include "sig.h"
#include "pathnames.h"
#include "externs.h"
extern int EOF_Reached;
#define NO_PIPE -1
#define REDIRECT_BOTH -2
#define NO_VARIABLE -1
/* Values that can be returned by execute_command (). */
#define EXECUTION_FAILURE 1
#define EXECUTION_SUCCESS 0
/* Usage messages by builtins result in a return status of 2. */
#define EX_BADUSAGE 2
/* Special exit statuses used by the shell, internally and externally. */
#define EX_RETRYFAIL 124
#define EX_WEXPCOMSUB 125
#define EX_BINARY_FILE 126
#define EX_NOEXEC 126
#define EX_NOINPUT 126
#define EX_NOTFOUND 127
#define EX_SHERRBASE 256 /* all special error values are > this. */
#define EX_BADSYNTAX 257 /* shell syntax error */
#define EX_USAGE 258 /* syntax error in usage */
#define EX_REDIRFAIL 259 /* redirection failed */
#define EX_BADASSIGN 260 /* variable assignment error */
#define EX_EXPFAIL 261 /* word expansion failed */
/* Flag values that control parameter pattern substitution. */
#define MATCH_ANY 0x000
#define MATCH_BEG 0x001
#define MATCH_END 0x002
#define MATCH_TYPEMASK 0x003
#define MATCH_GLOBREP 0x010
#define MATCH_QUOTED 0x020
#define MATCH_STARSUB 0x040
/* Some needed external declarations. */
extern char **shell_environment;
extern WORD_LIST *rest_of_args;
/* Generalized global variables. */
extern int debugging_mode;
extern int executing, login_shell;
extern int interactive, interactive_shell;
extern int startup_state;
extern int shell_compatibility_level;
/* Structure to pass around that holds a bitmap of file descriptors
to close, and the size of that structure. Used in execute_cmd.c. */
struct fd_bitmap {
int size;
char *bitmap;
};
#define FD_BITMAP_SIZE 32
#define CTLESC '\001'
#define CTLNUL '\177'
/* Information about the current user. */
struct user_info {
uid_t uid, euid;
gid_t gid, egid;
char *user_name;
char *shell; /* shell from the password file */
char *home_dir;
};
extern struct user_info current_user;
/* Force gcc to not clobber X on a longjmp(). Old versions of gcc mangle
this badly. */
#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 8)
# define USE_VAR(x) ((void) &(x))
#else
# define USE_VAR(x)
#endif
/* Structure in which to save partial parsing state when doing things like
PROMPT_COMMAND and bash_execute_unix_command execution. */
typedef struct _sh_parser_state_t {
/* parsing state */
int parser_state;
int *token_state;
/* input line state -- line number saved elsewhere */
int input_line_terminator;
int eof_encountered;
#if defined (HANDLE_MULTIBYTE)
/* Nothing right now for multibyte state, but might want something later. */
#endif
/* history state affecting or modified by the parser */
int current_command_line_count;
#if defined (HISTORY)
int remember_on_history;
int history_expansion_inhibited;
#endif
/* execution state possibly modified by the parser */
int last_command_exit_value;
#if defined (ARRAY_VARS)
ARRAY *pipestatus;
#endif
sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
/* flags state affecting the parser */
int expand_aliases;
int echo_input_at_read;
} sh_parser_state_t;
/* Let's try declaring these here. */
extern sh_parser_state_t *save_parser_state __P((sh_parser_state_t *));
extern void restore_parser_state __P((sh_parser_state_t *));
+1 -1
View File
@@ -526,7 +526,7 @@ termsig_handler (sig)
#endif /* HISTORY */
#if defined (JOB_CONTROL)
if (interactive && sig == SIGHUP)
if (sig == SIGHUP && (interactive || (subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB))))
hangup_all_jobs ();
end_job_control ();
#endif /* JOB_CONTROL */
+38 -1
View File
@@ -450,7 +450,44 @@ termsig_sighandler (sig)
{
/* If we get called twice with the same signal before handling it,
terminate right away. */
if (sig == terminating_signal)
if (
#ifdef SIGHUP
sig != SIGHUP &&
#endif
#ifdef SIGINT
sig != SIGINT &&
#endif
#ifdef SIGDANGER
sig != SIGDANGER &&
#endif
#ifdef SIGPIPE
sig != SIGPIPE &&
#endif
#ifdef SIGALRM
sig != SIGALRM &&
#endif
#ifdef SIGTERM
sig != SIGTERM &&
#endif
#ifdef SIGXCPU
sig != SIGXCPU &&
#endif
#ifdef SIGXFSZ
sig != SIGXFSZ &&
#endif
#ifdef SIGVTALRM
sig != SIGVTALRM &&
#endif
#ifdef SIGLOST
sig != SIGLOST &&
#endif
#ifdef SIGUSR1
sig != SIGUSR1 &&
#endif
#ifdef SIGUSR2
sig != SIGUSR2 &&
#endif
sig == terminating_signal)
terminate_immediately = 1;
terminating_signal = sig;
+37
View File
@@ -44,6 +44,8 @@
#include "bashansi.h"
#include "bashintl.h"
#define NEED_XTRACE_SET_DECL
#include "shell.h"
#include "flags.h"
#include "execute_cmd.h"
@@ -4083,6 +4085,8 @@ struct name_and_function {
};
static struct name_and_function special_vars[] = {
{ "BASH_XTRACEFD", sv_xtracefd },
#if defined (READLINE)
# if defined (STRICT_POSIX)
{ "COLUMNS", sv_winsize },
@@ -4634,3 +4638,36 @@ set_pipestatus_from_exit (s)
set_pipestatus_array (v, 1);
#endif
}
void
sv_xtracefd (name)
char *name;
{
SHELL_VAR *v;
char *t, *e;
int fd;
FILE *fp;
v = find_variable (name);
if (v == 0)
{
xtrace_reset ();
return;
}
t = value_cell (v);
if (t == 0 || *t == 0)
xtrace_reset ();
else
{
fd = (int)strtol (t, &e, 10);
if (e != t && *e == '\0' && sh_validfd (fd))
{
fp = fdopen (fd, "w");
if (fp == 0)
internal_error ("%s: %s: cannot open as FILE", name, value_cell (v));
}
else
internal_error ("%s: %s: invalid value for trace file descriptor", name, value_cell (v));
}
}
+18 -6
View File
@@ -44,6 +44,8 @@
#include "bashansi.h"
#include "bashintl.h"
#define NEED_XTRACE_SET_DECL
#include "shell.h"
#include "flags.h"
#include "execute_cmd.h"
@@ -4083,6 +4085,8 @@ struct name_and_function {
};
static struct name_and_function special_vars[] = {
{ "BASH_XTRACEFD", sv_xtracefd },
#if defined (READLINE)
# if defined (STRICT_POSIX)
{ "COLUMNS", sv_winsize },
@@ -4304,12 +4308,6 @@ sv_hostfile (name)
clear_hostname_list ();
else
hostname_list_initialized = 0;
#if 0
#if defined (PROGRAMMABLE_COMPLETION)
set_itemlist_dirty (&it_hostnames);
#endif
#endif
}
#if defined (STRICT_POSIX)
@@ -4640,3 +4638,17 @@ set_pipestatus_from_exit (s)
set_pipestatus_array (v, 1);
#endif
}
void
sv_xtracefd (name)
char *name;
{
SHELL_VAR *v;
v = find_variable (name);
if (v == 0)
xtrace_reset ();
else
{
}
}
+1
View File
@@ -356,6 +356,7 @@ extern void sv_strict_posix __P((char *));
extern void sv_optind __P((char *));
extern void sv_opterr __P((char *));
extern void sv_locale __P((char *));
extern void sv_xtracefd __P((char *));
#if defined (READLINE)
extern void sv_comp_wordbreaks __P((char *));
+385
View File
@@ -0,0 +1,385 @@
/* variables.h -- data structures for shell variables. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_VARIABLES_H_)
#define _VARIABLES_H_
#include "stdc.h"
#include "array.h"
#include "assoc.h"
/* Shell variables and functions are stored in hash tables. */
#include "hashlib.h"
#include "conftypes.h"
/* A variable context. */
typedef struct var_context {
char *name; /* empty or NULL means global context */
int scope; /* 0 means global context */
int flags;
struct var_context *up; /* previous function calls */
struct var_context *down; /* down towards global context */
HASH_TABLE *table; /* variables at this scope */
} VAR_CONTEXT;
/* Flags for var_context->flags */
#define VC_HASLOCAL 0x01
#define VC_HASTMPVAR 0x02
#define VC_FUNCENV 0x04 /* also function if name != NULL */
#define VC_BLTNENV 0x08 /* builtin_env */
#define VC_TEMPENV 0x10 /* temporary_env */
#define VC_TEMPFLAGS (VC_FUNCENV|VC_BLTNENV|VC_TEMPENV)
/* Accessing macros */
#define vc_isfuncenv(vc) (((vc)->flags & VC_FUNCENV) != 0)
#define vc_isbltnenv(vc) (((vc)->flags & VC_BLTNENV) != 0)
#define vc_istempenv(vc) (((vc)->flags & (VC_TEMPFLAGS)) == VC_TEMPENV)
#define vc_istempscope(vc) (((vc)->flags & (VC_TEMPENV|VC_BLTNENV)) != 0)
#define vc_haslocals(vc) (((vc)->flags & VC_HASLOCAL) != 0)
#define vc_hastmpvars(vc) (((vc)->flags & VC_HASTMPVAR) != 0)
/* What a shell variable looks like. */
typedef struct variable *sh_var_value_func_t __P((struct variable *));
typedef struct variable *sh_var_assign_func_t __P((struct variable *, char *, arrayind_t, char *));
/* For the future */
union _value {
char *s; /* string value */
intmax_t i; /* int value */
COMMAND *f; /* function */
ARRAY *a; /* array */
HASH_TABLE *h; /* associative array */
double d; /* floating point number */
#if defined (HAVE_LONG_DOUBLE)
long double ld; /* long double */
#endif
struct variable *v; /* possible indirect variable use */
void *opaque; /* opaque data for future use */
};
typedef struct variable {
char *name; /* Symbol that the user types. */
char *value; /* Value that is returned. */
char *exportstr; /* String for the environment. */
sh_var_value_func_t *dynamic_value; /* Function called to return a `dynamic'
value for a variable, like $SECONDS
or $RANDOM. */
sh_var_assign_func_t *assign_func; /* Function called when this `special
variable' is assigned a value in
bind_variable. */
int attributes; /* export, readonly, array, invisible... */
int context; /* Which context this variable belongs to. */
} SHELL_VAR;
typedef struct _vlist {
SHELL_VAR **list;
int list_size; /* allocated size */
int list_len; /* current number of entries */
} VARLIST;
/* The various attributes that a given variable can have. */
/* First, the user-visible attributes */
#define att_exported 0x0000001 /* export to environment */
#define att_readonly 0x0000002 /* cannot change */
#define att_array 0x0000004 /* value is an array */
#define att_function 0x0000008 /* value is a function */
#define att_integer 0x0000010 /* internal representation is int */
#define att_local 0x0000020 /* variable is local to a function */
#define att_assoc 0x0000040 /* variable is an associative array */
#define att_trace 0x0000080 /* function is traced with DEBUG trap */
#define att_uppercase 0x0000100 /* word converted to uppercase on assignment */
#define att_lowercase 0x0000200 /* word converted to lowercase on assignment */
#define att_capcase 0x0000400 /* word capitalized on assignment */
#define user_attrs (att_exported|att_readonly|att_integer|att_local|att_trace|att_uppercase|att_lowercase|att_capcase)
#define attmask_user 0x0000fff
/* Internal attributes used for bookkeeping */
#define att_invisible 0x0001000 /* cannot see */
#define att_nounset 0x0002000 /* cannot unset */
#define att_noassign 0x0004000 /* assignment not allowed */
#define att_imported 0x0008000 /* came from environment */
#define att_special 0x0010000 /* requires special handling */
#define att_nofree 0x0020000 /* do not free value on unset */
#define attmask_int 0x00ff000
/* Internal attributes used for variable scoping. */
#define att_tempvar 0x0100000 /* variable came from the temp environment */
#define att_propagate 0x0200000 /* propagate to previous scope */
#define attmask_scope 0x0f00000
#define exported_p(var) ((((var)->attributes) & (att_exported)))
#define readonly_p(var) ((((var)->attributes) & (att_readonly)))
#define array_p(var) ((((var)->attributes) & (att_array)))
#define function_p(var) ((((var)->attributes) & (att_function)))
#define integer_p(var) ((((var)->attributes) & (att_integer)))
#define local_p(var) ((((var)->attributes) & (att_local)))
#define assoc_p(var) ((((var)->attributes) & (att_assoc)))
#define trace_p(var) ((((var)->attributes) & (att_trace)))
#define uppercase_p(var) ((((var)->attributes) & (att_uppercase)))
#define lowercase_p(var) ((((var)->attributes) & (att_lowercase)))
#define capcase_p(var) ((((var)->attributes) & (att_capcase)))
#define invisible_p(var) ((((var)->attributes) & (att_invisible)))
#define non_unsettable_p(var) ((((var)->attributes) & (att_nounset)))
#define noassign_p(var) ((((var)->attributes) & (att_noassign)))
#define imported_p(var) ((((var)->attributes) & (att_imported)))
#define specialvar_p(var) ((((var)->attributes) & (att_special)))
#define nofree_p(var) ((((var)->attributes) & (att_nofree)))
#define tempvar_p(var) ((((var)->attributes) & (att_tempvar)))
/* Acessing variable values: rvalues */
#define value_cell(var) ((var)->value)
#define function_cell(var) (COMMAND *)((var)->value)
#define array_cell(var) (ARRAY *)((var)->value)
#define assoc_cell(var) (HASH_TABLE *)((var)->value)
#define var_isnull(var) ((var)->value == 0)
#define var_isset(var) ((var)->value != 0)
/* Assigning variable values: lvalues */
#define var_setvalue(var, str) ((var)->value = (str))
#define var_setfunc(var, func) ((var)->value = (char *)(func))
#define var_setarray(var, arr) ((var)->value = (char *)(arr))
#define var_setassoc(var, arr) ((var)->value = (char *)(arr))
/* Make VAR be auto-exported. */
#define set_auto_export(var) \
do { (var)->attributes |= att_exported; array_needs_making = 1; } while (0)
#define SETVARATTR(var, attr, undo) \
((undo == 0) ? ((var)->attributes |= (attr)) \
: ((var)->attributes &= ~(attr)))
#define VSETATTR(var, attr) ((var)->attributes |= (attr))
#define VUNSETATTR(var, attr) ((var)->attributes &= ~(attr))
#define VGETFLAGS(var) ((var)->attributes)
#define VSETFLAGS(var, flags) ((var)->attributes = (flags))
#define VCLRFLAGS(var) ((var)->attributes = 0)
/* Macros to perform various operations on `exportstr' member of a SHELL_VAR. */
#define CLEAR_EXPORTSTR(var) (var)->exportstr = (char *)NULL
#define COPY_EXPORTSTR(var) ((var)->exportstr) ? savestring ((var)->exportstr) : (char *)NULL
#define SET_EXPORTSTR(var, value) (var)->exportstr = (value)
#define SAVE_EXPORTSTR(var, value) (var)->exportstr = (value) ? savestring (value) : (char *)NULL
#define FREE_EXPORTSTR(var) \
do { if ((var)->exportstr) free ((var)->exportstr); } while (0)
#define CACHE_IMPORTSTR(var, value) \
(var)->exportstr = savestring (value)
#define INVALIDATE_EXPORTSTR(var) \
do { \
if ((var)->exportstr) \
{ \
free ((var)->exportstr); \
(var)->exportstr = (char *)NULL; \
} \
} while (0)
/* Stuff for hacking variables. */
typedef int sh_var_map_func_t __P((SHELL_VAR *));
/* Where we keep the variables and functions */
extern VAR_CONTEXT *global_variables;
extern VAR_CONTEXT *shell_variables;
extern HASH_TABLE *shell_functions;
extern HASH_TABLE *temporary_env;
extern int variable_context;
extern char *dollar_vars[];
extern char **export_env;
extern void initialize_shell_variables __P((char **, int));
extern SHELL_VAR *set_if_not __P((char *, char *));
extern void sh_set_lines_and_columns __P((int, int));
extern void set_pwd __P((void));
extern void set_ppid __P((void));
extern void make_funcname_visible __P((int));
extern SHELL_VAR *var_lookup __P((const char *, VAR_CONTEXT *));
extern SHELL_VAR *find_function __P((const char *));
extern FUNCTION_DEF *find_function_def __P((const char *));
extern SHELL_VAR *find_variable __P((const char *));
extern SHELL_VAR *find_variable_internal __P((const char *, int));
extern SHELL_VAR *find_tempenv_variable __P((const char *));
extern SHELL_VAR *copy_variable __P((SHELL_VAR *));
extern SHELL_VAR *make_local_variable __P((const char *));
extern SHELL_VAR *bind_variable __P((const char *, char *, int));
extern SHELL_VAR *bind_function __P((const char *, COMMAND *));
extern void bind_function_def __P((const char *, FUNCTION_DEF *));
extern SHELL_VAR **map_over __P((sh_var_map_func_t *, VAR_CONTEXT *));
SHELL_VAR **map_over_funcs __P((sh_var_map_func_t *));
extern SHELL_VAR **all_shell_variables __P((void));
extern SHELL_VAR **all_shell_functions __P((void));
extern SHELL_VAR **all_visible_variables __P((void));
extern SHELL_VAR **all_visible_functions __P((void));
extern SHELL_VAR **all_exported_variables __P((void));
extern SHELL_VAR **local_exported_variables __P((void));
extern SHELL_VAR **all_local_variables __P((void));
#if defined (ARRAY_VARS)
extern SHELL_VAR **all_array_variables __P((void));
#endif
extern char **all_variables_matching_prefix __P((const char *));
extern char **make_var_array __P((HASH_TABLE *));
extern char **add_or_supercede_exported_var __P((char *, int));
extern char *get_variable_value __P((SHELL_VAR *));
extern char *get_string_value __P((const char *));
extern char *sh_get_env_value __P((const char *));
extern char *make_variable_value __P((SHELL_VAR *, char *, int));
extern SHELL_VAR *bind_variable_value __P((SHELL_VAR *, char *, int));
extern SHELL_VAR *bind_int_variable __P((char *, char *));
extern SHELL_VAR *bind_var_to_int __P((char *, intmax_t));
extern int assign_in_env __P((WORD_DESC *));
extern int unbind_variable __P((const char *));
extern int unbind_func __P((const char *));
extern int unbind_function_def __P((const char *));
extern int makunbound __P((const char *, VAR_CONTEXT *));
extern int kill_local_variable __P((const char *));
extern void delete_all_variables __P((HASH_TABLE *));
extern void delete_all_contexts __P((VAR_CONTEXT *));
extern VAR_CONTEXT *new_var_context __P((char *, int));
extern void dispose_var_context __P((VAR_CONTEXT *));
extern VAR_CONTEXT *push_var_context __P((char *, int, HASH_TABLE *));
extern void pop_var_context __P((void));
extern VAR_CONTEXT *push_scope __P((int, HASH_TABLE *));
extern void pop_scope __P((int));
extern void push_context __P((char *, int, HASH_TABLE *));
extern void pop_context __P((void));
extern void push_dollar_vars __P((void));
extern void pop_dollar_vars __P((void));
extern void dispose_saved_dollar_vars __P((void));
extern void push_args __P((WORD_LIST *));
extern void pop_args __P((void));
extern void adjust_shell_level __P((int));
extern void non_unsettable __P((char *));
extern void dispose_variable __P((SHELL_VAR *));
extern void dispose_used_env_vars __P((void));
extern void dispose_function_env __P((void));
extern void dispose_builtin_env __P((void));
extern void merge_temporary_env __P((void));
extern void merge_builtin_env __P((void));
extern void kill_all_local_variables __P((void));
extern void set_var_read_only __P((char *));
extern void set_func_read_only __P((const char *));
extern void set_var_auto_export __P((char *));
extern void set_func_auto_export __P((const char *));
extern void sort_variables __P((SHELL_VAR **));
extern void maybe_make_export_env __P((void));
extern void update_export_env_inplace __P((char *, int, char *));
extern void put_command_name_into_env __P((char *));
extern void put_gnu_argv_flags_into_env __P((intmax_t, char *));
extern void print_var_list __P((SHELL_VAR **));
extern void print_func_list __P((SHELL_VAR **));
extern void print_assignment __P((SHELL_VAR *));
extern void print_var_value __P((SHELL_VAR *, int));
extern void print_var_function __P((SHELL_VAR *));
#if defined (ARRAY_VARS)
extern SHELL_VAR *make_new_array_variable __P((char *));
extern SHELL_VAR *make_local_array_variable __P((char *));
extern SHELL_VAR *make_new_assoc_variable __P((char *));
extern SHELL_VAR *make_local_assoc_variable __P((char *));
extern void set_pipestatus_array __P((int *, int));
#endif
extern void set_pipestatus_from_exit __P((int));
/* The variable in NAME has just had its state changed. Check to see if it
is one of the special ones where something special happens. */
extern void stupidly_hack_special_variables __P((char *));
/* Reinitialize some special variables that have external effects upon unset
when the shell reinitializes itself. */
extern void reinit_special_variables __P((void));
extern int get_random_number __P((void));
/* The `special variable' functions that get called when a particular
variable is set. */
extern void sv_ifs __P((char *));
extern void sv_path __P((char *));
extern void sv_mail __P((char *));
extern void sv_globignore __P((char *));
extern void sv_ignoreeof __P((char *));
extern void sv_strict_posix __P((char *));
extern void sv_optind __P((char *));
extern void sv_opterr __P((char *));
extern void sv_locale __P((char *));
#if defined (READLINE)
extern void sv_comp_wordbreaks __P((char *));
extern void sv_terminal __P((char *));
extern void sv_hostfile __P((char *));
extern void sv_winsize __P((char *));
#endif
#if defined (__CYGWIN__)
extern void sv_home __P((char *));
#endif
#if defined (HISTORY)
extern void sv_histsize __P((char *));
extern void sv_histignore __P((char *));
extern void sv_history_control __P((char *));
# if defined (BANG_HISTORY)
extern void sv_histchars __P((char *));
# endif
extern void sv_histtimefmt __P((char *));
#endif /* HISTORY */
#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
extern void sv_tz __P((char *));
#endif
#endif /* !_VARIABLES_H_ */