New library

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@1037 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1996-11-17 22:00:28 +00:00
parent 99dc5f53cf
commit 771895a10e
9 changed files with 2034 additions and 0 deletions

87
lib/editline/Makefile.in Normal file
View File

@@ -0,0 +1,87 @@
#
# $Id$
#
SHELL = /bin/sh
srcdir = @srcdir@
VPATH = @srcdir@
CC = @CC@
AR = ar
RANLIB = @RANLIB@
DEFS = @DEFS@ -DLIBDIR='"$(libdir)"'
CFLAGS = @CFLAGS@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
prefix = @prefix@
exec_prefix = $(prefix)
libdir = $(exec_prefix)/lib
PICFLAGS = @PICFLAGS@
LIBNAME = libeditline
LIBEXT = @LIBEXT@
SHLIBEXT = @SHLIBEXT@
SHARED = @SHARED@
LIB = $(LIBNAME).$(LIBEXT) $(AFS_EXTRA_LIBS)
SOURCES = editline.c complete.c sysunix.c
OBJECTS = editline.o complete.o sysunix.o
all: $(LIB)
Wall:
make CFLAGS="-g -Wall -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
.c.o:
$(CC) -c $(CPPFLAGS) $(DEFS) -I../.. -I../../include -I$(srcdir) $(CFLAGS) $(PICFLAGS) $<
install: all
$(MKINSTALLDIRS) $(libdir)
$(INSTALL) -m 0555 $(LIB) $(libdir)
uninstall:
TAGS: $(SOURCES)
etags $(SOURCES)
check:
clean:
rm -f $(LIB) *.o *.a
mostlyclean: clean
distclean: clean
rm -f Makefile *.tab.c *~
realclean: distclean
rm -f TAGS
dist: $(DISTFILES)
for file in $(DISTFILES); do \
ln $$file ../`cat ../.fname`/lib \
|| cp -p $$file ../`cat ../.fname`/lib; \
done
$(LIBNAME).a: $(OBJECTS) @AFS_EXTRA_OBJS@
rm -f $@
$(AR) cr $@ $(OBJECTS) @AFS_EXTRA_OBJS@
-$(RANLIB) $@
$(LIBNAME).$(SHLIBEXT): $(OBJECTS)
rm -f $@
$(CC) $(CFLAGS) $(PICFLAGS) $(SHARED) -o $@ $(OBJECTS)
# AIX: this almost works with gcc, but somehow it fails to use the
# correct ld, use ld instead
afslib.so: afslib.o
ld -o $@ -bM:SRE -bI:$(srcdir)/afsl.exp -bE:$(srcdir)/afslib.exp -bnoentry afslib.o
$(OBJECTS): ../../config.h

45
lib/editline/README Normal file
View File

@@ -0,0 +1,45 @@
$Revision$
This is a line-editing library. It can be linked into almost any
program to provide command-line editing and recall.
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.
Configuration is done in the Makefile. Type "make testit" to get
a small slow shell for testing.
An earlier version was distributed with Byron's rc. Principal
changes over that version include:
Faster.
Is eight-bit clean (thanks to brendan@cs.widener.edu)
Written in K&R C, but ANSI compliant (gcc all warnings)
Propagates EOF properly; rc trip test now passes
Doesn't need or use or provide memmove.
More robust
Calling sequence changed to be compatible with readline.
Test program, new manpage, better configuration
More system-independant; includes Unix and OS-9 support.
Enjoy,
Rich $alz
<rsalz@osf.org>
Copyright 1992 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.

205
lib/editline/complete.c Normal file
View File

