editline-1.12/0042755000175000017500000000000007104610240011352 5ustar jimjimeditline-1.12/README0100440000175000017500000000426005467752760012251 0ustar jimjim$Revision: 1.11 $ 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. This contains some changes since the posting to comp.sources.misc: - Bugfix for completion on absolute pathnames. - Better handling of M-n versus showing raw 8bit chars. - Better signal handling. - Now supports termios/termio/sgttyb ioctl's. - Add M-m command to toggle how 8bit data is displayed. The following changes, made since the last public release, come from J.G. Vons : - History-searching no longer redraws the line wrong - Added ESC-ESC as synonym for ESC-? - SIGQUIT (normally ^\) now sends a signal, not indicating EOF. - Fixed some typo's and unclear wording in the manpage. - Fixed completion when all entries shared a common prefix. - Fixed some meta-char line-redrawing bugs. Enjoy, Rich $alz Copyright 1992,1993 Simmule Turner and Rich Salz. All rights reserved. This software is not subject to any license of the American Telephone and Telegraph Company or of the Regents of the University of California. Permission is granted to anyone to use this software for any purpose on any computer system, and to alter it and redistribute it freely, subject to the following restrictions: 1. The authors are not responsible for the consequences of use of this software, no matter how awful, even if they arise from flaws in it. 2. The origin of this software must not be misrepresented, either by explicit claim or by omission. Since few users ever read sources, credits must appear in the documentation. 3. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. Since few users ever read sources, credits must appear in the documentation. 4. This notice may not be removed or altered. editline-1.12/MANIFEST0100444000175000017500000000100306341106160012471 0ustar jimjimFile Name Description -------------------------------------------------------- README Release notes and copyright MANIFEST This shipping list Make.os9 OS-9 makefile Makefile Unix makefile complete.c Filename completion routines editline.3 Manual page for editline library editline.c Line-editing routines editline.h Internal library header file os9.h OS-9-specific declarations sysos9.c OS-9-specific routines sysunix.c Unix-specific routines testit.c Test driver unix.h Unix-specific declarations editline-1.12/Make.os90100440000175000017500000000053405445646434012676 0ustar jimjim## $Revision: 1.2 $ ## ## OS-9 makefile for editline library. ## .SUFFIXES: RFILES = editline.r complete.r sysos9.r %.r: %.c cc68 -r -Dstrchr=index -Dstrrchr=rindex -DNEED_STRDUP -DSYS_OS9 $*.c testit: testit.r editline.lib cc68 -f=testit testit.r -l=editline.lib $(RFILES): $(RFILES:%.r=%.c) editline.lib: $(RFILES) cat $(RFILES) >$@ editline-1.12/Makefile0100640000175000017500000000364006444261214013015 0ustar jimjim## $Revision: 1.10 $ ## ## Unix makefile for editline library. ## ## Set your options: ## -DANSI_ARROWS ANSI arrows keys work like emacs. ## -DHAVE_STDLIB Have . ## -DHAVE_TCGETATTR Have tcgetattr(), tcsetattr(). ## -DHAVE_TERMIO Have "struct termio" and ## (If neither of above two, we use and BSD ioctl's) ## -DHIDE Make static functions static (non debug). ## -DHIST_SIZE=n History size. ## -DNEED_STRDUP Don't have strdup(). ## -DUNIQUE_HISTORY Don't save command if same as last one. ## -DUSE_DIRENT Use , not ? ## -DUSE_TERMCAP Use the termcap library for terminal size ## see LDFLAGS, below, if you set this. ## -DNEED_PERROR Don't have perror() (used in testit) ## -DDO_SIGTSTP Send SIGTSTP on "suspend" key DEFS = -DANSI_ARROWS -DHAVE_STDLIB -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX -DNEED_STRDUP ## Set your C compiler: WARN = -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings \ -Wunused -Wcomment -Wswitch CC = gcc -ansi $(WARN) #CFLAGS = $(DEFS) -O -g #CC = gcc CFLAGS = $(DEFS) -g ## If you have -DUSE_TERMCAP, set this as appropriate: #LDFLAGS = -ltermlib #LDFLAGS = -ltermcap ## Set ranlib as appropriate: RANLIB = ranlib #RANLIB = echo ## End of configuration. SOURCES = editline.c complete.c sysunix.c OBJECTS = editline.o complete.o sysunix.o all: libedit.a testit: testit.c libedit.a $(CC) $(CFLAGS) -o testit testit.c libedit.a $(LDFLAGS) shar: FORCE shar `sed -e 1,2d -e 's/[ ].*//' shar FORCE: clean: rm -f *.[oa] testit foo core tags lint lint.all a.out Part01 lint: testit lint -a -b -u -x $(DEFS) $(SOURCES) testit.c >lint.all sed -e '/warning: function prototype not in scope/d' \ -e '/warning: old style argument declaration/'d \ -e '/mix of old and new style function declaration/'d \ lint libedit.a: $(OBJECTS) @rm -f $@ ar r $@ $(OBJECTS) $(RANLIB) $@ $(OBJECTS): editline.h editline-1.12/complete.c0100440000175000017500000000776205467752664013362 0ustar jimjim/* $Revision: 1.5 $ ** ** History and file completion functions for editline library. */ #include "editline.h" #if defined(NEED_STRDUP) /* ** Return an allocated copy of a string. */ char * strdup(p) char *p; { char *new; if ((new = NEW(char, strlen(p) + 1)) != NULL) (void)strcpy(new, p); return new; } #endif /* defined(NEED_STRDUP) */ /* ** 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 + 1] = '\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 { /* Find largest matching substring. */ for (*unique = 0, 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; } editline-1.12/editline.30100440000175000017500000001253205662601554013242 0ustar jimjim.\" $Revision: 1.5 $ .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; \& prefixing the string with a caret (^) forces it to \& match only at the beginning of a history line ^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\ ESC Show possible completions; see below 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\ m Toggle if 8bit chars display as themselves or with \& an ``M\-'' prefix ESC\ u Make word uppercase [n] ESC\ y Yank back last killed text 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 followed by either a question mark or another escape, 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 and Rich $alz . Original manual page by DaviD W. Sanderson . editline-1.12/editline.c0100440000175000017500000006135106341106254013315 0ustar jimjim/* $Revision: 1.12 $ ** ** Main editing routines for editline library. */ #include "editline.h" #include #include /* ** Manifest constants. */ #define SCREEN_WIDTH 80 #define SCREEN_ROWS 24 #define NO_ARG (-1) #define DEL 127 #define TAB '\t' #define CTL(x) ((x) & 0x1F) #define ISCTL(x) ((x) && (x) < ' ') #define UNCTL(x) ((x) + 64) #define META(x) ((x) | 0x80) #define ISMETA(x) ((x) & 0x80) #define UNMETA(x) ((x) & 0x7F) #define MAPSIZE 32 #define METAMAPSIZE 16 #if !defined(HIST_SIZE) #define HIST_SIZE 20 #endif /* !defined(HIST_SIZE) */ typedef CONST CHAR *STRING; /* ** Command status codes. */ typedef enum _STATUS { CSdone, CSeof, CSmove, CSdispatch, CSstay, CSsignal } STATUS; /* ** The type of case-changing to perform. */ typedef enum _CASE { TOupper, TOlower } CASE; /* ** Key to command mapping. */ typedef struct _KEYMAP { CHAR Key; char Active; STATUS (*Function)(); } KEYMAP; /* ** Command history structure. */ typedef struct _HISTORY { int Size; int Pos; CHAR *Lines[HIST_SIZE]; } HISTORY; /* ** Globals. */ int rl_eof; int rl_erase; int rl_intr; int rl_kill; int rl_quit; #if defined(DO_SIGTSTP) int rl_susp; #endif /* defined(DO_SIGTSTP) */ STATIC CHAR NIL[] = ""; STATIC STRING Input = NIL; STATIC CHAR *Line; STATIC CONST char *Prompt; STATIC CHAR *Yanked; STATIC char *Screen; STATIC char NEWLINE[]= CRLF; STATIC HISTORY H; STATIC int Repeat; STATIC int End; STATIC int Mark; STATIC int OldPoint; STATIC int Point; STATIC int PushBack; STATIC int Pushed; STATIC int Signal; FORWARD KEYMAP Map[MAPSIZE]; FORWARD KEYMAP MetaMap[METAMAPSIZE]; STATIC SIZE_T Length; STATIC SIZE_T ScreenCount; STATIC SIZE_T ScreenSize; STATIC char *backspace; STATIC int TTYwidth; STATIC int TTYrows; /* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */ int rl_meta_chars = 1; /* ** Declarations. */ STATIC CHAR *editinput(); extern int read(); extern int write(); #if defined(USE_TERMCAP) extern char *getenv(); extern char *tgetstr(); extern int tgetent(); extern int tgetnum(); #endif /* defined(USE_TERMCAP) */ /* ** TTY input/output functions. */ STATIC void TTYflush() { if (ScreenCount) { (void)write(1, Screen, ScreenCount); ScreenCount = 0; } } STATIC void TTYput(c) CONST CHAR c; { Screen[ScreenCount] = c; if (++ScreenCount >= ScreenSize - 1) { ScreenSize += SCREEN_INC; RENEW(Screen, char, ScreenSize); } } STATIC void TTYputs(p) STRING p; { while (*p) TTYput(*p++); } STATIC void TTYshow(c) CHAR c; { if (c == DEL) { TTYput('^'); TTYput('?'); } else if (c == TAB) { /* XXX */ } else if (ISCTL(c)) { TTYput('^'); TTYput(UNCTL(c)); } else if (rl_meta_chars && ISMETA(c)) { TTYput('M'); TTYput('-'); TTYput(UNMETA(c)); } else TTYput(c); } STATIC void TTYstring(p) CHAR *p; { while (*p) TTYshow(*p++); } STATIC unsigned int TTYget() { CHAR c; TTYflush(); if (Pushed) { Pushed = 0; return PushBack; } if (*Input) return *Input++; return read(0, &c, (SIZE_T)1) == 1 ? c : EOF; } #define TTYback() (backspace ? TTYputs((STRING)backspace) : TTYput('\b')) STATIC void TTYbackn(n) int n; { while (--n >= 0) TTYback(); } STATIC void TTYinfo() { static int init; #if defined(USE_TERMCAP) char *term; char buff[2048]; char *bp; char *p; #endif /* defined(USE_TERMCAP) */ #if defined(TIOCGWINSZ) struct winsize W; #endif /* defined(TIOCGWINSZ) */ if (init) { #if defined(TIOCGWINSZ) /* Perhaps we got resized. */ if (ioctl(0, TIOCGWINSZ, &W) >= 0 && W.ws_col > 0 && W.ws_row > 0) { TTYwidth = (int)W.ws_col; TTYrows = (int)W.ws_row; } #endif /* defined(TIOCGWINSZ) */ return; } init++; TTYwidth = TTYrows = 0; #if defined(USE_TERMCAP) bp = &buff[0]; if ((term = getenv("TERM")) == NULL) term = "dumb"; if (tgetent(buff, term) < 0) { TTYwidth = SCREEN_WIDTH; TTYrows = SCREEN_ROWS; return; } p = tgetstr("le", &bp); backspace = p ? strdup(p) : NULL; TTYwidth = tgetnum("co"); TTYrows = tgetnum("li"); #endif /* defined(USE_TERMCAP) */ #if defined(TIOCGWINSZ) if (ioctl(0, TIOCGWINSZ, &W) >= 0) { TTYwidth = (int)W.ws_col; TTYrows = (int)W.ws_row; } #endif /* defined(TIOCGWINSZ) */ if (TTYwidth <= 0 || TTYrows <= 0) { TTYwidth = SCREEN_WIDTH; TTYrows = SCREEN_ROWS; } } /* ** Print an array of words in columns. */ STATIC void columns(ac, av) int ac; CHAR **av; { CHAR *p; int i; int j; int k; int len; int skip; int longest; int cols; /* Find longest name, determine column count from that. */ for (longest = 0, i = 0; i < ac; i++) if ((j = strlen((char *)av[i])) > longest) longest = j; cols = TTYwidth / (longest + 3); TTYputs((STRING)NEWLINE); for (skip = ac / cols + 1, i = 0; i < skip; i++) { for (j = i; j < ac; j += skip) { for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++) TTYput(*p); if (j + skip < ac) while (++len < longest + 3) TTYput(' '); } TTYputs((STRING)NEWLINE); } } STATIC void reposition() { int i; CHAR *p; TTYput('\r'); TTYputs((STRING)Prompt); for (i = Point, p = Line; --i >= 0; p++) TTYshow(*p); } STATIC void left(Change) STATUS Change; { CHAR c; TTYback(); if (Point) { c = Line[Point - 1]; if (c == TAB) { /* XXX */ } else if (ISCTL(c)) TTYback(); else if (rl_meta_chars && ISMETA(c)) { TTYback(); TTYback(); } } if (Change == CSmove) Point--; } STATIC void right(Change) STATUS Change; { TTYshow(Line[Point]); if (Change == CSmove) Point++; } STATIC STATUS ring_bell() { TTYput('\07'); TTYflush(); return CSstay; } STATIC STATUS do_macro(c) unsigned int c; { CHAR name[4]; name[0] = '_'; name[1] = c; name[2] = '_'; name[3] = '\0'; if ((Input = (CHAR *)getenv((char *)name)) == NULL) { Input = NIL; return ring_bell(); } return CSstay; } STATIC STATUS do_forward(move) STATUS move; { int i; CHAR *p; i = 0; do { p = &Line[Point]; for ( ; Point < End && (*p == ' ' || !isalnum(*p)); Point++, p++) if (move == CSmove) right(CSstay); for (; Point < End && isalnum(*p); Point++, p++) if (move == CSmove) right(CSstay); if (Point == End) break; } while (++i < Repeat); return CSstay; } STATIC STATUS do_case(type) CASE type; { int i; int end; int count; CHAR *p; (void)do_forward(CSstay); if (OldPoint != Point) { if ((count = Point - OldPoint) < 0) count = -count; Point = OldPoint; if ((end = Point + count) > End) end = End; for (i = Point, p = &Line[i]; i < end; i++, p++) { if (type == TOupper) { if (islower(*p)) *p = toupper(*p); } else if (isupper(*p)) *p = tolower(*p); right(CSmove); } } return CSstay; } STATIC STATUS case_down_word() { return do_case(TOlower); } STATIC STATUS case_up_word() { return do_case(TOupper); } STATIC void ceol() { int extras; int i; CHAR *p; for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) { TTYput(' '); if (*p == TAB) { /* XXX */ } else if (ISCTL(*p)) { TTYput(' '); extras++; } else if (rl_meta_chars && ISMETA(*p)) { TTYput(' '); TTYput(' '); extras += 2; } } for (i += extras; i > Point; i--) TTYback(); } STATIC void clear_line() { Point = -strlen(Prompt); TTYput('\r'); ceol(); Point = 0; End = 0; Line[0] = '\0'; } STATIC STATUS insert_string(p) CHAR *p; { SIZE_T len; int i; CHAR *new; CHAR *q; len = strlen((char *)p); if (End + len >= Length) { if ((new = NEW(CHAR, Length + len + MEM_INC)) == NULL) return CSstay; if (Length) { COPYFROMTO(new, Line, Length); DISPOSE(Line); } Line = new; Length += len + MEM_INC; } for (q = &Line[Point], i = End - Point; --i >= 0; ) q[len + i] = q[i]; COPYFROMTO(&Line[Point], p, len); End += len; Line[End] = '\0'; TTYstring(&Line[Point]); Point += len; return Point == End ? CSstay : CSmove; } STATIC STATUS redisplay() { TTYputs((STRING)NEWLINE); TTYputs((STRING)Prompt); TTYstring(Line); return CSmove; } STATIC STATUS redisplay_no_nl() { TTYput('\r'); TTYputs((STRING)Prompt); TTYstring(Line); return CSmove; } STATIC STATUS toggle_meta_mode() { rl_meta_chars = !rl_meta_chars; return redisplay(); } STATIC CHAR * next_hist() { return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos]; } STATIC CHAR * prev_hist() { return H.Pos == 0 ? NULL : H.Lines[--H.Pos]; } STATIC STATUS do_insert_hist(p) CHAR *p; { if (p == NULL) return ring_bell(); Point = 0; reposition(); ceol(); End = 0; return insert_string(p); } STATIC STATUS do_hist(move) CHAR *(*move)(); { CHAR *p; int i; i = 0; do { if ((p = (*move)()) == NULL) return ring_bell(); } while (++i < Repeat); return do_insert_hist(p); } STATIC STATUS h_next() { return do_hist(next_hist); } STATIC STATUS h_prev() { return do_hist(prev_hist); } STATIC STATUS h_first() { return do_insert_hist(H.Lines[H.Pos = 0]); } STATIC STATUS h_last() { return do_insert_hist(H.Lines[H.Pos = H.Size - 1]); } /* ** Return zero if pat appears as a substring in text. */ STATIC int substrcmp(text, pat, len) char *text; char *pat; int len; { CHAR c; if ((c = *pat) == '\0') return *text == '\0'; for ( ; *text; text++) if (*text == c && strncmp(text, pat, len) == 0) return 0; return 1; } STATIC CHAR * search_hist(search, move) CHAR *search; CHAR *(*move)(); { static CHAR *old_search; int len; int pos; int (*match)(); char *pat; /* Save or get remembered search pattern. */ if (search && *search) { if (old_search) DISPOSE(old_search); old_search = (CHAR *)strdup((char *)search); } else { if (old_search == NULL || *old_search == '\0') return NULL; search = old_search; } /* Set up pattern-finder. */ if (*search == '^') { match = strncmp; pat = (char *)(search + 1); } else { match = substrcmp; pat = (char *)search; } len = strlen(pat); for (pos = H.Pos; (*move)() != NULL; ) if ((*match)((char *)H.Lines[H.Pos], pat, len) == 0) return H.Lines[H.Pos]; H.Pos = pos; return NULL; } STATIC STATUS h_search() { static int Searching; CONST char *old_prompt; CHAR *(*move)(); CHAR *p; if (Searching) return ring_bell(); Searching = 1; clear_line(); old_prompt = Prompt; Prompt = "Search: "; TTYputs((STRING)Prompt); move = Repeat == NO_ARG ? prev_hist : next_hist; p = editinput(); Searching = 0; if (p == NULL && Signal > 0) { Signal = 0; clear_line(); Prompt = old_prompt; return redisplay_no_nl(); } p = search_hist(p, move); clear_line(); Prompt = old_prompt; if (p == NULL) { (void)ring_bell(); return redisplay_no_nl(); } return do_insert_hist(p); } STATIC STATUS fd_char() { int i; i = 0; do { if (Point >= End) break; right(CSmove); } while (++i < Repeat); return CSstay; } STATIC void save_yank(begin, i) int begin; int i; { if (Yanked) { DISPOSE(Yanked); Yanked = NULL; } if (i < 1) return; if ((Yanked = NEW(CHAR, (SIZE_T)i + 1)) != NULL) { COPYFROMTO(Yanked, &Line[begin], i); Yanked[i] = '\0'; } } STATIC STATUS delete_string(count) int count; { int i; CHAR *p; if (count <= 0 || End == Point) return ring_bell(); if (count == 1 && Point == End - 1) { /* Optimize common case of delete at end of line. */ End--; p = &Line[Point]; i = 1; TTYput(' '); if (*p == TAB) { /* XXX */ } else if (ISCTL(*p)) { i = 2; TTYput(' '); } else if (rl_meta_chars && ISMETA(*p)) { i = 3; TTYput(' '); TTYput(' '); } TTYbackn(i); *p = '\0'; return CSmove; } if (Point + count > End && (count = End - Point) <= 0) return CSstay; if (count > 1) save_yank(Point, count); ceol(); for (p = &Line[Point], i = End - (Point + count) + 1; --i >= 0; p++) p[0] = p[count]; End -= count; TTYstring(&Line[Point]); return CSmove; } STATIC STATUS bk_char() { int i; i = 0; do { if (Point == 0) break; left(CSmove); } while (++i < Repeat); return CSstay; } STATIC STATUS bk_del_char() { int i; i = 0; do { if (Point == 0) break; left(CSmove); } while (++i < Repeat); return delete_string(i); } STATIC STATUS kill_line() { int i; if (Repeat != NO_ARG) { if (Repeat < Point) { i = Point; Point = Repeat; reposition(); (void)delete_string(i - Point); } else if (Repeat > Point) { right(CSmove); (void)delete_string(Repeat - Point - 1); } return CSmove; } save_yank(Point, End - Point); ceol(); Line[Point] = '\0'; End = Point; return CSstay; } STATIC STATUS insert_char(c) int c; { STATUS s; CHAR buff[2]; CHAR *p; CHAR *q; int i; if (Repeat == NO_ARG || Repeat < 2) { buff[0] = c; buff[1] = '\0'; return insert_string(buff); } if ((p = NEW(CHAR, Repeat + 1)) == NULL) return CSstay; for (i = Repeat, q = p; --i >= 0; ) *q++ = c; *q = '\0'; Repeat = 0; s = insert_string(p); DISPOSE(p); return s; } STATIC STATUS meta() { unsigned int c; KEYMAP *kp; if ((c = TTYget()) == EOF) return CSeof; #if defined(ANSI_ARROWS) /* Also include VT-100 arrows. */ if (c == '[' || c == 'O') switch ((int)(c = TTYget())) { default: return ring_bell(); case EOF: return CSeof; case 'A': return h_prev(); case 'B': return h_next(); case 'C': return fd_char(); case 'D': return bk_char(); } #endif /* defined(ANSI_ARROWS) */ if (isdigit(c)) { for (Repeat = c - '0'; (c = TTYget()) != EOF && isdigit(c); ) Repeat = Repeat * 10 + c - '0'; Pushed = 1; PushBack = c; return CSstay; } if (isupper(c)) return do_macro(c); for (OldPoint = Point, kp = MetaMap; kp < &MetaMap[METAMAPSIZE]; kp++) if (kp->Key == c && kp->Active) return (*kp->Function)(); return ring_bell(); } STATIC STATUS emacs(c) unsigned int c; { STATUS s; KEYMAP *kp; #if 0 /* This test makes it impossible to enter eight-bit characters when * meta-char mode is enabled. */ if (rl_meta_chars && ISMETA(c)) { Pushed = 1; PushBack = UNMETA(c); return meta(); } #endif /* 0 */ for (kp = Map; kp < &Map[MAPSIZE]; kp++) if (kp->Key == c && kp->Active) break; s = kp < &Map[MAPSIZE] ? (*kp->Function)() : insert_char((int)c); if (!Pushed) /* No pushback means no repeat count; hacky, but true. */ Repeat = NO_ARG; return s; } STATIC STATUS TTYspecial(c) unsigned int c; { if (rl_meta_chars && ISMETA(c)) return CSdispatch; if (c == rl_erase || c == DEL) return bk_del_char(); if (c == rl_kill) { if (Point != 0) { Point = 0; reposition(); } Repeat = NO_ARG; return kill_line(); } if (c == rl_eof && Point == 0 && End == 0) return CSeof; if (c == rl_intr) { Signal = SIGINT; return CSsignal; } if (c == rl_quit) { Signal = SIGQUIT; return CSsignal; } #if defined(DO_SIGTSTP) if (c == rl_susp) { Signal = SIGTSTP; return CSsignal; } #endif /* defined(DO_SIGTSTP) */ return CSdispatch; } STATIC CHAR * editinput() { unsigned int c; Repeat = NO_ARG; OldPoint = Point = Mark = End = 0; Line[0] = '\0'; Signal = -1; while ((c = TTYget()) != EOF) switch (TTYspecial(c)) { case CSdone: return Line; case CSeof: return NULL; case CSsignal: return (CHAR *)""; case CSmove: reposition(); break; case CSdispatch: switch (emacs(c)) { case CSdone: return Line; case CSeof: return NULL; case CSsignal: return (CHAR *)""; case CSmove: reposition(); break; case CSdispatch: case CSstay: break; } break; case CSstay: break; } return NULL; } STATIC void hist_add(p) CHAR *p; { int i; if ((p = (CHAR *)strdup((char *)p)) == NULL) return; if (H.Size < HIST_SIZE) H.Lines[H.Size++] = p; else { DISPOSE(H.Lines[0]); for (i = 0; i < HIST_SIZE - 1; i++) H.Lines[i] = H.Lines[i + 1]; H.Lines[i] = p; } H.Pos = H.Size - 1; } STATIC char * read_redirected() { int size; char *p; char *line; char *end; for (size = MEM_INC, p = line = NEW(char, size), end = p + size; ; p++) { if (p == end) { size += MEM_INC; p = line = realloc(line, size); end = p + size; } if (read(0, p, 1) <= 0) { /* Ignore "incomplete" lines at EOF, just like we do for a tty. */ free(line); return NULL; } if (*p == '\n') break; } *p = '\0'; return line; } /* ** For compatibility with FSF readline. */ /* ARGSUSED0 */ void rl_reset_terminal(p) char *p; { } void rl_initialize() { } int rl_insert(count, c) int count; int c; { if (count > 0) { Repeat = count; (void)insert_char(c); (void)redisplay_no_nl(); } return 0; } int (*rl_event_hook)(); int rl_key_action(c, flag) int c; char flag; { KEYMAP *kp; int size; if (ISMETA(c)) { kp = MetaMap; size = METAMAPSIZE; } else { kp = Map; size = MAPSIZE; } for ( ; --size >= 0; kp++) if (kp->Key == c) { kp->Active = c ? 1 : 0; return 1; } return -1; } char * readline(prompt) CONST char *prompt; { CHAR *line; int s; if (!isatty(0)) { TTYflush(); return read_redirected(); } if (Line == NULL) { Length = MEM_INC; if ((Line = NEW(CHAR, Length)) == NULL) return NULL; } TTYinfo(); rl_ttyset(0); hist_add(NIL); ScreenSize = SCREEN_INC; Screen = NEW(char, ScreenSize); Prompt = prompt ? prompt : (char *)NIL; TTYputs((STRING)Prompt); if ((line = editinput()) != NULL) { line = (CHAR *)strdup((char *)line); TTYputs((STRING)NEWLINE); TTYflush(); } rl_ttyset(1); DISPOSE(Screen); DISPOSE(H.Lines[--H.Size]); if (Signal > 0) { s = Signal; Signal = 0; (void)kill(getpid(), s); } return (char *)line; } void add_history(p) char *p; { if (p == NULL || *p == '\0') return; #if defined(UNIQUE_HISTORY) if (H.Size && strcmp(p, H.Lines[H.Size - 1]) == 0) return; #endif /* defined(UNIQUE_HISTORY) */ hist_add((CHAR *)p); } STATIC STATUS beg_line() { if (Point) { Point = 0; return CSmove; } return CSstay; } STATIC STATUS del_char() { return delete_string(Repeat == NO_ARG ? 1 : Repeat); } STATIC STATUS end_line() { if (Point != End) { Point = End; return CSmove; } return CSstay; } /* ** Return allocated copy of word under cursor, moving cursor after the ** word. */ STATIC CHAR * find_word() { static char SEPS[] = "\"#;&|^$=`'{}()<>\n\t "; CHAR *p; CHAR *new; SIZE_T len; /* Move forward to end of word. */ p = &Line[Point]; for ( ; Point < End && strchr(SEPS, (char)*p) == NULL; Point++, p++) right(CSstay); /* Back up to beginning of word. */ for (p = &Line[Point]; p > Line && strchr(SEPS, (char)p[-1]) == NULL; p--) continue; len = Point - (p - Line) + 1; if ((new = NEW(CHAR, len)) == NULL) return NULL; COPYFROMTO(new, p, len); new[len - 1] = '\0'; return new; } STATIC STATUS c_complete() { CHAR *p; CHAR *word; int unique; word = find_word(); p = (CHAR *)rl_complete((char *)word, &unique); if (word) DISPOSE(word); if (p && *p) { (void)insert_string(p); if (!unique) (void)ring_bell(); DISPOSE(p); return redisplay_no_nl(); } return ring_bell(); } STATIC STATUS c_possible() { CHAR **av; CHAR *word; int ac; word = find_word(); ac = rl_list_possib((char *)word, (char ***)&av); if (word) DISPOSE(word); if (ac) { columns(ac, av); while (--ac >= 0) DISPOSE(av[ac]); DISPOSE(av); return redisplay_no_nl(); } return ring_bell(); } STATIC STATUS accept_line() { Line[End] = '\0'; return CSdone; } STATIC STATUS transpose() { CHAR c; if (Point) { if (Point == End) left(CSmove); c = Line[Point - 1]; left(CSstay); Line[Point - 1] = Line[Point]; TTYshow(Line[Point - 1]); Line[Point++] = c; TTYshow(c); } return CSstay; } STATIC STATUS quote() { unsigned int c; return (c = TTYget()) == EOF ? CSeof : insert_char((int)c); } STATIC STATUS wipe() { int i; if (Mark > End) return ring_bell(); if (Point > Mark) { i = Point; Point = Mark; Mark = i; reposition(); } return delete_string(Mark - Point); } STATIC STATUS mk_set() { Mark = Point; return CSstay; } STATIC STATUS exchange() { unsigned int c; if ((c = TTYget()) != CTL('X')) return c == EOF ? CSeof : ring_bell(); if ((c = Mark) <= End) { Mark = Point; Point = c; return CSmove; } return CSstay; } STATIC STATUS yank() { if (Yanked && *Yanked) return insert_string(Yanked); return CSstay; } STATIC STATUS copy_region() { if (Mark > End) return ring_bell(); if (Point > Mark) save_yank(Mark, Point - Mark); else save_yank(Point, Mark - Point); return CSstay; } STATIC STATUS move_to_char() { unsigned int c; int i; CHAR *p; if ((c = TTYget()) == EOF) return CSeof; for (i = Point + 1, p = &Line[i]; i < End; i++, p++) if (*p == c) { Point = i; return CSmove; } return CSstay; } STATIC STATUS fd_word() { return do_forward(CSmove); } STATIC STATUS fd_kill_word() { int i; (void)do_forward(CSstay); if (OldPoint != Point) { i = Point - OldPoint; Point = OldPoint; return delete_string(i); } return CSstay; } STATIC STATUS bk_word() { int i; CHAR *p; i = 0; do { for (p = &Line[Point]; p > Line && !isalnum(p[-1]); p--) left(CSmove); for (; p > Line && p[-1] != ' ' && isalnum(p[-1]); p--) left(CSmove); if (Point == 0) break; } while (++i < Repeat); return CSstay; } STATIC STATUS bk_kill_word() { (void)bk_word(); if (OldPoint != Point) return delete_string(OldPoint - Point); return CSstay; } STATIC int argify(line, avp) CHAR *line; CHAR ***avp; { CHAR *c; CHAR **p; CHAR **new; int ac; int i; i = MEM_INC; if ((*avp = p = NEW(CHAR*, i))== NULL) return 0; for (c = line; isspace(*c); c++) continue; if (*c == '\n' || *c == '\0') return 0; for (ac = 0, p[ac++] = c; *c && *c != '\n'; ) { if (isspace(*c)) { *c++ = '\0'; if (*c && *c != '\n') { if (ac + 1 == i) { new = NEW(CHAR*, i + MEM_INC); if (new == NULL) { p[ac] = NULL; return ac; } COPYFROMTO(new, p, i * sizeof (char **)); i += MEM_INC; DISPOSE(p); *avp = p = new; } p[ac++] = c; } } else c++; } *c = '\0'; p[ac] = NULL; return ac; } STATIC STATUS last_argument() { CHAR **av; CHAR *p; STATUS s; int ac; if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL) return ring_bell(); if ((p = (CHAR *)strdup((char *)p)) == NULL) return CSstay; ac = argify(p, &av); if (Repeat != NO_ARG) s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell(); else s = ac ? insert_string(av[ac - 1]) : CSstay; if (ac) DISPOSE(av); DISPOSE(p); return s; } STATIC KEYMAP Map[MAPSIZE] = { { CTL('@'), 1, ring_bell }, { CTL('A'), 1, beg_line }, { CTL('B'), 1, bk_char }, { CTL('D'), 1, del_char }, { CTL('E'), 1, end_line }, { CTL('F'), 1, fd_char }, { CTL('G'), 1, ring_bell }, { CTL('H'), 1, bk_del_char }, { CTL('I'), 1, c_complete }, { CTL('J'), 1, accept_line }, { CTL('K'), 1, kill_line }, { CTL('L'), 1, redisplay }, { CTL('M'), 1, accept_line }, { CTL('N'), 1, h_next }, { CTL('O'), 1, ring_bell }, { CTL('P'), 1, h_prev }, { CTL('Q'), 1, ring_bell }, { CTL('R'), 1, h_search }, { CTL('S'), 1, ring_bell }, { CTL('T'), 1, transpose }, { CTL('U'), 1, ring_bell }, { CTL('V'), 1, quote }, { CTL('W'), 1, wipe }, { CTL('X'), 1, exchange }, { CTL('Y'), 1, yank }, { CTL('Z'), 1, ring_bell }, { CTL('['), 1, meta }, { CTL(']'), 1, move_to_char }, { CTL('^'), 1, ring_bell }, { CTL('_'), 1, ring_bell }, }; STATIC KEYMAP MetaMap[16]= { { CTL('H'), 1, bk_kill_word }, { CTL('['), 1, c_possible }, { DEL, 1, bk_kill_word }, { ' ', 1, mk_set }, { '.', 1, last_argument }, { '<', 1, h_first }, { '>', 1, h_last }, { '?', 1, c_possible }, { 'b', 1, bk_word }, { 'd', 1, fd_kill_word }, { 'f', 1, fd_word }, { 'l', 1, case_down_word }, { 'm', 1, toggle_meta_mode}, { 'u', 1, case_up_word }, { 'y', 1, yank }, { 'w', 1, copy_region }, }; editline-1.12/editline.h0100440000175000017500000000324305447367640013334 0ustar jimjim/* $Revision: 1.4 $ ** ** Internal header file for editline library. */ #include #if defined(HAVE_STDLIB) #include #include #endif /* defined(HAVE_STDLIB) */ #if defined(SYS_UNIX) #include "unix.h" #endif /* defined(SYS_UNIX) */ #if defined(SYS_OS9) #include "os9.h" #endif /* defined(SYS_OS9) */ #if !defined(SIZE_T) #define SIZE_T unsigned int #endif /* !defined(SIZE_T) */ typedef unsigned char CHAR; #if defined(HIDE) #define STATIC static #else #define STATIC /* NULL */ #endif /* !defined(HIDE) */ #if !defined(CONST) #if defined(__STDC__) #define CONST const #else #define CONST #endif /* defined(__STDC__) */ #endif /* !defined(CONST) */ #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; #if defined(DO_SIGTSTP) extern int rl_susp; #endif /* defined(DO_SIGTSTP) */ extern char *rl_complete(); extern int rl_list_possib(); extern void rl_ttyset(); extern void rl_add_slash(); #if !defined(HAVE_STDLIB) extern char *getenv(); extern char *malloc(); extern char *realloc(); extern char *memcpy(); extern char *strcat(); extern char *strchr(); extern char *strrchr(); extern char *strcpy(); extern char *strdup(); extern int strcmp(); extern int strlen(); extern int strncmp(); #endif /* !defined(HAVE_STDLIB) */ editline-1.12/os9.h0100440000175000017500000000025605445646434012251 0ustar jimjim/* $Revision: 1.1 $ ** ** Editline system header file for OS-9 (on 68k). */ #define CRLF "\r\l" #define FORWARD extern #include typedef struct direct DIRENTRY; editline-1.12/sysos9.c0100440000175000017500000000214005445646434012775 0ustar jimjim/* $Revision: 1.1 $ ** ** OS-9 system-dependant routines for editline library. */ #include "editline.h" #include #include void rl_ttyset(Reset) int Reset; { static struct sgbuf old; struct sgbuf new; if (Reset == 0) { _gs_opt(0, &old); _gs_opt(0, &new); new.sg_backsp = 0; new.sg_delete = 0; new.sg_echo = 0; new.sg_alf = 0; new.sg_nulls = 0; new.sg_pause = 0; new.sg_page = 0; new.sg_bspch = 0; new.sg_dlnch = 0; new.sg_eorch = 0; new.sg_eofch = 0; new.sg_rlnch = 0; new.sg_dulnch = 0; new.sg_psch = 0; new.sg_kbich = 0; new.sg_kbach = 0; new.sg_bsech = 0; new.sg_bellch = 0; new.sg_xon = 0; new.sg_xoff = 0; new.sg_tabcr = 0; new.sg_tabsiz = 0; _ss_opt(0, &new); rl_erase = old.sg_bspch; rl_kill = old.sg_dlnch; rl_eof = old.sg_eofch; rl_intr = old.sg_kbich; rl_quit = -1; } else _ss_opt(0, &old); } void rl_add_slash(path, p) char *path; char *p; { (void)strcat(p, access(path, S_IREAD | S_IFDIR) ? " " : "/"); } editline-1.12/sysunix.c0100440000175000017500000000534606261000030013226 0ustar jimjim/* $Revision: 1.5 $ ** ** Unix system-dependant routines for editline library. */ #include "editline.h" #if defined(HAVE_TCGETATTR) #include void rl_ttyset(Reset) int Reset; { static struct termios old; struct termios new; if (Reset == 0) { if (tcgetattr(0, &old) < 0) perror("tcgetattr"); rl_erase = old.c_cc[VERASE]; rl_kill = old.c_cc[VKILL]; rl_eof = old.c_cc[VEOF]; rl_intr = old.c_cc[VINTR]; rl_quit = old.c_cc[VQUIT]; #if defined(DO_SIGTSTP) rl_susp = old.c_cc[VSUSP]; #endif /* defined(DO_SIGTSTP) */ new = old; new.c_lflag &= ~(ECHO | ICANON | ISIG); new.c_iflag &= ~(ISTRIP | INPCK); new.c_cc[VMIN] = 1; new.c_cc[VTIME] = 0; if (tcsetattr(0, TCSADRAIN, &new) < 0) perror("tcsetattr"); } else (void)tcsetattr(0, TCSADRAIN, &old); } #else #if defined(HAVE_TERMIO) #include void rl_ttyset(Reset) int Reset; { static struct termio old; struct termio new; if (Reset == 0) { (void)ioctl(0, TCGETA, &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]; #if defined(DO_SIGTSTP) rl_susp = old.c_cc[VSUSP]; #endif /* defined(DO_SIGTSTP) */ new = old; new.c_lflag &= ~(ECHO | ICANON | ISIG); new.c_iflag &= ~(ISTRIP | INPCK); new.c_cc[VMIN] = 1; new.c_cc[VTIME] = 0; (void)ioctl(0, TCSETAW, &new); } else (void)ioctl(0, TCSETAW, &old); } #else #include void rl_ttyset(Reset) int Reset; { static struct sgttyb old_sgttyb; static struct tchars old_tchars; struct sgttyb new_sgttyb; struct tchars new_tchars; #if defined(DO_SIGTSTP) struct ltchars old_ltchars; #endif /* defined(DO_SIGTSTP) */ if (Reset == 0) { (void)ioctl(0, TIOCGETP, &old_sgttyb); rl_erase = old_sgttyb.sg_erase; rl_kill = old_sgttyb.sg_kill; (void)ioctl(0, TIOCGETC, &old_tchars); rl_eof = old_tchars.t_eofc; rl_intr = old_tchars.t_intrc; rl_quit = old_tchars.t_quitc; #if defined(DO_SIGTSTP) (void)ioctl(0, TIOCGLTC, &old_ltchars); rl_susp = old_ltchars.t_suspc; #endif /* defined(DO_SIGTSTP) */ new_sgttyb = old_sgttyb; new_sgttyb.sg_flags &= ~ECHO; new_sgttyb.sg_flags |= RAW; #if defined(PASS8) new_sgttyb.sg_flags |= PASS8; #endif /* defined(PASS8) */ (void)ioctl(0, TIOCSETP, &new_sgttyb); new_tchars = old_tchars; new_tchars.t_intrc = -1; new_tchars.t_quitc = -1; (void)ioctl(0, TIOCSETC, &new_tchars); } else { (void)ioctl(0, TIOCSETP, &old_sgttyb); (void)ioctl(0, TIOCSETC, &old_tchars); } } #endif /* defined(HAVE_TERMIO) */ #endif /* defined(HAVE_TCGETATTR) */ void rl_add_slash(path, p) char *path; char *p; { struct stat Sb; if (stat(path, &Sb) >= 0) (void)strcat(p, S_ISDIR(Sb.st_mode) ? "/" : " "); } editline-1.12/testit.c0100440000175000017500000000215605445646434013047 0ustar jimjim/* $Revision: 1.4 $ ** ** A "micro-shell" to test editline library. ** If given any arguments, commands aren't executed. */ #include #if defined(HAVE_STDLIB) #include #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(); extern char *getenv(); #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 *prompt; char *p; int doit; doit = ac == 1; if ((prompt = getenv("TESTPROMPT")) == NULL) prompt = "testit> "; while ((p = readline(prompt)) != 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 */ } editline-1.12/unix.h0100440000175000017500000000066005445646434012521 0ustar jimjim/* $Revision: 1.1 $ ** ** Editline system header file for Unix. */ #define CRLF "\r\n" #define FORWARD STATIC #include #include #if defined(USE_DIRENT) #include typedef struct dirent DIRENTRY; #else #include 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) */