]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20050519 snapshot
authorChet Ramey <chet.ramey@case.edu>
Sat, 3 Dec 2011 18:47:06 +0000 (13:47 -0500)
committerChet Ramey <chet.ramey@case.edu>
Sat, 3 Dec 2011 18:47:06 +0000 (13:47 -0500)
22 files changed:
CWRU/CWRU.chlog
CWRU/CWRU.chlog~
array.c
array.c~
builtins/exec.def
builtins/exec.def~ [new file with mode: 0644]
builtins/read.def
builtins/read.def~
execute_cmd.c
execute_cmd.c~
jobs.c
jobs.c~
lib/readline/callback.c
lib/readline/display.c~
lib/readline/examples/rlptytest.c [new file with mode: 0644]
lib/readline/macro.c
lib/readline/readline.c
lib/readline/rlprivate.h
lib/readline/search.c
lib/readline/vi_mode.c
parse.y~
version.c

index 7444a86702a92e757fef6f19087e7b19350e6b6a..5c758cf818f93b08152dc6ce2fc58b6600600653 100644 (file)
@@ -11503,3 +11503,109 @@ lib/readline/text.c
 lib/readline/vi_mode.c
        - changed set-mark, goto-mark, change-char, and char-search to work
          when called by callback functions
+
+                                  5/17
+                                  ----
+
+lib/readline/rlprivate.h
+       - new struct declaration for a `reading key sequence' context
+
+lib/readline/readline.c
+       - new variable, _rl_dispatching_keymap, keeps track of which keymap
+         we are currently searching
+       - functions to allocate and deallocate contexts for reading multi-char
+         key sequences
+
+                                  5/18
+                                  ----
+lib/readline/rlprivate.h
+       - new struct defining a context for multiple-key key sequences (the
+         base case is escape-prefixed commands)
+
+lib/readline/readline.c
+       - change structure of _rl_dispatch_subseq to allow for callback code
+         to use it - rudimentary support for supporting the existing
+         recursion using a stack of contexts, each with a reference to the
+         previous
+       - fix so that  ^G works when in callback mode
+
+lib/readline/callback.c
+       - call the appropriate multiple-key sequence callback if the state is
+         set
+
+                                  5/19
+                                  ----
+lib/readline/readline.c
+       - broke code from _readline_internal_char after call to rl_dispatch
+         out into separate function:  _rl_internal_char_cleanup, callable by
+         other parts of the code
+       - change _rl_internal_char_cleanup to unset _rl_want_redisplay after
+         it calls (*rl_redisplay_func)
+
+lib/readline/callback.c
+       - call _rl_internal_char_cleanup from rl_callback_read_char when
+         appropriate
+
+                                  5/24
+                                  ----
+lib/readline/callback.c
+       - use _rl_dispatch_callback and a chain of _rl_keyseq_contexts to
+         simulate the recursion used to decode multicharacter key sequences
+         (even things like ESC- as meta-prefix)
+       - call setjmp in rl_callback_read_char to give things like rl_abort
+         a place to jump, since the saved location in readline() will not
+         be valid
+       - keep calling _rl_dispatch_callback from rl_callback_read_char while
+         we are still decoding a multi-key key sequence
+       - keep calling readline_internal_char from rl_callback_read_char while
+         we are reading characters from a macro
+
+lib/readline/macro.c
+       - use a slightly different strategy upon encountering the end of a macro
+         when using the callback interface:  when the last character of a
+         macro is read, and we are reading a command, pop the macro off the    
+         stack immediately so the loop in rl_callback_read_char terminates
+         when it should
+
+lib/readline/readline.c
+       - if longjmp() is called and we end up at the saved location while
+         using the callback interface, just return -- don't go back into a
+         blocking read
+       - new function to dispose a chain of rl_keyseq_cxts
+       - only read new input in _rl_dispatch_callback if the KSEQ_DISPATCHED
+         flag is not set in the current keyseq context -- if it is, we are
+         traversing the chain back up and should use what we already saved
+       - use -3 as a magic value from _rl_dispatch_subseq to indicate that
+         we're allocating a new context and moving downward in the chain
+         (a special return value for the benefit of _rl_dispatch_callback)
+
+lib/readline/rlprivate.h
+       - new extern declaration for _rl_keyseq_chain_dispose
+
+                                   6/1
+                                   ---
+builtins/read.def
+       - fixed a bug that occurred when reading a set number of chars and
+         the nth char is a backslash (read one too many).  Bug reported by
+         Chris Morgan <chmorgan@gmail.com>
+
+execute_cmd.c
+       - fix execute_builtin so the `unset' builtin also operates on the
+         temporary environment in POSIX mode (as well as source and eval),
+         so that unsetting variables in the temporary environment doesn't
+         leave them set when unset completes.  Report by Eric Blake
+         <ebb9@byu.net>
+
+array.c
+       - fix from William Park for array_rshift when shifting right on an
+         empty array -- corrects calculation of array->max_index
+
+builtins/exec.def
+       - if an exec fails and the execfail option is set, don't call
+         restart_job_control unless the shell is interactive or job_control
+         is set
+
+jobs.c
+       - add a run-time check for WCONTINUED being defined in header files
+         but rejected with EINVAL by waitpid().  Fix from Maciej Rozycki
+         <macro@linux-mips.org>
index 32e1239f54d1f9f0e25c33ecdf9369ac2f56285d..29ae0607054e270aa713f4b7e183aa5a5518a878 100644 (file)
@@ -11463,3 +11463,147 @@ lib/readline/callback.c
 support/shobj-conf,configure.in
        - add support for dragonfly bsd, the same as freebsd
 
