v08i003: Georgia Tech 'se' Screen Editor

sources-request at mirror.UUCP sources-request at mirror.UUCP
Tue Jan 27 07:18:01 AEST 1987


Submitted by: emoryu1!arnold (Arnold D. Robbins)
Mod.sources: Volume 8, Issue 3
Archive-name: se/Part03


Here is the second release of the Georgia Tech Screen Editor, 'se'.
There were enough changes that a whole new posting is warranted.

Major Changes:
	All Georgia Tech specific stuff removed.
	It understands window size changes on 4.3BSD and ATT Unix PC/3B1
	Support for the shared library on the ATT Unix PC/3B1
	Considerable source code reorganization in certain files.

Enjoy,

Arnold Robbins

#! /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 the files:
#	scratch.c
#	screen.c
#	scriptse.1
#	scriptse.c
#	se.h
#	where
export PATH; PATH=/bin:$PATH
echo shar: extracting "'scratch.c'" '(11621 characters)'
if test -f 'scratch.c'
then
	echo shar: will not over-write existing file "'scratch.c'"
else
cat << \SHAR_EOF > 'scratch.c'
#ifndef lint
static char RCSid[] = "$Header: scratch.c,v 1.2 86/07/17 17:21:38 arnold Exp $";
#endif

/*
 * $Log:	scratch.c,v $
 * Revision 1.2  86/07/17  17:21:38  arnold
 * Calls to error() changed to reflect whether or not to coredump.
 * 
 * Revision 1.1  86/05/06  13:38:04  osadr
 * Initial revision
 * 
 * 
 */

/*
** scratch.c
**
** scratch file handling for se screen editor.
**
** If OLD_SCRATCH is defined, then this file will contain the
** original scratch file handling, based on linked lists,
** from the ratfor version of Software Tools.  This method is
** real good at moving lines around, but is poor for finding lines.
**
** If OLD_SCRATCH is not defined, which is the default, this file will use
** the line handling methodology presented in Software Tools In Pascal,
** *without* changing the way any of the routines are called.
**
** Bascially, the lines are always kept in order in the Buf array.
** Thus, lines 1 through 5 are in Buf[1] through Buf[5]. blkmove() and
** reverse() do the work of moving lines around in the buffer. The alloc()
** routine, therefore, always allocates the first empty slot, which will be
** at Lastln + 1, if there is room.
**
** Deleted lines are kept at the end of the buffer. Limbo points to the first
** line in the group of lines which were last deleted, or else Limbo == NOMORE.
**
** It is a very good idea to read the chapters on editing in BOTH editions of
** Software Tools, before trying to muck with this. It also helps to be a
** little bit off the wall....
**
** In fact, I would go as far as saying, "If you touch this, it will break.
** It is held together with chewing gum, scotch tape, and bobby pins."
** (Of course, you could always use OLD_SCRATCH, which definitely works.
** It just increases the size of the editor.)  So much for the old
** "Just replace the implementation of the underlying primitives..."
*/

#include "se.h"
#include "extern.h"

/* alloc --- allocate space for a new pointer block */


static LINEDESC *alloc (ptr)
register LINEDESC **ptr;
{
#ifdef OLD_SCRATCH	/* old way */
	if (Free == NOMORE)   /* no free list, expand into unallocated space */
	{
		if (Lastbf - Buf + BUFENT <= MAXBUF)   /* see if there's room */
		{
			*ptr = Lastbf;
			Lastbf += BUFENT;
		}
		else
			*ptr = NOMORE;		/* out of pointer space */
	}
	else	/* remove a block from free list */
	{
		*ptr = Free;
		Free = Free->Prevline;
	}
#else	/* new way */
	int limbo_index = Limbo - Buf;	/* use indices instead of pointers */
		/* N.B.: this statement is meaningless if Limbo == NOMORE */
		/* but if so, we don't use limbo_index anyway */

	if (Limbo == NOMORE)
		if (Lastln < (MAXBUF - 1) - 1)	/* dumb zero based indexing! */
			*ptr = &Buf[Lastln + 1];
		else
			*ptr = NOMORE;
	else if (limbo_index - Lastln > 1)
		*ptr = &Buf[Lastln + 1];
	else
		*ptr = NOMORE;
#endif

	return (*ptr);
}


/* bump --- advance line number and corresponding index simultaneously */

bump (line, ix, way)
int *line, way;
LINEDESC **ix;
{
	if (way == FORWARD)	/* increment line number */
	{
#ifdef OLD_SCRATCH
		*ix = (*ix)->Nextline;
		if (*ix == Line0)
			*line = 0;
		else
			(*line)++;
#else
		(*ix)++;
		if (*ix == &Buf[Lastln+1])
		{
			*line = 0;
			*ix = Line0;
		}
		else
			(*line)++;
#endif
	}
	else	/* decrement line number */
	{
		if (*ix == Line0)
			*line = Lastln;
		else
			(*line)--;
#ifdef OLD_SCRATCH
		*ix = (*ix)->Prevline;
#else
		if (*ix == Line0)
			*ix = &Buf[Lastln];
		else
			(*ix)--;
#endif
	}
}



/* closef --- close a file */

static closef (fd)
filedes fd;
{
	close (fd);
}




/* clrbuf --- purge scratch file */

clrbuf ()
{

	if (Lastln > 0)
		svdel (1, Lastln);

	closef (Scr);
	unlink (Scrname);
}



/* garbage_collect --- compress scratch file */

garbage_collect ()
{
	char new_name [MAXLINE];
	register int i, new_scrend;
	int new_fd;
	register LINEDESC *p;

	makscr (&new_fd, new_name);
	remark ("collecting garbage");
	new_scrend = 0;
#ifdef OLD_SCRATCH
	for (p = Limbo, i = 1; i <= Limcnt; p = p->Nextline, i++)
#else
	for (p = Limbo, i = 1; i <= Limcnt; p++, i++)
#endif
	{
		gtxt (p);
		seekf ((long) new_scrend * 8, new_fd);
		writef (Txt, (int) p->Lineleng, new_fd);
		p->Seekaddr = new_scrend;
		new_scrend += (p->Lineleng + 7) / 8;
	}
#ifdef OLD_SCRATCH
	for (p = Line0, i = 0; i <= Lastln; p = p->Nextline, i++)
#else
	for (p = Line0, i = 0; i <= Lastln; p++, i++)
#endif
	{
		gtxt (p);
		seekf ((long) new_scrend * 8, new_fd);
		writef (Txt, (int) p->Lineleng, new_fd);
		p->Seekaddr = new_scrend;
		new_scrend += (p->Lineleng + 7) / 8;
	}

	closef (Scr);
	unlink (Scrname);

	Scr = new_fd;
	sprintf (Scrname, "%s", new_name);
	Scrend = new_scrend;
	Lost_lines = 0;

	remark ("");
}



/* gettxt --- locate text for line, copy to txt */

LINEDESC *gettxt (line)
int line;
{
	register LINEDESC *k;
	LINEDESC *getind ();

	k = getind (line);
	gtxt (k);

	return (k);
}



/* gtxt --- retrieve a line from the scratch file */

gtxt (ptr)
register LINEDESC *ptr;
{
	int readf ();

	seekf ((long) ptr->Seekaddr * 8, Scr); /* position to start of file */
	/*
	 * rounded Seekaddr to 8 byte sections, giving larger
	 * buffer space for text (*8)
	 */

	return (readf (Txt, (int) ptr->Lineleng, Scr) - 1);
}



/* inject --- insert a new line after curln */