@@ -0,0 +1,205 @@
/* $Revision$
**
** History and file completion functions for editline library.
*/
#include "editline.h"
/*
** strcmp-like sorting predicate for qsort.
*/
static int
compare(p1, p2)
const void *p1;
const void *p2;
{
const char **v1;
const char **v2;
v1 = (const char **)p1;
v2 = (const char **)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(dir, file, avp)
char *dir;
char *file;
char ***avp;
{
char **av;
char **new;
char *p;
DIR *dp;
DIRENTRY *ep;
size_t ac;
size_t len;
if ((dp = opendir(dir)) == NULL)
return 0;
av = NULL;
ac = 0;
len = strlen(file);
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;
if ((ac % MEM_INC) == 0) {
if ((new = NEW(char*, ac + MEM_INC)) == NULL)
break;
if (ac) {
COPYFROMTO(new, av, ac * sizeof (char **));
DISPOSE(av);
}
*avp = av = new;
}
if ((av[ac] = strdup(p)) == NULL) {
if (ac == 0)
DISPOSE(av);
break;
}
ac++;
}
/* Clean up and return. */
(void)closedir(dp);
if (ac)
qsort(av, ac, sizeof (char **), compare);
return ac;
}
/*
** Split a pathname into allocated directory and trailing filename parts.
*/
static int
SplitPath(path, dirpart, filepart)
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) {
DISPOSE(dpart);
return -1;
}
}
else {
if ((dpart = strdup(path)) == NULL)
return -1;
dpart[fpart - path] = '\0';
if ((fpart = strdup(++fpart)) == NULL) {
DISPOSE(dpart);
return -1;
}
}
*dirpart = dpart;
*filepart = fpart;
return 0;
}
/*
** Attempt to complete the pathname, returning an allocated copy.
** Fill in *unique if we completed it, or set it to 0 if ambiguous.
*/
char *
rl_complete(pathname, unique)
char *pathname;
int *unique;
{
char **av;
char *dir;
char *file;
char *new;
char *p;
size_t ac;
size_t end;
size_t i;
size_t j;
size_t len;
if (SplitPath(pathname, &dir, &file) < 0)
return NULL;
if ((ac = FindMatches(dir, file, &av)) == 0) {
DISPOSE(dir);
DISPOSE(file);
return NULL;
}
p = NULL;
len = strlen(file);
if (ac == 1) {
/* Exactly one match -- finish it off. */
*unique = 1;
j = strlen(av[0]) - len + 2;
if ((p = NEW(char, j + 1)) != NULL) {
COPYFROMTO(p, av[0] + len, j);
if ((new = NEW(char, strlen(dir) + strlen(av[0]) + 2)) != NULL) {
(void)strcpy(new, dir);
(void)strcat(new, "/");
(void)strcat(new, av[0]);
rl_add_slash(new, p);
DISPOSE(new);
}
}
}
else {
*unique = 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;
if ((p = NEW(char, j)) != NULL) {
COPYFROMTO(p, av[0] + len, j);
p[j - 1] = '\0';
}
}
}
}
/* Clean up and return. */
DISPOSE(dir);
DISPOSE(file);
for (i = 0; i < ac; i++)
DISPOSE(av[i]);
DISPOSE(av);
return p;
}
/*
** Return all possible completions.
*/
int
rl_list_possib(pathname, avp)
char *pathname;
char ***avp;
{
char *dir;
char *file;
int ac;
if (SplitPath(pathname, &dir, &file) < 0)
return 0;
ac = FindMatches(dir, file, avp);
DISPOSE(dir);
DISPOSE(file);
return ac;
}

175
lib/editline/editline.3 Normal file
View File

