OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [readline/] [text.c] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.