Readline 5.1 import for HEAD.

This commit is contained in:
Daniel Jacobowitz 2006-05-05 18:26:14 +00:00
parent 7f8411279d
commit 5bdf862214
87 changed files with 9021 additions and 8722 deletions

View File

@ -1,3 +1,8 @@
2006-05-05 Daniel Jacobowitz <dan@codesourcery.com>
* Makefile.in (GDB_DOC_SOURCE_INCLUDES): Update for readline 5.1.
* gdb.texinfo: Likewise.
2006-05-05 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.texinfo (Remote Configuration): Remove "set remotedebug"

View File

@ -101,7 +101,7 @@ GDB_DOC_SOURCE_INCLUDES = \
$(srcdir)/fdl.texi \
$(srcdir)/gpl.texi \
$(srcdir)/agentexpr.texi \
$(READLINE_DIR)/rluser.texinfo \
$(READLINE_DIR)/rluser.texi \
$(READLINE_DIR)/inc-hist.texinfo
GDB_DOC_BUILD_INCLUDES = \
gdb-cfg.texi \

View File

@ -21667,7 +21667,7 @@ things without first using the debugger to find the facts.
@c inc-hist.texinfo
@c Use -I with makeinfo to point to the appropriate directory,
@c environment var TEXINPUTS with TeX.
@include rluser.texinfo
@include rluser.texi
@include inc-hist.texinfo

View File

@ -697,3 +697,224 @@ doc/Makefile.in
- new maybe-clean target that removes the generated documentation if
the build directory differs from the source directory
- distclean target now depends on maybe-clean
7/17
----
[readline-4.3 released]
7/18
----
shlib/Makefile.in
- fix bad dependency: text.so: terminal.c, make it depend on text.c
8/7
---
support/shlib-install
- break `linux' out into its own stanza: it seems that linux
distributions are all moving to the following scheme:
libreadline.so.4.3 installed version
libreadline.so.4 -> libreadline.so.4.3 symlink
libreadline.so -> libreadline.so.4 symlink
10/29
-----
support/shlib-install
- change INSTALL_LINK[12] to use `&&' instead of `;' so it only
tries the link if the cd succeeds; put ${echo} in there, too
- use $LN instead of `ln -s' so it works on machines without symlinks
- change special linux stanza to use cd before ln also
- change to use $INSTALL_LINK1 and $INSTALL_LINK2 appropriately
instead of explicit commands in various stanzas
2/1
---
config.h.in
- add HAVE_MBRTOWC and HAVE_MBRLEN
- add NO_MULTIBYTE_SUPPORT for new configure argument
- add STDC_HEADERS
configure.in
- new argument --enable-multibyte (enabled by default), allows
multibyte support to be turned off even on systems that support it
- add check for ansi stdc headers with call to AC_HEADER_STDC
2/3
---
configure.in
- add call to BASH_FUNC_CTYPE_NONASCII
config.h.in
- add CTYPE_NON_ASCII
2/20
----
doc/manvers.texinfo
- renamed to version.texi to match other GNU software
- UPDATE-MONTH variable is now `UPDATED-MONTH'
doc/{hist,rlman,rluserman}.texinfo
- include version.texi
doc/{rltech,rluser,hstech,hsuser}.texi
- changed the suffix from `texinfo' to `texi'
doc/Makefile.in
- made appropriate changes for {{rl,hs}tech,{rl,hs}user}.texi
doc/{rlman,rluserman}.texinfo
- changed the suffix from `texinfo' to `texi'
doc/hist.texinfo
- renamed to history.texi to be more consistent
6/11
----
shlib/Makefile.in
- have configure substitute value of `@LDFLAGS@' into the assignment
to SHLIB_XLDFLAGS
6/16
----
configure.in
- readline and history libraries are now at version 5.0
8/18
----
support/shlib-install
- support for FreeBSD-gnu (from Robert Millan)
12/4
----
Makefile.in
- add variables for localedir and the PACKAGE_* variables, auto-set
by configure
12/9
----
Makefile.in
- use mkinstalldirs instead of mkdirs
4/22
----
Makefile.in
- separate doc install/uninstall out into two new targets:
install-doc and uninstall-doc
- make install-doc and uninstall-doc prerequisites of appropriate
install and uninstall targets
examples/rl-fgets.c
- new example from Harold Levy that wraps fgets replacement functions
that call readline in a shared library that can be interposed with
LD_PRELOAD
7/27
----
[readline-5.0 released]
11/15
-----
examples/rlfe/{ChangeLog,Makefile.in,README,config.h.in,configure,configure.in,extern.h,os.h,pty.c,rlfe.c,screen.h}
- new version of rlfe, rlfe-0.4, from Per Bothner; now a standalone
application
11/16
-----
shlib/Makefile.in
- substitute TERMCAP_LIB in from configure
configure.in
- if SHLIB_LIBS doesn't include a termcap library (curses, ncurses,
termcap, termlib), append the value of $TERMCAP_LIB to it
11/30
-----
configure.in
- take out change from 11/16; it doesn't work for some systems (e.g.,
SunOS 4.x and Solaris 2.6)
- add support for --enable-purify configure argument
- pass TERMCAP_LIB in environment when calling shobj-conf
examples/Makefile.in
- add support for building examples with purify
1/23/2005
---------
configure.in
- set BUILD_DIR to contain backslashes to escape any spaces in the
directory name -- this is what make will accept in targets and
prerequisites, so it's better than trying to use double quotes
2/25
----
configure.in
- change check for sys/ptem.h to include sys/stream.h if present, to
avoid the `present but cannot be compiled' messages on Solaris and
SVR4.2 (does anyone still use SVR4.2?)
5/7
---
configure.in
- add cross-compiling support from the bash configure.in, which cygwin
and mingw have apparently adopted
- add check for pwd.h, fcntl.h
- add checks for fcntl, kill system calls
- add checks for getpw{ent,nam,uid} C library functions
- pass a compile-time option through to Makefiles if cross-compiling
config.h.in
- add HAVE_PWD_H for <pwd.h>, HAVE_FCNTL_H for <fcntl.h>
- add HAVE_FCNTL, HAVE_KILL for respective system calls
- add HAVE_GETPW{ENT,NAM,UID} for passwd functions
Makefile.in,shlib/Makefile.in
- @CROSS_COMPILE@ is substituted into DEFS (equal to -DCROSS_COMPILING
if bash is being cross-compiled)
8/2
---
examples/Makefile.in
- use $(READLINE_LIB) instead of -lreadline to get around MacOS X 10.4's
preference for (incompatible) shared libraries over static libraries
in the load path
8/11
----
support/shobj-conf
- new variable: SHLIB_LIBPREF, prefix for shared library name (defaults
to `lib'
- new variable: SHLIB_DLLVERSION, used on Cygwin to set the library
version number
- new variable: SHLIB_DOT, separator character between library name and
suffix and version information (defaults to `.')
- new stanza for cygwin to generate windows-compatible dll
support/shlib-install
- add new option `-b bindir' for systems like cygwin/windows that
require it
- new stanza for cygwin that installs a dll into $bindir and an implied
link library into $libdir
configure.in
- substitute new variables from shobj-conf
shlib/Makefile.in
- substitute bindir, SHLIB_DOT, SHLIB_LIBPREF, SHLIB_DLLVERSION from
configure
- pass `-b $(bindir)' to shlib-install for install and uninstall targets
- library names now use $SHLIB_LIBPREF and $SHLIB_DOT
INSTALL,README
- document new SHLIB_DOT, SHLIB_LIBPREF, and SHLIB_DLLVERSION variables
10/4
----
[readline-5.1-beta1 frozen]
12/1
----
configure.in
- changed release status to `release'
[readline-5.1 frozen]

View File

@ -1,3 +1,312 @@
This document details the changes between this version, readline-5.1,
and the previous version, readline-5.0.
1. Changes to Readline
a. Fixed a bug that caused multiliine prompts to be wrapped and displayed
incorrectly.
b. Fixed a bug that caused ^P/^N in emacs mode to fail to display the current
line correctly.
c. Fixed a problem in computing the number of invisible characters on the first
line of a prompt whose length exceeds the screen width.
d. Fixed vi-mode searching so that failure preserves the current line rather
than the last line in the history list.
e. Fixed the vi-mode `~' command (change-case) to have the correct behavior at
end-of-line when manipulating multibyte characters.
f. Fixed the vi-mode `r' command (change-char) to have the correct behavior at
end-of-line when manipulating multibyte characters.
g. Fixed multiple bugs in the redisplay of multibyte characters: displaying
prompts longer than the screen width containing multibyte characters,
h. Fix the calculation of the number of physical characters in the prompt
string when it contains multibyte characters.
i. A non-zero value for the `rl_complete_suppress_append' variable now causes
no `/' to be appended to a directory name.
j. Fixed forward-word and backward-word to work when words contained
multibyte characters.
k. Fixed a bug in finding the delimiter of a `?' substring when performing
history expansion in a locale that supports multibyte characters.
l. Fixed a memory leak caused by not freeing the timestamp in a history entry.
m. Fixed a bug that caused "\M-x" style key bindings to not obey the setting
of the `convert-meta' variable.
n. Fixed saving and restoring primary prompt when prompting for incremental
and non-incremental searches; search prompts now display multibyte
characters correctly.
o. Fixed a bug that caused keys originally bound to self-insert but shadowed
by a multi-character key sequence to not be inserted.
p. Fixed code so rl_prep_term_function and rl_deprep_term_function aren't
dereferenced if NULL (matching the documentation).
q. Extensive changes to readline to add enough state so that commands
requiring additional characters (searches, multi-key sequences, numeric
arguments, commands requiring an additional specifier character like
vi-mode change-char, etc.) work without synchronously waiting for
additional input.
r. Lots of changes so readline builds and runs on MinGW.
s. Readline no longer tries to modify the terminal settings when running in
callback mode.
t. The Readline display code no longer sets the location of the last invisible
character in the prompt if the \[\] sequence is empty.
u. The `change-case' command now correctly changes the case of multibyte
characters.
v. Changes to the shared library construction scripts to deal with Windows
DLL naming conventions for Cygwin.
w. Fixed the redisplay code to avoid core dumps resulting from a poorly-timed
SIGWINCH.
x. Fixed the non-incremental search code in vi mode to dispose of any current
undo list when copying a line from the history into the current editing
buffer.
y. Fixed a bug that caused reversing the incremental search direction to
not work correctly.
z. Fixed the vi-mode `U' command to only undo up to the first time insert mode
was entered, as Posix specifies.
aa. Fixed a bug in the vi-mode `r' command that left the cursor in the wrong
place.
bb. Fixed a redisplay bug caused by moving the cursor vertically to a line
with invisible characters in the prompt in a multibyte locale.
cc. Fixed a bug that could cause the terminal special chars to be bound in the
wrong keymap in vi mode.
2. New Features in Readline
a. The key sequence sent by the keypad `delete' key is now automatically
bound to delete-char.
b. A negative argument to menu-complete now cycles backward through the
completion list.
c. A new bindable readline variable: bind-tty-special-chars. If non-zero,
readline will bind the terminal special characters to their readline
equivalents when it's called (on by default).
d. New bindable command: vi-rubout. Saves deleted text for possible
reinsertion, as with any vi-mode `text modification' command; `X' is bound
to this in vi command mode.
e. If the rl_completion_query_items is set to a value < 0, readline never
asks the user whether or not to view the possible completions.
f. The `C-w' binding in incremental search now understands multibyte
characters.
g. New application-callable auxiliary function, rl_variable_value, returns
a string corresponding to a readline variable's value.
h. When parsing inputrc files and variable binding commands, the parser
strips trailing whitespace from values assigned to boolean variables
before checking them.
i. A new external application-controllable variable that allows the LINES
and COLUMNS environment variables to set the window size regardless of
what the kernel returns.
-------------------------------------------------------------------------------
This document details the changes between this version, readline-5.0,
and the previous version, readline-4.3.
1. Changes to Readline
a. Fixes to avoid core dumps because of null pointer references in the
multibyte character code.
b. Fix to avoid infinite recursion caused by certain key combinations.
c. Fixed a bug that caused the vi-mode `last command' to be set incorrectly.
d. Readline no longer tries to read ahead more than one line of input, even
when more is available.
e. Fixed the code that adjusts the point to not mishandle null wide
characters.
f. Fixed a bug in the history expansion `g' modifier that caused it to skip
every other match.
g. Fixed a bug that caused the prompt to overwrite previous output when the
output doesn't contain a newline and the locale supports multibyte
characters. This same change fixes the problem of readline redisplay
slowing down dramatically as the line gets longer in multibyte locales.
h. History traversal with arrow keys in vi insertion mode causes the cursor
to be placed at the end of the new line, like in emacs mode.
i. The locale initialization code does a better job of using the right
precedence and defaulting when checking the appropriate environment
variables.
j. Fixed the history word tokenizer to handle <( and >( better when used as
part of bash.
k. The overwrite mode code received several bug fixes to improve undo.
l. Many speedups to the multibyte character redisplay code.
m. The callback character reading interface should not hang waiting to read
keyboard input.
n. Fixed a bug with redoing vi-mode `s' command.
o. The code that initializes the terminal tracks changes made to the terminal
special characters with stty(1) (or equivalent), so that these changes
are reflected in the readline bindings. New application-callable function
to make it work: rl_tty_unset_default_bindings().
p. Fixed a bug that could cause garbage to be inserted in the buffer when
changing character case in vi mode when using a multibyte locale.
q. Fixed a bug in the redisplay code that caused problems on systems
supporting multibyte characters when moving between history lines when the
new line has more glyphs but fewer bytes.
r. Undo and redo now work better after exiting vi insertion mode.
s. Make sure system calls are restarted after a SIGWINCH is received using
SA_RESTART.
t. Improvements to the code that displays possible completions when using
multibyte characters.
u. Fixed a problem when parsing nested if statements in inputrc files.
v. The completer now takes multibyte characters into account when looking for
quoted substrings on which to perform completion.
w. The history search functions now perform better bounds checking on the
history list.
x. Change to history expansion functions to treat `^' as equivalent to word
one, as the documention states.
y. Some changes to the display code to improve display and redisplay of
multibyte characters.
z. Changes to speed up the multibyte character redisplay code.
aa. Fixed a bug in the vi-mode `E' command that caused it to skip over the
last character of a word if invoked while point was on the word's
next-to-last character.
bb. Fixed a bug that could cause incorrect filename quoting when
case-insensitive completion was enabled and the word being completed
contained backslashes quoting word break characters.
cc. Fixed a bug in redisplay triggered when the prompt string contains
invisible characters.
dd. Fixed some display (and other) bugs encountered in multibyte locales
when a non-ascii character was the last character on a line.
ee. Fixed some display bugs caused by multibyte characters in prompt strings.
ff. Fixed a problem with history expansion caused by non-whitespace characters
used as history word delimiters.
gg. Fixed a problem that could cause readline to refer to freed memory when
moving between history lines while doing searches.
hh. Improvements to the code that expands and displays prompt strings
containing multibyte characters.
ii. Fixed a problem with vi-mode not correctly remembering the numeric argument
to the last `c'hange command for later use with `.'.
jj. Fixed a bug in vi-mode that caused multi-digit count arguments to work
incorrectly.
kk. Fixed a problem in vi-mode that caused the last text modification command
to not be remembered across different command lines.
ll. Fixed problems with changing characters and changing case at the end of
the line.
mm. Fixed a problem with readline saving the contents of the current line
before beginning a non-interactive search.
nn. Fixed a problem with EOF detection when using rl_event_hook.
oo. Fixed a problem with the vi mode `p' and `P' commands ignoring numeric
arguments.
2. New Features in Readline
a. History expansion has a new `a' modifier equivalent to the `g' modifier
for compatibility with the BSD csh.
b. History expansion has a new `G' modifier equivalent to the BSD csh `g'
modifier, which performs a substitution once per word.
c. All non-incremental search operations may now undo the operation of
replacing the current line with the history line.
d. The text inserted by an `a' command in vi mode can be reinserted with
`.'.
e. New bindable variable, `show-all-if-unmodified'. If set, the readline
completer will list possible completions immediately if there is more
than one completion and partial completion cannot be performed.
f. There is a new application-callable `free_history_entry()' function.
g. History list entries now contain timestamp information; the history file
functions know how to read and write timestamp information associated
with each entry.
h. Four new key binding functions have been added:
rl_bind_key_if_unbound()
rl_bind_key_if_unbound_in_map()
rl_bind_keyseq_if_unbound()
rl_bind_keyseq_if_unbound_in_map()
i. New application variable, rl_completion_quote_character, set to any
quote character readline finds before it calls the application completion
function.
j. New application variable, rl_completion_suppress_quote, settable by an
application completion function. If set to non-zero, readline does not
attempt to append a closing quote to a completed word.
k. New application variable, rl_completion_found_quote, set to a non-zero
value if readline determines that the word to be completed is quoted.
Set before readline calls any application completion function.
l. New function hook, rl_completion_word_break_hook, called when readline
needs to break a line into words when completion is attempted. Allows
the word break characters to vary based on position in the line.
m. New bindable command: unix-filename-rubout. Does the same thing as
unix-word-rubout, but adds `/' to the set of word delimiters.
n. When listing completions, directories have a `/' appended if the
`mark-directories' option has been enabled.
-------------------------------------------------------------------------------
This document details the changes between this version, readline-4.3,
and the previous version, readline-4.2a.

View File

@ -1,3 +1,7 @@
2006-04-24 Daniel Jacobowitz <dan@codesourcery.com>
Imported readline 5.1, and upstream patches 001-004.
2006-03-21 Denis Pilat <denis.pilat@st.com>
* histfile.c (read_history_range): Remove '\r' character from

View File

@ -1,7 +1,7 @@
Basic Installation
==================
These are installation instructions for Readline-4.3.
These are installation instructions for Readline-5.1.
The simplest way to compile readline is:
@ -238,6 +238,9 @@ SHLIB_XLDFLAGS Additional flags to pass to SHOBJ_LD for shared library
SHLIB_LIBS Any additional libraries that shared libraries should be
linked against when they are created.
SHLIB_LIBPREF The prefix to use when generating the filename of the shared
library. The default is `lib'; Cygwin uses `cyg'.
SHLIB_LIBSUFF The suffix to add to `libreadline' and `libhistory' when
generating the filename of the shared library. Many systems
use `so'; HP-UX uses `sl'.
@ -254,6 +257,17 @@ SHLIB_LIBVERSION The string to append to the filename to indicate the version
numbers; use `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' on those systems.
Other Unix versions use different schemes.
SHLIB_DLLVERSION The version number for shared libraries that determines API
compatibility between readline versions and the underlying
system. Used only on Cygwin. Defaults to $SHLIB_MAJOR, but
can be overridden at configuration time by defining DLLVERSION
in the environment.
SHLIB_DOT The character used to separate the name of the shared library
from the suffix and version information. The default is `.';
systems like Cygwin which don't separate version information
from the library name should set this to the empty string.
SHLIB_STATUS Set this to `supported' when you have defined the other
necessary variables. Make uses this to determine whether
or not shared library creation should be attempted. If

View File

@ -3,6 +3,7 @@
#
doc d
examples d
examples/rlfe d
support d
shlib d
COPYING f
@ -11,6 +12,7 @@ MANIFEST f
INSTALL f
CHANGELOG f
CHANGES f
NEWS f
USAGE f
aclocal.m4 f
config.h.in f
@ -74,23 +76,26 @@ histfile.c f
histsearch.c f
shlib/Makefile.in f
support/config.guess f
support/config.rpath f
support/config.sub f
support/install.sh f
support/mkdirs f
support/mkdist f
support/mkinstalldirs f
support/shobj-conf f
support/shlib-install f
support/wcwidth.c f
doc/Makefile.in f
doc/texinfo.tex f
doc/manvers.texinfo f
doc/rlman.texinfo f
doc/rltech.texinfo f
doc/rluser.texinfo f
doc/rluserman.texinfo f
doc/hist.texinfo f
doc/hstech.texinfo f
doc/hsuser.texinfo f
doc/version.texi f
doc/fdl.texi f
doc/rlman.texi f
doc/rltech.texi f
doc/rluser.texi f
doc/rluserman.texi f
doc/history.texi f
doc/hstech.texi f
doc/hsuser.texi f
doc/readline.3 f
doc/history.3 f
doc/texi2dvi f
@ -100,13 +105,25 @@ examples/excallback.c f
examples/fileman.c f
examples/manexamp.c f
examples/readlinebuf.h f
examples/rl-fgets.c f
examples/rlcat.c f
examples/rlfe.c f
examples/rltest.c f
examples/rl.c f
examples/rlptytest.c f
examples/rlversion.c f
examples/histexamp.c f
examples/Inputrc f
examples/rlfe/ChangeLog f
examples/rlfe/Makefile.in f
examples/rlfe/README f
examples/rlfe/config.h.in f
examples/rlfe/configure f
examples/rlfe/configure.in f
examples/rlfe/extern.h f
examples/rlfe/os.h f
examples/rlfe/pty.c f
examples/rlfe/rlfe.c f
examples/rlfe/screen.h f
# formatted documentation, from MANIFEST.doc
doc/readline.ps f
doc/history.ps f
@ -124,3 +141,6 @@ doc/readline.0 f
doc/history.0 f
doc/readline_3.ps f
doc/history_3.ps f
doc/history.pdf f
doc/readline.pdf f
doc/rluserman.pdf f

View File

@ -1,6 +1,6 @@
## -*- text -*- ##
# Master Makefile for the GNU readline library.
# Copyright (C) 1994, 1998 Free Software Foundation, Inc.
# Copyright (C) 1994-2004 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -18,6 +18,14 @@
RL_LIBRARY_VERSION = @LIBVERSION@
RL_LIBRARY_NAME = readline
PACKAGE = @PACKAGE_NAME@
VERSION = @PACKAGE_VERSION@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_VERSION = @PACKAGE_VERSION@
srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
@ -35,6 +43,8 @@ RM = rm -f
CP = cp
MV = mv
PURIFY = @PURIFY@
@SET_MAKE@
SHELL = @MAKE_SHELL@
@ -45,6 +55,8 @@ bindir = @bindir@
libdir = @libdir@
mandir = @mandir@
includedir = @includedir@
datadir = @datadir@
localedir = $(datadir)/locale
infodir = @infodir@
@ -61,7 +73,7 @@ CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DRL_LIBRARY_VERSION='"$(RL_LIBRARY_VERSION)"'
CPPFLAGS = @CPPFLAGS@
DEFS = @DEFS@
DEFS = @DEFS@ @CROSS_COMPILE@
LOCAL_DEFS = @LOCAL_DEFS@
TERMCAP_LIB = @TERMCAP_LIB@
@ -211,7 +223,7 @@ uninstall-headers:
maybe-uninstall-headers: uninstall-headers
## CYGNUS LOCAL
## GDB LOCAL
## Don't mess with people's installed readline's.
## This tries to install this version of readline over whatever
## version is already installed on the system (which could be a
@ -223,37 +235,41 @@ install:
#install: $(INSTALL_TARGETS)
install-static: installdirs $(STATIC_LIBS) install-headers
install-static: installdirs $(STATIC_LIBS) install-headers install-doc
-$(MV) $(DESTDIR)$(libdir)/libreadline.a $(DESTDIR)$(libdir)/libreadline.old
$(INSTALL_DATA) libreadline.a $(DESTDIR)$(libdir)/libreadline.a
-test -n "$(RANLIB)" && $(RANLIB) $(DESTDIR)$(libdir)/libreadline.a
-$(MV) $(DESTDIR)$(libdir)/libhistory.a $(DESTDIR)$(libdir)/libhistory.old
$(INSTALL_DATA) libhistory.a $(DESTDIR)$(libdir)/libhistory.a
-test -n "$(RANLIB)" && $(RANLIB) $(DESTDIR)$(libdir)/libhistory.a
installdirs: $(srcdir)/support/mkinstalldirs
-$(SHELL) $(srcdir)/support/mkinstalldirs $(DESTDIR)$(includedir) \
$(DESTDIR)$(includedir)/readline $(DESTDIR)$(libdir) \
$(DESTDIR)$(infodir) $(DESTDIR)$(man3dir)
uninstall: uninstall-headers uninstall-doc
-test -n "$(DESTDIR)$(libdir)" && cd $(DESTDIR)$(libdir) && \
${RM} libreadline.a libreadline.old libhistory.a libhistory.old $(SHARED_LIBS)
-( cd shlib; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall )
install-shared: installdirs install-headers shared install-doc
-( cd shlib ; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} install )
uninstall-shared: maybe-uninstall-headers
-( cd shlib; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall )
install-doc: installdirs
-( if test -d doc ; then \
cd doc && \
${MAKE} ${MFLAGS} infodir=$(infodir) DESTDIR=${DESTDIR} install; \
fi )
installdirs: $(srcdir)/support/mkdirs
-$(SHELL) $(srcdir)/support/mkdirs $(DESTDIR)$(includedir) \
$(DESTDIR)$(includedir)/readline $(DESTDIR)$(libdir) \
$(DESTDIR)$(infodir) $(DESTDIR)$(man3dir)
uninstall: uninstall-headers
-test -n "$(DESTDIR)$(libdir)" && cd $(DESTDIR)$(libdir) && \
${RM} libreadline.a libreadline.old libhistory.a libhistory.old $(SHARED_LIBS)
uninstall-doc:
-( if test -d doc ; then \
cd doc && \
${MAKE} ${MFLAGS} infodir=$(infodir) DESTDIR=${DESTDIR} $@; \
${MAKE} ${MFLAGS} infodir=$(infodir) DESTDIR=${DESTDIR} uninstall; \
fi )
-( cd shlib; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall )
install-shared: installdirs install-headers shared
-( cd shlib ; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} install )
uninstall-shared: maybe-uninstall-headers
-( cd shlib; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall )
TAGS: force
$(ETAGS) $(CSOURCES) $(HSOURCES)

View File

@ -1,7 +1,7 @@
Introduction
============
This is the Gnu Readline library, version 4.3.
This is the Gnu Readline library, version 5.1.
The Readline library provides a set of functions for use by applications
that allow users to edit command lines as they are typed in. Both
@ -102,6 +102,9 @@ SHLIB_XLDFLAGS Additional flags to pass to SHOBJ_LD for shared library
SHLIB_LIBS Any additional libraries that shared libraries should be
linked against when they are created.
SHLIB_LIBPREF The prefix to use when generating the filename of the shared
library. The default is `lib'; Cygwin uses `cyg'.
SHLIB_LIBSUFF The suffix to add to `libreadline' and `libhistory' when
generating the filename of the shared library. Many systems
use `so'; HP-UX uses `sl'.
@ -118,6 +121,17 @@ SHLIB_LIBVERSION The string to append to the filename to indicate the version
numbers; use `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' on those systems.
Other Unix versions use different schemes.
SHLIB_DLLVERSION The version number for shared libraries that determines API
compatibility between readline versions and the underlying
system. Used only on Cygwin. Defaults to $SHLIB_MAJOR, but
can be overridden at configuration time by defining DLLVERSION
in the environment.
SHLIB_DOT The character used to separate the name of the shared library
from the suffix and version information. The default is `.';
systems like Cygwin which don't separate version information
from the library name should set this to the empty string.
SHLIB_STATUS Set this to `supported' when you have defined the other
necessary variables. Make uses this to determine whether
or not shared library creation should be attempted.

View File

@ -1,56 +0,0 @@
/* acconfig.h
This file is in the public domain.
Descriptive text for the C preprocessor macros that
the distributed Autoconf macros can define.
No software package will use all of them; autoheader copies the ones
your configure.in uses into your configuration header file templates.
The entries are in sort -df order: alphabetical, case insensitive,
ignoring punctuation (such as underscores). Although this order
can split up related entries, it makes it easier to check whether
a given entry is in the file.
Leave the following blank line there!! Autoheader needs it. */
/* Definitions pulled in from aclocal.m4. */
#undef VOID_SIGHANDLER
#undef GWINSZ_IN_SYS_IOCTL
#undef TIOCSTAT_IN_SYS_IOCTL
#undef HAVE_GETPW_DECLS
#undef FIONREAD_IN_SYS_IOCTL
#undef HAVE_BSD_SIGNALS
#undef HAVE_LSTAT
#undef HAVE_POSIX_SIGNALS
#undef HAVE_POSIX_SIGSETJMP
#undef HAVE_USG_SIGHOLD
#undef MUST_REINSTALL_SIGHANDLERS
#undef SPEED_T_IN_SYS_TYPES
#undef STRCOLL_BROKEN
#undef STRUCT_DIRENT_HAS_D_FILENO
#undef STRUCT_DIRENT_HAS_D_INO
#undef STRUCT_WINSIZE_IN_SYS_IOCTL
#undef STRUCT_WINSIZE_IN_TERMIOS
/* Leave that blank line there!! Autoheader needs it.
If you're adding to this file, keep in mind:
The entries are in sort -df order: alphabetical, case insensitive,
ignoring punctuation (such as underscores). */

2311
readline/aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* bind.c -- key binding and startup file support for the readline library. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 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.
@ -19,8 +19,13 @@
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,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (__TANDEM)
# include <floss.h>
#endif
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
@ -72,6 +77,9 @@ static char *_rl_read_file PARAMS((char *, size_t *));
static void _rl_init_file_error PARAMS((const char *));
static int _rl_read_init_file PARAMS((const char *, int));
static int glean_key_from_name PARAMS((char *));
static int find_boolean_var PARAMS((const char *));
static char *_rl_get_string_variable_value PARAMS((const char *));
static int substring_member_of_array PARAMS((char *, const char **));
static int currently_reading_init_file;
@ -148,6 +156,34 @@ rl_bind_key_in_map (key, function, map)
return (result);
}
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
now, this is always used to attempt to bind the arrow keys, hence the
check for rl_vi_movement_mode. */
int
rl_bind_key_if_unbound_in_map (key, default_func, kmap)
int key;
rl_command_func_t *default_func;
Keymap kmap;
{
char keyseq[2];
keyseq[0] = (unsigned char)key;
keyseq[1] = '\0';
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap));
}
int
rl_bind_key_if_unbound (key, default_func)
int key;
rl_command_func_t *default_func;
{
char keyseq[2];
keyseq[0] = (unsigned char)key;
keyseq[1] = '\0';
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
}
/* Make KEY do nothing in the currently selected keymap.
Returns non-zero in case of error. */
int
@ -199,10 +235,31 @@ rl_unbind_command_in_map (command, map)
return (rl_unbind_function_in_map (func, map));
}
/* Bind the key sequence represented by the string KEYSEQ to
FUNCTION, starting in the current keymap. This makes new
keymaps as necessary. */
int
rl_bind_keyseq (keyseq, function)
const char *keyseq;
rl_command_func_t *function;
{
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap));
}
/* Bind the key sequence represented by the string KEYSEQ to
FUNCTION. This makes new keymaps as necessary. The initial
place to do bindings is in MAP. */
int
rl_bind_keyseq_in_map (keyseq, function, map)
const char *keyseq;
rl_command_func_t *function;
Keymap map;
{
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
}
/* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */
int
rl_set_key (keyseq, function, map)
const char *keyseq;
rl_command_func_t *function;
@ -211,6 +268,40 @@ rl_set_key (keyseq, function, map)
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
}
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
now, this is always used to attempt to bind the arrow keys, hence the
check for rl_vi_movement_mode. */
int
rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)
const char *keyseq;
rl_command_func_t *default_func;
Keymap kmap;
{
rl_command_func_t *func;
if (keyseq)
{
func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL);
#if defined (VI_MODE)
if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
#else
if (!func || func == rl_do_lowercase_version)
#endif
return (rl_bind_keyseq_in_map (keyseq, default_func, kmap));
else
return 1;
}
return 0;
}
int
rl_bind_keyseq_if_unbound (keyseq, default_func)
const char *keyseq;
rl_command_func_t *default_func;
{
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
}
/* Bind the key sequence represented by the string KEYSEQ to
the string of characters MACRO. This makes new keymaps as
necessary. The initial place to do bindings is in MAP. */
@ -253,7 +344,7 @@ rl_generic_bind (type, keyseq, data, map)
k.function = 0;
/* If no keys to bind to, exit right away. */
if (!keyseq || !*keyseq)
if (keyseq == 0 || *keyseq == 0)
{
if (type == ISMACR)
free (data);
@ -281,7 +372,7 @@ rl_generic_bind (type, keyseq, data, map)
if (ic < 0 || ic >= KEYMAP_SIZE)
return -1;
if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic))
if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
{
ic = UNMETA (ic);
if (map[ESC].type == ISKMAP)
@ -372,7 +463,14 @@ rl_translate_keyseq (seq, array, len)
else if (c == 'M')
{
i++;
array[l++] = ESC; /* ESC is meta-prefix */
/* XXX - should obey convert-meta setting? */
if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP)
array[l++] = ESC; /* ESC is meta-prefix */
else
{
i++;
array[l++] = META (seq[i]);
}
}
else if (c == 'C')
{
@ -912,9 +1010,15 @@ parser_else (args)
return 0;
}
#if 0
/* Check the previous (n - 1) levels of the stack to make sure that
we haven't previously turned off parsing. */
for (i = 0; i < if_stack_depth - 1; i++)
#else
/* Check the previous (n) levels of the stack to make sure that
we haven't previously turned off parsing. */
for (i = 0; i < if_stack_depth; i++)
#endif
if (if_stack[i] == 1)
return 0;
@ -1091,9 +1195,9 @@ rl_parse_and_bind (string)
/* If this is a command to set a variable, then do that. */
if (_rl_stricmp (string, "set") == 0)
{
char *var = string + i;
char *value;
char *var, *value, *e;
var = string + i;
/* Make VAR point to start of variable name. */
while (*var && whitespace (*var)) var++;
@ -1104,6 +1208,20 @@ rl_parse_and_bind (string)
*value++ = '\0';
while (*value && whitespace (*value)) value++;
/* Strip trailing whitespace from values to boolean variables. Temp
fix until I get a real quoted-string parser here. */
i = find_boolean_var (var);
if (i >= 0)
{
/* remove trailing whitespace */
e = value + strlen (value) - 1;
while (e >= value && whitespace (*e))
e--;
e++; /* skip back to whitespace or EOS */
if (*e && e >= value)
*e = '\0';
}
rl_variable_bind (var, value);
return 0;
}
@ -1124,8 +1242,9 @@ rl_parse_and_bind (string)
the quoted string delimiter, like the shell. */
if (*funname == '\'' || *funname == '"')
{
int delimiter = string[i++], passc;
int delimiter, passc;
delimiter = string[i++];
for (passc = 0; c = string[i]; i++)
{
if (passc)
@ -1161,7 +1280,7 @@ rl_parse_and_bind (string)
}
/* If this is a new-style key-binding, then do the binding with
rl_set_key (). Otherwise, let the older code deal with it. */
rl_bind_keyseq (). Otherwise, let the older code deal with it. */
if (*string == '"')
{
char *seq;
@ -1200,7 +1319,7 @@ rl_parse_and_bind (string)
rl_macro_bind (seq, &funname[1], _rl_keymap);
}
else
rl_set_key (seq, rl_named_function (funname), _rl_keymap);
rl_bind_keyseq (seq, rl_named_function (funname));
free (seq);
return 0;
@ -1261,6 +1380,7 @@ static struct {
int *value;
int flags;
} boolean_varlist [] = {
{ "bind-tty-special-chars", &_rl_bind_stty_chars, 0 },
{ "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
{ "byte-oriented", &rl_byte_oriented, 0 },
{ "completion-ignore-case", &_rl_completion_case_fold, 0 },
@ -1281,6 +1401,7 @@ static struct {
{ "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL },
{ "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
{ "show-all-if-ambiguous", &_rl_complete_show_all, 0 },
{ "show-all-if-unmodified", &_rl_complete_show_unmodified, 0 },
#if defined (VISIBLE_STATS)
{ "visible-stats", &rl_visible_stats, 0 },
#endif /* VISIBLE_STATS */
@ -1373,13 +1494,34 @@ find_string_var (name)
values result in 0 (false). */
static int
bool_to_int (value)
char *value;
const char *value;
{
return (value == 0 || *value == '\0' ||
(_rl_stricmp (value, "on") == 0) ||
(value[0] == '1' && value[1] == '\0'));
}
char *
rl_variable_value (name)
const char *name;
{
register int i;
int v;
char *ret;
/* Check for simple variables first. */
i = find_boolean_var (name);
if (i >= 0)
return (*boolean_varlist[i].value ? "on" : "off");
i = find_string_var (name);
if (i >= 0)
return (_rl_get_string_variable_value (string_varlist[i].name));
/* Unknown variable names return NULL. */
return 0;
}
int
rl_variable_bind (name, value)
const char *name, *value;
@ -1650,7 +1792,7 @@ rl_get_keymap_name_from_edit_mode ()
/* Each of the following functions produces information about the
state of keybindings and functions known to Readline. The info
is always printed to rl_outstream, and in such a way that it can
be read back in (i.e., passed to rl_parse_and_bind (). */
be read back in (i.e., passed to rl_parse_and_bind ()). */
/* Print the names of functions known to Readline. */
void
@ -2022,12 +2164,68 @@ rl_dump_macros (count, key)
return (0);
}
static char *
_rl_get_string_variable_value (name)
const char *name;
{
static char numbuf[32];
char *ret;
int n;
if (_rl_stricmp (name, "bell-style") == 0)
{
switch (_rl_bell_preference)
{
case NO_BELL:
return "none";
case VISIBLE_BELL:
return "visible";
case AUDIBLE_BELL:
default:
return "audible";
}
}
else if (_rl_stricmp (name, "comment-begin") == 0)
return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
else if (_rl_stricmp (name, "completion-query-items") == 0)
{
sprintf (numbuf, "%d", rl_completion_query_items);
return (numbuf);
}
else if (_rl_stricmp (name, "editing-mode") == 0)
return (rl_get_keymap_name_from_edit_mode ());
else if (_rl_stricmp (name, "isearch-terminators") == 0)
{
if (_rl_isearch_terminators == 0)
return 0;
ret = _rl_untranslate_macro_value (_rl_isearch_terminators);
if (ret)
{
strncpy (numbuf, ret, sizeof (numbuf) - 1);
free (ret);
numbuf[sizeof(numbuf) - 1] = '\0';
}
else
numbuf[0] = '\0';
return numbuf;
}
else if (_rl_stricmp (name, "keymap") == 0)
{
ret = rl_get_keymap_name (_rl_keymap);
if (ret == 0)
ret = rl_get_keymap_name_from_edit_mode ();
return (ret ? ret : "none");
}
else
return (0);
}
void
rl_variable_dumper (print_readably)
int print_readably;
{
int i;
const char *kname;
char *v;
for (i = 0; boolean_varlist[i].name; i++)
{
@ -2039,63 +2237,16 @@ rl_variable_dumper (print_readably)
*boolean_varlist[i].value ? "on" : "off");
}
/* bell-style */
switch (_rl_bell_preference)
for (i = 0; string_varlist[i].name; i++)
{
case NO_BELL:
kname = "none"; break;
case VISIBLE_BELL:
kname = "visible"; break;
case AUDIBLE_BELL:
default:
kname = "audible"; break;
}
if (print_readably)
fprintf (rl_outstream, "set bell-style %s\n", kname);
else
fprintf (rl_outstream, "bell-style is set to `%s'\n", kname);
/* comment-begin */
if (print_readably)
fprintf (rl_outstream, "set comment-begin %s\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
else
fprintf (rl_outstream, "comment-begin is set to `%s'\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
/* completion-query-items */
if (print_readably)
fprintf (rl_outstream, "set completion-query-items %d\n", rl_completion_query_items);
else
fprintf (rl_outstream, "completion-query-items is set to `%d'\n", rl_completion_query_items);
/* editing-mode */
if (print_readably)
fprintf (rl_outstream, "set editing-mode %s\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
else
fprintf (rl_outstream, "editing-mode is set to `%s'\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
/* isearch-terminators */
if (_rl_isearch_terminators)
{
char *disp;
disp = _rl_untranslate_macro_value (_rl_isearch_terminators);
v = _rl_get_string_variable_value (string_varlist[i].name);
if (v == 0) /* _rl_isearch_terminators can be NULL */
continue;
if (print_readably)
fprintf (rl_outstream, "set isearch-terminators \"%s\"\n", disp);
fprintf (rl_outstream, "set %s %s\n", string_varlist[i].name, v);
else
fprintf (rl_outstream, "isearch-terminators is set to \"%s\"\n", disp);
free (disp);
fprintf (rl_outstream, "%s is set to `%s'\n", string_varlist[i].name, v);
}
/* keymap */
kname = rl_get_keymap_name (_rl_keymap);
if (kname == 0)
kname = rl_get_keymap_name_from_edit_mode ();
if (print_readably)
fprintf (rl_outstream, "set keymap %s\n", kname ? kname : "none");
else
fprintf (rl_outstream, "keymap is set to `%s'\n", kname ? kname : "none");
}
/* Print all of the current variables and their values to
@ -2112,28 +2263,6 @@ rl_dump_variables (count, key)
return (0);
}
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
now, this is always used to attempt to bind the arrow keys, hence the
check for rl_vi_movement_mode. */
void
_rl_bind_if_unbound (keyseq, default_func)
const char *keyseq;
rl_command_func_t *default_func;
{
rl_command_func_t *func;
if (keyseq)
{
func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL);
#if defined (VI_MODE)
if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
#else
if (!func || func == rl_do_lowercase_version)
#endif
rl_set_key (keyseq, default_func, _rl_keymap);
}
}
/* Return non-zero if any members of ARRAY are a substring in STRING. */
static int
substring_member_of_array (string, array)

View File

@ -1,6 +1,6 @@
/* callback.c -- functions to use readline as an X `callback' mechanism. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 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.
@ -44,9 +44,14 @@
#include "readline.h"
#include "rlprivate.h"
/* Private data for callback registration functions. See comments in
rl_callback_read_char for more details. */
_rl_callback_func_t *_rl_callback_func = 0;
_rl_callback_generic_arg *_rl_callback_data = 0;
/* **************************************************************** */
/* */
/* Callback Readline Functions */
/* Callback Readline Functions */
/* */
/* **************************************************************** */
@ -72,7 +77,8 @@ _rl_callback_newline ()
{
in_handler = 1;
(*rl_prep_term_function) (_rl_meta_flag);
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
#if defined (HANDLE_SIGNALS)
rl_set_signals ();
@ -89,6 +95,7 @@ rl_callback_handler_install (prompt, linefunc)
rl_vcpfunc_t *linefunc;
{
rl_set_prompt (prompt);
RL_SETSTATE (RL_STATE_CALLBACK);
rl_linefunc = linefunc;
_rl_callback_newline ();
}
@ -98,7 +105,8 @@ void
rl_callback_read_char ()
{
char *line;
int eof;
int eof, jcode;
static procenv_t olevel;
if (rl_linefunc == NULL)
{
@ -106,7 +114,79 @@ rl_callback_read_char ()
abort ();
}
eof = readline_internal_char ();
memcpy ((void *)olevel, (void *)readline_top_level, sizeof (procenv_t));
jcode = setjmp (readline_top_level);
if (jcode)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
memcpy ((void *)readline_top_level, (void *)olevel, sizeof (procenv_t));
return;
}
if (RL_ISSTATE (RL_STATE_ISEARCH))
{
eof = _rl_isearch_callback (_rl_iscxt);
if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
rl_callback_read_char ();
return;
}
else if (RL_ISSTATE (RL_STATE_NSEARCH))
{
eof = _rl_nsearch_callback (_rl_nscxt);
return;
}
else if (RL_ISSTATE (RL_STATE_NUMERICARG))
{
eof = _rl_arg_callback (_rl_argcxt);
if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
rl_callback_read_char ();
/* XXX - this should handle _rl_last_command_was_kill better */
else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
_rl_internal_char_cleanup ();
return;
}
else if (RL_ISSTATE (RL_STATE_MULTIKEY))
{
eof = _rl_dispatch_callback (_rl_kscxt); /* For now */
while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED))
eof = _rl_dispatch_callback (_rl_kscxt);
if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0)
{
_rl_internal_char_cleanup ();
_rl_want_redisplay = 1;
}
}
else if (_rl_callback_func)
{
/* This allows functions that simply need to read an additional character
(like quoted-insert) to register a function to be called when input is
available. _rl_callback_data is simply a pointer to a struct that has
the argument count originally passed to the registering function and
space for any additional parameters. */
eof = (*_rl_callback_func) (_rl_callback_data);
/* If the function `deregisters' itself, make sure the data is cleaned
up. */
if (_rl_callback_func == 0)
{
if (_rl_callback_data)
{
_rl_callback_data_dispose (_rl_callback_data);
_rl_callback_data = 0;
}
_rl_internal_char_cleanup ();
}
}
else
eof = readline_internal_char ();
if (rl_done == 0 && _rl_want_redisplay)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
}
/* We loop in case some function has pushed input back with rl_execute_next. */
for (;;)
@ -115,7 +195,8 @@ rl_callback_read_char ()
{
line = readline_internal_teardown (eof);
(*rl_deprep_term_function) ();
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
rl_clear_signals ();
#endif
@ -131,10 +212,10 @@ rl_callback_read_char ()
if (in_handler == 0 && rl_linefunc)
_rl_callback_newline ();
}
if (rl_pending_input)
if (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT))
eof = readline_internal_char ();
else
break;
break;
}
}
@ -143,14 +224,37 @@ void
rl_callback_handler_remove ()
{
rl_linefunc = NULL;
RL_UNSETSTATE (RL_STATE_CALLBACK);
if (in_handler)
{
in_handler = 0;
(*rl_deprep_term_function) ();
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
rl_clear_signals ();
#endif
}
}
_rl_callback_generic_arg *
_rl_callback_data_alloc (count)
int count;
{
_rl_callback_generic_arg *arg;
arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg));
arg->count = count;
arg->i1 = arg->i2 = 0;
return arg;
}
void _rl_callback_data_dispose (arg)
_rl_callback_generic_arg *arg;
{
if (arg)
free (arg);
}
#endif

View File

@ -77,11 +77,17 @@
# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif
#define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
#if defined (CTYPE_NON_ASCII)
# define NON_NEGATIVE(c) 1
#else
# define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
#endif
/* Some systems define these; we want our definitions. */
#undef ISPRINT
/* Beware: these only work with single-byte ASCII characters. */
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))

View File

@ -1,6 +1,6 @@
/* complete.c -- filename completion for readline. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 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.
@ -28,7 +28,7 @@
#include <sys/types.h>
#include <fcntl.h>
#if defined (HAVE_SYS_FILE_H)
#include <sys/file.h>
# include <sys/file.h>
#endif
#if defined (HAVE_UNISTD_H)
@ -48,7 +48,7 @@
extern int errno;
#endif /* !errno */
#ifdef HAVE_PWD_H
#if defined (HAVE_PWD_H)
#include <pwd.h>
#endif
@ -81,10 +81,9 @@ typedef int QSFUNC ();
/* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is
defined. */
#if defined(HAVE_GETPWENT) && \
(!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE))
#if defined (HAVE_GETPWENT) && (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE))
extern struct passwd *getpwent PARAMS((void));
#endif /* defiend (HAVE_GETPWENT) && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */
#endif /* HAVE_GETPWENT && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */
/* If non-zero, then this is the address of a function to call when
completing a word would normally display the list of possible matches.
@ -102,12 +101,16 @@ rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)N
static int stat_char PARAMS((char *));
#endif
static int path_isdir PARAMS((const char *));
static char *rl_quote_filename PARAMS((char *, int, char *));
static void set_completion_defaults PARAMS((int));
static int get_y_or_n PARAMS((int));
static int _rl_internal_pager PARAMS((int));
static char *printable_part PARAMS((char *));
static int fnwidth PARAMS((const char *));
static int fnprint PARAMS((const char *));
static int print_filename PARAMS((char *, char *));
static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
@ -133,6 +136,10 @@ static char *make_quoted_replacement PARAMS((char *, int, char *));
/* If non-zero, non-unique completions always show the list of matches. */
int _rl_complete_show_all = 0;
/* If non-zero, non-unique completions show the list of matches, unless it
is not possible to do partial completion and modify the line. */
int _rl_complete_show_unmodified = 0;
/* If non-zero, completed directory names have a slash appended. */
int _rl_complete_mark_directories = 1;
@ -201,7 +208,8 @@ int rl_completion_type = 0;
/* Up to this many items will be displayed in response to a
possible-completions call. After that, we ask the user if
she is sure she wants to see them all. */
she is sure she wants to see them all. A negative value means
don't ask. */
int rl_completion_query_items = 100;
int _rl_page_completions = 1;
@ -217,7 +225,12 @@ const char *rl_basic_quote_characters = "\"'";
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
const char *rl_completer_word_break_characters = (const char *)NULL;
/*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL;
/* Hook function to allow an application to set the completion word
break characters before readline breaks up the line. Allows
position-dependent word break characters. */
rl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
@ -285,6 +298,19 @@ int rl_completion_suppress_append = 0;
default is a space. */
int rl_completion_append_character = ' ';
/* If non-zero, the completion functions don't append any closing quote.
This is set to 0 by rl_complete_internal and may be changed by an
application-specific completion function. */
int rl_completion_suppress_quote = 0;
/* Set to any quote character readline thinks it finds before any application
completion function is called. */
int rl_completion_quote_character;
/* Set to a non-zero value if readline found quoting anywhere in the word to
be completed; set before any application completion function is called. */
int rl_completion_found_quote;
/* If non-zero, a slash will be appended to completed filenames that are
symbolic links to directory names, subject to the value of the
mark-directories variable (which is user-settable). This exists so
@ -323,6 +349,8 @@ rl_complete (ignore, invoking_key)
return (rl_complete_internal ('?'));
else if (_rl_complete_show_all)
return (rl_complete_internal ('!'));
else if (_rl_complete_show_unmodified)
return (rl_complete_internal ('@'));
else
return (rl_complete_internal (TAB));
}
@ -355,6 +383,8 @@ rl_completion_mode (cfunc)
return '?';
else if (_rl_complete_show_all)
return '!';
else if (_rl_complete_show_unmodified)
return '@';
else
return TAB;
}
@ -375,7 +405,7 @@ set_completion_defaults (what_to_do)
rl_filename_completion_desired = 0;
rl_filename_quoting_desired = 1;
rl_completion_type = what_to_do;
rl_completion_suppress_append = 0;
rl_completion_suppress_append = rl_completion_suppress_quote = 0;
/* The completion entry function may optionally change this. */
rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
@ -426,6 +456,15 @@ _rl_internal_pager (lines)
return 0;
}
static int
path_isdir (filename)
const char *filename;
{
struct stat finfo;
return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode));
}
#if defined (VISIBLE_STATS)
/* Return the character which best describes FILENAME.
`@' for symbolic links
@ -523,53 +562,149 @@ printable_part (pathname)
return ++temp;
}
/* Compute width of STRING when displayed on screen by print_filename */
static int
fnwidth (string)
const char *string;
{
int width, pos;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
int left, w;
size_t clen;
wchar_t wc;
left = strlen (string) + 1;
memset (&ps, 0, sizeof (mbstate_t));
#endif
width = pos = 0;
while (string[pos])
{
if (CTRL_CHAR (*string) || *string == RUBOUT)
{
width += 2;
pos++;
}
else
{
#if defined (HANDLE_MULTIBYTE)
clen = mbrtowc (&wc, string + pos, left - pos, &ps);
if (MB_INVALIDCH (clen))
{
width++;
pos++;
memset (&ps, 0, sizeof (mbstate_t));
}
else if (MB_NULLWCH (clen))
break;
else
{
pos += clen;
w = wcwidth (wc);
width += (w >= 0) ? w : 1;
}
#else
width++;
pos++;
#endif
}
}
return width;
}
static int
fnprint (to_print)
const char *to_print;
{
int printed_len;
const char *s;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
const char *end;
size_t tlen;
int width, w;
wchar_t wc;
end = to_print + strlen (to_print) + 1;
memset (&ps, 0, sizeof (mbstate_t));
#endif
printed_len = 0;
s = to_print;
while (*s)
{
if (CTRL_CHAR (*s))
{
putc ('^', rl_outstream);
putc (UNCTRL (*s), rl_outstream);
printed_len += 2;
s++;
#if defined (HANDLE_MULTIBYTE)
memset (&ps, 0, sizeof (mbstate_t));
#endif
}
else if (*s == RUBOUT)
{
putc ('^', rl_outstream);
putc ('?', rl_outstream);
printed_len += 2;
s++;
#if defined (HANDLE_MULTIBYTE)
memset (&ps, 0, sizeof (mbstate_t));
#endif
}
else
{
#if defined (HANDLE_MULTIBYTE)
tlen = mbrtowc (&wc, s, end - s, &ps);
if (MB_INVALIDCH (tlen))
{
tlen = 1;
width = 1;
memset (&ps, 0, sizeof (mbstate_t));
}
else if (MB_NULLWCH (tlen))
break;
else
{
w = wcwidth (wc);
width = (w >= 0) ? w : 1;
}
fwrite (s, 1, tlen, rl_outstream);
s += tlen;
printed_len += width;
#else
putc (*s, rl_outstream);
s++;
printed_len++;
#endif
}
}
return printed_len;
}
/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we
are using it, check for and output a single character for `special'
filenames. Return the number of characters we output. */
#define PUTX(c) \
do { \
if (CTRL_CHAR (c)) \
{ \
putc ('^', rl_outstream); \
putc (UNCTRL (c), rl_outstream); \
printed_len += 2; \
} \
else if (c == RUBOUT) \
{ \
putc ('^', rl_outstream); \
putc ('?', rl_outstream); \
printed_len += 2; \
} \
else \
{ \
putc (c, rl_outstream); \
printed_len++; \
} \
} while (0)
static int
print_filename (to_print, full_pathname)
char *to_print, *full_pathname;
{
int printed_len = 0;
#if !defined (VISIBLE_STATS)
char *s;
int printed_len, extension_char, slen, tlen;
char *s, c, *new_full_pathname, *dn;
for (s = to_print; *s; s++)
{
PUTX (*s);
}
#else
char *s, c, *new_full_pathname;
int extension_char, slen, tlen;
extension_char = 0;
printed_len = fnprint (to_print);
for (s = to_print; *s; s++)
{
PUTX (*s);
}
if (rl_filename_completion_desired && rl_visible_stats)
#if defined (VISIBLE_STATS)
if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories))
#else
if (rl_filename_completion_desired && _rl_complete_mark_directories)
#endif
{
/* If to_print != full_pathname, to_print is the basename of the
path passed. In this case, we try to expand the directory
@ -585,7 +720,17 @@ print_filename (to_print, full_pathname)
files in the root directory. If we pass a null string to the
bash directory completion hook, for example, it will expand it
to the current directory. We just want the `/'. */
s = tilde_expand (full_pathname && *full_pathname ? full_pathname : "/");
if (full_pathname == 0 || *full_pathname == 0)
dn = "/";
else if (full_pathname[0] != '/')
dn = full_pathname;
else if (full_pathname[1] == 0)
dn = "//"; /* restore trailing slash to `//' */
else if (full_pathname[1] == '/' && full_pathname[2] == 0)
dn = "/"; /* don't turn /// into // */
else
dn = full_pathname;
s = tilde_expand (dn);
if (rl_directory_completion_hook)
(*rl_directory_completion_hook) (&s);
@ -593,10 +738,20 @@ print_filename (to_print, full_pathname)
tlen = strlen (to_print);
new_full_pathname = (char *)xmalloc (slen + tlen + 2);
strcpy (new_full_pathname, s);
if (s[slen - 1] == '/')
slen--;
else
new_full_pathname[slen] = '/';
new_full_pathname[slen] = '/';
strcpy (new_full_pathname + slen + 1, to_print);
extension_char = stat_char (new_full_pathname);
#if defined (VISIBLE_STATS)
if (rl_visible_stats)
extension_char = stat_char (new_full_pathname);
else
#endif
if (path_isdir (new_full_pathname))
extension_char = '/';
free (new_full_pathname);
to_print[-1] = c;
@ -604,7 +759,13 @@ print_filename (to_print, full_pathname)
else
{
s = tilde_expand (full_pathname);
extension_char = stat_char (s);
#if defined (VISIBLE_STATS)
if (rl_visible_stats)
extension_char = stat_char (s);
else
#endif
if (path_isdir (s))
extension_char = '/';
}
free (s);
@ -614,7 +775,7 @@ print_filename (to_print, full_pathname)
printed_len++;
}
}
#endif /* VISIBLE_STATS */
return printed_len;
}
@ -654,19 +815,25 @@ _rl_find_completion_word (fp, dp)
int *fp, *dp;
{
int scan, end, found_quote, delimiter, pass_next, isbrk;
char quote_char;
char quote_char, *brkchars;
end = rl_point;
found_quote = delimiter = 0;
quote_char = '\0';
brkchars = 0;
if (rl_completion_word_break_hook)
brkchars = (*rl_completion_word_break_hook) ();
if (brkchars == 0)
brkchars = rl_completer_word_break_characters;
if (rl_completer_quote_characters)
{
/* We have a list of characters which can be used in pairs to
quote substrings for the completer. Try to find the start
of an unclosed quoted substring. */
/* FOUND_QUOTE is set so we know what kind of quotes we found. */
for (scan = pass_next = 0; scan < end; scan++)
for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY))
{
if (pass_next)
{
@ -716,15 +883,11 @@ _rl_find_completion_word (fp, dp)
/* We didn't find an unclosed quoted substring upon which to do
completion, so use the word break characters to find the
substring on which to complete. */
#if defined (HANDLE_MULTIBYTE)
while (rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_ANY))
#else
while (--rl_point)
#endif
while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))
{
scan = rl_line_buffer[rl_point];
if (strchr (rl_completer_word_break_characters, scan) == 0)
if (strchr (brkchars, scan) == 0)
continue;
/* Call the application-specific function to tell us whether
@ -752,9 +915,9 @@ _rl_find_completion_word (fp, dp)
if (rl_char_is_quoted_p)
isbrk = (found_quote == 0 ||
(*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
strchr (rl_completer_word_break_characters, scan) != 0;
strchr (brkchars, scan) != 0;
else
isbrk = strchr (rl_completer_word_break_characters, scan) != 0;
isbrk = strchr (brkchars, scan) != 0;
if (isbrk)
{
@ -789,6 +952,9 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
{
char **matches, *temp;
rl_completion_found_quote = found_quote;
rl_completion_quote_character = quote_char;
/* If the user wants to TRY to complete, but then wants to give
up and use the default completion function, they set the
variable rl_attempted_completion_function. */
@ -892,6 +1058,7 @@ compute_lcd_of_matches (match_list, matches, text)
{
register int i, c1, c2, si;
int low; /* Count of max-matched characters. */
char *dtext; /* dequoted TEXT, if needed */
#if defined (HANDLE_MULTIBYTE)
int v;
mbstate_t ps1, ps2;
@ -983,6 +1150,26 @@ compute_lcd_of_matches (match_list, matches, text)
the user typed in the face of multiple matches differing in case. */
if (_rl_completion_case_fold)
{
/* We're making an assumption here:
IF we're completing filenames AND
the application has defined a filename dequoting function AND
we found a quote character AND
the application has requested filename quoting
THEN
we assume that TEXT was dequoted before checking against
the file system and needs to be dequoted here before we
check against the list of matches
FI */
dtext = (char *)NULL;
if (rl_filename_completion_desired &&
rl_filename_dequoting_function &&
rl_completion_found_quote &&
rl_filename_quoting_desired)
{
dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
text = dtext;
}
/* sort the list to get consistent answers. */
qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
@ -1002,6 +1189,8 @@ compute_lcd_of_matches (match_list, matches, text)
else
/* otherwise, just use the text the user typed. */
strncpy (match_list[0], text, low);
FREE (dtext);
}
else
strncpy (match_list[0], match_list[1], low);
@ -1206,7 +1395,7 @@ display_matches (matches)
for (max = 0, i = 1; matches[i]; i++)
{
temp = printable_part (matches[i]);
len = strlen (temp);
len = fnwidth (temp);
if (len > max)
max = len;
@ -1223,7 +1412,7 @@ display_matches (matches)
/* If there are many items, then ask the user if she really wants to
see them all. */
if (len >= rl_completion_query_items)
if (rl_completion_query_items > 0 && len >= rl_completion_query_items)
{
rl_crlf ();
fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
@ -1341,7 +1530,8 @@ append_to_match (text, delimiter, quote_char, nontrivial_match)
struct stat finfo;
temp_string_index = 0;
if (quote_char && rl_point && rl_line_buffer[rl_point - 1] != quote_char)
if (quote_char && rl_point && rl_completion_suppress_quote == 0 &&
rl_line_buffer[rl_point - 1] != quote_char)
temp_string[temp_string_index++] = quote_char;
if (delimiter)
@ -1359,7 +1549,7 @@ append_to_match (text, delimiter, quote_char, nontrivial_match)
: stat (filename, &finfo);
if (s == 0 && S_ISDIR (finfo.st_mode))
{
if (_rl_complete_mark_directories)
if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */)
{
/* This is clumsy. Avoid putting in a double slash if point
is at the end of the line and the previous character is a
@ -1452,7 +1642,9 @@ _rl_free_match_list (matches)
TAB means do standard completion.
`*' means insert all of the possible completions.
`!' means to do standard completion, and list all possible completions if
there is more than one. */
there is more than one.
`@' means to do standard completion, and list all possible completions if
there is more than one and partial completion is not possible. */
int
rl_complete_internal (what_to_do)
int what_to_do;
@ -1471,7 +1663,6 @@ rl_complete_internal (what_to_do)
our_func = rl_completion_entry_function
? rl_completion_entry_function
: rl_filename_completion_function;
/* We now look backwards for the start of a filename/variable word. */
end = rl_point;
found_quote = delimiter = 0;
@ -1519,6 +1710,7 @@ rl_complete_internal (what_to_do)
{
case TAB:
case '!':
case '@':
/* Insert the first match with proper quoting. */
if (*matches[0])
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
@ -1538,6 +1730,12 @@ rl_complete_internal (what_to_do)
display_matches (matches);
break;
}
else if (what_to_do == '@')
{
if (nontrivial_lcd == 0)
display_matches (matches);
break;
}
else if (rl_editing_mode != vi_mode)
rl_ding (); /* There are other matches remaining. */
}
@ -1665,7 +1863,7 @@ rl_username_completion_function (text, state)
setpwent ();
}
#ifdef HAVE_GETPWENT
#if defined (HAVE_GETPWENT)
while (entry = getpwent ())
{
/* Null usernames should result in all users as possible completions. */
@ -1676,7 +1874,7 @@ rl_username_completion_function (text, state)
if (entry == 0)
{
#ifdef HAVE_GETPWENT
#if defined (HAVE_GETPWENT)
endpwent ();
#endif
return ((char *)NULL);
@ -1990,9 +2188,11 @@ rl_menu_complete (count, ignore)
return (0);
}
match_list_index = (match_list_index + count) % match_list_size;
match_list_index += count;
if (match_list_index < 0)
match_list_index += match_list_size;
else
match_list_index %= match_list_size;
if (match_list_index == 0 && match_list_size > 1)
{

View File

@ -1,22 +0,0 @@
/* config.h.bot */
/* modify settings or make new ones based on what autoconf tells us. */
/* Ultrix botches type-ahead when switching from canonical to
non-canonical mode, at least through version 4.3 */
#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix)
# define TERMIOS_MISSING
#endif
#if defined (STRCOLL_BROKEN)
# undef HAVE_STRCOLL
#endif
#if defined (__STDC__) && defined (HAVE_STDARG_H)
# define PREFER_STDARG
# define USE_VARARGS
#else
# if defined (HAVE_VARARGS_H)
# define PREFER_VARARGS
# define USE_VARARGS
# endif
#endif

View File

@ -1,11 +1,17 @@
/* config.h.in. Maintained by hand. */
/* Define NO_MULTIBYTE_SUPPORT to not compile in support for multibyte
characters, even if the OS supports them. */
#undef NO_MULTIBYTE_SUPPORT
/* Define if on MINIX. */
#undef _MINIX
/* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE
#undef VOID_SIGHANDLER
/* Characteristics of the compiler. */
#undef const
@ -20,11 +26,18 @@
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
#undef STAT_MACROS_BROKEN
#undef VOID_SIGHANDLER
/* Define if you have the fcntl function. */
#undef HAVE_FCNTL
#undef HAVE_FCNTL
/* Define if you have the getpwent function. */
#undef HAVE_GETPWENT
/* Define if you have the getpwnam function. */
#undef HAVE_GETPWNAM
/* Define if you have the getpwuid function. */
#undef HAVE_GETPWUID
/* Define if you have the isascii function. */
#undef HAVE_ISASCII
@ -37,6 +50,9 @@
/* Define if you have the lstat function. */
#undef HAVE_LSTAT
/* Define if you have the mbrlen function. */
#undef HAVE_MBRLEN
/* Define if you have the mbrtowc function. */
#undef HAVE_MBRTOWC
@ -49,15 +65,6 @@
/* Define if you have the putenv function. */
#undef HAVE_PUTENV
/* Define if you have the getpwent function. */
#undef HAVE_GETPWENT
/* Define if you have the getpwnam function. */
#undef HAVE_GETPWNAM
/* Define if you have the getpwnam function. */
#undef HAVE_GETPWUID
/* Define if you have the select function. */
#undef HAVE_SELECT
@ -84,12 +91,20 @@
/* Define if you have the vsnprintf function. */
#undef HAVE_VSNPRINTF
/* Define if you have the wctomb function. */
#undef HAVE_WCTOMB
/* Define if you have the wcwidth function. */
#undef HAVE_WCWIDTH
#undef STDC_HEADERS
/* Define if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <langinfo.h> header file. */
#undef HAVE_LANGINFO_H
@ -198,6 +213,8 @@
#undef HAVE_POSIX_SIGSETJMP
#undef CTYPE_NON_ASCII
/* modify settings or make new ones based on what autoconf tells us. */
/* Ultrix botches type-ahead when switching from canonical to

1691
readline/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -4,38 +4,102 @@ dnl
dnl report bugs to chet@po.cwru.edu
dnl
dnl Process this file with autoconf to produce a configure script.
AC_REVISION([for Readline 4.3, version 2.45, from autoconf version] AC_ACVERSION)
AC_INIT(readline, 4.3, bug-readline@gnu.org)
# Copyright (C) 1987-2005 Free Software Foundation, Inc.
# This program 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 2, or (at your option)
# any later version.
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
AC_REVISION([for Readline 5.1, version 2.59])
AC_INIT(readline, 5.1-release, bug-readline@gnu.org)
dnl make sure we are using a recent autoconf version
AC_PREREQ(2.50)
AC_CONFIG_SRCDIR(readline.h)
dnl GDB LOCAL
dnl AC_CONFIG_AUX_DIR(./support)
AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/..)
AC_CONFIG_HEADERS(config.h)
dnl update the value of RL_READLINE_VERSION in readline.h when this changes
LIBVERSION=4.3
LIBVERSION=5.1
AC_CANONICAL_HOST
dnl configure defaults
opt_curses=no
opt_purify=no
dnl arguments to configure
AC_ARG_WITH(curses, AC_HELP_STRING([--with-curses], [use the curses library instead of the termcap library]), opt_curses=$withval)
AC_ARG_WITH(purify, AC_HELP_STRING([--with-purify], [configure to postprocess with purify]), opt_purify=$withval)
if test "$opt_curses" = "yes"; then
prefer_curses=yes
fi
if test "$opt_purify" = yes; then
PURIFY="purify"
else
PURIFY=
fi
dnl option parsing for optional features
opt_multibyte=yes
opt_static_libs=yes
opt_shared_libs=no
AC_ARG_ENABLE(multibyte, AC_HELP_STRING([--enable-multibyte], [enable multibyte characters if OS supports them]), opt_multibyte=$enableval)
dnl AC_ARG_ENABLE(shared, AC_HELP_STRING([--enable-shared], [build shared libraries [[default=YES]]]), opt_shared_libs=$enableval)
AC_ARG_ENABLE(static, AC_HELP_STRING([--enable-static], [build static libraries [[default=YES]]]), opt_static_libs=$enableval)
if test $opt_multibyte = no; then
AC_DEFINE(NO_MULTIBYTE_SUPPORT)
fi
dnl load up the cross-building cache file -- add more cases and cache
dnl files as necessary
dnl Note that host and target machine are the same, and different than the
dnl build machine.
if test "x$cross_compiling" = "xyes"; then
case "${host}" in
*-cygwin*)
cross_cache=${srcdir}/cross-build/cygwin.cache
;;
*-mingw*)
cross_cache=${srcdir}/cross-build/mingw.cache
;;
i[[3456]]86-*-beos*)
cross_cache=${srcdir}/cross-build/x86-beos.cache
;;
*) echo "configure: cross-compiling for $host is not supported" >&2
;;
esac
if test -n "${cross_cache}" && test -r "${cross_cache}"; then
echo "loading cross-build cache file ${cross_cache}"
. ${cross_cache}
fi
unset cross_cache
CROSS_COMPILE='-DCROSS_COMPILING'
AC_SUBST(CROSS_COMPILE)
fi
echo ""
echo "Beginning configuration for readline-$LIBVERSION for ${host_cpu}-${host_vendor}-${host_os}"
echo ""
@ -49,7 +113,8 @@ dnl AC_AIX
AC_MINIX
dnl BEGIN changes for CYGNUS cross-building for Cygwin
dnl NOTE: Some of these changes may no longer be necessary.
dnl load up the cross-building cache file -- add more cases and cache
dnl files as necessary
if test "x$cross_compiling" = "xyes"; then
@ -73,14 +138,7 @@ if test "x$cross_compiling" = "xyes"; then
unset cross_cache
fi
fi
if test "x$cross_compiling" = "xyes"; then
CROSS_COMPILING_FLAG=-DCROSS_COMPILING
else
CROSS_COMPILING_FLAG=
fi
AC_SUBST(CROSS_COMPILING_FLAG)
if test -z "$CC_FOR_BUILD"; then
if test "x$cross_compiling" = "xno"; then
CC_FOR_BUILD='$(CC)'
@ -115,19 +173,29 @@ AC_TYPE_SIGNAL
AC_TYPE_SIZE_T
AC_CHECK_TYPE(ssize_t, int)
AC_HEADER_STDC
AC_HEADER_STAT
AC_HEADER_DIRENT
AC_CHECK_FUNCS(fcntl kill lstat memmove putenv select setenv setlocale \
strcasecmp strpbrk tcgetattr vsnprintf isascii isxdigit \
getpwnam getpwent getpwuid)
AC_CHECK_FUNCS(fcntl kill lstat)
AC_CHECK_FUNCS(memmove putenv select setenv setlocale \
strcasecmp strpbrk tcgetattr vsnprintf)
AC_CHECK_FUNCS(isascii isxdigit)
AC_CHECK_FUNCS(getpwent getpwnam getpwuid)
AC_FUNC_STRCOLL
AC_CHECK_HEADERS(unistd.h stdlib.h varargs.h stdarg.h string.h strings.h \
limits.h sys/ptem.h sys/pte.h sys/stream.h sys/select.h \
termcap.h termios.h termio.h sys/file.h locale.h memory.h \
pwd.h)
AC_CHECK_HEADERS(fcntl.h unistd.h stdlib.h varargs.h stdarg.h string.h strings.h \
limits.h locale.h pwd.h memory.h termcap.h termios.h termio.h)
AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h)
AC_CHECK_HEADERS(sys/ptem.h,,,
[[
#if HAVE_SYS_STREAM_H
# include <sys/stream.h>
#endif
]])
BASH_SYS_SIGNAL_VINTAGE
BASH_SYS_REINSTALL_SIGHANDLERS
@ -135,6 +203,7 @@ BASH_SYS_REINSTALL_SIGHANDLERS
BASH_FUNC_POSIX_SETJMP
BASH_FUNC_LSTAT
BASH_FUNC_STRCOLL
BASH_FUNC_CTYPE_NONASCII
BASH_CHECK_GETPW_FUNCS
@ -179,7 +248,13 @@ esac
#
if test -f ${srcdir}/support/shobj-conf; then
AC_MSG_CHECKING(configuration for building shared libraries)
eval `${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}`
eval `TERMCAP_LIB=$TERMCAP_LIB ${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}`
# case "$SHLIB_LIBS" in
# *curses*|*termcap*|*termlib*) ;;
# *) SHLIB_LIBS="$SHLIB_LIBS $TERMCAP_LIB" ;;
# esac
AC_SUBST(SHOBJ_CC)
AC_SUBST(SHOBJ_CFLAGS)
AC_SUBST(SHOBJ_LD)
@ -189,8 +264,11 @@ if test -f ${srcdir}/support/shobj-conf; then
AC_SUBST(SHOBJ_STATUS)
AC_SUBST(SHLIB_STATUS)
AC_SUBST(SHLIB_XLDFLAGS)
AC_SUBST(SHLIB_DOT)
AC_SUBST(SHLIB_LIBPREF)
AC_SUBST(SHLIB_LIBSUFF)
AC_SUBST(SHLIB_LIBVERSION)
AC_SUBST(SHLIB_DLLVERSION)
AC_SUBST(SHLIB_LIBS)
AC_MSG_RESULT($SHLIB_STATUS)
@ -227,6 +305,12 @@ msdosdjgpp*) BUILD_DIR=`pwd.exe` ;; # to prevent //d/path/file
*) BUILD_DIR=`pwd` ;;
esac
case "$BUILD_DIR" in
*\ *) BUILD_DIR=`echo "$BUILD_DIR" | sed 's: :\\\\ :g'` ;;
*) ;;
esac
AC_SUBST(PURIFY)
AC_SUBST(BUILD_DIR)
AC_SUBST(CFLAGS)

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,7 @@
2006-04-24 Daniel Jacobowitz <dan@codesourcery.com>
Imported readline 5.1, and upstream patches 001-004.
2003-09-14 Andrew Cagney <cagney@redhat.com>
* history.0: Delete generated file.

View File

@ -1,7 +1,7 @@
# This makefile for Readline library documentation is in -*- text -*- mode.
# Emacs likes it that way.
# Copyright (C) 1996 Free Software Foundation, Inc.
# Copyright (C) 1996-2004 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -52,14 +52,18 @@ TEXI2DVI = $(srcdir)/texi2dvi
TEXI2HTML = $(srcdir)/texi2html
QUIETPS = #set this to -q to shut up dvips
PAPERSIZE = letter
PSDPI = 300 # I don't have any 600-dpi printers
PSDPI = 600
DVIPS = dvips -D ${PSDPI} $(QUIETPS) -t ${PAPERSIZE} -o $@ # tricky
RLSRC = $(srcdir)/rlman.texinfo $(srcdir)/rluser.texinfo \
$(srcdir)/rltech.texinfo $(srcdir)/manvers.texinfo \
$(srcdir)/rluserman.texinfo
HISTSRC = $(srcdir)/hist.texinfo $(srcdir)/hsuser.texinfo \
$(srcdir)/hstech.texinfo $(srcdir)/manvers.texinfo
# These tools might not be available; they're not required
DVIPDF = dvipdfm -o $@ -p ${PAPERSIZE}
PSPDF = gs -sPAPERSIZE=${PAPERSIZE} -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -sOutputFile=$@
RLSRC = $(srcdir)/rlman.texi $(srcdir)/rluser.texi \
$(srcdir)/rltech.texi $(srcdir)/version.texi \
$(srcdir)/rluserman.texi
HISTSRC = $(srcdir)/history.texi $(srcdir)/hsuser.texi \
$(srcdir)/hstech.texi $(srcdir)/version.texi
# This should be a program that converts troff to an ascii-readable format
NROFF = groff -Tascii
@ -72,39 +76,54 @@ INFOOBJ = readline.info history.info rluserman.info
PSOBJ = readline.ps history.ps rluserman.ps readline_3.ps history_3.ps
HTMLOBJ = readline.html history.html rluserman.html
TEXTOBJ = readline.0 history.0
PDFOBJ = readline.pdf history.pdf rluserman.pdf
INTERMEDIATE_OBJ = rlman.dvi hist.dvi rluserman.dvi
INTERMEDIATE_OBJ = rlman.dvi
DIST_DOCS = $(DVIOBJ) $(PSOBJ) $(HTMLOBJ) $(INFOOBJ) $(TEXTOBJ)
.SUFFIXES: .0 .3 .ps .txt .dvi
.SUFFIXES: .0 .3 .ps .txt .dvi .html .pdf
.3.0:
$(RM) $@
-${NROFF} -man $< > $@
.ps.pdf:
$(RM) $@
-${PSPDF} $<
.dvi.pdf:
$(RM) $@
-${DVIPDF} $<
all: info dvi html ps text
nodvi: info html text
info: $(INFOOBJ)
dvi: $(DVIOBJ)
ps: $(PSOBJ)
html: $(HTMLOBJ)
text: $(TEXTOBJ)
pdf: $(PDFOBJ)
readline.dvi: $(RLSRC)
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rlman.texinfo
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rlman.texi
mv rlman.dvi readline.dvi
readline.info: $(RLSRC)
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texinfo
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texi
rluserman.dvi: $(RLSRC)
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rluserman.texinfo
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rluserman.texi
rluserman.info: $(RLSRC)
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rluserman.texinfo
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rluserman.texi
history.dvi: ${HISTSRC}
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/hist.texinfo
mv hist.dvi history.dvi
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/history.texi
history.info: ${HISTSRC}
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/hist.texinfo
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/history.texi
readline.ps: readline.dvi
$(RM) $@
@ -122,22 +141,15 @@ history.ps: history.dvi
# This leaves readline.html and rlman.html -- rlman.html is for www.gnu.org
#
readline.html: ${RLSRC}
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rlman.texinfo
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rlman.texi
sed -e 's:rlman.html:readline.html:g' rlman.html > readline.html
$(RM) rlman.html
rluserman.html: ${RLSRC}
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rluserman.texinfo
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/rluserman.texi
history.html: ${HISTSRC}
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/hist.texinfo
sed -e 's:hist.html:history.html:g' hist.html > history.html
$(RM) hist.html
info: $(INFOOBJ)
dvi: $(DVIOBJ)
ps: $(PSOBJ)
html: $(HTMLOBJ)
text: $(TEXTOBJ)
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/history.texi
readline.0: readline.3
@ -151,9 +163,14 @@ history_3.ps: history.3
${RM} $@
${GROFF} -man < $(srcdir)/history.3 > $@
readline.pdf: readline.dvi
history.pdf: history.dvi
rluserman.pdf: rluserman.dvi
clean:
$(RM) *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
*.fns *.kys *.tps *.vrs *.bt *.bts *.o core *.core
$(RM) *.aux *.bak *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps \
*.pgs *.bt *.bts *.rw *.rws *.fns *.kys *.tps *.vrs *.o \
core *.core
mostlyclean: clean
@ -169,6 +186,7 @@ maybe-clean:
maintainer-clean: clean
$(RM) $(DIST_DOCS)
$(RM) $(INTERMEDIATE_OBJ)
$(RM) $(PDFOBJ)
$(RM) Makefile
installdirs: $(topdir)/support/mkdirs

View File

@ -1,110 +0,0 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header (This is for running Texinfo on a region.)
@setfilename history.info
@settitle GNU History Library
@c %**end of header (This is for running Texinfo on a region.)
@setchapternewpage odd
@include manvers.texinfo
@ifinfo
@dircategory Libraries
@direntry
* History: (history). The GNU history library API
@end direntry
This document describes the GNU History library, a programming tool that
provides a consistent user interface for recalling lines of previously
typed input.
Copyright (C) 1988-2002 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
pare preserved on all copies.
@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Free Software Foundation.
@end ifinfo
@titlepage
@title GNU History Library
@subtitle Edition @value{EDITION}, for @code{History Library} Version @value{VERSION}.
@subtitle @value{UPDATE-MONTH}
@author Brian Fox, Free Software Foundation
@author Chet Ramey, Case Western Reserve University
@page
This document describes the GNU History library, a programming tool that
provides a consistent user interface for recalling lines of previously
typed input.
Published by the Free Software Foundation @*
59 Temple Place, Suite 330, @*
Boston, MA 02111 USA
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Free Software Foundation.
@vskip 0pt plus 1filll
Copyright @copyright{} 1988-2002 Free Software Foundation, Inc.
@end titlepage
@ifinfo
@node Top
@top GNU History Library
This document describes the GNU History library, a programming tool that
provides a consistent user interface for recalling lines of previously
typed input.
@menu
* Using History Interactively:: GNU History User's Manual.
* Programming with GNU History:: GNU History Programmer's Manual.
* Concept Index:: Index of concepts described in this manual.
* Function and Variable Index:: Index of externally visible functions
and variables.
@end menu
@end ifinfo
@syncodeindex fn vr
@include hsuser.texinfo
@include hstech.texinfo
@node Concept Index
@appendix Concept Index
@printindex cp
@node Function and Variable Index
@appendix Function and Variable Index
@printindex vr
@contents
@bye

View File

@ -6,9 +6,9 @@
.\" Case Western Reserve University
.\" chet@ins.CWRU.Edu
.\"
.\" Last Change: Thu Jan 31 16:08:07 EST 2002
.\" Last Change: Thu Jul 31 08:46:08 EDT 2003
.\"
.TH HISTORY 3 "2002 January 31" "GNU History 4.3"
.TH HISTORY 3 "2003 July 31" "GNU History 5.0"
.\"
.\" File Name macro. This used to be `.PN', for Path Name,
.\" but Sun doesn't seem to like that very much.
@ -249,6 +249,10 @@ or `\fB:&\fP'. If used with
`\fB:s\fP', any delimiter can be used
in place of /, and the final delimiter is optional
if it is the last character of the event line.
An \fBa\fP may be used as a synonym for \fBg\fP.
.TP
.B G
Apply the following `\fBs\fP' modifier once to each word in the event line.
.PD
.SH "PROGRAMMING WITH HISTORY FUNCTIONS"
This section describes how to use the History library in other programs.
@ -292,6 +296,7 @@ declared as follows:
.nf
typedef struct _hist_entry {
char *line;
char *timestamp;
histdata_t data;
} HIST_ENTRY;
.fi
@ -345,14 +350,24 @@ parameters managing the list itself.
Place \fIstring\fP at the end of the history list. The associated data
field (if any) is set to \fBNULL\fP.
.Fn1 void add_history_time "const char *string"
Change the time stamp associated with the most recent history entry to
\fIstring\fP.
.Fn1 "HIST_ENTRY *" remove_history "int which"
Remove history entry at offset \fIwhich\fP from the history. The
removed element is returned so you can free the line, data,
and containing structure.
.Fn1 "histdata_t" free_history_entry "HIST_ENTRY *histent"
Free the history entry \fIhistent\fP and any history library private
data associated with it. Returns the application-specific data
so the caller can dispose of it.
.Fn3 "HIST_ENTRY *" replace_history_entry "int which" "const char *line" "histdata_t data"
Make the history entry at offset \fIwhich\fP have \fIline\fP and \fIdata\fP.
This returns the old entry so you can dispose of the data. In the case
This returns the old entry so the caller can dispose of any
application-specific data. In the case
of an invalid \fIwhich\fP, a \fBNULL\fP pointer is returned.
.Fn1 void clear_history "void"
@ -394,6 +409,9 @@ Return the history entry at position \fIoffset\fP, starting from
If there is no entry there, or if \fIoffset\fP
is greater than the history length, return a \fBNULL\fP pointer.
.Fn1 "time_t" history_get_time "HIST_ENTRY *"
Return the time stamp associated with the history entry passed as the argument.
.Fn1 int history_total_bytes "void"
Return the number of bytes that the primary history entries are using.
This function returns the sum of the lengths of all the lines in the
@ -551,6 +569,11 @@ The number of entries currently stored in the history list.
The maximum number of history entries. This must be changed using
\fBstifle_history()\fP.
.Vb int history_write_timestamps
If non-zero, timestamps are written to the history file, so they can be
preserved between sessions. The default value is 0, meaning that
timestamps are not saved.
.Vb char history_expansion_char
The character that introduces a history event. The default is \fB!\fP.
Setting this to 0 inhibits history expansion.

Binary file not shown.

View File

@ -1,550 +0,0 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988-2002 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
provided the copyright notice and this permission notice are preserved on
all copies.
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission notice
identical to this one except for the removal of this paragraph (this
paragraph not being relevant to the printed manual).
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
@node Programming with GNU History
@chapter Programming with GNU History
This chapter describes how to interface programs that you write
with the @sc{gnu} History Library.
It should be considered a technical guide.
For information on the interactive use of @sc{gnu} History, @pxref{Using
History Interactively}.
@menu
* Introduction to History:: What is the GNU History library for?
* History Storage:: How information is stored.
* History Functions:: Functions that you can use.
* History Variables:: Variables that control behaviour.
* History Programming Example:: Example of using the GNU History Library.
@end menu
@node Introduction to History
@section Introduction to History
Many programs read input from the user a line at a time. The @sc{gnu}
History library is able to keep track of those lines, associate arbitrary
data with each line, and utilize information from previous lines in
composing new ones.
The programmer using the History library has available functions
for remembering lines on a history list, associating arbitrary data
with a line, removing lines from the list, searching through the list
for a line containing an arbitrary text string, and referencing any line
in the list directly. In addition, a history @dfn{expansion} function
is available which provides for a consistent user interface across
different programs.
The user using programs written with the History library has the
benefit of a consistent user interface with a set of well-known
commands for manipulating the text of previous lines and using that text
in new commands. The basic history manipulation commands are similar to
the history substitution provided by @code{csh}.
If the programmer desires, he can use the Readline library, which
includes some history manipulation by default, and has the added
advantage of command line editing.
Before declaring any functions using any functionality the History
library provides in other code, an application writer should include
the file @code{<readline/history.h>} in any file that uses the
History library's features. It supplies extern declarations for all
of the library's public functions and variables, and declares all of
the public data structures.
@node History Storage
@section History Storage
The history list is an array of history entries. A history entry is
declared as follows:
@example
typedef void *histdata_t;
typedef struct _hist_entry @{
char *line;
histdata_t data;
@} HIST_ENTRY;
@end example
The history list itself might therefore be declared as
@example
HIST_ENTRY **the_history_list;
@end example
The state of the History library is encapsulated into a single structure:
@example
/*
* A structure used to pass around the current state of the history.
*/
typedef struct _hist_state @{
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
int offset; /* The location pointer within this array. */
int length; /* Number of elements within this array. */
int size; /* Number of slots allocated to this array. */
int flags;
@} HISTORY_STATE;
@end example
If the flags member includes @code{HS_STIFLED}, the history has been
stifled.
@node History Functions
@section History Functions
This section describes the calling sequence for the various functions
exported by the @sc{gnu} History library.
@menu
* Initializing History and State Management:: Functions to call when you
want to use history in a
program.
* History List Management:: Functions used to manage the list
of history entries.
* Information About the History List:: Functions returning information about
the history list.
* Moving Around the History List:: Functions used to change the position
in the history list.
* Searching the History List:: Functions to search the history list
for entries containing a string.
* Managing the History File:: Functions that read and write a file
containing the history list.
* History Expansion:: Functions to perform csh-like history
expansion.
@end menu
@node Initializing History and State Management
@subsection Initializing History and State Management
This section describes functions used to initialize and manage
the state of the History library when you want to use the history
functions in your program.
@deftypefun void using_history (void)
Begin a session in which the history functions might be used. This
initializes the interactive variables.
@end deftypefun
@deftypefun {HISTORY_STATE *} history_get_history_state (void)
Return a structure describing the current state of the input history.
@end deftypefun
@deftypefun void history_set_history_state (HISTORY_STATE *state)
Set the state of the history list according to @var{state}.
@end deftypefun
@node History List Management
@subsection History List Management
These functions manage individual entries on the history list, or set
parameters managing the list itself.
@deftypefun void add_history (const char *string)
Place @var{string} at the end of the history list. The associated data
field (if any) is set to @code{NULL}.
@end deftypefun
@deftypefun {HIST_ENTRY *} remove_history (int which)
Remove history entry at offset @var{which} from the history. The
removed element is returned so you can free the line, data,
and containing structure.
@end deftypefun
@deftypefun {HIST_ENTRY *} replace_history_entry (int which, const char *line, histdata_t data)
Make the history entry at offset @var{which} have @var{line} and @var{data}.
This returns the old entry so you can dispose of the data. In the case
of an invalid @var{which}, a @code{NULL} pointer is returned.
@end deftypefun
@deftypefun void clear_history (void)
Clear the history list by deleting all the entries.
@end deftypefun
@deftypefun void stifle_history (int max)
Stifle the history list, remembering only the last @var{max} entries.
@end deftypefun
@deftypefun int unstifle_history (void)
Stop stifling the history. This returns the previously-set
maximum number of history entries (as set by @code{stifle_history()}).
The value is positive if the history was
stifled, negative if it wasn't.
@end deftypefun
@deftypefun int history_is_stifled (void)
Returns non-zero if the history is stifled, zero if it is not.
@end deftypefun
@node Information About the History List
@subsection Information About the History List
These functions return information about the entire history list or
individual list entries.
@deftypefun {HIST_ENTRY **} history_list (void)
Return a @code{NULL} terminated array of @code{HIST_ENTRY *} which is the
current input history. Element 0 of this list is the beginning of time.
If there is no history, return @code{NULL}.
@end deftypefun
@deftypefun int where_history (void)
Returns the offset of the current history element.
@end deftypefun
@deftypefun {HIST_ENTRY *} current_history (void)
Return the history entry at the current position, as determined by
@code{where_history()}. If there is no entry there, return a @code{NULL}
pointer.
@end deftypefun
@deftypefun {HIST_ENTRY *} history_get (int offset)
Return the history entry at position @var{offset}, starting from
@code{history_base} (@pxref{History Variables}).
If there is no entry there, or if @var{offset}
is greater than the history length, return a @code{NULL} pointer.
@end deftypefun
@deftypefun int history_total_bytes (void)
Return the number of bytes that the primary history entries are using.
This function returns the sum of the lengths of all the lines in the
history.
@end deftypefun
@node Moving Around the History List
@subsection Moving Around the History List
These functions allow the current index into the history list to be
set or changed.
@deftypefun int history_set_pos (int pos)
Set the current history offset to @var{pos}, an absolute index
into the list.
Returns 1 on success, 0 if @var{pos} is less than zero or greater
than the number of history entries.
@end deftypefun
@deftypefun {HIST_ENTRY *} previous_history (void)
Back up the current history offset to the previous history entry, and
return a pointer to that entry. If there is no previous entry, return
a @code{NULL} pointer.
@end deftypefun
@deftypefun {HIST_ENTRY *} next_history (void)
Move the current history offset forward to the next history entry, and
return the a pointer to that entry. If there is no next entry, return
a @code{NULL} pointer.
@end deftypefun
@node Searching the History List
@subsection Searching the History List
@cindex History Searching
These functions allow searching of the history list for entries containing
a specific string. Searching may be performed both forward and backward
from the current history position. The search may be @dfn{anchored},
meaning that the string must match at the beginning of the history entry.
@cindex anchored search
@deftypefun int history_search (const char *string, int direction)
Search the history for @var{string}, starting at the current history offset.
If @var{direction} is less than 0, then the search is through
previous entries, otherwise through subsequent entries.
If @var{string} is found, then
the current history index is set to that history entry, and the value
returned is the offset in the line of the entry where
@var{string} was found. Otherwise, nothing is changed, and a -1 is
returned.
@end deftypefun
@deftypefun int history_search_prefix (const char *string, int direction)
Search the history for @var{string}, starting at the current history
offset. The search is anchored: matching lines must begin with
@var{string}. If @var{direction} is less than 0, then the search is
through previous entries, otherwise through subsequent entries.
If @var{string} is found, then the
current history index is set to that entry, and the return value is 0.
Otherwise, nothing is changed, and a -1 is returned.
@end deftypefun
@deftypefun int history_search_pos (const char *string, int direction, int pos)
Search for @var{string} in the history list, starting at @var{pos}, an
absolute index into the list. If @var{direction} is negative, the search
proceeds backward from @var{pos}, otherwise forward. Returns the absolute
index of the history element where @var{string} was found, or -1 otherwise.
@end deftypefun
@node Managing the History File
@subsection Managing the History File
The History library can read the history from and write it to a file.
This section documents the functions for managing a history file.
@deftypefun int read_history (const char *filename)
Add the contents of @var{filename} to the history list, a line at a time.
If @var{filename} is @code{NULL}, then read from @file{~/.history}.
Returns 0 if successful, or @code{errno} if not.
@end deftypefun
@deftypefun int read_history_range (const char *filename, int from, int to)
Read a range of lines from @var{filename}, adding them to the history list.
Start reading at line @var{from} and end at @var{to}.
If @var{from} is zero, start at the beginning. If @var{to} is less than
@var{from}, then read until the end of the file. If @var{filename} is
@code{NULL}, then read from @file{~/.history}. Returns 0 if successful,
or @code{errno} if not.
@end deftypefun
@deftypefun int write_history (const char *filename)
Write the current history to @var{filename}, overwriting @var{filename}
if necessary.
If @var{filename} is @code{NULL}, then write the history list to
@file{~/.history}.
Returns 0 on success, or @code{errno} on a read or write error.
@end deftypefun
@deftypefun int append_history (int nelements, const char *filename)
Append the last @var{nelements} of the history list to @var{filename}.
If @var{filename} is @code{NULL}, then append to @file{~/.history}.
Returns 0 on success, or @code{errno} on a read or write error.
@end deftypefun
@deftypefun int history_truncate_file (const char *filename, int nlines)
Truncate the history file @var{filename}, leaving only the last
@var{nlines} lines.
If @var{filename} is @code{NULL}, then @file{~/.history} is truncated.
Returns 0 on success, or @code{errno} on failure.
@end deftypefun
@node History Expansion
@subsection History Expansion
These functions implement history expansion.
@deftypefun int history_expand (char *string, char **output)
Expand @var{string}, placing the result into @var{output}, a pointer
to a string (@pxref{History Interaction}). Returns:
@table @code
@item 0
If no expansions took place (or, if the only change in
the text was the removal of escape characters preceding the history expansion
character);
@item 1
if expansions did take place;
@item -1
if there was an error in expansion;
@item 2
if the returned line should be displayed, but not executed,
as with the @code{:p} modifier (@pxref{Modifiers}).
@end table
If an error ocurred in expansion, then @var{output} contains a descriptive
error message.
@end deftypefun
@deftypefun {char *} get_history_event (const char *string, int *cindex, int qchar)
Returns the text of the history event beginning at @var{string} +
@var{*cindex}. @var{*cindex} is modified to point to after the event
specifier. At function entry, @var{cindex} points to the index into
@var{string} where the history event specification begins. @var{qchar}
is a character that is allowed to end the event specification in addition
to the ``normal'' terminating characters.
@end deftypefun
@deftypefun {char **} history_tokenize (const char *string)
Return an array of tokens parsed out of @var{string}, much as the
shell might. The tokens are split on the characters in the
@var{history_word_delimiters} variable,
and shell quoting conventions are obeyed.
@end deftypefun
@deftypefun {char *} history_arg_extract (int first, int last, const char *string)
Extract a string segment consisting of the @var{first} through @var{last}
arguments present in @var{string}. Arguments are split using
@code{history_tokenize}.
@end deftypefun
@node History Variables
@section History Variables
This section describes the externally-visible variables exported by
the @sc{gnu} History Library.
@deftypevar int history_base
The logical offset of the first entry in the history list.
@end deftypevar
@deftypevar int history_length
The number of entries currently stored in the history list.
@end deftypevar
@deftypevar int history_max_entries
The maximum number of history entries. This must be changed using
@code{stifle_history()}.
@end deftypevar
@deftypevar char history_expansion_char
The character that introduces a history event. The default is @samp{!}.
Setting this to 0 inhibits history expansion.
@end deftypevar
@deftypevar char history_subst_char
The character that invokes word substitution if found at the start of
a line. The default is @samp{^}.
@end deftypevar
@deftypevar char history_comment_char
During tokenization, if this character is seen as the first character
of a word, then it and all subsequent characters up to a newline are
ignored, suppressing history expansion for the remainder of the line.
This is disabled by default.
@end deftypevar
@deftypevar {char *} history_word_delimiters
The characters that separate tokens for @code{history_tokenize()}.
The default value is @code{" \t\n()<>;&|"}.
@end deftypevar
@deftypevar {char *} history_no_expand_chars
The list of characters which inhibit history expansion if found immediately
following @var{history_expansion_char}. The default is space, tab, newline,
carriage return, and @samp{=}.
@end deftypevar
@deftypevar {char *} history_search_delimiter_chars
The list of additional characters which can delimit a history search
string, in addition to space, TAB, @samp{:} and @samp{?} in the case of
a substring search. The default is empty.
@end deftypevar
@deftypevar int history_quotes_inhibit_expansion
If non-zero, single-quoted words are not scanned for the history expansion
character. The default value is 0.
@end deftypevar
@deftypevar {rl_linebuf_func_t *} history_inhibit_expansion_function
This should be set to the address of a function that takes two arguments:
a @code{char *} (@var{string})
and an @code{int} index into that string (@var{i}).
It should return a non-zero value if the history expansion starting at
@var{string[i]} should not be performed; zero if the expansion should
be done.
It is intended for use by applications like Bash that use the history
expansion character for additional purposes.
By default, this variable is set to @code{NULL}.
@end deftypevar
@node History Programming Example
@section History Programming Example
The following program demonstrates simple use of the @sc{gnu} History Library.
@smallexample
#include <stdio.h>
#include <readline/history.h>
main (argc, argv)
int argc;
char **argv;
@{
char line[1024], *t;
int len, done = 0;
line[0] = 0;
using_history ();
while (!done)
@{
printf ("history$ ");
fflush (stdout);
t = fgets (line, sizeof (line) - 1, stdin);
if (t && *t)
@{
len = strlen (t);
if (t[len - 1] == '\n')
t[len - 1] = '\0';
@}
if (!t)
strcpy (line, "quit");
if (line[0])
@{
char *expansion;
int result;
result = history_expand (line, &expansion);
if (result)
fprintf (stderr, "%s\n", expansion);
if (result < 0 || result == 2)
@{
free (expansion);
continue;
@}
add_history (expansion);
strncpy (line, expansion, sizeof (line) - 1);
free (expansion);
@}
if (strcmp (line, "quit") == 0)
done = 1;
else if (strcmp (line, "save") == 0)
write_history ("history_file");
else if (strcmp (line, "read") == 0)
read_history ("history_file");
else if (strcmp (line, "list") == 0)
@{
register HIST_ENTRY **the_list;
register int i;
the_list = history_list ();
if (the_list)
for (i = 0; the_list[i]; i++)
printf ("%d: %s\n", i + history_base, the_list[i]->line);
@}
else if (strncmp (line, "delete", 6) == 0)
@{
int which;
if ((sscanf (line + 6, "%d", &which)) == 1)
@{
HIST_ENTRY *entry = remove_history (which);
if (!entry)
fprintf (stderr, "No such entry %d\n", which);
else
@{
free (entry->line);
free (entry);
@}
@}
else
@{
fprintf (stderr, "non-numeric arg given to `delete'\n");
@}
@}
@}
@}
@end smallexample

View File

@ -1,437 +0,0 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988-2002 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
provided the copyright notice and this permission notice are preserved on
all copies.
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission notice
identical to this one except for the removal of this paragraph (this
paragraph not being relevant to the printed manual).
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
@node Using History Interactively
@chapter Using History Interactively
@ifclear BashFeatures
@defcodeindex bt
@end ifclear
@ifset BashFeatures
This chapter describes how to use the @sc{gnu} History Library
interactively, from a user's standpoint.
It should be considered a user's guide.
For information on using the @sc{gnu} History Library in other programs,
see the @sc{gnu} Readline Library Manual.
@end ifset
@ifclear BashFeatures
This chapter describes how to use the @sc{gnu} History Library interactively,
from a user's standpoint. It should be considered a user's guide. For
information on using the @sc{gnu} History Library in your own programs,
@pxref{Programming with GNU History}.
@end ifclear
@ifset BashFeatures
@menu
* Bash History Facilities:: How Bash lets you manipulate your command
history.
* Bash History Builtins:: The Bash builtin commands that manipulate
the command history.
* History Interaction:: What it feels like using History as a user.
@end menu
@end ifset
@ifclear BashFeatures
@menu
* History Interaction:: What it feels like using History as a user.
@end menu
@end ifclear
@ifset BashFeatures
@node Bash History Facilities
@section Bash History Facilities
@cindex command history
@cindex history list
When the @option{-o history} option to the @code{set} builtin
is enabled (@pxref{The Set Builtin}),
the shell provides access to the @dfn{command history},
the list of commands previously typed.
The value of the @env{HISTSIZE} shell variable is used as the
number of commands to save in a history list.
The text of the last @env{$HISTSIZE}
commands (default 500) is saved.
The shell stores each command in the history list prior to
parameter and variable expansion
but after history expansion is performed, subject to the
values of the shell variables
@env{HISTIGNORE} and @env{HISTCONTROL}.
When the shell starts up, the history is initialized from the
file named by the @env{HISTFILE} variable (default @file{~/.bash_history}).
The file named by the value of @env{HISTFILE} is truncated, if
necessary, to contain no more than the number of lines specified by
the value of the @env{HISTFILESIZE} variable.
When an interactive shell exits, the last
@env{$HISTSIZE} lines are copied from the history list to the file
named by @env{$HISTFILE}.
If the @code{histappend} shell option is set (@pxref{Bash Builtins}),
the lines are appended to the history file,
otherwise the history file is overwritten.
If @env{HISTFILE}
is unset, or if the history file is unwritable, the history is
not saved. After saving the history, the history file is truncated
to contain no more than @env{$HISTFILESIZE}
lines. If @env{HISTFILESIZE} is not set, no truncation is performed.
The builtin command @code{fc} may be used to list or edit and re-execute
a portion of the history list.
The @code{history} builtin may be used to display or modify the history
list and manipulate the history file.
When using command-line editing, search commands
are available in each editing mode that provide access to the
history list (@pxref{Commands For History}).
The shell allows control over which commands are saved on the history
list. The @env{HISTCONTROL} and @env{HISTIGNORE}
variables may be set to cause the shell to save only a subset of the
commands entered.
The @code{cmdhist}
shell option, if enabled, causes the shell to attempt to save each
line of a multi-line command in the same history entry, adding
semicolons where necessary to preserve syntactic correctness.
The @code{lithist}
shell option causes the shell to save the command with embedded newlines
instead of semicolons.
The @code{shopt} builtin is used to set these options.
@xref{Bash Builtins}, for a description of @code{shopt}.
@node Bash History Builtins
@section Bash History Builtins
@cindex history builtins
Bash provides two builtin commands which manipulate the
history list and history file.
@table @code
@item fc
@btindex fc
@example
@code{fc [-e @var{ename}] [-nlr] [@var{first}] [@var{last}]}
@code{fc -s [@var{pat}=@var{rep}] [@var{command}]}
@end example
Fix Command. In the first form, a range of commands from @var{first} to
@var{last} is selected from the history list. Both @var{first} and
@var{last} may be specified as a string (to locate the most recent
command beginning with that string) or as a number (an index into the
history list, where a negative number is used as an offset from the
current command number). If @var{last} is not specified it is set to
@var{first}. If @var{first} is not specified it is set to the previous
command for editing and @minus{}16 for listing. If the @option{-l} flag is
given, the commands are listed on standard output. The @option{-n} flag
suppresses the command numbers when listing. The @option{-r} flag
reverses the order of the listing. Otherwise, the editor given by
@var{ename} is invoked on a file containing those commands. If
@var{ename} is not given, the value of the following variable expansion
is used: @code{$@{FCEDIT:-$@{EDITOR:-vi@}@}}. This says to use the
value of the @env{FCEDIT} variable if set, or the value of the
@env{EDITOR} variable if that is set, or @code{vi} if neither is set.
When editing is complete, the edited commands are echoed and executed.
In the second form, @var{command} is re-executed after each instance
of @var{pat} in the selected command is replaced by @var{rep}.
A useful alias to use with the @code{fc} command is @code{r='fc -s'}, so
that typing @samp{r cc} runs the last command beginning with @code{cc}
and typing @samp{r} re-executes the last command (@pxref{Aliases}).
@item history
@btindex history
@example
history [@var{n}]
history -c
history -d @var{offset}
history [-anrw] [@var{filename}]
history -ps @var{arg}
@end example
With no options, display the history list with line numbers.
Lines prefixed with a @samp{*} have been modified.
An argument of @var{n} lists only the last @var{n} lines.
Options, if supplied, have the following meanings:
@table @code
@item -c
Clear the history list. This may be combined
with the other options to replace the history list completely.
@item -d @var{offset}
Delete the history entry at position @var{offset}.
@var{offset} should be specified as it appears when the history is
displayed.
@item -a
Append the new
history lines (history lines entered since the beginning of the
current Bash session) to the history file.
@item -n
Append the history lines not already read from the history file
to the current history list. These are lines appended to the history
file since the beginning of the current Bash session.
@item -r
Read the current history file and append its contents to
the history list.
@item -w
Write out the current history to the history file.
@item -p
Perform history substitution on the @var{arg}s and display the result
on the standard output, without storing the results in the history list.
@item -s
The @var{arg}s are added to the end of
the history list as a single entry.
@end table
When any of the @option{-w}, @option{-r}, @option{-a}, or @option{-n} options is
used, if @var{filename}
is given, then it is used as the history file. If not, then
the value of the @env{HISTFILE} variable is used.
@end table
@end ifset
@node History Interaction
@section History Expansion
@cindex history expansion
The History library provides a history expansion feature that is similar
to the history expansion provided by @code{csh}. This section
describes the syntax used to manipulate the history information.
History expansions introduce words from the history list into
the input stream, making it easy to repeat commands, insert the
arguments to a previous command into the current input line, or
fix errors in previous commands quickly.
History expansion takes place in two parts. The first is to determine
which line from the history list should be used during substitution.
The second is to select portions of that line for inclusion into the
current one. The line selected from the history is called the
@dfn{event}, and the portions of that line that are acted upon are
called @dfn{words}. Various @dfn{modifiers} are available to manipulate
the selected words. The line is broken into words in the same fashion
that Bash does, so that several words
surrounded by quotes are considered one word.
History expansions are introduced by the appearance of the
history expansion character, which is @samp{!} by default.
@ifset BashFeatures
Only @samp{\} and @samp{'} may be used to escape the history expansion
character.
@end ifset
@ifset BashFeatures
Several shell options settable with the @code{shopt}
builtin (@pxref{Bash Builtins}) may be used to tailor
the behavior of history expansion. If the
@code{histverify} shell option is enabled, and Readline
is being used, history substitutions are not immediately passed to
the shell parser.
Instead, the expanded line is reloaded into the Readline
editing buffer for further modification.
If Readline is being used, and the @code{histreedit}
shell option is enabled, a failed history expansion will be
reloaded into the Readline editing buffer for correction.
The @option{-p} option to the @code{history} builtin command
may be used to see what a history expansion will do before using it.
The @option{-s} option to the @code{history} builtin may be used to
add commands to the end of the history list without actually executing
them, so that they are available for subsequent recall.
This is most useful in conjunction with Readline.
The shell allows control of the various characters used by the
history expansion mechanism with the @code{histchars} variable.
@end ifset
@menu
* Event Designators:: How to specify which history line to use.
* Word Designators:: Specifying which words are of interest.
* Modifiers:: Modifying the results of substitution.
@end menu
@node Event Designators
@subsection Event Designators
@cindex event designators
An event designator is a reference to a command line entry in the
history list.
@cindex history events
@table @asis
@item @code{!}
Start a history substitution, except when followed by a space, tab,
the end of the line, @samp{=} or @samp{(}.
@item @code{!@var{n}}
Refer to command line @var{n}.
@item @code{!-@var{n}}
Refer to the command @var{n} lines back.
@item @code{!!}
Refer to the previous command. This is a synonym for @samp{!-1}.
@item @code{!@var{string}}
Refer to the most recent command starting with @var{string}.
@item @code{!?@var{string}[?]}
Refer to the most recent command containing @var{string}. The trailing
@samp{?} may be omitted if the @var{string} is followed immediately by
a newline.
@item @code{^@var{string1}^@var{string2}^}
Quick Substitution. Repeat the last command, replacing @var{string1}
with @var{string2}. Equivalent to
@code{!!:s/@var{string1}/@var{string2}/}.
@item @code{!#}
The entire command line typed so far.
@end table
@node Word Designators
@subsection Word Designators
Word designators are used to select desired words from the event.
A @samp{:} separates the event specification from the word designator. It
may be omitted if the word designator begins with a @samp{^}, @samp{$},
@samp{*}, @samp{-}, or @samp{%}. Words are numbered from the beginning
of the line, with the first word being denoted by 0 (zero). Words are
inserted into the current line separated by single spaces.
@need 0.75
For example,
@table @code
@item !!
designates the preceding command. When you type this, the preceding
command is repeated in toto.
@item !!:$
designates the last argument of the preceding command. This may be
shortened to @code{!$}.
@item !fi:2
designates the second argument of the most recent command starting with
the letters @code{fi}.
@end table
@need 0.75
Here are the word designators:
@table @code
@item 0 (zero)
The @code{0}th word. For many applications, this is the command word.
@item @var{n}
The @var{n}th word.
@item ^
The first argument; that is, word 1.
@item $
The last argument.
@item %
The word matched by the most recent @samp{?@var{string}?} search.
@item @var{x}-@var{y}
A range of words; @samp{-@var{y}} abbreviates @samp{0-@var{y}}.
@item *
All of the words, except the @code{0}th. This is a synonym for @samp{1-$}.
It is not an error to use @samp{*} if there is just one word in the event;
the empty string is returned in that case.
@item @var{x}*
Abbreviates @samp{@var{x}-$}
@item @var{x}-
Abbreviates @samp{@var{x}-$} like @samp{@var{x}*}, but omits the last word.
@end table
If a word designator is supplied without an event specification, the
previous command is used as the event.
@node Modifiers
@subsection Modifiers
After the optional word designator, you can add a sequence of one or more
of the following modifiers, each preceded by a @samp{:}.
@table @code
@item h
Remove a trailing pathname component, leaving only the head.
@item t
Remove all leading pathname components, leaving the tail.
@item r
Remove a trailing suffix of the form @samp{.@var{suffix}}, leaving
the basename.
@item e
Remove all but the trailing suffix.
@item p
Print the new command but do not execute it.
@ifset BashFeatures
@item q
Quote the substituted words, escaping further substitutions.
@item x
Quote the substituted words as with @samp{q},
but break into words at spaces, tabs, and newlines.
@end ifset
@item s/@var{old}/@var{new}/
Substitute @var{new} for the first occurrence of @var{old} in the
event line. Any delimiter may be used in place of @samp{/}.
The delimiter may be quoted in @var{old} and @var{new}
with a single backslash. If @samp{&} appears in @var{new},
it is replaced by @var{old}. A single backslash will quote
the @samp{&}. The final delimiter is optional if it is the last
character on the input line.
@item &
Repeat the previous substitution.
@item g
Cause changes to be applied over the entire event line. Used in
conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/},
or with @samp{&}.
@end table

View File

@ -1,7 +1,7 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988-1999 Free Software Foundation, Inc.
Copyright (C) 1988-2002 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
@ -38,11 +38,10 @@ For information on using the @sc{gnu} History Library in other programs,
see the @sc{gnu} Readline Library Manual.
@end ifset
@ifclear BashFeatures
This chapter describes how to use the GNU History Library interactively,
This chapter describes how to use the @sc{gnu} History Library interactively,
from a user's standpoint. It should be considered a user's guide.
@c For
@c information on using the GNU History Library in your own programs,
@c @pxref{Programming with GNU History}.
For information on using the @sc{gnu} History Library in other programs,
see the @sc{gnu} Readline Library Manual.
@end ifclear
@ifset BashFeatures
@ -66,36 +65,39 @@ from a user's standpoint. It should be considered a user's guide.
@cindex command history
@cindex history list
When the @samp{-o history} option to the @code{set} builtin
When the @option{-o history} option to the @code{set} builtin
is enabled (@pxref{The Set Builtin}),
the shell provides access to the @var{command history},
the shell provides access to the @dfn{command history},
the list of commands previously typed.
The value of the @code{HISTSIZE} shell variable is used as the
The value of the @env{HISTSIZE} shell variable is used as the
number of commands to save in a history list.
The text of the last @code{$HISTSIZE}
The text of the last @env{$HISTSIZE}
commands (default 500) is saved.
The shell stores each command in the history list prior to
parameter and variable expansion
but after history expansion is performed, subject to the
values of the shell variables
@code{HISTIGNORE} and @code{HISTCONTROL}.
@env{HISTIGNORE} and @env{HISTCONTROL}.
When the shell starts up, the history is initialized from the
file named by the @code{HISTFILE} variable (default @file{~/.bash_history}).
The file named by the value of @code{HISTFILE} is truncated, if
file named by the @env{HISTFILE} variable (default @file{~/.bash_history}).
The file named by the value of @env{HISTFILE} is truncated, if
necessary, to contain no more than the number of lines specified by
the value of the @code{HISTFILESIZE} variable.
the value of the @env{HISTFILESIZE} variable.
When an interactive shell exits, the last
@code{$HISTSIZE} lines are copied from the history list to the file
named by @code{$HISTFILE}.
@env{$HISTSIZE} lines are copied from the history list to the file
named by @env{$HISTFILE}.
If the @code{histappend} shell option is set (@pxref{Bash Builtins}),
the lines are appended to the history file,
otherwise the history file is overwritten.
If @code{HISTFILE}
If @env{HISTFILE}
is unset, or if the history file is unwritable, the history is
not saved. After saving the history, the history file is truncated
to contain no more than @code{$HISTFILESIZE}
lines. If @code{HISTFILESIZE} is not set, no truncation is performed.
to contain no more than @env{$HISTFILESIZE}
lines. If @env{HISTFILESIZE} is not set, no truncation is performed.
If the @env{HISTTIMEFORMAT} is set, the time stamp information
associated with each history entry is written to the history file.
The builtin command @code{fc} may be used to list or edit and re-execute
a portion of the history list.
@ -106,7 +108,7 @@ are available in each editing mode that provide access to the
history list (@pxref{Commands For History}).
The shell allows control over which commands are saved on the history
list. The @code{HISTCONTROL} and @code{HISTIGNORE}
list. The @env{HISTCONTROL} and @env{HISTIGNORE}
variables may be set to cause the shell to save only a subset of the
commands entered.
The @code{cmdhist}
@ -142,15 +144,15 @@ command beginning with that string) or as a number (an index into the
history list, where a negative number is used as an offset from the
current command number). If @var{last} is not specified it is set to
@var{first}. If @var{first} is not specified it is set to the previous
command for editing and @minus{}16 for listing. If the @samp{-l} flag is
given, the commands are listed on standard output. The @samp{-n} flag
suppresses the command numbers when listing. The @samp{-r} flag
command for editing and @minus{}16 for listing. If the @option{-l} flag is
given, the commands are listed on standard output. The @option{-n} flag
suppresses the command numbers when listing. The @option{-r} flag
reverses the order of the listing. Otherwise, the editor given by
@var{ename} is invoked on a file containing those commands. If
@var{ename} is not given, the value of the following variable expansion
is used: @code{$@{FCEDIT:-$@{EDITOR:-vi@}@}}. This says to use the
value of the @code{FCEDIT} variable if set, or the value of the
@code{EDITOR} variable if that is set, or @code{vi} if neither is set.
value of the @env{FCEDIT} variable if set, or the value of the
@env{EDITOR} variable if that is set, or @code{vi} if neither is set.
When editing is complete, the edited commands are echoed and executed.
In the second form, @var{command} is re-executed after each instance
@ -171,8 +173,14 @@ history -ps @var{arg}
@end example
With no options, display the history list with line numbers.
Lines prefixed with with a @samp{*} have been modified.
Lines prefixed with a @samp{*} have been modified.
An argument of @var{n} lists only the last @var{n} lines.
If the shell variable @env{HISTTIMEFORMAT} is set and not null,
it is used as a format string for @var{strftime} to display
the time stamp associated with each displayed history entry.
No intervening blank is printed between the formatted time stamp
and the history line.
Options, if supplied, have the following meanings:
@table @code
@ -212,10 +220,10 @@ the history list as a single entry.
@end table
When any of the @samp{-w}, @samp{-r}, @samp{-a}, or @samp{-n} options is
When any of the @option{-w}, @option{-r}, @option{-a}, or @option{-n} options is
used, if @var{filename}
is given, then it is used as the history file. If not, then
the value of the @code{HISTFILE} variable is used.
the value of the @env{HISTFILE} variable is used.
@end table
@end ifset
@ -261,9 +269,9 @@ editing buffer for further modification.
If Readline is being used, and the @code{histreedit}
shell option is enabled, a failed history expansion will be
reloaded into the Readline editing buffer for correction.
The @samp{-p} option to the @code{history} builtin command
The @option{-p} option to the @code{history} builtin command
may be used to see what a history expansion will do before using it.
The @samp{-s} option to the @code{history} builtin may be used to
The @option{-s} option to the @code{history} builtin may be used to
add commands to the end of the history list without actually executing
them, so that they are available for subsequent recall.
This is most useful in conjunction with Readline.
@ -289,8 +297,15 @@ history list.
@table @asis
@item @code{!}
@ifset BashFeatures
Start a history substitution, except when followed by a space, tab,
the end of the line, @samp{=} or @samp{(}.
the end of the line, @samp{=} or @samp{(} (when the
@code{extglob} shell option is enabled using the @code{shopt} builtin).
@end ifset
@ifclear BashFeatures
Start a history substitution, except when followed by a space, tab,
the end of the line, or @samp{=}.
@end ifclear
@item @code{!@var{n}}
Refer to command line @var{n}.
@ -431,8 +446,12 @@ character on the input line.
Repeat the previous substitution.
@item g
@itemx a
Cause changes to be applied over the entire event line. Used in
conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/},
or with @samp{&}.
@item G
Apply the following @samp{s} modifier once to each word in the event.
@end table

View File

@ -1,10 +0,0 @@
@ignore
Copyright (C) 1988-2002 Free Software Foundation, Inc.
@end ignore
@set EDITION 4.3
@set VERSION 4.3
@set UPDATED 2002 March 4
@set UPDATE-MONTH March 2002
@set LASTCHANGE Mon Mar 4 12:00:16 EST 2002

View File

@ -6,9 +6,9 @@
.\" Case Western Reserve University
.\" chet@ins.CWRU.Edu
.\"
.\" Last Change: Tue Jan 22 09:18:25 EST 2002
.\" Last Change: Tue Sep 13 12:07:26 EDT 2005
.\"
.TH READLINE 3 "2002 January 22" "GNU Readline 4.3"
.TH READLINE 3 "2005 Sep 13" "GNU Readline 5.1-beta1"
.\"
.\" File Name macro. This used to be `.PN', for Path Name,
.\" but Sun doesn't seem to like that very much.
@ -34,8 +34,8 @@ readline \- get a line from a user with editing
\fBreadline\fP (\fIconst char *prompt\fP);
.fi
.SH COPYRIGHT
.if n Readline is Copyright (C) 1989\-2002 by the Free Software Foundation, Inc.
.if t Readline is Copyright \(co 1989\-2002 by the Free Software Foundation, Inc.
.if n Readline is Copyright (C) 1989\-2004 by the Free Software Foundation, Inc.
.if t Readline is Copyright \(co 1989\-2004 by the Free Software Foundation, Inc.
.SH DESCRIPTION
.LP
.B readline
@ -328,6 +328,10 @@ Except where noted, readline variables can take the values
or
.B Off
(without regard to case).
Unrecognized variable names are ignored.
When a variable value is read, empty or null values, "on" (case-insensitive),
and "1" are equivalent to \fBOn\fP. All other values are equivalent to
\fBOff\fP.
The variables and their default values are:
.PP
.PD 0
@ -338,6 +342,11 @@ If set to \fBnone\fP, readline never rings the bell. If set to
\fBvisible\fP, readline uses a visible bell if one is available.
If set to \fBaudible\fP, readline attempts to ring the terminal's bell.
.TP
.B bind\-tty\-special\-chars (On)
If set to \fBOn\fP, readline attempts to bind the control characters
treated specially by the kernel's terminal driver to their readline
equivalents.
.TP
.B comment\-begin (``#'')
The string that is inserted in \fBvi\fP mode when the
.B insert\-comment
@ -360,7 +369,7 @@ It may be set to any integer value greater than or equal to
zero. If the number of possible completions is greater than
or equal to the value of this variable, the user is asked whether
or not he wishes to view them; otherwise they are simply listed
on the terminal.
on the terminal. A negative value causes readline to never ask.
.TP
.B convert\-meta (On)
If set to \fBOn\fP, readline will convert characters with the
@ -391,9 +400,9 @@ arrow keys.
If set to \fBon\fP, tilde expansion is performed when readline
attempts word completion.
.TP
.B history-preserve-point
.B history\-preserve\-point (Off)
If set to \fBon\fP, the history code attempts to place point at the
same location on each history line retrived with \fBprevious-history\fP
same location on each history line retrieved with \fBprevious-history\fP
or \fBnext-history\fP.
.TP
.B horizontal\-scroll\-mode (Off)
@ -465,6 +474,16 @@ set to
words which have more than one possible completion cause the
matches to be listed immediately instead of ringing the bell.
.TP
.B show\-all\-if\-unmodified (Off)
This alters the default behavior of the completion functions in
a fashion similar to \fBshow\-all\-if\-ambiguous\fP.
If set to
.BR on ,
words which have more than one possible completion without any
possible partial completion (the possible completions don't share
a common prefix) cause the matches to be listed immediately instead
of ringing the bell.
.TP
.B visible\-stats (Off)
If set to \fBOn\fP, a character denoting a file's type as reported
by \fIstat\fP(2) is appended to the filename when listing possible
@ -681,6 +700,8 @@ With an argument
insert the \fIn\fPth word from the previous command (the words
in the previous command begin with word 0). A negative argument
inserts the \fIn\fPth word from the end of the previous command.
Once the argument \fIn\fP is computed, the argument is extracted
as if the "!\fIn\fP" history expansion had been specified.
.TP
.B
yank\-last\-arg (M\-.\^, M\-_\^)
@ -689,6 +710,8 @@ the previous history entry). With an argument,
behave exactly like \fByank\-nth\-arg\fP.
Successive calls to \fByank\-last\-arg\fP move back through the history
list, inserting the last argument of each line in turn.
The history expansion facilities are used to extract the last argument,
as if the "!$" history expansion had been specified.
.PD
.SS Commands for Changing Text
.PP
@ -787,6 +810,11 @@ Word boundaries are the same as those used by \fBbackward\-word\fP.
Kill the word behind point, using white space as a word boundary.
The killed text is saved on the kill-ring.
.TP
.B unix\-filename\-rubout
Kill the word behind point, using white space and the slash character
as the word boundaries.
The killed text is saved on the kill-ring.
.TP
.B delete\-horizontal\-space (M\-\e)
Delete all spaces and tabs around point.
.TP
@ -868,7 +896,7 @@ with a single match from the list of possible completions.
Repeated execution of \fBmenu\-complete\fP steps through the list
of possible completions, inserting each match in turn.
At the end of the list of completions, the bell is rung
(subject to the setting of \Bbell\-style\fP)
(subject to the setting of \fBbell\-style\fP)
and the original text is restored.
An argument of \fIn\fP moves \fIn\fP positions forward in the list
of matches; a negative argument may be used to move backward
@ -979,7 +1007,7 @@ of an \fIinputrc\fP file.
.TP
.B dump\-macros
Print all of the readline key sequences bound to macros and the
strings they ouput. If a numeric argument is supplied,
strings they output. If a numeric argument is supplied,
the output is formatted in such a way that it can be made part
of an \fIinputrc\fP file.
.TP

Binary file not shown.

View File

@ -1,108 +0,0 @@
\input texinfo @c -*-texinfo-*-
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename readline.info
@settitle GNU Readline Library
@comment %**end of header (This is for running Texinfo on a region.)
@synindex vr fn
@setchapternewpage odd
@include manvers.texinfo
@ifinfo
@dircategory Libraries
@direntry
* Readline: (readline). The GNU readline library API
@end direntry
This document describes the GNU Readline Library, a utility which aids
in the consistency of user interface across discrete programs that need
to provide a command line interface.
Copyright (C) 1988-2002 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
pare preserved on all copies.
@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Free Software Foundation.
@end ifinfo
@titlepage
@title GNU Readline Library
@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}.
@subtitle @value{UPDATE-MONTH}
@author Brian Fox, Free Software Foundation
@author Chet Ramey, Case Western Reserve University
@page
This document describes the GNU Readline Library, a utility which aids
in the consistency of user interface across discrete programs that need
to provide a command line interface.
Published by the Free Software Foundation @*
59 Temple Place, Suite 330, @*
Boston, MA 02111 USA
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Free Software Foundation.
@vskip 0pt plus 1filll
Copyright @copyright{} 1988-2002 Free Software Foundation, Inc.
@end titlepage
@ifinfo
@node Top
@top GNU Readline Library
This document describes the GNU Readline Library, a utility which aids
in the consistency of user interface across discrete programs that need
to provide a command line interface.
@menu
* Command Line Editing:: GNU Readline User's Manual.
* Programming with GNU Readline:: GNU Readline Programmer's Manual.
* Concept Index:: Index of concepts described in this manual.
* Function and Variable Index:: Index of externally visible functions
and variables.
@end menu
@end ifinfo
@include rluser.texinfo
@include rltech.texinfo
@node Concept Index
@unnumbered Concept Index
@printindex cp
@node Function and Variable Index
@unnumbered Function and Variable Index
@printindex fn
@contents
@bye

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,94 +0,0 @@
\input texinfo @c -*-texinfo-*-
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename rluserman.info
@settitle GNU Readline Library
@comment %**end of header (This is for running Texinfo on a region.)
@setchapternewpage odd
@include manvers.texinfo
@ifinfo
@dircategory Libraries
@direntry
* RLuserman: (rluserman). The GNU readline library User's Manual.
@end direntry
This document describes the end user interface of the GNU Readline Library,
a utility which aids in the consistency of user interface across discrete
programs that need to provide a command line interface.
Copyright (C) 1988-2002 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
pare preserved on all copies.
@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Free Software Foundation.
@end ifinfo
@titlepage
@title GNU Readline Library User Interface
@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}.
@subtitle @value{UPDATE-MONTH}
@author Brian Fox, Free Software Foundation
@author Chet Ramey, Case Western Reserve University
@page
This document describes the end user interface of the GNU Readline Library,
a utility which aids in the consistency of user interface across discrete
programs that need to provide a command line interface.
Published by the Free Software Foundation @*
59 Temple Place, Suite 330, @*
Boston, MA 02111 USA
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Free Software Foundation.
@vskip 0pt plus 1filll
Copyright @copyright{} 1988-2002 Free Software Foundation, Inc.
@end titlepage
@ifinfo
@node Top
@top GNU Readline Library
This document describes the end user interface of the GNU Readline Library,
a utility which aids in the consistency of user interface across discrete
programs that need to provide a command line interface.
@menu
* Command Line Editing:: GNU Readline User's Manual.
@end menu
@end ifinfo
@include rluser.texinfo
@contents
@bye

View File

@ -2,7 +2,8 @@
# texi2dvi --- produce DVI (or PDF) files from Texinfo (or LaTeX) sources.
# $Id$
#
# Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001,
# 2002, 2003 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -29,9 +30,9 @@
rcs_revision='$Revision$'
rcs_version=`set - $rcs_revision; echo $2`
program=`echo $0 | sed -e 's!.*/!!'`
version="texi2dvi (GNU Texinfo 4.0) $rcs_version
version="texi2dvi (GNU Texinfo 4.5) $rcs_version
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 2003 Free Software Foundation, Inc.
There is NO warranty. You may redistribute this software
under the terms of the GNU General Public License.
For more information about these matters, see the files named COPYING."
@ -46,46 +47,52 @@ is used to determine its language (LaTeX or Texinfo).
Makeinfo is used to perform Texinfo macro expansion before running TeX
when needed.
Options:
-@ Use @input instead of \input; for preloaded Texinfo.
-b, --batch No interaction.
-c, --clean Remove all auxiliary files.
-D, --debug Turn on shell debugging (set -x).
-e, --expand Force macro expansion using makeinfo.
-I DIR Search DIR for Texinfo files.
-h, --help Display this help and exit successfully.
-l, --language=LANG Specify the LANG of FILE: LaTeX or Texinfo.
-p, --pdf Use pdftex or pdflatex for processing.
-q, --quiet No output unless errors (implies --batch).
-s, --silent Same as --quiet.
-t, --texinfo=CMD Insert CMD after @setfilename in copy of input file.
Multiple values accumulate.
-v, --version Display version information and exit successfully.
-V, --verbose Report on what is done.
Operation modes:
-b, --batch no interaction
-c, --clean remove all auxiliary files
-D, --debug turn on shell debugging (set -x)
-h, --help display this help and exit successfully
-o, --output=OFILE leave output in OFILE (implies --clean);
Only one input FILE may be specified in this case
-q, --quiet no output unless errors (implies --batch)
-s, --silent same as --quiet
-v, --version display version information and exit successfully
-V, --verbose report on what is done
TeX tuning:
-@ use @input instead of \input; for preloaded Texinfo
-e, -E, --expand force macro expansion using makeinfo
-I DIR search DIR for Texinfo files
-l, --language=LANG specify the LANG of FILE (LaTeX or Texinfo)
-p, --pdf use pdftex or pdflatex for processing
-t, --texinfo=CMD insert CMD after @setfilename in copy of input file
multiple values accumulate
The values of the BIBTEX, LATEX (or PDFLATEX), MAKEINDEX, MAKEINFO,
TEX (or PDFTEX), and TEXINDEX environment variables are used to run
those commands, if they are set.
Email bug reports to <bug-texinfo@gnu.org>,
general questions and discussion to <help-texinfo@gnu.org>."
general questions and discussion to <help-texinfo@gnu.org>.
Texinfo home page: http://www.gnu.org/software/texinfo/"
# Initialize variables for option overriding and otherwise.
# Don't use `unset' since old bourne shells don't have this command.
# Instead, assign them an empty value.
escape='\'
batch=false # eval for batch mode
clean=
debug=
escape='\'
expand= # t for expansion via makeinfo
oformat=dvi
set_language=
miincludes= # makeinfo include path
oformat=dvi
oname= # --output
quiet= # by default let the tools' message be displayed
set_language=
textra=
tmpdir=${TMPDIR:-/tmp}/t2d$$ # avoid collisions on 8.3 filesystems.
txincludes= # TEXINPUTS extensions
txincludes= # TEXINPUTS extensions, with trailing colon
txiprereq=19990129 # minimum texinfo.tex version to have macro expansion
quiet= # by default let the tools' message be displayed
verbose=false # echo for verbose mode
orig_pwd=`pwd`
@ -98,6 +105,12 @@ else
path_sep=":"
fi
# Pacify verbose cds.
CDPATH=${ZSH_VERSION+.}$path_sep
# In case someone crazy insists on using grep -E.
: ${EGREP=egrep}
# Save this so we can construct a new TEXINPUTS path for each file.
TEXINPUTS_orig="$TEXINPUTS"
# Unfortunately makeindex does not read TEXINPUTS.
@ -136,14 +149,21 @@ while test x"$1" != x"$arg_sep"; do
-q | -s | --q* | --s*) quiet=t; batch=eval;;
-c | --c*) clean=t;;
-D | --d*) debug=t;;
-e | --e*) expand=t;;
-e | -E | --e*) expand=t;;
-h | --h*) echo "$usage"; exit 0;;
-I | --I*)
shift
miincludes="$miincludes -I $1"
txincludes="$txincludes$path_sep$1"
txincludes="$txincludes$1$path_sep"
;;
-l | --l*) shift; set_language=$1;;
-o | --o*)
shift
clean=t
case "$1" in
/* | ?:/*) oname=$1;;
*) oname="$orig_pwd/$1";;
esac;;
-p | --p*) oformat=pdf;;
-t | --t*) shift; textra="$textra\\
$1";;
@ -168,11 +188,20 @@ done
shift
# Interpret remaining command line args as filenames.
if test $# = 0; then
case $# in
0)
echo "$0: Missing file arguments." >&2
echo "$0: Try \`--help' for more information." >&2
exit 2
fi
;;
1) ;;
*)
if test -n "$oname"; then
echo "$0: Can't use option \`--output' with more than one argument." >&2
exit 2
fi
;;
esac
# Prepare the temporary directory. Remove it at exit, unless debugging.
if test -z "$debug"; then
@ -205,14 +234,23 @@ cat <<EOF >$comment_iftex_sed
s/^@c texi2dvi//
}
}
/^@html/,/^@end html/d
/^@ifhtml/,/^@end ifhtml/d
/^@ifnottex/,/^@end ifnottex/d
/^@html/,/^@end html/{
s/^/@c (texi2dvi)/
}
/^@ifhtml/,/^@end ifhtml/{
s/^/@c (texi2dvi)/
}
/^@ifnottex/,/^@end ifnottex/{
s/^/@c (texi2dvi)/
}
/^@ifinfo/,/^@end ifinfo/{
/^@node/p
/^@menu/,/^@end menu/p
d
t
s/^/@c (texi2dvi)/
}
s/^@ifnotinfo/@c texi2dvi@ifnotinfo/
s/^@end ifnotinfo/@c texi2dvi@end ifnotinfo/
EOF
# Uncommenting is simple: Remove any leading `@c texi2dvi'.
uncomment_iftex_sed=$utildir/uncomment.sed
@ -230,7 +268,7 @@ cat <<\EOF >$get_xref_files
# Get list of xref files (indexes, tables and lists).
# Find all files having root filename with a two-letter extension,
# saves the ones that are really Texinfo-related files. .?o? catches
# LaTeX tables and lists.
# many files: .toc, .log, LaTeX tables and lists, FiXme's .lox, maybe more.
for this_file in "$1".?o? "$1".aux "$1".?? "$1".idx; do
# If file is empty, skip it.
test -s "$this_file" || continue
@ -273,7 +311,7 @@ for command_line_filename in ${1+"$@"}; do
# If the COMMAND_LINE_FILENAME is not absolute (e.g., --debug.tex),
# prepend `./' in order to avoid that the tools take it as an option.
echo "$command_line_filename" | egrep '^(/|[A-z]:/)' >/dev/null \
echo "$command_line_filename" | $EGREP '^(/|[A-z]:/)' >/dev/null \
|| command_line_filename="./$command_line_filename"
# See if the file exists. If it doesn't we're in trouble since, even
@ -314,22 +352,67 @@ for command_line_filename in ${1+"$@"}; do
# Make all those directories and give up if we can't succeed.
mkdir $tmpdir_src $tmpdir_xtr $tmpdir_bak || exit 1
# Source file might include additional sources. Put `.' and
# directory where source file(s) reside in TEXINPUTS before anything
# else. `.' goes first to ensure that any old .aux, .cps,
# Source file might include additional sources.
# We want `.:$orig_pwd' before anything else. (We'll add `.:' later
# after all other directories have been turned into absolute paths.)
# `.' goes first to ensure that any old .aux, .cps,
# etc. files in ${directory} don't get used in preference to fresher
# files in `.'. Include orig_pwd in case we are in clean mode, where
# we've cd'd to a temp directory.
common=".$path_sep$orig_pwd$path_sep$filename_dir$path_sep$txincludes$path_sep"
common="$orig_pwd$path_sep$filename_dir$path_sep$txincludes"
TEXINPUTS="$common$TEXINPUTS_orig"
INDEXSTYLE="$common$INDEXSTYLE_orig"
# Convert relative paths to absolute paths, so we can run in another
# directory (e.g., in --clean mode, or during the macro-support
# detection.)
#
# Empty path components are meaningful to tex. We rewrite them
# as `EMPTY' so they don't get lost when we split on $path_sep.
TEXINPUTS=`echo $TEXINPUTS |sed 's/^:/EMPTY:/;s/:$/:EMPTY/;s/::/:EMPTY:/g'`
INDEXSTYLE=`echo $INDEXSTYLE |sed 's/^:/EMPTY:/;s/:$/:EMPTY/;s/::/:EMPTY:/g'`
save_IFS=$IFS
IFS=$path_sep
set x $TEXINPUTS; shift
TEXINPUTS=.
for dir
do
case $dir in
EMPTY)
TEXINPUTS=$TEXINPUTS$path_sep
;;
[\\/]* | ?:[\\/]*) # Absolute paths don't need to be expansed.
TEXINPUTS=$TEXINPUTS$path_sep$dir
;;
*)
abs=`cd "$dir" && pwd` && TEXINPUTS=$TEXINPUTS$path_sep$abs
;;
esac
done
set x $INDEXSTYLE; shift
INDEXSTYLE=.
for dir
do
case $dir in
EMPTY)
INDEXSTYLE=$INDEXSTYLE$path_sep
;;
[\\/]* | ?:[\\/]*) # Absolute paths don't need to be expansed.
INDEXSTYLE=$INDEXSTYLE$path_sep$dir
;;
*)
abs=`cd "$dir" && pwd` && INDEXSTYLE=$INDEXSTYLE$path_sep$abs
;;
esac
done
IFS=$save_IFS
# If the user explicitly specified the language, use that.
# Otherwise, if the first line is \input texinfo, assume it's texinfo.
# Otherwise, guess from the file extension.
if test -n "$set_language"; then
language=$set_language
elif sed 1q "$command_line_filename" | fgrep 'input texinfo' >/dev/null; then
elif sed 1q "$command_line_filename" | grep 'input texinfo' >/dev/null; then
language=texinfo
else
language=
@ -373,9 +456,9 @@ for command_line_filename in ${1+"$@"}; do
txiversion_tex=txiversion.tex
echo '\input texinfo.tex @bye' >$tmpdir/$txiversion_tex
# Run in the tmpdir to avoid leaving files.
eval `cd $tmpdir >/dev/null \
&& $tex $txiversion_tex 2>/dev/null \
| sed -n 's/^.*\[\(.*\)version \(....\)-\(..\)-\(..\).*$/txiformat=\1 txiversion="\2\3\4"/p'`
eval `cd $tmpdir >/dev/null &&
$tex $txiversion_tex 2>/dev/null |
sed -n 's/^.*\[\(.*\)version \(....\)-\(..\)-\(..\).*$/txiformat=\1 txiversion="\2\3\4"/p'`
$verbose "texinfo.tex preloaded as \`$txiformat', version is \`$txiversion' ..."
if test "$txiprereq" -le "$txiversion" >/dev/null 2>&1; then
makeinfo=
@ -467,10 +550,14 @@ for command_line_filename in ${1+"$@"}; do
# What we'll run texindex on -- exclude non-index files.
# Since we know index files are last, it is correct to remove everything
# before .aux and .?o?.
# before .aux and .?o?. But don't really do <anything>o<anything>
# -- don't match whitespace as <anything>.
# Otherwise, if orig_xref_files contains something like
# foo.xo foo.whatever
# the space after the o will get matched.
index_files=`echo "$orig_xref_files" \
| sed "s!.*\.aux!!g;
s!./$filename_noext\..o.!!g;
s!./$filename_noext\.[^ ]o[^ ]!!g;
s/^[ ]*//;s/[ ]*$//"`
# Run texindex (or makeindex) on current index files. If they
# already exist, and after running TeX a first time the index
@ -489,8 +576,8 @@ for command_line_filename in ${1+"$@"}; do
# Prevent $ESCAPE from being interpreted by the shell if it happens
# to be `/'.
$batch tex_args="\\${escape}nonstopmode\ \\${escape}input"
$verbose "Running $cmd ..."
cmd="$tex $tex_args $filename_input"
$verbose "Running $cmd ..."
if $cmd >&5; then :; else
echo "$0: $tex exited with bad status, quitting." >&2
echo "$0: see $filename_noext.log for errors." >&2
@ -508,7 +595,7 @@ for command_line_filename in ${1+"$@"}; do
# subdirs, since texi2dvi does not try to compare xref files in
# subdirs. Performing xref files test is still good since LaTeX
# does not report changes in xref files.
if fgrep "Rerun to get" "$filename_noext.log" >/dev/null 2>&1; then
if grep "Rerun to get" "$filename_noext.log" >/dev/null 2>&1; then
finished=
fi
@ -550,8 +637,13 @@ for command_line_filename in ${1+"$@"}; do
# - the next file is processed in correct conditions
# - the temporary file can be removed
if test -n "$clean"; then
$verbose "Copying $oformat file from `pwd` to $orig_pwd"
cp -p "./$filename_noext.$oformat" "$orig_pwd"
if test -n "$oname"; then
dest=$oname
else
dest=$orig_pwd
fi
$verbose "Copying $oformat file from `pwd` to $dest"
cp -p "./$filename_noext.$oformat" "$dest"
cd / # in case $orig_pwd is on a different drive (for DOS)
cd $orig_pwd || exit 1
fi

View File

@ -278,7 +278,13 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
{ ISFUNC, rl_insert }, /* Latin capital letter Y with acute */
{ ISFUNC, rl_insert }, /* Latin capital letter thorn (Icelandic) */
{ ISFUNC, rl_insert }, /* Latin small letter sharp s (German) */
#ifndef __MINGW32__
{ ISFUNC, rl_insert }, /* Latin small letter a with grave */
#else
/* Temporary - this is a bug in readline 5.1 that should be fixed in
readline 5.2. */
{ ISFUNC, 0 }, /* Must leave this unbound for the arrow keys to work. */
#endif
{ ISFUNC, rl_insert }, /* Latin small letter a with acute */
{ ISFUNC, rl_insert }, /* Latin small letter a with circumflex */
{ ISFUNC, rl_insert }, /* Latin small letter a with tilde */

View File

@ -1,3 +1,7 @@
2006-04-24 Daniel Jacobowitz <dan@codesourcery.com>
Imported readline 5.1, and upstream patches 001-004.
2002-02-24 Elena Zannoni <ezannoni@redhat.com>
* ChangeLog.gdb: Rename from ChangeLog.Cygnus.

View File

@ -40,6 +40,8 @@ INCLUDES = -I$(srcdir) -I$(top_srcdir) -I..
CCFLAGS = $(DEFS) $(LOCAL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(CFLAGS)
LDFLAGS = -g -L.. @LDFLAGS@
PURIFY = @PURIFY@
READLINE_LIB = ../libreadline.a
HISTORY_LIB = ../libhistory.a
@ -50,33 +52,35 @@ TERMCAP_LIB = @TERMCAP_LIB@
$(CC) $(CCFLAGS) -c $<
EXECUTABLES = fileman rltest rl rlcat rlversion histexamp
OBJECTS = fileman.o rltest.o rl.o rlversion.o histexamp.o
OBJECTS = fileman.o rltest.o rl.o rlcat.o rlversion.o histexamp.o
all: $(EXECUTABLES)
everything: all rlfe
everything: all
rl: rl.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rl.o -lreadline $(TERMCAP_LIB)
$(PURIFY) $(CC) $(LDFLAGS) -o $@ rl.o $(READLINE_LIB) $(TERMCAP_LIB)
rlcat: rlcat.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rlcat.o -lreadline $(TERMCAP_LIB)
$(PURIFY) $(CC) $(LDFLAGS) -o $@ rlcat.o $(READLINE_LIB) $(TERMCAP_LIB)
fileman: fileman.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ fileman.o -lreadline $(TERMCAP_LIB)
$(PURIFY) $(CC) $(LDFLAGS) -o $@ fileman.o $(READLINE_LIB) $(TERMCAP_LIB)
rltest: rltest.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rltest.o -lreadline $(TERMCAP_LIB)
$(PURIFY) $(CC) $(LDFLAGS) -o $@ rltest.o $(READLINE_LIB) $(TERMCAP_LIB)
rlptytest: rlptytest.o $(READLINE_LIB)
$(PURIFY) $(CC) $(LDFLAGS) -o $@ rlptytest.o $(READLINE_LIB) $(TERMCAP_LIB)
rlversion: rlversion.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rlversion.o -lreadline $(TERMCAP_LIB)
$(CC) $(LDFLAGS) -o $@ rlversion.o $(READLINE_LIB) $(TERMCAP_LIB)
histexamp: histexamp.o $(HISTORY_LIB)
$(CC) $(LDFLAGS) -o $@ histexamp.o -lhistory $(TERMCAP_LIB)
$(PURIFY) $(CC) $(LDFLAGS) -o $@ histexamp.o -lhistory $(TERMCAP_LIB)
clean mostlyclean:
$(RM) $(OBJECTS)
$(RM) $(EXECUTABLES) *.exe
$(RM) rlfe.o rlfe
distclean maintainer-clean: clean
$(RM) Makefile
@ -86,19 +90,13 @@ rltest.o: rltest.c
rl.o: rl.c
rlversion.o: rlversion.c
histexamp.o: histexamp.c
rlcat.o: rlcat.c
rlptytest.o: rlptytest.c
fileman.o: $(top_srcdir)/readline.h
rltest.o: $(top_srcdir)/readline.h
rl.o: $(top_srcdir)/readline.h
rlversion.o: $(top_srcdir)/readline.h
histexamp.o: $(top_srcdir)/history.h
# Stuff for Per Bothner's `rlfe' program
rlfe: rlfe.o $(READLINE_LIB) $(HISTORY_LIB)
$(CC) $(LDFLAGS) -o $@ rlfe.o -lreadline -lhistory ${TERMCAP_LIB}
rlfe.o: rlfe.c
rlfe.o: $(top_srcdir)/readline.h
rlfe.o: $(top_srcdir)/history.h
rlcat.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
rlptytest.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h

View File

@ -26,14 +26,17 @@
# include <readline/history.h>
#endif
#include <string.h>
main (argc, argv)
int argc;
char **argv;
{
char line[1024], *t;
int len, done = 0;
int len, done;
line[0] = 0;
done = 0;
using_history ();
while (!done)
@ -42,71 +45,80 @@ main (argc, argv)
fflush (stdout);
t = fgets (line, sizeof (line) - 1, stdin);
if (t && *t)
{
len = strlen (t);
if (t[len - 1] == '\n')
t[len - 1] = '\0';
}
{
len = strlen (t);
if (t[len - 1] == '\n')
t[len - 1] = '\0';
}
if (!t)
strcpy (line, "quit");
strcpy (line, "quit");
if (line[0])
{
char *expansion;
int result;
{
char *expansion;
int result;
using_history ();
using_history ();
result = history_expand (line, &expansion);
if (result)
fprintf (stderr, "%s\n", expansion);
result = history_expand (line, &expansion);
if (result)
fprintf (stderr, "%s\n", expansion);
if (result < 0 || result == 2)
{
free (expansion);
continue;
}
if (result < 0 || result == 2)
{
free (expansion);
continue;
}
add_history (expansion);
strncpy (line, expansion, sizeof (line) - 1);
free (expansion);
}
add_history (expansion);
strncpy (line, expansion, sizeof (line) - 1);
free (expansion);
}
if (strcmp (line, "quit") == 0)
done = 1;
done = 1;
else if (strcmp (line, "save") == 0)
write_history ("history_file");
write_history ("history_file");
else if (strcmp (line, "read") == 0)
read_history ("history_file");
read_history ("history_file");
else if (strcmp (line, "list") == 0)
{
register HIST_ENTRY **the_list;
register int i;
{
register HIST_ENTRY **the_list;
register int i;
time_t tt;
char timestr[128];
the_list = history_list ();
if (the_list)
for (i = 0; the_list[i]; i++)
printf ("%d: %s\n", i + history_base, the_list[i]->line);
}
the_list = history_list ();
if (the_list)
for (i = 0; the_list[i]; i++)
{
tt = history_get_time (the_list[i]);
if (tt)
strftime (timestr, sizeof (timestr), "%a %R", localtime(&tt));
else
strcpy (timestr, "??");
printf ("%d: %s: %s\n", i + history_base, timestr, the_list[i]->line);
}
}
else if (strncmp (line, "delete", 6) == 0)
{
int which;
if ((sscanf (line + 6, "%d", &which)) == 1)
{
HIST_ENTRY *entry = remove_history (which);
if (!entry)
fprintf (stderr, "No such entry %d\n", which);
else
{
free (entry->line);
free (entry);
}
}
else
{
fprintf (stderr, "non-numeric arg given to `delete'\n");
}
}
{
int which;
if ((sscanf (line + 6, "%d", &which)) == 1)
{
HIST_ENTRY *entry = remove_history (which);
if (!entry)
fprintf (stderr, "No such entry %d\n", which);
else
{
free (entry->line);
free (entry);
}
}
else
{
fprintf (stderr, "non-numeric arg given to `delete'\n");
}
}
}
}

View File

@ -31,12 +31,19 @@
#include <stdio.h>
#include <sys/types.h>
#include "posixstat.h"
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
extern void exit();
#endif
#if defined (READLINE_LIBRARY)
# include "posixstat.h"
# include "readline.h"
# include "history.h"
#else
# include <sys/stat.h>
# include <readline/readline.h>
# include <readline/history.h>
#endif

View File

@ -40,6 +40,12 @@
#include <string.h>
#include <errno.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
extern void exit();
#endif
#ifndef errno
extern int errno;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,12 @@
#include <stdio.h>
#include <sys/types.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
extern void exit();
#endif
#ifdef READLINE_LIBRARY
# include "readline.h"
# include "history.h"

View File

@ -30,6 +30,12 @@
#include <sys/types.h>
#include "posixstat.h"
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
extern void exit();
#endif
#ifdef READLINE_LIBRARY
# include "readline.h"
#else

View File

@ -131,6 +131,7 @@ static FUNMAP default_funmap[] = {
{ "tty-status", rl_tty_status },
{ "undo", rl_undo_command },
{ "universal-argument", rl_universal_argument },
{ "unix-filename-rubout", rl_unix_filename_rubout },
{ "unix-line-discard", rl_unix_line_discard },
{ "unix-word-rubout", rl_unix_word_rubout },
{ "upcase-word", rl_upcase_word },
@ -175,6 +176,7 @@ static FUNMAP default_funmap[] = {
{ "vi-put", rl_vi_put },
{ "vi-redo", rl_vi_redo },
{ "vi-replace", rl_vi_replace },
{ "vi-rubout", rl_vi_rubout },
{ "vi-search", rl_vi_search },
{ "vi-search-again", rl_vi_search_again },
{ "vi-set-mark", rl_vi_set_mark },

View File

@ -1,6 +1,6 @@
/* histexpand.c -- history expansion. */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1989-2004 Free Software Foundation, Inc.
This file contains the GNU History Library (the Library), a set of
routines for managing the text of previously typed lines.
@ -52,6 +52,8 @@
#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>"
#define HISTORY_QUOTE_CHARACTERS "\"'`"
#define slashify_in_quotes "\\`\"$"
typedef int _hist_search_func_t PARAMS((const char *, int));
extern int rl_byte_oriented; /* declared in mbutil.c */
@ -65,6 +67,8 @@ static int subst_rhs_len;
static char *get_history_word_specifier PARAMS((char *, char *, int *));
static char *history_find_word PARAMS((char *, int));
static int history_tokenize_word PARAMS((const char *, int));
static char *history_substring PARAMS((const char *, int, int));
static char *quote_breaks PARAMS((char *));
@ -202,23 +206,24 @@ get_history_event (string, caller_index, delimiting_quote)
/* Only a closing `?' or a newline delimit a substring search string. */
for (local_index = i; c = string[i]; i++)
{
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int v;
mbstate_t ps;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int v;
mbstate_t ps;
memset (&ps, 0, sizeof (mbstate_t));
/* These produce warnings because we're passing a const string to a
function that takes a non-const string. */
_rl_adjust_point ((char *)string, i, &ps);
if ((v = _rl_get_char_len ((char *)string + i, &ps)) > 1)
{
i += v - 1;
continue;
}
}
memset (&ps, 0, sizeof (mbstate_t));
/* These produce warnings because we're passing a const string to a
function that takes a non-const string. */
_rl_adjust_point (string, i, &ps);
if ((v = _rl_get_char_len (string + i, &ps)) > 1)
{
i += v - 1;
continue;
}
}
else
#endif /* HANDLE_MULTIBYTE */
if ((!substring_okay && (whitespace (c) || c == ':' ||
(history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
@ -226,6 +231,7 @@ get_history_event (string, caller_index, delimiting_quote)
string[i] == '\n' ||
(substring_okay && string[i] == '?'))
break;
}
which = i - local_index;
temp = (char *)xmalloc (1 + which);
@ -517,7 +523,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
char *current_line; /* for !# */
{
int i, n, starting_index;
int substitute_globally, want_quotes, print_only;
int substitute_globally, subst_bywords, want_quotes, print_only;
char *event, *temp, *result, *tstr, *t, c, *word_spec;
int result_len;
#if defined (HANDLE_MULTIBYTE)
@ -599,19 +605,25 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
FREE (word_spec);
/* Perhaps there are other modifiers involved. Do what they say. */
want_quotes = substitute_globally = print_only = 0;
want_quotes = substitute_globally = subst_bywords = print_only = 0;
starting_index = i;
while (string[i] == ':')
{
c = string[i + 1];
if (c == 'g')
if (c == 'g' || c == 'a')
{
substitute_globally = 1;
i++;
c = string[i + 1];
}
else if (c == 'G')
{
subst_bywords = 1;
i++;
c = string[i + 1];
}
switch (c)
{
@ -683,7 +695,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
case 's':
{
char *new_event;
int delimiter, failed, si, l_temp;
int delimiter, failed, si, l_temp, ws, we;
if (c == 's')
{
@ -760,33 +772,67 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
}
/* Find the first occurrence of THIS in TEMP. */
si = 0;
/* Substitute SUBST_RHS for SUBST_LHS in TEMP. There are three
cases to consider:
1. substitute_globally == subst_bywords == 0
2. substitute_globally == 1 && subst_bywords == 0
3. substitute_globally == 0 && subst_bywords == 1
In the first case, we substitute for the first occurrence only.
In the second case, we substitute for every occurrence.
In the third case, we tokenize into words and substitute the
first occurrence of each word. */
si = we = 0;
for (failed = 1; (si + subst_lhs_len) <= l_temp; si++)
if (STREQN (temp+si, subst_lhs, subst_lhs_len))
{
int len = subst_rhs_len - subst_lhs_len + l_temp;
new_event = (char *)xmalloc (1 + len);
strncpy (new_event, temp, si);
strncpy (new_event + si, subst_rhs, subst_rhs_len);
strncpy (new_event + si + subst_rhs_len,
temp + si + subst_lhs_len,
l_temp - (si + subst_lhs_len));
new_event[len] = '\0';
free (temp);
temp = new_event;
{
/* First skip whitespace and find word boundaries if
we're past the end of the word boundary we found
the last time. */
if (subst_bywords && si > we)
{
for (; temp[si] && whitespace (temp[si]); si++)
;
ws = si;
we = history_tokenize_word (temp, si);
}
failed = 0;
if (STREQN (temp+si, subst_lhs, subst_lhs_len))
{
int len = subst_rhs_len - subst_lhs_len + l_temp;
new_event = (char *)xmalloc (1 + len);
strncpy (new_event, temp, si);
strncpy (new_event + si, subst_rhs, subst_rhs_len);
strncpy (new_event + si + subst_rhs_len,
temp + si + subst_lhs_len,
l_temp - (si + subst_lhs_len));
new_event[len] = '\0';
free (temp);
temp = new_event;
if (substitute_globally)
{
si += subst_rhs_len;
l_temp = strlen (temp);
substitute_globally++;
continue;
}
else
break;
}
failed = 0;
if (substitute_globally)
{
/* Reported to fix a bug that causes it to skip every
other match when matching a single character. Was
si += subst_rhs_len previously. */
si += subst_rhs_len - 1;
l_temp = strlen (temp);
substitute_globally++;
continue;
}
else if (subst_bywords)
{
si = we;
l_temp = strlen (temp);
continue;
}
else
break;
}
}
if (substitute_globally > 1)
{
@ -879,7 +925,7 @@ history_expand (hstring, output)
char **output;
{
register int j;
int i, r, l, passc, cc, modified, eindex, only_printing;
int i, r, l, passc, cc, modified, eindex, only_printing, dquote;
char *string;
/* The output string, and its length. */
@ -942,7 +988,7 @@ history_expand (hstring, output)
/* `!' followed by one of the characters in history_no_expand_chars
is NOT an expansion. */
for (i = 0; string[i]; i++)
for (i = dquote = 0; string[i]; i++)
{
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
@ -984,9 +1030,19 @@ history_expand (hstring, output)
else
break;
}
/* XXX - at some point, might want to extend this to handle
double quotes as well. */
else if (history_quotes_inhibit_expansion && string[i] == '\'')
/* Shell-like quoting: allow backslashes to quote double quotes
inside a double-quoted string. */
else if (dquote && string[i] == '\\' && cc == '"')
i++;
/* More shell-like quoting: if we're paying attention to single
quotes and letting them quote the history expansion character,
then we need to pay attention to double quotes, because single
quotes are not special inside double-quoted strings. */
else if (history_quotes_inhibit_expansion && string[i] == '"')
{
dquote = 1 - dquote;
}
else if (dquote == 0 && history_quotes_inhibit_expansion && string[i] == '\'')
{
/* If this is bash, single quotes inhibit history expansion. */
i++;
@ -999,6 +1055,7 @@ history_expand (hstring, output)
if (cc == '\'' || cc == history_expansion_char)
i++;
}
}
if (string[i] != history_expansion_char)
@ -1010,7 +1067,7 @@ history_expand (hstring, output)
}
/* Extract and perform the substitution. */
for (passc = i = j = 0; i < l; i++)
for (passc = dquote = i = j = 0; i < l; i++)
{
int tchar = string[i];
@ -1061,11 +1118,16 @@ history_expand (hstring, output)
ADD_CHAR (tchar);
break;
case '"':
dquote = 1 - dquote;
ADD_CHAR (tchar);
break;
case '\'':
{
/* If history_quotes_inhibit_expansion is set, single quotes
inhibit history expansion. */
if (history_quotes_inhibit_expansion)
if (dquote == 0 && history_quotes_inhibit_expansion)
{
int quote, slen;
@ -1160,7 +1222,9 @@ history_expand (hstring, output)
if (only_printing)
{
#if 0
add_history (result);
#endif
return (2);
}
@ -1223,7 +1287,10 @@ get_history_word_specifier (spec, from, caller_index)
if (spec[i] == '-')
first = 0;
else if (spec[i] == '^')
first = 1;
{
first = 1;
i++;
}
else if (_rl_digit_p (spec[i]) && expecting_word_spec)
{
for (first = 0; _rl_digit_p (spec[i]); i++)
@ -1338,7 +1405,103 @@ history_arg_extract (first, last, string)
return (result);
}
#define slashify_in_quotes "\\`\"$"
static int
history_tokenize_word (string, ind)
const char *string;
int ind;
{
register int i;
int delimiter;
i = ind;
delimiter = 0;
if (member (string[i], "()\n"))
{
i++;
return i;
}
if (member (string[i], "<>;&|$"))
{
int peek = string[i + 1];
if (peek == string[i] && peek != '$')
{
if (peek == '<' && string[i + 2] == '-')
i++;
i += 2;
return i;
}
else
{
if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
(peek == '>' && string[i] == '&') ||
(peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
(peek == '(' && string[i] == '$')) /* ) */
{
i += 2;
return i;
}
}
if (string[i] != '$')
{
i++;
return i;
}
}
/* Get word from string + i; */
if (member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i++];
for (; string[i]; i++)
{
if (string[i] == '\\' && string[i + 1] == '\n')
{
i++;
continue;
}
if (string[i] == '\\' && delimiter != '\'' &&
(delimiter != '"' || member (string[i], slashify_in_quotes)))
{
i++;
continue;
}
if (delimiter && string[i] == delimiter)
{
delimiter = 0;
continue;
}
if (!delimiter && (member (string[i], history_word_delimiters)))
break;
if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i];
}
return i;
}
static char *
history_substring (string, start, end)
const char *string;
int start, end;
{
register int len;
register char *result;
len = end - start;
result = (char *)xmalloc (len + 1);
strncpy (result, string + start, len);
result[len] = '\0';
return result;
}
/* Parse STRING into tokens and return an array of strings. If WIND is
not -1 and INDP is not null, we also want the word surrounding index
@ -1351,7 +1514,6 @@ history_tokenize_internal (string, wind, indp)
{
char **result;
register int i, start, result_index, size;
int len, delimiter;
/* If we're searching for a string that's not part of a word (e.g., " "),
make sure we set *INDP to a reasonable value. */
@ -1362,8 +1524,6 @@ history_tokenize_internal (string, wind, indp)
exactly where the shell would split them. */
for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
{
delimiter = 0;
/* Skip leading whitespace. */
for (; string[i] && whitespace (string[i]); i++)
;
@ -1371,88 +1531,30 @@ history_tokenize_internal (string, wind, indp)
return (result);
start = i;
if (member (string[i], "()\n"))
i = history_tokenize_word (string, start);
/* If we have a non-whitespace delimiter character (which would not be
skipped by the loop above), use it and any adjacent delimiters to
make a separate field. Any adjacent white space will be skipped the
next time through the loop. */
if (i == start && history_word_delimiters)
{
i++;
goto got_token;
while (string[i] && member (string[i], history_word_delimiters))
i++;
}
if (member (string[i], "<>;&|$"))
{
int peek = string[i + 1];
if (peek == string[i] && peek != '$')
{
if (peek == '<' && string[i + 2] == '-')
i++;
i += 2;
goto got_token;
}
else
{
if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
((peek == '>') && (string[i] == '&')) ||
((peek == '(') && (string[i] == '$')))
{
i += 2;
goto got_token;
}
}
if (string[i] != '$')
{
i++;
goto got_token;
}
}
/* Get word from string + i; */
if (member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i++];
for (; string[i]; i++)
{
if (string[i] == '\\' && string[i + 1] == '\n')
{
i++;
continue;
}
if (string[i] == '\\' && delimiter != '\'' &&
(delimiter != '"' || member (string[i], slashify_in_quotes)))
{
i++;
continue;
}
if (delimiter && string[i] == delimiter)
{
delimiter = 0;
continue;
}
if (!delimiter && (member (string[i], history_word_delimiters)))
break;
if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i];
}
got_token:
/* If we are looking for the word in which the character at a
particular index falls, remember it. */
if (indp && wind != -1 && wind >= start && wind < i)
*indp = result_index;
len = i - start;
if (result_index + 2 >= size)
result = (char **)xrealloc (result, ((size += 10) * sizeof (char *)));
result[result_index] = (char *)xmalloc (1 + len);
strncpy (result[result_index], string + start, len);
result[result_index][len] = '\0';
result[++result_index] = (char *)NULL;
result[result_index++] = history_substring (string, start, i);
result[result_index] = (char *)NULL;
}
return (result);

View File

@ -1,6 +1,6 @@
/* histfile.c - functions to manipulate the history file. */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1989-2003 Free Software Foundation, Inc.
This file contains the GNU History Library (the Library), a set of
routines for managing the text of previously typed lines.
@ -23,8 +23,13 @@
/* The goal is to make the implementation transparent, so that you
don't have to know what data types are used, just what functions
you can call. I think I have done that. */
#define READLINE_LIBRARY
#if defined (__TANDEM)
# include <floss.h>
#endif
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
@ -32,7 +37,7 @@
#include <stdio.h>
#include <sys/types.h>
#ifndef _MINIX
#if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
#include "posixstat.h"
@ -52,7 +57,7 @@
# undef HAVE_MMAP
#endif
#ifdef HAVE_MMAP
#ifdef HISTORY_USE_MMAP
# include <sys/mman.h>
# ifdef MAP_FILE
@ -67,7 +72,7 @@
# define MAP_FAILED ((void *)-1)
# endif
#endif /* HAVE_MMAP */
#endif /* HISTORY_USE_MMAP */
/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
on win 95/98/nt), we want to open files with O_BINARY mode so that there
@ -93,6 +98,13 @@ extern int errno;
#include "rlshell.h"
#include "xmalloc.h"
/* If non-zero, we write timestamps to the history file in history_do_write() */
int history_write_timestamps = 0;
/* Does S look like the beginning of a history timestamp entry? Placeholder
for more extensive tests. */
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char)
/* Return the string that should be used in the place of this
filename. This only matters when you don't specify the
filename to read_history (), or write_history (). */
@ -151,13 +163,20 @@ read_history_range (filename, from, to)
const char *filename;
int from, to;
{
register char *line_start, *line_end;
char *input, *buffer, *bufend;
register char *line_start, *line_end, *p;
char *input, *buffer, *bufend, *last_ts;
int file, current_line, chars_read;
struct stat finfo;
size_t file_size;
#if defined (EFBIG)
int overflow_errno = EFBIG;
#elif defined (EOVERFLOW)
int overflow_errno = EOVERFLOW;
#else
int overflow_errno = EIO;
#endif
buffer = (char *)NULL;
buffer = last_ts = (char *)NULL;
input = history_filename (filename);
file = open (input, O_RDONLY|O_BINARY, 0666);
@ -169,37 +188,42 @@ read_history_range (filename, from, to)
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
#if defined (EFBIG)
errno = EFBIG;
#elif defined (EOVERFLOW)
errno = EOVERFLOW;
#endif
errno = overflow_errno;
goto error_and_exit;
}
#ifdef HAVE_MMAP
#ifdef HISTORY_USE_MMAP
/* We map read/write and private so we can change newlines to NULs without
affecting the underlying object. */
buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0);
if ((void *)buffer == MAP_FAILED)
goto error_and_exit;
{
errno = overflow_errno;
goto error_and_exit;
}
chars_read = file_size;
#else
buffer = (char *)malloc (file_size + 1);
if (buffer == 0)
goto error_and_exit;
{
errno = overflow_errno;
goto error_and_exit;
}
chars_read = read (file, buffer, file_size);
#endif
if (chars_read < 0)
{
error_and_exit:
chars_read = errno;
if (errno != 0)
chars_read = errno;
else
chars_read = EIO;
if (file >= 0)
close (file);
FREE (input);
#ifndef HAVE_MMAP
#ifndef HISTORY_USE_MMAP
FREE (buffer);
#endif
@ -220,8 +244,12 @@ read_history_range (filename, from, to)
for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
if (*line_end == '\n')
{
current_line++;
line_start = line_end + 1;
p = line_end + 1;
/* If we see something we think is a timestamp, continue with this
line. We should check more extensively here... */
if (HIST_TIMESTAMP_START(p) == 0)
current_line++;
line_start = p;
}
/* If there are lines left to gobble, then gobble them now. */
@ -234,7 +262,22 @@ read_history_range (filename, from, to)
*line_end = '\0';
if (*line_start)
add_history (line_start);
{
if (HIST_TIMESTAMP_START(line_start) == 0)
{
add_history (line_start);
if (last_ts)
{
add_history_time (last_ts);
last_ts = NULL;
}
}
else
{
last_ts = line_start;
current_line--;
}
}
current_line++;
@ -245,7 +288,7 @@ read_history_range (filename, from, to)
}
FREE (input);
#ifndef HAVE_MMAP
#ifndef HISTORY_USE_MMAP
FREE (buffer);
#else
munmap (buffer, file_size);
@ -262,7 +305,7 @@ history_truncate_file (fname, lines)
const char *fname;
int lines;
{
char *buffer, *filename, *bp;
char *buffer, *filename, *bp, *bp1; /* bp1 == bp+1 */
int file, chars_read, rv;
struct stat finfo;
size_t file_size;
@ -325,11 +368,14 @@ history_truncate_file (fname, lines)
}
/* Count backwards from the end of buffer until we have passed
LINES lines. */
for (bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
LINES lines. bp1 is set funny initially. But since bp[1] can't
be a comment character (since it's off the end) and *bp can't be
both a newline and the history comment character, it should be OK. */
for (bp1 = bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
{
if (*bp == '\n')
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
lines--;
bp1 = bp;
}
/* If this is the first line, then the file contains exactly the
@ -338,11 +384,14 @@ history_truncate_file (fname, lines)
the current value of i and 0. Otherwise, write from the start of
this line until the end of the buffer. */
for ( ; bp > buffer; bp--)
if (*bp == '\n')
{
bp++;
break;
}
{
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
{
bp++;
break;
}
bp1 = bp;
}
/* Write only if there are more lines in the file than we want to
truncate to. */
@ -377,9 +426,9 @@ history_do_write (filename, nelements, overwrite)
register int i;
char *output;
int file, mode, rv;
#ifdef HISTORY_USE_MMAP
size_t cursize;
#ifdef HAVE_MMAP
mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
#else
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
@ -393,7 +442,7 @@ history_do_write (filename, nelements, overwrite)
return (errno);
}
#ifdef HAVE_MMAP
#ifdef HISTORY_USE_MMAP
cursize = overwrite ? 0 : lseek (file, 0, SEEK_END);
#endif
@ -411,10 +460,18 @@ history_do_write (filename, nelements, overwrite)
the_history = history_list ();
/* Calculate the total number of bytes to write. */
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
buffer_size += 1 + strlen (the_history[i]->line);
#if 0
buffer_size += 2 + HISTENT_BYTES (the_history[i]);
#else
{
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
buffer_size += strlen (the_history[i]->timestamp) + 1;
buffer_size += strlen (the_history[i]->line) + 1;
}
#endif
/* Allocate the buffer, and fill it. */
#ifdef HAVE_MMAP
#ifdef HISTORY_USE_MMAP
if (ftruncate (file, buffer_size+cursize) == -1)
goto mmap_error;
buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize);
@ -439,12 +496,18 @@ mmap_error:
for (j = 0, i = history_length - nelements; i < history_length; i++)
{
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
{
strcpy (buffer + j, the_history[i]->timestamp);
j += strlen (the_history[i]->timestamp);
buffer[j++] = '\n';
}
strcpy (buffer + j, the_history[i]->line);
j += strlen (the_history[i]->line);
buffer[j++] = '\n';
}
#ifdef HAVE_MMAP
#ifdef HISTORY_USE_MMAP
if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0)
rv = errno;
#else

View File

@ -1,6 +1,6 @@
/* History.c -- standalone history library */
/* history.c -- standalone history library */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1989-2005 Free Software Foundation, Inc.
This file contains the GNU History Library (the Library), a set of
routines for managing the text of previously typed lines.
@ -52,6 +52,8 @@
/* The number of slots to increase the_history by. */
#define DEFAULT_HISTORY_GROW_SIZE 50
static char *hist_inittime PARAMS((void));
/* **************************************************************** */
/* */
/* History Functions */
@ -123,14 +125,15 @@ using_history ()
}
/* Return the number of bytes that the primary history entries are using.
This just adds up the lengths of the_history->lines. */
This just adds up the lengths of the_history->lines and the associated
timestamps. */
int
history_total_bytes ()
{
register int i, result;
for (i = result = 0; the_history && the_history[i]; i++)
result += strlen (the_history[i]->line);
result += HISTENT_BYTES (the_history[i]);
return (result);
}
@ -201,11 +204,45 @@ history_get (offset)
int local_index;
local_index = offset - history_base;
return (local_index >= history_length || local_index < 0 || !the_history)
return (local_index >= history_length || local_index < 0 || the_history == 0)
? (HIST_ENTRY *)NULL
: the_history[local_index];
}
time_t
history_get_time (hist)
HIST_ENTRY *hist;
{
char *ts;
time_t t;
if (hist == 0 || hist->timestamp == 0)
return 0;
ts = hist->timestamp;
if (ts[0] != history_comment_char)
return 0;
t = (time_t) atol (ts + 1); /* XXX - should use strtol() here */
return t;
}
static char *
hist_inittime ()
{
time_t t;
char ts[64], *ret;
t = (time_t) time ((time_t *)0);
#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
#else
sprintf (ts, "X%lu", (unsigned long) t);
#endif
ret = savestring (ts);
ret[0] = history_comment_char;
return ret;
}
/* Place STRING at the end of the history list. The data field
is set to NULL. */
void
@ -225,10 +262,7 @@ add_history (string)
/* If there is something in the slot, then remove it. */
if (the_history[0])
{
free (the_history[0]->line);
free (the_history[0]);
}
(void) free_history_entry (the_history[0]);
/* Copy the rest of the entries, moving down one slot. */
for (i = 0; i < history_length; i++)
@ -260,10 +294,41 @@ add_history (string)
temp->line = savestring (string);
temp->data = (char *)NULL;
temp->timestamp = hist_inittime ();
the_history[history_length] = (HIST_ENTRY *)NULL;
the_history[history_length - 1] = temp;
}
/* Change the time stamp of the most recent history entry to STRING. */
void
add_history_time (string)
const char *string;
{
HIST_ENTRY *hs;
hs = the_history[history_length - 1];
FREE (hs->timestamp);
hs->timestamp = savestring (string);
}
/* Free HIST and return the data so the calling application can free it
if necessary and desired. */
histdata_t
free_history_entry (hist)
HIST_ENTRY *hist;
{
histdata_t x;
if (hist == 0)
return ((histdata_t) 0);
FREE (hist->line);
FREE (hist->timestamp);
x = hist->data;
free (hist);
return (x);
}
/* Make the history entry at WHICH have LINE and DATA. This returns
the old entry so you can dispose of the data. In the case of an
invalid WHICH, a NULL pointer is returned. */
@ -275,7 +340,7 @@ replace_history_entry (which, line, data)
{
HIST_ENTRY *temp, *old_value;
if (which >= history_length)
if (which < 0 || which >= history_length)
return ((HIST_ENTRY *)NULL);
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
@ -283,6 +348,7 @@ replace_history_entry (which, line, data)
temp->line = savestring (line);
temp->data = data;
temp->timestamp = savestring (old_value->timestamp);
the_history[which] = temp;
return (old_value);
@ -298,17 +364,15 @@ remove_history (which)
HIST_ENTRY *return_value;
register int i;
if (which >= history_length || !history_length)
return_value = (HIST_ENTRY *)NULL;
else
{
return_value = the_history[which];
if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
return ((HIST_ENTRY *)NULL);
for (i = which; i < history_length; i++)
the_history[i] = the_history[i + 1];
return_value = the_history[which];
history_length--;
}
for (i = which; i < history_length; i++)
the_history[i] = the_history[i + 1];
history_length--;
return (return_value);
}
@ -327,10 +391,7 @@ stifle_history (max)
{
/* This loses because we cannot free the data. */
for (i = 0, j = history_length - max; i < j; i++)
{
free (the_history[i]->line);
free (the_history[i]);
}
free_history_entry (the_history[i]);
history_base = i;
for (j = 0, i = history_length - max; j < max; i++, j++)
@ -372,8 +433,7 @@ clear_history ()
/* This loses because we cannot free the data. */
for (i = 0; i < history_length; i++)
{
free (the_history[i]->line);
free (the_history[i]);
free_history_entry (the_history[i]);
the_history[i] = (HIST_ENTRY *)NULL;
}

View File

@ -1,5 +1,5 @@
/* History.h -- the names of functions that you can call in history. */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
/* history.h -- the names of functions that you can call in history. */
/* Copyright (C) 1989-2003 Free Software Foundation, Inc.
This file contains the GNU History Library (the Library), a set of
routines for managing the text of previously typed lines.
@ -26,6 +26,8 @@
extern "C" {
#endif
#include <time.h> /* XXX - for history timestamp code */
#if defined READLINE_LIBRARY
# include "rlstdc.h"
# include "rltypedefs.h"
@ -43,9 +45,13 @@ typedef char *histdata_t;
/* The structure used to store a history entry. */
typedef struct _hist_entry {
char *line;
char *timestamp; /* char * rather than time_t for read/write */
histdata_t data;
} HIST_ENTRY;
/* Size of the history-library-managed space in history entry HS. */
#define HISTENT_BYTES(hs) (strlen ((hs)->line) + strlen ((hs)->timestamp))
/* A structure used to pass the current state of the history stuff around. */
typedef struct _hist_state {
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
@ -76,11 +82,19 @@ extern void history_set_history_state PARAMS((HISTORY_STATE *));
The associated data field (if any) is set to NULL. */
extern void add_history PARAMS((const char *));
/* Change the timestamp associated with the most recent history entry to
STRING. */
extern void add_history_time PARAMS((const char *));
/* A reasonably useless function, only here for completeness. WHICH
is the magic number that tells us which element to delete. The
elements are numbered from 0. */
extern HIST_ENTRY *remove_history PARAMS((int));
/* Free the history entry H and return any application-specific data
associated with it. */
extern histdata_t free_history_entry PARAMS((HIST_ENTRY *));
/* Make the history entry at WHICH have LINE and DATA. This returns
the old entry so you can dispose of the data. In the case of an
invalid WHICH, a NULL pointer is returned. */
@ -119,6 +133,10 @@ extern HIST_ENTRY *current_history PARAMS((void));
array. OFFSET is relative to history_base. */
extern HIST_ENTRY *history_get PARAMS((int));
/* Return the timestamp associated with the HIST_ENTRY * passed as an
argument */
extern time_t history_get_time PARAMS((HIST_ENTRY *));
/* Return the number of bytes that the primary history entries are using.
This just adds up the lengths of the_history->lines. */
extern int history_total_bytes PARAMS((void));
@ -231,6 +249,8 @@ extern char *history_no_expand_chars;
extern char *history_search_delimiter_chars;
extern int history_quotes_inhibit_expansion;
extern int history_write_timestamps;
/* Backwards compatibility */
extern int max_input_history;

View File

@ -77,11 +77,11 @@ history_search_internal (string, direction, anchored)
if (string == 0 || *string == '\0')
return (-1);
if (!history_length || ((i == history_length) && !reverse))
if (!history_length || ((i >= history_length) && !reverse))
return (-1);
if (reverse && (i == history_length))
i--;
if (reverse && (i >= history_length))
i = history_length - 1;
#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)

View File

@ -1,6 +1,6 @@
/* input.c -- character input functions for readline. */
/* Copyright (C) 1994 Free Software Foundation, Inc.
/* Copyright (C) 1994-2005 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.
@ -21,6 +21,10 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (__TANDEM)
# include <floss.h>
#endif
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
@ -154,6 +158,12 @@ _rl_unget_char (key)
return (0);
}
int
_rl_pushed_input_available ()
{
return (push_index != pop_index);
}
/* If a character is available to be read, then read it and stuff it into
IBUFFER. Otherwise, just return. Returns number of characters read
(0 if none available) and -1 on error (EIO). */
@ -162,7 +172,7 @@ rl_gather_tyi ()
{
int tty;
register int tem, result;
int chars_avail;
int chars_avail, k;
char input;
#if defined(HAVE_SELECT)
fd_set readfds, exceptfds;
@ -202,9 +212,24 @@ rl_gather_tyi ()
fcntl (tty, F_SETFL, tem);
if (chars_avail == -1 && errno == EAGAIN)
return 0;
if (chars_avail == 0) /* EOF */
{
rl_stuff_char (EOF);
return (0);
}
}
#endif /* O_NDELAY */
#if defined (__MINGW32__)
/* We use getch to read console input, so use the same
mechanism to check for more. Otherwise, we don't know. */
if (isatty (fileno (rl_instream)))
chars_avail = _kbhit ();
else
chars_avail = 0;
result = 0;
#endif
/* If there's nothing available, don't waste time trying to read
something. */
if (chars_avail <= 0)
@ -225,7 +250,12 @@ rl_gather_tyi ()
if (result != -1)
{
while (chars_avail--)
rl_stuff_char ((*rl_getc_function) (rl_instream));
{
k = (*rl_getc_function) (rl_instream);
rl_stuff_char (k);
if (k == NEWLINE || k == RETURN)
break;
}
}
else
{
@ -283,6 +313,13 @@ _rl_input_available ()
return (chars_avail);
#endif
#endif
#if defined (__MINGW32__)
/* We use getch to read console input, so use the same
mechanism to check for more. Otherwise, we don't know. */
if (isatty (fileno (rl_instream)))
return _kbhit ();
#endif
return 0;
@ -424,12 +461,9 @@ rl_getc (stream)
while (1)
{
#ifdef __MINGW32__
/* On Windows, use a special routine to read a single character
from the console. (Otherwise, no characters are available
until the user hits the return key.) */
#if defined (__MINGW32__)
if (isatty (fileno (stream)))
return getch ();
return (getch ());
#endif
result = read (fileno (stream), &c, sizeof (unsigned char));
@ -506,6 +540,12 @@ _rl_read_mbchar (mbchar, size)
ps = ps_back;
continue;
}
else if (mbchar_bytes_length == 0)
{
mbchar[0] = '\0'; /* null wide character */
mb_len = 1;
break;
}
else if (mbchar_bytes_length > (size_t)(0))
break;
}

View File

@ -4,7 +4,7 @@
/* */
/* **************************************************************** */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 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
@ -56,12 +56,17 @@
/* Variables exported to other files in the readline library. */
char *_rl_isearch_terminators = (char *)NULL;
_rl_search_cxt *_rl_iscxt = 0;
/* Variables imported from other files in the readline library. */
extern HIST_ENTRY *_rl_saved_line_for_history;
/* Forward declarations */
static int rl_search_history PARAMS((int, int));
static _rl_search_cxt *_rl_isearch_init PARAMS((int));
static void _rl_isearch_fini PARAMS((_rl_search_cxt *));
static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
/* Last line found by the current incremental search, so we don't `find'
identical lines many times in a row. */
static char *prev_line_found;
@ -72,6 +77,57 @@ static int last_isearch_string_len;
static char *default_isearch_terminators = "\033\012";
_rl_search_cxt *
_rl_scxt_alloc (type, flags)
int type, flags;
{
_rl_search_cxt *cxt;
cxt = (_rl_search_cxt *)xmalloc (sizeof (_rl_search_cxt));
cxt->type = type;
cxt->sflags = flags;
cxt->search_string = 0;
cxt->search_string_size = cxt->search_string_index = 0;
cxt->lines = 0;
cxt->allocated_line = 0;
cxt->hlen = cxt->hindex = 0;
cxt->save_point = rl_point;
cxt->save_mark = rl_mark;
cxt->save_line = where_history ();
cxt->last_found_line = cxt->save_line;
cxt->prev_line_found = 0;
cxt->save_undo_list = 0;
cxt->history_pos = 0;
cxt->direction = 0;
cxt->lastc = 0;
cxt->sline = 0;
cxt->sline_len = cxt->sline_index = 0;
cxt->search_terminators = 0;
return cxt;
}
void
_rl_scxt_dispose (cxt, flags)
_rl_search_cxt *cxt;
int flags;
{
FREE (cxt->search_string);
FREE (cxt->allocated_line);
FREE (cxt->lines);
free (cxt);
}
/* Search backwards through the history looking for a string which is typed
interactively. Start with the current line. */
int
@ -92,7 +148,7 @@ rl_forward_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,
DIRECTION is zero for forward, or non-zero 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
@ -140,6 +196,418 @@ rl_display_search (search_string, reverse_p, where)
(*rl_redisplay_function) ();
}
static _rl_search_cxt *
_rl_isearch_init (direction)
int direction;
{
_rl_search_cxt *cxt;
register int i;
HIST_ENTRY **hlist;
cxt = _rl_scxt_alloc (RL_SEARCH_ISEARCH, 0);
if (direction < 0)
cxt->sflags |= SF_REVERSE;
cxt->search_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
: default_isearch_terminators;
/* Create an arrary of pointers to the lines that we want to search. */
hlist = history_list ();
rl_maybe_replace_line ();
i = 0;
if (hlist)
for (i = 0; hlist[i]; i++);
/* Allocate space for this many lines, +1 for the current input line,
and remember those lines. */
cxt->lines = (char **)xmalloc ((1 + (cxt->hlen = i)) * sizeof (char *));
for (i = 0; i < cxt->hlen; i++)
cxt->lines[i] = hlist[i]->line;
if (_rl_saved_line_for_history)
cxt->lines[i] = _rl_saved_line_for_history->line;
else
{
/* Keep track of this so we can free it. */
cxt->allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
strcpy (cxt->allocated_line, &rl_line_buffer[0]);
cxt->lines[i] = cxt->allocated_line;
}
cxt->hlen++;
/* The line where we start the search. */
cxt->history_pos = cxt->save_line;
rl_save_prompt ();
/* Initialize search parameters. */
cxt->search_string = (char *)xmalloc (cxt->search_string_size = 128);
cxt->search_string[cxt->search_string_index = 0] = '\0';
/* Normalize DIRECTION into 1 or -1. */
cxt->direction = (direction >= 0) ? 1 : -1;
cxt->sline = rl_line_buffer;
cxt->sline_len = strlen (cxt->sline);
cxt->sline_index = rl_point;
_rl_iscxt = cxt; /* save globally */
return cxt;
}
static void
_rl_isearch_fini (cxt)
_rl_search_cxt *cxt;
{
/* First put back the original state. */
strcpy (rl_line_buffer, cxt->lines[cxt->save_line]);
rl_restore_prompt ();
/* Save the search string for possible later use. */
FREE (last_isearch_string);
last_isearch_string = cxt->search_string;
last_isearch_string_len = cxt->search_string_index;
cxt->search_string = 0;
if (cxt->last_found_line < cxt->save_line)
rl_get_previous_history (cxt->save_line - cxt->last_found_line, 0);
else
rl_get_next_history (cxt->last_found_line - cxt->save_line, 0);
/* If the string was not found, put point at the end of the last matching
line. If last_found_line == orig_line, we didn't find any matching
history lines at all, so put point back in its original position. */
if (cxt->sline_index < 0)
{
if (cxt->last_found_line == cxt->save_line)
cxt->sline_index = cxt->save_point;
else
cxt->sline_index = strlen (rl_line_buffer);
rl_mark = cxt->save_mark;
}
rl_point = cxt->sline_index;
/* Don't worry about where to put the mark here; rl_get_previous_history
and rl_get_next_history take care of it. */
rl_clear_message ();
}
int
_rl_search_getchar (cxt)
_rl_search_cxt *cxt;
{
int c;
/* Read a key and decide how to proceed. */
RL_SETSTATE(RL_STATE_MOREINPUT);
c = cxt->lastc = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX);
#endif
return c;
}
/* Process just-read character C according to isearch context CXT. Return
-1 if the caller should just free the context and return, 0 if we should
break out of the loop, and 1 if we should continue to read characters. */
int
_rl_isearch_dispatch (cxt, c)
_rl_search_cxt *cxt;
int c;
{
int n, wstart, wlen, limit, cval;
rl_command_func_t *f;
f = (rl_command_func_t *)NULL;
/* Translate the keys we do something with to opcodes. */
if (c >= 0 && _rl_keymap[c].type == ISFUNC)
{
f = _rl_keymap[c].function;
if (f == rl_reverse_search_history)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
else if (f == rl_forward_search_history)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -2 : -1;
else if (f == rl_rubout)
cxt->lastc = -3;
else if (c == CTRL ('G'))
cxt->lastc = -4;
else if (c == CTRL ('W')) /* XXX */
cxt->lastc = -5;
else if (c == CTRL ('Y')) /* XXX */
cxt->lastc = -6;
}
/* The characters in isearch_terminators (set from the user-settable
variable isearch-terminators) are used to terminate the search but
not subsequently execute the character as a command. The default
value is "\033\012" (ESC and C-J). */
if (strchr (cxt->search_terminators, cxt->lastc))
{
/* ESC still terminates the search, but if there is pending
input or if input arrives within 0.1 seconds (on systems
with select(2)) it is used as a prefix character
with rl_execute_next. WATCH OUT FOR THIS! This is intended
to allow the arrow keys to be used like ^F and ^B are used
to terminate the search and execute the movement command.
XXX - since _rl_input_available depends on the application-
settable keyboard timeout value, this could alternatively
use _rl_input_queued(100000) */
if (cxt->lastc == ESC && _rl_input_available ())
rl_execute_next (ESC);
return (0);
}
#define ENDSRCH_CHAR(c) \
((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
if (cxt->lastc >= 0 && (cxt->mb[0] && cxt->mb[1] == '\0') && ENDSRCH_CHAR (cxt->lastc))
{
/* This sets rl_pending_input to c; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (cxt->lastc);
return (0);
}
}
else
#endif
if (cxt->lastc >= 0 && ENDSRCH_CHAR (cxt->lastc))
{
/* This sets rl_pending_input to LASTC; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (cxt->lastc);
return (0);
}
/* Now dispatch on the character. `Opcodes' affect the search string or
state. Other characters are added to the string. */
switch (cxt->lastc)
{
/* search again */
case -1:
if (cxt->search_string_index == 0)
{
if (last_isearch_string)
{
cxt->search_string_size = 64 + last_isearch_string_len;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
strcpy (cxt->search_string, last_isearch_string);
cxt->search_string_index = last_isearch_string_len;
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
break;
}
return (1);
}
else if (cxt->sflags & SF_REVERSE)
cxt->sline_index--;
else if (cxt->sline_index != cxt->sline_len)
cxt->sline_index++;
else
rl_ding ();
break;
/* switch directions */
case -2:
cxt->direction = -cxt->direction;
if (cxt->direction < 0)
cxt->sflags |= SF_REVERSE;
else
cxt->sflags &= ~SF_REVERSE;
break;
/* delete character from search string. */
case -3: /* C-H, DEL */
/* This is tricky. To do this right, we need to keep a
stack of search positions for the current search, with
sentinels marking the beginning and end. But this will
do until we have a real isearch-undo. */
if (cxt->search_string_index == 0)
rl_ding ();
else
cxt->search_string[--cxt->search_string_index] = '\0';
break;
case -4: /* C-G, abort */
rl_replace_line (cxt->lines[cxt->save_line], 0);
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
rl_restore_prompt();
rl_clear_message ();
return -1;
case -5: /* C-W */
/* skip over portion of line we already matched and yank word */
wstart = rl_point + cxt->search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
/* if not in a word, move to one. */
cval = _rl_char_value (rl_line_buffer, wstart);
if (_rl_walphabetic (cval) == 0)
{
rl_ding ();
break;
}
n = MB_NEXTCHAR (rl_line_buffer, wstart, 1, MB_FIND_NONZERO);;
while (n < rl_end)
{
cval = _rl_char_value (rl_line_buffer, n);
if (_rl_walphabetic (cval) == 0)
break;
n = MB_NEXTCHAR (rl_line_buffer, n, 1, MB_FIND_NONZERO);;
}
wlen = n - wstart + 1;
if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size)
{
cxt->search_string_size += wlen + 1;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
for (; wstart < n; wstart++)
cxt->search_string[cxt->search_string_index++] = rl_line_buffer[wstart];
cxt->search_string[cxt->search_string_index] = '\0';
break;
case -6: /* C-Y */
/* skip over portion of line we already matched and yank rest */
wstart = rl_point + cxt->search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
n = rl_end - wstart + 1;
if (cxt->search_string_index + n + 1 >= cxt->search_string_size)
{
cxt->search_string_size += n + 1;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
for (n = wstart; n < rl_end; n++)
cxt->search_string[cxt->search_string_index++] = rl_line_buffer[n];
cxt->search_string[cxt->search_string_index] = '\0';
break;
/* Add character to search string and continue search. */
default:
if (cxt->search_string_index + 2 >= cxt->search_string_size)
{
cxt->search_string_size += 128;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int j, l;
for (j = 0, l = strlen (cxt->mb); j < l; )
cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
}
else
#endif
cxt->search_string[cxt->search_string_index++] = c;
cxt->search_string[cxt->search_string_index] = '\0';
break;
}
for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; )
{
limit = cxt->sline_len - cxt->search_string_index + 1;
/* Search the current line. */
while ((cxt->sflags & SF_REVERSE) ? (cxt->sline_index >= 0) : (cxt->sline_index < limit))
{
if (STREQN (cxt->search_string, cxt->sline + cxt->sline_index, cxt->search_string_index))
{
cxt->sflags |= SF_FOUND;
break;
}
else
cxt->sline_index += cxt->direction;
}
if (cxt->sflags & SF_FOUND)
break;
/* Move to the next line, but skip new copies of the line
we just found and lines shorter than the string we're
searching for. */
do
{
/* Move to the next line. */
cxt->history_pos += cxt->direction;
/* At limit for direction? */
if ((cxt->sflags & SF_REVERSE) ? (cxt->history_pos < 0) : (cxt->history_pos == cxt->hlen))
{
cxt->sflags |= SF_FAILED;
break;
}
/* We will need these later. */
cxt->sline = cxt->lines[cxt->history_pos];
cxt->sline_len = strlen (cxt->sline);
}
while ((cxt->prev_line_found && STREQ (cxt->prev_line_found, cxt->lines[cxt->history_pos])) ||
(cxt->search_string_index > cxt->sline_len));
if (cxt->sflags & SF_FAILED)
break;
/* Now set up the line for searching... */
cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0;
}
if (cxt->sflags & SF_FAILED)
{
/* We cannot find the search string. Ding the bell. */
rl_ding ();
cxt->history_pos = cxt->last_found_line;
return 1;
}
/* 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. */
if (cxt->sflags & SF_FOUND)
{
cxt->prev_line_found = cxt->lines[cxt->history_pos];
rl_replace_line (cxt->lines[cxt->history_pos], 0);
rl_point = cxt->sline_index;
cxt->last_found_line = cxt->history_pos;
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
}
return 1;
}
static int
_rl_isearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;
{
if (r >= 0)
_rl_isearch_fini (cxt);
_rl_scxt_dispose (cxt, 0);
_rl_iscxt = 0;
RL_UNSETSTATE(RL_STATE_ISEARCH);
return (r != 0);
}
/* 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
@ -148,413 +616,51 @@ static int
rl_search_history (direction, invoking_key)
int direction, 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, *allocated_line;
/* The length of LINES. */
int hlen;
/* Where we get LINES from. */
HIST_ENTRY **hlist;
register int i;
int orig_point, orig_mark, orig_line, last_found_line;
int c, found, failed, sline_len;
int n, wstart, wlen;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
#endif
/* The line currently being searched. */
char *sline;
/* Offset in that line. */
int line_index;
/* Non-zero if we are doing a reverse search. */
int reverse;
/* The list of characters which terminate the search, but are not
subsequently executed. If the variable isearch-terminators has
been set, we use that value, otherwise we use ESC and C-J. */
char *isearch_terminators;
_rl_search_cxt *cxt; /* local for now, but saved globally */
int c, r;
RL_SETSTATE(RL_STATE_ISEARCH);
orig_point = rl_point;
orig_mark = rl_mark;
last_found_line = orig_line = where_history ();
reverse = direction < 0;
hlist = history_list ();
allocated_line = (char *)NULL;
cxt = _rl_isearch_init (direction);
isearch_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
: default_isearch_terminators;
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
/* Create an arrary of pointers to the lines that we want to search. */
rl_maybe_replace_line ();
i = 0;
if (hlist)
for (i = 0; hlist[i]; i++);
/* If we are using the callback interface, all we do is set up here and
return. The key is that we leave RL_STATE_ISEARCH set. */
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
/* Allocate space for this many lines, +1 for the current input line,
and remember those lines. */
lines = (char **)xmalloc ((1 + (hlen = i)) * sizeof (char *));
for (i = 0; i < hlen; i++)
lines[i] = hlist[i]->line;
if (_rl_saved_line_for_history)
lines[i] = _rl_saved_line_for_history->line;
else
{
/* Keep track of this so we can free it. */
allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
strcpy (allocated_line, &rl_line_buffer[0]);
lines[i] = allocated_line;
}
hlen++;
/* The line where we start the search. */
i = orig_line;
rl_save_prompt ();
/* Initialize search parameters. */
search_string = (char *)xmalloc (search_string_size = 128);
*search_string = '\0';
search_string_index = 0;
prev_line_found = (char *)0; /* XXX */
/* Normalize DIRECTION into 1 or -1. */
direction = (direction >= 0) ? 1 : -1;
rl_display_search (search_string, reverse, -1);
sline = rl_line_buffer;
sline_len = strlen (sline);
line_index = rl_point;
found = failed = 0;
r = -1;
for (;;)
{
rl_command_func_t *f = (rl_command_func_t *)NULL;
/* Read a key and decide how to proceed. */
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
#endif
/* Translate the keys we do something with to opcodes. */
if (c >= 0 && _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;
else if (f == rl_rubout)
c = -3;
else if (c == CTRL ('G'))
c = -4;
else if (c == CTRL ('W')) /* XXX */
c = -5;
else if (c == CTRL ('Y')) /* XXX */
c = -6;
}
/* The characters in isearch_terminators (set from the user-settable
variable isearch-terminators) are used to terminate the search but
not subsequently execute the character as a command. The default
value is "\033\012" (ESC and C-J). */
if (strchr (isearch_terminators, c))
{
/* ESC still terminates the search, but if there is pending
input or if input arrives within 0.1 seconds (on systems
with select(2)) it is used as a prefix character
with rl_execute_next. WATCH OUT FOR THIS! This is intended
to allow the arrow keys to be used like ^F and ^B are used
to terminate the search and execute the movement command.
XXX - since _rl_input_available depends on the application-
settable keyboard timeout value, this could alternatively
use _rl_input_queued(100000) */
if (c == ESC && _rl_input_available ())
rl_execute_next (ESC);
break;
}
#define ENDSRCH_CHAR(c) \
((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
if (c >= 0 && strlen (mb) == 1 && ENDSRCH_CHAR (c))
{
/* This sets rl_pending_input to c; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (c);
break;
}
}
else
#endif
if (c >= 0 && ENDSRCH_CHAR (c))
{
/* This sets rl_pending_input to c; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (c);
break;
}
switch (c)
{
case -1:
if (search_string_index == 0)
{
if (last_isearch_string)
{
search_string_size = 64 + last_isearch_string_len;
search_string = (char *)xrealloc (search_string, search_string_size);
strcpy (search_string, last_isearch_string);
search_string_index = last_isearch_string_len;
rl_display_search (search_string, reverse, -1);
break;
}
continue;
}
else if (reverse)
--line_index;
else if (line_index != sline_len)
++line_index;
else
rl_ding ();
break;
/* switch directions */
case -2:
direction = -direction;
reverse = direction < 0;
break;
/* delete character from search string. */
case -3: /* C-H, DEL */
/* This is tricky. To do this right, we need to keep a
stack of search positions for the current search, with
sentinels marking the beginning and end. But this will
do until we have a real isearch-undo. */
if (search_string_index == 0)
rl_ding ();
else
search_string[--search_string_index] = '\0';
break;
case -4: /* C-G */
rl_replace_line (lines[orig_line], 0);
rl_point = orig_point;
rl_mark = orig_mark;
rl_restore_prompt();
rl_clear_message ();
if (allocated_line)
free (allocated_line);
free (lines);
RL_UNSETSTATE(RL_STATE_ISEARCH);
return 0;
case -5: /* C-W */
/* skip over portion of line we already matched */
wstart = rl_point + search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
/* if not in a word, move to one. */
if (rl_alphabetic(rl_line_buffer[wstart]) == 0)
{
rl_ding ();
break;
}
n = wstart;
while (n < rl_end && rl_alphabetic(rl_line_buffer[n]))
n++;
wlen = n - wstart + 1;
if (search_string_index + wlen + 1 >= search_string_size)
{
search_string_size += wlen + 1;
search_string = (char *)xrealloc (search_string, search_string_size);
}
for (; wstart < n; wstart++)
search_string[search_string_index++] = rl_line_buffer[wstart];
search_string[search_string_index] = '\0';
break;
case -6: /* C-Y */
/* skip over portion of line we already matched */
wstart = rl_point + search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
n = rl_end - wstart + 1;
if (search_string_index + n + 1 >= search_string_size)
{
search_string_size += n + 1;
search_string = (char *)xrealloc (search_string, search_string_size);
}
for (n = wstart; n < rl_end; n++)
search_string[search_string_index++] = rl_line_buffer[n];
search_string[search_string_index] = '\0';
break;
default:
/* Add character to search string and continue search. */
if (search_string_index + 2 >= search_string_size)
{
search_string_size += 128;
search_string = (char *)xrealloc (search_string, search_string_size);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int j, l;
for (j = 0, l = strlen (mb); j < l; )
search_string[search_string_index++] = mb[j++];
}
else
#endif
search_string[search_string_index++] = c;
search_string[search_string_index] = '\0';
break;
}
for (found = failed = 0;;)
{
int limit = sline_len - search_string_index + 1;
/* Search the current line. */
while (reverse ? (line_index >= 0) : (line_index < limit))
{
if (STREQN (search_string, sline + line_index, search_string_index))
{
found++;
break;
}
else
line_index += direction;
}
if (found)
break;
/* Move to the next line, but skip new copies of the line
we just found and lines shorter than the string we're
searching for. */
do
{
/* Move to the next line. */
i += direction;
/* At limit for direction? */
if (reverse ? (i < 0) : (i == hlen))
{
failed++;
break;
}
/* We will need these later. */
sline = lines[i];
sline_len = strlen (sline);
}
while ((prev_line_found && STREQ (prev_line_found, lines[i])) ||
(search_string_index > sline_len));
if (failed)
break;
/* Now set up the line for searching... */
line_index = reverse ? sline_len - search_string_index : 0;
}
if (failed)
{
/* We cannot find the search string. Ding the bell. */
rl_ding ();
i = last_found_line;
continue; /* XXX - was break */
}
/* 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. */
if (found)
{
prev_line_found = lines[i];
rl_replace_line (lines[i], 0);
rl_point = line_index;
last_found_line = i;
rl_display_search (search_string, reverse, (i == orig_line) ? -1 : i);
}
c = _rl_search_getchar (cxt);
/* We might want to handle EOF here (c == 0) */
r = _rl_isearch_dispatch (cxt, cxt->lastc);
if (r <= 0)
break;
}
/* 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
LINE_INDEX is -1, then that shows that the string searched for was
not found. We use this to determine where to place rl_point. */
/* First put back the original state. */
strcpy (rl_line_buffer, lines[orig_line]);
rl_restore_prompt ();
/* Save the search string for possible later use. */
FREE (last_isearch_string);
last_isearch_string = search_string;
last_isearch_string_len = search_string_index;
if (last_found_line < orig_line)
rl_get_previous_history (orig_line - last_found_line, 0);
else
rl_get_next_history (last_found_line - orig_line, 0);
/* If the string was not found, put point at the end of the last matching
line. If last_found_line == orig_line, we didn't find any matching
history lines at all, so put point back in its original position. */
if (line_index < 0)
{
if (last_found_line == orig_line)
line_index = orig_point;
else
line_index = strlen (rl_line_buffer);
rl_mark = orig_mark;
}
rl_point = line_index;
/* Don't worry about where to put the mark here; rl_get_previous_history
and rl_get_next_history take care of it. */
rl_clear_message ();
FREE (allocated_line);
free (lines);
RL_UNSETSTATE(RL_STATE_ISEARCH);
return 0;
return (_rl_isearch_cleanup (cxt, r));
}
#if defined (READLINE_CALLBACKS)
/* Called from the callback functions when we are ready to read a key. The
callback functions know to call this because RL_ISSTATE(RL_STATE_ISEARCH).
If _rl_isearch_dispatch finishes searching, this function is responsible
for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */
int
_rl_isearch_callback (cxt)
_rl_search_cxt *cxt;
{
int c, r;
c = _rl_search_getchar (cxt);
/* We might want to handle EOF here */
r = _rl_isearch_dispatch (cxt, cxt->lastc);
return (r <= 0) ? _rl_isearch_cleanup (cxt, r) : 0;
}
#endif

View File

@ -64,11 +64,13 @@ rl_make_bare_keymap ()
keymap[i].function = (rl_command_func_t *)NULL;
}
#if 0
for (i = 'A'; i < ('Z' + 1); i++)
{
keymap[i].type = ISFUNC;
keymap[i].function = rl_do_lowercase_version;
}
#endif
return (keymap);
}
@ -79,8 +81,9 @@ rl_copy_keymap (map)
Keymap map;
{
register int i;
Keymap temp = rl_make_bare_keymap ();
Keymap temp;
temp = rl_make_bare_keymap ();
for (i = 0; i < KEYMAP_SIZE; i++)
{
temp[i].type = map[i].type;
@ -109,12 +112,8 @@ rl_make_keymap ()
newmap[CTRL('H')].function = rl_rubout;
#if KEYMAP_SIZE > 128
/* Printing characters in some 8-bit character sets. */
for (i = 128; i < 160; i++)
newmap[i].function = rl_insert;
/* ISO Latin-1 printing characters should self-insert. */
for (i = 160; i < 256; i++)
/* Printing characters in ISO Latin-1 and some 8-bit character sets. */
for (i = 128; i < 256; i++)
newmap[i].function = rl_insert;
#endif /* KEYMAP_SIZE > 128 */

View File

@ -339,6 +339,47 @@ rl_unix_word_rubout (count, key)
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* This deletes one filename component in a Unix pathname. That is, it
deletes backward to directory separator (`/') or whitespace. */
int
rl_unix_filename_rubout (count, key)
int count, key;
{
int orig_point, c;
if (rl_point == 0)
rl_ding ();
else
{
orig_point = rl_point;
if (count <= 0)
count = 1;
while (count--)
{
c = rl_line_buffer[rl_point - 1];
while (rl_point && (whitespace (c) || c == '/'))
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
while (rl_point && (whitespace (c) == 0) && c != '/')
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
}
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}

View File

@ -100,6 +100,8 @@ _rl_with_macro_input (string)
int
_rl_next_macro_key ()
{
int c;
if (rl_executing_macro == 0)
return (0);
@ -109,7 +111,14 @@ _rl_next_macro_key ()
return (_rl_next_macro_key ());
}
#if defined (READLINE_CALLBACKS)
c = rl_executing_macro[executing_macro_index++];
if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD) && rl_executing_macro[executing_macro_index] == 0)
_rl_pop_executing_macro ();
return c;
#else
return (rl_executing_macro[executing_macro_index++]);
#endif
}
/* Save the currently executing macro on a stack of saved macros. */

View File

@ -1,6 +1,6 @@
/* mbutil.c -- readline multibyte character utility functions */
/* Copyright (C) 2001 Free Software Foundation, Inc.
/* Copyright (C) 2001-2005 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.
@ -77,27 +77,29 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
char *string;
int seed, count, find_non_zero;
{
size_t tmp = 0;
size_t tmp;
mbstate_t ps;
int point = 0;
int point;
wchar_t wc;
tmp = 0;
memset(&ps, 0, sizeof (mbstate_t));
if (seed < 0)
seed = 0;
if (count <= 0)
return seed;
point = seed + _rl_adjust_point(string, seed, &ps);
point = seed + _rl_adjust_point (string, seed, &ps);
/* if this is true, means that seed was not pointed character
started byte. So correct the point and consume count */
if (seed < point)
count --;
count--;
while (count > 0)
{
tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps);
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
if (MB_INVALIDCH ((size_t)tmp))
{
/* invalid bytes. asume a byte represents a character */
point++;
@ -105,9 +107,8 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
/* reset states. */
memset(&ps, 0, sizeof(mbstate_t));
}
else if (tmp == (size_t)0)
/* found '\0' char */
break;
else if (MB_NULLWCH (tmp))
break; /* found wide '\0' */
else
{
/* valid bytes */
@ -127,15 +128,16 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
if (find_non_zero)
{
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
while (wcwidth (wc) == 0)
while (tmp > 0 && wcwidth (wc) == 0)
{
point += tmp;
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
if (tmp == (size_t)(0) || tmp == (size_t)(-1) || tmp == (size_t)(-2))
if (MB_NULLWCH (tmp) || MB_INVALIDCH (tmp))
break;
}
}
return point;
return point;
}
static int
@ -160,7 +162,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero)
while (point < seed)
{
tmp = mbrtowc (&wc, string + point, length - point, &ps);
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
if (MB_INVALIDCH ((size_t)tmp))
{
/* in this case, bytes are invalid or shorted to compose
multibyte char, so assume that the first byte represents
@ -169,8 +171,12 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero)
/* clear the state of the byte sequence, because
in this case effect of mbstate is undefined */
memset(&ps, 0, sizeof (mbstate_t));
/* Since we're assuming that this byte represents a single
non-zero-width character, don't forget about it. */
prev = point;
}
else if (tmp == 0)
else if (MB_NULLWCH (tmp))
break; /* Found '\0' char. Can this happen? */
else
{
@ -273,7 +279,7 @@ _rl_adjust_point(string, point, ps)
while (pos < point)
{
tmp = mbrlen (string + pos, length - pos, ps);
if((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
if (MB_INVALIDCH ((size_t)tmp))
{
/* in this case, bytes are invalid or shorted to compose
multibyte char, so assume that the first byte represents
@ -284,7 +290,7 @@ _rl_adjust_point(string, point, ps)
if (ps)
memset (ps, 0, sizeof (mbstate_t));
}
else if (tmp == 0)
else if (MB_NULLWCH (tmp))
pos++;
else
pos += tmp;
@ -310,6 +316,28 @@ _rl_is_mbchar_matched (string, seed, end, mbchar, length)
return 0;
return 1;
}
wchar_t
_rl_char_value (buf, ind)
char *buf;
int ind;
{
size_t tmp;
wchar_t wc;
mbstate_t ps;
int l;
if (MB_LEN_MAX == 1 || rl_byte_oriented)
return ((wchar_t) buf[ind]);
l = strlen (buf);
if (ind >= l - 1)
return ((wchar_t) buf[ind]);
memset (&ps, 0, sizeof (mbstate_t));
tmp = mbrtowc (&wc, buf + ind, l - ind, &ps);
if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))
return ((wchar_t) buf[ind]);
return wc;
}
#endif /* HANDLE_MULTIBYTE */
/* Find next `count' characters started byte point of the specified seed.

View File

@ -1,6 +1,6 @@
/* misc.c -- miscellaneous bindable readline functions. */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 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.
@ -63,6 +63,8 @@ void _rl_free_history_entry PARAMS((HIST_ENTRY *));
to preserve the value of rl_point from line to line. */
int _rl_history_preserve_point = 0;
_rl_arg_cxt _rl_argcxt;
/* Saved target point for when _rl_history_preserve_point is set. Special
value of -1 means that point is at the end of the line. */
int _rl_history_saved_point = -1;
@ -73,77 +75,74 @@ int _rl_history_saved_point = -1;
/* */
/* **************************************************************** */
/* Handle C-u style numeric args, as well as M--, and M-digits. */
static int
rl_digit_loop ()
int
_rl_arg_overflow ()
{
int key, c, sawminus, sawdigits;
rl_save_prompt ();
RL_SETSTATE(RL_STATE_NUMERICARG);
sawminus = sawdigits = 0;
while (1)
if (rl_numeric_arg > 1000000)
{
if (rl_numeric_arg > 1000000)
_rl_argcxt = 0;
rl_explicit_arg = rl_numeric_arg = 0;
rl_ding ();
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return 1;
}
return 0;
}
void
_rl_arg_init ()
{
rl_save_prompt ();
_rl_argcxt = 0;
RL_SETSTATE(RL_STATE_NUMERICARG);
}
int
_rl_arg_getchar ()
{
int c;
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
return c;
}
/* Process C as part of the current numeric argument. Return -1 if the
argument should be aborted, 0 if we should not read any more chars, and
1 if we should continue to read chars. */
int
_rl_arg_dispatch (cxt, c)
_rl_arg_cxt cxt;
int c;
{
int key, r;
key = c;
/* If we see a key bound to `universal-argument' after seeing digits,
it ends the argument but is otherwise ignored. */
if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
{
if ((cxt & NUM_SAWDIGITS) == 0)
{
sawdigits = rl_explicit_arg = rl_numeric_arg = 0;
rl_ding ();
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
rl_numeric_arg *= 4;
return 1;
}
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
RL_SETSTATE(RL_STATE_MOREINPUT);
key = c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (c < 0)
{
_rl_abort_internal ();
return -1;
}
/* If we see a key bound to `universal-argument' after seeing digits,
it ends the argument but is otherwise ignored. */
if (_rl_keymap[c].type == ISFUNC &&
_rl_keymap[c].function == rl_universal_argument)
{
if (sawdigits == 0)
{
rl_numeric_arg *= 4;
continue;
}
else
{
RL_SETSTATE(RL_STATE_MOREINPUT);
key = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return (_rl_dispatch (key, _rl_keymap));
}
}
c = UNMETA (c);
if (_rl_digit_p (c))
{
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0';
sawdigits = rl_explicit_arg = 1;
}
else if (c == '-' && rl_explicit_arg == 0)
{
rl_numeric_arg = sawminus = 1;
rl_arg_sign = -1;
}
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_argcxt |= NUM_READONE;
return 0; /* XXX */
}
else
{
/* Make M-- command equivalent to M--1 command. */
if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0)
rl_explicit_arg = 1;
RL_SETSTATE(RL_STATE_MOREINPUT);
key = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
@ -151,35 +150,96 @@ rl_digit_loop ()
}
}
/*NOTREACHED*/
c = UNMETA (c);
if (_rl_digit_p (c))
{
r = _rl_digit_value (c);
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r;
rl_explicit_arg = 1;
_rl_argcxt |= NUM_SAWDIGITS;
}
else if (c == '-' && rl_explicit_arg == 0)
{
rl_numeric_arg = 1;
_rl_argcxt |= NUM_SAWMINUS;
rl_arg_sign = -1;
}
else
{
/* Make M-- command equivalent to M--1 command. */
if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
rl_explicit_arg = 1;
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
r = _rl_dispatch (key, _rl_keymap);
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
/* At worst, this will cause an extra redisplay. Otherwise,
we have to wait until the next character comes in. */
if (rl_done == 0)
(*rl_redisplay_function) ();
r = 0;
}
return r;
}
return 1;
}
/* Add the current digit to the argument in progress. */
/* Handle C-u style numeric args, as well as M--, and M-digits. */
static int
rl_digit_loop ()
{
int c, r;
while (1)
{
if (_rl_arg_overflow ())
return 1;
c = _rl_arg_getchar ();
if (c < 0)
{
_rl_abort_internal ();
return -1;
}
r = _rl_arg_dispatch (_rl_argcxt, c);
if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
break;
}
}
/* Create a default argument. */
void
_rl_reset_argument ()
{
rl_numeric_arg = rl_arg_sign = 1;
rl_explicit_arg = 0;
_rl_argcxt = 0;
}
/* Start a numeric argument with initial value KEY */
int
rl_digit_argument (ignore, key)
int ignore, key;
{
rl_execute_next (key);
return (rl_digit_loop ());
}
/* What to do when you abort reading an argument. */
int
rl_discard_argument ()
{
rl_ding ();
rl_clear_message ();
_rl_init_argument ();
return 0;
}
/* Create a default argument. */
int
_rl_init_argument ()
{
rl_numeric_arg = rl_arg_sign = 1;
rl_explicit_arg = 0;
return 0;
_rl_arg_init ();
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_arg_dispatch (_rl_argcxt, key);
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
return 0;
}
else
{
rl_execute_next (key);
return (rl_digit_loop ());
}
}
/* C-u, universal argument. Multiply the current argument by 4.
@ -189,8 +249,43 @@ int
rl_universal_argument (count, key)
int count, key;
{
_rl_arg_init ();
rl_numeric_arg *= 4;
return (rl_digit_loop ());
return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
}
int
_rl_arg_callback (cxt)
_rl_arg_cxt cxt;
{
int c, r;
c = _rl_arg_getchar ();
if (_rl_argcxt & NUM_READONE)
{
_rl_argcxt &= ~NUM_READONE;
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
rl_execute_next (c);
return 0;
}
r = _rl_arg_dispatch (cxt, c);
return (r != 1);
}
/* What to do when you abort reading an argument. */
int
rl_discard_argument ()
{
rl_ding ();
rl_clear_message ();
_rl_reset_argument ();
return 0;
}
/* **************************************************************** */
@ -225,8 +320,10 @@ _rl_free_history_entry (entry)
{
if (entry == 0)
return;
if (entry->line)
free (entry->line);
FREE (entry->line);
FREE (entry->timestamp);
free (entry);
}
@ -242,6 +339,7 @@ rl_maybe_replace_line ()
{
temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
free (temp->line);
FREE (temp->timestamp);
free (temp);
}
return 0;
@ -253,6 +351,8 @@ rl_maybe_unsave_line ()
{
if (_rl_saved_line_for_history)
{
/* Can't call with `1' because rl_undo_list might point to an undo
list from a history entry, as in rl_replace_from_history() below. */
rl_replace_line (_rl_saved_line_for_history->line, 0);
rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
_rl_free_history_entry (_rl_saved_line_for_history);
@ -272,8 +372,10 @@ rl_maybe_save_line ()
{
_rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
_rl_saved_line_for_history->timestamp = (char *)NULL;
_rl_saved_line_for_history->data = (char *)rl_undo_list;
}
return 0;
}
@ -298,7 +400,7 @@ _rl_history_set_point ()
rl_point = rl_end;
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
rl_point = 0;
#endif /* VI_MODE */
@ -311,6 +413,8 @@ rl_replace_from_history (entry, flags)
HIST_ENTRY *entry;
int flags; /* currently unused */
{
/* Can't call with `1' because rl_undo_list might point to an undo list
from a history entry, just like we're setting up here. */
rl_replace_line (entry->line, 0);
rl_undo_list = (UNDO_LIST *)entry->data;
rl_point = rl_end;
@ -435,6 +539,7 @@ rl_get_previous_history (count, key)
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
}
return 0;
}

View File

@ -75,6 +75,23 @@ static char *normalize_codeset PARAMS((char *));
static char *find_codeset PARAMS((char *, size_t *));
#endif /* !HAVE_SETLOCALE */
static char *_rl_get_locale_var PARAMS((const char *));
static char *
_rl_get_locale_var (v)
const char *v;
{
char *lspec;
lspec = sh_get_env_value ("LC_ALL");
if (lspec == 0 || *lspec == 0)
lspec = sh_get_env_value (v);
if (lspec == 0 || *lspec == 0)
lspec = sh_get_env_value ("LANG");
return lspec;
}
/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
to decide the defaults for 8-bit character input and output. Returns
1 if we set eight-bit mode. */
@ -84,10 +101,21 @@ _rl_init_eightbit ()
/* If we have setlocale(3), just check the current LC_CTYPE category
value, and go into eight-bit mode if it's not C or POSIX. */
#if defined (HAVE_SETLOCALE)
char *t;
char *lspec, *t;
/* Set the LC_CTYPE locale category from environment variables. */
t = setlocale (LC_CTYPE, "");
lspec = _rl_get_locale_var ("LC_CTYPE");
/* Since _rl_get_locale_var queries the right environment variables,
we query the current locale settings with setlocale(), and, if
that doesn't return anything, we set lspec to the empty string to
force the subsequent call to setlocale() to define the `native'
environment. */
if (lspec == 0 || *lspec == 0)
lspec = setlocale (LC_CTYPE, (char *)NULL);
if (lspec == 0)
lspec = "";
t = setlocale (LC_CTYPE, lspec);
if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0))
{
_rl_meta_flag = 1;
@ -105,9 +133,8 @@ _rl_init_eightbit ()
/* We don't have setlocale. Finesse it. Check the environment for the
appropriate variables and set eight-bit mode if they have the right
values. */
lspec = sh_get_env_value ("LC_ALL");
if (lspec == 0) lspec = sh_get_env_value ("LC_CTYPE");
if (lspec == 0) lspec = sh_get_env_value ("LANG");
lspec = _rl_get_locale_var ("LC_CTYPE");
if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
return (0);
for (i = 0; t && legal_lang_values[i]; i++)

View File

@ -21,6 +21,10 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (__TANDEM)
# include <floss.h>
#endif
#include "rlconf.h"
#if defined (HAVE_CONFIG_H)

View File

@ -25,7 +25,11 @@
#if defined (HAVE_DIRENT_H)
# include <dirent.h>
# define D_NAMLEN(d) (strlen ((d)->d_name))
# if defined (HAVE_STRUCT_DIRENT_D_NAMLEN)
# define D_NAMLEN(d) ((d)->d_namlen)
# else
# define D_NAMLEN(d) (strlen ((d)->d_name))
# endif /* !HAVE_STRUCT_DIRENT_D_NAMLEN */
#else
# if defined (HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
@ -42,11 +46,11 @@
# define D_NAMLEN(d) ((d)->d_namlen)
#endif /* !HAVE_DIRENT_H */
#if defined (STRUCT_DIRENT_HAS_D_INO) && !defined (STRUCT_DIRENT_HAS_D_FILENO)
#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO)
# define d_fileno d_ino
#endif
#if defined (_POSIX_SOURCE) && (!defined (STRUCT_DIRENT_HAS_D_INO) || defined (BROKEN_DIRENT_D_INO))
#if defined (_POSIX_SOURCE) && (!defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO))
/* Posix does not require that the d_ino field be present, and some
systems do not provide it. */
# define REAL_DIR_ENTRY(dp) 1

View File

@ -1,7 +1,7 @@
/* readline.c -- a general facility for reading lines of input
with emacs style editing and completion. */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 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.
@ -68,11 +68,11 @@
#include "xmalloc.h"
#ifndef RL_LIBRARY_VERSION
# define RL_LIBRARY_VERSION "4.3"
# define RL_LIBRARY_VERSION "5.1"
#endif
#ifndef RL_READLINE_VERSION
# define RL_READLINE_VERSION 0x0403
# define RL_READLINE_VERSION 0x0501
#endif
extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
@ -85,6 +85,10 @@ static void bind_arrow_keys_internal PARAMS((Keymap));
static void bind_arrow_keys PARAMS((void));
static void readline_default_bindings PARAMS((void));
static void reset_default_bindings PARAMS((void));
static int _rl_subseq_result PARAMS((int, Keymap, int, int));
static int _rl_subseq_getchar PARAMS((int));
/* **************************************************************** */
/* */
@ -103,6 +107,7 @@ int rl_gnu_readline_p = 1;
By default, it is the standard emacs keymap. */
Keymap _rl_keymap = emacs_standard_keymap;
/* The current style of editing. */
int rl_editing_mode = emacs_mode;
@ -218,6 +223,9 @@ char *_rl_comment_begin;
/* Keymap holding the function currently being executed. */
Keymap rl_executing_keymap;
/* Keymap we're currently using to dispatch. */
Keymap _rl_dispatching_keymap;
/* Non-zero means to erase entire line, including prompt, on empty input lines. */
int rl_erase_empty_line = 0;
@ -229,6 +237,9 @@ int rl_num_chars_to_read;
char *rl_line_buffer = (char *)NULL;
int rl_line_buffer_len = 0;
/* Key sequence `contexts' */
_rl_keyseq_cxt *_rl_kscxt = 0;
/* Forward declarations used by the display, termcap, and history code. */
/* **************************************************************** */
@ -250,6 +261,10 @@ int _rl_convert_meta_chars_to_ascii = 1;
rather than as a meta-prefixed escape sequence. */
int _rl_output_meta_chars = 0;
/* Non-zero means to look at the termios special characters and bind
them to equivalent readline functions at startup. */
int _rl_bind_stty_chars = 1;
/* **************************************************************** */
/* */
/* Top Level Functions */
@ -267,6 +282,7 @@ rl_set_prompt (prompt)
{
FREE (rl_prompt);
rl_prompt = prompt ? savestring (prompt) : (char *)NULL;
rl_display_prompt = rl_prompt ? rl_prompt : "";
rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
return 0;
@ -290,14 +306,16 @@ readline (prompt)
rl_set_prompt (prompt);
rl_initialize ();
(*rl_prep_term_function) (_rl_meta_flag);
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
#if defined (HANDLE_SIGNALS)
rl_set_signals ();
#endif
value = readline_internal ();
(*rl_deprep_term_function) ();
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
rl_clear_signals ();
@ -347,7 +365,7 @@ readline_internal_setup ()
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
rl_vi_insertion_mode (1, 0);
rl_vi_insertion_mode (1, 'i');
#endif /* VI_MODE */
if (rl_pre_input_hook)
@ -387,6 +405,36 @@ readline_internal_teardown (eof)
return (eof ? (char *)NULL : savestring (the_line));
}
void
_rl_internal_char_cleanup ()
{
#if defined (VI_MODE)
/* In vi mode, when you exit insert mode, the cursor moves back
over the previous character. We explicitly check for that here. */
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
rl_vi_check ();
#endif /* VI_MODE */
if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
rl_newline (1, '\n');
}
if (rl_done == 0)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
}
/* If the application writer has told us to erase the entire line if
the only character typed was something bound to rl_newline, do so. */
if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline &&
rl_point == 0 && rl_end == 0)
_rl_erase_entire_line ();
}
STATIC_CALLBACK int
#if defined (READLINE_CALLBACKS)
readline_internal_char ()
@ -409,12 +457,21 @@ readline_internal_charloop ()
code = setjmp (readline_top_level);
if (code)
(*rl_redisplay_function) ();
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
/* If we get here, we're not being called from something dispatched
from _rl_callback_read_char(), which sets up its own value of
readline_top_level (saving and restoring the old, of course), so
we can just return here. */
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
}
if (rl_pending_input == 0)
{
/* Then initialize the argument and number of keys read. */
_rl_init_argument ();
_rl_reset_argument ();
rl_key_sequence_length = 0;
}
@ -448,27 +505,7 @@ readline_internal_charloop ()
if (rl_pending_input == 0 && lk == _rl_last_command_was_kill)
_rl_last_command_was_kill = 0;
#if defined (VI_MODE)
/* In vi mode, when you exit insert mode, the cursor moves back
over the previous character. We explicitly check for that here. */
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
rl_vi_check ();
#endif /* VI_MODE */
if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read)
{
(*rl_redisplay_function) ();
rl_newline (1, '\n');
}
if (rl_done == 0)
(*rl_redisplay_function) ();
/* If the application writer has told us to erase the entire line if
the only character typed was something bound to rl_newline, do so. */
if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline &&
rl_point == 0 && rl_end == 0)
_rl_erase_entire_line ();
_rl_internal_char_cleanup ();
#if defined (READLINE_CALLBACKS)
return 0;
@ -518,6 +555,107 @@ _rl_set_the_line ()
the_line = rl_line_buffer;
}
#if defined (READLINE_CALLBACKS)
_rl_keyseq_cxt *
_rl_keyseq_cxt_alloc ()
{
_rl_keyseq_cxt *cxt;
cxt = (_rl_keyseq_cxt *)xmalloc (sizeof (_rl_keyseq_cxt));
cxt->flags = cxt->subseq_arg = cxt->subseq_retval = 0;
cxt->okey = 0;
cxt->ocxt = _rl_kscxt;
cxt->childval = 42; /* sentinel value */
return cxt;
}
void
_rl_keyseq_cxt_dispose (cxt)
_rl_keyseq_cxt *cxt;
{
free (cxt);
}
void
_rl_keyseq_chain_dispose ()
{
_rl_keyseq_cxt *cxt;
while (_rl_kscxt)
{
cxt = _rl_kscxt;
_rl_kscxt = _rl_kscxt->ocxt;
_rl_keyseq_cxt_dispose (cxt);
}
}
#endif
static int
_rl_subseq_getchar (key)
int key;
{
int k;
if (key == ESC)
RL_SETSTATE(RL_STATE_METANEXT);
RL_SETSTATE(RL_STATE_MOREINPUT);
k = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (key == ESC)
RL_UNSETSTATE(RL_STATE_METANEXT);
return k;
}
#if defined (READLINE_CALLBACKS)
int
_rl_dispatch_callback (cxt)
_rl_keyseq_cxt *cxt;
{
int nkey, r;
/* For now */
#if 1
/* The first time this context is used, we want to read input and dispatch
on it. When traversing the chain of contexts back `up', we want to use
the value from the next context down. We're simulating recursion using
a chain of contexts. */
if ((cxt->flags & KSEQ_DISPATCHED) == 0)
{
nkey = _rl_subseq_getchar (cxt->okey);
r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg);
cxt->flags |= KSEQ_DISPATCHED;
}
else
r = cxt->childval;
#else
r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg);
#endif
/* For now */
r = _rl_subseq_result (r, cxt->oldmap, cxt->okey, (cxt->flags & KSEQ_SUBSEQ));
if (r == 0) /* success! */
{
_rl_keyseq_chain_dispose ();
RL_UNSETSTATE (RL_STATE_MULTIKEY);
return r;
}
if (r != -3) /* magic value that says we added to the chain */
_rl_kscxt = cxt->ocxt;
if (_rl_kscxt)
_rl_kscxt->childval = r;
if (r != -3)
_rl_keyseq_cxt_dispose (cxt);
return r;
}
#endif /* READLINE_CALLBACKS */
/* Do the command associated with KEY in MAP.
If the associated command is really a keymap, then read
another key, and dispatch into that map. */
@ -526,6 +664,7 @@ _rl_dispatch (key, map)
register int key;
Keymap map;
{
_rl_dispatching_keymap = map;
return _rl_dispatch_subseq (key, map, 0);
}
@ -538,6 +677,9 @@ _rl_dispatch_subseq (key, map, got_subseq)
int r, newkey;
char *macro;
rl_command_func_t *func;
#if defined (READLINE_CALLBACKS)
_rl_keyseq_cxt *cxt;
#endif
if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
{
@ -571,13 +713,9 @@ _rl_dispatch_subseq (key, map, got_subseq)
rl_executing_keymap = map;
#if 0
_rl_suppress_redisplay = (map[key].function == rl_insert) && _rl_input_available ();
#endif
rl_dispatching = 1;
RL_SETSTATE(RL_STATE_DISPATCHING);
r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
(*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
RL_UNSETSTATE(RL_STATE_DISPATCHING);
rl_dispatching = 0;
@ -606,6 +744,10 @@ _rl_dispatch_subseq (key, map, got_subseq)
}
else
{
#if defined (READLINE_CALLBACKS)
RL_UNSETSTATE (RL_STATE_MULTIKEY);
_rl_keyseq_chain_dispose ();
#endif
_rl_abort_internal ();
return -1;
}
@ -627,44 +769,43 @@ _rl_dispatch_subseq (key, map, got_subseq)
#endif
rl_key_sequence_length++;
_rl_dispatching_keymap = FUNCTION_TO_KEYMAP (map, key);
if (key == ESC)
RL_SETSTATE(RL_STATE_METANEXT);
RL_SETSTATE(RL_STATE_MOREINPUT);
newkey = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (key == ESC)
RL_UNSETSTATE(RL_STATE_METANEXT);
/* Allocate new context here. Use linked contexts (linked through
cxt->ocxt) to simulate recursion */
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
/* Return 0 only the first time, to indicate success to
_rl_callback_read_char. The rest of the time, we're called
from _rl_dispatch_callback, so we return 3 to indicate
special handling is necessary. */
r = RL_ISSTATE (RL_STATE_MULTIKEY) ? -3 : 0;
cxt = _rl_keyseq_cxt_alloc ();
if (got_subseq)
cxt->flags |= KSEQ_SUBSEQ;
cxt->okey = key;
cxt->oldmap = map;
cxt->dmap = _rl_dispatching_keymap;
cxt->subseq_arg = got_subseq || cxt->dmap[ANYOTHERKEY].function;
RL_SETSTATE (RL_STATE_MULTIKEY);
_rl_kscxt = cxt;
return r; /* don't indicate immediate success */
}
#endif
newkey = _rl_subseq_getchar (key);
if (newkey < 0)
{
_rl_abort_internal ();
return -1;
}
r = _rl_dispatch_subseq (newkey, FUNCTION_TO_KEYMAP (map, key), got_subseq || map[ANYOTHERKEY].function);
if (r == -2)
/* We didn't match anything, and the keymap we're indexed into
shadowed a function previously bound to that prefix. Call
the function. The recursive call to _rl_dispatch_subseq has
already taken care of pushing any necessary input back onto
the input queue with _rl_unget_char. */
r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key));
else if (r && map[ANYOTHERKEY].function)
{
/* We didn't match (r is probably -1), so return something to
tell the caller that it should try ANYOTHERKEY for an
overridden function. */
_rl_unget_char (key);
return -2;
}
else if (r && got_subseq)
{
/* OK, back up the chain. */
_rl_unget_char (key);
return -1;
}
r = _rl_dispatch_subseq (newkey, _rl_dispatching_keymap, got_subseq || map[ANYOTHERKEY].function);
return _rl_subseq_result (r, map, key, got_subseq);
}
else
{
@ -688,9 +829,69 @@ _rl_dispatch_subseq (key, map, got_subseq)
_rl_vi_textmod_command (key))
_rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
#endif
return (r);
}
static int
_rl_subseq_result (r, map, key, got_subseq)
int r;
Keymap map;
int key, got_subseq;
{
Keymap m;
int type, nt;
rl_command_func_t *func, *nf;
if (r == -2)
/* We didn't match anything, and the keymap we're indexed into
shadowed a function previously bound to that prefix. Call
the function. The recursive call to _rl_dispatch_subseq has
already taken care of pushing any necessary input back onto
the input queue with _rl_unget_char. */
{
m = _rl_dispatching_keymap;
type = m[ANYOTHERKEY].type;
func = m[ANYOTHERKEY].function;
if (type == ISFUNC && func == rl_do_lowercase_version)
r = _rl_dispatch (_rl_to_lower (key), map);
else if (type == ISFUNC && func == rl_insert)
{
/* If the function that was shadowed was self-insert, we
somehow need a keymap with map[key].func == self-insert.
Let's use this one. */
nt = m[key].type;
nf = m[key].function;
m[key].type = type;
m[key].function = func;
r = _rl_dispatch (key, m);
m[key].type = nt;
m[key].function = nf;
}
else
r = _rl_dispatch (ANYOTHERKEY, m);
}
else if (r && map[ANYOTHERKEY].function)
{
/* We didn't match (r is probably -1), so return something to
tell the caller that it should try ANYOTHERKEY for an
overridden function. */
_rl_unget_char (key);
_rl_dispatching_keymap = map;
return -2;
}
else if (r && got_subseq)
{
/* OK, back up the chain. */
_rl_unget_char (key);
_rl_dispatching_keymap = map;
return -1;
}
return r;
}
/* **************************************************************** */
/* */
/* Initializations */
@ -839,7 +1040,7 @@ readline_initialize_everything ()
/* If the completion parser's default word break characters haven't
been set yet, then do so now. */
if (rl_completer_word_break_characters == (char *)NULL)
rl_completer_word_break_characters = rl_basic_word_break_characters;
rl_completer_word_break_characters = (char *)rl_basic_word_break_characters;
}
/* If this system allows us to look at the values of the regular
@ -848,7 +1049,20 @@ readline_initialize_everything ()
static void
readline_default_bindings ()
{
rl_tty_set_default_bindings (_rl_keymap);
if (_rl_bind_stty_chars)
rl_tty_set_default_bindings (_rl_keymap);
}
/* Reset the default bindings for the terminal special characters we're
interested in back to rl_insert and read the new ones. */
static void
reset_default_bindings ()
{
if (_rl_bind_stty_chars)
{
rl_tty_unset_default_bindings (_rl_keymap);
rl_tty_set_default_bindings (_rl_keymap);
}
}
/* Bind some common arrow key sequences in MAP. */
@ -862,42 +1076,33 @@ bind_arrow_keys_internal (map)
_rl_keymap = map;
#if defined (__MSDOS__)
_rl_bind_if_unbound ("\033[0A", rl_get_previous_history);
_rl_bind_if_unbound ("\033[0B", rl_backward_char);
_rl_bind_if_unbound ("\033[0C", rl_forward_char);
_rl_bind_if_unbound ("\033[0D", rl_get_next_history);
rl_bind_keyseq_if_unbound ("\033[0A", rl_get_previous_history);
rl_bind_keyseq_if_unbound ("\033[0B", rl_backward_char);
rl_bind_keyseq_if_unbound ("\033[0C", rl_forward_char);
rl_bind_keyseq_if_unbound ("\033[0D", rl_get_next_history);
#endif
#ifdef __MINGW32__
/* Under Windows, when an extend key (like an arrow key) is
pressed, getch() will return 340 (octal) followed by a code for
the extended key. We use macros to transform those into the
normal ANSI terminal sequences for these keys. */
rl_bind_keyseq_if_unbound ("\033[A", rl_get_previous_history);
rl_bind_keyseq_if_unbound ("\033[B", rl_get_next_history);
rl_bind_keyseq_if_unbound ("\033[C", rl_forward_char);
rl_bind_keyseq_if_unbound ("\033[D", rl_backward_char);
rl_bind_keyseq_if_unbound ("\033[H", rl_beg_of_line);
rl_bind_keyseq_if_unbound ("\033[F", rl_end_of_line);
/* Up arrow. */
rl_macro_bind ("\340H", "\033[A", map);
/* Left arrow. */
rl_macro_bind ("\340K", "\033[D", map);
/* Right arrow. */
rl_macro_bind ("\340M", "\033[C", map);
/* Down arrow. */
rl_macro_bind ("\340P", "\033[B", map);
rl_bind_keyseq_if_unbound ("\033OA", rl_get_previous_history);
rl_bind_keyseq_if_unbound ("\033OB", rl_get_next_history);
rl_bind_keyseq_if_unbound ("\033OC", rl_forward_char);
rl_bind_keyseq_if_unbound ("\033OD", rl_backward_char);
rl_bind_keyseq_if_unbound ("\033OH", rl_beg_of_line);
rl_bind_keyseq_if_unbound ("\033OF", rl_end_of_line);
#if defined (__MINGW32__)
rl_bind_keyseq_if_unbound ("\340H", rl_get_previous_history);
rl_bind_keyseq_if_unbound ("\340P", rl_get_next_history);
rl_bind_keyseq_if_unbound ("\340M", rl_forward_char);
rl_bind_keyseq_if_unbound ("\340K", rl_backward_char);
#endif
_rl_bind_if_unbound ("\033[A", rl_get_previous_history);
_rl_bind_if_unbound ("\033[B", rl_get_next_history);
_rl_bind_if_unbound ("\033[C", rl_forward_char);
_rl_bind_if_unbound ("\033[D", rl_backward_char);
_rl_bind_if_unbound ("\033[H", rl_beg_of_line);
_rl_bind_if_unbound ("\033[F", rl_end_of_line);
_rl_bind_if_unbound ("\033OA", rl_get_previous_history);
_rl_bind_if_unbound ("\033OB", rl_get_next_history);
_rl_bind_if_unbound ("\033OC", rl_forward_char);
_rl_bind_if_unbound ("\033OD", rl_backward_char);
_rl_bind_if_unbound ("\033OH", rl_beg_of_line);
_rl_bind_if_unbound ("\033OF", rl_end_of_line);
_rl_keymap = xkeymap;
}
@ -950,9 +1155,7 @@ rl_save_state (sp)
sp->macro = rl_executing_macro;
sp->catchsigs = rl_catch_signals;
#if defined (SIGWINCH)
sp->catchsigwinch = rl_catch_sigwinch;
#endif
return (0);
}
@ -986,9 +1189,7 @@ rl_restore_state (sp)
rl_executing_macro = sp->macro;
rl_catch_signals = sp->catchsigs;
#if defined (SIGWINCH)
rl_catch_sigwinch = sp->catchsigwinch;
#endif
return (0);
}

View File

@ -1,6 +1,6 @@
/* Readline.h -- the names of functions callable from within readline. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 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.
@ -40,9 +40,9 @@ extern "C" {
#endif
/* Hex-encoded Readline version number. */
#define RL_READLINE_VERSION 0x0403 /* Readline 4.3 */
#define RL_VERSION_MAJOR 4
#define RL_VERSION_MINOR 3
#define RL_READLINE_VERSION 0x0501 /* Readline 5.1 */
#define RL_VERSION_MAJOR 5
#define RL_VERSION_MINOR 1
/* Readline data structures. */
@ -160,6 +160,7 @@ extern int rl_kill_line PARAMS((int, int));
extern int rl_backward_kill_line PARAMS((int, int));
extern int rl_kill_full_line PARAMS((int, int));
extern int rl_unix_word_rubout PARAMS((int, int));
extern int rl_unix_filename_rubout PARAMS((int, int));
extern int rl_unix_line_discard PARAMS((int, int));
extern int rl_copy_region_to_kill PARAMS((int, int));
extern int rl_kill_region PARAMS((int, int));
@ -240,6 +241,7 @@ extern int rl_vi_column PARAMS((int, int));
extern int rl_vi_delete_to PARAMS((int, int));
extern int rl_vi_change_to PARAMS((int, int));
extern int rl_vi_yank_to PARAMS((int, int));
extern int rl_vi_rubout PARAMS((int, int));
extern int rl_vi_delete PARAMS((int, int));
extern int rl_vi_back_to_indent PARAMS((int, int));
extern int rl_vi_first_print PARAMS((int, int));
@ -258,6 +260,8 @@ extern int rl_vi_check PARAMS((void));
extern int rl_vi_domove PARAMS((int, int *));
extern int rl_vi_bracktype PARAMS((int));
extern void rl_vi_start_inserting PARAMS((int, int, int));
/* VI-mode pseudo-bindable commands, used as utility functions. */
extern int rl_vi_fWord PARAMS((int, int));
extern int rl_vi_bWord PARAMS((int, int));
@ -290,12 +294,22 @@ extern int rl_bind_key PARAMS((int, rl_command_func_t *));
extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
extern int rl_unbind_key PARAMS((int));
extern int rl_unbind_key_in_map PARAMS((int, Keymap));
extern int rl_bind_key_if_unbound PARAMS((int, rl_command_func_t *));
extern int rl_bind_key_if_unbound_in_map PARAMS((int, rl_command_func_t *, Keymap));
extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap));
extern int rl_unbind_command_in_map PARAMS((const char *, Keymap));
extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_bind_keyseq PARAMS((const char *, rl_command_func_t *));
extern int rl_bind_keyseq_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *));
extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap));
extern char *rl_variable_value PARAMS((const char *));
extern int rl_variable_bind PARAMS((const char *, const char *));
/* Backwards compatibility, use rl_bind_keyseq_in_map instead. */
extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
/* Backwards compatibility, use rl_generic_bind instead. */
extern int rl_macro_bind PARAMS((const char *, const char *, Keymap));
@ -358,7 +372,7 @@ extern int rl_clear_message PARAMS((void));
extern int rl_reset_line_state PARAMS((void));
extern int rl_crlf PARAMS((void));
#if (defined (__STDC__) || defined (__cplusplus)) && defined (USE_VARARGS) && defined (PREFER_STDARG)
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else
extern int rl_message ();
@ -384,11 +398,13 @@ extern char *rl_copy_text PARAMS((int, int));
extern void rl_prep_terminal PARAMS((int));
extern void rl_deprep_terminal PARAMS((void));
extern void rl_tty_set_default_bindings PARAMS((Keymap));
extern void rl_tty_unset_default_bindings PARAMS((Keymap));
extern int rl_reset_terminal PARAMS((const char *));
extern void rl_resize_terminal PARAMS((void));
extern void rl_set_screen_size PARAMS((int, int));
extern void rl_get_screen_size PARAMS((int *, int *));
extern void rl_reset_screen_size PARAMS((void));
extern char *rl_get_termcap PARAMS((const char *));
@ -516,6 +532,11 @@ extern const char *rl_terminal_name;
extern FILE *rl_instream;
extern FILE *rl_outstream;
/* If non-zero, Readline gives values of LINES and COLUMNS from the environment
greater precedence than values fetched from the kernel when computing the
screen dimensions. */
extern int rl_prefer_env_winsize;
/* If non-zero, then this is the address of a function to call just
before readline_internal () prints the first prompt. */
extern rl_hook_func_t *rl_startup_hook;
@ -603,7 +624,12 @@ extern const char *rl_basic_word_break_characters;
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
extern const char *rl_completer_word_break_characters;
extern /*const*/ char *rl_completer_word_break_characters;
/* Hook function to allow an application to set the completion word
break characters before readline breaks up the line. Allows
position-dependent word break characters. */
extern rl_cpvfunc_t *rl_completion_word_break_hook;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
@ -687,6 +713,11 @@ extern int rl_attempted_completion_over;
functions. */
extern int rl_completion_type;
/* Up to this many items will be displayed in response to a
possible-completions call. After that, we ask the user if she
is sure she wants to see them all. The default value is 100. */
extern int rl_completion_query_items;
/* Character appended to completed words when at the end of the line. The
default is a space. Nothing is added if this is '\0'. */
extern int rl_completion_append_character;
@ -695,10 +726,18 @@ extern int rl_completion_append_character;
rl_completion_append_character will not be appended. */
extern int rl_completion_suppress_append;
/* Up to this many items will be displayed in response to a
possible-completions call. After that, we ask the user if she
is sure she wants to see them all. The default value is 100. */
extern int rl_completion_query_items;
/* Set to any quote character readline thinks it finds before any application
completion function is called. */
extern int rl_completion_quote_character;
/* Set to a non-zero value if readline found quoting anywhere in the word to
be completed; set before any application completion function is called. */
extern int rl_completion_found_quote;
/* If non-zero, the completion functions don't append any closing quote.
This is set to 0 by rl_complete_internal and may be changed by an
application-specific completion function. */
extern int rl_completion_suppress_quote;
/* If non-zero, a slash will be appended to completed filenames that are
symbolic links to directory names, subject to the value of the
@ -729,28 +768,33 @@ extern int rl_inhibit_completion;
#define MULT_MATCH 2
/* Possible state values for rl_readline_state */
#define RL_STATE_NONE 0x00000 /* no state; before first call */
#define RL_STATE_NONE 0x000000 /* no state; before first call */
#define RL_STATE_INITIALIZING 0x00001 /* initializing */
#define RL_STATE_INITIALIZED 0x00002 /* initialization done */
#define RL_STATE_TERMPREPPED 0x00004 /* terminal is prepped */
#define RL_STATE_READCMD 0x00008 /* reading a command key */
#define RL_STATE_METANEXT 0x00010 /* reading input after ESC */
#define RL_STATE_DISPATCHING 0x00020 /* dispatching to a command */
#define RL_STATE_MOREINPUT 0x00040 /* reading more input in a command function */
#define RL_STATE_ISEARCH 0x00080 /* doing incremental search */
#define RL_STATE_NSEARCH 0x00100 /* doing non-inc search */
#define RL_STATE_SEARCH 0x00200 /* doing a history search */
#define RL_STATE_NUMERICARG 0x00400 /* reading numeric argument */
#define RL_STATE_MACROINPUT 0x00800 /* getting input from a macro */
#define RL_STATE_MACRODEF 0x01000 /* defining keyboard macro */
#define RL_STATE_OVERWRITE 0x02000 /* overwrite mode */
#define RL_STATE_COMPLETING 0x04000 /* doing completion */
#define RL_STATE_SIGHANDLER 0x08000 /* in readline sighandler */
#define RL_STATE_UNDOING 0x10000 /* doing an undo */
#define RL_STATE_INPUTPENDING 0x20000 /* rl_execute_next called */
#define RL_STATE_INITIALIZING 0x000001 /* initializing */
#define RL_STATE_INITIALIZED 0x000002 /* initialization done */
#define RL_STATE_TERMPREPPED 0x000004 /* terminal is prepped */
#define RL_STATE_READCMD 0x000008 /* reading a command key */
#define RL_STATE_METANEXT 0x000010 /* reading input after ESC */
#define RL_STATE_DISPATCHING 0x000020 /* dispatching to a command */
#define RL_STATE_MOREINPUT 0x000040 /* reading more input in a command function */
#define RL_STATE_ISEARCH 0x000080 /* doing incremental search */
#define RL_STATE_NSEARCH 0x000100 /* doing non-inc search */
#define RL_STATE_SEARCH 0x000200 /* doing a history search */
#define RL_STATE_NUMERICARG 0x000400 /* reading numeric argument */
#define RL_STATE_MACROINPUT 0x000800 /* getting input from a macro */
#define RL_STATE_MACRODEF 0x001000 /* defining keyboard macro */
#define RL_STATE_OVERWRITE 0x002000 /* overwrite mode */
#define RL_STATE_COMPLETING 0x004000 /* doing completion */
#define RL_STATE_SIGHANDLER 0x008000 /* in readline sighandler */
#define RL_STATE_UNDOING 0x010000 /* doing an undo */
#define RL_STATE_INPUTPENDING 0x020000 /* rl_execute_next called */
#define RL_STATE_TTYCSAVED 0x040000 /* tty special chars saved */
#define RL_STATE_CALLBACK 0x080000 /* using the callback interface */
#define RL_STATE_VIMOTION 0x100000 /* reading vi motion arg */
#define RL_STATE_MULTIKEY 0x200000 /* reading multiple-key command */
#define RL_STATE_VICMDONCE 0x400000 /* entered vi command mode at least once */
#define RL_STATE_DONE 0x80000 /* done; accepted line */
#define RL_STATE_DONE 0x800000 /* done; accepted line */
#define RL_SETSTATE(x) (rl_readline_state |= (x))
#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
@ -785,6 +829,12 @@ struct readline_state {
int catchsigs;
int catchsigwinch;
/* search state */
/* completion state */
/* options state */
/* reserved for future expansion, so the struct size doesn't change */
char reserved[64];
};

View File

@ -2,7 +2,7 @@
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.
/* Copyright (C) 1987-2005 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
@ -32,15 +32,17 @@
#include "rlstdc.h"
#if defined (__MINGW32__)
# define NO_TTY_DRIVER
#elif defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
# define TERMIOS_TTY_DRIVER
#else
# if defined (HAVE_TERMIO_H)
# define TERMIO_TTY_DRIVER
# else
# define NEW_TTY_DRIVER
# if !defined (__MINGW32__)
# define NEW_TTY_DRIVER
# else
# define NO_TTY_DRIVER
# endif
# endif
#endif
@ -79,7 +81,7 @@ extern int _rl_stricmp PARAMS((char *, char *));
extern int _rl_strnicmp PARAMS((char *, char *, int));
#endif
#if defined (HAVE_STRPBRK)
#if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE)
# define _rl_strpbrk(a,b) strpbrk((a),(b))
#else
extern char *_rl_strpbrk PARAMS((const char *, const char *));

View File

@ -45,12 +45,28 @@
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H)
# include <wchar.h>
# include <wctype.h>
# if defined (HAVE_MBSTATE_T) && defined (HAVE_MBSRTOWCS)
# if defined (HAVE_MBSTATE_T) && defined (HAVE_MBSRTOWCS) && defined (HAVE_MBRTOWC) && defined (HAVE_MBRLEN) && defined (HAVE_WCWIDTH)
/* system is supposed to support XPG5 */
# define HANDLE_MULTIBYTE 1
# endif
#endif
/* If we don't want multibyte chars even on a system that supports them, let
the configuring user turn multibyte support off. */
#if defined (NO_MULTIBYTE_SUPPORT)
# undef HANDLE_MULTIBYTE
#endif
/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0)
# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0)
# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
# define mbrlen(s, n, ps) (mbrlen) (s, n, 0)
# define mbstate_t int
#endif
/* Make sure MB_LEN_MAX is at least 16 on systems that claim to be able to
handle multibyte chars (some systems define MB_LEN_MAX as 1) */
#ifdef HANDLE_MULTIBYTE
@ -91,6 +107,24 @@ extern int _rl_read_mbstring PARAMS((int, char *, int));
extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
extern wchar_t _rl_char_value PARAMS((char *, int));
extern int _rl_walphabetic PARAMS((wchar_t));
#define _rl_to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc))
#define _rl_to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc))
#define MB_NEXTCHAR(b,s,c,f) \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \
? _rl_find_next_mbchar ((b), (s), (c), (f)) \
: ((s) + (c)))
#define MB_PREVCHAR(b,s,f) \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \
? _rl_find_prev_mbchar ((b), (s), (f)) \
: ((s) - 1))
#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
#define MB_NULLWCH(x) ((x) == 0)
#else /* !HANDLE_MULTIBYTE */
#undef MB_LEN_MAX
@ -102,6 +136,19 @@ extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1))
#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2))
#define _rl_char_value(buf,ind) ((buf)[(ind)])
#define _rl_walphabetic(c) (rl_alphabetic (c))
#define _rl_to_wupper(c) (_rl_to_upper (c))
#define _rl_to_wlower(c) (_rl_to_lower (c))
#define MB_NEXTCHAR(b,s,c,f) ((s) + (c))
#define MB_PREVCHAR(b,s,f) ((s) - 1)
#define MB_INVALIDCH(x) (0)
#define MB_NULLWCH(x) (0)
#endif /* !HANDLE_MULTIBYTE */
extern int rl_byte_oriented;

View File

@ -1,7 +1,7 @@
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
/* Copyright (C) 1999 Free Software Foundation, Inc.
/* Copyright (C) 1999-2005 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.
@ -28,6 +28,95 @@
#include "rlstdc.h"
#include "posixjmp.h" /* defines procenv_t */
/*************************************************************************
* *
* Global structs undocumented in texinfo manual and not in readline.h *
* *
*************************************************************************/
/* search types */
#define RL_SEARCH_ISEARCH 0x01 /* incremental search */
#define RL_SEARCH_NSEARCH 0x02 /* non-incremental search */
#define RL_SEARCH_CSEARCH 0x04 /* intra-line char search */
/* search flags */
#define SF_REVERSE 0x01
#define SF_FOUND 0x02
#define SF_FAILED 0x04
typedef struct __rl_search_context
{
int type;
int sflags;
char *search_string;
int search_string_index;
int search_string_size;
char **lines;
char *allocated_line;
int hlen;
int hindex;
int save_point;
int save_mark;
int save_line;
int last_found_line;
char *prev_line_found;
UNDO_LIST *save_undo_list;
int history_pos;
int direction;
int lastc;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
#endif
char *sline;
int sline_len;
int sline_index;
char *search_terminators;
} _rl_search_cxt;
/* Callback data for reading numeric arguments */
#define NUM_SAWMINUS 0x01
#define NUM_SAWDIGITS 0x02
#define NUM_READONE 0x04
typedef int _rl_arg_cxt;
/* A context for reading key sequences longer than a single character when
using the callback interface. */
#define KSEQ_DISPATCHED 0x01
#define KSEQ_SUBSEQ 0x02
#define KSEQ_RECURSIVE 0x04
typedef struct __rl_keyseq_context
{
int flags;
int subseq_arg;
int subseq_retval; /* XXX */
Keymap dmap;
Keymap oldmap;
int okey;
struct __rl_keyseq_context *ocxt;
int childval;
} _rl_keyseq_cxt;
/* fill in more as needed */
/* `Generic' callback data and functions */
typedef struct __rl_callback_generic_arg
{
int count;
int i1, i2;
/* add here as needed */
} _rl_callback_generic_arg;
typedef int _rl_callback_func_t PARAMS((_rl_callback_generic_arg *));
/*************************************************************************
* *
* Global functions undocumented in texinfo manual and not in readline.h *
@ -54,6 +143,8 @@ extern int readline_echoing_p;
extern int rl_key_sequence_length;
extern int rl_byte_oriented;
extern _rl_keyseq_cxt *_rl_kscxt;
/* display.c */
extern int rl_display_fixed;
@ -100,10 +191,19 @@ extern void readline_internal_setup PARAMS((void));
extern char *readline_internal_teardown PARAMS((int));
extern int readline_internal_char PARAMS((void));
extern _rl_keyseq_cxt *_rl_keyseq_cxt_alloc PARAMS((void));
extern void _rl_keyseq_cxt_dispose PARAMS((_rl_keyseq_cxt *));
extern void _rl_keyseq_chain_dispose PARAMS((void));
extern int _rl_dispatch_callback PARAMS((_rl_keyseq_cxt *));
/* callback.c */
extern _rl_callback_generic_arg *_rl_callback_data_alloc PARAMS((int));
extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *));
#endif /* READLINE_CALLBACKS */
/* bind.c */
extern void _rl_bind_if_unbound PARAMS((const char *, rl_command_func_t *));
/* complete.c */
extern char _rl_find_completion_word PARAMS((int *, int *));
@ -131,6 +231,16 @@ extern int _rl_input_available PARAMS((void));
extern int _rl_input_queued PARAMS((int));
extern void _rl_insert_typein PARAMS((int));
extern int _rl_unget_char PARAMS((int));
extern int _rl_pushed_input_available PARAMS((void));
/* isearch.c */
extern _rl_search_cxt *_rl_scxt_alloc PARAMS((int, int));
extern void _rl_scxt_dispose PARAMS((_rl_search_cxt *, int));
extern int _rl_isearch_dispatch PARAMS((_rl_search_cxt *, int));
extern int _rl_isearch_callback PARAMS((_rl_search_cxt *));
extern int _rl_search_getchar PARAMS((_rl_search_cxt *));
/* macro.c */
extern void _rl_with_macro_input PARAMS((char *));
@ -141,7 +251,12 @@ extern void _rl_add_macro_char PARAMS((int));
extern void _rl_kill_kbd_macro PARAMS((void));
/* misc.c */
extern int _rl_init_argument PARAMS((void));
extern int _rl_arg_overflow PARAMS((void));
extern void _rl_arg_init PARAMS((void));
extern int _rl_arg_getchar PARAMS((void));
extern int _rl_arg_callback PARAMS((_rl_arg_cxt));
extern void _rl_reset_argument PARAMS((void));
extern void _rl_start_using_history PARAMS((void));
extern int _rl_free_saved_history_line PARAMS((void));
extern void _rl_set_insert_mode PARAMS((int, int));
@ -157,11 +272,15 @@ extern void _rl_init_line_state PARAMS((void));
extern void _rl_set_the_line PARAMS((void));
extern int _rl_dispatch PARAMS((int, Keymap));
extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
extern void _rl_internal_char_cleanup PARAMS((void));
/* rltty.c */
extern int _rl_disable_tty_signals PARAMS((void));
extern int _rl_restore_tty_signals PARAMS((void));
/* search.c */
extern int _rl_nsearch_callback PARAMS((_rl_search_cxt *));
/* terminal.c */
extern void _rl_get_screen_size PARAMS((int, int));
extern int _rl_init_terminal_io PARAMS((const char *));
@ -217,8 +336,13 @@ extern void _rl_vi_done_inserting PARAMS((void));
extern const char *_rl_possible_control_prefixes[];
extern const char *_rl_possible_meta_prefixes[];
/* callback.c */
extern _rl_callback_func_t *_rl_callback_func;
extern _rl_callback_generic_arg *_rl_callback_data;
/* complete.c */
extern int _rl_complete_show_all;
extern int _rl_complete_show_unmodified;
extern int _rl_complete_mark_directories;
extern int _rl_complete_mark_symlink_dirs;
extern int _rl_print_completions_horizontally;
@ -230,11 +354,14 @@ extern int _rl_page_completions;
extern int _rl_vis_botlin;
extern int _rl_last_c_pos;
extern int _rl_suppress_redisplay;
extern int _rl_want_redisplay;
extern char *rl_display_prompt;
/* isearch.c */
extern char *_rl_isearch_terminators;
extern _rl_search_cxt *_rl_iscxt;
/* macro.c */
extern char *_rl_executing_macro;
@ -242,6 +369,8 @@ extern char *_rl_executing_macro;
extern int _rl_history_preserve_point;
extern int _rl_history_saved_point;
extern _rl_arg_cxt _rl_argcxt;
/* readline.c */
extern int _rl_horizontal_scroll_mode;
extern int _rl_mark_modified_lines;
@ -249,6 +378,7 @@ extern int _rl_bell_preference;
extern int _rl_meta_flag;
extern int _rl_convert_meta_chars_to_ascii;
extern int _rl_output_meta_chars;
extern int _rl_bind_stty_chars;
extern char *_rl_comment_begin;
extern unsigned char _rl_parsing_conditionalized_out;
extern Keymap _rl_keymap;
@ -258,6 +388,9 @@ extern int _rl_last_command_was_kill;
extern int _rl_eof_char;
extern procenv_t readline_top_level;
/* search.c */
extern _rl_search_cxt *_rl_nscxt;
/* terminal.c */
extern int _rl_enable_keypad;
extern int _rl_enable_meta;
@ -281,4 +414,7 @@ extern int _rl_term_autowrap;
extern int _rl_doing_an_undo;
extern int _rl_undo_group_level;
/* vi_mode.c */
extern int _rl_vi_last_command;
#endif /* _RL_PRIVATE_H_ */

View File

@ -37,7 +37,7 @@
#endif
#ifndef __attribute__
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
# define __attribute__(x)
# endif
#endif

View File

@ -1,7 +1,7 @@
/* rltty.c -- functions to prepare and restore the terminal for readline's
use. */
/* Copyright (C) 1992 Free Software Foundation, Inc.
/* Copyright (C) 1992-2005 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.
@ -188,6 +188,8 @@ static int set_tty_settings PARAMS((int, TIOTYPE *));
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
static void
save_tty_chars (tiop)
TIOTYPE *tiop;
@ -229,12 +231,11 @@ get_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
{
#if defined (TIOCGWINSZ)
set_winsize (tty);
#endif
tiop->flags = tiop->lflag = 0;
errno = 0;
if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
return -1;
tiop->flags |= SGTTY_SET;
@ -404,6 +405,9 @@ static int set_tty_settings PARAMS((int, TIOTYPE *));
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE));
#if defined (FLUSHO)
# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
#else
@ -515,10 +519,9 @@ get_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
{
#if defined (TIOCGWINSZ)
set_winsize (tty);
#endif
errno = 0;
if (_get_tty_settings (tty, tiop) < 0)
return -1;
@ -632,10 +635,9 @@ prepare_terminal_settings (meta_flag, oldtio, tiop)
#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
}
#endif /* NEW_TTY_DRIVER */
#endif /* !NEW_TTY_DRIVER */
/* Put the terminal in CBREAK mode so that we can detect key
presses. */
/* Put the terminal in CBREAK mode so that we can detect key presses. */
#if defined (NO_TTY_DRIVER)
void
rl_prep_terminal (meta_flag)
@ -650,7 +652,6 @@ rl_deprep_terminal ()
}
#else /* ! NO_TTY_DRIVER */
/* Put the terminal in CBREAK mode so that we can detect key presses. */
void
rl_prep_terminal (meta_flag)
int meta_flag;
@ -668,13 +669,43 @@ rl_prep_terminal (meta_flag)
if (get_tty_settings (tty, &tio) < 0)
{
#if defined (ENOTSUP)
/* MacOS X, at least, lies about the value of errno if tcgetattr fails. */
if (errno == ENOTTY || errno == ENOTSUP)
#else
if (errno == ENOTTY)
#endif
readline_echoing_p = 1; /* XXX */
release_sigint ();
return;
}
otio = tio;
if (_rl_bind_stty_chars)
{
#if defined (VI_MODE)
/* If editing in vi mode, make sure we restore the bindings in the
insertion keymap no matter what keymap we ended up in. */
if (rl_editing_mode == vi_mode)
rl_tty_unset_default_bindings (vi_insertion_keymap);
else
#endif
rl_tty_unset_default_bindings (_rl_keymap);
}
save_tty_chars (&otio);
RL_SETSTATE(RL_STATE_TTYCSAVED);
if (_rl_bind_stty_chars)
{
#if defined (VI_MODE)
/* If editing in vi mode, make sure we set the bindings in the
insertion keymap no matter what keymap we ended up in. */
if (rl_editing_mode == vi_mode)
_rl_bind_tty_special_chars (vi_insertion_keymap, tio);
else
#endif
_rl_bind_tty_special_chars (_rl_keymap, tio);
}
prepare_terminal_settings (meta_flag, otio, &tio);
@ -809,6 +840,90 @@ rl_stop_output (count, key)
/* */
/* **************************************************************** */
#if !defined (NO_TTY_DRIVER)
#define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func)
#endif
#if defined (NO_TTY_DRIVER)
#define SET_SPECIAL(sc, func)
#define RESET_SPECIAL(c)
#elif defined (NEW_TTY_DRIVER)
static void
set_special_char (kmap, tiop, sc, func)
Keymap kmap;
TIOTYPE *tiop;
int sc;
rl_command_func_t *func;
{
if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC)
kmap[(unsigned char)sc].function = func;
}
#define RESET_SPECIAL(c) \
if (c != -1 && kmap[(unsigned char)c].type == ISFUNC)
kmap[(unsigned char)c].function = rl_insert;
static void
_rl_bind_tty_special_chars (kmap, ttybuff)
Keymap kmap;
TIOTYPE ttybuff;
{
if (ttybuff.flags & SGTTY_SET)
{
SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
}
# if defined (TIOCGLTC)
if (ttybuff.flags & LTCHARS_SET)
{
SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
}
# endif /* TIOCGLTC */
}
#else /* !NEW_TTY_DRIVER */
static void
set_special_char (kmap, tiop, sc, func)
Keymap kmap;
TIOTYPE *tiop;
int sc;
rl_command_func_t *func;
{
unsigned char uc;
uc = tiop->c_cc[sc];
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
kmap[uc].function = func;
}
/* used later */
#define RESET_SPECIAL(uc) \
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
kmap[uc].function = rl_insert;
static void
_rl_bind_tty_special_chars (kmap, ttybuff)
Keymap kmap;
TIOTYPE ttybuff;
{
SET_SPECIAL (VERASE, rl_rubout);
SET_SPECIAL (VKILL, rl_unix_line_discard);
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VLNEXT, rl_quoted_insert);
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VWERASE, rl_unix_word_rubout);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#endif /* !NEW_TTY_DRIVER */
/* Set the system's default editing characters to their readline equivalents
in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
void
@ -817,63 +932,13 @@ rltty_set_default_bindings (kmap)
{
#if !defined (NO_TTY_DRIVER)
TIOTYPE ttybuff;
int tty = fileno (rl_instream);
int tty;
static int called = 0;
#if defined (NEW_TTY_DRIVER)
#define SET_SPECIAL(sc, func) \
do \
{ \
int ic; \
ic = sc; \
if (ic != -1 && kmap[(unsigned char)ic].type == ISFUNC) \
kmap[(unsigned char)ic].function = func; \
} \
while (0)
tty = fileno (rl_instream);
if (get_tty_settings (tty, &ttybuff) == 0)
{
if (ttybuff.flags & SGTTY_SET)
{
SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
}
# if defined (TIOCGLTC)
if (ttybuff.flags & LTCHARS_SET)
{
SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
}
# endif /* TIOCGLTC */
}
#else /* !NEW_TTY_DRIVER */
#define SET_SPECIAL(sc, func) \
do \
{ \
unsigned char uc; \
uc = ttybuff.c_cc[sc]; \
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
kmap[uc].function = func; \
} \
while (0)
if (get_tty_settings (tty, &ttybuff) == 0)
{
SET_SPECIAL (VERASE, rl_rubout);
SET_SPECIAL (VKILL, rl_unix_line_discard);
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VLNEXT, rl_quoted_insert);
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VWERASE, rl_unix_word_rubout);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#endif /* !NEW_TTY_DRIVER */
_rl_bind_tty_special_chars (kmap, ttybuff);
#endif
}
@ -886,6 +951,30 @@ rl_tty_set_default_bindings (kmap)
rltty_set_default_bindings (kmap);
}
/* Rebind all of the tty special chars that readline worries about back
to self-insert. Call this before saving the current terminal special
chars with save_tty_chars(). This only works on POSIX termios or termio
systems. */
void
rl_tty_unset_default_bindings (kmap)
Keymap kmap;
{
/* Don't bother before we've saved the tty special chars at least once. */
if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
return;
RESET_SPECIAL (_rl_tty_chars.t_erase);
RESET_SPECIAL (_rl_tty_chars.t_kill);
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
RESET_SPECIAL (_rl_tty_chars.t_lnext);
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
RESET_SPECIAL (_rl_tty_chars.t_werase);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#if defined (HANDLE_SIGNALS)
#if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER)

View File

@ -61,22 +61,22 @@
#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
typedef struct _rl_tty_chars {
char t_eof;
char t_eol;
char t_eol2;
char t_erase;
char t_werase;
char t_kill;
char t_reprint;
char t_intr;
char t_quit;
char t_susp;
char t_dsusp;
char t_start;
char t_stop;
char t_lnext;
char t_flush;
char t_status;
unsigned char t_eof;
unsigned char t_eol;
unsigned char t_eol2;
unsigned char t_erase;
unsigned char t_werase;
unsigned char t_kill;
unsigned char t_reprint;
unsigned char t_intr;
unsigned char t_quit;
unsigned char t_susp;
unsigned char t_dsusp;
unsigned char t_start;
unsigned char t_stop;
unsigned char t_lnext;
unsigned char t_flush;
unsigned char t_status;
} _RL_TTY_CHARS;
#endif /* _RLTTY_H_ */

View File

@ -1,6 +1,6 @@
/* rltypedefs.h -- Type declarations for readline functions. */
/* Copyright (C) 2000 Free Software Foundation, Inc.
/* Copyright (C) 2000-2004 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.
@ -79,6 +79,12 @@ typedef void rl_voidfunc_t PARAMS((void));
typedef void rl_vintfunc_t PARAMS((int));
typedef void rl_vcpfunc_t PARAMS((char *));
typedef void rl_vcppfunc_t PARAMS((char **));
typedef char *rl_cpvfunc_t PARAMS((void));
typedef char *rl_cpifunc_t PARAMS((int));
typedef char *rl_cpcpfunc_t PARAMS((char *));
typedef char *rl_cpcppfunc_t PARAMS((char **));
#endif /* _RL_FUNCTION_TYPEDEF */
#ifdef __cplusplus

View File

@ -1,6 +1,6 @@
/* savestring.c */
/* Copyright (C) 1998 Free Software Foundation, Inc.
/* Copyright (C) 1998,2003 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.
@ -19,6 +19,7 @@
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,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include <config.h>
#ifdef HAVE_STRING_H

View File

@ -1,6 +1,6 @@
/* search.c - code for non-incremental searching in emacs and vi modes. */
/* Copyright (C) 1992 Free Software Foundation, Inc.
/* Copyright (C) 1992-2005 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
@ -53,6 +53,8 @@
#endif
#define abs(x) (((x) >= 0) ? (x) : -(x))
_rl_search_cxt *_rl_nscxt = 0;
extern HIST_ENTRY *_rl_saved_line_for_history;
/* Functions imported from the rest of the library. */
@ -68,13 +70,19 @@ static int rl_history_search_pos;
static char *history_search_string;
static int history_string_size;
static UNDO_LIST *noninc_saved_undo_list;
static void make_history_line_current PARAMS((HIST_ENTRY *));
static int noninc_search_from_pos PARAMS((char *, int, int));
static void noninc_dosearch PARAMS((char *, int));
static void noninc_search PARAMS((int, int));
static int noninc_dosearch PARAMS((char *, int));
static int noninc_search PARAMS((int, int));
static int rl_history_search_internal PARAMS((int, int));
static void rl_history_search_reinit PARAMS((void));
static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
/* Make the data from the history entry ENTRY be the contents of the
current line. This doesn't do anything with rl_point; the caller
must set it. */
@ -82,8 +90,16 @@ static void
make_history_line_current (entry)
HIST_ENTRY *entry;
{
rl_replace_line (entry->line, 0);
rl_undo_list = (UNDO_LIST *)entry->data;
_rl_replace_text (entry->line, 0, rl_end);
_rl_fix_point (1);
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
/* POSIX.2 says that the `U' command doesn't affect the copy of any
command lines to the edit line. We're going to implement that by
making the undo list start after the matching line is copied to the
current editing buffer. */
rl_free_undo_list ();
#endif
if (_rl_saved_line_for_history)
_rl_free_history_entry (_rl_saved_line_for_history);
@ -125,8 +141,8 @@ noninc_search_from_pos (string, pos, dir)
/* 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
entries. Returns 1 if the search was successful, 0 otherwise. */
static int
noninc_dosearch (string, dir)
char *string;
int dir;
@ -137,7 +153,7 @@ noninc_dosearch (string, dir)
if (string == 0 || *string == '\0' || noninc_history_pos < 0)
{
rl_ding ();
return;
return 0;
}
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
@ -148,7 +164,7 @@ noninc_dosearch (string, dir)
rl_clear_message ();
rl_point = 0;
rl_ding ();
return;
return 0;
}
noninc_history_pos = pos;
@ -159,7 +175,7 @@ noninc_dosearch (string, dir)
#if defined (VI_MODE)
if (rl_editing_mode != vi_mode)
#endif
history_set_pos (oldpos);
history_set_pos (oldpos);
make_history_line_current (entry);
@ -167,27 +183,29 @@ noninc_dosearch (string, dir)
rl_mark = rl_end;
rl_clear_message ();
return 1;
}
/* 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;
static _rl_search_cxt *
_rl_nsearch_init (dir, pchar)
int dir, pchar;
{
int saved_point, saved_mark, c;
_rl_search_cxt *cxt;
char *p;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
#endif
cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
if (dir < 0)
cxt->sflags |= SF_REVERSE; /* not strictly needed */
cxt->direction = dir;
cxt->history_pos = cxt->save_line;
rl_maybe_save_line ();
saved_point = rl_point;
saved_mark = rl_mark;
/* Clear the undo list, since reading the search string should create its
own undo list, and the whole list will end up being freed when we
finish reading the search string. */
rl_undo_list = 0;
/* Use the line buffer to read the search string. */
rl_line_buffer[0] = 0;
@ -197,99 +215,169 @@ noninc_search (dir, pchar)
rl_message (p, 0, 0);
free (p);
#define SEARCH_RETURN rl_restore_prompt (); RL_UNSETSTATE(RL_STATE_NSEARCH); return
RL_SETSTATE(RL_STATE_NSEARCH);
/* Read the search string. */
while (1)
{
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
_rl_nscxt = cxt;
return cxt;
}
static int
_rl_nsearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;
{
_rl_scxt_dispose (cxt, 0);
_rl_nscxt = 0;
RL_UNSETSTATE(RL_STATE_NSEARCH);
return (r != 1);
}
static void
_rl_nsearch_abort (cxt)
_rl_search_cxt *cxt;
{
rl_maybe_unsave_line ();
rl_clear_message ();
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
}
/* Process just-read character C according to search context CXT. Return -1
if the caller should abort the search, 0 if we should break out of the
loop, and 1 if we should continue to read characters. */
static int
_rl_nsearch_dispatch (cxt, c)
_rl_search_cxt *cxt;
int c;
{
switch (c)
{
case CTRL('W'):
rl_unix_word_rubout (1, c);
break;
case CTRL('U'):
rl_unix_line_discard (1, c);
break;
case RETURN:
case NEWLINE:
return 0;
case CTRL('H'):
case RUBOUT:
if (rl_point == 0)
{
_rl_nsearch_abort (cxt);
return -1;
}
_rl_rubout_char (1, c);
break;
case CTRL('C'):
case CTRL('G'):
rl_ding ();
_rl_nsearch_abort (cxt);
return -1;
default:
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
rl_insert_text (cxt->mb);
else
#endif
if (c == 0)
break;
switch (c)
{
case CTRL('H'):
case RUBOUT:
if (rl_point == 0)
{
rl_maybe_unsave_line ();
rl_clear_message ();
rl_point = saved_point;
rl_mark = saved_mark;
SEARCH_RETURN;
}
_rl_rubout_char (1, c);
break;
case CTRL('W'):
rl_unix_word_rubout (1, c);
break;
case CTRL('U'):
rl_unix_line_discard (1, c);
break;
case RETURN:
case NEWLINE:
goto dosearch;
/* NOTREACHED */
break;
case CTRL('C'):
case CTRL('G'):
rl_maybe_unsave_line ();
rl_clear_message ();
rl_point = saved_point;
rl_mark = saved_mark;
rl_ding ();
SEARCH_RETURN;
default:
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (mb);
else
#endif
_rl_insert_char (1, c);
break;
}
(*rl_redisplay_function) ();
_rl_insert_char (1, c);
break;
}
dosearch:
rl_mark = saved_mark;
(*rl_redisplay_function) ();
return 1;
}
/* Perform one search according to CXT, using NONINC_SEARCH_STRING. Return
-1 if the search should be aborted, any other value means to clean up
using _rl_nsearch_cleanup (). Returns 1 if the search was successful,
0 otherwise. */
static int
_rl_nsearch_dosearch (cxt)
_rl_search_cxt *cxt;
{
rl_mark = cxt->save_mark;
/* 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)
if (noninc_search_string == 0)
{
rl_ding ();
SEARCH_RETURN;
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
return -1;
}
}
else
{
/* We want to start the search from the current history position. */
noninc_history_pos = where_history ();
noninc_history_pos = cxt->save_line;
FREE (noninc_search_string);
noninc_search_string = savestring (rl_line_buffer);
/* If we don't want the subsequent undo list generated by the search
matching a history line to include the contents of the search string,
we need to clear rl_line_buffer here. For now, we just clear the
undo list generated by reading the search string. (If the search
fails, the old undo list will be restored by rl_maybe_unsave_line.) */
rl_free_undo_list ();
}
rl_restore_prompt ();
noninc_dosearch (noninc_search_string, dir);
RL_UNSETSTATE(RL_STATE_NSEARCH);
return (noninc_dosearch (noninc_search_string, cxt->direction));
}
/* 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 int
noninc_search (dir, pchar)
int dir;
int pchar;
{
_rl_search_cxt *cxt;
int c, r;
cxt = _rl_nsearch_init (dir, pchar);
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
/* Read the search string. */
r = 0;
while (1)
{
c = _rl_search_getchar (cxt);
if (c == 0)
break;
r = _rl_nsearch_dispatch (cxt, c);
if (r < 0)
return 1;
else if (r == 0)
break;
}
r = _rl_nsearch_dosearch (cxt);
return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
}
/* Search forward through the history list for a string. If the vi-mode
@ -298,8 +386,7 @@ int
rl_noninc_forward_search (count, key)
int count, key;
{
noninc_search (1, (key == '?') ? '?' : 0);
return 0;
return noninc_search (1, (key == '?') ? '?' : 0);
}
/* Reverse search the history list for a string. If the vi-mode code
@ -308,8 +395,7 @@ int
rl_noninc_reverse_search (count, key)
int count, key;
{
noninc_search (-1, (key == '/') ? '/' : 0);
return 0;
return noninc_search (-1, (key == '/') ? '/' : 0);
}
/* Search forward through the history list for the last string searched
@ -318,13 +404,15 @@ int
rl_noninc_forward_search_again (count, key)
int count, key;
{
int r;
if (!noninc_search_string)
{
rl_ding ();
return (-1);
}
noninc_dosearch (noninc_search_string, 1);
return 0;
r = noninc_dosearch (noninc_search_string, 1);
return (r != 1);
}
/* Reverse search in the history list for the last string searched
@ -333,15 +421,34 @@ int
rl_noninc_reverse_search_again (count, key)
int count, key;
{
int r;
if (!noninc_search_string)
{
rl_ding ();
return (-1);
}
noninc_dosearch (noninc_search_string, -1);
return 0;
r = noninc_dosearch (noninc_search_string, -1);
return (r != 1);
}
#if defined (READLINE_CALLBACKS)
int
_rl_nsearch_callback (cxt)
_rl_search_cxt *cxt;
{
int c, r;
c = _rl_search_getchar (cxt);
r = _rl_nsearch_dispatch (cxt, c);
if (r != 0)
return 1;
r = _rl_nsearch_dosearch (cxt);
return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
}
#endif
static int
rl_history_search_internal (count, dir)
int count, dir;

View File

@ -27,7 +27,6 @@
#endif
#include <sys/types.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
@ -49,8 +48,10 @@
# include <limits.h>
#endif
#if defined (HAVE_FCNTL_H)
#include <fcntl.h>
#ifdef HAVE_PWD_H
#endif
#if defined (HAVE_PWD_H)
#include <pwd.h>
#endif
@ -60,9 +61,9 @@
#include "rlshell.h"
#include "xmalloc.h"
#if !defined (HAVE_GETPW_DECLS)
#if defined (HAVE_GETPWUID) && !defined (HAVE_GETPW_DECLS)
extern struct passwd *getpwuid PARAMS((uid_t));
#endif /* !HAVE_GETPW_DECLS */
#endif /* HAVE_GETPWUID && !HAVE_GETPW_DECLS */
#ifndef NULL
# define NULL 0
@ -125,23 +126,27 @@ sh_set_lines_and_columns (lines, cols)
{
char *b;
#if defined (HAVE_PUTENV)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
sprintf (b, "LINES=%d", lines);
putenv (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
sprintf (b, "COLUMNS=%d", cols);
putenv (b);
#else /* !HAVE_PUTENV */
# if defined (HAVE_SETENV)
#if defined (HAVE_SETENV)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", lines);
setenv ("LINES", b, 1);
free (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", cols);
setenv ("COLUMNS", b, 1);
# endif /* HAVE_SETENV */
#endif /* !HAVE_PUTENV */
free (b);
#else /* !HAVE_SETENV */
# if defined (HAVE_PUTENV)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
sprintf (b, "LINES=%d", lines);
putenv (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
sprintf (b, "COLUMNS=%d", cols);
putenv (b);
# endif /* HAVE_PUTENV */
#endif /* !HAVE_SETENV */
}
char *
@ -158,7 +163,7 @@ sh_get_home_dir ()
struct passwd *entry;
home_dir = (char *)NULL;
#ifdef HAVE_GETPWUID
#if defined (HAVE_GETPWUID)
entry = getpwuid (getuid ());
if (entry)
home_dir = entry->pw_dir;
@ -176,7 +181,7 @@ int
sh_unset_nodelay_mode (fd)
int fd;
{
#ifdef HAVE_FNCTL
#if defined (HAVE_FCNTL)
int flags, bflags;
if ((flags = fcntl (fd, F_GETFL, 0)) < 0)

View File

@ -1,7 +1,7 @@
## -*- text -*- ##
# Makefile for the GNU readline library shared library support.
#
# Copyright (C) 1998 Free Software Foundation, Inc.
# Copyright (C) 1998-2003 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -17,6 +17,14 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
PACKAGE = @PACKAGE_NAME@
VERSION = @PACKAGE_VERSION@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_VERSION = @PACKAGE_VERSION@
RL_LIBRARY_VERSION = @LIBVERSION@
RL_LIBRARY_NAME = readline
@ -45,7 +53,10 @@ host_os = @host_os@
prefix = @prefix@
exec_prefix = @exec_prefix@
includedir = @includedir@
bindir = @bindir@
libdir = @libdir@
datadir = @datadir@
localedir = $(datadir)/locale
# Support an alternate destination root directory for package building
DESTDIR =
@ -55,7 +66,7 @@ LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DRL_LIBRARY_VERSION='"$(RL_LIBRARY_VERSION)"'
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@ @CFLAGS@
DEFS = @DEFS@
DEFS = @DEFS@ @CROSS_COMPILE@
LOCAL_DEFS = @LOCAL_DEFS@
#
@ -72,14 +83,20 @@ SHOBJ_LDFLAGS = @SHOBJ_LDFLAGS@
SHOBJ_XLDFLAGS = @SHOBJ_XLDFLAGS@
SHOBJ_LIBS = @SHOBJ_LIBS@
SHLIB_XLDFLAGS = @SHLIB_XLDFLAGS@
SHLIB_XLDFLAGS = @LDFLAGS@ @SHLIB_XLDFLAGS@
SHLIB_LIBS = @SHLIB_LIBS@
SHLIB_DOT = @SHLIB_DOT@
SHLIB_LIBPREF = @SHLIB_LIBPREF@
SHLIB_LIBSUFF = @SHLIB_LIBSUFF@
SHLIB_LIBVERSION = @SHLIB_LIBVERSION@
SHLIB_DLLVERSION = @SHLIB_DLLVERSION@
SHLIB_STATUS = @SHLIB_STATUS@
TERMCAP_LIB = @TERMCAP_LIB@
# shared library versioning
SHLIB_MAJOR= @SHLIB_MAJOR@
# shared library systems like SVR4's do not use minor versions
@ -99,8 +116,8 @@ CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(CPPFLAGS) $(INCLUDES) $(LOCAL_CFLAGS) $(CFLAGS
# The name of the main library target.
SHARED_READLINE = libreadline.$(SHLIB_LIBVERSION)
SHARED_HISTORY = libhistory.$(SHLIB_LIBVERSION)
SHARED_READLINE = $(SHLIB_LIBPREF)readline$(SHLIB_DOT)$(SHLIB_LIBVERSION)
SHARED_HISTORY = $(SHLIB_LIBPREF)history$(SHLIB_DOT)$(SHLIB_LIBVERSION)
SHARED_LIBS = $(SHARED_READLINE) $(SHARED_HISTORY)
WCWIDTH_OBJ = @WCWIDTH_OBJ@
@ -117,7 +134,7 @@ CSOURCES = $(topdir)/readline.c $(topdir)/funmap.c $(topdir)/keymaps.c \
$(topdir)/histfile.c $(topdir)/nls.c $(topdir)/search.c \
$(topdir)/shell.c $(topdir)/savestring.c $(topdir)/tilde.c \
$(topdir)/text.c $(topdir)/misc.c $(topdir)/compat.c \
$(topdir)/mbutil.c $(WCWIDTH_SRC)
$(topdir)/mbutil.c $(topdir)/support/wcwidth.c
# The header files for this library.
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
@ -170,13 +187,13 @@ installdirs: $(topdir)/support/mkdirs
-$(SHELL) $(topdir)/support/mkdirs $(DESTDIR)$(libdir)
install: installdirs $(SHLIB_STATUS)
$(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -i "$(INSTALL_DATA)" $(SHARED_HISTORY)
$(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -i "$(INSTALL_DATA)" $(SHARED_READLINE)
$(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -b $(DESTDIR)$(bindir) -i "$(INSTALL_DATA)" $(SHARED_HISTORY)
$(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -b $(DESTDIR)$(bindir) -i "$(INSTALL_DATA)" $(SHARED_READLINE)
@echo install: you may need to run ldconfig
uninstall:
$(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -U $(SHARED_HISTORY)
$(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -U $(SHARED_READLINE)
$(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -b $(DESTDIR)$(bindir) -U $(SHARED_HISTORY)
$(SHELL) $(topdir)/support/shlib-install -O $(host_os) -d $(DESTDIR)$(libdir) -b $(DESTDIR)$(bindir) -U $(SHARED_READLINE)
@echo uninstall: you may need to run ldconfig
clean mostlyclean: force
@ -396,7 +413,7 @@ search.so: $(topdir)/search.c
shell.so: $(topdir)/shell.c
signals.so: $(topdir)/signals.c
terminal.so: $(topdir)/terminal.c
text.so: $(topdir)/terminal.c
text.so: $(topdir)/text.c
tilde.so: $(topdir)/tilde.c
undo.so: $(topdir)/undo.c
util.so: $(topdir)/util.c
@ -430,7 +447,7 @@ search.so: search.c
signals.so: signals.c
shell.so: shell.c
terminal.so: terminal.c
text.so: terminal.c
text.so: text.c
tilde.so: tilde.c
undo.so: undo.c
util.so: util.c

View File

@ -1,6 +1,6 @@
/* signals.c -- signal handling support for readline. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 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.
@ -73,6 +73,10 @@ typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt
# define sigemptyset(m)
#endif /* !HAVE_POSIX_SIGNALS */
#ifndef SA_RESTART
# define SA_RESTART 0
#endif
static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
@ -85,12 +89,12 @@ int rl_catch_signals = 1;
/* If non-zero, readline will install a signal handler for SIGWINCH. */
#ifdef SIGWINCH
int rl_catch_sigwinch = 1;
#else
int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
#endif
static int signals_set_flag;
#ifdef SIGWINCH
static int sigwinch_set_flag;
#endif
/* **************************************************************** */
/* */
@ -127,11 +131,11 @@ rl_signal_handler (sig)
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
/* Since the signal will not be blocked while we are in the signal
handler, ignore it until rl_clear_signals resets the catcher. */
if (sig == SIGINT
#ifdef SIGALRM
|| sig == SIGALRM
#endif
)
# if defined (SIGALRM)
if (sig == SIGINT || sig == SIGALRM)
# else
if (sig == SIGINT)
# endif
rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
@ -141,16 +145,16 @@ rl_signal_handler (sig)
rl_free_line_state ();
/* FALLTHROUGH */
case SIGTERM:
#if defined (SIGTSTP)
case SIGTSTP:
case SIGTTOU:
case SIGTTIN:
#endif /* SIGTSTP */
#ifdef SIGALRM
#if defined (SIGALRM)
case SIGALRM:
#endif
case SIGTERM:
#ifdef SIGQUIT
#if defined (SIGQUIT)
case SIGQUIT:
#endif
rl_cleanup_after_signal ();
@ -168,13 +172,10 @@ rl_signal_handler (sig)
signal (sig, SIG_ACK);
#endif
/* If we have the POSIX kill function, use it; otherwise, fall
back to the ISO C raise function. (Windows is an example of
a platform that has raise, but not kill.) */
#ifdef HAVE_KILL
#if defined (HAVE_KILL)
kill (getpid (), sig);
#else
raise (sig);
raise (sig); /* assume we have raise */
#endif
/* Let the signal that we just sent through. */
@ -250,7 +251,7 @@ rl_set_sighandler (sig, handler, ohandler)
struct sigaction act;
act.sa_handler = handler;
act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */
act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
sigemptyset (&act.sa_mask);
sigemptyset (&ohandler->sa_mask);
sigaction (sig, &act, &old_handler);
@ -292,11 +293,11 @@ rl_set_signals ()
{
rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
#ifdef SIGQUIT
#if defined (SIGQUIT)
rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
#endif
#ifdef SIGALRM
#if defined (SIGALRM)
oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (SIGALRM, &old_alrm, &dummy);
@ -347,10 +348,10 @@ rl_clear_signals ()
rl_sigaction (SIGINT, &old_int, &dummy);
rl_sigaction (SIGTERM, &old_term, &dummy);
#ifdef SIGQUIT
#if defined (SIGQUIT)
rl_sigaction (SIGQUIT, &old_quit, &dummy);
#endif
#ifdef SIGALRM
#if defined (SIGALRM)
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#endif
@ -387,7 +388,8 @@ void
rl_cleanup_after_signal ()
{
_rl_clean_up_for_exit ();
(*rl_deprep_term_function) ();
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
rl_clear_signals ();
rl_clear_pending_input ();
}
@ -396,7 +398,8 @@ rl_cleanup_after_signal ()
void
rl_reset_after_signal ()
{
(*rl_prep_term_function) (_rl_meta_flag);
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
rl_set_signals ();
}
@ -417,7 +420,7 @@ rl_free_line_state ()
_rl_kill_kbd_macro ();
rl_clear_message ();
_rl_init_argument ();
_rl_reset_argument ();
}
#endif /* HANDLE_SIGNALS */

View File

@ -3,7 +3,7 @@
# shlib-install - install a shared library and do any necessary host-specific
# post-installation configuration (like ldconfig)
#
# usage: shlib-install [-D] -O host_os -d installation-dir -i install-prog [-U] library
# usage: shlib-install [-D] -O host_os -d installation-dir [-b bin-dir] -i install-prog [-U] library
#
# Chet Ramey
# chet@po.cwru.edu
@ -15,7 +15,7 @@ INSTALLDIR=/usr/local/lib
LDCONFIG=ldconfig
PROGNAME=`basename $0`
USAGE="$PROGNAME [-D] -O host_os -d installation-dir -i install-prog [-U] library"
USAGE="$PROGNAME [-D] -O host_os -d installation-dir [-b bin-dir] -i install-prog [-U] library"
# process options
@ -23,6 +23,7 @@ while [ $# -gt 0 ]; do
case "$1" in
-O) shift; host_os="$1"; shift ;;
-d) shift; INSTALLDIR="$1"; shift ;;
-b) shift; BINDIR="$1" ; shift ;;
-i) shift; INSTALLPROG="$1" ; shift ;;
-D) echo=echo ; shift ;;
-U) uninstall=true ; shift ;;
@ -64,11 +65,30 @@ fi
# post-install/uninstall
# HP-UX and Darwin/MacOS X require that a shared library have execute permission
# Cygwin installs both a dll (which must go in $BINDIR) and an implicit
# link library (in $libdir)
case "$host_os" in
hpux*|darwin*|macosx*)
if [ -z "$uninstall" ]; then
chmod 555 ${INSTALLDIR}/${LIBNAME}
fi ;;
cygwin*)
IMPLIBNAME=`echo ${LIBNAME} \
| sed -e 's,^cyg,lib,' -e 's,[0-9]*.dll$,.dll.a,'`
if [ -z "$uninstall" ]; then
${echo} $RM ${BINDIR}/${LIBNAME}.${OLDSUFF}
if [ -f "$BINDIR/$LIBNAME" ]; then
${echo} $MV $BINDIR/$LIBNAME $BINDIR/$LIBNAME.$OLDSUFF
fi
${echo} $MV ${INSTALLDIR}/${LIBNAME} ${BINDIR}/${LIBNAME}
${echo} chmod a+x ${BINDIR}/${LIBNAME}
${echo} eval ${INSTALLPROG} ${LIBNAME}.a \
${INSTALLDIR}/${IMPLIBNAME}
else
${echo} ${RM} ${BINDIR}/${LIBNAME}
${echo} ${RM} ${INSTALLDIR}/${IMPLIBNAME}
fi ;;
*) ;;
esac
@ -88,24 +108,38 @@ case "$LIBNAME" in
LINK1=`echo $LIBNAME | sed 's:\(.*\)\.[0-9]\.[0-9]:\1:'` # libname.dylib
esac
INSTALL_LINK1='cd $INSTALLDIR ; ln -s $LIBNAME $LINK1'
INSTALL_LINK2='cd $INSTALLDIR ; ln -s $LIBNAME $LINK2'
INSTALL_LINK1='${echo} cd $INSTALLDIR && ${echo} ${LN} $LIBNAME $LINK1'
INSTALL_LINK2='${echo} cd $INSTALLDIR && ${echo} ${LN} $LIBNAME $LINK2'
#
# Create symlinks to the installed library. This section is incomplete.
#
case "$host_os" in
*linux*|bsdi4*|*gnu*|darwin*|macosx*)
*linux*)
# libname.so.M -> libname.so.M.N
${echo} ${RM} ${INSTALLDIR}/$LINK2
if [ -z "$uninstall" ]; then
${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK2
eval $INSTALL_LINK2
fi
# libname.so -> libname.so.M
${echo} ${RM} ${INSTALLDIR}/$LINK1
if [ -z "$uninstall" ]; then
${echo} cd $INSTALLDIR && ${echo} ${LN} $LINK2 $LINK1
fi
;;
bsdi4*|*gnu*|darwin*|macosx*|k*bsd*-gnu)
# libname.so.M -> libname.so.M.N
${echo} ${RM} ${INSTALLDIR}/$LINK2
if [ -z "$uninstall" ]; then
eval $INSTALL_LINK2
fi
# libname.so -> libname.so.M.N
${echo} ${RM} ${INSTALLDIR}/$LINK1
if [ -z "$uninstall" ]; then
${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1
eval $INSTALL_LINK1
fi
;;
@ -113,7 +147,7 @@ solaris2*|aix4.[2-9]*|osf*|irix[56]*|sysv[45]*|dgux*)
# libname.so -> libname.so.M
${echo} ${RM} ${INSTALLDIR}/$LINK1
if [ -z "$uninstall" ]; then
${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1
eval $INSTALL_LINK1
fi
;;
@ -124,19 +158,19 @@ freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*)
# libname.so -> libname.so.M
${echo} ${RM} ${INSTALLDIR}/$LINK1
if [ -z "$uninstall" ]; then
${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1
eval $INSTALL_LINK1
fi
else
# libname.so.M -> libname.so.M.N
${echo} ${RM} ${INSTALLDIR}/$LINK2
if [ -z "$uninstall" ]; then
${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK2
eval $INSTALL_LINK2
fi
# libname.so -> libname.so.M.N
${echo} ${RM} ${INSTALLDIR}/$LINK1
if [ -z "$uninstall" ]; then
${echo} ln -s $LIBNAME ${INSTALLDIR}/$LINK1
eval $INSTALL_LINK1
fi
fi
;;
@ -145,11 +179,16 @@ hpux1*)
# libname.sl -> libname.M
${echo} ${RM} ${INSTALLDIR}/$LINK1.sl
if [ -z "$uninstall" ]; then
# ${echo} ln -s $LIBNAME ${INSTALLDIR}/${LINK1}.sl
${echo} ln -s $LIBNAME ${INSTALLDIR}/${LINK1}
eval $INSTALL_LINK1
fi
;;
cygwin*)
# Links to .dlls don't work. Hence shobj-conf used DLLVERSION.dll
# instead of so.SHLIB_MAJOR.SHLIB_MINOR. The postinstall above
# took care of everything else.
;;
*) ;;
esac

View File

@ -41,9 +41,13 @@ SHOBJ_LIBS=
SHLIB_XLDFLAGS=
SHLIB_LIBS=
SHLIB_DOT='.'
SHLIB_LIBPREF='lib'
SHLIB_LIBSUFF='so'
SHLIB_LIBVERSION='$(SHLIB_LIBSUFF)'
SHLIB_DLLVERSION='$(SHLIB_MAJOR)'
PROGNAME=`basename $0`
USAGE="$PROGNAME [-C compiler] -c host_cpu -o host_os -v host_vendor"
@ -78,10 +82,14 @@ sunos4*)
sunos5*-*gcc*|solaris2*-*gcc*)
SHOBJ_CFLAGS=-fpic
SHOBJ_LD='${CC}'
# This line works for the Solaris linker in /usr/ccs/bin/ld
SHOBJ_LDFLAGS='-shared -Wl,-i -Wl,-h,$@'
# This line works for the GNU ld
# SHOBJ_LDFLAGS='-shared -Wl,-h,$@'
ld_used=`gcc -print-prog-name=ld`
if ${ld_used} -V 2>&1 | grep GNU >/dev/null 2>&1; then
# This line works for the GNU ld
SHOBJ_LDFLAGS='-shared -Wl,-h,$@'
else
# This line works for the Solaris linker in /usr/ccs/bin/ld
SHOBJ_LDFLAGS='-shared -Wl,-i -Wl,-h,$@'
fi
# SHLIB_XLDFLAGS='-R $(libdir)'
SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)'
@ -97,7 +105,7 @@ sunos5*|solaris2*)
;;
# All versions of Linux or the semi-mythical GNU Hurd.
linux*|gnu*)
linux*-*|gnu*-*|k*bsd*-gnu-*)
SHOBJ_CFLAGS=-fPIC
SHOBJ_LD='${CC}'
SHOBJ_LDFLAGS='-shared -Wl,-soname,$@'
@ -116,7 +124,7 @@ freebsd2* | netbsd*)
;;
# FreeBSD-3.x ELF
freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*)
freebsd[3-9]*|freebsdelf[3-9]*|freebsdaout[3-9]*|dragonfly*)
SHOBJ_CFLAGS=-fpic
SHOBJ_LD='${CC}'
@ -138,17 +146,23 @@ darwin*|macosx*)
SHOBJ_STATUS=unsupported
SHLIB_STATUS=supported
SHOBJ_CFLAGS='-dynamic -fno-common'
SHOBJ_CFLAGS='-fno-common'
SHOBJ_LD=/usr/bin/libtool
SHOBJ_LD='${CC}'
SHLIB_LIBVERSION='$(SHLIB_MAJOR)$(SHLIB_MINOR).$(SHLIB_LIBSUFF)'
SHLIB_LIBSUFF='dylib'
SHOBJ_LDFLAGS='-dynamic'
SHLIB_XLDFLAGS='-arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
case "${host_os}" in
darwin[78]*) SHOBJ_LDFLAGS=''
SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
;;
*) SHOBJ_LDFLAGS='-dynamic'
SHLIB_XLDFLAGS='-arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
;;
esac
SHLIB_LIBS='-lSystem'
SHLIB_LIBS='-lncurses' # see if -lcurses works on MacOS X 10.1
;;
openbsd*)
@ -296,6 +310,8 @@ hpux10*-*gcc*)
# must use gcc; the bundled cc cannot compile PIC code
SHOBJ_CFLAGS='-fpic'
SHOBJ_LD='${CC}'
# if you have problems linking here, moving the `-Wl,+h,$@' from
# SHLIB_XLDFLAGS to SHOBJ_LDFLAGS has been reported to work
SHOBJ_LDFLAGS='-shared -Wl,-b -Wl,+s'
SHLIB_XLDFLAGS='-Wl,+h,$@ -Wl,+b,$(libdir)'
@ -400,7 +416,39 @@ sysv5uw7*)
SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)'
;;
sysv5UnixWare*-*gcc*)
SHOBJ_CFLAGS=-fpic
SHOBJ_LD='${CC}'
SHOBJ_LDFLAGS='-shared'
SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)'
;;
sysv5UnixWare*)
SHOBJ_CFLAGS='-K PIC'
SHOBJ_LD=ld
SHOBJ_LDFLAGS='-G -dy -z text -h $@'
SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)'
;;
sysv5OpenUNIX*-*gcc*)
SHOBJ_CFLAGS=-fpic
SHOBJ_LD='${CC}'
SHOBJ_LDFLAGS='-shared'
SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)'
;;
sysv5OpenUNIX*)
SHOBJ_CFLAGS='-K PIC'
SHOBJ_LD=ld
SHOBJ_LDFLAGS='-G -dy -z text -h $@'
SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)'
;;
dgux*-*gcc*)
SHOBJ_CFLAGS=-fpic
SHOBJ_LD='${CC}'
@ -422,6 +470,24 @@ msdos*)
SHLIB_STATUS=unsupported
;;
cygwin*)
SHOBJ_LD='$(CC)'
SHOBJ_LDFLAGS='-shared -Wl,--enable-auto-import -Wl,--enable-auto-image-base -Wl,--export-all -Wl,--out-implib=$(@).a'
SHLIB_LIBPREF='cyg'
SHLIB_LIBSUFF='dll'
SHLIB_LIBVERSION='$(SHLIB_DLLVERSION).$(SHLIB_LIBSUFF)'
SHLIB_LIBS='$(TERMCAP_LIB)'
SHLIB_DOT=
# For official cygwin releases, DLLVERSION will be defined in the
# environment of configure, and will be incremented any time the API
# changes in a non-backwards compatible manner. Otherwise, it is just
# SHLIB_MAJOR.
if [ -n "$DLLVERSION" ] ; then
SHLIB_DLLVERSION="$DLLVERSION"
fi
;;
#
# Rely on correct gcc configuration for everything else
#
@ -449,8 +515,14 @@ echo SHOBJ_LIBS=\'"$SHOBJ_LIBS"\'
echo SHLIB_XLDFLAGS=\'"$SHLIB_XLDFLAGS"\'
echo SHLIB_LIBS=\'"$SHLIB_LIBS"\'
echo SHLIB_DOT=\'"$SHLIB_DOT"\'
echo SHLIB_LIBPREF=\'"$SHLIB_LIBPREF"\'
echo SHLIB_LIBSUFF=\'"$SHLIB_LIBSUFF"\'
echo SHLIB_LIBVERSION=\'"$SHLIB_LIBVERSION"\'
echo SHLIB_DLLVERSION=\'"$SHLIB_DLLVERSION"\'
echo SHOBJ_STATUS=\'"$SHOBJ_STATUS"\'
echo SHLIB_STATUS=\'"$SHLIB_STATUS"\'

View File

@ -1,6 +1,6 @@
/* terminal.c -- controlling the terminal with termcap. */
/* Copyright (C) 1996 Free Software Foundation, Inc.
/* Copyright (C) 1996-2005 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.
@ -78,6 +78,8 @@
#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
int rl_prefer_env_winsize;
/* **************************************************************** */
/* */
/* Terminal and Termcap */
@ -87,9 +89,6 @@
#ifndef __MSDOS__
static char *term_buffer = (char *)NULL;
static char *term_string_buffer = (char *)NULL;
/* Non-zero means this terminal can't really do anything. */
static int dumb_term;
#endif /* !__MSDOS__ */
static int tcap_initialized;
@ -134,7 +133,7 @@ char *_rl_term_up;
static char *_rl_visible_bell;
/* Non-zero means the terminal can auto-wrap lines. */
int _rl_term_autowrap;
int _rl_term_autowrap = -1;
/* Non-zero means that this terminal has a meta key. */
static int term_has_meta;
@ -159,6 +158,9 @@ static char *_rl_term_kh;
static char *_rl_term_kH;
static char *_rl_term_at7; /* @7 */
/* Delete key */
static char *_rl_term_kD;
/* Insert key */
static char *_rl_term_kI;
@ -205,12 +207,14 @@ _rl_get_screen_size (tty, ignore_env)
#if defined (TIOCGWINSZ)
struct winsize window_size;
#endif /* TIOCGWINSZ */
int wr, wc;
wr = wc = -1;
#if defined (TIOCGWINSZ)
if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
{
_rl_screenwidth = (int) window_size.ws_col;
_rl_screenheight = (int) window_size.ws_row;
wc = (int) window_size.ws_col;
wr = (int) window_size.ws_row;
}
#endif /* TIOCGWINSZ */
@ -232,13 +236,25 @@ _rl_get_screen_size (tty, ignore_env)
_emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
#endif
if (ignore_env || rl_prefer_env_winsize == 0)
{
_rl_screenwidth = wc;
_rl_screenheight = wr;
}
else
_rl_screenwidth = _rl_screenheight = -1;
/* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
is unset. */
is unset. If we prefer the environment, check it first before
assigning the value returned by the kernel. */
if (_rl_screenwidth <= 0)
{
if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
_rl_screenwidth = atoi (ss);
if (_rl_screenwidth <= 0)
_rl_screenwidth = wc;
#if defined (__DJGPP__)
if (_rl_screenwidth <= 0)
_rl_screenwidth = ScreenCols ();
@ -255,6 +271,9 @@ _rl_get_screen_size (tty, ignore_env)
if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
_rl_screenheight = atoi (ss);
if (_rl_screenheight <= 0)
_rl_screenheight = wr;
#if defined (__DJGPP__)
if (_rl_screenheight <= 0)
_rl_screenheight = ScreenRows ();
@ -286,16 +305,20 @@ void
_rl_set_screen_size (rows, cols)
int rows, cols;
{
if (rows == 0 || cols == 0)
return;
if (_rl_term_autowrap == -1)
_rl_init_terminal_io (rl_terminal_name);
_rl_screenheight = rows;
_rl_screenwidth = cols;
if (rows > 0)
_rl_screenheight = rows;
if (cols > 0)
{
_rl_screenwidth = cols;
if (_rl_term_autowrap == 0)
_rl_screenwidth--;
}
if (_rl_term_autowrap == 0)
_rl_screenwidth--;
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
if (rows > 0 || cols > 0)
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
}
void
@ -314,6 +337,12 @@ rl_get_screen_size (rows, cols)
if (cols)
*cols = _rl_screenwidth;
}
void
rl_reset_screen_size ()
{
_rl_get_screen_size (fileno (rl_instream), 0);
}
void
rl_resize_terminal ()
@ -347,6 +376,7 @@ static struct _tc_string tc_strings[] =
{ "ei", &_rl_term_ei },
{ "ic", &_rl_term_ic },
{ "im", &_rl_term_im },
{ "kD", &_rl_term_kD }, /* delete */
{ "kH", &_rl_term_kH }, /* home down ?? */
{ "kI", &_rl_term_kI }, /* insert */
{ "kd", &_rl_term_kd },
@ -381,11 +411,7 @@ get_term_capabilities (bp)
register int i;
for (i = 0; i < NUM_TC_STRINGS; i++)
# ifdef __LCC__
*(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
# else
*(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
# endif
#endif
tcap_initialized = 1;
}
@ -401,7 +427,6 @@ _rl_init_terminal_io (terminal_name)
term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
_rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
tty = rl_instream ? fileno (rl_instream) : 0;
_rl_screenwidth = _rl_screenheight = 0;
if (term == 0)
term = "dumb";
@ -451,12 +476,17 @@ _rl_init_terminal_io (terminal_name)
_rl_term_autowrap = 0; /* used by _rl_get_screen_size */
/* Allow calling application to set default height and width, using
rl_set_screen_size */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
{
#if defined (__EMX__)
_emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
_rl_screenwidth--;
_emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
_rl_screenwidth--;
#else /* !__EMX__ */
_rl_get_screen_size (tty, 0);
_rl_get_screen_size (tty, 0);
#endif /* !__EMX__ */
}
/* Defaults. */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
@ -471,7 +501,7 @@ _rl_init_terminal_io (terminal_name)
_rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
_rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
_rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
_rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL;
_rl_term_kh = _rl_term_kH = _rl_term_kI = _rl_term_kD = (char *)NULL;
_rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
_rl_term_mm = _rl_term_mo = (char *)NULL;
_rl_term_ve = _rl_term_vs = (char *)NULL;
@ -503,7 +533,10 @@ _rl_init_terminal_io (terminal_name)
_rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
_rl_get_screen_size (tty, 0);
/* Allow calling application to set default height and width, using
rl_set_screen_size */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
_rl_get_screen_size (tty, 0);
/* "An application program can assume that the terminal can do
character insertion if *any one of* the capabilities `IC',
@ -542,13 +575,15 @@ bind_termcap_arrow_keys (map)
xkeymap = _rl_keymap;
_rl_keymap = map;
_rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
_rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
_rl_bind_if_unbound (_rl_term_kr, rl_forward);
_rl_bind_if_unbound (_rl_term_kl, rl_backward);
rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history);
rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history);
rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char);
rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char);
_rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
_rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete);
_rl_keymap = xkeymap;
}
@ -575,6 +610,7 @@ int
rl_reset_terminal (terminal_name)
const char *terminal_name;
{
_rl_screenwidth = _rl_screenheight = 0;
_rl_init_terminal_io (terminal_name);
return 0;
}
@ -656,8 +692,8 @@ rl_ding ()
tputs (_rl_visible_bell, 1, _rl_output_character_function);
break;
}
#endif
/* FALLTHROUGH */
#endif
case AUDIBLE_BELL:
fprintf (stderr, "\007");
fflush (stderr);

View File

@ -1,6 +1,6 @@
/* text.c -- text handling commands for readline. */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 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.
@ -62,6 +62,11 @@
static int rl_change_case PARAMS((int, int));
static int _rl_char_search PARAMS((int, int, int));
#if defined (READLINE_CALLBACKS)
static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *));
static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *));
#endif
/* **************************************************************** */
/* */
/* Insert and Delete */
@ -170,6 +175,9 @@ _rl_fix_point (fix_mark_too)
}
#undef _RL_FIX_POINT
/* Replace the contents of the line buffer between START and END with
TEXT. The operation is undoable. To replace the entire line in an
undoable mode, use _rl_replace_text(text, 0, rl_end); */
int
_rl_replace_text (text, start, end)
const char *text;
@ -417,8 +425,7 @@ rl_end_of_line (count, key)
return 0;
}
/* XXX - these might need changes for multibyte characters */
/* Move forward a word. We do what Emacs does. */
/* Move forward a word. We do what Emacs does. Handles multibyte chars. */
int
rl_forward_word (count, key)
int count, key;
@ -435,68 +442,80 @@ rl_forward_word (count, key)
/* If we are not in a word, move forward until we are in one.
Then, move forward until we hit a non-alphabetic character. */
c = rl_line_buffer[rl_point];
if (rl_alphabetic (c) == 0)
c = _rl_char_value (rl_line_buffer, rl_point);
if (_rl_walphabetic (c) == 0)
{
while (++rl_point < rl_end)
rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
while (rl_point < rl_end)
{
c = rl_line_buffer[rl_point];
if (rl_alphabetic (c))
c = _rl_char_value (rl_line_buffer, rl_point);
if (_rl_walphabetic (c))
break;
rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
}
}
if (rl_point == rl_end)
return 0;
while (++rl_point < rl_end)
rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
while (rl_point < rl_end)
{
c = rl_line_buffer[rl_point];
if (rl_alphabetic (c) == 0)
c = _rl_char_value (rl_line_buffer, rl_point);
if (_rl_walphabetic (c) == 0)
break;
rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
}
--count;
}
return 0;
}
/* Move backward a word. We do what Emacs does. */
/* Move backward a word. We do what Emacs does. Handles multibyte chars. */
int
rl_backward_word (count, key)
int count, key;
{
int c;
int c, p;
if (count < 0)
return (rl_forward_word (-count, key));
while (count)
{
if (!rl_point)
if (rl_point == 0)
return 0;
/* Like rl_forward_word (), except that we look at the characters
just before point. */
c = rl_line_buffer[rl_point - 1];
if (rl_alphabetic (c) == 0)
p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
c = _rl_char_value (rl_line_buffer, p);
if (_rl_walphabetic (c) == 0)
{
while (--rl_point)
rl_point = p;
while (rl_point > 0)
{
c = rl_line_buffer[rl_point - 1];
if (rl_alphabetic (c))
p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
c = _rl_char_value (rl_line_buffer, p);
if (_rl_walphabetic (c))
break;
rl_point = p;
}
}
while (rl_point)
{
c = rl_line_buffer[rl_point - 1];
if (rl_alphabetic (c) == 0)
p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
c = _rl_char_value (rl_line_buffer, p);
if (_rl_walphabetic (c) == 0)
break;
else
--rl_point;
rl_point = p;
}
--count;
@ -753,10 +772,8 @@ _rl_insert_char (count, c)
return 0;
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX == 1 || rl_byte_oriented)
{
#endif
/* We are inserting a single character.
If there is pending input, then make a string of all of the
pending characters that are bound to rl_insert, and insert
@ -772,8 +789,8 @@ _rl_insert_char (count, c)
str[0] = c;
rl_insert_text (str);
}
#if defined (HANDLE_MULTIBYTE)
}
#if defined (HANDLE_MULTIBYTE)
else
{
rl_insert_text (incoming);
@ -801,13 +818,10 @@ _rl_overwrite_char (count, c)
k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
#endif
rl_begin_undo_group ();
for (i = 0; i < count; i++)
{
rl_begin_undo_group ();
if (rl_point < rl_end)
rl_delete (1, c);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (mbkey);
@ -815,9 +829,12 @@ _rl_overwrite_char (count, c)
#endif
_rl_insert_char (1, c);
rl_end_undo_group ();
if (rl_point < rl_end)
rl_delete (1, c);
}
rl_end_undo_group ();
return 0;
}
@ -830,27 +847,63 @@ rl_insert (count, c)
}
/* Insert the next typed character verbatim. */
int
rl_quoted_insert (count, key)
int count, key;
static int
_rl_insert_next (count)
int count;
{
int c;
#if defined (HANDLE_SIGNALS)
_rl_disable_tty_signals ();
#endif
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_SIGNALS)
_rl_restore_tty_signals ();
if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
_rl_restore_tty_signals ();
#endif
return (_rl_insert_char (count, c));
}
#if defined (READLINE_CALLBACKS)
static int
_rl_insert_next_callback (data)
_rl_callback_generic_arg *data;
{
int count;
count = data->count;
/* Deregister function, let rl_callback_read_char deallocate data */
_rl_callback_func = 0;
_rl_want_redisplay = 1;
return _rl_insert_next (count);
}
#endif
int
rl_quoted_insert (count, key)
int count, key;
{
/* Let's see...should the callback interface futz with signal handling? */
#if defined (HANDLE_SIGNALS)
if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
_rl_disable_tty_signals ();
#endif
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_func = _rl_insert_next_callback;
return (0);
}
#endif
return _rl_insert_next (count);
}
/* Insert a tab character. */
int
rl_tab_insert (count, key)
@ -877,7 +930,8 @@ rl_newline (count, key)
if (rl_editing_mode == vi_mode)
{
_rl_vi_done_inserting ();
_rl_vi_reset_last ();
if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
_rl_vi_reset_last ();
}
#endif /* VI_MODE */
@ -935,9 +989,12 @@ _rl_overwrite_rubout (count, key)
rl_delete_text (opoint, rl_point);
/* Emacs puts point at the beginning of the sequence of spaces. */
opoint = rl_point;
_rl_insert_char (l, ' ');
rl_point = opoint;
if (rl_point < rl_end)
{
opoint = rl_point;
_rl_insert_char (l, ' ');
rl_point = opoint;
}
rl_end_undo_group ();
@ -981,43 +1038,17 @@ _rl_rubout_char (count, key)
return -1;
}
orig_point = rl_point;
if (count > 1 || rl_explicit_arg)
{
orig_point = rl_point;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_backward_char (count, key);
else
#endif
rl_backward_byte (count, key);
rl_backward_char (count, key);
rl_kill_text (orig_point, rl_point);
}
else
else if (MB_CUR_MAX == 1 || rl_byte_oriented)
{
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX == 1 || rl_byte_oriented)
{
#endif
c = rl_line_buffer[--rl_point];
rl_delete_text (rl_point, rl_point + 1);
#if defined (HANDLE_MULTIBYTE)
}
else
{
int orig_point;
orig_point = rl_point;
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
c = rl_line_buffer[rl_point];
rl_delete_text (rl_point, orig_point);
}
#endif /* HANDLE_MULTIBYTE */
/* I don't think that the hack for end of line is needed for
multibyte chars. */
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX == 1 || rl_byte_oriented)
#endif
c = rl_line_buffer[--rl_point];
rl_delete_text (rl_point, orig_point);
/* The erase-at-end-of-line hack is of questionable merit now. */
if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
{
int l;
@ -1025,6 +1056,11 @@ _rl_rubout_char (count, key)
_rl_erase_at_end_of_line (l);
}
}
else
{
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
rl_delete_text (rl_point, orig_point);
}
return 0;
}
@ -1035,8 +1071,6 @@ int
rl_delete (count, key)
int count, key;
{
int r;
if (count < 0)
return (_rl_rubout_char (-count, key));
@ -1049,27 +1083,22 @@ rl_delete (count, key)
if (count > 1 || rl_explicit_arg)
{
int orig_point = rl_point;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_forward_char (count, key);
else
#endif
rl_forward_byte (count, key);
r = rl_kill_text (orig_point, rl_point);
rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
return r;
}
else
{
int new_point;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
new_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
else
new_point = rl_point + 1;
return (rl_delete_text (rl_point, new_point));
new_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
rl_delete_text (rl_point, new_point);
}
return 0;
}
/* Delete the character under the cursor, unless the insertion
@ -1106,6 +1135,10 @@ rl_delete_horizontal_space (count, ignore)
rl_delete_text (start, rl_point);
rl_point = start;
}
if (rl_point < 0)
rl_point = 0;
return 0;
}
@ -1199,42 +1232,80 @@ static int
rl_change_case (count, op)
int count, op;
{
register int start, end;
int inword, c;
int start, next, end;
int inword, c, nc, nop;
#if defined (HANDLE_MULTIBYTE)
wchar_t wc, nwc;
char mb[MB_LEN_MAX+1];
int mblen, p;
mbstate_t ps;
#endif
start = rl_point;
rl_forward_word (count, 0);
end = rl_point;
if (op != UpCase && op != DownCase && op != CapCase)
{
rl_ding ();
return -1;
}
if (count < 0)
SWAP (start, end);
#if defined (HANDLE_MULTIBYTE)
memset (&ps, 0, sizeof (mbstate_t));
#endif
/* We are going to modify some text, so let's prepare to undo it. */
rl_modifying (start, end);
for (inword = 0; start < end; start++)
inword = 0;
while (start < end)
{
c = rl_line_buffer[start];
switch (op)
c = _rl_char_value (rl_line_buffer, start);
/* This assumes that the upper and lower case versions are the same width. */
next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
if (_rl_walphabetic (c) == 0)
{
case UpCase:
rl_line_buffer[start] = _rl_to_upper (c);
break;
case DownCase:
rl_line_buffer[start] = _rl_to_lower (c);
break;
case CapCase:
rl_line_buffer[start] = (inword == 0) ? _rl_to_upper (c) : _rl_to_lower (c);
inword = rl_alphabetic (rl_line_buffer[start]);
break;
default:
rl_ding ();
return -1;
inword = 0;
start = next;
continue;
}
if (op == CapCase)
{
nop = inword ? DownCase : UpCase;
inword = 1;
}
else
nop = op;
if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c))
{
nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
rl_line_buffer[start] = nc;
}
#if defined (HANDLE_MULTIBYTE)
else
{
mbrtowc (&wc, rl_line_buffer + start, end - start, &ps);
nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
if (nwc != wc) /* just skip unchanged characters */
{
mblen = wcrtomb (mb, nwc, &ps);
if (mblen > 0)
mb[mblen] = '\0';
/* Assume the same width */
strncpy (rl_line_buffer + start, mb, mblen);
}
}
#endif
start = next;
}
rl_point = end;
return 0;
}
@ -1314,11 +1385,11 @@ rl_transpose_chars (count, key)
{
#if defined (HANDLE_MULTIBYTE)
char *dummy;
int i, prev_point;
int i;
#else
char dummy[2];
#endif
int char_length;
int char_length, prev_point;
if (count == 0)
return 0;
@ -1333,20 +1404,12 @@ rl_transpose_chars (count, key)
if (rl_point == rl_end)
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
--rl_point;
rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
count = 1;
}
#if defined (HANDLE_MULTIBYTE)
prev_point = rl_point;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
#endif
rl_point--;
rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
#if defined (HANDLE_MULTIBYTE)
char_length = prev_point - rl_point;
@ -1480,10 +1543,33 @@ _rl_char_search (count, fdir, bdir)
}
#endif /* !HANDLE_MULTIBYTE */
#if defined (READLINE_CALLBACKS)
static int
_rl_char_search_callback (data)
_rl_callback_generic_arg *data;
{
_rl_callback_func = 0;
_rl_want_redisplay = 1;
return (_rl_char_search (data->count, data->i1, data->i2));
}
#endif
int
rl_char_search (count, key)
int count, key;
{
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_data->i1 = FFIND;
_rl_callback_data->i2 = BFIND;
_rl_callback_func = _rl_char_search_callback;
return (0);
}
#endif
return (_rl_char_search (count, FFIND, BFIND));
}
@ -1491,6 +1577,17 @@ int
rl_backward_char_search (count, key)
int count, key;
{
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_data->i1 = BFIND;
_rl_callback_data->i2 = FFIND;
_rl_callback_func = _rl_char_search_callback;
return (0);
}
#endif
return (_rl_char_search (count, BFIND, FFIND));
}

View File

@ -43,9 +43,9 @@
#endif /* HAVE_STDLIB_H */
#include <sys/types.h>
#ifdef HAVE_PWD_H
#if defined (HAVE_PWD_H)
#include <pwd.h>
#endif /* HAVE_PWD_H */
#endif
#include "tilde.h"
@ -55,10 +55,14 @@ static void *xmalloc (), *xrealloc ();
# include "xmalloc.h"
#endif /* TEST || STATIC_MALLOC */
#if defined (HAVE_GETPWNAM) && !defined (HAVE_GETPW_DECLS)
#if !defined (HAVE_GETPW_DECLS)
# if defined (HAVE_GETPWUID)
extern struct passwd *getpwuid PARAMS((uid_t));
# endif
# if defined (HAVE_GETPWNAM)
extern struct passwd *getpwnam PARAMS((const char *));
#endif /* defined (HAVE_GETPWNAM) && !HAVE_GETPW_DECLS */
# endif
#endif /* !HAVE_GETPW_DECLS */
#if !defined (savestring)
#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
@ -279,6 +283,39 @@ isolate_tilde_prefix (fname, lenp)
return ret;
}
#if 0
/* Public function to scan a string (FNAME) beginning with a tilde and find
the portion of the string that should be passed to the tilde expansion
function. Right now, it just calls tilde_find_suffix and allocates new
memory, but it can be expanded to do different things later. */
char *
tilde_find_word (fname, flags, lenp)
const char *fname;
int flags, *lenp;
{
int x;
char *r;
x = tilde_find_suffix (fname);
if (x == 0)
{
r = savestring (fname);
if (lenp)
*lenp = 0;
}
else
{
r = (char *)xmalloc (1 + x);
strncpy (r, fname, x);
r[x] = '\0';
if (lenp)
*lenp = x;
}
return r;
}
#endif
/* Return a string that is PREFIX concatenated with SUFFIX starting at
SUFFIND. */
static char *
@ -349,8 +386,11 @@ tilde_expand_word (filename)
/* No preexpansion hook, or the preexpansion hook failed. Look in the
password database. */
dirname = (char *)NULL;
#ifdef HAVE_GETPWNAM
#if defined (HAVE_GETPWNAM)
user_entry = getpwnam (username);
#else
user_entry = 0;
#endif
if (user_entry == 0)
{
/* If the calling program has a special syntax for expanding tildes,
@ -370,12 +410,12 @@ tilde_expand_word (filename)
if (dirname == 0)
dirname = savestring (filename);
}
#if defined (HAVE_GETPWENT)
else
{
free (username);
dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len);
}
endpwent ();
#endif
return (dirname);

View File

@ -71,6 +71,9 @@ extern char *tilde_expand PARAMS((const char *));
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
extern char *tilde_expand_word PARAMS((const char *));
/* Find the portion of the string beginning with ~ that should be expanded. */
extern char *tilde_find_word PARAMS((const char *, int, int *));
#ifdef __cplusplus
}
#endif

View File

@ -237,7 +237,12 @@ rl_revert_line (count, key)
{
while (rl_undo_list)
rl_do_undo ();
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
rl_point = rl_mark = 0; /* rl_end should be set correctly */
#endif
}
return 0;
}

View File

@ -1,6 +1,6 @@
/* util.c -- readline utility functions */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 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.
@ -44,6 +44,7 @@
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
#if defined (TIOCSTAT_IN_SYS_IOCTL)
# include <sys/ioctl.h>
@ -78,13 +79,29 @@ rl_alphabetic (c)
strchr (pathname_alphabetic_chars, c) != NULL);
}
#if defined (HANDLE_MULTIBYTE)
int
_rl_walphabetic (wc)
wchar_t wc;
{
int c;
if (iswalnum (wc))
return (1);
c = wc & 0177;
return (_rl_allow_pathname_alphabetic_chars &&
strchr (pathname_alphabetic_chars, c) != NULL);
}
#endif
/* How to abort things. */
int
_rl_abort_internal ()
{
rl_ding ();
rl_clear_message ();
_rl_init_argument ();
_rl_reset_argument ();
rl_clear_pending_input ();
RL_UNSETSTATE (RL_STATE_MACRODEF);
@ -250,7 +267,7 @@ _rl_strpbrk (string1, string2)
{
v = _rl_get_char_len (string1, &ps);
if (v > 1)
string += v - 1; /* -1 to account for auto-increment in loop */
string1 += v - 1; /* -1 to account for auto-increment in loop */
}
#endif
}

View File

@ -130,7 +130,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, rl_revert_line }, /* U */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* V */
{ ISFUNC, rl_vi_next_word }, /* W */
{ ISFUNC, rl_rubout }, /* X */
{ ISFUNC, rl_vi_rubout }, /* X */
{ ISFUNC, rl_vi_yank_to }, /* Y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Z */

View File

@ -1,7 +1,7 @@
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 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.
@ -63,6 +63,8 @@
#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
#endif
int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
/* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert;
@ -83,12 +85,12 @@ static int vi_continued_command;
static char *vi_insert_buffer;
static int vi_insert_buffer_size;
static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
static int _rl_vi_last_repeat = 1;
static int _rl_vi_last_arg_sign = 1;
static int _rl_vi_last_motion;
#if defined (HANDLE_MULTIBYTE)
static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
static int _rl_vi_last_search_mblen;
#else
static int _rl_vi_last_search_char;
#endif
@ -106,8 +108,22 @@ static int vi_mark_chars['z' - 'a' + 1];
static void _rl_vi_stuff_insert PARAMS((int));
static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
static int _rl_vi_arg_dispatch PARAMS((int));
static int rl_digit_loop1 PARAMS((void));
static int _rl_vi_set_mark PARAMS((void));
static int _rl_vi_goto_mark PARAMS((void));
static int _rl_vi_callback_getchar PARAMS((char *, int));
#if defined (READLINE_CALLBACKS)
static int _rl_vi_callback_set_mark PARAMS((_rl_callback_generic_arg *));
static int _rl_vi_callback_goto_mark PARAMS((_rl_callback_generic_arg *));
static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *));
static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *));
#endif
void
_rl_vi_initialize_line ()
{
@ -115,6 +131,8 @@ _rl_vi_initialize_line ()
for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
vi_mark_chars[i] = -1;
RL_UNSETSTATE(RL_STATE_VICMDONCE);
}
void
@ -135,6 +153,16 @@ _rl_vi_set_last (key, repeat, sign)
_rl_vi_last_arg_sign = sign;
}
/* A convenience function that calls _rl_vi_set_last to save the last command
information and enters insertion mode. */
void
rl_vi_start_inserting (key, repeat, sign)
int key, repeat, sign;
{
_rl_vi_set_last (key, repeat, sign);
rl_vi_insertion_mode (1, key);
}
/* Is the command C a VI mode text modification command? */
int
_rl_vi_textmod_command (c)
@ -261,10 +289,12 @@ rl_vi_search (count, key)
switch (key)
{
case '?':
_rl_free_saved_history_line ();
rl_noninc_forward_search (count, key);
break;
case '/':
_rl_free_saved_history_line ();
rl_noninc_reverse_search (count, key);
break;
@ -297,10 +327,8 @@ rl_vi_complete (ignore, key)
rl_complete (0, key);
if (key == '*' || key == '\\')
{
_rl_vi_set_last (key, 1, rl_arg_sign);
rl_vi_insertion_mode (1, key);
}
rl_vi_start_inserting (key, 1, rl_arg_sign);
return (0);
}
@ -310,8 +338,7 @@ rl_vi_tilde_expand (ignore, key)
int ignore, key;
{
rl_tilde_expand (0, key);
_rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */
rl_vi_insertion_mode (1, key);
rl_vi_start_inserting (key, 1, rl_arg_sign);
return (0);
}
@ -429,7 +456,8 @@ rl_vi_eWord (count, ignore)
/* Move to the next non-whitespace character (to the start of the
next word). */
while (++rl_point < rl_end && whitespace (rl_line_buffer[rl_point]));
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
rl_point++;
if (rl_point && rl_point < rl_end)
{
@ -640,7 +668,7 @@ _rl_vi_done_inserting ()
}
else
{
if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list)
if ((_rl_vi_last_key_before_insert == 'i' || _rl_vi_last_key_before_insert == 'a') && rl_undo_list)
_rl_vi_save_insert (rl_undo_list);
/* XXX - Other keys probably need to be checked. */
else if (_rl_vi_last_key_before_insert == 'C')
@ -660,6 +688,13 @@ rl_vi_movement_mode (count, key)
_rl_keymap = vi_movement_keymap;
_rl_vi_done_inserting ();
/* This is how POSIX.2 says `U' should behave -- everything up until the
first time you go into command mode should not be undone. */
if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0)
rl_free_undo_list ();
RL_SETSTATE (RL_STATE_VICMDONCE);
return (0);
}
@ -681,7 +716,7 @@ _rl_vi_change_mbchar_case (count)
{
wchar_t wc;
char mb[MB_LEN_MAX+1];
int mblen;
int mblen, p;
mbstate_t ps;
memset (&ps, 0, sizeof (mbstate_t));
@ -704,11 +739,14 @@ _rl_vi_change_mbchar_case (count)
/* Vi is kind of strange here. */
if (wc)
{
mblen = wctomb (mb, wc);
p = rl_point;
mblen = wcrtomb (mb, wc, &ps);
if (mblen >= 0)
mb[mblen] = '\0';
rl_begin_undo_group ();
rl_delete (1, 0);
rl_vi_delete (1, 0);
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++; /* XXX - should we advance more than 1 for mbchar? */
rl_insert_text (mb);
rl_end_undo_group ();
rl_vi_check ();
@ -725,12 +763,13 @@ int
rl_vi_change_case (count, ignore)
int count, ignore;
{
char c = 0;
int c, p;
/* Don't try this on an empty line. */
if (rl_point >= rl_end)
return (0);
c = 0;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
return (_rl_vi_change_mbchar_case (count));
@ -752,8 +791,11 @@ rl_vi_change_case (count, ignore)
/* Vi is kind of strange here. */
if (c)
{
p = rl_point;
rl_begin_undo_group ();
rl_delete (1, c);
rl_vi_delete (1, c);
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++;
_rl_insert_char (1, c);
rl_end_undo_group ();
rl_vi_check ();
@ -771,7 +813,9 @@ rl_vi_put (count, key)
if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
rl_yank (1, key);
while (count--)
rl_yank (1, key);
rl_backward_char (1, key);
return (0);
}
@ -819,7 +863,10 @@ rl_vi_domove (key, nextkey)
{
save = rl_numeric_arg;
rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION);
rl_digit_loop1 ();
RL_UNSETSTATE (RL_STATE_VIMOTION);
rl_numeric_arg *= save;
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key (); /* real command */
@ -892,52 +939,59 @@ rl_vi_domove (key, nextkey)
return (0);
}
/* Process C as part of the current numeric argument. Return -1 if the
argument should be aborted, 0 if we should not read any more chars, and
1 if we should continue to read chars. */
static int
_rl_vi_arg_dispatch (c)
int c;
{
int key;
key = c;
if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
{
rl_numeric_arg *= 4;
return 1;
}
c = UNMETA (c);
if (_rl_digit_p (c))
{
if (rl_explicit_arg)
rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
else
rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
return 1;
}
else
{
rl_clear_message ();
rl_stuff_char (key);
return 0;
}
}
/* A simplified loop for vi. Don't dispatch key at end.
Don't recognize minus sign?
Should this do rl_save_prompt/rl_restore_prompt? */
static int
rl_digit_loop1 ()
{
int key, c;
int c, r;
RL_SETSTATE(RL_STATE_NUMERICARG);
while (1)
{
if (rl_numeric_arg > 1000000)
{
rl_explicit_arg = rl_numeric_arg = 0;
rl_ding ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return 1;
}
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
RL_SETSTATE(RL_STATE_MOREINPUT);
key = c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (_rl_arg_overflow ())
return 1;
if (c >= 0 && _rl_keymap[c].type == ISFUNC &&
_rl_keymap[c].function == rl_universal_argument)
{
rl_numeric_arg *= 4;
continue;
}
c = _rl_arg_getchar ();
c = UNMETA (c);
if (_rl_digit_p (c))
{
if (rl_explicit_arg)
rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
else
rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
}
else
{
rl_clear_message ();
rl_stuff_char (key);
break;
}
r = _rl_vi_arg_dispatch (c);
if (r <= 0)
break;
}
RL_UNSETSTATE(RL_STATE_NUMERICARG);
@ -1017,8 +1071,7 @@ rl_vi_change_to (count, key)
/* `C' does not save the text inserted for undoing or redoing. */
if (_rl_uppercase_p (key) == 0)
_rl_vi_doing_insert = 1;
_rl_vi_set_last (key, count, rl_arg_sign);
rl_vi_insertion_mode (1, key);
rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
}
return (0);
@ -1028,8 +1081,9 @@ int
rl_vi_yank_to (count, key)
int count, key;
{
int c, save = rl_point;
int c, save;
save = rl_point;
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
@ -1053,12 +1107,46 @@ rl_vi_yank_to (count, key)
return (0);
}
int
rl_vi_rubout (count, key)
int count, key;
{
int p, opoint;
if (count < 0)
return (rl_vi_delete (-count, key));
if (rl_point == 0)
{
rl_ding ();
return -1;
}
opoint = rl_point;
if (count > 1 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_backward_char (count, key);
else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
rl_point -= count;
if (rl_point < 0)
rl_point = 0;
rl_kill_text (rl_point, opoint);
return (0);
}
int
rl_vi_delete (count, key)
int count, key;
{
int end;
if (count < 0)
return (rl_vi_rubout (-count, key));
if (rl_end == 0)
{
rl_ding ();
@ -1077,6 +1165,7 @@ rl_vi_delete (count, key)
if (rl_point > 0 && rl_point == rl_end)
rl_backward_char (1, key);
return (0);
}
@ -1097,64 +1186,102 @@ rl_vi_first_print (count, key)
return (rl_vi_back_to_indent (1, key));
}
static int _rl_cs_dir, _rl_cs_orig_dir;
#if defined (READLINE_CALLBACKS)
static int
_rl_vi_callback_char_search (data)
_rl_callback_generic_arg *data;
{
#if defined (HANDLE_MULTIBYTE)
_rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
#else
RL_SETSTATE(RL_STATE_MOREINPUT);
_rl_vi_last_search_char = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#endif
_rl_callback_func = 0;
_rl_want_redisplay = 1;
#if defined (HANDLE_MULTIBYTE)
return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));
#else
return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_char));
#endif
}
#endif
int
rl_vi_char_search (count, key)
int count, key;
{
#if defined (HANDLE_MULTIBYTE)
static char *target;
static int mb_len;
static int tlen;
#else
static char target;
#endif
static int orig_dir, dir;
if (key == ';' || key == ',')
dir = key == ';' ? orig_dir : -orig_dir;
_rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
else
{
switch (key)
{
case 't':
_rl_cs_orig_dir = _rl_cs_dir = FTO;
break;
case 'T':
_rl_cs_orig_dir = _rl_cs_dir = BTO;
break;
case 'f':
_rl_cs_orig_dir = _rl_cs_dir = FFIND;
break;
case 'F':
_rl_cs_orig_dir = _rl_cs_dir = BFIND;
break;
}
if (vi_redoing)
#if defined (HANDLE_MULTIBYTE)
target = _rl_vi_last_search_mbchar;
#else
target = _rl_vi_last_search_char;
{
/* set target and tlen below */
}
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_data->i1 = _rl_cs_dir;
_rl_callback_func = _rl_vi_callback_char_search;
return (0);
}
#endif
else
{
#if defined (HANDLE_MULTIBYTE)
mb_len = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
target = _rl_vi_last_search_mbchar;
_rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
#else
RL_SETSTATE(RL_STATE_MOREINPUT);
_rl_vi_last_search_char = target = rl_read_key ();
_rl_vi_last_search_char = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#endif
}
switch (key)
{
case 't':
orig_dir = dir = FTO;
break;
case 'T':
orig_dir = dir = BTO;
break;
case 'f':
orig_dir = dir = FFIND;
break;
case 'F':
orig_dir = dir = BFIND;
break;
}
}
#if defined (HANDLE_MULTIBYTE)
return (_rl_char_search_internal (count, dir, target, mb_len));
target = _rl_vi_last_search_mbchar;
tlen = _rl_vi_last_search_mblen;
#else
return (_rl_char_search_internal (count, dir, target));
target = _rl_vi_last_search_char;
#endif
#if defined (HANDLE_MULTIBYTE)
return (_rl_char_search_internal (count, _rl_cs_dir, target, tlen));
#else
return (_rl_char_search_internal (count, _rl_cs_dir, target));
#endif
}
@ -1265,51 +1392,100 @@ rl_vi_bracktype (c)
}
}
/* XXX - think about reading an entire mbchar with _rl_read_mbchar and
inserting it in one bunch instead of the loop below (like in
rl_vi_char_search or _rl_vi_change_mbchar_case. Set c to mbchar[0]
for test against 033 or ^C. Make sure that _rl_read_mbchar does
this right. */
static int
_rl_vi_change_char (count, c, mb)
int count, c;
char *mb;
{
int p;
if (c == '\033' || c == CTRL ('C'))
return -1;
rl_begin_undo_group ();
while (count-- && rl_point < rl_end)
{
p = rl_point;
rl_vi_delete (1, c);
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (mb);
else
#endif
_rl_insert_char (1, c);
}
/* The cursor shall be left on the last character changed. */
rl_backward_char (1, c);
rl_end_undo_group ();
return (0);
}
static int
_rl_vi_callback_getchar (mb, mblen)
char *mb;
int mblen;
{
int c;
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = _rl_read_mbstring (c, mb, mblen);
#endif
return c;
}
#if defined (READLINE_CALLBACKS)
static int
_rl_vi_callback_change_char (data)
_rl_callback_generic_arg *data;
{
int c;
char mb[MB_LEN_MAX];
_rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
_rl_callback_func = 0;
_rl_want_redisplay = 1;
return (_rl_vi_change_char (data->count, c, mb));
}
#endif
int
rl_vi_change_char (count, key)
int count, key;
{
int c;
char mb[MB_LEN_MAX];
if (vi_redoing)
c = _rl_vi_last_replacement;
else
{
RL_SETSTATE(RL_STATE_MOREINPUT);
_rl_vi_last_replacement = c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
c = _rl_vi_last_replacement;
mb[0] = c;
mb[1] = '\0';
}
if (c == '\033' || c == CTRL ('C'))
return -1;
while (count-- && rl_point < rl_end)
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
rl_begin_undo_group ();
rl_delete (1, c);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
while (_rl_insert_char (1, c))
{
RL_SETSTATE (RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE (RL_STATE_MOREINPUT);
}
else
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_func = _rl_vi_callback_change_char;
return (0);
}
#endif
_rl_insert_char (1, c);
if (count == 0)
rl_backward_char (1, c);
else
_rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
rl_end_undo_group ();
}
return (0);
return (_rl_vi_change_char (count, c, mb));
}
int
@ -1318,7 +1494,7 @@ rl_vi_subst (count, key)
{
/* If we are redoing, rl_vi_change_to will stuff the last motion char */
if (vi_redoing == 0)
rl_stuff_char ((key == 'S') ? 'c' : ' '); /* `S' == `cc', `s' == `c ' */
rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
return (rl_vi_change_to (count, 'c'));
}
@ -1434,9 +1610,8 @@ rl_vi_possible_completions()
#endif
/* Functions to save and restore marks. */
int
rl_vi_set_mark (count, key)
int count, key;
static int
_rl_vi_set_mark ()
{
int ch;
@ -1454,9 +1629,36 @@ rl_vi_set_mark (count, key)
return 0;
}
#if defined (READLINE_CALLBACKS)
static int
_rl_vi_callback_set_mark (data)
_rl_callback_generic_arg *data;
{
_rl_callback_func = 0;
_rl_want_redisplay = 1;
return (_rl_vi_set_mark ());
}
#endif
int
rl_vi_goto_mark (count, key)
rl_vi_set_mark (count, key)
int count, key;
{
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = 0;
_rl_callback_func = _rl_vi_callback_set_mark;
return (0);
}
#endif
return (_rl_vi_set_mark ());
}
static int
_rl_vi_goto_mark ()
{
int ch;
@ -1485,4 +1687,31 @@ rl_vi_goto_mark (count, key)
return 0;
}
#if defined (READLINE_CALLBACKS)
static int
_rl_vi_callback_goto_mark (data)
_rl_callback_generic_arg *data;
{
_rl_callback_func = 0;
_rl_want_redisplay = 1;
return (_rl_vi_goto_mark ());
}
#endif
int
rl_vi_goto_mark (count, key)
int count, key;
{
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = 0;
_rl_callback_func = _rl_vi_callback_goto_mark;
return (0);
}
#endif
return (_rl_vi_goto_mark ());
}
#endif /* VI_MODE */