mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-25 05:00:01 +00:00
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:
parent
8b564df836
commit
5e98bbab17
@ -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:
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
1396
readline/bind.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
1205
readline/complete.c
Normal file
File diff suppressed because it is too large
Load Diff
801
readline/display.c
Normal file
801
readline/display.c
Normal 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
378
readline/isearch.c
Normal 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 ();
|
||||
}
|
||||
}
|
@ -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
115
readline/parens.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
4509
readline/readline.c
4509
readline/readline.c
File diff suppressed because it is too large
Load Diff
250
readline/rldefs.h
Normal file
250
readline/rldefs.h
Normal 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
271
readline/search.c
Normal 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
396
readline/tilde.c
Normal 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
33
readline/tilde.h
Normal 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
76
readline/xmalloc.c
Normal 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 */
|
Loading…
Reference in New Issue
Block a user