Imported from ../bash-2.05b.tar.gz.
[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 "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 */