10 Commits

Author SHA1 Message Date
Joachim Nilsson
0646b511ab Update README and bump version to 1.14.0 for release. 2010-08-12 16:58:36 +02:00
Joachim Nilsson
4f134f1025 Reduce tgetent() buffer size from 2048 to 1024. 2010-08-12 16:27:10 +02:00
Joachim Nilsson
850e36f9db Fix SIGFPE regression in tty_info() introduced in rl_reset_terminal() commit.
When adding support for rl_reset_termial() the tty_info() code was also
refactored.  This however led to the introduction of a bug that caused
tty_cols to be set to zero.  This in turn caused c_possible() to fail
with SIGFPE in el_print_columns().

Regression was introduced in 1c89c9886c
2010-08-12 16:20:29 +02:00
Joachim Nilsson
d72069144e Minor cleanup of unnecessary explicit casts. 2010-08-11 21:19:41 +02:00
Joachim Nilsson
fc08d47bce Update debian build script for configure based build and simplify rules. 2010-08-11 19:23:24 +02:00
Joachim Nilsson
87e69be38b Add support for inhibiting completion: rl_inhibit_completion 2010-08-11 13:14:32 +02:00
Joachim Nilsson
f984a48dae Update TODO and change to use org-mode. 2010-08-11 12:48:36 +02:00
Joachim Nilsson
d4d0c002dc Update build instructions with info on --prefix 2010-08-08 17:20:36 +02:00
Joachim Nilsson
2b747467f0 Add the customary INSTALL file with some basic help on the build process. 2010-08-08 17:17:12 +02:00
Joachim Nilsson
56478685d6 Remember to check custom completion handlers before release. 2010-08-07 12:24:05 +02:00
16 changed files with 160 additions and 617 deletions

44
INSTALL Normal file
View File

@@ -0,0 +1,44 @@
HowTo Build Minix Editline
==========================
Minix editline makes use of GNU configure tools, which includes autoconf, automake
and libtool. This enables high levels of portability and ease of use In most cases
all you need to do is unpack the tarball, enter the directory and type:
./configure
There are are, however, more options available. For instance, sometimes it is useful
to build editline as a static library, type:
./configure --disable-shared
By default editline employs a default handler for the TAB key, pressing it once
completes to the nearest matching filename in the current working directory, or it
can display a listing of possible completions. For some uses this default is not
desirable at all, type:
./configure --disable-default-complete
An even more common desire is to change the default install location. By default all
configure scripts setup /usr/local as the install "prefix", to change this type:
./configure --prefix=/home/troglobit/tmp
Advanced users are encouraged to read up on --libdir, --mandir, etc. in the GNU
Configure and Build System.
For more available options, type:
./configure --help
To build and install, simply type:
make
followed by
sudo make install
Good Luck!
//Joachim

View File

@@ -36,8 +36,8 @@ host_triplet = @host@
subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/configure NEWS TODO config.guess config.sub \
depcomp install-sh ltmain.sh missing
$(top_srcdir)/configure INSTALL NEWS TODO config.guess \
config.sub depcomp install-sh ltmain.sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \

43
README
View File