+                                5/13-5/15
+                                ---------
+lib/readline/callback.c
+       - support for readline functions to `register' a function that will
+         be called when more input is available, with a generic data
+         structure to encapsulate the arguments and parameters.  Primarily
+         intended for functions that read a single additional character,
+         like quoted-insert
+       - support for callback code reading numeric arguments in a loop,
+         using readline state and an auxiliary variable
+       - support for callback code performing non-incremental searches using
+         the same search context struct as the isearch code
+
+lib/readline/{callback,display}.c
+       - if a callback function sets `_rl_redisplay_wanted', the redisplay
+         function will be called as soon as it returns
+
+lib/readline/input.c
+       - changes to _rl_read_mbchar to handle reading the null multibyte
+         character and translating it into '\0'
+
+lib/readline/misc.c
+       - break rl_digit_loop() into component functions that can be called
+         individually from the callback code more easily
+       - share some of the functions with rl_digit_loop1() in vi_mode.c
+
+lib/readline/readline.h
+       - change the version #defines to reflect readline 5.1
+
+lib/readline/search.c
+       - break code into smaller functions that can be composed to work with
+         the callback code more easily
+
+lib/readline/text.c
+       - in rl_quoted_insert(), don't messa around with the tty signals if
+         running in `callback mode'
+
+lib/readline/vi_mode.c
+       - changed set-mark, goto-mark, change-char, and char-search to work
+         when called by callback functions
+
+                                  5/17
+                                  ----
+
+lib/readline/rlprivate.h
+       - new struct declaration for a `reading key sequence' context
+
+lib/readline/readline.c
+       - new variable, _rl_dispatching_keymap, keeps track of which keymap
+         we are currently searching
+       - functions to allocate and deallocate contexts for reading multi-char
+         key sequences
+
+                                  5/18
+                                  ----
+lib/readline/rlprivate.h
+       - new struct defining a context for multiple-key key sequences (the
+         base case is escape-prefixed commands)
+
+lib/readline/readline.c
+       - change structure of _rl_dispatch_subseq to allow for callback code
+         to use it - rudimentary support for supporting the existing
+         recursion using a stack of contexts, each with a reference to the
+         previous
+       - fix so that  ^G works when in callback mode
+
+lib/readline/callback.c
+       - call the appropriate multiple-key sequence callback if the state is
+         set
+
+                                  5/19
+                                  ----
+lib/readline/readline.c
+       - broke code from _readline_internal_char after call to rl_dispatch
+         out into separate function:  _rl_internal_char_cleanup, callable by
+         other parts of the code
+       - change _rl_internal_char_cleanup to unset _rl_want_redisplay after
+         it calls (*rl_redisplay_func)
+
+lib/readline/callback.c
+       - call _rl_internal_char_cleanup from rl_callback_read_char when
+         appropriate
+
+                                  5/24
+                                  ----
+lib/readline/callback.c
+       - use _rl_dispatch_callback and a chain of _rl_keyseq_contexts to
+         simulate the recursion used to decode multicharacter key sequences
+         (even things like ESC- as meta-prefix)
+       - call setjmp in rl_callback_read_char to give things like rl_abort
+         a place to jump, since the saved location in readline() will not
+         be valid
+       - keep calling _rl_dispatch_callback from rl_callback_read_char while
+         we are still decoding a multi-key key sequence
+       - keep calling readline_internal_char from rl_callback_read_char while
+         we are reading characters from a macro
+
+lib/readline/macro.c
+       - use a slightly different strategy upon encountering the end of a macro
+         when using the callback interface:  when the last character of a
+         macro is read, and we are reading a command, pop the macro off the    
+         stack immediately so the loop in rl_callback_read_char terminates
+         when it should
+
+lib/readline/readline.c
+       - if longjmp() is called and we end up at the saved location while
+         using the callback interface, just return -- don't go back into a
+         blocking read
+       - new function to dispose a chain of rl_keyseq_cxts
+       - only read new input in _rl_dispatch_callback if the KSEQ_DISPATCHED
+         flag is not set in the current keyseq context -- if it is, we are
+         traversing the chain back up and should use what we already saved
+       - use -3 as a magic value from _rl_dispatch_subseq to indicate that
+         we're allocating a new context and moving downward in the chain
+         (a special return value for the benefit of _rl_dispatch_callback)
+
+lib/readline/rlprivate.h
+       - new extern declaration for _rl_keyseq_chain_dispose
+
+                                   6/1
+                                   ---
+builtins/read.def
+       - fixed a bug that occurred when reading a set number of chars and
+         the nth char is a backslash (read one too many)
+
+execute_cmd.c
+       - fix execute_builtin so the `unset' builtin also operates on the
+         temporary environment in POSIX mode (as well as source and eval),
+         so that unsetting variables in the temporary environment doesn't
+         leave them set when unset completes
+
+array.c
+       - fix from William Park for array_rshift when shifting right on an
+         empty array -- corrects calculation of array->max_index
+
+builtins/exec.def
+       - if an exec fails and the execfail option is set, don't call
+         restart_job_control unless the shell is interactive or job_control
+         is set
+
+jobs.c
+       - add a run-time check for WCONTINUED being defined in header files
+         but rejected with EINVAL by waitpid().  Fix from Maciej Rozycki
+         <macro@linux-mips.org>
diff --git a/array.c b/array.c
index 69672d14cfd4b8541e40bd651a66b277a4b42722..c32b61344d10c697ba26658cbe651aa663fa2ad4 100644 (file)
--- a/array.c
+++ b/array.c
@@ -257,14 +257,14 @@ char      *s;
                        return 1;
        }
 
-       a->max_index += n;
-
        /*
         * Renumber all elements in the array except the one we just added.
         */
        for ( ; ae != a->head; ae = element_forw(ae))
                element_index(ae) += n;
 
+       a->max_index = element_index(a->head->prev);
+
        return (a->num_elements);
 }
 
index 2b362c678c5c0242eb2e186f7a8992eeec2fcd58..69672d14cfd4b8541e40bd651a66b277a4b42722 100644 (file)
--- a/array.c~
+++ b/array.c~
@@ -556,7 +556,6 @@ ARRAY       *a;
        return (REVERSE_LIST(list, WORD_LIST *));
 }
 
-/* XXX - changes needed to support `+=' */
 ARRAY *
 array_assign_list (array, list)
 ARRAY  *array;
index acfdae102dacf5c5b9d35b788f24431145501b3d..0818a25e21cb6b9fad071e8c6ba055cc61b4410a 100644 (file)
@@ -221,7 +221,8 @@ failed_exec:
   initialize_signals (1);
 
 #if defined (JOB_CONTROL)
-  restart_job_control ();
+  if (interactive_shell || job_control)
+    restart_job_control ();
 #endif /* JOB_CONTROL */
 
   return (exit_value);
