gdb vendor branch: Bring in additional source files
[dragonfly.git] / contrib / gdb-7 / readline / misc.c
1 /* misc.c -- miscellaneous bindable readline functions. */
2
3 /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
4
5    This file is part of the GNU Readline Library (Readline), a library
6    for reading lines of text with interactive input and history editing.      
7
8    Readline is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 3 of the License, or
11    (at your option) any later version.
12
13    Readline is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #define READLINE_LIBRARY
23
24 #if defined (HAVE_CONFIG_H)
25 #  include <config.h>
26 #endif
27
28 #if defined (HAVE_UNISTD_H)
29 #  include <unistd.h>
30 #endif /* HAVE_UNISTD_H */
31
32 #if defined (HAVE_STDLIB_H)
33 #  include <stdlib.h>
34 #else
35 #  include "ansi_stdlib.h"
36 #endif /* HAVE_STDLIB_H */
37
38 #if defined (HAVE_LOCALE_H)
39 #  include <locale.h>
40 #endif
41
42 #include <stdio.h>
43
44 /* System-specific feature definitions and include files. */
45 #include "rldefs.h"
46 #include "rlmbutil.h"
47
48 /* Some standard library routines. */
49 #include "readline.h"
50 #include "history.h"
51
52 #include "rlprivate.h"
53 #include "rlshell.h"
54 #include "xmalloc.h"
55
56 static int rl_digit_loop PARAMS((void));
57 static void _rl_history_set_point PARAMS((void));
58
59 /* Forward declarations used in this file */
60 void _rl_free_history_entry PARAMS((HIST_ENTRY *));
61
62 /* If non-zero, rl_get_previous_history and rl_get_next_history attempt
63    to preserve the value of rl_point from line to line. */
64 int _rl_history_preserve_point = 0;
65
66 _rl_arg_cxt _rl_argcxt;
67
68 /* Saved target point for when _rl_history_preserve_point is set.  Special
69    value of -1 means that point is at the end of the line. */
70 int _rl_history_saved_point = -1;
71
72 /* **************************************************************** */
73 /*                                                                  */
74 /*                      Numeric Arguments                           */
75 /*                                                                  */
76 /* **************************************************************** */
77
78 int
79 _rl_arg_overflow ()
80 {
81   if (rl_numeric_arg > 1000000)
82     {
83       _rl_argcxt = 0;
84       rl_explicit_arg = rl_numeric_arg = 0;
85       rl_ding ();
86       rl_restore_prompt ();
87       rl_clear_message ();
88       RL_UNSETSTATE(RL_STATE_NUMERICARG);
89       return 1;
90     }
91   return 0;
92 }
93
94 void
95 _rl_arg_init ()
96 {
97   rl_save_prompt ();
98   _rl_argcxt = 0;
99   RL_SETSTATE(RL_STATE_NUMERICARG);
100 }
101
102 int
103 _rl_arg_getchar ()
104 {
105   int c;
106
107   rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
108   RL_SETSTATE(RL_STATE_MOREINPUT);
109   c = rl_read_key ();
110   RL_UNSETSTATE(RL_STATE_MOREINPUT);
111
112   return c;
113 }
114
115 /* Process C as part of the current numeric argument.  Return -1 if the
116    argument should be aborted, 0 if we should not read any more chars, and
117    1 if we should continue to read chars. */
118 int
119 _rl_arg_dispatch (cxt, c)
120      _rl_arg_cxt cxt;
121      int c;
122 {
123   int key, r;
124
125   key = c;
126
127   /* If we see a key bound to `universal-argument' after seeing digits,
128       it ends the argument but is otherwise ignored. */
129   if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
130     {
131       if ((cxt & NUM_SAWDIGITS) == 0)
132         {
133           rl_numeric_arg *= 4;
134           return 1;
135         }
136       else if (RL_ISSTATE (RL_STATE_CALLBACK))
137         {
138           _rl_argcxt |= NUM_READONE;
139           return 0;     /* XXX */
140         }
141       else
142         {
143           RL_SETSTATE(RL_STATE_MOREINPUT);
144           key = rl_read_key ();
145           RL_UNSETSTATE(RL_STATE_MOREINPUT);
146           rl_restore_prompt ();
147           rl_clear_message ();
148           RL_UNSETSTATE(RL_STATE_NUMERICARG);
149           if (key < 0)
150             return -1;
151           return (_rl_dispatch (key, _rl_keymap));
152         }
153     }
154
155   c = UNMETA (c);
156
157   if (_rl_digit_p (c))
158     {
159       r = _rl_digit_value (c);          
160       rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) +  r : r;
161       rl_explicit_arg = 1;
162       _rl_argcxt |= NUM_SAWDIGITS;
163     }
164   else if (c == '-' && rl_explicit_arg == 0)
165     {
166       rl_numeric_arg = 1;
167       _rl_argcxt |= NUM_SAWMINUS;
168       rl_arg_sign = -1;
169     }
170   else
171     {
172       /* Make M-- command equivalent to M--1 command. */
173       if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
174         rl_explicit_arg = 1;
175       rl_restore_prompt ();
176       rl_clear_message ();
177       RL_UNSETSTATE(RL_STATE_NUMERICARG);
178
179       r = _rl_dispatch (key, _rl_keymap);
180       if (RL_ISSTATE (RL_STATE_CALLBACK))
181         {
182           /* At worst, this will cause an extra redisplay.  Otherwise,
183              we have to wait until the next character comes in. */
184           if (rl_done == 0)
185             (*rl_redisplay_function) ();
186           r = 0;
187         }
188       return r;
189     }
190
191   return 1;
192 }
193
194 /* Handle C-u style numeric args, as well as M--, and M-digits. */
195 static int
196 rl_digit_loop ()
197 {
198   int c, r;
199
200   while (1)
201     {
202       if (_rl_arg_overflow ())
203         return 1;
204
205       c = _rl_arg_getchar ();
206
207       if (c < 0)
208         {
209           _rl_abort_internal ();
210           return -1;
211         }
212
213       r = _rl_arg_dispatch (_rl_argcxt, c);
214       if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
215         break;
216     }
217
218   return r;
219 }
220
221 /* Create a default argument. */
222 void
223 _rl_reset_argument ()
224 {
225   rl_numeric_arg = rl_arg_sign = 1;
226   rl_explicit_arg = 0;
227   _rl_argcxt = 0;
228 }
229
230 /* Start a numeric argument with initial value KEY */
231 int
232 rl_digit_argument (ignore, key)
233      int ignore, key;
234 {
235   _rl_arg_init ();
236   if (RL_ISSTATE (RL_STATE_CALLBACK))
237     {
238       _rl_arg_dispatch (_rl_argcxt, key);
239       rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
240       return 0;
241     }
242   else
243     {
244       rl_execute_next (key);
245       return (rl_digit_loop ());
246     }
247 }
248
249 /* C-u, universal argument.  Multiply the current argument by 4.
250    Read a key.  If the key has nothing to do with arguments, then
251    dispatch on it.  If the key is the abort character then abort. */
252 int
253 rl_universal_argument (count, key)
254      int count, key;
255 {
256   _rl_arg_init ();
257   rl_numeric_arg *= 4;
258
259   return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
260 }
261
262 int
263 _rl_arg_callback (cxt)
264      _rl_arg_cxt cxt;
265 {
266   int c, r;
267
268   c = _rl_arg_getchar ();
269
270   if (_rl_argcxt & NUM_READONE)
271     {
272       _rl_argcxt &= ~NUM_READONE;
273       rl_restore_prompt ();
274       rl_clear_message ();
275       RL_UNSETSTATE(RL_STATE_NUMERICARG);
276       rl_execute_next (c);
277       return 0;
278     }
279
280   r = _rl_arg_dispatch (cxt, c);
281   return (r != 1);
282 }
283
284 /* What to do when you abort reading an argument. */
285 int
286 rl_discard_argument ()
287 {
288   rl_ding ();
289   rl_clear_message ();
290   _rl_reset_argument ();
291
292   return 0;
293 }
294
295 /* **************************************************************** */
296 /*                                                                  */
297 /*                      History Utilities                           */
298 /*                                                                  */
299 /* **************************************************************** */
300
301 /* We already have a history library, and that is what we use to control
302    the history features of readline.  This is our local interface to
303    the history mechanism. */
304
305 /* While we are editing the history, this is the saved
306    version of the original line. */
307 HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
308
309 /* Set the history pointer back to the last entry in the history. */
310 void
311 _rl_start_using_history ()
312 {
313   using_history ();
314   if (_rl_saved_line_for_history)
315     _rl_free_history_entry (_rl_saved_line_for_history);
316
317   _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
318 }
319
320 /* Free the contents (and containing structure) of a HIST_ENTRY. */
321 void
322 _rl_free_history_entry (entry)
323      HIST_ENTRY *entry;
324 {
325   if (entry == 0)
326     return;
327
328   FREE (entry->line);
329   FREE (entry->timestamp);
330
331   xfree (entry);
332 }
333
334 /* Perhaps put back the current line if it has changed. */
335 int
336 rl_maybe_replace_line ()
337 {
338   HIST_ENTRY *temp;
339
340   temp = current_history ();
341   /* If the current line has changed, save the changes. */
342   if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
343     {
344       temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
345       xfree (temp->line);
346       FREE (temp->timestamp);
347       xfree (temp);
348     }
349   return 0;
350 }
351
352 /* Restore the _rl_saved_line_for_history if there is one. */
353 int
354 rl_maybe_unsave_line ()
355 {
356   if (_rl_saved_line_for_history)
357     {
358       /* Can't call with `1' because rl_undo_list might point to an undo
359          list from a history entry, as in rl_replace_from_history() below. */
360       rl_replace_line (_rl_saved_line_for_history->line, 0);
361       rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
362       _rl_free_history_entry (_rl_saved_line_for_history);
363       _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
364       rl_point = rl_end;        /* rl_replace_line sets rl_end */
365     }
366   else
367     rl_ding ();
368   return 0;
369 }
370
371 /* Save the current line in _rl_saved_line_for_history. */
372 int
373 rl_maybe_save_line ()
374 {
375   if (_rl_saved_line_for_history == 0)
376     {
377       _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
378       _rl_saved_line_for_history->line = savestring (rl_line_buffer);
379       _rl_saved_line_for_history->timestamp = (char *)NULL;
380       _rl_saved_line_for_history->data = (char *)rl_undo_list;
381     }
382
383   return 0;
384 }
385
386 int
387 _rl_free_saved_history_line ()
388 {
389   if (_rl_saved_line_for_history)
390     {
391       _rl_free_history_entry (_rl_saved_line_for_history);
392       _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
393     }
394   return 0;
395 }
396
397 static void
398 _rl_history_set_point ()
399 {
400   rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
401                 ? _rl_history_saved_point
402                 : rl_end;
403   if (rl_point > rl_end)
404     rl_point = rl_end;
405
406 #if defined (VI_MODE)
407   if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
408     rl_point = 0;
409 #endif /* VI_MODE */
410
411   if (rl_editing_mode == emacs_mode)
412     rl_mark = (rl_point == rl_end ? 0 : rl_end);
413 }
414
415 void
416 rl_replace_from_history (entry, flags)
417      HIST_ENTRY *entry;
418      int flags;                 /* currently unused */
419 {
420   /* Can't call with `1' because rl_undo_list might point to an undo list
421      from a history entry, just like we're setting up here. */
422   rl_replace_line (entry->line, 0);
423   rl_undo_list = (UNDO_LIST *)entry->data;
424   rl_point = rl_end;
425   rl_mark = 0;
426
427 #if defined (VI_MODE)
428   if (rl_editing_mode == vi_mode)
429     {
430       rl_point = 0;
431       rl_mark = rl_end;
432     }
433 #endif
434 }
435
436 /* Process and free undo lists attached to each history entry prior to the
437    current entry, inclusive, reverting each line to its saved state.  This 
438    is destructive, and state about the current line is lost.  This is not
439    intended to be called while actively editing, and the current line is
440    not assumed to have been added to the history list. */
441 void
442 _rl_revert_all_lines ()
443 {
444   int hpos;
445   HIST_ENTRY *entry;
446   UNDO_LIST *ul, *saved_undo_list;
447   char *lbuf;
448
449   lbuf = savestring (rl_line_buffer);
450   saved_undo_list = rl_undo_list;
451   hpos = where_history ();
452
453   entry = (hpos == history_length) ? previous_history () : current_history ();
454   while (entry)
455     {
456       if (ul = (UNDO_LIST *)entry->data)
457         {
458           if (ul == saved_undo_list)
459             saved_undo_list = 0;
460           /* Set up rl_line_buffer and other variables from history entry */
461           rl_replace_from_history (entry, 0);   /* entry->line is now current */
462           /* Undo all changes to this history entry */
463           while (rl_undo_list)
464             rl_do_undo ();
465           /* And copy the reverted line back to the history entry, preserving
466              the timestamp. */
467           FREE (entry->line);
468           entry->line = savestring (rl_line_buffer);
469           entry->data = 0;
470         }
471       entry = previous_history ();
472     }
473
474   /* Restore history state */
475   rl_undo_list = saved_undo_list;       /* may have been set to null */
476   history_set_pos (hpos);
477   
478   /* reset the line buffer */
479   rl_replace_line (lbuf, 0);
480   _rl_set_the_line ();
481
482   /* and clean up */
483   xfree (lbuf);
484 }  
485
486 /* **************************************************************** */
487 /*                                                                  */
488 /*                      History Commands                            */
489 /*                                                                  */
490 /* **************************************************************** */
491
492 /* Meta-< goes to the start of the history. */
493 int
494 rl_beginning_of_history (count, key)
495      int count, key;
496 {
497   return (rl_get_previous_history (1 + where_history (), key));
498 }
499
500 /* Meta-> goes to the end of the history.  (The current line). */
501 int
502 rl_end_of_history (count, key)
503      int count, key;
504 {
505   rl_maybe_replace_line ();
506   using_history ();
507   rl_maybe_unsave_line ();
508   return 0;
509 }
510
511 /* Move down to the next history line. */
512 int
513 rl_get_next_history (count, key)
514      int count, key;
515 {
516   HIST_ENTRY *temp;
517
518   if (count < 0)
519     return (rl_get_previous_history (-count, key));
520
521   if (count == 0)
522     return 0;
523
524   rl_maybe_replace_line ();
525
526   /* either not saved by rl_newline or at end of line, so set appropriately. */
527   if (_rl_history_saved_point == -1 && (rl_point || rl_end))
528     _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
529
530   temp = (HIST_ENTRY *)NULL;
531   while (count)
532     {
533       temp = next_history ();
534       if (!temp)
535         break;
536       --count;
537     }
538
539   if (temp == 0)
540     rl_maybe_unsave_line ();
541   else
542     {
543       rl_replace_from_history (temp, 0);
544       _rl_history_set_point ();
545     }
546   return 0;
547 }
548
549 /* Get the previous item out of our interactive history, making it the current
550    line.  If there is no previous history, just ding. */
551 int
552 rl_get_previous_history (count, key)
553      int count, key;
554 {
555   HIST_ENTRY *old_temp, *temp;
556
557   if (count < 0)
558     return (rl_get_next_history (-count, key));
559
560   if (count == 0)
561     return 0;
562
563   /* either not saved by rl_newline or at end of line, so set appropriately. */
564   if (_rl_history_saved_point == -1 && (rl_point || rl_end))
565     _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
566
567   /* If we don't have a line saved, then save this one. */
568   rl_maybe_save_line ();
569
570   /* If the current line has changed, save the changes. */
571   rl_maybe_replace_line ();
572
573   temp = old_temp = (HIST_ENTRY *)NULL;
574   while (count)
575     {
576       temp = previous_history ();
577       if (temp == 0)
578         break;
579
580       old_temp = temp;
581       --count;
582     }
583
584   /* If there was a large argument, and we moved back to the start of the
585      history, that is not an error.  So use the last value found. */
586   if (!temp && old_temp)
587     temp = old_temp;
588
589   if (temp == 0)
590     rl_ding ();
591   else
592     {
593       rl_replace_from_history (temp, 0);
594       _rl_history_set_point ();
595     }
596
597   return 0;
598 }
599
600 /* **************************************************************** */
601 /*                                                                  */
602 /*                          Editing Modes                           */
603 /*                                                                  */
604 /* **************************************************************** */
605 /* How to toggle back and forth between editing modes. */
606 int
607 rl_vi_editing_mode (count, key)
608      int count, key;
609 {
610 #if defined (VI_MODE)
611   _rl_set_insert_mode (RL_IM_INSERT, 1);        /* vi mode ignores insert mode */
612   rl_editing_mode = vi_mode;
613   rl_vi_insert_mode (1, key);
614 #endif /* VI_MODE */
615
616   return 0;
617 }
618
619 int
620 rl_emacs_editing_mode (count, key)
621      int count, key;
622 {
623   rl_editing_mode = emacs_mode;
624   _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
625   _rl_keymap = emacs_standard_keymap;
626   return 0;
627 }
628
629 /* Function for the rest of the library to use to set insert/overwrite mode. */
630 void
631 _rl_set_insert_mode (im, force)
632      int im, force;
633 {
634 #ifdef CURSOR_MODE
635   _rl_set_cursor (im, force);
636 #endif
637
638   rl_insert_mode = im;
639 }
640
641 /* Toggle overwrite mode.  A positive explicit argument selects overwrite
642    mode.  A negative or zero explicit argument selects insert mode. */
643 int
644 rl_overwrite_mode (count, key)
645      int count, key;
646 {
647   if (rl_explicit_arg == 0)
648     _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
649   else if (count > 0)
650     _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
651   else
652     _rl_set_insert_mode (RL_IM_INSERT, 0);
653
654   return 0;
655 }