]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20080320 snapshot
authorChet Ramey <chet.ramey@case.edu>
Wed, 7 Dec 2011 14:20:50 +0000 (09:20 -0500)
committerChet Ramey <chet.ramey@case.edu>
Wed, 7 Dec 2011 14:20:50 +0000 (09:20 -0500)
18 files changed:
CWRU/CWRU.chlog
CWRU/CWRU.chlog~
bracecomp.c
builtins/printf.def
builtins/printf.def.save1 [new file with mode: 0644]
builtins/printf.def~
lib/readline/display.c
lib/readline/display.c~
lib/readline/doc/rltech.texi
lib/readline/doc/rltech.texi~
lib/readline/readline.c
lib/readline/readline.c~
lib/readline/rlprivate.h
lib/readline/rlprivate.h~
lib/readline/rltty.c
lib/readline/rltty.c~
lib/readline/signals.c
lib/readline/signals.c~

index 47fc790dc9e609295e67df3cb30b22f042ce8db0..63dc454e928ed079ed8f6d1c1c34cca819877da0 100644 (file)
@@ -15380,6 +15380,9 @@ pcomplete.c
          etc.)
        - new function, pcomp_set_compspec_options, to set or unset bits in
          the options word of a passed compspec (default CURCS)
+       - only call bash_dequote_filename (via rl_filename_dequoting_function)
+         from pcomp_filename_completion_function if the readline state
+         word indicates word completion is in progress
 
 pcomplete.h
        - new extern declaration for curcs
@@ -15393,3 +15396,37 @@ bashline.c
                   the following character is one of the special ones
        - call pcomp_set_readline_variables from attempt_shell_completion
          instead of doing the equivalent inline
+
+                                  3/18
+                                  ----
+bracecomp.c
+       - make sure we sort array of matches in byte order (using strcmp). so
+         the brace calculations work correctly even when the locale orders
+         characters like aAbBcC...zZ.  Fixes bug reported by Torsten Nahm
+         <torstennahm@torstennahm.de>
+
+                                  3/20
+                                  ----
+lib/readline/{rltty,signals}.c
+       - move block_sigint and release_sigint from rltty.c to signals.c; add
+         _rl_ prefix to make them public to the library; change callers.
+         From Jan Kratchovil <jan.kratchovil@redhat.com>
+
+lib/readline/rlprivate.h
+       - new extern declarations for _rl_block_sigint and _rl_release_sigint
+
+lib/readline/display.c
+       - add calls to _rl_block_sigint and _rl_release_sigint to rl_redisplay,
+         since it maniupluates global data structures.  Fix from Jan
+         Kratchovil <jan.kratchovil@redhat.com>
+
+builtins/printf.def
+       - change calls to asprintf and manually adding to vbuf to use calls
+         to vsnprintf against vbuf directly -- if the number of characters
+         to be written overflows the buffer, realloc the buffer and use
+         vsnprintf again.  This should reduce the memory used by printf.
+         Idea from Yuya Katayama <yuya999@gmail.com>
+
+lib/readline/doc/rltech.texi
+       - documented rest of readline's state flags, including RL_STATE_CALLBACK
+       - documented rl_save_state and rl_restore_state
index 446e76a357f9e957531ad4aeb648448d75f09dc1..a00c80997b99aef552e3493fc00451591321c2bf 100644 (file)
@@ -15378,10 +15378,16 @@ pcomplete.c
        - new function, pcomp_set_readline_variables, that sets or unsets
          readline variables based on a passed flags value (COPT_FILENAMES,
          etc.)
+       - new function, pcomp_set_compspec_options, to set or unset bits in
+         the options word of a passed compspec (default CURCS)
+       - only call bash_dequote_filename (via rl_filename_dequoting_function)
+         from pcomp_filename_completion_function if the readline state
+         word indicates word completion is in progress
 
 pcomplete.h
        - new extern declaration for curcs
        - new extern declaration for pcomp_set_readline_variables
+       - new extern declaration for pcomp_set_compspec_options
 
 bashline.c
        - fix bash_dequote_filename to implement shell quoting conventions:
@@ -15390,3 +15396,33 @@ bashline.c
                   the following character is one of the special ones
        - call pcomp_set_readline_variables from attempt_shell_completion
          instead of doing the equivalent inline
+
+                                  3/18
+                                  ----
+bracecomp.c
+       - make sure we sort array of matches in byte order (using strcmp). so
+         the brace calculations work correctly even when the locale orders
+         characters like aAbBcC...zZ.  Fixes bug reported by Torsten Nahm
+         <torstennahm@torstennahm.de>
+
+                                  3/20
+                                  ----
+lib/readline/{rltty,signals}.c
+       - move block_sigint and release_sigint from rltty.c to signals.c; add
+         _rl_ prefix to make them public to the library; change callers.
+         From Jan Kratchovil <jan.kratchovil@redhat.com>
+
+lib/readline/rlprivate.h
+       - new extern declarations for _rl_block_sigint and _rl_release_sigint
+
+lib/readline/display.c
+       - add calls to _rl_block_sigint and _rl_release_sigint to rl_redisplay,
+         since it maniupluates global data structures.  Fix from Jan
+         Kratchovil <jan.kratchovil@redhat.com>
+
+builtins/printf.def
+       - change calls to asprintf and manually adding to vbuf to use calls
+         to vsnprintf against vbuf directly -- if the number of characters
+         to be written overflows the buffer, realloc the buffer and use
+         vsnprintf again.  This should reduce the memory used by printf.
+         Idea from Yuya Katayama <yuya999@gmail.com>
index 34fc91e8d03e5881b3d71359194a3a9f78e6e4c1..c5645f6c1956a43be743e56593320b1e88e00591 100644 (file)
 #endif
 
 #include "bashansi.h"
+#include "shmbutil.h"
 
 #include "shell.h"
 #include <readline/readline.h>
 
+static int _strcompare __P((char **, char **));
+
 /* Find greatest common prefix of two strings. */
 static int
 string_gcd (s1, s2)
@@ -145,6 +148,19 @@ really_munge_braces (array, real_start, real_end, gcd_zero)
   return (result);
 }
 
+static int
+_strcompare (s1, s2)
+     char **s1, **s2;
+{
+  int result;
+
+  result = **s1 - **s2;
+  if (result == 0)
+    result = strcmp (*s1, *s2);
+
+  return result;
+}
+
 static int
 hack_braces_completion (names)
      char **names;
@@ -152,7 +168,11 @@ hack_braces_completion (names)
   register int i;
   char *temp;
 
