Bash-4.3 distribution sources and documentation
[platform/upstream/bash.git] / builtins / fc.def
index 9b298cb..cf6b72c 100644 (file)
@@ -1,7 +1,7 @@
 This file is fc.def, from which is created fc.c.
 It implements the builtin "fc" in Bash.
 
-Copyright (C) 1987-2010 Free Software Foundation, Inc.
+Copyright (C) 1987-2011 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -52,7 +52,7 @@ $END
 #include <config.h>
 
 #if defined (HISTORY)
-#ifndef _MINIX
+#if defined (HAVE_SYS_PARAM_H)
 #  include <sys/param.h>
 #endif
 #include "../bashtypes.h"
@@ -85,7 +85,7 @@ $END
 extern int errno;
 #endif /* !errno */
 
-extern int current_command_line_count, saved_command_line_count;
+extern int current_command_line_count;
 extern int literal_history;
 extern int posixly_correct;
 extern int subshell_environment, interactive_shell;
@@ -173,7 +173,7 @@ fc_builtin (list)
   register int i;
   register char *sep;
   int numbering, reverse, listing, execute;
-  int histbeg, histend, last_hist, retval, opt, rh;
+  int histbeg, histend, last_hist, retval, opt, rh, real_last;
   FILE *stream;
   REPL *rlist, *rl;
   char *ename, *command, *newcom, *fcedit;
@@ -303,6 +303,14 @@ fc_builtin (list)
   rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
   last_hist = i - rh - hist_last_line_added;
 
+  /* Make sure that real_last is calculated the same way here and in
+     fc_gethnum.  The return value from fc_gethnum is treated specially if
+     it is == real_last and we are listing commands. */
+  real_last = i;
+  /* back up from the end to the last non-null history entry */
+  while (hlist[real_last] == 0 && real_last > 0)
+    real_last--;
+
   /* XXX */
   if (i == last_hist && hlist[last_hist] == 0)
     while (last_hist >= 0 && hlist[last_hist] == 0)
@@ -320,6 +328,8 @@ fc_builtin (list)
 
       if (list)
        histend = fc_gethnum (list->word->word, hlist);
+      else if (histbeg == real_last)
+       histend = listing ? real_last : histbeg;
       else
        histend = listing ? last_hist : histbeg;
     }
@@ -475,7 +485,7 @@ fc_gethnum (command, hlist)
      HIST_ENTRY **hlist;
 {
   int sign, n, clen, rh;
-  register int i, j, last_hist;
+  register int i, j, last_hist, real_last;
   register char *s;
 
   sign = 1;
@@ -503,12 +513,17 @@ fc_gethnum (command, hlist)
   if (last_hist < 0)
     return (-1);
 
+  real_last = i;
   i = last_hist;
 
   /* No specification defaults to most recent command. */
   if (command == NULL)
     return (i);
 
+  /* back up from the end to the last non-null history entry */
+  while (hlist[real_last] == 0 && real_last > 0)
+    real_last--;
+
   /* Otherwise, there is a specification.  It can be a number relative to
      the current position, or an absolute history number. */
   s = command;
@@ -533,7 +548,7 @@ fc_gethnum (command, hlist)
          return (n < 0 ? 0 : n);
        }
       else if (n == 0)
-       return (i);
+       return ((sign == -1) ? real_last : i);
       else
        {
          n -= history_base;