Merge in changes from bash-1.13. The most obvious one is

that the file readline.c has been split into multiple files.
	* bind.c, complete.c, dispay.c, isearch.c, parens.c, rldefs.h,
	rltty.c, search.c signals.c, tilde.c, tilde.h, xmalloc.c:  New files.
This commit is contained in:
Per Bothner 1994-01-16 03:39:57 +00:00
parent 8b564df836
commit 5e98bbab17
16 changed files with 5574 additions and 4035 deletions

View File

@ -28,28 +28,40 @@ Things-to-keep:
COPYING
ChangeLog
Makefile.in
configure.bat
bind.c
chardefs.h
complete.c
config
configure.bat
configure.in
display.c
doc
emacs_keymap.c
examples
funmap.c
history.c
history.h
isearch.c
keymaps.c
keymaps.h
parens.c
readline.c
readline.h
rldefs.h
rltty.c
search.c
signals.c
sysdep-aix.h
sysdep-irix.h
sysdep-norm.h
sysdep-obsd.h
sysdep-sco.h
sysdep-sysv4.h
tilde.c
tilde.h
vi_keymap.c
vi_mode.c
xmalloc.c
Things-to-lose:

View File

@ -1,3 +1,10 @@
Sat Jan 15 19:36:12 1994 Per Bothner (bothner@kalessin.cygnus.com)
Merge in changes from bash-1.13. The most obvious one is
that the file readline.c has been split into multiple files.
* bind.c, complete.c, dispay.c, isearch.c, parens.c, rldefs.h,
rltty.c, search.c signals.c, tilde.c, tilde.h, xmalloc.c: New files.
Sat Dec 11 16:29:17 1993 Steve Chamberlain (sac@thepub.cygnus.com)
* readline.c (rl_getc): If GO32, trim high bit from getkey,

View File

@ -81,10 +81,22 @@ CP = cp
LOCAL_INCLUDES = -I$(srcdir)/../
CSOURCES = readline.c history.c funmap.c keymaps.c vi_mode.c \
emacs_keymap.c vi_keymap.c
# The name of the main library target.
LIBRARY_NAME = libreadline.a
# The C code source files for this library.
CSOURCES = readline.c funmap.c keymaps.c vi_mode.c parens.c \
rltty.c complete.c bind.c isearch.c display.c signals.c \
emacs_keymap.c vi_keymap.c history.c tilde.c xmalloc.c
# The header files for this library.
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h \
posixstat.h tilde.h
OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \
rltty.o complete.o bind.o isearch.o display.o signals.o \
history.o tilde.o xmalloc.o
HSOURCES = readline.h chardefs.h history.h keymaps.h
SOURCES = $(CSOURCES) $(HSOURCES)
DOCUMENTATION = readline.texi inc-read.texi \
@ -94,6 +106,17 @@ SUPPORT = COPYING Makefile $(DOCUMENTATION) ChangeLog
THINGS_TO_TAR = $(SOURCES) $(SUPPORT)
FLAGS_TO_PASS = \
"prefix=$(prefix)" \
"exec_prefix=$(exec_prefix)" \
"against=$(against)" \
"MAKEINFO=$(MAKEINFO)" \
"INSTALL=$(INSTALL)" \
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
"INSTALL_DATA=$(INSTALL_DATA)"
SUBDIRS = doc
#### Host, target, and site specific Makefile fragments come in here.
###
@ -106,11 +129,18 @@ all: libreadline.a
check:
installcheck:
info:
dvi:
clean-info: force
-rm -f *.info*
info dvi install-info clean-info: force
@$(MAKE) $(FLAGS_TO_PASS) DO=$@ "DODIRS=$(SUBDIRS)" subdir_do
subdir_do: force
@for i in $(DODIRS); do \
if [ -f ./$$i/Makefile ] ; then \
if (cd ./$$i; \
$(MAKE) $(FLAGS_TO_PASS) $(DO)) ; then true ; \
else exit 1 ; fi ; \
else true ; fi ; \
done
history.info: $(srcdir)/history.texi
$(MAKEINFO) -o history.info $(srcdir)/history.texi
@ -118,9 +148,9 @@ history.info: $(srcdir)/history.texi
readline.info: $(srcdir)/readline.texi $(srcdir)/inc-read.texi
$(MAKEINFO) -o readline.info $(srcdir)/readline.texi
libreadline.a: readline.o history.o funmap.o keymaps.o tilde.o vi_mode.o
libreadline.a: $(OBJECTS)
$(RM) -f libreadline.a
$(AR) $(AR_FLAGS) libreadline.a readline.o history.o funmap.o keymaps.o tilde.o vi_mode.o
$(AR) $(AR_FLAGS) libreadline.a $(OBJECTS)
$(RANLIB) libreadline.a
readline.o: readline.h chardefs.h keymaps.h history.h readline.c vi_mode.c
@ -146,35 +176,13 @@ readline.tar.Z: readline.tar
compress -f readline.tar
install:
-parent=`echo $(libdir)|sed -e 's@/[^/]*$$@@'`; \
if [ -d $$parent ] ; then true ; else mkdir $$parent ; fi
-if [ -d $(libdir) ] ; then true ; else mkdir $(libdir) ; fi
$(INSTALL_DATA) libreadline.a $(libdir)/libreadline.a
$(RANLIB) $(libdir)/libreadline.a
-parent=`echo $(includedir)|sed -e 's@/[^/]*$$@@'`; \
if [ -d $$parent ] ; then true ; else mkdir $$parent ; fi
-if [ -d $(includedir) ] ; then true ; else mkdir $(includedir) ; fi
-if [ -d $(includedir)/readline ] ; then true ; else mkdir $(includedir)/readline ; fi
$(INSTALL_DATA) $(srcdir)/readline.h $(includedir)/readline/readline.h
$(INSTALL_DATA) $(srcdir)/keymaps.h $(includedir)/readline/keymaps.h
$(INSTALL_DATA) $(srcdir)/chardefs.h $(includedir)/readline/chardefs.h
install-info: info
# -parent=`echo $(infodir)|sed -e 's@/[^/]*$$@@'`; \
# if [ -d $$parent ] ; then true ; else mkdir $$parent ; fi
# -if [ -d $(infodir) ] ; then true ; else mkdir $(infodir) ; fi
# for i in *.info* ; do \
# $(INSTALL_DATA) $$i $(infodir)/$$i ; \
# done
includes:
-parent=`echo $(includedir)|sed -e 's@/[^/]*$$@@'`; \
if [ -d $$parent ] ; then true ; else mkdir $$parent ; fi
-if [ -d $(includedir) ] ; then true ; else mkdir $(includedir) ; fi
-if [ ! -r $(includedir)/readline ]; then\
mkdir $(includedir)/readline;\
chmod a+r $(includedir)/readline;\
fi
$(INSTALL_FILE) $(srcdir)/readline.h $(includedir)/readline/readline.h
$(INSTALL_FILE) $(srcdir)/keymaps.h $(includedir)/readline/keymaps.h
$(INSTALL_FILE) $(srcdir)/chardefs.h $(includedir)/readline/chardefs.h

