c353252bc9fbe8adee0bf206a994c2d85d9eee73
[external/binutils.git] / readline / text.c
1 /* text.c -- text handling commands for readline. */
2
3 /* Copyright (C) 1987-2016 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 #if defined (__EMX__)
49 #  define INCL_DOSPROCESS
50 #  include <os2.h>
51 #endif /* __EMX__ */
52
53 /* Some standard library routines. */
54 #include "readline.h"
55 #include "history.h"
56
57 #include "rlprivate.h"
58 #include "rlshell.h"
59 #include "xmalloc.h"
60
61 /* Forward declarations. */
62 static int rl_change_case PARAMS((int, int));
63 static int _rl_char_search PARAMS((int, int, int));
64
65 #if defined (READLINE_CALLBACKS)
66 static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *));
67 static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *));
68 #endif
69
70 /* The largest chunk of text that can be inserted in one call to
71    rl_insert_text.  Text blocks larger than this are divided. */
72 #define TEXT_COUNT_MAX  1024
73
74 int _rl_optimize_typeahead = 1; /* rl_insert tries to read typeahead */
75
76 /* **************************************************************** */
77 /*                                                                  */
78 /*                      Insert and Delete                           */
79 /*                                                                  */
80 /* **************************************************************** */
81
82 /* Insert a string of text into the line at point.  This is the only
83    way that you should do insertion.  _rl_insert_char () calls this
84    function.  Returns the number of characters inserted. */
85 int
86 rl_insert_text (string)
87      const char *string;
88 {
89   register int i, l;
90
91   l = (string && *string) ? strlen (string) : 0;
92   if (l == 0)
93     return 0;
94
95   if (rl_end + l >= rl_line_buffer_len)
96     rl_extend_line_buffer (rl_end + l);
97
98   for (i = rl_end; i >= rl_point; i--)
99     rl_line_buffer[i + l] = rl_line_buffer[i];
100   strncpy (rl_line_buffer + rl_point, string, l);
101
102   /* Remember how to undo this if we aren't undoing something. */
103   if (_rl_doing_an_undo == 0)
104     {
105       /* If possible and desirable, concatenate the undos. */
106       if ((l == 1) &&
107           rl_undo_list &&
108           (rl_undo_list->what == UNDO_INSERT) &&
109           (rl_undo_list->end == rl_point) &&
110           (rl_undo_list->end - rl_undo_list->start < 20))
111         rl_undo_list->end++;
112       else
113         rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
114     }
115   rl_point += l;
116   rl_end += l;
117   rl_line_buffer[rl_end] = '\0';
118   return l;
119 }
120
121 /* Delete the string between FROM and TO.  FROM is inclusive, TO is not.
122    Returns the number of characters deleted. */
123 int
124 rl_delete_text (from, to)
125      int from, to;
126 {
127   register char *text;
128   register int diff, i;
129
130   /* Fix it if the caller is confused. */
131   if (from > to)
132     SWAP (from, to);
133
134   /* fix boundaries */
135   if (to > rl_end)
136     {
137       to = rl_end;
138       if (from > to)
139         from = to;
140     }
141   if (from < 0)
142     from = 0;
143
144   text = rl_copy_text (from, to);
145
146   /* Some versions of strncpy() can't handle overlapping arguments. */
147   diff = to - from;
148   for (i = from; i < rl_end - diff; i++)
149     rl_line_buffer[i] = rl_line_buffer[i + diff];
150
151   /* Remember how to undo this delete. */
152   if (_rl_doing_an_undo == 0)
153     rl_add_undo (UNDO_DELETE, from, to, text);
154   else
155     xfree (text);
156
157   rl_end -= diff;
158   rl_line_buffer[rl_end] = '\0';
159   return (diff);
160 }
161
162 /* Fix up point so that it is within the line boundaries after killing
163    text.  If FIX_MARK_TOO is non-zero, the mark is forced within line
164    boundaries also. */
165
166 #define _RL_FIX_POINT(x) \
167         do { \
168         if (x > rl_end) \
169           x = rl_end; \
170         else if (x < 0) \
171           x = 0; \
172         } while (0)
173
174 void
175 _rl_fix_point (fix_mark_too)
176      int fix_mark_too;
177 {
178   _RL_FIX_POINT (rl_point);
179   if (fix_mark_too)
180     _RL_FIX_POINT (rl_mark);
181 }
182 #undef _RL_FIX_POINT
183
184 /* Replace the contents of the line buffer between START and END with
185    TEXT.  The operation is undoable.  To replace the entire line in an
186    undoable mode, use _rl_replace_text(text, 0, rl_end); */
187 int
188 _rl_replace_text (text, start, end)
189      const char *text;
190      int start, end;
191 {
192   int n;
193
194   n = 0;
195   rl_begin_undo_group ();
196   if (start <= end)
197     rl_delete_text (start, end + 1);
198   rl_point = start;
199   if (*text)
200     n = rl_insert_text (text);
201   rl_end_undo_group ();
202
203   return n;
204 }
205
206 /* Replace the current line buffer contents with TEXT.  If CLEAR_UNDO is
207    non-zero, we free the current undo list. */
208 void
209 rl_replace_line (text, clear_undo)
210      const char *text;
211      int clear_undo;
212 {
213   int len;
214
215   len = strlen (text);
216   if (len >= rl_line_buffer_len)
217     rl_extend_line_buffer (len);
218   strcpy (rl_line_buffer, text);
219   rl_end = len;
220
221   if (clear_undo)
222     rl_free_undo_list ();
223
224   _rl_fix_point (1);
225 }
226
227 /* **************************************************************** */
228 /*                                                                  */
229 /*                      Readline character functions                */
230 /*                                                                  */
231 /* **************************************************************** */
232
233 /* This is not a gap editor, just a stupid line input routine.  No hair
234    is involved in writing any of the functions, and none should be. */
235
236 /* Note that:
237
238    rl_end is the place in the string that we would place '\0';
239    i.e., it is always safe to place '\0' there.
240
241    rl_point is the place in the string where the cursor is.  Sometimes
242    this is the same as rl_end.
243
244    Any command that is called interactively receives two arguments.
245    The first is a count: the numeric arg passed to this command.
246    The second is the key which invoked this command.
247 */
248
249 /* **************************************************************** */
250 /*                                                                  */
251 /*                      Movement Commands                           */
252 /*                                                                  */
253 /* **************************************************************** */
254
255 /* Note that if you `optimize' the display for these functions, you cannot
256    use said functions in other functions which do not do optimizing display.
257    I.e., you will have to update the data base for rl_redisplay, and you
258    might as well let rl_redisplay do that job. */
259
260 /* Move forward COUNT bytes. */
261 int
262 rl_forward_byte (count, key)
263      int count, key;
264 {
265   if (count < 0)
266     return (rl_backward_byte (-count, key));
267
268   if (count > 0)
269     {
270       int end, lend;
271
272       end = rl_point + count;
273 #if defined (VI_MODE)
274       lend = rl_end > 0 ? rl_end - (VI_COMMAND_MODE()) : rl_end;
275 #else
276       lend = rl_end;
277 #endif
278
279       if (end > lend)
280         {
281           rl_point = lend;
282           rl_ding ();
283         }
284       else
285         rl_point = end;
286     }
287
288   if (rl_end < 0)
289     rl_end = 0;
290
291   return 0;
292 }
293
294 int
295 _rl_forward_char_internal (count)
296      int count;
297 {
298   int point;
299
300 #if defined (HANDLE_MULTIBYTE)
301   point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
302
303 #if defined (VI_MODE)
304   if (point >= rl_end && VI_COMMAND_MODE())
305     point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
306 #endif
307
308     if (rl_end < 0)
309         rl_end = 0;
310 #else
311   point = rl_point + count;
312   if (point > rl_end)
313     point = rl_end;
314 #endif
315
316   return (point);
317 }
318
319 #if defined (HANDLE_MULTIBYTE)
320 /* Move forward COUNT characters. */
321 int
322 rl_forward_char (count, key)
323      int count, key;
324 {
325   int point;
326
327   if (MB_CUR_MAX == 1 || rl_byte_oriented)
328     return (rl_forward_byte (count, key));
329
330   if (count < 0)
331     return (rl_backward_char (-count, key));
332
333   if (count > 0)
334     {
335       if (rl_point == rl_end && EMACS_MODE())
336         {
337           rl_ding ();
338           return 0;
339         }
340
341       point = _rl_forward_char_internal (count);
342
343       if (rl_point == point)
344         rl_ding ();
345
346       rl_point = point;
347     }
348
349   return 0;
350 }
351 #else /* !HANDLE_MULTIBYTE */
352 int
353 rl_forward_char (count, key)
354      int count, key;
355 {
356   return (rl_forward_byte (count, key));
357 }
358 #endif /* !HANDLE_MULTIBYTE */
359   
360 /* Backwards compatibility. */
361 int
362 rl_forward (count, key)
363      int count, key;
364 {
365   return (rl_forward_char (count, key));
366 }
367
368 /* Move backward COUNT bytes. */
369 int
370 rl_backward_byte (count, key)
371      int count, key;
372 {
373   if (count < 0)
374     return (rl_forward_byte (-count, key));
375
376   if (count > 0)
377     {
378       if (rl_point < count)
379         {
380           rl_point = 0;
381           rl_ding ();
382         }
383       else
384         rl_point -= count;
385     }
386
387   if (rl_point < 0)
388     rl_point = 0;
389
390   return 0;
391 }
392
393 #if defined (HANDLE_MULTIBYTE)
394 /* Move backward COUNT characters. */
395 int
396 rl_backward_char (count, key)
397      int count, key;
398 {
399   int point;
400
401   if (MB_CUR_MAX == 1 || rl_byte_oriented)
402     return (rl_backward_byte (count, key));
403
404   if (count < 0)
405     return (rl_forward_char (-count, key));
406
407   if (count > 0)
408     {
409       point = rl_point;
410
411       while (count > 0 && point > 0)
412         {
413           point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
414           count--;
415         }
416       if (count > 0)
417         {
418           rl_point = 0;
419           rl_ding ();
420         }
421       else
422         rl_point = point;
423     }
424
425   return 0;
426 }
427 #else
428 int
429 rl_backward_char (count, key)
430      int count, key;
431 {
432   return (rl_backward_byte (count, key));
433 }
434 #endif
435
436 /* Backwards compatibility. */
437 int
438 rl_backward (count, key)
439      int count, key;
440 {
441   return (rl_backward_char (count, key));
442 }
443
444 /* Move to the beginning of the line. */
445 int
446 rl_beg_of_line (count, key)
447      int count, key;
448 {
449   rl_point = 0;
450   return 0;
451 }
452
453 /* Move to the end of the line. */
454 int
455 rl_end_of_line (count, key)
456      int count, key;
457 {
458   rl_point = rl_end;
459   return 0;
460 }
461
462 /* Move forward a word.  We do what Emacs does.  Handles multibyte chars. */
463 int
464 rl_forward_word (count, key)
465      int count, key;
466 {
467   int c;
468
469   if (count < 0)
470     return (rl_backward_word (-count, key));
471
472   while (count)
473     {
474       if (rl_point == rl_end)
475         return 0;
476
477       /* If we are not in a word, move forward until we are in one.
478          Then, move forward until we hit a non-alphabetic character. */
479       c = _rl_char_value (rl_line_buffer, rl_point);
480
481       if (_rl_walphabetic (c) == 0)
482         {
483           rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
484           while (rl_point < rl_end)
485             {
486               c = _rl_char_value (rl_line_buffer, rl_point);
487               if (_rl_walphabetic (c))
488                 break;
489               rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
490             }
491         }
492
493       if (rl_point == rl_end)
494         return 0;
495
496       rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
497       while (rl_point < rl_end)
498         {
499           c = _rl_char_value (rl_line_buffer, rl_point);
500           if (_rl_walphabetic (c) == 0)
501             break;
502           rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
503         }
504
505       --count;
506     }
507
508   return 0;
509 }
510
511 /* Move backward a word.  We do what Emacs does.  Handles multibyte chars. */
512 int
513 rl_backward_word (count, key)
514      int count, key;
515 {
516   int c, p;
517
518   if (count < 0)
519     return (rl_forward_word (-count, key));
520
521   while (count)
522     {
523       if (rl_point == 0)
524         return 0;
525
526       /* Like rl_forward_word (), except that we look at the characters
527          just before point. */
528
529       p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
530       c = _rl_char_value (rl_line_buffer, p);
531
532       if (_rl_walphabetic (c) == 0)
533         {
534           rl_point = p;
535           while (rl_point > 0)
536             {
537               p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
538               c = _rl_char_value (rl_line_buffer, p);
539               if (_rl_walphabetic (c))
540                 break;
541               rl_point = p;
542             }
543         }
544
545       while (rl_point)
546         {
547           p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
548           c = _rl_char_value (rl_line_buffer, p);         
549           if (_rl_walphabetic (c) == 0)
550             break;
551           else
552             rl_point = p;
553         }
554
555       --count;
556     }
557
558   return 0;
559 }
560
561 /* Clear the current line.  Numeric argument to C-l does this. */
562 int
563 rl_refresh_line (ignore1, ignore2)
564      int ignore1, ignore2;
565 {
566   int curr_line;
567
568   curr_line = _rl_current_display_line ();
569
570   _rl_move_vert (curr_line);
571   _rl_move_cursor_relative (0, rl_line_buffer);   /* XXX is this right */
572
573   _rl_clear_to_eol (0);         /* arg of 0 means to not use spaces */
574
575   rl_redraw_prompt_last_line ();
576   rl_display_fixed = 1;
577
578   return 0;
579 }
580
581 /* C-l typed to a line without quoting clears the screen, and then reprints
582    the prompt and the current input line.  Given a numeric arg, redraw only
583    the current line. */
584 int
585 rl_clear_screen (count, key)
586      int count, key;
587 {
588   if (rl_explicit_arg)
589     {
590       rl_refresh_line (count, key);
591       return 0;
592     }
593
594   _rl_clear_screen ();          /* calls termcap function to clear screen */
595   rl_forced_update_display ();
596   rl_display_fixed = 1;
597
598   return 0;
599 }
600
601 int
602 rl_skip_csi_sequence (count, key)
603      int count, key;
604 {
605   int ch;
606
607   RL_SETSTATE (RL_STATE_MOREINPUT);
608   do
609     ch = rl_read_key ();
610   while (ch >= 0x20 && ch < 0x40);
611   RL_UNSETSTATE (RL_STATE_MOREINPUT);
612
613   return (ch < 0);
614 }
615
616 int
617 rl_arrow_keys (count, c)
618      int count, c;
619 {
620   int ch;
621
622   RL_SETSTATE(RL_STATE_MOREINPUT);
623   ch = rl_read_key ();
624   RL_UNSETSTATE(RL_STATE_MOREINPUT);
625   if (ch < 0)
626     return (1);
627
628   switch (_rl_to_upper (ch))
629     {
630     case 'A':
631       rl_get_previous_history (count, ch);
632       break;
633
634     case 'B':
635       rl_get_next_history (count, ch);
636       break;
637
638     case 'C':
639       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
640         rl_forward_char (count, ch);
641       else
642         rl_forward_byte (count, ch);
643       break;
644
645     case 'D':
646       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
647         rl_backward_char (count, ch);
648       else
649         rl_backward_byte (count, ch);
650       break;
651
652     default:
653       rl_ding ();
654     }
655
656   return 0;
657 }
658
659 /* **************************************************************** */
660 /*                                                                  */
661 /*                      Text commands                               */
662 /*                                                                  */
663 /* **************************************************************** */
664
665 #ifdef HANDLE_MULTIBYTE
666 static char pending_bytes[MB_LEN_MAX];
667 static int pending_bytes_length = 0;
668 static mbstate_t ps = {0};
669 #endif
670
671 /* Insert the character C at the current location, moving point forward.
672    If C introduces a multibyte sequence, we read the whole sequence and
673    then insert the multibyte char into the line buffer. */
674 int
675 _rl_insert_char (count, c)
676      int count, c;
677 {
678   register int i;
679   char *string;
680 #ifdef HANDLE_MULTIBYTE
681   int string_size;
682   char incoming[MB_LEN_MAX + 1];
683   int incoming_length = 0;
684   mbstate_t ps_back;
685   static int stored_count = 0;
686 #endif
687
688   if (count <= 0)
689     return 0;
690
691 #if defined (HANDLE_MULTIBYTE)
692   if (MB_CUR_MAX == 1 || rl_byte_oriented)
693     {
694       incoming[0] = c;
695       incoming[1] = '\0';
696       incoming_length = 1;
697     }
698   else
699     {
700       wchar_t wc;
701       size_t ret;
702
703       if (stored_count <= 0)
704         stored_count = count;
705       else
706         count = stored_count;
707
708       ps_back = ps;
709       pending_bytes[pending_bytes_length++] = c;
710       ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
711
712       if (ret == (size_t)-2)
713         {
714           /* Bytes too short to compose character, try to wait for next byte.
715              Restore the state of the byte sequence, because in this case the
716              effect of mbstate is undefined. */
717           ps = ps_back;
718           return 1;
719         }
720       else if (ret == (size_t)-1)
721         {
722           /* Invalid byte sequence for the current locale.  Treat first byte
723              as a single character. */
724           incoming[0] = pending_bytes[0];
725           incoming[1] = '\0';
726           incoming_length = 1;
727           pending_bytes_length--;
728           memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
729           /* Clear the state of the byte sequence, because in this case the
730              effect of mbstate is undefined. */
731           memset (&ps, 0, sizeof (mbstate_t));
732         }
733       else if (ret == (size_t)0)
734         {
735           incoming[0] = '\0';
736           incoming_length = 0;
737           pending_bytes_length--;
738           /* Clear the state of the byte sequence, because in this case the
739              effect of mbstate is undefined. */
740           memset (&ps, 0, sizeof (mbstate_t));
741         }
742       else
743         {
744           /* We successfully read a single multibyte character. */
745           memcpy (incoming, pending_bytes, pending_bytes_length);
746           incoming[pending_bytes_length] = '\0';
747           incoming_length = pending_bytes_length;
748           pending_bytes_length = 0;
749         }
750     }
751 #endif /* HANDLE_MULTIBYTE */
752           
753   /* If we can optimize, then do it.  But don't let people crash
754      readline because of extra large arguments. */
755   if (count > 1 && count <= TEXT_COUNT_MAX)
756     {
757 #if defined (HANDLE_MULTIBYTE)
758       string_size = count * incoming_length;
759       string = (char *)xmalloc (1 + string_size);
760
761       i = 0;
762       while (i < string_size)
763         {
764           strncpy (string + i, incoming, incoming_length);
765           i += incoming_length;
766         }
767       incoming_length = 0;
768       stored_count = 0;
769 #else /* !HANDLE_MULTIBYTE */
770       string = (char *)xmalloc (1 + count);
771
772       for (i = 0; i < count; i++)
773         string[i] = c;
774 #endif /* !HANDLE_MULTIBYTE */
775
776       string[i] = '\0';
777       rl_insert_text (string);
778       xfree (string);
779
780       return 0;
781     }
782
783   if (count > TEXT_COUNT_MAX)
784     {
785       int decreaser;
786 #if defined (HANDLE_MULTIBYTE)
787       string_size = incoming_length * TEXT_COUNT_MAX;
788       string = (char *)xmalloc (1 + string_size);
789
790       i = 0;
791       while (i < string_size)
792         {
793           strncpy (string + i, incoming, incoming_length);
794           i += incoming_length;
795         }
796
797       while (count)
798         {
799           decreaser = (count > TEXT_COUNT_MAX) ? TEXT_COUNT_MAX : count;
800           string[decreaser*incoming_length] = '\0';
801           rl_insert_text (string);
802           count -= decreaser;
803         }
804
805       xfree (string);
806       incoming_length = 0;
807       stored_count = 0;
808 #else /* !HANDLE_MULTIBYTE */
809       char str[TEXT_COUNT_MAX+1];
810
811       for (i = 0; i < TEXT_COUNT_MAX; i++)
812         str[i] = c;
813
814       while (count)
815         {
816           decreaser = (count > TEXT_COUNT_MAX ? TEXT_COUNT_MAX : count);
817           str[decreaser] = '\0';
818           rl_insert_text (str);
819           count -= decreaser;
820         }
821 #endif /* !HANDLE_MULTIBYTE */
822
823       return 0;
824     }
825
826   if (MB_CUR_MAX == 1 || rl_byte_oriented)
827     {
828       /* We are inserting a single character.
829          If there is pending input, then make a string of all of the
830          pending characters that are bound to rl_insert, and insert
831          them all.  Don't do this if we're current reading input from
832          a macro. */
833       if ((RL_ISSTATE (RL_STATE_MACROINPUT) == 0) && _rl_pushed_input_available ())
834         _rl_insert_typein (c);
835       else
836         {
837           /* Inserting a single character. */
838           char str[2];
839
840           str[1] = '\0';
841           str[0] = c;
842           rl_insert_text (str);
843         }
844     }
845 #if defined (HANDLE_MULTIBYTE)
846   else
847     {
848       rl_insert_text (incoming);
849       stored_count = 0;
850     }
851 #endif
852
853   return 0;
854 }
855
856 /* Overwrite the character at point (or next COUNT characters) with C.
857    If C introduces a multibyte character sequence, read the entire sequence
858    before starting the overwrite loop. */
859 int
860 _rl_overwrite_char (count, c)
861      int count, c;
862 {
863   int i;
864 #if defined (HANDLE_MULTIBYTE)
865   char mbkey[MB_LEN_MAX];
866   int k;
867
868   /* Read an entire multibyte character sequence to insert COUNT times. */
869   if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
870     k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
871 #endif
872
873   rl_begin_undo_group ();
874
875   for (i = 0; i < count; i++)
876     {
877 #if defined (HANDLE_MULTIBYTE)
878       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
879         rl_insert_text (mbkey);
880       else
881 #endif
882         _rl_insert_char (1, c);
883
884       if (rl_point < rl_end)
885         rl_delete (1, c);
886     }
887
888   rl_end_undo_group ();
889
890   return 0;
891 }
892
893 int
894 rl_insert (count, c)
895      int count, c;
896 {
897   int r, n, x;
898
899   r = (rl_insert_mode == RL_IM_INSERT) ? _rl_insert_char (count, c) : _rl_overwrite_char (count, c);
900
901   /* XXX -- attempt to batch-insert pending input that maps to self-insert */
902   x = 0;
903   n = (unsigned short)-2;
904   while (_rl_optimize_typeahead &&
905          (RL_ISSTATE (RL_STATE_INPUTPENDING|RL_STATE_MACROINPUT) == 0) &&
906          _rl_pushed_input_available () == 0 &&
907          _rl_input_queued (0) &&
908          (n = rl_read_key ()) > 0 &&
909          _rl_keymap[(unsigned char)n].type == ISFUNC &&
910          _rl_keymap[(unsigned char)n].function == rl_insert)
911     {
912       r = (rl_insert_mode == RL_IM_INSERT) ? _rl_insert_char (1, n) : _rl_overwrite_char (1, n);
913       /* _rl_insert_char keeps its own set of pending characters to compose a
914          complete multibyte character, and only returns 1 if it sees a character
915          that's part of a multibyte character but too short to complete one.  We
916          can try to read another character in the hopes that we will get the
917          next one or just punt.  Right now we try to read another character.
918          We don't want to call rl_insert_next if _rl_insert_char has already
919          stored the character in the pending_bytes array because that will
920          result in doubled input. */
921       n = (unsigned short)-2;
922       x++;              /* count of bytes of typeahead read, currently unused */
923       if (r == 1)       /* read partial multibyte character */
924         continue;
925       if (rl_done || r != 0)
926         break;
927     }
928
929   if (n != (unsigned short)-2)          /* -2 = sentinel value for having inserted N */
930     {
931       /* setting rl_pending_input inhibits setting rl_last_func so we do it
932          ourselves here */
933       rl_last_func = rl_insert; 
934       _rl_reset_argument ();
935       rl_executing_keyseq[rl_key_sequence_length = 0] = '\0';
936       r = rl_execute_next (n);
937     }
938
939   return r;
940 }
941
942 /* Insert the next typed character verbatim. */
943 static int
944 _rl_insert_next (count)
945      int count;
946 {
947   int c;
948
949   RL_SETSTATE(RL_STATE_MOREINPUT);
950   c = rl_read_key ();
951   RL_UNSETSTATE(RL_STATE_MOREINPUT);
952
953   if (c < 0)
954     return 1;
955
956   if (RL_ISSTATE (RL_STATE_MACRODEF))
957     _rl_add_macro_char (c);
958
959 #if defined (HANDLE_SIGNALS)
960   if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
961     _rl_restore_tty_signals ();
962 #endif
963
964   return (_rl_insert_char (count, c));  
965 }
966
967 #if defined (READLINE_CALLBACKS)
968 static int
969 _rl_insert_next_callback (data)
970      _rl_callback_generic_arg *data;
971 {
972   int count;
973
974   count = data->count;
975
976   /* Deregister function, let rl_callback_read_char deallocate data */
977   _rl_callback_func = 0;
978   _rl_want_redisplay = 1;
979  
980   return _rl_insert_next (count);
981 }
982 #endif
983   
984 int
985 rl_quoted_insert (count, key)
986      int count, key;
987 {
988   /* Let's see...should the callback interface futz with signal handling? */
989 #if defined (HANDLE_SIGNALS)
990   if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
991     _rl_disable_tty_signals ();
992 #endif
993
994 #if defined (READLINE_CALLBACKS)
995   if (RL_ISSTATE (RL_STATE_CALLBACK))
996     {
997       _rl_callback_data = _rl_callback_data_alloc (count);
998       _rl_callback_func = _rl_insert_next_callback;
999       return (0);
1000     }
1001 #endif
1002       
1003   return _rl_insert_next (count);
1004 }
1005
1006 /* Insert a tab character. */
1007 int
1008 rl_tab_insert (count, key)
1009      int count, key;
1010 {
1011   return (_rl_insert_char (count, '\t'));
1012 }
1013
1014 /* What to do when a NEWLINE is pressed.  We accept the whole line.
1015    KEY is the key that invoked this command.  I guess it could have
1016    meaning in the future. */
1017 int
1018 rl_newline (count, key)
1019      int count, key;
1020 {
1021   rl_done = 1;
1022
1023   if (_rl_history_preserve_point)
1024     _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
1025
1026   RL_SETSTATE(RL_STATE_DONE);
1027
1028 #if defined (VI_MODE)
1029   if (rl_editing_mode == vi_mode)
1030     {
1031       _rl_vi_done_inserting ();
1032       if (_rl_vi_textmod_command (_rl_vi_last_command) == 0)    /* XXX */
1033         _rl_vi_reset_last ();
1034     }
1035 #endif /* VI_MODE */
1036
1037   /* If we've been asked to erase empty lines, suppress the final update,
1038      since _rl_update_final calls rl_crlf(). */
1039   if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
1040     return 0;
1041
1042   if (_rl_echoing_p)
1043     _rl_update_final ();
1044   return 0;
1045 }
1046
1047 /* What to do for some uppercase characters, like meta characters,
1048    and some characters appearing in emacs_ctlx_keymap.  This function
1049    is just a stub, you bind keys to it and the code in _rl_dispatch ()
1050    is special cased. */
1051 int
1052 rl_do_lowercase_version (ignore1, ignore2)
1053      int ignore1, ignore2;
1054 {
1055   return 0;
1056 }
1057
1058 /* This is different from what vi does, so the code's not shared.  Emacs
1059    rubout in overwrite mode has one oddity:  it replaces a control
1060    character that's displayed as two characters (^X) with two spaces. */
1061 int
1062 _rl_overwrite_rubout (count, key)
1063      int count, key;
1064 {
1065   int opoint;
1066   int i, l;
1067
1068   if (rl_point == 0)
1069     {
1070       rl_ding ();
1071       return 1;
1072     }
1073
1074   opoint = rl_point;
1075
1076   /* L == number of spaces to insert */
1077   for (i = l = 0; i < count; i++)
1078     {
1079       rl_backward_char (1, key);
1080       l += rl_character_len (rl_line_buffer[rl_point], rl_point);       /* not exactly right */
1081     }
1082
1083   rl_begin_undo_group ();
1084
1085   if (count > 1 || rl_explicit_arg)
1086     rl_kill_text (opoint, rl_point);
1087   else
1088     rl_delete_text (opoint, rl_point);
1089
1090   /* Emacs puts point at the beginning of the sequence of spaces. */
1091   if (rl_point < rl_end)
1092     {
1093       opoint = rl_point;
1094       _rl_insert_char (l, ' ');
1095       rl_point = opoint;
1096     }
1097
1098   rl_end_undo_group ();
1099
1100   return 0;
1101 }
1102   
1103 /* Rubout the character behind point. */
1104 int
1105 rl_rubout (count, key)
1106      int count, key;
1107 {
1108   if (count < 0)
1109     return (rl_delete (-count, key));
1110
1111   if (!rl_point)
1112     {
1113       rl_ding ();
1114       return 1;
1115     }
1116
1117   if (rl_insert_mode == RL_IM_OVERWRITE)
1118     return (_rl_overwrite_rubout (count, key));
1119
1120   return (_rl_rubout_char (count, key));
1121 }
1122
1123 int
1124 _rl_rubout_char (count, key)
1125      int count, key;
1126 {
1127   int orig_point;
1128   unsigned char c;
1129
1130   /* Duplicated code because this is called from other parts of the library. */
1131   if (count < 0)
1132     return (rl_delete (-count, key));
1133
1134   if (rl_point == 0)
1135     {
1136       rl_ding ();
1137       return 1;
1138     }
1139
1140   orig_point = rl_point;
1141   if (count > 1 || rl_explicit_arg)
1142     {
1143       rl_backward_char (count, key);
1144       rl_kill_text (orig_point, rl_point);
1145     }
1146   else if (MB_CUR_MAX == 1 || rl_byte_oriented)
1147     {
1148       c = rl_line_buffer[--rl_point];
1149       rl_delete_text (rl_point, orig_point);
1150       /* The erase-at-end-of-line hack is of questionable merit now. */
1151       if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos)
1152         {
1153           int l;
1154           l = rl_character_len (c, rl_point);
1155           _rl_erase_at_end_of_line (l);
1156         }
1157     }
1158   else
1159     {
1160       rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1161       rl_delete_text (rl_point, orig_point);
1162     }
1163
1164   return 0;
1165 }
1166
1167 /* Delete the character under the cursor.  Given a numeric argument,
1168    kill that many characters instead. */
1169 int
1170 rl_delete (count, key)
1171      int count, key;
1172 {
1173   int xpoint;
1174
1175   if (count < 0)
1176     return (_rl_rubout_char (-count, key));
1177
1178   if (rl_point == rl_end)
1179     {
1180       rl_ding ();
1181       return 1;
1182     }
1183
1184   if (count > 1 || rl_explicit_arg)
1185     {
1186       xpoint = rl_point;
1187       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1188         rl_forward_char (count, key);
1189       else
1190         rl_forward_byte (count, key);
1191
1192       rl_kill_text (xpoint, rl_point);
1193       rl_point = xpoint;
1194     }
1195   else
1196     {
1197       xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
1198       rl_delete_text (rl_point, xpoint);
1199     }
1200   return 0;
1201 }
1202
1203 /* Delete the character under the cursor, unless the insertion
1204    point is at the end of the line, in which case the character
1205    behind the cursor is deleted.  COUNT is obeyed and may be used
1206    to delete forward or backward that many characters. */      
1207 int
1208 rl_rubout_or_delete (count, key)
1209      int count, key;
1210 {
1211   if (rl_end != 0 && rl_point == rl_end)
1212     return (_rl_rubout_char (count, key));
1213   else
1214     return (rl_delete (count, key));
1215 }  
1216
1217 /* Delete all spaces and tabs around point. */
1218 int
1219 rl_delete_horizontal_space (count, ignore)
1220      int count, ignore;
1221 {
1222   int start;
1223
1224   while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
1225     rl_point--;
1226
1227   start = rl_point;
1228
1229   while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1230     rl_point++;
1231
1232   if (start != rl_point)
1233     {
1234       rl_delete_text (start, rl_point);
1235       rl_point = start;
1236     }
1237
1238   if (rl_point < 0)
1239     rl_point = 0;
1240
1241   return 0;
1242 }
1243
1244 /* Like the tcsh editing function delete-char-or-list.  The eof character
1245    is caught before this is invoked, so this really does the same thing as
1246    delete-char-or-list-or-eof, as long as it's bound to the eof character. */
1247 int
1248 rl_delete_or_show_completions (count, key)
1249      int count, key;
1250 {
1251   if (rl_end != 0 && rl_point == rl_end)
1252     return (rl_possible_completions (count, key));
1253   else
1254     return (rl_delete (count, key));
1255 }
1256
1257 #ifndef RL_COMMENT_BEGIN_DEFAULT
1258 #define RL_COMMENT_BEGIN_DEFAULT "#"
1259 #endif
1260
1261 /* Turn the current line into a comment in shell history.
1262    A K*rn shell style function. */
1263 int
1264 rl_insert_comment (count, key)
1265      int count, key;
1266 {
1267   char *rl_comment_text;
1268   int rl_comment_len;
1269
1270   rl_beg_of_line (1, key);
1271   rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
1272
1273   if (rl_explicit_arg == 0)
1274     rl_insert_text (rl_comment_text);
1275   else
1276     {
1277       rl_comment_len = strlen (rl_comment_text);
1278       if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
1279         rl_delete_text (rl_point, rl_point + rl_comment_len);
1280       else
1281         rl_insert_text (rl_comment_text);
1282     }
1283
1284   (*rl_redisplay_function) ();
1285   rl_newline (1, '\n');
1286
1287   return (0);
1288 }
1289
1290 /* **************************************************************** */
1291 /*                                                                  */
1292 /*                      Changing Case                               */
1293 /*                                                                  */
1294 /* **************************************************************** */
1295
1296 /* The three kinds of things that we know how to do. */
1297 #define UpCase 1
1298 #define DownCase 2
1299 #define CapCase 3
1300
1301 /* Uppercase the word at point. */
1302 int
1303 rl_upcase_word (count, key)
1304      int count, key;
1305 {
1306   return (rl_change_case (count, UpCase));
1307 }
1308
1309 /* Lowercase the word at point. */
1310 int
1311 rl_downcase_word (count, key)
1312      int count, key;
1313 {
1314   return (rl_change_case (count, DownCase));
1315 }
1316
1317 /* Upcase the first letter, downcase the rest. */
1318 int
1319 rl_capitalize_word (count, key)
1320      int count, key;
1321 {
1322  return (rl_change_case (count, CapCase));
1323 }
1324
1325 /* The meaty function.
1326    Change the case of COUNT words, performing OP on them.
1327    OP is one of UpCase, DownCase, or CapCase.
1328    If a negative argument is given, leave point where it started,
1329    otherwise, leave it where it moves to. */
1330 static int
1331 rl_change_case (count, op)
1332      int count, op;
1333 {
1334   int start, next, end;
1335   int inword, c, nc, nop;
1336 #if defined (HANDLE_MULTIBYTE)
1337   wchar_t wc, nwc;
1338   char mb[MB_LEN_MAX+1];
1339   int mlen;
1340   size_t m;
1341   mbstate_t mps;
1342 #endif
1343
1344   start = rl_point;
1345   rl_forward_word (count, 0);
1346   end = rl_point;
1347
1348   if (op != UpCase && op != DownCase && op != CapCase)
1349     {
1350       rl_ding ();
1351       return 1;
1352     }
1353
1354   if (count < 0)
1355     SWAP (start, end);
1356
1357 #if defined (HANDLE_MULTIBYTE)
1358   memset (&mps, 0, sizeof (mbstate_t));
1359 #endif
1360
1361   /* We are going to modify some text, so let's prepare to undo it. */
1362   rl_modifying (start, end);
1363
1364   inword = 0;
1365   while (start < end)
1366     {
1367       c = _rl_char_value (rl_line_buffer, start);
1368       /*  This assumes that the upper and lower case versions are the same width. */
1369       next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
1370
1371       if (_rl_walphabetic (c) == 0)
1372         {
1373           inword = 0;
1374           start = next;
1375           continue;
1376         }
1377
1378       if (op == CapCase)
1379         {
1380           nop = inword ? DownCase : UpCase;
1381           inword = 1;
1382         }
1383       else
1384         nop = op;
1385       if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii ((unsigned char)c))
1386         {
1387           nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
1388           rl_line_buffer[start] = nc;
1389         }
1390 #if defined (HANDLE_MULTIBYTE)
1391       else
1392         {
1393           m = mbrtowc (&wc, rl_line_buffer + start, end - start, &mps);
1394           if (MB_INVALIDCH (m))
1395             wc = (wchar_t)rl_line_buffer[start];
1396           else if (MB_NULLWCH (m))
1397             wc = L'\0';
1398           nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
1399           if  (nwc != wc)       /*  just skip unchanged characters */
1400             {
1401               mlen = wcrtomb (mb, nwc, &mps);
1402               if (mlen > 0)
1403                 mb[mlen] = '\0';
1404               /* Assume the same width */
1405               strncpy (rl_line_buffer + start, mb, mlen);
1406             }
1407         }
1408 #endif
1409
1410       start = next;
1411     }
1412
1413   rl_point = end;
1414   return 0;
1415 }
1416
1417 /* **************************************************************** */
1418 /*                                                                  */
1419 /*                      Transposition                               */
1420 /*                                                                  */
1421 /* **************************************************************** */
1422
1423 /* Transpose the words at point.  If point is at the end of the line,
1424    transpose the two words before point. */
1425 int
1426 rl_transpose_words (count, key)
1427      int count, key;
1428 {
1429   char *word1, *word2;
1430   int w1_beg, w1_end, w2_beg, w2_end;
1431   int orig_point = rl_point;
1432
1433   if (!count)
1434     return 0;
1435
1436   /* Find the two words. */
1437   rl_forward_word (count, key);
1438   w2_end = rl_point;
1439   rl_backward_word (1, key);
1440   w2_beg = rl_point;
1441   rl_backward_word (count, key);
1442   w1_beg = rl_point;
1443   rl_forward_word (1, key);
1444   w1_end = rl_point;
1445
1446   /* Do some check to make sure that there really are two words. */
1447   if ((w1_beg == w2_beg) || (w2_beg < w1_end))
1448     {
1449       rl_ding ();
1450       rl_point = orig_point;
1451       return 1;
1452     }
1453
1454   /* Get the text of the words. */
1455   word1 = rl_copy_text (w1_beg, w1_end);
1456   word2 = rl_copy_text (w2_beg, w2_end);
1457
1458   /* We are about to do many insertions and deletions.  Remember them
1459      as one operation. */
1460   rl_begin_undo_group ();
1461
1462   /* Do the stuff at word2 first, so that we don't have to worry
1463      about word1 moving. */
1464   rl_point = w2_beg;
1465   rl_delete_text (w2_beg, w2_end);
1466   rl_insert_text (word1);
1467
1468   rl_point = w1_beg;
1469   rl_delete_text (w1_beg, w1_end);
1470   rl_insert_text (word2);
1471
1472   /* This is exactly correct since the text before this point has not
1473      changed in length. */
1474   rl_point = w2_end;
1475
1476   /* I think that does it. */
1477   rl_end_undo_group ();
1478   xfree (word1);
1479   xfree (word2);
1480
1481   return 0;
1482 }
1483
1484 /* Transpose the characters at point.  If point is at the end of the line,
1485    then transpose the characters before point. */
1486 int
1487 rl_transpose_chars (count, key)
1488      int count, key;
1489 {
1490 #if defined (HANDLE_MULTIBYTE)
1491   char *dummy;
1492   int i;
1493 #else
1494   char dummy[2];
1495 #endif
1496   int char_length, prev_point;
1497
1498   if (count == 0)
1499     return 0;
1500
1501   if (!rl_point || rl_end < 2)
1502     {
1503       rl_ding ();
1504       return 1;
1505     }
1506
1507   rl_begin_undo_group ();
1508
1509   if (rl_point == rl_end)
1510     {
1511       rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1512       count = 1;
1513     }
1514
1515   prev_point = rl_point;
1516   rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1517
1518 #if defined (HANDLE_MULTIBYTE)
1519   char_length = prev_point - rl_point;
1520   dummy = (char *)xmalloc (char_length + 1);
1521   for (i = 0; i < char_length; i++)
1522     dummy[i] = rl_line_buffer[rl_point + i];
1523   dummy[i] = '\0';
1524 #else
1525   dummy[0] = rl_line_buffer[rl_point];
1526   dummy[char_length = 1] = '\0';
1527 #endif
1528
1529   rl_delete_text (rl_point, rl_point + char_length);
1530
1531   rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1532
1533   _rl_fix_point (0);
1534   rl_insert_text (dummy);
1535   rl_end_undo_group ();
1536
1537 #if defined (HANDLE_MULTIBYTE)
1538   xfree (dummy);
1539 #endif
1540
1541   return 0;
1542 }
1543
1544 /* **************************************************************** */
1545 /*                                                                  */
1546 /*                      Character Searching                         */
1547 /*                                                                  */
1548 /* **************************************************************** */
1549
1550 int
1551 #if defined (HANDLE_MULTIBYTE)
1552 _rl_char_search_internal (count, dir, smbchar, len)
1553      int count, dir;
1554      char *smbchar;
1555      int len;
1556 #else
1557 _rl_char_search_internal (count, dir, schar)
1558      int count, dir, schar;
1559 #endif
1560 {
1561   int pos, inc;
1562 #if defined (HANDLE_MULTIBYTE)
1563   int prepos;
1564 #endif
1565
1566   if (dir == 0)
1567     return 1;
1568
1569   pos = rl_point;
1570   inc = (dir < 0) ? -1 : 1;
1571   while (count)
1572     {
1573       if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
1574         {
1575           rl_ding ();
1576           return 1;
1577         }
1578
1579 #if defined (HANDLE_MULTIBYTE)
1580       pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1581                       : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
1582 #else
1583       pos += inc;
1584 #endif
1585       do
1586         {
1587 #if defined (HANDLE_MULTIBYTE)
1588           if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
1589 #else
1590           if (rl_line_buffer[pos] == schar)
1591 #endif
1592             {
1593               count--;
1594               if (dir < 0)
1595                 rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
1596                                         : pos;
1597               else
1598                 rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
1599                                         : pos;
1600               break;
1601             }
1602 #if defined (HANDLE_MULTIBYTE)
1603           prepos = pos;
1604 #endif
1605         }
1606 #if defined (HANDLE_MULTIBYTE)
1607       while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
1608                        : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
1609 #else
1610       while ((dir < 0) ? pos-- : ++pos < rl_end);
1611 #endif
1612     }
1613   return (0);
1614 }
1615
1616 /* Search COUNT times for a character read from the current input stream.
1617    FDIR is the direction to search if COUNT is non-negative; otherwise
1618    the search goes in BDIR.  So much is dependent on HANDLE_MULTIBYTE
1619    that there are two separate versions of this function. */
1620 #if defined (HANDLE_MULTIBYTE)
1621 static int
1622 _rl_char_search (count, fdir, bdir)
1623      int count, fdir, bdir;
1624 {
1625   char mbchar[MB_LEN_MAX];
1626   int mb_len;
1627
1628   mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
1629
1630   if (mb_len <= 0)
1631     return 1;
1632
1633   if (count < 0)
1634     return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
1635   else
1636     return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
1637 }
1638 #else /* !HANDLE_MULTIBYTE */
1639 static int
1640 _rl_char_search (count, fdir, bdir)
1641      int count, fdir, bdir;
1642 {
1643   int c;
1644
1645   RL_SETSTATE(RL_STATE_MOREINPUT);
1646   c = rl_read_key ();
1647   RL_UNSETSTATE(RL_STATE_MOREINPUT);
1648
1649   if (c < 0)
1650     return 1;
1651
1652   if (count < 0)
1653     return (_rl_char_search_internal (-count, bdir, c));
1654   else
1655     return (_rl_char_search_internal (count, fdir, c));
1656 }
1657 #endif /* !HANDLE_MULTIBYTE */
1658
1659 #if defined (READLINE_CALLBACKS)
1660 static int
1661 _rl_char_search_callback (data)
1662      _rl_callback_generic_arg *data;
1663 {
1664   _rl_callback_func = 0;
1665   _rl_want_redisplay = 1;
1666
1667   return (_rl_char_search (data->count, data->i1, data->i2));
1668 }
1669 #endif
1670
1671 int
1672 rl_char_search (count, key)
1673      int count, key;
1674 {
1675 #if defined (READLINE_CALLBACKS)
1676   if (RL_ISSTATE (RL_STATE_CALLBACK))
1677     {
1678       _rl_callback_data = _rl_callback_data_alloc (count);
1679       _rl_callback_data->i1 = FFIND;
1680       _rl_callback_data->i2 = BFIND;
1681       _rl_callback_func = _rl_char_search_callback;
1682       return (0);
1683     }
1684 #endif
1685   
1686   return (_rl_char_search (count, FFIND, BFIND));
1687 }
1688
1689 int
1690 rl_backward_char_search (count, key)
1691      int count, key;
1692 {
1693 #if defined (READLINE_CALLBACKS)
1694   if (RL_ISSTATE (RL_STATE_CALLBACK))
1695     {
1696       _rl_callback_data = _rl_callback_data_alloc (count);
1697       _rl_callback_data->i1 = BFIND;
1698       _rl_callback_data->i2 = FFIND;
1699       _rl_callback_func = _rl_char_search_callback;
1700       return (0);
1701     }
1702 #endif
1703
1704   return (_rl_char_search (count, BFIND, FFIND));
1705 }
1706
1707 /* **************************************************************** */
1708 /*                                                                  */
1709 /*                 The Mark and the Region.                         */
1710 /*                                                                  */
1711 /* **************************************************************** */
1712
1713 /* Set the mark at POSITION. */
1714 int
1715 _rl_set_mark_at_pos (position)
1716      int position;
1717 {
1718   if (position > rl_end)
1719     return 1;
1720
1721   rl_mark = position;
1722   return 0;
1723 }
1724
1725 /* A bindable command to set the mark. */
1726 int
1727 rl_set_mark (count, key)
1728      int count, key;
1729 {
1730   return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
1731 }
1732
1733 /* Exchange the position of mark and point. */
1734 int
1735 rl_exchange_point_and_mark (count, key)
1736      int count, key;
1737 {
1738   if (rl_mark > rl_end)
1739     rl_mark = -1;
1740
1741   if (rl_mark == -1)
1742     {
1743       rl_ding ();
1744       return 1;
1745     }
1746   else
1747     SWAP (rl_point, rl_mark);
1748
1749   return 0;
1750 }