diff --git a/builtins/exec.def~ b/builtins/exec.def~
new file mode 100644 (file)
index 0000000..acfdae1
--- /dev/null
@@ -0,0 +1,228 @@
+This file is exec.def, from which is created exec.c.
+It implements the builtin "exec" in Bash.
+
+Copyright (C) 1987-2003 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, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
+
+$PRODUCES exec.c
+
+$BUILTIN exec
+$FUNCTION exec_builtin
+$SHORT_DOC exec [-cl] [-a name] file [redirection ...]
+Exec FILE, replacing this shell with the specified program.
+If FILE is not specified, the redirections take effect in this
+shell.  If the first argument is `-l', then place a dash in the
+zeroth arg passed to FILE, as login does.  If the `-c' option
+is supplied, FILE is executed with a null environment.  The `-a'
+option means to make set argv[0] of the executed process to NAME.
+If the file cannot be executed and the shell is not interactive,
+then the shell exits, unless the shell option `execfail' is set.
+$END
+
+#include <config.h>
+
+#include "../bashtypes.h"
+#include "posixstat.h"
+#include <signal.h>
+#include <errno.h>
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
+
+#include "../bashansi.h"
+#include "../bashintl.h"
+
+#include "../shell.h"
+#include "../execute_cmd.h"
+#include "../findcmd.h"
+#if defined (JOB_CONTROL)
+#  include "../jobs.h"
+#endif
+#include "../flags.h"
+#include "../trap.h"
+#if defined (HISTORY)
+#  include "../bashhist.h"
+#endif
+#include "common.h"
+#include "bashgetopt.h"
+
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+extern int subshell_environment;
+extern REDIRECT *redirection_undo_list;
+
+int no_exit_on_failed_exec;
+
+/* If the user wants this to look like a login shell, then
+   prepend a `-' onto NAME and return the new name. */
+static char *
+mkdashname (name)
+     char *name;
+{
+  char *ret;
+
+  ret = (char *)xmalloc (2 + strlen (name));
+  ret[0] = '-';
+  strcpy (ret + 1, name);
+  return ret;
+}
+
+int
+exec_builtin (list)
+     WORD_LIST *list;
+{
+  int exit_value = EXECUTION_FAILURE;
+  int cleanenv, login, opt;
+  char *argv0, *command, **args, **env, *newname, *com2;
+
+  cleanenv = login = 0;
+  argv0 = (char *)NULL;
+
+  reset_internal_getopt ();
+  while ((opt = internal_getopt (list, "cla:")) != -1)
+    {
+      switch (opt)
+       {
+       case 'c':
+         cleanenv = 1;
+         break;
+       case 'l':
+         login = 1;
+         break;
+       case 'a':
+         argv0 = list_optarg;
+         break;
+       default:
+         builtin_usage ();
+         return (EX_USAGE);
+       }
+    }
+  list = loptend;
+
+  /* First, let the redirections remain. */
+  dispose_redirects (redirection_undo_list);
+  redirection_undo_list = (REDIRECT *)NULL;
+
+  if (list == 0)
+    return (EXECUTION_SUCCESS);
+
+#if defined (RESTRICTED_SHELL)
+  if (restricted)
+    {
+      sh_restricted ((char *)NULL);
+      return (EXECUTION_FAILURE);
+    }
+#endif /* RESTRICTED_SHELL */
+
+  args = strvec_from_word_list (list, 1, 0, (int *)NULL);
+
+  /* A command with a slash anywhere in its name is not looked up in $PATH. */
+  command = absolute_program (args[0]) ? args[0] : search_for_command (args[0]);
+
+  if (command == 0)
+    {
+      sh_notfound (args[0]);
+      exit_value = EX_NOTFOUND;        /* As per Posix.2, 3.14.6 */
+      goto failed_exec;
+    }
+
+  com2 = full_pathname (command);
+  if (com2)
+    {
+      if (command != args[0])
+       free (command);
+      command = com2;
+    }
+
+  if (argv0)
+    {
+      free (args[0]);
+      args[0] = login ? mkdashname (argv0) : savestring (argv0);
+    }
+  else if (login)
+    {
+      newname = mkdashname (args[0]);
+      free (args[0]);
+      args[0] = newname;
+    }
+
+  /* Decrement SHLVL by 1 so a new shell started here has the same value,
+     preserving the appearance.  After we do that, we need to change the
+     exported environment to include the new value. */
+  if (cleanenv == 0)
+    adjust_shell_level (-1);
+
+  if (cleanenv)
+    env = (char **)NULL;
+  else
+    {  
+      maybe_make_export_env ();
+      env = export_env;
+    }
+
+#if defined (HISTORY)
+  if (interactive_shell && subshell_environment == 0)
+    maybe_save_shell_history ();
+#endif /* HISTORY */
+
+  restore_original_signals ();
+
+#if defined (JOB_CONTROL)
+  if (subshell_environment == 0)
+    end_job_control ();
+#endif /* JOB_CONTROL */
+
+  shell_execve (command, args, env);
+
+  /* We have to set this to NULL because shell_execve has called realloc()
+     to stuff more items at the front of the array, which may have caused
+     the memory to be freed by realloc().  We don't want to free it twice. */
+  args = (char **)NULL;
+  if (cleanenv == 0)
+    adjust_shell_level (1);
+
+  if (executable_file (command) == 0)
+    {
+      builtin_error (_("%s: cannot execute: %s"), command, strerror (errno));
+      exit_value = EX_NOEXEC;  /* As per Posix.2, 3.14.6 */
+    }
+  else
+    file_error (command);
+
+failed_exec:
+  FREE (command);
+
+  if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
+    exit_shell (exit_value);
+
+  if (args)
+    strvec_dispose (args);
+
+  initialize_traps ();
+  initialize_signals (1);
+
+#if defined (JOB_CONTROL)
+  restart_job_control ();
+#endif /* JOB_CONTROL */
+
+  return (exit_value);
+}
index dd8a7727da2582ea878e26e60623f7c7d42b6fe3..bb01cca78d4fcb2fbf4c28a906f7128cb587a91e 100644 (file)
@@ -425,11 +425,11 @@ read_builtin (list)
         newline pair still disappears from the input. */
       if (pass_next)
        {
+         pass_next = 0;
          if (c == '\n')
            i--;                /* back up over the CTLESC */
          else
-           input_string[i++] = c;
-         pass_next = 0;
+           goto add_char;
          continue;
        }
 
@@ -450,6 +450,7 @@ read_builtin (list)
          input_string[i++] = CTLESC;
        }
 
+add_char:
       input_string[i++] = c;
       nr++;
 
index c5f658e940d692ce562696d645ef98d312a8076e..69a4426d8c16dcc740d75fa01b37b727ea13b299 100644 (file)
@@ -124,7 +124,7 @@ read_builtin (list)
      WORD_LIST *list;
 {
   register char *varname;
-  int size, i, pass_next, saw_escape, eof, opt, retval, code;
+  int size, i, nr, pass_next, saw_escape, eof, opt, retval, code;
   int input_is_tty, input_is_pipe, unbuffered_read;
   int raw, edit, nchars, silent, have_timeout, fd;
   unsigned int tmout;
@@ -173,7 +173,7 @@ read_builtin (list)
 #endif
 
   tmout = 0;           /* no timeout */
-  nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
+  nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
   delim = '\n';                /* read until newline */
 
   reset_internal_getopt ();
@@ -425,11 +425,15 @@ read_builtin (list)
         newline pair still disappears from the input. */
       if (pass_next)
        {
+         pass_next = 0;
          if (c == '\n')
            i--;                /* back up over the CTLESC */
          else
+#if 0
            input_string[i++] = c;
-         pass_next = 0;
+#else
+           goto add_char;
+#endif
          continue;
        }
 
@@ -450,9 +454,11 @@ read_builtin (list)
          input_string[i++] = CTLESC;
        }
 
+add_char:
       input_string[i++] = c;
+      nr++;
 
-      if (nchars > 0 && i >= nchars)
+      if (nchars > 0 && nr >= nchars)
        break;
     }
   input_string[i] = '\0';
index b17d4073b7f9069016fc970ddc859cad8968f2d8..0c81fff194419b95276189ed2fe019f31efe28b9 100644 (file)
@@ -3051,7 +3051,12 @@ execute_builtin (builtin, words, flags, subshell)
   /* The temporary environment for a builtin is supposed to apply to
      all commands executed by that builtin.  Currently, this is a
      problem only with the `source' and `eval' builtins. */
+#if 0
   isbltinenv = (builtin == source_builtin || builtin == eval_builtin);