1396
readline/bind.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,21 @@
/* chardefs.h -- Character definitions for readline. */
#ifndef _CHARDEFS_
#define _CHARDEFS_
#include <ctype.h>
#if defined (HAVE_STRING_H)
# include <string.h>
#else
# include <strings.h>
#endif /* HAVE_STRING_H */
#ifndef savestring
#define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x))
extern char *xmalloc ();
# ifndef strcpy
extern char *strcpy ();
# endif
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
#endif
#ifndef whitespace
@ -14,11 +27,13 @@
#endif
/* Some character stuff. */
#define control_character_threshold 0x020 /* smaller than this is control */
#define meta_character_threshold 0x07f /* larger than this is Meta. */
#define control_character_threshold 0x020 /* Smaller than this is control. */
#define meta_character_threshold 0x07f /* Larger than this is Meta. */
#define control_character_bit 0x40 /* 0x000000, must be off. */
#define meta_character_bit 0x080 /* x0000000, must be on. */
#define largest_char 255 /* Largest character value. */
#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
#define CTRL(c) ((c) & (~control_character_bit))
#define META(c) ((c) | meta_character_bit)
@ -38,13 +53,41 @@
#define CTRL_P(c) ((c) < control_character_threshold)
#define META_P(c) ((c) > meta_character_threshold)
#ifndef NEWLINE
#define NEWLINE '\n'
#endif
#ifndef RETURN
#define RETURN CTRL('M')
#endif
#ifndef RUBOUT
#define RUBOUT 0x07f
#endif
#ifndef TAB
#define TAB '\t'
#endif
#ifdef ABORT_CHAR
#undef ABORT_CHAR
#endif
#define ABORT_CHAR CTRL('G')
#ifdef PAGE
#undef PAGE
#endif
#define PAGE CTRL('L')
#ifdef SPACE
#undef SPACE
#endif
#define SPACE 0x020
#ifdef ESC
#undef ESC
#endif
#define ESC CTRL('[')
#endif /* _CHARDEFS_ */

1205
readline/complete.c Normal file

File diff suppressed because it is too large Load Diff

801
readline/display.c Normal file
View File

