1 This file is fc.def, from which is created fc.c.
2 It implements the builtin "fc" in Bash.
4 Copyright (C) 1987-2011 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
8 Bash is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
26 $SHORT_DOC fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]
27 Display or execute commands from the history list.
29 fc is used to list or edit and re-execute commands from the history list.
30 FIRST and LAST can be numbers specifying the range, or FIRST can be a
31 string, which means the most recent command beginning with that
35 -e ENAME select which editor to use. Default is FCEDIT, then EDITOR,
37 -l list lines instead of editing
38 -n omit line numbers when listing
39 -r reverse the order of the lines (newest listed first)
41 With the `fc -s [pat=rep ...] [command]' format, COMMAND is
42 re-executed after the substitution OLD=NEW is performed.
44 A useful alias to use with this is r='fc -s', so that typing `r cc'
45 runs the last command beginning with `cc' and typing `r' re-executes
49 Returns success or status of executed command; non-zero if an error occurs.
55 #if defined (HAVE_SYS_PARAM_H)
56 # include <sys/param.h>
58 #include "../bashtypes.h"
59 #include "posixstat.h"
60 #if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
61 # include <sys/file.h>
64 #if defined (HAVE_UNISTD_H)
69 #include <chartypes.h>
71 #include "../bashansi.h"
72 #include "../bashintl.h"
76 #include "../builtins.h"
78 #include "../bashhist.h"
80 #include <readline/history.h>
81 #include "bashgetopt.h"
88 extern int current_command_line_count;
89 extern int literal_history;
90 extern int posixly_correct;
91 extern int subshell_environment, interactive_shell;
93 extern int unlink __P((const char *));
95 extern FILE *sh_mktmpfp __P((char *, int, char **));
97 /* **************************************************************** */
99 /* The K*rn shell style fc command (Fix Command) */
101 /* **************************************************************** */
103 /* fc builtin command (fix command) for Bash for those who
104 like K*rn-style history better than csh-style.
106 fc [-e ename] [-nlr] [first] [last]
108 FIRST and LAST can be numbers specifying the range, or FIRST can be
109 a string, which means the most recent command beginning with that
112 -e ENAME selects which editor to use. Default is FCEDIT, then EDITOR,
113 then the editor which corresponds to the current readline editing
116 -l means list lines instead of editing.
117 -n means no line numbers listed.
118 -r means reverse the order of the lines (making it newest listed first).
120 fc -e - [pat=rep ...] [command]
121 fc -s [pat=rep ...] [command]
123 Equivalent to !command:sg/pat/rep execpt there can be multiple PAT=REP's.
126 /* Data structure describing a list of global replacements to perform. */
127 typedef struct repl {
133 /* Accessors for HIST_ENTRY lists that are called HLIST. */
134 #define histline(i) (hlist[(i)]->line)
135 #define histdata(i) (hlist[(i)]->data)
137 #define FREE_RLIST() \
139 for (rl = rlist; rl; ) { \
151 static char *fc_dosubs __P((char *, REPL *));
152 static char *fc_gethist __P((char *, HIST_ENTRY **));
153 static int fc_gethnum __P((char *, HIST_ENTRY **));
154 static int fc_number __P((WORD_LIST *));
155 static void fc_replhist __P((char *));
156 #ifdef INCLUDE_UNUSED
157 static char *fc_readline __P((FILE *));
158 static void fc_addhist __P((char *));
161 /* String to execute on a file that we want to edit. */
162 #define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}"
163 #if defined (STRICT_POSIX)
164 # define POSIX_FC_EDIT_COMMAND "${FCEDIT:-ed}"
166 # define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"
175 int numbering, reverse, listing, execute;
176 int histbeg, histend, last_hist, retval, opt, rh, real_last;
179 char *ename, *command, *newcom, *fcedit;
184 reverse = listing = execute = 0;
185 ename = (char *)NULL;
187 /* Parse out the options and set which of the two forms we're in. */
188 reset_internal_getopt ();
189 lcurrent = list; /* XXX */
190 while (fc_number (loptend = lcurrent) == 0 &&
191 (opt = internal_getopt (list, ":e:lnrs")) != -1)
223 if (ename && (*ename == '-') && (ename[1] == '\0'))
226 /* The "execute" form of the command (re-run, with possible string
230 rlist = (REPL *)NULL;
231 while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL))
234 rl = (REPL *)xmalloc (sizeof (REPL));
235 rl->next = (REPL *)NULL;
236 rl->pat = savestring (list->word->word);
237 rl->rep = savestring (sep);
249 /* If we have a list of substitutions to do, then reverse it
250 to get the replacements in the proper order. */
252 rlist = REVERSE_LIST (rlist, REPL *);
254 hlist = history_list ();
256 /* If we still have something in list, it is a command spec.
257 Otherwise, we use the most recent command in time. */
258 command = fc_gethist (list ? list->word->word : (char *)NULL, hlist);
262 builtin_error (_("no command found"));
266 return (EXECUTION_FAILURE);
271 newcom = fc_dosubs (command, rlist);
277 fprintf (stderr, "%s\n", command);
278 fc_replhist (command); /* replace `fc -s' with command */
279 /* Posix says that the re-executed commands should be entered into the
281 return (parse_and_execute (command, "fc", SEVAL_NOHIST));
284 /* This is the second form of the command (the list-or-edit-and-rerun
286 hlist = history_list ();
288 return (EXECUTION_SUCCESS);
289 for (i = 0; hlist[i]; i++);
291 /* With the Bash implementation of history, the current command line
292 ("fc blah..." and so on) is already part of the history list by
293 the time we get to this point. This just skips over that command
294 and makes the last command that this deals with be the last command
295 the user entered before the fc. We need to check whether the
296 line was actually added (HISTIGNORE may have caused it to not be),
297 so we check hist_last_line_added. */
299 /* Even though command substitution through parse_and_execute turns off
300 remember_on_history, command substitution in a shell when set -o history
301 has been enabled (interactive or not) should use it in the last_hist
302 calculation as if it were on. */
303 rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
304 last_hist = i - rh - hist_last_line_added;
306 /* Make sure that real_last is calculated the same way here and in
307 fc_gethnum. The return value from fc_gethnum is treated specially if
308 it is == real_last and we are listing commands. */
310 /* back up from the end to the last non-null history entry */
311 while (hlist[real_last] == 0 && real_last > 0)
315 if (i == last_hist && hlist[last_hist] == 0)
316 while (last_hist >= 0 && hlist[last_hist] == 0)
320 sh_erange ((char *)NULL, _("history specification"));
321 return (EXECUTION_FAILURE);
326 histbeg = fc_gethnum (list->word->word, hlist);
330 histend = fc_gethnum (list->word->word, hlist);
331 else if (histbeg == real_last)
332 histend = listing ? real_last : histbeg;
334 histend = listing ? last_hist : histbeg;
338 /* The default for listing is the last 16 history items. */
342 histbeg = histend - 16 + 1; /* +1 because loop below uses >= */
347 /* For editing, it is the last history command. */
348 histbeg = histend = last_hist;
351 /* "When not listing, the fc command that caused the editing shall not be
352 entered into the history list." */
353 if (listing == 0 && hist_last_line_added)
355 bash_delete_last_history ();
356 /* If we're editing a single command -- the last command in the
357 history -- and we just removed the dummy command added by
358 edit_and_execute_command (), we need to check whether or not we
359 just removed the last command in the history and need to back
360 the pointer up. remember_on_history is off because we're running
361 in parse_and_execute(). */
362 if (histbeg == histend && histend == last_hist && hlist[last_hist] == 0)
363 last_hist = histbeg = --histend;
366 /* We print error messages for line specifications out of range. */
367 if ((histbeg < 0) || (histend < 0))
369 sh_erange ((char *)NULL, _("history specification"));
370 return (EXECUTION_FAILURE);
373 if (histend < histbeg)
387 stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn);
390 builtin_error (_("%s: cannot open temp file: %s"), fn ? fn : "", strerror (errno));
392 return (EXECUTION_FAILURE);
396 for (i = reverse ? histend : histbeg; reverse ? i >= histbeg : i <= histend; reverse ? i-- : i++)
400 fprintf (stream, "%d", i + history_base);
404 fputs ("\t", stream);
406 fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
408 fprintf (stream, "%s\n", histline (i));
412 return (sh_chkwrite (EXECUTION_SUCCESS));
419 return (EXECUTION_FAILURE);
423 /* Now edit the file of commands. */
426 command = (char *)xmalloc (strlen (ename) + strlen (fn) + 2);
427 sprintf (command, "%s %s", ename, fn);
431 fcedit = posixly_correct ? POSIX_FC_EDIT_COMMAND : FC_EDIT_COMMAND;
432 command = (char *)xmalloc (3 + strlen (fcedit) + strlen (fn));
433 sprintf (command, "%s %s", fcedit, fn);
435 retval = parse_and_execute (command, "fc", SEVAL_NOHIST);
436 if (retval != EXECUTION_SUCCESS)
440 return (EXECUTION_FAILURE);
443 /* Make sure parse_and_execute doesn't turn this off, even though a
444 call to parse_and_execute farther up the function call stack (e.g.,
445 if this is called by vi_edit_and_execute_command) may have already
446 called bash_history_disable. */
447 remember_on_history = 1;
449 /* Turn on the `v' flag while fc_execute_file runs so the commands
450 will be echoed as they are read by the parser. */
451 begin_unwind_frame ("fc builtin");
452 add_unwind_protect ((Function *)xfree, fn);
453 add_unwind_protect (unlink, fn);
454 unwind_protect_int (echo_input_at_read);
455 echo_input_at_read = 1;
457 retval = fc_execute_file (fn);
459 run_unwind_frame ("fc builtin");
464 /* Return 1 if LIST->word->word is a legal number for fc's use. */
473 s = list->word->word;
476 return (legal_number (s, (intmax_t *)NULL));
479 /* Return an absolute index into HLIST which corresponds to COMMAND. If
480 COMMAND is a number, then it was specified in relative terms. If it
481 is a string, then it is the start of a command line present in HLIST. */
483 fc_gethnum (command, hlist)
487 int sign, n, clen, rh;
488 register int i, j, last_hist, real_last;
492 /* Count history elements. */
493 for (i = 0; hlist[i]; i++);
495 /* With the Bash implementation of history, the current command line
496 ("fc blah..." and so on) is already part of the history list by
497 the time we get to this point. This just skips over that command
498 and makes the last command that this deals with be the last command
499 the user entered before the fc. We need to check whether the
500 line was actually added (HISTIGNORE may have caused it to not be),
501 so we check hist_last_line_added. This needs to agree with the
502 calculation of last_hist in fc_builtin above. */
503 /* Even though command substitution through parse_and_execute turns off
504 remember_on_history, command substitution in a shell when set -o history
505 has been enabled (interactive or not) should use it in the last_hist
506 calculation as if it were on. */
507 rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
508 last_hist = i - rh - hist_last_line_added;
510 if (i == last_hist && hlist[last_hist] == 0)
511 while (last_hist >= 0 && hlist[last_hist] == 0)
519 /* No specification defaults to most recent command. */
523 /* back up from the end to the last non-null history entry */
524 while (hlist[real_last] == 0 && real_last > 0)
527 /* Otherwise, there is a specification. It can be a number relative to
528 the current position, or an absolute history number. */
531 /* Handle possible leading minus sign. */
532 if (s && (*s == '-'))
543 /* If the value is negative or zero, then it is an offset from
544 the current history item. */
548 return (n < 0 ? 0 : n);
551 return ((sign == -1) ? real_last : i);
555 return (i < n ? i : n);
559 clen = strlen (command);
560 for (j = i; j >= 0; j--)
562 if (STREQN (command, histline (j), clen))
568 /* Locate the most recent history line which begins with
569 COMMAND in HLIST, and return a malloc()'ed copy of it. */
571 fc_gethist (command, hlist)
578 return ((char *)NULL);
580 i = fc_gethnum (command, hlist);
583 return (savestring (histline (i)));
585 return ((char *)NULL);
588 #ifdef INCLUDE_UNUSED
589 /* Read the edited history lines from STREAM and return them
590 one at a time. This can read unlimited length lines. The
591 caller should free the storage. */
597 int line_len = 0, lindex = 0;
598 char *line = (char *)NULL;
600 while ((c = getc (stream)) != EOF)
602 if ((lindex + 2) >= line_len)
603 line = (char *)xrealloc (line, (line_len += 128));
607 line[lindex++] = '\n';
608 line[lindex++] = '\0';
620 return ((char *)NULL);
623 if (lindex + 2 >= line_len)
624 line = (char *)xrealloc (line, lindex + 3);
626 line[lindex++] = '\n'; /* Finish with newline if none in file */
627 line[lindex++] = '\0';
632 /* Perform the SUBS on COMMAND.
633 SUBS is a list of substitutions, and COMMAND is a simple string.
634 Return a pointer to a malloc'ed string which contains the substituted
637 fc_dosubs (command, subs)
641 register char *new, *t;
644 for (new = savestring (command), r = subs; r; r = r->next)
646 t = strsub (new, r->pat, r->rep, 1);
653 /* Use `command' to replace the last entry in the history list, which,
654 by this time, is `fc blah...'. The intent is that the new command
655 become the history entry, and that `fc' should never appear in the
656 history list. This way you can do `r' to your heart's content. */
658 fc_replhist (command)
663 if (command == 0 || *command == '\0')
666 n = strlen (command);
667 if (command[n - 1] == '\n')
668 command[n - 1] = '\0';
670 if (command && *command)
672 bash_delete_last_history ();
673 maybe_add_history (command); /* Obeys HISTCONTROL setting. */
677 #ifdef INCLUDE_UNUSED
678 /* Add LINE to the history, after removing a single trailing newline. */
685 if (line == 0 || *line == 0)
690 if (line[n - 1] == '\n')
694 maybe_add_history (line); /* Obeys HISTCONTROL setting. */