[alt.sources] command line editor

bogatko@lzga.ATT.COM (George Bogatko) (09/04/90)

HI:

	I recently had need for an command line editor for a test program.

	The ones available were either killing a fly with a shotgun, or
were so convoluted to use that they weren't worth the trouble.  Also
most inflated the program by 50% or more.

	So, I re-invented the wheel, and wrote this one.  It's 1/5 the
code and complexity of most that I've seen, and does exactly what I need
a simple one line editor to do.  I can insert, delete, characters,
jump from word to word, front of line, back of line, etc, plus a
50 line history in a ring buffer.  (You can hack the code to provide more 
history capacity if you need to.)

	It won't do what EMACS or VI will do, but since I rarely need
all of that in a test function, it suffices quite nicely.

	It avoids termcap or terminfo, so you don't have to worry about
that either. 

	To include it in your C program, do:

		str = edline("your prompt:  ");
		puts(str);

	I hope you can use it.

GB.

COMPILED/TESTED ON : Pyramid OSx (both S5 and BSD universes), Sys5.2, Sys5.3.

SYSTEM DEPENDANCES: 

makefile.s5
	Sys5.2 users (older VAX and Amdahl), If you get a warnings
	concerning 'sigset()', set -DNOSIGSET in the CFLAGS line.

makefile.bsd
	-DNOSIGSET has been set anyway.  I've left the "signal()" calls
	the same as in Sys5.  You may want to substitute something more
	'BSD-ish'.  Watch out for 'setjmp' in "edit.c".  It worked on
	the Pyramid, but I don't know what will happen on other machines.


******** CUT HERE ******** CUT HERE ******** CUT HERE ******** CUT HERE ******


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	edline.3
#	edline.c
#	edit.c
#	main.c
#	makefile.s5
#	makefile.bsd
# This archive created: Tue Sep  4 12:05:11 1990
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'edline.3'" '(2067 characters)'
if test -f 'edline.3'
then
       echo shar: "will not over-write existing file 'edline.3'"
else
sed 's/^      X//' << \SHAR_EOF > 'edline.3'
      X.TH EDLINE 3
      X.SH NAME
      Xedline - command line editor
      X.SH SYNOPSIS
      X.nf
      X.B "char *edline(prompt)
      X.B "char *prompt;
      X.SH DESCRIPTION
      X\fIEdline()\fP is a simple command line editor suitable for use in test programs and demos.
      XIt relys only on character writes and backspaces to position the cursor, and
      Xthus doesn't need any knowledge of what TERM setting you are using.
      X
      XThe function keeps a 50 line command history in a circular array.
      X.SH INPUT
      XThe editor uses the following keys for commands:
      X.TP 40
      XACCEPT LINE
      X.B <return>
      X.TP
      XAPPEND
      X.B a
      X.TP
      XDELETE A CHAR
      X.B x
      X.TP
      XREPLACE A CHAR
      X.B r
      X.TP
      XEND INSERT/APPEND MODE
      X.B ESC
      X.TP
      XERASE LINE AND START AGAIN
      X.B BREAK(break key - SIGINT)
      X.TP
      XINSERT
      X.B i
      X.TP
      XMOVE BACKWARD A WORD
      X.B b
      X.TP
      XMOVE DOWN A LINE
      X.B j
      X.TP
      XMOVE FORWARD A WORD
      X.B w
      X.TP
      XMOVE LEFT A CHAR
      X.B h
      X.TP
      XMOVE RIGHT A CHAR
      X.B l
      X.TP
      XMOVE TO BEGINNING OF LINE
      X.B 0
      X.TP
      XMOVE TO END OF LINE
      X.B $
      X.TP
      XMOVE UP A LINE
      X.B k
      X.SH FILES
      XThe history is kept in RAM.  There is no \fI.history\fP file.
      X.SH OUTPUT
      XThe return from
      X.I edline()
      Xis the entered string, or (char *)NULL if SIGQUIT was hit.
      X.SH TERMIO
      X.I ioctl
      Xis used to reset the terminal into RAW mode during the editing process.
      XBecause of this, SIGINT and SIGQUIT are trapped.  
      XNotice in the above chart that SIGINT is used to reset the line
      Xand start again. 
      XSIGQUIT will return (char *)NULL;
      X.bp
      X.SH EXAMPLE
      X.nf
      X.ft CW
      X#include <stdio.h>
      Xextern char *edline();
      X
      Xmain()
      X{
      Xchar *str;
      X	for(;;)
      X	{
      X		str = edline("prompt:  ");
      X		if( ! strcmp(str, "quit") || str == (char *)NULL )
      X			break;
      X		else
      X			printf("str: '%s'\\n",str);
      X	}
      X	return 0;
      X}
      X
      X.SH CAVEATS
      XA maximum of 78 - strlen(prompt) characters are allowed in any string.
      X
      XYou cannot SIGINT from 'edline()' once you have started.
      XUse SIGQUIT to break out, and trap for (char *)NULL;
      X
      XSIGINT and SIGQUIT are the only signals trapped by
      X.I edline().
      XAny others (core dumps, alarms etc.) will leave the function (i.e. your
      Xscreen) in a scrambled state.
      XIf you want more, you will need to change the source.
      X
      X.I assert(3)
      Xis used for memory allocation checking.