@ -0,0 +1,801 @@
/* display.c -- readline redisplay facility. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <sys/types.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#if !defined (strrchr)
extern char *strrchr ();
#endif /* !strchr */
/* Global and pseudo-global variables and functions
imported from readline.c. */
extern char *rl_prompt;
extern int readline_echoing_p;
extern char *term_clreol, *term_im, *term_ic, *term_ei, *term_DC;
/* Termcap variables. */
extern char *term_up, *term_dc, *term_cr, *term_IC;
extern int screenheight, screenwidth, terminal_can_insert;
extern void _rl_output_some_chars ();
extern void _rl_output_character_function ();
extern int _rl_convert_meta_chars_to_ascii;
extern int _rl_horizontal_scroll_mode;
extern int _rl_mark_modified_lines;
extern int _rl_prefer_visible_bell;
/* Pseudo-global functions (local to the readline library) exported
by this file. */
void _rl_move_cursor_relative (), _rl_output_some_chars ();
void _rl_move_vert ();
static void update_line (), clear_to_eol ();
static void delete_chars (), insert_some_chars ();
extern char *xmalloc (), *xrealloc ();
/* **************************************************************** */
/* */
/* Display stuff */
/* */
/* **************************************************************** */
/* This is the stuff that is hard for me. I never seem to write good
display routines in C. Let's see how I do this time. */
/* (PWP) Well... Good for a simple line updater, but totally ignores
the problems of input lines longer than the screen width.
update_line and the code that calls it makes a multiple line,
automatically wrapping line update. Carefull attention needs
to be paid to the vertical position variables.
handling of terminals with autowrap on (incl. DEC braindamage)
could be improved a bit. Right now I just cheat and decrement
screenwidth by one. */
/* Keep two buffers; one which reflects the current contents of the
screen, and the other to draw what we think the new contents should
be. Then compare the buffers, and make whatever changes to the
screen itself that we should. Finally, make the buffer that we
just drew into be the one which reflects the current contents of the
screen, and place the cursor where it belongs.
Commands that want to can fix the display themselves, and then let
this function know that the display has been fixed by setting the
RL_DISPLAY_FIXED variable. This is good for efficiency. */
/* What YOU turn on when you have handled all redisplay yourself. */
int rl_display_fixed = 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;
/* Pseudo-global variables declared here. */
/* The visible cursor position. If you print some text, adjust this. */
int _rl_last_c_pos = 0;
int _rl_last_v_pos = 0;
/* Number of lines currently on screen minus 1. */
int _rl_vis_botlin = 0;
/* Variables used only in this file. */
/* 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;
/* A buffer for `modeline' messages. */
static char msg_buf[128];
/* Non-zero forces the redisplay even if we thought it was unnecessary. */
static int forced_display = 0;
/* Default and initial buffer size. Can grow. */
static int line_size = 1024;
/* Basic redisplay algorithm. */
rl_redisplay ()
{
register int in, out, c, linenum;
register char *line = invisible_line;
char *prompt_this_line;
int c_pos = 0;
int inv_botlin = 0; /* Number of lines in newly drawn buffer. */
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. */
out = 0;
if (_rl_mark_modified_lines && 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 caller's misconception. */
if (visible_line[0] != invisible_line[0])
rl_display_fixed = 0;
prompt_this_line = strrchr (rl_display_prompt, '\n');
if (!prompt_this_line)
prompt_this_line = rl_display_prompt;
else
{
prompt_this_line++;
if (forced_display)
_rl_output_some_chars
(rl_display_prompt, prompt_this_line - rl_display_prompt);
}
strncpy (line + out, prompt_this_line, strlen (prompt_this_line));
out += strlen (prompt_this_line);
line[out] = '\0';
for (in = 0; in < rl_end; in++)
{
c = (unsigned char)rl_line_buffer[in];
if (out + 8 >= line_size) /* XXX - 8 for \t */
{
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 (META_CHAR (c))
{
if (_rl_convert_meta_chars_to_ascii)
{
sprintf (line + out, "\\%o", c);
out += 4;
}
else
line[out++] = c;
}
#define DISPLAY_TABS
#if defined (DISPLAY_TABS)
else if (c == '\t')
{
register int newout = (out | (int)7) + 1;
while (out < newout)
line[out++] = ' ';
}
#endif
else if (c < ' ')
{
line[out++] = '^';
line[out++] = UNCTRL (c); /* XXX was c ^ 0x40 */
}
else if (c == 127)
{
line[out++] = '^';
line[out++] = '?';
}
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 (!_rl_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 > _rl_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 (_rl_vis_botlin > inv_botlin)
{
char *tt;
for (; linenum <= _rl_vis_botlin; linenum++)
{
tt = &visible_line[linenum * screenwidth];
_rl_move_vert (linenum);
_rl_move_cursor_relative (0, tt);
clear_to_eol
((linenum == _rl_vis_botlin) ? strlen (tt) : screenwidth);
}
}
_rl_vis_botlin = inv_botlin;
/* Move the cursor where it should be. */
_rl_move_vert (c_pos / screenwidth);
_rl_move_cursor_relative (c_pos % screenwidth,
&invisible_line[(c_pos / screenwidth) * screenwidth]);
}
}
else /* Do horizontal scrolling. */
{
int lmargin;
/* Always at top line. */
_rl_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);
_rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
last_lmargin = lmargin;
}
}
fflush (rl_outstream);
/* 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 void
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 > ofd) && (nls > nfd) && (*ols == *nls))
{
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++;
}
_rl_move_vert (current_line);
_rl_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)
{
/* Sometimes it is cheaper to print the characters rather than
use the terminal's capabilities. */
if ((2 * (ne - nfd)) < lendiff && !term_IC)
{
_rl_output_some_chars (nfd, (ne - nfd));
_rl_last_c_pos += (ne - nfd);
}
else
{
if (*ols)
{
insert_some_chars (nfd, lendiff);
_rl_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. */
_rl_output_some_chars (nfd, lendiff);
_rl_last_c_pos += lendiff;
}
/* Copy (new) chars to screen from first diff to last match. */
if (((nls - nfd) - lendiff) > 0)
{
_rl_output_some_chars (&nfd[lendiff], ((nls - nfd) - lendiff));
_rl_last_c_pos += ((nls - nfd) - lendiff);
}
}
}
else
{ /* cannot insert chars, write to EOL */
_rl_output_some_chars (nfd, (ne - nfd));
_rl_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)
{
_rl_output_some_chars (nfd, (nls - nfd));
_rl_last_c_pos += (nls - nfd);
}
}
/* Otherwise, print over the existing material. */
else
{
_rl_output_some_chars (nfd, (ne - nfd));
_rl_last_c_pos += (ne - nfd);
clear_to_eol ((oe - old) - (ne - new));
}
}
}
/* Tell the update routines that we have moved onto a new (empty) line. */
rl_on_new_line ()
{
if (visible_line)
visible_line[0] = '\0';
_rl_last_c_pos = _rl_last_v_pos = 0;
_rl_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 _rl_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. */
void
_rl_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 < _rl_last_c_pos - new)
{
#ifdef __MSDOS__
putc('\r', rl_outstream);
#else
tputs (term_cr, 1, _rl_output_character_function);
#endif
_rl_last_c_pos = 0;
}
if (_rl_last_c_pos == new) return;
if (_rl_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. */
#if defined (HACK_TERMCAP_MOTION)
extern char *term_forward_char;
if (term_forward_char)
for (i = _rl_last_c_pos; i < new; i++)
tputs (term_forward_char, 1, _rl_output_character_function);
else
for (i = _rl_last_c_pos; i < new; i++)
putc (data[i], rl_outstream);
#else
for (i = _rl_last_c_pos; i < new; i++)
putc (data[i], rl_outstream);
#endif /* HACK_TERMCAP_MOTION */
}
else
backspace (_rl_last_c_pos - new);
_rl_last_c_pos = new;
}
/* PWP: move the cursor up or down. */
void
_rl_move_vert (to)
int to;
{
register int delta, i;
if (_rl_last_v_pos == to || to > screenheight)
return;
#ifdef __GO32__
{
int row, col;
ScreenGetCursor (&row, &col);
ScreenSetCursor ((row + to - _rl_last_v_pos), col);
}
#else /* __GO32__ */
if ((delta = to - _rl_last_v_pos) > 0)
{
for (i = 0; i < delta; i++)
putc ('\n', rl_outstream);
tputs (term_cr, 1, _rl_output_character_function);
_rl_last_c_pos = 0;
}
else
{ /* delta < 0 */
if (term_up && *term_up)
for (i = 0; i < -delta; i++)
tputs (term_up, 1, _rl_output_character_function);
}
#endif /* !__GO32__ */
_rl_last_v_pos = to; /* Now TO is here */
}
/* Physically print C on rl_outstream. This is for functions which know
how to optimize the display. */
rl_show_char (c)
int c;
{
if (META_CHAR (c) && _rl_convert_meta_chars_to_ascii)
{
fprintf (rl_outstream, "M-");
c = UNMETA (c);
}
#if defined (DISPLAY_TABS)
if (c < 32 && c != '\t')
#else
if (c < 32)
#endif /* !DISPLAY_TABS */
{
c += 64;
}
putc (c, rl_outstream);
fflush (rl_outstream);
}
int
rl_character_len (c, pos)
register int c, pos;
{
if (META_CHAR (c))
return (_rl_convert_meta_chars_to_ascii ? 4 : 1);
if (c == '\t')
{
#if defined (DISPLAY_TABS)
return (((pos | (int)7) + 1) - pos);
#else
return (2);
#endif /* !DISPLAY_TABS */
}
if (isprint (c))
return (1);
else
return (2);
}
/* How to print things in the "echo-area". The prompt is treated as a
mini-modeline. */
#if defined (HAVE_VARARGS_H)
rl_message (va_alist)
va_dcl
{
char *format;
va_list args;
va_start (args);
format = va_arg (args, char *);
vsprintf (msg_buf, format, args);
va_end (args);
rl_display_prompt = msg_buf;
rl_redisplay ();
}
#else /* !HAVE_VARARGS_H */
rl_message (format, arg1, arg2)
char *format;
{
sprintf (msg_buf, format, arg1, arg2);
rl_display_prompt = msg_buf;
rl_redisplay ();
}
#endif /* !HAVE_VARARGS_H */
/* How to clear things from the "echo-area". */
rl_clear_message ()
{
rl_display_prompt = rl_prompt;
rl_redisplay ();
}
rl_reset_line_state ()
{
rl_on_new_line ();
rl_display_prompt = rl_prompt ? rl_prompt : "";
forced_display = 1;
}
/* Quick redisplay hack when erasing characters at the end of the line. */
void
_rl_erase_at_end_of_line (l)
int l;
{
register int i;
backspace (l);
for (i = 0; i < l; i++)
putc (' ', rl_outstream);
backspace (l);
for (i = 0; i < l; i++)
visible_line[--_rl_last_c_pos] = '\0';
rl_display_fixed++;
}
/* Clear to the end of the line. COUNT is the minimum
number of character spaces to clear, */
static void
clear_to_eol (count)
int count;
{
#ifndef __GO32__
if (term_clreol)
{
tputs (term_clreol, 1, _rl_output_character_function);
}
else
#endif /* !__GO32__ */
{
register int i;
/* Do one more character space. */
count++;
for (i = 0; i < count; i++)
putc (' ', rl_outstream);
backspace (count);
}
}
/* Insert COUNT characters from STRING to the output stream. */
static void
insert_some_chars (string, count)
char *string;
int count;
{
#ifdef __GO32__
int row, col, width;
char *row_start;
ScreenGetCursor (&row, &col);
width = ScreenCols ();
row_start = ScreenPrimary + (row * width);
memcpy (row_start + col + count, row_start + col, width - col - count);
/* Place the text on the screen. */
_rl_output_some_chars (string, count);
#else /* __GO32__ */
/* 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, _rl_output_character_function);
_rl_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, _rl_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, _rl_output_character_function);
}
/* Print the text. */
_rl_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, _rl_output_character_function);
}
#endif /* __GO32__ */
}
/* Delete COUNT characters from the display line. */
static void
delete_chars (count)
int count;
{
#if defined (__GO32__)
int row, col, width;
char *row_start;
ScreenGetCursor (&row, &col);
width = ScreenCols ();
row_start = ScreenPrimary + (row * width);
memcpy (row_start + col, row_start + col + count, width - col - count);
memset (row_start + width - count, 0, count * 2);
#else /* !__GO32__ */
if (count > screenwidth)
return;
if (term_DC && *term_DC)
{
char *tgoto (), *buffer;
buffer = tgoto (term_DC, 0, count);
tputs (buffer, 1, _rl_output_character_function);
}
else
{
if (term_dc && *term_dc)
while (count--)
tputs (term_dc, 1, _rl_output_character_function);
}
#endif /* !__GO32__ */
}