@@ -0,0 +1,175 @@
.\" $Revision$
.TH EDITLINE 3
.SH NAME
editline \- command-line editing library with history
.SH SYNOPSIS
.nf
.B "char *"
.B "readline(prompt)"
.B " char *prompt;"
.B "void"
.B "add_history(line)"
.B " char *line;"
.fi
.SH DESCRIPTION
.I Editline
is a library that provides an line-editing interface with text recall.
It is intended to be compatible with the
.I readline
library provided by the Free Software Foundation, but much smaller.
The bulk of this manual page describes the user interface.
.PP
The
.I readline
routine returns a line of text with the trailing newline removed.
The data is returned in a buffer allocated with
.IR malloc (3),
so the space should be released with
.IR free (3)
when the calling program is done with it.
Before accepting input from the user, the specified
.I prompt
is displayed on the terminal.
.PP
The
.I add_history
routine makes a copy of the specified
.I line
and adds it to the internal history list.
.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, ``^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 ``ESC.''
Note that unlike control keys, case matters in escape sequences; ``ESC\ F''
is not the same as ``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,
.IR n ,
where
.I n
is a number.
To enter a repeat count, type the escape key, the number, and then
the command to execute.
For example, ``ESC\ 4\ ^f'' moves forward four characters.
If a command may be given a repeat count then the text ``[n]'' is given at the
end of its description.
.PP
The following control characters are accepted:
.RS
.nf
.ta \w'ESC DEL 'u
^A Move to the beginning of the line
^B Move left (backwards) [n]
^D Delete character [n]
^E Move to end of line
^F Move right (forwards) [n]
^G Ring the bell
^H Delete character before cursor (backspace key) [n]
^I Complete filename (tab key); see below
^J Done with line (return key)
^K Kill to end of line (or column [n])
^L Redisplay line
^M Done with line (alternate return key)
^N Get next line from history [n]
^P Get previous line from history [n]
^R Search backward (forward if [n]) through history for text;
\& must start line if text begins with an uparrow
^T Transpose characters
^V Insert next character, even if it is an edit command
^W Wipe to the mark
^X^X Exchange current location and mark
^Y Yank back last killed text
^[ Start an escape sequence (escape key)
^]c Move forward to next character ``c''
^? Delete character before cursor (delete key) [n]
.fi
.RE
.PP
The following escape sequences are provided.
.RS
.nf
.ta \w'ESC DEL 'u
ESC\ ^H Delete previous word (backspace key) [n]
ESC\ DEL Delete previous word (delete key) [n]
ESC\ SP Set the mark (space key); see ^X^X and ^Y above
ESC\ \. Get the last (or [n]'th) word from previous line
ESC\ \? Show possible completions; see below
ESC\ < Move to start of history
ESC\ > Move to end of history
ESC\ b Move backward a word [n]
ESC\ d Delete word under cursor [n]
ESC\ f Move forward a word [n]
ESC\ l Make word lowercase [n]
ESC\ u Make word uppercase [n]
ESC\ y Yank back last killed text
ESC\ v Show library version
ESC\ w Make area up to mark yankable
ESC\ nn Set repeat count to the number nn
ESC\ C Read from environment variable ``_C_'', where C is
\& an uppercase letter
.fi
.RE
.PP
The
.I editline
library has a small macro facility.
If you type the escape key followed by an uppercase letter,
.IR C ,
then the contents of the environment variable
.I _C_
are read in as if you had typed them at the keyboard.
For example, if the variable
.I _L_
contains the following:
.RS
^A^Kecho '^V^[[H^V^[[2J'^M
.RE
Then typing ``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
.I editline
library also does filename completion.
Suppose the root directory has the following files in it:
.RS
.nf
.ta \w'core 'u
bin vmunix
core vmunix.old
.fi
.RE
If you type ``rm\ /v'' and then the tab key.
.I Editline
will then finish off as much of the name as possible by adding ``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:
.RS
.nf
.RI "rm /v[TAB]" munix .TAB old
.fi
.RE
The tab key is shown by ``[TAB]'' and the automatically-entered text
is shown in italics.
.SH "BUGS AND LIMITATIONS"
Cannot handle lines more than 80 columns.
.SH AUTHORS
Simmule R. Turner <uunet.uu.net!capitol!sysgo!simmy>
and Rich $alz <rsalz@osf.org>.
Original manual page by DaviD W. Sanderson <dws@ssec.wisc.edu>.

1338
lib/editline/editline.c Normal file

File diff suppressed because it is too large Load Diff

59
lib/editline/editline.h Normal file
View File

@@ -0,0 +1,59 @@
/* $Revision$
**
** Internal header file for editline library.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CRLF "\r\n"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_DIRENT_H
#include <dirent.h>
typedef struct dirent DIRENTRY;
#else
#include <sys/dir.h>
typedef struct direct DIRENTRY;
#endif
#if !defined(S_ISDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif /* !defined(S_ISDIR) */
typedef unsigned char CHAR;
#define MEM_INC 64
#define SCREEN_INC 256
#define DISPOSE(p) free((char *)(p))
#define NEW(T, c) \
((T *)malloc((unsigned int)(sizeof (T) * (c))))
#define RENEW(p, T, c) \
(p = (T *)realloc((char *)(p), (unsigned int)(sizeof (T) * (c))))
#define COPYFROMTO(new, p, len) \
(void)memcpy((char *)(new), (char *)(p), (int)(len))
/*
** 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;
extern char *rl_complete();
extern int rl_list_possib();
extern void rl_ttyset();
extern void rl_add_slash();

44
lib/editline/sysunix.c Normal file
View File

@@ -0,0 +1,44 @@
/* $Revision$
**
** Unix system-dependant routines for editline library.
*/
#include "editline.h"
#include <termios.h>
void
rl_ttyset(int Reset)
{
static struct termios old;
struct termios new;
if (Reset == 0) {
tcgetattr(0, &old);
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];
new = old;
new.c_cc[VINTR] = -1;
new.c_cc[VQUIT] = -1;
new.c_lflag &= ~(ECHO | ICANON);
new.c_iflag &= ~(ISTRIP | INPCK);
new.c_cc[VMIN] = 1;
new.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new);
}
else
tcsetattr(0, TCSANOW, &old);
}
void
rl_add_slash(char *path, char *p)
{
struct stat Sb;
if (stat(path, &Sb) >= 0)
strcat(p, S_ISDIR(Sb.st_mode) ? "/" : " ");
}

