page@swan.ulowell.edu (Bob Page) (03/15/89)
Submitted-by: grwalter@watcgl.waterloo.edu (Fred Walter)
Posting-number: Volume 89, Issue 41
Archive-name: editors/stevie35a.2
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# alloc.c
# amiga.c
# fileio.c
# os2.c
# stevie.h
# tags
# term.h
# tos.h
# version.c
# This archive created: Tue Mar 14 14:41:09 1989
cat << \SHAR_EOF > alloc.c
/*
* STEVIE - Simply Try this Editor for VI Enthusiasts
*
* Code Contributions By : Tim Thompson twitch!tjt
* Tony Andrews onecom!wldrdg!tony
* G. R. (Fred) Walter watmath!watcgl!grwalter
*/
#include "stevie.h"
/*
* This file contains various routines dealing with allocation and
* deallocation of data structures.
*/
char *
alloc(size)
unsigned size;
{
char *p; /* pointer to new storage space */
#ifdef AMIGA
char *pp;
/*
* Before allocating any memory make sure there is enough for a system
* requester left.
*/
pp = malloc((unsigned) 40000);
if (pp == (char *) NULL) { /* if there is no more room... */
emsg("alloc() is unable to find memory!");
return (NULL);
}
#endif
p = malloc(size);
if (p == (char *) NULL) /* if there is no more room... */
emsg("alloc() is unable to find memory!");
#ifdef AMIGA
free(pp);
#endif
return (p);
}
char *
strsave(string)
char *string;
{
return (strcpy(alloc((unsigned) (strlen(string) + 1)), string));
}
void
screenalloc()
{
int i;
/*
* If we're changing the size of the screen, free the old arrays
*/
if (Realscreen != NULL)
free(Realscreen);
if (Nextscreen != NULL)
free(Nextscreen);
if (LinePointers != NULL)
free((char *) LinePointers);
if (LineSizes != NULL)
free(LineSizes);
Realscreen = malloc((unsigned) (Rows * Columns));
Nextscreen = malloc((unsigned) (Rows * Columns));
LinePointers = (LINE **) malloc((unsigned) (Rows * sizeof(LINE *)));
LineSizes = malloc((unsigned) Rows);
for (i = 0; i < Rows; i++) {
LinePointers[i] = NULL;
LineSizes[i] = 0;
}
}
/*
* Allocate and initialize a new line structure with room for 'nchars'
* characters.
*/
LINE *
newline(nchars)
int nchars;
{
register LINE *l;
l = (LINE *) alloc((unsigned) sizeof(LINE));
if (l == NULL)
return (LINE *) NULL;
l->s = alloc((unsigned) nchars); /* the line is empty */
l->s[0] = NUL;
l->size = nchars;
l->prev = (LINE *) NULL; /* should be initialized by caller */
l->next = (LINE *) NULL;
return l;
}
/*
* filealloc() - construct an initial empty file buffer
*/
void
filealloc()
{
if ((Filemem->linep = newline(1)) == NULL) {
fprintf(stderr, "Unable to allocate file memory!\n");
getout(1);
}
if ((Filetop->linep = newline(1)) == NULL) {
fprintf(stderr, "Unable to allocate file memory!\n");
getout(1);
}
if ((Fileend->linep = newline(1)) == NULL) {
fprintf(stderr, "Unable to allocate file memory!\n");
getout(1);
}
Filemem->index = 0;
Filetop->index = 0;
Fileend->index = 0;
Filetop->linep->prev = NULL;
Filetop->linep->next = Filemem->linep; /* connect Filetop to Filemem */
Filemem->linep->prev = Filetop->linep;
Filemem->linep->next = Fileend->linep; /* connect Filemem to Fileend */
Fileend->linep->prev = Filemem->linep;
Fileend->linep->next = NULL;
*Curschar = *Filemem;
*Topchar = *Filemem;
Filemem->linep->num = 0;
Fileend->linep->num = 0xffffffffL;
clrall(); /* clear all marks */
}
/*
* freeall() - free the current buffer
*
* Free all lines in the current buffer.
*/
void
freeall()
{
LINE *lp;
LINE *xlp;
int i;
for (lp = Filetop->linep; lp != NULL; lp = xlp) {
if (lp->s != NULL)
free(lp->s);
xlp = lp->next;
free((char *) lp);
}
Curschar->linep = NULL; /* clear pointers */
Filemem->linep = NULL;
Filetop->linep = NULL;
Fileend->linep = NULL;
for (i = 0; i < Rows; i++) {/* clear screen information */
LinePointers[i] = NULL;
LineSizes[i] = 0;
}
}
/*
* canincrease(n) - returns TRUE if the current line can be increased 'n'
* bytes
*
* This routine returns immediately if the requested space is available. If not,
* it attempts to allocate the space and adjust the data structures
* accordingly. If everything fails it returns FALSE.
*/
bool_t
canincrease(n)
register int n;
{
register int nsize;
register char *s; /* pointer to new space */
nsize = strlen(Curschar->linep->s) + 1 + n; /* size required */
if (nsize <= Curschar->linep->size)
return TRUE;
/*
* Need to allocate more space for the string. Allow some extra space on
* the assumption that we may need it soon. This avoids excessive numbers
* of calls to malloc while entering new text.
*/
s = alloc((unsigned) (nsize + SLOP));
if (s == NULL) {
emsg("Can't add anything, file is too big!");
State = NORMAL;
return FALSE;
}
Curschar->linep->size = nsize + SLOP;
strcpy(s, Curschar->linep->s);
free(Curschar->linep->s);
Curschar->linep->s = s;
return TRUE;
}
SHAR_EOF
cat << \SHAR_EOF > amiga.c
/*
* Amiga system-dependent routines.
*/
#include <proto/dos.h>
#include "stevie.h"
long raw_in = 0;
long raw_out = 0;
#define BSIZE 2048
static char outbuf[BSIZE];
static int bpos = 0;
void
flushbuf()
{
if (bpos != 0)
Write(raw_out, outbuf, bpos);
bpos = 0;
}
/*
* Macro to output a character. Used within this file for speed.
*/
#define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
int
GetCharacter()
{
char c;
Read(raw_in, &c, sizeof(c));
return ((int) c);
}
/*
* getCSIsequence - get a CSI sequence
* - either cursor keys, help, functionkeys, or some
* other sequence (if other, check window size)
*/
int
getCSIsequence()
{
int c;
int param1;
int param2;
c = GetCharacter();
if (isdigit(c)) {
param1 = 0;
while (isdigit(c)) {
param1 = param1 * 10 + c - '0';
c = GetCharacter();
}
if (c == '~') /* function key */
return ((char) (K_F1 + param1));
/* must be an event of some sort or a window bound report */
if (c == ';') {
param2 = 0;
c = GetCharacter();
while (isdigit(c)) {
param2 = param2 * 10 + c - '0';
c = GetCharacter();
}
if (c == ';') {
param1 = 0;
c = GetCharacter();
while (isdigit(c)) {
param1 = param1 * 10 + c - '0';
c = GetCharacter();
}
if (c == ';') {
param2 = 0;
c = GetCharacter();
while (isdigit(c)) {
param2 = param2 * 10 + c - '0';
c = GetCharacter();
}
if (c == ' ') {
c = GetCharacter();
if (c == 'r') {
if (param1 < 2)
param1 = 2;
if (param2 < 5)
param2 = 5;
if (Columns != param2 || Rows != param1) {
Columns = param2;
Rows = param1;
P(P_LI) = Rows;
return (-1);
} else
return 0;
}
}
}
}
}
while ((c != '|') && (c != '~'))
c = GetCharacter();
outstr("\033[0 q");
flushbuf();
}
switch (c) {
case 'A': /* cursor up */
return K_UARROW;
case 'B': /* cursor down */
return K_DARROW;
case 'C': /* cursor right */
return K_RARROW;
case 'D': /* cursor left */
return K_LARROW;
case 'T': /* shift cursor up */
return K_SUARROW;
case 'S': /* shift cursor down */
return K_SDARROW;
case ' ': /* shift cursor left or right */
c = GetCharacter();
if (c == 'A') /* shift cursor left */
return K_SLARROW;
if (c == '@') /* shift cursor right */
return K_SRARROW;
break;
case '?': /* help */
c = GetCharacter();
if (c == '~')
return K_HELP;
break;
}
return 0; /* some other control code */
}
/*
* inchar() - get a character from the keyboard
*/
int
inchar()
{
int c;
flushbuf();
for (;;) {
c = GetCharacter();
if (c != 0x9b)
break;
c = getCSIsequence();
if (c > 0)
break;
if (c == -1) {
screenalloc();
screenclear();
msg("");
updateNextscreen(NOT_VALID);
cursupdate();
updateNextscreen(NOT_VALID);
cursupdate();
updateRealscreen();
windgoto(Cursrow, Curscol);
flushbuf();
}
}
return c;
}
void
outchar(c)
char c;
{
outbuf[bpos++] = c;
if (bpos >= BSIZE)
flushbuf();
}
void
outstr(s)
char *s;
{
while (*s)
outone(*s++);
}
void
beep()
{
if (RedrawingDisabled)
return;
outone('\007');
}
void
sleep(n)
int n;
{
void Delay();
if (n > 0)
Delay(50L * n);
}
void
delay()
{
void Delay();
Delay(25L);
}
void
windinit()
{
Columns = 80;
P(P_LI) = Rows = 24;
raw_in = Input();
if (!IsInteractive(raw_in)) {
raw_in = Open("RAW:0/0/480/200/STEVIE", MODE_NEWFILE);
if (raw_in == NULL) {
fprintf(stderr, "Can't open window ?!?!?!?\n");
exit(2);
}
raw_out = raw_in;
} else {
raw_out = Output();
if (raw(stdin) != 0)
perror("Can't change to raw mode ?!?!?!?");
}
outstr("\033[12{"); /* window resize events activated */
flushbuf();
for (;;) {
outstr("\033[0 q"); /* get window size */
flushbuf();
if (GetCharacter() == 0x9b)
if (getCSIsequence() == -1)
break;
}
}
void
windexit(r)
int r;
{
outstr("\033[12}"); /* window resize events de-activated */
flushbuf();
if (raw_in != raw_out) {
if (cooked(stdin) != 0)
perror("Can't change to cooked mode ?!?!?!?");
} else {
Close(raw_in);
}
exit(r);
}
void
windgoto(r, c)
int c;
int r;
{
r++;
c++;
outstr("\033[");
if (r >= 10)
outchar((char) (r / 10 + '0'));
outchar((char) (r % 10 + '0'));
outchar(';');
if (c >= 10)
outchar((char) (c / 10 + '0'));
outchar((char) (c % 10 + '0'));
outchar('H');
}
FILE *
fopenb(fname, mode)
char *fname;
char *mode;
{
FILE *fopen();
char modestr[16];
sprintf(modestr, "%sb", mode);
return fopen(fname, modestr);
}
SHAR_EOF
cat << \SHAR_EOF > fileio.c
/*
* STEVIE - Simply Try this Editor for VI Enthusiasts
*
* Code Contributions By : Tim Thompson twitch!tjt
* Tony Andrews onecom!wldrdg!tony
* G. R. (Fred) Walter watmath!watcgl!grwalter
*/
#include "stevie.h"
void
filemess(s)
char *s;
{
sprintf(IObuff, "\"%s\" %s", ((Filename == NULL) ? "" : Filename), s);
msg(IObuff);
}
void
renum()
{
LPtr *p;
unsigned long l = 0;
for (p = Filemem; p != NULL; p = nextline(p), l += LINEINC)
p->linep->num = l;
Fileend->linep->num = 0xffffffffL;
}
#ifdef MEGAMAX
overlay "fileio"
#endif
bool_t
readfile(fname, fromp, nochangename)
char *fname;
LPtr *fromp;
bool_t nochangename; /* if TRUE, don't change the Filename */
{
FILE *f, *fopen();
LINE *curr;
char buf2[80];
int c;
int IObuffsize = 0;
long nchars = 0;
int linecnt = 0;
bool_t wasempty = bufempty();
int nonascii = 0; /* count garbage characters */
int nulls = 0; /* count nulls */
bool_t incomplete = FALSE; /* was the last line incomplete? */
bool_t toolong = FALSE; /* a line was too long */
curr = fromp->linep;
if (!nochangename)
Filename = strsave(fname);
f = fopen(fname, "r");
if (f == NULL)
return TRUE;
filemess("");
do {
c = getc(f);
if (c == EOF) {
if (IObuffsize == 0)/* normal loop termination */
break;
/*
* If we get EOF in the middle of a line, note the fact and
* complete the line ourselves.
*/
incomplete = TRUE;
c = NL;
}
if (c >= 0x80) {
c -= 0x80;
nonascii++;
}
/*
* If we reached the end of the line, OR we ran out of space for it,
* then process the complete line.
*/
if (c == NL || IObuffsize == (IOSIZE - 1)) {
LINE *lp;
if (c != NL)
toolong = TRUE;
IObuff[IObuffsize++] = NUL;
if ((lp = newline(IObuffsize)) == NULL) {
fprintf(stderr, "not enough memory - should never happen");
getout(1);
}
strcpy(lp->s, IObuff);
curr->next->prev = lp; /* new line to next one */
lp->next = curr->next;
curr->next = lp; /* new line to prior one */
lp->prev = curr;
curr = lp; /* new line becomes current */
IObuffsize = 0;
linecnt++;
} else if (c == NUL) {
nulls++; /* count and ignore nulls */
} else {
IObuff[IObuffsize++] = (char) c; /* normal character */
}
nchars++;
} while (!incomplete && !toolong);
fclose(f);
/*
* If the buffer was empty when we started, we have to go back and remove
* the "dummy" line at Filemem and patch up the ptrs.
*/
if (wasempty && linecnt != 0) {
LINE *dummy = Filemem->linep; /* dummy line ptr */
free(dummy->s); /* free string space */
Filemem->linep = Filemem->linep->next;
free((char *) dummy); /* free LINE struct */
Filemem->linep->prev = Filetop->linep;
Filetop->linep->next = Filemem->linep;
Curschar->linep = Filemem->linep;
Topchar->linep = Filemem->linep;
}
renum();
if (toolong) {
sprintf(IObuff, "\"%s\" Line too long", fname);
msg(IObuff);
return FALSE;
}
sprintf(IObuff, "\"%s\" %s%d line%s, %ld character%s",
fname,
incomplete ? "[Incomplete last line] " : "",
linecnt, (linecnt > 1) ? "s" : "",
nchars, (nchars > 1) ? "s" : "");
buf2[0] = NUL;
if (nonascii || nulls) {
if (nonascii) {
if (nulls)
sprintf(buf2, " (%d null, %d non-ASCII)",
nulls, nonascii);
else
sprintf(buf2, " (%d non-ASCII)", nonascii);
} else
sprintf(buf2, " (%d null)", nulls);
}
strcat(IObuff, buf2);
msg(IObuff);
return FALSE;
}
/*
* writeit - write to file 'fname' lines 'start' through 'end'
*
* If either 'start' or 'end' contain null line pointers, the default is to use
* the start or end of the file respectively.
*/
bool_t
writeit(fname, start, end)
char *fname;
LPtr *start, *end;
{
FILE *f, *fopen();
FILE *fopenb(); /* open in binary mode, where needed */
char *backup, *s;
long nchars;
int lines;
LPtr *p;
sprintf(IObuff, "\"%s\"", fname);
msg(IObuff);
/*
* Form the backup file name - change foo.* to foo.bak
*/
backup = alloc((unsigned) (strlen(fname) + 5));
strcpy(backup, fname);
for (s = backup; *s && *s != '.'; s++);
*s = NUL;
strcat(backup, ".bak");
/*
* Delete any existing backup and move the current version to the backup.
* For safety, we don't remove the backup until the write has finished
* successfully. And if the 'backup' option is set, leave it around.
*/
rename(fname, backup);
f = P(P_CR) ? fopen(fname, "w") : fopenb(fname, "w");
if (f == NULL) {
emsg("Can't open file for writing!");
free((char *) backup);
return FALSE;
}
/*
* If we were given a bound, start there. Otherwise just start at the
* beginning of the file.
*/
if (start == NULL || start->linep == NULL)
p = Filemem;
else
p = start;
lines = 0;
nchars = 0;
do {
fprintf(f, "%s\n", p->linep->s);
nchars += strlen(p->linep->s) + 1;
lines++;
/*
* If we were given an upper bound, and we just did that line, then
* bag it now.
*/
if (end != NULL && end->linep != NULL) {
if (end->linep == p->linep)
break;
}
} while ((p = nextline(p)) != NULL);
fclose(f);
sprintf(IObuff, "\"%s\" %d line%s, %ld character%s", fname,
lines, (lines > 1) ? "s" : "",
nchars, (nchars > 1) ? "s" : "");
msg(IObuff);
UNCHANGED;
/*
* Remove the backup unless they want it left around
*/
if (!P(P_BK))
remove(backup);
free((char *) backup);
return TRUE;
}
SHAR_EOF
cat << \SHAR_EOF > os2.c
/*
* OS/2 System-dependent routines.
*
* $Log: os2.c,v $
* Revision 1.2 88/04/25 16:50:19 tony
* Minor changes for OS/2 version 1.1; also fixed up the RCS header.
*
* Revision 1.1 88/03/21 12:04:23 tony
* Initial revision
*
*
*/
#define INCL_BASE
#include <os2.h>
#include "stevie.h"
/*
* inchar() - get a character from the keyboard
*/
int
inchar()
{
int c;
for (;; beep()) { /* loop until we get a valid character */
flushbuf(); /* flush any pending output */
switch (c = getch()) {
case 0x1e:
return K_CGRAVE;
case 0: /* special key */
case 0xe0: /* special key */
if (State != NORMAL) {
c = getch(); /* throw away next char */
continue; /* and loop for another char */
}
switch (c = getch()) {
case 0x50:
return K_DARROW;
case 0x48:
return K_UARROW;
case 0x4b:
return K_LARROW;
case 0x4d:
return K_RARROW;
case 0x52:
return K_INSERT;
case 0x47:
stuffReadbuff("1G");
return -1;
case 0x4f:
stuffReadbuff("G");
return -1;
case 0x51:
stuffReadbuff(mkstr(CTRL('F')));
return -1;
case 0x49:
stuffReadbuff(mkstr(CTRL('B')));
return -1;
/*
* Hard-code some useful function key macros.
*/
case 0x3b: /* F1 */
stuffReadbuff(":p\n");
return -1;
case 0x54: /* SF1 */
stuffReadbuff(":p!\n");
return -1;
case 0x3c: /* F2 */
stuffReadbuff(":n\n");
return -1;
case 0x55: /* SF2 */
stuffReadbuff(":n!\n");
return -1;
case 0x3d: /* F3 */
stuffReadbuff(":e #\n");
return -1;
case 0x3e: /* F4 */
stuffReadbuff(":rew\n");
return -1;
case 0x57: /* SF4 */
stuffReadbuff(":rew!\n");
return -1;
case 0x3f: /* F5 */
stuffReadbuff("[[");
return -1;
case 0x40: /* F6 */
stuffReadbuff("]]");
return -1;
case 0x41: /* F7 */
stuffReadbuff("<<");
return -1;
case 0x42: /* F8 */
stuffReadbuff(">>");
return -1;
case 0x43: /* F9 */
stuffReadbuff(":x\n");
return -1;
case 0x44: /* F10 */
stuffReadbuff(":help\n");
return -1;
default:
break;
}
break;
default:
return c;
}
}
}
#define BSIZE 2048
static char outbuf[BSIZE];
static int bpos = 0;
flushbuf()
{
if (bpos != 0)
write(1, outbuf, bpos);
bpos = 0;
}
/*
* Macro to output a character. Used within this file for speed.
*/
#define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
/*
* Function version for use outside this file.
*/
void
outchar(c)
register char c;
{
outbuf[bpos++] = c;
if (bpos >= BSIZE)
flushbuf();
}
static char cell[2] = {0, 7};
/*
* outstr(s) - write a string to the console
*
* We implement insert/delete line escape sequences here. This is kind
* of a kludge, but at least it's localized to a single point.
*/
void
outstr(s)
register char *s;
{
if (strcmp(s, T_DL) == 0) { /* delete line */
int r, c;
flushbuf();
VioGetCurPos(&r, &c, 0);
VioScrollUp(r, 0, 100, 100, 1, cell, 0);
return;
}
if (strcmp(s, T_IL) == 0) { /* insert line */
int r, c;
flushbuf();
VioGetCurPos(&r, &c, 0);
VioScrollDn(r, 0, 100, 100, 1, cell, 0);
return;
}
while (*s) {
outone(*s++);
}
}
void
beep()
{
if (RedrawingDisabled)
return;
outone('\007');
}
void
sleep(n)
int n;
{
DosSleep(1000L * n);
}
void
delay()
{
flushbuf();
DosSleep(300L);
}
void
windinit()
{
Columns = 80;
P(P_LI) = Rows = 25;
}
void
windexit(r)
int r;
{
flushbuf();
exit(r);
}
void
windgoto(r, c)
register int r, c;
{
r += 1;
c += 1;
/* I would recommend the following:
flushbuf();
VioSetCurPos(r, c, 0);
Alex */
/*
* Check for overflow once, to save time.
*/
if (bpos + 8 >= BSIZE)
flushbuf();
outbuf[bpos++] = '\033';
outbuf[bpos++] = '[';
if (r >= 10)
outbuf[bpos++] = r / 10 + '0';
outbuf[bpos++] = r % 10 + '0';
outbuf[bpos++] = ';';
if (c >= 10)
outbuf[bpos++] = c / 10 + '0';
outbuf[bpos++] = c % 10 + '0';
outbuf[bpos++] = 'H';
}
FILE *
fopenb(fname, mode)
char *fname;
char *mode;
{
FILE *fopen();
char modestr[16];
sprintf(modestr, "%sb", mode);
return fopen(fname, modestr);
}
SHAR_EOF
cat << \SHAR_EOF > stevie.h
/*
* STEVIE - Simply Try this Editor for VI Enthusiasts
*
* Code Contributions By : Tim Thompson twitch!tjt
* Tony Andrews onecom!wldrdg!tony
* G. R. (Fred) Walter watmath!watcgl!grwalter
*/
#include "env.h"
#include <stdio.h>
#ifndef ATARI
# ifndef UNIX
# include <stdlib.h>
# endif
#endif
#include <ctype.h>
#ifndef MWC
# include <string.h>
#endif
#include "ascii.h"
#include "keymap.h"
#include "param.h"
#include "term.h"
#include "macros.h"
#ifdef AMIGA
/*
* This won't be needed if you have a version of Lattice 4.01 without broken
* break signal handling.
*/
#include <signal.h>
#endif
extern char *strchr();
#define NORMAL 0
#define CMDLINE 1
#define INSERT 2
#define APPEND 3
#define UNDO 4
#define REDO 5
#define PUT 6
#define FORWARD 7
#define BACKWARD 8
#define VALID 9
#define NOT_VALID 10
#define VALID_TO_CURSCHAR 11
/*
* Boolean type definition and constants
*/
typedef int bool_t;
#ifndef TRUE
#define FALSE (0)
#define TRUE (1)
#endif
#define SORTOF (2)
#define YES TRUE
#define NO FALSE
#define MAYBE SORTOF
/*
* Maximum screen dimensions
*/
#define MAX_COLUMNS 140L
/*
* Buffer sizes
*/
#define CMDBUFFSIZE MAX_COLUMNS /* size of the command processing buffer */
#define LSIZE 512 /* max. size of a line in the tags file */
#define IOSIZE (1024+1) /* file i/o and sprintf buffer size */
#define YANKSIZE 5200 /* yank buffer size */
#define INSERT_SIZE 5300 /* insert, redo and undo buffer size must be
* bigger than YANKSIZE */
#define REDO_UNDO_SIZE 5400 /* redo, undo and (undo an undo) buffer size
* must be bigger than INSERT_SIZE */
#define READSIZE 5500 /* read buffer size must be bigger than
* YANKSIZE and REDO_UNDO_SIZE */
/*
* SLOP is the amount of extra space we get for text on a line during editing
* operations that need more space. This keeps us from calling alloc every
* time we get a character during insert mode. No extra space is allocated
* when the file is initially read.
*/
#define SLOP 10
/*
* LINEINC is the gap we leave between the artificial line numbers. This
* helps to avoid renumbering all the lines every time a new line is
* inserted.
*
* Since line numbers are stored in longs (32 bits), a LINEINC of 10000
* lets us have > 200,000 lines and we won't have to renumber very often.
*/
#define LINEINC 10000
#define CHANGED { Changed = TRUE; }
#define UNCHANGED { Changed = FALSE; }
struct line {
struct line *next; /* next line */
struct line *prev; /* previous line */
char *s; /* text for this line */
int size; /* actual size of space at 's' */
unsigned long num; /* line "number" */
};
#define LINEOF(x) ((x)->linep->num)
struct lptr {
struct line *linep; /* line we're referencing */
int index; /* position within that line */
};
typedef struct line LINE;
typedef struct lptr LPtr;
struct charinfo {
char ch_size;
char *ch_str;
};
extern struct charinfo chars[];
extern int State;
extern int Rows;
extern int Columns;
extern char *Realscreen;
extern char *Nextscreen;
extern int NumLineSizes;
extern LINE **LinePointers;
extern char *LineSizes;
extern char *Filename;
extern LPtr *Filemem;
extern LPtr *Filetop;
extern LPtr *Fileend;
extern LPtr *Topchar;
extern LPtr *Botchar;
extern LPtr *Curschar;
extern LPtr *Insstart;
extern int Cursrow, Curscol, Cursvcol, Curswant;
extern bool_t set_want_col;
extern int Prenum;
extern bool_t Changed;
extern bool_t RedrawingDisabled;
extern bool_t MustRedrawLine;
extern bool_t MustRedrawScreen;
extern bool_t UndoInProgress;
extern bool_t Binary;
extern char *IObuff;
extern char *Insbuffptr;
extern char *Insbuff;
extern char *Readbuffptr;
extern char *Readbuff;
extern char *Redobuffptr;
extern char *Redobuff;
extern char *Undobuffptr;
extern char *Undobuff;
extern char *UndoUndobuffptr;
extern char *UndoUndobuff;
extern char *Yankbuffptr;
extern char *Yankbuff;
extern char last_command;
extern char last_command_char;
extern char *strcpy();
/* alloc.c */
char *alloc();
char *strsave();
void screenalloc(), filealloc(), freeall();
LINE *newline();
bool_t canincrease();
/* cmdline.c */
void readcmdline();
void dotag();
void msg(), emsg(), smsg();
void gotocmdline();
void wait_return();
/* dec.c */
int dec();
/* edit.c */
void edit(), insertchar(), getout(), scrollup(), scrolldown(), beginline();
bool_t oneright(), oneleft(), oneup(), onedown();
/* fileio.c */
void filemess(), renum();
bool_t readfile(), writeit();
/* updateNs.c */
void updateNextscreen();
/* updateRs.c */
void updateRealscreen();
/* help.c */
bool_t help();
/* inc.c */
int inc();
/* linefunc.c */
LPtr *nextline(), *prevline(), *coladvance();
/* main.c */
void stuffReadbuff();
void stuffnumReadbuff();
char vgetc();
char vpeekc();
/* mark.c */
void setpcmark(), clrall(), clrmark();
bool_t setmark();
LPtr *getmark();
/* misccmds.c */
bool_t OpenForward();
bool_t OpenBackward();
void fileinfo(), inschar(), insstr(), delline();
bool_t delchar();
int cntllines(), plines();
LPtr *gotoline();
/* normal.c */
void normal();
void ResetBuffers();
void AppendToInsbuff();
void AppendToRedobuff();
void AppendNumberToRedobuff();
void AppendToUndobuff();
void AppendNumberToUndobuff();
void AppendPositionToUndobuff();
void AppendToUndoUndobuff();
void AppendNumberToUndoUndobuff();
void AppendPositionToUndoUndobuff();
bool_t linewhite();
/* mk.c */
char *mkstr();
char *mkline();
/* param.c */
void doset();
/* screen.c */
void nexttoscreen();
void updateline();
void redrawline();
void screenclear();
void cursupdate();
void prt_line();
void s_del();
void s_ins();
/* search.c */
void doglob();
void dosub();
void searchagain();
bool_t dosearch();
bool_t repsearch();
bool_t searchc(), crepsearch(), findfunc();
LPtr *showmatch();
LPtr *fwd_word(), *bck_word(), *end_word();
/*
* Machine-dependent routines.
*/
#ifdef AMIGA
# include "amiga.h"
#endif
#ifdef BSD
# include "bsd.h"
#endif
#ifdef UNIX
# include "unix.h"
#endif
#ifdef TOS
# include "tos.h"
#endif
#ifdef OS2
# include "os2.h"
#endif
#ifdef DOS
# include "dos.h"
#endif
SHAR_EOF
cat << \SHAR_EOF > tags
ISSPECIAL edit.c /^#define ISSPECIAL(c) ((c) == BS || (c) == NL || (c/
alloc alloc.c /^alloc(size)$/
badcmd cmdline.c /^badcmd()$/
beginline edit.c /^beginline(flag)$/
canincrease alloc.c /^canincrease(n)$/
dec dec.c /^dec(lp)$/
doecmd cmdline.c /^doecmd(arg, force)$/
doshell cmdline.c /^doshell()$/
dotag cmdline.c /^dotag(tag, force)$/
edit edit.c /^edit()$/
emsg cmdline.c /^emsg(s)$/
filealloc alloc.c /^filealloc()$/
freeall alloc.c /^freeall()$/
get_line cmdline.c /^get_line(cp)$/
get_range cmdline.c /^get_range(cp)$/
getout edit.c /^getout(r)$/
gotocmdline cmdline.c /^gotocmdline(clr, firstc)$/
insertchar edit.c /^insertchar(c)$/
msg cmdline.c /^msg(s)$/
newline alloc.c /^newline(nchars)$/
onedown edit.c /^onedown(n)$/
oneleft edit.c /^oneleft()$/
oneright edit.c /^oneright()$/
oneup edit.c /^oneup(n)$/
readcmdline cmdline.c /^readcmdline(firstc, cmdline)$/
screenalloc alloc.c /^screenalloc()$/
scrolldown edit.c /^scrolldown(nlines)$/
scrollup edit.c /^scrollup(nlines)$/
smsg cmdline.c /^smsg(s, a1, a2, a3, a4, a5, a6, a7, a8, a9)$/
strsave alloc.c /^strsave(string)$/
wait_return cmdline.c /^wait_return()$/
Mmain main.c /^main(argc, argv)$/
clrall mark.c /^clrall()$/
clrmark mark.c /^clrmark(line)$/
coladvance linefunc.c /^coladvance(p, col)$/
filemess fileio.c /^filemess(s)$/
getmark mark.c /^getmark(c)$/
help help.c /^help()$/
inc inc.c /^inc(lp)$/
longline help.c /^longline(p)$/
nextline linefunc.c /^nextline(curr)$/
prevline linefunc.c /^prevline(curr)$/
readfile fileio.c /^readfile(fname, fromp, nochangename)$/
renum fileio.c /^renum()$/
setmark mark.c /^setmark(c)$/
setpcmark mark.c /^setpcmark()$/
stuffReadbuff main.c /^stuffReadbuff(s)$/
stuffnumReadbuff main.c /^stuffnumReadbuff(n)$/
usage main.c /^usage()$/
vgetc main.c /^vgetc()$/
vpeekc main.c /^vpeekc()$/
writeit fileio.c /^writeit(fname, start, end)$/
AppendNumberToRedobuff normal.c /^AppendNumberToRedobuff(n)$/
AppendNumberToUndoUndobuff normal.c /^AppendNumberToUndoUndobuff(n)$/
AppendNumberToUndobuff normal.c /^AppendNumberToUndobuff(n)$/
AppendPositionToUndoUndobuff normal.c /^AppendPositionToUndoUndobuff(column, row)$/
AppendPositionToUndobuff normal.c /^AppendPositionToUndobuff(column, row)$/
AppendToInsbuff normal.c /^AppendToInsbuff(s)$/
AppendToRedobuff normal.c /^AppendToRedobuff(s)$/
AppendToUndoUndobuff normal.c /^AppendToUndoUndobuff(s)$/
AppendToUndobuff normal.c /^AppendToUndobuff(s)$/
DEFAULT1 normal.c /^#define DEFAULT1(x) (((x) == 0) ? 1 : (x))$/
IDCHAR normal.c /^#define IDCHAR(c) (isalpha(c) || isdigit(c) || (c)/
OpenBackward misccmds.c /^OpenBackward(can_ai)$/
OpenForward misccmds.c /^OpenForward(can_ai)$/
ResetBuffers normal.c /^ResetBuffers()$/
cntllines misccmds.c /^cntllines(pbegin, pend)$/
cooked raw.c /^cooked(fp)$/
cursupdate screen.c /^cursupdate()$/
delchar misccmds.c /^delchar(fixpos, undo)$/
delline misccmds.c /^delline(nlines, can_update)$/
dochange normal.c /^dochange()$/
dodelete normal.c /^dodelete(redraw, setup_for_undo, try_to_yank)$/
dojoin normal.c /^dojoin(leading_space, strip_leading_spaces)$/
doput normal.c /^doput(dir)$/
doset param.c /^doset(arg, inter)$/
doshift normal.c /^doshift(op)$/
doyank normal.c /^doyank()$/
fileinfo misccmds.c /^fileinfo()$/
gotoline misccmds.c /^gotoline(n)$/
inschar misccmds.c /^inschar(c)$/
insstr misccmds.c /^insstr(s)$/
linewhite normal.c /^linewhite(p)$/
normal normal.c /^normal(c)$/
plines misccmds.c /^plines(p)$/
prt_line screen.c /^prt_line(s)$/
raw raw.c /^raw(fp)$/
redrawline screen.c /^redrawline()$/
s_del screen.c /^s_del(row, nlines)$/
s_ins screen.c /^s_ins(row, nlines)$/
screenclear screen.c /^screenclear()$/
showparms param.c /^showparms(all)$/
startinsert normal.c /^startinsert(startln)$/
tabinout normal.c /^tabinout(shift_type, num)$/
updateline screen.c /^updateline()$/
C0 search.c /^#define C0(c) (((c) == ' ') || ((c) == '\\t') || ((/
C1 search.c /^#define C1(c) (isalpha(c) || isdigit(c) || ((c) ==/
OTHERDIR search.c /^#define OTHERDIR(x) (((x) == FORWARD) ? BACKWARD :/
SendPacket sendpacket.c /^SendPacket(pid, action, args, nargs)$/
bck_word search.c /^bck_word(p, type)$/
bcksearch search.c /^bcksearch(str)$/
cls search.c /^cls(c)$/
crepsearch search.c /^crepsearch(flag)$/
doglob search.c /^doglob(lp, up, cmd)$/
dosearch search.c /^dosearch(dir, str)$/
dosub search.c /^dosub(lp, up, cmd)$/
end_word search.c /^end_word(p, type)$/
findfunc search.c /^findfunc(dir)$/
fwd_word search.c /^fwd_word(p, type)$/
fwdsearch search.c /^fwdsearch(str)$/
mapstring search.c /^mapstring(s)$/
regerror search.c /^regerror(s)$/
repsearch search.c /^repsearch(flag)$/
searchagain search.c /^searchagain(dir)$/
searchc search.c /^searchc(c, dir, type)$/
showmatch search.c /^showmatch()$/
ssearch search.c /^ssearch(dir, str)$/
updateNextscreen updateNs.c /^updateNextscreen(type)$/
CTRL ascii.h /^#define CTRL(x) ((x) & 0x1f)$/
updateRealscreen updateRs.c /^updateRealscreen()$/
LINE stevie.h 122
LINEOF stevie.h /^#define LINEOF(x) ((x)->linep->num)$/
LPTR stevie.h 123
P param.h /^#define P(n) (params[n].value)$/
RowNumber macros.h /^#define RowNumber(p) (UndoInProgress ? 0 : cntllin/
anyinput macros.h /^#define anyinput() (Readbuffptr != NULL)$/
bool_t stevie.h 53
buf1line macros.h /^#define buf1line() (Filemem->linep->next == Fileen/
bufempty macros.h /^#define bufempty() (buf1line() && Filemem->linep->/
endofline macros.h /^#define endofline(p) \\$/
equal macros.h /^#define equal(a, b) (((a)->linep == (b)->linep) &&/
gchar macros.h /^#define gchar(lp) ((lp)->linep->s[(lp)->index])$/
gt macros.h /^#define gt(a, b) ((LINEOF(a) != LINEOF(b)) \\$/
gtoreq macros.h /^#define gtoreq(a, b) ((LINEOF(a) != LINEOF(b)) \\$/
lineempty macros.h /^#define lineempty(p) ((p)->linep->s[0] == NUL)$/
lt macros.h /^#define lt(a, b) ((LINEOF(a) != LINEOF(b)) \\$/
ltoreq macros.h /^#define ltoreq(a, b) ((LINEOF(a) != LINEOF(b)) \\$/
mkline mk.c /^mkline(n)$/
mkstr mk.c /^mkstr(c)$/
pchar macros.h /^#define pchar(lp, c) ((lp)->linep->s[(lp)->index] /
pswap macros.h /^#define pswap(a, b) { LPTR pswaptmp; pswaptmp = a;/
startofline macros.h /^#define startofline(p) ((p)->index == 0)$/
GetCharacter amiga.c /^GetCharacter()$/
beep amiga.c /^beep()$/
delay amiga.c /^delay()$/
flushbuf amiga.c /^flushbuf()$/
fopenb amiga.c /^fopenb(fname, mode)$/
getCSIsequence amiga.c /^getCSIsequence()$/
inchar amiga.c /^inchar()$/
outchar amiga.c /^outchar(c)$/
outone amiga.c /^#define outone(c) outbuf[bpos++] = c; if (bpos >= /
outstr amiga.c /^outstr(s)$/
sleep amiga.c /^sleep(n)$/
windexit amiga.c /^windexit(r)$/
windgoto amiga.c /^windgoto(r, c)$/
windinit amiga.c /^windinit()$/
SHAR_EOF
cat << \SHAR_EOF > term.h
/*
* STEVIE - Simply Try this Editor for VI Enthusiasts
*
* Code Contributions By : Tim Thompson twitch!tjt
* Tony Andrews onecom!wldrdg!tony
* G. R. (Fred) Walter watmath!watcgl!grwalter
*/
/*
* This file contains the machine dependent escape sequences that the editor
* needs to perform various operations. Some of the sequences here are
* optional. Anything not available should be indicated by a null string. In
* the case of insert/delete line sequences, the editor checks the capability
* and works around the deficiency, if necessary.
*
* Currently, insert/delete line sequences are used for screen scrolling. There
* are lots of terminals that have 'index' and 'reverse index' capabilities,
* but no line insert/delete. For this reason, the editor routines s_ins()
* and s_del() should be modified to use 'index' sequences when the line to
* be inserted or deleted at line zero.
*/
/*
* The macro names here correspond (more or less) to the actual ANSI names
*/
#ifdef ATARI
#define T_EL "\033l" /* erase the entire current line */
#define T_IL "\033L" /* insert one line */
#define T_IL_B ""
#define T_DL "\033M" /* delete one line */
#define T_DL_B ""
#define T_SC "\033j" /* save the cursor position */
#define T_ED "\033E" /* erase display (may optionally home cursor) */
#define T_RC "\033k" /* restore the cursor position */
#define T_CI "\033f" /* invisible cursor (very optional) */
#define T_CV "\033e" /* visible cursor (very optional) */
#define T_TP "" /* plain text */
#define T_TI "" /* inverse-video text */
#endif
#ifdef UNIX
/*
* The UNIX sequences are hard-wired for ansi-like terminals. I should really
* use termcap/terminfo, but the UNIX port was done for profiling, not for
* actual use, so it wasn't worth the effort.
*/
#define T_EL "\033[2K" /* erase the entire current line */
#define T_IL "\033[L" /* insert one line */
#define T_IL_B ""
#define T_DL "\033[M" /* delete one line */
#define T_DL_B ""
#define T_ED "\033[2J" /* erase display (may optionally home cursor) */
#define T_SC "\0337" /* save the cursor position */
#define T_RC "\0338" /* restore the cursor position */
#define T_CI "" /* invisible cursor (very optional) */
#define T_CV "" /* visible cursor (very optional) */
#define T_TP "" /* plain text */
#define T_TI "" /* inverse-video text */
#endif
#ifdef BSD
/* The BSD 4.3 sequences are hard-wired for ansi-like terminals. */
#define T_EL "\033[2K" /* erase the entire current line */
#define T_IL "\033[L" /* insert line */
#define T_IL_B ""
#define T_DL "\033[M" /* delete line */
#define T_DL_B ""
#define T_ED "\033[2J" /* erase display (may optionally home cursor) */
#define T_SC "" /* save the cursor position */
#define T_RC "" /* restore the cursor position */
#define T_CI "" /* invisible cursor (very optional) */
#define T_CV "" /* visible cursor (very optional) */
#define T_TP "" /* plain text */
#define T_TI "" /* inverse-video text */
#endif
#ifdef OS2
/*
* The OS/2 ansi console driver is pretty deficient. No insert or delete line
* sequences. The erase line sequence only erases from the cursor to the end
* of the line. For our purposes that works out okay, since the only time
* T_EL is used is when the cursor is in column 0.
*
* The insert/delete line sequences marked here are actually implemented in
* the file os2.c using direct OS/2 system calls. This makes the capability
* available for the rest of the editor via appropriate escape sequences
* passed to outstr().
*/
#define T_EL "\033[K" /* erase the entire current line */
#define T_IL "\033[L" /* insert one line - fake (see os2.c) */
#define T_IL_B ""
#define T_DL "\033[M" /* delete one line - fake (see os2.c) */
#define T_DL_B ""
#define T_ED "\033[2J" /* erase display (may optionally home cursor) */
#define T_SC "\033[s" /* save the cursor position */
#define T_RC "\033[u" /* restore the cursor position */
#define T_CI "" /* invisible cursor (very optional) */
#define T_CV "" /* visible cursor (very optional) */
#define T_TP "" /* plain text */
#define T_TI "" /* inverse-video text */
#endif
#ifdef AMIGA
/*
* The erase line sequence only erases from the cursor to the end of the
* line. For our purposes that works out okay, since the only time T_EL is
* used is when the cursor is in column 0.
*/
#define T_EL "\033[K" /* erase the entire current line */
#define T_IL "\033[" /* insert line */
#define T_IL_B "L"
#define T_DL "\033[" /* delete line */
#define T_DL_B "M"
#define T_ED "\014" /* erase display (may optionally home cursor) */
#define T_RC "" /* restore the cursor position */
#define T_SC "" /* save the cursor position */
#define T_CI "\033[0 p" /* invisible cursor (very optional) */
#define T_CV "\033[1 p" /* visible cursor (very optional) */
#define T_TP "\033[0m" /* plain text */
#define T_TI "\033[7m" /* inverse-video text */
#endif
#ifdef DOS
/*
* DOS sequences
*
* Some of the following sequences require the use of the "nansi.sys"
* console driver. The standard "ansi.sys" driver doesn't support
* sequences for insert/delete line.
*/
#define T_EL "\033[K" /* erase the entire current line */
#define T_IL "\033[L" /* insert line (requires nansi.sys driver) */
#define T_IL_B ""
#define T_DL "\033[M" /* delete line (requires nansi.sys driver) */
#define T_DL_B ""
#define T_ED "\033[2J" /* erase display (may optionally home cursor) */
#define T_SC "\033[s" /* save the cursor position */
#define T_RC "\033[u" /* restore the cursor position */
#define T_CI "" /* invisible cursor (very optional) */
#define T_CV "" /* visible cursor (very optional) */
#define T_TP "" /* plain text */
#define T_TI "" /* inverse-video text */
#endif
SHAR_EOF
cat << \SHAR_EOF > tos.h
/*
* Atari Machine-dependent routines.
*/
int inchar();
void outchar();
void outstr(), beep();
void remove(), rename();
void windinit(), windexit(), windgoto();
void delay();
void sleep();
SHAR_EOF
cat << \SHAR_EOF > version.c
/*
* STEVIE - Simply Try this Editor for VI Enthusiasts
*
* Code Contributions By : Tim Thompson twitch!tjt
* Tony Andrews onecom!wldrdg!tony
* G. R. (Fred) Walter watmath!watcgl!grwalter
*/
/*
* Version Changes (and person who did them)
* ------- ---------------------------------
* 3.10 - version that started it all. Found on comp.sources.unix
* Jun88 Volume 15 i037, i038, i039, i040, i042, and INF3
* - Tim Thompson and Tony Andrews
*
* 3.10A - took version of STEVIE posted to usenet and added Amiga
* and BSD support; added undo and redo commands; sped up
* output to screen; sped up on-screen activities (such as
* cursoring); fixed miscellaneous small bugs and changed some
* commands so that they more closely resembled vi.
* - GRWalter (Fred)
*
* 3.11B - added the ability to be run in the background (STEVIE will
* attempt to use the current window, but if it can't then it
* will open its own window). Fixed some other miscellaneous
* bugs (some to do with re-sizing the screen, one to do with
* undo'ing changes on lines that start with whitespace).
* - GRWalter (Fred)
*
* 3.11C - fixed a bug that was causing the entire screen to be refreshed
* at the wrong times sometimes. Input mode was sped up as well
* as a bug involving lines that wrapped was fixed. Changed :ta
* a bit. Fixed bug triggered when files are > 6000 lines.
* - GRWalter (Fred)
*
* 3.31A - Tony Andrews put out a divergent version of STEVIE (version 3.31).
* I moved the important stuff over into my version.
*
* Here is a list of what was moved over :
*
*************************************************************************
* Revision 3.29 88/06/26 14:53:19 tony
* Added support for a simple form of the "global" command. It supports
* commands of the form "g/pat/d" or "g/pat/p", to delete or print lines
* that match the given pattern. A range spec may be used to limit the
* lines to be searched.
*
* Revision 3.28 88/06/25 21:44:22 tony
* Fixed a problem in the processing of colon commands that caused
* substitutions of patterns containing white space to fail.
*
* Revision 3.26 88/06/10 13:44:06 tony
* Fixed a bug involving writing out files with long pathnames. A small
* fixed size buffer was being used. The space for the backup file name
* is now allocated dynamically.
*
* Revision 1.12 88/05/03 14:39:52 tony
* Also merged in support for DOS.
*
* Revision 1.11 88/05/02 21:38:21 tony
* The code that reads files now handles boundary/error conditions much
* better, and generates status/error messages that are compatible with
* the real vi. Also fixed a bug in repeated reverse searches that got
* inserted in the recent changes to search.c.
*
* Revision 1.10 88/05/02 07:35:41 tony
* Fixed a bug in the routine plines() that was introduced during changes
* made for the last version.
*
* Revision 1.9 88/05/01 20:10:19 tony
* Fixed some problems with auto-indent, and added support for the "number"
* parameter.
*
* Revision 1.8 88/04/30 20:00:49 tony
* Added support for the auto-indent feature.
*
* Revision 1.6 88/04/28 08:19:35 tony
* Modified Henry Spencer's regular expression library to support new
* features that couldn't be done easily with the existing interface.
* This code is now a direct part of the editor source code. The editor
* now supports the "ignorecase" parameter, and multiple substitutions
* per line, as in "1,$s/foo/bar/g".
*
* Revision 1.5 88/04/24 21:38:00 tony
* Added preliminary support for the substitute command. Full range specs.
* are supported, but only a single substitution is allowed on each line.
*
* Revision 1.4 88/04/23 20:41:01 tony
* Worked around a problem with adding lines to the end of the buffer when
* the cursor is at the bottom of the screen (in misccmds.c). Also fixed a
* bug that caused reverse searches from the start of the file to bomb.
*
* Revision 1.3 88/03/24 08:57:00 tony
* Fixed a bug in cmdline() that had to do with backspacing out of colon
* commands or searches. Searches were okay, but colon commands backed out
* one backspace too early.
*
* Revision 1.2 88/03/21 16:47:55 tony
* Fixed a bug in renum() causing problems with large files (>6400 lines).
*************************************************************************
* - GRWalter (Fred)
*
* 3.32A - added the :[range]d command. Played with 'p' and 'P'.
* Added undo capability to :s and :g//d commands.
* Added '%' as a line range specifier (entire file).
* Fixed search so that tags file from real ctags could be used.
* Fixed undo after delete everything operation.
* Made prt_line work in nu mode (so :g//p works right).
* Fixed ai mode (when there was text after the cursor it didn't ai).
* Fixed 'J' (didn't handle next line just having whitespace).
* Fixed :[range] so it behaves like the real vi (goes to highest
* line number in the given range).
* Made it so that the cursor is on the last char inserted instead
* the one right after when there is exactly 1 char right after.
* Made change operator work properly when it ended on the
* end of the line.
* - GRWalter (Fred)
*
* 3.33A - no longer updateNextscreen when putting or undoing or
* redoing until I am done. 'p', 'u' and '.' thus sped up.
* - no longer recalculate line lengths when cursupdate() called,
* which speeds up lots'a things (like on-screen cursoring).
* - avoid redrawing (in updateNextscreen) as much as possible, which
* speeds up (among other things) cursoring (off screen), put, undo,
* redo, etc.
* - GRWalter (Fred)
*
* 3.34A - rewrote updateNextscreen and updatenextline so they won't do as
* much work. Sped up cursoring off-screen. Fixed bug in cursupdate
* (could index through NULL pointer).
* - GRWalter (Fred)
*
* 3.35A - Compiles with Lattice 5.0 now - needed miscellaneous changes.
* - Environment variables (EXINIT) finally used.
* - Stevie is now compiled so it's residentable.
* - Fixed bug in insstr() (caused problems with redo of inserts).
* - Fixed buffer overflow/corrupt messages.
* - Tweaked updateNextscreen routine some more.
* - Added __DATE__ and __TIME__ of compilation to help screen.
* - GRWalter (Fred)
*/
char *Version = "STEVIE - Version 3.35A";
SHAR_EOF
# End of shell archive
exit 0
--
Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page
Have five nice days.