v08i005: Georgia Tech 'se' Screen Editor

sources-request at mirror.UUCP sources-request at mirror.UUCP
Tue Jan 27 07:20:09 AEST 1987


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


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:
#	term.c
#	libchangetty
#	pat
export PATH; PATH=/bin:$PATH
echo shar: extracting "'term.c'" '(37533 characters)'
if test -f 'term.c'
then
	echo shar: will not over-write existing file "'term.c'"
else
cat << \SHAR_EOF > 'term.c'
#ifndef lint
static char RCSid[] = "$Header: term.c,v 1.7 86/11/12 11:37:30 arnold Exp $";
#endif

/*
 * $Log:	term.c,v $
 * Revision 1.7  86/11/12  11:37:30  arnold
 * Fixed winsize() to verify that cols and rows not 0 before assigning
 * them to Nrows and Ncols.
 * 
 * Revision 1.6  86/10/14  11:10:36  arnold
 * Reorganization of window handling stuff. Added (untested) code for sun.
 * 
 * Revision 1.5  86/10/07  14:50:48  arnold
 * Changed setterm to set_term, to avoid Unix/PC shared library conflict.
 * Fixed winsize() to set Nrows and Ncols on first call, as well.
 * 
 * Revision 1.4  86/09/19  12:15:28  arnold
 * Fixes to BSD windowing for real 4.3, from BRL.
 * 
 * Revision 1.3  86/07/17  17:23:19  arnold
 * Massive reorganization and cleaning up. Terminal initialization
 * stuff moved here, and homogenized.
 * 
 * Revision 1.2  86/07/14  17:19:33  arnold
 * Added code that notices whether or not the window we are runnng in has
 * changed sizes. It definitely works on the Unix PC, and should work on
 * BRL Unix and 4.3 BSD.
 * 
 * Revision 1.1  86/05/06  13:38:53  osadr
 * Initial revision
 * 
 * 
 */

/*
** term.c
**
** provide terminal functions for se
**
** If HARD_TERMS is *not* defined, which is the default, se will
** use the termlib library, which provides terminal independant operations.
** This makes se both smaller, and more flexible.
**
** If HARD_TERMS is defined, then se will use the original code, which
** had terminal types hard-wired into the code.  This would be useful for
** a system which does not have the termlib library.
**
** On System V systems, we have two possibilities.  Release 1 did not have
** the terminfo package, so we assume that if it is Release 1, someone will
** have ported the BSD termlib library.  If it is Release 2, then the new
** terminfo package is there, and we wil use it.
**
** This file is large. It is organized as follows.
**
** Routines that do not care whether or not HARD_TERMS is defined.
** Routines that are only if HARD_TERMS is NOT defined. These contain:
**	BSD/termlib routines
**	System V/terminfo routines
**	Routines idenpendant of BSD/System V
** Routines that are only if HARD_TERMS is defined.
** Routines that have regular and conditonal code mixed.
*/

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

/* outc -- write a character to the terminal */

int outc (c)
char c;
{
	twrite (1, &c, 1);
}

#ifndef HARD_TERMS
#if defined (BSD) || !defined (S5R2)
/*
 * code for using BSD termlib -- getting capabilities, and writing them out.
 */

/* capabilities from termcap */

static int AM;		/* automatic margins, i.e. wraps at column 80 */

static char *VS;	/* visual start -- e.g. clear status line */
static char *VE;	/* visual end -- e.g. restore status line */
static char *TI;	/* terminal init -- whatever needed for screen ops */
static char *TE;	/* terminal ops end */
static char *CM;	/* cursor motion, used by tgoto() */
static char *CE;	/* clear to end of line */
static char *DL;	/* hardware delete line */
static char *AL;	/* hardware add (insert) line */
static char *CL;	/* clear screen */

extern char PC;		/* Pad character, usually '\0' */

static char *pcstr;
extern char *tgoto (), *tgetstr ();	/* termlib routines */

static char caps[128];		/* space for decoded capability strings */
static char *addr_caps;		/* address of caps for relocation */

#define TERMBUFSIZ	1024+1
static char termbuf[TERMBUFSIZ];

/* getdescrip --- get descriptions out of termcap entry */

static getdescrip ()
{
	int i;
	static struct _table {
		char *name;
		char **ptr_to_cap;
		} table[] = {
			"vs",	& VS,
			"ve",	& VE,
			"ti",	& TI,
			"te",	& TE,
			"cm",	& CM,
			"ce",	& CE,
			"dl",	& DL,
			"al",	& AL,
			"cl",	& CL,
			"pc",	& pcstr,
			NULL,	NULL
			};

	AM = tgetflag ("am");		/* only boolean se needs */

	/* get string values */

	for (i = 0; table[i].name != NULL; i++)
		*(table[i].ptr_to_cap) = tgetstr (table[i].name, & addr_caps);
}

/* setcaps -- get the capabilities from termcap file into termbuf */

static setcaps (term)
char *term;
{
	switch (tgetent (termbuf, term)) {
	case -1:
		error (NO, "se: couldn't open termcap file.");

	case 0:
		error (NO, "se: no termcap entry for %s terminals.", term);

	case 1:
		addr_caps = caps;
		getdescrip ();		/* get terminal description */
		Nrows = tgetnum ("li");
		Ncols = tgetnum ("co");
		break;

	default:
		error (YES, "in setcaps: can't happen.\n");
	}

	return (OK);
}

#else

/* use the new terminfo package */
/*
 * Do NOT include <curses.h>, since it redefines
 * USG, ERR, and OK, to values inconsistent with what
 * we use.
 */

/* fix a problem in /usr/include/term.h */
#include <termio.h>
typedef struct termio SGTTY;

#include <term.h>	/* should be all we really need */

#define AM	auto_right_margin
#define TI	enter_ca_mode
#define TE	exit_ca_mode
#define VS	cursor_visible
#define VE	cursor_normal
#define CL	clear_screen
#define CE	clr_eol
#define DL	delete_line
#define AL	insert_line

/* setcaps -- get the capabilities from the terminfo database */

static setcaps (term)
char *term;
{
	int ret = 0;

	setupterm (term, 1, & ret);
	if (ret != 1)
		return (ERR);
	Nrows = lines;
	Ncols = columns;

	return (OK);
}
#endif

/* t_init -- put out terminal initialization string */

t_init ()
{
	if (VS)
		tputs (VS, 1, outc);
	if (TI)
		tputs (TI, 1, outc);	/* terminal initializations */
}

/* t_exit -- put out strings to turn off whatever modes we had turned on */

t_exit ()
{
	/* terminal exiting strings */
	if (TE)
		tputs (TE, 1, outc);
	if (VE)
		tputs (VE, 1, outc);
	tflush ();	/* force it out */
}

/* winsize --- get the size of the window from the windowing system */
/*		also arrange to catch the windowing signal */

#include <signal.h>

#ifdef SIGWIND			/* UNIX PC */
#include <sys/font.h>
#include <sys/window.h>
#define WINSIG		SIGWIND
#define WINIOCTL	WIOCGETD
#define WINSTRUCT	uwdata
#define COLS		(w.uw_width / w.uw_hs)
#define ROWS		(w.uw_height / w.uw_vs)
#endif

#ifdef SIGWINCH			/* 4.3 BSD and/or Sun 3.x */

#define WINSIG		SIGWINCH

#ifdef sun
#undef NEWLINE		/* shouldn't hurt; these are in sun include files */
#undef TAB
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/tty.h>
#define WINIOCTL TIOCGSIZE
#define WINSTRUCT ttysize
#define COLS w.ts_cols
#define ROWS w.ts_lines

#else

#include <sys/ioctl.h>
#define WINIOCTL	TIOCGWINSZ
#define WINSTRUCT	winsize
#define COLS w.ws_col
#define ROWS w.ws_row
#endif
#endif

static struct WINSTRUCT w;

winsize ()
{
#if defined(SIGWIND) || defined(SIGWINCH)
	static int first = 1;
	static char savestatus[MAXCOLS];
	int row, oldstatus = Nrows - 1;
	int cols, rows;

	signal (WINSIG, winsize);

	if (ioctl (0, WINIOCTL, (char *) & w) != -1)
	{
		cols = COLS;
		rows = ROWS;

		if (first)
		{
			first = 0;
			if (cols && rows)
			{
				Ncols = cols;
				Nrows = rows;
			}
			return;		/* don't redraw screen */
		}
		else if (Ncols == cols && Nrows == rows)
		{
			/* only position changed */
#ifdef SIGWIND
			remark ("window repositioned");
#endif
			return;
		}
		else
		{
			if (cols && rows)
			{
				Ncols = cols;
				Nrows = rows;
			}
		}
	}
	else
		return;

	move_ (Screen_image[oldstatus], savestatus, MAXCOLS);
	clrscreen ();
	Toprow = 0;
	Botrow = Nrows - 3;
	Cmdrow = Botrow + 1;
	Sclen = -1;

	for (row = 0; row < Nrows; row++)
		move_ (Blanks, Screen_image[row], MAXCOLS);
		/* clear screen */

	First_affected = Topln;
	adjust_window (Curln, Curln);
	updscreen ();	/* reload from buffer */
	loadstr (savestatus, Nrows - 1, 0, Ncols);
	remark ("window size change");
	tflush ();
#endif
}

#else

/* begin terminal dependant routines */

/* addspos --- position cursor to (row, col) on ADDS Consul 980 */

