1 This file is fc.def, from which is created fc.c.
2 It implements the builtin "fc" in Bash.
4 Copyright (C) 1987-2002 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 it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING. If not, write to the Free Software
20 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
27 $SHORT_DOC fc [-e ename] [-nlr] [first] [last] or fc -s [pat=rep] [cmd]
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
34 -e ENAME selects which editor to use. Default is FCEDIT, then EDITOR,
37 -l means list lines instead of editing.
38 -n means no line numbers listed.
39 -r means reverse the order of the lines (making it newest listed first).
41 With the `fc -s [pat=rep ...] [command]' format, the 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
53 # include <sys/param.h>
55 #include "../bashtypes.h"
56 #include "posixstat.h"
58 # include <sys/file.h>
61 #if defined (HAVE_UNISTD_H)
66 #include <chartypes.h>
68 #include "../bashansi.h"
72 #include "../builtins.h"
74 #include "../bashhist.h"
76 #include <readline/history.h>
77 #include "bashgetopt.h"
84 extern int echo_input_at_read;
85 extern int current_command_line_count;
86 extern int literal_history;
88 extern int unlink __P((const char *));
90 extern FILE *sh_mktmpfp __P((char *, int, char **));
92 /* **************************************************************** */
94 /* The K*rn shell style fc command (Fix Command) */
96 /* **************************************************************** */
98 /* fc builtin command (fix command) for Bash for those who
99 like K*rn-style history better than csh-style.
101 fc [-e ename] [-nlr] [first] [last]
103 FIRST and LAST can be numbers specifying the range, or FIRST can be
104 a string, which means the most recent command beginning with that
107 -e ENAME selects which editor to use. Default is FCEDIT, then EDITOR,
108 then the editor which corresponds to the current readline editing
111 -l means list lines instead of editing.
112 -n means no line numbers listed.
113 -r means reverse the order of the lines (making it newest listed first).
115 fc -e - [pat=rep ...] [command]
116 fc -s [pat=rep ...] [command]
118 Equivalent to !command:sg/pat/rep execpt there can be multiple PAT=REP's.
121 /* Data structure describing a list of global replacements to perform. */
122 typedef struct repl {
128 /* Accessors for HIST_ENTRY lists that are called HLIST. */
129 #define histline(i) (hlist[(i)]->line)
130 #define histdata(i) (hlist[(i)]->data)
132 #define FREE_RLIST() \
134 for (rl = rlist; rl; ) { \
146 static char *fc_dosubs __P((char *, REPL *));
147 static char *fc_gethist __P((char *, HIST_ENTRY **));
148 static int fc_gethnum __P((char *, HIST_ENTRY **));
149 static int fc_number __P((WORD_LIST *));
150 static void fc_replhist __P((char *));
151 #ifdef INCLUDE_UNUSED
152 static char *fc_readline __P((FILE *));
153 static void fc_addhist __P((char *));
156 /* String to execute on a file that we want to edit. */
157 #define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}"
165 int numbering, reverse, listing, execute;
166 int histbeg, histend, last_hist, retval, opt;
169 char *ename, *command, *newcom;
174 reverse = listing = execute = 0;
175 ename = (char *)NULL;
177 /* Parse out the options and set which of the two forms we're in. */
178 reset_internal_getopt ();
179 lcurrent = list; /* XXX */
180 while (fc_number (loptend = lcurrent) == 0 &&
181 (opt = internal_getopt (list, ":e:lnrs")) != -1)
213 if (ename && (*ename == '-') && (ename[1] == '\0'))
216 /* The "execute" form of the command (re-run, with possible string
220 rlist = (REPL *)NULL;
221 while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL))
224 rl = (REPL *)xmalloc (sizeof (REPL));
225 rl->next = (REPL *)NULL;
226 rl->pat = savestring (list->word->word);
227 rl->rep = savestring (sep);
239 /* If we have a list of substitutions to do, then reverse it
240 to get the replacements in the proper order. */
242 rlist = REVERSE_LIST (rlist, REPL *);
244 hlist = history_list ();
246 /* If we still have something in list, it is a command spec.
247 Otherwise, we use the most recent command in time. */
248 command = fc_gethist (list ? list->word->word : (char *)NULL, hlist);
252 builtin_error ("no command found");
256 return (EXECUTION_FAILURE);
261 newcom = fc_dosubs (command, rlist);
267 fprintf (stderr, "%s\n", command);
268 fc_replhist (command); /* replace `fc -s' with command */
269 return (parse_and_execute (command, "fc", SEVAL_NOHIST));
272 /* This is the second form of the command (the list-or-edit-and-rerun
274 hlist = history_list ();
276 return (EXECUTION_SUCCESS);
277 for (i = 0; hlist[i]; i++);
279 /* With the Bash implementation of history, the current command line
280 ("fc blah..." and so on) is already part of the history list by
281 the time we get to this point. This just skips over that command
282 and makes the last command that this deals with be the last command
283 the user entered before the fc. We need to check whether the
284 line was actually added (HISTIGNORE may have caused it to not be),
285 so we check hist_last_line_added. */
287 last_hist = i - 1 - hist_last_line_added;
291 histbeg = fc_gethnum (list->word->word, hlist);
295 histend = fc_gethnum (list->word->word, hlist);
297 histend = listing ? last_hist : histbeg;
301 /* The default for listing is the last 16 history items. */
305 histbeg = histend - 16;
310 /* For editing, it is the last history command. */
311 histbeg = histend = last_hist;
314 /* We print error messages for line specifications out of range. */
315 if ((histbeg < 0) || (histend < 0))
317 sh_erange ((char *)NULL, "history specification");
318 return (EXECUTION_FAILURE);
321 if (histend < histbeg)
335 stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn);
338 builtin_error ("cannot open temp file %s", fn ? fn : "");
340 return (EXECUTION_FAILURE);
344 for (i = reverse ? histend : histbeg; reverse ? i >= histbeg : i <= histend; reverse ? i-- : i++)
348 fprintf (stream, "%d", i + history_base);
350 fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
351 fprintf (stream, "%s\n", histline (i));
355 return (EXECUTION_SUCCESS);
359 /* Now edit the file of commands. */
362 command = (char *)xmalloc (strlen (ename) + strlen (fn) + 2);
363 sprintf (command, "%s %s", ename, fn);
367 command = (char *)xmalloc (3 + strlen (FC_EDIT_COMMAND) + strlen (fn));
368 sprintf (command, "%s %s", FC_EDIT_COMMAND, fn);
370 retval = parse_and_execute (command, "fc", SEVAL_NOHIST);
371 if (retval != EXECUTION_SUCCESS)
375 return (EXECUTION_FAILURE);
378 /* Make sure parse_and_execute doesn't turn this off, even though a
379 call to parse_and_execute farther up the function call stack (e.g.,
380 if this is called by vi_edit_and_execute_command) may have already
381 called bash_history_disable. */
382 remember_on_history = 1;
384 /* Turn on the `v' flag while fc_execute_file runs so the commands
385 will be echoed as they are read by the parser. */
386 begin_unwind_frame ("fc builtin");
387 add_unwind_protect ((Function *)xfree, fn);
388 add_unwind_protect (unlink, fn);
389 unwind_protect_int (echo_input_at_read);
390 echo_input_at_read = 1;
392 retval = fc_execute_file (fn);
394 run_unwind_frame ("fc builtin");
399 /* Return 1 if LIST->word->word is a legal number for fc's use. */
408 s = list->word->word;
411 return (legal_number (s, (intmax_t *)NULL));
414 /* Return an absolute index into HLIST which corresponds to COMMAND. If
415 COMMAND is a number, then it was specified in relative terms. If it
416 is a string, then it is the start of a command line present in HLIST. */
418 fc_gethnum (command, hlist)
422 int sign = 1, n, clen;
426 /* Count history elements. */
427 for (i = 0; hlist[i]; i++);
429 /* With the Bash implementation of history, the current command line
430 ("fc blah..." and so on) is already part of the history list by
431 the time we get to this point. This just skips over that command
432 and makes the last command that this deals with be the last command
433 the user entered before the fc. We need to check whether the
434 line was actually added (HISTIGNORE may have caused it to not be),
435 so we check hist_last_line_added. */
436 i -= 1 + hist_last_line_added;
438 /* No specification defaults to most recent command. */
442 /* Otherwise, there is a specification. It can be a number relative to
443 the current position, or an absolute history number. */
446 /* Handle possible leading minus sign. */
447 if (s && (*s == '-'))
458 /* If the value is negative or zero, then it is an offset from
459 the current history item. */
463 return (n < 0 ? 0 : n);
470 return (i < n ? i : n);
474 clen = strlen (command);
475 for (j = i; j >= 0; j--)
477 if (STREQN (command, histline (j), clen))
483 /* Locate the most recent history line which begins with
484 COMMAND in HLIST, and return a malloc()'ed copy of it. */
486 fc_gethist (command, hlist)
493 return ((char *)NULL);
495 i = fc_gethnum (command, hlist);
498 return (savestring (histline (i)));
500 return ((char *)NULL);
503 #ifdef INCLUDE_UNUSED
504 /* Read the edited history lines from STREAM and return them
505 one at a time. This can read unlimited length lines. The
506 caller should free the storage. */
512 int line_len = 0, lindex = 0;
513 char *line = (char *)NULL;
515 while ((c = getc (stream)) != EOF)
517 if ((lindex + 2) >= line_len)
518 line = (char *)xrealloc (line, (line_len += 128));
522 line[lindex++] = '\n';
523 line[lindex++] = '\0';
535 return ((char *)NULL);
538 if (lindex + 2 >= line_len)
539 line = (char *)xrealloc (line, lindex + 3);
541 line[lindex++] = '\n'; /* Finish with newline if none in file */
542 line[lindex++] = '\0';
547 /* Perform the SUBS on COMMAND.
548 SUBS is a list of substitutions, and COMMAND is a simple string.
549 Return a pointer to a malloc'ed string which contains the substituted
552 fc_dosubs (command, subs)
556 register char *new, *t;
559 for (new = savestring (command), r = subs; r; r = r->next)
561 t = strsub (new, r->pat, r->rep, 1);
568 /* Use `command' to replace the last entry in the history list, which,
569 by this time, is `fc blah...'. The intent is that the new command
570 become the history entry, and that `fc' should never appear in the
571 history list. This way you can do `r' to your heart's content. */
573 fc_replhist (command)
577 HIST_ENTRY **hlist, *histent, *discard;
580 if (command == 0 || *command == '\0')
583 hlist = history_list ();
588 for (i = 0; hlist[i]; i++);
591 /* History_get () takes a parameter that should be
592 offset by history_base. */
594 histent = history_get (history_base + i); /* Don't free this */
598 n = strlen (command);
600 if (command[n - 1] == '\n')
601 command[n - 1] = '\0';
603 if (command && *command)
605 discard = remove_history (i);
608 FREE (discard->line);
609 free ((char *) discard);
611 maybe_add_history (command); /* Obeys HISTCONTROL setting. */
615 #ifdef INCLUDE_UNUSED
616 /* Add LINE to the history, after removing a single trailing newline. */
625 if (line[n - 1] == '\n')
629 maybe_add_history (line);