Return-Path: osf.org!rsalz Received: from postman.osf.org ([130.105.1.152]) by hawkwind.utcs.toronto.edu with SMTP id <2770>; Mon, 26 Oct 1992 16:59:19 -0500 Received: from earth.osf.org by postman.osf.org (5.64+/OSF 1.0) id AA12344; Mon, 26 Oct 92 16:59:05 -0500 Received: by earth.osf.org (5.64/4.7) id AA01084; Mon, 26 Oct 92 16:59:01 -0500 Date: Mon, 26 Oct 1992 16:59:01 -0500 From: rsalz@osf.org Message-Id: <9210262159.AA01084@earth.osf.org> To: cks@hawkwind.utcs.toronto.edu Subject: Re: Revised editline #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # Contents: README Makefile editline.3 editline.h unix.h editline.c # complete.c sysunix.c testit.c Make.os9 os9.h sysos9.c # Wrapped by rsalz@earth on Mon Oct 26 11:17:04 1992 PATH=/bin:/usr/bin:/usr/ucb ; export PATH echo If this archive is complete, you will see the following message: echo ' "shar: End of archive."' if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1934 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' X$Revision: 1.5 $ X XThis is a line-editing library. It can be linked into almost any Xprogram to provide command-line editing and recall. X XIt is call-compatible with the FSF readline library, but it is a Xfraction of the size (and offers fewer features). It does not use Xstandard I/O. It is distributed under a "C News-like" copyright. X XConfiguration is done in the Makefile. Type "make testit" to get Xa small slow shell for testing. X XAn earlier version was distributed with Byron's rc. Principal Xchanges over that version include: X Faster. X Is eight-bit clean (thanks to brendan@cs.widener.edu) X Written in K&R C, but ANSI compliant (gcc all warnings) X Propagates EOF properly; rc trip test now passes X Doesn't need or use or provide memmove. X More robust X Calling sequence changed to be compatible with readline. X Test program, new manpage, better configuration X More system-independant; includes Unix and OS-9 support. X XEnjoy, X Rich $alz X X X Copyright 1992 Simmule Turner and Rich Salz. All rights reserved. X X This software is not subject to any license of the American Telephone X and Telegraph Company or of the Regents of the University of California. X X Permission is granted to anyone to use this software for any purpose on X any computer system, and to alter it and redistribute it freely, subject X to the following restrictions: X 1. The authors are not responsible for the consequences of use of this X software, no matter how awful, even if they arise from flaws in it. X 2. The origin of this software must not be misrepresented, either by X explicit claim or by omission. Since few users ever read sources, X credits must appear in the documentation. X 3. Altered versions must be plainly marked as such, and must not be X misrepresented as being the original software. Since few users X ever read sources, credits must appear in the documentation. X 4. This notice may not be removed or altered. END_OF_FILE if test 1934 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(1836 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X## $Revision: 1.3 $ X## X## Unix makefile for editline library. X## X X## Set your options: X## -DANSI_ARROWS ANSI arrows keys work like emacs. X## -DHAVE_STDLIB Have . X## -DHAVE_TCGETATTR Have tcgetattr(), tcsetattr(). X## -DHIDE Make static functions static (non debug). X## -DHIST_SIZE=n History size. X## -DNEED_STRDUP Don't have strdup(). X## -DUNIQUE_HISTORY Don't save command if same as last one. X## -DUSE_DIRENT Use , not ? X## -DUSE_TERMCAP Use the termcap library for terminal size X## see LDFLAGS, below, if you set this. X## -DNEED_PERROR Don't have perror() (used in testit) XDEFS = -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX X X## Set your C compiler: XWARN = -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings \ X -Wunused -Wcomment -Wswitch XCC = gcc -ansi $(WARN) X#CC = cc XCFLAGS = $(DEFS) -O -g X X## If you have -DUSE_TERMCAP, set this as appropriate: X#LDFLAGS = -ltermlib X#LDFLAGS = -ltermcap X X## Set ranlib as appropriate: XRANLIB = ranlib X#RANLIB = echo X X## End of configuration. X XSOURCES = editline.c complete.c sysunix.c XOBJECTS = editline.o complete.o sysunix.o XSHARFILES = README Makefile editline.3 editline.h unix.h editline.c \ X complete.c sysunix.c testit.c \ X Make.os9 os9.h sysos9.c X Xall: libedit.a X Xtestit: testit.c libedit.a X $(CC) $(CFLAGS) -o testit testit.c libedit.a $(LDFLAGS) X Xshar: $(SHARFILES) X shar $(SHARFILES) >shar X Xclean: X rm -f *.[oa] testit foo core tags lint lint.all a.out shar X Xlint: testit X lint -a -b -u -x $(DEFS) $(SOURCES) testit.c >lint.all X sed -e '/warning: function prototype not in scope/d' \ X -e '/warning: old style argument declaration/'d \ X -e '/mix of old and new style function declaration/'d \ X lint X Xlibedit.a: $(OBJECTS) X @rm -f $@ X ar r $@ $(OBJECTS) X $(RANLIB) $@ X X$(OBJECTS): editline.h END_OF_FILE if test 1836 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'editline.3' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'editline.3'\" else echo shar: Extracting \"'editline.3'\" \(5281 characters\) sed "s/^X//" >'editline.3' <<'END_OF_FILE' X.\" $Revision: 1.1 $ X.TH EDITLINE 3 X.SH NAME Xeditline \- command-line editing library with history X.SH SYNOPSIS X.nf X.B "char *" X.B "readline(prompt)" X.B " char *prompt;" X X.B "void" X.B "add_history(line)" X.B " char *line;" X.fi X.SH DESCRIPTION X.I Editline Xis a library that provides an line-editing interface with text recall. XIt is intended to be compatible with the X.I readline Xlibrary provided by the Free Software Foundation, but much smaller. XThe bulk of this manual page describes the user interface. X.PP XThe X.I readline Xroutine returns a line of text with the trailing newline removed. XThe data is returned in a buffer allocated with X.IR malloc (3), Xso the space should be released with X.IR free (3) Xwhen the calling program is done with it. XBefore accepting input from the user, the specified X.I prompt Xis displayed on the terminal. X.PP XThe X.I add_history Xroutine makes a copy of the specified X.I line Xand adds it to the internal history list. X.SS "User Interface" XA program that uses this library provides a simple emacs-like editing Xinterface to its users. XA line may be edited before it is sent to the calling program by typing either Xcontrol characters or escape sequences. XA control character, shown as a caret followed by a letter, is typed by Xholding down the ``control'' key while the letter is typed. XFor example, ``^A'' is a control-A. XAn escape sequence is entered by typing the ``escape'' key followed by one or Xmore characters. XThe escape key is abbreviated as ``ESC.'' XNote that unlike control keys, case matters in escape sequences; ``ESC\ F'' Xis not the same as ``ESC\ f''. X.PP XAn editing command may be typed anywhere on the line, not just at the Xbeginning. XIn addition, a return may also be typed anywhere on the line, not just at Xthe end. X.PP XMost editing commands may be given a repeat count, X.IR n , Xwhere X.I n Xis a number. XTo enter a repeat count, type the escape key, the number, and then Xthe command to execute. XFor example, ``ESC\ 4\ ^f'' moves forward four characters. XIf a command may be given a repeat count then the text ``[n]'' is given at the Xend of its description. X.PP XThe following control characters are accepted: X.RS X.nf X.ta \w'ESC DEL 'u X^A Move to the beginning of the line X^B Move left (backwards) [n] X^D Delete character [n] X^E Move to end of line X^F Move right (forwards) [n] X^G Ring the bell X^H Delete character before cursor (backspace key) [n] X^I Complete filename (tab key); see below X^J Done with line (return key) X^K Kill to end of line (or column [n]) X^L Redisplay line X^M Done with line (alternate return key) X^N Get next line from history [n] X^P Get previous line from history [n] X^R Search backward (forward if [n]) through history for text; X\& must start line if text begins with an uparrow X^T Transpose characters X^V Insert next character, even if it is an edit command X^W Wipe to the mark X^X^X Exchange current location and mark X^Y Yank back last killed text X^[ Start an escape sequence (escape key) X^]c Move forward to next character ``c'' X^? Delete character before cursor (delete key) [n] X.fi X.RE X.PP XThe following escape sequences are provided. X.RS X.nf X.ta \w'ESC DEL 'u XESC\ ^H Delete previous word (backspace key) [n] XESC\ DEL Delete previous word (delete key) [n] XESC\ SP Set the mark (space key); see ^X^X and ^Y above XESC\ \. Get the last (or [n]'th) word from previous line XESC\ \? Show possible completions; see below XESC\ < Move to start of history XESC\ > Move to end of history XESC\ b Move backward a word [n] XESC\ d Delete word under cursor [n] XESC\ f Move forward a word [n] XESC\ l Make word lowercase [n] XESC\ u Make word uppercase [n] XESC\ y Yank back last killed text XESC\ v Show library version XESC\ w Make area up to mark yankable XESC\ nn Set repeat count to the number nn XESC\ C Read from environment variable ``_C_'', where C is X\& an uppercase letter X.fi X.RE X.PP XThe X.I editline Xlibrary has a small macro facility. XIf you type the escape key followed by an uppercase letter, X.IR C , Xthen the contents of the environment variable X.I _C_ Xare read in as if you had typed them at the keyboard. XFor example, if the variable X.I _L_ Xcontains the following: X.RS X^A^Kecho '^V^[[H^V^[[2J'^M X.RE XThen typing ``ESC L'' will move to the beginning of the line, kill the Xentire line, enter the echo command needed to clear the terminal (if your Xterminal is like a VT-100), and send the line back to the shell. X.PP XThe X.I editline Xlibrary also does filename completion. XSuppose the root directory has the following files in it: X.RS X.nf X.ta \w'core 'u Xbin vmunix Xcore vmunix.old X.fi X.RE XIf you type ``rm\ /v'' and then the tab key. X.I Editline Xwill then finish off as much of the name as possible by adding ``munix''. XBecause the name is not unique, it will then beep. XIf you type the escape key and a question mark, it will display the Xtwo choices. XIf you then type a period and a tab, the library will finish off the filename Xfor you: X.RS X.nf X.RI "rm /v[TAB]" munix .TAB old X.fi X.RE XThe tab key is shown by ``[TAB]'' and the automatically-entered text Xis shown in italics. X.SH "BUGS AND LIMITATIONS" XCannot handle lines more than 80 columns. X.SH AUTHORS XSimmule R. Turner Xand Rich $alz . XOriginal manual page by DaviD W. Sanderson . END_OF_FILE if test 5281 -ne `wc -c <'editline.3'`; then echo shar: \"'editline.3'\" unpacked with wrong size! fi # end of 'editline.3' fi if test -f 'editline.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'editline.h'\" else echo shar: Extracting \"'editline.h'\" \(1622 characters\) sed "s/^X//" >'editline.h' <<'END_OF_FILE' X/* $Revision: 1.3 $ X** X** Internal header file for editline library. X*/ X#include X#if defined(HAVE_STDLIB) X#include X#include X#endif /* defined(HAVE_STDLIB) */ X#if defined(SYS_UNIX) X#include "unix.h" X#endif /* defined(SYS_UNIX) */ X#if defined(SYS_OS9) X#include "os9.h" X#endif /* defined(SYS_OS9) */ X X#if !defined(SIZE_T) X#define SIZE_T unsigned int X#endif /* !defined(SIZE_T) */ X Xtypedef unsigned char CHAR; X X#if defined(HIDE) X#define STATIC static X#else X#define STATIC /* NULL */ X#endif /* !defined(HIDE) */ X X#if !defined(CONST) X#if defined(__STDC__) X#define CONST const X#else X#define CONST X#endif /* defined(__STDC__) */ X#endif /* !defined(CONST) */ X X X#define MEM_INC 64 X#define SCREEN_INC 256 X X#define DISPOSE(p) free((char *)(p)) X#define NEW(T, c) \ X ((T *)malloc((unsigned int)(sizeof (T) * (c)))) X#define RENEW(p, T, c) \ X (p = (T *)realloc((char *)(p), (unsigned int)(sizeof (T) * (c)))) X#define COPYFROMTO(new, p, len) \ X (void)memcpy((char *)(new), (char *)(p), (int)(len)) X X X/* X** Variables and routines internal to this package. X*/ Xextern int rl_eof; Xextern int rl_erase; Xextern int rl_intr; Xextern int rl_kill; Xextern int rl_quit; Xextern char *rl_complete(); Xextern int rl_list_possib(); Xextern void rl_ttyset(); Xextern void rl_add_slash(); X X#if !defined(HAVE_STDLIB) Xextern char *getenv(); Xextern char *malloc(); Xextern char *realloc(); Xextern char *memcpy(); Xextern char *strcat(); Xextern char *strchr(); Xextern char *strrchr(); Xextern char *strcpy(); Xextern char *strdup(); Xextern int strcmp(); Xextern int strlen(); Xextern int strncmp(); X#endif /* !defined(HAVE_STDLIB) */ END_OF_FILE if test 1622 -ne `wc -c <'editline.h'`; then echo shar: \"'editline.h'\" unpacked with wrong size! fi # end of 'editline.h' fi if test -f 'unix.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'unix.h'\" else echo shar: Extracting \"'unix.h'\" \(432 characters\) sed "s/^X//" >'unix.h' <<'END_OF_FILE' X/* $Revision: 1.1 $ X** X** Editline system header file for Unix. X*/ X X#define CRLF "\r\n" X#define FORWARD STATIC X X#include X#include X X#if defined(USE_DIRENT) X#include Xtypedef struct dirent DIRENTRY; X#else X#include Xtypedef struct direct DIRENTRY; X#endif /* defined(USE_DIRENT) */ X X#if !defined(S_ISDIR) X#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) X#endif /* !defined(S_ISDIR) */ END_OF_FILE if test 432 -ne `wc -c <'unix.h'`; then echo shar: \"'unix.h'\" unpacked with wrong size! fi # end of 'unix.h' fi if test -f 'editline.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'editline.c'\" else echo shar: Extracting \"'editline.c'\" \(22788 characters\) sed "s/^X//" >'editline.c' <<'END_OF_FILE' X/* $Revision: 1.4 $ X** X** Main editing routines for editline library. X*/ X#include "editline.h" X#include X#include X X/* X** Manifest constants. X*/ X#define SCREEN_WIDTH 80 X#define SCREEN_ROWS 24 X#define NO_ARG (-1) X#define DEL 127 X#define CTL(x) ((x) & 0x1F) X#define ISCTL(x) ((x) && (x) < ' ') X#define UNCTL(x) ((x) + 64) X#define META(x) ((x) | 0x80) X#define ISMETA(x) ((x) & 0x80) X#define UNMETA(x) ((x) & 0x7F) X#if !defined(HIST_SIZE) X#define HIST_SIZE 20 X#endif /* !defined(HIST_SIZE) */ X X/* X** Command status codes. X*/ Xtypedef enum _STATUS { X CSdone, CSeof, CSmove, CSdispatch, CSstay, X} STATUS; X X/* X** The type of case-changing to perform. X*/ Xtypedef enum _CASE { X TOupper, TOlower X} CASE; X X/* X** Key to command mapping. X*/ Xtypedef struct _KEYMAP { X CHAR Key; X STATUS (*Function)(); X} KEYMAP; X X/* X** Command history structure. X*/ Xtypedef struct _HISTORY { X int Size; X int Pos; X CHAR *Lines[HIST_SIZE]; X} HISTORY; X X/* X** Globals. X*/ Xint rl_eof; Xint rl_erase; Xint rl_intr; Xint rl_kill; Xint rl_quit; X XSTATIC CHAR NIL[] = ""; XSTATIC CONST CHAR *Input = NIL; XSTATIC CHAR *Line; XSTATIC CONST char *Prompt; XSTATIC CHAR *Yanked; XSTATIC char *Screen; XSTATIC char NEWLINE[]= CRLF; XSTATIC HISTORY H; XSTATIC int Repeat; XSTATIC int End; XSTATIC int Mark; XSTATIC int OldPoint; XSTATIC int Point; XSTATIC int PushBack; XSTATIC int Pushed; XSTATIC int Signal; XFORWARD KEYMAP Map[33]; XFORWARD KEYMAP MetaMap[16]; XSTATIC SIZE_T Length; XSTATIC SIZE_T ScreenCount; XSTATIC SIZE_T ScreenSize; XSTATIC char *backspace; XSTATIC int TTYwidth; XSTATIC int TTYrows; X X/* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */ Xint rl_meta_chars = 1; X X/* X** Declarations. X*/ XSTATIC CHAR *editinput(); Xextern int read(); Xextern int write(); X#if defined(USE_TERMCAP) Xextern char *getenv(); Xextern char *tgetstr(); Xextern int tgetent(); X#endif /* defined(USE_TERMCAP) */ X X/* X** TTY input/output functions. X*/ X XSTATIC void XTTYflush() X{ X if (ScreenCount) { X (void)write(1, Screen, ScreenCount); X ScreenCount = 0; X } X} X XSTATIC void XTTYput(c) X CHAR c; X{ X Screen[ScreenCount] = c; X if (++ScreenCount >= ScreenSize - 1) { X ScreenSize += SCREEN_INC; X RENEW(Screen, char, ScreenSize); X } X} X XSTATIC void XTTYputs(p) X CHAR *p; X{ X while (*p) X TTYput(*p++); X} X XSTATIC void XTTYshow(c) X CHAR c; X{ X if (c == DEL) { X TTYput('^'); X TTYput('?'); X } X else if (ISCTL(c)) { X TTYput('^'); X TTYput(UNCTL(c)); X } X else if (rl_meta_chars && ISMETA(c)) { X TTYput('M'); X TTYput('-'); X TTYput(UNMETA(c)); X } X else X TTYput(c); X} X XSTATIC void XTTYstring(p) X CHAR *p; X{ X while (*p) X TTYshow(*p++); X} X XSTATIC unsigned int XTTYget() X{ X CHAR c; X X TTYflush(); X if (Pushed) { X Pushed = 0; X return PushBack; X } X if (*Input) X return *Input++; X return read(0, &c, (SIZE_T)1) == 1 ? c : EOF; X} X X#define TTYback() (backspace ? TTYputs((CHAR *)backspace) : TTYput('\b')) X XSTATIC void XTTYbackn(n) X int n; X{ X while (--n >= 0) X TTYback(); X} X XSTATIC void XTTYinfo() X{ X static int init; X#if defined(USE_TERMCAP) X char *term; X char buff[2048]; X char *bp; X#endif /* defined(USE_TERMCAP) */ X#if defined(TIOCGWINSZ) X struct winsize W; X#endif /* defined(TIOCGWINSZ) */ X X if (init) { X#if defined(TIOCGWINSZ) X /* Perhaps we got resized. */ X if (ioctl(0, TIOCGWINSZ, &W) >= 0 X && W.ws_col > 0 && W.ws_row > 0) { X TTYwidth = (int)W.ws_col; X TTYrows = (int)W.ws_row; X } X#endif /* defined(TIOCGWINSZ) */ X return; X } X init++; X X TTYwidth = TTYrows = 0; X#if defined(USE_TERMCAP) X bp = &buff[0]; X if ((term = getenv("TERM")) == NULL) X term = "dumb"; X if (tgetent(buff, term) < 0) { X TTYwidth = SCREEN_WIDTH; X TTYrows = SCREEN_ROWS; X return; X } X backspace = strdup(tgetstr("le", &bp)); X TTYwidth = tgetnum("co"); X TTYrows = tgetnum("li"); X#endif /* defined(USE_TERMCAP) */ X X#if defined(TIOCGWINSZ) X if (ioctl(0, TIOCGWINSZ, &W) >= 0) { X TTYwidth = (int)W.ws_col; X TTYrows = (int)W.ws_row; X } X#endif /* defined(TIOCGWINSZ) */ X X if (TTYwidth <= 0 || TTYrows <= 0) { X TTYwidth = SCREEN_WIDTH; X TTYrows = SCREEN_ROWS; X } X} X X X/* X** Print an array of words in columns. X*/ XSTATIC void Xcolumns(ac, av) X int ac; X CHAR **av; X{ X CHAR *p; X int i; X int j; X int k; X int len; X int skip; X int longest; X int cols; X X /* Find longest name, determine column count from that. */ X for (longest = 0, i = 0; i < ac; i++) X if ((j = strlen((char *)av[i])) > longest) X longest = j; X cols = TTYwidth / (longest + 3); X X TTYputs((CHAR *)NEWLINE); X for (skip = ac / cols + 1, i = 0; i < skip; i++) { X for (j = i; j < ac; j += skip) { X for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++) X TTYput(*p); X if (j + skip < ac) X while (++len < longest + 3) X TTYput(' '); X } X TTYputs((CHAR *)NEWLINE); X } X} X XSTATIC void Xreposition() X{ X int i; X CHAR *p; X X TTYput('\r'); X TTYputs((CHAR *)Prompt); X for (i = Point, p = Line; --i >= 0; p++) X TTYshow(*p); X} X XSTATIC void Xleft(Change) X STATUS Change; X{ X TTYback(); X if (Point) { X if (ISCTL(Line[Point - 1])) X TTYback(); X else if (rl_meta_chars && ISMETA(Line[Point - 1])) { X TTYback(); X TTYback(); X } X } X if (Change == CSmove) X Point--; X} X XSTATIC void Xright(Change) X STATUS Change; X{ X TTYshow(Line[Point]); X if (Change == CSmove) X Point++; X} X XSTATIC STATUS Xring_bell() X{ X TTYput('\07'); X TTYflush(); X return CSstay; X} X XSTATIC STATUS Xdo_macro(c) X unsigned int c; X{ X CHAR name[4]; X X name[0] = '_'; X name[1] = c; X name[2] = '_'; X name[3] = '\0'; X X if ((Input = (CHAR *)getenv((char *)name)) == NULL) { X Input = NIL; X return ring_bell(); X } X return CSstay; X} X XSTATIC STATUS Xdo_forward(move) X STATUS move; X{ X int i; X CHAR *p; X X i = 0; X do { X p = &Line[Point]; X for ( ; Point < End && (*p == ' ' || !isalnum(*p)); Point++, p++) X if (move == CSmove) X right(CSstay); X X for (; Point < End && isalnum(*p); Point++, p++) X if (move == CSmove) X right(CSstay); X X if (Point == End) X break; X } while (++i < Repeat); X X return CSstay; X} X XSTATIC STATUS Xdo_case(type) X CASE type; X{ X int i; X int end; X int count; X CHAR *p; X X (void)do_forward(CSstay); X if (OldPoint != Point) { X if ((count = Point - OldPoint) < 0) X count = -count; X Point = OldPoint; X if ((end = Point + count) > End) X end = End; X for (i = Point, p = &Line[i]; i < end; i++, p++) { X if (type == TOupper) { X if (islower(*p)) X *p = toupper(*p); X } X else if (isupper(*p)) X *p = tolower(*p); X right(CSmove); X } X } X return CSstay; X} X XSTATIC STATUS Xcase_down_word() X{ X return do_case(TOlower); X} X XSTATIC STATUS Xcase_up_word() X{ X return do_case(TOupper); X} X XSTATIC void Xceol() X{ X int extras; X int i; X CHAR *p; X X for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) { X TTYput(' '); X if (ISCTL(*p)) { X TTYput(' '); X extras++; X } X else if (rl_meta_chars && ISMETA(*p)) { X TTYput(' '); X TTYput(' '); X extras += 2; X } X } X X for (i += extras; i > Point; i--) X TTYback(); X} X XSTATIC void Xclear_line() X{ X Point = -strlen(Prompt); X TTYput('\r'); X ceol(); X Point = 0; X End = 0; X Line[0] = '\0'; X} X XSTATIC STATUS Xinsert_string(p) X CHAR *p; X{ X SIZE_T len; X int i; X CHAR *new; X CHAR *q; X X len = strlen((char *)p); X if (End + len >= Length) { X if ((new = NEW(CHAR, Length + len + MEM_INC)) == NULL) X return CSstay; X if (Length) { X COPYFROMTO(new, Line, Length); X DISPOSE(Line); X } X Line = new; X Length += len + MEM_INC; X } X X for (q = &Line[Point], i = End - Point; --i >= 0; ) X q[len + i] = q[i]; X COPYFROMTO(&Line[Point], p, len); X End += len; X Line[End] = '\0'; X TTYstring(&Line[Point]); X Point += len; X X return Point == End ? CSstay : CSmove; X} X XSTATIC STATUS Xredisplay() X{ X TTYputs((CHAR *)NEWLINE); X TTYputs((CHAR *)Prompt); X TTYstring(Line); X return CSmove; X} X X XSTATIC CHAR * Xnext_hist() X{ X return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos]; X} X XSTATIC CHAR * Xprev_hist() X{ X return H.Pos == 0 ? NULL : H.Lines[--H.Pos]; X} X XSTATIC STATUS Xdo_insert_hist(p) X CHAR *p; X{ X if (p == NULL) X return ring_bell(); X Point = 0; X reposition(); X ceol(); X End = 0; X return insert_string(p); X} X XSTATIC STATUS Xdo_hist(move) X CHAR *(*move)(); X{ X CHAR *p; X int i; X X i = 0; X do { X if ((p = (*move)()) == NULL) X return ring_bell(); X } while (++i < Repeat); X return do_insert_hist(p); X} X XSTATIC STATUS Xh_next() X{ X return do_hist(next_hist); X} X XSTATIC STATUS Xh_prev() X{ X return do_hist(prev_hist); X} X XSTATIC STATUS Xh_first() X{ X return do_insert_hist(H.Lines[H.Pos = 0]); X} X XSTATIC STATUS Xh_last() X{ X return do_insert_hist(H.Lines[H.Pos = H.Size - 1]); X} X X/* X** Return zero if pat appears as a substring in text. X*/ XSTATIC int Xsubstrcmp(text, pat, len) X char *text; X char *pat; X int len; X{ X CHAR c; X X if ((c = *pat) == '\0') X return *text == '\0'; X for ( ; *text; text++) X if (*text == c && strncmp(text, pat, len) == 0) X return 0; X return 1; X} X XSTATIC CHAR * Xsearch_hist(search, move) X CHAR *search; X CHAR *(*move)(); X{ X static CHAR *old_search; X int len; X int pos; X int (*match)(); X char *pat; X X /* Save or get remembered search pattern. */ X if (search && *search) { X if (old_search) X DISPOSE(old_search); X old_search = (CHAR *)strdup((char *)search); X } X else { X if (old_search == NULL || *old_search == '\0') X return NULL; X search = old_search; X } X X /* Set up pattern-finder. */ X if (*search == '^') { X match = strncmp; X pat = (char *)(search + 1); X } X else { X match = substrcmp; X pat = (char *)search; X } X len = strlen(pat); X X for (pos = H.Pos; (*move)() != NULL; ) X if ((*match)((char *)H.Lines[H.Pos], pat, len) == 0) X return H.Lines[H.Pos]; X H.Pos = pos; X return NULL; X} X XSTATIC STATUS Xh_search() X{ X static int Searching; X CONST char *old_prompt; X CHAR *(*move)(); X CHAR *p; X X if (Searching) X return ring_bell(); X Searching = 1; X X clear_line(); X old_prompt = Prompt; X Prompt = "Search: "; X TTYputs((CHAR *)Prompt); X move = Repeat == NO_ARG ? prev_hist : next_hist; X p = editinput(); X Prompt = old_prompt; X Searching = 0; X clear_line(); X TTYputs((CHAR *)Prompt); X if (p == NULL && Signal > 0) { X Signal = 0; X return redisplay(); X } X p = search_hist(p, move); X return do_insert_hist(p); X} X XSTATIC STATUS Xfd_char() X{ X int i; X X i = 0; X do { X if (Point >= End) X break; X right(CSmove); X } while (++i < Repeat); X return CSstay; X} X XSTATIC void Xsave_yank(begin, i) X int begin; X int i; X{ X if (Yanked) { X DISPOSE(Yanked); X Yanked = NULL; X } X X if (i < 1) X return; X X if ((Yanked = NEW(CHAR, (SIZE_T)i + 1)) != NULL) { X COPYFROMTO(Yanked, &Line[begin], i); X Yanked[i] = '\0'; X } X} X XSTATIC STATUS Xdelete_string(count) X int count; X{ X int i; X CHAR *p; X X if (count <= 0 || End == Point) X return ring_bell(); X X if (count == 1 && Point == End - 1) { X /* Optimize common case of delete at end of line. */ X End--; X p = &Line[Point]; X i = 1; X TTYput(' '); X if (ISCTL(*p)) { X i = 2; X TTYput(' '); X } X else if (rl_meta_chars && ISMETA(*p)) { X i = 3; X TTYput(' '); X TTYput(' '); X } X TTYbackn(i); X *p = '\0'; X return CSmove; X } X if (Point + count > End && (count = End - Point) <= 0) X return CSstay; X X if (count > 1) X save_yank(Point, count); X X for (p = &Line[Point], i = End - (Point + count) + 1; --i >= 0; p++) X p[0] = p[count]; X ceol(); X End -= count; X TTYstring(&Line[Point]); X return CSmove; X} X XSTATIC STATUS Xbk_char() X{ X int i; X X i = 0; X do { X if (Point == 0) X break; X left(CSmove); X } while (++i < Repeat); X X return CSstay; X} X XSTATIC STATUS Xbk_del_char() X{ X int i; X X i = 0; X do { X if (Point == 0) X break; X left(CSmove); X } while (++i < Repeat); X X return delete_string(i); X} X XSTATIC STATUS Xkill_line() X{ X int i; X X if (Repeat != NO_ARG) { X if (Repeat < Point) { X i = Point; X Point = Repeat; X reposition(); X (void)delete_string(i - Point); X } X else if (Repeat > Point) { X right(CSmove); X (void)delete_string(Repeat - Point - 1); X } X return CSmove; X } X X save_yank(Point, End - Point); X Line[Point] = '\0'; X ceol(); X End = Point; X return CSstay; X} X XSTATIC STATUS Xinsert_char(c) X int c; X{ X STATUS s; X CHAR buff[2]; X CHAR *p; X CHAR *q; X int i; X X if (Repeat == NO_ARG || Repeat < 2) { X buff[0] = c; X buff[1] = '\0'; X return insert_string(buff); X } X X if ((p = NEW(CHAR, Repeat + 1)) == NULL) X return CSstay; X for (i = Repeat, q = p; --i >= 0; ) X *q++ = c; X *q = '\0'; X Repeat = 0; X s = insert_string(p); X DISPOSE(p); X return s; X} X XSTATIC STATUS Xmeta() X{ X unsigned int c; X KEYMAP *kp; X X if ((c = TTYget()) == EOF) X return CSeof; X#if defined(ANSI_ARROWS) X /* Also include VT-100 arrows. */ X if (c == '[' || c == 'O') X switch (c = TTYget()) { X default: return ring_bell(); X case EOF: return CSeof; X case 'A': return h_prev(); X case 'B': return h_next(); X case 'C': return fd_char(); X case 'D': return bk_char(); X } X#endif /* defined(ANSI_ARROWS) */ X X if (isdigit(c)) { X for (Repeat = c - '0'; (c = TTYget()) != EOF && isdigit(c); ) X Repeat = Repeat * 10 + c - '0'; X Pushed = 1; X PushBack = c; X return CSstay; X } X X if (isupper(c)) X return do_macro(c); X for (OldPoint = Point, kp = MetaMap; kp->Function; kp++) X if (kp->Key == c) X return (*kp->Function)(); X X return ring_bell(); X} X XSTATIC STATUS Xemacs(c) X unsigned int c; X{ X STATUS s; X KEYMAP *kp; X X if (ISMETA(c)) { X Pushed = 1; X PushBack = UNMETA(c); X return meta(); X } X for (kp = Map; kp->Function; kp++) X if (kp->Key == c) X break; X s = kp->Function ? (*kp->Function)() : insert_char((int)c); X if (!Pushed) X /* No pushback means no repeat count; hacky, but true. */ X Repeat = NO_ARG; X return s; X} X XSTATIC STATUS XTTYspecial(c) X unsigned int c; X{ X if (ISMETA(c)) X return CSdispatch; X X if (c == rl_erase || c == DEL) X return bk_del_char(); X if (c == rl_kill) { X if (Point != 0) { X Point = 0; X reposition(); X } X Repeat = NO_ARG; X return kill_line(); X } X if (c == rl_eof && Point == 0 && End == 0) X return CSeof; X if (c == rl_intr) { X Signal = SIGINT; X return CSeof; X } X if (c == rl_quit) { X Signal = SIGQUIT; X return CSeof; X } X X return CSdispatch; X} X XSTATIC CHAR * Xeditinput() X{ X unsigned int c; X X Repeat = NO_ARG; X OldPoint = Point = Mark = End = 0; X Line[0] = '\0'; X X Signal = -1; X while ((c = TTYget()) != EOF) X switch (TTYspecial(c)) { X case CSdone: X return Line; X case CSeof: X return NULL; X case CSmove: X reposition(); X break; X case CSdispatch: X switch (emacs(c)) { X case CSdone: X return Line; X case CSeof: X return NULL; X case CSmove: X reposition(); X break; X case CSdispatch: X case CSstay: X break; X } X break; X case CSstay: X break; X } X return NULL; X} X XSTATIC void Xhist_add(p) X CHAR *p; X{ X int i; X X if ((p = (CHAR *)strdup((char *)p)) == NULL) X return; X if (H.Size < HIST_SIZE) X H.Lines[H.Size++] = p; X else { X DISPOSE(H.Lines[0]); X for (i = 0; i < HIST_SIZE - 1; i++) X H.Lines[i] = H.Lines[i + 1]; X H.Lines[i] = p; X } X H.Pos = H.Size - 1; X} X X/* X** For compatibility with FSF readline. X*/ X/* ARGSUSED0 */ Xvoid Xrl_reset_terminal(p) X char *p; X{ X} X Xvoid Xrl_initialize() X{ X} X Xchar * Xreadline(prompt) X CONST char *prompt; X{ X CHAR *line; X int s; X X if (Line == NULL) { X Length = MEM_INC; X if ((Line = NEW(CHAR, Length)) == NULL) X return NULL; X } X X TTYinfo(); X rl_ttyset(0); X hist_add(NIL); X ScreenSize = SCREEN_INC; X Screen = NEW(char, ScreenSize); X Prompt = prompt ? prompt : (char *)NIL; X TTYputs((CHAR *)Prompt); X if ((line = editinput()) != NULL) { X line = (CHAR *)strdup((char *)line); X TTYputs((CHAR *)NEWLINE); X TTYflush(); X } X rl_ttyset(1); X DISPOSE(Screen); X DISPOSE(H.Lines[--H.Size]); X if (Signal > 0) { X s = Signal; X Signal = 0; X (void)kill(getpid(), s); X } X return (char *)line; X} X Xvoid Xadd_history(p) X char *p; X{ X if (p == NULL || *p == '\0') X return; X X#if defined(UNIQUE_HISTORY) X if (H.Pos && strcmp(p, H.Lines[H.Pos - 1]) == 0) X return; X#endif /* defined(UNIQUE_HISTORY) */ X hist_add((CHAR *)p); X} X X XSTATIC STATUS Xbeg_line() X{ X if (Point) { X Point = 0; X return CSmove; X } X return CSstay; X} X XSTATIC STATUS Xdel_char() X{ X return delete_string(Repeat == NO_ARG ? 1 : Repeat); X} X XSTATIC STATUS Xend_line() X{ X if (Point != End) { X Point = End; X return CSmove; X } X return CSstay; X} X X/* X** Move back to the beginning of the current word and return an X** allocated copy of it. X*/ XSTATIC CHAR * Xfind_word() X{ X static char SEPS[] = "#;&|^$=`'{}()<>\n\t "; X CHAR *p; X CHAR *new; X SIZE_T len; X X for (p = &Line[Point]; p > Line && strchr(SEPS, (char)p[-1]) == NULL; p--) X continue; X len = Point - (p - Line) + 1; X if ((new = NEW(CHAR, len)) == NULL) X return NULL; X COPYFROMTO(new, p, len); X new[len - 1] = '\0'; X return new; X} X XSTATIC STATUS Xc_complete() X{ X CHAR *p; X CHAR *word; X int unique; X STATUS s; X X word = find_word(); X p = (CHAR *)rl_complete((char *)word, &unique); X if (word) X DISPOSE(word); X if (p && *p) { X s = insert_string(p); X if (!unique) X (void)ring_bell(); X DISPOSE(p); X return s; X } X return ring_bell(); X} X XSTATIC STATUS Xc_possible() X{ X CHAR **av; X CHAR *word; X int ac; X X word = find_word(); X ac = rl_list_possib((char *)word, (char ***)&av); X if (word) X DISPOSE(word); X if (ac) { X columns(ac, av); X while (--ac >= 0) X DISPOSE(av[ac]); X DISPOSE(av); X return CSmove; X } X return ring_bell(); X} X XSTATIC STATUS Xaccept_line() X{ X Line[End] = '\0'; X return CSdone; X} X XSTATIC STATUS Xtranspose() X{ X CHAR c; X X if (Point) { X if (Point == End) X left(CSmove); X c = Line[Point - 1]; X left(CSstay); X Line[Point - 1] = Line[Point]; X TTYshow(Line[Point - 1]); X Line[Point++] = c; X TTYshow(c); X } X return CSstay; X} X XSTATIC STATUS Xquote() X{ X unsigned int c; X X return (c = TTYget()) == EOF ? CSeof : insert_char((int)c); X} X XSTATIC STATUS Xwipe() X{ X int i; X X if (Mark > End) X return ring_bell(); X X if (Point > Mark) { X i = Point; X Point = Mark; X Mark = i; X reposition(); X } X X return delete_string(Mark - Point); X} X XSTATIC STATUS Xmk_set() X{ X Mark = Point; X return CSstay; X} X XSTATIC STATUS Xexchange() X{ X unsigned int c; X X if ((c = TTYget()) != CTL('X')) X return c == EOF ? CSeof : ring_bell(); X X if ((c = Mark) <= End) { X Mark = Point; X Point = c; X return CSmove; X } X return CSstay; X} X XSTATIC STATUS Xyank() X{ X if (Yanked && *Yanked) X return insert_string(Yanked); X return CSstay; X} X XSTATIC STATUS Xcopy_region() X{ X if (Mark > End) X return ring_bell(); X X if (Point > Mark) X save_yank(Mark, Point - Mark); X else X save_yank(Point, Mark - Point); X X return CSstay; X} X XSTATIC STATUS Xmove_to_char() X{ X unsigned int c; X int i; X CHAR *p; X X if ((c = TTYget()) == EOF) X return CSeof; X for (i = Point + 1, p = &Line[i]; i < End; i++, p++) X if (*p == c) { X Point = i; X return CSmove; X } X return CSstay; X} X XSTATIC STATUS Xfd_word() X{ X return do_forward(CSmove); X} X XSTATIC STATUS Xfd_kill_word() X{ X int i; X X (void)do_forward(CSstay); X if (OldPoint != Point) { X i = Point - OldPoint; X Point = OldPoint; X return delete_string(i); X } X return CSstay; X} X XSTATIC STATUS Xbk_word() X{ X int i; X CHAR *p; X X i = 0; X do { X for (p = &Line[Point]; p > Line && !isalnum(p[-1]); p--) X left(CSmove); X X for (; p > Line && p[-1] != ' ' && isalnum(p[-1]); p--) X left(CSmove); X X if (Point == 0) X break; X } while (++i < Repeat); X X return CSstay; X} X XSTATIC STATUS Xbk_kill_word() X{ X (void)bk_word(); X if (OldPoint != Point) X return delete_string(OldPoint - Point); X return CSstay; X} X XSTATIC int Xargify(line, avp) X CHAR *line; X CHAR ***avp; X{ X CHAR *c; X CHAR **p; X CHAR **new; X int ac; X int i; X X i = MEM_INC; X if ((*avp = p = NEW(CHAR*, i))== NULL) X return 0; X X for (c = line; isspace(*c); c++) X continue; X if (*c == '\n' || *c == '\0') X return 0; X X for (ac = 0, p[ac++] = c; *c && *c != '\n'; ) { X if (isspace(*c)) { X *c++ = '\0'; X if (*c && *c != '\n') { X if (ac + 1 == i) { X new = NEW(CHAR*, i + MEM_INC); X if (new == NULL) { X p[ac] = NULL; X return ac; X } X COPYFROMTO(new, p, i * sizeof (char **)); X i += MEM_INC; X DISPOSE(p); X *avp = p = new; X } X p[ac++] = c; X } X } X else X c++; X } X *c = '\0'; X p[ac] = NULL; X return ac; X} X XSTATIC STATUS Xlast_argument() X{ X CHAR **av; X CHAR *p; X STATUS s; X int ac; X X if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL) X return ring_bell(); X X if ((p = (CHAR *)strdup((char *)p)) == NULL) X return CSstay; X ac = argify(p, &av); X X if (Repeat != NO_ARG) X s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell(); X else X s = ac ? insert_string(av[ac - 1]) : CSstay; X X if (ac) X DISPOSE(av); X DISPOSE(p); X return s; X} X XSTATIC KEYMAP Map[33] = { X { CTL('@'), ring_bell }, X { CTL('A'), beg_line }, X { CTL('B'), bk_char }, X { CTL('D'), del_char }, X { CTL('E'), end_line }, X { CTL('F'), fd_char }, X { CTL('G'), ring_bell }, X { CTL('H'), bk_del_char }, X { CTL('I'), c_complete }, X { CTL('J'), accept_line }, X { CTL('K'), kill_line }, X { CTL('L'), redisplay }, X { CTL('M'), accept_line }, X { CTL('N'), h_next }, X { CTL('O'), ring_bell }, X { CTL('P'), h_prev }, X { CTL('Q'), ring_bell }, X { CTL('R'), h_search }, X { CTL('S'), ring_bell }, X { CTL('T'), transpose }, X { CTL('U'), ring_bell }, X { CTL('V'), quote }, X { CTL('W'), wipe }, X { CTL('X'), exchange }, X { CTL('Y'), yank }, X { CTL('Z'), ring_bell }, X { CTL('['), meta }, X { CTL(']'), move_to_char }, X { CTL('^'), ring_bell }, X { CTL('_'), ring_bell }, X { 0, NULL } X}; X XSTATIC KEYMAP MetaMap[16]= { X { CTL('H'), bk_kill_word }, X { DEL, bk_kill_word }, X { ' ', mk_set }, X { '.', last_argument }, X { '<', h_first }, X { '>', h_last }, X { '?', c_possible }, X { 'b', bk_word }, X { 'd', fd_kill_word }, X { 'f', fd_word }, X { 'l', case_down_word }, X { 'u', case_up_word }, X { 'y', yank }, X { 'w', copy_region }, X { 0, NULL } X}; END_OF_FILE if test 22788 -ne `wc -c <'editline.c'`; then echo shar: \"'editline.c'\" unpacked with wrong size! fi # end of 'editline.c' fi if test -f 'complete.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'complete.c'\" else echo shar: Extracting \"'complete.c'\" \(4113 characters\) sed "s/^X//" >'complete.c' <<'END_OF_FILE' X/* $Revision: 1.3 $ X** X** History and file completion functions for editline library. X*/ X#include "editline.h" X X X#if defined(NEED_STRDUP) X/* X** Return an allocated copy of a string. X*/ Xchar * Xstrdup(p) X char *p; X{ X char *new; X X if ((new = NEW(char, strlen(p) + 1)) != NULL) X (void)strcpy(new, p); X return new; X} X#endif /* defined(NEED_STRDUP) */ X X/* X** strcmp-like sorting predicate for qsort. X*/ XSTATIC int Xcompare(p1, p2) X CONST void *p1; X CONST void *p2; X{ X CONST char **v1; X CONST char **v2; X X v1 = (CONST char **)p1; X v2 = (CONST char **)p2; X return strcmp(*v1, *v2); X} X X/* X** Fill in *avp with an array of names that match file, up to its length. X** Ignore . and .. . X*/ XSTATIC int XFindMatches(dir, file, avp) X char *dir; X char *file; X char ***avp; X{ X char **av; X char **new; X char *p; X DIR *dp; X DIRENTRY *ep; X SIZE_T ac; X SIZE_T len; X X if ((dp = opendir(dir)) == NULL) X return 0; X X av = NULL; X ac = 0; X len = strlen(file); X while ((ep = readdir(dp)) != NULL) { X p = ep->d_name; X if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0'))) X continue; X if (len && strncmp(p, file, len) != 0) X continue; X X if ((ac % MEM_INC) == 0) { X if ((new = NEW(char*, ac + MEM_INC)) == NULL) X break; X if (ac) { X COPYFROMTO(new, av, ac * sizeof (char **)); X DISPOSE(av); X } X *avp = av = new; X } X X if ((av[ac] = strdup(p)) == NULL) { X if (ac == 0) X DISPOSE(av); X break; X } X ac++; X } X X /* Clean up and return. */ X (void)closedir(dp); X if (ac) X qsort(av, ac, sizeof (char **), compare); X return ac; X} X X/* X** Split a pathname into allocated directory and trailing filename parts. X*/ XSTATIC int XSplitPath(path, dirpart, filepart) X char *path; X char **dirpart; X char **filepart; X{ X static char DOT[] = "."; X char *dpart; X char *fpart; X X if ((fpart = strrchr(path, '/')) == NULL) { X if ((dpart = strdup(DOT)) == NULL) X return -1; X if ((fpart = strdup(path)) == NULL) { X DISPOSE(dpart); X return -1; X } X } X else { X if ((dpart = strdup(path)) == NULL) X return -1; X dpart[fpart - path + 1] = '\0'; X if ((fpart = strdup(++fpart)) == NULL) { X DISPOSE(dpart); X return -1; X } X } X *dirpart = dpart; X *filepart = fpart; X return 0; X} X X/* X** Attempt to complete the pathname, returning an allocated copy. X** Fill in *unique if we completed it, or set it to 0 if ambiguous. X*/ Xchar * Xrl_complete(pathname, unique) X char *pathname; X int *unique; X{ X char **av; X char *dir; X char *file; X char *new; X char *p; X SIZE_T ac; X SIZE_T end; X SIZE_T i; X SIZE_T j; X SIZE_T len; X X if (SplitPath(pathname, &dir, &file) < 0) X return NULL; X if ((ac = FindMatches(dir, file, &av)) == 0) { X DISPOSE(dir); X DISPOSE(file); X return NULL; X } X X p = NULL; X len = strlen(file); X if (ac == 1) { X /* Exactly one match -- finish it off. */ X *unique = 1; X j = strlen(av[0]) - len + 2; X if ((p = NEW(char, j + 1)) != NULL) { X COPYFROMTO(p, av[0] + len, j); X if ((new = NEW(char, strlen(dir) + strlen(av[0]) + 2)) != NULL) { X (void)strcpy(new, dir); X (void)strcat(new, "/"); X (void)strcat(new, av[0]); X rl_add_slash(new, p); X DISPOSE(new); X } X } X } X else { X *unique = 0; X if (len) { X /* Find largest matching substring. */ X for (i = len, end = strlen(av[0]); i < end; i++) X for (j = 1; j < ac; j++) X if (av[0][i] != av[j][i]) X goto breakout; X breakout: X if (i > len) { X j = i - len + 1; X if ((p = NEW(char, j)) != NULL) { X COPYFROMTO(p, av[0] + len, j); X p[j - 1] = '\0'; X } X } X } X } X X /* Clean up and return. */ X DISPOSE(dir); X DISPOSE(file); X for (i = 0; i < ac; i++) X DISPOSE(av[i]); X DISPOSE(av); X return p; X} X X/* X** Return all possible completions. X*/ Xint Xrl_list_possib(pathname, avp) X char *pathname; X char ***avp; X{ X char *dir; X char *file; X int ac; X X if (SplitPath(pathname, &dir, &file) < 0) X return 0; X ac = FindMatches(dir, file, avp); X DISPOSE(dir); X DISPOSE(file); X return ac; X} END_OF_FILE if test 4113 -ne `wc -c <'complete.c'`; then echo shar: \"'complete.c'\" unpacked with wrong size! fi # end of 'complete.c' fi if test -f 'sysunix.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sysunix.c'\" else echo shar: Extracting \"'sysunix.c'\" \(1798 characters\) sed "s/^X//" >'sysunix.c' <<'END_OF_FILE' X/* $Revision: 1.1 $ X** X** Unix system-dependant routines for editline library. X*/ X#include "editline.h" X X#if defined(HAVE_TCGETATTR) X#include X Xvoid Xrl_ttyset(Reset) X int Reset; X{ X static struct termios old; X struct termios new; X X if (Reset == 0) { X (void)tcgetattr(0, &old); X rl_erase = old.c_cc[VERASE]; X rl_kill = old.c_cc[VKILL]; X rl_eof = old.c_cc[VEOF]; X rl_intr = old.c_cc[VINTR]; X rl_quit = old.c_cc[VQUIT]; X X new = old; X new.c_cc[VINTR] = -1; X new.c_cc[VQUIT] = -1; X new.c_lflag &= ~(ECHO | ICANON); X new.c_iflag &= ~(ISTRIP | INPCK); X new.c_cc[VMIN] = 1; X new.c_cc[VTIME] = 0; X (void)tcsetattr(0, TCSANOW, &new); X } X else X (void)tcsetattr(0, TCSANOW, &old); X} X X#else X#include X Xvoid Xrl_ttyset(Reset) X int Reset; X{ X static struct sgttyb old_sgttyb; X static struct tchars old_tchars; X struct sgttyb new_sgttyb; X struct tchars new_tchars; X X if (Reset == 0) { X (void)ioctl(0, TIOCGETP, &old_sgttyb); X rl_erase = old_sgttyb.sg_erase; X rl_kill = old_sgttyb.sg_kill; X X (void)ioctl(0, TIOCGETC, &old_tchars); X rl_eof = old_tchars.t_eofc; X rl_intr = old_tchars.t_intrc; X rl_quit = old_tchars.t_quitc; X X new_sgttyb = old_sgttyb; X new_sgttyb.sg_flags &= ~ECHO; X new_sgttyb.sg_flags |= RAW; X#if defined(PASS8) X new_sgttyb.sg_flags |= PASS8; X#endif /* defined(PASS8) */ X (void)ioctl(0, TIOCSETP, &new_sgttyb); X X new_tchars = old_tchars; X new_tchars.t_intrc = -1; X new_tchars.t_quitc = -1; X (void)ioctl(0, TIOCSETC, &new_tchars); X } X else { X (void)ioctl(0, TIOCSETP, &old_sgttyb); X (void)ioctl(0, TIOCSETC, &old_tchars); X } X} X#endif /* defined(HAVE_TCGETATTR) */ X Xvoid Xrl_add_slash(path, p) X char *path; X char *p; X{ X struct stat Sb; X X if (stat(path, &Sb) >= 0) X (void)strcat(p, S_ISDIR(Sb.st_mode) ? "/" : " "); X} END_OF_FILE if test 1798 -ne `wc -c <'sysunix.c'`; then echo shar: \"'sysunix.c'\" unpacked with wrong size! fi # end of 'sysunix.c' fi if test -f 'testit.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'testit.c'\" else echo shar: Extracting \"'testit.c'\" \(1024 characters\) sed "s/^X//" >'testit.c' <<'END_OF_FILE' X/* $Revision: 1.2 $ X** X** A "micro-shell" to test editline library. X** If given any arguments, commands aren't executed. X*/ X#include X#if defined(HAVE_STDLIB) X#include X#endif /* defined(HAVE_STDLIB) */ X Xextern char *readline(); Xextern void add_history(); X X#if !defined(HAVE_STDLIB) Xextern int chdir(); Xextern int free(); Xextern int strncmp(); Xextern int system(); Xextern void exit(); X#endif /* !defined(HAVE_STDLIB) */ X X X#if defined(NEED_PERROR) Xvoid Xperror(s) X char *s; X{ X extern int errno; X X (voidf)printf(stderr, "%s: error %d\n", s, errno); X} X#endif /* defined(NEED_PERROR) */ X X X/* ARGSUSED1 */ Xint Xmain(ac, av) X int ac; X char *av[]; X{ X char *p; X int doit; X X doit = ac == 1; X while ((p = readline("testit> ")) != NULL) { X (void)printf("\t\t\t|%s|\n", p); X if (doit) X if (strncmp(p, "cd ", 3) == 0) { X if (chdir(&p[3]) < 0) X perror(&p[3]); X } X else if (system(p) != 0) X perror(p); X add_history(p); X free(p); X } X exit(0); X /* NOTREACHED */ X} END_OF_FILE if test 1024 -ne `wc -c <'testit.c'`; then echo shar: \"'testit.c'\" unpacked with wrong size! fi # end of 'testit.c' fi if test -f 'Make.os9' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Make.os9'\" else echo shar: Extracting \"'Make.os9'\" \(348 characters\) sed "s/^X//" >'Make.os9' <<'END_OF_FILE' X## $Revision: 1.2 $ X## X## OS-9 makefile for editline library. X## X X.SUFFIXES: X XRFILES = editline.r complete.r sysos9.r X X%.r: %.c X cc68 -r -Dstrchr=index -Dstrrchr=rindex -DNEED_STRDUP -DSYS_OS9 $*.c X Xtestit: testit.r editline.lib X cc68 -f=testit testit.r -l=editline.lib X X$(RFILES): $(RFILES:%.r=%.c) X Xeditline.lib: $(RFILES) X cat $(RFILES) >$@ END_OF_FILE if test 348 -ne `wc -c <'Make.os9'`; then echo shar: \"'Make.os9'\" unpacked with wrong size! fi # end of 'Make.os9' fi if test -f 'os9.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'os9.h'\" else echo shar: Extracting \"'os9.h'\" \(174 characters\) sed "s/^X//" >'os9.h' <<'END_OF_FILE' X/* $Revision: 1.1 $ X** X** Editline system header file for OS-9 (on 68k). X*/ X X#define CRLF "\r\l" X#define FORWARD extern X X#include Xtypedef struct direct DIRENTRY; END_OF_FILE if test 174 -ne `wc -c <'os9.h'`; then echo shar: \"'os9.h'\" unpacked with wrong size! fi # end of 'os9.h' fi if test -f 'sysos9.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sysos9.c'\" else echo shar: Extracting \"'sysos9.c'\" \(1120 characters\) sed "s/^X//" >'sysos9.c' <<'END_OF_FILE' X/* $Revision: 1.1 $ X** X** OS-9 system-dependant routines for editline library. X*/ X#include "editline.h" X#include X#include X X Xvoid Xrl_ttyset(Reset) X int Reset; X{ X static struct sgbuf old; X struct sgbuf new; X X X if (Reset == 0) { X _gs_opt(0, &old); X _gs_opt(0, &new); X new.sg_backsp = 0; new.sg_delete = 0; new.sg_echo = 0; X new.sg_alf = 0; new.sg_nulls = 0; new.sg_pause = 0; X new.sg_page = 0; new.sg_bspch = 0; new.sg_dlnch = 0; X new.sg_eorch = 0; new.sg_eofch = 0; new.sg_rlnch = 0; X new.sg_dulnch = 0; new.sg_psch = 0; new.sg_kbich = 0; X new.sg_kbach = 0; new.sg_bsech = 0; new.sg_bellch = 0; X new.sg_xon = 0; new.sg_xoff = 0; new.sg_tabcr = 0; X new.sg_tabsiz = 0; X _ss_opt(0, &new); X rl_erase = old.sg_bspch; X rl_kill = old.sg_dlnch; X rl_eof = old.sg_eofch; X rl_intr = old.sg_kbich; X rl_quit = -1; X } X else X _ss_opt(0, &old); X} X Xvoid Xrl_add_slash(path, p) X char *path; X char *p; X{ X (void)strcat(p, access(path, S_IREAD | S_IFDIR) ? " " : "/"); X} END_OF_FILE if test 1120 -ne `wc -c <'sysos9.c'`; then echo shar: \"'sysos9.c'\" unpacked with wrong size! fi # end of 'sysos9.c' fi echo shar: End of archive. exit 0