+#else
+  isbltinenv = (builtin == source_builtin || builtin == eval_builtin || builtin == unset_builtin);
+#endif
+
   if (isbltinenv)
     {
       if (subshell == 0)
index 2de0d28e6b3299d99b852ddad5bd87935bf654d8..82fb057e926631d26911cda5bc53215bca5c3f00 100644 (file)
@@ -369,7 +369,6 @@ shell_control_structure (type)
 {
   switch (type)
     {
-    case cm_for:
 #if defined (ARITH_FOR_COMMAND)
     case cm_arith_for:
 #endif
@@ -386,7 +385,9 @@ shell_control_structure (type)
     case cm_while:
     case cm_until:
     case cm_if:
+    case cm_for:
     case cm_group:
+    case cm_function_def:
       return (1);
 
     default:
@@ -3049,8 +3050,14 @@ execute_builtin (builtin, words, flags, subshell)
 
   /* The temporary environment for a builtin is supposed to apply to
      all commands executed by that builtin.  Currently, this is a
+#if 0
      problem only with the `source' and `eval' builtins. */
   isbltinenv = (builtin == source_builtin || builtin == eval_builtin);
+#else
+     problem only with the `source', `unset', and `eval' builtins. */
+  isbltinenv = (builtin == source_builtin || builtin == eval_builtin || builtin == unset_builtin);
+#endif
+
   if (isbltinenv)
     {
       if (subshell == 0)
diff --git a/jobs.c b/jobs.c
index f8a5c8193a9ff089d5ae45d19fe5ab2a124aa40d..05d93950be86994d77e8aa27e4e5f1f2ea3d4852 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -2818,6 +2818,7 @@ waitchld (wpid, block)
   PROCESS *child;
   pid_t pid;
   int call_set_current, last_stopped_job, job, children_exited, waitpid_flags;
+  static int wcontinued = WCONTINUED;  /* run-time fix for glibc problem */
 
   call_set_current = children_exited = 0;
   last_stopped_job = NO_JOB;
@@ -2827,12 +2828,19 @@ waitchld (wpid, block)
       /* We don't want to be notified about jobs stopping if job control
         is not active.  XXX - was interactive_shell instead of job_control */
       waitpid_flags = (job_control && subshell_environment == 0)
-                       ? (WUNTRACED|WCONTINUED)
+                       ? (WUNTRACED|wcontinued)
                        : 0;
       if (sigchld || block == 0)
        waitpid_flags |= WNOHANG;
       pid = WAITPID (-1, &status, waitpid_flags);
 
+      /* WCONTINUED may be rejected by waitpid as invalid even when defined */
+      if (wcontinued && pid < 0 && errno == EINVAL)
+       {
+         wcontinued = 0;
+         continue;     /* jump back to the test and retry without WCONTINUED */
+       }
+
       /* The check for WNOHANG is to make sure we decrement sigchld only
         if it was non-zero before we called waitpid. */
       if (sigchld > 0 && (waitpid_flags & WNOHANG))
diff --git a/jobs.c~ b/jobs.c~
index faa264aea5e97d03146661961d5c8fad91cdfa63..f8a5c8193a9ff089d5ae45d19fe5ab2a124aa40d 100644 (file)
--- a/jobs.c~
+++ b/jobs.c~
@@ -755,7 +755,6 @@ bgp_prune ()
   while (bgpids.npid > js.c_childmax)
     {
       ps = bgpids.list;
-itrace("bgp_prune: deleting %d -> %d", ps->pid, bgpids.npid - 1);
       bgpids.list = bgpids.list->next;
       free (ps);
       bgpids.npid--;
index 9469233daa3a0f7fb6d84f9874edb8c3e5301fb4..9120969ca238f627341c8a1bbfeaead7af744048 100644 (file)
@@ -51,7 +51,7 @@ _rl_callback_generic_arg *_rl_callback_data = 0;
 
 /* **************************************************************** */
 /*                                                                 */
-/*                     Callback Readline Functions                 */
+/*                     Callback Readline Functions              */
 /*                                                                 */
 /* **************************************************************** */
 
@@ -105,7 +105,8 @@ void
 rl_callback_read_char ()
 {
   char *line;
-  int eof;
+  int eof, jcode;
+  static procenv_t olevel;
 
   if (rl_linefunc == NULL)
     {
@@ -113,6 +114,16 @@ rl_callback_read_char ()
       abort ();
     }
 
+  memcpy ((void *)olevel, (void *)readline_top_level, sizeof (procenv_t));
+  jcode = setjmp (readline_top_level);
+  if (jcode)
+    {
+      (*rl_redisplay_function) ();
+      _rl_want_redisplay = 0;
+      memcpy ((void *)readline_top_level, (void *)olevel, sizeof (procenv_t));
+      return;
+    }
+
   if  (RL_ISSTATE (RL_STATE_ISEARCH))
     {
       eof = _rl_isearch_callback (_rl_iscxt);
@@ -130,10 +141,24 @@ rl_callback_read_char ()
     {
       eof = _rl_arg_callback (_rl_argcxt);
       if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
-        rl_callback_read_char ();
+       rl_callback_read_char ();
+      /* XXX - this should handle _rl_last_command_was_kill better */
+      else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
+       _rl_internal_char_cleanup ();
 
       return;
     }
+  else if (RL_ISSTATE (RL_STATE_MULTIKEY))
+    {
+      eof = _rl_dispatch_callback (_rl_kscxt); /* For now */
+      while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED))
+       eof = _rl_dispatch_callback (_rl_kscxt);
+      if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0)
+       {
+         _rl_internal_char_cleanup ();
+         _rl_want_redisplay = 1;
+       }
+    }
   else if (_rl_callback_func)
     {
       /* This allows functions that simply need to read an additional character
@@ -144,11 +169,15 @@ rl_callback_read_char ()
       eof = (*_rl_callback_func) (_rl_callback_data);
       /* If the function `deregisters' itself, make sure the data is cleaned
         up. */
-      if (_rl_callback_func == 0 && _rl_callback_data)
-        {
-          _rl_callback_data_dispose (_rl_callback_data);
-          _rl_callback_data = 0;
-        }
+      if (_rl_callback_func == 0)
+       {
+         if (_rl_callback_data)        
+           {
+             _rl_callback_data_dispose (_rl_callback_data);
+             _rl_callback_data = 0;
+           }
+         _rl_internal_char_cleanup ();
+       }
     }
   else
     eof = readline_internal_char ();
@@ -183,10 +212,10 @@ rl_callback_read_char ()
          if (in_handler == 0 && rl_linefunc)
            _rl_callback_newline ();
        }
-      if (rl_pending_input || _rl_pushed_input_available ())
+      if (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT))
        eof = readline_internal_char ();
       else
-        break;
+       break;
     }
 }
 
index 86a0174ab498c5b498a2bff75b09aefc82eaa96c..6ed566a266087e04fbe575fd46de00c37de71d39 100644 (file)
@@ -118,6 +118,7 @@ rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
 int rl_display_fixed = 0;
 
 int _rl_suppress_redisplay = 0;
+int _rl_want_redisplay = 0;
 
 /* The stuff that gets printed out before the actual text of the line.
    This is usually pointing to rl_prompt. */
@@ -601,6 +602,7 @@ rl_redisplay ()
   num = 0;
 #endif
 
+fprintf(stderr, "rl_redisplay: local_prompt = %s\r\n", local_prompt);
   /* prompt_invis_chars_first_line is the number of invisible characters in
      the first physical line of the prompt.
      wrap_offset - prompt_invis_chars_first_line is the number of invis
@@ -2050,6 +2052,9 @@ insert_some_chars (string, count, col)
      char *string;
      int count, col;
 {
+#if defined (__MSDOS__) || defined (__MINGW32__)
+  _rl_output_some_chars (string, count);
+#else
   /* DEBUGGING */
   if (MB_CUR_MAX == 1 || rl_byte_oriented)
     if (count != col)
@@ -2088,6 +2093,7 @@ insert_some_chars (string, count, col)
       if (_rl_term_ei && *_rl_term_ei)
        tputs (_rl_term_ei, 1, _rl_output_character_function);
     }
+#endif /* __MSDOS__ || __MINGW32__ */
 }
 
 /* Delete COUNT characters from the display line. */
@@ -2098,6 +2104,7 @@ delete_chars (count)
   if (count > _rl_screenwidth) /* XXX */
     return;
 
+#if !defined (__MSDOS__) && !defined (__MINGW32__)
   if (_rl_term_DC && *_rl_term_DC)
     {
       char *buffer;
@@ -2110,6 +2117,7 @@ delete_chars (count)
        while (count--)
          tputs (_rl_term_dc, 1, _rl_output_character_function);
     }
+#endif /* !__MSDOS__ && !__MINGW32__ */
 }
 
 void