-  temp = really_munge_braces (names, 1, strvec_len (names), 0);
+  i = strvec_len (names);
+  if (MB_CUR_MAX > 1 && i > 2)
+    qsort (names+1, i-1, sizeof (char *), (QSFUNC *)_strcompare);
+      
+  temp = really_munge_braces (names, 1, i, 0);
 
   for (i = 0; names[i]; ++i)
     {
index 0a42ba61fbe627740cff25061715fed933a37fc4..0d74b65c1c0d80dd6ab7da4583f79f3da1b2d1f8 100644 (file)
@@ -107,31 +107,22 @@ extern int errno;
 
 #define PF(f, func) \
   do { \
-    char *b = 0; \
     int nw; \
     clearerr (stdout); \
     if (have_fieldwidth && have_precision) \
-      nw = asprintf(&b, f, fieldwidth, precision, func); \
+      nw = vflag ? vbprintf (f, fieldwidth, precision, func) : printf (f, fieldwidth, precision, func); \
     else if (have_fieldwidth) \
-      nw = asprintf(&b, f, fieldwidth, func); \
+      nw = vflag ? vbprintf (f, fieldwidth, func) : printf (f, fieldwidth, func); \
     else if (have_precision) \
-      nw = asprintf(&b, f, precision, func); \
+      nw = vflag ? vbprintf (f, precision, func) : printf (f, fieldwidth, func); \
     else \
-      nw = asprintf(&b, f, func); \
+      nw = vflag ? vbprintf (f, func) : printf (f, func); \
     tw += nw; \
-    if (b) \
+    if (ferror (stdout)) \
       { \
-       if (vflag) \
-         (void)vbadd (b, nw); \
-       else \
-         (void)fputs (b, stdout); \
-       if (ferror (stdout)) \
-         { \
-           sh_wrerror (); \
-           clearerr (stdout); \
-           return (EXECUTION_FAILURE); \
-         } \
-       free (b); \
+       sh_wrerror (); \
+       clearerr (stdout); \
+       return (EXECUTION_FAILURE); \
       } \
   } while (0)
 
@@ -175,11 +166,16 @@ extern int errno;
 extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
 #endif
 
+#ifndef HAVE_VSNPRINTF
+extern int vsnprintf __P((char *, size_t, const char *, ...)) __attribute__((__format__ (printf, 3, 4)));
+#endif
+
 static void printf_erange __P((char *));
 static int printstr __P((char *, char *, int, int, int));
 static int tescape __P((char *, char *, int *));
 static char *bexpand __P((char *, int, int *, int *));
 static char *vbadd __P((char *, int));
+static int vbprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
 static char *mklong __P((char *, char *, size_t));
 static int getchr __P((void));
 static char *getstr __P((void));
@@ -862,6 +858,42 @@ vbadd (buf, blen)
   return vbuf;
 }
 
+static int
+#if defined (PREFER_STDARG)
+vbprintf (const char *format, ...)
+#else
+vbprintf (format, va_alist)
+  const char *format;
+  va_dcl
+#endif
+{
+  va_list args;
+  size_t nlen;
+  int blen;
+
+  SH_VA_START (args, format);
+  blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
+
+  nlen = vblen + blen + 1;
+  if (nlen >= vbsize)
+    {
+      vbsize = ((nlen + 63) >> 6) << 6;
+      vbuf = (char *)xrealloc (vbuf, vbsize);
+      blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
+    }
+
+  va_end (args);
+  vblen += blen;
+  vbuf[vblen] = '\0';
+
+#ifdef DEBUG
+  if  (strlen (vbuf) != vblen)
+    internal_error  ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
+#endif
+  
+  return (blen);
+}
+
 static char *
 mklong (str, modifiers, mlen)
      char *str;
