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
*));
60 static int check_history_control
__P((char *));
61 static void really_add_history
__P((char *));
63 static struct ignorevar histignore
=
69 (sh_iv_item_func_t
*)histignore_item_func
,
72 #define HIGN_EXPAND 0x01
74 /* Declarations of bash history variables. */
75 /* Non-zero means to remember lines typed to the shell on the history
76 list. This is different than the user-controlled behaviour; this
77 becomes zero when we read lines from a file, for example. */
78 int remember_on_history
= 1;
80 /* The number of lines that Bash has added to this history session. */
81 int history_lines_this_session
;
83 /* The number of lines that Bash has read from the history file. */
84 int history_lines_in_file
;
86 #if defined (BANG_HISTORY)
87 /* Non-zero means do no history expansion on this line, regardless
88 of what history_expansion says. */
89 int history_expansion_inhibited
;
92 /* With the old default, every line was saved in the history individually.
93 I.e., if the user enters:
98 Each line will be individually saved in the history.
105 If the variable command_oriented_history is set, multiple lines
106 which form one command will be saved as one history entry.
117 The user can then recall the whole command all at once instead
118 of just being able to recall one line at a time.
120 This is now enabled by default.
122 int command_oriented_history
= 1;
124 /* Set to 1 if the first line of a possibly-multi-line command was saved
125 in the history list. Managed by maybe_add_history(), but global so
126 the history-manipluating builtins can see it. */
127 int current_command_first_line_saved
= 0;
129 /* Non-zero means to store newlines in the history list when using
130 command_oriented_history rather than trying to use semicolons. */
133 /* Non-zero means to append the history to the history file at shell
134 exit, even if the history has been stifled. */
135 int force_append_history
;
137 /* A nit for picking at history saving.
138 Value of 0 means save all lines parsed by the shell on the history.
139 Value of 1 means save all lines that do not start with a space.
140 Value of 2 means save all lines that do not match the last line saved. */
143 /* Set to 1 if the last command was added to the history list successfully
144 as a separate history entry; set to 0 if the line was ignored or added
145 to a previous entry as part of command-oriented-history processing. */
146 int hist_last_line_added
;
148 #if defined (READLINE)
149 /* If non-zero, and readline is being used, the user is offered the
150 chance to re-edit a failed history expansion. */
151 int history_reediting
;
153 /* If non-zero, and readline is being used, don't directly execute a
154 line with history substitution. Reload it into the editing buffer
155 instead and let the user further edit and confirm with a newline. */
158 #endif /* READLINE */
160 /* Non-zero means to not save function definitions in the history list. */
161 int dont_save_function_defs
;
163 /* Variables declared in other files used here. */
164 extern int current_command_line_count
;
166 extern struct dstack dstack
;
168 static int bash_history_inhibit_expansion
__P((char *, int));
169 #if defined (READLINE)
170 static void re_edit
__P((char *));
172 static int history_expansion_p
__P((char *));
173 static int shell_comment
__P((char *));
174 static int should_expand
__P((char *));
175 static HIST_ENTRY
*last_history_entry
__P((void));
176 static char *expand_histignore_pattern
__P((char *));
177 static int history_should_ignore
__P((char *));
179 /* Is the history expansion starting at string[i] one that should not
182 bash_history_inhibit_expansion (string
, i
)
186 /* The shell uses ! as a pattern negation character in globbing [...]
187 expressions, so let those pass without expansion. */
188 if (i
> 0 && (string
[i
- 1] == '[') && member (']', string
+ i
+ 1))
190 /* The shell uses ! as the indirect expansion character, so let those
191 expansions pass as well. */
192 else if (i
> 1 && string
[i
- 1] == '{' && string
[i
- 2] == '$' &&
193 member ('}', string
+ i
+ 1))
195 #if defined (EXTENDED_GLOB)
196 else if (extended_glob
&& i
> 1 && string
[i
+1] == '(' && member (')', string
+ i
+ 2))
204 bash_initialize_history ()
206 history_quotes_inhibit_expansion
= 1;
207 history_search_delimiter_chars
= ";&()|<>";
208 history_inhibit_expansion_function
= bash_history_inhibit_expansion
;
212 bash_history_reinit (interact
)
215 #if defined (BANG_HISTORY)
216 history_expansion
= interact
!= 0;
217 history_expansion_inhibited
= 1;
219 remember_on_history
= interact
!= 0;
220 history_inhibit_expansion_function
= bash_history_inhibit_expansion
;
224 bash_history_disable ()
226 remember_on_history
= 0;
227 #if defined (BANG_HISTORY)
228 history_expansion_inhibited
= 1;
233 bash_history_enable ()
235 remember_on_history
= 1;
236 #if defined (BANG_HISTORY)
237 history_expansion_inhibited
= 0;
239 history_inhibit_expansion_function
= bash_history_inhibit_expansion
;
240 sv_history_control ("HISTCONTROL");
241 sv_histignore ("HISTIGNORE");
244 /* Load the history list from the history file. */
251 /* Truncate history file for interactive shells which desire it.
252 Note that the history file is automatically truncated to the
253 size of HISTSIZE if the user does not explicitly set the size
255 set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
256 sv_histsize ("HISTFILESIZE");
258 /* Read the history in HISTFILE into the history list. */
259 hf
= get_string_value ("HISTFILE");
261 if (hf
&& *hf
&& stat (hf
, &buf
) == 0)
265 history_lines_in_file
= where_history ();
269 #ifdef INCLUDE_UNUSED
270 /* Write the existing history out to the history file. */
277 hf
= get_string_value ("HISTFILE");
278 if (hf
&& *hf
&& stat (hf
, &buf
) == 0)
280 /* Append only the lines that occurred this session to
284 if (history_lines_this_session
< where_history () || force_append_history
)
285 append_history (history_lines_this_session
, hf
);
289 sv_histsize ("HISTFILESIZE");
295 maybe_append_history (filename
)
301 result
= EXECUTION_SUCCESS
;
302 if (history_lines_this_session
&& (history_lines_this_session
< where_history ()))
304 /* If the filename was supplied, then create it if necessary. */
305 if (stat (filename
, &buf
) == -1 && errno
== ENOENT
)
307 fd
= open (filename
, O_WRONLY
|O_CREAT
, 0600);
310 builtin_error ("%s: cannot create: %s", filename
, strerror (errno
));
311 return (EXECUTION_FAILURE
);
315 result
= append_history (history_lines_this_session
, filename
);
316 history_lines_in_file
+= history_lines_this_session
;
317 history_lines_this_session
= 0;
322 /* If this is an interactive shell, then append the lines executed
323 this session to the history file. */
325 maybe_save_shell_history ()
332 if (history_lines_this_session
)
334 hf
= get_string_value ("HISTFILE");
338 /* If the file doesn't exist, then create it. */
339 if (stat (hf
, &buf
) == -1)
342 file
= open (hf
, O_CREAT
| O_TRUNC
| O_WRONLY
, 0600);
347 /* Now actually append the lines if the history hasn't been
348 stifled. If the history has been stifled, rewrite the
351 if (history_lines_this_session
<= where_history () || force_append_history
)
353 result
= append_history (history_lines_this_session
, hf
);
354 history_lines_in_file
+= history_lines_this_session
;
358 result
= write_history (hf
);
359 history_lines_in_file
= history_lines_this_session
;
361 history_lines_this_session
= 0;
363 sv_histsize ("HISTFILESIZE");
369 #if defined (READLINE)
370 /* Tell readline () that we have some text for it to edit. */
375 if (bash_input
.type
== st_stdin
)
378 #endif /* READLINE */
380 /* Return 1 if this line needs history expansion. */
382 history_expansion_p (line
)
387 for (s
= line
; *s
; s
++)
388 if (*s
== history_expansion_char
|| *s
== history_subst_char
)
393 /* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then
394 print the results of expanding the line if there were any changes.
395 If there is an error, return NULL, otherwise the expanded line is
396 returned. If ADDIT is non-zero the line is added to the history
397 list after history expansion. ADDIT is just a suggestion;
398 REMEMBER_ON_HISTORY can veto, and does.
399 Right now this does history expansion. */
401 pre_process_line (line
, print_changes
, addit
)
403 int print_changes
, addit
;
412 # if defined (BANG_HISTORY)
413 /* History expand the line. If this results in no errors, then
414 add that line to the history if ADDIT is non-zero. */
415 if (!history_expansion_inhibited
&& history_expansion
&& history_expansion_p (line
))
417 expanded
= history_expand (line
, &history_value
);
424 internal_error ("%s", history_value
);
425 #if defined (READLINE)
426 else if (hist_verify
== 0 || expanded
== 2)
430 fprintf (stderr
, "%s\n", history_value
);
433 /* If there was an error, return NULL. */
434 if (expanded
< 0 || expanded
== 2) /* 2 == print only */
436 free (history_value
);
438 # if defined (READLINE)
439 /* New hack. We can allow the user to edit the
440 failed history expansion. */
441 if (history_reediting
&& expanded
< 0)
443 # endif /* READLINE */
444 return ((char *)NULL
);
447 # if defined (READLINE)
448 if (hist_verify
&& expanded
== 1)
450 re_edit (history_value
);
451 return ((char *)NULL
);
456 /* Let other expansions know that return_value can be free'ed,
457 and that a line has been added to the history list. Note
458 that we only add lines that have something in them. */
460 return_value
= history_value
;
462 # endif /* BANG_HISTORY */
464 if (addit
&& remember_on_history
&& *return_value
)
465 maybe_add_history (return_value
);
469 return_value
= savestring (line
);
472 return (return_value
);
475 /* Return 1 if the first non-whitespace character in LINE is a `#', indicating
476 * that the line is a shell comment. */
483 for (p
= line
; p
&& *p
&& whitespace (*p
); p
++)
485 return (p
&& *p
== '#');
488 #ifdef INCLUDE_UNUSED
489 /* Remove shell comments from LINE. A `#' and anything after it is a comment.
490 This isn't really useful yet, since it doesn't handle quoting. */
492 filter_comments (line
)
497 for (p
= line
; p
&& *p
&& *p
!= '#'; p
++)
505 /* Check LINE against what HISTCONTROL says to do. Returns 1 if the line
506 should be saved; 0 if it should be discarded. */
508 check_history_control (line
)
514 switch (history_control
)
516 case 0: /* nothing */
518 case 1: /* ignorespace */
519 return (*line
!= ' ');
520 case 3: /* ignoreboth */
523 /* FALLTHROUGH if case == 3 (`ignoreboth') */
524 case 2: /* ignoredups */
526 temp
= previous_history ();
528 r
= (temp
== 0 || STREQ (temp
->line
, line
) == 0);
537 /* Add LINE to the history list, handling possibly multi-line compound
538 commands. We note whether or not we save the first line of each command
539 (which is usually the entire command and history entry), and don't add
540 the second and subsequent lines of a multi-line compound command if we
541 didn't save the first line. We don't usually save shell comment lines in
542 compound commands in the history, because they could have the effect of
543 commenting out the rest of the command when the entire command is saved as
544 a single history entry (when COMMAND_ORIENTED_HISTORY is enabled). If
545 LITERAL_HISTORY is set, we're saving lines in the history with embedded
546 newlines, so it's OK to save comment lines. We also make sure to save
547 multiple-line quoted strings or other constructs. */
549 maybe_add_history (line
)
552 hist_last_line_added
= 0;
554 /* Don't use the value of history_control to affect the second
555 and subsequent lines of a multi-line command (old code did
556 this only when command_oriented_history is enabled). */
557 if (current_command_line_count
> 1)
559 if (current_command_first_line_saved
&&
560 (literal_history
|| dstack
.delimiter_depth
!= 0 || shell_comment (line
) == 0))
561 bash_add_history (line
);
565 /* This is the first line of a (possible multi-line) command. Note whether
566 or not we should save the first line and remember it. */
567 current_command_first_line_saved
= check_add_history (line
, 0);
570 /* Just check LINE against HISTCONTROL and HISTIGNORE and add it to the
571 history if it's OK. Used by `history -s' as well as maybe_add_history().
572 Returns 1 if the line was saved in the history, 0 otherwise. */
574 check_add_history (line
, force
)
578 if (check_history_control (line
) && history_should_ignore (line
) == 0)
582 really_add_history (line
);
586 bash_add_history (line
);
592 /* Add a line to the history list.
593 The variable COMMAND_ORIENTED_HISTORY controls the style of history
594 remembering; when non-zero, and LINE is not the first line of a
595 complete parser construct, append LINE to the last history line instead
596 of adding it as a new line. */
598 bash_add_history (line
)
601 int add_it
, offset
, curlen
;
602 HIST_ENTRY
*current
, *old
;
603 char *chars_to_add
, *new_line
;
606 if (command_oriented_history
&& current_command_line_count
> 1)
608 chars_to_add
= literal_history
? "\n" : history_delimiting_chars ();
611 current
= previous_history ();
615 /* If the previous line ended with an escaped newline (escaped
616 with backslash, but otherwise unquoted), then remove the quoted
617 newline, since that is what happens when the line is parsed. */
618 curlen
= strlen (current
->line
);
620 if (dstack
.delimiter_depth
== 0 && current
->line
[curlen
- 1] == '\\' &&
621 current
->line
[curlen
- 2] != '\\')
623 current
->line
[curlen
- 1] = '\0';
628 new_line
= (char *)xmalloc (1
631 + strlen (chars_to_add
));
632 sprintf (new_line
, "%s%s%s", current
->line
, chars_to_add
, line
);
633 offset
= where_history ();
634 old
= replace_history_entry (offset
, new_line
, current
->data
);
647 really_add_history (line
);
653 really_add_history (line
)
656 hist_last_line_added
= 1;
658 history_lines_this_session
++;
665 return (get_string_value ("HISTSIZE") ? history_base
+ where_history () : 1);
674 for (p
= s
; p
&& *p
; p
++)
685 histignore_item_func (ign
)
688 if (should_expand (ign
->val
))
689 ign
->flags
|= HIGN_EXPAND
;
694 setup_history_ignore (varname
)
697 setup_ignore_patterns (&histignore
);
701 last_history_entry ()
706 he
= previous_history ();
716 he
= last_history_entry ();
718 return ((char *)NULL
);
723 expand_histignore_pattern (pat
)
729 phe
= last_history_entry ();
731 if (phe
== (HIST_ENTRY
*)0)
732 return (savestring (pat
));
734 ret
= strcreplace (pat
, '&', phe
->line
, 1);
739 /* Return 1 if we should not put LINE into the history according to the
740 patterns in HISTIGNORE. */
742 history_should_ignore (line
)
745 register int i
, match
;
748 if (histignore
.num_ignores
== 0)
751 for (i
= match
= 0; i
< histignore
.num_ignores
; i
++)
753 if (histignore
.ignores
[i
].flags
& HIGN_EXPAND
)
754 npat
= expand_histignore_pattern (histignore
.ignores
[i
].val
);
756 npat
= histignore
.ignores
[i
].val
;
758 match
= strmatch (npat
, line
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
;
760 if (histignore
.ignores
[i
].flags
& HIGN_EXPAND
)