bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bash fc out-of-range incompatibility with POSIX and ksh


From: Paul Eggert
Subject: Bash fc out-of-range incompatibility with POSIX and ksh
Date: Mon, 19 Nov 2001 17:03:32 -0800 (PST)

Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' 
-DCONF_VENDOR='pc' -DSHELL -DHAVE_CONFIG_H   -I.  -I.. -I../include -I../lib -g 
-O2
uname output: Linux dum.twinsun.com 2.2.18ss.e820-bda652a #4 SMP Tue Jun 5 
11:24:08 PDT 2001 i686 unknown
Machine Type: i686-pc-linux-gnu

Bash Version: 2.05a
Patch Level: 0
Release Status: release

Description:
        I ran into this problem when switching from ksh to Bash.
        I used the following function:

        hi() { fc -l -10; }

        to get the last 10 lines of history.  Bash prints an error
        if I invoke "fc -l -10" and there are fewer than 10 lines of
        history.  ksh just prints all the lines that there are, with
        no error.

        I had a similar problem with this function:

        wh() { fc -l 1 | grep -e "$1"; }

        It works correctly with ksh, but not with Bash, once the
        history base grows past 1.

        POSIX 1003.2-1992 section 5.12.14 page 547 lines 2212-2219
        require the ksh behavior.  Here's a quote:

           When a range of commands is used, it shall not be an error to
           specify first or last values that are not in the history list; fc
           shall substitute the value representing the oldest or newest
           command in the list, as appropriate. For example, if there are only
           ten commands in the history list, numbered 1 to 10:

           fc -l
           fc 1 99

           shall list and edit, respectively, all ten commands.

Repeat-By:
        $ echo foo
        foo
        $ fc -l 10000000
        bash: fc: history specification out of range

        The last line should be something like
        "23      echo foo" instead.

Fix:

2001-11-19  Paul Eggert  <eggert@twinsun.com>

        * builtins/fc.def (fc_gethnum):
        If a number is out of range, substitute the nearest
        value in range.  ksh does this, and POSIX requires it.

        (fc_builtin): Don't bother checking for (histbeg > last_hist) ||
        (histend > last_hist); it's impossible now.

===================================================================
RCS file: builtins/fc.def,v
retrieving revision 2.5.1.4.0.1
retrieving revision 2.5.1.4.0.2
diff -pu -r2.5.1.4.0.1 -r2.5.1.4.0.2
--- builtins/fc.def     2001/11/19 06:00:59     2.5.1.4.0.1
+++ builtins/fc.def     2001/11/20 00:42:15     2.5.1.4.0.2
@@ -313,8 +313,7 @@ fc_builtin (list)
     }
 
   /* We print error messages for line specifications out of range. */
-  if ((histbeg < 0) || (histend < 0) ||
-      (histbeg > last_hist) || (histend > last_hist))
+  if ((histbeg < 0) || (histend < 0))
     {
       builtin_error ("history specification out of range");
       return (EXECUTION_FAILURE);
@@ -457,19 +456,20 @@ fc_gethnum (command, hlist)
       n = atoi (s);
       n *= sign;
 
-      /* Anything specified greater than the last history element that we
-        deal with is an error. */
-      if (n > i + history_base)
-       return (-1);
-
       /* If the value is negative or zero, then it is an offset from
         the current history item. */
       if (n < 0)
-       return (i + n + 1);
+       {
+         n += i + 1;
+         return (n < 0 ? 0 : n);
+       }
       else if (n == 0)
        return (i);
       else
-       return (n - history_base);
+       {
+         n -= history_base;
+         return (i < n ? i : n);
+       }
     }
 
   clen = strlen (command);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]