static addspos (row, col)
int row, col;
{
	char coord;
	int ntabs, where;

	if (Currow != row || col < Curcol - 7)
	{
		twrite (1, "\013", 1);	/* VT */
		coord = '@' + row;
		twrite (1, &coord, 1);
		Currow = row;
		Curcol = 0;
	}

	if (col > Curcol + 2)
	{
		ntabs = (col + 2) / 5;	/* from beginning */
		where = ntabs * 5;
		ntabs -= Curcol / 5;	/* from Curcol */
		if (ntabs + abs (where - col) <= 4)
		{
			for (; ntabs > 0; ntabs--)
				twrite (1, "\t", 1);
			Curcol = where;
		}
	}

	if (col > Curcol + 4)
	{
		where = col - Curcol;
		twrite (1, "\033\005", 2);	/* ESC ENQ */
		coord = '0' + (where / 10);
		twrite (1, &coord, 1);
		coord = '0' + (where % 10);
		twrite (1, &coord, 1);
		Curcol = col;
	}

	while (Curcol < col)
	{
		twrite (1, &Screen_image[Currow][Curcol], 1);
		Curcol++;
	}

	while (Curcol > col)
	{
		twrite (1, "\b", 1);
		Curcol--;
	}
}

/* admpos --- position cursor to (row, col) on ADM-3A and ADM-31 terminals */

static admpos (row, col)
int row, col;
{
	int dist;
	char coord;

	dist = col - Curcol;
	if (dist < 0)
		dist = -dist;
	if (row == Currow && dist < 4)  /* 4 chars for abs. position */
	{
		while (Curcol < col)
		{
			twrite (1, &Screen_image[Currow][Curcol], 1);
			Curcol++;
		}
		while (Curcol > col)
		{
			twrite (1, "\b", 1);
			Curcol--;
		}
	}
	else
	{
		twrite (1, "\033=", 2);
		coord = row + ' ';
		twrite (1, &coord, 1);
		coord = col + ' ';
		twrite (1, &coord, 1);
		Currow = row;
		Curcol = col;
	}
}



/* ansipos --- position cursor on ANSI X something-or-other terminals */

static ansipos (row, col)
register int row, col;
{
	register int dist;

	char absseq[20], relseq[50];
	int absp = 0;
	register int relp = 0;
	register int trow, tcol;

	/*** Build relative positioning string--handle row first ***/
	trow = Currow; 
	tcol = Curcol;
	if (row >= trow && row <= trow + 3)
		for (; trow < row; trow++)
			relseq[relp++] = '\012';
	else if (row < trow && row >= trow - 1)
		for (; trow > row; trow--)
		{ 
			relseq[relp++] = '\033'; 
			relseq[relp++] = 'M'; 
		}
	else if (row >= trow)
	{
		relseq[relp++] = '\033';
		relseq[relp++] = '[';
		dist = row - trow;
		if (dist >= 10)
			relseq[relp++] = '0' + dist / 10;
		relseq[relp++] = '0' + dist % 10;
		relseq[relp++] = 'B';
		trow = row;
	}
	else /* row < trow */
	{
		relseq[relp++] = '\033';
		relseq[relp++] = '[';
		dist = trow - row;
		if (dist >= 10)
			relseq[relp++] = '0' + dist / 10;
		relseq[relp++] = '0' + dist % 10;
		relseq[relp++] = 'A';
		trow = row;
	}

	/*** Now do the column part of relative positioning ***/
	if (col >= tcol - 2 && col <= tcol + 2)
		;       /* skip coarse positioning -- just do the fine stuff */
	else
	{
		if (col <= 4)
		{
			relseq[relp++] = '\015';
			tcol = 0;
		}
		dist = col - tcol;
		if (col < 72 && dist > 2
		    && dist < 8 && (col + 1) % 8 <= 2)
		{
			relseq[relp++] = '\t';
			tcol = ((tcol + 8) / 8) * 8;
		}
	}
	dist = col - tcol;
	if (dist < 0)
		dist = -dist;
	if (dist == 0)
		;
	else if (dist < 4)  /* 4 chars for abs. position */
	{
		while (tcol < col)
		{
			relseq[relp++] = Screen_image[trow][tcol];
			tcol++;
		}
		while (tcol > col)
		{
			relseq[relp++] = '\b';
			tcol--;
		}
	}
	else if (col >= tcol)
	{
		relseq[relp++] = '\033';
		relseq[relp++] = '[';
		if (dist >= 10)
			relseq[relp++] = '0' + dist / 10;
		relseq[relp++] = '0' + dist % 10;
		relseq[relp++] = 'C';
		tcol = col;
	}
	else /* if (col < tcol) */
	{
		relseq[relp++] = '\033';
		relseq[relp++] = '[';
		if (dist >= 10)
			relseq[relp++] = '0' + dist / 10;
		relseq[relp++] = '0' + dist % 10;
		relseq[relp++] = 'D';
		tcol = col;
	}

	/*** If relative positioning will do it, forget absolute ***/
	if (relp <= 5)
		twrite (1, relseq, relp);
	else
	{
		absseq[absp++] = '\033';
		absseq[absp++] = '[';
		if (row >= 9)
			absseq[absp++] = '0' + (row + 1) / 10;
		absseq[absp++] = '0' + (row + 1) % 10;
		absseq[absp++] = ';';
		if (col >= 9)
			absseq[absp++] = '0' + (col + 1) / 10;
		absseq[absp++] = '0' + (col + 1) % 10;
		absseq[absp++] = 'H';
		if (absp >= relp)
			twrite (1, relseq, relp);
		else
			twrite (1, absseq, absp);
	}
	Curcol = col;
	Currow = row;
}



/* anppos --- position cursor on Allen & Paul model 1 */

static anppos (row, col)
int row, col;
{
	char coord;

	if (row == Currow)      /* if close, just sneak right or left */
	{
		if (col == Curcol + 1)
			twrite (1, "\t", 1);
		else if (col == Curcol + 2)
			twrite (1, "\t\t", 2);
		else if (col == Curcol - 1)
			twrite (1, "\b", 1);
		else if (col == Curcol - 2)
			twrite (1, "\b\b", 2);
		else
		{
			twrite (1, "\033C", 2);
			coord = col + ' ';
			twrite (1, &coord, 1);
		}
	}

	else if (col == Curcol) /* if close, sneak up or down */
	{
		if (row == Currow + 1)
			twrite (1, "\012", 1);
		else if (row == Currow + 2)
			twrite (1, "\012\012", 2);
		else if (row == Currow - 1)
			twrite (1, "\013", 1);
		else if (row == Currow - 2)
			twrite (1, "\013\013", 2);
		else
		{
		/* because of bug in anp software, abs row pos is not working.
		 * the following code was replaced to compensate:
		 *
		 *          twrite (1, "\033R", 2);
		 *          coord = row + ' ';
		 *          twrite (1, &coord, 1);
		 */
			twrite (1, "\033P", 2);
			coord = row + ' ';
			twrite (1, &coord, 1);
			coord = col + ' ';
			twrite (1, &coord, 1);
		}
	}
	else	/* resort to absolute positioning */
	{
		twrite (1, "\033P", 2);
		coord = row + ' ';
		twrite (1, &coord, 1);
		coord = col + ' ';
		twrite (1, &coord, 1);
	}

	Currow = row;
	Curcol = col;
}

/* b200coord --- transmit a coordinate for Beehive 200 cursor addressing */

static b200coord (coord)
int coord;
{
	char acc;
	int tens, units;

	tens = coord / 10;
	units = coord - 10 * tens;
	acc = units + 16 * tens;

	twrite (1, & acc, 1);
}

/* beepos --- position cursor on Beehive terminal */

static beepos (row, col)
int row, col;
{
	if (row == Currow + 1 && col == 0 && Term_type != SBEE)
	{
		twrite (1, "\r\n", 2);		/*  CR LF */
		Curcol = 0;
		Currow++;
	}
	else if (row == 0 && col == 0)		/* home cursor */
	{
		twrite (1, "\033H", 2);
		Currow = Curcol = 0;
	}
	else if (row == Currow && col > Curcol && col <= Curcol + 4)
		while (Curcol != col)
		{
			twrite (1, &Screen_image[Currow][Curcol], 1);
			Curcol++;
		}
	else if (row == Currow && col < Curcol && col >= Curcol - 4)
		while (Curcol != col)
		{
			twrite (1, "\b", 1);
			Curcol--;
		}
	else		/* resort to absolute addressing */
	{
		twrite (1, "\033F", 2);
		if (Term_type == BEE200 || Term_type == SOL)
		{
			b200coord (row);
			b200coord (col);
		}
		else if (Term_type == BEE150)
		{
			char r, c;

			r = row + ' ';
			c = col + ' ';
			twrite (1, &r, 1);
			twrite (1, &c, 1);
		}
		else		/* is superbee */
		{
			sbeecoord (col);
			sbeecoord (row);
		}

		Currow = row;
		Curcol = col;
	}
}

/* cgpos --- position cursor on Chromatics CG */