diff --git a/lib/readline/examples/rlptytest.c b/lib/readline/examples/rlptytest.c
new file mode 100644 (file)
index 0000000..87bfc3a
--- /dev/null
@@ -0,0 +1,294 @@
+#if defined (HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <curses.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <signal.h>
+
+#if 0  /* LINUX */
+#include <pty.h>
+#else
+#include <util.h>
+#endif
+
+#ifdef READLINE_LIBRARY
+#  include "readline.h"
+#else
+#  include <readline/readline.h>
+#endif
+
+/**
+ * Master/Slave PTY used to keep readline off of stdin/stdout.
+ */
+static int masterfd = -1;
+static int slavefd;
+
+void
+sigint (s)
+     int s;
+{
+  tty_reset (STDIN_FILENO);
+  close (masterfd);
+  close (slavefd);
+  printf ("\n");
+  exit (0);
+}
+
+static int 
+user_input()
+{
+  int size;
+  const int MAX = 1024;
+  char *buf = (char *)malloc(MAX+1);
+
+  size = read (STDIN_FILENO, buf, MAX);
+  if (size == -1)
+    return -1;
+
+  size = write (masterfd, buf, size);
+  if (size == -1)
+    return -1;
+
+  return 0;
+}
+
+static int 
+readline_input()
+{
+  const int MAX = 1024;
+  char *buf = (char *)malloc(MAX+1);
+  int size;
+
+  size = read (masterfd, buf, MAX);
+  if (size == -1)
+    {
+      free( buf );
+      buf = NULL;
+      return -1;
+    }
+
+  buf[size] = 0;
+
+  /* Display output from readline */
+  if ( size > 0 )
+    fprintf(stderr, "%s", buf);
+
+  free( buf );
+  buf = NULL;
+  return 0;
+}
+
+static void 
+rlctx_send_user_command(char *line)
+{
+  /* This happens when rl_callback_read_char gets EOF */
+  if ( line == NULL )
+    return;
+    
+  if (strcmp (line, "exit") == 0) {
+       tty_reset (STDIN_FILENO);
+       close (masterfd);
+       close (slavefd);
+       printf ("\n");
+       exit (0);
+  }
+  
+  /* Don't add the enter command */
+  if ( line && *line != '\0' )
+    add_history(line);
+}
+
+static void 
+custom_deprep_term_function ()
+{
+}
+
+static int 
+init_readline (int inputfd, int outputfd) 
+{
+  FILE *inputFILE, *outputFILE;
+
+  inputFILE = fdopen (inputfd, "r");
+  if (!inputFILE)
+    return -1;
+
+  outputFILE = fdopen (outputfd, "w");
+  if (!outputFILE)
+    return -1;
+
+  rl_instream = inputFILE;
+  rl_outstream = outputFILE;
+
+  /* Tell readline what the prompt is if it needs to put it back */
+  rl_callback_handler_install("(rltest):  ", rlctx_send_user_command);
+
+  /* Set the terminal type to dumb so the output of readline can be
+   * understood by tgdb */
+  if ( rl_reset_terminal("dumb") == -1 )
+    return -1;
+
+  /* For some reason, readline can not deprep the terminal.
+   * However, it doesn't matter because no other application is working on
+   * the terminal besides readline */
+  rl_deprep_term_function = custom_deprep_term_function;
+
+  using_history();
+  read_history(".history"); 
+
+  return 0;
+}
+
+static int 
+main_loop(void)
+{
+  fd_set rset;
+  int max;
+    
+  max = (masterfd > STDIN_FILENO) ? masterfd : STDIN_FILENO;
+  max = (max > slavefd) ? max : slavefd;
+
+  for (;;)
+    {
+      /* Reset the fd_set, and watch for input from GDB or stdin */
+      FD_ZERO(&rset);
+        
+      FD_SET(STDIN_FILENO, &rset);
+      FD_SET(slavefd, &rset);
+      FD_SET(masterfd, &rset);
+
+      /* Wait for input */
+      if (select(max + 1, &rset, NULL, NULL, NULL) == -1)
+        {
+          if (errno == EINTR)
+             continue;
+          else
+            return -1;
+        }
+
+      /* Input received through the pty:  Handle it 
+       * Wrote to masterfd, slave fd has that input, alert readline to read it. 
+       */
+      if (FD_ISSET(slavefd, &rset))
+        rl_callback_read_char();
+
+      /* Input received through the pty.
+       * Readline read from slavefd, and it wrote to the masterfd. 
+       */
+      if (FD_ISSET(masterfd, &rset))
+        if ( readline_input() == -1 )
+          return -1;
+
+      /* Input received:  Handle it, write to masterfd (input to readline) */
+      if (FD_ISSET(STDIN_FILENO, &rset))
+        if ( user_input() == -1 )
+          return -1;
+  }
+
+  return 0;
+}
+
+/* The terminal attributes before calling tty_cbreak */
+static struct termios save_termios;
+static struct winsize size;
+static enum { RESET, TCBREAK } ttystate = RESET;
+
+/* tty_cbreak: Sets terminal to cbreak mode. Also known as noncanonical mode.
+ *    1. Signal handling is still turned on, so the user can still type those.
+ *    2. echo is off
+ *    3. Read in one char at a time.
+ *
+ * fd    - The file descriptor of the terminal
+ * 
+ * Returns: 0 on sucess, -1 on error
+ */
+int tty_cbreak(int fd){
+   struct termios buf;
+    int ttysavefd = -1;
+   
+   if(tcgetattr(fd, &save_termios) < 0)
+      return -1;
+      
+   buf = save_termios;
+   buf.c_lflag &= ~(ECHO | ICANON);
+   buf.c_iflag &= ~(ICRNL | INLCR);
+   buf.c_cc[VMIN] = 1;
+   buf.c_cc[VTIME] = 0;
+
+#if defined (VLNEXT) && defined (_POSIX_VDISABLE)
+   buf.c_cc[VLNEXT] = _POSIX_VDISABLE;
+#endif
+
+#if defined (VDSUSP) && defined (_POSIX_VDISABLE)
+   buf.c_cc[VDSUSP] = _POSIX_VDISABLE;
+#endif
+
+   if(tcsetattr(fd, TCSAFLUSH, &buf) < 0)
+      return -1;
+
+   ttystate = TCBREAK;
+   ttysavefd = fd;
+
+   /* set size */
+   if(ioctl(fd, TIOCGWINSZ, (char *)&size) < 0)
+      return -1;
+
+#ifdef DEBUG
+   err_msg("%d rows and %d cols\n", size.ws_row, size.ws_col);   
+#endif
+   
+   return (0);   
+}
+
+/* tty_reset: Sets the terminal attributes back to their previous state.
+ * PRE: tty_cbreak must have already been called.
+ * 
+ * fd    - The file descrioptor of the terminal to reset.
+ * 
+ * Returns: 0 on success, -1 on error
+ */
+int tty_reset(int fd){
+   if(ttystate != TCBREAK)
+      return (0);
+
+   if(tcsetattr(fd, TCSAFLUSH, &save_termios) < 0)
+      return (-1);
+      
+   ttystate = RESET;
+   
+   return 0;   
+}
+
+int 
+main()
+{
+  int val;
+  val = openpty (&masterfd, &slavefd, NULL, NULL, NULL);
+  if (val == -1)
+    return -1;
+
+  val = init_readline (slavefd, slavefd);
+  if (val == -1)
+    return -1;
+
+  val = tty_cbreak (STDIN_FILENO);
+  if (val == -1)
+    return -1;
+
+  signal (SIGINT, sigint);
+
+  val = main_loop ();
+
+  tty_reset (STDIN_FILENO);
+
+  if (val == -1)
+    return -1;
+
+  return 0;
+}
index b73c3af9aa47304b02200df7edfbf717f6388dc5..2975bf1f74fae541d05033b44b824257d8c631f1 100644 (file)
@@ -100,6 +100,8 @@ _rl_with_macro_input (string)
 int
 _rl_next_macro_key ()
 {
+  int c;
+
   if (rl_executing_macro == 0)
     return (0);
 
@@ -109,7 +111,14 @@ _rl_next_macro_key ()
       return (_rl_next_macro_key ());
     }
 
