[comp.sources.amiga] v89i130: stevie - vi editor clone v3.6, Part01/06

page%swap@Sun.COM (Bob Page) (05/12/89)

Submitted-by: grwalter@watmath.waterloo.edu (Fred Walter)
Posting-number: Volume 89, Issue 130
Archive-name: editors/stevie36.1

Differences between this version and 3.35A:
	- much faster screen I/O
	- will no longer lock-up until the window is resized
	- a lot more out-of-memory checking
	- miscellaneous bug fixes.

Stevie requires a fair amount of memory to use.  As always, it can
be made resident.

# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
#	MAKE_TAGS
#	Makefile
#	README
#	TODO
#	alloc.c
#	amiga.c
#	amiga.h
#	ascii.h
#	bsd.c
#	bsd.h
#	charset.c
# This is archive 1 of a 6-part kit.
# This archive created: Thu May 11 19:41:24 1989
echo "extracting MAKE_TAGS"
sed 's/^X//' << \SHAR_EOF > MAKE_TAGS
X/ctags/ctags -t    alloc.c charset.c cmdline.c dec.c edit.c
X/ctags/ctags -t -a fileio.c help.c inc.c linefunc.c main.c mark.c
X/ctags/ctags -t -a misccmds.c normal.c param.c screen.c
X/ctags/ctags -t -a search.c format_l.c
X/ctags/ctags -t -a s_io.c ascii.h keymap.h
X/ctags/ctags -t -a macros.h param.h stevie.h term.h mk.c
X
X/ctags/ctags -t -a amiga.h amiga.c
SHAR_EOF
echo "extracting Makefile"
sed 's/^X//' << \SHAR_EOF > Makefile
X#
X# Makefile for Lattice C 5.0 on Amiga
X#
X
X.c.o:
X	lc $(CFLAGS) $<
X
X#CFLAGS = -cu -ma -DAMIGA
XCFLAGS = -cu -ma -O -DAMIGA
XLINKFLAGS = NODEBUG
XLIBS = lib:lc.lib
X
XMACH=	amiga.o
X
XOBJ1=	main.o edit.o linefunc.o normal.o cmdline.o charset.o
XOBJ2=	format_l.o misccmds.o help.o dec.o inc.o search.o alloc.o
XOBJ3=	mk.o regexp.o regsub.o version.o
XOBJ4=	s_io.o mark.o screen.o fileio.o param.o
X
XOBJ= $(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(MACH)
X
Xall: stevie
X	say "done all"
X
Xstevie: $(OBJ) Makefile
X	BLINK TO stevie FROM lib:cres.o $(OBJ) LIBRARY $(LIBS) $(LINKFLAGS)
X
Xclean:
X	delete $(OBJ1)
X	delete $(OBJ2)
X	delete $(OBJ3)
X	delete $(OBJ4)
X	delete $(MACH)
X	delete stevie
SHAR_EOF
echo "extracting README"
sed 's/^X//' << \SHAR_EOF > README
XSTEVIE Source Release
X
XThis is a source release of the STEVIE editor, a public domain clone
Xof the UNIX editor 'vi'. The program was originally developed for the
XAtari ST, but has been ported to UNIX, OS/2, BSD 4.3 and the Amiga as well.
X
XThere are currently two divergent versions of STEVIE. This version is the one
Xthat was ported to the Amiga and then worked on by me (G. R. Walter). The other
Xone Tony Andrews continued to work on. My version is faster in some respects
Xthen his version, and his version does a couple of things mine doesn't. 
X
XThe files included in this release are:
X
XREADME
X	This file.
X
Xstevie.doc
X	Reference manual for STEVIE. Assumes familiarity with vi.
X
Xsource.doc
X	Quick overview of the major data structures used.
X
Xporting.doc
X	Tips for porting STEVIE to other systems.
X
Xmakefile.dos
Xmakefile.os2
Xmakefile.usg
Xmakefile.tos
Xmakefile.bsd
Xmakefile.amiga.lattice
X	Makefiles for MS DOS, OS/2, UNIX System V, Atari ST, BSD 4.3 UNIX and
Xthe Amiga respectively.
X
Xamiga.c
Xamiga.h
Xbsd.c
Xbsd.h
Xdos.c
Xdos.h
Xos2.c
Xos2.h
Xunix.c
Xunix.h
Xtos.c
Xtos.h
X	System-dependent routines for the same.
X
Xalloc.c ascii.h cmdline.c edit.c fileio.c help.c charset.c
Xkeymap.h linefunc.c main.c mark.c misccmds.c normal.c param.c
Xregexp.c regsub.c version.c regexp.h regmagic.h
Xparam.h ptrfunc.c screen.c search.c stevie.h term.h macros.h
X
X	C source and header files for STEVIE.
X
XTo compile STEVIE for one of the provided systems:
X
X	1. Compile the regular expression library and install as
X	   appropriate for your system.
X
X	2. Edit the file 'env.h' to set the system defines as needed.
X
X	3. Check the makefile for your system, and modify as needed.
X
X	4. Compile.
X
XNOTE: implicit in the design is the assumption that char's are unsigned. Thus
X      if your compiler assumes different by default, change the default or
X      you may have to change the source.
X
XTony Andrews            March  12, 1988
XG. R. (Fred) Walter     August 14, 1988
SHAR_EOF
echo "extracting TODO"
sed 's/^X//' << \SHAR_EOF > TODO
XTo Do
X-----
X
X- Change the static buffers for insert/undo/redo/undoundo/etc to dynamic
X  buffers.
X
X- Add #'d and named buffers.
X
X- Add 'R' and 'U'.
X
X- In cmdline.c make get_range() give the appropriate error messages when it
X  gets a bad line range.
X
X- Add & (do last search and replace on current line) and :[range]&
X  (do last search and replace on the range of lines).
X
X- add set wrapmargin command
X- add set shiftwidth command
X- add set autowrite command
X
X- add checks for out of memory when strsave() is used
SHAR_EOF
echo "extracting alloc.c"
sed 's/^X//' << \SHAR_EOF > alloc.c
X/*
X * STEVIE - Simply Try this Editor for VI Enthusiasts
X *
X * Code Contributions By : Tim Thompson           twitch!tjt
X *                         Tony Andrews           onecom!wldrdg!tony 
X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
X */
X
X#ifdef AMIGA
X# include <proto/exec.h>
X# include <exec/memory.h>
X# define PANIC_FACTOR_CHIP 40000
X#endif
X#include "stevie.h"
X
X/*
X * This file contains various routines dealing with allocation and
X * deallocation of data structures. 
X */
X
Xchar           *
Xalloc(size)
X    unsigned        size;
X{
X    char           *p;		/* pointer to new storage space */
X
X    p = malloc(size);
X    if (p == (char *) NULL) {	/* if there is no more room... */
X	emsg("alloc() is unable to find memory!");
X	sleep(5);
X    }
X#ifdef AMIGA
X    if (AvailMem(MEMF_CHIP) < PANIC_FACTOR_CHIP) {
X	free(p);
X	p = (char *) NULL;
X	emsg("alloc() - not enough CHIP memory!");
X	sleep(5);
X    }
X#endif
X
X    return (p);
X}
X
Xchar           *
Xstrsave(string)
X    char           *string;
X{
X    char           *s;
X
X    s = alloc((unsigned) (strlen(string) + 1));
X    if (s != (char *) NULL)
X	strcpy(s, string);
X    return (s);
X}
X
Xvoid
Xscreenalloc()
X{
X    int             i;
X
X    /*
X     * If we're changing the size of the screen, free the old arrays 
X     */
X    if (LinePointers != (LINE **) NULL)
X	free((char *) LinePointers);
X    if (LineSizes != (char *) NULL)
X	free(LineSizes);
X
X    LinePointers = (LINE **) malloc((unsigned) (Rows * sizeof(LINE *)));
X    LineSizes = malloc((unsigned) Rows);
X    if (LinePointers == (LINE **) NULL || LineSizes == (char *) NULL) {
X	fprintf(stderr, "Unable to allocate screen memory!\n");
X	getout(1);
X    }
X    for (i = 0; i < Rows; i++) {
X	LinePointers[i] = (LINE *) NULL;
X	LineSizes[i] = (char) 0;
X    }
X    NumLineSizes = -1;
X}
X
X/*
X * Allocate and initialize a new line structure with room for 'nchars'
X * characters. 
X */
XLINE           *
Xnewline(nchars)
X    int             nchars;
X{
X    register LINE  *l;
X
X    if (nchars == 0)
X	nchars = 1;
X
X    l = (LINE *) alloc((unsigned) sizeof(LINE));
X    if (l != (LINE *) NULL) {
X	l->s = alloc((unsigned) nchars);	/* the line is empty */
X	if (l->s != (char *) NULL) {
X	    l->s[0] = NUL;
X	    l->size = nchars;
X
X	    l->prev = (LINE *) NULL;	/* should be initialized by caller */
X	    l->next = (LINE *) NULL;
X	} else {
X	    free((char *) l);
X	    l = (LINE *) NULL;
X	}
X    }
X    return l;
X}
X
X/*
X * filealloc() - construct an initial empty file buffer 
X */
Xvoid
Xfilealloc()
X{
X    Filemem->linep = newline(1);
X    Filetop->linep = newline(1);
X    Fileend->linep = newline(1);
X    if (Filemem->linep == (LINE *) NULL ||
X	Filetop->linep == (LINE *) NULL ||
X	Fileend->linep == (LINE *) NULL) {
X	fprintf(stderr, "Unable to allocate file memory!\n");
X	getout(1);
X    }
X    Filemem->index = 0;
X    Filetop->index = 0;
X    Fileend->index = 0;
X
X    Filetop->linep->prev = (LINE *) NULL;
X    Filetop->linep->next = Filemem->linep;	/* connect Filetop to Filemem */
X    Filemem->linep->prev = Filetop->linep;
X
X    Filemem->linep->next = Fileend->linep;	/* connect Filemem to Fileend */
X    Fileend->linep->prev = Filemem->linep;
X    Fileend->linep->next = (LINE *) NULL;
X
X    *Curschar = *Filemem;
X    *Topchar = *Filemem;
X
X    Filemem->linep->num = 0;
X    Fileend->linep->num = 0xffffffffL;
X
X    clrall();			/* clear all marks */
X}
X
X/*
X * freeall() - free the current buffer 
X *
X * Free all lines in the current buffer. 
X */
Xvoid
Xfreeall()
X{
X    LINE           *lp;
X    LINE           *xlp;
X    int             i;
X
X    for (lp = Filetop->linep; lp != (LINE *) NULL; lp = xlp) {
X	if (lp->s != (char *) NULL)
X	    free(lp->s);
X	xlp = lp->next;
X	free((char *) lp);
X    }
X
X    Curschar->linep = (LINE *) NULL;	/* clear pointers */
X    Filemem->linep = (LINE *) NULL;
X    Filetop->linep = (LINE *) NULL;
X    Fileend->linep = (LINE *) NULL;
X
X    for (i = 0; i < Rows; i++) {/* clear screen information */
X	LinePointers[i] = (LINE *) NULL;
X	LineSizes[i] = (char) 0;
X    }
X    NumLineSizes = -1;
X}
X
X/*
X * canincrease(n) - returns TRUE if the current line can be increased 'n'
X * bytes 
X *
X * This routine returns immediately if the requested space is available. If not,
X * it attempts to allocate the space and adjust the data structures
X * accordingly. If everything fails it returns FALSE. 
X */
Xbool_t
Xcanincrease(n)
X    register int    n;
X{
X    register int    nsize;
X    register char  *s;		/* pointer to new space */
X
X    nsize = strlen(Curschar->linep->s) + 1 + n;	/* size required */
X
X    if (nsize <= Curschar->linep->size)
X	return TRUE;
X
X    /*
X     * Need to allocate more space for the string. Allow some extra space on
X     * the assumption that we may need it soon. This avoids excessive numbers
X     * of calls to malloc while entering new text. 
X     */
X    s = alloc((unsigned) (nsize + SLOP));
X    if (s == (char *) NULL) {
X	emsg("Can't add anything, file is too big!");
X	State = NORMAL;
X	return FALSE;
X    }
X    Curschar->linep->size = nsize + SLOP;
X    strcpy(s, Curschar->linep->s);
X    free(Curschar->linep->s);
X    Curschar->linep->s = s;
X
X    return TRUE;
X}
SHAR_EOF
echo "extracting amiga.c"
sed 's/^X//' << \SHAR_EOF > amiga.c
X/*
X * Amiga system-dependent routines. 
X */
X
X#include <proto/exec.h>
X#include <proto/dos.h>
X#include <exec/memory.h>
X#include <devices/conunit.h>
X#include <stdio.h>
X#include <ios1.h>
X#include <error.h>
X
X#include "stevie.h"
X
X/* Globals initialized by get_ConUnit() */
Xstruct Window  *conWindow;
Xstruct ConUnit *conUnit;
X
Xextern int      errno;		/* The error variable */
X
Xlong            raw_in = 0;
Xlong            raw_out = 0;
X
X#define BSIZE   2048
Xstatic char     outbuf[BSIZE];
Xstatic int      bpos = 0;
X
Xvoid
Xflushbuf()
X{
X    if (bpos != 0)
X	Write(raw_out, outbuf, bpos);
X    bpos = 0;
X}
X
Xvoid
Xoutchar(c)
X    char            c;
X{
X    outbuf[bpos++] = c;
X    if (bpos >= BSIZE)
X	flushbuf();
X}
X
Xvoid
Xoutstr(s)
X    char           *s;
X{
X    while (*s) {
X	outbuf[bpos++] = *s++;
X	if (bpos >= BSIZE)
X	    flushbuf();
X    }
X}
X
Xint
XGetCharacter()
X{
X    char            c;
X
X    Read(raw_in, &c, sizeof(c));
X    return ((int) c);
X}
X
X/*
X * getCSIsequence - get a CSI sequence
X *                - either cursor keys, help, or function keys
X */
X
Xint
XgetCSIsequence()
X{
X    int             c;
X    int             tmp;
X
X
X    c = GetCharacter();
X    if (isdigit(c)) {
X	tmp = 0;
X	while (isdigit(c)) {
X	    tmp = tmp * 10 + c - '0';
X	    c = GetCharacter();
X	}
X	if (c == '~')		/* function key */
X	    return ((char) (K_F1 + tmp));
X    }
X    switch (c) {
X      case 'A':		/* cursor up */
X	return K_UARROW;
X      case 'B':		/* cursor down */
X	return K_DARROW;
X      case 'C':		/* cursor right */
X	return K_RARROW;
X      case 'D':		/* cursor left */
X	return K_LARROW;
X      case 'T':		/* shift cursor up */
X	return K_SUARROW;
X      case 'S':		/* shift cursor down */
X	return K_SDARROW;
X      case ' ':		/* shift cursor left or right */
X	c = GetCharacter();
X	if (c == 'A')		/* shift cursor left */
X	    return K_SLARROW;
X	if (c == '@')		/* shift cursor right */
X	    return K_SRARROW;
X	break;
X      case '?':		/* help */
X	c = GetCharacter();
X	if (c == '~')
X	    return K_HELP;
X	break;
X    }
X    while ((c != '|') && (c != '~')) {
X	if (WaitForChar(raw_in, 500L) == 0)
X	    break;
X	c = GetCharacter();
X    }
X
X    /* must have been screen resize event */
X    s_clear();
X    flushbuf();
X    if (get_ConUnit(raw_in) != 0) {	/* hopefully never exit .... */
X	emsg("STEVIE: can't get ConUnit info ?!?!?!?\n");
X	sleep(5);
X	return 0;
X    }
X    Rows = conUnit->cu_YMax + 1;
X    Columns = conUnit->cu_XMax + 1;
X    if (Columns < 5)
X	Columns = 5;
X    if (Columns > MAX_COLUMNS)
X	Columns = MAX_COLUMNS;
X    if (Rows < 2)
X	Rows = 2;
X    P(P_LI) = Rows;
X
X    screenalloc();
X    tmp = RedrawingDisabled;
X    RedrawingDisabled = TRUE;
X    S_NOT_VALID;
X    cursupdate(UPDATE_ALL);	/* make sure not below Botchar */
X    RedrawingDisabled = FALSE;
X    s_refresh(NOT_VALID);	/* draw it */
X    RedrawingDisabled = tmp;
X    windgoto(Cursrow, Curscol);
X    flushbuf();
X
X    return 0;
X}
X
X/*
X * inchar() - get a character from the keyboard 
X */
Xint
Xinchar()
X{
X    int             c;
X
X    flushbuf();
X
X    for (;;) {
X	c = GetCharacter();
X	if (c == 0x9b)
X	    c = getCSIsequence();
X	if (c != 0)
X	    break;
X    }
X
X    return c;
X}
X
Xvoid
Xbeep()
X{
X    if (RedrawingDisabled)
X	return;
X
X    outbuf[bpos++] = '\007';
X    if (bpos >= BSIZE)
X	flushbuf();
X}
X
Xvoid
Xsleep(n)
X    int             n;
X{
X    void            Delay();
X
X    if (n > 0)
X	Delay(50L * n);
X}
X
Xvoid
Xdelay()
X{
X    void            Delay();
X
X    Delay(25L);
X}
X
Xvoid
Xwindinit()
X{
X    raw_in = Input();
X    if (!IsInteractive(raw_in)) {
X	raw_in = Open("RAW:0/0/480/200/STEVIE", MODE_NEWFILE);
X	if (raw_in == NULL) {
X	    fprintf(stderr, "STEVIE: Can't open window ?!?!?!?\n");
X	    exit(2);
X	}
X	raw_out = raw_in;
X    } else {
X	raw_out = Output();
X	if (raw(raw_in) != 0) {
X	    perror("STEVIE: Can't change to raw mode ?!?!?!?");
X	    exit(2);
X	}
X    }
X
X    if (get_ConUnit(raw_in) != 0) {
X	fprintf(stderr, "STEVIE: can't get ConUnit info ?!?!?!?\n");
X	windexit(3);
X    }
X    /* get window size */
X    P(P_LI) = Rows = conUnit->cu_YMax + 1;
X    Columns = conUnit->cu_XMax + 1;
X
X    outstr("\033[12{");		/* window resize events activated */
X    flushbuf();
X}
X
Xvoid
Xwindexit(r)
X    int             r;
X{
X    outstr("\033[12}");		/* window resize events de-activated */
X    flushbuf();
X
X    if (raw_in != raw_out) {
X	if (cooked(raw_in) != 0)
X	    perror("STEVIE: Can't change to cooked mode ?!?!?!?");
X    } else {
X	Close(raw_in);
X    }
X
X    exit(r);
X}
X
Xvoid
Xwindgoto(r, c)
X    int             c;
X    int             r;
X{
X    r++;
X    c++;
X
X    outstr("\033[");
X    if (r >= 10)
X	outchar((char) (r / 10 + '0'));
X    outchar((char) (r % 10 + '0'));
X    outchar(';');
X    if (c >= 10)
X	outchar((char) (c / 10 + '0'));
X    outchar((char) (c % 10 + '0'));
X    outchar('H');
X}
X
XFILE           *
Xfopenb(fname, mode)
X    char           *fname;
X    char           *mode;
X{
X    FILE           *fopen();
X    char            modestr[16];
X
X    sprintf(modestr, "%sb", mode);
X    return fopen(fname, modestr);
X}
X
X/*
X * raw() & cooked()
X *
X * These are routines for setting a given stream to raw or cooked mode on the
X * Amiga. This is useful when you are using Lattice C to produce programs
X * that want to read single characters with the "getch()" or "fgetc" call. 
X *
X * Written : 18-Jun-87 By Chuck McManis.
X */
X
X/*
X * Function raw() - Convert the specified File Handle to 'raw' mode. This
X * only works on TTY's and essentially keeps DOS from translating keys for
X * you.
X */
X
Xlong
Xraw(afh)
X    struct FileHandle *afh;
X{
X    struct MsgPort *mp;		/* The File Handle message port */
X    long            Arg[1], res;
X
X    mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
X    Arg[0] = -1L;
X    res = SendPacket(mp, ACTION_SCREEN_MODE, Arg, 1);
X    if (res == 0) {
X	errno = ENXIO;
X	return (-1);
X    }
X    return (0);
X}
X
X/*
X * Function - cooked() this function returns the designate file pointer to
X * it's normal, wait for a <CR> mode. This is exactly like raw() except that
X * it sends a 0 to the console to make it back into a CON: from a RAW: 
X */
X
Xlong
Xcooked(afh)
X    struct FileHandle *afh;
X{
X    struct MsgPort *mp;		/* The File Handle message port */
X    long            Arg[1], res;
X
X    mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
X    Arg[0] = 0L;
X    res = SendPacket(mp, ACTION_SCREEN_MODE, Arg, 1);
X    if (res == 0) {
X	errno = ENXIO;
X	return (-1);
X    }
X    return (0);
X}
X
X/*
X * Code for this routine came from the following :
X *
X * ConPackets.c -  C. Scheppner, A. Finkel, P. Lindsay  CBM
X *   DOS packet example
X *   Requires 1.2
X *
X * which I found on Fish Disk 56.
X */
X
X/* initializes conWindow and conUnit (global vars) */
Xlong
Xget_ConUnit(afh)
X    struct FileHandle *afh;
X{
X    struct MsgPort *mp;		/* The File Handle message port */
X    struct InfoData *id;
X    long            Arg[8], res;
X
X    if (!IsInteractive((BPTR) afh)) {
X	errno = ENOTTY;
X	return (-1);
X    }
X    mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
X
X    /* Alloc to insure longword alignment */
X    id = (struct InfoData *) AllocMem(sizeof(struct InfoData),
X				      MEMF_PUBLIC | MEMF_CLEAR);
X    if (!id) {
X	errno = ENOMEM;
X	return (-1);
X    }
X    Arg[0] = ((ULONG) id) >> 2;
X    res = SendPacket(mp, ACTION_DISK_INFO, Arg, 1);
X    conWindow = (struct Window *) id->id_VolumeNode;
X    conUnit = (struct ConUnit *) ((struct IOStdReq *) id->id_InUse)->io_Unit;
X    FreeMem(id, sizeof(struct InfoData));
X    if (res == 0) {
X	errno = ENXIO;
X	return (-1);
X    }
X    return (0);
X}
X
X/*
X * SendPacket() - written by Phil Lindsay, Carolyn Scheppner, and Andy
X * Finkel. This function will send a packet of the given type to the Message
X * Port supplied. 
X */
X
Xlong
XSendPacket(pid, action, args, nargs)
X    struct MsgPort *pid;	/* process indentifier ... (handlers message
X				 * port ) */
X    long            action,	/* packet type ... (what you want handler to
X				 * do )   */
X                    args[],	/* a pointer to a argument list */
X                    nargs;	/* number of arguments in list  */
X{
X    struct MsgPort *replyport;
X    struct StandardPacket *packet;
X
X    long            count, *pargs, res1;
X
X    replyport = (struct MsgPort *) CreatePort(NULL, 0);
X    if (!replyport)
X	return (0);
X
X    /* Allocate space for a packet, make it public and clear it */
X    packet = (struct StandardPacket *)
X	AllocMem((long) sizeof(struct StandardPacket),
X		 MEMF_PUBLIC | MEMF_CLEAR);
X    if (!packet) {
X	DeletePort(replyport);
X	return (0);
X    }
X    packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
X    packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
X    packet->sp_Pkt.dp_Port = replyport;
X    packet->sp_Pkt.dp_Type = action;
X
X    /* copy the args into the packet */
X    pargs = &(packet->sp_Pkt.dp_Arg1);	/* address of first argument */
X    for (count = 0; count < nargs; count++)
X	pargs[count] = args[count];
X
X    PutMsg(pid, packet);	/* send packet */
X
X    WaitPort(replyport);
X    GetMsg(replyport);
X
X    res1 = packet->sp_Pkt.dp_Res1;
X
X    FreeMem(packet, (long) sizeof(struct StandardPacket));
X    DeletePort(replyport);
X
X    return (res1);
X}
SHAR_EOF
echo "extracting amiga.h"
sed 's/^X//' << \SHAR_EOF > amiga.h
X/*
X * Amiga Machine-dependent routines. 
X */
X
Xvoid flushbuf();
X
Xint  inchar();
Xvoid outchar();
Xvoid outstr();
Xvoid beep();
Xvoid windinit();
Xvoid windexit();
Xvoid windgoto();
Xvoid delay();
Xvoid sleep();
SHAR_EOF
echo "extracting ascii.h"
sed 's/^X//' << \SHAR_EOF > ascii.h
X/*
X * STEVIE - Simply Try this Editor for VI Enthusiasts
X *
X * Code Contributions By : Tim Thompson           twitch!tjt
X *                         Tony Andrews           onecom!wldrdg!tony 
X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
X */
X
X/*
X * Definitions of various common control characters 
X */
X
X#define	NUL			'\000'
X#define	BS			'\010'
X#define	BS_STR			"\010"
X#define	TAB			'\011'
X#define	NL			'\012'
X#define	NL_STR			"\012"
X#define	CR			'\015'
X#define	ESC			'\033'
X#define	ESC_STR			"\033"
X
X#define	UNDO_SHIFTJ		'\333'
X#define	UNDO_SHIFTJ_STR		"\333"
X
X#define	ENABLE_REDRAWING	'\334'
X#define	ENABLE_REDRAWING_STR	"\334"
X
X#define	CTRL(x)	((x) & 0x1f)
SHAR_EOF
echo "extracting bsd.c"
sed 's/^X//' << \SHAR_EOF > bsd.c
X/*
X * System-dependent routines for BSD 4.3 UNIX 
X */
X
X#include "stevie.h"
X#include <sgtty.h>
X
X#ifdef OLD_IO
X#define BSIZE   2048
Xstatic char     outbuf[BSIZE];
Xstatic int      bpos = 0;
X
Xvoid
Xflushbuf()
X{
X    if (bpos != 0)
X	fwrite(outbuf, sizeof(*outbuf), bpos, stdout);
X    fflush(stdout);
X    bpos = 0;
X}
X
Xvoid
Xoutchar(c)
X    char            c;
X{
X    outbuf[bpos++] = c;
X    if (bpos >= BSIZE)
X	flushbuf();
X}
X
Xvoid
Xoutstr(s)
X    char           *s;
X{
X    while (*s) {
X	outbuf[bpos++] = *s++;
X	if (bpos >= BSIZE)
X	    flushbuf();
X    }
X}
X#endif
X
X/*
X * inchar() - get a character from the keyboard 
X */
Xint
Xinchar()
X{
X    int             c;
X
X    flushbuf();			/* flush any pending output */
X
X    c = getchar();
X
X    return c;
X}
X
Xvoid
Xbeep()
X{
X    if (RedrawingDisabled)
X	return;
X
X    outchar('\007');
X}
X
Xvoid
Xdelay()
X{
X    sleep(1);
X}
X
Xstatic struct sgttyb ostate;
X
Xvoid
Xwindinit()
X{
X    char           *getenv();
X    struct sgttyb   nstate;
X#ifdef CHECK_TERM
X    char           *term;
X
X    term = getenv("TERM");
X    if (!term) {
X	fprintf(stderr, "Invalid terminal type '%s'\n", term);
X	exit(1);
X    }
X    if ((strncmp(term, "vt", 2) != 0) && (strncmp(term, "kd", 2) != 0)) {
X	fprintf(stderr, "Invalid terminal type '%s'\n", term);
X	exit(1);
X    }
X#endif
X
X    Columns = 80;
X    P(P_LI) = Rows = 24;
X
X    /*
X     * Go into cbreak mode 
X     */
X    ioctl(1, (long) TIOCGETP, (char *) &ostate);
X    nstate = ostate;
X    nstate.sg_flags = nstate.sg_flags & ~(ECHO | CRMOD) | CBREAK;
X    ioctl(1, (long) TIOCSETP, (char *) &nstate);
X}
X
Xvoid
Xwindexit(r)
X    int             r;
X{
X    flushbuf();
X
X    ioctl(0, (long) TIOCSETP, (char *) &ostate);
X
X    exit(r);
X}
X
Xvoid
Xwindgoto(r, c)
X    int             c;
X    int             r;
X{
X    r++;
X    c++;
X
X    outstr("\033[");
X    if (r >= 10)
X	outchar((char) (r / 10 + '0'));
X    outchar((char) (r % 10 + '0'));
X    outchar(';');
X    if (c >= 10)
X	outchar((char) (c / 10 + '0'));
X    outchar((char) (c % 10 + '0'));
X    outchar('H');
X}
X
XFILE           *
Xfopenb(fname, mode)
X    char           *fname;
X    char           *mode;
X{
X    return fopen(fname, mode);
X}
SHAR_EOF
echo "extracting bsd.h"
sed 's/^X//' << \SHAR_EOF > bsd.h
X/*
X * BSD 4.3 Machine-dependent routines. 
X */
X
Xint  inchar();
X
X#ifdef OLD_IO
Xvoid flushbuf();
Xvoid outchar();
Xvoid outstr();
X#else
X# define flushbuf() fflush(stdout)
X# define outchar(C) putchar(C)
X# define outstr(S)  fputs((S), stdout)
X#endif
X
Xvoid beep();
X#define remove(path) unlink(path)
Xint rename();
Xvoid windinit();
Xvoid windexit();
Xvoid windgoto();
Xvoid delay();
SHAR_EOF
echo "extracting charset.c"
sed 's/^X//' << \SHAR_EOF > charset.c
X/*
X * STEVIE - Simply Try this Editor for VI Enthusiasts
X *
X * Code Contributions By : Tim Thompson           twitch!tjt
X *                         Tony Andrews           onecom!wldrdg!tony 
X *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
X */
X
X#include "stevie.h"
X
X/*
X * This file shows how to display characters on the screen. This is approach
X * is something of an overkill. It's a remnant from the original code that
X * isn't worth messing with for now. TABS are special-cased depending on the
X * value of the "list" parameter. 
X */
X
Xstruct charinfo chars[] = {
X			    /* 0 */ 0, 0,	/* both must be zero */
X			    /* 1 */ 2, "^A",
X			    /* 2 */ 2, "^B",
X			    /* 3 */ 2, "^C",
X			    /* 4 */ 2, "^D",
X			    /* 5 */ 2, "^E",
X			    /* 6 */ 2, "^F",
X			    /* 7 */ 2, "^G",
X			    /* 8 */ 2, "^H",
X			    /* 9 */ 2, "^I",
X			    /* 10 */ 7, "[ERROR]",	/* shouldn't happen */
X			    /* 11 */ 2, "^K",
X			    /* 12 */ 2, "^L",
X			    /* 13 */ 2, "^M",
X			    /* 14 */ 2, "^N",
X			    /* 15 */ 2, "^O",
X			    /* 16 */ 2, "^P",
X			    /* 17 */ 2, "^Q",
X			    /* 18 */ 2, "^R",
X			    /* 19 */ 2, "^S",
X			    /* 20 */ 2, "^T",
X			    /* 21 */ 2, "^U",
X			    /* 22 */ 2, "^V",
X			    /* 23 */ 2, "^W",
X			    /* 24 */ 2, "^X",
X			    /* 25 */ 2, "^Y",
X			    /* 26 */ 2, "^Z",
X			    /* 27 */ 2, "^[",
X			    /* 28 */ 2, "^\\",
X			    /* 29 */ 2, "^]",
X			    /* 30 */ 2, "^^",
X			    /* 31 */ 2, "^_",
X			    /* 32 */ 1, " ",
X			    /* 33 */ 1, "!",
X			    /* 34 */ 1, "\"",
X			    /* 35 */ 1, "#",
X			    /* 36 */ 1, "$",
X			    /* 37 */ 1, "%",
X			    /* 38 */ 1, "&",
X			    /* 39 */ 1, "'",
X			    /* 40 */ 1, "(",
X			    /* 41 */ 1, ")",
X			    /* 42 */ 1, "*",
X			    /* 43 */ 1, "+",
X			    /* 44 */ 1, ",",
X			    /* 45 */ 1, "-",
X			    /* 46 */ 1, ".",
X			    /* 47 */ 1, "/",
X			    /* 48 */ 1, "0",
X			    /* 49 */ 1, "1",
X			    /* 50 */ 1, "2",
X			    /* 51 */ 1, "3",
X			    /* 52 */ 1, "4",
X			    /* 53 */ 1, "5",
X			    /* 54 */ 1, "6",
X			    /* 55 */ 1, "7",
X			    /* 56 */ 1, "8",
X			    /* 57 */ 1, "9",
X			    /* 58 */ 1, ":",
X			    /* 59 */ 1, ";",
X			    /* 60 */ 1, "<",
X			    /* 61 */ 1, "=",
X			    /* 62 */ 1, ">",
X			    /* 63 */ 1, "?",
X			    /* 64 */ 1, "@",
X			    /* 65 */ 1, "A",
X			    /* 66 */ 1, "B",
X			    /* 67 */ 1, "C",
X			    /* 68 */ 1, "D",
X			    /* 69 */ 1, "E",
X			    /* 70 */ 1, "F",
X			    /* 71 */ 1, "G",
X			    /* 72 */ 1, "H",
X			    /* 73 */ 1, "I",
X			    /* 74 */ 1, "J",
X			    /* 75 */ 1, "K",
X			    /* 76 */ 1, "L",
X			    /* 77 */ 1, "M",
X			    /* 78 */ 1, "N",
X			    /* 79 */ 1, "O",
X			    /* 80 */ 1, "P",
X			    /* 81 */ 1, "Q",
X			    /* 82 */ 1, "R",
X			    /* 83 */ 1, "S",
X			    /* 84 */ 1, "T",
X			    /* 85 */ 1, "U",
X			    /* 86 */ 1, "V",
X			    /* 87 */ 1, "W",
X			    /* 88 */ 1, "X",
X			    /* 89 */ 1, "Y",
X			    /* 90 */ 1, "Z",
X			    /* 91 */ 1, "[",
X			    /* 92 */ 1, "\\",
X			    /* 93 */ 1, "]",
X			    /* 94 */ 1, "^",
X			    /* 95 */ 1, "_",
X			    /* 96 */ 1, "`",
X			    /* 97 */ 1, "a",
X			    /* 98 */ 1, "b",
X			    /* 99 */ 1, "c",
X			    /* 100 */ 1, "d",
X			    /* 101 */ 1, "e",
X			    /* 102 */ 1, "f",
X			    /* 103 */ 1, "g",
X			    /* 104 */ 1, "h",
X			    /* 105 */ 1, "i",
X			    /* 106 */ 1, "j",
X			    /* 107 */ 1, "k",
X			    /* 108 */ 1, "l",
X			    /* 109 */ 1, "m",
X			    /* 110 */ 1, "n",
X			    /* 111 */ 1, "o",
X			    /* 112 */ 1, "p",
X			    /* 113 */ 1, "q",
X			    /* 114 */ 1, "r",
X			    /* 115 */ 1, "s",
X			    /* 116 */ 1, "t",
X			    /* 117 */ 1, "u",
X			    /* 118 */ 1, "v",
X			    /* 119 */ 1, "w",
X			    /* 120 */ 1, "x",
X			    /* 121 */ 1, "y",
X			    /* 122 */ 1, "z",
X			    /* 123 */ 1, "{",
X			    /* 124 */ 1, "|",
X			    /* 125 */ 1, "}",
X			    /* 126 */ 1, "~",
X			    /* 127 */ 2, "^?",
X			    /* 128 */ 5, "[128]",
X			    /* 129 */ 5, "[129]",
X			    /* 130 */ 5, "[130]",
X			    /* 131 */ 5, "[131]",
X			    /* 132 */ 5, "[132]",
X			    /* 133 */ 5, "[133]",
X			    /* 134 */ 5, "[134]",
X			    /* 135 */ 5, "[135]",
X			    /* 136 */ 5, "[136]",
X			    /* 137 */ 5, "[137]",
X			    /* 138 */ 5, "[138]",
X			    /* 139 */ 5, "[139]",
X			    /* 140 */ 5, "[140]",
X			    /* 141 */ 5, "[141]",
X			    /* 142 */ 5, "[142]",
X			    /* 143 */ 5, "[143]",
X			    /* 144 */ 5, "[144]",
X			    /* 145 */ 5, "[145]",
X			    /* 146 */ 5, "[146]",
X			    /* 147 */ 5, "[147]",
X			    /* 148 */ 5, "[148]",
X			    /* 149 */ 5, "[149]",
X			    /* 150 */ 5, "[150]",
X			    /* 151 */ 5, "[151]",
X			    /* 152 */ 5, "[152]",
X			    /* 153 */ 5, "[153]",
X			    /* 154 */ 5, "[154]",
X			    /* 155 */ 5, "[155]",
X			    /* 156 */ 5, "[156]",
X			    /* 157 */ 5, "[157]",
X			    /* 158 */ 5, "[158]",
X			    /* 159 */ 5, "[159]",
X#ifdef AMIGA
X			    /* 160 */ 1, "\240",
X			    /* 161 */ 1, "\241",
X			    /* 162 */ 1, "\242",
X			    /* 163 */ 1, "\243",
X			    /* 164 */ 1, "\244",
X			    /* 165 */ 1, "\245",
X			    /* 166 */ 1, "\246",
X			    /* 167 */ 1, "\247",
X			    /* 168 */ 1, "\250",
X			    /* 169 */ 1, "\251",
X			    /* 170 */ 1, "\252",
X			    /* 171 */ 1, "\253",
X			    /* 172 */ 1, "\254",
X			    /* 173 */ 1, "\255",
X			    /* 174 */ 1, "\256",
X			    /* 175 */ 1, "\257",
X			    /* 176 */ 1, "\260",
X			    /* 177 */ 1, "\261",
X			    /* 178 */ 1, "\262",
X			    /* 179 */ 1, "\263",
X			    /* 180 */ 1, "\264",
X			    /* 181 */ 1, "\265",
X			    /* 182 */ 1, "\266",
X			    /* 183 */ 1, "\267",
X			    /* 184 */ 1, "\270",
X			    /* 185 */ 1, "\271",
X			    /* 186 */ 1, "\272",
X			    /* 187 */ 1, "\273",
X			    /* 188 */ 1, "\274",
X			    /* 189 */ 1, "\275",
X			    /* 190 */ 1, "\276",
X			    /* 191 */ 1, "\277",
X			    /* 192 */ 1, "\300",
X			    /* 193 */ 1, "\301",
X			    /* 194 */ 1, "\302",
X			    /* 195 */ 1, "\303",
X			    /* 196 */ 1, "\304",
X			    /* 197 */ 1, "\305",
X			    /* 198 */ 1, "\306",
X			    /* 199 */ 1, "\307",
X			    /* 200 */ 1, "\310",
X			    /* 201 */ 1, "\311",
X			    /* 202 */ 1, "\312",
X			    /* 203 */ 1, "\313",
X			    /* 204 */ 1, "\314",
X			    /* 205 */ 1, "\315",
X			    /* 206 */ 1, "\316",
X			    /* 207 */ 1, "\317",
X			    /* 208 */ 1, "\320",
X			    /* 209 */ 1, "\321",
X			    /* 210 */ 1, "\322",
X			    /* 211 */ 1, "\323",
X			    /* 212 */ 1, "\324",
X			    /* 213 */ 1, "\325",
X			    /* 214 */ 1, "\326",
X			    /* 215 */ 1, "\327",
X			    /* 216 */ 1, "\330",
X			    /* 217 */ 1, "\331",
X			    /* 218 */ 1, "\332",
X			    /* 219 */ 1, "\333",
X			    /* 220 */ 1, "\334",
X			    /* 221 */ 1, "\335",
X			    /* 222 */ 1, "\336",
X			    /* 223 */ 1, "\337",
X			    /* 224 */ 1, "\340",
X			    /* 225 */ 1, "\341",
X			    /* 226 */ 1, "\342",
X			    /* 227 */ 1, "\343",
X			    /* 228 */ 1, "\344",
X			    /* 229 */ 1, "\345",
X			    /* 230 */ 1, "\346",
X			    /* 231 */ 1, "\347",
X			    /* 232 */ 1, "\350",
X			    /* 233 */ 1, "\351",
X			    /* 234 */ 1, "\352",
X			    /* 235 */ 1, "\353",
X			    /* 236 */ 1, "\354",
X			    /* 237 */ 1, "\355",
X			    /* 238 */ 1, "\356",
X			    /* 239 */ 1, "\357",
X			    /* 240 */ 1, "\360",
X			    /* 241 */ 1, "\361",
X			    /* 242 */ 1, "\362",
X			    /* 243 */ 1, "\363",
X			    /* 244 */ 1, "\364",
X			    /* 245 */ 1, "\365",
X			    /* 246 */ 1, "\366",
X			    /* 247 */ 1, "\367",
X			    /* 248 */ 1, "\370",
X			    /* 249 */ 1, "\371",
X			    /* 250 */ 1, "\372",
X			    /* 251 */ 1, "\373",
X			    /* 252 */ 1, "\374",
X			    /* 253 */ 1, "\375",
X			    /* 254 */ 1, "\376",
X			    /* 255 */ 1, "\377"
X#else
X			    /* 160 */ 5, "[160]",
X			    /* 161 */ 5, "[161]",
X			    /* 162 */ 5, "[162]",
X			    /* 163 */ 5, "[163]",
X			    /* 164 */ 5, "[164]",
X			    /* 165 */ 5, "[165]",
X			    /* 166 */ 5, "[166]",
X			    /* 167 */ 5, "[167]",
X			    /* 168 */ 5, "[168]",
X			    /* 169 */ 5, "[169]",
X			    /* 170 */ 5, "[170]",
X			    /* 171 */ 5, "[171]",
X			    /* 172 */ 5, "[172]",
X			    /* 173 */ 5, "[173]",
X			    /* 174 */ 5, "[174]",
X			    /* 175 */ 5, "[175]",
X			    /* 176 */ 5, "[176]",
X			    /* 177 */ 5, "[177]",
X			    /* 178 */ 5, "[178]",
X			    /* 179 */ 5, "[179]",
X			    /* 180 */ 5, "[180]",
X			    /* 181 */ 5, "[181]",
X			    /* 182 */ 5, "[182]",
X			    /* 183 */ 5, "[183]",
X			    /* 184 */ 5, "[184]",
X			    /* 185 */ 5, "[185]",
X			    /* 186 */ 5, "[186]",
X			    /* 187 */ 5, "[187]",
X			    /* 188 */ 5, "[188]",
X			    /* 189 */ 5, "[189]",
X			    /* 190 */ 5, "[190]",
X			    /* 191 */ 5, "[191]",
X			    /* 192 */ 5, "[192]",
X			    /* 193 */ 5, "[193]",
X			    /* 194 */ 5, "[194]",
X			    /* 195 */ 5, "[195]",
X			    /* 196 */ 5, "[196]",
X			    /* 197 */ 5, "[197]",
X			    /* 198 */ 5, "[198]",
X			    /* 199 */ 5, "[199]",
X			    /* 200 */ 5, "[200]",
X			    /* 201 */ 5, "[201]",
X			    /* 202 */ 5, "[202]",
X			    /* 203 */ 5, "[203]",
X			    /* 204 */ 5, "[204]",
X			    /* 205 */ 5, "[205]",
X			    /* 206 */ 5, "[206]",
X			    /* 207 */ 5, "[207]",
X			    /* 208 */ 5, "[208]",
X			    /* 209 */ 5, "[209]",
X			    /* 210 */ 5, "[210]",
X			    /* 211 */ 5, "[211]",
X			    /* 212 */ 5, "[212]",
X			    /* 213 */ 5, "[213]",
X			    /* 214 */ 5, "[214]",
X			    /* 215 */ 5, "[215]",
X			    /* 216 */ 5, "[216]",
X			    /* 217 */ 5, "[217]",
X			    /* 218 */ 5, "[218]",
X			    /* 219 */ 5, "[219]",
X			    /* 220 */ 5, "[220]",
X			    /* 221 */ 5, "[221]",
X			    /* 222 */ 5, "[222]",
X			    /* 223 */ 5, "[223]",
X			    /* 224 */ 5, "[224]",
X			    /* 225 */ 5, "[225]",
X			    /* 226 */ 5, "[226]",
X			    /* 227 */ 5, "[227]",
X			    /* 228 */ 5, "[228]",
X			    /* 229 */ 5, "[229]",
X			    /* 230 */ 5, "[230]",
X			    /* 231 */ 5, "[231]",
X			    /* 232 */ 5, "[232]",
X			    /* 233 */ 5, "[233]",
X			    /* 234 */ 5, "[234]",
X			    /* 235 */ 5, "[235]",
X			    /* 236 */ 5, "[236]",
X			    /* 237 */ 5, "[237]",
X			    /* 238 */ 5, "[238]",
X			    /* 239 */ 5, "[239]",
X			    /* 240 */ 5, "[240]",
X			    /* 241 */ 5, "[241]",
X			    /* 242 */ 5, "[242]",
X			    /* 243 */ 5, "[243]",
X			    /* 244 */ 5, "[244]",
X			    /* 245 */ 5, "[245]",
X			    /* 246 */ 5, "[246]",
X			    /* 247 */ 5, "[247]",
X			    /* 248 */ 5, "[248]",
X			    /* 249 */ 5, "[249]",
X			    /* 250 */ 5, "[250]",
X			    /* 251 */ 5, "[251]",
X			    /* 252 */ 5, "[252]",
X			    /* 253 */ 5, "[253]",
X			    /* 254 */ 5, "[254]",
X			    /* 255 */ 5, "[255]"
X#endif
X};
SHAR_EOF
echo "End of archive 1 (of 6)"
# if you want to concatenate archives, remove anything after this line
exit