ed88b2ccfd134f837614f327624b8d2e708f3cf1
[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, 675 Mass Ave, Cambridge, MA 02139, 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)
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 /* Add LINE to the history list depending on the value of HISTORY_CONTROL. */
461 void
462 maybe_add_history (line)
463      char *line;
464 {
465   int should_add;
466   HIST_ENTRY *temp;
467
468   should_add = hist_last_line_added = 0;
469
470   /* Don't use the value of history_control to affect the second
471      and subsequent lines of a multi-line command (old code did
472      this only when command_oriented_history is enabled). */
473 #if 0
474   if (command_oriented_history && current_command_line_count > 1)
475 #else
476   if (current_command_line_count > 1)
477 #endif
478     {
479       bash_add_history (line);
480       return;
481     }
482
483   switch (history_control)
484     {
485     case 0:
486       should_add = 1;
487       break;
488     case 1:
489       if (*line != ' ')
490         should_add = 1;
491       break;
492     case 3:
493       if (*line == ' ')
494         break;
495       /* FALLTHROUGH if case == 3 (`ignoreboth') */
496     case 2:
497       using_history ();
498       temp = previous_history ();
499
500       if (temp == 0 || STREQ (temp->line, line) == 0)
501         should_add = 1;
502
503       using_history ();
504       break;
505     }
506
507   if (should_add && history_should_ignore (line) == 0)
508     bash_add_history (line);
509 }
510
511 /* Add a line to the history list.
512    The variable COMMAND_ORIENTED_HISTORY controls the style of history
513    remembering;  when non-zero, and LINE is not the first line of a
514    complete parser construct, append LINE to the last history line instead
515    of adding it as a new line. */
516 void
517 bash_add_history (line)
518      char *line;
519 {
520   int add_it, offset, curlen;
521   HIST_ENTRY *current, *old;
522   char *chars_to_add, *new_line;
523
524   add_it = 1;
525   if (command_oriented_history && current_command_line_count > 1)
526     {
527       chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
528
529       using_history ();
530       current = previous_history ();
531
532       if (current)
533         {
534           /* If the previous line ended with an escaped newline (escaped
535              with backslash, but otherwise unquoted), then remove the quoted
536              newline, since that is what happens when the line is parsed. */
537           curlen = strlen (current->line);
538
539           if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
540               current->line[curlen - 2] != '\\')
541             {
542               current->line[curlen - 1] = '\0';
543               curlen--;
544               chars_to_add = "";
545             }
546
547           new_line = (char *) xmalloc (1
548                                        + curlen
549                                        + strlen (line)
550                                        + strlen (chars_to_add));
551           sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
552           offset = where_history ();
553           old = replace_history_entry (offset, new_line, current->data);
554           free (new_line);
555
556           if (old)
557             {
558               FREE (old->line);
559               free (old);
560             }
561           add_it = 0;
562         }
563     }
564
565   if (add_it)
566     {
567       hist_last_line_added = 1;
568       add_history (line);
569       history_lines_this_session++;
570     }
571   using_history ();
572 }
573
574 int
575 history_number ()
576 {
577   using_history ();
578   return (get_string_value ("HISTSIZE") ? history_base + where_history () : 1);
579 }
580
581 static int
582 should_expand (s)
583      char *s;
584 {
585   char *p;
586
587   for (p = s; p && *p; p++)
588     {
589       if (*p == '\\')
590         p++;
591       else if (*p == '&')
592         return 1;
593     }
594   return 0;
595 }
596
597 static int
598 histignore_item_func (ign)
599      struct ign *ign;
600 {
601   if (should_expand (ign->val))
602     ign->flags |= HIGN_EXPAND;
603   return (0);
604 }
605
606 void
607 setup_history_ignore (varname)
608      char *varname;
609 {
610   setup_ignore_patterns (&histignore);
611 }
612
613 static HIST_ENTRY *
614 last_history_entry ()
615 {
616   HIST_ENTRY *he;
617
618   using_history ();
619   he = previous_history ();
620   using_history ();
621   return he;
622 }
623
624 char *
625 last_history_line ()
626 {
627   HIST_ENTRY *he;
628
629   he = last_history_entry ();
630   if (he == 0)
631     return ((char *)NULL);
632   return he->line;
633 }
634
635 static char *
636 expand_histignore_pattern (pat)
637      char *pat;
638 {
639   HIST_ENTRY *phe;
640   char *ret, *p, *r, *t;
641   int len, rlen, ind, tlen;
642
643   phe = last_history_entry ();
644
645   if (phe == (HIST_ENTRY *)0)
646     return (savestring (pat));
647
648   len = strlen (phe->line);
649   rlen = len + strlen (pat) + 2;
650   ret = xmalloc (rlen);
651
652   for (p = pat, r = ret; p && *p; )
653     {
654       if (*p == '&')
655         {
656           ind = r - ret;
657           if (glob_pattern_p (phe->line) || strchr (phe->line, '\\'))
658             {
659               t = quote_globbing_chars (phe->line);
660               tlen = strlen (t);
661               RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
662               r = ret + ind;    /* in case reallocated */
663               strcpy (r, t);
664               r += tlen;
665               free (t);
666             }
667           else
668             {
669               tlen = strlen (phe->line);
670               RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen);
671               r = ret + ind;    /* in case reallocated */
672               strcpy (r, phe->line);
673               r += len;
674             }
675           p++;
676           continue;
677         }
678
679       if (*p == '\\' && p[1] == '&')
680         p++;
681
682       *r++ = *p++;
683     }
684   *r = '\0';
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 */