diff --git a/builtins/printf.def.save1 b/builtins/printf.def.save1
new file mode 100644 (file)
index 0000000..2b564cf
--- /dev/null
@@ -0,0 +1,1057 @@
+This file is printf.def, from which is created printf.c.
+It implements the builtin "printf" in Bash.
+
+Copyright (C) 1997-2008 Free Software Foundation, Inc.
+
+This file is part of GNU Bash, the Bourne Again SHell.
+
+Bash is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+Bash is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with Bash; see the file COPYING.  If not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+
+$PRODUCES printf.c
+
+$BUILTIN printf
+$FUNCTION printf_builtin
+$SHORT_DOC printf [-v var] format [arguments]
+Formats and prints ARGUMENTS under control of the FORMAT.
+
+Options:
+  -v var       assign the output to shell variable VAR rather than
+               display it on the standard output
+
+FORMAT is a character string which contains three types of objects: plain
+characters, which are simply copied to standard output; character escape
+sequences, which are converted and copied to the standard output; and
+format specifications, each of which causes printing of the next successive
+argument.
+
+In addition to the standard format specifications described in printf(1)
+and printf(3), printf interprets:
+
+  %b   expand backslash escape sequences in the corresponding argument
+  %q   quote the argument in a way that can be reused as shell input
+$END
+
+#include <config.h>
+
+#include "../bashtypes.h"
+
+#include <errno.h>
+#if defined (HAVE_LIMITS_H)
+#  include <limits.h>
+#else
+   /* Assume 32-bit ints. */
+#  define INT_MAX              2147483647
+#  define INT_MIN              (-2147483647-1)
+#endif
+
+#if defined (PREFER_STDARG)
+#  include <stdarg.h>
+#else
+#  include <varargs.h>
+#endif
+
+#include <stdio.h>
+#include <chartypes.h>
+
+#ifdef HAVE_INTTYPES_H
+#  include <inttypes.h>
+#endif
+
+#include "../bashansi.h"
+#include "../bashintl.h"
+
+#include "../shell.h"
+#include "shmbutil.h"
+#include "stdc.h"
+#include "bashgetopt.h"
+#include "common.h"
+
+#if defined (PRI_MACROS_BROKEN)
+#  undef PRIdMAX
+#endif
+
+#if !defined (PRIdMAX)
+#  if HAVE_LONG_LONG
+#    define PRIdMAX    "lld"
+#  else
+#    define PRIdMAX    "ld"
+#  endif
+#endif
+
+#if !defined (errno)
+extern int errno;
+#endif
+
+#define PC(c) \
+  do { \
+    char b[2]; \
+    tw++; \
+    b[0] = c; b[1] = '\0'; \
+    if (vflag) \
+      vbadd (b, 1); \
+    else \
+      putchar (c); \
+  } while (0)
+
+#define PF(f, func) \
+  do { \
+    char *b = 0; \
+    int nw; \
+    clearerr (stdout); \
+    if (have_fieldwidth && have_precision) \
+      nw = asprintf(&b, f, fieldwidth, precision, func); \
+    else if (have_fieldwidth) \
+      nw = asprintf(&b, f, fieldwidth, func); \
+    else if (have_precision) \
+      nw = asprintf(&b, f, precision, func); \
+    else \
+      nw = asprintf(&b, f, func); \
+    tw += nw; \
+    if (b) \
+      { \
+       if (vflag) \
+         (void)vbadd (b, nw); \
+       else \
+         (void)fputs (b, stdout); \
+       if (ferror (stdout)) \
+         { \
+           sh_wrerror (); \
+           clearerr (stdout); \
+           return (EXECUTION_FAILURE); \
+         } \
+       free (b); \
+      } \
+  } while (0)
+
+/* We free the buffer used by mklong() if it's `too big'. */
+#define PRETURN(value) \
+  do \
+    { \
+      if (vflag) \
+       { \
+         bind_variable  (vname, vbuf, 0); \
+         stupidly_hack_special_variables (vname); \
+       } \
+      if (conv_bufsize > 4096 ) \
+       { \
+         free (conv_buf); \
+         conv_bufsize = 0; \
+         conv_buf = 0; \
+       } \
+      if (vbsize > 4096) \
+       { \
+         free (vbuf); \
+         vbsize = 0; \
+         vbuf = 0; \
+       } \
+      else if (vbuf) \
+       vbuf[0] = 0; \
+      fflush (stdout); \
+      if (ferror (stdout)) \
+       { \
+         clearerr (stdout); \
+         return (EXECUTION_FAILURE); \
+       } \
+      return (value); \
+    } \
+  while (0)
+
+#define SKIP1 "#'-+ 0"
+#define LENMODS "hjlLtz"
+
+#ifndef HAVE_ASPRINTF
+extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
+#endif
+
+#ifndef HAVE_VSNPRINTF
+extern int vsnprintf __P((char *, size_t, const char *, ...)) __attribute__((__format__ (printf, 3, 4)));
+#endif
+
+static void printf_erange __P((char *));
+static int printstr __P((char *, char *, int, int, int));
+static int tescape __P((char *, char *, int *));
+static char *bexpand __P((char *, int, int *, int *));
+static char *vbadd __P((char *, int));
+static char *mklong __P((char *, char *, size_t));
+static int getchr __P((void));
+static char *getstr __P((void));
+static int  getint __P((void));
+static intmax_t getintmax __P((void));
+static uintmax_t getuintmax __P((void));
+
+#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN)
+typedef long double floatmax_t;
+#  define FLOATMAX_CONV        "L"
+#  define strtofltmax  strtold
+#else
+typedef double floatmax_t;
+#  define FLOATMAX_CONV        ""
+#  define strtofltmax  strtod
+#endif
+static floatmax_t getfloatmax __P((void));
+
+static intmax_t asciicode __P((void));
+
+static WORD_LIST *garglist;
+static int retval;
+static int conversion_error;
+
+/* printf -v var support */
+static int vflag = 0;
+static char *vbuf, *vname;
+static size_t vbsize;
+static int vblen;
+
+static intmax_t tw;
+
+static char *conv_buf;
+static size_t conv_bufsize;
+
+int
+printf_builtin (list)
+     WORD_LIST *list;
+{
+  int ch, fieldwidth, precision;
+  int have_fieldwidth, have_precision;
+  char convch, thisch, nextch, *format, *modstart, *fmt, *start;
+
+  conversion_error = 0;
+  retval = EXECUTION_SUCCESS;
+
+  vflag = 0;
+
+  reset_internal_getopt ();
+  while ((ch = internal_getopt (list, "v:")) != -1)
+    {
+      switch (ch)
+       {
+       case 'v':
+         if (legal_identifier (vname = list_optarg))
+           {
+             vflag = 1;
+             vblen = 0;
+             if (vbuf)
+               vbuf[0] = 0;
+           }
+         else
+           {
+             sh_invalidid (vname);
+             return (EX_USAGE);
+           }
+         break;
+       default:
+         builtin_usage ();
+         return (EX_USAGE);
+       }
+    }
+  list = loptend;      /* skip over possible `--' */
+
+  if (list == 0)
+    {
+      builtin_usage ();
+      return (EX_USAGE);
+    }
+
+  if (list->word->word == 0 || list->word->word[0] == '\0')
+    return (EXECUTION_SUCCESS);
+
+  format = list->word->word;
+  tw = 0;
+
+  garglist = list->next;
+
+  /* If the format string is empty after preprocessing, return immediately. */
+  if (format == 0 || *format == 0)
+    return (EXECUTION_SUCCESS);
+         
+  /* Basic algorithm is to scan the format string for conversion
+     specifications -- once one is found, find out if the field
+     width or precision is a '*'; if it is, gather up value.  Note,
+     format strings are reused as necessary to use up the provided
+     arguments, arguments of zero/null string are provided to use
+     up the format string. */
+  do
+    {
+      tw = 0;
+      /* find next format specification */
+      for (fmt = format; *fmt; fmt++)
+       {
+         precision = fieldwidth = 0;
+         have_fieldwidth = have_precision = 0;
+
+         if (*fmt == '\\')
+           {
+             fmt++;
+             /* A NULL third argument to tescape means to bypass the
+                special processing for arguments to %b. */
+             fmt += tescape (fmt, &nextch, (int *)NULL);
+             PC (nextch);
+             fmt--;    /* for loop will increment it for us again */
+             continue;
+           }
+
+         if (*fmt != '%')
+           {
+             PC (*fmt);
+             continue;
+           }
+
+         /* ASSERT(*fmt == '%') */
+         start = fmt++;
+
+         if (*fmt == '%')              /* %% prints a % */
+           {
+             PC ('%');
+             continue;
+           }
+
+         /* found format specification, skip to field width */
+         for (; *fmt && strchr(SKIP1, *fmt); ++fmt)
+           ;
+
+         /* Skip optional field width. */
+         if (*fmt == '*')
+           {
+             fmt++;
+             have_fieldwidth = 1;
+             fieldwidth = getint ();
+           }
+         else
+           while (DIGIT (*fmt))
+             fmt++;
+
+         /* Skip optional '.' and precision */
+         if (*fmt == '.')
+           {
+             ++fmt;
+             if (*fmt == '*')
+               {
+                 fmt++;
+                 have_precision = 1;
+                 precision = getint ();
+               }
+             else
+               {
+                 /* Negative precisions are allowed but treated as if the
+                    precision were missing; I would like to allow a leading
+                    `+' in the precision number as an extension, but lots
+                    of asprintf/fprintf implementations get this wrong. */
+#if 0
+                 if (*fmt == '-' || *fmt == '+')
+#else
+                 if (*fmt == '-')
+#endif
+                   fmt++;
+                 while (DIGIT (*fmt))
+                   fmt++;
+               }
+           }
+
+         /* skip possible format modifiers */
+         modstart = fmt;
+         while (*fmt && strchr (LENMODS, *fmt))
+           fmt++;
+           
+         if (*fmt == 0)
+           {
+             builtin_error (_("`%s': missing format character"), start);
+             PRETURN (EXECUTION_FAILURE);
+           }
+
+         convch = *fmt;
+         thisch = modstart[0];
+         nextch = modstart[1];
+         modstart[0] = convch;
+         modstart[1] = '\0';
+
+         switch(convch)
+           {
+           case 'c':
+             {
+               char p;
+
+               p = getchr ();
+               PF(start, p);
+               break;
+             }
+
+           case 's':
+             {
+               char *p;
+
+               p = getstr ();
+               PF(start, p);
+               break;
+             }
+
+           case 'n':
+             {
+               char *var;
+
+               var = getstr ();
+               if (var && *var)
+                 {
+                   if (legal_identifier (var))
+                     bind_var_to_int (var, tw);
+                   else
+                     {
+                       sh_invalidid (var);
+                       PRETURN (EXECUTION_FAILURE);
+                     }
+                 }
+               break;
+             }
+
+           case 'b':           /* expand escapes in argument */
+             {
+               char *p, *xp;
+               int rlen, r;
+
+               p = getstr ();
+               ch = rlen = r = 0;
+               xp = bexpand (p, strlen (p), &ch, &rlen);
+
+               if (xp)
+                 {
+                   /* Have to use printstr because of possible NUL bytes
+                      in XP -- printf does not handle that well. */
+                   r = printstr (start, xp, rlen, fieldwidth, precision);
+                   if (r < 0)
+                     {
+                       sh_wrerror ();
+                       clearerr (stdout);
+                       retval = EXECUTION_FAILURE;
+                     }
+                   free (xp);
+                 }
+
+               if (ch || r < 0)
+                 PRETURN (retval);
+               break;
+             }
+
+           case 'q':           /* print with shell quoting */
+             {
+               char *p, *xp;
+               int r;
+
+               r = 0;
+               p = getstr ();
+               if (p && *p == 0)       /* XXX - getstr never returns null */
+                 xp = savestring ("''");
+               else if (ansic_shouldquote (p))
+                 xp = ansic_quote (p, 0, (int *)0);
+               else
+                 xp = sh_backslash_quote (p);
+               if (xp)
+                 {
+                   /* Use printstr to get fieldwidth and precision right. */
+                   r = printstr (start, xp, strlen (xp), fieldwidth, precision);
+                   if (r < 0)
+                     {
+                       sh_wrerror ();
+                       clearerr (stdout);
+                     }
+                   free (xp);
+                 }
+
+               if (r < 0)
+                 PRETURN (EXECUTION_FAILURE);
+               break;
+             }
+
+           case 'd':
+           case 'i':
+             {
+               char *f;
+               long p;
+               intmax_t pp;
+
+               p = pp = getintmax ();
+               if (p != pp)
+                 {
+                   f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
+                   PF (f, pp);
+                 }
+               else
+                 {
+                   /* Optimize the common case where the integer fits
+                      in "long".  This also works around some long
+                      long and/or intmax_t library bugs in the common
+                      case, e.g. glibc 2.2 x86.  */
+                   f = mklong (start, "l", 1);
+                   PF (f, p);
+                 }
+               break;
+             }
+
+           case 'o':
+           case 'u':
+           case 'x':
+           case 'X':
+             {
+               char *f;
+               unsigned long p;
+               uintmax_t pp;
+
+               p = pp = getuintmax ();
+               if (p != pp)
+                 {
+                   f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
+                   PF (f, pp);
+                 }
+               else
+                 {
+                   f = mklong (start, "l", 1);
+                   PF (f, p);
+                 }
+               break;
+             }
+
+           case 'e':
+           case 'E':
+           case 'f':
+           case 'F':
+           case 'g':
+           case 'G':
+#if defined (HAVE_PRINTF_A_FORMAT)
+           case 'a':
+           case 'A':
+#endif
+             {
+               char *f;
+               floatmax_t p;
+
+               p = getfloatmax ();
+               f = mklong (start, FLOATMAX_CONV, sizeof(FLOATMAX_CONV) - 1);
+               PF (f, p);
+               break;
+             }
+
+           /* We don't output unrecognized format characters; we print an
+              error message and return a failure exit status. */
+           default:
+             builtin_error (_("`%c': invalid format character"), convch);
+             PRETURN (EXECUTION_FAILURE);
+           }
+
+         modstart[0] = thisch;
+         modstart[1] = nextch;
+       }
+
+      if (ferror (stdout))
+       {
+         sh_wrerror ();
+         clearerr (stdout);
+         PRETURN (EXECUTION_FAILURE);
+       }
+    }
+  while (garglist && garglist != list->next);
+
+  if (conversion_error)
+    retval = EXECUTION_FAILURE;
+
+  PRETURN (retval);
+}
+
+static void
+printf_erange (s)
+     char *s;
+{
+  builtin_error (_("warning: %s: %s"), s, strerror(ERANGE));
+}
+
+/* We duplicate a lot of what printf(3) does here. */
+static int
+printstr (fmt, string, len, fieldwidth, precision)
+     char *fmt;                        /* format */
+     char *string;             /* expanded string argument */
+     int len;                  /* length of expanded string */
+     int fieldwidth;           /* argument for width of `*' */
+     int precision;            /* argument for precision of `*' */
+{
+#if 0
+  char *s;
+#endif
+  int padlen, nc, ljust, i;
+  int fw, pr;                  /* fieldwidth and precision */
+
+#if 0
+  if (string == 0 || *string == '\0')
+#else
+  if (string == 0 || len == 0)
+#endif
+    return;
+
+#if 0
+  s = fmt;
+#endif
+  if (*fmt == '%')
+    fmt++;
+
+  ljust = fw = 0;
+  pr = -1;
+
+  /* skip flags */
+  while (strchr (SKIP1, *fmt))
+    {
+      if (*fmt == '-')
+       ljust = 1;
+      fmt++;
+    }
+
+  /* get fieldwidth, if present */
+  if (*fmt == '*')
+    {
+      fmt++;
+      fw = fieldwidth;
+      if (fw < 0)
+       {
+         fw = -fw;
+         ljust = 1;
+       }
+    }
+  else if (DIGIT (*fmt))
+    {
+      fw = *fmt++ - '0';
+      while (DIGIT (*fmt))
+       fw = (fw * 10) + (*fmt++ - '0');
+    }
+
+  /* get precision, if present */
+  if (*fmt == '.')
+    {
+      fmt++;
+      if (*fmt == '*')
+       {
+         fmt++;
+         pr = precision;
+       }
+      else if (DIGIT (*fmt))
+       {
+         pr = *fmt++ - '0';
+         while (DIGIT (*fmt))
+           pr = (pr * 10) + (*fmt++ - '0');
+       }
+    }
+
+#if 0
+  /* If we remove this, get rid of `s'. */
+  if (*fmt != 'b' && *fmt != 'q')
+    {
+      internal_error ("format parsing problem: %s", s);
+      fw = pr = 0;
+    }
+#endif
+
+  /* chars from string to print */
+  nc = (pr >= 0 && pr <= len) ? pr : len;
+
+  padlen = fw - nc;
+  if (padlen < 0)
+    padlen = 0;
+  if (ljust)
+    padlen = -padlen;
+
+  /* leading pad characters */
+  for (; padlen > 0; padlen--)
+    PC (' ');
+
+  /* output NC characters from STRING */
+  for (i = 0; i < nc; i++)
+    PC (string[i]);
+
+  /* output any necessary trailing padding */
+  for (; padlen < 0; padlen++)
+    PC (' ');
+
+  return (ferror (stdout) ? -1 : 0);
+}
+  
+/* Convert STRING by expanding the escape sequences specified by the
+   POSIX standard for printf's `%b' format string.  If SAWC is non-null,
+   perform the processing appropriate for %b arguments.  In particular,
+   recognize `\c' and use that as a string terminator.  If we see \c, set
+   *SAWC to 1 before returning.  LEN is the length of STRING. */
+
+/* Translate a single backslash-escape sequence starting at ESTART (the
+   character after the backslash) and return the number of characters
+   consumed by the sequence.  CP is the place to return the translated
+   value.  *SAWC is set to 1 if the escape sequence was \c, since that means
+   to short-circuit the rest of the processing.  If SAWC is null, we don't
+   do the \c short-circuiting, and \c is treated as an unrecognized escape
+   sequence; we also bypass the other processing specific to %b arguments.  */
+static int
+tescape (estart, cp, sawc)
+     char *estart;
+     char *cp;
+     int *sawc;
+{
+  register char *p;
+  int temp, c, evalue;
+
+  p = estart;
+
+  switch (c = *p++)
+    {
+#if defined (__STDC__)
+      case 'a': *cp = '\a'; break;
+#else
+      case 'a': *cp = '\007'; break;
+#endif
+
+      case 'b': *cp = '\b'; break;
+
+      case 'e':
+      case 'E': *cp = '\033'; break;   /* ESC -- non-ANSI */
+
+      case 'f': *cp = '\f'; break;
+
+      case 'n': *cp = '\n'; break;
+
+      case 'r': *cp = '\r'; break;
+
+      case 't': *cp = '\t'; break;
+
+      case 'v': *cp = '\v'; break;
+
+      /* The octal escape sequences are `\0' followed by up to three octal
+        digits (if SAWC), or `\' followed by up to three octal digits (if
+        !SAWC).  As an extension, we allow the latter form even if SAWC. */
+      case '0': case '1': case '2': case '3':
+      case '4': case '5': case '6': case '7':
+       evalue = OCTVALUE (c);
+       for (temp = 2 + (!evalue && !!sawc); ISOCTAL (*p) && temp--; p++)
+         evalue = (evalue * 8) + OCTVALUE (*p);
+       *cp = evalue & 0xFF;
+       break;
+
+      /* And, as another extension, we allow \xNNN, where each N is a
+        hex digit. */
+      case 'x':
+#if 0
+       for (evalue = 0; ISXDIGIT ((unsigned char)*p); p++)
+#else
+       for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++)
+#endif
+         evalue = (evalue * 16) + HEXVALUE (*p);
+       if (p == estart + 1)
+         {
+           builtin_error (_("missing hex digit for \\x"));
+           *cp = '\\';
+           return 0;
+         }
+       *cp = evalue & 0xFF;
+       break;
+
+      case '\\':       /* \\ -> \ */
+       *cp = c;
+       break;
+
+      /* SAWC == 0 means that \', \", and \? are recognized as escape
+        sequences, though the only processing performed is backslash
+        removal. */
+      case '\'': case '"': case '?':
+       if (!sawc)
+         *cp = c;
+       else
+         {
+           *cp = '\\';
+           return 0;
+         }
+       break;
+
+      case 'c':
+       if (sawc)
+         {
+           *sawc = 1;
+           break;
+         }
+      /* other backslash escapes are passed through unaltered */
+      default:
+       *cp = '\\';
+       return 0;
+      }
+  return (p - estart);
+}
+
+static char *
+bexpand (string, len, sawc, lenp)
+     char *string;
+     int len, *sawc, *lenp;
+{
+  int temp;
+  char *ret, *r, *s, c;
+
+#if 0
+  if (string == 0 || *string == '\0')
+#else
+  if (string == 0 || len == 0)
+#endif
+    {
+      if (sawc)
+       *sawc = 0;
+      if (lenp)
+       *lenp = 0;
+      return ((char *)NULL);
+    }
+
+  ret = (char *)xmalloc (len + 1);
+  for (r = ret, s = string; s && *s; )
+    {
+      c = *s++;
+      if (c != '\\' || *s == '\0')
+       {
+         *r++ = c;
+         continue;
+       }
+      temp = 0;
+      s += tescape (s, &c, &temp);
+      if (temp)
+       {
+         if (sawc)
+           *sawc = 1;
+         break;
+       }
+
+      *r++ = c;
+    }
+
+  *r = '\0';
+  if (lenp)
+    *lenp = r - ret;
+  return ret;
+}
+
+static char *
+vbadd (buf, blen)
+     char *buf;
+     int blen;
+{
+  size_t nlen;
+
+  nlen = vblen + blen + 1;
+  if (nlen >= vbsize)
+    {
+      vbsize = ((nlen + 63) >> 6) << 6;
+      vbuf = (char *)xrealloc (vbuf, vbsize);
+    }
+
+  if (blen == 1)
+    vbuf[vblen++] = buf[0];
+  else if (blen > 1)
+    {
+      FASTCOPY (buf, vbuf  + vblen, blen);
+      vblen += blen;
+    }
+  vbuf[vblen] = '\0';
+
+#ifdef DEBUG
+  if  (strlen (vbuf) != vblen)
+    internal_error  ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
+#endif
+
+  return vbuf;
+}
+
+static char *
+mklong (str, modifiers, mlen)
+     char *str;
+     char *modifiers;
+     size_t mlen;
+{
+  size_t len, slen;
+
+  slen = strlen (str);
+  len = slen + mlen + 1;
+
+  if (len > conv_bufsize)
+    {
+      conv_bufsize = (((len + 1023) >> 10) << 10);
+      conv_buf = (char *)xrealloc (conv_buf, conv_bufsize);
+    }
+
+  FASTCOPY (str, conv_buf, slen - 1);
+  FASTCOPY (modifiers, conv_buf + slen - 1, mlen);
+
+  conv_buf[len - 2] = str[slen - 1];
+  conv_buf[len - 1] = '\0';
+  return (conv_buf);
+}
+
+static int
+getchr ()
+{
+  int ret;
+
+  if (garglist == 0)
+    return ('\0');
+
+  ret = (int)garglist->word->word[0];
+  garglist = garglist->next;
+  return ret;
+}
+
+static char *
+getstr ()
+{
+  char *ret;
+
+  if (garglist == 0)
+    return ("");
+
+  ret = garglist->word->word;
+  garglist = garglist->next;
+  return ret;
+}
+
+static int
+getint ()
+{
+  intmax_t ret;
+
+  ret = getintmax ();
+
+  if (ret > INT_MAX)
+    {
+      printf_erange (garglist->word->word);
+      ret = INT_MAX;
+    }
+  else if (ret < INT_MIN)
+    {
+      printf_erange (garglist->word->word);
+      ret = INT_MIN;
+    }
+
+  return ((int)ret);
+}
+
+static intmax_t
+getintmax ()
+{
+  intmax_t ret;
+  char *ep;
+
+  if (garglist == 0)
+    return (0);
+
+  if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
+    return asciicode ();
+
+  errno = 0;
+  ret = strtoimax (garglist->word->word, &ep, 0);
+
+  if (*ep)
+    {
+      sh_invalidnum (garglist->word->word);
+      /* POSIX.2 says ``...a diagnostic message shall be written to standard
+        error, and the utility shall not exit with a zero exit status, but
+        shall continue processing any remaining operands and shall write the
+         value accumulated at the time the error was detected to standard
+        output.''  Yecch. */
+      ret = 0;
+      conversion_error = 1;
+    }
+  else if (errno == ERANGE)
+    printf_erange (garglist->word->word);
+
+  garglist = garglist->next;
+  return (ret);
+}
+
+static uintmax_t
+getuintmax ()
+{
+  uintmax_t ret;
+  char *ep;
+
+  if (garglist == 0)
+    return (0);
+
+  if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
+    return asciicode ();
+
+  errno = 0;
+  ret = strtoumax (garglist->word->word, &ep, 0);
+  
+  if (*ep)
+    {
+      sh_invalidnum (garglist->word->word);
+      /* Same POSIX.2 conversion error requirements as getintmax(). */
+      ret = 0;
+      conversion_error = 1;
+    }
+  else if (errno == ERANGE)
+    printf_erange (garglist->word->word);
+
+  garglist = garglist->next;
+  return (ret);
+}
+
+static floatmax_t
+getfloatmax ()
+{
+  floatmax_t ret;
+  char *ep;
+
+  if (garglist == 0)
+    return (0);
+
+  if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
+    return asciicode ();
+
+  errno = 0;
+  ret = strtofltmax (garglist->word->word, &ep);
+
+  if (*ep)
+    {
+      sh_invalidnum (garglist->word->word);
+      /* Same thing about POSIX.2 conversion error requirements. */
+      ret = 0;
+      conversion_error = 1;
+    }
+  else if (errno == ERANGE)
+    printf_erange (garglist->word->word);
+
+  garglist = garglist->next;
+  return (ret);
+}
+
+/* NO check is needed for garglist here. */
+static intmax_t
+asciicode ()
+{
+  register intmax_t ch;
+#if defined (HANDLE_MULTIBYTE)
+  wchar_t wc;
+  size_t mblength, slen;
+#endif
+  DECLARE_MBSTATE;
+
+#if defined (HANDLE_MULTIBYTE)
+  slen = strlen (garglist->word->word+1);
+  mblength = MBLEN (garglist->word->word+1, slen);
+  if (mblength > 1)
+    {
+      mblength = mbtowc (&wc, garglist->word->word+1, slen);
+      ch = wc;         /* XXX */
+    }
+  else
+#endif
+    ch = (unsigned char)garglist->word->word[1];
+
+  garglist = garglist->next;
+  return (ch);
+}
index e26e9796098c6515af51686ba52fa25fafe0ed70..620f8f3d8b5cd928556eac4fec9d1d712fdb317d 100644 (file)
@@ -37,7 +37,7 @@ format specifications, each of which causes printing of the next successive
 argument.
 
 In addition to the standard format specifications described in printf(1)
