zsh - ksh/tcsh-like shell (part 7 of 8)

Paul John Falstad pfalstad at phoenix.Princeton.EDU
Sat Dec 15 10:33:21 AEST 1990


---cut here---cut here---cut here---
-/* What YOU turn on when you have handled all redisplay yourself. */
-int rl_display_fixed = 0;
-
-/* The visible cursor position.  If you print some text, adjust this. */
-int last_c_pos = 0;
-int last_v_pos = 0;
-
-/* The last left edge of text that was displayed.  This is used when
-   doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
-static int last_lmargin = 0;
-
-/* The line display buffers.  One is the line currently displayed on
-   the screen.  The other is the line about to be displayed. */
-static char *visible_line = (char *)NULL;
-static char *invisible_line = (char *)NULL;
-
-/* Number of lines currently on screen minus 1. */
-int vis_botlin = 0;
-
-/* A buffer for `modeline' messages. */
-char msg_buf[128];
-
-/* Non-zero forces the redisplay even if we thought it was unnecessary. */
-int forced_display = 0;
-
-/* The stuff that gets printed out before the actual text of the line.
-   This is usually pointing to rl_prompt. */
-char *rl_display_prompt = (char *)NULL;
-
-/* Default and initial buffer size.  Can grow. */
-static int line_size = 1024;
-
-/* Non-zero means to always use horizontal scrolling in line display. */
-int horizontal_scroll_mode = 0;
-
-/* I really disagree with this, but my boss (among others) insists that we
-   support compilers that don't work.  I don't think we are gaining by doing
-   so; what is the advantage in producing better code if we can't use it? */
-/* The following two declarations belong inside the
-   function block, not here. */
-static void move_cursor_relative ();
-static void output_some_chars ();
-static void output_character_function ();
-static int compare_strings ();
-
-/* Basic redisplay algorithm. */
-rl_redisplay ()
-{
-	register int in, out, c, linenum;
-	register char *line = invisible_line;
-	int c_pos = 0;
-	int inv_botlin = 0;		/* Number of lines in newly drawn buffer. */
-
-	extern int readline_echoing_p;
-
-	if (!readline_echoing_p)
-		return;
-
-	if (!rl_display_prompt)
-		rl_display_prompt = "";
-
-	if (!invisible_line)
-	{
-		visible_line = (char *)xmalloc (line_size);
-		invisible_line = (char *)xmalloc (line_size);
-		line = invisible_line;
-		for (in = 0; in < line_size; in++)
-		{
-			visible_line[in] = 0;
-			invisible_line[in] = 1;
-		}
-		rl_on_new_line ();
-	}
-
-	/* Draw the line into the buffer. */
-	c_pos = -1;
-
-	/* Mark the line as modified or not.  We only do this for history
-     lines.  No we don't.  -pjf */
-	out = 0;
-	/*if (current_history () && rl_undo_list)
-    {
-      line[out++] = '*';
-      line[out] = '\0';
-    }*/
-
-	/* If someone thought that the redisplay was handled, but the currently
-     visible line has a different modification state than the one about
-     to become visible, then correct the callers misconception. */
-	if (visible_line[0] != invisible_line[0])
-		rl_display_fixed = 0;
-
-	strncpy (line + out,  rl_display_prompt, strlen (rl_display_prompt));
-	out += strlen (rl_display_prompt);
-	line[out] = '\0';
-
-	for (in = 0; in < rl_end; in++)
-	{
-		c = the_line[in];
-
-		if (out + 1 >= line_size)
-		{
-			line_size *= 2;
-			visible_line = (char *)xrealloc (visible_line, line_size);
-			invisible_line = (char *)xrealloc (invisible_line, line_size);
-			line = invisible_line;
-		}
-
-		if (in == rl_point)
-			c_pos = out;
-
-		if (c > 127)
-		{
-			line[out++] = 'M';
-			line[out++] = '-';
-			line[out++] = c - 128;
-		}
-#define DISPLAY_TABS
-#ifdef DISPLAY_TABS
-		else if (c == '\t')
-		{
-			register int newout = (out | (int)7) + 1;
-			while (out < newout)
-				line[out++] = ' ';
-		}
-#endif
-		else if (c == '\n')
-		{
-			line[out++] = '\\';
-			line[out++] = 'n';
-		}
-		else if (c < 32)
-		{
-			line[out++] = '^';
-			line[out++] = c + 64;
-		}
-		else
-			line[out++] = c;
-	}
-	line[out] = '\0';
-	if (c_pos < 0)
-		c_pos = out;
-
-	/* PWP: now is when things get a bit hairy.  The visible and invisible
-     line buffers are really multiple lines, which would wrap every
-     (screenwidth - 1) characters.  Go through each in turn, finding
-     the changed region and updating it.  The line order is top to bottom. */
-
-	/* If we can move the cursor up and down, then use multiple lines,
-     otherwise, let long lines display in a single terminal line, and
-     horizontally scroll it. */
-
-	if (!horizontal_scroll_mode && term_up && *term_up)
-	{
-		int total_screen_chars = (screenwidth * screenheight);
-
-		if (!rl_display_fixed || forced_display)
-		{
-			forced_display = 0;
-
-			/* If we have more than a screenful of material to display, then
-	     only display a screenful.  We should display the last screen,
-	     not the first.  I'll fix this in a minute. */
-			if (out >= total_screen_chars)
-				out = total_screen_chars - 1;
-
-			/* Number of screen lines to display. */
-			inv_botlin = out / screenwidth;
-
-			/* For each line in the buffer, do the updating display. */
-			for (linenum = 0; linenum <= inv_botlin; linenum++)
-				update_line (linenum > vis_botlin ? ""
-				    : &visible_line[linenum * screenwidth],
-				    &invisible_line[linenum * screenwidth],
-				    linenum);
-
-			/* We may have deleted some lines.  If so, clear the left over
-	     blank ones at the bottom out. */
-			if (vis_botlin > inv_botlin)
-			{
-				char *tt;
-				for (; linenum <= vis_botlin; linenum++)
-				{
-					tt = &visible_line[linenum * screenwidth];
-					move_vert (linenum);
-					move_cursor_relative (0, tt);
-					clear_to_eol ((linenum == vis_botlin)?
-					    strlen (tt) : screenwidth);
-				}
-			}
-			vis_botlin = inv_botlin;
-
-			/* Move the cursor where it should be. */
-			move_vert (c_pos / screenwidth);
-			move_cursor_relative (c_pos % screenwidth,
-			    &invisible_line[(c_pos / screenwidth) * screenwidth]);
-		}
-	}
-	else	/* Do horizontal scrolling. */
-	{
-		int lmargin;
-
-		/* Always at top line. */
-		last_v_pos = 0;
-
-		/* If the display position of the cursor would be off the edge
-	 of the screen, start the display of this line at an offset that
-	 leaves the cursor on the screen. */
-		if (c_pos - last_lmargin > screenwidth - 2)
-			lmargin = (c_pos / (screenwidth / 3) - 2) * (screenwidth / 3);
-		else if (c_pos - last_lmargin < 1)
-			lmargin = ((c_pos - 1) / (screenwidth / 3)) * (screenwidth / 3);
-		else
-			lmargin = last_lmargin;
-
-		/* If the first character on the screen isn't the first character
-	 in the display line, indicate this with a special character. */
-		if (lmargin > 0)
-			line[lmargin] = '<';
-
-		if (lmargin + screenwidth < out)
-			line[lmargin + screenwidth - 1] = '>';
-
-		if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
-		{
-			forced_display = 0;
-			update_line (&visible_line[last_lmargin],
-			    &invisible_line[lmargin], 0);
-
-			move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
-			last_lmargin = lmargin;
-		}
-	}
-	fflush (out_stream);
-
-	/* Swap visible and non-visible lines. */
-	{
-		char *temp = visible_line;
-		visible_line = invisible_line;
-		invisible_line = temp;
-		rl_display_fixed = 0;
-	}
-}
-
-/* PWP: update_line() is based on finding the middle difference of each
-   line on the screen; vis:
-
-			     /old first difference
-	/beginning of line   |              /old last same       /old EOL
-	v		     v              v                    v
-old:	eddie> Oh, my little gruntle-buggy is to me, as lurgid as
-new:	eddie> Oh, my little buggy says to me, as lurgid as
-	^		     ^        ^			   ^
-	\beginning of line   |        \new last same	   \new end of line
-			     \new first difference
-
-   All are character pointers for the sake of speed.  Special cases for
-   no differences, as well as for end of line additions must be handeled.
-
-   Could be made even smarter, but this works well enough */
-static
-update_line (old, new, current_line)
-register char *old, *new;
-int current_line;
-{
-	register char *ofd, *ols, *oe, *nfd, *nls, *ne;
-	int lendiff, wsatend;
-
-	/* Find first difference. */
-	for (ofd = old, nfd = new;
-	    (ofd - old < screenwidth) && *ofd && (*ofd == *nfd);
-	    ofd++, nfd++)
-		;
-
-	/* Move to the end of the screen line. */
-	for (oe = ofd; ((oe - old) < screenwidth) && *oe; oe++);
-	for (ne = nfd; ((ne - new) < screenwidth) && *ne; ne++);
-
-	/* If no difference, continue to next line. */
-	if (ofd == oe && nfd == ne)
-		return;
-
-	wsatend = 1;			/* flag for trailing whitespace */
-	ols = oe - 1;			/* find last same */
-	nls = ne - 1;
-	while ((*ols == *nls) && (ols > ofd) && (nls > nfd))
-	{
-		if (*ols != ' ')
-			wsatend = 0;
-		ols--;
-		nls--;
-	}
-
-	if (wsatend)
-	{
-		ols = oe;
-		nls = ne;
-	}
-	else if (*ols != *nls)
-	{
-		if (*ols)			/* don't step past the NUL */
-			ols++;
-		if (*nls)
-			nls++;
-	}
-
-	move_vert (current_line);
-	move_cursor_relative (ofd - old, old);
-
-	/* if (len (new) > len (old)) */
-	lendiff = (nls - nfd) - (ols - ofd);
-
-	/* Insert (diff(len(old),len(new)) ch */
-	if (lendiff > 0)
-	{
-		if (terminal_can_insert)
-		{
-			extern char *term_IC;
-
-			/* Sometimes it is cheaper to print the characters rather than
-	     use the terminal's capabilities. */
-			if ((2 * (ne - nfd)) < lendiff && !term_IC)
-			{
-				output_some_chars (nfd, (ne - nfd));
-				last_c_pos += (ne - nfd);
-			}
-			else
-			{
-				if (*ols)
-				{
-					insert_some_chars (nfd, lendiff);
-					last_c_pos += lendiff;
-				}
-				else
-				{
-					/* At the end of a line the characters do not have to
-		     be "inserted".  They can just be placed on the screen. */
-					output_some_chars (nfd, lendiff);
-					last_c_pos += lendiff;
-				}
-				/* Copy (new) chars to screen from first diff to last match. */
-				if (((nls - nfd) - lendiff) > 0)
-				{
-					output_some_chars (&nfd[lendiff], ((nls - nfd) - lendiff));
-					last_c_pos += ((nls - nfd) - lendiff);
-				}
-			}
-		}
-		else
-		{		/* cannot insert chars, write to EOL */
-			output_some_chars (nfd, (ne - nfd));
-			last_c_pos += (ne - nfd);
-		}
-	}
-	else	/* Delete characters from line. */
-	{
-		/* If possible and inexpensive to use terminal deletion, then do so. */
-		if (term_dc && (2 * (ne - nfd)) >= (-lendiff))
-		{
-			if (lendiff)
-				delete_chars (-lendiff); /* delete (diff) characters */
-
-			/* Copy (new) chars to screen from first diff to last match */
-			if ((nls - nfd) > 0)
-			{
-				output_some_chars (nfd, (nls - nfd));
-				last_c_pos += (nls - nfd);
-			}
-		}
-		/* Otherwise, print over the existing material. */
-		else
-		{
-			output_some_chars (nfd, (ne - nfd));
-			last_c_pos += (ne - nfd);
-			clear_to_eol ((oe - old) - (ne - new));
-		}
-	}
-}
-
-/* (PWP) tell the update routines that we have moved onto a
-   new (empty) line. */
-rl_on_new_line ()
-{
-	if (visible_line)
-		visible_line[0] = '\0';
-
-	last_c_pos = last_v_pos = 0;
-	vis_botlin = last_lmargin = 0;
-}
-
-/* Actually update the display, period. */
-rl_forced_update_display ()
-{
-	if (visible_line)
-	{
-		register char *temp = visible_line;
-
-		while (*temp) *temp++ = '\0';
-	}
-	rl_on_new_line ();
-	forced_display++;
-	rl_redisplay ();
-}
-
-/* Move the cursor from last_c_pos to NEW, which are buffer indices.
-   DATA is the contents of the screen line of interest; i.e., where
-   the movement is being done. */
-static void
-move_cursor_relative (new, data)
-int new;
-char *data;
-{
-	register int i;
-
-	/* It may be faster to output a CR, and then move forwards instead
-     of moving backwards. */
-	if (new + 1 < last_c_pos - new)
-	{
-		tputs (term_cr, 1, output_character_function);
-		last_c_pos = 0;
-	}
-
-	if (last_c_pos == new) return;
-
-	if (last_c_pos < new)
-	{
-		/* Move the cursor forward.  We do it by printing the command
-	 to move the cursor forward if there is one, else print that
-	 portion of the output buffer again.  Which is cheaper? */
-
-		/* The above comment is left here for posterity.  It is faster
-	 to print one character (non-control) than to print a control
-	 sequence telling the terminal to move forward one character.
-	 That kind of control is for people who don't know what the
-	 data is underneath the cursor. */
-#ifdef HACK_TERMCAP_MOTION
-		extern char *term_forward_char;
-
-		if (term_forward_char)
-			for (i = last_c_pos; i < new; i++)
-				tputs (term_forward_char, 1, output_character_function);
-		else
-			for (i = last_c_pos; i < new; i++)
-				putc (data[i], out_stream);
-#else
-		for (i = last_c_pos; i < new; i++)
-			putc (data[i], out_stream);
-#endif				/* HACK_TERMCAP_MOTION */
-	}
-	else
-		backspace (last_c_pos - new);
-	last_c_pos = new;
-}
-
-/* PWP: move the cursor up or down. */
-move_vert (to)
-int to;
-{
-	void output_character_function ();
-	register int delta, i;
-
-	if (last_v_pos == to) return;
-
-	if (to > screenheight)
-		return;
-
-	if ((delta = to - last_v_pos) > 0)
-	{
-		for (i = 0; i < delta; i++)
-			putc ('\n', out_stream);
-		tputs (term_cr, 1, output_character_function);
-		last_c_pos = 0;		/* because crlf() will do \r\n */
-	}
-	else
-	{			/* delta < 0 */
-		if (term_up && *term_up)
-			for (i = 0; i < -delta; i++)
-				tputs (term_up, 1, output_character_function);
-	}
-	last_v_pos = to;		/* now to is here */
-}
-
-/* Physically print C on out_stream.  This is for functions which know
-   how to optimize the display. */
-rl_show_char (c)
-int c;
-{
-	if (c > 127)
-	{
-		fprintf (out_stream, "M-");
-		c -= 128;
-	}
-
-#ifdef DISPLAY_TABS
-	if (c < 32 && c != '\t')
-#else
-		if (c < 32)
-#endif
-		{
-
-			c += 64;
-		}
-
-	putc (c, out_stream);
-	fflush (out_stream);
-}
-
-#ifdef DISPLAY_TABS
-int
-rl_character_len (c, pos)
-register int c, pos;
-{
-	if (c < ' ' || c > 126)
-	{
-		if (c == '\t')
-			return (((pos | (int)7) + 1) - pos);
-		else
-			return (3);
-	}
-	else
-		return (1);
-}
-#else
-int
-rl_character_len (c)
-int c;
-{
-	if (c < ' ' || c > 126)
-		return (3);
-	else
-		return (1);
-}
-#endif  /* DISPLAY_TAB */
-
-/* How to print things in the "echo-area".  The prompt is treated as a
-   mini-modeline. */
-rl_message (string, arg1, arg2)
-char *string;
-{
-	sprintf (msg_buf, string, arg1, arg2);
-	rl_display_prompt = msg_buf;
-	rl_redisplay ();
-}
-
-/* How to clear things from the "echo-area". */
-rl_clear_message ()
-{
-	rl_display_prompt = rl_prompt;
-	rl_redisplay ();
-}
-
-/* **************************************************************** */
-/*								    */
-/*			Terminal and Termcap			    */
-/*								    */
-/* **************************************************************** */
-
-static char *term_buffer = (char *)NULL;
-static char *term_string_buffer = (char *)NULL;
-
-/* Non-zero means this terminal can't really do anything. */
-int dumb_term = 0;
-
-char PC;
-char *BC, *UP;
-
-/* Some strings to control terminal actions.  These are output by tputs (). */
-char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
-
-int screenwidth, screenheight;
-
-/* Non-zero if we determine that the terminal can do character insertion. */
-int terminal_can_insert = 0;
-
-/* How to insert characters. */
-char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
-
-/* How to delete characters. */
-char *term_dc, *term_DC;
-
-#ifdef HACK_TERMCAP_MOTION
-char *term_forward_char;
-#endif  /* HACK_TERMCAP_MOTION */
-
-/* How to go up a line. */
-char *term_up;
-
-/* Re-initialize the terminal considering that the TERM/TERMCAP variable
-   has changed. */
-rl_reset_terminal (terminal_name)
-char *terminal_name;
-{
-	init_terminal_io (terminal_name);
-}
-
-init_terminal_io (terminal_name)
-char *terminal_name;
-{
-	char *term = (terminal_name? terminal_name : (char *)getenv ("TERM"));
-	char *tgetstr (), *buffer;
-
-
-	if (!term_string_buffer)
-		term_string_buffer = (char *)xmalloc (2048);
-
-	if (!term_buffer)
-		term_buffer = (char *)xmalloc (2048);
-
-	buffer = term_string_buffer;
-
-	term_clrpag = term_cr = term_clreol = (char *)NULL;
-
-	if (!term)
-		term = "dumb";
-
-	if (tgetent (term_buffer, term) < 0)
-	{
-		dumb_term = 1;
-		return;
-	}
-
-	BC = tgetstr ("pc", &buffer);
-	PC = buffer ? *buffer : 0;
-
-	term_backspace = tgetstr ("le", &buffer);
-
-	term_cr = tgetstr ("cr", &buffer);
-	term_clreol = tgetstr ("ce", &buffer);
-	term_clrpag = tgetstr ("cl", &buffer);
-
-	if (!term_cr)
-		term_cr =  "\r";
-
-#ifdef HACK_TERMCAP_MOTION
-	term_forward_char = tgetstr ("nd", &buffer);
-#endif  /* HACK_TERMCAP_MOTION */
-
-	screenwidth = tgetnum ("co");
-	if (screenwidth <= 0)
-		screenwidth = 80;
-	screenwidth--;		/* PWP: avoid autowrap bugs */
-
-	screenheight = tgetnum ("li");
-	if (screenheight <= 0)
-		screenheight = 24;
-
-	term_im = tgetstr ("im", &buffer);
-	term_ei = tgetstr ("ei", &buffer);
-	term_IC = tgetstr ("IC", &buffer);
-	term_ic = tgetstr ("ic", &buffer);
-
-	/* "An application program can assume that the terminal can do
-      character insertion if *any one of* the capabilities `IC',
-      `im', `ic' or `ip' is provided."  But we can't do anything if
-      only `ip' is provided, so... */
-	terminal_can_insert = (term_IC || term_im || term_ic);
-
-	term_up = tgetstr ("up", &buffer);
-	term_dc = tgetstr ("dc", &buffer);
-	term_DC = tgetstr ("DC", &buffer);
-}
-
-/* A function for the use of tputs () */
-static void
-output_character_function (c)
-int c;
-{
-	putc (c, out_stream);
-}
-
-/* Write COUNT characters from STRING to the output stream. */
-static void
-output_some_chars (string, count)
-char *string;
-int count;
-{
-	fwrite (string, 1, count, out_stream);
-}
-
-
-/* Delete COUNT characters from the display line. */
-static
-delete_chars (count)
-int count;
-{
-	if (count > screenwidth)
-		return;
-
-	if (term_DC && *term_DC)
-	{
-		char *tgoto (), *buffer;
-		buffer = tgoto (term_DC, 0, count);
-		tputs (buffer, 1, output_character_function);
-	}
-	else
-	{
-		if (term_dc && *term_dc)
-			while (count--)
-				tputs (term_dc, 1, output_character_function);
-	}
-}
-
-/* Insert COUNT character from STRING to the output stream. */
-static
-insert_some_chars (string, count)
-char *string;
-int count;
-{
-	/* If IC is defined, then we do not have to "enter" insert mode. */
-	if (term_IC)
-	{
-		char *tgoto (), *buffer;
-		buffer = tgoto (term_IC, 0, count);
-		tputs (buffer, 1, output_character_function);
-		output_some_chars (string, count);
-	}
-	else
-	{
-		register int i;
-
-		/* If we have to turn on insert-mode, then do so. */
-		if (term_im && *term_im)
-			tputs (term_im, 1, output_character_function);
-
-		/* If there is a special command for inserting characters, then
-	 use that first to open up the space. */
-		if (term_ic && *term_ic)
-		{
-			for (i = count; i--; )
-				tputs (term_ic, 1, output_character_function);
-		}
-
-		/* Print the text. */
-		output_some_chars (string, count);
-
-		/* If there is a string to turn off insert mode, we had best use
-	 it now. */
-		if (term_ei && *term_ei)
-			tputs (term_ei, 1, output_character_function);
-	}
-}
-
-/* Move the cursor back. */
-backspace (count)
-int count;
-{
-	register int i;
-
-	if (term_backspace)
-		for (i = 0; i < count; i++)
-			tputs (term_backspace, 1, output_character_function);
-	else
-		for (i = 0; i < count; i++)
-			putc ('\b', out_stream);
-}
-
-/* Move to the start of the next line. */
-crlf ()
-{
-	tputs (term_cr, 1, output_character_function);
-	putc ('\n', out_stream);
-}
-
-/* Clear to the end of the line.  COUNT is the minimum
-   number of character spaces to clear, */
-clear_to_eol (count)
-int count;
-{
-	if (term_clreol)
-	{
-		tputs (term_clreol, 1, output_character_function);
-	}
-	else
-	{
-		register int i;
-
-		/* Do one more character space. */
-		count++;
-
-		for (i = 0; i < count; i++)
-			putc (' ', out_stream);
-
-		backspace (count);
-	}
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*		      Saving and Restoring the TTY	    	    */
-/*								    */
-/* **************************************************************** */
-
-#ifdef NEW_TTY_DRIVER
-
-/* We use this to get and set the tty_flags. */
-static struct sgttyb the_ttybuff;
-
-/* Put the terminal in CBREAK mode so that we can detect key presses. */
-rl_prep_terminal ()
-{
-int original_tty_flags,local_mode_flags;
-
-	static int firsttime = 1;
-	int tty = fileno (rl_instream);
-
-	/* We always get the latest tty values.  Maybe stty changed them. */
-	ioctl (tty, TIOCGETP, &the_ttybuff);
-	original_tty_flags = ((the_ttybuff.sg_flags)&~(O_CBREAK|O_RAW))|O_ECHO;
-
-	readline_echoing_p = (original_tty_flags & ECHO);
-
-	/* If this terminal doesn't care how the 8th bit is used,
-     then we can use it for the meta-key.
-     We check by seeing if BOTH odd and even parity are allowed. */
-	if ((the_ttybuff.sg_flags & ODDP) && (the_ttybuff.sg_flags & EVENP))
-	{
-#ifdef PASS8
-		the_ttybuff.sg_flags |= PASS8;
-#endif
-	}
-
-	/* Hack on local mode flags if we can. */
-#if defined (TIOCLGET) && defined (LPASS8)
-	{
-		int flags;
-
-		ioctl (tty, TIOCLGET, &local_mode_flags);
-		flags = local_mode_flags | LPASS8;
-		ioctl (tty, TIOCLSET, &flags);
-	}
-#endif
-
-#ifdef TIOCGETC
-	{
-		struct tchars temp;
-
-		ioctl (tty, TIOCGETC, &temp);
-
-		/* Get rid of C-s and C-q.
-       We remember the value of startc (C-q) so that if the terminal is in
-       xoff state, the user can xon it by pressing that character. */
-		xon_char = temp.t_startc;
-		temp.t_stopc = -1;
-		temp.t_startc = -1;
-
-		/* If there is an XON character, bind it to restart the output. */
-		if (xon_char != -1)
-			rl_bind_key (xon_char, rl_restart_output);
-
-		/* If there is an EOF char, bind eof_char to it. */
-		if (temp.t_eofc != -1)
-			eof_char = temp.t_eofc;
-
-#ifdef NEVER
-		/* Get rid of C-\ and C-c. */
-		temp.t_intrc = temp.t_quitc = -1;
-#endif
-
-		ioctl (tty, TIOCSETC, &temp);
-	}
-#endif /* TIOCGETC */
-
-#ifdef TIOCGLTC
-	{
-		struct ltchars temp;
-
-		ioctl (tty, TIOCGLTC, &temp);
-
-		/* Make the interrupt keys go away.  Just enough to make people happy. */
-		temp.t_dsuspc = -1;		/* C-y */
-		temp.t_lnextc = -1;		/* C-v */
-
-		ioctl (tty, TIOCSLTC, &temp);
-	}
-#endif /* TIOCGLTC */
-
-	the_ttybuff.sg_flags &= ~ECHO;
-	the_ttybuff.sg_flags |= CBREAK;
-	ioctl (tty, TIOCSETN, &the_ttybuff);
-}
-
-
-#else  /* !defined (NEW_TTY_DRIVER) */
-
-#if !defined (VMIN)
-#define VMIN VEOF
-#endif
-
-#if !defined (VTIME)
-#define VTIME VEOL
-#endif
-
-static struct termio otio;
-
-rl_prep_terminal ()
-{
-	int tty = fileno (rl_instream);
-	struct termio tio;
-
-	ioctl (tty, TCGETA, &tio);
-	ioctl (tty, TCGETA, &otio);
-
-	readline_echoing_p = (tio.c_lflag & ECHO);
-
-	tio.c_lflag &= ~(ICANON|ECHO);
-	tio.c_iflag &= ~(IXON|IXOFF|IXANY|ISTRIP|INPCK);
-
-#if !defined (HANDLE_SIGNALS)
-	tio.c_lflag &= ~ISIG;
-#endif
-
-	tio.c_cc[VMIN] = 1;
-	tio.c_cc[VTIME] = 0;
-	ioctl (tty, TCSETAW, &tio);
-	ioctl (tty, TCXONC, 1);	/* Simulate a ^Q. */
-}
-
-#endif  /* NEW_TTY_DRIVER */
-
-/* Restore the terminal to its original state. */
-rl_deprep_terminal ()
-{
-	rl_active = 0;
-	restoretty();
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Utility Functions			    */
-/*								    */
-/* **************************************************************** */
-
-/* Return 0 if C is not a member of the class of characters that belong
-   in words, or 1 if it is. */
-
-int allow_pathname_alphabetic_chars = 0;
-char *pathname_alphabetic_chars = "/-_=~.#$";
-
-int
-alphabetic (c)
-int c;
-{
-	char *rindex ();
-	if (pure_alphabetic (c) || (numeric (c)))
-		return (1);
-
-	if (allow_pathname_alphabetic_chars)
-		return ((int)rindex (pathname_alphabetic_chars, c));
-	else
-		return (0);
-}
-
-/* Return non-zero if C is a numeric character. */
-int
-numeric (c)
-int c;
-{
-	return (c >= '0' && c <= '9');
-}
-
-/* Ring the terminal bell. */
-int
-ding ()
-{
-extern int opts[128];
-
-	if (readline_echoing_p && opts['B'] == 0)
-	{
-		fprintf (stderr, "\007");
-		fflush (stderr);
-	}
-	return (-1);
-}
-
-/* How to abort things. */
-rl_abort ()
-{
-	ding ();
-	rl_clear_message ();
-	rl_init_argument ();
-	rl_pending_input = 0;
-
-	defining_kbd_macro = 0;
-	while (executing_macro)
-		pop_executing_macro ();
-
-	longjmp (readline_top_level, 1);
-}
-
-/* Return a copy of the string between FROM and TO.
-   FROM is inclusive, TO is not. */
-static char *
-rl_copy (from, to)
-int from, to;
-{
-	register int length;
-	char *copy;
-
-	/* Fix it if the caller is confused. */
-	if (from > to) {
-		int t = from;
-		from = to;
-		to = t;
-	}
-
-	length = to - from;
-	copy = (char *)xmalloc (1 + length);
-	strncpy (copy, the_line + from, length);
-	copy[length] = '\0';
-	return (copy);
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Insert and Delete			    */
-/*								    */
-/* **************************************************************** */
-
-
-/* Insert a string of text into the line at point.  This is the only
-   way that you should do insertion.  rl_insert () calls this
-   function. */
-rl_insert_text (string)
-char *string;
-{
-	extern int doing_an_undo;
-	register int i, l = strlen (string);
-	while (rl_end + l >= rl_line_buffer_len)
-	{
-		rl_line_buffer =
-		    (char *)xrealloc (rl_line_buffer,
-		    rl_line_buffer_len += DEFAULT_BUFFER_SIZE);
-		the_line = rl_line_buffer;
-	}
-
-	for (i = rl_end; i >= rl_point; i--)
-		the_line[i + l] = the_line[i];
-	strncpy (the_line + rl_point, string, l);
-
-	/* Remember how to undo this if we aren't undoing something. */
-	if (!doing_an_undo)
-	{
-		/* If possible and desirable, concatenate the undos. */
-		if ((strlen (string) == 1) &&
-		    rl_undo_list &&
-		    (rl_undo_list->what == UNDO_INSERT) &&
-		    (rl_undo_list->end == rl_point) &&
-		    (rl_undo_list->end - rl_undo_list->start < 20))
-			rl_undo_list->end++;
-		else
-			rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
-	}
-	rl_point += l;
-	rl_end += l;
-	the_line[rl_end] = '\0';
-}
-
-/* Delete the string between FROM and TO.  FROM is
-   inclusive, TO is not. */
-rl_delete_text (from, to)
-int from, to;
-{
-	extern int doing_an_undo;
-	register char *text;
-
-	/* Fix it if the caller is confused. */
-	if (from > to) {
-		int t = from;
-		from = to;
-		to = t;
-	}
-	text = rl_copy (from, to);
-	strncpy (the_line + from, the_line + to, rl_end - to);
-
-	/* Remember how to undo this delete. */
-	if (!doing_an_undo)
-		rl_add_undo (UNDO_DELETE, from, to, text);
-	else
-		free (text);
-
-	rl_end -= (to - from);
-	the_line[rl_end] = '\0';
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Readline character functions		    */
-/*								    */
-/* **************************************************************** */
-
-/* This is not a gap editor, just a stupid line input routine.  No hair
-   is involved in writing any of the functions, and none should be. */
-
-/* Note that:
-
-   rl_end is the place in the string that we would place '\0';
-   i.e., it is always safe to place '\0' there.
-
-   rl_point is the place in the string where the cursor is.  Sometimes
-   this is the same as rl_end.
-
-   Any command that is called interactively receives two arguments.
-   The first is a count: the numeric arg pased to this command.
-   The second is the key which invoked this command.
-*/
-
-
-/* **************************************************************** */
-/*								    */
-/*			Movement Commands			    */
-/*								    */
-/* **************************************************************** */
-
-/* Note that if you `optimize' the display for these functions, you cannot
-   use said functions in other functions which do not do optimizing display.
-   I.e., you will have to update the data base for rl_redisplay, and you
-   might as well let rl_redisplay do that job. */
-
-/* Move forward COUNT characters. */
-rl_forward (count)
-int count;
-{
-	if (count < 0)
-		rl_backward (-count);
-	else
-		while (count)
-		{
-#ifdef VI_MODE
-			if (rl_point == (rl_end - (rl_editing_mode == vi_mode)))
-#else
-				if (rl_point == rl_end)
-#endif
-				{
-					ding ();
-					return;
-				}
-				else
-					rl_point++;
-			--count;
-		}
-}
-
-/* Move backward COUNT characters. */
-rl_backward (count)
-int count;
-{
-	if (count < 0)
-		rl_forward (-count);
-	else
-		while (count)
-		{
-			if (!rl_point)
-			{
-				ding ();
-				return;
-			}
-			else
-				--rl_point;
-			--count;
-		}
-}
-
-/* Move to the beginning of the line. */
-rl_beg_of_line ()
-{
-	rl_point = 0;
-}
-
-/* Move to the end of the line. */
-rl_end_of_line ()
-{
-	rl_point = rl_end;
-}
-
-/* Move forward a word.  We do what Emacs does. */
-rl_forward_word (count)
-int count;
-{
-	int c;
-
-	if (count < 0)
-	{
-		rl_backward_word (-count);
-		return;
-	}
-
-	while (count)
-	{
-		if (rl_point == rl_end)
-			return;
-
-		/* If we are not in a word, move forward until we are in one.
-	 Then, move forward until we hit a non-alphabetic character. */
-		c = the_line[rl_point];
-		if (!alphabetic (c))
-		{
-			while (++rl_point < rl_end)
-			{
-				c = the_line[rl_point];
-				if (alphabetic (c)) break;
-			}
-		}
-		if (rl_point == rl_end) return;
-		while (++rl_point < rl_end)
-		{
-			c = the_line[rl_point];
-			if (!alphabetic (c)) break;
-		}
-		--count;
-	}
-}
-
-/* Move backward a word.  We do what Emacs does. */
-rl_backward_word (count)
-int count;
-{
-	int c;
-
-	if (count < 0)
-	{
-		rl_forward_word (-count);
-		return;
-	}
-
-	while (count)
-	{
-		if (!rl_point)
-			return;
-
-		/* Like rl_forward_word (), except that we look at the characters
-	 just before point. */
-
-		c = the_line[rl_point - 1];
-		if (!alphabetic (c))
-		{
-			while (--rl_point)
-			{
-				c = the_line[rl_point - 1];
-				if (alphabetic (c)) break;
-			}
-		}
-
-		while (rl_point)
-		{
-			c = the_line[rl_point - 1];
-			if (!alphabetic (c))
-				break;
-			else --rl_point;
-		}
-		--count;
-	}
-}
-
-/* Clear the current line.  Numeric argument to C-l does this. */
-rl_refresh_line ()
-{
-	int curr_line = last_c_pos / screenwidth;
-	extern char *term_clreol;
-
-	move_vert(curr_line);
-	move_cursor_relative (0, the_line);   /* XXX is this right */
-
-	if (term_clreol)
-		tputs (term_clreol, 1, output_character_function);
-
-	rl_forced_update_display ();
-	rl_display_fixed = 1;
-}
-
-/* C-l typed to a line without quoting clears the screen, and then reprints
-   the prompt and the current input line.  Given a numeric arg, redraw only
-   the current line. */
-rl_clear_screen ()
-{
-	extern char *term_clrpag;
-
-	if (rl_explicit_arg)
-	{
-		rl_refresh_line ();
-		return;
-	}
-
-	if (term_clrpag)
-		tputs (term_clrpag, 1, output_character_function);
-	else
-		crlf ();
-
-	rl_forced_update_display ();
-	rl_display_fixed = 1;
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Text commands				    */
-/*								    */
-/* **************************************************************** */
-
-/* Insert the character C at the current location, moving point forward. */
-rl_insert (count, c)
-int count, c;
-{
-	register int i;
-	char *string;
-
-	if (count <= 0)
-		return;
-
-	/* If we can optimize, then do it.  But don't let people crash
-     readline because of extra large arguments. */
-	if (count > 1 && count < 1024)
-	{
-		string = (char *)alloca (1 + count);
-
-		for (i = 0; i < count; i++)
-			string[i] = c;
-
-		string[i] = '\0';
-		rl_insert_text (string);
-		return;
-	}
-
-	if (count > 1024)
-	{
-		int decreaser;
-
-		string = (char *)alloca (1024 + 1);
-
-		for (i = 0; i < 1024; i++)
-			string[i] = c;
-
-		while (count)
-		{
-			decreaser = (count > 1024 ? 1024 : count);
-			string[decreaser] = '\0';
-			rl_insert_text (string);
-			count -= decreaser;
-		}
-		return;
-	}
-
-	/* We are inserting a single character.
-     If there is pending input, then make a string of all of the
-     pending characters that are bound to rl_insert, and insert
-     them all. */
-	if (any_typein)
-	{
-		int key = 0, t;
-
-		i = 0;
-		string = (char *)alloca (ibuffer_len + 1);
-		string[i++] = c;
-
-		while ((t = rl_get_char (&key)) &&
-		    (keymap[key].type == ISFUNC &&
-		    keymap[key].function == rl_insert))
-			string[i++] = key;
-
-		if (t)
-			rl_unget_char (key);
-
-		string[i] = '\0';
-		rl_insert_text (string);
-		return;
-	}
-	else
-	{
-		/* Inserting a single character. */
-		string = (char *)alloca (2);
-
-		string[1] = '\0';
-		string[0] = c;
-		rl_insert_text (string);
-	}
-}
-
-/* Insert the next typed character verbatim. */
-rl_quoted_insert (count)
-int count;
-{
-	int c = rl_read_key ();
-	rl_insert (count, c);
-}
-
-/* Insert a tab character. */
-rl_tab_insert (count)
-int count;
-{
-	rl_insert (count, '\t');
-}
-
-/* What to do when a NEWLINE is pressed.  We accept the whole line.
-   KEY is the key that invoked this command.  I guess it could have
-   meaning in the future. */
-rl_newline (count, key)
-int count, key;
-{
-
-	rl_done = 1;
-#ifdef VI_MODE
-	{
-		extern int vi_doing_insert;
-		if (vi_doing_insert)
-		{
-			rl_end_undo_group ();
-			vi_doing_insert = 0;
-		}
-	}
-#endif /* VI_MODE */
-
-	if (readline_echoing_p)
-	{
-		move_vert (vis_botlin);
-		vis_botlin = 0;
-		crlf ();
-		fflush (out_stream);
-		rl_display_fixed++;
-	}
-	rl_end_of_line(); 
-	rl_insert(1,'\n');  /* added by pjf */
-}
-
-rl_clean_up_for_exit ()
-{
-	if (readline_echoing_p)
-	{
-		move_vert (vis_botlin);
-		vis_botlin = 0;
-		fflush (out_stream);
-		rl_restart_output ();
-	}
-}
-
-/* What to do for some uppercase characters, like meta characters,
-   and some characters appearing in emacs_ctlx_keymap.  This function
-   is just a stub, you bind keys to it and the code in rl_dispatch ()
-   is special cased. */
-rl_do_lowercase_version (ignore1, ignore2)
-int ignore1, ignore2;
-{
-}
-
-/* Rubout the character behind point. */
-rl_rubout (count)
-int count;
-{
-	if (count < 0)
-	{
-		rl_delete (-count);
-		return;
-	}
-
-	if (!rl_point)
-	{
-		ding ();
-		return;
-	}
-
-	if (count > 1)
-	{
-		int orig_point = rl_point;
-		rl_backward (count);
-		rl_kill_text (orig_point, rl_point);
-	}
-	else
-	{
-		int c = the_line[--rl_point];
-		rl_delete_text (rl_point, rl_point + 1);
-
-		if (rl_point == rl_end && alphabetic (c) && last_c_pos)
-		{
-			backspace (1);
-			putc (' ', out_stream);
-			backspace (1);
-			last_c_pos--;
-			rl_display_fixed++;
-		}
-	}
-}
-
-/* Delete the character under the cursor.  Given a numeric argument,
-   kill that many characters instead. */
-rl_delete (count, invoking_key)
-int count, invoking_key;
-{
-	if (count < 0)
-	{
-		rl_rubout (-count);
-		return;
-	}
-
-	if (rl_point == rl_end)
-	{
-		ding ();
-		return;
-	}
-
-	if (count > 1)
-	{
-		int orig_point = rl_point;
-		rl_forward (count);
-		rl_kill_text (orig_point, rl_point);
-		rl_point = orig_point;
-	}
-	else
-		rl_delete_text (rl_point, rl_point + 1);
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Kill commands				    */
-/*								    */
-/* **************************************************************** */
-
-/* The next two functions mimic unix line editing behaviour, except they
-   save the deleted text on the kill ring.  This is safer than not saving
-   it, and since we have a ring, nobody should get screwed. */
-
-/* This does what C-w does in Unix.  We can't prevent people from
-   using behaviour that they expect. */
-rl_unix_word_rubout ()
-{
-	if (!rl_point) ding ();
-	else {
-		int orig_point = rl_point;
-		while (rl_point && whitespace (the_line[rl_point - 1]))
-			rl_point--;
-		while (rl_point && !whitespace (the_line[rl_point - 1]))
-			rl_point--;
-		rl_kill_text (rl_point, orig_point);
-	}
-}
-
-/* Here is C-u doing what Unix does.  You don't *have* to use these
-   key-bindings.  We have a choice of killing the entire line, or
-   killing from where we are to the start of the line.  We choose the
-   latter, because if you are a Unix weenie, then you haven't backspaced
-   into the line at all, and if you aren't, then you know what you are
-   doing.  (pjf: I disagree*/
-rl_unix_line_discard ()
-{
-	rl_end_of_line();
-	if (!rl_point) ding ();
-	else {
-		rl_kill_text (rl_point, 0);
-		rl_point = 0;
-	}
-}
-
-
-
-/* **************************************************************** */
-/*								    */
-/*			Commands For Typos			    */
-/*								    */
-/* **************************************************************** */
-
-/* Random and interesting things in here.  */
-
-
-/* **************************************************************** */
-/*								    */
-/*			Changing Case				    */
-/*								    */
-/* **************************************************************** */
-
-/* The three kinds of things that we know how to do. */
-#define UpCase 1
-#define DownCase 2
-#define CapCase 3
-
-/* Uppercase the word at point. */
-rl_upcase_word (count)
-int count;
-{
-	rl_change_case (count, UpCase);
-}
-
-/* Lowercase the word at point. */
-rl_downcase_word (count)
-int count;
-{
-	rl_change_case (count, DownCase);
-}
-
-/* Upcase the first letter, downcase the rest. */
-rl_capitalize_word (count)
-int count;
-{
-	rl_change_case (count, CapCase);
-}
-
-/* The meaty function.
-   Change the case of COUNT words, performing OP on them.
-   OP is one of UpCase, DownCase, or CapCase.
-   If a negative argument is given, leave point where it started,
-   otherwise, leave it where it moves to. */
-rl_change_case (count, op)
-int count, op;
-{
-	register int start = rl_point, end;
-	int state = 0;
-
-	rl_forward_word (count);
-	end = rl_point;
-
-	if (count < 0)
-	{
-		int temp = start;
-		start = end;
-		end = temp;
-	}
-
-	/* We are going to modify some text, so let's prepare to undo it. */
-	rl_modifying (start, end);
-
-	for (; start < end; start++)
-	{
-		switch (op)
-		{
-		case UpCase:
-			the_line[start] = to_upper (the_line[start]);
-			break;
-
-		case DownCase:
-			the_line[start] = to_lower (the_line[start]);
-			break;
-
-		case CapCase:
-			if (state == 0)
-			{
-				the_line[start] = to_upper (the_line[start]);
-				state = 1;
-			}
-			else
-			{
-				the_line[start] = to_lower (the_line[start]);
-			}
-			if (!pure_alphabetic (the_line[start]))
-				state = 0;
-			break;
-
-		default:
-			abort ();
-		}
-	}
-	rl_point = end;
-}
-
-/* **************************************************************** */
-/*								    */
-/*			Transposition				    */
-/*								    */
-/* **************************************************************** */
-
-/* Transpose the words at point. */
-rl_transpose_words (count)
-int count;
-{
-	char *word1, *word2;
-	int w1_beg, w1_end, w2_beg, w2_end;
-	int orig_point = rl_point;
-
-	if (!count) return;
-
-	/* Find the two words. */
-	rl_forward_word (count);
-	w2_end = rl_point;
-	rl_backward_word (1);
-	w2_beg = rl_point;
-	rl_backward_word (count);
-	w1_beg = rl_point;
-	rl_forward_word (1);
-	w1_end = rl_point;
-
-	/* Do some check to make sure that there really are two words. */
-	if ((w1_beg == w2_beg) || (w2_beg < w1_end))
-	{
-		ding ();
-		rl_point = orig_point;
-		return;
-	}
-
-	/* Get the text of the words. */
-	word1 = rl_copy (w1_beg, w1_end);
-	word2 = rl_copy (w2_beg, w2_end);
-
-	/* We are about to do many insertions and deletions.  Remember them
-     as one operation. */
-	rl_begin_undo_group ();
-
-	/* Do the stuff at word2 first, so that we don't have to worry
-     about word1 moving. */
-	rl_point = w2_beg;
-	rl_delete_text (w2_beg, w2_end);
-	rl_insert_text (word1);
-
-	rl_point = w1_beg;
-	rl_delete_text (w1_beg, w1_end);
-	rl_insert_text (word2);
-
-	/* This is exactly correct since the text before this point has not
-     changed in length. */
-	rl_point = w2_end;
-
-	/* I think that does it. */
-	rl_end_undo_group ();
-	free (word1); 
-	free (word2);
-}
-
-/* Transpose the characters at point.  If point is at the end of the line,
-   then transpose the characters before point. */
-rl_transpose_chars (count)
-int count;
-{
-	if (!count)
-		return;
-
-	if (!rl_point || rl_end < 2) {
-		ding ();
-		return;
-	}
-
-	while (count) {
-		if (rl_point == rl_end) {
-			int t = the_line[rl_point - 1];
-			the_line[rl_point - 1] = the_line[rl_point - 2];
-			the_line[rl_point - 2] = t;
-		} else {
-			int t = the_line[rl_point];
-			the_line[rl_point] = the_line[rl_point - 1];
-			the_line[rl_point - 1] = t;
-			if (count < 0 && rl_point)
-				rl_point--;
-			else
-				rl_point++;
-		}
-		if (count < 0)
-			count++;
-		else
-			count--;
-	}
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Bogus Flow Control      		    */
-/*								    */
-/* **************************************************************** */
-
-rl_restart_output (count, key)
-int count, key;
-{
-	int fildes = fileno (stdin);
-#ifdef TIOCSTART
-	ioctl (fildes, TIOCSTART, 0);
-#endif /* TIOCSTART */
-}
-
-/* **************************************************************** */
-/*								    */
-/*	Completion matching, from readline's point of view.	    */
-/*								    */
-/* **************************************************************** */
-
-/* Pointer to the generator function for completion_matches ().
-   NULL means to use filename_entry_function (), the default filename
-   completer. */
-Function *rl_completion_entry_function = (Function *)NULL;
-
-/* Pointer to alternative function to create matches.
-   Function is called with TEXT, START, and END.
-   START and END are indices in RL_LINE_BUFFER saying what the boundaries
-   of TEXT are.
-   If this function exists and returns NULL then call the value of
-   rl_completion_entry_function to try to match, otherwise use the
-   array of strings returned. */
-Function *rl_attempted_completion_function = (Function *)NULL;
-
-/* Complete the word at or before point.  You have supplied the function
-   that does the initial simple matching selection algorithm (see
-   completion_matches ()).  The default is to do filename completion. */
-rl_complete (ignore, invoking_key)
-int ignore, invoking_key;
-{
-	rl_complete_internal (TAB);
-}
-
-/* List the possible completions.  See description of rl_complete (). */
-rl_possible_completions ()
-{
-	rl_complete_internal ('?');
-}
-
-/* The user must press "y" or "n". Non-zero return means "y" pressed. */
-get_y_or_n ()
-{
-	int c;
-loop:
-	c = rl_read_key ();
-	if (c == 'y' || c == 'Y') return (1);
-	if (c == 'n' || c == 'N') return (0);
-	if (c == ABORT_CHAR) rl_abort ();
-	ding (); 
-	goto loop;
-}
-
-/* Up to this many items will be displayed in response to a
-   possible-completions call.  After that, we ask the user if
-   she is sure she wants to see them all. */
-int rl_completion_query_items = 100;
-
-/* The basic list of characters that signal a break between words for the
-   completer routine.  The contents of this variable is what breaks words
-   in the shell, i.e. " \t\n\"\\'`@><" */
-char *rl_basic_word_break_characters = " \t\n@><;(";
-
-/* The list of characters that signal a break between words for
-   rl_complete_internal.  The default list is the contents of
-   rl_basic_word_break_characters.  */
-char *rl_completer_word_break_characters = (char *)NULL;
-
-/* List of characters that are word break characters, but should be left
-   in TEXT when it is passed to the completion function.  The shell uses
-   this to help determine what kind of completing to do. */
-char *rl_special_prefixes = (char *)NULL;
-
-/* If non-zero, then disallow duplicates in the matches. */
-int rl_ignore_completion_duplicates = 1;
-
-/* Non-zero means that the results of the matches are to be treated
-   as filenames.  This is ALWAYS zero on entry, and can only be changed
-   within a completion entry finder function. */
-int rl_filename_completion_desired = 0;
-
-/* Complete the word at or before point.
-   WHAT_TO_DO says what to do with the completion.
-   `?' means list the possible completions.
-   TAB means do standard completion.
-   `*' means insert all of the possible completions. */
-rl_complete_internal (what_to_do)
-int what_to_do;
-{
-	char *filename_completion_function ();
-	char **completion_matches (), **matches;
-	Function *our_func;
-	int start, end,did = 0;
-	char *text;
-
-	if (rl_completion_entry_function)
-		our_func = rl_completion_entry_function;
-	else
-		our_func = (int (*)())filename_completion_function;
-
-	/* Only the completion entry function can change this. */
-	rl_filename_completion_desired = 0;
-
-	/* We now look backwards for the start of a filename/variable word. */
-	end = rl_point;
-	if (rl_point)
-	{
-		for(;;) {
-			while (--rl_point >= 0 &&
-			    !rindex (rl_completer_word_break_characters, the_line[rl_point]))
-				if (the_line[rl_point] == '`')
-					while(rl_point-- && the_line[rl_point] != '`');
-				else if (the_line[rl_point] == '\'')
-					while(rl_point-- && the_line[rl_point] != '\'');
-				else if (the_line[rl_point] == '\"')
-					while(rl_point-- && the_line[rl_point] != '\"');
-
-			if (rl_point < 0)
-				{
-				rl_point = end;
-				ding();
-				return 0;
-				}
-			if (rl_point == 0 || the_line[rl_point-1] != '\\')
-				break;
-			rl_point--;
-		}
-		/* If we are at a word break, then advance past it. */
-		if (rindex (rl_completer_word_break_characters,  (the_line[rl_point])))
-			rl_point++;
-	}
-
-	start = rl_point;
-	rl_point = end;
-	text = rl_copy (start, end);
-	text = docompsubs(text,&did);
-	rl_prep_terminal();
-	if (!text)
-		return 0;
-	if (did)
-	{
-		rl_delete_text (start, rl_point);
-		rl_point = start;
-		if (what_to_do == '?')
-			puts(text);
-		else if (did == 2)
-			rl_insert_text(text);
-		else
-			rl_safe_insert_text (text);
-		free(text);
-		return 0;
-	}
-	/* If the user wants to TRY to complete, but then wants to give
-     up and use the default completion function, they set the
-     variable rl_attempted_completion_function. */
-	if (rl_attempted_completion_function)
-	{
-		matches =
-		    (char **)(*rl_attempted_completion_function) (text, start, end);
-
-		if (matches)
-			goto after_usual_completion;
-	}
-
-	matches = completion_matches (text, our_func, start, end);
-
-after_usual_completion:
-	free (text);
-
-	if (!matches)
-		ding ();
-	else
-	{
-		register int i;
-
-some_matches:
-
-		/* It seems to me that in all the cases we handle we would like
-	 to ignore duplicate possiblilities.  Scan for the text to
-	 insert being identical to the other completions. */
-		if (rl_ignore_completion_duplicates)
-		{
-			char *lowest_common;
-			int j, newlen = 0;
-
-			/* Sort the items. */
-			/* It is safe to sort this array, because the lowest common
-	     denominator found in matches[0] will remain in place. */
-			for (i = 0; matches[i]; i++);
-			qsort (matches, i, sizeof (char *), compare_strings);
-
-			/* Remember the lowest common denimator for it may be unique. */
-			lowest_common = savestring (matches[0]);
-
-			for (i = 0; matches[i + 1]; i++)
-			{
-				if (strcmp (matches[i], matches[i + 1]) == 0)
-				{
-					free (matches[i]);
-					matches[i] = (char *)-1;
-				}
-				else
-					newlen++;
-			}
-
-			/* We have marked all the dead slots with (char *)-1.
-	     Copy all the non-dead entries into a new array. */
-			{
-				char **temp_array =
-				(char **)malloc ((3 + newlen) * sizeof (char *));
-
-				for (i = 1, j = 1; matches[i]; i++)
-					if (matches[i] != (char *)-1)
-						temp_array[j++] = matches[i];
-				temp_array[j] = (char *)NULL;
-
-				if (matches[0] != (char *)-1)
-					free (matches[0]);
-				free (matches);
-
-				matches = temp_array;
-			}
-
-			/* Place the lowest common denominator back in [0]. */
-			matches[0] = lowest_common;
-
-			/* If there is one string left, and it is identical to the
-	     lowest common denominator, then the LCD is the string to
-	     insert. */
-			if (j == 2 && strcmp (matches[0], matches[1]) == 0)
-			{
-				free (matches[1]);
-				matches[1] = (char *)NULL;
-			}
-		}
-
-		switch (what_to_do)
-		{
-		case TAB:
-			if (matches[0])
-			{
-				rl_delete_text (start, rl_point);
-				rl_point = start;
-				rl_safe_insert_text (matches[0]);
-			}
-
-			/* If there are more matches, ring the bell to indicate.
-	     If this was the only match, and we are hacking files,
-	     check the file to see if it was a directory.  If so,
-	     add a '/' to the name.  If not, and we are at the end
-	     of the line, then add a space. */
-			if (matches[1])
-			{
-			extern int opts[128];
-
-				ding ();		/* There are other matches remaining. */
-				if (opts['9'] == 2)
-					goto autolist;
-			}
-			else
-			{
-				char temp_string[2];
-
-				temp_string[0] = ' ';
-				temp_string[1] = '\0';
-
-				if (rl_filename_completion_desired)
-				{
-					struct stat finfo;
-					char *tilde_expand ();
-					char *filename = tilde_expand (matches[0]);
-
-					if ((stat (filename, &finfo) == 0) &&
-					    ((finfo.st_mode & S_IFMT) == S_IFDIR))
-					{
-						if (the_line[rl_point] != '/')
-							rl_insert_text ("/");
-					}
-					else
-					{
-						if (rl_point == rl_end)
-							rl_insert_text (temp_string);
-					}
-					free (filename);
-				}
-				else
-				{
-					if (rl_point == rl_end)
-						rl_insert_text (temp_string);
-				}
-			}
-			break;
-
-		case '*':
-			{
-				int i = 1;
-
-				rl_delete_text (start, rl_point);
-				rl_point = start;
-				rl_begin_undo_group ();
-				if (matches[1])
-				{
-					while (matches[i])
-					{
-						rl_safe_insert_text (matches[i++]);
-						rl_insert_text (" ");
-					}
-				}
-				else
-				{
-					rl_safe_insert_text (matches[0]);
-					rl_insert_text (" ");
-				}
-				rl_end_undo_group ();
-			}
-			break;
-
-
-		case '?':
-			{
-				int len, count, limit, max = 0;
-				int j, k, l;
-
-autolist:
-				/* Handle simple case first.  What if there is only one answer? */
-				if (!matches[1])
-				{
-					char *rindex (), *temp;
-
-					if (rl_filename_completion_desired)
-						temp = rindex (matches[0], '/');
-					else
-						temp = (char *)NULL;
-
-					if (!temp)
-						temp = matches[0];
-					else
-						temp++;
-
-					crlf ();
-					fprintf (out_stream, "%s", temp);
-					crlf ();
-					goto restart;
-				}
-
-				/* There is more than one answer.  Find out how many there are,
-	       and find out what the maximum printed length of a single entry
-	       is. */
-				for (i = 1; matches[i]; i++)
-				{
-					char *rindex (), *temp = (char *)NULL;
-
-					/* If we are hacking filenames, then only count the characters
-		   after the last slash in the pathname. */
-					if (rl_filename_completion_desired)
-						temp = rindex (matches[i], '/');
-					else
-						temp = (char *)NULL;
-
-					if (!temp)
-						temp = matches[i];
-					else
-						temp++;
-
-					if (strlen (temp) > max)
-						max = strlen (temp);
-				}
-
-				len = i;
-
-				/* If there are many items, then ask the user if she
-	       really wants to see them all. */
-				if (len >= rl_completion_query_items)
-				{
-					crlf ();
-					fprintf (out_stream,
-					    "There are %d possibilities.  Do you really", len);
-					crlf ();
-					fprintf (out_stream, "wish to see them all? (y or n)");
-					fflush (out_stream);
-					if (!get_y_or_n ())
-					{
-						crlf ();
-						goto restart;
-					}
-				}
-				/* How many items of MAX length can we fit in the screen window? */
-				max += 2;
-				limit = screenwidth / max;
-				if (limit != 1 && (limit * max == screenwidth))
-					limit--;
-
-				/* How many iterations of the printing loop? */
-				count = (len + (limit - 1)) / limit;
-
-				/* Watch out for special case.  If LEN is less than LIMIT, then
-	       just do the inner printing loop. */
-				if (len < limit) count = 1;
-
-				/* Sort the items if they are not already sorted. */
-				if (!rl_ignore_completion_duplicates)
-					qsort (matches, len, sizeof (char *), compare_strings);
-
-				/* Print the sorted items, up-and-down alphabetically, like
-	       ls might. */
-				crlf ();
-
-				for (i = 1; i < count + 1; i++)
-				{
-					for (j = 0, l = i; j < limit; j++)
-					{
-						if (l > len || !matches[l])
-						{
-							break;
-						}
-						else
-						{
-							char *rindex (), *temp = (char *)NULL;
-
-							if (rl_filename_completion_desired)
-								temp = rindex (matches[l], '/');
-							else
-								temp = (char *)NULL;
-
-							if (!temp)
-								temp = matches[l];
-							else
-								temp++;
-
-							fprintf (out_stream, "%s", temp);
-							for (k = 0; k < max - strlen (temp); k++)
-								putc (' ', out_stream);
-						}
-						l += count;
-					}
-					crlf ();
-				}
-restart:
-
-				rl_on_new_line ();
-			}
-			break;
-
-		default:
-			abort ();
-		}
-
-		for (i = 0; matches[i]; i++)
-			free (matches[i]);
-		free (matches);
-	}
-}
-
-/* Stupid comparison routine for qsort () ing strings. */
-static int
-compare_strings (s1, s2)
-char **s1, **s2;
-{
-	return (strcmp (*s1, *s2));
-}
-
-/* If non-null, this contains the address of a function to call if the
-   standard meaning for expanding a tilde fails.  The function is called
-   with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
-   which is the expansion, or a NULL pointer if there is no expansion. */
-Function *rl_tilde_expander = (Function *)NULL;
-
-/* Expand FILENAME if it begins with a tilde.  This always returns
-   a new string. */
-char *
-tilde_expand (filename)
-char *filename;
-{
-	char *dirname = filename ? savestring (filename) : (char *)NULL;
-
-	if (dirname && *dirname == '~')
-	{
-		char *temp_name;
-		if (!dirname[1] || dirname[1] == '/')
-		{
-			/* Prepend $HOME to the rest of the string. */
-			char *temp_home = (char *)getenv ("HOME");
-
-			temp_name = (char *)alloca (1 + strlen (&dirname[1])
-			    + (temp_home? strlen (temp_home) : 0));
-			temp_name[0] = '\0';
-			if (temp_home)
-				strcpy (temp_name, temp_home);
-			strcat (temp_name, &dirname[1]);
-			free (dirname);
-			dirname = savestring (temp_name);
-		}
-		else
-		{
-			struct passwd *getpwnam (), *user_entry;
-			char *username = (char *)alloca (257);
-			int i, c;
-
-			for (i = 1; c = dirname[i]; i++)
-			{
-				if (c == '/') break;
-				else username[i - 1] = c;
-			}
-			username[i - 1] = '\0';
-
-			if (!(user_entry = getpwnam (username)))
-			{
-				/* If the calling program has a special syntax for
-		 expanding tildes, and we couldn't find a standard
-		 expansion, then let them try. */
-				if (rl_tilde_expander)
-				{
-					char *expansion;
-
-					expansion = (char *)(*rl_tilde_expander) (username);
-
-					if (expansion)
-					{
-						temp_name = (char *)alloca (1 + strlen (expansion)
-						    + strlen (&dirname[i]));
-						strcpy (temp_name, expansion);
-						strcat (temp_name, &dirname[i]);
-						free (expansion);
-						goto return_name;
-					}
-				}
-				/*
-	       * We shouldn't report errors.
-	       */
-			}
-			else
-			{
-				temp_name = (char *)alloca (1 + strlen (user_entry->pw_dir)
-				    + strlen (&dirname[i]));
-				strcpy (temp_name, user_entry->pw_dir);
-				strcat (temp_name, &dirname[i]);
-return_name:
-				free (dirname);
-				dirname = savestring (temp_name);
-			}
-		}
-	}
-	return (dirname);
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Undo, and Undoing			    */
-/*								    */
-/* **************************************************************** */
-
-/* Non-zero tells rl_delete_text and rl_insert_text to not add to
-   the undo list. */
-int doing_an_undo = 0;
-
-/* The current undo list for THE_LINE. */
-UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
-
-/* Remember how to undo something.  Concatenate some undos if that
-   seems right. */
-rl_add_undo (what, start, end, text)
-enum undo_code what;
-int start, end;
-char *text;
-{
-	UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
-	temp->what = what;
-	temp->start = start;
-	temp->end = end;
-	temp->text = text;
-	temp->next = rl_undo_list;
-	rl_undo_list = temp;
-}
-
-/* Free the existing undo list. */
-free_undo_list ()
-{
-	while (rl_undo_list) {
-		UNDO_LIST *release = rl_undo_list;
-		rl_undo_list = rl_undo_list->next;
-
-		if (release->what == UNDO_DELETE)
-			free (release->text);
-
-		free (release);
-	}
-}
-
-/* Undo the next thing in the list.  Return 0 if there
-   is nothing to undo, or non-zero if there was. */
-int
-rl_do_undo ()
-{
-	UNDO_LIST *release;
-	int waiting_for_begin = 0;
-
-undo_thing:
-	if (!rl_undo_list)
-		return (0);
-
-	doing_an_undo = 1;
-
-	switch (rl_undo_list->what) {
-
-		/* Undoing deletes means inserting some text. */
-	case UNDO_DELETE:
-		rl_point = rl_undo_list->start;
-		rl_insert_text (rl_undo_list->text);
-		free (rl_undo_list->text);
-		break;
-
-		/* Undoing inserts means deleting some text. */
-	case UNDO_INSERT:
-		rl_delete_text (rl_undo_list->start, rl_undo_list->end);
-		rl_point = rl_undo_list->start;
-		break;
-
-		/* Undoing an END means undoing everything 'til we get to
-       a BEGIN. */
-	case UNDO_END:
-		waiting_for_begin++;
-		break;
-
-		/* Undoing a BEGIN means that we are done with this group. */
-	case UNDO_BEGIN:
-		if (waiting_for_begin)
-			waiting_for_begin--;
-		else
-			abort ();
-		break;
-	}
-
-	doing_an_undo = 0;
-
-	release = rl_undo_list;
-	rl_undo_list = rl_undo_list->next;
-	free (release);
-
-	if (waiting_for_begin)
-		goto undo_thing;
-
-	return (1);
-}
-
-/* Begin a group.  Subsequent undos are undone as an atomic operation. */
-rl_begin_undo_group ()
-{
-	rl_add_undo (UNDO_BEGIN, 0, 0, 0);
-}
-
-/* End an undo group started with rl_begin_undo_group (). */
-rl_end_undo_group ()
-{
-	rl_add_undo (UNDO_END, 0, 0, 0);
-}
-
-/* Save an undo entry for the text from START to END. */
-rl_modifying (start, end)
-int start, end;
-{
-	if (start > end)
-	{
-		int t = start;
-		start = end;
-		end = t;
-	}
-
-	if (start != end)
-	{
-		char *temp = rl_copy (start, end);
-		rl_begin_undo_group ();
-		rl_add_undo (UNDO_DELETE, start, end, temp);
-		rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
-		rl_end_undo_group ();
-	}
-}
-
-/* Revert the current line to its previous state. */
-rl_revert_line ()
-{
-	if (!rl_undo_list) ding ();
-	else {
-		while (rl_undo_list)
-			rl_do_undo ();
-	}
-}
-
-/* Do some undoing of things that were done. */
-rl_undo_command (count)
-{
-	if (count < 0) return;	/* Nothing to do. */
-
-	while (count)
-	{
-		if (rl_do_undo ())
-		{
-			count--;
-		}
-		else
-		{
-			ding ();
-			break;
-		}
-	}
-}
-
-/* **************************************************************** */
-/*								    */
-/*			History Utilities			    */
-/*								    */
-/* **************************************************************** */
-
-/* We already have a history library, and that is what we use to control
-   the history features of readline.  However, this is our local interface
-   to the history mechanism. */
-
-/* While we are editing the history, this is the saved
-   version of the original line. */
-HIST_ENTRY *saved_line_for_history = (HIST_ENTRY *)NULL;
-
-/* Set the history pointer back to the last entry in the history. */
-start_using_history ()
-{
-	using_history ();
-	if (saved_line_for_history)
-		free_history_entry (saved_line_for_history);
-
-	saved_line_for_history = (HIST_ENTRY *)NULL;
-}
-
-/* Free the contents (and containing structure) of a HIST_ENTRY. */
-free_history_entry (entry)
-HIST_ENTRY *entry;
-{
-	if (!entry) return;
-	if (entry->line)
-		free (entry->line);
-	free (entry);
-}
-
-/* Perhaps put back the current line if it has changed. */
-maybe_replace_line ()
-{
-	HIST_ENTRY *temp = current_history ();
-
-	/* If the current line has changed, save the changes. */
-	if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list)) {
-		free (temp->line);
-		free (temp);
-	}
-}
-
-/* Put back the saved_line_for_history if there is one. */
-maybe_unsave_line ()
-{
-	if (saved_line_for_history) {
-		strcpy (the_line, saved_line_for_history->line);
-		rl_undo_list = (UNDO_LIST *)saved_line_for_history->data;
-		free_history_entry (saved_line_for_history);
-		saved_line_for_history = (HIST_ENTRY *)NULL;
-		rl_end = rl_point = strlen (the_line);
-	} else {
-		ding ();
-	}
-}
-
-/* Save the current line in saved_line_for_history. */
-maybe_save_line ()
-{
-	if (!saved_line_for_history) {
-		saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
-		saved_line_for_history->line = savestring (the_line);
-		saved_line_for_history->data = (char *)rl_undo_list;
-	}
-}
-
-
-
-/* **************************************************************** */
-/*								    */
-/*			History Commands			    */
-/*								    */
-/* **************************************************************** */
-
-/* Meta-< goes to the start of the history. */
-rl_beginning_of_history ()
-{
-	rl_get_previous_history (1 + where_history ());
-}
-
-/* Meta-> goes to the end of the history.  (The current line). */
-rl_end_of_history ()
-{
-	maybe_replace_line ();
-	using_history ();
-	maybe_unsave_line ();
-}
-
-/* Move down to the next history line. */
-rl_get_next_history (count)
-int count;
-{
-	HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
-
-	if (count < 0)
-	{
-		rl_get_previous_history (-count);
-		return;
-	}
-
-	if (!count)
-		return;
-
-	maybe_replace_line ();
-
-	while (count)
-	{
-		temp = next_history ();
-		if (!temp)
-			break;
-		if (--count)
-			free(temp);
-	}
-
-	if (!temp)
-		maybe_unsave_line ();
-	else
-	{
-		free(temp);
-		strcpy (the_line, temp->line);
-		rl_undo_list = (UNDO_LIST *)temp->data;
-		rl_end = rl_point = strlen (the_line);
-	}
-}
-
-/* Get the previous item out of our interactive history, making it the current
-   line.  If there is no previous history, just ding. */
-rl_get_previous_history (count)
-int count;
-{
-	HIST_ENTRY *old_temp = (HIST_ENTRY *)NULL;
-	HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
-
-	if (count < 0)
-	{
-		rl_get_next_history (-count);
-		return;
-	}
-
-	if (!count)
-		return;
-
-	/* If we don't have a line saved, then save this one. */
-	maybe_save_line ();
-
-	/* If the current line has changed, save the changes. */
-	maybe_replace_line ();
-
-	while (count)
-	{
-		temp = previous_history ();
-		if (!temp)
-			break;
-		else
-			old_temp = temp;
-		if (--count)
-			free(temp);
-	}
-
-	/* If there was a large argument, and we moved back to the start of the
-     history, that is not an error.  So use the last value found. */
-	if (!temp && old_temp)
-		temp = old_temp;
-
-	if (!temp)
-		ding ();
-	else
-	{
-		strcpy (the_line, temp->line);
-		rl_undo_list = (UNDO_LIST *)temp->data;
-		rl_end = rl_point = strlen (the_line);
-#ifdef VI_MODE
-		if (rl_editing_mode == vi_mode)
-			rl_point = 0;
-#endif /* VI_MODE */
-	}
-}
-
-/* There is a command in ksh which yanks into this line, the last word
-   of the previous line.  Here it is.  We left it on M-. */
-rl_yank_previous_last_arg (ignore)
-int ignore;
-{
-}
-
-/* Make C be the next command to be executed. */
-rl_execute_next (c)
-int c;
-{
-	rl_pending_input = c;
-}
-
-/* **************************************************************** */
-/*								    */
-/*			Killing Mechanism			    */
-/*								    */
-/* **************************************************************** */
-
-/* What we assume for a max number of kills. */
-#define DEFAULT_MAX_KILLS 10
-
-/* The real variable to look at to find out when to flush kills. */
-int rl_max_kills = DEFAULT_MAX_KILLS;
-
-/* Where to store killed text. */
-char **rl_kill_ring = (char **)NULL;
-
-/* Where we are in the kill ring. */
-int rl_kill_index = 0;
-
-/* How many slots we have in the kill ring. */
-int rl_kill_ring_length = 0;
-
-/* How to say that you only want to save a certain amount
-   of kill material. */
-rl_set_retained_kills (num)
-int num;
-{
-}
-
-/* The way to kill something.  This appends or prepends to the last
-   kill, if the last command was a kill command.  if FROM is less
-   than TO, then the text is appended, otherwise prepended.  If the
-   last command was not a kill command, then a new slot is made for
-   this kill. */
-rl_kill_text (from, to)
-int from, to;
-{
-	int slot;
-	char *text = rl_copy (from, to);
-
-	/* Is there anything to kill? */
-	if (from == to) {
-		free (text);
-		last_command_was_kill++;
-		return;
-	}
-
-	/* Delete the copied text from the line. */
-	rl_delete_text (from, to);
-
-	/* First, find the slot to work with. */
-	if (!last_command_was_kill) {
-
-		/* Get a new slot.  */
-		if (!rl_kill_ring) {
-
-			/* If we don't have any defined, then make one. */
-			rl_kill_ring =
-			    (char **)xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
-			slot = 1;
-
-		} else {
-
-			/* We have to add a new slot on the end, unless we have exceeded
-	 the max limit for remembering kills. */
-			slot = rl_kill_ring_length;
-			if (slot == rl_max_kills) {
-				register int i;
-				free (rl_kill_ring[0]);
-				for (i = 0; i < slot; i++)
-					rl_kill_ring[i] = rl_kill_ring[i + 1];
-			} else {
-				rl_kill_ring =
-				    (char **)xrealloc (rl_kill_ring,
-				    ((slot = (rl_kill_ring_length += 1)) + 1)
-				    * sizeof (char *));
-			}
-		}
-		slot--;
-	} else {
-		slot = rl_kill_ring_length - 1;
-	}
-
-	/* If the last command was a kill, prepend or append. */
-	if (last_command_was_kill) {
-		char *old = rl_kill_ring[slot];
-		char *new = (char *)xmalloc (1 + strlen (old) + strlen (text));
-
-		if (from < to) {
-			strcpy (new, old);
-			strcat (new, text);
-		} else {
-			strcpy (new, text);
-			strcat (new, old);
-		}
-		free (old);
-		free (text);
-		rl_kill_ring[slot] = new;
-	} else {
-		rl_kill_ring[slot] = text;
-	}
-	rl_kill_index = slot;
-	last_command_was_kill++;
-}
-
-/* Now REMEMBER!  In order to do prepending or appending correctly, kill
-   commands always make rl_point's original position be the FROM argument,
-   and rl_point's extent be the TO argument. */
-
-
-/* **************************************************************** */
-/*								    */
-/*			Killing Commands			    */
-/*								    */
-/* **************************************************************** */
-
-/* Delete the word at point, saving the text in the kill ring. */
-rl_kill_word (count)
-int count;
-{
-	int orig_point = rl_point;
-
-	if (count < 0)
-		rl_backward_kill_word (-count);
-	else
-	{
-		rl_forward_word (count);
-
-		if (rl_point != orig_point)
-			rl_kill_text (orig_point, rl_point);
-
-		rl_point = orig_point;
-	}
-}
-
-/* Rubout the word before point, placing it on the kill ring. */
-rl_backward_kill_word (count)
-int count;
-{
-	int orig_point = rl_point;
-
-	if (count < 0)
-		rl_kill_word (-count);
-	else
-	{
-		rl_backward_word (count);
-
-		if (rl_point != orig_point)
-			rl_kill_text (orig_point, rl_point);
-	}
-}
-
-/* Kill from here to the end of the line.  If DIRECTION is negative, kill
-   back to the line start instead. */
-rl_kill_line (direction)
-int direction;
-{
-	int orig_point = rl_point;
-
-	if (direction < 0)
-		rl_backward_kill_line (1);
-	else
-	{
-		rl_end_of_line ();
-		if (orig_point != rl_point)
-			rl_kill_text (orig_point, rl_point);
-		rl_point = orig_point;
-	}
-}
-
-/* Kill backwards to the start of the line.  If DIRECTION is negative, kill
-   forwards to the line end instead. */
-rl_backward_kill_line (direction)
-int direction;
-{
-	int orig_point = rl_point;
-
-	if (direction < 0)
-		rl_kill_line (1);
-	else
-	{
-		if (!rl_point)
-			ding ();
-		else
-		{
-			rl_beg_of_line ();
-			rl_kill_text (orig_point, rl_point);
-		}
-	}
-}
-
-/* Yank back the last killed text.  This ignores arguments. */
-rl_yank ()
-{
-	if (!rl_kill_ring) rl_abort ();
-	rl_insert_text (rl_kill_ring[rl_kill_index]);
-}
-
-/* If the last command was yank, or yank_pop, and the text just
-   before point is identical to the current kill item, then
-   delete that text from the line, rotate the index down, and
-   yank back some other text. */
-rl_yank_pop ()
-{
-	int l;
-
-	if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
-	    !rl_kill_ring)
-	{
-		rl_abort ();
-	}
-
-	l = strlen (rl_kill_ring[rl_kill_index]);
-	if (((rl_point - l) >= 0) &&
-	    (strncmp (the_line + (rl_point - l),
-	    rl_kill_ring[rl_kill_index], l) == 0))
-	{
-		rl_delete_text ((rl_point - l), rl_point);
-		rl_point -= l;
-		rl_kill_index--;
-		if (rl_kill_index < 0)
-			rl_kill_index = rl_kill_ring_length - 1;
-		rl_yank ();
-	}
-	else
-		rl_abort ();
-
-}
-
-extern char *extracthistarg();
-
-/* Yank the COUNTth argument from the previous history line. */
-rl_yank_nth_arg (count, ignore)
-int count;
-{
-char *arg;
-
-	arg = extracthistarg(count);
-	if (!arg || !*arg)
-	{
-		ding ();
-		return;
-	}
-
-	rl_begin_undo_group ();
-	if (rl_point && the_line[rl_point - 1] != ' ')
-		rl_insert_text (" ");
-	rl_insert_text (arg);
-	free (arg);
-	rl_end_undo_group ();
-}
-
-/* Vi Mode. */
-#ifdef VI_MODE
-#include "vi_mode.c"
-#endif /* VI_MODE */
-
-/* How to toggle back and forth between editing modes. */
-rl_vi_editing_mode ()
-{
-#ifdef VI_MODE
-	rl_editing_mode = vi_mode;
-	rl_vi_insertion_mode ();
-#endif /* VI_MODE */
-}
-
-rl_emacs_editing_mode ()
-{
-	rl_editing_mode = emacs_mode;
-	keymap = emacs_standard_keymap;
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			     Completion				    */
-/*								    */
-/* **************************************************************** */
-
-/* Non-zero means that case is not significant in completion. */
-int completion_case_fold = 0;
-
-/* Return an array of (char *) which is a list of completions for TEXT.
-   If there are no completions, return a NULL pointer.
-   The first entry in the returned array is the substitution for TEXT.
-    The remaining entries are the possible completions.
-   The array is terminated with a NULL pointer.
-
-   ENTRY_FUNCTION is a function of two args, and returns a (char *).
-     The first argument is TEXT.
-     The second is a state argument; it should be zero on the first call, and
-     non-zero on subsequent calls.  It returns a NULL pointer to the caller
-     when there are no more matches.
- */
-char **
-completion_matches (text, entry_function)
-char *text;
-char *(*entry_function) ();
-{
-	/* Number of slots in match_list. */
-	int match_list_size;
-
-	/* The list of matches. */
-	char **match_list =
-	(char **)xmalloc (((match_list_size = 10) + 1) * sizeof (char *));
-
-	/* Number of matches actually found. */
-	int matches = 0;
-
-	/* Temporary string binder. */
-	char *string;
-
-	match_list[1] = (char *)NULL;
-
-	while (string = (*entry_function) (text, matches))
-	{
-		if (matches + 1 == match_list_size)
-			match_list =
-			    (char **)xrealloc (match_list,
-			    ((match_list_size += 10) + 1) * sizeof (char *));
-
-		match_list[++matches] = string;
-		match_list[matches + 1] = (char *)NULL;
-	}
-
-	/* If there were any matches, then look through them finding out the
-     lowest common denominator.  That then becomes match_list[0]. */
-	if (matches)
-	{
-		register int i = 1;
-		int low = 100000;		/* Count of max-matched characters. */
-
-		/* If only one match, just use that. */
-		if (matches == 1)
-		{
-			match_list[0] = match_list[1];
-			match_list[1] = (char *)NULL;
-		}
-		else
-		{
-			/* Otherwise, compare each member of the list with
-	     the next, finding out where they stop matching. */
-
-			while (i < matches)
-			{
-				register int c1, c2, si;
-
-				if (completion_case_fold)
-				{
-					for (si = 0;
-					    (c1 = to_lower(match_list[i][si])) &&
-					    (c2 = to_lower(match_list[i + 1][si]));
-					    si++)
-						if (c1 != c2) break;
-				}
-				else
-				{
-					for (si = 0;
-					    (c1 = match_list[i][si]) &&
-					    (c2 = match_list[i + 1][si]);
-					    si++)
-						if (c1 != c2) break;
-				}
-
-				if (low > si) low = si;
-				i++;
-			}
-			match_list[0] = (char *)xmalloc (low + 1);
-			strncpy (match_list[0], match_list[1], low);
-			match_list[0][low] = '\0';
-		}
-	}
-	else	/* There were no matches. */
-	{
-		free (match_list);
-		match_list = (char **)NULL;
-	}
-	return (match_list);
-}
-
-/* Okay, now we write the entry_function for filename completion.  In the
-   general case.  Note that completion in the shell is a little different
-   because of all the pathnames that must be followed when looking up the
-   completion for a command. */
-char *
-filename_completion_function (text, state)
-int state;
-char *text;
-{
-	static DIR *directory;
-	static char *filename = (char *)NULL;
-	static char *dirname = (char *)NULL;
-	static char *users_dirname = (char *)NULL;
-	static int filename_len;
-
-	struct direct *entry = (struct direct *)NULL;
-
-	/* If we don't have any state, then do some initialization. */
-	if (!state)
-	{
-		char *rindex (), *temp;
-
-		if (dirname) free (dirname);
-		if (filename) free (filename);
-		if (users_dirname) free (users_dirname);
-
-		filename = savestring (text);
-		if (!*text) text = ".";
-		dirname = savestring (text);
-
-		temp = rindex (dirname, '/');
-
-		if (temp)
-		{
-			strcpy (filename, ++temp);
-			*temp = '\0';
-		}
-		else
-			strcpy (dirname, ".");
-
-		/* We aren't done yet.  We also support the "~user" syntax. */
-
-		/* Save the version of the directory that the user typed. */
-		users_dirname = savestring (dirname);
-		directory = opendir (dirname);
-		filename_len = strlen (filename);
-
-		rl_filename_completion_desired = 1;
-	}
-
-	/* At this point we should entertain the possibility of hacking wildcarded
-     filenames, like /usr/man*\/te<TAB>.  If the directory name contains
-     globbing characters, then build an array of directories to glob on, and
-     glob on the first one. */
-
-	/* Now that we have some state, we can read the directory. */
-
-	while (directory && (entry = readdir (directory)))
-	{
-		/* Special case for no filename.
-	 All entries except "." and ".." match. */
-		if (!filename_len)
-		{
-			if ((strcmp (entry->d_name, ".") != 0) &&
-			    (strcmp (entry->d_name, "..") != 0))
-				break;
-		}
-		else
-		{
-			/* Otherwise, if these match upto the length of filename, then
-	     it is a match. */
-#ifdef TMB_SYSV
-			if ((strlen (entry->d_name) >= filename_len) &&
-			    (strncmp (filename, entry->d_name, filename_len) == 0))
-#else
-				if ((entry->d_namlen >= filename_len) &&
-				    (strncmp (filename, entry->d_name, filename_len) == 0))
-#endif /* TMB_SYSV */
-				{
-					break;
-				}
-		}
-	}
-
-	if (!entry)
-	{
-		if (directory)
-		{
-			closedir (directory);
-			directory = (DIR *)NULL;
-		}
-		return (char *)NULL;
-	}
-	else
-	{
-		char *temp;
-
-		if (dirname && (strcmp (dirname, ".") != 0))
-		{
-#ifdef TMB_SYSV
-			temp = (char *)xmalloc (1 + strlen (users_dirname)
-			    + strlen (entry->d_name));
-#else
-			temp = (char *)xmalloc (1 + strlen (users_dirname)
-			    + entry->d_namlen);
-#endif /* TMB_SYSV */
-			strcpy (temp, users_dirname);
-			strcat (temp, entry->d_name);
-		}
-		else
-		{
-			temp = (savestring (entry->d_name));
-		}
-		return (temp);
-	}
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Binding keys				    */
-/*								    */
-/* **************************************************************** */
-
-/* rl_add_defun (char *name, Function *function, int key)
-   Add NAME to the list of named functions.  Make FUNCTION
-   be the function that gets called.
-   If KEY is not -1, then bind it. */
-rl_add_defun (name, function, key)
-char *name;
-Function *function;
-int key;
-{
-	if (key != -1)
-		rl_bind_key (key, function);
-	rl_add_funmap_entry (name, function);
-}
-
-/* Bind KEY to FUNCTION.  Returns non-zero if KEY is out of range. */
-int
-rl_bind_key (key, function)
-int key;
-Function *function;
-{
-	if (key < 0)
-		return (key);
-
-	if (key > 127 && key < 256)
-	{
-		if (keymap[ESC].type == ISKMAP)
-		{
-			Keymap escmap = (Keymap)keymap[ESC].function;
-
-			key -= 128;
-			escmap[key].type = ISFUNC;
-			escmap[key].function = function;
-			return (0);
-		}
-		return (key);
-	}
-
-	keymap[key].type = ISFUNC;
-	keymap[key].function = function;
-	return (0);
-}
-
-/* Bind KEY to FUNCTION in MAP.  Returns non-zero in case of invalid
-   KEY. */
-int
-rl_bind_key_in_map (key, function, map)
-int key;
-Function *function;
-Keymap map;
-{
-	int result;
-	Keymap oldmap = keymap;
-
-	keymap = map;
-	result = rl_bind_key (key, function);
-	keymap = oldmap;
-	return (result);
-}
-
-/* Make KEY do nothing in the currently selected keymap.
-   Returns non-zero in case of error. */
-int
-rl_unbind_key (key)
-int key;
-{
-	return (rl_bind_key (key, (Function *)NULL));
-}
-
-/* Make KEY do nothing in MAP.
-   Returns non-zero in case of error. */
-int
-rl_unbind_key_in_map (key, map)
-int key;
-Keymap map;
-{
-	return (rl_bind_key_in_map (key, (Function *)NULL, map));
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
-   FUNCTION.  This makes new keymaps as necessary.  The initial
-   place to do bindings is in MAP. */
-rl_set_key (keyseq, function, map)
-char *keyseq;
-Function *function;
-Keymap map;
-{
-	rl_generic_bind (ISFUNC, keyseq, function, map);
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
-   the string of characters MACRO.  This makes new keymaps as
-   necessary.  The initial place to do bindings is in MAP. */
-rl_macro_bind (keyseq, macro, map)
-char *keyseq, *macro;
-Keymap map;
-{
-	char *macro_keys = (char *)xmalloc (2 * (strlen (macro)));
-	int macro_keys_len;
-
-	if (rl_translate_keyseq (macro, macro_keys, &macro_keys_len))
-	{
-		free (macro_keys);
-		return;
-	}
-	rl_generic_bind (ISMACR, keyseq, macro_keys, map);
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
-   the arbitrary pointer DATA.  TYPE says what kind of data is
-   pointed to by DATA, right now this can be a function (ISFUNC),
-   a macro (ISMACR), or a keymap (ISKMAP).  This makes new keymaps
-   as necessary.  The initial place to do bindings is in MAP. */
-rl_generic_bind (type, keyseq, data, map)
-int type;
-char *keyseq, *data;
-Keymap map;
-{
-	char *keys;
-	int keys_len;
-	register int i;
-
-	/* If no keys to bind to, exit right away. */
-	if (!keyseq || !*keyseq)
-	{
-		if (type == ISMACR)
-			free (data);
-		return;
-	}
-
-	keys = (char *)alloca (1 + (2 * strlen (keyseq)));
-
-	/* Translate the ASCII representation of KEYSEQ into an array
-     of characters.  Stuff the characters into ARRAY, and the
-     length of ARRAY into LENGTH. */
-	if (rl_translate_keyseq (keyseq, keys, &keys_len))
-		return;
-
-	/* Bind keys, making new keymaps as necessary. */
-	for (i = 0; i < keys_len; i++)
-	{
-		if (i + 1 < keys_len)
-		{
-			if (map[keys[i]].type != ISKMAP)
-			{
-				if (map[i].type == ISMACR)
-					free ((char *)map[i].function);
-
-				map[keys[i]].type = ISKMAP;
-				map[keys[i]].function = (Function *)rl_make_bare_keymap ();
-			}
-			map = (Keymap)map[keys[i]].function;
-		}
-		else
-		{
-			if (map[keys[i]].type == ISMACR)
-				free ((char *)map[keys[i]].function);
-
-			map[keys[i]].function = (Function *)data;
-			map[keys[i]].type = type;
-		}
-	}
-}
-
-/* Translate the ASCII representation of SEQ, stuffing the
-   values into ARRAY, an array of characters.  LEN gets the
-   final length of ARRAY.  Return non-zero if there was an
-   error parsing SEQ. */
-rl_translate_keyseq (seq, array, len)
-char *seq, *array;
-int *len;
-{
-	register int i, c, l = 0;
-
-	for (i = 0; c = seq[i]; i++)
-	{
-		if (c == '\\')
-		{
-			c = seq[++i];
-
-			if (!c)
-				break;
-
-			if (((c == 'C' || c == 'M') &&  seq[i + 1] == '-') ||
-			    (c == 'e'))
-			{
-				/* Handle special case of backwards define. */
-				if (strncmp (&seq[i], "C-\\M-", 5) == 0)
-				{
-					array[l++] = ESC;
-					i += 5;
-					array[l++] = CTRL (to_upper (seq[i]));
-					if (!seq[i])
-						i--;
-					continue;
-				}
-
-				switch (c)
-				{
-				case 'M':
-					i++;
-					array[l++] = ESC;
-					break;
-
-				case 'C':
-					i += 2;
-					array[l++] = CTRL (to_upper (seq[i]));
-					break;
-
-				case 'e':
-					array[l++] = ESC;
-				}
-
-				continue;
-			}
-		}
-		array[l++] = c;
-	}
-
-	*len = l;
-	array[l] = '\0';
-	return (0);
-}
-
-/* Return a pointer to the function that STRING represents.
-   If STRING doesn't have a matching function, then a NULL pointer
-   is returned. */
-Function *
-rl_named_function (string)
-char *string;
-{
-	register int i;
-
-	for (i = 0; funmap[i]; i++)
-		if (stricmp (funmap[i]->name, string) == 0)
-			return (funmap[i]->function);
-	return ((Function *)NULL);
-}
-
---cut here---cut here---cut here---



More information about the Alt.sources mailing list