home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume31 / editline / part01 < prev    next >
Encoding:
Text File  |  1992-08-13  |  49.6 KB  |  2,394 lines

  1. Newsgroups: comp.sources.misc
  2. From: rsalz@osf.org (Rich $alz)
  3. Subject:  v31i071:  editline - Small line-editing library, Part01/01
  4. Message-ID: <1992Aug2.030527.9953@sparky.imd.sterling.com>
  5. X-Md4-Signature: 1f497d9e04faa0d64f2c0eedc53941b7
  6. Date: Sun, 2 Aug 1992 03:05:27 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: rsalz@osf.org (Rich $alz)
  10. Posting-number: Volume 31, Issue 71
  11. Archive-name: editline/part01
  12. Environment: UNIX, OS-9
  13.  
  14. This is a line-editing library.  It can be linked into almost any
  15. program to provide command-line editing and recall.
  16.  
  17. It is call-compatible with the FSF readline library, but it is a
  18. fraction of the size (and offers fewer features).  It does not use
  19. standard I/O.  It is distributed under a "C News-like" copyright.
  20.  
  21. Configuration is done in the Makefile.  Type "make testit" to get
  22. a small slow shell for testing.
  23.  
  24. An earlier version was distributed with Byron's rc.  Principal
  25. changes over that version include:
  26.     Faster.
  27.     Is eight-bit clean (thanks to brendan@cs.widener.edu)
  28.     Written in K&R C, but ANSI compliant (gcc all warnings)
  29.     Propagates EOF properly; rc trip test now passes
  30.     Doesn't need or use or provide memmove.
  31.     More robust
  32.     Calling sequence changed to be compatible with readline.
  33.     Test program, new manpage, better configuration
  34.     More system-independant; includes Unix and OS-9 support.
  35.  
  36. Enjoy,
  37.     Rich $alz
  38.     <rsalz@osf.org>
  39. #! /bin/sh
  40. # This is a shell archive.  Remove anything before this line, then feed it
  41. # into a shell via "sh file" or similar.  To overwrite existing files,
  42. # type "sh file -c".
  43. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  44. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  45. # Contents:  README Makefile editline.3 editline.h unix.h editline.c
  46. #   complete.c sysunix.c testit.c Make.os9 os9.h sysos9.c
  47. # Wrapped by rsalz@earth on Thu Jul 30 11:41:20 1992
  48. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  49. echo If this archive is complete, you will see the following message:
  50. echo '          "shar: End of archive."'
  51. if test -f 'README' -a "${1}" != "-c" ; then 
  52.   echo shar: Will not clobber existing file \"'README'\"
  53. else
  54.   echo shar: Extracting \"'README'\" \(1934 characters\)
  55.   sed "s/^X//" >'README' <<'END_OF_FILE'
  56. X$Revision: 1.5 $
  57. X
  58. XThis is a line-editing library.  It can be linked into almost any
  59. Xprogram to provide command-line editing and recall.
  60. X
  61. XIt is call-compatible with the FSF readline library, but it is a
  62. Xfraction of the size (and offers fewer features).  It does not use
  63. Xstandard I/O.  It is distributed under a "C News-like" copyright.
  64. X
  65. XConfiguration is done in the Makefile.  Type "make testit" to get
  66. Xa small slow shell for testing.
  67. X
  68. XAn earlier version was distributed with Byron's rc.  Principal
  69. Xchanges over that version include:
  70. X    Faster.
  71. X    Is eight-bit clean (thanks to brendan@cs.widener.edu)
  72. X    Written in K&R C, but ANSI compliant (gcc all warnings)
  73. X    Propagates EOF properly; rc trip test now passes
  74. X    Doesn't need or use or provide memmove.
  75. X    More robust
  76. X    Calling sequence changed to be compatible with readline.
  77. X    Test program, new manpage, better configuration
  78. X    More system-independant; includes Unix and OS-9 support.
  79. X
  80. XEnjoy,
  81. X    Rich $alz
  82. X    <rsalz@osf.org>
  83. X
  84. X Copyright 1992 Simmule Turner and Rich Salz.  All rights reserved.
  85. X
  86. X This software is not subject to any license of the American Telephone
  87. X and Telegraph Company or of the Regents of the University of California.
  88. X
  89. X Permission is granted to anyone to use this software for any purpose on
  90. X any computer system, and to alter it and redistribute it freely, subject
  91. X to the following restrictions:
  92. X 1. The authors are not responsible for the consequences of use of this
  93. X    software, no matter how awful, even if they arise from flaws in it.
  94. X 2. The origin of this software must not be misrepresented, either by
  95. X    explicit claim or by omission.  Since few users ever read sources,
  96. X    credits must appear in the documentation.
  97. X 3. Altered versions must be plainly marked as such, and must not be
  98. X    misrepresented as being the original software.  Since few users
  99. X    ever read sources, credits must appear in the documentation.
  100. X 4. This notice may not be removed or altered.
  101. END_OF_FILE
  102.   if test 1934 -ne `wc -c <'README'`; then
  103.     echo shar: \"'README'\" unpacked with wrong size!
  104.   fi
  105.   # end of 'README'
  106. fi
  107. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  108.   echo shar: Will not clobber existing file \"'Makefile'\"
  109. else
  110.   echo shar: Extracting \"'Makefile'\" \(1836 characters\)
  111.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  112. X##  $Revision: 1.3 $
  113. X##
  114. X##  Unix makefile for editline library.
  115. X##
  116. X
  117. X##  Set your options:
  118. X##    -DANSI_ARROWS        ANSI arrows keys work like emacs.
  119. X##    -DHAVE_STDLIB        Have <stdlib.h>.
  120. X##    -DHAVE_TCGETATTR    Have tcgetattr(), tcsetattr().
  121. X##    -DHIDE            Make static functions static (non debug).
  122. X##    -DHIST_SIZE=n        History size.
  123. X##    -DNEED_STRDUP        Don't have strdup().
  124. X##    -DUNIQUE_HISTORY    Don't save command if same as last one.
  125. X##    -DUSE_DIRENT        Use <dirent.h>, not <sys/dir.h>?
  126. X##    -DUSE_TERMCAP        Use the termcap library for terminal size
  127. X##                see LDFLAGS, below, if you set this.
  128. X##    -DNEED_PERROR        Don't have perror() (used in testit)
  129. XDEFS    = -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX
  130. X
  131. X##  Set your C compiler:
  132. XWARN    = -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings \
  133. X    -Wunused -Wcomment -Wswitch
  134. XCC    = gcc -ansi $(WARN)
  135. X#CC    = cc
  136. XCFLAGS    = $(DEFS) -O -g
  137. X
  138. X##  If you have -DUSE_TERMCAP, set this as appropriate:
  139. X#LDFLAGS = -ltermlib
  140. X#LDFLAGS = -ltermcap
  141. X
  142. X##  Set ranlib as appropriate:
  143. XRANLIB    = ranlib
  144. X#RANLIB    = echo
  145. X
  146. X##  End of configuration.
  147. X
  148. XSOURCES    = editline.c complete.c sysunix.c
  149. XOBJECTS    = editline.o complete.o sysunix.o
  150. XSHARFILES =    README Makefile editline.3 editline.h unix.h editline.c \
  151. X        complete.c sysunix.c testit.c \
  152. X        Make.os9 os9.h sysos9.c
  153. X
  154. Xall:        libedit.a
  155. X
  156. Xtestit:        testit.c libedit.a
  157. X    $(CC) $(CFLAGS) -o testit testit.c libedit.a $(LDFLAGS)
  158. X
  159. Xshar:        $(SHARFILES)
  160. X    shar $(SHARFILES) >shar
  161. X
  162. Xclean:
  163. X    rm -f *.[oa] testit foo core tags lint lint.all a.out shar
  164. X
  165. Xlint:        testit
  166. X    lint -a -b -u -x $(DEFS) $(SOURCES) testit.c >lint.all
  167. X    sed -e '/warning: function prototype not in scope/d' \
  168. X        -e '/warning: old style argument declaration/'d \
  169. X        -e '/mix of old and new style function declaration/'d \
  170. X        <lint.all >lint
  171. X
  172. Xlibedit.a:    $(OBJECTS)
  173. X    @rm -f $@
  174. X    ar r $@ $(OBJECTS)
  175. X    $(RANLIB) $@
  176. X
  177. X$(OBJECTS):    editline.h
  178. END_OF_FILE
  179.   if test 1836 -ne `wc -c <'Makefile'`; then
  180.     echo shar: \"'Makefile'\" unpacked with wrong size!
  181.   fi
  182.   # end of 'Makefile'
  183. fi
  184. if test -f 'editline.3' -a "${1}" != "-c" ; then 
  185.   echo shar: Will not clobber existing file \"'editline.3'\"
  186. else
  187.   echo shar: Extracting \"'editline.3'\" \(5281 characters\)
  188.   sed "s/^X//" >'editline.3' <<'END_OF_FILE'
  189. X.\" $Revision: 1.1 $
  190. X.TH EDITLINE 3
  191. X.SH NAME
  192. Xeditline \- command-line editing library with history
  193. X.SH SYNOPSIS
  194. X.nf
  195. X.B "char *"
  196. X.B "readline(prompt)"
  197. X.B "     char    *prompt;"
  198. X
  199. X.B "void"
  200. X.B "add_history(line)"
  201. X.B "    char    *line;"
  202. X.fi
  203. X.SH DESCRIPTION
  204. X.I Editline
  205. Xis a library that provides an line-editing interface with text recall.
  206. XIt is intended to be compatible with the
  207. X.I readline
  208. Xlibrary provided by the Free Software Foundation, but much smaller.
  209. XThe bulk of this manual page describes the user interface.
  210. X.PP
  211. XThe
  212. X.I readline
  213. Xroutine returns a line of text with the trailing newline removed.
  214. XThe data is returned in a buffer allocated with
  215. X.IR malloc (3),
  216. Xso the space should be released with
  217. X.IR free (3)
  218. Xwhen the calling program is done with it.
  219. XBefore accepting input from the user, the specified
  220. X.I prompt
  221. Xis displayed on the terminal.
  222. X.PP
  223. XThe
  224. X.I add_history
  225. Xroutine makes a copy of the specified
  226. X.I line
  227. Xand adds it to the internal history list.
  228. X.SS "User Interface"
  229. XA program that uses this library provides a simple emacs-like editing
  230. Xinterface to its users.
  231. XA line may be edited before it is sent to the calling program by typing either
  232. Xcontrol characters or escape sequences.
  233. XA control character, shown as a caret followed by a letter, is typed by
  234. Xholding down the ``control'' key while the letter is typed.
  235. XFor example, ``^A'' is a control-A.
  236. XAn escape sequence is entered by typing the ``escape'' key followed by one or
  237. Xmore characters.
  238. XThe escape key is abbreviated as ``ESC.''
  239. XNote that unlike control keys, case matters in escape sequences; ``ESC\ F''
  240. Xis not the same as ``ESC\ f''.
  241. X.PP
  242. XAn editing command may be typed anywhere on the line, not just at the
  243. Xbeginning.
  244. XIn addition, a return may also be typed anywhere on the line, not just at
  245. Xthe end.
  246. X.PP
  247. XMost editing commands may be given a repeat count,
  248. X.IR n ,
  249. Xwhere
  250. X.I n
  251. Xis a number.
  252. XTo enter a repeat count, type the escape key, the number, and then
  253. Xthe command to execute.
  254. XFor example, ``ESC\ 4\ ^f'' moves forward four characters.
  255. XIf a command may be given a repeat count then the text ``[n]'' is given at the
  256. Xend of its description.
  257. X.PP
  258. XThe following control characters are accepted:
  259. X.RS
  260. X.nf
  261. X.ta \w'ESC DEL  'u
  262. X^A    Move to the beginning of the line
  263. X^B    Move left (backwards) [n]
  264. X^D    Delete character [n]
  265. X^E    Move to end of line
  266. X^F    Move right (forwards) [n]
  267. X^G    Ring the bell
  268. X^H    Delete character before cursor (backspace key) [n]
  269. X^I    Complete filename (tab key); see below
  270. X^J    Done with line (return key)
  271. X^K    Kill to end of line (or column [n])
  272. X^L    Redisplay line
  273. X^M    Done with line (alternate return key)
  274. X^N    Get next line from history [n]
  275. X^P    Get previous line from history [n]
  276. X^R    Search backward (forward if [n]) through history for text;
  277. X\&    must start line if text begins with an uparrow
  278. X^T    Transpose characters
  279. X^V    Insert next character, even if it is an edit command
  280. X^W    Wipe to the mark
  281. X^X^X    Exchange current location and mark
  282. X^Y    Yank back last killed text
  283. X^[    Start an escape sequence (escape key)
  284. X^]c    Move forward to next character ``c''
  285. X^?    Delete character before cursor (delete key) [n]
  286. X.fi
  287. X.RE
  288. X.PP
  289. XThe following escape sequences are provided.
  290. X.RS
  291. X.nf
  292. X.ta \w'ESC DEL  'u
  293. XESC\ ^H    Delete previous word (backspace key) [n]
  294. XESC\ DEL    Delete previous word (delete key) [n]
  295. XESC\ SP    Set the mark (space key); see ^X^X and ^Y above
  296. XESC\ \.    Get the last (or [n]'th) word from previous line
  297. XESC\ \?    Show possible completions; see below
  298. XESC\ <    Move to start of history
  299. XESC\ >    Move to end of history
  300. XESC\ b    Move backward a word [n]
  301. XESC\ d    Delete word under cursor [n]
  302. XESC\ f    Move forward a word [n]
  303. XESC\ l    Make word lowercase [n]
  304. XESC\ u    Make word uppercase [n]
  305. XESC\ y    Yank back last killed text
  306. XESC\ v    Show library version
  307. XESC\ w    Make area up to mark yankable
  308. XESC\ nn    Set repeat count to the number nn
  309. XESC\ C    Read from environment variable ``_C_'', where C is
  310. X\&    an uppercase letter
  311. X.fi
  312. X.RE
  313. X.PP
  314. XThe
  315. X.I editline
  316. Xlibrary has a small macro facility.
  317. XIf you type the escape key followed by an uppercase letter,
  318. X.IR C ,
  319. Xthen the contents of the environment variable
  320. X.I _C_
  321. Xare read in as if you had typed them at the keyboard.
  322. XFor example, if the variable
  323. X.I _L_
  324. Xcontains the following:
  325. X.RS
  326. X^A^Kecho '^V^[[H^V^[[2J'^M
  327. X.RE
  328. XThen typing ``ESC L'' will move to the beginning of the line, kill the
  329. Xentire line, enter the echo command needed to clear the terminal (if your
  330. Xterminal is like a VT-100), and send the line back to the shell.
  331. X.PP
  332. XThe
  333. X.I editline
  334. Xlibrary also does filename completion.
  335. XSuppose the root directory has the following files in it:
  336. X.RS
  337. X.nf
  338. X.ta \w'core   'u
  339. Xbin    vmunix
  340. Xcore    vmunix.old
  341. X.fi
  342. X.RE
  343. XIf you type ``rm\ /v'' and then the tab key.
  344. X.I Editline
  345. Xwill then finish off as much of the name as possible by adding ``munix''.
  346. XBecause the name is not unique, it will then beep.
  347. XIf you type the escape key and a question mark, it will display the
  348. Xtwo choices.
  349. XIf you then type a period and a tab, the library will finish off the filename
  350. Xfor you:
  351. X.RS
  352. X.nf
  353. X.RI "rm /v[TAB]" munix .TAB old
  354. X.fi
  355. X.RE
  356. XThe tab key is shown by ``[TAB]'' and the automatically-entered text
  357. Xis shown in italics.
  358. X.SH "BUGS AND LIMITATIONS"
  359. XCannot handle lines more than 80 columns.
  360. X.SH AUTHORS
  361. XSimmule R. Turner <uunet.uu.net!capitol!sysgo!simmy>
  362. Xand Rich $alz <rsalz@osf.org>.
  363. XOriginal manual page by DaviD W. Sanderson <dws@ssec.wisc.edu>.
  364. END_OF_FILE
  365.   if test 5281 -ne `wc -c <'editline.3'`; then
  366.     echo shar: \"'editline.3'\" unpacked with wrong size!
  367.   fi
  368.   # end of 'editline.3'
  369. fi
  370. if test -f 'editline.h' -a "${1}" != "-c" ; then 
  371.   echo shar: Will not clobber existing file \"'editline.h'\"
  372. else
  373.   echo shar: Extracting \"'editline.h'\" \(1622 characters\)
  374.   sed "s/^X//" >'editline.h' <<'END_OF_FILE'
  375. X/*  $Revision: 1.3 $
  376. X**
  377. X**  Internal header file for editline library.
  378. X*/
  379. X#include <stdio.h>
  380. X#if    defined(HAVE_STDLIB)
  381. X#include <stdlib.h>
  382. X#include <string.h>
  383. X#endif    /* defined(HAVE_STDLIB) */
  384. X#if    defined(SYS_UNIX)
  385. X#include "unix.h"
  386. X#endif    /* defined(SYS_UNIX) */
  387. X#if    defined(SYS_OS9)
  388. X#include "os9.h"
  389. X#endif    /* defined(SYS_OS9) */
  390. X
  391. X#if    !defined(SIZE_T)
  392. X#define SIZE_T    unsigned int
  393. X#endif    /* !defined(SIZE_T) */
  394. X
  395. Xtypedef unsigned char    CHAR;
  396. X
  397. X#if    defined(HIDE)
  398. X#define STATIC    static
  399. X#else
  400. X#define STATIC    /* NULL */
  401. X#endif    /* !defined(HIDE) */
  402. X
  403. X#if    !defined(CONST)
  404. X#if    defined(__STDC__)
  405. X#define CONST    const
  406. X#else
  407. X#define CONST
  408. X#endif    /* defined(__STDC__) */
  409. X#endif    /* !defined(CONST) */
  410. X
  411. X
  412. X#define MEM_INC        64
  413. X#define SCREEN_INC    256
  414. X
  415. X#define DISPOSE(p)    free((char *)(p))
  416. X#define NEW(T, c)    \
  417. X    ((T *)malloc((unsigned int)(sizeof (T) * (c))))
  418. X#define RENEW(p, T, c)    \
  419. X    (p = (T *)realloc((char *)(p), (unsigned int)(sizeof (T) * (c))))
  420. X#define COPYFROMTO(new, p, len)    \
  421. X    (void)memcpy((char *)(new), (char *)(p), (int)(len))
  422. X
  423. X
  424. X/*
  425. X**  Variables and routines internal to this package.
  426. X*/
  427. Xextern int    rl_eof;
  428. Xextern int    rl_erase;
  429. Xextern int    rl_intr;
  430. Xextern int    rl_kill;
  431. Xextern int    rl_quit;
  432. Xextern char    *rl_complete();
  433. Xextern int    rl_list_possib();
  434. Xextern void    rl_ttyset();
  435. Xextern void    rl_add_slash();
  436. X
  437. X#if    !defined(HAVE_STDLIB)
  438. Xextern char    *getenv();
  439. Xextern char    *malloc();
  440. Xextern char    *realloc();
  441. Xextern char    *memcpy();
  442. Xextern char    *strcat();
  443. Xextern char    *strchr();
  444. Xextern char    *strrchr();
  445. Xextern char    *strcpy();
  446. Xextern char    *strdup();
  447. Xextern int    strcmp();
  448. Xextern int    strlen();
  449. Xextern int    strncmp();
  450. X#endif    /* !defined(HAVE_STDLIB) */
  451. END_OF_FILE
  452.   if test 1622 -ne `wc -c <'editline.h'`; then
  453.     echo shar: \"'editline.h'\" unpacked with wrong size!
  454.   fi
  455.   # end of 'editline.h'
  456. fi
  457. if test -f 'unix.h' -a "${1}" != "-c" ; then 
  458.   echo shar: Will not clobber existing file \"'unix.h'\"
  459. else
  460.   echo shar: Extracting \"'unix.h'\" \(432 characters\)
  461.   sed "s/^X//" >'unix.h' <<'END_OF_FILE'
  462. X/*  $Revision: 1.1 $
  463. X**
  464. X**  Editline system header file for Unix.
  465. X*/
  466. X
  467. X#define CRLF        "\r\n"
  468. X#define FORWARD        STATIC
  469. X
  470. X#include <sys/types.h>
  471. X#include <sys/stat.h>
  472. X
  473. X#if    defined(USE_DIRENT)
  474. X#include <dirent.h>
  475. Xtypedef struct dirent    DIRENTRY;
  476. X#else
  477. X#include <sys/dir.h>
  478. Xtypedef struct direct    DIRENTRY;
  479. X#endif    /* defined(USE_DIRENT) */
  480. X
  481. X#if    !defined(S_ISDIR)
  482. X#define S_ISDIR(m)        (((m) & S_IFMT) == S_IFDIR)
  483. X#endif    /* !defined(S_ISDIR) */
  484. END_OF_FILE
  485.   if test 432 -ne `wc -c <'unix.h'`; then
  486.     echo shar: \"'unix.h'\" unpacked with wrong size!
  487.   fi
  488.   # end of 'unix.h'
  489. fi
  490. if test -f 'editline.c' -a "${1}" != "-c" ; then 
  491.   echo shar: Will not clobber existing file \"'editline.c'\"
  492. else
  493.   echo shar: Extracting \"'editline.c'\" \(22520 characters\)
  494.   sed "s/^X//" >'editline.c' <<'END_OF_FILE'
  495. X/*  $Revision: 1.4 $
  496. X**
  497. X**  Main editing routines for editline library.
  498. X*/
  499. X#include "editline.h"
  500. X#include <ctype.h>
  501. X
  502. X/*
  503. X**  Manifest constants.
  504. X*/
  505. X#define SCREEN_WIDTH    80
  506. X#define SCREEN_ROWS    24
  507. X#define NO_ARG        (-1)
  508. X#define DEL        127
  509. X#define CTL(x)        ((x) & 0x1F)
  510. X#define ISCTL(x)    ((x) && (x) < ' ')
  511. X#define UNCTL(x)    ((x) + 64)
  512. X#define META(x)        ((x) | 0x80)
  513. X#define ISMETA(x)    ((x) & 0x80)
  514. X#define UNMETA(x)    ((x) & 0x7F)
  515. X#if    !defined(HIST_SIZE)
  516. X#define HIST_SIZE    20
  517. X#endif    /* !defined(HIST_SIZE) */
  518. X
  519. X/*
  520. X**  Command status codes.
  521. X*/
  522. Xtypedef enum _STATUS {
  523. X    CSdone, CSeof, CSmove, CSdispatch, CSstay
  524. X} STATUS;
  525. X
  526. X/*
  527. X**  The type of case-changing to perform.
  528. X*/
  529. Xtypedef enum _CASE {
  530. X    TOupper, TOlower
  531. X} CASE;
  532. X
  533. X/*
  534. X**  Key to command mapping.
  535. X*/
  536. Xtypedef struct _KEYMAP {
  537. X    CHAR    Key;
  538. X    STATUS    (*Function)();
  539. X} KEYMAP;
  540. X
  541. X/*
  542. X**  Command history structure.
  543. X*/
  544. Xtypedef struct _HISTORY {
  545. X    int        Size;
  546. X    int        Pos;
  547. X    CHAR    *Lines[HIST_SIZE];
  548. X} HISTORY;
  549. X
  550. X/*
  551. X**  Globals.
  552. X*/
  553. Xint        rl_eof;
  554. Xint        rl_erase;
  555. Xint        rl_intr;
  556. Xint        rl_kill;
  557. X
  558. XSTATIC CHAR        NIL[] = "";
  559. XSTATIC CONST CHAR    *Input = NIL;
  560. XSTATIC CHAR        *Line;
  561. XSTATIC CONST char    *Prompt;
  562. XSTATIC CHAR        *Yanked;
  563. XSTATIC char        *Screen;
  564. XSTATIC char        NEWLINE[]= CRLF;
  565. XSTATIC HISTORY        H;
  566. Xint        rl_quit;
  567. XSTATIC int        Repeat;
  568. XSTATIC int        End;
  569. XSTATIC int        Mark;
  570. XSTATIC int        OldPoint;
  571. XSTATIC int        Point;
  572. XSTATIC int        PushBack;
  573. XSTATIC int        Pushed;
  574. XFORWARD KEYMAP        Map[33];
  575. XFORWARD KEYMAP        MetaMap[16];
  576. XSTATIC SIZE_T        Length;
  577. XSTATIC SIZE_T        ScreenCount;
  578. XSTATIC SIZE_T        ScreenSize;
  579. XSTATIC char        *backspace;
  580. XSTATIC int        TTYwidth;
  581. XSTATIC int        TTYrows;
  582. X
  583. X/* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */
  584. Xint        rl_meta_chars = 1;
  585. X
  586. X/*
  587. X**  Declarations.
  588. X*/
  589. XSTATIC CHAR    *editinput();
  590. Xextern int    read();
  591. Xextern int    write();
  592. X#if    defined(USE_TERMCAP)
  593. Xextern char    *getenv();
  594. Xextern char    *tgetstr();
  595. Xextern int    tgetent();
  596. X#endif    /* defined(USE_TERMCAP) */
  597. X
  598. X/*
  599. X**  TTY input/output functions.
  600. X*/
  601. X
  602. XSTATIC void
  603. XTTYflush()
  604. X{
  605. X    if (ScreenCount) {
  606. X    (void)write(1, Screen, ScreenCount);
  607. X    ScreenCount = 0;
  608. X    }
  609. X}
  610. X
  611. XSTATIC void
  612. XTTYput(c)
  613. X    CHAR    c;
  614. X{
  615. X    Screen[ScreenCount] = c;
  616. X    if (++ScreenCount >= ScreenSize - 1) {
  617. X    ScreenSize += SCREEN_INC;
  618. X    RENEW(Screen, char, ScreenSize);
  619. X    }
  620. X}
  621. X
  622. XSTATIC void
  623. XTTYputs(p)
  624. X    CHAR    *p;
  625. X{
  626. X    while (*p)
  627. X    TTYput(*p++);
  628. X}
  629. X
  630. XSTATIC void
  631. XTTYshow(c)
  632. X    CHAR    c;
  633. X{
  634. X    if (c == DEL) {
  635. X    TTYput('^');
  636. X    TTYput('?');
  637. X    }
  638. X    else if (ISCTL(c)) {
  639. X    TTYput('^');
  640. X    TTYput(UNCTL(c));
  641. X    }
  642. X    else if (rl_meta_chars && ISMETA(c)) {
  643. X    TTYput('M');
  644. X    TTYput('-');
  645. X    TTYput(UNMETA(c));
  646. X    }
  647. X    else
  648. X    TTYput(c);
  649. X}
  650. X
  651. XSTATIC void
  652. XTTYstring(p)
  653. X    CHAR    *p;
  654. X{
  655. X    while (*p)
  656. X    TTYshow(*p++);
  657. X}
  658. X
  659. XSTATIC unsigned int
  660. XTTYget()
  661. X{
  662. X    CHAR    c;
  663. X
  664. X    TTYflush();
  665. X    if (Pushed) {
  666. X    Pushed = 0;
  667. X    return PushBack;
  668. X    }
  669. X    if (*Input)
  670. X    return *Input++;
  671. X    return read(0, &c, (SIZE_T)1) == 1 ? c : EOF;
  672. X}
  673. X
  674. X#define TTYback()    (backspace ? TTYputs((CHAR *)backspace) : TTYput('\b'))
  675. X
  676. XSTATIC void
  677. XTTYbackn(n)
  678. X    int        n;
  679. X{
  680. X    while (--n >= 0)
  681. X    TTYback();
  682. X}
  683. X
  684. XSTATIC void
  685. XTTYinfo()
  686. X{
  687. X    static int        init;
  688. X#if    defined(USE_TERMCAP)
  689. X    char        *term;
  690. X    char        buff[2048];
  691. X    char        *bp;
  692. X#endif    /* defined(USE_TERMCAP) */
  693. X#if    defined(TIOCGWINSZ)
  694. X    struct winsize    W;
  695. X#endif    /* defined(TIOCGWINSZ) */
  696. X
  697. X    if (init) {
  698. X#if    defined(TIOCGWINSZ)
  699. X    /* Perhaps we got resized. */
  700. X    if (ioctl(0, TIOCGWINSZ, &W) >= 0
  701. X     && W.ws_col > 0 && W.ws_row > 0) {
  702. X        TTYwidth = (int)W.ws_col;
  703. X        TTYrows = (int)W.ws_row;
  704. X    }
  705. X#endif    /* defined(TIOCGWINSZ) */
  706. X    return;
  707. X    }
  708. X    init++;
  709. X
  710. X    TTYwidth = TTYrows = 0;
  711. X#if    defined(USE_TERMCAP)
  712. X    bp = &buff[0];
  713. X    if ((term = getenv("TERM")) == NULL)
  714. X    term = "dumb";
  715. X    if (tgetent(buff, term) < 0) {
  716. X       TTYwidth = SCREEN_WIDTH;
  717. X       TTYrows = SCREEN_ROWS;
  718. X       return;
  719. X    }
  720. X    backspace = tgetstr("le", &bp);
  721. X    TTYwidth = tgetnum("co");
  722. X    TTYrows = tgetnum("li");
  723. X#endif    /* defined(USE_TERMCAP) */
  724. X
  725. X#if    defined(TIOCGWINSZ)
  726. X    if (ioctl(0, TIOCGWINSZ, &W) >= 0) {
  727. X    TTYwidth = (int)W.ws_col;
  728. X    TTYrows = (int)W.ws_row;
  729. X    }
  730. X#endif    /* defined(TIOCGWINSZ) */
  731. X
  732. X    if (TTYwidth <= 0 || TTYrows <= 0) {
  733. X    TTYwidth = SCREEN_WIDTH;
  734. X    TTYrows = SCREEN_ROWS;
  735. X    }
  736. X}
  737. X
  738. X
  739. X/*
  740. X**  Print an array of words in columns.
  741. X*/
  742. XSTATIC void
  743. Xcolumns(ac, av)
  744. X    int        ac;
  745. X    CHAR    **av;
  746. X{
  747. X    CHAR    *p;
  748. X    int        i;
  749. X    int        j;
  750. X    int        k;
  751. X    int        len;
  752. X    int        skip;
  753. X    int        longest;
  754. X    int        cols;
  755. X
  756. X    /* Find longest name, determine column count from that. */
  757. X    for (longest = 0, i = 0; i < ac; i++)
  758. X    if ((j = strlen((char *)av[i])) > longest)
  759. X        longest = j;
  760. X    cols = TTYwidth / (longest + 3);
  761. X
  762. X    TTYputs((CHAR *)NEWLINE);
  763. X    for (skip = ac / cols + 1, i = 0; i < skip; i++) {
  764. X    for (j = i; j < ac; j += skip) {
  765. X        for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++)
  766. X        TTYput(*p);
  767. X        if (j + skip < ac)
  768. X        while (++len < longest + 3)
  769. X            TTYput(' ');
  770. X    }
  771. X    TTYputs((CHAR *)NEWLINE);
  772. X    }
  773. X}
  774. X
  775. XSTATIC void
  776. Xreposition()
  777. X{
  778. X    int        i;
  779. X    CHAR    *p;
  780. X
  781. X    TTYput('\r');
  782. X    TTYputs((CHAR *)Prompt);
  783. X    for (i = Point, p = Line; --i >= 0; p++)
  784. X    TTYshow(*p);
  785. X}
  786. X
  787. XSTATIC void
  788. Xleft(Change)
  789. X    STATUS    Change;
  790. X{
  791. X    TTYback();
  792. X    if (Point) {
  793. X    if (ISCTL(Line[Point - 1]))
  794. X        TTYback();
  795. X        else if (rl_meta_chars && ISMETA(Line[Point - 1])) {
  796. X        TTYback();
  797. X        TTYback();
  798. X    }
  799. X    }
  800. X    if (Change == CSmove)
  801. X    Point--;
  802. X}
  803. X
  804. XSTATIC void
  805. Xright(Change)
  806. X    STATUS    Change;
  807. X{
  808. X    TTYshow(Line[Point]);
  809. X    if (Change == CSmove)
  810. X    Point++;
  811. X}
  812. X
  813. XSTATIC STATUS
  814. Xring_bell()
  815. X{
  816. X    TTYput('\07');
  817. X    TTYflush();
  818. X    return CSstay;
  819. X}
  820. X
  821. XSTATIC STATUS
  822. Xdo_macro(c)
  823. X    unsigned int    c;
  824. X{
  825. X    CHAR        name[4];
  826. X
  827. X    name[0] = '_';
  828. X    name[1] = c;
  829. X    name[2] = '_';
  830. X    name[3] = '\0';
  831. X
  832. X    if ((Input = (CHAR *)getenv((char *)name)) == NULL) {
  833. X    Input = NIL;
  834. X    return ring_bell();
  835. X    }
  836. X    return CSstay;
  837. X}
  838. X
  839. XSTATIC STATUS
  840. Xdo_forward(move)
  841. X    STATUS    move;
  842. X{
  843. X    int        i;
  844. X    CHAR    *p;
  845. X
  846. X    i = 0;
  847. X    do {
  848. X    p = &Line[Point];
  849. X    for ( ; Point < End && (*p == ' ' || !isalnum(*p)); Point++, p++)
  850. X        if (move == CSmove)
  851. X        right(CSstay);
  852. X
  853. X    for (; Point < End && isalnum(*p); Point++, p++)
  854. X        if (move == CSmove)
  855. X        right(CSstay);
  856. X
  857. X    if (Point == End)
  858. X        break;
  859. X    } while (++i < Repeat);
  860. X
  861. X    return CSstay;
  862. X}
  863. X
  864. XSTATIC STATUS
  865. Xdo_case(type)
  866. X    CASE    type;
  867. X{
  868. X    int        i;
  869. X    int        end;
  870. X    int        count;
  871. X    CHAR    *p;
  872. X
  873. X    (void)do_forward(CSstay);
  874. X    if (OldPoint != Point) {
  875. X    if ((count = Point - OldPoint) < 0)
  876. X        count = -count;
  877. X    Point = OldPoint;
  878. X    if ((end = Point + count) > End)
  879. X        end = End;
  880. X    for (i = Point, p = &Line[i]; i < end; i++, p++) {
  881. X        if (type == TOupper) {
  882. X        if (islower(*p))
  883. X            *p = toupper(*p);
  884. X        }
  885. X        else if (isupper(*p))
  886. X        *p = tolower(*p);
  887. X        right(CSmove);
  888. X    }
  889. X    }
  890. X    return CSstay;
  891. X}
  892. X
  893. XSTATIC STATUS
  894. Xcase_down_word()
  895. X{
  896. X    return do_case(TOlower);
  897. X}
  898. X
  899. XSTATIC STATUS
  900. Xcase_up_word()
  901. X{
  902. X    return do_case(TOupper);
  903. X}
  904. X
  905. XSTATIC void
  906. Xceol()
  907. X{
  908. X    int        extras;
  909. X    int        i;
  910. X    CHAR    *p;
  911. X
  912. X    for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) {
  913. X    TTYput(' ');
  914. X    if (ISCTL(*p)) {
  915. X        TTYput(' ');
  916. X        extras++;
  917. X    }
  918. X    else if (rl_meta_chars && ISMETA(*p)) {
  919. X        TTYput(' ');
  920. X        TTYput(' ');
  921. X        extras += 2;
  922. X    }
  923. X    }
  924. X
  925. X    for (i += extras; i > Point; i--)
  926. X    TTYback();
  927. X}
  928. X
  929. XSTATIC void
  930. Xclear_line()
  931. X{
  932. X    Point = -strlen(Prompt);
  933. X    TTYput('\r');
  934. X    ceol();
  935. X    Point = 0;
  936. X    End = 0;
  937. X    Line[0] = '\0';
  938. X}
  939. X
  940. XSTATIC STATUS
  941. Xinsert_string(p)
  942. X    CHAR    *p;
  943. X{
  944. X    SIZE_T    len;
  945. X    int        i;
  946. X    CHAR    *new;
  947. X    CHAR    *q;
  948. X
  949. X    len = strlen((char *)p);
  950. X    if (End + len >= Length) {
  951. X    if ((new = NEW(CHAR, Length + len + MEM_INC)) == NULL)
  952. X        return CSstay;
  953. X    if (Length) {
  954. X        COPYFROMTO(new, Line, Length);
  955. X        DISPOSE(Line);
  956. X    }
  957. X    Line = new;
  958. X    Length += len + MEM_INC;
  959. X    }
  960. X
  961. X    for (q = &Line[Point], i = End - Point; --i >= 0; )
  962. X    q[len + i] = q[i];
  963. X    COPYFROMTO(&Line[Point], p, len);
  964. X    End += len;
  965. X    Line[End] = '\0';
  966. X    TTYstring(&Line[Point]);
  967. X    Point += len;
  968. X
  969. X    return Point == End ? CSstay : CSmove;
  970. X}
  971. X
  972. X
  973. XSTATIC CHAR *
  974. Xnext_hist()
  975. X{
  976. X    return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos];
  977. X}
  978. X
  979. XSTATIC CHAR *
  980. Xprev_hist()
  981. X{
  982. X    return H.Pos == 0 ? NULL : H.Lines[--H.Pos];
  983. X}
  984. X
  985. XSTATIC STATUS
  986. Xdo_insert_hist(p)
  987. X    CHAR    *p;
  988. X{
  989. X    if (p == NULL)
  990. X    return ring_bell();
  991. X    Point = 0;
  992. X    reposition();
  993. X    ceol();
  994. X    End = 0;
  995. X    return insert_string(p);
  996. X}
  997. X
  998. XSTATIC STATUS
  999. Xdo_hist(move)
  1000. X    CHAR    *(*move)();
  1001. X{
  1002. X    CHAR    *p;
  1003. X    int        i;
  1004. X
  1005. X    i = 0;
  1006. X    do {
  1007. X    if ((p = (*move)()) == NULL)
  1008. X        return ring_bell();
  1009. X    } while (++i < Repeat);
  1010. X    return do_insert_hist(p);
  1011. X}
  1012. X
  1013. XSTATIC STATUS
  1014. Xh_next()
  1015. X{
  1016. X    return do_hist(next_hist);
  1017. X}
  1018. X
  1019. XSTATIC STATUS
  1020. Xh_prev()
  1021. X{
  1022. X    return do_hist(prev_hist);
  1023. X}
  1024. X
  1025. XSTATIC STATUS
  1026. Xh_first()
  1027. X{
  1028. X    return do_insert_hist(H.Lines[H.Pos = 0]);
  1029. X}
  1030. X
  1031. XSTATIC STATUS
  1032. Xh_last()
  1033. X{
  1034. X    return do_insert_hist(H.Lines[H.Pos = H.Size - 1]);
  1035. X}
  1036. X
  1037. X/*
  1038. X**  Return zero if pat appears as a substring in text.
  1039. X*/
  1040. XSTATIC int
  1041. Xsubstrcmp(text, pat, len)
  1042. X    char    *text;
  1043. X    char    *pat;
  1044. X    int        len;
  1045. X{
  1046. X    CHAR    c;
  1047. X
  1048. X    if ((c = *pat) == '\0')
  1049. X        return *text == '\0';
  1050. X    for ( ; *text; text++)
  1051. X        if (*text == c && strncmp(text, pat, len) == 0)
  1052. X            return 0;
  1053. X    return 1;
  1054. X}
  1055. X
  1056. XSTATIC CHAR *
  1057. Xsearch_hist(search, move)
  1058. X    CHAR    *search;
  1059. X    CHAR    *(*move)();
  1060. X{
  1061. X    static CHAR    *old_search;
  1062. X    int        len;
  1063. X    int        pos;
  1064. X    int        (*match)();
  1065. X    char    *pat;
  1066. X
  1067. X    /* Save or get remembered search pattern. */
  1068. X    if (search && *search) {
  1069. X    if (old_search)
  1070. X        DISPOSE(old_search);
  1071. X    old_search = (CHAR *)strdup((char *)search);
  1072. X    }
  1073. X    else {
  1074. X    if (old_search == NULL || *old_search == '\0')
  1075. X            return NULL;
  1076. X    search = old_search;
  1077. X    }
  1078. X
  1079. X    /* Set up pattern-finder. */
  1080. X    if (*search == '^') {
  1081. X    match = strncmp;
  1082. X    pat = (char *)(search + 1);
  1083. X    }
  1084. X    else {
  1085. X    match = substrcmp;
  1086. X    pat = (char *)search;
  1087. X    }
  1088. X    len = strlen(pat);
  1089. X
  1090. X    for (pos = H.Pos; (*move)() != NULL; )
  1091. X    if ((*match)((char *)H.Lines[H.Pos], pat, len) == 0)
  1092. X            return H.Lines[H.Pos];
  1093. X    H.Pos = pos;
  1094. X    return NULL;
  1095. X}
  1096. X
  1097. XSTATIC STATUS
  1098. Xh_search()
  1099. X{
  1100. X    static int    Searching;
  1101. X    CONST char    *old_prompt;
  1102. X    CHAR    *(*move)();
  1103. X    CHAR    *p;
  1104. X
  1105. X    if (Searching)
  1106. X    return ring_bell();
  1107. X    Searching = 1;
  1108. X
  1109. X    clear_line();
  1110. X    old_prompt = Prompt;
  1111. X    Prompt = "Search: ";
  1112. X    TTYputs((CHAR *)Prompt);
  1113. X    move = Repeat == NO_ARG ? prev_hist : next_hist;
  1114. X    p = search_hist(editinput(), move);
  1115. X    clear_line();
  1116. X    Prompt = old_prompt;
  1117. X    TTYputs((CHAR *)Prompt);
  1118. X
  1119. X    Searching = 0;
  1120. X    return do_insert_hist(p);
  1121. X}
  1122. X
  1123. XSTATIC STATUS
  1124. Xfd_char()
  1125. X{
  1126. X    int        i;
  1127. X
  1128. X    i = 0;
  1129. X    do {
  1130. X    if (Point >= End)
  1131. X        break;
  1132. X    right(CSmove);
  1133. X    } while (++i < Repeat);
  1134. X    return CSstay;
  1135. X}
  1136. X
  1137. XSTATIC void
  1138. Xsave_yank(begin, i)
  1139. X    int        begin;
  1140. X    int        i;
  1141. X{
  1142. X    if (Yanked) {
  1143. X    DISPOSE(Yanked);
  1144. X    Yanked = NULL;
  1145. X    }
  1146. X
  1147. X    if (i < 1)
  1148. X    return;
  1149. X
  1150. X    if ((Yanked = NEW(CHAR, (SIZE_T)i + 1)) != NULL) {
  1151. X    COPYFROMTO(Yanked, &Line[begin], i);
  1152. X    Yanked[i] = '\0';
  1153. X    }
  1154. X}
  1155. X
  1156. XSTATIC STATUS
  1157. Xdelete_string(count)
  1158. X    int        count;
  1159. X{
  1160. X    int        i;
  1161. X    CHAR    *p;
  1162. X
  1163. X    if (count <= 0 || End == Point)
  1164. X    return ring_bell();
  1165. X
  1166. X    if (count == 1 && Point == End - 1) {
  1167. X    /* Optimize common case of delete at end of line. */
  1168. X    End--;
  1169. X    p = &Line[Point];
  1170. X    i = 1;
  1171. X    TTYput(' ');
  1172. X    if (ISCTL(*p)) {
  1173. X        i = 2;
  1174. X        TTYput(' ');
  1175. X    }
  1176. X    else if (rl_meta_chars && ISMETA(*p)) {
  1177. X        i = 3;
  1178. X        TTYput(' ');
  1179. X        TTYput(' ');
  1180. X    }
  1181. X    TTYbackn(i);
  1182. X    *p = '\0';
  1183. X    return CSmove;
  1184. X    }
  1185. X    if (Point + count > End && (count = End - Point) <= 0)
  1186. X    return CSstay;
  1187. X
  1188. X    if (count > 1)
  1189. X    save_yank(Point, count);
  1190. X
  1191. X    for (p = &Line[Point], i = End - (Point + count) + 1; --i >= 0; p++)
  1192. X    p[0] = p[count];
  1193. X    ceol();
  1194. X    End -= count;
  1195. X    TTYstring(&Line[Point]);
  1196. X    return CSmove;
  1197. X}
  1198. X
  1199. XSTATIC STATUS
  1200. Xbk_char()
  1201. X{
  1202. X    int        i;
  1203. X
  1204. X    i = 0;
  1205. X    do {
  1206. X    if (Point == 0)
  1207. X        break;
  1208. X    left(CSmove);
  1209. X    } while (++i < Repeat);
  1210. X
  1211. X    return CSstay;
  1212. X}
  1213. X
  1214. XSTATIC STATUS
  1215. Xbk_del_char()
  1216. X{
  1217. X    int        i;
  1218. X
  1219. X    i = 0;
  1220. X    do {
  1221. X    if (Point == 0)
  1222. X        break;
  1223. X    left(CSmove);
  1224. X    } while (++i < Repeat);
  1225. X
  1226. X    return delete_string(i);
  1227. X}
  1228. X
  1229. XSTATIC STATUS
  1230. Xredisplay()
  1231. X{
  1232. X    TTYputs((CHAR *)NEWLINE);
  1233. X    TTYputs((CHAR *)Prompt);
  1234. X    TTYstring(Line);
  1235. X    return CSmove;
  1236. X}
  1237. X
  1238. XSTATIC STATUS
  1239. Xkill_line()
  1240. X{
  1241. X    int        i;
  1242. X
  1243. X    if (Repeat != NO_ARG) {
  1244. X    if (Repeat < Point) {
  1245. X        i = Point;
  1246. X        Point = Repeat;
  1247. X        reposition();
  1248. X        (void)delete_string(i - Point);
  1249. X    }
  1250. X    else if (Repeat > Point) {
  1251. X        right(CSmove);
  1252. X        (void)delete_string(Repeat - Point - 1);
  1253. X    }
  1254. X    return CSmove;
  1255. X    }
  1256. X
  1257. X    save_yank(Point, End - Point);
  1258. X    Line[Point] = '\0';
  1259. X    ceol();
  1260. X    End = Point;
  1261. X    return CSstay;
  1262. X}
  1263. X
  1264. XSTATIC STATUS
  1265. Xinsert_char(c)
  1266. X    int        c;
  1267. X{
  1268. X    STATUS    s;
  1269. X    CHAR    buff[2];
  1270. X    CHAR    *p;
  1271. X    CHAR    *q;
  1272. X    int        i;
  1273. X
  1274. X    if (Repeat == NO_ARG || Repeat < 2) {
  1275. X    buff[0] = c;
  1276. X    buff[1] = '\0';
  1277. X    return insert_string(buff);
  1278. X    }
  1279. X
  1280. X    if ((p = NEW(CHAR, Repeat + 1)) == NULL)
  1281. X    return CSstay;
  1282. X    for (i = Repeat, q = p; --i >= 0; )
  1283. X    *q++ = c;
  1284. X    *q = '\0';
  1285. X    Repeat = 0;
  1286. X    s = insert_string(p);
  1287. X    DISPOSE(p);
  1288. X    return s;
  1289. X}
  1290. X
  1291. XSTATIC STATUS
  1292. Xmeta()
  1293. X{
  1294. X    unsigned int    c;
  1295. X    KEYMAP        *kp;
  1296. X
  1297. X    if ((c = TTYget()) == EOF)
  1298. X    return CSeof;
  1299. X#if    defined(ANSI_ARROWS)
  1300. X    /* Also include VT-100 arrows. */
  1301. X    if (c == '[' || c == 'O')
  1302. X    switch (c = TTYget()) {
  1303. X    default:    return ring_bell();
  1304. X    case EOF:    return CSeof;
  1305. X    case 'A':    return h_prev();
  1306. X    case 'B':    return h_next();
  1307. X    case 'C':    return fd_char();
  1308. X    case 'D':    return bk_char();
  1309. X    }
  1310. X#endif    /* defined(ANSI_ARROWS) */
  1311. X
  1312. X    if (isdigit(c)) {
  1313. X    for (Repeat = c - '0'; (c = TTYget()) != EOF && isdigit(c); )
  1314. X        Repeat = Repeat * 10 + c - '0';
  1315. X    Pushed = 1;
  1316. X    PushBack = c;
  1317. X    return CSstay;
  1318. X    }
  1319. X
  1320. X    if (isupper(c))
  1321. X    return do_macro(c);
  1322. X    for (OldPoint = Point, kp = MetaMap; kp->Function; kp++)
  1323. X    if (kp->Key == c)
  1324. X        return (*kp->Function)();
  1325. X
  1326. X    return ring_bell();
  1327. X}
  1328. X
  1329. XSTATIC STATUS
  1330. Xemacs(c)
  1331. X    unsigned int    c;
  1332. X{
  1333. X    STATUS        s;
  1334. X    KEYMAP        *kp;
  1335. X
  1336. X    if (ISMETA(c)) {
  1337. X    Pushed = 1;
  1338. X    PushBack = UNMETA(c);
  1339. X    return meta();
  1340. X    }
  1341. X    for (kp = Map; kp->Function; kp++)
  1342. X    if (kp->Key == c)
  1343. X        break;
  1344. X    s = kp->Function ? (*kp->Function)() : insert_char((int)c);
  1345. X    if (!Pushed)
  1346. X    /* No pushback means no repeat count; hacky, but true. */
  1347. X    Repeat = NO_ARG;
  1348. X    return s;
  1349. X}
  1350. X
  1351. XSTATIC STATUS
  1352. XTTYspecial(c)
  1353. X    unsigned int    c;
  1354. X{
  1355. X    if (ISMETA(c))
  1356. X    return CSdispatch;
  1357. X
  1358. X    if (c == rl_erase || c == DEL)
  1359. X    return bk_del_char();
  1360. X    if (c == rl_kill) {
  1361. X    if (Point != 0) {
  1362. X        Point = 0;
  1363. X        reposition();
  1364. X    }
  1365. X    Repeat = NO_ARG;
  1366. X    return kill_line();
  1367. X    }
  1368. X    if (c == rl_intr || c == rl_quit) {
  1369. X    Point = End = 0;
  1370. X    Line[0] = '\0';
  1371. X    return redisplay();
  1372. X    }
  1373. X    if (c == rl_eof && Point == 0 && End == 0)
  1374. X    return CSeof;
  1375. X
  1376. X    return CSdispatch;
  1377. X}
  1378. X
  1379. XSTATIC CHAR *
  1380. Xeditinput()
  1381. X{
  1382. X    unsigned int    c;
  1383. X
  1384. X    Repeat = NO_ARG;
  1385. X    OldPoint = Point = Mark = End = 0;
  1386. X    Line[0] = '\0';
  1387. X
  1388. X    while ((c = TTYget()) != EOF)
  1389. X    switch (TTYspecial(c)) {
  1390. X    case CSdone:
  1391. X        return Line;
  1392. X    case CSeof:
  1393. X        return NULL;
  1394. X    case CSmove:
  1395. X        reposition();
  1396. X        break;
  1397. X    case CSdispatch:
  1398. X        switch (emacs(c)) {
  1399. X        case CSdone:
  1400. X        return Line;
  1401. X        case CSeof:
  1402. X        return NULL;
  1403. X        case CSmove:
  1404. X        reposition();
  1405. X        break;
  1406. X        case CSdispatch:
  1407. X        case CSstay:
  1408. X        break;
  1409. X        }
  1410. X        break;
  1411. X    case CSstay:
  1412. X        break;
  1413. X    }
  1414. X    return NULL;
  1415. X}
  1416. X
  1417. XSTATIC void
  1418. Xhist_add(p)
  1419. X    CHAR    *p;
  1420. X{
  1421. X    int        i;
  1422. X
  1423. X    if ((p = (CHAR *)strdup((char *)p)) == NULL)
  1424. X    return;
  1425. X    if (H.Size < HIST_SIZE)
  1426. X    H.Lines[H.Size++] = p;
  1427. X    else {
  1428. X    DISPOSE(H.Lines[0]);
  1429. X    for (i = 0; i < HIST_SIZE - 1; i++)
  1430. X        H.Lines[i] = H.Lines[i + 1];
  1431. X    H.Lines[i] = p;
  1432. X    }
  1433. X    H.Pos = H.Size - 1;
  1434. X}
  1435. X
  1436. X/*
  1437. X**  For compatibility with FSF readline.
  1438. X*/
  1439. X/* ARGSUSED0 */
  1440. Xvoid
  1441. Xrl_reset_terminal(p)
  1442. X    char    *p;
  1443. X{
  1444. X}
  1445. X
  1446. Xvoid
  1447. Xrl_initialize()
  1448. X{
  1449. X}
  1450. X
  1451. Xchar *
  1452. Xreadline(prompt)
  1453. X    CONST char    *prompt;
  1454. X{
  1455. X    CHAR    *line;
  1456. X
  1457. X    if (Line == NULL) {
  1458. X    Length = MEM_INC;
  1459. X    if ((Line = NEW(CHAR, Length)) == NULL)
  1460. X        return NULL;
  1461. X    }
  1462. X
  1463. X    TTYinfo();
  1464. X    rl_ttyset(0);
  1465. X    hist_add(NIL);
  1466. X    ScreenSize = SCREEN_INC;
  1467. X    Screen = NEW(char, ScreenSize);
  1468. X    Prompt = prompt ? prompt : (char *)NIL;
  1469. X    TTYputs((CHAR *)Prompt);
  1470. X    if ((line = editinput()) != NULL) {
  1471. X    line = (CHAR *)strdup((char *)line);
  1472. X    TTYputs((CHAR *)NEWLINE);
  1473. X    TTYflush();
  1474. X    }
  1475. X    rl_ttyset(1);
  1476. X    DISPOSE(Screen);
  1477. X    DISPOSE(H.Lines[--H.Size]);
  1478. X    return (char *)line;
  1479. X}
  1480. X
  1481. Xvoid
  1482. Xadd_history(p)
  1483. X    char    *p;
  1484. X{
  1485. X    if (p == NULL || *p == '\0')
  1486. X    return;
  1487. X
  1488. X#if    defined(UNIQUE_HISTORY)
  1489. X    if (H.Pos && strcmp(p, H.Lines[H.Pos - 1]) == 0)
  1490. X        return;
  1491. X#endif    /* defined(UNIQUE_HISTORY) */
  1492. X    hist_add((CHAR *)p);
  1493. X}
  1494. X
  1495. X
  1496. XSTATIC STATUS
  1497. Xbeg_line()
  1498. X{
  1499. X    if (Point) {
  1500. X    Point = 0;
  1501. X    return CSmove;
  1502. X    }
  1503. X    return CSstay;
  1504. X}
  1505. X
  1506. XSTATIC STATUS
  1507. Xdel_char()
  1508. X{
  1509. X    return delete_string(Repeat == NO_ARG ? 1 : Repeat);
  1510. X}
  1511. X
  1512. XSTATIC STATUS
  1513. Xend_line()
  1514. X{
  1515. X    if (Point != End) {
  1516. X    Point = End;
  1517. X    return CSmove;
  1518. X    }
  1519. X    return CSstay;
  1520. X}
  1521. X
  1522. X/*
  1523. X**  Move back to the beginning of the current word and return an
  1524. X**  allocated copy of it.
  1525. X*/
  1526. XSTATIC CHAR *
  1527. Xfind_word()
  1528. X{
  1529. X    static char    SEPS[] = "#;&|^$=`'{}()<>\n\t ";
  1530. X    CHAR    *p;
  1531. X    CHAR    *new;
  1532. X    SIZE_T    len;
  1533. X
  1534. X    for (p = &Line[Point]; p > Line && strchr(SEPS, (char)p[-1]) == NULL; p--)
  1535. X    continue;
  1536. X    len = Point - (p - Line) + 1;
  1537. X    if ((new = NEW(CHAR, len)) == NULL)
  1538. X    return NULL;
  1539. X    COPYFROMTO(new, p, len);
  1540. X    new[len - 1] = '\0';
  1541. X    return new;
  1542. X}
  1543. X
  1544. XSTATIC STATUS
  1545. Xc_complete()
  1546. X{
  1547. X    CHAR    *p;
  1548. X    CHAR    *word;
  1549. X    int        unique;
  1550. X    STATUS    s;
  1551. X
  1552. X    word = find_word();
  1553. X    p = (CHAR *)rl_complete((char *)word, &unique);
  1554. X    if (word)
  1555. X    DISPOSE(word);
  1556. X    if (p && *p) {
  1557. X    s = insert_string(p);
  1558. X    if (!unique)
  1559. X        (void)ring_bell();
  1560. X    DISPOSE(p);
  1561. X    return s;
  1562. X    }
  1563. X    return ring_bell();
  1564. X}
  1565. X
  1566. XSTATIC STATUS
  1567. Xc_possible()
  1568. X{
  1569. X    CHAR    **av;
  1570. X    CHAR    *word;
  1571. X    int        ac;
  1572. X
  1573. X    word = find_word();
  1574. X    ac = rl_list_possib((char *)word, (char ***)&av);
  1575. X    if (word)
  1576. X    DISPOSE(word);
  1577. X    if (ac) {
  1578. X    columns(ac, av);
  1579. X    while (--ac >= 0)
  1580. X        DISPOSE(av[ac]);
  1581. X    DISPOSE(av);
  1582. X    return CSmove;
  1583. X    }
  1584. X    return ring_bell();
  1585. X}
  1586. X
  1587. XSTATIC STATUS
  1588. Xaccept_line()
  1589. X{
  1590. X    Line[End] = '\0';
  1591. X    return CSdone;
  1592. X}
  1593. X
  1594. XSTATIC STATUS
  1595. Xtranspose()
  1596. X{
  1597. X    CHAR    c;
  1598. X
  1599. X    if (Point) {
  1600. X    if (Point == End)
  1601. X        left(CSmove);
  1602. X    c = Line[Point - 1];
  1603. X    left(CSstay);
  1604. X    Line[Point - 1] = Line[Point];
  1605. X    TTYshow(Line[Point - 1]);
  1606. X    Line[Point++] = c;
  1607. X    TTYshow(c);
  1608. X    }
  1609. X    return CSstay;
  1610. X}
  1611. X
  1612. XSTATIC STATUS
  1613. Xquote()
  1614. X{
  1615. X    unsigned int    c;
  1616. X
  1617. X    return (c = TTYget()) == EOF ? CSeof : insert_char((int)c);
  1618. X}
  1619. X
  1620. XSTATIC STATUS
  1621. Xwipe()
  1622. X{
  1623. X    int        i;
  1624. X
  1625. X    if (Mark > End)
  1626. X    return ring_bell();
  1627. X
  1628. X    if (Point > Mark) {
  1629. X    i = Point;
  1630. X    Point = Mark;
  1631. X    Mark = i;
  1632. X    reposition();
  1633. X    }
  1634. X
  1635. X    return delete_string(Mark - Point);
  1636. X}
  1637. X
  1638. XSTATIC STATUS
  1639. Xmk_set()
  1640. X{
  1641. X    Mark = Point;
  1642. X    return CSstay;
  1643. X}
  1644. X
  1645. XSTATIC STATUS
  1646. Xexchange()
  1647. X{
  1648. X    unsigned int    c;
  1649. X
  1650. X    if ((c = TTYget()) != CTL('X'))
  1651. X    return c == EOF ? CSeof : ring_bell();
  1652. X
  1653. X    if ((c = Mark) <= End) {
  1654. X    Mark = Point;
  1655. X    Point = c;
  1656. X    return CSmove;
  1657. X    }
  1658. X    return CSstay;
  1659. X}
  1660. X
  1661. XSTATIC STATUS
  1662. Xyank()
  1663. X{
  1664. X    if (Yanked && *Yanked)
  1665. X    return insert_string(Yanked);
  1666. X    return CSstay;
  1667. X}
  1668. X
  1669. XSTATIC STATUS
  1670. Xcopy_region()
  1671. X{
  1672. X    if (Mark > End)
  1673. X    return ring_bell();
  1674. X
  1675. X    if (Point > Mark)
  1676. X    save_yank(Mark, Point - Mark);
  1677. X    else
  1678. X    save_yank(Point, Mark - Point);
  1679. X
  1680. X    return CSstay;
  1681. X}
  1682. X
  1683. XSTATIC STATUS
  1684. Xmove_to_char()
  1685. X{
  1686. X    unsigned int    c;
  1687. X    int            i;
  1688. X    CHAR        *p;
  1689. X
  1690. X    if ((c = TTYget()) == EOF)
  1691. X    return CSeof;
  1692. X    for (i = Point + 1, p = &Line[i]; i < End; i++, p++)
  1693. X    if (*p == c) {
  1694. X        Point = i;
  1695. X        return CSmove;
  1696. X    }
  1697. X    return CSstay;
  1698. X}
  1699. X
  1700. XSTATIC STATUS
  1701. Xfd_word()
  1702. X{
  1703. X    return do_forward(CSmove);
  1704. X}
  1705. X
  1706. XSTATIC STATUS
  1707. Xfd_kill_word()
  1708. X{
  1709. X    int        i;
  1710. X
  1711. X    (void)do_forward(CSstay);
  1712. X    if (OldPoint != Point) {
  1713. X    i = Point - OldPoint;
  1714. X    Point = OldPoint;
  1715. X    return delete_string(i);
  1716. X    }
  1717. X    return CSstay;
  1718. X}
  1719. X
  1720. XSTATIC STATUS
  1721. Xbk_word()
  1722. X{
  1723. X    int        i;
  1724. X    CHAR    *p;
  1725. X
  1726. X    i = 0;
  1727. X    do {
  1728. X    for (p = &Line[Point]; p > Line && !isalnum(p[-1]); p--)
  1729. X        left(CSmove);
  1730. X
  1731. X    for (; p > Line && p[-1] != ' ' && isalnum(p[-1]); p--)
  1732. X        left(CSmove);
  1733. X
  1734. X    if (Point == 0)
  1735. X        break;
  1736. X    } while (++i < Repeat);
  1737. X
  1738. X    return CSstay;
  1739. X}
  1740. X
  1741. XSTATIC STATUS
  1742. Xbk_kill_word()
  1743. X{
  1744. X    (void)bk_word();
  1745. X    if (OldPoint != Point)
  1746. X    return delete_string(OldPoint - Point);
  1747. X    return CSstay;
  1748. X}
  1749. X
  1750. XSTATIC int
  1751. Xargify(line, avp)
  1752. X    CHAR    *line;
  1753. X    CHAR    ***avp;
  1754. X{
  1755. X    CHAR    *c;
  1756. X    CHAR    **p;
  1757. X    CHAR    **new;
  1758. X    int        ac;
  1759. X    int        i;
  1760. X
  1761. X    i = MEM_INC;
  1762. X    if ((*avp = p = NEW(CHAR*, i))== NULL)
  1763. X     return 0;
  1764. X
  1765. X    for (c = line; isspace(*c); c++)
  1766. X    continue;
  1767. X    if (*c == '\n' || *c == '\0')
  1768. X    return 0;
  1769. X
  1770. X    for (ac = 0, p[ac++] = c; *c && *c != '\n'; ) {
  1771. X    if (isspace(*c)) {
  1772. X        *c++ = '\0';
  1773. X        if (*c && *c != '\n') {
  1774. X        if (ac + 1 == i) {
  1775. X            new = NEW(CHAR*, i + MEM_INC);
  1776. X            if (new == NULL) {
  1777. X            p[ac] = NULL;
  1778. X            return ac;
  1779. X            }
  1780. X            COPYFROMTO(new, p, i * sizeof (char **));
  1781. X            i += MEM_INC;
  1782. X            DISPOSE(p);
  1783. X            *avp = p = new;
  1784. X        }
  1785. X        p[ac++] = c;
  1786. X        }
  1787. X    }
  1788. X    else
  1789. X        c++;
  1790. X    }
  1791. X    *c = '\0';
  1792. X    p[ac] = NULL;
  1793. X    return ac;
  1794. X}
  1795. X
  1796. XSTATIC STATUS
  1797. Xlast_argument()
  1798. X{
  1799. X    CHAR    **av;
  1800. X    CHAR    *p;
  1801. X    STATUS    s;
  1802. X    int        ac;
  1803. X
  1804. X    if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL)
  1805. X    return ring_bell();
  1806. X
  1807. X    if ((p = (CHAR *)strdup((char *)p)) == NULL)
  1808. X    return CSstay;
  1809. X    ac = argify(p, &av);
  1810. X
  1811. X    if (Repeat != NO_ARG)
  1812. X    s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell();
  1813. X    else
  1814. X    s = ac ? insert_string(av[ac - 1]) : CSstay;
  1815. X
  1816. X    if (ac)
  1817. X    DISPOSE(av);
  1818. X    DISPOSE(p);
  1819. X    return s;
  1820. X}
  1821. X
  1822. XSTATIC KEYMAP    Map[33] = {
  1823. X    {    CTL('@'),    ring_bell    },
  1824. X    {    CTL('A'),    beg_line    },
  1825. X    {    CTL('B'),    bk_char        },
  1826. X    {    CTL('D'),    del_char    },
  1827. X    {    CTL('E'),    end_line    },
  1828. X    {    CTL('F'),    fd_char        },
  1829. X    {    CTL('G'),    ring_bell    },
  1830. X    {    CTL('H'),    bk_del_char    },
  1831. X    {    CTL('I'),    c_complete    },
  1832. X    {    CTL('J'),    accept_line    },
  1833. X    {    CTL('K'),    kill_line    },
  1834. X    {    CTL('L'),    redisplay    },
  1835. X    {    CTL('M'),    accept_line    },
  1836. X    {    CTL('N'),    h_next        },
  1837. X    {    CTL('O'),    ring_bell    },
  1838. X    {    CTL('P'),    h_prev        },
  1839. X    {    CTL('Q'),    ring_bell    },
  1840. X    {    CTL('R'),    h_search    },
  1841. X    {    CTL('S'),    ring_bell    },
  1842. X    {    CTL('T'),    transpose    },
  1843. X    {    CTL('U'),    ring_bell    },
  1844. X    {    CTL('V'),    quote        },
  1845. X    {    CTL('W'),    wipe        },
  1846. X    {    CTL('X'),    exchange    },
  1847. X    {    CTL('Y'),    yank        },
  1848. X    {    CTL('Z'),    ring_bell    },
  1849. X    {    CTL('['),    meta        },
  1850. X    {    CTL(']'),    move_to_char    },
  1851. X    {    CTL('^'),    ring_bell    },
  1852. X    {    CTL('_'),    ring_bell    },
  1853. X    {    0,        NULL        }
  1854. X};
  1855. X
  1856. XSTATIC KEYMAP    MetaMap[16]= {
  1857. X    {    CTL('H'),    bk_kill_word    },
  1858. X    {    DEL,        bk_kill_word    },
  1859. X    {    ' ',        mk_set    },
  1860. X    {    '.',        last_argument    },
  1861. X    {    '<',        h_first        },
  1862. X    {    '>',        h_last        },
  1863. X    {    '?',        c_possible    },
  1864. X    {    'b',        bk_word        },
  1865. X    {    'd',        fd_kill_word    },
  1866. X    {    'f',        fd_word        },
  1867. X    {    'l',        case_down_word    },
  1868. X    {    'u',        case_up_word    },
  1869. X    {    'y',        yank        },
  1870. X    {    'w',        copy_region    },
  1871. X    {    0,        NULL        }
  1872. X};
  1873. END_OF_FILE
  1874.   if test 22520 -ne `wc -c <'editline.c'`; then
  1875.     echo shar: \"'editline.c'\" unpacked with wrong size!
  1876.   fi
  1877.   # end of 'editline.c'
  1878. fi
  1879. if test -f 'complete.c' -a "${1}" != "-c" ; then 
  1880.   echo shar: Will not clobber existing file \"'complete.c'\"
  1881. else
  1882.   echo shar: Extracting \"'complete.c'\" \(4109 characters\)
  1883.   sed "s/^X//" >'complete.c' <<'END_OF_FILE'
  1884. X/*  $Revision: 1.3 $
  1885. X**
  1886. X**  History and file completion functions for editline library.
  1887. X*/
  1888. X#include "editline.h"
  1889. X
  1890. X
  1891. X#if    defined(NEED_STRDUP)
  1892. X/*
  1893. X**  Return an allocated copy of a string.
  1894. X*/
  1895. Xchar *
  1896. Xstrdup(p)
  1897. X    char    *p;
  1898. X{
  1899. X    char    *new;
  1900. X
  1901. X    if ((new = NEW(char, strlen(p) + 1)) != NULL)
  1902. X    (void)strcpy(new, p);
  1903. X    return new;
  1904. X}
  1905. X#endif    /* defined(NEED_STRDUP) */
  1906. X
  1907. X/*
  1908. X**  strcmp-like sorting predicate for qsort.
  1909. X*/
  1910. XSTATIC int
  1911. Xcompare(p1, p2)
  1912. X    CONST void    *p1;
  1913. X    CONST void    *p2;
  1914. X{
  1915. X    CONST char    **v1;
  1916. X    CONST char    **v2;
  1917. X
  1918. X    v1 = (CONST char **)p1;
  1919. X    v2 = (CONST char **)p2;
  1920. X    return strcmp(*v1, *v2);
  1921. X}
  1922. X
  1923. X/*
  1924. X**  Fill in *avp with an array of names that match file, up to its length.
  1925. X**  Ignore . and .. .
  1926. X*/
  1927. XSTATIC int
  1928. XFindMatches(dir, file, avp)
  1929. X    char    *dir;
  1930. X    char    *file;
  1931. X    char    ***avp;
  1932. X{
  1933. X    char    **av;
  1934. X    char    **new;
  1935. X    char    *p;
  1936. X    DIR        *dp;
  1937. X    DIRENTRY    *ep;
  1938. X    SIZE_T    ac;
  1939. X    SIZE_T    len;
  1940. X
  1941. X    if ((dp = opendir(dir)) == NULL)
  1942. X    return 0;
  1943. X
  1944. X    av = NULL;
  1945. X    ac = 0;
  1946. X    len = strlen(file);
  1947. X    while ((ep = readdir(dp)) != NULL) {
  1948. X    p = ep->d_name;
  1949. X    if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0')))
  1950. X        continue;
  1951. X    if (len && strncmp(p, file, len) != 0)
  1952. X        continue;
  1953. X
  1954. X    if ((ac % MEM_INC) == 0) {
  1955. X        if ((new = NEW(char*, ac + MEM_INC)) == NULL)
  1956. X        break;
  1957. X        if (ac) {
  1958. X        COPYFROMTO(new, av, ac * sizeof (char **));
  1959. X        DISPOSE(av);
  1960. X        }
  1961. X        *avp = av = new;
  1962. X    }
  1963. X
  1964. X    if ((av[ac] = strdup(p)) == NULL) {
  1965. X        if (ac == 0)
  1966. X        DISPOSE(av);
  1967. X        break;
  1968. X    }
  1969. X    ac++;
  1970. X    }
  1971. X
  1972. X    /* Clean up and return. */
  1973. X    (void)closedir(dp);
  1974. X    if (ac)
  1975. X    qsort(av, ac, sizeof (char **), compare);
  1976. X    return ac;
  1977. X}
  1978. X
  1979. X/*
  1980. X**  Split a pathname into allocated directory and trailing filename parts.
  1981. X*/
  1982. XSTATIC int
  1983. XSplitPath(path, dirpart, filepart)
  1984. X    char    *path;
  1985. X    char    **dirpart;
  1986. X    char    **filepart;
  1987. X{
  1988. X    static char    DOT[] = ".";
  1989. X    char    *dpart;
  1990. X    char    *fpart;
  1991. X
  1992. X    if ((fpart = strrchr(path, '/')) == NULL) {
  1993. X    if ((dpart = strdup(DOT)) == NULL)
  1994. X        return -1;
  1995. X    if ((fpart = strdup(path)) == NULL) {
  1996. X        DISPOSE(dpart);
  1997. X        return -1;
  1998. X    }
  1999. X    }
  2000. X    else {
  2001. X    if ((dpart = strdup(path)) == NULL)
  2002. X        return -1;
  2003. X    dpart[fpart - path] = '\0';
  2004. X    if ((fpart = strdup(++fpart)) == NULL) {
  2005. X        DISPOSE(dpart);
  2006. X        return -1;
  2007. X    }
  2008. X    }
  2009. X    *dirpart = dpart;
  2010. X    *filepart = fpart;
  2011. X    return 0;
  2012. X}
  2013. X
  2014. X/*
  2015. X**  Attempt to complete the pathname, returning an allocated copy.
  2016. X**  Fill in *unique if we completed it, or set it to 0 if ambiguous.
  2017. X*/
  2018. Xchar *
  2019. Xrl_complete(pathname, unique)
  2020. X    char    *pathname;
  2021. X    int        *unique;
  2022. X{
  2023. X    char    **av;
  2024. X    char    *dir;
  2025. X    char    *file;
  2026. X    char    *new;
  2027. X    char    *p;
  2028. X    SIZE_T    ac;
  2029. X    SIZE_T    end;
  2030. X    SIZE_T    i;
  2031. X    SIZE_T    j;
  2032. X    SIZE_T    len;
  2033. X
  2034. X    if (SplitPath(pathname, &dir, &file) < 0)
  2035. X    return NULL;
  2036. X    if ((ac = FindMatches(dir, file, &av)) == 0) {
  2037. X    DISPOSE(dir);
  2038. X    DISPOSE(file);
  2039. X    return NULL;
  2040. X    }
  2041. X
  2042. X    p = NULL;
  2043. X    len = strlen(file);
  2044. X    if (ac == 1) {
  2045. X    /* Exactly one match -- finish it off. */
  2046. X    *unique = 1;
  2047. X    j = strlen(av[0]) - len + 2;
  2048. X    if ((p = NEW(char, j + 1)) != NULL) {
  2049. X        COPYFROMTO(p, av[0] + len, j);
  2050. X        if ((new = NEW(char, strlen(dir) + strlen(av[0]) + 2)) != NULL) {
  2051. X        (void)strcpy(new, dir);
  2052. X        (void)strcat(new, "/");
  2053. X        (void)strcat(new, av[0]);
  2054. X        rl_add_slash(new, p);
  2055. X        DISPOSE(new);
  2056. X        }
  2057. X    }
  2058. X    }
  2059. X    else {
  2060. X    *unique = 0;
  2061. X    if (len) {
  2062. X        /* Find largest matching substring. */
  2063. X        for (i = len, end = strlen(av[0]); i < end; i++)
  2064. X        for (j = 1; j < ac; j++)
  2065. X            if (av[0][i] != av[j][i])
  2066. X            goto breakout;
  2067. X  breakout:
  2068. X        if (i > len) {
  2069. X        j = i - len + 1;
  2070. X        if ((p = NEW(char, j)) != NULL) {
  2071. X            COPYFROMTO(p, av[0] + len, j);
  2072. X            p[j - 1] = '\0';
  2073. X        }
  2074. X        }
  2075. X    }
  2076. X    }
  2077. X
  2078. X    /* Clean up and return. */
  2079. X    DISPOSE(dir);
  2080. X    DISPOSE(file);
  2081. X    for (i = 0; i < ac; i++)
  2082. X    DISPOSE(av[i]);
  2083. X    DISPOSE(av);
  2084. X    return p;
  2085. X}
  2086. X
  2087. X/*
  2088. X**  Return all possible completions.
  2089. X*/
  2090. Xint
  2091. Xrl_list_possib(pathname, avp)
  2092. X    char    *pathname;
  2093. X    char    ***avp;
  2094. X{
  2095. X    char    *dir;
  2096. X    char    *file;
  2097. X    int        ac;
  2098. X
  2099. X    if (SplitPath(pathname, &dir, &file) < 0)
  2100. X    return 0;
  2101. X    ac = FindMatches(dir, file, avp);
  2102. X    DISPOSE(dir);
  2103. X    DISPOSE(file);
  2104. X    return ac;
  2105. X}
  2106. END_OF_FILE
  2107.   if test 4109 -ne `wc -c <'complete.c'`; then
  2108.     echo shar: \"'complete.c'\" unpacked with wrong size!
  2109.   fi
  2110.   # end of 'complete.c'
  2111. fi
  2112. if test -f 'sysunix.c' -a "${1}" != "-c" ; then 
  2113.   echo shar: Will not clobber existing file \"'sysunix.c'\"
  2114. else
  2115.   echo shar: Extracting \"'sysunix.c'\" \(1798 characters\)
  2116.   sed "s/^X//" >'sysunix.c' <<'END_OF_FILE'
  2117. X/*  $Revision: 1.1 $
  2118. X**
  2119. X**  Unix system-dependant routines for editline library.
  2120. X*/
  2121. X#include "editline.h"
  2122. X
  2123. X#if    defined(HAVE_TCGETATTR)
  2124. X#include <termios.h>
  2125. X
  2126. Xvoid
  2127. Xrl_ttyset(Reset)
  2128. X    int                Reset;
  2129. X{
  2130. X    static struct termios    old;
  2131. X    struct termios        new;
  2132. X
  2133. X    if (Reset == 0) {
  2134. X    (void)tcgetattr(0, &old);
  2135. X    rl_erase = old.c_cc[VERASE];
  2136. X    rl_kill = old.c_cc[VKILL];
  2137. X    rl_eof = old.c_cc[VEOF];
  2138. X    rl_intr = old.c_cc[VINTR];
  2139. X    rl_quit = old.c_cc[VQUIT];
  2140. X
  2141. X    new = old;
  2142. X    new.c_cc[VINTR] = -1;
  2143. X    new.c_cc[VQUIT] = -1;
  2144. X    new.c_lflag &= ~(ECHO | ICANON);
  2145. X    new.c_iflag &= ~(ISTRIP | INPCK);
  2146. X    new.c_cc[VMIN] = 1;
  2147. X    new.c_cc[VTIME] = 0;
  2148. X    (void)tcsetattr(0, TCSANOW, &new);
  2149. X    }
  2150. X    else
  2151. X    (void)tcsetattr(0, TCSANOW, &old);
  2152. X}
  2153. X
  2154. X#else
  2155. X#include <sgtty.h>
  2156. X
  2157. Xvoid
  2158. Xrl_ttyset(Reset)
  2159. X    int                Reset;
  2160. X{
  2161. X    static struct sgttyb    old_sgttyb;
  2162. X    static struct tchars    old_tchars;
  2163. X    struct sgttyb        new_sgttyb;
  2164. X    struct tchars        new_tchars;
  2165. X
  2166. X    if (Reset == 0) {
  2167. X    (void)ioctl(0, TIOCGETP, &old_sgttyb);
  2168. X    rl_erase = old_sgttyb.sg_erase;
  2169. X    rl_kill = old_sgttyb.sg_kill;
  2170. X
  2171. X    (void)ioctl(0, TIOCGETC, &old_tchars);
  2172. X    rl_eof = old_tchars.t_eofc;
  2173. X    rl_intr = old_tchars.t_intrc;
  2174. X    rl_quit = old_tchars.t_quitc;
  2175. X
  2176. X    new_sgttyb = old_sgttyb;
  2177. X    new_sgttyb.sg_flags &= ~ECHO;
  2178. X    new_sgttyb.sg_flags |= RAW;
  2179. X#if    defined(PASS8)
  2180. X    new_sgttyb.sg_flags |= PASS8;
  2181. X#endif    /* defined(PASS8) */
  2182. X    (void)ioctl(0, TIOCSETP, &new_sgttyb);
  2183. X
  2184. X    new_tchars = old_tchars;
  2185. X    new_tchars.t_intrc = -1;
  2186. X    new_tchars.t_quitc = -1;
  2187. X    (void)ioctl(0, TIOCSETC, &new_tchars);
  2188. X    }
  2189. X    else {
  2190. X    (void)ioctl(0, TIOCSETP, &old_sgttyb);
  2191. X    (void)ioctl(0, TIOCSETC, &old_tchars);
  2192. X    }
  2193. X}
  2194. X#endif    /* defined(HAVE_TCGETATTR) */
  2195. X
  2196. Xvoid
  2197. Xrl_add_slash(path, p)
  2198. X    char    *path;
  2199. X    char    *p;
  2200. X{
  2201. X    struct stat    Sb;
  2202. X
  2203. X    if (stat(path, &Sb) >= 0)
  2204. X    (void)strcat(p, S_ISDIR(Sb.st_mode) ? "/" : " ");
  2205. X}
  2206. END_OF_FILE
  2207.   if test 1798 -ne `wc -c <'sysunix.c'`; then
  2208.     echo shar: \"'sysunix.c'\" unpacked with wrong size!
  2209.   fi
  2210.   # end of 'sysunix.c'
  2211. fi
  2212. if test -f 'testit.c' -a "${1}" != "-c" ; then 
  2213.   echo shar: Will not clobber existing file \"'testit.c'\"
  2214. else
  2215.   echo shar: Extracting \"'testit.c'\" \(1024 characters\)
  2216.   sed "s/^X//" >'testit.c' <<'END_OF_FILE'
  2217. X/*  $Revision: 1.2 $
  2218. X**
  2219. X**  A "micro-shell" to test editline library.
  2220. X**  If given any arguments, commands aren't executed.
  2221. X*/
  2222. X#include <stdio.h>
  2223. X#if    defined(HAVE_STDLIB)
  2224. X#include <stdlib.h>
  2225. X#endif    /* defined(HAVE_STDLIB) */
  2226. X
  2227. Xextern char    *readline();
  2228. Xextern void    add_history();
  2229. X
  2230. X#if    !defined(HAVE_STDLIB)
  2231. Xextern int    chdir();
  2232. Xextern int    free();
  2233. Xextern int    strncmp();
  2234. Xextern int    system();
  2235. Xextern void    exit();
  2236. X#endif    /* !defined(HAVE_STDLIB) */
  2237. X
  2238. X
  2239. X#if    defined(NEED_PERROR)
  2240. Xvoid
  2241. Xperror(s)
  2242. X    char    *s;
  2243. X{
  2244. X    extern int    errno;
  2245. X
  2246. X    (voidf)printf(stderr, "%s: error %d\n", s, errno);
  2247. X}
  2248. X#endif    /* defined(NEED_PERROR) */
  2249. X
  2250. X
  2251. X/* ARGSUSED1 */
  2252. Xint
  2253. Xmain(ac, av)
  2254. X    int        ac;
  2255. X    char    *av[];
  2256. X{
  2257. X    char    *p;
  2258. X    int        doit;
  2259. X
  2260. X    doit = ac == 1;
  2261. X    while ((p = readline("testit> ")) != NULL) {
  2262. X    (void)printf("\t\t\t|%s|\n", p);
  2263. X    if (doit)
  2264. X        if (strncmp(p, "cd ", 3) == 0) {
  2265. X        if (chdir(&p[3]) < 0)
  2266. X            perror(&p[3]);
  2267. X        }
  2268. X        else if (system(p) != 0)
  2269. X        perror(p);
  2270. X    add_history(p);
  2271. X    free(p);
  2272. X    }
  2273. X    exit(0);
  2274. X    /* NOTREACHED */
  2275. X}
  2276. END_OF_FILE
  2277.   if test 1024 -ne `wc -c <'testit.c'`; then
  2278.     echo shar: \"'testit.c'\" unpacked with wrong size!
  2279.   fi
  2280.   # end of 'testit.c'
  2281. fi
  2282. if test -f 'Make.os9' -a "${1}" != "-c" ; then 
  2283.   echo shar: Will not clobber existing file \"'Make.os9'\"
  2284. else
  2285.   echo shar: Extracting \"'Make.os9'\" \(348 characters\)
  2286.   sed "s/^X//" >'Make.os9' <<'END_OF_FILE'
  2287. X##  $Revision: 1.2 $
  2288. X##
  2289. X##  OS-9 makefile for editline library.
  2290. X##
  2291. X
  2292. X.SUFFIXES:
  2293. X
  2294. XRFILES    = editline.r complete.r sysos9.r
  2295. X
  2296. X%.r:        %.c
  2297. X    cc68 -r -Dstrchr=index -Dstrrchr=rindex -DNEED_STRDUP -DSYS_OS9 $*.c
  2298. X
  2299. Xtestit:        testit.r editline.lib
  2300. X    cc68 -f=testit testit.r -l=editline.lib
  2301. X
  2302. X$(RFILES):    $(RFILES:%.r=%.c)
  2303. X
  2304. Xeditline.lib:    $(RFILES)
  2305. X    cat $(RFILES) >$@
  2306. END_OF_FILE
  2307.   if test 348 -ne `wc -c <'Make.os9'`; then
  2308.     echo shar: \"'Make.os9'\" unpacked with wrong size!
  2309.   fi
  2310.   # end of 'Make.os9'
  2311. fi
  2312. if test -f 'os9.h' -a "${1}" != "-c" ; then 
  2313.   echo shar: Will not clobber existing file \"'os9.h'\"
  2314. else
  2315.   echo shar: Extracting \"'os9.h'\" \(174 characters\)
  2316.   sed "s/^X//" >'os9.h' <<'END_OF_FILE'
  2317. X/*  $Revision: 1.1 $
  2318. X**
  2319. X**  Editline system header file for OS-9 (on 68k).
  2320. X*/
  2321. X
  2322. X#define CRLF        "\r\l"
  2323. X#define FORWARD        extern
  2324. X
  2325. X#include <dir.h>
  2326. Xtypedef struct direct    DIRENTRY;
  2327. END_OF_FILE
  2328.   if test 174 -ne `wc -c <'os9.h'`; then
  2329.     echo shar: \"'os9.h'\" unpacked with wrong size!
  2330.   fi
  2331.   # end of 'os9.h'
  2332. fi
  2333. if test -f 'sysos9.c' -a "${1}" != "-c" ; then 
  2334.   echo shar: Will not clobber existing file \"'sysos9.c'\"
  2335. else
  2336.   echo shar: Extracting \"'sysos9.c'\" \(1120 characters\)
  2337.   sed "s/^X//" >'sysos9.c' <<'END_OF_FILE'
  2338. X/*  $Revision: 1.1 $
  2339. X**
  2340. X**  OS-9 system-dependant routines for editline library.
  2341. X*/
  2342. X#include "editline.h"
  2343. X#include <sgstat.h>
  2344. X#include <modes.h>
  2345. X
  2346. X
  2347. Xvoid
  2348. Xrl_ttyset(Reset)
  2349. X    int            Reset;
  2350. X{
  2351. X    static struct sgbuf    old;
  2352. X    struct sgbuf    new;
  2353. X
  2354. X
  2355. X    if (Reset == 0) {
  2356. X        _gs_opt(0, &old);
  2357. X        _gs_opt(0, &new);
  2358. X        new.sg_backsp = 0;    new.sg_delete = 0;    new.sg_echo = 0;
  2359. X        new.sg_alf = 0;        new.sg_nulls = 0;    new.sg_pause = 0;
  2360. X        new.sg_page = 0;    new.sg_bspch = 0;    new.sg_dlnch = 0;
  2361. X        new.sg_eorch = 0;    new.sg_eofch = 0;    new.sg_rlnch = 0;
  2362. X        new.sg_dulnch = 0;    new.sg_psch = 0;    new.sg_kbich = 0;
  2363. X        new.sg_kbach = 0;    new.sg_bsech = 0;    new.sg_bellch = 0;
  2364. X        new.sg_xon = 0;        new.sg_xoff = 0;    new.sg_tabcr = 0;
  2365. X        new.sg_tabsiz = 0;
  2366. X        _ss_opt(0, &new);
  2367. X        rl_erase = old.sg_bspch;
  2368. X        rl_kill = old.sg_dlnch;
  2369. X        rl_eof = old.sg_eofch;
  2370. X        rl_intr = old.sg_kbich;
  2371. X        rl_quit = -1;
  2372. X    }
  2373. X    else
  2374. X        _ss_opt(0, &old);
  2375. X}
  2376. X
  2377. Xvoid
  2378. Xrl_add_slash(path, p)
  2379. X    char    *path;
  2380. X    char    *p;
  2381. X{
  2382. X    (void)strcat(p, access(path, S_IREAD | S_IFDIR) ? " " : "/");
  2383. X}
  2384. END_OF_FILE
  2385.   if test 1120 -ne `wc -c <'sysos9.c'`; then
  2386.     echo shar: \"'sysos9.c'\" unpacked with wrong size!
  2387.   fi
  2388.   # end of 'sysos9.c'
  2389. fi
  2390. echo shar: End of archive.
  2391. exit 0
  2392.  
  2393. exit 0 # Just in case...
  2394.