-and printf(3), print interprets:
+and printf(3), printf interprets:
 
   %b   expand backslash escape sequences in the corresponding argument
   %q   quote the argument in a way that can be reused as shell input
@@ -107,31 +107,22 @@ extern int errno;
 
 #define PF(f, func) \
   do { \
-    char *b = 0; \
     int nw; \
     clearerr (stdout); \
     if (have_fieldwidth && have_precision) \
-      nw = asprintf(&b, f, fieldwidth, precision, func); \
+      nw = vflag ? vbprintf (f, fieldwidth, precision, func) : printf (f, fieldwidth, precision, func); \
     else if (have_fieldwidth) \
-      nw = asprintf(&b, f, fieldwidth, func); \
+      nw = vflag ? vbprintf (f, fieldwidth, func) : printf (f, fieldwidth, func); \
     else if (have_precision) \
-      nw = asprintf(&b, f, precision, func); \
+      nw = vflag ? vbprintf (f, precision, func) : printf (f, fieldwidth, func); \
     else \
-      nw = asprintf(&b, f, func); \
+      nw = vflag ? vbprintf (f, func) : printf (f, func); \
     tw += nw; \
-    if (b) \
+    if (ferror (stdout)) \
       { \
-       if (vflag) \
-         (void)vbadd (b, nw); \
-       else \
-         (void)fputs (b, stdout); \
-       if (ferror (stdout)) \
-         { \
-           sh_wrerror (); \
-           clearerr (stdout); \
-           return (EXECUTION_FAILURE); \
-         } \
-       free (b); \
+       sh_wrerror (); \
+       clearerr (stdout); \
+       return (EXECUTION_FAILURE); \
       } \
   } while (0)
 