+#if defined (READLINE_CALLBACKS)
+  c = rl_executing_macro[executing_macro_index++];
+  if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD) && rl_executing_macro[executing_macro_index] == 0)
+      _rl_pop_executing_macro ();
+  return c;
+#else
   return (rl_executing_macro[executing_macro_index++]);
+#endif
 }
 
 /* Save the currently executing macro on a stack of saved macros. */
index 2ac774523bd1c9b7f350c077d5b52c02bf3d31c9..aafad068ec704c5d5fde2271207046777f6812dc 100644 (file)
 #include "xmalloc.h"
 
 #ifndef RL_LIBRARY_VERSION
-#  define RL_LIBRARY_VERSION "5.0"
+#  define RL_LIBRARY_VERSION "5.1"
 #endif
 
 #ifndef RL_READLINE_VERSION
-#  define RL_READLINE_VERSION  0x0500
+#  define RL_READLINE_VERSION  0x0501
 #endif
 
 extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
@@ -87,6 +87,9 @@ static void bind_arrow_keys PARAMS((void));
 static void readline_default_bindings PARAMS((void));
 static void reset_default_bindings PARAMS((void));
 
+static int _rl_subseq_result PARAMS((int, Keymap, int, int));
+static int _rl_subseq_getchar PARAMS((int));
+
 /* **************************************************************** */
 /*                                                                 */
 /*                     Line editing input utility                  */
@@ -104,6 +107,7 @@ int rl_gnu_readline_p = 1;
    By default, it is the standard emacs keymap. */
 Keymap _rl_keymap = emacs_standard_keymap;
 
+
 /* The current style of editing. */
 int rl_editing_mode = emacs_mode;
 
@@ -219,6 +223,9 @@ char *_rl_comment_begin;
 /* Keymap holding the function currently being executed. */
 Keymap rl_executing_keymap;
 
+/* Keymap we're currently using to dispatch. */
+Keymap _rl_dispatching_keymap;
+
 /* Non-zero means to erase entire line, including prompt, on empty input lines. */
 int rl_erase_empty_line = 0;
 
@@ -230,6 +237,9 @@ int rl_num_chars_to_read;
 char *rl_line_buffer = (char *)NULL;
 int rl_line_buffer_len = 0;
 
+/* Key sequence `contexts' */
+_rl_keyseq_cxt *_rl_kscxt = 0;
+
 /* Forward declarations used by the display, termcap, and history code. */
 
 /* **************************************************************** */
@@ -394,6 +404,36 @@ readline_internal_teardown (eof)
   return (eof ? (char *)NULL : savestring (the_line));
 }
 
+void
+_rl_internal_char_cleanup ()
+{
+#if defined (VI_MODE)
+  /* In vi mode, when you exit insert mode, the cursor moves back
+     over the previous character.  We explicitly check for that here. */
+  if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
+    rl_vi_check ();
+#endif /* VI_MODE */
+
+  if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read)
+    {
+      (*rl_redisplay_function) ();
+      _rl_want_redisplay = 0;
+      rl_newline (1, '\n');
+    }
+
+  if (rl_done == 0)
+    {
+      (*rl_redisplay_function) ();
+      _rl_want_redisplay = 0;
+    }
+
+  /* If the application writer has told us to erase the entire line if
+     the only character typed was something bound to rl_newline, do so. */
+  if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline &&
+      rl_point == 0 && rl_end == 0)
+    _rl_erase_entire_line ();
+}
+
 STATIC_CALLBACK int
 #if defined (READLINE_CALLBACKS)
 readline_internal_char ()
@@ -416,7 +456,16 @@ readline_internal_charloop ()
       code = setjmp (readline_top_level);
 
       if (code)
-       (*rl_redisplay_function) ();
+       {
+         (*rl_redisplay_function) ();
+         _rl_want_redisplay = 0;
+         /* If we get here, we're not being called from something dispatched
+            from _rl_callback_read_char(), which sets up its own value of
+            readline_top_level (saving and restoring the old, of course), so
+            we can just return here. */
+         if (RL_ISSTATE (RL_STATE_CALLBACK))
+           return (0);
+       }
 
       if (rl_pending_input == 0)
        {
@@ -455,27 +504,7 @@ readline_internal_charloop ()
       if (rl_pending_input == 0 && lk == _rl_last_command_was_kill)
        _rl_last_command_was_kill = 0;
 
-#if defined (VI_MODE)
-      /* In vi mode, when you exit insert mode, the cursor moves back
-        over the previous character.  We explicitly check for that here. */
-      if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
-       rl_vi_check ();
-#endif /* VI_MODE */
-
-      if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read)
-        {
-          (*rl_redisplay_function) ();
-          rl_newline (1, '\n');
-        }
-
-      if (rl_done == 0)
-       (*rl_redisplay_function) ();
-
-      /* If the application writer has told us to erase the entire line if
-         the only character typed was something bound to rl_newline, do so. */
-      if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline &&
-         rl_point == 0 && rl_end == 0)
-       _rl_erase_entire_line ();
+      _rl_internal_char_cleanup ();
 
 #if defined (READLINE_CALLBACKS)
       return 0;
@@ -525,6 +554,107 @@ _rl_set_the_line ()
   the_line = rl_line_buffer;
 }
 