378
readline/isearch.c Normal file
View File

@ -0,0 +1,378 @@
/* **************************************************************** */
/* */
/* I-Search and Searching */
/* */
/* **************************************************************** */
/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
This file contains the Readline Library (the Library), a set of
routines for providing Emacs style line input to programs that ask
for it.
The Library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
The Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#if defined (__GNUC__)
# define alloca __builtin_alloca
#else
# if defined (sparc) || defined (HAVE_ALLOCA_H)
# include <alloca.h>
# endif
#endif
#include "readline.h"
#include "history.h"
extern Keymap _rl_keymap;
extern HIST_ENTRY *saved_line_for_history;
extern int rl_line_buffer_len;
extern int rl_point, rl_end;
extern char *rl_prompt, *rl_line_buffer;
/* Remove these declarations when we have a complete libgnu.a. */
extern char *xmalloc (), *xrealloc ();
static void rl_search_history ();
/* Search backwards through the history looking for a string which is typed
interactively. Start with the current line. */
rl_reverse_search_history (sign, key)
int sign;
int key;
{
rl_search_history (-sign, key);
}
/* Search forwards through the history looking for a string which is typed
interactively. Start with the current line. */
rl_forward_search_history (sign, key)
int sign;
int key;
{
rl_search_history (sign, key);
}
/* Display the current state of the search in the echo-area.
SEARCH_STRING contains the string that is being searched for,
DIRECTION is zero for forward, or 1 for reverse,
WHERE is the history list number of the current line. If it is
-1, then this line is the starting one. */
static void
rl_display_search (search_string, reverse_p, where)
char *search_string;
int reverse_p, where;
{
char *message = (char *)NULL;
message =
(char *)xmalloc (1 + (search_string ? strlen (search_string) : 0) + 30);
*message = '\0';
#if defined (NOTDEF)
if (where != -1)
sprintf (message, "[%d]", where + history_base);
#endif /* NOTDEF */
strcat (message, "(");
if (reverse_p)
strcat (message, "reverse-");
strcat (message, "i-search)`");
if (search_string)
strcat (message, search_string);
strcat (message, "': ");
rl_message ("%s", message, 0);
free (message);
rl_redisplay ();
}
/* Search through the history looking for an interactively typed string.
This is analogous to i-search. We start the search in the current line.
DIRECTION is which direction to search; >= 0 means forward, < 0 means
backwards. */
static void
rl_search_history (direction, invoking_key)
int direction;
int invoking_key;
{
/* The string that the user types in to search for. */
char *search_string;
/* The current length of SEARCH_STRING. */
int search_string_index;
/* The amount of space that SEARCH_STRING has allocated to it. */
int search_string_size;
/* The list of lines to search through. */
char **lines;
/* The length of LINES. */
int hlen;
/* Where we get LINES from. */
HIST_ENTRY **hlist = history_list ();
register int i = 0;
int orig_point = rl_point;
int orig_line = where_history ();
int last_found_line = orig_line;
int c, done = 0;
/* The line currently being searched. */
char *sline;
/* Offset in that line. */
int index;
/* Non-zero if we are doing a reverse search. */
int reverse = (direction < 0);
/* Create an arrary of pointers to the lines that we want to search. */
maybe_replace_line ();
if (hlist)
for (i = 0; hlist[i]; i++);
/* Allocate space for this many lines, +1 for the current input line,
and remember those lines. */
lines = (char **)alloca ((1 + (hlen = i)) * sizeof (char *));
for (i = 0; i < hlen; i++)
lines[i] = hlist[i]->line;
if (saved_line_for_history)
lines[i] = saved_line_for_history->line;
else
/* So I have to type it in this way instead. */
{
char *alloced_line;
/* Keep that MIPS alloca () happy. */
alloced_line = (char *)alloca (1 + strlen (rl_line_buffer));
lines[i] = alloced_line;
strcpy (lines[i], &rl_line_buffer[0]);
}
hlen++;
/* The line where we start the search. */
i = orig_line;
/* Initialize search parameters. */
search_string = (char *)xmalloc (search_string_size = 128);
*search_string = '\0';
search_string_index = 0;
/* Normalize DIRECTION into 1 or -1. */
if (direction >= 0)
direction = 1;
else
direction = -1;
rl_display_search (search_string, reverse, -1);
sline = rl_line_buffer;
index = rl_point;
while (!done)
{
c = rl_read_key ();
/* Hack C to Do What I Mean. */
{
Function *f = (Function *)NULL;
if (_rl_keymap[c].type == ISFUNC)
{
f = _rl_keymap[c].function;
if (f == rl_reverse_search_history)
c = reverse ? -1 : -2;
else if (f == rl_forward_search_history)
c = !reverse ? -1 : -2;
}
}
switch (c)
{
case ESC:
done = 1;
continue;
/* case invoking_key: */
case -1:
goto search_again;
/* switch directions */
case -2:
direction = -direction;
reverse = (direction < 0);
goto do_search;
case CTRL ('G'):
strcpy (rl_line_buffer, lines[orig_line]);
rl_point = orig_point;
rl_end = strlen (rl_line_buffer);
rl_clear_message ();
return;
default:
if (c < 32 || c > 126)
{
rl_execute_next (c);
done = 1;
continue;
}
else
{
if (search_string_index + 2 >= search_string_size)
search_string = (char *)xrealloc
(search_string, (search_string_size += 128));
search_string[search_string_index++] = c;
search_string[search_string_index] = '\0';
goto do_search;
search_again:
if (!search_string_index)
continue;
else
{
if (reverse)
--index;
else
if (index != strlen (sline))
++index;
else
ding ();
}
do_search:
while (1)
{
if (reverse)
{
while (index >= 0)
if (strncmp
(search_string, sline + index, search_string_index)
== 0)
goto string_found;
else
index--;
}
else
{
register int limit =
(strlen (sline) - search_string_index) + 1;
while (index < limit)
{
if (strncmp (search_string,
sline + index,
search_string_index) == 0)
goto string_found;
index++;
}
}
next_line:
i += direction;
/* At limit for direction? */
if ((reverse && i < 0) ||
(!reverse && i == hlen))
goto search_failed;
sline = lines[i];
if (reverse)
index = strlen (sline);
else
index = 0;
/* If the search string is longer than the current
line, no match. */
if (search_string_index > (int)strlen (sline))
goto next_line;
/* Start actually searching. */
if (reverse)
index -= search_string_index;
}
search_failed:
/* We cannot find the search string. Ding the bell. */
ding ();
i = last_found_line;
break;
string_found:
/* We have found the search string. Just display it. But don't
actually move there in the history list until the user accepts
the location. */
{
int line_len;
line_len = strlen (lines[i]);
if (line_len >= rl_line_buffer_len)
rl_extend_line_buffer (line_len);
strcpy (rl_line_buffer, lines[i]);
rl_point = index;
rl_end = line_len;
last_found_line = i;
rl_display_search
(search_string, reverse, (i == orig_line) ? -1 : i);
}
}
}
continue;
}
/* The searching is over. The user may have found the string that she
was looking for, or else she may have exited a failing search. If
INDEX is -1, then that shows that the string searched for was not
found. We use this to determine where to place rl_point. */
{
int now = last_found_line;
/* First put back the original state. */
strcpy (rl_line_buffer, lines[orig_line]);
/* Free the search string. */
free (search_string);
if (now < orig_line)
rl_get_previous_history (orig_line - now);
else
rl_get_next_history (now - orig_line);
/* If the index of the "matched" string is less than zero, then the
final search string was never matched, so put point somewhere
reasonable. */
if (index < 0)
index = strlen (rl_line_buffer);
rl_point = index;
rl_clear_message ();
}
}

