1 This file is history.def, from which is created history.c.
2 It implements the builtin "history" in Bash.
4 Copyright (C) 1987-2002 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
8 Bash is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING. If not, write to the Free Software
20 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
25 $FUNCTION history_builtin
27 $SHORT_DOC history [-c] [-d offset] [n] or history -awrn [filename] or history -ps arg [arg...]
28 Display the history list with line numbers. Lines listed with
29 with a `*' have been modified. Argument of N says to list only
30 the last N lines. The `-c' option causes the history list to be
31 cleared by deleting all of the entries. The `-d' option deletes
32 the history entry at offset OFFSET. The `-w' option writes out the
33 current history to the history file; `-r' means to read the file and
34 append the contents to the history list instead. `-a' means
35 to append history lines from this session to the history file.
36 Argument `-n' means to read all history lines not already read
37 from the history file and append them to the history list. If
38 FILENAME is given, then that is used as the history file else
39 if $HISTFILE has a value, that is used, else ~/.bash_history.
40 If the -s option is supplied, the non-option ARGs are appended to
41 the history list as a single entry. The -p option means to perform
42 history expansion on each ARG and display the result, without storing
43 anything in the history list.
49 #include "../bashtypes.h"
51 # include <sys/file.h>
53 #include "posixstat.h"
57 #if defined (HAVE_UNISTD_H)
61 #include "../bashansi.h"
64 #include "../bashhist.h"
65 #include <readline/history.h>
66 #include "bashgetopt.h"
73 extern int current_command_line_count;
75 static void display_history __P((WORD_LIST *));
76 static int delete_histent __P((int));
77 static int delete_last_history __P((void));
78 static void push_history __P((WORD_LIST *));
79 static int expand_and_print_history __P((WORD_LIST *));
91 history_builtin (list)
94 int flags, opt, result, old_history_lines;
95 char *filename, *delete_arg;
96 intmax_t delete_offset;
99 reset_internal_getopt ();
100 while ((opt = internal_getopt (list, "acd:npsrw")) != -1)
124 delete_arg = list_optarg;
127 #if defined (BANG_HISTORY)
138 opt = flags & (AFLAG|RFLAG|WFLAG|NFLAG);
139 if (opt && opt != AFLAG && opt != RFLAG && opt != WFLAG && opt != NFLAG)
141 builtin_error ("cannot use more than one of -anrw");
142 return (EXECUTION_FAILURE);
145 /* clear the history, but allow other arguments to add to it again. */
150 return (EXECUTION_SUCCESS);
157 return (EXECUTION_SUCCESS);
159 #if defined (BANG_HISTORY)
160 else if (flags & PFLAG)
163 return (expand_and_print_history (list));
164 return (EXECUTION_SUCCESS);
167 else if (flags & DFLAG)
169 if ((legal_number (delete_arg, &delete_offset) == 0)
170 || (delete_offset < history_base)
171 || (delete_offset > (history_base + history_length)))
173 sh_erange (delete_arg, "history position");
174 return (EXECUTION_FAILURE);
177 result = delete_histent (opt - history_base);
178 /* Since remove_history changes history_length, this can happen if
179 we delete the last history entry. */
180 if (where_history () > history_length)
181 history_set_pos (history_length);
182 return (result ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
184 else if ((flags & (AFLAG|RFLAG|NFLAG|WFLAG|CFLAG)) == 0)
186 display_history (list);
187 return (EXECUTION_SUCCESS);
190 filename = list ? list->word->word : get_string_value ("HISTFILE");
191 result = EXECUTION_SUCCESS;
193 if (flags & AFLAG) /* Append session's history to file. */
194 result = maybe_append_history (filename);
195 else if (flags & WFLAG) /* Write entire history. */
196 result = write_history (filename);
197 else if (flags & RFLAG) /* Read entire file. */
198 result = read_history (filename);
199 else if (flags & NFLAG) /* Read `new' history from file. */
201 /* Read all of the lines in the file that we haven't already read. */
202 old_history_lines = history_lines_in_file;
204 result = read_history_range (filename, history_lines_in_file, -1);
206 history_lines_in_file = where_history ();
207 history_lines_this_session += history_lines_in_file - old_history_lines;
210 return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
213 /* Accessors for HIST_ENTRY lists that are called HLIST. */
214 #define histline(i) (hlist[(i)]->line)
215 #define histdata(i) (hlist[(i)]->data)
218 display_history (list)
227 limit = get_numeric_arg (list, 0);
234 hlist = history_list ();
238 for (i = 0; hlist[i]; i++)
241 if (0 <= limit && limit < i)
249 printf ("%5d%c %s\n", i + history_base,
250 histdata(i) ? '*' : ' ',
257 /* Delete and free the history list entry at offset I. */
264 discard = remove_history (i);
268 free (discard->line);
269 free ((char *) discard);
275 delete_last_history ()
278 HIST_ENTRY **hlist, *histent;
280 hlist = history_list ();
284 for (i = 0; hlist[i]; i++)
288 /* History_get () takes a parameter that must be offset by history_base. */
289 histent = history_get (history_base + i); /* Don't free this */
293 return (delete_histent (i));
296 /* Remove the last entry in the history list and add each argument in
297 LIST to the history. */
304 /* Delete the last history entry if it was a single entry added to the
305 history list (generally the `history -s' itself), or if `history -s'
306 is being used in a compound command and the compound command was
307 added to the history as a single element (command-oriented history).
308 If you don't want history -s to remove the compound command from the
309 history, change #if 0 to #if 1 below. */
311 if (hist_last_line_added && delete_last_history () == 0)
313 if ((hist_last_line_added || (current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history))
314 && delete_last_history () == 0)
318 s = string_list (list);
319 /* Call check_add_history with FORCE set to 1 to skip the check against
320 current_command_line_count. If history -s is used in a compound
321 command, the above code will delete the compound command's history
322 entry and this call will add the line to the history as a separate
323 entry. Without FORCE=1, if current_command_line_count were > 1, the
324 line would be appended to the entry before the just-deleted entry. */
325 check_add_history (s, 1); /* obeys HISTCONTROL, HISTIGNORE */
329 #if defined (BANG_HISTORY)
331 expand_and_print_history (list)
337 if (hist_last_line_added && delete_last_history () == 0)
338 return EXECUTION_FAILURE;
339 result = EXECUTION_SUCCESS;
342 r = history_expand (list->word->word, &s);
345 builtin_error ("%s: history expansion failed", list->word->word);
346 result = EXECUTION_FAILURE;
359 #endif /* BANG_HISTORY */