Imported from ../bash-4.0-rc1.tar.gz.
[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-2009 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 #ifndef _MINIX
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
92 extern int unlink __P((const char *));
93
94 extern FILE *sh_mktmpfp __P((char *, int, char **));
95
96 /* **************************************************************** */
97 /*                                                                  */
98 /*      The K*rn shell style fc command (Fix Command)               */
99 /*                                                                  */
100 /* **************************************************************** */
101
102 /* fc builtin command (fix command) for Bash for those who
103    like K*rn-style history better than csh-style.
104
105      fc [-e ename] [-nlr] [first] [last]
106
107    FIRST and LAST can be numbers specifying the range, or FIRST can be
108    a string, which means the most recent command beginning with that
109    string.
110
111    -e ENAME selects which editor to use.  Default is FCEDIT, then EDITOR,
112       then the editor which corresponds to the current readline editing
113       mode, then vi.
114
115    -l means list lines instead of editing.
116    -n means no line numbers listed.
117    -r means reverse the order of the lines (making it newest listed first).
118
119      fc -e - [pat=rep ...] [command]
120      fc -s [pat=rep ...] [command]
121
122    Equivalent to !command:sg/pat/rep execpt there can be multiple PAT=REP's.
123 */
124
125 /* Data structure describing a list of global replacements to perform. */
126 typedef struct repl {
127   struct repl *next;
128   char *pat;
129   char *rep;
130 } REPL;
131
132 /* Accessors for HIST_ENTRY lists that are called HLIST. */
133 #define histline(i) (hlist[(i)]->line)
134 #define histdata(i) (hlist[(i)]->data)
135
136 #define FREE_RLIST() \
137         do { \
138                 for (rl = rlist; rl; ) { \
139                         REPL *r;        \
140                         r = rl->next; \
141                         if (rl->pat) \
142                                 free (rl->pat); \
143                         if (rl->rep) \
144                                 free (rl->rep); \
145                         free (rl); \
146                         rl = r; \
147                 } \
148         } while (0)
149
150 static char *fc_dosubs __P((char *, REPL *));
151 static char *fc_gethist __P((char *, HIST_ENTRY **));
152 static int fc_gethnum __P((char *, HIST_ENTRY **));
153 static int fc_number __P((WORD_LIST *));
154 static void fc_replhist __P((char *));
155 #ifdef INCLUDE_UNUSED
156 static char *fc_readline __P((FILE *));
157 static void fc_addhist __P((char *));
158 #endif
159
160 /* String to execute on a file that we want to edit. */
161 #define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}"
162 #if defined (STRICT_POSIX)
163 #  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-ed}"
164 #else
165 #  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"
166 #endif
167
168 int
169 fc_builtin (list)
170      WORD_LIST *list;
171 {
172   register int i;
173   register char *sep;
174   int numbering, reverse, listing, execute;
175   int histbeg, histend, last_hist, retval, opt;
176   FILE *stream;
177   REPL *rlist, *rl;
178   char *ename, *command, *newcom, *fcedit;
179   HIST_ENTRY **hlist;
180   char *fn;
181
182   numbering = 1;
183   reverse = listing = execute = 0;
184   ename = (char *)NULL;
185
186   /* Parse out the options and set which of the two forms we're in. */
187   reset_internal_getopt ();
188   lcurrent = list;              /* XXX */
189   while (fc_number (loptend = lcurrent) == 0 &&
190          (opt = internal_getopt (list, ":e:lnrs")) != -1)
191     {
192       switch (opt)
193         {
194         case 'n':
195           numbering = 0;
196           break;
197
198         case 'l':
199           listing = 1;
200           break;
201
202         case 'r':
203           reverse = 1;
204           break;
205
206         case 's':
207           execute = 1;
208           break;
209
210         case 'e':
211           ename = list_optarg;
212           break;
213
214         default:
215           builtin_usage ();
216           return (EX_USAGE);
217         }
218     }
219
220   list = loptend;
221
222   if (ename && (*ename == '-') && (ename[1] == '\0'))
223     execute = 1;
224
225   /* The "execute" form of the command (re-run, with possible string
226      substitutions). */
227   if (execute)
228     {
229       rlist = (REPL *)NULL;
230       while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL))
231         {
232           *sep++ = '\0';
233           rl = (REPL *)xmalloc (sizeof (REPL));
234           rl->next = (REPL *)NULL;
235           rl->pat = savestring (list->word->word);
236           rl->rep = savestring (sep);
237
238           if (rlist == NULL)
239             rlist = rl;
240           else
241             {
242               rl->next = rlist;
243               rlist = rl;
244             }
245           list = list->next;
246         }
247
248       /* If we have a list of substitutions to do, then reverse it
249          to get the replacements in the proper order. */
250
251       rlist = REVERSE_LIST (rlist, REPL *);
252
253       hlist = history_list ();
254
255       /* If we still have something in list, it is a command spec.
256          Otherwise, we use the most recent command in time. */
257       command = fc_gethist (list ? list->word->word : (char *)NULL, hlist);
258
259       if (command == NULL)
260         {
261           builtin_error (_("no command found"));
262           if (rlist)
263             FREE_RLIST ();
264
265           return (EXECUTION_FAILURE);
266         }
267
268       if (rlist)
269         {
270           newcom = fc_dosubs (command, rlist);
271           free (command);
272           FREE_RLIST ();
273           command = newcom;
274         }
275
276       fprintf (stderr, "%s\n", command);
277       fc_replhist (command);    /* replace `fc -s' with command */
278       return (parse_and_execute (command, "fc", SEVAL_NOHIST));
279     }
280
281   /* This is the second form of the command (the list-or-edit-and-rerun
282      form). */
283   hlist = history_list ();
284   if (hlist == 0)
285     return (EXECUTION_SUCCESS);
286   for (i = 0; hlist[i]; i++);
287
288   /* With the Bash implementation of history, the current command line
289      ("fc blah..." and so on) is already part of the history list by
290      the time we get to this point.  This just skips over that command
291      and makes the last command that this deals with be the last command
292      the user entered before the fc.  We need to check whether the
293      line was actually added (HISTIGNORE may have caused it to not be),
294      so we check hist_last_line_added. */
295
296   last_hist = i - remember_on_history - hist_last_line_added;
297
298   if (list)
299     {
300       histbeg = fc_gethnum (list->word->word, hlist);
301       list = list->next;
302
303       if (list)
304         histend = fc_gethnum (list->word->word, hlist);
305       else
306         histend = listing ? last_hist : histbeg;
307     }
308   else
309     {
310       /* The default for listing is the last 16 history items. */
311       if (listing)
312         {
313           histend = last_hist;
314           histbeg = histend - 16 + 1;   /* +1 because loop below uses >= */
315           if (histbeg < 0)
316             histbeg = 0;
317         }
318       else
319         /* For editing, it is the last history command. */
320         histbeg = histend = last_hist;
321     }
322
323   /* "When not listing, the fc command that caused the editing shall not be
324      entered into the history list." */
325   if (listing == 0 && hist_last_line_added)
326     {
327       bash_delete_last_history ();
328       /* If we're editing a single command -- the last command in the
329          history -- and we just removed the dummy command added by
330          edit_and_execute_command (), we need to check whether or not we
331          just removed the last command in the history and need to back
332          the pointer up.  remember_on_history is off because we're running
333          in parse_and_execute(). */
334       if (histbeg == histend && histend == last_hist && hlist[last_hist] == 0)
335         last_hist = histbeg = --histend;
336     }
337
338   /* We print error messages for line specifications out of range. */
339   if ((histbeg < 0) || (histend < 0))
340     {
341       sh_erange ((char *)NULL, _("history specification"));
342       return (EXECUTION_FAILURE);
343     }
344
345   if (histend < histbeg)
346     {
347       i = histend;
348       histend = histbeg;
349       histbeg = i;
350
351       reverse = 1;
352     }
353
354   if (listing)
355     stream = stdout;
356   else
357     {
358       numbering = 0;
359       stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn);
360       if (stream == 0)
361         {
362           builtin_error (_("%s: cannot open temp file: %s"), fn ? fn : "", strerror (errno));
363           FREE (fn);
364           return (EXECUTION_FAILURE);
365         }
366     }
367
368   for (i = reverse ? histend : histbeg; reverse ? i >= histbeg : i <= histend; reverse ? i-- : i++)
369     {
370       QUIT;
371       if (numbering)
372         fprintf (stream, "%d", i + history_base);
373       if (listing)
374         {
375           if (posixly_correct)
376             fputs ("\t", stream);
377           else
378             fprintf (stream, "\t%c", histdata (i) ? '*' : ' ');
379         }
380       fprintf (stream, "%s\n", histline (i));
381     }
382
383   if (listing)
384     return (sh_chkwrite (EXECUTION_SUCCESS));
385
386   fflush (stream);
387   if (ferror (stream))
388     {
389       sh_wrerror ();
390       fclose (stream);
391       return (EXECUTION_FAILURE);
392     }
393   fclose (stream);
394
395   /* Now edit the file of commands. */
396   if (ename)
397     {
398       command = (char *)xmalloc (strlen (ename) + strlen (fn) + 2);
399       sprintf (command, "%s %s", ename, fn);
400     }
401   else
402     {
403       fcedit = posixly_correct ? POSIX_FC_EDIT_COMMAND : FC_EDIT_COMMAND;
404       command = (char *)xmalloc (3 + strlen (fcedit) + strlen (fn));
405       sprintf (command, "%s %s", fcedit, fn);
406     }
407   retval = parse_and_execute (command, "fc", SEVAL_NOHIST);
408   if (retval != EXECUTION_SUCCESS)
409     {
410       unlink (fn);
411       free (fn);
412       return (EXECUTION_FAILURE);
413     }
414
415   /* Make sure parse_and_execute doesn't turn this off, even though a
416      call to parse_and_execute farther up the function call stack (e.g.,
417      if this is called by vi_edit_and_execute_command) may have already
418      called bash_history_disable. */
419   remember_on_history = 1;
420
421   /* Turn on the `v' flag while fc_execute_file runs so the commands
422      will be echoed as they are read by the parser. */
423   begin_unwind_frame ("fc builtin");
424   add_unwind_protect ((Function *)xfree, fn);
425   add_unwind_protect (unlink, fn);
426   unwind_protect_int (echo_input_at_read);
427   echo_input_at_read = 1;
428     
429   retval = fc_execute_file (fn);
430
431   run_unwind_frame ("fc builtin");
432
433   return (retval);
434 }
435
436 /* Return 1 if LIST->word->word is a legal number for fc's use. */
437 static int
438 fc_number (list)
439      WORD_LIST *list;
440 {
441   char *s;
442
443   if (list == 0)
444     return 0;
445   s = list->word->word;
446   if (*s == '-')
447     s++;
448   return (legal_number (s, (intmax_t *)NULL));
449 }
450
451 /* Return an absolute index into HLIST which corresponds to COMMAND.  If
452    COMMAND is a number, then it was specified in relative terms.  If it
453    is a string, then it is the start of a command line present in HLIST. */
454 static int
455 fc_gethnum (command, hlist)
456      char *command;
457      HIST_ENTRY **hlist;
458 {
459   int sign, n, clen;
460   register int i, j;
461   register char *s;
462
463   sign = 1;
464   /* Count history elements. */
465   for (i = 0; hlist[i]; i++);
466
467   /* With the Bash implementation of history, the current command line
468      ("fc blah..." and so on) is already part of the history list by
469      the time we get to this point.  This just skips over that command
470      and makes the last command that this deals with be the last command
471      the user entered before the fc.  We need to check whether the
472      line was actually added (HISTIGNORE may have caused it to not be),
473      so we check hist_last_line_added.  This needs to agree with the
474      calculation of last_hist in fc_builtin above. */
475   i -= remember_on_history + hist_last_line_added;
476
477   /* No specification defaults to most recent command. */
478   if (command == NULL)
479     return (i);
480
481   /* Otherwise, there is a specification.  It can be a number relative to
482      the current position, or an absolute history number. */
483   s = command;
484
485   /* Handle possible leading minus sign. */
486   if (s && (*s == '-'))
487     {
488       sign = -1;
489       s++;
490     }
491
492   if (s && DIGIT(*s))
493     {
494       n = atoi (s);
495       n *= sign;
496
497       /* If the value is negative or zero, then it is an offset from
498          the current history item. */
499       if (n < 0)
500         {
501           n += i + 1;
502           return (n < 0 ? 0 : n);
503         }
504       else if (n == 0)
505         return (i);
506       else
507         {
508           n -= history_base;
509           return (i < n ? i : n);
510         }
511     }
512
513   clen = strlen (command);
514   for (j = i; j >= 0; j--)
515     {
516       if (STREQN (command, histline (j), clen))
517         return (j);
518     }
519   return (-1);
520 }
521
522 /* Locate the most recent history line which begins with
523    COMMAND in HLIST, and return a malloc()'ed copy of it. */
524 static char *
525 fc_gethist (command, hlist)
526      char *command;
527      HIST_ENTRY **hlist;
528 {
529   int i;
530
531   if (hlist == 0)
532     return ((char *)NULL);
533
534   i = fc_gethnum (command, hlist);
535
536   if (i >= 0)
537     return (savestring (histline (i)));
538   else
539     return ((char *)NULL);
540 }
541
542 #ifdef INCLUDE_UNUSED
543 /* Read the edited history lines from STREAM and return them
544    one at a time.  This can read unlimited length lines.  The
545    caller should free the storage. */
546 static char *
547 fc_readline (stream)
548      FILE *stream;
549 {
550   register int c;
551   int line_len = 0, lindex = 0;
552   char *line = (char *)NULL;
553
554   while ((c = getc (stream)) != EOF)
555     {
556       if ((lindex + 2) >= line_len)
557         line = (char *)xrealloc (line, (line_len += 128));
558
559       if (c == '\n')
560         {
561           line[lindex++] = '\n';
562           line[lindex++] = '\0';
563           return (line);
564         }
565       else
566         line[lindex++] = c;
567     }
568
569   if (!lindex)
570     {
571       if (line)
572         free (line);
573
574       return ((char *)NULL);
575     }
576
577   if (lindex + 2 >= line_len)
578     line = (char *)xrealloc (line, lindex + 3);
579
580   line[lindex++] = '\n';            /* Finish with newline if none in file */
581   line[lindex++] = '\0';
582   return (line);
583 }
584 #endif
585
586 /* Perform the SUBS on COMMAND.
587    SUBS is a list of substitutions, and COMMAND is a simple string.
588    Return a pointer to a malloc'ed string which contains the substituted
589    command. */
590 static char *
591 fc_dosubs (command, subs)
592      char *command;
593      REPL *subs;
594 {
595   register char *new, *t;
596   register REPL *r;
597
598   for (new = savestring (command), r = subs; r; r = r->next)
599     {
600       t = strsub (new, r->pat, r->rep, 1);
601       free (new);
602       new = t;
603     }
604   return (new);
605 }
606
607 /* Use `command' to replace the last entry in the history list, which,
608    by this time, is `fc blah...'.  The intent is that the new command
609    become the history entry, and that `fc' should never appear in the
610    history list.  This way you can do `r' to your heart's content. */
611 static void
612 fc_replhist (command)
613      char *command;
614 {
615   int n;
616
617   if (command == 0 || *command == '\0')
618     return;
619
620   n = strlen (command);
621   if (command[n - 1] == '\n')
622     command[n - 1] = '\0';
623
624   if (command && *command)
625     {
626       bash_delete_last_history ();
627       maybe_add_history (command);      /* Obeys HISTCONTROL setting. */
628     }
629 }
630
631 #ifdef INCLUDE_UNUSED
632 /* Add LINE to the history, after removing a single trailing newline. */
633 static void
634 fc_addhist (line)
635      char *line;
636 {
637   register int n;
638
639   if (line == 0 || *line == 0)
640     return;
641
642   n = strlen (line);
643
644   if (line[n - 1] == '\n')
645     line[n - 1] = '\0';
646
647   if (line && *line)
648     maybe_add_history (line);           /* Obeys HISTCONTROL setting. */
649 }
650 #endif
651
652 #endif /* HISTORY */