+#if defined (READLINE_CALLBACKS)
+_rl_keyseq_cxt *
+_rl_keyseq_cxt_alloc ()
+{
+  _rl_keyseq_cxt *cxt;
+
+  cxt = (_rl_keyseq_cxt *)xmalloc (sizeof (_rl_keyseq_cxt));
+
+  cxt->flags = cxt->subseq_arg = cxt->subseq_retval = 0;
+
+  cxt->okey = 0;
+  cxt->ocxt = _rl_kscxt;
+  cxt->childval = 42;          /* sentinel value */
+
+  return cxt;
+}
+
+void
+_rl_keyseq_cxt_dispose (cxt)
+    _rl_keyseq_cxt *cxt;
+{
+  free (cxt);
+}
+
+void
+_rl_keyseq_chain_dispose ()
+{
+  _rl_keyseq_cxt *cxt;
+
+  while (_rl_kscxt)
+    {
+      cxt = _rl_kscxt;
+      _rl_kscxt = _rl_kscxt->ocxt;
+      _rl_keyseq_cxt_dispose (cxt);
+    }
+}
+#endif
+
+static int
+_rl_subseq_getchar (key)
+     int key;
+{
+  int k;
+
+  if (key == ESC)
+    RL_SETSTATE(RL_STATE_METANEXT);
+  RL_SETSTATE(RL_STATE_MOREINPUT);
+  k = rl_read_key ();
+  RL_UNSETSTATE(RL_STATE_MOREINPUT);
+  if (key == ESC)
+    RL_UNSETSTATE(RL_STATE_METANEXT);
+
+  return k;
+}
+
+#if defined (READLINE_CALLBACKS)
+int
+_rl_dispatch_callback (cxt)
+     _rl_keyseq_cxt *cxt;
+{
+  int nkey, r;
+
+  /* For now */
+#if 1
+  /* The first time this context is used, we want to read input and dispatch
+     on it.  When traversing the chain of contexts back `up', we want to use
+     the value from the next context down.  We're simulating recursion using
+     a chain of contexts. */
+  if ((cxt->flags & KSEQ_DISPATCHED) == 0)
+    {
+      nkey = _rl_subseq_getchar (cxt->okey);
+      r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg);
+      cxt->flags |= KSEQ_DISPATCHED;
+    }
+  else
+    r = cxt->childval;
+#else
+  r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg);
+#endif
+
+  /* For now */
+  r = _rl_subseq_result (r, cxt->oldmap, cxt->okey, (cxt->flags & KSEQ_SUBSEQ));
+
+  if (r == 0)                  /* success! */
+    {
+      _rl_keyseq_chain_dispose ();
+      RL_UNSETSTATE (RL_STATE_MULTIKEY);
+      return r;
+    }
+
+  if (r != -3)                 /* magic value that says we added to the chain */
+    _rl_kscxt = cxt->ocxt;
+  if (_rl_kscxt)
+    _rl_kscxt->childval = r;
+  if (r != -3)
+    _rl_keyseq_cxt_dispose (cxt);
+
+  return r;
+}
+#endif /* READLINE_CALLBACKS */
+  
 /* Do the command associated with KEY in MAP.
    If the associated command is really a keymap, then read
    another key, and dispatch into that map. */
@@ -533,6 +663,7 @@ _rl_dispatch (key, map)
      register int key;
      Keymap map;
 {
+  _rl_dispatching_keymap = map;
   return _rl_dispatch_subseq (key, map, 0);
 }
 
@@ -545,6 +676,9 @@ _rl_dispatch_subseq (key, map, got_subseq)
   int r, newkey;
   char *macro;
   rl_command_func_t *func;
+#if defined (READLINE_CALLBACKS)
+  _rl_keyseq_cxt *cxt;
+#endif
 
   if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
     {
@@ -578,10 +712,6 @@ _rl_dispatch_subseq (key, map, got_subseq)
 
          rl_executing_keymap = map;
 
-#if 0
-         _rl_suppress_redisplay = (map[key].function == rl_insert) && _rl_input_available ();
-#endif
-
          rl_dispatching = 1;
          RL_SETSTATE(RL_STATE_DISPATCHING);
          r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
@@ -613,6 +743,10 @@ _rl_dispatch_subseq (key, map, got_subseq)
        }
       else
        {
+#if defined (READLINE_CALLBACKS)
+         RL_UNSETSTATE (RL_STATE_MULTIKEY);
+         _rl_keyseq_chain_dispose ();
+#endif
          _rl_abort_internal ();
          return -1;
        }
@@ -634,66 +768,43 @@ _rl_dispatch_subseq (key, map, got_subseq)
 #endif
 
          rl_key_sequence_length++;
+         _rl_dispatching_keymap = FUNCTION_TO_KEYMAP (map, key);
 
-         if (key == ESC)
-           RL_SETSTATE(RL_STATE_METANEXT);
-         RL_SETSTATE(RL_STATE_MOREINPUT);
-         newkey = rl_read_key ();
-         RL_UNSETSTATE(RL_STATE_MOREINPUT);
-         if (key == ESC)
-           RL_UNSETSTATE(RL_STATE_METANEXT);
+         /* Allocate new context here.  Use linked contexts (linked through
+            cxt->ocxt) to simulate recursion */
+#if defined (READLINE_CALLBACKS)
+         if (RL_ISSTATE (RL_STATE_CALLBACK))
+           {
+             /* Return 0 only the first time, to indicate success to
+                _rl_callback_read_char.  The rest of the time, we're called
+                from _rl_dispatch_callback, so we return 3 to indicate
+                special handling is necessary. */
+             r = RL_ISSTATE (RL_STATE_MULTIKEY) ? -3 : 0;
+             cxt = _rl_keyseq_cxt_alloc ();
+
+             if (got_subseq)
+               cxt->flags |= KSEQ_SUBSEQ;
+             cxt->okey = key;
+             cxt->oldmap = map;
+             cxt->dmap = _rl_dispatching_keymap;
+             cxt->subseq_arg = got_subseq || cxt->dmap[ANYOTHERKEY].function;
+
+             RL_SETSTATE (RL_STATE_MULTIKEY);
+             _rl_kscxt = cxt;
+
+             return r;         /* don't indicate immediate success */
+           }
+#endif
 
+         newkey = _rl_subseq_getchar (key);
          if (newkey < 0)
            {
              _rl_abort_internal ();
              return -1;
            }
 
-         r = _rl_dispatch_subseq (newkey, FUNCTION_TO_KEYMAP (map, key), got_subseq || map[ANYOTHERKEY].function);
-
-         if (r == -2)
-           /* We didn't match anything, and the keymap we're indexed into
-              shadowed a function previously bound to that prefix.  Call
-              the function.  The recursive call to _rl_dispatch_subseq has
-              already taken care of pushing any necessary input back onto
-              the input queue with _rl_unget_char. */
-           {
-             Keymap m = FUNCTION_TO_KEYMAP (map, key);
-             int type = m[ANYOTHERKEY].type;
-             func = m[ANYOTHERKEY].function;
-             if (type == ISFUNC && func == rl_do_lowercase_version)
-               r = _rl_dispatch (_rl_to_lower (key), map);
-             else if (type == ISFUNC && func == rl_insert)
-               {
-                 /* If the function that was shadowed was self-insert, we
-                    somehow need a keymap with map[key].func == self-insert.
-                    Let's use this one. */
-                 int nt = m[key].type;
-                 rl_command_func_t *nf = m[key].function;
-
-                 m[key].type = type;
-                 m[key].function = func;
-                 r = _rl_dispatch (key, m);
-                 m[key].type = nt;
-                 m[key].function = nf;
-               }
-             else
-               r = _rl_dispatch (ANYOTHERKEY, m);
-           }
-         else if (r && map[ANYOTHERKEY].function)
-           {
-             /* We didn't match (r is probably -1), so return something to
-                tell the caller that it should try ANYOTHERKEY for an
-                overridden function. */
-             _rl_unget_char (key);
-             return -2;
-           }
-         else if (r && got_subseq)
-           {
-             /* OK, back up the chain. */
-             _rl_unget_char (key);
-             return -1;
-           }
+         r = _rl_dispatch_subseq (newkey, _rl_dispatching_keymap, got_subseq || map[ANYOTHERKEY].function);
+         return _rl_subseq_result (r, map, key, got_subseq);
        }
       else
        {
@@ -717,9 +828,69 @@ _rl_dispatch_subseq (key, map, got_subseq)
       _rl_vi_textmod_command (key))
     _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
 #endif
+
   return (r);
 }
 