inject (lin)
register char lin [];
{
	register int i;
	int maklin ();
	register LINEDESC *k1, *k2;
	LINEDESC *k3;
	LINEDESC *getind ();

	for (i = 0; lin [i] != EOS; )
	{
		i = maklin (lin, i, &k3);       /* create a single line */
		if (i == ERR)
		{
			Errcode = ECANTINJECT;
			return (ERR);
		}
#ifdef OLD_SCRATCH
		k1 = getind (Curln);            /* get pointer to curln */
		k2 = k1-> Nextline;             /* get pointer to nextln */
		relink (k1, k3, k3, k2);        /* set pointers of new line */
		relink (k3, k2, k1, k3);        /* set pointers of prev, next */
		svins (Curln, 1);
		Lastln++;		/* update Lastln */
#else
		Lastln++;		/* update Lastln */
		blkmove (Lastln, Lastln, Curln);
		svins (Curln, 1);
#endif
		Curln++;		/* update Curln */
	}
	return (OK);
}



/* maklin --- construct a new line, add to scratch file */

maklin (lin, i, newind)
register char lin [];
register int i;
LINEDESC **newind;
{

	char text [MAXLINE];
	register int l, n;
	LINEDESC *ptr;
	LINEDESC *alloc ();

	if (alloc (&ptr) == NOMORE)     /* get space for pointer block */
		return (ERR);

	for (n = i; lin [n] != EOS; n++)	/* find end of line */
		if (lin [n] == '\n')
		{
			n++;
			break;
		}

	if (n - i >= MAXLINE )  /* can't handle more than MAXLINE chars/line */
		n = i + MAXLINE - 1;
	l = n - i + 1;          /* length of new line (including EOS) */

	move_ (&lin [i], text, l);      /* move new line into text */
	text [l - 1] = EOS;             /* add EOS */

	ptr->Seekaddr = Scrend; /* will be added to end of scratch file */
	ptr->Lineleng = l;      /* line length including EOS */
	ptr->Globmark = NO;     /* not marked for Global command */
	ptr->Markname = DEFAULTNAME;    /* give it default mark name */

	seekf ((long) Scrend * 8, Scr); /* go to end of scratch file */
	writef (text, l, Scr);          /* write line on scratch file */
	Scrend += (l + 7) / 8;          /* update end-of-file pointer */

	Buffer_changed = YES;

	*newind = ptr;                  /* return index of new line */
	return (n);                     /* return next char of interest in lin */
}



/* makscr --- create a new scratch file */

makscr (fd, str)
register filedes *fd;
register char str[];
{
	register int i;

	for (i = 0; i <= 9; i++)
	{
		sprintf (str, "/usr/tmp/se%d.%d", getpid(), i);
		/* create str name in /usr/tmp */
		if ((*fd = open (str, 0)) < 0)
		{
			/* if the file is not there, close it and create it */
			close (*fd);
			if ((*fd = creat (str, 0700)) > 0)
			{
				close (*fd);
				if ((*fd = open (str, 2)) > 0)
					return;
			}
		}
		else
			close (*fd);

	}
	error (YES, "can't create scratch file");
}



/* nextln --- get line after "line" */

nextln (line)
int line;
{
	register int ret;

	ret = line + 1;
	if (ret > Lastln)
		ret = 0;

	return (ret);
}



/* prevln --- get line before "line" */

prevln (line)
int line;
{
	register int ret;

	ret = line - 1;
	if (ret < 0)
		ret = Lastln;

	return (ret);
}



/* readf --- read count words from fd into buf */

readf (buf, count, fd)
char buf [];
int  count, fd;
{
	register int ret;

	ret = read (fd, buf, count);
	if (ret != count)
		error (YES, "Fatal scratch file read error");

	return (ret);
}


#ifdef OLD_SCRATCH
/* relink --- rewrite two half links */

relink (a, x, y, b)
LINEDESC *a, *b, *x, *y;
{
	x->Prevline = a;
	y->Nextline = b;
}
#endif



/* seekf --- position file open on fd to pos */

static seekf (pos, fd)
long pos;
filedes fd;
{
	register long ret;
	long lseek ();

	ret = lseek (fd, pos, 0);               /* abs seek */
	if (ret != pos)
		error (YES, "Fatal scratch file seek error");
	return (OK);
}



/* mkbuf --- create scratch file, initialize line 0 */

mkbuf ()
{
	LINEDESC *p;

	makscr (&Scr, Scrname);	/* create a scratch file */
	Scrend = 0;		/* initially empty */

	Curln = 0;
#ifdef OLD_SCRATCH
	Lastln = 0;
#else
	Lastln = -1;		/* alloc depends on this... */
#endif

#ifdef OLD_SCRATCH
	Lastbf = &Buf[0];       /* next word available for allocation ?? */
	Free = NOMORE;          /* free list initially empty */
#endif
	Limbo = NOMORE;         /* no lines in limbo */
	Limcnt = 0;
	Lost_lines = 0;         /* no garbage in scratch file yet */

	maklin ("", 0, &p);     /* create an empty line */
#ifdef OLD_SCRATCH
	relink (p, p, p, p);    /* establish initial linked list */
#endif
	p->Markname = EOS;	/* give it an illegal mark name */
	Line0 = p;              /* henceforth and forevermore */

#ifndef OLD_SCRATCH
	Lastln = 0;
#endif
}



/* sp_inject --- special inject for reading files */

LINEDESC *sp_inject (lin, len, line)
char lin[];
int  len;
LINEDESC *line;
{
	register LINEDESC *k, *ret;
	LINEDESC *ptr;
	LINEDESC *alloc ();

	ret = alloc (&ptr);
	if (ptr == NOMORE)
	{
		Errcode = ECANTINJECT;
		return (ret);
	}

	ptr->Seekaddr = Scrend;
	ptr->Lineleng = len + 1;
	ptr->Globmark = NO;
	ptr->Markname = DEFAULTNAME;

	seekf ((long) Scrend * 8, Scr);
	writef (lin, len + 1, Scr);
	Scrend += ((len + 1) + 7) / 8;          /* fudge for larger buffer */
	Lastln++;

	Buffer_changed = YES;

#ifdef OLD_SCRATCH
	k = line->Nextline;
	relink (line, ptr, ptr, k);
	relink (ptr, k, line, ptr);
#else
	/*
	 * this part dependant on the fact that we set
	 * Curln = line in the routine do_read.
	 */
	blkmove (ptr - Buf, ptr - Buf, Curln);	/* need line no's */
	Curln++;
#endif

	return (ret);
}



/* writef --- write count words from buf onto fd */

writef (buf, count, fd)
char buf[];
int  count;
filedes fd;
{
	register int ret;

	ret = write (fd, buf, count);
	if (ret != count)
		error (YES, "Fatal scratch file write error");
	return (ret);
}



/* getind --- locate line index in buffer */

LINEDESC *getind (line)
register int line;
{
#ifdef OLD_SCRATCH
	register LINEDESC *k;

	k = Line0;
	line++;
	while (--line)
		k = k->Nextline;

	return (k);
#else
	return (&Buf[line]);
#endif
}

#ifndef OLD_SCRATCH

/* blkmove -- use SWT in Pascal line handling */

blkmove (n1, n2, n3)	/* move block of lines n1..n2 to after n3 */
int n1, n2, n3;
{
	if (n3 < n1 -1)
	{
		reverse (n3 + 1, n1 - 1);
		reverse (n1, n2);
		reverse (n3 + 1, n2);
	}
	else if (n3 > n2)
	{
		reverse (n1, n2);
		reverse (n2 + 1, n3);
		reverse (n1, n3);
	}
}

/* reverse -- reverse buf[n1]..buf[n2] */

reverse (n1, n2)
register int n1, n2;
{
	LINEDESC temp;

	while (n1 < n2)
	{
		temp = Buf[n1];
		Buf[n1] = Buf[n2];
		Buf[n2] = temp;
		n1++;
		n2--;
	}
}
#endif
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'screen.c'" '(23199 characters)'
if test -f 'screen.c'
then
	echo shar: will not over-write existing file "'screen.c'"