SHAR_EOF
if test 2067 -ne "`wc -c < 'edline.3'`"
then
       echo shar: "error transmitting 'edline.3'" '(should have been 2067 characters)'
fi
fi
echo shar: "extracting 'edline.c'" '(2949 characters)'
if test -f 'edline.c'
then
       echo shar: "will not over-write existing file 'edline.c'"
else
sed 's/^      X//' << \SHAR_EOF > 'edline.c'
      X/******************************************************************************
      X*                                                                             *
      X*                                  edline.c                                   *
      X*                                                                             *
      X******************************************************************************/
      X
      X/*--------------------------  INITIAL CODING DATE -----------------------------
      XTue Sep 12 09:19:55 EDT 1989 by George M. Bogatko
      X
      X--------------------------------  HEADER FILES  -----------------------------*/
      X#include <stdio.h>
      X#include <assert.h>
      X
      X/*------------------  TYPEDEF'S, DEFINES, STRUCTURE DEF'S  ------------------*/
      X#define BUFRSIZE 81
      X#define MAXSLOTS 50
      X
      X/*----------------  IMPORTED GLOBAL VARIABLE/FUNCTION DEF'S  ----------------*/
      Xextern int edit();
      X
      X/*----------------  EXPORTED GLOBAL VARIABLE/FUNCTION DEF'S  ----------------*/
      X
      X/*----------------  INTERNAL GLOBAL VARIABLE/FUNCTION DEF'S  ----------------*/
      X#ident "@(#)edline.c	2.5 9/4/90 - George M. Bogatko -"
      X
      X/*-----------------------------------------------------------------------------
      X
      XSYNOPSIS:
      X	char *edline(char *prompt)
      X
      XDESCRIPTION:
      X	EDLINE is the feeder function in the 'edline' command line editor.
      X
      X	It takes the prompt passed in and passes it along to 'edit()'
      X
      X	It also keeps a 50 line circular array of strings as a 'history'
      X	similar to 'ksh'.
      X
      XCAVEATS:
      X
      X=============================================================================*/
      X
      Xchar *edline(prompt)
      Xchar *prompt;
      X{
      Xint ret;
      X
      Xstatic char (*buf)[BUFRSIZE] = (char (*)[BUFRSIZE])NULL;
      Xstatic char *tbuf = (char *)NULL;
      Xstatic int curslot = 0;
      Xstatic int hit_the_top = 0;
      Xstatic int lastslot = 0;
      X
      X	if( buf == (char (*)[BUFRSIZE])NULL )
      X		assert( (buf = (char (*)[BUFRSIZE])calloc(MAXSLOTS, BUFRSIZE)) != (char (*)[BUFRSIZE])NULL );
      X
      X	if( tbuf == (char *)NULL )
      X		assert( (tbuf = (char *)calloc(BUFRSIZE, sizeof(char))) != (char *)NULL );
      X	for(ret = 0;;)
      X	{
      X		switch(ret)
      X		{
      X		case 255:
      X			strcpy(tbuf, " ");
      X			ret = edit(tbuf,prompt);
      X			break;
      X		case 254:
      X			putchar('\n');
      X			return (char *)NULL;
      X			break;
      X		case 0:
      X			*tbuf = '\0';
      X			ret = edit(tbuf,prompt);
      X			break;
      X		case '\n':
      X			if( *tbuf != '\0' )
      X			{
      X				strcpy(buf[lastslot], tbuf);
      X				if( ++lastslot >= MAXSLOTS )
      X				{
      X					hit_the_top = 1;
      X					lastslot = 0;
      X				}
      X				curslot = lastslot;
      X			}
      X			putchar('\n');
      X			return tbuf;
      X			break;
      X		case 'j':
      X			if( hit_the_top )
      X			{
      X				if( ++curslot >= MAXSLOTS )
      X					curslot = 0;
      X			}
      X			else
      X			{
      X				if( ++curslot >= lastslot )
      X					curslot = 0;
      X			}
      X
      X			strcpy(tbuf, buf[curslot]);
      X			ret = edit(tbuf,prompt);
      X			break;
      X		case 'k':
      X			if( --curslot < 0 )
      X			{
      X				if( hit_the_top )
      X				{
      X					curslot = MAXSLOTS-1;
      X				}
      X				else
      X					curslot = lastslot-1;
      X			}
      X
      X			strcpy(tbuf, buf[curslot]);
      X			ret = edit(tbuf,prompt);
      X			break;
      X		default:
      X			putchar(7);
      X			break;
      X		}
      X	}
      X}