static cgpos (row, col)
int row, col;
{
	char i, j;

	if (row == Currow + 1 && col == 0)
	{
		twrite (1, "\r\n", 2);		/* CR LF */
		Curcol = 0;
		Currow++;
	}
	else if (row == 0 && col == 0)		/* home cursor */
	{
		twrite (1, "\034", 1);	/* FS */
		Currow = Curcol = 0;
	}
	else if (row == Currow && col > Curcol && col <= Curcol + 7)
		while (Curcol != col)
		{
			twrite (1, "\035", 1);	/* GS */
			Curcol++;
		}
	else if (row == Currow && col < Curcol && col >= Curcol - 7)
		while (Curcol != col)
		{
			twrite (1, "\b", 1);
			Curcol--;
		}
	else
	{
		/* resort to absolute addressing */
		twrite (1, "\001U", 2);		/* SOH U */
		i = 511 - (10 * row);
		j = 6 * col;
		cgcoord (j);
		cgcoord (i);
		Currow = row;
		Curcol = col;
	}

}


/* cgcoord --- output a decimal coordinate for Chromatics CG */

static cgcoord (i)
int i;
{
	int units, tens, hundreds;
	char coords[4];

	units = i % 10;
	i /= 10;
	tens = i % 10;
	i /= 10;
	hundreds = i % 10;

	coords[0] = hundreds + 16 + ' ';
	coords[1] = tens + 16 + ' ';
	coords[2] = units + 16 + ' ';
	coords[3] = EOS;
	twrite (1, coords, 3);
}



/* gt40pos --- position cursor to (row, col) on DEC GT40 with Waugh software */

static gt40pos (row, col)
int row, col;
{
	char coord;

	if (row != Currow && col != Curcol)	/* absolute positioning */
	{
		twrite (1, "\033", 1);
		coord = row + ' ';
		twrite (1, &coord, 1);
		coord = col + ' ';
		twrite (1, &coord, 1);
		Currow = row;
		Curcol = col;
	}
	else if (row != Currow)		/* col must = Curcol */
	{				/* vertical positioning */
		twrite (1, "\006", 1);	/* ACK */
		coord = row + ' ';
		twrite (1, &coord, 1);
		Currow = row;
	}
	else if (abs (col - Curcol) < 2)
		uhcm (col);
	else
	{
		twrite (1, "\025", 1);	/* NACK */
		coord = col + ' ';
		twrite (1, &coord, 1);
		Curcol = col;
	}
}



/* h19pos --- position cursor on Heath H19 (DEC VT52 compatible, supposedly) */

static h19pos (row, col)
int row, col;
{
	int dist;
	char coord;

	dist = col - Curcol;
	if (dist < 0)
		dist = -dist;
	if (row == Currow && dist < 4)  /* 4 chars for abs. position */
	{
		while (Curcol < col)
		{
			twrite (1, &Screen_image[Currow][Curcol], 1);
			Curcol++;
		}
		while (Curcol > col)
		{
			twrite (1, "\b", 1);
			Curcol--;
		}
	}
	else
	{
		twrite (1, "\033Y", 2);
		coord = row + ' ';
		twrite (1, &coord, 1);
		coord = col + ' ';
		twrite (1, &coord, 1);
		Currow = row;
		Curcol = col;
	}
}

/* hp21pos --- position cursor on HP 2621 terminal */

static hp21pos (row, col)
int row, col;
{
	int units, tens;

	if (row == Currow && col == 0)
	{
		twrite (1, "\r\n", 2);		/* CR LF */
		Curcol = 0;
		Currow++;
	}
	else if (row == 0 && col == 0)		/* home cursor */
	{
		twrite (1, "\033H", 2);
		Currow = Curcol = 0;
	}
	else if (row == Currow && col > Curcol && col <= Curcol + 4)
		while (Curcol != col)
		{
			twrite (1, &Screen_image[Currow][Curcol], 1);
			Curcol++;
		}
	else if (row == Currow && col < Curcol && col >= Curcol - 4)
		while (Curcol != col)
		{
			twrite (1, "\b", 1);
			Curcol--;
		}
	else if (2 * abs (Currow - row) + abs (Curcol - col) <= 7)
	{
		while (Currow < row)
		{
			twrite (1, "\033B", 2);
			Currow++;
		}
		while (Currow > row)
		{
			twrite (1, "\033A", 2);
			Currow--;
		}
		while (Curcol > col)
		{
			twrite (1, "\b", 1);
			Curcol--;
		}
		while (Curcol < col)
		{
			twrite (1, & Screen_image[Currow][Curcol], 1);
			Curcol++;
		}
	}
	else
	{
		/* resort to absolute addressing */
		char c;

		twrite (1, "\033&a", 3);
		units = row % 10;
		tens = row / 10;
		if (tens != 0)
		{
			c = tens + '0';
			twrite (1, &c, 1);
		}
		c = units + '0';
		twrite (1, &c, 1);
		twrite (1, "y", 1);
		units = col % 10;
		tens = col / 10;
		if (tens != 0)
		{
			c = tens + '0';
			twrite (1, &c, 1);
		}
		c = units + '0';
		twrite (1, &c, 1);
		twrite (1, "C", 1);
		Currow = row;
		Curcol = col;
	}
}


/* hazpos --- position cursor on Hazeltine 1510 */

static hazpos (row, col)
int row, col;
{
	int dist;
	char c;

	dist = col - Curcol;
	if (dist < 0)
		dist = -dist;
	if (row == Currow && dist < 4)  /* 4 chars for abs. position */
	{
		while (Curcol < col)
		{
			twrite (1, &Screen_image[Currow][Curcol], 1);
			Curcol++;
		}
		while (Curcol > col)
		{
			twrite (1, "\b", 1);
			Curcol--;
		}
	}
	else
	{
		twrite (1, "\033\021", 2);
		c = col;
		twrite (1, &c, 1);
		c = row;
		twrite (1, &c, 1);
		Currow = row;
		Curcol = col;
	}
}


/* ibmpos --- position cursor on IBM 3101 terminal */

static ibmpos (row, col)
int row, col;
{
	int dist;
	static char abspos[] = "\033\Y\0\0";

	dist = col - Curcol;
	if (dist < 0)
		dist = -dist;
	
	if (row == Currow && dist < 4)		/* 4 chars for abs pos */
	{
		while (Curcol < col)
		{
			twrite (1, & Screen_image[Currow][Curcol], 1);
			Curcol++;
		}
		while (Curcol > col)
		{
			twrite (1, "\b", 1);
			Curcol--;
		}
	}
	else
	{
		abspos[2] = row + ' ';
		abspos[3] = col + ' ';
		twrite (1, abspos, 4);
		Currow = row;
		Curcol = col;
	}
}



/* iscpos --- position cursor on ISC 8001 color terminal */

static iscpos (row, col)
int row, col;
{
	char r, c;

	if (row == 0 && col == 0)
		twrite (1, "\b", 1);
	else
	{
		twrite (1, "\003", 1);		/* ETX */
		r = row;
		c = col;
		twrite (1, & r, 1);
		twrite (1, & c, 1);
	}

	Currow = row;
	Curcol = col;
}

/* netpos --- position cursor on Netron terminal */

static netpos (row, col)
int row, col;
{
	static char abspos[] = "\033=\0\0";

	abspos[2] = (char) row;
	abspos[3] = (char) col;
	twrite (1, abspos, 4);
	Currow = row;
	Curcol = col;
}

/* pepos --- position cursor on Perkin-Elmer 550 & 1100 terminals */

static pepos (row, col)
int row, col;
{
	char coord;

	/* get on correct row first */
	if (Currow == row)
		;		/* already on correct row; nothing to do */
	else if (row == Currow - 1)
	{
		twrite (1, "\033A", 2);		/* cursor up */
		Currow--;
	}
	else if (row == Currow + 1)
	{
		twrite (1, "\033B", 2);		/* cursor down */
		Currow++;
	}
	else
	{
		/* vertical absolute positioning */
		twrite (1, "\033X", 2);
		coord = row + ' ';
		twrite (1, & coord, 1);
	}

	/* now perform horizontal motion */
	if (abs (col - Curcol) > 3)	/* do absolute horizontal position */
	{
		twrite (1, "\033Y", 2);
		coord = col + ' ';
		twrite (1, &coord, 1);
		Curcol = col;
	}
	else
		uhcm (col);
}

/* sbeecoord --- transmit a coordinate for Superbee terminal */

static sbeecoord (coord)
int coord;
{
	char r, c;

	r = (coord / 10) + ' ';
	c = (coord % 10) + ' ';
	twrite (1, & r, 1);
	twrite (1, & c, 1);
}

/* trspos --- position cursor on TRS80 Model 1 */

static trspos (row, col)
int row, col;
{
	while (Currow != row)
	{
		if (Currow > row)
		{
			twrite (1, "\033", 1);
			Currow--;
		}
		else
		{
			twrite (1, "\032", 1);		/* SUB */
			Currow++;
		}
	}

	if (Curcol != col)
	{
		if (col > Curcol)
			while (col > Curcol)
			{
				twrite (1, "\031", 1);	/* EM */
				Curcol++;
			}
		else if (col < Curcol / 2)
		{
			twrite (1, "\035", 1);	/* GS */
			Curcol = 0;
			while (Curcol < col)
			{
				twrite (1, "\031", 1);	/* EM */
				Curcol++;
			}
		}
		else
			while (col < Curcol)
			{
				twrite (1, "\030", 1);	/* CAN */
				Curcol--;
			}
	}
}



/* tvtpos --- position cursor on Allen's TV Typetwriter II */

