forked from Imagelibrary/binutils-gdb
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:
@@ -28,28 +28,40 @@ Things-to-keep:
|
|||||||
COPYING
|
COPYING
|
||||||
ChangeLog
|
ChangeLog
|
||||||
Makefile.in
|
Makefile.in
|
||||||
configure.bat
|
bind.c
|
||||||
chardefs.h
|
chardefs.h
|
||||||
|
complete.c
|
||||||
config
|
config
|
||||||
|
configure.bat
|
||||||
configure.in
|
configure.in
|
||||||
|
display.c
|
||||||
doc
|
doc
|
||||||
emacs_keymap.c
|
emacs_keymap.c
|
||||||
examples
|
examples
|
||||||
funmap.c
|
funmap.c
|
||||||
history.c
|
history.c
|
||||||
history.h
|
history.h
|
||||||
|
isearch.c
|
||||||
keymaps.c
|
keymaps.c
|
||||||
keymaps.h
|
keymaps.h
|
||||||
|
parens.c
|
||||||
readline.c
|
readline.c
|
||||||
readline.h
|
readline.h
|
||||||
|
rldefs.h
|
||||||
|
rltty.c
|
||||||
|
search.c
|
||||||
|
signals.c
|
||||||
sysdep-aix.h
|
sysdep-aix.h
|
||||||
sysdep-irix.h
|
sysdep-irix.h
|
||||||
sysdep-norm.h
|
sysdep-norm.h
|
||||||
sysdep-obsd.h
|
sysdep-obsd.h
|
||||||
sysdep-sco.h
|
sysdep-sco.h
|
||||||
sysdep-sysv4.h
|
sysdep-sysv4.h
|
||||||
|
tilde.c
|
||||||
|
tilde.h
|
||||||
vi_keymap.c
|
vi_keymap.c
|
||||||
vi_mode.c
|
vi_mode.c
|
||||||
|
xmalloc.c
|
||||||
|
|
||||||
Things-to-lose:
|
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)
|
Sat Dec 11 16:29:17 1993 Steve Chamberlain (sac@thepub.cygnus.com)
|
||||||
|
|
||||||
* readline.c (rl_getc): If GO32, trim high bit from getkey,
|
* readline.c (rl_getc): If GO32, trim high bit from getkey,
|
||||||
|
|||||||
@@ -81,10 +81,22 @@ CP = cp
|
|||||||
|
|
||||||
LOCAL_INCLUDES = -I$(srcdir)/../
|
LOCAL_INCLUDES = -I$(srcdir)/../
|
||||||
|
|
||||||
CSOURCES = readline.c history.c funmap.c keymaps.c vi_mode.c \
|
# The name of the main library target.
|
||||||
emacs_keymap.c vi_keymap.c
|
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)
|
SOURCES = $(CSOURCES) $(HSOURCES)
|
||||||
|
|
||||||
DOCUMENTATION = readline.texi inc-read.texi \
|
DOCUMENTATION = readline.texi inc-read.texi \
|
||||||
@@ -94,6 +106,17 @@ SUPPORT = COPYING Makefile $(DOCUMENTATION) ChangeLog
|
|||||||
|
|
||||||
THINGS_TO_TAR = $(SOURCES) $(SUPPORT)
|
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.
|
#### Host, target, and site specific Makefile fragments come in here.
|
||||||
###
|
###
|
||||||
|
|
||||||
@@ -106,11 +129,18 @@ all: libreadline.a
|
|||||||
|
|
||||||
check:
|
check:
|
||||||
installcheck:
|
installcheck:
|
||||||
info:
|
|
||||||
dvi:
|
|
||||||
|
|
||||||
clean-info: force
|
info dvi install-info clean-info: force
|
||||||
-rm -f *.info*
|
@$(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
|
history.info: $(srcdir)/history.texi
|
||||||
$(MAKEINFO) -o 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
|
readline.info: $(srcdir)/readline.texi $(srcdir)/inc-read.texi
|
||||||
$(MAKEINFO) -o readline.info $(srcdir)/readline.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
|
$(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
|
$(RANLIB) libreadline.a
|
||||||
|
|
||||||
readline.o: readline.h chardefs.h keymaps.h history.h readline.c vi_mode.c
|
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
|
compress -f readline.tar
|
||||||
|
|
||||||
install:
|
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
|
$(INSTALL_DATA) libreadline.a $(libdir)/libreadline.a
|
||||||
$(RANLIB) $(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)/readline.h $(includedir)/readline/readline.h
|
||||||
$(INSTALL_DATA) $(srcdir)/keymaps.h $(includedir)/readline/keymaps.h
|
$(INSTALL_DATA) $(srcdir)/keymaps.h $(includedir)/readline/keymaps.h
|
||||||
$(INSTALL_DATA) $(srcdir)/chardefs.h $(includedir)/readline/chardefs.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:
|
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)/readline.h $(includedir)/readline/readline.h
|
||||||
$(INSTALL_FILE) $(srcdir)/keymaps.h $(includedir)/readline/keymaps.h
|
$(INSTALL_FILE) $(srcdir)/keymaps.h $(includedir)/readline/keymaps.h
|
||||||
$(INSTALL_FILE) $(srcdir)/chardefs.h $(includedir)/readline/chardefs.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. */
|
/* chardefs.h -- Character definitions for readline. */
|
||||||
#ifndef _CHARDEFS_
|
#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
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef whitespace
|
#ifndef whitespace
|
||||||
@@ -14,11 +27,13 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some character stuff. */
|
/* Some character stuff. */
|
||||||
#define control_character_threshold 0x020 /* smaller than this is control */
|
#define control_character_threshold 0x020 /* Smaller than this is control. */
|
||||||
#define meta_character_threshold 0x07f /* larger than this is Meta. */
|
#define meta_character_threshold 0x07f /* Larger than this is Meta. */
|
||||||
#define control_character_bit 0x40 /* 0x000000, must be off. */
|
#define control_character_bit 0x40 /* 0x000000, must be off. */
|
||||||
#define meta_character_bit 0x080 /* x0000000, must be on. */
|
#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 CTRL(c) ((c) & (~control_character_bit))
|
||||||
#define META(c) ((c) | meta_character_bit)
|
#define META(c) ((c) | meta_character_bit)
|
||||||
|
|
||||||
@@ -38,13 +53,41 @@
|
|||||||
#define CTRL_P(c) ((c) < control_character_threshold)
|
#define CTRL_P(c) ((c) < control_character_threshold)
|
||||||
#define META_P(c) ((c) > meta_character_threshold)
|
#define META_P(c) ((c) > meta_character_threshold)
|
||||||
|
|
||||||
|
#ifndef NEWLINE
|
||||||
#define NEWLINE '\n'
|
#define NEWLINE '\n'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RETURN
|
||||||
#define RETURN CTRL('M')
|
#define RETURN CTRL('M')
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RUBOUT
|
||||||
#define RUBOUT 0x07f
|
#define RUBOUT 0x07f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TAB
|
||||||
#define TAB '\t'
|
#define TAB '\t'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ABORT_CHAR
|
||||||
|
#undef ABORT_CHAR
|
||||||
|
#endif
|
||||||
#define ABORT_CHAR CTRL('G')
|
#define ABORT_CHAR CTRL('G')
|
||||||
|
|
||||||
|
#ifdef PAGE
|
||||||
|
#undef PAGE
|
||||||
|
#endif
|
||||||
#define PAGE CTRL('L')
|
#define PAGE CTRL('L')
|
||||||
|
|
||||||
|
#ifdef SPACE
|
||||||
|
#undef SPACE
|
||||||
|
#endif
|
||||||
#define SPACE 0x020
|
#define SPACE 0x020
|
||||||
|
|
||||||
|
#ifdef ESC
|
||||||
|
#undef ESC
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ESC CTRL('[')
|
#define ESC CTRL('[')
|
||||||
|
|
||||||
#endif /* _CHARDEFS_ */
|
#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. */
|
/* 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_
|
#ifndef _KEYMAPS_H_
|
||||||
#define _KEYMAPS_H_
|
#define _KEYMAPS_H_
|
||||||
|
|
||||||
@@ -20,12 +40,17 @@ typedef struct _keymap_entry {
|
|||||||
Function *function;
|
Function *function;
|
||||||
} KEYMAP_ENTRY;
|
} 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:
|
/* I wanted to make the above structure contain a union of:
|
||||||
union { Function *function; struct _keymap_entry *keymap; } value;
|
union { Function *function; struct _keymap_entry *keymap; } value;
|
||||||
but this made it impossible for me to create a static array.
|
but this made it impossible for me to create a static array.
|
||||||
Maybe I need C lessons. */
|
Maybe I need C lessons. */
|
||||||
|
|
||||||
typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[128];
|
typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
|
||||||
typedef KEYMAP_ENTRY *Keymap;
|
typedef KEYMAP_ENTRY *Keymap;
|
||||||
|
|
||||||
/* The values that TYPE can have in a keymap entry. */
|
/* 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. */
|
the Meta digits bound to produce numeric arguments. */
|
||||||
Keymap rl_make_keymap ();
|
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_ */
|
#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 */
|
||||||
Reference in New Issue
Block a user