else
cat << \SHAR_EOF > 'screen.c'
#ifndef lint
static char RCSid[] = "$Header: screen.c,v 1.3 86/07/17 17:22:19 arnold Exp $";
#endif

/*
 * $Log:	screen.c,v $
 * Revision 1.3  86/07/17  17:22:19  arnold
 * Senddelay() moved to term.c, where it belongs.
 * 
 * Revision 1.2  86/05/27  17:46:46  osadr
 * Fix for early 4.2 BSD systems to use <sys/time.h> instead of <time.h>.
 * 
 * Revision 1.1  86/05/06  13:38:18  osadr
 * Initial revision
 * 
 * 
 */

/*
** screen.c
**
** screen handling functions for the screen editor.
*/


#include "se.h"
#include "extern.h"
#ifdef BSD4_2
#include <sys/time.h>
#else
#include <time.h>
#endif

/* clrrow --- clear out all of a row except the bar */

clrrow (row)
register int row;
{
	loadstr ("", row, 0, BARCOL - 1);
	loadstr ("", row, BARCOL + 1, Ncols - 1);
}



/* display_message --- copy contents of message file to screen */

display_message (fp)
FILE *fp;
{
	char lin[MAXCOLS];
	char *fgets ();
	int row, col, eof, k;
	static char more[] = " M O R E   T O   C O M E ";

	if (Toprow > 0)
	{
		Topln = max (0, Topln - (Toprow - 1));
		Toprow = 0;
	}

	eof = NO;
	for (row = Toprow; row <= Botrow; row++)
	{
		if (fgets (lin, Ncols, fp) == NULL)
		{
			eof = YES;
			break;
		}
		Toprow++;
		Topln++;
		lin[strlen (lin)] = EOS;		/* remove '\n' */
		loadstr (lin, row, 0, Ncols);
	}

	if (eof == NO)
	{
		k = (Ncols - strlen (more)) / 2;
		for (col = 0; col < k; col++)
			load ('*', row, col);

		for (k = 0; more[k] != EOS; k++, col++)
			load (more[k], row, col);

		for (; col < Ncols; col++)
			load ('*', row, col);

		Toprow++;
		Topln++;
		row++;
	}

	for (col = 0; col < Ncols; col++)
		load ('-', row, col);
	Toprow++;
	Topln++;

	if (Topln > Lastln)
		adjust_window (0, Lastln);

	if (Curln < Topln)
		Curln = Topln;

	First_affected = Topln;		/* must rewrite the whole screen */

	mesg ("Enter o- to restore display", HELP_MSG);

	if (eof == YES)
		return (EOF);

	return (OK);
}

static char smargin[] = "MARGIN";

/* getcmd --- read a line from the terminal (for se) */