@@ -175,11 +166,17 @@ extern int errno;
 extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
 #endif
 
+#ifndef HAVE_VSNPRINTF
+extern int vsnprintf __P((char *, size_t, const char *, ...)) __attribute__((__format__ (printf, 3, 4)));
+#endif
+
 static void printf_erange __P((char *));
 static int printstr __P((char *, char *, int, int, int));
 static int tescape __P((char *, char *, int *));
 static char *bexpand __P((char *, int, int *, int *));
 static char *vbadd __P((char *, int));
+static int vbprintf __P((const char *, ...))
+ __attribute__((__format__ (printf, 1, 2)));
 static char *mklong __P((char *, char *, size_t));
 static int getchr __P((void));
 static char *getstr __P((void));
@@ -862,6 +859,42 @@ vbadd (buf, blen)
   return vbuf;
 }
 
+static int
+#if defined (PREFER_STDARG)
+vbprintf (const char *format, ...)
+#else
+vbprintf (format, va_alist)
+  const char *format;
+  va_dcl
+#endif
+{
+  va_list args;
+  size_t nlen;
+  int blen;
+
+  SH_VA_START (args, format);
+  blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
+
+  nlen = vblen + blen + 1;
+  if (nlen >= vbsize)
+    {
+      vbsize = ((nlen + 63) >> 6) << 6;
+      vbuf = (char *)xrealloc (vbuf, vbsize);
+      blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
+    }
+
+  va_end (args);
+  vblen += blen;
+  vbuf[vblen] = '\0';
+
+#ifdef DEBUG
+  if  (strlen (vbuf) != vblen)
+    internal_error  ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
+#endif
+  
+  return (blen);
+}
+
 static char *
 mklong (str, modifiers, mlen)
      char *str;
