gdb/testsuite: Make use of exec_has_index_section function
[binutils-gdb.git] / readline / misc.c
index d4558321dec558006f1a9366381fff3567e5fc9f..64b1457d29e8af0bcefc6553ca97e93cf0cd6ad0 100644 (file)
@@ -1,24 +1,24 @@
 /* misc.c -- miscellaneous bindable readline functions. */
 
-/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2017 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.
+   This file is part of the GNU Readline Library (Readline), a library
+   for reading lines of text with interactive input and history editing.      
 
-   The GNU Readline Library 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
+   Readline 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 3 of the License, or
    (at your option) any later version.
 
-   The GNU Readline Library 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
+   Readline 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.
 
-   The GNU General Public License is often shipped with GNU software, and
-   is generally kept in a file called COPYING or LICENSE.  If you do not
-   have a copy of the license, write to the Free Software Foundation,
-   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+   You should have received a copy of the GNU General Public License
+   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 #define READLINE_LIBRARY
 
 #if defined (HAVE_CONFIG_H)
@@ -76,7 +76,7 @@ int _rl_history_saved_point = -1;
 /* **************************************************************** */
 
 int
-_rl_arg_overflow ()
+_rl_arg_overflow (void)
 {
   if (rl_numeric_arg > 1000000)
     {
@@ -92,7 +92,7 @@ _rl_arg_overflow ()
 }
 
 void
-_rl_arg_init ()
+_rl_arg_init (void)
 {
   rl_save_prompt ();
   _rl_argcxt = 0;
@@ -100,7 +100,7 @@ _rl_arg_init ()
 }
 
 int
-_rl_arg_getchar ()
+_rl_arg_getchar (void)
 {
   int c;
 
@@ -116,9 +116,7 @@ _rl_arg_getchar ()
    argument should be aborted, 0 if we should not read any more chars, and
    1 if we should continue to read chars. */
 int
-_rl_arg_dispatch (cxt, c)
-     _rl_arg_cxt cxt;
-     int c;
+_rl_arg_dispatch (_rl_arg_cxt cxt, int c)
 {
   int key, r;
 
@@ -126,7 +124,7 @@ _rl_arg_dispatch (cxt, c)
 
   /* If we see a key bound to `universal-argument' after seeing digits,
       it ends the argument but is otherwise ignored. */
-  if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
+  if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
     {
       if ((cxt & NUM_SAWDIGITS) == 0)
        {
@@ -146,6 +144,8 @@ _rl_arg_dispatch (cxt, c)
          rl_restore_prompt ();
          rl_clear_message ();
          RL_UNSETSTATE(RL_STATE_NUMERICARG);
+         if (key < 0)
+           return -1;
          return (_rl_dispatch (key, _rl_keymap));
        }
     }
@@ -191,7 +191,7 @@ _rl_arg_dispatch (cxt, c)
 
 /* Handle C-u style numeric args, as well as M--, and M-digits. */
 static int
-rl_digit_loop ()
+rl_digit_loop (void)
 {
   int c, r;
 
@@ -212,11 +212,13 @@ rl_digit_loop ()
       if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
         break;
     }
+
+  return r;
 }
 
 /* Create a default argument. */
 void
-_rl_reset_argument ()
+_rl_reset_argument (void)
 {
   rl_numeric_arg = rl_arg_sign = 1;
   rl_explicit_arg = 0;
@@ -225,8 +227,7 @@ _rl_reset_argument ()
 
 /* Start a numeric argument with initial value KEY */
 int
-rl_digit_argument (ignore, key)
-     int ignore, key;
+rl_digit_argument (int ignore, int key)
 {
   _rl_arg_init ();
   if (RL_ISSTATE (RL_STATE_CALLBACK))
@@ -246,8 +247,7 @@ rl_digit_argument (ignore, key)
    Read a key.  If the key has nothing to do with arguments, then
    dispatch on it.  If the key is the abort character then abort. */
 int
-rl_universal_argument (count, key)
-     int count, key;
+rl_universal_argument (int count, int key)
 {
   _rl_arg_init ();
   rl_numeric_arg *= 4;
@@ -256,12 +256,13 @@ rl_universal_argument (count, key)
 }
 
 int
-_rl_arg_callback (cxt)
-     _rl_arg_cxt cxt;
+_rl_arg_callback (_rl_arg_cxt cxt)
 {
   int c, r;
 
   c = _rl_arg_getchar ();
+  if (c < 0)
+    return (1);                /* EOF */
 
   if (_rl_argcxt & NUM_READONE)
     {
@@ -274,12 +275,14 @@ _rl_arg_callback (cxt)
     }
 
   r = _rl_arg_dispatch (cxt, c);
+  if (r > 0)
+    rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
   return (r != 1);
 }
 
 /* What to do when you abort reading an argument. */
 int
-rl_discard_argument ()
+rl_discard_argument (void)
 {
   rl_ding ();
   rl_clear_message ();
@@ -304,7 +307,7 @@ HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
 
 /* Set the history pointer back to the last entry in the history. */
 void
-_rl_start_using_history ()
+_rl_start_using_history (void)
 {
   using_history ();
   if (_rl_saved_line_for_history)
@@ -315,8 +318,7 @@ _rl_start_using_history ()
 
 /* Free the contents (and containing structure) of a HIST_ENTRY. */
 void
-_rl_free_history_entry (entry)
-     HIST_ENTRY *entry;
+_rl_free_history_entry (HIST_ENTRY *entry)
 {
   if (entry == 0)
     return;
@@ -324,12 +326,12 @@ _rl_free_history_entry (entry)
   FREE (entry->line);
   FREE (entry->timestamp);
 
-  free (entry);
+  xfree (entry);
 }
 
 /* Perhaps put back the current line if it has changed. */
 int
-rl_maybe_replace_line ()
+rl_maybe_replace_line (void)
 {
   HIST_ENTRY *temp;
 
@@ -338,16 +340,16 @@ rl_maybe_replace_line ()
   if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
     {
       temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
-      free (temp->line);
+      xfree (temp->line);
       FREE (temp->timestamp);
-      free (temp);
+      xfree (temp);
     }
   return 0;
 }
 
 /* Restore the _rl_saved_line_for_history if there is one. */
 int
-rl_maybe_unsave_line ()
+rl_maybe_unsave_line (void)
 {
   if (_rl_saved_line_for_history)
     {
@@ -366,7 +368,7 @@ rl_maybe_unsave_line ()
 
 /* Save the current line in _rl_saved_line_for_history. */
 int
-rl_maybe_save_line ()
+rl_maybe_save_line (void)
 {
   if (_rl_saved_line_for_history == 0)
     {
@@ -380,7 +382,7 @@ rl_maybe_save_line ()
 }
 
 int
-_rl_free_saved_history_line ()
+_rl_free_saved_history_line (void)
 {
   if (_rl_saved_line_for_history)
     {
@@ -391,7 +393,7 @@ _rl_free_saved_history_line ()
 }
 
 static void
-_rl_history_set_point ()
+_rl_history_set_point (void)
 {
   rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
                ? _rl_history_saved_point
@@ -409,9 +411,7 @@ _rl_history_set_point ()
 }
 
 void
-rl_replace_from_history (entry, flags)
-     HIST_ENTRY *entry;
-     int flags;                        /* currently unused */
+rl_replace_from_history (HIST_ENTRY *entry, int flags)
 {
   /* Can't call with `1' because rl_undo_list might point to an undo list
      from a history entry, just like we're setting up here. */
@@ -427,8 +427,89 @@ rl_replace_from_history (entry, flags)
       rl_mark = rl_end;
     }
 #endif
+}
+
+/* Process and free undo lists attached to each history entry prior to the
+   current entry, inclusive, reverting each line to its saved state.  This 
+   is destructive, and state about the current line is lost.  This is not
+   intended to be called while actively editing, and the current line is
+   not assumed to have been added to the history list. */
+void
+_rl_revert_all_lines (void)
+{
+  int hpos;
+  HIST_ENTRY *entry;
+  UNDO_LIST *ul, *saved_undo_list;
+  char *lbuf;
+
+  lbuf = savestring (rl_line_buffer);
+  saved_undo_list = rl_undo_list;
+  hpos = where_history ();
+
+  entry = (hpos == history_length) ? previous_history () : current_history ();
+  while (entry)
+    {
+      if (ul = (UNDO_LIST *)entry->data)
+       {
+         if (ul == saved_undo_list)
+           saved_undo_list = 0;
+         /* Set up rl_line_buffer and other variables from history entry */
+         rl_replace_from_history (entry, 0);   /* entry->line is now current */
+         entry->data = 0;                      /* entry->data is now current undo list */
+         /* Undo all changes to this history entry */
+         while (rl_undo_list)
+           rl_do_undo ();
+         /* And copy the reverted line back to the history entry, preserving
+            the timestamp. */
+         FREE (entry->line);
+         entry->line = savestring (rl_line_buffer);
+       }
+      entry = previous_history ();
+    }
+
+  /* Restore history state */
+  rl_undo_list = saved_undo_list;      /* may have been set to null */
+  history_set_pos (hpos);
+  
+  /* reset the line buffer */
+  rl_replace_line (lbuf, 0);
+  _rl_set_the_line ();
+
+  /* and clean up */
+  xfree (lbuf);
 }  
 
+/* Free the history list, including private readline data and take care
+   of pointer aliases to history data.  Resets rl_undo_list if it points
+   to an UNDO_LIST * saved as some history entry's data member.  This
+   should not be called while editing is active. */
+void
+rl_clear_history (void)
+{
+  HIST_ENTRY **hlist, *hent;
+  register int i;
+  UNDO_LIST *ul, *saved_undo_list;
+
+  saved_undo_list = rl_undo_list;
+  hlist = history_list ();             /* direct pointer, not copy */
+
+  for (i = 0; i < history_length; i++)
+    {
+      hent = hlist[i];
+      if (ul = (UNDO_LIST *)hent->data)
+       {
+         if (ul == saved_undo_list)
+           saved_undo_list = 0;
+         _rl_free_undo_list (ul);
+         hent->data = 0;
+       }
+      _rl_free_history_entry (hent);
+    }
+
+  history_offset = history_length = 0;
+  rl_undo_list = saved_undo_list;      /* should be NULL */
+}
+
 /* **************************************************************** */
 /*                                                                 */
 /*                     History Commands                            */
@@ -437,16 +518,14 @@ rl_replace_from_history (entry, flags)
 
 /* Meta-< goes to the start of the history. */
 int
-rl_beginning_of_history (count, key)
-     int count, key;
+rl_beginning_of_history (int count, int key)
 {
   return (rl_get_previous_history (1 + where_history (), key));
 }
 
 /* Meta-> goes to the end of the history.  (The current line). */
 int
-rl_end_of_history (count, key)
-     int count, key;
+rl_end_of_history (int count, int key)
 {
   rl_maybe_replace_line ();
   using_history ();
@@ -456,8 +535,7 @@ rl_end_of_history (count, key)
 
 /* Move down to the next history line. */
 int
-rl_get_next_history (count, key)
-     int count, key;
+rl_get_next_history (int count, int key)
 {
   HIST_ENTRY *temp;
 
@@ -495,15 +573,14 @@ rl_get_next_history (count, key)
 /* Get the previous item out of our interactive history, making it the current
    line.  If there is no previous history, just ding. */
 int
-rl_get_previous_history (count, key)
-     int count, key;
+rl_get_previous_history (int count, int key)
 {
   HIST_ENTRY *old_temp, *temp;
 
   if (count < 0)
     return (rl_get_next_history (-count, key));
 
-  if (count == 0)
+  if (count == 0 || history_list () == 0)
     return 0;
 
   /* either not saved by rl_newline or at end of line, so set appropriately. */
@@ -533,7 +610,10 @@ rl_get_previous_history (count, key)
     temp = old_temp;
 
   if (temp == 0)
-    rl_ding ();
+    {
+      rl_maybe_unsave_line ();
+      rl_ding ();
+    }
   else
     {
       rl_replace_from_history (temp, 0);
@@ -550,32 +630,33 @@ rl_get_previous_history (count, key)
 /* **************************************************************** */
 /* How to toggle back and forth between editing modes. */
 int
-rl_vi_editing_mode (count, key)
-     int count, key;
+rl_vi_editing_mode (int count, int key)
 {
 #if defined (VI_MODE)
   _rl_set_insert_mode (RL_IM_INSERT, 1);       /* vi mode ignores insert mode */
   rl_editing_mode = vi_mode;
-  rl_vi_insertion_mode (1, key);
+  rl_vi_insert_mode (1, key);
 #endif /* VI_MODE */
 
   return 0;
 }
 
 int
-rl_emacs_editing_mode (count, key)
-     int count, key;
+rl_emacs_editing_mode (int count, int key)
 {
   rl_editing_mode = emacs_mode;
   _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
   _rl_keymap = emacs_standard_keymap;
+
+  if (_rl_show_mode_in_prompt)
+    _rl_reset_prompt ();
+
   return 0;
 }
 
 /* Function for the rest of the library to use to set insert/overwrite mode. */
 void
-_rl_set_insert_mode (im, force)
-     int im, force;
+_rl_set_insert_mode (int im, int force)
 {
 #ifdef CURSOR_MODE
   _rl_set_cursor (im, force);
@@ -587,8 +668,7 @@ _rl_set_insert_mode (im, force)
 /* Toggle overwrite mode.  A positive explicit argument selects overwrite
    mode.  A negative or zero explicit argument selects insert mode. */
 int
-rl_overwrite_mode (count, key)
-     int count, key;
+rl_overwrite_mode (int count, int key)
 {
   if (rl_explicit_arg == 0)
     _rl_set_insert_mode (rl_insert_mode ^ 1, 0);