commit bash-20080313 snapshot

This commit is contained in:
Chet Ramey
2011-12-07 09:20:32 -05:00
parent 29d25b5400
commit 7e52d2bf76
22 changed files with 4207 additions and 42 deletions
+46
View File
@@ -15347,3 +15347,49 @@ builtins/read.def
lib/glob/xmbsrtowcs.c
- cut the number of memory allocations in xdupmbstowcs by not keeping
track of the indices if the caller hasn't asked for it
3/17
----
builtins/fc.def
- make sure the adjustment to i in fc_gethnum uses the same formula
fc_builtin uses to calculate last_hist
- make sure that every time fc_gethnum is called, the fc command last
in the history list has not yet been deleted, since fc_gethnum
assumes that it has not. Fix from John Haxby <john.haxby@oracle.com>
lib/readline/complete.c
- new private library function, _rl_reset_completion_state(), used to
reset any completion state internal to the library when a signal
is received
- call _rl_reset_completion_state() before returning from
rl_complete_internal
lib/readline/rlprivate.h
- new extern declaration for _rl_reset_completion_state
lib/readline/signals.c
- call _rl_reset_completion_state from rl_signal_handler on SIGINT.
This fixes one of the problems identified by Mika Fischer
<mf+ubuntu@zoopnet.de>
pcomplete.c
- programmable_completions now saves pointer to the compspec it's
working with in new global variable CURCS
- new function, pcomp_set_readline_variables, that sets or unsets
readline variables based on a passed flags value (COPT_FILENAMES,
etc.)
- new function, pcomp_set_compspec_options, to set or unset bits in
the options word of a passed compspec (default CURCS)
pcomplete.h
- new extern declaration for curcs
- new extern declaration for pcomp_set_readline_variables
- new extern declaration for pcomp_set_compspec_options
bashline.c
- fix bash_dequote_filename to implement shell quoting conventions:
1. Inhibit backslash stripping within single quotes
2. Inhibit backslash stripping within double quotes only if
the following character is one of the special ones
- call pcomp_set_readline_variables from attempt_shell_completion
instead of doing the equivalent inline
+49
View File
@@ -15341,3 +15341,52 @@ builtins/cd.def
builtins/read.def
- when read times out, make sure input_string is null-terminated before
assigning any partial input read to the named variables
3/10
----
lib/glob/xmbsrtowcs.c
- cut the number of memory allocations in xdupmbstowcs by not keeping
track of the indices if the caller hasn't asked for it
3/17
----
builtins/fc.def
- make sure the adjustment to i in fc_gethnum uses the same formula
fc_builtin uses to calculate last_hist
- make sure that every time fc_gethnum is called, the fc command last
in the history list has not yet been deleted, since fc_gethnum
assumes that it has not. Fix from John Haxby <john.haxby@oracle.com>
lib/readline/complete.c
- new private library function, _rl_reset_completion_state(), used to
reset any completion state internal to the library when a signal
is received
- call _rl_reset_completion_state() before returning from
rl_complete_internal
lib/readline/rlprivate.h
- new extern declaration for _rl_reset_completion_state
lib/readline/signals.c
- call _rl_reset_completion_state from rl_signal_handler on SIGINT.
This fixes one of the problems identified by Mika Fischer
<mf+ubuntu@zoopnet.de>
pcomplete.c
- programmable_completions now saves pointer to the compspec it's
working with in new global variable CURCS
- new function, pcomp_set_readline_variables, that sets or unsets
readline variables based on a passed flags value (COPT_FILENAMES,
etc.)
pcomplete.h
- new extern declaration for curcs
- new extern declaration for pcomp_set_readline_variables
bashline.c
- fix bash_dequote_filename to implement shell quoting conventions:
1. Inhibit backslash stripping within single quotes
2. Inhibit backslash stripping within double quotes only if
the following character is one of the special ones
- call pcomp_set_readline_variables from attempt_shell_completion
instead of doing the equivalent inline
+10 -8
View File
@@ -1095,13 +1095,7 @@ attempt_shell_completion (text, start, end)
option has been set with the `-o default' option to complete. */
if (foundcs)
{
/* If the user specified that the compspec returns filenames, make
sure that readline knows it. */
if (foundcs & COPT_FILENAMES)
rl_filename_completion_desired = 1;
/* If the user doesn't want a space appended, tell readline. */
if (foundcs & COPT_NOSPACE)
rl_completion_suppress_append = 1;
pcomp_set_readline_variables (foundcs, 1);
/* Turn what the programmable completion code returns into what
readline wants. I should have made compute_lcd_of_matches
external... */
@@ -2862,9 +2856,17 @@ bash_dequote_filename (text, quote_char)
ret = (char *)xmalloc (l + 1);
for (quoted = quote_char, p = text, r = ret; p && *p; p++)
{
/* Allow backslash-quoted characters to pass through unscathed. */
/* Allow backslash-escaped characters to pass through unscathed. */
if (*p == '\\')
{
/* Backslashes are preserved within single quotes. */
if (quoted == '\'')
*r++ = *p;
/* Backslashes are preserved within double quotes unless the
character is one that is defined to be escaped */
else if (quoted == '"' && ((sh_syntaxtab[p[1]] & CBSDQUOTE) == 0))
*r++ = *p;
*r++ = *++p;
if (*p == '\0')
break;
+3217
View File
File diff suppressed because it is too large Load Diff
+10 -3
View File
@@ -1487,8 +1487,6 @@ command_word_completion_function (hint_text, state)
int l, vl, dl, dl2, xl;
char *rd, *dh2, *expdir;
dh2 = directory_part ? bash_dequote_filename (directory_part, 0) : 0;
vl = strlen (val);
rd = savestring (filename_hint);
@@ -1496,6 +1494,7 @@ command_word_completion_function (hint_text, state)
dl = strlen (rd);
free (rd);
dh2 = directory_part ? bash_dequote_filename (directory_part, 0) : 0;
bash_directory_expansion (&dh2);
dl2 = strlen (dh2);
@@ -2863,9 +2862,17 @@ bash_dequote_filename (text, quote_char)
ret = (char *)xmalloc (l + 1);
for (quoted = quote_char, p = text, r = ret; p && *p; p++)
{
/* Allow backslash-quoted characters to pass through unscathed. */
/* Allow backslash-escaped characters to pass through unscathed. */
if (*p == '\\')
{
/* Backslashes are preserved within single quotes. */
if (quoted == '\'')
*r++ = *p;
/* Backslashes are preserved within double quotes unless the
character is one that is defined to be escaped */
else if (quoted == '"' && ((sh_syntaxtab[p[1]] & CBSDQUOTE) == 0))
*r++ = *p;
*r++ = *++p;
if (*p == '\0')
break;
+1 -1
View File
@@ -66,7 +66,7 @@ LOCAL_DEFS = @LOCAL_DEFS@
LIBS = @LIBS@
LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
LDFLAGS_FOR_BUILD = $(LDFLAGS)
LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ $(LOCAL_LDFLAGS) $(CFLAGS_FOR_BUILD)
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
#LIBS_FOR_BUILD = @LIBS_FOR_BUILD@
LIBS_FOR_BUILD = $(LIBS)
+10 -8
View File
@@ -290,11 +290,6 @@ fc_builtin (list)
line was actually added (HISTIGNORE may have caused it to not be),
so we check hist_last_line_added. */
/* "When not listing, the fc command that caused the editing shall not be
entered into the history list." */
if (listing == 0 && hist_last_line_added)
delete_last_history ();
last_hist = i - remember_on_history - hist_last_line_added;
if (list)
@@ -322,6 +317,11 @@ fc_builtin (list)
histbeg = histend = last_hist;
}
/* "When not listing, the fc command that caused the editing shall not be
entered into the history list." */
if (listing == 0 && hist_last_line_added)
delete_last_history ();
/* We print error messages for line specifications out of range. */
if ((histbeg < 0) || (histend < 0))
{
@@ -443,10 +443,11 @@ fc_gethnum (command, hlist)
char *command;
HIST_ENTRY **hlist;
{
int sign = 1, n, clen;
int sign, n, clen;
register int i, j;
register char *s;
sign = 1;
/* Count history elements. */
for (i = 0; hlist[i]; i++);
@@ -456,8 +457,9 @@ fc_gethnum (command, hlist)
and makes the last command that this deals with be the last command
the user entered before the fc. We need to check whether the
line was actually added (HISTIGNORE may have caused it to not be),
so we check hist_last_line_added. */
i -= 1 + hist_last_line_added;
so we check hist_last_line_added. This needs to agree with the
calculation of last_hist in fc_builtin above. */
i -= remember_on_history + hist_last_line_added;
/* No specification defaults to most recent command. */
if (command == NULL)
+6 -4
View File
@@ -290,7 +290,7 @@ fc_builtin (list)
line was actually added (HISTIGNORE may have caused it to not be),
so we check hist_last_line_added. */
/* "When not listing, the fc command that caused the editing shall not be
/* "When not listing, the fc command that caused the editing shall not be
entered into the history list." */
if (listing == 0 && hist_last_line_added)
delete_last_history ();
@@ -443,10 +443,11 @@ fc_gethnum (command, hlist)
char *command;
HIST_ENTRY **hlist;
{
int sign = 1, n, clen;
int sign, n, clen;
register int i, j;
register char *s;
sign = 1;
/* Count history elements. */
for (i = 0; hlist[i]; i++);
@@ -456,8 +457,9 @@ fc_gethnum (command, hlist)
and makes the last command that this deals with be the last command
the user entered before the fc. We need to check whether the
line was actually added (HISTIGNORE may have caused it to not be),
so we check hist_last_line_added. */
i -= 1 + hist_last_line_added;
so we check hist_last_line_added. This needs to agree with the
calculation of last_hist in fc_builtin above. */
i -= remember_on_history + hist_last_line_added;
/* No specification defaults to most recent command. */
if (command == NULL)
+12
View File
@@ -405,6 +405,14 @@ rl_completion_mode (cfunc)
/* */
/************************************/
/* Reset readline state on a signal or other event. */
void
_rl_reset_completion_state ()
{
rl_completion_found_quote = 0;
rl_completion_quote_character = 0;
}
/* Set default values for readline word completion. These are the variables
that application completion functions can change or inspect. */
static void
@@ -1697,6 +1705,7 @@ rl_complete_internal (what_to_do)
FREE (saved_line_buffer);
completion_changed_buffer = 0;
RL_UNSETSTATE(RL_STATE_COMPLETING);
_rl_reset_completion_state ();
return (0);
}
@@ -1711,6 +1720,7 @@ rl_complete_internal (what_to_do)
FREE (saved_line_buffer);
completion_changed_buffer = 0;
RL_UNSETSTATE(RL_STATE_COMPLETING);
_rl_reset_completion_state ();
return (0);
}
@@ -1765,6 +1775,7 @@ rl_complete_internal (what_to_do)
rl_ding ();
FREE (saved_line_buffer);
RL_UNSETSTATE(RL_STATE_COMPLETING);
_rl_reset_completion_state ();
return 1;
}
@@ -1778,6 +1789,7 @@ rl_complete_internal (what_to_do)
}
RL_UNSETSTATE(RL_STATE_COMPLETING);
_rl_reset_completion_state ();
return 0;
}
+9 -1
View File
@@ -405,6 +405,14 @@ rl_completion_mode (cfunc)
/* */
/************************************/
/* Reset readline state on a signal. */
void
_rl_reset_completion_state ()
{
rl_completion_found_quote = 0;
rl_completion_quote_character = 0;
}
/* Set default values for readline word completion. These are the variables
that application completion functions can change or inspect. */
static void
@@ -599,7 +607,7 @@ fnwidth (string)
width = pos = 0;
while (string[pos])
{
if (CTRL_CHAR (*string) || *string == RUBOUT)
if (CTRL_CHAR (string[pos]) || string[pos] == RUBOUT)
{
width += 2;
pos++;
+1
View File
@@ -216,6 +216,7 @@ extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *));
/* bind.c */
/* complete.c */
extern void _rl_reset_completion_state PARAMS((void));
extern char _rl_find_completion_word PARAMS((int *, int *));
extern void _rl_free_match_list PARAMS((char **));
+1
View File
@@ -34,6 +34,7 @@
* *
*************************************************************************/
#define EMACS_MODE() (rl_editing_mode == emacs_mode)
#define VI_COMMAND_MODE() (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
#define VI_INSERT_MODE() (rl_editing_mode == vi_mode && _rl_keymap == vi_insertion_keymap)
+1
View File
@@ -142,6 +142,7 @@ rl_signal_handler (sig)
switch (sig)
{
case SIGINT:
_rl_reset_completion_state ();
rl_free_line_state ();
/* FALLTHROUGH */
+466
View File
@@ -0,0 +1,466 @@
/* signals.c -- signal handling support for readline. */
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library 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 2, or
(at your option) any later version.
The GNU Readline Library 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.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h> /* Just for NULL. Yuck. */
#include <sys/types.h>
#include <signal.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#if defined (GWINSZ_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL */
#if defined (HANDLE_SIGNALS)
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#if !defined (RETSIGTYPE)
# if defined (VOID_SIGHANDLER)
# define RETSIGTYPE void
# else
# define RETSIGTYPE int
# endif /* !VOID_SIGHANDLER */
#endif /* !RETSIGTYPE */
#if defined (VOID_SIGHANDLER)
# define SIGHANDLER_RETURN return
#else
# define SIGHANDLER_RETURN return (0)
#endif
/* This typedef is equivalent to the one for Function; it allows us
to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
typedef RETSIGTYPE SigHandler ();
#if defined (HAVE_POSIX_SIGNALS)
typedef struct sigaction sighandler_cxt;
# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
#else
typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
# define sigemptyset(m)
#endif /* !HAVE_POSIX_SIGNALS */
#ifndef SA_RESTART
# define SA_RESTART 0
#endif
static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
/* Exported variables for use by applications. */
/* If non-zero, readline will install its own signal handlers for
SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
int rl_catch_signals = 1;
/* If non-zero, readline will install a signal handler for SIGWINCH. */
#ifdef SIGWINCH
int rl_catch_sigwinch = 1;
#else
int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
#endif
static int signals_set_flag;
static int sigwinch_set_flag;
/* **************************************************************** */
/* */
/* Signal Handling */
/* */
/* **************************************************************** */
static sighandler_cxt old_int, old_term, old_alrm, old_quit;
#if defined (SIGTSTP)
static sighandler_cxt old_tstp, old_ttou, old_ttin;
#endif
#if defined (SIGWINCH)
static sighandler_cxt old_winch;
#endif
/* Readline signal handler functions. */
static RETSIGTYPE
rl_signal_handler (sig)
int sig;
{
#if defined (HAVE_POSIX_SIGNALS)
sigset_t set;
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
long omask;
# else /* !HAVE_BSD_SIGNALS */
sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */
# endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
RL_SETSTATE(RL_STATE_SIGHANDLER);
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
/* Since the signal will not be blocked while we are in the signal
handler, ignore it until rl_clear_signals resets the catcher. */
# if defined (SIGALRM)
if (sig == SIGINT || sig == SIGALRM)
# else
if (sig == SIGINT)
# endif
rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
switch (sig)
{
case SIGINT:
rl_free_line_state ();
/* FALLTHROUGH */
case SIGTERM:
#if defined (SIGTSTP)
case SIGTSTP:
case SIGTTOU:
case SIGTTIN:
#endif /* SIGTSTP */
#if defined (SIGALRM)
case SIGALRM:
#endif
#if defined (SIGQUIT)
case SIGQUIT:
#endif
rl_cleanup_after_signal ();
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&set);
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
sigdelset (&set, sig);
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
omask = sigblock (0);
# endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
#if defined (__EMX__)
signal (sig, SIG_ACK);
#endif
#if defined (HAVE_KILL)
kill (getpid (), sig);
#else
raise (sig); /* assume we have raise */
#endif
/* Let the signal that we just sent through. */
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
sigsetmask (omask & ~(sigmask (sig)));
# endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
rl_reset_after_signal ();
}
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
SIGHANDLER_RETURN;
}
#if defined (SIGWINCH)
static RETSIGTYPE
rl_sigwinch_handler (sig)
int sig;
{
SigHandler *oh;
#if defined (MUST_REINSTALL_SIGHANDLERS)
sighandler_cxt dummy_winch;
/* We don't want to change old_winch -- it holds the state of SIGWINCH
disposition set by the calling application. We need this state
because we call the application's SIGWINCH handler after updating
our own idea of the screen size. */
rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
#endif
RL_SETSTATE(RL_STATE_SIGHANDLER);
rl_resize_terminal ();
/* If another sigwinch handler has been installed, call it. */
oh = (SigHandler *)old_winch.sa_handler;
if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
(*oh) (sig);
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
SIGHANDLER_RETURN;
}
#endif /* SIGWINCH */
/* Functions to manage signal handling. */
#if !defined (HAVE_POSIX_SIGNALS)
static int
rl_sigaction (sig, nh, oh)
int sig;
sighandler_cxt *nh, *oh;
{
oh->sa_handler = signal (sig, nh->sa_handler);
return 0;
}
#endif /* !HAVE_POSIX_SIGNALS */
/* Set up a readline-specific signal handler, saving the old signal
information in OHANDLER. Return the old signal handler, like
signal(). */
static SigHandler *
rl_set_sighandler (sig, handler, ohandler)
int sig;
SigHandler *handler;
sighandler_cxt *ohandler;
{
sighandler_cxt old_handler;
#if defined (HAVE_POSIX_SIGNALS)
struct sigaction act;
act.sa_handler = handler;
act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
sigemptyset (&act.sa_mask);
sigemptyset (&ohandler->sa_mask);
sigaction (sig, &act, &old_handler);
#else
old_handler.sa_handler = (SigHandler *)signal (sig, handler);
#endif /* !HAVE_POSIX_SIGNALS */
/* XXX -- assume we have memcpy */
/* If rl_set_signals is called twice in a row, don't set the old handler to
rl_signal_handler, because that would cause infinite recursion. */
if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
return (ohandler->sa_handler);
}
static void
rl_maybe_set_sighandler (sig, handler, ohandler)
int sig;
SigHandler *handler;
sighandler_cxt *ohandler;
{
sighandler_cxt dummy;
SigHandler *oh;
sigemptyset (&dummy.sa_mask);
oh = rl_set_sighandler (sig, handler, ohandler);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (sig, ohandler, &dummy);
}
int
rl_set_signals ()
{
sighandler_cxt dummy;
SigHandler *oh;
#if defined (HAVE_POSIX_SIGNALS)
static int sigmask_set = 0;
static sigset_t bset, oset;
#endif
#if defined (HAVE_POSIX_SIGNALS)
if (rl_catch_signals && sigmask_set == 0)
{
sigemptyset (&bset);
sigaddset (&bset, SIGINT);
sigaddset (&bset, SIGTERM);
#if defined (SIGQUIT)
sigaddset (&bset, SIGQUIT);
#endif
#if defined (SIGALRM)
sigaddset (&bset, SIGALRM);
#endif
#if defined (SIGTSTP)
sigaddset (&bset, SIGTSTP);
#endif
#if defined (SIGTTIN)
sigaddset (&bset, SIGTTIN);
#endif
#if defined (SIGTTOU)
sigaddset (&bset, SIGTTOU);
#endif
sigmask_set = 1;
}
#endif /* HAVE_POSIX_SIGNALS */
if (rl_catch_signals && signals_set_flag == 0)
{
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&oset);
sigprocmask (SIG_BLOCK, &bset, &oset);
#endif
rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
#if defined (SIGQUIT)
rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
#endif
#if defined (SIGALRM)
oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
/* If the application using readline has already installed a signal
handler with SA_RESTART, SIGALRM will cause reads to be restarted
automatically, so readline should just get out of the way. Since
we tested for SIG_IGN above, we can just test for SIG_DFL here. */
if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#endif /* HAVE_POSIX_SIGNALS */
#endif /* SIGALRM */
#if defined (SIGTSTP)
rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
#endif /* SIGTSTP */
#if defined (SIGTTOU)
rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
#endif /* SIGTTOU */
#if defined (SIGTTIN)
rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
#endif /* SIGTTIN */
signals_set_flag = 1;
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
#endif
}
#if defined (SIGWINCH)
if (rl_catch_sigwinch && sigwinch_set_flag == 0)
{
rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
sigwinch_set_flag = 1;
}
#endif /* SIGWINCH */
return 0;
}
int
rl_clear_signals ()
{
sighandler_cxt dummy;
if (rl_catch_signals && signals_set_flag == 1)
{
sigemptyset (&dummy.sa_mask);
rl_sigaction (SIGINT, &old_int, &dummy);
rl_sigaction (SIGTERM, &old_term, &dummy);
#if defined (SIGQUIT)
rl_sigaction (SIGQUIT, &old_quit, &dummy);
#endif
#if defined (SIGALRM)
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#endif
#if defined (SIGTSTP)
rl_sigaction (SIGTSTP, &old_tstp, &dummy);
#endif /* SIGTSTP */
#if defined (SIGTTOU)
rl_sigaction (SIGTTOU, &old_ttou, &dummy);
#endif /* SIGTTOU */
#if defined (SIGTTIN)
rl_sigaction (SIGTTIN, &old_ttin, &dummy);
#endif /* SIGTTIN */
signals_set_flag = 0;
}
#if defined (SIGWINCH)
if (rl_catch_sigwinch && sigwinch_set_flag == 1)
{
sigemptyset (&dummy.sa_mask);
rl_sigaction (SIGWINCH, &old_winch, &dummy);
sigwinch_set_flag = 0;
}
#endif
return 0;
}
/* Clean up the terminal and readline state after catching a signal, before
resending it to the calling application. */
void
rl_cleanup_after_signal ()
{
_rl_clean_up_for_exit ();
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
rl_clear_pending_input ();
rl_clear_signals ();
}
/* Reset the terminal and readline state after a signal handler returns. */
void
rl_reset_after_signal ()
{
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
rl_set_signals ();
}
/* Free up the readline variable line state for the current line (undo list,
any partial history entry, any keyboard macros in progress, and any
numeric arguments in process) after catching a signal, before calling
rl_cleanup_after_signal(). */
void
rl_free_line_state ()
{
register HIST_ENTRY *entry;
rl_free_undo_list ();
entry = current_history ();
if (entry)
entry->data = (char *)NULL;
_rl_kill_kbd_macro ();
rl_clear_message ();
_rl_reset_argument ();
}
#endif /* HANDLE_SIGNALS */
+41 -8
View File
@@ -164,6 +164,8 @@ ITEMLIST it_stopped = { LIST_DYNAMIC, it_init_stopped, (STRINGLIST *)0 };
ITEMLIST it_users = { LIST_DYNAMIC }; /* unused */
ITEMLIST it_variables = { LIST_DYNAMIC, it_init_variables, (STRINGLIST *)0 };
COMPSPEC *curcs;
#ifdef DEBUG
/* Debugging code */
static void
@@ -688,18 +690,17 @@ pcomp_filename_completion_function (text, state)
{
FREE (dfn);
/* remove backslashes quoting special characters in filenames. */
if (rl_filename_dequoting_function)
{
#if 0
qc = (text[0] == '"' || text[0] == '\'') ? text[0] : 0;
#if 1
if (RL_ISSTATE (RL_STATE_COMPLETING) && rl_filename_dequoting_function)
#else
if (rl_filename_dequoting_function)
#endif
{
/* Use rl_completion_quote_character because any single or
double quotes have been removed by the time TEXT makes it
here, and we don't want to remove backslashes inside
quoted strings. */
qc = rl_dispatching ? rl_completion_quote_character : 0;
#endif
dfn = (*rl_filename_dequoting_function) ((char *)text, qc);
dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
}
else
dfn = savestring (text);
@@ -1359,6 +1360,34 @@ gen_compspec_completions (cs, cmd, word, start, end)
return (ret);
}
void
pcomp_set_readline_variables (flags, nval)
int flags, nval;
{
/* If the user specified that the compspec returns filenames, make
sure that readline knows it. */
if (flags & COPT_FILENAMES)
rl_filename_completion_desired = nval;
/* If the user doesn't want a space appended, tell readline. */
if (flags & COPT_NOSPACE)
rl_completion_suppress_append = nval;
}
/* Set or unset FLAGS in the options word of the current compspec.
SET_OR_UNSET is 1 for setting, 0 for unsetting. */
void
pcomp_set_compspec_options (cs, flags, set_or_unset)
COMPSPEC *cs;
int flags, set_or_unset;
{
if (cs == 0 || (cs = curcs) == 0)
return;
if (set_or_unset)
cs->options |= flags;
else
cs->options &= ~flags;
}
/* The driver function for the programmable completion code. Returns a list
of matches for WORD, which is an argument to command CMD. START and END
bound the command currently being completed in rl_line_buffer. */
@@ -1368,7 +1397,7 @@ programmable_completions (cmd, word, start, end, foundp)
const char *word;
int start, end, *foundp;
{
COMPSPEC *cs;
COMPSPEC *cs, *oldcs;
STRINGLIST *ret;
char **rmatches, *t;
@@ -1390,6 +1419,9 @@ programmable_completions (cmd, word, start, end, foundp)
cs = compspec_copy (cs);
oldcs = curcs;
curcs = cs;
/* Signal the caller that we found a COMPSPEC for this command, and pass
back any meta-options associated with the compspec. */
if (foundp)
@@ -1397,6 +1429,7 @@ programmable_completions (cmd, word, start, end, foundp)
ret = gen_compspec_completions (cs, cmd, word, start, end);
curcs = oldcs;
compspec_dispose (cs);
if (ret)
+44 -8
View File
@@ -164,6 +164,8 @@ ITEMLIST it_stopped = { LIST_DYNAMIC, it_init_stopped, (STRINGLIST *)0 };
ITEMLIST it_users = { LIST_DYNAMIC }; /* unused */
ITEMLIST it_variables = { LIST_DYNAMIC, it_init_variables, (STRINGLIST *)0 };
COMPSPEC *curcs;
#ifdef DEBUG
/* Debugging code */
static void
@@ -688,18 +690,17 @@ pcomp_filename_completion_function (text, state)
{
FREE (dfn);
/* remove backslashes quoting special characters in filenames. */
if (rl_filename_dequoting_function)
{
#if 0
qc = (text[0] == '"' || text[0] == '\'') ? text[0] : 0;
#if 1
if (RL_ISSTATE (RL_STATE_COMPLETING) && rl_filename_dequoting_function)
#else
if (rl_filename_dequoting_function)
#endif
{
/* Use rl_completion_quote_character because any single or
double quotes have been removed by the time TEXT makes it
here, and we don't want to remove backslashes inside
quoted strings. */
qc = rl_dispatching ? rl_completion_quote_character : 0;
#endif
dfn = (*rl_filename_dequoting_function) ((char *)text, qc);
dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
}
else
dfn = savestring (text);
@@ -1164,7 +1165,11 @@ command_line_to_word_list (line, llen, sentinel, nwp, cwp)
WORD_LIST *ret;
char *delims;
#if 0
delims = "()<>;&| \t\n"; /* shell metacharacters break words */
#else
delims = rl_completer_word_break_characters;
#endif
ret = split_at_delims (line, llen, delims, sentinel, nwp, cwp);
return (ret);
}
@@ -1355,6 +1360,33 @@ gen_compspec_completions (cs, cmd, word, start, end)
return (ret);
}
void
pcomp_set_readline_variables (flags, nval)
int flags, nval;
{
/* If the user specified that the compspec returns filenames, make
sure that readline knows it. */
if (flags & COPT_FILENAMES)
rl_filename_completion_desired = nval;
/* If the user doesn't want a space appended, tell readline. */
if (flags & COPT_NOSPACE)
rl_completion_suppress_append = nval;
}
/* Set or unset FLAGS in the options word of the current compspec.
SET_OR_UNSET is 1 for setting, 0 for unsetting. */
void
pcomp_set_compspec_options (flags, set_or_unset)
int flags, set_or_unset;
{
if (curcs == 0)
return;
if (set_or_unset)
curcs->options |= flags;
else
curcs->options &= ~flags;
}
/* The driver function for the programmable completion code. Returns a list
of matches for WORD, which is an argument to command CMD. START and END
bound the command currently being completed in rl_line_buffer. */
@@ -1364,7 +1396,7 @@ programmable_completions (cmd, word, start, end, foundp)
const char *word;
int start, end, *foundp;
{
COMPSPEC *cs;
COMPSPEC *cs, *oldcs;
STRINGLIST *ret;
char **rmatches, *t;
@@ -1386,6 +1418,9 @@ programmable_completions (cmd, word, start, end, foundp)
cs = compspec_copy (cs);
oldcs = curcs;
curcs = cs;
/* Signal the caller that we found a COMPSPEC for this command, and pass
back any meta-options associated with the compspec. */
if (foundp)
@@ -1393,6 +1428,7 @@ programmable_completions (cmd, word, start, end, foundp)
ret = gen_compspec_completions (cs, cmd, word, start, end);
curcs = oldcs;
compspec_dispose (cs);
if (ret)
+4
View File
@@ -124,6 +124,8 @@ extern ITEMLIST it_stopped;
extern ITEMLIST it_users;
extern ITEMLIST it_variables;
extern COMPSPEC *curcs;
/* Functions from pcomplib.c */
extern COMPSPEC *compspec_create __P((void));
extern void compspec_dispose __P((COMPSPEC *));
@@ -150,4 +152,6 @@ extern STRINGLIST *completions_to_stringlist __P((char **));
extern STRINGLIST *gen_compspec_completions __P((COMPSPEC *, const char *, const char *, int, int));
extern char **programmable_completions __P((const char *, const char *, int, int, int *));
extern void pcomp_set_readline_variables __P((int, int));
extern void pcomp_set_compspec_options __P((COMPSPEC *, int, int));
#endif /* _PCOMPLETE_H_ */
+157
View File
@@ -0,0 +1,157 @@
/* pcomplete.h - structure definitions and other stuff for programmable
completion. */
/* Copyright (C) 1999-2002 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 2, 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; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_PCOMPLETE_H_)
# define _PCOMPLETE_H_
#include "stdc.h"
#include "hashlib.h"
typedef struct compspec {
int refcount;
unsigned long actions;
unsigned long options;
char *globpat;
char *words;
char *prefix;
char *suffix;
char *funcname;
char *command;
char *filterpat;
} COMPSPEC;
/* Values for COMPSPEC actions. These are things the shell knows how to
build internally. */
#define CA_ALIAS (1<<0)
#define CA_ARRAYVAR (1<<1)
#define CA_BINDING (1<<2)
#define CA_BUILTIN (1<<3)
#define CA_COMMAND (1<<4)
#define CA_DIRECTORY (1<<5)
#define CA_DISABLED (1<<6)
#define CA_ENABLED (1<<7)
#define CA_EXPORT (1<<8)
#define CA_FILE (1<<9)
#define CA_FUNCTION (1<<10)
#define CA_GROUP (1<<11)
#define CA_HELPTOPIC (1<<12)
#define CA_HOSTNAME (1<<13)
#define CA_JOB (1<<14)
#define CA_KEYWORD (1<<15)
#define CA_RUNNING (1<<16)
#define CA_SERVICE (1<<17)
#define CA_SETOPT (1<<18)
#define CA_SHOPT (1<<19)
#define CA_SIGNAL (1<<20)
#define CA_STOPPED (1<<21)
#define CA_USER (1<<22)
#define CA_VARIABLE (1<<23)
/* Values for COMPSPEC options field. */
#define COPT_RESERVED (1<<0) /* reserved for other use */
#define COPT_DEFAULT (1<<1)
#define COPT_FILENAMES (1<<2)
#define COPT_DIRNAMES (1<<3)
#define COPT_NOSPACE (1<<4)
#define COPT_BASHDEFAULT (1<<5)
#define COPT_PLUSDIRS (1<<6)
/* List of items is used by the code that implements the programmable
completions. */
typedef struct _list_of_items {
int flags;
int (*list_getter) __P((struct _list_of_items *)); /* function to call to get the list */
STRINGLIST *slist;
/* These may or may not be used. */
STRINGLIST *genlist; /* for handing to the completion code one item at a time */
int genindex; /* index of item last handed to completion code */
} ITEMLIST;
/* Values for ITEMLIST -> flags */
#define LIST_DYNAMIC 0x001
#define LIST_DIRTY 0x002
#define LIST_INITIALIZED 0x004
#define LIST_MUSTSORT 0x008
#define LIST_DONTFREE 0x010
#define LIST_DONTFREEMEMBERS 0x020
extern HASH_TABLE *prog_completes;
extern int prog_completion_enabled;
/* Not all of these are used yet. */
extern ITEMLIST it_aliases;
extern ITEMLIST it_arrayvars;
extern ITEMLIST it_bindings;
extern ITEMLIST it_builtins;
extern ITEMLIST it_commands;
extern ITEMLIST it_directories;
extern ITEMLIST it_disabled;
extern ITEMLIST it_enabled;
extern ITEMLIST it_exports;
extern ITEMLIST it_files;
extern ITEMLIST it_functions;
extern ITEMLIST it_groups;
extern ITEMLIST it_hostnames;
extern ITEMLIST it_jobs;
extern ITEMLIST it_keywords;
extern ITEMLIST it_running;
extern ITEMLIST it_services;
extern ITEMLIST it_setopts;
extern ITEMLIST it_shopts;
extern ITEMLIST it_signals;
extern ITEMLIST it_stopped;
extern ITEMLIST it_users;
extern ITEMLIST it_variables;
extern COMPSPEC *curcs;
/* Functions from pcomplib.c */
extern COMPSPEC *compspec_create __P((void));
extern void compspec_dispose __P((COMPSPEC *));
extern COMPSPEC *compspec_copy __P((COMPSPEC *));
extern void progcomp_create __P((void));
extern void progcomp_flush __P((void));
extern void progcomp_dispose __P((void));
extern int progcomp_size __P((void));
extern int progcomp_insert __P((char *, COMPSPEC *));
extern int progcomp_remove __P((char *));
extern COMPSPEC *progcomp_search __P((const char *));
extern void progcomp_walk __P((hash_wfunc *));
/* Functions from pcomplete.c */
extern void set_itemlist_dirty __P((ITEMLIST *));
extern STRINGLIST *completions_to_stringlist __P((char **));
extern STRINGLIST *gen_compspec_completions __P((COMPSPEC *, const char *, const char *, int, int));
extern char **programmable_completions __P((const char *, const char *, int, int, int *));
extern void pcomp_set_readline_variables __P((int, int));
extern void pcomp_set_compspec_options __P((int, int));
#endif /* _PCOMPLETE_H_ */
+1 -1
View File
@@ -58,7 +58,7 @@ LIBS_FOR_BUILD = ${LIBS} # XXX
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
LDFLAGS_FOR_BUILD = $(LDFLAGS)
LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ $(LOCAL_LDFLAGS) $(CFLAGS_FOR_BUILD)
INCLUDES = -I${BUILD_DIR} -I${topdir}
+12
View File
@@ -108,4 +108,16 @@ xx xb xc
echo 44 48 4c
44 48 4c
./history.tests: line 90: fc: no command found
aa
bb
cc
echo cc
echo cc
cc
aa
bb
cc
echo cc
echo cc
cc
1
+11
View File
@@ -92,6 +92,17 @@ r cc
unalias -a
alias
# these two blocks had better both result in the same output
echo aa
echo bb
echo cc
fc -e cat
echo aa
echo bb
echo cc
fc -e cat -1
set +o history
shopt -q -o history
+98
View File
@@ -0,0 +1,98 @@
trap 'rm /tmp/newhistory' 0
# bad options
history -x
# cannot use -r and -w at the same time
history -r -w /dev/null
# bad option
fc -v
unset HISTFILESIZE
# all of these should result in an empty history list
history -c
history -r /dev/null
history -n /dev/null
history -c
HISTFILE=history.list
HISTCONTROL=ignoreboth
HISTIGNORE='&:history*:fc*'
HISTSIZE=32
shopt -s cmdhist
set -o history
history
fc -l
fc -nl
fc -lr
fc -nlr
history -s "echo line for history"
history
history -p '!!'
fc -nl
HISTFILE=/tmp/newhistory
history -a
echo displaying \$HISTFILE after history -a
cat $HISTFILE
history
history -w
cat $HISTFILE
history -s "echo line 2 for history"
history
history -p '!e'
history -p '!!'
# this should show up as one history entry
for x in one two three
do
:
done
history
# just a basic test. a full test suite for history expansion should be
# created
set -H
!!
!e
unset HISTSIZE
unset HISTFILE
fc -l 4
fc -l 4 8
fc -l one=two three=four 502
history 4
shopt -so history
shopt -s expand_aliases
alias r="fc -s"
echo aa ab ac
r a=x
r x=4 b=8
# this had better fail with `no command found'
r cc
unalias -a
alias
set +o history
shopt -q -o history
echo $?