static tvtpos (row, col)
int row, col;
{
	register int horirel, horiabs, vertrel, vertabs;

	horirel = col - Curcol;
	if (horirel < 0)
		horirel = -horirel;

	horiabs = col;

	if (row <= Currow)
		vertrel = Currow - row;
	else
		vertrel = Nrows - (row - Currow);

	if (row == 0)
		vertabs = 0;
	else
		vertabs = Nrows - row;

	if (1 + horiabs + vertabs <= horirel + vertrel)
	{
		twrite (1, "\014", 1);
		Currow = Curcol = 0;
	}

	while (Currow != row)
	{
		twrite (1, "\013", 1);
		Currow--;
		if (Currow < 0)
			Currow = Nrows - 1;
	}

	if (Curcol > col)
		for (; Curcol != col; Curcol--)
			twrite (1, "\b", 1);
	else
		for (; Curcol != col; Curcol++)
			twrite (1, "\t", 1);
}



/* regentpos --- position cursor on ADDS Regent 100 */

static regentpos (row, col)
int row, col;
{
	int dist;
	char coord;

	dist = col - Curcol;
	if (dist < 0)
		dist = -dist;
	
	if (dist > 4 || Currow != row)
	{
		twrite (1, "\033Y", 2);
		coord = ' ' + row;
		twrite (1, &coord, 1);
		coord = ' ' + col;
		twrite (1, &coord, 1);
		Currow = row;
		Curcol = col;
	}
	else
	{
		while (row < Currow)
		{
			twrite (1, "\032", 1);	/* SUB, cursor up */
			Currow--;
		}
		while (row > Currow)
		{
			twrite (1, "\n", 1);
			Currow++;
			Curcol = 1;
		}
		if (col > Curcol)
			while (col != Curcol)
			{
				twrite (1, &Screen_image[Currow][Curcol], 1);
				Curcol++;
			}
		else if ((Curcol - col) * 2 >= Ncols)
			while (col != Curcol)
			{
				twrite (1, "\006", 1);	/* ACK, cursor right */
				if (Curcol == Ncols)
					Curcol = 1;
				else
					Curcol++;
			}
		else
			while (col != Curcol)
			{
				twrite (1, "\b", 1);
				Curcol--;
			}
	}
}



/* vipos --- position cursor on Visual 200 & 50 */

static vipos (row, col)
register int row, col;
{
	register int dist;
	register char coord;

	if (row == Currow + 1 && col < 3)
	{
		twrite (1, "\015\012", 2);
		Currow++;
		Curcol = 0;
	}
	dist = col - Curcol;
	if (Term_type == VI200 && row == Currow && col < 72 && dist > 2
	    && dist < 8 && (col + 1) % 8 < 2)
	{
		twrite (1, "\t", 1);
		Curcol = ((Curcol + 7) / 8) * 8;
		dist = col - Curcol;
	}
	if (dist < 0)
		dist = -dist;
	if (row == Currow && dist < 4)  /* 4 chars for abs. position */
	{
		while (Curcol < col)
		{
			twrite (1, &Screen_image[Currow][Curcol], 1);
			Curcol++;
		}
		while (Curcol > col)
		{
			twrite (1, "\b", 1);
			Curcol--;
		}
	}
	else
	{
		twrite (1, "\033Y", 2);
		coord = row + ' ';
		twrite (1, &coord, 1);
		coord = col + ' ';
		twrite (1, &coord, 1);
		Currow = row;
		Curcol = col;
	}
}



/* vcpos --- position cursor Volker-Craig 4404 (ADM3A mode) */

static vcpos (row, col)
int row, col;
{
	int dist;
	char coord;

	dist = col - Curcol;
	if (dist < 0)
		dist = -dist;
	if (row == Currow && dist < 4)  /* 4 chars for abs. position */
	{
		while (Curcol < col)
		{
			twrite (1, &Screen_image[Currow][Curcol], 1);
			Curcol++;
		}
		while (Curcol > col)
		{
			twrite (1, "\b", 1);
			Curcol--;
		}
	}
	else
	{
		twrite (1, "\033=", 2);
		coord = row + ' ';
		twrite (1, &coord, 1);
		coord = col + ' ';
		twrite (1, &coord, 1);
		Currow = row;
		Curcol = col;
	}
}


/* espritpos --- position cursor on Hazeltine Esprit */

static espritpos (row, col)
int row, col;
{
	int dist;
	char c;

	dist = col - Curcol;
	if (dist < 0)
		dist = -dist;
	if (row == Currow && dist < 4)  /* 4 chars for abs. position */
	{
		while (Curcol < col)
		{
			twrite (1, &Screen_image[Currow][Curcol], 1);
			Curcol++;
		}
		while (Curcol > col)
		{
			twrite (1, "\b", 1);
			Curcol--;
		}
	}
	else
	{
		twrite (1, "\033\021", 2);
		c = col >= 32 ? col : col + '`';
		twrite (1, &c, 1);
		c = row >= 32 ? row : row + '`';
		twrite (1, &c, 1);
		Currow = row;
		Curcol = col;
	}
}

/* uhcm --- universal horizontal cursor motion */

static uhcm (col)
int col;
{
	while (Curcol < col)
	{
		twrite (1, &Screen_image[Currow][Curcol], 1);
		Curcol++;
	}

	while (Curcol > col)
	{
		twrite (1, "\b", 1);
		Curcol--;
	}
}


/* senddelay --- send NULs to delay n milliseconds */

senddelay (n)
int n;
{
	register int q;

	q = (long) n * Tspeed / 1000l;
	while (q > 0)
	{
		twrite (1, "\0\0\0\0\0\0\0\0\0\0", q > 10 ? 10 : q);
		q -= 10;
	}
}


/* decode_mnemonic --- decode a terminal type mnemonic */

static int decode_mnemonic (str)
char str[];
{
	int i;
	int strbsr ();

	static struct {
		char *s;
		int t;
	} stab[] = {
		"950",          TVI950,
		"adm31",        ADM31,  
		"adm3a",        ADM3A,  
		"anp",          ANP,    
		"b150",         BEE150,   
		"b200",         BEE200,   
		"cg",           CG,     
		"consul",       ADDS980,
		"esprit",       ESPRIT,
		"fox",          FOX,    
		"gt40",         GT40,   
		"h19",          H19,    
		"haz",          HAZ1510,
		"hp21",         HP21,   
		"hz1510",       HAZ1510,
		"ibm",          IBM,    
		"isc",          ISC8001,
		"netron",       NETRON, 
		"regent",       ADDS100,
		"regent40",     ADDS100,	/* kludge */
		"sbee",         SBEE,   
		"sol",          SOL,    
		"trs80",        TRS80,  
		"ts1",          TS1,
		"tvt",          TVT,    
		"vc4404",       VC4404,
		"vi200",        VI200,
		"vi300",	VI300,
		"vi50",         VI50,
	};

	i = strbsr ((char *)stab, sizeof (stab), sizeof (stab[0]), str);
	if (i == EOF)
		return (ERR);
	else
		return (stab[i].t);
}
#endif

/* terminal handling functions used throughout the editor */

/* send --- send a printable character, predict cursor position */

send (chr)
char chr;
{
	if (Currow == Nrows - 1 && Curcol == Ncols - 1)
		return;         /* anything in corner causes scroll... */

#ifndef HARD_TERMS
	outc (chr);
#else
	twrite (1, &chr, 1);
#endif

	if (Curcol == Ncols - 1)
	{
#ifndef HARD_TERMS
		if (AM)		/* terminal wraps when hits last column */
#else
		if (Term_type != TVT && Term_type != NETRON
		    && Term_type != ESPRIT && Term_type != VI300)
#endif
		{
			Curcol = 0;
			Currow++;
		}
	}
	else		/* cursor not at extreme right */
		Curcol++;
}

/* clrscreen --- clear entire screen */

clrscreen ()
{
	Curcol = Currow = 0;
	/* clearing screen homes cursor to upper left corner */
	/* on all terminals */

#ifndef HARD_TERMS
	tputs (CL, 1, outc);
#else
	switch (Term_type) {
	case ADDS980:
	case ADDS100:
	case GT40:
	case CG:
	case ISC8001:
	case ANP:
	case NETRON:
		twrite (1, "\014", 1);
		break;
	case FOX:
		twrite (1, "\033K", 2);		/* clear display and all tabs */
		break;
	case TVT:
		twrite (1, "\014\017", 2);	/* home, erase to end of screen */
		break;
	case BEE150:
	case BEE200:
	case SBEE:
	case SOL:
	case H19:
		twrite (1, "\033E", 2);
		break;
	case HAZ1510:
	case ESPRIT:
		twrite (1, "\033\034", 2);
		break;
	case ADM3A:
	case VC4404:
	case TVI950:
		twrite (1, "\032", 1);
		break;
	case TS1:
		twrite (1, "\033*", 2);
		break;
	case ADM31:
		twrite (1, "\033+", 2);
		break;
	case IBM:
		twrite (1, "\033L", 2);
		break;
	case HP21:
		twrite (1, "\033H\033J", 4);	/* home cursor, erase to end of screen */
		break;
	case TRS80:
		twrite (1, "\034\037", 2);
		break;
	case VI200:
		twrite (1, "\033v", 2);
		break;
	case VI300:
		twrite (1, "\033[H\033[J", 6);
		/* home cursor, clear screen */
		break;
	case VI50:
		twrite (1, "\033v", 2);
		senddelay (30);
		break;
	}

	senddelay (20);
#endif
}


/* position_cursor --- position terminal's cursor to (row, col) */