@@ -1,39 +1,36 @@
README -*-text-*-
This is a line editing library. It can be linked into almost any program to
provide command-line editing and history.
provide command-line editing and history. It is call-compatible with the FSF
readline library, but is a fraction of the size (and offers fewer features).
It is call-compatible with the FSF readline library, but it is a fraction of
the size (and offers fewer features). It does not use standard I/O. It is
distributed under a "C News-like" copyright, see the file LICENSE for details.
The editline library was created by Simmule Turner and Rich Salz back in 1992.
At the time they chose to distribute the code under a "C News-like" copyright,
see the file LICENSE for details.
The small size (<30k), lack of dependencies (no ncurses needed!) and the free
license should make this library interesting to many embedded developers.
Configuration is made by supplying different options to the GNU configure
script. In the examples/ directory you can find some small code snippets
used for testing.
script. In the examples/ directory you can find some small code snippets used
for testing.
Before finding out about the Debian version I was on the lookout for a really
small replacement for the GNU readline package. Not only was libreadline large
and GPL:ed (instead of LGPL:ed), it also depends on libncurses, the resulting
size was a bit too much for my embedded system. I eventually stubmled upon the
BSD libedit library, which was sufficient for a while, even though it too
depends on libncurses. I searched my soul and went back to where I, back in
1996, started out -- Minix. And there it was, a really small readline
replacement!
This version of the editline library is a fork off the Minix3 sources. Other
know versions, often based off of the original comp.sources.unix posting are:
In 2000 Jim Studt packaged libeditline for Debian[1], the exact origin of the
Debian code base is unclear, see the Sid package[2] for details. There were
some notable differences between that version and the upstream Minix sources,
all of which have now been merged here.
* Debian libeditline, http://packages.qa.debian.org/e/editline.html
* Heimdal, http://www.h5l.org
* Festival speech-tools, http://festvox.org/festival/
* Steve Tell's editline patches, http://www.cs.unc.edu/~tell/dist.html
The most intersting patches and bug fixes from each fork have been merged here.
Outstanding issues are listed in the TODO file.
An explanation of the version numbering may be in order. I didn't know about
the Debian version for quite some time, so I kept a different name for the
package and a different versioning scheme. In June 2009, I decided to line up
alongside Debian, with the intent of merging the efforts. Sorry for any
confusion this might cause.
alongside Debian, with the intent of merging the efforts.
Enjoy,
Joachim Nilsson <troglobit()vmlinux!org>
[1] - http://lists.debian.org/debian-devel/2000/05/msg00548.html
[2] - http://packages.debian.org/sid/libeditline0

29
TODO
View File

