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