position_cursor (row, col)
int row, col;
{
	if (row < Nrows && row >= 0		/* within vertical range? */
	    && col < Ncols && col >= 0		/* within horizontal range? */
	    && (row != Currow || col != Curcol))/* not already there? */
#ifndef HARD_TERMS
	{
		if (row == Currow && abs (Curcol - col) <= 4)
		{
			/* short motion in current line */
			if (Curcol < col)
				for (; Curcol != col; Curcol++)
					twrite (1, &Screen_image[Currow][Curcol], 1);
			else
				for (; Curcol != col; Curcol--)
					twrite (1, "\b", 1);
		}
		else
		{
#if defined (USG) && defined(S5R2)
			tputs (tparm (cursor_address, row, col), 1, outc);
#else
			tputs (tgoto (CM, col, row), 1, outc);
#endif
			Currow = row;
			Curcol = col;
		}
	}
#else
		switch (Term_type) {
		case ADDS980:
			addspos (row, col);
			break;
		case ADDS100:
			regentpos (row, col);
			break;
		case HP21:
			hp21pos (row, col);
			break;
		case FOX:
			pepos (row, col);
			break;
		case TVT:
			tvtpos (row, col);
			break;
		case GT40:
			gt40pos (row, col);
			break;
		case BEE150:
		case BEE200:
		case SBEE:
		case SOL:
			beepos (row, col);
			break;
		case VC4404:
			vcpos (row, col);
			break;
		case HAZ1510:
			hazpos (row, col);
			break;
		case ESPRIT:
			espritpos (row, col);
			break;
		case CG:
			cgpos (row, col);
			break;
		case ISC8001:
			iscpos (row, col);
			break;
		case ADM3A:
		case ADM31:
		case TS1:
		case TVI950:
			admpos (row, col);
			break;
		case IBM:
			ibmpos (row, col);
			break;
		case ANP:
			anppos (row, col);
			break;
		case NETRON:
			netpos (row, col);
			break;
		case H19:
			h19pos (row, col);
			break;
		case TRS80:
			trspos (row, col);
			break;
		case VI200:  
		case VI50:
			vipos (row, col);
			break;
		case VI300:
			ansipos (row, col);
			break;
		}
#endif
}


/* setscreen --- initialize screen and associated descriptive variables */

setscreen ()
{
	register int row, col;

#ifndef HARD_TERMS
	t_init ();	/* put out the 'ti' and 'vs' capabilities */
#endif
	clrscreen ();	/* clear physical screen, set cursor position */

	Toprow = 0;
	Botrow = Nrows - 3; /* 1 for 0-origin, 1 for status, 1 for cmd */
	Cmdrow = Botrow + 1;
	Topln = 1;
	Sclen = -1;         /* make sure we assume nothing on the screen */

	for (row = 0; row < Nrows; row++)	/* now clear virtual screen */
		for (col = 0; col < Ncols; col++)
			Screen_image[row][col] = ' ';

	for (col = 0; col < Ncols; col++)	/* and clear out status line */
		Msgalloc[col] = NOMSG;

	Insert_mode = NO;
}


/* inslines --- insert 'n' lines on the screen at 'row' */

inslines (row, n)
int row, n;
{
	register int i;
	int delay;

	position_cursor (row, 0);
#ifdef HARD_TERMS
	if (Term_type == VI300)
	{
		char pseq[10];
		register int pp = 0;
		pseq[pp++] = '\033';
		pseq[pp++] = '[';
		if (n >= 10)
			pseq[pp++] = '0' + n / 10;
		pseq[pp++] = '0' + n % 10;
		pseq[pp++] = 'L';
		twrite (1, pseq, pp);
		delay = 0;
	}
	else
#endif
		for (i = 0; i < n; i++)
		{
#ifndef HARD_TERMS
			tputs (AL, n, outc);
			tflush ();
#else
			switch (Term_type) {
			case VI200:
				twrite (1, "\033L", 2);
				delay = 0;
				break;
			case VI50:
			case H19:
				twrite (1, "\033L", 2);
				delay = 32;
				break;
			case ESPRIT:
				twrite (1, "\033\032", 2);
				delay = 32;
				break;
			case TS1:
			case TVI950:
				twrite (1, "\033E", 2);
				delay = 0;
				break;
			case ADDS100:
				twrite (1, "\033M", 2);
				delay = 96;
				break;
			default:
				error (YES, "in inslines: shouldn't happen");
			}

			if (delay != 0)
				senddelay (delay);
#endif
		}

	for (i = Nrows - 1; i - n >= Currow; i--)
		move_ (Screen_image[i - n], Screen_image[i], Ncols);

	for (; i >= Currow; i--)
		move_ (Blanks, Screen_image[i], Ncols);
}


/* dellines --- delete 'n' lines beginning at 'row' */

dellines (row, n)
int row, n;
{
	register int i;
	int delay;

	position_cursor (row, 0);
#ifdef HARD_TERMS
	if (Term_type == VI300)
	{
		char pseq[10];
		register int pp = 0;
		pseq[pp++] = '\033';
		pseq[pp++] = '[';
		if (n >= 10)
			pseq[pp++] = '0' + n / 10;
		pseq[pp++] = '0' + n % 10;
		pseq[pp++] = 'M';
		twrite (1, pseq, pp);
		delay = 0;
	}
	else
#endif
		for (i = 0; i < n; i++)
		{
#ifndef HARD_TERMS
			tputs (DL, n, outc);
			tflush ();
#else
			switch (Term_type) {
			case VI200:
				twrite (1, "\033M", 2);
				delay = 0;
				break;
			case VI50:
				twrite (1, "\033M", 2);
				delay = 32;
				break;
			case H19:
				twrite (1, "\033M", 2);
				delay = 32;
				break;
			case TS1:
			case TVI950:
				twrite (1, "\033R", 2);
				delay = 0;
				break;
			case ESPRIT:
				twrite (1, "\033\023", 2);
				delay = 32;
				break;
			case ADDS100:
				twrite (1, "\033l", 2);
				delay = 96;
				break;
			default:
				error (YES, "in dellines: shouldn't happen");
			}

			if (delay != 0)
				senddelay (delay);
#endif
		}

	for (i = Currow; i + n < Nrows; i++)
		move_ (Screen_image[i + n], Screen_image[i], Ncols);

	for (; i < Nrows; i++)
		move_ (Blanks, Screen_image[i], Ncols);
}


/* hwinsdel --- return 1 if the terminal has hardware insert/delete */

int hwinsdel ()
{
	if (No_hardware == YES)
		return (NO);

#ifndef HARD_TERMS
	return (AL != NULL && DL != NULL);
#else
	switch (Term_type) {
	case VI300:
	case VI200:
	case VI50:
	case ESPRIT:
	case H19:
	case TS1:
	case TVI950:
	case ADDS100:
		return 1;
	}
	return 0;
#endif
}


/* clear_to_eol --- clear screen to end-of-line */

clear_to_eol (row, col)
int row, col;
{
	register int c, flag; 
	register int hardware = NO;

#ifdef HARD_TERMS
	switch (Term_type) {
	case BEE200:
	case BEE150:
	case FOX:
	case SBEE:
	case ADDS100:
	case HP21:
	case IBM:
	case ANP:
	case NETRON:
	case H19:
	case TS1:
	case TRS80:
	case ADM31:
	case VI200:
	case VI300:
	case VI50:
	case VC4404:
	case ESPRIT:
	case TVI950:
		hardware = YES;
		break;
	default:
		hardware = (Term_type == ADDS980 && row < Nrows - 1)
				|| (Term_type == TVT && row > 0);
	}
#else
	hardware = (CE != NULL);
#endif

	flag = NO;

	for (c = col; c < Ncols; c++)
		if (Screen_image[row][c] != ' ')
		{
			Screen_image[row][c] = ' ';
			if (hardware)
				flag = YES;
			else
			{
				position_cursor (row, c);
				send (' ');
			}
		}

	if (flag == YES)
	{
		position_cursor (row, col);
#ifndef HARD_TERMS
		tputs (CE, 1, outc);
#else
		switch (Term_type) {
		case BEE200: 
		case BEE150:
		case SBEE:
		case ADDS100:
		case HP21:
		case H19:
		case VC4404:
		case TS1:
		case TVI950:
		case VI50:
			twrite (1, "\033K", 2);
			break;
		case FOX:
		case IBM:
			twrite (1, "\033I", 2);
			break;
		case ADDS980:
			twrite (1, "\n", 1);
			Currow++;
			Curcol = 0;
			break;
		case ANP:
			twrite (1, "\033L", 2);
			break;
		case NETRON:
			twrite (1, "\005", 1);
			break;
		case TRS80:
			twrite (1, "\036", 1);
			break;
		case ADM31:
			twrite (1, "\033T", 2);
			break;
		case VI200:
			twrite (1, "\033x", 2);
			break;
		case VI300:
			twrite (1, "\033[K", 3);
			break;
		case ESPRIT:
			twrite (1, "\033\017", 2);
			break;
		case TVT:
			twrite (1, "\013\012", 2);
			break;
		} /* end switch */
#endif
	} /* end if (flag == YES) */
}

/* set_term -- initialize terminal parameters and actual capabilities */

