Bash-4.3 distribution sources and documentation
[platform/upstream/bash.git] / builtins / fc.def
1 This file is fc.def, from which is created fc.c.
2 It implements the builtin "fc" in Bash.
3
4 Copyright (C) 1987-2011 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
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.
12
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.
17
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/>.
20
21 $PRODUCES fc.c
22
23 $BUILTIN fc
24 $FUNCTION fc_builtin
25 $DEPENDS_ON HISTORY
26 $SHORT_DOC fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]
27 Display or execute commands from the history list.
28
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
32 string.
33
34 Options:
35   -e ENAME      select which editor to use.  Default is FCEDIT, then EDITOR,
36                 then vi
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)
40
41 With the `fc -s [pat=rep ...] [command]' format, COMMAND is
42 re-executed after the substitution OLD=NEW is performed.
43
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
46 the last command.
47
48 Exit Status:
49 Returns success or status of executed command; non-zero if an error occurs.
50 $END
51
52 #include <config.h>
53
54 #if defined (HISTORY)
55 #if defined (HAVE_SYS_PARAM_H)
56 #  include <sys/param.h>
57 #endif
58 #include "../bashtypes.h"
59 #include "posixstat.h"
60 #if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
61 #  include <sys/file.h>
62 #endif
63
64 #if defined (HAVE_UNISTD_H)
65 #  include <unistd.h>
66 #endif
67
68 #include <stdio.h>
69 #include <chartypes.h>
70
71 #include "../bashansi.h"
72 #include "../bashintl.h"
73 #include <errno.h>
74
75 #include "../shell.h"
76 #include "../builtins.h"
77 #include "../flags.h"
78 #include "../bashhist.h"
79 #include "maxpath.h"
80 #include <readline/history.h>
81 #include "bashgetopt.h"
82 #include "common.h"
83
84 #if !defined (errno)
85 extern int errno;
86 #endif /* !errno */
87
88 extern int current_command_line_count;
89 extern int literal_history;
90 extern int posixly_correct;
91 extern int subshell_environment, interactive_shell;
92
93 extern int unlink __P((const char *));
94
95 extern FILE *sh_mktmpfp __P((char *, int, char **));
96
97 /* **************************************************************** */
98 /*                                                                  */
99 /*      The K*rn shell style fc command (Fix Command)               */
100 /*                                                                  */
101 /* **************************************************************** */
102
103 /* fc builtin command (fix command) for Bash for those who
104    like K*rn-style history better than csh-style.
105
106      fc [-e ename] [-nlr] [first] [last]
107
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
110    string.
111
112    -e ENAME selects which editor to use.  Default is FCEDIT, then EDITOR,
113       then the editor which corresponds to the current readline editing
114       mode, then vi.
115
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).
119
120      fc -e - [pat=rep ...] [command]
121      fc -s [pat=rep ...] [command]
122
123    Equivalent to !command:sg/pat/rep execpt there can be multiple PAT=REP's.
124 */
125
126 /* Data structure describing a list of global replacements to perform. */
127 typedef struct repl {
128   struct repl *next;
129   char *pat;
130   char *rep;
131 } REPL;
132
133 /* Accessors for HIST_ENTRY lists that are called HLIST. */
134 #define histline(i) (hlist[(i)]->line)
135 #define histdata(i) (hlist[(i)]->data)
136
137 #define FREE_RLIST() \
138         do { \
139                 for (rl = rlist; rl; ) { \
140                         REPL *r;        \
141                         r = rl->next; \
142                         if (rl->pat) \
143                                 free (rl->pat); \
144                         if (rl->rep) \
145                                 free (rl->rep); \
146                         free (rl); \
147                         rl = r; \
148                 } \
149         } while (0)
150
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 *));
159 #endif
160
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}"
165 #else
166 #  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"
167 #endif
168
169 int
170 fc_builtin (list)
171      WORD_LIST *list;
172 {
173   register int i;
174   register char *sep;
175   int numbering, reverse, listing, execute;
176   int histbeg, histend, last_hist, retval, opt, rh, real_last;
177   FILE *stream;
178   REPL *rlist, *rl;
179   char *ename, *command, *newcom, *fcedit;
180   HIST_ENTRY **hlist;
181   char *fn;
182
183   numbering = 1;
184   reverse = listing = execute = 0;
185   ename = (char *)NULL;
186
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)
192     {
193       switch (opt)
194         {
195         case 'n':
196           numbering = 0;
197           break;
198
199         case 'l':
200           listing = 1;
201           break;
202
203         case 'r':
204           reverse = 1;
205           break;
206
207         case 's':
208           execute = 1;
209           break;
210
211         case 'e':
212           ename = list_optarg;
213           break;
214
215         default:
216           builtin_usage ();
217           return (EX_USAGE);
218         }
219     }
220
221   list = loptend;
222
223   if (ename && (*ename == '-') && (ename[1] == '\0'))
224     execute = 1;
225
226   /* The "execute" form of the command (re-run, with possible string
227      substitutions). */
228   if (execute)
229     {
230       rlist = (REPL *)NULL;
231       while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL))
232         {
233           *sep++ = '\0';
234           rl = (REPL *)xmalloc (sizeof (REPL));
235           rl->next = (REPL *)NULL;
236           rl->pat = savestring (list->word->word);
237           rl->rep = savestring (sep);
238
239           if (rlist == NULL)
240             rlist = rl;
241           else
242             {
243               rl->next = rlist;
244               rlist = rl;
245             }
246           list = list->next;
247         }
248
249       /* If we have a list of substitutions to do, then reverse it
250          to get the replacements in the proper order. */
251
252       rlist = REVERSE_LIST (rlist, REPL *);
253
254       hlist = history_list ();
255
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);
259
260       if (command == NULL)
261         {
262           builtin_error (_("no command found"));
263           if (rlist)
264             FREE_RLIST ();
265
266           return (EXECUTION_FAILURE);
267         }
268
269       if (rlist)
270         {
271           newcom = fc_dosubs (command, rlist);
272           free (command);
273           FREE_RLIST ();
274           command = newcom;
275         }
276
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
280          history. */
281       return (parse_and_execute (command, "fc", SEVAL_NOHIST));
282     }
283
284   /* This is the second form of the command (the list-or-edit-and-rerun
285      form). */
286   hlist = history_list ();
287   if (hlist == 0)
288     return (EXECUTION_SUCCESS);
289   for (i = 0; hlist[i]; i++);
290
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. */
298
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;
305
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. */
309   real_last = i;
310   /* back up from the end to the last non-null history entry */
311   while (hlist[real_last] == 0 && real_last > 0)
312     real_last--;
313
314   /* XXX */
315   if (i == last_hist && hlist[last_hist] == 0)
316     while (last_hist >= 0 && hlist[last_hist] == 0)
317       last_hist--;
318   if (last_hist < 0)
319     {
320       sh_erange ((char *)NULL, _("history specification"));
321       return (EXECUTION_FAILURE);
322     }
323
324   if (list)
325     {
326       histbeg = fc_gethnum (list->word->word, hlist);
327       list = list->next;
328
329       if (list)
330         histend = fc_gethnum (list->word->word, hlist);
331       else if (histbeg == real_last)
332         histend = listing ? real_last : histbeg;
333       else
334         histend = listing ? last_hist : histbeg;
335     }
336   else
337     {
338       /* The default for listing is the last 16 history items. */
339       if (listing)
340         {
341           histend = last_hist;
342           histbeg = histend - 16 + 1;   /* +1 because loop below uses >= */
343           if (histbeg < 0)
344             histbeg = 0;
345         }
346       else
347         /* For editing, it is the last history command. */
348         histbeg = histend = last_hist;
349     }
350
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)
354     {
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;
364     }
365
366   /* We print error messages for line specifications out of range. */
367   if ((histbeg < 0) || (histend < 0))
368     {
369       sh_erange ((char *)NULL, _("history specification"));
370       return (EXECUTION_FAILURE);
371     }
372
373   if (histend < histbeg)
374     {
375       i = histend;
376       histend = histbeg;
377       histbeg = i;
378
379       reverse = 1;
380     }
381
382   if (listing)
383     stream = stdout;
384   else
385     {
386       numbering = 0;
387       stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn);
388       if (stream == 0)
389         {
390           builtin_error (_("%s: cannot open temp file: %s"), fn ? fn : "", strerror (errno));
391           FREE (fn);
392           return (EXECUTION_FAILURE);
393         }
394     }
395
396   for (i = reverse ? histend : histbeg; reverse ? i >= histbeg : i <= histend; reverse ? i-- : i++)
397     {
398       QUIT;
399       if (numbering)
400         fprintf (stream, "%d", i + history_base);
401       if (listing)
402         {
403           if (posixly_correct)
404             fputs ("\t", stream);
405           else
406             fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
407         }
408       fprintf (stream, "%s\n", histline (i));
409     }
410
411   if (listing)
412     return (sh_chkwrite (EXECUTION_SUCCESS));
413
414   fflush (stream);
415   if (ferror (stream))
416     {
417       sh_wrerror ();
418       fclose (stream);
419       return (EXECUTION_FAILURE);
420     }
421   fclose (stream);
422
423   /* Now edit the file of commands. */
424   if (ename)
425     {
426       command = (char *)xmalloc (strlen (ename) + strlen (fn) + 2);
427       sprintf (command, "%s %s", ename, fn);
428     }
429   else
430     {
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);
434     }
435   retval = parse_and_execute (command, "fc", SEVAL_NOHIST);
436   if (retval != EXECUTION_SUCCESS)
437     {
438       unlink (fn);
439       free (fn);
440       return (EXECUTION_FAILURE);
441     }
442
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;
448
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;
456     
457   retval = fc_execute_file (fn);
458
459   run_unwind_frame ("fc builtin");
460
461   return (retval);
462 }
463
464 /* Return 1 if LIST->word->word is a legal number for fc's use. */
465 static int
466 fc_number (list)
467      WORD_LIST *list;
468 {
469   char *s;
470
471   if (list == 0)
472     return 0;
473   s = list->word->word;
474   if (*s == '-')
475     s++;
476   return (legal_number (s, (intmax_t *)NULL));
477 }
478
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. */
482 static int
483 fc_gethnum (command, hlist)
484      char *command;
485      HIST_ENTRY **hlist;
486 {
487   int sign, n, clen, rh;
488   register int i, j, last_hist, real_last;
489   register char *s;
490
491   sign = 1;
492   /* Count history elements. */
493   for (i = 0; hlist[i]; i++);
494
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;
509
510   if (i == last_hist && hlist[last_hist] == 0)
511     while (last_hist >= 0 && hlist[last_hist] == 0)
512       last_hist--;
513   if (last_hist < 0)
514     return (-1);
515
516   real_last = i;
517   i = last_hist;
518
519   /* No specification defaults to most recent command. */
520   if (command == NULL)
521     return (i);
522
523   /* back up from the end to the last non-null history entry */
524   while (hlist[real_last] == 0 && real_last > 0)
525     real_last--;
526
527   /* Otherwise, there is a specification.  It can be a number relative to
528      the current position, or an absolute history number. */
529   s = command;
530
531   /* Handle possible leading minus sign. */
532   if (s && (*s == '-'))
533     {
534       sign = -1;
535       s++;
536     }
537
538   if (s && DIGIT(*s))
539     {
540       n = atoi (s);
541       n *= sign;
542
543       /* If the value is negative or zero, then it is an offset from
544          the current history item. */
545       if (n < 0)
546         {
547           n += i + 1;
548           return (n < 0 ? 0 : n);
549         }
550       else if (n == 0)
551         return ((sign == -1) ? real_last : i);
552       else
553         {
554           n -= history_base;
555           return (i < n ? i : n);
556         }
557     }
558
559   clen = strlen (command);
560   for (j = i; j >= 0; j--)
561     {
562       if (STREQN (command, histline (j), clen))
563         return (j);
564     }
565   return (-1);
566 }
567
568 /* Locate the most recent history line which begins with
569    COMMAND in HLIST, and return a malloc()'ed copy of it. */
570 static char *
571 fc_gethist (command, hlist)
572      char *command;
573      HIST_ENTRY **hlist;
574 {
575   int i;
576
577   if (hlist == 0)
578     return ((char *)NULL);
579
580   i = fc_gethnum (command, hlist);
581
582   if (i >= 0)
583     return (savestring (histline (i)));
584   else
585     return ((char *)NULL);
586 }
587
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. */
592 static char *
593 fc_readline (stream)
594      FILE *stream;
595 {
596   register int c;
597   int line_len = 0, lindex = 0;
598   char *line = (char *)NULL;
599
600   while ((c = getc (stream)) != EOF)
601     {
602       if ((lindex + 2) >= line_len)
603         line = (char *)xrealloc (line, (line_len += 128));
604
605       if (c == '\n')
606         {
607           line[lindex++] = '\n';
608           line[lindex++] = '\0';
609           return (line);
610         }
611       else
612         line[lindex++] = c;
613     }
614
615   if (!lindex)
616     {
617       if (line)
618         free (line);
619
620       return ((char *)NULL);
621     }
622
623   if (lindex + 2 >= line_len)
624     line = (char *)xrealloc (line, lindex + 3);
625
626   line[lindex++] = '\n';            /* Finish with newline if none in file */
627   line[lindex++] = '\0';
628   return (line);
629 }
630 #endif
631
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
635    command. */
636 static char *
637 fc_dosubs (command, subs)
638      char *command;
639      REPL *subs;
640 {
641   register char *new, *t;
642   register REPL *r;
643
644   for (new = savestring (command), r = subs; r; r = r->next)
645     {
646       t = strsub (new, r->pat, r->rep, 1);
647       free (new);
648       new = t;
649     }
650   return (new);
651 }
652
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. */
657 static void
658 fc_replhist (command)
659      char *command;
660 {
661   int n;
662
663   if (command == 0 || *command == '\0')
664     return;
665
666   n = strlen (command);
667   if (command[n - 1] == '\n')
668     command[n - 1] = '\0';
669
670   if (command && *command)
671     {
672       bash_delete_last_history ();
673       maybe_add_history (command);      /* Obeys HISTCONTROL setting. */
674     }
675 }
676
677 #ifdef INCLUDE_UNUSED
678 /* Add LINE to the history, after removing a single trailing newline. */
679 static void
680 fc_addhist (line)
681      char *line;
682 {
683   register int n;
684
685   if (line == 0 || *line == 0)
686     return;
687
688   n = strlen (line);
689
690   if (line[n - 1] == '\n')
691     line[n - 1] = '\0';
692
693   if (line && *line)
694     maybe_add_history (line);           /* Obeys HISTCONTROL setting. */
695 }
696 #endif
697
698 #endif /* HISTORY */