Annotation of embedaddon/readline/bind.c, revision 1.1.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, ¯o_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>