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