SHAR_EOF
if test 2949 -ne "`wc -c < 'edline.c'`"
then
       echo shar: "error transmitting 'edline.c'" '(should have been 2949 characters)'
fi
fi
echo shar: "extracting 'edit.c'" '(8293 characters)'
if test -f 'edit.c'
then
       echo shar: "will not over-write existing file 'edit.c'"
else
sed 's/^      X//' << \SHAR_EOF > 'edit.c'
      X/******************************************************************************
      X*                                                                             *
      X*                                    edit.c                                   *
      X*                                                                             *
      X******************************************************************************/
      X
      X/*--------------------------  INITIAL CODING DATE -----------------------------
      XTue Sep 12 09:09:54 EDT 1989 by George M. Bogatko
      X
      X--------------------------------  HEADER FILES  -----------------------------*/
      X#include <stdio.h>
      X#include <signal.h>
      X#include <sys/types.h>
      X#include <sys/termio.h>
      X#include <setjmp.h>
      X#include <ctype.h>
      X
      X/*------------------  TYPEDEF'S, DEFINES, STRUCTURE DEF'S  ------------------*/
      X#define ESC 27
      X#define BELL write(1, &bell, 1)
      X#define CURBACK write(1, &curback, 1)
      X#define SPACE write(1, &space, 1)
      X#define PROMPT write(1, prompt, strlen(prompt))
      X
      X#ifdef NOSIGSET
      X#define sigset signal
      X#endif
      X
      X/*----------------  IMPORTED GLOBAL VARIABLE/FUNCTION DEF'S  ----------------*/
      X
      X/*----------------  EXPORTED GLOBAL VARIABLE/FUNCTION DEF'S  ----------------*/
      Xextern int edit();
      X
      X/*----------------  INTERNAL GLOBAL VARIABLE/FUNCTION DEF'S  ----------------*/
      X#ident "%W% %G% - George M. Bogatko -"
      X
      X/* static */ extern void sig_handle();
      Xstatic jmp_buf jumpbuf;
      Xstatic int lastlen; /* length of the last edited buffer, for blanking out */
      X
      X#ifdef NOSIGSET
      Xstatic int (*oldintsig)();
      Xstatic int (*oldquitsig)();
      X#else
      Xstatic void (*oldintsig)();
      Xstatic void (*oldquitsig)();
      X#endif
      X
      Xstatic char *spaces=
      X"                                                                           ";
      Xstatic char *backspaces="\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
      X
      X
      X/*-----------------------------------------------------------------------------
      X
      XSYNOPSIS:
      X	int edit(char *buf, char *prompt)
      X
      XDESCRIPTION:
      X
      X	EDIT is the workhorse of the 'edline' command line editor.  It
      X	takes a buffer of characters, and applies the following editing
      X	commands to it:
      X
      X	ACCEPT LINE 		 	<return>
      X	APPEND 				a
      X	DELETE A CHAR  		 	x
      X	REPLACE A CHAR  		r
      X	END INSERT/APPEND MODE 		ESC
      X	ERASE LINE AND START AGAIN 	BREAK(break key) or QUIT(ctrl-\)
      X	INSERT 		  		i
      X	MOVE BACKWARD A WORD 		b
      X	MOVE DOWN A LINE 		j
      X	MOVE FORWARD A WORD 		w
      X	MOVE LEFT A CHAR 		h
      X	MOVE RIGHT A CHAR 		l
      X	MOVE TO BEGINNING OF LINE	0
      X	MOVE TO END OF LINE 		$
      X	MOVE UP A LINE 			k
      X
      X	The function does NOT rely on any TERM setting, but does everything
      X	with writes and backspaces.
      X
      X	ioctl is used to set the terminal in RAW mode.  SIGINT and SIGQUIT are
      X	trapped to restore the previous settings.
      X
      X	The function returns the last character hit, or 255 if SIGINT or
      X	SIGQUIT are caught.
      X
      X
      XCAVEATS:
      X	Certain perverse combinations of commands given in a very fast
      X	sequence will produce strange characters.
      X
      X	This is usually called from 'edline()'
      X
      X	The maximum line length is 78 - strlen(prompt)
      X
      X=============================================================================*/
      Xint edit(buf, prompt)
      Xchar *buf;
      Xchar *prompt;
      X{
      Xunsigned char	
      X	*ps=0,		/* start of buffer */
      X	*pe=0,		/* end of buffer */
      X	*pc=0,		/* current place in buffer */
      X	*cp=0,		/* a 'current pointer' used in manipulations */
      X	bell = '\007',  /* BEEEEP!! */
      X	c = 0,		/* a temporary character holder */
      X	curback='\b',	/* backspace */
      X	gotofront = '\r', /* plain return */
      X	newline = '\n', /* plain newline */
      X	space = ' ';	/* space */
      X
      Xenum {first, next} time = next; /* for first time only things */
      X
      Xint	
      X	char_count = 0,
      X	eof = 0,
      X	erase_char = 0,
      X	fieldlen = 0,
      X	jmpret,
      X	maxlen = 78 - strlen(prompt);
      X
      Xstruct termio no_canon, canon;
      X
      X/*
      X * flush standard in and out so that any 'printf' or previous stdin
      X * requests are cleared out
      X */
      X	fflush(stdin);
      X	fflush(stdout);
      X/*
      X * set terminal for prompt input
      X */
      X	ioctl(0, TCGETA, &canon);
      X	no_canon = canon;
      X
      X	erase_char = canon.c_cc[2];
      X	eof = canon.c_cc[4];
      X
      X	no_canon.c_lflag &= ~(ICANON|ECHO|ECHOE);
      X	no_canon.c_cc[4] = 1;
      X	no_canon.c_cc[5] = 0;
      X
      X	ioctl(0, TCSETAW, &no_canon);
      X/*
      X * handle sigint sigquit
      X */
      X	oldintsig = sigset(SIGINT, sig_handle);
      X	oldquitsig = sigset(SIGQUIT, sig_handle); 
      X
      X	if( (jmpret = setjmp(jumpbuf)) != 0 )
      X	{
      X		if(jmpret == SIGINT)
      X			c = 255;
      X		if(jmpret == SIGQUIT)
      X			c = 254;
      X		goto abort;
      X	}
      X/*
      X * edit buffer
      X */
      X
      X/* DISPLAY BUFFER */
      X
      X	PROMPT;
      X	if( *buf )
      X	{
      X		fieldlen = char_count = strlen(buf);
      X		write(1,buf,char_count);
      X		if( lastlen > fieldlen )
      X			write(1,spaces,lastlen-fieldlen);
      X		write(1,&gotofront,1);
      X		PROMPT;
      X		if( *buf == ' ' )
      X		{
      X			*buf = '\0';
      X			char_count = 0;
      X			time = first;
      X		}
      X	}
      X	else
      X		time = first;
      X/*
      X * set pointers
      X */
      X	pc = ps = (unsigned char *)buf;
      X	pe = ps + strlen(buf);
      X
      X
      X	for(;;)
      X	{
      X/* 
      X * prime the pump by forcing 'insert' mode if this is the first time
      X * in the editor.
      X */
      X		if( time == first )
      X		{
      X			c = 'i';
      X			time = next;
      X		}
      X		else
      X			read(0, &c, 1);
      X
      X		switch(c)
      X		{
      X/* EXIT EDITING */
      X		case '\n':
      X			goto abort;
      X			break;
      X
      X/* END OF LINE */
      X		case '$':
      X			fieldlen = pe-(pc+1);
      X			write(1,pc,fieldlen);
      X			pc+=fieldlen;
      X			break;
      X
      X/* BEGINNING OF LINE */
      X		case '0':
      X			write(1, &gotofront, 1); 
      X			PROMPT;
      X			pc = ps;
      X			break;
      X
      X/* MOVE LEFT */
      X		case 'h':
      X			if( pc>ps )
      X			{
      X				CURBACK;
      X				pc--;
      X			}
      X			else
      X				BELL;
      X			break;
      X
      X/* INSERT MODE */
      X/*
      X * yes, there's some yank and put code here. shoot me
      X */
      X		case 'a':
      X			if(*ps != '\0')
      X				write(1, pc++, 1);
      X
      X		/* NO BREAK HERE -- FALL THRU */
      X
      X		case 'i':
      X			for(;;)
      X			{
      X				read(0, &c, 1);
      X
      X	/* END INSERT MODE */
      X				if( c == ESC )
      X				{
      X					if( pc > ps)
      X					{
      X						pc--;
      X						CURBACK;
      X					}
      X					break;
      X				}
      X	/* DELETE CHARACTER WITHIN INSERT MODE */
      X				else if( c == erase_char )
      X				{
      X					if( *ps == '\0' || pc <= ps )
      X					{
      X						pc = ps;
      X						BELL;
      X						continue;
      X					}
      X					else
      X					{
      X						pc--;
      X						CURBACK;
      X					}
      X
      X					for(cp = pc; *cp != '\0'; cp++)
      X					{
      X						*cp = *(cp+1);
      X					}
      X
      X					fieldlen=pe-pc;
      X					if(fieldlen)
      X						write(1,pc,fieldlen-1);
      X					SPACE;
      X					write(1,backspaces,fieldlen);
      X
      X					pe--;
      X					char_count--;
      X				}
      X	/* EXIT EDITING FROM INSERT MODE */
      X				else if ( c == '\n' )
      X					goto abort;
      X	/* GATHER CHARS IN INSERT MODE */
      X				else if( isalnum(c) || ispunct(c) || c == ' ' )
      X				{
      X					if( ++char_count >= maxlen )
      X					{
      X						BELL;
      X						char_count--;
      X						continue;
      X					}
      X					for(cp = pe; cp >= pc; cp--)
      X					{
      X						*(cp+1) = *cp;
      X					}
      X					*pc = c;
      X
      X					fieldlen=(pe-pc);
      X					write(1,pc,fieldlen+1);
      X					pc++;
      X					write(1,backspaces,fieldlen);
      X
      X					pe++;
      X				}
      X			}
      X			break;
      X
      X/* UP, DOWN A LINE -- command character returned to 'edline()' */
      X		case 'j':
      X		case 'k':
      X			goto abort;
      X			break;
      X
      X/* MOVE RIGHT */
      X		case 'l':
      X		case ' ':
      X
      X			if( *(pc+1) == '\0' )
      X				BELL;
      X			else
      X			{
      X				write(1, pc, 1);
      X				pc++;
      X			}
      X			break;
      X
      X/* FORWARD A WORD */
      X		case 'w':
      X			if( (pc+1) == pe )
      X				break;
      X			else
      X			{
      X				do
      X					write(1, pc++, 1);
      X				while( isalnum(*pc) && *(pc+1) != '\0' );
      X				if( *(pc+1) != '\0' )
      X					write(1, pc++, 1);
      X			}
      X			break;
      X
      X/* BACKWARD A WORD */
      X		case 'b':
      X			if( pc <= ps )
      X			{
      X				pc = ps;
      X				break;
      X			}
      X			else
      X			{
      X				do
      X				{
      X					CURBACK;
      X					pc--;
      X				}
      X				while( isalnum(*pc) && pc > ps );
      X				if( pc > ps )
      X				{
      X					CURBACK;
      X					pc--;
      X				}
      X			}
      X			break;
      X				
      X/* DELETE A CHAR */
      X		case 'x':
      X			if( *ps == '\0' || pc < ps )
      X			{
      X				pc = ps;
      X				BELL;
      X				break;
      X			}
      X
      X			for(cp = pc; *cp != '\0'; cp++)
      X			{
      X				*cp = *(cp+1);
      X			}
      X
      X
      X
      X			fieldlen=pe-pc;
      X			if(fieldlen)
      X				write(1,pc,fieldlen-1);
      X			SPACE;
      X			write(1,backspaces,fieldlen);
      X
      X			pe--;
      X			char_count--;
      X
      X			if( pc >= pe )
      X			{
      X				pc--;
      X				if( pc >= ps )
      X					CURBACK;
      X			}
      X
      X			break;
      X
      X/* REPLACE A CHAR */
      X		case 'r':
      X			read(0, &c, 1);
      X			if( c != ESC )
      X			{
      X				*pc = c;
      X				write(1, pc, 1);
      X				write(1,backspaces,1);
      X			}
      X			break;
      X
      X/* ERROR */
      X		default:
      X			BELL;
      X			break;
      X		}
      X	}
      Xabort:
      X/*
      X * clean up and return 
      X */
      X	write(1, &gotofront, 1); 
      X	ioctl(0, TCSETAW, &canon);
      X	sigset(SIGINT, oldintsig);
      X	sigset(SIGQUIT, oldquitsig);
      X
      X	lastlen=strlen(buf);
      X	return c;
      X}
      X
      Xstatic void sig_handle(sig)
      X{
      X	longjmp(jumpbuf, sig);
      X}