getcmd (lin, col1, curpos, termchar)
char *lin, *termchar;
int col1, *curpos;
{
	int cursor, nlpos, prev_cursor, prev_status, status,
	scan_pos, tab_pos, first, strlen (),
	scan_tab (), scan_char (), cread ();
	char c;

	nlpos = strlen (lin) - 1;
	if (nlpos == -1 || lin[nlpos] != '\n')
		nlpos++;

	if (*curpos < 0)
		cursor = 0;
	else if (*curpos >= MAXLINE - 1)
		cursor = nlpos;
	else
		set_cursor (*curpos, &status, &cursor, &nlpos, lin);
	prev_cursor = cursor;

	watch ();	/* display the time of day */

	switch (Nchoise) {	/* update the line number display */
	case CURLINE:
		litnnum ("line ", Curln, LINE_MSG);
		break;
	case LASTLINE:
		litnnum ("$ = ", Lastln, LINE_MSG);
		break;
	case TOPLINE:
		litnnum ("# = ", Topln, LINE_MSG);
		break;
	default:
		mesg ("", LINE_MSG);
		break;
	}

	if (cursor + 1 < Warncol)	/* erase the column display */
		mesg ("", COL_MSG);

	*termchar = EOS;	/* not yet terminated */
	status = OK;
	prev_status = ERR;
	first = col1;

	while (*termchar == EOS)
	{
		lin[nlpos] = EOS;	/* make sure the line has an EOS */
		if (status == ERR)	/* last iteration generated an error */
			twrite (1, "\007", 1);	/* Bell */
		else if (prev_status == ERR)	/* last one OK but one before had error */
			mesg ("", CHAR_MSG);

		prev_status = status;
		status = OK;

		if (first > cursor)     /* do horiz. scroll if needed */
			first = cursor;
		else if (first < cursor - Ncols + POOPCOL + 1)
			first = cursor - Ncols + POOPCOL + 1;

		if (first == col1)      /* indicate horizontally shifted line */
			load ('|', Cmdrow, BARCOL);
		else if (first > col1)
			load ('<', Cmdrow, BARCOL);
		else if (first < col1)
			load ('>', Cmdrow, BARCOL);
		loadstr (&lin[first], Cmdrow, POOPCOL, Ncols - 1);

		if (cursor == Warncol - 1 && prev_cursor < Warncol - 1)
			twrite (1, "\007", 1);   /* Bell */
		if (cursor >= Warncol - 1)
			litnnum ("col ", cursor + 1, COL_MSG);
		else if (prev_cursor >= Warncol - 1)
			mesg ("", COL_MSG);

		position_cursor (Cmdrow, cursor + POOPCOL - first);
		prev_cursor = cursor;

		/* get a character  */
		switch (c = cread()) {		/* branch on character value */

	/* Literal characters: */
		case ' ': case '!': case '"': case '#': case '$': case '%': 
		case '&': case '\'': case '(': case ')': case '*': case '+':
		case ',': case '-': case '.': case '/': case '0': case '1': 
		case '2': case '3': case '4': case '5': case '6': case '7':
		case '8': case '9': case ':': case ';': case '<': case '=': 
		case '>': case '?': case '@': case '[': case '\\': case ']':
		case '^': case '_': case '`': case '{': case '|': case '}': 
		case '~': case 'A': case 'B': case 'C': case 'D': case 'E':
		case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': 
		case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q':
		case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': 
		case 'X': case 'Y': case 'Z': case 'a': case 'b': case 'c':
		case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': 
		case 'j': case 'k': case 'l': case 'm': case 'n': case 'o':
		case 'p': case 'q': case 'r': case 's': case 't': case 'u': 
		case 'v': case 'w': case 'x': case 'y': case 'z': case ESC:
			if (c == ESC) /* take next char literally */
			{
				if ((c = cread()) == '\r')
					c = '\n';
			}
			else if (Invert_case == YES && isalpha (c))
				c ^= 040;       /* toggle case (ASCII only) */
			if (Insert_mode == YES)
				insert (1, &nlpos, &status, cursor, lin);
			else if (cursor >= MAXLINE - 2)
			{
				status = ERR;
				mesg (smargin, CHAR_MSG);
			}
			if (status != ERR)
			{
				lin[cursor++] = c;
				if (nlpos < cursor)
					nlpos = cursor;
				if (c == '\n')
					*termchar = CURSOR_SAME;
			}
			break;

	/* Leftward cursor functions: */
		case CURSOR_LEFT:
			set_cursor (cursor - 1, &status, &cursor, &nlpos, lin);
			break;

		case TAB_LEFT:
			tab_pos = scan_tab (TAB_LEFT, cursor, &status);
			if (status != ERR)
				cursor = tab_pos;
			break;

		case SKIP_LEFT:
			cursor = 0;
			break;

		case SCAN_LEFT:
			scan_pos = scan_char (c, YES, cursor, nlpos,
			    lin, &status);
			if (status != ERR)
				cursor = scan_pos;
			break;

		case G_LEFT:
			set_cursor (cursor - 1, &status, &cursor, &nlpos, lin);
			if (status != ERR)
				gobble (1, cursor, &status, &nlpos, lin);
			break;

		case G_TAB_LEFT:
			tab_pos = scan_tab (TAB_LEFT, cursor, &status);
			if (status != ERR)
			{
				cursor = tab_pos;
				gobble (prev_cursor - tab_pos, cursor,
				    &status, &nlpos, lin);
			}
			break;

		case KILL_LEFT:
			cursor = 0;
			gobble (prev_cursor /* - 1 */, cursor, &status, &nlpos, lin);
			break;

		case G_SCAN_LEFT:
			scan_pos = scan_char (c, NO, cursor, nlpos,
			    lin, &status);
			if (status != ERR)
			{
				cursor = scan_pos;
				gobble (prev_cursor - scan_pos, cursor,
				    &status, &nlpos, lin);
			}
			break;

	/* Rightward cursor functions: */
		case CURSOR_RIGHT:
			set_cursor (cursor + 1, &status, &cursor, &nlpos, lin);
			break;

		case TAB_RIGHT:
			tab_pos = scan_tab (TAB_RIGHT, cursor, &status);
			if (status != ERR)
				set_cursor (tab_pos, &status, &cursor,
				    &nlpos, lin);
			break;

		case SKIP_RIGHT:
			cursor = nlpos;
			first = col1;
			break;

		case SCAN_RIGHT:
			scan_pos = scan_char (c, YES, cursor, nlpos,
			    lin, &status);
			if (status != ERR)
				cursor = scan_pos;
			break;

		case G_RIGHT:
			gobble (1, cursor, &status, &nlpos, lin);
			break;

		case G_TAB_RIGHT:
			tab_pos = scan_tab (TAB_RIGHT, cursor,
			    &status);
			if (status != ERR)
				gobble (tab_pos - cursor, cursor, &status,
				    &nlpos, lin);
			break;

		case KILL_RIGHT:
			gobble (nlpos - cursor, cursor, &status, &nlpos, lin);
			break;

		case G_SCAN_RIGHT:
			scan_pos = scan_char (c, NO, cursor, nlpos,
			    lin, &status);
			if (status != ERR)
				gobble (scan_pos - cursor, cursor, &status,
				    &nlpos, lin);
			break;

	/* Line termination functions: */
		case T_SKIP_RIGHT:
			cursor = nlpos;
			*termchar = c;
			break;

		case T_KILL_RIGHT:
			nlpos = cursor;
			*termchar = c;
			break;

		case FUNNY:
		case CURSOR_UP:
		case CURSOR_DOWN:
			*termchar = c;
			break;

	/* Insertion functions: */
		case INSERT_BLANK:
			insert (1, &nlpos, &status, cursor, lin);
			if (status != ERR)
				lin[cursor] = ' ';
			break;

		case INSERT_NEWLINE:
			insert (1, &nlpos, &status, cursor, lin);
			if (status != ERR)
			{
				lin[cursor] = '\n';
				*termchar = CURSOR_UP;
			}
			break;

		case INSERT_TAB:
			while (lin[cursor] == ' ' || lin[cursor] == '\t')
				cursor++;
			tab_pos = scan_tab (TAB_RIGHT, cursor, &status);
			if (status != ERR)
				insert (tab_pos - cursor, &nlpos, &status,
				    cursor, lin);
			if (status != ERR)
				for (; cursor < tab_pos; cursor++)
					lin[cursor] = ' ';
			cursor = prev_cursor;
			break;

	/* Miscellanious control functions: */
		case TOGGLE_INSERT_MODE:
			Insert_mode = YES + NO - Insert_mode;
			if (Insert_mode == NO)
				mesg ("", INS_MSG);
			else
				mesg ("INSERT", INS_MSG);
			break;

		case SHIFT_CASE:
			Invert_case = YES + NO - Invert_case;
			if (Invert_case == NO)
				mesg ("", CASE_MSG);
			else
				mesg ("CASE", CASE_MSG);
			break;

		case KILL_ALL:
			nlpos = cursor = 0;
			break;

		case FIX_SCREEN:
			restore_screen ();
			break;

		default:
			status = ERR;
			mesg ("WHA?", CHAR_MSG);
			break;
		} /* end switch */
	} /* while (termchar == EOS) */

	lin[nlpos] = '\n';
	lin[nlpos + 1] = EOS;

	load ('|', Cmdrow, BARCOL);
	if (nlpos <= col1)
		loadstr ("", Cmdrow, POOPCOL, Ncols - 1);
	else
		loadstr (&lin[col1], Cmdrow, POOPCOL, Ncols - 1);

	if (cursor >= Warncol - 1)
		litnnum ("col ", cursor + 1, COL_MSG);
	else if (prev_cursor >= Warncol - 1)
		mesg ("", COL_MSG);

	*curpos = cursor;
}



/* cread --- read a character, handle interrupts and hangups */
/*              ALL keyboard input should pass through this routine */

int cread ()
{
	char c;
	int read ();

	tflush ();
	if (Peekc)
	{
		c = Peekc;
		Peekc = EOS;
	}
	else
	{
#ifdef BSD4_2
		Reading = YES;
#endif
		if (read (0, &c, 1) == -1)
			if (Hup_caught)
				hangup ();
			else	/* must be a SIGINT at present */
			{
				Int_caught = 0;
				Errcode = ENOERR;
				c = '\177';
			}
#ifdef BSD4_2
		Reading = NO;
#endif
	}

	return c;
}



/* scan_char --- scan current line for a character */

static int scan_char (chr, wrap, cursor, nlpos, lin, status)
char chr, *lin;
int wrap, cursor, nlpos, *status;
{
	register char c;
	register int inc, scan_pos;
	int cread ();

	c = cread ();
	if (Invert_case == YES && isalpha (c))
		c ^= 040;       /* toggle case */
	if (c == chr)
		c = Last_char_scanned;
	Last_char_scanned = c;

	if (chr == SCAN_LEFT || chr == G_SCAN_LEFT)
		inc = -1;
	else
		inc = 1;

	/* NOTE:  modify this code AT YOUR OWN RISK! */
	scan_pos = cursor;
	do
	{
		if (scan_pos < 0)
			if (wrap == NO)
				break;
			else
				scan_pos = nlpos;
		else if (scan_pos > nlpos)
			if (wrap == NO)
				break;
			else
				scan_pos = 0;
		else
			scan_pos += inc;
		if (-1 < scan_pos && scan_pos < nlpos && lin[scan_pos] == c)
			break;
	} while (scan_pos != cursor);

	if (scan_pos < 0 || scan_pos >= nlpos || lin[scan_pos] != c)
	{
		*status = ERR;
		mesg ("NOCHAR", CHAR_MSG);
	}

	return (scan_pos);
}



static int scan_tab (chr, cursor, status)
char chr;
int cursor, *status;
{
	register int inc, tab_pos;

	if (chr == TAB_LEFT)
	{
		inc = -1;
		tab_pos = cursor - 1;
	}
	else
	{
		inc = 1;
		tab_pos = cursor + 1;
	}

	for (; -1 < tab_pos && tab_pos < MAXLINE; tab_pos += inc)
		if (Tabstops[tab_pos] == YES)
			break;

	if (tab_pos < 0 || tab_pos >= MAXLINE - 1)
	{
		*status = ERR;
		mesg (smargin, CHAR_MSG);
	}

	return (tab_pos);
}



/* gobble --- delete characters starting at the current cursor position */

