is enabled, and turns off when extdebug is disabled. The documentation
has always said that shopt does this. Report from Peng Yu
<pengyu.ut@gmail.com>
+
+ 5/27
+ ----
+findcmd.[ch]
+ - add support for EXECIGNORE shell variable, list of extglob patterns that
+ prevent matching filenames from being identified as executable files
+
+variables.c
+ - EXECIGNORE: arrange for findcmd.c:setup_exec_ignore to be called when
+ $EXECIGNORE changes
+
+variables.h
+ - sv_execignore: extern declaration
+
+doc/{bash.1,bashref.texi}
+ - document EXECIGNORE variable
+
+ 5/28
+ ----
+lib/readline/callback.c
+ - rl_callback_sigcleanup: new function, cleans up and unsets any state
+ rl_callback_read_char uses. Intended to be used after a signal
+
+lib/readline/signals.c
+ - _rl_handle_signal: call rl_callback_sigcleanup on SIGINT. Fixes bug
+ reported to python group by Martin Panter <vadmium+floss@gmail.com>
+
+lib/readline/isearch.c
+ - _rl_isearch_cleanup: now a public function so rl_callback_cleanup can
+ call it
+
+lib/readline/search.c
+ - _rl_nsearch_cleanup: now a public function so rl_callback_cleanup can
+ call it
+
+lib/readline/rlprivate.h
+ - _rl_[in]search_cleanup: extern declarations
+
+lib/readline/readline.h
+ - rl_callback_sigcleanup: new extern declaration
+
+lib/readline/doc/rltech.texi
+ - rl_callback_sigcleanup: documented
+
+lib/readline/readline.h
+ - bump readline version to 7.0 due to addition of rl_callback_sigcleanup
+
+ 5/29
+ ----
+builtins/declare.def
+ - declare_internal: if we are trying to change attributes or value for a
+ nameref variable whose value points to an unset variable, make sure we
+ create a new variable whose name is the value of the nameref variable.
+ That is,
+
+ declare -n foo=bar
+ unset foo # unsets bar
+ declare -i foo
+
+ should create a (invisible) variable named `bar' with the integer
+ attribute. Fixes problem reported by Greg Wooledge
+ <wooledg@eeg.ccf.org>
+
+builtins/set.def
+ - unset_builtin: if we find a nameref variable when we look it up with
+ find_variable (the returned variable has a name different from what
+ we looked up), make sure we use that new name for the rest of the
+ function rather than rely on unbind_variable to do the same thing as
+ find_variable. Fixes problem reported by Greg Wooledge
+ <wooledg@eeg.ccf.org>
+ - unset_builtin: if we try to unset a nameref variable whose value is
+ not a set variable, make sure we don't try to unset the nameref itself,
+ but rather the variable it points to. This ensures that the following
+ always works as it should
+
+ declare -n foo=bar
+ unset foo # unsets bar and leaves foo unchanged
+
+lib/readline/funmap.c
+ - vi-insertion-mode: make sure it maps to rl_vi_insert_mode, which is
+ actually what the `i' keybinding in vi_movement_keymap maps to.
+ Cosmetic fix from isabella parakiss <izaberina@gmail.com>
tests/nameref7.sub f
tests/nameref8.sub f
tests/nameref9.sub f
+tests/nameref10.sub f
tests/nameref.right f
tests/new-exp.tests f
tests/new-exp1.sub f
assign_error++;
NEXT_VARIABLE ();
}
+#if 0
+ if (value && *value && legal_identifier (value) == 0)
+ {
+ builtin_error (_("%s: invalid variable name for name reference"), value);
+ assign_error++;
+ NEXT_VARIABLE ();
+ }
+#endif
}
#if defined (ARRAY_VARS)
var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar));
}
+ /* See if we are trying to set flags or value for an existing nameref
+ that points to a non-existent variable: e.g.,
+ declare -n foo=bar
+ unset foo # unsets bar
+ declare -i foo
+ foo=4+4
+ declare -p foo */
+ if (var == 0 && (flags_on || flags_off || offset))
+ {
+ refvar = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name);
+ if (refvar && nameref_p (refvar) == 0)
+ refvar = 0;
+ if (refvar)
+ var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar));
+ if (refvar && var == 0)
+ {
+ free (name);
+ name = savestring (nameref_cell (refvar));
+ }
+ }
if (var == 0)
var = mkglobal ? find_global_variable (name) : find_variable (name);
}
else if (flags_on & att_nameref)
{
+#if 0
+ if (nameref_p (var) == 0 && var_isset (var) && var_isnull (var) == 0 && legal_identifier (value_cell (var)) == 0)
+ {
+ builtin_error (_("%s: invalid variable name for name reference"), value_cell (var));
+ any_failed++;
+ NEXT_VARIABLE ();
+ }
+#endif
/* ksh93 compat: turning on nameref attribute turns off -ilu */
VUNSETATTR (var, att_integer|att_uppercase|att_lowercase|att_capcase);
}
NEXT_VARIABLE ();
}
+ /* if we have a nameref we want to use it */
+ if (var && unset_function == 0 && nameref == 0 && STREQ (name, name_cell(var)) == 0)
+ name = name_cell (var);
+
/* Posix.2 says try variables first, then functions. If we would
find a function after unsuccessfully searching for a variable,
note that we're acting on a function now as if -f were
}
else
#endif /* ARRAY_VARS */
- tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name));
+ /* If we're trying to unset a nameref variable whose value isn't a set
+ variable, make sure we still try to unset the nameref's value */
+ if (var == 0 && nameref == 0 && unset_function == 0)
+ {
+ var = find_variable_last_nameref (name);
+ tem = (var && nameref_p (var)) ? unbind_variable (nameref_cell (var)) : unbind_variable (name);
+ }
+ else
+ tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name));
/* This is what Posix.2 says: ``If neither -f nor -v
is specified, the name refers to a variable; if a variable by
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
-.\" Last Change: Fri Apr 10 15:04:46 EDT 2015
+.\" Last Change: Wed May 27 14:55:39 EDT 2015
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2015 April 10" "GNU Bash 4.4"
+.TH BASH 1 "2015 May 27" "GNU Bash 4.4"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
.BR BASH_ENV ;
used when the shell is invoked in POSIX mode.
.TP
+.B EXECIGNORE
+A colon-separated list of extended glob patterns (see \fBPattern Matching\fP)
+defining the list of filenames to be ignored by command search.
+Files whose full pathnames match one of these patterns are not considered
+executable files for the purposes of completion and command execution.
+This does not affect the behavior of the \fB[\fP, \fBtest\fP, and \fB[[\fP
+commands.
+Use this variable to ignore shared library files that have the executable
+bit set, but are not executable files.
+.TP
.B FCEDIT
The default editor for the
.B fc
The numeric effective user id of the current user. This variable
is readonly.
+@item EXECIGNORE
+A colon-separated list of extended glob patterns (@pxref{Pattern Matching})
+defining the list of filenames to be ignored by command search.
+Files whose full pathnames match one of these patterns are not considered
+executable files for the purposes of completion and command execution.
+This does not affect the behavior of the @code{[}, @code{test}, and @code{[[}
+commands.
+Use this variable to ignore shared library files that have the executable
+bit set, but are not executable files.
+
@item FCEDIT
The editor used as a default by the @option{-e} option to the @code{fc}
builtin command.
Copyright (C) 1988-2015 Free Software Foundation, Inc.
@end ignore
-@set LASTCHANGE Fri Apr 10 15:04:14 EDT 2015
+@set LASTCHANGE Wed May 27 14:56:01 EDT 2015
@set EDITION 4.4
@set VERSION 4.4
-@set UPDATED 10 April 2015
-@set UPDATED-MONTH April 2015
+@set UPDATED 27 May 2015
+@set UPDATED-MONTH May 2015
/* findcmd.c -- Functions to search for commands by name. */
-/* Copyright (C) 1997-2012 Free Software Foundation, Inc.
+/* Copyright (C) 1997-2015 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
#include "hashcmd.h"
#include "findcmd.h" /* matching prototypes and declarations */
+#include <glob/strmatch.h>
+
#if !defined (errno)
extern int errno;
#endif
containing the file of interest. */
int dot_found_in_search = 0;
+/* Set up EXECIGNORE; a blacklist of patterns that executable files should not
+ match. */
+static struct ignorevar execignore =
+{
+ "EXECIGNORE",
+ NULL,
+ 0,
+ NULL,
+ NULL
+};
+
+void
+setup_exec_ignore (varname)
+ char *varname;
+{
+ setup_ignore_patterns (&execignore);
+}
+
+static int
+exec_name_should_ignore (name)
+ const char *name;
+{
+ struct ign *p;
+
+ for (p = execignore.ignores; p && p->val; p++)
+ if (strmatch (p->val, (char *)name, FNM_EXTMATCH|FNM_CASEFOLD) != FNM_NOMATCH)
+ return 1;
+ return 0;
+}
+
/* Return some flags based on information about this file.
The EXISTS bit is non-zero if the file is found.
The EXECABLE bit is non-zero the file is executble.
file access mechanisms into account. eaccess uses the effective
user and group IDs, not the real ones. We could use sh_eaccess,
but we don't want any special treatment for /dev/fd. */
- if (eaccess (name, X_OK) == 0)
+ if (exec_name_should_ignore (name) == 0 && eaccess (name, X_OK) == 0)
r |= FS_EXECABLE;
if (eaccess (name, R_OK) == 0)
r |= FS_READABLE;
/* We have to use access(2) to determine access because AFS does not
support Unix file system semantics. This may produce wrong
answers for non-AFS files when ruid != euid. I hate AFS. */
- if (access (name, X_OK) == 0)
+ if (exec_name_should_ignore (name) == 0 && access (name, X_OK) == 0)
r |= FS_EXECABLE;
if (access (name, R_OK) == 0)
r |= FS_READABLE;
if (current_user.euid == (uid_t)0)
{
r |= FS_READABLE;
- if (finfo.st_mode & S_IXUGO)
+ if (exec_name_should_ignore (name) == 0 && (finfo.st_mode & S_IXUGO))
r |= FS_EXECABLE;
return r;
}
/* If we are the owner of the file, the owner bits apply. */
if (current_user.euid == finfo.st_uid)
{
- if (finfo.st_mode & S_IXUSR)
+ if (exec_name_should_ignore (name) == 0 && (finfo.st_mode & S_IXUSR))
r |= FS_EXECABLE;
if (finfo.st_mode & S_IRUSR)
r |= FS_READABLE;
/* If we are in the owning group, the group permissions apply. */
else if (group_member (finfo.st_gid))
{
- if (finfo.st_mode & S_IXGRP)
+ if (exec_name_should_ignore (name) == 0 && (finfo.st_mode & S_IXGRP))
r |= FS_EXECABLE;
if (finfo.st_mode & S_IRGRP)
r |= FS_READABLE;
/* findcmd.h - functions from findcmd.c. */
-/* Copyright (C) 1997-2012 Free Software Foundation, Inc.
+/* Copyright (C) 1997-2015 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
extern char *find_path_file __P((const char *));
extern char *search_for_command __P((const char *, int));
extern char *user_command_matches __P((const char *, int, int));
+extern void setup_exec_ignore __P((char *));
#endif /* _FINDCMD_H_ */
xfree (arg);
}
+/* Make sure that this agrees with cases in rl_callback_read_char */
+void
+rl_callback_sigcleanup ()
+{
+ if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
+ return;
+
+ if (RL_ISSTATE (RL_STATE_ISEARCH))
+ _rl_isearch_cleanup (_rl_iscxt, 0);
+ else if (RL_ISSTATE (RL_STATE_NSEARCH))
+ _rl_nsearch_cleanup (_rl_nscxt, 0);
+ else if (RL_ISSTATE (RL_STATE_VIMOTION))
+ RL_UNSETSTATE (RL_STATE_VIMOTION);
+ else if (RL_ISSTATE (RL_STATE_NUMERICARG))
+ {
+ _rl_argcxt = 0;
+ RL_UNSETSTATE (RL_STATE_NUMERICARG);
+ }
+ else if (RL_ISSTATE (RL_STATE_MULTIKEY))
+ RL_UNSETSTATE (RL_STATE_MULTIKEY);
+
+ _rl_callback_func = 0;
+}
#endif
@code{NULL} line.
@end deftypefun
+@deftypefun void rl_callback_sigcleanup (void)
+Clean up any internal state the callback interface uses to maintain state
+between calls to rl_callback_read_char (e.g., the state of any active
+incremental searches). This is intended to be used by applications that
+wish to perform their own signal handling; Readline's internal signal handler
+calls this when appropriate.
+@end deftypefun
+
@deftypefun void rl_callback_handler_remove (void)
Restore the terminal to its initial state and remove the line handler.
You may call this function from within a callback as well as independently.
@set EDITION 6.4
@set VERSION 6.4
-@set UPDATED 24 May 2015
+@set UPDATED 28 May 2015
@set UPDATED-MONTH May 2015
-@set LASTCHANGE Sun May 24 18:01:45 EDT 2015
+@set LASTCHANGE Thu May 28 16:58:07 EDT 2015
--- /dev/null
+/* Standard include files. stdio.h is required. */
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+/* Used for select(2) */
+#include <sys/types.h>
+#include <sys/select.h>
+#include <errno.h>
+
+#include <signal.h>
+
+#include <stdio.h>
+
+/* Standard readline include files. */
+#if defined (READLINE_LIBRARY)
+# include "readline.h"
+# include "history.h"
+#else
+# include <readline/readline.h>
+# include <readline/history.h>
+#endif
+
+static void cb_linehandler (char *);
+static void sigint_sighandler (int);
+static int sigint_handler (int);
+
+static int saw_signal = 0;
+
+int running;
+const char *prompt = "rltest$ ";
+char *input_string;
+
+/* Callback function called for each line when accept-line executed, EOF
+ seen, or EOF character read. This sets a flag and returns; it could
+ also call exit(3). */
+static void
+cb_linehandler (char *line)
+{
+ if (line && *line)
+ add_history (line);
+ printf ("input line: %s\n", line ? line : "");
+ input_string = line;
+ rl_callback_handler_remove ();
+}
+
+static char *
+cb_readline ()
+{
+ fd_set fds;
+ int r, err;
+ char *not_done = "";
+
+ /* Install the line handler. */
+ rl_callback_handler_install (prompt, cb_linehandler);
+
+if (RL_ISSTATE (RL_STATE_ISEARCH))
+ fprintf(stderr, "cb_readline: after handler install, state (ISEARCH) = %d", rl_readline_state);
+else if (RL_ISSTATE (RL_STATE_NSEARCH))
+ fprintf(stderr, "cb_readline: after handler install, state (NSEARCH) = %d", rl_readline_state);
+/* MULTIKEY VIMOTION NUMERICARG _rl_callback_func */
+
+ FD_ZERO (&fds);
+ FD_SET (fileno (rl_instream), &fds);
+
+ input_string = not_done;
+
+ while (input_string == not_done)
+ {
+ r = err = 0;
+ /* Enter a simple event loop. This waits until something is available
+ to read on readline's input stream (defaults to standard input) and
+ calls the builtin character read callback to read it. It does not
+ have to modify the user's terminal settings. */
+ while (r == 0)
+ {
+ struct timeval timeout = {0, 100000};
+ struct timeval *timeoutp = NULL;
+
+ timeoutp = &timeout;
+ FD_SET (fileno (rl_instream), &fds);
+ r = select (FD_SETSIZE, &fds, NULL, NULL, timeoutp);
+ err = errno;
+ }
+
+ if (saw_signal)
+ sigint_handler (saw_signal);
+
+ if (r < 0)
+ {
+ perror ("rltest: select");
+ rl_callback_handler_remove ();
+ break;
+ }
+
+ /* if (FD_ISSET (fileno (rl_instream), &fds)) */
+ if (r > 0)
+ rl_callback_read_char ();
+ }
+ return input_string;
+}
+
+void
+sigint_sighandler (s)
+ int s;
+{
+ saw_signal = s;
+}
+
+int
+sigint_handler (s)
+ int s;
+{
+ rl_free_line_state ();
+ rl_callback_sigcleanup ();
+ rl_cleanup_after_signal ();
+ rl_callback_handler_remove ();
+ saw_signal = 0;
+fprintf(stderr, "sigint_handler: readline state = %d\r\n", rl_readline_state);
+ return s;
+}
+
+int
+main (int c, char **v)
+{
+ char *p;
+
+ running = 1;
+ rl_catch_signals = 1;
+
+ rl_bind_key_in_map ('r', rl_history_search_backward, emacs_meta_keymap);
+ rl_bind_key_in_map ('s', rl_history_search_forward, emacs_meta_keymap);
+
+ signal (SIGINT, sigint_sighandler);
+ while (running)
+ {
+ p = cb_readline ();
+ if (p == 0 || strcmp (p, "exit") == 0)
+ break;
+ }
+ printf ("rl-callbacktest2: Event loop has exited\n");
+ return 0;
+}
{ "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-insertion-mode", rl_vi_insert_mode },
{ "vi-match", rl_vi_match },
{ "vi-movement-mode", rl_vi_movement_mode },
{ "vi-next-word", rl_vi_next_word },
static _rl_search_cxt *_rl_isearch_init PARAMS((int));
static void _rl_isearch_fini PARAMS((_rl_search_cxt *));
-static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
/* Last line found by the current incremental search, so we don't `find'
identical lines many times in a row. Now part of isearch context. */
return 1;
}
-static int
+int
_rl_isearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;
#endif
/* Hex-encoded Readline version number. */
-#define RL_READLINE_VERSION 0x0604 /* Readline 6.4 */
-#define RL_VERSION_MAJOR 6
-#define RL_VERSION_MINOR 4
+#define RL_READLINE_VERSION 0x0700 /* Readline 7.0 */
+#define RL_VERSION_MAJOR 7
+#define RL_VERSION_MINOR 0
/* Readline data structures. */
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));
+extern void rl_callback_sigcleanup PARAMS((void));
/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
/* VI-mode bindable commands. */
extern int _rl_isearch_dispatch PARAMS((_rl_search_cxt *, int));
extern int _rl_isearch_callback PARAMS((_rl_search_cxt *));
+extern int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
extern int _rl_search_getchar PARAMS((_rl_search_cxt *));
/* search.c */
extern int _rl_nsearch_callback PARAMS((_rl_search_cxt *));
+extern int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
/* signals.c */
extern void _rl_signal_handler PARAMS((int));
static void rl_history_search_reinit PARAMS((int));
static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
-static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
return cxt;
}
-static int
+int
_rl_nsearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;
case SIGINT:
_rl_reset_completion_state ();
rl_free_line_state ();
+#if defined (READLINE_CALLBACKS)
+ rl_callback_sigcleanup ();
+#endif
+
/* FALLTHROUGH */
#if defined (SIGTSTP)
/* pathexp.h -- The shell interface to the globbing library. */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2015 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
extern char **shell_glob_filename __P((const char *));
/* Filename completion ignore. Used to implement the "fignore" facility of
- tcsh and GLOBIGNORE (like ksh-93 FIGNORE).
+ tcsh, GLOBIGNORE (like ksh-93 FIGNORE), and EXECIGNORE.
It is passed a NULL-terminated array of (char *)'s that must be
free()'d if they are deleted. The first element (names[0]) is the
typedef int sh_iv_item_func_t __P((struct ign *));
struct ignorevar {
- char *varname; /* FIGNORE or GLOBIGNORE */
+ char *varname; /* FIGNORE, GLOBIGNORE, or EXECIGNORE */
struct ign *ignores; /* Store the ignore strings here */
int num_ignores; /* How many are there? */
char *last_ignoreval; /* Last value of variable - cached for speed */
-BUILD_DIR=/usr/local/build/chet/bash/bash-current
+BUILD_DIR=/usr/local/build/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
idX2
idx2
idX2
+declare -n foo="x[\$zero]"
+42
+declare -a x=([0]="4")
+declare -n foo="x[\$(echo 0)]"
+4
+comsub
+x[i=0]
+comsub
+4
+comsub
+4
+comsub
+4
+declare -n foo="somevariable"
+./nameref10.sub: line 38: typeset: somevariable: not found
+foo =
+declare -n foo="somevariable"
+declare -A somevariable=([jug]="brown" )
+./nameref10.sub: line 45: warning: foo=([jug]="brown" ): quoted compound array assignment deprecated
+declare -n foo="somevariable"
+declare -A somevariable=([jug]="brown" )
+declare -n foo="somevariable"
+./nameref10.sub: line 49: typeset: somevariable: not found
+./nameref10.sub: line 51: typeset: foo: not found
+./nameref10.sub: line 51: typeset: somevariable: not found
+declare -n foo="bar"
+./nameref10.sub: line 55: typeset: bar: not found
+declare -n foo="bar"
+./nameref10.sub: line 57: typeset: bar: not found
+declare -n foo="bar"
+declare -i bar="8"
+8
+declare -n foo="bar"
+./nameref10.sub: line 64: typeset: bar: not found
${THIS_SH} ./nameref7.sub
${THIS_SH} ./nameref8.sub
${THIS_SH} ./nameref9.sub
+${THIS_SH} ./nameref10.sub
--- /dev/null
+# testing behavior of command substitution as one of expansions performed by
+# array subscripting; should behave the same directly as when done through
+# a nameref
+
+x[0]=42
+zero=0
+f() { typeset -n foo="$1"; declare -p foo; echo "$foo"; }
+
+f 'x[$zero]'
+
+x[$(echo 0)]=4
+declare -p x
+
+f 'x[$(echo 0)]'
+
+unset -f f
+f()
+{
+ typeset -n foo="$1";
+
+ echo "x[i=0$(echo comsub >&2)]"
+ echo "${x[i=0$(echo comsub >&2)]}"
+ echo "${!1}"
+ echo "$foo"
+}
+
+f 'x[i=0$(echo comsub >&2)]'
+
+unset -f f
+unset x
+
+# problems with unset and namerefs pointing to non-existent variables pointed
+# out after bash-4.3 released
+
+typeset -n foo=somevariable
+foo=bar
+unset foo # unsets somevariable
+typeset -p foo somevariable
+echo foo = $foo
+
+typeset -A foo # should create array variable named somevariable
+foo["jug"]="brown"
+
+typeset -p foo somevariable
+typeset -A foo='([jug]="brown" )'
+typeset -p foo somevariable
+
+unset foo
+typeset -p foo somevariable
+unset -n foo
+typeset -p foo somevariable
+
+unset bar
+typeset -n foo=bar
+typeset -p foo bar
+unset foo
+typeset -p foo bar
+typeset -i foo
+foo=4+4
+typeset -p foo bar
+echo "$foo"
+
+unset foo
+typeset -p foo bar
# XXX -- another self-referencing error?
# ksh93 makes this another invalid self-reference
-unset foo bar
+unset foo
+unset -n bar
+
bar=123
foobar()
{
short=( a b )
echo "expect <a b>"
echo ${long[@]}
-unset short long
+unset long
+unset -n short
# assignment to a previously-unset variable
typeset -n short=long
short=foo
echo "expect <foo>"
echo ${long}
-unset short long
+unset long
+unset -n short
unset foo bar
barfunc bar
unset -f foobar
-unset foo bar
+unset bar
+unset -n foo
# should ref at global scope survive call to foobar()?
unset ref x
recho "${x[@]}"
unset ref x
+unset -n ref
+
typeset -n ref
ref=x
# make sure nameref to a previously-unset variable creates the variable
# make sure they work inside arithmetic expressions
unset foo bar ref x xxx
+unset -n ref
+
typeset -i ivar
typeset -n iref=ivar
{ "COMP_WORDBREAKS", sv_comp_wordbreaks },
#endif
+ { "EXECIGNORE", sv_execignore },
+
{ "FUNCNEST", sv_funcnest },
{ "GLOBIGNORE", sv_globignore },
funcnest_max = num;
}
+/* What to do when EXECIGNORE changes. */
+void
+sv_execignore (name)
+ char *name;
+{
+ setup_exec_ignore (name);
+}
+
/* What to do when GLOBIGNORE changes. */
void
sv_globignore (name)
return;
v = find_variable (name);
- if (v == 0 || var_isnull (v))
+ if (v == 0 || var_isset (v) == 0)
rl_reset_screen_size ();
else
{
/* variables.h -- data structures for shell variables. */
-/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2015 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
#define tempvar_p(var) ((((var)->attributes) & (att_tempvar)))
+/* Variable names: lvalues */
+#define name_cell(var) ((var)->name)
+
/* Acessing variable values: rvalues */
#define value_cell(var) ((var)->value)
#define function_cell(var) (COMMAND *)((var)->value)
#define NAMEREF_MAX 8 /* only 8 levels of nameref indirection */
-#define var_isnull(var) ((var)->value == 0)
#define var_isset(var) ((var)->value != 0)
+#define var_isunset(var) ((var)->value == 0)
+#define var_isnull(var) ((var)->value && *(var)->value == 0)
/* Assigning variable values: lvalues */
#define var_setvalue(var, str) ((var)->value = (str))
extern void sv_path __P((char *));
extern void sv_mail __P((char *));
extern void sv_funcnest __P((char *));
+extern void sv_execignore __P((char *));
extern void sv_globignore __P((char *));
extern void sv_ignoreeof __P((char *));
extern void sv_strict_posix __P((char *));