Initial commit.
This commit is contained in:
commit
9a97e08178
276
ChangeLog.md
Normal file
276
ChangeLog.md
Normal file
@ -0,0 +1,276 @@
|
||||
Change Log
|
||||
==========
|
||||
|
||||
All notable changes to the project are documented in this file.
|
||||
|
||||
[1.17.1][] - 2022-08-25
|
||||
-----------------------
|
||||
### Changes
|
||||
- Revert to Make.
|
||||
|
||||
|
||||
[1.17.1][] - 2020-02-23
|
||||
-----------------------
|
||||
|
||||
### Fixes
|
||||
- Fix #38: Fix for multiline representing as one line
|
||||
- Fix packaging, missing files in libeditline1, regression from 1.16.0
|
||||
- Fix packaging, update to latest std version
|
||||
- Fix formatting of function names in man page
|
||||
- Restore tar.gz distribution, for usability on systems that do not
|
||||
have xz in their default install
|
||||
|
||||
|
||||
[1.17.0][] - 2020-01-05
|
||||
-----------------------
|
||||
|
||||
### Changes
|
||||
- Simple multi-line support by Dima Volynets, @dvolynets
|
||||
|
||||
### Fixes
|
||||
- Fix return value from `read_history()` and `write_history()`, could
|
||||
return `errno` instead of `EOF` to indicate error. Now both functions
|
||||
have uniform return values on error
|
||||
- Handle internal `realloc()` errors better. Now memory is not leaked
|
||||
if `realloc()` fails
|
||||
- Fix possible NULL pointer dereference in key binding lookup function
|
||||
|
||||
|
||||
[1.16.1][] - 2019-06-07
|
||||
-----------------------
|
||||
|
||||
### Changes
|
||||
- Major updates to the `editline.3` man page
|
||||
- Cleanup of examples `cli.c` and `fileman.c`
|
||||
- Add example of hidden input prompt to `cli.c`
|
||||
|
||||
### Fixes
|
||||
- Fix #20: `configure --disable-eof` does not bite
|
||||
- Fix #23: Make Ctrl-L clear the screan instead of starting a new line
|
||||
Like Ctrl-D, which exits, Ctrl-L only clears the screen when the line
|
||||
is empty and the cursor is at the start of the line, otherwise Ctrl-L
|
||||
will redraw/refresh the current line.
|
||||
- Fix #24: Fix behavior when TTY is narrower than column width, by Will Dietz
|
||||
- Fix #25: Avoid continuously duplicate commands in history
|
||||
- Fix #31: Aborting i-search with Ctrl-C should not generate signal
|
||||
|
||||
|
||||
[1.16.0][] - 2018-09-16
|
||||
-----------------------
|
||||
|
||||
Event loop callback support.
|
||||
|
||||
### Changes
|
||||
- `rl_unintialize()`, new function to free all memory, by Claus Fischer
|
||||
- `rl_insert_text()`, new GNU Readline compat function
|
||||
- `rl_refresh_line()`, new GNU Readline compat function
|
||||
- `rl_callback_*()`, alternate interface to plain `readline()` for event
|
||||
loops. Modeled after the GNU Readline API
|
||||
- `rl_completion_entry_function`, and `rl_attempted_completion_function`
|
||||
are two new GNU Readline compat user hooks for the completion framework
|
||||
- `rl_completion_matches()` and `rl_filename_completion_function()`
|
||||
are two new GNU Readline compat functions
|
||||
- Add new example: `fileman.c` from GNU Readline to demonstrate the
|
||||
level of compatibility of the revamped completion framework
|
||||
- Add support for Ctrl-Right and Ctrl-Left, forward/backward word
|
||||
- Add .deb package to official release target
|
||||
|
||||
### Fixes
|
||||
- Fixed header guards, avoid using leading `__`
|
||||
- Spell check fixes
|
||||
- Remove duplicate code in history check
|
||||
- Use `NULL` instead of `0`, and `-1` instead of `NULL`, where applicable
|
||||
- Misc. minor Coverity Scan fixes
|
||||
- Misc. minor fixes to `testit.c` example code
|
||||
- Add `-Wextra` to std `CFLAGS`
|
||||
- Check `fclose()` return value in in `write_history()` and `read_history()`
|
||||
- Initialize global variables and reset to `NULL` on `free()`
|
||||
- Fix off-by-one in forward kill word, avoid deleting too much
|
||||
- Skip (or kill) leading whitespace when skipping (or killing) forwards
|
||||
|
||||
|
||||
[1.15.3][] - 2017-09-07
|
||||
-----------------------
|
||||
|
||||
Bug fix release.
|
||||
|
||||
### Changes
|
||||
- Refactor all enable/disable configure options, same problem as in #7
|
||||
|
||||
### Fixes
|
||||
- Fix #7: `--enable-termcap` configure option does not work. The script
|
||||
enabled termcap by default rather than the other way around.
|
||||
|
||||
Also, check for terminfo as well, when `--enable-termcap` is selected.
|
||||
|
||||
|
||||
[1.15.2][] - 2016-06-06
|
||||
-----------------------
|
||||
|
||||
Bug fixes and minor feature creep in `pkg-config` support.
|
||||
|
||||
### Changes
|
||||
- Prevent mangling of symbols when linking with C++. Patch courtesy of
|
||||
Jakub Pawlowski
|
||||
- Add `libeditline.pc` for `pkg-config`
|
||||
|
||||
### Fixes
|
||||
- Do not assume a termcap library exists, check for `tgetent()` in
|
||||
curses, ncurses, tinfo and termcap libraries
|
||||
- Call `tty_flush()` when user calls `rl_forced_update_display()`
|
||||
to prevent screen becoming garbled. Patch by Jakub Pawlowski
|
||||
|
||||
|
||||
[1.15.1][] - 2015-11-16
|
||||
-----------------------
|
||||
|
||||
Bug fixes only.
|
||||
|
||||
### Changes
|
||||
- Update README with origin of this version of editline
|
||||
|
||||
### Fixes
|
||||
- Fix build system, don't force automake v1.11, require at least v1.11
|
||||
- Fix build problem with examples using `--enable-termcap`
|
||||
|
||||
|
||||
[1.15.0][] - 2015-09-10
|
||||
-----------------------
|
||||
|
||||
### Changes
|
||||
- Add support for `--disable-eof` and `--disable-sigint` to disable
|
||||
default Ctrl-D and Ctrl-C behavior
|
||||
- Add support for `el_no_hist` to disable access to and auto-save of history
|
||||
- GNU readline compat functions for prompt handling and redisplay
|
||||
- Refactor: replace variables named 'new' with non-reserved word
|
||||
- Add support for [Travis-CI][], continuous integration with GitHub
|
||||
- Add support for [Coverity Scan][], the best static code analyzer,
|
||||
integrated with [Travis-CI][] -- scan runs for each push to master
|
||||
- Rename NEWS.md --> ChangeLog.md, with symlinks for <kbd>make install</kbd>
|
||||
- Attempt to align with http://keepachangelog.com/ for this file
|
||||
- Cleanup and improve Markdown syntax in [README.md][]
|
||||
- Add API and example to [README.md][], inspired by [libuEv][]
|
||||
- Removed generated files from version control. Use `./autogen.sh`
|
||||
to generate the `configure` script when working from GIT. This
|
||||
does not affect distributed tarballs
|
||||
|
||||
### Fixes
|
||||
- Fix issue #2, regression in Ctrl-D (EOF) behavior. Regression
|
||||
introduced in [1.14.1][]. Fixed by @TobyGoodwin
|
||||
- Fix memory leak in completion handler. Found by [Coverity Scan][].
|
||||
- Fix suspicious use of `sizeof(char **)`, same as `sizeof(char *)` but
|
||||
non-portable. Found by [Coverity Scan][]
|
||||
- Fix out-of-bounds access in user key binding routines
|
||||
Found by [Coverity Scan][].
|
||||
- Fix invisible example code in man page
|
||||
|
||||
|
||||
[1.14.2][] - 2014-09-14
|
||||
-----------------------
|
||||
|
||||
Bug fixes only.
|
||||
|
||||
### Fixes
|
||||
- Fix `el_no_echo` bug causing secrets to leak when disabling no-echo
|
||||
- Handle `EINTR` in syscalls better
|
||||
|
||||
|
||||
[1.14.1][] - 2014-09-14
|
||||
-----------------------
|
||||
|
||||
Minor fixes and additions.
|
||||
|
||||
### Changes
|
||||
- Don't print status message on `stderr` in key binding funcions
|
||||
- Export `el_del_char()`
|
||||
- Check for and return pending signals when detected
|
||||
- Allow custom key bindings ...
|
||||
|
||||
### Fixes
|
||||
- Bug fixes ...
|
||||
|
||||
|
||||
[1.14.0][] - 2010-08-10
|
||||
-----------------------
|
||||
|
||||
Major cleanups and further merges with Debian editline package.
|
||||
|
||||
### Changes
|
||||
- Merge in changes to `debian/` from `editline_1.12-6.debian.tar.gz`
|
||||
- Migrate to use libtool
|
||||
- Make `UNIQUE_HISTORY` configurable
|
||||
- Make scrollback history (`HIST_SIZE`) configurable
|
||||
- Configure options for toggling terminal bell and `SIGSTOP` (Ctrl-Z)
|
||||
- Configure option for using termcap to read/control terminal size
|
||||
- Rename Signal to `el_intr_pending`, from Festival speech-tools
|
||||
- Merge support for capitalizing words (`M-c`) from Festival
|
||||
speech-tools by Alan W Black <mailto:awb()cstr!ed!ac!uk>
|
||||
- Fallback backspace handling, in case `tgetstr("le")` fails
|
||||
|
||||
### Fixes
|
||||
- Cleanups and fixes thanks to the Sparse static code analysis tool
|
||||
- Merge `el_no_echo` patch from Festival speech-tools
|
||||
- Merge fixes from Heimdal project
|
||||
- Completely refactor `rl_complete()` and `rl_list_possib()` with
|
||||
fixes from the Heimdal project. Use `rl_set_complete_func()` and
|
||||
`rl_set_list_possib_func()`. Default completion callbacks are now
|
||||
available as a configure option `--enable-default-complete`
|
||||
- Memory leak fixes
|
||||
- Actually fix 8-bit handling by reverting old Debian patch
|
||||
- Merge patch to improve compatibility with GNU readline, thanks to
|
||||
Steve Tell from way back in 1997 and 1998
|
||||
|
||||
|
||||
[1.13.0][] - 2010-03-09
|
||||
-----------------------
|
||||
|
||||
Adaptations to Debian editline package.
|
||||
|
||||
### Changes
|
||||
- Major version number bump, adapt to Jim Studt's v1.12
|
||||
- Import `debian/` directory and adapt it to configure et al.
|
||||
- Change library name to libeditline to distinguish it from BSD libedit
|
||||
|
||||
|
||||
[0.3.0][] - 2009-02-08
|
||||
----------------------
|
||||
|
||||
### Changes
|
||||
- Support for ANSI arrow keys using <kbd>configure --enable-arrow-keys</kbd>
|
||||
|
||||
|
||||
[0.2.3][] - 2008-12-02
|
||||
----------------------
|
||||
|
||||
### Changes
|
||||
- Patches from Debian package merged
|
||||
- Support for custom command completion
|
||||
|
||||
|
||||
[0.1.0][] - 2008-06-07
|
||||
----------------------
|
||||
|
||||
### Changes
|
||||
- First version, forked from Minix current 2008-06-06
|
||||
|
||||
|
||||
[UNRELEASED]: https://github.com/troglobit/finit/compare/1.17.1...HEAD
|
||||
[1.17.1]: https://github.com/troglobit/finit/compare/1.17.0...1.17.1
|
||||
[1.17.0]: https://github.com/troglobit/finit/compare/1.16.1...1.17.0
|
||||
[1.16.1]: https://github.com/troglobit/finit/compare/1.16.0...1.16.1
|
||||
[1.16.0]: https://github.com/troglobit/finit/compare/1.15.3...1.16.0
|
||||
[1.15.3]: https://github.com/troglobit/finit/compare/1.15.2...1.15.3
|
||||
[1.15.2]: https://github.com/troglobit/finit/compare/1.15.1...1.15.2
|
||||
[1.15.1]: https://github.com/troglobit/finit/compare/1.15.0...1.15.1
|
||||
[1.15.0]: https://github.com/troglobit/finit/compare/1.14.2...1.15.0
|
||||
[1.14.2]: https://github.com/troglobit/finit/compare/1.14.1...1.14.2
|
||||
[1.14.1]: https://github.com/troglobit/finit/compare/1.14.0...1.14.1
|
||||
[1.14.0]: https://github.com/troglobit/finit/compare/1.13.0...1.14.0
|
||||
[1.13.0]: https://github.com/troglobit/finit/compare/0.3.0...1.13.0
|
||||
[0.3.0]: https://github.com/troglobit/finit/compare/0.2.3...0.3.0
|
||||
[0.2.3]: https://github.com/troglobit/finit/compare/0.1.0...0.2.3
|
||||
[0.1.0]: https://github.com/troglobit/finit/compare/0.0.0...0.1.0
|
||||
[libuEv]: http://github.com/troglobit/libuev
|
||||
[Travis-CI]: https://travis-ci.org/troglobit/uftpd
|
||||
[Coverity Scan]: https://scan.coverity.com/projects/2947
|
||||
[README.md]: https://github.com/troglobit/editline/blob/master/README.md
|
18
LICENSE
Normal file
18
LICENSE
Normal file
@ -0,0 +1,18 @@
|
||||
Copyright 1992,1993 Simmule Turner and Rich Salz
|
||||
All rights reserved.
|
||||
|
||||
This software is not subject to any license of the American Telephone
|
||||
and Telegraph Company or of the Regents of the University of California.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose on
|
||||
any computer system, and to alter it and redistribute it freely, subject
|
||||
to the following restrictions:
|
||||
1. The authors are not responsible for the consequences of use of this
|
||||
software, no matter how awful, even if they arise from flaws in it.
|
||||
2. The origin of this software must not be misrepresented, either by
|
||||
explicit claim or by omission. Since few users ever read sources,
|
||||
credits must appear in the documentation.
|
||||
3. Altered versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software. Since few users
|
||||
ever read sources, credits must appear in the documentation.
|
||||
4. This notice may not be removed or altered.
|
29
Makefile
Normal file
29
Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
.POSIX:
|
||||
|
||||
TARGETS = libeditline.so libeditline.so.1 libeditline.so.1.0.2 libeditline.a
|
||||
|
||||
all: dynamic static
|
||||
|
||||
install: all
|
||||
install -Dm644 ${TARGETS} ${DESTDIR}/${PREFIX}/lib/
|
||||
install -Dm644 editline.3 ${DESTDIR}/${PREFIX}/share/man/man3/
|
||||
install -Dm644 libeditline.pc ${DESTDIR}/${PREFIX}/lib/pkgconfig/
|
||||
|
||||
dynamic: object
|
||||
cc -o libeditline.so -shared *.o
|
||||
ln -s libeditline.so libeditline.so.1
|
||||
ln -s libeditline.so libeditline.so.1.0.2
|
||||
|
||||
static: object
|
||||
ar -r *.o
|
||||
mv a.out libeditline.a
|
||||
|
||||
object: complete.o editline.o sysunix.o
|
||||
|
||||
clean:
|
||||
rm *.so* *.a *.o
|
||||
|
||||
.SUFFIX:
|
||||
.c.o:
|
||||
cc -c $<
|
||||
|
272
README.md
Normal file
272
README.md
Normal file
@ -0,0 +1,272 @@
|
||||
Editline
|
||||
========
|
||||
[![License Badge][]][License] [![Travis Status]][Travis] [![Coverity Status]][Coverity Scan]
|
||||
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [API](#api)
|
||||
* [Example](#example)
|
||||
* [Build & Install](#build--install)
|
||||
* [Origin & References](#origin--references)
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This is a small [line editing][] library. It can be linked into almost
|
||||
any program to provide command line editing and history functions. It
|
||||
is call compatible with the [FSF readline][] library, but at a fraction
|
||||
of the size, and as a result fewer features. It is also distributed
|
||||
under a much more liberal [License][].
|
||||
|
||||
The small size (<30k), lack of dependencies (ncurses not needed!), and
|
||||
the free license should make this library interesting to many embedded
|
||||
developers.
|
||||
|
||||
Editline has several optional build-time features that can be enabled by
|
||||
supplying different options to the GNU configure script. See the output
|
||||
from <kbd>configure --help</kbd> for details. Some useful hints on how
|
||||
to use the library is available in the `examples/` directory.
|
||||
|
||||
Editline is maintained collaboratively at [GitHub][].
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Below is a very brief example to illustrate how one can use Editline to
|
||||
create a simple CLI, Ctrl-D exits the program. A slightly more advanced
|
||||
example is Jush, <https://github.com/troglobit/jush/>, a small and very
|
||||
simplistic UNIX shell. The Editline sources also include an `examples/`
|
||||
sub-directory.
|
||||
|
||||
1. Build and install the library, preferably using a [release tarball][]
|
||||
The configure script defaults to a `/usr/local` prefix.
|
||||
|
||||
tar xf editline-1.15.3.tar.xz
|
||||
cd editline-1.15.3/
|
||||
./configure --prefix=/usr
|
||||
make all
|
||||
sudo make install
|
||||
|
||||
2. Place the below source code in a separate project directory,
|
||||
e.g. `~/src/example.c`
|
||||
|
||||
```C
|
||||
#include <stdlib.h>
|
||||
#include <editline.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char *p;
|
||||
|
||||
while ((p = readline("CLI> ")) != NULL) {
|
||||
puts(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
3. Compile the example:
|
||||
|
||||
cd ~/src/
|
||||
make LDLIBS=-leditline example
|
||||
|
||||
Here I use `make` and rely on its implicit (built-in) rules to handle
|
||||
all the compiler magic, but you may want to create your own Makefile for
|
||||
the project. In particular if you don't change the default prefix
|
||||
(above), because then you need to specify the search path for the
|
||||
include file(s) and the library manually.
|
||||
|
||||
A simple `~/src/Makefile` could look like this:
|
||||
|
||||
CFLAGS = -I/usr/local/include
|
||||
LDFLAGS = -L/usr/local/lib
|
||||
LDLIBS = -leditline
|
||||
EXEC = example
|
||||
OBJS = example.o
|
||||
|
||||
all: $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJS)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJS) $(EXEC)
|
||||
|
||||
distclean: clean
|
||||
$(RM) *.o *~ *.bak
|
||||
|
||||
Then simply type `make` from your `~/src/` directory. You can also use
|
||||
`pkg-config` for your `~/src/Makefile`, replace the following lines:
|
||||
|
||||
CFLAGS = $(shell pkg-config --cflags libeditline)
|
||||
LDFLAGS = $(shell pkg-config --libs-only-L libeditline)
|
||||
LDLIBS = $(shell pkg-config --libs-only-l libeditline)
|
||||
|
||||
Then simply type <kbd>make</kbd>, like above.
|
||||
|
||||
However, most `.rpm` based distributions `pkg-config` doesn't search in
|
||||
`/usr/local` anymore, so you need to call make like this:
|
||||
|
||||
PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig make
|
||||
|
||||
Debian/Ubuntu based systems do not have this problem.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
Here is the libeditline interfaces. It has a small compatibility layer
|
||||
to [FSF readline][], which may not be entirely up-to-date.
|
||||
|
||||
```C
|
||||
/* Editline specific global variables. */
|
||||
int el_no_echo; /* Do not echo input characters */
|
||||
int el_no_hist; /* Disable auto-save of and access to history,
|
||||
* e.g. for password prompts or wizards */
|
||||
int el_hist_size; /* Size of history scrollback buffer, default: 15 */
|
||||
|
||||
/* Editline specific functions. */
|
||||
char * el_find_word (void);
|
||||
void el_print_columns (int ac, char **av);
|
||||
el_status_t el_ring_bell (void);
|
||||
el_status_t el_del_char (void);
|
||||
|
||||
/* Callback function for key binding */
|
||||
typedef el_status_t el_keymap_func_t(void);
|
||||
|
||||
/* Bind key to a callback, use CTL('f') to change Ctrl-F, for example */
|
||||
el_status_t el_bind_key (int key, el_keymap_func_t function);
|
||||
el_status_t el_bind_key_in_metamap (int key, el_keymap_func_t function);
|
||||
|
||||
/* For compatibility with FSF readline. */
|
||||
int rl_point;
|
||||
int rl_mark;
|
||||
int rl_end;
|
||||
int rl_inhibit_complete;
|
||||
char *rl_line_buffer;
|
||||
const char *rl_readline_name;
|
||||
|
||||
void (*rl_deprep_term_function)(void);
|
||||
void rl_deprep_terminal (void);
|
||||
void rl_reset_terminal (const char *terminal_name);
|
||||
|
||||
void rl_initialize (void);
|
||||
void rl_uninitialize (void); /* Free all internal memory */
|
||||
|
||||
void rl_save_prompt (void);
|
||||
void rl_restore_prompt (void);
|
||||
void rl_set_prompt (const char *prompt);
|
||||
|
||||
void rl_clear_message (void);
|
||||
void rl_forced_update_display (void);
|
||||
|
||||
/* Main function to use, saves history by default */
|
||||
char *readline (const char *prompt);
|
||||
|
||||
/* Use to save a read line to history, when el_no_hist is set */
|
||||
void add_history (const char *line);
|
||||
|
||||
/* Load and save editline history from/to a file. */
|
||||
int read_history (const char *filename);
|
||||
int write_history (const char *filename);
|
||||
|
||||
/* Magic completion API, see examples/cli.c for more info */
|
||||
rl_complete_func_t *rl_set_complete_func (rl_complete_func_t *func);
|
||||
rl_list_possib_func_t *rl_set_list_possib_func (rl_list_possib_func_t *func);
|
||||
|
||||
/* Alternate interface to plain readline(), for event loops */
|
||||
void rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *lhandler);
|
||||
void rl_callback_read_char (void);
|
||||
void rl_callback_handler_remove (void);
|
||||
```
|
||||
|
||||
|
||||
Build & Install
|
||||
---------------
|
||||
|
||||
Editline was originally designed for older UNIX systems and Plan 9. The
|
||||
current maintainer works exclusively on GNU/Linux systems, so it may use
|
||||
GCC and GNU Make specific extensions here and there. This is not on
|
||||
purpose and patches or pull requests to correct this are most welcome!
|
||||
|
||||
1. Configure editline with default features: <kbd>./configure</kbd>
|
||||
2. Build the library and examples: <kbd>make all</kbd>
|
||||
3. Install using <kbd>make install</kbd>
|
||||
|
||||
The `$DESTDIR` environment variable is honored at install. For more
|
||||
options, see <kbd>./configure --help</kbd>
|
||||
|
||||
Remember to run `ldconfig` after install to update the linker cache. If
|
||||
you've installed to a non-standard location (`--prefix`) you may also
|
||||
have to update your `/etc/ld.so.conf`, or use `pkg-confg` to build your
|
||||
application (above).
|
||||
|
||||
**NOTE:** RedHat/Fedora/CentOS and other `.rpm`-based distributions do
|
||||
not consider `/usr/local` as standard path anymore. So make sure to
|
||||
`./configure --prefix=/usr`, otherwise the build system use the GNU
|
||||
default, which is `/usr/local`. The Debian based distributions, like
|
||||
Ubuntu, do not have this problem.
|
||||
|
||||
|
||||
Origin & References
|
||||
--------------------
|
||||
|
||||
This [line editing][] library was created by [Rich Salz][] and Simmule
|
||||
Turner and in 1992. It is distributed with a “[C News][]-like” license,
|
||||
similar to the [BSD license][]. Rich's current version is however under
|
||||
the Apache license. For details on the licensing terms of this version
|
||||
of the software, see [License][].
|
||||
|
||||
This version of the editline library was forked from the [Minix 2][]
|
||||
source tree and is *not* related to the similarily named NetBSD version
|
||||
that [Jess Thrysøe][jess] disitributes to the world outside *BSD. The
|
||||
libraries have much in common, but the latter is heavily refactored and
|
||||
also relies on libtermcap (usually supplied by ncurses), whereas this
|
||||
library only uses termios from the standard C library.
|
||||
|
||||
Patches and bug fixes from the following forks, based on the original
|
||||
[comp.sources.unix][] posting, have been merged:
|
||||
|
||||
* Debian [libeditline][]
|
||||
* [Heimdal][]
|
||||
* [Festival][] speech-tools
|
||||
* [Steve Tell][]'s editline patches
|
||||
|
||||
The version numbering scheme today follows that of the Debian version,
|
||||
details available in the [ChangeLog.md][]. The current [maintainer][]
|
||||
was unaware of the Debian version for quite some time, so a different
|
||||
name and versioning scheme was used. In June 2009 this was changed to
|
||||
line up alongside Debian, with the intent is to eventually merge the
|
||||
efforts.
|
||||
|
||||
Outstanding issues are listed in the [TODO.md][] file.
|
||||
|
||||
[GitHub]: https://github.com/troglobit/editline
|
||||
[line editing]: https://github.com/troglobit/editline/blob/master/docs/README
|
||||
[release tarball]: https://github.com/troglobit/editline/releases
|
||||
[maintainer]: http://troglobit.com
|
||||
[C News]: https://en.wikipedia.org/wiki/C_News
|
||||
[TODO.md]: https://github.com/troglobit/editline/blob/master/docs/TODO.md
|
||||
[ChangeLog.md]: https://github.com/troglobit/editline/blob/master/ChangeLog.md
|
||||
[FSF readline]: http://www.gnu.org/software/readline/
|
||||
[Rich Salz]: https://github.com/richsalz/editline/
|
||||
[comp.sources.unix]: http://ftp.cs.toronto.edu/pub/white/pub/rc/editline.shar
|
||||
[Minix 2]: http://www.cise.ufl.edu/~cop4600/cgi-bin/lxr/http/source.cgi/lib/editline/
|
||||
[jess]: http://thrysoee.dk/editline/
|
||||
[BSD license]: http://en.wikipedia.org/wiki/BSD_licenses
|
||||
[libeditline]: http://packages.qa.debian.org/e/editline.html
|
||||
[Heimdal]: http://www.h5l.org
|
||||
[Festival]: http://festvox.org/festival/
|
||||
[Steve Tell]: http://www.cs.unc.edu/~tell/dist.html
|
||||
[License]: https://github.com/troglobit/editline/blob/master/LICENSE
|
||||
[License Badge]: https://img.shields.io/badge/License-C%20News-orange.svg
|
||||
[Travis]: https://travis-ci.org/troglobit/editline
|
||||
[Travis Status]: https://travis-ci.org/troglobit/editline.png?branch=master
|
||||
[Coverity Scan]: https://scan.coverity.com/projects/2982
|
||||
[Coverity Status]: https://scan.coverity.com/projects/2982/badge.svg
|
442
complete.c
Normal file
442
complete.c
Normal file
@ -0,0 +1,442 @@
|
||||
/* History and file completion functions for editline library.
|
||||
*
|
||||
* Copyright (c) 1992, 1993 Simmule Turner and Rich Salz
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or of the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
* 1. The authors are not responsible for the consequences of use of this
|
||||
* software, no matter how awful, even if they arise from flaws in it.
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Since few users ever read sources,
|
||||
* credits must appear in the documentation.
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software. Since few users
|
||||
* ever read sources, credits must appear in the documentation.
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "editline.h"
|
||||
|
||||
#define MAX_TOTAL_MATCHES (256 << sizeof(char *))
|
||||
|
||||
int rl_attempted_completion_over = 0;
|
||||
rl_completion_func_t *rl_attempted_completion_function = NULL;
|
||||
rl_compentry_func_t *rl_completion_entry_function = NULL;
|
||||
|
||||
/* Wrap strcmp() for qsort() -- weird construct to pass -Wcast-qual */
|
||||
static int compare(const void *p1, const void *p2)
|
||||
{
|
||||
char *const *v1 = (char *const *)p1;
|
||||
char *const *v2 = (char *const *)p2;
|
||||
|
||||
return strcmp(*v1, *v2);
|
||||
}
|
||||
|
||||
/* Fill in *avp with an array of names that match file, up to its length.
|
||||
* Ignore . and .. . */
|
||||
static int FindMatches(char *dir, char *file, char ***avp)
|
||||
{
|
||||
char **av;
|
||||
char **word;
|
||||
char *p;
|
||||
DIR *dp;
|
||||
DIRENTRY *ep;
|
||||
size_t ac;
|
||||
size_t len;
|
||||
size_t choices;
|
||||
size_t total;
|
||||
|
||||
if ((dp = opendir(dir)) == NULL)
|
||||
return 0;
|
||||
|
||||
av = NULL;
|
||||
ac = 0;
|
||||
len = strlen(file);
|
||||
choices = 0;
|
||||
total = 0;
|
||||
while ((ep = readdir(dp)) != NULL) {
|
||||
p = ep->d_name;
|
||||
if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0')))
|
||||
continue;
|
||||
if (len && strncmp(p, file, len) != 0)
|
||||
continue;
|
||||
|
||||
choices++;
|
||||
if ((total += strlen(p)) > MAX_TOTAL_MATCHES) {
|
||||
/* This is a bit too much. */
|
||||
while (ac > 0) free(av[--ac]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ac % MEM_INC) == 0) {
|
||||
word = malloc(sizeof(char *) * (ac + MEM_INC));
|
||||
if (!word) {
|
||||
total = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ac) {
|
||||
memcpy(word, av, ac * sizeof(char *));
|
||||
free(av);
|
||||
}
|
||||
*avp = av = word;
|
||||
}
|
||||
|
||||
if ((av[ac] = strdup(p)) == NULL) {
|
||||
if (ac == 0)
|
||||
free(av);
|
||||
total = 0;
|
||||
break;
|
||||
}
|
||||
ac++;
|
||||
}
|
||||
|
||||
/* Clean up and return. */
|
||||
closedir(dp);
|
||||
if (total > MAX_TOTAL_MATCHES) {
|
||||
char many[sizeof(total) * 3];
|
||||
|
||||
p = many + sizeof(many);
|
||||
*--p = '\0';
|
||||
while (choices > 0) {
|
||||
*--p = '0' + choices % 10;
|
||||
choices /= 10;
|
||||
}
|
||||
|
||||
while (p > many + sizeof(many) - 8)
|
||||
*--p = ' ';
|
||||
|
||||
if ((p = strdup(p)) != NULL)
|
||||
av[ac++] = p;
|
||||
|
||||
if ((p = strdup("choices")) != NULL)
|
||||
av[ac++] = p;
|
||||
} else {
|
||||
if (ac)
|
||||
qsort(av, ac, sizeof(char *), compare);
|
||||
}
|
||||
|
||||
return ac;
|
||||
}
|
||||
|
||||
/* Split a pathname into allocated directory and trailing filename parts. */
|
||||
static int SplitPath(const char *path, char **dirpart, char **filepart)
|
||||
{
|
||||
static char DOT[] = ".";
|
||||
char *dpart;
|
||||
char *fpart;
|
||||
|
||||
if ((fpart = strrchr(path, '/')) == NULL) {
|
||||
if ((dpart = strdup(DOT)) == NULL)
|
||||
return -1;
|
||||
|
||||
if ((fpart = strdup(path)) == NULL) {
|
||||
free(dpart);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if ((dpart = strdup(path)) == NULL)
|
||||
return -1;
|
||||
|
||||
dpart[fpart - path + 1] = '\0';
|
||||
if ((fpart = strdup(fpart + 1)) == NULL) {
|
||||
free(dpart);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
*dirpart = dpart;
|
||||
*filepart = fpart;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static rl_complete_func_t *el_complete_func = NULL;
|
||||
|
||||
/* For compatibility with the Heimdal project. */
|
||||
rl_complete_func_t *rl_set_complete_func(rl_complete_func_t *func)
|
||||
{
|
||||
rl_complete_func_t *old = el_complete_func;
|
||||
el_complete_func = func;
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
/* Attempt to complete the pathname, returning an allocated copy.
|
||||
* Fill in *match if we completed it, or set it to 0 if ambiguous. */
|
||||
char *el_filename_complete(char *pathname, int *match)
|
||||
{
|
||||
char **av;
|
||||
char *dir;
|
||||
char *file;
|
||||
char *path;
|
||||
char *p;
|
||||
size_t ac;
|
||||
size_t end;
|
||||
size_t i;
|
||||
size_t j;
|
||||
size_t len;
|
||||
|
||||
if (SplitPath((const char *)pathname, &dir, &file) < 0)
|
||||
return NULL;
|
||||
|
||||
if ((ac = FindMatches(dir, file, &av)) == 0) {
|
||||
free(dir);
|
||||
free(file);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = NULL;
|
||||
len = strlen(file);
|
||||
if (ac == 1) {
|
||||
/* Exactly one match -- finish it off. */
|
||||
*match = 1;
|
||||
j = strlen(av[0]) - len + 2;
|
||||
p = malloc(sizeof(char) * (j + 1));
|
||||
if (p) {
|
||||
memcpy(p, av[0] + len, j);
|
||||
len = strlen(dir) + strlen(av[0]) + 2;
|
||||
path = malloc(sizeof(char) * len);
|
||||
if (path) {
|
||||
snprintf(path, len, "%s/%s", dir, av[0]);
|
||||
rl_add_slash(path, p);
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*match = 0;
|
||||
if (len) {
|
||||
/* Find largest matching substring. */
|
||||
for (i = len, end = strlen(av[0]); i < end; i++) {
|
||||
for (j = 1; j < ac; j++) {
|
||||
if (av[0][i] != av[j][i])
|
||||
goto breakout;
|
||||
}
|
||||
}
|
||||
breakout:
|
||||
if (i > len) {
|
||||
j = i - len + 1;
|
||||
p = malloc(sizeof(char) * j);
|
||||
if (p) {
|
||||
memcpy(p, av[0] + len, j);
|
||||
p[j - 1] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up and return. */
|
||||
free(dir);
|
||||
free(file);
|
||||
for (i = 0; i < ac; i++)
|
||||
free(av[i]);
|
||||
free(av);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
char *rl_filename_completion_function(const char *text, int state)
|
||||
{
|
||||
char *dir;
|
||||
char *file;
|
||||
static char **av;
|
||||
static size_t i, ac;
|
||||
|
||||
if (!state) {
|
||||
if (SplitPath(text, &dir, &file) < 0)
|
||||
return NULL;
|
||||
|
||||
ac = FindMatches(dir, file, &av);
|
||||
free(dir);
|
||||
free(file);
|
||||
if (!ac)
|
||||
return NULL;
|
||||
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (i < ac)
|
||||
return av[i++];
|
||||
|
||||
do {
|
||||
free(av[--i]);
|
||||
} while (i > 0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Similar to el_find_word(), but used by GNU Readline API */
|
||||
static char *rl_find_token(size_t *len)
|
||||
{
|
||||
char *ptr;
|
||||
int pos;
|
||||
|
||||
for (pos = rl_point; pos < rl_end; pos++) {
|
||||
if (isspace(rl_line_buffer[pos])) {
|
||||
if (pos > 0)
|
||||
pos--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ptr = &rl_line_buffer[pos];
|
||||
while (pos >= 0 && !isspace(rl_line_buffer[pos])) {
|
||||
if (pos == 0)
|
||||
break;
|
||||
|
||||
pos--;
|
||||
}
|
||||
|
||||
if (ptr != &rl_line_buffer[pos]) {
|
||||
*len = (size_t)(ptr - &rl_line_buffer[pos]);
|
||||
return &rl_line_buffer[pos];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* "uses an application-supplied generator function to generate the list
|
||||
* of possible matches, and then returns the array of these matches. The
|
||||
* caller should place the address of its generator function in
|
||||
* rl_completion_entry_function"
|
||||
*/
|
||||
char **rl_completion_matches(const char *token, rl_compentry_func_t *generator)
|
||||
{
|
||||
int state = 0, num = 0;
|
||||
char **array, *entry;
|
||||
|
||||
if (!generator) {
|
||||
generator = rl_completion_entry_function;
|
||||
if (!generator)
|
||||
generator = rl_filename_completion_function;
|
||||
}
|
||||
|
||||
if (!generator)
|
||||
return NULL;
|
||||
|
||||
array = malloc(512 * sizeof(char *));
|
||||
if (!array)
|
||||
return NULL;
|
||||
|
||||
while (num < 511 && (entry = generator(token, state))) {
|
||||
state = 1;
|
||||
array[num++] = entry;
|
||||
}
|
||||
array[num] = NULL;
|
||||
|
||||
if (!num) {
|
||||
free(array);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
static char *complete(char *token, int *match)
|
||||
{
|
||||
size_t len = 0;
|
||||
char *word, **words = NULL;
|
||||
int start, end;
|
||||
|
||||
word = rl_find_token(&len);
|
||||
if (!word)
|
||||
goto fallback;
|
||||
|
||||
start = word - rl_line_buffer;
|
||||
end = start + len;
|
||||
|
||||
word = strndup(word, len);
|
||||
if (!word)
|
||||
goto fallback;
|
||||
|
||||
rl_attempted_completion_over = 0;
|
||||
words = rl_attempted_completion_function(word, start, end);
|
||||
|
||||
if (!rl_attempted_completion_over && !words)
|
||||
words = rl_completion_matches(word, NULL);
|
||||
|
||||
if (words) {
|
||||
int i = 0;
|
||||
|
||||
free(word);
|
||||
word = NULL;
|
||||
if (words[0])
|
||||
word = strdup(words[0] + len);
|
||||
|
||||
while (words[i])
|
||||
free(words[i++]);
|
||||
free(words);
|
||||
|
||||
if (word)
|
||||
return word;
|
||||
}
|
||||
|
||||
fallback:
|
||||
return el_filename_complete(token, match);
|
||||
}
|
||||
|
||||
/*
|
||||
* First check for editline specific custom completion function, then
|
||||
* for any GNU Readline compat, then fallback to filename completion.
|
||||
*/
|
||||
char *rl_complete(char *token, int *match)
|
||||
{
|
||||
if (el_complete_func)
|
||||
return el_complete_func(token, match);
|
||||
|
||||
if (rl_attempted_completion_function)
|
||||
return complete(token, match);
|
||||
|
||||
return el_filename_complete(token, match);
|
||||
}
|
||||
|
||||
static rl_list_possib_func_t *el_list_possib_func = NULL;
|
||||
|
||||
/* For compatibility with the Heimdal project. */
|
||||
rl_list_possib_func_t *rl_set_list_possib_func(rl_list_possib_func_t *func)
|
||||
{
|
||||
rl_list_possib_func_t *old = el_list_possib_func;
|
||||
el_list_possib_func = func;
|
||||
return old;
|
||||
}
|
||||
|
||||
/* Default possible completions. */
|
||||
int el_filename_list_possib(char *pathname, char ***av)
|
||||
{
|
||||
char *dir;
|
||||
char *file;
|
||||
int ac;
|
||||
|
||||
if (SplitPath(pathname, &dir, &file) < 0)
|
||||
return 0;
|
||||
|
||||
ac = FindMatches(dir, file, av);
|
||||
free(dir);
|
||||
free(file);
|
||||
|
||||
return ac;
|
||||
}
|
||||
|
||||
/* Return all possible completions. */
|
||||
int rl_list_possib(char *token, char ***av)
|
||||
{
|
||||
if (el_list_possib_func)
|
||||
return el_list_possib_func(token, av);
|
||||
|
||||
return el_filename_list_possib(token, av);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Local Variables:
|
||||
* c-file-style: "k&r"
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
169
config.h
Normal file
169
config.h
Normal file
@ -0,0 +1,169 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if the `closedir' function returns void instead of `int'. */
|
||||
/* #undef CLOSEDIR_VOID */
|
||||
|
||||
/* Define to include ANSI arrow keys support. */
|
||||
#define CONFIG_ANSI_ARROWS 1
|
||||
|
||||
/* Define to enable EOF (Ctrl-D) key. */
|
||||
#define CONFIG_EOF 1
|
||||
|
||||
/* Define to enable SIGINT (Ctrl-C) key. */
|
||||
#define CONFIG_SIGINT 1
|
||||
|
||||
/* Define to enable SIGSTOP (Ctrl-Z) key. */
|
||||
/* #undef CONFIG_SIGSTOP */
|
||||
|
||||
/* Define to enable terminal bell on completion. */
|
||||
/* #undef CONFIG_TERMINAL_BELL */
|
||||
|
||||
/* Define to skip duplicate lines in the scrollback history. */
|
||||
#define CONFIG_UNIQUE_HISTORY 1
|
||||
|
||||
/* Define to use the termcap library for terminal size. */
|
||||
/* #undef CONFIG_USE_TERMCAP */
|
||||
|
||||
/* Define to 1 if `TIOCGWINSZ' requires <sys/ioctl.h>. */
|
||||
#define GWINSZ_IN_SYS_IOCTL 1
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#define HAVE_DIRENT_H 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `curses' library (-lcurses). */
|
||||
/* #undef HAVE_LIBCURSES */
|
||||
|
||||
/* Define to 1 if you have the `ncurses' library (-lncurses). */
|
||||
/* #undef HAVE_LIBNCURSES */
|
||||
|
||||
/* Define to 1 if you have the `termcap' library (-ltermcap). */
|
||||
/* #undef HAVE_LIBTERMCAP */
|
||||
|
||||
/* Define to 1 if you have the `terminfo' library (-lterminfo). */
|
||||
/* #undef HAVE_LIBTERMINFO */
|
||||
|
||||
/* Define to 1 if you have the `tinfo' library (-ltinfo). */
|
||||
/* #undef HAVE_LIBTINFO */
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
#define HAVE_MALLOC_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
|
||||
/* Define to 1 if you have the `perror' function. */
|
||||
#define HAVE_PERROR 1
|
||||
|
||||
/* Define to 1 if you have the <sgtty.h> header file. */
|
||||
/* #undef HAVE_SGTTY_H */
|
||||
|
||||
/* Define to 1 if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define to 1 if `stat' has the bug that it succeeds when given the
|
||||
zero-length file name argument. */
|
||||
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strrchr' function. */
|
||||
#define HAVE_STRRCHR 1
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `tcgetattr' function. */
|
||||
#define HAVE_TCGETATTR 1
|
||||
|
||||
/* Define to 1 if you have the <termcap.h> header file. */
|
||||
#define HAVE_TERMCAP_H 1
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#define HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if you have the <termio.h> header file. */
|
||||
/* #undef HAVE_TERMIO_H */
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
|
||||
slash. */
|
||||
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "editline"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "https://github.com/troglobit/editline/issues"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "editline"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "editline 1.17.1"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "editline"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.17.1"
|
||||
|
||||
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
/* #undef STAT_MACROS_BROKEN */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Default to UNIX backend, should be detected. */
|
||||
#define SYS_UNIX 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.17.1"
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
286
editline.3
Normal file
286
editline.3
Normal file
@ -0,0 +1,286 @@
|
||||
.Dd February 23, 2020
|
||||
.Dt EDITLINE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm editline
|
||||
.Nd command-line editing library with history
|
||||
.Sh LIBRARY
|
||||
.Lb libeditline
|
||||
.Sh SYNOPSIS
|
||||
.In editline.h
|
||||
.Ft char *
|
||||
.Fo readline
|
||||
.Fa const char *prompt
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo add_history
|
||||
.Fa const char *line
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo read_history
|
||||
.Fa const char *filename
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo write_history
|
||||
.Fa const char *filename
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a library that provides n line-editing interface with history. It
|
||||
is intended to be functionally equivalent with the
|
||||
.Nm readline
|
||||
library provided by the Free Software Foundation, but much smaller. The
|
||||
bulk of this manual page describes the basic user interface. More APIs,
|
||||
both native and for
|
||||
.Nm readline
|
||||
compatibility ,
|
||||
are also available. See the
|
||||
.Cm editline.h
|
||||
header file for details.
|
||||
.Pp
|
||||
The
|
||||
.Fn readline
|
||||
function displays the given
|
||||
.Fa prompt
|
||||
on stdout, waits for user input on stdin and then returns a line of text
|
||||
with the trailing newline removed. The data is returned in a buffer
|
||||
allocated with
|
||||
.Xr malloc 3 ,
|
||||
so the space should be released with
|
||||
.Xr free 3
|
||||
when the calling program is done with it.
|
||||
.Pp
|
||||
Each line returned is automatically saved in the internal history list,
|
||||
unless it happens to be equal to the previous line. This is
|
||||
configurable if you are building editline from source, i.e. if you would
|
||||
rather like to call
|
||||
.Fn add_history
|
||||
manually.
|
||||
.Pp
|
||||
The
|
||||
.Fn read_history
|
||||
and
|
||||
.Fn write_history
|
||||
functions can be used to load and store the history of your application.
|
||||
.Em Note:
|
||||
these APIs do not do any tilde or environment variable expansion of the
|
||||
given filename.
|
||||
.Ss User Interface
|
||||
A program that uses this library provides a simple emacs-like editing
|
||||
interface to its users. A line may be edited before it is sent to the
|
||||
calling program by typing either control characters or escape sequences.
|
||||
A control character, shown as a caret followed by a letter, is typed by
|
||||
holding down the control key while the letter is typed. For example,
|
||||
.Cm ^A
|
||||
is a control-A. An escape sequence is entered by typing the escape key
|
||||
followed by one or more characters. The escape key is abbreviated as
|
||||
.Cm ESC .
|
||||
Note that unlike control keys, case matters in escape sequences;
|
||||
.Cm ESC F
|
||||
is not the same as
|
||||
.Cm ESC f .
|
||||
.Pp
|
||||
An editing command may be typed anywhere on the line, not just at the
|
||||
beginning. In addition, a return may also be typed anywhere on the
|
||||
line, not just at the end.
|
||||
.Pp
|
||||
Most editing commands may be given a repeat count,
|
||||
.Ar n ,
|
||||
where
|
||||
.Ar n
|
||||
is a number. To enter a repeat count, type the escape key, the number,
|
||||
and then the command to execute. For example,
|
||||
.Cm ESC 4 ^f
|
||||
moves forward four characters. If a command may be given a repeat count
|
||||
then the text
|
||||
.Cm [n]
|
||||
is given at the end of its description.
|
||||
.Pp
|
||||
The following control characters are accepted:
|
||||
.Pp
|
||||
.Bl -tag -width "ESC DEL " -compact
|
||||
.It ^A
|
||||
Move to the beginning of the line
|
||||
.It ^B
|
||||
Move left (backwards) [n]
|
||||
.It ^D
|
||||
Delete character [n]
|
||||
.It ^E
|
||||
Move to end of line
|
||||
.It ^F
|
||||
Move right (forwards) [n]
|
||||
.It ^G
|
||||
Ring the bell
|
||||
.It ^H
|
||||
Delete character before cursor (backspace key) [n]
|
||||
.It ^I
|
||||
Complete filename (tab key); see below
|
||||
.It ^J
|
||||
Done with line (return key)
|
||||
.It ^K
|
||||
Kill to end of line (or column [n])
|
||||
.It ^L
|
||||
Redisplay line
|
||||
.It ^M
|
||||
Done with line (alternate return key)
|
||||
.It ^N
|
||||
Get next line from history [n]
|
||||
.It ^P
|
||||
Get previous line from history [n]
|
||||
.It ^R
|
||||
Search backward (forward if [n]) through history for text; prefixing the
|
||||
string with a caret (^) forces it to match only at the beginning of a
|
||||
history line
|
||||
.It ^T
|
||||
Transpose characters
|
||||
.It ^V
|
||||
Insert next character, even if it is an edit command
|
||||
.It ^W
|
||||
Wipe to the mark
|
||||
.It ^X^X
|
||||
Exchange current location and mark
|
||||
.It ^Y
|
||||
Yank back last killed text
|
||||
.It ^[
|
||||
Start an escape sequence (escape key)
|
||||
.It ^]c
|
||||
Move forward to next character
|
||||
.Cm c
|
||||
.It ^?
|
||||
Delete character before cursor (delete key) [n]
|
||||
.El
|
||||
.Pp
|
||||
The following escape sequences are provided:
|
||||
.Pp
|
||||
.Bl -tag -width "ESC DEL " -compact
|
||||
.It ESC ^H
|
||||
Delete previous word (backspace key) [n]
|
||||
.It ESC DEL
|
||||
Delete previous word (delete key) [n]
|
||||
.It ESC SP
|
||||
Set the mark (space key); see ^X^X and ^Y above
|
||||
.It ESC\ .
|
||||
Get the last (or [n]'th) word from previous line
|
||||
.It ESC\ ?
|
||||
Show possible completions; see below
|
||||
.It ESC <
|
||||
Move to start of history
|
||||
.It ESC >
|
||||
Move to end of history
|
||||
.It ESC b
|
||||
Move backward a word [n]
|
||||
.It ESC d
|
||||
Delete word under cursor [n]
|
||||
.It ESC f
|
||||
Move forward a word [n]
|
||||
.It ESC l
|
||||
Make word lowercase [n]
|
||||
.It ESC m
|
||||
Toggle if 8bit chars display normally or with an
|
||||
.Ar M-
|
||||
prefix
|
||||
.It ESC u
|
||||
Make word uppercase [n]
|
||||
.It ESC y
|
||||
Yank back last killed text
|
||||
.It ESC v
|
||||
Show library version
|
||||
.It ESC w
|
||||
Make area up to mark yankable
|
||||
.It ESC nn
|
||||
Set repeat count to the number nn
|
||||
.It ESC C
|
||||
Read from environment variable
|
||||
.Ar $C ,
|
||||
where
|
||||
.Ar C
|
||||
is an uppercase letter
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
library has a small macro facility. If you type the escape key followed
|
||||
by an uppercase letter,
|
||||
.Ar C ,
|
||||
then the contents of the environment variable
|
||||
.Ar $C
|
||||
are read in as if you had typed them at the keyboard. For example, if
|
||||
the variable
|
||||
.Ar $L
|
||||
contains the following:
|
||||
.Pp
|
||||
.Dl ^A^Kecho '^V^[[H^V^[[2J'^M
|
||||
.Pp
|
||||
Then typing
|
||||
.Cm ESC L
|
||||
will move to the beginning of the line, kill the entire line, enter the
|
||||
echo command needed to clear the terminal (if your terminal is like a
|
||||
VT-100), and send the line back to the shell.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
library also does filename completion. Suppose the root directory has
|
||||
the following files in it:
|
||||
.Pp
|
||||
.Dl bin vmunix
|
||||
.Dl core vmunix.old
|
||||
.Pp
|
||||
If you type
|
||||
.Cm rm /v
|
||||
and then the tab key,
|
||||
.Nm
|
||||
will then finish off as much of the name as possible by adding
|
||||
.Ar munix .
|
||||
Because the name is not unique, it will then beep. If you type the
|
||||
escape key and a question mark, it will display the two choices. If you
|
||||
then type a period and a tab, the library will finish off the filename
|
||||
for you:
|
||||
.Pp
|
||||
.Bd -ragged -offset indent
|
||||
rm /v[TAB]
|
||||
.Em munix
|
||||
\&.[TAB]
|
||||
.Em old
|
||||
.Ed
|
||||
.Pp
|
||||
The tab key is shown by [TAB] and the automatically-entered text
|
||||
is shown in italics, or underline.
|
||||
.Sh USAGE
|
||||
To include
|
||||
.Nm
|
||||
in your program, call it as you do any other function and link your
|
||||
program with
|
||||
.Ar -leditline .
|
||||
.Ss Example
|
||||
The following brief example lets you enter a line and edit it, then displays it.
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <editline.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char *p;
|
||||
|
||||
while ((p = readline("CLI> "))) {
|
||||
puts(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
.El
|
||||
.Sh AUTHORS
|
||||
The original editline library was posted to comp.sources.unix newsgroup
|
||||
by created by Simmule R. Turner and Rich Salz in 1992. It now exists in
|
||||
several forks: Debian, Minix, Heimdal, Festival speech tools, Mozilla,
|
||||
Google Gadgets for Linux, and many other places. The original manual
|
||||
page was made by David W. Sanderson.
|
||||
.Pp
|
||||
This version was originally based on the Minix 2 sources, but has since
|
||||
evolved to include patches from all relevant forks. It is currently
|
||||
maintained by Joachim Nilsson at GitHub,
|
||||
.Aq http://github.com/troglobit/editline
|
||||
.Sh BUGS
|
||||
Does not handle multiple lines or unicode characters well.
|
2064
editline.c
Normal file
2064
editline.c
Normal file
File diff suppressed because it is too large
Load Diff
232
editline.h
Normal file
232
editline.h
Normal file
@ -0,0 +1,232 @@
|
||||
/* Internal header file for editline library.
|
||||
*
|
||||
* Copyright (c) 1992, 1993 Simmule Turner and Rich Salz
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or of the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
* 1. The authors are not responsible for the consequences of use of this
|
||||
* software, no matter how awful, even if they arise from flaws in it.
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Since few users ever read sources,
|
||||
* credits must appear in the documentation.
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software. Since few users
|
||||
* ever read sources, credits must appear in the documentation.
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
#ifndef EDITLINE_PRIVATE_H_
|
||||
#define EDITLINE_PRIVATE_H_
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#ifdef SYS_UNIX
|
||||
#include "unix.h"
|
||||
#endif
|
||||
#ifdef SYS_OS9
|
||||
#include "os9.h"
|
||||
#endif
|
||||
/* The following two are for TIOCGWINSZ */
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
# include <termios.h>
|
||||
#endif
|
||||
#ifdef GWINSZ_IN_SYS_IOCTL
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#define MEM_INC 64
|
||||
#define SCREEN_INC 256
|
||||
|
||||
/* From The Practice of Programming, by Kernighan and Pike */
|
||||
#ifndef NELEMS
|
||||
#define NELEMS(array) (sizeof(array) / sizeof(array[0]))
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Variables and routines internal to this package.
|
||||
*/
|
||||
extern int rl_eof;
|
||||
extern int rl_erase;
|
||||
extern int rl_intr;
|
||||
extern int rl_kill;
|
||||
extern int rl_quit;
|
||||
#ifdef CONFIG_SIGSTOP
|
||||
extern int rl_susp;
|
||||
#endif
|
||||
void rl_ttyset(int Reset);
|
||||
void rl_add_slash(char *path, char *p);
|
||||
char *rl_complete(char *token, int *match);
|
||||
int rl_list_possib(char *token, char ***av);
|
||||
|
||||
#ifndef HAVE_STDLIB_H
|
||||
extern char *getenv(const char *name);
|
||||
extern char *malloc(size_t size);
|
||||
extern char *realloc(void *ptr, size_t size);
|
||||
extern char *memcpy(void *dest, const void *src, size_t n);
|
||||
extern char *strcat(char *dest, const char *src);
|
||||
extern char *strchr(const char *s, int c);
|
||||
extern char *strrchr(const char *s, int c);
|
||||
extern char *strcpy(char *dest, const char *src);
|
||||
extern char *strdup(const char *s);
|
||||
extern int strcmp(const char *s1, const char *s2);
|
||||
extern int strlen(const char *s);
|
||||
extern int strncmp(const char *s1, const char *s2, size_t n);
|
||||
#endif/* !HAVE_STDLIB_H */
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
extern char *strdup(const char *s);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 Simmule Turner and Rich Salz
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or of the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
* 1. The authors are not responsible for the consequences of use of this
|
||||
* software, no matter how awful, even if they arise from flaws in it.
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Since few users ever read sources,
|
||||
* credits must appear in the documentation.
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software. Since few users
|
||||
* ever read sources, credits must appear in the documentation.
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
#ifndef EDITLINE_H_
|
||||
#define EDITLINE_H_
|
||||
|
||||
/* Handy macros when binding keys. */
|
||||
#define CTL(x) ((x) & 0x1F)
|
||||
#define ISCTL(x) ((x) && (x) < ' ')
|
||||
#define UNCTL(x) ((x) + 64)
|
||||
#define META(x) ((x) | 0x80)
|
||||
#define ISMETA(x) ((x) & 0x80)
|
||||
#define UNMETA(x) ((x) & 0x7F)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Command status codes. */
|
||||
typedef enum {
|
||||
CSdone = 0, /* OK */
|
||||
CSeof, /* Error, or EOF */
|
||||
CSmove,
|
||||
CSdispatch,
|
||||
CSstay,
|
||||
CSsignal
|
||||
} el_status_t;
|
||||
|
||||
/* Editline specific types, despite rl_ prefix. From Heimdal project. */
|
||||
typedef int rl_list_possib_func_t(char*, char***);
|
||||
typedef el_status_t el_keymap_func_t(void);
|
||||
typedef int rl_hook_func_t(void);
|
||||
typedef int rl_getc_func_t(void);
|
||||
typedef void rl_voidfunc_t(void);
|
||||
typedef void rl_vintfunc_t(int);
|
||||
typedef void rl_vcpfunc_t(char *);
|
||||
|
||||
/* FSF Readline compat tupes */
|
||||
typedef char *rl_complete_func_t (char *, int*);
|
||||
typedef char *rl_compentry_func_t (const char *, int);
|
||||
typedef char **rl_completion_func_t (const char *, int, int);
|
||||
|
||||
/* Display 8-bit chars "as-is" or as `M-x'? Toggle with M-m. (Default:0 - "as-is") */
|
||||
extern int rl_meta_chars;
|
||||
|
||||
/* Editline specific functions. */
|
||||
extern char * el_find_word(void);
|
||||
extern void el_print_columns(int ac, char **av);
|
||||
extern el_status_t el_ring_bell(void);
|
||||
extern el_status_t el_del_char(void);
|
||||
|
||||
extern el_status_t el_bind_key(int key, el_keymap_func_t function);
|
||||
extern el_status_t el_bind_key_in_metamap(int key, el_keymap_func_t function);
|
||||
|
||||
extern const char *el_next_hist(void);
|
||||
extern const char *el_prev_hist(void);
|
||||
|
||||
extern char *rl_complete(char *token, int *match);
|
||||
extern int rl_list_possib(char *token, char ***av);
|
||||
extern char **rl_completion_matches(const char *token, rl_compentry_func_t *generator);
|
||||
extern char *rl_filename_completion_function(const char *text, int state);
|
||||
|
||||
/* For compatibility with FSF readline. */
|
||||
extern int rl_point;
|
||||
extern int rl_mark;
|
||||
extern int rl_end;
|
||||
extern int rl_inhibit_complete;
|
||||
extern char *rl_line_buffer;
|
||||
extern const char *rl_readline_name;
|
||||
extern FILE *rl_instream; /* The stdio stream from which input is read. Defaults to stdin if NULL - Not supported yet! */
|
||||
extern FILE *rl_outstream; /* The stdio stream to which output is flushed. Defaults to stdout if NULL - Not supported yet! */
|
||||
extern int el_no_echo; /* E.g under emacs, don't echo except prompt */
|
||||
extern int el_no_hist; /* Disable auto-save of and access to history -- e.g. for password prompts or wizards */
|
||||
extern int el_hist_size; /* size of history scrollback buffer, default: 15 */
|
||||
|
||||
extern void rl_initialize (void);
|
||||
extern void rl_reset_terminal (const char *terminal_name);
|
||||
extern void rl_uninitialize (void);
|
||||
|
||||
extern void rl_save_prompt (void);
|
||||
extern void rl_restore_prompt (void);
|
||||
extern void rl_set_prompt (const char *prompt);
|
||||
|
||||
extern void rl_clear_message (void);
|
||||
extern void rl_forced_update_display(void);
|
||||
|
||||
extern void rl_prep_terminal (int meta_flag);
|
||||
extern void rl_deprep_terminal (void);
|
||||
|
||||
extern int rl_getc(void);
|
||||
extern int rl_insert_text (const char *text);
|
||||
extern int rl_refresh_line (int ignore1, int ignore2);
|
||||
|
||||
extern char *readline (const char *prompt);
|
||||
|
||||
extern void add_history (const char *line);
|
||||
extern int read_history (const char *filename);
|
||||
extern int write_history (const char *filename);
|
||||
|
||||
extern rl_getc_func_t *rl_set_getc_func(rl_getc_func_t *func);
|
||||
|
||||
extern rl_completion_func_t *rl_attempted_completion_function;
|
||||
extern rl_complete_func_t *rl_set_complete_func (rl_complete_func_t *func);
|
||||
extern rl_list_possib_func_t *rl_set_list_possib_func (rl_list_possib_func_t *func);
|
||||
|
||||
/* Alternate interface to plain readline(), for event loops */
|
||||
extern void rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *lhandler);
|
||||
extern void rl_callback_read_char (void);
|
||||
extern void rl_callback_handler_remove (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EDITLINE_H_ */
|
||||
#endif /* EDITLINE_PRIVATE_H_ */
|
12
libeditline.pc
Normal file
12
libeditline.pc
Normal file
@ -0,0 +1,12 @@
|
||||
prefix=/usr/local
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: editline
|
||||
Description: A small line editing library without termcap/curses
|
||||
Version: 1.17.1
|
||||
Requires:
|
||||
Libs: -L${libdir} -leditline
|
||||
Cflags: -I${includedir}
|
||||
|
251
sysunix.c
Normal file
251
sysunix.c
Normal file
@ -0,0 +1,251 @@
|
||||
/* Unix system-dependant routines for editline library.
|
||||
*
|
||||
* Copyright (c) 1992, 1993 Simmule Turner and Rich Salz
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or of the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
* 1. The authors are not responsible for the consequences of use of this
|
||||
* software, no matter how awful, even if they arise from flaws in it.
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Since few users ever read sources,
|
||||
* credits must appear in the documentation.
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software. Since few users
|
||||
* ever read sources, credits must appear in the documentation.
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include "editline.h"
|
||||
|
||||
#ifndef HAVE_TCGETATTR
|
||||
/* Wrapper for ioctl syscalls to restart on signal */
|
||||
static int ioctl_wrap(int fd, int req, void *arg)
|
||||
{
|
||||
int result, retries = 3;
|
||||
|
||||
while (-1 == (result = ioctl(fd, req, arg)) && retries > 0) {
|
||||
retries--;
|
||||
|
||||
if (EINTR == errno)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Prefer termios over the others since it is likely the most portable. */
|
||||
#if defined(HAVE_TCGETATTR)
|
||||
#include <termios.h>
|
||||
|
||||
/* Wrapper for tcgetattr */
|
||||
static int getattr(int fd, struct termios *arg)
|
||||
{
|
||||
int result, retries = 3;
|
||||
|
||||
while (-1 == (result = tcgetattr(fd, arg)) && retries > 0) {
|
||||
retries--;
|
||||
|
||||
if (EINTR == errno)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Wrapper for tcgetattr */
|
||||
static int setattr(int fd, int opt, const struct termios *arg)
|
||||
{
|
||||
int result, retries = 3;
|
||||
|
||||
while (-1 == (result = tcsetattr(fd, opt, arg)) && retries > 0) {
|
||||
retries--;
|
||||
|
||||
if (EINTR == errno)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void rl_ttyset(int Reset)
|
||||
{
|
||||
static struct termios old;
|
||||
struct termios new;
|
||||
|
||||
if (!Reset) {
|
||||
if (-1 == getattr(0, &old))
|
||||
perror("Failed tcgetattr()");
|
||||
|
||||
rl_erase = old.c_cc[VERASE];
|
||||
rl_kill = old.c_cc[VKILL];
|
||||
rl_eof = old.c_cc[VEOF];
|
||||
rl_intr = old.c_cc[VINTR];
|
||||
rl_quit = old.c_cc[VQUIT];
|
||||
#ifdef CONFIG_SIGSTOP
|
||||
rl_susp = old.c_cc[VSUSP];
|
||||
#endif
|
||||
|
||||
new = old;
|
||||
new.c_lflag &= ~(ECHO | ICANON | ISIG);
|
||||
new.c_iflag &= ~INPCK;
|
||||
if (rl_meta_chars)
|
||||
new.c_iflag |= ISTRIP;
|
||||
else
|
||||
new.c_iflag &= ~ISTRIP;
|
||||
new.c_cc[VMIN] = 1;
|
||||
new.c_cc[VTIME] = 0;
|
||||
if (-1 == setattr(0, TCSADRAIN, &new))
|
||||
perror("Failed tcsetattr(TCSADRAIN)");
|
||||
} else {
|
||||
if (-1 == setattr(0, TCSADRAIN, &old))
|
||||
perror("Failed tcsetattr(TCSADRAIN)");
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(HAVE_TERMIO_H)
|
||||
#include <termio.h>
|
||||
|
||||
void rl_ttyset(int Reset)
|
||||
{
|
||||
static struct termio old;
|
||||
struct termio new;
|
||||
|
||||
if (!Reset) {
|
||||
if (-1 == ioctl_wrap(0, TCGETA, &old))
|
||||
perror("Failed ioctl(TCGETA)");
|
||||
|
||||
rl_erase = old.c_cc[VERASE];
|
||||
rl_kill = old.c_cc[VKILL];
|
||||
rl_eof = old.c_cc[VEOF];
|
||||
rl_intr = old.c_cc[VINTR];
|
||||
rl_quit = old.c_cc[VQUIT];
|
||||
#ifdef CONFIG_SIGSTOP
|
||||
rl_susp = old.c_cc[VSUSP];
|
||||
#endif
|
||||
|
||||
new = old;
|
||||
new.c_lflag &= ~(ECHO | ICANON | ISIG);
|
||||
new.c_iflag &= ~INPCK;
|
||||
if (rl_meta_chars)
|
||||
new.c_iflag |= ISTRIP;
|
||||
else
|
||||
new.c_iflag &= ~ISTRIP;
|
||||
|
||||
new.c_cc[VMIN] = 1;
|
||||
new.c_cc[VTIME] = 0;
|
||||
if (-1 == ioctl_wrap(0, TCSETAW, &new))
|
||||
perror("Failed ioctl(TCSETAW)");
|
||||
} else {
|
||||
if (-1 == ioctl_wrap(0, TCSETAW, &old))
|
||||
perror("Failed ioctl(TCSETAW)");
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(HAVE_SGTTY_H)
|
||||
#include <sgtty.h>
|
||||
|
||||
void rl_ttyset(int Reset)
|
||||
{
|
||||
static struct sgttyb old_sgttyb;
|
||||
static struct tchars old_tchars;
|
||||
struct sgttyb new_sgttyb;
|
||||
struct tchars new_tchars;
|
||||
#ifdef CONFIG_SIGSTOP
|
||||
struct ltchars old_ltchars;
|
||||
#endif
|
||||
|
||||
if (!Reset) {
|
||||
if (-1 == ioctl_wrap(0, TIOCGETP, &old_sgttyb))
|
||||
perror("Failed TIOCGETP");
|
||||
|
||||
rl_erase = old_sgttyb.sg_erase;
|
||||
rl_kill = old_sgttyb.sg_kill;
|
||||
|
||||
if (-1 == ioctl_wrap(0, TIOCGETC, &old_tchars))
|
||||
perror("Failed TIOCGETC");
|
||||
|
||||
rl_eof = old_tchars.t_eofc;
|
||||
rl_intr = old_tchars.t_intrc;
|
||||
rl_quit = old_tchars.t_quitc;
|
||||
|
||||
#ifdef CONFIG_SIGSTOP
|
||||
if (-1 == ioctl_wrap(0, TIOCGLTC, &old_ltchars))
|
||||
perror("Failed TIOCGLTC");
|
||||
|
||||
rl_susp = old_ltchars.t_suspc;
|
||||
#endif
|
||||
|
||||
new_sgttyb = old_sgttyb;
|
||||
new_sgttyb.sg_flags &= ~ECHO;
|
||||
new_sgttyb.sg_flags |= RAW;
|
||||
if (rl_meta_chars)
|
||||
new_sgttyb.sg_flags &= ~PASS8;
|
||||
else
|
||||
new_sgttyb.sg_flags |= PASS8;
|
||||
|
||||
if (-1 == ioctl_wrap(0, TIOCSETP, &new_sgttyb))
|
||||
perror("Failed TIOCSETP");
|
||||
|
||||
new_tchars = old_tchars;
|
||||
new_tchars.t_intrc = -1;
|
||||
new_tchars.t_quitc = -1;
|
||||
if (-1 == ioctl_wrap(0, TIOCSETC, &new_tchars))
|
||||
perror("Failed TIOCSETC");
|
||||
} else {
|
||||
if (-1 == ioctl_wrap(0, TIOCSETP, &old_sgttyb))
|
||||
perror("Failed TIOCSETP");
|
||||
|
||||
if (-1 == ioctl_wrap(0, TIOCSETC, &old_tchars))
|
||||
perror("Failed TIOCSETC");
|
||||
}
|
||||
}
|
||||
#else /* Neither HAVE_SGTTY_H, HAVE_TERMIO_H or HAVE_TCGETATTR */
|
||||
#error Unsupported platform, missing tcgetattr(), termio.h and sgtty.h
|
||||
#endif /* Neither HAVE_SGTTY_H, HAVE_TERMIO_H or HAVE_TCGETATTR */
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
/* Return an allocated copy of a string. */
|
||||
char *strdup(const char *s)
|
||||
{
|
||||
size_t len;
|
||||
char *ptr;
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
len = strlen(s) + 1;
|
||||
ptr = malloc(len);
|
||||
if (ptr)
|
||||
return memcpy(ptr, s, len);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void rl_add_slash(char *path, char *p)
|
||||
{
|
||||
struct stat Sb;
|
||||
|
||||
if (stat(path, &Sb) >= 0)
|
||||
strcat(p, S_ISDIR(Sb.st_mode) ? "/" : " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Local Variables:
|
||||
* c-file-style: "k&r"
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
36
unix.h
Normal file
36
unix.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* Editline system header file for Unix.
|
||||
*
|
||||
* Copyright (c) 1992, 1993 Simmule Turner and Rich Salz
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or of the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
* 1. The authors are not responsible for the consequences of use of this
|
||||
* software, no matter how awful, even if they arise from flaws in it.
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Since few users ever read sources,
|
||||
* credits must appear in the documentation.
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software. Since few users
|
||||
* ever read sources, credits must appear in the documentation.
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
#ifndef EDITLINE_UNIX_H_
|
||||
#define EDITLINE_UNIX_H_
|
||||
|
||||
#define CRLF "\r\n"
|
||||
#define FORWARD STATIC
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <dirent.h>
|
||||
typedef struct dirent DIRENTRY;
|
||||
|
||||
#endif /* EDITLINE_UNIX_H_ */
|
Loading…
Reference in New Issue
Block a user