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)
27 # include <sys/types.h>
32 #include "bashtypes.h"
36 #include "posixstat.h"
42 #include "parser.h" /* for the struct dstack stuff. */
43 #include "pathexp.h" /* for the struct ignorevar stuff */
44 #include "builtins/common.h"
46 #include <readline/history.h>
47 #include <glob/fnmatch.h>
49 #if defined (READLINE)
50 # include "bashline.h"
57 extern int glob_pattern_p ();
59 static int histignore_item_func ();
61 static struct ignorevar histignore =
67 (Function *)histignore_item_func,
70 #define HIGN_EXPAND 0x01
72 /* Declarations of bash history variables. */
73 /* Non-zero means to remember lines typed to the shell on the history
74 list. This is different than the user-controlled behaviour; this
75 becomes zero when we read lines from a file, for example. */
76 int remember_on_history = 1;
78 /* The number of lines that Bash has added to this history session. */
79 int history_lines_this_session;
81 /* The number of lines that Bash has read from the history file. */
82 int history_lines_in_file;
84 #if defined (BANG_HISTORY)
85 /* Non-zero means do no history expansion on this line, regardless
86 of what history_expansion says. */
87 int history_expansion_inhibited;
90 /* By default, every line is saved in the history individually. I.e.,
96 Each line will be individually saved in the history.
103 If the variable command_oriented_history is set, multiple lines
104 which form one command will be saved as one history entry.
115 The user can then recall the whole command all at once instead
116 of just being able to recall one line at a time.
118 int command_oriented_history = 1;
120 /* Non-zero means to store newlines in the history list when using
121 command_oriented_history rather than trying to use semicolons. */
124 /* Non-zero means to append the history to the history file at shell
125 exit, even if the history has been stifled. */
126 int force_append_history;
128 /* A nit for picking at history saving.
129 Value of 0 means save all lines parsed by the shell on the history.
130 Value of 1 means save all lines that do not start with a space.
131 Value of 2 means save all lines that do not match the last line saved. */
134 /* Set to 1 if the last command was added to the history list successfully
135 as a separate history entry; set to 0 if the line was ignored or added
136 to a previous entry as part of command-oriented-history processing. */
137 int hist_last_line_added;
139 #if defined (READLINE)
140 /* If non-zero, and readline is being used, the user is offered the
141 chance to re-edit a failed history expansion. */
142 int history_reediting;
144 /* If non-zero, and readline is being used, don't directly execute a
145 line with history substitution. Reload it into the editing buffer
146 instead and let the user further edit and confirm with a newline. */
149 #endif /* READLINE */
151 /* Variables declared in other files used here. */
152 extern int interactive;
153 extern int current_command_line_count;
155 extern struct dstack dstack;
157 extern char *extract_colon_unit ();
158 extern char *history_delimiting_chars ();
159 extern void maybe_add_history (); /* forward declaration */
160 extern void bash_add_history (); /* forward declaration */
162 static int history_should_ignore ();
164 /* Is the history expansion starting at string[i] one that should not
167 bash_history_inhibit_expansion (string, i)
171 /* The shell uses ! as a pattern negation character in globbing [...]
172 expressions, so let those pass without expansion. */
173 if (i > 0 && (string[i - 1] == '[') && member (']', string + i + 1))
175 /* The shell uses ! as the indirect expansion character, so let those
176 expansions pass as well. */
177 else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' &&
178 member ('}', string + i + 1))
180 #if defined (EXTENDED_GLOB)
181 else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
189 bash_initialize_history ()
191 history_quotes_inhibit_expansion = 1;
192 history_search_delimiter_chars = ";&()|<>";
193 history_inhibit_expansion_function = bash_history_inhibit_expansion;
197 bash_history_reinit (interact)
200 #if defined (BANG_HISTORY)
201 history_expansion = interact != 0;
202 history_expansion_inhibited = 1;
204 remember_on_history = interact != 0;
205 history_inhibit_expansion_function = bash_history_inhibit_expansion;
209 bash_history_disable ()
211 remember_on_history = 0;
212 #if defined (BANG_HISTORY)
213 history_expansion_inhibited = 1;
218 bash_history_enable ()
220 remember_on_history = 1;
221 #if defined (BANG_HISTORY)
222 history_expansion_inhibited = 0;
224 history_inhibit_expansion_function = bash_history_inhibit_expansion;
225 sv_history_control ("HISTCONTROL");
226 sv_histignore ("HISTIGNORE");
229 /* Load the history list from the history file. */
236 /* Truncate history file for interactive shells which desire it.
237 Note that the history file is automatically truncated to the
238 size of HISTSIZE if the user does not explicitly set the size
240 set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
241 sv_histsize ("HISTFILESIZE");
243 /* Read the history in HISTFILE into the history list. */
244 hf = get_string_value ("HISTFILE");
246 if (hf && *hf && stat (hf, &buf) == 0)
250 history_lines_in_file = where_history ();
254 #ifdef INCLUDE_UNUSED
255 /* Write the existing history out to the history file. */
262 hf = get_string_value ("HISTFILE");
263 if (hf && *hf && stat (hf, &buf) == 0)
265 /* Append only the lines that occurred this session to
269 if (history_lines_this_session < where_history () || force_append_history)
270 append_history (history_lines_this_session, hf);
274 sv_histsize ("HISTFILESIZE");
280 maybe_append_history (filename)
286 result = EXECUTION_SUCCESS;
287 if (history_lines_this_session && (history_lines_this_session < where_history ()))
289 /* If the filename was supplied, then create it if necessary. */
290 if (stat (filename, &buf) == -1 && errno == ENOENT)
292 fd = open (filename, O_WRONLY|O_CREAT, 0600);
295 builtin_error ("%s: cannot create: %s", filename, strerror (errno));
296 return (EXECUTION_FAILURE);
300 result = append_history (history_lines_this_session, filename);
301 history_lines_in_file += history_lines_this_session;
302 history_lines_this_session = 0;
307 /* If this is an interactive shell, then append the lines executed
308 this session to the history file. */
310 maybe_save_shell_history ()
317 if (history_lines_this_session)
319 hf = get_string_value ("HISTFILE");
323 /* If the file doesn't exist, then create it. */
324 if (stat (hf, &buf) == -1)
327 file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
332 /* Now actually append the lines if the history hasn't been
333 stifled. If the history has been stifled, rewrite the
336 if (history_lines_this_session <= where_history () || force_append_history)
338 result = append_history (history_lines_this_session, hf);
339 history_lines_in_file += history_lines_this_session;
343 result = write_history (hf);
344 history_lines_in_file = history_lines_this_session;
346 history_lines_this_session = 0;
348 sv_histsize ("HISTFILESIZE");
354 #if defined (READLINE)
355 /* Tell readline () that we have some text for it to edit. */
360 if (bash_input.type == st_stdin)
363 #endif /* READLINE */
365 /* Return 1 if this line needs history expansion. */
367 history_expansion_p (line)
372 for (s = line; *s; s++)
373 if (*s == history_expansion_char || *s == history_subst_char)
378 /* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then
379 print the results of expanding the line if there were any changes.
380 If there is an error, return NULL, otherwise the expanded line is
381 returned. If ADDIT is non-zero the line is added to the history
382 list after history expansion. ADDIT is just a suggestion;
383 REMEMBER_ON_HISTORY can veto, and does.
384 Right now this does history expansion. */
386 pre_process_line (line, print_changes, addit)
388 int print_changes, addit;
397 # if defined (BANG_HISTORY)
398 /* History expand the line. If this results in no errors, then
399 add that line to the history if ADDIT is non-zero. */
400 if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
402 expanded = history_expand (line, &history_value);
409 internal_error ("%s", history_value);
410 #if defined (READLINE)
411 else if (hist_verify == 0)
415 fprintf (stderr, "%s\n", history_value);
418 /* If there was an error, return NULL. */
419 if (expanded < 0 || expanded == 2) /* 2 == print only */
421 free (history_value);
423 # if defined (READLINE)
424 /* New hack. We can allow the user to edit the
425 failed history expansion. */
426 if (history_reediting && expanded < 0)
428 # endif /* READLINE */
429 return ((char *)NULL);
432 # if defined (READLINE)
433 if (hist_verify && expanded == 1)
435 re_edit (history_value);
436 return ((char *)NULL);
441 /* Let other expansions know that return_value can be free'ed,
442 and that a line has been added to the history list. Note
443 that we only add lines that have something in them. */
445 return_value = history_value;
447 # endif /* BANG_HISTORY */
449 if (addit && remember_on_history && *return_value)
450 maybe_add_history (return_value);
454 return_value = savestring (line);
457 return (return_value);
460 /* Add LINE to the history list depending on the value of HISTORY_CONTROL. */
462 maybe_add_history (line)
468 should_add = hist_last_line_added = 0;
470 /* Don't use the value of history_control to affect the second
471 and subsequent lines of a multi-line command (old code did
472 this only when command_oriented_history is enabled). */
474 if (command_oriented_history && current_command_line_count > 1)
476 if (current_command_line_count > 1)
479 bash_add_history (line);
483 switch (history_control)
495 /* FALLTHROUGH if case == 3 (`ignoreboth') */
498 temp = previous_history ();
500 if (temp == 0 || STREQ (temp->line, line) == 0)
507 if (should_add && history_should_ignore (line) == 0)
508 bash_add_history (line);
511 /* Add a line to the history list.
512 The variable COMMAND_ORIENTED_HISTORY controls the style of history
513 remembering; when non-zero, and LINE is not the first line of a
514 complete parser construct, append LINE to the last history line instead
515 of adding it as a new line. */
517 bash_add_history (line)
520 int add_it, offset, curlen;
521 HIST_ENTRY *current, *old;
522 char *chars_to_add, *new_line;
525 if (command_oriented_history && current_command_line_count > 1)
527 chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
530 current = previous_history ();
534 /* If the previous line ended with an escaped newline (escaped
535 with backslash, but otherwise unquoted), then remove the quoted
536 newline, since that is what happens when the line is parsed. */
537 curlen = strlen (current->line);
539 if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
540 current->line[curlen - 2] != '\\')
542 current->line[curlen - 1] = '\0';
547 new_line = (char *) xmalloc (1
550 + strlen (chars_to_add));
551 sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
552 offset = where_history ();
553 old = replace_history_entry (offset, new_line, current->data);
567 hist_last_line_added = 1;
569 history_lines_this_session++;
578 return (get_string_value ("HISTSIZE") ? history_base + where_history () : 1);
587 for (p = s; p && *p; p++)
598 histignore_item_func (ign)
601 if (should_expand (ign->val))
602 ign->flags |= HIGN_EXPAND;
607 setup_history_ignore (varname)
610 setup_ignore_patterns (&histignore);
614 last_history_entry ()
619 he = previous_history ();
629 he = last_history_entry ();
631 return ((char *)NULL);
636 expand_histignore_pattern (pat)
640 char *ret, *p, *r, *t;
641 int len, rlen, ind, tlen;
643 phe = last_history_entry ();
645 if (phe == (HIST_ENTRY *)0)
646 return (savestring (pat));
648 len = strlen (phe->line);
649 rlen = len + strlen (pat) + 2;
650 ret = xmalloc (rlen);
652 for (p = pat, r = ret; p && *p; )
657 if (glob_pattern_p (phe->line) || strchr (phe->line, '\\'))
659 t = quote_globbing_chars (phe->line);
661 RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
662 r = ret + ind; /* in case reallocated */
669 tlen = strlen (phe->line);
670 RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
671 r = ret + ind; /* in case reallocated */
672 strcpy (r, phe->line);
679 if (*p == '\\' && p[1] == '&')
688 /* Return 1 if we should not put LINE into the history according to the
689 patterns in HISTIGNORE. */
691 history_should_ignore (line)
694 register int i, match;
697 if (histignore.num_ignores == 0)
700 for (i = match = 0; i < histignore.num_ignores; i++)
702 if (histignore.ignores[i].flags & HIGN_EXPAND)
703 npat = expand_histignore_pattern (histignore.ignores[i].val);
705 npat = histignore.ignores[i].val;
707 match = fnmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH;
709 if (histignore.ignores[i].flags & HIGN_EXPAND)