Annotation of embedaddon/readline/bind.c, revision 1.1

1.1     ! misho       1: /* bind.c -- key binding and startup file support for the readline library. */
        !             2: 
        !             3: /* Copyright (C) 1987-2012 Free Software Foundation, Inc.
        !             4: 
        !             5:    This file is part of the GNU Readline Library (Readline), a library
        !             6:    for reading lines of text with interactive input and history editing.
        !             7: 
        !             8:    Readline is free software: you can redistribute it and/or modify
        !             9:    it under the terms of the GNU General Public License as published by
        !            10:    the Free Software Foundation, either version 3 of the License, or
        !            11:    (at your option) any later version.
        !            12: 
        !            13:    Readline is distributed in the hope that it will be useful,
        !            14:    but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            16:    GNU General Public License for more details.
        !            17: 
        !            18:    You should have received a copy of the GNU General Public License
        !            19:    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
        !            20: */
        !            21: 
        !            22: #define READLINE_LIBRARY
        !            23: 
        !            24: #if defined (__TANDEM)
        !            25: #  include <floss.h>
        !            26: #endif
        !            27: 
        !            28: #if defined (HAVE_CONFIG_H)
        !            29: #  include <config.h>
        !            30: #endif
        !            31: 
        !            32: #include <stdio.h>
        !            33: #include <sys/types.h>
        !            34: #include <fcntl.h>
        !            35: #if defined (HAVE_SYS_FILE_H)
        !            36: #  include <sys/file.h>
        !            37: #endif /* HAVE_SYS_FILE_H */
        !            38: 
        !            39: #if defined (HAVE_UNISTD_H)
        !            40: #  include <unistd.h>
        !            41: #endif /* HAVE_UNISTD_H */
        !            42: 
        !            43: #if defined (HAVE_STDLIB_H)
        !            44: #  include <stdlib.h>
        !            45: #else
        !            46: #  include "ansi_stdlib.h"
        !            47: #endif /* HAVE_STDLIB_H */
        !            48: 
        !            49: #include <errno.h>
        !            50: 
        !            51: #if !defined (errno)
        !            52: extern int errno;
        !            53: #endif /* !errno */
        !            54: 
        !            55: #include "posixstat.h"
        !            56: 
        !            57: /* System-specific feature definitions and include files. */
        !            58: #include "rldefs.h"
        !            59: 
        !            60: /* Some standard library routines. */
        !            61: #include "readline.h"
        !            62: #include "history.h"
        !            63: 
        !            64: #include "rlprivate.h"
        !            65: #include "rlshell.h"
        !            66: #include "xmalloc.h"
        !            67: 
        !            68: #if !defined (strchr) && !defined (__STDC__)
        !            69: extern char *strchr (), *strrchr ();
        !            70: #endif /* !strchr && !__STDC__ */
        !            71: 
        !            72: /* Variables exported by this file. */
        !            73: Keymap rl_binding_keymap;
        !            74: 
        !            75: static int _rl_skip_to_delim PARAMS((char *, int, int));
        !            76: 
        !            77: static char *_rl_read_file PARAMS((char *, size_t *));
        !            78: static void _rl_init_file_error PARAMS((const char *));
        !            79: static int _rl_read_init_file PARAMS((const char *, int));
        !            80: static int glean_key_from_name PARAMS((char *));
        !            81: 
        !            82: static int find_boolean_var PARAMS((const char *));
        !            83: static int find_string_var PARAMS((const char *));
        !            84: 
        !            85: static char *_rl_get_string_variable_value PARAMS((const char *));
        !            86: static int substring_member_of_array PARAMS((const char *, const char * const *));
        !            87: 
        !            88: static int currently_reading_init_file;
        !            89: 
        !            90: /* used only in this file */
        !            91: static int _rl_prefer_visible_bell = 1;
        !            92: 
        !            93: /* **************************************************************** */
        !            94: /*                                                                 */
        !            95: /*                     Binding keys                                */
        !            96: /*                                                                 */
        !            97: /* **************************************************************** */
        !            98: 
        !            99: /* rl_add_defun (char *name, rl_command_func_t *function, int key)
        !           100:    Add NAME to the list of named functions.  Make FUNCTION be the function
        !           101:    that gets called.  If KEY is not -1, then bind it. */
        !           102: int
        !           103: rl_add_defun (name, function, key)
        !           104:      const char *name;
        !           105:      rl_command_func_t *function;
        !           106:      int key;
        !           107: {
        !           108:   if (key != -1)
        !           109:     rl_bind_key (key, function);
        !           110:   rl_add_funmap_entry (name, function);
        !           111:   return 0;
        !           112: }
        !           113: 
        !           114: /* Bind KEY to FUNCTION.  Returns non-zero if KEY is out of range. */
        !           115: int
        !           116: rl_bind_key (key, function)
        !           117:      int key;
        !           118:      rl_command_func_t *function;
        !           119: {
        !           120:   if (key < 0)
        !           121:     return (key);
        !           122: 
        !           123:   if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
        !           124:     {
        !           125:       if (_rl_keymap[ESC].type == ISKMAP)
        !           126:        {
        !           127:          Keymap escmap;
        !           128: 
        !           129:          escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC);
        !           130:          key = UNMETA (key);
        !           131:          escmap[key].type = ISFUNC;
        !           132:          escmap[key].function = function;
        !           133:          return (0);
        !           134:        }
        !           135:       return (key);
        !           136:     }
        !           137: 
        !           138:   _rl_keymap[key].type = ISFUNC;
        !           139:   _rl_keymap[key].function = function;
        !           140:   rl_binding_keymap = _rl_keymap;
        !           141:   return (0);
        !           142: }
        !           143: 
        !           144: /* Bind KEY to FUNCTION in MAP.  Returns non-zero in case of invalid
        !           145:    KEY. */
        !           146: int
        !           147: rl_bind_key_in_map (key, function, map)
        !           148:      int key;
        !           149:      rl_command_func_t *function;
        !           150:      Keymap map;
        !           151: {
        !           152:   int result;
        !           153:   Keymap oldmap;
        !           154: 
        !           155:   oldmap = _rl_keymap;
        !           156:   _rl_keymap = map;
        !           157:   result = rl_bind_key (key, function);
        !           158:   _rl_keymap = oldmap;
        !           159:   return (result);
        !           160: }
        !           161: 
        !           162: /* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound.  Right
        !           163:    now, this is always used to attempt to bind the arrow keys, hence the
        !           164:    check for rl_vi_movement_mode. */
        !           165: int
        !           166: rl_bind_key_if_unbound_in_map (key, default_func, kmap)
        !           167:      int key;
        !           168:      rl_command_func_t *default_func;
        !           169:      Keymap kmap;
        !           170: {
        !           171:   char keyseq[2];
        !           172: 
        !           173:   keyseq[0] = (unsigned char)key;
        !           174:   keyseq[1] = '\0';
        !           175:   return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap));
        !           176: }
        !           177: 
        !           178: int
        !           179: rl_bind_key_if_unbound (key, default_func)
        !           180:      int key;
        !           181:      rl_command_func_t *default_func;
        !           182: {
        !           183:   char keyseq[2];
        !           184: 
        !           185:   keyseq[0] = (unsigned char)key;
        !           186:   keyseq[1] = '\0';
        !           187:   return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
        !           188: }
        !           189: 
        !           190: /* Make KEY do nothing in the currently selected keymap.
        !           191:    Returns non-zero in case of error. */
        !           192: int
        !           193: rl_unbind_key (key)
        !           194:      int key;
        !           195: {
        !           196:   return (rl_bind_key (key, (rl_command_func_t *)NULL));
        !           197: }
        !           198: 
        !           199: /* Make KEY do nothing in MAP.
        !           200:    Returns non-zero in case of error. */
        !           201: int
        !           202: rl_unbind_key_in_map (key, map)
        !           203:      int key;
        !           204:      Keymap map;
        !           205: {
        !           206:   return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map));
        !           207: }
        !           208: 
        !           209: /* Unbind all keys bound to FUNCTION in MAP. */
        !           210: int
        !           211: rl_unbind_function_in_map (func, map)
        !           212:      rl_command_func_t *func;
        !           213:      Keymap map;
        !           214: {
        !           215:   register int i, rval;
        !           216: 
        !           217:   for (i = rval = 0; i < KEYMAP_SIZE; i++)
        !           218:     {
        !           219:       if (map[i].type == ISFUNC && map[i].function == func)
        !           220:        {
        !           221:          map[i].function = (rl_command_func_t *)NULL;
        !           222:          rval = 1;
        !           223:        }
        !           224:     }
        !           225:   return rval;
        !           226: }
        !           227: 
        !           228: int
        !           229: rl_unbind_command_in_map (command, map)
        !           230:      const char *command;
        !           231:      Keymap map;
        !           232: {
        !           233:   rl_command_func_t *func;
        !           234: 
        !           235:   func = rl_named_function (command);
        !           236:   if (func == 0)
        !           237:     return 0;
        !           238:   return (rl_unbind_function_in_map (func, map));
        !           239: }
        !           240: 
        !           241: /* Bind the key sequence represented by the string KEYSEQ to
        !           242:    FUNCTION, starting in the current keymap.  This makes new
        !           243:    keymaps as necessary. */
        !           244: int
        !           245: rl_bind_keyseq (keyseq, function)
        !           246:      const char *keyseq;
        !           247:      rl_command_func_t *function;
        !           248: {
        !           249:   return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap));
        !           250: }
        !           251: 
        !           252: /* Bind the key sequence represented by the string KEYSEQ to
        !           253:    FUNCTION.  This makes new keymaps as necessary.  The initial
        !           254:    place to do bindings is in MAP. */
        !           255: int
        !           256: rl_bind_keyseq_in_map (keyseq, function, map)
        !           257:      const char *keyseq;
        !           258:      rl_command_func_t *function;
        !           259:      Keymap map;
        !           260: {
        !           261:   return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
        !           262: }
        !           263: 
        !           264: /* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */
        !           265: int
        !           266: rl_set_key (keyseq, function, map)
        !           267:      const char *keyseq;
        !           268:      rl_command_func_t *function;
        !           269:      Keymap map;
        !           270: {
        !           271:   return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
        !           272: }
        !           273: 
        !           274: /* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound.  Right
        !           275:    now, this is always used to attempt to bind the arrow keys, hence the
        !           276:    check for rl_vi_movement_mode. */
        !           277: int
        !           278: rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)
        !           279:      const char *keyseq;
        !           280:      rl_command_func_t *default_func;
        !           281:      Keymap kmap;
        !           282: {
        !           283:   rl_command_func_t *func;
        !           284: 
        !           285:   if (keyseq)
        !           286:     {
        !           287:       func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL);
        !           288: #if defined (VI_MODE)
        !           289:       if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
        !           290: #else
        !           291:       if (!func || func == rl_do_lowercase_version)
        !           292: #endif
        !           293:        return (rl_bind_keyseq_in_map (keyseq, default_func, kmap));
        !           294:       else
        !           295:        return 1;
        !           296:     }
        !           297:   return 0;
        !           298: }
        !           299: 
        !           300: int
        !           301: rl_bind_keyseq_if_unbound (keyseq, default_func)
        !           302:      const char *keyseq;
        !           303:      rl_command_func_t *default_func;
        !           304: {
        !           305:   return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
        !           306: }
        !           307: 
        !           308: /* Bind the key sequence represented by the string KEYSEQ to
        !           309:    the string of characters MACRO.  This makes new keymaps as
        !           310:    necessary.  The initial place to do bindings is in MAP. */
        !           311: int
        !           312: rl_macro_bind (keyseq, macro, map)
        !           313:      const char *keyseq, *macro;
        !           314:      Keymap map;
        !           315: {
        !           316:   char *macro_keys;
        !           317:   int macro_keys_len;
        !           318: 
        !           319:   macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1);
        !           320: 
        !           321:   if (rl_translate_keyseq (macro, macro_keys, &macro_keys_len))
        !           322:     {
        !           323:       xfree (macro_keys);
        !           324:       return -1;
        !           325:     }
        !           326:   rl_generic_bind (ISMACR, keyseq, macro_keys, map);
        !           327:   return 0;
        !           328: }
        !           329: 
        !           330: /* Bind the key sequence represented by the string KEYSEQ to
        !           331:    the arbitrary pointer DATA.  TYPE says what kind of data is
        !           332:    pointed to by DATA, right now this can be a function (ISFUNC),
        !           333:    a macro (ISMACR), or a keymap (ISKMAP).  This makes new keymaps
        !           334:    as necessary.  The initial place to do bindings is in MAP. */
        !           335: int
        !           336: rl_generic_bind (type, keyseq, data, map)
        !           337:      int type;
        !           338:      const char *keyseq;
        !           339:      char *data;
        !           340:      Keymap map;
        !           341: {
        !           342:   char *keys;
        !           343:   int keys_len;
        !           344:   register int i;
        !           345:   KEYMAP_ENTRY k;
        !           346: 
        !           347:   k.function = 0;
        !           348: 
        !           349:   /* If no keys to bind to, exit right away. */
        !           350:   if (keyseq == 0 || *keyseq == 0)
        !           351:     {
        !           352:       if (type == ISMACR)
        !           353:        xfree (data);
        !           354:       return -1;
        !           355:     }
        !           356: 
        !           357:   keys = (char *)xmalloc (1 + (2 * strlen (keyseq)));
        !           358: 
        !           359:   /* Translate the ASCII representation of KEYSEQ into an array of
        !           360:      characters.  Stuff the characters into KEYS, and the length of
        !           361:      KEYS into KEYS_LEN. */
        !           362:   if (rl_translate_keyseq (keyseq, keys, &keys_len))
        !           363:     {
        !           364:       xfree (keys);
        !           365:       return -1;
        !           366:     }
        !           367: 
        !           368:   /* Bind keys, making new keymaps as necessary. */
        !           369:   for (i = 0; i < keys_len; i++)
        !           370:     {
        !           371:       unsigned char uc = keys[i];
        !           372:       int ic;
        !           373: 
        !           374:       ic = uc;
        !           375:       if (ic < 0 || ic >= KEYMAP_SIZE)
        !           376:         {
        !           377:           xfree (keys);
        !           378:          return -1;
        !           379:         }
        !           380: 
        !           381:       if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
        !           382:        {
        !           383:          ic = UNMETA (ic);
        !           384:          if (map[ESC].type == ISKMAP)
        !           385:            map = FUNCTION_TO_KEYMAP (map, ESC);
        !           386:        }
        !           387: 
        !           388:       if ((i + 1) < keys_len)
        !           389:        {
        !           390:          if (map[ic].type != ISKMAP)
        !           391:            {
        !           392:              /* We allow subsequences of keys.  If a keymap is being
        !           393:                 created that will `shadow' an existing function or macro
        !           394:                 key binding, we save that keybinding into the ANYOTHERKEY
        !           395:                 index in the new map.  The dispatch code will look there
        !           396:                 to find the function to execute if the subsequence is not
        !           397:                 matched.  ANYOTHERKEY was chosen to be greater than
        !           398:                 UCHAR_MAX. */
        !           399:              k = map[ic];
        !           400: 
        !           401:              map[ic].type = ISKMAP;
        !           402:              map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
        !           403:            }
        !           404:          map = FUNCTION_TO_KEYMAP (map, ic);
        !           405:          /* The dispatch code will return this function if no matching
        !           406:             key sequence is found in the keymap.  This (with a little
        !           407:             help from the dispatch code in readline.c) allows `a' to be
        !           408:             mapped to something, `abc' to be mapped to something else,
        !           409:             and the function bound  to `a' to be executed when the user
        !           410:             types `abx', leaving `bx' in the input queue. */
        !           411:          if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR))
        !           412:            {
        !           413:              map[ANYOTHERKEY] = k;
        !           414:              k.function = 0;
        !           415:            }
        !           416:        }
        !           417:       else
        !           418:        {
        !           419:          if (map[ic].type == ISMACR)
        !           420:            xfree ((char *)map[ic].function);
        !           421:          else if (map[ic].type == ISKMAP)
        !           422:            {
        !           423:              map = FUNCTION_TO_KEYMAP (map, ic);
        !           424:              ic = ANYOTHERKEY;
        !           425:              /* If we're trying to override a keymap with a null function
        !           426:                 (e.g., trying to unbind it), we can't use a null pointer
        !           427:                 here because that's indistinguishable from having not been
        !           428:                 overridden.  We use a special bindable function that does
        !           429:                 nothing. */
        !           430:              if (type == ISFUNC && data == 0)
        !           431:                data = (char *)_rl_null_function;
        !           432:            }
        !           433: 
        !           434:          map[ic].function = KEYMAP_TO_FUNCTION (data);
        !           435:          map[ic].type = type;
        !           436:        }
        !           437: 
        !           438:       rl_binding_keymap = map;
        !           439:     }
        !           440:   xfree (keys);
        !           441:   return 0;
        !           442: }
        !           443: 
        !           444: /* Translate the ASCII representation of SEQ, stuffing the values into ARRAY,
        !           445:    an array of characters.  LEN gets the final length of ARRAY.  Return
        !           446:    non-zero if there was an error parsing SEQ. */
        !           447: int
        !           448: rl_translate_keyseq (seq, array, len)
        !           449:      const char *seq;
        !           450:      char *array;
        !           451:      int *len;
        !           452: {
        !           453:   register int i, c, l, temp;
        !           454: 
        !           455:   for (i = l = 0; c = seq[i]; i++)
        !           456:     {
        !           457:       if (c == '\\')
        !           458:        {
        !           459:          c = seq[++i];
        !           460: 
        !           461:          if (c == 0)
        !           462:            break;
        !           463: 
        !           464:          /* Handle \C- and \M- prefixes. */
        !           465:          if ((c == 'C' || c == 'M') && seq[i + 1] == '-')
        !           466:            {
        !           467:              /* Handle special case of backwards define. */
        !           468:              if (strncmp (&seq[i], "C-\\M-", 5) == 0)
        !           469:                {
        !           470:                  array[l++] = ESC;     /* ESC is meta-prefix */
        !           471:                  i += 5;
        !           472:                  array[l++] = CTRL (_rl_to_upper (seq[i]));
        !           473:                  if (seq[i] == '\0')
        !           474:                    i--;
        !           475:                }
        !           476:              else if (c == 'M')
        !           477:                {
        !           478:                  i++;          /* seq[i] == '-' */
        !           479:                  /* XXX - obey convert-meta setting */
        !           480:                  if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP)
        !           481:                    array[l++] = ESC;   /* ESC is meta-prefix */
        !           482:                  else if (seq[i+1] == '\\' && seq[i+2] == 'C' && seq[i+3] == '-')
        !           483:                    {
        !           484:                      i += 4;
        !           485:                      temp = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
        !           486:                      array[l++] = META (temp);
        !           487:                    }
        !           488:                  else
        !           489:                    {
        !           490:                      /* This doesn't yet handle things like \M-\a, which may
        !           491:                         or may not have any reasonable meaning.  You're
        !           492:                         probably better off using straight octal or hex. */
        !           493:                      i++;
        !           494:                      array[l++] = META (seq[i]);
        !           495:                    }
        !           496:                }
        !           497:              else if (c == 'C')
        !           498:                {
        !           499:                  i += 2;
        !           500:                  /* Special hack for C-?... */
        !           501:                  array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
        !           502:                }
        !           503:              continue;
        !           504:            }         
        !           505: 
        !           506:          /* Translate other backslash-escaped characters.  These are the
        !           507:             same escape sequences that bash's `echo' and `printf' builtins
        !           508:             handle, with the addition of \d -> RUBOUT.  A backslash
        !           509:             preceding a character that is not special is stripped. */
        !           510:          switch (c)
        !           511:            {
        !           512:            case 'a':
        !           513:              array[l++] = '\007';
        !           514:              break;
        !           515:            case 'b':
        !           516:              array[l++] = '\b';
        !           517:              break;
        !           518:            case 'd':
        !           519:              array[l++] = RUBOUT;      /* readline-specific */
        !           520:              break;
        !           521:            case 'e':
        !           522:              array[l++] = ESC;
        !           523:              break;
        !           524:            case 'f':
        !           525:              array[l++] = '\f';
        !           526:              break;
        !           527:            case 'n':
        !           528:              array[l++] = NEWLINE;
        !           529:              break;
        !           530:            case 'r':
        !           531:              array[l++] = RETURN;
        !           532:              break;
        !           533:            case 't':
        !           534:              array[l++] = TAB;
        !           535:              break;
        !           536:            case 'v':
        !           537:              array[l++] = 0x0B;
        !           538:              break;
        !           539:            case '\\':
        !           540:              array[l++] = '\\';
        !           541:              break;
        !           542:            case '0': case '1': case '2': case '3':
        !           543:            case '4': case '5': case '6': case '7':
        !           544:              i++;
        !           545:              for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++)
        !           546:                c = (c * 8) + OCTVALUE (seq[i]);
        !           547:              i--;      /* auto-increment in for loop */
        !           548:              array[l++] = c & largest_char;
        !           549:              break;
        !           550:            case 'x':
        !           551:              i++;
        !           552:              for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++)
        !           553:                c = (c * 16) + HEXVALUE (seq[i]);
        !           554:              if (temp == 2)
        !           555:                c = 'x';
        !           556:              i--;      /* auto-increment in for loop */
        !           557:              array[l++] = c & largest_char;
        !           558:              break;
        !           559:            default:    /* backslashes before non-special chars just add the char */
        !           560:              array[l++] = c;
        !           561:              break;    /* the backslash is stripped */
        !           562:            }
        !           563:          continue;
        !           564:        }
        !           565: 
        !           566:       array[l++] = c;
        !           567:     }
        !           568: 
        !           569:   *len = l;
        !           570:   array[l] = '\0';
        !           571:   return (0);
        !           572: }
        !           573: 
        !           574: static int
        !           575: _rl_isescape (c)
        !           576:      int c;
        !           577: {
        !           578:   switch (c)
        !           579:     {
        !           580:     case '\007':
        !           581:     case '\b':
        !           582:     case '\f':
        !           583:     case '\n':
        !           584:     case '\r':
        !           585:     case TAB:
        !           586:     case 0x0b:  return (1);
        !           587:     default: return (0);
        !           588:     }
        !           589: }
        !           590: 
        !           591: static int
        !           592: _rl_escchar (c)
        !           593:      int c;
        !           594: {
        !           595:   switch (c)
        !           596:     {
        !           597:     case '\007':  return ('a');
        !           598:     case '\b':  return ('b');
        !           599:     case '\f':  return ('f');
        !           600:     case '\n':  return ('n');
        !           601:     case '\r':  return ('r');
        !           602:     case TAB:  return ('t');
        !           603:     case 0x0b:  return ('v');
        !           604:     default: return (c);
        !           605:     }
        !           606: }
        !           607: 
        !           608: char *
        !           609: rl_untranslate_keyseq (seq)
        !           610:      int seq;
        !           611: {
        !           612:   static char kseq[16];
        !           613:   int i, c;
        !           614: 
        !           615:   i = 0;
        !           616:   c = seq;
        !           617:   if (META_CHAR (c))
        !           618:     {
        !           619:       kseq[i++] = '\\';
        !           620:       kseq[i++] = 'M';
        !           621:       kseq[i++] = '-';
        !           622:       c = UNMETA (c);
        !           623:     }
        !           624:   else if (c == ESC)
        !           625:     {
        !           626:       kseq[i++] = '\\';
        !           627:       c = 'e';
        !           628:     }
        !           629:   else if (CTRL_CHAR (c))
        !           630:     {
        !           631:       kseq[i++] = '\\';
        !           632:       kseq[i++] = 'C';
        !           633:       kseq[i++] = '-';
        !           634:       c = _rl_to_lower (UNCTRL (c));
        !           635:     }
        !           636:   else if (c == RUBOUT)
        !           637:     {
        !           638:       kseq[i++] = '\\';
        !           639:       kseq[i++] = 'C';
        !           640:       kseq[i++] = '-';
        !           641:       c = '?';
        !           642:     }
        !           643: 
        !           644:   if (c == ESC)
        !           645:     {
        !           646:       kseq[i++] = '\\';
        !           647:       c = 'e';
        !           648:     }
        !           649:   else if (c == '\\' || c == '"')
        !           650:     {
        !           651:       kseq[i++] = '\\';
        !           652:     }
        !           653: 
        !           654:   kseq[i++] = (unsigned char) c;
        !           655:   kseq[i] = '\0';
        !           656:   return kseq;
        !           657: }
        !           658: 
        !           659: char *
        !           660: _rl_untranslate_macro_value (seq, use_escapes)
        !           661:      char *seq;
        !           662:      int use_escapes;
        !           663: {
        !           664:   char *ret, *r, *s;
        !           665:   int c;
        !           666: 
        !           667:   r = ret = (char *)xmalloc (7 * strlen (seq) + 1);
        !           668:   for (s = seq; *s; s++)
        !           669:     {
        !           670:       c = *s;
        !           671:       if (META_CHAR (c))
        !           672:        {
        !           673:          *r++ = '\\';
        !           674:          *r++ = 'M';
        !           675:          *r++ = '-';
        !           676:          c = UNMETA (c);
        !           677:        }
        !           678:       else if (c == ESC)
        !           679:        {
        !           680:          *r++ = '\\';
        !           681:          c = 'e';
        !           682:        }
        !           683:       else if (CTRL_CHAR (c))
        !           684:        {
        !           685:          *r++ = '\\';
        !           686:          if (use_escapes && _rl_isescape (c))
        !           687:            c = _rl_escchar (c);
        !           688:          else
        !           689:            {
        !           690:              *r++ = 'C';
        !           691:              *r++ = '-';
        !           692:              c = _rl_to_lower (UNCTRL (c));
        !           693:            }
        !           694:        }
        !           695:       else if (c == RUBOUT)
        !           696:        {
        !           697:          *r++ = '\\';
        !           698:          *r++ = 'C';
        !           699:          *r++ = '-';
        !           700:          c = '?';
        !           701:        }
        !           702: 
        !           703:       if (c == ESC)
        !           704:        {
        !           705:          *r++ = '\\';
        !           706:          c = 'e';
        !           707:        }
        !           708:       else if (c == '\\' || c == '"')
        !           709:        *r++ = '\\';
        !           710: 
        !           711:       *r++ = (unsigned char)c;
        !           712:     }
        !           713:   *r = '\0';
        !           714:   return ret;
        !           715: }
        !           716: 
        !           717: /* Return a pointer to the function that STRING represents.
        !           718:    If STRING doesn't have a matching function, then a NULL pointer
        !           719:    is returned. */
        !           720: rl_command_func_t *
        !           721: rl_named_function (string)
        !           722:      const char *string;
        !           723: {
        !           724:   register int i;
        !           725: 
        !           726:   rl_initialize_funmap ();
        !           727: 
        !           728:   for (i = 0; funmap[i]; i++)
        !           729:     if (_rl_stricmp (funmap[i]->name, string) == 0)
        !           730:       return (funmap[i]->function);
        !           731:   return ((rl_command_func_t *)NULL);
        !           732: }
        !           733: 
        !           734: /* Return the function (or macro) definition which would be invoked via
        !           735:    KEYSEQ if executed in MAP.  If MAP is NULL, then the current keymap is
        !           736:    used.  TYPE, if non-NULL, is a pointer to an int which will receive the
        !           737:    type of the object pointed to.  One of ISFUNC (function), ISKMAP (keymap),
        !           738:    or ISMACR (macro). */
        !           739: rl_command_func_t *
        !           740: rl_function_of_keyseq (keyseq, map, type)
        !           741:      const char *keyseq;
        !           742:      Keymap map;
        !           743:      int *type;
        !           744: {
        !           745:   register int i;
        !           746: 
        !           747:   if (map == 0)
        !           748:     map = _rl_keymap;
        !           749: 
        !           750:   for (i = 0; keyseq && keyseq[i]; i++)
        !           751:     {
        !           752:       unsigned char ic = keyseq[i];
        !           753: 
        !           754:       if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
        !           755:        {
        !           756:          if (map[ESC].type == ISKMAP)
        !           757:            {
        !           758:              map = FUNCTION_TO_KEYMAP (map, ESC);
        !           759:              ic = UNMETA (ic);
        !           760:            }
        !           761:          /* XXX - should we just return NULL here, since this obviously
        !           762:             doesn't match? */
        !           763:          else
        !           764:            {
        !           765:              if (type)
        !           766:                *type = map[ESC].type;
        !           767: 
        !           768:              return (map[ESC].function);
        !           769:            }
        !           770:        }
        !           771: 
        !           772:       if (map[ic].type == ISKMAP)
        !           773:        {
        !           774:          /* If this is the last key in the key sequence, return the
        !           775:             map. */
        !           776:          if (keyseq[i + 1] == '\0')
        !           777:            {
        !           778:              if (type)
        !           779:                *type = ISKMAP;
        !           780: 
        !           781:              return (map[ic].function);
        !           782:            }
        !           783:          else
        !           784:            map = FUNCTION_TO_KEYMAP (map, ic);
        !           785:        }
        !           786:       /* If we're not at the end of the key sequence, and the current key
        !           787:         is bound to something other than a keymap, then the entire key
        !           788:         sequence is not bound. */
        !           789:       else if (map[ic].type != ISKMAP && keyseq[i+1])
        !           790:        return ((rl_command_func_t *)NULL);
        !           791:       else     /* map[ic].type != ISKMAP && keyseq[i+1] == 0 */
        !           792:        {
        !           793:          if (type)
        !           794:            *type = map[ic].type;
        !           795: 
        !           796:          return (map[ic].function);
        !           797:        }
        !           798:     }
        !           799:   return ((rl_command_func_t *) NULL);
        !           800: }
        !           801: 
        !           802: /* The last key bindings file read. */
        !           803: static char *last_readline_init_file = (char *)NULL;
        !           804: 
        !           805: /* The file we're currently reading key bindings from. */
        !           806: static const char *current_readline_init_file;
        !           807: static int current_readline_init_include_level;
        !           808: static int current_readline_init_lineno;
        !           809: 
        !           810: /* Read FILENAME into a locally-allocated buffer and return the buffer.
        !           811:    The size of the buffer is returned in *SIZEP.  Returns NULL if any
        !           812:    errors were encountered. */
        !           813: static char *
        !           814: _rl_read_file (filename, sizep)
        !           815:      char *filename;
        !           816:      size_t *sizep;
        !           817: {
        !           818:   struct stat finfo;
        !           819:   size_t file_size;
        !           820:   char *buffer;
        !           821:   int i, file;
        !           822: 
        !           823:   if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0)
        !           824:     return ((char *)NULL);
        !           825: 
        !           826:   file_size = (size_t)finfo.st_size;
        !           827: 
        !           828:   /* check for overflow on very large files */
        !           829:   if (file_size != finfo.st_size || file_size + 1 < file_size)
        !           830:     {
        !           831:       if (file >= 0)
        !           832:        close (file);
        !           833: #if defined (EFBIG)
        !           834:       errno = EFBIG;
        !           835: #endif
        !           836:       return ((char *)NULL);
        !           837:     }
        !           838: 
        !           839:   /* Read the file into BUFFER. */
        !           840:   buffer = (char *)xmalloc (file_size + 1);
        !           841:   i = read (file, buffer, file_size);
        !           842:   close (file);
        !           843: 
        !           844:   if (i < 0)
        !           845:     {
        !           846:       xfree (buffer);
        !           847:       return ((char *)NULL);
        !           848:     }
        !           849: 
        !           850:   RL_CHECK_SIGNALS ();
        !           851: 
        !           852:   buffer[i] = '\0';
        !           853:   if (sizep)
        !           854:     *sizep = i;
        !           855: 
        !           856:   return (buffer);
        !           857: }
        !           858: 
        !           859: /* Re-read the current keybindings file. */
        !           860: int
        !           861: rl_re_read_init_file (count, ignore)
        !           862:      int count, ignore;
        !           863: {
        !           864:   int r;
        !           865:   r = rl_read_init_file ((const char *)NULL);
        !           866:   rl_set_keymap_from_edit_mode ();
        !           867:   return r;
        !           868: }
        !           869: 
        !           870: /* Do key bindings from a file.  If FILENAME is NULL it defaults
        !           871:    to the first non-null filename from this list:
        !           872:      1. the filename used for the previous call
        !           873:      2. the value of the shell variable `INPUTRC'
        !           874:      3. ~/.inputrc
        !           875:      4. /etc/inputrc
        !           876:    If the file existed and could be opened and read, 0 is returned,
        !           877:    otherwise errno is returned. */
        !           878: int
        !           879: rl_read_init_file (filename)
        !           880:      const char *filename;
        !           881: {
        !           882:   /* Default the filename. */
        !           883:   if (filename == 0)
        !           884:     filename = last_readline_init_file;
        !           885:   if (filename == 0)
        !           886:     filename = sh_get_env_value ("INPUTRC");
        !           887:   if (filename == 0 || *filename == 0)
        !           888:     {
        !           889:       filename = DEFAULT_INPUTRC;
        !           890:       /* Try to read DEFAULT_INPUTRC; fall back to SYS_INPUTRC on failure */
        !           891:       if (_rl_read_init_file (filename, 0) == 0)
        !           892:        return 0;
        !           893:       filename = SYS_INPUTRC;
        !           894:     }
        !           895: 
        !           896: #if defined (__MSDOS__)
        !           897:   if (_rl_read_init_file (filename, 0) == 0)
        !           898:     return 0;
        !           899:   filename = "~/_inputrc";
        !           900: #endif
        !           901:   return (_rl_read_init_file (filename, 0));
        !           902: }
        !           903: 
        !           904: static int
        !           905: _rl_read_init_file (filename, include_level)
        !           906:      const char *filename;
        !           907:      int include_level;
        !           908: {
        !           909:   register int i;
        !           910:   char *buffer, *openname, *line, *end;
        !           911:   size_t file_size;
        !           912: 
        !           913:   current_readline_init_file = filename;
        !           914:   current_readline_init_include_level = include_level;
        !           915: 
        !           916:   openname = tilde_expand (filename);
        !           917:   buffer = _rl_read_file (openname, &file_size);
        !           918:   xfree (openname);
        !           919: 
        !           920:   RL_CHECK_SIGNALS ();
        !           921:   if (buffer == 0)
        !           922:     return (errno);
        !           923:   
        !           924:   if (include_level == 0 && filename != last_readline_init_file)
        !           925:     {
        !           926:       FREE (last_readline_init_file);
        !           927:       last_readline_init_file = savestring (filename);
        !           928:     }
        !           929: 
        !           930:   currently_reading_init_file = 1;
        !           931: 
        !           932:   /* Loop over the lines in the file.  Lines that start with `#' are
        !           933:      comments; all other lines are commands for readline initialization. */
        !           934:   current_readline_init_lineno = 1;
        !           935:   line = buffer;
        !           936:   end = buffer + file_size;
        !           937:   while (line < end)
        !           938:     {
        !           939:       /* Find the end of this line. */
        !           940:       for (i = 0; line + i != end && line[i] != '\n'; i++);
        !           941: 
        !           942: #if defined (__CYGWIN__)
        !           943:       /* ``Be liberal in what you accept.'' */
        !           944:       if (line[i] == '\n' && line[i-1] == '\r')
        !           945:        line[i - 1] = '\0';
        !           946: #endif
        !           947: 
        !           948:       /* Mark end of line. */
        !           949:       line[i] = '\0';
        !           950: 
        !           951:       /* Skip leading whitespace. */
        !           952:       while (*line && whitespace (*line))
        !           953:         {
        !           954:          line++;
        !           955:          i--;
        !           956:         }
        !           957: 
        !           958:       /* If the line is not a comment, then parse it. */
        !           959:       if (*line && *line != '#')
        !           960:        rl_parse_and_bind (line);
        !           961: 
        !           962:       /* Move to the next line. */
        !           963:       line += i + 1;
        !           964:       current_readline_init_lineno++;
        !           965:     }
        !           966: 
        !           967:   xfree (buffer);
        !           968:   currently_reading_init_file = 0;
        !           969:   return (0);
        !           970: }
        !           971: 
        !           972: static void
        !           973: _rl_init_file_error (msg)
        !           974:      const char *msg;
        !           975: {
        !           976:   if (currently_reading_init_file)
        !           977:     _rl_errmsg ("%s: line %d: %s\n", current_readline_init_file,
        !           978:                     current_readline_init_lineno, msg);
        !           979:   else
        !           980:     _rl_errmsg ("%s", msg);
        !           981: }
        !           982: 
        !           983: /* **************************************************************** */
        !           984: /*                                                                 */
        !           985: /*                     Parser Directives                           */
        !           986: /*                                                                 */
        !           987: /* **************************************************************** */
        !           988: 
        !           989: typedef int _rl_parser_func_t PARAMS((char *));
        !           990: 
        !           991: /* Things that mean `Control'. */
        !           992: const char * const _rl_possible_control_prefixes[] = {
        !           993:   "Control-", "C-", "CTRL-", (const char *)NULL
        !           994: };
        !           995: 
        !           996: const char * const _rl_possible_meta_prefixes[] = {
        !           997:   "Meta", "M-", (const char *)NULL
        !           998: };
        !           999: 
        !          1000: /* Conditionals. */
        !          1001: 
        !          1002: /* Calling programs set this to have their argv[0]. */
        !          1003: const char *rl_readline_name = "other";
        !          1004: 
        !          1005: /* Stack of previous values of parsing_conditionalized_out. */
        !          1006: static unsigned char *if_stack = (unsigned char *)NULL;
        !          1007: static int if_stack_depth;
        !          1008: static int if_stack_size;
        !          1009: 
        !          1010: /* Push _rl_parsing_conditionalized_out, and set parser state based
        !          1011:    on ARGS. */
        !          1012: static int
        !          1013: parser_if (args)
        !          1014:      char *args;
        !          1015: {
        !          1016:   register int i;
        !          1017: 
        !          1018:   /* Push parser state. */
        !          1019:   if (if_stack_depth + 1 >= if_stack_size)
        !          1020:     {
        !          1021:       if (!if_stack)
        !          1022:        if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
        !          1023:       else
        !          1024:        if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);
        !          1025:     }
        !          1026:   if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out;
        !          1027: 
        !          1028:   /* If parsing is turned off, then nothing can turn it back on except
        !          1029:      for finding the matching endif.  In that case, return right now. */
        !          1030:   if (_rl_parsing_conditionalized_out)
        !          1031:     return 0;
        !          1032: 
        !          1033:   /* Isolate first argument. */
        !          1034:   for (i = 0; args[i] && !whitespace (args[i]); i++);
        !          1035: 
        !          1036:   if (args[i])
        !          1037:     args[i++] = '\0';
        !          1038: 
        !          1039:   /* Handle "$if term=foo" and "$if mode=emacs" constructs.  If this
        !          1040:      isn't term=foo, or mode=emacs, then check to see if the first
        !          1041:      word in ARGS is the same as the value stored in rl_readline_name. */
        !          1042:   if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0)
        !          1043:     {
        !          1044:       char *tem, *tname;
        !          1045: 
        !          1046:       /* Terminals like "aaa-60" are equivalent to "aaa". */
        !          1047:       tname = savestring (rl_terminal_name);
        !          1048:       tem = strchr (tname, '-');
        !          1049:       if (tem)
        !          1050:        *tem = '\0';
        !          1051: 
        !          1052:       /* Test the `long' and `short' forms of the terminal name so that
        !          1053:         if someone has a `sun-cmd' and does not want to have bindings
        !          1054:         that will be executed if the terminal is a `sun', they can put
        !          1055:         `$if term=sun-cmd' into their .inputrc. */
        !          1056:       _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) &&
        !          1057:                                        _rl_stricmp (args + 5, rl_terminal_name);
        !          1058:       xfree (tname);
        !          1059:     }
        !          1060: #if defined (VI_MODE)
        !          1061:   else if (_rl_strnicmp (args, "mode=", 5) == 0)
        !          1062:     {
        !          1063:       int mode;
        !          1064: 
        !          1065:       if (_rl_stricmp (args + 5, "emacs") == 0)
        !          1066:        mode = emacs_mode;
        !          1067:       else if (_rl_stricmp (args + 5, "vi") == 0)
        !          1068:        mode = vi_mode;
        !          1069:       else
        !          1070:        mode = no_mode;
        !          1071: 
        !          1072:       _rl_parsing_conditionalized_out = mode != rl_editing_mode;
        !          1073:     }
        !          1074: #endif /* VI_MODE */
        !          1075:   /* Check to see if the first word in ARGS is the same as the
        !          1076:      value stored in rl_readline_name. */
        !          1077:   else if (_rl_stricmp (args, rl_readline_name) == 0)
        !          1078:     _rl_parsing_conditionalized_out = 0;
        !          1079:   else
        !          1080:     _rl_parsing_conditionalized_out = 1;
        !          1081:   return 0;
        !          1082: }
        !          1083: 
        !          1084: /* Invert the current parser state if there is anything on the stack. */
        !          1085: static int
        !          1086: parser_else (args)
        !          1087:      char *args;
        !          1088: {
        !          1089:   register int i;
        !          1090: 
        !          1091:   if (if_stack_depth == 0)
        !          1092:     {
        !          1093:       _rl_init_file_error ("$else found without matching $if");
        !          1094:       return 0;
        !          1095:     }
        !          1096: 
        !          1097: #if 0
        !          1098:   /* Check the previous (n - 1) levels of the stack to make sure that
        !          1099:      we haven't previously turned off parsing. */
        !          1100:   for (i = 0; i < if_stack_depth - 1; i++)
        !          1101: #else
        !          1102:   /* Check the previous (n) levels of the stack to make sure that
        !          1103:      we haven't previously turned off parsing. */
        !          1104:   for (i = 0; i < if_stack_depth; i++)
        !          1105: #endif
        !          1106:     if (if_stack[i] == 1)
        !          1107:       return 0;
        !          1108: 
        !          1109:   /* Invert the state of parsing if at top level. */
        !          1110:   _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out;
        !          1111:   return 0;
        !          1112: }
        !          1113: 
        !          1114: /* Terminate a conditional, popping the value of
        !          1115:    _rl_parsing_conditionalized_out from the stack. */
        !          1116: static int
        !          1117: parser_endif (args)
        !          1118:      char *args;
        !          1119: {
        !          1120:   if (if_stack_depth)
        !          1121:     _rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
        !          1122:   else
        !          1123:     _rl_init_file_error ("$endif without matching $if");
        !          1124:   return 0;
        !          1125: }
        !          1126: 
        !          1127: static int
        !          1128: parser_include (args)
        !          1129:      char *args;
        !          1130: {
        !          1131:   const char *old_init_file;
        !          1132:   char *e;
        !          1133:   int old_line_number, old_include_level, r;
        !          1134: 
        !          1135:   if (_rl_parsing_conditionalized_out)
        !          1136:     return (0);
        !          1137: 
        !          1138:   old_init_file = current_readline_init_file;
        !          1139:   old_line_number = current_readline_init_lineno;
        !          1140:   old_include_level = current_readline_init_include_level;
        !          1141: 
        !          1142:   e = strchr (args, '\n');
        !          1143:   if (e)
        !          1144:     *e = '\0';
        !          1145:   r = _rl_read_init_file ((const char *)args, old_include_level + 1);
        !          1146: 
        !          1147:   current_readline_init_file = old_init_file;
        !          1148:   current_readline_init_lineno = old_line_number;
        !          1149:   current_readline_init_include_level = old_include_level;
        !          1150: 
        !          1151:   return r;
        !          1152: }
        !          1153:   
        !          1154: /* Associate textual names with actual functions. */
        !          1155: static const struct {
        !          1156:   const char * const name;
        !          1157:   _rl_parser_func_t *function;
        !          1158: } parser_directives [] = {
        !          1159:   { "if", parser_if },
        !          1160:   { "endif", parser_endif },
        !          1161:   { "else", parser_else },
        !          1162:   { "include", parser_include },
        !          1163:   { (char *)0x0, (_rl_parser_func_t *)0x0 }
        !          1164: };
        !          1165: 
        !          1166: /* Handle a parser directive.  STATEMENT is the line of the directive
        !          1167:    without any leading `$'. */
        !          1168: static int
        !          1169: handle_parser_directive (statement)
        !          1170:      char *statement;
        !          1171: {
        !          1172:   register int i;
        !          1173:   char *directive, *args;
        !          1174: 
        !          1175:   /* Isolate the actual directive. */
        !          1176: 
        !          1177:   /* Skip whitespace. */
        !          1178:   for (i = 0; whitespace (statement[i]); i++);
        !          1179: 
        !          1180:   directive = &statement[i];
        !          1181: 
        !          1182:   for (; statement[i] && !whitespace (statement[i]); i++);
        !          1183: 
        !          1184:   if (statement[i])
        !          1185:     statement[i++] = '\0';
        !          1186: 
        !          1187:   for (; statement[i] && whitespace (statement[i]); i++);
        !          1188: 
        !          1189:   args = &statement[i];
        !          1190: 
        !          1191:   /* Lookup the command, and act on it. */
        !          1192:   for (i = 0; parser_directives[i].name; i++)
        !          1193:     if (_rl_stricmp (directive, parser_directives[i].name) == 0)
        !          1194:       {
        !          1195:        (*parser_directives[i].function) (args);
        !          1196:        return (0);
        !          1197:       }
        !          1198: 
        !          1199:   /* display an error message about the unknown parser directive */
        !          1200:   _rl_init_file_error ("unknown parser directive");
        !          1201:   return (1);
        !          1202: }
        !          1203: 
        !          1204: /* Start at STRING[START] and look for DELIM.  Return I where STRING[I] ==
        !          1205:    DELIM or STRING[I] == 0.  DELIM is usually a double quote. */
        !          1206: static int
        !          1207: _rl_skip_to_delim (string, start, delim)
        !          1208:      char *string;
        !          1209:      int start, delim;
        !          1210: {
        !          1211:   int i, c, passc;
        !          1212: 
        !          1213:   for (i = start,passc = 0; c = string[i]; i++)
        !          1214:     {
        !          1215:       if (passc)
        !          1216:        {
        !          1217:          passc = 0;
        !          1218:          if (c == 0)
        !          1219:            break;
        !          1220:          continue;
        !          1221:        }
        !          1222: 
        !          1223:       if (c == '\\')
        !          1224:        {
        !          1225:          passc = 1;
        !          1226:          continue;
        !          1227:        }
        !          1228: 
        !          1229:       if (c == delim)
        !          1230:        break;
        !          1231:     }
        !          1232: 
        !          1233:   return i;
        !          1234: }
        !          1235: 
        !          1236: /* Read the binding command from STRING and perform it.
        !          1237:    A key binding command looks like: Keyname: function-name\0,
        !          1238:    a variable binding command looks like: set variable value.
        !          1239:    A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
        !          1240: int
        !          1241: rl_parse_and_bind (string)
        !          1242:      char *string;
        !          1243: {
        !          1244:   char *funname, *kname;
        !          1245:   register int c, i;
        !          1246:   int key, equivalency;
        !          1247: 
        !          1248:   while (string && whitespace (*string))
        !          1249:     string++;
        !          1250: 
        !          1251:   if (string == 0 || *string == 0 || *string == '#')
        !          1252:     return 0;
        !          1253: 
        !          1254:   /* If this is a parser directive, act on it. */
        !          1255:   if (*string == '$')
        !          1256:     {
        !          1257:       handle_parser_directive (&string[1]);
        !          1258:       return 0;
        !          1259:     }
        !          1260: 
        !          1261:   /* If we aren't supposed to be parsing right now, then we're done. */
        !          1262:   if (_rl_parsing_conditionalized_out)
        !          1263:     return 0;
        !          1264: 
        !          1265:   i = 0;
        !          1266:   /* If this keyname is a complex key expression surrounded by quotes,
        !          1267:      advance to after the matching close quote.  This code allows the
        !          1268:      backslash to quote characters in the key expression. */
        !          1269:   if (*string == '"')
        !          1270:     {
        !          1271:       i = _rl_skip_to_delim (string, 1, '"');
        !          1272: 
        !          1273:       /* If we didn't find a closing quote, abort the line. */
        !          1274:       if (string[i] == '\0')
        !          1275:         {
        !          1276:           _rl_init_file_error ("no closing `\"' in key binding");
        !          1277:           return 1;
        !          1278:         }
        !          1279:       else
        !          1280:         i++;   /* skip past closing double quote */
        !          1281:     }
        !          1282: 
        !          1283:   /* Advance to the colon (:) or whitespace which separates the two objects. */
        !          1284:   for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
        !          1285: 
        !          1286:   equivalency = (c == ':' && string[i + 1] == '=');
        !          1287: 
        !          1288:   /* Mark the end of the command (or keyname). */
        !          1289:   if (string[i])
        !          1290:     string[i++] = '\0';
        !          1291: 
        !          1292:   /* If doing assignment, skip the '=' sign as well. */
        !          1293:   if (equivalency)
        !          1294:     string[i++] = '\0';
        !          1295: 
        !          1296:   /* If this is a command to set a variable, then do that. */
        !          1297:   if (_rl_stricmp (string, "set") == 0)
        !          1298:     {
        !          1299:       char *var, *value, *e;
        !          1300:       int s;
        !          1301: 
        !          1302:       var = string + i;
        !          1303:       /* Make VAR point to start of variable name. */
        !          1304:       while (*var && whitespace (*var)) var++;
        !          1305: 
        !          1306:       /* Make VALUE point to start of value string. */
        !          1307:       value = var;
        !          1308:       while (*value && whitespace (*value) == 0) value++;
        !          1309:       if (*value)
        !          1310:        *value++ = '\0';
        !          1311:       while (*value && whitespace (*value)) value++;
        !          1312: 
        !          1313:       /* Strip trailing whitespace from values of boolean variables. */
        !          1314:       if (find_boolean_var (var) >= 0)
        !          1315:        {
        !          1316:          /* remove trailing whitespace */
        !          1317: remove_trailing:
        !          1318:          e = value + strlen (value) - 1;
        !          1319:          while (e >= value && whitespace (*e))
        !          1320:            e--;
        !          1321:          e++;          /* skip back to whitespace or EOS */
        !          1322:          
        !          1323:          if (*e && e >= value)
        !          1324:            *e = '\0';
        !          1325:        }
        !          1326:       else if ((i = find_string_var (var)) >= 0)
        !          1327:        {
        !          1328:          /* Allow quoted strings in variable values */
        !          1329:          if (*value == '"')
        !          1330:            {
        !          1331:              i = _rl_skip_to_delim (value, 1, *value);
        !          1332:              value[i] = '\0';
        !          1333:              value++;  /* skip past the quote */
        !          1334:            }
        !          1335:          else
        !          1336:            goto remove_trailing;
        !          1337:        }
        !          1338:        
        !          1339:       rl_variable_bind (var, value);
        !          1340:       return 0;
        !          1341:     }
        !          1342: 
        !          1343:   /* Skip any whitespace between keyname and funname. */
        !          1344:   for (; string[i] && whitespace (string[i]); i++);
        !          1345:   funname = &string[i];
        !          1346: 
        !          1347:   /* Now isolate funname.
        !          1348:      For straight function names just look for whitespace, since
        !          1349:      that will signify the end of the string.  But this could be a
        !          1350:      macro definition.  In that case, the string is quoted, so skip
        !          1351:      to the matching delimiter.  We allow the backslash to quote the
        !          1352:      delimiter characters in the macro body. */
        !          1353:   /* This code exists to allow whitespace in macro expansions, which
        !          1354:      would otherwise be gobbled up by the next `for' loop.*/
        !          1355:   /* XXX - it may be desirable to allow backslash quoting only if " is
        !          1356:      the quoted string delimiter, like the shell. */
        !          1357:   if (*funname == '\'' || *funname == '"')
        !          1358:     {
        !          1359:       i = _rl_skip_to_delim (string, i+1, *funname);
        !          1360:       if (string[i])
        !          1361:        i++;
        !          1362:     }
        !          1363: 
        !          1364:   /* Advance to the end of the string.  */
        !          1365:   for (; string[i] && whitespace (string[i]) == 0; i++);
        !          1366: 
        !          1367:   /* No extra whitespace at the end of the string. */
        !          1368:   string[i] = '\0';
        !          1369: 
        !          1370:   /* Handle equivalency bindings here.  Make the left-hand side be exactly
        !          1371:      whatever the right-hand evaluates to, including keymaps. */
        !          1372:   if (equivalency)
        !          1373:     {
        !          1374:       return 0;
        !          1375:     }
        !          1376: 
        !          1377:   /* If this is a new-style key-binding, then do the binding with
        !          1378:      rl_bind_keyseq ().  Otherwise, let the older code deal with it. */
        !          1379:   if (*string == '"')
        !          1380:     {
        !          1381:       char *seq;
        !          1382:       register int j, k, passc;
        !          1383: 
        !          1384:       seq = (char *)xmalloc (1 + strlen (string));
        !          1385:       for (j = 1, k = passc = 0; string[j]; j++)
        !          1386:        {
        !          1387:          /* Allow backslash to quote characters, but leave them in place.
        !          1388:             This allows a string to end with a backslash quoting another
        !          1389:             backslash, or with a backslash quoting a double quote.  The
        !          1390:             backslashes are left in place for rl_translate_keyseq (). */
        !          1391:          if (passc || (string[j] == '\\'))
        !          1392:            {
        !          1393:              seq[k++] = string[j];
        !          1394:              passc = !passc;
        !          1395:              continue;
        !          1396:            }
        !          1397: 
        !          1398:          if (string[j] == '"')
        !          1399:            break;
        !          1400: 
        !          1401:          seq[k++] = string[j];
        !          1402:        }
        !          1403:       seq[k] = '\0';
        !          1404: 
        !          1405:       /* Binding macro? */
        !          1406:       if (*funname == '\'' || *funname == '"')
        !          1407:        {
        !          1408:          j = strlen (funname);
        !          1409: 
        !          1410:          /* Remove the delimiting quotes from each end of FUNNAME. */
        !          1411:          if (j && funname[j - 1] == *funname)
        !          1412:            funname[j - 1] = '\0';
        !          1413: 
        !          1414:          rl_macro_bind (seq, &funname[1], _rl_keymap);
        !          1415:        }
        !          1416:       else
        !          1417:        rl_bind_keyseq (seq, rl_named_function (funname));
        !          1418: 
        !          1419:       xfree (seq);
        !          1420:       return 0;
        !          1421:     }
        !          1422: 
        !          1423:   /* Get the actual character we want to deal with. */
        !          1424:   kname = strrchr (string, '-');
        !          1425:   if (kname == 0)
        !          1426:     kname = string;
        !          1427:   else
        !          1428:     kname++;
        !          1429: 
        !          1430:   key = glean_key_from_name (kname);
        !          1431: 
        !          1432:   /* Add in control and meta bits. */
        !          1433:   if (substring_member_of_array (string, _rl_possible_control_prefixes))
        !          1434:     key = CTRL (_rl_to_upper (key));
        !          1435: 
        !          1436:   if (substring_member_of_array (string, _rl_possible_meta_prefixes))
        !          1437:     key = META (key);
        !          1438: 
        !          1439:   /* Temporary.  Handle old-style keyname with macro-binding. */
        !          1440:   if (*funname == '\'' || *funname == '"')
        !          1441:     {
        !          1442:       char useq[2];
        !          1443:       int fl = strlen (funname);
        !          1444: 
        !          1445:       useq[0] = key; useq[1] = '\0';
        !          1446:       if (fl && funname[fl - 1] == *funname)
        !          1447:        funname[fl - 1] = '\0';
        !          1448: 
        !          1449:       rl_macro_bind (useq, &funname[1], _rl_keymap);
        !          1450:     }
        !          1451: #if defined (PREFIX_META_HACK)
        !          1452:   /* Ugly, but working hack to keep prefix-meta around. */
        !          1453:   else if (_rl_stricmp (funname, "prefix-meta") == 0)
        !          1454:     {
        !          1455:       char seq[2];
        !          1456: 
        !          1457:       seq[0] = key;
        !          1458:       seq[1] = '\0';
        !          1459:       rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap);
        !          1460:     }
        !          1461: #endif /* PREFIX_META_HACK */
        !          1462:   else
        !          1463:     rl_bind_key (key, rl_named_function (funname));
        !          1464:   return 0;
        !          1465: }
        !          1466: 
        !          1467: /* Simple structure for boolean readline variables (i.e., those that can
        !          1468:    have one of two values; either "On" or 1 for truth, or "Off" or 0 for
        !          1469:    false. */
        !          1470: 
        !          1471: #define V_SPECIAL      0x1
        !          1472: 
        !          1473: static const struct {
        !          1474:   const char * const name;
        !          1475:   int *value;
        !          1476:   int flags;
        !          1477: } boolean_varlist [] = {
        !          1478:   { "bind-tty-special-chars",  &_rl_bind_stty_chars,           0 },
        !          1479:   { "blink-matching-paren",    &rl_blink_matching_paren,       V_SPECIAL },
        !          1480:   { "byte-oriented",           &rl_byte_oriented,              0 },
        !          1481: #if defined (COLOR_SUPPORT)
        !          1482:   { "colored-stats",           &_rl_colored_stats,             0 },
        !          1483: #endif
        !          1484:   { "completion-ignore-case",  &_rl_completion_case_fold,      0 },
        !          1485:   { "completion-map-case",     &_rl_completion_case_map,       0 },
        !          1486:   { "convert-meta",            &_rl_convert_meta_chars_to_ascii, 0 },
        !          1487:   { "disable-completion",      &rl_inhibit_completion,         0 },
        !          1488:   { "echo-control-characters", &_rl_echo_control_chars,        0 },
        !          1489:   { "enable-keypad",           &_rl_enable_keypad,             0 },
        !          1490:   { "enable-meta-key",         &_rl_enable_meta,               0 },
        !          1491:   { "expand-tilde",            &rl_complete_with_tilde_expansion, 0 },
        !          1492:   { "history-preserve-point",  &_rl_history_preserve_point,    0 },
        !          1493:   { "horizontal-scroll-mode",  &_rl_horizontal_scroll_mode,    0 },
        !          1494:   { "input-meta",              &_rl_meta_flag,                 0 },
        !          1495:   { "mark-directories",                &_rl_complete_mark_directories, 0 },
        !          1496:   { "mark-modified-lines",     &_rl_mark_modified_lines,       0 },
        !          1497:   { "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 },
        !          1498:   { "match-hidden-files",      &_rl_match_hidden_files,        0 },
        !          1499:   { "menu-complete-display-prefix", &_rl_menu_complete_prefix_first, 0 },
        !          1500:   { "meta-flag",               &_rl_meta_flag,                 0 },
        !          1501:   { "output-meta",             &_rl_output_meta_chars,         0 },
        !          1502:   { "page-completions",                &_rl_page_completions,          0 },
        !          1503:   { "prefer-visible-bell",     &_rl_prefer_visible_bell,       V_SPECIAL },
        !          1504:   { "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
        !          1505:   { "revert-all-at-newline",   &_rl_revert_all_at_newline,     0 },
        !          1506:   { "show-all-if-ambiguous",   &_rl_complete_show_all,         0 },
        !          1507:   { "show-all-if-unmodified",  &_rl_complete_show_unmodified,  0 },
        !          1508:   { "show-mode-in-prompt",     &_rl_show_mode_in_prompt,       0 },
        !          1509:   { "skip-completed-text",     &_rl_skip_completed_text,       0 },
        !          1510: #if defined (VISIBLE_STATS)
        !          1511:   { "visible-stats",           &rl_visible_stats,              0 },
        !          1512: #endif /* VISIBLE_STATS */
        !          1513:   { (char *)NULL, (int *)NULL, 0 }
        !          1514: };
        !          1515: 
        !          1516: static int
        !          1517: find_boolean_var (name)
        !          1518:      const char *name;
        !          1519: {
        !          1520:   register int i;
        !          1521: 
        !          1522:   for (i = 0; boolean_varlist[i].name; i++)
        !          1523:     if (_rl_stricmp (name, boolean_varlist[i].name) == 0)
        !          1524:       return i;
        !          1525:   return -1;
        !          1526: }
        !          1527: 
        !          1528: /* Hooks for handling special boolean variables, where a
        !          1529:    function needs to be called or another variable needs
        !          1530:    to be changed when they're changed. */
        !          1531: static void
        !          1532: hack_special_boolean_var (i)
        !          1533:      int i;
        !          1534: {
        !          1535:   const char *name;
        !          1536: 
        !          1537:   name = boolean_varlist[i].name;
        !          1538: 
        !          1539:   if (_rl_stricmp (name, "blink-matching-paren") == 0)
        !          1540:     _rl_enable_paren_matching (rl_blink_matching_paren);
        !          1541:   else if (_rl_stricmp (name, "prefer-visible-bell") == 0)
        !          1542:     {
        !          1543:       if (_rl_prefer_visible_bell)
        !          1544:        _rl_bell_preference = VISIBLE_BELL;
        !          1545:       else
        !          1546:        _rl_bell_preference = AUDIBLE_BELL;
        !          1547:     }
        !          1548:   else if (_rl_stricmp (name, "show-mode-in-prompt") == 0)
        !          1549:     _rl_reset_prompt ();
        !          1550: }
        !          1551: 
        !          1552: typedef int _rl_sv_func_t PARAMS((const char *));
        !          1553: 
        !          1554: /* These *must* correspond to the array indices for the appropriate
        !          1555:    string variable.  (Though they're not used right now.) */
        !          1556: #define V_BELLSTYLE    0
        !          1557: #define V_COMBEGIN     1
        !          1558: #define V_EDITMODE     2
        !          1559: #define V_ISRCHTERM    3
        !          1560: #define V_KEYMAP       4
        !          1561: 
        !          1562: #define        V_STRING        1
        !          1563: #define V_INT          2
        !          1564: 
        !          1565: /* Forward declarations */
        !          1566: static int sv_bell_style PARAMS((const char *));
        !          1567: static int sv_combegin PARAMS((const char *));
        !          1568: static int sv_dispprefix PARAMS((const char *));
        !          1569: static int sv_compquery PARAMS((const char *));
        !          1570: static int sv_compwidth PARAMS((const char *));
        !          1571: static int sv_editmode PARAMS((const char *));
        !          1572: static int sv_histsize PARAMS((const char *));
        !          1573: static int sv_isrchterm PARAMS((const char *));
        !          1574: static int sv_keymap PARAMS((const char *));
        !          1575: static int sv_seqtimeout PARAMS((const char *));
        !          1576: 
        !          1577: static const struct {
        !          1578:   const char * const name;
        !          1579:   int flags;
        !          1580:   _rl_sv_func_t *set_func;
        !          1581: } string_varlist[] = {
        !          1582:   { "bell-style",      V_STRING,       sv_bell_style },
        !          1583:   { "comment-begin",   V_STRING,       sv_combegin },
        !          1584:   { "completion-display-width", V_INT, sv_compwidth },
        !          1585:   { "completion-prefix-display-length", V_INT, sv_dispprefix },
        !          1586:   { "completion-query-items", V_INT,   sv_compquery },
        !          1587:   { "editing-mode",    V_STRING,       sv_editmode },
        !          1588:   { "history-size",    V_INT,          sv_histsize },
        !          1589:   { "isearch-terminators", V_STRING,   sv_isrchterm },
        !          1590:   { "keymap",          V_STRING,       sv_keymap },
        !          1591:   { "keyseq-timeout",  V_INT,          sv_seqtimeout },
        !          1592:   { (char *)NULL,      0, (_rl_sv_func_t *)0 }
        !          1593: };
        !          1594: 
        !          1595: static int
        !          1596: find_string_var (name)
        !          1597:      const char *name;
        !          1598: {
        !          1599:   register int i;
        !          1600: 
        !          1601:   for (i = 0; string_varlist[i].name; i++)
        !          1602:     if (_rl_stricmp (name, string_varlist[i].name) == 0)
        !          1603:       return i;
        !          1604:   return -1;
        !          1605: }
        !          1606: 
        !          1607: /* A boolean value that can appear in a `set variable' command is true if
        !          1608:    the value is null or empty, `on' (case-insenstive), or "1".  Any other
        !          1609:    values result in 0 (false). */
        !          1610: static int
        !          1611: bool_to_int (value)
        !          1612:      const char *value;
        !          1613: {
        !          1614:   return (value == 0 || *value == '\0' ||
        !          1615:                (_rl_stricmp (value, "on") == 0) ||
        !          1616:                (value[0] == '1' && value[1] == '\0'));
        !          1617: }
        !          1618: 
        !          1619: char *
        !          1620: rl_variable_value (name)
        !          1621:      const char *name;
        !          1622: {
        !          1623:   register int i;
        !          1624: 
        !          1625:   /* Check for simple variables first. */
        !          1626:   i = find_boolean_var (name);
        !          1627:   if (i >= 0)
        !          1628:     return (*boolean_varlist[i].value ? "on" : "off");
        !          1629: 
        !          1630:   i = find_string_var (name);
        !          1631:   if (i >= 0)
        !          1632:     return (_rl_get_string_variable_value (string_varlist[i].name));
        !          1633: 
        !          1634:   /* Unknown variable names return NULL. */
        !          1635:   return 0;
        !          1636: }
        !          1637: 
        !          1638: int
        !          1639: rl_variable_bind (name, value)
        !          1640:      const char *name, *value;
        !          1641: {
        !          1642:   register int i;
        !          1643:   int  v;
        !          1644: 
        !          1645:   /* Check for simple variables first. */
        !          1646:   i = find_boolean_var (name);
        !          1647:   if (i >= 0)
        !          1648:     {
        !          1649:       *boolean_varlist[i].value = bool_to_int (value);
        !          1650:       if (boolean_varlist[i].flags & V_SPECIAL)
        !          1651:        hack_special_boolean_var (i);
        !          1652:       return 0;
        !          1653:     }
        !          1654: 
        !          1655:   i = find_string_var (name);
        !          1656: 
        !          1657:   /* For the time being, unknown variable names or string names without a
        !          1658:      handler function are simply ignored. */
        !          1659:   if (i < 0 || string_varlist[i].set_func == 0)
        !          1660:     return 0;
        !          1661: 
        !          1662:   v = (*string_varlist[i].set_func) (value);
        !          1663:   return v;
        !          1664: }
        !          1665: 
        !          1666: static int
        !          1667: sv_editmode (value)
        !          1668:      const char *value;
        !          1669: {
        !          1670:   if (_rl_strnicmp (value, "vi", 2) == 0)
        !          1671:     {
        !          1672: #if defined (VI_MODE)
        !          1673:       _rl_keymap = vi_insertion_keymap;
        !          1674:       rl_editing_mode = vi_mode;
        !          1675: #endif /* VI_MODE */
        !          1676:       return 0;
        !          1677:     }
        !          1678:   else if (_rl_strnicmp (value, "emacs", 5) == 0)
        !          1679:     {
        !          1680:       _rl_keymap = emacs_standard_keymap;
        !          1681:       rl_editing_mode = emacs_mode;
        !          1682:       return 0;
        !          1683:     }
        !          1684:   return 1;
        !          1685: }
        !          1686: 
        !          1687: static int
        !          1688: sv_combegin (value)
        !          1689:      const char *value;
        !          1690: {
        !          1691:   if (value && *value)
        !          1692:     {
        !          1693:       FREE (_rl_comment_begin);
        !          1694:       _rl_comment_begin = savestring (value);
        !          1695:       return 0;
        !          1696:     }
        !          1697:   return 1;
        !          1698: }
        !          1699: 
        !          1700: static int
        !          1701: sv_dispprefix (value)
        !          1702:      const char *value;
        !          1703: {
        !          1704:   int nval = 0;
        !          1705: 
        !          1706:   if (value && *value)
        !          1707:     {
        !          1708:       nval = atoi (value);
        !          1709:       if (nval < 0)
        !          1710:        nval = 0;
        !          1711:     }
        !          1712:   _rl_completion_prefix_display_length = nval;
        !          1713:   return 0;
        !          1714: }
        !          1715: 
        !          1716: static int
        !          1717: sv_compquery (value)
        !          1718:      const char *value;
        !          1719: {
        !          1720:   int nval = 100;
        !          1721: 
        !          1722:   if (value && *value)
        !          1723:     {
        !          1724:       nval = atoi (value);
        !          1725:       if (nval < 0)
        !          1726:        nval = 0;
        !          1727:     }
        !          1728:   rl_completion_query_items = nval;
        !          1729:   return 0;
        !          1730: }
        !          1731: 
        !          1732: static int
        !          1733: sv_compwidth (value)
        !          1734:      const char *value;
        !          1735: {
        !          1736:   int nval = -1;
        !          1737: 
        !          1738:   if (value && *value)
        !          1739:     nval = atoi (value);
        !          1740: 
        !          1741:   _rl_completion_columns = nval;
        !          1742:   return 0;
        !          1743: }
        !          1744: 
        !          1745: static int
        !          1746: sv_histsize (value)
        !          1747:      const char *value;
        !          1748: {
        !          1749:   int nval;
        !          1750: 
        !          1751:   nval = 500;
        !          1752:   if (value && *value)
        !          1753:     {
        !          1754:       nval = atoi (value);
        !          1755:       if (nval < 0)
        !          1756:        {
        !          1757:          unstifle_history ();
        !          1758:          return 0;
        !          1759:        }
        !          1760:     }
        !          1761:   stifle_history (nval);
        !          1762:   return 0;
        !          1763: }
        !          1764: 
        !          1765: static int
        !          1766: sv_keymap (value)
        !          1767:      const char *value;
        !          1768: {
        !          1769:   Keymap kmap;
        !          1770: 
        !          1771:   kmap = rl_get_keymap_by_name (value);
        !          1772:   if (kmap)
        !          1773:     {
        !          1774:       rl_set_keymap (kmap);
        !          1775:       return 0;
        !          1776:     }
        !          1777:   return 1;
        !          1778: }
        !          1779: 
        !          1780: static int
        !          1781: sv_seqtimeout (value)
        !          1782:      const char *value;
        !          1783: {
        !          1784:   int nval;
        !          1785: 
        !          1786:   nval = 0;
        !          1787:   if (value && *value)
        !          1788:     {
        !          1789:       nval = atoi (value);
        !          1790:       if (nval < 0)
        !          1791:        nval = 0;
        !          1792:     }
        !          1793:   _rl_keyseq_timeout = nval;
        !          1794:   return 0;
        !          1795: }
        !          1796: 
        !          1797: static int
        !          1798: sv_bell_style (value)
        !          1799:      const char *value;
        !          1800: {
        !          1801:   if (value == 0 || *value == '\0')
        !          1802:     _rl_bell_preference = AUDIBLE_BELL;
        !          1803:   else if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0)
        !          1804:     _rl_bell_preference = NO_BELL;
        !          1805:   else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0)
        !          1806:     _rl_bell_preference = AUDIBLE_BELL;
        !          1807:   else if (_rl_stricmp (value, "visible") == 0)
        !          1808:     _rl_bell_preference = VISIBLE_BELL;
        !          1809:   else
        !          1810:     return 1;
        !          1811:   return 0;
        !          1812: }
        !          1813: 
        !          1814: static int
        !          1815: sv_isrchterm (value)
        !          1816:      const char *value;
        !          1817: {
        !          1818:   int beg, end, delim;
        !          1819:   char *v;
        !          1820: 
        !          1821:   if (value == 0)
        !          1822:     return 1;
        !          1823: 
        !          1824:   /* Isolate the value and translate it into a character string. */
        !          1825:   v = savestring (value);
        !          1826:   FREE (_rl_isearch_terminators);
        !          1827:   if (v[0] == '"' || v[0] == '\'')
        !          1828:     {
        !          1829:       delim = v[0];
        !          1830:       for (beg = end = 1; v[end] && v[end] != delim; end++)
        !          1831:        ;
        !          1832:     }
        !          1833:   else
        !          1834:     {
        !          1835:       for (beg = end = 0; whitespace (v[end]) == 0; end++)
        !          1836:        ;
        !          1837:     }
        !          1838: 
        !          1839:   v[end] = '\0';
        !          1840: 
        !          1841:   /* The value starts at v + beg.  Translate it into a character string. */
        !          1842:   _rl_isearch_terminators = (char *)xmalloc (2 * strlen (v) + 1);
        !          1843:   rl_translate_keyseq (v + beg, _rl_isearch_terminators, &end);
        !          1844:   _rl_isearch_terminators[end] = '\0';
        !          1845: 
        !          1846:   xfree (v);
        !          1847:   return 0;
        !          1848: }
        !          1849:       
        !          1850: /* Return the character which matches NAME.
        !          1851:    For example, `Space' returns ' '. */
        !          1852: 
        !          1853: typedef struct {
        !          1854:   const char * const name;
        !          1855:   int value;
        !          1856: } assoc_list;
        !          1857: 
        !          1858: static const assoc_list name_key_alist[] = {
        !          1859:   { "DEL", 0x7f },
        !          1860:   { "ESC", '\033' },
        !          1861:   { "Escape", '\033' },
        !          1862:   { "LFD", '\n' },
        !          1863:   { "Newline", '\n' },
        !          1864:   { "RET", '\r' },
        !          1865:   { "Return", '\r' },
        !          1866:   { "Rubout", 0x7f },
        !          1867:   { "SPC", ' ' },
        !          1868:   { "Space", ' ' },
        !          1869:   { "Tab", 0x09 },
        !          1870:   { (char *)0x0, 0 }
        !          1871: };
        !          1872: 
        !          1873: static int
        !          1874: glean_key_from_name (name)
        !          1875:      char *name;
        !          1876: {
        !          1877:   register int i;
        !          1878: 
        !          1879:   for (i = 0; name_key_alist[i].name; i++)
        !          1880:     if (_rl_stricmp (name, name_key_alist[i].name) == 0)
        !          1881:       return (name_key_alist[i].value);
        !          1882: 
        !          1883:   return (*(unsigned char *)name);     /* XXX was return (*name) */
        !          1884: }
        !          1885: 
        !          1886: /* Auxiliary functions to manage keymaps. */
        !          1887: static const struct {
        !          1888:   const char * const name;
        !          1889:   Keymap map;
        !          1890: } keymap_names[] = {
        !          1891:   { "emacs", emacs_standard_keymap },
        !          1892:   { "emacs-standard", emacs_standard_keymap },
        !          1893:   { "emacs-meta", emacs_meta_keymap },
        !          1894:   { "emacs-ctlx", emacs_ctlx_keymap },
        !          1895: #if defined (VI_MODE)
        !          1896:   { "vi", vi_movement_keymap },
        !          1897:   { "vi-move", vi_movement_keymap },
        !          1898:   { "vi-command", vi_movement_keymap },
        !          1899:   { "vi-insert", vi_insertion_keymap },
        !          1900: #endif /* VI_MODE */
        !          1901:   { (char *)0x0, (Keymap)0x0 }
        !          1902: };
        !          1903: 
        !          1904: Keymap
        !          1905: rl_get_keymap_by_name (name)
        !          1906:      const char *name;
        !          1907: {
        !          1908:   register int i;
        !          1909: 
        !          1910:   for (i = 0; keymap_names[i].name; i++)
        !          1911:     if (_rl_stricmp (name, keymap_names[i].name) == 0)
        !          1912:       return (keymap_names[i].map);
        !          1913:   return ((Keymap) NULL);
        !          1914: }
        !          1915: 
        !          1916: char *
        !          1917: rl_get_keymap_name (map)
        !          1918:      Keymap map;
        !          1919: {
        !          1920:   register int i;
        !          1921:   for (i = 0; keymap_names[i].name; i++)
        !          1922:     if (map == keymap_names[i].map)
        !          1923:       return ((char *)keymap_names[i].name);
        !          1924:   return ((char *)NULL);
        !          1925: }
        !          1926:   
        !          1927: void
        !          1928: rl_set_keymap (map)
        !          1929:      Keymap map;
        !          1930: {
        !          1931:   if (map)
        !          1932:     _rl_keymap = map;
        !          1933: }
        !          1934: 
        !          1935: Keymap
        !          1936: rl_get_keymap ()
        !          1937: {
        !          1938:   return (_rl_keymap);
        !          1939: }
        !          1940: 
        !          1941: void
        !          1942: rl_set_keymap_from_edit_mode ()
        !          1943: {
        !          1944:   if (rl_editing_mode == emacs_mode)
        !          1945:     _rl_keymap = emacs_standard_keymap;
        !          1946: #if defined (VI_MODE)
        !          1947:   else if (rl_editing_mode == vi_mode)
        !          1948:     _rl_keymap = vi_insertion_keymap;
        !          1949: #endif /* VI_MODE */
        !          1950: }
        !          1951: 
        !          1952: char *
        !          1953: rl_get_keymap_name_from_edit_mode ()
        !          1954: {
        !          1955:   if (rl_editing_mode == emacs_mode)
        !          1956:     return "emacs";
        !          1957: #if defined (VI_MODE)
        !          1958:   else if (rl_editing_mode == vi_mode)
        !          1959:     return "vi";
        !          1960: #endif /* VI_MODE */
        !          1961:   else
        !          1962:     return "none";
        !          1963: }
        !          1964: 
        !          1965: /* **************************************************************** */
        !          1966: /*                                                                 */
        !          1967: /*               Key Binding and Function Information              */
        !          1968: /*                                                                 */
        !          1969: /* **************************************************************** */
        !          1970: 
        !          1971: /* Each of the following functions produces information about the
        !          1972:    state of keybindings and functions known to Readline.  The info
        !          1973:    is always printed to rl_outstream, and in such a way that it can
        !          1974:    be read back in (i.e., passed to rl_parse_and_bind ()). */
        !          1975: 
        !          1976: /* Print the names of functions known to Readline. */
        !          1977: void
        !          1978: rl_list_funmap_names ()
        !          1979: {
        !          1980:   register int i;
        !          1981:   const char **funmap_names;
        !          1982: 
        !          1983:   funmap_names = rl_funmap_names ();
        !          1984: 
        !          1985:   if (!funmap_names)
        !          1986:     return;
        !          1987: 
        !          1988:   for (i = 0; funmap_names[i]; i++)
        !          1989:     fprintf (rl_outstream, "%s\n", funmap_names[i]);
        !          1990: 
        !          1991:   xfree (funmap_names);
        !          1992: }
        !          1993: 
        !          1994: static char *
        !          1995: _rl_get_keyname (key)
        !          1996:      int key;
        !          1997: {
        !          1998:   char *keyname;
        !          1999:   int i, c;
        !          2000: 
        !          2001:   keyname = (char *)xmalloc (8);
        !          2002: 
        !          2003:   c = key;
        !          2004:   /* Since this is going to be used to write out keysequence-function
        !          2005:      pairs for possible inclusion in an inputrc file, we don't want to
        !          2006:      do any special meta processing on KEY. */
        !          2007: 
        !          2008: #if 1
        !          2009:   /* XXX - Experimental */
        !          2010:   /* We might want to do this, but the old version of the code did not. */
        !          2011: 
        !          2012:   /* If this is an escape character, we don't want to do any more processing.
        !          2013:      Just add the special ESC key sequence and return. */
        !          2014:   if (c == ESC)
        !          2015:     {
        !          2016:       keyname[0] = '\\';
        !          2017:       keyname[1] = 'e';
        !          2018:       keyname[2] = '\0';
        !          2019:       return keyname;
        !          2020:     }
        !          2021: #endif
        !          2022: 
        !          2023:   /* RUBOUT is translated directly into \C-? */
        !          2024:   if (key == RUBOUT)
        !          2025:     {
        !          2026:       keyname[0] = '\\';
        !          2027:       keyname[1] = 'C';
        !          2028:       keyname[2] = '-';
        !          2029:       keyname[3] = '?';
        !          2030:       keyname[4] = '\0';
        !          2031:       return keyname;
        !          2032:     }
        !          2033: 
        !          2034:   i = 0;
        !          2035:   /* Now add special prefixes needed for control characters.  This can
        !          2036:      potentially change C. */
        !          2037:   if (CTRL_CHAR (c))
        !          2038:     {
        !          2039:       keyname[i++] = '\\';
        !          2040:       keyname[i++] = 'C';
        !          2041:       keyname[i++] = '-';
        !          2042:       c = _rl_to_lower (UNCTRL (c));
        !          2043:     }
        !          2044: 
        !          2045:   /* XXX experimental code.  Turn the characters that are not ASCII or
        !          2046:      ISO Latin 1 (128 - 159) into octal escape sequences (\200 - \237).
        !          2047:      This changes C. */
        !          2048:   if (c >= 128 && c <= 159)
        !          2049:     {
        !          2050:       keyname[i++] = '\\';
        !          2051:       keyname[i++] = '2';
        !          2052:       c -= 128;
        !          2053:       keyname[i++] = (c / 8) + '0';
        !          2054:       c = (c % 8) + '0';
        !          2055:     }
        !          2056: 
        !          2057:   /* Now, if the character needs to be quoted with a backslash, do that. */
        !          2058:   if (c == '\\' || c == '"')
        !          2059:     keyname[i++] = '\\';
        !          2060: 
        !          2061:   /* Now add the key, terminate the string, and return it. */
        !          2062:   keyname[i++] = (char) c;
        !          2063:   keyname[i] = '\0';
        !          2064: 
        !          2065:   return keyname;
        !          2066: }
        !          2067: 
        !          2068: /* Return a NULL terminated array of strings which represent the key
        !          2069:    sequences that are used to invoke FUNCTION in MAP. */
        !          2070: char **
        !          2071: rl_invoking_keyseqs_in_map (function, map)
        !          2072:      rl_command_func_t *function;
        !          2073:      Keymap map;
        !          2074: {
        !          2075:   register int key;
        !          2076:   char **result;
        !          2077:   int result_index, result_size;
        !          2078: 
        !          2079:   result = (char **)NULL;
        !          2080:   result_index = result_size = 0;
        !          2081: 
        !          2082:   for (key = 0; key < KEYMAP_SIZE; key++)
        !          2083:     {
        !          2084:       switch (map[key].type)
        !          2085:        {
        !          2086:        case ISMACR:
        !          2087:          /* Macros match, if, and only if, the pointers are identical.
        !          2088:             Thus, they are treated exactly like functions in here. */
        !          2089:        case ISFUNC:
        !          2090:          /* If the function in the keymap is the one we are looking for,
        !          2091:             then add the current KEY to the list of invoking keys. */
        !          2092:          if (map[key].function == function)
        !          2093:            {
        !          2094:              char *keyname;
        !          2095: 
        !          2096:              keyname = _rl_get_keyname (key);
        !          2097: 
        !          2098:              if (result_index + 2 > result_size)
        !          2099:                {
        !          2100:                  result_size += 10;
        !          2101:                  result = (char **)xrealloc (result, result_size * sizeof (char *));
        !          2102:                }
        !          2103: 
        !          2104:              result[result_index++] = keyname;
        !          2105:              result[result_index] = (char *)NULL;
        !          2106:            }
        !          2107:          break;
        !          2108: 
        !          2109:        case ISKMAP:
        !          2110:          {
        !          2111:            char **seqs;
        !          2112:            register int i;
        !          2113: 
        !          2114:            /* Find the list of keyseqs in this map which have FUNCTION as
        !          2115:               their target.  Add the key sequences found to RESULT. */
        !          2116:            if (map[key].function)
        !          2117:              seqs =
        !          2118:                rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key));
        !          2119:            else
        !          2120:              break;
        !          2121: 
        !          2122:            if (seqs == 0)
        !          2123:              break;
        !          2124: 
        !          2125:            for (i = 0; seqs[i]; i++)
        !          2126:              {
        !          2127:                char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
        !          2128: 
        !          2129:                if (key == ESC)
        !          2130:                  {
        !          2131:                    /* If ESC is the meta prefix and we're converting chars
        !          2132:                       with the eighth bit set to ESC-prefixed sequences, then
        !          2133:                       we can use \M-.  Otherwise we need to use the sequence
        !          2134:                       for ESC. */
        !          2135:                    if (_rl_convert_meta_chars_to_ascii && map[ESC].type == ISKMAP)
        !          2136:                      sprintf (keyname, "\\M-");
        !          2137:                    else
        !          2138:                      sprintf (keyname, "\\e");
        !          2139:                  }
        !          2140:                else if (CTRL_CHAR (key))
        !          2141:                  sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key)));
        !          2142:                else if (key == RUBOUT)
        !          2143:                  sprintf (keyname, "\\C-?");
        !          2144:                else if (key == '\\' || key == '"')
        !          2145:                  {
        !          2146:                    keyname[0] = '\\';
        !          2147:                    keyname[1] = (char) key;
        !          2148:                    keyname[2] = '\0';
        !          2149:                  }
        !          2150:                else
        !          2151:                  {
        !          2152:                    keyname[0] = (char) key;
        !          2153:                    keyname[1] = '\0';
        !          2154:                  }
        !          2155:                
        !          2156:                strcat (keyname, seqs[i]);
        !          2157:                xfree (seqs[i]);
        !          2158: 
        !          2159:                if (result_index + 2 > result_size)
        !          2160:                  {
        !          2161:                    result_size += 10;
        !          2162:                    result = (char **)xrealloc (result, result_size * sizeof (char *));
        !          2163:                  }
        !          2164: 
        !          2165:                result[result_index++] = keyname;
        !          2166:                result[result_index] = (char *)NULL;
        !          2167:              }
        !          2168: 
        !          2169:            xfree (seqs);
        !          2170:          }
        !          2171:          break;
        !          2172:        }
        !          2173:     }
        !          2174:   return (result);
        !          2175: }
        !          2176: 
        !          2177: /* Return a NULL terminated array of strings which represent the key
        !          2178:    sequences that can be used to invoke FUNCTION using the current keymap. */
        !          2179: char **
        !          2180: rl_invoking_keyseqs (function)
        !          2181:      rl_command_func_t *function;
        !          2182: {
        !          2183:   return (rl_invoking_keyseqs_in_map (function, _rl_keymap));
        !          2184: }
        !          2185: 
        !          2186: /* Print all of the functions and their bindings to rl_outstream.  If
        !          2187:    PRINT_READABLY is non-zero, then print the output in such a way
        !          2188:    that it can be read back in. */
        !          2189: void
        !          2190: rl_function_dumper (print_readably)
        !          2191:      int print_readably;
        !          2192: {
        !          2193:   register int i;
        !          2194:   const char **names;
        !          2195:   const char *name;
        !          2196: 
        !          2197:   names = rl_funmap_names ();
        !          2198: 
        !          2199:   fprintf (rl_outstream, "\n");
        !          2200: 
        !          2201:   for (i = 0; name = names[i]; i++)
        !          2202:     {
        !          2203:       rl_command_func_t *function;
        !          2204:       char **invokers;
        !          2205: 
        !          2206:       function = rl_named_function (name);
        !          2207:       invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap);
        !          2208: 
        !          2209:       if (print_readably)
        !          2210:        {
        !          2211:          if (!invokers)
        !          2212:            fprintf (rl_outstream, "# %s (not bound)\n", name);
        !          2213:          else
        !          2214:            {
        !          2215:              register int j;
        !          2216: 
        !          2217:              for (j = 0; invokers[j]; j++)
        !          2218:                {
        !          2219:                  fprintf (rl_outstream, "\"%s\": %s\n",
        !          2220:                           invokers[j], name);
        !          2221:                  xfree (invokers[j]);
        !          2222:                }
        !          2223: 
        !          2224:              xfree (invokers);
        !          2225:            }
        !          2226:        }
        !          2227:       else
        !          2228:        {
        !          2229:          if (!invokers)
        !          2230:            fprintf (rl_outstream, "%s is not bound to any keys\n",
        !          2231:                     name);
        !          2232:          else
        !          2233:            {
        !          2234:              register int j;
        !          2235: 
        !          2236:              fprintf (rl_outstream, "%s can be found on ", name);
        !          2237: 
        !          2238:              for (j = 0; invokers[j] && j < 5; j++)
        !          2239:                {
        !          2240:                  fprintf (rl_outstream, "\"%s\"%s", invokers[j],
        !          2241:                           invokers[j + 1] ? ", " : ".\n");
        !          2242:                }
        !          2243: 
        !          2244:              if (j == 5 && invokers[j])
        !          2245:                fprintf (rl_outstream, "...\n");
        !          2246: 
        !          2247:              for (j = 0; invokers[j]; j++)
        !          2248:                xfree (invokers[j]);
        !          2249: 
        !          2250:              xfree (invokers);
        !          2251:            }
        !          2252:        }
        !          2253:     }
        !          2254: 
        !          2255:   xfree (names);
        !          2256: }
        !          2257: 
        !          2258: /* Print all of the current functions and their bindings to
        !          2259:    rl_outstream.  If an explicit argument is given, then print
        !          2260:    the output in such a way that it can be read back in. */
        !          2261: int
        !          2262: rl_dump_functions (count, key)
        !          2263:      int count, key;
        !          2264: {
        !          2265:   if (rl_dispatching)
        !          2266:     fprintf (rl_outstream, "\r\n");
        !          2267:   rl_function_dumper (rl_explicit_arg);
        !          2268:   rl_on_new_line ();
        !          2269:   return (0);
        !          2270: }
        !          2271: 
        !          2272: static void
        !          2273: _rl_macro_dumper_internal (print_readably, map, prefix)
        !          2274:      int print_readably;
        !          2275:      Keymap map;
        !          2276:      char *prefix;
        !          2277: {
        !          2278:   register int key;
        !          2279:   char *keyname, *out;
        !          2280:   int prefix_len;
        !          2281: 
        !          2282:   for (key = 0; key < KEYMAP_SIZE; key++)
        !          2283:     {
        !          2284:       switch (map[key].type)
        !          2285:        {
        !          2286:        case ISMACR:
        !          2287:          keyname = _rl_get_keyname (key);
        !          2288:          out = _rl_untranslate_macro_value ((char *)map[key].function, 0);
        !          2289: 
        !          2290:          if (print_readably)
        !          2291:            fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
        !          2292:                                                         keyname,
        !          2293:                                                         out ? out : "");
        !          2294:          else
        !          2295:            fprintf (rl_outstream, "%s%s outputs %s\n", prefix ? prefix : "",
        !          2296:                                                        keyname,
        !          2297:                                                        out ? out : "");
        !          2298:          xfree (keyname);
        !          2299:          xfree (out);
        !          2300:          break;
        !          2301:        case ISFUNC:
        !          2302:          break;
        !          2303:        case ISKMAP:
        !          2304:          prefix_len = prefix ? strlen (prefix) : 0;
        !          2305:          if (key == ESC)
        !          2306:            {
        !          2307:              keyname = (char *)xmalloc (3 + prefix_len);
        !          2308:              if (prefix)
        !          2309:                strcpy (keyname, prefix);
        !          2310:              keyname[prefix_len] = '\\';
        !          2311:              keyname[prefix_len + 1] = 'e';
        !          2312:              keyname[prefix_len + 2] = '\0';
        !          2313:            }
        !          2314:          else
        !          2315:            {
        !          2316:              keyname = _rl_get_keyname (key);
        !          2317:              if (prefix)
        !          2318:                {
        !          2319:                  out = (char *)xmalloc (strlen (keyname) + prefix_len + 1);
        !          2320:                  strcpy (out, prefix);
        !          2321:                  strcpy (out + prefix_len, keyname);
        !          2322:                  xfree (keyname);
        !          2323:                  keyname = out;
        !          2324:                }
        !          2325:            }
        !          2326: 
        !          2327:          _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname);
        !          2328:          xfree (keyname);
        !          2329:          break;
        !          2330:        }
        !          2331:     }
        !          2332: }
        !          2333: 
        !          2334: void
        !          2335: rl_macro_dumper (print_readably)
        !          2336:      int print_readably;
        !          2337: {
        !          2338:   _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL);
        !          2339: }
        !          2340: 
        !          2341: int
        !          2342: rl_dump_macros (count, key)
        !          2343:      int count, key;
        !          2344: {
        !          2345:   if (rl_dispatching)
        !          2346:     fprintf (rl_outstream, "\r\n");
        !          2347:   rl_macro_dumper (rl_explicit_arg);
        !          2348:   rl_on_new_line ();
        !          2349:   return (0);
        !          2350: }
        !          2351: 
        !          2352: static char *
        !          2353: _rl_get_string_variable_value (name)
        !          2354:      const char *name;
        !          2355: {
        !          2356:   static char numbuf[32];
        !          2357:   char *ret;
        !          2358: 
        !          2359:   if (_rl_stricmp (name, "bell-style") == 0)
        !          2360:     {
        !          2361:       switch (_rl_bell_preference)
        !          2362:        {
        !          2363:          case NO_BELL:
        !          2364:            return "none";
        !          2365:          case VISIBLE_BELL:
        !          2366:            return "visible";
        !          2367:          case AUDIBLE_BELL:
        !          2368:          default:
        !          2369:            return "audible";
        !          2370:        }
        !          2371:     }
        !          2372:   else if (_rl_stricmp (name, "comment-begin") == 0)
        !          2373:     return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
        !          2374:   else if (_rl_stricmp (name, "completion-display-width") == 0)
        !          2375:     {
        !          2376:       sprintf (numbuf, "%d", _rl_completion_columns);
        !          2377:       return (numbuf);
        !          2378:     }
        !          2379:   else if (_rl_stricmp (name, "completion-prefix-display-length") == 0)
        !          2380:     {
        !          2381:       sprintf (numbuf, "%d", _rl_completion_prefix_display_length);
        !          2382:       return (numbuf);
        !          2383:     }
        !          2384:   else if (_rl_stricmp (name, "completion-query-items") == 0)
        !          2385:     {
        !          2386:       sprintf (numbuf, "%d", rl_completion_query_items);
        !          2387:       return (numbuf);
        !          2388:     }
        !          2389:   else if (_rl_stricmp (name, "editing-mode") == 0)
        !          2390:     return (rl_get_keymap_name_from_edit_mode ());
        !          2391:   else if (_rl_stricmp (name, "history-size") == 0)
        !          2392:     {
        !          2393:       sprintf (numbuf, "%d", history_is_stifled() ? history_max_entries : 0);
        !          2394:       return (numbuf);
        !          2395:     }
        !          2396:   else if (_rl_stricmp (name, "isearch-terminators") == 0)
        !          2397:     {
        !          2398:       if (_rl_isearch_terminators == 0)
        !          2399:        return 0;
        !          2400:       ret = _rl_untranslate_macro_value (_rl_isearch_terminators, 0);
        !          2401:       if (ret)
        !          2402:        {
        !          2403:          strncpy (numbuf, ret, sizeof (numbuf) - 1);
        !          2404:          xfree (ret);
        !          2405:          numbuf[sizeof(numbuf) - 1] = '\0';
        !          2406:        }
        !          2407:       else
        !          2408:        numbuf[0] = '\0';
        !          2409:       return numbuf;
        !          2410:     }
        !          2411:   else if (_rl_stricmp (name, "keymap") == 0)
        !          2412:     {
        !          2413:       ret = rl_get_keymap_name (_rl_keymap);
        !          2414:       if (ret == 0)
        !          2415:        ret = rl_get_keymap_name_from_edit_mode ();
        !          2416:       return (ret ? ret : "none");
        !          2417:     }
        !          2418:   else if (_rl_stricmp (name, "keyseq-timeout") == 0)
        !          2419:     {
        !          2420:       sprintf (numbuf, "%d", _rl_keyseq_timeout);    
        !          2421:       return (numbuf);
        !          2422:     }
        !          2423:   else
        !          2424:     return (0);
        !          2425: }
        !          2426: 
        !          2427: void
        !          2428: rl_variable_dumper (print_readably)
        !          2429:      int print_readably;
        !          2430: {
        !          2431:   int i;
        !          2432:   char *v;
        !          2433: 
        !          2434:   for (i = 0; boolean_varlist[i].name; i++)
        !          2435:     {
        !          2436:       if (print_readably)
        !          2437:         fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name,
        !          2438:                               *boolean_varlist[i].value ? "on" : "off");
        !          2439:       else
        !          2440:         fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name,
        !          2441:                               *boolean_varlist[i].value ? "on" : "off");
        !          2442:     }
        !          2443: 
        !          2444:   for (i = 0; string_varlist[i].name; i++)
        !          2445:     {
        !          2446:       v = _rl_get_string_variable_value (string_varlist[i].name);
        !          2447:       if (v == 0)      /* _rl_isearch_terminators can be NULL */
        !          2448:        continue;
        !          2449:       if (print_readably)
        !          2450:         fprintf (rl_outstream, "set %s %s\n", string_varlist[i].name, v);
        !          2451:       else
        !          2452:         fprintf (rl_outstream, "%s is set to `%s'\n", string_varlist[i].name, v);
        !          2453:     }
        !          2454: }
        !          2455: 
        !          2456: /* Print all of the current variables and their values to
        !          2457:    rl_outstream.  If an explicit argument is given, then print
        !          2458:    the output in such a way that it can be read back in. */
        !          2459: int
        !          2460: rl_dump_variables (count, key)
        !          2461:      int count, key;
        !          2462: {
        !          2463:   if (rl_dispatching)
        !          2464:     fprintf (rl_outstream, "\r\n");
        !          2465:   rl_variable_dumper (rl_explicit_arg);
        !          2466:   rl_on_new_line ();
        !          2467:   return (0);
        !          2468: }
        !          2469: 
        !          2470: /* Return non-zero if any members of ARRAY are a substring in STRING. */
        !          2471: static int
        !          2472: substring_member_of_array (string, array)
        !          2473:      const char *string;
        !          2474:      const char * const *array;
        !          2475: {
        !          2476:   while (*array)
        !          2477:     {
        !          2478:       if (_rl_strindex (string, *array))
        !          2479:        return (1);
        !          2480:       array++;
        !          2481:     }
        !          2482:   return (0);
        !          2483: }

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