set_term (type)
char *type; 
{
	if (type == NULL)
		error (NO, "se: terminal type not available");

	if (type[0] == EOS)
		error (NO, "in set_term: can't happen.");

	Ncols = Nrows = -1;

#ifdef HARD_TERMS
	if ((Term_type = decode_mnemonic (type)) == ERR)
		error (NO, "se: could not find terminal in internal database");

	switch (Term_type) {
	case ADDS980: 
	case FOX: 
	case HAZ1510: 
	case ADDS100:
	case BEE150: 
	case ADM3A: 
	case IBM: 
	case HP21: 
	case H19:
	case ADM31: 
	case VI200: 
	case VC4404: 
	case ESPRIT: 
	case TS1:
	case TVI950: 
	case VI50: 
	case VI300:
		Nrows = 24;
		Ncols = 80;
		break;
	case ANP:
		Nrows = 24;
		Ncols = 96;
		break;
	case SOL: 
	case NETRON: 
	case TRS80:
		Nrows = 16;
		Ncols = 64;
		break;
	case TVT:
		Nrows = 16;
		Ncols = 63;
		break;
	case GT40:
		Nrows = 32;
		Ncols = 73;
		break;
	case CG:
		Nrows = 51;
		Ncols = 85;
		break;
	case ISC8001:
		Nrows = 48;
		Ncols = 80;
		break;
	case BEE200: 
	case SBEE:
		Nrows = 25;
		Ncols = 80;
		break;
	}
#else
	if (setcaps (type) == ERR)
		error (NO, "se: could not find terminal in system database");


	PC = pcstr ? pcstr[0] : EOS;

	if (*tgoto (CM, 0, 0) == 'O')	/* OOPS returned.. */
		error (NO, "se: terminal does not have cursor motion.");

	/*
	 * first, get it from the library. then check the
	 * windowing system, if there is one.
	 */
	winsize ();
#endif

	if (Nrows == -1)
		error (NO, "se: could not determine number of rows");

	if (Ncols == -1)
		error (NO, "se: could not determine number of columns");

	return OK;
}
SHAR_EOF
fi # end of overwriting check
if test ! -d 'libchangetty'
then
	echo shar: creating directory "'libchangetty'"
	mkdir 'libchangetty'
fi
echo shar: entering directory "'libchangetty'"
cd 'libchangetty'
echo shar: extracting "'changetty.c'" '(5555 characters)'
if test -f 'changetty.c'
then
	echo shar: will not over-write existing file "'changetty.c'"
else
cat << \SHAR_EOF > 'changetty.c'
#ifndef lint
static char RCSid[] = "$Header: changetty.c,v 1.2 86/07/11 15:23:06 osadr Exp $";
#endif

/*
 * $Log:	changetty.c,v $
 * Revision 1.2  86/07/11  15:23:06  osadr
 * Removed Georgia Tech specific code.
 * 
 * Revision 1.1  86/05/06  13:31:06  osadr
 * Initial revision
 * 
 * 
 */

/*
** changetty.c
**
** Localize in one place all the data and functions
** needed to change to and from cbreak mode for
** the se screen editor.
**
** Only functions available to rest of se are:
** ttyedit(), ttynormal(), and getspeed().
**
** If USG is defined, we use the System V TTY driver.
** Otherwise (the default) we use the Berkeley terminal driver.
**
** If we are using System V, then the Release 2 version does not
** need ospeed.  If not release 2, we assume Release 1 that someone
** have moved the BSD termlib to.
*/

#include "../ascii.h"
#include "../constdefs.h"

#ifdef USG
#include <termio.h>
#else
#include <sgtty.h>
#endif

#if defined (BSD) || ! defined (S5R2)
extern short ospeed;		/* from the termlib library */
static int set_ospeed = NO;
#endif

#ifdef USG
/* all the info needed for the System V terminal driver */

typedef struct termio TTYINFO;	/* S5 control flags */
#else
/* all the info needed for the Berkeley terminal driver */

typedef struct junk {		/* terminal information */
	struct sgttyb sgttyb;	/* V7 control flags */
	struct tchars tchars;	/* V7 control characters */
	short local;		/* local mode settings */
	struct ltchars ltchars;	/* local control characters */
	} TTYINFO;
#endif

static TTYINFO OldTtyInfo;	/* initial state of terminal */
static TTYINFO NewTtyInfo;	/* modified state for editing */

static int first = YES;		/* first time anything called */


static init()
{
	if (gttyinfo(1, &OldTtyInfo) == -1)	/* get current state */
		error ("couldn't get TTY info from system. get help!\n");

	NewTtyInfo = OldTtyInfo;	/* copy it */
	mttyinfo(&NewTtyInfo);		/* change, but don't reset terminal */
	/* really should check the return value here ... */
}


ttyedit()	/* set the terminal to correct modes for editing */
{
	if (first == YES)
	{
		first = NO;
		init();
	}

	sttyinfo(1, &NewTtyInfo);	/* make the change */
	/* really should check the return value here too ... */
}

ttynormal()	/* set the terminal to correct modes for normal use */
{
	if (first)
	{
		first = NO;
		init();
	}

	sttyinfo(1, &OldTtyInfo);	/* make the change */
}

/* getspeed --- find out the terminal speed in characters/second */
/*		this routine only used if terminal types are hardwired */
/*		into se, however, since it will be in an archive, the */
/*		loader won't grab it if it isn't needed. */

int getspeed(fd)
int fd;
{
	register int i;
	TTYINFO ttybuf;
	static struct brstruct {
		int unixrate;
		int cps;
		int baudrate;
		} stab[] = {
			B0,	0,	0,
			B50,	5,	50,
			B75,	8,	75,
			B110,	10,	110,
			B134,	14,	134,
			B150,	15,	150,
			B200,	20,	200,
			B300,	30,	300,
			B600,	60,	600,
			B1200,	120,	1200,
			B1800,	180,	1800,
			B2400,	240,	2400,
			B4800,	480,	4800,
			B9600,	960,	9600
		};

	if (first)		/* might as well set it here, too */
	{
		first = NO;
		init();
	}

	if (gttyinfo(fd, &ttybuf) == -1)
		return 960;

	for (i = 0; i < sizeof(stab) / sizeof(struct brstruct); i++)
#ifdef USG
		if (stab[i].unixrate == (ttybuf.c_cflag & 017))
#else
		if (stab[i].unixrate == (ttybuf.sgttyb.sg_ospeed))
#endif
			return stab[i].cps;

	return 960;
}

/* gttyinfo --- make all necessary calls to obtain terminal status */

static int gttyinfo(fd, buf)
int fd;		/* file descriptor of terminal */
TTYINFO *buf;	/* terminal info buffer to be filled in */
{
#ifdef USG
	if (ioctl(fd, TCGETA, buf) < 0)
#else
	if (gtty(fd, &(buf->sgttyb))  < 0
		|| ioctl(fd, TIOCGETC, &(buf->tchars)) < 0
		|| ioctl(fd, TIOCLGET, &(buf->local)) < 0
		|| ioctl(fd, TIOCGLTC, &(buf->ltchars)) < 0)
#endif
	{
		return -1;
	}

#if defined (BSD) || ! defined (S5R2)
	if (set_ospeed == NO)
	{
		set_ospeed = YES;
#ifdef BSD
		ospeed = (buf->sgttyb).sg_ospeed;
#else
		ospeed = buf->c_cflag & 017;	/* tty speed, see termio(7) */
#endif
	}
#endif

	return 0;
}

/* mttyinfo --- modify a TTYINFO structure for interactive operation */

static int mttyinfo(buf)
TTYINFO *buf;		/* buffer containing TTYINFO to be modified */
{
#ifdef USG
	buf->c_cc[0] = DLE;	/* interrupt */
	buf->c_cc[1] = -1;	/* ignore quit */
	buf->c_cc[4] = 1;	/* min # chars to read */
	buf->c_cc[5] = 1;	/* min time to wait */

	buf->c_iflag &= ~(INLCR|IGNCR|ICRNL);	/* allow CR to come thru */
	buf->c_lflag |= ISIG|NOFLSH;	/* keep these bits */
	buf->c_lflag &= ~(ICANON|XCASE|ECHO|ECHOE|ECHOK|ECHONL);
#else
	static struct tchars newtchars = {DLE, -1, DC1, DC3, EOT, -1};
	static struct ltchars newltchars = {-1, -1, -1, -1, -1, -1};

	buf->sgttyb.sg_flags |= (CBREAK);    /* keep these bits */
	buf->sgttyb.sg_flags &= ~(ECHO|CRMOD|LCASE|RAW|ALLDELAY);
	buf->tchars = newtchars;
	/* buf->local |= (LLITOUT);	/* Dan Forsyth says to comment out */
	buf->local &= ~(LCRTBS|LCRTERA|LPRTERA|LTOSTOP|LFLUSHO|LCRTKIL|
#ifndef BSD4_2
				LINTRUP|
#endif
				LCTLECH|LPENDIN);
	buf->ltchars = newltchars;
#endif
	return 0;
}

/* sttyinfo --- make all necessary calls to set terminal status */