index 3dad963ae86b9ae021aa3ce0386eff45c0b4e6e3..b4d957283111f6421cfe8511281cbb923db8bd2a 100644 (file)
@@ -506,9 +506,13 @@ rl_redisplay ()
   int _rl_wrapped_multicolumn = 0;
 #endif
 
-  if (!readline_echoing_p)
+  if (readline_echoing_p == 0)
     return;
 
+  /* Block keyboard interrupts because this function manipulates global
+     data structures. */
+  _rl_block_sigint ();  
+
   if (!rl_display_prompt)
     rl_display_prompt = "";
 
@@ -1233,6 +1237,8 @@ rl_redisplay ()
     else
       visible_wrap_offset = wrap_offset;
   }
+
+  _rl_release_sigint ();
 }
 
 /* PWP: update_line() is based on finding the middle difference of each
index 58e12f75d1fb55835e4276b1c3d185398a7a02af..3dad963ae86b9ae021aa3ce0386eff45c0b4e6e3 100644 (file)
@@ -656,7 +656,6 @@ rl_redisplay ()
 #endif
 
 #if defined (HANDLE_MULTIBYTE)
-  if (line_state_invisible 
   memset (line_state_invisible->wrapped_line, 0, line_state_invisible->wbsize * sizeof (int));
   num = 0;
 #endif
index 3c6da875ae5aa7c3577430bbce76191918cec4a5..4f499330c59b71c3387afac2b3ef7a44d0b30d83 100644 (file)
@@ -523,6 +523,20 @@ Readline is performing word completion.
 Readline is currently executing the readline signal handler.
 @item RL_STATE_UNDOING
 Readline is performing an undo.
+@item RL_STATE_INPUTPENDING
+Readline has input pending due to a call to @code{rl_execute_next()}.
+@item RL_STATE_TTYCSAVED
+Readline has saved the values of the terminal's special characters.
+@item RL_STATE_CALLBACK
+Readline is currently using the alternate (callback) interface
+(@pxref{Alternate Interface}).
+@item RL_STATE_VIMOTION
+Readline is reading the argument to a vi-mode "motion" command.
+@item RL_STATE_MULTIKEY
+Readline is reading a multiple-keystroke command.
+@item RL_STATE_VICMDONCE
+Readline has entered vi command (movement) mode at least one time during
+the current call to @code{readline()}.
 @item RL_STATE_DONE
 Readline has read a key sequence bound to @code{accept-line}
 and is about to return the line to the caller.
@@ -1083,6 +1097,21 @@ environment variable is used.
 @node Utility Functions
 @subsection Utility Functions
 
+@deftypefun int rl_save_state (struct readline_state *sp)
+Save a snapshot of Readline's internal state to @var{sp}.
+The contents of the @var{readline_state} structure are documented
+in @file{readline.h}.
+The caller is responsible for allocating the structure.
+@end deftypefun
+
+@deftypefun int rl_restore_state (struct readline_state *sp)
+Restore Readline's internal state to that stored in @var{sp}, which must
+have been saved by a call to @code{rl_save_state}.
+The contents of the @var{readline_state} structure are documented
+in @file{readline.h}.
+The caller is responsible for freeing the structure.
+@end deftypefun
+
 @deftypefun void rl_free (void *mem)
 Deallocate the memory pointed to by @var{mem}.  @var{mem} must have been
 allocated by @code{malloc}.
index 8ee15261e81e059ed3d5ad50063573d8b60ce038..79f638b764f48b39d5f406af501433f46afe8763 100644 (file)
@@ -1,7 +1,6 @@
 @comment %**start of header (This is for running Texinfo on a region.)
 @setfilename rltech.info
 @comment %**end of header (This is for running Texinfo on a region.)
-@setchapternewpage odd
 
 @ifinfo
 This document describes the GNU Readline Library, a utility for aiding
@@ -1084,6 +1083,21 @@ environment variable is used.
 @node Utility Functions
 @subsection Utility Functions
 
+@deftypefun int rl_save_state (struct readline_state *sp)
+Save a snapshot of Readline's internal state to @var{sp}.
+The contents of the @var{readline_state} structure are documented
+in @file{readline.h}.
+The caller is responsible for allocating the structure.
+@end deftypefun
+
+@deftypefun int rl_restore_state (struct readline_state *sp)
+Restore Readline's internal state to that stored in @var{sp}, which must
+have been saved by a call to @code{rl_save_state}.
+The contents of the @var{readline_state} structure are documented
+in @file{readline.h}.
+The caller is responsible for freeing the structure.
+@end deftypefun
+
 @deftypefun void rl_free (void *mem)
 Deallocate the memory pointed to by @var{mem}.  @var{mem} must have been
 allocated by @code{malloc}.
index 3d629fded37cdf9249d66dccdee5f6e9a07c4708..a31b092bf222ceedd14a252954937adb9e29b535 100644 (file)
@@ -305,7 +305,9 @@ readline (prompt)
      const char *prompt;
 {
   char *value;
+#if 0
   int in_callback;
+#endif
 
   /* If we are at EOF return a NULL string. */
   if (rl_pending_input == EOF)
