mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-11 20:50:42 +02:00
commit bash-20080522 snapshot
This commit is contained in:
@@ -31,6 +31,8 @@
|
||||
#define SEVAL_NOHIST 0x004
|
||||
#define SEVAL_NOFREE 0x008
|
||||
#define SEVAL_RESETLINE 0x010
|
||||
#define SEVAL_PARSEONLY 0x020
|
||||
#define SEVAL_NOLONGJMP 0x040
|
||||
|
||||
/* Flags for describe_command, shared between type.def and command.def */
|
||||
#define CDESC_ALL 0x001 /* type -a */
|
||||
|
||||
@@ -142,6 +142,7 @@ extern int describe_command __P((char *, int));
|
||||
|
||||
/* Functions from setattr.def */
|
||||
extern int set_or_show_attributes __P((WORD_LIST *, int, int));
|
||||
extern int show_all_var_attributes __P((int, int));
|
||||
extern int show_var_attributes __P((SHELL_VAR *, int, int));
|
||||
extern int show_name_attributes __P((char *, int));
|
||||
extern void set_var_attribute __P((char *, int, int));
|
||||
|
||||
+172
-53
@@ -1,6 +1,6 @@
|
||||
/* Evaluate a string as one or more shell commands.
|
||||
|
||||
Copyright (C) 1996-2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2008 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include "../redir.h"
|
||||
#include "../trap.h"
|
||||
|
||||
#include <y.tab.h>
|
||||
|
||||
#if defined (HISTORY)
|
||||
# include "../bashhist.h"
|
||||
#endif
|
||||
@@ -58,6 +60,7 @@ extern int errno;
|
||||
|
||||
extern int indirection_level, subshell_environment;
|
||||
extern int line_number;
|
||||
extern int current_token, shell_eof_token;
|
||||
extern int last_command_exit_value;
|
||||
extern int running_trap;
|
||||
extern int loop_level;
|
||||
@@ -67,6 +70,17 @@ int parse_and_execute_level = 0;
|
||||
|
||||
static int cat_file __P((REDIRECT *));
|
||||
|
||||
#define PE_TAG "parse_and_execute top"
|
||||
#define PS_TAG "parse_string top"
|
||||
|
||||
#if defined (HISTORY)
|
||||
static void
|
||||
set_history_remembering ()
|
||||
{
|
||||
remember_on_history = enable_history_list;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* How to force parse_and_execute () to clean up after itself. */
|
||||
void
|
||||
parse_and_execute_cleanup ()
|
||||
@@ -76,16 +90,59 @@ parse_and_execute_cleanup ()
|
||||
run_trap_cleanup (running_trap - 1);
|
||||
unfreeze_jobs_list ();
|
||||
}
|
||||
run_unwind_frame ("parse_and_execute_top");
|
||||
run_unwind_frame (PE_TAG);
|
||||
}
|
||||
|
||||
#if defined (HISTORY)
|
||||
static void
|
||||
set_history_remembering ()
|
||||
parse_prologue (string, flags, tag)
|
||||
char *string;
|
||||
int flags;
|
||||
char *tag;
|
||||
{
|
||||
remember_on_history = enable_history_list;
|
||||
char *orig_string;
|
||||
int x;
|
||||
|
||||
orig_string = string;
|
||||
/* Unwind protect this invocation of parse_and_execute (). */
|
||||
begin_unwind_frame (tag);
|
||||
unwind_protect_int (parse_and_execute_level);
|
||||
unwind_protect_jmp_buf (top_level);
|
||||
unwind_protect_int (indirection_level);
|
||||
unwind_protect_int (line_number);
|
||||
unwind_protect_int (loop_level);
|
||||
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
|
||||
unwind_protect_int (interactive);
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (parse_and_execute_level == 0)
|
||||
add_unwind_protect (set_history_remembering, (char *)NULL);
|
||||
else
|
||||
unwind_protect_int (remember_on_history); /* can be used in scripts */
|
||||
# if defined (BANG_HISTORY)
|
||||
if (interactive_shell)
|
||||
unwind_protect_int (history_expansion_inhibited);
|
||||
# endif /* BANG_HISTORY */
|
||||
#endif /* HISTORY */
|
||||
|
||||
if (interactive_shell)
|
||||
{
|
||||
x = get_current_prompt_level ();
|
||||
add_unwind_protect (set_current_prompt_level, x);
|
||||
}
|
||||
|
||||
add_unwind_protect (pop_stream, (char *)NULL);
|
||||
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
|
||||
add_unwind_protect (xfree, orig_string);
|
||||
end_unwind_frame ();
|
||||
|
||||
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
|
||||
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (flags & SEVAL_NOHIST)
|
||||
bash_history_disable ();
|
||||
#endif /* HISTORY */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Parse and execute the commands in STRING. Returns whatever
|
||||
execute_command () returns. This frees STRING. FLAGS is a
|
||||
@@ -104,50 +161,16 @@ parse_and_execute (string, from_file, flags)
|
||||
const char *from_file;
|
||||
int flags;
|
||||
{
|
||||
int code, x, lreset;
|
||||
int code, lreset;
|
||||
volatile int should_jump_to_top_level, last_result;
|
||||
char *orig_string;
|
||||
COMMAND *volatile command;
|
||||
|
||||
orig_string = string;
|
||||
/* Unwind protect this invocation of parse_and_execute (). */
|
||||
begin_unwind_frame ("parse_and_execute_top");
|
||||
unwind_protect_int (parse_and_execute_level);
|
||||
unwind_protect_jmp_buf (top_level);
|
||||
unwind_protect_int (indirection_level);
|
||||
unwind_protect_int (line_number);
|
||||
unwind_protect_int (loop_level);
|
||||
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
|
||||
unwind_protect_int (interactive);
|
||||
|
||||
lreset = flags & SEVAL_RESETLINE;
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (parse_and_execute_level == 0)
|
||||
add_unwind_protect (set_history_remembering, (char *)NULL);
|
||||
else
|
||||
unwind_protect_int (remember_on_history);
|
||||
# if defined (BANG_HISTORY)
|
||||
if (interactive_shell)
|
||||
{
|
||||
unwind_protect_int (history_expansion_inhibited);
|
||||
}
|
||||
# endif /* BANG_HISTORY */
|
||||
#endif /* HISTORY */
|
||||
|
||||
if (interactive_shell)
|
||||
{
|
||||
x = get_current_prompt_level ();
|
||||
add_unwind_protect (set_current_prompt_level, x);
|
||||
}
|
||||
|
||||
add_unwind_protect (pop_stream, (char *)NULL);
|
||||
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
|
||||
add_unwind_protect (xfree, orig_string);
|
||||
end_unwind_frame ();
|
||||
parse_prologue (string, flags, PE_TAG);
|
||||
|
||||
parse_and_execute_level++;
|
||||
|
||||
lreset = flags & SEVAL_RESETLINE;
|
||||
|
||||
/* Reset the line number if the caller wants us to. If we don't reset the
|
||||
line number, we have to subtract one, because we will add one just
|
||||
before executing the next command (resetting the line number sets it to
|
||||
@@ -157,13 +180,6 @@ parse_and_execute (string, from_file, flags)
|
||||
line_number--;
|
||||
|
||||
indirection_level++;
|
||||
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
|
||||
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (flags & SEVAL_NOHIST)
|
||||
bash_history_disable ();
|
||||
#endif /* HISTORY */
|
||||
|
||||
code = should_jump_to_top_level = 0;
|
||||
last_result = EXECUTION_SUCCESS;
|
||||
@@ -224,7 +240,7 @@ parse_and_execute (string, from_file, flags)
|
||||
|
||||
if (parse_command () == 0)
|
||||
{
|
||||
if (interactive_shell == 0 && read_but_dont_execute)
|
||||
if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
|
||||
{
|
||||
last_result = EXECUTION_SUCCESS;
|
||||
dispose_command (global_command);
|
||||
@@ -303,7 +319,7 @@ parse_and_execute (string, from_file, flags)
|
||||
|
||||
out:
|
||||
|
||||
run_unwind_frame ("parse_and_execute_top");
|
||||
run_unwind_frame (PE_TAG);
|
||||
|
||||
if (interrupt_state && parse_and_execute_level == 0)
|
||||
{
|
||||
@@ -320,6 +336,109 @@ parse_and_execute (string, from_file, flags)
|
||||
return (last_result);
|
||||
}
|
||||
|
||||
/* Parse a command contained in STRING according to FLAGS and return the
|
||||
number of characters consumed from the string. If non-NULL, set *ENDP
|
||||
to the position in the string where the parse ended. Used to validate
|
||||
command substitutions during parsing to obey Posix rules about finding
|
||||
the end of the command and balancing parens. */
|
||||
int
|
||||
parse_string (string, from_file, flags, endp)
|
||||
char *string;
|
||||
const char *from_file;
|
||||
int flags;
|
||||
char **endp;
|
||||
{
|
||||
int code, nc;
|
||||
volatile int should_jump_to_top_level;
|
||||
COMMAND *volatile command, *oglobal;
|
||||
char *ostring;
|
||||
|
||||
parse_prologue (string, flags, PS_TAG);
|
||||
|
||||
/* Reset the line number if the caller wants us to. If we don't reset the
|
||||
line number, we have to subtract one, because we will add one just
|
||||
before executing the next command (resetting the line number sets it to
|
||||
0; the first line number is 1). */
|
||||
push_stream (0);
|
||||
|
||||
code = should_jump_to_top_level = 0;
|
||||
oglobal = global_command;
|
||||
|
||||
with_input_from_string (string, from_file);
|
||||
while (*(bash_input.location.string))
|
||||
{
|
||||
command = (COMMAND *)NULL;
|
||||
|
||||
#if 0
|
||||
if (interrupt_state)
|
||||
break;
|
||||
#endif
|
||||
|
||||
/* Provide a location for functions which `longjmp (top_level)' to
|
||||
jump to. */
|
||||
code = setjmp (top_level);
|
||||
|
||||
if (code)
|
||||
{
|
||||
#if defined (DEBUG)
|
||||
itrace("parse_string: longjmp executed: code = %d", code);
|
||||
#endif
|
||||
should_jump_to_top_level = 0;
|
||||
switch (code)
|
||||
{
|
||||
case FORCE_EOF:
|
||||
case ERREXIT:
|
||||
case EXITPROG:
|
||||
case DISCARD: /* XXX */
|
||||
if (command)
|
||||
dispose_command (command);
|
||||
/* Remember to call longjmp (top_level) after the old
|
||||
value for it is restored. */
|
||||
should_jump_to_top_level = 1;
|
||||
goto out;
|
||||
|
||||
default:
|
||||
command_error ("parse_string", CMDERR_BADJUMP, code, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (parse_command () == 0)
|
||||
{
|
||||
dispose_command (global_command);
|
||||
global_command = (COMMAND *)NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((flags & SEVAL_NOLONGJMP) == 0)
|
||||
{
|
||||
should_jump_to_top_level = 1;
|
||||
code = DISCARD;
|
||||
}
|
||||
else
|
||||
reset_parser (); /* XXX - sets token_to_read */
|
||||
break;
|
||||
}
|
||||
|
||||
if (current_token == yacc_EOF || current_token == shell_eof_token)
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
global_command = oglobal;
|
||||
nc = bash_input.location.string - ostring;
|
||||
if (endp)
|
||||
*endp = bash_input.location.string;
|
||||
|
||||
run_unwind_frame (PS_TAG);
|
||||
|
||||
if (should_jump_to_top_level)
|
||||
jump_to_top_level (code);
|
||||
|
||||
return (nc);
|
||||
}
|
||||
|
||||
/* Handle a $( < file ) command substitution. This expands the filename,
|
||||
returning errors as appropriate, then just cats the file to the standard
|
||||
output. */
|
||||
|
||||
+69
-48
@@ -1,6 +1,6 @@
|
||||
/* Evaluate a string as one or more shell commands.
|
||||
|
||||
Copyright (C) 1996-2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996-2008 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include "../redir.h"
|
||||
#include "../trap.h"
|
||||
|
||||
#include <y.tab.h>
|
||||
|
||||
#if defined (HISTORY)
|
||||
# include "../bashhist.h"
|
||||
#endif
|
||||
@@ -58,6 +60,7 @@ extern int errno;
|
||||
|
||||
extern int indirection_level, subshell_environment;
|
||||
extern int line_number;
|
||||
extern int current_token, shell_eof_token;
|
||||
extern int last_command_exit_value;
|
||||
extern int running_trap;
|
||||
extern int loop_level;
|
||||
@@ -67,6 +70,17 @@ int parse_and_execute_level = 0;
|
||||
|
||||
static int cat_file __P((REDIRECT *));
|
||||
|
||||
#define PE_TAG "parse_and_execute top"
|
||||
#define PS_TAG "parse_string top"
|
||||
|
||||
#if defined (HISTORY)
|
||||
static void
|
||||
set_history_remembering ()
|
||||
{
|
||||
remember_on_history = enable_history_list;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* How to force parse_and_execute () to clean up after itself. */
|
||||
void
|
||||
parse_and_execute_cleanup ()
|
||||
@@ -76,13 +90,58 @@ parse_and_execute_cleanup ()
|
||||
run_trap_cleanup (running_trap - 1);
|
||||
unfreeze_jobs_list ();
|
||||
}
|
||||
run_unwind_frame ("parse_and_execute_top");
|
||||
run_unwind_frame (PE_TAG);
|
||||
}
|
||||
|
||||
static void
|
||||
set_history_remembering ()
|
||||
parse_prologue (string, flags, tag)
|
||||
char *string;
|
||||
int flags;
|
||||
char *tag;
|
||||
{
|
||||
remember_on_history = enable_history_list;
|
||||
char *orig_string;
|
||||
int x;
|
||||
|
||||
orig_string = string;
|
||||
/* Unwind protect this invocation of parse_and_execute (). */
|
||||
begin_unwind_frame (tag);
|
||||
unwind_protect_int (parse_and_execute_level);
|
||||
unwind_protect_jmp_buf (top_level);
|
||||
unwind_protect_int (indirection_level);
|
||||
unwind_protect_int (line_number);
|
||||
unwind_protect_int (loop_level);
|
||||
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
|
||||
unwind_protect_int (interactive);
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (parse_and_execute_level == 0)
|
||||
add_unwind_protect (set_history_remembering, (char *)NULL);
|
||||
else
|
||||
unwind_protect_int (remember_on_history); /* can be used in scripts */
|
||||
# if defined (BANG_HISTORY)
|
||||
if (interactive_shell)
|
||||
unwind_protect_int (history_expansion_inhibited);
|
||||
# endif /* BANG_HISTORY */
|
||||
#endif /* HISTORY */
|
||||
|
||||
if (interactive_shell)
|
||||
{
|
||||
x = get_current_prompt_level ();
|
||||
add_unwind_protect (set_current_prompt_level, x);
|
||||
}
|
||||
|
||||
add_unwind_protect (pop_stream, (char *)NULL);
|
||||
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
|
||||
add_unwind_protect (xfree, orig_string);
|
||||
end_unwind_frame ();
|
||||
|
||||
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
|
||||
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (flags & SEVAL_NOHIST)
|
||||
bash_history_disable ();
|
||||
#endif /* HISTORY */
|
||||
}
|
||||
|
||||
/* Parse and execute the commands in STRING. Returns whatever
|
||||
@@ -102,47 +161,16 @@ parse_and_execute (string, from_file, flags)
|
||||
const char *from_file;
|
||||
int flags;
|
||||
{
|
||||
int code, x, lreset;
|
||||
int code, lreset;
|
||||
volatile int should_jump_to_top_level, last_result;
|
||||
char *orig_string;
|
||||
COMMAND *volatile command;
|
||||
|
||||
orig_string = string;
|
||||
/* Unwind protect this invocation of parse_and_execute (). */
|
||||
begin_unwind_frame ("parse_and_execute_top");
|
||||
unwind_protect_int (parse_and_execute_level);
|
||||
unwind_protect_jmp_buf (top_level);
|
||||
unwind_protect_int (indirection_level);
|
||||
unwind_protect_int (line_number);
|
||||
unwind_protect_int (loop_level);
|
||||
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
|
||||
unwind_protect_int (interactive);
|
||||
|
||||
lreset = flags & SEVAL_RESETLINE;
|
||||
|
||||
#if defined (HISTORY)
|
||||
add_unwind_protect (set_history_remembering, (char *)NULL);
|
||||
# if defined (BANG_HISTORY)
|
||||
if (interactive_shell)
|
||||
{
|
||||
unwind_protect_int (history_expansion_inhibited);
|
||||
}
|
||||
# endif /* BANG_HISTORY */
|
||||
#endif /* HISTORY */
|
||||
|
||||
if (interactive_shell)
|
||||
{
|
||||
x = get_current_prompt_level ();
|
||||
add_unwind_protect (set_current_prompt_level, x);
|
||||
}
|
||||
|
||||
add_unwind_protect (pop_stream, (char *)NULL);
|
||||
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
|
||||
add_unwind_protect (xfree, orig_string);
|
||||
end_unwind_frame ();
|
||||
parse_prologue (string, flags, PE_TAG);
|
||||
|
||||
parse_and_execute_level++;
|
||||
|
||||
lreset = flags & SEVAL_RESETLINE;
|
||||
|
||||
/* Reset the line number if the caller wants us to. If we don't reset the
|
||||
line number, we have to subtract one, because we will add one just
|
||||
before executing the next command (resetting the line number sets it to
|
||||
@@ -152,13 +180,6 @@ parse_and_execute (string, from_file, flags)
|
||||
line_number--;
|
||||
|
||||
indirection_level++;
|
||||
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
|
||||
interactive = (flags & SEVAL_NONINT) ? 0 : 1;
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (flags & SEVAL_NOHIST)
|
||||
bash_history_disable ();
|
||||
#endif /* HISTORY */
|
||||
|
||||
code = should_jump_to_top_level = 0;
|
||||
last_result = EXECUTION_SUCCESS;
|
||||
@@ -219,7 +240,7 @@ parse_and_execute (string, from_file, flags)
|
||||
|
||||
if (parse_command () == 0)
|
||||
{
|
||||
if (interactive_shell == 0 && read_but_dont_execute)
|
||||
if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute))
|
||||
{
|
||||
last_result = EXECUTION_SUCCESS;
|
||||
dispose_command (global_command);
|
||||
@@ -298,7 +319,7 @@ parse_and_execute (string, from_file, flags)
|
||||
|
||||
out:
|
||||
|
||||
run_unwind_frame ("parse_and_execute_top");
|
||||
run_unwind_frame (PE_TAG);
|
||||
|
||||
if (interrupt_state && parse_and_execute_level == 0)
|
||||
{
|
||||
|
||||
+2
-3
@@ -93,7 +93,6 @@ extern int posixly_correct;
|
||||
extern int unlink __P((const char *));
|
||||
|
||||
extern FILE *sh_mktmpfp __P((char *, int, char **));
|
||||
extern int delete_last_history __P((void));
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
@@ -326,7 +325,7 @@ fc_builtin (list)
|
||||
entered into the history list." */
|
||||
if (listing == 0 && hist_last_line_added)
|
||||
{
|
||||
delete_last_history ();
|
||||
bash_delete_last_history ();
|
||||
/* If we're editing a single command -- the last command in the
|
||||
history -- and we just removed the dummy command added by
|
||||
edit_and_execute_command (), we need to check whether or not we
|
||||
@@ -625,7 +624,7 @@ fc_replhist (command)
|
||||
|
||||
if (command && *command)
|
||||
{
|
||||
delete_last_history ();
|
||||
bash_delete_last_history ();
|
||||
maybe_add_history (command); /* Obeys HISTCONTROL setting. */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,8 +337,6 @@ fc_builtin (list)
|
||||
last_hist = histbeg = --histend;
|
||||
}
|
||||
|
||||
itrace ("fc: last_hist = %d histbeg = %d histend = %d", last_hist, histbeg, histend);
|
||||
|
||||
/* We print error messages for line specifications out of range. */
|
||||
if ((histbeg < 0) || (histend < 0))
|
||||
{
|
||||
|
||||
+5
-50
@@ -87,11 +87,8 @@ extern int errno;
|
||||
extern int current_command_line_count;
|
||||
extern int force_append_history; /* shopt -s histappend */
|
||||
|
||||
int delete_last_history __P((void));
|
||||
|
||||
static char *histtime __P((HIST_ENTRY *, const char *));
|
||||
static void display_history __P((WORD_LIST *));
|
||||
static int delete_histent __P((int));
|
||||
static void push_history __P((WORD_LIST *));
|
||||
static int expand_and_print_history __P((WORD_LIST *));
|
||||
|
||||
@@ -162,7 +159,7 @@ history_builtin (list)
|
||||
/* clear the history, but allow other arguments to add to it again. */
|
||||
if (flags & CFLAG)
|
||||
{
|
||||
clear_history ();
|
||||
bash_clear_history ();
|
||||
if (list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
@@ -191,7 +188,7 @@ history_builtin (list)
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
opt = delete_offset;
|
||||
result = delete_histent (opt - history_base);
|
||||
result = bash_delete_histent (opt - history_base);
|
||||
/* Since remove_history changes history_length, this can happen if
|
||||
we delete the last history entry. */
|
||||
if (where_history () > history_length)
|
||||
@@ -310,48 +307,6 @@ display_history (list)
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete and free the history list entry at offset I. */
|
||||
static int
|
||||
delete_histent (i)
|
||||
int i;
|
||||
{
|
||||
HIST_ENTRY *discard;
|
||||
|
||||
discard = remove_history (i);
|
||||
if (discard)
|
||||
free_history_entry (discard);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
delete_last_history ()
|
||||
{
|
||||
register int i;
|
||||
HIST_ENTRY **hlist, *histent;
|
||||
int r;
|
||||
|
||||
hlist = history_list ();
|
||||
if (hlist == NULL)
|
||||
return 0;
|
||||
|
||||
for (i = 0; hlist[i]; i++)
|
||||
;
|
||||
i--;
|
||||
|
||||
/* History_get () takes a parameter that must be offset by history_base. */
|
||||
histent = history_get (history_base + i); /* Don't free this */
|
||||
if (histent == NULL)
|
||||
return 0;
|
||||
|
||||
r = delete_histent (i);
|
||||
|
||||
if (where_history () > history_length)
|
||||
history_set_pos (history_length);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Remove the last entry in the history list and add each argument in
|
||||
LIST to the history. */
|
||||
static void
|
||||
@@ -367,12 +322,12 @@ push_history (list)
|
||||
If you don't want history -s to remove the compound command from the
|
||||
history, change #if 0 to #if 1 below. */
|
||||
#if 0
|
||||
if (hist_last_line_pushed == 0 && hist_last_line_added && delete_last_history () == 0)
|
||||
if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0)
|
||||
#else
|
||||
if (hist_last_line_pushed == 0 &&
|
||||
(hist_last_line_added ||
|
||||
(current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history))
|
||||
&& delete_last_history () == 0)
|
||||
&& bash_delete_last_history () == 0)
|
||||
#endif
|
||||
return;
|
||||
|
||||
@@ -397,7 +352,7 @@ expand_and_print_history (list)
|
||||
char *s;
|
||||
int r, result;
|
||||
|
||||
if (hist_last_line_pushed == 0 && hist_last_line_added && delete_last_history () == 0)
|
||||
if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0)
|
||||
return EXECUTION_FAILURE;
|
||||
result = EXECUTION_SUCCESS;
|
||||
while (list)
|
||||
|
||||
+6
-18
@@ -51,6 +51,9 @@ if $HISTFILE has a value, that is used, else ~/.bash_history.
|
||||
If the $HISTTIMEFORMAT variable is set and not null, its value is used
|
||||
as a format string for strftime(3) to print the time stamp associated
|
||||
with each displayed history entry. No time stamps are printed otherwise.
|
||||
|
||||
Exit Status:
|
||||
Returns success unless an invalid option is given or an error occurs.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
@@ -88,7 +91,6 @@ int delete_last_history __P((void));
|
||||
|
||||
static char *histtime __P((HIST_ENTRY *, const char *));
|
||||
static void display_history __P((WORD_LIST *));
|
||||
static int delete_histent __P((int));
|
||||
static void push_history __P((WORD_LIST *));
|
||||
static int expand_and_print_history __P((WORD_LIST *));
|
||||
|
||||
@@ -159,7 +161,7 @@ history_builtin (list)
|
||||
/* clear the history, but allow other arguments to add to it again. */
|
||||
if (flags & CFLAG)
|
||||
{
|
||||
clear_history ();
|
||||
bash_clear_history ();
|
||||
if (list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
@@ -188,7 +190,7 @@ history_builtin (list)
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
opt = delete_offset;
|
||||
result = delete_histent (opt - history_base);
|
||||
result = bash_delete_histent (opt - history_base);
|
||||
/* Since remove_history changes history_length, this can happen if
|
||||
we delete the last history entry. */
|
||||
if (where_history () > history_length)
|
||||
@@ -307,20 +309,6 @@ display_history (list)
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete and free the history list entry at offset I. */
|
||||
static int
|
||||
delete_histent (i)
|
||||
int i;
|
||||
{
|
||||
HIST_ENTRY *discard;
|
||||
|
||||
discard = remove_history (i);
|
||||
if (discard)
|
||||
free_history_entry (discard);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
delete_last_history ()
|
||||
{
|
||||
@@ -341,7 +329,7 @@ delete_last_history ()
|
||||
if (histent == NULL)
|
||||
return 0;
|
||||
|
||||
r = delete_histent (i);
|
||||
r = bash_delete_histent (i);
|
||||
|
||||
if (where_history () > history_length)
|
||||
history_set_pos (history_length);
|
||||
|
||||
Reference in New Issue
Block a user