static int sttyinfo(fd, buf)
int fd;		/* file descriptor of terminal */
TTYINFO *buf;	/* terminal info buffer */
{
#ifdef USG
	if (ioctl(fd, TCSETAW, buf) < 0)
#else
	if (ioctl(fd, TIOCSETN, &(buf->sgttyb)) < 0
			|| ioctl(fd, TIOCSETC, &(buf->tchars)) < 0
			|| ioctl(fd, TIOCLSET, &(buf->local)) < 0
			|| ioctl(fd, TIOCSLTC, &(buf->ltchars)) < 0)
#endif
		return	-1;

	return 0;
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'makefile'" '(734 characters)'
if test -f 'makefile'
then
	echo shar: will not over-write existing file "'makefile'"
else
cat << \SHAR_EOF > 'makefile'
# 
# $Header: makefile,v 1.2 86/07/11 15:23:24 osadr Exp $
# 
# $Log:	makefile,v $
# Revision 1.2  86/07/11  15:23:24  osadr
# Changed to ensure the proper 'ar' program is used.
# 
# Revision 1.1  86/05/06  13:31:30  osadr
# Initial revision
# 
# 
# 
# makefile for libchangetty.a -- terminal resetting functions

TARGET= libchangetty.a
SRCS= changetty.c
OBJS= changetty.o
PRINTS= $(SRCS) makefile

CFLAGS= -O `cat ../flags`

$(TARGET): $(OBJS) ../flags
	/bin/ar ruv $(TARGET) $(OBJS)
	if test -r /usr/bin/ranlib; then /usr/bin/ranlib $(TARGET); fi

clean:
	rm -fr $(OBJS)

clobber: clean
	rm -fr $(TARGET) print2

print:
	prt $(PRINTS) | lpr -b 'tty lib'
	touch print2

print2: $(PRINTS)
	prt $? | lpr -b 'new tty lib'
	touch print2
SHAR_EOF
fi # end of overwriting check
echo shar: done with directory "'libchangetty'"
cd ..
if test ! -d 'pat'
then
	echo shar: creating directory "'pat'"
	mkdir 'pat'
fi
echo shar: entering directory "'pat'"
cd 'pat'
echo shar: extracting "'pat.c'" '(11312 characters)'
if test -f 'pat.c'
then
	echo shar: will not over-write existing file "'pat.c'"
else
cat << \SHAR_EOF > 'pat.c'
#ifndef lint
static char RCSid[] = "$Header: pat.c,v 1.2 86/07/11 15:24:44 osadr Exp $";
#endif

/*
 * $Log:	pat.c,v $
 * Revision 1.2  86/07/11  15:24:44  osadr
 * Removed Georgia Tech-ism of changeable pattern characters.
 * 
 * Revision 1.1  86/05/06  13:32:49  osadr
 * Initial revision
 * 
 * 
 */

/*
** pat.c
**
** pattern matching subroutines for the se screen editor.
**
** routines declared static are not necessary for the rest
** of the editor, therefore make them static in the name
** of modularity.
*/

#include <stdio.h>
#include <ctype.h>
#include "../constdefs.h"

/* Definitions used only for pattern matching */

#define AND             '&'
#define CCL             '['
#define CCLEND          ']'
#define CHAR            'a'
#define CLOSIZE         1
#define CLOSURE         '*'
#define DASH            '-'
#define DITTO           0200
#define EOL             '$'
#define NCCL            'n'
#define NEWLINE         '\n'
#define TAB             '\t'
#define ANY		'.'
#define BOL		'^'
#define NOTINCCL	'^'
#define START_TAG	'('
#define STOP_TAG	')'
#define ESCAPE		'\\'

/* Array dimensions and other limit values */
#define MAXLINE         128
#define MAXPAT          128

/* Pattern matching subroutines: */

/* match () --- find match anywhere on line */

match (lin, pat)
register char lin[];
register char pat[];
{
	int junk[9];
	register char *pc;

	for (pc = lin; *pc != EOS; pc++)
		if (amatch (lin, pc - lin, pat, junk, junk) >= 0)
			return (YES);
	return (NO);
}


/* amatch() --- (recursive) look for match starting at lin[from] */

amatch(lin, from, pat, tagbeg, tagend)
int from, tagbeg[], tagend[];
char lin[], pat[];
{
	char *ch, *lastc;
	register char *ppat;
	int k;

	lastc = lin + from;     /* next unexamined input character */
	for (ppat = pat; *ppat != EOS; ppat += patsiz (ppat))
		if (*ppat == CLOSURE)   /* a closure entry */
		{
			ppat++;
			for (ch = lastc; *ch != EOS; )
				/* match as many as possible */
				if (omatch (lin, &ch, ppat) == NO)
					break;
			/*
			 * ch now points to character that made us fail
			 * try to match rest of pattern against rest of input
			 * shrink the closure by 1 after each failure
			 */
			for (ppat += patsiz (ppat); ch >= lastc; ch--)
				/* successful match of rest of pattern */
				if ((k = amatch (lin, ch - lin, ppat, tagbeg,
				    tagend)) >= 0)
					break;
			lastc = lin + k;        /* if k < 0, failure */
						/* if k >= 0, success */
			break;
		}
		else if (*ppat == START_TAG)
			tagbeg[*(ppat + 1)] = lastc - lin;
		else if (*ppat == STOP_TAG)
			tagend[*(ppat + 1)] = lastc - lin;
			/* non-closure */
		else if (omatch (lin, &lastc, ppat) == NO)
			return (-1);
		/* else
			omatch succeeded */
	return (lastc - lin);
}

/* omatch () --- try to match a single pattern at ppat */

static omatch (lin, adplin, ppat)
char lin[], **adplin, *ppat;
{
	register char *plin;
	register int bump, retval;

	plin = *adplin;
	retval = NO;
	if (*plin == EOS)
		return (retval);
	bump = -1;
	switch (*ppat) {
	case CHAR:
		if (*plin == *(ppat + 1))
			bump = 1;
		break;

	case BOL:
		if (plin == lin)
			bump = 0;
		break;

	case ANY:
		if (*plin != NEWLINE)
			bump = 1;
		break;

	case EOL:
		if (*plin == NEWLINE)
			bump = 0;
		break;

	case CCL:
		if (locate (*plin, ppat + 1) == YES)
			bump = 1;
		break;

	case NCCL:
		if (*plin != NEWLINE && locate (*plin, ppat + 1) == NO)
			bump = 1;
		break;

	default:
		error ("in omatch: can't happen.");
	}

	if (bump >= 0)
	{
		*adplin += bump;
		retval = YES;
	}
	return (retval);
}


/* locate () --- look for c in char class at ppat */

static locate (c, ppat)
register char c, *ppat;
{
	register char *pclas;

	/* size of class is at ppat, characters follow */
	for (pclas = ppat + *ppat; pclas > ppat; pclas--)
		if (c == *pclas)
			return (YES);
	return (NO);
}


/* patsiz () --- returns size of pattern entry at ppat */

static patsiz (ppat)
register char *ppat;
{

	switch (*ppat) {
	case CHAR:
	case START_TAG:
	case STOP_TAG:
		return (2);

	case BOL:
	case EOL:
	case ANY:
		return (1);

	case CCL:
	case NCCL:
		return (*(ppat + 1) + 2);

	case CLOSURE:
		return (CLOSIZE);

	default:
		error ("in patsiz: can't happen.");
	}
}


/* makpat () --- make pattern from arg[from], terminate at delim */

makpat (arg, from, delim, pat)
char arg[], delim, pat[];
int from;
{
	char ch, esc ();
	int argsub, junk, lastsub, ls, patsub, tag_nest, tag_num, tag_stack[9];

	lastsub = patsub = 0;
	tag_num = -1;
	tag_nest = -1;
	for (argsub = from; arg[argsub] != delim && arg[argsub] != EOS;
	    argsub++)
	{
		ls = patsub;
		if (arg[argsub] == ANY)
			junk = addset (ANY, pat, &patsub, MAXPAT);
		else if (arg[argsub] == BOL && argsub == from)
			junk = addset (BOL, pat, &patsub, MAXPAT);
		else if (arg[argsub] == EOL && arg[argsub + 1] == delim)
			junk = addset (EOL, pat, &patsub, MAXPAT);
		else if (arg[argsub] == CCL)
		{
			if (getccl (arg, &argsub, pat, &patsub) == ERR)
				return (ERR);
		}
		else if (arg[argsub] == CLOSURE && argsub > from)
		{
			ls = lastsub;
			if (pat[ls] == BOL || pat[ls] == EOL ||
			    pat[ls] == CLOSURE || pat[ls] == START_TAG ||
			    pat[ls] == STOP_TAG)
				break;
			stclos (pat, &patsub, &lastsub);
		}
		else if (start_tag(arg, &argsub))
		{
			/* too many tagged sub-patterns */
			if (tag_num >= 8)
				break;
			tag_num++;
			tag_nest++;
			tag_stack[tag_nest] = tag_num;
			junk = addset (START_TAG, pat, &patsub, MAXPAT);
			junk = addset (tag_num, pat, &patsub, MAXPAT);
		}
		else if (stop_tag(arg, &argsub) && tag_nest > -1)
		{
			junk = addset (STOP_TAG, pat, &patsub, MAXPAT);
			junk = addset (tag_stack[tag_nest], pat, &patsub, MAXPAT);
			tag_nest--;
		}
		else
		{
			junk = addset (CHAR, pat, &patsub, MAXPAT);

			/* don't allow match of newline other than via $ */
			if ((ch = esc(arg, &argsub)) == NEWLINE)
				return (ERR);
			junk = addset (ch, pat, &patsub, MAXPAT);
		}
		lastsub = ls;
	}

	if (arg[argsub] != delim)               /* terminated early */
		return (ERR);
	else if (addset (EOS, pat, &patsub, MAXPAT) == NO)      /* no room */
		return (ERR);
	else if (tag_nest != -1)
		return (ERR);
	else
		return (argsub);
}


/* getccl () --- expand char class at arg[*pasub] into pat[*pindex] */

static getccl (arg, pasub, pat, pindex)
char arg[], pat[];
int *pasub, *pindex;
{
	int junk, start;

	(*pasub)++;             /* skip over [ */
	if (arg[*pasub] == NOTINCCL)
	{
		junk = addset (NCCL, pat, pindex, MAXPAT);
		(*pasub)++;
	}
	else
		junk = addset (CCL, pat, pindex, MAXPAT);

	start = *pindex;
	junk = addset (0, pat, pindex, MAXPAT); /* leave room for count */
	filset (CCLEND, arg, pasub, pat, pindex, MAXPAT);
	pat[start] = *pindex - start - 1;

	if (arg[*pasub] == CCLEND)
		return (OK);
	else
		return (ERR);
}


/* stclos () --- insert closure entry at pat[*ppatsub] */

static stclos (pat, ppatsub, plastsub)
char pat[];
int *ppatsub, *plastsub;
{
	int i, j, junk;

	for (i = *ppatsub - 1; i >= *plastsub; i--)     /* make a hole */
	{
		j = i + CLOSIZE;
		junk = addset (pat[i], pat, &j, MAXPAT);
	}
	*ppatsub += CLOSIZE;
	/* put closure in it */
	junk = addset (CLOSURE, pat, plastsub, MAXPAT);
}


/* maksub () --- make substitution string in sub */

maksub (arg, from, delim, sub)
char arg[], delim, sub[];
int from;
{
	char esc ();
	int argsub, index, junk;

	index = 0;
	for (argsub = from; arg[argsub] != delim && arg[argsub] != EOS;
	    argsub++)
		if (arg[argsub] == AND)
		{
			junk = addset (DITTO, sub, &index, MAXPAT);
			junk = addset (0, sub, &index, MAXPAT);
		}
		else if (arg[argsub] == ESCAPE && isdigit (arg[argsub + 1]))
		{
			argsub++;
			junk = addset (DITTO, sub, &index, MAXPAT);
			junk = addset (arg[argsub] - '0', sub, &index, MAXPAT);
		}
		else
			junk = addset (esc (arg, &argsub), sub, &index, MAXPAT);
	if (arg[argsub] != delim)               /* missing delimeter */
		return (ERR);
	else if (addset (EOS, sub, &index, MAXPAT) == NO)       /* no room */
		return (ERR);
	else
		return (argsub);
}


/* catsub () --- add replacement text to end of new */

catsub (lin, from, to, sub, new, k, maxnew)
register char lin[], new[], sub[];
int from[], *k, maxnew, to[];
{
	int junk, ri;
	register int i, j;

	for (i = 0; sub[i] != EOS; i++)
		if ((sub[i] & 0xff) == DITTO)
		{
			ri = sub[++i];
			for (j = from[ri]; j < to[ri]; j++)
				junk = addset (lin[j], new, k, maxnew);
		}
		else
			junk = addset (sub[i], new, k, maxnew);
}


/* filset () --- expand set at array[*pasub] into set[*pindex], stop at delim */

filset (delim, array, pasub, set, pindex, maxset)
char array[], delim, set[];
int maxset, *pasub, *pindex;
{
	char esc ();
	int junk;
	static char digits[] = "0123456789";
	static char lowalf[] = "abcdefghijklmnopqrstuvwxyz";
	static char upalf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

	for ( ; array[*pasub] != delim && array[*pasub] != EOS; (*pasub)++)
		if (array[*pasub] == ESCAPE)
			junk = addset (esc (array, pasub), set, pindex, maxset);
		else if (array[*pasub] != DASH)
			junk = addset (array[*pasub], set, pindex, maxset);
			/* literal DASH */
		else if (*pindex <= 0 || array[*pasub + 1] == EOS ||
		    array[*pasub + 1] == delim)
			junk = addset (DASH, set, pindex, maxset);
		/* else if (index (digits, set[*pindex - 1]) >= 0) */
		else if (isdigit(set[*pindex - 1]))
			dodash (digits, array, pasub, set, pindex, maxset);
		/* else if(index (lowalf, set[*pindex - 1]) >= 0) */
		else if (islower(set[*pindex - 1]))
			dodash (lowalf, array, pasub, set, pindex, maxset);
		/* else if (index (upalf, set[*pindex - 1]) >= 0) */
		else if (isupper(set[*pindex - 1]))
			dodash (upalf, array, pasub, set, pindex, maxset);
		else
			junk = addset (DASH, set, pindex, maxset);
}


/*
** dodash () --- expand array[*pasub - 1]-array[*pasub + 1] into set[*pindex],
**               from valid
*/

static dodash (valid, array, pasub, set, pindex, maxset)
char array[], set[], valid[];
int maxset, *pasub, *pindex;
{
	char esc ();
	int junk, k, limit;

	(*pasub)++;
	(*pindex)--;
	limit = index (valid, esc (array, pasub));
	for (k = index (valid, set[*pindex]); k <= limit; k++)
		junk = addset (valid[k], set, pindex, maxset);
}


/* addset () --- put c in set[*pindex];  if it fits, increment *pindex */

addset (c, set, pindex, maxsiz)
int maxsiz, *pindex;
char c, set[];
{

	if (*pindex >= maxsiz)
		return (NO);
	else
	{
		set[(*pindex)++] = c;
		return (YES);
	}
}


/* esc () --- map array[*pindex] into escaped character if appropriate */

char esc (array, pindex)
char array[];
int *pindex;
{

	if (array[*pindex] != ESCAPE)
		return (array[*pindex]);
	else if (array[*pindex + 1] == EOS)     /* ESCAPE not special at end */
		return (ESCAPE);
	else
	{
		if (array[++(*pindex)] == 'n')
			return (NEWLINE);
		else if (array[*pindex] == 't')
			return (TAB);
		else
			return (array[*pindex]);
	}
}

/* start_tag --- determine if we've seen the start of a tagged pattern */

static int start_tag(arg, argsub)
char *arg;
int *argsub;
{
	if (arg[*argsub] == ESCAPE && arg[*argsub + 1] == START_TAG)
	{
		(*argsub)++;
		return (YES);
	}
	else
		return (NO);
}

/* stop_tag --- determine if we've seen the end of a tagged pattern */

static int stop_tag(arg, argsub)
char *arg;
int *argsub;
{
	if (arg[*argsub] == ESCAPE && arg[*argsub + 1] == STOP_TAG)
	{
		(*argsub)++;
		return (YES);
	}
	else
		return (NO);
}
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'makefile'" '(673 characters)'
if test -f 'makefile'
then
	echo shar: will not over-write existing file "'makefile'"
else
cat << \SHAR_EOF > 'makefile'
# 
# $Header: makefile,v 1.2 86/07/11 15:25:14 osadr Exp $
# 
# $Log:	makefile,v $
# Revision 1.2  86/07/11  15:25:14  osadr
# Changed to ensure that the proper 'ar' program gets used.
# 
# Revision 1.1  86/05/06  13:33:07  osadr
# Initial revision
# 
# 
# 
# makefile for pattern library for 'se'

CFLAGS=-O

PR=pr

libpat.a: pat.o
	/bin/ar ruv libpat.a pat.o
	if test -r /usr/bin/ranlib; then /usr/bin/ranlib libpat.a; fi

pat.o: pat.c

install: libpat.a
	cp libpat.a /usr/lib

print:
	$(PR) pat.c makefile | lpr -b 'pat lib'
	touch print2

print2: pat.c makefile
	$(PR) $? | lpr -b 'new pat lib'
	touch print2

clean:
	rm -f pat.o

clobber: clean
	rm -f libpat.a print2
SHAR_EOF
fi # end of overwriting check
echo shar: extracting "'llib-lpat'" '(1270 characters)'
if test -f 'llib-lpat'
then
	echo shar: will not over-write existing file "'llib-lpat'"
else
cat << \SHAR_EOF > 'llib-lpat'
/* llib-lpat --- lint library for pattern routines */

/*LINTLIBRARY*/

match (lin, pat)
char lin[];
char pat[];
{
	return 0;
}          


amatch(lin, from, pat, tagbeg, tagend)
int from, tagbeg[], tagend[];
char lin[], pat[];
{
	return 0;
}


static omatch (lin, adplin, ppat)
char lin[], **adplin, *ppat;
{
	return 0;
}


static locate (c, ppat)
char c, *ppat;
{
	return 0;
}


static patsiz (ppat)
char *ppat;
{
	return 0;
}


makpat (arg, from, delim, pat)
char arg[], delim, pat[];
int from;
{
	return 0;
}


static getccl (arg, pasub, pat, pindex)
char arg[], pat[];
int *pasub, *pindex;
{
	return 0;
}


static stclos (pat, ppatsub, plastsub)
char pat[];
int *ppatsub, *plastsub;
{
}


maksub (arg, from, delim, sub)
char arg[], delim, sub[];
int from;
{
	return 0;
}


catsub (lin, from, to, sub, new, k, maxnew)
char lin[], new[], sub[];
int from[], *k, maxnew, to[];
{
}


filset (delim, array, pasub, set, pindex, maxset)
char array[], delim, set[];
int maxset, *pasub, *pindex;
{
}


static dodash (valid, array, pasub, set, pindex, maxset)
char array[], set[], valid[];
int maxset, *pasub, *pindex;
{
}


addset (c, set, pindex, maxsiz)
int maxsiz, *pindex;
char c, set[];
{
	return 0;
}

char esc (array, pindex)
char array[];
int *pindex;
{
	return 0;
}
SHAR_EOF
fi # end of overwriting check
echo shar: done with directory "'pat'"
cd ..
#	End of shell archive
exit 0



More information about the Mod.sources mailing list