#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 5 (of 13)."
# Contents:  stevie/fileio.c stevie/main.c stevie/term.h stevie/tos.c
# Wrapped by thor@surt on Fri Oct 16 09:43:46 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'stevie/fileio.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stevie/fileio.c'\"
else
echo shar: Extracting \"'stevie/fileio.c'\" \(7765 characters\)
sed "s/^X//" >'stevie/fileio.c' <<'END_OF_FILE'
X/* $Header: /nw/tony/src/stevie/src/RCS/fileio.c,v 1.12 89/08/06 09:50:01 tony Exp $
X *
X * Basic file I/O routines.
X */
X
X#ifndef VxWorks
X# include <sys/types.h>		/* For stat() and chmod() */
X# include <sys/stat.h>		/* Ditto */
X#endif
X#include "stevie.h"
X
Xvoid
Xfilemess(s)
Xchar	*s;
X{
X	smsg("\"%s\" %s", (Filename == NULL) ? "" : Filename, s);
X	flushbuf();
X}
X
Xvoid
Xrenum()
X{
X	LPTR	*p;
X	unsigned long l = 0;
X
X	for (p = Filemem; p != NULL ;p = nextline(p), l += LINEINC)
X		p->linep->num = l;
X
X	Fileend->linep->num = 0xffffffff;
X}
X
X#define	MAXLINE	256	/* maximum size of a line */
X
Xbool_t
Xreadfile(fname,fromp,nochangename)
X/*-------------------------------------------------
X * Note that this will try to expand the file name using environment
X * variables.  For this reason, we copy it into an 80-byte buffer,
X * so that there's room to expand it.
X *
X * It uses the environment-variable convention of UNIX, even
X * under systems with other conventions.  That is, your home directory
X * would be called $HOME (even in DOS, where you might want to say %HOME%)
X *-----------------------------------------------------*/
Xchar	*fname;
XLPTR	*fromp;
Xbool_t	nochangename;	/* if TRUE, don't change the Filename */
X{
X	FILE	*f, *fopen();
X	register LINE	*curr;
X	char	buff[MAXLINE], buf2[80];
X	char	namebuf[80];
X	register int	i, c;
X	register long	nchars = 0;
X	int	linecnt = 0;
X	bool_t	wasempty = bufempty();
X	int	nonascii = 0;		/* count garbage characters */
X	int	nulls = 0;		/* count nulls */
X	bool_t	incomplete = FALSE;	/* was the last line incomplete? */
X	bool_t	toolong = FALSE;	/* a line was too long */
X
X	curr = fromp->linep;
X
X	strncpy (namebuf, fname, 80);
X	EnvEval (namebuf, 80);
X
X	if ( ! nochangename )
X		Filename = strsave(namebuf);
X
X	if ( (f=fopen(fixname(namebuf),"r")) == NULL )
X		return TRUE;
X
X	filemess("");
X
X	i = 0;
X	do {
X		c = getc(f);
X
X		if (c == EOF) {
X			if (i == 0)	/* normal loop termination */
X				break;
X
X			/*
X			 * If we get EOF in the middle of a line, note the
X			 * fact and complete the line ourselves.
X			 */
X			incomplete = TRUE;
X			c = NL;
X		}
X
X		/*
X		 * Abort if we get an interrupt, but finished reading the
X		 * current line first.
X		 */
X		if (got_int && i == 0)
X			break;
X
X		if (c >= 0x80) {
X			c -= 0x80;
X			nonascii++;
X		}
X
X		/*
X		 * If we reached the end of the line, OR we ran out of
X		 * space for it, then process the complete line.
X		 */
X		if (c == NL || i == (MAXLINE-1)) {
X			LINE	*lp;
X
X			if (c != NL)
X				toolong = TRUE;
X
X			buff[i] = '\0';
X			if ((lp = newline(strlen(buff))) == NULL)
X				exit(1);
X
X			strcpy(lp->s, buff);
X
X			curr->next->prev = lp;	/* new line to next one */
X			lp->next = curr->next;
X
X			curr->next = lp;	/* new line to prior one */
X			lp->prev = curr;
X
X			curr = lp;		/* new line becomes current */
X			i = 0;
X			linecnt++;
X
X		} else if (c == NUL)
X			nulls++;		/* count and ignore nulls */
X		else {
X			buff[i++] = c;		/* normal character */
X		}
X
X		nchars++;
X
X	} while (!incomplete && !toolong);
X
X	fclose(f);
X
X	/*
X	 * If the buffer was empty when we started, we have to go back
X	 * and remove the "dummy" line at Filemem and patch up the ptrs.
X	 */
X	if (wasempty && nchars != 0) {
X		LINE	*dummy = Filemem->linep;	/* dummy line ptr */
X
X		free(dummy->s);				/* free string space */
X		Filemem->linep = Filemem->linep->next;
X		free((char *)dummy);			/* free LINE struct */
X		Filemem->linep->prev = Filetop->linep;
X		Filetop->linep->next = Filemem->linep;
X
X		Curschar->linep = Filemem->linep;
X		Topchar->linep  = Filemem->linep;
X	}
X
X	renum();
X
X	if (got_int) {
X		smsg("\"%s\" Interrupt", namebuf);
X		got_int = FALSE;
X		return FALSE;		/* an interrupt isn't really an error */
X	}
X
X	if (toolong) {
X		smsg("\"%s\" Line too long", namebuf);
X		return FALSE;
X	}
X
X	sprintf(buff, "\"%s\" %s%d line%s, %ld character%s",
X		namebuf,
X		incomplete ? "[Incomplete last line] " : "",
X		linecnt, (linecnt != 1) ? "s" : "",
X		nchars, (nchars != 1) ? "s" : "");
X
X	buf2[0] = NUL;
X
X	if (nonascii || nulls) {
X		if (nonascii) {
X			if (nulls)
X				sprintf(buf2, " (%d null, %d non-ASCII)",
X					nulls, nonascii);
X			else
X				sprintf(buf2, " (%d non-ASCII)", nonascii);
X		} else
X			sprintf(buf2, " (%d null)", nulls);
X	}
X	strcat(buff, buf2);
X	msg(buff);
X
X	return FALSE;
X}
X
X
X/*
X * writeit - write to file 'fname' lines 'start' through 'end'
X *
X * If either 'start' or 'end' contain null line pointers, the default
X * is to use the start or end of the file respectively.
X */
Xbool_t
Xwriteit(fname, start, end)
Xchar	*fname;
XLPTR	*start, *end;
X{
X        int err;
X	FILE	*f, *fopen();
X	FILE	*fopenb();		/* open in binary mode, where needed */
X	char	*backup;
X	register char	*s;
X	register long	nchars;
X	register int	lines;
X	register LPTR	*p;
X#ifndef VxWorks
X	struct stat statbuf;
X	int	    statres;
X#endif
X
X	smsg("\"%s\"", fname);
X
X	/* Expand any environment variables left in the name.
X	 * fname better be in a variable big enough to handle the
X	 * expansion (80 bytes).
X	 */
X	EnvEval (fname, 80);
X
X#ifndef VxWorks
X	/* If the file already exists, get what we need to know
X	 * (like current mode).
X	 */
X	statres = stat (fname, &statbuf);
X#endif
X
X	/*
X	 * Form the backup file name - change foo.* to foo.bak
X	 */
X	backup = alloc((unsigned) (strlen(fname) + 5));
X	if (backup == NULL) {
X		emsg("Out of malloc() memory!");
X		return FALSE;
X	}
X
X	strcpy(backup, fname);
X	for (s = backup; *s && *s != '.' ;s++)
X		;
X	*s = NUL;
X	strcat(backup, ".bak");
X
X	/*
X	 * Delete any existing backup and move the current version
X	 * to the backup. For safety, we don't remove the backup
X	 * until the write has finished successfully. And if the
X	 * 'backup' option is set, leave it around.
X         * For VxWorks, renaming is conditional on the 'backup' option,
X         * and we never leave the backup around.
X	 */
X#ifdef VxWorks
X	if (P(P_BK))
X	   _rename(fname, backup);   /* we use _rename() to not step on rename()
X                                          in usrLib */
X        else
X           delete(fname);            /* delete original file, so that we can
X                                          do optimum squeeze below */
X# ifdef RT11
X        /* squeeze RT-11 disk */
X        squeeze(fname);           /* no use checking for errors */
X# endif
X#else
X	rename(fname, backup);
X#endif
X
X
X        /* in VxWorks, and in fact unix in general, P_CR has no effect */
X	f = P(P_CR) ? fopen(fixname(fname), "w") : fopenb(fixname(fname), "w");
X
X	if (f == NULL) {
X		emsg("Can't open file for writing!");
X		free(backup);
X		return FALSE;
X	}
X
X	/*
X	 * If we were given a bound, start there. Otherwise just
X	 * start at the beginning of the file.
X	 */
X	if (start == NULL || start->linep == NULL)
X		p = Filemem;
X	else
X		p = start;
X
X	lines = nchars = 0;
X	do {
X		err=fprintf(f, "%s\n", p->linep->s);
X                if (err==EOF)  {
X                   emsg("Error: write failed or disk full!");
X	           fclose(f);
X	           free(backup);
X                   return FALSE;
X                }
X
X		nchars += strlen(p->linep->s) + 1;
X		lines++;
X
X		/*
X		 * If we were given an upper bound, and we just did that
X		 * line, then bag it now.
X		 */
X		if (end != NULL && end->linep != NULL) {
X			if (end->linep == p->linep)
X				break;
X		}
X
X	} while ((p = nextline(p)) != NULL);
X
X	err=fclose(f);
X        if (err==EOF)  {
X           emsg("Error: write failed or disk full!");
X           free(backup);
X           return FALSE;
X        }
X
X	smsg("\"%s\" %d line%s, %ld character%s", fname,
X		lines, (lines > 1) ? "s" : "",
X		nchars, (nchars > 1) ? "s" : "");
X
X	UNCHANGED;
X
X	/*
X	 * Remove the backup unless they want it left around
X         * (always remove in VxWorks)
X	 */
X#ifndef VxWorks
X	if (!P(P_BK))
X#endif
X		remove(backup);
X
X	free(backup);
X
X#ifndef VxWorks
X	/*
X	 * Set the mode of the new file to agree with the old.
X	 */
X	if (statres==0)
X		chmod (fname, statbuf.st_mode);
X#endif
X
X	return TRUE;
X}
END_OF_FILE
if test 7765 -ne `wc -c <'stevie/fileio.c'`; then
    echo shar: \"'stevie/fileio.c'\" unpacked with wrong size!
