]> git.ipfire.org Git - thirdparty/bash.git/blob - bashhist.c
809026687c686a9a741fe4a1734d63ff0e60b32d
[thirdparty/bash.git] / bashhist.c
1 /* bashhist.c -- bash interface to the GNU history library. */
2
3 /* Copyright (C) 1993 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
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
10 version.
11
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
15 for more details.
16
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. */
20
21 #include "config.h"
22
23 #if defined (HISTORY)
24
25 #if defined (HAVE_UNISTD_H)
26 # ifdef _MINIX
27 # include <sys/types.h>
28 # endif
29 # include <unistd.h>
30 #endif
31
32 #include "bashtypes.h"
33 #include <stdio.h>
34 #include <errno.h>
35 #include "bashansi.h"
36 #include "posixstat.h"
37 #include "filecntl.h"
38
39 #include "shell.h"
40 #include "flags.h"
41 #include "input.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"
46
47 #include <readline/history.h>
48 #include <glob/glob.h>
49 #include <glob/strmatch.h>
50
51 #if defined (READLINE)
52 # include "bashline.h"
53 #endif
54
55 #if !defined (errno)
56 extern int errno;
57 #endif
58
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 *));
62
63 static struct ignorevar histignore =
64 {
65 "HISTIGNORE",
66 (struct ign *)0,
67 0,
68 (char *)0,
69 (sh_iv_item_func_t *)histignore_item_func,
70 };
71
72 #define HIGN_EXPAND 0x01
73
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;
79
80 /* The number of lines that Bash has added to this history session. */
81 int history_lines_this_session;
82
83 /* The number of lines that Bash has read from the history file. */
84 int history_lines_in_file;
85
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;
90 #endif
91
92 /* With the old default, every line was saved in the history individually.
93 I.e., if the user enters:
94 bash$ for i in a b c
95 > do
96 > echo $i
97 > done
98 Each line will be individually saved in the history.
99 bash$ history
100 10 for i in a b c
101 11 do
102 12 echo $i
103 13 done
104 14 history
105 If the variable command_oriented_history is set, multiple lines
106 which form one command will be saved as one history entry.
107 bash$ for i in a b c
108 > do
109 > echo $i
110 > done
111 bash$ history
112 10 for i in a b c
113 do
114 echo $i
115 done
116 11 history
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.
119
120 This is now enabled by default.
121 */
122 int command_oriented_history = 1;
123
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;
128
129 /* Non-zero means to store newlines in the history list when using
130 command_oriented_history rather than trying to use semicolons. */
131 int literal_history;
132
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;
136
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. */
141 int history_control;
142
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;
147
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;
152
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. */
156 int hist_verify;
157
158 #endif /* READLINE */
159
160 /* Non-zero means to not save function definitions in the history list. */
161 int dont_save_function_defs;
162
163 /* Variables declared in other files used here. */
164 extern int current_command_line_count;
165
166 extern struct dstack dstack;
167
168 static int bash_history_inhibit_expansion __P((char *, int));
169 #if defined (READLINE)
170 static void re_edit __P((char *));
171 #endif
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 *));
178
179 /* Is the history expansion starting at string[i] one that should not
180 be expanded? */
181 static int
182 bash_history_inhibit_expansion (string, i)
183 char *string;
184 int i;
185 {
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))
189 return (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))
194 return (1);
195 #if defined (EXTENDED_GLOB)
196 else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
197 return (1);
198 #endif
199 else
200 return (0);
201 }
202
203 void
204 bash_initialize_history ()
205 {
206 history_quotes_inhibit_expansion = 1;
207 history_search_delimiter_chars = ";&()|<>";
208 history_inhibit_expansion_function = bash_history_inhibit_expansion;
209 }
210
211 void
212 bash_history_reinit (interact)
213 int interact;
214 {
215 #if defined (BANG_HISTORY)
216 history_expansion = interact != 0;
217 history_expansion_inhibited = 1;
218 #endif
219 remember_on_history = interact != 0;
220 history_inhibit_expansion_function = bash_history_inhibit_expansion;
221 }
222
223 void
224 bash_history_disable ()
225 {
226 remember_on_history = 0;
227 #if defined (BANG_HISTORY)
228 history_expansion_inhibited = 1;
229 #endif
230 }
231
232 void
233 bash_history_enable ()
234 {
235 remember_on_history = 1;
236 #if defined (BANG_HISTORY)
237 history_expansion_inhibited = 0;
238 #endif
239 history_inhibit_expansion_function = bash_history_inhibit_expansion;
240 sv_history_control ("HISTCONTROL");
241 sv_histignore ("HISTIGNORE");
242 }
243
244 /* Load the history list from the history file. */
245 void
246 load_history ()
247 {
248 char *hf;
249 struct stat buf;
250
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
254 differently. */
255 set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
256 sv_histsize ("HISTFILESIZE");
257
258 /* Read the history in HISTFILE into the history list. */
259 hf = get_string_value ("HISTFILE");
260
261 if (hf && *hf && stat (hf, &buf) == 0)
262 {
263 read_history (hf);
264 using_history ();
265 history_lines_in_file = where_history ();
266 }
267 }
268
269 #ifdef INCLUDE_UNUSED
270 /* Write the existing history out to the history file. */
271 void
272 save_history ()
273 {
274 char *hf;
275 struct stat buf;
276
277 hf = get_string_value ("HISTFILE");
278 if (hf && *hf && stat (hf, &buf) == 0)
279 {
280 /* Append only the lines that occurred this session to
281 the history file. */
282 using_history ();
283
284 if (history_lines_this_session < where_history () || force_append_history)
285 append_history (history_lines_this_session, hf);
286 else
287 write_history (hf);
288
289 sv_histsize ("HISTFILESIZE");
290 }
291 }
292 #endif
293
294 int
295 maybe_append_history (filename)
296 char *filename;
297 {
298 int fd, result;
299 struct stat buf;
300
301 result = EXECUTION_SUCCESS;
302 if (history_lines_this_session && (history_lines_this_session < where_history ()))
303 {
304 /* If the filename was supplied, then create it if necessary. */
305 if (stat (filename, &buf) == -1 && errno == ENOENT)
306 {
307 fd = open (filename, O_WRONLY|O_CREAT, 0600);
308 if (fd < 0)
309 {
310 builtin_error ("%s: cannot create: %s", filename, strerror (errno));
311 return (EXECUTION_FAILURE);
312 }
313 close (fd);
314 }
315 result = append_history (history_lines_this_session, filename);
316 history_lines_in_file += history_lines_this_session;
317 history_lines_this_session = 0;
318 }
319 return (result);
320 }
321
322 /* If this is an interactive shell, then append the lines executed
323 this session to the history file. */
324 int
325 maybe_save_shell_history ()
326 {
327 int result;
328 char *hf;
329 struct stat buf;
330
331 result = 0;
332 if (history_lines_this_session)
333 {
334 hf = get_string_value ("HISTFILE");
335
336 if (hf && *hf)
337 {
338 /* If the file doesn't exist, then create it. */
339 if (stat (hf, &buf) == -1)
340 {
341 int file;
342 file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
343 if (file != -1)
344 close (file);
345 }
346
347 /* Now actually append the lines if the history hasn't been
348 stifled. If the history has been stifled, rewrite the
349 history file. */
350 using_history ();
351 if (history_lines_this_session <= where_history () || force_append_history)
352 {
353 result = append_history (history_lines_this_session, hf);
354 history_lines_in_file += history_lines_this_session;
355 }
356 else
357 {
358 result = write_history (hf);
359 history_lines_in_file = history_lines_this_session;
360 }
361 history_lines_this_session = 0;
362
363 sv_histsize ("HISTFILESIZE");
364 }
365 }
366 return (result);
367 }
368
369 #if defined (READLINE)
370 /* Tell readline () that we have some text for it to edit. */
371 static void
372 re_edit (text)
373 char *text;
374 {
375 if (bash_input.type == st_stdin)
376 bash_re_edit (text);
377 }
378 #endif /* READLINE */
379
380 /* Return 1 if this line needs history expansion. */
381 static int
382 history_expansion_p (line)
383 char *line;
384 {
385 register char *s;
386
387 for (s = line; *s; s++)
388 if (*s == history_expansion_char || *s == history_subst_char)
389 return 1;
390 return 0;
391 }
392
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. */
400 char *
401 pre_process_line (line, print_changes, addit)
402 char *line;
403 int print_changes, addit;
404 {
405 char *history_value;
406 char *return_value;
407 int expanded;
408
409 return_value = line;
410 expanded = 0;
411
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))
416 {
417 expanded = history_expand (line, &history_value);
418
419 if (expanded)
420 {
421 if (print_changes)
422 {
423 if (expanded < 0)
424 internal_error ("%s", history_value);
425 #if defined (READLINE)
426 else if (hist_verify == 0 || expanded == 2)
427 #else
428 else
429 #endif
430 fprintf (stderr, "%s\n", history_value);
431 }
432
433 /* If there was an error, return NULL. */
434 if (expanded < 0 || expanded == 2) /* 2 == print only */
435 {
436 free (history_value);
437
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)
442 re_edit (line);
443 # endif /* READLINE */
444 return ((char *)NULL);
445 }
446
447 # if defined (READLINE)
448 if (hist_verify && expanded == 1)
449 {
450 re_edit (history_value);
451 return ((char *)NULL);
452 }
453 # endif
454 }
455
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. */
459 expanded = 1;
460 return_value = history_value;
461 }
462 # endif /* BANG_HISTORY */
463
464 if (addit && remember_on_history && *return_value)
465 maybe_add_history (return_value);
466
467 #if 0
468 if (expanded == 0)
469 return_value = savestring (line);
470 #endif
471
472 return (return_value);
473 }
474
475 /* Return 1 if the first non-whitespace character in LINE is a `#', indicating
476 * that the line is a shell comment. */
477 static int
478 shell_comment (line)
479 char *line;
480 {
481 char *p;
482
483 for (p = line; p && *p && whitespace (*p); p++)
484 ;
485 return (p && *p == '#');
486 }
487
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. */
491 static char *
492 filter_comments (line)
493 char *line;
494 {
495 char *p;
496
497 for (p = line; p && *p && *p != '#'; p++)
498 ;
499 if (p && *p == '#')
500 *p = '\0';
501 return (line);
502 }
503 #endif
504
505 /* Check LINE against what HISTCONTROL says to do. Returns 1 if the line
506 should be saved; 0 if it should be discarded. */
507 static int
508 check_history_control (line)
509 char *line;
510 {
511 HIST_ENTRY *temp;
512 int r;
513
514 switch (history_control)
515 {
516 case 0: /* nothing */
517 return 1;
518 case 1: /* ignorespace */
519 return (*line != ' ');
520 case 3: /* ignoreboth */
521 if (*line == ' ')
522 return 0;
523 /* FALLTHROUGH if case == 3 (`ignoreboth') */
524 case 2: /* ignoredups */
525 using_history ();
526 temp = previous_history ();
527
528 r = (temp == 0 || STREQ (temp->line, line) == 0);
529
530 using_history ();
531 return r;
532 }
533
534 return 0;
535 }
536
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. */
548 void
549 maybe_add_history (line)
550 char *line;
551 {
552 hist_last_line_added = 0;
553
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)
558 {
559 if (current_command_first_line_saved &&
560 (literal_history || dstack.delimiter_depth != 0 || shell_comment (line) == 0))
561 bash_add_history (line);
562 return;
563 }
564
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);
568 }
569
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. */
573 int
574 check_add_history (line, force)
575 char *line;
576 int force;
577 {
578 if (check_history_control (line) && history_should_ignore (line) == 0)
579 {
580 if (force)
581 {
582 really_add_history (line);
583 using_history ();
584 }
585 else
586 bash_add_history (line);
587 return 1;
588 }
589 return 0;
590 }
591
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. */
597 void
598 bash_add_history (line)
599 char *line;
600 {
601 int add_it, offset, curlen;
602 HIST_ENTRY *current, *old;
603 char *chars_to_add, *new_line;
604
605 add_it = 1;
606 if (command_oriented_history && current_command_line_count > 1)
607 {
608 chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
609
610 using_history ();
611 current = previous_history ();
612
613 if (current)
614 {
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);
619
620 if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
621 current->line[curlen - 2] != '\\')
622 {
623 current->line[curlen - 1] = '\0';
624 curlen--;
625 chars_to_add = "";
626 }
627
628 new_line = (char *)xmalloc (1
629 + curlen
630 + strlen (line)
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);
635 free (new_line);
636
637 if (old)
638 {
639 FREE (old->line);
640 free (old);
641 }
642 add_it = 0;
643 }
644 }
645
646 if (add_it)
647 really_add_history (line);
648
649 using_history ();
650 }
651
652 static void
653 really_add_history (line)
654 char *line;
655 {
656 hist_last_line_added = 1;
657 add_history (line);
658 history_lines_this_session++;
659 }
660
661 int
662 history_number ()
663 {
664 using_history ();
665 return (get_string_value ("HISTSIZE") ? history_base + where_history () : 1);
666 }
667
668 static int
669 should_expand (s)
670 char *s;
671 {
672 char *p;
673
674 for (p = s; p && *p; p++)
675 {
676 if (*p == '\\')
677 p++;
678 else if (*p == '&')
679 return 1;
680 }
681 return 0;
682 }
683
684 static int
685 histignore_item_func (ign)
686 struct ign *ign;
687 {
688 if (should_expand (ign->val))
689 ign->flags |= HIGN_EXPAND;
690 return (0);
691 }
692
693 void
694 setup_history_ignore (varname)
695 char *varname;
696 {
697 setup_ignore_patterns (&histignore);
698 }
699
700 static HIST_ENTRY *
701 last_history_entry ()
702 {
703 HIST_ENTRY *he;
704
705 using_history ();
706 he = previous_history ();
707 using_history ();
708 return he;
709 }
710
711 char *
712 last_history_line ()
713 {
714 HIST_ENTRY *he;
715
716 he = last_history_entry ();
717 if (he == 0)
718 return ((char *)NULL);
719 return he->line;
720 }
721
722 static char *
723 expand_histignore_pattern (pat)
724 char *pat;
725 {
726 HIST_ENTRY *phe;
727 char *ret;
728
729 phe = last_history_entry ();
730
731 if (phe == (HIST_ENTRY *)0)
732 return (savestring (pat));
733
734 ret = strcreplace (pat, '&', phe->line, 1);
735
736 return ret;
737 }
738
739 /* Return 1 if we should not put LINE into the history according to the
740 patterns in HISTIGNORE. */
741 static int
742 history_should_ignore (line)
743 char *line;
744 {
745 register int i, match;
746 char *npat;
747
748 if (histignore.num_ignores == 0)
749 return 0;
750
751 for (i = match = 0; i < histignore.num_ignores; i++)
752 {
753 if (histignore.ignores[i].flags & HIGN_EXPAND)
754 npat = expand_histignore_pattern (histignore.ignores[i].val);
755 else
756 npat = histignore.ignores[i].val;
757
758 match = strmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH;
759
760 if (histignore.ignores[i].flags & HIGN_EXPAND)
761 free (npat);
762
763 if (match)
764 break;
765 }
766
767 return match;
768 }
769 #endif /* HISTORY */