@@ -1,12 +1,35 @@
TODO
TODO -*-org-*-
Issues in need of work. Mostly compatibility with GNU readline, BSD libedit,
http://www.thrysoee.dk/editline/, and usability improvements.
Remember, the general idea is to keep Minix editline small.
* Verify for 1.14.0 that custom completion handlers still work
After reverting "fix" in 0.2.2 that made rl_complete() a function pointer we need to
make sure the same functionality is still available with the new infrastructure.
(Which is more inspired by BSD libedit and GNU readline.
* Investigate GNU readline dependencies needed for "fileman" example
The BSD libedit library has imported the GNU readline "fileman" example into its
tree to demonstrate the abilities of that library. This would also be quite useful
for Minix editline.
The first task is to investigate the depependencies and form TODO list items
detailing what is missing and, if possible, proposals how to implement including any
optional configure flags.
* Port "fileman" example from BSD libedit, http://www.thrysoee.dk/editline/
* Instead of supporting multiline input, try the Emacs approach, line scrolling.
* Add support for rl_bind_key(), currently only en editline specific el_bind_key() exists.
* Add support for inhibiting completion: rl_inhibit_completion
* Make "char *rl_prompt" globally visible.
* Add support for rl_set_prompt().
* Add support for --enable-utf8 to configure
* Use strcmp(nl_langinfo(CODESET), "UTF-8") to look for utf8 capable terminal.
* Implement simple UTF-8 parser according to http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8

20
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for editline 1.14.0-rc1.
# Generated by GNU Autoconf 2.65 for editline 1.14.0.
#
# Report bugs to <troglobit@vmlinux.org>.
#
@@ -701,8 +701,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='editline'
PACKAGE_TARNAME='editline'
PACKAGE_VERSION='1.14.0-rc1'
PACKAGE_STRING='editline 1.14.0-rc1'
PACKAGE_VERSION='1.14.0'
PACKAGE_STRING='editline 1.14.0'
PACKAGE_BUGREPORT='troglobit@vmlinux.org'
PACKAGE_URL=''
@@ -1424,7 +1424,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures editline 1.14.0-rc1 to adapt to many kinds of systems.
\`configure' configures editline 1.14.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1494,7 +1494,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of editline 1.14.0-rc1:";;
short | recursive ) echo "Configuration of editline 1.14.0:";;
esac
cat <<\_ACEOF
@@ -1604,7 +1604,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
editline configure 1.14.0-rc1
editline configure 1.14.0
generated by GNU Autoconf 2.65
Copyright (C) 2009 Free Software Foundation, Inc.
@@ -2029,7 +2029,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by editline $as_me 1.14.0-rc1, which was
It was created by editline $as_me 1.14.0, which was
generated by GNU Autoconf 2.65. Invocation command line was
$ $0 $@
@@ -2843,7 +2843,7 @@ fi
# Define the identity of the package.
PACKAGE='editline'
VERSION='1.14.0-rc1'
VERSION='1.14.0'
cat >>confdefs.h <<_ACEOF
@@ -11920,7 +11920,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by editline $as_me 1.14.0-rc1, which was
This file was extended by editline $as_me 1.14.0, which was
generated by GNU Autoconf 2.65. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -11986,7 +11986,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
editline config.status 1.14.0-rc1
editline config.status 1.14.0
configured by $0, generated by GNU Autoconf 2.65,
with options \\"\$ac_cs_config\\"

View File

@@ -13,7 +13,7 @@
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
AC_PREREQ(2.61)
AC_INIT(editline, 1.14.0-rc1, troglobit@vmlinux.org)
AC_INIT(editline, 1.14.0, troglobit@vmlinux.org)
AC_CONFIG_SRCDIR([src/editline.c])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_MACRO_DIR([m4])

6
debian/changelog vendored
View File

@@ -1,3 +1,9 @@
editline (1.14.0-1) unstable; urgency=low
* Update to new configure based build.
-- Joachim Nilsson <joachim.nilsson@vmlinux.org> Wed, 11 Aug 2010 13:28:00 +0100
editline (1.12-6) unstable; urgency=low
* Switch package format to 3.0 (quilt).

View File

@@ -1 +0,0 @@
usr/lib/*.so.*

4
debian/libeditline-dev.install vendored Normal file
View File

@@ -0,0 +1,4 @@
usr/include
usr/lib/libeditline*.*a
usr/lib/libeditline*.so
usr/share/man/man3

1
debian/libeditline0.install vendored Normal file
View File

@@ -0,0 +1 @@
usr/lib/libeditline*.so.*

33
debian/rules vendored
View File

@@ -1,5 +1,5 @@
#!/usr/bin/make -f
# Sample debian/rules that uses debhelper.
# debian/rules for libeditline
# GNU copyright 1997 to 1999 by Joey Hess.
# Uncomment this to turn on verbose mode.
@@ -12,14 +12,12 @@ major=0
build: build-stamp
build-stamp:
dh_testdir
$(MAKE)
touch build-stamp
dh_auto_configure
dh_auto_build
clean:
dh_testdir
dh_testroot
rm -f build-stamp
[ ! -f Makefile ] || $(MAKE) clean
dh_auto_clean
dh_clean
install: build
@@ -27,29 +25,18 @@ install: build
dh_testroot
dh_clean -k
dh_installdirs
$(MAKE) install DESTDIR=`pwd`/debian/libeditline-dev
cp include_editline.h \
`pwd`/debian/libeditline-dev/usr/include/editline.h
dh_auto_install
binary-indep: build install
binary-indep: install
binary-arch: build install
# build libeditline${major} package by moving files from editline-dev
binary-arch: install
dh_testdir
dh_testroot
# build libeditline${major} package by moving files from editline-dev
dh_movefiles --sourcedir=debian/libeditline-dev \
-plibeditline$(major) \
usr/lib/libeditline.so.$(major) \
usr/lib/libeditline.so.$(version)
dh_auto_install
dh_install --sourcedir=debian/tmp
dh_installdocs
dh_installexamples
dh_installmenu
dh_installmanpages
rm -rf debian/libeditline0/usr/share/man/
dh_installcron
dh_installinfo
dh_installchangelogs
dh_link
dh_strip
dh_compress
dh_fixperms

View File

@@ -1,6 +1,6 @@
AUTOMAKE_OPTIONS = foreign
noinst_PROGRAMS = testit cli fileman
noinst_PROGRAMS = testit cli
LDADD = $(top_builddir)/src/libeditline.la $(TERMLIBS)
AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include
AM_LDFLAGS = -static

View File

@@ -34,7 +34,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = testit$(EXEEXT) cli$(EXEEXT) fileman$(EXEEXT)
noinst_PROGRAMS = testit$(EXEEXT) cli$(EXEEXT)
subdir = examples
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -58,11 +58,6 @@ cli_DEPENDENCIES = $(top_builddir)/src/libeditline.la \
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
fileman_SOURCES = fileman.c
fileman_OBJECTS = fileman.$(OBJEXT)
fileman_LDADD = $(LDADD)
fileman_DEPENDENCIES = $(top_builddir)/src/libeditline.la \
$(am__DEPENDENCIES_1)
testit_SOURCES = testit.c
testit_OBJECTS = testit.$(OBJEXT)
testit_LDADD = $(LDADD)
@@ -94,8 +89,8 @@ am__v_CCLD_0 = @echo " CCLD " $@;
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = cli.c fileman.c testit.c
DIST_SOURCES = cli.c fileman.c testit.c
SOURCES = cli.c testit.c
DIST_SOURCES = cli.c testit.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -262,9 +257,6 @@ clean-noinstPROGRAMS:
cli$(EXEEXT): $(cli_OBJECTS) $(cli_DEPENDENCIES)
@rm -f cli$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(cli_OBJECTS) $(cli_LDADD) $(LIBS)
fileman$(EXEEXT): $(fileman_OBJECTS) $(fileman_DEPENDENCIES)
@rm -f fileman$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(fileman_OBJECTS) $(fileman_LDADD) $(LIBS)
testit$(EXEEXT): $(testit_OBJECTS) $(testit_DEPENDENCIES)
@rm -f testit$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(testit_OBJECTS) $(testit_LDADD) $(LIBS)
@@ -276,7 +268,6 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cli.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileman.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testit.Po@am__quote@
.c.o:

View File

@@ -1,499 +0,0 @@
/* fileman.c -- A tiny application which demonstrates how to use the
GNU Readline library. This application interactively allows users
to manipulate files and their modes.
NOTE: this was taken from the GNU Readline documentation and ported
to libedit. A commad to output the history list was added.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <locale.h>
#include <time.h>
/* GNU readline
#include <readline/readline.h>
#include <readline/history.h>
*/
/* NetBSD libedit
#include <editline/readline.h>
*/
#include <editline.h>
void * xmalloc (size_t size);
void too_dangerous (char *caller);
void initialize_readline ();
int execute_line (char *line);
int valid_argument (char *caller, char *arg);
typedef int rl_icpfunc_t (char *);
/* The names of functions that actually do the manipulation. */
int com_list (char *);
int com_view (char *);
int com_history (char *);
int com_rename(char *);
int com_stat(char *);
int com_pwd(char *);
int com_delete(char *);
int com_help(char *);
int com_cd(char *);
int com_quit(char *);
/* A structure which contains information on the commands this program
can understand. */
typedef struct {
char *name; /* User printable name of the function. */
rl_icpfunc_t *func; /* Function to call to do the job. */
char *doc; /* Documentation for this function. */
} COMMAND;
COMMAND commands[] = {
{ "cd", com_cd, "Change to directory DIR" },
{ "delete", com_delete, "Delete FILE" },
{ "help", com_help, "Display this text" },
{ "?", com_help, "Synonym for `help'" },
{ "list", com_list, "List files in DIR" },
{ "ls", com_list, "Synonym for `list'" },
{ "pwd", com_pwd, "Print the current working directory" },
{ "quit", com_quit, "Quit using Fileman" },
{ "rename", com_rename, "Rename FILE to NEWNAME" },
{ "stat", com_stat, "Print out statistics on FILE" },
{ "view", com_view, "View the contents of FILE" },
{ "history", com_history, "List editline history" },
{ (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL }
};
/* Forward declarations. */
char *stripwhite ();
COMMAND *find_command ();
/* The name of this program, as taken from argv[0]. */
char *progname;
/* When non-zero, this means the user is done using this program. */
int done;
char *
dupstr (char* s)
{
char *r;
r = xmalloc (strlen (s) + 1);
strcpy (r, s);
return (r);
}
int
main (int argc, char **argv)
{
char *line, *s;
progname = argv[0];
setlocale(LC_CTYPE, "");
initialize_readline(); /* Bind our completer. */
stifle_history(7);
/* Loop reading and executing lines until the user quits. */
for ( ; done == 0; )
{
line = readline ("FileMan: ");
if (!line)
break;
/* Remove leading and trailing whitespace from the line.
Then, if there is anything left, add it to the history list
and execute it. */
s = stripwhite(line);
if (*s) {
char* expansion;
int result;
result = history_expand(s, &expansion);
if (result < 0 || result == 2) {
fprintf(stderr, "%s\n", expansion);
} else {
add_history(expansion);
execute_line(expansion);
}
free(expansion);
}
free(line);
}
exit (0);
return 0;
}
/* Execute a command line. */
int
execute_line (char *line)
{
register int i;
COMMAND *command;
char *word;
/* Isolate the command word. */
i = 0;
while (line[i] && isspace (line[i]))
i++;
word = line + i;
while (line[i] && !isspace (line[i]))
i++;
if (line[i])
line[i++] = '\0';
command = find_command (word);
if (!command)
{
fprintf (stderr, "%s: No such command for FileMan.\n", word);
return (-1);
}
/* Get argument to command, if any. */
while (isspace (line[i]))
i++;
word = line + i;
/* Call the function. */
return ((*(command->func)) (word));
}
/* Look up NAME as the name of a command, and return a pointer to that
command. Return a NULL pointer if NAME isn't a command name. */
COMMAND *
find_command (char *name)
{
register int i;
for (i = 0; commands[i].name; i++)
if (strcmp (name, commands[i].name) == 0)
return (&commands[i]);
return ((COMMAND *)NULL);
}
/* Strip whitespace from the start and end of STRING. Return a pointer
into STRING. */
char *
stripwhite (char *string)
{
register char *s, *t;
for (s = string; isspace (*s); s++)
;
if (*s == 0)
return (s);
t = s + strlen (s) - 1;
while (t > s && isspace (*t))
t--;
*++t = '\0';
return s;
}
/* **************************************************************** */
/* */
/* Interface to Readline Completion */
/* */
/* **************************************************************** */
char *command_generator(const char *, int);
char **fileman_completion(const char *, int, int);
/* Tell the GNU Readline library how to complete. We want to try to
complete on command names if this is the first word in the line, or
on filenames if not. */
void
initialize_readline ()
{
/* Allow conditional parsing of the ~/.inputrc file. */
rl_readline_name = "FileMan";
/* Tell the completer that we want a crack first. */
rl_attempted_completion_function = fileman_completion;
}
/* Attempt to complete on the contents of TEXT. START and END
bound the region of rl_line_buffer that contains the word to
complete. TEXT is the word to complete. We can use the entire
contents of rl_line_buffer in case we want to do some simple
parsing. Returnthe array of matches, or NULL if there aren't any. */
char **
fileman_completion (const char* text, int start, int end)
{
char **matches;
matches = (char **)NULL;
/* If this word is at the start of the line, then it is a command
to complete. Otherwise it is the name of a file in the current
directory. */
if (start == 0)
/* TODO */
matches = completion_matches (text, command_generator);
/* matches = rl_completion_matches (text, command_generator); */
return (matches);
}
/* Generator function for command completion. STATE lets us
know whether to start from scratch; without any state
(i.e. STATE == 0), then we start at the top of the list. */
char *
command_generator (text, state)
const char *text;
int state;
{
static int list_index, len;
char *name;
/* If this is a new word to complete, initialize now. This
includes saving the length of TEXT for efficiency, and
initializing the index variable to 0. */
if (!state)
{
list_index = 0;
len = strlen (text);
}
/* Return the next name which partially matches from the
command list. */
while (name = commands[list_index].name)
{
list_index++;
if (strncmp (name, text, len) == 0)
return (dupstr(name));
}
/* If no names matched, then return NULL. */
return ((char *)NULL);
}
/* **************************************************************** */
/* */
/* FileMan Commands */
/* */
/* **************************************************************** */
/* String to pass to system (). This is for the LIST, VIEW and RENAME
commands. */
static char syscom[1024];
/* List the file(s) named in arg. */
int
com_list (char *arg)
{
if (!arg)
arg = "";
sprintf (syscom, "ls -FClg %s", arg);
return (system (syscom));
}
int
com_view (char *arg)
{
if (!valid_argument ("view", arg))
return 1;
sprintf (syscom, "more %s", arg);
return (system (syscom));
}
int
com_history(char* arg)
{
HIST_ENTRY *he;
/* rewind history */
while (next_history())
;
for (he = current_history(); he != NULL; he = previous_history()) {
//printf("%5d %s\n", *((int*)he->data) - 1, he->line);
printf("%s\n", he->line);
}
return 0;
}
int
com_rename (char *arg)
{
too_dangerous ("rename");
return (1);
}
int
com_stat (char *arg)
{
struct stat finfo;
if (!valid_argument ("stat", arg))
return (1);
if (stat (arg, &finfo) == -1)
{
perror (arg);
return (1);
}
printf ("Statistics for `%s':\n", arg);
printf ("%s has %ld link%s, and is %lld byte%s in length.\n", arg,
(long) finfo.st_nlink,
(finfo.st_nlink == 1) ? "" : "s",
(long long) finfo.st_size,
(finfo.st_size == 1) ? "" : "s");
printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime));
printf (" Last access at: %s", ctime (&finfo.st_atime));
printf (" Last modified at: %s", ctime (&finfo.st_mtime));
return (0);
}
int
com_delete (char *arg)
{
too_dangerous ("delete");
return (1);
}
/* Print out help for ARG, or for all of the commands if ARG is
not present. */
int
com_help (char *arg)
{
register int i;
int printed = 0;
for (i = 0; commands[i].name; i++)
{
if (!*arg || (strcmp (arg, commands[i].name) == 0))
{
printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc);
printed++;
}
}
if (!printed)
{
printf ("No commands match `%s'. Possibilties are:\n", arg);
for (i = 0; commands[i].name; i++)
{
/* Print in six columns. */
if (printed == 6)
{
printed = 0;
printf ("\n");
}
printf ("%s\t", commands[i].name);
printed++;
}
if (printed)
printf ("\n");
}
return (0);
}
/* Change to the directory ARG. */
int
com_cd (char *arg)
{
if (chdir (arg) == -1)
{
perror (arg);
return 1;
}
com_pwd ("");
return (0);
}
/* Print out the current working directory. */
int
com_pwd (char* ignore)
{
char dir[1024], *s;
s = (char*)getcwd(dir, sizeof(dir) - 1);
if (s == 0)
{
printf ("Error getting pwd: %s\n", dir);
return 1;
}
printf ("Current directory is %s\n", dir);
return 0;
}
/* The user wishes to quit using this program. Just set DONE
non-zero. */
int
com_quit (char *arg)
{
done = 1;
return (0);
}
/* Function which tells you that you can't do this. */
void
too_dangerous (char *caller)
{
fprintf (stderr,
"%s: Too dangerous for me to distribute.\n",
caller);
fprintf (stderr, "Write it yourself.\n");
}
/* Return non-zero if ARG is a valid argument for CALLER,
else print an error message and return zero. */
int
valid_argument (char *caller, char *arg)
{
if (!arg || !*arg)
{
fprintf (stderr, "%s: Argument required.\n", caller);
return (0);
}
return (1);
}
void *
xmalloc (size_t size)
{
register void *value = (void*)malloc(size);
if (value == 0)
fprintf(stderr, "virtual memory exhausted");
return value;
}