static gobble (len, cursor, status, nlpos, lin)
int len, cursor, *status, *nlpos;
char *lin;
{
	if (cursor + len > *nlpos)
	{
		*status = ERR;
		mesg (smargin, CHAR_MSG);
	}
	else if (len > 0)
	{
		strcpy (&lin[cursor], &lin[cursor + len]);
		*nlpos -= len;
	}
}



/* insert --- shift characters right starting at the current cursor position */

static insert (len, nlpos, status, cursor, lin)
register int len, *nlpos, cursor;
int *status;
register char *lin;
{
	register int fr, to;

	if (*nlpos + len >= MAXLINE - 1)
	{
		*status = ERR;
		mesg (smargin, CHAR_MSG);
	}
	else
	{
		for (fr = *nlpos, to = *nlpos + len; fr >= cursor; fr--, to--)
			lin[to] = lin[fr];
		*nlpos += len;
	}
}



/* set_cursor --- move the cursor, extend line if necessary */

static set_cursor (pos, status, cursor, nlpos, lin)
register int pos, *status, *cursor, *nlpos;
register char *lin;
{
	if (pos < 0 || pos >= MAXLINE - 1)
	{
		*status = ERR;
		mesg (smargin, CHAR_MSG);
	}
	else
	{
		*cursor = pos;
		for (; *nlpos < *cursor; (*nlpos)++)
			lin[*nlpos] = ' ';
	}
}


/* litnnum --- display literal and number in message area */

litnnum (lit, num, type)
register char *lit;
register int num, type;
{
	char msg[MAXLINE];

	sprintf (msg, "%s%d", lit, num);
	mesg (msg, type);
}



/* load --- load a character onto the screen at given coordinates */

load (chr, row, col)
register char chr;
register int row, col;
{
	register char ch;

	ch = (chr < ' ' || chr >= DEL) ? Unprintable : chr;

	if (row >= 0 && row < Nrows && col >= 0 && col < Ncols
	    && Screen_image[row][col] != ch)
	{
		position_cursor (row, col);
		Screen_image[row][col] = ch;
		send (ch);
	}
}


/* loadstr --- load a string into a field of the screen */

loadstr (str, row, stcol, endcol)
register char *str;
int row, stcol, endcol;
{
	register char ch;
	register int p, c, limit;

	if (row >= 0 && row < Nrows && stcol >= 0)
	{
		c = stcol;
		for (p = 0; str[p] != EOS; p++)
		{
			if (c >= Ncols)
				break;
			ch = str[p];
			if (ch < ' ' || ch >= DEL)
				ch = Unprintable;
			if (Screen_image[row][c] != ch)
			{
				Screen_image[row][c] = ch;
				position_cursor (row, c);
				send (ch);
			}
			c++;
		}
		if (endcol >= Ncols - 1 && c < Ncols - 1)
			clear_to_eol (row, c);
		else
		{
			limit = (endcol < Ncols - 1) ? endcol : Ncols - 1;
			for (; c <= limit; c++)
				if (Screen_image[row][c] != ' ')
				{
					Screen_image[row][c] = ' ';
					position_cursor (row, c);
					send (' ');
				}
		}
	}
}


/* mesg --- display a message in the status row */

mesg (s, t)
char *s;
register int t;
{
	register int col, need, c, first, last;
	int strlen ();

	for (first = 0; first < Ncols; first++)
		if (Msgalloc[first] == t)
			break;
	for (last = first; last < Ncols; last++)
	{
		if (Msgalloc[last] != t)
			break;
		Msgalloc[last] = NOMSG;
	}
	for (; first > 0 && Msgalloc[first - 1] == NOMSG; first--)
		;

	need = strlen (s) + 2;  /* for two blanks */

	if (need > 2)           /* non-empty message */
	{
		if (need <= last - first)       /* fits in previous slot */
			col = first;		/* keep it there */
		else		/* needs a new slot */
			for (col = 0; col < Ncols - 1; col = c)
			{
				while (col < Ncols - 1
				    && Msgalloc[col] != NOMSG)
					col++;
				for (c = col; Msgalloc[c] == NOMSG; c++)
					if (c >= Ncols - 1)
						break;
				if (c - col >= need)
					break;
			}

		if (col + need >= Ncols)        /* have to collect garbage */
		{
			col = 0;
			for (c = 0; c < Ncols; c++)
				if (Msgalloc[c] != NOMSG)
				{
					load (Screen_image[Nrows - 1][c],
					    Nrows - 1, col);
					Msgalloc[col] = Msgalloc[c];
					col++;
				}
			for (c = col; c < Ncols; c++)
				Msgalloc[c] = NOMSG;
		}

		load (' ', Nrows - 1, col);
		loadstr (s, Nrows - 1, col + 1, 0);
		load (' ', Nrows - 1, col + need - 1);
		last = col + need - 1;
		if (last > Ncols - 1)
			last = Ncols - 1;
		for (c = col; c <= last; c++)
			Msgalloc[c] = t;
	}

	for (col = 0; col < Ncols; col++)
		if (Msgalloc[col] == NOMSG)
			load ('.', Nrows - 1, col);
	tflush ();
}

/* prompt --- load str into margin of command line */

prompt (str)
char *str;
{
	loadstr (str, Cmdrow, 0, BARCOL - 1);
	tflush ();
}



/* restore_screen --- screen has been garbaged; fix it */

restore_screen ()
{
	register int row, col;
	int intrpt ();

	clrscreen ();
	for (row = 0; row < Nrows && ! intrpt (); row++)
		for (col = 0; col < Ncols; col++)
			if (Screen_image[row][col] != ' ')
			{
				position_cursor (row, col);
				send (Screen_image[row][col]);
			}

	remark ("");	/* get rid of 'type control-q....' */
}

/* saynum --- display a number in the message area */

saynum (n)
int n;
{
	char s[MAXLINE];

	sprintf (s, "%d", n);
	remark (s);
}

/* updscreen --- update screen from edit buffer */

updscreen ()
{
	char abs_lineno[10], rel_lineno[10];
	register int line, row;
	register int i;
	int prevln ();
	register LINEDESC *k;
	LINEDESC *getind ();

	fixscreen ();

	line = Topln;
	k = getind (line);

	for (row = Toprow; row <= Botrow; row++)
	{
		if (line > Lastln || line < 1)
		{
			loadstr ("", row, 0, BARCOL - 1);
			load ('|', row, BARCOL);
			loadstr ("", row, BARCOL + 1, Ncols - 1);
		}
		else
		{
			if (line == Curln)
				loadstr (".  ->", row, 0, NAMECOL - 1);
			else if (line == 1)
				loadstr ("1", row, 0, NAMECOL - 1);
			else if (line == Lastln)
				loadstr ("$", row, 0, NAMECOL - 1);
			else if (Absnos == NO && row <= 25)
			{
				rel_lineno[0] = Rel_a + row;
				rel_lineno[1] = EOS;
				loadstr (rel_lineno, row, 0, NAMECOL - 1);
			}
			else
			{
				sprintf (abs_lineno, "%d", line);
				loadstr (abs_lineno, row, 0, NAMECOL - 1);
			}

			load ((char) k->Markname, row, NAMECOL);
			load ('|', row, BARCOL);

			if (line >= First_affected)
			{
				gtxt (k);
				if (Firstcol >= k->Lineleng)
					loadstr ("", row, POOPCOL, Ncols - 1);
				else
					loadstr (&Txt[Firstcol], row, POOPCOL,
					    Ncols - 1);
			}
		}

		line++;
		k = NEXTLINE(k);
	}

	First_affected = Lastln;

	Sctop = Topln;
	Sclen = Botrow - Toprow + 1;
	for (i = 0; i < Sclen; i++)
		Scline[i] = Sctop + i <= Lastln ? i : -1;
}



/* warn_deleted --- indicate which rows on screen are no longer valid */

