1 /* bashhist.c -- bash interface to the GNU history library. */
3 /* Copyright (C) 1993 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
19 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #if defined (HAVE_UNISTD_H)
29 #include "bashtypes.h"
33 #include "posixstat.h"
39 #include "parser.h" /* for the struct dstack stuff. */
40 #include "pathexp.h" /* for the struct ignorevar stuff */
41 #include "builtins/common.h"
43 #include <readline/history.h>
44 #include <glob/fnmatch.h>
46 #if defined (READLINE)
47 # include "bashline.h"
54 extern int glob_pattern_p ();
56 static int histignore_item_func ();
58 static struct ignorevar histignore =
64 (Function *)histignore_item_func,
67 #define HIGN_EXPAND 0x01
69 /* Declarations of bash history variables. */
70 /* Non-zero means to remember lines typed to the shell on the history
71 list. This is different than the user-controlled behaviour; this
72 becomes zero when we read lines from a file, for example. */
73 int remember_on_history = 1;
75 /* The number of lines that Bash has added to this history session. */
76 int history_lines_this_session;
78 /* The number of lines that Bash has read from the history file. */
79 int history_lines_in_file;
81 #if defined (BANG_HISTORY)
82 /* Non-zero means do no history expansion on this line, regardless
83 of what history_expansion says. */
84 int history_expansion_inhibited;
87 /* By default, every line is saved in the history individually. I.e.,
93 Each line will be individually saved in the history.
100 If the variable command_oriented_history is set, multiple lines
101 which form one command will be saved as one history entry.
112 The user can then recall the whole command all at once instead
113 of just being able to recall one line at a time.
115 int command_oriented_history = 1;
117 /* Non-zero means to store newlines in the history list when using
118 command_oriented_history rather than trying to use semicolons. */
121 /* Non-zero means to append the history to the history file at shell
122 exit, even if the history has been stifled. */
123 int force_append_history;
125 /* A nit for picking at history saving.
126 Value of 0 means save all lines parsed by the shell on the history.
127 Value of 1 means save all lines that do not start with a space.
128 Value of 2 means save all lines that do not match the last line saved. */
131 /* Set to 1 if the last command was added to the history list successfully
132 as a separate history entry; set to 0 if the line was ignored or added
133 to a previous entry as part of command-oriented-history processing. */
134 int hist_last_line_added;
136 #if defined (READLINE)
137 /* If non-zero, and readline is being used, the user is offered the
138 chance to re-edit a failed history expansion. */
139 int history_reediting;
141 /* If non-zero, and readline is being used, don't directly execute a
142 line with history substitution. Reload it into the editing buffer
143 instead and let the user further edit and confirm with a newline. */
146 #endif /* READLINE */
148 /* Variables declared in other files used here. */
149 extern int interactive;
150 extern int current_command_line_count;
152 extern struct dstack dstack;
154 extern char *extract_colon_unit ();
155 extern char *history_delimiting_chars ();
156 extern void maybe_add_history (); /* forward declaration */
157 extern void bash_add_history (); /* forward declaration */
159 static int history_should_ignore ();
161 /* Is the history expansion starting at string[i] one that should not
164 bash_history_inhibit_expansion (string, i)
168 /* The shell uses ! as a pattern negation character in globbing [...]
169 expressions, so let those pass without expansion. */
170 if (i > 0 && (string[i - 1] == '[') && member (']', string + i + 1))
172 /* The shell uses ! as the indirect expansion character, so let those
173 expansions pass as well. */
174 else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' &&
175 member ('}', string + i + 1))
182 bash_initialize_history ()
184 history_quotes_inhibit_expansion = 1;
185 history_search_delimiter_chars = ";&()|<>";
186 history_inhibit_expansion_function = bash_history_inhibit_expansion;
190 bash_history_reinit (interact)
193 #if defined (BANG_HISTORY)
194 history_expansion = interact != 0;
195 history_expansion_inhibited = 1;
197 remember_on_history = interact != 0;
198 history_inhibit_expansion_function = bash_history_inhibit_expansion;
202 bash_history_disable ()
204 remember_on_history = 0;
205 #if defined (BANG_HISTORY)
206 history_expansion_inhibited = 1;
211 bash_history_enable ()
213 remember_on_history = 1;
214 #if defined (BANG_HISTORY)
215 history_expansion_inhibited = 0;
217 history_inhibit_expansion_function = bash_history_inhibit_expansion;
218 sv_history_control ("HISTCONTROL");
219 sv_histignore ("HISTIGNORE");
222 /* Load the history list from the history file. */
229 /* Truncate history file for interactive shells which desire it.
230 Note that the history file is automatically truncated to the
231 size of HISTSIZE if the user does not explicitly set the size
233 set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
234 sv_histsize ("HISTFILESIZE");
236 /* Read the history in HISTFILE into the history list. */
237 hf = get_string_value ("HISTFILE");
239 if (hf && *hf && stat (hf, &buf) == 0)
243 history_lines_in_file = where_history ();
247 #ifdef INCLUDE_UNUSED
248 /* Write the existing history out to the history file. */
255 hf = get_string_value ("HISTFILE");
256 if (hf && *hf && stat (hf, &buf) == 0)
258 /* Append only the lines that occurred this session to
262 if (history_lines_this_session < where_history () || force_append_history)
263 append_history (history_lines_this_session, hf);
267 sv_histsize ("HISTFILESIZE");
273 maybe_append_history (filename)
279 result = EXECUTION_SUCCESS;
280 if (history_lines_this_session && (history_lines_this_session < where_history ()))
282 /* If the filename was supplied, then create it if necessary. */
283 if (stat (filename, &buf) == -1 && errno == ENOENT)
285 fd = open (filename, O_WRONLY|O_CREAT, 0666);
288 builtin_error ("%s: cannot create: %s", filename, strerror (errno));
289 return (EXECUTION_FAILURE);
293 result = append_history (history_lines_this_session, filename);
294 history_lines_in_file += history_lines_this_session;
295 history_lines_this_session = 0;
300 /* If this is an interactive shell, then append the lines executed
301 this session to the history file. */
303 maybe_save_shell_history ()
310 if (history_lines_this_session)
312 hf = get_string_value ("HISTFILE");
316 /* If the file doesn't exist, then create it. */
317 if (stat (hf, &buf) == -1)
320 file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0666);
325 /* Now actually append the lines if the history hasn't been
326 stifled. If the history has been stifled, rewrite the
329 if (history_lines_this_session <= where_history () || force_append_history)
331 result = append_history (history_lines_this_session, hf);
332 history_lines_in_file += history_lines_this_session;
336 result = write_history (hf);
337 history_lines_in_file = history_lines_this_session;
339 history_lines_this_session = 0;
341 sv_histsize ("HISTFILESIZE");
347 #if defined (READLINE)
348 /* Tell readline () that we have some text for it to edit. */
353 if (bash_input.type == st_stdin)
356 #endif /* READLINE */
358 /* Return 1 if this line needs history expansion. */
360 history_expansion_p (line)
365 for (s = line; *s; s++)
366 if (*s == history_expansion_char || *s == history_subst_char)
371 /* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then
372 print the results of expanding the line if there were any changes.
373 If there is an error, return NULL, otherwise the expanded line is
374 returned. If ADDIT is non-zero the line is added to the history
375 list after history expansion. ADDIT is just a suggestion;
376 REMEMBER_ON_HISTORY can veto, and does.
377 Right now this does history expansion. */
379 pre_process_line (line, print_changes, addit)
381 int print_changes, addit;
390 # if defined (BANG_HISTORY)
391 /* History expand the line. If this results in no errors, then
392 add that line to the history if ADDIT is non-zero. */
393 if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
395 expanded = history_expand (line, &history_value);
402 internal_error (history_value);
403 #if defined (READLINE)
404 else if (hist_verify == 0)
408 fprintf (stderr, "%s\n", history_value);
411 /* If there was an error, return NULL. */
412 if (expanded < 0 || expanded == 2) /* 2 == print only */
414 free (history_value);
416 # if defined (READLINE)
417 /* New hack. We can allow the user to edit the
418 failed history expansion. */
419 if (history_reediting && expanded < 0)
421 # endif /* READLINE */
422 return ((char *)NULL);
425 # if defined (READLINE)
426 if (hist_verify && expanded == 1)
428 re_edit (history_value);
429 return ((char *)NULL);
434 /* Let other expansions know that return_value can be free'ed,
435 and that a line has been added to the history list. Note
436 that we only add lines that have something in them. */
438 return_value = history_value;
440 # endif /* BANG_HISTORY */
442 if (addit && remember_on_history && *return_value)
443 maybe_add_history (return_value);
447 return_value = savestring (line);
450 return (return_value);
453 /* Add LINE to the history list depending on the value of HISTORY_CONTROL. */
455 maybe_add_history (line)
461 should_add = hist_last_line_added = 0;
463 /* Don't use the value of history_control to affect the second
464 and subsequent lines of a multi-line command when
465 command_oriented_history is enabled. */
466 if (command_oriented_history && current_command_line_count > 1)
468 bash_add_history (line);
472 switch (history_control)
484 /* FALLTHROUGH if case == 3 (`ignoreboth') */
487 temp = previous_history ();
489 if (temp == 0 || STREQ (temp->line, line) == 0)
496 if (should_add && history_should_ignore (line) == 0)
497 bash_add_history (line);
500 /* Add a line to the history list.
501 The variable COMMAND_ORIENTED_HISTORY controls the style of history
502 remembering; when non-zero, and LINE is not the first line of a
503 complete parser construct, append LINE to the last history line instead
504 of adding it as a new line. */
506 bash_add_history (line)
509 int add_it, offset, curlen;
510 HIST_ENTRY *current, *old;
511 char *chars_to_add, *new_line;
514 if (command_oriented_history && current_command_line_count > 1)
516 chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
519 current = previous_history ();
523 /* If the previous line ended with an escaped newline (escaped
524 with backslash, but otherwise unquoted), then remove the quoted
525 newline, since that is what happens when the line is parsed. */
526 curlen = strlen (current->line);
528 if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
529 current->line[curlen - 2] != '\\')
531 current->line[curlen - 1] = '\0';
536 new_line = (char *) xmalloc (1
539 + strlen (chars_to_add));
540 sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
541 offset = where_history ();
542 old = replace_history_entry (offset, new_line, current->data);
556 hist_last_line_added = 1;
558 history_lines_this_session++;
567 return (get_string_value ("HISTSIZE") ? history_base + where_history () : 1);
576 for (p = s; p && *p; p++)
587 histignore_item_func (ign)
590 if (should_expand (ign->val))
591 ign->flags |= HIGN_EXPAND;
596 setup_history_ignore (varname)
599 setup_ignore_patterns (&histignore);
603 last_history_entry ()
608 he = previous_history ();
618 he = last_history_entry ();
620 return ((char *)NULL);
625 expand_histignore_pattern (pat)
629 char *ret, *p, *r, *t;
630 int len, rlen, ind, tlen;
632 phe = last_history_entry ();
634 if (phe == (HIST_ENTRY *)0)
635 return (savestring (pat));
637 len = strlen (phe->line);
638 rlen = len + strlen (pat) + 2;
639 ret = xmalloc (rlen);
641 for (p = pat, r = ret; p && *p; )
646 if (glob_pattern_p (phe->line) || strchr (phe->line, '\\'))
648 t = quote_globbing_chars (phe->line);
650 RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
651 r = ret + ind; /* in case reallocated */
658 tlen = strlen (phe->line);
659 RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
660 r = ret + ind; /* in case reallocated */
661 strcpy (r, phe->line);
668 if (*p == '\\' && p[1] == '&')
677 /* Return 1 if we should not put LINE into the history according to the
678 patterns in HISTIGNORE. */
680 history_should_ignore (line)
683 register int i, match;
686 if (histignore.num_ignores == 0)
689 for (i = match = 0; i < histignore.num_ignores; i++)
691 if (histignore.ignores[i].flags & HIGN_EXPAND)
692 npat = expand_histignore_pattern (histignore.ignores[i].val);
694 npat = histignore.ignores[i].val;
696 match = fnmatch (npat, line, 0) != FNM_NOMATCH;
698 if (histignore.ignores[i].flags & HIGN_EXPAND)