index 498b06112cef6351a85df5d477f66cf041e78626..91693faa9dab261dcbe829315a2f1033cf1894c3 100644 (file)
@@ -1,7 +1,7 @@
 /* readline.c -- a general facility for reading lines of input
    with emacs style editing and completion. */
 
-/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2008 Free Software Foundation, Inc.
 
    This file is part of the GNU Readline Library, a library for
    reading lines of text with interactive input and history editing.
@@ -1189,6 +1189,7 @@ rl_save_state (sp)
   sp->prompt = rl_prompt;
 
   sp->rlstate = rl_readline_state;
+  sp->in_callback = RL_ISSTATE (RL_STATE_CALLBACK).
   sp->done = rl_done;
   sp->kmap = _rl_keymap;
 
@@ -1223,6 +1224,7 @@ rl_restore_state (sp)
   rl_prompt = sp->prompt;
 
   rl_readline_state = sp->rlstate;
+  /* Don't need to do anything with sp->in_callback */
   rl_done = sp->done;
   _rl_keymap = sp->kmap;
 
index 8b0ad269e21069d281b2231e11ed1c11456ef236..1e26dce1d06d3aac7bb4c11383cc3c840d782d2b 100644 (file)
@@ -294,6 +294,10 @@ extern int _rl_restore_tty_signals PARAMS((void));
 /* search.c */
 extern int _rl_nsearch_callback PARAMS((_rl_search_cxt *));
 
+/* signals.c */
+extern void _rl_block_sigint PARAMS((void));
+extern void _rl_release_sigint PARAMS((void));
+
 /* terminal.c */
 extern void _rl_get_screen_size PARAMS((int, int));
 extern int _rl_init_terminal_io PARAMS((const char *));
index 8e1079940011a218ca825fb5ac02e1f2691f4347..8b0ad269e21069d281b2231e11ed1c11456ef236 100644 (file)
@@ -216,6 +216,7 @@ extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *));
 /* bind.c */
 
 /* complete.c */
+extern void _rl_reset_completion_state PARAMS((void));
 extern char _rl_find_completion_word PARAMS((int *, int *));
 extern void _rl_free_match_list PARAMS((char **));
 
index 47c462897cf4fd7f19e6d353622d5dbaed222c76..f2120cb1ad8c6bfbb376c6f951801528699bfefa 100644 (file)
@@ -52,75 +52,8 @@ extern int errno;
 rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
 rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
 
-static void block_sigint PARAMS((void));
-static void release_sigint PARAMS((void));
-
 static void set_winsize PARAMS((int));
 