+static int
+_rl_subseq_result (r, map, key, got_subseq)
+     int r;
+     Keymap map;
+     int key, got_subseq;
+{
+  Keymap m;
+  int type, nt;
+  rl_command_func_t *func, *nf;
+  
+  if (r == -2)
+    /* We didn't match anything, and the keymap we're indexed into
+       shadowed a function previously bound to that prefix.  Call
+       the function.  The recursive call to _rl_dispatch_subseq has
+       already taken care of pushing any necessary input back onto
+       the input queue with _rl_unget_char. */
+    {
+      m = _rl_dispatching_keymap;
+      type = m[ANYOTHERKEY].type;
+      func = m[ANYOTHERKEY].function;
+      if (type == ISFUNC && func == rl_do_lowercase_version)
+       r = _rl_dispatch (_rl_to_lower (key), map);
+      else if (type == ISFUNC && func == rl_insert)
+       {
+         /* If the function that was shadowed was self-insert, we
+            somehow need a keymap with map[key].func == self-insert.
+            Let's use this one. */
+         nt = m[key].type;
+         nf = m[key].function;
+
+         m[key].type = type;
+         m[key].function = func;
+         r = _rl_dispatch (key, m);
+         m[key].type = nt;
+         m[key].function = nf;
+       }
+      else
+       r = _rl_dispatch (ANYOTHERKEY, m);
+    }
+  else if (r && map[ANYOTHERKEY].function)
+    {
+      /* We didn't match (r is probably -1), so return something to
+        tell the caller that it should try ANYOTHERKEY for an
+        overridden function. */
+      _rl_unget_char (key);
+      _rl_dispatching_keymap = map;
+      return -2;
+    }
+  else if (r && got_subseq)
+    {
+      /* OK, back up the chain. */
+      _rl_unget_char (key);
+      _rl_dispatching_keymap = map;
+      return -1;
+    }
+
+  return r;
+}
+
 /* **************************************************************** */
 /*                                                                 */
 /*                     Initializations                             */
index 4eafa7d6492cb884854a53070cdb5d4ec5e93e4b..efc954cc58aab8b4b7cb38b4062d81716bbdc317 100644 (file)
@@ -85,6 +85,26 @@ typedef struct  __rl_search_context
 
 typedef int _rl_arg_cxt;
 
+/* A context for reading key sequences longer than a single character when
+   using the callback interface. */
+#define KSEQ_DISPATCHED        0x01
+#define KSEQ_SUBSEQ    0x02
+#define KSEQ_RECURSIVE 0x04
+
+typedef struct __rl_keyseq_context
+{
+  int flags;
+  int subseq_arg;
+  int subseq_retval;           /* XXX */
+  Keymap dmap;
+
+  Keymap oldmap;
+  int okey;
+  struct __rl_keyseq_context *ocxt;
+  int childval;
+} _rl_keyseq_cxt;
+
+  /* fill in more as needed */
 /* `Generic' callback data and functions */
 typedef struct __rl_callback_generic_arg 
 {
@@ -121,6 +141,8 @@ extern int readline_echoing_p;
 extern int rl_key_sequence_length;
 extern int rl_byte_oriented;
 
+extern _rl_keyseq_cxt *_rl_kscxt;
+
 /* display.c */
 extern int rl_display_fixed;
 
@@ -167,6 +189,12 @@ extern void readline_internal_setup PARAMS((void));
 extern char *readline_internal_teardown PARAMS((int));
 extern int readline_internal_char PARAMS((void));
 
+extern _rl_keyseq_cxt *_rl_keyseq_cxt_alloc PARAMS((void));
+extern void _rl_keyseq_cxt_dispose PARAMS((_rl_keyseq_cxt *));
+extern void _rl_keyseq_chain_dispose PARAMS((void));
+
+extern int _rl_dispatch_callback PARAMS((_rl_keyseq_cxt *));
+     
 /* callback.c */
 extern _rl_callback_generic_arg *_rl_callback_data_alloc PARAMS((int));
 extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *));
@@ -242,6 +270,7 @@ extern void _rl_init_line_state PARAMS((void));
 extern void _rl_set_the_line PARAMS((void));
 extern int _rl_dispatch PARAMS((int, Keymap));
 extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
+extern void _rl_internal_char_cleanup PARAMS((void));
 
 /* rltty.c */
 extern int _rl_disable_tty_signals PARAMS((void));
index 103efd1abb5aa74a2b7c3d49d2bd3246fe993ad7..b4c174d53c862cf0ea0d43b1da464872a7784936 100644 (file)
@@ -421,6 +421,7 @@ rl_noninc_reverse_search_again (count, key)
   return (r != 1);
 }
 
+#if defined (READLINE_CALLBACKS)
 int
 _rl_nsearch_callback (cxt)
      _rl_search_cxt *cxt;
@@ -435,6 +436,7 @@ _rl_nsearch_callback (cxt)
   r = _rl_nsearch_dosearch (cxt);
   return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
 }
+#endif
   
 static int
 rl_history_search_internal (count, dir)
index 06ec4427a2cbc9aac530c98926cae321235caca8..efaef3992b58706cac6bf85f7a80398eb9706b92 100644 (file)
@@ -1188,7 +1188,7 @@ _rl_vi_callback_char_search (data)
   _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
 #else
   RL_SETSTATE(RL_STATE_MOREINPUT);
-  _rl_vi_last_search_char = target = rl_read_key ();
+  _rl_vi_last_search_char = rl_read_key ();
   RL_UNSETSTATE(RL_STATE_MOREINPUT);
 #endif
 
@@ -1437,9 +1437,7 @@ _rl_vi_callback_change_char (data)
      _rl_callback_generic_arg *data;
 {
   int c;
-#if defined (HANDLE_MULTIBYTE)
   char mb[MB_LEN_MAX];
-#endif
 
   _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
 
index 4c57ff4be494bc91dc91b655d2cf1a776a3e33fb..9ea5b6dea1494e8c386c65b01da07e6b21c92a00 100644 (file)
--- a/parse.y~
+++ b/parse.y~
@@ -1968,6 +1968,7 @@ shell_getc (remove_quoted_newline)
        }
 
       shell_input_line_index = 0;
+itrace("reset shell_input_line_index = 0");
       shell_input_line_len = i;                /* == strlen (shell_input_line) */
 
       set_line_mbstate ();
@@ -4614,7 +4615,7 @@ parse_string_to_word_list (s, flags, whom)
          line_number = orig_line_number + line_number - 1;
          orig_current_token = current_token;
          current_token = tok;
-         yyerror ((char *)NULL);       /* does the right thing */
+         yyerror (NULL);       /* does the right thing */
          current_token = orig_current_token;
          if (wl)
            dispose_words (wl);
@@ -4689,7 +4690,7 @@ parse_compound_assignment (retlenp)
          if (tok == yacc_EOF)  /* ( */
            parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
          else
-           yyerror ((char *)NULL);     /* does the right thing */
+           yyerror(NULL);      /* does the right thing */
          if (wl)
            dispose_words (wl);
          wl = &parse_string_error;
index bad76b01ad798b470f22140cb48c6bb633ef8b45..f373372765db581d873e2a040c828712225eec6b 100644 (file)
--- a/version.c
+++ b/version.c
@@ -1,6 +1,6 @@
 /* version.c -- distribution and version numbers. */
 
-/* Copyright (C) 1989 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2005 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -79,5 +79,5 @@ show_shell_version (extended)
 {
   printf ("GNU bash, version %s (%s)\n", shell_version_string (), MACHTYPE);
   if (extended)
-    printf (_("Copyright (C) 2004 Free Software Foundation, Inc.\n"));
+    printf (_("Copyright (C) 2005 Free Software Foundation, Inc.\n"));
 }