View File

@ -1,5 +1,25 @@
/* keymaps.h -- Manipulation of readline keymaps. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _KEYMAPS_H_
#define _KEYMAPS_H_
@ -20,12 +40,17 @@ typedef struct _keymap_entry {
Function *function;
} KEYMAP_ENTRY;
/* This must be large enough to hold bindings for all of the characters
in a desired character set (e.g, 128 for ASCII, 256 for ISO Latin-x,
and so on). */
#define KEYMAP_SIZE 256
/* I wanted to make the above structure contain a union of:
union { Function *function; struct _keymap_entry *keymap; } value;
but this made it impossible for me to create a static array.
Maybe I need C lessons. */
typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[128];
typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
typedef KEYMAP_ENTRY *Keymap;
/* The values that TYPE can have in a keymap entry. */
@ -48,6 +73,14 @@ Keymap rl_copy_keymap ();
the Meta digits bound to produce numeric arguments. */
Keymap rl_make_keymap ();
/* Return the keymap corresponding to a given name. Names look like
`emacs' or `emacs-meta' or `vi-insert'. */
Keymap rl_get_keymap_by_name ();
/* Return the current keymap. */
Keymap rl_get_keymap ();
/* Set the current keymap to MAP. */
void rl_set_keymap ();
#endif /* _KEYMAPS_H_ */

115
readline/parens.c Normal file
View File

@ -0,0 +1,115 @@
/* parens.c -- Implemenation of matching parenthesis feature. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include "readline.h"
/* Non-zero means try to blink the matching open parenthesis when the
close parenthesis is inserted. */
#if defined (FD_SET)
int rl_blink_matching_paren = 1;
#else /* !FD_SET */
int rl_blink_matching_paren = 0;
#endif /* !FD_SET */
static int find_matching_open ();
rl_insert_close (count, invoking_key)
int count, invoking_key;
{
extern int rl_explicit_arg;
if (rl_explicit_arg || !rl_blink_matching_paren)
rl_insert (count, invoking_key);
else
{
#if defined (FD_SET)
int orig_point, match_point, ready;
struct timeval timer;
fd_set readfds;
rl_insert (1, invoking_key);
rl_redisplay ();
match_point =
find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
/* Emacs might message or ring the bell here, but I don't. */
if (match_point < 0)
return;
FD_ZERO (&readfds);
FD_SET (fileno (rl_instream), &readfds);
timer.tv_sec = 1;
timer.tv_usec = 500;
orig_point = rl_point;
rl_point = match_point;
rl_redisplay ();
ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
rl_point = orig_point;
#else /* !FD_SET */
rl_insert (count, invoking_key);
#endif /* !FD_SET */
}
}
static int
find_matching_open (string, from, closer)
char *string;
int from, closer;
{
register int i;
int opener, level, delimiter;
switch (closer)
{
case ']': opener = '['; break;
case '}': opener = '{'; break;
case ')': opener = '('; break;
default:
return (-1);
}
level = 1; /* The closer passed in counts as 1. */
delimiter = 0; /* Delimited state unknown. */
for (i = from; i > -1; i--)
{
if (delimiter && (string[i] == delimiter))
delimiter = 0;
else if ((string[i] == '\'') || (string[i] == '"'))
delimiter = rl_line_buffer[i];
else if (!delimiter && (string[i] == closer))
level++;
else if (!delimiter && (string[i] == opener))
level--;
if (!level)
break;
}
return (i);
}

File diff suppressed because it is too large Load Diff

250
readline/rldefs.h Normal file
View File