View File

@@ -49,10 +49,11 @@ extern void el_bind_key_in_metamap(int key, el_keymap_func_t function);
extern char *rl_complete(char *token, int *match);
extern int rl_list_possib(char *token, char ***av);
/* For compatibility with GNU Readline. */
/* 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! */
@@ -63,24 +64,18 @@ extern int el_hist_size; /* size of history scrollback buffer, default:
extern void rl_initialize(void);
extern void rl_reset_terminal(const char *terminal_name);
extern void rl_prep_terminal(int meta_flag);
extern void rl_deprep_terminal(void);
extern int rl_getc(void);
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_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);
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);
extern char *(*rl_completion_entry_function)(const char *text, int state);
extern char *rl_filename_completion_function(const char *text, int state);
void rl_prep_terminal(int meta_flag);
void rl_deprep_terminal(void);
extern int rl_attempted_completion_over;
extern char **(*rl_attempted_completion_function)(const char *text, int start, int end);
int rl_getc(void);
#endif /* __EDITLINE_H__ */

View File

@@ -1,7 +1,6 @@
/* Main editing routines for editline library.
*
* Copyright (c) 1992, 1993 Simmule Turner and Rich Salz. All rights reserved.
* Copyright (c) 1998 Alan W. Black <awb()cstr!ed.ac!uk>, for Edinburgh Speech Tools.
*
* This software is not subject to any license of the American Telephone
* and Telegraph Company or of the Regents of the University of California.
@@ -117,6 +116,7 @@ int rl_point;
int rl_mark;
int rl_end;
int rl_meta_chars = 0; /* Display 8-bit chars as the actual char(0) or as `M-x'(1)? */
int rl_inhibit_complete = 0;
char *rl_line_buffer;
const char *rl_prompt;
const char *rl_readline_name; /* Set by calling program, for conditional parsing of ~/.inputrc - Not supported yet! */
@@ -244,23 +244,6 @@ static void tty_backn(int n)
static void tty_info(void)
{
static int init;
if (init) {
#ifdef TIOCGWINSZ
struct winsize W;
if (ioctl(el_outfd, TIOCGWINSZ, &W) >= 0 && W.ws_col > 0 && W.ws_row > 0) {
tty_cols = (int)W.ws_col;
tty_rows = (int)W.ws_row;
}
#endif
return;
}
init++;
/* Initialize to faulty values to trigger fallback if nothing else works. */
tty_cols = tty_rows = -1;
rl_reset_terminal(NULL);
}
@@ -905,7 +888,15 @@ static el_status_t emacs(int c)
if (kp->Key == c)
break;
}
s = kp->Function ? kp->Function() : insert_char(c);
if (kp->Function) {
s = kp->Function();
if (s == CSdispatch) /* If Function is inhibited. */
s = insert_char(c);
} else {
s = insert_char(c);
}
if (!el_pushed) {
/* No pushback means no repeat count; hacky, but true. */
Repeat = NO_ARG;
@@ -1074,7 +1065,7 @@ static char *read_redirected(void)
void rl_reset_terminal(const char *terminal_name)
{
#ifdef CONFIG_USE_TERMCAP
char buff[2048];
char buf[1024];
char *bp;
#endif
#ifdef TIOCGWINSZ
@@ -1083,15 +1074,16 @@ void rl_reset_terminal(const char *terminal_name)
if (terminal_name) {
el_term = terminal_name;
return;
} else if ((el_term = getenv("TERM")) == NULL) {
el_term = "dumb";
}
if ((el_term = getenv("TERM")) == NULL)
el_term = "dumb";
/* Initialize to faulty values to trigger fallback if nothing else works. */
tty_cols = tty_rows = -1;
#ifdef CONFIG_USE_TERMCAP
bp = buff;
if (-1 != tgetent(buff, el_term)) {
bp = buf;
if (-1 != tgetent(buf, el_term)) {
if ((backspace = tgetstr("le", &bp)) != NULL)
backspace = strdup(backspace);
tty_cols = tgetnum("co");
@@ -1102,7 +1094,7 @@ void rl_reset_terminal(const char *terminal_name)
if (tty_cols <= 0 || tty_rows <= 0) {
#ifdef TIOCGWINSZ
if (-1 != ioctl(el_outfd, TIOCGWINSZ, &W)) {
if (ioctl(el_outfd, TIOCGWINSZ, &W) >= 0 && W.ws_col > 0 && W.ws_row > 0) {
tty_cols = (int)W.ws_col;
tty_rows = (int)W.ws_row;
return;
@@ -1315,20 +1307,23 @@ static el_status_t c_complete(void)
char *word, *new;
size_t len;
int unique;
el_status_t s = 0;
el_status_t s = CSdone;
if (rl_inhibit_complete)
return CSdispatch;
word = el_find_word();
p = (char *)rl_complete((char *)word, &unique);
p = rl_complete(word, &unique);
if (word)
free(word);
if (p) {
len = strlen((char *)p);
len = strlen(p);
word = p;
new = q = malloc(sizeof(char) * (2 * len + 1));
if (!new)
return CSstay;
while (*p) {
if ((*p < ' ' || strchr(SEPS, (char) *p) != NULL)
if ((*p < ' ' || strchr(SEPS, *p) != NULL)
&& (!unique || p[1] != 0)) {
*q++ = '\\';
}