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