@ -0,0 +1,250 @@
/* rldefs.h -- an attempt to isolate some of the system-specific defines
for readline. This should be included after any files that define
system-specific constants like _POSIX_VERSION or USG. */
/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
This file contains the Readline Library (the Library), a set of
routines for providing Emacs style line input to programs that ask
for it.
The Library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
The Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (_RLDEFS_H)
#define _RLDEFS_H
#if defined (__GNUC__)
# undef alloca
# define alloca __builtin_alloca
#else
# if defined (sparc) || defined (HAVE_ALLOCA_H)
# include <alloca.h>
# endif
#endif
#define NEW_TTY_DRIVER
#define HAVE_BSD_SIGNALS
/* #define USE_XON_XOFF */
#ifdef __MSDOS__
#undef NEW_TTY_DRIVER
#undef HAVE_BSD_SIGNALS
#endif
#if defined (__linux__)
# include <termcap.h>
#endif /* __linux__ */
/* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */
#if defined (USG) && !defined (hpux)
# undef HAVE_BSD_SIGNALS
#endif
/* System V machines use termio. */
#if !defined (_POSIX_VERSION)
# if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || defined (DGUX)
# undef NEW_TTY_DRIVER
# define TERMIO_TTY_DRIVER
# include <termio.h>
# if !defined (TCOON)
# define TCOON 1
# endif
# endif /* USG || hpux || Xenix || sgi || DUGX */
#endif /* !_POSIX_VERSION */
/* Posix systems use termios and the Posix signal functions. */
#if defined (_POSIX_VERSION)
# if !defined (TERMIOS_MISSING)
# undef NEW_TTY_DRIVER
# define TERMIOS_TTY_DRIVER
# include <termios.h>
# endif /* !TERMIOS_MISSING */
# define HAVE_POSIX_SIGNALS
# if !defined (O_NDELAY)
# define O_NDELAY O_NONBLOCK /* Posix-style non-blocking i/o */
# endif /* O_NDELAY */
#endif /* _POSIX_VERSION */
/* System V.3 machines have the old 4.1 BSD `reliable' signal interface. */
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
# if defined (USGr3)
# if !defined (HAVE_USG_SIGHOLD)
# define HAVE_USG_SIGHOLD
# endif /* !HAVE_USG_SIGHOLD */
# endif /* USGr3 */
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
/* Other (BSD) machines use sgtty. */
#if defined (NEW_TTY_DRIVER)
# include <sgtty.h>
#endif
/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and
it is not already defined. It is used both to determine if a
special character is disabled and to disable certain special
characters. Posix systems should set to 0, USG systems to -1. */
#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)
# if defined (_POSIX_VERSION)
# define _POSIX_VDISABLE 0
# else /* !_POSIX_VERSION */
# define _POSIX_VDISABLE -1
# endif /* !_POSIX_VERSION */
#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
#if 1
# define D_NAMLEN(d) strlen ((d)->d_name)
#else /* !1 */
#if !defined (SHELL) && (defined (_POSIX_VERSION) || defined (USGr3))
# if !defined (HAVE_DIRENT_H)
# define HAVE_DIRENT_H
# endif /* !HAVE_DIRENT_H */
#endif /* !SHELL && (_POSIX_VERSION || USGr3) */
#if defined (HAVE_DIRENT_H)
# include <dirent.h>
# if !defined (direct)
# define direct dirent
# endif /* !direct */
# define D_NAMLEN(d) strlen ((d)->d_name)
#else /* !HAVE_DIRENT_H */
# define D_NAMLEN(d) ((d)->d_namlen)
# if defined (USG)
# if defined (Xenix)
# include <sys/ndir.h>
# else /* !Xenix (but USG...) */
# include "ndir.h"
# endif /* !Xenix */
# else /* !USG */
# include <sys/dir.h>
# endif /* !USG */
#endif /* !HAVE_DIRENT_H */
#endif /* !1 */
#if defined (USG) && defined (TIOCGWINSZ) && !defined (Linux)
# include <sys/stream.h>
# if defined (HAVE_SYS_PTEM_H)
# include <sys/ptem.h>
# endif /* HAVE_SYS_PTEM_H */
# if defined (HAVE_SYS_PTE_H)
# include <sys/pte.h>
# endif /* HAVE_SYS_PTE_H */
#endif /* USG && TIOCGWINSZ && !Linux */
/* Posix macro to check file in statbuf for directory-ness.
This requires that <sys/stat.h> be included before this test. */
#if defined (S_IFDIR) && !defined (S_ISDIR)
#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
#endif
/* Decide which flavor of the header file describing the C library
string functions to include and include it. */
#if defined (USG) || defined (NeXT)
# if !defined (HAVE_STRING_H)
# define HAVE_STRING_H
# endif /* !HAVE_STRING_H */
#endif /* USG || NeXT */
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if !defined (strchr) && !defined (__STDC__)
extern char *strchr (), *strrchr ();
#endif /* !strchr && !__STDC__ */
#if defined (HAVE_VARARGS_H)
# include <varargs.h>
#endif /* HAVE_VARARGS_H */
/* This definition is needed by readline.c, rltty.c, and signals.c. */
/* If on, then readline handles signals in a way that doesn't screw. */
#define HANDLE_SIGNALS
#if !defined (emacs_mode)
# define no_mode -1
# define vi_mode 0
# define emacs_mode 1
#endif
/* Define some macros for dealing with assorted signalling disciplines.
These macros provide a way to use signal blocking and disabling
without smothering your code in a pile of #ifdef's.
SIGNALS_UNBLOCK; Stop blocking all signals.
{
SIGNALS_DECLARE_SAVED (name); Declare a variable to save the
signal blocking state.
...
SIGNALS_BLOCK (SIGSTOP, name); Block a signal, and save the previous
state for restoration later.
...
SIGNALS_RESTORE (name); Restore previous signals.
}
*/
#ifdef HAVE_POSIX_SIGNALS
/* POSIX signals */
#define SIGNALS_UNBLOCK \
do { sigset_t set; \
sigemptyset (&set); \
sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL); \
} while (0)
#define SIGNALS_DECLARE_SAVED(name) sigset_t name
#define SIGNALS_BLOCK(SIG, saved) \
do { sigset_t set; \
sigemptyset (&set); \
sigaddset (&set, SIG); \
sigprocmask (SIG_BLOCK, &set, &saved); \
} while (0)
#define SIGNALS_RESTORE(saved) \
sigprocmask (SIG_SETMASK, &saved, (sigset_t *)NULL)
#else /* HAVE_POSIX_SIGNALS */
#ifdef HAVE_BSD_SIGNALS
/* BSD signals */
#define SIGNALS_UNBLOCK sigsetmask (0)
#define SIGNALS_DECLARE_SAVED(name) int name
#define SIGNALS_BLOCK(SIG, saved) saved = sigblock (sigmask (SIG))
#define SIGNALS_RESTORE(saved) sigsetmask (saved)
#else /* HAVE_BSD_SIGNALS */
/* None of the Above */
#define SIGNALS_UNBLOCK /* nothing */
#define SIGNALS_DECLARE_SAVED(name) /* nothing */
#define SIGNALS_BLOCK(SIG, saved) /* nothing */
#define SIGNALS_RESTORE(saved) /* nothing */
#endif /* HAVE_BSD_SIGNALS */
#endif /* HAVE_POSIX_SIGNALS */
/* End of signal handling definitions. */
#endif /* !_RLDEFS_H */

271
readline/search.c Normal file
View File

