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, 59 Temple Place, Suite 330, Boston, MA 02111 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 "bashhist.h" /* matching prototypes and declarations */
45 #include "builtins/common.h"
47 #include <readline/history.h>
48 #include <glob/glob.h>
49 #include <glob/strmatch.h>
51 #if defined (READLINE)
52 # include "bashline.h"
59 static int histignore_item_func __P((struct ign *));
61 static struct ignorevar histignore =
67 (sh_iv_item_func_t *)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 /* Non-zero means to not save function definitions in the history list. */
152 int dont_save_function_defs;
154 /* Variables declared in other files used here. */
155 extern int current_command_line_count;
157 extern struct dstack dstack;
159 static int bash_history_inhibit_expansion __P((char *, int));
160 #if defined (READLINE)
161 static void re_edit __P((char *));
163 static int history_expansion_p __P((char *));
164 static int shell_comment __P((char *));
165 static int should_expand __P((char *));
166 static HIST_ENTRY *last_history_entry __P((void));
167 static char *expand_histignore_pattern __P((char *));
168 static int history_should_ignore __P((char *));
170 /* Is the history expansion starting at string[i] one that should not
173 bash_history_inhibit_expansion (string, i)
177 /* The shell uses ! as a pattern negation character in globbing [...]
178 expressions, so let those pass without expansion. */
179 if (i > 0 && (string[i - 1] == '[') && member (']', string + i + 1))
181 /* The shell uses ! as the indirect expansion character, so let those
182 expansions pass as well. */
183 else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' &&
184 member ('}', string + i + 1))
186 #if defined (EXTENDED_GLOB)
187 else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
195 bash_initialize_history ()
197 history_quotes_inhibit_expansion = 1;
198 history_search_delimiter_chars = ";&()|<>";
199 history_inhibit_expansion_function = bash_history_inhibit_expansion;
203 bash_history_reinit (interact)
206 #if defined (BANG_HISTORY)
207 history_expansion = interact != 0;
208 history_expansion_inhibited = 1;
210 remember_on_history = interact != 0;
211 history_inhibit_expansion_function = bash_history_inhibit_expansion;
215 bash_history_disable ()
217 remember_on_history = 0;
218 #if defined (BANG_HISTORY)
219 history_expansion_inhibited = 1;
224 bash_history_enable ()
226 remember_on_history = 1;
227 #if defined (BANG_HISTORY)
228 history_expansion_inhibited = 0;
230 history_inhibit_expansion_function = bash_history_inhibit_expansion;
231 sv_history_control ("HISTCONTROL");
232 sv_histignore ("HISTIGNORE");
235 /* Load the history list from the history file. */
242 /* Truncate history file for interactive shells which desire it.
243 Note that the history file is automatically truncated to the
244 size of HISTSIZE if the user does not explicitly set the size
246 set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
247 sv_histsize ("HISTFILESIZE");
249 /* Read the history in HISTFILE into the history list. */
250 hf = get_string_value ("HISTFILE");
252 if (hf && *hf && stat (hf, &buf) == 0)
256 history_lines_in_file = where_history ();
260 #ifdef INCLUDE_UNUSED
261 /* Write the existing history out to the history file. */
268 hf = get_string_value ("HISTFILE");
269 if (hf && *hf && stat (hf, &buf) == 0)
271 /* Append only the lines that occurred this session to
275 if (history_lines_this_session < where_history () || force_append_history)
276 append_history (history_lines_this_session, hf);
280 sv_histsize ("HISTFILESIZE");
286 maybe_append_history (filename)
292 result = EXECUTION_SUCCESS;
293 if (history_lines_this_session && (history_lines_this_session < where_history ()))
295 /* If the filename was supplied, then create it if necessary. */
296 if (stat (filename, &buf) == -1 && errno == ENOENT)
298 fd = open (filename, O_WRONLY|O_CREAT, 0600);
301 builtin_error ("%s: cannot create: %s", filename, strerror (errno));
302 return (EXECUTION_FAILURE);
306 result = append_history (history_lines_this_session, filename);
307 history_lines_in_file += history_lines_this_session;
308 history_lines_this_session = 0;
313 /* If this is an interactive shell, then append the lines executed
314 this session to the history file. */
316 maybe_save_shell_history ()
323 if (history_lines_this_session)
325 hf = get_string_value ("HISTFILE");
329 /* If the file doesn't exist, then create it. */
330 if (stat (hf, &buf) == -1)
333 file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
338 /* Now actually append the lines if the history hasn't been
339 stifled. If the history has been stifled, rewrite the
342 if (history_lines_this_session <= where_history () || force_append_history)
344 result = append_history (history_lines_this_session, hf);
345 history_lines_in_file += history_lines_this_session;
349 result = write_history (hf);
350 history_lines_in_file = history_lines_this_session;
352 history_lines_this_session = 0;
354 sv_histsize ("HISTFILESIZE");
360 #if defined (READLINE)
361 /* Tell readline () that we have some text for it to edit. */
366 if (bash_input.type == st_stdin)
369 #endif /* READLINE */
371 /* Return 1 if this line needs history expansion. */
373 history_expansion_p (line)
378 for (s = line; *s; s++)
379 if (*s == history_expansion_char || *s == history_subst_char)
384 /* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then
385 print the results of expanding the line if there were any changes.
386 If there is an error, return NULL, otherwise the expanded line is
387 returned. If ADDIT is non-zero the line is added to the history
388 list after history expansion. ADDIT is just a suggestion;
389 REMEMBER_ON_HISTORY can veto, and does.
390 Right now this does history expansion. */
392 pre_process_line (line, print_changes, addit)
394 int print_changes, addit;
403 # if defined (BANG_HISTORY)
404 /* History expand the line. If this results in no errors, then
405 add that line to the history if ADDIT is non-zero. */
406 if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
408 expanded = history_expand (line, &history_value);
415 internal_error ("%s", history_value);
416 #if defined (READLINE)
417 else if (hist_verify == 0 || expanded == 2)
421 fprintf (stderr, "%s\n", history_value);
424 /* If there was an error, return NULL. */
425 if (expanded < 0 || expanded == 2) /* 2 == print only */
427 free (history_value);
429 # if defined (READLINE)
430 /* New hack. We can allow the user to edit the
431 failed history expansion. */
432 if (history_reediting && expanded < 0)
434 # endif /* READLINE */
435 return ((char *)NULL);
438 # if defined (READLINE)
439 if (hist_verify && expanded == 1)
441 re_edit (history_value);
442 return ((char *)NULL);
447 /* Let other expansions know that return_value can be free'ed,
448 and that a line has been added to the history list. Note
449 that we only add lines that have something in them. */
451 return_value = history_value;
453 # endif /* BANG_HISTORY */
455 if (addit && remember_on_history && *return_value)
456 maybe_add_history (return_value);
460 return_value = savestring (line);
463 return (return_value);
466 /* Return 1 if the first non-whitespace character in LINE is a `#', indicating
467 * that the line is a shell comment. */
474 for (p = line; p && *p && whitespace (*p); p++)
476 return (p && *p == '#');
479 #ifdef INCLUDE_UNUSED
480 /* Remove shell comments from LINE. A `#' and anything after it is a comment.
481 This isn't really useful yet, since it doesn't handle quoting. */
483 filter_comments (line)
488 for (p = line; p && *p && *p != '#'; p++)
496 /* Add LINE to the history list depending on the value of HISTORY_CONTROL. */
498 maybe_add_history (line)
501 static int first_line_saved = 0;
504 hist_last_line_added = 0;
506 /* Don't use the value of history_control to affect the second
507 and subsequent lines of a multi-line command (old code did
508 this only when command_oriented_history is enabled). */
510 if (command_oriented_history && current_command_line_count > 1)
512 if (current_command_line_count > 1)
515 if (first_line_saved &&
516 (literal_history || dstack.delimiter_depth != 0 || shell_comment (line) == 0))
517 bash_add_history (line);
521 /* This is the first line of a (possible multi-line) command. Note whether
522 or not we should save the first line and remember it. */
523 first_line_saved = 0;
525 switch (history_control)
528 first_line_saved = 1;
532 first_line_saved = 1;
537 /* FALLTHROUGH if case == 3 (`ignoreboth') */
540 temp = previous_history ();
542 if (temp == 0 || STREQ (temp->line, line) == 0)
543 first_line_saved = 1;
549 if (first_line_saved && history_should_ignore (line) == 0)
550 bash_add_history (line);
552 first_line_saved = 0;
555 /* Add a line to the history list.
556 The variable COMMAND_ORIENTED_HISTORY controls the style of history
557 remembering; when non-zero, and LINE is not the first line of a
558 complete parser construct, append LINE to the last history line instead
559 of adding it as a new line. */
561 bash_add_history (line)
564 int add_it, offset, curlen;
565 HIST_ENTRY *current, *old;
566 char *chars_to_add, *new_line;
569 if (command_oriented_history && current_command_line_count > 1)
571 chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
574 current = previous_history ();
578 /* If the previous line ended with an escaped newline (escaped
579 with backslash, but otherwise unquoted), then remove the quoted
580 newline, since that is what happens when the line is parsed. */
581 curlen = strlen (current->line);
583 if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
584 current->line[curlen - 2] != '\\')
586 current->line[curlen - 1] = '\0';
591 new_line = (char *)xmalloc (1
594 + strlen (chars_to_add));
595 sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
596 offset = where_history ();
597 old = replace_history_entry (offset, new_line, current->data);
611 hist_last_line_added = 1;
613 history_lines_this_session++;
622 return (get_string_value ("HISTSIZE") ? history_base + where_history () : 1);
631 for (p = s; p && *p; p++)
642 histignore_item_func (ign)
645 if (should_expand (ign->val))
646 ign->flags |= HIGN_EXPAND;
651 setup_history_ignore (varname)
654 setup_ignore_patterns (&histignore);
658 last_history_entry ()
663 he = previous_history ();
673 he = last_history_entry ();
675 return ((char *)NULL);
680 expand_histignore_pattern (pat)
686 phe = last_history_entry ();
688 if (phe == (HIST_ENTRY *)0)
689 return (savestring (pat));
691 ret = strcreplace (pat, '&', phe->line, 1);
696 /* Return 1 if we should not put LINE into the history according to the
697 patterns in HISTIGNORE. */
699 history_should_ignore (line)
702 register int i, match;
705 if (histignore.num_ignores == 0)
708 for (i = match = 0; i < histignore.num_ignores; i++)
710 if (histignore.ignores[i].flags & HIGN_EXPAND)
711 npat = expand_histignore_pattern (histignore.ignores[i].val);
713 npat = histignore.ignores[i].val;
715 match = strmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH;
717 if (histignore.ignores[i].flags & HIGN_EXPAND)