]> git.ipfire.org Git - thirdparty/bash.git/blame - builtins/history.def
Imported from ../bash-2.02.tar.gz.
[thirdparty/bash.git] / builtins / history.def
CommitLineData
726f6388
JA
1This file is history.def, from which is created history.c.
2It implements the builtin "history" in Bash.
3
4Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
8Bash is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 1, or (at your option) any later
11version.
12
13Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with Bash; see the file COPYING. If not, write to the Free Software
20Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21
22$PRODUCES history.c
23
24$BUILTIN history
25$FUNCTION history_builtin
26$DEPENDS_ON HISTORY
ccc6cda3 27$SHORT_DOC history [-c] [n] or history -awrn [filename] or history -ps arg [arg...]
726f6388
JA
28Display the history list with line numbers. Lines listed with
29with a `*' have been modified. Argument of N says to list only
ccc6cda3
JA
30the last N lines. The -c option causes the history list to be
31cleared by deleting all of the entries. The `-w' option writes out the
32current history to the history file; `-r' means to read the file and
33append the contents to the history list instead. `-a' means
726f6388
JA
34to append history lines from this session to the history file.
35Argument `-n' means to read all history lines not already read
ccc6cda3
JA
36from the history file and append them to the history list. If
37FILENAME is given, then that is used as the history file else
38if $HISTFILE has a value, that is used, else ~/.bash_history.
39If the -s option is supplied, the non-option ARGs are appended to
40the history list as a single entry. The -p option means to perform
41history expansion on each ARG and display the result, without storing
42anything in the history list.
726f6388
JA
43$END
44
ccc6cda3
JA
45#include <config.h>
46
726f6388 47#if defined (HISTORY)
d166f048 48#include "../bashtypes.h"
cce855bc
JA
49#ifndef _MINIX
50# include <sys/file.h>
51#endif
726f6388 52#include "../posixstat.h"
ccc6cda3
JA
53#include "../filecntl.h"
54#include <errno.h>
55#include <stdio.h>
56#if defined (HAVE_UNISTD_H)
57# include <unistd.h>
58#endif
59
60#include "../bashansi.h"
61
62#include "../shell.h"
726f6388
JA
63#include "../bashhist.h"
64#include <readline/history.h>
ccc6cda3
JA
65#include "bashgetopt.h"
66#include "common.h"
67
68#if !defined (errno)
69extern int errno;
70#endif
726f6388 71
ccc6cda3
JA
72static void display_history ();
73static void push_history ();
74static int expand_and_print_history ();
726f6388 75
ccc6cda3
JA
76#define AFLAG 0x01
77#define RFLAG 0x02
78#define WFLAG 0x04
79#define NFLAG 0x08
80#define SFLAG 0x10
81#define PFLAG 0x20
82#define CFLAG 0x40
83
84int
726f6388
JA
85history_builtin (list)
86 WORD_LIST *list;
87{
ccc6cda3
JA
88 int flags, opt, result;
89 char *filename;
726f6388 90
ccc6cda3
JA
91 flags = 0;
92 reset_internal_getopt ();
93 while ((opt = internal_getopt (list, "acnpsrw")) != -1)
726f6388 94 {
ccc6cda3 95 switch (opt)
726f6388 96 {
ccc6cda3
JA
97 case 'a':
98 flags |= AFLAG;
726f6388 99 break;
ccc6cda3
JA
100 case 'c':
101 flags |= CFLAG;
102 break;
103 case 'n':
104 flags |= NFLAG;
105 break;
106 case 'r':
107 flags |= RFLAG;
108 break;
109 case 'w':
110 flags |= WFLAG;
111 break;
112 case 's':
113 flags |= SFLAG;
114 break;
115 case 'p':
116#if defined (BANG_HISTORY)
117 flags |= PFLAG;
118#endif
119 break;
120 default:
121 builtin_usage ();
726f6388
JA
122 return (EX_USAGE);
123 }
ccc6cda3
JA
124 }
125 list = loptend;
126
127 opt = flags & (AFLAG|RFLAG|WFLAG|NFLAG);
128 if (opt && opt != AFLAG && opt != RFLAG && opt != WFLAG && opt != NFLAG)
129 {
130 builtin_error ("cannot use more than one of -anrw");
131 return (EXECUTION_FAILURE);
132 }
133
134 /* clear the history, but allow other arguments to add to it again. */
135 if (flags & CFLAG)
136 {
137 clear_history ();
138 if (list == 0)
139 return (EXECUTION_SUCCESS);
726f6388
JA
140 }
141
ccc6cda3
JA
142 if (flags & SFLAG)
143 {
144 if (list)
145 push_history (list);
146 return (EXECUTION_SUCCESS);
147 }
148#if defined (BANG_HISTORY)
149 else if (flags & PFLAG)
150 {
151 if (list)
152 return (expand_and_print_history (list));
153 return (EXECUTION_SUCCESS);
154 }
155#endif
156 else if ((flags & (AFLAG|RFLAG|NFLAG|WFLAG|CFLAG)) == 0)
157 {
158 display_history (list);
159 return (EXECUTION_SUCCESS);
160 }
161
162 filename = list ? list->word->word : get_string_value ("HISTFILE");
163 result = EXECUTION_SUCCESS;
164
165 if (flags & AFLAG) /* Append session's history to file. */
166 result = maybe_append_history (filename);
167 else if (flags & WFLAG) /* Write entire history. */
168 result = write_history (filename);
169 else if (flags & RFLAG) /* Read entire file. */
170 result = read_history (filename);
171 else if (flags & NFLAG) /* Read `new' history from file. */
172 {
173 /* Read all of the lines in the file that we haven't already read. */
174 using_history ();
175 result = read_history_range (filename, history_lines_in_file, -1);
176 using_history ();
177 history_lines_in_file = where_history ();
178 }
179
180 return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
181}
182
183/* Accessors for HIST_ENTRY lists that are called HLIST. */
184#define histline(i) (hlist[(i)]->line)
185#define histdata(i) (hlist[(i)]->data)
186
187static void
188display_history (list)
189 WORD_LIST *list;
190{
191 register int i;
192 int limited, limit;
193 HIST_ENTRY **hlist;
194
726f6388
JA
195 if (list)
196 {
197 limited = 1;
d166f048 198 limit = get_numeric_arg (list, 0);
726f6388 199 }
ccc6cda3
JA
200 else
201 limited = limit = 0;
726f6388
JA
202
203 hlist = history_list ();
204
205 if (hlist)
206 {
ccc6cda3
JA
207 for (i = 0; hlist[i]; i++)
208 ;
726f6388
JA
209
210 if (limit < 0)
211 limit = -limit;
212
ccc6cda3 213 if ((limited == 0) || ((i -= limit) < 0))
726f6388 214 i = 0;
726f6388
JA
215
216 while (hlist[i])
217 {
218 QUIT;
219 printf ("%5d%c %s\n", i + history_base,
ccc6cda3
JA
220 histdata(i) ? '*' : ' ',
221 histline(i));
726f6388
JA
222 i++;
223 }
224 }
726f6388 225}
ccc6cda3
JA
226
227static int
228delete_last_history ()
229{
230 register int i;
231 HIST_ENTRY **hlist, *histent, *discard;
232
233 hlist = history_list ();
234 if (hlist == NULL)
235 return 0;
236
237 for (i = 0; hlist[i]; i++)
238 ;
239 i--;
240
241 /* History_get () takes a parameter that must be offset by history_base. */
242 histent = history_get (history_base + i); /* Don't free this */
243 if (histent == NULL)
244 return 0;
245
246 discard = remove_history (i);
247 if (discard)
248 {
249 if (discard->line)
250 free (discard->line);
251 free ((char *) discard);
252 }
253 return (1);
254}
255
256/* Remove the last entry in the history list and add each argument in
257 LIST to the history. */
258static void
259push_history (list)
260 WORD_LIST *list;
261{
262 char *s;
263
d166f048 264 if (hist_last_line_added && delete_last_history () == 0)
ccc6cda3
JA
265 return;
266 s = string_list (list);
267 maybe_add_history (s); /* Obeys HISTCONTROL setting. */
268 free (s);
269}
270
271#if defined (BANG_HISTORY)
272static int
273expand_and_print_history (list)
274 WORD_LIST *list;
275{
276 char *s;
277 int r, result;
278
d166f048 279 if (hist_last_line_added && delete_last_history () == 0)
ccc6cda3
JA
280 return EXECUTION_FAILURE;
281 result = EXECUTION_SUCCESS;
282 while (list)
283 {
284 r = history_expand (list->word->word, &s);
285 if (r < 0)
286 {
287 builtin_error ("%s: history expansion failed", list->word->word);
288 result = EXECUTION_FAILURE;
289 }
290 else
291 {
292 fputs (s, stdout);
293 putchar ('\n');
294 }
295 FREE (s);
296 list = list->next;
297 }
298 fflush (stdout);
299 return result;
300}
301#endif /* BANG_HISTORY */
726f6388 302#endif /* HISTORY */