fi
# end of 'stevie/fileio.c'
fi
if test -f 'stevie/main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stevie/main.c'\"
else
echo shar: Extracting \"'stevie/main.c'\" \(8183 characters\)
sed "s/^X//" >'stevie/main.c' <<'END_OF_FILE'
X/* $Header: /nw/tony/src/stevie/src/RCS/main.c,v 1.12 89/08/02 19:53:27 tony Exp $
X *
X * The main routine and routines to deal with the input buffer.
X */
X
X#include "stevie.h"
X
Xint Rows;		/* Number of Rows and Columns */
Xint Columns;		/* in the current window. */
X
Xchar *Realscreen = NULL;	/* What's currently on the screen, a single */
X				/* array of size Rows*Columns. */
Xchar *Nextscreen = NULL;	/* What's to be put on the screen. */
X
Xchar *Filename = NULL;	/* Current file name */
X
XLPTR *Filemem;		/* Pointer to the first line of the file */
X
XLPTR *Filetop;		/* Line 'above' the start of the file */
X
XLPTR *Fileend;		/* Pointer to the end of the file in Filemem. */
X			/* (It points to the byte AFTER the last byte.) */
X
XLPTR *Topchar;		/* Pointer to the byte in Filemem which is */
X			/* in the upper left corner of the screen. */
X
XLPTR *Botchar;		/* Pointer to the byte in Filemem which is */
X			/* just off the bottom of the screen. */
X
XLPTR *Curschar;		/* Pointer to byte in Filemem at which the */
X			/* cursor is currently placed. */
X
Xint Cursrow, Curscol;	/* Current position of cursor */
X
Xint Cursvcol;		/* Current virtual column, the column number of */
X			/* the file's actual line, as opposed to the */
X			/* column number we're at on the screen.  This */
X			/* makes a difference on lines that span more */
X			/* than one screen line. */
X
Xint Curswant = 0;	/* The column we'd like to be at. This is used */
X			/* try to stay in the same column through up/down */
X			/* cursor motions. */
X
Xbool_t set_want_col;	/* If set, then update Curswant the next time */
X			/* through cursupdate() to the current virtual */
X			/* column. */
X
Xint State = NORMAL;	/* This is the current state of the command */
X			/* interpreter. */
X
Xint Prenum = 0;		/* The (optional) number before a command. */
X
XLPTR *Insstart;		/* This is where the latest insert/append */
X			/* mode started. */
X
Xbool_t Changed = 0;	/* Set to 1 if something in the file has been */
X			/* changed and not written out. */
X
Xchar Redobuff[1024];	/* Each command should stuff characters into this */
X			/* buffer that will re-execute itself. */
X
Xchar Insbuff[1024];	/* Each insertion gets stuffed into this buffer. */
X
Xint Ninsert = 0;	/* Number of characters in the current insertion. */
Xchar *Insptr = NULL;
X
Xbool_t	got_int=FALSE;	/* set to TRUE when an interrupt occurs (if possible) */
X
Xbool_t	interactive = FALSE;	/* set TRUE when main() is ready to roll */
X
X#ifdef VxWorks
Xchar* DfltTerm = NULL;  /* terminal type if specified in cmd line */
X#endif
X
Xchar **files;		/* list of input files */
Xint  numfiles;		/* number of input files */
Xint  curfile;		/* number of the current file */
X
Xstatic void
Xusage()
X{
X
X#ifdef VxWorks
X	fprintf(stderr, "Usage: vi [\"file\" ...]\n");
X	fprintf(stderr, "       vi \"-t[erm]\",\"term\"[,\"file\" ...]\n");
X/*	fprintf(stderr, "       vi \"-ta[g]\",\"tag\"\n"); */
X	fprintf(stderr, "       vi \"+[num]\",\"file\"\n");
X	fprintf(stderr, "       vi \"+/pat\",\"file\"\n");
X#else
X        fprintf(stderr, "Usage: stevie [file ...]\n");
X        fprintf(stderr, "       stevie -t tag\n");
X        fprintf(stderr, "       stevie +[num] file\n");
X        fprintf(stderr, "       stevie +/pat  file\n");
X#endif  /* VxWorks */
X	exit(1);
X}
X
Xmain(argc,argv)
Xint	argc;
Xchar	*argv[];
X{
X	char	*initstr, *getenv();	/* init string from the environment */
X	char	*tag = NULL;		/* tag from command line */
X	char	*pat = NULL;		/* pattern from command line */
X	int	line = -1;		/* line number from command line */
X        int	l;                      /* length of option word */
X
X	/*
X	 * Process the command line arguments.
X	 */
X	if (argc > 1) {
X		switch (argv[1][0]) {
X		
X		case '-':			/* -tag or -term */
X			l=strlen(argv[1]);
X			if (l<2 || argv[2]==NULL) {
X				usage();
X			}
X
X#ifdef VxWorks
X                        if (strncmp("-term",argv[1],l)==0)  {
X				DfltTerm=argv[2];
X				if (argc>3) {
X					Filename = strsave(argv[3]);
X					files = &(argv[3]);
X					numfiles = argc - 3;
X				}
X				else {
X					Filename = NULL;
X					numfiles = 1;
X				}
X                        }
X			else 
X#endif  /* VxWorks */
X                        if (strncmp("-tag",argv[1],l)==0)  {
X				Filename = NULL;
X				tag = argv[2];
X				numfiles = 1;
X                        }
X			else  {
X				usage();
X                        }
X			break;
X
X		case '+':			/* +n or +/pat */
X			if (argv[1][1] == '/') {
X				if (argv[2] == NULL)
X					usage();
X				Filename = strsave(argv[2]);
X				pat = &(argv[1][1]);
X				numfiles = 1;
X
X			} else if (isdigit(argv[1][1]) || argv[1][1] == NUL) {
X				if (argv[2] == NULL)
X					usage();
X				Filename = strsave(argv[2]);
X				numfiles = 1;
X
X				line = (isdigit(argv[1][1])) ?
X					atoi(&(argv[1][1])) : 0;
X			} else
X				usage();
X
X			break;
X
X		default:			/* must be a file name */
X			Filename = strsave(argv[1]);
X			files = &(argv[1]);
X			numfiles = argc - 1;
X			break;
X		}
X	} else {
X		Filename = NULL;
X		numfiles = 1;
X	}
X	curfile = 0;
X
X 	if (numfiles > 1)
X 		fprintf(stderr, "%d files to edit\n", numfiles);
X 
X	windinit();
X
X	/*
X	 * Allocate LPTR structures for all the various position pointers
X	 */
X 	if ((Filemem = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X 	    (Filetop = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X 	    (Fileend = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X 	    (Topchar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X 	    (Botchar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X 	    (Curschar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X	    (Insstart = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
X	    (screenalloc() == -1) ) {
X		fprintf(stderr, "Can't allocate data structures\n");
X		windexit(0);
X	}
X
X	filealloc();		/* Initialize Filemem, Filetop, and Fileend */
X
X	screenclear();
X
X	if ((initstr = getenv("EXINIT")) != NULL) {
X		char *lp, buf[128];
X
X		if ((lp = getenv("LINES")) != NULL) {
X			sprintf(buf, "%s lines=%s", initstr, lp);
X			docmdln(buf);
X		} else
X			docmdln(initstr);
X	}
X
X	if (Filename != NULL) {
X		if (readfile(Filename, Filemem, FALSE))
X			filemess("[New File]");
X	} else if (tag == NULL)
X		msg("Empty Buffer");
X
X	setpcmark();
X
X	if (tag) {
X		stuffin(":ta ");
X		stuffin(tag);
X		stuffin("\n");
X
X	} else if (pat) {
X		stuffin(pat);
X		stuffin("\n");
X
X	} else if (line >= 0) {
X		if (line > 0)
X			stuffnum(line);
X		stuffin("G");
X	}
X
X	interactive = TRUE;
X
X	edit();
X
X	windexit(0);
X
X	return 1;		/* shouldn't be reached */
X}
X
X#define	RBSIZE	1024
Xstatic char getcbuff[RBSIZE];
Xstatic char *getcnext = NULL;
X
Xvoid
Xstuffin(s)
Xchar	*s;
X{
X	if (s == NULL) {		/* clear the stuff buffer */
X		getcnext = NULL;
X		return;
X	}
X
X	if (getcnext == NULL) {
X		strcpy(getcbuff,s);
X		getcnext = getcbuff;
X	} else
X		strcat(getcbuff,s);
X}
X
Xvoid
Xstuffnum(n)
Xint	n;
X{
X	char	buf[32];
X
X	sprintf(buf, "%d", n);
X	stuffin(buf);
X}
X
Xint
Xvgetc()
X{
X	register int	c;
X
X	/*
X	 * inchar() may map special keys by using stuffin(). If it does
X	 * so, it returns -1 so we know to loop here to get a real char.
X	 */
X	do {
X		if ( getcnext != NULL ) {
X			int nextc = *getcnext++;
X			if ( *getcnext == NUL ) {
X				*getcbuff = NUL;
X				getcnext = NULL;
X			}
X			return(nextc);
X		}
X		c = inchar();
X	} while (c == -1);
X
X	return c;
X}
X
X/*
X * anyinput
X *
X * Return non-zero if input is pending.
X */
X
Xbool_t
Xanyinput()
X{
X	return (getcnext != NULL);
X}
X
X/*
X * do_mlines() - process mode lines for the current file
X *
X * Returns immediately if the "ml" parameter isn't set.
X */
X#define	NMLINES	5	/* no. of lines at start/end to check for modelines */
X
Xvoid
Xdo_mlines()
X{
X	void	chk_mline();
X	int	i;
X	register LPTR	*p;
X
X	if (!P(P_ML))
X		return;
X
X	p = Filemem;
X	for (i=0; i < NMLINES ;i++) {
X		chk_mline(p->linep->s);
X		if ((p = nextline(p)) == NULL)
X			break;
X	}
X
X	if ((p = prevline(Fileend)) == NULL)
X		return;
X
X	for (i=0; i < NMLINES ;i++) {
X		chk_mline(p->linep->s);
X		if ((p = prevline(p)) == NULL)
X			break;
X	}
X}
X
X/*
X * chk_mline() - check a single line for a mode string
X */
Xstatic void
Xchk_mline(s)
Xregister char	*s;
X{
X	register char	*cs;		/* local copy of any modeline found */
X	register char	*e;
X
X	for (; *s != NUL ;s++) {
X		if (strncmp(s, "vi:", 3) == 0 || strncmp(s, "ex:", 3) == 0) {
X			cs = strsave(s+3);
X			if ((e = strchr(cs, ':')) != NULL) {
X				*e = NUL;
X				stuffin(mkstr(CTRL('o')));
X				docmdln(cs);
X			}
X			free(cs);
X		}
X	}
X}
END_OF_FILE
if test 8183 -ne `wc -c <'stevie/main.c'`; then
    echo shar: \"'stevie/main.c'\" unpacked with wrong size!
fi
# end of 'stevie/main.c'
fi
if test -f 'stevie/term.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stevie/term.h'\"
else
echo shar: Extracting \"'stevie/term.h'\" \(7477 characters\)
sed "s/^X//" >'stevie/term.h' <<'END_OF_FILE'
X/* $Header: /nw/tony/src/stevie/src/RCS/term.h,v 1.7 89/08/01 17:25:18 tony Exp $
X *
X * System-dependent escape sequence definitions.
X */
X
X#ifdef	TERMCAP
X
Xextern char *T_EL;		/* erase the entire current line */
Xextern char *T_IL;		/* insert one line */
Xextern char *T_DL;		/* delete one line */
Xextern char *T_SC;		/* save the cursor position */
Xextern char *T_ED;		/* erase display (may optionally home cursor) */
Xextern char *T_RC;		/* restore the cursor position */
Xextern char *T_CI;		/* invisible cursor (very optional) */
Xextern char *T_CV;		/* visible cursor (very optional) */
X
Xextern char *T_CM;		/* cursor motion string */
X
Xextern char *T_KU;          /* code sequence sent by up-arrow key */
Xextern char *T_KD;          /* code sequence sent by down-arrow key */
Xextern char *T_KL;          /* code sequence sent by left-arrow key */
Xextern char *T_KR;          /* code sequence sent by right-arrow key */
X
X#else
X
X/*
X * This file contains the machine dependent escape sequences that
X * the editor needs to perform various operations. Some of the sequences
X * here are optional. Anything not available should be indicated by
X * a null string. In the case of insert/delete line sequences, the
X * editor checks the capability and works around the deficiency, if
X * necessary.
X *
X * Currently, insert/delete line sequences are used for screen scrolling.
X * There are lots of terminals that have 'index' and 'reverse index'
X * capabilities, but no line insert/delete. For this reason, the editor
X * routines s_ins() and s_del() should be modified to use 'index'
X * sequences when the line to be inserted or deleted line zero.
X */
X
X/*
X * The macro names here correspond (more or less) to the actual ANSI names
X */
X
X#ifdef	ATARI
X#ifdef	MINIX
X
X#define	T_EL	"\033[2K"	/* erase the entire current line */
X#define	T_IL	"\033[L"	/* insert one line */
X#define	T_DL	"\033[M"	/* delete one line */
X#define	T_SC	"\0337"		/* save the cursor position */
X#define	T_ED	"\033[2J"	/* erase display (may optionally home cursor) */
X#define	T_RC	"\0338"		/* restore the cursor position */
X#define	T_CI	""		/* invisible cursor (very optional) */
X#define	T_CV	""		/* visible cursor (very optional) */
X
X#else
X
X#define	T_EL	"\033l"		/* erase the entire current line */
X#define	T_IL	"\033L"		/* insert one line */
X#define	T_DL	"\033M"		/* delete one line */
X#define	T_SC	"\033j"		/* save the cursor position */
X#define	T_ED	"\033E"		/* erase display (may optionally home cursor) */
X#define	T_RC	"\033k"		/* restore the cursor position */
X#define	T_CI	"\033f"		/* invisible cursor (very optional) */
X#define	T_CV	"\033e"		/* visible cursor (very optional) */
X
X#endif
X#endif
X
X#ifdef	UNIX
X/*
X * The following sequences are hard-wired for ansi-like terminals. To get
X * termcap support, define TERMCAP in env.h and these sequences go away.
X */
X#define	T_EL	"\033[2K"	/* erase the entire current line */
X#define	T_IL	"\033[L"	/* insert one line */
X#define	T_DL	"\033[M"	/* delete one line */
X#define	T_ED	"\033[2J"	/* erase display (may optionally home cursor) */
X#define	T_SC	"\0337"		/* save the cursor position */
X#define	T_RC	"\0338"		/* restore the cursor position */
X#define	T_CI	""		/* invisible cursor (very optional) */
X#define	T_CV	""		/* visible cursor (very optional) */
X
X#define	T_KU	"\033OA"	/* sent by cursor up */
X#define	T_KD	"\033OB"	/* sent by cursor down */
X#define	T_KR	"\033OC"	/* sent by cursor right */
X#define	T_KL	"\033OD"	/* sent by cursor left */
X
X#endif
X
X#ifdef	OS2
X/*
X * The OS/2 ansi console driver is pretty deficient. No insert or delete line
X * sequences. The erase line sequence only erases from the cursor to the end
X * of the line. For our purposes that works out okay, since the only time
X * T_EL is used is when the cursor is in column 0.
X *
X * The insert/delete line sequences marked here are actually implemented in
X * the file os2.c using direct OS/2 system calls. This makes the capability
X * available for the rest of the editor via appropriate escape sequences
X * passed to outstr().
X */
X#define	T_EL	"\033[K"	/* erase the entire current line */
X#define	T_IL	"\033[L"	/* insert one line - fake (see os2.c) */
X#define	T_DL	"\033[M"	/* delete one line - fake (see os2.c) */
X#define	T_ED	"\033[2J"	/* erase display (may optionally home cursor) */
X#define	T_SC	"\033[s"	/* save the cursor position */
X#define	T_RC	"\033[u"	/* restore the cursor position */
X#define	T_CI	""		/* invisible cursor (very optional) */
X#define	T_CV	""		/* visible cursor (very optional) */
X#endif
X
X
X#ifdef	DOS
X/*
X * DOS sequences
X *
X * Some of the following sequences require the use of the "nansi.sys"
X * console driver. The standard "ansi.sys" driver doesn't support
X * sequences for insert/delete line.
X */
X#define	T_EL	"\033[K"	/* erase the entire current line */
X#define	T_IL	"\033[L"	/* insert line (requires nansi.sys driver) */
X#define	T_DL	"\033[M"	/* delete line (requires nansi.sys driver) */
X#define	T_ED	"\033[2J"	/* erase display (may optionally home cursor) */
X#define	T_SC	"\033[s"	/* save the cursor position */
X#define	T_RC	"\033[u"	/* restore the cursor position */
X#define	T_CI	""		/* invisible cursor (very optional) */
X#define	T_CV	""		/* visible cursor (very optional) */
X#endif
X
X#endif
X
X/*
X * Machine-variant screen handling definitions.
X *
X * Define some macros which for invoking screen functions, whether by
X * callling a bios function or outputting an escape sequence to be
X * interpreted by a PC console driver or terminal.
X *
X * At this writing, not all of Stevie has been converted to use these
X * macros.  So far, only DOS and PC BIOS versions are completely converted.
X * Other versions are partly converted (because of changes I made in Stevie's
X * common code), but they have not been tested.  I'll convert others which I'm
X * in a position to test, but I'll leave any I can't test alone.  Hopefully,
X * this will minimize any damage to working versions which I can't test. -LAS
X */
X
X#ifdef BIOS
X
X#define	CANDL		TRUE		/* Can delete lines */
X#define	CANIL		TRUE		/* Can insert lines */
X#define	CLEOL		bios_t_el()	/* Erase to end-of-line */
X#define	CLS		bios_t_ed()	/* Erase entire display */
X#define	CRTDL(r,l)	bios_t_dl(r,l)	/* Delete lines from display */
X#define	CRTIL(r,l)	bios_t_il(r,l)	/* Insert lines in display */
X#define	CUROFF		bios_t_ci()	/* Make cursor invisible */
X#define	CURON		bios_t_cv()	/* Make cursor visible */
X#define	RESCUR		bios_t_rc()	/* Restore saved cursor position */
X#define	SAVCUR		bios_t_sc()	/* Save cursor position */
X
X#else		/* Not BIOS */
X
X#define	CANDL		(T_DL[0]!='\0')	/* Determine if can delete lines */
X#define	CANIL		(T_IL[0]!='\0')	/* Determine if can insert lines */
X#ifdef TERMCAP
X# define CLEOL	 flushbuf(); outstr(T_EL); flushbuf_pad() /* Erase to EOL */
X# define CLS	 flushbuf(); outstr(T_ED); flushbuf_pad() /* Erase display */
X#else
X# define CLEOL	 outstr(T_EL)	/* Erase to end-of-line */
X# define CLS	 outstr(T_ED)	/* Erase entire display */
X#endif
X#define	CRTDL(r,l)	DO_DL(r,l)	/* Delete lines from display */
X#define	CRTIL(r,l)	DO_IL(r,l)	/* Insert lines in display */
X#define	CUROFF		outstr(T_CI)	/* Make cursor invisible */
X#define	CURON		outstr(T_CV)	/* Make cursor visible */
X#define	RESCUR		outstr(T_RC)	/* Restore saved cursor position */
X#define	SAVCUR		outstr(T_SC)	/* Save cursor position */
X
X#define	DO_DL(r,l) {\
X	int __xx_knt = l;\
X	while (__xx_knt-- > 0) {outstr(T_DL);}\
X}
X
X#define	DO_IL(r,l) {\
X	int __xx_knt = l;\
X	while (__xx_knt-- > 0) {outstr(T_IL);}\
X}
X
X#endif		/* Not BIOS */
X
X
END_OF_FILE
if test 7477 -ne `wc -c <'stevie/term.h'`; then
    echo shar: \"'stevie/term.h'\" unpacked with wrong size!
fi
# end of 'stevie/term.h'
fi
if test -f 'stevie/tos.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stevie/tos.c'\"
else
echo shar: Extracting \"'stevie/tos.c'\" \(7202 characters\)
sed "s/^X//" >'stevie/tos.c' <<'END_OF_FILE'
X/* $Header: /nw/tony/src/stevie/src/RCS/tos.c,v 1.5 89/07/13 22:45:31 tony Exp $
X *
X * System-dependent routines for the Atari ST.
X */
X
X#include "stevie.h"
X
X#include <osbind.h>
X
X/*
X * inchar() - get a character from the keyboard
X *
X * Certain special keys are mapped to values above 0x80. These
X * mappings are defined in keymap.h. If the key has a non-zero
X * ascii value, it is simply returned. Otherwise it may be a
X * special key we want to map.
X *
X * The ST has a bug involving keyboard input that seems to occur
X * when typing quickly, especially typing capital letters. Sometimes
X * a value of 0x02540000 is read. This doesn't correspond to anything
X * on the keyboard, according to my documentation. My solution is to
X * loop when any unknown key is seen. Normally, the bell is rung to
X * indicate the error. If the "bug" value is seen, we ignore it completely.
X */
Xint
Xinchar()
X{
X	register long	c;
X
X	for (;;) {
X		c = Bconin(2);
X	
X		if ((c & 0xff) != 0)
X			return ((int) c);
X	
X		switch ((int) (c >> 16) & 0xff) {
X	
X		case 0x62: return K_HELP;
X		case 0x61: return K_UNDO;
X		case 0x52: return K_INSERT;
X		case 0x47: return K_HOME;
X		case 0x48: return K_UARROW;
X		case 0x50: return K_DARROW;
X		case 0x4b: return K_LARROW;
X		case 0x4d: return K_RARROW;
X		case 0x29: return K_CCIRCM;	/* control-circumflex */
X		
X		/*
X		 * Occurs due to a bug in TOS.
X		 */
X		case 0x54:
X			break;
X		/*
X		 * Add the function keys here later if we put in support
X		 * for macros.
X		 */
X	
X		default:
X			beep();
X			break;
X	
X		}
X	}
X}
X
Xvoid
Xoutchar(c)
Xchar	c;
X{
X	if (c < ' ')
X		Bconout(2, c);
X	else
X		Bconout(5, c);
X}
X
Xvoid
Xoutstr(s)
Xregister char	*s;
X{
X	while (*s)
X		Bconout(2, *s++);
X}
X
X/*
X * flushbuf() - a no-op for TOS
X */
Xvoid
Xflushbuf()
X{
X}
X
X#define	BGND	0
X#define	TEXT	3
X
X/*
X * vbeep() - visual bell
X */
Xstatic void
Xvbeep()
X{
X	int	text, bgnd;		/* text and background colors */
X	long	l;
X
X	text = Setcolor(TEXT, -1);
X	bgnd = Setcolor(BGND, -1);
X
X	Setcolor(TEXT, bgnd);		/* swap colors */
X	Setcolor(BGND, text);
X
X	for (l=0; l < 5000 ;l++)	/* short pause */
X		;
X
X	Setcolor(TEXT, text);		/* restore colors */
X	Setcolor(BGND, bgnd);
X}
X
Xvoid
Xbeep()
X{
X	if (P(P_VB))
X		vbeep();
X	else
X		outchar('\007');
X}
X
X/*
X * remove(file) - remove a file
X */
Xvoid
Xremove(file)
Xchar	*file;
X{
X	Fdelete(file);
X}
X
X/*
X * rename(of, nf) - rename existing file 'of' to 'nf'
X */
Xvoid
Xrename(of, nf)
Xchar	*of, *nf;
X{
X	Fdelete(nf);		/* if 'nf' exists, remove it */
X	Frename(0, of, nf);
X}
X
Xvoid
Xwindinit()
X{
X	if (Getrez() == 0)
X		Columns = 40;		/* low resolution */
X	else
X		Columns = 80;		/* medium or high */
X
X	P(P_LI) = Rows = 25;
X
X	Cursconf(1,NULL);
X}
X
Xvoid
Xwindexit(r)
Xint	r;
X{
X	exit(r);
X}
X
Xstatic	char	gobuf[5] = { '\033', 'Y', '\0', '\0', '\0' };
X
Xvoid
Xwindgoto(r, c)
Xint	r, c;
X{
X	gobuf[2] = r + 040;
X	gobuf[3] = c + 040;
X	outstr(gobuf);
X}
X
X/*
X * System calls or library routines missing in TOS.
X */
X
Xvoid
Xsleep(n)
Xint	n;
X{
X	int	k;
X
X	k = Tgettime();
X	while ( Tgettime() <= k+n )
X		;
X}
X
Xvoid
Xpause()
X{
X	long	n;
X
X	for (n = 0; n < 8000 ;n++)
X		;
X}
X
Xint
Xsystem(cmd)
Xchar	*cmd;
X{
X	char	arg[1];
X
X	arg[0] = (char) 0;	/* no arguments passed to the shell */
X
X	if (Pexec(0, cmd, arg, 0L) < 0)
X		return -1;
X	else
X		return 0;
X}
X
X#ifdef	SOZOBON
X
XFILE *
Xfopenb(fname, mode)
Xchar	*fname;
Xchar	*mode;
X{
X	char	modestr[10];
X
X	sprintf(modestr, "%sb", mode);
X
X	return fopen(fname, modestr);
X}
X
X#endif
X
X#ifndef	SOZOBON
X/*
X * getenv() - get a string from the environment
X *
X * Both Alcyon and Megamax are missing getenv(). This routine works for
X * both compilers and with the Beckemeyer and Gulam shells. With gulam,
X * the env_style variable should be set to either "mw" or "gu".
X */
Xchar *
Xgetenv(name)
Xchar	*name;
X{
X	extern long	_base;
X	char	*envp, *p;
X
X	envp = *((char **) (_base + 0x2c));
X
X	for (; *envp ;envp += strlen(envp)+1) {
X		if (strncmp(envp, name, strlen(name)) == 0) {
X			p = envp + strlen(name);
X			if (*p++ == '=')
X				return p;
X		}
X	}
X	return (char *) 0;
X}
X#endif
X
X/*
X * mktemp() - quick hack since there isn't one here
X */
Xchar *
Xmktemp(name)
Xchar	*name;
X{
X	int	num;		/* pasted into the string to make it unique */
X	char	cbuf[7];
X	char	*s;		/* where the X's start in name */
X	int	fd;
X
X	if ((s = strchr(name, 'X')) == NULL)	/* needs to be an X */
X		return (char *) NULL;
X
X	if (strlen(s) != 6)			/* should be 6 X's */
X		return (char *) NULL;
X
X	for (num = 0; num < 1000 ;num++) {
X		sprintf(cbuf, "%06d", num);
X		strcpy(s, cbuf);
X		if ((fd = open(name, 0)) < 0)
X			return name;
X		close(fd);
X	}
X	return (char *) NULL;
X}
X
Xvoid
Xdoshell(cmd)
Xchar	*cmd;
X{
X	if (cmd == NULL) {
X		shell();
X		return;
X	}
X	system(cmd);
X	wait_return();
X}
X
X#define	PSIZE	128
X
X/*
X * fixname(s) - fix up a dos name
X *
X * Takes a name like:
X *
X *	\x\y\z\base.ext
X *
X * and trims 'base' to 8 characters, and 'ext' to 3.
X */
Xchar *
Xfixname(s)
Xchar	*s;
X{
X	char	*strchr(), *strrchr();
X	static	char	f[PSIZE];
X	char	base[32];
X	char	ext[32];
X	char	*p;
X	int	i;
X
X	strcpy(f, s);
X
X	for (i=0; i < PSIZE ;i++)
X		if (f[i] == '/')
X			f[i] = '\\';
X
X	/*
X	 * Split the name into directory, base, extension.
X	 */
X	if ((p = strrchr(f, '\\')) != NULL) {
X		strcpy(base, p+1);
X		p[1] = '\0';
X	} else {
X		strcpy(base, f);
X		f[0] = '\0';
X	}
X
X	if ((p = strchr(base, '.')) != NULL) {
X		strcpy(ext, p+1);
X		*p = '\0';
X	} else
X		ext[0] = '\0';
X
X	/*
X	 * Trim the base name if necessary.
X	 */
X	if (strlen(base) > 8)
X		base[8] = '\0';
X	
X	if (strlen(ext) > 3)
X		ext[3] = '\0';
X
X	/*
X	 * Paste it all back together
X	 */
X	strcat(f, base);
X	strcat(f, ".");
X	strcat(f, ext);
X
X	return f;
X}
X
X/*
X *	FILL IT IN, FOR YOUR SYSTEM, AND SHARE IT!
X *
X *	The next couple of functions do system-specific stuff.
X *	They currently do nothing; I'm not familiar enough with
X *	system-specific programming on this system.
X *	If you fill it in for your system, please post the results
X *	and share with the rest of us.
X */
X
X
Xsetcolor (c)
X/*
X * Set the color to c, using the local system convention for numbering
X * colors or video attributes.
X *
X * If you implement this, remember to note the original color in
X * windinit(), before you do any setcolor() commands, and
X * do a setcolor() back to the original as part of windexit().
X */
X  int c:
X{
X}
X
X
Xsetrows (r)
X/*
X * Set the number of lines to r, if possible.  Otherwise
X * "do the right thing".  Return the number of lines actually set.
X *
X * If you implement this, remember to note the original number of rows
X * in windinit(), before you do any setrows() commands, and
X * do a setrows() back to the original as part of windexit().
X */
X  int r;
X{
X	/* Since we do nothing, just return the current number of lines */
X	return ( P(P_LI) );
X}
X
X
Xvbeep ()
X/*
X * Do a "visual bell".  This generally consists of flashing the screen
X * once in inverse video.
X */
X{
X	int	color, revco;
X
X	color = P( P_CO );		/* get current color */
X	revco = reverse_color (color);	/* system-specific */
X	setcolor (revco);
X	flushbuf ();
X	pause ();
X	setcolor (color);
X	windgoto (Cursrow, Curscol);
X	flushbuf ();
X}
X
Xreverse_color (co)
X/*
X * Returns the inverse video attribute or color of co.
X * The existing code below is VERY simple-minded.
X * Replace it with proper code for your system.
X */
X int co;
X{
X	if (co)		return (0);
X	else		return (1);
X}
X
X
X/********** End of do-it-yourself kit **********************/
X
END_OF_FILE
if test 7202 -ne `wc -c <'stevie/tos.c'`; then
    echo shar: \"'stevie/tos.c'\" unpacked with wrong size!
fi
# end of 'stevie/tos.c'
fi
echo shar: End of archive 5 \(of 13\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 13 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