-/* **************************************************************** */
-/*                                                                 */
-/*                        Signal Management                        */
-/*                                                                 */
-/* **************************************************************** */
-
-#if defined (HAVE_POSIX_SIGNALS)
-static sigset_t sigint_set, sigint_oset;
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-static int sigint_oldmask;
-#  endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-static int sigint_blocked;
-
-/* Cause SIGINT to not be delivered until the corresponding call to
-   release_sigint(). */
-static void
-block_sigint ()
-{
-  if (sigint_blocked)
-    return;
-
-#if defined (HAVE_POSIX_SIGNALS)
-  sigemptyset (&sigint_set);
-  sigemptyset (&sigint_oset);
-  sigaddset (&sigint_set, SIGINT);
-  sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-  sigint_oldmask = sigblock (sigmask (SIGINT));
-#  else /* !HAVE_BSD_SIGNALS */
-#    if defined (HAVE_USG_SIGHOLD)
-  sighold (SIGINT);
-#    endif /* HAVE_USG_SIGHOLD */
-#  endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  sigint_blocked = 1;
-}
-
-/* Allow SIGINT to be delivered. */
-static void
-release_sigint ()
-{
-  if (sigint_blocked == 0)
-    return;
-
-#if defined (HAVE_POSIX_SIGNALS)
-  sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
-#else
-#  if defined (HAVE_BSD_SIGNALS)
-  sigsetmask (sigint_oldmask);
-#  else /* !HAVE_BSD_SIGNALS */
-#    if defined (HAVE_USG_SIGHOLD)
-  sigrelse (SIGINT);
-#    endif /* HAVE_USG_SIGHOLD */
-#  endif /* !HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-
-  sigint_blocked = 0;
-}
-
 /* **************************************************************** */
 /*                                                                 */
 /*                   Saving and Restoring the TTY                  */
@@ -663,7 +596,7 @@ rl_prep_terminal (meta_flag)
     return;
 
   /* Try to keep this function from being INTerrupted. */
-  block_sigint ();
+  _rl_block_sigint ();
 
   tty = fileno (rl_instream);
 
@@ -677,7 +610,8 @@ rl_prep_terminal (meta_flag)
       if (errno == ENOTTY || errno == EINVAL)
 #endif
        readline_echoing_p = 1;         /* XXX */
-      release_sigint ();
+
+      _rl_release_sigint ();
       return;
     }
 
@@ -712,7 +646,7 @@ rl_prep_terminal (meta_flag)
 
   if (set_tty_settings (tty, &tio) < 0)
     {
-      release_sigint ();
+      _rl_release_sigint ();
       return;
     }
 
@@ -723,7 +657,7 @@ rl_prep_terminal (meta_flag)
   terminal_prepped = 1;
   RL_SETSTATE(RL_STATE_TERMPREPPED);
 
-  release_sigint ();
+  _rl_release_sigint ();
 }
 
 /* Restore the terminal's normal settings and modes. */
@@ -736,7 +670,7 @@ rl_deprep_terminal ()
     return;
 
   /* Try to keep this function from being interrupted. */
-  block_sigint ();
+  _rl_block_sigint ();
 
   tty = fileno (rl_instream);
 
@@ -747,14 +681,14 @@ rl_deprep_terminal ()
 
   if (set_tty_settings (tty, &otio) < 0)
     {
-      release_sigint ();
+      _rl_release_sigint ();
       return;
     }
 
   terminal_prepped = 0;
   RL_UNSETSTATE(RL_STATE_TERMPREPPED);
 
-  release_sigint ();
+  _rl_release_sigint ();
 }
 #endif /* !NO_TTY_DRIVER */
 \f
index a51fe2dac31b7ea4cd362ef6da17b2b39731f2be..47c462897cf4fd7f19e6d353622d5dbaed222c76 100644 (file)
@@ -670,10 +670,11 @@ rl_prep_terminal (meta_flag)
   if (get_tty_settings (tty, &tio) < 0)
     {
 #if defined (ENOTSUP)
-      /* MacOS X, at least, lies about the value of errno if tcgetattr fails. */
-      if (errno == ENOTTY || errno == ENOTSUP)
+      /* MacOS X and Linux, at least, lie about the value of errno if
+        tcgetattr fails. */
+      if (errno == ENOTTY || errno == EINVAL || errno == ENOTSUP)
 #else
-      if (errno == ENOTTY)
+      if (errno == ENOTTY || errno == EINVAL)
 #endif
        readline_echoing_p = 1;         /* XXX */
       release_sigint ();
index f79d65b154e2f85adced30d730bcb256ef909270..d7564cfc3951154c3725361f56aaf1398f4b1c6f 100644 (file)
 #  include <sys/ioctl.h>
 #endif /* GWINSZ_IN_SYS_IOCTL */
 
-#if defined (HANDLE_SIGNALS)
 /* Some standard library routines. */
 #include "readline.h"
 #include "history.h"
 
 #include "rlprivate.h"
 
+#if defined (HANDLE_SIGNALS)
+
 #if !defined (RETSIGTYPE)
 #  if defined (VOID_SIGHANDLER)
 #    define RETSIGTYPE void
@@ -465,3 +466,67 @@ rl_free_line_state ()
 }
 
 #endif  /* HANDLE_SIGNALS */
+
+/* **************************************************************** */
+/*                                                                 */
+/*                        SIGINT Management                        */
+/*                                                                 */
+/* **************************************************************** */
+
+#if defined (HAVE_POSIX_SIGNALS)
+static sigset_t sigint_set, sigint_oset;
+#else /* !HAVE_POSIX_SIGNALS */
+#  if defined (HAVE_BSD_SIGNALS)
+static int sigint_oldmask;
+#  endif /* HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+static int sigint_blocked;
+
+/* Cause SIGINT to not be delivered until the corresponding call to
+   release_sigint(). */
+void
+_rl_block_sigint ()
+{
+  if (sigint_blocked)
+    return;
+
+#if defined (HAVE_POSIX_SIGNALS)
+  sigemptyset (&sigint_set);
+  sigemptyset (&sigint_oset);
+  sigaddset (&sigint_set, SIGINT);
+  sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
+#else /* !HAVE_POSIX_SIGNALS */
+#  if defined (HAVE_BSD_SIGNALS)
+  sigint_oldmask = sigblock (sigmask (SIGINT));
+#  else /* !HAVE_BSD_SIGNALS */
+#    if defined (HAVE_USG_SIGHOLD)
+  sighold (SIGINT);
+#    endif /* HAVE_USG_SIGHOLD */
+#  endif /* !HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+  sigint_blocked = 1;
+}
+
+/* Allow SIGINT to be delivered. */
+void
+_rl_release_sigint ()
+{
+  if (sigint_blocked == 0)
+    return;
+
+#if defined (HAVE_POSIX_SIGNALS)
+  sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
+#else
+#  if defined (HAVE_BSD_SIGNALS)
+  sigsetmask (sigint_oldmask);
+#  else /* !HAVE_BSD_SIGNALS */
+#    if defined (HAVE_USG_SIGHOLD)
+  sigrelse (SIGINT);
+#    endif /* HAVE_USG_SIGHOLD */
+#  endif /* !HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+  sigint_blocked = 0;
+}
index c088b6f42c99feafc4e670e411365f2f2be350e3..f79d65b154e2f85adced30d730bcb256ef909270 100644 (file)
@@ -142,6 +142,7 @@ rl_signal_handler (sig)
   switch (sig)
     {
     case SIGINT:
+      _rl_reset_completion_state ();
       rl_free_line_state ();
       /* FALLTHROUGH */