@ -0,0 +1,271 @@
/* search.c - code for non-incremental searching in emacs and vi modes. */
/* Copyright (C) 1992 Free Software Foundation, Inc.
This file is part of the Readline Library (the Library), a set of
routines for providing Emacs style line input to programs that ask
for it.
The Library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
The Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#if defined (__GNUC__)
# define alloca __builtin_alloca
#else
# if defined (sparc) || defined (HAVE_ALLOCA_H)
# include <alloca.h>
# endif
#endif
#include "readline.h"
#include "history.h"
extern char *xmalloc (), *xrealloc ();
/* Variables imported from readline.c */
extern int rl_point, rl_end, rl_line_buffer_len;
extern Keymap _rl_keymap;
extern char *rl_prompt;
extern char *rl_line_buffer;
extern HIST_ENTRY *saved_line_for_history;
static char *noninc_search_string = (char *) NULL;
static int noninc_history_pos = 0;
/* Search the history list for STRING starting at absolute history position
POS. If STRING begins with `^', the search must match STRING at the
beginning of a history line, otherwise a full substring match is performed
for STRING. DIR < 0 means to search backwards through the history list,
DIR >= 0 means to search forward. */
static int
noninc_search_from_pos (string, pos, dir)
char *string;
int pos, dir;
{
int ret, old;
old = where_history ();
history_set_pos (pos);
if (*string == '^')
ret = history_search_prefix (string + 1, dir);
else
ret = history_search (string, dir);
if (ret != -1)
ret = where_history ();
history_set_pos (old);
return (ret);
}
/* Search for a line in the history containing STRING. If DIR is < 0, the
search is backwards through previous entries, else through subsequent
entries. */
static void
noninc_dosearch (string, dir)
char *string;
int dir;
{
int oldpos, pos;
HIST_ENTRY *entry;
if (string == 0 || *string == 0 || noninc_history_pos < 0)
{
ding ();
return;
}
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
if (pos == -1)
{
/* Search failed, current history position unchanged. */
maybe_unsave_line ();
rl_clear_message ();
rl_point = 0;
ding ();
return;
}
noninc_history_pos = pos;
oldpos = where_history ();
history_set_pos (noninc_history_pos);
entry = current_history ();
history_set_pos (oldpos);
{
int line_len;
line_len = strlen (entry->line);
if (line_len >= rl_line_buffer_len)
rl_extend_line_buffer (line_len);
strcpy (rl_line_buffer, entry->line);
}
rl_undo_list = (UNDO_LIST *)entry->data;
rl_end = strlen (rl_line_buffer);
rl_point = 0;
rl_clear_message ();
if (saved_line_for_history)
free_history_entry (saved_line_for_history);
saved_line_for_history = (HIST_ENTRY *)NULL;
}
/* Search non-interactively through the history list. DIR < 0 means to
search backwards through the history of previous commands; otherwise
the search is for commands subsequent to the current position in the
history list. PCHAR is the character to use for prompting when reading
the search string; if not specified (0), it defaults to `:'. */
static void
noninc_search (dir, pchar)
int dir;
int pchar;
{
int saved_point, c, pmtlen;
char *p;
maybe_save_line ();
saved_point = rl_point;
/* Use the line buffer to read the search string. */
rl_line_buffer[0] = 0;
rl_end = rl_point = 0;
pmtlen = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
p = (char *)alloca (2 + pmtlen);
if (pmtlen)
strcpy (p, rl_prompt);
p[pmtlen] = pchar ? pchar : ':';
p[pmtlen + 1] = '\0';
rl_message (p, 0, 0);
/* Read the search string. */
while (c = rl_read_key ())
{
switch (c)
{
case CTRL('H'):
case RUBOUT:
if (rl_point == 0)
{
maybe_unsave_line ();
rl_clear_message ();
rl_point = saved_point;
return;
}
/* FALLTHROUGH */
case CTRL('W'):
case CTRL('U'):
rl_dispatch (c, _rl_keymap);
break;
case RETURN:
case NEWLINE:
goto dosearch;
/* NOTREACHED */
break;
case CTRL('C'):
case CTRL('G'):
maybe_unsave_line ();
rl_clear_message ();
rl_point = saved_point;
ding ();
return;
default:
rl_insert (1, c);
break;
}
rl_redisplay ();
}
dosearch:
/* If rl_point == 0, we want to re-use the previous search string and
start from the saved history position. If there's no previous search
string, punt. */
if (rl_point == 0)
{
if (!noninc_search_string)
{
ding ();
return;
}
}
else
{
/* We want to start the search from the current history position. */
noninc_history_pos = where_history ();
if (noninc_search_string)
free (noninc_search_string);
noninc_search_string = savestring (rl_line_buffer);
}
noninc_dosearch (noninc_search_string, dir);
}
/* Search forward through the history list for a string. If the vi-mode
code calls this, KEY will be `?'. */
rl_noninc_forward_search (count, key)
int count, key;
{
if (key == '?')
noninc_search (1, '?');
else
noninc_search (1, 0);
}
/* Reverse search the history list for a string. If the vi-mode code
calls this, KEY will be `/'. */
rl_noninc_reverse_search (count, key)
int count, key;
{
if (key == '/')
noninc_search (-1, '/');
else
noninc_search (-1, 0);
}
/* Search forward through the history list for the last string searched
for. If there is no saved search string, abort. */
rl_noninc_forward_search_again (count, key)
int count, key;
{
if (!noninc_search_string)
{
ding ();
return (-1);
}
noninc_dosearch (noninc_search_string, 1);
}
/* Reverse search in the history list for the last string searched
for. If there is no saved search string, abort. */
rl_noninc_reverse_search_again (count, key)
int count, key;
{
if (!noninc_search_string)
{
ding ();
return (-1);
}
noninc_dosearch (noninc_search_string, -1);
}

396
readline/tilde.c Normal file
View File

