1 This file is fc.def, from which is created fc.c.
2 It implements the builtin "fc" in Bash.
4 Copyright (C) 1987, 1989, 1991 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 if (rlist && rlist->next)
243 rlist = (REPL *)reverse_list ((GENERIC_LIST *) rlist);
245 hlist = history_list ();
247 /* If we still have something in list, it is a command spec.
248 Otherwise, we use the most recent command in time. */
249 command = fc_gethist (list ? list->word->word : (char *)NULL, hlist);
253 builtin_error ("no command found");
257 return (EXECUTION_FAILURE);
262 newcom = fc_dosubs (command, rlist);
268 fprintf (stderr, "%s\n", command);
269 fc_replhist (command); /* replace `fc -s' with command */
270 return (parse_and_execute (command, "fc", SEVAL_NOHIST));
273 /* This is the second form of the command (the list-or-edit-and-rerun
275 hlist = history_list ();
277 return (EXECUTION_SUCCESS);
278 for (i = 0; hlist[i]; i++);
280 /* With the Bash implementation of history, the current command line
281 ("fc blah..." and so on) is already part of the history list by
282 the time we get to this point. This just skips over that command
283 and makes the last command that this deals with be the last command
284 the user entered before the fc. We need to check whether the
285 line was actually added (HISTIGNORE may have caused it to not be),
286 so we check hist_last_line_added. */
288 last_hist = i - 1 - hist_last_line_added;
292 histbeg = fc_gethnum (list->word->word, hlist);
296 histend = fc_gethnum (list->word->word, hlist);
298 histend = listing ? last_hist : histbeg;
302 /* The default for listing is the last 16 history items. */
306 histbeg = histend - 16;
311 /* For editing, it is the last history command. */
312 histbeg = histend = last_hist;
315 /* We print error messages for line specifications out of range. */
316 if ((histbeg < 0) || (histend < 0) ||
317 (histbeg > last_hist) || (histend > last_hist))
319 builtin_error ("history specification out of range");
320 return (EXECUTION_FAILURE);
323 if (histend < histbeg)
337 stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn);
340 builtin_error ("cannot open temp file %s", fn ? fn : "");
342 return (EXECUTION_FAILURE);
346 for (i = reverse ? histend : histbeg; reverse ? i >= histbeg : i <= histend; reverse ? i-- : i++)
350 fprintf (stream, "%d", i + history_base);
352 fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
353 fprintf (stream, "%s\n", histline (i));
357 return (EXECUTION_SUCCESS);
361 /* Now edit the file of commands. */
364 command = (char *)xmalloc (strlen (ename) + strlen (fn) + 2);
365 sprintf (command, "%s %s", ename, fn);
369 command = (char *)xmalloc (3 + strlen (FC_EDIT_COMMAND) + strlen (fn));
370 sprintf (command, "%s %s", FC_EDIT_COMMAND, fn);
372 retval = parse_and_execute (command, "fc", SEVAL_NOHIST);
373 if (retval != EXECUTION_SUCCESS)
377 return (EXECUTION_FAILURE);
380 /* Make sure parse_and_execute doesn't turn this off, even though a
381 call to parse_and_execute farther up the function call stack (e.g.,
382 if this is called by vi_edit_and_execute_command) may have already
383 called bash_history_disable. */
384 remember_on_history = 1;
386 /* Turn on the `v' flag while fc_execute_file runs so the commands
387 will be echoed as they are read by the parser. */
388 begin_unwind_frame ("fc builtin");
389 add_unwind_protect ((Function *)xfree, fn);
390 add_unwind_protect (unlink, fn);
391 unwind_protect_int (echo_input_at_read);
392 echo_input_at_read = 1;
394 retval = fc_execute_file (fn);
396 run_unwind_frame ("fc builtin");
401 /* Return 1 if LIST->word->word is a legal number for fc's use. */
410 s = list->word->word;
413 return (legal_number (s, (long *)NULL));
416 /* Return an absolute index into HLIST which corresponds to COMMAND. If
417 COMMAND is a number, then it was specified in relative terms. If it
418 is a string, then it is the start of a command line present in HLIST. */
420 fc_gethnum (command, hlist)
424 int sign = 1, n, clen;
428 /* Count history elements. */
429 for (i = 0; hlist[i]; i++);
431 /* With the Bash implementation of history, the current command line
432 ("fc blah..." and so on) is already part of the history list by
433 the time we get to this point. This just skips over that command
434 and makes the last command that this deals with be the last command
435 the user entered before the fc. We need to check whether the
436 line was actually added (HISTIGNORE may have caused it to not be),
437 so we check hist_last_line_added. */
438 i -= 1 + hist_last_line_added;
440 /* No specification defaults to most recent command. */
444 /* Otherwise, there is a specification. It can be a number relative to
445 the current position, or an absolute history number. */
448 /* Handle possible leading minus sign. */
449 if (s && (*s == '-'))
460 /* Anything specified greater than the last history element that we
461 deal with is an error. */
462 if (n > i + history_base)
465 /* If the value is negative or zero, then it is an offset from
466 the current history item. */
472 return (n - history_base);
475 clen = strlen (command);
476 for (j = i; j >= 0; j--)
478 if (STREQN (command, histline (j), clen))
484 /* Locate the most recent history line which begins with
485 COMMAND in HLIST, and return a malloc()'ed copy of it. */
487 fc_gethist (command, hlist)
494 return ((char *)NULL);
496 i = fc_gethnum (command, hlist);
499 return (savestring (histline (i)));
501 return ((char *)NULL);
504 #ifdef INCLUDE_UNUSED
505 /* Read the edited history lines from STREAM and return them
506 one at a time. This can read unlimited length lines. The
507 caller should free the storage. */
513 int line_len = 0, lindex = 0;
514 char *line = (char *)NULL;
516 while ((c = getc (stream)) != EOF)
518 if ((lindex + 2) >= line_len)
519 line = (char *)xrealloc (line, (line_len += 128));
523 line[lindex++] = '\n';
524 line[lindex++] = '\0';
536 return ((char *)NULL);
539 if (lindex + 2 >= line_len)
540 line = (char *)xrealloc (line, lindex + 3);
542 line[lindex++] = '\n'; /* Finish with newline if none in file */
543 line[lindex++] = '\0';
548 /* Perform the SUBS on COMMAND.
549 SUBS is a list of substitutions, and COMMAND is a simple string.
550 Return a pointer to a malloc'ed string which contains the substituted
553 fc_dosubs (command, subs)
557 register char *new, *t;
560 for (new = savestring (command), r = subs; r; r = r->next)
562 t = strsub (new, r->pat, r->rep, 1);
569 /* Use `command' to replace the last entry in the history list, which,
570 by this time, is `fc blah...'. The intent is that the new command
571 become the history entry, and that `fc' should never appear in the
572 history list. This way you can do `r' to your heart's content. */
574 fc_replhist (command)
578 HIST_ENTRY **hlist, *histent, *discard;
581 if (command == 0 || *command == '\0')
584 hlist = history_list ();
589 for (i = 0; hlist[i]; i++);
592 /* History_get () takes a parameter that should be
593 offset by history_base. */
595 histent = history_get (history_base + i); /* Don't free this */
599 n = strlen (command);
601 if (command[n - 1] == '\n')
602 command[n - 1] = '\0';
604 if (command && *command)
606 discard = remove_history (i);
609 FREE (discard->line);
610 free ((char *) discard);
612 maybe_add_history (command); /* Obeys HISTCONTROL setting. */
616 #ifdef INCLUDE_UNUSED
617 /* Add LINE to the history, after removing a single trailing newline. */
626 if (line[n - 1] == '\n')
630 maybe_add_history (line);