]> git.ipfire.org Git - thirdparty/bash.git/blame - bashhist.c
Bash-4.1 distribution source
[thirdparty/bash.git] / bashhist.c
CommitLineData
726f6388
JA
1/* bashhist.c -- bash interface to the GNU history library. */
2
3185942a 3/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
726f6388
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
3185942a
JA
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
726f6388 11
3185942a
JA
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
726f6388 16
3185942a
JA
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
726f6388 20
ccc6cda3
JA
21#include "config.h"
22
23#if defined (HISTORY)
24
25#if defined (HAVE_UNISTD_H)
cce855bc
JA
26# ifdef _MINIX
27# include <sys/types.h>
28# endif
ccc6cda3
JA
29# include <unistd.h>
30#endif
31
32#include "bashtypes.h"
726f6388
JA
33#include <stdio.h>
34#include <errno.h>
35#include "bashansi.h"
36#include "posixstat.h"
37#include "filecntl.h"
d166f048 38
b80f6443
JA
39#include "bashintl.h"
40
0001803f
CR
41#if defined (SYSLOG_HISTORY)
42# include <syslog.h>
43#endif
44
726f6388
JA
45#include "shell.h"
46#include "flags.h"
ccc6cda3
JA
47#include "input.h"
48#include "parser.h" /* for the struct dstack stuff. */
49#include "pathexp.h" /* for the struct ignorevar stuff */
f73dda09 50#include "bashhist.h" /* matching prototypes and declarations */
ccc6cda3 51#include "builtins/common.h"
d166f048 52
726f6388 53#include <readline/history.h>
f73dda09
JA
54#include <glob/glob.h>
55#include <glob/strmatch.h>
ccc6cda3
JA
56
57#if defined (READLINE)
58# include "bashline.h"
b80f6443 59extern int rl_done, rl_dispatching; /* should really include readline.h */
ccc6cda3
JA
60#endif
61
62#if !defined (errno)
63extern int errno;
64#endif
65
f73dda09 66static int histignore_item_func __P((struct ign *));
7117c2d2 67static int check_history_control __P((char *));
b80f6443 68static void hc_erasedups __P((char *));
7117c2d2 69static void really_add_history __P((char *));
ccc6cda3
JA
70
71static struct ignorevar histignore =
72{
73 "HISTIGNORE",
74 (struct ign *)0,
75 0,
76 (char *)0,
f73dda09 77 (sh_iv_item_func_t *)histignore_item_func,
ccc6cda3
JA
78};
79
80#define HIGN_EXPAND 0x01
726f6388
JA
81
82/* Declarations of bash history variables. */
83/* Non-zero means to remember lines typed to the shell on the history
84 list. This is different than the user-controlled behaviour; this
85 becomes zero when we read lines from a file, for example. */
86int remember_on_history = 1;
f1be666c 87int enable_history_list = 1; /* value for `set -o history' */
726f6388 88
b80f6443
JA
89/* The number of lines that Bash has added to this history session. The
90 difference between the number of the top element in the history list
91 (offset from history_base) and the number of lines in the history file.
92 Appending this session's history to the history file resets this to 0. */
ccc6cda3 93int history_lines_this_session;
726f6388
JA
94
95/* The number of lines that Bash has read from the history file. */
ccc6cda3 96int history_lines_in_file;
726f6388 97
ccc6cda3 98#if defined (BANG_HISTORY)
726f6388
JA
99/* Non-zero means do no history expansion on this line, regardless
100 of what history_expansion says. */
ccc6cda3
JA
101int history_expansion_inhibited;
102#endif
726f6388 103
7117c2d2
JA
104/* With the old default, every line was saved in the history individually.
105 I.e., if the user enters:
726f6388 106 bash$ for i in a b c
ccc6cda3
JA
107 > do
108 > echo $i
109 > done
726f6388
JA
110 Each line will be individually saved in the history.
111 bash$ history
112 10 for i in a b c
ccc6cda3
JA
113 11 do
114 12 echo $i
115 13 done
116 14 history
726f6388
JA
117 If the variable command_oriented_history is set, multiple lines
118 which form one command will be saved as one history entry.
119 bash$ for i in a b c
ccc6cda3
JA
120 > do
121 > echo $i
122 > done
123 bash$ history
726f6388
JA
124 10 for i in a b c
125 do
126 echo $i
127 done
ccc6cda3 128 11 history
726f6388
JA
129 The user can then recall the whole command all at once instead
130 of just being able to recall one line at a time.
7117c2d2
JA
131
132 This is now enabled by default.
726f6388 133 */
ccc6cda3
JA
134int command_oriented_history = 1;
135
7117c2d2
JA
136/* Set to 1 if the first line of a possibly-multi-line command was saved
137 in the history list. Managed by maybe_add_history(), but global so
138 the history-manipluating builtins can see it. */
139int current_command_first_line_saved = 0;
140
ccc6cda3
JA
141/* Non-zero means to store newlines in the history list when using
142 command_oriented_history rather than trying to use semicolons. */
143int literal_history;
144
145/* Non-zero means to append the history to the history file at shell
146 exit, even if the history has been stifled. */
147int force_append_history;
726f6388 148
b80f6443
JA
149/* A nit for picking at history saving. Flags have the following values:
150
151 Value == 0 means save all lines parsed by the shell on the history.
152 Value & HC_IGNSPACE means save all lines that do not start with a space.
153 Value & HC_IGNDUPS means save all lines that do not match the last
154 line saved.
155 Value & HC_ERASEDUPS means to remove all other matching lines from the
156 history list before saving the latest line. */
ccc6cda3
JA
157int history_control;
158
d166f048
JA
159/* Set to 1 if the last command was added to the history list successfully
160 as a separate history entry; set to 0 if the line was ignored or added
161 to a previous entry as part of command-oriented-history processing. */
162int hist_last_line_added;
163
95732b49
JA
164/* Set to 1 if builtins/history.def:push_history added the last history
165 entry. */
166int hist_last_line_pushed;
167
ccc6cda3
JA
168#if defined (READLINE)
169/* If non-zero, and readline is being used, the user is offered the
170 chance to re-edit a failed history expansion. */
171int history_reediting;
172
173/* If non-zero, and readline is being used, don't directly execute a
174 line with history substitution. Reload it into the editing buffer
175 instead and let the user further edit and confirm with a newline. */
176int hist_verify;
d166f048
JA
177
178#endif /* READLINE */
726f6388 179
f73dda09
JA
180/* Non-zero means to not save function definitions in the history list. */
181int dont_save_function_defs;
182
726f6388 183/* Variables declared in other files used here. */
726f6388 184extern int current_command_line_count;
726f6388 185
ccc6cda3
JA
186extern struct dstack dstack;
187
f73dda09
JA
188static int bash_history_inhibit_expansion __P((char *, int));
189#if defined (READLINE)
190static void re_edit __P((char *));
191#endif
192static int history_expansion_p __P((char *));
193static int shell_comment __P((char *));
194static int should_expand __P((char *));
195static HIST_ENTRY *last_history_entry __P((void));
196static char *expand_histignore_pattern __P((char *));
197static int history_should_ignore __P((char *));
ccc6cda3 198
d166f048
JA
199/* Is the history expansion starting at string[i] one that should not
200 be expanded? */
201static int
202bash_history_inhibit_expansion (string, i)
203 char *string;
204 int i;
205{
206 /* The shell uses ! as a pattern negation character in globbing [...]
207 expressions, so let those pass without expansion. */
208 if (i > 0 && (string[i - 1] == '[') && member (']', string + i + 1))
209 return (1);
210 /* The shell uses ! as the indirect expansion character, so let those
211 expansions pass as well. */
212 else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' &&
213 member ('}', string + i + 1))
214 return (1);
cce855bc
JA
215#if defined (EXTENDED_GLOB)
216 else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
217 return (1);
218#endif
d166f048
JA
219 else
220 return (0);
221}
222
ccc6cda3
JA
223void
224bash_initialize_history ()
225{
226 history_quotes_inhibit_expansion = 1;
227 history_search_delimiter_chars = ";&()|<>";
d166f048 228 history_inhibit_expansion_function = bash_history_inhibit_expansion;
95732b49 229#if defined (BANG_HISTORY)
b80f6443 230 sv_histchars ("histchars");
95732b49 231#endif
ccc6cda3
JA
232}
233
234void
235bash_history_reinit (interact)
236 int interact;
237{
238#if defined (BANG_HISTORY)
239 history_expansion = interact != 0;
240 history_expansion_inhibited = 1;
241#endif
f1be666c 242 remember_on_history = enable_history_list = interact != 0;
d166f048 243 history_inhibit_expansion_function = bash_history_inhibit_expansion;
ccc6cda3
JA
244}
245
246void
247bash_history_disable ()
248{
249 remember_on_history = 0;
250#if defined (BANG_HISTORY)
251 history_expansion_inhibited = 1;
252#endif
253}
254
255void
256bash_history_enable ()
257{
258 remember_on_history = 1;
259#if defined (BANG_HISTORY)
260 history_expansion_inhibited = 0;
261#endif
d166f048 262 history_inhibit_expansion_function = bash_history_inhibit_expansion;
ccc6cda3
JA
263 sv_history_control ("HISTCONTROL");
264 sv_histignore ("HISTIGNORE");
265}
726f6388
JA
266
267/* Load the history list from the history file. */
268void
269load_history ()
270{
271 char *hf;
272
273 /* Truncate history file for interactive shells which desire it.
274 Note that the history file is automatically truncated to the
275 size of HISTSIZE if the user does not explicitly set the size
276 differently. */
0628567a
JA
277 set_if_not ("HISTSIZE", "500");
278 sv_histsize ("HISTSIZE");
279
726f6388 280 set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
ccc6cda3 281 sv_histsize ("HISTFILESIZE");
726f6388
JA
282
283 /* Read the history in HISTFILE into the history list. */
284 hf = get_string_value ("HISTFILE");
285
3185942a 286 if (hf && *hf && file_exists (hf))
726f6388 287 {
ccc6cda3
JA
288 read_history (hf);
289 using_history ();
290 history_lines_in_file = where_history ();
726f6388
JA
291 }
292}
293
3185942a
JA
294void
295bash_clear_history ()
296{
297 clear_history ();
298 history_lines_this_session = 0;
299}
300
301/* Delete and free the history list entry at offset I. */
302int
303bash_delete_histent (i)
304 int i;
305{
306 HIST_ENTRY *discard;
307
308 discard = remove_history (i);
309 if (discard)
310 free_history_entry (discard);
311 history_lines_this_session--;
312
313 return 1;
314}
315
316int
317bash_delete_last_history ()
318{
319 register int i;
320 HIST_ENTRY **hlist, *histent;
321 int r;
322
323 hlist = history_list ();
324 if (hlist == NULL)
325 return 0;
326
327 for (i = 0; hlist[i]; i++)
328 ;
329 i--;
330
331 /* History_get () takes a parameter that must be offset by history_base. */
332 histent = history_get (history_base + i); /* Don't free this */
333 if (histent == NULL)
334 return 0;
335
336 r = bash_delete_histent (i);
337
338 if (where_history () > history_length)
339 history_set_pos (history_length);
340
341 return r;
342}
343
d166f048 344#ifdef INCLUDE_UNUSED
726f6388
JA
345/* Write the existing history out to the history file. */
346void
347save_history ()
348{
ccc6cda3 349 char *hf;
726f6388 350
ccc6cda3 351 hf = get_string_value ("HISTFILE");
3185942a 352 if (hf && *hf && file_exists (hf))
726f6388 353 {
ccc6cda3
JA
354 /* Append only the lines that occurred this session to
355 the history file. */
356 using_history ();
726f6388 357
ccc6cda3
JA
358 if (history_lines_this_session < where_history () || force_append_history)
359 append_history (history_lines_this_session, hf);
360 else
361 write_history (hf);
ccc6cda3
JA
362 sv_histsize ("HISTFILESIZE");
363 }
364}
d166f048 365#endif
ccc6cda3
JA
366
367int
368maybe_append_history (filename)
369 char *filename;
370{
371 int fd, result;
372 struct stat buf;
373
374 result = EXECUTION_SUCCESS;
375 if (history_lines_this_session && (history_lines_this_session < where_history ()))
376 {
377 /* If the filename was supplied, then create it if necessary. */
378 if (stat (filename, &buf) == -1 && errno == ENOENT)
379 {
b72432fd 380 fd = open (filename, O_WRONLY|O_CREAT, 0600);
ccc6cda3
JA
381 if (fd < 0)
382 {
b80f6443 383 builtin_error (_("%s: cannot create: %s"), filename, strerror (errno));
ccc6cda3
JA
384 return (EXECUTION_FAILURE);
385 }
386 close (fd);
726f6388 387 }
ccc6cda3
JA
388 result = append_history (history_lines_this_session, filename);
389 history_lines_in_file += history_lines_this_session;
390 history_lines_this_session = 0;
726f6388 391 }
ccc6cda3 392 return (result);
726f6388
JA
393}
394
395/* If this is an interactive shell, then append the lines executed
396 this session to the history file. */
397int
398maybe_save_shell_history ()
399{
ccc6cda3
JA
400 int result;
401 char *hf;
726f6388 402
ccc6cda3 403 result = 0;
726f6388
JA
404 if (history_lines_this_session)
405 {
ccc6cda3 406 hf = get_string_value ("HISTFILE");
726f6388
JA
407
408 if (hf && *hf)
409 {
726f6388 410 /* If the file doesn't exist, then create it. */
3185942a 411 if (file_exists (hf) == 0)
726f6388 412 {
ccc6cda3 413 int file;
b72432fd 414 file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
726f6388
JA
415 if (file != -1)
416 close (file);
417 }
418
419 /* Now actually append the lines if the history hasn't been
420 stifled. If the history has been stifled, rewrite the
421 history file. */
422 using_history ();
ccc6cda3 423 if (history_lines_this_session <= where_history () || force_append_history)
726f6388
JA
424 {
425 result = append_history (history_lines_this_session, hf);
426 history_lines_in_file += history_lines_this_session;
427 }
428 else
429 {
430 result = write_history (hf);
431 history_lines_in_file = history_lines_this_session;
432 }
433 history_lines_this_session = 0;
ccc6cda3
JA
434
435 sv_histsize ("HISTFILESIZE");
726f6388
JA
436 }
437 }
438 return (result);
439}
440
ccc6cda3 441#if defined (READLINE)
726f6388
JA
442/* Tell readline () that we have some text for it to edit. */
443static void
444re_edit (text)
445 char *text;
446{
ccc6cda3 447 if (bash_input.type == st_stdin)
726f6388 448 bash_re_edit (text);
ccc6cda3 449}
726f6388 450#endif /* READLINE */
ccc6cda3
JA
451
452/* Return 1 if this line needs history expansion. */
453static int
454history_expansion_p (line)
455 char *line;
456{
457 register char *s;
458
459 for (s = line; *s; s++)
460 if (*s == history_expansion_char || *s == history_subst_char)
461 return 1;
462 return 0;
726f6388 463}
726f6388
JA
464
465/* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then
466 print the results of expanding the line if there were any changes.
467 If there is an error, return NULL, otherwise the expanded line is
468 returned. If ADDIT is non-zero the line is added to the history
469 list after history expansion. ADDIT is just a suggestion;
470 REMEMBER_ON_HISTORY can veto, and does.
471 Right now this does history expansion. */
472char *
473pre_process_line (line, print_changes, addit)
474 char *line;
475 int print_changes, addit;
476{
477 char *history_value;
478 char *return_value;
ccc6cda3 479 int expanded;
726f6388
JA
480
481 return_value = line;
ccc6cda3 482 expanded = 0;
726f6388
JA
483
484# if defined (BANG_HISTORY)
485 /* History expand the line. If this results in no errors, then
486 add that line to the history if ADDIT is non-zero. */
ccc6cda3 487 if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
726f6388
JA
488 {
489 expanded = history_expand (line, &history_value);
490
491 if (expanded)
492 {
493 if (print_changes)
494 {
495 if (expanded < 0)
cce855bc 496 internal_error ("%s", history_value);
d166f048 497#if defined (READLINE)
bb70624e 498 else if (hist_verify == 0 || expanded == 2)
d166f048
JA
499#else
500 else
501#endif
726f6388
JA
502 fprintf (stderr, "%s\n", history_value);
503 }
504
505 /* If there was an error, return NULL. */
506 if (expanded < 0 || expanded == 2) /* 2 == print only */
507 {
b80f6443
JA
508# if defined (READLINE)
509 if (expanded == 2 && rl_dispatching == 0 && *history_value)
510# else
511 if (expanded == 2 && *history_value)
512# endif /* !READLINE */
513 maybe_add_history (history_value);
514
726f6388
JA
515 free (history_value);
516
ccc6cda3 517# if defined (READLINE)
726f6388
JA
518 /* New hack. We can allow the user to edit the
519 failed history expansion. */
b80f6443 520 if (history_reediting && expanded < 0 && rl_done)
ccc6cda3
JA
521 re_edit (line);
522# endif /* READLINE */
523 return ((char *)NULL);
524 }
525
526# if defined (READLINE)
527 if (hist_verify && expanded == 1)
528 {
529 re_edit (history_value);
726f6388
JA
530 return ((char *)NULL);
531 }
ccc6cda3 532# endif
726f6388
JA
533 }
534
535 /* Let other expansions know that return_value can be free'ed,
536 and that a line has been added to the history list. Note
537 that we only add lines that have something in them. */
538 expanded = 1;
539 return_value = history_value;
540 }
541# endif /* BANG_HISTORY */
542
543 if (addit && remember_on_history && *return_value)
544 maybe_add_history (return_value);
545
d166f048 546#if 0
ccc6cda3 547 if (expanded == 0)
726f6388 548 return_value = savestring (line);
d166f048 549#endif
726f6388
JA
550
551 return (return_value);
552}
553
bb70624e
JA
554/* Return 1 if the first non-whitespace character in LINE is a `#', indicating
555 * that the line is a shell comment. */
556static int
557shell_comment (line)
558 char *line;
559{
560 char *p;
561
562 for (p = line; p && *p && whitespace (*p); p++)
563 ;
564 return (p && *p == '#');
565}
566
f73dda09 567#ifdef INCLUDE_UNUSED
bb70624e
JA
568/* Remove shell comments from LINE. A `#' and anything after it is a comment.
569 This isn't really useful yet, since it doesn't handle quoting. */
570static char *
571filter_comments (line)
572 char *line;
573{
574 char *p;
575
576 for (p = line; p && *p && *p != '#'; p++)
577 ;
578 if (p && *p == '#')
579 *p = '\0';
580 return (line);
581}
f73dda09 582#endif
bb70624e 583
7117c2d2
JA
584/* Check LINE against what HISTCONTROL says to do. Returns 1 if the line
585 should be saved; 0 if it should be discarded. */
586static int
587check_history_control (line)
726f6388
JA
588 char *line;
589{
ccc6cda3 590 HIST_ENTRY *temp;
7117c2d2 591 int r;
ccc6cda3 592
b80f6443
JA
593 if (history_control == 0)
594 return 1;
595
596 /* ignorespace or ignoreboth */
597 if ((history_control & HC_IGNSPACE) && *line == ' ')
598 return 0;
599
600 /* ignoredups or ignoreboth */
601 if (history_control & HC_IGNDUPS)
7117c2d2 602 {
7117c2d2
JA
603 using_history ();
604 temp = previous_history ();
605
606 r = (temp == 0 || STREQ (temp->line, line) == 0);
607
608 using_history ();
b80f6443
JA
609
610 if (r == 0)
611 return r;
7117c2d2
JA
612 }
613
b80f6443
JA
614 return 1;
615}
616
617/* Remove all entries matching LINE from the history list. Triggered when
618 HISTCONTROL includes `erasedups'. */
619static void
620hc_erasedups (line)
621 char *line;
622{
623 HIST_ENTRY *temp;
624 int r;
625
626 using_history ();
627 while (temp = previous_history ())
628 {
629 if (STREQ (temp->line, line))
630 {
631 r = where_history ();
632 remove_history (r);
633 }
634 }
635 using_history ();
7117c2d2
JA
636}
637
638/* Add LINE to the history list, handling possibly multi-line compound
639 commands. We note whether or not we save the first line of each command
640 (which is usually the entire command and history entry), and don't add
641 the second and subsequent lines of a multi-line compound command if we
642 didn't save the first line. We don't usually save shell comment lines in
643 compound commands in the history, because they could have the effect of
644 commenting out the rest of the command when the entire command is saved as
645 a single history entry (when COMMAND_ORIENTED_HISTORY is enabled). If
646 LITERAL_HISTORY is set, we're saving lines in the history with embedded
647 newlines, so it's OK to save comment lines. We also make sure to save
648 multiple-line quoted strings or other constructs. */
649void
650maybe_add_history (line)
651 char *line;
652{
28ef6c31 653 hist_last_line_added = 0;
726f6388
JA
654
655 /* Don't use the value of history_control to affect the second
cce855bc
JA
656 and subsequent lines of a multi-line command (old code did
657 this only when command_oriented_history is enabled). */
cce855bc 658 if (current_command_line_count > 1)
ccc6cda3 659 {
7117c2d2 660 if (current_command_first_line_saved &&
28ef6c31 661 (literal_history || dstack.delimiter_depth != 0 || shell_comment (line) == 0))
bb70624e 662 bash_add_history (line);
ccc6cda3
JA
663 return;
664 }
726f6388 665
28ef6c31
JA
666 /* This is the first line of a (possible multi-line) command. Note whether
667 or not we should save the first line and remember it. */
7117c2d2
JA
668 current_command_first_line_saved = check_add_history (line, 0);
669}
28ef6c31 670
7117c2d2
JA
671/* Just check LINE against HISTCONTROL and HISTIGNORE and add it to the
672 history if it's OK. Used by `history -s' as well as maybe_add_history().
673 Returns 1 if the line was saved in the history, 0 otherwise. */
674int
675check_add_history (line, force)
676 char *line;
677 int force;
678{
679 if (check_history_control (line) && history_should_ignore (line) == 0)
726f6388 680 {
b80f6443
JA
681 /* We're committed to saving the line. If the user has requested it,
682 remove other matching lines from the history. */
683 if (history_control & HC_ERASEDUPS)
684 hc_erasedups (line);
685
7117c2d2
JA
686 if (force)
687 {
688 really_add_history (line);
689 using_history ();
690 }
691 else
692 bash_add_history (line);
693 return 1;
726f6388 694 }
7117c2d2 695 return 0;
726f6388
JA
696}
697
0001803f
CR
698#if defined (SYSLOG_HISTORY)
699#define SYSLOG_MAXLEN 600
700
701void
702bash_syslog_history (line)
703 const char *line;
704{
705 char trunc[SYSLOG_MAXLEN];
706
707 if (strlen(line) < SYSLOG_MAXLEN)
708 syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY: PID=%d UID=%d %s", getpid(), current_user.uid, line);
709 else
710 {
711 strncpy (trunc, line, SYSLOG_MAXLEN);
712 trunc[SYSLOG_MAXLEN - 1] = '\0';
713 syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY (TRUNCATED): PID=%d UID=%d %s", getpid(), current_user.uid, trunc);
714 }
715}
716#endif
717
726f6388
JA
718/* Add a line to the history list.
719 The variable COMMAND_ORIENTED_HISTORY controls the style of history
720 remembering; when non-zero, and LINE is not the first line of a
721 complete parser construct, append LINE to the last history line instead
722 of adding it as a new line. */
d166f048 723void
726f6388
JA
724bash_add_history (line)
725 char *line;
726{
ccc6cda3
JA
727 int add_it, offset, curlen;
728 HIST_ENTRY *current, *old;
729 char *chars_to_add, *new_line;
726f6388 730
ccc6cda3 731 add_it = 1;
726f6388
JA
732 if (command_oriented_history && current_command_line_count > 1)
733 {
ccc6cda3 734 chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
726f6388
JA
735
736 using_history ();
726f6388
JA
737 current = previous_history ();
738
739 if (current)
740 {
741 /* If the previous line ended with an escaped newline (escaped
742 with backslash, but otherwise unquoted), then remove the quoted
743 newline, since that is what happens when the line is parsed. */
726f6388
JA
744 curlen = strlen (current->line);
745
ccc6cda3 746 if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
726f6388
JA
747 current->line[curlen - 2] != '\\')
748 {
749 current->line[curlen - 1] = '\0';
750 curlen--;
751 chars_to_add = "";
752 }
753
f73dda09
JA
754 new_line = (char *)xmalloc (1
755 + curlen
756 + strlen (line)
757 + strlen (chars_to_add));
726f6388 758 sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
ccc6cda3 759 offset = where_history ();
726f6388
JA
760 old = replace_history_entry (offset, new_line, current->data);
761 free (new_line);
762
763 if (old)
b80f6443
JA
764 free_history_entry (old);
765
726f6388
JA
766 add_it = 0;
767 }
768 }
769
770 if (add_it)
7117c2d2
JA
771 really_add_history (line);
772
0001803f
CR
773#if defined (SYSLOG_HISTORY)
774 bash_syslog_history (line);
775#endif
776
726f6388
JA
777 using_history ();
778}
779
7117c2d2
JA
780static void
781really_add_history (line)
782 char *line;
783{
784 hist_last_line_added = 1;
95732b49 785 hist_last_line_pushed = 0;
7117c2d2
JA
786 add_history (line);
787 history_lines_this_session++;
788}
789
726f6388
JA
790int
791history_number ()
792{
793 using_history ();
95732b49 794 return (remember_on_history ? history_base + where_history () : 1);
ccc6cda3
JA
795}
796
797static int
798should_expand (s)
799 char *s;
800{
801 char *p;
802
803 for (p = s; p && *p; p++)
804 {
805 if (*p == '\\')
806 p++;
807 else if (*p == '&')
808 return 1;
809 }
810 return 0;
811}
812
813static int
814histignore_item_func (ign)
815 struct ign *ign;
816{
817 if (should_expand (ign->val))
818 ign->flags |= HIGN_EXPAND;
819 return (0);
820}
821
822void
823setup_history_ignore (varname)
824 char *varname;
825{
826 setup_ignore_patterns (&histignore);
827}
828
829static HIST_ENTRY *
830last_history_entry ()
831{
832 HIST_ENTRY *he;
833
834 using_history ();
835 he = previous_history ();
836 using_history ();
837 return he;
838}
839
840char *
841last_history_line ()
842{
843 HIST_ENTRY *he;
844
845 he = last_history_entry ();
846 if (he == 0)
847 return ((char *)NULL);
848 return he->line;
849}
850
851static char *
852expand_histignore_pattern (pat)
853 char *pat;
854{
855 HIST_ENTRY *phe;
bb70624e 856 char *ret;
ccc6cda3
JA
857
858 phe = last_history_entry ();
859
860 if (phe == (HIST_ENTRY *)0)
861 return (savestring (pat));
862
bb70624e 863 ret = strcreplace (pat, '&', phe->line, 1);
ccc6cda3 864
ccc6cda3
JA
865 return ret;
866}
867
868/* Return 1 if we should not put LINE into the history according to the
869 patterns in HISTIGNORE. */
870static int
871history_should_ignore (line)
872 char *line;
873{
874 register int i, match;
875 char *npat;
876
877 if (histignore.num_ignores == 0)
878 return 0;
879
880 for (i = match = 0; i < histignore.num_ignores; i++)
881 {
882 if (histignore.ignores[i].flags & HIGN_EXPAND)
883 npat = expand_histignore_pattern (histignore.ignores[i].val);
884 else
885 npat = histignore.ignores[i].val;
886
f73dda09 887 match = strmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH;
ccc6cda3
JA
888
889 if (histignore.ignores[i].flags & HIGN_EXPAND)
890 free (npat);
891
892 if (match)
893 break;
894 }
895
896 return match;
726f6388 897}
ccc6cda3 898#endif /* HISTORY */