|
|
1.1 root 1: /* readline.c -- a general facility for reading lines of input
2: with emacs style editing and completion. */
3:
4: /* Copyright 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
5:
6: This file contains the Readline Library (the Library), a set of
7: routines for providing Emacs style line input to programs that ask
8: for it.
9:
10: The Library is free software; you can redistribute it and/or modify
11: it under the terms of the GNU General Public License as published by
12: the Free Software Foundation; either version 2 of the License, or
13: (at your option) any later version.
14:
15: The Library is distributed in the hope that it will be useful,
16: but WITHOUT ANY WARRANTY; without even the implied warranty of
17: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: GNU General Public License for more details.
19:
20: You should have received a copy of the GNU General Public License
21: along with this program; if not, write to the Free Software
22: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23:
24: /* Remove these declarations when we have a complete libgnu.a. */
25: /* #define STATIC_MALLOC */
26: #if !defined (STATIC_MALLOC)
27: extern char *xmalloc (), *xrealloc ();
28: #else
29: static char *xmalloc (), *xrealloc ();
30: #endif /* STATIC_MALLOC */
31:
32: #include "sysdep.h"
33: #include <sys/types.h>
34: #include <stdio.h>
35: #include <fcntl.h>
36: #ifndef NO_SYS_FILE
37: #include <sys/file.h>
38: #endif
39: #include <signal.h>
40:
41: #if defined (HAVE_UNISTD_H)
42: # include <unistd.h>
43: #endif
44:
45: #define NEW_TTY_DRIVER
46: #define HAVE_BSD_SIGNALS
47: /* #define USE_XON_XOFF */
48:
49: #ifdef __MSDOS__
50: #undef NEW_TTY_DRIVER
51: #undef HAVE_BSD_SIGNALS
52: #endif
53:
54: /* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */
55: #if defined (USG) && !defined (hpux)
56: #undef HAVE_BSD_SIGNALS
57: #endif
58:
59: /* System V machines use termio. */
60: #if !defined (_POSIX_VERSION)
61: # if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || defined (DGUX)
62: # undef NEW_TTY_DRIVER
63: # define TERMIO_TTY_DRIVER
64: # include <termio.h>
65: # if !defined (TCOON)
66: # define TCOON 1
67: # endif
68: # endif /* USG || hpux || Xenix || sgi || DUGX */
69: #endif /* !_POSIX_VERSION */
70:
71: /* Posix systems use termios and the Posix signal functions. */
72: #if defined (_POSIX_VERSION)
73: # if !defined (TERMIOS_MISSING)
74: # undef NEW_TTY_DRIVER
75: # define TERMIOS_TTY_DRIVER
76: # include <termios.h>
77: # endif /* !TERMIOS_MISSING */
78: # define HAVE_POSIX_SIGNALS
79: # if !defined (O_NDELAY)
80: # define O_NDELAY O_NONBLOCK /* Posix-style non-blocking i/o */
81: # endif /* O_NDELAY */
82: #endif /* _POSIX_VERSION */
83:
84: /* Other (BSD) machines use sgtty. */
85: #if defined (NEW_TTY_DRIVER)
86: #include <sgtty.h>
87: #endif
88:
89: /* Define _POSIX_VDISABLE if we are not using the `new' tty driver and
90: it is not already defined. It is used both to determine if a
91: special character is disabled and to disable certain special
92: characters. Posix systems should set to 0, USG systems to -1. */
93: #if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)
94: # if defined (_POSIX_VERSION)
95: # define _POSIX_VDISABLE 0
96: # else /* !_POSIX_VERSION */
97: # define _POSIX_VDISABLE -1
98: # endif /* !_POSIX_VERSION */
99: #endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
100:
101: /* Define some macros for dealing with assorted signalling disciplines.
102:
103: These macros provide a way to use signal blocking and disabling
104: without smothering your code in a pile of #ifdef's.
105:
106: SIGNALS_UNBLOCK; Stop blocking all signals.
107:
108: {
109: SIGNALS_DECLARE_SAVED (name); Declare a variable to save the
110: signal blocking state.
111: ...
112: SIGNALS_BLOCK (SIGSTOP, name); Block a signal, and save the previous
113: state for restoration later.
114: ...
115: SIGNALS_RESTORE (name); Restore previous signals.
116: }
117:
118: */
119:
120: #ifdef HAVE_POSIX_SIGNALS
121: /* POSIX signals */
122:
123: #define SIGNALS_UNBLOCK \
124: do { sigset_t set; \
125: sigemptyset (&set); \
126: sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL); \
127: } while (0)
128:
129: #define SIGNALS_DECLARE_SAVED(name) sigset_t name
130:
131: #define SIGNALS_BLOCK(SIG, saved) \
132: do { sigset_t set; \
133: sigemptyset (&set); \
134: sigaddset (&set, SIG); \
135: sigprocmask (SIG_BLOCK, &set, &saved); \
136: } while (0)
137:
138: #define SIGNALS_RESTORE(saved) \
139: sigprocmask (SIG_SETMASK, &saved, (sigset_t *)NULL)
140:
141:
142: #else /* HAVE_POSIX_SIGNALS */
143: #ifdef HAVE_BSD_SIGNALS
144: /* BSD signals */
145:
146: #define SIGNALS_UNBLOCK sigsetmask (0)
147: #define SIGNALS_DECLARE_SAVED(name) int name
148: #define SIGNALS_BLOCK(SIG, saved) saved = sigblock (sigmask (SIG))
149: #define SIGNALS_RESTORE(saved) sigsetmask (saved)
150:
151:
152: #else /* HAVE_BSD_SIGNALS */
153: /* None of the Above */
154:
155: #define SIGNALS_UNBLOCK /* nothing */
156: #define SIGNALS_DECLARE_SAVED(name) /* nothing */
157: #define SIGNALS_BLOCK(SIG, saved) /* nothing */
158: #define SIGNALS_RESTORE(saved) /* nothing */
159:
160:
161: #endif /* HAVE_BSD_SIGNALS */
162: #endif /* HAVE_POSIX_SIGNALS */
163:
164: /* End of signal handling definitions. */
165:
166:
167: #include <errno.h>
168: extern int errno;
169:
170: #include <setjmp.h>
171: #include <sys/stat.h>
172:
173: /* Posix macro to check file in statbuf for directory-ness. */
174: #if defined (S_IFDIR) && !defined (S_ISDIR)
175: #define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
176: #endif
177:
178: #ifndef __MSDOS__
179: /* These next are for filename completion. Perhaps this belongs
180: in a different place. */
181: #include <pwd.h>
182: #endif /* __MSDOS__ */
183:
184: #if defined (USG) && !defined (isc386) && !defined (sgi)
185: struct passwd *getpwuid (), *getpwent ();
186: #endif
187:
188: /* #define HACK_TERMCAP_MOTION */
189:
190: /* Some standard library routines. */
191: #include "readline.h"
192: #include "history.h"
193:
194: #ifndef digit
195: #define digit(c) ((c) >= '0' && (c) <= '9')
196: #endif
197:
198: #ifndef isletter
199: #define isletter(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
200: #endif
201:
202: #ifndef digit_value
203: #define digit_value(c) ((c) - '0')
204: #endif
205:
206: #ifndef member
207: #define member(c, s) ((c) ? index ((s), (c)) : 0)
208: #endif
209:
210: #ifndef isident
211: #define isident(c) ((isletter(c) || digit(c) || c == '_'))
212: #endif
213:
214: #ifndef exchange
215: #define exchange(x, y) {int temp = x; x = y; y = temp;}
216: #endif
217:
218: #if !defined (rindex)
219: extern char *rindex ();
220: #endif /* rindex */
221:
222: #if !defined (index)
223: extern char *index ();
224: #endif /* index */
225:
226: extern char *getenv ();
227: extern char *tilde_expand ();
228:
229: static update_line ();
230: static void output_character_function ();
231: static delete_chars ();
232: static void insert_some_chars ();
233:
234: #if defined (VOID_SIGHANDLER)
235: # define sighandler void
236: #else
237: # define sighandler int
238: #endif /* VOID_SIGHANDLER */
239:
240: /* This typedef is equivalant to the one for Function; it allows us
241: to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
242: typedef sighandler SigHandler ();
243:
244: /* If on, then readline handles signals in a way that doesn't screw. */
245: #define HANDLE_SIGNALS
246:
247: #ifdef __GO32__
248: #include <sys/pc.h>
249: #undef HANDLE_SIGNALS
250: #endif
251:
252:
253: /* **************************************************************** */
254: /* */
255: /* Line editing input utility */
256: /* */
257: /* **************************************************************** */
258:
259: /* A pointer to the keymap that is currently in use.
260: By default, it is the standard emacs keymap. */
261: Keymap keymap = emacs_standard_keymap;
262:
263: #define no_mode -1
264: #define vi_mode 0
265: #define emacs_mode 1
266:
267: /* The current style of editing. */
268: int rl_editing_mode = emacs_mode;
269:
270: /* Non-zero if the previous command was a kill command. */
271: static int last_command_was_kill = 0;
272:
273: /* The current value of the numeric argument specified by the user. */
274: int rl_numeric_arg = 1;
275:
276: /* Non-zero if an argument was typed. */
277: int rl_explicit_arg = 0;
278:
279: /* Temporary value used while generating the argument. */
280: int rl_arg_sign = 1;
281:
282: /* Non-zero means we have been called at least once before. */
283: static int rl_initialized = 0;
284:
285: /* If non-zero, this program is running in an EMACS buffer. */
286: static char *running_in_emacs = (char *)NULL;
287:
288: /* The current offset in the current input line. */
289: int rl_point;
290:
291: /* Mark in the current input line. */
292: int rl_mark;
293:
294: /* Length of the current input line. */
295: int rl_end;
296:
297: /* Make this non-zero to return the current input_line. */
298: int rl_done;
299:
300: /* The last function executed by readline. */
301: Function *rl_last_func = (Function *)NULL;
302:
303: /* Top level environment for readline_internal (). */
304: static jmp_buf readline_top_level;
305:
306: /* The streams we interact with. */
307: static FILE *in_stream, *out_stream;
308:
309: /* The names of the streams that we do input and output to. */
310: FILE *rl_instream, *rl_outstream;
311:
312: /* Non-zero means echo characters as they are read. */
313: int readline_echoing_p = 1;
314:
315: /* Current prompt. */
316: char *rl_prompt;
317:
318: /* The number of characters read in order to type this complete command. */
319: int rl_key_sequence_length = 0;
320:
321: /* If non-zero, then this is the address of a function to call just
322: before readline_internal () prints the first prompt. */
323: Function *rl_startup_hook = (Function *)NULL;
324:
325: /* If non-zero, then this is the address of a function to call when
326: completing on a directory name. The function is called with
327: the address of a string (the current directory name) as an arg. */
328: Function *rl_symbolic_link_hook = (Function *)NULL;
329:
330: /* What we use internally. You should always refer to RL_LINE_BUFFER. */
331: static char *the_line;
332:
333: /* The character that can generate an EOF. Really read from
334: the terminal driver... just defaulted here. */
335: static int eof_char = CTRL ('D');
336:
337: /* Non-zero makes this the next keystroke to read. */
338: int rl_pending_input = 0;
339:
340: /* Pointer to a useful terminal name. */
341: char *rl_terminal_name = (char *)NULL;
342:
343: /* Line buffer and maintenence. */
344: char *rl_line_buffer = (char *)NULL;
345: int rl_line_buffer_len = 0;
346: #define DEFAULT_BUFFER_SIZE 256
347:
348:
349: /* **************************************************************** */
350: /* */
351: /* `Forward' declarations */
352: /* */
353: /* **************************************************************** */
354:
355: /* Non-zero means do not parse any lines other than comments and
356: parser directives. */
357: static unsigned char parsing_conditionalized_out = 0;
358:
359: /* Caseless strcmp (). */
360: static int stricmp (), strnicmp ();
361: static char *strpbrk ();
362:
363: /* Non-zero means to save keys that we dispatch on in a kbd macro. */
364: static int defining_kbd_macro = 0;
365:
366:
367: /* **************************************************************** */
368: /* */
369: /* Top Level Functions */
370: /* */
371: /* **************************************************************** */
372:
373: static void rl_prep_terminal (), rl_deprep_terminal ();
374: static void clear_to_eol (), rl_generic_bind ();
375:
376: /* Read a line of input. Prompt with PROMPT. A NULL PROMPT means
377: none. A return value of NULL means that EOF was encountered. */
378: char *
379: readline (prompt)
380: char *prompt;
381: {
382: char *readline_internal ();
383: char *value;
384:
385: rl_prompt = prompt;
386:
387: /* If we are at EOF return a NULL string. */
388: if (rl_pending_input == EOF)
389: {
390: rl_pending_input = 0;
391: return ((char *)NULL);
392: }
393:
394: rl_initialize ();
395: rl_prep_terminal ();
396:
397: #if defined (HANDLE_SIGNALS)
398: rl_set_signals ();
399: #endif
400:
401: value = readline_internal ();
402: rl_deprep_terminal ();
403:
404: #if defined (HANDLE_SIGNALS)
405: rl_clear_signals ();
406: #endif
407:
408: return (value);
409: }
410:
411: /* Read a line of input from the global rl_instream, doing output on
412: the global rl_outstream.
413: If rl_prompt is non-null, then that is our prompt. */
414: char *
415: readline_internal ()
416: {
417: int lastc, c, eof_found;
418:
419: in_stream = rl_instream;
420: out_stream = rl_outstream;
421:
422: lastc = -1;
423: eof_found = 0;
424:
425: if (rl_startup_hook)
426: (*rl_startup_hook) ();
427:
428: if (!readline_echoing_p)
429: {
430: if (rl_prompt)
431: {
432: fprintf (out_stream, "%s", rl_prompt);
433: fflush (out_stream);
434: }
435: }
436: else
437: {
438: rl_on_new_line ();
439: rl_redisplay ();
440: #if defined (VI_MODE)
441: if (rl_editing_mode == vi_mode)
442: rl_vi_insertion_mode ();
443: #endif /* VI_MODE */
444: }
445:
446: while (!rl_done)
447: {
448: int lk = last_command_was_kill;
449: int code = setjmp (readline_top_level);
450:
451: if (code)
452: rl_redisplay ();
453:
454: if (!rl_pending_input)
455: {
456: /* Then initialize the argument and number of keys read. */
457: rl_init_argument ();
458: rl_key_sequence_length = 0;
459: }
460:
461: c = rl_read_key ();
462:
463: /* EOF typed to a non-blank line is a <NL>. */
464: if (c == EOF && rl_end)
465: c = NEWLINE;
466:
467: /* The character eof_char typed to blank line, and not as the
468: previous character is interpreted as EOF. */
469: if (((c == eof_char && lastc != c) || c == EOF) && !rl_end)
470: {
471: eof_found = 1;
472: break;
473: }
474:
475: lastc = c;
476: rl_dispatch (c, keymap);
477:
478: /* If there was no change in last_command_was_kill, then no kill
479: has taken place. Note that if input is pending we are reading
480: a prefix command, so nothing has changed yet. */
481: if (!rl_pending_input)
482: {
483: if (lk == last_command_was_kill)
484: last_command_was_kill = 0;
485: }
486:
487: #if defined (VI_MODE)
488: /* In vi mode, when you exit insert mode, the cursor moves back
489: over the previous character. We explicitly check for that here. */
490: if (rl_editing_mode == vi_mode && keymap == vi_movement_keymap)
491: rl_vi_check ();
492: #endif /* VI_MODE */
493:
494: if (!rl_done)
495: rl_redisplay ();
496: }
497:
498: /* Restore the original of this history line, iff the line that we
499: are editing was originally in the history, AND the line has changed. */
500: {
501: HIST_ENTRY *entry = current_history ();
502:
503: if (entry && rl_undo_list)
504: {
505: char *temp = savestring (the_line);
506: rl_revert_line ();
507: entry = replace_history_entry (where_history (), the_line,
508: (HIST_ENTRY *)NULL);
509: free_history_entry (entry);
510:
511: strcpy (the_line, temp);
512: free (temp);
513: }
514: }
515:
516: /* At any rate, it is highly likely that this line has an undo list. Get
517: rid of it now. */
518: if (rl_undo_list)
519: free_undo_list ();
520:
521: if (eof_found)
522: return (char *)NULL;
523: else
524: return (savestring (the_line));
525: }
526:
527:
528: /* **************************************************************** */
529: /* */
530: /* Signal Handling */
531: /* */
532: /* **************************************************************** */
533:
534: #if defined (SIGWINCH)
535: static SigHandler *old_sigwinch = (SigHandler *)NULL;
536:
537: static sighandler
538: rl_handle_sigwinch (sig)
539: int sig;
540: {
541: char *term;
542:
543: term = rl_terminal_name;
544:
545: if (readline_echoing_p)
546: {
547: if (!term)
548: term = getenv ("TERM");
549: if (!term)
550: term = "dumb";
551: rl_reset_terminal (term);
552: #if defined (NOTDEF)
553: crlf ();
554: rl_forced_update_display ();
555: #endif /* NOTDEF */
556: }
557:
558: if (old_sigwinch &&
559: old_sigwinch != (SigHandler *)SIG_IGN &&
560: old_sigwinch != (SigHandler *)SIG_DFL)
561: (*old_sigwinch) (sig);
562: #if !defined (VOID_SIGHANDLER)
563: return (0);
564: #endif /* VOID_SIGHANDLER */
565: }
566: #endif /* SIGWINCH */
567:
568: #if defined (HANDLE_SIGNALS)
569: /* Interrupt handling. */
570: static SigHandler
571: *old_int = (SigHandler *)NULL,
572: *old_tstp = (SigHandler *)NULL,
573: *old_ttou = (SigHandler *)NULL,
574: *old_ttin = (SigHandler *)NULL,
575: *old_cont = (SigHandler *)NULL,
576: *old_alrm = (SigHandler *)NULL;
577:
578: /* Handle an interrupt character. */
579: static sighandler
580: rl_signal_handler (sig)
581: int sig;
582: {
583: #if !defined (HAVE_BSD_SIGNALS)
584: /* Since the signal will not be blocked while we are in the signal
585: handler, ignore it until rl_clear_signals resets the catcher. */
586: if (sig == SIGINT)
587: signal (sig, SIG_IGN);
588: #endif /* !HAVE_BSD_SIGNALS */
589:
590: switch (sig)
591: {
592: case SIGINT:
593: free_undo_list ();
594: rl_clear_message ();
595: rl_init_argument ();
596:
597: #if defined (SIGTSTP)
598: case SIGTSTP:
599: case SIGTTOU:
600: case SIGTTIN:
601: #endif /* SIGTSTP */
602: case SIGALRM:
603: rl_clean_up_for_exit ();
604: rl_deprep_terminal ();
605: rl_clear_signals ();
606: rl_pending_input = 0;
607:
608: kill (getpid (), sig);
609:
610: SIGNALS_UNBLOCK;
611:
612: rl_prep_terminal ();
613: rl_set_signals ();
614: }
615:
616: #if !defined (VOID_SIGHANDLER)
617: return (0);
618: #endif /* !VOID_SIGHANDLER */
619: }
620:
621: rl_set_signals ()
622: {
623: old_int = (SigHandler *)signal (SIGINT, rl_signal_handler);
624: if (old_int == (SigHandler *)SIG_IGN)
625: signal (SIGINT, SIG_IGN);
626:
627: old_alrm = (SigHandler *)signal (SIGALRM, rl_signal_handler);
628: if (old_alrm == (SigHandler *)SIG_IGN)
629: signal (SIGALRM, SIG_IGN);
630:
631: #if defined (SIGTSTP)
632: old_tstp = (SigHandler *)signal (SIGTSTP, rl_signal_handler);
633: if (old_tstp == (SigHandler *)SIG_IGN)
634: signal (SIGTSTP, SIG_IGN);
635: #endif
636: #if defined (SIGTTOU)
637: old_ttou = (SigHandler *)signal (SIGTTOU, rl_signal_handler);
638: old_ttin = (SigHandler *)signal (SIGTTIN, rl_signal_handler);
639:
640: if (old_tstp == (SigHandler *)SIG_IGN)
641: {
642: signal (SIGTTOU, SIG_IGN);
643: signal (SIGTTIN, SIG_IGN);
644: }
645: #endif
646:
647: #if defined (SIGWINCH)
648: old_sigwinch = (SigHandler *)signal (SIGWINCH, rl_handle_sigwinch);
649: #endif
650: }
651:
652: rl_clear_signals ()
653: {
654: signal (SIGINT, old_int);
655: signal (SIGALRM, old_alrm);
656:
657: #if defined (SIGTSTP)
658: signal (SIGTSTP, old_tstp);
659: #endif
660:
661: #if defined (SIGTTOU)
662: signal (SIGTTOU, old_ttou);
663: signal (SIGTTIN, old_ttin);
664: #endif
665:
666: #if defined (SIGWINCH)
667: signal (SIGWINCH, old_sigwinch);
668: #endif
669: }
670: #endif /* HANDLE_SIGNALS */
671:
672:
673: /* **************************************************************** */
674: /* */
675: /* Character Input Buffering */
676: /* */
677: /* **************************************************************** */
678:
679: #if defined (USE_XON_XOFF)
680: /* If the terminal was in xoff state when we got to it, then xon_char
681: contains the character that is supposed to start it again. */
682: static int xon_char, xoff_state;
683: #endif /* USE_XON_XOFF */
684:
685: static int pop_index = 0, push_index = 0, ibuffer_len = 511;
686: static unsigned char ibuffer[512];
687:
688: /* Non-null means it is a pointer to a function to run while waiting for
689: character input. */
690: Function *rl_event_hook = (Function *)NULL;
691:
692: #define any_typein (push_index != pop_index)
693:
694: /* Add KEY to the buffer of characters to be read. */
695: rl_stuff_char (key)
696: int key;
697: {
698: if (key == EOF)
699: {
700: key = NEWLINE;
701: rl_pending_input = EOF;
702: }
703: ibuffer[push_index++] = key;
704: if (push_index >= ibuffer_len)
705: push_index = 0;
706: }
707:
708: /* Return the amount of space available in the
709: buffer for stuffing characters. */
710: int
711: ibuffer_space ()
712: {
713: if (pop_index > push_index)
714: return (pop_index - push_index);
715: else
716: return (ibuffer_len - (push_index - pop_index));
717: }
718:
719: /* Get a key from the buffer of characters to be read.
720: Return the key in KEY.
721: Result is KEY if there was a key, or 0 if there wasn't. */
722: int
723: rl_get_char (key)
724: int *key;
725: {
726: if (push_index == pop_index)
727: return (0);
728:
729: *key = ibuffer[pop_index++];
730:
731: if (pop_index >= ibuffer_len)
732: pop_index = 0;
733:
734: return (1);
735: }
736:
737: /* Stuff KEY into the *front* of the input buffer.
738: Returns non-zero if successful, zero if there is
739: no space left in the buffer. */
740: int
741: rl_unget_char (key)
742: int key;
743: {
744: if (ibuffer_space ())
745: {
746: pop_index--;
747: if (pop_index < 0)
748: pop_index = ibuffer_len - 1;
749: ibuffer[pop_index] = key;
750: return (1);
751: }
752: return (0);
753: }
754:
755: /* If a character is available to be read, then read it
756: and stuff it into IBUFFER. Otherwise, just return. */
757: rl_gather_tyi ()
758: {
759: #ifdef __GO32__
760: char input;
761: if (isatty(0))
762: {
763: int i = rl_getc();
764: if (i != EOF)
765: rl_stuff_char(i);
766: }
767: else
768: if (kbhit() && ibuffer_space())
769: rl_stuff_char(getkey());
770: #else
771: int tty = fileno (in_stream);
772: register int tem, result = -1;
773: long chars_avail;
774: char input;
775:
776: #if defined (FIONREAD)
777: result = ioctl (tty, FIONREAD, &chars_avail);
778: #endif
779:
780: if (result == -1)
781: {
782: int flags;
783:
784: flags = fcntl (tty, F_GETFL, 0);
785:
786: fcntl (tty, F_SETFL, (flags | O_NDELAY));
787: chars_avail = read (tty, &input, 1);
788:
789: fcntl (tty, F_SETFL, flags);
790: if (chars_avail == -1 && errno == EAGAIN)
791: return;
792: }
793:
794: /* If there's nothing available, don't waste time trying to read
795: something. */
796: if (chars_avail == 0)
797: return;
798:
799: tem = ibuffer_space ();
800:
801: if (chars_avail > tem)
802: chars_avail = tem;
803:
804: /* One cannot read all of the available input. I can only read a single
805: character at a time, or else programs which require input can be
806: thwarted. If the buffer is larger than one character, I lose.
807: Damn! */
808: if (tem < ibuffer_len)
809: chars_avail = 0;
810:
811: if (result != -1)
812: {
813: while (chars_avail--)
814: rl_stuff_char (rl_getc (in_stream));
815: }
816: else
817: {
818: if (chars_avail)
819: rl_stuff_char (input);
820: }
821: #endif /* def __GO32__/else */
822: }
823:
824: static int next_macro_key ();
825: /* Read a key, including pending input. */
826: int
827: rl_read_key ()
828: {
829: int c;
830:
831: rl_key_sequence_length++;
832:
833: if (rl_pending_input)
834: {
835: c = rl_pending_input;
836: rl_pending_input = 0;
837: }
838: else
839: {
840: /* If input is coming from a macro, then use that. */
841: if (c = next_macro_key ())
842: return (c);
843:
844: /* If the user has an event function, then call it periodically. */
845: if (rl_event_hook)
846: {
847: while (rl_event_hook && !rl_get_char (&c))
848: {
849: (*rl_event_hook) ();
850: rl_gather_tyi ();
851: }
852: }
853: else
854: {
855: if (!rl_get_char (&c))
856: c = rl_getc (in_stream);
857: }
858: }
859:
860: return (c);
861: }
862:
863: /* I'm beginning to hate the declaration rules for various compilers. */
864: static void add_macro_char (), with_macro_input ();
865:
866: /* Do the command associated with KEY in MAP.
867: If the associated command is really a keymap, then read
868: another key, and dispatch into that map. */
869: rl_dispatch (key, map)
870: register int key;
871: Keymap map;
872: {
873:
874: if (defining_kbd_macro)
875: add_macro_char (key);
876:
877: if (key > 127 && key < 256)
878: {
879: if (map[ESC].type == ISKMAP)
880: {
881: map = (Keymap)map[ESC].function;
882: key -= 128;
883: rl_dispatch (key, map);
884: }
885: else
886: ding ();
887: return;
888: }
889:
890: switch (map[key].type)
891: {
892: case ISFUNC:
893: {
894: Function *func = map[key].function;
895:
896: if (func != (Function *)NULL)
897: {
898: /* Special case rl_do_lowercase_version (). */
899: if (func == rl_do_lowercase_version)
900: {
901: rl_dispatch (to_lower (key), map);
902: return;
903: }
904:
905: (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
906:
907: /* If we have input pending, then the last command was a prefix
908: command. Don't change the state of rl_last_func. Otherwise,
909: remember the last command executed in this variable. */
910: if (!rl_pending_input)
911: rl_last_func = map[key].function;
912: }
913: else
914: {
915: rl_abort ();
916: return;
917: }
918: }
919: break;
920:
921: case ISKMAP:
922: if (map[key].function != (Function *)NULL)
923: {
924: int newkey;
925:
926: rl_key_sequence_length++;
927: newkey = rl_read_key ();
928: rl_dispatch (newkey, (Keymap)map[key].function);
929: }
930: else
931: {
932: rl_abort ();
933: return;
934: }
935: break;
936:
937: case ISMACR:
938: if (map[key].function != (Function *)NULL)
939: {
940: char *macro;
941:
942: macro = savestring ((char *)map[key].function);
943: with_macro_input (macro);
944: return;
945: }
946: break;
947: }
948: }
949:
950:
951: /* **************************************************************** */
952: /* */
953: /* Hacking Keyboard Macros */
954: /* */
955: /* **************************************************************** */
956:
957: /* The currently executing macro string. If this is non-zero,
958: then it is a malloc ()'ed string where input is coming from. */
959: static char *executing_macro = (char *)NULL;
960:
961: /* The offset in the above string to the next character to be read. */
962: static int executing_macro_index = 0;
963:
964: /* The current macro string being built. Characters get stuffed
965: in here by add_macro_char (). */
966: static char *current_macro = (char *)NULL;
967:
968: /* The size of the buffer allocated to current_macro. */
969: static int current_macro_size = 0;
970:
971: /* The index at which characters are being added to current_macro. */
972: static int current_macro_index = 0;
973:
974: /* A structure used to save nested macro strings.
975: It is a linked list of string/index for each saved macro. */
976: struct saved_macro {
977: struct saved_macro *next;
978: char *string;
979: int index;
980: };
981:
982: /* The list of saved macros. */
983: struct saved_macro *macro_list = (struct saved_macro *)NULL;
984:
985: /* Forward declarations of static functions. Thank you C. */
986: static void push_executing_macro (), pop_executing_macro ();
987:
988: /* This one has to be declared earlier in the file. */
989: /* static void add_macro_char (); */
990:
991: /* Set up to read subsequent input from STRING.
992: STRING is free ()'ed when we are done with it. */
993: static void
994: with_macro_input (string)
995: char *string;
996: {
997: push_executing_macro ();
998: executing_macro = string;
999: executing_macro_index = 0;
1000: }
1001:
1002: /* Return the next character available from a macro, or 0 if
1003: there are no macro characters. */
1004: static int
1005: next_macro_key ()
1006: {
1007: if (!executing_macro)
1008: return (0);
1009:
1010: if (!executing_macro[executing_macro_index])
1011: {
1012: pop_executing_macro ();
1013: return (next_macro_key ());
1014: }
1015:
1016: return (executing_macro[executing_macro_index++]);
1017: }
1018:
1019: /* Save the currently executing macro on a stack of saved macros. */
1020: static void
1021: push_executing_macro ()
1022: {
1023: struct saved_macro *saver;
1024:
1025: saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
1026: saver->next = macro_list;
1027: saver->index = executing_macro_index;
1028: saver->string = executing_macro;
1029:
1030: macro_list = saver;
1031: }
1032:
1033: /* Discard the current macro, replacing it with the one
1034: on the top of the stack of saved macros. */
1035: static void
1036: pop_executing_macro ()
1037: {
1038: if (executing_macro)
1039: free (executing_macro);
1040:
1041: executing_macro = (char *)NULL;
1042: executing_macro_index = 0;
1043:
1044: if (macro_list)
1045: {
1046: struct saved_macro *disposer = macro_list;
1047: executing_macro = macro_list->string;
1048: executing_macro_index = macro_list->index;
1049: macro_list = macro_list->next;
1050: free (disposer);
1051: }
1052: }
1053:
1054: /* Add a character to the macro being built. */
1055: static void
1056: add_macro_char (c)
1057: int c;
1058: {
1059: if (current_macro_index + 1 >= current_macro_size)
1060: {
1061: if (!current_macro)
1062: current_macro = (char *)xmalloc (current_macro_size = 25);
1063: else
1064: current_macro =
1065: (char *)xrealloc (current_macro, current_macro_size += 25);
1066: }
1067:
1068: current_macro[current_macro_index++] = c;
1069: current_macro[current_macro_index] = '\0';
1070: }
1071:
1072: /* Begin defining a keyboard macro.
1073: Keystrokes are recorded as they are executed.
1074: End the definition with rl_end_kbd_macro ().
1075: If a numeric argument was explicitly typed, then append this
1076: definition to the end of the existing macro, and start by
1077: re-executing the existing macro. */
1078: rl_start_kbd_macro (ignore1, ignore2)
1079: int ignore1, ignore2;
1080: {
1081: if (defining_kbd_macro)
1082: rl_abort ();
1083:
1084: if (rl_explicit_arg)
1085: {
1086: if (current_macro)
1087: with_macro_input (savestring (current_macro));
1088: }
1089: else
1090: current_macro_index = 0;
1091:
1092: defining_kbd_macro = 1;
1093: }
1094:
1095: /* Stop defining a keyboard macro.
1096: A numeric argument says to execute the macro right now,
1097: that many times, counting the definition as the first time. */
1098: rl_end_kbd_macro (count, ignore)
1099: int count, ignore;
1100: {
1101: if (!defining_kbd_macro)
1102: rl_abort ();
1103:
1104: current_macro_index -= (rl_key_sequence_length - 1);
1105: current_macro[current_macro_index] = '\0';
1106:
1107: defining_kbd_macro = 0;
1108:
1109: rl_call_last_kbd_macro (--count, 0);
1110: }
1111:
1112: /* Execute the most recently defined keyboard macro.
1113: COUNT says how many times to execute it. */
1114: rl_call_last_kbd_macro (count, ignore)
1115: int count, ignore;
1116: {
1117: if (!current_macro)
1118: rl_abort ();
1119:
1120: while (count--)
1121: with_macro_input (savestring (current_macro));
1122: }
1123:
1124:
1125: /* **************************************************************** */
1126: /* */
1127: /* Initializations */
1128: /* */
1129: /* **************************************************************** */
1130:
1131: /* Initliaze readline (and terminal if not already). */
1132: rl_initialize ()
1133: {
1134: extern char *rl_display_prompt;
1135:
1136: /* If we have never been called before, initialize the
1137: terminal and data structures. */
1138: if (!rl_initialized)
1139: {
1140: readline_initialize_everything ();
1141: rl_initialized++;
1142: }
1143:
1144: /* Initalize the current line information. */
1145: rl_point = rl_end = 0;
1146: the_line = rl_line_buffer;
1147: the_line[0] = 0;
1148:
1149: /* We aren't done yet. We haven't even gotten started yet! */
1150: rl_done = 0;
1151:
1152: /* Tell the history routines what is going on. */
1153: start_using_history ();
1154:
1155: /* Make the display buffer match the state of the line. */
1156: {
1157: extern char *rl_display_prompt;
1158: extern int forced_display;
1159:
1160: rl_on_new_line ();
1161:
1162: rl_display_prompt = rl_prompt ? rl_prompt : "";
1163: forced_display = 1;
1164: }
1165:
1166: /* No such function typed yet. */
1167: rl_last_func = (Function *)NULL;
1168:
1169: /* Parsing of key-bindings begins in an enabled state. */
1170: parsing_conditionalized_out = 0;
1171: }
1172:
1173: /* Initialize the entire state of the world. */
1174: readline_initialize_everything ()
1175: {
1176: /* Find out if we are running in Emacs. */
1177: running_in_emacs = getenv ("EMACS");
1178:
1179: /* Set up input and output if they aren't already. */
1180: if (!rl_instream)
1181: rl_instream = stdin;
1182: if (!rl_outstream)
1183: rl_outstream = stdout;
1184:
1185: /* Allocate data structures. */
1186: if (!rl_line_buffer)
1187: rl_line_buffer =
1188: (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE);
1189:
1190: /* Initialize the terminal interface. */
1191: init_terminal_io ((char *)NULL);
1192:
1193: /* Bind tty characters to readline functions. */
1194: readline_default_bindings ();
1195:
1196: /* Initialize the function names. */
1197: rl_initialize_funmap ();
1198:
1199: /* Read in the init file. */
1200: rl_read_init_file ((char *)NULL);
1201:
1202: /* If the completion parser's default word break characters haven't
1203: been set yet, then do so now. */
1204: {
1205: extern char *rl_completer_word_break_characters;
1206: extern char *rl_basic_word_break_characters;
1207:
1208: if (rl_completer_word_break_characters == (char *)NULL)
1209: rl_completer_word_break_characters = rl_basic_word_break_characters;
1210: }
1211: }
1212:
1213: /* If this system allows us to look at the values of the regular
1214: input editing characters, then bind them to their readline
1215: equivalents, iff the characters are not bound to keymaps. */
1216: readline_default_bindings ()
1217: {
1218: #ifndef __GO32__
1219:
1220: #if defined (NEW_TTY_DRIVER)
1221: struct sgttyb ttybuff;
1222: int tty = fileno (rl_instream);
1223:
1224: if (ioctl (tty, TIOCGETP, &ttybuff) != -1)
1225: {
1226: int erase, kill;
1227:
1228: erase = ttybuff.sg_erase;
1229: kill = ttybuff.sg_kill;
1230:
1231: if (erase != -1 && keymap[erase].type == ISFUNC)
1232: keymap[erase].function = rl_rubout;
1233:
1234: if (kill != -1 && keymap[kill].type == ISFUNC)
1235: keymap[kill].function = rl_unix_line_discard;
1236: }
1237:
1238: #if defined (TIOCGLTC)
1239: {
1240: struct ltchars lt;
1241:
1242: if (ioctl (tty, TIOCGLTC, <) != -1)
1243: {
1244: int erase, nextc;
1245:
1246: erase = lt.t_werasc;
1247: nextc = lt.t_lnextc;
1248:
1249: if (erase != -1 && keymap[erase].type == ISFUNC)
1250: keymap[erase].function = rl_unix_word_rubout;
1251:
1252: if (nextc != -1 && keymap[nextc].type == ISFUNC)
1253: keymap[nextc].function = rl_quoted_insert;
1254: }
1255: }
1256: #endif /* TIOCGLTC */
1257: #else /* not NEW_TTY_DRIVER */
1258:
1259: #if defined (TERMIOS_TTY_DRIVER)
1260: struct termios ttybuff;
1261: #else
1262: struct termio ttybuff;
1263: #endif /* TERMIOS_TTY_DRIVER */
1264: int tty = fileno (rl_instream);
1265:
1266: #if defined (TERMIOS_TTY_DRIVER)
1267: if (tcgetattr (tty, &ttybuff) != -1)
1268: #else
1269: if (ioctl (tty, TCGETA, &ttybuff) != -1)
1270: #endif /* !TERMIOS_TTY_DRIVER */
1271: {
1272: int erase, kill;
1273:
1274: erase = ttybuff.c_cc[VERASE];
1275: kill = ttybuff.c_cc[VKILL];
1276:
1277: if (erase != _POSIX_VDISABLE &&
1278: keymap[(unsigned char)erase].type == ISFUNC)
1279: keymap[(unsigned char)erase].function = rl_rubout;
1280:
1281: if (kill != _POSIX_VDISABLE &&
1282: keymap[(unsigned char)kill].type == ISFUNC)
1283: keymap[(unsigned char)kill].function = rl_unix_line_discard;
1284:
1285: #if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
1286: {
1287: int nextc;
1288:
1289: nextc = ttybuff.c_cc[VLNEXT];
1290:
1291: if (nextc != _POSIX_VDISABLE &&
1292: keymap[(unsigned char)nextc].type == ISFUNC)
1293: keymap[(unsigned char)nextc].function = rl_quoted_insert;
1294: }
1295: #endif /* VLNEXT && TERMIOS_TTY_DRIVER */
1296:
1297: #if defined (VWERASE)
1298: {
1299: int werase;
1300:
1301: werase = ttybuff.c_cc[VWERASE];
1302:
1303: if (werase != _POSIX_VDISABLE &&
1304: keymap[(unsigned char)werase].type == ISFUNC)
1305: keymap[(unsigned char)werase].function = rl_unix_word_rubout;
1306: }
1307: #endif /* VWERASE */
1308: }
1309: #endif /* !NEW_TTY_DRIVER */
1310: #endif /* def __GO32__ */
1311: }
1312:
1313:
1314: /* **************************************************************** */
1315: /* */
1316: /* Numeric Arguments */
1317: /* */
1318: /* **************************************************************** */
1319:
1320: /* Handle C-u style numeric args, as well as M--, and M-digits. */
1321:
1322: /* Add the current digit to the argument in progress. */
1323: rl_digit_argument (ignore, key)
1324: int ignore, key;
1325: {
1326: rl_pending_input = key;
1327: rl_digit_loop ();
1328: }
1329:
1330: /* What to do when you abort reading an argument. */
1331: rl_discard_argument ()
1332: {
1333: ding ();
1334: rl_clear_message ();
1335: rl_init_argument ();
1336: }
1337:
1338: /* Create a default argument. */
1339: rl_init_argument ()
1340: {
1341: rl_numeric_arg = rl_arg_sign = 1;
1342: rl_explicit_arg = 0;
1343: }
1344:
1345: /* C-u, universal argument. Multiply the current argument by 4.
1346: Read a key. If the key has nothing to do with arguments, then
1347: dispatch on it. If the key is the abort character then abort. */
1348: rl_universal_argument ()
1349: {
1350: rl_numeric_arg *= 4;
1351: rl_digit_loop ();
1352: }
1353:
1354: rl_digit_loop ()
1355: {
1356: int key, c;
1357: while (1)
1358: {
1359: rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0);
1360: key = c = rl_read_key ();
1361:
1362: if (keymap[c].type == ISFUNC &&
1363: keymap[c].function == rl_universal_argument)
1364: {
1365: rl_numeric_arg *= 4;
1366: continue;
1367: }
1368: c = UNMETA (c);
1369: if (numeric (c))
1370: {
1371: if (rl_explicit_arg)
1372: rl_numeric_arg = (rl_numeric_arg * 10) + (c - '0');
1373: else
1374: rl_numeric_arg = (c - '0');
1375: rl_explicit_arg = 1;
1376: }
1377: else
1378: {
1379: if (c == '-' && !rl_explicit_arg)
1380: {
1381: rl_numeric_arg = 1;
1382: rl_arg_sign = -1;
1383: }
1384: else
1385: {
1386: rl_clear_message ();
1387: rl_dispatch (key, keymap);
1388: return;
1389: }
1390: }
1391: }
1392: }
1393:
1394:
1395: /* **************************************************************** */
1396: /* */
1397: /* Display stuff */
1398: /* */
1399: /* **************************************************************** */
1400:
1401: /* This is the stuff that is hard for me. I never seem to write good
1402: display routines in C. Let's see how I do this time. */
1403:
1404: /* (PWP) Well... Good for a simple line updater, but totally ignores
1405: the problems of input lines longer than the screen width.
1406:
1407: update_line and the code that calls it makes a multiple line,
1408: automatically wrapping line update. Carefull attention needs
1409: to be paid to the vertical position variables.
1410:
1411: handling of terminals with autowrap on (incl. DEC braindamage)
1412: could be improved a bit. Right now I just cheat and decrement
1413: screenwidth by one. */
1414:
1415: /* Keep two buffers; one which reflects the current contents of the
1416: screen, and the other to draw what we think the new contents should
1417: be. Then compare the buffers, and make whatever changes to the
1418: screen itself that we should. Finally, make the buffer that we
1419: just drew into be the one which reflects the current contents of the
1420: screen, and place the cursor where it belongs.
1421:
1422: Commands that want to can fix the display themselves, and then let
1423: this function know that the display has been fixed by setting the
1424: RL_DISPLAY_FIXED variable. This is good for efficiency. */
1425:
1426: /* Termcap variables: */
1427: extern char *term_up, *term_dc, *term_cr;
1428: extern int screenheight, screenwidth, terminal_can_insert;
1429:
1430: /* What YOU turn on when you have handled all redisplay yourself. */
1431: int rl_display_fixed = 0;
1432:
1433: /* The visible cursor position. If you print some text, adjust this. */
1434: int last_c_pos = 0;
1435: int last_v_pos = 0;
1436:
1437: /* The last left edge of text that was displayed. This is used when
1438: doing horizontal scrolling. It shifts in thirds of a screenwidth. */
1439: static int last_lmargin = 0;
1440:
1441: /* The line display buffers. One is the line currently displayed on
1442: the screen. The other is the line about to be displayed. */
1443: static char *visible_line = (char *)NULL;
1444: static char *invisible_line = (char *)NULL;
1445:
1446: /* Number of lines currently on screen minus 1. */
1447: int vis_botlin = 0;
1448:
1449: /* A buffer for `modeline' messages. */
1450: char msg_buf[128];
1451:
1452: /* Non-zero forces the redisplay even if we thought it was unnecessary. */
1453: int forced_display = 0;
1454:
1455: /* The stuff that gets printed out before the actual text of the line.
1456: This is usually pointing to rl_prompt. */
1457: char *rl_display_prompt = (char *)NULL;
1458:
1459: /* Default and initial buffer size. Can grow. */
1460: static int line_size = 1024;
1461:
1462: /* Non-zero means to always use horizontal scrolling in line display. */
1463: static int horizontal_scroll_mode = 0;
1464:
1465: /* Non-zero means to display an asterisk at the starts of history lines
1466: which have been modified. */
1467: static int mark_modified_lines = 0;
1468:
1469: /* Non-zero means to use a visible bell if one is available rather than
1470: simply ringing the terminal bell. */
1471: static int prefer_visible_bell = 0;
1472:
1473: /* I really disagree with this, but my boss (among others) insists that we
1474: support compilers that don't work. I don't think we are gaining by doing
1475: so; what is the advantage in producing better code if we can't use it? */
1476: /* The following two declarations belong inside the
1477: function block, not here. */
1478: static void move_cursor_relative ();
1479: static void output_some_chars ();
1480: static void output_character_function ();
1481: static int compare_strings ();
1482:
1483: /* Basic redisplay algorithm. */
1484: rl_redisplay ()
1485: {
1486: register int in, out, c, linenum;
1487: register char *line = invisible_line;
1488: char *prompt_this_line;
1489: int c_pos = 0;
1490: int inv_botlin = 0; /* Number of lines in newly drawn buffer. */
1491:
1492: extern int readline_echoing_p;
1493:
1494: if (!readline_echoing_p)
1495: return;
1496:
1497: if (!rl_display_prompt)
1498: rl_display_prompt = "";
1499:
1500: if (!invisible_line)
1501: {
1502: visible_line = (char *)xmalloc (line_size);
1503: invisible_line = (char *)xmalloc (line_size);
1504: line = invisible_line;
1505: for (in = 0; in < line_size; in++)
1506: {
1507: visible_line[in] = 0;
1508: invisible_line[in] = 1;
1509: }
1510: rl_on_new_line ();
1511: }
1512:
1513: /* Draw the line into the buffer. */
1514: c_pos = -1;
1515:
1516: /* Mark the line as modified or not. We only do this for history
1517: lines. */
1518: out = 0;
1519: if (mark_modified_lines && current_history () && rl_undo_list)
1520: {
1521: line[out++] = '*';
1522: line[out] = '\0';
1523: }
1524:
1525: /* If someone thought that the redisplay was handled, but the currently
1526: visible line has a different modification state than the one about
1527: to become visible, then correct the callers misconception. */
1528: if (visible_line[0] != invisible_line[0])
1529: rl_display_fixed = 0;
1530:
1531: prompt_this_line = rindex (rl_display_prompt, '\n');
1532: if (!prompt_this_line)
1533: prompt_this_line = rl_display_prompt;
1534: else
1535: {
1536: prompt_this_line++;
1537: if (forced_display)
1538: output_some_chars (rl_display_prompt,
1539: prompt_this_line - rl_display_prompt);
1540: }
1541:
1542: strncpy (line + out, prompt_this_line, strlen (prompt_this_line));
1543: out += strlen (prompt_this_line);
1544: line[out] = '\0';
1545:
1546: for (in = 0; in < rl_end; in++)
1547: {
1548: c = (unsigned char)the_line[in];
1549:
1550: if (out + 1 >= line_size)
1551: {
1552: line_size *= 2;
1553: visible_line = (char *)xrealloc (visible_line, line_size);
1554: invisible_line = (char *)xrealloc (invisible_line, line_size);
1555: line = invisible_line;
1556: }
1557:
1558: if (in == rl_point)
1559: c_pos = out;
1560:
1561: if (c > 127)
1562: {
1563: line[out++] = 'M';
1564: line[out++] = '-';
1565: line[out++] = c - 128;
1566: }
1567: #define DISPLAY_TABS
1568: #if defined (DISPLAY_TABS)
1569: else if (c == '\t')
1570: {
1571: register int newout = (out | (int)7) + 1;
1572: while (out < newout)
1573: line[out++] = ' ';
1574: }
1575: #endif
1576: else if (c < 32)
1577: {
1578: line[out++] = 'C';
1579: line[out++] = '-';
1580: line[out++] = c + 64;
1581: }
1582: else if (c == 127)
1583: {
1584: line[out++] = 'C';
1585: line[out++] = '-';
1586: line[out++] = '?';
1587: }
1588: else
1589: line[out++] = c;
1590: }
1591: line[out] = '\0';
1592: if (c_pos < 0)
1593: c_pos = out;
1594:
1595: /* PWP: now is when things get a bit hairy. The visible and invisible
1596: line buffers are really multiple lines, which would wrap every
1597: (screenwidth - 1) characters. Go through each in turn, finding
1598: the changed region and updating it. The line order is top to bottom. */
1599:
1600: /* If we can move the cursor up and down, then use multiple lines,
1601: otherwise, let long lines display in a single terminal line, and
1602: horizontally scroll it. */
1603:
1604: if (!horizontal_scroll_mode && term_up && *term_up)
1605: {
1606: int total_screen_chars = (screenwidth * screenheight);
1607:
1608: if (!rl_display_fixed || forced_display)
1609: {
1610: forced_display = 0;
1611:
1612: /* If we have more than a screenful of material to display, then
1613: only display a screenful. We should display the last screen,
1614: not the first. I'll fix this in a minute. */
1615: if (out >= total_screen_chars)
1616: out = total_screen_chars - 1;
1617:
1618: /* Number of screen lines to display. */
1619: inv_botlin = out / screenwidth;
1620:
1621: /* For each line in the buffer, do the updating display. */
1622: for (linenum = 0; linenum <= inv_botlin; linenum++)
1623: update_line (linenum > vis_botlin ? ""
1624: : &visible_line[linenum * screenwidth],
1625: &invisible_line[linenum * screenwidth],
1626: linenum);
1627:
1628: /* We may have deleted some lines. If so, clear the left over
1629: blank ones at the bottom out. */
1630: if (vis_botlin > inv_botlin)
1631: {
1632: char *tt;
1633: for (; linenum <= vis_botlin; linenum++)
1634: {
1635: tt = &visible_line[linenum * screenwidth];
1636: move_vert (linenum);
1637: move_cursor_relative (0, tt);
1638: clear_to_eol ((linenum == vis_botlin)?
1639: strlen (tt) : screenwidth);
1640: }
1641: }
1642: vis_botlin = inv_botlin;
1643:
1644: /* Move the cursor where it should be. */
1645: move_vert (c_pos / screenwidth);
1646: move_cursor_relative (c_pos % screenwidth,
1647: &invisible_line[(c_pos / screenwidth) * screenwidth]);
1648: }
1649: }
1650: else /* Do horizontal scrolling. */
1651: {
1652: int lmargin;
1653:
1654: /* Always at top line. */
1655: last_v_pos = 0;
1656:
1657: /* If the display position of the cursor would be off the edge
1658: of the screen, start the display of this line at an offset that
1659: leaves the cursor on the screen. */
1660: if (c_pos - last_lmargin > screenwidth - 2)
1661: lmargin = (c_pos / (screenwidth / 3) - 2) * (screenwidth / 3);
1662: else if (c_pos - last_lmargin < 1)
1663: lmargin = ((c_pos - 1) / (screenwidth / 3)) * (screenwidth / 3);
1664: else
1665: lmargin = last_lmargin;
1666:
1667: /* If the first character on the screen isn't the first character
1668: in the display line, indicate this with a special character. */
1669: if (lmargin > 0)
1670: line[lmargin] = '<';
1671:
1672: if (lmargin + screenwidth < out)
1673: line[lmargin + screenwidth - 1] = '>';
1674:
1675: if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
1676: {
1677: forced_display = 0;
1678: update_line (&visible_line[last_lmargin],
1679: &invisible_line[lmargin], 0);
1680:
1681: move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
1682: last_lmargin = lmargin;
1683: }
1684: }
1685: fflush (out_stream);
1686:
1687: /* Swap visible and non-visible lines. */
1688: {
1689: char *temp = visible_line;
1690: visible_line = invisible_line;
1691: invisible_line = temp;
1692: rl_display_fixed = 0;
1693: }
1694: }
1695:
1696: /* PWP: update_line() is based on finding the middle difference of each
1697: line on the screen; vis:
1698:
1699: /old first difference
1700: /beginning of line | /old last same /old EOL
1701: v v v v
1702: old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
1703: new: eddie> Oh, my little buggy says to me, as lurgid as
1704: ^ ^ ^ ^
1705: \beginning of line | \new last same \new end of line
1706: \new first difference
1707:
1708: All are character pointers for the sake of speed. Special cases for
1709: no differences, as well as for end of line additions must be handeled.
1710:
1711: Could be made even smarter, but this works well enough */
1712: static
1713: update_line (old, new, current_line)
1714: register char *old, *new;
1715: int current_line;
1716: {
1717: register char *ofd, *ols, *oe, *nfd, *nls, *ne;
1718: int lendiff, wsatend;
1719:
1720: /* Find first difference. */
1721: for (ofd = old, nfd = new;
1722: (ofd - old < screenwidth) && *ofd && (*ofd == *nfd);
1723: ofd++, nfd++)
1724: ;
1725:
1726: /* Move to the end of the screen line. */
1727: for (oe = ofd; ((oe - old) < screenwidth) && *oe; oe++);
1728: for (ne = nfd; ((ne - new) < screenwidth) && *ne; ne++);
1729:
1730: /* If no difference, continue to next line. */
1731: if (ofd == oe && nfd == ne)
1732: return;
1733:
1734: wsatend = 1; /* flag for trailing whitespace */
1735: ols = oe - 1; /* find last same */
1736: nls = ne - 1;
1737: while ((*ols == *nls) && (ols > ofd) && (nls > nfd))
1738: {
1739: if (*ols != ' ')
1740: wsatend = 0;
1741: ols--;
1742: nls--;
1743: }
1744:
1745: if (wsatend)
1746: {
1747: ols = oe;
1748: nls = ne;
1749: }
1750: else if (*ols != *nls)
1751: {
1752: if (*ols) /* don't step past the NUL */
1753: ols++;
1754: if (*nls)
1755: nls++;
1756: }
1757:
1758: move_vert (current_line);
1759: move_cursor_relative (ofd - old, old);
1760:
1761: /* if (len (new) > len (old)) */
1762: lendiff = (nls - nfd) - (ols - ofd);
1763:
1764: /* Insert (diff(len(old),len(new)) ch */
1765: if (lendiff > 0)
1766: {
1767: if (terminal_can_insert)
1768: {
1769: extern char *term_IC;
1770:
1771: /* Sometimes it is cheaper to print the characters rather than
1772: use the terminal's capabilities. */
1773: if ((2 * (ne - nfd)) < lendiff && !term_IC)
1774: {
1775: output_some_chars (nfd, (ne - nfd));
1776: last_c_pos += (ne - nfd);
1777: }
1778: else
1779: {
1780: if (*ols)
1781: {
1782: insert_some_chars (nfd, lendiff);
1783: last_c_pos += lendiff;
1784: }
1785: else
1786: {
1787: /* At the end of a line the characters do not have to
1788: be "inserted". They can just be placed on the screen. */
1789: output_some_chars (nfd, lendiff);
1790: last_c_pos += lendiff;
1791: }
1792: /* Copy (new) chars to screen from first diff to last match. */
1793: if (((nls - nfd) - lendiff) > 0)
1794: {
1795: output_some_chars (&nfd[lendiff], ((nls - nfd) - lendiff));
1796: last_c_pos += ((nls - nfd) - lendiff);
1797: }
1798: }
1799: }
1800: else
1801: { /* cannot insert chars, write to EOL */
1802: output_some_chars (nfd, (ne - nfd));
1803: last_c_pos += (ne - nfd);
1804: }
1805: }
1806: else /* Delete characters from line. */
1807: {
1808: /* If possible and inexpensive to use terminal deletion, then do so. */
1809: if (term_dc && (2 * (ne - nfd)) >= (-lendiff))
1810: {
1811: if (lendiff)
1812: delete_chars (-lendiff); /* delete (diff) characters */
1813:
1814: /* Copy (new) chars to screen from first diff to last match */
1815: if ((nls - nfd) > 0)
1816: {
1817: output_some_chars (nfd, (nls - nfd));
1818: last_c_pos += (nls - nfd);
1819: }
1820: }
1821: /* Otherwise, print over the existing material. */
1822: else
1823: {
1824: output_some_chars (nfd, (ne - nfd));
1825: last_c_pos += (ne - nfd);
1826: clear_to_eol ((oe - old) - (ne - new));
1827: }
1828: }
1829: }
1830:
1831: /* (PWP) tell the update routines that we have moved onto a
1832: new (empty) line. */
1833: rl_on_new_line ()
1834: {
1835: if (visible_line)
1836: visible_line[0] = '\0';
1837:
1838: last_c_pos = last_v_pos = 0;
1839: vis_botlin = last_lmargin = 0;
1840: }
1841:
1842: /* Actually update the display, period. */
1843: rl_forced_update_display ()
1844: {
1845: if (visible_line)
1846: {
1847: register char *temp = visible_line;
1848:
1849: while (*temp) *temp++ = '\0';
1850: }
1851: rl_on_new_line ();
1852: forced_display++;
1853: rl_redisplay ();
1854: }
1855:
1856: /* Move the cursor from last_c_pos to NEW, which are buffer indices.
1857: DATA is the contents of the screen line of interest; i.e., where
1858: the movement is being done. */
1859: static void
1860: move_cursor_relative (new, data)
1861: int new;
1862: char *data;
1863: {
1864: register int i;
1865:
1866: /* It may be faster to output a CR, and then move forwards instead
1867: of moving backwards. */
1868: if (new + 1 < last_c_pos - new)
1869: {
1870: #ifdef __MSDOS__
1871: putc('\r', out_stream);
1872: #else
1873: tputs (term_cr, 1, output_character_function);
1874: #endif
1875: last_c_pos = 0;
1876: }
1877:
1878: if (last_c_pos == new) return;
1879:
1880: if (last_c_pos < new)
1881: {
1882: /* Move the cursor forward. We do it by printing the command
1883: to move the cursor forward if there is one, else print that
1884: portion of the output buffer again. Which is cheaper? */
1885:
1886: /* The above comment is left here for posterity. It is faster
1887: to print one character (non-control) than to print a control
1888: sequence telling the terminal to move forward one character.
1889: That kind of control is for people who don't know what the
1890: data is underneath the cursor. */
1891: #if defined (HACK_TERMCAP_MOTION)
1892: extern char *term_forward_char;
1893:
1894: if (term_forward_char)
1895: for (i = last_c_pos; i < new; i++)
1896: tputs (term_forward_char, 1, output_character_function);
1897: else
1898: for (i = last_c_pos; i < new; i++)
1899: putc (data[i], out_stream);
1900: #else
1901: for (i = last_c_pos; i < new; i++)
1902: putc (data[i], out_stream);
1903: #endif /* HACK_TERMCAP_MOTION */
1904: }
1905: else
1906: backspace (last_c_pos - new);
1907: last_c_pos = new;
1908: }
1909:
1910: /* PWP: move the cursor up or down. */
1911: move_vert (to)
1912: int to;
1913: {
1914: void output_character_function ();
1915: register int delta, i;
1916:
1917: if (last_v_pos == to) return;
1918:
1919: if (to > screenheight)
1920: return;
1921:
1922: #ifdef __GO32__
1923: {
1924: int cur_r, cur_c;
1925: ScreenGetCursor(&cur_r, &cur_c);
1926: ScreenSetCursor(cur_r+to-last_v_pos, cur_c);
1927: }
1928: #else /* __GO32__ */
1929: if ((delta = to - last_v_pos) > 0)
1930: {
1931: for (i = 0; i < delta; i++)
1932: putc ('\n', out_stream);
1933: tputs (term_cr, 1, output_character_function);
1934: last_c_pos = 0;
1935: }
1936: else
1937: { /* delta < 0 */
1938: if (term_up && *term_up)
1939: for (i = 0; i < -delta; i++)
1940: tputs (term_up, 1, output_character_function);
1941: }
1942: #endif /* __GO32__ */
1943: last_v_pos = to; /* now to is here */
1944: }
1945:
1946: /* Physically print C on out_stream. This is for functions which know
1947: how to optimize the display. */
1948: rl_show_char (c)
1949: int c;
1950: {
1951: if (c > 127)
1952: {
1953: fprintf (out_stream, "M-");
1954: c -= 128;
1955: }
1956:
1957: #if defined (DISPLAY_TABS)
1958: if (c < 32 && c != '\t')
1959: #else
1960: if (c < 32)
1961: #endif
1962: {
1963:
1964: c += 64;
1965: }
1966:
1967: putc (c, out_stream);
1968: fflush (out_stream);
1969: }
1970:
1971: #if defined (DISPLAY_TABS)
1972: int
1973: rl_character_len (c, pos)
1974: register int c, pos;
1975: {
1976: if (c < ' ' || c > 126)
1977: {
1978: if (c == '\t')
1979: return (((pos | (int)7) + 1) - pos);
1980: else
1981: return (3);
1982: }
1983: else
1984: return (1);
1985: }
1986: #else
1987: int
1988: rl_character_len (c)
1989: int c;
1990: {
1991: if (c < ' ' || c > 126)
1992: return (3);
1993: else
1994: return (1);
1995: }
1996: #endif /* DISPLAY_TAB */
1997:
1998: /* How to print things in the "echo-area". The prompt is treated as a
1999: mini-modeline. */
2000: rl_message (string, arg1, arg2)
2001: char *string;
2002: {
2003: sprintf (msg_buf, string, arg1, arg2);
2004: rl_display_prompt = msg_buf;
2005: rl_redisplay ();
2006: }
2007:
2008: /* How to clear things from the "echo-area". */
2009: rl_clear_message ()
2010: {
2011: rl_display_prompt = rl_prompt;
2012: rl_redisplay ();
2013: }
2014:
2015: /* **************************************************************** */
2016: /* */
2017: /* Terminal and Termcap */
2018: /* */
2019: /* **************************************************************** */
2020:
2021: static char *term_buffer = (char *)NULL;
2022: static char *term_string_buffer = (char *)NULL;
2023:
2024: /* Non-zero means this terminal can't really do anything. */
2025: int dumb_term = 0;
2026:
2027: /* On Solaris2, sys/types.h brings in sys/reg.h,
2028: which screws up the Termcap variable PC, used below. */
2029:
2030: #undef PC
2031:
2032: char PC;
2033: char *BC, *UP;
2034:
2035: /* Some strings to control terminal actions. These are output by tputs (). */
2036: char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
2037:
2038: int screenwidth, screenheight;
2039:
2040: /* Non-zero if we determine that the terminal can do character insertion. */
2041: int terminal_can_insert = 0;
2042:
2043: /* How to insert characters. */
2044: char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
2045:
2046: /* How to delete characters. */
2047: char *term_dc, *term_DC;
2048:
2049: #if defined (HACK_TERMCAP_MOTION)
2050: char *term_forward_char;
2051: #endif /* HACK_TERMCAP_MOTION */
2052:
2053: /* How to go up a line. */
2054: char *term_up;
2055:
2056: /* A visible bell, if the terminal can be made to flash the screen. */
2057: char *visible_bell;
2058:
2059: /* Re-initialize the terminal considering that the TERM/TERMCAP variable
2060: has changed. */
2061: rl_reset_terminal (terminal_name)
2062: char *terminal_name;
2063: {
2064: init_terminal_io (terminal_name);
2065: }
2066:
2067: init_terminal_io (terminal_name)
2068: char *terminal_name;
2069: {
2070: #ifdef __GO32__
2071: screenwidth = ScreenCols();
2072: screenheight = ScreenRows();
2073: term_cr = "\r";
2074: term_im = term_ei = term_ic = term_IC = (char *)NULL;
2075: term_up = term_dc = term_DC = visible_bell = (char *)NULL;
2076: #if defined (HACK_TERMCAP_MOTION)
2077: term_forward_char = (char *)NULL;
2078: #endif
2079: terminal_can_insert = 0;
2080: return;
2081: #else
2082: extern char *tgetstr ();
2083: char *term, *buffer;
2084: #if defined (TIOCGWINSZ)
2085: struct winsize window_size;
2086: #endif
2087: int tty;
2088:
2089: term = terminal_name ? terminal_name : getenv ("TERM");
2090:
2091: if (!term_string_buffer)
2092: term_string_buffer = (char *)xmalloc (2048);
2093:
2094: if (!term_buffer)
2095: term_buffer = (char *)xmalloc (2048);
2096:
2097: buffer = term_string_buffer;
2098:
2099: term_clrpag = term_cr = term_clreol = (char *)NULL;
2100:
2101: if (!term)
2102: term = "dumb";
2103:
2104: if (tgetent (term_buffer, term) <= 0)
2105: {
2106: dumb_term = 1;
2107: screenwidth = 79;
2108: screenheight = 24;
2109: term_cr = "\r";
2110: term_im = term_ei = term_ic = term_IC = (char *)NULL;
2111: term_up = term_dc = term_DC = visible_bell = (char *)NULL;
2112: #if defined (HACK_TERMCAP_MOTION)
2113: term_forward_char = (char *)NULL;
2114: #endif
2115: terminal_can_insert = 0;
2116: return;
2117: }
2118:
2119: BC = tgetstr ("pc", &buffer);
2120: PC = buffer ? *buffer : 0;
2121:
2122: term_backspace = tgetstr ("le", &buffer);
2123:
2124: term_cr = tgetstr ("cr", &buffer);
2125: term_clreol = tgetstr ("ce", &buffer);
2126: term_clrpag = tgetstr ("cl", &buffer);
2127:
2128: if (!term_cr)
2129: term_cr = "\r";
2130:
2131: #if defined (HACK_TERMCAP_MOTION)
2132: term_forward_char = tgetstr ("nd", &buffer);
2133: #endif /* HACK_TERMCAP_MOTION */
2134:
2135: if (rl_instream)
2136: tty = fileno (rl_instream);
2137: else
2138: tty = 0;
2139:
2140: screenwidth = screenheight = 0;
2141: #if defined (TIOCGWINSZ)
2142: if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
2143: {
2144: screenwidth = (int) window_size.ws_col;
2145: screenheight = (int) window_size.ws_row;
2146: }
2147: #endif
2148:
2149: if (screenwidth <= 0 || screenheight <= 0)
2150: {
2151: screenwidth = tgetnum ("co");
2152: screenheight = tgetnum ("li");
2153: }
2154:
2155: screenwidth--;
2156:
2157: if (screenwidth <= 0)
2158: screenwidth = 79;
2159:
2160: if (screenheight <= 0)
2161: screenheight = 24;
2162:
2163: term_im = tgetstr ("im", &buffer);
2164: term_ei = tgetstr ("ei", &buffer);
2165: term_IC = tgetstr ("IC", &buffer);
2166: term_ic = tgetstr ("ic", &buffer);
2167:
2168: /* "An application program can assume that the terminal can do
2169: character insertion if *any one of* the capabilities `IC',
2170: `im', `ic' or `ip' is provided." But we can't do anything if
2171: only `ip' is provided, so... */
2172: terminal_can_insert = (term_IC || term_im || term_ic);
2173:
2174: term_up = tgetstr ("up", &buffer);
2175: term_dc = tgetstr ("dc", &buffer);
2176: term_DC = tgetstr ("DC", &buffer);
2177:
2178: visible_bell = tgetstr ("vb", &buffer);
2179: #endif /* !__GO32__ */
2180: }
2181:
2182: /* A function for the use of tputs () */
2183: static void
2184: output_character_function (c)
2185: int c;
2186: {
2187: putc (c, out_stream);
2188: }
2189:
2190: /* Write COUNT characters from STRING to the output stream. */
2191: static void
2192: output_some_chars (string, count)
2193: char *string;
2194: int count;
2195: {
2196: fwrite (string, 1, count, out_stream);
2197: }
2198:
2199: /* Delete COUNT characters from the display line. */
2200: static
2201: delete_chars (count)
2202: int count;
2203: {
2204: #ifdef __GO32__
2205: int r, c, w;
2206: ScreenGetCursor(&r, &c);
2207: w = ScreenCols();
2208: memcpy(ScreenPrimary+r*w+c, ScreenPrimary+r*w+c+count, w-c-count);
2209: memset(ScreenPrimary+r*w+w-count, 0, count*2);
2210: #else /* __GO32__ */
2211: if (count > screenwidth)
2212: return;
2213:
2214: if (term_DC && *term_DC)
2215: {
2216: char *tgoto (), *buffer;
2217: buffer = tgoto (term_DC, 0, count);
2218: tputs (buffer, 1, output_character_function);
2219: }
2220: else
2221: {
2222: if (term_dc && *term_dc)
2223: while (count--)
2224: tputs (term_dc, 1, output_character_function);
2225: }
2226: #endif /* __GO32__ */
2227: }
2228:
2229: /* Insert COUNT characters from STRING to the output stream. */
2230: static void
2231: insert_some_chars (string, count)
2232: char *string;
2233: int count;
2234: {
2235: #ifdef __GO32__
2236: int r, c, w;
2237: ScreenGetCursor(&r, &c);
2238: w = ScreenCols();
2239: memcpy(ScreenPrimary+r*w+c+count, ScreenPrimary+r*w+c, w-c-count);
2240: /* Print the text. */
2241: output_some_chars (string, count);
2242: #else /* __GO32__ */
2243: /* If IC is defined, then we do not have to "enter" insert mode. */
2244: if (term_IC)
2245: {
2246: char *tgoto (), *buffer;
2247: buffer = tgoto (term_IC, 0, count);
2248: tputs (buffer, 1, output_character_function);
2249: output_some_chars (string, count);
2250: }
2251: else
2252: {
2253: register int i;
2254:
2255: /* If we have to turn on insert-mode, then do so. */
2256: if (term_im && *term_im)
2257: tputs (term_im, 1, output_character_function);
2258:
2259: /* If there is a special command for inserting characters, then
2260: use that first to open up the space. */
2261: if (term_ic && *term_ic)
2262: {
2263: for (i = count; i--; )
2264: tputs (term_ic, 1, output_character_function);
2265: }
2266:
2267: /* Print the text. */
2268: output_some_chars (string, count);
2269:
2270: /* If there is a string to turn off insert mode, we had best use
2271: it now. */
2272: if (term_ei && *term_ei)
2273: tputs (term_ei, 1, output_character_function);
2274: }
2275: #endif /* __GO32__ */
2276: }
2277:
2278: /* Move the cursor back. */
2279: backspace (count)
2280: int count;
2281: {
2282: register int i;
2283:
2284: #ifndef __GO32__
2285: if (term_backspace)
2286: for (i = 0; i < count; i++)
2287: tputs (term_backspace, 1, output_character_function);
2288: else
2289: #endif /* !__GO32__ */
2290: for (i = 0; i < count; i++)
2291: putc ('\b', out_stream);
2292: }
2293:
2294: /* Move to the start of the next line. */
2295: crlf ()
2296: {
2297: #if defined (NEW_TTY_DRIVER)
2298: tputs (term_cr, 1, output_character_function);
2299: #endif /* NEW_TTY_DRIVER */
2300: putc ('\n', out_stream);
2301: }
2302:
2303: /* Clear to the end of the line. COUNT is the minimum
2304: number of character spaces to clear, */
2305: static void
2306: clear_to_eol (count)
2307: int count;
2308: {
2309: #ifndef __GO32__
2310: if (term_clreol)
2311: {
2312: tputs (term_clreol, 1, output_character_function);
2313: }
2314: else
2315: #endif /* !__GO32__ */
2316: {
2317: register int i;
2318:
2319: /* Do one more character space. */
2320: count++;
2321:
2322: for (i = 0; i < count; i++)
2323: putc (' ', out_stream);
2324:
2325: backspace (count);
2326: }
2327: }
2328:
2329:
2330: /* **************************************************************** */
2331: /* */
2332: /* Saving and Restoring the TTY */
2333: /* */
2334: /* **************************************************************** */
2335:
2336: /* Non-zero means that the terminal is in a prepped state. */
2337: static int terminal_prepped = 0;
2338:
2339: #if defined (NEW_TTY_DRIVER)
2340:
2341: /* Standard flags, including ECHO. */
2342: static int original_tty_flags = 0;
2343:
2344: /* Local mode flags, like LPASS8. */
2345: static int local_mode_flags = 0;
2346:
2347: /* Terminal characters. This has C-s and C-q in it. */
2348: static struct tchars original_tchars;
2349:
2350: /* Local special characters. This has the interrupt characters in it. */
2351: #if defined (TIOCGLTC)
2352: static struct ltchars original_ltchars;
2353: #endif
2354:
2355: /* We use this to get and set the tty_flags. */
2356: static struct sgttyb the_ttybuff;
2357:
2358: /* Put the terminal in CBREAK mode so that we can detect key presses. */
2359: static void
2360: rl_prep_terminal ()
2361: {
2362: #ifndef __GO32__
2363: int tty = fileno (rl_instream);
2364: SIGNALS_DECLARE_SAVED (saved_signals);
2365:
2366: if (terminal_prepped)
2367: return;
2368:
2369: SIGNALS_BLOCK (SIGINT, saved_signals);
2370:
2371: /* We always get the latest tty values. Maybe stty changed them. */
2372: ioctl (tty, TIOCGETP, &the_ttybuff);
2373: original_tty_flags = the_ttybuff.sg_flags;
2374:
2375: readline_echoing_p = (original_tty_flags & ECHO);
2376:
2377: #if defined (TIOCLGET)
2378: ioctl (tty, TIOCLGET, &local_mode_flags);
2379: #endif
2380:
2381: #if !defined (ANYP)
2382: # define ANYP (EVENP | ODDP)
2383: #endif
2384:
2385: /* If this terminal doesn't care how the 8th bit is used,
2386: then we can use it for the meta-key. We check by seeing
2387: if BOTH odd and even parity are allowed. */
2388: if (the_ttybuff.sg_flags & ANYP)
2389: {
2390: #if defined (PASS8)
2391: the_ttybuff.sg_flags |= PASS8;
2392: #endif
2393:
2394: /* Hack on local mode flags if we can. */
2395: #if defined (TIOCLGET) && defined (LPASS8)
2396: {
2397: int flags;
2398: flags = local_mode_flags | LPASS8;
2399: ioctl (tty, TIOCLSET, &flags);
2400: }
2401: #endif /* TIOCLGET && LPASS8 */
2402: }
2403:
2404: #if defined (TIOCGETC)
2405: {
2406: struct tchars temp;
2407:
2408: ioctl (tty, TIOCGETC, &original_tchars);
2409: temp = original_tchars;
2410:
2411: #if defined (USE_XON_XOFF)
2412: /* Get rid of C-s and C-q.
2413: We remember the value of startc (C-q) so that if the terminal is in
2414: xoff state, the user can xon it by pressing that character. */
2415: xon_char = temp.t_startc;
2416: temp.t_stopc = -1;
2417: temp.t_startc = -1;
2418:
2419: /* If there is an XON character, bind it to restart the output. */
2420: if (xon_char != -1)
2421: rl_bind_key (xon_char, rl_restart_output);
2422: #endif /* USE_XON_XOFF */
2423:
2424: /* If there is an EOF char, bind eof_char to it. */
2425: if (temp.t_eofc != -1)
2426: eof_char = temp.t_eofc;
2427:
2428: #if defined (NO_KILL_INTR)
2429: /* Get rid of C-\ and C-c. */
2430: temp.t_intrc = temp.t_quitc = -1;
2431: #endif /* NO_KILL_INTR */
2432:
2433: ioctl (tty, TIOCSETC, &temp);
2434: }
2435: #endif /* TIOCGETC */
2436:
2437: #if defined (TIOCGLTC)
2438: {
2439: struct ltchars temp;
2440:
2441: ioctl (tty, TIOCGLTC, &original_ltchars);
2442: temp = original_ltchars;
2443:
2444: /* Make the interrupt keys go away. Just enough to make people
2445: happy. */
2446: temp.t_dsuspc = -1; /* C-y */
2447: temp.t_lnextc = -1; /* C-v */
2448:
2449: ioctl (tty, TIOCSLTC, &temp);
2450: }
2451: #endif /* TIOCGLTC */
2452:
2453: the_ttybuff.sg_flags &= ~(ECHO | CRMOD);
2454: the_ttybuff.sg_flags |= CBREAK;
2455: ioctl (tty, TIOCSETN, &the_ttybuff);
2456:
2457: terminal_prepped = 1;
2458:
2459: SIGNALS_RESTORE (saved_signals);
2460: #endif /* !__GO32__ */
2461: }
2462:
2463: /* Restore the terminal to its original state. */
2464: static void
2465: rl_deprep_terminal ()
2466: {
2467: #ifndef __GO32__
2468: int tty = fileno (rl_instream);
2469: SIGNALS_DECLARE_SAVED (saved_signals);
2470:
2471: if (!terminal_prepped)
2472: return;
2473:
2474: SIGNALS_BLOCK (SIGINT, saved_signals);
2475:
2476: the_ttybuff.sg_flags = original_tty_flags;
2477: ioctl (tty, TIOCSETN, &the_ttybuff);
2478: readline_echoing_p = 1;
2479:
2480: #if defined (TIOCLGET)
2481: ioctl (tty, TIOCLSET, &local_mode_flags);
2482: #endif
2483:
2484: #if defined (TIOCSLTC)
2485: ioctl (tty, TIOCSLTC, &original_ltchars);
2486: #endif
2487:
2488: #if defined (TIOCSETC)
2489: ioctl (tty, TIOCSETC, &original_tchars);
2490: #endif
2491: terminal_prepped = 0;
2492:
2493: SIGNALS_RESTORE (saved_signals);
2494: #endif /* !__GO32 */
2495: }
2496:
2497: #else /* !defined (NEW_TTY_DRIVER) */
2498:
2499: #if !defined (VMIN)
2500: #define VMIN VEOF
2501: #endif
2502:
2503: #if !defined (VTIME)
2504: #define VTIME VEOL
2505: #endif
2506:
2507: #ifndef __GO32__
2508: #if defined (TERMIOS_TTY_DRIVER)
2509: static struct termios otio;
2510: #else
2511: static struct termio otio;
2512: #endif /* !TERMIOS_TTY_DRIVER */
2513: #endif /* __GO32__ */
2514:
2515: static void
2516: rl_prep_terminal ()
2517: {
2518: #ifndef __GO32__
2519: int tty = fileno (rl_instream);
2520: #if defined (TERMIOS_TTY_DRIVER)
2521: struct termios tio;
2522: #else
2523: struct termio tio;
2524: #endif /* !TERMIOS_TTY_DRIVER */
2525:
2526: SIGNALS_DECLARE_SAVED (saved_signals);
2527:
2528: if (terminal_prepped)
2529: return;
2530:
2531: /* Try to keep this function from being INTerrupted. We can do it
2532: on POSIX and systems with BSD-like signal handling. */
2533: SIGNALS_BLOCK (SIGINT, saved_signals);
2534:
2535: #if defined (TERMIOS_TTY_DRIVER)
2536: tcgetattr (tty, &tio);
2537: #else
2538: ioctl (tty, TCGETA, &tio);
2539: #endif /* !TERMIOS_TTY_DRIVER */
2540:
2541: otio = tio;
2542:
2543: readline_echoing_p = (tio.c_lflag & ECHO);
2544:
2545: tio.c_lflag &= ~(ICANON|ECHO);
2546:
2547: if (otio.c_cc[VEOF] != _POSIX_VDISABLE)
2548: eof_char = otio.c_cc[VEOF];
2549:
2550: #if defined (USE_XON_XOFF)
2551: #if defined (IXANY)
2552: tio.c_iflag &= ~(IXON|IXOFF|IXANY);
2553: #else
2554: /* `strict' Posix systems do not define IXANY. */
2555: tio.c_iflag &= ~(IXON|IXOFF);
2556: #endif /* IXANY */
2557: #endif /* USE_XON_XOFF */
2558:
2559: /* Only turn this off if we are using all 8 bits. */
2560: /* |ISTRIP|INPCK */
2561: tio.c_iflag &= ~(ISTRIP | INPCK);
2562:
2563: /* Make sure we differentiate between CR and NL on input. */
2564: tio.c_iflag &= ~(ICRNL | INLCR);
2565:
2566: #if !defined (HANDLE_SIGNALS)
2567: tio.c_lflag &= ~ISIG;
2568: #else
2569: tio.c_lflag |= ISIG;
2570: #endif
2571:
2572: tio.c_cc[VMIN] = 1;
2573: tio.c_cc[VTIME] = 0;
2574:
2575: /* Turn off characters that we need on Posix systems with job control,
2576: just to be sure. This includes ^Y and ^V. This should not really
2577: be necessary. */
2578: #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_JOB_CONTROL)
2579:
2580: #if defined (VLNEXT)
2581: tio.c_cc[VLNEXT] = _POSIX_VDISABLE;
2582: #endif
2583:
2584: #if defined (VDSUSP)
2585: tio.c_cc[VDSUSP] = _POSIX_VDISABLE;
2586: #endif
2587:
2588: #endif /* POSIX && JOB_CONTROL */
2589:
2590: #if defined (TERMIOS_TTY_DRIVER)
2591: tcsetattr (tty, TCSADRAIN, &tio);
2592: tcflow (tty, TCOON); /* Simulate a ^Q. */
2593: #else
2594: ioctl (tty, TCSETAW, &tio);
2595: ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
2596: #endif /* !TERMIOS_TTY_DRIVER */
2597:
2598: terminal_prepped = 1;
2599:
2600: SIGNALS_RESTORE (saved_signals);
2601: #endif /* !__GO32__ */
2602: }
2603:
2604: static void
2605: rl_deprep_terminal ()
2606: {
2607: #ifndef __GO32__
2608: int tty = fileno (rl_instream);
2609:
2610: /* Try to keep this function from being INTerrupted. We can do it
2611: on POSIX and systems with BSD-like signal handling. */
2612: SIGNALS_DECLARE_SAVED (saved_signals);
2613:
2614: if (!terminal_prepped)
2615: return;
2616:
2617: SIGNALS_BLOCK (SIGINT, saved_signals);
2618:
2619: #if defined (TERMIOS_TTY_DRIVER)
2620: tcsetattr (tty, TCSADRAIN, &otio);
2621: tcflow (tty, TCOON); /* Simulate a ^Q. */
2622: #else /* TERMIOS_TTY_DRIVER */
2623: ioctl (tty, TCSETAW, &otio);
2624: ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
2625: #endif /* !TERMIOS_TTY_DRIVER */
2626:
2627: terminal_prepped = 0;
2628:
2629: SIGNALS_RESTORE (saved_signals);
2630: #endif /* !__GO32__ */
2631: }
2632: #endif /* NEW_TTY_DRIVER */
2633:
2634: void
2635: rl_deprepare_terminal()
2636: {
2637: rl_clear_signals();
2638: rl_deprep_terminal();
2639: }
2640:
2641: void
2642: rl_prepare_terminal()
2643: {
2644: rl_set_signals();
2645: rl_prep_terminal();
2646: }
2647:
2648:
2649: /* **************************************************************** */
2650: /* */
2651: /* Utility Functions */
2652: /* */
2653: /* **************************************************************** */
2654:
2655: /* Return 0 if C is not a member of the class of characters that belong
2656: in words, or 1 if it is. */
2657:
2658: int allow_pathname_alphabetic_chars = 0;
2659: char *pathname_alphabetic_chars = "/-_=~.#$";
2660:
2661: int
2662: alphabetic (c)
2663: int c;
2664: {
2665: if (pure_alphabetic (c) || (numeric (c)))
2666: return (1);
2667:
2668: if (allow_pathname_alphabetic_chars)
2669: return ((int)rindex (pathname_alphabetic_chars, c));
2670: else
2671: return (0);
2672: }
2673:
2674: /* Return non-zero if C is a numeric character. */
2675: int
2676: numeric (c)
2677: int c;
2678: {
2679: return (c >= '0' && c <= '9');
2680: }
2681:
2682: /* Ring the terminal bell. */
2683: int
2684: ding ()
2685: {
2686: if (readline_echoing_p)
2687: {
2688: #ifndef __GO32__
2689: if (prefer_visible_bell && visible_bell)
2690: tputs (visible_bell, 1, output_character_function);
2691: else
2692: #endif /* !__GO32__ */
2693: {
2694: fprintf (stderr, "\007");
2695: fflush (stderr);
2696: }
2697: }
2698: return (-1);
2699: }
2700:
2701: /* How to abort things. */
2702: rl_abort ()
2703: {
2704: ding ();
2705: rl_clear_message ();
2706: rl_init_argument ();
2707: rl_pending_input = 0;
2708:
2709: defining_kbd_macro = 0;
2710: while (executing_macro)
2711: pop_executing_macro ();
2712:
2713: rl_last_func = (Function *)NULL;
2714: longjmp (readline_top_level, 1);
2715: }
2716:
2717: /* Return a copy of the string between FROM and TO.
2718: FROM is inclusive, TO is not. */
2719: #if defined (sun) /* Yes, that's right, some crufty function in sunview is
2720: called rl_copy (). */
2721: static
2722: #endif
2723: char *
2724: rl_copy (from, to)
2725: int from, to;
2726: {
2727: register int length;
2728: char *copy;
2729:
2730: /* Fix it if the caller is confused. */
2731: if (from > to)
2732: {
2733: int t = from;
2734: from = to;
2735: to = t;
2736: }
2737:
2738: length = to - from;
2739: copy = (char *)xmalloc (1 + length);
2740: strncpy (copy, the_line + from, length);
2741: copy[length] = '\0';
2742: return (copy);
2743: }
2744:
2745: /* Increase the size of RL_LINE_BUFFER until it has enough space to hold
2746: LEN characters. */
2747: void
2748: rl_extend_line_buffer (len)
2749: int len;
2750: {
2751: while (len >= rl_line_buffer_len)
2752: rl_line_buffer =
2753: (char *)xrealloc
2754: (rl_line_buffer, rl_line_buffer_len += DEFAULT_BUFFER_SIZE);
2755:
2756: the_line = rl_line_buffer;
2757: }
2758:
2759:
2760: /* **************************************************************** */
2761: /* */
2762: /* Insert and Delete */
2763: /* */
2764: /* **************************************************************** */
2765:
2766: /* Insert a string of text into the line at point. This is the only
2767: way that you should do insertion. rl_insert () calls this
2768: function. */
2769: rl_insert_text (string)
2770: char *string;
2771: {
2772: extern int doing_an_undo;
2773: register int i, l = strlen (string);
2774:
2775: if (rl_end + l >= rl_line_buffer_len)
2776: rl_extend_line_buffer (rl_end + l);
2777:
2778: for (i = rl_end; i >= rl_point; i--)
2779: the_line[i + l] = the_line[i];
2780: strncpy (the_line + rl_point, string, l);
2781:
2782: /* Remember how to undo this if we aren't undoing something. */
2783: if (!doing_an_undo)
2784: {
2785: /* If possible and desirable, concatenate the undos. */
2786: if ((strlen (string) == 1) &&
2787: rl_undo_list &&
2788: (rl_undo_list->what == UNDO_INSERT) &&
2789: (rl_undo_list->end == rl_point) &&
2790: (rl_undo_list->end - rl_undo_list->start < 20))
2791: rl_undo_list->end++;
2792: else
2793: rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
2794: }
2795: rl_point += l;
2796: rl_end += l;
2797: the_line[rl_end] = '\0';
2798: }
2799:
2800: /* Delete the string between FROM and TO. FROM is
2801: inclusive, TO is not. */
2802: rl_delete_text (from, to)
2803: int from, to;
2804: {
2805: extern int doing_an_undo;
2806: register char *text;
2807:
2808: /* Fix it if the caller is confused. */
2809: if (from > to)
2810: {
2811: int t = from;
2812: from = to;
2813: to = t;
2814: }
2815: text = rl_copy (from, to);
2816: strncpy (the_line + from, the_line + to, rl_end - to);
2817:
2818: /* Remember how to undo this delete. */
2819: if (!doing_an_undo)
2820: rl_add_undo (UNDO_DELETE, from, to, text);
2821: else
2822: free (text);
2823:
2824: rl_end -= (to - from);
2825: the_line[rl_end] = '\0';
2826: }
2827:
2828:
2829: /* **************************************************************** */
2830: /* */
2831: /* Readline character functions */
2832: /* */
2833: /* **************************************************************** */
2834:
2835: /* This is not a gap editor, just a stupid line input routine. No hair
2836: is involved in writing any of the functions, and none should be. */
2837:
2838: /* Note that:
2839:
2840: rl_end is the place in the string that we would place '\0';
2841: i.e., it is always safe to place '\0' there.
2842:
2843: rl_point is the place in the string where the cursor is. Sometimes
2844: this is the same as rl_end.
2845:
2846: Any command that is called interactively receives two arguments.
2847: The first is a count: the numeric arg pased to this command.
2848: The second is the key which invoked this command.
2849: */
2850:
2851:
2852: /* **************************************************************** */
2853: /* */
2854: /* Movement Commands */
2855: /* */
2856: /* **************************************************************** */
2857:
2858: /* Note that if you `optimize' the display for these functions, you cannot
2859: use said functions in other functions which do not do optimizing display.
2860: I.e., you will have to update the data base for rl_redisplay, and you
2861: might as well let rl_redisplay do that job. */
2862:
2863: /* Move forward COUNT characters. */
2864: rl_forward (count)
2865: int count;
2866: {
2867: if (count < 0)
2868: rl_backward (-count);
2869: else
2870: while (count)
2871: {
2872: #if defined (VI_MODE)
2873: if (rl_point == (rl_end - (rl_editing_mode == vi_mode)))
2874: #else
2875: if (rl_point == rl_end)
2876: #endif /* VI_MODE */
2877: {
2878: ding ();
2879: return;
2880: }
2881: else
2882: rl_point++;
2883: --count;
2884: }
2885: }
2886:
2887: /* Move backward COUNT characters. */
2888: rl_backward (count)
2889: int count;
2890: {
2891: if (count < 0)
2892: rl_forward (-count);
2893: else
2894: while (count)
2895: {
2896: if (!rl_point)
2897: {
2898: ding ();
2899: return;
2900: }
2901: else
2902: --rl_point;
2903: --count;
2904: }
2905: }
2906:
2907: /* Move to the beginning of the line. */
2908: rl_beg_of_line ()
2909: {
2910: rl_point = 0;
2911: }
2912:
2913: /* Move to the end of the line. */
2914: rl_end_of_line ()
2915: {
2916: rl_point = rl_end;
2917: }
2918:
2919: /* Move forward a word. We do what Emacs does. */
2920: rl_forward_word (count)
2921: int count;
2922: {
2923: int c;
2924:
2925: if (count < 0)
2926: {
2927: rl_backward_word (-count);
2928: return;
2929: }
2930:
2931: while (count)
2932: {
2933: if (rl_point == rl_end)
2934: return;
2935:
2936: /* If we are not in a word, move forward until we are in one.
2937: Then, move forward until we hit a non-alphabetic character. */
2938: c = the_line[rl_point];
2939: if (!alphabetic (c))
2940: {
2941: while (++rl_point < rl_end)
2942: {
2943: c = the_line[rl_point];
2944: if (alphabetic (c)) break;
2945: }
2946: }
2947: if (rl_point == rl_end) return;
2948: while (++rl_point < rl_end)
2949: {
2950: c = the_line[rl_point];
2951: if (!alphabetic (c)) break;
2952: }
2953: --count;
2954: }
2955: }
2956:
2957: /* Move backward a word. We do what Emacs does. */
2958: rl_backward_word (count)
2959: int count;
2960: {
2961: int c;
2962:
2963: if (count < 0)
2964: {
2965: rl_forward_word (-count);
2966: return;
2967: }
2968:
2969: while (count)
2970: {
2971: if (!rl_point)
2972: return;
2973:
2974: /* Like rl_forward_word (), except that we look at the characters
2975: just before point. */
2976:
2977: c = the_line[rl_point - 1];
2978: if (!alphabetic (c))
2979: {
2980: while (--rl_point)
2981: {
2982: c = the_line[rl_point - 1];
2983: if (alphabetic (c)) break;
2984: }
2985: }
2986:
2987: while (rl_point)
2988: {
2989: c = the_line[rl_point - 1];
2990: if (!alphabetic (c))
2991: break;
2992: else --rl_point;
2993: }
2994: --count;
2995: }
2996: }
2997:
2998: /* Clear the current line. Numeric argument to C-l does this. */
2999: rl_refresh_line ()
3000: {
3001: int curr_line = last_c_pos / screenwidth;
3002: extern char *term_clreol;
3003:
3004: move_vert(curr_line);
3005: move_cursor_relative (0, the_line); /* XXX is this right */
3006:
3007: #ifdef __GO32__
3008: {
3009: int r, c, w;
3010: ScreenGetCursor(&r, &c);
3011: w = ScreenCols();
3012: memset(ScreenPrimary+r*w+c, 0, (w-c)*2);
3013: }
3014: #else /* __GO32__ */
3015: if (term_clreol)
3016: tputs (term_clreol, 1, output_character_function);
3017: #endif /* __GO32__/else */
3018:
3019: rl_forced_update_display ();
3020: rl_display_fixed = 1;
3021: }
3022:
3023: /* C-l typed to a line without quoting clears the screen, and then reprints
3024: the prompt and the current input line. Given a numeric arg, redraw only
3025: the current line. */
3026: rl_clear_screen ()
3027: {
3028: extern char *term_clrpag;
3029:
3030: if (rl_explicit_arg)
3031: {
3032: rl_refresh_line ();
3033: return;
3034: }
3035:
3036: #ifndef __GO32__
3037: if (term_clrpag)
3038: tputs (term_clrpag, 1, output_character_function);
3039: else
3040: #endif /* !__GO32__ */
3041: crlf ();
3042:
3043: rl_forced_update_display ();
3044: rl_display_fixed = 1;
3045: }
3046:
3047: rl_arrow_keys (count, c)
3048: int count, c;
3049: {
3050: int ch;
3051:
3052: ch = rl_read_key ();
3053:
3054: switch (to_upper (ch))
3055: {
3056: case 'A':
3057: rl_get_previous_history (count);
3058: break;
3059:
3060: case 'B':
3061: rl_get_next_history (count);
3062: break;
3063:
3064: case 'C':
3065: rl_forward (count);
3066: break;
3067:
3068: case 'D':
3069: rl_backward (count);
3070: break;
3071:
3072: default:
3073: ding ();
3074: }
3075: }
3076:
3077:
3078: /* **************************************************************** */
3079: /* */
3080: /* Text commands */
3081: /* */
3082: /* **************************************************************** */
3083:
3084: /* Insert the character C at the current location, moving point forward. */
3085: rl_insert (count, c)
3086: int count, c;
3087: {
3088: register int i;
3089: char *string;
3090:
3091: if (count <= 0)
3092: return;
3093:
3094: /* If we can optimize, then do it. But don't let people crash
3095: readline because of extra large arguments. */
3096: if (count > 1 && count < 1024)
3097: {
3098: string = (char *)alloca (1 + count);
3099:
3100: for (i = 0; i < count; i++)
3101: string[i] = c;
3102:
3103: string[i] = '\0';
3104: rl_insert_text (string);
3105: return;
3106: }
3107:
3108: if (count > 1024)
3109: {
3110: int decreaser;
3111:
3112: string = (char *)alloca (1024 + 1);
3113:
3114: for (i = 0; i < 1024; i++)
3115: string[i] = c;
3116:
3117: while (count)
3118: {
3119: decreaser = (count > 1024 ? 1024 : count);
3120: string[decreaser] = '\0';
3121: rl_insert_text (string);
3122: count -= decreaser;
3123: }
3124: return;
3125: }
3126:
3127: /* We are inserting a single character.
3128: If there is pending input, then make a string of all of the
3129: pending characters that are bound to rl_insert, and insert
3130: them all. */
3131: if (any_typein)
3132: {
3133: int key = 0, t;
3134:
3135: i = 0;
3136: string = (char *)alloca (ibuffer_len + 1);
3137: string[i++] = c;
3138:
3139: while ((t = rl_get_char (&key)) &&
3140: (keymap[key].type == ISFUNC &&
3141: keymap[key].function == rl_insert))
3142: string[i++] = key;
3143:
3144: if (t)
3145: rl_unget_char (key);
3146:
3147: string[i] = '\0';
3148: rl_insert_text (string);
3149: return;
3150: }
3151: else
3152: {
3153: /* Inserting a single character. */
3154: string = (char *)alloca (2);
3155:
3156: string[1] = '\0';
3157: string[0] = c;
3158: rl_insert_text (string);
3159: }
3160: }
3161:
3162: /* Insert the next typed character verbatim. */
3163: rl_quoted_insert (count)
3164: int count;
3165: {
3166: int c = rl_read_key ();
3167: rl_insert (count, c);
3168: }
3169:
3170: /* Insert a tab character. */
3171: rl_tab_insert (count)
3172: int count;
3173: {
3174: rl_insert (count, '\t');
3175: }
3176:
3177: /* What to do when a NEWLINE is pressed. We accept the whole line.
3178: KEY is the key that invoked this command. I guess it could have
3179: meaning in the future. */
3180: rl_newline (count, key)
3181: int count, key;
3182: {
3183:
3184: rl_done = 1;
3185:
3186: #if defined (VI_MODE)
3187: {
3188: extern int vi_doing_insert;
3189: if (vi_doing_insert)
3190: {
3191: rl_end_undo_group ();
3192: vi_doing_insert = 0;
3193: }
3194: }
3195: #endif /* VI_MODE */
3196:
3197: if (readline_echoing_p)
3198: {
3199: move_vert (vis_botlin);
3200: vis_botlin = 0;
3201: crlf ();
3202: fflush (out_stream);
3203: rl_display_fixed++;
3204: }
3205: }
3206:
3207: rl_clean_up_for_exit ()
3208: {
3209: if (readline_echoing_p)
3210: {
3211: move_vert (vis_botlin);
3212: vis_botlin = 0;
3213: fflush (out_stream);
3214: rl_restart_output ();
3215: }
3216: }
3217:
3218: /* What to do for some uppercase characters, like meta characters,
3219: and some characters appearing in emacs_ctlx_keymap. This function
3220: is just a stub, you bind keys to it and the code in rl_dispatch ()
3221: is special cased. */
3222: rl_do_lowercase_version (ignore1, ignore2)
3223: int ignore1, ignore2;
3224: {
3225: }
3226:
3227: /* Rubout the character behind point. */
3228: rl_rubout (count)
3229: int count;
3230: {
3231: if (count < 0)
3232: {
3233: rl_delete (-count);
3234: return;
3235: }
3236:
3237: if (!rl_point)
3238: {
3239: ding ();
3240: return;
3241: }
3242:
3243: if (count > 1)
3244: {
3245: int orig_point = rl_point;
3246: rl_backward (count);
3247: rl_kill_text (orig_point, rl_point);
3248: }
3249: else
3250: {
3251: int c = the_line[--rl_point];
3252: rl_delete_text (rl_point, rl_point + 1);
3253:
3254: if (rl_point == rl_end && alphabetic (c) && last_c_pos)
3255: {
3256: backspace (1);
3257: putc (' ', out_stream);
3258: backspace (1);
3259: last_c_pos--;
3260: visible_line[last_c_pos] = '\0';
3261: rl_display_fixed++;
3262: }
3263: }
3264: }
3265:
3266: /* Delete the character under the cursor. Given a numeric argument,
3267: kill that many characters instead. */
3268: rl_delete (count, invoking_key)
3269: int count, invoking_key;
3270: {
3271: if (count < 0)
3272: {
3273: rl_rubout (-count);
3274: return;
3275: }
3276:
3277: if (rl_point == rl_end)
3278: {
3279: ding ();
3280: return;
3281: }
3282:
3283: if (count > 1)
3284: {
3285: int orig_point = rl_point;
3286: rl_forward (count);
3287: rl_kill_text (orig_point, rl_point);
3288: rl_point = orig_point;
3289: }
3290: else
3291: rl_delete_text (rl_point, rl_point + 1);
3292: }
3293:
3294:
3295: /* **************************************************************** */
3296: /* */
3297: /* Kill commands */
3298: /* */
3299: /* **************************************************************** */
3300:
3301: /* The next two functions mimic unix line editing behaviour, except they
3302: save the deleted text on the kill ring. This is safer than not saving
3303: it, and since we have a ring, nobody should get screwed. */
3304:
3305: /* This does what C-w does in Unix. We can't prevent people from
3306: using behaviour that they expect. */
3307: rl_unix_word_rubout ()
3308: {
3309: if (!rl_point) ding ();
3310: else {
3311: int orig_point = rl_point;
3312: while (rl_point && whitespace (the_line[rl_point - 1]))
3313: rl_point--;
3314: while (rl_point && !whitespace (the_line[rl_point - 1]))
3315: rl_point--;
3316: rl_kill_text (rl_point, orig_point);
3317: }
3318: }
3319:
3320: /* Here is C-u doing what Unix does. You don't *have* to use these
3321: key-bindings. We have a choice of killing the entire line, or
3322: killing from where we are to the start of the line. We choose the
3323: latter, because if you are a Unix weenie, then you haven't backspaced
3324: into the line at all, and if you aren't, then you know what you are
3325: doing. */
3326: rl_unix_line_discard ()
3327: {
3328: if (!rl_point) ding ();
3329: else {
3330: rl_kill_text (rl_point, 0);
3331: rl_point = 0;
3332: }
3333: }
3334:
3335:
3336:
3337: /* **************************************************************** */
3338: /* */
3339: /* Commands For Typos */
3340: /* */
3341: /* **************************************************************** */
3342:
3343: /* Random and interesting things in here. */
3344:
3345: /* **************************************************************** */
3346: /* */
3347: /* Changing Case */
3348: /* */
3349: /* **************************************************************** */
3350:
3351: /* The three kinds of things that we know how to do. */
3352: #define UpCase 1
3353: #define DownCase 2
3354: #define CapCase 3
3355:
3356: /* Uppercase the word at point. */
3357: rl_upcase_word (count)
3358: int count;
3359: {
3360: rl_change_case (count, UpCase);
3361: }
3362:
3363: /* Lowercase the word at point. */
3364: rl_downcase_word (count)
3365: int count;
3366: {
3367: rl_change_case (count, DownCase);
3368: }
3369:
3370: /* Upcase the first letter, downcase the rest. */
3371: rl_capitalize_word (count)
3372: int count;
3373: {
3374: rl_change_case (count, CapCase);
3375: }
3376:
3377: /* The meaty function.
3378: Change the case of COUNT words, performing OP on them.
3379: OP is one of UpCase, DownCase, or CapCase.
3380: If a negative argument is given, leave point where it started,
3381: otherwise, leave it where it moves to. */
3382: rl_change_case (count, op)
3383: int count, op;
3384: {
3385: register int start = rl_point, end;
3386: int state = 0;
3387:
3388: rl_forward_word (count);
3389: end = rl_point;
3390:
3391: if (count < 0)
3392: {
3393: int temp = start;
3394: start = end;
3395: end = temp;
3396: }
3397:
3398: /* We are going to modify some text, so let's prepare to undo it. */
3399: rl_modifying (start, end);
3400:
3401: for (; start < end; start++)
3402: {
3403: switch (op)
3404: {
3405: case UpCase:
3406: the_line[start] = to_upper (the_line[start]);
3407: break;
3408:
3409: case DownCase:
3410: the_line[start] = to_lower (the_line[start]);
3411: break;
3412:
3413: case CapCase:
3414: if (state == 0)
3415: {
3416: the_line[start] = to_upper (the_line[start]);
3417: state = 1;
3418: }
3419: else
3420: {
3421: the_line[start] = to_lower (the_line[start]);
3422: }
3423: if (!pure_alphabetic (the_line[start]))
3424: state = 0;
3425: break;
3426:
3427: default:
3428: abort ();
3429: }
3430: }
3431: rl_point = end;
3432: }
3433:
3434: /* **************************************************************** */
3435: /* */
3436: /* Transposition */
3437: /* */
3438: /* **************************************************************** */
3439:
3440: /* Transpose the words at point. */
3441: rl_transpose_words (count)
3442: int count;
3443: {
3444: char *word1, *word2;
3445: int w1_beg, w1_end, w2_beg, w2_end;
3446: int orig_point = rl_point;
3447:
3448: if (!count) return;
3449:
3450: /* Find the two words. */
3451: rl_forward_word (count);
3452: w2_end = rl_point;
3453: rl_backward_word (1);
3454: w2_beg = rl_point;
3455: rl_backward_word (count);
3456: w1_beg = rl_point;
3457: rl_forward_word (1);
3458: w1_end = rl_point;
3459:
3460: /* Do some check to make sure that there really are two words. */
3461: if ((w1_beg == w2_beg) || (w2_beg < w1_end))
3462: {
3463: ding ();
3464: rl_point = orig_point;
3465: return;
3466: }
3467:
3468: /* Get the text of the words. */
3469: word1 = rl_copy (w1_beg, w1_end);
3470: word2 = rl_copy (w2_beg, w2_end);
3471:
3472: /* We are about to do many insertions and deletions. Remember them
3473: as one operation. */
3474: rl_begin_undo_group ();
3475:
3476: /* Do the stuff at word2 first, so that we don't have to worry
3477: about word1 moving. */
3478: rl_point = w2_beg;
3479: rl_delete_text (w2_beg, w2_end);
3480: rl_insert_text (word1);
3481:
3482: rl_point = w1_beg;
3483: rl_delete_text (w1_beg, w1_end);
3484: rl_insert_text (word2);
3485:
3486: /* This is exactly correct since the text before this point has not
3487: changed in length. */
3488: rl_point = w2_end;
3489:
3490: /* I think that does it. */
3491: rl_end_undo_group ();
3492: free (word1); free (word2);
3493: }
3494:
3495: /* Transpose the characters at point. If point is at the end of the line,
3496: then transpose the characters before point. */
3497: rl_transpose_chars (count)
3498: int count;
3499: {
3500: if (!count)
3501: return;
3502:
3503: if (!rl_point || rl_end < 2) {
3504: ding ();
3505: return;
3506: }
3507:
3508: while (count)
3509: {
3510: if (rl_point == rl_end)
3511: {
3512: int t = the_line[rl_point - 1];
3513:
3514: the_line[rl_point - 1] = the_line[rl_point - 2];
3515: the_line[rl_point - 2] = t;
3516: }
3517: else
3518: {
3519: int t = the_line[rl_point];
3520:
3521: the_line[rl_point] = the_line[rl_point - 1];
3522: the_line[rl_point - 1] = t;
3523:
3524: if (count < 0 && rl_point)
3525: rl_point--;
3526: else
3527: rl_point++;
3528: }
3529:
3530: if (count < 0)
3531: count++;
3532: else
3533: count--;
3534: }
3535: }
3536:
3537:
3538: /* **************************************************************** */
3539: /* */
3540: /* Bogus Flow Control */
3541: /* */
3542: /* **************************************************************** */
3543:
3544: rl_restart_output (count, key)
3545: int count, key;
3546: {
3547: int fildes = fileno (rl_outstream);
3548: #if defined (TIOCSTART)
3549: #if defined (apollo)
3550: ioctl (&fildes, TIOCSTART, 0);
3551: #else
3552: ioctl (fildes, TIOCSTART, 0);
3553: #endif /* apollo */
3554:
3555: #else
3556: # if defined (TERMIOS_TTY_DRIVER)
3557: tcflow (fildes, TCOON);
3558: # else
3559: # if defined (TCXONC)
3560: ioctl (fildes, TCXONC, TCOON);
3561: # endif /* TCXONC */
3562: # endif /* !TERMIOS_TTY_DRIVER */
3563: #endif /* TIOCSTART */
3564: }
3565:
3566: rl_stop_output (count, key)
3567: int count, key;
3568: {
3569: int fildes = fileno (rl_instream);
3570:
3571: #if defined (TIOCSTOP)
3572: # if defined (apollo)
3573: ioctl (&fildes, TIOCSTOP, 0);
3574: # else
3575: ioctl (fildes, TIOCSTOP, 0);
3576: # endif /* apollo */
3577: #else
3578: # if defined (TERMIOS_TTY_DRIVER)
3579: tcflow (fildes, TCOOFF);
3580: # else
3581: # if defined (TCXONC)
3582: ioctl (fildes, TCXONC, TCOON);
3583: # endif /* TCXONC */
3584: # endif /* !TERMIOS_TTY_DRIVER */
3585: #endif /* TIOCSTOP */
3586: }
3587:
3588: /* **************************************************************** */
3589: /* */
3590: /* Completion matching, from readline's point of view. */
3591: /* */
3592: /* **************************************************************** */
3593:
3594: /* Pointer to the generator function for completion_matches ().
3595: NULL means to use filename_entry_function (), the default filename
3596: completer. */
3597: Function *rl_completion_entry_function = (Function *)NULL;
3598:
3599: /* Pointer to alternative function to create matches.
3600: Function is called with TEXT, START, and END.
3601: START and END are indices in RL_LINE_BUFFER saying what the boundaries
3602: of TEXT are.
3603: If this function exists and returns NULL then call the value of
3604: rl_completion_entry_function to try to match, otherwise use the
3605: array of strings returned. */
3606: Function *rl_attempted_completion_function = (Function *)NULL;
3607:
3608: /* Local variable states what happened during the last completion attempt. */
3609: static int completion_changed_buffer = 0;
3610:
3611: /* Complete the word at or before point. You have supplied the function
3612: that does the initial simple matching selection algorithm (see
3613: completion_matches ()). The default is to do filename completion. */
3614:
3615: rl_complete (ignore, invoking_key)
3616: int ignore, invoking_key;
3617: {
3618: if (rl_last_func == rl_complete && !completion_changed_buffer)
3619: rl_complete_internal ('?');
3620: else
3621: rl_complete_internal (TAB);
3622: }
3623:
3624: /* List the possible completions. See description of rl_complete (). */
3625: rl_possible_completions ()
3626: {
3627: rl_complete_internal ('?');
3628: }
3629:
3630: /* The user must press "y" or "n". Non-zero return means "y" pressed. */
3631: get_y_or_n ()
3632: {
3633: int c;
3634: loop:
3635: c = rl_read_key ();
3636: if (c == 'y' || c == 'Y') return (1);
3637: if (c == 'n' || c == 'N') return (0);
3638: if (c == ABORT_CHAR) rl_abort ();
3639: ding (); goto loop;
3640: }
3641:
3642: /* Up to this many items will be displayed in response to a
3643: possible-completions call. After that, we ask the user if
3644: she is sure she wants to see them all. */
3645: int rl_completion_query_items = 100;
3646:
3647: /* The basic list of characters that signal a break between words for the
3648: completer routine. The contents of this variable is what breaks words
3649: in the shell, i.e. " \t\n\"\\'`@$><=" */
3650: char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
3651:
3652: /* The list of characters that signal a break between words for
3653: rl_complete_internal. The default list is the contents of
3654: rl_basic_word_break_characters. */
3655: char *rl_completer_word_break_characters = (char *)NULL;
3656:
3657: /* The list of characters which are used to quote a substring of the command
3658: line. Command completion occurs on the entire substring, and within the
3659: substring rl_completer_word_break_characters are treated as any other
3660: character, unless they also appear within this list. */
3661: char *rl_completer_quote_characters = (char *)NULL;
3662:
3663: /* List of characters that are word break characters, but should be left
3664: in TEXT when it is passed to the completion function. The shell uses
3665: this to help determine what kind of completing to do. */
3666: char *rl_special_prefixes = (char *)NULL;
3667:
3668: /* If non-zero, then disallow duplicates in the matches. */
3669: int rl_ignore_completion_duplicates = 1;
3670:
3671: /* Non-zero means that the results of the matches are to be treated
3672: as filenames. This is ALWAYS zero on entry, and can only be changed
3673: within a completion entry finder function. */
3674: int rl_filename_completion_desired = 0;
3675:
3676: /* This function, if defined, is called by the completer when real
3677: filename completion is done, after all the matching names have been
3678: generated. It is passed a (char**) known as matches in the code below.
3679: It consists of a NULL-terminated array of pointers to potential
3680: matching strings. The 1st element (matches[0]) is the maximal
3681: substring that is common to all matches. This function can re-arrange
3682: the list of matches as required, but all elements of the array must be
3683: free()'d if they are deleted. The main intent of this function is
3684: to implement FIGNORE a la SunOS csh. */
3685: Function *rl_ignore_some_completions_function = (Function *)NULL;
3686:
3687: /* Complete the word at or before point.
3688: WHAT_TO_DO says what to do with the completion.
3689: `?' means list the possible completions.
3690: TAB means do standard completion.
3691: `*' means insert all of the possible completions. */
3692: rl_complete_internal (what_to_do)
3693: int what_to_do;
3694: {
3695: char *filename_completion_function ();
3696: char **completion_matches (), **matches;
3697: Function *our_func;
3698: int start, scan, end, delimiter = 0;
3699: char *text, *saved_line_buffer;
3700: char quote_char = '\0';
3701: char *replacement;
3702:
3703: if (the_line)
3704: saved_line_buffer = savestring (the_line);
3705: else
3706: saved_line_buffer = (char *)NULL;
3707:
3708: if (rl_completion_entry_function)
3709: our_func = rl_completion_entry_function;
3710: else
3711: our_func = (int (*)())filename_completion_function;
3712:
3713: /* Only the completion entry function can change this. */
3714: rl_filename_completion_desired = 0;
3715:
3716: /* We now look backwards for the start of a filename/variable word. */
3717: end = rl_point;
3718:
3719: if (rl_point)
3720: {
3721: if (rl_completer_quote_characters)
3722: {
3723: /* We have a list of characters which can be used in pairs to quote
3724: substrings for completion. Try to find the start of an unclosed
3725: quoted substring.
3726: FIXME: Doesn't yet handle '\' escapes to hid embedded quotes */
3727: for (scan = 0; scan < end; scan++)
3728: {
3729: if (quote_char != '\0')
3730: {
3731: /* Ignore everything until the matching close quote char */
3732: if (the_line[scan] == quote_char)
3733: {
3734: /* Found matching close quote. Abandon this substring. */
3735: quote_char = '\0';
3736: rl_point = end;
3737: }
3738: }
3739: else if (rindex (rl_completer_quote_characters, the_line[scan]))
3740: {
3741: /* Found start of a quoted substring. */
3742: quote_char = the_line[scan];
3743: rl_point = scan + 1;
3744: }
3745: }
3746: }
3747: if (rl_point == end)
3748: {
3749: /* We didn't find an unclosed quoted substring upon which to do
3750: completion, so use the word break characters to find the
3751: substring on which to do completion. */
3752: while (--rl_point &&
3753: !rindex (rl_completer_word_break_characters,
3754: the_line[rl_point])) {;}
3755: }
3756:
3757: /* If we are at a word break, then advance past it. */
3758: if (rindex (rl_completer_word_break_characters, the_line[rl_point]))
3759: {
3760: /* If the character that caused the word break was a quoting
3761: character, then remember it as the delimiter. */
3762: if (rindex ("\"'", the_line[rl_point]) && (end - rl_point) > 1)
3763: delimiter = the_line[rl_point];
3764:
3765: /* If the character isn't needed to determine something special
3766: about what kind of completion to perform, then advance past it. */
3767:
3768: if (!rl_special_prefixes ||
3769: !rindex (rl_special_prefixes, the_line[rl_point]))
3770: rl_point++;
3771: }
3772: }
3773:
3774: start = rl_point;
3775: rl_point = end;
3776: text = rl_copy (start, end);
3777:
3778: /* If the user wants to TRY to complete, but then wants to give
3779: up and use the default completion function, they set the
3780: variable rl_attempted_completion_function. */
3781: if (rl_attempted_completion_function)
3782: {
3783: matches =
3784: (char **)(*rl_attempted_completion_function) (text, start, end);
3785:
3786: if (matches)
3787: {
3788: our_func = (Function *)NULL;
3789: goto after_usual_completion;
3790: }
3791: }
3792:
3793: matches = completion_matches (text, our_func);
3794:
3795: after_usual_completion:
3796: free (text);
3797:
3798: if (!matches)
3799: ding ();
3800: else
3801: {
3802: register int i;
3803:
3804: some_matches:
3805:
3806: /* It seems to me that in all the cases we handle we would like
3807: to ignore duplicate possibilities. Scan for the text to
3808: insert being identical to the other completions. */
3809: if (rl_ignore_completion_duplicates)
3810: {
3811: char *lowest_common;
3812: int j, newlen = 0;
3813:
3814: /* Sort the items. */
3815: /* It is safe to sort this array, because the lowest common
3816: denominator found in matches[0] will remain in place. */
3817: for (i = 0; matches[i]; i++);
3818: qsort (matches, i, sizeof (char *), compare_strings);
3819:
3820: /* Remember the lowest common denominator for it may be unique. */
3821: lowest_common = savestring (matches[0]);
3822:
3823: for (i = 0; matches[i + 1]; i++)
3824: {
3825: if (strcmp (matches[i], matches[i + 1]) == 0)
3826: {
3827: free (matches[i]);
3828: matches[i] = (char *)-1;
3829: }
3830: else
3831: newlen++;
3832: }
3833:
3834: /* We have marked all the dead slots with (char *)-1.
3835: Copy all the non-dead entries into a new array. */
3836: {
3837: char **temp_array =
3838: (char **)malloc ((3 + newlen) * sizeof (char *));
3839:
3840: for (i = 1, j = 1; matches[i]; i++)
3841: {
3842: if (matches[i] != (char *)-1)
3843: temp_array[j++] = matches[i];
3844: }
3845:
3846: temp_array[j] = (char *)NULL;
3847:
3848: if (matches[0] != (char *)-1)
3849: free (matches[0]);
3850:
3851: free (matches);
3852:
3853: matches = temp_array;
3854: }
3855:
3856: /* Place the lowest common denominator back in [0]. */
3857: matches[0] = lowest_common;
3858:
3859: /* If there is one string left, and it is identical to the
3860: lowest common denominator, then the LCD is the string to
3861: insert. */
3862: if (j == 2 && strcmp (matches[0], matches[1]) == 0)
3863: {
3864: free (matches[1]);
3865: matches[1] = (char *)NULL;
3866: }
3867: }
3868:
3869: switch (what_to_do)
3870: {
3871: case TAB:
3872: /* If we are matching filenames, then here is our chance to
3873: do clever processing by re-examining the list. Call the
3874: ignore function with the array as a parameter. It can
3875: munge the array, deleting matches as it desires. */
3876: if (rl_ignore_some_completions_function &&
3877: our_func == (int (*)())filename_completion_function)
3878: (void)(*rl_ignore_some_completions_function)(matches);
3879:
3880: /* If we are doing completions on quoted substrings, and any matches
3881: contain any of the completer word break characters, then auto-
3882: matically prepend the substring with a quote character (just
3883: pick the first one from the list of such) if it does not already
3884: begin with a quote string. FIXME: Need to remove any such
3885: automatically inserted quote character when it no longer is
3886: necessary, such as if we change the string we are completing on
3887: and the new set of matches don't require a quoted substring? */
3888:
3889: replacement = matches[0];
3890: if (matches[0] != NULL
3891: && rl_completer_quote_characters != NULL
3892: && (quote_char == '\0'))
3893: {
3894: for (i = 1; matches[i] != NULL; i++)
3895: {
3896: if (strpbrk (matches[i], rl_completer_word_break_characters))
3897: {
3898: /* Found an embedded word break character in a potential
3899: match, so need to prepend a quote character if we are
3900: replacing the completion string. */
3901: replacement = (char *)alloca (strlen (matches[0]) + 2);
3902: quote_char = *rl_completer_quote_characters;
3903: *replacement = quote_char;
3904: strcpy (replacement + 1, matches[0]);
3905: break;
3906: }
3907: }
3908: }
3909: if (replacement)
3910: {
3911: rl_delete_text (start, rl_point);
3912: rl_point = start;
3913: rl_insert_text (replacement);
3914: }
3915:
3916: /* If there are more matches, ring the bell to indicate.
3917: If this was the only match, and we are hacking files,
3918: check the file to see if it was a directory. If so,
3919: add a '/' to the name. If not, and we are at the end
3920: of the line, then add a space. */
3921: if (matches[1])
3922: {
3923: ding (); /* There are other matches remaining. */
3924: }
3925: else
3926: {
3927: char temp_string[16];
3928: int temp_index = 0;
3929:
3930: if (quote_char)
3931: {
3932: temp_string[temp_index++] = quote_char;
3933: }
3934: temp_string[temp_index++] = delimiter ? delimiter : ' ';
3935: temp_string[temp_index++] = '\0';
3936:
3937: if (rl_filename_completion_desired)
3938: {
3939: struct stat finfo;
3940: char *filename = tilde_expand (matches[0]);
3941:
3942: if ((stat (filename, &finfo) == 0) &&
3943: S_ISDIR (finfo.st_mode))
3944: {
3945: if (the_line[rl_point] != '/')
3946: rl_insert_text ("/");
3947: }
3948: else
3949: {
3950: if (rl_point == rl_end)
3951: rl_insert_text (temp_string);
3952: }
3953: free (filename);
3954: }
3955: else
3956: {
3957: if (rl_point == rl_end)
3958: rl_insert_text (temp_string);
3959: }
3960: }
3961: break;
3962:
3963: case '*':
3964: {
3965: int i = 1;
3966:
3967: rl_delete_text (start, rl_point);
3968: rl_point = start;
3969: rl_begin_undo_group ();
3970: if (matches[1])
3971: {
3972: while (matches[i])
3973: {
3974: rl_insert_text (matches[i++]);
3975: rl_insert_text (" ");
3976: }
3977: }
3978: else
3979: {
3980: rl_insert_text (matches[0]);
3981: rl_insert_text (" ");
3982: }
3983: rl_end_undo_group ();
3984: }
3985: break;
3986:
3987: case '?':
3988: {
3989: int len, count, limit, max = 0;
3990: int j, k, l;
3991:
3992: /* Handle simple case first. What if there is only one answer? */
3993: if (!matches[1])
3994: {
3995: char *temp;
3996:
3997: if (rl_filename_completion_desired)
3998: temp = rindex (matches[0], '/');
3999: else
4000: temp = (char *)NULL;
4001:
4002: if (!temp)
4003: temp = matches[0];
4004: else
4005: temp++;
4006:
4007: crlf ();
4008: fprintf (out_stream, "%s", temp);
4009: crlf ();
4010: goto restart;
4011: }
4012:
4013: /* There is more than one answer. Find out how many there are,
4014: and find out what the maximum printed length of a single entry
4015: is. */
4016: for (i = 1; matches[i]; i++)
4017: {
4018: char *temp = (char *)NULL;
4019:
4020: /* If we are hacking filenames, then only count the characters
4021: after the last slash in the pathname. */
4022: if (rl_filename_completion_desired)
4023: temp = rindex (matches[i], '/');
4024: else
4025: temp = (char *)NULL;
4026:
4027: if (!temp)
4028: temp = matches[i];
4029: else
4030: temp++;
4031:
4032: if (strlen (temp) > max)
4033: max = strlen (temp);
4034: }
4035:
4036: len = i;
4037:
4038: /* If there are many items, then ask the user if she
4039: really wants to see them all. */
4040: if (len >= rl_completion_query_items)
4041: {
4042: crlf ();
4043: fprintf (out_stream,
4044: "There are %d possibilities. Do you really", len);
4045: crlf ();
4046: fprintf (out_stream, "wish to see them all? (y or n)");
4047: fflush (out_stream);
4048: if (!get_y_or_n ())
4049: {
4050: crlf ();
4051: goto restart;
4052: }
4053: }
4054: /* How many items of MAX length can we fit in the screen window? */
4055: max += 2;
4056: limit = screenwidth / max;
4057: if (limit != 1 && (limit * max == screenwidth))
4058: limit--;
4059:
4060: /* Avoid a possible floating exception. If max > screenwidth,
4061: limit will be 0 and a divide-by-zero fault will result. */
4062: if (limit == 0)
4063: limit = 1;
4064:
4065: /* How many iterations of the printing loop? */
4066: count = (len + (limit - 1)) / limit;
4067:
4068: /* Watch out for special case. If LEN is less than LIMIT, then
4069: just do the inner printing loop. */
4070: if (len < limit) count = 1;
4071:
4072: /* Sort the items if they are not already sorted. */
4073: if (!rl_ignore_completion_duplicates)
4074: qsort (matches, len, sizeof (char *), compare_strings);
4075:
4076: /* Print the sorted items, up-and-down alphabetically, like
4077: ls might. */
4078: crlf ();
4079:
4080: for (i = 1; i < count + 1; i++)
4081: {
4082: for (j = 0, l = i; j < limit; j++)
4083: {
4084: if (l > len || !matches[l])
4085: {
4086: break;
4087: }
4088: else
4089: {
4090: char *temp = (char *)NULL;
4091:
4092: if (rl_filename_completion_desired)
4093: temp = rindex (matches[l], '/');
4094: else
4095: temp = (char *)NULL;
4096:
4097: if (!temp)
4098: temp = matches[l];
4099: else
4100: temp++;
4101:
4102: fprintf (out_stream, "%s", temp);
4103: for (k = 0; k < max - strlen (temp); k++)
4104: putc (' ', out_stream);
4105: }
4106: l += count;
4107: }
4108: crlf ();
4109: }
4110: restart:
4111:
4112: rl_on_new_line ();
4113: }
4114: break;
4115:
4116: default:
4117: abort ();
4118: }
4119:
4120: for (i = 0; matches[i]; i++)
4121: free (matches[i]);
4122: free (matches);
4123: }
4124:
4125: /* Check to see if the line has changed through all of this manipulation. */
4126: if (saved_line_buffer)
4127: {
4128: if (strcmp (the_line, saved_line_buffer) != 0)
4129: completion_changed_buffer = 1;
4130: else
4131: completion_changed_buffer = 0;
4132:
4133: free (saved_line_buffer);
4134: }
4135: }
4136:
4137: /* Stupid comparison routine for qsort () ing strings. */
4138: static int
4139: compare_strings (s1, s2)
4140: char **s1, **s2;
4141: {
4142: return (strcmp (*s1, *s2));
4143: }
4144:
4145: /* A completion function for usernames.
4146: TEXT contains a partial username preceded by a random
4147: character (usually `~'). */
4148: char *
4149: username_completion_function (text, state)
4150: int state;
4151: char *text;
4152: {
4153: #ifdef __GO32__
4154: return (char *)NULL;
4155: #else /* !__GO32__ */
4156: static char *username = (char *)NULL;
4157: static struct passwd *entry;
4158: static int namelen, first_char, first_char_loc;
4159:
4160: if (!state)
4161: {
4162: if (username)
4163: free (username);
4164:
4165: first_char = *text;
4166:
4167: if (first_char == '~')
4168: first_char_loc = 1;
4169: else
4170: first_char_loc = 0;
4171:
4172: username = savestring (&text[first_char_loc]);
4173: namelen = strlen (username);
4174: setpwent ();
4175: }
4176:
4177: while (entry = getpwent ())
4178: {
4179: if (strncmp (username, entry->pw_name, namelen) == 0)
4180: break;
4181: }
4182:
4183: if (!entry)
4184: {
4185: endpwent ();
4186: return ((char *)NULL);
4187: }
4188: else
4189: {
4190: char *value = (char *)xmalloc (2 + strlen (entry->pw_name));
4191:
4192: *value = *text;
4193:
4194: strcpy (value + first_char_loc, entry->pw_name);
4195:
4196: if (first_char == '~')
4197: rl_filename_completion_desired = 1;
4198:
4199: return (value);
4200: }
4201: #endif /* !__GO32__ */
4202: }
4203:
4204: /* **************************************************************** */
4205: /* */
4206: /* Undo, and Undoing */
4207: /* */
4208: /* **************************************************************** */
4209:
4210: /* Non-zero tells rl_delete_text and rl_insert_text to not add to
4211: the undo list. */
4212: int doing_an_undo = 0;
4213:
4214: /* The current undo list for THE_LINE. */
4215: UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
4216:
4217: /* Remember how to undo something. Concatenate some undos if that
4218: seems right. */
4219: rl_add_undo (what, start, end, text)
4220: enum undo_code what;
4221: int start, end;
4222: char *text;
4223: {
4224: UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
4225: temp->what = what;
4226: temp->start = start;
4227: temp->end = end;
4228: temp->text = text;
4229: temp->next = rl_undo_list;
4230: rl_undo_list = temp;
4231: }
4232:
4233: /* Free the existing undo list. */
4234: free_undo_list ()
4235: {
4236: while (rl_undo_list) {
4237: UNDO_LIST *release = rl_undo_list;
4238: rl_undo_list = rl_undo_list->next;
4239:
4240: if (release->what == UNDO_DELETE)
4241: free (release->text);
4242:
4243: free (release);
4244: }
4245: }
4246:
4247: /* Undo the next thing in the list. Return 0 if there
4248: is nothing to undo, or non-zero if there was. */
4249: int
4250: rl_do_undo ()
4251: {
4252: UNDO_LIST *release;
4253: int waiting_for_begin = 0;
4254:
4255: undo_thing:
4256: if (!rl_undo_list)
4257: return (0);
4258:
4259: doing_an_undo = 1;
4260:
4261: switch (rl_undo_list->what) {
4262:
4263: /* Undoing deletes means inserting some text. */
4264: case UNDO_DELETE:
4265: rl_point = rl_undo_list->start;
4266: rl_insert_text (rl_undo_list->text);
4267: free (rl_undo_list->text);
4268: break;
4269:
4270: /* Undoing inserts means deleting some text. */
4271: case UNDO_INSERT:
4272: rl_delete_text (rl_undo_list->start, rl_undo_list->end);
4273: rl_point = rl_undo_list->start;
4274: break;
4275:
4276: /* Undoing an END means undoing everything 'til we get to
4277: a BEGIN. */
4278: case UNDO_END:
4279: waiting_for_begin++;
4280: break;
4281:
4282: /* Undoing a BEGIN means that we are done with this group. */
4283: case UNDO_BEGIN:
4284: if (waiting_for_begin)
4285: waiting_for_begin--;
4286: else
4287: abort ();
4288: break;
4289: }
4290:
4291: doing_an_undo = 0;
4292:
4293: release = rl_undo_list;
4294: rl_undo_list = rl_undo_list->next;
4295: free (release);
4296:
4297: if (waiting_for_begin)
4298: goto undo_thing;
4299:
4300: return (1);
4301: }
4302:
4303: /* Begin a group. Subsequent undos are undone as an atomic operation. */
4304: rl_begin_undo_group ()
4305: {
4306: rl_add_undo (UNDO_BEGIN, 0, 0, 0);
4307: }
4308:
4309: /* End an undo group started with rl_begin_undo_group (). */
4310: rl_end_undo_group ()
4311: {
4312: rl_add_undo (UNDO_END, 0, 0, 0);
4313: }
4314:
4315: /* Save an undo entry for the text from START to END. */
4316: rl_modifying (start, end)
4317: int start, end;
4318: {
4319: if (start > end)
4320: {
4321: int t = start;
4322: start = end;
4323: end = t;
4324: }
4325:
4326: if (start != end)
4327: {
4328: char *temp = rl_copy (start, end);
4329: rl_begin_undo_group ();
4330: rl_add_undo (UNDO_DELETE, start, end, temp);
4331: rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
4332: rl_end_undo_group ();
4333: }
4334: }
4335:
4336: /* Revert the current line to its previous state. */
4337: rl_revert_line ()
4338: {
4339: if (!rl_undo_list) ding ();
4340: else {
4341: while (rl_undo_list)
4342: rl_do_undo ();
4343: }
4344: }
4345:
4346: /* Do some undoing of things that were done. */
4347: rl_undo_command (count)
4348: {
4349: if (count < 0) return; /* Nothing to do. */
4350:
4351: while (count)
4352: {
4353: if (rl_do_undo ())
4354: {
4355: count--;
4356: }
4357: else
4358: {
4359: ding ();
4360: break;
4361: }
4362: }
4363: }
4364:
4365: /* **************************************************************** */
4366: /* */
4367: /* History Utilities */
4368: /* */
4369: /* **************************************************************** */
4370:
4371: /* We already have a history library, and that is what we use to control
4372: the history features of readline. However, this is our local interface
4373: to the history mechanism. */
4374:
4375: /* While we are editing the history, this is the saved
4376: version of the original line. */
4377: HIST_ENTRY *saved_line_for_history = (HIST_ENTRY *)NULL;
4378:
4379: /* Set the history pointer back to the last entry in the history. */
4380: start_using_history ()
4381: {
4382: using_history ();
4383: if (saved_line_for_history)
4384: free_history_entry (saved_line_for_history);
4385:
4386: saved_line_for_history = (HIST_ENTRY *)NULL;
4387: }
4388:
4389: /* Free the contents (and containing structure) of a HIST_ENTRY. */
4390: free_history_entry (entry)
4391: HIST_ENTRY *entry;
4392: {
4393: if (!entry) return;
4394: if (entry->line)
4395: free (entry->line);
4396: free (entry);
4397: }
4398:
4399: /* Perhaps put back the current line if it has changed. */
4400: maybe_replace_line ()
4401: {
4402: HIST_ENTRY *temp = current_history ();
4403:
4404: /* If the current line has changed, save the changes. */
4405: if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
4406: {
4407: temp = replace_history_entry (where_history (), the_line, rl_undo_list);
4408: free (temp->line);
4409: free (temp);
4410: }
4411: }
4412:
4413: /* Put back the saved_line_for_history if there is one. */
4414: maybe_unsave_line ()
4415: {
4416: if (saved_line_for_history)
4417: {
4418: int line_len;
4419:
4420: line_len = strlen (saved_line_for_history->line);
4421:
4422: if (line_len >= rl_line_buffer_len)
4423: rl_extend_line_buffer (line_len);
4424:
4425: strcpy (the_line, saved_line_for_history->line);
4426: rl_undo_list = (UNDO_LIST *)saved_line_for_history->data;
4427: free_history_entry (saved_line_for_history);
4428: saved_line_for_history = (HIST_ENTRY *)NULL;
4429: rl_end = rl_point = strlen (the_line);
4430: }
4431: else
4432: ding ();
4433: }
4434:
4435: /* Save the current line in saved_line_for_history. */
4436: maybe_save_line ()
4437: {
4438: if (!saved_line_for_history)
4439: {
4440: saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
4441: saved_line_for_history->line = savestring (the_line);
4442: saved_line_for_history->data = (char *)rl_undo_list;
4443: }
4444: }
4445:
4446: /* **************************************************************** */
4447: /* */
4448: /* History Commands */
4449: /* */
4450: /* **************************************************************** */
4451:
4452: /* Meta-< goes to the start of the history. */
4453: rl_beginning_of_history ()
4454: {
4455: rl_get_previous_history (1 + where_history ());
4456: }
4457:
4458: /* Meta-> goes to the end of the history. (The current line). */
4459: rl_end_of_history ()
4460: {
4461: maybe_replace_line ();
4462: using_history ();
4463: maybe_unsave_line ();
4464: }
4465:
4466: /* Move down to the next history line. */
4467: rl_get_next_history (count)
4468: int count;
4469: {
4470: HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
4471:
4472: if (count < 0)
4473: {
4474: rl_get_previous_history (-count);
4475: return;
4476: }
4477:
4478: if (!count)
4479: return;
4480:
4481: maybe_replace_line ();
4482:
4483: while (count)
4484: {
4485: temp = next_history ();
4486: if (!temp)
4487: break;
4488: --count;
4489: }
4490:
4491: if (!temp)
4492: maybe_unsave_line ();
4493: else
4494: {
4495: int line_len;
4496:
4497: line_len = strlen (temp->line);
4498:
4499: if (line_len >= rl_line_buffer_len)
4500: rl_extend_line_buffer (line_len);
4501:
4502: strcpy (the_line, temp->line);
4503: rl_undo_list = (UNDO_LIST *)temp->data;
4504: rl_end = rl_point = strlen (the_line);
4505: #if defined (VI_MODE)
4506: if (rl_editing_mode == vi_mode)
4507: rl_point = 0;
4508: #endif /* VI_MODE */
4509: }
4510: }
4511:
4512: /* Get the previous item out of our interactive history, making it the current
4513: line. If there is no previous history, just ding. */
4514: rl_get_previous_history (count)
4515: int count;
4516: {
4517: HIST_ENTRY *old_temp = (HIST_ENTRY *)NULL;
4518: HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
4519:
4520: if (count < 0)
4521: {
4522: rl_get_next_history (-count);
4523: return;
4524: }
4525:
4526: if (!count)
4527: return;
4528:
4529: /* If we don't have a line saved, then save this one. */
4530: maybe_save_line ();
4531:
4532: /* If the current line has changed, save the changes. */
4533: maybe_replace_line ();
4534:
4535: while (count)
4536: {
4537: temp = previous_history ();
4538: if (!temp)
4539: break;
4540: else
4541: old_temp = temp;
4542: --count;
4543: }
4544:
4545: /* If there was a large argument, and we moved back to the start of the
4546: history, that is not an error. So use the last value found. */
4547: if (!temp && old_temp)
4548: temp = old_temp;
4549:
4550: if (!temp)
4551: ding ();
4552: else
4553: {
4554: int line_len;
4555:
4556: line_len = strlen (temp->line);
4557:
4558: if (line_len >= rl_line_buffer_len)
4559: rl_extend_line_buffer (line_len);
4560:
4561: strcpy (the_line, temp->line);
4562: rl_undo_list = (UNDO_LIST *)temp->data;
4563: rl_end = rl_point = line_len;
4564:
4565: #if defined (VI_MODE)
4566: if (rl_editing_mode == vi_mode)
4567: rl_point = 0;
4568: #endif /* VI_MODE */
4569: }
4570: }
4571:
4572:
4573: /* **************************************************************** */
4574: /* */
4575: /* I-Search and Searching */
4576: /* */
4577: /* **************************************************************** */
4578:
4579: /* Search backwards through the history looking for a string which is typed
4580: interactively. Start with the current line. */
4581: rl_reverse_search_history (sign, key)
4582: int sign;
4583: int key;
4584: {
4585: rl_search_history (-sign, key);
4586: }
4587:
4588: /* Search forwards through the history looking for a string which is typed
4589: interactively. Start with the current line. */
4590: rl_forward_search_history (sign, key)
4591: int sign;
4592: int key;
4593: {
4594: rl_search_history (sign, key);
4595: }
4596:
4597: /* Display the current state of the search in the echo-area.
4598: SEARCH_STRING contains the string that is being searched for,
4599: DIRECTION is zero for forward, or 1 for reverse,
4600: WHERE is the history list number of the current line. If it is
4601: -1, then this line is the starting one. */
4602: rl_display_search (search_string, reverse_p, where)
4603: char *search_string;
4604: int reverse_p, where;
4605: {
4606: char *message = (char *)NULL;
4607:
4608: message =
4609: (char *)alloca (1 + (search_string ? strlen (search_string) : 0) + 30);
4610:
4611: *message = '\0';
4612:
4613: #if defined (NOTDEF)
4614: if (where != -1)
4615: sprintf (message, "[%d]", where + history_base);
4616: #endif /* NOTDEF */
4617:
4618: strcat (message, "(");
4619:
4620: if (reverse_p)
4621: strcat (message, "reverse-");
4622:
4623: strcat (message, "i-search)`");
4624:
4625: if (search_string)
4626: strcat (message, search_string);
4627:
4628: strcat (message, "': ");
4629: rl_message (message, 0, 0);
4630: rl_redisplay ();
4631: }
4632:
4633: /* Search through the history looking for an interactively typed string.
4634: This is analogous to i-search. We start the search in the current line.
4635: DIRECTION is which direction to search; >= 0 means forward, < 0 means
4636: backwards. */
4637: rl_search_history (direction, invoking_key)
4638: int direction;
4639: int invoking_key;
4640: {
4641: /* The string that the user types in to search for. */
4642: char *search_string = (char *)alloca (128);
4643:
4644: /* The current length of SEARCH_STRING. */
4645: int search_string_index;
4646:
4647: /* The list of lines to search through. */
4648: char **lines;
4649:
4650: /* The length of LINES. */
4651: int hlen;
4652:
4653: /* Where we get LINES from. */
4654: HIST_ENTRY **hlist = history_list ();
4655:
4656: register int i = 0;
4657: int orig_point = rl_point;
4658: int orig_line = where_history ();
4659: int last_found_line = orig_line;
4660: int c, done = 0;
4661:
4662: /* The line currently being searched. */
4663: char *sline;
4664:
4665: /* Offset in that line. */
4666: int index;
4667:
4668: /* Non-zero if we are doing a reverse search. */
4669: int reverse = (direction < 0);
4670:
4671: /* Create an arrary of pointers to the lines that we want to search. */
4672: maybe_replace_line ();
4673: if (hlist)
4674: for (i = 0; hlist[i]; i++);
4675:
4676: /* Allocate space for this many lines, +1 for the current input line,
4677: and remember those lines. */
4678: lines = (char **)alloca ((1 + (hlen = i)) * sizeof (char *));
4679: for (i = 0; i < hlen; i++)
4680: lines[i] = hlist[i]->line;
4681:
4682: if (saved_line_for_history)
4683: lines[i] = saved_line_for_history->line;
4684: else
4685: /* So I have to type it in this way instead. */
4686: {
4687: char *alloced_line;
4688:
4689: /* Keep that mips alloca happy. */
4690: alloced_line = (char *)alloca (1 + strlen (the_line));
4691: lines[i] = alloced_line;
4692: strcpy (lines[i], &the_line[0]);
4693: }
4694:
4695: hlen++;
4696:
4697: /* The line where we start the search. */
4698: i = orig_line;
4699:
4700: /* Initialize search parameters. */
4701: *search_string = '\0';
4702: search_string_index = 0;
4703:
4704: /* Normalize DIRECTION into 1 or -1. */
4705: if (direction >= 0)
4706: direction = 1;
4707: else
4708: direction = -1;
4709:
4710: rl_display_search (search_string, reverse, -1);
4711:
4712: sline = the_line;
4713: index = rl_point;
4714:
4715: while (!done)
4716: {
4717: c = rl_read_key ();
4718:
4719: /* Hack C to Do What I Mean. */
4720: {
4721: Function *f = (Function *)NULL;
4722:
4723: if (keymap[c].type == ISFUNC)
4724: {
4725: f = keymap[c].function;
4726:
4727: if (f == rl_reverse_search_history)
4728: c = reverse ? -1 : -2;
4729: else if (f == rl_forward_search_history)
4730: c = !reverse ? -1 : -2;
4731: }
4732: }
4733:
4734: switch (c)
4735: {
4736: case ESC:
4737: done = 1;
4738: continue;
4739:
4740: /* case invoking_key: */
4741: case -1:
4742: goto search_again;
4743:
4744: /* switch directions */
4745: case -2:
4746: direction = -direction;
4747: reverse = (direction < 0);
4748:
4749: goto do_search;
4750:
4751: case CTRL ('G'):
4752: strcpy (the_line, lines[orig_line]);
4753: rl_point = orig_point;
4754: rl_end = strlen (the_line);
4755: rl_clear_message ();
4756: return;
4757:
4758: default:
4759: if (c < 32 || c > 126)
4760: {
4761: rl_execute_next (c);
4762: done = 1;
4763: continue;
4764: }
4765: else
4766: {
4767: search_string[search_string_index++] = c;
4768: search_string[search_string_index] = '\0';
4769: goto do_search;
4770:
4771: search_again:
4772:
4773: if (!search_string_index)
4774: continue;
4775: else
4776: {
4777: if (reverse)
4778: --index;
4779: else
4780: if (index != strlen (sline))
4781: ++index;
4782: else
4783: ding ();
4784: }
4785: do_search:
4786:
4787: while (1)
4788: {
4789: if (reverse)
4790: {
4791: while (index >= 0)
4792: if (strncmp
4793: (search_string, sline + index, search_string_index)
4794: == 0)
4795: goto string_found;
4796: else
4797: index--;
4798: }
4799: else
4800: {
4801: register int limit =
4802: (strlen (sline) - search_string_index) + 1;
4803:
4804: while (index < limit)
4805: {
4806: if (strncmp (search_string,
4807: sline + index,
4808: search_string_index) == 0)
4809: goto string_found;
4810: index++;
4811: }
4812: }
4813:
4814: next_line:
4815: i += direction;
4816:
4817: /* At limit for direction? */
4818: if ((reverse && i < 0) ||
4819: (!reverse && i == hlen))
4820: goto search_failed;
4821:
4822: sline = lines[i];
4823: if (reverse)
4824: index = strlen (sline);
4825: else
4826: index = 0;
4827:
4828: /* If the search string is longer than the current
4829: line, no match. */
4830: if (search_string_index > strlen (sline))
4831: goto next_line;
4832:
4833: /* Start actually searching. */
4834: if (reverse)
4835: index -= search_string_index;
4836: }
4837:
4838: search_failed:
4839: /* We cannot find the search string. Ding the bell. */
4840: ding ();
4841: i = last_found_line;
4842: break;
4843:
4844: string_found:
4845: /* We have found the search string. Just display it. But don't
4846: actually move there in the history list until the user accepts
4847: the location. */
4848: {
4849: int line_len;
4850:
4851: line_len = strlen (lines[i]);
4852:
4853: if (line_len >= rl_line_buffer_len)
4854: rl_extend_line_buffer (line_len);
4855:
4856: strcpy (the_line, lines[i]);
4857: rl_point = index;
4858: rl_end = line_len;
4859: last_found_line = i;
4860: rl_display_search
4861: (search_string, reverse, (i == orig_line) ? -1 : i);
4862: }
4863: }
4864: }
4865: continue;
4866: }
4867:
4868: /* The searching is over. The user may have found the string that she
4869: was looking for, or else she may have exited a failing search. If
4870: INDEX is -1, then that shows that the string searched for was not
4871: found. We use this to determine where to place rl_point. */
4872: {
4873: int now = last_found_line;
4874:
4875: /* First put back the original state. */
4876: strcpy (the_line, lines[orig_line]);
4877:
4878: if (now < orig_line)
4879: rl_get_previous_history (orig_line - now);
4880: else
4881: rl_get_next_history (now - orig_line);
4882:
4883: /* If the index of the "matched" string is less than zero, then the
4884: final search string was never matched, so put point somewhere
4885: reasonable. */
4886: if (index < 0)
4887: index = strlen (the_line);
4888:
4889: rl_point = index;
4890: rl_clear_message ();
4891: }
4892: }
4893:
4894: /* Make C be the next command to be executed. */
4895: rl_execute_next (c)
4896: int c;
4897: {
4898: rl_pending_input = c;
4899: }
4900:
4901: /* **************************************************************** */
4902: /* */
4903: /* Killing Mechanism */
4904: /* */
4905: /* **************************************************************** */
4906:
4907: /* What we assume for a max number of kills. */
4908: #define DEFAULT_MAX_KILLS 10
4909:
4910: /* The real variable to look at to find out when to flush kills. */
4911: int rl_max_kills = DEFAULT_MAX_KILLS;
4912:
4913: /* Where to store killed text. */
4914: char **rl_kill_ring = (char **)NULL;
4915:
4916: /* Where we are in the kill ring. */
4917: int rl_kill_index = 0;
4918:
4919: /* How many slots we have in the kill ring. */
4920: int rl_kill_ring_length = 0;
4921:
4922: /* How to say that you only want to save a certain amount
4923: of kill material. */
4924: rl_set_retained_kills (num)
4925: int num;
4926: {}
4927:
4928: /* The way to kill something. This appends or prepends to the last
4929: kill, if the last command was a kill command. if FROM is less
4930: than TO, then the text is appended, otherwise prepended. If the
4931: last command was not a kill command, then a new slot is made for
4932: this kill. */
4933: rl_kill_text (from, to)
4934: int from, to;
4935: {
4936: int slot;
4937: char *text = rl_copy (from, to);
4938:
4939: /* Is there anything to kill? */
4940: if (from == to)
4941: {
4942: free (text);
4943: last_command_was_kill++;
4944: return;
4945: }
4946:
4947: /* Delete the copied text from the line. */
4948: rl_delete_text (from, to);
4949:
4950: /* First, find the slot to work with. */
4951: if (!last_command_was_kill)
4952: {
4953: /* Get a new slot. */
4954: if (!rl_kill_ring)
4955: {
4956: /* If we don't have any defined, then make one. */
4957: rl_kill_ring = (char **)
4958: xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
4959: slot = 1;
4960: }
4961: else
4962: {
4963: /* We have to add a new slot on the end, unless we have
4964: exceeded the max limit for remembering kills. */
4965: slot = rl_kill_ring_length;
4966: if (slot == rl_max_kills)
4967: {
4968: register int i;
4969: free (rl_kill_ring[0]);
4970: for (i = 0; i < slot; i++)
4971: rl_kill_ring[i] = rl_kill_ring[i + 1];
4972: }
4973: else
4974: {
4975: rl_kill_ring =
4976: (char **)
4977: xrealloc (rl_kill_ring,
4978: ((slot = (rl_kill_ring_length += 1)) + 1)
4979: * sizeof (char *));
4980: }
4981: }
4982: slot--;
4983: }
4984: else
4985: {
4986: slot = rl_kill_ring_length - 1;
4987: }
4988:
4989: /* If the last command was a kill, prepend or append. */
4990: if (last_command_was_kill && rl_editing_mode != vi_mode)
4991: {
4992: char *old = rl_kill_ring[slot];
4993: char *new = (char *)xmalloc (1 + strlen (old) + strlen (text));
4994:
4995: if (from < to)
4996: {
4997: strcpy (new, old);
4998: strcat (new, text);
4999: }
5000: else
5001: {
5002: strcpy (new, text);
5003: strcat (new, old);
5004: }
5005: free (old);
5006: free (text);
5007: rl_kill_ring[slot] = new;
5008: }
5009: else
5010: {
5011: rl_kill_ring[slot] = text;
5012: }
5013: rl_kill_index = slot;
5014: last_command_was_kill++;
5015: }
5016:
5017: /* Now REMEMBER! In order to do prepending or appending correctly, kill
5018: commands always make rl_point's original position be the FROM argument,
5019: and rl_point's extent be the TO argument. */
5020:
5021: /* **************************************************************** */
5022: /* */
5023: /* Killing Commands */
5024: /* */
5025: /* **************************************************************** */
5026:
5027: /* Delete the word at point, saving the text in the kill ring. */
5028: rl_kill_word (count)
5029: int count;
5030: {
5031: int orig_point = rl_point;
5032:
5033: if (count < 0)
5034: rl_backward_kill_word (-count);
5035: else
5036: {
5037: rl_forward_word (count);
5038:
5039: if (rl_point != orig_point)
5040: rl_kill_text (orig_point, rl_point);
5041:
5042: rl_point = orig_point;
5043: }
5044: }
5045:
5046: /* Rubout the word before point, placing it on the kill ring. */
5047: rl_backward_kill_word (count)
5048: int count;
5049: {
5050: int orig_point = rl_point;
5051:
5052: if (count < 0)
5053: rl_kill_word (-count);
5054: else
5055: {
5056: rl_backward_word (count);
5057:
5058: if (rl_point != orig_point)
5059: rl_kill_text (orig_point, rl_point);
5060: }
5061: }
5062:
5063: /* Kill from here to the end of the line. If DIRECTION is negative, kill
5064: back to the line start instead. */
5065: rl_kill_line (direction)
5066: int direction;
5067: {
5068: int orig_point = rl_point;
5069:
5070: if (direction < 0)
5071: rl_backward_kill_line (1);
5072: else
5073: {
5074: rl_end_of_line ();
5075: if (orig_point != rl_point)
5076: rl_kill_text (orig_point, rl_point);
5077: rl_point = orig_point;
5078: }
5079: }
5080:
5081: /* Kill backwards to the start of the line. If DIRECTION is negative, kill
5082: forwards to the line end instead. */
5083: rl_backward_kill_line (direction)
5084: int direction;
5085: {
5086: int orig_point = rl_point;
5087:
5088: if (direction < 0)
5089: rl_kill_line (1);
5090: else
5091: {
5092: if (!rl_point)
5093: ding ();
5094: else
5095: {
5096: rl_beg_of_line ();
5097: rl_kill_text (orig_point, rl_point);
5098: }
5099: }
5100: }
5101:
5102: /* Yank back the last killed text. This ignores arguments. */
5103: rl_yank ()
5104: {
5105: if (!rl_kill_ring) rl_abort ();
5106: rl_insert_text (rl_kill_ring[rl_kill_index]);
5107: }
5108:
5109: /* If the last command was yank, or yank_pop, and the text just
5110: before point is identical to the current kill item, then
5111: delete that text from the line, rotate the index down, and
5112: yank back some other text. */
5113: rl_yank_pop ()
5114: {
5115: int l;
5116:
5117: if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
5118: !rl_kill_ring)
5119: {
5120: rl_abort ();
5121: }
5122:
5123: l = strlen (rl_kill_ring[rl_kill_index]);
5124: if (((rl_point - l) >= 0) &&
5125: (strncmp (the_line + (rl_point - l),
5126: rl_kill_ring[rl_kill_index], l) == 0))
5127: {
5128: rl_delete_text ((rl_point - l), rl_point);
5129: rl_point -= l;
5130: rl_kill_index--;
5131: if (rl_kill_index < 0)
5132: rl_kill_index = rl_kill_ring_length - 1;
5133: rl_yank ();
5134: }
5135: else
5136: rl_abort ();
5137:
5138: }
5139:
5140: /* Yank the COUNTth argument from the previous history line. */
5141: rl_yank_nth_arg (count, ignore)
5142: int count;
5143: {
5144: register HIST_ENTRY *entry = previous_history ();
5145: char *arg;
5146:
5147: if (entry)
5148: next_history ();
5149: else
5150: {
5151: ding ();
5152: return;
5153: }
5154:
5155: arg = history_arg_extract (count, count, entry->line);
5156: if (!arg || !*arg)
5157: {
5158: ding ();
5159: return;
5160: }
5161:
5162: rl_begin_undo_group ();
5163:
5164: #if defined (VI_MODE)
5165: /* Vi mode always inserts a space befoe yanking the argument, and it
5166: inserts it right *after* rl_point. */
5167: if (rl_editing_mode == vi_mode)
5168: rl_point++;
5169: #endif /* VI_MODE */
5170:
5171: if (rl_point && the_line[rl_point - 1] != ' ')
5172: rl_insert_text (" ");
5173:
5174: rl_insert_text (arg);
5175: free (arg);
5176:
5177: rl_end_undo_group ();
5178: }
5179:
5180: /* How to toggle back and forth between editing modes. */
5181: rl_vi_editing_mode ()
5182: {
5183: #if defined (VI_MODE)
5184: rl_editing_mode = vi_mode;
5185: rl_vi_insertion_mode ();
5186: #endif /* VI_MODE */
5187: }
5188:
5189: rl_emacs_editing_mode ()
5190: {
5191: rl_editing_mode = emacs_mode;
5192: keymap = emacs_standard_keymap;
5193: }
5194:
5195:
5196: /* **************************************************************** */
5197: /* */
5198: /* Completion */
5199: /* */
5200: /* **************************************************************** */
5201:
5202: /* Non-zero means that case is not significant in completion. */
5203: int completion_case_fold = 0;
5204:
5205: /* Return an array of (char *) which is a list of completions for TEXT.
5206: If there are no completions, return a NULL pointer.
5207: The first entry in the returned array is the substitution for TEXT.
5208: The remaining entries are the possible completions.
5209: The array is terminated with a NULL pointer.
5210:
5211: ENTRY_FUNCTION is a function of two args, and returns a (char *).
5212: The first argument is TEXT.
5213: The second is a state argument; it should be zero on the first call, and
5214: non-zero on subsequent calls. It returns a NULL pointer to the caller
5215: when there are no more matches.
5216: */
5217: char **
5218: completion_matches (text, entry_function)
5219: char *text;
5220: char *(*entry_function) ();
5221: {
5222: /* Number of slots in match_list. */
5223: int match_list_size;
5224:
5225: /* The list of matches. */
5226: char **match_list =
5227: (char **)xmalloc (((match_list_size = 10) + 1) * sizeof (char *));
5228:
5229: /* Number of matches actually found. */
5230: int matches = 0;
5231:
5232: /* Temporary string binder. */
5233: char *string;
5234:
5235: match_list[1] = (char *)NULL;
5236:
5237: while (string = (*entry_function) (text, matches))
5238: {
5239: if (matches + 1 == match_list_size)
5240: match_list = (char **)xrealloc
5241: (match_list, ((match_list_size += 10) + 1) * sizeof (char *));
5242:
5243: match_list[++matches] = string;
5244: match_list[matches + 1] = (char *)NULL;
5245: }
5246:
5247: /* If there were any matches, then look through them finding out the
5248: lowest common denominator. That then becomes match_list[0]. */
5249: if (matches)
5250: {
5251: register int i = 1;
5252: int low = 100000; /* Count of max-matched characters. */
5253:
5254: /* If only one match, just use that. */
5255: if (matches == 1)
5256: {
5257: match_list[0] = match_list[1];
5258: match_list[1] = (char *)NULL;
5259: }
5260: else
5261: {
5262: /* Otherwise, compare each member of the list with
5263: the next, finding out where they stop matching. */
5264:
5265: while (i < matches)
5266: {
5267: register int c1, c2, si;
5268:
5269: if (completion_case_fold)
5270: {
5271: for (si = 0;
5272: (c1 = to_lower(match_list[i][si])) &&
5273: (c2 = to_lower(match_list[i + 1][si]));
5274: si++)
5275: if (c1 != c2) break;
5276: }
5277: else
5278: {
5279: for (si = 0;
5280: (c1 = match_list[i][si]) &&
5281: (c2 = match_list[i + 1][si]);
5282: si++)
5283: if (c1 != c2) break;
5284: }
5285:
5286: if (low > si) low = si;
5287: i++;
5288: }
5289: match_list[0] = (char *)xmalloc (low + 1);
5290: strncpy (match_list[0], match_list[1], low);
5291: match_list[0][low] = '\0';
5292: }
5293: }
5294: else /* There were no matches. */
5295: {
5296: free (match_list);
5297: match_list = (char **)NULL;
5298: }
5299: return (match_list);
5300: }
5301:
5302: /* Okay, now we write the entry_function for filename completion. In the
5303: general case. Note that completion in the shell is a little different
5304: because of all the pathnames that must be followed when looking up the
5305: completion for a command. */
5306: char *
5307: filename_completion_function (text, state)
5308: int state;
5309: char *text;
5310: {
5311: static DIR *directory;
5312: static char *filename = (char *)NULL;
5313: static char *dirname = (char *)NULL;
5314: static char *users_dirname = (char *)NULL;
5315: static int filename_len;
5316:
5317: dirent *entry = (dirent *)NULL;
5318:
5319: /* If we don't have any state, then do some initialization. */
5320: if (!state)
5321: {
5322: char *temp;
5323:
5324: if (dirname) free (dirname);
5325: if (filename) free (filename);
5326: if (users_dirname) free (users_dirname);
5327:
5328: filename = savestring (text);
5329: if (!*text) text = ".";
5330: dirname = savestring (text);
5331:
5332: temp = rindex (dirname, '/');
5333:
5334: if (temp)
5335: {
5336: strcpy (filename, ++temp);
5337: *temp = '\0';
5338: }
5339: else
5340: strcpy (dirname, ".");
5341:
5342: /* We aren't done yet. We also support the "~user" syntax. */
5343:
5344: /* Save the version of the directory that the user typed. */
5345: users_dirname = savestring (dirname);
5346: {
5347: char *temp_dirname;
5348:
5349: temp_dirname = tilde_expand (dirname);
5350: free (dirname);
5351: dirname = temp_dirname;
5352:
5353: if (rl_symbolic_link_hook)
5354: (*rl_symbolic_link_hook) (&dirname);
5355: }
5356: directory = opendir (dirname);
5357: filename_len = strlen (filename);
5358:
5359: rl_filename_completion_desired = 1;
5360: }
5361:
5362: /* At this point we should entertain the possibility of hacking wildcarded
5363: filenames, like /usr/man/man<WILD>/te<TAB>. If the directory name
5364: contains globbing characters, then build an array of directories to
5365: glob on, and glob on the first one. */
5366:
5367: /* Now that we have some state, we can read the directory. */
5368:
5369: while (directory && (entry = readdir (directory)))
5370: {
5371: /* Special case for no filename.
5372: All entries except "." and ".." match. */
5373: if (!filename_len)
5374: {
5375: if ((strcmp (entry->d_name, ".") != 0) &&
5376: (strcmp (entry->d_name, "..") != 0))
5377: break;
5378: }
5379: else
5380: {
5381: /* Otherwise, if these match upto the length of filename, then
5382: it is a match. */
5383: if (entry->d_name[0] == filename[0] && /* Quick test */
5384: (strncmp (filename, entry->d_name, filename_len) == 0))
5385: {
5386: break;
5387: }
5388: }
5389: }
5390:
5391: if (!entry)
5392: {
5393: if (directory)
5394: {
5395: closedir (directory);
5396: directory = (DIR *)NULL;
5397: }
5398: return (char *)NULL;
5399: }
5400: else
5401: {
5402: char *temp;
5403:
5404: if (dirname && (strcmp (dirname, ".") != 0))
5405: {
5406: temp = (char *)
5407: xmalloc (1 + strlen (users_dirname) + strlen (entry->d_name));
5408: strcpy (temp, users_dirname);
5409: strcat (temp, entry->d_name);
5410: }
5411: else
5412: {
5413: temp = (savestring (entry->d_name));
5414: }
5415: return (temp);
5416: }
5417: }
5418:
5419:
5420: /* **************************************************************** */
5421: /* */
5422: /* Binding keys */
5423: /* */
5424: /* **************************************************************** */
5425:
5426: /* rl_add_defun (char *name, Function *function, int key)
5427: Add NAME to the list of named functions. Make FUNCTION
5428: be the function that gets called.
5429: If KEY is not -1, then bind it. */
5430: rl_add_defun (name, function, key)
5431: char *name;
5432: Function *function;
5433: int key;
5434: {
5435: if (key != -1)
5436: rl_bind_key (key, function);
5437: rl_add_funmap_entry (name, function);
5438: }
5439:
5440: /* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */
5441: int
5442: rl_bind_key (key, function)
5443: int key;
5444: Function *function;
5445: {
5446: if (key < 0)
5447: return (key);
5448:
5449: if (key > 127 && key < 256)
5450: {
5451: if (keymap[ESC].type == ISKMAP)
5452: {
5453: Keymap escmap = (Keymap)keymap[ESC].function;
5454:
5455: key -= 128;
5456: escmap[key].type = ISFUNC;
5457: escmap[key].function = function;
5458: return (0);
5459: }
5460: return (key);
5461: }
5462:
5463: keymap[key].type = ISFUNC;
5464: keymap[key].function = function;
5465: return (0);
5466: }
5467:
5468: /* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid
5469: KEY. */
5470: int
5471: rl_bind_key_in_map (key, function, map)
5472: int key;
5473: Function *function;
5474: Keymap map;
5475: {
5476: int result;
5477: Keymap oldmap = keymap;
5478:
5479: keymap = map;
5480: result = rl_bind_key (key, function);
5481: keymap = oldmap;
5482: return (result);
5483: }
5484:
5485: /* Make KEY do nothing in the currently selected keymap.
5486: Returns non-zero in case of error. */
5487: int
5488: rl_unbind_key (key)
5489: int key;
5490: {
5491: return (rl_bind_key (key, (Function *)NULL));
5492: }
5493:
5494: /* Make KEY do nothing in MAP.
5495: Returns non-zero in case of error. */
5496: int
5497: rl_unbind_key_in_map (key, map)
5498: int key;
5499: Keymap map;
5500: {
5501: return (rl_bind_key_in_map (key, (Function *)NULL, map));
5502: }
5503:
5504: /* Bind the key sequence represented by the string KEYSEQ to
5505: FUNCTION. This makes new keymaps as necessary. The initial
5506: place to do bindings is in MAP. */
5507: rl_set_key (keyseq, function, map)
5508: char *keyseq;
5509: Function *function;
5510: Keymap map;
5511: {
5512: rl_generic_bind (ISFUNC, keyseq, function, map);
5513: }
5514:
5515: /* Bind the key sequence represented by the string KEYSEQ to
5516: the string of characters MACRO. This makes new keymaps as
5517: necessary. The initial place to do bindings is in MAP. */
5518: rl_macro_bind (keyseq, macro, map)
5519: char *keyseq, *macro;
5520: Keymap map;
5521: {
5522: char *macro_keys;
5523: int macro_keys_len;
5524:
5525: macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1);
5526:
5527: if (rl_translate_keyseq (macro, macro_keys, ¯o_keys_len))
5528: {
5529: free (macro_keys);
5530: return;
5531: }
5532: rl_generic_bind (ISMACR, keyseq, macro_keys, map);
5533: }
5534:
5535: /* Bind the key sequence represented by the string KEYSEQ to
5536: the arbitrary pointer DATA. TYPE says what kind of data is
5537: pointed to by DATA, right now this can be a function (ISFUNC),
5538: a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps
5539: as necessary. The initial place to do bindings is in MAP. */
5540:
5541: static void
5542: rl_generic_bind (type, keyseq, data, map)
5543: int type;
5544: char *keyseq, *data;
5545: Keymap map;
5546: {
5547: char *keys;
5548: int keys_len;
5549: register int i;
5550:
5551: /* If no keys to bind to, exit right away. */
5552: if (!keyseq || !*keyseq)
5553: {
5554: if (type == ISMACR)
5555: free (data);
5556: return;
5557: }
5558:
5559: keys = (char *)alloca (1 + (2 * strlen (keyseq)));
5560:
5561: /* Translate the ASCII representation of KEYSEQ into an array
5562: of characters. Stuff the characters into ARRAY, and the
5563: length of ARRAY into LENGTH. */
5564: if (rl_translate_keyseq (keyseq, keys, &keys_len))
5565: return;
5566:
5567: /* Bind keys, making new keymaps as necessary. */
5568: for (i = 0; i < keys_len; i++)
5569: {
5570: if (i + 1 < keys_len)
5571: {
5572: if (map[keys[i]].type != ISKMAP)
5573: {
5574: if (map[i].type == ISMACR)
5575: free ((char *)map[i].function);
5576:
5577: map[keys[i]].type = ISKMAP;
5578: map[keys[i]].function = (Function *)rl_make_bare_keymap ();
5579: }
5580: map = (Keymap)map[keys[i]].function;
5581: }
5582: else
5583: {
5584: if (map[keys[i]].type == ISMACR)
5585: free ((char *)map[keys[i]].function);
5586:
5587: map[keys[i]].function = (Function *)data;
5588: map[keys[i]].type = type;
5589: }
5590: }
5591: }
5592:
5593: /* Translate the ASCII representation of SEQ, stuffing the
5594: values into ARRAY, an array of characters. LEN gets the
5595: final length of ARRAY. Return non-zero if there was an
5596: error parsing SEQ. */
5597: rl_translate_keyseq (seq, array, len)
5598: char *seq, *array;
5599: int *len;
5600: {
5601: register int i, c, l = 0;
5602:
5603: for (i = 0; c = seq[i]; i++)
5604: {
5605: if (c == '\\')
5606: {
5607: c = seq[++i];
5608:
5609: if (!c)
5610: break;
5611:
5612: if (((c == 'C' || c == 'M') && seq[i + 1] == '-') ||
5613: (c == 'e'))
5614: {
5615: /* Handle special case of backwards define. */
5616: if (strncmp (&seq[i], "C-\\M-", 5) == 0)
5617: {
5618: array[l++] = ESC;
5619: i += 5;
5620: array[l++] = CTRL (to_upper (seq[i]));
5621: if (!seq[i])
5622: i--;
5623: continue;
5624: }
5625:
5626: switch (c)
5627: {
5628: case 'M':
5629: i++;
5630: array[l++] = ESC;
5631: break;
5632:
5633: case 'C':
5634: i += 2;
5635: /* Special hack for C-?... */
5636: if (seq[i] == '?')
5637: array[l++] = RUBOUT;
5638: else
5639: array[l++] = CTRL (to_upper (seq[i]));
5640: break;
5641:
5642: case 'e':
5643: array[l++] = ESC;
5644: }
5645:
5646: continue;
5647: }
5648: }
5649: array[l++] = c;
5650: }
5651:
5652: *len = l;
5653: array[l] = '\0';
5654: return (0);
5655: }
5656:
5657: /* Return a pointer to the function that STRING represents.
5658: If STRING doesn't have a matching function, then a NULL pointer
5659: is returned. */
5660: Function *
5661: rl_named_function (string)
5662: char *string;
5663: {
5664: register int i;
5665:
5666: for (i = 0; funmap[i]; i++)
5667: if (stricmp (funmap[i]->name, string) == 0)
5668: return (funmap[i]->function);
5669: return ((Function *)NULL);
5670: }
5671:
5672: /* The last key bindings file read. */
5673: #ifdef __MSDOS__
5674: /* Don't know what to do, but this is a guess */
5675: static char *last_readline_init_file = "/INPUTRC";
5676: #else
5677: static char *last_readline_init_file = "~/.inputrc";
5678: #endif
5679:
5680: /* Re-read the current keybindings file. */
5681: rl_re_read_init_file (count, ignore)
5682: int count, ignore;
5683: {
5684: rl_read_init_file ((char *)NULL);
5685: }
5686:
5687: /* Do key bindings from a file. If FILENAME is NULL it defaults
5688: to `~/.inputrc'. If the file existed and could be opened and
5689: read, 0 is returned, otherwise errno is returned. */
5690: int
5691: rl_read_init_file (filename)
5692: char *filename;
5693: {
5694: register int i;
5695: char *buffer, *openname, *line, *end;
5696: struct stat finfo;
5697: int file;
5698:
5699: /* Default the filename. */
5700: if (!filename)
5701: filename = last_readline_init_file;
5702:
5703: openname = tilde_expand (filename);
5704:
5705: if (!openname || *openname == '\000')
5706: return ENOENT;
5707:
5708: if ((stat (openname, &finfo) < 0) ||
5709: (file = open (openname, O_RDONLY, 0666)) < 0)
5710: {
5711: free (openname);
5712: return (errno);
5713: }
5714: else
5715: free (openname);
5716:
5717: last_readline_init_file = filename;
5718:
5719: /* Read the file into BUFFER. */
5720: buffer = (char *)xmalloc (finfo.st_size + 1);
5721: i = read (file, buffer, finfo.st_size);
5722: close (file);
5723:
5724: if (i != finfo.st_size)
5725: return (errno);
5726:
5727: /* Loop over the lines in the file. Lines that start with `#' are
5728: comments; all other lines are commands for readline initialization. */
5729: line = buffer;
5730: end = buffer + finfo.st_size;
5731: while (line < end)
5732: {
5733: /* Find the end of this line. */
5734: for (i = 0; line + i != end && line[i] != '\n'; i++);
5735:
5736: /* Mark end of line. */
5737: line[i] = '\0';
5738:
5739: /* If the line is not a comment, then parse it. */
5740: if (*line != '#')
5741: rl_parse_and_bind (line);
5742:
5743: /* Move to the next line. */
5744: line += i + 1;
5745: }
5746: return (0);
5747: }
5748:
5749: /* **************************************************************** */
5750: /* */
5751: /* Parser Directives */
5752: /* */
5753: /* **************************************************************** */
5754:
5755: /* Conditionals. */
5756:
5757: /* Calling programs set this to have their argv[0]. */
5758: char *rl_readline_name = "other";
5759:
5760: /* Stack of previous values of parsing_conditionalized_out. */
5761: static unsigned char *if_stack = (unsigned char *)NULL;
5762: static int if_stack_depth = 0;
5763: static int if_stack_size = 0;
5764:
5765: /* Push parsing_conditionalized_out, and set parser state based on ARGS. */
5766: parser_if (args)
5767: char *args;
5768: {
5769: register int i;
5770:
5771: /* Push parser state. */
5772: if (if_stack_depth + 1 >= if_stack_size)
5773: {
5774: if (!if_stack)
5775: if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
5776: else
5777: if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);
5778: }
5779: if_stack[if_stack_depth++] = parsing_conditionalized_out;
5780:
5781: /* If parsing is turned off, then nothing can turn it back on except
5782: for finding the matching endif. In that case, return right now. */
5783: if (parsing_conditionalized_out)
5784: return;
5785:
5786: /* Isolate first argument. */
5787: for (i = 0; args[i] && !whitespace (args[i]); i++);
5788:
5789: if (args[i])
5790: args[i++] = '\0';
5791:
5792: /* Handle "if term=foo" and "if mode=emacs" constructs. If this
5793: isn't term=foo, or mode=emacs, then check to see if the first
5794: word in ARGS is the same as the value stored in rl_readline_name. */
5795: if (rl_terminal_name && strnicmp (args, "term=", 5) == 0)
5796: {
5797: char *tem, *tname;
5798:
5799: /* Terminals like "aaa-60" are equivalent to "aaa". */
5800: tname = savestring (rl_terminal_name);
5801: tem = rindex (tname, '-');
5802: if (tem)
5803: *tem = '\0';
5804:
5805: if (stricmp (args + 5, tname) == 0)
5806: parsing_conditionalized_out = 0;
5807: else
5808: parsing_conditionalized_out = 1;
5809: }
5810: #if defined (VI_MODE)
5811: else if (strnicmp (args, "mode=", 5) == 0)
5812: {
5813: int mode;
5814:
5815: if (stricmp (args + 5, "emacs") == 0)
5816: mode = emacs_mode;
5817: else if (stricmp (args + 5, "vi") == 0)
5818: mode = vi_mode;
5819: else
5820: mode = no_mode;
5821:
5822: if (mode == rl_editing_mode)
5823: parsing_conditionalized_out = 0;
5824: else
5825: parsing_conditionalized_out = 1;
5826: }
5827: #endif /* VI_MODE */
5828: /* Check to see if the first word in ARGS is the same as the
5829: value stored in rl_readline_name. */
5830: else if (stricmp (args, rl_readline_name) == 0)
5831: parsing_conditionalized_out = 0;
5832: else
5833: parsing_conditionalized_out = 1;
5834: }
5835:
5836: /* Invert the current parser state if there is anything on the stack. */
5837: parser_else (args)
5838: char *args;
5839: {
5840: register int i;
5841:
5842: if (!if_stack_depth)
5843: {
5844: /* Error message? */
5845: return;
5846: }
5847:
5848: /* Check the previous (n - 1) levels of the stack to make sure that
5849: we haven't previously turned off parsing. */
5850: for (i = 0; i < if_stack_depth - 1; i++)
5851: if (if_stack[i] == 1)
5852: return;
5853:
5854: /* Invert the state of parsing if at top level. */
5855: parsing_conditionalized_out = !parsing_conditionalized_out;
5856: }
5857:
5858: /* Terminate a conditional, popping the value of
5859: parsing_conditionalized_out from the stack. */
5860: parser_endif (args)
5861: char *args;
5862: {
5863: if (if_stack_depth)
5864: parsing_conditionalized_out = if_stack[--if_stack_depth];
5865: else
5866: {
5867: /* *** What, no error message? *** */
5868: }
5869: }
5870:
5871: /* Associate textual names with actual functions. */
5872: static struct {
5873: char *name;
5874: Function *function;
5875: } parser_directives [] = {
5876: { "if", parser_if },
5877: { "endif", parser_endif },
5878: { "else", parser_else },
5879: { (char *)0x0, (Function *)0x0 }
5880: };
5881:
5882: /* Handle a parser directive. STATEMENT is the line of the directive
5883: without any leading `$'. */
5884: static int
5885: handle_parser_directive (statement)
5886: char *statement;
5887: {
5888: register int i;
5889: char *directive, *args;
5890:
5891: /* Isolate the actual directive. */
5892:
5893: /* Skip whitespace. */
5894: for (i = 0; whitespace (statement[i]); i++);
5895:
5896: directive = &statement[i];
5897:
5898: for (; statement[i] && !whitespace (statement[i]); i++);
5899:
5900: if (statement[i])
5901: statement[i++] = '\0';
5902:
5903: for (; statement[i] && whitespace (statement[i]); i++);
5904:
5905: args = &statement[i];
5906:
5907: /* Lookup the command, and act on it. */
5908: for (i = 0; parser_directives[i].name; i++)
5909: if (stricmp (directive, parser_directives[i].name) == 0)
5910: {
5911: (*parser_directives[i].function) (args);
5912: return (0);
5913: }
5914:
5915: /* *** Should an error message be output? */
5916: return (1);
5917: }
5918:
5919: /* Ugly but working hack for binding prefix meta. */
5920: #define PREFIX_META_HACK
5921:
5922: static int substring_member_of_array ();
5923:
5924: /* Read the binding command from STRING and perform it.
5925: A key binding command looks like: Keyname: function-name\0,
5926: a variable binding command looks like: set variable value.
5927: A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
5928: rl_parse_and_bind (string)
5929: char *string;
5930: {
5931: extern char *possible_control_prefixes[], *possible_meta_prefixes[];
5932: char *funname, *kname;
5933: register int c;
5934: int key, i;
5935:
5936: while (string && whitespace (*string))
5937: string++;
5938:
5939: if (!string || !*string || *string == '#')
5940: return;
5941:
5942: /* If this is a parser directive, act on it. */
5943: if (*string == '$')
5944: {
5945: handle_parser_directive (&string[1]);
5946: return;
5947: }
5948:
5949: /* If we are supposed to be skipping parsing right now, then do it. */
5950: if (parsing_conditionalized_out)
5951: return;
5952:
5953: i = 0;
5954: /* If this keyname is a complex key expression surrounded by quotes,
5955: advance to after the matching close quote. */
5956: if (*string == '"')
5957: {
5958: for (i = 1; c = string[i]; i++)
5959: {
5960: if (c == '"' && string[i - 1] != '\\')
5961: break;
5962: }
5963: }
5964:
5965: /* Advance to the colon (:) or whitespace which separates the two objects. */
5966: for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
5967:
5968: /* Mark the end of the command (or keyname). */
5969: if (string[i])
5970: string[i++] = '\0';
5971:
5972: /* If this is a command to set a variable, then do that. */
5973: if (stricmp (string, "set") == 0)
5974: {
5975: char *var = string + i;
5976: char *value;
5977:
5978: /* Make VAR point to start of variable name. */
5979: while (*var && whitespace (*var)) var++;
5980:
5981: /* Make value point to start of value string. */
5982: value = var;
5983: while (*value && !whitespace (*value)) value++;
5984: if (*value)
5985: *value++ = '\0';
5986: while (*value && whitespace (*value)) value++;
5987:
5988: rl_variable_bind (var, value);
5989: return;
5990: }
5991:
5992: /* Skip any whitespace between keyname and funname. */
5993: for (; string[i] && whitespace (string[i]); i++);
5994: funname = &string[i];
5995:
5996: /* Now isolate funname.
5997: For straight function names just look for whitespace, since
5998: that will signify the end of the string. But this could be a
5999: macro definition. In that case, the string is quoted, so skip
6000: to the matching delimiter. */
6001: if (*funname == '\'' || *funname == '"')
6002: {
6003: int delimiter = string[i++];
6004:
6005: for (; c = string[i]; i++)
6006: {
6007: if (c == delimiter && string[i - 1] != '\\')
6008: break;
6009: }
6010: if (c)
6011: i++;
6012: }
6013:
6014: /* Advance to the end of the string. */
6015: for (; string[i] && !whitespace (string[i]); i++);
6016:
6017: /* No extra whitespace at the end of the string. */
6018: string[i] = '\0';
6019:
6020: /* If this is a new-style key-binding, then do the binding with
6021: rl_set_key (). Otherwise, let the older code deal with it. */
6022: if (*string == '"')
6023: {
6024: char *seq = (char *)alloca (1 + strlen (string));
6025: register int j, k = 0;
6026:
6027: for (j = 1; string[j]; j++)
6028: {
6029: if (string[j] == '"' && string[j - 1] != '\\')
6030: break;
6031:
6032: seq[k++] = string[j];
6033: }
6034: seq[k] = '\0';
6035:
6036: /* Binding macro? */
6037: if (*funname == '\'' || *funname == '"')
6038: {
6039: j = strlen (funname);
6040:
6041: if (j && funname[j - 1] == *funname)
6042: funname[j - 1] = '\0';
6043:
6044: rl_macro_bind (seq, &funname[1], keymap);
6045: }
6046: else
6047: rl_set_key (seq, rl_named_function (funname), keymap);
6048:
6049: return;
6050: }
6051:
6052: /* Get the actual character we want to deal with. */
6053: kname = rindex (string, '-');
6054: if (!kname)
6055: kname = string;
6056: else
6057: kname++;
6058:
6059: key = glean_key_from_name (kname);
6060:
6061: /* Add in control and meta bits. */
6062: if (substring_member_of_array (string, possible_control_prefixes))
6063: key = CTRL (to_upper (key));
6064:
6065: if (substring_member_of_array (string, possible_meta_prefixes))
6066: key = META (key);
6067:
6068: /* Temporary. Handle old-style keyname with macro-binding. */
6069: if (*funname == '\'' || *funname == '"')
6070: {
6071: char seq[2];
6072: int fl = strlen (funname);
6073:
6074: seq[0] = key; seq[1] = '\0';
6075: if (fl && funname[fl - 1] == *funname)
6076: funname[fl - 1] = '\0';
6077:
6078: rl_macro_bind (seq, &funname[1], keymap);
6079: }
6080: #if defined (PREFIX_META_HACK)
6081: /* Ugly, but working hack to keep prefix-meta around. */
6082: else if (stricmp (funname, "prefix-meta") == 0)
6083: {
6084: char seq[2];
6085:
6086: seq[0] = key;
6087: seq[1] = '\0';
6088: rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, keymap);
6089: }
6090: #endif /* PREFIX_META_HACK */
6091: else
6092: rl_bind_key (key, rl_named_function (funname));
6093: }
6094:
6095: rl_variable_bind (name, value)
6096: char *name, *value;
6097: {
6098: if (stricmp (name, "editing-mode") == 0)
6099: {
6100: if (strnicmp (value, "vi", 2) == 0)
6101: {
6102: #if defined (VI_MODE)
6103: keymap = vi_insertion_keymap;
6104: rl_editing_mode = vi_mode;
6105: #else
6106: #if defined (NOTDEF)
6107: /* What state is the terminal in? I'll tell you:
6108: non-determinate! That means we cannot do any output. */
6109: ding ();
6110: #endif /* NOTDEF */
6111: #endif /* VI_MODE */
6112: }
6113: else if (strnicmp (value, "emacs", 5) == 0)
6114: {
6115: keymap = emacs_standard_keymap;
6116: rl_editing_mode = emacs_mode;
6117: }
6118: }
6119: else if (stricmp (name, "horizontal-scroll-mode") == 0)
6120: {
6121: if (!*value || stricmp (value, "On") == 0)
6122: horizontal_scroll_mode = 1;
6123: else
6124: horizontal_scroll_mode = 0;
6125: }
6126: else if (stricmp (name, "mark-modified-lines") == 0)
6127: {
6128: if (!*value || stricmp (value, "On") == 0)
6129: mark_modified_lines = 1;
6130: else
6131: mark_modified_lines = 0;
6132: }
6133: else if (stricmp (name, "prefer-visible-bell") == 0)
6134: {
6135: if (!*value || stricmp (value, "On") == 0)
6136: prefer_visible_bell = 1;
6137: else
6138: prefer_visible_bell = 0;
6139: }
6140: else if (stricmp (name, "comment-begin") == 0)
6141: {
6142: #if defined (VI_MODE)
6143: extern char *rl_vi_comment_begin;
6144:
6145: if (*value)
6146: {
6147: if (rl_vi_comment_begin)
6148: free (rl_vi_comment_begin);
6149:
6150: rl_vi_comment_begin = savestring (value);
6151: }
6152: #endif /* VI_MODE */
6153: }
6154: }
6155:
6156: /* Return the character which matches NAME.
6157: For example, `Space' returns ' '. */
6158:
6159: typedef struct {
6160: char *name;
6161: int value;
6162: } assoc_list;
6163:
6164: assoc_list name_key_alist[] = {
6165: { "DEL", 0x7f },
6166: { "ESC", '\033' },
6167: { "Escape", '\033' },
6168: { "LFD", '\n' },
6169: { "Newline", '\n' },
6170: { "RET", '\r' },
6171: { "Return", '\r' },
6172: { "Rubout", 0x7f },
6173: { "SPC", ' ' },
6174: { "Space", ' ' },
6175: { "Tab", 0x09 },
6176: { (char *)0x0, 0 }
6177: };
6178:
6179: int
6180: glean_key_from_name (name)
6181: char *name;
6182: {
6183: register int i;
6184:
6185: for (i = 0; name_key_alist[i].name; i++)
6186: if (stricmp (name, name_key_alist[i].name) == 0)
6187: return (name_key_alist[i].value);
6188:
6189: return (*name);
6190: }
6191:
6192:
6193: /* **************************************************************** */
6194: /* */
6195: /* Key Binding and Function Information */
6196: /* */
6197: /* **************************************************************** */
6198:
6199: /* Each of the following functions produces information about the
6200: state of keybindings and functions known to Readline. The info
6201: is always printed to rl_outstream, and in such a way that it can
6202: be read back in (i.e., passed to rl_parse_and_bind (). */
6203:
6204: /* Print the names of functions known to Readline. */
6205: void
6206: rl_list_funmap_names (ignore)
6207: int ignore;
6208: {
6209: register int i;
6210: char **funmap_names;
6211: extern char **rl_funmap_names ();
6212:
6213: funmap_names = rl_funmap_names ();
6214:
6215: if (!funmap_names)
6216: return;
6217:
6218: for (i = 0; funmap_names[i]; i++)
6219: fprintf (rl_outstream, "%s\n", funmap_names[i]);
6220:
6221: free (funmap_names);
6222: }
6223:
6224: /* Return a NULL terminated array of strings which represent the key
6225: sequences that are used to invoke FUNCTION in MAP. */
6226: static char **
6227: invoking_keyseqs_in_map (function, map)
6228: Function *function;
6229: Keymap map;
6230: {
6231: register int key;
6232: char **result;
6233: int result_index, result_size;
6234:
6235: result = (char **)NULL;
6236: result_index = result_size = 0;
6237:
6238: for (key = 0; key < 128; key++)
6239: {
6240: switch (map[key].type)
6241: {
6242: case ISMACR:
6243: /* Macros match, if, and only if, the pointers are identical.
6244: Thus, they are treated exactly like functions in here. */
6245: case ISFUNC:
6246: /* If the function in the keymap is the one we are looking for,
6247: then add the current KEY to the list of invoking keys. */
6248: if (map[key].function == function)
6249: {
6250: char *keyname = (char *)xmalloc (5);
6251:
6252: if (CTRL_P (key))
6253: sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key)));
6254: else if (key == RUBOUT)
6255: sprintf (keyname, "\\C-?");
6256: else
6257: sprintf (keyname, "%c", key);
6258:
6259: if (result_index + 2 > result_size)
6260: {
6261: if (!result)
6262: result = (char **) xmalloc
6263: ((result_size = 10) * sizeof (char *));
6264: else
6265: result = (char **) xrealloc
6266: (result, (result_size += 10) * sizeof (char *));
6267: }
6268:
6269: result[result_index++] = keyname;
6270: result[result_index] = (char *)NULL;
6271: }
6272: break;
6273:
6274: case ISKMAP:
6275: {
6276: char **seqs = (char **)NULL;
6277:
6278: /* Find the list of keyseqs in this map which have FUNCTION as
6279: their target. Add the key sequences found to RESULT. */
6280: if (map[key].function)
6281: seqs =
6282: invoking_keyseqs_in_map (function, (Keymap)map[key].function);
6283:
6284: if (seqs)
6285: {
6286: register int i;
6287:
6288: for (i = 0; seqs[i]; i++)
6289: {
6290: char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
6291:
6292: if (key == ESC)
6293: sprintf (keyname, "\\e");
6294: else if (CTRL_P (key))
6295: sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key)));
6296: else if (key == RUBOUT)
6297: sprintf (keyname, "\\C-?");
6298: else
6299: sprintf (keyname, "%c", key);
6300:
6301: strcat (keyname, seqs[i]);
6302:
6303: if (result_index + 2 > result_size)
6304: {
6305: if (!result)
6306: result = (char **)
6307: xmalloc ((result_size = 10) * sizeof (char *));
6308: else
6309: result = (char **)
6310: xrealloc (result,
6311: (result_size += 10) * sizeof (char *));
6312: }
6313:
6314: result[result_index++] = keyname;
6315: result[result_index] = (char *)NULL;
6316: }
6317: }
6318: }
6319: break;
6320: }
6321: }
6322: return (result);
6323: }
6324:
6325: /* Return a NULL terminated array of strings which represent the key
6326: sequences that can be used to invoke FUNCTION using the current keymap. */
6327: char **
6328: rl_invoking_keyseqs (function)
6329: Function *function;
6330: {
6331: return (invoking_keyseqs_in_map (function, keymap));
6332: }
6333:
6334: /* Print all of the current functions and their bindings to
6335: rl_outstream. If an explicit argument is given, then print
6336: the output in such a way that it can be read back in. */
6337: int
6338: rl_dump_functions (count)
6339: int count;
6340: {
6341: void rl_function_dumper ();
6342:
6343: rl_function_dumper (rl_explicit_arg);
6344: rl_on_new_line ();
6345: return (0);
6346: }
6347:
6348: /* Print all of the functions and their bindings to rl_outstream. If
6349: PRINT_READABLY is non-zero, then print the output in such a way
6350: that it can be read back in. */
6351: void
6352: rl_function_dumper (print_readably)
6353: int print_readably;
6354: {
6355: register int i;
6356: char **rl_funmap_names (), **names;
6357: char *name;
6358:
6359: names = rl_funmap_names ();
6360:
6361: fprintf (rl_outstream, "\n");
6362:
6363: for (i = 0; name = names[i]; i++)
6364: {
6365: Function *function;
6366: char **invokers;
6367:
6368: function = rl_named_function (name);
6369: invokers = invoking_keyseqs_in_map (function, keymap);
6370:
6371: if (print_readably)
6372: {
6373: if (!invokers)
6374: fprintf (rl_outstream, "# %s (not bound)\n", name);
6375: else
6376: {
6377: register int j;
6378:
6379: for (j = 0; invokers[j]; j++)
6380: {
6381: fprintf (rl_outstream, "\"%s\": %s\n",
6382: invokers[j], name);
6383: free (invokers[j]);
6384: }
6385:
6386: free (invokers);
6387: }
6388: }
6389: else
6390: {
6391: if (!invokers)
6392: fprintf (rl_outstream, "%s is not bound to any keys\n",
6393: name);
6394: else
6395: {
6396: register int j;
6397:
6398: fprintf (rl_outstream, "%s can be found on ", name);
6399:
6400: for (j = 0; invokers[j] && j < 5; j++)
6401: {
6402: fprintf (rl_outstream, "\"%s\"%s", invokers[j],
6403: invokers[j + 1] ? ", " : ".\n");
6404: }
6405:
6406: if (j == 5 && invokers[j])
6407: fprintf (rl_outstream, "...\n");
6408:
6409: for (j = 0; invokers[j]; j++)
6410: free (invokers[j]);
6411:
6412: free (invokers);
6413: }
6414: }
6415: }
6416: }
6417:
6418:
6419: /* **************************************************************** */
6420: /* */
6421: /* String Utility Functions */
6422: /* */
6423: /* **************************************************************** */
6424:
6425: static char *strindex ();
6426:
6427: /* Return pointer to first occurance in STRING1 of any character from STRING2,
6428: or NULL if no occurance found. */
6429: static char *
6430: strpbrk (string1, string2)
6431: char *string1, *string2;
6432: {
6433: register char *scan;
6434:
6435: for (; *string1 != '\0'; string1++)
6436: {
6437: for (scan = string2; *scan != '\0'; scan++)
6438: {
6439: if (*string1 == *scan)
6440: {
6441: return (string1);
6442: }
6443: }
6444: }
6445: return (NULL);
6446: }
6447:
6448: /* Return non-zero if any members of ARRAY are a substring in STRING. */
6449: static int
6450: substring_member_of_array (string, array)
6451: char *string, **array;
6452: {
6453: while (*array)
6454: {
6455: if (strindex (string, *array))
6456: return (1);
6457: array++;
6458: }
6459: return (0);
6460: }
6461:
6462: /* Whoops, Unix doesn't have strnicmp. */
6463:
6464: /* Compare at most COUNT characters from string1 to string2. Case
6465: doesn't matter. */
6466: static int
6467: strnicmp (string1, string2, count)
6468: char *string1, *string2;
6469: {
6470: register char ch1, ch2;
6471:
6472: while (count)
6473: {
6474: ch1 = *string1++;
6475: ch2 = *string2++;
6476: if (to_upper(ch1) == to_upper(ch2))
6477: count--;
6478: else break;
6479: }
6480: return (count);
6481: }
6482:
6483: /* strcmp (), but caseless. */
6484: static int
6485: stricmp (string1, string2)
6486: char *string1, *string2;
6487: {
6488: register char ch1, ch2;
6489:
6490: while (*string1 && *string2)
6491: {
6492: ch1 = *string1++;
6493: ch2 = *string2++;
6494: if (to_upper(ch1) != to_upper(ch2))
6495: return (1);
6496: }
6497: return (*string1 | *string2);
6498: }
6499:
6500: /* Determine if s2 occurs in s1. If so, return a pointer to the
6501: match in s1. The compare is case insensitive. */
6502: static char *
6503: strindex (s1, s2)
6504: register char *s1, *s2;
6505: {
6506: register int i, l = strlen (s2);
6507: register int len = strlen (s1);
6508:
6509: for (i = 0; (len - i) >= l; i++)
6510: if (strnicmp (&s1[i], s2, l) == 0)
6511: return (s1 + i);
6512: return ((char *)NULL);
6513: }
6514:
6515:
6516: /* **************************************************************** */
6517: /* */
6518: /* USG (System V) Support */
6519: /* */
6520: /* **************************************************************** */
6521:
6522: /* When compiling and running in the `Posix' environment, Ultrix does
6523: not restart system calls, so this needs to do it. */
6524: int
6525: rl_getc (stream)
6526: FILE *stream;
6527: {
6528: int result;
6529: unsigned char c;
6530:
6531: #ifdef __GO32__
6532: if (isatty(0))
6533: return getkey();
6534: #endif /* __GO32__ */
6535:
6536: while (1)
6537: {
6538: result = read (fileno (stream), &c, sizeof (char));
6539:
6540: if (result == sizeof (char))
6541: return (c);
6542:
6543: /* If zero characters are returned, then the file that we are
6544: reading from is empty! Return EOF in that case. */
6545: if (result == 0)
6546: return (EOF);
6547:
6548: #ifndef __GO32__
6549: /* If the error that we received was SIGINT, then try again,
6550: this is simply an interrupted system call to read ().
6551: Otherwise, some error ocurred, also signifying EOF. */
6552: if (errno != EINTR)
6553: return (EOF);
6554: #endif /* !__GO32__ */
6555: }
6556: }
6557:
6558: #if defined (STATIC_MALLOC)
6559:
6560: /* **************************************************************** */
6561: /* */
6562: /* xmalloc and xrealloc () */
6563: /* */
6564: /* **************************************************************** */
6565:
6566: static void memory_error_and_abort ();
6567:
6568: static char *
6569: xmalloc (bytes)
6570: int bytes;
6571: {
6572: char *temp = (char *)malloc (bytes);
6573:
6574: if (!temp)
6575: memory_error_and_abort ();
6576: return (temp);
6577: }
6578:
6579: static char *
6580: xrealloc (pointer, bytes)
6581: char *pointer;
6582: int bytes;
6583: {
6584: char *temp;
6585:
6586: if (!pointer)
6587: temp = (char *)malloc (bytes);
6588: else
6589: temp = (char *)realloc (pointer, bytes);
6590:
6591: if (!temp)
6592: memory_error_and_abort ();
6593:
6594: return (temp);
6595: }
6596:
6597: static void
6598: memory_error_and_abort ()
6599: {
6600: fprintf (stderr, "readline: Out of virtual memory!\n");
6601: abort ();
6602: }
6603: #endif /* STATIC_MALLOC */
6604:
6605:
6606: /* **************************************************************** */
6607: /* */
6608: /* Testing Readline */
6609: /* */
6610: /* **************************************************************** */
6611:
6612: #if defined (TEST)
6613:
6614: main ()
6615: {
6616: HIST_ENTRY **history_list ();
6617: char *temp = (char *)NULL;
6618: char *prompt = "readline% ";
6619: int done = 0;
6620:
6621: while (!done)
6622: {
6623: temp = readline (prompt);
6624:
6625: /* Test for EOF. */
6626: if (!temp)
6627: exit (1);
6628:
6629: /* If there is anything on the line, print it and remember it. */
6630: if (*temp)
6631: {
6632: fprintf (stderr, "%s\r\n", temp);
6633: add_history (temp);
6634: }
6635:
6636: /* Check for `command' that we handle. */
6637: if (strcmp (temp, "quit") == 0)
6638: done = 1;
6639:
6640: if (strcmp (temp, "list") == 0)
6641: {
6642: HIST_ENTRY **list = history_list ();
6643: register int i;
6644: if (list)
6645: {
6646: for (i = 0; list[i]; i++)
6647: {
6648: fprintf (stderr, "%d: %s\r\n", i, list[i]->line);
6649: free (list[i]->line);
6650: }
6651: free (list);
6652: }
6653: }
6654: free (temp);
6655: }
6656: }
6657:
6658: #endif /* TEST */
6659:
6660:
6661: /*
6662: * Local variables:
6663: * compile-command: "gcc -g -traditional -I. -I.. -DTEST -o readline readline.c keymaps.o funmap.o history.o -ltermcap"
6664: * end:
6665: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.