mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 07:43:07 +02:00
commit bash-20080313 snapshot
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+10
-3
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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 **));
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -142,6 +142,7 @@ rl_signal_handler (sig)
|
||||
switch (sig)
|
||||
{
|
||||
case SIGINT:
|
||||
_rl_reset_completion_state ();
|
||||
rl_free_line_state ();
|
||||
/* FALLTHROUGH */
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 $?
|
||||
Reference in New Issue
Block a user