SHAR_EOF
if test 8293 -ne "`wc -c < 'edit.c'`"
then
       echo shar: "error transmitting 'edit.c'" '(should have been 8293 characters)'
fi
fi
echo shar: "extracting 'main.c'" '(907 characters)'
if test -f 'main.c'
then
       echo shar: "will not over-write existing file 'main.c'"
else
sed 's/^      X//' << \SHAR_EOF > 'main.c'
      X#include <stdio.h>
      Xextern char *edline();
      Xextern void edcommands();
      X
      Xmain()
      X{
      Xchar *str;
      X	for(;;)
      X	{
      X		str = edline("prompt:  ");
      X		if( ! strcmp(str, "quit") || (str == (char *)NULL) )
      X			break;
      X		else if( ! strcmp(str, "help") )
      X			edcommands();
      X		else
      X			printf("str: '%s'\n",str);
      X	}
      X	return 0;
      X}
      X
      Xvoid edcommands()
      X{
      Xstatic char *strs[] = {
      X"",
      X"ACCEPT LINE \t\t \t<return>",
      X"APPEND \t\t\t\ta",
      X"DELETE A CHAR  \t\t \tx",
      X"REPLACE A CHAR  \t\tr",
      X"END INSERT/APPEND MODE \t\tESC",
      X"ERASE LINE AND START AGAIN \tBREAK(break key)",
      X"INSERT \t\t  \t\ti",
      X"MOVE BACKWARD A WORD \t\tb",
      X"MOVE DOWN A LINE \t\tj",
      X"MOVE FORWARD A WORD \t\tw",
      X"MOVE LEFT A CHAR \t\th",
      X"MOVE RIGHT A CHAR \t\tl",
      X"MOVE TO BEGINNING OF LINE\t0",
      X"MOVE TO END OF LINE \t\t$",
      X"MOVE UP A LINE \t\t\tk",
      X"",
      X"LEAVE EDITOR \t\t\tquit",
      X"",
      X(char *)NULL
      X};
      X
      Xint i;
      X
      X	for(i=0;strs[i]!=(char *)NULL;i++)
      X		puts(strs[i]);
      X
      X	return;
      X}