@ -0,0 +1,396 @@
/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
This file is part of GNU Readline, a library for reading lines
of text with interactive input and history editing.
Readline is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any
later version.
Readline is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if defined (__GNUC__)
# undef alloca
# define alloca __builtin_alloca
#else /* !__GNUC__ */
# if defined (_AIX)
#pragma alloca
# else /* !_AIX */
# if defined (HAVE_ALLOCA_H)
# include <alloca.h>
# endif /* HAVE_ALLOCA_H */
# endif /* !AIX */
#endif /* !__GNUC__ */
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <tilde/tilde.h>
#include <pwd.h>
#if !defined (sgi) && !defined (isc386)
extern struct passwd *getpwnam (), *getpwuid ();
#endif /* !sgi */
#if !defined (savestring)
extern char *xmalloc ();
# ifndef strcpy
extern char *strcpy ();
# endif
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
#endif /* !savestring */
#if !defined (NULL)
# if defined (__STDC__)
# define NULL ((void *) 0)
# else
# define NULL 0x0
# endif /* !__STDC__ */
#endif /* !NULL */
#if defined (TEST) || defined (STATIC_MALLOC)
static char *xmalloc (), *xrealloc ();
#else
extern char *xmalloc (), *xrealloc ();
#endif /* TEST || STATIC_MALLOC */
/* The default value of tilde_additional_prefixes. This is set to
whitespace preceding a tilde so that simple programs which do not
perform any word separation get desired behaviour. */
static char *default_prefixes[] =
{ " ~", "\t~", (char *)NULL };
/* The default value of tilde_additional_suffixes. This is set to
whitespace or newline so that simple programs which do not
perform any word separation get desired behaviour. */
static char *default_suffixes[] =
{ " ", "\n", (char *)NULL };
/* 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 *tilde_expansion_failure_hook = (Function *)NULL;
/* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */
char **tilde_additional_prefixes = default_prefixes;
/* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */
char **tilde_additional_suffixes = default_suffixes;
/* Find the start of a tilde expansion in STRING, and return the index of
the tilde which starts the expansion. Place the length of the text
which identified this tilde starter in LEN, excluding the tilde itself. */
static int
tilde_find_prefix (string, len)
char *string;
int *len;
{
register int i, j, string_len;
register char **prefixes = tilde_additional_prefixes;
string_len = strlen (string);
*len = 0;
if (!*string || *string == '~')
return (0);
if (prefixes)
{
for (i = 0; i < string_len; i++)
{
for (j = 0; prefixes[j]; j++)
{
if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0)
{
*len = strlen (prefixes[j]) - 1;
return (i + *len);
}
}
}
}
return (string_len);
}
/* Find the end of a tilde expansion in STRING, and return the index of
the character which ends the tilde definition. */
static int
tilde_find_suffix (string)
char *string;
{
register int i, j, string_len;
register char **suffixes = tilde_additional_suffixes;
string_len = strlen (string);
for (i = 0; i < string_len; i++)
{
if (string[i] == '/' || !string[i])
break;
for (j = 0; suffixes && suffixes[j]; j++)
{
if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
return (i);
}
}
return (i);
}
/* Return a new string which is the result of tilde expanding STRING. */
char *
tilde_expand (string)
char *string;
{
char *result, *tilde_expand_word ();
int result_size, result_index;
result_size = result_index = 0;
result = (char *)NULL;
/* Scan through STRING expanding tildes as we come to them. */
while (1)
{
register int start, end;
char *tilde_word, *expansion;
int len;
/* Make START point to the tilde which starts the expansion. */
start = tilde_find_prefix (string, &len);
/* Copy the skipped text into the result. */
if ((result_index + start + 1) > result_size)
result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
strncpy (result + result_index, string, start);
result_index += start;
/* Advance STRING to the starting tilde. */
string += start;
/* Make END be the index of one after the last character of the
username. */
end = tilde_find_suffix (string);
/* If both START and END are zero, we are all done. */
if (!start && !end)
break;
/* Expand the entire tilde word, and copy it into RESULT. */
tilde_word = (char *)xmalloc (1 + end);
strncpy (tilde_word, string, end);
tilde_word[end] = '\0';
string += end;
expansion = tilde_expand_word (tilde_word);
free (tilde_word);
len = strlen (expansion);
if ((result_index + len + 1) > result_size)
result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
strcpy (result + result_index, expansion);
result_index += len;
free (expansion);
}
result[result_index] = '\0';
return (result);
}
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
char *
tilde_expand_word (filename)
char *filename;
{
char *dirname;
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");
/* If there is no HOME variable, look up the directory in
the password database. */
if (!temp_home)
{
struct passwd *entry;
entry = getpwuid (getuid ());
if (entry)
temp_home = entry->pw_dir;
}
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 *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 (tilde_expansion_failure_hook)
{
char *expansion;
expansion =
(char *)(*tilde_expansion_failure_hook) (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);
}
endpwent ();
}
}
return (dirname);
}
#if defined (TEST)
#undef NULL
#include <stdio.h>
main (argc, argv)
int argc;
char **argv;
{
char *result, line[512];
int done = 0;
while (!done)
{
printf ("~expand: ");
fflush (stdout);
if (!gets (line))
strcpy (line, "done");
if ((strcmp (line, "done") == 0) ||
(strcmp (line, "quit") == 0) ||
(strcmp (line, "exit") == 0))
{
done = 1;
break;
}
result = tilde_expand (line);
printf (" --> %s\n", result);
free (result);
}
exit (0);
}
static void memory_error_and_abort ();
static char *
xmalloc (bytes)
int bytes;
{
char *temp = (char *)malloc (bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static char *
xrealloc (pointer, bytes)
char *pointer;
int bytes;
{
char *temp;
if (!pointer)
temp = (char *)malloc (bytes);
else
temp = (char *)realloc (pointer, bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static void
memory_error_and_abort ()
{
fprintf (stderr, "readline: Out of virtual memory!\n");
abort ();
}
/*
* Local variables:
* compile-command: "gcc -g -DTEST -o tilde tilde.c"
* end:
*/
#endif /* TEST */

33
readline/tilde.h Normal file
View File

@ -0,0 +1,33 @@
/* tilde.h: Externally available variables and function in libtilde.a. */
/* Function pointers can be declared as (Function *)foo. */
#if !defined (__FUNCTION_DEF)
# define __FUNCTION_DEF
typedef int Function ();
typedef void VFunction ();
typedef char *CPFunction ();
typedef char **CPPFunction ();
#endif /* _FUNCTION_DEF */
/* 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. */
extern Function *tilde_expansion_failure_hook;
/* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */
extern char **tilde_additional_prefixes;
/* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */
extern char **tilde_additional_suffixes;
/* Return a new string which is the result of tilde expanding STRING. */
extern char *tilde_expand ();
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
extern char *tilde_expand_word ();

76
readline/xmalloc.c Normal file
View File

@ -0,0 +1,76 @@
/* xmalloc.c -- safe versions of malloc and realloc */
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of GNU Readline, a library for reading lines
of text with interactive input and history editing.
Readline is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any
later version.
Readline is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if defined (ALREADY_HAVE_XMALLOC)
#else
#include <stdio.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#endif /* HAVE_STDLIB_H */
static void memory_error_and_abort ();
/* **************************************************************** */
/* */
/* Memory Allocation and Deallocation. */
/* */
/* **************************************************************** */
/* Return a pointer to free()able block of memory large enough
to hold BYTES number of bytes. If the memory cannot be allocated,
print an error message and abort. */
char *
xmalloc (bytes)
int bytes;
{
char *temp = (char *)malloc (bytes);
if (!temp)
memory_error_and_abort ("xmalloc");
return (temp);
}
char *
xrealloc (pointer, bytes)
char *pointer;
int bytes;
{
char *temp;
if (!pointer)
temp = (char *)malloc (bytes);
else
temp = (char *)realloc (pointer, bytes);
if (!temp)
memory_error_and_abort ("xrealloc");
return (temp);
}
static void
memory_error_and_abort (fname)
char *fname;
{
fprintf (stderr, "%s: Out of virtual memory!\n", fname);
abort ();
}
#endif /* !ALREADY_HAVE_XMALLOC */