1 /* misc.c -- miscellaneous bindable readline functions. */
2 
3 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
4 
5    This file is part of the GNU Readline Library, a library for
6    reading lines of text with interactive input and history editing.
7 
8    The GNU Readline Library is free software; you can redistribute it
9    and/or modify it under the terms of the GNU General Public License
10    as published by the Free Software Foundation; either version 2, or
11    (at your option) any later version.
12 
13    The GNU Readline Library is distributed in the hope that it will be
14    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    The GNU General Public License is often shipped with GNU software, and
19    is generally kept in a file called COPYING or LICENSE.  If you do not
20    have a copy of the license, write to the Free Software Foundation,
21    51 Franklin Street, Fifth Floor, Boston, MA  02110-1335  USA. */
22 #define READLINE_LIBRARY
23 
24 #if defined (HAVE_CONFIG_H)
25 #  include "config_readline.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
_rl_arg_overflow()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
_rl_arg_init()95 _rl_arg_init ()
96 {
97   rl_save_prompt ();
98   _rl_argcxt = 0;
99   RL_SETSTATE(RL_STATE_NUMERICARG);
100 }
101 
102 int
_rl_arg_getchar()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
_rl_arg_dispatch(cxt,c)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 	  return (_rl_dispatch (key, _rl_keymap));
150 	}
151     }
152 
153   c = UNMETA (c);
154 
155   if (_rl_digit_p (c))
156     {
157       r = _rl_digit_value (c);
158       rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) +  r : r;
159       rl_explicit_arg = 1;
160       _rl_argcxt |= NUM_SAWDIGITS;
161     }
162   else if (c == '-' && rl_explicit_arg == 0)
163     {
164       rl_numeric_arg = 1;
165       _rl_argcxt |= NUM_SAWMINUS;
166       rl_arg_sign = -1;
167     }
168   else
169     {
170       /* Make M-- command equivalent to M--1 command. */
171       if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
172 	rl_explicit_arg = 1;
173       rl_restore_prompt ();
174       rl_clear_message ();
175       RL_UNSETSTATE(RL_STATE_NUMERICARG);
176 
177       r = _rl_dispatch (key, _rl_keymap);
178       if (RL_ISSTATE (RL_STATE_CALLBACK))
179 	{
180 	  /* At worst, this will cause an extra redisplay.  Otherwise,
181 	     we have to wait until the next character comes in. */
182 	  if (rl_done == 0)
183 	    (*rl_redisplay_function) ();
184 	  r = 0;
185 	}
186       return r;
187     }
188 
189   return 1;
190 }
191 
192 /* Handle C-u style numeric args, as well as M--, and M-digits. */
193 static int
rl_digit_loop()194 rl_digit_loop ()
195 {
196   int c, r;
197 
198   while (1)
199     {
200       if (_rl_arg_overflow ())
201 	return 1;
202 
203       c = _rl_arg_getchar ();
204 
205       if (c < 0)
206 	{
207 	  _rl_abort_internal ();
208 	  return -1;
209 	}
210 
211       r = _rl_arg_dispatch (_rl_argcxt, c);
212       if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
213         break;
214     }
215 
216   return r;
217 }
218 
219 /* Create a default argument. */
220 void
_rl_reset_argument()221 _rl_reset_argument ()
222 {
223   rl_numeric_arg = rl_arg_sign = 1;
224   rl_explicit_arg = 0;
225   _rl_argcxt = 0;
226 }
227 
228 /* Start a numeric argument with initial value KEY */
229 int
rl_digit_argument(ignore,key)230 rl_digit_argument (ignore, key)
231      int ignore __attribute__((unused)), key;
232 {
233   _rl_arg_init ();
234   if (RL_ISSTATE (RL_STATE_CALLBACK))
235     {
236       _rl_arg_dispatch (_rl_argcxt, key);
237       rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
238       return 0;
239     }
240   else
241     {
242       rl_execute_next (key);
243       return (rl_digit_loop ());
244     }
245 }
246 
247 /* C-u, universal argument.  Multiply the current argument by 4.
248    Read a key.  If the key has nothing to do with arguments, then
249    dispatch on it.  If the key is the abort character then abort. */
250 int
rl_universal_argument(count,key)251 rl_universal_argument (count, key)
252      int count __attribute__((unused)), key __attribute__((unused));
253 {
254   _rl_arg_init ();
255   rl_numeric_arg *= 4;
256 
257   return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
258 }
259 
260 int
_rl_arg_callback(cxt)261 _rl_arg_callback (cxt)
262      _rl_arg_cxt cxt;
263 {
264   int c, r;
265 
266   c = _rl_arg_getchar ();
267 
268   if (_rl_argcxt & NUM_READONE)
269     {
270       _rl_argcxt &= ~NUM_READONE;
271       rl_restore_prompt ();
272       rl_clear_message ();
273       RL_UNSETSTATE(RL_STATE_NUMERICARG);
274       rl_execute_next (c);
275       return 0;
276     }
277 
278   r = _rl_arg_dispatch (cxt, c);
279   return (r != 1);
280 }
281 
282 /* What to do when you abort reading an argument. */
283 int
rl_discard_argument()284 rl_discard_argument ()
285 {
286   rl_ding ();
287   rl_clear_message ();
288   _rl_reset_argument ();
289 
290   return 0;
291 }
292 
293 /* **************************************************************** */
294 /*								    */
295 /*			History Utilities			    */
296 /*								    */
297 /* **************************************************************** */
298 
299 /* We already have a history library, and that is what we use to control
300    the history features of readline.  This is our local interface to
301    the history mechanism. */
302 
303 /* While we are editing the history, this is the saved
304    version of the original line. */
305 HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
306 
307 /* Set the history pointer back to the last entry in the history. */
308 void
_rl_start_using_history()309 _rl_start_using_history ()
310 {
311   using_history ();
312   if (_rl_saved_line_for_history)
313     _rl_free_history_entry (_rl_saved_line_for_history);
314 
315   _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
316 }
317 
318 /* Free the contents (and containing structure) of a HIST_ENTRY. */
319 void
_rl_free_history_entry(entry)320 _rl_free_history_entry (entry)
321      HIST_ENTRY *entry;
322 {
323   if (entry == 0)
324     return;
325 
326   FREE (entry->line);
327   FREE (entry->timestamp);
328 
329   free (entry);
330 }
331 
332 /* Perhaps put back the current line if it has changed. */
333 int
rl_maybe_replace_line()334 rl_maybe_replace_line ()
335 {
336   HIST_ENTRY *temp;
337 
338   temp = current_history ();
339   /* If the current line has changed, save the changes. */
340   if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
341     {
342       temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
343       free (temp->line);
344       FREE (temp->timestamp);
345       free (temp);
346     }
347   return 0;
348 }
349 
350 /* Restore the _rl_saved_line_for_history if there is one. */
351 int
rl_maybe_unsave_line()352 rl_maybe_unsave_line ()
353 {
354   if (_rl_saved_line_for_history)
355     {
356       /* Can't call with `1' because rl_undo_list might point to an undo
357 	 list from a history entry, as in rl_replace_from_history() below. */
358       rl_replace_line (_rl_saved_line_for_history->line, 0);
359       rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
360       _rl_free_history_entry (_rl_saved_line_for_history);
361       _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
362       rl_point = rl_end;	/* rl_replace_line sets rl_end */
363     }
364   else
365     rl_ding ();
366   return 0;
367 }
368 
369 /* Save the current line in _rl_saved_line_for_history. */
370 int
rl_maybe_save_line()371 rl_maybe_save_line ()
372 {
373   if (_rl_saved_line_for_history == 0)
374     {
375       _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
376       _rl_saved_line_for_history->line = savestring (rl_line_buffer);
377       _rl_saved_line_for_history->timestamp = (char *)NULL;
378       _rl_saved_line_for_history->data = (char *)rl_undo_list;
379     }
380 
381   return 0;
382 }
383 
384 int
_rl_free_saved_history_line()385 _rl_free_saved_history_line ()
386 {
387   if (_rl_saved_line_for_history)
388     {
389       _rl_free_history_entry (_rl_saved_line_for_history);
390       _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
391     }
392   return 0;
393 }
394 
395 static void
_rl_history_set_point()396 _rl_history_set_point ()
397 {
398   rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
399 		? _rl_history_saved_point
400 		: rl_end;
401   if (rl_point > rl_end)
402     rl_point = rl_end;
403 
404 #if defined (VI_MODE)
405   if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
406     rl_point = 0;
407 #endif /* VI_MODE */
408 
409   if (rl_editing_mode == emacs_mode)
410     rl_mark = (rl_point == rl_end ? 0 : rl_end);
411 }
412 
413 void
rl_replace_from_history(entry,flags)414 rl_replace_from_history (entry, flags)
415      HIST_ENTRY *entry;
416      int flags __attribute__((unused));	/* currently unused */
417 {
418   /* Can't call with `1' because rl_undo_list might point to an undo list
419      from a history entry, just like we're setting up here. */
420   rl_replace_line (entry->line, 0);
421   rl_undo_list = (UNDO_LIST *)entry->data;
422   rl_point = rl_end;
423   rl_mark = 0;
424 
425 #if defined (VI_MODE)
426   if (rl_editing_mode == vi_mode)
427     {
428       rl_point = 0;
429       rl_mark = rl_end;
430     }
431 #endif
432 }
433 
434 /* **************************************************************** */
435 /*								    */
436 /*			History Commands			    */
437 /*								    */
438 /* **************************************************************** */
439 
440 /* Meta-< goes to the start of the history. */
441 int
rl_beginning_of_history(count,key)442 rl_beginning_of_history (count, key)
443      int count __attribute__((unused)), key;
444 {
445   return (rl_get_previous_history (1 + where_history (), key));
446 }
447 
448 /* Meta-> goes to the end of the history.  (The current line). */
449 int
rl_end_of_history(count,key)450 rl_end_of_history (count, key)
451      int count __attribute__((unused)), key __attribute__((unused));
452 {
453   rl_maybe_replace_line ();
454   using_history ();
455   rl_maybe_unsave_line ();
456   return 0;
457 }
458 
459 /* Move down to the next history line. */
460 int
rl_get_next_history(count,key)461 rl_get_next_history (count, key)
462      int count, key;
463 {
464   HIST_ENTRY *temp;
465 
466   if (count < 0)
467     return (rl_get_previous_history (-count, key));
468 
469   if (count == 0)
470     return 0;
471 
472   rl_maybe_replace_line ();
473 
474   /* either not saved by rl_newline or at end of line, so set appropriately. */
475   if (_rl_history_saved_point == -1 && (rl_point || rl_end))
476     _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
477 
478   temp = (HIST_ENTRY *)NULL;
479   while (count)
480     {
481       temp = next_history ();
482       if (!temp)
483 	break;
484       --count;
485     }
486 
487   if (temp == 0)
488     rl_maybe_unsave_line ();
489   else
490     {
491       rl_replace_from_history (temp, 0);
492       _rl_history_set_point ();
493     }
494   return 0;
495 }
496 
497 /* Get the previous item out of our interactive history, making it the current
498    line.  If there is no previous history, just ding. */
499 int
rl_get_previous_history(count,key)500 rl_get_previous_history (count, key)
501      int count, key;
502 {
503   HIST_ENTRY *old_temp, *temp;
504 
505   if (count < 0)
506     return (rl_get_next_history (-count, key));
507 
508   if (count == 0)
509     return 0;
510 
511   /* either not saved by rl_newline or at end of line, so set appropriately. */
512   if (_rl_history_saved_point == -1 && (rl_point || rl_end))
513     _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
514 
515   /* If we don't have a line saved, then save this one. */
516   rl_maybe_save_line ();
517 
518   /* If the current line has changed, save the changes. */
519   rl_maybe_replace_line ();
520 
521   temp = old_temp = (HIST_ENTRY *)NULL;
522   while (count)
523     {
524       temp = previous_history ();
525       if (temp == 0)
526 	break;
527 
528       old_temp = temp;
529       --count;
530     }
531 
532   /* If there was a large argument, and we moved back to the start of the
533      history, that is not an error.  So use the last value found. */
534   if (!temp && old_temp)
535     temp = old_temp;
536 
537   if (temp == 0)
538     rl_ding ();
539   else
540     {
541       rl_replace_from_history (temp, 0);
542       _rl_history_set_point ();
543     }
544 
545   return 0;
546 }
547 
548 /* **************************************************************** */
549 /*								    */
550 /*			    Editing Modes			    */
551 /*								    */
552 /* **************************************************************** */
553 /* How to toggle back and forth between editing modes. */
554 int
rl_vi_editing_mode(count,key)555 rl_vi_editing_mode (count, key)
556      int count __attribute__((unused)), key;
557 {
558 #if defined (VI_MODE)
559   _rl_set_insert_mode (RL_IM_INSERT, 1);	/* vi mode ignores insert mode */
560   rl_editing_mode = vi_mode;
561   rl_vi_insertion_mode (1, key);
562 #endif /* VI_MODE */
563 
564   return 0;
565 }
566 
567 int
rl_emacs_editing_mode(count,key)568 rl_emacs_editing_mode (count, key)
569      int count __attribute__((unused)), key __attribute__((unused));
570 {
571   rl_editing_mode = emacs_mode;
572   _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
573   _rl_keymap = emacs_standard_keymap;
574   return 0;
575 }
576 
577 /* Function for the rest of the library to use to set insert/overwrite mode. */
578 void
_rl_set_insert_mode(im,force)579 _rl_set_insert_mode (im, force)
580      int im, force __attribute__((unused));
581 {
582 #ifdef CURSOR_MODE
583   _rl_set_cursor (im, force);
584 #endif
585 
586   rl_insert_mode = im;
587 }
588 
589 /* Toggle overwrite mode.  A positive explicit argument selects overwrite
590    mode.  A negative or zero explicit argument selects insert mode. */
591 int
rl_overwrite_mode(count,key)592 rl_overwrite_mode (count, key)
593      int count, key __attribute__((unused));
594 {
595   if (rl_explicit_arg == 0)
596     _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
597   else if (count > 0)
598     _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
599   else
600     _rl_set_insert_mode (RL_IM_INSERT, 0);
601 
602   return 0;
603 }
604