Annotation of embedaddon/readline/text.c, revision 1.1.1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>