SHAR_EOF
if test 907 -ne "`wc -c < 'main.c'`"
then
       echo shar: "error transmitting 'main.c'" '(should have been 907 characters)'
fi
fi
echo shar: "extracting 'makefile.s5'" '(259 characters)'
if test -f 'makefile.s5'
then
       echo shar: "will not over-write existing file 'makefile.s5'"
else
sed 's/^      X//' << \SHAR_EOF > 'makefile.s5'
      XCFLAGS=-I. -O
      XLIBS=-s
      X
      XLIBRARY=libedline.a
      X
      X.PRECIOUS:	$(LIBRARY)
      X
      XOBJS=\
      Xmain.o 
      X
      XOUTPUT=\
      Xedline
      X
      X$(OUTPUT):	$(OBJS) $(LIBRARY)
      X	cc -o $(OUTPUT) $(OBJS) $(LIBRARY) $(LIBS)
      X
      X$(LIBRARY):	$(LIBRARY)(edline.o) \
      X		$(LIBRARY)(edit.o)
      X		@echo $(LIBRARY) uptodate
SHAR_EOF
if test 259 -ne "`wc -c < 'makefile.s5'`"
then
       echo shar: "error transmitting 'makefile.s5'" '(should have been 259 characters)'
fi
fi
echo shar: "extracting 'makefile.bsd'" '(237 characters)'
if test -f 'makefile.bsd'
then
       echo shar: "will not over-write existing file 'makefile.bsd'"
else
sed 's/^      X//' << \SHAR_EOF > 'makefile.bsd'
      XCFLAGS=-I. -O -DNOSIGSET
      X
      XLIBRARY=libedline.a
      XLIBS=-s
      X
      XMOBJS=\
      Xmain.o 
      X
      XLOBJS=\
      Xedit.o \
      Xedline.o
      X
      Xedline:	$(MOBJS) $(LIBRARY)
      X	cc -o edline $(MOBJS) $(LIBRARY) $(LIBS)
      X
      X$(LIBRARY): $(LOBJS)
      X	ar rv $(LIBRARY) $(LOBJS)
      X	ranlib $(LIBRARY)
SHAR_EOF
if test 237 -ne "`wc -c < 'makefile.bsd'`"
then
       echo shar: "error transmitting 'makefile.bsd'" '(should have been 237 characters)'
fi
fi
exit 0
#	End of shell archive