warn_deleted (from, to)
register int from, to;
{
	register int row;

	for (row = Toprow; row <= Botrow; row++)
		if (Topln + row - Toprow >= from
		    && Topln + row - Toprow <= to)
			loadstr ("gone", row, 0, BARCOL - 1);
}


/* watch --- keep time displayed on screen for users without watches */

watch ()
{
	long clock;
	struct tm *now, *localtime ();
	char face[10];

	time (&clock);
	now = localtime (&clock);
	sprintf (face, "%02d:%02d", now->tm_hour, now->tm_min);
	mesg (face, TIME_MSG);
}

/* adjust_window --- position window to include lines 'from' through 'to' */

adjust_window (from, to)
register int from, to;
{
	register int i, l1, l2, hw;
	int hwinsdel();

	/* see if the whole range of lines is on the screen */
	if (from < Topln || to > Topln + (Botrow - Toprow))
	{
		/* find the first and last lines that are on the screen */
		for (i = 0; i < Sclen && Scline[i] == -1; i++)
			;
		l1 = i < Sclen ? Scline[i] + Sctop : Lastln + 1;
		for (i = Sclen - 1; i >= 0 && Scline[i] == -1; i--)
			;
		l2 = i >= 0 ? Scline[i] + Sctop : 0;

		/* see if we have hardware line insert/delete */
		hw = hwinsdel();

		/* now find the best place to move the screen */
		if (to - from > Botrow - Toprow)
			Topln = to - (Botrow - Toprow);     /* put last part on screen */
		else if (hw && from >= l1 && to <= l2)
			Topln = (l1 + l2 + Toprow - Botrow) / 2;/* center l1 through l2 */
		else if (hw && from < l1 && l1 - from < (Botrow - Toprow + 1) / 2)
			Topln = from;                       /* slide the screen down */
		else if (hw && to > l2 && to - l2 < (Botrow - Toprow + 1) / 2)
			Topln = to - (Botrow - Toprow);     /* slide the screen up */
		else
			Topln = (from + to + Toprow - Botrow) / 2; /* center the range */
		if (Topln + (Botrow - Toprow) > Lastln)
			Topln = Lastln - (Botrow - Toprow);
		if (Topln < 1)
			Topln = 1;
		if (First_affected > Topln)
			First_affected = Topln;
	}
}


/* svdel --- record the deletion of buffer lines for screen update */

svdel (ln, n)
register int ln, n;
{
	register int i, j, lb, ub;

	if (ln + n <= Sctop)
		Sctop -= n;
	else if (ln < Sctop)
	{
		ub = ln + n - Sctop;
		for (i = 0; i < Sclen; i++)
			if (Scline[i] == -1)
				;
			else if (Scline[i] < ub)
				Scline[i] = -1;
			else
				Scline[i] -= ub;
		Sctop = ln;
	}
	else
	{
		lb = ln - Sctop;
		ub = ln + n - Sctop;
		for (i = 0; i < Sclen; i++)
			if (Scline[i] == -1 || Scline[i] < lb)
				;
			else if (Scline[i] < ub)
				Scline[i] = -1;
			else
				Scline[i] -= n;
	}
}


/* svins --- record a buffer insertion for screen updating */

svins (ln, n)
register int ln, n;
{
	register int i, lb;

	if (ln < Sctop)
		Sctop += n;
	else
	{
		lb = ln - Sctop;
		for (i = 0; i < Sclen; i++)
			if (Scline[i] != -1 && Scline[i] > lb)
				Scline[i] += n;
	}

}


/* fixscreen --- try to patch up the screen using insert/delete line */

fixscreen ()
{
	register int oi;	/* "old" screen index */
	register int ni;	/* "new" screen index */
	register int dc;	/* number of deletions in current block */
	register int ic;	/* number of insertions in current block */
	register int ul;	/* number of lines that must be rewritten if */
				/* we don't update by insert/delete */
	int wline[MAXROWS];	/* new screen contents; Scline contains old */
	int p;

	/* if the screen width was changed, give up before it's too late */
	if (Botrow - Toprow + 1 != Sclen || ! hwinsdel())
		return;

	/* scale the offsets in Scline to the new Topln; set any that are */
	/* off the screen to -1 so we won't have to fool with them */
	for (oi = 0; oi < Sclen; oi++)
		if (Scline[oi] == -1 || Scline[oi] + Sctop < Topln
		    || Scline[oi] + Sctop > Topln + (Botrow - Toprow))
			Scline[oi] = -1;
		else
			Scline[oi] += Sctop - Topln;

	/* fill in wline with only those numbers that are in Scline */
	for (oi = 0, ni = 0; ni < Sclen; ni++)
	{
		while (oi < Sclen && Scline[oi] == -1)
			oi++;
		if (oi < Sclen && Scline[oi] == ni)
		{
			wline[ni] = ni;
			oi++;
		}
		else
			wline[ni] = -1;
	}

	/* see if it's still advisable to fix the screen: if the number */
	/* of lines that must be rewritten is less than 2 + the number */
	/* of lines that must be inserted, don't bother (this is a dumb */
	/* but fairly effective heuristic) */
	ul = ni = 0;
	for (oi = 0; oi < Sclen; oi++)
	{
		if (Scline[oi] != wline[oi] || Scline[oi] == -1)
			ul++;
		if (wline[oi] == -1)
			ni++;
	}
	if (ul < ni + 2)
		return;

	/* Now scan the screens backwards and put out delete-lines */
	/* for all deletions and changes with more old lines than new */
	oi = ni = Sclen - 1;
	while (oi >= 0 || ni >= 0)
	{
		for (dc = 0; oi >= 0 && Scline[oi] == -1; dc++)
			oi--;
		for (ic = 0; ni >= 0 && wline[ni] == -1; ic++)
			ni--;
		if (dc > ic)
			dellines (oi + 1 + Toprow + ic, dc - ic);
		while (oi >= 0 && Scline[oi] != -1
		    && ni >= 0 && wline[ni] == Scline[oi])
			oi--, ni--;
	}

	/* At last, scan the screens forward and put out insert-lines */
	/* for all insertions and changes with more new lines than old */
	oi = ni = 0;
	while (oi < Sclen || ni < Sclen)
	{
		p = ni;
		for (dc = 0; oi < Sclen && Scline[oi] == -1; dc++)
			oi++;
		for (ic = 0; ni < Sclen && wline[ni] == -1; ic++)
			ni++;
		if (ic > dc)
			inslines (p + Toprow + dc, ic - dc);
		while (oi < Sclen && Scline[oi] != -1
		    && ni < Sclen && wline[ni] == Scline[oi])
			oi++, ni++;
	}

}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'scriptse.1'" '(1863 characters)'
if test -f 'scriptse.1'
then
	echo shar: will not over-write existing file "'scriptse.1'"