59
lib/editline/testit.c Normal file
View File

@@ -0,0 +1,59 @@
/* $Revision$
**
** A "micro-shell" to test editline library.
** If given any arguments, commands aren't executed.
*/
#include <stdio.h>
#if defined(HAVE_STDLIB)
#include <stdlib.h>
#endif /* defined(HAVE_STDLIB) */
extern char *readline();
extern void add_history();
#if !defined(HAVE_STDLIB)
extern int chdir();
extern int free();
extern int strncmp();
extern int system();
extern void exit();
#endif /* !defined(HAVE_STDLIB) */
#if defined(NEED_PERROR)
void
perror(s)
char *s;
{
extern int errno;
(voidf)printf(stderr, "%s: error %d\n", s, errno);
}
#endif /* defined(NEED_PERROR) */
/* ARGSUSED1 */
int
main(ac, av)
int ac;
char *av[];
{
char *p;
int doit;
doit = ac == 1;
while ((p = readline("testit> ")) != NULL) {
(void)printf("\t\t\t|%s|\n", p);
if (doit)
if (strncmp(p, "cd ", 3) == 0) {
if (chdir(&p[3]) < 0)
perror(&p[3]);
}
else if (system(p) != 0)
perror(p);
add_history(p);
free(p);
}
exit(0);
/* NOTREACHED */
}

22
lib/editline/unix.h Normal file
View File

@@ -0,0 +1,22 @@
/* $Revision$
**
** Editline system header file for Unix.
*/
#define CRLF "\r\n"
#define FORWARD STATIC
#include <sys/types.h>
#include <sys/stat.h>
#if defined(USE_DIRENT)
#include <dirent.h>
typedef struct dirent DIRENTRY;
#else
#include <sys/dir.h>
typedef struct direct DIRENTRY;
#endif /* defined(USE_DIRENT) */
#if !defined(S_ISDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif /* !defined(S_ISDIR) */