85e4eebec7f1981bea4d1f06763a1675feba9c26
[platform/upstream/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 "builtins/common.h"
45
46 #include <readline/history.h>
47 #include <glob/fnmatch.h>
48
49 #if defined (READLINE)
50 #  include "bashline.h"
51 #endif
52
53 #if !defined (errno)
54 extern int errno;
55 #endif
56
57 extern int glob_pattern_p ();
58
59 static int histignore_item_func ();
60
61 static struct ignorevar histignore =
62 {
63   "HISTIGNORE",
64   (struct ign *)0,
65   0,
66   (char *)0,
67   (Function *)histignore_item_func,
68 };
69
70 #define HIGN_EXPAND 0x01
71
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;
77
78 /* The number of lines that Bash has added to this history session. */
79 int history_lines_this_session;
80
81 /* The number of lines that Bash has read from the history file. */
82 int history_lines_in_file;
83
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;
88 #endif
89
90 /* By default, every line is saved in the history individually.  I.e.,
91    if the user enters:
92         bash$ for i in a b c
93         > do
94         > echo $i
95         > done
96    Each line will be individually saved in the history.
97         bash$ history
98         10  for i in a b c
99         11  do
100         12  echo $i
101         13  done
102         14  history
103    If the variable command_oriented_history is set, multiple lines
104    which form one command will be saved as one history entry.
105         bash$ for i in a b c
106         > do
107         > echo $i
108         > done
109         bash$ history
110         10  for i in a b c
111     do
112     echo $i
113     done
114         11  history
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.
117    */
118 int command_oriented_history = 1;
119
120 /* Non-zero means to store newlines in the history list when using
121    command_oriented_history rather than trying to use semicolons. */
122 int literal_history;
123
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;
127
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. */
132 int history_control;
133
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;
138
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;
143
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. */
147 int hist_verify;
148
149 #endif /* READLINE */
150
151 /* Variables declared in other files used here. */
152 extern int interactive;
153 extern int current_command_line_count;
154
155 extern struct dstack dstack;
156
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 */
161
162 static int history_should_ignore ();
163
164 /* Is the history expansion starting at string[i] one that should not
165    be expanded? */
166 static int
167 bash_history_inhibit_expansion (string, i)
168      char *string;
169      int i;
170 {
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))
174     return (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))
179     return (1);
180 #if defined (EXTENDED_GLOB)
181   else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
182     return (1);
183 #endif
184   else
185     return (0);
186 }
187
188 void
189 bash_initialize_history ()
190 {
191   history_quotes_inhibit_expansion = 1;
192   history_search_delimiter_chars = ";&()|<>";
193   history_inhibit_expansion_function = bash_history_inhibit_expansion;
194 }
195
196 void
197 bash_history_reinit (interact)
198      int interact;
199 {
200 #if defined (BANG_HISTORY)
201   history_expansion = interact != 0;
202   history_expansion_inhibited = 1;
203 #endif
204   remember_on_history = interact != 0;
205   history_inhibit_expansion_function = bash_history_inhibit_expansion;
206 }
207
208 void
209 bash_history_disable ()
210 {
211   remember_on_history = 0;
212 #if defined (BANG_HISTORY)
213   history_expansion_inhibited = 1;
214 #endif
215 }
216
217 void
218 bash_history_enable ()
219 {
220   remember_on_history = 1;
221 #if defined (BANG_HISTORY)
222   history_expansion_inhibited = 0;
223 #endif
224   history_inhibit_expansion_function = bash_history_inhibit_expansion;
225   sv_history_control ("HISTCONTROL");
226   sv_histignore ("HISTIGNORE");
227 }
228
229 /* Load the history list from the history file. */
230 void
231 load_history ()
232 {
233   char *hf;
234   struct stat buf;
235
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
239      differently. */
240   set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
241   sv_histsize ("HISTFILESIZE");
242
243   /* Read the history in HISTFILE into the history list. */
244   hf = get_string_value ("HISTFILE");
245
246   if (hf && *hf && stat (hf, &buf) == 0)
247     {
248       read_history (hf);
249       using_history ();
250       history_lines_in_file = where_history ();
251     }
252 }
253
254 #ifdef INCLUDE_UNUSED
255 /* Write the existing history out to the history file. */
256 void
257 save_history ()
258 {
259   char *hf;
260   struct stat buf;
261
262   hf = get_string_value ("HISTFILE");
263   if (hf && *hf && stat (hf, &buf) == 0)
264     {
265       /* Append only the lines that occurred this session to
266          the history file. */
267       using_history ();
268
269       if (history_lines_this_session < where_history () || force_append_history)
270         append_history (history_lines_this_session, hf);
271       else
272         write_history (hf);
273
274       sv_histsize ("HISTFILESIZE");
275     }
276 }
277 #endif
278
279 int
280 maybe_append_history (filename)
281      char *filename;
282 {
283   int fd, result;
284   struct stat buf;
285
286   result = EXECUTION_SUCCESS;
287   if (history_lines_this_session && (history_lines_this_session < where_history ()))
288     {
289       /* If the filename was supplied, then create it if necessary. */
290       if (stat (filename, &buf) == -1 && errno == ENOENT)
291         {
292           fd = open (filename, O_WRONLY|O_CREAT, 0600);
293           if (fd < 0)
294             {
295               builtin_error ("%s: cannot create: %s", filename, strerror (errno));
296               return (EXECUTION_FAILURE);
297             }
298           close (fd);
299         }
300       result = append_history (history_lines_this_session, filename);
301       history_lines_in_file += history_lines_this_session;
302       history_lines_this_session = 0;
303     }
304   return (result);
305 }
306
307 /* If this is an interactive shell, then append the lines executed
308    this session to the history file. */
309 int
310 maybe_save_shell_history ()
311 {
312   int result;
313   char *hf;
314   struct stat buf;
315
316   result = 0;
317   if (history_lines_this_session)
318     {
319       hf = get_string_value ("HISTFILE");
320
321       if (hf && *hf)
322         {
323           /* If the file doesn't exist, then create it. */
324           if (stat (hf, &buf) == -1)
325             {
326               int file;
327               file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
328               if (file != -1)
329                 close (file);
330             }
331
332           /* Now actually append the lines if the history hasn't been
333              stifled.  If the history has been stifled, rewrite the
334              history file. */
335           using_history ();
336           if (history_lines_this_session <= where_history () || force_append_history)
337             {
338               result = append_history (history_lines_this_session, hf);
339               history_lines_in_file += history_lines_this_session;
340             }
341           else
342             {
343               result = write_history (hf);
344               history_lines_in_file = history_lines_this_session;
345             }
346           history_lines_this_session = 0;
347
348           sv_histsize ("HISTFILESIZE");
349         }
350     }
351   return (result);
352 }
353
354 #if defined (READLINE)
355 /* Tell readline () that we have some text for it to edit. */
356 static void
357 re_edit (text)
358      char *text;
359 {
360   if (bash_input.type == st_stdin)
361     bash_re_edit (text);
362 }
363 #endif /* READLINE */
364
365 /* Return 1 if this line needs history expansion. */
366 static int
367 history_expansion_p (line)
368      char *line;
369 {
370   register char *s;
371
372   for (s = line; *s; s++)
373     if (*s == history_expansion_char || *s == history_subst_char)
374       return 1;
375   return 0;
376 }
377
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. */
385 char *
386 pre_process_line (line, print_changes, addit)
387      char *line;
388      int print_changes, addit;
389 {
390   char *history_value;
391   char *return_value;
392   int expanded;
393
394   return_value = line;
395   expanded = 0;
396
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))
401     {
402       expanded = history_expand (line, &history_value);
403
404       if (expanded)
405         {
406           if (print_changes)
407             {
408               if (expanded < 0)
409                 internal_error ("%s", history_value);
410 #if defined (READLINE)
411               else if (hist_verify == 0 || expanded == 2)
412 #else
413               else
414 #endif
415                 fprintf (stderr, "%s\n", history_value);
416             }
417
418           /* If there was an error, return NULL. */
419           if (expanded < 0 || expanded == 2)    /* 2 == print only */
420             {
421               free (history_value);
422
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)
427                 re_edit (line);
428 #    endif /* READLINE */
429               return ((char *)NULL);
430             }
431
432 #    if defined (READLINE)
433           if (hist_verify && expanded == 1)
434             {
435               re_edit (history_value);
436               return ((char *)NULL);
437             }
438 #    endif
439         }
440
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. */
444       expanded = 1;
445       return_value = history_value;
446     }
447 #  endif /* BANG_HISTORY */
448
449   if (addit && remember_on_history && *return_value)
450     maybe_add_history (return_value);
451
452 #if 0
453   if (expanded == 0)
454     return_value = savestring (line);
455 #endif
456
457   return (return_value);
458 }
459
460 /* Return 1 if the first non-whitespace character in LINE is a `#', indicating
461  * that the line is a shell comment. */
462 static int
463 shell_comment (line)
464      char *line;
465 {
466   char *p;
467
468   for (p = line; p && *p && whitespace (*p); p++)
469     ;
470   return (p && *p == '#');
471 }
472
473 /* Remove shell comments from LINE.  A `#' and anything after it is a comment.
474    This isn't really useful yet, since it doesn't handle quoting. */
475 static char *
476 filter_comments (line)
477      char *line;
478 {
479   char *p;
480
481   for (p = line; p && *p && *p != '#'; p++)
482     ;
483   if (p && *p == '#')
484     *p = '\0';
485   return (line);
486 }
487
488 /* Add LINE to the history list depending on the value of HISTORY_CONTROL. */
489 void
490 maybe_add_history (line)
491      char *line;
492 {
493   static int first_line_saved = 0;
494   HIST_ENTRY *temp;
495
496   hist_last_line_added = 0;
497
498   /* Don't use the value of history_control to affect the second
499      and subsequent lines of a multi-line command (old code did
500      this only when command_oriented_history is enabled). */
501 #if 0
502   if (command_oriented_history && current_command_line_count > 1)
503 #else
504   if (current_command_line_count > 1)
505 #endif
506     {
507       if (first_line_saved &&
508           (literal_history || dstack.delimiter_depth != 0 || shell_comment (line) == 0))
509         bash_add_history (line);
510       return;
511     }
512
513   /* This is the first line of a (possible multi-line) command.  Note whether
514      or not we should save the first line and remember it. */
515   first_line_saved = 0;
516
517   switch (history_control)
518     {
519     case 0:
520       first_line_saved = 1;
521       break;
522     case 1:
523       if (*line != ' ')
524         first_line_saved = 1;
525       break;
526     case 3:
527       if (*line == ' ')
528         break;
529       /* FALLTHROUGH if case == 3 (`ignoreboth') */
530     case 2:
531       using_history ();
532       temp = previous_history ();
533
534       if (temp == 0 || STREQ (temp->line, line) == 0)
535         first_line_saved = 1;
536
537       using_history ();
538       break;
539     }
540
541   if (first_line_saved && history_should_ignore (line) == 0)
542     bash_add_history (line);
543   else
544     first_line_saved = 0;
545 }
546
547 /* Add a line to the history list.
548    The variable COMMAND_ORIENTED_HISTORY controls the style of history
549    remembering;  when non-zero, and LINE is not the first line of a
550    complete parser construct, append LINE to the last history line instead
551    of adding it as a new line. */
552 void
553 bash_add_history (line)
554      char *line;
555 {
556   int add_it, offset, curlen;
557   HIST_ENTRY *current, *old;
558   char *chars_to_add, *new_line;
559
560   add_it = 1;
561   if (command_oriented_history && current_command_line_count > 1)
562     {
563       chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
564
565       using_history ();
566       current = previous_history ();
567
568       if (current)
569         {
570           /* If the previous line ended with an escaped newline (escaped
571              with backslash, but otherwise unquoted), then remove the quoted
572              newline, since that is what happens when the line is parsed. */
573           curlen = strlen (current->line);
574
575           if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
576               current->line[curlen - 2] != '\\')
577             {
578               current->line[curlen - 1] = '\0';
579               curlen--;
580               chars_to_add = "";
581             }
582
583           new_line = (char *) xmalloc (1
584                                        + curlen
585                                        + strlen (line)
586                                        + strlen (chars_to_add));
587           sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
588           offset = where_history ();
589           old = replace_history_entry (offset, new_line, current->data);
590           free (new_line);
591
592           if (old)
593             {
594               FREE (old->line);
595               free (old);
596             }
597           add_it = 0;
598         }
599     }
600
601   if (add_it)
602     {
603       hist_last_line_added = 1;
604       add_history (line);
605       history_lines_this_session++;
606     }
607   using_history ();
608 }
609
610 int
611 history_number ()
612 {
613   using_history ();
614   return (get_string_value ("HISTSIZE") ? history_base + where_history () : 1);
615 }
616
617 static int
618 should_expand (s)
619      char *s;
620 {
621   char *p;
622
623   for (p = s; p && *p; p++)
624     {
625       if (*p == '\\')
626         p++;
627       else if (*p == '&')
628         return 1;
629     }
630   return 0;
631 }
632
633 static int
634 histignore_item_func (ign)
635      struct ign *ign;
636 {
637   if (should_expand (ign->val))
638     ign->flags |= HIGN_EXPAND;
639   return (0);
640 }
641
642 void
643 setup_history_ignore (varname)
644      char *varname;
645 {
646   setup_ignore_patterns (&histignore);
647 }
648
649 static HIST_ENTRY *
650 last_history_entry ()
651 {
652   HIST_ENTRY *he;
653
654   using_history ();
655   he = previous_history ();
656   using_history ();
657   return he;
658 }
659
660 char *
661 last_history_line ()
662 {
663   HIST_ENTRY *he;
664
665   he = last_history_entry ();
666   if (he == 0)
667     return ((char *)NULL);
668   return he->line;
669 }
670
671 static char *
672 expand_histignore_pattern (pat)
673      char *pat;
674 {
675   HIST_ENTRY *phe;
676   char *ret;
677
678   phe = last_history_entry ();
679
680   if (phe == (HIST_ENTRY *)0)
681     return (savestring (pat));
682
683   ret = strcreplace (pat, '&', phe->line, 1);
684
685   return ret;
686 }
687
688 /* Return 1 if we should not put LINE into the history according to the
689    patterns in HISTIGNORE. */
690 static int
691 history_should_ignore (line)
692      char *line;
693 {
694   register int i, match;
695   char *npat;
696
697   if (histignore.num_ignores == 0)
698     return 0;
699
700   for (i = match = 0; i < histignore.num_ignores; i++)
701     {
702       if (histignore.ignores[i].flags & HIGN_EXPAND)
703         npat = expand_histignore_pattern (histignore.ignores[i].val);
704       else
705         npat = histignore.ignores[i].val;
706
707       match = fnmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH;
708
709       if (histignore.ignores[i].flags & HIGN_EXPAND)
710         free (npat);
711
712       if (match)
713         break;
714     }
715
716   return match;
717 }
718 #endif /* HISTORY */