else
cat << \SHAR_EOF > 'scriptse.1'
.\" 
.\" $Header: scriptse.1,v 1.2 86/07/11 15:17:32 osadr Exp $
.\" 
.\" $Log:	scriptse.1,v $
.\" Revision 1.2  86/07/11  15:17:32  osadr
.\" Removal of Georgia Tech specific items, and some cleaning up.
.\" 
.\" Revision 1.1  86/05/06  13:41:03  osadr
.\" Initial revision
.\" 
.\" 
.\" 
.TH SCRIPTSE 1 local
.SH NAME
scriptse \- make scripts for se
.SH SYNOPSIS
.B scriptse
[
.B \-d
]
< script_file |
.B se
[ & ]
.SH DESCRIPTION
.I Scriptse
reads standard input, and writes standard output.
It is a simple filter which turns newlines ('\en') into carriage
returns ('\er') for
.IR se (1).
This allows
.I se
to be run from a prepared script.
.I Se
can then be fired off into the background, if you wish.
.PP
After each carriage return,
.I scriptse
adds an ASCII DEL character ('\e177').
This is so that command lines which fail will be erased,
and the next command can then be executed.
If it did not, command lines would get concatenated together, and they
would simply continue to fail.
Ultimately, the editor would run out of input buffer and start to
contiunuously ring the bell on the terminal.
With the DEL character, each command line is executed on its own.
.PP
.I Scriptse
takes one option, \-d.
If this option is used,
.I scriptse
will
.I not
add the ASCII DEL after each carriage return.
This is useful for program which want to turn newlines into carraige
returns.
.PP
If you do use a script, either sit back and watch it run, or redirect
the output into a file (or
.BR /dev/null ,
if you are confident).
.SH SEE ALSO
.IR se (1).
.SH CAVEATS
.PP
It is rather difficult to interrupt
.I se
when it is running, so editor scripts should write their
changed buffer to a new file, in case something goes wrong.
.SH BUGS
.PP
Does no checking for any of
.IR se 's
control characters.
If you put control characters into a script, you are taking your chances.
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'scriptse.c'" '(824 characters)'
if test -f 'scriptse.c'
then
	echo shar: will not over-write existing file "'scriptse.c'"
else
cat << \SHAR_EOF > 'scriptse.c'
#ifndef lint
static char RCSid[] = "$Header: scriptse.c,v 1.1 86/05/06 13:38:32 osadr Exp $";
#endif

/*
 * $Log:	scriptse.c,v $
 * Revision 1.1  86/05/06  13:38:32  osadr
 * Initial revision
 * 
 * 
 */

/*
** scriptse.c
**
** turn input into a form se
** can use as a script.
**
** This is very quick-and-dirty, not checking
** for any of se's control characters.
*/

#include <stdio.h>

main (argc, argv)
int argc;
char **argv;
{
	register int c;
	register int dflag = 0;

	if (argc > 1)
		if (strcmp (argv[1], "-d") == 0)
			dflag = 1;
		else
		{
			fprintf (stderr, "usage: %s [-d] < file > newfile\n",
				argv[0]);
			exit (1);
		}

	while ((c = getchar()) != EOF)
	{
		if (c != '\n')		/* most frequent case */
			putchar (c);
		else
		{
			putchar ('\r');
			if (! dflag)
				putchar ('\177');
		}
	}
	
	exit (0);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'se.h'" '(7835 characters)'
if test -f 'se.h'
then
	echo shar: will not over-write existing file "'se.h'"
else
cat << \SHAR_EOF > 'se.h'
/*
 * $Header: se.h,v 1.3 86/07/11 15:09:54 osadr Exp $
 */

/*
 * $Log:	se.h,v $
 * Revision 1.3  86/07/11  15:09:54  osadr
 * Removed Many Georgia Tech specific things.
 * 
 * Revision 1.2  86/05/27  17:44:15  osadr
 * Removed flexnames dependancy on PREVLINE and PREVLINE2, changed to
 * PREVLN and PREVLN2.
 * 
 * Revision 1.1  86/05/06  13:36:23  osadr
 * Initial revision
 * 
 * 
 */

/* se.h	--- definitions	for the	screen editor */

#include <stdio.h>
#include <ctype.h>
#include <signal.h>

/* some standard definitions used throughout the screen editor */
#include "constdefs.h"
#include "ascii.h"	/* definitions of ascii characters */

/* new data types */
typedef	int filedes;		/* Unix	file descriptor	*/

typedef	struct ldesc {		/* line	descriptor */
#ifdef OLD_SCRATCH
	struct	ldesc *Prevline; /* link to previous line */
	struct	ldesc *Nextline; /* link to next line */
#endif
	unsigned Seekaddr;	/* scratch file seek address / 8 */
	unsigned Lineleng : 16;	/* line length	including NL  EOS */
	unsigned Globmark : 1;	/* mark for global commands */
	unsigned Markname : 7;	/* mark name associated with line */
} LINEDESC;

/* Language extensions */
#define min(a,b)	((a)<(b)?(a):(b))
#define max(a,b)	((a)>(b)?(a):(b))
#define SKIPBL(l,i)	while (l[i] == ' ') (i)++

/* save a little procedure call overhead... */
#define remark(text)	mesg(text, REMARK_MSG)

/* Arbitrary definitions */
#define BACKWARD	-1
#define FORWARD		0
#define NOSTATUS	1
#define NOMORE		0
#define NEWLINE		'\n'
#define TAB		'\t'
#define RETERR	1
#define RETOK	0

/* Array dimensions and	other limit values */
#define MAXBUF		8192
#define MAXTOBUF	512
#define MAXCHARS	10
#define MAXROWS		200
#define MINROWS		16
#define MAXCOLS		200
#define MAXLINE		512
#define MAXPAT		512
#define GARB_FACTOR	2
#define GARB_THRESHOLD	1000
#define BUFENT		1
#define KEYSIZE		11

/* Message classes for status line at bottom of	screen */
#define NOMSG		0
#define REMARK_MSG	1
#define CHAR_MSG	2
#define CASE_MSG	3
#define INS_MSG		4
#define TIME_MSG	5
#define FILE_MSG	6
#define COL_MSG		7
#define LINE_MSG	8
#define COMPRESS_MSG	9
#define HELP_MSG	10
#define MODE_MSG	11
#define CRYPT_MSG	12

/* Characters typed by the user	*/
#define ANYWAY		'!'
#define APPENDCOM	'a'
#define UCAPPENDCOM	'A'
#define BACKSCAN	'?'
#define BACKSEARCH	'<'
#define CHANGE		'c'
#define UCCHANGE	'C'
#define COPYCOM		't'
#define UCCOPYCOM	'T'
#define CURLINE		'.'
#define DEFAULTNAME	' '
#define DELCOM		'd'
#define UCDELCOM	'D'
#define ENTER		'e'
#define UCENTER		'E'
#define ESCAPE		'\\'
#define EXCLUDE		'x'
#define UCEXCLUDE	'X'
#define GLOBAL		'g'
#define UCGLOBAL	'G'
#define GMARK		'\''
#define HELP		'h'
#define UCHELP		'H'
#define INSERT		'i'
#define UCINSERT	'I'
#define JOINCOM		'j'
#define UCJOINCOM	'J'
#define LASTLINE	'$'
#define LOCATECMD	'l'
#define UCLOCATECMD	'L'
#define MARKCOM		'k'
#define UCMARKCOM	'K'
#define MOVECOM		'm'
#define UCMOVECOM	'M'
#define NAMECOM		'n'
#define UCNAMECOM	'N'
#define NOTINCCL	'^'
#define OPTCOM		'o'
#define UCOPTCOM	'O'
#define PAGECOM		':'
#define OVERLAYCOM	'v'
#define UCOVERLAYCOM	'V'
#define PREVLN		'^'
#define PREVLN2		'-'
#define PRINT		'p'
#define UCPRINT		'P'
#define PRINTCUR	'='
#define PRINTFIL	'f'
#define UCPRINTFIL	'F'
#define QUIT		'q'
#define UCQUIT		'Q'
#define READCOM		'r'
#define UCREADCOM	'R'
#define SCAN		'/'
#define SEARCH		'>'
#define SUBSTITUTE	's'
#define UCSUBSTITUTE	'S'
#define TLITCOM		'y'
#define UCTLITCOM	'Y'
#define TOPLINE		'#'
#define UNDOCOM		'u'
#define UCUNDOCOM	'U'
#define WRITECOM	'w'
#define UCWRITECOM	'W'
#define XMARK		'~'
#define MISCCOM		'z'
#define UCMISCCOM	'Z'
#define SHELLCOM	'!'

/* Error message numbers.  Arbitrary so	long as	they are different. */
#define EBACKWARD	1
#define ENOPAT		2
#define EBADPAT		3
#define EBADSTR		4
#define EBADSUB		5
#define ECANTREAD	6
#define EEGARB		7
#define EFILEN		8
#define EBADTABS	9
#define EINSIDEOUT	10
#define EKNOTFND	11
#define ELINE1		12
#define E2LONG		13
#define ENOERR		14
#define ENOLIMBO	15
#define EODLSSGTR	16
#define EORANGE		17
#define EOWHAT		18
#define EPNOTFND	19
#define ESTUPID		20
#define EWHATZAT	21
#define EBREAK		22
#define ELINE2		23
#define ECANTWRITE	24
#define ECANTINJECT	25
#define ENOMATCH	26
#define ENOFN		27
#define EBADLIST	28
#define ENOLIST		29
#define ENONSENSE	30
#define ENOHELP		31
#define EBADLNR		32
#define EFEXISTS	33
#define EBADCOL		34
#define ENOLANG		35
#define ETRUNC		36
#define ENOSHELL	37
#define ECANTFORK	38
#define EHANGUP		39
#define ENOSUB		40
#define ENOCMD		41

#ifdef HARD_TERMS
/* Terminal types */
#define NOTERM		0	/* type	not known yet */
#define ADDS980		1	/* ADDS	Consul 980 */
#define ADDS100		2	/* ADDS	Regent 100, 20,	40, etc	*/
#define FOX		3	/* Perkin-Elmer	1100 */
#define TVT		4	/* Allen's SWTPC T. V. Typewriter II */
#define GT40		5	/* DEC GT40 with Waugh terminal	program	*/
#define BEE150		6	/* Beehive 150 */
#define BEE200		7	/* Beehive 200 */
#define SBEE		8	/* Beehive Super-Bee */
#define SOL		9	/* Sol emulating Beehive 200 */
#define HAZ1510		10	/* Hazeltine 1500 series */
#define CG		11	/* Chromatics CG */
#define ISC8001		12	/* ISC 8001 color terminal */
#define ADM3A		13	/* Lear-Siegler	ADM 3A */
#define IBM		14	/* IBM 3101 */
#define ANP		15	/* Allen & Paul	model 1	*/
#define NETRON		16	/* Netronics */
#define H19		17	/* Heath H19/Zenith Z19	*/
#define TRS80		18	/* Radio Shaft TRS80 */
#define HP21		19	/* Hewlett-Packard 2621A/P */
#define ADM31		20	/* Lear-Siegler	ADM 31 */
#define VI200		21	/* VIsual 200 terminal */
#define VC4404		22	/* Volker-Craig	4404 */
#define ESPRIT		23	/* Hazeltine Esprit (Hazeltine mode) */
#define TS1		24	/* Falco TS-1 */
#define TVI950		25	/* Televideo 950 */
#define VI50		26	/* Visual 50 */
#define VI300		27	/* Visual 300	*/
#endif

/* Screen design positions */
#define NAMECOL		5	/* column to put mark name in */
#define BARCOL		6	/* column for "|" divider */
#define POOPCOL		7	/* column for text to start in */

/* Control characters */

/* Leftward cursor motion */
#define CURSOR_LEFT		CTRL_H	/* left	one column */
#define TAB_LEFT		CTRL_E	/* left	one tab	stop */
#define SKIP_LEFT		CTRL_W	/* go to column	1 */
#define SCAN_LEFT		CTRL_L	/* scan	left for a char	*/
#define G_LEFT			CTRL_U	/* erase char to left */
#define G_TAB_LEFT		FS	/* erase to prev tab stop */
#define KILL_LEFT		CTRL_Y	/* erase to column 1 */
#define G_SCAN_LEFT		CTRL_N	/* scan	left and erase */

/* Rightward cursor motion */
#define CURSOR_RIGHT		CTRL_G	/* right one column */
#define TAB_RIGHT		CTRL_I	/* right one tab stop */
#define SKIP_RIGHT		CTRL_O	/* go to end of	line */
#define SCAN_RIGHT		CTRL_J	/* scan	right for char */
#define G_RIGHT			CTRL_R	/* erase over cursor */
#define G_TAB_RIGHT		RS	/* erase to next tab */
#define KILL_RIGHT		CTRL_T	/* erase to end	of line	*/
#define G_SCAN_RIGHT		CTRL_B	/* scan	right and erase	*/

/* Line	termination */
#define T_SKIP_RIGHT		CTRL_V	/* skip	to end and terminate */
#define T_KILL_RIGHT		CR	/* KILL_RIGHT,	SKIP_RIGHT_AND_TERM */
#define FUNNY			CTRL_F	/* take	funny return */
#define CURSOR_UP		CTRL_D	/* move	up one line */
#define CURSOR_DOWN		CTRL_K	/* move	down one line */
#define CURSOR_SAME		CTRL_J	/* leave cursor	on same	line */

/* Insertion */
#define INSERT_BLANK		CTRL_C	/* insert one blank */
#define INSERT_TAB		CTRL_X	/* insert blanks to next tab */
#define INSERT_NEWLINE		US	/* insert a newline */

/* Miscellany */
#define TOGGLE_INSERT_MODE	CTRL_A	/* toggle insert mode flag */
#define SHIFT_CASE		CTRL_Z	/* toggle case mapping flag */
#define KILL_ALL		DEL	/* erase entire	line */
#define FIX_SCREEN		GS	/* clear and restore screen */

/* Function for moving around the buffer, either style line handling: */
#ifdef OLD_SCRATCH
#define NEXTLINE(k)	((k) -> Nextline)
#else
#define NEXTLINE(k)	(((k) < &Buf[Lastln]) ? (k) + 1 : Line0)
#endif
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'where'" '(1190 characters)'
if test -f 'where'
then
	echo shar: will not over-write existing file "'where'"
else
cat << \SHAR_EOF > 'where'
#! /bin/sh
# 
# $Header: where,v 1.2 86/07/11 15:14:10 osadr Exp $
# 
# $Log:	where,v $
# Revision 1.2  86/07/11  15:14:10  osadr
# Removed Georgia Tech specific items.
# 
# Revision 1.1  86/05/06  13:34:27  osadr
# Initial revision
# 
# 
# 

# where --- shell file to determine what kind of environment we are in

if test -r /bin/universe	# on a pyramid
then
	OPATH=$PATH
	PATH=/bin
	case `universe` in	# universe is dumb, looking only at argv[0]
	att)	echo "-DUSG -UBSD -UBSD4_2"
		if grep LOBLK /usr/include/sys/termio.h > /dev/null
		then
			echo -DS5R2
		else
			echo -US5R2
		fi
		;;

	ucb)	echo "-UUSG -DBSD -DBSD4_2 -US5R2"
		;;

	*)	echo unknown operating system! 1>&2
		echo "-UUSG -UBSD -UBSD4_2"	# undefine them all
		echo "-US5R2"
		;;
	esac
	PATH=$OPATH
else		# on something that is not a pyramid
	if grep SIGTSTP /usr/include/signal.h > /dev/null
	then		# berkeley unix
		if test -r /usr/include/whoami.h	# 4.1
		then
			echo "-UUSG -DBSD -UBSD4_2"
		else					# 4.2
			echo "-UUSG -DBSD -DBSD4_2"
		fi
		echo -US5R2
	else			# ATT unix
		echo "-DUSG -UBSD -UBSD4_2"
		if grep LOBLK /usr/include/sys/termio.h > /dev/null
		then
			echo -DS5R2
		else
			echo -US5R2
		fi
	fi
fi
SHAR_EOF
chmod +x 'where'
fi # end of overwriting check
#	End of shell archive
exit 0



More information about the Mod.sources mailing list